diff --git a/DEPS b/DEPS index 280d92e6..4ef66bc 100644 --- a/DEPS +++ b/DEPS
@@ -109,7 +109,7 @@ # 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': 'c0b96b43766ee4efd9f75247763fd936be76dff8', + 'v8_revision': '686dfc3f13a5fe766bfc25f2a84a8c64d45aa4e7', # 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. @@ -117,7 +117,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': 'e8dd07969872491eeb18cedae67ec892433aa5ca', + 'angle_revision': 'c0b82333ab279be7efc4752fd24f9c87b00310b5', # 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. @@ -165,7 +165,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': '920acc5657065dbcce54ce3093368ce6db5aa66b', + 'catapult_revision': '7453eba4feb2d90136a9415a6670ad41b866c93f', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -595,7 +595,7 @@ # Build tools for Chrome OS. Note: This depends on third_party/pyelftools. 'src/third_party/chromite': { - 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '10f3ee914d209c26f4f0e38c96b44853eb13ebd1', + 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '8241a7599974ed98de3e87c521b3a85047f614d3', 'condition': 'checkout_linux', }, @@ -954,7 +954,7 @@ }, 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + 'f7f0def7921b6c6f23ff37e42ce2042f8363c3cc', + Var('android_git') + '/platform/external/perfetto.git' + '@' + '40a2e1ea24495c6df976f194890e0843d52ada68', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + 'ac0d98b5cee6c024b0cffeb4f8f45b6fc5ccdb78', @@ -1106,7 +1106,7 @@ Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + '6d2f3f4cb8bac1f7c4a945c73d07a33df74f22f9', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + 'b5c6dd4349074a1ce98541a7959734772d833073', + Var('webrtc_git') + '/src.git' + '@' + 'cbcbc225687faf8226995c2823380adf06bd1afb', 'src/third_party/xdg-utils': { 'url': Var('chromium_git') + '/chromium/deps/xdg-utils.git' + '@' + 'd80274d5869b17b8c9067a1022e4416ee7ed5e0d', @@ -1137,7 +1137,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@c0e1056a6c8eb6f2cba9bcaa92c64e9c0ebcfaa7', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@bea5a39cb8956b75ebf37087530c71e3e6fdd6e3', 'condition': 'checkout_src_internal', },
diff --git a/WATCHLISTS b/WATCHLISTS index 8b139b5..c818caf0 100644 --- a/WATCHLISTS +++ b/WATCHLISTS
@@ -114,6 +114,9 @@ 'arc_auth': { 'filepath': 'chrome/browser/chromeos/arc/arc_auth' }, + 'arc_common': { + 'filepath': 'components/arc/common/', + }, 'arc_fileapi': { 'filepath': 'chrome/browser/chromeos/arc/fileapi' }, @@ -1791,6 +1794,7 @@ 'yusukes+watch@chromium.org', 'arc-reviews+chromium@google.com'], 'arc_auth': ['khmel+watch@chromium.org'], + 'arc_common': ['hashimoto+watch@chromium.org'], 'arc_fileapi': ['nya+watch@chromium.org'], 'arc_kiosk': ['poromov+watch@chromium.org'], 'arc_net': ['abhishekbh@chromium.org',
diff --git a/ash/BUILD.gn b/ash/BUILD.gn index 7ce5e92..90dd255 100644 --- a/ash/BUILD.gn +++ b/ash/BUILD.gn
@@ -34,6 +34,7 @@ "accelerators/accelerator_controller.h", "accessibility/accessibility_controller.h", "accessibility/accessibility_delegate.h", + "accessibility/ax_host_service.h", "accessibility/focus_ring_controller.h", "app_list/app_list_controller_impl.h", "detachable_base/detachable_base_handler.h", @@ -131,6 +132,7 @@ "accessibility/accessibility_observer.h", "accessibility/accessibility_panel_layout_manager.cc", "accessibility/accessibility_panel_layout_manager.h", + "accessibility/ax_host_service.cc", "accessibility/default_accessibility_delegate.cc", "accessibility/default_accessibility_delegate.h", "accessibility/focus_ring_controller.cc", @@ -1687,6 +1689,7 @@ "accessibility/accessibility_focus_ring_group_unittest.cc", "accessibility/accessibility_highlight_controller_unittest.cc", "accessibility/accessibility_panel_layout_manager_unittest.cc", + "accessibility/ax_host_service_unittest.cc", "accessibility/key_accessibility_enabler_unittest.cc", "accessibility/touch_accessibility_enabler_unittest.cc", "accessibility/touch_exploration_controller_unittest.cc",
diff --git a/ash/accessibility/accessibility_delegate.h b/ash/accessibility/accessibility_delegate.h index c59d0e6..0a33e6d3 100644 --- a/ash/accessibility/accessibility_delegate.h +++ b/ash/accessibility/accessibility_delegate.h
@@ -5,9 +5,15 @@ #ifndef ASH_ACCESSIBILITY_ACCESSIBILITY_DELEGATE_H_ #define ASH_ACCESSIBILITY_ACCESSIBILITY_DELEGATE_H_ +#include <vector> + #include "ash/ash_export.h" -#include "base/time/time.h" -#include "ui/accessibility/ax_enums.mojom.h" +#include "ui/accessibility/ax_tree_id.h" +#include "ui/accessibility/ax_tree_update.h" + +namespace ui { +struct AXEvent; +} namespace ash { @@ -36,6 +42,14 @@ // is not saved, return a negative value. virtual double GetSavedScreenMagnifierScale() = 0; + // Automation API support for remote mojo apps. + // TODO(jamescook): Convert to mojo API. + virtual void DispatchAccessibilityEvent( + const ui::AXTreeID& tree_id, + const std::vector<ui::AXTreeUpdate>& updates, + const ui::AXEvent& event) = 0; + virtual void DispatchTreeDestroyedEvent(const ui::AXTreeID& tree_id) = 0; + // NOTE: Prefer adding methods to AccessibilityController, see class comment. };
diff --git a/chrome/browser/chromeos/accessibility/ax_host_service.cc b/ash/accessibility/ax_host_service.cc similarity index 70% rename from chrome/browser/chromeos/accessibility/ax_host_service.cc rename to ash/accessibility/ax_host_service.cc index 6b128237..00ac720c 100644 --- a/chrome/browser/chromeos/accessibility/ax_host_service.cc +++ b/ash/accessibility/ax_host_service.cc
@@ -2,19 +2,19 @@ // 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/ax_host_service.h" +#include "ash/accessibility/ax_host_service.h" #include "ash/accessibility/accessibility_controller.h" +#include "ash/accessibility/accessibility_delegate.h" #include "ash/shell.h" #include "base/bind.h" -#include "chrome/browser/extensions/api/automation_internal/automation_event_router.h" -#include "chrome/common/extensions/chrome_extension_messages.h" #include "services/service_manager/public/cpp/connector.h" #include "services/service_manager/public/cpp/service_context.h" #include "ui/accessibility/ax_event.h" -#include "ui/aura/env.h" #include "ui/views/mus/ax_remote_host.h" +namespace ash { + AXHostService* AXHostService::instance_ = nullptr; bool AXHostService::automation_enabled_ = false; @@ -23,12 +23,8 @@ // AX tree ID is automatically assigned. DCHECK(!tree_id().empty()); - // ash::Shell may not exist in tests. - if (ash::Shell::HasInstance()) { - // TODO(jamescook): Eliminate this when tree ID assignment is handed in ash. - ash::Shell::Get()->accessibility_controller()->set_remote_ax_tree_id( - tree_id()); - } + // TODO(jamescook): Eliminate this when multiple remote trees are supported. + Shell::Get()->accessibility_controller()->set_remote_ax_tree_id(tree_id()); DCHECK(!instance_); instance_ = this; @@ -71,16 +67,12 @@ const std::vector<ui::AXTreeUpdate>& updates, const ui::AXEvent& event) { CHECK_EQ(tree_id, this->tree_id()); - ExtensionMsg_AccessibilityEventBundleParams event_bundle; - event_bundle.tree_id = tree_id; - for (const ui::AXTreeUpdate& update : updates) - event_bundle.updates.push_back(update); - event_bundle.events.push_back(event); - event_bundle.mouse_location = aura::Env::GetInstance()->last_mouse_location(); - - // Forward the tree updates and the event to the accessibility extension. - extensions::AutomationEventRouter::GetInstance()->DispatchAccessibilityEvents( - event_bundle); + // Use an in-process delegate back to Chrome for efficiency in classic ash. + // For mash we'll need to pass around a mojo interface pointer such that a + // remote app can talk directly to the browser process and not ping-pong + // through the ash process. + Shell::Get()->accessibility_delegate()->DispatchAccessibilityEvent( + tree_id, updates, event); } void AXHostService::PerformAction(const ui::AXActionData& data) { @@ -104,6 +96,7 @@ } void AXHostService::OnRemoteHostDisconnected() { - extensions::AutomationEventRouter::GetInstance()->DispatchTreeDestroyedEvent( - tree_id(), nullptr /* browser_context */); + Shell::Get()->accessibility_delegate()->DispatchTreeDestroyedEvent(tree_id()); } + +} // namespace ash
diff --git a/chrome/browser/chromeos/accessibility/ax_host_service.h b/ash/accessibility/ax_host_service.h similarity index 84% rename from chrome/browser/chromeos/accessibility/ax_host_service.h rename to ash/accessibility/ax_host_service.h index 9d2fa2a..b0809cde0 100644 --- a/chrome/browser/chromeos/accessibility/ax_host_service.h +++ b/ash/accessibility/ax_host_service.h
@@ -2,26 +2,30 @@ // 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_AX_HOST_SERVICE_H_ -#define CHROME_BROWSER_CHROMEOS_ACCESSIBILITY_AX_HOST_SERVICE_H_ +#ifndef ASH_ACCESSIBILITY_AX_HOST_SERVICE_H_ +#define ASH_ACCESSIBILITY_AX_HOST_SERVICE_H_ #include <memory> +#include "ash/ash_export.h" #include "mojo/public/cpp/bindings/binding_set.h" #include "mojo/public/cpp/bindings/interface_ptr_set.h" #include "services/service_manager/public/cpp/binder_registry.h" #include "services/service_manager/public/cpp/service.h" #include "ui/accessibility/ax_host_delegate.h" +#include "ui/accessibility/ax_tree_id.h" #include "ui/accessibility/mojom/ax_host.mojom.h" +namespace ash { + // Forwards accessibility events from clients in other processes that use aura // and views (e.g. the Chrome OS keyboard shortcut_viewer) to accessibility // extensions. Renderers, PDF, etc. use a different path. Created when the first // client connects over mojo. Implements AXHostDelegate by routing actions over // mojo to the remote process. -class AXHostService : public service_manager::Service, - public ax::mojom::AXHost, - public ui::AXHostDelegate { +class ASH_EXPORT AXHostService : public service_manager::Service, + public ax::mojom::AXHost, + public ui::AXHostDelegate { public: AXHostService(); ~AXHostService() override; @@ -66,4 +70,6 @@ DISALLOW_COPY_AND_ASSIGN(AXHostService); }; -#endif // CHROME_BROWSER_CHROMEOS_ACCESSIBILITY_AX_HOST_SERVICE_H_ +} // namespace ash + +#endif // ASH_ACCESSIBILITY_AX_HOST_SERVICE_H_
diff --git a/chrome/browser/chromeos/accessibility/ax_host_service_unittest.cc b/ash/accessibility/ax_host_service_unittest.cc similarity index 91% rename from chrome/browser/chromeos/accessibility/ax_host_service_unittest.cc rename to ash/accessibility/ax_host_service_unittest.cc index 43ac4b48..4ecc260b 100644 --- a/chrome/browser/chromeos/accessibility/ax_host_service_unittest.cc +++ b/ash/accessibility/ax_host_service_unittest.cc
@@ -2,8 +2,9 @@ // 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/ax_host_service.h" +#include "ash/accessibility/ax_host_service.h" +#include "ash/test/ash_test_base.h" #include "base/bind.h" #include "base/macros.h" #include "base/test/scoped_task_environment.h" @@ -11,6 +12,7 @@ #include "testing/gtest/include/gtest/gtest.h" #include "ui/accessibility/mojom/ax_host.mojom.h" +namespace ash { namespace { class TestAXRemoteHost : ax::mojom::AXRemoteHost { @@ -51,16 +53,7 @@ DISALLOW_COPY_AND_ASSIGN(TestAXRemoteHost); }; -class AXHostServiceTest : public testing::Test { - public: - AXHostServiceTest() = default; - ~AXHostServiceTest() override = default; - - private: - base::test::ScopedTaskEnvironment scoped_task_enviroment_; - - DISALLOW_COPY_AND_ASSIGN(AXHostServiceTest); -}; +using AXHostServiceTest = AshTestBase; TEST_F(AXHostServiceTest, AddClientThenEnable) { AXHostService service; @@ -120,3 +113,4 @@ } } // namespace +} // namespace ash
diff --git a/ash/accessibility/default_accessibility_delegate.cc b/ash/accessibility/default_accessibility_delegate.cc index f57af83..f4b5ec3 100644 --- a/ash/accessibility/default_accessibility_delegate.cc +++ b/ash/accessibility/default_accessibility_delegate.cc
@@ -40,4 +40,12 @@ return std::numeric_limits<double>::min(); } +void DefaultAccessibilityDelegate::DispatchAccessibilityEvent( + const ui::AXTreeID& tree_id, + const std::vector<ui::AXTreeUpdate>& updates, + const ui::AXEvent& event) {} + +void DefaultAccessibilityDelegate::DispatchTreeDestroyedEvent( + const ui::AXTreeID& tree_id) {} + } // namespace ash
diff --git a/ash/accessibility/default_accessibility_delegate.h b/ash/accessibility/default_accessibility_delegate.h index 4287df6..2f09148 100644 --- a/ash/accessibility/default_accessibility_delegate.h +++ b/ash/accessibility/default_accessibility_delegate.h
@@ -11,6 +11,7 @@ namespace ash { +// Used in tests and non-production code like ash_shell_with_content. class ASH_EXPORT DefaultAccessibilityDelegate : public AccessibilityDelegate { public: DefaultAccessibilityDelegate(); @@ -21,6 +22,10 @@ bool ShouldShowAccessibilityMenu() const override; void SaveScreenMagnifierScale(double scale) override; double GetSavedScreenMagnifierScale() override; + void DispatchAccessibilityEvent(const ui::AXTreeID& tree_id, + const std::vector<ui::AXTreeUpdate>& updates, + const ui::AXEvent& event) override; + void DispatchTreeDestroyedEvent(const ui::AXTreeID& tree_id) override; private: bool screen_magnifier_enabled_ = false;
diff --git a/ash/ash_service.cc b/ash/ash_service.cc index 5ec00b29..399948e4 100644 --- a/ash/ash_service.cc +++ b/ash/ash_service.cc
@@ -203,6 +203,7 @@ service_manager::mojom::ServiceRequest service, const std::string& name, service_manager::mojom::PIDReceiverPtr pid_receiver) { + // TODO(jamescook): Create the AXHostService here under mash. DCHECK_EQ(name, ws::mojom::kServiceName); Shell::Get()->window_service_owner()->BindWindowService(std::move(service)); if (base::FeatureList::IsEnabled(features::kMash)) {
diff --git a/ash/shelf/shelf_tooltip_manager.cc b/ash/shelf/shelf_tooltip_manager.cc index 4c76da5..3f41ada8 100644 --- a/ash/shelf/shelf_tooltip_manager.cc +++ b/ash/shelf/shelf_tooltip_manager.cc
@@ -31,27 +31,29 @@ ShelfTooltipManager::ShelfTooltipManager(ShelfView* shelf_view) : timer_delay_(kTooltipAppearanceDelay), shelf_view_(shelf_view), - bubble_(nullptr), weak_factory_(this) { shelf_view_->shelf()->AddObserver(this); - Shell::Get()->AddPointerWatcher(this, views::PointerWatcherEventTypes::BASIC); + Shell::Get()->AddPreTargetHandler(this); } ShelfTooltipManager::~ShelfTooltipManager() { - Shell::Get()->RemovePointerWatcher(this); + Shell::Get()->RemovePreTargetHandler(this); shelf_view_->shelf()->RemoveObserver(this); if (shelf_view_->GetWidget() && shelf_view_->GetWidget()->GetNativeWindow()) shelf_view_->GetWidget()->GetNativeWindow()->RemovePreTargetHandler(this); } -void ShelfTooltipManager::Init() { - shelf_view_->GetWidget()->GetNativeWindow()->AddPreTargetHandler(this); -} - -void ShelfTooltipManager::Close() { +void ShelfTooltipManager::Close(bool animate) { + // Cancel any timer set to show a tooltip after a delay. timer_.Stop(); - if (bubble_) - bubble_->GetWidget()->Close(); + if (!bubble_) + return; + if (!animate) { + // Cancel the typical hiding animation to hide the bubble immediately. + ::wm::SetWindowVisibilityAnimationTransition( + bubble_->GetWidget()->GetNativeWindow(), ::wm::ANIMATE_NONE); + } + bubble_->GetWidget()->Close(); bubble_ = nullptr; } @@ -64,13 +66,8 @@ } void ShelfTooltipManager::ShowTooltip(views::View* view) { - timer_.Stop(); - if (bubble_) { - // Cancel the hiding animation to hide the old bubble immediately. - ::wm::SetWindowVisibilityAnimationTransition( - bubble_->GetWidget()->GetNativeWindow(), ::wm::ANIMATE_NONE); - Close(); - } + // Hide the old bubble immediately, skipping the typical closing animation. + Close(false /*animate*/); if (!ShouldShowTooltipForView(view)) return; @@ -115,37 +112,23 @@ } } -void ShelfTooltipManager::OnPointerEventObserved( - const ui::PointerEvent& event, - const gfx::Point& location_in_screen, - gfx::NativeView target) { - if (event.type() != ui::ET_POINTER_DOWN || !bubble_) - return; - - // If the click was outside the tooltip, always close it. - if (!bubble_->GetWidget()->GetWindowBoundsInScreen().Contains( - location_in_screen)) { - Close(); - return; - } - - // Close the bubble if appropriate. - if (bubble_->ShouldCloseOnPressDown()) - Close(); -} - void ShelfTooltipManager::OnMouseEvent(ui::MouseEvent* event) { - if (event->type() == ui::ET_MOUSE_EXITED) { - if (bubble_ && bubble_->ShouldCloseOnMouseExit()) - Close(); - - // Don't show any tooltip we were planning on showing after a delay. - timer_.Stop(); + if (bubble_ && event->type() == ui::ET_MOUSE_PRESSED) { + ProcessPressedEvent(*event); return; } - if (event->type() != ui::ET_MOUSE_MOVED) + if (bubble_ && event->type() == ui::ET_MOUSE_EXITED && + bubble_->ShouldCloseOnMouseExit()) { + Close(); return; + } + + // The code below handles mouse move events within the shelf window. + if (event->type() != ui::ET_MOUSE_MOVED || + event->target() != shelf_view_->GetWidget()->GetNativeWindow()) { + return; + } gfx::Point point = event->location(); views::View::ConvertPointFromWidget(shelf_view_, &point); @@ -161,6 +144,11 @@ Close(); } +void ShelfTooltipManager::OnTouchEvent(ui::TouchEvent* event) { + if (bubble_ && event->type() == ui::ET_TOUCH_PRESSED) + ProcessPressedEvent(*event); +} + void ShelfTooltipManager::WillChangeVisibilityState( ShelfVisibilityState new_state) { if (new_state == SHELF_HIDDEN) @@ -168,15 +156,8 @@ } void ShelfTooltipManager::OnAutoHideStateChanged(ShelfAutoHideState new_state) { - if (new_state == SHELF_AUTO_HIDE_HIDDEN) { - timer_.Stop(); - // AutoHide state change happens during an event filter, so immediate close - // may cause a crash in the HandleMouseEvent() after the filter. So we just - // schedule the Close here. - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, - base::Bind(&ShelfTooltipManager::Close, weak_factory_.GetWeakPtr())); - } + if (new_state == SHELF_AUTO_HIDE_HIDDEN) + Close(); } bool ShelfTooltipManager::ShouldShowTooltipForView(views::View* view) { @@ -188,4 +169,12 @@ shelf->GetAutoHideState() == SHELF_AUTO_HIDE_SHOWN)); } +void ShelfTooltipManager::ProcessPressedEvent(const ui::LocatedEvent& event) { + // Always close the tooltip on press events outside the tooltip. + if (bubble_->ShouldCloseOnPressDown() || + event.target() != bubble_->GetWidget()->GetNativeWindow()) { + Close(); + } +} + } // namespace ash
diff --git a/ash/shelf/shelf_tooltip_manager.h b/ash/shelf/shelf_tooltip_manager.h index c6e0748e..b7ff2a2 100644 --- a/ash/shelf/shelf_tooltip_manager.h +++ b/ash/shelf/shelf_tooltip_manager.h
@@ -7,33 +7,32 @@ #include "ash/ash_export.h" #include "ash/shelf/shelf_observer.h" -#include "ash/shelf/shelf_tooltip_bubble_base.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "base/timer/timer.h" #include "ui/events/event_handler.h" -#include "ui/views/pointer_watcher.h" + +namespace ui { +class LocatedEvent; +} namespace views { class View; } namespace ash { +class ShelfTooltipBubbleBase; class ShelfView; // ShelfTooltipManager manages the tooltip bubble that appears for shelf items. class ASH_EXPORT ShelfTooltipManager : public ui::EventHandler, - public views::PointerWatcher, public ShelfObserver { public: explicit ShelfTooltipManager(ShelfView* shelf_view); ~ShelfTooltipManager() override; - // Initializes the tooltip manager once the shelf is shown. - void Init(); - - // Closes the tooltip. - void Close(); + // Closes the tooltip; uses an animation if |animate| is true. + void Close(bool animate = true); // Returns true if the tooltip is currently visible. bool IsVisible() const; @@ -51,11 +50,7 @@ protected: // ui::EventHandler overrides: void OnMouseEvent(ui::MouseEvent* event) override; - - // views::PointerWatcher overrides: - void OnPointerEventObserved(const ui::PointerEvent& event, - const gfx::Point& location_in_screen, - gfx::NativeView target) override; + void OnTouchEvent(ui::TouchEvent* event) override; // ShelfObserver overrides: void WillChangeVisibilityState(ShelfVisibilityState new_state) override; @@ -68,11 +63,13 @@ // A helper function to check for shelf visibility and view validity. bool ShouldShowTooltipForView(views::View* view); + // A helper function to close the tooltip on mouse and touch press events. + void ProcessPressedEvent(const ui::LocatedEvent& event); + int timer_delay_; base::OneShotTimer timer_; - ShelfView* shelf_view_; - ShelfTooltipBubbleBase* bubble_; + ShelfTooltipBubbleBase* bubble_ = nullptr; base::WeakPtrFactory<ShelfTooltipManager> weak_factory_;
diff --git a/ash/shelf/shelf_tooltip_manager_unittest.cc b/ash/shelf/shelf_tooltip_manager_unittest.cc index 9e3bd615..af4d66df 100644 --- a/ash/shelf/shelf_tooltip_manager_unittest.cc +++ b/ash/shelf/shelf_tooltip_manager_unittest.cc
@@ -9,6 +9,7 @@ #include "ash/public/cpp/shelf_model.h" #include "ash/shelf/app_list_button.h" #include "ash/shelf/shelf.h" +#include "ash/shelf/shelf_tooltip_bubble_base.h" #include "ash/shelf/shelf_view.h" #include "ash/shelf/shelf_view_test_api.h" #include "ash/shell.h" @@ -122,10 +123,6 @@ ASSERT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, GetPrimaryShelf()->auto_hide_behavior()); ASSERT_EQ(SHELF_AUTO_HIDE_HIDDEN, GetPrimaryShelf()->GetAutoHideState()); - - // Tooltip visibility change for auto hide may take time. - EXPECT_TRUE(tooltip_manager_->IsVisible()); - RunAllPendingInMessageLoop(); EXPECT_FALSE(tooltip_manager_->IsVisible()); // Do not show the view if the shelf is hidden.
diff --git a/ash/shelf/shelf_view.cc b/ash/shelf/shelf_view.cc index 9316830..0f91ddd 100644 --- a/ash/shelf/shelf_view.cc +++ b/ash/shelf/shelf_view.cc
@@ -1793,12 +1793,6 @@ node_data->SetName(l10n_util::GetStringUTF8(IDS_ASH_SHELF_ACCESSIBLE_NAME)); } -void ShelfView::ViewHierarchyChanged( - const ViewHierarchyChangedDetails& details) { - if (details.is_add && details.child == this) - tooltip_.Init(); -} - void ShelfView::OnGestureEvent(ui::GestureEvent* event) { // Do not forward events to |shelf_| (which forwards events to the shelf // layout manager) as we do not want gestures on the overflow to open the app
diff --git a/ash/shelf/shelf_view.h b/ash/shelf/shelf_view.h index f2b8206e..81febaa 100644 --- a/ash/shelf/shelf_view.h +++ b/ash/shelf/shelf_view.h
@@ -392,8 +392,6 @@ void OnBoundsChanged(const gfx::Rect& previous_bounds) override; FocusTraversable* GetPaneFocusTraversable() override; void GetAccessibleNodeData(ui::AXNodeData* node_data) override; - void ViewHierarchyChanged( - const ViewHierarchyChangedDetails& details) override; // Overridden from ui::EventHandler: void OnGestureEvent(ui::GestureEvent* event) override;
diff --git a/ash/system/night_light/night_light_feature_pod_controller.cc b/ash/system/night_light/night_light_feature_pod_controller.cc index 518f8eb..31739d8 100644 --- a/ash/system/night_light/night_light_feature_pod_controller.cc +++ b/ash/system/night_light/night_light_feature_pod_controller.cc
@@ -14,6 +14,8 @@ #include "ash/system/tray/tray_popup_utils.h" #include "ash/system/unified/feature_pod_button.h" #include "ash/system/unified/unified_system_tray_controller.h" +#include "base/metrics/histogram_macros.h" +#include "base/metrics/user_metrics.h" #include "ui/base/l10n/l10n_util.h" namespace ash { @@ -47,11 +49,21 @@ DCHECK(features::IsNightLightEnabled()); Shell::Get()->night_light_controller()->Toggle(); UpdateButton(); + + if (Shell::Get()->night_light_controller()->GetEnabled()) { + base::RecordAction( + base::UserMetricsAction("StatusArea_NightLight_Enabled")); + } else { + base::RecordAction( + base::UserMetricsAction("StatusArea_NightLight_Disabled")); + } } void NightLightFeaturePodController::OnLabelPressed() { DCHECK(features::IsNightLightEnabled()); if (TrayPopupUtils::CanOpenWebUISettings()) { + base::RecordAction( + base::UserMetricsAction("StatusArea_NightLight_Settings")); Shell::Get()->system_tray_model()->client_ptr()->ShowDisplaySettings(); tray_controller_->CloseBubble(); }
diff --git a/ash/system/tray/system_tray_item_uma_type.h b/ash/system/tray/system_tray_item_uma_type.h index cf85c4c..c2f34a2 100644 --- a/ash/system/tray/system_tray_item_uma_type.h +++ b/ash/system/tray/system_tray_item_uma_type.h
@@ -41,7 +41,8 @@ UMA_USER = 24, UMA_VPN = 25, UMA_NIGHT_LIGHT = 26, - UMA_COUNT = 27, + UMA_QUIET_MODE = 27, + UMA_COUNT = 28, }; } // namespace ash
diff --git a/ash/system/unified/quiet_mode_feature_pod_controller.cc b/ash/system/unified/quiet_mode_feature_pod_controller.cc index dfbc682..6d43464 100644 --- a/ash/system/unified/quiet_mode_feature_pod_controller.cc +++ b/ash/system/unified/quiet_mode_feature_pod_controller.cc
@@ -10,6 +10,8 @@ #include "ash/strings/grit/ash_strings.h" #include "ash/system/unified/feature_pod_button.h" #include "ash/system/unified/unified_system_tray_controller.h" +#include "base/metrics/histogram_macros.h" +#include "base/metrics/user_metrics.h" #include "ui/base/l10n/l10n_util.h" #include "ui/message_center/message_center.h" @@ -55,6 +57,13 @@ MessageCenter* message_center = MessageCenter::Get(); bool is_quiet_mode = message_center->IsQuietMode(); message_center->SetQuietMode(!is_quiet_mode); + + if (message_center->IsQuietMode()) { + base::RecordAction(base::UserMetricsAction("StatusArea_QuietMode_Enabled")); + } else { + base::RecordAction( + base::UserMetricsAction("StatusArea_QuietMode_Disabled")); + } } void QuietModeFeaturePodController::OnLabelPressed() { @@ -62,7 +71,7 @@ } SystemTrayItemUmaType QuietModeFeaturePodController::GetUmaType() const { - return SystemTrayItemUmaType::UMA_NOT_RECORDED; + return SystemTrayItemUmaType::UMA_QUIET_MODE; } void QuietModeFeaturePodController::OnQuietModeChanged(bool in_quiet_mode) {
diff --git a/ash/system/unified/unified_system_tray_controller.cc b/ash/system/unified/unified_system_tray_controller.cc index a583830..ccbf3be 100644 --- a/ash/system/unified/unified_system_tray_controller.cc +++ b/ash/system/unified/unified_system_tray_controller.cc
@@ -40,6 +40,7 @@ #include "ash/system/unified_accessibility_detailed_view_controller.h" #include "ash/wm/lock_state_controller.h" #include "base/metrics/histogram_macros.h" +#include "base/metrics/user_metrics.h" #include "base/numerics/ranges.h" #include "ui/gfx/animation/slide_animation.h" #include "ui/message_center/message_center.h" @@ -65,6 +66,10 @@ animation_->Reset(model->IsExpandedOnOpen() ? 1.0 : 0.0); animation_->SetSlideDuration(kExpandAnimationDurationMs); animation_->SetTweenType(gfx::Tween::EASE_IN_OUT); + + Shell::Get()->metrics()->RecordUserMetricsAction(UMA_STATUS_AREA_MENU_OPENED); + UMA_HISTOGRAM_BOOLEAN("ChromeOS.SystemTray.IsExpandedOnOpen", + model_->IsExpandedOnOpen()); } UnifiedSystemTrayController::~UnifiedSystemTrayController() = default; @@ -161,6 +166,9 @@ } void UnifiedSystemTrayController::HandleClearAllAction() { + base::RecordAction( + base::UserMetricsAction("StatusArea_Notifications_ClearAll")); + // When the animation is finished, OnClearAllAnimationEnded() is called. unified_view_->ShowClearAllAnimation(); }
diff --git a/ash/wm/base_state.cc b/ash/wm/base_state.cc index 8fef967e..6c9fab23 100644 --- a/ash/wm/base_state.cc +++ b/ash/wm/base_state.cc
@@ -39,6 +39,7 @@ if (event->IsBoundsEvent()) { HandleBoundsEvents(window_state, event); + window_state->UpdatePipRoundedCorners(); return; } DCHECK(event->IsTransitionEvent());
diff --git a/ash/wm/window_state.cc b/ash/wm/window_state.cc index 3d69cce7..d31eec0 100644 --- a/ash/wm/window_state.cc +++ b/ash/wm/window_state.cc
@@ -32,6 +32,7 @@ #include "ui/compositor/scoped_layer_animation_settings.h" #include "ui/display/display.h" #include "ui/display/screen.h" +#include "ui/views/painter.h" #include "ui/wm/core/coordinate_conversion.h" #include "ui/wm/core/ime_util_chromeos.h" #include "ui/wm/core/window_util.h" @@ -40,6 +41,9 @@ namespace wm { namespace { +// TODO(edcourtney): Move this to a PIP specific file, once it's created. +const int kPipRoundedCornerRadius = 8; + bool IsTabletModeEnabled() { return Shell::Get() ->tablet_mode_controller() @@ -660,6 +664,28 @@ CrossFadeAnimation(window_, std::move(old_layer_owner), animation_type); } +void WindowState::UpdatePipRoundedCorners() { + auto* layer = window()->layer(); + if (!IsPip()) { + if (layer) + layer->SetMaskLayer(nullptr); + pip_mask_.reset(); + return; + } + + gfx::Rect bounds = window()->bounds(); + if (layer && (!pip_mask_ || pip_mask_->layer()->size() != bounds.size())) { + layer->SetMaskLayer(nullptr); + pip_mask_ = views::Painter::CreatePaintedLayer( + views::Painter::CreateSolidRoundRectPainter(SK_ColorBLACK, + kPipRoundedCornerRadius)); + pip_mask_->layer()->SetBounds(bounds); + pip_mask_->layer()->SetFillsBoundsOpaquely(false); + layer->SetFillsBoundsOpaquely(false); + layer->SetMaskLayer(pip_mask_->layer()); + } +} + WindowState* GetActiveWindowState() { aura::Window* active = GetActiveWindow(); return active ? GetWindowState(active) : nullptr;
diff --git a/ash/wm/window_state.h b/ash/wm/window_state.h index 92fa9d0..c471434 100644 --- a/ash/wm/window_state.h +++ b/ash/wm/window_state.h
@@ -17,6 +17,7 @@ #include "base/optional.h" #include "ui/aura/window_observer.h" #include "ui/base/ui_base_types.h" +#include "ui/compositor/layer_owner.h" #include "ui/gfx/animation/tween.h" namespace gfx { @@ -399,6 +400,10 @@ const gfx::Rect& bounds, gfx::Tween::Type animation_type = gfx::Tween::EASE_OUT); + // Updates rounded corners for PIP window states. Removes rounded corners + // for non-PIP window states. + void UpdatePipRoundedCorners(); + // aura::WindowObserver: void OnWindowPropertyChanged(aura::Window* window, const void* key, @@ -422,6 +427,9 @@ bool cached_always_on_top_; bool allow_set_bounds_direct_ = false; + // Mask layer for PIP windows. + std::unique_ptr<ui::LayerOwner> pip_mask_ = nullptr; + // A property to save the ratio between snapped window width and display // workarea width. It is used to update snapped window width on // AdjustSnappedBounds() when handling workspace events.
diff --git a/base/BUILD.gn b/base/BUILD.gn index 1ed0b8a..1a4c116b0 100644 --- a/base/BUILD.gn +++ b/base/BUILD.gn
@@ -2973,7 +2973,10 @@ "android/java/src/org/chromium/base/memory/MemoryPressureUma.java", "android/java/src/org/chromium/base/task/AsyncTask.java", "android/java/src/org/chromium/base/task/ChromeThreadPoolExecutor.java", + "android/java/src/org/chromium/base/task/SequencedTaskRunner.java", "android/java/src/org/chromium/base/task/SerialExecutor.java", + "android/java/src/org/chromium/base/task/SingleThreadTaskRunner.java", + "android/java/src/org/chromium/base/task/TaskRunner.java", ] # New versions of BuildConfig.java and NativeLibraries.java
diff --git a/base/android/java/src/org/chromium/base/task/SequencedTaskRunner.java b/base/android/java/src/org/chromium/base/task/SequencedTaskRunner.java new file mode 100644 index 0000000..69118fd2 --- /dev/null +++ b/base/android/java/src/org/chromium/base/task/SequencedTaskRunner.java
@@ -0,0 +1,13 @@ +// 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. + +package org.chromium.base.task; + +/** + * Tasks posted will be run in order with respect to this sequence, but they may be executed + * on arbitrary threads. Unless specified otherwise by the provider of a given + * SequencedTaskRunner, tasks posted to it have no ordering, nor mutual exclusion, execution + * guarantees w.r.t. other SequencedTaskRunners. + */ +public interface SequencedTaskRunner extends TaskRunner {}
diff --git a/base/android/java/src/org/chromium/base/task/SingleThreadTaskRunner.java b/base/android/java/src/org/chromium/base/task/SingleThreadTaskRunner.java new file mode 100644 index 0000000..015b077 --- /dev/null +++ b/base/android/java/src/org/chromium/base/task/SingleThreadTaskRunner.java
@@ -0,0 +1,10 @@ +// 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. + +package org.chromium.base.task; + +/** + * Tasks posted will be run in order on a single thread. + */ +public interface SingleThreadTaskRunner extends SequencedTaskRunner {}
diff --git a/base/android/java/src/org/chromium/base/task/TaskRunner.java b/base/android/java/src/org/chromium/base/task/TaskRunner.java new file mode 100644 index 0000000..0a2eaac --- /dev/null +++ b/base/android/java/src/org/chromium/base/task/TaskRunner.java
@@ -0,0 +1,27 @@ +// 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. + +package org.chromium.base.task; + +/** + * A task queue that posts Java tasks onto the C++ browser scheduler, if loaded. Otherwise this + * will be backed by an {@link android.os.Handler} or the java thread pool. The TaskQueue interface + * provides no guarantee over the order or the thread on which the task will be executed. + * + * Very similar to {@link java.util.concurrent.Executor} but conforms to chromium terminology. + */ +public interface TaskRunner { + /** + * Posts a task to run immediately. + * + * @param task The task to be run immediately. + */ + public void postTask(Runnable task); + + /** + * Instructs the TaskRunner to initialize the native TaskRunner and migrate any tasks over to + * it. + */ + void initNativeTaskRunner(); +}
diff --git a/base/bits.h b/base/bits.h index a1c8b5de..cbd46c08 100644 --- a/base/bits.h +++ b/base/bits.h
@@ -10,6 +10,8 @@ #include <stddef.h> #include <stdint.h> +#include <type_traits> + #include "base/compiler_specific.h" #include "base/logging.h" #include "build/build_config.h"
diff --git a/chrome/VERSION b/chrome/VERSION index 10c3fb7..ac1ecde 100644 --- a/chrome/VERSION +++ b/chrome/VERSION
@@ -1,4 +1,4 @@ MAJOR=71 MINOR=0 -BUILD=3564 +BUILD=3565 PATCH=0
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiController.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiController.java index b66fcea..27cb28a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiController.java
@@ -53,7 +53,7 @@ parameters.keySet().toArray(new String[parameters.size()]), parameters.values().toArray(new String[parameters.size()])); - // Stop Autofill Assistant when the tab is detached from the activity. + // Shut down Autofill Assistant when the tab is detached from the activity. activityTab.addObserver(new EmptyTabObserver() { @Override public void onActivityAttachmentChanged(Tab tab, boolean isAttached) { @@ -64,7 +64,7 @@ } }); - // Stop Autofill Assistant when the selected tab (foreground tab) is changed. + // Shut down Autofill Assistant when the selected tab (foreground tab) is changed. TabModel currentTabModel = activity.getTabModelSelector().getCurrentModel(); currentTabModel.addObserver(new EmptyTabModelObserver() { @Override @@ -122,6 +122,11 @@ } @CalledByNative + private void onShutdown() { + mUiDelegate.shutdown(); + } + + @CalledByNative private void onUpdateScripts(String[] scriptNames, String[] scriptPaths) { List<AutofillAssistantUiDelegate.ScriptHandle> scriptHandles = new ArrayList<>(); // Note that scriptNames and scriptPaths are one-on-one matched by index.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiDelegate.java index 276025a..912ce8d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiDelegate.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiDelegate.java
@@ -103,8 +103,7 @@ mBottomBar.findViewById(R.id.close_button).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - mFullContainer.setVisibility(View.GONE); - mClient.onDismiss(); + shutdown(); } }); mBottomBar.findViewById(R.id.feedback_button) @@ -164,4 +163,12 @@ public void hideOverlay() { mOverlay.setVisibility(View.GONE); } + + /** + * Shuts down the Autofill Assistant. The UI disappears and any associated state goes away. + */ + public void shutdown() { + mFullContainer.setVisibility(View.GONE); + mClient.onDismiss(); + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/ModuleHostImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/ModuleHostImpl.java index c67f6ffb..226921a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/ModuleHostImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/ModuleHostImpl.java
@@ -10,7 +10,7 @@ * The implementation of {@link IModuleHost}. */ public class ModuleHostImpl extends BaseModuleHost { - private static final int VERSION = 3; + private static final int VERSION = 4; private static final int MINIMUM_MODULE_VERSION = 1; private final Context mApplicationContext;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/SadTabViewFactory.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/SadTab.java similarity index 60% rename from chrome/android/java/src/org/chromium/chrome/browser/tab/SadTabViewFactory.java rename to chrome/android/java/src/org/chromium/chrome/browser/tab/SadTab.java index 6694ec7..3aa1d277 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tab/SadTabViewFactory.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/SadTab.java
@@ -4,6 +4,7 @@ package org.chromium.chrome.browser.tab; +import android.app.Activity; import android.content.Context; import android.graphics.Canvas; import android.graphics.Paint; @@ -16,35 +17,170 @@ import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; +import android.widget.FrameLayout; +import android.widget.FrameLayout.LayoutParams; import android.widget.TextView; +import org.chromium.base.UserData; +import org.chromium.base.VisibleForTesting; import org.chromium.base.metrics.RecordHistogram; import org.chromium.chrome.R; import org.chromium.chrome.browser.ChromeFeatureList; +import org.chromium.chrome.browser.help.HelpAndFeedback; +import org.chromium.chrome.browser.profiles.Profile; import org.chromium.components.ui_metrics.SadTabEvent; +import org.chromium.content_public.browser.LoadUrlParams; import org.chromium.ui.text.NoUnderlineClickableSpan; import org.chromium.ui.text.SpanApplier; import org.chromium.ui.text.SpanApplier.SpanInfo; /** - * A factory class for creating the "Sad Tab" view, which is shown in place of a crashed renderer. + * Represent the sad tab displayed in place of a crashed renderer. Instantiated on the first + * |show()| request from a Tab, and destroyed together with it. */ -public class SadTabViewFactory { +public class SadTab extends EmptyTabObserver implements UserData { + private static final Class<SadTab> USER_DATA_KEY = SadTab.class; + + private final Tab mTab; + + private View mView; + /** - * @param context Context of the resulting Sad Tab view. + * Counts the number of successive refreshes on the sad tab page. The count is is reset after a + * successful page load. + */ + private int mSadTabSuccessiveRefreshCounter; + + public static SadTab from(Tab tab) { + SadTab sadTab = get(tab); + if (sadTab == null) { + sadTab = tab.getUserDataHost().setUserData(USER_DATA_KEY, new SadTab(tab)); + } + return sadTab; + } + + public static SadTab get(Tab tab) { + return tab.getUserDataHost().getUserData(USER_DATA_KEY); + } + + public static boolean isShowing(Tab tab) { + SadTab sadTab = get(tab); + return sadTab != null ? sadTab.isShowing() : false; + } + + @VisibleForTesting + public SadTab(Tab tab) { + mTab = tab; + mTab.addObserver(this); + } + + /** + * Constructs and shows a sad tab (Aw, Snap!). + */ + public void show() { + if (mTab.getWebContents() == null) return; + + // Make sure we are not adding the "Aw, snap" view over an existing one. + assert mView == null; + + // If the tab has crashed twice in a row change the sad tab view to the "Send Feedback" + // version and change the onClickListener. + final boolean showSendFeedbackView = mSadTabSuccessiveRefreshCounter >= 1; + + Runnable suggestionAction = new Runnable() { + @Override + public void run() { + Activity activity = mTab.getWindowAndroid().getActivity().get(); + assert activity != null; + HelpAndFeedback.getInstance(activity).show(activity, + activity.getString(R.string.help_context_sad_tab), + Profile.getLastUsedProfile(), null); + } + }; + + Runnable buttonAction = new Runnable() { + @Override + public void run() { + if (showSendFeedbackView) { + mTab.getActivity().startHelpAndFeedback( + mTab.getUrl(), "MobileSadTabFeedback", mTab.getProfile()); + } else { + mTab.reload(); + } + } + }; + + mView = createView( + suggestionAction, buttonAction, showSendFeedbackView, mTab.isIncognito()); + mSadTabSuccessiveRefreshCounter++; + + // Show the sad tab inside ContentView. + mTab.getContentView().addView(mView, + new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); + mTab.notifyContentChanged(); + } + + /** + * Removes the sad tab view if present. + */ + @VisibleForTesting + void removeIfPresent() { + if (isShowing()) { + mTab.getContentView().removeView(mView); + mTab.notifyContentChanged(); + } + mView = null; + } + + /** + * @return Whether or not the sad tab is showing. + */ + public boolean isShowing() { + return mView != null && mView.getParent() == mTab.getContentView(); + } + + // TabObserver + + @Override + public void onLoadUrl(Tab tab, LoadUrlParams params, int loadType) { + removeIfPresent(); + } + + @Override + public void onPageLoadStarted(Tab tab, String url) { + removeIfPresent(); + } + + @Override + public void onPageLoadFinished(Tab tab) { + // Reset the succressiveRefresh counter after successfully loading a page. + mSadTabSuccessiveRefreshCounter = 0; + removeIfPresent(); + } + + // UserData + + @Override + public void destroy() { + mTab.removeObserver(this); + } + + /** * @param suggestionAction {@link Runnable} to be executed when user clicks "try these * suggestions". * @param buttonAction {@link Runnable} to be executed when the button is pressed. * (e.g., refreshing the page or sending feedback) * @param showSendFeedbackView Whether to show the "send feedback" version of the Sad Tab view. * @param isIncognito Whether the Sad Tab view is being showin in an incognito tab. - * @return A "Sad Tab" view instance which is used in place of a crashed renderer. + * @return A {@link View} instance which is used in place of a crashed renderer. */ - public static View createSadTabView(Context context, final Runnable suggestionAction, - final Runnable buttonAction, final boolean showSendFeedbackView, boolean isIncognito) { + protected View createView(final Runnable suggestionAction, Runnable buttonAction, + boolean showSendFeedbackView, boolean isIncognito) { + Context context = mTab.getThemedApplicationContext(); + // Inflate Sad tab and initialize. - LayoutInflater inflater = (LayoutInflater) context.getSystemService( - Context.LAYOUT_INFLATER_SERVICE); + LayoutInflater inflater = + (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); View sadTabView = inflater.inflate(R.layout.sad_tab, null); TextView titleText = (TextView) sadTabView.findViewById(R.id.sad_tab_title); @@ -65,12 +201,12 @@ button.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { - SadTabViewFactory.recordEvent(showSendFeedbackView, SadTabEvent.BUTTON_CLICKED); + recordEvent(showSendFeedbackView, SadTabEvent.BUTTON_CLICKED); buttonAction.run(); } }); - SadTabViewFactory.recordEvent(showSendFeedbackView, SadTabEvent.DISPLAYED); + recordEvent(showSendFeedbackView, SadTabEvent.DISPLAYED); return sadTabView; } @@ -85,7 +221,7 @@ private static CharSequence getHelpMessage( Context context, final Runnable suggestionAction, final boolean showSendFeedback) { NoUnderlineClickableSpan linkSpan = new NoUnderlineClickableSpan((view) -> { - SadTabViewFactory.recordEvent(showSendFeedback, SadTabEvent.HELP_LINK_CLICKED); + recordEvent(showSendFeedback, SadTabEvent.HELP_LINK_CLICKED); suggestionAction.run(); }); @@ -179,4 +315,10 @@ c, p, x + mXOffset, dir, top, baseline, bottom, text, start, end, first, l); } } + + // Bare minimum set up so |isShowing| returns true. + @VisibleForTesting + public static void initForTesting(Tab tab, SadTab sadTab) { + tab.getUserDataHost().setUserData(USER_DATA_KEY, sadTab); + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java index caeceb16..bb77bdb 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java
@@ -27,7 +27,6 @@ import android.view.accessibility.AccessibilityEvent; import android.widget.Button; import android.widget.FrameLayout; -import android.widget.FrameLayout.LayoutParams; import android.widget.PopupWindow; import android.widget.PopupWindow.OnDismissListener; @@ -67,7 +66,6 @@ import org.chromium.chrome.browser.feature_engagement.TrackerFactory; import org.chromium.chrome.browser.fullscreen.FullscreenManager; import org.chromium.chrome.browser.fullscreen.FullscreenOptions; -import org.chromium.chrome.browser.help.HelpAndFeedback; import org.chromium.chrome.browser.infobar.InfoBarContainer; import org.chromium.chrome.browser.media.ui.MediaSessionTabHelper; import org.chromium.chrome.browser.native_page.FrozenNativePage; @@ -371,17 +369,6 @@ private boolean mIsDetached; /** - * Reference to the current sadTabView if one is defined. - */ - private View mSadTabView; - - /** - * Counts the number of successive refreshes on the sad tab page. The count is is reset after a - * successful page load. - */ - private int mSadTabSuccessiveRefreshCounter; - - /** * Stores total data saved at the start of a page load. Used to calculate delta at the end of * page load, which is just an estimate of the data saved for the current page load since there * may be multiple pages loading at the same time. This estimate is used to get an idea of how @@ -714,8 +701,6 @@ mIsNativePageCommitPending = maybeShowNativePage(params.getUrl(), false); } - removeSadTabIfPresent(); - // Clear the app association if the user navigated to a different page from the omnibox. if ((params.getTransitionType() & PageTransition.FROM_ADDRESS_BAR) == PageTransition.FROM_ADDRESS_BAR) { @@ -1617,7 +1602,6 @@ */ protected void didStartPageLoad(String validatedUrl, boolean showingErrorPage) { updateTitle(); - removeSadTabIfPresent(); mDataSavedOnStartPageLoad = DataReductionProxySettings.getInstance().getContentLengthSavedInHistorySummary(); @@ -1634,9 +1618,6 @@ updateTitle(); updateFullscreenEnabledState(); - // Reset the succressiveRefresh counter after successfully loading a page. - mSadTabSuccessiveRefreshCounter = 0; - for (TabObserver observer : mObservers) observer.onPageLoadFinished(this); mIsBeingRestored = false; @@ -1900,72 +1881,6 @@ } /** - * Constructs and shows a sad tab (Aw, Snap!). - */ - protected void showSadTab() { - if (getWebContents() == null) return; - - // If the tab has crashed twice in a row change the sad tab view to the "Send Feedback" - // version and change the onClickListener. - final boolean showSendFeedbackView = mSadTabSuccessiveRefreshCounter >= 1; - - Runnable suggestionAction = new Runnable() { - @Override - public void run() { - Activity activity = mWindowAndroid.getActivity().get(); - assert activity != null; - HelpAndFeedback.getInstance(activity).show(activity, - activity.getString(R.string.help_context_sad_tab), - Profile.getLastUsedProfile(), null); - } - }; - - Runnable buttonAction = new Runnable() { - @Override - public void run() { - if (showSendFeedbackView) { - getActivity().startHelpAndFeedback( - getUrl(), "MobileSadTabFeedback", getProfile()); - } else { - reload(); - } - } - }; - - // Make sure we are not adding the "Aw, snap" view over an existing one. - assert mSadTabView == null; - - mSadTabView = SadTabViewFactory.createSadTabView(mThemedApplicationContext, - suggestionAction, buttonAction, showSendFeedbackView, mIncognito); - mSadTabSuccessiveRefreshCounter++; - // Show the sad tab inside ContentView. - mContentView.addView(mSadTabView, - new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); - notifyContentChanged(); - } - - /** - * Removes the sad tab view if present. - */ - private void removeSadTabIfPresent() { - if (isShowingSadTab()) { - mContentView.removeView(mSadTabView); - notifyContentChanged(); - } - mSadTabView = null; - } - - /** - * Removes any existing sad tab view and shows it again. This "reloads" the tab without - * going through any formal loading logic. - */ - @VisibleForTesting - public void reloadSadTabForTesting() { - removeSadTabIfPresent(); - showSadTab(); - } - - /** * @return The ID of the renderer process that backs this tab or * {@link #INVALID_RENDER_PROCESS_PID} if there is none. */ @@ -1979,13 +1894,13 @@ * @return Whether or not the sad tab is showing. */ public boolean isShowingSadTab() { - return mSadTabView != null && mSadTabView.getParent() == mContentView; + return SadTab.isShowing(this); } /** * Calls onContentChanged on all TabObservers and updates accessibility visibility. */ - private void notifyContentChanged() { + void notifyContentChanged() { for (TabObserver observer : mObservers) observer.onContentChanged(this); updateAccessibilityVisibility(); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabWebContentsObserver.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabWebContentsObserver.java index 6eebfec..766c09e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabWebContentsObserver.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabWebContentsObserver.java
@@ -122,7 +122,7 @@ } } else { rendererCrashStatus = TAB_RENDERER_CRASH_STATUS_SHOWN_IN_FOREGROUND_APP; - mTab.showSadTab(); + SadTab.from(mTab).show(); // This is necessary to correlate histogram data with stability counts. RecordHistogram.recordBooleanHistogram("Stability.Android.RendererCrash", true); }
diff --git a/chrome/android/java_sources.gni b/chrome/android/java_sources.gni index 3caaf8b2..14b2c4c 100644 --- a/chrome/android/java_sources.gni +++ b/chrome/android/java_sources.gni
@@ -1431,8 +1431,8 @@ "java/src/org/chromium/chrome/browser/tab/ChildBackgroundTabShowObserver.java", "java/src/org/chromium/chrome/browser/tab/EmptyTabObserver.java", "java/src/org/chromium/chrome/browser/tab/InterceptNavigationDelegateImpl.java", + "java/src/org/chromium/chrome/browser/tab/SadTab.java", "java/src/org/chromium/chrome/browser/tab/SadTabView.java", - "java/src/org/chromium/chrome/browser/tab/SadTabViewFactory.java", "java/src/org/chromium/chrome/browser/tab/Tab.java", "java/src/org/chromium/chrome/browser/tab/TabBrowserControlsOffsetHelper.java", "java/src/org/chromium/chrome/browser/tab/TabContextMenuItemDelegate.java",
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/TabTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/TabTest.java index c766786..b753ac57 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/TabTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/TabTest.java
@@ -51,6 +51,10 @@ } }; + private boolean isShowingSadTab() throws Exception { + return ThreadUtils.runOnUiThreadBlocking(() -> mTab.isShowingSadTab()); + } + @Before public void setUp() throws Exception { mActivityTestRule.startMainActivityOnBlankPage(); @@ -101,7 +105,7 @@ Assert.assertFalse(mTab.needsReload()); Assert.assertFalse(mTab.isHidden()); - Assert.assertFalse(mTab.isShowingSadTab()); + Assert.assertFalse(isShowingSadTab()); // Stop the activity and simulate a killed renderer. ApplicationTestUtils.fireHomeScreenIntent(InstrumentationRegistry.getTargetContext()); @@ -114,7 +118,7 @@ } }); Assert.assertTrue(mTab.needsReload()); - Assert.assertFalse(mTab.isShowingSadTab()); + Assert.assertFalse(isShowingSadTab()); ApplicationTestUtils.launchChrome(InstrumentationRegistry.getTargetContext()); @@ -126,7 +130,7 @@ } }); Assert.assertFalse(mTab.needsReload()); - Assert.assertFalse(mTab.isShowingSadTab()); + Assert.assertFalse(isShowingSadTab()); } @Test
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/infobar/InfoBarTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/infobar/InfoBarTest.java index 09b6935..e3e7bbf 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/infobar/InfoBarTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/infobar/InfoBarTest.java
@@ -592,7 +592,7 @@ // The renderer should have been killed and the InfoBar removed. mListener.removeInfoBarAnimationFinished("InfoBar not removed."); Assert.assertTrue("Wrong infobar count", mActivityTestRule.getInfoBars().isEmpty()); - CriteriaHelper.pollInstrumentationThread(new Criteria() { + CriteriaHelper.pollUiThread(new Criteria() { @Override public boolean isSatisfied() { return mActivityTestRule.getActivity().getActivityTab().isShowingSadTab();
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/photo_picker/PhotoPickerDialogTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/photo_picker/PhotoPickerDialogTest.java index fa10c22..ab05ac3 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/photo_picker/PhotoPickerDialogTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/photo_picker/PhotoPickerDialogTest.java
@@ -6,6 +6,7 @@ import static org.chromium.base.test.util.ScalableTimeout.scaleTimeout; +import android.os.Build; import android.support.test.filters.LargeTest; import android.support.v7.widget.RecyclerView; import android.view.View; @@ -20,7 +21,7 @@ import org.chromium.base.ThreadUtils; import org.chromium.base.test.util.CallbackHelper; import org.chromium.base.test.util.CommandLineFlags; -import org.chromium.base.test.util.DisabledTest; +import org.chromium.base.test.util.DisableIf; import org.chromium.chrome.R; import org.chromium.chrome.browser.ChromeActivity; import org.chromium.chrome.browser.ChromeSwitches; @@ -198,12 +199,8 @@ }); } - /** - * Continues to be flaky on bots which doesn't reproduce on local devices, - * continuing to investigate offline. - */ @Test - @DisabledTest(message = "crbug.com/761060") + @DisableIf.Build(sdk_is_less_than = Build.VERSION_CODES.LOLLIPOP, message = "crbug.com/761060") @LargeTest public void testNoSelection() throws Throwable { createDialog(false, Arrays.asList("image/*")); // Multi-select = false. @@ -220,12 +217,8 @@ dismissDialog(); } - /** - * Continues to be flaky on bots which doesn't reproduce on local devices, - * continuing to investigate offline. - */ @Test - @DisabledTest(message = "crbug.com/761060") + @DisableIf.Build(sdk_is_less_than = Build.VERSION_CODES.LOLLIPOP, message = "crbug.com/761060") @LargeTest public void testSingleSelectionPhoto() throws Throwable { createDialog(false, Arrays.asList("image/*")); // Multi-select = false. @@ -245,12 +238,8 @@ dismissDialog(); } - /** - * Continues to be flaky on bots which doesn't reproduce on local devices, - * continuing to investigate offline. - */ @Test - @DisabledTest(message = "crbug.com/761060") + @DisableIf.Build(sdk_is_less_than = Build.VERSION_CODES.LOLLIPOP, message = "crbug.com/761060") @LargeTest public void testMultiSelectionPhoto() throws Throwable { createDialog(true, Arrays.asList("image/*")); // Multi-select = true.
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/tab/SadTabTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/tab/SadTabTest.java index d3e2dec..7740228 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/tab/SadTabTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/tab/SadTabTest.java
@@ -25,6 +25,8 @@ import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.net.test.util.TestWebServer; +import java.util.concurrent.ExecutionException; + /** * Tests related to the sad tab logic. */ @@ -41,6 +43,14 @@ mActivityTestRule.startMainActivityOnBlankPage(); } + private static boolean isShowingSadTab(Tab tab) { + try { + return ThreadUtils.runOnUiThreadBlocking(() -> tab.isShowingSadTab()); + } catch (ExecutionException e) { + return false; + } + } + /** * Verify that the sad tab is shown when the renderer crashes. */ @@ -50,9 +60,9 @@ public void testSadTabShownWhenRendererProcessKilled() { final Tab tab = mActivityTestRule.getActivity().getActivityTab(); - Assert.assertFalse(tab.isShowingSadTab()); + Assert.assertFalse(isShowingSadTab(tab)); simulateRendererKilled(tab, true); - Assert.assertTrue(tab.isShowingSadTab()); + Assert.assertTrue(isShowingSadTab(tab)); } /** @@ -65,9 +75,9 @@ public void testSadTabNotShownWhenRendererProcessKilledInBackround() { final Tab tab = mActivityTestRule.getActivity().getActivityTab(); - Assert.assertFalse(tab.isShowingSadTab()); + Assert.assertFalse(isShowingSadTab(tab)); simulateRendererKilled(tab, false); - Assert.assertFalse(tab.isShowingSadTab()); + Assert.assertFalse(isShowingSadTab(tab)); } /** @@ -127,16 +137,16 @@ public void testSadTabPageButtonText() throws IllegalArgumentException, InterruptedException { final Tab tab = mActivityTestRule.getActivity().getActivityTab(); - Assert.assertFalse(tab.isShowingSadTab()); + Assert.assertFalse(isShowingSadTab(tab)); simulateRendererKilled(tab, true); - Assert.assertTrue(tab.isShowingSadTab()); + Assert.assertTrue(isShowingSadTab(tab)); String actualText = getSadTabButton(tab).getText().toString(); Assert.assertEquals("Expected the sad tab button to have the reload label", mActivityTestRule.getActivity().getString(R.string.sad_tab_reload_label), actualText); reloadSadTab(tab); - Assert.assertTrue(tab.isShowingSadTab()); + Assert.assertTrue(isShowingSadTab(tab)); actualText = getSadTabButton(tab).getText().toString(); Assert.assertEquals( "Expected the sad tab button to have the feedback label after the tab button " @@ -147,7 +157,7 @@ Assert.assertFalse( "Expected about:blank to destroy the sad tab however the sad tab is still in " + "view", - tab.isShowingSadTab()); + isShowingSadTab(tab)); simulateRendererKilled(tab, true); actualText = getSadTabButton(tab).getText().toString(); Assert.assertEquals( @@ -159,7 +169,7 @@ /** * Helper method that kills the renderer on a UI thread. */ - private void simulateRendererKilled(final Tab tab, final boolean visible) { + private static void simulateRendererKilled(final Tab tab, final boolean visible) { ThreadUtils.runOnUiThreadBlocking(new Runnable() { @Override public void run() { @@ -172,11 +182,13 @@ /** * Helper method that reloads a tab with a SadTabView currently displayed. */ - private void reloadSadTab(final Tab tab) { + private static void reloadSadTab(final Tab tab) { ThreadUtils.runOnUiThreadBlocking(new Runnable() { @Override public void run() { - tab.reloadSadTabForTesting(); + SadTab sadTab = SadTab.from(tab); + sadTab.removeIfPresent(); + sadTab.show(); } }); } @@ -187,7 +199,7 @@ * @return Returns the button that is on the SadTabView, null if SadTabView. * doesn't exist. */ - private Button getSadTabButton(Tab tab) { + private static Button getSadTabButton(Tab tab) { return (Button) tab.getContentView().findViewById(R.id.sad_tab_button); }
diff --git a/chrome/android/profiles/newest.txt b/chrome/android/profiles/newest.txt index c34910d..4724b19 100644 --- a/chrome/android/profiles/newest.txt +++ b/chrome/android/profiles/newest.txt
@@ -1 +1 @@ -chromeos-chrome-amd64-71.0.3561.0_rc-r1.afdo.bz2 \ No newline at end of file +chromeos-chrome-amd64-71.0.3563.0_rc-r1.afdo.bz2 \ No newline at end of file
diff --git a/chrome/app_shim/BUILD.gn b/chrome/app_shim/BUILD.gn index 8e5763f8..06cbaf0 100644 --- a/chrome/app_shim/BUILD.gn +++ b/chrome/app_shim/BUILD.gn
@@ -18,8 +18,10 @@ "//chrome:strings", "//chrome/common", "//chrome/common:mojo_bindings", + "//content/public/browser", "//ipc", "//mojo/core/embedder", + "//ui/accelerated_widget_mac", "//ui/base", "//ui/views:views", ]
diff --git a/chrome/app_shim/DEPS b/chrome/app_shim/DEPS index 90bfe99..7bca52a8 100644 --- a/chrome/app_shim/DEPS +++ b/chrome/app_shim/DEPS
@@ -1,5 +1,6 @@ include_rules = [ "+chrome/grit/generated_resources.h", "+chrome/installer/launcher_support", + "+content/public/browser", "+mojo/core/embedder", ]
diff --git a/chrome/app_shim/chrome_main_app_mode_mac.mm b/chrome/app_shim/chrome_main_app_mode_mac.mm index 208384cd..6f345237 100644 --- a/chrome/app_shim/chrome_main_app_mode_mac.mm +++ b/chrome/app_shim/chrome_main_app_mode_mac.mm
@@ -37,11 +37,14 @@ #include "chrome/common/mac/app_shim.mojom.h" #include "chrome/common/mac/app_shim_param_traits.h" #include "chrome/grit/generated_resources.h" +#include "content/public/browser/ns_view_bridge_factory_impl.h" +#include "content/public/common/ns_view_bridge_factory.mojom.h" #include "mojo/core/embedder/embedder.h" #include "mojo/core/embedder/scoped_ipc_support.h" #include "mojo/public/cpp/bindings/binding.h" #include "mojo/public/cpp/platform/named_platform_channel.h" #include "mojo/public/cpp/system/isolated_connection.h" +#include "ui/accelerated_widget_mac/window_resize_helper_mac.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/resource/resource_bundle.h" #include "ui/views/cocoa/bridge_factory_impl.h" @@ -131,6 +134,8 @@ void LaunchAppDone(apps::AppShimLaunchResult result) override; void CreateViewsBridgeFactory( views_bridge_mac::mojom::BridgeFactoryRequest request) override; + void CreateContentNSViewBridgeFactory( + content::mojom::NSViewBridgeFactoryAssociatedRequest request) override; void Hide() override; void UnhideWithoutActivation() override; void SetUserAttention(apps::AppShimAttentionType attention_type) override; @@ -313,6 +318,11 @@ views_bridge_mac::BridgeFactoryImpl::Get()->BindRequest(std::move(request)); } +void AppShimController::CreateContentNSViewBridgeFactory( + content::mojom::NSViewBridgeFactoryAssociatedRequest request) { + content::NSViewBridgeFactoryImpl::Get()->BindRequest(std::move(request)); +} + void AppShimController::Hide() { [NSApp hide:nil]; } @@ -650,6 +660,7 @@ AppShimController controller; base::MessageLoopForUI main_message_loop; base::PlatformThread::SetName("CrAppShimMain"); + ui::WindowResizeHelperMac::Get()->Init(base::ThreadTaskRunnerHandle::Get()); // In tests, launching Chrome does nothing, and we won't get a ping response, // so just assume the socket exists.
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 7b601373..f54ffe17 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -2927,6 +2927,8 @@ "status_icons/desktop_notification_balloon.h", "sync/glue/extension_data_type_controller.cc", "sync/glue/extension_data_type_controller.h", + "sync/glue/extension_model_type_controller.cc", + "sync/glue/extension_model_type_controller.h", "sync/glue/extension_setting_data_type_controller.cc", "sync/glue/extension_setting_data_type_controller.h", "sync/glue/theme_data_type_controller.cc", @@ -3973,12 +3975,13 @@ deps += [ "//media/mojo/interfaces" ] if (enable_widevine) { - # TODO(crbug.com/349182): Also check WIDEVINE_CDM_IS_COMPONENT. - sources += [ - "component_updater/widevine_cdm_component_installer.cc", - "component_updater/widevine_cdm_component_installer.h", - ] - deps += [ "//third_party/widevine/cdm:headers" ] + if (enable_widevine_cdm_component) { + sources += [ + "component_updater/widevine_cdm_component_installer.cc", + "component_updater/widevine_cdm_component_installer.h", + ] + deps += [ "//third_party/widevine/cdm:headers" ] + } if (is_win) { sources += [ "media/widevine_hardware_caps_win.cc",
diff --git a/chrome/browser/DEPS b/chrome/browser/DEPS index 7793cb5d..5ce5910 100644 --- a/chrome/browser/DEPS +++ b/chrome/browser/DEPS
@@ -215,11 +215,8 @@ specific_include_rules = { "ash_service_registry\.cc": [ - # The following are needed for classic mode to create the WindowService. - # Once Ash runs out of process no longer needed. - "+ash/shell.h", - # Needed for classic mode. + "+ash/accessibility/ax_host_service.h", "+ash/ash_service.h", ], # TODO(mash): Fix. https://crbug.com/768439, https://crbug.com/768395.
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index da2e0dc..d770b45 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -3298,11 +3298,6 @@ #endif // OS_CHROMEOS #if defined(OS_CHROMEOS) - {"enable-zip-archiver-packer", - flag_descriptions::kEnableZipArchiverPackerName, - flag_descriptions::kEnableZipArchiverPackerDescription, kOsCrOS, - ENABLE_DISABLE_VALUE_TYPE(chromeos::switches::kEnableZipArchiverPacker, - chromeos::switches::kDisableZipArchiverPacker)}, {"enable-zip-archiver-unpacker", flag_descriptions::kZipArchiverUnpackerName, flag_descriptions::kZipArchiverUnpackerDescription, kOsCrOS,
diff --git a/chrome/browser/android/autofill_assistant/ui_controller_android.cc b/chrome/browser/android/autofill_assistant/ui_controller_android.cc index ca13abc..b217fbc40 100644 --- a/chrome/browser/android/autofill_assistant/ui_controller_android.cc +++ b/chrome/browser/android/autofill_assistant/ui_controller_android.cc
@@ -87,6 +87,11 @@ AttachCurrentThread(), java_autofill_assistant_ui_controller_); } +void UiControllerAndroid::Shutdown() { + Java_AutofillAssistantUiController_onShutdown( + AttachCurrentThread(), java_autofill_assistant_ui_controller_); +} + void UiControllerAndroid::UpdateScripts( const std::vector<ScriptHandle>& scripts) { std::vector<std::string> script_paths;
diff --git a/chrome/browser/android/autofill_assistant/ui_controller_android.h b/chrome/browser/android/autofill_assistant/ui_controller_android.h index 3e04ded..df4a9d7 100644 --- a/chrome/browser/android/autofill_assistant/ui_controller_android.h +++ b/chrome/browser/android/autofill_assistant/ui_controller_android.h
@@ -30,6 +30,7 @@ void ShowStatusMessage(const std::string& message) override; void ShowOverlay() override; void HideOverlay() override; + void Shutdown() override; void UpdateScripts(const std::vector<ScriptHandle>& scripts) override; void ChooseAddress( base::OnceCallback<void(const std::string&)> callback) override;
diff --git a/chrome/browser/android/download/video_frame_thumbnail_converter.cc b/chrome/browser/android/download/video_frame_thumbnail_converter.cc index 0b38ed6..208c34e 100644 --- a/chrome/browser/android/download/video_frame_thumbnail_converter.cc +++ b/chrome/browser/android/download/video_frame_thumbnail_converter.cc
@@ -38,8 +38,7 @@ cc::SkiaPaintCanvas canvas(skbitmap); renderer.Copy(frame, &canvas, media::Context3D(context_provider_->ContextGL(), - context_provider_->GrContext()), - context_provider_->ContextSupport()); + context_provider_->GrContext())); std::move(pixel_callback).Run(true, std::move(skbitmap)); }
diff --git a/chrome/browser/apps/app_shim/app_shim_host_mac.cc b/chrome/browser/apps/app_shim/app_shim_host_mac.cc index adbe53af..5a148b2 100644 --- a/chrome/browser/apps/app_shim/app_shim_host_mac.cc +++ b/chrome/browser/apps/app_shim/app_shim_host_mac.cc
@@ -11,7 +11,10 @@ #include "base/logging.h" #include "chrome/browser/apps/app_shim/app_shim_handler_mac.h" #include "content/public/browser/browser_thread.h" +#include "content/public/browser/ns_view_bridge_factory_host.h" +#include "content/public/common/ns_view_bridge_factory.mojom.h" #include "ui/base/ui_base_features.h" +#include "ui/views/cocoa/bridge_factory_host.h" #include "ui/views_bridge_mac/mojo/bridge_factory.mojom.h" AppShimHost::AppShimHost() @@ -65,14 +68,25 @@ return; app_shim_ = std::move(app_shim_ptr); - // Create the interface that will be used by views::NativeWidgetMac to create - // NSWindows hosted in the app shim process. if (features::HostWindowsInAppShimProcess()) { + // Create the interface that will be used by views::NativeWidgetMac to + // create NSWindows hosted in the app shim process. views_bridge_mac::mojom::BridgeFactoryRequest views_bridge_factory_request; views_bridge_factory_host_ = std::make_unique<views::BridgeFactoryHost>( &views_bridge_factory_request); app_shim_->CreateViewsBridgeFactory( std::move(views_bridge_factory_request)); + + // Create the interface that will be used content::RenderWidgetHostView to + // create NSViews hosted in the app shim process. + content::mojom::NSViewBridgeFactoryAssociatedRequest + content_bridge_factory_request; + content_bridge_factory_ = + std::make_unique<content::NSViewBridgeFactoryHost>( + &content_bridge_factory_request, + views_bridge_factory_host_->GetHostId()); + app_shim_->CreateContentNSViewBridgeFactory( + std::move(content_bridge_factory_request)); } profile_path_ = profile_dir; app_id_ = app_id;
diff --git a/chrome/browser/apps/app_shim/app_shim_host_mac.h b/chrome/browser/apps/app_shim/app_shim_host_mac.h index 6a45f791..73a76d1 100644 --- a/chrome/browser/apps/app_shim/app_shim_host_mac.h +++ b/chrome/browser/apps/app_shim/app_shim_host_mac.h
@@ -16,7 +16,14 @@ #include "mojo/public/cpp/bindings/binding.h" #include "mojo/public/cpp/platform/platform_channel_endpoint.h" #include "mojo/public/cpp/system/isolated_connection.h" -#include "ui/views/cocoa/bridge_factory_host.h" + +namespace content { +class NSViewBridgeFactoryHost; +} // namespace content + +namespace views { +class BridgeFactoryHost; +} // namespace views // This is the counterpart to AppShimController in // chrome/app/chrome_main_app_mode_mac.mm. The AppShimHost owns itself, and is @@ -64,6 +71,7 @@ mojo::IsolatedConnection mojo_connection_; chrome::mojom::AppShimPtr app_shim_; std::unique_ptr<views::BridgeFactoryHost> views_bridge_factory_host_; + std::unique_ptr<content::NSViewBridgeFactoryHost> content_bridge_factory_; mojo::Binding<chrome::mojom::AppShimHost> host_binding_; std::string app_id_; base::FilePath profile_path_;
diff --git a/chrome/browser/apps/app_shim/app_shim_host_mac_unittest.cc b/chrome/browser/apps/app_shim/app_shim_host_mac_unittest.cc index 9e4984ef..5dec953 100644 --- a/chrome/browser/apps/app_shim/app_shim_host_mac_unittest.cc +++ b/chrome/browser/apps/app_shim/app_shim_host_mac_unittest.cc
@@ -10,6 +10,8 @@ #include "base/macros.h" #include "base/memory/ptr_util.h" +#include "base/single_thread_task_runner.h" +#include "base/test/scoped_task_environment.h" #include "base/test/test_simple_task_runner.h" #include "chrome/common/mac/app_shim_param_traits.h" #include "ipc/ipc_message.h" @@ -46,6 +48,8 @@ } void CreateViewsBridgeFactory( views_bridge_mac::mojom::BridgeFactoryRequest request) override {} + void CreateContentNSViewBridgeFactory( + content::mojom::NSViewBridgeFactoryAssociatedRequest request) override {} void Hide() override {} void UnhideWithoutActivation() override {} void SetUserAttention(apps::AppShimAttentionType attention_type) override {} @@ -83,9 +87,7 @@ class AppShimHostTest : public testing::Test, public apps::AppShimHandler { public: - AppShimHostTest() - : task_runner_(new base::TestSimpleTaskRunner), - task_runner_handle_(task_runner_) {} + AppShimHostTest() { task_runner_ = base::ThreadTaskRunnerHandle::Get(); } ~AppShimHostTest() override { if (host_) @@ -93,7 +95,8 @@ DCHECK(!host_); } - scoped_refptr<base::TestSimpleTaskRunner> task_runner() { + void RunUntilIdle() { scoped_task_environment_.RunUntilIdle(); } + scoped_refptr<base::SingleThreadTaskRunner> task_runner() { return task_runner_; } TestingAppShimHost* host() { return host_.get(); } @@ -106,7 +109,7 @@ } apps::AppShimLaunchResult GetLaunchResult() { - task_runner_->RunUntilIdle(); + RunUntilIdle(); return shim_->GetLaunchResult(); } @@ -149,8 +152,8 @@ host_ = host->GetWeakPtr(); } - scoped_refptr<base::TestSimpleTaskRunner> task_runner_; - base::ThreadTaskRunnerHandle task_runner_handle_; + scoped_refptr<base::SingleThreadTaskRunner> task_runner_; + base::test::ScopedTaskEnvironment scoped_task_environment_; std::unique_ptr<TestingAppShim> shim_; @@ -182,15 +185,15 @@ GetMojoHost()->FocusApp(apps::APP_SHIM_FOCUS_NORMAL, std::vector<base::FilePath>()); - task_runner()->RunUntilIdle(); + RunUntilIdle(); EXPECT_EQ(1, focus_count_); GetMojoHost()->QuitApp(); - task_runner()->RunUntilIdle(); + RunUntilIdle(); EXPECT_EQ(1, quit_count_); SimulateDisconnect(); - task_runner()->RunUntilIdle(); + RunUntilIdle(); EXPECT_EQ(1, close_count_); EXPECT_EQ(nullptr, host()); apps::AppShimHandler::RemoveHandler(kTestAppId);
diff --git a/chrome/browser/apps/app_shim/app_shim_host_manager_browsertest_mac.mm b/chrome/browser/apps/app_shim/app_shim_host_manager_browsertest_mac.mm index 89ab8ca..958be60 100644 --- a/chrome/browser/apps/app_shim/app_shim_host_manager_browsertest_mac.mm +++ b/chrome/browser/apps/app_shim/app_shim_host_manager_browsertest_mac.mm
@@ -51,6 +51,8 @@ void LaunchAppDone(apps::AppShimLaunchResult result) override {} void CreateViewsBridgeFactory( views_bridge_mac::mojom::BridgeFactoryRequest request) override {} + void CreateContentNSViewBridgeFactory( + content::mojom::NSViewBridgeFactoryAssociatedRequest request) override {} void Hide() override {} void UnhideWithoutActivation() override {} void SetUserAttention(apps::AppShimAttentionType attention_type) override {}
diff --git a/chrome/browser/ash_service_registry.cc b/chrome/browser/ash_service_registry.cc index 0a694395..25d15c5 100644 --- a/chrome/browser/ash_service_registry.cc +++ b/chrome/browser/ash_service_registry.cc
@@ -4,6 +4,7 @@ #include "chrome/browser/ash_service_registry.h" +#include "ash/accessibility/ax_host_service.h" #include "ash/ash_service.h" #include "ash/components/quick_launch/public/mojom/constants.mojom.h" #include "ash/components/shortcut_viewer/public/mojom/shortcut_viewer.mojom.h" @@ -15,7 +16,6 @@ #include "base/strings/utf_string_conversions.h" #include "base/threading/thread_task_runner_handle.h" #include "build/build_config.h" -#include "chrome/browser/chromeos/accessibility/ax_host_service.h" #include "chrome/browser/chromeos/prefs/pref_connector_service.h" #include "chrome/grit/generated_resources.h" #include "content/public/common/service_manager_connection.h" @@ -84,20 +84,20 @@ (*services)[ash::mojom::kPrefConnectorServiceName] = info; } + if (features::IsMultiProcessMash()) + return; + { // Register the accessibility host service. service_manager::EmbeddedServiceInfo info; info.task_runner = base::ThreadTaskRunnerHandle::Get(); info.factory = base::BindRepeating([]() -> std::unique_ptr<service_manager::Service> { - return std::make_unique<AXHostService>(); + return std::make_unique<ash::AXHostService>(); }); (*services)[ax::mojom::kAXHostServiceName] = info; } - if (features::IsMultiProcessMash()) - return; - (*services)[ash::mojom::kServiceName] = ash::AshService::CreateEmbeddedServiceInfo(); }
diff --git a/chrome/browser/chrome_browser_main.cc b/chrome/browser/chrome_browser_main.cc index 341a5366..93496353 100644 --- a/chrome/browser/chrome_browser_main.cc +++ b/chrome/browser/chrome_browser_main.cc
@@ -66,7 +66,6 @@ #include "chrome/browser/component_updater/sth_set_component_installer.h" #include "chrome/browser/component_updater/subresource_filter_component_installer.h" #include "chrome/browser/component_updater/supervised_user_whitelist_installer.h" -#include "chrome/browser/component_updater/widevine_cdm_component_installer.h" #include "chrome/browser/defaults.h" #include "chrome/browser/first_run/first_run.h" #include "chrome/browser/lifetime/application_lifetime.h" @@ -306,6 +305,10 @@ #include "chrome/browser/vr/service/vr_service_impl.h" #endif +#if BUILDFLAG(ENABLE_WIDEVINE_CDM_COMPONENT) +#include "chrome/browser/component_updater/widevine_cdm_component_installer.h" +#endif // BUILDFLAG(ENABLE_WIDEVINE_CDM_COMPONENT) + #if defined(USE_AURA) #include "services/service_manager/runner/common/client_util.h" #include "ui/aura/env.h" @@ -549,9 +552,9 @@ RegisterPepperFlashComponent(cus); #endif // !defined(OS_ANDROID) -#if BUILDFLAG(ENABLE_WIDEVINE) && BUILDFLAG(ENABLE_LIBRARY_CDMS) +#if BUILDFLAG(ENABLE_WIDEVINE_CDM_COMPONENT) RegisterWidevineCdmComponent(cus); -#endif // BUILDFLAG(ENABLE_WIDEVINE) && BUILDFLAG(ENABLE_LIBRARY_CDMS) +#endif // BUILDFLAG(ENABLE_WIDEVINE_CDM_COMPONENT) #if BUILDFLAG(ENABLE_NACL) && !defined(OS_ANDROID) #if defined(OS_CHROMEOS)
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn index 0a8dc3a..6004ff7 100644 --- a/chrome/browser/chromeos/BUILD.gn +++ b/chrome/browser/chromeos/BUILD.gn
@@ -92,6 +92,8 @@ "//chromeos/components/proximity_auth/logging", "//chromeos/components/tether", "//chromeos/services/device_sync/public/cpp", + "//chromeos/services/machine_learning/public/cpp", + "//chromeos/services/machine_learning/public/mojom", "//chromeos/services/multidevice_setup/public/cpp", "//chromeos/services/multidevice_setup/public/cpp:android_sms_app_helper_delegate", "//chromeos/services/multidevice_setup/public/cpp:android_sms_pairing_state_tracker", @@ -263,8 +265,6 @@ "accessibility/accessibility_manager.h", "accessibility/accessibility_panel.cc", "accessibility/accessibility_panel.h", - "accessibility/ax_host_service.cc", - "accessibility/ax_host_service.h", "accessibility/chromevox_panel.cc", "accessibility/chromevox_panel.h", "accessibility/dictation_chromeos.cc", @@ -1841,6 +1841,8 @@ # Extension API implementations. "extensions/arc_apps_private_api.cc", "extensions/arc_apps_private_api.h", + "extensions/autotest_private/autotest_private_api.cc", + "extensions/autotest_private/autotest_private_api.h", "extensions/backdrop_wallpaper_handlers/backdrop_wallpaper_handlers.cc", "extensions/backdrop_wallpaper_handlers/backdrop_wallpaper_handlers.h", "extensions/echo_private_api.cc", @@ -2019,7 +2021,6 @@ "../policy/default_geolocation_policy_handler_unittest.cc", "../resources/chromeos/zip_archiver/test/char_coding_test.cc", "../ui/browser_finder_chromeos_unittest.cc", - "accessibility/ax_host_service_unittest.cc", "app_mode/startup_app_launcher_unittest.cc", "apps/intent_helper/apps_navigation_throttle_unittest.cc", "apps/intent_helper/page_transition_util_unittest.cc",
diff --git a/chrome/browser/chromeos/arc/arc_util.cc b/chrome/browser/chromeos/arc/arc_util.cc index f1b3952e..7bdf54a5 100644 --- a/chrome/browser/chromeos/arc/arc_util.cc +++ b/chrome/browser/chromeos/arc/arc_util.cc
@@ -686,4 +686,10 @@ return supervision_transition; } +bool IsPlayStoreAvailable() { + return (!IsRobotOrOfflineDemoAccountMode() || + chromeos::DemoSession::IsDeviceInDemoMode()) && + !ShouldArcAlwaysStartWithNoPlayStore(); +} + } // namespace arc
diff --git a/chrome/browser/chromeos/arc/arc_util.h b/chrome/browser/chromeos/arc/arc_util.h index 590ac4c..6e6f117 100644 --- a/chrome/browser/chromeos/arc/arc_util.h +++ b/chrome/browser/chromeos/arc/arc_util.h
@@ -9,6 +9,7 @@ #include "ash/public/interfaces/voice_interaction_controller.mojom.h" #include "base/callback_forward.h" +#include "chrome/browser/chromeos/login/demo_mode/demo_session.h" #include "components/arc/arc_supervision_transition.h" // Most utility should be put in components/arc/arc_util.{h,cc}, rather than @@ -160,6 +161,10 @@ // Returns the supervision transition status as stored in profile prefs. ArcSupervisionTransition GetSupervisionTransition(const Profile* profile); +// Returns true if Play Store package is present and can be launched in this +// session. +bool IsPlayStoreAvailable(); + } // namespace arc #endif // CHROME_BROWSER_CHROMEOS_ARC_ARC_UTIL_H_
diff --git a/chrome/browser/chromeos/arc/arc_util_unittest.cc b/chrome/browser/chromeos/arc/arc_util_unittest.cc index c80a382..d752835 100644 --- a/chrome/browser/chromeos/arc/arc_util_unittest.cc +++ b/chrome/browser/chromeos/arc/arc_util_unittest.cc
@@ -838,6 +838,40 @@ EXPECT_FALSE(IsArcStatsReportingEnabled()); } +TEST_F(ChromeArcUtilTest, ArcStartModeDefault) { + auto* command_line = base::CommandLine::ForCurrentProcess(); + command_line->InitFromArgv({"", "--arc-availability=installed"}); + EXPECT_TRUE(IsPlayStoreAvailable()); +} + +TEST_F(ChromeArcUtilTest, ArcStartModeDefaultPublicSession) { + auto* command_line = base::CommandLine::ForCurrentProcess(); + command_line->InitFromArgv({"", "--arc-availability=installed"}); + ScopedLogIn login(GetFakeUserManager(), + AccountId::FromUserEmail("public_user@gmail.com"), + user_manager::USER_TYPE_PUBLIC_ACCOUNT); + EXPECT_FALSE(IsPlayStoreAvailable()); +} + +TEST_F(ChromeArcUtilTest, ArcStartModeDefaultDemoMode) { + auto* command_line = base::CommandLine::ForCurrentProcess(); + command_line->InitFromArgv({"", "--arc-availability=installed"}); + chromeos::DemoSession::SetDemoConfigForTesting( + chromeos::DemoSession::DemoModeConfig::kOnline); + ScopedLogIn login(GetFakeUserManager(), + AccountId::FromUserEmail("public_user@gmail.com"), + user_manager::USER_TYPE_PUBLIC_ACCOUNT); + EXPECT_TRUE(IsPlayStoreAvailable()); +} + +TEST_F(ChromeArcUtilTest, ArcStartModeWithoutPlayStore) { + auto* command_line = base::CommandLine::ForCurrentProcess(); + command_line->InitFromArgv( + {"", "--arc-availability=installed", + "--arc-start-mode=always-start-with-no-play-store"}); + EXPECT_FALSE(IsPlayStoreAvailable()); +} + using ArcMigrationTest = ChromeArcUtilTest; TEST_F(ArcMigrationTest, IsMigrationAllowedUnmanagedUser) {
diff --git a/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_util.cc b/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_util.cc index c85555b..fb0db06 100644 --- a/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_util.cc +++ b/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_util.cc
@@ -234,8 +234,7 @@ for (const auto& mapping : kAndroidMimeTypeMappings) { std::vector<base::StringPiece> extensions = base::SplitStringPiece( mapping.extensions, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); - auto iter = std::find(extensions.begin(), extensions.end(), ext); - if (iter != extensions.end()) + if (base::ContainsValue(extensions, ext)) return mapping.mime_type; } return std::string();
diff --git a/chrome/browser/chromeos/arc/input_method_manager/arc_input_method_manager_service_unittest.cc b/chrome/browser/chromeos/arc/input_method_manager/arc_input_method_manager_service_unittest.cc index 3e2bb22..c45b34b 100644 --- a/chrome/browser/chromeos/arc/input_method_manager/arc_input_method_manager_service_unittest.cc +++ b/chrome/browser/chromeos/arc/input_method_manager/arc_input_method_manager_service_unittest.cc
@@ -107,9 +107,7 @@ bool IsInputMethodAllowed(const std::string& ime_id) { return allowed_input_methods_.empty() || - (std::find(allowed_input_methods_.begin(), - allowed_input_methods_.end(), - ime_id) != allowed_input_methods_.end()); + base::ContainsValue(allowed_input_methods_, ime_id); } std::vector<std::tuple<std::string, im::InputMethodDescriptors>>
diff --git a/chrome/browser/extensions/api/autotest_private/DEPS b/chrome/browser/chromeos/extensions/autotest_private/DEPS similarity index 100% rename from chrome/browser/extensions/api/autotest_private/DEPS rename to chrome/browser/chromeos/extensions/autotest_private/DEPS
diff --git a/chrome/browser/chromeos/extensions/autotest_private/OWNERS b/chrome/browser/chromeos/extensions/autotest_private/OWNERS new file mode 100644 index 0000000..c345b9b --- /dev/null +++ b/chrome/browser/chromeos/extensions/autotest_private/OWNERS
@@ -0,0 +1,3 @@ +achuith@chromium.org +derat@chromium.org +stevenjb@chromium.org
diff --git a/chrome/browser/extensions/api/autotest_private/autotest_private_api.cc b/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.cc similarity index 97% rename from chrome/browser/extensions/api/autotest_private/autotest_private_api.cc rename to chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.cc index e10ed44..189fb40 100644 --- a/chrome/browser/extensions/api/autotest_private/autotest_private_api.cc +++ b/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.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 "chrome/browser/extensions/api/autotest_private/autotest_private_api.h" +#include "chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.h" #include <memory> #include <sstream> @@ -75,8 +75,7 @@ auto permissions = std::make_unique<base::ListValue>(); for (URLPatternSet::const_iterator perm = pattern_set.begin(); - perm != pattern_set.end(); - ++perm) { + perm != pattern_set.end(); ++perm) { permissions->AppendString(perm->GetAsString()); } @@ -241,8 +240,9 @@ ExtensionFunction::ResponseAction AutotestPrivateLockScreenFunction::Run() { DVLOG(1) << "AutotestPrivateLockScreenFunction"; #if defined(OS_CHROMEOS) - chromeos::DBusThreadManager::Get()->GetSessionManagerClient()-> - RequestLockScreen(); + chromeos::DBusThreadManager::Get() + ->GetSessionManagerClient() + ->RequestLockScreen(); #endif return RespondNow(NoArguments()); } @@ -266,8 +266,7 @@ ExtensionList all; all.insert(all.end(), extensions.begin(), extensions.end()); all.insert(all.end(), disabled_extensions.begin(), disabled_extensions.end()); - for (ExtensionList::const_iterator it = all.begin(); - it != all.end(); ++it) { + for (ExtensionList::const_iterator it = all.begin(); it != all.end(); ++it) { const Extension* extension = it->get(); std::string id = extension->id(); std::unique_ptr<base::DictionaryValue> extension_value( @@ -289,13 +288,11 @@ extension_value->Set("apiPermissions", GetAPIPermissions(extension)); Manifest::Location location = extension->location(); - extension_value->SetBoolean("isComponent", - location == Manifest::COMPONENT); - extension_value->SetBoolean("isInternal", - location == Manifest::INTERNAL); + extension_value->SetBoolean("isComponent", location == Manifest::COMPONENT); + extension_value->SetBoolean("isInternal", location == Manifest::INTERNAL); extension_value->SetBoolean("isUserInstalled", - location == Manifest::INTERNAL || - Manifest::IsUnpackedLocation(location)); + location == Manifest::INTERNAL || + Manifest::IsUnpackedLocation(location)); extension_value->SetBoolean("isEnabled", service->IsExtensionEnabled(id)); extension_value->SetBoolean( "allowedInIncognito", util::IsIncognitoEnabled(id, browser_context())); @@ -312,7 +309,7 @@ return RespondNow(OneArgument(std::move(return_value))); } -static int AccessArray(const volatile int arr[], const volatile int *index) { +static int AccessArray(const volatile int arr[], const volatile int* index) { return arr[*index]; } @@ -904,10 +901,8 @@ return new AutotestPrivateAPI(); } -AutotestPrivateAPI::AutotestPrivateAPI() : test_mode_(false) { -} +AutotestPrivateAPI::AutotestPrivateAPI() : test_mode_(false) {} -AutotestPrivateAPI::~AutotestPrivateAPI() { -} +AutotestPrivateAPI::~AutotestPrivateAPI() {} } // namespace extensions
diff --git a/chrome/browser/extensions/api/autotest_private/autotest_private_api.h b/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.h similarity index 96% rename from chrome/browser/extensions/api/autotest_private/autotest_private_api.h rename to chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.h index ff073d0..11f38f5 100644 --- a/chrome/browser/extensions/api/autotest_private/autotest_private_api.h +++ b/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.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 CHROME_BROWSER_EXTENSIONS_API_AUTOTEST_PRIVATE_AUTOTEST_PRIVATE_API_H_ -#define CHROME_BROWSER_EXTENSIONS_API_AUTOTEST_PRIVATE_AUTOTEST_PRIVATE_API_H_ +#ifndef CHROME_BROWSER_CHROMEOS_EXTENSIONS_AUTOTEST_PRIVATE_AUTOTEST_PRIVATE_API_H_ +#define CHROME_BROWSER_CHROMEOS_EXTENSIONS_AUTOTEST_PRIVATE_AUTOTEST_PRIVATE_API_H_ #include <string> @@ -382,7 +382,7 @@ class AutotestPrivateAPI : public BrowserContextKeyedAPI { public: static BrowserContextKeyedAPIFactory<AutotestPrivateAPI>* - GetFactoryInstance(); + GetFactoryInstance(); // TODO(achuith): Replace these with a mock object for system calls. bool test_mode() const { return test_mode_; } @@ -404,9 +404,9 @@ template <> KeyedService* - BrowserContextKeyedAPIFactory<AutotestPrivateAPI>::BuildServiceInstanceFor( - content::BrowserContext* context) const; +BrowserContextKeyedAPIFactory<AutotestPrivateAPI>::BuildServiceInstanceFor( + content::BrowserContext* context) const; } // namespace extensions -#endif // CHROME_BROWSER_EXTENSIONS_API_AUTOTEST_PRIVATE_AUTOTEST_PRIVATE_API_H_ +#endif // CHROME_BROWSER_CHROMEOS_EXTENSIONS_AUTOTEST_PRIVATE_AUTOTEST_PRIVATE_API_H_
diff --git a/chrome/browser/extensions/api/autotest_private/autotest_private_apitest.cc b/chrome/browser/chromeos/extensions/autotest_private/autotest_private_apitest.cc similarity index 93% rename from chrome/browser/extensions/api/autotest_private/autotest_private_apitest.cc rename to chrome/browser/chromeos/extensions/autotest_private/autotest_private_apitest.cc index 5db6970e..e1a8cfce 100644 --- a/chrome/browser/extensions/api/autotest_private/autotest_private_apitest.cc +++ b/chrome/browser/chromeos/extensions/autotest_private/autotest_private_apitest.cc
@@ -6,7 +6,7 @@ #include "build/build_config.h" #include "chrome/browser/chromeos/arc/arc_session_manager.h" -#include "chrome/browser/extensions/api/autotest_private/autotest_private_api.h" +#include "chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.h" #include "chrome/browser/extensions/extension_apitest.h" #include "components/arc/arc_util.h"
diff --git a/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc b/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc index c9473e2a..1f69cc1 100644 --- a/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc +++ b/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc
@@ -86,7 +86,6 @@ bool tablet_mode = false; bool enable_drivefs = false; bool with_browser = false; - bool needs_zip = false; bool offline = false; }; @@ -97,13 +96,6 @@ } }; -// ZipCase: FilesAppBrowserTest with zip/unzip support. -struct ZipCase : public TestCase { - explicit ZipCase(const char* name) : TestCase(name) { - needs_zip = true; - } -}; - // FilesApp browser test. class FilesAppBrowserTest : public FileManagerBrowserTestBase, public ::testing::WithParamInterface<TestCase> { @@ -155,8 +147,6 @@ return GetParam().with_browser; } - bool GetNeedsZipSupport() const override { return GetParam().needs_zip; } - bool GetIsOffline() const override { return GetParam().offline; } private: @@ -245,16 +235,16 @@ WRAPPED_INSTANTIATE_TEST_CASE_P( MAYBE_ZipFiles, /* zip_files.js */ FilesAppBrowserTest, - ::testing::Values(ZipCase("zipFileOpenDownloads").InGuestMode(), - ZipCase("zipFileOpenDownloads"), - ZipCase("zipFileOpenDrive").EnableDriveFs(), - ZipCase("zipFileOpenDrive"), - ZipCase("zipFileOpenUsb"), - ZipCase("zipCreateFileDownloads").InGuestMode(), - ZipCase("zipCreateFileDownloads"), - ZipCase("zipCreateFileDrive").EnableDriveFs(), - ZipCase("zipCreateFileDrive"), - ZipCase("zipCreateFileUsb"))); + ::testing::Values(TestCase("zipFileOpenDownloads").InGuestMode(), + TestCase("zipFileOpenDownloads"), + TestCase("zipFileOpenDrive").EnableDriveFs(), + TestCase("zipFileOpenDrive"), + TestCase("zipFileOpenUsb"), + TestCase("zipCreateFileDownloads").InGuestMode(), + TestCase("zipCreateFileDownloads"), + TestCase("zipCreateFileDrive").EnableDriveFs(), + TestCase("zipCreateFileDrive"), + TestCase("zipCreateFileUsb"))); WRAPPED_INSTANTIATE_TEST_CASE_P( CreateNewFolder, /* create_new_folder.js */
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 9f12a8e..b3a7a0ef 100644 --- a/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.cc +++ b/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.cc
@@ -116,7 +116,7 @@ enum EntryType { FILE, DIRECTORY, TEAM_DRIVE }; // Represents whether an entry appears in 'Share with Me' or not. - enum SharedOption { NONE, SHARED }; + enum SharedOption { NONE, SHARED, SHARED_WITH_ME, NESTED_SHARED_WITH_ME }; // The actual AddEntriesMessage contents. @@ -278,6 +278,10 @@ SharedOption* option) { if (value == "shared") *option = SHARED; + else if (value == "sharedWithMe") + *option = SHARED_WITH_ME; + else if (value == "nestedSharedWithMe") + *option = NESTED_SHARED_WITH_ME; else if (value == "none") *option = NONE; else @@ -685,12 +689,16 @@ case AddEntriesMessage::FILE: CreateFile(entry.source_file_name, parent_entry->resource_id(), target_name, entry.mime_type, - entry.shared_option == AddEntriesMessage::SHARED, + entry.shared_option == AddEntriesMessage::SHARED || + entry.shared_option == AddEntriesMessage::SHARED_WITH_ME, entry.last_modified_time, file_capabilities); break; case AddEntriesMessage::DIRECTORY: - CreateDirectory(parent_entry->resource_id(), target_name, - entry.last_modified_time, file_capabilities); + CreateDirectory( + parent_entry->resource_id(), target_name, entry.last_modified_time, + entry.shared_option == AddEntriesMessage::SHARED || + entry.shared_option == AddEntriesMessage::SHARED_WITH_ME, + file_capabilities); break; case AddEntriesMessage::TEAM_DRIVE: CreateTeamDrive(entry.team_drive_name, team_drive_capabilities); @@ -716,6 +724,7 @@ const std::string& parent_id, const std::string& target_name, const base::Time& modification_time, + bool shared_with_me, const google_apis::FileResourceCapabilities& capabilities) { google_apis::DriveApiErrorCode error = google_apis::DRIVE_OTHER_ERROR; @@ -740,6 +749,11 @@ base::RunLoop().RunUntilIdle(); ASSERT_TRUE(error == google_apis::HTTP_SUCCESS); ASSERT_TRUE(entry); + + if (shared_with_me) { + ASSERT_EQ(google_apis::HTTP_SUCCESS, + fake_drive_service_->SetFileAsSharedWithMe(entry->file_id())); + } } // Creates a test file with the given spec. @@ -837,13 +851,15 @@ const base::FilePath target_path = GetTargetPathForTestEntry(entry); entries_.insert(std::make_pair(target_path, entry)); + fake_drivefs_->SetMetadata( + GetRelativeDrivePathForTestEntry(entry), entry.mime_type, + base::FilePath(entry.target_path).BaseName().value(), entry.pinned, + entry.shared_option == AddEntriesMessage::SharedOption::SHARED || + entry.shared_option == + AddEntriesMessage::SharedOption::SHARED_WITH_ME); + switch (entry.type) { case AddEntriesMessage::FILE: { - fake_drivefs_->SetMetadata( - GetRelativeDrivePathForTestEntry(entry), entry.mime_type, - base::FilePath(entry.target_path).BaseName().value(), entry.pinned, - entry.shared_option == AddEntriesMessage::SharedOption::SHARED); - if (entry.source_file_name.empty()) { ASSERT_EQ(0, base::WriteFile(target_path, "", 0)); break; @@ -908,7 +924,8 @@ // Update the modified time of parent directories because they may be // also affected by the update of child items. if (path.DirName() != GetTeamDriveGrandRoot() && - path.DirName() != GetMyDrivePath()) { + path.DirName() != GetMyDrivePath() && + path.DirName() != GetSharedWithMePath()) { const auto it = entries_.find(path.DirName()); if (it == entries_.end()) return false; @@ -921,14 +938,24 @@ base::FilePath GetTargetPathForTestEntry( const AddEntriesMessage::TestEntryInfo& entry) { const base::FilePath target_path = - entry.team_drive_name.empty() - ? GetMyDrivePath().Append(entry.target_path) - : GetTeamDrivePath(entry.team_drive_name).Append(entry.target_path); + GetTargetBasePathForTestEntry(entry).Append(entry.target_path); if (entry.name_text != entry.target_path) return target_path.DirName().Append(entry.name_text); return target_path; } + base::FilePath GetTargetBasePathForTestEntry( + const AddEntriesMessage::TestEntryInfo& entry) { + if (entry.shared_option == AddEntriesMessage::SHARED_WITH_ME || + entry.shared_option == AddEntriesMessage::NESTED_SHARED_WITH_ME) { + return GetSharedWithMePath(); + } + if (!entry.team_drive_name.empty()) { + return GetTeamDrivePath(entry.team_drive_name); + } + return GetMyDrivePath(); + } + base::FilePath GetRelativeDrivePathForTestEntry( const AddEntriesMessage::TestEntryInfo& entry) { const base::FilePath target_path = GetTargetPathForTestEntry(entry); @@ -945,6 +972,10 @@ return mount_path().Append("team_drives"); } + base::FilePath GetSharedWithMePath() { + return mount_path().Append(".files-by-id/123"); + } + base::FilePath GetTeamDrivePath(const std::string& team_drive_name) { return GetTeamDriveGrandRoot().Append(team_drive_name); } @@ -1125,10 +1156,6 @@ return false; } -bool FileManagerBrowserTestBase::GetNeedsZipSupport() const { - return false; -} - bool FileManagerBrowserTestBase::GetIsOffline() const { return false; } @@ -1208,6 +1235,11 @@ return; } + if (name == "getDriveFsEnabled") { + *output = IsDriveFsTest() ? "true" : "false"; + return; + } + if (name == "getRootPaths") { // Obtain the root paths. const auto downloads_root = util::GetDownloadsMountPointName(profile());
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 3ad34f1b..93f3997 100644 --- a/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.h +++ b/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.h
@@ -50,7 +50,6 @@ virtual bool GetTabletMode() const; virtual bool GetEnableDriveFs() const; virtual bool GetRequiresStartupBrowser() const; - virtual bool GetNeedsZipSupport() const; virtual bool GetIsOffline() const; // Launches the test extension from GetTestExtensionManifestName() and uses @@ -71,9 +70,6 @@ // Returns true if the test requires DriveFS. bool IsDriveFsTest() const { return GetEnableDriveFs(); } - // Returns true if the test requires zip/unzip support. - bool IsZipTest() const { return GetNeedsZipSupport(); } - // Returns true if Drive should act as if offline. bool IsOfflineTest() const { return GetIsOffline(); }
diff --git a/chrome/browser/chromeos/login/demo_mode/demo_session.cc b/chrome/browser/chromeos/login/demo_mode/demo_session.cc index 4524a6d..e3e152f 100644 --- a/chrome/browser/chromeos/login/demo_mode/demo_session.cc +++ b/chrome/browser/chromeos/login/demo_mode/demo_session.cc
@@ -13,6 +13,7 @@ #include "base/files/file_util.h" #include "base/optional.h" #include "base/path_service.h" +#include "base/stl_util.h" #include "base/sys_info.h" #include "base/task/post_task.h" #include "chrome/browser/apps/platform_apps/app_load_service.h" @@ -174,6 +175,11 @@ bool is_demo_mode = is_demo_device_mode || is_demo_device_domain; const PrefService* prefs = g_browser_process->local_state(); + + // The testing browser process might not have local state. + if (!prefs) + return DemoModeConfig::kNone; + // Demo mode config preference is set at the end of the demo setup after // device is enrolled. auto demo_config = DemoModeConfig::kNone; @@ -337,9 +343,8 @@ if (!net::NetworkChangeNotifier::IsOffline()) return false; - return std::find(ignore_pin_policy_offline_apps_.begin(), - ignore_pin_policy_offline_apps_.end(), - app_id_or_package) != ignore_pin_policy_offline_apps_.end(); + return base::ContainsValue(ignore_pin_policy_offline_apps_, + app_id_or_package); } void DemoSession::SetExtensionsExternalLoader(
diff --git a/chrome/browser/chromeos/login/oobe_interactive_ui_test.cc b/chrome/browser/chromeos/login/oobe_interactive_ui_test.cc index 0478e8f..ff9e7a5 100644 --- a/chrome/browser/chromeos/login/oobe_interactive_ui_test.cc +++ b/chrome/browser/chromeos/login/oobe_interactive_ui_test.cc
@@ -14,6 +14,7 @@ #include "chrome/browser/chromeos/login/wizard_controller.h" #include "chrome/browser/lifetime/application_lifetime.h" #include "chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h" +#include "chromeos/chromeos_switches.h" #include "chromeos/dbus/update_engine_client.h" #include "content/public/browser/notification_service.h" @@ -65,6 +66,12 @@ OobeInteractiveUITest() = default; ~OobeInteractiveUITest() override = default; + void SetUpCommandLine(base::CommandLine* command_line) override { + command_line->AppendSwitch(switches::kEnableMarketingOptInScreen); + + OobeBaseTest::SetUpCommandLine(command_line); + } + void TearDownOnMainThread() override { // If the login display is still showing, exit gracefully. if (LoginDisplayHost::default_host()) {
diff --git a/chrome/browser/chromeos/login/wizard_controller.cc b/chrome/browser/chromeos/login/wizard_controller.cc index 170bf91..a3bbd1e6 100644 --- a/chrome/browser/chromeos/login/wizard_controller.cc +++ b/chrome/browser/chromeos/login/wizard_controller.cc
@@ -705,7 +705,9 @@ void WizardController::ShowMarketingOptInScreen() { // Skip the screen for public sessions and non-regular ephemeral users. - if (IsPublicSessionOrEphemeralLogin()) { + if (!base::CommandLine::ForCurrentProcess()->HasSwitch( + chromeos::switches::kEnableMarketingOptInScreen) || + IsPublicSessionOrEphemeralLogin()) { OnMarketingOptInFinished(); return; }
diff --git a/chrome/browser/component_updater/widevine_cdm_component_installer.cc b/chrome/browser/component_updater/widevine_cdm_component_installer.cc index dca801b..83dc69bb 100644 --- a/chrome/browser/component_updater/widevine_cdm_component_installer.cc +++ b/chrome/browser/component_updater/widevine_cdm_component_installer.cc
@@ -46,8 +46,8 @@ #include "third_party/widevine/cdm/buildflags.h" #include "third_party/widevine/cdm/widevine_cdm_common.h" -#if !BUILDFLAG(ENABLE_WIDEVINE) -#error This file should only be compiled when Widevine is enabled +#if !BUILDFLAG(ENABLE_WIDEVINE_CDM_COMPONENT) +#error This file should only be compiled when Widevine CDM component is enabled #endif using content::BrowserThread; @@ -55,8 +55,6 @@ namespace component_updater { -#if defined(WIDEVINE_CDM_IS_COMPONENT) - namespace { // CRX hash. The extension id is: oimompecagnajdejgnnjijobebaeigek. @@ -515,14 +513,10 @@ absolute_cdm_install_dir, base::Passed(&manifest))); } -#endif // defined(WIDEVINE_CDM_IS_COMPONENT) - void RegisterWidevineCdmComponent(ComponentUpdateService* cus) { -#if defined(WIDEVINE_CDM_IS_COMPONENT) auto installer = base::MakeRefCounted<ComponentInstaller>( std::make_unique<WidevineCdmComponentInstallerPolicy>()); installer->Register(cus, base::OnceClosure()); -#endif // defined(WIDEVINE_CDM_IS_COMPONENT) } } // namespace component_updater
diff --git a/chrome/browser/devtools/devtools_eye_dropper.h b/chrome/browser/devtools/devtools_eye_dropper.h index 5c0c293..aaa87d2 100644 --- a/chrome/browser/devtools/devtools_eye_dropper.h +++ b/chrome/browser/devtools/devtools_eye_dropper.h
@@ -12,6 +12,7 @@ #include "components/viz/host/client_frame_sink_video_capturer.h" #include "content/public/browser/render_widget_host.h" #include "content/public/browser/web_contents_observer.h" +#include "media/renderers/paint_canvas_video_renderer.h" #include "third_party/skia/include/core/SkBitmap.h" namespace blink { @@ -58,6 +59,7 @@ content::RenderWidgetHost::MouseEventCallback mouse_event_callback_; content::RenderWidgetHost* host_; std::unique_ptr<viz::ClientFrameSinkVideoCapturer> video_capturer_; + media::PaintCanvasVideoRenderer video_renderer_; base::WeakPtrFactory<DevToolsEyeDropper> weak_factory_; DISALLOW_COPY_AND_ASSIGN(DevToolsEyeDropper);
diff --git a/chrome/browser/download/offline_item_model.cc b/chrome/browser/download/offline_item_model.cc index 25dee33..258ff97 100644 --- a/chrome/browser/download/offline_item_model.cc +++ b/chrome/browser/download/offline_item_model.cc
@@ -80,6 +80,11 @@ data->was_ui_notified_ = was_ui_notified; } +base::FilePath OfflineItemModel::GetFileNameToReportUser() const { + return offline_item_ ? base::FilePath::FromUTF8Unsafe(offline_item_->title) + : base::FilePath(); +} + base::FilePath OfflineItemModel::GetTargetFilePath() const { return offline_item_ ? offline_item_->file_path : base::FilePath(); }
diff --git a/chrome/browser/download/offline_item_model.h b/chrome/browser/download/offline_item_model.h index 4a6c3c9..d2d47dc 100644 --- a/chrome/browser/download/offline_item_model.h +++ b/chrome/browser/download/offline_item_model.h
@@ -39,6 +39,7 @@ int PercentComplete() const override; bool WasUINotified() const override; void SetWasUINotified(bool should_notify) override; + base::FilePath GetFileNameToReportUser() const override; base::FilePath GetTargetFilePath() const override; void OpenDownload() override; void Pause() override;
diff --git a/chrome/browser/extensions/BUILD.gn b/chrome/browser/extensions/BUILD.gn index ead993a..32b520fb 100644 --- a/chrome/browser/extensions/BUILD.gn +++ b/chrome/browser/extensions/BUILD.gn
@@ -59,8 +59,6 @@ "api/automation_internal/automation_event_router.h", "api/automation_internal/automation_internal_api.cc", "api/automation_internal/automation_internal_api.h", - "api/autotest_private/autotest_private_api.cc", - "api/autotest_private/autotest_private_api.h", "api/bookmark_manager_private/bookmark_manager_private_api.cc", "api/bookmark_manager_private/bookmark_manager_private_api.h", "api/bookmarks/bookmark_api_constants.cc", @@ -997,8 +995,6 @@ "//ash/public/cpp", "//chromeos/components/proximity_auth", "//chromeos/services/ime/public/mojom", - "//chromeos/services/machine_learning/public/cpp", - "//chromeos/services/machine_learning/public/mojom", "//components/arc", "//components/chrome_apps", "//components/constrained_window",
diff --git a/chrome/browser/extensions/api/autotest_private/OWNERS b/chrome/browser/extensions/api/autotest_private/OWNERS deleted file mode 100644 index 408e726..0000000 --- a/chrome/browser/extensions/api/autotest_private/OWNERS +++ /dev/null
@@ -1 +0,0 @@ -achuith@chromium.org
diff --git a/chrome/browser/extensions/component_loader.cc b/chrome/browser/extensions/component_loader.cc index 167f528..ebbb3faa 100644 --- a/chrome/browser/extensions/component_loader.cc +++ b/chrome/browser/extensions/component_loader.cc
@@ -323,9 +323,7 @@ void ComponentLoader::AddZipArchiverExtension() { #if defined(OS_CHROMEOS) base::FilePath resources_path; - if ((chromeos::switches::IsZipArchiverPackerEnabled() || - chromeos::switches::IsZipArchiverUnpackerEnabled()) && - base::PathService::Get(chrome::DIR_RESOURCES, &resources_path)) { + if (base::PathService::Get(chrome::DIR_RESOURCES, &resources_path)) { AddWithNameAndDescriptionFromDir( resources_path.Append(extension_misc::kZipArchiverExtensionPath), extension_misc::kZipArchiverExtensionId,
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index b7a3103..a787ba6b 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -3274,10 +3274,6 @@ "Enable Zero State Suggestions feature in Launcher, which will show " "suggetions when launcher search box is active with an empty query"; -const char kEnableZipArchiverPackerName[] = "ZIP archiver - Packer"; -const char kEnableZipArchiverPackerDescription[] = - "Enable the ability to archive files on Drive in the Files app"; - const char kEolNotificationName[] = "Disable Device End of Life notification."; const char kEolNotificationDescription[] = "Disable Notifcation when Device is End of Life.";
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index 30b2ace..3474b4a 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -1999,9 +1999,6 @@ extern const char kEnableZeroStateSuggestionsName[]; extern const char kEnableZeroStateSuggestionsDescription[]; -extern const char kEnableZipArchiverPackerName[]; -extern const char kEnableZipArchiverPackerDescription[]; - extern const char kEolNotificationName[]; extern const char kEolNotificationDescription[];
diff --git a/chrome/browser/media/encrypted_media_browsertest.cc b/chrome/browser/media/encrypted_media_browsertest.cc index 3c3ce39..c2bb7321 100644 --- a/chrome/browser/media/encrypted_media_browsertest.cc +++ b/chrome/browser/media/encrypted_media_browsertest.cc
@@ -556,16 +556,9 @@ TestSimplePlayback("bear-320x240-opus-av_enc-v.webm", kWebMOpusAudioVp9Video); } -// TODO(xhwang): Test is flaky on Mac. https://crbug.com/835585 -#if defined(MACOS) -#define MAYBE_Playback_Multiple_VideoAudio_WebM \ - DISABLED_Playback_Multiple_VideoAudio_WebM -#else -#define MAYBE_Playback_Multiple_VideoAudio_WebM \ - Playback_Multiple_VideoAudio_WebM -#endif +// TODO(xhwang): Test is flaky. https://crbug.com/890124. IN_PROC_BROWSER_TEST_P(EncryptedMediaTest, - MAYBE_Playback_Multiple_VideoAudio_WebM) { + DISABLED_Playback_Multiple_VideoAudio_WebM) { if (!IsPlayBackPossible(CurrentKeySystem())) { DVLOG(0) << "Skipping test - Playback_Multiple test requires playback."; return;
diff --git a/chrome/browser/password_manager/password_store_factory.cc b/chrome/browser/password_manager/password_store_factory.cc index b0454989..7e626167 100644 --- a/chrome/browser/password_manager/password_store_factory.cc +++ b/chrome/browser/password_manager/password_store_factory.cc
@@ -290,7 +290,6 @@ ps->PreparePasswordHashData(GetSyncUsername(profile)); #endif - password_manager_util::RemoveUselessCredentials(ps, profile->GetPrefs(), 60); auto network_context_getter = base::BindRepeating( [](Profile* profile) -> network::mojom::NetworkContext* { if (!g_browser_process->profile_manager()->IsValidProfile(profile)) @@ -299,11 +298,8 @@ ->GetNetworkContext(); }, profile); - base::SequencedTaskRunnerHandle::Get()->PostDelayedTask( - FROM_HERE, - base::BindOnce(&password_manager_util::ReportHttpMigrationMetrics, ps, - network_context_getter), - base::TimeDelta::FromSeconds(60)); + password_manager_util::RemoveUselessCredentials(ps, profile->GetPrefs(), 60, + network_context_getter); #if defined(OS_WIN) || defined(OS_MACOSX) || \ (defined(OS_LINUX) && !defined(OS_CHROMEOS))
diff --git a/chrome/browser/password_manager/password_store_mac.cc b/chrome/browser/password_manager/password_store_mac.cc index c4ae8b3..6e9685c7 100644 --- a/chrome/browser/password_manager/password_store_mac.cc +++ b/chrome/browser/password_manager/password_store_mac.cc
@@ -4,6 +4,7 @@ #include "chrome/browser/password_manager/password_store_mac.h" #include "base/metrics/histogram_macros.h" +#include "components/os_crypt/os_crypt.h" #include "components/password_manager/core/common/password_manager_pref_names.h" using password_manager::MigrationStatus; @@ -33,9 +34,13 @@ PasswordStoreMac::~PasswordStoreMac() = default; -void PasswordStoreMac::InitOnBackgroundSequence( +bool PasswordStoreMac::InitOnBackgroundSequence( const syncer::SyncableService::StartSyncFlare& flare) { - PasswordStoreDefault::InitOnBackgroundSequence(flare); + if (!PasswordStoreDefault::InitOnBackgroundSequence(flare)) + return false; + + if (!OSCrypt::IsEncryptionAvailable()) + return false; if (login_db() && (initial_status_ == MigrationStatus::NOT_STARTED || initial_status_ == MigrationStatus::FAILED_ONCE || @@ -53,6 +58,8 @@ "PasswordManager.KeychainMigration.Status", static_cast<int>(initial_status_), static_cast<int>(MigrationStatus::MIGRATION_STATUS_COUNT)); + + return true; } void PasswordStoreMac::UpdateStatusPref(MigrationStatus status) {
diff --git a/chrome/browser/password_manager/password_store_mac.h b/chrome/browser/password_manager/password_store_mac.h index 6503e4a..3c7431e 100644 --- a/chrome/browser/password_manager/password_store_mac.h +++ b/chrome/browser/password_manager/password_store_mac.h
@@ -9,6 +9,7 @@ #include "base/macros.h" #include "components/password_manager/core/browser/keychain_migration_status_mac.h" +#include "components/password_manager/core/browser/password_store.h" #include "components/password_manager/core/browser/password_store_default.h" #include "components/prefs/pref_member.h" @@ -35,7 +36,7 @@ ~PasswordStoreMac() override; // PasswordStore: - void InitOnBackgroundSequence( + bool InitOnBackgroundSequence( const syncer::SyncableService::StartSyncFlare& flare) override; // Writes status to the prefs.
diff --git a/chrome/browser/prefs/pref_service_incognito_whitelist.cc b/chrome/browser/prefs/pref_service_incognito_whitelist.cc index c9617637..026dc1c 100644 --- a/chrome/browser/prefs/pref_service_incognito_whitelist.cc +++ b/chrome/browser/prefs/pref_service_incognito_whitelist.cc
@@ -72,6 +72,9 @@ bookmarks::prefs::kShowAppsShortcutInBookmarkBar, bookmarks::prefs::kShowManagedBookmarksInBookmarkBar, bookmarks::prefs::kShowBookmarkBar, +#if defined(OS_ANDROID) + prefs::kPartnerBookmarkMappings, +#endif // defined(OS_ANDROID) // Metrics preferences are out of profile scope and are merged between // incognito and regular modes. @@ -206,37 +209,8 @@ // audited, checked with owners, and removed or transfered to // |kPersistentPrefNames|. const char* const kTemporaryIncognitoWhitelist[] = { - // chrome/common/pref_names.h - prefs::kWebRTCMultipleRoutesEnabled, - prefs::kWebRTCNonProxiedUdpEnabled, - prefs::kWebRTCIPHandlingPolicy, - - prefs::kDefaultTasksByMimeType, - prefs::kDefaultTasksBySuffix, - - prefs::kDefaultAudioCaptureDevice, - prefs::kDefaultVideoCaptureDevice, prefs::kMediaDeviceIdSalt, - prefs::kClearPluginLSODataEnabled, - prefs::kPepperFlashSettingsEnabled, - - prefs::kPerformanceTracingEnabled, - -#if !defined(OS_ANDROID) - prefs::kMediaGalleriesUniqueId, - prefs::kMediaGalleriesRememberedGalleries, -#endif // !defined(OS_ANDROID) - -#if defined(OS_ANDROID) - prefs::kPartnerBookmarkMappings, -#endif // defined(OS_ANDROID) - -#if BUILDFLAG(ENABLE_BACKGROUND_MODE) -// prefs::kRestartInBackground, -#endif - - prefs::kBackgroundTracingLastUpload, }; } // namespace
diff --git a/chrome/browser/resources/chromeos/chromevox/BUILD.gn b/chrome/browser/resources/chromeos/chromevox/BUILD.gn index 30a3a87..c9213194 100644 --- a/chrome/browser/resources/chromeos/chromevox/BUILD.gn +++ b/chrome/browser/resources/chromeos/chromevox/BUILD.gn
@@ -45,7 +45,6 @@ "chromevox/background/tabs_api_handler.js", "chromevox/injected/active_indicator.js", "chromevox/injected/api_implementation.js", - "chromevox/injected/console_tts.js", "chromevox/injected/event_suspender.js", "chromevox/injected/event_watcher.js", "chromevox/injected/history.js", @@ -125,6 +124,7 @@ "cvox2/background/braille_command_handler.js", "cvox2/background/chromevox_state.js", "cvox2/background/command_handler.js", + "cvox2/background/console_tts.js", "cvox2/background/constants.js", "cvox2/background/cursors.js", "cvox2/background/custom_automation_event.js",
diff --git a/chrome/browser/resources/chromeos/chromevox/braille/nav_braille.js b/chrome/browser/resources/chromeos/chromevox/braille/nav_braille.js index 9069c05..5ec2769 100644 --- a/chrome/browser/resources/chromeos/chromevox/braille/nav_braille.js +++ b/chrome/browser/resources/chromeos/chromevox/braille/nav_braille.js
@@ -11,8 +11,6 @@ goog.provide('cvox.NavBraille'); -goog.require('LogStore'); -goog.require('TextLog'); goog.require('Spannable'); /** @@ -111,15 +109,3 @@ endIndex: this.endIndex }; }; - -/** - * Output braille text to console. - */ -cvox.NavBraille.prototype.brailleLogging = function() { - if (localStorage['enableBrailleLogging'] != 'true') - return; - - var logStr = 'Braille "' + this.text.toString() + '"'; - LogStore.getInstance().writeTextLog(logStr, TextLog.LogType.BRAILLE); - console.log(logStr); -};
diff --git a/chrome/browser/resources/chromeos/chromevox/chromevox/background/background.js b/chrome/browser/resources/chromeos/chromevox/chromevox/background/background.js index fca0d8f..5d4371e 100644 --- a/chrome/browser/resources/chromeos/chromevox/chromevox/background/background.js +++ b/chrome/browser/resources/chromeos/chromevox/chromevox/background/background.js
@@ -9,6 +9,7 @@ goog.provide('cvox.ChromeVoxBackground'); goog.require('ChromeVoxState'); +goog.require('ConsoleTts'); goog.require('EventStreamLogger'); goog.require('LogStore'); goog.require('Msgs'); @@ -21,7 +22,6 @@ goog.require('cvox.ChromeVoxPrefs'); goog.require('cvox.ClassicEarcons'); goog.require('cvox.CompositeTts'); -goog.require('cvox.ConsoleTts'); goog.require('cvox.ExtensionBridge'); goog.require('cvox.InjectedScriptLoader'); goog.require('cvox.NavBraille'); @@ -131,7 +131,7 @@ this.prefs = new cvox.ChromeVoxPrefs(); cvox.ChromeVoxBackground.readPrefs(); - var consoleTts = cvox.ConsoleTts.getInstance(); + var consoleTts = ConsoleTts.getInstance(); consoleTts.setEnabled(this.prefs.getPrefs()['enableSpeechLogging'] == 'true'); LogStore.getInstance();
diff --git a/chrome/browser/resources/chromeos/chromevox/chromevox/background/options.js b/chrome/browser/resources/chromeos/chromevox/chromevox/background/options.js index 25680de..766c29c2 100644 --- a/chrome/browser/resources/chromeos/chromevox/chromevox/background/options.js +++ b/chrome/browser/resources/chromeos/chromevox/chromevox/background/options.js
@@ -9,6 +9,7 @@ goog.provide('cvox.OptionsPage'); +goog.require('ConsoleTts'); goog.require('EventStreamLogger'); goog.require('Msgs'); goog.require('PanelCommand'); @@ -19,7 +20,6 @@ goog.require('cvox.ChromeVox'); goog.require('cvox.ChromeVoxPrefs'); goog.require('cvox.CommandStore'); -goog.require('cvox.ConsoleTts'); goog.require('cvox.ExtensionBridge'); goog.require('cvox.PlatformFilter'); goog.require('cvox.PlatformUtil'); @@ -38,7 +38,7 @@ /** * The ChromeVoxConsoleTts object. - * @type {cvox.ConsoleTts} + * @type {ConsoleTts} */ cvox.OptionsPage.consoleTts; @@ -50,7 +50,7 @@ cvox.OptionsPage.init = function() { cvox.OptionsPage.prefs = chrome.extension.getBackgroundPage().prefs; cvox.OptionsPage.consoleTts = - chrome.extension.getBackgroundPage().cvox.ConsoleTts.getInstance(); + chrome.extension.getBackgroundPage().ConsoleTts.getInstance(); cvox.OptionsPage.populateVoicesSelect(); cvox.BrailleTable.getAll(function(tables) { /** @type {!Array<cvox.BrailleTable.Table>} */
diff --git a/chrome/browser/resources/chromeos/chromevox/chromevox/background/prefs.js b/chrome/browser/resources/chromeos/chromevox/chromevox/background/prefs.js index bcf78ef1..159b38a 100644 --- a/chrome/browser/resources/chromeos/chromevox/chromevox/background/prefs.js +++ b/chrome/browser/resources/chromeos/chromevox/chromevox/background/prefs.js
@@ -10,9 +10,9 @@ goog.provide('cvox.ChromeVoxPrefs'); +goog.require('ConsoleTts'); goog.require('EventStreamLogger'); goog.require('cvox.ChromeVox'); -goog.require('cvox.ConsoleTts'); goog.require('cvox.ExtensionBridge'); goog.require('cvox.KeyMap'); @@ -303,7 +303,7 @@ cvox.ChromeVoxPrefs.prototype.setLoggingPrefs = function(key, value) { localStorage[key] = value; if (key == 'enableSpeechLogging') - cvox.ConsoleTts.getInstance().setEnabled(value); + ConsoleTts.getInstance().setEnabled(value); else if (key == 'enableEventStreamLogging') EventStreamLogger.instance.notifyEventStreamFilterChangedAll(value); };
diff --git a/chrome/browser/resources/chromeos/chromevox/chromevox/injected/console_tts.js b/chrome/browser/resources/chromeos/chromevox/chromevox/injected/console_tts.js deleted file mode 100644 index 2fa0916d..0000000 --- a/chrome/browser/resources/chromeos/chromevox/chromevox/injected/console_tts.js +++ /dev/null
@@ -1,85 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -/** - * @fileoverview A TTS engine that writes to window.console. - */ - -goog.provide('cvox.ConsoleTts'); - -goog.require('LogStore'); -goog.require('TextLog'); -goog.require('cvox.AbstractTts'); -goog.require('cvox.TtsInterface'); - -/** - * @constructor - * @implements {cvox.TtsInterface} - */ -cvox.ConsoleTts = function() { - /** - * True if the console TTS is enabled by the user. - * @type {boolean} - * @private - */ - this.enabled_ = false; -}; -goog.addSingletonGetter(cvox.ConsoleTts); - - -/** @override */ -cvox.ConsoleTts.prototype.speak = function(textString, queueMode, properties) { - if (this.enabled_ && window['console']) { - var logStr = 'Speak'; - if (queueMode == cvox.QueueMode.FLUSH) { - logStr += ' (I)'; - } else if (queueMode == cvox.QueueMode.CATEGORY_FLUSH) { - logStr += ' (C)'; - } else { - logStr += ' (Q)'; - } - if (properties && properties.category) { - logStr += ' category=' + properties.category; - } - logStr += ' "' + textString + '"'; - LogStore.getInstance().writeTextLog(logStr, TextLog.LogType.SPEECH); - console.log(logStr); - } - return this; -}; - -/** @override */ -cvox.ConsoleTts.prototype.isSpeaking = function() { - return false; -}; - -/** @override */ -cvox.ConsoleTts.prototype.stop = function() { - if (this.enabled_) { - console.log('Stop'); - } -}; - -/** @override */ -cvox.ConsoleTts.prototype.addCapturingEventListener = function(listener) {}; - -/** @override */ -cvox.ConsoleTts.prototype.increaseOrDecreaseProperty = function() {}; - -/** @override */ -cvox.ConsoleTts.prototype.propertyToPercentage = function() {}; - -/** - * Sets the enabled bit. - * @param {boolean} enabled The new enabled bit. - */ -cvox.ConsoleTts.prototype.setEnabled = function(enabled) { - this.enabled_ = enabled; -}; - -/** @override */ -cvox.ConsoleTts.prototype.getDefaultProperty = function(property) {}; - -/** @override */ -cvox.ConsoleTts.prototype.toggleSpeechOnOrOff = function() {};
diff --git a/chrome/browser/resources/chromeos/chromevox/chromevox/injected/init_globals.js b/chrome/browser/resources/chromeos/chromevox/chromevox/injected/init_globals.js index 243117e6..d140a9c 100644 --- a/chrome/browser/resources/chromeos/chromevox/chromevox/injected/init_globals.js +++ b/chrome/browser/resources/chromeos/chromevox/chromevox/injected/init_globals.js
@@ -12,7 +12,6 @@ goog.require('cvox.ChromeVox'); goog.require('cvox.ChromeVoxEventWatcher'); goog.require('cvox.CompositeTts'); -goog.require('cvox.ConsoleTts'); goog.require('cvox.HostFactory'); goog.require('cvox.NavigationManager'); goog.require('cvox.Serializer'); @@ -35,8 +34,7 @@ cvox.ChromeVox.tts = new cvox.CompositeTts() .add(cvox.HostFactory.getTts()) - .add(cvox.History.getInstance()) - .add(cvox.ConsoleTts.getInstance()); + .add(cvox.History.getInstance()); if (!cvox.ChromeVox.braille) { cvox.ChromeVox.braille = cvox.HostFactory.getBraille();
diff --git a/chrome/browser/resources/chromeos/chromevox/chromevox/injected/user_commands.js b/chrome/browser/resources/chromeos/chromevox/chromevox/injected/user_commands.js index 991f5ab..356d52c 100644 --- a/chrome/browser/resources/chromeos/chromevox/chromevox/injected/user_commands.js +++ b/chrome/browser/resources/chromeos/chromevox/chromevox/injected/user_commands.js
@@ -22,7 +22,6 @@ goog.require('cvox.ChromeVox'); goog.require('cvox.ChromeVoxKbHandler'); goog.require('cvox.CommandStore'); -goog.require('cvox.ConsoleTts'); goog.require('cvox.ContextMenuWidget'); goog.require('cvox.DomPredicates'); goog.require('cvox.DomUtil'); @@ -572,9 +571,6 @@ case 'stopHistoryRecording': cvox.History.getInstance().stopRecording(); break; - case 'enableConsoleTts': - cvox.ConsoleTts.getInstance().setEnabled(true); - break; case 'toggleBrailleCaptions': cvox.ChromeVox.host.sendToBackgroundPage({ 'target': 'Prefs',
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/console_tts.js b/chrome/browser/resources/chromeos/chromevox/cvox2/background/console_tts.js new file mode 100644 index 0000000..0c3896c --- /dev/null +++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/console_tts.js
@@ -0,0 +1,87 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/** + * @fileoverview A TTS engine that writes to window.console. + */ + +goog.provide('ConsoleTts'); + +goog.require('LogStore'); +goog.require('TextLog'); +goog.require('cvox.AbstractTts'); +goog.require('cvox.TtsInterface'); + +/** + * @constructor + * @implements {cvox.TtsInterface} + */ +ConsoleTts = function() { + /** + * True if the console TTS is enabled by the user. + * @type {boolean} + * @private + */ + this.enabled_ = false; +}; +goog.addSingletonGetter(ConsoleTts); + + +/** @override */ +ConsoleTts.prototype = { + speak: function(textString, queueMode, properties) { + if (this.enabled_ && window['console']) { + var logStr = 'Speak'; + if (queueMode == cvox.QueueMode.FLUSH) { + logStr += ' (I)'; + } else if (queueMode == cvox.QueueMode.CATEGORY_FLUSH) { + logStr += ' (C)'; + } else { + logStr += ' (Q)'; + } + if (properties && properties.category) { + logStr += ' category=' + properties.category; + } + logStr += ' "' + textString + '"'; + LogStore.getInstance().writeTextLog(logStr, TextLog.LogType.SPEECH); + console.log(logStr); + } + return this; + }, + + /** @override */ + isSpeaking: function() { + return false; + }, + + /** @override */ + stop: function() { + if (this.enabled_) { + console.log('Stop'); + } + }, + + /** @override */ + addCapturingEventListener: function(listener) {}, + + /** @override */ + increaseOrDecreaseProperty: function() {}, + + /** @override */ + propertyToPercentage: function() {}, + + /** + * Sets the enabled bit. + * @param {boolean} enabled The new enabled bit. + */ + setEnabled: function(enabled) { + this.enabled_ = enabled; + }, + + /** @override */ + getDefaultProperty: function(property) {}, + + /** @override */ + toggleSpeechOnOrOff: function() {} +};
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/output.js b/chrome/browser/resources/chromeos/chromevox/cvox2/background/output.js index 0ef9c11..8f7ca2e 100644 --- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/output.js +++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/output.js
@@ -1073,7 +1073,6 @@ var output = new cvox.NavBraille( {text: buff, startIndex: startIndex, endIndex: endIndex}); - output.brailleLogging(); cvox.ChromeVox.braille.write(output); if (this.brailleRulesStr_.str) {
diff --git a/chrome/browser/resources/chromeos/chromevox/host/chrome/braille_background.js b/chrome/browser/resources/chromeos/chromevox/host/chrome/braille_background.js index b77c546..bb0e4a1e 100644 --- a/chrome/browser/resources/chromeos/chromevox/host/chrome/braille_background.js +++ b/chrome/browser/resources/chromeos/chromevox/host/chrome/braille_background.js
@@ -10,6 +10,7 @@ goog.require('BrailleKeyEventRewriter'); goog.require('ChromeVoxState'); +goog.require('LogStore'); goog.require('cvox.BrailleDisplayManager'); goog.require('cvox.BrailleInputHandler'); goog.require('cvox.BrailleInterface'); @@ -73,6 +74,13 @@ if (this.frozen_) { return; } + + if (localStorage['enableBrailleLogging'] == 'true') { + var logStr = 'Braille "' + params.text.toString() + '"'; + LogStore.getInstance().writeTextLog(logStr, TextLog.LogType.BRAILLE); + console.log(logStr); + } + this.setContent_(params, null); };
diff --git a/chrome/browser/resources/chromeos/zip_archiver/cpp/BUILD.gn b/chrome/browser/resources/chromeos/zip_archiver/cpp/BUILD.gn index e90607aa..a030b278 100644 --- a/chrome/browser/resources/chromeos/zip_archiver/cpp/BUILD.gn +++ b/chrome/browser/resources/chromeos/zip_archiver/cpp/BUILD.gn
@@ -22,6 +22,7 @@ "request.h", "volume.cc", "volume.h", + "volume_archive.cc", "volume_archive.h", "volume_archive_minizip.cc", "volume_archive_minizip.h",
diff --git a/chrome/browser/resources/chromeos/zip_archiver/cpp/compressor.cc b/chrome/browser/resources/chromeos/zip_archiver/cpp/compressor.cc index 14630495..1b3c7b42 100644 --- a/chrome/browser/resources/chromeos/zip_archiver/cpp/compressor.cc +++ b/chrome/browser/resources/chromeos/zip_archiver/cpp/compressor.cc
@@ -26,14 +26,14 @@ explicit JavaScriptCompressorRequestor(Compressor* compressor) : compressor_(compressor) {} - virtual void WriteChunkRequest(int64_t offset, - int64_t length, - const pp::VarArrayBuffer& buffer) { + void WriteChunkRequest(int64_t offset, + int64_t length, + const pp::VarArrayBuffer& buffer) override { compressor_->message_sender()->SendWriteChunk(compressor_->compressor_id(), buffer, offset, length); } - virtual void ReadFileChunkRequest(int64_t length) { + void ReadFileChunkRequest(int64_t length) override { compressor_->message_sender()->SendReadFileChunk( compressor_->compressor_id(), length); }
diff --git a/chrome/browser/resources/chromeos/zip_archiver/cpp/compressor_archive_minizip.h b/chrome/browser/resources/chromeos/zip_archiver/cpp/compressor_archive_minizip.h index b2d739a..0c8dbcc 100644 --- a/chrome/browser/resources/chromeos/zip_archiver/cpp/compressor_archive_minizip.h +++ b/chrome/browser/resources/chromeos/zip_archiver/cpp/compressor_archive_minizip.h
@@ -35,22 +35,22 @@ public: explicit CompressorArchiveMinizip(CompressorStream* compressor_stream); - virtual ~CompressorArchiveMinizip(); + ~CompressorArchiveMinizip() override; // Creates an archive object. - virtual bool CreateArchive(); + bool CreateArchive() override; // Closes the archive. - virtual bool CloseArchive(bool has_error); + bool CloseArchive(bool has_error) override; // Cancels the compression process. - virtual void CancelArchive(); + void CancelArchive() override; // Adds an entry to the archive. - virtual bool AddToArchive(const std::string& filename, - int64_t file_size, - int64_t modification_time, - bool is_directory); + bool AddToArchive(const std::string& filename, + int64_t file_size, + int64_t modification_time, + bool is_directory) override; // A getter function for zip_file_. zipFile zip_file() const { return zip_file_; }
diff --git a/chrome/browser/resources/chromeos/zip_archiver/cpp/compressor_io_javascript_stream.cc b/chrome/browser/resources/chromeos/zip_archiver/cpp/compressor_io_javascript_stream.cc index 8a0a13c..bc15e66 100644 --- a/chrome/browser/resources/chromeos/zip_archiver/cpp/compressor_io_javascript_stream.cc +++ b/chrome/browser/resources/chromeos/zip_archiver/cpp/compressor_io_javascript_stream.cc
@@ -22,31 +22,19 @@ CompressorIOJavaScriptStream::CompressorIOJavaScriptStream( JavaScriptCompressorRequestorInterface* requestor) : requestor_(requestor), + available_data_cond_(&shared_state_lock_), + data_written_cond_(&shared_state_lock_), + available_data_(false), buffer_offset_(-1), buffer_data_length_(0), - buffer_(std::make_unique<char[]>(kMaximumDataChunkSize)) { - pthread_mutex_init(&shared_state_lock_, nullptr); - pthread_cond_init(&available_data_cond_, nullptr); - pthread_cond_init(&data_written_cond_, nullptr); + buffer_(std::make_unique<char[]>(kMaximumDataChunkSize)) {} - pthread_mutex_lock(&shared_state_lock_); - available_data_ = false; - pthread_mutex_unlock(&shared_state_lock_); -} - -CompressorIOJavaScriptStream::~CompressorIOJavaScriptStream() { - pthread_mutex_lock(&shared_state_lock_); - pthread_mutex_unlock(&shared_state_lock_); - pthread_cond_destroy(&data_written_cond_); - pthread_cond_destroy(&available_data_cond_); - pthread_mutex_destroy(&shared_state_lock_); -} +CompressorIOJavaScriptStream::~CompressorIOJavaScriptStream() = default; int64_t CompressorIOJavaScriptStream::Flush() { - pthread_mutex_lock(&shared_state_lock_); + base::AutoLock al(shared_state_lock_); if (buffer_data_length_ == 0) { - pthread_mutex_unlock(&shared_state_lock_); return 0; } @@ -59,11 +47,11 @@ requestor_->WriteChunkRequest(buffer_offset_, buffer_data_length_, array_buffer); - pthread_cond_wait(&data_written_cond_, &shared_state_lock_); + // TODO(amistry): Handle spurious wakeups. + data_written_cond_.Wait(); int64_t written_bytes = written_bytes_; if (written_bytes < buffer_data_length_) { - pthread_mutex_unlock(&shared_state_lock_); return -1 /* Error */; } @@ -71,14 +59,13 @@ buffer_offset_ = -1; buffer_data_length_ = 0; - pthread_mutex_unlock(&shared_state_lock_); return written_bytes; } int64_t CompressorIOJavaScriptStream::Write(int64_t zip_offset, int64_t zip_length, const char* zip_buffer) { - pthread_mutex_lock(&shared_state_lock_); + base::AutoLock al(shared_state_lock_); // The offset from which the data should be written onto the archive. int64_t current_offset = zip_offset; @@ -104,11 +91,11 @@ (current_offset < buffer_offset_ || buffer_offset_ + buffer_data_length_ < current_offset + left_length) /* 4 */) { - pthread_mutex_unlock(&shared_state_lock_); int64_t bytes_to_write = buffer_data_length_; + + base::AutoUnlock aul(shared_state_lock_); if (Flush() != bytes_to_write) return -1; - pthread_mutex_lock(&shared_state_lock_); } // How many bytes we should copy to buffer_ in this iteration. @@ -129,39 +116,36 @@ left_length -= copy_length; } while (left_length > 0); - pthread_mutex_unlock(&shared_state_lock_); return zip_length; } int64_t CompressorIOJavaScriptStream::WriteChunkDone(int64_t written_bytes) { - pthread_mutex_lock(&shared_state_lock_); + base::AutoLock al(shared_state_lock_); written_bytes_ = written_bytes; - pthread_cond_signal(&data_written_cond_); - pthread_mutex_unlock(&shared_state_lock_); + data_written_cond_.Signal(); return written_bytes; } int64_t CompressorIOJavaScriptStream::Read(int64_t bytes_to_read, char* destination_buffer) { - pthread_mutex_lock(&shared_state_lock_); + base::AutoLock al(shared_state_lock_); destination_buffer_ = destination_buffer; requestor_->ReadFileChunkRequest(bytes_to_read); while (!available_data_) { - pthread_cond_wait(&available_data_cond_, &shared_state_lock_); + available_data_cond_.Wait(); } int64_t read_bytes = read_bytes_; available_data_ = false; - pthread_mutex_unlock(&shared_state_lock_); return read_bytes; } int64_t CompressorIOJavaScriptStream::ReadFileChunkDone( int64_t read_bytes, pp::VarArrayBuffer* array_buffer) { - pthread_mutex_lock(&shared_state_lock_); + base::AutoLock al(shared_state_lock_); // JavaScript sets a negative value in read_bytes if an error occurred while // reading a chunk. @@ -173,7 +157,6 @@ read_bytes_ = read_bytes; available_data_ = true; - pthread_cond_signal(&available_data_cond_); - pthread_mutex_unlock(&shared_state_lock_); + available_data_cond_.Signal(); return read_bytes; }
diff --git a/chrome/browser/resources/chromeos/zip_archiver/cpp/compressor_io_javascript_stream.h b/chrome/browser/resources/chromeos/zip_archiver/cpp/compressor_io_javascript_stream.h index b967c4c..524fa36 100644 --- a/chrome/browser/resources/chromeos/zip_archiver/cpp/compressor_io_javascript_stream.h +++ b/chrome/browser/resources/chromeos/zip_archiver/cpp/compressor_io_javascript_stream.h
@@ -5,17 +5,16 @@ #ifndef CHROME_BROWSER_RESOURCES_CHROMEOS_ZIP_ARCHIVER_CPP_COMPRESSOR_IO_JAVASCRIPT_STREAM_H_ #define CHROME_BROWSER_RESOURCES_CHROMEOS_ZIP_ARCHIVER_CPP_COMPRESSOR_IO_JAVASCRIPT_STREAM_H_ -#include <pthread.h> #include <cstdint> #include <memory> #include <string> +#include "base/synchronization/condition_variable.h" +#include "base/synchronization/lock.h" #include "chrome/browser/resources/chromeos/zip_archiver/cpp/compressor_stream.h" #include "ppapi/cpp/instance_handle.h" #include "ppapi/cpp/var_array_buffer.h" #include "ppapi/utility/completion_callback_factory.h" -#include "ppapi/utility/threading/lock.h" -#include "ppapi/utility/threading/simple_thread.h" class JavaScriptCompressorRequestorInterface; @@ -24,31 +23,31 @@ CompressorIOJavaScriptStream( JavaScriptCompressorRequestorInterface* requestor); - virtual ~CompressorIOJavaScriptStream(); + ~CompressorIOJavaScriptStream() override; // Flushes the data in buffer_. Since minizip sends tons of write requests and // communication between C++ and JS is very expensive, we need to cache data // in buffer_ and send them in a lump. - virtual int64_t Flush(); + int64_t Flush() override; - virtual int64_t Write(int64_t zip_offset, - int64_t zip_length, - const char* zip_buffer); + int64_t Write(int64_t zip_offset, + int64_t zip_length, + const char* zip_buffer) override; - virtual int64_t WriteChunkDone(int64_t write_bytes); + int64_t WriteChunkDone(int64_t write_bytes) override; - virtual int64_t Read(int64_t bytes_to_read, char* destination_buffer); + int64_t Read(int64_t bytes_to_read, char* destination_buffer) override; - virtual int64_t ReadFileChunkDone(int64_t read_bytes, - pp::VarArrayBuffer* buffer); + int64_t ReadFileChunkDone(int64_t read_bytes, + pp::VarArrayBuffer* buffer) override; private: // A requestor that makes calls to JavaScript to read and write chunks. JavaScriptCompressorRequestorInterface* requestor_; - pthread_mutex_t shared_state_lock_; - pthread_cond_t available_data_cond_; - pthread_cond_t data_written_cond_; + base::Lock shared_state_lock_; + base::ConditionVariable available_data_cond_; + base::ConditionVariable data_written_cond_; // The bytelength of the data written onto the archive for the last write // chunk request. If this value is negative, some error occurred when writing
diff --git a/chrome/browser/resources/chromeos/zip_archiver/cpp/volume.cc b/chrome/browser/resources/chromeos/zip_archiver/cpp/volume.cc index a2b1662..bbb5f1fd 100644 --- a/chrome/browser/resources/chromeos/zip_archiver/cpp/volume.cc +++ b/chrome/browser/resources/chromeos/zip_archiver/cpp/volume.cc
@@ -63,7 +63,7 @@ pp::VarDictionary parent_entries = pp::VarDictionary(parent_metadata->Get("entries")); - unsigned int position = entry_path.find(kPathDelimiter); + std::string::size_type position = entry_path.find(kPathDelimiter); pp::VarDictionary entry_metadata; std::string entry_name; @@ -114,16 +114,16 @@ // JavaScriptRequestor does not own the volume pointer. explicit JavaScriptRequestor(Volume* volume) : volume_(volume) {} - virtual void RequestFileChunk(const std::string& request_id, - int64_t offset, - int64_t bytes_to_read) { + void RequestFileChunk(const std::string& request_id, + int64_t offset, + int64_t bytes_to_read) override { PP_DCHECK(offset >= 0); PP_DCHECK(bytes_to_read > 0); volume_->message_sender()->SendFileChunkRequest( volume_->file_system_id(), request_id, offset, bytes_to_read); } - virtual void RequestPassphrase(const std::string& request_id) { + void RequestPassphrase(const std::string& request_id) override { volume_->message_sender()->SendPassphraseRequest(volume_->file_system_id(), request_id); } @@ -136,8 +136,8 @@ // Volume constructor. class VolumeArchiveFactory : public VolumeArchiveFactoryInterface { public: - virtual std::unique_ptr<VolumeArchive> Create( - std::unique_ptr<VolumeReader> reader) { + std::unique_ptr<VolumeArchive> Create( + std::unique_ptr<VolumeReader> reader) override { return std::make_unique<VolumeArchiveMinizip>(std::move(reader)); } }; @@ -149,7 +149,7 @@ // VolumeReaderFactory does not own the volume pointer. explicit VolumeReaderFactory(Volume* volume) : volume_(volume) {} - virtual std::unique_ptr<VolumeReader> Create(int64_t archive_size) { + std::unique_ptr<VolumeReader> Create(int64_t archive_size) override { return std::make_unique<VolumeReaderJavaScriptStream>(archive_size, volume_->requestor()); }
diff --git a/chrome/browser/resources/chromeos/zip_archiver/cpp/volume_archive.cc b/chrome/browser/resources/chromeos/zip_archiver/cpp/volume_archive.cc new file mode 100644 index 0000000..27cdd0a --- /dev/null +++ b/chrome/browser/resources/chromeos/zip_archiver/cpp/volume_archive.cc
@@ -0,0 +1,10 @@ +// 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/resources/chromeos/zip_archiver/cpp/volume_archive.h" + +VolumeArchive::VolumeArchive(std::unique_ptr<VolumeReader> reader) + : reader_(std::move(reader)) {} + +VolumeArchive::~VolumeArchive() = default;
diff --git a/chrome/browser/resources/chromeos/zip_archiver/cpp/volume_archive.h b/chrome/browser/resources/chromeos/zip_archiver/cpp/volume_archive.h index ed835d0..4629ef3f 100644 --- a/chrome/browser/resources/chromeos/zip_archiver/cpp/volume_archive.h +++ b/chrome/browser/resources/chromeos/zip_archiver/cpp/volume_archive.h
@@ -17,10 +17,9 @@ // to be thread safe and its methods shouldn't be called in parallel. class VolumeArchive { public: - explicit VolumeArchive(std::unique_ptr<VolumeReader> reader) - : reader_(std::move(reader)) {} + explicit VolumeArchive(std::unique_ptr<VolumeReader> reader); - virtual ~VolumeArchive() {} + virtual ~VolumeArchive(); // For functions that need to return more than pass/fail results. enum Result {
diff --git a/chrome/browser/resources/chromeos/zip_archiver/cpp/volume_archive_minizip.cc b/chrome/browser/resources/chromeos/zip_archiver/cpp/volume_archive_minizip.cc index 804ee0ed..3031aa7 100644 --- a/chrome/browser/resources/chromeos/zip_archiver/cpp/volume_archive_minizip.cc +++ b/chrome/browser/resources/chromeos/zip_archiver/cpp/volume_archive_minizip.cc
@@ -246,8 +246,8 @@ int64_t previous_offset = reader()->offset(); char* buffer_pointer = static_cache_.get(); int64_t left_length = static_cache_size_; - static_cache_offset_ = - std::max(reader()->archive_size() - static_cache_size_, 0LL); + static_cache_offset_ = std::max(reader()->archive_size() - static_cache_size_, + static_cast<int64_t>(0)); if (reader()->Seek(static_cache_offset_, ZLIB_FILEFUNC_SEEK_SET) < 0) { set_error_message(kArchiveOpenError); return false /* Error */;
diff --git a/chrome/browser/resources/chromeos/zip_archiver/cpp/volume_archive_minizip.h b/chrome/browser/resources/chromeos/zip_archiver/cpp/volume_archive_minizip.h index dd114b05..0a91456 100644 --- a/chrome/browser/resources/chromeos/zip_archiver/cpp/volume_archive_minizip.h +++ b/chrome/browser/resources/chromeos/zip_archiver/cpp/volume_archive_minizip.h
@@ -45,31 +45,33 @@ public: explicit VolumeArchiveMinizip(std::unique_ptr<VolumeReader> reader); - virtual ~VolumeArchiveMinizip(); + ~VolumeArchiveMinizip() override; // See volume_archive_interface.h. - virtual bool Init(const std::string& encoding); + bool Init(const std::string& encoding) override; // See volume_archive_interface.h. - virtual VolumeArchive::Result GetCurrentFileInfo(std::string* path_name, - bool* isEncodedInUtf8, - int64_t* size, - bool* is_directory, - time_t* modification_time); + VolumeArchive::Result GetCurrentFileInfo(std::string* path_name, + bool* isEncodedInUtf8, + int64_t* size, + bool* is_directory, + time_t* modification_time) override; - virtual VolumeArchive::Result GoToNextFile(); + VolumeArchive::Result GoToNextFile() override; // See volume_archive_interface.h. - virtual bool SeekHeader(const std::string& path_name); + bool SeekHeader(const std::string& path_name) override; // See volume_archive_interface.h. - virtual int64_t ReadData(int64_t offset, int64_t length, const char** buffer); + int64_t ReadData(int64_t offset, + int64_t length, + const char** buffer) override; // See volume_archive_interface.h. - virtual void MaybeDecompressAhead(); + void MaybeDecompressAhead() override; // See volume_archive_interface.h. - virtual bool Cleanup(); + bool Cleanup() override; int64_t reader_data_size() const { return reader_data_size_; }
diff --git a/chrome/browser/resources/chromeos/zip_archiver/cpp/volume_reader_javascript_stream.cc b/chrome/browser/resources/chromeos/zip_archiver/cpp/volume_reader_javascript_stream.cc index 5e541cb0..221ad451 100644 --- a/chrome/browser/resources/chromeos/zip_archiver/cpp/volume_reader_javascript_stream.cc +++ b/chrome/browser/resources/chromeos/zip_archiver/cpp/volume_reader_javascript_stream.cc
@@ -19,15 +19,13 @@ available_data_(false), read_error_(false), passphrase_error_(false), + available_data_cond_(&shared_state_lock_), + available_passphrase_cond_(&shared_state_lock_), offset_(0), // For first call -1 will force a chunk request from JavaScript as offset // parameter is 0. last_read_chunk_offset_(-1), read_ahead_array_buffer_ptr_(&first_array_buffer_) { - pthread_mutex_init(&shared_state_lock_, nullptr); - pthread_cond_init(&available_data_cond_, nullptr); - pthread_cond_init(&available_passphrase_cond_, nullptr); - // Dummy Map the second buffer as first buffer is used for read ahead by // read_ahead_array_buffer_ptr_. This operation is required in order for Unmap // to correctly work in the destructor and VolumeReaderJavaScriptStream::Read. @@ -35,10 +33,6 @@ } VolumeReaderJavaScriptStream::~VolumeReaderJavaScriptStream() { - pthread_mutex_destroy(&shared_state_lock_); - pthread_cond_destroy(&available_data_cond_); - pthread_cond_destroy(&available_passphrase_cond_); - // Unmap last mapped buffer. This is the other buffer to // read_ahead_array_buffer_ptr_ as read_ahead_array_buffer_ptr_ must be // available for SetBufferAndSignal to overwrite. @@ -48,6 +42,14 @@ second_array_buffer_.Unmap(); } +int64_t VolumeReaderJavaScriptStream::offset() { + return offset_; +} + +int64_t VolumeReaderJavaScriptStream::archive_size() { + return archive_size_; +} + void VolumeReaderJavaScriptStream::SetBufferAndSignal( const pp::VarArrayBuffer& array_buffer, int64_t read_offset) { @@ -68,7 +70,7 @@ // buffer can still be used. In such case we should use it. That can greatly // improve traversing headers for archives with small files! - pthread_mutex_lock(&shared_state_lock_); + base::AutoLock al(shared_state_lock_); if (read_offset == offset_ && !available_data_ && !read_error_) { // Signal VolumeReaderJavaScriptStream::Read to continue execution. Copies // buffer locally so minizip has the buffer in memory when working with @@ -80,43 +82,38 @@ *read_ahead_array_buffer_ptr_ = array_buffer; // Copy operation. available_data_ = true; - pthread_cond_signal(&available_data_cond_); + available_data_cond_.Signal(); } - pthread_mutex_unlock(&shared_state_lock_); } void VolumeReaderJavaScriptStream::ReadErrorSignal() { - pthread_mutex_lock(&shared_state_lock_); + base::AutoLock al(shared_state_lock_); read_error_ = true; // Read error from JavaScript. - pthread_cond_signal(&available_data_cond_); - pthread_mutex_unlock(&shared_state_lock_); + available_data_cond_.Signal(); } void VolumeReaderJavaScriptStream::SetPassphraseAndSignal( const std::string& passphrase) { - pthread_mutex_lock(&shared_state_lock_); + base::AutoLock al(shared_state_lock_); // Signal VolumeReaderJavaScriptStream::Passphrase to continue execution. available_passphrase_ = passphrase; - pthread_cond_signal(&available_passphrase_cond_); - pthread_mutex_unlock(&shared_state_lock_); + available_passphrase_cond_.Signal(); } void VolumeReaderJavaScriptStream::PassphraseErrorSignal() { - pthread_mutex_lock(&shared_state_lock_); + base::AutoLock al(shared_state_lock_); passphrase_error_ = true; // Passphrase error from JavaScript. - pthread_cond_signal(&available_passphrase_cond_); - pthread_mutex_unlock(&shared_state_lock_); + available_passphrase_cond_.Signal(); } int64_t VolumeReaderJavaScriptStream::Read(int64_t bytes_to_read, const void** destination_buffer) { PP_DCHECK(bytes_to_read > 0); - pthread_mutex_lock(&shared_state_lock_); + base::AutoLock al(shared_state_lock_); // No more data, so signal end of reading. if (offset_ >= archive_size_) { - pthread_mutex_unlock(&shared_state_lock_); return 0; } @@ -129,15 +126,13 @@ while (!available_data_) { // Check again available data as first call // was done outside guarded zone. if (read_error_) { - pthread_mutex_unlock(&shared_state_lock_); return -1; } - pthread_cond_wait(&available_data_cond_, &shared_state_lock_); + available_data_cond_.Wait(); } } if (read_error_) { // Read ahead failed. - pthread_mutex_unlock(&shared_state_lock_); return -1; } @@ -178,13 +173,12 @@ // Read ahead next chunk with a length similar to current read. RequestChunk(bytes_to_read); - pthread_mutex_unlock(&shared_state_lock_); return bytes_read; } int64_t VolumeReaderJavaScriptStream::Seek(int64_t offset, int whence) { - pthread_mutex_lock(&shared_state_lock_); + base::AutoLock al(shared_state_lock_); int64_t new_offset = offset_; switch (whence) { @@ -199,17 +193,14 @@ break; default: PP_NOTREACHED(); - pthread_mutex_unlock(&shared_state_lock_); return -1; } if (new_offset < 0) { - pthread_mutex_unlock(&shared_state_lock_); return -1; } offset_ = new_offset; - pthread_mutex_unlock(&shared_state_lock_); return new_offset; } @@ -224,25 +215,24 @@ // The error is not recoverable. Once passphrase fails to be provided, it is // never asked again. Note, that still users are able to retry entering the // password, unless they click Cancel. - pthread_mutex_lock(&shared_state_lock_); - if (passphrase_error_) { - pthread_mutex_unlock(&shared_state_lock_); - return result; + { + base::AutoLock al(shared_state_lock_); + if (passphrase_error_) { + return result; + } } - pthread_mutex_unlock(&shared_state_lock_); // Request the passphrase outside of the lock. requestor_->RequestPassphrase(request_id_); - pthread_mutex_lock(&shared_state_lock_); + base::AutoLock al(shared_state_lock_); // Wait for the passphrase from JavaScript. - pthread_cond_wait(&available_passphrase_cond_, &shared_state_lock_); + // TODO(amistry): Handle spurious wakeups. + available_passphrase_cond_.Wait(); if (!passphrase_error_) result.reset(new std::string(available_passphrase_)); - pthread_mutex_unlock(&shared_state_lock_); - return result; }
diff --git a/chrome/browser/resources/chromeos/zip_archiver/cpp/volume_reader_javascript_stream.h b/chrome/browser/resources/chromeos/zip_archiver/cpp/volume_reader_javascript_stream.h index 484211e..6490b0e 100644 --- a/chrome/browser/resources/chromeos/zip_archiver/cpp/volume_reader_javascript_stream.h +++ b/chrome/browser/resources/chromeos/zip_archiver/cpp/volume_reader_javascript_stream.h
@@ -5,11 +5,12 @@ #ifndef CHROME_BROWSER_RESOURCES_CHROMEOS_ZIP_ARCHIVER_CPP_VOLUME_READER_JAVASCRIPT_STREAM_H_ #define CHROME_BROWSER_RESOURCES_CHROMEOS_ZIP_ARCHIVER_CPP_VOLUME_READER_JAVASCRIPT_STREAM_H_ -#include <pthread.h> #include <cstdint> #include <memory> #include <string> +#include "base/synchronization/condition_variable.h" +#include "base/synchronization/lock.h" #include "chrome/browser/resources/chromeos/zip_archiver/cpp/volume_reader.h" #include "ppapi/cpp/var_array_buffer.h" @@ -27,7 +28,7 @@ VolumeReaderJavaScriptStream(int64_t archive_size, JavaScriptRequestorInterface* requestor); - virtual ~VolumeReaderJavaScriptStream(); + ~VolumeReaderJavaScriptStream() override; // Sets the internal array buffer used for reads and signal the blocked // VolumeReaderJavaScriptStream::Read to continue execution. Must be done in @@ -59,10 +60,10 @@ // See volume_reader.h for description. This method blocks on // available_data_cond_. SetBufferAndSignal should unblock it from another // thread. - virtual int64_t Read(int64_t bytes_to_read, const void** destination_buffer); + int64_t Read(int64_t bytes_to_read, const void** destination_buffer) override; // See volume_reader.h for description. - virtual int64_t Seek(int64_t offset, int whence); + int64_t Seek(int64_t offset, int whence) override; // Sets the request Id to be used by the reader. void SetRequestId(const std::string& request_id); @@ -70,11 +71,11 @@ // See volume_reader.h for description. The method blocks on // available_passphrase_cond_. SetPassphraseAndSignal should unblock it from // another thread. - virtual std::unique_ptr<std::string> Passphrase(); + std::unique_ptr<std::string> Passphrase() override; - virtual int64_t offset() { return offset_; } + int64_t offset() override; - int64_t archive_size() { return archive_size_; } + int64_t archive_size() override; private: // Request a chunk of length number of bytes from JavaScript starting from @@ -94,14 +95,11 @@ std::string available_passphrase_; // Stores a passphrase from JavaScript. bool passphrase_error_; // Marks an error in getting the passphrase. - // Must use POSIX mutexes instead of pp::Lock because there is no pp::Cond. - // pp::Lock uses POSIX mutexes anyway on Linux, but pp::Lock can also pe used - // on other operating systems as Windows. For now this is not an issue as this - // extension is used only on Chromebooks. The shared_state_lock_ is used to - // protect members which are accessed by more than one thread. - pthread_mutex_t shared_state_lock_; - pthread_cond_t available_data_cond_; - pthread_cond_t available_passphrase_cond_; + // The shared_state_lock_ is used to protect members which are accessed by + // more than one thread. + base::Lock shared_state_lock_; + base::ConditionVariable available_data_cond_; + base::ConditionVariable available_passphrase_cond_; int64_t offset_; // The offset from where read should be done. int64_t last_read_chunk_offset_; // The offset reached after last call to
diff --git a/chrome/browser/resources/chromeos/zip_archiver/unpacker-test/cpp/fake_volume_reader.cc b/chrome/browser/resources/chromeos/zip_archiver/unpacker-test/cpp/fake_volume_reader.cc index bfec94d..0836294 100644 --- a/chrome/browser/resources/chromeos/zip_archiver/unpacker-test/cpp/fake_volume_reader.cc +++ b/chrome/browser/resources/chromeos/zip_archiver/unpacker-test/cpp/fake_volume_reader.cc
@@ -16,10 +16,10 @@ return 0; // Not important. } -int64_t FakeVolumeReader::Seek(int64_t offset, int whence) { +int64_t FakeVolumeReader::Seek(int64_t offset, base::File::Whence whence) { return 0; // Not important. } -const char* FakeVolumeReader::Passphrase() { +std::unique_ptr<std::string> FakeVolumeReader::Passphrase() { return NULL; // Not important. }
diff --git a/chrome/browser/resources/chromeos/zip_archiver/unpacker-test/cpp/fake_volume_reader.h b/chrome/browser/resources/chromeos/zip_archiver/unpacker-test/cpp/fake_volume_reader.h index 24f242f..1b2d631 100644 --- a/chrome/browser/resources/chromeos/zip_archiver/unpacker-test/cpp/fake_volume_reader.h +++ b/chrome/browser/resources/chromeos/zip_archiver/unpacker-test/cpp/fake_volume_reader.h
@@ -15,12 +15,12 @@ class FakeVolumeReader : public VolumeReader { public: FakeVolumeReader(); - virtual ~FakeVolumeReader(); + ~FakeVolumeReader() override; - int64_t Read(int64_t bytes_to_read, const void** destination_buffer); + int64_t Read(int64_t bytes_to_read, const void** destination_buffer) override; int64_t Skip(int64_t bytes_to_skip); - int64_t Seek(int64_t offset, int whence); - const char* Passphrase(); + int64_t Seek(int64_t offset, base::File::Whence whence) override; + std::unique_ptr<std::string> Passphrase() override; }; #endif // CHROME_BROWSER_RESOURCES_CHROMEOS_ZIP_ARCHIVER_UNPACKER_TEST_CPP_FAKE_VOLUME_READER_H_
diff --git a/chrome/browser/resources/md_bookmarks/app.html b/chrome/browser/resources/md_bookmarks/app.html index 348cd0a..14d0ae99 100644 --- a/chrome/browser/resources/md_bookmarks/app.html +++ b/chrome/browser/resources/md_bookmarks/app.html
@@ -70,7 +70,7 @@ <bookmarks-toolbar sidebar-width="[[sidebarWidth_]]" role="banner"> </bookmarks-toolbar> <div id="main-container"> - <div id="sidebar" role="navigation" aria-label="$i18n{sidebarAxLabel}"> + <div id="sidebar" role="tree" aria-label="$i18n{sidebarAxLabel}"> <bookmarks-folder-node item-id="0" depth="-1"></bookmarks-folder-node> </div> <div id="splitter"></div>
diff --git a/chrome/browser/resources/md_bookmarks/folder_node.html b/chrome/browser/resources/md_bookmarks/folder_node.html index 8d766470..536e318 100644 --- a/chrome/browser/resources/md_bookmarks/folder_node.html +++ b/chrome/browser/resources/md_bookmarks/folder_node.html
@@ -82,7 +82,8 @@ on-contextmenu="onContextMenu_" tabindex$="[[getTabIndex_(selectedFolder_, itemId)]]" hidden="[[isRootFolder_(depth)]]" - role="treeitem"> + role="treeitem" + aria-owns="descendants"> <template is="dom-if" if="[[hasChildFolder_]]"> <paper-icon-button-light id="arrow"> <button on-click="toggleFolder_"
diff --git a/chrome/browser/resources/print_preview/new/pages_settings.html b/chrome/browser/resources/print_preview/new/pages_settings.html index 552596c5..22e39988 100644 --- a/chrome/browser/resources/print_preview/new/pages_settings.html +++ b/chrome/browser/resources/print_preview/new/pages_settings.html
@@ -2,6 +2,7 @@ <link rel="import" href="chrome://resources/cr_elements/cr_radio_button/cr_radio_button.html"> <link rel="import" href="chrome://resources/cr_elements/cr_input/cr_input.html"> +<link rel="import" href="chrome://resources/polymer/v1_0/paper-radio-group/paper-radio-group.html"> <link rel="import" href="../data/document_info.html"> <link rel="import" href="../print_preview_utils.html"> <link rel="import" href="input_behavior.html"> @@ -13,11 +14,15 @@ <dom-module id="print-preview-pages-settings"> <template> <style include="print-preview-shared"> + :host { + --paper-radio-group-item-padding: 0; + } + :host([error-state_='0']) #pageSettingsCustomInput { --cr-input-error-display: none; } - :host(:not([error-state_='0'])) #custom-radio-button { + :host(:not([error-state_='0'])) #customRadioButton { /* Margin = -1 * error height = -1 * (16px + 2 lines * line-height) */ --cr-radio-button-disc: { margin-top: calc(-16px - 2 * .75rem); @@ -38,30 +43,29 @@ class="input-settings-section multirow-controls"> <span slot="title">$i18n{pagesLabel}</span> <div slot="controls" id="controls"> - <div class="radio"> - <cr-radio-button name="pages" id="all-radio-button" - checked$="[[!customSelected_]]" - disabled$="[[getDisabled_(disabled)]]" - on-click="onAllRadioClick_"> - <span>$i18n{optionAllPages}</span> + <paper-radio-group selectable="cr-radio-button" class="radio" + disabled$="[[controlsDisabled_]]" + selected="{{optionSelected_}}"> + <cr-radio-button name="[[pagesValueEnum_.ALL]]" id="allRadioButton" + disabled$="[[controlsDisabled_]]" + label="$i18n{optionAllPages}"> </cr-radio-button> - <cr-radio-button name="pages" id="custom-radio-button" - checked$="[[customSelected_]]" - disabled$="[[getDisabled_(disabled)]]" - aria-label="$i18n{optionCustomPages}" - on-click="onCustomRadioClick_" - on-focus="onCustomRadioFocus_" - on-blur="onCustomInputBlur_"> + <cr-radio-button id="customRadioButton" + disabled$="[[controlsDisabled_]]" + name="[[pagesValueEnum_.CUSTOM]]" + on-blur="onCustomRadioBlur_" + aria-label="$i18n{optionCustomPages}"> <cr-input id="pageSettingsCustomInput" type="text" data-timeout-delay="500" on-keydown="onKeydown_" - disabled$="[[getDisabled_(disabled)]]" spellcheck="false" + disabled$="[[controlsDisabled_]]" spellcheck="false" on-focus="onCustomInputFocus_" on-blur="onCustomInputBlur_" + tabindex="[[computeTabIndex_(optionSelected_)]]" placeholder="$i18n{examplePageRangeText}" error-message="[[getHintMessage_(errorState_, documentInfo.pageCount)]]"> </cr-input> </cr-radio-button> - </div> + </paper-radio-group> </div> </print-preview-settings-section> </template>
diff --git a/chrome/browser/resources/print_preview/new/pages_settings.js b/chrome/browser/resources/print_preview/new/pages_settings.js index 6207c58..5bc0f1a 100644 --- a/chrome/browser/resources/print_preview/new/pages_settings.js +++ b/chrome/browser/resources/print_preview/new/pages_settings.js
@@ -12,6 +12,12 @@ OUT_OF_BOUNDS: 2, }; +/** @enum {string} */ +const PagesValue = { + ALL: 'all', + CUSTOM: 'custom', +}; + Polymer({ is: 'print-preview-pages-settings', @@ -33,14 +39,28 @@ computed: 'computeAllPagesArray_(documentInfo.pageCount)', }, - /** @private {boolean} */ - customSelected_: { + /** @private {string} */ + optionSelected_: { type: Boolean, - value: false, + value: PagesValue.ALL, + observer: 'onOptionSelectedChange_', }, disabled: Boolean, + /** + * Note: |disabled| specifies whether printing, and any settings section + * not in an error state, is disabled. |controlsDisabled_| specifies whether + * the pages section should be disabled, based on the value of |disabled| + * and the state of this section. + * @private {boolean} Whether this section is disabled. + */ + controlsDisabled_: { + type: Boolean, + computed: 'computeControlsDisabled_(disabled, errorState_)', + observer: 'onControlsDisabledChanged_', + }, + /** @private {number} */ errorState_: { type: Number, @@ -52,7 +72,7 @@ pagesToPrint_: { type: Array, computed: 'computePagesToPrint_(' + - 'inputString_, customSelected_, allPagesArray_)', + 'inputString_, optionSelected_, allPagesArray_)', }, /** @private {!Array<{to: number, from: number}>} */ @@ -60,6 +80,15 @@ type: Array, computed: 'computeRangesToPrint_(pagesToPrint_, allPagesArray_)', }, + + /** + * Mirroring the enum so that it can be used from HTML bindings. + * @private + */ + pagesValueEnum_: { + type: Object, + value: PagesValue, + }, }, observers: [ @@ -91,7 +120,7 @@ * |disabled|. * @private */ - getDisabled_: function() { + computeControlsDisabled_: function() { // Disable the input if other settings are responsible for the error state. return this.errorState_ == PagesInputErrorState.NO_ERROR && this.disabled; }, @@ -123,7 +152,7 @@ * @private */ computePagesToPrint_: function() { - if (!this.customSelected_ || this.inputString_ === '') { + if (this.optionSelected_ === PagesValue.ALL || this.inputString_ === '') { this.errorState_ = PagesInputErrorState.NO_ERROR; return this.allPagesArray_; } @@ -274,34 +303,17 @@ }, /** @private */ - onAllRadioClick_: function() { - this.customSelected_ = false; - }, - - /** - * @param {Event} event Contains information about where focus came from. - * @private - */ - onCustomRadioFocus_: function(event) { - if (event.relatedTarget !== this.$.pageSettingsCustomInput) - this.onCustomRadioClick_(); - }, - - /** @private */ - onCustomRadioClick_: function() { - /** @type {!CrInputElement} */ (this.$.pageSettingsCustomInput) - .inputElement.focus(); - }, - - /** @private */ - onCustomInputFocus_: function() { - this.customSelected_ = true; + onOptionSelectedChange_: function() { + if (this.optionSelected_ === PagesValue.CUSTOM) { + /** @type {!CrInputElement} */ (this.$.pageSettingsCustomInput) + .inputElement.focus(); + } }, /** @private */ resetIfEmpty_: function() { if (this.inputString_ === '') - this.customSelected_ = false; + this.optionSelected_ = PagesValue.ALL; }, /** @@ -311,6 +323,24 @@ if (e.key == 'Enter') { this.resetAndUpdate(); this.resetIfEmpty_(); + } else if (e.shiftKey && e.key == 'Tab') { + this.$.customRadioButton.focus(); + e.stopPropagation(); + e.preventDefault(); + } else if (e.key === 'ArrowRight' || e.key === 'ArrowLeft') { + e.stopPropagation(); + } + }, + + /** + * @param {Event} event Contains information about where focus is going. + * @private + */ + onCustomRadioBlur_: function(event) { + if (event.relatedTarget != + /** @type {!CrInputElement} */ + (this.$.pageSettingsCustomInput).inputElement) { + this.resetIfEmpty_(); } }, @@ -321,8 +351,38 @@ onCustomInputBlur_: function(event) { this.resetAndUpdate(); - if (event.relatedTarget != this.$$('#custom-radio-button')) + if (event.relatedTarget != this.$.customRadioButton) { this.resetIfEmpty_(); + + // Manually set tab index to -1, so that this is not identified as the + // target for the radio group if the user navigates back. + this.$.customRadioButton.tabIndex = -1; + } + }, + + /** @private */ + onCustomInputFocus_: function() { + if (this.optionSelected_ !== PagesValue.CUSTOM) + this.optionSelected_ = PagesValue.CUSTOM; + }, + + /** @private */ + onControlsDisabledChanged_: function() { + if (!this.controlsDisabled_) { + if (this.optionSelected_ === PagesValue.CUSTOM) + this.$.allRadioButton.tabIndex = -1; + else + this.$.customRadioButton.tabIndex = -1; + } + }, + + /** + * Gets a tab index for the custom input if it can be tabbed to. + * @return {number} + * @private + */ + computeTabIndex_: function() { + return this.optionSelected_ === PagesValue.CUSTOM ? 0 : -1; }, /**
diff --git a/chrome/browser/sync/chrome_sync_client.cc b/chrome/browser/sync/chrome_sync_client.cc index 640ee8f..dbc0364e 100644 --- a/chrome/browser/sync/chrome_sync_client.cc +++ b/chrome/browser/sync/chrome_sync_client.cc
@@ -68,10 +68,13 @@ #include "components/sync/base/report_unrecoverable_error.h" #include "components/sync/driver/async_directory_type_controller.h" #include "components/sync/driver/sync_api_component_factory.h" +#include "components/sync/driver/sync_driver_switches.h" #include "components/sync/driver/sync_util.h" +#include "components/sync/driver/syncable_service_based_model_type_controller.h" #include "components/sync/engine/passive_model_worker.h" #include "components/sync/engine/sequenced_model_worker.h" #include "components/sync/engine/ui_model_worker.h" +#include "components/sync/model/model_type_store_service.h" #include "components/sync/user_events/user_event_service.h" #include "components/sync_bookmarks/bookmark_sync_service.h" #include "components/sync_preferences/pref_service_syncable.h" @@ -93,6 +96,7 @@ #include "chrome/browser/extensions/api/storage/settings_sync_util.h" #include "chrome/browser/extensions/extension_sync_service.h" #include "chrome/browser/sync/glue/extension_data_type_controller.h" +#include "chrome/browser/sync/glue/extension_model_type_controller.h" #include "chrome/browser/sync/glue/extension_setting_data_type_controller.h" #endif // BUILDFLAG(ENABLE_EXTENSIONS) @@ -124,6 +128,7 @@ using content::BrowserThread; #if BUILDFLAG(ENABLE_EXTENSIONS) using browser_sync::ExtensionDataTypeController; +using browser_sync::ExtensionModelTypeController; using browser_sync::ExtensionSettingDataTypeController; #endif // BUILDFLAG(ENABLE_EXTENSIONS) using browser_sync::SearchEngineDataTypeController; @@ -295,15 +300,31 @@ // App sync is enabled by default. Register unless explicitly // disabled. if (!disabled_types.Has(syncer::APPS)) { - controllers.push_back(std::make_unique<ExtensionDataTypeController>( - syncer::APPS, error_callback, this, profile_)); + if (base::FeatureList::IsEnabled(switches::kSyncPseudoUSSApps)) { + controllers.push_back(std::make_unique<ExtensionModelTypeController>( + syncer::APPS, GetModelTypeStoreService()->GetStoreFactory(), + base::BindOnce(&ChromeSyncClient::GetSyncableServiceForType, + base::Unretained(this), syncer::APPS), + profile_)); + } else { + controllers.push_back(std::make_unique<ExtensionDataTypeController>( + syncer::APPS, error_callback, this, profile_)); + } } // Extension sync is enabled by default. Register unless explicitly // disabled. if (!disabled_types.Has(syncer::EXTENSIONS)) { - controllers.push_back(std::make_unique<ExtensionDataTypeController>( - syncer::EXTENSIONS, error_callback, this, profile_)); + if (base::FeatureList::IsEnabled(switches::kSyncPseudoUSSExtensions)) { + controllers.push_back(std::make_unique<ExtensionModelTypeController>( + syncer::EXTENSIONS, GetModelTypeStoreService()->GetStoreFactory(), + base::BindOnce(&ChromeSyncClient::GetSyncableServiceForType, + base::Unretained(this), syncer::EXTENSIONS), + profile_)); + } else { + controllers.push_back(std::make_unique<ExtensionDataTypeController>( + syncer::EXTENSIONS, error_callback, this, profile_)); + } } // Extension setting sync is enabled by default. Register unless explicitly @@ -324,8 +345,16 @@ #if !defined(OS_ANDROID) // Theme sync is enabled by default. Register unless explicitly disabled. if (!disabled_types.Has(syncer::THEMES)) { - controllers.push_back(std::make_unique<ThemeDataTypeController>( - error_callback, this, profile_)); + if (base::FeatureList::IsEnabled(switches::kSyncPseudoUSSThemes)) { + controllers.push_back(std::make_unique<ExtensionModelTypeController>( + syncer::THEMES, GetModelTypeStoreService()->GetStoreFactory(), + base::BindOnce(&ChromeSyncClient::GetSyncableServiceForType, + base::Unretained(this), syncer::THEMES), + profile_)); + } else { + controllers.push_back(std::make_unique<ThemeDataTypeController>( + error_callback, this, profile_)); + } } // Search Engine sync is enabled by default. Register unless explicitly @@ -338,17 +367,33 @@ #endif // !defined(OS_ANDROID) #if BUILDFLAG(ENABLE_APP_LIST) - controllers.push_back(std::make_unique<AsyncDirectoryTypeController>( - syncer::APP_LIST, error_callback, this, syncer::GROUP_UI, - base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::UI}))); + if (base::FeatureList::IsEnabled(switches::kSyncPseudoUSSAppList)) { + controllers.push_back( + std::make_unique<syncer::SyncableServiceBasedModelTypeController>( + syncer::APP_LIST, GetModelTypeStoreService()->GetStoreFactory(), + base::BindOnce(&ChromeSyncClient::GetSyncableServiceForType, + base::Unretained(this), syncer::APP_LIST))); + } else { + controllers.push_back(std::make_unique<AsyncDirectoryTypeController>( + syncer::APP_LIST, error_callback, this, syncer::GROUP_UI, + base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::UI}))); + } #endif // BUILDFLAG(ENABLE_APP_LIST) #if defined(OS_LINUX) || defined(OS_WIN) // Dictionary sync is enabled by default. if (!disabled_types.Has(syncer::DICTIONARY)) { - controllers.push_back(std::make_unique<AsyncDirectoryTypeController>( - syncer::DICTIONARY, error_callback, this, syncer::GROUP_UI, - base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::UI}))); + if (base::FeatureList::IsEnabled(switches::kSyncPseudoUSSDictionary)) { + controllers.push_back( + std::make_unique<syncer::SyncableServiceBasedModelTypeController>( + syncer::DICTIONARY, GetModelTypeStoreService()->GetStoreFactory(), + base::BindOnce(&ChromeSyncClient::GetSyncableServiceForType, + base::Unretained(this), syncer::DICTIONARY))); + } else { + controllers.push_back(std::make_unique<AsyncDirectoryTypeController>( + syncer::DICTIONARY, error_callback, this, syncer::GROUP_UI, + base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::UI}))); + } } #endif // defined(OS_LINUX) || defined(OS_WIN)
diff --git a/chrome/browser/sync/glue/extension_model_type_controller.cc b/chrome/browser/sync/glue/extension_model_type_controller.cc new file mode 100644 index 0000000..619d96d9 --- /dev/null +++ b/chrome/browser/sync/glue/extension_model_type_controller.cc
@@ -0,0 +1,39 @@ +// 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/sync/glue/extension_model_type_controller.h" + +#include <utility> + +#include "chrome/browser/profiles/profile.h" +#include "extensions/browser/extension_system.h" + +namespace browser_sync { + +ExtensionModelTypeController::ExtensionModelTypeController( + syncer::ModelType type, + syncer::OnceModelTypeStoreFactory store_factory, + SyncableServiceProvider syncable_service_provider, + Profile* profile) + : SyncableServiceBasedModelTypeController( + type, + std::move(store_factory), + std::move(syncable_service_provider)), + profile_(profile) { + DCHECK(type == syncer::EXTENSIONS || type == syncer::APPS || + type == syncer::THEMES); +} + +ExtensionModelTypeController::~ExtensionModelTypeController() {} + +void ExtensionModelTypeController::LoadModels( + const syncer::ConfigureContext& configure_context, + const ModelLoadCallback& model_load_callback) { + DCHECK(CalledOnValidThread()); + extensions::ExtensionSystem::Get(profile_)->InitForRegularProfile( + /*extensions_enabled=*/true); + ModelTypeController::LoadModels(configure_context, model_load_callback); +} + +} // namespace browser_sync
diff --git a/chrome/browser/sync/glue/extension_model_type_controller.h b/chrome/browser/sync/glue/extension_model_type_controller.h new file mode 100644 index 0000000..1e61396 --- /dev/null +++ b/chrome/browser/sync/glue/extension_model_type_controller.h
@@ -0,0 +1,40 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_SYNC_GLUE_EXTENSION_MODEL_TYPE_CONTROLLER_H_ +#define CHROME_BROWSER_SYNC_GLUE_EXTENSION_MODEL_TYPE_CONTROLLER_H_ + +#include "base/macros.h" +#include "components/sync/driver/syncable_service_based_model_type_controller.h" + +class Profile; + +namespace browser_sync { + +// Controller with custom logic to start the extensions machinery when sync is +// starting. Analogous to ExtensionDataTypeController and +// ThemeDataTypeController. +class ExtensionModelTypeController + : public syncer::SyncableServiceBasedModelTypeController { + public: + ExtensionModelTypeController( + syncer::ModelType type, + syncer::OnceModelTypeStoreFactory store_factory, + SyncableServiceProvider syncable_service_provider, + Profile* profile); + ~ExtensionModelTypeController() override; + + // DataTypeController overrides. + void LoadModels(const syncer::ConfigureContext& configure_context, + const ModelLoadCallback& model_load_callback) override; + + private: + Profile* const profile_; + + DISALLOW_COPY_AND_ASSIGN(ExtensionModelTypeController); +}; + +} // namespace browser_sync + +#endif // CHROME_BROWSER_SYNC_GLUE_EXTENSION_MODEL_TYPE_CONTROLLER_H_
diff --git a/chrome/browser/sync/profile_sync_test_util.cc b/chrome/browser/sync/profile_sync_test_util.cc index a5550f7..c064cf0 100644 --- a/chrome/browser/sync/profile_sync_test_util.cc +++ b/chrome/browser/sync/profile_sync_test_util.cc
@@ -11,6 +11,7 @@ #include "base/location.h" #include "base/single_thread_task_runner.h" #include "chrome/browser/invalidation/deprecated_profile_invalidation_provider_factory.h" +#include "chrome/browser/invalidation/profile_invalidation_provider_factory.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/signin/identity_manager_factory.h" #include "chrome/browser/signin/signin_manager_factory.h" @@ -19,6 +20,7 @@ #include "chrome/test/base/testing_profile.h" #include "components/browser_sync/profile_sync_service.h" #include "components/browser_sync/profile_sync_test_util.h" +#include "components/invalidation/impl/invalidation_switches.h" #include "components/invalidation/impl/profile_invalidation_provider.h" #include "components/signin/core/browser/signin_manager.h" #include "components/sync/driver/startup_controller.h" @@ -54,10 +56,16 @@ init_params.start_behavior = ProfileSyncService::MANUAL_START; init_params.sync_client = std::move(sync_client); init_params.network_time_update_callback = base::DoNothing(); + bool fcm_invalidations_enabled = + base::FeatureList::IsEnabled(invalidation::switches::kFCMInvalidations); init_params.invalidations_identity_provider = - invalidation::DeprecatedProfileInvalidationProviderFactory::GetForProfile( - profile) - ->GetIdentityProvider(); + fcm_invalidations_enabled + ? invalidation::ProfileInvalidationProviderFactory::GetForProfile( + profile) + ->GetIdentityProvider() + : invalidation::DeprecatedProfileInvalidationProviderFactory:: + GetForProfile(profile) + ->GetIdentityProvider(); init_params.url_loader_factory = content::BrowserContext::GetDefaultStoragePartition(profile) ->GetURLLoaderFactoryForBrowserProcess();
diff --git a/chrome/browser/sync/test/integration/single_client_apps_sync_test.cc b/chrome/browser/sync/test/integration/single_client_apps_sync_test.cc index 2d8b246..4e88fd5 100644 --- a/chrome/browser/sync/test/integration/single_client_apps_sync_test.cc +++ b/chrome/browser/sync/test/integration/single_client_apps_sync_test.cc
@@ -3,16 +3,36 @@ // found in the LICENSE file. #include "base/macros.h" +#include "base/test/scoped_feature_list.h" #include "chrome/browser/sync/test/integration/apps_helper.h" #include "chrome/browser/sync/test/integration/sync_test.h" #include "chrome/browser/sync/test/integration/updated_progress_marker_checker.h" #include "components/browser_sync/profile_sync_service.h" +#include "components/sync/driver/sync_driver_switches.h" + +namespace { using apps_helper::AllProfilesHaveSameApps; using apps_helper::InstallApp; using apps_helper::InstallPlatformApp; -class SingleClientAppsSyncTest : public SyncTest { +// Class that enables or disables USS based on test parameter. Must be the first +// base class of the test fixture. +class UssSwitchToggler : public testing::WithParamInterface<bool> { + public: + UssSwitchToggler() { + if (GetParam()) { + override_features_.InitAndEnableFeature(switches::kSyncPseudoUSSApps); + } else { + override_features_.InitAndDisableFeature(switches::kSyncPseudoUSSApps); + } + } + + private: + base::test::ScopedFeatureList override_features_; +}; + +class SingleClientAppsSyncTest : public UssSwitchToggler, public SyncTest { public: SingleClientAppsSyncTest() : SyncTest(SINGLE_CLIENT) {} @@ -22,12 +42,12 @@ DISALLOW_COPY_AND_ASSIGN(SingleClientAppsSyncTest); }; -IN_PROC_BROWSER_TEST_F(SingleClientAppsSyncTest, StartWithNoApps) { +IN_PROC_BROWSER_TEST_P(SingleClientAppsSyncTest, StartWithNoApps) { ASSERT_TRUE(SetupSync()); ASSERT_TRUE(AllProfilesHaveSameApps()); } -IN_PROC_BROWSER_TEST_F(SingleClientAppsSyncTest, StartWithSomeLegacyApps) { +IN_PROC_BROWSER_TEST_P(SingleClientAppsSyncTest, StartWithSomeLegacyApps) { ASSERT_TRUE(SetupClients()); const int kNumApps = 5; @@ -40,7 +60,7 @@ ASSERT_TRUE(AllProfilesHaveSameApps()); } -IN_PROC_BROWSER_TEST_F(SingleClientAppsSyncTest, StartWithSomePlatformApps) { +IN_PROC_BROWSER_TEST_P(SingleClientAppsSyncTest, StartWithSomePlatformApps) { ASSERT_TRUE(SetupClients()); const int kNumApps = 5; @@ -53,7 +73,7 @@ ASSERT_TRUE(AllProfilesHaveSameApps()); } -IN_PROC_BROWSER_TEST_F(SingleClientAppsSyncTest, InstallSomeLegacyApps) { +IN_PROC_BROWSER_TEST_P(SingleClientAppsSyncTest, InstallSomeLegacyApps) { ASSERT_TRUE(SetupSync()); const int kNumApps = 5; @@ -66,7 +86,7 @@ ASSERT_TRUE(AllProfilesHaveSameApps()); } -IN_PROC_BROWSER_TEST_F(SingleClientAppsSyncTest, InstallSomePlatformApps) { +IN_PROC_BROWSER_TEST_P(SingleClientAppsSyncTest, InstallSomePlatformApps) { ASSERT_TRUE(SetupSync()); const int kNumApps = 5; @@ -79,7 +99,7 @@ ASSERT_TRUE(AllProfilesHaveSameApps()); } -IN_PROC_BROWSER_TEST_F(SingleClientAppsSyncTest, InstallSomeApps) { +IN_PROC_BROWSER_TEST_P(SingleClientAppsSyncTest, InstallSomeApps) { ASSERT_TRUE(SetupSync()); int i = 0; @@ -99,3 +119,9 @@ ASSERT_TRUE(UpdatedProgressMarkerChecker(GetSyncService(0)).Wait()); ASSERT_TRUE(AllProfilesHaveSameApps()); } + +INSTANTIATE_TEST_CASE_P(USS, + SingleClientAppsSyncTest, + ::testing::Values(false, true)); + +} // namespace
diff --git a/chrome/browser/sync/test/integration/single_client_dictionary_sync_test.cc b/chrome/browser/sync/test/integration/single_client_dictionary_sync_test.cc index 763e1a3..c4e96bc 100644 --- a/chrome/browser/sync/test/integration/single_client_dictionary_sync_test.cc +++ b/chrome/browser/sync/test/integration/single_client_dictionary_sync_test.cc
@@ -3,12 +3,35 @@ // found in the LICENSE file. #include "base/macros.h" +#include "base/test/scoped_feature_list.h" #include "chrome/browser/sync/test/integration/dictionary_helper.h" #include "chrome/browser/sync/test/integration/sync_test.h" #include "chrome/browser/sync/test/integration/updated_progress_marker_checker.h" #include "components/browser_sync/profile_sync_service.h" +#include "components/sync/driver/sync_driver_switches.h" -class SingleClientDictionarySyncTest : public SyncTest { +namespace { + +// Class that enables or disables USS based on test parameter. Must be the first +// base class of the test fixture. +class UssSwitchToggler : public testing::WithParamInterface<bool> { + public: + UssSwitchToggler() { + if (GetParam()) { + override_features_.InitAndEnableFeature( + switches::kSyncPseudoUSSDictionary); + } else { + override_features_.InitAndDisableFeature( + switches::kSyncPseudoUSSDictionary); + } + } + + private: + base::test::ScopedFeatureList override_features_; +}; + +class SingleClientDictionarySyncTest : public UssSwitchToggler, + public SyncTest { public: SingleClientDictionarySyncTest() : SyncTest(SINGLE_CLIENT) {} ~SingleClientDictionarySyncTest() override {} @@ -17,7 +40,7 @@ DISALLOW_COPY_AND_ASSIGN(SingleClientDictionarySyncTest); }; -IN_PROC_BROWSER_TEST_F(SingleClientDictionarySyncTest, Sanity) { +IN_PROC_BROWSER_TEST_P(SingleClientDictionarySyncTest, Sanity) { ASSERT_TRUE(SetupSync()) << "SetupSync() failed."; dictionary_helper::LoadDictionaries(); ASSERT_TRUE(dictionary_helper::DictionariesMatch()); @@ -31,3 +54,9 @@ ASSERT_TRUE(UpdatedProgressMarkerChecker(GetSyncService(0)).Wait()); ASSERT_TRUE(dictionary_helper::DictionariesMatch()); } + +INSTANTIATE_TEST_CASE_P(USS, + SingleClientDictionarySyncTest, + ::testing::Values(false, true)); + +} // namespace
diff --git a/chrome/browser/sync/test/integration/single_client_extensions_sync_test.cc b/chrome/browser/sync/test/integration/single_client_extensions_sync_test.cc index cda11f3..38c6f7a5e 100644 --- a/chrome/browser/sync/test/integration/single_client_extensions_sync_test.cc +++ b/chrome/browser/sync/test/integration/single_client_extensions_sync_test.cc
@@ -3,20 +3,43 @@ // found in the LICENSE file. #include "base/macros.h" +#include "base/test/scoped_feature_list.h" #include "chrome/browser/sync/test/integration/await_match_status_change_checker.h" #include "chrome/browser/sync/test/integration/extensions_helper.h" #include "chrome/browser/sync/test/integration/sync_test.h" #include "chrome/browser/sync/test/integration/updated_progress_marker_checker.h" #include "components/browser_sync/profile_sync_service.h" +#include "components/sync/driver/sync_driver_switches.h" #include "components/sync/test/fake_server/fake_server.h" +namespace { + using extensions_helper::AllProfilesHaveSameExtensionsAsVerifier; using extensions_helper::DisableExtension; using extensions_helper::GetInstalledExtensions; using extensions_helper::InstallExtension; using extensions_helper::InstallExtensionForAllProfiles; -class SingleClientExtensionsSyncTest : public SyncTest { +// Class that enables or disables USS based on test parameter. Must be the first +// base class of the test fixture. +class UssSwitchToggler : public testing::WithParamInterface<bool> { + public: + UssSwitchToggler() { + if (GetParam()) { + override_features_.InitAndEnableFeature( + switches::kSyncPseudoUSSExtensions); + } else { + override_features_.InitAndDisableFeature( + switches::kSyncPseudoUSSExtensions); + } + } + + private: + base::test::ScopedFeatureList override_features_; +}; + +class SingleClientExtensionsSyncTest : public UssSwitchToggler, + public SyncTest { public: SingleClientExtensionsSyncTest() : SyncTest(SINGLE_CLIENT) {} @@ -26,12 +49,12 @@ DISALLOW_COPY_AND_ASSIGN(SingleClientExtensionsSyncTest); }; -IN_PROC_BROWSER_TEST_F(SingleClientExtensionsSyncTest, StartWithNoExtensions) { +IN_PROC_BROWSER_TEST_P(SingleClientExtensionsSyncTest, StartWithNoExtensions) { ASSERT_TRUE(SetupSync()); ASSERT_TRUE(AllProfilesHaveSameExtensionsAsVerifier()); } -IN_PROC_BROWSER_TEST_F(SingleClientExtensionsSyncTest, +IN_PROC_BROWSER_TEST_P(SingleClientExtensionsSyncTest, StartWithSomeExtensions) { ASSERT_TRUE(SetupClients()); @@ -45,7 +68,7 @@ ASSERT_TRUE(AllProfilesHaveSameExtensionsAsVerifier()); } -IN_PROC_BROWSER_TEST_F(SingleClientExtensionsSyncTest, InstallSomeExtensions) { +IN_PROC_BROWSER_TEST_P(SingleClientExtensionsSyncTest, InstallSomeExtensions) { ASSERT_TRUE(SetupSync()); const int kNumExtensions = 5; @@ -66,7 +89,7 @@ // Tests the case of an uninstall from the server conflicting with a local // modification, which we expect to be resolved in favor of the uninstall. -IN_PROC_BROWSER_TEST_F(SingleClientExtensionsSyncTest, UninstallWinsConflicts) { +IN_PROC_BROWSER_TEST_P(SingleClientExtensionsSyncTest, UninstallWinsConflicts) { ASSERT_TRUE(SetupClients()); // Start with an extension installed, and setup sync. @@ -102,3 +125,9 @@ EXPECT_TRUE(checker.Wait()); EXPECT_TRUE(GetInstalledExtensions(GetProfile(0)).empty()); } + +INSTANTIATE_TEST_CASE_P(USS, + SingleClientExtensionsSyncTest, + ::testing::Values(false, true)); + +} // namespace
diff --git a/chrome/browser/sync/test/integration/single_client_themes_sync_test.cc b/chrome/browser/sync/test/integration/single_client_themes_sync_test.cc index fa5b140d..63f68eb 100644 --- a/chrome/browser/sync/test/integration/single_client_themes_sync_test.cc +++ b/chrome/browser/sync/test/integration/single_client_themes_sync_test.cc
@@ -3,6 +3,7 @@ // found in the LICENSE file. #include "base/macros.h" +#include "base/test/scoped_feature_list.h" #include "build/build_config.h" #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/sync/test/integration/sync_integration_test_util.h" @@ -11,6 +12,7 @@ #include "chrome/browser/sync/test/integration/updated_progress_marker_checker.h" #include "chrome/browser/themes/theme_service_factory.h" #include "components/browser_sync/profile_sync_service.h" +#include "components/sync/driver/sync_driver_switches.h" #include "content/public/test/test_utils.h" using themes_helper::GetCustomTheme; @@ -23,7 +25,23 @@ namespace { -class SingleClientThemesSyncTest : public SyncTest { +// Class that enables or disables USS based on test parameter. Must be the first +// base class of the test fixture. +class UssSwitchToggler : public testing::WithParamInterface<bool> { + public: + UssSwitchToggler() { + if (GetParam()) { + override_features_.InitAndEnableFeature(switches::kSyncPseudoUSSThemes); + } else { + override_features_.InitAndDisableFeature(switches::kSyncPseudoUSSThemes); + } + } + + private: + base::test::ScopedFeatureList override_features_; +}; + +class SingleClientThemesSyncTest : public UssSwitchToggler, public SyncTest { public: SingleClientThemesSyncTest() : SyncTest(SINGLE_CLIENT) {} ~SingleClientThemesSyncTest() override {} @@ -36,7 +54,7 @@ // start with SetupClients(), change the theme state, then call // SetupSync()). -IN_PROC_BROWSER_TEST_F(SingleClientThemesSyncTest, CustomTheme) { +IN_PROC_BROWSER_TEST_P(SingleClientThemesSyncTest, CustomTheme) { ASSERT_TRUE(SetupSync()) << "SetupSync() failed."; EXPECT_FALSE(UsingCustomTheme(GetProfile(0))); @@ -55,9 +73,9 @@ // TODO(sync): Fails on Chrome OS. See http://crbug.com/84575. #if defined(OS_CHROMEOS) -IN_PROC_BROWSER_TEST_F(SingleClientThemesSyncTest, DISABLED_NativeTheme) { +IN_PROC_BROWSER_TEST_P(SingleClientThemesSyncTest, DISABLED_NativeTheme) { #else -IN_PROC_BROWSER_TEST_F(SingleClientThemesSyncTest, NativeTheme) { +IN_PROC_BROWSER_TEST_P(SingleClientThemesSyncTest, NativeTheme) { #endif // OS_CHROMEOS ASSERT_TRUE(SetupSync()) << "SetupSync() failed."; @@ -79,7 +97,7 @@ EXPECT_TRUE(UsingSystemTheme(verifier())); } -IN_PROC_BROWSER_TEST_F(SingleClientThemesSyncTest, DefaultTheme) { +IN_PROC_BROWSER_TEST_P(SingleClientThemesSyncTest, DefaultTheme) { ASSERT_TRUE(SetupSync()) << "SetupSync() failed."; SetCustomTheme(GetProfile(0)); @@ -100,4 +118,8 @@ EXPECT_TRUE(UsingDefaultTheme(verifier())); } +INSTANTIATE_TEST_CASE_P(USS, + SingleClientThemesSyncTest, + ::testing::Values(false, true)); + } // namespace
diff --git a/chrome/browser/sync/test/integration/sync_test.cc b/chrome/browser/sync/test/integration/sync_test.cc index b30f6a80..b32e000 100644 --- a/chrome/browser/sync/test/integration/sync_test.cc +++ b/chrome/browser/sync/test/integration/sync_test.cc
@@ -34,6 +34,7 @@ #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/history/history_service_factory.h" #include "chrome/browser/invalidation/deprecated_profile_invalidation_provider_factory.h" +#include "chrome/browser/invalidation/profile_invalidation_provider_factory.h" #include "chrome/browser/lifetime/application_lifetime.h" #include "chrome/browser/net/system_network_context_manager.h" #include "chrome/browser/profiles/profile_manager.h" @@ -647,6 +648,8 @@ } void SyncTest::SetUpInvalidations(int index) { + bool fcm_invalidations_enabled = + base::FeatureList::IsEnabled(invalidation::switches::kFCMInvalidations); switch (server_type_) { case EXTERNAL_LIVE_SERVER: // DO NOTHING. External live sync servers use GCM to notify profiles of @@ -655,12 +658,22 @@ break; case IN_PROCESS_FAKE_SERVER: { - KeyedService* test_factory = - invalidation::DeprecatedProfileInvalidationProviderFactory:: - GetInstance() - ->SetTestingFactoryAndUse( - GetProfile(index), - BuildFakeServerProfileInvalidationProvider); + KeyedService* test_factory; + if (fcm_invalidations_enabled) { + test_factory = + invalidation::ProfileInvalidationProviderFactory::GetInstance() + ->SetTestingFactoryAndUse( + GetProfile(index), + BuildFakeServerProfileInvalidationProvider); + + } else { + test_factory = + invalidation::DeprecatedProfileInvalidationProviderFactory:: + GetInstance() + ->SetTestingFactoryAndUse( + GetProfile(index), + BuildFakeServerProfileInvalidationProvider); + } invalidation::InvalidationService* invalidation_service = static_cast<invalidation::ProfileInvalidationProvider*>(test_factory) ->GetInvalidationService(); @@ -683,8 +696,15 @@ TestUsesSelfNotifications() ? BuildSelfNotifyingP2PProfileInvalidationProvider : BuildRealisticP2PProfileInvalidationProvider; - invalidation::DeprecatedProfileInvalidationProviderFactory::GetInstance() - ->SetTestingFactoryAndUse(GetProfile(index), invalidation_provider); + if (fcm_invalidations_enabled) { + invalidation::ProfileInvalidationProviderFactory::GetInstance() + ->SetTestingFactoryAndUse(GetProfile(index), invalidation_provider); + } else { + invalidation::DeprecatedProfileInvalidationProviderFactory:: + GetInstance() + ->SetTestingFactoryAndUse(GetProfile(index), + invalidation_provider); + } } } @@ -704,10 +724,20 @@ } case SERVER_TYPE_UNDECIDED: case LOCAL_PYTHON_SERVER: - invalidation::InvalidationService* invalidation_service = - invalidation::DeprecatedProfileInvalidationProviderFactory:: - GetForProfile(GetProfile(index)) - ->GetInvalidationService(); + bool fcm_invalidations_enabled = base::FeatureList::IsEnabled( + invalidation::switches::kFCMInvalidations); + invalidation::InvalidationService* invalidation_service; + if (fcm_invalidations_enabled) { + invalidation_service = + invalidation::ProfileInvalidationProviderFactory::GetForProfile( + GetProfile(index)) + ->GetInvalidationService(); + } else { + invalidation_service = + invalidation::DeprecatedProfileInvalidationProviderFactory:: + GetForProfile(GetProfile(index)) + ->GetInvalidationService(); + } invalidation::P2PInvalidationService* p2p_invalidation_service = static_cast<invalidation::P2PInvalidationService*>( invalidation_service);
diff --git a/chrome/browser/sync/test/integration/two_client_apps_sync_test.cc b/chrome/browser/sync/test/integration/two_client_apps_sync_test.cc index ce508b0..1f90ad4 100644 --- a/chrome/browser/sync/test/integration/two_client_apps_sync_test.cc +++ b/chrome/browser/sync/test/integration/two_client_apps_sync_test.cc
@@ -6,6 +6,7 @@ #include "base/macros.h" #include "base/strings/utf_string_conversions.h" +#include "base/test/scoped_feature_list.h" #include "build/build_config.h" #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/extensions/bookmark_app_helper.h" @@ -22,6 +23,7 @@ #include "chrome/browser/web_applications/extensions/bookmark_app_util.h" #include "chrome/common/extensions/manifest_handlers/app_launch_info.h" #include "chrome/common/extensions/manifest_handlers/app_theme_color_info.h" +#include "components/sync/driver/sync_driver_switches.h" #include "components/sync/model/string_ordinal.h" #include "content/public/browser/notification_service.h" #include "content/public/test/test_utils.h" @@ -47,6 +49,22 @@ namespace { +// Class that enables or disables USS based on test parameter. Must be the first +// base class of the test fixture. +class UssSwitchToggler : public testing::WithParamInterface<bool> { + public: + UssSwitchToggler() { + if (GetParam()) { + override_features_.InitAndEnableFeature(switches::kSyncPseudoUSSApps); + } else { + override_features_.InitAndDisableFeature(switches::kSyncPseudoUSSApps); + } + } + + private: + base::test::ScopedFeatureList override_features_; +}; + extensions::ExtensionRegistry* GetExtensionRegistry(Profile* profile) { return extensions::ExtensionRegistry::Get(profile); } @@ -57,7 +75,7 @@ } // namespace -class TwoClientAppsSyncTest : public SyncTest { +class TwoClientAppsSyncTest : public UssSwitchToggler, public SyncTest { public: TwoClientAppsSyncTest() : SyncTest(TWO_CLIENT) { DisableVerifier(); @@ -71,12 +89,12 @@ DISALLOW_COPY_AND_ASSIGN(TwoClientAppsSyncTest); }; -IN_PROC_BROWSER_TEST_F(TwoClientAppsSyncTest, E2E_ENABLED(StartWithNoApps)) { +IN_PROC_BROWSER_TEST_P(TwoClientAppsSyncTest, E2E_ENABLED(StartWithNoApps)) { ASSERT_TRUE(SetupSync()); ASSERT_TRUE(AppsMatchChecker().Wait()); } -IN_PROC_BROWSER_TEST_F(TwoClientAppsSyncTest, E2E_ENABLED(StartWithSameApps)) { +IN_PROC_BROWSER_TEST_P(TwoClientAppsSyncTest, E2E_ENABLED(StartWithSameApps)) { ASSERT_TRUE(SetupClients()); const int kNumApps = 5; @@ -98,7 +116,7 @@ #else #define MAYBE_StartWithDifferentApps StartWithDifferentApps #endif -IN_PROC_BROWSER_TEST_F(TwoClientAppsSyncTest, MAYBE_StartWithDifferentApps) { +IN_PROC_BROWSER_TEST_P(TwoClientAppsSyncTest, MAYBE_StartWithDifferentApps) { ASSERT_TRUE(SetupClients()); int i = 0; @@ -131,7 +149,7 @@ // Install some apps on both clients, then sync. Then install some apps on only // one client, some on only the other, and then sync again. Both clients should // end up with all apps, and the app and page ordinals should be identical. -IN_PROC_BROWSER_TEST_F(TwoClientAppsSyncTest, +IN_PROC_BROWSER_TEST_P(TwoClientAppsSyncTest, E2E_ENABLED(InstallDifferentApps)) { ASSERT_TRUE(SetupClients()); @@ -158,7 +176,7 @@ ASSERT_TRUE(AppsMatchChecker().Wait()); } -IN_PROC_BROWSER_TEST_F(TwoClientAppsSyncTest, E2E_ENABLED(Add)) { +IN_PROC_BROWSER_TEST_P(TwoClientAppsSyncTest, E2E_ENABLED(Add)) { ASSERT_TRUE(SetupSync()); ASSERT_TRUE(AppsMatchChecker().Wait()); @@ -167,7 +185,7 @@ ASSERT_TRUE(AppsMatchChecker().Wait()); } -IN_PROC_BROWSER_TEST_F(TwoClientAppsSyncTest, E2E_ENABLED(Uninstall)) { +IN_PROC_BROWSER_TEST_P(TwoClientAppsSyncTest, E2E_ENABLED(Uninstall)) { ASSERT_TRUE(SetupSync()); ASSERT_TRUE(AppsMatchChecker().Wait()); @@ -182,7 +200,7 @@ // client and sync again. Now install a new app on the first client and sync. // Both client should only have the second app, with identical app and page // ordinals. -IN_PROC_BROWSER_TEST_F(TwoClientAppsSyncTest, +IN_PROC_BROWSER_TEST_P(TwoClientAppsSyncTest, E2E_ENABLED(UninstallThenInstall)) { ASSERT_TRUE(SetupSync()); ASSERT_TRUE(AppsMatchChecker().Wait()); @@ -197,7 +215,7 @@ ASSERT_TRUE(AppsMatchChecker().Wait()); } -IN_PROC_BROWSER_TEST_F(TwoClientAppsSyncTest, E2E_ENABLED(Merge)) { +IN_PROC_BROWSER_TEST_P(TwoClientAppsSyncTest, E2E_ENABLED(Merge)) { ASSERT_TRUE(SetupSync()); ASSERT_TRUE(AppsMatchChecker().Wait()); @@ -215,7 +233,7 @@ ASSERT_TRUE(AppsMatchChecker().Wait()); } -IN_PROC_BROWSER_TEST_F(TwoClientAppsSyncTest, +IN_PROC_BROWSER_TEST_P(TwoClientAppsSyncTest, E2E_ENABLED(UpdateEnableDisableApp)) { ASSERT_TRUE(SetupSync()); ASSERT_TRUE(AppsMatchChecker().Wait()); @@ -230,7 +248,7 @@ ASSERT_TRUE(AppsMatchChecker().Wait()); } -IN_PROC_BROWSER_TEST_F(TwoClientAppsSyncTest, +IN_PROC_BROWSER_TEST_P(TwoClientAppsSyncTest, E2E_ENABLED(UpdateIncognitoEnableDisable)) { ASSERT_TRUE(SetupSync()); ASSERT_TRUE(AppsMatchChecker().Wait()); @@ -248,7 +266,7 @@ // Install the same app on both clients, then sync. Change the page ordinal on // one client and sync. Both clients should have the updated page ordinal for // the app. -IN_PROC_BROWSER_TEST_F(TwoClientAppsSyncTest, E2E_ENABLED(UpdatePageOrdinal)) { +IN_PROC_BROWSER_TEST_P(TwoClientAppsSyncTest, E2E_ENABLED(UpdatePageOrdinal)) { ASSERT_TRUE(SetupSync()); ASSERT_TRUE(AppsMatchChecker().Wait()); @@ -265,7 +283,7 @@ // Install the same app on both clients, then sync. Change the app launch // ordinal on one client and sync. Both clients should have the updated app // launch ordinal for the app. -IN_PROC_BROWSER_TEST_F(TwoClientAppsSyncTest, +IN_PROC_BROWSER_TEST_P(TwoClientAppsSyncTest, E2E_ENABLED(UpdateAppLaunchOrdinal)) { ASSERT_TRUE(SetupSync()); ASSERT_TRUE(AppsMatchChecker().Wait()); @@ -284,7 +302,7 @@ // Adjust the CWS location within a page on the first client and sync. Adjust // which page the CWS appears on and sync. Both clients should have the same // page and app launch ordinal values for the CWS. -IN_PROC_BROWSER_TEST_F(TwoClientAppsSyncTest, E2E_ENABLED(UpdateCWSOrdinals)) { +IN_PROC_BROWSER_TEST_P(TwoClientAppsSyncTest, E2E_ENABLED(UpdateCWSOrdinals)) { ASSERT_TRUE(SetupSync()); ASSERT_TRUE(AppsMatchChecker().Wait()); @@ -313,7 +331,7 @@ // Adjust the launch type on the first client and sync. Both clients should // have the same launch type values for the CWS. -IN_PROC_BROWSER_TEST_F(TwoClientAppsSyncTest, E2E_ENABLED(UpdateLaunchType)) { +IN_PROC_BROWSER_TEST_P(TwoClientAppsSyncTest, E2E_ENABLED(UpdateLaunchType)) { ASSERT_TRUE(SetupSync()); ASSERT_TRUE(AppsMatchChecker().Wait()); @@ -339,7 +357,7 @@ extensions::LAUNCH_TYPE_REGULAR); } -IN_PROC_BROWSER_TEST_F(TwoClientAppsSyncTest, UnexpectedLaunchType) { +IN_PROC_BROWSER_TEST_P(TwoClientAppsSyncTest, UnexpectedLaunchType) { ASSERT_TRUE(SetupSync()); ASSERT_TRUE(AllProfilesHaveSameApps()); @@ -378,7 +396,7 @@ ASSERT_TRUE(AppsMatchChecker().Wait()); } -IN_PROC_BROWSER_TEST_F(TwoClientAppsSyncTest, BookmarkAppBasic) { +IN_PROC_BROWSER_TEST_P(TwoClientAppsSyncTest, BookmarkAppBasic) { ASSERT_TRUE(SetupSync()); ASSERT_TRUE(AllProfilesHaveSameApps()); @@ -411,7 +429,7 @@ } } -IN_PROC_BROWSER_TEST_F(TwoClientAppsSyncTest, BookmarkAppMinimal) { +IN_PROC_BROWSER_TEST_P(TwoClientAppsSyncTest, BookmarkAppMinimal) { ASSERT_TRUE(SetupSync()); ASSERT_TRUE(AllProfilesHaveSameApps()); @@ -453,7 +471,7 @@ return nullptr; } -IN_PROC_BROWSER_TEST_F(TwoClientAppsSyncTest, BookmarkAppThemeColor) { +IN_PROC_BROWSER_TEST_P(TwoClientAppsSyncTest, BookmarkAppThemeColor) { ASSERT_TRUE(SetupSync()); ASSERT_TRUE(AllProfilesHaveSameApps()); @@ -489,7 +507,7 @@ EXPECT_EQ(SK_ColorBLUE, theme_color.value()); } -IN_PROC_BROWSER_TEST_F(TwoClientAppsSyncTest, IsLocallyInstalled) { +IN_PROC_BROWSER_TEST_P(TwoClientAppsSyncTest, IsLocallyInstalled) { ASSERT_TRUE(SetupSync()); ASSERT_TRUE(AllProfilesHaveSameApps()); @@ -541,3 +559,7 @@ // TODO(akalin): Add tests exercising: // - Offline installation/uninstallation behavior // - App-specific properties + +INSTANTIATE_TEST_CASE_P(USS, + TwoClientAppsSyncTest, + ::testing::Values(false, true));
diff --git a/chrome/browser/sync/test/integration/two_client_dictionary_sync_test.cc b/chrome/browser/sync/test/integration/two_client_dictionary_sync_test.cc index 45983cb..f4a97f05 100644 --- a/chrome/browser/sync/test/integration/two_client_dictionary_sync_test.cc +++ b/chrome/browser/sync/test/integration/two_client_dictionary_sync_test.cc
@@ -4,6 +4,7 @@ #include "base/macros.h" #include "base/strings/string_number_conversions.h" +#include "base/test/scoped_feature_list.h" #include "chrome/browser/sync/test/integration/dictionary_helper.h" #include "chrome/browser/sync/test/integration/profile_sync_service_harness.h" #include "chrome/browser/sync/test/integration/sync_integration_test_util.h" @@ -11,10 +12,31 @@ #include "chrome/browser/sync/test/integration/updated_progress_marker_checker.h" #include "components/spellcheck/common/spellcheck_common.h" #include "components/sync/base/model_type.h" +#include "components/sync/driver/sync_driver_switches.h" + +namespace { using spellcheck::kMaxSyncableDictionaryWords; -class TwoClientDictionarySyncTest : public SyncTest { +// Class that enables or disables USS based on test parameter. Must be the first +// base class of the test fixture. +class UssSwitchToggler : public testing::WithParamInterface<bool> { + public: + UssSwitchToggler() { + if (GetParam()) { + override_features_.InitAndEnableFeature( + switches::kSyncPseudoUSSDictionary); + } else { + override_features_.InitAndDisableFeature( + switches::kSyncPseudoUSSDictionary); + } + } + + private: + base::test::ScopedFeatureList override_features_; +}; + +class TwoClientDictionarySyncTest : public UssSwitchToggler, public SyncTest { public: TwoClientDictionarySyncTest() : SyncTest(TWO_CLIENT) {} ~TwoClientDictionarySyncTest() override {} @@ -25,7 +47,7 @@ DISALLOW_COPY_AND_ASSIGN(TwoClientDictionarySyncTest); }; -IN_PROC_BROWSER_TEST_F(TwoClientDictionarySyncTest, E2E_ENABLED(Sanity)) { +IN_PROC_BROWSER_TEST_P(TwoClientDictionarySyncTest, E2E_ENABLED(Sanity)) { ASSERT_TRUE(SetupSync()) << "SetupSync() failed."; dictionary_helper::LoadDictionaries(); ASSERT_TRUE(DictionaryMatchChecker().Wait()); @@ -54,7 +76,7 @@ ASSERT_EQ(words.size(), dictionary_helper::GetDictionarySize(0)); } -IN_PROC_BROWSER_TEST_F(TwoClientDictionarySyncTest, +IN_PROC_BROWSER_TEST_P(TwoClientDictionarySyncTest, E2E_ENABLED(SimultaneousAdd)) { ASSERT_TRUE(SetupSync()) << "SetupSync() failed."; dictionary_helper::LoadDictionaries(); @@ -66,7 +88,7 @@ ASSERT_EQ(1UL, dictionary_helper::GetDictionarySize(0)); } -IN_PROC_BROWSER_TEST_F(TwoClientDictionarySyncTest, +IN_PROC_BROWSER_TEST_P(TwoClientDictionarySyncTest, E2E_ENABLED(SimultaneousRemove)) { ASSERT_TRUE(SetupSync()) << "SetupSync() failed."; dictionary_helper::LoadDictionaries(); @@ -83,7 +105,7 @@ ASSERT_EQ(0UL, dictionary_helper::GetDictionarySize(0)); } -IN_PROC_BROWSER_TEST_F(TwoClientDictionarySyncTest, +IN_PROC_BROWSER_TEST_P(TwoClientDictionarySyncTest, E2E_ENABLED(AddDifferentToEach)) { ASSERT_TRUE(SetupSync()) << "SetupSync() failed."; dictionary_helper::LoadDictionaries(); @@ -97,7 +119,7 @@ static_cast<int>(dictionary_helper::GetDictionarySize(0))); } -IN_PROC_BROWSER_TEST_F(TwoClientDictionarySyncTest, +IN_PROC_BROWSER_TEST_P(TwoClientDictionarySyncTest, E2E_ENABLED(RemoveOnAAddOnB)) { ASSERT_TRUE(SetupSync()) << "SetupSync() failed."; dictionary_helper::LoadDictionaries(); @@ -118,7 +140,7 @@ // Tests the case where a client has more words added than the // kMaxSyncableDictionaryWords limit. -IN_PROC_BROWSER_TEST_F(TwoClientDictionarySyncTest, Limit) { +IN_PROC_BROWSER_TEST_P(TwoClientDictionarySyncTest, Limit) { ASSERT_TRUE(SetupSync()) << "SetupSync() failed."; dictionary_helper::LoadDictionaries(); ASSERT_TRUE(DictionaryMatchChecker().Wait()); @@ -162,3 +184,9 @@ ASSERT_TRUE( NumDictionaryEntriesChecker(0, kMaxSyncableDictionaryWords).Wait()); } + +INSTANTIATE_TEST_CASE_P(USS, + TwoClientDictionarySyncTest, + ::testing::Values(false, true)); + +} // namespace
diff --git a/chrome/browser/sync/test/integration/two_client_extensions_sync_test.cc b/chrome/browser/sync/test/integration/two_client_extensions_sync_test.cc index 7fcfe7d..130def9 100644 --- a/chrome/browser/sync/test/integration/two_client_extensions_sync_test.cc +++ b/chrome/browser/sync/test/integration/two_client_extensions_sync_test.cc
@@ -3,11 +3,15 @@ // found in the LICENSE file. #include "base/macros.h" +#include "base/test/scoped_feature_list.h" #include "build/build_config.h" #include "chrome/browser/sync/test/integration/extensions_helper.h" #include "chrome/browser/sync/test/integration/profile_sync_service_harness.h" #include "chrome/browser/sync/test/integration/sync_integration_test_util.h" #include "chrome/browser/sync/test/integration/sync_test.h" +#include "components/sync/driver/sync_driver_switches.h" + +namespace { using extensions_helper::AllProfilesHaveSameExtensions; using extensions_helper::DisableExtension; @@ -19,7 +23,25 @@ using extensions_helper::InstallExtension; using extensions_helper::UninstallExtension; -class TwoClientExtensionsSyncTest : public SyncTest { +// Class that enables or disables USS based on test parameter. Must be the first +// base class of the test fixture. +class UssSwitchToggler : public testing::WithParamInterface<bool> { + public: + UssSwitchToggler() { + if (GetParam()) { + override_features_.InitAndEnableFeature( + switches::kSyncPseudoUSSExtensions); + } else { + override_features_.InitAndDisableFeature( + switches::kSyncPseudoUSSExtensions); + } + } + + private: + base::test::ScopedFeatureList override_features_; +}; + +class TwoClientExtensionsSyncTest : public UssSwitchToggler, public SyncTest { public: TwoClientExtensionsSyncTest() : SyncTest(TWO_CLIENT) { DisableVerifier(); } @@ -29,7 +51,7 @@ DISALLOW_COPY_AND_ASSIGN(TwoClientExtensionsSyncTest); }; -IN_PROC_BROWSER_TEST_F(TwoClientExtensionsSyncTest, +IN_PROC_BROWSER_TEST_P(TwoClientExtensionsSyncTest, E2E_ENABLED(StartWithNoExtensions)) { ASSERT_TRUE(SetupSync()); ASSERT_TRUE(ExtensionsMatchChecker().Wait()); @@ -48,7 +70,7 @@ #else #define MAYBE_StartWithSameExtensions StartWithSameExtensions #endif -IN_PROC_BROWSER_TEST_F(TwoClientExtensionsSyncTest, +IN_PROC_BROWSER_TEST_P(TwoClientExtensionsSyncTest, E2E_ENABLED(MAYBE_StartWithSameExtensions)) { ASSERT_TRUE(SetupClients()); @@ -70,7 +92,7 @@ #else #define MAYBE_StartWithDifferentExtensions StartWithDifferentExtensions #endif -IN_PROC_BROWSER_TEST_F(TwoClientExtensionsSyncTest, +IN_PROC_BROWSER_TEST_P(TwoClientExtensionsSyncTest, MAYBE_E2E(MAYBE_StartWithDifferentExtensions)) { ASSERT_TRUE(SetupClients()); @@ -99,7 +121,7 @@ static_cast<int>(GetInstalledExtensions(GetProfile(0)).size())); } -IN_PROC_BROWSER_TEST_F(TwoClientExtensionsSyncTest, +IN_PROC_BROWSER_TEST_P(TwoClientExtensionsSyncTest, E2E_ENABLED(InstallDifferentExtensions)) { ASSERT_TRUE(SetupClients()); @@ -130,7 +152,7 @@ static_cast<int>(GetInstalledExtensions(GetProfile(0)).size())); } -IN_PROC_BROWSER_TEST_F(TwoClientExtensionsSyncTest, MAYBE_E2E(Add)) { +IN_PROC_BROWSER_TEST_P(TwoClientExtensionsSyncTest, MAYBE_E2E(Add)) { ASSERT_TRUE(SetupSync()); ASSERT_TRUE(AllProfilesHaveSameExtensions()); @@ -140,7 +162,7 @@ EXPECT_EQ(1u, GetInstalledExtensions(GetProfile(0)).size()); } -IN_PROC_BROWSER_TEST_F(TwoClientExtensionsSyncTest, MAYBE_E2E(Uninstall)) { +IN_PROC_BROWSER_TEST_P(TwoClientExtensionsSyncTest, MAYBE_E2E(Uninstall)) { ASSERT_TRUE(SetupSync()); ASSERT_TRUE(AllProfilesHaveSameExtensions()); @@ -152,7 +174,7 @@ EXPECT_TRUE(GetInstalledExtensions(GetProfile(0)).empty()); } -IN_PROC_BROWSER_TEST_F(TwoClientExtensionsSyncTest, +IN_PROC_BROWSER_TEST_P(TwoClientExtensionsSyncTest, MAYBE_E2E(UpdateEnableDisableExtension)) { ASSERT_TRUE(SetupSync()); ASSERT_TRUE(AllProfilesHaveSameExtensions()); @@ -171,7 +193,7 @@ ASSERT_TRUE(ExtensionsMatchChecker().Wait()); } -IN_PROC_BROWSER_TEST_F(TwoClientExtensionsSyncTest, +IN_PROC_BROWSER_TEST_P(TwoClientExtensionsSyncTest, E2E_ENABLED(UpdateIncognitoEnableDisable)) { ASSERT_TRUE(SetupSync()); ASSERT_TRUE(AllProfilesHaveSameExtensions()); @@ -192,7 +214,7 @@ // Regression test for bug 104399: ensure that an extension installed prior to // setting up sync, when uninstalled, is also uninstalled from sync. -IN_PROC_BROWSER_TEST_F(TwoClientExtensionsSyncTest, +IN_PROC_BROWSER_TEST_P(TwoClientExtensionsSyncTest, E2E_ENABLED(UninstallPreinstalledExtensions)) { ASSERT_TRUE(SetupClients()); ASSERT_TRUE(AllProfilesHaveSameExtensions()); @@ -212,3 +234,9 @@ // TODO(akalin): Add tests exercising: // - Offline installation/uninstallation behavior + +INSTANTIATE_TEST_CASE_P(USS, + TwoClientExtensionsSyncTest, + ::testing::Values(false, true)); + +} // namespace
diff --git a/chrome/browser/sync/test/integration/two_client_themes_sync_test.cc b/chrome/browser/sync/test/integration/two_client_themes_sync_test.cc index 68beb142..a8d651cb 100644 --- a/chrome/browser/sync/test/integration/two_client_themes_sync_test.cc +++ b/chrome/browser/sync/test/integration/two_client_themes_sync_test.cc
@@ -3,10 +3,14 @@ // found in the LICENSE file. #include "base/macros.h" +#include "base/test/scoped_feature_list.h" #include "chrome/browser/sync/test/integration/profile_sync_service_harness.h" #include "chrome/browser/sync/test/integration/sync_integration_test_util.h" #include "chrome/browser/sync/test/integration/sync_test.h" #include "chrome/browser/sync/test/integration/themes_helper.h" +#include "components/sync/driver/sync_driver_switches.h" + +namespace { using themes_helper::GetCustomTheme; using themes_helper::GetThemeID; @@ -17,7 +21,23 @@ using themes_helper::UsingDefaultTheme; using themes_helper::UsingSystemTheme; -class TwoClientThemesSyncTest : public SyncTest { +// Class that enables or disables USS based on test parameter. Must be the first +// base class of the test fixture. +class UssSwitchToggler : public testing::WithParamInterface<bool> { + public: + UssSwitchToggler() { + if (GetParam()) { + override_features_.InitAndEnableFeature(switches::kSyncPseudoUSSThemes); + } else { + override_features_.InitAndDisableFeature(switches::kSyncPseudoUSSThemes); + } + } + + private: + base::test::ScopedFeatureList override_features_; +}; + +class TwoClientThemesSyncTest : public UssSwitchToggler, public SyncTest { public: TwoClientThemesSyncTest() : SyncTest(TWO_CLIENT) {} ~TwoClientThemesSyncTest() override {} @@ -31,7 +51,7 @@ // Starts with default themes, then sets up sync and uses it to set all // profiles to use a custom theme. Does not actually install any themes, but // instead verifies the custom theme is pending for install. -IN_PROC_BROWSER_TEST_F(TwoClientThemesSyncTest, +IN_PROC_BROWSER_TEST_P(TwoClientThemesSyncTest, E2E_ENABLED(DefaultThenSyncCustom)) { ASSERT_TRUE(SetupSync()); @@ -53,7 +73,7 @@ // Starts with custom themes, then sets up sync and uses it to set all profiles // to the system theme. -IN_PROC_BROWSER_TEST_F(TwoClientThemesSyncTest, +IN_PROC_BROWSER_TEST_P(TwoClientThemesSyncTest, E2E_ENABLED(CustomThenSyncNative)) { ASSERT_TRUE(SetupClients()); @@ -73,7 +93,7 @@ // Starts with custom themes, then sets up sync and uses it to set all profiles // to the default theme. -IN_PROC_BROWSER_TEST_F(TwoClientThemesSyncTest, +IN_PROC_BROWSER_TEST_P(TwoClientThemesSyncTest, E2E_ENABLED(CustomThenSyncDefault)) { ASSERT_TRUE(SetupClients()); @@ -94,7 +114,7 @@ // // Most other tests have significant coverage of model association. This test // is intended to test steady-state scenarios. -IN_PROC_BROWSER_TEST_F(TwoClientThemesSyncTest, E2E_ENABLED(CycleOptions)) { +IN_PROC_BROWSER_TEST_P(TwoClientThemesSyncTest, E2E_ENABLED(CycleOptions)) { ASSERT_TRUE(SetupSync()) << "SetupSync() failed."; SetCustomTheme(GetProfile(0)); @@ -120,3 +140,9 @@ ThemePendingInstallChecker(GetProfile(1), GetCustomTheme(1)).Wait()); EXPECT_EQ(GetCustomTheme(1), GetThemeID(GetProfile(0))); } + +INSTANTIATE_TEST_CASE_P(USS, + TwoClientThemesSyncTest, + ::testing::Values(false, true)); + +} // namespace
diff --git a/chrome/browser/ui/app_list/arc/arc_app_list_prefs.cc b/chrome/browser/ui/app_list/arc/arc_app_list_prefs.cc index ed643e0..aaf98f6 100644 --- a/chrome/browser/ui/app_list/arc/arc_app_list_prefs.cc +++ b/chrome/browser/ui/app_list/arc/arc_app_list_prefs.cc
@@ -18,6 +18,7 @@ #include "chrome/browser/chromeos/arc/arc_session_manager.h" #include "chrome/browser/chromeos/arc/arc_util.h" #include "chrome/browser/chromeos/arc/policy/arc_policy_util.h" +#include "chrome/browser/chromeos/login/demo_mode/demo_session.h" #include "chrome/browser/chromeos/login/session/user_session_manager.h" #include "chrome/browser/image_decoder.h" #include "chrome/browser/profiles/profile.h" @@ -1000,9 +1001,12 @@ const bool launchable) { const std::string app_id = shortcut ? GetAppId(package_name, intent_uri) : GetAppId(package_name, activity); - // Do not add Play Store app for Public Session and Kiosk modes. - if (app_id == arc::kPlayStoreAppId && arc::IsRobotOrOfflineDemoAccountMode()) + // TODO(khmel): Use show_in_launcher flag to hide the Play Store app. + if (app_id == arc::kPlayStoreAppId && + arc::IsRobotOrOfflineDemoAccountMode() && + !chromeos::DemoSession::IsDeviceInDemoMode()) { return; + } std::string updated_name = name; // Add "(beta)" string to Play Store. See crbug.com/644576 for details.
diff --git a/chrome/browser/ui/app_list/arc/arc_default_app_list.cc b/chrome/browser/ui/app_list/arc/arc_default_app_list.cc index 891a0aa5..ea3d818 100644 --- a/chrome/browser/ui/app_list/arc/arc_default_app_list.cc +++ b/chrome/browser/ui/app_list/arc/arc_default_app_list.cc
@@ -1,3 +1,4 @@ +// 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. @@ -9,13 +10,13 @@ #include "base/json/json_file_value_serializer.h" #include "base/path_service.h" #include "base/task/post_task.h" +#include "chrome/browser/chromeos/arc/arc_util.h" #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h" #include "chrome/browser/ui/app_list/arc/arc_app_scoped_pref_update.h" #include "chrome/browser/ui/app_list/arc/arc_app_utils.h" #include "chrome/common/chrome_paths.h" -#include "components/arc/arc_util.h" #include "components/pref_registry/pref_registry_syncable.h" #include "content/public/browser/browser_thread.h" #include "extensions/browser/extension_system.h"
diff --git a/chrome/browser/ui/app_list/search/search_result_ranker/app_launch_predictor.cc b/chrome/browser/ui/app_list/search/search_result_ranker/app_launch_predictor.cc index 772736f..cfaa529 100644 --- a/chrome/browser/ui/app_list/search/search_result_ranker/app_launch_predictor.cc +++ b/chrome/browser/ui/app_list/search/search_result_ranker/app_launch_predictor.cc
@@ -6,7 +6,9 @@ #include <cmath> +#include "ash/public/cpp/app_list/app_list_features.h" #include "base/logging.h" +#include "base/metrics/field_trial_params.h" #include "base/stl_util.h" namespace app_list { @@ -16,12 +18,10 @@ constexpr base::TimeDelta kSaveInternal = base::TimeDelta::FromHours(1); // A bin with index i has 5 adjacent bins as: i + 0, i + 1, i + 2, i + 22, and -// i + 23. They each contributes to the final Rank score with different level: -// 0.6 for i-th bin itself, 0.15 for i + 1 (one hour later) and i + 23 ( -// one hour earlier), 0.05 for i + 2 (two hours later) and i + 22 (two hours -// earlier). +// i + 23 which stand for the bin i itself, 1 hour later, 2 hours later, +// 2 hours earlier and 1 hour earlier. Each adjacent bin contributes to the +// final Rank score with weights from BinWeightsFromFlagOrDefault(); constexpr int kAdjacentHourBin[] = {0, 1, 2, 22, 23}; -constexpr float kAdjacentHourWeight[] = {0.6, 0.15, 0.05, 0.05, 0.15}; } // namespace @@ -157,6 +157,7 @@ const auto& frequency_table_map = proto_.hour_app_launch_predictor().binned_frequency_table(); + const std::vector<float> weights = BinWeightsFromFlagOrDefault(); for (size_t i = 0; i < base::size(kAdjacentHourBin); ++i) { // Finds adjacent bin and weight. const int adj_bin = @@ -166,7 +167,7 @@ continue; const auto& frequency_table = find_frequency_table->second; - const float weight = kAdjacentHourWeight[i]; + const float weight = weights[i]; // Accumulates the frequency to the output. if (frequency_table.total_counts() > 0) { @@ -256,6 +257,44 @@ } } +std::vector<float> HourAppLaunchPredictor::BinWeightsFromFlagOrDefault() { + const std::vector<float> default_weights = {0.6, 0.15, 0.05, 0.05, 0.15}; + std::vector<float> weights(5); + + // Get weights for adjacent bins. Every weight has to be within [0.0, 1.0] + // And the sum weights[1] + ..., + weights[4] also needs to be in [0.0, 1.0] + // so that the weight[0] is set to be 1.0 - (weights[1] + ..., + weights[4]). + weights[1] = static_cast<float>(base::GetFieldTrialParamByFeatureAsDouble( + app_list_features::kEnableAppSearchResultRanker, + "weight_1_hour_later_bin", -1.0)); + if (weights[1] < 0.0 || weights[1] > 1.0) + return default_weights; + + weights[2] = static_cast<float>(base::GetFieldTrialParamByFeatureAsDouble( + app_list_features::kEnableAppSearchResultRanker, + "weight_2_hour_later_bin", -1.0)); + if (weights[2] < 0.0 || weights[2] > 1.0) + return default_weights; + + weights[3] = static_cast<float>(base::GetFieldTrialParamByFeatureAsDouble( + app_list_features::kEnableAppSearchResultRanker, + "weight_2_hour_earlier_bin", -1.0)); + if (weights[3] < 0.0 || weights[3] > 1.0) + return default_weights; + + weights[4] = static_cast<float>(base::GetFieldTrialParamByFeatureAsDouble( + app_list_features::kEnableAppSearchResultRanker, + "weight_1_hour_earlier_bin", -1.0)); + if (weights[4] < 0.0 || weights[4] > 1.0) + return default_weights; + + weights[0] = 1.0 - weights[1] - weights[2] - weights[3] - weights[4]; + if (weights[0] < 0.0 || weights[0] > 1.0) + return default_weights; + + return weights; +} + void FakeAppLaunchPredictor::SetShouldSave(bool should_save) { should_save_ = should_save; }
diff --git a/chrome/browser/ui/app_list/search/search_result_ranker/app_launch_predictor.h b/chrome/browser/ui/app_list/search/search_result_ranker/app_launch_predictor.h index d62cdb1e..deb9c75 100644 --- a/chrome/browser/ui/app_list/search/search_result_ranker/app_launch_predictor.h +++ b/chrome/browser/ui/app_list/search/search_result_ranker/app_launch_predictor.h
@@ -138,11 +138,17 @@ FRIEND_TEST_ALL_PREFIXES(HourAppLaunchPredictorTest, GetTheRightBin); FRIEND_TEST_ALL_PREFIXES(HourAppLaunchPredictorTest, RankFromSingleBin); FRIEND_TEST_ALL_PREFIXES(HourAppLaunchPredictorTest, RankFromMultipleBin); + FRIEND_TEST_ALL_PREFIXES(HourAppLaunchPredictorTest, CheckDefaultWeights); + FRIEND_TEST_ALL_PREFIXES(HourAppLaunchPredictorTest, SetWeightsFromFlag); FRIEND_TEST_ALL_PREFIXES(HourAppLaunchPredictorTest, FromProtoDecay); // Returns current bin index of this predictor. int GetBin() const; + // Get weights of adjacent bins from flag which will be set using finch config + // for exploring possible options. + static std::vector<float> BinWeightsFromFlagOrDefault(); + // The proto for this predictor. AppLaunchPredictorProto proto_; // Last time the predictor was saved.
diff --git a/chrome/browser/ui/app_list/search/search_result_ranker/app_launch_predictor_unittest.cc b/chrome/browser/ui/app_list/search/search_result_ranker/app_launch_predictor_unittest.cc index 22be4c8..dd16a86 100644 --- a/chrome/browser/ui/app_list/search/search_result_ranker/app_launch_predictor_unittest.cc +++ b/chrome/browser/ui/app_list/search/search_result_ranker/app_launch_predictor_unittest.cc
@@ -4,11 +4,14 @@ #include "chrome/browser/ui/app_list/search/search_result_ranker/app_launch_predictor.h" +#include "ash/public/cpp/app_list/app_list_features.h" +#include "base/test/scoped_feature_list.h" #include "base/test/scoped_mock_clock_override.h" #include "chrome/browser/ui/app_list/search/search_result_ranker/app_launch_predictor_test_util.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +using testing::ElementsAre; using testing::UnorderedElementsAre; using testing::Pair; using testing::FloatEq; @@ -153,6 +156,7 @@ // Checks the apps are ranked based on frequency in a single bin. TEST_F(HourAppLaunchPredictorTest, RankFromSingleBin) { HourAppLaunchPredictor predictor; + const auto& weights = HourAppLaunchPredictor::BinWeightsFromFlagOrDefault(); // Create a model that trained on kTarget1 3 times, and kTarget2 2 times. SetLocalTime(1, 10); @@ -174,14 +178,16 @@ SetLocalTime(1, 10); EXPECT_THAT(predictor.Rank(), - UnorderedElementsAre(Pair(kTarget1, FloatEq(0.6 * 0.6)), - Pair(kTarget2, FloatEq(0.6 * 0.4)))); + UnorderedElementsAre(Pair(kTarget1, FloatEq(weights[0] * 0.6)), + Pair(kTarget2, FloatEq(weights[0] * 0.4)))); } // Checks the apps are ranked based on linearly combined scores from adjacent // bins. TEST_F(HourAppLaunchPredictorTest, RankFromMultipleBin) { HourAppLaunchPredictor predictor; + const auto& weights = HourAppLaunchPredictor::BinWeightsFromFlagOrDefault(); + // For bin 10 SetLocalTime(1, 10); predictor.Train(kTarget1); @@ -210,15 +216,63 @@ EXPECT_THAT( predictor.Rank(), UnorderedElementsAre( - Pair(kTarget1, FloatEq(0.6 * 2.0 / 3.0 + 0.15 * 0.5)), - Pair(kTarget2, FloatEq(0.6 * 1.0 / 3.0 + 0.15 * 0.5 + 0.05 * 1.0)))); + Pair(kTarget1, FloatEq(weights[0] * 2.0 / 3.0 + weights[1] * 0.5)), + Pair(kTarget2, FloatEq(weights[0] * 1.0 / 3.0 + weights[1] * 0.5 + + weights[2] * 1.0)))); // Check weekends. SetLocalTime(0, 9); EXPECT_THAT( predictor.Rank(), - UnorderedElementsAre(Pair(kTarget1, FloatEq(0.15 * 1.0 / 2.0)), - Pair(kTarget2, FloatEq(0.15 * 1.0 / 2.0 + 0.05)))); + UnorderedElementsAre( + Pair(kTarget1, FloatEq(weights[1] * 1.0 / 2.0)), + Pair(kTarget2, FloatEq(weights[1] * 1.0 / 2.0 + weights[2])))); +} + +// Check the default weights are set correctly. +TEST_F(HourAppLaunchPredictorTest, CheckDefaultWeights) { + base::test::ScopedFeatureList scoped_feature_list_; + scoped_feature_list_.InitAndEnableFeature( + app_list_features::kEnableAppSearchResultRanker); + + EXPECT_THAT(HourAppLaunchPredictor::BinWeightsFromFlagOrDefault(), + ElementsAre(FloatEq(0.6), FloatEq(0.15), FloatEq(0.05), + FloatEq(0.05), FloatEq(0.15))); +} + +// Checks that the weights are set from flag correctly. +TEST_F(HourAppLaunchPredictorTest, SetWeightsFromFlag) { + base::test::ScopedFeatureList scoped_feature_list_; + scoped_feature_list_.InitAndEnableFeatureWithParameters( + app_list_features::kEnableAppSearchResultRanker, + {{"weight_1_hour_later_bin", "0.1"}, + {"weight_2_hour_later_bin", "0.2"}, + {"weight_2_hour_earlier_bin", "0.22"}, + {"weight_1_hour_earlier_bin", "0.23"}}); + + HourAppLaunchPredictor predictor; + const auto& weights = HourAppLaunchPredictor::BinWeightsFromFlagOrDefault(); + + EXPECT_THAT(weights, ElementsAre(FloatEq(0.25), FloatEq(0.1), FloatEq(0.2), + FloatEq(0.22), FloatEq(0.23))); + + // For bin 0 + SetLocalTime(1, 0); + predictor.Train(kTarget1); + predictor.Train(kTarget1); + predictor.Train(kTarget2); + + // For bin 1 + SetLocalTime(1, 1); + predictor.Train(kTarget1); + predictor.Train(kTarget2); + + SetLocalTime(1, 0); + EXPECT_THAT( + predictor.Rank(), + UnorderedElementsAre( + Pair(kTarget1, FloatEq(weights[0] * 2.0 / 3.0 + weights[1] * 0.5)), + Pair(kTarget2, FloatEq(weights[0] * 1.0 / 3.0 + weights[1] * 0.5)))); } // Checks FromProto applies decay correctly.
diff --git a/chrome/browser/ui/ash/chrome_accessibility_delegate.cc b/chrome/browser/ui/ash/chrome_accessibility_delegate.cc index 8001a75..10072534 100644 --- a/chrome/browser/ui/ash/chrome_accessibility_delegate.cc +++ b/chrome/browser/ui/ash/chrome_accessibility_delegate.cc
@@ -8,6 +8,9 @@ #include "chrome/browser/chromeos/accessibility/accessibility_manager.h" #include "chrome/browser/chromeos/accessibility/magnification_manager.h" +#include "chrome/browser/extensions/api/automation_internal/automation_event_router.h" +#include "chrome/common/extensions/chrome_extension_messages.h" +#include "ui/aura/env.h" using chromeos::AccessibilityManager; using chromeos::MagnificationManager; @@ -42,3 +45,25 @@ return std::numeric_limits<double>::min(); } + +void ChromeAccessibilityDelegate::DispatchAccessibilityEvent( + const ui::AXTreeID& tree_id, + const std::vector<ui::AXTreeUpdate>& updates, + const ui::AXEvent& event) { + ExtensionMsg_AccessibilityEventBundleParams event_bundle; + event_bundle.tree_id = tree_id; + for (const ui::AXTreeUpdate& update : updates) + event_bundle.updates.push_back(update); + event_bundle.events.push_back(event); + event_bundle.mouse_location = aura::Env::GetInstance()->last_mouse_location(); + + // Forward the tree updates and the event to the accessibility extension. + extensions::AutomationEventRouter::GetInstance()->DispatchAccessibilityEvents( + event_bundle); +} + +void ChromeAccessibilityDelegate::DispatchTreeDestroyedEvent( + const ui::AXTreeID& tree_id) { + extensions::AutomationEventRouter::GetInstance()->DispatchTreeDestroyedEvent( + tree_id, nullptr /* browser_context */); +}
diff --git a/chrome/browser/ui/ash/chrome_accessibility_delegate.h b/chrome/browser/ui/ash/chrome_accessibility_delegate.h index 015bd0f..773acc7 100644 --- a/chrome/browser/ui/ash/chrome_accessibility_delegate.h +++ b/chrome/browser/ui/ash/chrome_accessibility_delegate.h
@@ -20,6 +20,10 @@ bool ShouldShowAccessibilityMenu() const override; void SaveScreenMagnifierScale(double scale) override; double GetSavedScreenMagnifierScale() override; + void DispatchAccessibilityEvent(const ui::AXTreeID& tree_id, + const std::vector<ui::AXTreeUpdate>& updates, + const ui::AXEvent& event) override; + void DispatchTreeDestroyedEvent(const ui::AXTreeID& tree_id) override; private: DISALLOW_COPY_AND_ASSIGN(ChromeAccessibilityDelegate);
diff --git a/chrome/browser/ui/aura/accessibility/DEPS b/chrome/browser/ui/aura/accessibility/DEPS index b2306413..fbced7a8 100644 --- a/chrome/browser/ui/aura/accessibility/DEPS +++ b/chrome/browser/ui/aura/accessibility/DEPS
@@ -1,6 +1,7 @@ specific_include_rules = { "automation_manager_aura\.cc": [ # TODO(mash): Fix. https://crbug.com/756054 + "+ash/accessibility/ax_host_service.h", "+ash/shell.h", "+ash/wm/window_util.h", ],
diff --git a/chrome/browser/ui/aura/accessibility/automation_manager_aura.cc b/chrome/browser/ui/aura/accessibility/automation_manager_aura.cc index df90b96..abda461 100644 --- a/chrome/browser/ui/aura/accessibility/automation_manager_aura.cc +++ b/chrome/browser/ui/aura/accessibility/automation_manager_aura.cc
@@ -25,9 +25,9 @@ #include "ui/views/widget/widget.h" #if defined(OS_CHROMEOS) +#include "ash/accessibility/ax_host_service.h" #include "ash/shell.h" #include "ash/wm/window_util.h" -#include "chrome/browser/chromeos/accessibility/ax_host_service.h" #include "ui/base/ui_base_features.h" #include "ui/views/widget/widget_delegate.h" #endif @@ -58,7 +58,8 @@ } } // Gain access to out-of-process native windows. - AXHostService::SetAutomationEnabled(true); + // TODO(mash): Split AXHostService into chrome and ash parts. + ash::AXHostService::SetAutomationEnabled(true); #endif } @@ -67,7 +68,7 @@ Reset(true); #if defined(OS_CHROMEOS) - AXHostService::SetAutomationEnabled(false); + ash::AXHostService::SetAutomationEnabled(false); #endif }
diff --git a/chrome/browser/ui/views/overlay/overlay_window_views.cc b/chrome/browser/ui/views/overlay/overlay_window_views.cc index c3807c3..189a2c7 100644 --- a/chrome/browser/ui/views/overlay/overlay_window_views.cc +++ b/chrome/browser/ui/views/overlay/overlay_window_views.cc
@@ -246,18 +246,25 @@ GetControlsScrimLayer()->SetColor(gfx::kGoogleGrey900); GetControlsScrimLayer()->SetOpacity(0.43f); - // views::View that toggles play/pause. ------------------------------------- - play_pause_controls_view_->SetImageAlignment( - views::ImageButton::ALIGN_CENTER, views::ImageButton::ALIGN_MIDDLE); - play_pause_controls_view_->SetToggled(controller_->IsPlayerActive()); - play_pause_controls_view_->set_owned_by_client(); + // view::View that holds the controls. -------------------------------------- + controls_parent_view_->SetPaintToLayer(ui::LAYER_TEXTURED); + controls_parent_view_->SetSize(GetBounds().size()); + controls_parent_view_->layer()->SetFillsBoundsOpaquely(false); + controls_parent_view_->set_owned_by_client(); // views::View that closes the window. -------------------------------------- close_controls_view_->SetPaintToLayer(ui::LAYER_TEXTURED); close_controls_view_->layer()->SetFillsBoundsOpaquely(false); close_controls_view_->set_owned_by_client(); - UpdatePlayPauseControlsSize(); + // view::View that holds the video. ----------------------------------------- + video_view_->SetPaintToLayer(ui::LAYER_TEXTURED); + + // views::View that toggles play/pause. ------------------------------------- + play_pause_controls_view_->SetImageAlignment( + views::ImageButton::ALIGN_CENTER, views::ImageButton::ALIGN_MIDDLE); + play_pause_controls_view_->SetToggled(controller_->IsPlayerActive()); + play_pause_controls_view_->set_owned_by_client(); // Accessibility. play_pause_controls_view_->SetFocusForPlatform(); // Make button focusable. @@ -274,21 +281,13 @@ play_pause_controls_view_->SetToggledTooltipText(pause_button_label); play_pause_controls_view_->SetInstallFocusRingOnFocus(true); - // Add as child views to |controls_parent_view_|. -------------------------- - controls_parent_view_->SetSize(GetBounds().size()); - controls_parent_view_->SetPaintToLayer(ui::LAYER_TEXTURED); + // Set up view::Views heirarchy. -------------------------------------------- controls_parent_view_->AddChildView(play_pause_controls_view_.get()); - controls_parent_view_->layer()->SetFillsBoundsOpaquely(false); - controls_parent_view_->set_owned_by_client(); - - // Add as child views to this widget. --------------------------------------- GetContentsView()->AddChildView(controls_scrim_view_.get()); GetContentsView()->AddChildView(controls_parent_view_.get()); GetContentsView()->AddChildView(close_controls_view_.get()); - // Paint to ui::Layers. ----------------------------------------------------- - video_view_->SetPaintToLayer(ui::LAYER_TEXTURED); - + UpdatePlayPauseControlsSize(); UpdateControlsVisibility(false); }
diff --git a/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc b/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc index 6f46b0d..6dbb63a 100644 --- a/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc +++ b/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc
@@ -62,7 +62,6 @@ #include "chromeos/chromeos_switches.h" #include "chromeos/services/multidevice_setup/public/cpp/url_provider.h" #include "chromeos/strings/grit/chromeos_strings.h" -#include "components/arc/arc_util.h" #include "components/user_manager/user_manager.h" #include "ui/chromeos/devicetype_utils.h" #include "ui/chromeos/events/keyboard_layout_util.h"
diff --git a/chrome/browser/web_applications/bookmark_apps/external_web_apps.cc b/chrome/browser/web_applications/bookmark_apps/external_web_apps.cc index 8e1ee50..fa06d6ad 100644 --- a/chrome/browser/web_applications/bookmark_apps/external_web_apps.cc +++ b/chrome/browser/web_applications/bookmark_apps/external_web_apps.cc
@@ -4,13 +4,16 @@ #include "chrome/browser/web_applications/bookmark_apps/external_web_apps.h" +#include <map> #include <memory> #include <string> #include <utility> #include "base/callback.h" +#include "base/feature_list.h" #include "base/files/file_enumerator.h" #include "base/json/json_file_value_serializer.h" +#include "base/no_destructor.h" #include "base/path_service.h" #include "base/task/post_task.h" #include "base/threading/scoped_blocking_call.h" @@ -35,6 +38,12 @@ // The default value of kCreateShortcuts if false. constexpr char kCreateShortcuts[] = "create_shortcuts"; +// kFeatureName is an optional string parameter specifying a feature +// associated with this app. If specified: +// - if the feature is enabled, the app will be installed +// - if the feature is not enabled, the app will be removed. +constexpr char kFeatureName[] = "feature_name"; + // kLaunchContainer is a required string which can be "window" or "tab" // and controls what sort of container the web app is launched in. constexpr char kLaunchContainer[] = "launch_container"; @@ -48,6 +57,30 @@ FILE_PATH_LITERAL("web_apps"); #endif +bool IsFeatureEnabled(const std::string& feature_name) { + // The feature system ensures there is only ever one Feature instance for each + // given feature name. To enable multiple apps to be gated by the same field + // trial this means there needs to be a global map of Features that is used. + static base::NoDestructor< + std::map<std::string, std::unique_ptr<base::Feature>>> + feature_map; + if (!feature_map->count(feature_name)) { + // To ensure the string used in the feature (which is a char*) is stable + // (i.e. is not freed later on), the key of the map is used. So, first + // insert a null Feature into the map, and then swap it with a real Feature + // constructed using the pointer from the key. + auto it = feature_map->insert(std::make_pair(feature_name, nullptr)).first; + it->second = std::make_unique<base::Feature>( + base::Feature{it->first.c_str(), base::FEATURE_DISABLED_BY_DEFAULT}); + } + + // Use the feature from the map, not the one in the pair above, as it has a + // stable address. + const auto it = feature_map->find(feature_name); + DCHECK(it != feature_map->end()); + return base::FeatureList::IsEnabled(*it->second); +} + std::vector<web_app::PendingAppManager::AppInfo> ScanDir(base::FilePath dir) { base::ScopedBlockingCall scoped_blocking_call(base::BlockingType::MAY_BLOCK); base::FilePath::StringType extension(FILE_PATH_LITERAL(".json")); @@ -79,6 +112,12 @@ std::unique_ptr<base::DictionaryValue> dict_value = base::DictionaryValue::From(std::move(value)); + std::string feature_name; + if (dict_value->GetString(kFeatureName, &feature_name)) { + if (!IsFeatureEnabled(feature_name)) + continue; + } + std::string app_url_str; if (!dict_value->GetString(kAppUrl, &app_url_str) || app_url_str.empty()) { VLOG(2) << file.value() << " had an invalid " << kAppUrl;
diff --git a/chrome/browser/web_applications/bookmark_apps/external_web_apps_unittest.cc b/chrome/browser/web_applications/bookmark_apps/external_web_apps_unittest.cc index 3d924a32..18b8f6f 100644 --- a/chrome/browser/web_applications/bookmark_apps/external_web_apps_unittest.cc +++ b/chrome/browser/web_applications/bookmark_apps/external_web_apps_unittest.cc
@@ -7,8 +7,10 @@ #include <algorithm> #include <vector> +#include "base/feature_list.h" #include "base/path_service.h" #include "base/stl_util.h" +#include "base/test/scoped_feature_list.h" #include "chrome/common/chrome_paths.h" #include "testing/gtest/include/gtest/gtest.h" #include "url/gurl.h" @@ -136,3 +138,26 @@ // correct except for an invalid "launch_container" field. EXPECT_EQ(0u, app_infos.size()); } + +TEST_F(ScanDirForExternalWebAppsTest, EnabledByFinch) { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitAndEnableFeature( + base::Feature{"test_feature_name", base::FEATURE_DISABLED_BY_DEFAULT}); + auto app_infos = web_app::ScanDirForExternalWebAppsForTesting( + test_dir("enabled_by_finch")); + + // The enabled_by_finch directory contains two JSON file containing apps + // that have field trials. As the matching featureis enabled, they should be + // in our list of apps to install. + EXPECT_EQ(2u, app_infos.size()); +} + +TEST_F(ScanDirForExternalWebAppsTest, NotEnabledByFinch) { + auto app_infos = web_app::ScanDirForExternalWebAppsForTesting( + test_dir("enabled_by_finch")); + + // The enabled_by_finch directory contains two JSON file containing apps + // that have field trials. As the matching featureis enabled, they should not + // be in our list of apps to install. + EXPECT_EQ(0u, app_infos.size()); +}
diff --git a/chrome/chrome_cleaner/chrome_utils/extensions_util.cc b/chrome/chrome_cleaner/chrome_utils/extensions_util.cc index 1a4ae916..c2828733 100644 --- a/chrome/chrome_cleaner/chrome_utils/extensions_util.cc +++ b/chrome/chrome_cleaner/chrome_utils/extensions_util.cc
@@ -207,11 +207,8 @@ for (const auto& entry : *default_extensions) { base::string16 extension_id = base::UTF8ToUTF16(entry.first); - if (std::find(default_extension_whitelist.begin(), - default_extension_whitelist.end(), - extension_id) == default_extension_whitelist.end()) { + if (!base::ContainsValue(default_extension_whitelist, extension_id)) policies->emplace_back(extension_id, extensions_file); - } } }
diff --git a/chrome/chrome_cleaner/scanner/urza_scanner_impl_unittest.cc b/chrome/chrome_cleaner/scanner/urza_scanner_impl_unittest.cc index dec29d90..53dc811 100644 --- a/chrome/chrome_cleaner/scanner/urza_scanner_impl_unittest.cc +++ b/chrome/chrome_cleaner/scanner/urza_scanner_impl_unittest.cc
@@ -201,10 +201,8 @@ void ExpectFoundPUPs(const std::set<UwSId>& pups) { EXPECT_EQ(pups.size(), found_pups_.size()); std::set<UwSId>::const_iterator pup = pups.begin(); - for (; pup != pups.end(); ++pup) { - EXPECT_NE(found_pups_.end(), - std::find(found_pups_.begin(), found_pups_.end(), *pup)); - } + for (; pup != pups.end(); ++pup) + EXPECT_TRUE(base::ContainsValue(found_pups_, *pup)); EXPECT_EQ(pups.size(), pups_seen_in_progress_callback_.size()); EXPECT_EQ(pups, pups_seen_in_progress_callback_); }
diff --git a/chrome/common/chrome_content_client.cc b/chrome/common/chrome_content_client.cc index d06d0cf..d6cb69e 100644 --- a/chrome/common/chrome_content_client.cc +++ b/chrome/common/chrome_content_client.cc
@@ -96,16 +96,12 @@ #if BUILDFLAG(ENABLE_LIBRARY_CDMS) #include "media/cdm/cdm_paths.h" // nogncheck -// The order is sensitive here as WIDEVINE_CDM_IS_COMPONENT is defined in -// widevine_cdm_common.h. -// TODO(xhwang): Also make WIDEVINE_CDM_IS_COMPONENT a buildflag to avoid this. -#include "third_party/widevine/cdm/widevine_cdm_common.h" // nogncheck // Registers Widevine CDM if Widevine is enabled, the Widevine CDM is // bundled and not a component. When the Widevine CDM is a component, it is // registered in widevine_cdm_component_installer.cc. -#if BUILDFLAG(ENABLE_WIDEVINE) && BUILDFLAG(SHOULD_BUNDLE_WIDEVINE_CDM) && \ - !defined(WIDEVINE_CDM_IS_COMPONENT) +#if BUILDFLAG(SHOULD_BUNDLE_WIDEVINE_CDM) && !BUILDFLAG(ENABLE_WIDEVINE_CDM_COMPONENT) #define REGISTER_BUNDLED_WIDEVINE_CDM +#include "third_party/widevine/cdm/widevine_cdm_common.h" // nogncheck // TODO(crbug.com/663554): Needed for WIDEVINE_CDM_VERSION_STRING. Support // component updated CDM on all desktop platforms and remove this. // This file is In SHARED_INTERMEDIATE_DIR.
diff --git a/chrome/common/extensions/api/autotest_private.idl b/chrome/common/extensions/api/autotest_private.idl index b6e838a..e3ff3d8a 100644 --- a/chrome/common/extensions/api/autotest_private.idl +++ b/chrome/common/extensions/api/autotest_private.idl
@@ -4,6 +4,8 @@ // API for integration testing. To be used on test images with a test component // extension. +[platforms=("chromeos"), + implemented_in="chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.h"] namespace autotestPrivate { dictionary LoginStatusDict {
diff --git a/chrome/common/mac/app_shim.mojom b/chrome/common/mac/app_shim.mojom index 4ad1dbd..7005ff32 100644 --- a/chrome/common/mac/app_shim.mojom +++ b/chrome/common/mac/app_shim.mojom
@@ -4,6 +4,7 @@ module chrome.mojom; +import "content/public/common/ns_view_bridge_factory.mojom"; import "mojo/public/mojom/base/file_path.mojom"; import "ui/views_bridge_mac/mojo/bridge_factory.mojom"; @@ -26,6 +27,13 @@ CreateViewsBridgeFactory( views_bridge_mac.mojom.BridgeFactory& views_bridge_factory); + // Create the interface through which a content structure + // (RenderWidgetHostView or WebContentsView) may create an NSView that exists + // in the app shim process. + CreateContentNSViewBridgeFactory( + associated content.mojom.NSViewBridgeFactory& + content_ns_views_bridge_factory); + // Signals that a previous LaunchApp message has been processed, and lets the // app shim process know whether it was registered successfully. LaunchAppDone(AppShimLaunchResult launch_result);
diff --git a/chrome/renderer/BUILD.gn b/chrome/renderer/BUILD.gn index b051404..5f1fed1 100644 --- a/chrome/renderer/BUILD.gn +++ b/chrome/renderer/BUILD.gn
@@ -233,7 +233,7 @@ } } - if (enable_library_cdms && enable_widevine) { + if (enable_widevine_cdm_component) { deps += [ "//third_party/widevine/cdm:headers" ] }
diff --git a/chrome/renderer/media/chrome_key_systems_provider.cc b/chrome/renderer/media/chrome_key_systems_provider.cc index 48d53984..e1ba7562 100644 --- a/chrome/renderer/media/chrome_key_systems_provider.cc +++ b/chrome/renderer/media/chrome_key_systems_provider.cc
@@ -6,10 +6,9 @@ #include "base/time/default_tick_clock.h" #include "chrome/renderer/media/chrome_key_systems.h" -#include "media/media_buildflags.h" #include "third_party/widevine/cdm/buildflags.h" -#if BUILDFLAG(ENABLE_LIBRARY_CDMS) && BUILDFLAG(ENABLE_WIDEVINE) +#if BUILDFLAG(ENABLE_WIDEVINE_CDM_COMPONENT) #include "third_party/widevine/cdm/widevine_cdm_common.h" #endif @@ -36,8 +35,7 @@ // Check whether all potentially supported key systems are supported. If so, // no need to update again. -#if BUILDFLAG(ENABLE_LIBRARY_CDMS) && BUILDFLAG(ENABLE_WIDEVINE) && \ - defined(WIDEVINE_CDM_IS_COMPONENT) +#if BUILDFLAG(ENABLE_WIDEVINE_CDM_COMPONENT) for (const auto& properties : *key_systems) { if (properties->GetKeySystemName() == kWidevineKeySystem) { is_update_needed_ = false;
diff --git a/chrome/renderer/media/chrome_key_systems_provider_unittest.cc b/chrome/renderer/media/chrome_key_systems_provider_unittest.cc index be8fa26..a57a4ab 100644 --- a/chrome/renderer/media/chrome_key_systems_provider_unittest.cc +++ b/chrome/renderer/media/chrome_key_systems_provider_unittest.cc
@@ -127,7 +127,7 @@ EXPECT_FALSE(key_systems_provider.IsKeySystemsUpdateNeeded()); tick_clock.Advance(base::TimeDelta::FromMilliseconds(10)); -#if BUILDFLAG(ENABLE_WIDEVINE) && defined(WIDEVINE_CDM_IS_COMPONENT) +#if BUILDFLAG(ENABLE_WIDEVINE_CDM_COMPONENT) // Require update once enough time has passed for builds that install Widevine // as a component. EXPECT_TRUE(key_systems_provider.IsKeySystemsUpdateNeeded()); @@ -157,5 +157,5 @@ // No update needed for builds that either don't offer Widevine or do so // as part of Chrome rather than component installer. EXPECT_FALSE(key_systems_provider.IsKeySystemsUpdateNeeded()); -#endif // BUILDFLAG(ENABLE_WIDEVINE) && defined(WIDEVINE_CDM_IS_COMPONENT) +#endif // BUILDFLAG(ENABLE_WIDEVINE_CDM_COMPONENT) }
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index ce204893..252ed9d 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -1622,6 +1622,7 @@ "../browser/chromeos/extensions/accessibility_features_apitest.cc", "../browser/chromeos/extensions/action_handlers/action_handlers_apitest.cc", "../browser/chromeos/extensions/arc_apps_private_apitest.cc", + "../browser/chromeos/extensions/autotest_private/autotest_private_apitest.cc", "../browser/chromeos/extensions/default_keyboard_extension_browser_test.cc", "../browser/chromeos/extensions/default_keyboard_extension_browser_test.h", "../browser/chromeos/extensions/echo_private_apitest.cc", @@ -1766,7 +1767,6 @@ "../browser/chromeos/system/device_disabling_browsertest.cc", "../browser/chromeos/system/tray_accessibility_browsertest.cc", "../browser/drive/drive_notification_manager_factory_browsertest.cc", - "../browser/extensions/api/autotest_private/autotest_private_apitest.cc", "../browser/extensions/api/certificate_provider/certificate_provider_apitest.cc", "../browser/extensions/api/networking_private/networking_private_apitest.cc", "../browser/extensions/api/networking_private/networking_private_chromeos_apitest.cc",
diff --git a/chrome/test/base/testing_profile.cc b/chrome/test/base/testing_profile.cc index 639b140..b32a606e 100644 --- a/chrome/test/base/testing_profile.cc +++ b/chrome/test/base/testing_profile.cc
@@ -1014,7 +1014,7 @@ const base::FilePath& relative_partition_path) { if (base::FeatureList::IsEnabled(network::features::kNetworkService)) { network::mojom::NetworkContextPtr network_context; - mojo::MakeRequest(&network_context); + network_context_request_ = mojo::MakeRequest(&network_context); return network_context; } return nullptr;
diff --git a/chrome/test/base/testing_profile.h b/chrome/test/base/testing_profile.h index b784b5e2..7c56cc1 100644 --- a/chrome/test/base/testing_profile.h +++ b/chrome/test/base/testing_profile.h
@@ -19,6 +19,7 @@ #include "components/domain_reliability/clear_mode.h" #include "components/keyed_service/content/browser_context_keyed_service_factory.h" #include "extensions/buildflags/buildflags.h" +#include "services/network/public/mojom/network_context.mojom.h" #include "services/network/public/mojom/network_service.mojom.h" #if defined(OS_CHROMEOS) @@ -404,6 +405,10 @@ // request context. Currently, only the CookieMonster is hooked up. scoped_refptr<net::URLRequestContextGetter> extensions_request_context_; + // Holds a dummy network context request to avoid triggering connection error + // handler. + network::mojom::NetworkContextRequest network_context_request_; + bool force_incognito_; std::unique_ptr<Profile> incognito_profile_; TestingProfile* original_profile_;
diff --git a/chrome/test/chromedriver/test/run_py_tests.py b/chrome/test/chromedriver/test/run_py_tests.py index 97de8f4..e02ea9c 100755 --- a/chrome/test/chromedriver/test/run_py_tests.py +++ b/chrome/test/chromedriver/test/run_py_tests.py
@@ -106,6 +106,8 @@ ] _VERSION_SPECIFIC_FILTER['69'] = [ + # https://bugs.chromium.org/p/chromedriver/issues/detail?id=1945 + 'ChromeDriverTest.testWindowFullScreen', # https://bugs.chromium.org/p/chromedriver/issues/detail?id=2515 'HeadlessInvalidCertificateTest.*', # Feature not yet supported in this version @@ -113,6 +115,8 @@ ] _VERSION_SPECIFIC_FILTER['68'] = [ + # https://bugs.chromium.org/p/chromedriver/issues/detail?id=1945 + 'ChromeDriverTest.testWindowFullScreen', # Feature not yet supported in this version 'ChromeDriverTest.testGenerateTestReport', ]
diff --git a/chrome/test/data/web_app_default_apps/enabled_by_finch/chrome_platform_status.json b/chrome/test/data/web_app_default_apps/enabled_by_finch/chrome_platform_status.json new file mode 100644 index 0000000..27013c3 --- /dev/null +++ b/chrome/test/data/web_app_default_apps/enabled_by_finch/chrome_platform_status.json
@@ -0,0 +1,6 @@ +{ + "app_url": "https://www.chromestatus.com/features", + "create_shortcuts": true, + "feature_name": "test_feature_name", + "launch_container": "tab" +}
diff --git a/chrome/test/data/web_app_default_apps/enabled_by_finch/google_search.json b/chrome/test/data/web_app_default_apps/enabled_by_finch/google_search.json new file mode 100644 index 0000000..9fb169dc --- /dev/null +++ b/chrome/test/data/web_app_default_apps/enabled_by_finch/google_search.json
@@ -0,0 +1,6 @@ +{ + "app_url": "https://google.com", + "create_shortcuts": true, + "feature_name": "test_feature_name", + "launch_container": "tab" +}
diff --git a/chrome/test/data/webui/print_preview/pages_settings_test.js b/chrome/test/data/webui/print_preview/pages_settings_test.js index 954fdc7..29f7ed15 100644 --- a/chrome/test/data/webui/print_preview/pages_settings_test.js +++ b/chrome/test/data/webui/print_preview/pages_settings_test.js
@@ -66,23 +66,27 @@ documentInfo.updatePageCount(pageCount); pagesSection.notifyPath('documentInfo.pageCount'); Polymer.dom.flush(); + let input = null; + return test_util.waitForRender(pagesSection) + .then(() => { + input = pagesSection.$.pageSettingsCustomInput.inputElement; + const readyForInput = pagesSection.$.customRadioButton.checked ? + Promise.resolve() : + test_util.eventToPromise('focus', input); - const input = pagesSection.$.pageSettingsCustomInput.inputElement; - const readyForInput = pagesSection.$$('#custom-radio-button').checked ? - Promise.resolve() : - test_util.eventToPromise('focus', input); + // Select custom + pagesSection.$.customRadioButton.click(); + return readyForInput; + }) + .then(() => { + // Set input string + input.value = inputString; + input.dispatchEvent( + new CustomEvent('input', {composed: true, bubbles: true})); - // Select custom - pagesSection.$$('#custom-radio-button').click(); - return readyForInput.then(() => { - // Set input string - input.value = inputString; - input.dispatchEvent( - new CustomEvent('input', {composed: true, bubbles: true})); - - // Validate results - return test_util.eventToPromise('input-change', pagesSection); - }); + // Validate results + return test_util.eventToPromise('input-change', pagesSection); + }); } /** @param {!Array<number>} expectedPages The expected pages value. */
diff --git a/chrome/test/data/webui/print_preview/settings_section_test.js b/chrome/test/data/webui/print_preview/settings_section_test.js index 99d676d..4670b74 100644 --- a/chrome/test/data/webui/print_preview/settings_section_test.js +++ b/chrome/test/data/webui/print_preview/settings_section_test.js
@@ -557,8 +557,8 @@ assertFalse(pagesElement.hidden); // Default value is all pages. Print ticket expects this to be empty. - const allRadio = pagesElement.$$('#all-radio-button'); - const customRadio = pagesElement.$$('#custom-radio-button'); + const allRadio = pagesElement.$.allRadioButton; + const customRadio = pagesElement.$.customRadioButton; const pagesCrInput = pagesElement.$.pageSettingsCustomInput; const pagesInput = pagesCrInput.inputElement; @@ -582,10 +582,10 @@ // Set selection of pages 1 and 2. customRadio.click(); - // Manually set |customSelected_| since focus may not work correctly on + // Manually set |optionSelected_| since focus may not work correctly on // MacOS. The PageSettingsTests verify this behavior is correct on all // platforms. - pagesElement.set('customSelected_', true); + pagesElement.set('optionSelected_', pagesElement.pagesValueEnum_.CUSTOM); triggerInputEvent(pagesInput, '1-2'); return test_util.eventToPromise('input-change', pagesElement)
diff --git a/chromeos/CHROMEOS_LKGM b/chromeos/CHROMEOS_LKGM index 9b4a632..022b672b 100644 --- a/chromeos/CHROMEOS_LKGM +++ b/chromeos/CHROMEOS_LKGM
@@ -1 +1 @@ -11100.0.0 \ No newline at end of file +11107.0.0 \ No newline at end of file
diff --git a/chromeos/chromeos_switches.cc b/chromeos/chromeos_switches.cc index 0dc72e5..8660ec4 100644 --- a/chromeos/chromeos_switches.cc +++ b/chromeos/chromeos_switches.cc
@@ -332,6 +332,9 @@ // Enables animated transitions during first-run tutorial. const char kEnableFirstRunUITransitions[] = "enable-first-run-ui-transitions"; +// Enables the marketing opt-in screen in OOBE. +const char kEnableMarketingOptInScreen[] = "enable-market-opt-in"; + // Enables notifications about captive portals in session. const char kEnableNetworkPortalNotification[] = "enable-network-portal-notification"; @@ -366,12 +369,6 @@ // Enables the VoiceInteraction support. const char kEnableVoiceInteraction[] = "enable-voice-interaction"; -// Enables zip archiver - packer. -const char kEnableZipArchiverPacker[] = "enable-zip-archiver-packer"; - -// Disables zip archiver - packer. -const char kDisableZipArchiverPacker[] = "disable-zip-archiver-packer"; - // Enables zip archiver - unpacker. const char kEnableZipArchiverUnpacker[] = "enable-zip-archiver-unpacker"; @@ -704,12 +701,6 @@ kDisableZipArchiverUnpacker); } -bool IsZipArchiverPackerEnabled() { - // Enabled by default. - return !base::CommandLine::ForCurrentProcess()->HasSwitch( - kDisableZipArchiverPacker); -} - bool IsSigninFrameClientCertsEnabled() { return !base::CommandLine::ForCurrentProcess()->HasSwitch( kDisableSigninFrameClientCerts);
diff --git a/chromeos/chromeos_switches.h b/chromeos/chromeos_switches.h index 89058ab..6f51a85 100644 --- a/chromeos/chromeos_switches.h +++ b/chromeos/chromeos_switches.h
@@ -85,7 +85,6 @@ kDisableSystemTimezoneAutomaticDetectionPolicy[]; CHROMEOS_EXPORT extern const char kDisableVolumeAdjustSound[]; CHROMEOS_EXPORT extern const char kDisableWakeOnWifi[]; -CHROMEOS_EXPORT extern const char kDisableZipArchiverPacker[]; CHROMEOS_EXPORT extern const char kDisableZipArchiverUnpacker[]; CHROMEOS_EXPORT extern const char kEnableArc[]; CHROMEOS_EXPORT extern const char kEnableArcOobeOptinNoSkip[]; @@ -99,6 +98,7 @@ CHROMEOS_EXPORT extern const char kEnableExtensionAssetsSharing[]; CHROMEOS_EXPORT extern const char kEnableFileManagerTouchMode[]; CHROMEOS_EXPORT extern const char kEnableFirstRunUITransitions[]; +CHROMEOS_EXPORT extern const char kEnableMarketingOptInScreen[]; CHROMEOS_EXPORT extern const char kEnableNetworkPortalNotification[]; CHROMEOS_EXPORT extern const char kEnableOfflineDemoMode[]; CHROMEOS_EXPORT extern const char kEnablePhysicalKeyboardAutocorrect[]; @@ -108,7 +108,6 @@ CHROMEOS_EXPORT extern const char kEnableTouchpadThreeFingerClick[]; CHROMEOS_EXPORT extern const char kEnableVideoPlayerChromecastSupport[]; CHROMEOS_EXPORT extern const char kEnableVoiceInteraction[]; -CHROMEOS_EXPORT extern const char kEnableZipArchiverPacker[]; CHROMEOS_EXPORT extern const char kEnableZipArchiverUnpacker[]; CHROMEOS_EXPORT extern const char kEnterpriseDisableArc[]; CHROMEOS_EXPORT extern const char kEnterpriseDisableLicenseTypeSelection[]; @@ -208,9 +207,6 @@ // Returns true if Zip Archiver is enabled for unpacking files. CHROMEOS_EXPORT bool IsZipArchiverUnpackerEnabled(); -// Returns true if Zip Archiver is enabled for packing files. -CHROMEOS_EXPORT bool IsZipArchiverPackerEnabled(); - // Returns true if client certificate authentication for the sign-in frame on // the Chrome OS sign-in screen is enabled. CHROMEOS_EXPORT bool IsSigninFrameClientCertsEnabled();
diff --git a/chromeos/components/drivefs/fake_drivefs.cc b/chromeos/components/drivefs/fake_drivefs.cc index 1939d1f9..9e73ccb8 100644 --- a/chromeos/components/drivefs/fake_drivefs.cc +++ b/chromeos/components/drivefs/fake_drivefs.cc
@@ -120,7 +120,9 @@ static std::vector<drivefs::mojom::QueryItemPtr> SearchFiles( const base::FilePath& mount_path) { std::vector<drivefs::mojom::QueryItemPtr> results; - base::FileEnumerator walker(mount_path, true, base::FileEnumerator::FILES); + base::FileEnumerator walker( + mount_path, true, + base::FileEnumerator::FILES | base::FileEnumerator::DIRECTORIES); for (auto file = walker.Next(); !file.empty(); file = walker.Next()) { auto item = drivefs::mojom::QueryItem::New(); item->path = base::FilePath("/"); @@ -157,29 +159,26 @@ void OnComplete() { if (--pending_callbacks_ == 0) { - if (!query_.empty() || available_offline_ || shared_with_me_) { - // Filter out non-matching results. - base::EraseIf(results_, [=](const auto& item_ptr) { - const base::FilePath path = item_ptr->path; - const drivefs::mojom::FileMetadata* metadata = - item_ptr->metadata.get(); - if (!query_.empty()) { - return base::ToLowerASCII(path.BaseName().value()).find(query_) == - std::string::npos; - } - if (available_offline_) { - if (metadata && metadata->available_offline) - return false; - if (metadata && - metadata->type == mojom::FileMetadata::Type::kHosted) - return false; - } - if (shared_with_me_ && metadata) { - return !metadata->shared; - } + // Filter out non-matching results. + base::EraseIf(results_, [=](const auto& item_ptr) { + if (!item_ptr->metadata) { return true; - }); - } + } + const base::FilePath path = item_ptr->path; + const drivefs::mojom::FileMetadata* metadata = item_ptr->metadata.get(); + if (!query_.empty()) { + return base::ToLowerASCII(path.BaseName().value()).find(query_) == + std::string::npos; + } + if (available_offline_) { + return !metadata->available_offline && + metadata->type != mojom::FileMetadata::Type::kHosted; + } + if (shared_with_me_) { + return !metadata->shared; + } + return false; + }); std::move(callback_).Run(drive::FileError::FILE_ERROR_OK, {std::move(results_)});
diff --git a/chromeos/services/ime/ime_service_unittest.cc b/chromeos/services/ime/ime_service_unittest.cc index eceb940..08b5612 100644 --- a/chromeos/services/ime/ime_service_unittest.cc +++ b/chromeos/services/ime/ime_service_unittest.cc
@@ -152,19 +152,20 @@ TEST_F(ImeServiceTest, MultipleClients) { bool success = false; - TestClientChannel test_channel; + TestClientChannel test_channel1; + TestClientChannel test_channel2; mojom::InputChannelPtr to_engine_ptr1; mojom::InputChannelPtr to_engine_ptr2; ime_manager_->ConnectToImeEngine( "m17n:ar", mojo::MakeRequest(&to_engine_ptr1), - test_channel.CreateInterfacePtrAndBind(), extra, + test_channel1.CreateInterfacePtrAndBind(), extra, base::BindOnce(&ConnectCallback, &success)); ime_manager_.FlushForTesting(); ime_manager_->ConnectToImeEngine( "m17n:ar", mojo::MakeRequest(&to_engine_ptr2), - test_channel.CreateInterfacePtrAndBind(), extra, + test_channel2.CreateInterfacePtrAndBind(), extra, base::BindOnce(&ConnectCallback, &success)); ime_manager_.FlushForTesting();
diff --git a/components/arc/arc_util.cc b/components/arc/arc_util.cc index efc40632e..aa476967 100644 --- a/components/arc/arc_util.cc +++ b/components/arc/arc_util.cc
@@ -75,18 +75,6 @@ return false; } -bool IsPlayStoreAvailable() { - if (IsRobotOrOfflineDemoAccountMode()) - return false; - const auto* command_line = base::CommandLine::ForCurrentProcess(); - if (!command_line->HasSwitch(chromeos::switches::kArcStartMode)) - return true; - - const std::string value = - command_line->GetSwitchValueASCII(chromeos::switches::kArcStartMode); - return value != kAlwaysStartWithNoPlayStore; -} - bool ShouldArcAlwaysStart() { const auto* command_line = base::CommandLine::ForCurrentProcess(); if (!command_line->HasSwitch(chromeos::switches::kArcStartMode)) @@ -96,6 +84,11 @@ return value == kAlwaysStartWithNoPlayStore || value == kAlwaysStart; } +bool ShouldArcAlwaysStartWithNoPlayStore() { + return base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( + chromeos::switches::kArcStartMode) == kAlwaysStartWithNoPlayStore; +} + bool ShouldShowOptInForTesting() { return base::CommandLine::ForCurrentProcess()->HasSwitch( chromeos::switches::kArcForceShowOptInUi);
diff --git a/components/arc/arc_util.h b/components/arc/arc_util.h index cbf7656..bbfc2b8 100644 --- a/components/arc/arc_util.h +++ b/components/arc/arc_util.h
@@ -40,14 +40,16 @@ // to run ARC. bool IsWebstoreSearchEnabled(); -// Returns true if ARC image has Play Store package. -bool IsPlayStoreAvailable(); - // Returns true if ARC should always start within the primary user session // (opted in user or not), and other supported mode such as guest and Kiosk // mode. bool ShouldArcAlwaysStart(); +// Returns true if ARC should always start with no Play Store availability +// within the primary user session (opted in user or not), and other supported +// mode such as guest and Kiosk mode. +bool ShouldArcAlwaysStartWithNoPlayStore(); + // Returns true if ARC OptIn ui needs to be shown for testing. bool ShouldShowOptInForTesting();
diff --git a/components/arc/arc_util_unittest.cc b/components/arc/arc_util_unittest.cc index 4192eae..0bc9e2a0 100644 --- a/components/arc/arc_util_unittest.cc +++ b/components/arc/arc_util_unittest.cc
@@ -239,7 +239,15 @@ auto* command_line = base::CommandLine::ForCurrentProcess(); command_line->InitFromArgv({"", "--arc-availability=installed"}); EXPECT_FALSE(ShouldArcAlwaysStart()); - EXPECT_TRUE(IsPlayStoreAvailable()); + EXPECT_FALSE(ShouldArcAlwaysStartWithNoPlayStore()); +} + +TEST_F(ArcUtilTest, ArcStartModeAlwaysStart) { + auto* command_line = base::CommandLine::ForCurrentProcess(); + command_line->InitFromArgv( + {"", "--arc-availability=installed", "--arc-start-mode=always-start"}); + EXPECT_TRUE(ShouldArcAlwaysStart()); + EXPECT_FALSE(ShouldArcAlwaysStartWithNoPlayStore()); } TEST_F(ArcUtilTest, ArcStartModeWithoutPlayStore) { @@ -248,7 +256,7 @@ {"", "--arc-availability=installed", "--arc-start-mode=always-start-with-no-play-store"}); EXPECT_TRUE(ShouldArcAlwaysStart()); - EXPECT_FALSE(IsPlayStoreAvailable()); + EXPECT_TRUE(ShouldArcAlwaysStartWithNoPlayStore()); } TEST_F(ArcUtilTest, ScaleFactorToDensity) {
diff --git a/components/autofill_assistant/browser/BUILD.gn b/components/autofill_assistant/browser/BUILD.gn index 767c230e..50cdd5d 100644 --- a/components/autofill_assistant/browser/BUILD.gn +++ b/components/autofill_assistant/browser/BUILD.gn
@@ -22,8 +22,14 @@ "actions/click_action.h", "actions/focus_element_action.cc", "actions/focus_element_action.h", + "actions/navigate_action.cc", + "actions/navigate_action.h", + "actions/reset_action.cc", + "actions/reset_action.h", "actions/select_option_action.cc", "actions/select_option_action.h", + "actions/stop_action.cc", + "actions/stop_action.h", "actions/tell_action.cc", "actions/tell_action.h", "actions/upload_dom_action.cc",
diff --git a/components/autofill_assistant/browser/actions/action_delegate.h b/components/autofill_assistant/browser/actions/action_delegate.h index 54d9073e..bd52c55d 100644 --- a/components/autofill_assistant/browser/actions/action_delegate.h +++ b/components/autofill_assistant/browser/actions/action_delegate.h
@@ -10,6 +10,8 @@ #include "base/callback_forward.h" +class GURL; + namespace autofill { class AutofillProfile; } @@ -90,6 +92,17 @@ NodeProto* node_tree_out, base::OnceCallback<void(bool)> callback) = 0; + // Load |url| in the current tab. Returns immediately, before the new page has + // been loaded. + virtual void LoadURL(const GURL& url) = 0; + + // Shut down Autofill Assistant at the end of the current script. + virtual void Shutdown() = 0; + + // Restart Autofill Assistant at the end of the current script with a cleared + // state. + virtual void Restart() = 0; + // Return the current ClientMemory. virtual ClientMemory* GetClientMemory() = 0;
diff --git a/components/autofill_assistant/browser/actions/mock_action_delegate.cc b/components/autofill_assistant/browser/actions/mock_action_delegate.cc index 3c4daf0..7036a53 100644 --- a/components/autofill_assistant/browser/actions/mock_action_delegate.cc +++ b/components/autofill_assistant/browser/actions/mock_action_delegate.cc
@@ -4,6 +4,8 @@ #include "components/autofill_assistant/browser/actions/mock_action_delegate.h" +#include "url/gurl.h" + namespace autofill_assistant { MockActionDelegate::MockActionDelegate() = default;
diff --git a/components/autofill_assistant/browser/actions/mock_action_delegate.h b/components/autofill_assistant/browser/actions/mock_action_delegate.h index 758e52a..2c6bee0 100644 --- a/components/autofill_assistant/browser/actions/mock_action_delegate.h +++ b/components/autofill_assistant/browser/actions/mock_action_delegate.h
@@ -5,6 +5,9 @@ #ifndef COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_ACTIONS_MOCK_ACTION_DELEGATE_H_ #define COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_ACTIONS_MOCK_ACTION_DELEGATE_H_ +#include <string> +#include <vector> + #include "base/callback.h" #include "components/autofill_assistant/browser/actions/action_delegate.h" #include "testing/gmock/include/gmock/gmock.h" @@ -95,6 +98,9 @@ void(const std::vector<std::string>& selectors, NodeProto* node_tree_out, base::OnceCallback<void(bool)> callback)); + MOCK_METHOD1(LoadURL, void(const GURL& url)); + MOCK_METHOD0(Shutdown, void()); + MOCK_METHOD0(Restart, void()); MOCK_METHOD0(GetClientMemory, ClientMemory*()); };
diff --git a/components/autofill_assistant/browser/actions/navigate_action.cc b/components/autofill_assistant/browser/actions/navigate_action.cc new file mode 100644 index 0000000..67e2c08 --- /dev/null +++ b/components/autofill_assistant/browser/actions/navigate_action.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 "components/autofill_assistant/browser/actions/navigate_action.h" + +#include <memory> +#include <utility> + +#include "base/callback.h" +#include "components/autofill_assistant/browser/actions/action_delegate.h" +#include "url/gurl.h" + +namespace autofill_assistant { + +NavigateAction::NavigateAction(const ActionProto& proto) : Action(proto) { + DCHECK(proto_.has_navigate()); +} + +NavigateAction::~NavigateAction() {} + +void NavigateAction::ProcessAction(ActionDelegate* delegate, + ProcessActionCallback callback) { + GURL url(proto_.navigate().url()); + delegate->LoadURL(url); + processed_action_proto_ = std::make_unique<ProcessedActionProto>(); + UpdateProcessedAction(/* status= */ true); + std::move(callback).Run(std::move(processed_action_proto_)); +} + +} // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/actions/navigate_action.h b/components/autofill_assistant/browser/actions/navigate_action.h new file mode 100644 index 0000000..f42c9f784 --- /dev/null +++ b/components/autofill_assistant/browser/actions/navigate_action.h
@@ -0,0 +1,29 @@ +// 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 COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_ACTIONS_NAVIGATE_ACTION_H_ +#define COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_ACTIONS_NAVIGATE_ACTION_H_ + +#include <string> + +#include "base/macros.h" +#include "components/autofill_assistant/browser/actions/action.h" + +namespace autofill_assistant { +// An action to display a message. +class NavigateAction : public Action { + public: + explicit NavigateAction(const ActionProto& proto); + ~NavigateAction() override; + + // Overrides Action: + void ProcessAction(ActionDelegate* delegate, + ProcessActionCallback callback) override; + + private: + DISALLOW_COPY_AND_ASSIGN(NavigateAction); +}; + +} // namespace autofill_assistant +#endif // COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_ACTIONS_NAVIGATE_ACTION_H_
diff --git a/components/autofill_assistant/browser/actions/reset_action.cc b/components/autofill_assistant/browser/actions/reset_action.cc new file mode 100644 index 0000000..ea3b81f --- /dev/null +++ b/components/autofill_assistant/browser/actions/reset_action.cc
@@ -0,0 +1,29 @@ +// 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 "components/autofill_assistant/browser/actions/reset_action.h" + +#include <memory> +#include <utility> + +#include "base/callback.h" +#include "components/autofill_assistant/browser/actions/action_delegate.h" + +namespace autofill_assistant { + +ResetAction::ResetAction(const ActionProto& proto) : Action(proto) { + DCHECK(proto_.has_reset()); +} + +ResetAction::~ResetAction() {} + +void ResetAction::ProcessAction(ActionDelegate* delegate, + ProcessActionCallback callback) { + delegate->Restart(); + processed_action_proto_ = std::make_unique<ProcessedActionProto>(); + UpdateProcessedAction(true); + std::move(callback).Run(std::move(processed_action_proto_)); +} + +} // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/actions/reset_action.h b/components/autofill_assistant/browser/actions/reset_action.h new file mode 100644 index 0000000..1fb19af --- /dev/null +++ b/components/autofill_assistant/browser/actions/reset_action.h
@@ -0,0 +1,29 @@ +// 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 COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_ACTIONS_RESET_ACTION_H_ +#define COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_ACTIONS_RESET_ACTION_H_ + +#include <string> + +#include "base/macros.h" +#include "components/autofill_assistant/browser/actions/action.h" + +namespace autofill_assistant { + +class ResetAction : public Action { + public: + explicit ResetAction(const ActionProto& proto); + ~ResetAction() override; + + // Overrides Action: + void ProcessAction(ActionDelegate* delegate, + ProcessActionCallback callback) override; + + private: + DISALLOW_COPY_AND_ASSIGN(ResetAction); +}; + +} // namespace autofill_assistant +#endif // COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_ACTIONS_RESET_ACTION_H_
diff --git a/components/autofill_assistant/browser/actions/stop_action.cc b/components/autofill_assistant/browser/actions/stop_action.cc new file mode 100644 index 0000000..fba77a7 --- /dev/null +++ b/components/autofill_assistant/browser/actions/stop_action.cc
@@ -0,0 +1,29 @@ +// 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 "components/autofill_assistant/browser/actions/stop_action.h" + +#include <memory> +#include <utility> + +#include "base/callback.h" +#include "components/autofill_assistant/browser/actions/action_delegate.h" + +namespace autofill_assistant { + +StopAction::StopAction(const ActionProto& proto) : Action(proto) { + DCHECK(proto_.has_stop()); +} + +StopAction::~StopAction() {} + +void StopAction::ProcessAction(ActionDelegate* delegate, + ProcessActionCallback callback) { + delegate->Shutdown(); + processed_action_proto_ = std::make_unique<ProcessedActionProto>(); + UpdateProcessedAction(true); + std::move(callback).Run(std::move(processed_action_proto_)); +} + +} // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/actions/stop_action.h b/components/autofill_assistant/browser/actions/stop_action.h new file mode 100644 index 0000000..de62b30 --- /dev/null +++ b/components/autofill_assistant/browser/actions/stop_action.h
@@ -0,0 +1,29 @@ +// 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 COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_ACTIONS_STOP_ACTION_H_ +#define COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_ACTIONS_STOP_ACTION_H_ + +#include <string> + +#include "base/macros.h" +#include "components/autofill_assistant/browser/actions/action.h" + +namespace autofill_assistant { + +class StopAction : public Action { + public: + explicit StopAction(const ActionProto& proto); + ~StopAction() override; + + // Overrides Action: + void ProcessAction(ActionDelegate* delegate, + ProcessActionCallback callback) override; + + private: + DISALLOW_COPY_AND_ASSIGN(StopAction); +}; + +} // namespace autofill_assistant +#endif // COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_ACTIONS_STOP_ACTION_H_
diff --git a/components/autofill_assistant/browser/actions/wait_for_dom_action.cc b/components/autofill_assistant/browser/actions/wait_for_dom_action.cc index c69b659c..be7dd36 100644 --- a/components/autofill_assistant/browser/actions/wait_for_dom_action.cc +++ b/components/autofill_assistant/browser/actions/wait_for_dom_action.cc
@@ -32,8 +32,8 @@ ProcessActionCallback callback) { processed_action_proto_ = std::make_unique<ProcessedActionProto>(); - // Fail the action if the selector is empty. - if (proto_.wait_for_dom().element().selectors().empty()) { + // Fail the action if selectors is empty. + if (proto_.wait_for_dom().selectors().empty()) { UpdateProcessedAction(false); DLOG(ERROR) << "Empty selector, failing action."; std::move(callback).Run(std::move(processed_action_proto_)); @@ -54,7 +54,7 @@ ProcessActionCallback callback) { DCHECK(rounds > 0); std::vector<std::string> selectors; - for (const auto& selector : proto_.wait_for_dom().element().selectors()) { + for (const auto& selector : proto_.wait_for_dom().selectors()) { selectors.emplace_back(selector); } delegate->ElementExists(
diff --git a/components/autofill_assistant/browser/client_memory.h b/components/autofill_assistant/browser/client_memory.h index 128c473..49d7ab12 100644 --- a/components/autofill_assistant/browser/client_memory.h +++ b/components/autofill_assistant/browser/client_memory.h
@@ -34,9 +34,6 @@ virtual void set_selected_address(const std::string& name, const std::string& guid); - // TODO(crbug.com/806868): Add a clear() method that resets the memory and - // call it when necessary (TBD). - private: base::Optional<std::string> selected_card_;
diff --git a/components/autofill_assistant/browser/controller.cc b/components/autofill_assistant/browser/controller.cc index 7d67ded..c7432cc 100644 --- a/components/autofill_assistant/browser/controller.cc +++ b/components/autofill_assistant/browser/controller.cc
@@ -56,7 +56,8 @@ client_(std::move(client)), web_controller_(std::move(web_controller)), service_(std::move(service)), - script_tracker_(std::make_unique<ScriptTracker>(this, this)), + script_tracker_(std::make_unique<ScriptTracker>(/* delegate= */ this, + /* listener= */ this)), parameters_(std::move(parameters)), memory_(std::make_unique<ClientMemory>()), allow_autostart_(true) { @@ -106,13 +107,32 @@ } void Controller::OnScriptExecuted(const std::string& script_path, - bool success) { + ScriptExecutor::Result result) { GetUiController()->HideOverlay(); - if (!success) { + if (!result.success) { LOG(ERROR) << "Failed to execute script " << script_path; // TODO(crbug.com/806868): Handle script execution failure. } + switch (result.at_end) { + case ScriptExecutor::SHUTDOWN: + GetUiController()->Shutdown(); // indirectly deletes this + return; + + case ScriptExecutor::RESTART: + script_tracker_ = std::make_unique<ScriptTracker>(/* delegate= */ this, + /* listener= */ this); + memory_ = std::make_unique<ClientMemory>(); + script_domain_ = ""; + break; + + case ScriptExecutor::CONTINUE: + break; + + default: + DLOG(ERROR) << "Unexpected value for at_end: " << result.at_end; + break; + } GetOrCheckScripts(web_contents()->GetLastCommittedURL()); }
diff --git a/components/autofill_assistant/browser/controller.h b/components/autofill_assistant/browser/controller.h index cd93b96..f9b93c4 100644 --- a/components/autofill_assistant/browser/controller.h +++ b/components/autofill_assistant/browser/controller.h
@@ -62,7 +62,8 @@ void GetOrCheckScripts(const GURL& url); void OnGetScripts(const GURL& url, bool result, const std::string& response); void OnScriptChosen(const std::string& script_path); - void OnScriptExecuted(const std::string& script_path, bool success); + void OnScriptExecuted(const std::string& script_path, + ScriptExecutor::Result result); // Overrides content::UiDelegate: void OnClickOverlay() override;
diff --git a/components/autofill_assistant/browser/controller_unittest.cc b/components/autofill_assistant/browser/controller_unittest.cc index 1a788dc..b6e0b1f 100644 --- a/components/autofill_assistant/browser/controller_unittest.cc +++ b/components/autofill_assistant/browser/controller_unittest.cc
@@ -23,6 +23,7 @@ using ::testing::Contains; using ::testing::ElementsAre; using ::testing::Eq; +using ::testing::InSequence; using ::testing::NiceMock; using ::testing::Pair; using ::testing::ReturnRef; @@ -101,6 +102,7 @@ // Updates the current url of the controller and forces a refresh, without // bothering with actually rendering any page content. void SimulateNavigateToUrl(const GURL& url) { + url_ = url; tester_->SetLastCommittedURL(url); controller_->DidFinishLoad(nullptr, url); } @@ -163,6 +165,65 @@ SimulateNavigateToUrl(GURL("http://a.example.com/path")); } +TEST_F(ControllerTest, Stop) { + ActionsResponseProto actions_response; + actions_response.add_actions()->mutable_stop(); + std::string actions_response_str; + actions_response.SerializeToString(&actions_response_str); + EXPECT_CALL(*mock_service_, OnGetActions(StrEq("stop"), _, _)) + .WillOnce(RunOnceCallback<2>(true, actions_response_str)); + EXPECT_CALL(*mock_service_, OnGetNextActions(_, _, _)) + .WillOnce(RunOnceCallback<2>(true, "")); + + EXPECT_CALL(*mock_ui_controller_, Shutdown()); + GetUiDelegate()->OnScriptSelected("stop"); +} + +TEST_F(ControllerTest, Reset) { + { + InSequence sequence; + + // 1. Fetch scripts for URL, which in contains a single "reset" script. + SupportsScriptResponseProto script_response; + AddRunnableScript(&script_response, "reset"); + std::string script_response_str; + script_response.SerializeToString(&script_response_str); + EXPECT_CALL(*mock_service_, OnGetScriptsForUrl(_, _, _)) + .WillOnce(RunOnceCallback<2>(true, script_response_str)); + + EXPECT_CALL(*mock_ui_controller_, UpdateScripts(SizeIs(1))); + + // 2. Execute the "reset" script, which contains a reset action. + ActionsResponseProto actions_response; + actions_response.add_actions()->mutable_reset(); + std::string actions_response_str; + actions_response.SerializeToString(&actions_response_str); + EXPECT_CALL(*mock_service_, OnGetActions(StrEq("reset"), _, _)) + .WillOnce(RunOnceCallback<2>(true, actions_response_str)); + + // 3. Report the result of running that action. + EXPECT_CALL(*mock_service_, OnGetNextActions(_, _, _)) + .WillOnce(RunOnceCallback<2>(true, "")); + + // 4. The reset action forces a reload of the scripts, even though the URL + // hasn't changed. The "reset" script is reported again to UpdateScripts. + EXPECT_CALL(*mock_service_, OnGetScriptsForUrl(_, _, _)) + .WillOnce(RunOnceCallback<2>(true, script_response_str)); + + // Reset forces the controller to fetch the scripts twice, even though the + // URL doesn't change.. + EXPECT_CALL(*mock_ui_controller_, UpdateScripts(SizeIs(1))); + } + + // Resetting should clear the client memory + controller_->GetClientMemory()->set_selected_card("set"); + + SimulateNavigateToUrl(GURL("http://a.example.com/path")); + GetUiDelegate()->OnScriptSelected("reset"); + + EXPECT_FALSE(controller_->GetClientMemory()->selected_card()); +} + TEST_F(ControllerTest, RefreshScriptWhenDomainChanges) { EXPECT_CALL(*mock_service_, OnGetScriptsForUrl(Eq(GURL("http://a.example.com/path1")), _, _))
diff --git a/components/autofill_assistant/browser/mock_ui_controller.h b/components/autofill_assistant/browser/mock_ui_controller.h index ed0f7a6..d02b43c4 100644 --- a/components/autofill_assistant/browser/mock_ui_controller.h +++ b/components/autofill_assistant/browser/mock_ui_controller.h
@@ -5,6 +5,9 @@ #ifndef COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_MOCK_UI_CONTROLLER_H_ #define COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_MOCK_UI_CONTROLLER_H_ +#include <string> +#include <vector> + #include "base/callback.h" #include "components/autofill_assistant/browser/script.h" #include "components/autofill_assistant/browser/ui_controller.h" @@ -21,6 +24,7 @@ MOCK_METHOD1(ShowStatusMessage, void(const std::string& message)); MOCK_METHOD0(ShowOverlay, void()); MOCK_METHOD0(HideOverlay, void()); + MOCK_METHOD0(Shutdown, void()); MOCK_METHOD1(UpdateScripts, void(const std::vector<ScriptHandle>& scripts)); void ChooseAddress(
diff --git a/components/autofill_assistant/browser/mock_web_controller.h b/components/autofill_assistant/browser/mock_web_controller.h index c243260..518e1e4 100644 --- a/components/autofill_assistant/browser/mock_web_controller.h +++ b/components/autofill_assistant/browser/mock_web_controller.h
@@ -21,6 +21,8 @@ MOCK_METHOD0(GetUrl, const GURL&()); + MOCK_METHOD1(LoadURL, void(const GURL&)); + void ClickElement(const std::vector<std::string>& selectors, base::OnceCallback<void(bool)> callback) override { // Transforming callback into a references allows using RunOnceCallback on
diff --git a/components/autofill_assistant/browser/protocol_utils.cc b/components/autofill_assistant/browser/protocol_utils.cc index 3ab4340..c44b2ff 100644 --- a/components/autofill_assistant/browser/protocol_utils.cc +++ b/components/autofill_assistant/browser/protocol_utils.cc
@@ -10,7 +10,10 @@ #include "components/autofill_assistant/browser/actions/autofill_action.h" #include "components/autofill_assistant/browser/actions/click_action.h" #include "components/autofill_assistant/browser/actions/focus_element_action.h" +#include "components/autofill_assistant/browser/actions/navigate_action.h" +#include "components/autofill_assistant/browser/actions/reset_action.h" #include "components/autofill_assistant/browser/actions/select_option_action.h" +#include "components/autofill_assistant/browser/actions/stop_action.h" #include "components/autofill_assistant/browser/actions/tell_action.h" #include "components/autofill_assistant/browser/actions/upload_dom_action.h" #include "components/autofill_assistant/browser/actions/wait_for_dom_action.h" @@ -170,16 +173,26 @@ actions->emplace_back(std::make_unique<WaitForDomAction>(action)); break; } - case ActionProto::ActionInfoCase::kUploadDom: { - actions->emplace_back(std::make_unique<UploadDomAction>(action)); - break; - } case ActionProto::ActionInfoCase::kSelectOption: { actions->emplace_back(std::make_unique<SelectOptionAction>(action)); break; } + case ActionProto::ActionInfoCase::kNavigate: { + actions->emplace_back(std::make_unique<NavigateAction>(action)); + break; + } + case ActionProto::ActionInfoCase::kStop: { + actions->emplace_back(std::make_unique<StopAction>(action)); + break; + } + case ActionProto::ActionInfoCase::kReset: { + actions->emplace_back(std::make_unique<ResetAction>(action)); + break; + } + default: case ActionProto::ActionInfoCase::ACTION_INFO_NOT_SET: { - LOG(ERROR) << "Unknown or unspported action."; + DLOG(ERROR) << "Unknown or unsupported action with action_case=" + << action.action_info_case(); break; } }
diff --git a/components/autofill_assistant/browser/script_executor.cc b/components/autofill_assistant/browser/script_executor.cc index a5c02f4..9e3f510 100644 --- a/components/autofill_assistant/browser/script_executor.cc +++ b/components/autofill_assistant/browser/script_executor.cc
@@ -21,7 +21,10 @@ ScriptExecutor::ScriptExecutor(const std::string& script_path, ScriptExecutorDelegate* delegate) - : script_path_(script_path), delegate_(delegate), weak_ptr_factory_(this) { + : script_path_(script_path), + delegate_(delegate), + at_end_(CONTINUE), + weak_ptr_factory_(this) { DCHECK(delegate_); } ScriptExecutor::~ScriptExecutor() {} @@ -112,13 +115,25 @@ std::move(callback)); } +void ScriptExecutor::LoadURL(const GURL& url) { + delegate_->GetWebController()->LoadURL(url); +} + +void ScriptExecutor::Shutdown() { + at_end_ = SHUTDOWN; +} + +void ScriptExecutor::Restart() { + at_end_ = RESTART; +} + ClientMemory* ScriptExecutor::GetClientMemory() { return delegate_->GetClientMemory(); } void ScriptExecutor::OnGetActions(bool result, const std::string& response) { if (!result) { - std::move(callback_).Run(false); + RunCallback(false); return; } processed_actions_.clear(); @@ -127,19 +142,28 @@ bool parse_result = ProtocolUtils::ParseActions(response, &last_server_payload_, &actions_); if (!parse_result) { - std::move(callback_).Run(false); + RunCallback(false); return; } if (actions_.empty()) { // Finished executing the script if there are no more actions. - std::move(callback_).Run(true); + RunCallback(true); return; } ProcessNextAction(); } +void ScriptExecutor::RunCallback(bool success) { + DCHECK(callback_); + + ScriptExecutor::Result result; + result.success = success; + result.at_end = at_end_; + std::move(callback_).Run(result); +} + void ScriptExecutor::ProcessNextAction() { // We could get into a strange situation if ProcessNextAction is called before // the action was reported as processed, which should not happen. In that case
diff --git a/components/autofill_assistant/browser/script_executor.h b/components/autofill_assistant/browser/script_executor.h index 59b8883..2bfb5cb5 100644 --- a/components/autofill_assistant/browser/script_executor.h +++ b/components/autofill_assistant/browser/script_executor.h
@@ -27,7 +27,25 @@ ScriptExecutorDelegate* delegate); ~ScriptExecutor() override; - using RunScriptCallback = base::OnceCallback<void(bool)>; + // What should happen after the script has run. + enum AtEnd { + // Continue normally. + CONTINUE = 0, + + // Shut down Autofill Assistant. + SHUTDOWN, + + // Reset all state and restart. + RESTART + }; + + // Contains the result of the Run operation. + struct Result { + bool success = false; + AtEnd at_end = AtEnd::CONTINUE; + }; + + using RunScriptCallback = base::OnceCallback<void(Result)>; void Run(RunScriptCallback callback); // Override ActionDelegate: @@ -62,10 +80,14 @@ void BuildNodeTree(const std::vector<std::string>& selectors, NodeProto* node_tree_out, base::OnceCallback<void(bool)> callback) override; + void LoadURL(const GURL& url) override; + void Shutdown() override; + void Restart() override; ClientMemory* GetClientMemory() override; private: void OnGetActions(bool result, const std::string& response); + void RunCallback(bool success); void ProcessNextAction(); void ProcessAction(Action* action); void GetNextActions(); @@ -78,6 +100,7 @@ std::vector<std::unique_ptr<Action>> actions_; std::vector<ProcessedActionProto> processed_actions_; std::string last_server_payload_; + AtEnd at_end_; base::WeakPtrFactory<ScriptExecutor> weak_ptr_factory_; DISALLOW_COPY_AND_ASSIGN(ScriptExecutor);
diff --git a/components/autofill_assistant/browser/script_executor_unittest.cc b/components/autofill_assistant/browser/script_executor_unittest.cc index 462283df..8aa3cbb 100644 --- a/components/autofill_assistant/browser/script_executor_unittest.cc +++ b/components/autofill_assistant/browser/script_executor_unittest.cc
@@ -23,6 +23,7 @@ using ::testing::AllOf; using ::testing::Contains; using ::testing::DoAll; +using ::testing::Field; using ::testing::NiceMock; using ::testing::Pair; using ::testing::SaveArg; @@ -81,7 +82,10 @@ TEST_F(ScriptExecutorTest, GetActionsFails) { EXPECT_CALL(mock_service_, OnGetActions(_, _, _)) .WillOnce(RunOnceCallback<2>(false, "")); - EXPECT_CALL(executor_callback_, Run(false)); + EXPECT_CALL(executor_callback_, + Run(AllOf(Field(&ScriptExecutor::Result::success, false), + Field(&ScriptExecutor::Result::at_end, + ScriptExecutor::CONTINUE)))); executor_->Run(executor_callback_.Get()); } @@ -95,11 +99,12 @@ _)) .WillOnce(RunOnceCallback<2>(true, "")); - EXPECT_CALL(executor_callback_, Run(true)); + EXPECT_CALL(executor_callback_, + Run(Field(&ScriptExecutor::Result::success, true))); executor_->Run(executor_callback_.Get()); } -TEST_F(ScriptExecutorTest, RunOneActionReportFailureAndStop) { +TEST_F(ScriptExecutorTest, RunOneActionReportAndReturn) { ActionsResponseProto actions_response; actions_response.set_server_payload("payload"); actions_response.add_actions() @@ -114,7 +119,10 @@ EXPECT_CALL(mock_service_, OnGetNextActions(_, _, _)) .WillOnce(DoAll(SaveArg<1>(&processed_actions_capture), RunOnceCallback<2>(true, ""))); - EXPECT_CALL(executor_callback_, Run(true)); + EXPECT_CALL(executor_callback_, + Run(AllOf(Field(&ScriptExecutor::Result::success, true), + Field(&ScriptExecutor::Result::at_end, + ScriptExecutor::CONTINUE)))); executor_->Run(executor_callback_.Get()); ASSERT_EQ(1u, processed_actions_capture.size()); @@ -140,13 +148,48 @@ RunOnceCallback<2>(true, Serialize(next_actions_response)))) .WillOnce(DoAll(SaveArg<1>(&processed_actions2_capture), RunOnceCallback<2>(true, ""))); - EXPECT_CALL(executor_callback_, Run(true)); + EXPECT_CALL(executor_callback_, + Run(Field(&ScriptExecutor::Result::success, true))); executor_->Run(executor_callback_.Get()); EXPECT_EQ(2u, processed_actions1_capture.size()); EXPECT_EQ(1u, processed_actions2_capture.size()); } +TEST_F(ScriptExecutorTest, StopAfterEnd) { + ActionsResponseProto actions_response; + actions_response.set_server_payload("payload"); + actions_response.add_actions()->mutable_stop(); + + EXPECT_CALL(mock_service_, OnGetActions(_, _, _)) + .WillOnce(RunOnceCallback<2>(true, Serialize(actions_response))); + + EXPECT_CALL(mock_service_, OnGetNextActions(_, _, _)) + .WillOnce(RunOnceCallback<2>(true, "")); + EXPECT_CALL(executor_callback_, + Run(AllOf(Field(&ScriptExecutor::Result::success, true), + Field(&ScriptExecutor::Result::at_end, + ScriptExecutor::SHUTDOWN)))); + executor_->Run(executor_callback_.Get()); +} + +TEST_F(ScriptExecutorTest, ResetAfterEnd) { + ActionsResponseProto actions_response; + actions_response.set_server_payload("payload"); + actions_response.add_actions()->mutable_reset(); + + EXPECT_CALL(mock_service_, OnGetActions(_, _, _)) + .WillOnce(RunOnceCallback<2>(true, Serialize(actions_response))); + + EXPECT_CALL(mock_service_, OnGetNextActions(_, _, _)) + .WillOnce(RunOnceCallback<2>(true, "")); + EXPECT_CALL(executor_callback_, + Run(AllOf(Field(&ScriptExecutor::Result::success, true), + Field(&ScriptExecutor::Result::at_end, + ScriptExecutor::RESTART)))); + executor_->Run(executor_callback_.Get()); +} + TEST_F(ScriptExecutorTest, InterruptActionListOnError) { ActionsResponseProto initial_actions_response; initial_actions_response.set_server_payload("payload"); @@ -174,7 +217,8 @@ RunOnceCallback<2>(true, Serialize(next_actions_response)))) .WillOnce(DoAll(SaveArg<1>(&processed_actions2_capture), RunOnceCallback<2>(true, ""))); - EXPECT_CALL(executor_callback_, Run(true)); + EXPECT_CALL(executor_callback_, + Run(Field(&ScriptExecutor::Result::success, true))); executor_->Run(executor_callback_.Get()); ASSERT_EQ(2u, processed_actions1_capture.size()); @@ -209,7 +253,8 @@ EXPECT_TRUE(scoped_task_environment_.MainThreadHasPendingTask()); // Moving forward in time triggers action execution. - EXPECT_CALL(executor_callback_, Run(true)); + EXPECT_CALL(executor_callback_, + Run(Field(&ScriptExecutor::Result::success, true))); scoped_task_environment_.FastForwardBy( base::TimeDelta::FromMilliseconds(1000)); EXPECT_FALSE(scoped_task_environment_.MainThreadHasPendingTask());
diff --git a/components/autofill_assistant/browser/script_tracker.cc b/components/autofill_assistant/browser/script_tracker.cc index 001cc84..d2cac1c 100644 --- a/components/autofill_assistant/browser/script_tracker.cc +++ b/components/autofill_assistant/browser/script_tracker.cc
@@ -59,9 +59,11 @@ } void ScriptTracker::ExecuteScript(const std::string& script_path, - base::OnceCallback<void(bool)> callback) { + ScriptExecutor::RunScriptCallback callback) { if (running()) { - std::move(callback).Run(false); + ScriptExecutor::Result result; + result.success = false; + std::move(callback).Run(result); return; } @@ -74,12 +76,10 @@ void ScriptTracker::OnScriptRun( const std::string& script_path, - base::OnceCallback<void(bool)> original_callback, - bool success) { - executed_scripts_[script_path] = - success ? SCRIPT_STATUS_SUCCESS : SCRIPT_STATUS_FAILURE; + ScriptExecutor::RunScriptCallback original_callback, + ScriptExecutor::Result result) { executor_.reset(); - std::move(original_callback).Run(success); + std::move(original_callback).Run(result); } void ScriptTracker::UpdateRunnableScriptsIfNecessary() {
diff --git a/components/autofill_assistant/browser/script_tracker.h b/components/autofill_assistant/browser/script_tracker.h index bd48e92..4e4d67e 100644 --- a/components/autofill_assistant/browser/script_tracker.h +++ b/components/autofill_assistant/browser/script_tracker.h
@@ -59,7 +59,7 @@ // Call CheckScripts to refresh the set of runnable script after script // execution. void ExecuteScript(const std::string& path, - base::OnceCallback<void(bool)> callback); + ScriptExecutor::RunScriptCallback callback); // Checks whether a script is currently running. There can be at most one // script running at a time. @@ -67,8 +67,8 @@ private: void OnScriptRun(const std::string& script_path, - base::OnceCallback<void(bool)> original_callback, - bool success); + ScriptExecutor::RunScriptCallback original_callback, + ScriptExecutor::Result result); void UpdateRunnableScriptsIfNecessary(); // Returns true if |runnable_| should be updated.
diff --git a/components/autofill_assistant/browser/script_tracker_unittest.cc b/components/autofill_assistant/browser/script_tracker_unittest.cc index d64d90cd..9acb108 100644 --- a/components/autofill_assistant/browser/script_tracker_unittest.cc +++ b/components/autofill_assistant/browser/script_tracker_unittest.cc
@@ -21,11 +21,12 @@ namespace autofill_assistant { using ::testing::_; using ::testing::ElementsAre; -using ::testing::UnorderedElementsAre; +using ::testing::Field; using ::testing::IsEmpty; using ::testing::NiceMock; using ::testing::ReturnRef; using ::testing::SizeIs; +using ::testing::UnorderedElementsAre; class ScriptTrackerTest : public testing::Test, public ScriptTracker::Listener, @@ -227,8 +228,9 @@ UnorderedElementsAre("script1", "script2")); // run 'script 1' - base::MockCallback<base::OnceCallback<void(bool)>> execute_callback; - EXPECT_CALL(execute_callback, Run(true)); + base::MockCallback<ScriptExecutor::RunScriptCallback> execute_callback; + EXPECT_CALL(execute_callback, + Run(Field(&ScriptExecutor::Result::success, true))); tracker_.ExecuteScript("script1", execute_callback.Get()); tracker_.CheckScripts();
diff --git a/components/autofill_assistant/browser/service.proto b/components/autofill_assistant/browser/service.proto index 385b3a0..de0cc72 100644 --- a/components/autofill_assistant/browser/service.proto +++ b/components/autofill_assistant/browser/service.proto
@@ -187,12 +187,15 @@ oneof action_info { ClickProto click = 5; SelectOptionProto select_option = 7; + NavigateProto navigate = 9; TellProto tell = 11; FocusElementProto focus_element = 12; WaitForDomProto wait_for_dom = 19; UseCreditCardProto use_card = 28; UseAddressProto use_address = 29; UploadDomProto upload_dom = 18; + ResetProto reset = 34; + StopProto stop = 35; } } @@ -340,11 +343,11 @@ // Ask Chrome to wait for an element in the DOM. This can be used to only // proceed to the next action once the page is ready. message WaitForDomProto { - // The element to wait. - optional ElementReferenceProto element = 1; - // Fail after waiting this amount of time. - optional int32 timeout_ms = 2; + optional int32 timeout_ms = 1; + + // The element to wait for. + repeated string selectors = 2; } // Volatile upload of a portion of the dom for backend analysis, does not store @@ -354,3 +357,14 @@ // page is returned. optional ElementReferenceProto tree_root = 1; } + +// Load the given URL in the current tab. +message NavigateProto { + optional string url = 1; +} + +// Resets Autofill Assistant: clears any state and server payload. +message ResetProto {} + +// Stop Autofill Assistant. +message StopProto {}
diff --git a/components/autofill_assistant/browser/ui_controller.h b/components/autofill_assistant/browser/ui_controller.h index 58063f4..db7d91e2 100644 --- a/components/autofill_assistant/browser/ui_controller.h +++ b/components/autofill_assistant/browser/ui_controller.h
@@ -5,13 +5,12 @@ #ifndef COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_UI_CONTROLLER_H_ #define COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_UI_CONTROLLER_H_ -#include "components/autofill_assistant/browser/script.h" -#include "components/autofill_assistant/browser/ui_delegate.h" - #include <string> #include <vector> #include "base/callback_forward.h" +#include "components/autofill_assistant/browser/script.h" +#include "components/autofill_assistant/browser/ui_delegate.h" namespace autofill_assistant { struct ScriptHandle; @@ -33,6 +32,11 @@ // Hide the overlay. virtual void HideOverlay() = 0; + // Shuts down Autofill Assistant: hide the UI and frees any associated state. + // + // Warning: this indirectly deletes the caller. + virtual void Shutdown() = 0; + // Update the list of scripts in the UI. virtual void UpdateScripts(const std::vector<ScriptHandle>& scripts) = 0;
diff --git a/components/autofill_assistant/browser/web_controller.cc b/components/autofill_assistant/browser/web_controller.cc index d38b4185..3dfe1f9 100644 --- a/components/autofill_assistant/browser/web_controller.cc +++ b/components/autofill_assistant/browser/web_controller.cc
@@ -4,6 +4,8 @@ #include "components/autofill_assistant/browser/web_controller.h" +#include <utility> + #include "base/callback.h" #include "base/logging.h" #include "components/autofill/content/browser/content_autofill_driver.h" @@ -83,6 +85,11 @@ return web_contents_->GetLastCommittedURL(); } +void WebController::LoadURL(const GURL& url) { + web_contents_->GetController().LoadURLWithParams( + content::NavigationController::LoadURLParams(url)); +} + void WebController::ClickElement(const std::vector<std::string>& selectors, base::OnceCallback<void(bool)> callback) { DCHECK(!selectors.empty());
diff --git a/components/autofill_assistant/browser/web_controller.h b/components/autofill_assistant/browser/web_controller.h index 9c3e155..278798b3 100644 --- a/components/autofill_assistant/browser/web_controller.h +++ b/components/autofill_assistant/browser/web_controller.h
@@ -45,6 +45,10 @@ // Returns the last committed URL of the associated |web_contents_|. virtual const GURL& GetUrl(); + // Load |url| in the current tab. Returns immediately, before the new page has + // been loaded. + virtual void LoadURL(const GURL& url); + // Perform a mouse left button click on the element given by |selectors| and // return the result through callback. // CSS selectors in |selectors| are ordered from top frame to the frame
diff --git a/components/autofill_assistant/browser/web_controller_browsertest.cc b/components/autofill_assistant/browser/web_controller_browsertest.cc index 0938619..0df28081 100644 --- a/components/autofill_assistant/browser/web_controller_browsertest.cc +++ b/components/autofill_assistant/browser/web_controller_browsertest.cc
@@ -14,6 +14,8 @@ namespace autofill_assistant { +const char* kTargetWebsitePath = "/autofill_assistant_target_website.html"; + class WebControllerBrowserTest : public content::ContentBrowserTest { public: WebControllerBrowserTest() {} @@ -26,9 +28,8 @@ http_server_->ServeFilesFromSourceDirectory( "components/test/data/autofill_assistant"); ASSERT_TRUE(http_server_->Start()); - ASSERT_TRUE(NavigateToURL( - shell(), - http_server_->GetURL("/autofill_assistant_target_website.html"))); + ASSERT_TRUE( + NavigateToURL(shell(), http_server_->GetURL(kTargetWebsitePath))); web_controller_ = WebController::CreateForWebContents(shell()->web_contents()); } @@ -200,9 +201,11 @@ std::move(done_callback).Run(); } + protected: + std::unique_ptr<WebController> web_controller_; + private: std::unique_ptr<net::EmbeddedTestServer> http_server_; - std::unique_ptr<WebController> web_controller_; DISALLOW_COPY_AND_ASSIGN(WebControllerBrowserTest); }; @@ -398,4 +401,11 @@ EXPECT_FALSE(SetFieldValue(selectors, "foobar")); } +IN_PROC_BROWSER_TEST_F(WebControllerBrowserTest, NavigateToUrl) { + EXPECT_EQ(kTargetWebsitePath, web_controller_->GetUrl().path()); + web_controller_->LoadURL(GURL(url::kAboutBlankURL)); + WaitForLoadStop(shell()->web_contents()); + EXPECT_EQ(url::kAboutBlankURL, web_controller_->GetUrl().spec()); +} + } // namespace
diff --git a/components/browser_sync/profile_sync_components_factory_impl.cc b/components/browser_sync/profile_sync_components_factory_impl.cc index a861e9c..5ed2abe 100644 --- a/components/browser_sync/profile_sync_components_factory_impl.cc +++ b/components/browser_sync/profile_sync_components_factory_impl.cc
@@ -35,7 +35,9 @@ #include "components/sync/driver/proxy_data_type_controller.h" #include "components/sync/driver/sync_client.h" #include "components/sync/driver/sync_driver_switches.h" +#include "components/sync/driver/syncable_service_based_model_type_controller.h" #include "components/sync/engine/sync_engine.h" +#include "components/sync/model/model_type_store_service.h" #include "components/sync/model_impl/forwarding_model_type_controller_delegate.h" #include "components/sync/model_impl/proxy_model_type_controller_delegate.h" #include "components/sync_bookmarks/bookmark_change_processor.h" @@ -59,6 +61,7 @@ using syncer::DataTypeManagerObserver; using syncer::ModelTypeController; using syncer::ProxyDataTypeController; +using syncer::SyncableServiceBasedModelTypeController; namespace browser_sync { @@ -266,13 +269,29 @@ // Favicon sync is enabled by default. Register unless explicitly disabled. if (!disabled_types.Has(syncer::FAVICON_IMAGES) && !disabled_types.Has(syncer::FAVICON_TRACKING)) { - // crbug/384552. We disable error uploading for this data types for now. - controllers.push_back(std::make_unique<AsyncDirectoryTypeController>( - syncer::FAVICON_IMAGES, base::RepeatingClosure(), sync_client_, - syncer::GROUP_UI, ui_thread_)); - controllers.push_back(std::make_unique<AsyncDirectoryTypeController>( - syncer::FAVICON_TRACKING, base::RepeatingClosure(), sync_client_, - syncer::GROUP_UI, ui_thread_)); + if (base::FeatureList::IsEnabled(switches::kSyncPseudoUSSFavicons)) { + controllers.push_back( + std::make_unique<SyncableServiceBasedModelTypeController>( + syncer::FAVICON_IMAGES, + sync_client_->GetModelTypeStoreService()->GetStoreFactory(), + base::BindOnce(&syncer::SyncClient::GetSyncableServiceForType, + base::Unretained(sync_client_), + syncer::FAVICON_IMAGES))); + controllers.push_back( + std::make_unique<SyncableServiceBasedModelTypeController>( + syncer::FAVICON_TRACKING, + sync_client_->GetModelTypeStoreService()->GetStoreFactory(), + base::BindOnce(&syncer::SyncClient::GetSyncableServiceForType, + base::Unretained(sync_client_), + syncer::FAVICON_TRACKING))); + } else { + controllers.push_back(std::make_unique<AsyncDirectoryTypeController>( + syncer::FAVICON_IMAGES, base::RepeatingClosure(), sync_client_, + syncer::GROUP_UI, ui_thread_)); + controllers.push_back(std::make_unique<AsyncDirectoryTypeController>( + syncer::FAVICON_TRACKING, base::RepeatingClosure(), sync_client_, + syncer::GROUP_UI, ui_thread_)); + } } } @@ -285,20 +304,40 @@ } if (!disabled_types.Has(syncer::PREFERENCES)) { - if (!override_prefs_controller_to_uss_for_test_) { + if (override_prefs_controller_to_uss_for_test_) { + controllers.push_back(CreateModelTypeControllerForModelRunningOnUIThread( + syncer::PREFERENCES)); + } else if (base::FeatureList::IsEnabled( + switches::kSyncPseudoUSSPreferences)) { + controllers.push_back( + std::make_unique<SyncableServiceBasedModelTypeController>( + syncer::PREFERENCES, + sync_client_->GetModelTypeStoreService()->GetStoreFactory(), + base::BindOnce(&syncer::SyncClient::GetSyncableServiceForType, + base::Unretained(sync_client_), + syncer::PREFERENCES))); + } else { controllers.push_back(std::make_unique<AsyncDirectoryTypeController>( syncer::PREFERENCES, error_callback, sync_client_, syncer::GROUP_UI, ui_thread_)); - } else { - controllers.push_back(CreateModelTypeControllerForModelRunningOnUIThread( - syncer::PREFERENCES)); } } if (!disabled_types.Has(syncer::PRIORITY_PREFERENCES)) { - controllers.push_back(std::make_unique<AsyncDirectoryTypeController>( - syncer::PRIORITY_PREFERENCES, error_callback, sync_client_, - syncer::GROUP_UI, ui_thread_)); + if (base::FeatureList::IsEnabled( + switches::kSyncPseudoUSSPriorityPreferences)) { + controllers.push_back( + std::make_unique<SyncableServiceBasedModelTypeController>( + syncer::PRIORITY_PREFERENCES, + sync_client_->GetModelTypeStoreService()->GetStoreFactory(), + base::BindOnce(&syncer::SyncClient::GetSyncableServiceForType, + base::Unretained(sync_client_), + syncer::PRIORITY_PREFERENCES))); + } else { + controllers.push_back(std::make_unique<AsyncDirectoryTypeController>( + syncer::PRIORITY_PREFERENCES, error_callback, sync_client_, + syncer::GROUP_UI, ui_thread_)); + } } #if defined(OS_CHROMEOS)
diff --git a/components/browser_sync/profile_sync_service.h b/components/browser_sync/profile_sync_service.h index 4b6efca..05d1160cb 100644 --- a/components/browser_sync/profile_sync_service.h +++ b/components/browser_sync/profile_sync_service.h
@@ -677,9 +677,6 @@ // is decremented back to zero, Sync setup is marked no longer in progress. int outstanding_setup_in_progress_handles_ = 0; - // List of available data type controllers. - syncer::DataTypeController::TypeMap data_type_controllers_; - // Whether the SyncEngine has been initialized. bool engine_initialized_; @@ -737,6 +734,9 @@ std::unique_ptr<syncer::DeviceInfoSyncBridge> device_info_sync_bridge_; + // List of available data type controllers. + syncer::DataTypeController::TypeMap data_type_controllers_; + std::unique_ptr<syncer::NetworkResources> network_resources_; const StartBehavior start_behavior_;
diff --git a/components/browser_sync/sync_auth_manager.cc b/components/browser_sync/sync_auth_manager.cc index 1f98567..b559018 100644 --- a/components/browser_sync/sync_auth_manager.cc +++ b/components/browser_sync/sync_auth_manager.cc
@@ -177,10 +177,7 @@ // Drop any access token here, to maintain the invariant that only one // of a token OR a pending request OR a pending retry can exist at any // time. - if (!access_token_.empty()) { - access_token_.clear(); - credentials_changed_callback_.Run(); - } + InvalidateAccessToken(); request_access_token_backoff_.InformOfRequest(false); ScheduleAccessTokenRequest(); } @@ -210,6 +207,20 @@ } } +void SyncAuthManager::InvalidateAccessToken() { + if (access_token_.empty()) { + return; + } + + identity_manager_->RemoveAccessTokenFromCache( + sync_account_.account_info.account_id, + OAuth2TokenService::ScopeSet{GaiaConstants::kChromeSyncOAuth2Scope}, + access_token_); + + access_token_.clear(); + credentials_changed_callback_.Run(); +} + void SyncAuthManager::ClearAccessTokenAndRequest() { access_token_.clear(); request_access_token_retry_timer_.Stop(); @@ -425,13 +436,7 @@ // Invalidate any previous token, otherwise the token service will return the // same token again. - if (!access_token_.empty()) { - identity_manager_->RemoveAccessTokenFromCache( - sync_account_.account_info.account_id, kOAuth2ScopeSet, access_token_); - - access_token_.clear(); - credentials_changed_callback_.Run(); - } + InvalidateAccessToken(); // Finally, kick off a new access token fetch. token_status_.token_request_time = base::Time::Now();
diff --git a/components/browser_sync/sync_auth_manager.h b/components/browser_sync/sync_auth_manager.h index 44f0578c..745919ad 100644 --- a/components/browser_sync/sync_auth_manager.h +++ b/components/browser_sync/sync_auth_manager.h
@@ -120,6 +120,12 @@ // account to another is exposed to observers as a sign-out + sign-in. bool UpdateSyncAccountIfNecessary(); + // Invalidates any current access token, which means invalidating it with the + // IdentityManager and also dropping our own cached copy. Meant to be called + // when we know the current token is invalid (e.g. expired). Does not do + // anything about any scheduled or ongoing request. + void InvalidateAccessToken(); + // Clears any access token we have, and cancels any pending or scheduled // request for one. void ClearAccessTokenAndRequest();
diff --git a/components/drive/service/fake_drive_service.cc b/components/drive/service/fake_drive_service.cc index 378a5074..414a268 100644 --- a/components/drive/service/fake_drive_service.cc +++ b/components/drive/service/fake_drive_service.cc
@@ -1563,6 +1563,19 @@ return HTTP_SUCCESS; } +google_apis::DriveApiErrorCode FakeDriveService::SetFileAsSharedWithMe( + const std::string& resource_id) { + DCHECK(thread_checker_.CalledOnValidThread()); + + EntryInfo* entry = FindEntryByResourceId(resource_id); + if (!entry) + return HTTP_NOT_FOUND; + + entry->change_resource.mutable_file()->set_shared_with_me_date( + base::Time::Now()); + return HTTP_SUCCESS; +} + void FakeDriveService::AddChangeObserver(ChangeObserver* change_observer) { change_observers_.AddObserver(change_observer); }
diff --git a/components/drive/service/fake_drive_service.h b/components/drive/service/fake_drive_service.h index de3ab351..10bcc28 100644 --- a/components/drive/service/fake_drive_service.h +++ b/components/drive/service/fake_drive_service.h
@@ -332,6 +332,9 @@ const std::string& resource_id, google_apis::drive::FileVisibility* visibility); + google_apis::DriveApiErrorCode SetFileAsSharedWithMe( + const std::string& resource_id); + void AddChangeObserver(ChangeObserver* observer); void RemoveChangeObserver(ChangeObserver* observer);
diff --git a/components/password_manager/core/browser/blacklisted_duplicates_cleaner_unittest.cc b/components/password_manager/core/browser/blacklisted_duplicates_cleaner_unittest.cc index f65f18d..43e2625 100644 --- a/components/password_manager/core/browser/blacklisted_duplicates_cleaner_unittest.cc +++ b/components/password_manager/core/browser/blacklisted_duplicates_cleaner_unittest.cc
@@ -4,6 +4,7 @@ #include "components/password_manager/core/browser/blacklisted_duplicates_cleaner.h" +#include "base/bind_helpers.h" #include "base/stl_util.h" #include "base/test/metrics/histogram_tester.h" #include "base/test/scoped_task_environment.h" @@ -87,7 +88,8 @@ prefs()->registry()->RegisterBooleanPref( prefs::kCredentialsWithWrongSignonRealmRemoved, true); - password_manager_util::RemoveUselessCredentials(store(), prefs(), 0); + password_manager_util::RemoveUselessCredentials(store(), prefs(), 0, + base::NullCallback()); scoped_task_environment.RunUntilIdle(); // Check that one of the next two forms was removed. @@ -99,7 +101,8 @@ EXPECT_FALSE( prefs()->GetBoolean(prefs::kDuplicatedBlacklistedCredentialsRemoved)); - password_manager_util::RemoveUselessCredentials(store(), prefs(), 0); + password_manager_util::RemoveUselessCredentials(store(), prefs(), 0, + base::NullCallback()); scoped_task_environment.RunUntilIdle(); EXPECT_TRUE( prefs()->GetBoolean(prefs::kDuplicatedBlacklistedCredentialsRemoved));
diff --git a/components/password_manager/core/browser/form_saver_impl.cc b/components/password_manager/core/browser/form_saver_impl.cc index 63835157..07d51de9 100644 --- a/components/password_manager/core/browser/form_saver_impl.cc +++ b/components/password_manager/core/browser/form_saver_impl.cc
@@ -16,10 +16,32 @@ #include "url/gurl.h" #include "url/origin.h" +using autofill::FormData; +using autofill::FormFieldData; using autofill::PasswordForm; namespace password_manager { +namespace { + +// Remove all information from |form| that is not required for signature +// calculation. +void SanitizeFormData(FormData* form) { + form->main_frame_origin = url::Origin(); + for (FormFieldData& field : form->fields) { + field.label.clear(); + field.value.clear(); + field.autocomplete_attribute.clear(); + field.option_values.clear(); + field.option_contents.clear(); + field.placeholder.clear(); + field.css_classes.clear(); + field.id.clear(); + } +} + +} // namespace + FormSaverImpl::FormSaverImpl(PasswordStore* store) : store_(store) { DCHECK(store); } @@ -53,11 +75,13 @@ } void FormSaverImpl::PresaveGeneratedPassword(const PasswordForm& generated) { + auto form = std::make_unique<PasswordForm>(generated); + SanitizeFormData(&form->form_data); if (presaved_) - store_->UpdateLoginWithPrimaryKey(generated, *presaved_); + store_->UpdateLoginWithPrimaryKey(*form, *presaved_); else - store_->AddLogin(generated); - presaved_.reset(new PasswordForm(generated)); + store_->AddLogin(*form); + presaved_ = std::move(form); } void FormSaverImpl::RemovePresavedPassword() { @@ -72,7 +96,7 @@ auto result = std::make_unique<FormSaverImpl>(store_); if (presaved_) result->presaved_ = std::make_unique<PasswordForm>(*presaved_); - return std::move(result); + return result; } void FormSaverImpl::SaveImpl( @@ -85,18 +109,20 @@ DCHECK(!pending.blacklisted_by_user); UpdatePreferredLoginState(pending.username_value, best_matches); + PasswordForm sanitized_pending(pending); + SanitizeFormData(&sanitized_pending.form_data); if (presaved_) { - store_->UpdateLoginWithPrimaryKey(pending, *presaved_); + store_->UpdateLoginWithPrimaryKey(sanitized_pending, *presaved_); presaved_ = nullptr; } else if (is_new_login) { - store_->AddLogin(pending); - if (!pending.username_value.empty()) - DeleteEmptyUsernameCredentials(pending, best_matches); + store_->AddLogin(sanitized_pending); + if (!sanitized_pending.username_value.empty()) + DeleteEmptyUsernameCredentials(sanitized_pending, best_matches); } else { if (old_primary_key) - store_->UpdateLoginWithPrimaryKey(pending, *old_primary_key); + store_->UpdateLoginWithPrimaryKey(sanitized_pending, *old_primary_key); else - store_->UpdateLogin(pending); + store_->UpdateLogin(sanitized_pending); } if (credentials_to_update) { @@ -115,6 +141,7 @@ form.username_value != preferred_username) { // This wasn't the selected login but it used to be preferred. PasswordForm update(form); + SanitizeFormData(&update.form_data); update.preferred = false; store_->UpdateLogin(update); }
diff --git a/components/password_manager/core/browser/form_saver_impl_unittest.cc b/components/password_manager/core/browser/form_saver_impl_unittest.cc index 9bccc89..758c90b3 100644 --- a/components/password_manager/core/browser/form_saver_impl_unittest.cc +++ b/components/password_manager/core/browser/form_saver_impl_unittest.cc
@@ -20,6 +20,7 @@ #include "testing/gtest/include/gtest/gtest.h" #include "url/gurl.h" +using autofill::FormFieldData; using autofill::PasswordForm; using base::ASCIIToUTF16; using base::StringPiece; @@ -530,4 +531,37 @@ clone->PresaveGeneratedPassword(generated); } +// Check that on saving the pending form |form_data| is sanitized. +TEST_F(FormSaverImplTest, FormDataSanitized) { + PasswordForm pending = CreatePending("nameofuser", "wordToP4a55"); + FormFieldData field; + field.name = ASCIIToUTF16("name"); + field.form_control_type = "password"; + field.value = ASCIIToUTF16("value"); + field.label = ASCIIToUTF16("label"); + field.placeholder = ASCIIToUTF16("placeholder"); + field.id = ASCIIToUTF16("id"); + field.css_classes = ASCIIToUTF16("css_classes"); + pending.form_data.fields.push_back(field); + + for (bool presave : {false, true}) { + PasswordForm saved; + EXPECT_CALL(*mock_store_, AddLogin(_)).WillOnce(SaveArg<0>(&saved)); + if (presave) + form_saver_.PresaveGeneratedPassword(pending); + else + form_saver_.Save(pending, {}); + + ASSERT_EQ(1u, saved.form_data.fields.size()); + const FormFieldData& saved_field = saved.form_data.fields[0]; + EXPECT_EQ(ASCIIToUTF16("name"), saved_field.name); + EXPECT_EQ("password", saved_field.form_control_type); + EXPECT_TRUE(saved_field.value.empty()); + EXPECT_TRUE(saved_field.label.empty()); + EXPECT_TRUE(saved_field.placeholder.empty()); + EXPECT_TRUE(saved_field.id.empty()); + EXPECT_TRUE(saved_field.css_classes.empty()); + } +} + } // namespace password_manager
diff --git a/components/password_manager/core/browser/http_credentials_cleaner.cc b/components/password_manager/core/browser/http_credentials_cleaner.cc index 072d27c..0119b85 100644 --- a/components/password_manager/core/browser/http_credentials_cleaner.cc +++ b/components/password_manager/core/browser/http_credentials_cleaner.cc
@@ -16,11 +16,17 @@ network_context_getter) : store_(std::move(store)), network_context_getter_(network_context_getter) { - store_->GetAutofillableLogins(this); } HttpCredentialCleaner::~HttpCredentialCleaner() = default; +void HttpCredentialCleaner::StartCleaning(Observer* observer) { + DCHECK(observer); + DCHECK(!observer_); + observer_ = observer; + store_->GetAutofillableLogins(this); +} + void HttpCredentialCleaner::OnGetPasswordStoreResults( std::vector<std::unique_ptr<autofill::PasswordForm>> results) { // Non HTTP or HTTPS credentials are ignored. @@ -103,7 +109,7 @@ https_credential_not_found_[is_hsts_enabled]); } - delete this; + observer_->CleaningCompleted(); } } // namespace password_manager \ No newline at end of file
diff --git a/components/password_manager/core/browser/http_credentials_cleaner.h b/components/password_manager/core/browser/http_credentials_cleaner.h index 42a0767..ec01e306 100644 --- a/components/password_manager/core/browser/http_credentials_cleaner.h +++ b/components/password_manager/core/browser/http_credentials_cleaner.h
@@ -15,6 +15,7 @@ #include "base/containers/flat_set.h" #include "base/memory/ref_counted.h" #include "components/autofill/core/common/password_form.h" +#include "components/password_manager/core/browser/credentials_cleaner.h" #include "components/password_manager/core/browser/hsts_query.h" #include "components/password_manager/core/browser/password_store_consumer.h" @@ -29,14 +30,20 @@ class PasswordStore; // This class is responsible for reporting metrics about HTTP to HTTPS -// migration. Important note: The object will delete itself once metrics are -// reported. Having a private destructor enforces this. -class HttpCredentialCleaner : public PasswordStoreConsumer { +// migration. +class HttpCredentialCleaner : public PasswordStoreConsumer, + public CredentialsCleaner { public: + // |network_context_getter| should return nullptr if it can't get the network + // context because whatever owns it is dead. HttpCredentialCleaner( scoped_refptr<PasswordStore> store, base::RepeatingCallback<network::mojom::NetworkContext*()> network_context_getter); + ~HttpCredentialCleaner() override; + + // CredentialsCleaner: + void StartCleaning(Observer* observer) override; private: // This type define a subset of PasswordForm where first argument is the @@ -46,8 +53,6 @@ using FormKey = std::tuple<std::string, autofill::PasswordForm::Scheme, base::string16>; - ~HttpCredentialCleaner() override; - // PasswordStoreConsumer: void OnGetPasswordStoreResults( std::vector<std::unique_ptr<autofill::PasswordForm>> results) override; @@ -56,6 +61,8 @@ base::string16 password_value, HSTSResult hsts_result); + // After metrics are reported, this function will inform the |observer_| about + // completion. void ReportMetrics(); scoped_refptr<PasswordStore> store_; @@ -68,6 +75,10 @@ // tuples of HTTPS forms to a list of passwords for that pair. std::map<FormKey, base::flat_set<base::string16>> https_credentials_map_; + // Used to signal completion of the clean-up. It is null until + // StartCleaning is called. + Observer* observer_ = nullptr; + // The number of HTTP credentials processed after HSTS query results are // received. size_t processed_results_ = 0;
diff --git a/components/password_manager/core/browser/http_credentials_cleaner_unittest.cc b/components/password_manager/core/browser/http_credentials_cleaner_unittest.cc index 571e3ed..1720124 100644 --- a/components/password_manager/core/browser/http_credentials_cleaner_unittest.cc +++ b/components/password_manager/core/browser/http_credentials_cleaner_unittest.cc
@@ -10,10 +10,13 @@ #include "base/test/bind_test_util.h" #include "base/test/metrics/histogram_tester.h" #include "base/test/scoped_task_environment.h" -#include "components/password_manager/core/browser/password_manager_util.h" #include "components/password_manager/core/browser/test_password_store.h" +#include "components/password_manager/core/common/password_manager_pref_names.h" +#include "components/prefs/pref_registry_simple.h" +#include "components/prefs/testing_pref_service.h" #include "net/url_request/url_request_test_util.h" #include "services/network/network_context.h" +#include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "url/gurl.h" @@ -90,6 +93,16 @@ } // namespace +class MockCredentialsCleanerObserver : public CredentialsCleaner::Observer { + public: + MockCredentialsCleanerObserver() = default; + ~MockCredentialsCleanerObserver() override = default; + MOCK_METHOD0(CleaningCompleted, void()); + + private: + DISALLOW_COPY_AND_ASSIGN(MockCredentialsCleanerObserver); +}; + class HttpCredentialCleanerTest : public ::testing::TestWithParam<TestCase> { public: HttpCredentialCleanerTest() = default; @@ -167,12 +180,10 @@ } scoped_task_environment.RunUntilIdle(); - const TestPasswordStore::PasswordMap passwords_before_cleaning = - store_->stored_passwords(); - base::HistogramTester histogram_tester; - password_manager_util::ReportHttpMigrationMetrics( + MockCredentialsCleanerObserver observer; + HttpCredentialCleaner cleaner( store_, base::BindLambdaForTesting([&]() -> network::mojom::NetworkContext* { // This needs to be network_context_pipe.get() and @@ -183,6 +194,8 @@ // even in the in-process case. return network_context_pipe.get(); })); + EXPECT_CALL(observer, CleaningCompleted); + cleaner.StartCleaning(&observer); scoped_task_environment.RunUntilIdle(); std::vector<Histogram> histograms_to_test;
diff --git a/components/password_manager/core/browser/invalid_realm_credential_cleaner_unittest.cc b/components/password_manager/core/browser/invalid_realm_credential_cleaner_unittest.cc index 620f0762..2143c26 100644 --- a/components/password_manager/core/browser/invalid_realm_credential_cleaner_unittest.cc +++ b/components/password_manager/core/browser/invalid_realm_credential_cleaner_unittest.cc
@@ -4,6 +4,7 @@ #include "components/password_manager/core/browser/invalid_realm_credential_cleaner.h" +#include "base/bind_helpers.h" #include "base/stl_util.h" #include "base/strings/utf_string_conversions.h" #include "base/test/scoped_task_environment.h" @@ -53,6 +54,11 @@ const base::string16 kUsernames[] = {base::ASCIIToUTF16("user0"), base::ASCIIToUTF16("user1")}; +// TODO(http://crbug.com/889983): This callback is needed to be passed to +// function that does the clean-up, but is not used. Remove it once the function +// is skipped. +auto null_callback = base::NullCallback(); + bool StoreContains(TestPasswordStore* store, const autofill::PasswordForm& form) { const auto it = store->stored_passwords().find(form.signon_realm); @@ -212,7 +218,8 @@ prefs.registry()->RegisterBooleanPref( prefs::kCredentialsWithWrongSignonRealmRemoved, false); - password_manager_util::RemoveUselessCredentials(password_store, &prefs, 0); + password_manager_util::RemoveUselessCredentials(password_store, &prefs, 0, + null_callback); scoped_task_environment.RunUntilIdle(); EXPECT_EQ(StoreContains(password_store.get(), https_form), @@ -351,7 +358,8 @@ prefs.registry()->RegisterBooleanPref( prefs::kCredentialsWithWrongSignonRealmRemoved, false); - password_manager_util::RemoveUselessCredentials(password_store, &prefs, 0); + password_manager_util::RemoveUselessCredentials(password_store, &prefs, 0, + null_callback); scoped_task_environment.RunUntilIdle(); EXPECT_NE(StoreContains(password_store.get(), https_form), @@ -390,7 +398,8 @@ prefs.registry()->RegisterBooleanPref( prefs::kCredentialsWithWrongSignonRealmRemoved, false); - password_manager_util::RemoveUselessCredentials(password_store, &prefs, 0); + password_manager_util::RemoveUselessCredentials(password_store, &prefs, 0, + null_callback); scoped_task_environment.RunUntilIdle(); // Check that credentials were not deleted.
diff --git a/components/password_manager/core/browser/mock_password_store.cc b/components/password_manager/core/browser/mock_password_store.cc index 8279307..c88b29a 100644 --- a/components/password_manager/core/browser/mock_password_store.cc +++ b/components/password_manager/core/browser/mock_password_store.cc
@@ -18,7 +18,9 @@ return base::SequencedTaskRunnerHandle::Get(); } -void MockPasswordStore::InitOnBackgroundSequence( - const syncer::SyncableService::StartSyncFlare& flare) {} +bool MockPasswordStore::InitOnBackgroundSequence( + const syncer::SyncableService::StartSyncFlare& flare) { + return true; +} } // namespace password_manager
diff --git a/components/password_manager/core/browser/mock_password_store.h b/components/password_manager/core/browser/mock_password_store.h index b8c714a..f2aca6a 100644 --- a/components/password_manager/core/browser/mock_password_store.h +++ b/components/password_manager/core/browser/mock_password_store.h
@@ -97,7 +97,7 @@ // PasswordStore: scoped_refptr<base::SequencedTaskRunner> CreateBackgroundTaskRunner() const override; - void InitOnBackgroundSequence( + bool InitOnBackgroundSequence( const syncer::SyncableService::StartSyncFlare& flare) override; };
diff --git a/components/password_manager/core/browser/password_manager_unittest.cc b/components/password_manager/core/browser/password_manager_unittest.cc index 698592a..580dd97 100644 --- a/components/password_manager/core/browser/password_manager_unittest.cc +++ b/components/password_manager/core/browser/password_manager_unittest.cc
@@ -19,6 +19,8 @@ #include "base/test/scoped_feature_list.h" #include "base/test/test_mock_time_task_runner.h" #include "build/build_config.h" +#include "components/autofill/core/common/form_data.h" +#include "components/autofill/core/common/form_field_data.h" #include "components/password_manager/core/browser/form_fetcher_impl.h" #include "components/password_manager/core/browser/mock_password_store.h" #include "components/password_manager/core/browser/new_password_form_manager.h" @@ -39,6 +41,8 @@ #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +using autofill::FormData; +using autofill::FormFieldData; using autofill::PasswordForm; using base::ASCIIToUTF16; using base::TestMockTimeTaskRunner; @@ -149,6 +153,20 @@ ACTION_P(SaveToScopedPtr, scoped) { scoped->reset(arg0); } +void SanitizeFormData(FormData* form) { + form->main_frame_origin = url::Origin(); + for (FormFieldData& field : form->fields) { + field.label.clear(); + field.value.clear(); + field.autocomplete_attribute.clear(); + field.option_values.clear(); + field.option_contents.clear(); + field.placeholder.clear(); + field.css_classes.clear(); + field.id.clear(); + } +} + } // namespace class PasswordManagerTest : public testing::Test { @@ -1781,20 +1799,26 @@ // The user accepts a generated password. form.password_value = base::ASCIIToUTF16("password"); - EXPECT_CALL(*store_, AddLogin(form)).WillOnce(Return()); + PasswordForm sanitized_form(form); + SanitizeFormData(&sanitized_form.form_data); + + EXPECT_CALL(*store_, AddLogin(sanitized_form)).WillOnce(Return()); manager()->OnPresaveGeneratedPassword(form); // The user updates the generated password. PasswordForm updated_form(form); updated_form.password_value = base::ASCIIToUTF16("password_12345"); - EXPECT_CALL(*store_, UpdateLoginWithPrimaryKey(updated_form, form)) + PasswordForm sanitized_updated_form(updated_form); + SanitizeFormData(&sanitized_updated_form.form_data); + EXPECT_CALL(*store_, + UpdateLoginWithPrimaryKey(sanitized_updated_form, sanitized_form)) .WillOnce(Return()); manager()->OnPresaveGeneratedPassword(updated_form); histogram_tester.ExpectUniqueSample( "PasswordManager.GeneratedFormHasNoFormManager", false, 2); // The user removes the generated password. - EXPECT_CALL(*store_, RemoveLogin(updated_form)).WillOnce(Return()); + EXPECT_CALL(*store_, RemoveLogin(sanitized_updated_form)).WillOnce(Return()); manager()->OnPasswordNoLongerGenerated(updated_form); } @@ -1830,6 +1854,7 @@ SCOPED_TRACE(testing::Message("found_matched_logins_in_store = ") << found_matched_logins_in_store); PasswordForm form(MakeFormWithOnlyNewPasswordField()); + SanitizeFormData(&form.form_data); std::vector<PasswordForm> observed = {form}; if (found_matched_logins_in_store) { EXPECT_CALL(*store_, GetLogins(_, _))
diff --git a/components/password_manager/core/browser/password_manager_util.cc b/components/password_manager/core/browser/password_manager_util.cc index c0511d16..49314ba 100644 --- a/components/password_manager/core/browser/password_manager_util.cc +++ b/components/password_manager/core/browser/password_manager_util.cc
@@ -48,17 +48,6 @@ } // namespace -#if !defined(OS_IOS) -void ReportHttpMigrationMetrics( - scoped_refptr<password_manager::PasswordStore> store, - base::RepeatingCallback<network::mojom::NetworkContext*()> - network_context_getter) { - // The object will delete itself once the metrics are recorded. - new password_manager::HttpCredentialCleaner(std::move(store), - network_context_getter); -} -#endif // !defined(OS_IOS) - // Update |credential| to reflect usage. void UpdateMetadataForUsage(PasswordForm* credential) { ++credential->times_used; @@ -200,7 +189,9 @@ void RemoveUselessCredentials( scoped_refptr<password_manager::PasswordStore> store, PrefService* prefs, - int delay_in_seconds) { + int delay_in_seconds, + base::RepeatingCallback<network::mojom::NetworkContext*()> + network_context_getter) { // TODO(https://crbug.com/887889): Remove the knowledge of the particular // preferences from this code. @@ -236,6 +227,15 @@ store, prefs)); } +#if !defined(OS_IOS) + // Can be null for some unittests. + if (!network_context_getter.is_null()) { + cleaning_tasks_runner->AddCleaningTask( + std::make_unique<password_manager::HttpCredentialCleaner>( + store, network_context_getter)); + } +#endif // !defined(OS_IOS) + base::SequencedTaskRunnerHandle::Get()->PostDelayedTask( FROM_HERE, base::BindOnce(&password_manager::CredentialsCleanerRunner::StartCleaning,
diff --git a/components/password_manager/core/browser/password_manager_util.h b/components/password_manager/core/browser/password_manager_util.h index a855bab..e6b75d65 100644 --- a/components/password_manager/core/browser/password_manager_util.h +++ b/components/password_manager/core/browser/password_manager_util.h
@@ -100,10 +100,16 @@ // hence blacklisted duplicates need to be removed. // (2) Removing or fixing of HTTPS credentials with wrong signon_realm. See // https://crbug.com/881731 for details. +// (3) Report metrics about HTTP to HTTPS migration process. This feature +// is not available on iOS platform because the HSTS query is not supported. +// |network_context_getter| is always null for iOS and it can also be null for +// some unittests. void RemoveUselessCredentials( scoped_refptr<password_manager::PasswordStore> store, PrefService* prefs, - int delay_in_seconds); + int delay_in_seconds, + base::RepeatingCallback<network::mojom::NetworkContext*()> + network_context_getter); // Excluding protocol from a signon_realm means to remove from the signon_realm // what is before the web origin (with the protocol excluded as well). For @@ -113,15 +119,6 @@ base::StringPiece GetSignonRealmWithProtocolExcluded( const autofill::PasswordForm& form); -// Report metrics about HTTP to HTTPS migration process. This function cannot be -// used on iOS platform because the HSTS query is not supported. -// |network_context_getter| should return nullptr if it can't get the network -// context because whatever owns it is dead. -void ReportHttpMigrationMetrics( - scoped_refptr<password_manager::PasswordStore> store, - base::RepeatingCallback<network::mojom::NetworkContext*()> - network_context_getter); - // Given all non-blacklisted |matches|, finds and populates // |best_matches_|, |preferred_match_| and |non_best_matches_| accordingly. // For comparing credentials the following rule is used: non-psl match is better
diff --git a/components/password_manager/core/browser/password_manager_util_unittest.cc b/components/password_manager/core/browser/password_manager_util_unittest.cc index 1577721..d6a7c3e 100644 --- a/components/password_manager/core/browser/password_manager_util_unittest.cc +++ b/components/password_manager/core/browser/password_manager_util_unittest.cc
@@ -9,6 +9,7 @@ #include <utility> #include <vector> +#include "base/bind_helpers.h" #include "base/macros.h" #include "base/stl_util.h" #include "base/strings/utf_string_conversions.h" @@ -176,7 +177,7 @@ password_manager::prefs::kCredentialsWithWrongSignonRealmRemoved, false); - RemoveUselessCredentials(password_store, &prefs, 0); + RemoveUselessCredentials(password_store, &prefs, 0, base::NullCallback()); scoped_task_environment.RunUntilIdle(); // Check that invalid credentials were removed. @@ -191,7 +192,7 @@ EXPECT_NE(StoreContains(password_store.get(), https_blacklisted), StoreContains(password_store.get(), https_blacklisted_duplicate)); - RemoveUselessCredentials(password_store, &prefs, 0); + RemoveUselessCredentials(password_store, &prefs, 0, base::NullCallback()); scoped_task_environment.RunUntilIdle(); // Nothing must be removed by a second call.
diff --git a/components/password_manager/core/browser/password_store.cc b/components/password_manager/core/browser/password_store.cc index e543a24..69d3a8c 100644 --- a/components/password_manager/core/browser/password_store.cc +++ b/components/password_manager/core/browser/password_store.cc
@@ -15,6 +15,7 @@ #include "base/metrics/histogram_macros.h" #include "base/stl_util.h" #include "base/task/post_task.h" +#include "base/task_runner_util.h" #include "base/threading/sequenced_task_runner_handle.h" #include "build/build_config.h" #include "components/autofill/core/common/form_data.h" @@ -122,7 +123,8 @@ PasswordStore::PasswordStore() : observers_(new base::ObserverListThreadSafe<Observer>()), is_propagating_password_changes_to_web_credentials_enabled_(false), - shutdown_called_(false) {} + shutdown_called_(false), + init_status_(InitStatus::kUnknown) {} bool PasswordStore::Init(const syncer::SyncableService::StartSyncFlare& flare, PrefService* prefs) { @@ -134,8 +136,12 @@ prefs_ = prefs; hash_password_manager_.set_prefs(prefs); #endif - ScheduleTask(base::BindRepeating(&PasswordStore::InitOnBackgroundSequence, - this, flare)); + if (background_task_runner_) { + base::PostTaskAndReplyWithResult( + background_task_runner_.get(), FROM_HERE, + base::BindOnce(&PasswordStore::InitOnBackgroundSequence, this, flare), + base::BindOnce(&PasswordStore::OnInitCompleted, this)); + } return true; } @@ -331,6 +337,10 @@ return false; } +bool PasswordStore::IsAbleToSavePasswords() const { + return init_status_ == InitStatus::kSuccess; +} + void PasswordStore::ShutdownOnUIThread() { ScheduleTask(base::Bind(&PasswordStore::DestroyOnBackgroundSequence, this)); // The AffiliationService must be destroyed from the main sequence. @@ -468,7 +478,7 @@ {base::MayBlock(), base::TaskPriority::USER_VISIBLE}); } -void PasswordStore::InitOnBackgroundSequence( +bool PasswordStore::InitOnBackgroundSequence( const syncer::SyncableService::StartSyncFlare& flare) { DCHECK(background_task_runner_->RunsTasksInCurrentSequence()); DCHECK(!syncable_service_); @@ -480,6 +490,7 @@ GetAutofillableLoginsImpl( std::make_unique<GetLoginsRequest>(reuse_detector_)); #endif + return true; } void PasswordStore::GetLoginsImpl(const FormDigest& form, @@ -604,6 +615,12 @@ } #endif +void PasswordStore::OnInitCompleted(bool success) { + DCHECK(main_task_runner_->RunsTasksInCurrentSequence()); + init_status_ = success ? InitStatus::kSuccess : InitStatus::kFailure; + // TODO(tsabolcec): Add UMA histogram to record the success rate. +} + void PasswordStore::Schedule( void (PasswordStore::*func)(std::unique_ptr<GetLoginsRequest>), PasswordStoreConsumer* consumer) {
diff --git a/components/password_manager/core/browser/password_store.h b/components/password_manager/core/browser/password_store.h index 8c17f18..f91e40d 100644 --- a/components/password_manager/core/browser/password_store.h +++ b/components/password_manager/core/browser/password_store.h
@@ -252,6 +252,9 @@ // Schedules the given |task| to be run on the PasswordStore's TaskRunner. bool ScheduleTask(const base::Closure& task); + // Returns true iff initialization was successful. + bool IsAbleToSavePasswords() const; + base::WeakPtr<syncer::SyncableService> GetPasswordSyncableService(); // TODO(crbug.com/706392): Fix password reuse detection for Android. @@ -369,6 +372,19 @@ }; #endif + // Status of PasswordStore::Init(). + enum class InitStatus { + // Initialization status is still not determined (init hasn't started or + // finished yet). + kUnknown, + // Initialization is successfully finished. + kSuccess, + // There was an error during initialization and PasswordStore is not ready + // to save or get passwords. + // Removing passwords may still work. + kFailure, + }; + ~PasswordStore() override; // Create a TaskRunner to be saved in |background_task_runner_|. @@ -376,8 +392,9 @@ const; // Creates PasswordSyncableService and PasswordReuseDetector instances on the - // background sequence. Subclasses can add more logic. - virtual void InitOnBackgroundSequence( + // background sequence. Subclasses can add more logic. Returns true on + // success. + virtual bool InitOnBackgroundSequence( const syncer::SyncableService::StartSyncFlare& flare); // Methods below will be run in PasswordStore's own sequence. @@ -521,6 +538,11 @@ FRIEND_TEST_ALL_PREFIXES(PasswordStoreTest, UpdatePasswordsStoredForAffiliatedWebsites); + // Called on the main thread after initialization is completed. + // |success| is true if initialization was successful. Sets the + // |init_status_|. + void OnInitCompleted(bool success); + // Schedule the given |func| to be run in the PasswordStore's own sequence // with responses delivered to |consumer| on the current sequence. void Schedule(void (PasswordStore::*func)(std::unique_ptr<GetLoginsRequest>), @@ -676,6 +698,8 @@ bool shutdown_called_; + InitStatus init_status_; + DISALLOW_COPY_AND_ASSIGN(PasswordStore); };
diff --git a/components/password_manager/core/browser/password_store_default.cc b/components/password_manager/core/browser/password_store_default.cc index 18a548e..a3be1aa2 100644 --- a/components/password_manager/core/browser/password_store_default.cc +++ b/components/password_manager/core/browser/password_store_default.cc
@@ -28,15 +28,19 @@ ScheduleTask(base::Bind(&PasswordStoreDefault::ResetLoginDB, this)); } -void PasswordStoreDefault::InitOnBackgroundSequence( +bool PasswordStoreDefault::InitOnBackgroundSequence( const syncer::SyncableService::StartSyncFlare& flare) { DCHECK(background_task_runner()->RunsTasksInCurrentSequence()); DCHECK(login_db_); + bool success = true; if (!login_db_->Init()) { login_db_.reset(); + // The initialization should be continued, because PasswordSyncableService + // has to be initialized even if database initialization failed. + success = false; LOG(ERROR) << "Could not create/open login database."; } - PasswordStore::InitOnBackgroundSequence(flare); + return PasswordStore::InitOnBackgroundSequence(flare) && success; } void PasswordStoreDefault::ReportMetricsImpl(
diff --git a/components/password_manager/core/browser/password_store_default.h b/components/password_manager/core/browser/password_store_default.h index 3a203da1..c80e3dd 100644 --- a/components/password_manager/core/browser/password_store_default.h +++ b/components/password_manager/core/browser/password_store_default.h
@@ -41,7 +41,7 @@ ~PasswordStoreDefault() override; // Opens |login_db_| on the background sequence. - void InitOnBackgroundSequence( + bool InitOnBackgroundSequence( const syncer::SyncableService::StartSyncFlare& flare) override; // Implements PasswordStore interface.
diff --git a/components/sync/BUILD.gn b/components/sync/BUILD.gn index e9a0a060..1ed14318 100644 --- a/components/sync/BUILD.gn +++ b/components/sync/BUILD.gn
@@ -157,6 +157,8 @@ "driver/sync_type_preference_provider.h", "driver/sync_util.cc", "driver/sync_util.h", + "driver/syncable_service_based_model_type_controller.cc", + "driver/syncable_service_based_model_type_controller.h", "driver/user_selectable_sync_type.h", "engine/commit_queue.cc", "engine/commit_queue.h", @@ -450,6 +452,8 @@ "model_impl/proxy_model_type_controller_delegate.h", "model_impl/sync_metadata_store_change_list.cc", "model_impl/sync_metadata_store_change_list.h", + "model_impl/syncable_service_based_bridge.cc", + "model_impl/syncable_service_based_bridge.h", "protocol/proto_enum_conversions.cc", "protocol/proto_enum_conversions.h", "protocol/proto_memory_estimations.cc", @@ -902,6 +906,7 @@ "model_impl/model_type_store_backend_unittest.cc", "model_impl/model_type_store_impl_unittest.cc", "model_impl/processor_entity_tracker_unittest.cc", + "model_impl/syncable_service_based_bridge_unittest.cc", "protocol/proto_enum_conversions_unittest.cc", "protocol/proto_value_conversions_unittest.cc", "syncable/change_record_unittest.cc",
diff --git a/components/sync/driver/sync_driver_switches.cc b/components/sync/driver/sync_driver_switches.cc index 42a1429..020aa1b 100644 --- a/components/sync/driver/sync_driver_switches.cc +++ b/components/sync/driver/sync_driver_switches.cc
@@ -46,6 +46,25 @@ const base::Feature kSyncClearDataOnPassphraseEncryption{ "ClearSyncDataOnPassphraseEncryption", base::FEATURE_DISABLED_BY_DEFAULT}; +// For each below, if enabled, the SyncableService implementation of the +// corresponding datatype(s) is wrapped within the USS architecture. +const base::Feature kSyncPseudoUSSAppList{"SyncPseudoUSSAppList", + base::FEATURE_DISABLED_BY_DEFAULT}; +const base::Feature kSyncPseudoUSSApps{"SyncPseudoUSSApps", + base::FEATURE_DISABLED_BY_DEFAULT}; +const base::Feature kSyncPseudoUSSDictionary{"SyncPseudoUSSDictionary", + base::FEATURE_DISABLED_BY_DEFAULT}; +const base::Feature kSyncPseudoUSSExtensions{"SyncPseudoUSSExtensions", + base::FEATURE_DISABLED_BY_DEFAULT}; +const base::Feature kSyncPseudoUSSFavicons{"SyncPseudoUSSFavicons", + base::FEATURE_DISABLED_BY_DEFAULT}; +const base::Feature kSyncPseudoUSSPreferences{ + "SyncPseudoUSSPreferences", base::FEATURE_DISABLED_BY_DEFAULT}; +const base::Feature kSyncPseudoUSSPriorityPreferences{ + "SyncPseudoUSSPriorityPreferences", base::FEATURE_DISABLED_BY_DEFAULT}; +const base::Feature kSyncPseudoUSSThemes{"SyncPseudoUSSThemes", + base::FEATURE_DISABLED_BY_DEFAULT}; + // If enabled, allows the Sync machinery ("transport layer") to start // independently of Sync-the-feature. const base::Feature kSyncStandaloneTransport{"SyncStandaloneTransport",
diff --git a/components/sync/driver/sync_driver_switches.h b/components/sync/driver/sync_driver_switches.h index f964a78..00b6099a 100644 --- a/components/sync/driver/sync_driver_switches.h +++ b/components/sync/driver/sync_driver_switches.h
@@ -23,6 +23,14 @@ extern const base::Feature kSyncAllowWalletDataInTransportModeWithCustomPassphrase; extern const base::Feature kSyncClearDataOnPassphraseEncryption; +extern const base::Feature kSyncPseudoUSSAppList; +extern const base::Feature kSyncPseudoUSSApps; +extern const base::Feature kSyncPseudoUSSDictionary; +extern const base::Feature kSyncPseudoUSSExtensions; +extern const base::Feature kSyncPseudoUSSFavicons; +extern const base::Feature kSyncPseudoUSSPreferences; +extern const base::Feature kSyncPseudoUSSPriorityPreferences; +extern const base::Feature kSyncPseudoUSSThemes; extern const base::Feature kSyncStandaloneTransport; extern const base::Feature kSyncSupportSecondaryAccount; extern const base::Feature kSyncUserEvents;
diff --git a/components/sync/driver/syncable_service_based_model_type_controller.cc b/components/sync/driver/syncable_service_based_model_type_controller.cc new file mode 100644 index 0000000..6d1ca9e --- /dev/null +++ b/components/sync/driver/syncable_service_based_model_type_controller.cc
@@ -0,0 +1,98 @@ +// 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 "components/sync/driver/syncable_service_based_model_type_controller.h" + +#include <utility> + +#include "components/sync/model_impl/client_tag_based_model_type_processor.h" +#include "components/sync/model_impl/forwarding_model_type_controller_delegate.h" +#include "components/sync/model_impl/syncable_service_based_bridge.h" + +namespace syncer { + +namespace { + +// Similar to ForwardingModelTypeControllerDelegate, but allows evaluating the +// reference to SyncableService in a lazy way, which is convenient for tests. +class ControllerDelegate : public ModelTypeControllerDelegate { + public: + using SyncableServiceProvider = + SyncableServiceBasedModelTypeController::SyncableServiceProvider; + + ControllerDelegate(ModelType type, + OnceModelTypeStoreFactory store_factory, + SyncableServiceProvider syncable_service_provider) + : type_(type), + store_factory_(std::move(store_factory)), + syncable_service_provider_(std::move(syncable_service_provider)) { + DCHECK(store_factory_); + DCHECK(syncable_service_provider_); + } + + ~ControllerDelegate() override {} + + void OnSyncStarting(const DataTypeActivationRequest& request, + StartCallback callback) override { + BuildOrGetBridgeDelegate()->OnSyncStarting(request, std::move(callback)); + } + + void OnSyncStopping(SyncStopMetadataFate metadata_fate) override { + BuildOrGetBridgeDelegate()->OnSyncStopping(metadata_fate); + } + + void GetAllNodesForDebugging(AllNodesCallback callback) override { + BuildOrGetBridgeDelegate()->GetAllNodesForDebugging(std::move(callback)); + } + + void GetStatusCountersForDebugging(StatusCountersCallback callback) override { + BuildOrGetBridgeDelegate()->GetStatusCountersForDebugging( + std::move(callback)); + } + + void RecordMemoryUsageAndCountsHistograms() override { + BuildOrGetBridgeDelegate()->RecordMemoryUsageAndCountsHistograms(); + } + + private: + ModelTypeControllerDelegate* BuildOrGetBridgeDelegate() { + if (!bridge_) { + base::WeakPtr<SyncableService> syncable_service = + std::move(syncable_service_provider_).Run(); + DCHECK(syncable_service); + bridge_ = std::make_unique<SyncableServiceBasedBridge>( + type_, std::move(store_factory_), + std::make_unique<ClientTagBasedModelTypeProcessor>( + type_, + /*dump_stack=*/base::RepeatingClosure()), + syncable_service.get()); + } + return bridge_->change_processor()->GetControllerDelegate().get(); + } + + const ModelType type_; + OnceModelTypeStoreFactory store_factory_; + SyncableServiceProvider syncable_service_provider_; + std::unique_ptr<ModelTypeSyncBridge> bridge_; + + DISALLOW_COPY_AND_ASSIGN(ControllerDelegate); +}; + +} // namespace + +SyncableServiceBasedModelTypeController:: + SyncableServiceBasedModelTypeController( + ModelType type, + OnceModelTypeStoreFactory store_factory, + SyncableServiceProvider syncable_service_provider) + : ModelTypeController(type, + std::make_unique<ControllerDelegate>( + type, + std::move(store_factory), + std::move(syncable_service_provider))) {} + +SyncableServiceBasedModelTypeController:: + ~SyncableServiceBasedModelTypeController() {} + +} // namespace syncer
diff --git a/components/sync/driver/syncable_service_based_model_type_controller.h b/components/sync/driver/syncable_service_based_model_type_controller.h new file mode 100644 index 0000000..bdc38fd --- /dev/null +++ b/components/sync/driver/syncable_service_based_model_type_controller.h
@@ -0,0 +1,40 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_SYNC_DRIVER_SYNCABLE_SERVICE_BASED_MODEL_TYPE_CONTROLLER_H_ +#define COMPONENTS_SYNC_DRIVER_SYNCABLE_SERVICE_BASED_MODEL_TYPE_CONTROLLER_H_ + +#include <memory> + +#include "base/callback_forward.h" +#include "base/macros.h" +#include "base/memory/weak_ptr.h" +#include "components/sync/base/model_type.h" +#include "components/sync/driver/model_type_controller.h" +#include "components/sync/model/model_type_store.h" + +namespace syncer { + +class SyncableService; + +// Controller responsible for integrating SyncableService implementations within +// a non-blocking datatype (USS). +class SyncableServiceBasedModelTypeController : public ModelTypeController { + public: + using SyncableServiceProvider = + base::OnceCallback<base::WeakPtr<syncer::SyncableService>()>; + + SyncableServiceBasedModelTypeController( + ModelType type, + OnceModelTypeStoreFactory store_factory, + SyncableServiceProvider syncable_service_provider); + ~SyncableServiceBasedModelTypeController() override; + + private: + DISALLOW_COPY_AND_ASSIGN(SyncableServiceBasedModelTypeController); +}; + +} // namespace syncer + +#endif // COMPONENTS_SYNC_DRIVER_SYNCABLE_SERVICE_BASED_MODEL_TYPE_CONTROLLER_H_
diff --git a/components/sync/model/model_type_sync_bridge.h b/components/sync/model/model_type_sync_bridge.h index 411fc44..a297134 100644 --- a/components/sync/model/model_type_sync_bridge.h +++ b/components/sync/model/model_type_sync_bridge.h
@@ -108,10 +108,10 @@ // Get or generate a client tag for |entity_data|. This must be the same tag // that was/would have been generated in the SyncableService/Directory world // for backward compatibility with pre-USS clients. The only time this - // theoretically needs to be called is on the creation of local data, however - // it is also used to verify the hash of remote data. If a model type was - // never launched pre-USS, then method does not need to be different from - // GetStorageKey(). Only the hash of this value is kept. + // theoretically needs to be called is on the creation of local data. + // + // If a model type was never launched pre-USS, then method does not need to be + // different from GetStorageKey(). Only the hash of this value is kept. virtual std::string GetClientTag(const EntityData& entity_data) = 0; // Must not be called unless SupportsGetStorageKey() returns true.
diff --git a/components/sync/model_impl/client_tag_based_model_type_processor.cc b/components/sync/model_impl/client_tag_based_model_type_processor.cc index ccd425a1..e72601ba 100644 --- a/components/sync/model_impl/client_tag_based_model_type_processor.cc +++ b/components/sync/model_impl/client_tag_based_model_type_processor.cc
@@ -1169,6 +1169,8 @@ memory_usage += EstimateMemoryUsage(model_type_state_); memory_usage += EstimateMemoryUsage(entities_); memory_usage += EstimateMemoryUsage(storage_key_to_tag_hash_); + // TODO(crbug.com/870624): Let bridges provide custom additional memory + // overhead, which is important for SyncableServiceBasedBridge. return memory_usage; }
diff --git a/components/sync/model_impl/syncable_service_based_bridge.cc b/components/sync/model_impl/syncable_service_based_bridge.cc new file mode 100644 index 0000000..49590a1 --- /dev/null +++ b/components/sync/model_impl/syncable_service_based_bridge.cc
@@ -0,0 +1,593 @@ +// 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 "components/sync/model_impl/syncable_service_based_bridge.h" + +#include <stdint.h> +#include <utility> + +#include "base/bind.h" +#include "base/bind_helpers.h" +#include "base/location.h" +#include "components/sync/base/hash_util.h" +#include "components/sync/model/mutable_data_batch.h" +#include "components/sync/model/sync_change.h" +#include "components/sync/model/sync_error_factory.h" +#include "components/sync/model/syncable_service.h" +#include "components/sync/model_impl/client_tag_based_model_type_processor.h" +#include "components/sync/protocol/persisted_entity_data.pb.h" + +namespace syncer { +namespace { + +// Same as kInvalidId in syncable/base_node.h. +constexpr int64_t kInvalidNodeId = 0; + +std::unique_ptr<EntityData> ConvertPersistedToEntityData( + const std::string& client_tag_hash, + std::unique_ptr<sync_pb::PersistedEntityData> data) { + DCHECK(data); + DCHECK(!client_tag_hash.empty()); + DCHECK(!data->non_unique_name().empty()); + auto entity_data = std::make_unique<EntityData>(); + + entity_data->non_unique_name = std::move(*data->mutable_non_unique_name()); + entity_data->specifics.Swap(data->mutable_specifics()); + entity_data->client_tag_hash = client_tag_hash; + return entity_data; +} + +sync_pb::PersistedEntityData CreatePersistedFromEntityData( + const EntityData& entity_data) { + DCHECK(!entity_data.non_unique_name.empty()); + + sync_pb::PersistedEntityData persisted; + persisted.set_non_unique_name(entity_data.non_unique_name); + *persisted.mutable_specifics() = entity_data.specifics; + return persisted; +} + +std::unique_ptr<sync_pb::PersistedEntityData> CreatePersistedFromSyncData( + const SyncDataLocal& sync_data) { + DCHECK(!sync_data.GetTitle().empty()); + auto persisted = std::make_unique<sync_pb::PersistedEntityData>(); + persisted->set_non_unique_name(sync_data.GetTitle()); + *persisted->mutable_specifics() = sync_data.GetSpecifics(); + return persisted; +} + +SyncChange::SyncChangeType ConvertToSyncChangeType( + EntityChange::ChangeType type) { + switch (type) { + case EntityChange::ACTION_DELETE: + return SyncChange::ACTION_DELETE; + case EntityChange::ACTION_ADD: + return SyncChange::ACTION_ADD; + case EntityChange::ACTION_UPDATE: + return SyncChange::ACTION_UPDATE; + } + NOTREACHED(); + return SyncChange::ACTION_INVALID; +} + +base::Optional<ModelError> ConvertToModelError(const SyncError& sync_error) { + if (sync_error.IsSet()) { + return ModelError(sync_error.location(), sync_error.message()); + } + return base::nullopt; +} + +// Object to propagate local changes to the bridge, which will ultimately +// propagate them to the server. +class ChangeProcessorImpl : public SyncChangeProcessor { + public: + ChangeProcessorImpl( + ModelType type, + const base::RepeatingCallback<void(const base::Optional<ModelError>&)>& + error_callback, + ModelTypeStore* store, + std::map<std::string, sync_pb::EntitySpecifics>* in_memory_store, + ModelTypeChangeProcessor* other) + : type_(type), + error_callback_(error_callback), + store_(store), + in_memory_store_(in_memory_store), + other_(other) { + DCHECK(store); + DCHECK(other); + } + + ~ChangeProcessorImpl() override {} + + SyncError ProcessSyncChanges(const base::Location& from_here, + const SyncChangeList& change_list) override { + std::unique_ptr<ModelTypeStore::WriteBatch> batch = + store_->CreateWriteBatch(); + + for (const SyncChange& change : change_list) { + DCHECK(change.sync_data().IsLocal()) + << " from " << change.location().ToString(); + SyncDataLocal sync_data(change.sync_data()); + DCHECK(sync_data.IsValid()) << " from " << change.location().ToString(); + const std::string storage_key = + GenerateSyncableHash(type_, sync_data.GetTag()); + DCHECK(!storage_key.empty()); + + switch (change.change_type()) { + case SyncChange::ACTION_INVALID: + NOTREACHED() << " from " << change.location().ToString(); + break; + case SyncChange::ACTION_ADD: + case SyncChange::ACTION_UPDATE: { + (*in_memory_store_)[storage_key] = sync_data.GetSpecifics(); + std::unique_ptr<sync_pb::PersistedEntityData> persisted_entity = + CreatePersistedFromSyncData(sync_data); + batch->WriteData(storage_key, persisted_entity->SerializeAsString()); + other_->Put( + storage_key, + ConvertPersistedToEntityData( + /*client_tag_hash=*/storage_key, std::move(persisted_entity)), + batch->GetMetadataChangeList()); + break; + } + case SyncChange::ACTION_DELETE: + in_memory_store_->erase(storage_key); + other_->Delete(storage_key, batch->GetMetadataChangeList()); + batch->DeleteData(storage_key); + break; + } + } + + store_->CommitWriteBatch(std::move(batch), error_callback_); + + return SyncError(); + } + + SyncDataList GetAllSyncData(ModelType type) const override { + // This function is not supported and not exercised by the relevant + // datatypes (that are integrated with this bridge). + NOTREACHED(); + return SyncDataList(); + } + + SyncError UpdateDataTypeContext(ModelType type, + ContextRefreshStatus refresh_status, + const std::string& context) override { + // This function is not supported and not exercised by anyone, since + // the USS flow doesn't use SharedChangeProcessor. + // TODO(crbug.com/870624): Remove this function altogether when the + // directory codebase is removed. + NOTREACHED(); + return SyncError(); + } + + void AddLocalChangeObserver(LocalChangeObserver* observer) override { + // This function is not supported and not exercised by the relevant + // datatypes (that are integrated with this bridge). + NOTREACHED(); + } + + void RemoveLocalChangeObserver(LocalChangeObserver* observer) override { + // This function is not supported and not exercised by the relevant + // datatypes (that are integrated with this bridge). + NOTREACHED(); + } + + private: + const ModelType type_; + const base::RepeatingCallback<void(const base::Optional<ModelError>&)> + error_callback_; + ModelTypeStore* const store_; + std::map<std::string, sync_pb::EntitySpecifics>* const in_memory_store_; + ModelTypeChangeProcessor* const other_; + + DISALLOW_COPY_AND_ASSIGN(ChangeProcessorImpl); +}; + +class SyncErrorFactoryImpl : public SyncErrorFactory { + public: + explicit SyncErrorFactoryImpl(ModelType type) : type_(type) {} + ~SyncErrorFactoryImpl() override = default; + + SyncError CreateAndUploadError(const base::Location& location, + const std::string& message) override { + // Uploading is not supported, we simply return the error. + return SyncError(location, SyncError::DATATYPE_ERROR, message, type_); + } + + private: + const ModelType type_; + + DISALLOW_COPY_AND_ASSIGN(SyncErrorFactoryImpl); +}; + +} // namespace + +SyncableServiceBasedBridge::SyncableServiceBasedBridge( + ModelType type, + OnceModelTypeStoreFactory store_factory, + std::unique_ptr<ModelTypeChangeProcessor> change_processor, + SyncableService* syncable_service) + : ModelTypeSyncBridge(std::move(change_processor)), + type_(type), + syncable_service_(syncable_service), + store_factory_(std::move(store_factory)), + syncable_service_started_(false), + weak_ptr_factory_(this) { + DCHECK(store_factory_); + DCHECK(syncable_service_); +} + +SyncableServiceBasedBridge::~SyncableServiceBasedBridge() { + // Stop the syncable service to make sure instances of ChangeProcessorImpl are + // not continued to be used. + if (syncable_service_started_) { + syncable_service_->StopSyncing(type_); + } +} + +std::unique_ptr<MetadataChangeList> +SyncableServiceBasedBridge::CreateMetadataChangeList() { + return ModelTypeStore::WriteBatch::CreateMetadataChangeList(); +} + +void SyncableServiceBasedBridge::OnSyncStarting( + const DataTypeActivationRequest& request) { + DCHECK(!syncable_service_started_); + + if (!store_factory_) { + // Sync was have been started earlier, and |store_| is guaranteed to be + // initialized because stopping of the datatype cannot be completed before + // ModelReadyToSync(). + DCHECK(store_); + MaybeStartSyncableService(); + return; + } + + std::move(store_factory_) + .Run(type_, base::BindOnce(&SyncableServiceBasedBridge::OnStoreCreated, + weak_ptr_factory_.GetWeakPtr())); + DCHECK(!store_factory_); +} + +base::Optional<ModelError> SyncableServiceBasedBridge::MergeSyncData( + std::unique_ptr<MetadataChangeList> metadata_change_list, + EntityChangeList entity_change_list) { + DCHECK(store_); + DCHECK(change_processor()->IsTrackingMetadata()); + DCHECK(!syncable_service_started_); + DCHECK(in_memory_store_.empty()); + + const SyncChangeList sync_change_list = StoreAndConvertRemoteChanges( + std::move(metadata_change_list), std::move(entity_change_list)); + + SyncDataList initial_sync_data; + initial_sync_data.reserve(sync_change_list.size()); + for (const SyncChange& change : sync_change_list) { + initial_sync_data.push_back(change.sync_data()); + } + + auto error_callback = + base::BindRepeating(&SyncableServiceBasedBridge::ReportErrorIfSet, + weak_ptr_factory_.GetWeakPtr()); + auto processor_impl = std::make_unique<ChangeProcessorImpl>( + type_, error_callback, store_.get(), &in_memory_store_, + change_processor()); + + const base::Optional<ModelError> merge_error = ConvertToModelError( + syncable_service_ + ->MergeDataAndStartSyncing( + type_, initial_sync_data, std::move(processor_impl), + std::make_unique<SyncErrorFactoryImpl>(type_)) + .error()); + + if (!merge_error) { + syncable_service_started_ = true; + } + + return merge_error; +} + +base::Optional<ModelError> SyncableServiceBasedBridge::ApplySyncChanges( + std::unique_ptr<MetadataChangeList> metadata_change_list, + EntityChangeList entity_change_list) { + DCHECK(store_); + DCHECK(change_processor()->IsTrackingMetadata()); + DCHECK(syncable_service_started_); + + const SyncChangeList sync_change_list = StoreAndConvertRemoteChanges( + std::move(metadata_change_list), std::move(entity_change_list)); + + if (sync_change_list.empty()) { + return base::nullopt; + } + + return ConvertToModelError( + syncable_service_->ProcessSyncChanges(FROM_HERE, sync_change_list)); +} + +void SyncableServiceBasedBridge::GetData(StorageKeyList storage_keys, + DataCallback callback) { + DCHECK(store_); + store_->ReadData( + storage_keys, + base::BindOnce(&SyncableServiceBasedBridge::OnReadDataForProcessor, + weak_ptr_factory_.GetWeakPtr(), std::move(callback))); +} + +void SyncableServiceBasedBridge::GetAllDataForDebugging(DataCallback callback) { + DCHECK(store_); + store_->ReadAllData( + base::BindOnce(&SyncableServiceBasedBridge::OnReadAllDataForProcessor, + weak_ptr_factory_.GetWeakPtr(), std::move(callback))); +} + +std::string SyncableServiceBasedBridge::GetClientTag( + const EntityData& entity_data) { + NOTREACHED(); + return std::string(); +} + +std::string SyncableServiceBasedBridge::GetStorageKey( + const EntityData& entity_data) { + // Not supported as per SupportsGetStorageKey(). + NOTREACHED(); + return std::string(); +} + +bool SyncableServiceBasedBridge::SupportsGetClientTag() const { + return false; +} + +bool SyncableServiceBasedBridge::SupportsGetStorageKey() const { + return false; +} + +ConflictResolution SyncableServiceBasedBridge::ResolveConflict( + const EntityData& local_data, + const EntityData& remote_data) const { + if (!remote_data.is_deleted()) { + return ConflictResolution::UseRemote(); + } + + DCHECK(!local_data.is_deleted()); + + // Ignore local changes for extensions/apps when server had a delete, to + // avoid unwanted reinstall of an uninstalled extension. + if (type_ == EXTENSIONS || type_ == APPS) { + DVLOG(1) << "Resolving conflict, ignoring local changes for extension/app"; + return ConflictResolution::UseRemote(); + } + + return ConflictResolution::UseLocal(); +} + +ModelTypeSyncBridge::StopSyncResponse +SyncableServiceBasedBridge::ApplyStopSyncChanges( + std::unique_ptr<MetadataChangeList> delete_metadata_change_list) { + DCHECK(store_); + + if (delete_metadata_change_list) { + in_memory_store_.clear(); + store_->DeleteAllDataAndMetadata(base::DoNothing()); + } + + if (syncable_service_started_) { + syncable_service_->StopSyncing(type_); + syncable_service_started_ = false; + } + + return StopSyncResponse::kModelStillReadyToSync; +} + +void SyncableServiceBasedBridge::OnStoreCreated( + const base::Optional<ModelError>& error, + std::unique_ptr<ModelTypeStore> store) { + if (error) { + change_processor()->ReportError(*error); + return; + } + + DCHECK(store); + store_ = std::move(store); + + store_->ReadAllData( + base::BindOnce(&SyncableServiceBasedBridge::OnReadAllDataForInit, + weak_ptr_factory_.GetWeakPtr())); +} + +void SyncableServiceBasedBridge::OnReadAllDataForInit( + const base::Optional<ModelError>& error, + std::unique_ptr<ModelTypeStore::RecordList> record_list) { + DCHECK(in_memory_store_.empty()); + + if (error) { + change_processor()->ReportError(*error); + return; + } + + for (const ModelTypeStore::Record& record : *record_list) { + sync_pb::PersistedEntityData persisted_entity; + if (!persisted_entity.ParseFromString(record.value)) { + change_processor()->ReportError( + {FROM_HERE, "Failed deserializing data."}); + return; + } + + in_memory_store_[record.id] = persisted_entity.specifics(); + } + + store_->ReadAllMetadata( + base::BindOnce(&SyncableServiceBasedBridge::OnReadAllMetadataForInit, + weak_ptr_factory_.GetWeakPtr())); +} + +void SyncableServiceBasedBridge::OnReadAllMetadataForInit( + const base::Optional<ModelError>& error, + std::unique_ptr<MetadataBatch> metadata_batch) { + DCHECK(!syncable_service_started_); + + if (error) { + change_processor()->ReportError(*error); + return; + } + + change_processor()->ModelReadyToSync(std::move(metadata_batch)); + MaybeStartSyncableService(); +} + +void SyncableServiceBasedBridge::MaybeStartSyncableService() { + DCHECK(!syncable_service_started_); + DCHECK(store_); + + // If sync wasn't enabled according to the loaded metadata, let's wait until + // MergeSyncData() is called before starting the SyncableService. + if (!change_processor()->IsTrackingMetadata()) { + return; + } + + // Sync enabled, so exercise MergeDataAndStartSyncing() immediately, since + // this function is reached only if sync is starting already. + SyncDataList initial_sync_data; + initial_sync_data.reserve(in_memory_store_.size()); + for (const std::pair<std::string, sync_pb::EntitySpecifics>& record : + in_memory_store_) { + initial_sync_data.push_back(SyncData::CreateRemoteData( + /*id=*/kInvalidNodeId, record.second, + /*last_modified_time=*/base::Time(), // Used by legacy sessions only. + /*client_tag_hash=*/record.first)); + } + + auto error_callback = + base::BindRepeating(&SyncableServiceBasedBridge::ReportErrorIfSet, + weak_ptr_factory_.GetWeakPtr()); + auto processor_impl = std::make_unique<ChangeProcessorImpl>( + type_, error_callback, store_.get(), &in_memory_store_, + change_processor()); + + const base::Optional<ModelError> merge_error = ConvertToModelError( + syncable_service_ + ->MergeDataAndStartSyncing( + type_, initial_sync_data, std::move(processor_impl), + std::make_unique<SyncErrorFactoryImpl>(type_)) + .error()); + + if (merge_error) { + change_processor()->ReportError(*merge_error); + } else { + syncable_service_started_ = true; + } +} + +SyncChangeList SyncableServiceBasedBridge::StoreAndConvertRemoteChanges( + std::unique_ptr<MetadataChangeList> metadata_change_list, + EntityChangeList entity_change_list) { + std::unique_ptr<ModelTypeStore::WriteBatch> batch = + store_->CreateWriteBatch(); + + SyncChangeList output_change_list; + output_change_list.reserve(entity_change_list.size()); + + for (const EntityChange& change : entity_change_list) { + switch (change.type()) { + case EntityChange::ACTION_DELETE: { + const std::string& storage_key = change.storage_key(); + DCHECK_NE(0U, in_memory_store_.count(storage_key)); + DVLOG(1) << ModelTypeToString(type_) + << ": Processing deletion with storage key: " << storage_key; + + output_change_list.emplace_back( + FROM_HERE, SyncChange::ACTION_DELETE, + SyncData::CreateRemoteData( + /*id=*/kInvalidNodeId, in_memory_store_[storage_key], + change.data().modification_time, + change.data().client_tag_hash)); + + // For tombstones, there is no actual data, which means no client tag + // hash either, but the processor provides the storage key. + DCHECK(!storage_key.empty()); + batch->DeleteData(storage_key); + in_memory_store_.erase(storage_key); + break; + } + + case EntityChange::ACTION_ADD: + // Because we use the client tag hash as storage key, let the processor + // know. + change_processor()->UpdateStorageKey( + change.data(), /*storage_key=*/change.data().client_tag_hash, + metadata_change_list.get()); + FALLTHROUGH; + + case EntityChange::ACTION_UPDATE: { + const std::string& storage_key = change.data().client_tag_hash; + DVLOG(1) << ModelTypeToString(type_) + << ": Processing add/update with key: " << storage_key; + + output_change_list.emplace_back( + FROM_HERE, ConvertToSyncChangeType(change.type()), + SyncData::CreateRemoteData( + /*id=*/kInvalidNodeId, change.data().specifics, + change.data().modification_time, + change.data().client_tag_hash)); + + batch->WriteData( + storage_key, + CreatePersistedFromEntityData(change.data()).SerializeAsString()); + in_memory_store_[storage_key] = change.data().specifics; + break; + } + } + } + + store_->CommitWriteBatch( + std::move(batch), + base::BindOnce(&SyncableServiceBasedBridge::ReportErrorIfSet, + weak_ptr_factory_.GetWeakPtr())); + + return output_change_list; +} + +void SyncableServiceBasedBridge::OnReadDataForProcessor( + DataCallback callback, + const base::Optional<ModelError>& error, + std::unique_ptr<ModelTypeStore::RecordList> record_list, + std::unique_ptr<ModelTypeStore::IdList> missing_id_list) { + OnReadAllDataForProcessor(std::move(callback), error, std::move(record_list)); +} + +void SyncableServiceBasedBridge::OnReadAllDataForProcessor( + DataCallback callback, + const base::Optional<ModelError>& error, + std::unique_ptr<ModelTypeStore::RecordList> record_list) { + if (error) { + change_processor()->ReportError(*error); + return; + } + + auto batch = std::make_unique<MutableDataBatch>(); + for (const ModelTypeStore::Record& record : *record_list) { + auto persisted_entity = std::make_unique<sync_pb::PersistedEntityData>(); + if (record.id.empty() || !persisted_entity->ParseFromString(record.value)) { + change_processor()->ReportError( + {FROM_HERE, "Failed deserializing data."}); + return; + } + + // Note that client tag hash is used as storage key too. + batch->Put(record.id, + ConvertPersistedToEntityData( + /*client_tag_hash=*/record.id, std::move(persisted_entity))); + } + std::move(callback).Run(std::move(batch)); +} + +void SyncableServiceBasedBridge::ReportErrorIfSet( + const base::Optional<ModelError>& error) { + if (error) { + change_processor()->ReportError(*error); + } +} + +} // namespace syncer
diff --git a/components/sync/model_impl/syncable_service_based_bridge.h b/components/sync/model_impl/syncable_service_based_bridge.h new file mode 100644 index 0000000..938d809 --- /dev/null +++ b/components/sync/model_impl/syncable_service_based_bridge.h
@@ -0,0 +1,103 @@ +// 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 COMPONENTS_SYNC_MODEL_IMPL_SYNCABLE_SERVICE_BASED_BRIDGE_H_ +#define COMPONENTS_SYNC_MODEL_IMPL_SYNCABLE_SERVICE_BASED_BRIDGE_H_ + +#include <map> +#include <memory> +#include <string> + +#include "base/callback_forward.h" +#include "base/macros.h" +#include "base/memory/weak_ptr.h" +#include "components/sync/model/model_error.h" +#include "components/sync/model/model_type_store.h" +#include "components/sync/model/model_type_sync_bridge.h" +#include "components/sync/model/sync_change_processor.h" + +namespace syncer { + +class MetadataBatch; +class ModelTypeChangeProcessor; +class SyncableService; + +// Implementation of ModelTypeSyncBridge that allows integrating legacy +// datatypes that implement SyncableService. Internally, it uses a database to +// persist and mimic the legacy directory's behavior, but as opposed to the +// legacy directory, it's not exposed anywhere outside this bridge, and is +// considered an implementation detail. +class SyncableServiceBasedBridge : public ModelTypeSyncBridge { + public: + // Pointers must not be null and |syncable_service| must outlive this object. + SyncableServiceBasedBridge( + ModelType type, + OnceModelTypeStoreFactory store_factory, + std::unique_ptr<ModelTypeChangeProcessor> change_processor, + SyncableService* syncable_service); + ~SyncableServiceBasedBridge() override; + + // ModelTypeSyncBridge implementation. + void OnSyncStarting(const DataTypeActivationRequest& request) override; + std::unique_ptr<MetadataChangeList> CreateMetadataChangeList() override; + base::Optional<ModelError> MergeSyncData( + std::unique_ptr<MetadataChangeList> metadata_change_list, + EntityChangeList entity_change_list) override; + base::Optional<ModelError> ApplySyncChanges( + std::unique_ptr<MetadataChangeList> metadata_change_list, + EntityChangeList entity_change_list) override; + void GetData(StorageKeyList storage_keys, DataCallback callback) override; + void GetAllDataForDebugging(DataCallback callback) override; + std::string GetClientTag(const EntityData& entity_data) override; + std::string GetStorageKey(const EntityData& entity_data) override; + bool SupportsGetClientTag() const override; + bool SupportsGetStorageKey() const override; + ConflictResolution ResolveConflict( + const EntityData& local_data, + const EntityData& remote_data) const override; + StopSyncResponse ApplyStopSyncChanges( + std::unique_ptr<MetadataChangeList> delete_metadata_change_list) override; + + private: + void OnStoreCreated(const base::Optional<ModelError>& error, + std::unique_ptr<ModelTypeStore> store); + void OnReadAllDataForInit( + const base::Optional<ModelError>& error, + std::unique_ptr<ModelTypeStore::RecordList> record_list); + void OnReadAllMetadataForInit(const base::Optional<ModelError>& error, + std::unique_ptr<MetadataBatch> metadata_batch); + void MaybeStartSyncableService(); + SyncChangeList StoreAndConvertRemoteChanges( + std::unique_ptr<MetadataChangeList> metadata_change_list, + EntityChangeList entity_change_list); + void OnReadDataForProcessor( + DataCallback callback, + const base::Optional<ModelError>& error, + std::unique_ptr<ModelTypeStore::RecordList> record_list, + std::unique_ptr<ModelTypeStore::IdList> missing_id_list); + void OnReadAllDataForProcessor( + DataCallback callback, + const base::Optional<ModelError>& error, + std::unique_ptr<ModelTypeStore::RecordList> record_list); + void ReportErrorIfSet(const base::Optional<ModelError>& error); + + const ModelType type_; + SyncableService* const syncable_service_; + OnceModelTypeStoreFactory store_factory_; + + std::unique_ptr<ModelTypeStore> store_; + bool syncable_service_started_; + + // In-memory copy of |store_|, needed for remote deletions, because we need to + // provide specifics of the deleted entity to the SyncableService. + std::map<std::string, sync_pb::EntitySpecifics> in_memory_store_; + + base::WeakPtrFactory<SyncableServiceBasedBridge> weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(SyncableServiceBasedBridge); +}; + +} // namespace syncer + +#endif // COMPONENTS_SYNC_MODEL_IMPL_SYNCABLE_SERVICE_BASED_BRIDGE_H_
diff --git a/components/sync/model_impl/syncable_service_based_bridge_unittest.cc b/components/sync/model_impl/syncable_service_based_bridge_unittest.cc new file mode 100644 index 0000000..4682028 --- /dev/null +++ b/components/sync/model_impl/syncable_service_based_bridge_unittest.cc
@@ -0,0 +1,432 @@ +// 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 "components/sync/model_impl/syncable_service_based_bridge.h" + +#include <utility> + +#include "base/bind.h" +#include "base/bind_helpers.h" +#include "base/message_loop/message_loop.h" +#include "base/run_loop.h" +#include "base/test/bind_test_util.h" +#include "base/test/mock_callback.h" +#include "components/sync/base/hash_util.h" +#include "components/sync/model/mock_model_type_change_processor.h" +#include "components/sync/model/model_error.h" +#include "components/sync/model/model_type_store_test_util.h" +#include "components/sync/model/sync_change.h" +#include "components/sync/model/sync_error_factory.h" +#include "components/sync/model/sync_merge_result.h" +#include "components/sync/model/syncable_service.h" +#include "components/sync/model_impl/client_tag_based_model_type_processor.h" +#include "components/sync/protocol/sync.pb.h" +#include "components/sync/test/engine/mock_model_type_worker.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace syncer { +namespace { + +using testing::DoAll; +using testing::ElementsAre; +using testing::IsEmpty; +using testing::NotNull; +using testing::Pair; +using testing::Return; +using testing::SaveArg; +using testing::_; + +const ModelType kModelType = PREFERENCES; + +sync_pb::EntitySpecifics GetTestSpecifics(const std::string& name = "name") { + sync_pb::EntitySpecifics specifics; + // Make specifics non empty, to avoid it being interpreted as a tombstone. + specifics.mutable_preference()->set_name(name); + return specifics; +} + +MATCHER_P(SyncDataRemoteMatches, name, "") { + return arg.IsValid() && !arg.IsLocal() && arg.GetDataType() == kModelType && + arg.GetSpecifics().preference().name() == name; +} + +MATCHER_P2(SyncChangeMatches, change_type, name, "") { + return arg.IsValid() && change_type == arg.change_type() && + arg.sync_data().GetDataType() == kModelType && + arg.sync_data().GetSpecifics().preference().name() == name; +} + +MATCHER_P(HasName, name, "") { + return arg && arg->specifics.preference().name() == name; +} + +class MockSyncableService : public SyncableService { + public: + MOCK_METHOD4( + MergeDataAndStartSyncing, + SyncMergeResult(ModelType type, + const SyncDataList& initial_sync_data, + std::unique_ptr<SyncChangeProcessor> sync_processor, + std::unique_ptr<SyncErrorFactory> sync_error_factory)); + MOCK_METHOD1(StopSyncing, void(ModelType type)); + MOCK_METHOD2(ProcessSyncChanges, + SyncError(const base::Location& from_here, + const SyncChangeList& change_list)); + MOCK_CONST_METHOD1(GetAllSyncData, SyncDataList(ModelType type)); +}; + +class SyncableServiceBasedBridgeTest : public ::testing::Test { + protected: + SyncableServiceBasedBridgeTest() { + ON_CALL(syncable_service_, MergeDataAndStartSyncing(_, _, _, _)) + .WillByDefault( + [&](ModelType type, const SyncDataList& initial_sync_data, + std::unique_ptr<SyncChangeProcessor> sync_processor, + std::unique_ptr<SyncErrorFactory> sync_error_factory) { + start_syncing_sync_processor_ = std::move(sync_processor); + return SyncMergeResult(kModelType); + }); + } + + ~SyncableServiceBasedBridgeTest() override {} + + void InitializeBridge() { + real_processor_ = + std::make_unique<syncer::ClientTagBasedModelTypeProcessor>( + kModelType, /*dump_stack=*/base::DoNothing(), + /*commit_only=*/false); + mock_processor_.DelegateCallsByDefaultTo(real_processor_.get()); + bridge_ = std::make_unique<SyncableServiceBasedBridge>( + kModelType, ModelTypeStoreTestUtil::FactoryForInMemoryStoreForTest(), + mock_processor_.CreateForwardingProcessor(), &syncable_service_); + } + + void ShutdownBridge() { + bridge_.reset(); + // The mock is still delegating to |real_processor_|, so we reset it too. + ASSERT_TRUE(testing::Mock::VerifyAndClear(&mock_processor_)); + real_processor_.reset(); + } + + void StartSyncing() { + syncer::DataTypeActivationRequest request; + request.error_handler = mock_error_handler_.Get(); + request.cache_guid = "TestCacheGuid"; + request.authenticated_account_id = "SomeAccountId"; + + base::RunLoop loop; + real_processor_->OnSyncStarting( + request, + base::BindLambdaForTesting( + [&](std::unique_ptr<syncer::DataTypeActivationResponse> response) { + worker_ = std::make_unique<MockModelTypeWorker>( + response->model_type_state, real_processor_.get()); + loop.Quit(); + })); + loop.Run(); + } + + std::map<std::string, std::unique_ptr<EntityData>> GetAllData() { + base::RunLoop loop; + std::unique_ptr<DataBatch> batch; + bridge_->GetAllDataForDebugging(base::BindLambdaForTesting( + [&loop, &batch](std::unique_ptr<DataBatch> input_batch) { + batch = std::move(input_batch); + loop.Quit(); + })); + loop.Run(); + EXPECT_NE(nullptr, batch); + + std::map<std::string, std::unique_ptr<EntityData>> storage_key_to_data; + while (batch && batch->HasNext()) { + storage_key_to_data.insert(batch->Next()); + } + return storage_key_to_data; + } + + const std::string kClientTag = "clienttag"; + const std::string kClientTagHash = + GenerateSyncableHash(kModelType, kClientTag); + + base::MessageLoop message_loop_; + testing::NiceMock<MockSyncableService> syncable_service_; + testing::NiceMock<MockModelTypeChangeProcessor> mock_processor_; + base::MockCallback<ModelErrorHandler> mock_error_handler_; + std::unique_ptr<syncer::ClientTagBasedModelTypeProcessor> real_processor_; + std::unique_ptr<SyncableServiceBasedBridge> bridge_; + std::unique_ptr<MockModelTypeWorker> worker_; + // SyncChangeProcessor received via MergeDataAndStartSyncing(), or null if it + // hasn't been called. + std::unique_ptr<SyncChangeProcessor> start_syncing_sync_processor_; + + private: + DISALLOW_COPY_AND_ASSIGN(SyncableServiceBasedBridgeTest); +}; + +TEST_F(SyncableServiceBasedBridgeTest, + ShouldStartSyncingWithEmptyInitialRemoteData) { + // Bridge initialization alone, without sync itself starting, should not + // issue calls to the syncable service. + EXPECT_CALL(syncable_service_, MergeDataAndStartSyncing(_, _, _, _)).Times(0); + InitializeBridge(); + + // Starting sync itself is also not sufficient, until initial remote data is + // received. + StartSyncing(); + + // Once the initial data is fetched from the server, + // MergeDataAndStartSyncing() should be exercised. + EXPECT_CALL( + syncable_service_, + MergeDataAndStartSyncing(kModelType, IsEmpty(), NotNull(), NotNull())); + worker_->UpdateFromServer(); + EXPECT_THAT(GetAllData(), IsEmpty()); +} + +TEST_F(SyncableServiceBasedBridgeTest, + ShouldStartSyncingWithNonEmptyInitialRemoteData) { + InitializeBridge(); + StartSyncing(); + + // Once the initial data is fetched from the server, + // MergeDataAndStartSyncing() should be exercised. + EXPECT_CALL(syncable_service_, + MergeDataAndStartSyncing( + kModelType, ElementsAre(SyncDataRemoteMatches("name1")), + NotNull(), NotNull())); + worker_->UpdateFromServer(kClientTagHash, GetTestSpecifics("name1")); + EXPECT_THAT(GetAllData(), ElementsAre(Pair(kClientTagHash, _))); +} + +TEST_F(SyncableServiceBasedBridgeTest, + ShouldStopSyncableServiceIfPreviouslyStarted) { + InitializeBridge(); + StartSyncing(); + worker_->UpdateFromServer(); + + EXPECT_CALL(syncable_service_, StopSyncing(kModelType)); + real_processor_->OnSyncStopping(KEEP_METADATA); + + EXPECT_CALL(syncable_service_, StopSyncing(_)).Times(0); + ShutdownBridge(); +} + +TEST_F(SyncableServiceBasedBridgeTest, + ShouldStopSyncableServiceDuringShutdownIfPreviouslyStarted) { + InitializeBridge(); + StartSyncing(); + worker_->UpdateFromServer(); + + EXPECT_CALL(syncable_service_, StopSyncing(kModelType)); + ShutdownBridge(); +} + +TEST_F(SyncableServiceBasedBridgeTest, + ShouldNotStopSyncableServiceIfNotPreviouslyStarted) { + EXPECT_CALL(syncable_service_, StopSyncing(_)).Times(0); + InitializeBridge(); + StartSyncing(); + real_processor_->OnSyncStopping(KEEP_METADATA); +} + +TEST_F(SyncableServiceBasedBridgeTest, + ShouldNotStopSyncableServiceDuringShutdownIfNotPreviouslyStarted) { + EXPECT_CALL(syncable_service_, StopSyncing(_)).Times(0); + InitializeBridge(); + StartSyncing(); + ShutdownBridge(); +} + +TEST_F(SyncableServiceBasedBridgeTest, ShouldPropagateErrorDuringStart) { + // Instrument MergeDataAndStartSyncing() to return an error. + SyncMergeResult merge_result(kModelType); + merge_result.set_error(SyncError(FROM_HERE, SyncError::PERSISTENCE_ERROR, + "Test error", kModelType)); + ON_CALL(syncable_service_, MergeDataAndStartSyncing(_, _, _, _)) + .WillByDefault(Return(merge_result)); + + EXPECT_CALL(mock_error_handler_, Run(_)); + + InitializeBridge(); + StartSyncing(); + worker_->UpdateFromServer(); + + // Since the syncable service failed to start, it shouldn't be stopped. + EXPECT_CALL(syncable_service_, StopSyncing(_)).Times(0); + ShutdownBridge(); +} + +TEST_F(SyncableServiceBasedBridgeTest, + ShouldStartSyncingWithPreviousDirectoryData) { + InitializeBridge(); + StartSyncing(); + worker_->UpdateFromServer(kClientTagHash, GetTestSpecifics("name1")); + real_processor_->OnSyncStopping(KEEP_METADATA); + EXPECT_THAT(GetAllData(), ElementsAre(Pair(kClientTagHash, _))); + + EXPECT_CALL(syncable_service_, + MergeDataAndStartSyncing( + kModelType, ElementsAre(SyncDataRemoteMatches("name1")), + NotNull(), NotNull())); + StartSyncing(); +} + +TEST_F(SyncableServiceBasedBridgeTest, ShouldSupportDisableReenableSequence) { + InitializeBridge(); + StartSyncing(); + worker_->UpdateFromServer(kClientTagHash, GetTestSpecifics()); + real_processor_->OnSyncStopping(CLEAR_METADATA); + EXPECT_THAT(GetAllData(), IsEmpty()); + + EXPECT_CALL(syncable_service_, MergeDataAndStartSyncing(_, _, _, _)).Times(0); + StartSyncing(); + EXPECT_CALL( + syncable_service_, + MergeDataAndStartSyncing(kModelType, IsEmpty(), NotNull(), NotNull())); + worker_->UpdateFromServer(); +} + +TEST_F(SyncableServiceBasedBridgeTest, + ShouldPropagateLocalEntitiesDuringMerge) { + ON_CALL(syncable_service_, MergeDataAndStartSyncing(_, _, _, _)) + .WillByDefault([&](ModelType type, const SyncDataList& initial_sync_data, + std::unique_ptr<SyncChangeProcessor> sync_processor, + std::unique_ptr<SyncErrorFactory> sync_error_factory) { + SyncChangeList change_list; + change_list.emplace_back( + FROM_HERE, SyncChange::ACTION_ADD, + SyncData::CreateLocalData(kClientTag, "title", GetTestSpecifics())); + const SyncError error = + sync_processor->ProcessSyncChanges(FROM_HERE, change_list); + EXPECT_FALSE(error.IsSet()); + return SyncMergeResult(kModelType); + }); + + InitializeBridge(); + StartSyncing(); + + EXPECT_CALL(mock_processor_, Put(kClientTagHash, NotNull(), NotNull())); + worker_->UpdateFromServer(); + EXPECT_THAT(GetAllData(), ElementsAre(Pair(kClientTagHash, _))); +} + +TEST_F(SyncableServiceBasedBridgeTest, ShouldPropagateLocalCreation) { + InitializeBridge(); + StartSyncing(); + worker_->UpdateFromServer(); + ASSERT_THAT(start_syncing_sync_processor_, NotNull()); + ASSERT_THAT(GetAllData(), IsEmpty()); + + EXPECT_CALL(mock_processor_, Put(kClientTagHash, NotNull(), NotNull())); + + SyncChangeList change_list; + change_list.emplace_back( + FROM_HERE, SyncChange::ACTION_ADD, + SyncData::CreateLocalData(kClientTag, "title", GetTestSpecifics())); + const SyncError error = + start_syncing_sync_processor_->ProcessSyncChanges(FROM_HERE, change_list); + EXPECT_FALSE(error.IsSet()); + EXPECT_THAT(GetAllData(), ElementsAre(Pair(kClientTagHash, _))); +} + +TEST_F(SyncableServiceBasedBridgeTest, ShouldPropagateLocalUpdate) { + InitializeBridge(); + StartSyncing(); + worker_->UpdateFromServer(kClientTagHash, GetTestSpecifics("name1")); + ASSERT_THAT(start_syncing_sync_processor_, NotNull()); + ASSERT_THAT(GetAllData(), + ElementsAre(Pair(kClientTagHash, HasName("name1")))); + + EXPECT_CALL(mock_processor_, Put(GenerateSyncableHash(kModelType, kClientTag), + NotNull(), NotNull())); + + SyncChangeList change_list; + change_list.emplace_back(FROM_HERE, SyncChange::ACTION_UPDATE, + SyncData::CreateLocalData( + kClientTag, "title", GetTestSpecifics("name2"))); + const SyncError error = + start_syncing_sync_processor_->ProcessSyncChanges(FROM_HERE, change_list); + EXPECT_FALSE(error.IsSet()); + EXPECT_THAT(GetAllData(), + ElementsAre(Pair(kClientTagHash, HasName("name2")))); +} + +TEST_F(SyncableServiceBasedBridgeTest, ShouldPropagateLocalDeletion) { + InitializeBridge(); + StartSyncing(); + worker_->UpdateFromServer(kClientTagHash, GetTestSpecifics("name1")); + ASSERT_THAT(start_syncing_sync_processor_, NotNull()); + ASSERT_THAT(GetAllData(), + ElementsAre(Pair(kClientTagHash, HasName("name1")))); + + EXPECT_CALL(mock_processor_, + Delete(GenerateSyncableHash(kModelType, kClientTag), NotNull())); + + SyncChangeList change_list; + change_list.emplace_back(FROM_HERE, SyncChange::ACTION_DELETE, + SyncData::CreateLocalDelete(kClientTag, kModelType)); + + const SyncError error = + start_syncing_sync_processor_->ProcessSyncChanges(FROM_HERE, change_list); + EXPECT_FALSE(error.IsSet()); + EXPECT_THAT(GetAllData(), IsEmpty()); +} + +TEST_F(SyncableServiceBasedBridgeTest, ShouldPropagateRemoteCreation) { + InitializeBridge(); + StartSyncing(); + worker_->UpdateFromServer(); + ASSERT_THAT(start_syncing_sync_processor_, NotNull()); + ASSERT_THAT(GetAllData(), IsEmpty()); + + EXPECT_CALL(syncable_service_, + ProcessSyncChanges(_, ElementsAre(SyncChangeMatches( + SyncChange::ACTION_ADD, "name1")))); + worker_->UpdateFromServer(kClientTagHash, GetTestSpecifics("name1")); + EXPECT_THAT(GetAllData(), + ElementsAre(Pair(kClientTagHash, HasName("name1")))); +} + +TEST_F(SyncableServiceBasedBridgeTest, ShouldPropagateRemoteUpdates) { + InitializeBridge(); + StartSyncing(); + worker_->UpdateFromServer(kClientTagHash, GetTestSpecifics("name1")); + ASSERT_THAT(start_syncing_sync_processor_, NotNull()); + ASSERT_THAT(GetAllData(), + ElementsAre(Pair(kClientTagHash, HasName("name1")))); + + EXPECT_CALL(syncable_service_, + ProcessSyncChanges(_, ElementsAre(SyncChangeMatches( + SyncChange::ACTION_UPDATE, "name2")))); + worker_->UpdateFromServer(kClientTagHash, GetTestSpecifics("name2")); + EXPECT_THAT(GetAllData(), + ElementsAre(Pair(kClientTagHash, HasName("name2")))); + + // A second update for the same entity. + EXPECT_CALL(syncable_service_, + ProcessSyncChanges(_, ElementsAre(SyncChangeMatches( + SyncChange::ACTION_UPDATE, "name3")))); + worker_->UpdateFromServer(kClientTagHash, GetTestSpecifics("name3")); + EXPECT_THAT(GetAllData(), + ElementsAre(Pair(kClientTagHash, HasName("name3")))); +} + +TEST_F(SyncableServiceBasedBridgeTest, ShouldPropagateRemoteDeletion) { + InitializeBridge(); + StartSyncing(); + worker_->UpdateFromServer(kClientTagHash, GetTestSpecifics("name1")); + ASSERT_THAT(start_syncing_sync_processor_, NotNull()); + ASSERT_THAT(GetAllData(), + ElementsAre(Pair(kClientTagHash, HasName("name1")))); + + EXPECT_CALL(syncable_service_, + ProcessSyncChanges(_, ElementsAre(SyncChangeMatches( + SyncChange::ACTION_DELETE, "name1")))); + worker_->TombstoneFromServer(kClientTagHash); + EXPECT_THAT(GetAllData(), IsEmpty()); +} + +} // namespace +} // namespace syncer
diff --git a/components/sync/protocol/persisted_entity_data.proto b/components/sync/protocol/persisted_entity_data.proto new file mode 100644 index 0000000..7661b29 --- /dev/null +++ b/components/sync/protocol/persisted_entity_data.proto
@@ -0,0 +1,23 @@ +// 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. + +syntax = "proto2"; + +option optimize_for = LITE_RUNTIME; + +package sync_pb; + +import "sync.proto"; + +// Sync proto to store entity data similar to what directory stores, used to +// persist data locally and never sent through the wire. +// +// Because it's conceptually similar to SyncEntity (actual protocol) and it's +// unclear how big this'll grow, we've kept compatibility with SyncEntity by +// using the same field numbers. +message PersistedEntityData { + // See corresponding fields in SyncEntity for details. + optional string non_unique_name = 8; + optional EntitySpecifics specifics = 21; +}
diff --git a/components/sync/protocol/protocol_sources.gni b/components/sync/protocol/protocol_sources.gni index 2b1b740..2e3c322 100644 --- a/components/sync/protocol/protocol_sources.gni +++ b/components/sync/protocol/protocol_sources.gni
@@ -37,6 +37,7 @@ "mountain_share_specifics", "nigori_specifics", "password_specifics", + "persisted_entity_data", "preference_specifics", "printer_specifics", "priority_preference_specifics",
diff --git a/components/variations/variations_crash_keys.cc b/components/variations/variations_crash_keys.cc index 91c477c..d43be0ef 100644 --- a/components/variations/variations_crash_keys.cc +++ b/components/variations/variations_crash_keys.cc
@@ -19,10 +19,10 @@ namespace { -// Size of the "num-experiments" crash key in bytes. 2048 bytes should be able -// to hold about 113 entries, given each entry is 18 bytes long (due to being +// Size of the "num-experiments" crash key in bytes. 4096 bytes should be able +// to hold about 227 entries, given each entry is 18 bytes long (due to being // of the form "8e7abfb0-c16397b7,"). -constexpr size_t kVariationsKeySize = 2048; +constexpr size_t kVariationsKeySize = 4096; // Crash key reporting the number of experiments. 8 is the size of the crash key // in bytes, which is used to hold an int as a string.
diff --git a/components/viz/service/display/gl_renderer.h b/components/viz/service/display/gl_renderer.h index ac15162..11d1664 100644 --- a/components/viz/service/display/gl_renderer.h +++ b/components/viz/service/display/gl_renderer.h
@@ -76,23 +76,7 @@ protected: void DidChangeVisibility() override; - const gfx::QuadF& SharedGeometryQuad() const { return shared_geometry_quad_; } - const StaticGeometryBinding* SharedGeometry() const { - return shared_geometry_.get(); - } - - // Returns the format to use for storage if copying from the current - // framebuffer. If the root renderpass is current, it uses the best matching - // format from the OutputSurface, otherwise it uses the best matching format - // from the texture being drawn to as the backbuffer. - GLenum GetFramebufferCopyTextureFormat(); - void ReleaseRenderPassTextures(); - enum BoundGeometry { NO_BINDING, SHARED_BINDING, CLIPPED_BINDING }; - void PrepareGeometry(BoundGeometry geometry_to_bind); - void SetStencilEnabled(bool enabled); bool stencil_enabled() const { return stencil_shadow_; } - void SetBlendEnabled(bool enabled); - bool blend_enabled() const { return blend_shadow_; } bool CanPartialSwap() override; void UpdateRenderPassTextures( @@ -169,6 +153,18 @@ struct DrawRenderPassDrawQuadParams; + // Returns the format to use for storage if copying from the current + // framebuffer. If the root renderpass is current, it uses the best matching + // format from the OutputSurface, otherwise it uses the best matching format + // from the texture being drawn to as the backbuffer. + GLenum GetFramebufferCopyTextureFormat(); + void ReleaseRenderPassTextures(); + enum BoundGeometry { NO_BINDING, SHARED_BINDING, CLIPPED_BINDING }; + void PrepareGeometry(BoundGeometry geometry_to_bind); + void SetStencilEnabled(bool enabled); + void SetBlendEnabled(bool enabled); + bool blend_enabled() const { return blend_shadow_; } + // If any of the following functions returns false, then it means that drawing // is not possible. bool InitializeRPDQParameters(DrawRenderPassDrawQuadParams* params); @@ -259,6 +255,11 @@ gfx::QuadF* local_quad, const gfx::Rect& tile_rect); + const gfx::QuadF& SharedGeometryQuad() const { return shared_geometry_quad_; } + const StaticGeometryBinding* SharedGeometry() const { + return shared_geometry_.get(); + } + // If |dst_color_space| is invalid, then no color conversion (apart from // YUV to RGB conversion) is performed. This explicit argument is available // so that video color conversion can be enabled separately from general color
diff --git a/components/viz/service/display/skia_renderer.cc b/components/viz/service/display/skia_renderer.cc index 587c10f1..cf8c28f 100644 --- a/components/viz/service/display/skia_renderer.cc +++ b/components/viz/service/display/skia_renderer.cc
@@ -182,6 +182,7 @@ SkiaOutputSurface* skia_output_surface) : DirectRenderer(settings, output_surface, resource_provider), skia_output_surface_(skia_output_surface), + quad_vertex_skrect_(gfx::RectFToSkRect(QuadVertexRect())), lock_set_for_external_use_(resource_provider) { if (auto* context_provider = output_surface_->context_provider()) { const auto& context_caps = context_provider->ContextCapabilities(); @@ -562,7 +563,7 @@ void SkiaRenderer::DrawDebugBorderQuad(const DebugBorderDrawQuad* quad) { // We need to apply the matrix manually to have pixel-sized stroke width. SkPoint vertices[4]; - gfx::RectFToSkRect(QuadVertexRect()).toQuad(vertices); + QuadVertexSkRect().toQuad(vertices); SkPoint transformed_vertices[4]; current_canvas_->getTotalMatrix().mapPoints(transformed_vertices, vertices, 4); @@ -580,8 +581,7 @@ void SkiaRenderer::DrawPictureQuad(const PictureDrawQuad* quad) { SkMatrix content_matrix; content_matrix.setRectToRect(gfx::RectFToSkRect(quad->tex_coord_rect), - gfx::RectFToSkRect(QuadVertexRect()), - SkMatrix::kFill_ScaleToFit); + QuadVertexSkRect(), SkMatrix::kFill_ScaleToFit); current_canvas_->concat(content_matrix); const bool needs_transparency = @@ -815,7 +815,6 @@ if (!can_draw) return; - const auto dest_rect = gfx::RectFToSkRect(QuadVertexRect()); SkRect content_rect; SkRect dest_visible_rect; if (params.filter_image) { @@ -841,7 +840,7 @@ SkRect mask_rect = gfx::RectFToSkRect( gfx::ScaleRect(quad->mask_uv_rect, quad->mask_texture_size.width(), quad->mask_texture_size.height())); - mask_to_dest_matrix.setRectToRect(mask_rect, dest_rect, + mask_to_dest_matrix.setRectToRect(mask_rect, QuadVertexSkRect(), SkMatrix::kFill_ScaleToFit); mask_filter = SkShaderMaskFilter::Make(mask_image->makeShader(&mask_to_dest_matrix)); @@ -865,7 +864,7 @@ // Convert the content_image to a shader, and use drawRect() with the // shader. SkMatrix content_to_dest_matrix; - content_to_dest_matrix.setRectToRect(content_rect, dest_rect, + content_to_dest_matrix.setRectToRect(content_rect, QuadVertexSkRect(), SkMatrix::kFill_ScaleToFit); auto shader = content_image->makeShader(&content_to_dest_matrix); current_paint_.setShader(std::move(shader)); @@ -882,7 +881,7 @@ : nullptr; DCHECK(background_image_filter); SkMatrix content_to_dest_matrix; - content_to_dest_matrix.setRectToRect(content_rect, dest_rect, + content_to_dest_matrix.setRectToRect(content_rect, QuadVertexSkRect(), SkMatrix::kFill_ScaleToFit); SkMatrix local_matrix; local_matrix.setTranslate(quad->filters_origin.x(), quad->filters_origin.y()); @@ -892,7 +891,7 @@ background_image_filter->makeWithLocalMatrix(local_matrix); SkAutoCanvasRestore auto_canvas_restore(current_canvas_, true /* do_save */); - current_canvas_->clipRect(dest_rect); + current_canvas_->clipRect(QuadVertexSkRect()); SkPaint paint; paint.setMaskFilter(mask_filter); @@ -919,8 +918,7 @@ current_paint_.setColor(SK_ColorMAGENTA); #endif current_paint_.setAlpha(quad->shared_quad_state->opacity * 255); - current_canvas_->drawRect(gfx::RectFToSkRect(QuadVertexRect()), - current_paint_); + current_canvas_->drawRect(QuadVertexSkRect(), current_paint_); } void SkiaRenderer::CopyDrawnRenderPass(
diff --git a/components/viz/service/display/skia_renderer.h b/components/viz/service/display/skia_renderer.h index e2fa854..05318a8 100644 --- a/components/viz/service/display/skia_renderer.h +++ b/components/viz/service/display/skia_renderer.h
@@ -104,6 +104,7 @@ GrContext* GetGrContext(); bool is_using_ddl() const { return !!skia_output_surface_; } const TileDrawQuad* CanPassBeDrawnDirectly(const RenderPass* pass) override; + const SkRect& QuadVertexSkRect() const { return quad_vertex_skrect_; } // A map from RenderPass id to the texture used to draw the RenderPass from. struct RenderPassBacking { @@ -138,6 +139,7 @@ SkCanvas* current_canvas_ = nullptr; SkSurface* current_surface_ = nullptr; SkPaint current_paint_; + const SkRect quad_vertex_skrect_; base::Optional<SyncQueryCollection> sync_queries_; bool use_swap_with_bounds_ = false;
diff --git a/components/viz/service/frame_sinks/direct_layer_tree_frame_sink.cc b/components/viz/service/frame_sinks/direct_layer_tree_frame_sink.cc index 8a56959..fa78b89 100644 --- a/components/viz/service/frame_sinks/direct_layer_tree_frame_sink.cc +++ b/components/viz/service/frame_sinks/direct_layer_tree_frame_sink.cc
@@ -132,6 +132,15 @@ const SurfaceDrawQuad* surface_quad = SurfaceDrawQuad::MaterialCast(quad); + // Skip the quad if the FrameSinkId between fallback and primary is not + // the same, because we don't know which FrameSinkId would be used to + // draw this quad. + if (surface_quad->surface_range.start() && + surface_quad->surface_range.start()->frame_sink_id() != + surface_quad->surface_range.end().frame_sink_id()) { + continue; + } + // Skip the quad if the transform is not invertible (i.e. it will not // be able to receive events). gfx::Transform target_to_quad_transform;
diff --git a/components/viz/service/gl/gpu_service_impl.cc b/components/viz/service/gl/gpu_service_impl.cc index 8ef41f3..7a7d21a 100644 --- a/components/viz/service/gl/gpu_service_impl.cc +++ b/components/viz/service/gl/gpu_service_impl.cc
@@ -710,8 +710,7 @@ client_id, client_tracing_id, is_gpu_host, cache_shaders_on_disk); mojo::MessagePipe pipe; - gpu_channel->Init(std::make_unique<gpu::SyncChannelFilteredSender>( - pipe.handle0.release(), gpu_channel, io_runner_, shutdown_event_)); + gpu_channel->Init(pipe.handle0.release(), shutdown_event_); media_gpu_channel_manager_->AddChannel(client_id);
diff --git a/content/browser/background_fetch/storage/mark_request_complete_task.cc b/content/browser/background_fetch/storage/mark_request_complete_task.cc index 78be237..7fcf47e 100644 --- a/content/browser/background_fetch/storage/mark_request_complete_task.cc +++ b/content/browser/background_fetch/storage/mark_request_complete_task.cc
@@ -62,8 +62,6 @@ void MarkRequestCompleteTask::StoreResponse(base::OnceClosure done_closure) { auto response = blink::mojom::FetchAPIResponse::New(); response->url_list = request_info_->GetURLChain(); - // TODO(crbug.com/838837): fill error and cors_exposed_header_names in - // response. response->response_type = network::mojom::FetchResponseType::kDefault; response->response_time = request_info_->GetResponseTime();
diff --git a/content/browser/devtools/devtools_video_consumer.cc b/content/browser/devtools/devtools_video_consumer.cc index 1dd814c..f06866c3 100644 --- a/content/browser/devtools/devtools_video_consumer.cc +++ b/content/browser/devtools/devtools_video_consumer.cc
@@ -57,7 +57,7 @@ skbitmap.allocN32Pixels(frame->visible_rect().width(), frame->visible_rect().height()); cc::SkiaPaintCanvas canvas(skbitmap); - renderer.Copy(frame, &canvas, media::Context3D(), nullptr); + renderer.Copy(frame, &canvas, media::Context3D()); return skbitmap; }
diff --git a/content/browser/loader/data_pipe_to_source_stream.cc b/content/browser/loader/data_pipe_to_source_stream.cc index 4a3694f..87f422f3 100644 --- a/content/browser/loader/data_pipe_to_source_stream.cc +++ b/content/browser/loader/data_pipe_to_source_stream.cc
@@ -33,7 +33,7 @@ int DataPipeToSourceStream::Read(net::IOBuffer* buf, int buf_size, net::CompletionOnceCallback callback) { - base::AutoReset<bool>(&inside_read_, true); + base::AutoReset<bool> inside_read_checker(&inside_read_, true); if (!body_.get()) { // We have finished reading the pipe.
diff --git a/content/browser/loader/navigation_url_loader_impl.cc b/content/browser/loader/navigation_url_loader_impl.cc index 838bef6ca..a5ea7dd9 100644 --- a/content/browser/loader/navigation_url_loader_impl.cc +++ b/content/browser/loader/navigation_url_loader_impl.cc
@@ -221,10 +221,8 @@ request_info->begin_params->headers); std::string accept_value = network::kFrameAcceptHeader; - // TODO(https://crbug.com/840704): Decide whether the Accept header should - // advertise the state of kSignedHTTPExchangeOriginTrial before starting the - // Origin-Trial. - if (signed_exchange_utils::IsSignedExchangeHandlingEnabled()) { + if (signed_exchange_utils::ShouldAdvertiseAcceptHeader( + url::Origin::Create(request_info->common_params.url))) { DCHECK(!accept_value.empty()); accept_value.append(kAcceptHeaderSignedExchangeSuffix); } @@ -988,6 +986,27 @@ // |resource_request_| during redirect. url_loader_modified_request_headers_ = modified_request_headers; + if (signed_exchange_utils::NeedToCheckRedirectedURLForAcceptHeader()) { + // Currently we send the SignedExchange accept header only for the limited + // origins when SignedHTTPExchangeOriginTrial feature is enabled without + // SignedHTTPExchange feature. We need to put the SignedExchange accept + // header on when redirecting to the origins in the OriginList of + // SignedHTTPExchangeAcceptHeader field trial, and need to remove it when + // redirecting to out of the OriginList. + if (!url_loader_modified_request_headers_) + url_loader_modified_request_headers_ = net::HttpRequestHeaders(); + std::string accept_value = network::kFrameAcceptHeader; + if (signed_exchange_utils::ShouldAdvertiseAcceptHeader( + url::Origin::Create(resource_request_->url))) { + DCHECK(!accept_value.empty()); + accept_value.append(kAcceptHeaderSignedExchangeSuffix); + } + url_loader_modified_request_headers_->SetHeader(network::kAcceptHeader, + accept_value); + resource_request_->headers.SetHeader(network::kAcceptHeader, + accept_value); + } + Restart(); }
diff --git a/content/browser/loader/resource_dispatcher_host_impl.cc b/content/browser/loader/resource_dispatcher_host_impl.cc index 58e1e1a..c0a78b1 100644 --- a/content/browser/loader/resource_dispatcher_host_impl.cc +++ b/content/browser/loader/resource_dispatcher_host_impl.cc
@@ -1505,10 +1505,8 @@ headers.AddHeadersFromString(info.begin_params->headers); std::string accept_value = network::kFrameAcceptHeader; - // TODO(https://crbug.com/840704): Decide whether the Accept header should - // advertise the state of kSignedHTTPExchangeOriginTrial before starting the - // Origin-Trial. - if (signed_exchange_utils::IsSignedExchangeHandlingEnabled()) { + if (signed_exchange_utils::ShouldAdvertiseAcceptHeader( + url::Origin::Create(info.common_params.url))) { DCHECK(!accept_value.empty()); accept_value.append(kAcceptHeaderSignedExchangeSuffix); }
diff --git a/content/browser/renderer_host/delegated_frame_host.cc b/content/browser/renderer_host/delegated_frame_host.cc index 8ba5624e..769bc582 100644 --- a/content/browser/renderer_host/delegated_frame_host.cc +++ b/content/browser/renderer_host/delegated_frame_host.cc
@@ -149,7 +149,7 @@ } bool DelegatedFrameHost::CanCopyFromCompositingSurface() const { - return active_device_scale_factor_ != 0.f; + return HasFallbackSurface() && active_device_scale_factor_ != 0.f; } bool DelegatedFrameHost::TransformPointToLocalCoordSpaceLegacy( @@ -330,6 +330,8 @@ return; } + client_->DelegatedFrameHostGetLayer()->SetFallbackSurfaceId( + surface_info.id()); active_local_surface_id_ = surface_info.id().local_surface_id(); active_device_scale_factor_ = surface_info.device_scale_factor();
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc index 1c2a8390..95444b0 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura.cc +++ b/content/browser/renderer_host/render_widget_host_view_aura.cc
@@ -1698,6 +1698,8 @@ // In TransformPointToLocalCoordSpace() there is a Point-to-Pixel conversion, // but it is not necessary here because the final target view is responsible // for converting before computing the final transform. + if (!HasFallbackSurface()) + return false; return target_view->TransformPointToLocalCoordSpace( point, GetCurrentSurfaceId(), transformed_point, source); }
diff --git a/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc b/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc index 26a8baaf..84876fe 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc +++ b/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc
@@ -3431,7 +3431,8 @@ EXPECT_FALSE(view_->HasFallbackSurface()); } -// This test verifies that the primary SurfaceId is populated on resize. +// This test verifies that the primary SurfaceId is populated on resize and +// the fallback SurfaceId is populated in OnFirstSurfaceActivation. TEST_F(RenderWidgetHostViewAuraSurfaceSynchronizationTest, SurfaceChanges) { // Early out because DelegatedFrameHost is not used in mash. if (features::IsMultiProcessMash()) @@ -3447,8 +3448,25 @@ view_->SetSize(gfx::Size(300, 300)); ASSERT_TRUE(view_->HasPrimarySurface()); EXPECT_EQ(gfx::Size(300, 300), view_->window_->layer()->size()); + EXPECT_FALSE(view_->HasFallbackSurface()); EXPECT_EQ(gfx::Size(300, 300), view_->delegated_frame_host_->CurrentFrameSizeInDipForTesting()); + + // Resizing should update the primary SurfaceId. + view_->SetSize(gfx::Size(400, 400)); + EXPECT_EQ(gfx::Size(400, 400), view_->window_->layer()->size()); + EXPECT_EQ(nullptr, view_->window_->layer()->GetFallbackSurfaceId()); + EXPECT_EQ(gfx::Size(400, 400), + view_->delegated_frame_host_->CurrentFrameSizeInDipForTesting()); + + // Fallback SurfaceId should be updated in OnFirstSurfaceActivation. + // Submitting a CompositorFrame should update the fallback SurfaceId + viz::SurfaceId surface_id(view_->GetFrameSinkId(), + view_->GetLocalSurfaceId()); + view_->delegated_frame_host_->OnFirstSurfaceActivation( + viz::SurfaceInfo(surface_id, 1.f, gfx::Size(400, 400))); + EXPECT_EQ(gfx::Size(400, 400), view_->window_->layer()->size()); + EXPECT_EQ(surface_id, *view_->window_->layer()->GetFallbackSurfaceId()); } // This test verifies that the primary SurfaceId is updated on device scale @@ -3645,8 +3663,7 @@ // Make [1] hidden, resize it. It should drop its frame. views[1]->Hide(); - // TODO(samans): Fix this expectation once https://crbug.com/878372 is fixed. - EXPECT_FALSE(views[1]->HasFallbackSurface()); + EXPECT_TRUE(views[1]->HasFallbackSurface()); gfx::Size size2(200, 200); views[1]->SetSize(size2); EXPECT_FALSE(views[1]->HasFallbackSurface()); @@ -5919,9 +5936,7 @@ viz::LocalSurfaceId id1 = view_->GetLocalSurfaceId(); view_->delegated_frame_host_->OnFirstSurfaceActivation(viz::SurfaceInfo( viz::SurfaceId(view_->GetFrameSinkId(), id1), 1, gfx::Size(20, 20))); - // TODO(samans): Fix these expectations once https://crbug.com/878372 is - // fixed. - EXPECT_FALSE(view_->window_->layer()->GetFallbackSurfaceId()); + EXPECT_TRUE(view_->window_->layer()->GetFallbackSurfaceId()->is_valid()); view_->Hide(); view_->SetSize(gfx::Size(54, 32)); view_->Show(); @@ -5944,12 +5959,10 @@ viz::LocalSurfaceId id1 = view_->GetLocalSurfaceId(); view_->delegated_frame_host_->OnFirstSurfaceActivation(viz::SurfaceInfo( viz::SurfaceId(view_->GetFrameSinkId(), id1), 1, gfx::Size(20, 20))); - // TODO(samans): Fix these expectations once https://crbug.com/878372 is - // fixed. - EXPECT_FALSE(view_->window_->layer()->GetFallbackSurfaceId()); + EXPECT_TRUE(view_->window_->layer()->GetFallbackSurfaceId()->is_valid()); view_->Hide(); view_->Show(); - EXPECT_FALSE(view_->window_->layer()->GetFallbackSurfaceId()); + EXPECT_TRUE(view_->window_->layer()->GetFallbackSurfaceId()->is_valid()); } // Check that TakeFallbackContentFrom() copies the fallback SurfaceId and @@ -5974,10 +5987,16 @@ view2->GetNativeView(), parent_view_->GetNativeView()->GetRootWindow(), gfx::Rect()); - // Call TakeFallbackContentFrom(). The second view should obtain a fallback - // from the first view. + // Set fallback for the first view. + viz::LocalSurfaceId id = view_->GetLocalSurfaceId(); + view_->delegated_frame_host_->OnFirstSurfaceActivation(viz::SurfaceInfo( + viz::SurfaceId(view_->GetFrameSinkId(), id), 1, gfx::Size(20, 20))); + EXPECT_TRUE(view_->window_->layer()->GetFallbackSurfaceId()->is_valid()); + + // Call TakeFallbackContentFrom(). The second view should now have the same + // fallback as the first view. view2->TakeFallbackContentFrom(view_); - EXPECT_EQ(view_->window_->layer()->GetPrimarySurfaceId()->ToSmallestId(), + EXPECT_EQ(*view_->window_->layer()->GetFallbackSurfaceId(), *view2->window_->layer()->GetFallbackSurfaceId()); DestroyView(view2);
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 d5c21de..fc8e9dec 100644 --- a/content/browser/renderer_host/render_widget_host_view_mac.mm +++ b/content/browser/renderer_host/render_widget_host_view_mac.mm
@@ -1311,6 +1311,8 @@ return true; } + if (!HasFallbackSurface()) + return false; return target_view->TransformPointToLocalCoordSpace( point, GetCurrentSurfaceId(), transformed_point, source); }
diff --git a/content/browser/service_worker/service_worker_cache_writer_unittest.cc b/content/browser/service_worker/service_worker_cache_writer_unittest.cc index 7c858bd1..d37f40a40 100644 --- a/content/browser/service_worker/service_worker_cache_writer_unittest.cc +++ b/content/browser/service_worker/service_worker_cache_writer_unittest.cc
@@ -19,306 +19,6 @@ namespace content { namespace { -// A test implementation of ServiceWorkerResponseReader. -// -// This class exposes the ability to expect reads (see ExpectRead*() below). -// Each call to ReadInfo() or ReadData() consumes another expected read, in the -// order those reads were expected, so: -// reader->ExpectReadInfoOk(5, false); -// reader->ExpectReadDataOk("abcdef", false); -// reader->ExpectReadDataOk("ghijkl", false); -// Expects these calls, in this order: -// reader->ReadInfo(...); // reader writes 5 into -// // |info_buf->response_data_size| -// reader->ReadData(...); // reader writes "abcdef" into |buf| -// reader->ReadData(...); // reader writes "ghijkl" into |buf| -// If an unexpected call happens, this class DCHECKs. -// If an expected read is marked "async", it will not complete immediately, but -// must be completed by the test using CompletePendingRead(). -// These is a convenience method AllExpectedReadsDone() which returns whether -// there are any expected reads that have not yet happened. -class MockServiceWorkerResponseReader : public ServiceWorkerResponseReader { - public: - MockServiceWorkerResponseReader() - : ServiceWorkerResponseReader( - 0, - base::WeakPtr<AppCacheDiskCacheInterface>()) {} - ~MockServiceWorkerResponseReader() override {} - - // ServiceWorkerResponseReader overrides - void ReadInfo(HttpResponseInfoIOBuffer* info_buf, - OnceCompletionCallback callback) override; - void ReadData(net::IOBuffer* buf, - int buf_len, - OnceCompletionCallback callback) override; - - // Test helpers. ExpectReadInfo() and ExpectReadData() give precise control - // over both the data to be written and the result to return. - // ExpectReadInfoOk() and ExpectReadDataOk() are convenience functions for - // expecting successful reads, which always have their length as their result. - - // Expect a call to ReadInfo() on this reader. For these functions, |len| will - // be used as |response_data_size|, not as the length of this particular read. - void ExpectReadInfo(size_t len, bool async, int result); - void ExpectReadInfoOk(size_t len, bool async); - - // Expect a call to ReadData() on this reader. For these functions, |len| is - // the length of the data to be written back; in ExpectReadDataOk(), |len| is - // implicitly the length of |data|. - void ExpectReadData(const char* data, size_t len, bool async, int result); - void ExpectReadDataOk(const std::string& data, bool async); - - // Complete a pending async read. It is an error to call this function without - // a pending async read (ie, a previous call to ReadInfo() or ReadData() - // having not run its callback yet). - void CompletePendingRead(); - - // Returns whether all expected reads have occurred. - bool AllExpectedReadsDone() { return expected_reads_.size() == 0; } - - private: - struct ExpectedRead { - ExpectedRead(size_t len, bool async, int result) - : data(nullptr), len(len), info(true), async(async), result(result) {} - ExpectedRead(const char* data, size_t len, bool async, int result) - : data(data), len(len), info(false), async(async), result(result) {} - const char* data; - size_t len; - bool info; - bool async; - int result; - }; - - base::queue<ExpectedRead> expected_reads_; - scoped_refptr<net::IOBuffer> pending_buffer_; - size_t pending_buffer_len_; - scoped_refptr<HttpResponseInfoIOBuffer> pending_info_; - OnceCompletionCallback pending_callback_; - - DISALLOW_COPY_AND_ASSIGN(MockServiceWorkerResponseReader); -}; - -void MockServiceWorkerResponseReader::ReadInfo( - HttpResponseInfoIOBuffer* info_buf, - OnceCompletionCallback callback) { - DCHECK(!expected_reads_.empty()); - ExpectedRead expected = expected_reads_.front(); - EXPECT_TRUE(expected.info); - if (expected.async) { - pending_info_ = info_buf; - pending_callback_ = std::move(callback); - } else { - expected_reads_.pop(); - info_buf->response_data_size = expected.len; - std::move(callback).Run(expected.result); - } -} - -void MockServiceWorkerResponseReader::ReadData( - net::IOBuffer* buf, - int buf_len, - OnceCompletionCallback callback) { - DCHECK(!expected_reads_.empty()); - ExpectedRead expected = expected_reads_.front(); - EXPECT_FALSE(expected.info); - if (expected.async) { - pending_callback_ = std::move(callback); - pending_buffer_ = buf; - pending_buffer_len_ = static_cast<size_t>(buf_len); - } else { - expected_reads_.pop(); - if (expected.len > 0) { - size_t to_read = std::min(static_cast<size_t>(buf_len), expected.len); - memcpy(buf->data(), expected.data, to_read); - } - std::move(callback).Run(expected.result); - } -} - -void MockServiceWorkerResponseReader::ExpectReadInfo(size_t len, - bool async, - int result) { - expected_reads_.push(ExpectedRead(len, async, result)); -} - -void MockServiceWorkerResponseReader::ExpectReadInfoOk(size_t len, bool async) { - expected_reads_.push(ExpectedRead(len, async, len)); -} - -void MockServiceWorkerResponseReader::ExpectReadData(const char* data, - size_t len, - bool async, - int result) { - expected_reads_.push(ExpectedRead(data, len, async, result)); -} - -void MockServiceWorkerResponseReader::ExpectReadDataOk(const std::string& data, - bool async) { - expected_reads_.push( - ExpectedRead(data.data(), data.size(), async, data.size())); -} - -void MockServiceWorkerResponseReader::CompletePendingRead() { - DCHECK(!expected_reads_.empty()); - ExpectedRead expected = expected_reads_.front(); - expected_reads_.pop(); - EXPECT_TRUE(expected.async); - if (expected.info) { - pending_info_->response_data_size = expected.len; - } else { - size_t to_read = std::min(pending_buffer_len_, expected.len); - if (to_read > 0) - memcpy(pending_buffer_->data(), expected.data, to_read); - } - pending_info_ = nullptr; - pending_buffer_ = nullptr; - OnceCompletionCallback callback = std::move(pending_callback_); - pending_callback_.Reset(); - std::move(callback).Run(expected.result); -} - -// A test implementation of ServiceWorkerResponseWriter. -// -// This class exposes the ability to expect writes (see ExpectWrite*Ok() below). -// Each write to this class via WriteInfo() or WriteData() consumes another -// expected write, in the order they were added, so: -// writer->ExpectWriteInfoOk(5, false); -// writer->ExpectWriteDataOk(6, false); -// writer->ExpectWriteDataOk(6, false); -// Expects these calls, in this order: -// writer->WriteInfo(...); // checks that |buf->response_data_size| == 5 -// writer->WriteData(...); // checks that 6 bytes are being written -// writer->WriteData(...); // checks that another 6 bytes are being written -// If this class receives an unexpected call to WriteInfo() or WriteData(), it -// DCHECKs. -// Expected writes marked async do not complete synchronously, but rather return -// without running their callback and need to be completed with -// CompletePendingWrite(). -// A convenience method AllExpectedWritesDone() is exposed so tests can ensure -// that all expected writes have been consumed by matching calls to WriteInfo() -// or WriteData(). -class MockServiceWorkerResponseWriter : public ServiceWorkerResponseWriter { - public: - MockServiceWorkerResponseWriter() - : ServiceWorkerResponseWriter( - 0, - base::WeakPtr<AppCacheDiskCacheInterface>()), - info_written_(0), - data_written_(0) {} - ~MockServiceWorkerResponseWriter() override {} - - // ServiceWorkerResponseWriter overrides - void WriteInfo(HttpResponseInfoIOBuffer* info_buf, - OnceCompletionCallback callback) override; - void WriteData(net::IOBuffer* buf, - int buf_len, - OnceCompletionCallback callback) override; - - // Enqueue expected writes. - void ExpectWriteInfoOk(size_t len, bool async); - void ExpectWriteInfo(size_t len, bool async, int result); - void ExpectWriteDataOk(size_t len, bool async); - void ExpectWriteData(size_t len, bool async, int result); - - // Complete a pending asynchronous write. This method DCHECKs unless there is - // a pending write (a write for which WriteInfo() or WriteData() has been - // called but the callback has not yet been run). - void CompletePendingWrite(); - - // Returns whether all expected reads have been consumed. - bool AllExpectedWritesDone() { return expected_writes_.size() == 0; } - - private: - struct ExpectedWrite { - ExpectedWrite(bool is_info, size_t length, bool async, int result) - : is_info(is_info), length(length), async(async), result(result) {} - bool is_info; - size_t length; - bool async; - int result; - }; - - base::queue<ExpectedWrite> expected_writes_; - - size_t info_written_; - size_t data_written_; - - OnceCompletionCallback pending_callback_; - - DISALLOW_COPY_AND_ASSIGN(MockServiceWorkerResponseWriter); -}; - -void MockServiceWorkerResponseWriter::WriteInfo( - HttpResponseInfoIOBuffer* info_buf, - OnceCompletionCallback callback) { - DCHECK(!expected_writes_.empty()); - ExpectedWrite write = expected_writes_.front(); - EXPECT_TRUE(write.is_info); - if (write.result > 0) { - EXPECT_EQ(write.length, static_cast<size_t>(info_buf->response_data_size)); - info_written_ += info_buf->response_data_size; - } - if (!write.async) { - expected_writes_.pop(); - std::move(callback).Run(write.result); - } else { - pending_callback_ = std::move(callback); - } -} - -void MockServiceWorkerResponseWriter::WriteData( - net::IOBuffer* buf, - int buf_len, - OnceCompletionCallback callback) { - DCHECK(!expected_writes_.empty()); - ExpectedWrite write = expected_writes_.front(); - EXPECT_FALSE(write.is_info); - if (write.result > 0) { - EXPECT_EQ(write.length, static_cast<size_t>(buf_len)); - data_written_ += buf_len; - } - if (!write.async) { - expected_writes_.pop(); - std::move(callback).Run(write.result); - } else { - pending_callback_ = std::move(callback); - } -} - -void MockServiceWorkerResponseWriter::ExpectWriteInfoOk(size_t length, - bool async) { - ExpectWriteInfo(length, async, length); -} - -void MockServiceWorkerResponseWriter::ExpectWriteDataOk(size_t length, - bool async) { - ExpectWriteData(length, async, length); -} - -void MockServiceWorkerResponseWriter::ExpectWriteInfo(size_t length, - bool async, - int result) { - DCHECK_NE(net::ERR_IO_PENDING, result); - ExpectedWrite expected(true, length, async, result); - expected_writes_.push(expected); -} - -void MockServiceWorkerResponseWriter::ExpectWriteData(size_t length, - bool async, - int result) { - DCHECK_NE(net::ERR_IO_PENDING, result); - ExpectedWrite expected(false, length, async, result); - expected_writes_.push(expected); -} - -void MockServiceWorkerResponseWriter::CompletePendingWrite() { - DCHECK(!expected_writes_.empty()); - ExpectedWrite write = expected_writes_.front(); - DCHECK(write.async); - expected_writes_.pop(); - std::move(pending_callback_).Run(write.result); -} - class ServiceWorkerCacheWriterTest : public ::testing::Test { public: ServiceWorkerCacheWriterTest() {}
diff --git a/content/browser/service_worker/service_worker_database_unittest.cc b/content/browser/service_worker/service_worker_database_unittest.cc index 8b0dca82d..74bc0ee 100644 --- a/content/browser/service_worker/service_worker_database_unittest.cc +++ b/content/browser/service_worker/service_worker_database_unittest.cc
@@ -9,7 +9,6 @@ #include <string> -#include "base/command_line.h" #include "base/files/file_util.h" #include "base/files/scoped_temp_dir.h" #include "base/macros.h" @@ -17,7 +16,6 @@ #include "base/strings/string_number_conversions.h" #include "content/browser/service_worker/service_worker_database.pb.h" #include "content/common/service_worker/service_worker_types.h" -#include "content/public/common/content_switches.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/mojom/service_worker/service_worker_object.mojom.h" @@ -548,11 +546,6 @@ } TEST(ServiceWorkerDatabaseTest, GetAllRegistrations) { - // TODO(https://crbug.com/618076): Remove the following command line switch - // when update_via_cache is shipped to stable. - base::CommandLine::ForCurrentProcess()->AppendSwitch( - switches::kEnableExperimentalWebPlatformFeatures); - std::unique_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory()); std::vector<RegistrationData> registrations; @@ -768,11 +761,6 @@ } TEST(ServiceWorkerDatabaseTest, Registration_Overwrite) { - // TODO(https://crbug.com/618076): Remove the following command line switch - // when update_via_cache is shipped to stable. - base::CommandLine::ForCurrentProcess()->AppendSwitch( - switches::kEnableExperimentalWebPlatformFeatures); - std::unique_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory()); GURL origin("http://example.com");
diff --git a/content/browser/service_worker/service_worker_navigation_loader.cc b/content/browser/service_worker/service_worker_navigation_loader.cc index 3319999..5552d4a 100644 --- a/content/browser/service_worker/service_worker_navigation_loader.cc +++ b/content/browser/service_worker/service_worker_navigation_loader.cc
@@ -416,6 +416,7 @@ if (fetch_result == ServiceWorkerFetchDispatcher::FetchEventResult::kShouldFallback) { + TransitionToStatus(Status::kCompleted); // TODO(falken): Propagate the timing info to the renderer somehow, or else // Navigation Timing etc APIs won't know about service worker. std::move(fallback_callback_)
diff --git a/content/browser/service_worker/service_worker_register_job.cc b/content/browser/service_worker/service_worker_register_job.cc index 969f6b0..c9e9f2f 100644 --- a/content/browser/service_worker/service_worker_register_job.cc +++ b/content/browser/service_worker/service_worker_register_job.cc
@@ -19,6 +19,7 @@ #include "content/browser/service_worker/service_worker_storage.h" #include "content/browser/service_worker/service_worker_version.h" #include "content/browser/service_worker/service_worker_write_to_cache_job.h" +#include "content/browser/url_loader_factory_getter.h" #include "content/common/service_worker/service_worker.mojom.h" #include "content/common/service_worker/service_worker_types.h" #include "content/common/service_worker/service_worker_utils.h" @@ -299,7 +300,9 @@ registration()->GetNewestVersion(); std::vector<ServiceWorkerDatabase::ResourceRecord> resources; version_to_update->script_cache_map()->GetResources(&resources); - update_checker_ = std::make_unique<ServiceWorkerUpdateChecker>(resources); + update_checker_ = std::make_unique<ServiceWorkerUpdateChecker>( + resources, version_to_update, + context_->loader_factory_getter()->GetNetworkFactory()); update_checker_->Start( base::BindOnce(&ServiceWorkerRegisterJob::OnUpdateCheckFinished, weak_factory_.GetWeakPtr()));
diff --git a/content/browser/service_worker/service_worker_single_script_update_checker.cc b/content/browser/service_worker/service_worker_single_script_update_checker.cc index 20a63dea..a08ad96 100644 --- a/content/browser/service_worker/service_worker_single_script_update_checker.cc +++ b/content/browser/service_worker/service_worker_single_script_update_checker.cc
@@ -3,34 +3,142 @@ // found in the LICENSE file. #include "content/browser/service_worker/service_worker_single_script_update_checker.h" -#include "content/browser/service_worker/service_worker_update_checker.h" + +#include "content/browser/appcache/appcache_response.h" +#include "content/browser/service_worker/service_worker_cache_writer.h" +#include "content/public/common/resource_type.h" +#include "mojo/public/cpp/system/simple_watcher.h" +#include "services/network/public/cpp/net_adapters.h" +#include "services/network/public/cpp/shared_url_loader_factory.h" +#include "third_party/blink/public/common/mime_util/mime_util.h" + +// TODO(momohatt): Use ServiceWorkerMetrics for UMA. + +namespace { + +constexpr net::NetworkTrafficAnnotationTag kUpdateCheckTrafficAnnotation = + net::DefineNetworkTrafficAnnotation("service_worker_update_checker", + R"( + semantics { + sender: "ServiceWorker System" + description: + "This request is issued by an update check to fetch the content of " + "the new scripts." + trigger: + "ServiceWorker's update logic, which is triggered by a navigation to a " + "site controlled by a service worker." + data: + "No body. 'Service-Worker: script' header is attached when it's the " + "main worker script. Requests may include cookies and credentials." + destination: WEBSITE + } + policy { + cookies_allowed: YES + cookies_store: "user" + setting: + "Users can control this feature via the 'Cookies' setting under " + "'Privacy, Content settings'. If cookies are disabled for a single " + "site, serviceworkers are disabled for the site only. If they are " + "totally disabled, all serviceworker requests will be stopped." + chrome_policy { + URLBlacklist { + URLBlacklist: { entries: '*' } + } + } + chrome_policy { + URLWhitelist { + URLWhitelist { } + } + } + } + comments: + "Chrome would be unable to update service workers without this type of " + "request. Using either URLBlacklist or URLWhitelist policies (or a " + "combination of both) limits the scope of these requests." + )"); + +} // namespace namespace content { ServiceWorkerSingleScriptUpdateChecker::ServiceWorkerSingleScriptUpdateChecker( - const GURL script_url, - int64_t resource_id, - ServiceWorkerUpdateChecker* owner) - : owner_(owner) { - NOTIMPLEMENTED(); + const GURL& url, + bool is_main_script, + scoped_refptr<network::SharedURLLoaderFactory> loader_factory, + std::unique_ptr<ServiceWorkerResponseReader> compare_reader, + std::unique_ptr<ServiceWorkerResponseReader> copy_reader, + std::unique_ptr<ServiceWorkerResponseWriter> writer, + ResultCallback callback) + : network_client_binding_(this), + network_watcher_(FROM_HERE, + mojo::SimpleWatcher::ArmingPolicy::MANUAL, + base::SequencedTaskRunnerHandle::Get()), + callback_(std::move(callback)), + weak_factory_(this) { + network::ResourceRequest resource_request; + resource_request.url = url; + resource_request.resource_type = + is_main_script ? RESOURCE_TYPE_SERVICE_WORKER : RESOURCE_TYPE_SCRIPT; + resource_request.do_not_prompt_for_login = true; + if (is_main_script) + resource_request.headers.SetHeader("Service-Worker", "script"); + + // TODO(momohatt): Handle cases where force_bypass_cache is enabled. + + // |compare_reader| shouldn't be a nullptr, which forces + // ServiceWorkerCacheWriter to do the comparison. + DCHECK(compare_reader); + cache_writer_ = std::make_unique<ServiceWorkerCacheWriter>( + std::move(compare_reader), std::move(copy_reader), std::move(writer), + true /* pause_when_not_identical */); + + network::mojom::URLLoaderClientPtr network_client; + network_client_binding_.Bind(mojo::MakeRequest(&network_client)); + + loader_factory->CreateLoaderAndStart( + mojo::MakeRequest(&network_loader_), -1 /* routing_id */, + -1 /* request_id */, network::mojom::kURLLoadOptionNone, resource_request, + std::move(network_client), + net::MutableNetworkTrafficAnnotationTag(kUpdateCheckTrafficAnnotation)); + DCHECK_EQ(NetworkLoaderState::kNotStarted, network_loader_state_); + network_loader_state_ = NetworkLoaderState::kLoadingHeader; } ServiceWorkerSingleScriptUpdateChecker:: ~ServiceWorkerSingleScriptUpdateChecker() = default; -void ServiceWorkerSingleScriptUpdateChecker::Start() { - CommitCompleted(true /* is_script_changed */); -} - // URLLoaderClient override ---------------------------------------------------- + void ServiceWorkerSingleScriptUpdateChecker::OnReceiveResponse( const network::ResourceResponseHead& response_head) { - NOTIMPLEMENTED(); + DCHECK_EQ(NetworkLoaderState::kLoadingHeader, network_loader_state_); + + // We don't have complete info here, but fill in what we have now. + // At least we need headers and SSL info. + auto response_info = std::make_unique<net::HttpResponseInfo>(); + response_info->headers = response_head.headers; + if (response_head.ssl_info.has_value()) + response_info->ssl_info = *response_head.ssl_info; + response_info->was_fetched_via_spdy = response_head.was_fetched_via_spdy; + response_info->was_alpn_negotiated = response_head.was_alpn_negotiated; + response_info->alpn_negotiated_protocol = + response_head.alpn_negotiated_protocol; + response_info->connection_info = response_head.connection_info; + response_info->socket_address = response_head.socket_address; + + // TODO(momohatt): Check for header errors. + + network_loader_state_ = NetworkLoaderState::kWaitingForBody; + + WriteHeaders( + base::MakeRefCounted<HttpResponseInfoIOBuffer>(std::move(response_info))); } void ServiceWorkerSingleScriptUpdateChecker::OnReceiveRedirect( const net::RedirectInfo& redirect_info, const network::ResourceResponseHead& response_head) { + // TODO(momohatt): Raise error and terminate the update check here, like + // ServiceWorkerNewScriptLoader does. NOTIMPLEMENTED(); } @@ -38,13 +146,12 @@ int64_t current_position, int64_t total_size, OnUploadProgressCallback ack_callback) { - NOTIMPLEMENTED(); + // The network request for update checking shouldn't have upload data. + NOTREACHED(); } void ServiceWorkerSingleScriptUpdateChecker::OnReceiveCachedMetadata( - const std::vector<uint8_t>& data) { - NOTIMPLEMENTED(); -} + const std::vector<uint8_t>& data) {} void ServiceWorkerSingleScriptUpdateChecker::OnTransferSizeUpdated( int32_t transfer_size_diff) { @@ -53,18 +160,226 @@ void ServiceWorkerSingleScriptUpdateChecker::OnStartLoadingResponseBody( mojo::ScopedDataPipeConsumerHandle consumer) { - NOTIMPLEMENTED(); + DCHECK_EQ(NetworkLoaderState::kWaitingForBody, network_loader_state_); + + network_consumer_ = std::move(consumer); + network_loader_state_ = NetworkLoaderState::kLoadingBody; + MaybeStartNetworkConsumerHandleWatcher(); } void ServiceWorkerSingleScriptUpdateChecker::OnComplete( const network::URLLoaderCompletionStatus& status) { - NOTIMPLEMENTED(); + NetworkLoaderState previous_loader_state = network_loader_state_; + network_loader_state_ = NetworkLoaderState::kCompleted; + if (status.error_code != net::OK) { + Finish(false /* is_script_changed */); + return; + } + + DCHECK(previous_loader_state == NetworkLoaderState::kWaitingForBody || + previous_loader_state == NetworkLoaderState::kLoadingBody); + + // Response body is empty. + if (previous_loader_state == NetworkLoaderState::kWaitingForBody) { + DCHECK_EQ(CacheWriterState::kNotStarted, body_writer_state_); + body_writer_state_ = CacheWriterState::kCompleted; + switch (header_writer_state_) { + case CacheWriterState::kNotStarted: + NOTREACHED() + << "Response header should be received before OnComplete()"; + break; + case CacheWriterState::kWriting: + // Wait until it's written. OnWriteHeadersComplete() will call + // Finish(). + return; + case CacheWriterState::kCompleted: + DCHECK(!network_consumer_.is_valid()); + // Compare the cached data with an empty data to notify |cache_writer_| + // of the end of the comparison. + CompareData(nullptr /* pending_buffer */, 0 /* bytes_available */); + break; + } + } + + // Response body exists. + if (previous_loader_state == NetworkLoaderState::kLoadingBody) { + switch (body_writer_state_) { + case CacheWriterState::kNotStarted: + DCHECK_EQ(CacheWriterState::kWriting, header_writer_state_); + return; + case CacheWriterState::kWriting: + DCHECK_EQ(CacheWriterState::kCompleted, header_writer_state_); + return; + case CacheWriterState::kCompleted: + DCHECK_EQ(CacheWriterState::kCompleted, header_writer_state_); + Finish(false /* is_script_changed */); + return; + } + } } + //------------------------------------------------------------------------------ -void ServiceWorkerSingleScriptUpdateChecker::CommitCompleted( - bool is_script_changed) { - owner_->OnOneUpdateCheckFinished(is_script_changed); +void ServiceWorkerSingleScriptUpdateChecker::WriteHeaders( + scoped_refptr<HttpResponseInfoIOBuffer> info_buffer) { + DCHECK_EQ(CacheWriterState::kNotStarted, header_writer_state_); + header_writer_state_ = CacheWriterState::kWriting; + + // Pass the header to the cache_writer_. This is written to the storage when + // the body had changes. + net::Error error = cache_writer_->MaybeWriteHeaders( + info_buffer.get(), + base::BindOnce( + &ServiceWorkerSingleScriptUpdateChecker::OnWriteHeadersComplete, + weak_factory_.GetWeakPtr())); + if (error == net::ERR_IO_PENDING) { + // OnWriteHeadersComplete() will be called asynchronously. + return; + } + // MaybeWriteHeaders() doesn't run the callback if it finishes synchronously, + // so explicitly call it here. + OnWriteHeadersComplete(error); +} + +void ServiceWorkerSingleScriptUpdateChecker::OnWriteHeadersComplete( + net::Error error) { + DCHECK_EQ(CacheWriterState::kWriting, header_writer_state_); + DCHECK_NE(net::ERR_IO_PENDING, error); + header_writer_state_ = CacheWriterState::kCompleted; + + if (error != net::OK) { + Finish(false /* is_script_changed */); + return; + } + + // Response body is empty. + if (network_loader_state_ == NetworkLoaderState::kCompleted && + body_writer_state_ == CacheWriterState::kCompleted) { + // Compare the cached data with an empty data to notify |cache_writer_| + // the end of the comparison. + CompareData(nullptr /* pending_buffer */, 0 /* bytes_available */); + return; + } + + MaybeStartNetworkConsumerHandleWatcher(); +} + +void ServiceWorkerSingleScriptUpdateChecker:: + MaybeStartNetworkConsumerHandleWatcher() { + if (network_loader_state_ == NetworkLoaderState::kWaitingForBody) { + // OnStartLoadingResponseBody() or OnComplete() will continue the sequence. + return; + } + if (header_writer_state_ != CacheWriterState::kCompleted) { + DCHECK_EQ(CacheWriterState::kWriting, header_writer_state_); + // OnWriteHeadersComplete() will continue the sequence. + return; + } + + DCHECK_EQ(CacheWriterState::kNotStarted, body_writer_state_); + body_writer_state_ = CacheWriterState::kWriting; + + network_watcher_.Watch( + network_consumer_.get(), + MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED, + MOJO_TRIGGER_CONDITION_SIGNALS_SATISFIED, + base::BindRepeating( + &ServiceWorkerSingleScriptUpdateChecker::OnNetworkDataAvailable, + weak_factory_.GetWeakPtr())); + network_watcher_.ArmOrNotify(); +} + +void ServiceWorkerSingleScriptUpdateChecker::OnNetworkDataAvailable( + MojoResult, + const mojo::HandleSignalsState& state) { + DCHECK_EQ(CacheWriterState::kCompleted, header_writer_state_); + DCHECK(network_consumer_.is_valid()); + scoped_refptr<network::MojoToNetPendingBuffer> pending_buffer; + uint32_t bytes_available = 0; + MojoResult result = network::MojoToNetPendingBuffer::BeginRead( + &network_consumer_, &pending_buffer, &bytes_available); + switch (result) { + case MOJO_RESULT_OK: + CompareData(std::move(pending_buffer), bytes_available); + return; + case MOJO_RESULT_FAILED_PRECONDITION: + // Closed by peer. This indicates all the data from the network service + // are read or there is an error. In the error case, the reason is + // notified via OnComplete(). + if (network_loader_state_ == NetworkLoaderState::kCompleted) { + // Compare the cached data with an empty data to notify |cache_writer_| + // the end of the comparison. + CompareData(nullptr /* pending_buffer */, 0 /* bytes_available */); + } + return; + case MOJO_RESULT_SHOULD_WAIT: + network_watcher_.ArmOrNotify(); + return; + } + NOTREACHED() << static_cast<int>(result); +} + +void ServiceWorkerSingleScriptUpdateChecker::CompareData( + scoped_refptr<network::MojoToNetPendingBuffer> pending_buffer, + uint32_t bytes_to_compare) { + auto buffer = base::MakeRefCounted<net::WrappedIOBuffer>( + pending_buffer ? pending_buffer->buffer() : nullptr); + + // Compare the network data and the stored data. + net::Error error = cache_writer_->MaybeWriteData( + buffer.get(), bytes_to_compare, + base::BindOnce( + &ServiceWorkerSingleScriptUpdateChecker::OnCompareDataComplete, + weak_factory_.GetWeakPtr(), + base::WrapRefCounted(pending_buffer.get()), bytes_to_compare)); + + if (pending_buffer) { + pending_buffer->CompleteRead(bytes_to_compare); + network_consumer_ = pending_buffer->ReleaseHandle(); + } + + if (error == net::ERR_IO_PENDING && !cache_writer_->is_pausing()) { + // OnCompareDataComplete() will be called asynchronously. + return; + } + // MaybeWriteData() doesn't run the callback if it finishes synchronously, so + // explicitly call it here. + OnCompareDataComplete(std::move(pending_buffer), bytes_to_compare, error); +} + +void ServiceWorkerSingleScriptUpdateChecker::OnCompareDataComplete( + scoped_refptr<network::MojoToNetPendingBuffer> pending_buffer, + uint32_t bytes_written, + net::Error error) { + if (cache_writer_->is_pausing()) { + // |cache_writer_| can be pausing only when it finds difference between + // stored body and network body. + DCHECK_EQ(net::ERR_IO_PENDING, error); + Finish(true /* is_script_changed */); + return; + } + if (!pending_buffer || error != net::OK) { + Finish(false /* is_script_changed */); + return; + } + DCHECK(pending_buffer); + network_watcher_.ArmOrNotify(); +} + +void ServiceWorkerSingleScriptUpdateChecker::Finish(bool is_script_changed) { + if (is_script_changed) { + // TODO(momohatt): pass the necessary information to the version to update. + } else { + network_loader_.reset(); + network_client_binding_.Close(); + network_consumer_.reset(); + } + network_watcher_.Cancel(); + network_loader_state_ = NetworkLoaderState::kCompleted; + header_writer_state_ = CacheWriterState::kCompleted; + body_writer_state_ = CacheWriterState::kCompleted; + + std::move(callback_).Run(is_script_changed); } } // namespace content
diff --git a/content/browser/service_worker/service_worker_single_script_update_checker.h b/content/browser/service_worker/service_worker_single_script_update_checker.h index 570b1eb3..d006ae26 100644 --- a/content/browser/service_worker/service_worker_single_script_update_checker.h +++ b/content/browser/service_worker/service_worker_single_script_update_checker.h
@@ -5,21 +5,45 @@ #ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_SINGLE_SCRIPT_UPDATE_CHECKER_H_ #define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_SINGLE_SCRIPT_UPDATE_CHECKER_H_ +#include "content/browser/service_worker/service_worker_disk_cache.h" +#include "content/common/content_export.h" +#include "mojo/public/cpp/bindings/binding.h" #include "services/network/public/mojom/url_loader.mojom.h" +namespace network { +class MojoToNetPendingBuffer; +class SharedURLLoaderFactory; +} // namespace network + namespace content { -class ServiceWorkerUpdateChecker; +struct HttpResponseInfoIOBuffer; +class ServiceWorkerCacheWriter; -class ServiceWorkerSingleScriptUpdateChecker +// Executes byte-for-byte update check of one script. This loads the script from +// the network and compares it with the stored counterpart read from +// |compare_reader|. The result will be passed as an argument of |callback|: +// true when they are identical and false otherwise. When |callback| is +// triggered, |cache_writer_| owned by |this| should be paused if the scripts +// were not identical. +class CONTENT_EXPORT ServiceWorkerSingleScriptUpdateChecker : public network::mojom::URLLoaderClient { public: - ServiceWorkerSingleScriptUpdateChecker(const GURL script_url, - int64_t resource_id, - ServiceWorkerUpdateChecker* owner); - ~ServiceWorkerSingleScriptUpdateChecker() override; + using ResultCallback = base::OnceCallback<void(bool)>; - void Start(); + // Both |compare_reader| and |copy_reader| should be created from the same + // resource ID, and this ID should locate where the script specified with + // |url| is stored. |writer| should be created with a new resource ID. + ServiceWorkerSingleScriptUpdateChecker( + const GURL& url, + bool is_main_script, + scoped_refptr<network::SharedURLLoaderFactory> loader_factory, + std::unique_ptr<ServiceWorkerResponseReader> compare_reader, + std::unique_ptr<ServiceWorkerResponseReader> copy_reader, + std::unique_ptr<ServiceWorkerResponseWriter> writer, + ResultCallback callback); + + ~ServiceWorkerSingleScriptUpdateChecker() override; // network::mojom::URLLoaderClient override: void OnReceiveResponse( @@ -37,9 +61,79 @@ void OnComplete(const network::URLLoaderCompletionStatus& status) override; private: - void CommitCompleted(bool is_script_changed); + enum class NetworkLoaderState { + kNotStarted, + kLoadingHeader, + kWaitingForBody, + kLoadingBody, + kCompleted + }; - ServiceWorkerUpdateChecker* owner_; + enum class CacheWriterState { kNotStarted, kWriting, kCompleted }; + + void WriteHeaders(scoped_refptr<HttpResponseInfoIOBuffer> info_buffer); + void OnWriteHeadersComplete(net::Error error); + + void MaybeStartNetworkConsumerHandleWatcher(); + void OnNetworkDataAvailable(MojoResult, + const mojo::HandleSignalsState& state); + void CompareData( + scoped_refptr<network::MojoToNetPendingBuffer> pending_buffer, + uint32_t bytes_available); + void OnCompareDataComplete( + scoped_refptr<network::MojoToNetPendingBuffer> pending_buffer, + uint32_t bytes_written, + net::Error error); + void Finish(bool is_script_changed); + + network::mojom::URLLoaderPtr network_loader_; + mojo::Binding<network::mojom::URLLoaderClient> network_client_binding_; + mojo::ScopedDataPipeConsumerHandle network_consumer_; + mojo::SimpleWatcher network_watcher_; + + std::unique_ptr<ServiceWorkerCacheWriter> cache_writer_; + ResultCallback callback_; + + // Represents the state of |network_loader_|. + // Corresponds to the steps described in the class comments. + // + // When response body exists: + // CreateLoaderAndStart(): kNotStarted -> kLoadingHeader + // OnReceiveResponse(): kLoadingHeader -> kWaitingForBody + // OnStartLoadingResponseBody(): kWaitingForBody -> kLoadingBody + // OnComplete(): kLoadingBody -> kCompleted + // + // When response body is empty: + // CreateLoaderAndStart(): kNotStarted -> kLoadingHeader + // OnReceiveResponse(): kLoadingHeader -> kWaitingForBody + // OnComplete(): kWaitingForBody -> kCompleted + NetworkLoaderState network_loader_state_ = NetworkLoaderState::kNotStarted; + + // Represents the state of |cache_writer_|. + // Set to kWriting when it starts to send the header to |cache_writer_|, and + // set to kCompleted when the header has been sent. + // + // OnReceiveResponse(): kNotStarted -> kWriting (in WriteHeaders()) + // OnWriteHeadersComplete(): kWriting -> kCompleted + CacheWriterState header_writer_state_ = CacheWriterState::kNotStarted; + + // Represents the state of |cache_writer_| and |network_consumer_|. + // Set to kWriting when |this| starts watching |network_consumer_|, and set to + // kCompleted when |cache_writer_| reports any difference between the stored + // body and the network body, or the entire body is compared without any + // difference. + // + // When response body exists: + // OnStartLoadingResponseBody() && OnWriteHeadersComplete(): + // kNotStarted -> kWriting + // OnNetworkDataAvailable() && MOJO_RESULT_FAILED_PRECONDITION: + // kWriting -> kCompleted + // + // When response body is empty: + // OnComplete(): kNotStarted -> kCompleted + CacheWriterState body_writer_state_ = CacheWriterState::kNotStarted; + + base::WeakPtrFactory<ServiceWorkerSingleScriptUpdateChecker> weak_factory_; }; } // namespace content
diff --git a/content/browser/service_worker/service_worker_single_script_update_checker_unittest.cc b/content/browser/service_worker/service_worker_single_script_update_checker_unittest.cc new file mode 100644 index 0000000..cc2188cd --- /dev/null +++ b/content/browser/service_worker/service_worker_single_script_update_checker_unittest.cc
@@ -0,0 +1,288 @@ +// 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/service_worker/service_worker_single_script_update_checker.h" + +#include <vector> +#include "base/containers/queue.h" +#include "base/run_loop.h" +#include "content/browser/service_worker/embedded_worker_test_helper.h" +#include "content/browser/service_worker/service_worker_context_core.h" +#include "content/browser/service_worker/service_worker_storage.h" +#include "content/browser/service_worker/service_worker_test_utils.h" +#include "content/public/test/test_browser_thread_bundle.h" +#include "net/http/http_util.h" +#include "services/network/test/test_url_loader_factory.h" + +namespace content { +namespace { + +constexpr char kScriptURL[] = "https://example.com/script.js"; +constexpr char kSuccessHeader[] = + "HTTP/1.1 200 OK\n" + "Content-Type: text/javascript\n\n"; + +class ServiceWorkerSingleScriptUpdateCheckerTest : public testing::Test { + public: + ServiceWorkerSingleScriptUpdateCheckerTest() + : thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP) {} + ~ServiceWorkerSingleScriptUpdateCheckerTest() override = default; + + ServiceWorkerStorage* storage() { return helper_->context()->storage(); } + + void SetUp() override { + helper_ = std::make_unique<EmbeddedWorkerTestHelper>(base::FilePath()); + base::RunLoop run_loop; + storage()->LazyInitializeForTest(run_loop.QuitClosure()); + run_loop.Run(); + } + + size_t TotalBytes(const std::vector<std::string>& data_chunks) { + size_t bytes = 0; + for (const auto& data : data_chunks) + bytes += data.size(); + return bytes; + } + + std::unique_ptr<ServiceWorkerSingleScriptUpdateChecker> + CreateSingleScriptUpdateChecker( + const char* url, + std::unique_ptr<ServiceWorkerResponseReader> compare_reader, + std::unique_ptr<ServiceWorkerResponseReader> copy_reader, + std::unique_ptr<ServiceWorkerResponseWriter> writer, + network::TestURLLoaderFactory* loader_factory, + base::Optional<bool>* out_script_changed) { + helper_->SetNetworkFactory(loader_factory); + return std::make_unique<ServiceWorkerSingleScriptUpdateChecker>( + GURL(url), true /* is_main_script */, + helper_->url_loader_factory_getter()->GetNetworkFactory(), + std::move(compare_reader), std::move(copy_reader), std::move(writer), + base::BindOnce( + [](base::Optional<bool>* out_script_changed, bool script_changed) { + *out_script_changed = script_changed; + }, + out_script_changed)); + } + + std::unique_ptr<network::TestURLLoaderFactory> CreateLoaderFactoryWithRespone( + const GURL& url, + std::string header, + std::string body, + net::Error error) { + auto loader_factory = std::make_unique<network::TestURLLoaderFactory>(); + network::ResourceResponseHead head; + head.headers = base::MakeRefCounted<net::HttpResponseHeaders>( + net::HttpUtil::AssembleRawHeaders(header.c_str(), header.size())); + network::URLLoaderCompletionStatus status(error); + status.decoded_body_length = body.size(); + loader_factory->AddResponse(url, head, body, status); + return loader_factory; + } + + protected: + TestBrowserThreadBundle thread_bundle_; + std::unique_ptr<EmbeddedWorkerTestHelper> helper_; + + private: + DISALLOW_COPY_AND_ASSIGN(ServiceWorkerSingleScriptUpdateCheckerTest); +}; + +TEST_F(ServiceWorkerSingleScriptUpdateCheckerTest, Identical_SingleSyncRead) { + // Response body from the network. + const std::string body_from_net("abcdef"); + + // Stored data for |kScriptURL|. + const std::vector<std::string> body_from_storage{body_from_net}; + + std::unique_ptr<network::TestURLLoaderFactory> loader_factory = + CreateLoaderFactoryWithRespone(GURL(kScriptURL), kSuccessHeader, + body_from_net, net::OK); + + auto compare_reader = std::make_unique<MockServiceWorkerResponseReader>(); + auto copy_reader = std::make_unique<MockServiceWorkerResponseReader>(); + auto writer = std::make_unique<MockServiceWorkerResponseWriter>(); + MockServiceWorkerResponseReader* compare_reader_rawptr = compare_reader.get(); + compare_reader->ExpectReadOk(body_from_storage, TotalBytes(body_from_storage), + false /* async */); + + base::Optional<bool> script_changed; + std::unique_ptr<ServiceWorkerSingleScriptUpdateChecker> checker = + CreateSingleScriptUpdateChecker(kScriptURL, std::move(compare_reader), + std::move(copy_reader), std::move(writer), + loader_factory.get(), &script_changed); + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(script_changed.has_value()); + EXPECT_FALSE(script_changed.value()); + EXPECT_TRUE(compare_reader_rawptr->AllExpectedReadsDone()); +} + +TEST_F(ServiceWorkerSingleScriptUpdateCheckerTest, Different_SingleSyncRead) { + // Response body from the network. + const std::string body_from_net("abcdef"); + + // Stored data for |kScriptURL|. + const std::vector<std::string> body_from_storage{"abxx"}; + + std::unique_ptr<network::TestURLLoaderFactory> loader_factory = + CreateLoaderFactoryWithRespone(GURL(kScriptURL), kSuccessHeader, + body_from_net, net::OK); + + auto compare_reader = std::make_unique<MockServiceWorkerResponseReader>(); + auto copy_reader = std::make_unique<MockServiceWorkerResponseReader>(); + auto writer = std::make_unique<MockServiceWorkerResponseWriter>(); + MockServiceWorkerResponseReader* compare_reader_rawptr = compare_reader.get(); + compare_reader->ExpectReadOk(body_from_storage, TotalBytes(body_from_storage), + false /* async */); + + base::Optional<bool> script_changed; + std::unique_ptr<ServiceWorkerSingleScriptUpdateChecker> checker = + CreateSingleScriptUpdateChecker(kScriptURL, std::move(compare_reader), + std::move(copy_reader), std::move(writer), + loader_factory.get(), &script_changed); + + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(script_changed.has_value()); + EXPECT_TRUE(script_changed.value()); + EXPECT_TRUE(compare_reader_rawptr->AllExpectedReadsDone()); +} + +TEST_F(ServiceWorkerSingleScriptUpdateCheckerTest, Different_MultipleSyncRead) { + // Response body from the network. + const std::string body_from_net("abcdef"); + + // Stored data for |kScriptURL| (the data for compare reader). + // The comparison should stop in the second block of data. + const std::vector<std::string> body_from_storage{"ab", "cx"}; + + std::unique_ptr<network::TestURLLoaderFactory> loader_factory = + CreateLoaderFactoryWithRespone(GURL(kScriptURL), kSuccessHeader, + body_from_net, net::OK); + + auto compare_reader = std::make_unique<MockServiceWorkerResponseReader>(); + auto copy_reader = std::make_unique<MockServiceWorkerResponseReader>(); + auto writer = std::make_unique<MockServiceWorkerResponseWriter>(); + MockServiceWorkerResponseReader* compare_reader_rawptr = compare_reader.get(); + compare_reader->ExpectReadOk(body_from_storage, TotalBytes(body_from_storage), + false /* async */); + + base::Optional<bool> script_changed; + std::unique_ptr<ServiceWorkerSingleScriptUpdateChecker> checker = + CreateSingleScriptUpdateChecker(kScriptURL, std::move(compare_reader), + std::move(copy_reader), std::move(writer), + loader_factory.get(), &script_changed); + + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(script_changed.has_value()); + EXPECT_TRUE(script_changed.value()); + EXPECT_TRUE(compare_reader_rawptr->AllExpectedReadsDone()); +} + +TEST_F(ServiceWorkerSingleScriptUpdateCheckerTest, NetworkDataLong_SyncRead) { + // Response body from the network. + const std::string body_from_net("abcdef"); + + // Stored data for |kScriptURL| (the data for compare reader). + const std::vector<std::string> body_from_storage{"ab", "cd", ""}; + + std::unique_ptr<network::TestURLLoaderFactory> loader_factory = + CreateLoaderFactoryWithRespone(GURL(kScriptURL), kSuccessHeader, + body_from_net, net::OK); + + auto compare_reader = std::make_unique<MockServiceWorkerResponseReader>(); + auto copy_reader = std::make_unique<MockServiceWorkerResponseReader>(); + auto writer = std::make_unique<MockServiceWorkerResponseWriter>(); + MockServiceWorkerResponseReader* compare_reader_rawptr = compare_reader.get(); + compare_reader->ExpectReadOk(body_from_storage, TotalBytes(body_from_storage), + false /* async */); + + base::Optional<bool> script_changed; + std::unique_ptr<ServiceWorkerSingleScriptUpdateChecker> checker = + CreateSingleScriptUpdateChecker(kScriptURL, std::move(compare_reader), + std::move(copy_reader), std::move(writer), + loader_factory.get(), &script_changed); + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(script_changed.has_value()); + EXPECT_TRUE(script_changed.value()); + EXPECT_TRUE(compare_reader_rawptr->AllExpectedReadsDone()); +} + +TEST_F(ServiceWorkerSingleScriptUpdateCheckerTest, NetworkDataShort_SyncRead) { + // Response body from the network. + const std::string body_from_net("abcdef"); + + // Stored data for |kScriptURL| (the data for compare reader). + const std::vector<std::string> body_in_storage{"ab", "cd", "ef", "gh"}; + + // Stored data that will actually be read from the compare reader. + // The last 2 bytes of |body_in_storage| won't be read. + const std::vector<std::string> body_read_from_storage{"ab", "cd", "ef"}; + + std::unique_ptr<network::TestURLLoaderFactory> loader_factory = + CreateLoaderFactoryWithRespone(GURL(kScriptURL), kSuccessHeader, + body_from_net, net::OK); + + auto compare_reader = std::make_unique<MockServiceWorkerResponseReader>(); + auto copy_reader = std::make_unique<MockServiceWorkerResponseReader>(); + auto writer = std::make_unique<MockServiceWorkerResponseWriter>(); + MockServiceWorkerResponseReader* compare_reader_rawptr = compare_reader.get(); + compare_reader->ExpectReadOk(body_read_from_storage, + TotalBytes(body_in_storage), false /* async */); + + base::Optional<bool> script_changed; + std::unique_ptr<ServiceWorkerSingleScriptUpdateChecker> checker = + CreateSingleScriptUpdateChecker(kScriptURL, std::move(compare_reader), + std::move(copy_reader), std::move(writer), + loader_factory.get(), &script_changed); + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(script_changed.has_value()); + EXPECT_TRUE(script_changed.value()); + EXPECT_TRUE(compare_reader_rawptr->AllExpectedReadsDone()); +} + +TEST_F(ServiceWorkerSingleScriptUpdateCheckerTest, Identical_SingleAsyncRead) { + // Response body from the network. + const std::string body_from_net("abcdef"); + + // Stored data for |kScriptURL| (the data for compare reader). + const std::vector<std::string> body_from_storage{body_from_net}; + + std::unique_ptr<network::TestURLLoaderFactory> loader_factory = + CreateLoaderFactoryWithRespone(GURL(kScriptURL), kSuccessHeader, + body_from_net, net::OK); + + auto compare_reader = std::make_unique<MockServiceWorkerResponseReader>(); + auto copy_reader = std::make_unique<MockServiceWorkerResponseReader>(); + auto writer = std::make_unique<MockServiceWorkerResponseWriter>(); + MockServiceWorkerResponseReader* compare_reader_rawptr = compare_reader.get(); + compare_reader->ExpectReadOk(body_from_storage, TotalBytes(body_from_storage), + true /* async */); + + base::Optional<bool> script_changed; + std::unique_ptr<ServiceWorkerSingleScriptUpdateChecker> checker = + CreateSingleScriptUpdateChecker(kScriptURL, std::move(compare_reader), + std::move(copy_reader), std::move(writer), + loader_factory.get(), &script_changed); + + // Update check stops in WriteHeader() due to the asynchronous read of the + // |compare_reader|. + base::RunLoop().RunUntilIdle(); + EXPECT_FALSE(script_changed.has_value()); + + // Continue the update check and trigger OnWriteHeadersComplete(). The resumed + // update check stops again at CompareData(). + compare_reader_rawptr->CompletePendingRead(); + base::RunLoop().RunUntilIdle(); + EXPECT_FALSE(script_changed.has_value()); + + // Continue the update check and trigger OnCompareDataComplete(). This will + // finish the entire update check. + compare_reader_rawptr->CompletePendingRead(); + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(script_changed.has_value()); + EXPECT_FALSE(script_changed.value()); + EXPECT_TRUE(compare_reader_rawptr->AllExpectedReadsDone()); +} + +} // namespace +} // namespace content
diff --git a/content/browser/service_worker/service_worker_test_utils.cc b/content/browser/service_worker/service_worker_test_utils.cc index 05e9cb7..344734b 100644 --- a/content/browser/service_worker/service_worker_test_utils.cc +++ b/content/browser/service_worker/service_worker_test_utils.cc
@@ -281,4 +281,178 @@ body.size()); } +MockServiceWorkerResponseReader::MockServiceWorkerResponseReader() + : ServiceWorkerResponseReader(0 /* resource_id */, + base::WeakPtr<AppCacheDiskCacheInterface>()) { +} + +MockServiceWorkerResponseReader::~MockServiceWorkerResponseReader() {} + +void MockServiceWorkerResponseReader::ReadInfo( + HttpResponseInfoIOBuffer* info_buf, + OnceCompletionCallback callback) { + DCHECK(!expected_reads_.empty()); + ExpectedRead expected = expected_reads_.front(); + EXPECT_TRUE(expected.info); + if (expected.async) { + pending_info_ = info_buf; + pending_callback_ = std::move(callback); + } else { + expected_reads_.pop(); + info_buf->response_data_size = expected.len; + std::move(callback).Run(expected.result); + } +} + +void MockServiceWorkerResponseReader::ReadData( + net::IOBuffer* buf, + int buf_len, + OnceCompletionCallback callback) { + DCHECK(!expected_reads_.empty()); + ExpectedRead expected = expected_reads_.front(); + EXPECT_FALSE(expected.info); + if (expected.async) { + pending_callback_ = std::move(callback); + pending_buffer_ = buf; + pending_buffer_len_ = static_cast<size_t>(buf_len); + } else { + expected_reads_.pop(); + if (expected.len > 0) { + size_t to_read = std::min(static_cast<size_t>(buf_len), expected.len); + memcpy(buf->data(), expected.data, to_read); + } + std::move(callback).Run(expected.result); + } +} + +void MockServiceWorkerResponseReader::ExpectReadInfo(size_t len, + bool async, + int result) { + expected_reads_.push(ExpectedRead(len, async, result)); +} + +void MockServiceWorkerResponseReader::ExpectReadInfoOk(size_t len, bool async) { + expected_reads_.push(ExpectedRead(len, async, len)); +} + +void MockServiceWorkerResponseReader::ExpectReadData(const char* data, + size_t len, + bool async, + int result) { + expected_reads_.push(ExpectedRead(data, len, async, result)); +} + +void MockServiceWorkerResponseReader::ExpectReadDataOk(const std::string& data, + bool async) { + expected_reads_.push( + ExpectedRead(data.data(), data.size(), async, data.size())); +} + +void MockServiceWorkerResponseReader::ExpectReadOk( + const std::vector<std::string>& stored_data, + const size_t bytes_stored, + const bool async) { + ExpectReadInfoOk(bytes_stored, async); + for (const auto& data : stored_data) + ExpectReadDataOk(data, async); +} + +void MockServiceWorkerResponseReader::CompletePendingRead() { + DCHECK(!expected_reads_.empty()); + ExpectedRead expected = expected_reads_.front(); + expected_reads_.pop(); + EXPECT_TRUE(expected.async); + if (expected.info) { + pending_info_->response_data_size = expected.len; + } else { + size_t to_read = std::min(pending_buffer_len_, expected.len); + if (to_read > 0) + memcpy(pending_buffer_->data(), expected.data, to_read); + } + pending_info_ = nullptr; + pending_buffer_ = nullptr; + OnceCompletionCallback callback = std::move(pending_callback_); + pending_callback_.Reset(); + std::move(callback).Run(expected.result); +} + +MockServiceWorkerResponseWriter::MockServiceWorkerResponseWriter() + : ServiceWorkerResponseWriter(0 /* resource_id */, + base::WeakPtr<AppCacheDiskCacheInterface>()), + info_written_(0), + data_written_(0) {} + +MockServiceWorkerResponseWriter::~MockServiceWorkerResponseWriter() = default; + +void MockServiceWorkerResponseWriter::WriteInfo( + HttpResponseInfoIOBuffer* info_buf, + OnceCompletionCallback callback) { + DCHECK(!expected_writes_.empty()); + ExpectedWrite write = expected_writes_.front(); + EXPECT_TRUE(write.is_info); + if (write.result > 0) { + EXPECT_EQ(write.length, static_cast<size_t>(info_buf->response_data_size)); + info_written_ += info_buf->response_data_size; + } + if (!write.async) { + expected_writes_.pop(); + std::move(callback).Run(write.result); + } else { + pending_callback_ = std::move(callback); + } +} + +void MockServiceWorkerResponseWriter::WriteData( + net::IOBuffer* buf, + int buf_len, + OnceCompletionCallback callback) { + DCHECK(!expected_writes_.empty()); + ExpectedWrite write = expected_writes_.front(); + EXPECT_FALSE(write.is_info); + if (write.result > 0) { + EXPECT_EQ(write.length, static_cast<size_t>(buf_len)); + data_written_ += buf_len; + } + if (!write.async) { + expected_writes_.pop(); + std::move(callback).Run(write.result); + } else { + pending_callback_ = std::move(callback); + } +} + +void MockServiceWorkerResponseWriter::ExpectWriteInfoOk(size_t length, + bool async) { + ExpectWriteInfo(length, async, length); +} + +void MockServiceWorkerResponseWriter::ExpectWriteDataOk(size_t length, + bool async) { + ExpectWriteData(length, async, length); +} + +void MockServiceWorkerResponseWriter::ExpectWriteInfo(size_t length, + bool async, + int result) { + DCHECK_NE(net::ERR_IO_PENDING, result); + ExpectedWrite expected(true, length, async, result); + expected_writes_.push(expected); +} + +void MockServiceWorkerResponseWriter::ExpectWriteData(size_t length, + bool async, + int result) { + DCHECK_NE(net::ERR_IO_PENDING, result); + ExpectedWrite expected(false, length, async, result); + expected_writes_.push(expected); +} + +void MockServiceWorkerResponseWriter::CompletePendingWrite() { + DCHECK(!expected_writes_.empty()); + ExpectedWrite write = expected_writes_.front(); + DCHECK(write.async); + expected_writes_.pop(); + std::move(pending_callback_).Run(write.result); +} + } // namespace content
diff --git a/content/browser/service_worker/service_worker_test_utils.h b/content/browser/service_worker/service_worker_test_utils.h index dba5946..aa81bbf 100644 --- a/content/browser/service_worker/service_worker_test_utils.h +++ b/content/browser/service_worker/service_worker_test_utils.h
@@ -13,6 +13,7 @@ #include "base/memory/weak_ptr.h" #include "base/task/post_task.h" #include "content/browser/service_worker/service_worker_database.h" +#include "content/browser/service_worker/service_worker_disk_cache.h" #include "content/common/service_worker/service_worker_provider.mojom.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" @@ -165,6 +166,154 @@ const std::string& meta_data, base::OnceClosure callback); +// A test implementation of ServiceWorkerResponseReader. +// +// This class exposes the ability to expect reads (see ExpectRead*() below). +// Each call to ReadInfo() or ReadData() consumes another expected read, in the +// order those reads were expected, so: +// reader->ExpectReadInfoOk(5, false); +// reader->ExpectReadDataOk("abcdef", false); +// reader->ExpectReadDataOk("ghijkl", false); +// Expects these calls, in this order: +// reader->ReadInfo(...); // reader writes 5 into +// // |info_buf->response_data_size| +// reader->ReadData(...); // reader writes "abcdef" into |buf| +// reader->ReadData(...); // reader writes "ghijkl" into |buf| +// If an unexpected call happens, this class DCHECKs. +// If an expected read is marked "async", it will not complete immediately, but +// must be completed by the test using CompletePendingRead(). +// These is a convenience method AllExpectedReadsDone() which returns whether +// there are any expected reads that have not yet happened. +class MockServiceWorkerResponseReader : public ServiceWorkerResponseReader { + public: + MockServiceWorkerResponseReader(); + ~MockServiceWorkerResponseReader() override; + + // ServiceWorkerResponseReader overrides + void ReadInfo(HttpResponseInfoIOBuffer* info_buf, + OnceCompletionCallback callback) override; + void ReadData(net::IOBuffer* buf, + int buf_len, + OnceCompletionCallback callback) override; + + // Test helpers. ExpectReadInfo() and ExpectReadData() give precise control + // over both the data to be written and the result to return. + // ExpectReadInfoOk() and ExpectReadDataOk() are convenience functions for + // expecting successful reads, which always have their length as their result. + + // Expect a call to ReadInfo() on this reader. For these functions, |len| will + // be used as |response_data_size|, not as the length of this particular read. + void ExpectReadInfo(size_t len, bool async, int result); + void ExpectReadInfoOk(size_t len, bool async); + + // Expect a call to ReadData() on this reader. For these functions, |len| is + // the length of the data to be written back; in ExpectReadDataOk(), |len| is + // implicitly the length of |data|. + void ExpectReadData(const char* data, size_t len, bool async, int result); + void ExpectReadDataOk(const std::string& data, bool async); + + // Convenient method for calling ExpectReadInfoOk() with the length being + // |bytes_stored|, and ExpectReadDataOk() for each element of |stored_data|. + void ExpectReadOk(const std::vector<std::string>& stored_data, + const size_t bytes_stored, + const bool async); + + // Complete a pending async read. It is an error to call this function without + // a pending async read (ie, a previous call to ReadInfo() or ReadData() + // having not run its callback yet). + void CompletePendingRead(); + + // Returns whether all expected reads have occurred. + bool AllExpectedReadsDone() { return expected_reads_.size() == 0; } + + private: + struct ExpectedRead { + ExpectedRead(size_t len, bool async, int result) + : data(nullptr), len(len), info(true), async(async), result(result) {} + ExpectedRead(const char* data, size_t len, bool async, int result) + : data(data), len(len), info(false), async(async), result(result) {} + const char* data; + size_t len; + bool info; + bool async; + int result; + }; + + base::queue<ExpectedRead> expected_reads_; + scoped_refptr<net::IOBuffer> pending_buffer_; + size_t pending_buffer_len_; + scoped_refptr<HttpResponseInfoIOBuffer> pending_info_; + OnceCompletionCallback pending_callback_; + + DISALLOW_COPY_AND_ASSIGN(MockServiceWorkerResponseReader); +}; + +// A test implementation of ServiceWorkerResponseWriter. +// +// This class exposes the ability to expect writes (see ExpectWrite*Ok() below). +// Each write to this class via WriteInfo() or WriteData() consumes another +// expected write, in the order they were added, so: +// writer->ExpectWriteInfoOk(5, false); +// writer->ExpectWriteDataOk(6, false); +// writer->ExpectWriteDataOk(6, false); +// Expects these calls, in this order: +// writer->WriteInfo(...); // checks that |buf->response_data_size| == 5 +// writer->WriteData(...); // checks that 6 bytes are being written +// writer->WriteData(...); // checks that another 6 bytes are being written +// If this class receives an unexpected call to WriteInfo() or WriteData(), it +// DCHECKs. +// Expected writes marked async do not complete synchronously, but rather return +// without running their callback and need to be completed with +// CompletePendingWrite(). +// A convenience method AllExpectedWritesDone() is exposed so tests can ensure +// that all expected writes have been consumed by matching calls to WriteInfo() +// or WriteData(). +class MockServiceWorkerResponseWriter : public ServiceWorkerResponseWriter { + public: + MockServiceWorkerResponseWriter(); + ~MockServiceWorkerResponseWriter() override; + + // ServiceWorkerResponseWriter overrides + void WriteInfo(HttpResponseInfoIOBuffer* info_buf, + OnceCompletionCallback callback) override; + void WriteData(net::IOBuffer* buf, + int buf_len, + OnceCompletionCallback callback) override; + + // Enqueue expected writes. + void ExpectWriteInfoOk(size_t len, bool async); + void ExpectWriteInfo(size_t len, bool async, int result); + void ExpectWriteDataOk(size_t len, bool async); + void ExpectWriteData(size_t len, bool async, int result); + + // Complete a pending asynchronous write. This method DCHECKs unless there is + // a pending write (a write for which WriteInfo() or WriteData() has been + // called but the callback has not yet been run). + void CompletePendingWrite(); + + // Returns whether all expected reads have been consumed. + bool AllExpectedWritesDone() { return expected_writes_.size() == 0; } + + private: + struct ExpectedWrite { + ExpectedWrite(bool is_info, size_t length, bool async, int result) + : is_info(is_info), length(length), async(async), result(result) {} + bool is_info; + size_t length; + bool async; + int result; + }; + + base::queue<ExpectedWrite> expected_writes_; + + size_t info_written_; + size_t data_written_; + + OnceCompletionCallback pending_callback_; + + DISALLOW_COPY_AND_ASSIGN(MockServiceWorkerResponseWriter); +}; + } // namespace content #endif // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_TEST_UTILS_H_
diff --git a/content/browser/service_worker/service_worker_update_checker.cc b/content/browser/service_worker/service_worker_update_checker.cc index 752e7343..1156b0e4 100644 --- a/content/browser/service_worker/service_worker_update_checker.cc +++ b/content/browser/service_worker/service_worker_update_checker.cc
@@ -4,11 +4,20 @@ #include "content/browser/service_worker/service_worker_update_checker.h" +#include "content/browser/service_worker/service_worker_context_core.h" +#include "content/browser/service_worker/service_worker_storage.h" +#include "content/browser/service_worker/service_worker_version.h" + namespace content { ServiceWorkerUpdateChecker::ServiceWorkerUpdateChecker( - std::vector<ServiceWorkerDatabase::ResourceRecord> scripts_to_compare) - : scripts_to_compare_(std::move(scripts_to_compare)), weak_factory_(this) {} + std::vector<ServiceWorkerDatabase::ResourceRecord> scripts_to_compare, + scoped_refptr<ServiceWorkerVersion> version_to_update, + scoped_refptr<network::SharedURLLoaderFactory> loader_factory) + : scripts_to_compare_(std::move(scripts_to_compare)), + version_to_update_(std::move(version_to_update)), + loader_factory_(std::move(loader_factory)), + weak_factory_(this) {} ServiceWorkerUpdateChecker::~ServiceWorkerUpdateChecker() = default; @@ -45,9 +54,21 @@ DCHECK_NE(kInvalidServiceWorkerResourceId, script.resource_id) << "All the target scripts should be stored in the storage."; + bool is_main_script = script.url == version_to_update_->script_url(); + ServiceWorkerStorage* storage = version_to_update_->context()->storage(); + + // We need two identical readers for comparing and reading the resource for + // |script.resource_id| from the storage. + auto compare_reader = storage->CreateResponseReader(script.resource_id); + auto copy_reader = storage->CreateResponseReader(script.resource_id); + + auto writer = storage->CreateResponseWriter(storage->NewResourceId()); + running_checker_ = std::make_unique<ServiceWorkerSingleScriptUpdateChecker>( - script.url, script.resource_id, this); - running_checker_->Start(); + script.url, is_main_script, loader_factory_, std::move(compare_reader), + std::move(copy_reader), std::move(writer), + base::BindOnce(&ServiceWorkerUpdateChecker::OnOneUpdateCheckFinished, + weak_factory_.GetWeakPtr())); } } // namespace content
diff --git a/content/browser/service_worker/service_worker_update_checker.h b/content/browser/service_worker/service_worker_update_checker.h index 4d7a6877..2bd0b08 100644 --- a/content/browser/service_worker/service_worker_update_checker.h +++ b/content/browser/service_worker/service_worker_update_checker.h
@@ -9,14 +9,22 @@ #include "content/browser/service_worker/service_worker_database.h" #include "content/browser/service_worker/service_worker_single_script_update_checker.h" +namespace network { +class SharedURLLoaderFactory; +} + namespace content { +class ServiceWorkerVersion; + class ServiceWorkerUpdateChecker { public: using UpdateStatusCallback = base::OnceCallback<void(bool)>; ServiceWorkerUpdateChecker( - std::vector<ServiceWorkerDatabase::ResourceRecord> scripts_to_compare); + std::vector<ServiceWorkerDatabase::ResourceRecord> scripts_to_compare, + scoped_refptr<ServiceWorkerVersion> version_to_update, + scoped_refptr<network::SharedURLLoaderFactory> loader_factory); ~ServiceWorkerUpdateChecker(); // |callback| is always triggered when Start() finishes. If the scripts are @@ -32,10 +40,14 @@ std::vector<ServiceWorkerDatabase::ResourceRecord> scripts_to_compare_; size_t scripts_compared_ = 0; + // The version which triggered this update. + scoped_refptr<ServiceWorkerVersion> version_to_update_; + std::unique_ptr<ServiceWorkerSingleScriptUpdateChecker> running_checker_; UpdateStatusCallback callback_; + scoped_refptr<network::SharedURLLoaderFactory> loader_factory_; base::WeakPtrFactory<ServiceWorkerUpdateChecker> weak_factory_; };
diff --git a/content/browser/web_package/signed_exchange_request_handler_browsertest.cc b/content/browser/web_package/signed_exchange_request_handler_browsertest.cc index bf516f3c4..fd28255 100644 --- a/content/browser/web_package/signed_exchange_request_handler_browsertest.cc +++ b/content/browser/web_package/signed_exchange_request_handler_browsertest.cc
@@ -13,6 +13,7 @@ #include "base/time/time.h" #include "content/browser/frame_host/navigation_handle_impl.h" #include "content/browser/web_package/signed_exchange_handler.h" +#include "content/browser/web_package/signed_exchange_utils.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/navigation_controller.h" @@ -32,13 +33,16 @@ #include "content/shell/browser/shell.h" #include "net/cert/cert_verify_result.h" #include "net/cert/mock_cert_verifier.h" +#include "net/dns/mock_host_resolver.h" #include "net/test/cert_test_util.h" #include "net/test/embedded_test_server/embedded_test_server.h" #include "net/test/embedded_test_server/http_request.h" +#include "net/test/embedded_test_server/http_response.h" #include "net/test/test_data_directory.h" #include "net/test/url_request/url_request_mock_http_job.h" #include "net/url_request/url_request_filter.h" #include "net/url_request/url_request_interceptor.h" +#include "services/network/loader_util.h" #include "services/network/public/cpp/features.h" #include "testing/gmock/include/gmock/gmock-matchers.h" @@ -183,14 +187,6 @@ mock_cert_verifier()->AddResultForCertAndHost( original_cert, "test.example.org", dummy_result, net::OK); - embedded_test_server()->RegisterRequestMonitor( - base::BindRepeating([](const net::test_server::HttpRequest& request) { - if (request.relative_url == "/sxg/test.example.org_test.sxg") { - const auto& accept_value = request.headers.find("accept")->second; - EXPECT_THAT(accept_value, - ::testing::HasSubstr("application/signed-exchange;v=b2")); - } - })); embedded_test_server()->ServeFilesFromSourceDirectory("content/test/data"); ASSERT_TRUE(embedded_test_server()->Start()); GURL url = embedded_test_server()->GetURL("/sxg/test.example.org_test.sxg"); @@ -330,14 +326,6 @@ InstallUrlInterceptor(GURL("https://test.example.org/test/"), "content/test/data/sxg/fallback.html"); - embedded_test_server()->RegisterRequestMonitor( - base::BindRepeating([](const net::test_server::HttpRequest& request) { - if (request.relative_url == "/sxg/test.example.org_test.sxg") { - const auto& accept_value = request.headers.find("accept")->second; - EXPECT_THAT(accept_value, - ::testing::HasSubstr("application/signed-exchange;v=b2")); - } - })); embedded_test_server()->ServeFilesFromSourceDirectory("content/test/data"); ASSERT_TRUE(embedded_test_server()->Start()); GURL url = embedded_test_server()->GetURL("/sxg/test.example.org_test.sxg"); @@ -357,4 +345,190 @@ SignedExchangeLoadResult::kOCSPError, 1); } +struct SignedExchangeAcceptHeaderBrowserTestParam { + SignedExchangeAcceptHeaderBrowserTestParam(bool sxg_enabled, + bool sxg_origin_trial_enabled, + bool sxg_accept_header_enabled) + : sxg_enabled(sxg_enabled), + sxg_origin_trial_enabled(sxg_origin_trial_enabled), + sxg_accept_header_enabled(sxg_accept_header_enabled) {} + const bool sxg_enabled; + const bool sxg_origin_trial_enabled; + const bool sxg_accept_header_enabled; +}; + +class SignedExchangeAcceptHeaderBrowserTest + : public ContentBrowserTest, + public testing::WithParamInterface< + SignedExchangeAcceptHeaderBrowserTestParam> { + public: + using self = SignedExchangeAcceptHeaderBrowserTest; + SignedExchangeAcceptHeaderBrowserTest() + : enabled_https_server_(net::EmbeddedTestServer::TYPE_HTTPS), + disabled_https_server_(net::EmbeddedTestServer::TYPE_HTTPS) {} + ~SignedExchangeAcceptHeaderBrowserTest() override = default; + + protected: + void SetUp() override { + std::vector<base::Feature> enable_features; + if (GetParam().sxg_enabled) + enable_features.push_back(features::kSignedHTTPExchange); + if (GetParam().sxg_origin_trial_enabled) + enable_features.push_back(features::kSignedHTTPExchangeOriginTrial); + feature_list_.InitWithFeatures(enable_features, {}); + + enabled_https_server_.ServeFilesFromSourceDirectory("content/test/data"); + enabled_https_server_.RegisterRequestHandler( + base::BindRepeating(&self::RedirectResponseHandler)); + enabled_https_server_.RegisterRequestMonitor( + base::BindRepeating(&self::MonitorRequest, base::Unretained(this))); + ASSERT_TRUE(enabled_https_server_.Start()); + + disabled_https_server_.ServeFilesFromSourceDirectory("content/test/data"); + disabled_https_server_.RegisterRequestHandler( + base::BindRepeating(&self::RedirectResponseHandler)); + disabled_https_server_.RegisterRequestMonitor( + base::BindRepeating(&self::MonitorRequest, base::Unretained(this))); + ASSERT_TRUE(disabled_https_server_.Start()); + + if (GetParam().sxg_accept_header_enabled) { + std::map<std::string, std::string> feature_parameters; + feature_parameters["OriginsList"] = + base::StringPrintf("127.0.0.1:%u", enabled_https_server_.port()); + feature_list_for_accept_header_.InitAndEnableFeatureWithParameters( + features::kSignedHTTPExchangeAcceptHeader, feature_parameters); + } + ContentBrowserTest::SetUp(); + } + + void NavigateAndWaitForTitle(const GURL& url, const std::string title) { + base::string16 expected_title = base::ASCIIToUTF16(title); + TitleWatcher title_watcher(shell()->web_contents(), expected_title); + NavigateToURL(shell(), url); + EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle()); + } + + bool ShouldHaveSXGAcceptHeaderInEnabledOrigin() { + return GetParam().sxg_enabled || (GetParam().sxg_origin_trial_enabled && + GetParam().sxg_accept_header_enabled); + } + + void CheckNavigationAcceptHeader(const GURL& url, bool should_have_sxg) { + if (should_have_sxg) { + EXPECT_EQ(GetInterceptedAcceptHeader(url), + std::string(network::kFrameAcceptHeader) + + std::string(kAcceptHeaderSignedExchangeSuffix)); + } else { + EXPECT_EQ(GetInterceptedAcceptHeader(url), + std::string(network::kFrameAcceptHeader)); + } + } + + net::EmbeddedTestServer enabled_https_server_; + net::EmbeddedTestServer disabled_https_server_; + + private: + static std::unique_ptr<net::test_server::HttpResponse> + RedirectResponseHandler(const net::test_server::HttpRequest& request) { + if (!base::StartsWith(request.relative_url, "/r?", + base::CompareCase::SENSITIVE)) { + return std::unique_ptr<net::test_server::HttpResponse>(); + } + std::unique_ptr<net::test_server::BasicHttpResponse> http_response( + new net::test_server::BasicHttpResponse); + http_response->set_code(net::HTTP_MOVED_PERMANENTLY); + http_response->AddCustomHeader("Location", request.relative_url.substr(3)); + return std::move(http_response); + } + + void MonitorRequest(const net::test_server::HttpRequest& request) { + const auto it = request.headers.find(std::string(network::kAcceptHeader)); + if (it == request.headers.end()) + return; + url_accept_header_map_[request.base_url.Resolve(request.relative_url)] = + it->second; + } + + std::string GetInterceptedAcceptHeader(const GURL& url) { + return url_accept_header_map_[url]; + } + + base::test::ScopedFeatureList feature_list_; + base::test::ScopedFeatureList feature_list_for_accept_header_; + + std::map<GURL, std::string> url_accept_header_map_; +}; + +IN_PROC_BROWSER_TEST_P(SignedExchangeAcceptHeaderBrowserTest, EnabledOrigin) { + const GURL enabled_test_url = enabled_https_server_.GetURL("/sxg/test.html"); + EXPECT_EQ(ShouldHaveSXGAcceptHeaderInEnabledOrigin(), + signed_exchange_utils::ShouldAdvertiseAcceptHeader( + url::Origin::Create(enabled_test_url))); + NavigateAndWaitForTitle(enabled_test_url, enabled_test_url.spec()); + CheckNavigationAcceptHeader(enabled_test_url, + ShouldHaveSXGAcceptHeaderInEnabledOrigin()); +} + +IN_PROC_BROWSER_TEST_P(SignedExchangeAcceptHeaderBrowserTest, DisabledOrigin) { + const GURL disabled_test_url = + disabled_https_server_.GetURL("/sxg/test.html"); + EXPECT_EQ(GetParam().sxg_enabled, + signed_exchange_utils::ShouldAdvertiseAcceptHeader( + url::Origin::Create(disabled_test_url))); + + NavigateAndWaitForTitle(disabled_test_url, disabled_test_url.spec()); + CheckNavigationAcceptHeader(disabled_test_url, GetParam().sxg_enabled); +} + +IN_PROC_BROWSER_TEST_P(SignedExchangeAcceptHeaderBrowserTest, + RedirectEnabledToDisabledToEnabled) { + const GURL enabled_test_url = enabled_https_server_.GetURL("/sxg/test.html"); + const GURL redirect_disabled_to_enabled_url = + disabled_https_server_.GetURL("/r?" + enabled_test_url.spec()); + const GURL redirect_enabled_to_disabled_to_enabled_url = + enabled_https_server_.GetURL("/r?" + + redirect_disabled_to_enabled_url.spec()); + NavigateAndWaitForTitle(redirect_enabled_to_disabled_to_enabled_url, + enabled_test_url.spec()); + + CheckNavigationAcceptHeader(redirect_enabled_to_disabled_to_enabled_url, + ShouldHaveSXGAcceptHeaderInEnabledOrigin()); + CheckNavigationAcceptHeader(redirect_disabled_to_enabled_url, + GetParam().sxg_enabled); + CheckNavigationAcceptHeader(enabled_test_url, + ShouldHaveSXGAcceptHeaderInEnabledOrigin()); +} + +IN_PROC_BROWSER_TEST_P(SignedExchangeAcceptHeaderBrowserTest, + RedirectDisabledToEnabledToDisabled) { + const GURL disabled_test_url = + disabled_https_server_.GetURL("/sxg/test.html"); + const GURL redirect_enabled_to_disabled_url = + enabled_https_server_.GetURL("/r?" + disabled_test_url.spec()); + const GURL redirect_disabled_to_enabled_to_disabled_url = + disabled_https_server_.GetURL("/r?" + + redirect_enabled_to_disabled_url.spec()); + NavigateAndWaitForTitle(redirect_disabled_to_enabled_to_disabled_url, + disabled_test_url.spec()); + + CheckNavigationAcceptHeader(redirect_disabled_to_enabled_to_disabled_url, + GetParam().sxg_enabled); + CheckNavigationAcceptHeader(redirect_enabled_to_disabled_url, + ShouldHaveSXGAcceptHeaderInEnabledOrigin()); + CheckNavigationAcceptHeader(disabled_test_url, GetParam().sxg_enabled); +} + +INSTANTIATE_TEST_CASE_P( + SignedExchangeAcceptHeaderBrowserTest, + SignedExchangeAcceptHeaderBrowserTest, + testing::Values( + SignedExchangeAcceptHeaderBrowserTestParam(false, false, false), + SignedExchangeAcceptHeaderBrowserTestParam(false, false, true), + SignedExchangeAcceptHeaderBrowserTestParam(false, true, false), + SignedExchangeAcceptHeaderBrowserTestParam(false, true, true), + SignedExchangeAcceptHeaderBrowserTestParam(true, false, false), + SignedExchangeAcceptHeaderBrowserTestParam(true, false, true), + SignedExchangeAcceptHeaderBrowserTestParam(true, true, false), + SignedExchangeAcceptHeaderBrowserTestParam(true, true, true))); + } // namespace content
diff --git a/content/browser/web_package/signed_exchange_utils.cc b/content/browser/web_package/signed_exchange_utils.cc index ed020c6d..a52b7b0 100644 --- a/content/browser/web_package/signed_exchange_utils.cc +++ b/content/browser/web_package/signed_exchange_utils.cc
@@ -48,9 +48,29 @@ } // namespace +bool NeedToCheckRedirectedURLForAcceptHeader() { + // When SignedHTTPExchange is enabled, the SignedExchange accept header must + // be sent to all origins. So we don't need to check the redirected URL. + return !base::FeatureList::IsEnabled(features::kSignedHTTPExchange) && + base::FeatureList::IsEnabled( + features::kSignedHTTPExchangeOriginTrial) && + base::FeatureList::IsEnabled( + features::kSignedHTTPExchangeAcceptHeader); +} + bool ShouldAdvertiseAcceptHeader(const url::Origin& origin) { - if (!base::FeatureList::IsEnabled(features::kSignedHTTPExchangeAcceptHeader)) + // When SignedHTTPExchange is enabled, we must send the SignedExchange accept + // header to all origins. + if (base::FeatureList::IsEnabled(features::kSignedHTTPExchange)) + return true; + // When SignedHTTPExchangeOriginTrial is not enabled or + // SignedHTTPExchangeAcceptHeader is not enabled, we must not send the + // SignedExchange accept header. + if (!base::FeatureList::IsEnabled(features::kSignedHTTPExchangeOriginTrial) || + !base::FeatureList::IsEnabled( + features::kSignedHTTPExchangeAcceptHeader)) { return false; + } // |origins_list| is initialized in a thread-safe manner. // Querying OriginsList::Match() should be safe since it's read-only access.
diff --git a/content/browser/web_package/signed_exchange_utils.h b/content/browser/web_package/signed_exchange_utils.h index 80c5171..bbcad0a 100644 --- a/content/browser/web_package/signed_exchange_utils.h +++ b/content/browser/web_package/signed_exchange_utils.h
@@ -38,9 +38,14 @@ base::Optional<SignedExchangeError::FieldIndexPair> error_field = base::nullopt); +// Returns true when SignedHTTPExchange feature is NOT enabled and +// SignedHTTPExchangeOriginTrial and SignedHTTPExchangeAcceptHeader features are +// enabled. +bool NeedToCheckRedirectedURLForAcceptHeader(); + // Returns true if Accept headers should be sent with // "application/signed-exchange". -bool ShouldAdvertiseAcceptHeader(const url::Origin& origin); +CONTENT_EXPORT bool ShouldAdvertiseAcceptHeader(const url::Origin& origin); // Returns true when SignedHTTPExchange feature or SignedHTTPExchangeOriginTrial // feature is enabled.
diff --git a/content/browser/webrtc/webrtc_audio_browsertest.cc b/content/browser/webrtc/webrtc_audio_browsertest.cc index aacf3404..538577a8b 100644 --- a/content/browser/webrtc/webrtc_audio_browsertest.cc +++ b/content/browser/webrtc/webrtc_audio_browsertest.cc
@@ -4,7 +4,6 @@ #include "base/command_line.h" #include "base/files/file_util.h" -#include "base/metrics/persistent_histogram_allocator.h" #include "base/test/scoped_feature_list.h" #include "base/threading/platform_thread.h" #include "build/build_config.h" @@ -39,15 +38,6 @@ // Force audio service out of process to disabled. audio_service_features_.InitWithFeatures({}, audio_service_oop_features); } -#if defined(OS_WIN) - // TODO(https://crbug.com/867827) remove histogram allocator creation when - // removing output controller checks. - if (!base::GlobalHistogramAllocator::Get()) { - const int32_t kAllocatorMemorySize = 8 << 20; - base::GlobalHistogramAllocator::CreateWithLocalMemory( - kAllocatorMemorySize, 0, "HistogramAllocatorTest"); - } -#endif } ~WebRtcAudioBrowserTest() override {}
diff --git a/content/browser/webrtc/webrtc_getusermedia_browsertest.cc b/content/browser/webrtc/webrtc_getusermedia_browsertest.cc index 48785fa9..bb6e4cbf2 100644 --- a/content/browser/webrtc/webrtc_getusermedia_browsertest.cc +++ b/content/browser/webrtc/webrtc_getusermedia_browsertest.cc
@@ -7,7 +7,6 @@ #include "base/command_line.h" #include "base/feature_list.h" #include "base/json/json_reader.h" -#include "base/metrics/persistent_histogram_allocator.h" #include "base/test/scoped_feature_list.h" #include "base/threading/thread_restrictions.h" #include "base/values.h" @@ -119,15 +118,6 @@ // Force audio service out of process to disabled. audio_service_features_.InitWithFeatures({}, audio_service_oop_features); } -#if defined(OS_WIN) - // TODO(https://crbug.com/867827) remove histogram allocator creation when - // removing output controller checks. - if (!base::GlobalHistogramAllocator::Get()) { - const int32_t kAllocatorMemorySize = 8 << 20; - base::GlobalHistogramAllocator::CreateWithLocalMemory( - kAllocatorMemorySize, 0, "HistogramAllocatorTest"); - } -#endif } ~WebRtcGetUserMediaBrowserTest() override {}
diff --git a/content/public/browser/browser_task_traits.h b/content/public/browser/browser_task_traits.h index 8ccee9d9..c370cec 100644 --- a/content/public/browser/browser_task_traits.h +++ b/content/public/browser/browser_task_traits.h
@@ -32,6 +32,10 @@ // To obtain a TaskRunner for the UI thread (analogous for the IO thread): // base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::UI}); // +// Tasks posted to the same BrowserThread with the same traits will be executed +// in the order they were posted, regardless of the TaskRunners they were +// posted via. +// // See //base/task/post_task.h for more detailed documentation. // // Posting to a BrowserThread must only be done after it was initialized (ref.
diff --git a/content/renderer/media/stream/media_stream_audio_processor_unittest.cc b/content/renderer/media/stream/media_stream_audio_processor_unittest.cc index b560026..7dc5ad67 100644 --- a/content/renderer/media/stream/media_stream_audio_processor_unittest.cc +++ b/content/renderer/media/stream/media_stream_audio_processor_unittest.cc
@@ -159,6 +159,9 @@ void VerifyDefaultComponents(MediaStreamAudioProcessor* audio_processor) { webrtc::AudioProcessing* audio_processing = audio_processor->audio_processing_.get(); + const webrtc::AudioProcessing::Config apm_config = + audio_processing->GetConfig(); + EXPECT_TRUE(apm_config.high_pass_filter.enabled); #if defined(OS_ANDROID) EXPECT_TRUE(audio_processing->echo_control_mobile()->is_enabled()); EXPECT_TRUE(audio_processing->echo_control_mobile()->routing_mode() == @@ -176,7 +179,6 @@ EXPECT_TRUE(audio_processing->noise_suppression()->is_enabled()); EXPECT_TRUE(audio_processing->noise_suppression()->level() == webrtc::NoiseSuppression::kHigh); - EXPECT_TRUE(audio_processing->high_pass_filter()->is_enabled()); EXPECT_TRUE(audio_processing->gain_control()->is_enabled()); #if defined(OS_ANDROID) EXPECT_TRUE(audio_processing->gain_control()->mode() ==
diff --git a/content/renderer/media/stream/webmediaplayer_ms.cc b/content/renderer/media/stream/webmediaplayer_ms.cc index 8d5a6ab..d2b6ef2 100644 --- a/content/renderer/media/stream/webmediaplayer_ms.cc +++ b/content/renderer/media/stream/webmediaplayer_ms.cc
@@ -829,7 +829,6 @@ compositor_->GetCurrentFrameWithoutUpdatingStatistics(); media::Context3D context_3d; - gpu::ContextSupport* context_support = nullptr; if (frame && frame->HasTextures()) { auto* provider = RenderThreadImpl::current()->SharedMainThreadContextProvider().get(); @@ -837,11 +836,11 @@ if (!provider) return; context_3d = media::Context3D(provider->ContextGL(), provider->GrContext()); - context_support = provider->ContextSupport(); + DCHECK(context_3d.gl); } const gfx::RectF dest_rect(rect.x, rect.y, rect.width, rect.height); video_renderer_.Paint(frame, canvas, dest_rect, flags, video_rotation_, - context_3d, context_support); + context_3d); } bool WebMediaPlayerMS::DidGetOpaqueResponseFromServiceWorker() const { @@ -1017,8 +1016,8 @@ DCHECK(context_3d.gl); return video_renderer_.CopyVideoFrameTexturesToGLTexture( - context_3d, provider->ContextSupport(), gl, video_frame.get(), target, - texture, internal_format, format, type, level, premultiply_alpha, flip_y); + context_3d, gl, video_frame.get(), target, texture, internal_format, + format, type, level, premultiply_alpha, flip_y); } bool WebMediaPlayerMS::CopyVideoYUVDataToPlatformTexture(
diff --git a/content/renderer/media/stream/webmediaplayer_ms_compositor.cc b/content/renderer/media/stream/webmediaplayer_ms_compositor.cc index 92b6b60..c53c0be2 100644 --- a/content/renderer/media/stream/webmediaplayer_ms_compositor.cc +++ b/content/renderer/media/stream/webmediaplayer_ms_compositor.cc
@@ -68,8 +68,7 @@ DCHECK(provider->ContextGL()); video_renderer->Copy( frame.get(), &paint_canvas, - media::Context3D(provider->ContextGL(), provider->GrContext()), - provider->ContextSupport()); + media::Context3D(provider->ContextGL(), provider->GrContext())); SkPixmap pixmap; const bool result = bitmap.peekPixels(&pixmap);
diff --git a/content/renderer/media/webrtc/peer_connection_tracker.cc b/content/renderer/media/webrtc/peer_connection_tracker.cc index cfd1e8d..76bffec 100644 --- a/content/renderer/media/webrtc/peer_connection_tracker.cc +++ b/content/renderer/media/webrtc/peer_connection_tracker.cc
@@ -433,8 +433,9 @@ class InternalStatsObserver : public webrtc::StatsObserver { public: - explicit InternalStatsObserver(int lid) - : lid_(lid), main_thread_(base::ThreadTaskRunnerHandle::Get()) {} + InternalStatsObserver(int lid, + scoped_refptr<base::SingleThreadTaskRunner> main_thread) + : lid_(lid), main_thread_(std::move(main_thread)) {} void OnComplete(const StatsReports& reports) override { std::unique_ptr<base::ListValue> list(new base::ListValue()); @@ -473,14 +474,19 @@ const scoped_refptr<base::SingleThreadTaskRunner> main_thread_; }; -PeerConnectionTracker::PeerConnectionTracker() - : next_local_id_(1), send_target_for_test_(nullptr) {} - PeerConnectionTracker::PeerConnectionTracker( - mojom::PeerConnectionTrackerHostAssociatedPtr host) + scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner) : next_local_id_(1), send_target_for_test_(nullptr), - peer_connection_tracker_host_ptr_(std::move(host)) {} + main_thread_task_runner_(std::move(main_thread_task_runner)) {} + +PeerConnectionTracker::PeerConnectionTracker( + mojom::PeerConnectionTrackerHostAssociatedPtr host, + scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner) + : next_local_id_(1), + send_target_for_test_(nullptr), + peer_connection_tracker_host_ptr_(std::move(host)), + main_thread_task_runner_(std::move(main_thread_task_runner)) {} PeerConnectionTracker::~PeerConnectionTracker() { } @@ -508,7 +514,8 @@ for (PeerConnectionIdMap::iterator it = peer_connection_id_map_.begin(); it != peer_connection_id_map_.end(); ++it) { rtc::scoped_refptr<InternalStatsObserver> observer( - new rtc::RefCountedObject<InternalStatsObserver>(it->second)); + new rtc::RefCountedObject<InternalStatsObserver>( + it->second, main_thread_task_runner_)); it->first->GetStats(observer, webrtc::PeerConnectionInterface::kStatsOutputLevelDebug,
diff --git a/content/renderer/media/webrtc/peer_connection_tracker.h b/content/renderer/media/webrtc/peer_connection_tracker.h index 24e0fd85..7f95e5df 100644 --- a/content/renderer/media/webrtc/peer_connection_tracker.h +++ b/content/renderer/media/webrtc/peer_connection_tracker.h
@@ -45,8 +45,11 @@ : public RenderThreadObserver, public base::SupportsWeakPtr<PeerConnectionTracker> { public: - PeerConnectionTracker(); - PeerConnectionTracker(mojom::PeerConnectionTrackerHostAssociatedPtr host); + explicit PeerConnectionTracker( + scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner); + PeerConnectionTracker( + mojom::PeerConnectionTrackerHostAssociatedPtr host, + scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner); ~PeerConnectionTracker() override; enum Source { @@ -262,6 +265,8 @@ mojom::PeerConnectionTrackerHostAssociatedPtr peer_connection_tracker_host_ptr_; + scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_; + DISALLOW_COPY_AND_ASSIGN(PeerConnectionTracker); };
diff --git a/content/renderer/media/webrtc/peer_connection_tracker_unittest.cc b/content/renderer/media/webrtc/peer_connection_tracker_unittest.cc index 8486597..2bda94c 100644 --- a/content/renderer/media/webrtc/peer_connection_tracker_unittest.cc +++ b/content/renderer/media/webrtc/peer_connection_tracker_unittest.cc
@@ -151,8 +151,9 @@ public: void CreateTrackerWithMocks() { mock_host_.reset(new MockPeerConnectionTrackerHost()); - tracker_.reset( - new PeerConnectionTracker(mock_host_->CreateInterfacePtrAndBind())); + tracker_.reset(new PeerConnectionTracker( + mock_host_->CreateInterfacePtrAndBind(), + blink::scheduler::GetSingleThreadTaskRunnerForTesting())); target_thread_.reset(new MockSendTargetThread()); tracker_->OverrideSendTargetForTesting(target_thread_.get()); } @@ -177,7 +178,8 @@ } // namespace TEST_F(PeerConnectionTrackerTest, CreatingObject) { - PeerConnectionTracker tracker; + PeerConnectionTracker tracker( + blink::scheduler::GetSingleThreadTaskRunnerForTesting()); } TEST_F(PeerConnectionTrackerTest, TrackCreateOffer) {
diff --git a/content/renderer/media/webrtc/rtc_dtmf_sender_handler.cc b/content/renderer/media/webrtc/rtc_dtmf_sender_handler.cc index 82ffa649..fa3c5767 100644 --- a/content/renderer/media/webrtc/rtc_dtmf_sender_handler.cc +++ b/content/renderer/media/webrtc/rtc_dtmf_sender_handler.cc
@@ -22,8 +22,9 @@ public base::RefCountedThreadSafe<Observer>, public webrtc::DtmfSenderObserverInterface { public: - explicit Observer(const base::WeakPtr<RtcDtmfSenderHandler>& handler) - : main_thread_(base::ThreadTaskRunnerHandle::Get()), handler_(handler) {} + explicit Observer(scoped_refptr<base::SingleThreadTaskRunner> main_thread, + const base::WeakPtr<RtcDtmfSenderHandler>& handler) + : main_thread_(std::move(main_thread)), handler_(handler) {} private: friend class base::RefCountedThreadSafe<Observer>; @@ -51,10 +52,12 @@ base::WeakPtr<RtcDtmfSenderHandler> handler_; }; -RtcDtmfSenderHandler::RtcDtmfSenderHandler(DtmfSenderInterface* dtmf_sender) +RtcDtmfSenderHandler::RtcDtmfSenderHandler( + scoped_refptr<base::SingleThreadTaskRunner> main_thread, + DtmfSenderInterface* dtmf_sender) : dtmf_sender_(dtmf_sender), webkit_client_(nullptr), weak_factory_(this) { DVLOG(1) << "::ctor"; - observer_ = new Observer(weak_factory_.GetWeakPtr()); + observer_ = new Observer(std::move(main_thread), weak_factory_.GetWeakPtr()); dtmf_sender_->RegisterObserver(observer_.get()); }
diff --git a/content/renderer/media/webrtc/rtc_dtmf_sender_handler.h b/content/renderer/media/webrtc/rtc_dtmf_sender_handler.h index 193bc77..a314ecc1 100644 --- a/content/renderer/media/webrtc/rtc_dtmf_sender_handler.h +++ b/content/renderer/media/webrtc/rtc_dtmf_sender_handler.h
@@ -16,6 +16,10 @@ #include "third_party/blink/public/platform/web_rtc_dtmf_sender_handler_client.h" #include "third_party/webrtc/api/dtmfsenderinterface.h" +namespace base { +class SingleThreadTaskRunner; +} + namespace content { // RtcDtmfSenderHandler is a delegate for the RTC DTMF Sender API messages @@ -27,7 +31,8 @@ class CONTENT_EXPORT RtcDtmfSenderHandler : public blink::WebRTCDTMFSenderHandler { public: - explicit RtcDtmfSenderHandler(webrtc::DtmfSenderInterface* dtmf_sender); + RtcDtmfSenderHandler(scoped_refptr<base::SingleThreadTaskRunner> main_thread, + webrtc::DtmfSenderInterface* dtmf_sender); ~RtcDtmfSenderHandler() override; // blink::WebRTCDTMFSenderHandler implementation.
diff --git a/content/renderer/media/webrtc/rtc_peer_connection_handler_unittest.cc b/content/renderer/media/webrtc/rtc_peer_connection_handler_unittest.cc index e281ec9..fa770cf 100644 --- a/content/renderer/media/webrtc/rtc_peer_connection_handler_unittest.cc +++ b/content/renderer/media/webrtc/rtc_peer_connection_handler_unittest.cc
@@ -148,6 +148,10 @@ class MockPeerConnectionTracker : public PeerConnectionTracker { public: + MockPeerConnectionTracker() + : PeerConnectionTracker( + blink::scheduler::GetSingleThreadTaskRunnerForTesting()) {} + MOCK_METHOD1(UnregisterPeerConnection, void(RTCPeerConnectionHandler* pc_handler)); // TODO(jiayl): add coverage for the following methods
diff --git a/content/renderer/media/webrtc/rtc_rtp_sender.cc b/content/renderer/media/webrtc/rtc_rtp_sender.cc index a2d16ec..14d7a5f5 100644 --- a/content/renderer/media/webrtc/rtc_rtp_sender.cc +++ b/content/renderer/media/webrtc/rtc_rtp_sender.cc
@@ -185,7 +185,8 @@ // webrtc signalling thread. DCHECK(main_task_runner_->BelongsToCurrentThread()); auto dtmf_sender = webrtc_sender_->GetDtmfSender(); - return std::make_unique<RtcDtmfSenderHandler>(dtmf_sender); + return std::make_unique<RtcDtmfSenderHandler>(main_task_runner_, + dtmf_sender); } std::unique_ptr<webrtc::RtpParameters> GetParameters() {
diff --git a/content/renderer/media/webrtc/webrtc_audio_sink.cc b/content/renderer/media/webrtc/webrtc_audio_sink.cc index 81becdc4..521f8ec 100644 --- a/content/renderer/media/webrtc/webrtc_audio_sink.cc +++ b/content/renderer/media/webrtc/webrtc_audio_sink.cc
@@ -18,9 +18,13 @@ WebRtcAudioSink::WebRtcAudioSink( const std::string& label, scoped_refptr<webrtc::AudioSourceInterface> track_source, - scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner) - : adapter_(new rtc::RefCountedObject<Adapter>( - label, std::move(track_source), std::move(signaling_task_runner))), + scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> main_task_runner) + : adapter_( + new rtc::RefCountedObject<Adapter>(label, + std::move(track_source), + std::move(signaling_task_runner), + std::move(main_task_runner))), fifo_(base::Bind(&WebRtcAudioSink::DeliverRebufferedAudio, base::Unretained(this))) { DVLOG(1) << "WebRtcAudioSink::WebRtcAudioSink()"; @@ -100,12 +104,14 @@ WebRtcAudioSink::Adapter::Adapter( const std::string& label, scoped_refptr<webrtc::AudioSourceInterface> source, - scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner) + scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> main_task_runner) : webrtc::MediaStreamTrack<webrtc::AudioTrackInterface>(label), source_(std::move(source)), signaling_task_runner_(std::move(signaling_task_runner)), - main_task_runner_(base::ThreadTaskRunnerHandle::Get()) { + main_task_runner_(std::move(main_task_runner)) { DCHECK(signaling_task_runner_); + DCHECK(main_task_runner_); } WebRtcAudioSink::Adapter::~Adapter() {
diff --git a/content/renderer/media/webrtc/webrtc_audio_sink.h b/content/renderer/media/webrtc/webrtc_audio_sink.h index a5667cc3..c2a6c381 100644 --- a/content/renderer/media/webrtc/webrtc_audio_sink.h +++ b/content/renderer/media/webrtc/webrtc_audio_sink.h
@@ -40,7 +40,8 @@ WebRtcAudioSink( const std::string& label, scoped_refptr<webrtc::AudioSourceInterface> track_source, - scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner); + scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> main_task_runner); ~WebRtcAudioSink() override; @@ -72,7 +73,8 @@ public: Adapter(const std::string& label, scoped_refptr<webrtc::AudioSourceInterface> source, - scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner); + scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> main_task_runner); base::SingleThreadTaskRunner* signaling_task_runner() const { return signaling_task_runner_.get();
diff --git a/content/renderer/media/webrtc/webrtc_media_stream_track_adapter.cc b/content/renderer/media/webrtc/webrtc_media_stream_track_adapter.cc index 92d4065c2..caa1974 100644 --- a/content/renderer/media/webrtc/webrtc_media_stream_track_adapter.cc +++ b/content/renderer/media/webrtc/webrtc_media_stream_track_adapter.cc
@@ -149,7 +149,7 @@ webrtc::AudioSourceInterface* source_interface = nullptr; local_track_audio_sink_.reset( new WebRtcAudioSink(web_track_.Id().Utf8(), source_interface, - factory_->GetWebRtcSignalingThread())); + factory_->GetWebRtcSignalingThread(), main_thread_)); if (auto* media_stream_source = ProcessedLocalAudioSource::From( MediaStreamAudioSource::From(web_track_.Source()))) {
diff --git a/content/renderer/media_recorder/video_track_recorder.cc b/content/renderer/media_recorder/video_track_recorder.cc index ef28d3170..c7fb3465 100644 --- a/content/renderer/media_recorder/video_track_recorder.cc +++ b/content/renderer/media_recorder/video_track_recorder.cc
@@ -313,8 +313,7 @@ DCHECK(context_provider->ContextGL()); video_renderer_->Copy(video_frame.get(), canvas_.get(), media::Context3D(context_provider->ContextGL(), - context_provider->GrContext()), - context_provider->ContextSupport()); + context_provider->GrContext())); SkPixmap pixmap; if (!bitmap_.peekPixels(&pixmap)) {
diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc index 5723681..f6b7f9f 100644 --- a/content/renderer/render_thread_impl.cc +++ b/content/renderer/render_thread_impl.cc
@@ -775,7 +775,8 @@ browser_plugin_manager_.reset(new BrowserPluginManager()); AddObserver(browser_plugin_manager_.get()); - peer_connection_tracker_.reset(new PeerConnectionTracker()); + peer_connection_tracker_.reset( + new PeerConnectionTracker(main_thread_runner())); AddObserver(peer_connection_tracker_.get()); p2p_socket_dispatcher_ = new P2PSocketDispatcher(); @@ -1166,25 +1167,14 @@ } void RenderThreadImpl::InitializeCompositorThread() { - blink::WebThreadCreationParams params( - blink::WebThreadType::kCompositorThread); -#if defined(OS_ANDROID) - params.thread_options.priority = base::ThreadPriority::DISPLAY; -#endif - blink_platform_impl_->InitializeCompositorThread(params); - blink::WebThread* compositor_thread = - blink_platform_impl_->CompositorThread(); - compositor_task_runner_ = compositor_thread->GetTaskRunner(); + blink_platform_impl_->InitializeCompositorThread(); + compositor_task_runner_ = blink_platform_impl_->CompositorThreadTaskRunner(); compositor_task_runner_->PostTask( FROM_HERE, base::BindOnce(base::IgnoreResult(&ThreadRestrictions::SetIOAllowed), false)); GetContentClient()->renderer()->PostCompositorThreadCreated( compositor_task_runner_.get()); -#if defined(OS_LINUX) - render_message_filter()->SetThreadPriority(compositor_thread->ThreadId(), - base::ThreadPriority::DISPLAY); -#endif } scoped_refptr<base::SingleThreadTaskRunner>
diff --git a/content/renderer/renderer_blink_platform_impl.cc b/content/renderer/renderer_blink_platform_impl.cc index 1e87b767..807e75b 100644 --- a/content/renderer/renderer_blink_platform_impl.cc +++ b/content/renderer/renderer_blink_platform_impl.cc
@@ -380,6 +380,16 @@ return url_loader_factory; } +void RendererBlinkPlatformImpl::SetDisplayThreadPriority( + base::PlatformThreadId thread_id) { +#if defined(OS_LINUX) + if (RenderThreadImpl* render_thread = RenderThreadImpl::current()) { + render_thread->render_message_filter()->SetThreadPriority( + thread_id, base::ThreadPriority::DISPLAY); + } +#endif +} + blink::BlameContext* RendererBlinkPlatformImpl::GetTopLevelBlameContext() { return &top_level_blame_context_; }
diff --git a/content/renderer/renderer_blink_platform_impl.h b/content/renderer/renderer_blink_platform_impl.h index 960ed3a..b74b59a 100644 --- a/content/renderer/renderer_blink_platform_impl.h +++ b/content/renderer/renderer_blink_platform_impl.h
@@ -196,6 +196,7 @@ blink::WebString ConvertIDNToUnicode(const blink::WebString& host) override; service_manager::Connector* GetConnector() override; blink::InterfaceProvider* GetInterfaceProvider() override; + void SetDisplayThreadPriority(base::PlatformThreadId thread_id) override; blink::BlameContext* GetTopLevelBlameContext() override; void RecordRappor(const char* metric, const blink::WebString& sample) override;
diff --git a/content/shell/renderer/layout_test/blink_test_runner.cc b/content/shell/renderer/layout_test/blink_test_runner.cc index 2366d29..0058ebb4 100644 --- a/content/shell/renderer/layout_test/blink_test_runner.cc +++ b/content/shell/renderer/layout_test/blink_test_runner.cc
@@ -107,7 +107,6 @@ using blink::WebURLError; using blink::WebURLRequest; using blink::WebTestingSupport; -using blink::WebThread; using blink::WebVector; using blink::WebView;
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index f99c8790..e42988d 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -1578,6 +1578,7 @@ "../browser/service_worker/service_worker_registration_unittest.cc", "../browser/service_worker/service_worker_request_handler_unittest.cc", "../browser/service_worker/service_worker_script_loader_factory_unittest.cc", + "../browser/service_worker/service_worker_single_script_update_checker_unittest.cc", "../browser/service_worker/service_worker_storage_unittest.cc", "../browser/service_worker/service_worker_url_request_job_unittest.cc", "../browser/service_worker/service_worker_version_unittest.cc",
diff --git a/extensions/renderer/dispatcher.cc b/extensions/renderer/dispatcher.cc index 5737483f6..a721305 100644 --- a/extensions/renderer/dispatcher.cc +++ b/extensions/renderer/dispatcher.cc
@@ -179,7 +179,7 @@ v8::Local<v8::Value> chrome(global->Get(chrome_string)); if (chrome->IsUndefined()) { chrome = v8::Object::New(context()->isolate()); - global->Set(chrome_string, chrome); + global->Set(context()->v8_context(), chrome_string, chrome).ToChecked(); } args.GetReturnValue().Set(chrome); }
diff --git a/extensions/renderer/js_extension_bindings_system.cc b/extensions/renderer/js_extension_bindings_system.cc index 783fa0c..beb355c 100644 --- a/extensions/renderer/js_extension_bindings_system.cc +++ b/extensions/renderer/js_extension_bindings_system.cc
@@ -36,9 +36,9 @@ // exist. v8::Local<v8::Object> GetOrCreateObject(const v8::Local<v8::Object>& object, const std::string& field, - v8::Isolate* isolate) { + ScriptContext* context) { v8::Local<v8::String> key = - v8::String::NewFromUtf8(isolate, field.c_str(), + v8::String::NewFromUtf8(context->isolate(), field.c_str(), v8::NewStringType::kInternalized) .ToLocalChecked(); // If the object has a callback property, it is assumed it is an unavailable @@ -52,8 +52,8 @@ return v8::Local<v8::Object>::Cast(value); } - v8::Local<v8::Object> new_object = v8::Object::New(isolate); - object->Set(key, new_object); + v8::Local<v8::Object> new_object = v8::Object::New(context->isolate()); + object->Set(context->v8_context(), key, new_object).ToChecked(); return new_object; } @@ -70,7 +70,7 @@ v8::Local<v8::Value> chrome(global->Get(chrome_string)); if (chrome->IsUndefined()) { chrome = v8::Object::New(context->isolate()); - global->Set(chrome_string, chrome); + global->Set(context->v8_context(), chrome_string, chrome).ToChecked(); } return chrome->IsObject() ? chrome.As<v8::Object>() : v8::Local<v8::Object>(); } @@ -113,7 +113,7 @@ if (bind_object.IsEmpty()) return v8::Local<v8::Object>(); } - bind_object = GetOrCreateObject(bind_object, split[i], context->isolate()); + bind_object = GetOrCreateObject(bind_object, split[i], context); } if (only_ancestor_available)
diff --git a/gin/interceptor_unittest.cc b/gin/interceptor_unittest.cc index 4af449f96..58f209a 100644 --- a/gin/interceptor_unittest.cc +++ b/gin/interceptor_unittest.cc
@@ -39,7 +39,10 @@ if (property == "value") { return ConvertToV8(isolate, value_); } else if (property == "func") { - return GetFunctionTemplate(isolate, "func")->GetFunction(); + v8::Local<v8::Context> context = isolate->GetCurrentContext(); + return GetFunctionTemplate(isolate, "func") + ->GetFunction(context) + .ToLocalChecked(); } else { return v8::Local<v8::Value>(); }
diff --git a/gpu/ipc/service/gpu_channel.cc b/gpu/ipc/service/gpu_channel.cc index 3ae6d87..a96a369 100644 --- a/gpu/ipc/service/gpu_channel.cc +++ b/gpu/ipc/service/gpu_channel.cc
@@ -304,39 +304,6 @@ return true; } -// Definitions for constructor and destructor of this interface are needed to -// avoid MSVC LNK2019. -FilteredSender::FilteredSender() = default; - -FilteredSender::~FilteredSender() = default; - -SyncChannelFilteredSender::SyncChannelFilteredSender( - IPC::ChannelHandle channel_handle, - IPC::Listener* listener, - scoped_refptr<base::SingleThreadTaskRunner> ipc_task_runner, - base::WaitableEvent* shutdown_event) - : channel_(IPC::SyncChannel::Create(channel_handle, - IPC::Channel::MODE_SERVER, - listener, - ipc_task_runner, - base::ThreadTaskRunnerHandle::Get(), - false, - shutdown_event)) {} - -SyncChannelFilteredSender::~SyncChannelFilteredSender() = default; - -bool SyncChannelFilteredSender::Send(IPC::Message* msg) { - return channel_->Send(msg); -} - -void SyncChannelFilteredSender::AddFilter(IPC::MessageFilter* filter) { - channel_->AddFilter(filter); -} - -void SyncChannelFilteredSender::RemoveFilter(IPC::MessageFilter* filter) { - channel_->RemoveFilter(filter); -} - GpuChannel::GpuChannel( GpuChannelManager* gpu_channel_manager, Scheduler* scheduler, @@ -361,29 +328,42 @@ DCHECK(gpu_channel_manager_); DCHECK(client_id_); filter_ = new GpuChannelMessageFilter(this, scheduler, task_runner); + // SharedImageInterfaceProxy/Stub is a singleton per channel, using a reserved + // route. + const int32_t shared_image_route_id = + static_cast<int32_t>(GpuChannelReservedRoutes::kSharedImageInterface); + shared_image_stub_ = + std::make_unique<SharedImageStub>(this, shared_image_route_id); + filter_->AddRoute(shared_image_route_id, shared_image_stub_->sequence()); + router_.AddRoute(shared_image_route_id, shared_image_stub_.get()); } GpuChannel::~GpuChannel() { // Clear stubs first because of dependencies. stubs_.clear(); - // Destroy filter first so that scheduler gets no more messages. + // Destroy filter first to stop posting tasks to scheduler. filter_->Destroy(); for (const auto& kv : stream_sequences_) scheduler_->DestroySequence(kv.second); } -void GpuChannel::Init(std::unique_ptr<FilteredSender> channel) { - channel_ = std::move(channel); - channel_->AddFilter(filter_.get()); - // SharedImageInterfaceProxy/Stub is a singleton per channel, using a reserved - // route. - const int32_t route_id = - static_cast<int32_t>(GpuChannelReservedRoutes::kSharedImageInterface); - shared_image_stub_ = std::make_unique<SharedImageStub>(this, route_id); - filter_->AddRoute(route_id, shared_image_stub_->sequence()); - router_.AddRoute(route_id, shared_image_stub_.get()); +void GpuChannel::Init(IPC::ChannelHandle channel_handle, + base::WaitableEvent* shutdown_event) { + sync_channel_ = IPC::SyncChannel::Create( + channel_handle, IPC::Channel::MODE_SERVER, this, io_task_runner_.get(), + task_runner_.get(), false, shutdown_event); + sync_channel_->AddFilter(filter_.get()); + channel_ = sync_channel_.get(); +} + +void GpuChannel::InitForTesting(IPC::Channel* channel) { + channel_ = channel; + // |channel| is an IPC::TestSink in tests, so don't add the filter to it + // because it will forward sent messages back to the filter. + // Call OnFilterAdded() to prevent DCHECK failures. + filter_->OnFilterAdded(channel); } void GpuChannel::SetUnhandledMessageListener(IPC::Listener* listener) {
diff --git a/gpu/ipc/service/gpu_channel.h b/gpu/ipc/service/gpu_channel.h index 3e8c1c6..4ea6463 100644 --- a/gpu/ipc/service/gpu_channel.h +++ b/gpu/ipc/service/gpu_channel.h
@@ -47,38 +47,10 @@ class SharedImageStub; class SyncPointManager; -class GPU_IPC_SERVICE_EXPORT FilteredSender : public IPC::Sender { - public: - FilteredSender(); - ~FilteredSender() override; - - virtual void AddFilter(IPC::MessageFilter* filter) = 0; - virtual void RemoveFilter(IPC::MessageFilter* filter) = 0; -}; - -class GPU_IPC_SERVICE_EXPORT SyncChannelFilteredSender : public FilteredSender { - public: - SyncChannelFilteredSender( - IPC::ChannelHandle channel_handle, - IPC::Listener* listener, - scoped_refptr<base::SingleThreadTaskRunner> ipc_task_runner, - base::WaitableEvent* shutdown_event); - ~SyncChannelFilteredSender() override; - - bool Send(IPC::Message* msg) override; - void AddFilter(IPC::MessageFilter* filter) override; - void RemoveFilter(IPC::MessageFilter* filter) override; - - private: - std::unique_ptr<IPC::SyncChannel> channel_; - - DISALLOW_COPY_AND_ASSIGN(SyncChannelFilteredSender); -}; - // Encapsulates an IPC channel between the GPU process and one renderer // process. On the renderer side there's a corresponding GpuChannelHost. class GPU_IPC_SERVICE_EXPORT GpuChannel : public IPC::Listener, - public FilteredSender { + public IPC::Sender { public: // Takes ownership of the renderer process handle. GpuChannel(GpuChannelManager* gpu_channel_manager, @@ -92,9 +64,12 @@ bool is_gpu_host); ~GpuChannel() override; - // The IPC channel cannot be passed in the constructor because it needs a - // listener. The listener is the GpuChannel and must be constructed first. - void Init(std::unique_ptr<FilteredSender> channel); + // Init() sets up the underlying IPC channel. Use a separate method because + // we don't want to do that in tests. + void Init(IPC::ChannelHandle channel_handle, + base::WaitableEvent* shutdown_event); + + void InitForTesting(IPC::Channel* channel); base::WeakPtr<GpuChannel> AsWeakPtr(); @@ -126,17 +101,16 @@ return io_task_runner_; } - FilteredSender* channel_for_testing() const { return channel_.get(); } - // IPC::Listener implementation: bool OnMessageReceived(const IPC::Message& msg) override; void OnChannelConnected(int32_t peer_pid) override; void OnChannelError() override; - // FilteredSender implementation: + // IPC::Sender implementation: bool Send(IPC::Message* msg) override; - void AddFilter(IPC::MessageFilter* filter) override; - void RemoveFilter(IPC::MessageFilter* filter) override; + + void AddFilter(IPC::MessageFilter* filter); + void RemoveFilter(IPC::MessageFilter* filter); void OnCommandBufferScheduled(CommandBufferStub* stub); void OnCommandBufferDescheduled(CommandBufferStub* stub); @@ -196,7 +170,8 @@ void OnDestroyCommandBuffer(int32_t route_id); void OnCrashForTesting(); - std::unique_ptr<FilteredSender> channel_; + std::unique_ptr<IPC::SyncChannel> sync_channel_; // nullptr in tests. + IPC::Sender* channel_; // Same as sync_channel_.get() except in tests. base::ProcessId peer_pid_ = base::kNullProcessId;
diff --git a/gpu/ipc/service/gpu_channel_test_common.cc b/gpu/ipc/service/gpu_channel_test_common.cc index a388a48a..787b918 100644 --- a/gpu/ipc/service/gpu_channel_test_common.cc +++ b/gpu/ipc/service/gpu_channel_test_common.cc
@@ -13,7 +13,6 @@ #include "gpu/ipc/service/gpu_channel.h" #include "gpu/ipc/service/gpu_channel_manager.h" #include "gpu/ipc/service/gpu_channel_manager_delegate.h" -#include "ipc/ipc_test_sink.h" #include "ui/gl/init/gl_factory.h" #include "ui/gl/test/gl_surface_test_support.h" #include "url/gurl.h" @@ -47,30 +46,6 @@ DISALLOW_COPY_AND_ASSIGN(TestGpuChannelManagerDelegate); }; -class TestSinkFilteredSender : public FilteredSender { - public: - TestSinkFilteredSender() : sink_(std::make_unique<IPC::TestSink>()) {} - ~TestSinkFilteredSender() override = default; - - IPC::TestSink* sink() const { return sink_.get(); } - - bool Send(IPC::Message* msg) override { return sink_->Send(msg); } - - void AddFilter(IPC::MessageFilter* filter) override { - // Needed to appease DCHECKs. - filter->OnFilterAdded(sink_.get()); - } - - void RemoveFilter(IPC::MessageFilter* filter) override { - filter->OnFilterRemoved(); - } - - private: - std::unique_ptr<IPC::TestSink> sink_; - - DISALLOW_COPY_AND_ASSIGN(TestSinkFilteredSender); -}; - GpuChannelTestCommon::GpuChannelTestCommon() : task_runner_(new base::TestSimpleTaskRunner), io_task_runner_(new base::TestSimpleTaskRunner), @@ -104,7 +79,7 @@ uint64_t kClientTracingId = 1; GpuChannel* channel = channel_manager()->EstablishChannel( client_id, kClientTracingId, is_gpu_host, true); - channel->Init(std::make_unique<TestSinkFilteredSender>()); + channel->InitForTesting(&sink_); base::ProcessId kProcessId = 1; channel->OnChannelConnected(kProcessId); return channel; @@ -112,13 +87,9 @@ void GpuChannelTestCommon::HandleMessage(GpuChannel* channel, IPC::Message* msg) { - IPC::TestSink* sink = - static_cast<TestSinkFilteredSender*>(channel->channel_for_testing()) - ->sink(); - // Some IPCs (such as GpuCommandBufferMsg_Initialize) will generate more // delayed responses, drop those if they exist. - sink->ClearMessages(); + sink_.ClearMessages(); // Needed to appease DCHECKs. msg->set_unblock(false); @@ -131,7 +102,7 @@ // Replies are sent to the sink. if (msg->is_sync()) { - const IPC::Message* reply_msg = sink->GetMessageAt(0); + const IPC::Message* reply_msg = sink_.GetMessageAt(0); ASSERT_TRUE(reply_msg); EXPECT_TRUE(!reply_msg->is_reply_error()); @@ -146,7 +117,7 @@ delete deserializer; } - sink->ClearMessages(); + sink_.ClearMessages(); delete msg; }
diff --git a/gpu/ipc/service/gpu_channel_test_common.h b/gpu/ipc/service/gpu_channel_test_common.h index 11a96d23..cd3aae11 100644 --- a/gpu/ipc/service/gpu_channel_test_common.h +++ b/gpu/ipc/service/gpu_channel_test_common.h
@@ -9,6 +9,7 @@ #include "base/memory/ref_counted.h" #include "base/memory/unsafe_shared_memory_region.h" +#include "ipc/ipc_test_sink.h" #include "testing/gtest/include/gtest/gtest.h" namespace base { @@ -42,6 +43,7 @@ base::UnsafeSharedMemoryRegion GetSharedMemoryRegion(); private: + IPC::TestSink sink_; scoped_refptr<base::TestSimpleTaskRunner> task_runner_; scoped_refptr<base::TestSimpleTaskRunner> io_task_runner_; std::unique_ptr<SyncPointManager> sync_point_manager_;
diff --git a/infra/config/global/cr-buildbucket.cfg b/infra/config/global/cr-buildbucket.cfg index 5fbc0bd..2389884d 100644 --- a/infra/config/global/cr-buildbucket.cfg +++ b/infra/config/global/cr-buildbucket.cfg
@@ -3252,9 +3252,7 @@ recipe { cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master" - # TODO(phoglund): change to chromium.webrtc.fyi once done rewriting the - # configs to be src-side - properties: "mastername:chromium.webrtc.fyi.experimental" + properties: "mastername:chromium.webrtc.fyi" name: "chromium" } service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
diff --git a/infra/config/global/luci-milo.cfg b/infra/config/global/luci-milo.cfg index ec8e043..749eb4b 100644 --- a/infra/config/global/luci-milo.cfg +++ b/infra/config/global/luci-milo.cfg
@@ -3869,109 +3869,109 @@ refs: "refs/heads/master" manifest_name: "REVISION" builders { - name: "buildbot/chromium.webrtc.fyi/Android Builder (dbg)" + name: "buildbot/chromium.webrtc.fyi/WebRTC Chromium FYI Android Builder (dbg)" name: "buildbucket/luci.chromium.webrtc.fyi/WebRTC Chromium FYI Android Builder (dbg)" category: "android|debug|builder" short_name: "32" } builders { - name: "buildbot/chromium.webrtc.fyi/Android Builder ARM64 (dbg)" + name: "buildbot/chromium.webrtc.fyi/WebRTC Chromium FYI Android Builder ARM64 (dbg)" name: "buildbucket/luci.chromium.webrtc.fyi/WebRTC Chromium FYI Android Builder ARM64 (dbg)" category: "android|debug|builder" short_name: "64" } builders { - name: "buildbot/chromium.webrtc.fyi/Android Tests (dbg) (K Nexus5)" + name: "buildbot/chromium.webrtc.fyi/WebRTC Chromium FYI Android Tests (dbg) (K Nexus5)" name: "buildbucket/luci.chromium.webrtc.fyi/WebRTC Chromium FYI Android Tests (dbg) (K Nexus5)" category: "android|debug|tester" short_name: "K" } builders { - name: "buildbot/chromium.webrtc.fyi/Android Tests (dbg) (M Nexus5X)" + name: "buildbot/chromium.webrtc.fyi/WebRTC Chromium FYI Android Tests (dbg) (M Nexus5X)" name: "buildbucket/luci.chromium.webrtc.fyi/WebRTC Chromium FYI Android Tests (dbg) (M Nexus5X)" category: "android|debug|tester" short_name: "M" } builders { - name: "buildbot/chromium.webrtc.fyi/Android Builder" + name: "buildbot/chromium.webrtc.fyi/WebRTC Chromium FYI Android Builder" name: "buildbucket/luci.chromium.webrtc.fyi/WebRTC Chromium FYI Android Builder" category: "android|release" short_name: "32" } builders { - name: "buildbot/chromium.webrtc.fyi/Linux Builder (dbg)" + name: "buildbot/chromium.webrtc.fyi/WebRTC Chromium FYI Linux Builder (dbg)" name: "buildbucket/luci.chromium.webrtc.fyi/WebRTC Chromium FYI Linux Builder (dbg)" category: "linux|debug" short_name: "bld" } builders { - name: "buildbot/chromium.webrtc.fyi/Linux Builder" + name: "buildbot/chromium.webrtc.fyi/WebRTC Chromium FYI Linux Builder" name: "buildbucket/luci.chromium.webrtc.fyi/WebRTC Chromium FYI Linux Builder" category: "linux|release" short_name: "bld" } builders { - name: "buildbot/chromium.webrtc.fyi/Linux Tester" + name: "buildbot/chromium.webrtc.fyi/WebRTC Chromium FYI Linux Tester" name: "buildbucket/luci.chromium.webrtc.fyi/WebRTC Chromium FYI Linux Tester" category: "linux|release" short_name: "tst" } builders { - name: "buildbot/chromium.webrtc.fyi/Mac Builder (dbg)" + name: "buildbot/chromium.webrtc.fyi/WebRTC Chromium FYI Mac Builder (dbg)" name: "buildbucket/luci.chromium.webrtc.fyi/WebRTC Chromium FYI Mac Builder (dbg)" category: "mac|debug" short_name: "bld" } builders { - name: "buildbot/chromium.webrtc.fyi/Mac Builder" + name: "buildbot/chromium.webrtc.fyi/WebRTC Chromium FYI Mac Builder" name: "buildbucket/luci.chromium.webrtc.fyi/WebRTC Chromium FYI Mac Builder" category: "mac|release" short_name: "bld" } builders { - name: "buildbot/chromium.webrtc.fyi/Mac Tester" + name: "buildbot/chromium.webrtc.fyi/WebRTC Chromium FYI Mac Tester" name: "buildbucket/luci.chromium.webrtc.fyi/WebRTC Chromium FYI Mac Tester" category: "mac|release" short_name: "tst" } builders { - name: "buildbot/chromium.webrtc.fyi/Win Builder (dbg)" + name: "buildbot/chromium.webrtc.fyi/WebRTC Chromium FYI Win Builder (dbg)" name: "buildbucket/luci.chromium.webrtc.fyi/WebRTC Chromium FYI Win Builder (dbg)" category: "win|debug" short_name: "bld" } builders { - name: "buildbot/chromium.webrtc.fyi/Win Builder" + name: "buildbot/chromium.webrtc.fyi/WebRTC Chromium FYI Win Builder" name: "buildbucket/luci.chromium.webrtc.fyi/WebRTC Chromium FYI Win Builder" category: "win|release|builder" short_name: "32" } builders { - name: "buildbot/chromium.webrtc.fyi/Win10 Tester" + name: "buildbot/chromium.webrtc.fyi/WebRTC Chromium FYI Win10 Tester" name: "buildbucket/luci.chromium.webrtc.fyi/WebRTC Chromium FYI Win10 Tester" category: "win|release|tester" short_name: "10" } builders { - name: "buildbot/chromium.webrtc.fyi/Win7 Tester" + name: "buildbot/chromium.webrtc.fyi/WebRTC Chromium FYI Win7 Tester" name: "buildbucket/luci.chromium.webrtc.fyi/WebRTC Chromium FYI Win7 Tester" category: "win|release|tester" short_name: "7" } builders { - name: "buildbot/chromium.webrtc.fyi/Win8 Tester" + name: "buildbot/chromium.webrtc.fyi/WebRTC Chromium FYI Win8 Tester" name: "buildbucket/luci.chromium.webrtc.fyi/WebRTC Chromium FYI Win8 Tester" category: "win|release|tester" short_name: "8" } builders { - name: "buildbot/chromium.webrtc.fyi/ios-device" + name: "buildbot/chromium.webrtc.fyi/WebRTC Chromium FYI ios-device" name: "buildbucket/luci.chromium.webrtc.fyi/WebRTC Chromium FYI ios-device" category: "ios" short_name: "dev" } builders { - name: "buildbot/chromium.webrtc.fyi/ios-simulator" + name: "buildbot/chromium.webrtc.fyi/WebRTC Chromium FYI ios-simulator" name: "buildbucket/luci.chromium.webrtc.fyi/WebRTC Chromium FYI ios-simulator" category: "ios" short_name: "sim"
diff --git a/ios/build/bots/chromium.webrtc.fyi.experimental/WebRTC Chromium FYI ios-device.json b/ios/build/bots/chromium.webrtc.fyi.experimental/WebRTC Chromium FYI ios-device.json deleted file mode 100644 index a46d34d..0000000 --- a/ios/build/bots/chromium.webrtc.fyi.experimental/WebRTC Chromium FYI ios-device.json +++ /dev/null
@@ -1,23 +0,0 @@ -{ - "comments": [ - "Builder for 32-bit devices.", - "Build is performed with gn+ninja.", - "TODO(crbug.com/877018): graduate to chromium.webrtc.fyi when it works." - ], - "xcode build version": "10a254a", - "gn_args": [ - "additional_target_cpus=[ \"arm64\" ]", - "goma_dir=\"$(goma_dir)\"", - "ios_enable_code_signing=false", - "is_component_build=false", - "is_debug=false", - "target_cpu=\"arm\"", - "target_os=\"ios\"", - "use_goma=true" - ], - "additional_compile_targets": [ - "all" - ], - "tests": [ - ] -}
diff --git a/ios/build/bots/chromium.webrtc.fyi.experimental/WebRTC Chromium FYI ios-simulator.json b/ios/build/bots/chromium.webrtc.fyi.experimental/WebRTC Chromium FYI ios-simulator.json deleted file mode 100644 index 8aaa591..0000000 --- a/ios/build/bots/chromium.webrtc.fyi.experimental/WebRTC Chromium FYI ios-simulator.json +++ /dev/null
@@ -1,65 +0,0 @@ -{ - "comments": [ - "Runs tests on @3x, @2x, 64-bit, 32-bit, phone, tablet, iOS 10, and iOS 9.", - "TODO(crbug.com/877018): graduate to chromium.webrtc.fyi when it works." - ], - "xcode build version": "10a254a", - "gn_args": [ - "additional_target_cpus=[\"x86\"]", - "goma_dir=\"$(goma_dir)\"", - "ios_enable_code_signing=false", - "is_component_build=false", - "is_debug=true", - "symbol_level=1", - "target_cpu=\"x64\"", - "target_os=\"ios\"", - "use_goma=true" - ], - "additional_compile_targets": [ - "all" - ], - "configuration": "Debug", - "sdk": "iphonesimulator10.0", - "tests": [ - { - "include": "common_tests.json", - "device type": "iPhone 6s Plus", - "os": "10.0" - }, - { - "include": "common_tests.json", - "device type": "iPhone 6s", - "os": "10.0" - }, - { - "include": "common_tests.json", - "device type": "iPhone 5", - "os": "10.0" - }, - { - "include": "common_tests.json", - "device type": "iPad Air 2", - "os": "10.0" - }, - { - "include": "common_tests.json", - "device type": "iPad Retina", - "os": "10.0" - }, - { - "include": "common_tests.json", - "device type": "iPhone 5", - "comments": [ - "This still relies on system iOS 9.0 legacy simulators,", - "since Xcode 8.0 doesn't provide it. But our test runner", - "doesn't support Xcode 7.0 anymore..." - ], - "os": "9.0" - }, - { - "include": "common_tests.json", - "device type": "iPad Air 2", - "os": "9.0" - } - ] -}
diff --git a/ios/build/bots/chromium.webrtc.fyi/ios-device.json b/ios/build/bots/chromium.webrtc.fyi/WebRTC Chromium FYI ios-device.json similarity index 100% rename from ios/build/bots/chromium.webrtc.fyi/ios-device.json rename to ios/build/bots/chromium.webrtc.fyi/WebRTC Chromium FYI ios-device.json
diff --git a/ios/build/bots/chromium.webrtc.fyi/ios-simulator.json b/ios/build/bots/chromium.webrtc.fyi/WebRTC Chromium FYI ios-simulator.json similarity index 100% rename from ios/build/bots/chromium.webrtc.fyi/ios-simulator.json rename to ios/build/bots/chromium.webrtc.fyi/WebRTC Chromium FYI ios-simulator.json
diff --git a/ios/chrome/app/startup/setup_debugging.mm b/ios/chrome/app/startup/setup_debugging.mm index 5a49e40..ffc0220 100644 --- a/ios/chrome/app/startup/setup_debugging.mm +++ b/ios/chrome/app/startup/setup_debugging.mm
@@ -34,7 +34,6 @@ [whiteList addObject:@"glif-google-to-dots_28"]; // TODO(crbug.com/721338): Add missing image. [whiteList addObject:@"voice_icon_keyboard_accessory"]; - [whiteList addObject:@"voice_icon"]; // TODO(crbug.com/754032): Add missing image. [whiteList addObject:@"ios_default_avatar"];
diff --git a/ios/chrome/app/strings/ios_strings.grd b/ios/chrome/app/strings/ios_strings.grd index 581981e5..2f0c71b 100644 --- a/ios/chrome/app/strings/ios_strings.grd +++ b/ios/chrome/app/strings/ios_strings.grd
@@ -1722,22 +1722,22 @@ <message name="IDS_IOS_TOOLS_MENU_BOOKMARKS" desc="The iOS menu item for opening the bookmarks manager [Length: 15em] [iOS only]"> Bookmarks </message> - <message name="IDS_IOS_TOOLS_MENU_CLOSE_ALL_INCOGNITO_TABS" desc="The iOS menu item for closing all incognito tabs [Length: 15em] [iOS only]"> + <message name="IDS_IOS_TOOLS_MENU_CLOSE_ALL_INCOGNITO_TABS" desc="The iOS menu item for closing all incognito tabs [iOS only]" meaning="[Length: unlimited]"> Close All Incognito Tabs </message> - <message name="IDS_IOS_TOOLS_MENU_CLOSE_ALL_TABS" desc="The iOS menu item for closing all tabs [Length: 15em] [iOS only]"> + <message name="IDS_IOS_TOOLS_MENU_CLOSE_ALL_TABS" desc="The iOS menu item for closing all tabs [iOS only]" meaning="[Length: unlimited]"> Close All Tabs </message> - <message name="IDS_IOS_TOOLS_MENU_CLOSE_TAB" desc="The iOS menu item for closing a tab [Length: 15em] [iOS only]"> + <message name="IDS_IOS_TOOLS_MENU_CLOSE_TAB" desc="The iOS menu item for closing a tab [iOS only]" meaning="[Length: unlimited]"> Close Tab </message> - <message name="IDS_IOS_TOOLS_MENU_EDIT_BOOKMARK" desc="The iOS menu item for editing a bookmark [Length: 25em] [iOS only]"> + <message name="IDS_IOS_TOOLS_MENU_EDIT_BOOKMARK" desc="The iOS menu item for editing a bookmark [iOS only]" meaning="[Length: unlimited]"> Edit Bookmark </message> - <message name="IDS_IOS_TOOLS_MENU_FIND_IN_PAGE" desc="The iOS menu item for searching in the current page [Length: 15em] [iOS only]"> + <message name="IDS_IOS_TOOLS_MENU_FIND_IN_PAGE" desc="The iOS menu item for searching in the current page [iOS only]" meaning="Open the Find In Page menu [Length: unlimited]"> Find in Page... </message> - <message name="IDS_IOS_TOOLS_MENU_HELP_MOBILE" desc="The Tools menu item for bringing up online help page. [Length: 15em. Width of Tools menu.]"> + <message name="IDS_IOS_TOOLS_MENU_HELP_MOBILE" desc="The Tools menu item for bringing up online help page." meaning="Open the help menu [Length: unlimited]"> Help </message> <message name="IDS_IOS_TOOLS_MENU_HELP_URL" translateable="false"> @@ -1746,10 +1746,10 @@ <message name="IDS_IOS_TOOLS_MENU_HISTORY" desc="The Tools menu item for opening the navigation history menu"> History </message> - <message name="IDS_IOS_TOOLS_MENU_NEW_INCOGNITO_TAB" desc="The iOS menu item for opening a new incognito tab [Length: 15em] [iOS only]" meaning="Tools menu entry to create a new Incognito tab."> + <message name="IDS_IOS_TOOLS_MENU_NEW_INCOGNITO_TAB" desc="The iOS menu item for opening a new incognito tab [iOS only]" meaning="Tools menu entry to create a new Incognito tab. [Length: Unlimited]"> New Incognito Tab </message> - <message name="IDS_IOS_TOOLS_MENU_NEW_TAB" desc="The iOS menu item for opening a new tab [Length: 15em] [iOS only]" meaning="Tools menu entry to create a new tab."> + <message name="IDS_IOS_TOOLS_MENU_NEW_TAB" desc="The iOS menu item for opening a new tab [iOS only]" meaning="Tools menu entry to create a new tab. [Length: Unlimited]"> New Tab </message> <message name="IDS_IOS_TOOLS_MENU_PASTE_AND_GO" desc="The iOS menu item for pasting a URL or text in the omnibox and navigating to the page or searching for the text"> @@ -1758,22 +1758,22 @@ <message name="IDS_IOS_TOOLS_MENU_QR_SCANNER" desc="The iOS menu item for opening the QR Code Scanner screen, allowing the user to scan QR code."> Scan QR Code </message> - <message name="IDS_IOS_TOOLS_MENU_READING_LIST" desc="The iOS menu item for opening the reading list [Length: 15em] [iOS only]"> + <message name="IDS_IOS_TOOLS_MENU_READING_LIST" desc="The iOS menu item for opening the reading list [iOS only]" meaning="Open the Reading List menu. [Length: Unlimited]"> Reading List </message> - <message name="IDS_IOS_TOOLS_MENU_RECENT_TABS" desc="The iOS menu item for opening the panel showing the recently closed tabs and the tabs from other devices. [Length: 15em]" meaning="[In Title case] [iOS only]"> + <message name="IDS_IOS_TOOLS_MENU_RECENT_TABS" desc="The iOS menu item for opening the panel showing the recently closed tabs and the tabs from other devices." meaning="[In Title case] [iOS only] [Length: Unlimited]"> Recent Tabs </message> <message name="IDS_IOS_TOOLS_MENU_RELOAD" desc="The title of the button in the menu allowing the user to reload the page."> Reload </message> - <message name="IDS_IOS_TOOLS_MENU_REQUEST_DESKTOP_SITE" desc="The iOS menu item for requesting the desktop site [Length: 15em] [iOS only]"> + <message name="IDS_IOS_TOOLS_MENU_REQUEST_DESKTOP_SITE" desc="The iOS menu item for requesting the desktop site [iOS only]" meaning="Request the desktop version of the current web site. [Length: Unlimited]"> Request Desktop Site </message> - <message name="IDS_IOS_TOOLS_MENU_REQUEST_MOBILE_SITE" desc="The iOS menu item for requesting the mobile site [Length: 25em] [iOS only]"> + <message name="IDS_IOS_TOOLS_MENU_REQUEST_MOBILE_SITE" desc="The iOS menu item for requesting the mobile site [iOS only]" meaning="Request the mobile version of the current web site. [Length: Unlimited]"> Request Mobile Site </message> - <message name="IDS_IOS_TOOLS_MENU_SETTINGS" desc="The iOS menu item for opening the settings [Length: 15em] [iOS only]"> + <message name="IDS_IOS_TOOLS_MENU_SETTINGS" desc="The iOS menu item for opening the settings [iOS only]" meaning="Open the settings menu. [Length:Unlimited]"> Settings </message> <message name="IDS_IOS_TOOLS_MENU_SHARE" desc="The iOS menu item for sharing the current URL [Length: 15em] [iOS only]">
diff --git a/ios/chrome/browser/browser_state/test_chrome_browser_state.h b/ios/chrome/browser/browser_state/test_chrome_browser_state.h index 0630cb7e..71b231c 100644 --- a/ios/chrome/browser/browser_state/test_chrome_browser_state.h +++ b/ios/chrome/browser/browser_state/test_chrome_browser_state.h
@@ -103,17 +103,6 @@ RefcountedBrowserStateKeyedServiceFactory::TestingFactory testing_factory); - // Deprecated, do not use. This is kept for compatibility with downstream - // code and will be removed as soon as the downstream code has been fixed - // to use the new interface. - void AddTestingFactory( - BrowserStateKeyedServiceFactory* service_factory, - std::unique_ptr<KeyedService> (*testing_factory)(web::BrowserState*)); - void AddTestingFactory( - RefcountedBrowserStateKeyedServiceFactory* service_factory, - scoped_refptr<RefcountedKeyedService> (*testing_factory)( - web::BrowserState*)); - // Sets the path to the directory to be used to hold ChromeBrowserState // data. void SetPath(const base::FilePath& path);
diff --git a/ios/chrome/browser/browser_state/test_chrome_browser_state.mm b/ios/chrome/browser/browser_state/test_chrome_browser_state.mm index dee2a25..9f028ca 100644 --- a/ios/chrome/browser/browser_state/test_chrome_browser_state.mm +++ b/ios/chrome/browser/browser_state/test_chrome_browser_state.mm
@@ -377,25 +377,6 @@ std::move(testing_factory)); } -void TestChromeBrowserState::Builder::AddTestingFactory( - BrowserStateKeyedServiceFactory* service_factory, - std::unique_ptr<KeyedService> (*testing_factory)(web::BrowserState*)) { - BrowserStateKeyedServiceFactory::TestingFactory wrapped_factory; - if (testing_factory) - wrapped_factory = base::BindRepeating(testing_factory); - AddTestingFactory(service_factory, std::move(wrapped_factory)); -} - -void TestChromeBrowserState::Builder::AddTestingFactory( - RefcountedBrowserStateKeyedServiceFactory* service_factory, - scoped_refptr<RefcountedKeyedService> (*testing_factory)( - web::BrowserState*)) { - RefcountedBrowserStateKeyedServiceFactory::TestingFactory wrapped_factory; - if (testing_factory) - wrapped_factory = base::BindRepeating(testing_factory); - AddTestingFactory(service_factory, std::move(wrapped_factory)); -} - void TestChromeBrowserState::Builder::SetPath(const base::FilePath& path) { DCHECK(!build_called_); state_path_ = path;
diff --git a/ios/chrome/browser/google/google_logo_service.mm b/ios/chrome/browser/google/google_logo_service.mm index 6566328..a32eb82 100644 --- a/ios/chrome/browser/google/google_logo_service.mm +++ b/ios/chrome/browser/google/google_logo_service.mm
@@ -37,17 +37,17 @@ GoogleLogoService::GoogleLogoService( TemplateURLService* template_url_service, scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) - : LogoServiceImpl(DoodleDirectory(), - // Personalized Doodles aren't supported on iOS (see - // https://crbug.com/711314), so no need to pass a - // GaiaCookieManagerService. - /*cookie_service=*/nullptr, - template_url_service, - image_fetcher::CreateIOSImageDecoder(), - std::move(url_loader_factory), - /*want_gray_logo_getter=*/base::BindRepeating([] { - return !IsUIRefreshPhase1Enabled(); - })) {} + : LogoServiceImpl( + DoodleDirectory(), + // Personalized Doodles aren't supported on iOS (see + // https://crbug.com/711314), so no need to pass a + // GaiaCookieManagerService. + /*cookie_service=*/nullptr, + template_url_service, + image_fetcher::CreateIOSImageDecoder(), + std::move(url_loader_factory), + /*want_gray_logo_getter=*/base::BindRepeating([] { return false; })) { +} GoogleLogoService::~GoogleLogoService() {}
diff --git a/ios/chrome/browser/ntp_snippets/ios_chrome_content_suggestions_service_factory_util.cc b/ios/chrome/browser/ntp_snippets/ios_chrome_content_suggestions_service_factory_util.cc index 7509e87..204dbc5 100644 --- a/ios/chrome/browser/ntp_snippets/ios_chrome_content_suggestions_service_factory_util.cc +++ b/ios/chrome/browser/ntp_snippets/ios_chrome_content_suggestions_service_factory_util.cc
@@ -29,7 +29,6 @@ #include "components/ntp_snippets/features.h" #include "components/ntp_snippets/logger.h" #include "components/ntp_snippets/ntp_snippets_constants.h" -#include "components/ntp_snippets/reading_list/reading_list_suggestions_provider.h" #include "components/ntp_snippets/remote/persistent_scheduler.h" #include "components/ntp_snippets/remote/remote_suggestions_database.h" #include "components/ntp_snippets/remote/remote_suggestions_fetcher_impl.h" @@ -37,7 +36,6 @@ #include "components/ntp_snippets/remote/remote_suggestions_scheduler_impl.h" #include "components/ntp_snippets/remote/remote_suggestions_status_service_impl.h" #include "components/ntp_snippets/user_classifier.h" -#include "components/reading_list/core/reading_list_model.h" #include "components/version_info/version_info.h" #include "google_apis/google_api_keys.h" #include "ios/chrome/browser/application_context.h" @@ -45,7 +43,6 @@ #include "ios/chrome/browser/favicon/ios_chrome_large_icon_service_factory.h" #include "ios/chrome/browser/history/history_service_factory.h" #include "ios/chrome/browser/pref_names.h" -#include "ios/chrome/browser/reading_list/reading_list_model_factory.h" #include "ios/chrome/browser/signin/identity_manager_factory.h" #include "ios/chrome/browser/ui/ui_util.h" #include "ios/chrome/common/channel_info.h" @@ -95,7 +92,6 @@ ContentSuggestionsService* suggestions_service = static_cast<ContentSuggestionsService*>(service.get()); - ntp_snippets::RegisterReadingListProvider(suggestions_service, browser_state); if (base::FeatureList::IsEnabled(ntp_snippets::kArticleSuggestionsFeature)) { ntp_snippets::RegisterRemoteSuggestionsProvider(suggestions_service, browser_state); @@ -142,24 +138,6 @@ std::move(scheduler), std::move(debug_logger)); } -void RegisterReadingListProvider(ContentSuggestionsService* service, - web::BrowserState* browser_state) { - // Prevent loading any reading list items for refresh. - if (IsUIRefreshPhase1Enabled()) - return; - - ios::ChromeBrowserState* chrome_browser_state = - ios::ChromeBrowserState::FromBrowserState(browser_state); - - ReadingListModel* reading_list_model = - ReadingListModelFactory::GetForBrowserState(chrome_browser_state); - std::unique_ptr<ntp_snippets::ReadingListSuggestionsProvider> - reading_list_suggestions_provider = - std::make_unique<ntp_snippets::ReadingListSuggestionsProvider>( - service, reading_list_model); - service->RegisterProvider(std::move(reading_list_suggestions_provider)); -} - void RegisterRemoteSuggestionsProvider(ContentSuggestionsService* service, web::BrowserState* browser_state) { ios::ChromeBrowserState* chrome_browser_state =
diff --git a/ios/chrome/browser/ntp_snippets/ios_chrome_content_suggestions_service_factory_util.h b/ios/chrome/browser/ntp_snippets/ios_chrome_content_suggestions_service_factory_util.h index 39fb7250..f6ab9fc 100644 --- a/ios/chrome/browser/ntp_snippets/ios_chrome_content_suggestions_service_factory_util.h +++ b/ios/chrome/browser/ntp_snippets/ios_chrome_content_suggestions_service_factory_util.h
@@ -25,10 +25,6 @@ std::unique_ptr<KeyedService> CreateChromeContentSuggestionsService( web::BrowserState* browser_state); -// Registers the Reading List provider. -void RegisterReadingListProvider(ContentSuggestionsService* service, - web::BrowserState* browser_state); - // Registers the RemoteSuggestionsProvider (articles provider). void RegisterRemoteSuggestionsProvider(ContentSuggestionsService* service, web::BrowserState* browser_state);
diff --git a/ios/chrome/browser/passwords/ios_chrome_password_store_factory.cc b/ios/chrome/browser/passwords/ios_chrome_password_store_factory.cc index f324428..67394d8 100644 --- a/ios/chrome/browser/passwords/ios_chrome_password_store_factory.cc +++ b/ios/chrome/browser/passwords/ios_chrome_password_store_factory.cc
@@ -7,6 +7,7 @@ #include <memory> #include <utility> +#include "base/bind_helpers.h" #include "base/command_line.h" #include "base/memory/singleton.h" #include "base/sequenced_task_runner.h" @@ -102,8 +103,8 @@ return nullptr; } password_manager_util::RemoveUselessCredentials( - store, ios::ChromeBrowserState::FromBrowserState(context)->GetPrefs(), - 60); + store, ios::ChromeBrowserState::FromBrowserState(context)->GetPrefs(), 60, + base::NullCallback()); return store; }
diff --git a/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_cell.mm b/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_cell.mm index bfc2199..f19f6b7f 100644 --- a/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_cell.mm +++ b/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_cell.mm
@@ -4,12 +4,10 @@ #import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_cell.h" -#import "ios/chrome/browser/ui/colors/MDCPalette+CrAdditions.h" #include "ios/chrome/browser/ui/ui_util.h" #import "ios/chrome/browser/ui/util/i18n_string.h" #import "ios/chrome/common/favicon/favicon_view.h" #import "ios/chrome/common/ui_util/constraints_ui_util.h" -#import "ios/third_party/material_components_ios/src/components/Palettes/src/MaterialPalettes.h" #import "ios/third_party/material_components_ios/src/components/Typography/src/MaterialTypography.h" #if !defined(__has_feature) || !__has_feature(objc_arc) @@ -18,11 +16,8 @@ namespace { const CGFloat kImageSize = 80; -const CGFloat kImageSizeLegacy = 62; const CGFloat kStandardSpacing = 13; -const CGFloat kStandardSpacingLegacy = 16; const CGFloat kSmallSpacing = 7; -const CGFloat kSmallSpacingLegacy = 8; // Size of the favicon view. const CGFloat kFaviconSize = 16; @@ -59,10 +54,6 @@ // Applies the constraints on the elements. Called in the init. - (void)applyConstraints; -// Helpers to account for legacy sizes -+ (CGFloat)imageSize; -+ (CGFloat)smallSpacing; - @end @implementation ContentSuggestionsCell @@ -82,10 +73,8 @@ if (self) { _titleLabel = [[UILabel alloc] initWithFrame:CGRectZero]; _imageContainer = [[UIView alloc] initWithFrame:CGRectZero]; - if (IsUIRefreshPhase1Enabled()) { - _imageContainer.layer.cornerRadius = 11; - _imageContainer.layer.masksToBounds = YES; - } + _imageContainer.layer.cornerRadius = 11; + _imageContainer.layer.masksToBounds = YES; _noImageIcon = [[UIImageView alloc] initWithFrame:CGRectZero]; _additionalInformationLabel = [[UILabel alloc] initWithFrame:CGRectZero]; _contentImageView = [[UIImageView alloc] initWithFrame:CGRectZero]; @@ -120,13 +109,8 @@ [[self class] configureTitleLabel:_titleLabel]; _additionalInformationLabel.font = [[self class] additionalInformationFont]; _faviconView.font = [[MDCTypography fontLoader] mediumFontOfSize:10]; - if (IsUIRefreshPhase1Enabled()) { - _additionalInformationLabel.textColor = - [UIColor colorWithWhite:0 alpha:0.54]; - } else { - _additionalInformationLabel.textColor = - [[MDCPalette greyPalette] tint700]; - } + _additionalInformationLabel.textColor = + [UIColor colorWithWhite:0 alpha:0.54]; [self applyConstraints]; } @@ -168,8 +152,8 @@ - (void)setDisplayImage:(BOOL)displayImage { if (displayImage) { - self.imageTitleSpacing.constant = [[self class] standardSpacing]; - self.imageSizeConstraint.constant = [[self class] imageSize]; + self.imageTitleSpacing.constant = kStandardSpacing; + self.imageSizeConstraint.constant = kImageSize; self.imageContainer.hidden = NO; } else { self.imageTitleSpacing.constant = 0; @@ -196,28 +180,15 @@ CGSize sizeForLabels = CGSizeMake(width - [self labelMarginWithImage:hasImage], 500); - if (IsUIRefreshPhase1Enabled()) { - CGFloat minimalHeight = - [[self class] imageSize] + [[self class] standardSpacing]; + CGFloat minimalHeight = kImageSize + kStandardSpacing; - CGFloat labelHeight = [[self class] standardSpacing]; - labelHeight += [titleLabel sizeThatFits:sizeForLabels].height; - labelHeight += [[self class] smallSpacing]; - CGFloat additionalInfoHeight = - [additionalInfoLabel sizeThatFits:sizeForLabels].height; - labelHeight += MAX(additionalInfoHeight, kFaviconSize); - return MAX(minimalHeight, labelHeight); - } else { - CGFloat labelHeight = 3 * [[self class] standardSpacing]; - labelHeight += [titleLabel sizeThatFits:sizeForLabels].height; - CGFloat additionalInfoHeight = - [additionalInfoLabel sizeThatFits:sizeForLabels].height; - labelHeight += MAX(additionalInfoHeight, kFaviconSize); - - CGFloat minimalHeight = hasImage ? [[self class] imageSize] : 0; - minimalHeight += 2 * [[self class] standardSpacing]; - return MAX(minimalHeight, labelHeight); - } + CGFloat labelHeight = kStandardSpacing; + labelHeight += [titleLabel sizeThatFits:sizeForLabels].height; + labelHeight += kSmallSpacing; + CGFloat additionalInfoHeight = + [additionalInfoLabel sizeThatFits:sizeForLabels].height; + labelHeight += MAX(additionalInfoHeight, kFaviconSize); + return MAX(minimalHeight, labelHeight); } #pragma mark - UICollectionViewCell @@ -232,9 +203,8 @@ - (void)traitCollectionDidChange:(UITraitCollection*)previousTraitCollection { [super traitCollectionDidChange:previousTraitCollection]; - if (IsUIRefreshPhase1Enabled() && - self.traitCollection.preferredContentSizeCategory != - previousTraitCollection.preferredContentSizeCategory) { + if (self.traitCollection.preferredContentSizeCategory != + previousTraitCollection.preferredContentSizeCategory) { [[self class] configureTitleLabel:_titleLabel]; _additionalInformationLabel.font = [[self class] additionalInformationFont]; } @@ -252,8 +222,7 @@ self.titleLabel.preferredMaxLayoutWidth = parentWidth - [[self class] labelMarginWithImage:self.displayImage]; self.additionalInformationLabel.preferredMaxLayoutWidth = - parentWidth - kFaviconSize - [[self class] smallSpacing] - - 2 * [[self class] standardSpacing]; + parentWidth - kFaviconSize - kSmallSpacing - 2 * kStandardSpacing; // Re-layout with the new preferred width to allow the label to adjust its // height. @@ -263,43 +232,17 @@ #pragma mark - Private - (void)applyConstraints { - _imageSizeConstraint = [_imageContainer.heightAnchor - constraintEqualToConstant:[[self class] imageSize]]; + _imageSizeConstraint = + [_imageContainer.heightAnchor constraintEqualToConstant:kImageSize]; _imageTitleSpacing = [_titleLabel.leadingAnchor constraintEqualToAnchor:_imageContainer.trailingAnchor - constant:[[self class] standardSpacing]]; - - if (IsUIRefreshPhase1Enabled()) { - [NSLayoutConstraint activateConstraints:@[ - [_imageContainer.bottomAnchor - constraintLessThanOrEqualToAnchor:_faviconView.bottomAnchor], - [_faviconView.topAnchor - constraintGreaterThanOrEqualToAnchor:self.titleLabel.bottomAnchor - constant:[[self class] smallSpacing]] - ]]; - } else { - [NSLayoutConstraint activateConstraints:@[ - [_imageContainer.bottomAnchor - constraintLessThanOrEqualToAnchor:self.contentView.bottomAnchor - constant:-[[self class] standardSpacing]], - [_additionalInformationLabel.topAnchor - constraintGreaterThanOrEqualToAnchor:_titleLabel.bottomAnchor - constant:[[self class] standardSpacing]], - [_additionalInformationLabel.bottomAnchor - constraintLessThanOrEqualToAnchor:self.contentView.bottomAnchor - constant:-[[self class] standardSpacing]], - [_faviconView.topAnchor - constraintGreaterThanOrEqualToAnchor:_titleLabel.bottomAnchor - constant:[[self class] standardSpacing]], - [_faviconView.bottomAnchor - constraintLessThanOrEqualToAnchor:self.contentView.bottomAnchor - constant:-[[self class] standardSpacing]], - ]]; - } + constant:kStandardSpacing]; [NSLayoutConstraint activateConstraints:@[ // Image. _imageSizeConstraint, + [_imageContainer.bottomAnchor + constraintLessThanOrEqualToAnchor:_faviconView.bottomAnchor], [_imageContainer.widthAnchor constraintEqualToAnchor:_imageContainer.heightAnchor], [_imageContainer.topAnchor constraintEqualToAnchor:_titleLabel.topAnchor], @@ -319,6 +262,9 @@ [_faviconView.heightAnchor constraintEqualToConstant:kFaviconSize], [_faviconView.widthAnchor constraintEqualToAnchor:_faviconView.heightAnchor], + [_faviconView.topAnchor + constraintGreaterThanOrEqualToAnchor:self.titleLabel.bottomAnchor + constant:kSmallSpacing], // No image icon. [_noImageIcon.centerXAnchor @@ -344,60 +290,39 @@ @"additional" : _additionalInformationLabel, @"favicon" : _faviconView, }, - @{ - @"space" : @([[self class] standardSpacing]), - @"small" : @([[self class] smallSpacing]) - }); -} - -+ (CGFloat)imageSize { - return IsUIRefreshPhase1Enabled() ? kImageSize : kImageSizeLegacy; + @{ @"space" : @(kStandardSpacing), + @"small" : @(kSmallSpacing) }); } + (CGFloat)standardSpacing { - return IsUIRefreshPhase1Enabled() ? kStandardSpacing : kStandardSpacingLegacy; -} - -+ (CGFloat)smallSpacing { - return IsUIRefreshPhase1Enabled() ? kSmallSpacing : kSmallSpacingLegacy; + return kStandardSpacing; } // Configures the |titleLabel|. + (void)configureTitleLabel:(UILabel*)titleLabel { - if (IsUIRefreshPhase1Enabled()) { - titleLabel.textColor = [UIColor colorWithWhite:0 alpha:0.8]; - UIFontDescriptor* descriptor = [[UIFontDescriptor - preferredFontDescriptorWithTextStyle:UIFontTextStyleSubheadline] - fontDescriptorWithSymbolicTraits:UIFontDescriptorTraitBold]; - titleLabel.font = [UIFont fontWithDescriptor:descriptor size:0]; - titleLabel.numberOfLines = 3; - } else { - titleLabel.font = [MDCTypography subheadFont]; - titleLabel.numberOfLines = 2; - } + titleLabel.textColor = [UIColor colorWithWhite:0 alpha:0.8]; + UIFontDescriptor* descriptor = [[UIFontDescriptor + preferredFontDescriptorWithTextStyle:UIFontTextStyleSubheadline] + fontDescriptorWithSymbolicTraits:UIFontDescriptorTraitBold]; + titleLabel.font = [UIFont fontWithDescriptor:descriptor size:0]; + titleLabel.numberOfLines = 3; } // Returns the font used to display the additional informations. + (UIFont*)additionalInformationFont { - if (IsUIRefreshPhase1Enabled()) { - return [UIFont preferredFontForTextStyle:UIFontTextStyleCaption2]; - } else { - return [MDCTypography captionFont]; - } + return [UIFont preferredFontForTextStyle:UIFontTextStyleCaption2]; } // Returns the margin for the labels, depending if the cell |hasImage|. + (CGFloat)labelMarginWithImage:(BOOL)hasImage { - CGFloat offset = - hasImage ? [[self class] imageSize] + [[self class] standardSpacing] : 0; - return 2 * [[self class] standardSpacing] + offset; + CGFloat offset = hasImage ? kImageSize + kStandardSpacing : 0; + return 2 * kStandardSpacing + offset; } // Returns the attributed string to be displayed. + (NSString*)stringForPublisher:(NSString*)publisherName date:(NSString*)date { - NSString* sep = IsUIRefreshPhase1Enabled() ? @"•" : @"-"; return AdjustStringForLocaleDirection( - [NSString stringWithFormat:@"%@ %@ %@ ", publisherName, sep, date]); + [NSString stringWithFormat:@"%@ • %@ ", publisherName, date]); } @end
diff --git a/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_footer_item.mm b/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_footer_item.mm index b2e7062..c2e5ade 100644 --- a/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_footer_item.mm +++ b/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_footer_item.mm
@@ -14,7 +14,6 @@ #endif namespace { -const CGFloat kButtonMargin = 2; const CGFloat kButtonPadding = 16; } @@ -89,10 +88,8 @@ _activityIndicator.translatesAutoresizingMaskIntoConstraints = NO; _button = [UIButton buttonWithType:UIButtonTypeSystem]; _button.translatesAutoresizingMaskIntoConstraints = NO; - if (IsUIRefreshPhase1Enabled()) { - _button.titleLabel.font = - [UIFont preferredFontForTextStyle:UIFontTextStyleFootnote]; - } + _button.titleLabel.font = + [UIFont preferredFontForTextStyle:UIFontTextStyleFootnote]; _button.contentEdgeInsets = UIEdgeInsetsMake(0, kButtonPadding, 0, kButtonPadding); [_button addTarget:self @@ -103,14 +100,7 @@ [self.contentView addSubview:_activityIndicator]; AddSameConstraints(self.contentView, _activityIndicator); - if (IsUIRefreshPhase1Enabled()) { - AddSameConstraints(self.contentView, _button); - } else { - ApplyVisualConstraintsWithMetrics( - @[ @"V:|-(margin)-[button]-(margin)-|", @"H:|-(margin)-[button]" ], - @{@"button" : _button}, - @{ @"margin" : @(kButtonMargin) }); - } + AddSameConstraints(self.contentView, _button); } return self; }
diff --git a/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_learn_more_item.mm b/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_learn_more_item.mm index 440a16a..ffda5aea0 100644 --- a/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_learn_more_item.mm +++ b/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_learn_more_item.mm
@@ -112,11 +112,7 @@ + (void)configureLabel:(UILabel*)label withText:(NSString*)text { label.numberOfLines = 0; label.textColor = [[MDCPalette greyPalette] tint700]; - if (IsUIRefreshPhase1Enabled()) { - label.font = [UIFont preferredFontForTextStyle:UIFontTextStyleFootnote]; - } else { - label.font = [MDCTypography italicFontFromFont:[MDCTypography captionFont]]; - } + label.font = [UIFont preferredFontForTextStyle:UIFontTextStyleFootnote]; NSRange linkRange; NSString* strippedText = ParseStringWithLink(text, &linkRange); DCHECK_NE(NSNotFound, static_cast<NSInteger>(linkRange.location));
diff --git a/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_cell.mm b/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_cell.mm index 14b67ee..c0c11286 100644 --- a/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_cell.mm +++ b/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_cell.mm
@@ -9,18 +9,11 @@ #import "ios/chrome/common/favicon/favicon_view.h" #import "ios/chrome/common/material_timing.h" #import "ios/chrome/common/ui_util/constraints_ui_util.h" -#import "ios/third_party/material_components_ios/src/components/Typography/src/MaterialTypography.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." #endif -namespace { - -const CGFloat kIconSizeLegacy = 48; - -} // namespace - @implementation ContentSuggestionsMostVisitedCell : MDCCollectionViewCell @synthesize faviconView = _faviconView; @@ -32,62 +25,39 @@ self = [super initWithFrame:frame]; if (self) { _titleLabel = [[UILabel alloc] init]; - if (IsUIRefreshPhase1Enabled()) { - _titleLabel.textColor = [UIColor colorWithWhite:0 alpha:kTitleAlpha]; - _titleLabel.font = [UIFont systemFontOfSize:12]; - } else { - _titleLabel.textColor = - [UIColor colorWithWhite:kLabelTextColor alpha:1.0]; - _titleLabel.font = [MDCTypography captionFont]; - } + _titleLabel.textColor = [UIColor colorWithWhite:0 alpha:kTitleAlpha]; + _titleLabel.font = [UIFont systemFontOfSize:12]; _titleLabel.textAlignment = NSTextAlignmentCenter; _titleLabel.preferredMaxLayoutWidth = [[self class] defaultSize].width; _titleLabel.numberOfLines = kLabelNumLines; _faviconView = [[FaviconViewNew alloc] init]; - if (IsUIRefreshPhase1Enabled()) { - _faviconView.font = [UIFont systemFontOfSize:22]; - } else { - _faviconView.font = [MDCTypography headlineFont]; - } + _faviconView.font = [UIFont systemFontOfSize:22]; _titleLabel.translatesAutoresizingMaskIntoConstraints = NO; _faviconView.translatesAutoresizingMaskIntoConstraints = NO; [self.contentView addSubview:_titleLabel]; UIView* containerView = nil; - if (IsUIRefreshPhase1Enabled()) { - UIImageView* faviconContainer = - [[UIImageView alloc] initWithFrame:self.bounds]; - faviconContainer.translatesAutoresizingMaskIntoConstraints = NO; - faviconContainer.image = [UIImage imageNamed:@"ntp_most_visited_tile"]; - [self.contentView addSubview:faviconContainer]; - [faviconContainer addSubview:_faviconView]; + UIImageView* faviconContainer = + [[UIImageView alloc] initWithFrame:self.bounds]; + faviconContainer.translatesAutoresizingMaskIntoConstraints = NO; + faviconContainer.image = [UIImage imageNamed:@"ntp_most_visited_tile"]; + [self.contentView addSubview:faviconContainer]; + [faviconContainer addSubview:_faviconView]; - [NSLayoutConstraint activateConstraints:@[ - [faviconContainer.widthAnchor constraintEqualToConstant:kIconSize], - [faviconContainer.heightAnchor - constraintEqualToAnchor:faviconContainer.widthAnchor], - [faviconContainer.centerXAnchor - constraintEqualToAnchor:_titleLabel.centerXAnchor], - [_faviconView.heightAnchor constraintEqualToConstant:32], - [_faviconView.widthAnchor - constraintEqualToAnchor:_faviconView.heightAnchor], - ]]; - AddSameCenterConstraints(_faviconView, faviconContainer); - containerView = faviconContainer; - } else { - [self.contentView addSubview:_faviconView]; - - [NSLayoutConstraint activateConstraints:@[ - [_faviconView.widthAnchor constraintEqualToConstant:kIconSizeLegacy], - [_faviconView.heightAnchor - constraintEqualToAnchor:_faviconView.widthAnchor], - [_faviconView.centerXAnchor - constraintEqualToAnchor:_titleLabel.centerXAnchor], - ]]; - containerView = _faviconView; - } + [NSLayoutConstraint activateConstraints:@[ + [faviconContainer.widthAnchor constraintEqualToConstant:kIconSize], + [faviconContainer.heightAnchor + constraintEqualToAnchor:faviconContainer.widthAnchor], + [faviconContainer.centerXAnchor + constraintEqualToAnchor:_titleLabel.centerXAnchor], + [_faviconView.heightAnchor constraintEqualToConstant:32], + [_faviconView.widthAnchor + constraintEqualToAnchor:_faviconView.heightAnchor], + ]]; + AddSameCenterConstraints(_faviconView, faviconContainer); + containerView = faviconContainer; ApplyVisualConstraintsWithMetrics( @[ @"V:|[container]-(space)-[title]", @"H:|[title]|" ],
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_updater.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_updater.mm index 45fa7bd..55af203 100644 --- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_updater.mm +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_updater.mm
@@ -663,59 +663,31 @@ if (![model headerForSectionWithIdentifier:sectionIdentifier] && sectionInfo.title) { - BOOL addHeader = YES; - - if (IsFromContentSuggestionsService(sectionIdentifier)) { - addHeader = IsUIRefreshPhase1Enabled(); - - if ([self.sectionIdentifiersFromContentSuggestions - containsObject:@(sectionIdentifier)]) { - return; - } - - if ([self.sectionIdentifiersFromContentSuggestions count] == 1) { - NSNumber* existingSectionIdentifier = - [self.sectionIdentifiersFromContentSuggestions anyObject]; - ContentSuggestionsSectionInformation* existingSectionInfo = - self.sectionInfoBySectionIdentifier[existingSectionIdentifier]; - [model setHeader:[self headerForSectionInfo:existingSectionInfo] - forSectionWithIdentifier:[existingSectionIdentifier integerValue]]; - addHeader = YES; - } else if ([self.sectionIdentifiersFromContentSuggestions count] > 1) { - addHeader = YES; - } - - [self.sectionIdentifiersFromContentSuggestions - addObject:@(sectionIdentifier)]; + DCHECK(IsFromContentSuggestionsService(sectionIdentifier)); + if ([self.sectionIdentifiersFromContentSuggestions + containsObject:@(sectionIdentifier)]) { + return; } - - if (addHeader) { - [model setHeader:[self headerForSectionInfo:sectionInfo] - forSectionWithIdentifier:sectionIdentifier]; - } + [self.sectionIdentifiersFromContentSuggestions + addObject:@(sectionIdentifier)]; + [model setHeader:[self headerForSectionInfo:sectionInfo] + forSectionWithIdentifier:sectionIdentifier]; } } // Returns the header for this |sectionInfo|. - (CollectionViewItem*)headerForSectionInfo: (ContentSuggestionsSectionInformation*)sectionInfo { - if (IsUIRefreshPhase1Enabled()) { - DCHECK(SectionIdentifierForInfo(sectionInfo) == SectionIdentifierArticles); - __weak ContentSuggestionsCollectionUpdater* weakSelf = self; - ContentSuggestionsArticlesHeaderItem* header = - [[ContentSuggestionsArticlesHeaderItem alloc] - initWithType:ItemTypeHeader - title:sectionInfo.title - callback:^{ - [weakSelf.dataSource toggleArticlesVisibility]; - }]; - header.expanded = sectionInfo.expanded; - return header; - } - CollectionViewTextItem* header = - [[CollectionViewTextItem alloc] initWithType:ItemTypeHeader]; - header.text = sectionInfo.title; - header.textColor = [[MDCPalette greyPalette] tint500]; + DCHECK(SectionIdentifierForInfo(sectionInfo) == SectionIdentifierArticles); + __weak ContentSuggestionsCollectionUpdater* weakSelf = self; + ContentSuggestionsArticlesHeaderItem* header = + [[ContentSuggestionsArticlesHeaderItem alloc] + initWithType:ItemTypeHeader + title:sectionInfo.title + callback:^{ + [weakSelf.dataSource toggleArticlesVisibility]; + }]; + header.expanded = sectionInfo.expanded; return header; }
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_utils.h b/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_utils.h index 2c1cfd8..f40b75f 100644 --- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_utils.h +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_utils.h
@@ -59,10 +59,6 @@ // Returns the nearest ancestor of |view| that is kind of |aClass|. UIView* nearestAncestor(UIView* view, Class aClass); -// Helper methods to support RxR for UIRefreshPhase1 and IpadIdiom pre-Refresh. -BOOL IsRegularXRegularSizeClass(id<UITraitEnvironment> environment); -BOOL IsRegularXRegularSizeClass(); - } // namespace content_suggestions #endif // IOS_CHROME_BROWSER_UI_CONTENT_SUGGESTIONS_CONTENT_SUGGESTIONS_COLLECTION_UTILS_H_
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_utils.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_utils.mm index 562adf2..f40579f 100644 --- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_utils.mm +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_utils.mm
@@ -13,7 +13,6 @@ #include "ios/chrome/browser/ui/ui_util.h" #import "ios/chrome/browser/ui/uikit_ui_util.h" #include "ios/chrome/grit/ios_strings.h" -#import "ios/third_party/material_components_ios/src/components/Typography/src/MaterialTypography.h" #include "ui/base/l10n/l10n_util.h" #if !defined(__has_feature) || !__has_feature(objc_arc) @@ -26,32 +25,21 @@ const CGFloat kHorizontalSpacingRegularXRegular = 19; const CGFloat kHorizontalSpacingOther = 9; const CGFloat kVerticalSpacing = 16; -const CGFloat kSpacingIPhone = 16; -const CGFloat kSpacingIPad = 24; // Width of search field. const CGFloat kSearchFieldLarge = 432; const CGFloat kSearchFieldSmall = 343; const CGFloat kSearchFieldMinMargin = 8; -const CGFloat kMinSearchFieldWidthLegacy = 50; // Veritcla margin of search hint text. const CGFloat kSearchHintMargin = 3; -// Offset to align the hint of the fake omnibox with the one in the toolbar. -const CGFloat kSearchHintVerticalOffset = 0.5; -// Maximum margin for the search field. -const CGFloat kMaxSearchFieldFrameMargin = 200; - // Top margin for the doodle. const CGFloat kDoodleTopMarginRegularXRegular = 162; const CGFloat kDoodleTopMarginOther = 58; -const CGFloat kDoodleTopMarginIPadLegacy = 82; // Top margin for the search field const CGFloat kSearchFieldTopMargin = 32; -const CGFloat kSearchFieldTopMarginIPhoneLegacy = 32; -const CGFloat kSearchFieldTopMarginIPadLegacy = 82; // Bottom margin for the search field. const CGFloat kNTPSearchFieldBottomPadding = 16; @@ -73,13 +61,6 @@ // engine. const CGFloat kNonGoogleSearchHeaderHeightIPad = 10; -// Returns the width necessary to fit |numberOfItem| items, with no padding on -// the side. -CGFloat widthForNumberOfItem(NSUInteger numberOfItem) { - return (numberOfItem - 1) * - content_suggestions::horizontalSpacingBetweenTiles() + - numberOfItem * [ContentSuggestionsMostVisitedCell defaultSize].width; -} } namespace content_suggestions { @@ -91,36 +72,17 @@ const NSUInteger kMostVisitedItemsPerLine = 4; NSUInteger numberOfTilesForWidth(CGFloat availableWidth) { - if (IsUIRefreshPhase1Enabled()) { - return kMostVisitedItemsPerLine; - } - - if (availableWidth > widthForNumberOfItem(4)) - return 4; - if (availableWidth > widthForNumberOfItem(3)) - return 3; - if (availableWidth > widthForNumberOfItem(2)) - return 2; - - return 1; + return kMostVisitedItemsPerLine; } CGFloat horizontalSpacingBetweenTiles() { - if (IsUIRefreshPhase1Enabled()) { - return (!IsCompactWidth() && !IsCompactHeight()) - ? kHorizontalSpacingRegularXRegular - : kHorizontalSpacingOther; - } else { - return IsIPadIdiom() ? kSpacingIPad : kSpacingIPhone; - } + return (!IsCompactWidth() && !IsCompactHeight()) + ? kHorizontalSpacingRegularXRegular + : kHorizontalSpacingOther; } CGFloat verticalSpacingBetweenTiles() { - if (IsUIRefreshPhase1Enabled()) { - return kVerticalSpacing; - } else { - return horizontalSpacingBetweenTiles(); - } + return kVerticalSpacing; } CGFloat centeredTilesMarginForWidth(CGFloat width) { @@ -131,14 +93,10 @@ (columns * [ContentSuggestionsMostVisitedCell defaultSize].width) - ((columns - 1) * horizontalSpace); CGFloat margin = AlignValueToPixel(whitespace / 2); - if (IsUIRefreshPhase1Enabled()) { - // Allow for less spacing as an edge case on smaller devices. - if (margin < horizontalSpace) { - DCHECK(width < 400); // For now this is only expected on small widths. - return fmaxf(margin, 0); - } - } else { - DCHECK(margin > horizontalSpace); + // Allow for less spacing as an edge case on smaller devices. + if (margin < horizontalSpace) { + DCHECK(width < 400); // For now this is only expected on small widths. + return fmaxf(margin, 0); } return margin; } @@ -151,37 +109,21 @@ } CGFloat doodleTopMargin(BOOL toolbarPresent) { - if (IsUIRefreshPhase1Enabled()) { - if (!IsCompactWidth() && !IsCompactHeight()) - return kDoodleTopMarginRegularXRegular; - return StatusBarHeight() + kDoodleTopMarginOther; - } - if (IsIPadIdiom()) - return kDoodleTopMarginIPadLegacy; - return toolbarPresent ? ntp_header::ToolbarHeight() : 0; + if (!IsCompactWidth() && !IsCompactHeight()) + return kDoodleTopMarginRegularXRegular; + return StatusBarHeight() + kDoodleTopMarginOther; } CGFloat searchFieldTopMargin() { - if (IsUIRefreshPhase1Enabled()) { - return kSearchFieldTopMargin; - } - if (IsIPadIdiom()) - return kSearchFieldTopMarginIPadLegacy; - return kSearchFieldTopMarginIPhoneLegacy; + return kSearchFieldTopMargin; } CGFloat searchFieldWidth(CGFloat superviewWidth) { - if (IsUIRefreshPhase1Enabled()) { - if (!IsCompactWidth() && !IsCompactHeight()) - return kSearchFieldLarge; + if (!IsCompactWidth() && !IsCompactHeight()) + return kSearchFieldLarge; - // Special case for narrow sizes. - return MIN(kSearchFieldSmall, superviewWidth - kSearchFieldMinMargin * 2); - } - CGFloat margin = centeredTilesMarginForWidth(superviewWidth); - if (margin > kMaxSearchFieldFrameMargin) - margin = kMaxSearchFieldFrameMargin; - return fmax(superviewWidth - 2 * margin, kMinSearchFieldWidthLegacy); + // Special case for narrow sizes. + return MIN(kSearchFieldSmall, superviewWidth - kSearchFieldMinMargin * 2); } CGFloat heightForLogoHeader(BOOL logoIsShowing, @@ -208,37 +150,24 @@ [searchHintLabel setTranslatesAutoresizingMaskIntoConstraints:NO]; [searchTapTarget addSubview:searchHintLabel]; - CGFloat centerYOffsetConstant = - IsUIRefreshPhase1Enabled() ? 0 : kSearchHintVerticalOffset; [NSLayoutConstraint activateConstraints:@[ [searchHintLabel.centerYAnchor - constraintEqualToAnchor:searchTapTarget.centerYAnchor - constant:centerYOffsetConstant], + constraintEqualToAnchor:searchTapTarget.centerYAnchor], [searchHintLabel.heightAnchor constraintEqualToConstant:kSearchFieldHeight - 2 * kSearchHintMargin], ]]; - if (IsUIRefreshPhase1Enabled()) { - [searchHintLabel.centerXAnchor - constraintEqualToAnchor:searchTapTarget.centerXAnchor] - .active = YES; - } + [searchHintLabel.centerXAnchor + constraintEqualToAnchor:searchTapTarget.centerXAnchor] + .active = YES; [searchHintLabel setText:l10n_util::GetNSString(IDS_OMNIBOX_EMPTY_HINT)]; if (base::i18n::IsRTL()) { [searchHintLabel setTextAlignment:NSTextAlignmentRight]; } - if (IsUIRefreshPhase1Enabled()) { - [searchHintLabel setTextColor:[UIColor colorWithWhite:0 alpha:kHintAlpha]]; - searchHintLabel.font = [UIFont systemFontOfSize:17]; - searchHintLabel.textAlignment = NSTextAlignmentCenter; - } else { - [searchHintLabel - setTextColor: - [UIColor colorWithWhite:kiPhoneLocationBarPlaceholderColorBrightness - alpha:1.0]]; - [searchHintLabel setFont:[MDCTypography subheadFont]]; - } + [searchHintLabel setTextColor:[UIColor colorWithWhite:0 alpha:kHintAlpha]]; + searchHintLabel.font = [UIFont systemFontOfSize:17]; + searchHintLabel.textAlignment = NSTextAlignmentCenter; } void configureVoiceSearchButton(UIButton* voiceSearchButton, @@ -257,15 +186,10 @@ [voiceSearchButton setAdjustsImageWhenHighlighted:NO]; - UIImage* micImage = - IsUIRefreshPhase1Enabled() - ? [[UIImage imageNamed:@"location_bar_voice"] - imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal] - : [UIImage imageNamed:@"voice_icon"]; + UIImage* micImage = [[UIImage imageNamed:@"location_bar_voice"] + imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]; [voiceSearchButton setImage:micImage forState:UIControlStateNormal]; - if (IsUIRefreshPhase1Enabled()) { - voiceSearchButton.tintColor = [UIColor colorWithWhite:0 alpha:0.7]; - } + voiceSearchButton.tintColor = [UIColor colorWithWhite:0 alpha:0.7]; [voiceSearchButton setAccessibilityLabel:l10n_util::GetNSString( IDS_IOS_ACCNAME_VOICE_SEARCH)]; [voiceSearchButton setAccessibilityIdentifier:@"Voice Search"]; @@ -281,17 +205,4 @@ return nearestAncestor([view superview], aClass); } -// Content suggestion dupliations of uikit_ui_util to allow wrapping behind -// the refresh flag. Post refresh remove these helpers and just check -// IsRxRSC instead. -BOOL IsRegularXRegularSizeClass(id<UITraitEnvironment> environment) { - return IsUIRefreshPhase1Enabled() ? ::IsRegularXRegularSizeClass(environment) - : IsIPadIdiom(); -} - -BOOL IsRegularXRegularSizeClass() { - return IsUIRefreshPhase1Enabled() ? ::IsRegularXRegularSizeClass() - : IsIPadIdiom(); -} - } // namespace content_suggestions
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_utils_unittest.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_utils_unittest.mm index 6b1becd..da5bf73 100644 --- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_utils_unittest.mm +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_utils_unittest.mm
@@ -89,26 +89,16 @@ // Setup. SetAsIPhone(); - if (IsUIRefreshPhase1Enabled()) { - CGFloat result = centeredTilesMarginForWidth(375); - EXPECT_EQ(28, result); - } else { - CGFloat result = centeredTilesMarginForWidth(374); - EXPECT_EQ(17, result); - } + CGFloat result = centeredTilesMarginForWidth(375); + EXPECT_EQ(28, result); } TEST_F(ContentSuggestionsCollectionUtilsTest, centeredTilesMarginIPad) { // Setup. SetAsIPad(); - if (IsUIRefreshPhase1Enabled()) { - CGFloat result = centeredTilesMarginForWidth(767); - EXPECT_EQ(209, result); - } else { - CGFloat result = centeredTilesMarginForWidth(700); - EXPECT_EQ(168, result); - } + CGFloat result = centeredTilesMarginForWidth(767); + EXPECT_EQ(209, result); } TEST_F(ContentSuggestionsCollectionUtilsTest, doodleFrameIPad) { @@ -118,17 +108,10 @@ // Action. CGFloat height = doodleHeight(YES); CGFloat topMargin = doodleTopMargin(YES); - CGFloat topMarginNoToolbar = doodleTopMargin(NO); // Test. - if (IsUIRefreshPhase1Enabled()) { - EXPECT_EQ(120, height); - EXPECT_EQ(162, topMargin); - } else { - EXPECT_EQ(120, height); - EXPECT_EQ(82, topMargin); - EXPECT_EQ(82, topMarginNoToolbar); - } + EXPECT_EQ(120, height); + EXPECT_EQ(162, topMargin); } TEST_F(ContentSuggestionsCollectionUtilsTest, doodleFrameIPhonePortrait) { @@ -140,19 +123,11 @@ CGFloat heightLogo = doodleHeight(YES); CGFloat heightNoLogo = doodleHeight(NO); CGFloat topMargin = doodleTopMargin(YES); - CGFloat topMarginNoToolbar = doodleTopMargin(NO); // Test. - if (IsUIRefreshPhase1Enabled()) { - EXPECT_EQ(120, heightLogo); - EXPECT_EQ(60, heightNoLogo); - EXPECT_EQ(58, topMargin); - } else { - EXPECT_EQ(120, heightLogo); - EXPECT_EQ(60, heightNoLogo); - EXPECT_EQ(56, topMargin); - EXPECT_EQ(0, topMarginNoToolbar); - } + EXPECT_EQ(120, heightLogo); + EXPECT_EQ(60, heightNoLogo); + EXPECT_EQ(58, topMargin); } TEST_F(ContentSuggestionsCollectionUtilsTest, doodleFrameIPhoneLandscape) { @@ -164,19 +139,11 @@ CGFloat heightLogo = doodleHeight(YES); CGFloat heightNoLogo = doodleHeight(NO); CGFloat topMargin = doodleTopMargin(YES); - CGFloat topMarginNoToolbar = doodleTopMargin(NO); // Test. - if (IsUIRefreshPhase1Enabled()) { - EXPECT_EQ(120, heightLogo); - EXPECT_EQ(60, heightNoLogo); - EXPECT_EQ(58, topMargin); - } else { - EXPECT_EQ(120, heightLogo); - EXPECT_EQ(60, heightNoLogo); - EXPECT_EQ(56, topMargin); - EXPECT_EQ(0, topMarginNoToolbar); - } + EXPECT_EQ(120, heightLogo); + EXPECT_EQ(60, heightNoLogo); + EXPECT_EQ(58, topMargin); } TEST_F(ContentSuggestionsCollectionUtilsTest, searchFieldFrameIPad) { @@ -184,7 +151,6 @@ SetAsIPad(); CGFloat width = 500; CGFloat largeIPadWidth = 1366; - CGFloat margin = centeredTilesMarginForWidth(width); // Action. CGFloat resultWidth = searchFieldWidth(width); @@ -192,15 +158,9 @@ CGFloat topMargin = searchFieldTopMargin(); // Test. - if (IsUIRefreshPhase1Enabled()) { - EXPECT_EQ(32, topMargin); - EXPECT_EQ(432, resultWidth); - EXPECT_EQ(432, resultWidthLargeIPad); - } else { - EXPECT_EQ(82, topMargin); - EXPECT_EQ(width - 2 * margin, resultWidth); - EXPECT_EQ(largeIPadWidth - 400, resultWidthLargeIPad); - } + EXPECT_EQ(32, topMargin); + EXPECT_EQ(432, resultWidth); + EXPECT_EQ(432, resultWidthLargeIPad); } TEST_F(ContentSuggestionsCollectionUtilsTest, searchFieldFrameIPhonePortrait) { @@ -208,20 +168,14 @@ SetAsIPhone(); SetAsPortrait(); CGFloat width = 500; - CGFloat margin = centeredTilesMarginForWidth(width); // Action. CGFloat resultWidth = searchFieldWidth(width); CGFloat topMargin = searchFieldTopMargin(); // Test. - if (IsUIRefreshPhase1Enabled()) { - EXPECT_EQ(32, topMargin); - EXPECT_EQ(343, resultWidth); - } else { - EXPECT_EQ(32, topMargin); - EXPECT_EQ(width - 2 * margin, resultWidth); - } + EXPECT_EQ(32, topMargin); + EXPECT_EQ(343, resultWidth); } TEST_F(ContentSuggestionsCollectionUtilsTest, searchFieldFrameIPhoneLandscape) { @@ -229,20 +183,14 @@ SetAsIPhone(); SetAsLandscape(); CGFloat width = 500; - CGFloat margin = centeredTilesMarginForWidth(width); // Action. CGFloat resultWidth = searchFieldWidth(width); CGFloat topMargin = searchFieldTopMargin(); // Test. - if (IsUIRefreshPhase1Enabled()) { - EXPECT_EQ(32, topMargin); - EXPECT_EQ(343, resultWidth); - } else { - EXPECT_EQ(32, topMargin); - EXPECT_EQ(width - 2 * margin, resultWidth); - } + EXPECT_EQ(32, topMargin); + EXPECT_EQ(343, resultWidth); } TEST_F(ContentSuggestionsCollectionUtilsTest, heightForLogoHeaderIPad) { @@ -250,17 +198,10 @@ SetAsIPad(); // Action, tests. - if (IsUIRefreshPhase1Enabled()) { - EXPECT_EQ(380, heightForLogoHeader(YES, YES, YES)); - EXPECT_EQ(404, heightForLogoHeader(YES, NO, YES)); - EXPECT_EQ(380, heightForLogoHeader(YES, YES, NO)); - EXPECT_EQ(404, heightForLogoHeader(YES, NO, NO)); - } else { - EXPECT_EQ(350, heightForLogoHeader(YES, YES, YES)); - EXPECT_EQ(374, heightForLogoHeader(YES, NO, YES)); - EXPECT_EQ(350, heightForLogoHeader(YES, YES, NO)); - EXPECT_EQ(374, heightForLogoHeader(YES, NO, NO)); - } + EXPECT_EQ(380, heightForLogoHeader(YES, YES, YES)); + EXPECT_EQ(404, heightForLogoHeader(YES, NO, YES)); + EXPECT_EQ(380, heightForLogoHeader(YES, YES, NO)); + EXPECT_EQ(404, heightForLogoHeader(YES, NO, NO)); } TEST_F(ContentSuggestionsCollectionUtilsTest, heightForLogoHeaderIPhone) { @@ -268,17 +209,10 @@ SetAsIPhone(); // Action, tests. - if (IsUIRefreshPhase1Enabled()) { - EXPECT_EQ(276, heightForLogoHeader(YES, YES, YES)); - EXPECT_EQ(276, heightForLogoHeader(YES, NO, YES)); - EXPECT_EQ(276, heightForLogoHeader(YES, YES, NO)); - EXPECT_EQ(276, heightForLogoHeader(YES, NO, NO)); - } else { - EXPECT_EQ(274, heightForLogoHeader(YES, YES, YES)); - EXPECT_EQ(274, heightForLogoHeader(YES, NO, YES)); - EXPECT_EQ(218, heightForLogoHeader(YES, YES, NO)); - EXPECT_EQ(218, heightForLogoHeader(YES, NO, NO)); - } + EXPECT_EQ(276, heightForLogoHeader(YES, YES, YES)); + EXPECT_EQ(276, heightForLogoHeader(YES, NO, YES)); + EXPECT_EQ(276, heightForLogoHeader(YES, YES, NO)); + EXPECT_EQ(276, heightForLogoHeader(YES, NO, NO)); } TEST_F(ContentSuggestionsCollectionUtilsTest, SizeIPhone6) { @@ -294,11 +228,7 @@ SetAsIPhone(); // Test. - if (IsUIRefreshPhase1Enabled()) { - EXPECT_EQ(4U, numberOfTilesForWidth(320)); - } else { - EXPECT_EQ(3U, numberOfTilesForWidth(320)); - } + EXPECT_EQ(4U, numberOfTilesForWidth(320)); } // Test for iPad portrait and iPhone landscape. @@ -312,11 +242,7 @@ SetAsIPad(); // Test. - if (IsUIRefreshPhase1Enabled()) { - EXPECT_EQ(4U, numberOfTilesForWidth(360)); - } else { - EXPECT_EQ(3U, numberOfTilesForWidth(360)); - } + EXPECT_EQ(4U, numberOfTilesForWidth(360)); } TEST_F(ContentSuggestionsCollectionUtilsTest, NearestAncestor) {
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_coordinator.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_coordinator.mm index 853a196..d8248dd 100644 --- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_coordinator.mm +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_coordinator.mm
@@ -39,7 +39,6 @@ #import "ios/chrome/browser/web_state_list/web_state_list.h" #include "ios/public/provider/chrome/browser/chrome_browser_provider.h" #import "ios/public/provider/chrome/browser/voice/voice_search_provider.h" -#include "ios/web/public/features.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." @@ -259,9 +258,7 @@ CGFloat topInset = 0.0; if (@available(iOS 11, *)) { topInset = self.suggestionsViewController.view.safeAreaInsets.top; - } else if (IsUIRefreshPhase1Enabled() || - base::FeatureList::IsEnabled( - web::features::kBrowserContainerFullscreen)) { + } else { // TODO(crbug.com/826369) Replace this when the NTP is contained by the // BVC with |self.suggestionsViewController.topLayoutGuide.length|. topInset = StatusBarHeight();
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_egtest.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_egtest.mm index 58b60b0..cd9ef9a7 100644 --- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_egtest.mm +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_egtest.mm
@@ -18,14 +18,11 @@ #include "components/ntp_snippets/content_suggestion.h" #include "components/ntp_snippets/content_suggestions_service.h" #include "components/ntp_snippets/mock_content_suggestions_provider.h" -#include "components/reading_list/core/reading_list_entry.h" -#include "components/reading_list/core/reading_list_model.h" #include "components/strings/grit/components_strings.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h" #include "ios/chrome/browser/chrome_switches.h" #include "ios/chrome/browser/ntp_snippets/ios_chrome_content_suggestions_service_factory.h" #include "ios/chrome/browser/ntp_snippets/ios_chrome_content_suggestions_service_factory_util.h" -#include "ios/chrome/browser/reading_list/reading_list_model_factory.h" #import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_header_item.h" #import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_learn_more_item.h" #include "ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_utils.h" @@ -33,6 +30,7 @@ #import "ios/chrome/browser/ui/content_suggestions/ntp_home_provider_test_singleton.h" #import "ios/chrome/browser/ui/content_suggestions/ntp_home_test_utils.h" #include "ios/chrome/browser/ui/ui_util.h" +#import "ios/chrome/browser/ui/uikit_ui_util.h" #include "ios/chrome/grit/ios_strings.h" #import "ios/chrome/test/app/chrome_test_util.h" #import "ios/chrome/test/app/history_test_util.h" @@ -149,7 +147,6 @@ ContentSuggestionsService* service = IOSChromeContentSuggestionsServiceFactory::GetForBrowserState( browserState); - RegisterReadingListProvider(service, browserState); [[ContentSuggestionsTestSingleton sharedInstance] registerArticleProvider:service]; } @@ -158,7 +155,6 @@ [self closeAllTabs]; ios::ChromeBrowserState* browserState = chrome_test_util::GetOriginalBrowserState(); - ReadingListModelFactory::GetForBrowserState(browserState)->DeleteAllEntries(); // Resets the Service associated with this browserState to a service with // default providers. The previous service is deleted. @@ -181,10 +177,6 @@ - (void)setUp { self.provider->FireCategoryStatusChanged(self.category, CategoryStatus::AVAILABLE); - - ReadingListModel* readingListModel = - ReadingListModelFactory::GetForBrowserState(self.browserState); - readingListModel->DeleteAllEntries(); [super setUp]; } @@ -244,173 +236,6 @@ assertWithMatcher:grey_notNil()]; } -// Tests that after dismissing a ReadingList item, it is not displayed on the -// NTP. But it is still unread in the Reading List surface. -- (void)testSwipeToDismissReadingListItem { - // TODO(crbug.com/807330): The collection view reading list section is not - // used in ui refresh. - if (IsUIRefreshPhase1Enabled()) { - EARL_GREY_TEST_SKIPPED(@"ReadingList section does not exist in UI Refresh"); - } - - // Add two items to Reading List. - std::string stdTitle1{"test title1"}; - std::string stdTitle2{"test title2"}; - NSString* title1 = base::SysUTF8ToNSString(stdTitle1); - NSString* title2 = base::SysUTF8ToNSString(stdTitle2); - ReadingListModel* readingListModel = - ReadingListModelFactory::GetForBrowserState(self.browserState); - readingListModel->AddEntry(GURL("http://chromium.org/2"), stdTitle2, - reading_list::ADDED_VIA_CURRENT_APP); - readingListModel->AddEntry(GURL("http://chromium.org/1"), stdTitle1, - reading_list::ADDED_VIA_CURRENT_APP); - - // Check that the two items are present in a new tab. - [ChromeEarlGreyUI openNewTab]; - [CellWithMatcher(grey_accessibilityID(title1)) - assertWithMatcher:grey_sufficientlyVisible()]; - [CellWithMatcher(grey_accessibilityID(title2)) - assertWithMatcher:grey_sufficientlyVisible()]; - - // Swipe to dismiss the first one. - [CellWithMatcher(grey_accessibilityID(title1)) - performAction:[GREYActions - actionForSwipeFastInDirection:kGREYDirectionLeft - xOriginStartPercentage:0.9 - yOriginStartPercentage:0.5]]; - - // Check the swiped item is dismissed. - [[EarlGrey - selectElementWithMatcher:grey_allOf(grey_accessibilityID(title1), - grey_sufficientlyVisible(), nil)] - assertWithMatcher:grey_nil()]; - - // Check the dismissed item is not present when opening a new NTP. - ScrollUp(); - [ChromeEarlGreyUI openNewTab]; - [CellWithMatcher(grey_accessibilityID(title2)) - assertWithMatcher:grey_sufficientlyVisible()]; - [[EarlGrey selectElementWithMatcher:grey_accessibilityID(title1)] - assertWithMatcher:grey_nil()]; - - // Open the Reading List surface. - ScrollUp(); - [ChromeEarlGreyUI openToolsMenu]; - [[EarlGrey - selectElementWithMatcher:chrome_test_util::ButtonWithAccessibilityLabelId( - IDS_IOS_TOOLS_MENU_READING_LIST)] - performAction:grey_tap()]; - - // Check that both entries are unread in the ReadingList surface. - [[EarlGrey selectElementWithMatcher:chrome_test_util:: - StaticTextWithAccessibilityLabelId( - IDS_IOS_READING_LIST_READ_HEADER)] - assertWithMatcher:grey_notVisible()]; - - [[EarlGrey selectElementWithMatcher: - chrome_test_util::StaticTextWithAccessibilityLabelId( - IDS_IOS_READING_LIST_UNREAD_HEADER)] - assertWithMatcher:grey_sufficientlyVisible()]; - - [[EarlGrey selectElementWithMatcher: - chrome_test_util::StaticTextWithAccessibilityLabel(title1)] - assertWithMatcher:grey_sufficientlyVisible()]; - - // On iPad two Reading List items are displayed as the Reading List view is - // displayed modally, the NTP is still visible. - [[EarlGrey - selectElementWithMatcher: - grey_allOf(chrome_test_util::StaticTextWithAccessibilityLabel(title2), - grey_not(grey_ancestor( - chrome_test_util::ContentSuggestionCollectionView())), - nil)] assertWithMatcher:grey_sufficientlyVisible()]; - - // Close Reading List. - [[EarlGrey - selectElementWithMatcher:chrome_test_util::ButtonWithAccessibilityLabelId( - IDS_IOS_READING_LIST_DONE_BUTTON)] - performAction:grey_tap()]; -} - -// Tests that only the 3 most recent Reading List items are displayed. -- (void)testReadingListItem { - // TODO(crbug.com/807330): The collection view reading list section is not - // used in ui refresh. - if (IsUIRefreshPhase1Enabled()) { - EARL_GREY_TEST_SKIPPED(@"ReadingList section does not exist in UI Refresh"); - } - - // Create entry titles for 4 unread entries and 1 read entry. - std::string stdTitle1{"test unread title1"}; - std::string stdTitle2{"test unread title2"}; - std::string stdTitle3{"test unread title3"}; - std::string stdTitle4{"test unread title4"}; - std::string stdReadTitle{"test read title"}; - NSString* title1 = base::SysUTF8ToNSString(stdTitle1); - NSString* title2 = base::SysUTF8ToNSString(stdTitle2); - NSString* title3 = base::SysUTF8ToNSString(stdTitle3); - NSString* title4 = base::SysUTF8ToNSString(stdTitle4); - NSString* readTitle = base::SysUTF8ToNSString(stdReadTitle); - - // Adds the entries: title1 is the oldest, title4 is the latest. - ReadingListModel* readingListModel = - ReadingListModelFactory::GetForBrowserState(self.browserState); - readingListModel->AddEntry(GURL("http://chromium.org/1"), stdTitle1, - reading_list::ADDED_VIA_CURRENT_APP); - readingListModel->AddEntry(GURL("http://chromium.org/2"), stdTitle2, - reading_list::ADDED_VIA_CURRENT_APP); - readingListModel->AddEntry(GURL("http://chromium.org/3"), stdTitle3, - reading_list::ADDED_VIA_CURRENT_APP); - readingListModel->AddEntry(GURL("http://chromium.org/5"), stdReadTitle, - reading_list::ADDED_VIA_CURRENT_APP); - readingListModel->SetReadStatus(GURL("http://chromium.org/5"), true); - readingListModel->AddEntry(GURL("http://chromium.org/4"), stdTitle4, - reading_list::ADDED_VIA_CURRENT_APP); - - // Check that only the first 3 unread items are displayed. - [ChromeEarlGreyUI openNewTab]; - [CellWithMatcher(grey_accessibilityID(title4)) - assertWithMatcher:grey_sufficientlyVisible()]; - [CellWithMatcher(grey_accessibilityID(title3)) - assertWithMatcher:grey_sufficientlyVisible()]; - [CellWithMatcher(grey_accessibilityID(title2)) - assertWithMatcher:grey_sufficientlyVisible()]; - [[EarlGrey selectElementWithMatcher:grey_accessibilityID(readTitle)] - assertWithMatcher:grey_nil()]; - [[EarlGrey selectElementWithMatcher:grey_accessibilityID(title1)] - assertWithMatcher:grey_nil()]; -} - -// Tests that tapping "More" on the Reading List section opens the Reading List -// surface. -- (void)testMoreReadingListSection { - // TODO(crbug.com/807330): The collection view reading list section is not - // used in ui refresh. - if (IsUIRefreshPhase1Enabled()) { - EARL_GREY_TEST_SKIPPED(@"ReadingList section does not exist in UI Refresh"); - } - // Add an entry to make sure the Reading List section is displayed. - ReadingListModel* readingListModel = - ReadingListModelFactory::GetForBrowserState(self.browserState); - readingListModel->AddEntry(GURL("http://chromium.org/2"), "test title", - reading_list::ADDED_VIA_CURRENT_APP); - - // Tap More. - [CellWithMatcher(chrome_test_util::StaticTextWithAccessibilityLabelId( - IDS_IOS_CONTENT_SUGGESTIONS_FOOTER_TITLE)) performAction:grey_tap()]; - - // Check the Reading List surface is opened. - [[EarlGrey selectElementWithMatcher:chrome_test_util:: - StaticTextWithAccessibilityLabelId( - IDS_IOS_TOOLS_MENU_READING_LIST)] - assertWithMatcher:grey_sufficientlyVisible()]; - - // Close Reading List. - [[EarlGrey - selectElementWithMatcher:chrome_test_util::ButtonWithAccessibilityLabelId( - IDS_IOS_READING_LIST_DONE_BUTTON)] - performAction:grey_tap()]; -} // Tests that a switch for the ContentSuggestions exists in the settings. The // behavior depends on having a real remote provider, so it cannot be tested @@ -425,33 +250,6 @@ assertWithMatcher:grey_sufficientlyVisible()]; } -// Tests that the section titles are displayed only if there are two sections. -- (void)testSectionTitle { - // TODO(crbug.com/807330): The collection view reading list section is not - // used in ui refresh. - if (IsUIRefreshPhase1Enabled()) { - EARL_GREY_TEST_SKIPPED(@"ReadingList section does not exist in UI Refresh"); - } - - ReadingListModel* readingListModel = - ReadingListModelFactory::GetForBrowserState(self.browserState); - readingListModel->AddEntry(GURL("http://chromium.org"), "test title", - reading_list::ADDED_VIA_CURRENT_APP); - - [CellWithMatcher(chrome_test_util::StaticTextWithAccessibilityLabelId( - IDS_NTP_READING_LIST_SUGGESTIONS_SECTION_HEADER)) - assertWithMatcher:grey_nil()]; - - std::vector<ContentSuggestion> suggestions; - suggestions.emplace_back( - Suggestion(self.category, "chromium", GURL("http://chromium.org"))); - self.provider->FireSuggestionsChanged(self.category, std::move(suggestions)); - - [CellWithMatcher(chrome_test_util::StaticTextWithAccessibilityLabelId( - IDS_NTP_READING_LIST_SUGGESTIONS_SECTION_HEADER)) - assertWithMatcher:grey_sufficientlyVisible()]; -} - // Tests that when tapping a suggestion, it is opened. When going back, the // disposition of the collection takes into account the previous scroll, even // when more is tapped. @@ -504,21 +302,10 @@ // Test that the omnibox is visible and taking full width, before any scroll // happen on iPhone. - if (!content_suggestions::IsRegularXRegularSizeClass()) { - if (!IsUIRefreshPhase1Enabled()) { - CGFloat collectionWidth = ntp_home::CollectionView().bounds.size.width; - [[EarlGrey - selectElementWithMatcher:grey_accessibilityID( - ntp_home::FakeOmniboxAccessibilityID())] - assertWithMatcher:grey_allOf(grey_sufficientlyVisible(), - ntp_home::OmniboxWidthBetween( - collectionWidth + 1, 1), - nil)]; - } - + if (!IsRegularXRegularSizeClass()) { // Test that the omnibox is still pinned to the top of the screen and // under the safe area. - CGFloat safeAreaTop = IsUIRefreshPhase1Enabled() ? StatusBarHeight() : 0; + CGFloat safeAreaTop = StatusBarHeight(); CGFloat contentOffset = ntp_home::CollectionView().contentOffset.y; CGFloat fakeOmniboxOrigin = ntp_home::FakeOmnibox().frame.origin.y; CGFloat pinnedOffset = contentOffset - (fakeOmniboxOrigin - safeAreaTop); @@ -557,149 +344,6 @@ assertWithMatcher:grey_sufficientlyVisible()]; } -// Tests that when long pressing a Reading List entry, a context menu is shown. -- (void)testReadingListLongPress { - // TODO(crbug.com/807330): The collection view reading list section is not - // used in ui refresh. - if (IsUIRefreshPhase1Enabled()) { - EARL_GREY_TEST_SKIPPED(@"ReadingList section does not exist in UI Refresh"); - } - - NSString* title = @"ReadingList test title"; - std::string sTitle{"ReadingList test title"}; - ReadingListModel* readingListModel = - ReadingListModelFactory::GetForBrowserState(self.browserState); - readingListModel->AddEntry(GURL("http://chromium.org"), sTitle, - reading_list::ADDED_VIA_CURRENT_APP); - - [CellWithMatcher(grey_accessibilityID(title)) performAction:grey_longPress()]; - - if (!content_suggestions::IsRegularXRegularSizeClass()) { - [[EarlGrey selectElementWithMatcher: - chrome_test_util::ButtonWithAccessibilityLabelId( - IDS_APP_CANCEL)] assertWithMatcher:grey_interactable()]; - } - - // No read later as it is already in the Reading List section. - [[EarlGrey - selectElementWithMatcher:chrome_test_util::ButtonWithAccessibilityLabelId( - IDS_IOS_CONTENT_CONTEXT_ADDTOREADINGLIST)] - assertWithMatcher:grey_nil()]; -} - -// Tests that "Open in New Tab" in context menu opens in a new tab. -- (void)testReadingListOpenNewTab { - // TODO(crbug.com/807330): The collection view reading list section is not - // used in ui refresh. - if (IsUIRefreshPhase1Enabled()) { - EARL_GREY_TEST_SKIPPED(@"ReadingList section does not exist in UI Refresh"); - } - - // Setup. - [self setupReadingListContextMenu]; - const GURL pageURL = self.testServer->GetURL(kPageURL); - - // Open in new tab. - [[EarlGrey - selectElementWithMatcher:chrome_test_util::ButtonWithAccessibilityLabelId( - IDS_IOS_CONTENT_CONTEXT_OPENLINKNEWTAB)] - performAction:grey_tap()]; - - // Check a new page in normal model is opened. - [ChromeEarlGrey waitForMainTabCount:2]; - [ChromeEarlGrey waitForIncognitoTabCount:0]; - - // Wait for the end of the new tab opening in background. This is needed as - // the iOS 11 devices cannot complete this animations while checking if the - // collection is present. - base::test::ios::SpinRunLoopWithMinDelay(base::TimeDelta::FromSecondsD(1)); - - // Check that the tab has been opened in background. - ConditionBlock condition = ^{ - NSError* error = nil; - [[EarlGrey selectElementWithMatcher:chrome_test_util:: - ContentSuggestionCollectionView()] - assertWithMatcher:grey_sufficientlyVisible() - error:&error]; - return error == nil; - }; - GREYAssert(base::test::ios::WaitUntilConditionOrTimeout( - base::test::ios::kWaitForUIElementTimeout, condition), - @"Collection view not visible"); - - // Check the page has been correctly opened. - chrome_test_util::SelectTabAtIndexInCurrentMode(1); - [ChromeEarlGrey waitForWebViewContainingText:kPageLoadedString]; - [[EarlGrey selectElementWithMatcher:chrome_test_util::OmniboxText( - pageURL.GetContent())] - assertWithMatcher:grey_notNil()]; -} - -// Tests that "Open in New Incognito Tab" in context menu opens in a new -// incognito tab. -- (void)testReadingListOpenNewIncognitoTab { - // TODO(crbug.com/807330): The collection view reading list section is not - // used in ui refresh. - if (IsUIRefreshPhase1Enabled()) { - EARL_GREY_TEST_SKIPPED(@"ReadingList section does not exist in UI Refresh"); - } - - // Setup. - [self setupReadingListContextMenu]; - const GURL pageURL = self.testServer->GetURL(kPageURL); - - // Open in new incognito tab. - [[EarlGrey selectElementWithMatcher: - chrome_test_util::ButtonWithAccessibilityLabelId( - IDS_IOS_CONTENT_CONTEXT_OPENLINKNEWINCOGNITOTAB)] - performAction:grey_tap()]; - - // Check that the tab has been opened in foreground. - [ChromeEarlGrey waitForWebViewContainingText:kPageLoadedString]; - [[EarlGrey selectElementWithMatcher:chrome_test_util::OmniboxText( - pageURL.GetContent())] - assertWithMatcher:grey_notNil()]; - - GREYAssertTrue(chrome_test_util::IsIncognitoMode(), - @"Test did not switch to incognito"); - - // Check only one incognito tab has been opened. - [ChromeEarlGrey waitForIncognitoTabCount:1]; - [ChromeEarlGrey waitForMainTabCount:1]; -} - -// Tests that "Remove" in context menu removes the entry. -- (void)testReadingListRemove { - // TODO(crbug.com/807330): The collection view reading list section is not - // used in ui refresh. - if (IsUIRefreshPhase1Enabled()) { - EARL_GREY_TEST_SKIPPED(@"ReadingList section does not exist in UI Refresh"); - } - - // Setup. - NSString* title = @"ReadingList test title"; - [self setupReadingListContextMenu]; - const GURL pageURL = self.testServer->GetURL(kPageURL); - - // Remove the element. - [[EarlGrey - selectElementWithMatcher:chrome_test_util::ButtonWithAccessibilityLabelId( - IDS_IOS_CONTENT_SUGGESTIONS_REMOVE)] - performAction:grey_tap()]; - - // Check the entry has been removed. - [[EarlGrey - selectElementWithMatcher:grey_allOf(grey_accessibilityID(title), - grey_sufficientlyVisible(), nil)] - assertWithMatcher:grey_nil()]; - - // Check the entry is still unread in the Reading List model. - ReadingListModel* readingListModel = - ReadingListModelFactory::GetForBrowserState(self.browserState); - GREYAssertEqual(1, readingListModel->unread_size(), - @"The number of unread entry has been changed."); -} - // Tests the "Open in New Tab" action of the Most Visited context menu. - (void)testMostVisitedNewTab { [self setupMostVisitedTileLongPress]; @@ -806,7 +450,7 @@ - (void)testMostVisitedLongPress { [self setupMostVisitedTileLongPress]; - if (!content_suggestions::IsRegularXRegularSizeClass()) { + if (!IsRegularXRegularSizeClass()) { [[EarlGrey selectElementWithMatcher: chrome_test_util::ButtonWithAccessibilityLabelId( IDS_APP_CANCEL)] assertWithMatcher:grey_interactable()]; @@ -835,24 +479,6 @@ #pragma mark - Test utils -// Setup a Reading List item and long press it to open the context menu. -- (void)setupReadingListContextMenu { - self.testServer->RegisterRequestHandler(base::Bind(&StandardResponse)); - GREYAssertTrue(self.testServer->Start(), @"Test server failed to start."); - const GURL pageURL = self.testServer->GetURL(kPageURL); - std::string sTitle{"ReadingList test title"}; - NSString* title = @"ReadingList test title"; - ReadingListModel* readingListModel = - ReadingListModelFactory::GetForBrowserState(self.browserState); - readingListModel->AddEntry(pageURL, sTitle, - reading_list::ADDED_VIA_CURRENT_APP); - [CellWithMatcher(grey_accessibilityID(title)) performAction:grey_longPress()]; - [ChromeEarlGrey waitForMainTabCount:1]; - [ChromeEarlGrey waitForIncognitoTabCount:0]; - GREYAssertEqual(1, readingListModel->unread_size(), - @"There should be only one unread entry."); -} - // Setup a most visited tile, and open the context menu by long pressing on it. - (void)setupMostVisitedTileLongPress { self.testServer->RegisterRequestHandler(base::Bind(&StandardResponse));
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_synchronizer.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_synchronizer.mm index 84a63d2..9984eb97 100644 --- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_synchronizer.mm +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_synchronizer.mm
@@ -14,7 +14,6 @@ #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_header_controlling.h" #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.h" #import "ios/chrome/browser/ui/uikit_ui_util.h" -#include "ios/web/public/features.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." @@ -26,10 +25,7 @@ UIEdgeInsets SafeAreaInsetsForViewWithinNTP(UIView* view) { UIEdgeInsets insets = SafeAreaInsetsForView(view); - if ((IsUIRefreshPhase1Enabled() || - base::FeatureList::IsEnabled( - web::features::kBrowserContainerFullscreen)) && - !base::ios::IsRunningOnIOS11OrLater()) { + if (!base::ios::IsRunningOnIOS11OrLater()) { // TODO(crbug.com/826369) Replace this when the NTP is contained by the // BVC with |self.collectionController.topLayoutGuide.length|. insets = UIEdgeInsetsMake(StatusBarHeight(), 0, 0, 0); @@ -180,10 +176,6 @@ [self.headerController unfocusOmnibox]; } - if (IsIPadIdiom() && !IsUIRefreshPhase1Enabled()) { - return; - } - if (self.shouldAnimateHeader) { UIEdgeInsets insets = SafeAreaInsetsForViewWithinNTP(self.collectionView); [self.headerController @@ -194,8 +186,7 @@ } - (void)updateFakeOmniboxOnNewWidth:(CGFloat)width { - if (self.shouldAnimateHeader && - (IsUIRefreshPhase1Enabled() || !IsIPadIdiom())) { + if (self.shouldAnimateHeader) { // We check -superview here because in certain scenarios (such as when the // VC is rotated underneath another presented VC), in a // UICollectionViewController -viewSafeAreaInsetsDidChange the VC.view has
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_view.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_view.mm index 2f34a3e..dff5fc3 100644 --- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_view.mm +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_view.mm
@@ -229,10 +229,7 @@ // Adjust the position of the search field's subviews by adjusting their // constraint constant value. - CGFloat constantDiff = IsUIRefreshPhase1Enabled() - ? -maxXInset * percent - : percent * (ntp_header::kMaxHorizontalMarginDiff + - inset + safeAreaInsets.left); + CGFloat constantDiff = -maxXInset * percent; for (NSLayoutConstraint* constraint in constraints) { if (constraint.constant > 0) constraint.constant = constantDiff + ntp_header::kHintLabelSidePadding;
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_view_controller.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_view_controller.mm index 9a0d468..da92accf 100644 --- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_view_controller.mm +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_view_controller.mm
@@ -37,10 +37,6 @@ using base::UserMetricsAction; -namespace { -const UIEdgeInsets kSearchBoxStretchInsets = {3, 3, 3, 3}; -} // namespace - @interface ContentSuggestionsHeaderViewController () // |YES| when notifications indicate the omnibox is focused. @@ -128,9 +124,6 @@ (id<UIViewControllerTransitionCoordinator>)coordinator { [super willTransitionToTraitCollection:newCollection withTransitionCoordinator:coordinator]; - if (!IsUIRefreshPhase1Enabled()) - return; - void (^transition)(id<UIViewControllerTransitionCoordinatorContext>) = ^(id<UIViewControllerTransitionCoordinatorContext> context) { // Ensure omnibox is reset when not a regular tablet. @@ -152,9 +145,9 @@ - (void)updateFakeOmniboxForOffset:(CGFloat)offset screenWidth:(CGFloat)screenWidth safeAreaInsets:(UIEdgeInsets)safeAreaInsets { - if (self.isShowing && IsUIRefreshPhase1Enabled()) { + if (self.isShowing) { CGFloat progress = - self.logoIsShowing || !content_suggestions::IsRegularXRegularSizeClass() + self.logoIsShowing || !IsRegularXRegularSizeClass() ? [self.headerView searchFieldProgressForOffset:offset safeAreaInsets:safeAreaInsets] // RxR with no logo hides the fakebox, so always show the omnibox. @@ -209,11 +202,11 @@ CGFloat offsetY = headerHeight - ntp_header::kScrolledToTopOmniboxBottomMargin; - if (!content_suggestions::IsRegularXRegularSizeClass(self)) { + if (!IsRegularXRegularSizeClass(self)) { CGFloat top = 0; if (@available(iOS 11, *)) { top = self.parentViewController.view.safeAreaInsets.top; - } else if (IsUIRefreshPhase1Enabled()) { + } else { // TODO(crbug.com/826369) Replace this when the NTP is contained by the // BVC with |self.parentViewController.topLayoutGuide.length|. top = StatusBarHeight(); @@ -274,12 +267,6 @@ // Initialize and add a search field tap target and a voice search button. - (void)addFakeOmnibox { self.fakeOmnibox = [[UIButton alloc] init]; - if (IsIPadIdiom() && !IsUIRefreshPhase1Enabled()) { - UIImage* searchBoxImage = [[UIImage imageNamed:@"ntp_google_search_box"] - resizableImageWithCapInsets:kSearchBoxStretchInsets]; - [self.fakeOmnibox setBackgroundImage:searchBoxImage - forState:UIControlStateNormal]; - } [self.fakeOmnibox setAdjustsImageWhenHighlighted:NO]; // Set isAccessibilityElement to NO so that Voice Search button is accessible. @@ -292,15 +279,9 @@ content_suggestions::configureSearchHintLabel(self.searchHintLabel, self.fakeOmnibox); - if (IsUIRefreshPhase1Enabled()) { - self.hintLabelLeadingConstraint = [self.searchHintLabel.leadingAnchor - constraintGreaterThanOrEqualToAnchor:[self.fakeOmnibox leadingAnchor] - constant:ntp_header::kHintLabelSidePadding]; - } else { - self.hintLabelLeadingConstraint = [self.searchHintLabel.leadingAnchor - constraintEqualToAnchor:[self.fakeOmnibox leadingAnchor] - constant:ntp_header::kHintLabelSidePaddingLegacy]; - } + self.hintLabelLeadingConstraint = [self.searchHintLabel.leadingAnchor + constraintGreaterThanOrEqualToAnchor:[self.fakeOmnibox leadingAnchor] + constant:ntp_header::kHintLabelSidePadding]; self.hintLabelLeadingConstraint.active = YES; // Set a button the same size as the fake omnibox as the accessibility @@ -394,11 +375,7 @@ } - (void)focusFakebox { - if (IsUIRefreshPhase1Enabled()) { - [self shiftTilesUp]; - } else { - [self.dispatcher fakeboxFocused]; - } + [self shiftTilesUp]; } // TODO(crbug.com/807330) The fakebox is currently a collection of views spread @@ -420,7 +397,7 @@ self.logoVendor.showingLogo = self.logoIsShowing; [self.doodleHeightConstraint setConstant:content_suggestions::doodleHeight(self.logoIsShowing)]; - if (content_suggestions::IsRegularXRegularSizeClass(self)) + if (IsRegularXRegularSizeClass(self)) [self.fakeOmnibox setHidden:!self.logoIsShowing]; [self.collectionSynchronizer invalidateLayout]; } @@ -456,9 +433,7 @@ } - (void)shiftTilesDown { - if ((IsUIRefreshPhase1Enabled() && IsSplitToolbarMode()) || - (!IsUIRefreshPhase1Enabled() && - !content_suggestions::IsRegularXRegularSizeClass(self))) { + if (IsSplitToolbarMode()) { [self.dispatcher onFakeboxBlur]; } [self.collectionSynchronizer shiftTilesDown]; @@ -468,12 +443,8 @@ - (void)shiftTilesUp { void (^completionBlock)() = ^{ - if (IsUIRefreshPhase1Enabled()) { - [self.dispatcher fakeboxFocused]; - } - if ((IsUIRefreshPhase1Enabled() && IsSplitToolbarMode()) || - (!IsUIRefreshPhase1Enabled() && - !content_suggestions::IsRegularXRegularSizeClass(self))) { + [self.dispatcher fakeboxFocused]; + if (IsSplitToolbarMode()) { [self.dispatcher onFakeboxAnimationComplete]; } };
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_layout.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_layout.mm index 2f19695..0c5fba6 100644 --- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_layout.mm +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_layout.mm
@@ -7,6 +7,7 @@ #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_utils.h" #import "ios/chrome/browser/ui/ntp/new_tab_page_header_constants.h" #include "ios/chrome/browser/ui/ui_util.h" +#import "ios/chrome/browser/ui/uikit_ui_util.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." @@ -25,14 +26,12 @@ CGFloat minimumHeight = collectionViewHeight + headerHeight - ntp_header::kScrolledToTopOmniboxBottomMargin; CGFloat topSafeArea = 0; - if (IsUIRefreshPhase1Enabled()) { - if (@available(iOS 11, *)) { - topSafeArea = self.collectionView.safeAreaInsets.top; - } else { - topSafeArea = StatusBarHeight(); - } + if (@available(iOS 11, *)) { + topSafeArea = self.collectionView.safeAreaInsets.top; + } else { + topSafeArea = StatusBarHeight(); } - if (!content_suggestions::IsRegularXRegularSizeClass(self.collectionView)) + if (!IsRegularXRegularSizeClass(self.collectionView)) minimumHeight -= ntp_header::ToolbarHeight() + topSafeArea + self.collectionView.contentInset.bottom; @@ -44,7 +43,7 @@ } - (NSArray*)layoutAttributesForElementsInRect:(CGRect)rect { - if (content_suggestions::IsRegularXRegularSizeClass()) + if (IsRegularXRegularSizeClass()) return [super layoutAttributesForElementsInRect:rect]; NSMutableArray* layoutAttributes = @@ -86,7 +85,7 @@ UICollectionViewLayoutAttributes* attributes = [super layoutAttributesForSupplementaryViewOfKind:kind atIndexPath:indexPath]; - if (content_suggestions::IsRegularXRegularSizeClass()) + if (IsRegularXRegularSizeClass()) return attributes; if ([kind isEqualToString:UICollectionElementKindSectionHeader] && @@ -101,12 +100,10 @@ // Prevent the fake omnibox from scrolling up off of the screen. CGFloat topSafeArea = 0; - if (IsUIRefreshPhase1Enabled()) { - if (@available(iOS 11, *)) { - topSafeArea = self.collectionView.safeAreaInsets.top; - } else { - topSafeArea = StatusBarHeight(); - } + if (@available(iOS 11, *)) { + topSafeArea = self.collectionView.safeAreaInsets.top; + } else { + topSafeArea = StatusBarHeight(); } CGFloat minY = headerHeight - ntp_header::kMinHeaderHeight - topSafeArea; if (contentOffset.y > minY) @@ -117,7 +114,7 @@ } - (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBound { - if (content_suggestions::IsRegularXRegularSizeClass()) + if (IsRegularXRegularSizeClass()) return [super shouldInvalidateLayoutForBoundsChange:newBound]; return YES; }
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_mediator.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_mediator.mm index 40ca0cf..961aea0 100644 --- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_mediator.mm +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_mediator.mm
@@ -49,7 +49,6 @@ using CSCollectionViewItem = CollectionViewItem<SuggestedContent>; // Maximum number of most visited tiles fetched. -const NSInteger kMaxNumMostVisitedTilesLegacy = 8; const NSInteger kMaxNumMostVisitedTiles = 4; } // namespace @@ -169,15 +168,10 @@ _mostVisitedSites = std::move(mostVisitedSites); _mostVisitedBridge = std::make_unique<ntp_tiles::MostVisitedSitesObserverBridge>(self); - NSInteger maxNumMostVisitedTiles = IsUIRefreshPhase1Enabled() - ? kMaxNumMostVisitedTiles - : kMaxNumMostVisitedTilesLegacy; _mostVisitedSites->SetMostVisitedURLsObserver(_mostVisitedBridge.get(), - maxNumMostVisitedTiles); - if (IsUIRefreshPhase1Enabled()) { - _readingListModelBridge = - std::make_unique<ReadingListModelBridge>(self, readingListModel); - } + kMaxNumMostVisitedTiles); + _readingListModelBridge = + std::make_unique<ReadingListModelBridge>(self, readingListModel); } return self; } @@ -202,8 +196,7 @@ } + (NSUInteger)maxSitesShown { - return IsUIRefreshPhase1Enabled() ? kMaxNumMostVisitedTiles - : kMaxNumMostVisitedTilesLegacy; + return kMaxNumMostVisitedTiles; } #pragma mark - ContentSuggestionsDataSource @@ -218,11 +211,7 @@ [sectionsInfo addObject:self.promoSectionInfo]; } - // Since action items are always visible in UI Refresh, always add - // |mostVisitedSectionInfo| in UI Refresh. - if (self.mostVisitedItems.count > 0 || IsUIRefreshPhase1Enabled()) { - [sectionsInfo addObject:self.mostVisitedSectionInfo]; - } + [sectionsInfo addObject:self.mostVisitedSectionInfo]; std::vector<ntp_snippets::Category> categories = self.contentService->GetCategories(); @@ -263,9 +252,7 @@ } } else if (sectionInfo == self.mostVisitedSectionInfo) { [convertedSuggestions addObjectsFromArray:self.mostVisitedItems]; - if (IsUIRefreshPhase1Enabled()) { - [convertedSuggestions addObjectsFromArray:self.actionButtonItems]; - } + [convertedSuggestions addObjectsFromArray:self.actionButtonItems]; } else if (sectionInfo == self.learnMoreSectionInfo) { [convertedSuggestions addObject:self.learnMoreItem]; } else { @@ -624,8 +611,7 @@ - (BOOL)isCategoryInitOrAvailable:(ntp_snippets::Category)category { ntp_snippets::CategoryStatus status = self.contentService->GetCategoryStatus(category); - if (IsUIRefreshPhase1Enabled() && - category.IsKnownCategory(ntp_snippets::KnownCategories::ARTICLES) && + if (category.IsKnownCategory(ntp_snippets::KnownCategories::ARTICLES) && status == ntp_snippets::CategoryStatus::CATEGORY_EXPLICITLY_DISABLED) return [self.contentArticlesEnabled value]; else @@ -639,8 +625,7 @@ - (BOOL)isCategoryAvailable:(ntp_snippets::Category)category { ntp_snippets::CategoryStatus status = self.contentService->GetCategoryStatus(category); - if (IsUIRefreshPhase1Enabled() && - category.IsKnownCategory(ntp_snippets::KnownCategories::ARTICLES) && + if (category.IsKnownCategory(ntp_snippets::KnownCategories::ARTICLES) && status == ntp_snippets::CategoryStatus::CATEGORY_EXPLICITLY_DISABLED) { return [self.contentArticlesEnabled value]; } else { @@ -652,8 +637,7 @@ // Returns whether the Articles category pref indicates it should be expanded, // otherwise returns YES. - (BOOL)isCategoryExpanded:(ntp_snippets::Category)category { - if (IsUIRefreshPhase1Enabled() && - category.IsKnownCategory(ntp_snippets::KnownCategories::ARTICLES)) + if (category.IsKnownCategory(ntp_snippets::KnownCategories::ARTICLES)) return [self.contentArticlesExpanded value]; else return YES;
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.mm index 4705870..8656ee4 100644 --- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.mm +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.mm
@@ -33,18 +33,9 @@ namespace { using CSCollectionViewItem = CollectionViewItem<SuggestedContent>; -const CGFloat kMaxCardWidth = 416; -const CGFloat kStandardSpacing = 8; const CGFloat kMostVisitedBottomMargin = 13; const CGFloat kCardBorderRadius = 11; -// Returns whether the cells should be displayed using the full width. -BOOL ShouldCellsBeFullWidth(UITraitCollection* collection) { - if (IsUIRefreshPhase1Enabled()) - return NO; - return collection.horizontalSizeClass == UIUserInterfaceSizeClassCompact && - collection.verticalSizeClass != UIUserInterfaceSizeClassCompact; -} } @interface ContentSuggestionsViewController ()<UIGestureRecognizerDelegate> @@ -187,12 +178,7 @@ updateFakeOmniboxOnNewWidth:self.collectionView.bounds.size.width]; [self.headerSynchronizer updateConstraints]; [self.collectionView reloadData]; - if (ShouldCellsBeFullWidth( - [UIApplication sharedApplication].keyWindow.traitCollection)) { - self.styler.cellStyle = MDCCollectionViewCellStyleGrouped; - } else { - self.styler.cellStyle = MDCCollectionViewCellStyleCard; - } + self.styler.cellStyle = MDCCollectionViewCellStyleCard; } - (void)clearOverscroll { @@ -213,9 +199,7 @@ // Overscroll action does not work well with content offset, so set this // to never and internally offset the UI to account for safe area insets. self.collectionView.contentInsetAdjustmentBehavior = - IsUIRefreshPhase1Enabled() - ? UIScrollViewContentInsetAdjustmentNever - : UIScrollViewContentInsetAdjustmentAutomatic; + UIScrollViewContentInsetAdjustmentNever; } self.collectionView.accessibilityIdentifier = [[self class] collectionAccessibilityIdentifier]; @@ -223,44 +207,13 @@ self.collectionView.delegate = self; self.collectionView.backgroundColor = ntp_home::kNTPBackgroundColor(); - if (ShouldCellsBeFullWidth( - [UIApplication sharedApplication].keyWindow.traitCollection)) { - self.styler.cellStyle = MDCCollectionViewCellStyleGrouped; - } else { - self.styler.cellStyle = MDCCollectionViewCellStyleCard; - if (IsUIRefreshPhase1Enabled()) - self.styler.cardBorderRadius = kCardBorderRadius; - } + self.styler.cellStyle = MDCCollectionViewCellStyleCard; + self.styler.cardBorderRadius = kCardBorderRadius; self.automaticallyAdjustsScrollViewInsets = NO; self.collectionView.translatesAutoresizingMaskIntoConstraints = NO; - if (base::FeatureList::IsEnabled( - web::features::kBrowserContainerFullscreen) && - !IsUIRefreshPhase1Enabled()) { - // Add a fake status bar at the top. - UIView* fakeStatusBar = [[UIView alloc] init]; - fakeStatusBar.backgroundColor = ntp_home::kNTPBackgroundColor(); - fakeStatusBar.translatesAutoresizingMaskIntoConstraints = NO; - [self.view addSubview:fakeStatusBar]; - AddSameConstraintsToSides( - self.view, fakeStatusBar, - LayoutSides::kTop | LayoutSides::kTrailing | LayoutSides::kLeading); - if (@available(iOS 11.0, *)) { - [fakeStatusBar.bottomAnchor - constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor] - .active = YES; - } else { - [fakeStatusBar.bottomAnchor - constraintEqualToAnchor:self.topLayoutGuide.bottomAnchor] - .active = YES; - } - ApplyVisualConstraints( - @[ @"V:|[statusBar][collection]|", @"H:|[collection]|" ], - @{@"collection" : self.collectionView, @"statusBar" : fakeStatusBar}); - } else { - ApplyVisualConstraints(@[ @"V:|[collection]|", @"H:|[collection]|" ], - @{@"collection" : self.collectionView}); - } + ApplyVisualConstraints(@[ @"V:|[collection]|", @"H:|[collection]|" ], + @{@"collection" : self.collectionView}); UILongPressGestureRecognizer* longPressRecognizer = [[UILongPressGestureRecognizer alloc] @@ -278,8 +231,7 @@ } - (void)updateOverscrollActionsState { - if (IsSplitToolbarMode(self) || - (!IsUIRefreshPhase1Enabled() && !IsRegularXRegularSizeClass(self))) { + if (IsSplitToolbarMode(self)) { [self.overscrollActionsController enableOverscrollActions]; } else { [self.overscrollActionsController disableOverscrollActions]; @@ -329,11 +281,7 @@ // Invalidating the layout after changing the cellStyle results in the layout // not being updated. Do it before to have it taken into account. [self.collectionView.collectionViewLayout invalidateLayout]; - if (ShouldCellsBeFullWidth(newCollection)) { - self.styler.cellStyle = MDCCollectionViewCellStyleGrouped; - } else { - self.styler.cellStyle = MDCCollectionViewCellStyleCard; - } + self.styler.cellStyle = MDCCollectionViewCellStyleCard; } - (void)traitCollectionDidChange:(UITraitCollection*)previousTraitCollection { @@ -441,58 +389,12 @@ parentInset.left = margin; parentInset.right = margin; if ([self.collectionUpdater isMostVisitedSection:section]) { - if (IsUIRefreshPhase1Enabled()) { - parentInset.bottom = kMostVisitedBottomMargin; - } else { - // Make sure the Content Suggestions is displayed at a reasonnable - // distance from the Most Visited tiles. - CGFloat maximumMargin = IsIPadIdiom() - ? ntp_home::kMostVisitedBottomMarginIPad - : ntp_home::kMostVisitedBottomMarginIPhone; - - NSInteger promoSection = -1; - for (NSInteger i = 0; i < [self.collectionViewModel numberOfSections]; - i++) { - if ([self.collectionUpdater isPromoSection:i]) { - promoSection = i; - } - } - - // Height for the displayed content. - CGFloat contentHeight = - [self collectionView:collectionView - layout:collectionViewLayout - referenceSizeForHeaderInSection:0] - .height; - contentHeight += kStandardSpacing; - if (promoSection >= 0) { - contentHeight += - [self collectionView:collectionView - cellHeightAtIndexPath:[NSIndexPath - indexPathForItem:0 - inSection:promoSection]]; - contentHeight += kStandardSpacing; - } - contentHeight += - 2 * [ContentSuggestionsMostVisitedCell defaultSize].height; - contentHeight += content_suggestions::verticalSpacingBetweenTiles(); - - // The Content Suggestions should idealy be displayed such as only part - // of the first suggestion is displayed. The distance should be capped - // to not push the suggestions too far. - CGFloat collectionHeight = collectionView.bounds.size.height; - CGFloat idealMargin = collectionHeight - contentHeight - - ntp_home::kSuggestionPeekingHeight; - CGFloat margin = MIN(MAX(kStandardSpacing, idealMargin), maximumMargin); - parentInset.bottom = margin; - } + parentInset.bottom = kMostVisitedBottomMargin; } } else if (self.styler.cellStyle == MDCCollectionViewCellStyleCard) { CGFloat collectionWidth = collectionView.bounds.size.width; CGFloat maxCardWidth = - IsUIRefreshPhase1Enabled() - ? content_suggestions::searchFieldWidth(collectionWidth) - : kMaxCardWidth; + content_suggestions::searchFieldWidth(collectionWidth); CGFloat margin = MAX(0, (collectionView.frame.size.width - maxCardWidth) / 2); parentInset.left = margin; @@ -517,13 +419,7 @@ - (BOOL)collectionView:(UICollectionView*)collectionView hidesInkViewAtIndexPath:(NSIndexPath*)indexPath { - if (IsUIRefreshPhase1Enabled()) - return YES; - ContentSuggestionType itemType = [self.collectionUpdater - contentSuggestionTypeForItem:[self.collectionViewModel - itemAtIndexPath:indexPath]]; - return [self.collectionUpdater isMostVisitedSection:indexPath.section] || - itemType == ContentSuggestionTypeEmpty; + return YES; } - (UIColor*)collectionView:(nonnull UICollectionView*)collectionView @@ -555,10 +451,7 @@ - (BOOL)collectionView:(UICollectionView*)collectionView shouldHideHeaderBackgroundForSection:(NSInteger)section { - if (IsUIRefreshPhase1Enabled()) { - return [self.collectionUpdater shouldUseCustomStyleForSection:section]; - } - return YES; + return [self.collectionUpdater shouldUseCustomStyleForSection:section]; } - (CGFloat)collectionView:(UICollectionView*)collectionView @@ -576,30 +469,20 @@ - (BOOL)collectionView:(UICollectionView*)collectionView shouldHideItemSeparatorAtIndexPath:(NSIndexPath*)indexPath { - if (IsUIRefreshPhase1Enabled()) { - // Special case, show a seperator between the last regular item and the - // footer. - if (![self.collectionUpdater - shouldUseCustomStyleForSection:indexPath.section] && - indexPath.row == - [self.collectionView numberOfItemsInSection:indexPath.section] - - 1) { - return NO; - } - return YES; - } else { - return [self collectionView:collectionView - shouldHideItemBackgroundAtIndexPath:indexPath]; + // Special case, show a seperator between the last regular item and the + // footer. + if (![self.collectionUpdater + shouldUseCustomStyleForSection:indexPath.section] && + indexPath.row == + [self.collectionView numberOfItemsInSection:indexPath.section] - 1) { + return NO; } + return YES; } - (BOOL)collectionView:(UICollectionView*)collectionView shouldHideHeaderSeparatorForSection:(NSInteger)section { - if (IsUIRefreshPhase1Enabled()) { - return [self.collectionUpdater shouldUseCustomStyleForSection:section]; - } else { - return YES; - } + return [self.collectionUpdater shouldUseCustomStyleForSection:section]; } #pragma mark - MDCCollectionViewEditingDelegate @@ -708,16 +591,14 @@ // though content suggestions appear under the top safe area, they are blocked // by the browser container view controller. - (void)correctMissingSafeArea { - if (IsUIRefreshPhase1Enabled()) { - if (@available(iOS 11, *)) { - UIEdgeInsets missingTop = UIEdgeInsetsZero; - // During the new tab animation the browser container view controller - // actually matches the browser view controller frame, so safe area does - // work, so be sure to check the parent view controller offset. - if (self.parentViewController.view.frame.origin.y == StatusBarHeight()) - missingTop = UIEdgeInsetsMake(StatusBarHeight(), 0, 0, 0); - self.additionalSafeAreaInsets = missingTop; - } + if (@available(iOS 11, *)) { + UIEdgeInsets missingTop = UIEdgeInsetsZero; + // During the new tab animation the browser container view controller + // actually matches the browser view controller frame, so safe area does + // work, so be sure to check the parent view controller offset. + if (self.parentViewController.view.frame.origin.y == StatusBarHeight()) + missingTop = UIEdgeInsetsMake(StatusBarHeight(), 0, 0, 0); + self.additionalSafeAreaInsets = missingTop; } } @@ -766,7 +647,7 @@ break; } - if (content_suggestions::IsRegularXRegularSizeClass(self)) + if (IsRegularXRegularSizeClass(self)) [self.headerSynchronizer unfocusOmnibox]; }
diff --git a/ios/chrome/browser/ui/content_suggestions/ntp_home_constant.mm b/ios/chrome/browser/ui/content_suggestions/ntp_home_constant.mm index d0d8e7b..54baf49 100644 --- a/ios/chrome/browser/ui/content_suggestions/ntp_home_constant.mm +++ b/ios/chrome/browser/ui/content_suggestions/ntp_home_constant.mm
@@ -19,11 +19,7 @@ const CGFloat kSuggestionPeekingHeight = 60; UIColor* kNTPBackgroundColor() { - if (IsUIRefreshPhase1Enabled()) { - return [UIColor colorWithWhite:0.98 alpha:1.0]; - } else { - return [UIColor whiteColor]; - } + return [UIColor colorWithWhite:0.98 alpha:1.0]; } } // namespace ntp_home
diff --git a/ios/chrome/browser/ui/content_suggestions/ntp_home_egtest.mm b/ios/chrome/browser/ui/content_suggestions/ntp_home_egtest.mm index 75f6678..8776372 100644 --- a/ios/chrome/browser/ui/content_suggestions/ntp_home_egtest.mm +++ b/ios/chrome/browser/ui/content_suggestions/ntp_home_egtest.mm
@@ -109,7 +109,6 @@ ContentSuggestionsService* service = IOSChromeContentSuggestionsServiceFactory::GetForBrowserState( browserState); - RegisterReadingListProvider(service, browserState); [[ContentSuggestionsTestSingleton sharedInstance] registerArticleProvider:service]; } @@ -206,7 +205,7 @@ - (void)testOmniboxWidthRotationBehindSettings { // TODO(crbug.com/652465): Enable the test for iPad when rotation bug is // fixed. - if (content_suggestions::IsRegularXRegularSizeClass()) { + if (IsRegularXRegularSizeClass()) { EARL_GREY_TEST_DISABLED(@"Disabled for iPad due to device rotation bug."); } [[GREYUIThreadExecutor sharedInstance] drainUntilIdle]; @@ -246,7 +245,7 @@ - (void)testOmniboxPinnedWidthRotation { // TODO(crbug.com/652465): Enable the test for iPad when rotation bug is // fixed. - if (content_suggestions::IsRegularXRegularSizeClass()) { + if (IsRegularXRegularSizeClass()) { EARL_GREY_TEST_DISABLED(@"Disabled for iPad due to device rotation bug."); } @@ -272,17 +271,9 @@ GREYAssertNotEqual(collectionWidth, collectionWidthAfterRotation, @"The collection width has not changed."); - if (IsUIRefreshPhase1Enabled()) { - // In UI refresh, scrolled, landscape, the fake omnibox is hidden. - [[EarlGrey selectElementWithMatcher:grey_accessibilityID( - FakeOmniboxAccessibilityID())] - assertWithMatcher:grey_not(grey_sufficientlyVisible())]; - } else { - [[EarlGrey selectElementWithMatcher:grey_accessibilityID( - FakeOmniboxAccessibilityID())] - assertWithMatcher:OmniboxWidthBetween(collectionWidthAfterRotation + 1, - 2)]; - } + [[EarlGrey selectElementWithMatcher:grey_accessibilityID( + FakeOmniboxAccessibilityID())] + assertWithMatcher:grey_not(grey_sufficientlyVisible())]; } // Tests that the promo is correctly displayed and removed once tapped. @@ -395,8 +386,7 @@ - (void)testTapFakeOmnibox { // TODO(crbug.com/753098): Re-enable this test on iOS 11 iPad once // grey_typeText works on iOS 11. - if (content_suggestions::IsRegularXRegularSizeClass() && - base::ios::IsRunningOnIOS11OrLater()) { + if (IsRegularXRegularSizeClass() && base::ios::IsRunningOnIOS11OrLater()) { EARL_GREY_TEST_DISABLED(@"Test disabled on iOS 11."); } // Setup the server. @@ -419,41 +409,11 @@ [ChromeEarlGrey waitForWebViewContainingText:kPageLoadedString]; } -// Tests that tapping the fake omnibox logs correctly. -// It is important for ranking algorithm of omnibox that requests from fakebox -// and real omnibox are marked appropriately. -- (void)testTapFakeOmniboxLogsCorrectly { - if (!IsIPadIdiom() || IsUIRefreshPhase1Enabled()) { - // This logging only happens on iPad pre-UIRefresh, since on iPhone there is - // no real omnibox on NTP, only fakebox, and post-UIRefresh the NTP never - // shows multiple omniboxes. - return; - } - - // Swizzle the method that needs to be called for correct logging. - __block BOOL tapped = NO; - ScopedBlockSwizzler swizzler([LocationBarLegacyCoordinator class], - @selector(focusOmniboxFromFakebox), ^{ - tapped = YES; - }); - - // Tap the fake omnibox. - [[EarlGrey selectElementWithMatcher:grey_accessibilityID( - FakeOmniboxAccessibilityID())] - performAction:grey_tap()]; - [ChromeEarlGrey - waitForElementWithMatcherSufficientlyVisible:chrome_test_util::Omnibox()]; - - // Check that the page is loaded. - GREYAssertTrue(tapped, @"The tap on the fakebox was not correctly logged."); -} - // Tests that tapping the omnibox search button logs correctly. // It is important for ranking algorithm of omnibox that requests from the // search button and real omnibox are marked appropriately. - (void)testTapOmniboxSearchButtonLogsCorrectly { - if (!IsUIRefreshPhase1Enabled() || !IsRefreshLocationBarEnabled() || - content_suggestions::IsRegularXRegularSizeClass()) { + if (IsRegularXRegularSizeClass()) { // This logging only happens on iPhone, since on iPad there's no secondary // toolbar. return; @@ -515,7 +475,7 @@ // TODO(crbug.com/826369) This should use collectionView.safeAreaInsets.top // instead of -StatusBarHeight once iOS10 is dropped and the NTP is out of // native content. - CGFloat top = IsUIRefreshPhase1Enabled() ? StatusBarHeight() : 0; + CGFloat top = StatusBarHeight(); GREYAssertTrue(offsetAfterTap.y >= origin.y + headerHeight - (60 + top), @"The collection has not moved."); @@ -578,8 +538,7 @@ // Tests tapping the search button when the fake omnibox is scrolled. - (void)testTapSearchButtonFakeOmniboxScrolled { - if (!IsUIRefreshPhase1Enabled() || - content_suggestions::IsRegularXRegularSizeClass()) { + if (IsRegularXRegularSizeClass()) { // This only happens on iPhone, since on iPad there's no secondary toolbar. return; }
diff --git a/ios/chrome/browser/ui/ntp/new_tab_page_controller.h b/ios/chrome/browser/ui/ntp/new_tab_page_controller.h index 5691fa8..685d2a9 100644 --- a/ios/chrome/browser/ui/ntp/new_tab_page_controller.h +++ b/ios/chrome/browser/ui/ntp/new_tab_page_controller.h
@@ -27,13 +27,8 @@ @class TabModel; @protocol UrlLoader; -// A controller for the New Tab Page user interface. Supports multiple "panels", -// each with its own controller. The panels are created lazily. -// -// The strongly retained instance variables |*Controller_| are instances of -// subclasses of CRWNativeContent that are created lazily. -// Each Panel is its own controller with the accessible views are added to the -// |ntpView_|. +// A controller for the New Tab Page user interface. Supports content +// suggestions and incognito, each with its own controller. // // The currently visible CRWNativeContent is accessible through // |currentController_|. @@ -47,7 +42,7 @@ swipeRecognizerProvider; // Exposes content inset of contentSuggestions collectionView to ensure all of -// content is visible under the bottom toolbar in ui refresh. +// content is visible under the bottom toolbar. @property(nonatomic) UIEdgeInsets contentInset; // Init with the given url (presumably "chrome://newtab") and loader object. @@ -75,8 +70,6 @@ #pragma mark - Testing -@class NewTabPageView; - @interface NewTabPageController (TestSupport) - (id<CRWNativeContent>)currentController; - (id<CRWNativeContent>)incognitoController;
diff --git a/ios/chrome/browser/ui/settings/google_services_settings_coordinator.mm b/ios/chrome/browser/ui/settings/google_services_settings_coordinator.mm index a0f8349..f9092982 100644 --- a/ios/chrome/browser/ui/settings/google_services_settings_coordinator.mm +++ b/ios/chrome/browser/ui/settings/google_services_settings_coordinator.mm
@@ -4,6 +4,7 @@ #import "ios/chrome/browser/ui/settings/google_services_settings_coordinator.h" +#include "base/mac/foundation_util.h" #include "base/metrics/user_metrics.h" #include "base/metrics/user_metrics_action.h" #include "components/browser_sync/profile_sync_service.h" @@ -15,6 +16,7 @@ #import "ios/chrome/browser/signin/authentication_service_factory.h" #include "ios/chrome/browser/sync/profile_sync_service_factory.h" #include "ios/chrome/browser/sync/sync_setup_service_factory.h" +#import "ios/chrome/browser/ui/authentication/authentication_flow.h" #import "ios/chrome/browser/ui/commands/application_commands.h" #import "ios/chrome/browser/ui/commands/open_new_tab_command.h" #import "ios/chrome/browser/ui/commands/show_signin_command.h" @@ -43,6 +45,11 @@ @property(nonatomic, strong) GoogleServicesSettingsMediator* mediator; // Returns the authentication service. @property(nonatomic, assign, readonly) AuthenticationService* authService; +// Manages the authentication flow for a given identity. +@property(nonatomic, strong) AuthenticationFlow* authenticationFlow; +// View controller presented by this coordinator. +@property(nonatomic, strong, readonly) + GoogleServicesSettingsViewController* googleServicesSettingsViewController; @end @@ -52,6 +59,7 @@ @synthesize delegate = _delegate; @synthesize dispatcher = _dispatcher; @synthesize mediator = _mediator; +@synthesize authenticationFlow = _authenticationFlow; - (void)start { UICollectionViewLayout* layout = [[MDCCollectionViewFlowLayout alloc] init]; @@ -95,10 +103,31 @@ return AuthenticationServiceFactory::GetForBrowserState(self.browserState); } +- (GoogleServicesSettingsViewController*)googleServicesSettingsViewController { + return base::mac::ObjCCast<GoogleServicesSettingsViewController>( + self.viewController); +} + #pragma mark - GoogleServicesSettingsLocalCommands - (void)restartAuthenticationFlow { - // TODO(crbug.com/849754): Restart the authentication flow. + ChromeIdentity* authenticatedIdentity = + AuthenticationServiceFactory::GetForBrowserState(self.browserState) + ->GetAuthenticatedIdentity(); + [self.googleServicesSettingsViewController preventUserInteraction]; + DCHECK(!self.authenticationFlow); + self.authenticationFlow = [[AuthenticationFlow alloc] + initWithBrowserState:self.browserState + identity:authenticatedIdentity + shouldClearData:SHOULD_CLEAR_DATA_USER_CHOICE + postSignInAction:POST_SIGNIN_ACTION_START_SYNC + presentingViewController:self.viewController]; + self.authenticationFlow.dispatcher = self.dispatcher; + __weak GoogleServicesSettingsCoordinator* weakSelf = self; + [self.authenticationFlow startSignInWithCompletion:^(BOOL success) { + // TODO(crbug.com/889919): Needs to add histogram for |success|. + [weakSelf.googleServicesSettingsViewController allowUserInteraction]; + }]; } - (void)openReauthDialogAsSyncIsInAuthError { @@ -113,7 +142,8 @@ } - (void)openPassphraseDialog { - // TODO(crbug.com/849754): open the passphrase dialog. + [self.dispatcher + showSyncPassphraseSettingsFromViewController:self.viewController]; } - (void)openGoogleActivityControlsDialog {
diff --git a/ios/web/web_state/web_frame_util.mm b/ios/web/web_state/web_frame_util.mm index 3550c57..8821a52f 100644 --- a/ios/web/web_state/web_frame_util.mm +++ b/ios/web/web_state/web_frame_util.mm
@@ -29,6 +29,8 @@ } WebFrame* GetWebFrameWithId(WebState* web_state, const std::string& frame_id) { + if (frame_id.size() == 0) + return nullptr; WebFramesManager* manager = WebFramesManager::FromWebState(web_state); DCHECK(manager); return manager->GetFrameWithId(frame_id);
diff --git a/ios/web_view/BUILD.gn b/ios/web_view/BUILD.gn index 64f0c40..591d5ee 100644 --- a/ios/web_view/BUILD.gn +++ b/ios/web_view/BUILD.gn
@@ -213,7 +213,11 @@ ] ios_web_view_sources += ios_web_view_public_headers if (ios_web_view_enable_sync) { - ios_web_view_sources += [ "internal/signin/cwv_identity.mm" ] + ios_web_view_sources += [ + "internal/signin/cwv_identity.mm", + "internal/sync/cwv_sync_controller.mm", + "internal/sync/cwv_sync_controller_internal.h", + ] } if (ios_web_view_enable_autofill) { ios_web_view_sources += [ @@ -378,6 +382,7 @@ "internal/cwv_html_element_unittest.mm", "internal/cwv_preferences_unittest.mm", "internal/cwv_preview_element_info_unittest.mm", + "internal/cwv_scroll_view_unittest.mm", "internal/signin/cwv_identity_unittest.mm", "internal/translate/cwv_translation_controller_unittest.mm", "internal/translate/cwv_translation_language_unittest.mm",
diff --git a/ios/web_view/internal/cwv_scroll_view.mm b/ios/web_view/internal/cwv_scroll_view.mm index f688dd0..2e4a541 100644 --- a/ios/web_view/internal/cwv_scroll_view.mm +++ b/ios/web_view/internal/cwv_scroll_view.mm
@@ -168,6 +168,14 @@ } } +- (BOOL)webViewScrollViewShouldScrollToTop: + (CRWWebViewScrollViewProxy*)webViewScrollViewProxy { + if ([_delegate respondsToSelector:@selector(scrollViewShouldScrollToTop:)]) { + return [_delegate scrollViewShouldScrollToTop:self]; + } + return YES; +} + - (void)webViewScrollViewDidResetContentSize: (CRWWebViewScrollViewProxy*)webViewScrollViewProxy { self.contentSize = _proxy.contentSize;
diff --git a/ios/web_view/internal/cwv_scroll_view_unittest.mm b/ios/web_view/internal/cwv_scroll_view_unittest.mm new file mode 100644 index 0000000..4ac915c --- /dev/null +++ b/ios/web_view/internal/cwv_scroll_view_unittest.mm
@@ -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. + +#import "ios/web_view/internal/cwv_scroll_view_internal.h" + +#import <UIKit/UIKit.h> + +#import "ios/web/public/web_state/ui/crw_web_view_scroll_view_proxy.h" +#import "ios/web_view/public/cwv_scroll_view_delegate.h" +#include "testing/gtest/include/gtest/gtest.h" +#import "testing/gtest_mac.h" +#include "testing/platform_test.h" +#import "third_party/ocmock/OCMock/OCMock.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +namespace ios_web_view { + +class CWVScrollViewTest : public PlatformTest { + protected: + CWVScrollViewTest() { + scroll_view_ = [[CWVScrollView alloc] init]; + + scroll_view_proxy_ = [[CRWWebViewScrollViewProxy alloc] init]; + scroll_view_.proxy = scroll_view_proxy_; + + ui_scroll_view_ = [[UIScrollView alloc] init]; + [scroll_view_proxy_ setScrollView:ui_scroll_view_]; + } + + CWVScrollView* scroll_view_; + UIScrollView* ui_scroll_view_; + CRWWebViewScrollViewProxy* scroll_view_proxy_; +}; + +// Tests CWVScrollView delegate callbacks. +TEST_F(CWVScrollViewTest, DelegateCallbacks) { + id delegate = OCMProtocolMock(@protocol(CWVScrollViewDelegate)); + scroll_view_.delegate = delegate; + + [[delegate expect] scrollViewWillBeginDragging:scroll_view_]; + [scroll_view_proxy_ scrollViewWillBeginDragging:ui_scroll_view_]; + + CGPoint targetContentOffset; + [[delegate expect] scrollViewWillEndDragging:scroll_view_ + withVelocity:CGPointZero + targetContentOffset:&targetContentOffset]; + [scroll_view_proxy_ scrollViewWillEndDragging:ui_scroll_view_ + withVelocity:CGPointZero + targetContentOffset:&targetContentOffset]; + + [[delegate expect] scrollViewDidScroll:scroll_view_]; + [scroll_view_proxy_ scrollViewDidScroll:ui_scroll_view_]; + + [[delegate expect] scrollViewDidEndDecelerating:scroll_view_]; + [scroll_view_proxy_ scrollViewDidEndDecelerating:ui_scroll_view_]; + + [[delegate expect] scrollViewShouldScrollToTop:scroll_view_]; + [scroll_view_proxy_ scrollViewShouldScrollToTop:ui_scroll_view_]; + + [[delegate expect] scrollViewWillBeginZooming:scroll_view_]; + [scroll_view_proxy_ scrollViewWillBeginZooming:ui_scroll_view_ withView:nil]; + + [delegate verify]; +} + +} // namespace ios_web_view
diff --git a/ios/web_view/internal/cwv_web_view_configuration.mm b/ios/web_view/internal/cwv_web_view_configuration.mm index 37fe6c1c6..217d557 100644 --- a/ios/web_view/internal/cwv_web_view_configuration.mm +++ b/ios/web_view/internal/cwv_web_view_configuration.mm
@@ -8,6 +8,7 @@ #include "base/logging.h" #include "base/threading/thread_restrictions.h" +#include "components/browser_sync/profile_sync_service.h" #include "ios/web_view/cwv_web_view_features.h" #include "ios/web_view/internal/app/application_context.h" #import "ios/web_view/internal/autofill/cwv_autofill_data_manager_internal.h" @@ -15,6 +16,13 @@ #import "ios/web_view/internal/cwv_preferences_internal.h" #import "ios/web_view/internal/cwv_user_content_controller_internal.h" #import "ios/web_view/internal/cwv_web_view_internal.h" +#include "ios/web_view/internal/signin/ios_web_view_signin_client.h" +#include "ios/web_view/internal/signin/web_view_account_tracker_service_factory.h" +#include "ios/web_view/internal/signin/web_view_oauth2_token_service_factory.h" +#include "ios/web_view/internal/signin/web_view_signin_client_factory.h" +#include "ios/web_view/internal/signin/web_view_signin_manager_factory.h" +#import "ios/web_view/internal/sync/cwv_sync_controller_internal.h" +#import "ios/web_view/internal/sync/web_view_profile_sync_service_factory.h" #include "ios/web_view/internal/web_view_browser_state.h" #include "ios/web_view/internal/web_view_global_state_util.h" @@ -40,6 +48,12 @@ CWVAutofillDataManager* autofillDataManager; #endif // BUILDFLAG(IOS_WEB_VIEW_ENABLE_AUTOFILL) +#if BUILDFLAG(IOS_WEB_VIEW_ENABLE_SYNC) +// This web view configuration's sync controller. +// nil if CWVWebViewConfiguration is created with +incognitoConfiguration. +@property(nonatomic, readonly, nullable) CWVSyncController* syncController; +#endif // BUILDFLAG(IOS_WEB_VIEW_ENABLE_SYNC) + // Initializes configuration with the specified browser state mode. - (instancetype)initWithBrowserState: (std::unique_ptr<ios_web_view::WebViewBrowserState>)browserState; @@ -52,6 +66,9 @@ @synthesize autofillDataManager = _autofillDataManager; #endif // BUILDFLAG(IOS_WEB_VIEW_ENABLE_AUTOFILL) @synthesize preferences = _preferences; +#if BUILDFLAG(IOS_WEB_VIEW_ENABLE_SYNC) +@synthesize syncController = _syncController; +#endif // BUILDFLAG(IOS_WEB_VIEW_ENABLE_SYNC) @synthesize userContentController = _userContentController; namespace { @@ -118,7 +135,6 @@ #if BUILDFLAG(IOS_WEB_VIEW_ENABLE_AUTOFILL) #pragma mark - Autofill - - (CWVAutofillDataManager*)autofillDataManager { if (!_autofillDataManager && self.persistent) { autofill::PersonalDataManager* personalDataManager = @@ -129,9 +145,42 @@ } return _autofillDataManager; } - #endif // BUILDFLAG(IOS_WEB_VIEW_ENABLE_AUTOFILL) +#if BUILDFLAG(IOS_WEB_VIEW_ENABLE_SYNC) +#pragma mark - Sync +- (CWVSyncController*)syncController { + if (!_syncController && self.persistent) { + browser_sync::ProfileSyncService* profileSyncService = + ios_web_view::WebViewProfileSyncServiceFactory::GetForBrowserState( + self.browserState); + AccountTrackerService* accountTrackerService = + ios_web_view::WebViewAccountTrackerServiceFactory::GetForBrowserState( + self.browserState); + SigninManager* signinManager = + ios_web_view::WebViewSigninManagerFactory::GetForBrowserState( + self.browserState); + ProfileOAuth2TokenService* tokenService = + ios_web_view::WebViewOAuth2TokenServiceFactory::GetForBrowserState( + self.browserState); + + _syncController = [[CWVSyncController alloc] + initWithProfileSyncService:profileSyncService + accountTrackerService:accountTrackerService + signinManager:signinManager + tokenService:tokenService]; + + // Set the newly created CWVSyncController on IOSWebViewSigninClient to + // so access tokens can be fetched. + IOSWebViewSigninClient* signinClient = + ios_web_view::WebViewSigninClientFactory::GetForBrowserState( + self.browserState); + signinClient->SetSyncController(_syncController); + } + return _syncController; +} +#endif // BUILDFLAG(IOS_WEB_VIEW_ENABLE_SYNC) + #pragma mark - Public Methods - (BOOL)isPersistent {
diff --git a/ios/web_view/internal/signin/ios_web_view_signin_client.h b/ios/web_view/internal/signin/ios_web_view_signin_client.h index d7db2c1..f5fc8bb 100644 --- a/ios/web_view/internal/signin/ios_web_view_signin_client.h +++ b/ios/web_view/internal/signin/ios_web_view_signin_client.h
@@ -16,6 +16,8 @@ #include "net/cookies/cookie_change_dispatcher.h" #include "services/network/public/cpp/shared_url_loader_factory.h" +@class CWVSyncController; + // iOS WebView specific signin client. class IOSWebViewSigninClient : public SigninClient, public SigninErrorController::Observer { @@ -46,6 +48,9 @@ content_settings::Observer* observer) override; void RemoveContentSettingsObserver( content_settings::Observer* observer) override; + void PreSignOut( + const base::RepeatingClosure& sign_out, + signin_metrics::ProfileSignout signout_source_metric) override; void DelayNetworkCall(const base::Closure& callback) override; std::unique_ptr<GaiaAuthFetcher> CreateGaiaAuthFetcher( GaiaAuthConsumer* consumer, @@ -57,6 +62,10 @@ // SigninErrorController::Observer implementation. void OnErrorChanged() override; + // CWVSyncController setter/getter. + void SetSyncController(CWVSyncController* sync_controller); + CWVSyncController* GetSyncController() const; + private: // Helper to delay callbacks until connection becomes online again. std::unique_ptr<WaitForNetworkCallbackHelper> network_callback_helper_; @@ -70,6 +79,10 @@ scoped_refptr<content_settings::CookieSettings> cookie_settings_; // Used to add and remove content settings observers. scoped_refptr<HostContentSettingsMap> host_content_settings_map_; + // Used by WebViewProfileOAuth2TokenServiceIOSProviderImpl to fetch access + // tokens. Also used to notify of signout events. Held weak so this class + // does not determine |sync_controller_|'s lifetime. + __weak CWVSyncController* sync_controller_ = nil; DISALLOW_COPY_AND_ASSIGN(IOSWebViewSigninClient); };
diff --git a/ios/web_view/internal/signin/ios_web_view_signin_client.mm b/ios/web_view/internal/signin/ios_web_view_signin_client.mm index b2101e65..b0ee3092 100644 --- a/ios/web_view/internal/signin/ios_web_view_signin_client.mm +++ b/ios/web_view/internal/signin/ios_web_view_signin_client.mm
@@ -7,6 +7,7 @@ #include "components/signin/core/browser/cookie_settings_util.h" #include "components/signin/core/browser/device_id_helper.h" #include "google_apis/gaia/gaia_auth_fetcher.h" +#import "ios/web_view/internal/sync/cwv_sync_controller_internal.h" #include "services/network/public/cpp/shared_url_loader_factory.h" #if !defined(__has_feature) || !__has_feature(objc_arc) @@ -84,6 +85,13 @@ host_content_settings_map_->RemoveObserver(observer); } +void IOSWebViewSigninClient::PreSignOut( + const base::RepeatingClosure& sign_out, + signin_metrics::ProfileSignout signout_source_metric) { + sign_out.Run(); + [sync_controller_ didSignoutWithSourceMetric:signout_source_metric]; +} + void IOSWebViewSigninClient::DelayNetworkCall(const base::Closure& callback) { network_callback_helper_->HandleCallback(callback); } @@ -97,3 +105,12 @@ } void IOSWebViewSigninClient::OnErrorChanged() {} + +void IOSWebViewSigninClient::SetSyncController( + CWVSyncController* sync_controller) { + sync_controller_ = sync_controller; +} + +CWVSyncController* IOSWebViewSigninClient::GetSyncController() const { + return sync_controller_; +}
diff --git a/ios/web_view/internal/signin/web_view_oauth2_token_service_factory.mm b/ios/web_view/internal/signin/web_view_oauth2_token_service_factory.mm index e0b86f61..4af229e 100644 --- a/ios/web_view/internal/signin/web_view_oauth2_token_service_factory.mm +++ b/ios/web_view/internal/signin/web_view_oauth2_token_service_factory.mm
@@ -56,7 +56,8 @@ IOSWebViewSigninClient* signin_client = WebViewSigninClientFactory::GetForBrowserState(browser_state); auto token_service_provider = - std::make_unique<WebViewProfileOAuth2TokenServiceIOSProviderImpl>(); + std::make_unique<WebViewProfileOAuth2TokenServiceIOSProviderImpl>( + signin_client); auto delegate = std::make_unique<ProfileOAuth2TokenServiceIOSDelegate>( signin_client, std::move(token_service_provider), WebViewAccountTrackerServiceFactory::GetForBrowserState(browser_state),
diff --git a/ios/web_view/internal/signin/web_view_profile_oauth2_token_service_ios_provider_impl.h b/ios/web_view/internal/signin/web_view_profile_oauth2_token_service_ios_provider_impl.h index c5dc1d2..26a69a7 100644 --- a/ios/web_view/internal/signin/web_view_profile_oauth2_token_service_ios_provider_impl.h +++ b/ios/web_view/internal/signin/web_view_profile_oauth2_token_service_ios_provider_impl.h
@@ -11,11 +11,15 @@ #include "base/macros.h" #include "components/signin/ios/browser/profile_oauth2_token_service_ios_provider.h" +class IOSWebViewSigninClient; + // Implementation of ProfileOAuth2TokenServiceIOSProvider. class WebViewProfileOAuth2TokenServiceIOSProviderImpl : public ProfileOAuth2TokenServiceIOSProvider { public: - WebViewProfileOAuth2TokenServiceIOSProviderImpl(); + // |signin_client| used to fetch access tokens. + explicit WebViewProfileOAuth2TokenServiceIOSProviderImpl( + IOSWebViewSigninClient* signin_client); ~WebViewProfileOAuth2TokenServiceIOSProviderImpl() override; // ios::ProfileOAuth2TokenServiceIOSProvider @@ -29,6 +33,9 @@ NSError* error) const override; private: + // Used to obtain access tokens in |GetAccessToken|. + IOSWebViewSigninClient* const signin_client_ = nullptr; + DISALLOW_COPY_AND_ASSIGN(WebViewProfileOAuth2TokenServiceIOSProviderImpl); };
diff --git a/ios/web_view/internal/signin/web_view_profile_oauth2_token_service_ios_provider_impl.mm b/ios/web_view/internal/signin/web_view_profile_oauth2_token_service_ios_provider_impl.mm index ab391de1..a0b4684a 100644 --- a/ios/web_view/internal/signin/web_view_profile_oauth2_token_service_ios_provider_impl.mm +++ b/ios/web_view/internal/signin/web_view_profile_oauth2_token_service_ios_provider_impl.mm
@@ -7,6 +7,7 @@ #include "base/logging.h" #include "base/strings/sys_string_conversions.h" #include "ios/web_view/internal/signin/ios_web_view_signin_client.h" +#import "ios/web_view/internal/sync/cwv_sync_controller_internal.h" #import "ios/web_view/public/cwv_identity.h" #if !defined(__has_feature) || !__has_feature(objc_arc) @@ -14,7 +15,9 @@ #endif WebViewProfileOAuth2TokenServiceIOSProviderImpl:: - WebViewProfileOAuth2TokenServiceIOSProviderImpl() {} + WebViewProfileOAuth2TokenServiceIOSProviderImpl( + IOSWebViewSigninClient* signin_client) + : signin_client_(signin_client) {} WebViewProfileOAuth2TokenServiceIOSProviderImpl:: ~WebViewProfileOAuth2TokenServiceIOSProviderImpl() = default; @@ -24,10 +27,25 @@ const std::string& client_id, const std::set<std::string>& scopes, const AccessTokenCallback& callback) { + // |sync_controller| may still be nil if this is called too early so + // |callback| will not be invoked. That's OK because this will be called again + // after |sync_controller| has been set. + CWVSyncController* sync_controller = signin_client_->GetSyncController(); + [sync_controller fetchAccessTokenForScopes:scopes callback:callback]; } std::vector<ProfileOAuth2TokenServiceIOSProvider::AccountInfo> WebViewProfileOAuth2TokenServiceIOSProviderImpl::GetAllAccounts() const { + // |sync_controller| may still be nil if this is called too early. That's OK + // because this will be called again after it has been set. + CWVSyncController* sync_controller = signin_client_->GetSyncController(); + CWVIdentity* current_identity = sync_controller.currentIdentity; + if (current_identity) { + AccountInfo account_info; + account_info.email = base::SysNSStringToUTF8(current_identity.email); + account_info.gaia = base::SysNSStringToUTF8(current_identity.gaiaID); + return {account_info}; + } return {}; }
diff --git a/ios/web_view/internal/sync/cwv_sync_controller.mm b/ios/web_view/internal/sync/cwv_sync_controller.mm new file mode 100644 index 0000000..bb6619ec --- /dev/null +++ b/ios/web_view/internal/sync/cwv_sync_controller.mm
@@ -0,0 +1,228 @@ +// 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 "ios/web_view/internal/sync/cwv_sync_controller_internal.h" + +#import <UIKit/UIKit.h> +#include <memory> + +#include "base/strings/sys_string_conversions.h" +#include "components/browser_sync/profile_sync_service.h" +#include "components/signin/core/browser/account_info.h" +#include "components/signin/core/browser/account_tracker_service.h" +#include "components/signin/core/browser/profile_oauth2_token_service.h" +#include "components/signin/core/browser/signin_manager.h" +#include "components/signin/ios/browser/profile_oauth2_token_service_ios_delegate.h" +#include "ios/web/public/web_thread.h" +#import "ios/web_view/public/cwv_identity.h" +#import "ios/web_view/public/cwv_sync_controller_data_source.h" +#import "ios/web_view/public/cwv_sync_controller_delegate.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +@interface CWVSyncController () + +// Called by WebViewSyncServiceObserverBridge's |OnSyncConfigurationCompleted|. +- (void)didCompleteSyncConfiguration; +// Called by WebViewSyncServiceObserverBridge's |OnSyncShutdown|. +- (void)didShutdownSync; + +// Call to refresh access tokens for |currentIdentity|. +- (void)reloadCredentials; + +@end + +namespace ios_web_view { + +// Bridge that observes browser_sync::ProfileSyncService and calls analagous +// methods on CWVSyncController. +class WebViewSyncServiceObserverBridge : public syncer::SyncServiceObserver { + public: + explicit WebViewSyncServiceObserverBridge(CWVSyncController* sync_controller) + : sync_controller_(sync_controller) {} + void OnStateChanged(syncer::SyncService* sync) override { + // No op. + } + + void OnSyncCycleCompleted(syncer::SyncService* sync) override { + // No op. + } + + void OnSyncConfigurationCompleted(syncer::SyncService* sync) override { + [sync_controller_ didCompleteSyncConfiguration]; + } + + void OnForeignSessionUpdated(syncer::SyncService* sync) override { + // No op. + } + + void OnSyncShutdown(syncer::SyncService* sync) override { + [sync_controller_ didShutdownSync]; + } + + private: + __weak CWVSyncController* sync_controller_; +}; + +} // namespace ios_web_view + +@implementation CWVSyncController { + browser_sync::ProfileSyncService* _profileSyncService; + AccountTrackerService* _accountTrackerService; + SigninManager* _signinManager; + IOSWebViewSigninClient* _signinClient; + ProfileOAuth2TokenService* _tokenService; + std::unique_ptr<ios_web_view::WebViewSyncServiceObserverBridge> _observer; + + // Data source that can provide access tokens. + __weak id<CWVSyncControllerDataSource> _dataSource; +} + +@synthesize delegate = _delegate; + +- (instancetype) +initWithProfileSyncService:(browser_sync::ProfileSyncService*)profileSyncService + accountTrackerService:(AccountTrackerService*)accountTrackerService + signinManager:(SigninManager*)signinManager + tokenService:(ProfileOAuth2TokenService*)tokenService { + self = [super init]; + if (self) { + _profileSyncService = profileSyncService; + _accountTrackerService = accountTrackerService; + _signinManager = signinManager; + _tokenService = tokenService; + _observer = + std::make_unique<ios_web_view::WebViewSyncServiceObserverBridge>(self); + _profileSyncService->AddObserver(_observer.get()); + + // Refresh access tokens on foreground to extend expiration dates. + [[NSNotificationCenter defaultCenter] + addObserver:self + selector:@selector(reloadCredentials) + name:UIApplicationWillEnterForegroundNotification + object:nil]; + } + return self; +} + +- (void)dealloc { + _profileSyncService->RemoveObserver(_observer.get()); +} + +#pragma mark - Public Methods + +- (CWVIdentity*)currentIdentity { + std::string authenticatedID = _signinManager->GetAuthenticatedAccountId(); + if (authenticatedID.empty()) { + return nil; + } + AccountInfo accountInfo = + _accountTrackerService->GetAccountInfo(authenticatedID); + NSString* email = base::SysUTF8ToNSString(accountInfo.email); + NSString* fullName = base::SysUTF8ToNSString(accountInfo.full_name); + NSString* gaiaID = base::SysUTF8ToNSString(accountInfo.gaia); + return + [[CWVIdentity alloc] initWithEmail:email fullName:fullName gaiaID:gaiaID]; +} + +- (BOOL)isPassphraseNeeded { + return _profileSyncService->IsPassphraseRequiredForDecryption(); +} + +- (void)startSyncWithIdentity:(CWVIdentity*)identity + dataSource: + (__weak id<CWVSyncControllerDataSource>)dataSource { + DCHECK(!_dataSource); + + _dataSource = dataSource; + + AccountInfo info; + info.gaia = base::SysNSStringToUTF8(identity.gaiaID); + info.email = base::SysNSStringToUTF8(identity.email); + info.full_name = base::SysNSStringToUTF8(identity.fullName); + std::string newAuthenticatedAccountID = + _accountTrackerService->SeedAccountInfo(info); + _signinManager->OnExternalSigninCompleted(info.email); + + [self reloadCredentials]; + _profileSyncService->RequestStart(); + _profileSyncService->SetFirstSetupComplete(); +} + +- (void)stopSyncAndClearIdentity { + _profileSyncService->RequestStop(syncer::SyncService::CLEAR_DATA); + _signinManager->SignOut( + signin_metrics::ProfileSignout::USER_CLICKED_SIGNOUT_SETTINGS, + signin_metrics::SignoutDelete::IGNORE_METRIC); + _dataSource = nil; +} + +- (BOOL)unlockWithPassphrase:(NSString*)passphrase { + return _profileSyncService->SetDecryptionPassphrase( + base::SysNSStringToUTF8(passphrase)); +} + +#pragma mark - Private Methods + +- (void)didCompleteSyncConfiguration { + if ([_delegate respondsToSelector:@selector(syncControllerDidStartSync:)]) { + [_delegate syncControllerDidStartSync:self]; + } +} + +- (void)didShutdownSync { + _profileSyncService->RemoveObserver(_observer.get()); +} + +- (void)reloadCredentials { + std::string authenticatedID = _signinManager->GetAuthenticatedAccountId(); + if (!authenticatedID.empty()) { + ProfileOAuth2TokenServiceIOSDelegate* tokenDelegate = + static_cast<ProfileOAuth2TokenServiceIOSDelegate*>( + _tokenService->GetDelegate()); + tokenDelegate->LoadCredentials(authenticatedID); + } +} + +#pragma mark - Internal Methods + +- (void)fetchAccessTokenForScopes:(const std::set<std::string>&)scopes + callback:(const ProfileOAuth2TokenServiceIOSProvider:: + AccessTokenCallback&)callback { + NSMutableArray<NSString*>* scopesArray = [NSMutableArray array]; + for (const auto& scope : scopes) { + [scopesArray addObject:base::SysUTF8ToNSString(scope)]; + } + ProfileOAuth2TokenServiceIOSProvider::AccessTokenCallback scopedCallback = + callback; + [_dataSource syncController:self + getAccessTokenForScopes:[scopesArray copy] + completionHandler:^(NSString* accessToken, NSDate* expirationDate, + NSError* error) { + if (!scopedCallback.is_null()) { + scopedCallback.Run(accessToken, expirationDate, error); + } + }]; +} + +- (void)didSignoutWithSourceMetric:(signin_metrics::ProfileSignout)metric { + if (![_delegate respondsToSelector:@selector + (syncController:didStopSyncWithReason:)]) { + return; + } + CWVStopSyncReason reason; + if (metric == signin_metrics::ProfileSignout::USER_CLICKED_SIGNOUT_SETTINGS) { + reason = CWVStopSyncReasonClient; + } else if (metric == signin_metrics::ProfileSignout::SERVER_FORCED_DISABLE) { + reason = CWVStopSyncReasonServer; + } else { + NOTREACHED(); + return; + } + [_delegate syncController:self didStopSyncWithReason:reason]; +} + +@end
diff --git a/ios/web_view/internal/sync/cwv_sync_controller_internal.h b/ios/web_view/internal/sync/cwv_sync_controller_internal.h new file mode 100644 index 0000000..1d0ee27 --- /dev/null +++ b/ios/web_view/internal/sync/cwv_sync_controller_internal.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 IOS_WEB_VIEW_INTERNAL_SYNC_CWV_SYNC_CONTROLLER_INTERNAL_H_ +#define IOS_WEB_VIEW_INTERNAL_SYNC_CWV_SYNC_CONTROLLER_INTERNAL_H_ + +#include <set> + +#include "components/signin/core/browser/signin_metrics.h" +#include "ios/web_view/internal/signin/web_view_profile_oauth2_token_service_ios_provider_impl.h" +#import "ios/web_view/public/cwv_sync_controller.h" + +namespace browser_sync { +class ProfileSyncService; +} // namespace browser_sync + +class AccountTrackerService; +class SigninManager; +class ProfileOAuth2TokenService; + +@interface CWVSyncController () + +// All dependencies must out live this class. +- (instancetype) +initWithProfileSyncService:(browser_sync::ProfileSyncService*)profileSyncService + accountTrackerService:(AccountTrackerService*)accountTrackerService + signinManager:(SigninManager*)signinManager + tokenService:(ProfileOAuth2TokenService*)tokenService + NS_DESIGNATED_INITIALIZER; + +// Called by WebViewProfileOAuth2TokenServiceIOSProviderImpl to obtain +// access tokens for |scopes| to be passed back in |callback|. +- (void)fetchAccessTokenForScopes:(const std::set<std::string>&)scopes + callback:(const ProfileOAuth2TokenServiceIOSProvider:: + AccessTokenCallback&)callback; + +// Called by IOSWebViewSigninClient when signing out. +- (void)didSignoutWithSourceMetric:(signin_metrics::ProfileSignout)metric; + +@end + +#endif // IOS_WEB_VIEW_INTERNAL_SYNC_CWV_SYNC_CONTROLLER_INTERNAL_H_
diff --git a/ios/web_view/internal/web_view_global_state_util.mm b/ios/web_view/internal/web_view_global_state_util.mm index fcf62ef..185244ae 100644 --- a/ios/web_view/internal/web_view_global_state_util.mm +++ b/ios/web_view/internal/web_view_global_state_util.mm
@@ -29,6 +29,13 @@ web_main_delegate = std::make_unique<ios_web_view::WebViewWebMainDelegate>(); web::WebMainParams params(web_main_delegate.get()); + params.argc = 2; + const char* executable = "ios-web-view"; + // This is used in SigninManagerBase to clear the tokens on startup. This + // greatly simplifies the management of ChromeWebView's signin state. + const char* clear_token = "--clear-token-service"; + const char* argv[] = {executable, clear_token}; + params.argv = argv; web_main = std::make_unique<web::WebMain>(std::move(params)); }); }
diff --git a/ios/web_view/public/cwv_scroll_view_delegate.h b/ios/web_view/public/cwv_scroll_view_delegate.h index 794333a6..31122b1 100644 --- a/ios/web_view/public/cwv_scroll_view_delegate.h +++ b/ios/web_view/public/cwv_scroll_view_delegate.h
@@ -24,6 +24,7 @@ targetContentOffset:(inout CGPoint*)targetContentOffset; - (void)scrollViewDidScroll:(CWVScrollView*)scrollView; - (void)scrollViewDidEndDecelerating:(CWVScrollView*)scrollView; +- (BOOL)scrollViewShouldScrollToTop:(CWVScrollView*)scrollView; // The equivalent in UIScrollViewDelegate also takes a parameter (UIView*)view, // but CWVScrollViewDelegate doesn't expose it for flexibility of future
diff --git a/media/blink/webmediaplayer_impl.cc b/media/blink/webmediaplayer_impl.cc index 0496c2d..253f3fd 100644 --- a/media/blink/webmediaplayer_impl.cc +++ b/media/blink/webmediaplayer_impl.cc
@@ -1152,8 +1152,7 @@ } video_renderer_.Paint( video_frame, canvas, gfx::RectF(gfx_rect), flags, - pipeline_metadata_.video_decoder_config.video_rotation(), context_3d, - context_provider_->ContextSupport()); + pipeline_metadata_.video_decoder_config.video_rotation(), context_3d); } bool WebMediaPlayerImpl::DidGetOpaqueResponseFromServiceWorker() const { @@ -1244,9 +1243,8 @@ context_provider_->GrContext()); } return video_renderer_.CopyVideoFrameTexturesToGLTexture( - context_3d, context_provider_->ContextSupport(), gl, video_frame.get(), - target, texture, internal_format, format, type, level, premultiply_alpha, - flip_y); + context_3d, gl, video_frame.get(), target, texture, internal_format, + format, type, level, premultiply_alpha, flip_y); } // static
diff --git a/media/gpu/v4l2/v4l2_device.cc b/media/gpu/v4l2/v4l2_device.cc index 83843ce0..024570f 100644 --- a/media/gpu/v4l2/v4l2_device.cc +++ b/media/gpu/v4l2/v4l2_device.cc
@@ -7,11 +7,14 @@ #include <libdrm/drm_fourcc.h> #include <linux/videodev2.h> #include <string.h> +#include <sys/mman.h> #include <sstream> +#include "base/bind.h" #include "base/logging.h" #include "base/numerics/safe_conversions.h" #include "build/build_config.h" +#include "media/base/bind_to_current_loop.h" #include "media/base/video_types.h" #include "media/gpu/v4l2/generic_v4l2_device.h" #if defined(ARCH_CPU_ARMEL) @@ -20,13 +23,774 @@ #define DVLOGF(level) DVLOG(level) << __func__ << "(): " #define VLOGF(level) VLOG(level) << __func__ << "(): " +#define VPLOGF(level) VPLOG(level) << __func__ << "(): " namespace media { +// Class used to store the state of a buffer that should persist between +// reference creations. This includes: +// * Result of initial VIDIOC_QUERYBUF ioctl, +// * Plane mappings. +// +// Also provides helper functions. +class V4L2Buffer { + public: + static std::unique_ptr<V4L2Buffer> Create(scoped_refptr<V4L2Device> device, + enum v4l2_buf_type type, + enum v4l2_memory memory, + size_t buffer_id); + ~V4L2Buffer(); + + void* GetPlaneMapping(const size_t plane); + const struct v4l2_buffer* v4l2_buffer() const { return &v4l2_buffer_; } + + private: + V4L2Buffer(scoped_refptr<V4L2Device> device, + enum v4l2_buf_type type, + enum v4l2_memory memory, + size_t buffer_id); + bool Query(); + + scoped_refptr<V4L2Device> device_; + std::vector<void*> plane_mappings_; + + // V4L2 data as queried by QUERYBUF. + struct v4l2_buffer v4l2_buffer_ = {}; + struct v4l2_plane v4l2_planes_[VIDEO_MAX_PLANES] = {{}}; + + DISALLOW_COPY_AND_ASSIGN(V4L2Buffer); +}; + +std::unique_ptr<V4L2Buffer> V4L2Buffer::Create(scoped_refptr<V4L2Device> device, + enum v4l2_buf_type type, + enum v4l2_memory memory, + size_t buffer_id) { + // Not using std::make_unique because constructor is private. + std::unique_ptr<V4L2Buffer> buffer( + new V4L2Buffer(device, type, memory, buffer_id)); + + if (!buffer->Query()) + return nullptr; + + return buffer; +} + +V4L2Buffer::V4L2Buffer(scoped_refptr<V4L2Device> device, + enum v4l2_buf_type type, + enum v4l2_memory memory, + size_t buffer_id) + : device_(device), plane_mappings_(VIDEO_MAX_PLANES) { + DCHECK(V4L2_TYPE_IS_MULTIPLANAR(type)); + v4l2_buffer_.m.planes = v4l2_planes_; + v4l2_buffer_.length = VIDEO_MAX_PLANES; + v4l2_buffer_.index = buffer_id; + v4l2_buffer_.type = type; + v4l2_buffer_.memory = memory; +} + +V4L2Buffer::~V4L2Buffer() { + if (v4l2_buffer_.memory == V4L2_MEMORY_MMAP) { + for (size_t i = 0; i < plane_mappings_.size(); i++) + if (plane_mappings_[i] != nullptr) + device_->Munmap(plane_mappings_[i], v4l2_buffer_.m.planes[i].length); + } +} + +bool V4L2Buffer::Query() { + int ret = device_->Ioctl(VIDIOC_QUERYBUF, &v4l2_buffer_); + if (ret) { + VPLOGF(1) << "VIDIOC_QUERYBUF failed: "; + return false; + } + + plane_mappings_.resize(v4l2_buffer_.length); + + return true; +} + +void* V4L2Buffer::GetPlaneMapping(const size_t plane) { + if (plane >= plane_mappings_.size()) { + VLOGF(1) << "Invalid plane " << plane << " requested."; + return nullptr; + } + + void* p = plane_mappings_[plane]; + if (p) + return p; + + // Do this check here to avoid repeating it after a buffer has been + // successfully mapped (we know we are of MMAP type by then). + if (v4l2_buffer_.memory != V4L2_MEMORY_MMAP) { + VLOGF(1) << "Cannot create mapping on non-MMAP buffer"; + return nullptr; + } + + p = device_->Mmap(NULL, v4l2_buffer_.m.planes[plane].length, + PROT_READ | PROT_WRITE, MAP_SHARED, + v4l2_buffer_.m.planes[plane].m.mem_offset); + if (p == MAP_FAILED) { + VPLOGF(1) << "mmap() failed: "; + return nullptr; + } + + plane_mappings_[plane] = p; + return p; +} + +// Module-private class that let users query/write V4L2 buffer information. +// It also makes some private V4L2Queue methods available to this module only. +class V4L2BufferQueueProxy { + public: + V4L2BufferQueueProxy(const struct v4l2_buffer* v4l2_buffer, + scoped_refptr<V4L2Queue> queue); + + void ReturnBuffer() { queue_->ReturnBuffer(BufferId()); } + + bool QueueBuffer(); + + void* GetPlaneMapping(const size_t plane) { + return queue_->buffers_[BufferId()]->GetPlaneMapping(plane); + } + + // Data from the buffer, that users can query and/or write. + struct v4l2_buffer v4l2_buffer_; + struct v4l2_plane v4l2_planes_[VIDEO_MAX_PLANES]; + + private: + size_t BufferId() const { return v4l2_buffer_.index; } + + // The queue must be kept alive as long as the reference to the buffer exists. + scoped_refptr<V4L2Queue> queue_; + + DISALLOW_COPY_AND_ASSIGN(V4L2BufferQueueProxy); +}; + +V4L2BufferQueueProxy::V4L2BufferQueueProxy( + const struct v4l2_buffer* v4l2_buffer, + scoped_refptr<V4L2Queue> queue) + : queue_(std::move(queue)) { + DCHECK(V4L2_TYPE_IS_MULTIPLANAR(v4l2_buffer->type)); + DCHECK_LE(v4l2_buffer->length, static_cast<uint32_t>(VIDEO_MAX_PLANES)); + + memcpy(&v4l2_buffer_, v4l2_buffer, sizeof(v4l2_buffer_)); + memcpy(v4l2_planes_, v4l2_buffer->m.planes, + sizeof(struct v4l2_plane) * v4l2_buffer->length); + v4l2_buffer_.m.planes = v4l2_planes_; +} + +bool V4L2BufferQueueProxy::QueueBuffer() { + bool queued = queue_->QueueBuffer(&v4l2_buffer_); + + // If an error occurred during queueing, then the buffer must be made + // available again. + if (!queued) + ReturnBuffer(); + + return queued; +} + +V4L2WritableBufferRef::V4L2WritableBufferRef() { + // Invalid buffers can be created from any thread. + DETACH_FROM_SEQUENCE(sequence_checker_); +} + +V4L2WritableBufferRef::V4L2WritableBufferRef( + const struct v4l2_buffer* v4l2_buffer, + scoped_refptr<V4L2Queue> queue) + : buffer_data_(std::make_unique<V4L2BufferQueueProxy>(v4l2_buffer, + std::move(queue))) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); +} + +V4L2WritableBufferRef::V4L2WritableBufferRef(V4L2WritableBufferRef&& other) + : buffer_data_(std::move(other.buffer_data_)) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK_CALLED_ON_VALID_SEQUENCE(other.sequence_checker_); +} + +V4L2WritableBufferRef::~V4L2WritableBufferRef() { + // Only valid references should be sequence-checked + if (buffer_data_) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + buffer_data_->ReturnBuffer(); + } +} + +V4L2WritableBufferRef& V4L2WritableBufferRef::operator=( + V4L2WritableBufferRef&& other) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK_CALLED_ON_VALID_SEQUENCE(other.sequence_checker_); + + if (this == &other) + return *this; + + if (IsValid()) + buffer_data_->ReturnBuffer(); + buffer_data_ = std::move(other.buffer_data_); + + return *this; +} + +bool V4L2WritableBufferRef::IsValid() const { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + return buffer_data_ != nullptr; +} + +enum v4l2_memory V4L2WritableBufferRef::Memory() const { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(IsValid()); + + return static_cast<enum v4l2_memory>(buffer_data_->v4l2_buffer_.memory); +} + +bool V4L2WritableBufferRef::DoQueue() && { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(IsValid()); + + bool queued = buffer_data_->QueueBuffer(); + + // Clear our own reference. + buffer_data_.reset(); + + return queued; +} + +bool V4L2WritableBufferRef::QueueMMap() && { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(IsValid()); + + // Move ourselves so our data gets freed no matter when we return + V4L2WritableBufferRef self(std::move(*this)); + + if (self.Memory() != V4L2_MEMORY_MMAP) { + VLOGF(1) << "Called on invalid buffer type!"; + return false; + } + + return std::move(self).DoQueue(); +} + +bool V4L2WritableBufferRef::QueueUserPtr(const std::vector<void*>& ptrs) && { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(IsValid()); + + // Move ourselves so our data gets freed no matter when we return + V4L2WritableBufferRef self(std::move(*this)); + + if (self.Memory() != V4L2_MEMORY_USERPTR) { + VLOGF(1) << "Called on invalid buffer type!"; + return false; + } + + if (ptrs.size() != self.PlanesCount()) { + VLOGF(1) << "Provided " << ptrs.size() << " pointers while we require " + << self.buffer_data_->v4l2_buffer_.length << "."; + return false; + } + + for (size_t i = 0; i < ptrs.size(); i++) + self.buffer_data_->v4l2_buffer_.m.planes[i].m.userptr = + reinterpret_cast<unsigned long>(ptrs[i]); + + return std::move(self).DoQueue(); +} + +bool V4L2WritableBufferRef::QueueDMABuf( + const std::vector<base::ScopedFD>& fds) && { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(IsValid()); + + // Move ourselves so our data gets freed no matter when we return + V4L2WritableBufferRef self(std::move(*this)); + + if (self.Memory() != V4L2_MEMORY_DMABUF) { + VLOGF(1) << "Called on invalid buffer type!"; + return false; + } + + if (fds.size() != self.PlanesCount()) { + VLOGF(1) << "Provided " << fds.size() << " FDs while we require " + << self.buffer_data_->v4l2_buffer_.length << "."; + return false; + } + + for (size_t i = 0; i < fds.size(); i++) + self.buffer_data_->v4l2_buffer_.m.planes[i].m.fd = fds[i].get(); + + return std::move(self).DoQueue(); +} + +size_t V4L2WritableBufferRef::PlanesCount() const { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(IsValid()); + + return buffer_data_->v4l2_buffer_.length; +} + +size_t V4L2WritableBufferRef::GetPlaneSize(const size_t plane) const { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(IsValid()); + + if (plane >= PlanesCount()) { + VLOGF(1) << "Invalid plane " << plane << " requested."; + return 0; + } + + return buffer_data_->v4l2_buffer_.m.planes[plane].length; +} + +void* V4L2WritableBufferRef::GetPlaneMapping(const size_t plane) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(IsValid()); + + return buffer_data_->GetPlaneMapping(plane); +} + +void V4L2WritableBufferRef::SetTimeStamp(const struct timeval& timestamp) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(IsValid()); + + buffer_data_->v4l2_buffer_.timestamp = timestamp; +} + +const struct timeval& V4L2WritableBufferRef::GetTimeStamp() const { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(IsValid()); + + return buffer_data_->v4l2_buffer_.timestamp; +} + +void V4L2WritableBufferRef::SetPlaneBytesUsed(const size_t plane, + const size_t bytes_used) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(IsValid()); + + if (plane >= PlanesCount()) { + VLOGF(1) << "Invalid plane " << plane << " requested."; + return; + } + + if (bytes_used >= GetPlaneSize(plane)) { + VLOGF(1) << "Set bytes used " << bytes_used << " larger than plane size " + << GetPlaneSize(plane) << "."; + return; + } + + buffer_data_->v4l2_buffer_.m.planes[plane].bytesused = bytes_used; +} + +size_t V4L2WritableBufferRef::GetPlaneBytesUsed(const size_t plane) const { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(IsValid()); + + if (plane >= PlanesCount()) { + VLOGF(1) << "Invalid plane " << plane << " requested."; + return 0; + } + + return buffer_data_->v4l2_buffer_.m.planes[plane].bytesused; +} + +size_t V4L2WritableBufferRef::BufferId() const { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(IsValid()); + + return buffer_data_->v4l2_buffer_.index; +} + +V4L2ReadableBuffer::V4L2ReadableBuffer(const struct v4l2_buffer* v4l2_buffer, + scoped_refptr<V4L2Queue> queue) + : buffer_data_(std::make_unique<V4L2BufferQueueProxy>(v4l2_buffer, + std::move(queue))) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); +} + +V4L2ReadableBuffer::~V4L2ReadableBuffer() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(buffer_data_); + + buffer_data_->ReturnBuffer(); +} + +bool V4L2ReadableBuffer::IsLast() const { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(buffer_data_); + + return buffer_data_->v4l2_buffer_.flags & V4L2_BUF_FLAG_LAST; +} + +struct timeval V4L2ReadableBuffer::GetTimeStamp() const { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(buffer_data_); + + return buffer_data_->v4l2_buffer_.timestamp; +} + +size_t V4L2ReadableBuffer::PlanesCount() const { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(buffer_data_); + + return buffer_data_->v4l2_buffer_.length; +} + +size_t V4L2ReadableBuffer::GetPlaneBytesUsed(const size_t plane) const { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(buffer_data_); + + if (plane >= PlanesCount()) { + VLOGF(1) << "Invalid plane " << plane << " requested."; + return 0; + } + + return buffer_data_->v4l2_planes_[plane].bytesused; +} + +size_t V4L2ReadableBuffer::BufferId() const { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(buffer_data_); + + return buffer_data_->v4l2_buffer_.index; +} + +// This class is used to expose buffer reference classes constructors to +// this module. This is to ensure that nobody else can create buffer references. +class V4L2BufferRefFactory { + public: + static V4L2WritableBufferRef CreateWritableRef( + const struct v4l2_buffer* v4l2_buffer, + scoped_refptr<V4L2Queue> queue) { + return V4L2WritableBufferRef(v4l2_buffer, std::move(queue)); + } + + static V4L2ReadableBufferRef CreateReadableRef( + const struct v4l2_buffer* v4l2_buffer, + scoped_refptr<V4L2Queue> queue) { + return new V4L2ReadableBuffer(v4l2_buffer, std::move(queue)); + } +}; + +V4L2Queue::V4L2Queue(scoped_refptr<V4L2Device> dev, + enum v4l2_buf_type type, + base::OnceClosure destroy_cb) + : type_(type), device_(dev), destroy_cb_(std::move(destroy_cb)) { + // TODO(acourbot): fix clients - the constructor should be called on the same + // sequence as the rest. + DETACH_FROM_SEQUENCE(sequence_checker_); +} + +V4L2Queue::~V4L2Queue() { + // TODO(acourbot): we do this prior to checking the sequence because we + // tolerate queues to be destroyed in the wrong thread if they are properly + // cleaned up. But ultimately clients should be fixed. + if (!is_streaming_ && buffers_.empty()) { + std::move(destroy_cb_).Run(); + return; + } + + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + if (is_streaming_) { + VLOGF(1) << "Queue is still streaming, trying to stop it..."; + Streamoff(); + } + + DCHECK(queued_buffers_.empty()); + DCHECK(free_buffers_.empty()); + + if (!buffers_.empty()) { + VLOGF(1) << "Buffers are still allocated, trying to deallocate them..."; + DeallocateBuffers(); + } + + std::move(destroy_cb_).Run(); +} + +size_t V4L2Queue::AllocateBuffers(size_t count, enum v4l2_memory memory) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK_EQ(free_buffers_.size(), 0u); + DCHECK_EQ(queued_buffers_.size(), 0u); + + if (IsStreaming()) { + VLOGF(1) << "Cannot allocate buffers while streaming."; + return 0; + } + + if (buffers_.size() != 0) { + VLOGF(1) << "Cannot allocate new buffers while others are still allocated."; + return 0; + } + + if (count == 0) { + VLOGF(1) << "Attempting to allocate 0 buffers."; + return 0; + } + + struct v4l2_requestbuffers reqbufs = {}; + reqbufs.count = count; + reqbufs.type = type_; + reqbufs.memory = memory; + DVLOGF(3) << "queue " << type_ << ": requesting " << count << " buffers."; + + int ret = device_->Ioctl(VIDIOC_REQBUFS, &reqbufs); + if (ret) { + VPLOGF(1) << "VIDIOC_REQBUFS failed: "; + return 0; + } + DVLOGF(3) << "queue " << type_ << ": got " << reqbufs.count << " buffers."; + + memory_ = memory; + + // Now query all buffer information. + for (size_t i = 0; i < reqbufs.count; i++) { + auto buffer = V4L2Buffer::Create(device_, type_, memory_, i); + + if (!buffer) { + DeallocateBuffers(); + + return 0; + } + + buffers_.emplace_back(std::move(buffer)); + ReturnBuffer(i); + } + + DCHECK_EQ(free_buffers_.size(), buffers_.size()); + DCHECK_EQ(queued_buffers_.size(), 0u); + + return buffers_.size(); +} + +bool V4L2Queue::DeallocateBuffers() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + if (IsStreaming()) { + VLOGF(1) << "Cannot deallocate buffers while streaming."; + return false; + } + + if (buffers_.size() != free_buffers_.size()) { + VPLOGF(1) << "Trying to deallocate buffers while some are still in use!"; + return false; + } + + if (buffers_.size() == 0) + return true; + + // Free all buffers. + struct v4l2_requestbuffers reqbufs = {}; + reqbufs.count = 0; + reqbufs.type = type_; + reqbufs.memory = memory_; + + int ret = device_->Ioctl(VIDIOC_REQBUFS, &reqbufs); + if (ret) { + VPLOGF(1) << "VIDIOC_REQBUFS failed: "; + return false; + } + + buffers_.clear(); + free_buffers_.clear(); + + DCHECK_EQ(free_buffers_.size(), 0u); + DCHECK_EQ(queued_buffers_.size(), 0u); + + return true; +} + +V4L2WritableBufferRef V4L2Queue::GetFreeBuffer() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + auto iter = free_buffers_.begin(); + + if (iter == free_buffers_.end()) { + VLOGF(3) << "No free buffer available!"; + return V4L2WritableBufferRef(); + } + + size_t buffer_id = *iter; + free_buffers_.erase(buffer_id); + + return V4L2BufferRefFactory::CreateWritableRef( + buffers_[buffer_id]->v4l2_buffer(), this); +} + +void V4L2Queue::ReturnBuffer(size_t buffer_id) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + auto inserted = free_buffers_.emplace(buffer_id); + DCHECK_EQ(inserted.second, true); +} + +bool V4L2Queue::QueueBuffer(struct v4l2_buffer* v4l2_buffer) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + int ret = device_->Ioctl(VIDIOC_QBUF, v4l2_buffer); + if (ret) { + VPLOGF(1) << "VIDIOC_QBUF failed: "; + return false; + } + + auto inserted = queued_buffers_.emplace(v4l2_buffer->index); + DCHECK_EQ(inserted.second, true); + + return true; +} + +std::pair<bool, V4L2ReadableBufferRef> V4L2Queue::DequeueBuffer() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + // No need to dequeue if no buffers queued. + if (QueuedBuffersCount() == 0) + return std::make_pair(true, nullptr); + + if (!IsStreaming()) { + VLOGF(1) << "Attempting to dequeue a buffer while not streaming."; + return std::make_pair(true, nullptr); + } + + struct v4l2_buffer v4l2_buffer = {}; + struct v4l2_plane planes[VIDEO_MAX_PLANES] = {{}}; + v4l2_buffer.type = type_; + v4l2_buffer.memory = memory_; + v4l2_buffer.m.planes = planes; + // TODO(acourbot): use actual number of planes. + v4l2_buffer.length = VIDEO_MAX_PLANES; + int ret = device_->Ioctl(VIDIOC_DQBUF, &v4l2_buffer); + if (ret) { + // TODO(acourbot): we should not have to check for EPIPE as codec clients + // should not call this method after the last buffer is dequeued. + switch (errno) { + case EAGAIN: + case EPIPE: + // This is not an error but won't provide a buffer either. + return std::make_pair(true, nullptr); + default: + VPLOGF(1) << "VIDIOC_DQBUF failed: "; + return std::make_pair(false, nullptr); + } + } + + auto it = queued_buffers_.find(v4l2_buffer.index); + DCHECK(it != queued_buffers_.end()); + queued_buffers_.erase(*it); + + return std::make_pair( + true, V4L2BufferRefFactory::CreateReadableRef(&v4l2_buffer, this)); +} + +bool V4L2Queue::IsStreaming() const { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + return is_streaming_; +} + +bool V4L2Queue::Streamon() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + if (is_streaming_) + return true; + + int arg = static_cast<int>(type_); + int ret = device_->Ioctl(VIDIOC_STREAMON, &arg); + if (ret) { + VPLOGF(1) << "VIDIOC_STREAMON failed: "; + return false; + } + + is_streaming_ = true; + + return true; +} + +bool V4L2Queue::Streamoff() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + // We do not check the value of IsStreaming(), because we may have queued + // buffers to the queue and wish to get them back - in such as case, we may + // need to do a VIDIOC_STREAMOFF on a stopped queue. + + int arg = static_cast<int>(type_); + int ret = device_->Ioctl(VIDIOC_STREAMOFF, &arg); + if (ret) { + VPLOGF(1) << "VIDIOC_STREAMOFF failed: "; + return false; + } + + for (const auto& buffer_id : queued_buffers_) + ReturnBuffer(buffer_id); + + queued_buffers_.clear(); + + is_streaming_ = false; + + return true; +} + +size_t V4L2Queue::AllocatedBuffersCount() const { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + return buffers_.size(); +} + +size_t V4L2Queue::FreeBuffersCount() const { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + return free_buffers_.size(); +} + +size_t V4L2Queue::QueuedBuffersCount() const { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + return queued_buffers_.size(); +} + +// This class is used to expose V4L2Queue's constructor to this module. This is +// to ensure that nobody else can create instances of it. +class V4L2QueueFactory { + public: + static scoped_refptr<V4L2Queue> CreateQueue(scoped_refptr<V4L2Device> dev, + enum v4l2_buf_type type, + base::OnceClosure destroy_cb) { + return new V4L2Queue(std::move(dev), type, std::move(destroy_cb)); + } +}; + V4L2Device::V4L2Device() {} V4L2Device::~V4L2Device() {} +scoped_refptr<V4L2Queue> V4L2Device::GetQueue(enum v4l2_buf_type type) { + switch (type) { + // Supported queue types. + case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: + case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: + break; + default: + VLOGF(1) << "Unsupported V4L2 queue type: " << type; + return nullptr; + } + + // TODO(acourbot): we should instead query the device for available queues, + // and allocate them accordingly. This will do for now though. + auto it = queues_.find(type); + if (it != queues_.end()) + return scoped_refptr<V4L2Queue>(it->second); + + scoped_refptr<V4L2Queue> queue = V4L2QueueFactory::CreateQueue( + this, type, + media::BindToCurrentLoop( + base::Bind(&V4L2Device::OnQueueDestroyed, this, type))); + + queues_[type] = queue.get(); + return queue; +} + +void V4L2Device::OnQueueDestroyed(v4l2_buf_type buf_type) { + auto it = queues_.find(buf_type); + DCHECK(it != queues_.end()); + queues_.erase(it); +} + // static scoped_refptr<V4L2Device> V4L2Device::Create() { VLOGF(2);
diff --git a/media/gpu/v4l2/v4l2_device.h b/media/gpu/v4l2/v4l2_device.h index db9514c3..d17657c9 100644 --- a/media/gpu/v4l2/v4l2_device.h +++ b/media/gpu/v4l2/v4l2_device.h
@@ -12,8 +12,11 @@ #include <stddef.h> #include <stdint.h> +#include <vector> + #include <linux/videodev2.h> +#include "base/containers/flat_map.h" #include "base/files/scoped_file.h" #include "base/memory/ref_counted.h" #include "media/base/video_decoder_config.h" @@ -34,6 +37,244 @@ namespace media { +class V4L2Queue; +class V4L2BufferQueueProxy; + +// A unique reference to a buffer for clients to prepare and submit. +// +// Clients can prepare a buffer for queuing using the methods of this class, and +// then either queue it using the Queue() method corresponding to the memory +// type of the buffer, or drop the reference to make the buffer available again. +class MEDIA_GPU_EXPORT V4L2WritableBufferRef { + public: + // Default constructor, creates invalid buffer reference. + V4L2WritableBufferRef(); + V4L2WritableBufferRef(V4L2WritableBufferRef&& other); + V4L2WritableBufferRef& operator=(V4L2WritableBufferRef&& other); + + // Returns true if the reference points to a valid buffer. + bool IsValid() const; + + // Return the memory type of the buffer. Useful to e.g. decide which Queue() + // method to use. + enum v4l2_memory Memory() const; + + // Queue a MMAP buffer. + // If successful, true is returned and the reference to the buffer is dropped + // so this reference becomes invalid. + // In case of error, false is returned and the buffer is returned to the free + // list. + bool QueueMMap() &&; + // Queue a USERPTR buffer, assigning |ptrs| as pointer for each plane. + // The size of |ptrs| must be equal to the number of planes of this buffer. + // If successful, true is returned and the reference to the buffer is dropped + // so this reference becomes invalid. + // In case of error, false is returned and the buffer is returned to the free + // list. + bool QueueUserPtr(const std::vector<void*>& ptrs) &&; + // Queue a DMABUF buffer, assigning |fds| as file descriptors for each plane. + // The size of |fds| must be equal to the number of planes of this buffer. + // If successful, true is returned and the reference to the buffer is dropped + // so this reference becomes invalid. + // In case of error, false is returned and the buffer is returned to the free + // list. + bool QueueDMABuf(const std::vector<base::ScopedFD>& fds) &&; + + // Returns the number of planes in this buffer. + size_t PlanesCount() const; + // Returns the size of the requested |plane|, in bytes. + size_t GetPlaneSize(const size_t plane) const; + // This method can only be used with MMAP buffers. + // It will return a pointer to the data of the |plane|th plane. + // In case of error (invalid plane index or mapping failed), a nullptr is + // returned. + void* GetPlaneMapping(const size_t plane); + // Set the timestamp field for this buffer. + void SetTimeStamp(const struct timeval& timestamp); + // Return the previously-set timestamp field for this buffer. + const struct timeval& GetTimeStamp() const; + // Set the number of bytes used for |plane|. + void SetPlaneBytesUsed(const size_t plane, const size_t bytes_used); + // Returns the previously-set number of bytes used for |plane|. + size_t GetPlaneBytesUsed(const size_t plane) const; + + // Return the V4L2 buffer ID of the underlying buffer. + // TODO(acourbot) This is used for legacy clients but should be ultimately + // removed. See crbug/879971 + size_t BufferId() const; + + ~V4L2WritableBufferRef(); + + private: + // Do the actual queue operation once the v4l2_buffer structure is properly + // filled. + bool DoQueue() &&; + + V4L2WritableBufferRef(const struct v4l2_buffer* v4l2_buffer, + scoped_refptr<V4L2Queue> queue); + friend class V4L2BufferRefFactory; + + std::unique_ptr<V4L2BufferQueueProxy> buffer_data_; + + SEQUENCE_CHECKER(sequence_checker_); + DISALLOW_COPY_AND_ASSIGN(V4L2WritableBufferRef); +}; + +// A reference to a read-only, dequeued buffer. +// +// Clients use this class to query the buffer state and content, and are +// guaranteed that the buffer will not be reused until all references are +// destroyed. +class MEDIA_GPU_EXPORT V4L2ReadableBuffer + : public base::RefCounted<V4L2ReadableBuffer> { + public: + // Returns whether the V4L2_BUF_FLAG_LAST flag is set for this buffer. + bool IsLast() const; + // Return the timestamp set by the driver on this buffer. + struct timeval GetTimeStamp() const; + // Returns the number of planes in this buffer. + size_t PlanesCount() const; + // Returns the number of bytes used for |plane|. + size_t GetPlaneBytesUsed(size_t plane) const; + + // Return the V4L2 buffer ID of the underlying buffer. + // TODO(acourbot) This is used for legacy clients but should be ultimately + // removed. See crbug/879971 + size_t BufferId() const; + + private: + ~V4L2ReadableBuffer(); + + V4L2ReadableBuffer(const struct v4l2_buffer* v4l2_buffer, + scoped_refptr<V4L2Queue> queue); + friend class V4L2BufferRefFactory; + + std::unique_ptr<V4L2BufferQueueProxy> buffer_data_; + + SEQUENCE_CHECKER(sequence_checker_); + friend class base::RefCounted<V4L2ReadableBuffer>; + DISALLOW_COPY_AND_ASSIGN(V4L2ReadableBuffer); +}; + +// Shortcut for naming consistency. +using V4L2ReadableBufferRef = scoped_refptr<V4L2ReadableBuffer>; + +class V4L2Device; +class V4L2Buffer; + +// Interface representing a specific queue of a |V4L2Device|. It provides free +// and queued buffer management that is commonly required by clients. +// +// Buffers managed by this class undergo the following cycle: +// 1) Allocated buffers are put into a free buffers pool, indicating that they +// are used neither by the client nor the hardware. +// 2) The client obtains a unique, writable reference to one of the free +// buffers in order to set its content and other parameters. +// 3) The client then queues the buffer obtained in 2), which invalidates its +// reference. The buffer is now prepared to be processed by the hardware. +// 4) Once the hardware is done with the buffer, it is ready to be dequeued by +// the client. The client obtains a read-only, counted reference to the +// buffer and can read its content and metadata, as well as making other +// references to it. The buffer will not be reused until all the references +// are dropped. Once this happens, the buffer goes back to the free list +// described in 1). +class MEDIA_GPU_EXPORT V4L2Queue + : public base::RefCountedThreadSafe<V4L2Queue> { + public: + // Allocate |count| buffers for the current format of this queue, with a + // specific |memory| allocation, and returns the number of buffers allocated + // or zero if an error occurred, or if references to any previously allocated + // buffers are still held by any clients. + // + // The number of allocated buffers may be larger than the number requested, so + // callers must always check the return value. + // + // Calling this method while buffers are still allocated results in an error. + size_t AllocateBuffers(size_t count, + enum v4l2_memory memory) WARN_UNUSED_RESULT; + + // Deallocate all buffers previously allocated by |AllocateBuffers|. Any + // references to buffers previously allocated held by the client must be + // released, or this call will fail. + bool DeallocateBuffers(); + + // Return a unique pointer to a free buffer for the caller to prepare and + // submit, or an empty pointer if no buffer is currently free. + // + // If the caller discards the returned reference, the underlying buffer is + // made available to clients again. + V4L2WritableBufferRef GetFreeBuffer(); + + // Attempt to dequeue a buffer, and return a reference to it if one was + // available. + // + // The first element of the returned pair will be false if an error occurred, + // in which case the second element will be nullptr. If no error occurred, + // then the first element will be true and the second element will contain a + // reference to the dequeued buffer if one was available, or nullptr + // otherwise. + // Dequeued buffers will not be reused by the driver until all references to + // them are dropped. + std::pair<bool, V4L2ReadableBufferRef> DequeueBuffer(); + + // Returns true if this queue is currently streaming. + bool IsStreaming() const; + // If not currently streaming, starts streaming. Returns true if we started + // streaming, or were already streaming, or false if we were not streaming + // and an error occurred when attempting to start the stream. On failure, any + // previously-queued buffers will be dequeued without processing and made + // available to the client, while any buffers held by the client will remain + // unchanged and their ownership will remain with the client. + bool Streamon(); + // If currently streaming, stops streaming. Also make all queued buffers + // available to the client again regardless of the streaming state. + // If an error occurred while attempting to stop streaming, then false is + // returned and queued buffers are left untouched since the V4L2 queue may + // still be using them. + bool Streamoff(); + + // Returns the number of buffers currently allocated for this queue. + size_t AllocatedBuffersCount() const; + // Returns the number of currently free buffers on this queue. + size_t FreeBuffersCount() const; + // Returns the number of buffers currently queued on this queue. + size_t QueuedBuffersCount() const; + + private: + ~V4L2Queue(); + + // Called when clients lose their reference to a buffer. + void ReturnBuffer(size_t buffer_id); + // Called when clients request a buffer to be queued. + bool QueueBuffer(struct v4l2_buffer* v4l2_buffer); + + const enum v4l2_buf_type type_; + enum v4l2_memory memory_ = V4L2_MEMORY_MMAP; + bool is_streaming_ = false; + + std::vector<std::unique_ptr<V4L2Buffer>> buffers_; + + // Buffers that are available for client to get and submit. + // Buffers in this list are not referenced by anyone else than ourselves. + std::set<size_t> free_buffers_; + // Buffers that have been queued by the client, and not dequeued yet. + std::set<size_t> queued_buffers_; + + scoped_refptr<V4L2Device> device_; + // Callback to call in this queue's destructor. + base::OnceClosure destroy_cb_; + + V4L2Queue(scoped_refptr<V4L2Device> dev, + enum v4l2_buf_type type, + base::OnceClosure destroy_cb); + friend class V4L2QueueFactory; + friend class V4L2BufferQueueProxy; + friend class base::RefCountedThreadSafe<V4L2Queue>; + + SEQUENCE_CHECKER(sequence_checker_); + DISALLOW_COPY_AND_ASSIGN(V4L2Queue); +}; + class MEDIA_GPU_EXPORT V4L2Device : public base::RefCountedThreadSafe<V4L2Device> { public: @@ -79,6 +320,10 @@ // The device will be closed in the destructor. virtual bool Open(Type type, uint32_t v4l2_pixfmt) = 0; + // Returns the V4L2Queue corresponding to the requested |type|, or nullptr + // if the requested queue type is not supported. + scoped_refptr<V4L2Queue> GetQueue(enum v4l2_buf_type type); + // Parameters and return value are the same as for the standard ioctl() system // call. virtual int Ioctl(int request, void* arg) = 0; @@ -208,6 +453,13 @@ // Return true on success, false on error or if the particular implementation // is not available. virtual bool Initialize() = 0; + + // Associates a v4l2_buf_type to its queue. + base::flat_map<enum v4l2_buf_type, V4L2Queue*> queues_; + + // Callback that is called upon a queue's destruction, to cleanup its pointer + // in queues_. + void OnQueueDestroyed(v4l2_buf_type buf_type); }; } // namespace media
diff --git a/media/renderers/paint_canvas_video_renderer.cc b/media/renderers/paint_canvas_video_renderer.cc index afbb91f..8d12b5f 100644 --- a/media/renderers/paint_canvas_video_renderer.cc +++ b/media/renderers/paint_canvas_video_renderer.cc
@@ -14,7 +14,6 @@ #include "cc/paint/paint_image.h" #include "cc/paint/paint_image_builder.h" #include "gpu/GLES2/gl2extchromium.h" -#include "gpu/command_buffer/client/context_support.h" #include "gpu/command_buffer/client/gles2_interface.h" #include "gpu/command_buffer/common/capabilities.h" #include "gpu/command_buffer/common/mailbox_holder.h" @@ -276,35 +275,6 @@ } } -void OnQueryDone(scoped_refptr<VideoFrame> video_frame, - gpu::gles2::GLES2Interface* gl, - unsigned query_id) { - gl->DeleteQueriesEXT(1, &query_id); - // |video_frame| is dropped here. -} - -void SynchronizeVideoFrameRead(scoped_refptr<VideoFrame> video_frame, - gpu::gles2::GLES2Interface* gl, - gpu::ContextSupport* context_support) { - DCHECK(gl); - DCHECK(context_support); - - SyncTokenClientImpl client(gl); - video_frame->UpdateReleaseSyncToken(&client); - - if (video_frame->metadata()->IsTrue( - VideoFrameMetadata::READ_LOCK_FENCES_ENABLED)) { - // |video_frame| must be kept alive during read operations. - unsigned query_id = 0; - gl->GenQueriesEXT(1, &query_id); - DCHECK(query_id); - gl->BeginQueryEXT(GL_COMMANDS_COMPLETED_CHROMIUM, query_id); - gl->EndQueryEXT(GL_COMMANDS_COMPLETED_CHROMIUM); - context_support->SignalQuery( - query_id, base::BindOnce(&OnQueryDone, video_frame, gl, query_id)); - } -} - } // anonymous namespace // Generates an RGB image from a VideoFrame. Convert YUV to RGB plain on GPU. @@ -446,8 +416,7 @@ const gfx::RectF& dest_rect, cc::PaintFlags& flags, VideoRotation video_rotation, - const Context3D& context_3d, - gpu::ContextSupport* context_support) { + const Context3D& context_3d) { DCHECK(thread_checker_.CalledOnValidThread()); if (flags.getAlpha() == 0) { return; @@ -540,23 +509,22 @@ canvas->flush(); if (video_frame->HasTextures()) { - // Synchronize |video_frame| with the read operations in UpdateLastImage(), - // which are triggered by canvas->flush(). - SynchronizeVideoFrameRead(video_frame, gl, context_support); + DCHECK(gl); + SyncTokenClientImpl client(gl); + video_frame->UpdateReleaseSyncToken(&client); } } void PaintCanvasVideoRenderer::Copy( const scoped_refptr<VideoFrame>& video_frame, cc::PaintCanvas* canvas, - const Context3D& context_3d, - gpu::ContextSupport* context_support) { + const Context3D& context_3d) { cc::PaintFlags flags; flags.setBlendMode(SkBlendMode::kSrc); flags.setFilterQuality(kLow_SkFilterQuality); Paint(video_frame, canvas, gfx::RectF(gfx::SizeF(video_frame->visible_rect().size())), flags, - media::VIDEO_ROTATION_0, context_3d, context_support); + media::VIDEO_ROTATION_0, context_3d); } namespace { @@ -933,14 +901,14 @@ target, texture, internal_format, format, type, level, premultiply_alpha, flip_y); gl->DeleteTextures(1, &source_texture); - gl->ShallowFlushCHROMIUM(); - // The caller must call SynchronizeVideoFrameRead() after this operation, but - // we can't do that because we don't have the ContextSupport. + gl->Flush(); + + SyncTokenClientImpl client(gl); + video_frame->UpdateReleaseSyncToken(&client); } bool PaintCanvasVideoRenderer::CopyVideoFrameTexturesToGLTexture( const Context3D& context_3d, - gpu::ContextSupport* context_support, gpu::gles2::GLES2Interface* destination_gl, const scoped_refptr<VideoFrame>& video_frame, unsigned int target, @@ -968,11 +936,7 @@ if (!backend_texture.getGLTextureInfo(&texture_info)) return false; - // Synchronize |video_frame| with the read operations in UpdateLastImage(), - // which are triggered by getBackendTexture(). gpu::gles2::GLES2Interface* canvas_gl = context_3d.gl; - SynchronizeVideoFrameRead(video_frame, canvas_gl, context_support); - gpu::MailboxHolder mailbox_holder; mailbox_holder.texture_target = texture_info.fTarget; canvas_gl->ProduceTextureDirectCHROMIUM(texture_info.fID, @@ -1000,30 +964,13 @@ gpu::SyncToken dest_sync_token; destination_gl->GenUnverifiedSyncTokenCHROMIUM(dest_sync_token.GetData()); canvas_gl->WaitSyncTokenCHROMIUM(dest_sync_token.GetConstData()); + + SyncTokenClientImpl client(canvas_gl); + video_frame->UpdateReleaseSyncToken(&client); } else { - gpu::gles2::GLES2Interface* canvas_gl = context_3d.gl; - - // Create a mailbox for the target texture. - gpu::MailboxHolder mailbox_holder; - mailbox_holder.texture_target = target; - destination_gl->ProduceTextureDirectCHROMIUM(texture, - mailbox_holder.mailbox.name); - destination_gl->GenUnverifiedSyncTokenCHROMIUM( - mailbox_holder.sync_token.GetData()); - - // Make the target texture available to |canvas_gl|. - canvas_gl->WaitSyncTokenCHROMIUM(mailbox_holder.sync_token.GetConstData()); - uint32_t intermediate_texture = - canvas_gl->CreateAndConsumeTextureCHROMIUM(mailbox_holder.mailbox.name); - - // Copy the texture contents and discard the intermediate texture. CopyVideoFrameSingleTextureToGLTexture( - canvas_gl, video_frame.get(), target, intermediate_texture, - internal_format, format, type, level, premultiply_alpha, flip_y); - canvas_gl->DeleteTextures(1, &intermediate_texture); - canvas_gl->ShallowFlushCHROMIUM(); - - SynchronizeVideoFrameRead(video_frame, canvas_gl, context_support); + destination_gl, video_frame.get(), target, texture, internal_format, + format, type, level, premultiply_alpha, flip_y); } return true; @@ -1261,9 +1208,8 @@ return false; last_id_ = video_frame->unique_id(); } - - DCHECK(last_image_); last_image_deleting_timer_.Reset(); + DCHECK(!!last_image_); return true; }
diff --git a/media/renderers/paint_canvas_video_renderer.h b/media/renderers/paint_canvas_video_renderer.h index d4752f3..d732111 100644 --- a/media/renderers/paint_canvas_video_renderer.h +++ b/media/renderers/paint_canvas_video_renderer.h
@@ -29,7 +29,6 @@ namespace gpu { struct Capabilities; -class ContextSupport; } namespace media { @@ -40,29 +39,25 @@ PaintCanvasVideoRenderer(); ~PaintCanvasVideoRenderer(); - // Paints |video_frame| translated and scaled to |dest_rect| on |canvas|. - // + // Paints |video_frame| on |canvas|, scaling and rotating the result to fit + // dimensions specified by |dest_rect|. // If the format of |video_frame| is PIXEL_FORMAT_NATIVE_TEXTURE, |context_3d| - // and |context_support| must be provided. + // must be provided. // - // If |video_frame| is nullptr or an unsupported format, |dest_rect| will be - // painted black. + // Black will be painted on |canvas| if |video_frame| is null. void Paint(const scoped_refptr<VideoFrame>& video_frame, cc::PaintCanvas* canvas, const gfx::RectF& dest_rect, cc::PaintFlags& flags, VideoRotation video_rotation, - const Context3D& context_3d, - gpu::ContextSupport* context_support); + const Context3D& context_3d); - // Paints |video_frame| scaled to its visible size on |canvas|. - // + // Copy |video_frame| on |canvas|. // If the format of |video_frame| is PIXEL_FORMAT_NATIVE_TEXTURE, |context_3d| - // and |context_support| must be provided. + // must be provided. void Copy(const scoped_refptr<VideoFrame>& video_frame, cc::PaintCanvas* canvas, - const Context3D& context_3d, - gpu::ContextSupport* context_support); + const Context3D& context_3d); // Convert the contents of |video_frame| to raw RGB pixels. |rgb_pixels| // should point into a buffer large enough to hold as many 32 bit RGBA pixels @@ -87,12 +82,15 @@ bool premultiply_alpha, bool flip_y); - // Copy the contents of |video_frame| to |texture| of |destination_gl|. - // + // Copy the contents of texture of |video_frame| to texture |texture| in + // context |destination_gl|. + // |level|, |internal_format|, |type| specify target texture |texture|. // The format of |video_frame| must be VideoFrame::NATIVE_TEXTURE. + // |context_3d| has a GrContext that may be used during the copy. + // CorrectLastImageDimensions() ensures that the source texture will be + // cropped to |visible_rect|. Returns true on success. bool CopyVideoFrameTexturesToGLTexture( const Context3D& context_3d, - gpu::ContextSupport* context_support, gpu::gles2::GLES2Interface* destination_gl, const scoped_refptr<VideoFrame>& video_frame, unsigned int target, @@ -170,6 +168,8 @@ // never be painted again, so we can release the resource. void ResetCache(); + void CorrectLastImageDimensions(const SkIRect& visible_rect); + // Used for unit test. SkISize LastImageDimensionsForTesting(); @@ -179,8 +179,6 @@ bool UpdateLastImage(const scoped_refptr<VideoFrame>& video_frame, const Context3D& context_3d); - void CorrectLastImageDimensions(const SkIRect& visible_rect); - // Last image used to draw to the canvas. cc::PaintImage last_image_;
diff --git a/media/renderers/paint_canvas_video_renderer_unittest.cc b/media/renderers/paint_canvas_video_renderer_unittest.cc index bd321305..3bca993 100644 --- a/media/renderers/paint_canvas_video_renderer_unittest.cc +++ b/media/renderers/paint_canvas_video_renderer_unittest.cc
@@ -225,7 +225,7 @@ cc::PaintFlags flags; flags.setFilterQuality(kLow_SkFilterQuality); renderer_.Paint(nullptr, canvas, kNaturalRect, flags, VIDEO_ROTATION_0, - Context3D(), nullptr); + Context3D()); } void PaintCanvasVideoRendererTest::Paint( @@ -260,13 +260,13 @@ flags.setBlendMode(mode); flags.setFilterQuality(kLow_SkFilterQuality); renderer_.Paint(video_frame, canvas, dest_rect, flags, video_rotation, - Context3D(), nullptr); + Context3D()); } void PaintCanvasVideoRendererTest::Copy( const scoped_refptr<VideoFrame>& video_frame, cc::PaintCanvas* canvas) { - renderer_.Copy(video_frame, canvas, Context3D(), nullptr); + renderer_.Copy(video_frame, canvas, Context3D()); } TEST_F(PaintCanvasVideoRendererTest, NoFrame) { @@ -564,7 +564,7 @@ flags.setFilterQuality(kNone_SkFilterQuality); renderer_.Paint(video_frame, &canvas, gfx::RectF(bitmap.width(), bitmap.height()), flags, - VIDEO_ROTATION_0, Context3D(), nullptr); + VIDEO_ROTATION_0, Context3D()); for (int j = 0; j < bitmap.height(); j++) { for (int i = 0; i < bitmap.width(); i++) { const int value = i + j * bitmap.width(); @@ -657,32 +657,43 @@ cc::PaintFlags flags; flags.setFilterQuality(kLow_SkFilterQuality); renderer_.Paint(video_frame, &canvas, kNaturalRect, flags, VIDEO_ROTATION_90, - context_3d, nullptr); + context_3d); } void EmptyCallback(const gpu::SyncToken& sync_token) {} TEST_F(PaintCanvasVideoRendererTest, CorrectFrameSizeToVisibleRect) { - constexpr int fWidth{16}, fHeight{16}; + int fWidth{16}, fHeight{16}; SkImageInfo imInfo = SkImageInfo::MakeN32(fWidth, fHeight, kOpaque_SkAlphaType); - cc::SkiaPaintCanvas canvas(AllocBitmap(kWidth, kHeight)); + sk_sp<const GrGLInterface> glInterface(GrGLCreateNullInterface()); + sk_sp<GrContext> grContext = GrContext::MakeGL(std::move(glInterface)); + sk_sp<SkSurface> surface = + SkSurface::MakeRenderTarget(grContext.get(), SkBudgeted::kYes, imInfo); + cc::SkiaPaintCanvas canvas(surface->getCanvas()); + + TestGLES2Interface gles2; + Context3D context_3d(&gles2, grContext.get()); gfx::Size coded_size(fWidth, fHeight); gfx::Size visible_size(fWidth / 2, fHeight / 2); - uint8_t memory[fWidth * fHeight * 2] = {0}; + gpu::MailboxHolder mailbox_holders[VideoFrame::kMaxPlanes]; + for (size_t i = 0; i < VideoFrame::kMaxPlanes; i++) { + mailbox_holders[i] = gpu::MailboxHolder( + gpu::Mailbox::Generate(), gpu::SyncToken(), GL_TEXTURE_RECTANGLE_ARB); + } - auto video_frame = media::VideoFrame::WrapExternalData( - media::PIXEL_FORMAT_Y16, coded_size, gfx::Rect(visible_size), - visible_size, &memory[0], fWidth * fHeight * 2, + auto video_frame = VideoFrame::WrapNativeTextures( + PIXEL_FORMAT_I420, mailbox_holders, base::Bind(EmptyCallback), coded_size, + gfx::Rect(visible_size), visible_size, base::TimeDelta::FromMilliseconds(4)); gfx::RectF visible_rect(visible_size.width(), visible_size.height()); cc::PaintFlags flags; renderer_.Paint(video_frame, &canvas, visible_rect, flags, VIDEO_ROTATION_0, - Context3D(), nullptr); + context_3d); EXPECT_EQ(fWidth / 2, renderer_.LastImageDimensionsForTesting().width()); EXPECT_EQ(fWidth / 2, renderer_.LastImageDimensionsForTesting().height());
diff --git a/media/renderers/video_resource_updater.cc b/media/renderers/video_resource_updater.cc index 5b4abce..952c9a7 100644 --- a/media/renderers/video_resource_updater.cc +++ b/media/renderers/video_resource_updater.cc
@@ -866,7 +866,7 @@ // This is software path, so canvas and video_frame are always backed // by software. - video_renderer_->Copy(video_frame, &canvas, Context3D(), nullptr); + video_renderer_->Copy(video_frame, &canvas, Context3D()); } else { HardwarePlaneResource* hardware_resource = plane_resource->AsHardware(); size_t bytes_per_row = viz::ResourceSizes::CheckedWidthInBytes<size_t>(
diff --git a/services/audio/output_controller.cc b/services/audio/output_controller.cc index 420ecfda..00e503a 100644 --- a/services/audio/output_controller.cc +++ b/services/audio/output_controller.cc
@@ -12,14 +12,12 @@ #include "base/bind_helpers.h" #include "base/compiler_specific.h" #include "base/metrics/histogram_macros.h" -#include "base/metrics/persistent_histogram_allocator.h" #include "base/numerics/safe_conversions.h" #include "base/stl_util.h" #include "base/strings/stringprintf.h" #include "base/task_runner_util.h" #include "base/threading/platform_thread.h" #include "base/trace_event/trace_event.h" -#include "build/build_config.h" #include "media/base/audio_timestamp_helper.h" #include "services/audio/stream_monitor.h" @@ -45,10 +43,6 @@ void LogStreamCreationResult(bool for_device_change, StreamCreationResult result) { -#if defined(OS_WIN) - // TODO(https://crbug.com/867827) remove histogram allocator check. - CHECK(base::GlobalHistogramAllocator::Get()); -#endif if (for_device_change) { UMA_HISTOGRAM_ENUMERATION( "Media.AudioOutputController.ProxyStreamCreationResultForDeviceChange", @@ -97,10 +91,6 @@ } OutputController::ErrorStatisticsTracker::~ErrorStatisticsTracker() { -#if defined(OS_WIN) - // TODO(https://crbug.com/867827) remove histogram allocator check. - CHECK(base::GlobalHistogramAllocator::Get()); -#endif UMA_HISTOGRAM_LONG_TIMES("Media.OutputStreamDuration", base::TimeTicks::Now() - start_time_); UMA_HISTOGRAM_BOOLEAN("Media.AudioOutputController.CallbackError", @@ -166,10 +156,6 @@ } bool OutputController::Create(bool is_for_device_change) { -#if defined(OS_WIN) - // TODO(https://crbug.com/867827) remove histogram allocator check. - CHECK(base::GlobalHistogramAllocator::Get()); -#endif DCHECK(task_runner_->BelongsToCurrentThread()); SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioOutputController.CreateTime"); TRACE_EVENT0("audio", "OutputController::Create"); @@ -240,10 +226,6 @@ } void OutputController::Play() { -#if defined(OS_WIN) - // TODO(https://crbug.com/867827) remove histogram allocator check. - CHECK(base::GlobalHistogramAllocator::Get()); -#endif DCHECK(task_runner_->BelongsToCurrentThread()); SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioOutputController.PlayTime"); TRACE_EVENT0("audio", "OutputController::Play"); @@ -289,10 +271,6 @@ } void OutputController::Pause() { -#if defined(OS_WIN) - // TODO(https://crbug.com/867827) remove histogram allocator check. - CHECK(base::GlobalHistogramAllocator::Get()); -#endif DCHECK(task_runner_->BelongsToCurrentThread()); SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioOutputController.PauseTime"); TRACE_EVENT0("audio", "OutputController::Pause"); @@ -312,10 +290,6 @@ } void OutputController::Close() { -#if defined(OS_WIN) - // TODO(https://crbug.com/867827) remove histogram allocator check. - CHECK(base::GlobalHistogramAllocator::Get()); -#endif DCHECK(task_runner_->BelongsToCurrentThread()); SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioOutputController.CloseTime"); TRACE_EVENT0("audio", "OutputController::Close"); @@ -567,10 +541,6 @@ } void OutputController::OnDeviceChange() { -#if defined(OS_WIN) - // TODO(https://crbug.com/867827) remove histogram allocator check. - CHECK(base::GlobalHistogramAllocator::Get()); -#endif DCHECK(task_runner_->BelongsToCurrentThread()); SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioOutputController.DeviceChangeTime"); TRACE_EVENT0("audio", "OutputController::OnDeviceChange");
diff --git a/services/audio/output_controller_unittest.cc b/services/audio/output_controller_unittest.cc index 51786f91..8b0ffee 100644 --- a/services/audio/output_controller_unittest.cc +++ b/services/audio/output_controller_unittest.cc
@@ -18,7 +18,6 @@ #include "base/logging.h" #include "base/macros.h" #include "base/memory/ref_counted.h" -#include "base/metrics/persistent_histogram_allocator.h" #include "base/optional.h" #include "base/run_loop.h" #include "base/single_thread_task_runner.h" @@ -27,7 +26,6 @@ #include "base/threading/thread.h" #include "base/time/time.h" #include "base/unguessable_token.h" -#include "build/build_config.h" #include "media/audio/audio_device_description.h" #include "media/audio/fake_audio_log_factory.h" #include "media/audio/fake_audio_manager.h" @@ -39,13 +37,13 @@ #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +using ::testing::_; using ::testing::AtLeast; using ::testing::Invoke; using ::testing::Mock; using ::testing::NiceMock; using ::testing::Return; using ::testing::StrictMock; -using ::testing::_; using media::AudioBus; using media::AudioManager; @@ -332,15 +330,6 @@ std::string(), &mock_sync_reader_, &stream_monitor_coordinator_, processing_id_); controller_->SetVolume(kTestVolume); -#if defined(OS_WIN) - // TODO(https://crbug.com/867827) remove histogram allocator creation when - // removing output controller checks. - if (!base::GlobalHistogramAllocator::Get()) { - const int32_t kAllocatorMemorySize = 8 << 20; - base::GlobalHistogramAllocator::CreateWithLocalMemory( - kAllocatorMemorySize, 0, "HistogramAllocatorTest"); - } -#endif } void TearDown() override { controller_ = base::nullopt; }
diff --git a/services/audio/output_stream_unittest.cc b/services/audio/output_stream_unittest.cc index 191e7c70..f5348fd1 100644 --- a/services/audio/output_stream_unittest.cc +++ b/services/audio/output_stream_unittest.cc
@@ -6,11 +6,9 @@ #include <utility> -#include "base/metrics/persistent_histogram_allocator.h" #include "base/test/mock_callback.h" #include "base/test/scoped_task_environment.h" #include "base/unguessable_token.h" -#include "build/build_config.h" #include "media/audio/audio_io.h" #include "media/audio/mock_audio_manager.h" #include "media/audio/test_audio_thread.h" @@ -118,15 +116,6 @@ stream_factory_binding_(&stream_factory_, mojo::MakeRequest(&stream_factory_ptr_)) { mojo::core::SetDefaultProcessErrorCallback(bad_message_callback_.Get()); -#if defined(OS_WIN) - // TODO(https://crbug.com/867827) remove histogram allocator creation when - // removing output controller checks. - if (!base::GlobalHistogramAllocator::Get()) { - const int32_t kAllocatorMemorySize = 8 << 20; - base::GlobalHistogramAllocator::CreateWithLocalMemory( - kAllocatorMemorySize, 0, "HistogramAllocatorTest"); - } -#endif } ~TestEnvironment() {
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json index 7fe9e730..cfc72399 100644 --- a/testing/buildbot/chromium.fyi.json +++ b/testing/buildbot/chromium.fyi.json
@@ -1604,6 +1604,17 @@ }, { "args": [ + "--enable-features=SingleProcessMash", + "--test-launcher-filter-file=../../testing/buildbot/filters/chromeos.single_process_mash.interactive_ui_tests.filter" + ], + "name": "single_process_mash_interactive_ui_tests", + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "interactive_ui_tests" + }, + { + "args": [ "--enable-features=VizDisplayCompositor" ], "name": "viz_interactive_ui_tests",
diff --git a/testing/buildbot/chromium.webrtc.fyi.experimental.json b/testing/buildbot/chromium.webrtc.fyi.experimental.json deleted file mode 100644 index 4951a90d..0000000 --- a/testing/buildbot/chromium.webrtc.fyi.experimental.json +++ /dev/null
@@ -1,655 +0,0 @@ -{ - "AAAAA1 AUTOGENERATED FILE DO NOT EDIT": {}, - "AAAAA2 See generate_buildbot_json.py to make changes": {}, - "WebRTC Chromium FYI Android Builder": { - "additional_compile_targets": [ - "browser_tests", - "capture_unittests", - "content_browsertests", - "content_unittests", - "jingle_unittests", - "remoting_unittests" - ] - }, - "WebRTC Chromium FYI Android Builder (dbg)": {}, - "WebRTC Chromium FYI Android Builder ARM64 (dbg)": {}, - "WebRTC Chromium FYI Android Tests (dbg) (K Nexus5)": { - "gtest_tests": [ - { - "args": [ - "--gtest_filter=WebRtc*" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "device_os": "K", - "device_type": "hammerhead", - "os": "Android" - } - ] - }, - "test": "content_browsertests" - } - ] - }, - "WebRTC Chromium FYI Android Tests (dbg) (M Nexus5X)": { - "gtest_tests": [ - { - "args": [ - "--gtest_filter=WebRtc*" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "device_os": "MMB29Q", - "device_type": "bullhead", - "os": "Android" - } - ] - }, - "test": "content_browsertests" - } - ] - }, - "WebRTC Chromium FYI Linux Builder": { - "additional_compile_targets": [ - "frame_analyzer", - "remoting/webapp:webapp" - ] - }, - "WebRTC Chromium FYI Linux Builder (dbg)": { - "additional_compile_targets": [ - "browser_tests", - "capture_unittests", - "content_browsertests", - "content_unittests", - "frame_analyzer", - "jingle_unittests", - "remoting_unittests", - "remoting/webapp:webapp" - ] - }, - "WebRTC Chromium FYI Linux Tester": { - "gtest_tests": [ - { - "args": [ - "--gtest_filter=WebRtcApprtcBrowserTest.*", - "--run-manual", - "--test-launcher-jobs=1" - ], - "name": "browser_tests_apprtc", - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "browser_tests" - }, - { - "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/webrtc_functional.browser_tests.filter", - "--run-manual", - "--test-launcher-jobs=1" - ], - "name": "browser_tests_functional", - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Ubuntu-14.04" - } - ] - }, - "test": "browser_tests" - }, - { - "args": [ - "--gtest_filter=WebRtc*" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Ubuntu-14.04" - } - ] - }, - "test": "content_browsertests" - }, - { - "args": [ - "--gtest_filter=WebRtc*MANUAL*:-UsingRealWebcam*", - "--run-manual", - "--ui-test-action-max-timeout=120000" - ], - "name": "content_browsertests_stress", - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Ubuntu-14.04" - } - ] - }, - "test": "content_browsertests" - }, - { - "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/webrtc.content_unittests.filter" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Ubuntu-14.04" - } - ] - }, - "test": "content_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Ubuntu-14.04" - } - ] - }, - "test": "jingle_unittests" - }, - { - "args": [ - "--gtest_filter=Webrtc*" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Ubuntu-14.04" - } - ] - }, - "test": "remoting_unittests" - } - ] - }, - "WebRTC Chromium FYI Mac Builder": { - "additional_compile_targets": [ - "frame_analyzer", - "remoting/webapp:webapp" - ] - }, - "WebRTC Chromium FYI Mac Builder (dbg)": { - "additional_compile_targets": [ - "browser_tests", - "capture_unittests", - "content_browsertests", - "content_unittests", - "frame_analyzer", - "jingle_unittests", - "remoting_unittests", - "remoting/webapp:webapp" - ] - }, - "WebRTC Chromium FYI Mac Tester": { - "gtest_tests": [ - { - "args": [ - "--gtest_filter=WebRtcApprtcBrowserTest.*", - "--run-manual", - "--test-launcher-jobs=1" - ], - "name": "browser_tests_apprtc", - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "browser_tests" - }, - { - "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/webrtc_functional.browser_tests.filter", - "--run-manual", - "--test-launcher-jobs=1" - ], - "name": "browser_tests_functional", - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "8086:0a2e", - "os": "Mac-10.12.6" - } - ] - }, - "test": "browser_tests" - }, - { - "args": [ - "--gtest_filter=WebRtc*" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "8086:0a2e", - "os": "Mac-10.12.6" - } - ] - }, - "test": "content_browsertests" - }, - { - "args": [ - "--gtest_filter=WebRtc*MANUAL*:-UsingRealWebcam*", - "--run-manual", - "--ui-test-action-max-timeout=120000" - ], - "name": "content_browsertests_stress", - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "8086:0a2e", - "os": "Mac-10.12.6" - } - ] - }, - "test": "content_browsertests" - }, - { - "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/webrtc.content_unittests.filter" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "8086:0a2e", - "os": "Mac-10.12.6" - } - ] - }, - "test": "content_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "8086:0a2e", - "os": "Mac-10.12.6" - } - ] - }, - "test": "jingle_unittests" - }, - { - "args": [ - "--gtest_filter=Webrtc*" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "8086:0a2e", - "os": "Mac-10.12.6" - } - ] - }, - "test": "remoting_unittests" - } - ] - }, - "WebRTC Chromium FYI Win Builder": { - "additional_compile_targets": [ - "frame_analyzer", - "remoting/webapp:webapp" - ] - }, - "WebRTC Chromium FYI Win Builder (dbg)": { - "additional_compile_targets": [ - "browser_tests", - "capture_unittests", - "content_browsertests", - "content_unittests", - "frame_analyzer", - "jingle_unittests", - "remoting_unittests", - "remoting/webapp:webapp" - ] - }, - "WebRTC Chromium FYI Win10 Tester": { - "gtest_tests": [ - { - "args": [ - "--gtest_filter=WebRtcApprtcBrowserTest.*", - "--run-manual", - "--test-launcher-jobs=1" - ], - "name": "browser_tests_apprtc", - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "browser_tests" - }, - { - "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/webrtc_functional.browser_tests.filter", - "--run-manual", - "--test-launcher-jobs=1" - ], - "name": "browser_tests_functional", - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-15063" - } - ] - }, - "test": "browser_tests" - }, - { - "args": [ - "--gtest_filter=WebRtc*" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-15063" - } - ] - }, - "test": "content_browsertests" - }, - { - "args": [ - "--gtest_filter=WebRtc*MANUAL*:-UsingRealWebcam*", - "--run-manual", - "--ui-test-action-max-timeout=120000" - ], - "name": "content_browsertests_stress", - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-15063" - } - ] - }, - "test": "content_browsertests" - }, - { - "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/webrtc.content_unittests.filter" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-15063" - } - ] - }, - "test": "content_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-15063" - } - ] - }, - "test": "jingle_unittests" - }, - { - "args": [ - "--gtest_filter=Webrtc*" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-15063" - } - ] - }, - "test": "remoting_unittests" - } - ] - }, - "WebRTC Chromium FYI Win7 Tester": { - "gtest_tests": [ - { - "args": [ - "--gtest_filter=WebRtcApprtcBrowserTest.*", - "--run-manual", - "--test-launcher-jobs=1" - ], - "name": "browser_tests_apprtc", - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "browser_tests" - }, - { - "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/webrtc_functional.browser_tests.filter", - "--run-manual", - "--test-launcher-jobs=1" - ], - "name": "browser_tests_functional", - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-7-SP1" - } - ] - }, - "test": "browser_tests" - }, - { - "args": [ - "--gtest_filter=WebRtc*" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-7-SP1" - } - ] - }, - "test": "content_browsertests" - }, - { - "args": [ - "--gtest_filter=WebRtc*MANUAL*:-UsingRealWebcam*", - "--run-manual", - "--ui-test-action-max-timeout=120000" - ], - "name": "content_browsertests_stress", - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-7-SP1" - } - ] - }, - "test": "content_browsertests" - }, - { - "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/webrtc.content_unittests.filter" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-7-SP1" - } - ] - }, - "test": "content_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-7-SP1" - } - ] - }, - "test": "jingle_unittests" - }, - { - "args": [ - "--gtest_filter=Webrtc*" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-7-SP1" - } - ] - }, - "test": "remoting_unittests" - } - ] - }, - "WebRTC Chromium FYI Win8 Tester": { - "gtest_tests": [ - { - "args": [ - "--gtest_filter=WebRtcApprtcBrowserTest.*", - "--run-manual", - "--test-launcher-jobs=1" - ], - "name": "browser_tests_apprtc", - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "browser_tests" - }, - { - "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/webrtc_functional.browser_tests.filter", - "--run-manual", - "--test-launcher-jobs=1" - ], - "name": "browser_tests_functional", - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-8.1-SP0" - } - ] - }, - "test": "browser_tests" - }, - { - "args": [ - "--gtest_filter=WebRtc*" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-8.1-SP0" - } - ] - }, - "test": "content_browsertests" - }, - { - "args": [ - "--gtest_filter=WebRtc*MANUAL*:-UsingRealWebcam*", - "--run-manual", - "--ui-test-action-max-timeout=120000" - ], - "name": "content_browsertests_stress", - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-8.1-SP0" - } - ] - }, - "test": "content_browsertests" - }, - { - "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/webrtc.content_unittests.filter" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-8.1-SP0" - } - ] - }, - "test": "content_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-8.1-SP0" - } - ] - }, - "test": "jingle_unittests" - }, - { - "args": [ - "--gtest_filter=Webrtc*" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-8.1-SP0" - } - ] - }, - "test": "remoting_unittests" - } - ] - } -}
diff --git a/testing/buildbot/chromium.webrtc.fyi.json b/testing/buildbot/chromium.webrtc.fyi.json index fc9268f..4951a90d 100644 --- a/testing/buildbot/chromium.webrtc.fyi.json +++ b/testing/buildbot/chromium.webrtc.fyi.json
@@ -1,7 +1,7 @@ { "AAAAA1 AUTOGENERATED FILE DO NOT EDIT": {}, "AAAAA2 See generate_buildbot_json.py to make changes": {}, - "Android Builder": { + "WebRTC Chromium FYI Android Builder": { "additional_compile_targets": [ "browser_tests", "capture_unittests", @@ -11,27 +11,55 @@ "remoting_unittests" ] }, - "Android Builder (dbg)": { - "additional_compile_targets": [ - "browser_tests", - "capture_unittests", - "content_browsertests", - "content_unittests", - "jingle_unittests", - "remoting_unittests" + "WebRTC Chromium FYI Android Builder (dbg)": {}, + "WebRTC Chromium FYI Android Builder ARM64 (dbg)": {}, + "WebRTC Chromium FYI Android Tests (dbg) (K Nexus5)": { + "gtest_tests": [ + { + "args": [ + "--gtest_filter=WebRtc*" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "device_os": "K", + "device_type": "hammerhead", + "os": "Android" + } + ] + }, + "test": "content_browsertests" + } ] }, - "Android Builder ARM64 (dbg)": { - "additional_compile_targets": [ - "browser_tests", - "capture_unittests", - "content_browsertests", - "content_unittests", - "jingle_unittests", - "remoting_unittests" + "WebRTC Chromium FYI Android Tests (dbg) (M Nexus5X)": { + "gtest_tests": [ + { + "args": [ + "--gtest_filter=WebRtc*" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_type": "bullhead", + "os": "Android" + } + ] + }, + "test": "content_browsertests" + } ] }, - "Linux Builder": { + "WebRTC Chromium FYI Linux Builder": { + "additional_compile_targets": [ + "frame_analyzer", + "remoting/webapp:webapp" + ] + }, + "WebRTC Chromium FYI Linux Builder (dbg)": { "additional_compile_targets": [ "browser_tests", "capture_unittests", @@ -43,7 +71,122 @@ "remoting/webapp:webapp" ] }, - "Linux Builder (dbg)": { + "WebRTC Chromium FYI Linux Tester": { + "gtest_tests": [ + { + "args": [ + "--gtest_filter=WebRtcApprtcBrowserTest.*", + "--run-manual", + "--test-launcher-jobs=1" + ], + "name": "browser_tests_apprtc", + "swarming": { + "can_use_on_swarming_builders": false + }, + "test": "browser_tests" + }, + { + "args": [ + "--test-launcher-filter-file=../../testing/buildbot/filters/webrtc_functional.browser_tests.filter", + "--run-manual", + "--test-launcher-jobs=1" + ], + "name": "browser_tests_functional", + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Ubuntu-14.04" + } + ] + }, + "test": "browser_tests" + }, + { + "args": [ + "--gtest_filter=WebRtc*" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Ubuntu-14.04" + } + ] + }, + "test": "content_browsertests" + }, + { + "args": [ + "--gtest_filter=WebRtc*MANUAL*:-UsingRealWebcam*", + "--run-manual", + "--ui-test-action-max-timeout=120000" + ], + "name": "content_browsertests_stress", + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Ubuntu-14.04" + } + ] + }, + "test": "content_browsertests" + }, + { + "args": [ + "--test-launcher-filter-file=../../testing/buildbot/filters/webrtc.content_unittests.filter" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Ubuntu-14.04" + } + ] + }, + "test": "content_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Ubuntu-14.04" + } + ] + }, + "test": "jingle_unittests" + }, + { + "args": [ + "--gtest_filter=Webrtc*" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Ubuntu-14.04" + } + ] + }, + "test": "remoting_unittests" + } + ] + }, + "WebRTC Chromium FYI Mac Builder": { + "additional_compile_targets": [ + "frame_analyzer", + "remoting/webapp:webapp" + ] + }, + "WebRTC Chromium FYI Mac Builder (dbg)": { "additional_compile_targets": [ "browser_tests", "capture_unittests", @@ -55,18 +198,122 @@ "remoting/webapp:webapp" ] }, - "Mac Builder": { - "additional_compile_targets": [ - "browser_tests", - "capture_unittests", - "content_browsertests", - "content_unittests", - "frame_analyzer", - "jingle_unittests", - "remoting_unittests" + "WebRTC Chromium FYI Mac Tester": { + "gtest_tests": [ + { + "args": [ + "--gtest_filter=WebRtcApprtcBrowserTest.*", + "--run-manual", + "--test-launcher-jobs=1" + ], + "name": "browser_tests_apprtc", + "swarming": { + "can_use_on_swarming_builders": false + }, + "test": "browser_tests" + }, + { + "args": [ + "--test-launcher-filter-file=../../testing/buildbot/filters/webrtc_functional.browser_tests.filter", + "--run-manual", + "--test-launcher-jobs=1" + ], + "name": "browser_tests_functional", + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a2e", + "os": "Mac-10.12.6" + } + ] + }, + "test": "browser_tests" + }, + { + "args": [ + "--gtest_filter=WebRtc*" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a2e", + "os": "Mac-10.12.6" + } + ] + }, + "test": "content_browsertests" + }, + { + "args": [ + "--gtest_filter=WebRtc*MANUAL*:-UsingRealWebcam*", + "--run-manual", + "--ui-test-action-max-timeout=120000" + ], + "name": "content_browsertests_stress", + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a2e", + "os": "Mac-10.12.6" + } + ] + }, + "test": "content_browsertests" + }, + { + "args": [ + "--test-launcher-filter-file=../../testing/buildbot/filters/webrtc.content_unittests.filter" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a2e", + "os": "Mac-10.12.6" + } + ] + }, + "test": "content_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a2e", + "os": "Mac-10.12.6" + } + ] + }, + "test": "jingle_unittests" + }, + { + "args": [ + "--gtest_filter=Webrtc*" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a2e", + "os": "Mac-10.12.6" + } + ] + }, + "test": "remoting_unittests" + } ] }, - "Mac Builder (dbg)": { + "WebRTC Chromium FYI Win Builder": { + "additional_compile_targets": [ + "frame_analyzer", + "remoting/webapp:webapp" + ] + }, + "WebRTC Chromium FYI Win Builder (dbg)": { "additional_compile_targets": [ "browser_tests", "capture_unittests", @@ -78,28 +325,331 @@ "remoting/webapp:webapp" ] }, - "Win Builder": { - "additional_compile_targets": [ - "browser_tests", - "capture_unittests", - "content_browsertests", - "content_unittests", - "frame_analyzer", - "jingle_unittests", - "remoting_unittests", - "remoting/webapp:webapp" + "WebRTC Chromium FYI Win10 Tester": { + "gtest_tests": [ + { + "args": [ + "--gtest_filter=WebRtcApprtcBrowserTest.*", + "--run-manual", + "--test-launcher-jobs=1" + ], + "name": "browser_tests_apprtc", + "swarming": { + "can_use_on_swarming_builders": false + }, + "test": "browser_tests" + }, + { + "args": [ + "--test-launcher-filter-file=../../testing/buildbot/filters/webrtc_functional.browser_tests.filter", + "--run-manual", + "--test-launcher-jobs=1" + ], + "name": "browser_tests_functional", + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Windows-10-15063" + } + ] + }, + "test": "browser_tests" + }, + { + "args": [ + "--gtest_filter=WebRtc*" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Windows-10-15063" + } + ] + }, + "test": "content_browsertests" + }, + { + "args": [ + "--gtest_filter=WebRtc*MANUAL*:-UsingRealWebcam*", + "--run-manual", + "--ui-test-action-max-timeout=120000" + ], + "name": "content_browsertests_stress", + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Windows-10-15063" + } + ] + }, + "test": "content_browsertests" + }, + { + "args": [ + "--test-launcher-filter-file=../../testing/buildbot/filters/webrtc.content_unittests.filter" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Windows-10-15063" + } + ] + }, + "test": "content_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Windows-10-15063" + } + ] + }, + "test": "jingle_unittests" + }, + { + "args": [ + "--gtest_filter=Webrtc*" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Windows-10-15063" + } + ] + }, + "test": "remoting_unittests" + } ] }, - "Win Builder (dbg)": { - "additional_compile_targets": [ - "browser_tests", - "capture_unittests", - "content_browsertests", - "content_unittests", - "frame_analyzer", - "jingle_unittests", - "remoting_unittests", - "remoting/webapp:webapp" + "WebRTC Chromium FYI Win7 Tester": { + "gtest_tests": [ + { + "args": [ + "--gtest_filter=WebRtcApprtcBrowserTest.*", + "--run-manual", + "--test-launcher-jobs=1" + ], + "name": "browser_tests_apprtc", + "swarming": { + "can_use_on_swarming_builders": false + }, + "test": "browser_tests" + }, + { + "args": [ + "--test-launcher-filter-file=../../testing/buildbot/filters/webrtc_functional.browser_tests.filter", + "--run-manual", + "--test-launcher-jobs=1" + ], + "name": "browser_tests_functional", + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Windows-7-SP1" + } + ] + }, + "test": "browser_tests" + }, + { + "args": [ + "--gtest_filter=WebRtc*" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Windows-7-SP1" + } + ] + }, + "test": "content_browsertests" + }, + { + "args": [ + "--gtest_filter=WebRtc*MANUAL*:-UsingRealWebcam*", + "--run-manual", + "--ui-test-action-max-timeout=120000" + ], + "name": "content_browsertests_stress", + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Windows-7-SP1" + } + ] + }, + "test": "content_browsertests" + }, + { + "args": [ + "--test-launcher-filter-file=../../testing/buildbot/filters/webrtc.content_unittests.filter" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Windows-7-SP1" + } + ] + }, + "test": "content_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Windows-7-SP1" + } + ] + }, + "test": "jingle_unittests" + }, + { + "args": [ + "--gtest_filter=Webrtc*" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Windows-7-SP1" + } + ] + }, + "test": "remoting_unittests" + } + ] + }, + "WebRTC Chromium FYI Win8 Tester": { + "gtest_tests": [ + { + "args": [ + "--gtest_filter=WebRtcApprtcBrowserTest.*", + "--run-manual", + "--test-launcher-jobs=1" + ], + "name": "browser_tests_apprtc", + "swarming": { + "can_use_on_swarming_builders": false + }, + "test": "browser_tests" + }, + { + "args": [ + "--test-launcher-filter-file=../../testing/buildbot/filters/webrtc_functional.browser_tests.filter", + "--run-manual", + "--test-launcher-jobs=1" + ], + "name": "browser_tests_functional", + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Windows-8.1-SP0" + } + ] + }, + "test": "browser_tests" + }, + { + "args": [ + "--gtest_filter=WebRtc*" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Windows-8.1-SP0" + } + ] + }, + "test": "content_browsertests" + }, + { + "args": [ + "--gtest_filter=WebRtc*MANUAL*:-UsingRealWebcam*", + "--run-manual", + "--ui-test-action-max-timeout=120000" + ], + "name": "content_browsertests_stress", + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Windows-8.1-SP0" + } + ] + }, + "test": "content_browsertests" + }, + { + "args": [ + "--test-launcher-filter-file=../../testing/buildbot/filters/webrtc.content_unittests.filter" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Windows-8.1-SP0" + } + ] + }, + "test": "content_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Windows-8.1-SP0" + } + ] + }, + "test": "jingle_unittests" + }, + { + "args": [ + "--gtest_filter=Webrtc*" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Windows-8.1-SP0" + } + ] + }, + "test": "remoting_unittests" + } ] } }
diff --git a/testing/buildbot/filters/BUILD.gn b/testing/buildbot/filters/BUILD.gn index b51942c..f0770e2 100644 --- a/testing/buildbot/filters/BUILD.gn +++ b/testing/buildbot/filters/BUILD.gn
@@ -87,6 +87,7 @@ testonly = true data = [ + "//testing/buildbot/filters/chromeos.single_process_mash.interactive_ui_tests.filter", "//testing/buildbot/filters/webui_polymer2_interactive_ui_tests.filter", ] }
diff --git a/testing/buildbot/filters/chromeos.single_process_mash.interactive_ui_tests.filter b/testing/buildbot/filters/chromeos.single_process_mash.interactive_ui_tests.filter new file mode 100644 index 0000000..9231452 --- /dev/null +++ b/testing/buildbot/filters/chromeos.single_process_mash.interactive_ui_tests.filter
@@ -0,0 +1,91 @@ +# These tests currently fail with SingleProcessMash enabled. +# Bug: crbug.com/883523 + +# Keyboard event related. See crbug.com/889101 +-BrowserCommandControllerInteractiveTest.KeyEventsShouldBeConsumedByWebPageInBrowserFullscreen +-BrowserCommandControllerInteractiveTest.KeyEventsShouldBeConsumedByWebPageInJsFullscreenExceptForEsc +-BrowserCommandControllerInteractiveTest.KeyEventsShouldBeConsumedByWebPageInJsFullscreenExceptForF11 +-BrowserCommandControllerInteractiveTest.ShortcutsShouldTakeEffectInBrowserFullscreen +-BrowserKeyEventsTest.CtrlKeyEvents +-BrowserKeyEventsTest.NormalKeyEvents +-KeyboardLockInteractiveBrowserTest.ActiveWithAllKeysLocked +-KeyboardLockInteractiveBrowserTest.ActiveWithSomeKeysLocked +-KeyboardLockInteractiveBrowserTest.CancelActiveKeyboardLockInFullscreen +-KeyboardLockInteractiveBrowserTest.RequestedButNotActive +-KeyboardLockInteractiveBrowserTest.SubsequentLockCallSupersedesPreviousCall +-SitePerProcessTextInputManagerTest.CorrectlyShowVirtualKeyboardIfEnabled +-TextInput_SurroundingTextChangedTest.FocusToTextContainingTextAreaByClickingCase +-TextInput_SurroundingTextChangedTest.SurroundingTextChangedWithComposition +-TextInput_SurroundingTextChangedTest.SurroundingTextChangedWithInsertText + +# misc. +-DevToolsManagerDelegateTest.ShowMinimizedWindow +-OmniboxViewViewsTest.DeactivateTouchEditingOnExecuteCommand +-OmniboxViewViewsTest.SelectAllOnTap +-WindowActivityWatcherTest.Basic +-WindowActivityWatcherTest.MultipleWindows +-WindowActivityWatcherTest.WindowActivation + +# Broken tests related to accessibility. crbug.com/888750 and crbug.com/889093 +-GuestSpokenFeedbackTest.FocusToolbar +-SelectToSpeakTest.ActivatesWithTapOnSelectToSpeakTray +-SelectToSpeakTest.BreaksAtParagraphBounds +-SelectToSpeakTest.ContinuesReadingDuringResize +-SelectToSpeakTest.FocusRingMovesWithMouse +-SelectToSpeakTest.ReadsStaticTextWithoutInlineTextChildren +-SelectToSpeakTest.SelectToSpeakTrayNotSpoken +-SelectToSpeakTest.SmoothlyReadsAcrossFormattedText +-SelectToSpeakTest.SmoothlyReadsAcrossInlineUrl +-SelectToSpeakTest.SmoothlyReadsAcrossMultipleLines +-SelectToSpeakTest.SpeakStatusTray +-SelectToSpeakTest.WorksWithStickyKeys +-StickyKeysBrowserTest.CtrlClickHomeButton +-StickyKeysBrowserTest.OpenNewTabs +-StickyKeysBrowserTest.OpenTrayMenu +-StickyKeysBrowserTest.OverlayShown +-StickyKeysBrowserTest.SearchLeftOmnibox +-TestAsNormalAndGuestUser/SpokenFeedbackTest.ChromeVoxNextTabRecovery/0 +-TestAsNormalAndGuestUser/SpokenFeedbackTest.ChromeVoxNextTabRecovery/1 +-TestAsNormalAndGuestUser/SpokenFeedbackTest.ChromeVoxShiftSearch/0 +-TestAsNormalAndGuestUser/SpokenFeedbackTest.ChromeVoxShiftSearch/1 +-TestAsNormalAndGuestUser/SpokenFeedbackTest.FocusToolbar/0 +-TestAsNormalAndGuestUser/SpokenFeedbackTest.FocusToolbar/1 +-TestAsNormalAndGuestUser/SpokenFeedbackTest.OpenStatusTray/0 +-TestAsNormalAndGuestUser/SpokenFeedbackTest.OpenStatusTray/1 + +# TabDragging: crbug.com/890071 +-DetachToBrowserInSeparateDisplayAndCancelTabDragControllerTest.CancelDragTabToWindowIn1stDisplay +-TabDragging/DetachToBrowserInSeparateDisplayTabDragControllerTest.DragBrowserWindowWhenMajorityOfBoundsInSecondDisplay/0 +-TabDragging/DetachToBrowserInSeparateDisplayTabDragControllerTest.DragSingleTabToSeparateWindowInSecondDisplay/0 +-TabDragging/DetachToBrowserInSeparateDisplayTabDragControllerTest.DragTabToWindowInSeparateDisplay/0 +-TabDragging/DetachToBrowserInSeparateDisplayTabDragControllerTest.DragTabToWindowOnSecondDisplay/0 +-TabDragging/DetachToBrowserTabDragControllerTest.DeferredTargetTabStripTest/1 +-TabDragging/DetachToBrowserTabDragControllerTest.DetachToOwnWindowFromMaximizedWindow/1 +-TabDragging/DetachToBrowserTabDragControllerTest.DetachToOwnWindowWhileInImmersiveFullscreenMode/1 +-TabDragging/DetachToBrowserTabDragControllerTest.DoNotAttachToOtherWindowTest/1 +-TabDragging/DetachToBrowserTabDragControllerTest.DoNotObserveDraggedWidgetAfterDragEnds/1 +-TabDragging/DetachToBrowserTabDragControllerTest.DragToOverviewNewWindowItem/1 +-TabDragging/DetachToBrowserTabDragControllerTest.DragToOverviewWindow/1 +-TabDragging/DetachToBrowserTabDragControllerTest.DragToSeparateWindow/1 +-TabDragging/DetachToBrowserTabDragControllerTest.DragWithMaskedWindows/0 +-TabDragging/DetachToBrowserTabDragControllerTest.DragWithMaskedWindows/1 +-TabDragging/DetachToBrowserTabDragControllerTestTouch.PressSecondFingerWhileDetached/0 +-TabDragging/DetachToBrowserTabDragControllerTestTouch.SecondFingerPressTest/0 + +# TabScrubber: crbug.com/889097 +-TabScrubberTest.Bounds +-TabScrubberTest.CloseBrowser +-TabScrubberTest.DeleteBeforeHighlighted +-TabScrubberTest.DeleteHighlighted +-TabScrubberTest.FullScreenBrowser +-TabScrubberTest.MoveAfter +-TabScrubberTest.MoveBefore +-TabScrubberTest.MoveHighlighted +-TabScrubberTest.Multi +-TabScrubberTest.MultiBrowser +-TabScrubberTest.Repeated +-TabScrubberTest.RTLMoveBefore +-TabScrubberTest.RTLMulti +-TabScrubberTest.RTLSkipped +-TabScrubberTest.Single +-TabScrubberTest.Skipped
diff --git a/testing/buildbot/filters/mojo.fyi.chromeos.network_browser_tests.filter b/testing/buildbot/filters/mojo.fyi.chromeos.network_browser_tests.filter index fb0d5f6..65dd820 100644 --- a/testing/buildbot/filters/mojo.fyi.chromeos.network_browser_tests.filter +++ b/testing/buildbot/filters/mojo.fyi.chromeos.network_browser_tests.filter
@@ -14,12 +14,6 @@ -ArcSessionManagerTest.ManagedAndroidAccount -ArcSessionManagerTest.ManagedChromeAccount -ArcSessionManagerTest.WellKnownConsumerAccount --BackgroundFetchBrowserTest.FetchesRunToCompletionAndUpdateTitle_Failed --BackgroundFetchBrowserTest.FetchesRunToCompletionAndUpdateTitle_Fetched --BackgroundFetchBrowserTest.FetchFromChildFrameWithPermissions --BackgroundFetchBrowserTest.FetchFromServiceWorker --BackgroundFetchBrowserTest.OfflineItemCollection_VerifyResourceDownloadedWhenDownloadTotalLargerThanActualSize --BackgroundFetchBrowserTest.OfflineItemCollection_VerifyResourceDownloadedWhenDownloadTotalSmallerThanActualSize -CheckSystemTokenAvailability/EnterprisePlatformKeysTest.Basic/0 -CheckSystemTokenAvailability/EnterprisePlatformKeysTest.Basic/1 -CheckSystemTokenAvailability/EnterprisePlatformKeysTest.Basic/2 @@ -31,9 +25,6 @@ -DeviceIDTest.Migration -DeviceIDTest.NewUsers -ExtensionWebRequestApiTest.WebRequestApiDoesNotCrashOnErrorAfterProfileDestroyed --FileManagerPrivateApiTest.OnFileChanged --FileManagerPrivateApiTest.Permissions --FileManagerUITest.QuickView -ForceMaximizeOnFirstRunTest.TwoRuns -ForceMaximizePolicyFalseTest.GeneralFirstRun -HostedAppNonClientFrameViewAshTest.FocusableViews/material @@ -134,11 +125,12 @@ # https://crbug.com/882610 -ChromeBrowserMainBrowserTest.VariationsServiceStartsRequestOnNetworkChange -NetworkConnectionTrackerBrowserTest.SimulateNetworkServiceCrash - -# Time out in StoragePartitionImpl::InitNetworkContext(). Might be related to -# https://crbug.com/882610 --ArcAuthServiceChildAccountTest.ChildTransition --FileManagerPrivateApiTest.OnFileChanged +-BackgroundFetchBrowserTest.FetchesRunToCompletionAndUpdateTitle_Failed +-BackgroundFetchBrowserTest.FetchesRunToCompletionAndUpdateTitle_Fetched +-BackgroundFetchBrowserTest.FetchFromChildFrameWithPermissions +-BackgroundFetchBrowserTest.FetchFromServiceWorker +-BackgroundFetchBrowserTest.OfflineItemCollection_VerifyResourceDownloadedWhenDownloadTotalLargerThanActualSize +-BackgroundFetchBrowserTest.OfflineItemCollection_VerifyResourceDownloadedWhenDownloadTotalSmallerThanActualSize # Relies on net::URLRequestInterceptor. # https://crbug.com/884782
diff --git a/testing/buildbot/test_suites.pyl b/testing/buildbot/test_suites.pyl index 2eb8976..e215548 100644 --- a/testing/buildbot/test_suites.pyl +++ b/testing/buildbot/test_suites.pyl
@@ -1815,6 +1815,13 @@ '--enable-features=Mash', ], }, + 'single_process_mash_interactive_ui_tests': { + 'test': 'interactive_ui_tests', + 'args': [ + '--enable-features=SingleProcessMash', + '--test-launcher-filter-file=../../testing/buildbot/filters/chromeos.single_process_mash.interactive_ui_tests.filter', + ], + }, }, 'memory_infra_isolated_scripts': {
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl index 93b43a7..5c357eab 100644 --- a/testing/buildbot/waterfalls.pyl +++ b/testing/buildbot/waterfalls.pyl
@@ -3428,112 +3428,6 @@ { 'name': 'chromium.webrtc.fyi', 'machines': { - 'Android Builder': { - 'additional_compile_targets': [ - 'browser_tests', - 'capture_unittests', - 'content_browsertests', - 'content_unittests', - 'jingle_unittests', - 'remoting_unittests', - ], - }, - 'Android Builder (dbg)': { - 'additional_compile_targets': [ - 'browser_tests', - 'capture_unittests', - 'content_browsertests', - 'content_unittests', - 'jingle_unittests', - 'remoting_unittests', - ], - }, - 'Android Builder ARM64 (dbg)': { - 'additional_compile_targets': [ - 'browser_tests', - 'capture_unittests', - 'content_browsertests', - 'content_unittests', - 'jingle_unittests', - 'remoting_unittests', - ], - }, - 'Linux Builder': { - 'additional_compile_targets': [ - 'browser_tests', - 'capture_unittests', - 'content_browsertests', - 'content_unittests', - 'frame_analyzer', - 'jingle_unittests', - 'remoting_unittests', - 'remoting/webapp:webapp', - ], - }, - 'Linux Builder (dbg)': { - 'additional_compile_targets': [ - 'browser_tests', - 'capture_unittests', - 'content_browsertests', - 'content_unittests', - 'frame_analyzer', - 'jingle_unittests', - 'remoting_unittests', - 'remoting/webapp:webapp', - ], - }, - 'Mac Builder': { - 'additional_compile_targets': [ - 'browser_tests', - 'capture_unittests', - 'content_browsertests', - 'content_unittests', - 'frame_analyzer', - 'jingle_unittests', - 'remoting_unittests', - ], - }, - 'Mac Builder (dbg)': { - 'additional_compile_targets': [ - 'browser_tests', - 'capture_unittests', - 'content_browsertests', - 'content_unittests', - 'frame_analyzer', - 'jingle_unittests', - 'remoting_unittests', - 'remoting/webapp:webapp', - ], - }, - 'Win Builder': { - 'additional_compile_targets': [ - 'browser_tests', - 'capture_unittests', - 'content_browsertests', - 'content_unittests', - 'frame_analyzer', - 'jingle_unittests', - 'remoting_unittests', - 'remoting/webapp:webapp', - ], - }, - 'Win Builder (dbg)': { - 'additional_compile_targets': [ - 'browser_tests', - 'capture_unittests', - 'content_browsertests', - 'content_unittests', - 'frame_analyzer', - 'jingle_unittests', - 'remoting_unittests', - 'remoting/webapp:webapp', - ], - }, - }, - }, - { - 'name': 'chromium.webrtc.fyi.experimental', - 'machines': { # For builders, specify targets if the builder has no associated # tester (if it does, it will build what the tester needs). 'WebRTC Chromium FYI Android Builder': {
diff --git a/testing/scripts/monochrome_apk_checker_wrapper.py b/testing/scripts/monochrome_apk_checker_wrapper.py index 4a1e8e5..a05f8bd 100755 --- a/testing/scripts/monochrome_apk_checker_wrapper.py +++ b/testing/scripts/monochrome_apk_checker_wrapper.py
@@ -50,7 +50,7 @@ 'actual': 'PASS' if success else 'FAIL', } if not success: - test['unexpected'] = True + test['is_unexpected'] = True json.dump({ 'version': 3,
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index 35757c1..ce496d42 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -1797,6 +1797,23 @@ ] } ], + "FCMInvalidationsExperiment": [ + { + "platforms": [ + "windows", + "mac", + "chromeos" + ], + "experiments": [ + { + "name": "FCMInvalidationsEnabled", + "enable_features": [ + "FCMInvalidations" + ] + } + ] + } + ], "FrameTypePriorityExperiment": [ { "platforms": [
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG index 07df34b..50e48e24 100644 --- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG +++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
@@ -339,8 +339,6 @@ crbug.com/591099 external/wpt/xhr/send-entity-body-document.htm [ Pass ] crbug.com/591099 fast/backgrounds/quirks-mode-line-box-backgrounds.html [ Failure ] crbug.com/591099 fast/block/float-avoids-padding-inline-ancestors.html [ Crash Failure ] -crbug.com/591099 fast/block/float/nopaint-after-layer-destruction.html [ Failure ] -crbug.com/591099 fast/block/float/nopaint-after-layer-destruction2.html [ Failure ] crbug.com/591099 fast/block/float/overlapping-floats-paint-hittest-order-1.html [ Failure ] crbug.com/591099 fast/block/positioning/positioned-child-inside-relative-positioned-anonymous-block.html [ Failure ] crbug.com/591099 fast/borders/bidi-002.html [ Failure ] @@ -353,7 +351,6 @@ crbug.com/591099 fast/css/absolute-inline-alignment-2.html [ Pass ] crbug.com/591099 fast/css/case-transform.html [ Failure ] crbug.com/835484 fast/css/focus-ring-recursive-continuations.html [ Failure ] -crbug.com/835484 fast/css/focus-ring-recursive-inlines.html [ Failure ] crbug.com/591099 fast/css/getComputedStyle/computed-style-percentage-top-with-position-inline.html [ Failure ] crbug.com/835484 fast/css/outline-auto-empty-rects.html [ Failure ] crbug.com/835484 fast/css/outline-narrowLine.html [ Failure ] @@ -362,7 +359,7 @@ crbug.com/591099 fast/events/wheel/mainthread-touchpad-fling-latching.html [ Pass ] crbug.com/591099 fast/events/wheel/wheel-scroll-latching-on-scrollbar.html [ Pass ] crbug.com/591099 fast/forms/placeholder-position.html [ Failure ] -crbug.com/591099 fast/forms/select/menulist-appearance-rtl.html [ Failure ] +crbug.com/890135 fast/forms/select/menulist-appearance-rtl.html [ Failure ] crbug.com/591099 fast/frames/crash-frameset-CSS-content-property.html [ Crash Pass ] crbug.com/835484 fast/inline/continuation-outlines-with-layers.html [ Failure ] crbug.com/835484 fast/inline/continuation-outlines.html [ Failure ] @@ -396,7 +393,7 @@ crbug.com/591099 fast/writing-mode/fieldsets.html [ Failure ] crbug.com/591099 fast/writing-mode/percentage-height-orthogonal-writing-modes.html [ Failure ] crbug.com/591099 fast/writing-mode/table-percent-width-quirk.html [ Pass ] -crbug.com/591099 fragmentation/transformed-clip-before-second-column.html [ Failure ] +crbug.com/890135 fragmentation/transformed-clip-before-second-column.html [ Failure ] crbug.com/591099 hittesting/inline-with-clip-path.html [ Failure ] crbug.com/855039 html/details_summary/details-writing-mode-align-center.html [ Failure ] crbug.com/855039 html/details_summary/details-writing-mode-align-left.html [ Failure ] @@ -418,17 +415,13 @@ crbug.com/591099 http/tests/security/setDomainRelaxationForbiddenForURLScheme.html [ Crash ] crbug.com/591099 idle-callback/test-runner-run-idle-tasks.html [ Pass ] crbug.com/591099 images/color-profile-image-filter-all.html [ Failure ] -crbug.com/591099 images/rendering-broken-block-flow-images.html [ Failure ] -crbug.com/591099 images/rendering-broken-images.html [ Failure ] +crbug.com/890135 images/rendering-broken-block-flow-images.html [ Failure ] +crbug.com/890135 images/rendering-broken-images.html [ Failure ] crbug.com/591099 inspector-protocol/dom-snapshot/dom-snapshot-getSnapshot-pseudo-element.js [ Failure ] crbug.com/591099 inspector-protocol/dom-snapshot/dom-snapshot-getSnapshot.js [ Failure ] crbug.com/714962 inspector-protocol/layout-fonts/languages-emoji-rare-glyphs.js [ Failure ] crbug.com/591099 inspector-protocol/timeline/page-frames.js [ Failure ] crbug.com/591099 intersection-observer/v2/text-shadow.html [ Failure ] -crbug.com/591099 media/audio-controls-rendering.html [ Failure ] -crbug.com/591099 media/media-document-audio-repaint.html [ Failure ] -crbug.com/591099 media/video-display-toggle.html [ Failure ] -crbug.com/591099 media/video-layer-crash.html [ Failure ] crbug.com/591099 paint/float/float-under-inline-self-painting-change.html [ Failure ] crbug.com/835484 paint/inline/focus-ring-under-absolute-with-relative-continuation.html [ Failure ] crbug.com/591099 paint/invalidation/clip/control-clip.html [ Failure ] @@ -492,20 +485,14 @@ crbug.com/591099 tables/mozilla/bugs/bug2973.html [ Failure ] crbug.com/591099 tables/mozilla/bugs/bug50695-2.html [ Failure ] crbug.com/591099 tables/mozilla/bugs/bug55527.html [ Failure ] -crbug.com/591099 transforms/3d/hit-testing/backface-no-transform-hit-test.html [ Failure ] -crbug.com/591099 transforms/3d/point-mapping/3d-point-mapping-deep.html [ Failure ] -crbug.com/591099 transforms/3d/point-mapping/3d-point-mapping-origins.html [ Failure ] -crbug.com/591099 transforms/3d/point-mapping/3d-point-mapping-overlapping.html [ Failure ] -crbug.com/591099 transforms/3d/point-mapping/3d-point-mapping-preserve-3d.html [ Failure ] -crbug.com/591099 transforms/3d/point-mapping/3d-point-mapping.html [ Failure ] crbug.com/591099 transforms/svg-vs-css.xhtml [ Failure ] crbug.com/870008 virtual/android/rootscroller/position-fixed-in-unscrollable-document-iframe.html [ Failure ] crbug.com/870008 virtual/android/rootscroller/position-fixed-in-unscrollable-document.html [ Failure ] crbug.com/591099 virtual/exotic-color-space/ [ Skip ] crbug.com/591099 virtual/feature-policy-vibrate/ [ Skip ] crbug.com/591099 virtual/gpu-rasterization/images/color-profile-image-filter-all.html [ Failure ] -crbug.com/591099 virtual/gpu-rasterization/images/rendering-broken-block-flow-images.html [ Failure ] -crbug.com/591099 virtual/gpu-rasterization/images/rendering-broken-images.html [ Failure ] +crbug.com/890135 virtual/gpu-rasterization/images/rendering-broken-block-flow-images.html [ Failure ] +crbug.com/890135 virtual/gpu-rasterization/images/rendering-broken-images.html [ Failure ] crbug.com/591099 virtual/gpu/fast/canvas/canvas-arc-circumference.html [ Failure Pass ] crbug.com/591099 virtual/gpu/fast/canvas/canvas-blending-color-over-image.html [ Pass ] crbug.com/591099 virtual/gpu/fast/canvas/canvas-blending-gradient-over-pattern.html [ Pass Timeout ] @@ -514,7 +501,6 @@ crbug.com/591099 virtual/layout_ng/ [ Skip ] crbug.com/824918 virtual/layout_ng_experimental/ [ Skip ] crbug.com/591099 virtual/mojo-blob-urls/external/wpt/FileAPI/url/sandboxed-iframe.html [ Pass ] -crbug.com/591099 virtual/mouseevent_fractional/fast/events/popup-allowed-from-gesture-initiated-event.html [ Failure ] crbug.com/591099 virtual/mouseevent_fractional/fast/events/touch/compositor-touch-hit-rects.html [ Failure ] crbug.com/591099 virtual/mouseevent_fractional/fast/events/wheel/mainthread-touchpad-fling-latching.html [ Pass ] crbug.com/591099 virtual/mouseevent_fractional/fast/events/wheel/wheel-scroll-latching-on-scrollbar.html [ Pass ] @@ -545,11 +531,6 @@ crbug.com/591099 virtual/stable/ [ Skip ] crbug.com/591099 virtual/threaded/ [ Skip ] crbug.com/591099 virtual/user-activation-v2/fast/events/mouse-cursor.html [ Failure ] -crbug.com/591099 virtual/user-activation-v2/fast/events/popup-allowed-from-gesture-initiated-event.html [ Failure ] crbug.com/591099 virtual/user-activation-v2/fast/events/touch/compositor-touch-hit-rects.html [ Failure ] -crbug.com/591099 virtual/video-surface-layer/media/audio-controls-rendering.html [ Failure ] -crbug.com/591099 virtual/video-surface-layer/media/media-document-audio-repaint.html [ Failure ] -crbug.com/591099 virtual/video-surface-layer/media/video-aspect-ratio.html [ Failure ] -crbug.com/591099 virtual/video-surface-layer/media/video-display-toggle.html [ Failure ] crbug.com/591099 virtual/video-surface-layer/media/video-layer-crash.html [ Crash Failure ] crbug.com/591099 virtual/webrtc-wpt-unified-plan/external/wpt/webrtc/RTCDTMFSender-ontonechange.https.html [ Pass ]
diff --git a/third_party/WebKit/LayoutTests/SlowTests b/third_party/WebKit/LayoutTests/SlowTests index 19dfed3..7fa152d 100644 --- a/third_party/WebKit/LayoutTests/SlowTests +++ b/third_party/WebKit/LayoutTests/SlowTests
@@ -202,8 +202,6 @@ crbug.com/528419 http/tests/devtools/elements/styles-2/pseudo-elements.js [ Slow ] -crbug.com/529345 [ Win10 ] paint/masks/fieldset-mask.html [ Slow ] - crbug.com/802029 fast/dom/shadow/focus-controller-recursion-crash.html [ Slow ] crbug.com/592183 external/wpt/webusb/usbDevice.https.html [ Slow ]
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations index e9641cb..f58124e 100644 --- a/third_party/WebKit/LayoutTests/TestExpectations +++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -1396,6 +1396,7 @@ crbug.com/591099 virtual/layout_ng_experimental/css3/flexbox/multiline.html [ Skip ] crbug.com/591099 virtual/layout_ng_experimental/css3/flexbox/negative-flex-rounding-assert.html [ Skip ] crbug.com/591099 virtual/layout_ng_experimental/css3/flexbox/negative-overflow.html [ Skip ] +crbug.com/591099 virtual/layout_ng_experimental/css3/flexbox/nested-flexbox-min-size-auto.html [ Skip ] crbug.com/591099 virtual/layout_ng_experimental/css3/flexbox/nested-orthogonal-flexbox-relayout.html [ Skip ] crbug.com/591099 virtual/layout_ng_experimental/css3/flexbox/nested-stretch.html [ Skip ] crbug.com/591099 virtual/layout_ng_experimental/css3/flexbox/order-painting.html [ Failure ] @@ -1515,7 +1516,6 @@ crbug.com/467127 virtual/layout_ng_experimental/external/wpt/css/css-flexbox/flex-minimum-height-flex-items-006.xht [ Skip ] crbug.com/249112 virtual/layout_ng_experimental/external/wpt/css/css-flexbox/flex-minimum-height-flex-items-007.xht [ Skip ] crbug.com/467127 virtual/layout_ng_experimental/external/wpt/css/css-flexbox/flex-minimum-height-flex-items-008.xht [ Skip ] -crbug.com/591099 virtual/layout_ng_experimental/external/wpt/css/css-flexbox/flex-minimum-height-flex-items-009.html [ Skip ] crbug.com/591099 virtual/layout_ng_experimental/external/wpt/css/css-flexbox/flex-minimum-width-flex-items-001.xht [ Failure ] crbug.com/591099 virtual/layout_ng_experimental/external/wpt/css/css-flexbox/flex-minimum-width-flex-items-002.xht [ Failure ] crbug.com/591099 virtual/layout_ng_experimental/external/wpt/css/css-flexbox/flex-minimum-width-flex-items-003.xht [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/css3/flexbox/nested-flexbox-min-size-auto.html b/third_party/WebKit/LayoutTests/css3/flexbox/nested-flexbox-min-size-auto.html new file mode 100644 index 0000000..1c9297d --- /dev/null +++ b/third_party/WebKit/LayoutTests/css3/flexbox/nested-flexbox-min-size-auto.html
@@ -0,0 +1,41 @@ +<!DOCTYPE html> +<link href="resources/flexbox.css" rel="stylesheet"> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> +<script src="../../resources/check-layout-th.js"></script> +<style> +#container { + height: 300px; + outline: 2px solid black; +} + +.inner +{ + width: 400px; + flex: 1; + background-color: green; +} +</style> +<script> +function change() { + var container = document.getElementById('container'); + container.offsetHeight; + container.style.height = '80px'; + checkLayout('#container'); +} +</script> +<body onload="change()"> +<p>Green rectangle should be entirely within the black rectangle</p> +<div id="log"></div> +<div id="container"> + <div class="flexbox column" style="height: 100%;"> + <div class="flexbox flex-one"> + <div class="flexbox column"> + <div class="flexbox column flex-one"> + <div class="inner" data-expected-height="80"> + </div> + </div> + </div> + </div> + </div> +</div>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-flexbox/flex-minimum-height-flex-items-009.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-flexbox/flex-minimum-height-flex-items-009.html deleted file mode 100644 index 718386a..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/css/css-flexbox/flex-minimum-height-flex-items-009.html +++ /dev/null
@@ -1,62 +0,0 @@ -<!DOCTYPE html> -<title>Tests correct handling of min-height: auto with dynamic changes</title> -<link rel="help" href="http://www.w3.org/TR/css-flexbox-1/#min-size-auto" title="4.5. Implied Minimum Size of Flex Items" /> -<link rel="author" title="Google Inc." href="http://www.google.com/"> -<link href="support/flexbox.css" rel="stylesheet"> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script src="/resources/check-layout-th.js"></script> -<style> -.container { - height: 300px; - outline: 2px solid black; -} - -.inner -{ - width: 400px; - flex: 1; - background-color: green; -} -#container2 .flexbox > * { flex-basis: 0; } -#container2 .column > * { flex-basis: auto; } -</style> -<script> -function change() { - var container = document.getElementById('container'); - container.offsetHeight; - container.style.height = '80px'; - container = document.getElementById('container2'); - container.offsetHeight; - container.style.height = '80px'; - checkLayout('.container'); -} -</script> -<body onload="change()"> -<p>Green rectangle should be entirely within the black rectangle</p> -<div id="log"></div> -<div id="container" class="container"> - <div class="flexbox column" style="height: 100%;"> - <div class="flexbox flex-one"> - <div class="flexbox column"> - <div class="flexbox column flex-one"> - <div class="inner" data-expected-height="80"> - </div> - </div> - </div> - </div> - </div> -</div> - -<div id="container2" class="container"> - <div class="flexbox column" style="height: 100%;"> - <div class="flexbox flex-one"> - <div class="flexbox column"> - <div class="flexbox column flex-one"> - <div class="inner" data-expected-height="80"> - </div> - </div> - </div> - </div> - </div> -</div>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-grid/alignment/grid-gutters-013.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-grid/alignment/grid-gutters-013.html new file mode 100644 index 0000000..e7281472 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-grid/alignment/grid-gutters-013.html
@@ -0,0 +1,36 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Grid Layout Test: Gutters adjacent to collapsed tracks also collapse</title> +<link rel="help" href="https://www.w3.org/TR/css-grid-1/#gutters"> +<link rel="help" href="https://www.w3.org/TR/css-align-3/#gap-shorthand"> +<link rel="help" href="https://www.w3.org/TR/css-align-3/#gap-legacy"> +<link rel="help" href="https://www.w3.org/TR/css-grid-1/#repeat-notation"> +<link rel="match" href="../../reference/ref-filled-green-100px-square.xht"> +<link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com"> +<meta name="assert" content="This test checks that gutters adjacent to collapsed tracks don't reduce the space available for aligning adjacent grid items." /> +<style> + #grid { + display: grid; + margin-top: -50px; + margin-left: -50px; + width: 500px; + height: 500px; + grid-gap: 100px; + grid-template-rows: repeat(auto-fit, 200px); + grid-template-columns: repeat(auto-fit, 200px); + align-items: center; + justify-items: center; + background: linear-gradient(red, red) no-repeat 50px 50px / 100px 100px; + } + + #grid > div { + background-color: green; + width: 50%; + height: 50%; + } +</style> + +<p>Test passes if there is a filled green square and <strong>no red</strong>.</p> +<div id="grid"> + <div></div> +</div>
diff --git a/third_party/WebKit/LayoutTests/fast/css/invalidation/defined-pseudo.html b/third_party/WebKit/LayoutTests/fast/css/invalidation/defined-pseudo.html new file mode 100644 index 0000000..a01bcf30 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/css/invalidation/defined-pseudo.html
@@ -0,0 +1,61 @@ +<!DOCTYPE html> +<script src="../../../resources/testharness.js"></script> +<script src="../../../resources/testharnessreport.js"></script> +<style> +#sibling, #child, #child3 { background-color: green } +custom-one:not(:defined) #child, +custom-two:not(:defined) + #sibling, +custom-three:not(:defined) #child3 { + background-color: red +} +</style> + +<custom-one> + <div></div> + <div id="child"></div> +</custom-one> + +<custom-two> + <div></div> + <div></div> +</custom-two> +<div id="sibling"></div> + +<custom-three> + <div></div> + <div id="child3"></div> +</custom-three> + +<script> +const RED = "rgb(255, 0, 0)"; +const GREEN = "rgb(0, 128, 0)"; + +test(() => { + // Initially :not(:defined). + assert_equals(getComputedStyle(child).backgroundColor, RED); + assert_equals(getComputedStyle(sibling).backgroundColor, RED); + assert_equals(getComputedStyle(child3).backgroundColor, RED); + + document.body.offsetTop; // force recalc + + customElements.define("custom-one", class extends HTMLElement {}); + if (window.internals) + assert_equals(internals.updateStyleAndReturnAffectedElementCount(), 1); + assert_equals(getComputedStyle(child).backgroundColor, GREEN); + + document.body.offsetTop; // force recalc + + customElements.define("custom-two", class extends HTMLElement {}); + if (window.internals) + assert_equals(internals.updateStyleAndReturnAffectedElementCount(), 1); + assert_equals(getComputedStyle(sibling).backgroundColor, GREEN); + + document.body.offsetTop; // force recalc + + document.registerElement("custom-three", { prototype: Object.create(HTMLElement.prototype) }); + if (window.internals) + assert_equals(internals.updateStyleAndReturnAffectedElementCount(), 1); + assert_equals(getComputedStyle(child3).backgroundColor, GREEN); + +}, "Use invalidation sets for :defined pseudo class.") +</script>
diff --git a/third_party/WebKit/LayoutTests/fast/css/invalidation/unresolved-pseudo-expected.txt b/third_party/WebKit/LayoutTests/fast/css/invalidation/unresolved-pseudo-expected.txt index 10538499..3f70e82 100644 --- a/third_party/WebKit/LayoutTests/fast/css/invalidation/unresolved-pseudo-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/css/invalidation/unresolved-pseudo-expected.txt
@@ -1,4 +1,5 @@ -CONSOLE WARNING: line 31: document.registerElement is deprecated and will be removed in M73, around March 2019. Please use window.customElements.define instead. See https://www.chromestatus.com/features/4642138092470272 for more details. +CONSOLE WARNING: :unresolved pseudo selector is deprecated and will be removed in M73, around March 2019. Please use :not(:defined) instead. See https://www.chromestatus.com/features/4642138092470272 for more details. +CONSOLE WARNING: line 41: document.registerElement is deprecated and will be removed in M73, around March 2019. Please use window.customElements.define instead. See https://www.chromestatus.com/features/4642138092470272 for more details. Use invalidation sets for :unresolved pseudo class. On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". @@ -6,10 +7,13 @@ PASS getComputedStyle(child).backgroundColor is red PASS getComputedStyle(sibling).backgroundColor is red +PASS getComputedStyle(child3).backgroundColor is red PASS internals.updateStyleAndReturnAffectedElementCount() is 1 PASS getComputedStyle(child).backgroundColor is green PASS internals.updateStyleAndReturnAffectedElementCount() is 1 PASS getComputedStyle(sibling).backgroundColor is green +PASS internals.updateStyleAndReturnAffectedElementCount() is 1 +PASS getComputedStyle(child3).backgroundColor is green PASS successfullyParsed is true TEST COMPLETE
diff --git a/third_party/WebKit/LayoutTests/fast/css/invalidation/unresolved-pseudo.html b/third_party/WebKit/LayoutTests/fast/css/invalidation/unresolved-pseudo.html index 3fb26f92..6dbf472 100644 --- a/third_party/WebKit/LayoutTests/fast/css/invalidation/unresolved-pseudo.html +++ b/third_party/WebKit/LayoutTests/fast/css/invalidation/unresolved-pseudo.html
@@ -1,8 +1,12 @@ <!DOCTYPE html> <script src="../../../resources/js-test.js"></script> <style> -#sibling, #child { background-color: green } -custom-one:unresolved #child, custom-two:unresolved + #sibling { background-color: red } +#sibling, #child, #child3 { background-color: green } +custom-one:unresolved #child, +custom-two:unresolved + #sibling, +custom-three:unresolved #child3 { + background-color: red +} </style> <custom-one> @@ -16,6 +20,11 @@ </custom-two> <div id="sibling"></div> +<custom-three> + <div></div> + <div id="child3"></div> +</custom-three> + <script> description("Use invalidation sets for :unresolved pseudo class.") @@ -25,6 +34,7 @@ // Initially :unresolved. shouldBe("getComputedStyle(child).backgroundColor", "red"); shouldBe("getComputedStyle(sibling).backgroundColor", "red"); +shouldBe("getComputedStyle(child3).backgroundColor", "red"); document.body.offsetTop; // force recalc @@ -44,4 +54,11 @@ shouldBe("internals.updateStyleAndReturnAffectedElementCount()", "1"); shouldBe("getComputedStyle(sibling).backgroundColor", "green"); +document.body.offsetTop; // force recalc + +customElements.define("custom-three", class extends HTMLElement {}); +if (window.internals) + shouldBe("internals.updateStyleAndReturnAffectedElementCount()", "1"); +shouldBe("getComputedStyle(child3).backgroundColor", "green"); + </script>
diff --git a/third_party/WebKit/LayoutTests/fast/dom/custom/element-upgrade-expected.txt b/third_party/WebKit/LayoutTests/fast/dom/custom/element-upgrade-expected.txt index f98ba21f..7497a6e 100644 --- a/third_party/WebKit/LayoutTests/fast/dom/custom/element-upgrade-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/dom/custom/element-upgrade-expected.txt
@@ -1,4 +1,5 @@ CONSOLE WARNING: line 17: document.registerElement is deprecated and will be removed in M73, around March 2019. Please use window.customElements.define instead. See https://www.chromestatus.com/features/4642138092470272 for more details. +CONSOLE WARNING: line 1: :unresolved pseudo selector is deprecated and will be removed in M73, around March 2019. Please use :not(:defined) instead. See https://www.chromestatus.com/features/4642138092470272 for more details. Tests the element upgrade algorithm. On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
diff --git a/third_party/WebKit/LayoutTests/fast/dom/custom/unresolved-pseudoclass-expected.txt b/third_party/WebKit/LayoutTests/fast/dom/custom/unresolved-pseudoclass-expected.txt index 600a1983..d0fa0fe 100644 --- a/third_party/WebKit/LayoutTests/fast/dom/custom/unresolved-pseudoclass-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/dom/custom/unresolved-pseudoclass-expected.txt
@@ -1,3 +1,4 @@ +CONSOLE WARNING: :unresolved pseudo selector is deprecated and will be removed in M73, around March 2019. Please use :not(:defined) instead. See https://www.chromestatus.com/features/4642138092470272 for more details. CONSOLE WARNING: line 34: document.registerElement is deprecated and will be removed in M73, around March 2019. Please use window.customElements.define instead. See https://www.chromestatus.com/features/4642138092470272 for more details. Tests the :unresolved pseudoclass.
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/float/nopaint-after-layer-destruction2-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/float/nopaint-after-layer-destruction2-expected.png new file mode 100644 index 0000000..2368ff77 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/float/nopaint-after-layer-destruction2-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/float/nopaint-after-layer-destruction2-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/float/nopaint-after-layer-destruction2-expected.txt new file mode 100644 index 0000000..7272bec --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/float/nopaint-after-layer-destruction2-expected.txt
@@ -0,0 +1,35 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x600 + LayoutNGBlockFlow {HTML} at (0,0) size 800x600 + LayoutNGBlockFlow {BODY} at (8,8) size 784x576 + LayoutNGBlockFlow {P} at (0,0) size 784x40 + LayoutText {#text} at (0,0) size 139x19 + text run at (0,0) width 139: "This is a pixel test for " + LayoutInline {I} at (0,0) size 762x39 + LayoutInline {A} at (0,0) size 347x19 [color=#0000EE] + LayoutText {#text} at (139,0) size 347x19 + text run at (139,0) width 347: "http://bugzilla.opendarwin.org/show_bug.cgi?id=4334" + LayoutText {#text} at (486,0) size 762x39 + text run at (486,0) width 276: " REGRESSION: Flickering when css-hover" + text run at (0,20) width 273: "should change opacity on floating elements" + LayoutText {#text} at (273,20) size 4x19 + text run at (273,20) width 4: "." + LayoutNGBlockFlow {P} at (0,56) size 784x20 + LayoutText {#text} at (0,0) size 491x19 + text run at (0,0) width 491: "There should be a solid green square below mixed in with a paragraph of text." + LayoutNGBlockFlow {DIV} at (0,112.72) size 784x141.72 + LayoutNGBlockFlow {DIV} at (0,0) size 784x141.72 + LayoutNGBlockFlow (floating) {DIV} at (3,3) size 75x75 [bgcolor=#008000] + LayoutNGBlockFlow {H3} at (0,0) size 784x23 + LayoutText {#text} at (81,0) size 163x22 + text run at (81,0) width 163: "Stanley Park Forest" + LayoutNGBlockFlow {P} at (0,41.72) size 784x100 + LayoutText {#text} at (81,0) size 784x99 + text run at (81,0) width 703: "The forest is primarily second and third growth. The area was saved from development because of its status as a" + text run at (81,20) width 664: "federal military reserve; it occupied a strategic location for defending the former provincial capital of New" + text run at (0,40) width 760: "Westminster in the case of an American naval invasion. Nevertheless, the federal government allowed logging operations" + text run at (0,60) width 763: "there in the mid-nineteenth century. Large swathes of the park were also deforested by natural causes on two occasions in" + text run at (0,80) width 105: "the 20th century." +layer at (8,100) size 784x2 clip at (0,0) size 0x0 + LayoutNGBlockFlow {HR} at (0,92) size 784x2 [border: (1px inset #EEEEEE)]
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/media/audio-controls-rendering-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/media/audio-controls-rendering-expected.txt index 610087a..d480650 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/media/audio-controls-rendering-expected.txt +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/media/audio-controls-rendering-expected.txt
@@ -44,6 +44,18 @@ LayoutBlockFlow (positioned) {DIV} at (0,0) size 0x4 [bgcolor=#000000DE] layer at (139,69) size 111x4 LayoutBlockFlow (positioned) {DIV} at (0,0) size 111x4 [bgcolor=#0000008A] +layer at (266,47) size 0x48 transparent + LayoutSlider {INPUT} at (258,3) size 0x48 [color=#9D968E] + LayoutFlexibleBox {DIV} at (0,22) size 0x4 +layer at (266,69) size 12x4 + LayoutBlockFlow (relative positioned) {DIV} at (0,0) size 12x4 [bgcolor=#00000033] + LayoutBlockFlow {DIV} at (0,-4) size 12x12 [bgcolor=#000000DE] +layer at (266,69) size 12x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 12x4 +layer at (266,69) size 0x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 0x4 [bgcolor=#000000DE] +layer at (266,69) size 12x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 12x4 [bgcolor=#0000008A] layer at (8,118) size 320x54 LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 320x54 layer at (8,118) size 320x54 @@ -72,6 +84,18 @@ LayoutBlockFlow (positioned) {DIV} at (0,0) size 0x4 [bgcolor=#000000DE] layer at (139,143) size 131x4 LayoutBlockFlow (positioned) {DIV} at (0,0) size 131x4 [bgcolor=#0000008A] +layer at (286,121) size 0x48 transparent + LayoutSlider {INPUT} at (278,3) size 0x48 [color=#9D968E] + LayoutFlexibleBox {DIV} at (0,22) size 0x4 +layer at (286,143) size 12x4 + LayoutBlockFlow (relative positioned) {DIV} at (0,0) size 12x4 [bgcolor=#00000033] + LayoutBlockFlow {DIV} at (0,-4) size 12x12 [bgcolor=#000000DE] +layer at (286,143) size 12x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 12x4 +layer at (286,143) size 0x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 0x4 [bgcolor=#000000DE] +layer at (286,143) size 12x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 12x4 [bgcolor=#0000008A] layer at (8,192) size 320x100 LayoutMedia (positioned) {AUDIO} at (8,192) size 320x100 [bgcolor=#0000FF] layer at (8,192) size 320x100 @@ -102,3 +126,15 @@ LayoutBlockFlow (positioned) {DIV} at (0,0) size 0x4 [bgcolor=#000000DE] layer at (139,263) size 131x4 LayoutBlockFlow (positioned) {DIV} at (0,0) size 131x4 [bgcolor=#0000008A] +layer at (286,241) size 0x48 transparent + LayoutSlider {INPUT} at (278,3) size 0x48 [color=#9D968E] + LayoutFlexibleBox {DIV} at (0,22) size 0x4 +layer at (286,263) size 12x4 + LayoutBlockFlow (relative positioned) {DIV} at (0,0) size 12x4 [bgcolor=#00000033] + LayoutBlockFlow {DIV} at (0,-4) size 12x12 [bgcolor=#000000DE] +layer at (286,263) size 12x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 12x4 +layer at (286,263) size 0x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 0x4 [bgcolor=#000000DE] +layer at (286,263) size 12x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 12x4 [bgcolor=#0000008A]
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/media/media-document-audio-repaint-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/media/media-document-audio-repaint-expected.txt index c48d0b8..f014079 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/media/media-document-audio-repaint-expected.txt +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/media/media-document-audio-repaint-expected.txt
@@ -46,3 +46,15 @@ LayoutBlockFlow (positioned) {DIV} at (0,0) size 55x4 [bgcolor=#000000DE] layer at (226,211) size 55x4 LayoutBlockFlow (positioned) {DIV} at (55,0) size 55x4 [bgcolor=#0000008A] + layer at (298,189) size 0x48 transparent + LayoutSlider {INPUT} at (258,3) size 0x48 [color=#9D968E] + LayoutFlexibleBox {DIV} at (0,22) size 0x4 + layer at (298,211) size 12x4 + LayoutBlockFlow (relative positioned) {DIV} at (0,0) size 12x4 [bgcolor=#00000033] + LayoutBlockFlow {DIV} at (0,-4) size 12x12 [bgcolor=#000000DE] + layer at (298,211) size 12x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 12x4 + layer at (298,211) size 0x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 0x4 [bgcolor=#000000DE] + layer at (298,211) size 12x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 12x4 [bgcolor=#0000008A]
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/media/video-display-toggle-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/media/video-display-toggle-expected.txt index a0e0e37..85686e2 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/media/video-display-toggle-expected.txt +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/media/video-display-toggle-expected.txt
@@ -16,31 +16,43 @@ LayoutNGBlockFlow (positioned) {DIV} at (0,0) size 320x240 layer at (8,28) size 320x240 LayoutFlexibleBox {DIV} at (0,0) size 320x240 -layer at (8,28) size 320x224 clip at (10,30) size 316x220 - LayoutButton (relative positioned) {INPUT} at (0,0) size 320x224 [border: (2px outset #C0C0C0)] - LayoutFlexibleBox (anonymous) at (8,82) size 304x60 - LayoutBlockFlow {DIV} at (122,0) size 60x60 [bgcolor=#FFFFFFE6] -layer at (8,204) size 320x48 - LayoutFlexibleBox (relative positioned) {DIV} at (0,176) size 320x48 - LayoutNGBlockFlow {DIV} at (16,0) size 31x48 [color=#FFFFFF] - LayoutText {#text} at (0,15) size 31x18 - text run at (0,15) width 31: "0:00" - LayoutNGBlockFlow {DIV} at (51,0) size 39x48 [color=#FFFFFF] - LayoutText {#text} at (0,15) size 39x18 - text run at (0,15) width 39: "/ 0:06" - LayoutNGBlockFlow {DIV} at (90,48) size 134x0 +layer at (118,86) size 100x100 + LayoutButton (positioned) {INPUT} at (110,58) size 100x100 + LayoutBlockFlow (anonymous) at (20,20) size 60x60 + LayoutBlockFlow {DIV} at (0,0) size 60x60 [bgcolor=#FFFFFFE6] +layer at (8,196) size 320x48 + LayoutFlexibleBox (relative positioned) {DIV} at (0,168) size 320x48 + LayoutNGBlockFlow {DIV} at (16,4) size 28x44 [color=#FFFFFF] + LayoutText {#text} at (0,14) size 28x16 + text run at (0,14) width 28: "0:00" + LayoutNGBlockFlow {DIV} at (48,4) size 36x44 [color=#FFFFFF] + LayoutText {#text} at (0,14) size 36x16 + text run at (0,14) width 36: "/ 0:06" + LayoutNGBlockFlow {DIV} at (84,48) size 140x0 LayoutButton {INPUT} at (224,0) size 48x48 LayoutButton {INPUT} at (272,0) size 48x48 -layer at (8,252) size 320x16 - LayoutSlider {INPUT} at (0,224) size 320x16 [color=#9D968E] - LayoutFlexibleBox {DIV} at (16,0) size 288x4 -layer at (24,252) size 288x4 - LayoutBlockFlow (relative positioned) {DIV} at (0,0) size 288x4 [bgcolor=#FFFFFF4D] -layer at (24,248) size 12x12 - LayoutBlockFlow (relative positioned) {DIV} at (0,-4) size 12x12 [bgcolor=#FFFFFF] -layer at (24,252) size 288x4 - LayoutBlockFlow (positioned) {DIV} at (0,0) size 288x4 -layer at (24,252) size 0x4 +layer at (232,196) size 0x48 transparent + LayoutSlider {INPUT} at (224,0) size 0x48 [color=#9D968E] + LayoutFlexibleBox {DIV} at (0,22) size 0x4 +layer at (232,218) size 12x4 + LayoutBlockFlow (relative positioned) {DIV} at (0,0) size 12x4 [bgcolor=#FFFFFF4D] + LayoutBlockFlow {DIV} at (0,-4) size 12x12 [bgcolor=#FFFFFF] +layer at (232,218) size 12x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 12x4 +layer at (232,218) size 0x4 LayoutBlockFlow (positioned) {DIV} at (0,0) size 0x4 [bgcolor=#FFFFFF] -layer at (24,252) size 288x4 +layer at (232,218) size 12x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 12x4 [bgcolor=#FFFFFF8A] +layer at (8,244) size 320x24 + LayoutSlider {INPUT} at (0,216) size 320x24 [color=#9D968E] + LayoutFlexibleBox {DIV} at (16,0) size 288x4 +layer at (24,244) size 288x4 + LayoutBlockFlow (relative positioned) {DIV} at (0,0) size 288x4 [bgcolor=#FFFFFF4D] +layer at (24,240) size 12x12 + LayoutBlockFlow (relative positioned) {DIV} at (0,-4) size 12x12 [bgcolor=#FFFFFF] +layer at (24,244) size 288x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 288x4 +layer at (24,244) size 0x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 0x4 [bgcolor=#FFFFFF] +layer at (24,244) size 288x4 LayoutBlockFlow (positioned) {DIV} at (0,0) size 288x4 [bgcolor=#FFFFFF8A]
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/media/video-layer-crash-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/media/video-layer-crash-expected.txt index c8e1f04a..20665a7 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/media/video-layer-crash-expected.txt +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/media/video-layer-crash-expected.txt
@@ -18,15 +18,15 @@ LayoutBR {BR} at (210,322) size 0x19 layer at (12,64) size 206x156 LayoutVideo {VIDEO} at (4,20) size 206x156 [border: (3px solid #FF0000)] -layer at (15,67) size 200x150 backgroundClip at (65,105) size 100x75 clip at (65,105) size 100x75 +layer at (65,105) size 100x75 LayoutFlexibleBox (relative positioned) {DIV} at (3,3) size 200x150 LayoutFlexibleBox {DIV} at (0,0) size 200x150 -layer at (15,67) size 200x150 backgroundClip at (65,105) size 100x75 clip at (65,105) size 100x75 +layer at (65,105) size 100x75 LayoutNGBlockFlow (positioned) {DIV} at (0,0) size 200x150 layer at (12,225) size 206x156 LayoutVideo {VIDEO} at (4,181) size 206x156 [border: (3px solid #FF0000)] -layer at (15,228) size 200x150 +layer at (-12,228) size 254x150 backgroundClip at (0,228) size 242x150 clip at (0,228) size 242x150 LayoutFlexibleBox (relative positioned) {DIV} at (3,3) size 200x150 LayoutFlexibleBox {DIV} at (0,0) size 200x150 -layer at (15,228) size 200x150 +layer at (-12,228) size 254x150 backgroundClip at (0,228) size 242x150 clip at (0,228) size 242x150 LayoutNGBlockFlow (positioned) {DIV} at (0,0) size 200x150
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/transforms/3d/hit-testing/backface-no-transform-hit-test-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/transforms/3d/hit-testing/backface-no-transform-hit-test-expected.txt index 8178bf2..698f6001 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/transforms/3d/hit-testing/backface-no-transform-hit-test-expected.txt +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/transforms/3d/hit-testing/backface-no-transform-hit-test-expected.txt
@@ -18,11 +18,11 @@ LayoutText {#text} at (197,32) size 4x19 text run at (197,32) width 4: " " LayoutText {#text} at (0,0) size 0x0 -layer at (27,63) size 160x160 +layer at (231,63) size 160x160 LayoutNGBlockFlow (relative positioned) {DIV} at (19,19) size 160x160 [bgcolor=#808080] LayoutText {#text} at (48,0) size 64x36 text run at (48,0) width 64: "box1" -layer at (227,63) size 160x160 +layer at (31,63) size 160x160 LayoutNGBlockFlow (relative positioned) {DIV} at (219,19) size 160x160 [bgcolor=#808080] LayoutText {#text} at (48,0) size 64x36 text run at (48,0) width 64: "box2"
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/transforms/3d/point-mapping/3d-point-mapping-deep-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/transforms/3d/point-mapping/3d-point-mapping-deep-expected.txt deleted file mode 100644 index 324feb6..0000000 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/transforms/3d/point-mapping/3d-point-mapping-deep-expected.txt +++ /dev/null
@@ -1,56 +0,0 @@ -layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 810 - LayoutView at (0,0) size 800x600 -layer at (0,0) size 785x600 - LayoutNGBlockFlow {HTML} at (0,0) size 785x600 - LayoutNGBlockFlow {BODY} at (0,0) size 785x600 [border: (1px solid #000000)] - LayoutNGBlockFlow {DIV} at (21,21) size 402x402 [border: (1px solid #000000)] - LayoutText {#text} at (0,0) size 0x0 -layer at (42,42) size 340x340 - LayoutNGBlockFlow {DIV} at (21,21) size 340x340 [bgcolor=#DDDDDD] [border: (1px solid #000000)] -layer at (63,63) size 300x300 - LayoutNGBlockFlow {DIV} at (21,21) size 300x300 [bgcolor=#81AA8A] [border: (1px solid #000000)] -layer at (104,104) size 300x300 - LayoutNGBlockFlow {DIV} at (41,41) size 300x300 [border: (1px solid #000000)] -layer at (145,145) size 300x300 - LayoutNGBlockFlow {DIV} at (41,41) size 300x300 [bgcolor=#AA7994] [border: (1px solid #000000)] -layer at (186,186) size 300x300 - LayoutNGBlockFlow {DIV} at (41,41) size 300x300 [border: (1px solid #000000)] -layer at (227,227) size 300x300 - LayoutNGBlockFlow {DIV} at (41,41) size 300x300 [bgcolor=#81AA8A] [border: (1px solid #000000)] -layer at (268,268) size 300x300 - LayoutNGBlockFlow {DIV} at (41,41) size 300x300 [border: (1px solid #000000)] - LayoutNGBlockFlow {DIV} at (61,61) size 90x90 [bgcolor=#0000FF] -layer at (30,650) size 345x160 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600 - LayoutNGBlockFlow (positioned) {DIV} at (30,650) size 345x160 - LayoutInline {SPAN} at (0,0) size 297x19 [color=#008000] - LayoutText {#text} at (0,0) size 297x19 - text run at (0,0) width 297: "PASS: event at (45, 45) hit box1 at offset (2, 2)" - LayoutBR {BR} at (297,15) size 0x0 - LayoutInline {SPAN} at (0,0) size 297x19 [color=#008000] - LayoutText {#text} at (0,20) size 297x19 - text run at (0,20) width 297: "PASS: event at (54, 44) hit box2 at offset (1, 1)" - LayoutBR {BR} at (297,35) size 0x0 - LayoutInline {SPAN} at (0,0) size 305x19 [color=#008000] - LayoutText {#text} at (0,40) size 305x19 - text run at (0,40) width 305: "PASS: event at (104, 93) hit box3 at offset (1, 1)" - LayoutBR {BR} at (305,55) size 0x0 - LayoutInline {SPAN} at (0,0) size 313x19 [color=#008000] - LayoutText {#text} at (0,60) size 313x19 - text run at (0,60) width 313: "PASS: event at (175, 137) hit box4 at offset (1, 1)" - LayoutBR {BR} at (313,75) size 0x0 - LayoutInline {SPAN} at (0,0) size 329x19 [color=#008000] - LayoutText {#text} at (0,80) size 329x19 - text run at (0,80) width 329: "PASS: event at (167, 528) hit box4 at offset (1, 295)" - LayoutBR {BR} at (329,95) size 0x0 - LayoutInline {SPAN} at (0,0) size 313x19 [color=#008000] - LayoutText {#text} at (0,100) size 313x19 - text run at (0,100) width 313: "PASS: event at (227, 197) hit box5 at offset (1, 1)" - LayoutBR {BR} at (313,115) size 0x0 - LayoutInline {SPAN} at (0,0) size 345x19 [color=#008000] - LayoutText {#text} at (0,120) size 345x19 - text run at (0,120) width 345: "PASS: event at (539, 569) hit box7 at offset (295, 295)" - LayoutBR {BR} at (345,135) size 0x0 - LayoutInline {SPAN} at (0,0) size 329x19 [color=#008000] - LayoutText {#text} at (0,140) size 329x19 - text run at (0,140) width 329: "PASS: event at (431, 441) hit box8 at offset (85, 85)" - LayoutBR {BR} at (329,155) size 0x0
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/transforms/3d/point-mapping/3d-point-mapping-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/transforms/3d/point-mapping/3d-point-mapping-expected.txt deleted file mode 100644 index 156fa48..0000000 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/transforms/3d/point-mapping/3d-point-mapping-expected.txt +++ /dev/null
@@ -1,73 +0,0 @@ -layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 680 - LayoutView at (0,0) size 800x600 -layer at (0,0) size 785x600 - LayoutNGBlockFlow {HTML} at (0,0) size 785x600 - LayoutNGBlockFlow {BODY} at (0,0) size 785x600 [border: (1px solid #000000)] -layer at (30,500) size 337x180 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600 - LayoutNGBlockFlow (positioned) {DIV} at (30,500) size 337x180 - LayoutInline {SPAN} at (0,0) size 297x19 [color=#008000] - LayoutText {#text} at (0,0) size 297x19 - text run at (0,0) width 297: "PASS: event at (44, 44) hit box1 at offset (1, 1)" - LayoutBR {BR} at (297,15) size 0x0 - LayoutInline {SPAN} at (0,0) size 297x19 [color=#008000] - LayoutText {#text} at (0,20) size 297x19 - text run at (0,20) width 297: "PASS: event at (69, 55) hit box2 at offset (1, 1)" - LayoutBR {BR} at (297,35) size 0x0 - LayoutInline {SPAN} at (0,0) size 329x19 [color=#008000] - LayoutText {#text} at (0,40) size 329x19 - text run at (0,40) width 329: "PASS: event at (165, 182) hit box2 at offset (95, 95)" - LayoutBR {BR} at (329,55) size 0x0 - LayoutInline {SPAN} at (0,0) size 305x19 [color=#008000] - LayoutText {#text} at (0,60) size 305x19 - text run at (0,60) width 305: "PASS: event at (333, 79) hit box7 at offset (1, 1)" - LayoutBR {BR} at (305,75) size 0x0 - LayoutInline {SPAN} at (0,0) size 313x19 [color=#008000] - LayoutText {#text} at (0,80) size 313x19 - text run at (0,80) width 313: "PASS: event at (87, 325) hit box10 at offset (1, 1)" - LayoutBR {BR} at (313,95) size 0x0 - LayoutInline {SPAN} at (0,0) size 337x19 [color=#008000] - LayoutText {#text} at (0,100) size 337x19 - text run at (0,100) width 337: "PASS: event at (196, 467) hit box10 at offset (97, 97)" - LayoutBR {BR} at (337,115) size 0x0 - LayoutInline {SPAN} at (0,0) size 321x19 [color=#008000] - LayoutText {#text} at (0,120) size 321x19 - text run at (0,120) width 321: "PASS: event at (333, 325) hit box13 at offset (1, 1)" - LayoutBR {BR} at (321,135) size 0x0 - LayoutInline {SPAN} at (0,0) size 321x19 [color=#008000] - LayoutText {#text} at (0,140) size 321x19 - text run at (0,140) width 321: "PASS: event at (353, 352) hit box14 at offset (1, 1)" - LayoutBR {BR} at (321,155) size 0x0 - LayoutInline {SPAN} at (0,0) size 337x19 [color=#008000] - LayoutText {#text} at (0,160) size 337x19 - text run at (0,160) width 337: "PASS: event at (472, 507) hit box14 at offset (96, 96)" - LayoutBR {BR} at (337,175) size 0x0 -layer at (21,21) size 202x202 - LayoutNGBlockFlow (positioned) {DIV} at (21,21) size 202x202 [border: (1px solid #000000)] -layer at (42,42) size 140x140 - LayoutNGBlockFlow {DIV} at (21,21) size 140x140 [bgcolor=#DDDDDD] [border: (1px solid #000000)] -layer at (63,63) size 100x100 - LayoutNGBlockFlow (relative positioned) {DIV} at (21,21) size 100x100 [bgcolor=#AAAAAA] [border: (1px solid #000000)] -layer at (267,21) size 202x202 - LayoutNGBlockFlow (positioned) {DIV} at (267,21) size 202x202 [border: (1px solid #000000)] -layer at (288,42) size 140x140 - LayoutNGBlockFlow {DIV} at (21,21) size 140x140 [bgcolor=#DDDDDD] [border: (1px solid #000000)] -layer at (309,63) size 100x100 - LayoutNGBlockFlow (relative positioned) {DIV} at (21,21) size 100x100 [bgcolor=#AAAAAA] [border: (1px solid #000000)] - LayoutNGBlockFlow {DIV} at (21,21) size 100x100 [bgcolor=#0000FF] [border: (1px solid #000000)] -layer at (21,267) size 202x202 - LayoutNGBlockFlow (positioned) {DIV} at (21,267) size 202x202 [border: (1px solid #000000)] -layer at (42,288) size 140x140 - LayoutNGBlockFlow {DIV} at (21,21) size 140x140 [bgcolor=#DDDDDD] [border: (1px solid #000000)] -layer at (63,309) size 100x100 - LayoutNGBlockFlow (relative positioned) {DIV} at (21,21) size 100x100 [bgcolor=#AAAAAA] [border: (1px solid #000000)] -layer at (84,330) size 100x100 - LayoutNGBlockFlow (relative positioned) {DIV} at (21,21) size 100x100 [bgcolor=#0000FF] [border: (1px solid #000000)] -layer at (267,267) size 202x202 - LayoutNGBlockFlow (positioned) {DIV} at (267,267) size 202x202 [border: (1px solid #000000)] -layer at (288,288) size 140x140 - LayoutNGBlockFlow {DIV} at (21,21) size 140x140 [bgcolor=#DDDDDD] [border: (1px solid #000000)] -layer at (309,309) size 100x100 - LayoutNGBlockFlow (relative positioned) {DIV} at (21,21) size 100x100 [bgcolor=#AAAAAA] [border: (1px solid #000000)] - LayoutNGBlockFlow {DIV} at (21,21) size 100x100 [bgcolor=#C0D69E] [border: (1px solid #000000)] -layer at (351,351) size 100x100 - LayoutNGBlockFlow (relative positioned) {DIV} at (21,21) size 100x100 [bgcolor=#0000FF] [border: (1px solid #000000)]
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/transforms/3d/point-mapping/3d-point-mapping-origins-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/transforms/3d/point-mapping/3d-point-mapping-origins-expected.txt index ede809ef..568deda 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/transforms/3d/point-mapping/3d-point-mapping-origins-expected.txt +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/transforms/3d/point-mapping/3d-point-mapping-origins-expected.txt
@@ -65,12 +65,12 @@ LayoutNGBlockFlow {DIV} at (21,21) size 140x140 [bgcolor=#DDDDDD] [border: (1px solid #000000)] layer at (63,310) size 100x100 LayoutNGBlockFlow (relative positioned) {DIV} at (21,21) size 100x100 [bgcolor=#AAAAAA] [border: (1px solid #000000)] -layer at (84,331) size 100x100 +layer at (88,282) size 136x170 LayoutNGBlockFlow (relative positioned) {DIV} at (21,21) size 100x100 [bgcolor=#0000FF] [border: (1px solid #000000)] layer at (288,289) size 140x140 LayoutNGBlockFlow {DIV} at (21,21) size 140x140 [bgcolor=#DDDDDD] [border: (1px solid #000000)] layer at (309,310) size 100x100 LayoutNGBlockFlow (relative positioned) {DIV} at (21,21) size 100x100 [bgcolor=#AAAAAA] [border: (1px solid #000000)] LayoutNGBlockFlow {DIV} at (21,21) size 100x100 [bgcolor=#C0D69E] [border: (1px solid #000000)] -layer at (351,352) size 100x100 +layer at (358,313) size 150x180 LayoutNGBlockFlow (relative positioned) {DIV} at (21,21) size 100x100 [bgcolor=#0000FF] [border: (1px solid #000000)]
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/transforms/3d/point-mapping/3d-point-mapping-overlapping-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/transforms/3d/point-mapping/3d-point-mapping-overlapping-expected.txt deleted file mode 100644 index 0abc557a..0000000 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/transforms/3d/point-mapping/3d-point-mapping-overlapping-expected.txt +++ /dev/null
@@ -1,38 +0,0 @@ -layer at (0,0) size 800x600 - LayoutView at (0,0) size 800x600 -layer at (0,0) size 800x600 - LayoutNGBlockFlow {HTML} at (0,0) size 800x600 - LayoutNGBlockFlow {BODY} at (0,0) size 800x600 [border: (1px solid #000000)] - LayoutNGBlockFlow (anonymous) at (1,1) size 798x342 - LayoutText {#text} at (0,0) size 0x0 - LayoutNGBlockFlow {P} at (1,359) size 798x20 - LayoutText {#text} at (0,0) size 602x19 - text run at (0,0) width 602: "The green overlay is translated in Z by 100px, so should hit test in front relative to the blue box." -layer at (30,400) size 343x80 - LayoutNGBlockFlow (positioned) {DIV} at (30,400) size 343x80 - LayoutInline {SPAN} at (0,0) size 321x19 [color=#008000] - LayoutText {#text} at (0,0) size 321x19 - text run at (0,0) width 321: "PASS: event at (285, 50) hit box2 at offset (197, 1)" - LayoutBR {BR} at (321,15) size 0x0 - LayoutInline {SPAN} at (0,0) size 321x19 [color=#008000] - LayoutText {#text} at (0,20) size 321x19 - text run at (0,20) width 321: "PASS: event at (174, 108) hit box3 at offset (50, 2)" - LayoutBR {BR} at (321,35) size 0x0 - LayoutInline {SPAN} at (0,0) size 328x19 [color=#008000] - LayoutText {#text} at (0,40) size 328x19 - text run at (0,40) width 328: "PASS: event at (61, 50) hit overlay at offset (39, 28)" - LayoutBR {BR} at (328,55) size 0x0 - LayoutInline {SPAN} at (0,0) size 343x19 [color=#008000] - LayoutText {#text} at (0,60) size 343x19 - text run at (0,60) width 343: "PASS: event at (119, 108) hit overlay at offset (97, 86)" - LayoutBR {BR} at (343,75) size 0x0 -layer at (21,21) size 302x302 - LayoutNGBlockFlow (relative positioned) {DIV} at (20,20) size 302x302 [border: (1px solid #000000)] -layer at (42,42) size 260x260 - LayoutNGBlockFlow (positioned) {DIV} at (21,21) size 260x260 [bgcolor=#DDDDDD] [border: (1px solid #000000)] -layer at (73,63) size 200x200 - LayoutNGBlockFlow (positioned) {DIV} at (31,21) size 200x200 [bgcolor=#AAAAAA] [border: (1px solid #000000)] -layer at (124,114) size 100x100 - LayoutNGBlockFlow (relative positioned) {DIV} at (51,51) size 100x100 [bgcolor=#0000FF] -layer at (22,22) size 150x300 - LayoutNGBlockFlow (positioned) {DIV} at (1,1) size 150x300 [bgcolor=#0080004D]
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/transforms/3d/point-mapping/3d-point-mapping-preserve-3d-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/transforms/3d/point-mapping/3d-point-mapping-preserve-3d-expected.txt deleted file mode 100644 index d0e61d0..0000000 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/transforms/3d/point-mapping/3d-point-mapping-preserve-3d-expected.txt +++ /dev/null
@@ -1,124 +0,0 @@ -layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 840 - LayoutView at (0,0) size 800x600 -layer at (0,0) size 785x600 - LayoutNGBlockFlow {HTML} at (0,0) size 785x600 - LayoutNGBlockFlow {BODY} at (0,0) size 785x600 [border: (1px solid #000000)] -layer at (30,500) size 337x340 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600 - LayoutNGBlockFlow (positioned) {DIV} at (30,500) size 337x340 - LayoutInline {SPAN} at (0,0) size 297x19 [color=#008000] - LayoutText {#text} at (0,0) size 297x19 - text run at (0,0) width 297: "PASS: event at (44, 44) hit box1 at offset (1, 1)" - LayoutBR {BR} at (297,15) size 0x0 - LayoutInline {SPAN} at (0,0) size 297x19 [color=#008000] - LayoutText {#text} at (0,20) size 297x19 - text run at (0,20) width 297: "PASS: event at (74, 68) hit box2 at offset (1, 1)" - LayoutBR {BR} at (297,35) size 0x0 - LayoutInline {SPAN} at (0,0) size 329x19 [color=#008000] - LayoutText {#text} at (0,40) size 329x19 - text run at (0,40) width 329: "PASS: event at (157, 164) hit box2 at offset (97, 97)" - LayoutBR {BR} at (329,55) size 0x0 - LayoutInline {SPAN} at (0,0) size 305x19 [color=#008000] - LayoutText {#text} at (0,60) size 305x19 - text run at (0,60) width 305: "PASS: event at (320, 68) hit box4 at offset (1, 1)" - LayoutBR {BR} at (305,75) size 0x0 - LayoutInline {SPAN} at (0,0) size 305x19 [color=#008000] - LayoutText {#text} at (0,80) size 305x19 - text run at (0,80) width 305: "PASS: event at (336, 87) hit box5 at offset (1, 1)" - LayoutBR {BR} at (305,95) size 0x0 - LayoutInline {SPAN} at (0,0) size 305x19 [color=#008000] - LayoutText {#text} at (0,100) size 305x19 - text run at (0,100) width 305: "PASS: event at (582, 87) hit box8 at offset (1, 1)" - LayoutBR {BR} at (305,115) size 0x0 - LayoutInline {SPAN} at (0,0) size 329x19 [color=#008000] - LayoutText {#text} at (0,120) size 329x19 - text run at (0,120) width 329: "PASS: event at (658, 174) hit box8 at offset (85, 85)" - LayoutBR {BR} at (329,135) size 0x0 - LayoutInline {SPAN} at (0,0) size 313x19 [color=#008000] - LayoutText {#text} at (0,140) size 313x19 - text run at (0,140) width 313: "PASS: event at (74, 314) hit box10 at offset (1, 1)" - LayoutBR {BR} at (313,155) size 0x0 - LayoutInline {SPAN} at (0,0) size 312x19 [color=#008000] - LayoutText {#text} at (0,160) size 312x19 - text run at (0,160) width 312: "PASS: event at (91, 351) hit box11 at offset (1, 1)" - LayoutBR {BR} at (312,175) size 0x0 - LayoutInline {SPAN} at (0,0) size 321x19 [color=#008000] - LayoutText {#text} at (0,180) size 321x19 - text run at (0,180) width 321: "PASS: event at (320, 314) hit box13 at offset (1, 1)" - LayoutBR {BR} at (321,195) size 0x0 - LayoutInline {SPAN} at (0,0) size 321x19 [color=#008000] - LayoutText {#text} at (0,200) size 321x19 - text run at (0,200) width 321: "PASS: event at (343, 351) hit box14 at offset (1, 1)" - LayoutBR {BR} at (321,215) size 0x0 - LayoutInline {SPAN} at (0,0) size 321x19 [color=#008000] - LayoutText {#text} at (0,220) size 321x19 - text run at (0,220) width 321: "PASS: event at (365, 375) hit box15 at offset (1, 1)" - LayoutBR {BR} at (321,235) size 0x0 - LayoutInline {SPAN} at (0,0) size 321x19 [color=#008000] - LayoutText {#text} at (0,240) size 321x19 - text run at (0,240) width 321: "PASS: event at (566, 314) hit box17 at offset (1, 1)" - LayoutBR {BR} at (321,255) size 0x0 - LayoutInline {SPAN} at (0,0) size 321x19 [color=#008000] - LayoutText {#text} at (0,260) size 321x19 - text run at (0,260) width 321: "PASS: event at (587, 352) hit box18 at offset (1, 1)" - LayoutBR {BR} at (321,275) size 0x0 - LayoutInline {SPAN} at (0,0) size 321x19 [color=#008000] - LayoutText {#text} at (0,280) size 321x19 - text run at (0,280) width 321: "PASS: event at (629, 401) hit box19 at offset (1, 1)" - LayoutBR {BR} at (321,295) size 0x0 - LayoutInline {SPAN} at (0,0) size 321x19 [color=#008000] - LayoutText {#text} at (0,300) size 321x19 - text run at (0,300) width 321: "PASS: event at (653, 422) hit box20 at offset (1, 1)" - LayoutBR {BR} at (321,315) size 0x0 - LayoutInline {SPAN} at (0,0) size 337x19 [color=#008000] - LayoutText {#text} at (0,320) size 337x19 - text run at (0,320) width 337: "PASS: event at (745, 505) hit box20 at offset (85, 86)" - LayoutBR {BR} at (337,335) size 0x0 -layer at (21,21) size 202x202 - LayoutNGBlockFlow (positioned) {DIV} at (21,21) size 202x202 [border: (1px solid #000000)] -layer at (42,42) size 140x140 - LayoutNGBlockFlow {DIV} at (21,21) size 140x140 [bgcolor=#DDDDDD] [border: (1px solid #000000)] -layer at (63,63) size 100x100 - LayoutNGBlockFlow (relative positioned) {DIV} at (21,21) size 100x100 [bgcolor=#81AA8A] [border: (1px solid #000000)] -layer at (267,21) size 202x202 - LayoutNGBlockFlow (positioned) {DIV} at (267,21) size 202x202 [border: (1px solid #000000)] -layer at (288,42) size 140x140 - LayoutNGBlockFlow {DIV} at (21,21) size 140x140 [bgcolor=#DDDDDD] [border: (1px solid #000000)] -layer at (309,63) size 100x100 - LayoutNGBlockFlow (relative positioned) {DIV} at (21,21) size 100x100 [bgcolor=#81AA8A] [border: (1px solid #000000)] - LayoutNGBlockFlow {DIV} at (21,21) size 90x90 [bgcolor=#0000FF] [border: (1px solid #000000)] -layer at (513,21) size 202x202 - LayoutNGBlockFlow (positioned) {DIV} at (513,21) size 202x202 [border: (1px solid #000000)] -layer at (534,42) size 140x140 - LayoutNGBlockFlow {DIV} at (21,21) size 140x140 [bgcolor=#DDDDDD] [border: (1px solid #000000)] -layer at (555,63) size 100x100 - LayoutNGBlockFlow (relative positioned) {DIV} at (21,21) size 100x100 [bgcolor=#81AA8A] [border: (1px solid #000000)] -layer at (576,84) size 90x90 - LayoutNGBlockFlow (relative positioned) {DIV} at (21,21) size 90x90 [bgcolor=#0000FF] [border: (1px solid #000000)] -layer at (21,267) size 202x202 - LayoutNGBlockFlow (positioned) {DIV} at (21,267) size 202x202 [border: (1px solid #000000)] -layer at (42,288) size 140x140 - LayoutNGBlockFlow {DIV} at (21,21) size 140x140 [bgcolor=#DDDDDD] [border: (1px solid #000000)] -layer at (63,309) size 100x100 - LayoutNGBlockFlow (relative positioned) {DIV} at (21,21) size 100x100 [bgcolor=#81AA8A] [border: (1px solid #000000)] -layer at (104,350) size 100x100 - LayoutNGBlockFlow (relative positioned) {DIV} at (41,41) size 100x100 [border: (1px solid #000000)] -layer at (267,267) size 202x202 - LayoutNGBlockFlow (positioned) {DIV} at (267,267) size 202x202 [border: (1px solid #000000)] -layer at (288,288) size 140x140 - LayoutNGBlockFlow {DIV} at (21,21) size 140x140 [bgcolor=#DDDDDD] [border: (1px solid #000000)] -layer at (309,309) size 100x100 - LayoutNGBlockFlow (relative positioned) {DIV} at (21,21) size 100x100 [bgcolor=#81AA8A] [border: (1px solid #000000)] -layer at (350,350) size 100x100 - LayoutNGBlockFlow (relative positioned) {DIV} at (41,41) size 100x100 [border: (1px solid #000000)] - LayoutNGBlockFlow {DIV} at (21,21) size 90x90 [bgcolor=#0000FF] [border: (1px solid #000000)] -layer at (513,267) size 202x202 - LayoutNGBlockFlow (positioned) {DIV} at (513,267) size 202x202 [border: (1px solid #000000)] -layer at (534,288) size 140x140 - LayoutNGBlockFlow {DIV} at (21,21) size 140x140 [bgcolor=#DDDDDD] [border: (1px solid #000000)] -layer at (555,309) size 100x100 - LayoutNGBlockFlow (relative positioned) {DIV} at (21,21) size 100x100 [bgcolor=#81AA8A] [border: (1px solid #000000)] -layer at (596,350) size 100x100 - LayoutNGBlockFlow (relative positioned) {DIV} at (41,41) size 100x100 [border: (1px solid #000000)] -layer at (637,391) size 100x100 - LayoutNGBlockFlow (relative positioned) {DIV} at (41,41) size 100x100 [bgcolor=#AA7994] [border: (1px solid #000000)] - LayoutNGBlockFlow {DIV} at (21,21) size 90x90 [bgcolor=#0000FF] [border: (1px solid #000000)]
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/transforms/svg-vs-css-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/transforms/svg-vs-css-expected.txt deleted file mode 100644 index ec949727..0000000 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/transforms/svg-vs-css-expected.txt +++ /dev/null
@@ -1,66 +0,0 @@ -layer at (0,0) size 800x600 - LayoutView at (0,0) size 800x600 -layer at (0,0) size 800x580 - LayoutNGBlockFlow {html} at (0,0) size 800x579.63 - LayoutNGBlockFlow {body} at (8,8) size 784x563.63 - LayoutNGBlockFlow {div} at (10,10) size 220x543.63 - LayoutNGBlockFlow {h2} at (0,19.91) size 220x27 - LayoutText {#text} at (0,0) size 120x26 - text run at (0,0) width 120: "SVG nested" - LayoutNGBlockFlow {h2} at (0,286.72) size 220x27 - LayoutText {#text} at (0,0) size 114x26 - text run at (0,0) width 114: "CSS nested" - LayoutText {#text} at (240,0) size 4x19 - text run at (240,0) width 4: " " - LayoutNGBlockFlow {div} at (254,10) size 220x543.63 - LayoutNGBlockFlow {h2} at (0,19.91) size 220x27 - LayoutText {#text} at (0,0) size 162x26 - text run at (0,0) width 162: "SVG compound" - LayoutNGBlockFlow {h2} at (0,286.72) size 220x27 - LayoutText {#text} at (0,0) size 156x26 - text run at (0,0) width 156: "CSS compound" - LayoutText {#text} at (484,0) size 4x19 - text run at (484,0) width 4: " " - LayoutNGBlockFlow {div} at (498,10) size 220x543.63 - LayoutNGBlockFlow {h2} at (0,19.91) size 220x27 - LayoutText {#text} at (0,0) size 128x26 - text run at (0,0) width 128: "SVG Matrix" - LayoutNGBlockFlow {h2} at (0,286.72) size 220x27 - LayoutText {#text} at (0,0) size 116x26 - text run at (0,0) width 116: "CSSMatrix" - LayoutText {#text} at (0,0) size 0x0 -layer at (28,85) size 200x200 - LayoutNGBlockFlow (relative positioned) {div} at (10,66.81) size 200x200 [bgcolor=#C0C0C0] [border: (1px solid #000000)] - LayoutSVGRoot {svg} at (1,1) size 200x200 - LayoutSVGContainer {g} at (-84.85,0) size 204.85x169.71 [transform={m=((1.00,0.00)(0.00,1.00)) t=(75.00,25.00)}] - LayoutSVGRect {rect} at (0,0) size 60x60 [stroke={[type=SOLID] [color=#000000] [dash array=[1.00, 1.00]]}] [x=0.00] [y=0.00] [width=60.00] [height=60.00] - LayoutSVGContainer {g} at (-42.43,0) size 102.43x84.85 [transform={m=((2.00,0.00)(0.00,2.00)) t=(0.00,0.00)}] - LayoutSVGRect {rect} at (0,0) size 60x60 [stroke={[type=SOLID] [color=#000000] [dash array=[1.00, 1.00]]}] [x=0.00] [y=0.00] [width=60.00] [height=60.00] - LayoutSVGRect {rect} at (0,0) size 60x60 [transform={m=((0.71,0.71)(-0.71,0.71)) t=(0.00,0.00)}] [stroke={[type=SOLID] [color=#0000FF]}] [x=0.00] [y=0.00] [width=60.00] [height=60.00] - LayoutText {#text} at (0,0) size 0x0 -layer at (28,352) size 200x200 - LayoutNGBlockFlow (relative positioned) {div} at (10,333.63) size 200x200 [bgcolor=#C0C0C0] [border: (1px solid #000000)] -layer at (29,353) size 60x60 - LayoutNGBlockFlow (positioned) {div} at (1,1) size 60x60 [border: (1px dotted #000000)] -layer at (105,379) size 60x60 - LayoutNGBlockFlow (positioned) {div} at (1,1) size 60x60 [border: (1px dotted #000000)] -layer at (31,355) size 60x60 - LayoutNGBlockFlow (positioned) {div} at (1,1) size 60x60 [border: (1px solid #0000FF)] -layer at (272,85) size 200x200 - LayoutNGBlockFlow (relative positioned) {div} at (10,66.81) size 200x200 [bgcolor=#C0C0C0] [border: (1px solid #000000)] - LayoutSVGRoot {svg} at (1,1) size 200x200 - LayoutSVGRect {rect} at (0,0) size 60x60 [transform={m=((1.41,1.41)(-1.41,1.41)) t=(75.00,25.00)}] [stroke={[type=SOLID] [color=#0000FF]}] [x=0.00] [y=0.00] [width=60.00] [height=60.00] - LayoutText {#text} at (0,0) size 0x0 -layer at (272,352) size 200x200 - LayoutNGBlockFlow (relative positioned) {div} at (10,333.63) size 200x200 [bgcolor=#C0C0C0] [border: (1px solid #000000)] -layer at (273,353) size 60x60 - LayoutNGBlockFlow (positioned) {div} at (1,1) size 60x60 [border: (1px solid #0000FF)] -layer at (516,85) size 200x200 - LayoutNGBlockFlow (relative positioned) {div} at (10,66.81) size 200x200 [bgcolor=#C0C0C0] [border: (1px solid #000000)] - LayoutSVGRoot {svg} at (1,1) size 200x200 - LayoutSVGRect {rect} at (0,0) size 60x60 [transform={m=((1.41,1.41)(-1.41,1.41)) t=(75.00,25.00)}] [stroke={[type=SOLID] [color=#0000FF]}] [x=0.00] [y=0.00] [width=60.00] [height=60.00] - LayoutText {#text} at (0,0) size 0x0 -layer at (516,352) size 200x200 - LayoutNGBlockFlow (relative positioned) {div} at (10,333.63) size 200x200 [bgcolor=#C0C0C0] [border: (1px solid #000000)] -layer at (517,353) size 60x60 - LayoutNGBlockFlow (positioned) {div} at (1,1) size 60x60 [border: (1px solid #0000FF)]
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/mouseevent_fractional/fast/events/popup-allowed-from-gesture-initiated-event-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/mouseevent_fractional/fast/events/popup-allowed-from-gesture-initiated-event-expected.txt deleted file mode 100644 index 50f1454..0000000 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/mouseevent_fractional/fast/events/popup-allowed-from-gesture-initiated-event-expected.txt +++ /dev/null
@@ -1,7 +0,0 @@ -Click Here Click Here Too -PASS win is non-null. -PASS successfullyParsed is true - -TEST COMPLETE -PASS win is non-null. -
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/video-surface-layer/media/audio-controls-rendering-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/video-surface-layer/media/audio-controls-rendering-expected.txt index 610087a..d480650 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/video-surface-layer/media/audio-controls-rendering-expected.txt +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/video-surface-layer/media/audio-controls-rendering-expected.txt
@@ -44,6 +44,18 @@ LayoutBlockFlow (positioned) {DIV} at (0,0) size 0x4 [bgcolor=#000000DE] layer at (139,69) size 111x4 LayoutBlockFlow (positioned) {DIV} at (0,0) size 111x4 [bgcolor=#0000008A] +layer at (266,47) size 0x48 transparent + LayoutSlider {INPUT} at (258,3) size 0x48 [color=#9D968E] + LayoutFlexibleBox {DIV} at (0,22) size 0x4 +layer at (266,69) size 12x4 + LayoutBlockFlow (relative positioned) {DIV} at (0,0) size 12x4 [bgcolor=#00000033] + LayoutBlockFlow {DIV} at (0,-4) size 12x12 [bgcolor=#000000DE] +layer at (266,69) size 12x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 12x4 +layer at (266,69) size 0x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 0x4 [bgcolor=#000000DE] +layer at (266,69) size 12x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 12x4 [bgcolor=#0000008A] layer at (8,118) size 320x54 LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 320x54 layer at (8,118) size 320x54 @@ -72,6 +84,18 @@ LayoutBlockFlow (positioned) {DIV} at (0,0) size 0x4 [bgcolor=#000000DE] layer at (139,143) size 131x4 LayoutBlockFlow (positioned) {DIV} at (0,0) size 131x4 [bgcolor=#0000008A] +layer at (286,121) size 0x48 transparent + LayoutSlider {INPUT} at (278,3) size 0x48 [color=#9D968E] + LayoutFlexibleBox {DIV} at (0,22) size 0x4 +layer at (286,143) size 12x4 + LayoutBlockFlow (relative positioned) {DIV} at (0,0) size 12x4 [bgcolor=#00000033] + LayoutBlockFlow {DIV} at (0,-4) size 12x12 [bgcolor=#000000DE] +layer at (286,143) size 12x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 12x4 +layer at (286,143) size 0x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 0x4 [bgcolor=#000000DE] +layer at (286,143) size 12x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 12x4 [bgcolor=#0000008A] layer at (8,192) size 320x100 LayoutMedia (positioned) {AUDIO} at (8,192) size 320x100 [bgcolor=#0000FF] layer at (8,192) size 320x100 @@ -102,3 +126,15 @@ LayoutBlockFlow (positioned) {DIV} at (0,0) size 0x4 [bgcolor=#000000DE] layer at (139,263) size 131x4 LayoutBlockFlow (positioned) {DIV} at (0,0) size 131x4 [bgcolor=#0000008A] +layer at (286,241) size 0x48 transparent + LayoutSlider {INPUT} at (278,3) size 0x48 [color=#9D968E] + LayoutFlexibleBox {DIV} at (0,22) size 0x4 +layer at (286,263) size 12x4 + LayoutBlockFlow (relative positioned) {DIV} at (0,0) size 12x4 [bgcolor=#00000033] + LayoutBlockFlow {DIV} at (0,-4) size 12x12 [bgcolor=#000000DE] +layer at (286,263) size 12x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 12x4 +layer at (286,263) size 0x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 0x4 [bgcolor=#000000DE] +layer at (286,263) size 12x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 12x4 [bgcolor=#0000008A]
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/video-surface-layer/media/media-document-audio-repaint-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/video-surface-layer/media/media-document-audio-repaint-expected.txt index c48d0b8..f014079 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/video-surface-layer/media/media-document-audio-repaint-expected.txt +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/video-surface-layer/media/media-document-audio-repaint-expected.txt
@@ -46,3 +46,15 @@ LayoutBlockFlow (positioned) {DIV} at (0,0) size 55x4 [bgcolor=#000000DE] layer at (226,211) size 55x4 LayoutBlockFlow (positioned) {DIV} at (55,0) size 55x4 [bgcolor=#0000008A] + layer at (298,189) size 0x48 transparent + LayoutSlider {INPUT} at (258,3) size 0x48 [color=#9D968E] + LayoutFlexibleBox {DIV} at (0,22) size 0x4 + layer at (298,211) size 12x4 + LayoutBlockFlow (relative positioned) {DIV} at (0,0) size 12x4 [bgcolor=#00000033] + LayoutBlockFlow {DIV} at (0,-4) size 12x12 [bgcolor=#000000DE] + layer at (298,211) size 12x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 12x4 + layer at (298,211) size 0x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 0x4 [bgcolor=#000000DE] + layer at (298,211) size 12x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 12x4 [bgcolor=#0000008A]
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/video-surface-layer/media/video-aspect-ratio-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/video-surface-layer/media/video-aspect-ratio-expected.png index b007d07..2d641c3 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/video-surface-layer/media/video-aspect-ratio-expected.png +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/video-surface-layer/media/video-aspect-ratio-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/video-surface-layer/media/video-display-toggle-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/video-surface-layer/media/video-display-toggle-expected.txt index d2234a46..8f97261 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/video-surface-layer/media/video-display-toggle-expected.txt +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/video-surface-layer/media/video-display-toggle-expected.txt
@@ -16,32 +16,44 @@ LayoutNGBlockFlow (positioned) {DIV} at (0,0) size 320x240 layer at (8,28) size 320x240 LayoutFlexibleBox {DIV} at (0,0) size 320x240 -layer at (8,28) size 320x224 clip at (10,30) size 316x220 - LayoutButton (relative positioned) {INPUT} at (0,0) size 320x224 [border: (2px outset #C0C0C0)] - LayoutFlexibleBox (anonymous) at (8,82) size 304x60 - LayoutBlockFlow {DIV} at (122,0) size 60x60 [bgcolor=#FFFFFFE6] -layer at (8,204) size 320x48 - LayoutFlexibleBox (relative positioned) {DIV} at (0,176) size 320x48 - LayoutNGBlockFlow {DIV} at (16,0) size 31x48 [color=#FFFFFF] - LayoutText {#text} at (0,15) size 31x18 - text run at (0,15) width 31: "0:00" - LayoutNGBlockFlow {DIV} at (51,0) size 39x48 [color=#FFFFFF] - LayoutText {#text} at (0,15) size 39x18 - text run at (0,15) width 39: "/ 0:06" - LayoutNGBlockFlow {DIV} at (90,48) size 86x0 +layer at (118,86) size 100x100 + LayoutButton (positioned) {INPUT} at (110,58) size 100x100 + LayoutBlockFlow (anonymous) at (20,20) size 60x60 + LayoutBlockFlow {DIV} at (0,0) size 60x60 [bgcolor=#FFFFFFE6] +layer at (8,196) size 320x48 + LayoutFlexibleBox (relative positioned) {DIV} at (0,168) size 320x48 + LayoutNGBlockFlow {DIV} at (16,4) size 28x44 [color=#FFFFFF] + LayoutText {#text} at (0,14) size 28x16 + text run at (0,14) width 28: "0:00" + LayoutNGBlockFlow {DIV} at (48,4) size 36x44 [color=#FFFFFF] + LayoutText {#text} at (0,14) size 36x16 + text run at (0,14) width 36: "/ 0:06" + LayoutNGBlockFlow {DIV} at (84,48) size 92x0 LayoutButton {INPUT} at (176,0) size 48x48 LayoutButton {INPUT} at (224,0) size 48x48 LayoutButton {INPUT} at (272,0) size 48x48 -layer at (8,252) size 320x16 - LayoutSlider {INPUT} at (0,224) size 320x16 [color=#9D968E] - LayoutFlexibleBox {DIV} at (16,0) size 288x4 -layer at (24,252) size 288x4 - LayoutBlockFlow (relative positioned) {DIV} at (0,0) size 288x4 [bgcolor=#FFFFFF4D] -layer at (24,248) size 12x12 - LayoutBlockFlow (relative positioned) {DIV} at (0,-4) size 12x12 [bgcolor=#FFFFFF] -layer at (24,252) size 288x4 - LayoutBlockFlow (positioned) {DIV} at (0,0) size 288x4 -layer at (24,252) size 0x4 +layer at (184,196) size 0x48 transparent + LayoutSlider {INPUT} at (176,0) size 0x48 [color=#9D968E] + LayoutFlexibleBox {DIV} at (0,22) size 0x4 +layer at (184,218) size 12x4 + LayoutBlockFlow (relative positioned) {DIV} at (0,0) size 12x4 [bgcolor=#FFFFFF4D] + LayoutBlockFlow {DIV} at (0,-4) size 12x12 [bgcolor=#FFFFFF] +layer at (184,218) size 12x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 12x4 +layer at (184,218) size 0x4 LayoutBlockFlow (positioned) {DIV} at (0,0) size 0x4 [bgcolor=#FFFFFF] -layer at (24,252) size 288x4 +layer at (184,218) size 12x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 12x4 [bgcolor=#FFFFFF8A] +layer at (8,244) size 320x24 + LayoutSlider {INPUT} at (0,216) size 320x24 [color=#9D968E] + LayoutFlexibleBox {DIV} at (16,0) size 288x4 +layer at (24,244) size 288x4 + LayoutBlockFlow (relative positioned) {DIV} at (0,0) size 288x4 [bgcolor=#FFFFFF4D] +layer at (24,240) size 12x12 + LayoutBlockFlow (relative positioned) {DIV} at (0,-4) size 12x12 [bgcolor=#FFFFFF] +layer at (24,244) size 288x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 288x4 +layer at (24,244) size 0x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 0x4 [bgcolor=#FFFFFF] +layer at (24,244) size 288x4 LayoutBlockFlow (positioned) {DIV} at (0,0) size 288x4 [bgcolor=#FFFFFF8A]
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/video-surface-layer/media/video-layer-crash-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/video-surface-layer/media/video-layer-crash-expected.txt deleted file mode 100644 index c8e1f04a..0000000 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/video-surface-layer/media/video-layer-crash-expected.txt +++ /dev/null
@@ -1,32 +0,0 @@ -layer at (0,0) size 800x600 - LayoutView at (0,0) size 800x600 -layer at (0,0) size 800x600 - LayoutNGBlockFlow {HTML} at (0,0) size 800x600 - LayoutNGBlockFlow {BODY} at (8,8) size 784x584 - LayoutNGBlockFlow {P} at (0,0) size 784x20 - LayoutText {#text} at (0,0) size 359x19 - text run at (0,0) width 359: "Test dynamic removal of transformed and reflected video" - LayoutNGBlockFlow (anonymous) at (0,36) size 784x342 - LayoutText {#text} at (0,0) size 4x19 - text run at (0,0) width 4: " " - LayoutBR {BR} at (4,0) size 0x19 - LayoutText {#text} at (0,161) size 4x19 - text run at (0,161) width 4: " " - LayoutBR {BR} at (210,161) size 0x19 - LayoutText {#text} at (0,322) size 4x19 - text run at (0,322) width 4: " " - LayoutBR {BR} at (210,322) size 0x19 -layer at (12,64) size 206x156 - LayoutVideo {VIDEO} at (4,20) size 206x156 [border: (3px solid #FF0000)] -layer at (15,67) size 200x150 backgroundClip at (65,105) size 100x75 clip at (65,105) size 100x75 - LayoutFlexibleBox (relative positioned) {DIV} at (3,3) size 200x150 - LayoutFlexibleBox {DIV} at (0,0) size 200x150 -layer at (15,67) size 200x150 backgroundClip at (65,105) size 100x75 clip at (65,105) size 100x75 - LayoutNGBlockFlow (positioned) {DIV} at (0,0) size 200x150 -layer at (12,225) size 206x156 - LayoutVideo {VIDEO} at (4,181) size 206x156 [border: (3px solid #FF0000)] -layer at (15,228) size 200x150 - LayoutFlexibleBox (relative positioned) {DIV} at (3,3) size 200x150 - LayoutFlexibleBox {DIV} at (0,0) size 200x150 -layer at (15,228) size 200x150 - LayoutNGBlockFlow (positioned) {DIV} at (0,0) size 200x150
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/sandbox-iframe-blocks-top-navigation-to-javascript.html b/third_party/WebKit/LayoutTests/http/tests/security/sandbox-iframe-blocks-top-navigation-to-javascript.html index 9cc1ea2..46672e782 100644 --- a/third_party/WebKit/LayoutTests/http/tests/security/sandbox-iframe-blocks-top-navigation-to-javascript.html +++ b/third_party/WebKit/LayoutTests/http/tests/security/sandbox-iframe-blocks-top-navigation-to-javascript.html
@@ -12,10 +12,12 @@ "<a href='javascript:top.location=\"/security/frameNavigation/resources/fail.html\";'>click</a>"; window.onmessage = t.step_func_done(e => { - // It was a SecurityError, but the error event got sanitized to - // "Script error." because the frames are cross-origin. - // See also: https://bugzilla.mozilla.org/show_bug.cgi?id=363897 - assert_equals(e.data, "Script error.", "The 'javascript:' navigation threw."); + const expected = + "Uncaught SecurityError: Failed to set the 'href' " + + "property on 'Location': The current window does not " + + "have permission to navigate the target frame to " + + "'/security/frameNavigation/resources/fail.html'."; + assert_equals(e.data, expected, "The 'javascript:' navigation threw."); assert_equals(i.contentDocument.body.innerText, "click", "The page contents did not change."); });
diff --git a/third_party/WebKit/LayoutTests/webexposed/custom-elements-expected.txt b/third_party/WebKit/LayoutTests/webexposed/custom-elements-expected.txt index 0c67a68..5c0642b 100644 --- a/third_party/WebKit/LayoutTests/webexposed/custom-elements-expected.txt +++ b/third_party/WebKit/LayoutTests/webexposed/custom-elements-expected.txt
@@ -1,3 +1,4 @@ +CONSOLE WARNING: line 1: :unresolved pseudo selector is deprecated and will be removed in M73, around March 2019. Please use :not(:defined) instead. See https://www.chromestatus.com/features/4642138092470272 for more details. Tests basic web-exposure of Custom Elements On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
diff --git a/third_party/blink/public/platform/platform.h b/third_party/blink/public/platform/platform.h index ead1da6..8dfa718 100644 --- a/third_party/blink/public/platform/platform.h +++ b/third_party/blink/public/platform/platform.h
@@ -447,7 +447,7 @@ // Create and initialize the compositor thread. The thread is saved in // Platform, and will be accessible through CompositorThread(). - void InitializeCompositorThread(const WebThreadCreationParams&); + void InitializeCompositorThread(); // Returns an interface to the current thread. WebThread* CurrentThread(); @@ -459,6 +459,17 @@ // renderer was created with threaded rendering disabled. WebThread* CompositorThread(); + // Returns the task runner of the compositor thread. This is available + // once InitializeCompositorThread() is called. + scoped_refptr<base::SingleThreadTaskRunner> CompositorThreadTaskRunner(); + + // This is called after the compositor thread is created, so the embedder + // can initiate an IPC to change its thread priority (on Linux we can't + // increase the nice value, so we need to ask the browser process). This + // function is only called from the main thread (where InitializeCompositor- + // Thread() is called). + virtual void SetDisplayThreadPriority(base::PlatformThreadId) {} + // Returns a blame context for attributing top-level work which does not // belong to a particular frame scope. virtual BlameContext* GetTopLevelBlameContext() { return nullptr; }
diff --git a/third_party/blink/renderer/bindings/core/v8/activity_logger_test.cc b/third_party/blink/renderer/bindings/core/v8/activity_logger_test.cc index 7489233f..a20c1a6 100644 --- a/third_party/blink/renderer/bindings/core/v8/activity_logger_test.cc +++ b/third_party/blink/renderer/bindings/core/v8/activity_logger_test.cc
@@ -96,8 +96,7 @@ void ExecuteScriptInIsolatedWorld(const String& script) const { v8::HandleScope scope(v8::Isolate::GetCurrent()); script_controller_->ExecuteScriptInIsolatedWorld( - kIsolatedWorldId, ScriptSourceCode(script), KURL(), - kNotSharableCrossOrigin); + kIsolatedWorldId, ScriptSourceCode(script), KURL(), kOpaqueResource); PumpPendingRequestsForFrameToLoad(web_view_helper_.LocalMainFrame()); }
diff --git a/third_party/blink/renderer/bindings/core/v8/scheduled_action.cc b/third_party/blink/renderer/bindings/core/v8/scheduled_action.cc index 45e783b..bb38f953 100644 --- a/third_party/blink/renderer/bindings/core/v8/scheduled_action.cc +++ b/third_party/blink/renderer/bindings/core/v8/scheduled_action.cc
@@ -170,11 +170,15 @@ } else { DVLOG(1) << "ScheduledAction::execute " << this << ": executing from source"; + // We're using |kSharableCrossOrigin| to keep the existing behavior, but + // this causes failures on + // wpt/html/webappapis/scripting/processing-model-2/compile-error-cross-origin-setTimeout.html + // and friends. frame->GetScriptController().ExecuteScriptAndReturnValue( script_state_->GetContext(), ScriptSourceCode(code_, ScriptSourceLocationType::kEvalForScheduledAction), - KURL(), kNotSharableCrossOrigin); + KURL(), kSharableCrossOrigin); } // The frame might be invalid at this point because JavaScript could have @@ -206,10 +210,14 @@ function, worker, script_state_->GetContext()->Global(), info.size(), info.data(), script_state_->GetIsolate()); } else { + // We're using |kSharableCrossOrigin| to keep the existing behavior, but + // this causes failures on + // wpt/html/webappapis/scripting/processing-model-2/compile-error-cross-origin-setTimeout.html + // and friends. worker->ScriptController()->Evaluate( ScriptSourceCode(code_, ScriptSourceLocationType::kEvalForScheduledAction), - kNotSharableCrossOrigin); + kSharableCrossOrigin); } }
diff --git a/third_party/blink/renderer/bindings/core/v8/script_controller.cc b/third_party/blink/renderer/bindings/core/v8/script_controller.cc index 8a0bb55b..9132487 100644 --- a/third_party/blink/renderer/bindings/core/v8/script_controller.cc +++ b/third_party/blink/renderer/bindings/core/v8/script_controller.cc
@@ -251,9 +251,10 @@ // Step 12.9 "Let script be result of creating a classic script given script // source, settings, base URL, and the default classic script fetch options." // [spec text] + // We pass |kSharableCrossOrigin| because |muted errors| is false by default. v8::Local<v8::Value> result = EvaluateScriptInMainWorld( ScriptSourceCode(script_source, ScriptSourceLocationType::kJavascriptUrl), - base_url, kNotSharableCrossOrigin, ScriptFetchOptions(), + base_url, kSharableCrossOrigin, ScriptFetchOptions(), kDoNotExecuteScriptWhenScriptsDisabled); // If executing script caused this frame to be removed from the page, we @@ -285,8 +286,8 @@ ExecuteScriptPolicy policy) { v8::HandleScope handle_scope(GetIsolate()); EvaluateScriptInMainWorld(ScriptSourceCode(script, source_location_type), - KURL(), kNotSharableCrossOrigin, - ScriptFetchOptions(), policy); + KURL(), kOpaqueResource, ScriptFetchOptions(), + policy); } void ScriptController::ExecuteScriptInMainWorld(
diff --git a/third_party/blink/renderer/bindings/core/v8/script_module_test.cc b/third_party/blink/renderer/bindings/core/v8/script_module_test.cc index 6fe37339..2390b8d8 100644 --- a/third_party/blink/renderer/bindings/core/v8/script_module_test.cc +++ b/third_party/blink/renderer/bindings/core/v8/script_module_test.cc
@@ -282,7 +282,7 @@ scope.GetFrame() .GetScriptController() .ExecuteScriptInMainWorldAndReturnValue( - ScriptSourceCode("window.foo"), KURL(), kNotSharableCrossOrigin); + ScriptSourceCode("window.foo"), KURL(), kOpaqueResource); ASSERT_TRUE(value->IsString()); EXPECT_EQ("bar", ToCoreString(v8::Local<v8::String>::Cast(value)));
diff --git a/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer_test.cc b/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer_test.cc index 15fa392..8e3f5480 100644 --- a/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer_test.cc +++ b/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer_test.cc
@@ -106,8 +106,7 @@ v8::Local<v8::Value> Eval(const String& source, V8TestingScope& scope) { return scope.GetFrame() .GetScriptController() - .ExecuteScriptInMainWorldAndReturnValue(source, KURL(), - kNotSharableCrossOrigin); + .ExecuteScriptInMainWorldAndReturnValue(source, KURL(), kOpaqueResource); } String ToJSON(v8::Local<v8::Object> object, const V8TestingScope& scope) {
diff --git a/third_party/blink/renderer/bindings/core/v8/v8_initializer.cc b/third_party/blink/renderer/bindings/core/v8/v8_initializer.cc index 4dbd097..716d8437 100644 --- a/third_party/blink/renderer/bindings/core/v8/v8_initializer.cc +++ b/third_party/blink/renderer/bindings/core/v8/v8_initializer.cc
@@ -262,11 +262,8 @@ return; } - AccessControlStatus access_control_status = kNotSharableCrossOrigin; - if (message->IsOpaque()) - access_control_status = kOpaqueResource; - else if (message->IsSharedCrossOrigin()) - access_control_status = kSharableCrossOrigin; + AccessControlStatus access_control_status = + message->IsSharedCrossOrigin() ? kSharableCrossOrigin : kOpaqueResource; ErrorEvent* event = ErrorEvent::Create( ToCoreStringWithNullCheck(message->Get()), std::move(location), @@ -313,15 +310,14 @@ ToCoreStringWithNullCheck(message->Get()), std::move(location), ScriptValue::From(script_state, data), &script_state->World()); - AccessControlStatus cors_status = message->IsSharedCrossOrigin() - ? kSharableCrossOrigin - : kNotSharableCrossOrigin; + AccessControlStatus access_control_status = + message->IsSharedCrossOrigin() ? kSharableCrossOrigin : kOpaqueResource; // If execution termination has been triggered as part of constructing // the error event from the v8::Message, quietly leave. if (!isolate->IsExecutionTerminating()) { ExecutionContext::From(script_state) - ->DispatchErrorEvent(event, cors_status); + ->DispatchErrorEvent(event, access_control_status); } per_isolate_data->SetReportingException(false); @@ -374,7 +370,7 @@ } String error_message; - AccessControlStatus cors_status = kNotSharableCrossOrigin; + AccessControlStatus cors_status = kOpaqueResource; std::unique_ptr<SourceLocation> location; v8::Local<v8::Message> message =
diff --git a/third_party/blink/renderer/bindings/core/v8/v8_lazy_event_listener.cc b/third_party/blink/renderer/bindings/core/v8/v8_lazy_event_listener.cc index 5f00ae29..2ff1bde 100644 --- a/third_party/blink/renderer/bindings/core/v8/v8_lazy_event_listener.cc +++ b/third_party/blink/renderer/bindings/core/v8/v8_lazy_event_listener.cc
@@ -218,11 +218,13 @@ SourceLocation::FromMessage(GetIsolate(), message, execution_context), &World()); - AccessControlStatus access_control_status = kNotSharableCrossOrigin; + AccessControlStatus access_control_status = kOpaqueResource; if (message->IsOpaque()) access_control_status = kOpaqueResource; else if (message->IsSharedCrossOrigin()) access_control_status = kSharableCrossOrigin; + else + NOTREACHED(); execution_context->DispatchErrorEvent(event, access_control_status); }
diff --git a/third_party/blink/renderer/bindings/core/v8/v8_script_runner_test.cc b/third_party/blink/renderer/bindings/core/v8/v8_script_runner_test.cc index 0f989bb0..edbdba2 100644 --- a/third_party/blink/renderer/bindings/core/v8/v8_script_runner_test.cc +++ b/third_party/blink/renderer/bindings/core/v8/v8_script_runner_test.cc
@@ -63,7 +63,7 @@ std::tie(compile_options, produce_cache_options, no_cache_reason) = V8CodeCache::GetCompileOptions(cache_options, source_code); v8::MaybeLocal<v8::Script> compiled_script = V8ScriptRunner::CompileScript( - script_state, source_code, kNotSharableCrossOrigin, compile_options, + script_state, source_code, kOpaqueResource, compile_options, no_cache_reason, ReferrerScriptInfo()); if (compiled_script.IsEmpty()) { return false; @@ -81,7 +81,7 @@ v8::ScriptCompiler::NoCacheReason no_cache_reason, V8CodeCache::ProduceCacheOptions produce_cache_options) { v8::MaybeLocal<v8::Script> compiled_script = V8ScriptRunner::CompileScript( - script_state, source_code, kNotSharableCrossOrigin, compile_options, + script_state, source_code, kOpaqueResource, compile_options, no_cache_reason, ReferrerScriptInfo()); if (compiled_script.IsEmpty()) { return false;
diff --git a/third_party/blink/renderer/core/core_export.h b/third_party/blink/renderer/core/core_export.h index 24af246f..0ccb042 100644 --- a/third_party/blink/renderer/core/core_export.h +++ b/third_party/blink/renderer/core/core_export.h
@@ -3,7 +3,7 @@ // found in the LICENSE file. // This header defines macros to export component's symbols. -// See "platform/PlatformExport.h" for details. +// See "platform/platform_export.h" for details. #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_CORE_EXPORT_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_CORE_EXPORT_H_
diff --git a/third_party/blink/renderer/core/css/BUILD.gn b/third_party/blink/renderer/core/css/BUILD.gn index 2a21dc8..f67c313 100644 --- a/third_party/blink/renderer/core/css/BUILD.gn +++ b/third_party/blink/renderer/core/css/BUILD.gn
@@ -848,6 +848,8 @@ "resolver/css_property_priority.h", "resolver/css_to_style_map.cc", "resolver/css_to_style_map.h", + "resolver/css_variable_animator.cc", + "resolver/css_variable_animator.h", "resolver/css_variable_resolver.cc", "resolver/css_variable_resolver.h", "resolver/element_resolve_context.cc",
diff --git a/third_party/blink/renderer/core/css/parser/css_selector_parser.cc b/third_party/blink/renderer/core/css/parser/css_selector_parser.cc index c6994ea..5431ec0 100644 --- a/third_party/blink/renderer/core/css/parser/css_selector_parser.cc +++ b/third_party/blink/renderer/core/css/parser/css_selector_parser.cc
@@ -1160,10 +1160,8 @@ break; } if (feature != WebFeature::kNumberOfFeatures) { - if (!Deprecation::DeprecationMessage(feature).IsEmpty() && - style_sheet_ && style_sheet_->AnyOwnerDocument()) { - Deprecation::CountDeprecation(*style_sheet_->AnyOwnerDocument(), - feature); + if (!Deprecation::DeprecationMessage(feature).IsEmpty()) { + context_->CountDeprecation(feature); } else { context_->Count(feature); }
diff --git a/third_party/blink/renderer/core/css/resolver/css_variable_animator.cc b/third_party/blink/renderer/core/css/resolver/css_variable_animator.cc new file mode 100644 index 0000000..04f05610 --- /dev/null +++ b/third_party/blink/renderer/core/css/resolver/css_variable_animator.cc
@@ -0,0 +1,84 @@ +// 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/core/css/resolver/css_variable_animator.h" + +#include "third_party/blink/renderer/core/animation/css_interpolation_environment.h" +#include "third_party/blink/renderer/core/animation/css_interpolation_types_map.h" +#include "third_party/blink/renderer/core/animation/invalidatable_interpolation.h" +#include "third_party/blink/renderer/core/animation/transition_interpolation.h" + +namespace blink { + +namespace { + +HashSet<PropertyHandle> CollectPending(const CSSAnimationUpdate& update) { + HashSet<PropertyHandle> pending; + for (const auto& entry : update.ActiveInterpolationsForCustomAnimations()) + pending.insert(entry.key); + for (const auto& entry : update.ActiveInterpolationsForCustomTransitions()) + pending.insert(entry.key); + return pending; +} + +const ActiveInterpolations& ActiveInterpolationsForCustomProperty( + const CSSAnimationUpdate& update, + const PropertyHandle& property) { + // Interpolations will never be found in both animations_map and + // transitions_map. This condition is ensured by + // CSSAnimations::CalculateTransitionUpdateForProperty(). + const ActiveInterpolationsMap& animations_map = + update.ActiveInterpolationsForCustomAnimations(); + const ActiveInterpolationsMap& transitions_map = + update.ActiveInterpolationsForCustomTransitions(); + const auto& animation = animations_map.find(property); + if (animation != animations_map.end()) { + DCHECK_EQ(transitions_map.find(property), transitions_map.end()); + return animation->value; + } + const auto& transition = transitions_map.find(property); + DCHECK_NE(transition, transitions_map.end()); + return transition->value; +} + +} // namespace + +CSSVariableAnimator::CSSVariableAnimator(StyleResolverState& state) + : CSSVariableResolver(state), + state_(state), + update_(state.AnimationUpdate()), + pending_properties_(CollectPending(update_)) {} + +void CSSVariableAnimator::ApplyAll() { + while (!pending_properties_.IsEmpty()) { + PropertyHandle property = *pending_properties_.begin(); + Apply(property); + DCHECK_EQ(pending_properties_.find(property), pending_properties_.end()); + } +} + +void CSSVariableAnimator::ApplyAnimation(const AtomicString& name) { + PropertyHandle property(name); + if (pending_properties_.Contains(property)) + Apply(property); +} + +void CSSVariableAnimator::Apply(const PropertyHandle& property) { + DCHECK(property.IsCSSCustomProperty()); + DCHECK(pending_properties_.Contains(property)); + const ActiveInterpolations& interpolations = + ActiveInterpolationsForCustomProperty(update_, property); + const Interpolation& interpolation = *interpolations.front(); + if (interpolation.IsInvalidatableInterpolation()) { + CSSInterpolationTypesMap map(state_.GetDocument().GetPropertyRegistry(), + state_.GetDocument()); + CSSInterpolationEnvironment environment(map, state_, this); + InvalidatableInterpolation::ApplyStack(interpolations, environment); + } else { + ToTransitionInterpolation(interpolation).Apply(state_); + } + pending_properties_.erase(property); +} + +} // namespace blink
diff --git a/third_party/blink/renderer/core/css/resolver/css_variable_animator.h b/third_party/blink/renderer/core/css/resolver/css_variable_animator.h new file mode 100644 index 0000000..6a284da --- /dev/null +++ b/third_party/blink/renderer/core/css/resolver/css_variable_animator.h
@@ -0,0 +1,49 @@ +// 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_CORE_CSS_RESOLVER_CSS_VARIABLE_ANIMATOR_H_ +#define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_RESOLVER_CSS_VARIABLE_ANIMATOR_H_ + +#include "third_party/blink/renderer/core/animation/interpolation.h" +#include "third_party/blink/renderer/core/animation/property_handle.h" +#include "third_party/blink/renderer/core/css/resolver/css_variable_resolver.h" + +namespace blink { + +class StyleResolverState; +class CSSAnimationUpdate; + +// CSSVariableAnimator is a special CSSVariableResolver which can apply +// animated values during var()-resolution. In other words, it makes sure that +// if a var()-reference to a currently animating custom property is encountered, +// we will first apply the animated value for that property before resolving it. +class CORE_EXPORT CSSVariableAnimator : public CSSVariableResolver { + STACK_ALLOCATED(); + + public: + explicit CSSVariableAnimator(StyleResolverState&); + + // Apply all custom property animations. After calling this, the set of + // pending properties will be empty and further calls to ApplyAll will have + // no effect. + void ApplyAll(); + + protected: + void ApplyAnimation(const AtomicString&) override; + + private: + // Apply the animated value of a single property. The property must exist + // in 'pending_properties_'. + void Apply(const PropertyHandle&); + + StyleResolverState& state_; + const CSSAnimationUpdate& update_; + // Set of custom properties with pending animations. We will apply these + // one by one until the set is empty. + HashSet<PropertyHandle> pending_properties_; +}; + +} // namespace blink + +#endif // CSSVariableAnimator
diff --git a/third_party/blink/renderer/core/css/resolver/css_variable_resolver.cc b/third_party/blink/renderer/core/css/resolver/css_variable_resolver.cc index 769dc7d..57172354 100644 --- a/third_party/blink/renderer/core/css/resolver/css_variable_resolver.cc +++ b/third_party/blink/renderer/core/css/resolver/css_variable_resolver.cc
@@ -329,20 +329,14 @@ range.ConsumeIncludingWhitespace().Value().ToAtomicString(); DCHECK(range.AtEnd() || (range.Peek().GetType() == kCommaToken)); - PropertyHandle property(variable_name); - if (state_.AnimationPendingCustomProperties().Contains(property) && - !variables_seen_.Contains(variable_name)) { - // We make the StyleResolverState mutable for animated custom properties as - // an optimisation. Without this we would need to compute animated values on - // the stack without saving the result or perform an expensive and complex - // value dependency graph analysis to compute them in the required order. - StyleResolver::ApplyAnimatedCustomProperty( - const_cast<StyleResolverState&>(state_), *this, property); + if (!variables_seen_.Contains(variable_name)) { + ApplyAnimation(variable_name); // Null custom property storage may become non-null after application, we // must refresh these cached values. inherited_variables_ = state_.Style()->InheritedVariables(); non_inherited_variables_ = state_.Style()->NonInheritedVariables(); } + scoped_refptr<CSSVariableData> variable_data = is_env_variable ? ValueForEnvironmentVariable(variable_name) : ValueForCustomProperty(variable_name, options);
diff --git a/third_party/blink/renderer/core/css/resolver/css_variable_resolver.h b/third_party/blink/renderer/core/css/resolver/css_variable_resolver.h index 8815821..d748138 100644 --- a/third_party/blink/renderer/core/css/resolver/css_variable_resolver.h +++ b/third_party/blink/renderer/core/css/resolver/css_variable_resolver.h
@@ -33,7 +33,7 @@ STACK_ALLOCATED(); public: - CSSVariableResolver(const StyleResolverState&); + explicit CSSVariableResolver(const StyleResolverState&); scoped_refptr<CSSVariableData> ResolveCustomPropertyAnimationKeyframe( const CSSCustomPropertyDeclaration& keyframe, @@ -48,6 +48,11 @@ void ComputeRegisteredVariables(); + protected: + // Called before looking up the value of some var()-reference to make it + // possible to apply animated properties during variable resolution. + virtual void ApplyAnimation(const AtomicString& name) {} + private: struct Options { STACK_ALLOCATED();
diff --git a/third_party/blink/renderer/core/css/resolver/style_resolver.cc b/third_party/blink/renderer/core/css/resolver/style_resolver.cc index 183a581..86bdf2b 100644 --- a/third_party/blink/renderer/core/css/resolver/style_resolver.cc +++ b/third_party/blink/renderer/core/css/resolver/style_resolver.cc
@@ -61,6 +61,7 @@ #include "third_party/blink/renderer/core/css/part_names.h" #include "third_party/blink/renderer/core/css/properties/css_property.h" #include "third_party/blink/renderer/core/css/resolver/animated_style_builder.h" +#include "third_party/blink/renderer/core/css/resolver/css_variable_animator.h" #include "third_party/blink/renderer/core/css/resolver/css_variable_resolver.h" #include "third_party/blink/renderer/core/css/resolver/match_result.h" #include "third_party/blink/renderer/core/css/resolver/media_query_result.h" @@ -1084,70 +1085,6 @@ } } -static void ApplyAnimatedCustomProperties(StyleResolverState& state) { - if (!state.IsAnimatingCustomProperties()) { - return; - } - CSSAnimationUpdate& update = state.AnimationUpdate(); - HashSet<PropertyHandle>& pending = state.AnimationPendingCustomProperties(); - DCHECK(pending.IsEmpty()); - for (const auto& interpolations : - {update.ActiveInterpolationsForCustomAnimations(), - update.ActiveInterpolationsForCustomTransitions()}) { - for (const auto& entry : interpolations) { - pending.insert(entry.key); - } - } - while (!pending.IsEmpty()) { - PropertyHandle property = *pending.begin(); - CSSVariableResolver variable_resolver(state); - StyleResolver::ApplyAnimatedCustomProperty(state, variable_resolver, - property); - // The property must no longer be pending after applying it. - DCHECK_EQ(pending.find(property), pending.end()); - } -} - -static const ActiveInterpolations& ActiveInterpolationsForCustomProperty( - const StyleResolverState& state, - const PropertyHandle& property) { - // Interpolations will never be found in both animations_map and - // transitions_map. This condition is ensured by - // CSSAnimations::CalculateTransitionUpdateForProperty(). - const ActiveInterpolationsMap& animations_map = - state.AnimationUpdate().ActiveInterpolationsForCustomAnimations(); - const ActiveInterpolationsMap& transitions_map = - state.AnimationUpdate().ActiveInterpolationsForCustomTransitions(); - const auto& animation = animations_map.find(property); - if (animation != animations_map.end()) { - DCHECK_EQ(transitions_map.find(property), transitions_map.end()); - return animation->value; - } - const auto& transition = transitions_map.find(property); - DCHECK_NE(transition, transitions_map.end()); - return transition->value; -} - -void StyleResolver::ApplyAnimatedCustomProperty( - StyleResolverState& state, - CSSVariableResolver& variable_resolver, - const PropertyHandle& property) { - DCHECK(property.IsCSSCustomProperty()); - DCHECK(state.AnimationPendingCustomProperties().Contains(property)); - const ActiveInterpolations& interpolations = - ActiveInterpolationsForCustomProperty(state, property); - const Interpolation& interpolation = *interpolations.front(); - if (interpolation.IsInvalidatableInterpolation()) { - CSSInterpolationTypesMap map(state.GetDocument().GetPropertyRegistry(), - state.GetDocument()); - CSSInterpolationEnvironment environment(map, state, &variable_resolver); - InvalidatableInterpolation::ApplyStack(interpolations, environment); - } else { - ToTransitionInterpolation(interpolation).Apply(state); - } - state.AnimationPendingCustomProperties().erase(property); -} - bool StyleResolver::ApplyAnimatedStandardProperties( StyleResolverState& state, const Element* animating_element) { @@ -1238,9 +1175,8 @@ void StyleResolver::ApplyAnimatedStandardProperties( StyleResolverState& state, const ActiveInterpolationsMap& active_interpolations_map) { - static_assert( - priority != kResolveVariables, - "Use applyAnimatedCustomProperty() for custom property animations"); + static_assert(priority != kResolveVariables, + "Use CSSVariableAnimator for custom property animations"); // TODO(alancutter): Don't apply presentation attribute animations here, // they should instead apply in // SVGElement::CollectStyleForPresentationAttribute(). @@ -1744,8 +1680,9 @@ CSSVariableResolver(state).ComputeRegisteredVariables(); - if (apply_animations == kIncludeAnimations) { - ApplyAnimatedCustomProperties(state); + if (apply_animations == kIncludeAnimations && + state.IsAnimatingCustomProperties()) { + CSSVariableAnimator(state).ApplyAll(); } }
diff --git a/third_party/blink/renderer/core/css/resolver/style_resolver.h b/third_party/blink/renderer/core/css/resolver/style_resolver.h index b3e6ff84..f300fa31 100644 --- a/third_party/blink/renderer/core/css/resolver/style_resolver.h +++ b/third_party/blink/renderer/core/css/resolver/style_resolver.h
@@ -52,7 +52,6 @@ class RuleSet; class CSSPropertyValueSet; class StyleRuleUsageTracker; -class CSSVariableResolver; enum RuleMatchingBehavior { kMatchAllRules, kMatchAllRulesExcludingSMIL }; @@ -136,10 +135,6 @@ void SetRuleUsageTracker(StyleRuleUsageTracker*); void UpdateMediaType(); - static void ApplyAnimatedCustomProperty(StyleResolverState&, - CSSVariableResolver&, - const PropertyHandle&); - static bool HasAuthorBackground(const StyleResolverState&); void Trace(blink::Visitor*);
diff --git a/third_party/blink/renderer/core/css/resolver/style_resolver_state.h b/third_party/blink/renderer/core/css/resolver/style_resolver_state.h index 3433438..fc9664a 100644 --- a/third_party/blink/renderer/core/css/resolver/style_resolver_state.h +++ b/third_party/blink/renderer/core/css/resolver/style_resolver_state.h
@@ -125,14 +125,6 @@ is_animating_custom_properties_ = value; } - HashSet<PropertyHandle>& AnimationPendingCustomProperties() { - return animation_pending_custom_properties_; - } - - const HashSet<PropertyHandle>& AnimationPendingCustomProperties() const { - return animation_pending_custom_properties_; - } - void SetParentStyle(scoped_refptr<const ComputedStyle>); const ComputedStyle* ParentStyle() const { return parent_style_.get(); } @@ -220,7 +212,6 @@ CSSAnimationUpdate animation_update_; bool is_animation_interpolation_map_ready_; bool is_animating_custom_properties_; - HashSet<PropertyHandle> animation_pending_custom_properties_; bool apply_property_to_regular_style_; bool apply_property_to_visited_link_style_;
diff --git a/third_party/blink/renderer/core/dom/BUILD.gn b/third_party/blink/renderer/core/dom/BUILD.gn index 7ffeb62..d1bf2dc 100644 --- a/third_party/blink/renderer/core/dom/BUILD.gn +++ b/third_party/blink/renderer/core/dom/BUILD.gn
@@ -127,6 +127,8 @@ "events/event_target_impl.h", "events/node_event_context.cc", "events/node_event_context.h", + "events/registered_event_listener.cc", + "events/registered_event_listener.h", "events/scoped_event_queue.cc", "events/scoped_event_queue.h", "events/simulated_click_options.h",
diff --git a/third_party/blink/renderer/core/dom/abort_controller.h b/third_party/blink/renderer/core/dom/abort_controller.h index 32e53cf..1cbd684 100644 --- a/third_party/blink/renderer/core/dom/abort_controller.h +++ b/third_party/blink/renderer/core/dom/abort_controller.h
@@ -23,7 +23,7 @@ static AbortController* Create(ExecutionContext*); ~AbortController() override; - // AbortController.idl + // abort_controller.idl // https://dom.spec.whatwg.org/#dom-abortcontroller-signal AbortSignal* signal() const { return signal_.Get(); }
diff --git a/third_party/blink/renderer/core/dom/abort_signal.h b/third_party/blink/renderer/core/dom/abort_signal.h index 3a257ac..23cadde 100644 --- a/third_party/blink/renderer/core/dom/abort_signal.h +++ b/third_party/blink/renderer/core/dom/abort_signal.h
@@ -24,7 +24,7 @@ explicit AbortSignal(ExecutionContext*); ~AbortSignal() override; - // AbortSignal.idl + // abort_signal.idl bool aborted() const { return aborted_flag_; } DEFINE_ATTRIBUTE_EVENT_LISTENER(abort);
diff --git a/third_party/blink/renderer/core/dom/attr.h b/third_party/blink/renderer/core/dom/attr.h index 09bc9491..cf12ab1b 100644 --- a/third_party/blink/renderer/core/dom/attr.h +++ b/third_party/blink/renderer/core/dom/attr.h
@@ -79,13 +79,13 @@ // Attr wraps either an element/name, or a name/value pair (when it's a // standalone Node.) - // Note that m_name is always set, but m_element/m_standaloneValue may be - // null. + // Note that name_ is always set, but element_ / + // standalone_value_or_attached_local_name_ may be null. TraceWrapperMember<Element> element_; QualifiedName name_; // Holds the value if it is a standalone Node, or the local name of the // attribute it is attached to on an Element. The latter may (letter case) - // differ from m_name's local name. As these two modes are non-overlapping, + // differ from name_'s local name. As these two modes are non-overlapping, // use a single field. AtomicString standalone_value_or_attached_local_name_; };
diff --git a/third_party/blink/renderer/core/dom/class_collection.h b/third_party/blink/renderer/core/dom/class_collection.h index ff0d74a..b4c7d6b 100644 --- a/third_party/blink/renderer/core/dom/class_collection.h +++ b/third_party/blink/renderer/core/dom/class_collection.h
@@ -38,9 +38,9 @@ class ClassCollection final : public HTMLCollection { public: - // classNames argument is an AtomicString because it is common for Elements to - // share the same class names. It is also used to construct a - // SpaceSplitString (m_classNames) and its constructor requires an + // class_names argument is an AtomicString because it is common for Elements + // to share the same class names. It is also used to construct a + // SpaceSplitString (class_names_) and its constructor requires an // AtomicString. static ClassCollection* Create(ContainerNode& root_node, CollectionType type,
diff --git a/third_party/blink/renderer/core/dom/container_node.h b/third_party/blink/renderer/core/dom/container_node.h index 578665e..ebb81ac 100644 --- a/third_party/blink/renderer/core/dom/container_node.h +++ b/third_party/blink/renderer/core/dom/container_node.h
@@ -294,7 +294,7 @@ void RebuildNonDistributedChildren(); // ----------------------------------------------------------------------------- - // Notification of document structure changes (see core/dom/Node.h for more + // Notification of document structure changes (see core/dom/node.h for more // notification methods) enum ChildrenChangeType {
diff --git a/third_party/blink/renderer/core/dom/context_features.h b/third_party/blink/renderer/core/dom/context_features.h index 2fa26426..bf995fb 100644 --- a/third_party/blink/renderer/core/dom/context_features.h +++ b/third_party/blink/renderer/core/dom/context_features.h
@@ -103,12 +103,12 @@ inline void ContextFeatures::UrlDidChange(Document* document) { // FIXME: The original code, commented out below, is obviously // wrong, but the seemingly correct fix of negating the test to - // the more logical 'if (!m_client)' crashes the renderer. + // the more logical 'if (!client_)' crashes the renderer. // See issue 294180 // - // if (m_client) - // return; - // m_client->urlDidChange(document); + // if (client_) + // return; + // client_->UrlDidChange(document); } } // namespace blink
diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc index 4caf2160..cdd6968 100644 --- a/third_party/blink/renderer/core/dom/document.cc +++ b/third_party/blink/renderer/core/dom/document.cc
@@ -747,9 +747,9 @@ lifecycle_.AdvanceTo(DocumentLifecycle::kInactive); - // Since CSSFontSelector requires Document::m_fetcher and StyleEngine owns - // CSSFontSelector, need to initialize m_styleEngine after initializing - // m_fetcher. + // Since CSSFontSelector requires Document::fetcher_ and StyleEngine owns + // CSSFontSelector, need to initialize style_engine_ after initializing + // fetcher_. style_engine_ = StyleEngine::Create(*this); // The parent's parser should be suspended together with all the other @@ -2984,8 +2984,8 @@ AXObjectCache* Document::ExistingAXObjectCache() const { auto& cache_owner = AXObjectCacheOwner(); - // If the layoutObject is gone then we are in the process of destruction. - // This method will be called before m_frame = nullptr. + // If the LayoutView is gone then we are in the process of destruction. + // This method will be called before frame_ = nullptr. if (!cache_owner.GetLayoutView()) return nullptr; @@ -4005,8 +4005,7 @@ // DOM 3 Core: When the Document supports the feature "HTML" [DOM Level 2 // HTML], the base URI is computed using first the value of the href attribute // of the HTML BASE element if any, and the value of the documentURI attribute - // from the Document interface otherwise (which we store, preparsed, in - // m_url). + // from the Document interface otherwise (which we store, preparsed, in url_). if (!base_element_url_.IsEmpty()) base_url_ = base_element_url_; else if (!base_url_override_.IsEmpty()) @@ -6575,7 +6574,7 @@ } void Document::DetachRange(Range* range) { - // We don't ASSERT m_ranges.contains(range) to allow us to call this + // We don't DCHECK ranges_.contains(range) to allow us to call this // unconditionally to fix: https://bugs.webkit.org/show_bug.cgi?id=26044 ranges_.erase(range); }
diff --git a/third_party/blink/renderer/core/dom/document.h b/third_party/blink/renderer/core/dom/document.h index bf0c2368..1cefa93f 100644 --- a/third_party/blink/renderer/core/dom/document.h +++ b/third_party/blink/renderer/core/dom/document.h
@@ -985,7 +985,7 @@ DocumentMarkerController& Markers() const { return *markers_; } // Support for Javascript execCommand, and related methods - // See "core/editing/commands/DocumentExecCommand.cpp" for implementations. + // See "core/editing/commands/document_exec_command.cc" for implementations. bool execCommand(const String& command, bool show_ui, const String& value, @@ -1259,8 +1259,8 @@ } HTMLDialogElement* ActiveModalDialog() const; - // A non-null m_templateDocumentHost implies that |this| was created by - // ensureTemplateDocument(). + // A non-null template_document_host_ implies that |this| was created by + // EnsureTemplateDocument(). bool IsTemplateDocument() const { return !!template_document_host_; } Document& EnsureTemplateDocument(); Document* TemplateDocumentHost() { return template_document_host_; } @@ -1642,9 +1642,9 @@ // Document URLs. KURL url_; // Document.URL: The URL from which this document was retrieved. KURL base_url_; // Node.baseURI: The URL to use when resolving relative URLs. - KURL - base_url_override_; // An alternative base URL that takes precedence over - // m_baseURL (but not m_baseElementURL). + // An alternative base URL that takes precedence over base_url_ (but + // not base_element_url_). + KURL base_url_override_; KURL base_element_url_; // The URL set by the <base> element. KURL cookie_url_; // The URL to use for cookie access. std::unique_ptr<OriginAccessEntry> access_entry_from_url_; @@ -1792,7 +1792,7 @@ // For early return in Fullscreen::fromIfExists() bool has_fullscreen_supplement_; - // The last element in |m_topLayerElements| is topmost in the top layer + // The last element in |top_layer_elements_| is topmost in the top layer // stack and is thus the one that will be visually on top. HeapVector<Member<Element>> top_layer_elements_;
diff --git a/third_party/blink/renderer/core/dom/document.idl b/third_party/blink/renderer/core/dom/document.idl index 072e5a8..5f6ff88 100644 --- a/third_party/blink/renderer/core/dom/document.idl +++ b/third_party/blink/renderer/core/dom/document.idl
@@ -104,7 +104,7 @@ // DOM tree accessors // Named getter is implemented without IDL code generation for better - // performance. See LocalWindowProxy.cpp. + // performance. See local_window_proxy.cc. // getter object (DOMString name); [Affects=Nothing, CEReactions, CustomElementCallbacks] attribute DOMString title; [CEReactions, CustomElementCallbacks] attribute DOMString dir;
diff --git a/third_party/blink/renderer/core/dom/document_parser.h b/third_party/blink/renderer/core/dom/document_parser.h index 157f3b7..9ffd54d4 100644 --- a/third_party/blink/renderer/core/dom/document_parser.h +++ b/third_party/blink/renderer/core/dom/document_parser.h
@@ -90,9 +90,9 @@ virtual void StopParsing(); // Document is expected to detach the parser before releasing its ref. - // After detach, m_document is cleared. The parser will unwind its + // After detach, document_ is cleared. The parser will unwind its // callstacks, but not produce any more nodes. - // It is impossible for the parser to touch the rest of WebCore after + // It is impossible for the parser to touch the rest of Blink Core after // detach is called. // Oilpan: We don't need to call detach when a Document is destructed. virtual void Detach(); @@ -129,7 +129,7 @@ bool document_was_loaded_as_part_of_navigation_; // Every DocumentParser needs a pointer back to the document. - // m_document will be 0 after the parser is stopped. + // document_ will be 0 after the parser is stopped. Member<Document> document_; HeapHashSet<WeakMember<DocumentParserClient>> clients_;
diff --git a/third_party/blink/renderer/core/dom/document_parser_timing.h b/third_party/blink/renderer/core/dom/document_parser_timing.h index f0c93090..4cea8dc 100644 --- a/third_party/blink/renderer/core/dom/document_parser_timing.h +++ b/third_party/blink/renderer/core/dom/document_parser_timing.h
@@ -63,7 +63,7 @@ // The getters below return monotonically-increasing time, or zero if the // given parser event has not yet occurred. See the comments for - // monotonicallyIncreasingTime in wtf/Time.h for additional details. + // MonotonicallyIncreasingTime in platform/wtf/time.h for additional details. TimeTicks ParserStart() const { return parser_start_; } TimeTicks ParserStop() const { return parser_stop_; }
diff --git a/third_party/blink/renderer/core/dom/element.cc b/third_party/blink/renderer/core/dom/element.cc index f4839c8..494a938 100644 --- a/third_party/blink/renderer/core/dom/element.cc +++ b/third_party/blink/renderer/core/dom/element.cc
@@ -395,9 +395,9 @@ void Element::SynchronizeAllAttributes() const { if (!GetElementData()) return; - // NOTE: anyAttributeMatches in SelectorChecker.cpp - // currently assumes that all lazy attributes have a null namespace. - // If that ever changes we'll need to fix that code. + // NOTE: AnyAttributeMatches in selector_checker.cc currently assumes that all + // lazy attributes have a null namespace. If that ever changes we'll need to + // fix that code. if (GetElementData()->style_attribute_is_dirty_) { DCHECK(IsStyledElement()); SynchronizeStyleAttributeInternal(); @@ -441,10 +441,10 @@ // animated SVG Attribute. It would seem we should only call this method // if SVGElement::isAnimatableAttribute is true, but the list of // animatable attributes in isAnimatableAttribute does not suffice to - // pass all layout tests. Also, m_animatedSVGAttributesAreDirty stays - // dirty unless synchronizeAnimatedSVGAttribute is called with - // anyQName(). This means that even if Element::synchronizeAttribute() - // is called on all attributes, m_animatedSVGAttributesAreDirty remains + // pass all layout tests. Also, animated_svg_attributes_are_dirty_ stays + // dirty unless SynchronizeAnimatedSVGAttribute is called with + // AnyQName(). This means that even if Element::SynchronizeAttribute() + // is called on all attributes, animated_svg_attributes_are_dirty_ remains // true. ToSVGElement(this)->SynchronizeAnimatedSVGAttribute( QualifiedName(g_null_atom, local_name, g_null_atom)); @@ -1972,8 +1972,8 @@ ParserDidSetAttributes(); - // Use attributeVector instead of m_elementData because attributeChanged might - // modify m_elementData. + // Use attribute_vector instead of element_data_ because AttributeChanged + // might modify element_data_. for (const auto& attribute : attribute_vector) { AttributeChanged(AttributeModificationParams( attribute.GetName(), g_null_atom, attribute.Value(),
diff --git a/third_party/blink/renderer/core/dom/element.h b/third_party/blink/renderer/core/dom/element.h index 83959960..be54612 100644 --- a/third_party/blink/renderer/core/dom/element.h +++ b/third_party/blink/renderer/core/dom/element.h
@@ -382,7 +382,7 @@ return ContainerNode::HasTagName(tag_name); } - // Should be called only by Document::createElementNS to fix up m_tagName + // Should be called only by Document::createElementNS to fix up tag_name_ // immediately after construction. void SetTagNameForCreateElementNS(const QualifiedName&);
diff --git a/third_party/blink/renderer/core/dom/element_data.h b/third_party/blink/renderer/core/dom/element_data.h index 8cdcc95..7ee0db9a 100644 --- a/third_party/blink/renderer/core/dom/element_data.h +++ b/third_party/blink/renderer/core/dom/element_data.h
@@ -158,7 +158,7 @@ // UniqueElementData is created when an element needs to mutate its attributes // or gains presentation attribute style (ex. width="10"). It does not need to // be created to fill in values in the ElementData that are derived from -// attributes. For example populating the m_inlineStyle from the style attribute +// attributes. For example populating the inline_style_ from the style attribute // doesn't require a UniqueElementData as all elements with the same style // attribute will have the same inline style. class UniqueElementData final : public ElementData {
diff --git a/third_party/blink/renderer/core/dom/events/event.cc b/third_party/blink/renderer/core/dom/events/event.cc index b9fa5584..0239dfb 100644 --- a/third_party/blink/renderer/core/dom/events/event.cc +++ b/third_party/blink/renderer/core/dom/events/event.cc
@@ -239,6 +239,10 @@ return false; } +bool Event::IsErrorEvent() const { + return false; +} + void Event::preventDefault() { if (handling_passive_ != PassiveMode::kNotPassive && handling_passive_ != PassiveMode::kNotPassiveDefault) {
diff --git a/third_party/blink/renderer/core/dom/events/event.h b/third_party/blink/renderer/core/dom/events/event.h index 4b1a53b..b122900 100644 --- a/third_party/blink/renderer/core/dom/events/event.h +++ b/third_party/blink/renderer/core/dom/events/event.h
@@ -163,7 +163,7 @@ bool IsScopedInV0() const; // Event creation timestamp in milliseconds. It returns a DOMHighResTimeStamp - // using the platform timestamp (see |m_platformTimeStamp|). + // using the platform timestamp (see |platform_time_stamp_|). // For more info see http://crbug.com/160524 double timeStamp(ScriptState*) const; TimeTicks PlatformTimeStamp() const { return platform_time_stamp_; } @@ -208,6 +208,7 @@ virtual bool IsBeforeTextInsertedEvent() const; virtual bool IsBeforeUnloadEvent() const; + virtual bool IsErrorEvent() const; virtual bool IsActivateInvisibleEvent() const; @@ -341,8 +342,8 @@ // does Event Timing report it. unsigned executed_listener_or_default_action_ : 1; - // Whether preventDefault was called when |m_handlingPassive| is - // true. This field is reset on each call to setHandlingPassive. + // Whether preventDefault was called when |handling_passive_| is + // true. This field is reset on each call to SetHandlingPassive. unsigned prevent_default_called_during_passive_ : 1; // Whether preventDefault was called on uncancelable event. unsigned prevent_default_called_on_uncancelable_event_ : 1;
diff --git a/third_party/blink/renderer/core/dom/events/event_dispatcher.cc b/third_party/blink/renderer/core/dom/events/event_dispatcher.cc index 5b4781f..a6710b3 100644 --- a/third_party/blink/renderer/core/dom/events/event_dispatcher.cc +++ b/third_party/blink/renderer/core/dom/events/event_dispatcher.cc
@@ -305,7 +305,7 @@ ToMouseEvent(*event_).type() == EventTypeNames::click; if (is_click) { // Fire an accessibility event indicating a node was clicked on. This is - // safe if m_event->target()->toNode() returns null. + // safe if event_->target()->ToNode() returns null. if (AXObjectCache* cache = node_->GetDocument().ExistingAXObjectCache()) cache->HandleClicked(event_->target()->ToNode());
diff --git a/third_party/blink/renderer/core/dom/events/event_listener_map.h b/third_party/blink/renderer/core/dom/events/event_listener_map.h index 35e4fa57..d2ee92d 100644 --- a/third_party/blink/renderer/core/dom/events/event_listener_map.h +++ b/third_party/blink/renderer/core/dom/events/event_listener_map.h
@@ -37,7 +37,7 @@ #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/dom/events/add_event_listener_options_resolved.h" #include "third_party/blink/renderer/core/dom/events/event_listener_options.h" -#include "third_party/blink/renderer/core/events/registered_event_listener.h" +#include "third_party/blink/renderer/core/dom/events/registered_event_listener.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable_visitor.h" #include "third_party/blink/renderer/platform/wtf/text/atomic_string_hash.h"
diff --git a/third_party/blink/renderer/core/dom/events/event_path.cc b/third_party/blink/renderer/core/dom/events/event_path.cc index 7aa7fc8..b5f52b1 100644 --- a/third_party/blink/renderer/core/dom/events/event_path.cc +++ b/third_party/blink/renderer/core/dom/events/event_path.cc
@@ -96,7 +96,7 @@ // For performance and memory usage reasons we want to store the // path using as few bytes as possible and with as few allocations // as possible which is why we gather the data on the stack before - // storing it in a perfectly sized m_nodeEventContexts Vector. + // storing it in a perfectly sized node_event_contexts_ Vector. HeapVector<Member<Node>, 64> nodes_in_path; Node* current = node_; @@ -141,8 +141,8 @@ void EventPath::CalculateTreeOrderAndSetNearestAncestorClosedTree() { // Precondition: - // - TreeScopes in m_treeScopeEventContexts must be *connected* in the same - // composed tree. + // - TreeScopes in tree_scope_event_contexts_ must be *connected* in the + // same composed tree. // - The root tree must be included. TreeScopeEventContext* root_tree = nullptr; for (const auto& tree_scope_event_context : tree_scope_event_contexts_) {
diff --git a/third_party/blink/renderer/core/dom/events/event_target.cc b/third_party/blink/renderer/core/dom/events/event_target.cc index 6c34fb3..c82f6aa9 100644 --- a/third_party/blink/renderer/core/dom/events/event_target.cc +++ b/third_party/blink/renderer/core/dom/events/event_target.cc
@@ -199,7 +199,7 @@ // because it will increase the size of EventTarget and all of its // subclasses with code that are mostly unnecessary for them, // resulting in a performance decrease. -// We also don't use ImplementedAs=EventTargetImpl in EventTarget.idl +// We also don't use ImplementedAs=EventTargetImpl in event_target.idl // because it will result in some complications with classes that are // currently derived from EventTarget. // Spec: https://dom.spec.whatwg.org/#dom-eventtarget-eventtarget
diff --git a/third_party/blink/renderer/core/events/registered_event_listener.cc b/third_party/blink/renderer/core/dom/events/registered_event_listener.cc similarity index 97% rename from third_party/blink/renderer/core/events/registered_event_listener.cc rename to third_party/blink/renderer/core/dom/events/registered_event_listener.cc index b281c84d..91efc19 100644 --- a/third_party/blink/renderer/core/events/registered_event_listener.cc +++ b/third_party/blink/renderer/core/dom/events/registered_event_listener.cc
@@ -22,7 +22,7 @@ * */ -#include "third_party/blink/renderer/core/events/registered_event_listener.h" +#include "third_party/blink/renderer/core/dom/events/registered_event_listener.h" #include "third_party/blink/renderer/core/dom/events/add_event_listener_options_resolved.h" #include "third_party/blink/renderer/core/dom/events/event.h"
diff --git a/third_party/blink/renderer/core/events/registered_event_listener.h b/third_party/blink/renderer/core/dom/events/registered_event_listener.h similarity index 92% rename from third_party/blink/renderer/core/events/registered_event_listener.h rename to third_party/blink/renderer/core/dom/events/registered_event_listener.h index 9af2c759..ac6bb8c 100644 --- a/third_party/blink/renderer/core/events/registered_event_listener.h +++ b/third_party/blink/renderer/core/dom/events/registered_event_listener.h
@@ -22,8 +22,8 @@ * */ -#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_EVENTS_REGISTERED_EVENT_LISTENER_H_ -#define THIRD_PARTY_BLINK_RENDERER_CORE_EVENTS_REGISTERED_EVENT_LISTENER_H_ +#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_DOM_EVENTS_REGISTERED_EVENT_LISTENER_H_ +#define THIRD_PARTY_BLINK_RENDERER_CORE_DOM_EVENTS_REGISTERED_EVENT_LISTENER_H_ #include "base/memory/scoped_refptr.h" #include "third_party/blink/renderer/platform/bindings/trace_wrapper_member.h" @@ -98,4 +98,4 @@ WTF_ALLOW_CLEAR_UNUSED_SLOTS_WITH_MEM_FUNCTIONS(blink::RegisteredEventListener); -#endif // THIRD_PARTY_BLINK_RENDERER_CORE_EVENTS_REGISTERED_EVENT_LISTENER_H_ +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_DOM_EVENTS_REGISTERED_EVENT_LISTENER_H_
diff --git a/third_party/blink/renderer/core/dom/mutation_observer.cc b/third_party/blink/renderer/core/dom/mutation_observer.cc index 85793581..ac2ea235 100644 --- a/third_party/blink/renderer/core/dom/mutation_observer.cc +++ b/third_party/blink/renderer/core/dom/mutation_observer.cc
@@ -300,7 +300,7 @@ void MutationObserver::Deliver() { DCHECK(!ShouldBeSuspended()); - // Calling clearTransientRegistrations() can modify m_registrations, so it's + // Calling ClearTransientRegistrations() can modify registrations_, so it's // necessary to make a copy of the transient registrations before operating on // them. HeapVector<Member<MutationObserverRegistration>, 1> transient_registrations;
diff --git a/third_party/blink/renderer/core/dom/mutation_observer_registration.cc b/third_party/blink/renderer/core/dom/mutation_observer_registration.cc index 836bb34..8f4cc21 100644 --- a/third_party/blink/renderer/core/dom/mutation_observer_registration.cc +++ b/third_party/blink/renderer/core/dom/mutation_observer_registration.cc
@@ -107,7 +107,7 @@ } void MutationObserverRegistration::Unregister() { - // |this| can outlives m_registrationNode. + // |this| can outlives registration_node_. if (registration_node_) registration_node_->UnregisterMutationObserver(this); else
diff --git a/third_party/blink/renderer/core/dom/node.cc b/third_party/blink/renderer/core/dom/node.cc index 43b367d..cb642b0 100644 --- a/third_party/blink/renderer/core/dom/node.cc +++ b/third_party/blink/renderer/core/dom/node.cc
@@ -2620,8 +2620,10 @@ static_cast<NodeFlags>(new_state); DCHECK(new_state == GetCustomElementState()); - if (element->IsDefined() != was_defined) + if (element->IsDefined() != was_defined) { element->PseudoStateChanged(CSSSelector::kPseudoDefined); + element->PseudoStateChanged(CSSSelector::kPseudoUnresolved); + } } void Node::SetV0CustomElementState(V0CustomElementState new_state) { @@ -2646,8 +2648,10 @@ SetFlag(kV0CustomElementFlag); SetFlag(new_state == kV0Upgraded, kV0CustomElementUpgradedFlag); - if (old_state == kV0NotCustomElement || new_state == kV0Upgraded) + if (old_state == kV0NotCustomElement || new_state == kV0Upgraded) { ToElement(this)->PseudoStateChanged(CSSSelector::kPseudoUnresolved); + ToElement(this)->PseudoStateChanged(CSSSelector::kPseudoDefined); + } } void Node::CheckSlotChange(SlotChangeType slot_change_type) {
diff --git a/third_party/blink/renderer/core/dom/node.h b/third_party/blink/renderer/core/dom/node.h index 8acd2ce..20acc9c 100644 --- a/third_party/blink/renderer/core/dom/node.h +++ b/third_party/blink/renderer/core/dom/node.h
@@ -38,7 +38,7 @@ #include "third_party/blink/renderer/platform/bindings/trace_wrapper_member.h" #include "third_party/blink/renderer/platform/geometry/layout_rect.h" -// This needs to be here because Element.cpp also depends on it. +// This needs to be here because element.cc also depends on it. #define DUMP_NODE_STATISTICS 0 namespace blink { @@ -680,7 +680,7 @@ } // ----------------------------------------------------------------------------- - // Notification of document structure changes (see ContainerNode.h for more + // Notification of document structure changes (see container_node.h for more // notification methods) // // At first, Blinkt notifies the node that it has been inserted into the
diff --git a/third_party/blink/renderer/core/dom/node_rare_data.cc b/third_party/blink/renderer/core/dom/node_rare_data.cc index db3b785..f340e29 100644 --- a/third_party/blink/renderer/core/dom/node_rare_data.cc +++ b/third_party/blink/renderer/core/dom/node_rare_data.cc
@@ -114,7 +114,7 @@ return *node_lists_; } -// Ensure the 10 bits reserved for the m_connectedFrameCount cannot overflow +// Ensure the 10 bits reserved for the connected_frame_count_ cannot overflow. static_assert(Page::kMaxNumberOfFrames < (1 << NodeRareData::kConnectedFrameCountBits), "Frame limit should fit in rare data count");
diff --git a/third_party/blink/renderer/core/dom/node_rare_data.h b/third_party/blink/renderer/core/dom/node_rare_data.h index dd4f747..394632d8 100644 --- a/third_party/blink/renderer/core/dom/node_rare_data.h +++ b/third_party/blink/renderer/core/dom/node_rare_data.h
@@ -124,9 +124,9 @@ void ClearNodeLists() { node_lists_.Clear(); } NodeListsNodeData* NodeLists() const { return node_lists_.Get(); } - // ensureNodeLists() and a following NodeListsNodeData functions must be + // EnsureNodeLists() and a following NodeListsNodeData functions must be // wrapped with a ThreadState::GCForbiddenScope in order to avoid an - // initialized m_nodeLists is cleared by NodeRareData::traceAfterDispatch(). + // initialized node_lists_ is cleared by NodeRareData::TraceAfterDispatch(). NodeListsNodeData& EnsureNodeLists() { DCHECK(ThreadState::Current()->IsGCForbidden()); if (!node_lists_)
diff --git a/third_party/blink/renderer/core/dom/processing_instruction.cc b/third_party/blink/renderer/core/dom/processing_instruction.cc index c20295e..bfe8e34 100644 --- a/third_party/blink/renderer/core/dom/processing_instruction.cc +++ b/third_party/blink/renderer/core/dom/processing_instruction.cc
@@ -81,7 +81,7 @@ } Node* ProcessingInstruction::Clone(Document& factory, CloneChildrenFlag) const { - // FIXME: Is it a problem that this does not copy m_localHref? + // FIXME: Is it a problem that this does not copy local_href_? // What about other data members? return Create(factory, target_, data_); }
diff --git a/third_party/blink/renderer/core/dom/qualified_name.h b/third_party/blink/renderer/core/dom/qualified_name.h index 3b91481..ea0348d 100644 --- a/third_party/blink/renderer/core/dom/qualified_name.h +++ b/third_party/blink/renderer/core/dom/qualified_name.h
@@ -79,8 +79,8 @@ RefCounted<QualifiedNameImpl>::Release(); } - // We rely on StringHasher's hashMemory clearing out the top 8 bits when - // doing hashing and use one of the bits for the m_isStatic value. + // We rely on StringHasher's HashMemory clearing out the top 8 bits when + // doing hashing and use one of the bits for the is_static_ value. mutable unsigned existing_hash_ : 24; unsigned is_static_ : 1; const AtomicString prefix_;
diff --git a/third_party/blink/renderer/core/dom/range.cc b/third_party/blink/renderer/core/dom/range.cc index 2835ccb..7832ffd 100644 --- a/third_party/blink/renderer/core/dom/range.cc +++ b/third_party/blink/renderer/core/dom/range.cc
@@ -603,9 +603,8 @@ // delete all children of commonRoot between the start and end container Node* process_start = ChildOfCommonRootBeforeOffset( &original_start.Container(), original_start.Offset(), common_root); - if (process_start && - original_start.Container() != - common_root) // processStart contains nodes before m_start. + // process_start contains nodes before start_. + if (process_start && original_start.Container() != common_root) process_start = process_start->nextSibling(); Node* process_end = ChildOfCommonRootBeforeOffset( &original_end.Container(), original_end.Offset(), common_root);
diff --git a/third_party/blink/renderer/core/dom/range_boundary_point.h b/third_party/blink/renderer/core/dom/range_boundary_point.h index 8c3a071c..1329ced 100644 --- a/third_party/blink/renderer/core/dom/range_boundary_point.h +++ b/third_party/blink/renderer/core/dom/range_boundary_point.h
@@ -128,8 +128,8 @@ inline const Position RangeBoundaryPoint::ToPosition() const { EnsureOffsetIsValid(); - // TODO(yosin): We should return |Position::beforeAnchor| when - // |m_containerNode| isn't |Text| node. + // TODO(yosin): We should return |Position::BeforeAnchor| when + // |container_node_| isn't a |Text| node. return Position(container_node_.Get(), offset_in_container_); }
diff --git a/third_party/blink/renderer/core/dom/scripted_animation_controller.cc b/third_party/blink/renderer/core/dom/scripted_animation_controller.cc index 5bdc1ac0..685a7871 100644 --- a/third_party/blink/renderer/core/dom/scripted_animation_controller.cc +++ b/third_party/blink/renderer/core/dom/scripted_animation_controller.cc
@@ -57,7 +57,7 @@ } void ScriptedAnimationController::Unpause() { - // It would be nice to put an DCHECK(m_suspendCount > 0) here, but in WK1 + // It would be nice to put an DCHECK_GT(suspend_count_, 0) here, but in WK1 // resume() can be called even when suspend hasn't (if a tab was created in // the background). if (suspend_count_ > 0)
diff --git a/third_party/blink/renderer/core/dom/shadow_root.cc b/third_party/blink/renderer/core/dom/shadow_root.cc index 89ce359b..f2d5200 100644 --- a/third_party/blink/renderer/core/dom/shadow_root.cc +++ b/third_party/blink/renderer/core/dom/shadow_root.cc
@@ -188,10 +188,10 @@ GetDocument().GetSlotAssignmentEngine().Connected(*this); - // FIXME: When parsing <video controls>, insertedInto() is called many times - // without invoking removedFrom. For now, we check - // m_registeredWithParentShadowroot. We would like to - // DCHECK(!m_registeredShadowRoot) here. + // FIXME: When parsing <video controls>, InsertedInto() is called many times + // without invoking RemovedFrom(). For now, we check + // registered_with_parent_shadow_root. We would like to + // DCHECK(!registered_with_parent_shadow_root) here. // https://bugs.webkit.org/show_bug.cig?id=101316 if (registered_with_parent_shadow_root_) return kInsertionDone;
diff --git a/third_party/blink/renderer/core/dom/space_split_string.cc b/third_party/blink/renderer/core/dom/space_split_string.cc index 38730b3..cfe0bdbc 100644 --- a/third_party/blink/renderer/core/dom/space_split_string.cc +++ b/third_party/blink/renderer/core/dom/space_split_string.cc
@@ -207,8 +207,8 @@ SpaceSplitString::Data::Data(const SpaceSplitString::Data& other) : RefCounted<Data>(), vector_(other.vector_) { - // Note that we don't copy m_keyString to indicate to the destructor that - // there's nothing to be removed from the sharedDataMap(). + // Note that we don't copy key_string_ to indicate to the destructor that + // there's nothing to be removed from the SharedDataMap(). } } // namespace blink
diff --git a/third_party/blink/renderer/core/dom/whitespace_attacher.cc b/third_party/blink/renderer/core/dom/whitespace_attacher.cc index b3029b4f..cbaf455 100644 --- a/third_party/blink/renderer/core/dom/whitespace_attacher.cc +++ b/third_party/blink/renderer/core/dom/whitespace_attacher.cc
@@ -20,7 +20,7 @@ void WhitespaceAttacher::DidReattach(Node* node, LayoutObject* prev_in_flow) { DCHECK(node); DCHECK(node->IsTextNode() || node->IsElementNode()); - // See Invariants in WhitespaceAttacher.h + // See Invariants in whitespace_attacher.h DCHECK(!last_display_contents_ || !last_text_node_needs_reattach_); ForceLastTextNodeNeedsReattach();
diff --git a/third_party/blink/renderer/core/editing/caret_display_item_client.cc b/third_party/blink/renderer/core/editing/caret_display_item_client.cc index b4ba2f9..44e3d3cf 100644 --- a/third_party/blink/renderer/core/editing/caret_display_item_client.cc +++ b/third_party/blink/renderer/core/editing/caret_display_item_client.cc
@@ -132,11 +132,11 @@ void CaretDisplayItemClient::UpdateStyleAndLayoutIfNeeded( const PositionWithAffinity& caret_position) { // This method may be called multiple times (e.g. in partial lifecycle - // updates) before a paint invalidation. We should save m_previousLayoutBlock - // and m_visualRectInPreviousLayoutBlock only if they have not been saved + // updates) before a paint invalidation. We should save previous_layout_block_ + // and visual_rect_in_previous_layout_block only if they have not been saved // since the last paint invalidation to ensure the caret painted in the // previous paint invalidated block will be invalidated. We don't care about - // intermediate changes of layoutBlock because they are not painted. + // intermediate changes of LayoutBlock because they are not painted. if (!previous_layout_block_) { previous_layout_block_ = layout_block_; visual_rect_in_previous_layout_block_ = visual_rect_; @@ -152,7 +152,7 @@ needs_paint_invalidation_ = true; if (new_layout_block == previous_layout_block_) { // The caret has disappeared and is reappearing in the same block, - // since the last paint invalidation. Set m_visualRect as if the caret + // since the last paint invalidation. Set visual_rect_ as if the caret // has always been there as paint invalidation doesn't care about the // intermediate changes. visual_rect_ = visual_rect_in_previous_layout_block_;
diff --git a/third_party/blink/renderer/core/editing/caret_display_item_client.h b/third_party/blink/renderer/core/editing/caret_display_item_client.h index 04dda7f..1fe23287 100644 --- a/third_party/blink/renderer/core/editing/caret_display_item_client.h +++ b/third_party/blink/renderer/core/editing/caret_display_item_client.h
@@ -93,13 +93,13 @@ LayoutRect local_rect_; LayoutBlock* layout_block_ = nullptr; - // Visual rect of the caret in m_layoutBlock. This is updated by - // invalidatePaintIfNeeded(). + // Visual rect of the caret in layout_block_. This is updated by + // InvalidatePaintIfNeeded(). LayoutRect visual_rect_; - // These are set to the previous value of m_layoutBlock and m_visualRect - // during updateStyleAndLayoutIfNeeded() if they haven't been set since the - // last paint invalidation. They can only be used in invalidatePaintIfNeeded() + // These are set to the previous value of layout_bloc_k and visual_rect_ + // during UpdateStyleAndLayoutIfNeeded() if they haven't been set since the + // last paint invalidation. They can only be used in InvalidatePaintIfNeeded() // to invalidate the caret in the previous layout block. const LayoutBlock* previous_layout_block_ = nullptr; LayoutRect visual_rect_in_previous_layout_block_;
diff --git a/third_party/blink/renderer/core/editing/commands/apply_style_command.cc b/third_party/blink/renderer/core/editing/commands/apply_style_command.cc index c02f371..e3f5775 100644 --- a/third_party/blink/renderer/core/editing/commands/apply_style_command.cc +++ b/third_party/blink/renderer/core/editing/commands/apply_style_command.cc
@@ -1088,8 +1088,8 @@ node = NodeTraversal::Next(*node)) { if (node->hasChildren()) continue; - // We don't consider m_isInlineElementToRemoveFunction here because we never - // apply style when m_isInlineElementToRemoveFunction is specified + // We don't consider is_inline_element_to_remove_function_ here because we + // never apply style when is_inline_element_to_remove_function_ is specified if (!style->StyleIsPresentInComputedStyleOfNode(node)) return true; if (styled_inline_element_ &&
diff --git a/third_party/blink/renderer/core/editing/commands/delete_selection_command.cc b/third_party/blink/renderer/core/editing/commands/delete_selection_command.cc index 5b58183..be93026 100644 --- a/third_party/blink/renderer/core/editing/commands/delete_selection_command.cc +++ b/third_party/blink/renderer/core/editing/commands/delete_selection_command.cc
@@ -739,12 +739,12 @@ if (downstream_end_.ComputeEditingOffset() > 0) { DeleteTextFromNode(text, 0, downstream_end_.ComputeEditingOffset()); } - // Remove children of m_downstreamEnd.anchorNode() that come after - // m_upstreamStart. Don't try to remove children if m_upstreamStart - // was inside m_downstreamEnd.anchorNode() and m_upstreamStart has + // Remove children of downstream_end_.AnchorNode() that come after + // upstream_start_. Don't try to remove children if upstream_start_ + // was inside downstream_end_.AnchorNode() and upstream_start_ has // been removed from the document, because then we don't know how many // children to remove. - // FIXME: Make m_upstreamStart a position we update as we remove + // FIXME: Make upstream_start_ a position we update as we remove // content, then we can always know which children to remove. } else if (!(start_node_was_descendant_of_end_node && !upstream_start_.IsConnected())) { @@ -836,7 +836,7 @@ CreateVisiblePosition(downstream_end_); VisiblePosition merge_destination = CreateVisiblePosition(upstream_start_); - // m_downstreamEnd's block has been emptied out by deletion. There is no + // downstream_end_'s block has been emptied out by deletion. There is no // content inside of it to move, so just remove it. Element* end_block = EnclosingBlock(downstream_end_.AnchorNode()); if (!end_block || @@ -850,7 +850,7 @@ RelocatablePosition relocatable_start( start_of_paragraph_to_move.DeepEquivalent()); - // We need to merge into m_upstreamStart's block, but it's been emptied out + // We need to merge into upstream_start_'s block, but it's been emptied out // and collapsed by deletion. if (!merge_destination.DeepEquivalent().AnchorNode() || (!merge_destination.DeepEquivalent().AnchorNode()->IsDescendantOf( @@ -987,14 +987,14 @@ if (end_table_row_ && end_table_row_->isConnected() && end_table_row_ != start_table_row_) { if (IsTableRowEmpty(end_table_row_.Get())) { - // Don't remove m_endTableRow if it's where we're putting the ending + // Don't remove end_table_row_ if it's where we're putting the ending // selection. if (!ending_position_.AnchorNode()->IsDescendantOf( end_table_row_.Get())) { - // FIXME: We probably shouldn't remove m_endTableRow unless it's + // FIXME: We probably shouldn't remove end_table_row_ unless it's // fully selected, even if it is empty. We'll need to start // adjusting the selection endpoints during deletion to know - // whether or not m_endTableRow was fully selected here. + // whether or not end_table_row_ was fully selected here. CompositeEditCommand::RemoveNode(end_table_row_.Get(), editing_state); if (editing_state->IsAborted()) return; @@ -1187,7 +1187,7 @@ if (editing_state->IsAborted()) return; } - // handleGeneralDelete cause DOM mutation events so |m_endingPosition| + // HandleGeneralDelete cause DOM mutation events so |ending_position_| // can be out of document. if (ending_position_.IsConnected()) { InsertNodeAt(placeholder, ending_position_, editing_state); @@ -1238,9 +1238,9 @@ InputEvent::InputType DeleteSelectionCommand::GetInputType() const { // |DeleteSelectionCommand| could be used with Cut, Menu Bar deletion and // |TypingCommand|. - // 1. Cut and Menu Bar deletion should rely on correct |m_inputType|. - // 2. |TypingCommand| will supply the |inputType()|, so |m_inputType| could - // default to |InputType::None|. + // 1. Cut and Menu Bar deletion should rely on correct |input_type_|. + // 2. |TypingCommand| will supply the |GetInputType()|, so |input_type_| could + // default to |InputType::kNone|. return input_type_; }
diff --git a/third_party/blink/renderer/core/editing/commands/edit_command.h b/third_party/blink/renderer/core/editing/commands/edit_command.h index d5456510..e6bff029 100644 --- a/third_party/blink/renderer/core/editing/commands/edit_command.h +++ b/third_party/blink/renderer/core/editing/commands/edit_command.h
@@ -51,7 +51,7 @@ // The |EditingState*| argument must not be nullptr. virtual void DoApply(EditingState*) = 0; - // |TypingCommand| will return the text of the last |m_commands|. + // |TypingCommand| will return the text of the last |commands_|. virtual String TextDataForInputEvent() const; virtual void Trace(blink::Visitor*);
diff --git a/third_party/blink/renderer/core/editing/commands/editor_command.cc b/third_party/blink/renderer/core/editing/commands/editor_command.cc index 9411126..eb76d97 100644 --- a/third_party/blink/renderer/core/editing/commands/editor_command.cc +++ b/third_party/blink/renderer/core/editing/commands/editor_command.cc
@@ -1281,7 +1281,7 @@ static const EditorInternalCommand kEditorCommands[] = { // Lists all commands in blink::WebEditingCommandType. // Must be ordered by |commandType| for index lookup. - // Covered by unit tests in EditingCommandTest.cpp + // Covered by unit tests in editing_command_test.cc {WebEditingCommandType::kAlignJustified, ExecuteJustifyFull, SupportedFromMenuOrKeyBinding, EnabledInRichlyEditableText, StateNone, ValueStateOrNull, kNotTextInsertion, CanNotExecuteWhenDisabled},
diff --git a/third_party/blink/renderer/core/editing/commands/editor_command_names.h b/third_party/blink/renderer/core/editing/commands/editor_command_names.h index 6be74053..95e822f 100644 --- a/third_party/blink/renderer/core/editing/commands/editor_command_names.h +++ b/third_party/blink/renderer/core/editing/commands/editor_command_names.h
@@ -8,7 +8,7 @@ namespace blink { // Must be ordered in a case-folding manner for binary search. Covered by unit -// tests in EditingCommandTest.cpp (not able to use static_assert) +// tests in editing_command_test.cc (not able to use static_assert) #define FOR_EACH_BLINK_EDITING_COMMAND_NAME(V) \ V(AlignCenter) \ V(AlignJustified) \
diff --git a/third_party/blink/renderer/core/editing/commands/insert_list_command.cc b/third_party/blink/renderer/core/editing/commands/insert_list_command.cc index 0213285..625716e 100644 --- a/third_party/blink/renderer/core/editing/commands/insert_list_command.cc +++ b/third_party/blink/renderer/core/editing/commands/insert_list_command.cc
@@ -363,8 +363,8 @@ DCHECK(HasEditableStyle(*list_element)); DCHECK(HasEditableStyle(*list_element->parentNode())); if (!list_element->HasTagName(list_tag)) { - // |listChildNode| will be removed from the list and a list of type - // |m_type| will be created. + // |list_child_node| will be removed from the list and a list of type + // |type_| will be created. switch_list_type = true; }
diff --git a/third_party/blink/renderer/core/editing/commands/insert_text_command.cc b/third_party/blink/renderer/core/editing/commands/insert_text_command.cc index 3f47650..c843bc3b 100644 --- a/third_party/blink/renderer/core/editing/commands/insert_text_command.cc +++ b/third_party/blink/renderer/core/editing/commands/insert_text_command.cc
@@ -248,7 +248,7 @@ if (placeholder.IsNotNull()) RemovePlaceholderAt(placeholder); } else { - // Make sure the document is set up to receive m_text + // Make sure the document is set up to receive text_ start_position = PositionInsideTextNode(start_position, editing_state); if (editing_state->IsAborted()) return;
diff --git a/third_party/blink/renderer/core/editing/commands/replace_selection_command.cc b/third_party/blink/renderer/core/editing/commands/replace_selection_command.cc index 3b4d2fb..d39ff1b 100644 --- a/third_party/blink/renderer/core/editing/commands/replace_selection_command.cc +++ b/third_party/blink/renderer/core/editing/commands/replace_selection_command.cc
@@ -804,7 +804,7 @@ const { // TODO(editing-dev): Hoist the call and change it into a DCHECK. GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets(); - // TODO(yosin): We should set |m_endOfInsertedContent| not in SELECT + // TODO(yosin): We should set |end_of_inserted_content_| not in SELECT // element, since contents of SELECT elements, e.g. OPTION, OPTGROUP, are // not editable, or SELECT element is an atomic on editing. HTMLSelectElement* enclosing_select = ToHTMLSelectElement( @@ -956,7 +956,7 @@ GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets(); - // Merging forward will remove m_endOfInsertedContent from the document. + // Merging forward will remove end_of_inserted_content from the document. if (merge_forward) { const VisibleSelection& visible_selection = EndingVisibleSelection(); if (start_of_inserted_content_.IsOrphan()) { @@ -964,8 +964,8 @@ visible_selection.VisibleStart().DeepEquivalent(); } end_of_inserted_content_ = visible_selection.VisibleEnd().DeepEquivalent(); - // If we merged text nodes, m_endOfInsertedContent could be null. If - // this is the case, we use m_startOfInsertedContent. + // If we merged text nodes, end_of_inserted_content_ could be null. If + // this is the case, we use start_of_inserted_content_. if (end_of_inserted_content_.IsNull()) end_of_inserted_content_ = start_of_inserted_content_; } @@ -1723,8 +1723,8 @@ InsertNodeAfter(node, end_node, editing_state); if (editing_state->IsAborted()) return; - // Make sure that |updateNodesInserted| does not change - // |m_startOfInsertedContent|. + // Make sure that |UpdateNodesInserted| does not change + // |start_of_inserted_content|. DCHECK(start_of_inserted_content_.IsNotNull()); UpdateNodesInserted(node); } @@ -1761,9 +1761,9 @@ } else { Text* node = GetDocument().CreateEditingTextNode( collapse_white_space ? NonBreakingSpaceString() : " "); - // Don't updateNodesInserted. Doing so would set m_endOfInsertedContent to - // be the node containing the leading space, but m_endOfInsertedContent is - // supposed to mark the end of pasted content. + // Don't UpdateNodesInserted. Doing so would set end_of_inserted_content_ + // to be the node containing the leading space, but + // end_of_inserted_content_ issupposed to mark the end of pasted content. InsertNodeBefore(node, start_node, editing_state); if (editing_state->IsAborted()) return; @@ -1921,9 +1921,9 @@ InputEvent::InputType ReplaceSelectionCommand::GetInputType() const { // |ReplaceSelectionCommand| could be used with Paste, Drag&Drop, // InsertFragment and |TypingCommand|. - // 1. Paste, Drag&Drop, InsertFragment should rely on correct |m_inputType|. - // 2. |TypingCommand| will supply the |inputType()|, so |m_inputType| could - // default to |InputType::None|. + // 1. Paste, Drag&Drop, InsertFragment should rely on correct |input_type_|. + // 2. |TypingCommand| will supply the |GetInputType()|, so |input_type_| could + // default to |InputType::kNone|. return input_type_; }
diff --git a/third_party/blink/renderer/core/editing/commands/smart_replace_icu.cc b/third_party/blink/renderer/core/editing/commands/smart_replace_icu.cc index 759a1c2..496d5a9 100644 --- a/third_party/blink/renderer/core/editing/commands/smart_replace_icu.cc +++ b/third_party/blink/renderer/core/editing/commands/smart_replace_icu.cc
@@ -43,8 +43,9 @@ uset_add(smart_set, string[i]); } -// This is mostly a port of the code in WebCore/editing/SmartReplaceCF.cpp -// except we use icu in place of CoreFoundations character classes. +// This is mostly a port of the code in +// core/editing/commands/smart_replace_cf.cc except we use icu in place of +// CoreFoundations character classes. static USet* GetSmartSet(bool is_previous_character) { static USet* pre_smart_set = nullptr; static USet* post_smart_set = nullptr;
diff --git a/third_party/blink/renderer/core/editing/dom_selection.h b/third_party/blink/renderer/core/editing/dom_selection.h index 2b68830..430adb0 100644 --- a/third_party/blink/renderer/core/editing/dom_selection.h +++ b/third_party/blink/renderer/core/editing/dom_selection.h
@@ -112,7 +112,7 @@ void UpdateFrameSelection(const SelectionInDOMTree&, Range*, const SetSelectionOptions&) const; - // Convenience methods for accessors, does not check m_frame present. + // Convenience methods for accessors, does not check owner Frame presence. VisibleSelection GetVisibleSelection() const; bool IsBaseFirstInSelection() const; const Position& AnchorPosition() const;
diff --git a/third_party/blink/renderer/core/editing/editing_strategy.cc b/third_party/blink/renderer/core/editing/editing_strategy.cc index 7a7cca6..2995371 100644 --- a/third_party/blink/renderer/core/editing/editing_strategy.cc +++ b/third_party/blink/renderer/core/editing/editing_strategy.cc
@@ -40,7 +40,7 @@ return 0; // editingIgnoresContent uses the same logic in - // isEmptyNonEditableNodeInEditable (EditingUtilities.cpp). We don't + // IsEmptyNonEditableNodeInEditable (editing_utilities.cc). We don't // understand why this function returns 1 even when the node doesn't have // children. return 1;
diff --git a/third_party/blink/renderer/core/editing/editing_style.cc b/third_party/blink/renderer/core/editing/editing_style.cc index 75fba860..44dfbd757 100644 --- a/third_party/blink/renderer/core/editing/editing_style.cc +++ b/third_party/blink/renderer/core/editing/editing_style.cc
@@ -271,7 +271,7 @@ : HTMLElementEquivalent(CSSPropertyTextDecorationLine, primitive_value, tag_name) -// m_propertyID is used in HTMLElementEquivalent::addToStyle +// CSSPropertyTextDecorationLine is used in HTMLElementEquivalent::AddToStyle {} bool HTMLTextDecorationEquivalent::PropertyExistsInStyle(
diff --git a/third_party/blink/renderer/core/editing/ephemeral_range.h b/third_party/blink/renderer/core/editing/ephemeral_range.h index d51b650..c247e84e 100644 --- a/third_party/blink/renderer/core/editing/ephemeral_range.h +++ b/third_party/blink/renderer/core/editing/ephemeral_range.h
@@ -33,7 +33,7 @@ }; // This class acts like |TraversalNextIterator| but in addition -// it allows to set current position and checks |m_current| pointer before +// it allows to set current position and checks |current_| pointer before // dereferencing. template <class TraversalNext> class CheckedTraversalNextIterator
diff --git a/third_party/blink/renderer/core/editing/finder/text_finder.cc b/third_party/blink/renderer/core/editing/finder/text_finder.cc index 95c4e1d1..408dab3 100644 --- a/third_party/blink/renderer/core/editing/finder/text_finder.cc +++ b/third_party/blink/renderer/core/editing/finder/text_finder.cc
@@ -497,7 +497,7 @@ } // If the Find function found a match it will have stored where the - // match was found in m_activeSelectionRect on the current frame. If we + // match was found in active_selection_rect_ on the current frame. If we // find this rect during scoping it means we have found the active // tickmark. bool found_active_match = false;
diff --git a/third_party/blink/renderer/core/editing/finder/text_finder.h b/third_party/blink/renderer/core/editing/finder/text_finder.h index 65c7c6b..da148edf 100644 --- a/third_party/blink/renderer/core/editing/finder/text_finder.h +++ b/third_party/blink/renderer/core/editing/finder/text_finder.h
@@ -242,7 +242,7 @@ // Keeps track of how many matches this frame has found so far, so that we // don't lose count between scoping efforts, and is also used (in conjunction - // with m_lastSearchString) to figure out if we need to search the frame + // with last_search_string_) to figure out if we need to search the frame // again. int last_match_count_;
diff --git a/third_party/blink/renderer/core/editing/frame_selection.cc b/third_party/blink/renderer/core/editing/frame_selection.cc index ed727836..ea47d4f 100644 --- a/third_party/blink/renderer/core/editing/frame_selection.cc +++ b/third_party/blink/renderer/core/editing/frame_selection.cc
@@ -242,7 +242,7 @@ if (!GetSelectionInDOMTree().IsNone() && !options.DoNotSetFocus()) { SetFocusedNodeIfNeeded(); // |setFocusedNodeIfNeeded()| dispatches sync events "FocusOut" and - // "FocusIn", |m_frame| may associate to another document. + // "FocusIn", |frame_| may associate to another document. if (!IsAvailable() || GetDocument() != current_document) { // Once we get test case to reach here, we should change this // if-statement to |DCHECK()|. @@ -1123,7 +1123,7 @@ } GranularityStrategy* FrameSelection::GetGranularityStrategy() { - // We do lazy initalization for m_granularityStrategy, because if we + // We do lazy initialization for granularity_strategy_, because if we // initialize it right in the constructor - the correct settings may not be // set yet. SelectionStrategy strategy_type = SelectionStrategy::kCharacter;
diff --git a/third_party/blink/renderer/core/editing/granularity_strategy_test.cc b/third_party/blink/renderer/core/editing/granularity_strategy_test.cc index d743e32..6542a2d 100644 --- a/third_party/blink/renderer/core/editing/granularity_strategy_test.cc +++ b/third_party/blink/renderer/core/editing/granularity_strategy_test.cc
@@ -43,7 +43,7 @@ Text* AppendTextNode(const String& data); void SetInnerHTML(const char*); - // Parses the text node, appending the info to m_letterPos and m_wordMiddles. + // Parses the text node, appending the info to letter_pos_ and word_middles_. void ParseText(Text*); void ParseText(const TextNodeVector&); @@ -74,7 +74,7 @@ // tested. Vector<IntPoint> letter_pos_; // Pixel coordinates of the middles of the words in the text being tested. - // (y coordinate is based on y coordinates of m_letterPos) + // (y coordinate is based on y coordinates of letter_pos_) Vector<IntPoint> word_middles_; };
diff --git a/third_party/blink/renderer/core/editing/ime/input_method_controller.cc b/third_party/blink/renderer/core/editing/ime/input_method_controller.cc index efd30e68..a4f43ae 100644 --- a/third_party/blink/renderer/core/editing/ime/input_method_controller.cc +++ b/third_party/blink/renderer/core/editing/ime/input_method_controller.cc
@@ -181,7 +181,7 @@ case TypingCommand::TextCompositionType::kTextCompositionCancel: // TODO(chongz): Use TypingCommand::insertText after TextEvent was // removed. (Removed from spec since 2012) - // See TextEvent.idl. + // See text_event.idl. frame.GetEventHandler().HandleTextInputEvent(text, nullptr, kTextEventInputComposition); break;
diff --git a/third_party/blink/renderer/core/editing/inline_box_position.h b/third_party/blink/renderer/core/editing/inline_box_position.h index a95fd02..464ff16 100644 --- a/third_party/blink/renderer/core/editing/inline_box_position.h +++ b/third_party/blink/renderer/core/editing/inline_box_position.h
@@ -83,7 +83,7 @@ // The print for |InlineBoxPosition| is available only for testing // in "webkit_unit_tests", and implemented in -// "core/editing/InlineBoxPositionTest.cpp". +// "core/editing/inline_box_position_test.cc". std::ostream& operator<<(std::ostream&, const InlineBoxPosition&); } // namespace blink
diff --git a/third_party/blink/renderer/core/editing/iterators/character_iterator.cc b/third_party/blink/renderer/core/editing/iterators/character_iterator.cc index 4bccec3..cfff0d204 100644 --- a/third_party/blink/renderer/core/editing/iterators/character_iterator.cc +++ b/third_party/blink/renderer/core/editing/iterators/character_iterator.cc
@@ -138,7 +138,7 @@ at_break_ = false; - // easy if there is enough left in the current m_textIterator run + // easy if there is enough left in the current text_iterator_ run int remaining = text_iterator_.length() - run_offset_; if (count < remaining) { run_offset_ += count; @@ -146,30 +146,30 @@ return; } - // exhaust the current m_textIterator run + // exhaust the current text_iterator_ run count -= remaining; offset_ += remaining; - // move to a subsequent m_textIterator run + // move to a subsequent text_iterator_ run for (text_iterator_.Advance(); !AtEnd(); text_iterator_.Advance()) { int run_length = text_iterator_.length(); if (!run_length) { at_break_ = text_iterator_.BreaksAtReplacedElement(); } else { - // see whether this is m_textIterator to use + // see whether this is text_iterator_ to use if (count < run_length) { run_offset_ = count; offset_ += count; return; } - // exhaust this m_textIterator run + // exhaust this text_iterator_ run count -= run_length; offset_ += run_length; } } - // ran to the end of the m_textIterator... no more runs left + // ran to the end of the text_iterator_... no more runs left at_break_ = true; run_offset_ = 0; }
diff --git a/third_party/blink/renderer/core/editing/iterators/fully_clipped_state_stack.cc b/third_party/blink/renderer/core/editing/iterators/fully_clipped_state_stack.cc index 4955e7f..d19897a 100644 --- a/third_party/blink/renderer/core/editing/iterators/fully_clipped_state_stack.cc +++ b/third_party/blink/renderer/core/editing/iterators/fully_clipped_state_stack.cc
@@ -53,10 +53,10 @@ const Node* node) { DCHECK_EQ(size(), DepthCrossingShadowBoundaries<Strategy>(*node)); - // FIXME: m_fullyClippedStack was added in response to + // FIXME: fully_clipped_stack_ was added in response to // <https://bugs.webkit.org/show_bug.cgi?id=26364> ("Search can find text // that's hidden by overflow:hidden"), but the logic here will not work - // correctly if a shadow tree redistributes nodes. m_fullyClippedStack relies + // correctly if a shadow tree redistributes nodes. fully_clipped_stack_ relies // on the assumption that DOM node hierarchy matches the layout tree, which is // not necessarily true if there happens to be shadow DOM distribution or // other mechanics that shuffle around the layout objects regardless of node
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 203fa7b..8653c5c 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
@@ -127,14 +127,14 @@ Member<const Node> end_node_; int end_offset_; - // Whether m_node has advanced beyond the iteration range (i.e. m_startNode). + // Whether m_node has advanced beyond the iteration range (i.e. start_node_). bool have_passed_start_node_; // Should handle first-letter layoutObject in the next call to handleTextNode. bool should_handle_first_letter_; - // Used when m_stopsOnFormControls is set to determine if the iterator should - // keep advancing. + // Used when behavior_.StopOnFormControls() is true to determine if the + // iterator should keep advancing. bool should_stop_; };
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 04e4ee88..a81a347 100644 --- a/third_party/blink/renderer/core/editing/iterators/text_iterator.cc +++ b/third_party/blink/renderer/core/editing/iterators/text_iterator.cc
@@ -132,7 +132,7 @@ return nullptr; } -// Figure out the initial value of m_shadowDepth: the depth of startContainer's +// Figure out the initial value of shadow_depth_: the depth of start_container's // tree scope from the common ancestor tree scope. template <typename Strategy> unsigned ShadowDepthOf(const Node& start_container, const Node& end_container); @@ -241,12 +241,12 @@ bool TextIteratorAlgorithm<Strategy>::HandleRememberedProgress() { // Handle remembered node that needed a newline after the text node's newline if (needs_another_newline_) { - // Emit the extra newline, and position it *inside* m_node, after m_node's + // Emit the extra newline, and position it *inside* node_, after node_'s // contents, in case it's a block, in the same way that we position the // first newline. The range for the emitted newline should start where the // line break begins. // FIXME: It would be cleaner if we emitted two newlines during the last - // iteration, instead of using m_needsAnotherNewline. + // iteration, instead of using needs_another_newline_. Node* last_child = Strategy::LastChild(*node_); const Node* base_node = last_child ? last_child : node_.Get(); EmitChar16AfterNode('\n', *base_node); @@ -645,7 +645,7 @@ return node->HasTagName(pTag); } -// Whether or not we should emit a character as we enter m_node (if it's a +// Whether or not we should emit a character as we enter node_ (if it's a // container) or as we hit it (if it's atomic). template <typename Strategy> bool TextIteratorAlgorithm<Strategy>::ShouldRepresentNodeOffsetZero() { @@ -676,15 +676,15 @@ return false; // If we are outside the start container's subtree, assume we need to emit. - // FIXME: m_startContainer could be an inline block + // FIXME: start_container_ could be an inline block if (!Strategy::IsDescendantOf(*node_, *start_container_)) return true; - // If we started as m_startContainer offset 0 and the current node is a + // If we started as start_container_ offset 0 and the current node is a // descendant of the start container, we already had enough context to // correctly decide whether to emit after a preceding block. We chose not to - // emit (m_hasEmitted is false), so don't second guess that now. - // NOTE: Is this really correct when m_node is not a leftmost descendant? + // emit (has_emitted_ is false), so don't second guess that now. + // NOTE: Is this really correct when node_ is not a leftmost descendant? // Probably immaterial since we likely would have already emitted something by // now. if (!start_offset_) @@ -727,15 +727,15 @@ template <typename Strategy> void TextIteratorAlgorithm<Strategy>::RepresentNodeOffsetZero() { - // Emit a character to show the positioning of m_node. + // Emit a character to show the positioning of 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 + // ShouldRepresentNodeOffsetZero() can create VisiblePositions, which is // expensive. So, we perform the inexpensive checks on m_node to see if it // necessitates emitting a character first and will early return before - // encountering shouldRepresentNodeOffsetZero()s worse case behavior. + // encountering ShouldRepresentNodeOffsetZero()s worse case behavior. if (ShouldEmitTabBeforeNode(*node_)) { if (ShouldRepresentNodeOffsetZero()) EmitChar16BeforeNode('\t', *node_); @@ -763,18 +763,18 @@ void TextIteratorAlgorithm<Strategy>::ExitNode() { // prevent emitting a newline when exiting a collapsed block at beginning of // the range - // FIXME: !m_hasEmitted does not necessarily mean there was a collapsed + // FIXME: !has_emitted_ does not necessarily mean there was a collapsed // block... it could have been an hr (e.g.). Also, a collapsed block could // have height (e.g. a table) and therefore look like a blank line. if (!text_state_.HasEmitted()) return; - // Emit with a position *inside* m_node, after m_node's contents, in + // Emit with a position *inside* node_, after node_'s contents, in // case it is a block, because the run should start where the // emitted character is positioned visually. Node* last_child = Strategy::LastChild(*node_); const Node* base_node = last_child ? last_child : node_.Get(); - // FIXME: This shouldn't require the m_lastTextNode to be true, but we can't + // FIXME: This shouldn't require the last_text_node to be true, but we can't // change that without making the logic in _web_attributedStringFromRange // match. We'll get that for free when we switch to use TextIterator in // _web_attributedStringFromRange. See <rdar://problem/5428427> for an example
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 51fd761..b2c2091ec 100644 --- a/third_party/blink/renderer/core/editing/iterators/text_iterator.h +++ b/third_party/blink/renderer/core/editing/iterators/text_iterator.h
@@ -215,7 +215,7 @@ const unsigned start_offset_; const Member<const Node> end_container_; const unsigned end_offset_; - // |m_endNode| stores |Strategy::childAt(*m_endContainer, m_endOffset - 1)|, + // |end_node_| stores |Strategy::ChildAt(*end_container_, end_offfset_ - 1)|, // if it exists, or |nullptr| otherwise. const Member<const Node> end_node_; const Member<const Node> past_end_node_;
diff --git a/third_party/blink/renderer/core/editing/local_caret_rect.h b/third_party/blink/renderer/core/editing/local_caret_rect.h index 3a9c15a..e8e8dc7 100644 --- a/third_party/blink/renderer/core/editing/local_caret_rect.h +++ b/third_party/blink/renderer/core/editing/local_caret_rect.h
@@ -49,7 +49,7 @@ CORE_EXPORT IntRect AbsoluteSelectionBoundsOf(const VisiblePosition&); CORE_EXPORT IntRect AbsoluteSelectionBoundsOf(const VisiblePositionInFlatTree&); -// Exposed to tests only. Implemented in LocalCaretRectTest.cpp. +// Exposed to tests only. Implemented in local_caret_rect_test.cc. bool operator==(const LocalCaretRect&, const LocalCaretRect&); std::ostream& operator<<(std::ostream&, const LocalCaretRect&);
diff --git a/third_party/blink/renderer/core/editing/markers/document_marker_controller.cc b/third_party/blink/renderer/core/editing/markers/document_marker_controller.cc index cfad8dd..8c5ce7f5 100644 --- a/third_party/blink/renderer/core/editing/markers/document_marker_controller.cc +++ b/third_party/blink/renderer/core/editing/markers/document_marker_controller.cc
@@ -265,19 +265,19 @@ DocumentMarker* const new_marker = create_marker_from_offsets( start_offset_in_current_container, end_offset_in_current_container); - AddMarkerToNode(node, new_marker); + AddMarkerToNode(ToText(node), new_marker); } } -void DocumentMarkerController::AddMarkerToNode(const Node& node, +void DocumentMarkerController::AddMarkerToNode(const Text& text, DocumentMarker* new_marker) { - DCHECK_GE(ToText(node).length(), new_marker->EndOffset()); + DCHECK_GE(text.length(), new_marker->EndOffset()); possibly_existing_marker_types_ = possibly_existing_marker_types_.Add( DocumentMarker::MarkerTypes(new_marker->GetType())); SetContext(document_); Member<MarkerLists>& markers = - markers_.insert(&node, nullptr).stored_value->value; + markers_.insert(&text, nullptr).stored_value->value; if (!markers) { markers = new MarkerLists; markers->Grow(DocumentMarker::kMarkerTypeIndexesCount); @@ -290,7 +290,7 @@ DocumentMarkerList* const list = ListForType(markers, new_marker_type); list->Add(new_marker); - InvalidatePaintForNode(node); + InvalidatePaintForNode(text); } // Moves markers from src_node to dst_node. Markers are moved if their start @@ -340,6 +340,9 @@ unsigned start_offset, int length, DocumentMarker::MarkerTypes marker_types) { + // TODO(yoichio): Make this function to take Text instead of Node. + if (!node.IsTextNode()) + return; if (length <= 0) return; @@ -347,7 +350,7 @@ return; DCHECK(!(markers_.IsEmpty())); - MarkerLists* const markers = markers_.at(&node); + MarkerLists* const markers = markers_.at(&ToText(node)); if (!markers) return; @@ -374,7 +377,7 @@ } if (empty_lists_count == DocumentMarker::kMarkerTypeIndexesCount) { - markers_.erase(&node); + markers_.erase(&ToText(node)); if (markers_.IsEmpty()) { possibly_existing_marker_types_ = DocumentMarker::MarkerTypes(); SetContext(nullptr); @@ -439,7 +442,9 @@ range.EndPosition().ComputeOffsetInContainerNode(); for (Node& node : range.Nodes()) { - MarkerLists* const markers = markers_.at(&node); + if (!node.IsTextNode()) + continue; + MarkerLists* const markers = markers_.at(&ToText(node)); if (!markers) continue; @@ -628,7 +633,10 @@ void DocumentMarkerController::InvalidateRectsForTextMatchMarkersInNode( const Node& node) { - MarkerLists* markers = markers_.at(&node); + // TODO(yoichio): Make this function to take Text instead of Node. + if (!node.IsTextNode()) + return; + MarkerLists* markers = markers_.at(&ToText(node)); const DocumentMarkerList* const marker_list = ListForType(markers, DocumentMarker::kTextMatch); @@ -645,7 +653,7 @@ void DocumentMarkerController::InvalidateRectsForAllTextMatchMarkers() { for (auto& node_markers : markers_) { - const Node& node = *node_markers.key; + const Text& node = *node_markers.key; InvalidateRectsForTextMatchMarkersInNode(node); } } @@ -669,11 +677,14 @@ void DocumentMarkerController::RemoveMarkersForNode( const Node* node, DocumentMarker::MarkerTypes marker_types) { + // TODO(yoichio): Make this function to take Text instead of Node. + if (!node->IsTextNode()) + return; if (!PossiblyHasMarkers(marker_types)) return; DCHECK(!markers_.IsEmpty()); - MarkerMap::iterator iterator = markers_.find(node); + MarkerMap::iterator iterator = markers_.find(ToText(node)); if (iterator != markers_.end()) RemoveMarkersFromList(iterator, marker_types); } @@ -681,18 +692,16 @@ void DocumentMarkerController::RemoveSpellingMarkersUnderWords( const Vector<String>& words) { for (auto& node_markers : markers_) { - const Node& node = *node_markers.key; - if (!node.IsTextNode()) - continue; + const Text& text = *node_markers.key; MarkerLists* markers = node_markers.value; for (DocumentMarker::MarkerType type : DocumentMarker::MarkerTypes::Misspelling()) { DocumentMarkerList* const list = ListForType(markers, type); if (!list) continue; - if (ToSpellCheckMarkerListImpl(list)->RemoveMarkersUnderWords( - ToText(node).data(), words)) { - InvalidatePaintForNode(node); + if (ToSpellCheckMarkerListImpl(list)->RemoveMarkersUnderWords(text.data(), + words)) { + InvalidatePaintForNode(text); } } } @@ -700,7 +709,10 @@ void DocumentMarkerController::RemoveSuggestionMarkerByTag(const Node* node, int32_t marker_tag) { - MarkerLists* markers = markers_.at(node); + // TODO(yoichio): Make this function to take Text instead of Node. + if (!node->IsTextNode()) + return; + MarkerLists* markers = markers_.at(ToText(node)); SuggestionMarkerListImpl* const list = ToSuggestionMarkerListImpl( ListForType(markers, DocumentMarker::kSuggestion)); if (!list->RemoveMarkerByTag(marker_tag)) @@ -714,7 +726,7 @@ return; DCHECK(!markers_.IsEmpty()); - HeapVector<Member<const Node>> nodes_with_markers; + HeapVector<Member<const Text>> nodes_with_markers; CopyKeysToVector(markers_, nodes_with_markers); unsigned size = nodes_with_markers.size(); for (unsigned i = 0; i < size; ++i) { @@ -782,19 +794,16 @@ return; DCHECK(!markers_.IsEmpty()); - // outer loop: process each markered node in the document - MarkerMap::iterator end = markers_.end(); - for (MarkerMap::iterator i = markers_.begin(); i != end; ++i) { - const Node* node = i->key; - - // inner loop: process each marker in the current node - MarkerLists* markers = i->value.Get(); + // outer loop: process each markered Text in the document + for (auto& iterator : markers_) { + // inner loop: process each marker in the current Text + MarkerLists* markers = iterator.value.Get(); for (DocumentMarker::MarkerType type : DocumentMarker::MarkerTypes::All()) { DocumentMarkerList* const list = ListForType(markers, type); if (!list || list->IsEmpty() || !marker_types.Contains(type)) continue; - InvalidatePaintForNode(*node); + InvalidatePaintForNode(*iterator.key); } } } @@ -832,7 +841,10 @@ unsigned start_offset, unsigned end_offset, bool active) { - MarkerLists* markers = markers_.at(node); + // TODO(yoichio): Make this function to take Text instead of Node. + if (!node->IsTextNode()) + return false; + MarkerLists* markers = markers_.at(ToText(node)); if (!markers) return false; @@ -853,10 +865,8 @@ #ifndef NDEBUG void DocumentMarkerController::ShowMarkers() const { StringBuilder builder; - MarkerMap::const_iterator end = markers_.end(); - for (MarkerMap::const_iterator node_iterator = markers_.begin(); - node_iterator != end; ++node_iterator) { - const Node* node = node_iterator->key; + for (auto& node_iterator : markers_) { + const Text* node = node_iterator.key; builder.Append(String::Format("%p", node)); MarkerLists* markers = markers_.at(node); for (DocumentMarker::MarkerType type : DocumentMarker::MarkerTypes::All()) { @@ -895,8 +905,9 @@ if (!PossiblyHasMarkers(DocumentMarker::MarkerTypes::All())) return; DCHECK(!markers_.IsEmpty()); - - MarkerLists* markers = markers_.at(node); + if (!node->IsTextNode()) + return; + MarkerLists* markers = markers_.at(ToText(node)); if (!markers) return;
diff --git a/third_party/blink/renderer/core/editing/markers/document_marker_controller.h b/third_party/blink/renderer/core/editing/markers/document_marker_controller.h index 47c3339..5496355 100644 --- a/third_party/blink/renderer/core/editing/markers/document_marker_controller.h +++ b/third_party/blink/renderer/core/editing/markers/document_marker_controller.h
@@ -143,11 +143,11 @@ void AddMarkerInternal( const EphemeralRange&, std::function<DocumentMarker*(int, int)> create_marker_from_offsets); - void AddMarkerToNode(const Node&, DocumentMarker*); + void AddMarkerToNode(const Text&, DocumentMarker*); using MarkerLists = HeapVector<Member<DocumentMarkerList>, DocumentMarker::kMarkerTypeIndexesCount>; - using MarkerMap = HeapHashMap<WeakMember<const Node>, Member<MarkerLists>>; + using MarkerMap = HeapHashMap<WeakMember<const Text>, Member<MarkerLists>>; static Member<DocumentMarkerList>& ListForType(MarkerLists*, DocumentMarker::MarkerType); bool PossiblyHasMarkers(DocumentMarker::MarkerTypes) const;
diff --git a/third_party/blink/renderer/core/editing/markers/grammar_marker_list_impl_test.cc b/third_party/blink/renderer/core/editing/markers/grammar_marker_list_impl_test.cc index d4ad416f..29192ae 100644 --- a/third_party/blink/renderer/core/editing/markers/grammar_marker_list_impl_test.cc +++ b/third_party/blink/renderer/core/editing/markers/grammar_marker_list_impl_test.cc
@@ -11,7 +11,7 @@ namespace blink { // Functionality implemented in SpellCheckMarkerListImpl is tested in -// SpellingMarkerListImplTest.cpp. +// spelling_marker_list_impl_test.cc. class GrammarMarkerListImplTest : public testing::Test { protected:
diff --git a/third_party/blink/renderer/core/editing/position.h b/third_party/blink/renderer/core/editing/position.h index f19cca9..f36799c 100644 --- a/third_party/blink/renderer/core/editing/position.h +++ b/third_party/blink/renderer/core/editing/position.h
@@ -133,12 +133,12 @@ } // Returns an offset for editing based on anchor type for using with - // |anchorNode()| function: - // - OffsetInAnchor m_offset - // - BeforeChildren 0 - // - BeforeAnchor 0 - // - AfterChildren last editing offset in anchor node - // - AfterAnchor last editing offset in anchor node + // |AnchorNode()| function: + // - kOffsetInAnchor offset_ + // - kBeforeChildren 0 + // - kBeforeAnchor 0 + // - kAfterChildren last editing offset in anchor node + // - kAfterAnchor last editing offset in anchor node // Editing operations will change in anchor node rather than nodes around // anchor node. int ComputeEditingOffset() const; @@ -231,10 +231,10 @@ // TODO(editing-dev): Since we should consider |Position| is constant in // tree, we should use |Member<const Node>|. see http://crbug.com/735327 Member<Node> anchor_node_; - // m_offset can be the offset inside m_anchorNode, or if - // editingIgnoresContent(m_anchorNode) returns true, then other places in - // editing will treat m_offset == 0 as "before the anchor" and m_offset > 0 as - // "after the anchor node". See parentAnchoredEquivalent for more info. + // offset_ can be the offset inside anchor_node_, or if + // EditingIgnoresContent(anchor_node_) returns true, then other places in + // editing will treat offset_ == 0 as "before the anchor" and offset_ > 0 as + // "after the anchor node". See ParentAnchoredEquivalent for more info. int offset_; PositionAnchorType anchor_type_; };
diff --git a/third_party/blink/renderer/core/editing/position_iterator.cc b/third_party/blink/renderer/core/editing/position_iterator.cc index 8cce67e..d5a5c9e 100644 --- a/third_party/blink/renderer/core/editing/position_iterator.cc +++ b/third_party/blink/renderer/core/editing/position_iterator.cc
@@ -63,7 +63,7 @@ dom_tree_version_(anchor_node->GetDocument().DomTreeVersion()) { for (Node* node = SelectableParentOf<Strategy>(*anchor_node); node; node = SelectableParentOf<Strategy>(*node)) { - // Each m_offsetsInAnchorNode[offset] should be an index of node in + // Each offsets_in_anchor_node_[offset] should be an index of node in // parent, but delay to calculate the index until it is needed for // performance. offsets_in_anchor_node_.push_back(kInvalidOffset); @@ -126,9 +126,8 @@ // For example, position is before E, F. DCHECK_EQ(Strategy::Parent(*node_after_position_in_anchor_), anchor_node_); DCHECK_NE(offsets_in_anchor_node_[depth_to_anchor_node_], kInvalidOffset); - // TODO(yoichio): This should be equivalent to - // PositionTemplate<Strategy>(m_anchorNode, - // PositionAnchorType::BeforeAnchor); + // TODO(yoichio): This should be equivalent to PositionTemplate<Strategy>( + // anchor_node_, PositionAnchorType::kBeforeAnchor). return PositionTemplate<Strategy>( anchor_node_, offsets_in_anchor_node_[depth_to_anchor_node_]); } @@ -163,11 +162,11 @@ // +-D // |-G // +-H - // Let |anchor| as |m_anchorNode| and - // |child| as |m_nodeAfterPositionInAnchor|. + // Let |anchor| as |anchor_node_| and + // |child| as |node_after_position_in_anchor_|. if (node_after_position_in_anchor_) { // Case #1: Move to position before the first child of - // |m_nodeAfterPositionInAnchor|. + // |node_after_position_in_anchor_|. // This is a point just before |child|. // Let |anchor| is A and |child| is B, // then next |anchor| is B and |child| is E. @@ -190,10 +189,10 @@ !ShouldTraverseChildren<Strategy>(*anchor_node_) && offset_in_anchor_ < Strategy::LastOffsetForEditing(anchor_node_)) { // Case #2. This is the next of Case #1 or #2 itself. - // Position is (|anchor|, |m_offsetInAchor|). + // Position is (|anchor|, |offset_in_anchor_|). // In this case |anchor| is a leaf(E,F,C,G or H) and - // |m_offsetInAnchor| is not on the end of |anchor|. - // Then just increment |m_offsetInAnchor|. + // |offset_in_anchor_| is not on the end of |anchor|. + // Then just increment |offset_in_anchor_|. offset_in_anchor_ = NextGraphemeBoundaryOf(*anchor_node_, offset_in_anchor_); } else { @@ -239,13 +238,13 @@ // +-D // |-G // +-H - // Let |anchor| as |m_anchorNode| and - // |child| as |m_nodeAfterPositionInAnchor|. - // decrement() is complex but logically reverse of increment(), of course:) + // Let |anchor| as |anchor_node_| and + // |child| as |node_after_position_in_anchor_|. + // Decrement() is complex but logically reverse of Increment(), of course:) if (node_after_position_in_anchor_) { anchor_node_ = Strategy::PreviousSibling(*node_after_position_in_anchor_); if (anchor_node_) { - // Case #1-a. This is a revese of increment()::Case#3-a. + // Case #1-a. This is a revese of Increment()::Case#3-a. // |child| has a previous sibling. // Let |anchor| is B and |child| is F, // next |anchor| is E and |child| is null. @@ -269,7 +268,7 @@ offsets_in_anchor_node_[depth_to_anchor_node_] = offset_in_anchor_; return; } else { - // Case #1-b. This is a revese of increment()::Case#1. + // Case #1-b. This is a revese of Increment()::Case#1. // |child| doesn't have a previous sibling. // Let |anchor| is B and |child| is E, // next |anchor| is A and |child| is B. @@ -298,7 +297,7 @@ ? 0 : Strategy::LastOffsetForEditing(anchor_node_); // Decrement depth initializing with -1 because - // |m_nodeAfterPositionInAnchor| is null so still unneeded. + // |node_after_position_in_anchor_| is null so still unneeded. if (depth_to_anchor_node_ >= offsets_in_anchor_node_.size()) offsets_in_anchor_node_.push_back(kInvalidOffset); else @@ -307,17 +306,17 @@ return; } if (offset_in_anchor_ && anchor_node_->GetLayoutObject()) { - // Case #3-a. This is a reverse of increment()::Case#2. + // Case #3-a. This is a reverse of Increment()::Case#2. // In this case |anchor| is a leaf(E,F,C,G or H) and - // |m_offsetInAnchor| is not on the beginning of |anchor|. - // Then just decrement |m_offsetInAnchor|. + // |offset_in_anchor_| is not on the beginning of |anchor|. + // Then just decrement |offset_in_anchor_|. offset_in_anchor_ = PreviousGraphemeBoundaryOf(*anchor_node_, offset_in_anchor_); return; } - // Case #3-b. This is a reverse of increment()::Case#1. + // Case #3-b. This is a reverse of Increment()::Case#1. // In this case |anchor| is a leaf(E,F,C,G or H) and - // |m_offsetInAnchor| is on the beginning of |anchor|. + // |offset_in_anchor_| is on the beginning of |anchor|. // Let |anchor| is E, // next |anchor| is B and |child| is E. node_after_position_in_anchor_ = anchor_node_;
diff --git a/third_party/blink/renderer/core/editing/position_iterator.h b/third_party/blink/renderer/core/editing/position_iterator.h index 43284e02..7a43559 100644 --- a/third_party/blink/renderer/core/editing/position_iterator.h +++ b/third_party/blink/renderer/core/editing/position_iterator.h
@@ -78,14 +78,14 @@ } Member<Node> anchor_node_; - // If this is non-null, Strategy::parent(*m_nodeAfterPositionInAnchor) == - // m_anchorNode; + // If this is non-null, Strategy::Parent(*node_after_position_in_anchor_) == + // anchor_node_; Member<Node> node_after_position_in_anchor_; int offset_in_anchor_; wtf_size_t depth_to_anchor_node_; - // If |m_nodeAfterPositionInAnchor| is not null, - // m_offsetsInAnchorNode[m_depthToAnchorNode] == - // Strategy::index(m_nodeAfterPositionInAnchor). + // If |node_after_position_in_anchor_| is not null, + // offsets_in_anchor_node_[depth_to_anchor_node_] == + // Strategy::Index(node_after_position_in_anchor_). Vector<int> offsets_in_anchor_node_; uint64_t dom_tree_version_; };
diff --git a/third_party/blink/renderer/core/editing/position_with_affinity.h b/third_party/blink/renderer/core/editing/position_with_affinity.h index 008ffbc..132de6af 100644 --- a/third_party/blink/renderer/core/editing/position_with_affinity.h +++ b/third_party/blink/renderer/core/editing/position_with_affinity.h
@@ -28,8 +28,8 @@ TextAffinity Affinity() const { return affinity_; } const PositionTemplate<Strategy>& GetPosition() const { return position_; } - // Returns true if both |this| and |other| is null or both |m_position| - // and |m_affinity| equal. + // Returns true if both |this| and |other| is null or both |position_| + // and |affinity_| equal. bool operator==(const PositionWithAffinityTemplate& other) const; bool operator!=(const PositionWithAffinityTemplate& other) const { return !operator==(other);
diff --git a/third_party/blink/renderer/core/editing/selection_controller.cc b/third_party/blink/renderer/core/editing/selection_controller.cc index e7e6162..7a774f5b 100644 --- a/third_party/blink/renderer/core/editing/selection_controller.cc +++ b/third_party/blink/renderer/core/editing/selection_controller.cc
@@ -557,7 +557,7 @@ return false; } - // |dispatchSelectStart()| can change document hosted by |m_frame|. + // |DispatchSelectStart()| can change document hosted by |frame_|. if (!this->Selection().IsAvailable()) return false; @@ -888,8 +888,8 @@ if (Selection().ComputeVisibleSelectionInDOMTreeDeprecated().IsRange()) { // A double-click when range is already selected // should not change the selection. So, do not call - // selectClosestWordFromMouseEvent, but do set - // m_beganSelectingText to prevent handleMouseReleaseEvent + // SelectClosestWordFromMouseEvent, but do set + // began_selecting_text_ to prevent HandleMouseReleaseEvent // from setting caret selection. selection_state_ = SelectionState::kExtendedSelection; return true;
diff --git a/third_party/blink/renderer/core/editing/selection_controller.h b/third_party/blink/renderer/core/editing/selection_controller.h index e16e007..636332b5 100644 --- a/third_party/blink/renderer/core/editing/selection_controller.h +++ b/third_party/blink/renderer/core/editing/selection_controller.h
@@ -119,7 +119,7 @@ FrameSelection& Selection() const; // Implements |DocumentShutdownObserver|. - // TODO(yosin): We should relocate |m_originalBaseInFlatTree| when DOM tree + // TODO(yosin): We should relocate |original_base_in_flat_tree_| when DOM tree // changed. void ContextDestroyed(Document*) final;
diff --git a/third_party/blink/renderer/core/editing/selection_editor.cc b/third_party/blink/renderer/core/editing/selection_editor.cc index 83922c86..7fc23596 100644 --- a/third_party/blink/renderer/core/editing/selection_editor.cc +++ b/third_party/blink/renderer/core/editing/selection_editor.cc
@@ -44,7 +44,7 @@ void SelectionEditor::AssertSelectionValid() const { #if DCHECK_IS_ON() // Since We don't track dom tree version during attribute changes, we can't - // use it for validity of |m_selection|. + // use it for validity of |selection_|. const_cast<SelectionEditor*>(this)->selection_.dom_tree_version_ = GetDocument().DomTreeVersion(); #endif
diff --git a/third_party/blink/renderer/core/editing/serializers/styled_markup_serializer.cc b/third_party/blink/renderer/core/editing/serializers/styled_markup_serializer.cc index 09e14ca..a56a84e 100644 --- a/third_party/blink/renderer/core/editing/serializers/styled_markup_serializer.cc +++ b/third_party/blink/renderer/core/editing/serializers/styled_markup_serializer.cc
@@ -206,7 +206,7 @@ } } - // If there is no the highest node in the selected nodes, |m_lastClosed| can + // If there is no the highest node in the selected nodes, |last_closed_| can // be #text when its parent is a formatting tag. In this case, #text is // wrapped by <span> tag, but this text should be wrapped by the formatting // tag. See http://crbug.com/634482
diff --git a/third_party/blink/renderer/core/editing/state_machines/backward_grapheme_boundary_state_machine.h b/third_party/blink/renderer/core/editing/state_machines/backward_grapheme_boundary_state_machine.h index ff523a0a..efac1ee2 100644 --- a/third_party/blink/renderer/core/editing/state_machines/backward_grapheme_boundary_state_machine.h +++ b/third_party/blink/renderer/core/editing/state_machines/backward_grapheme_boundary_state_machine.h
@@ -55,7 +55,7 @@ // Used for composing supplementary code point with surrogate pairs. UChar trail_surrogate_ = 0; - // The code point immediately after the m_BoundaryOffset. + // The code point immediately after the boundary_offset_. UChar32 next_code_point_; // The relative offset from the begging of this state machine.
diff --git a/third_party/blink/renderer/core/editing/state_machines/forward_grapheme_boundary_state_machine.cc b/third_party/blink/renderer/core/editing/state_machines/forward_grapheme_boundary_state_machine.cc index 9b40786..9293ebf 100644 --- a/third_party/blink/renderer/core/editing/state_machines/forward_grapheme_boundary_state_machine.cc +++ b/third_party/blink/renderer/core/editing/state_machines/forward_grapheme_boundary_state_machine.cc
@@ -163,8 +163,7 @@ if (Character::IsRegionalIndicator(prev_code_point_) && Character::IsRegionalIndicator(code_point)) { if (preceding_ris_count_ % 2 == 0) { - // Odd numbered RI case, note that m_prevCodePoint is also - // RI. + // Odd numbered RI case, note that prev_code_point_ is also RI. boundary_offset_ += 2; } return Finish();
diff --git a/third_party/blink/renderer/core/editing/state_machines/forward_grapheme_boundary_state_machine.h b/third_party/blink/renderer/core/editing/state_machines/forward_grapheme_boundary_state_machine.h index 8c0a54f5..9e612dfd 100644 --- a/third_party/blink/renderer/core/editing/state_machines/forward_grapheme_boundary_state_machine.h +++ b/third_party/blink/renderer/core/editing/state_machines/forward_grapheme_boundary_state_machine.h
@@ -58,7 +58,7 @@ // Used for composing supplementary code point with surrogate pairs. UChar pending_code_unit_ = 0; - // The code point immediately before the m_BoundaryOffset. + // The code point immediately before the boundary_offset_. UChar32 prev_code_point_; // The relative offset from the begging of this state machine.
diff --git a/third_party/blink/renderer/core/editing/visible_units.cc b/third_party/blink/renderer/core/editing/visible_units.cc index efc60394..d3c3e77 100644 --- a/third_party/blink/renderer/core/editing/visible_units.cc +++ b/third_party/blink/renderer/core/editing/visible_units.cc
@@ -581,7 +581,7 @@ return VisiblePosition(); } -// TODO(yosin): We should use |associatedLayoutObjectOf()| in "VisibleUnits.cpp" +// TODO(yosin): We should use |AssociatedLayoutObjectOf()| in "visible_units.cc" // where it takes |LayoutObject| from |Position|. int CaretMinOffset(const Node* node) { @@ -990,7 +990,7 @@ if (layout_object->IsBR()) { // TODO(leviw) The condition should be - // m_anchorType == PositionAnchorType::BeforeAnchor, but for now we + // anchor_type_ == PositionAnchorType::kBeforeAnchor, but for now we // still need to support legacy positions. if (position.IsAfterAnchor()) return false;
diff --git a/third_party/blink/renderer/core/events/BUILD.gn b/third_party/blink/renderer/core/events/BUILD.gn index a88f31af..f7facc6 100644 --- a/third_party/blink/renderer/core/events/BUILD.gn +++ b/third_party/blink/renderer/core/events/BUILD.gn
@@ -60,8 +60,6 @@ "progress_event.h", "promise_rejection_event.cc", "promise_rejection_event.h", - "registered_event_listener.cc", - "registered_event_listener.h", "resource_progress_event.cc", "resource_progress_event.h", "security_policy_violation_event.cc",
diff --git a/third_party/blink/renderer/core/events/error_event.cc b/third_party/blink/renderer/core/events/error_event.cc index 46fce0c0..ba74dbe 100644 --- a/third_party/blink/renderer/core/events/error_event.cc +++ b/third_party/blink/renderer/core/events/error_event.cc
@@ -82,6 +82,10 @@ return EventNames::ErrorEvent; } +bool ErrorEvent::IsErrorEvent() const { + return true; +} + bool ErrorEvent::CanBeDispatchedInWorld(const DOMWrapperWorld& world) const { return !world_ || world_ == &world; }
diff --git a/third_party/blink/renderer/core/events/error_event.h b/third_party/blink/renderer/core/events/error_event.h index e6a8d72..c4eca9c6 100644 --- a/third_party/blink/renderer/core/events/error_event.h +++ b/third_party/blink/renderer/core/events/error_event.h
@@ -89,6 +89,7 @@ const AtomicString& InterfaceName() const override; bool CanBeDispatchedInWorld(const DOMWrapperWorld&) const override; + bool IsErrorEvent() const override; DOMWrapperWorld* World() const { return world_.get(); } @@ -112,6 +113,8 @@ scoped_refptr<DOMWrapperWorld> world_; }; +DEFINE_EVENT_TYPE_CASTS(ErrorEvent); + } // namespace blink #endif // THIRD_PARTY_BLINK_RENDERER_CORE_EVENTS_ERROR_EVENT_H_
diff --git a/third_party/blink/renderer/core/exported/web_plugin_container_impl.cc b/third_party/blink/renderer/core/exported/web_plugin_container_impl.cc index 3f485a3d..228e92e 100644 --- a/third_party/blink/renderer/core/exported/web_plugin_container_impl.cc +++ b/third_party/blink/renderer/core/exported/web_plugin_container_impl.cc
@@ -564,7 +564,7 @@ v8::Local<v8::Value> result = frame->GetScriptController().ExecuteScriptInMainWorldAndReturnValue( ScriptSourceCode(script, ScriptSourceLocationType::kJavascriptUrl), - KURL(), kNotSharableCrossOrigin); + KURL(), kOpaqueResource); // Failure is reported as a null string. if (result.IsEmpty() || !result->IsString())
diff --git a/third_party/blink/renderer/core/frame/deprecation.cc b/third_party/blink/renderer/core/frame/deprecation.cc index aa7481e..5b6b3dd 100644 --- a/third_party/blink/renderer/core/frame/deprecation.cc +++ b/third_party/blink/renderer/core/frame/deprecation.cc
@@ -473,6 +473,11 @@ ReplacedWillBeRemoved("document.registerElement", "window.customElements.define", kM73, "4642138092470272")}; + case WebFeature::kCSSSelectorPseudoUnresolved: + return { + "CSSSelectorPseudoUnresolved", kM73, + ReplacedWillBeRemoved(":unresolved pseudo selector", ":not(:defined)", + kM73, "4642138092470272")}; case WebFeature:: kEncryptedMediaDisallowedByFeaturePolicyInCrossOriginIframe:
diff --git a/third_party/blink/renderer/core/frame/dom_timer_test.cc b/third_party/blink/renderer/core/frame/dom_timer_test.cc index 1f50fb5..5398e2d 100644 --- a/third_party/blink/renderer/core/frame/dom_timer_test.cc +++ b/third_party/blink/renderer/core/frame/dom_timer_test.cc
@@ -57,7 +57,7 @@ .GetFrame() ->GetScriptController() .ExecuteScriptInMainWorldAndReturnValue(ScriptSourceCode(expr), KURL(), - kNotSharableCrossOrigin); + kOpaqueResource); } Vector<double> ToDoubleArray(v8::Local<v8::Value> value, @@ -75,7 +75,7 @@ void ExecuteScriptAndWaitUntilIdle(const char* script_text) { ScriptSourceCode script(script_text); GetDocument().GetFrame()->GetScriptController().ExecuteScriptInMainWorld( - script, KURL(), kNotSharableCrossOrigin); + script, KURL(), kOpaqueResource); platform_->RunUntilIdle(); } };
diff --git a/third_party/blink/renderer/core/frame/local_frame_view.cc b/third_party/blink/renderer/core/frame/local_frame_view.cc index 360cfa7..883ea60 100644 --- a/third_party/blink/renderer/core/frame/local_frame_view.cc +++ b/third_party/blink/renderer/core/frame/local_frame_view.cc
@@ -2307,7 +2307,9 @@ ErrorEvent* error = ErrorEvent::Create( "ResizeObserver loop limit exceeded", SourceLocation::Capture(frame_->GetDocument()), nullptr); - frame_->GetDocument()->DispatchErrorEvent(error, kNotSharableCrossOrigin); + // We're using |kSharableCrossOrigin| as the error is made by blink itself. + // TODO(yhirano): Reconsider this. + frame_->GetDocument()->DispatchErrorEvent(error, kSharableCrossOrigin); // Ensure notifications will get delivered in next cycle. ScheduleAnimation(); }
diff --git a/third_party/blink/renderer/core/frame/pausable_script_executor.cc b/third_party/blink/renderer/core/frame/pausable_script_executor.cc index 1e7e867a..980585a 100644 --- a/third_party/blink/renderer/core/frame/pausable_script_executor.cc +++ b/third_party/blink/renderer/core/frame/pausable_script_executor.cc
@@ -59,12 +59,14 @@ Vector<v8::Local<v8::Value>> results; for (const auto& source : sources_) { + // Note: An error event in an isolated world will never be dispatched to + // a foreign world. v8::Local<v8::Value> script_value = world_id_ ? frame->GetScriptController().ExecuteScriptInIsolatedWorld( - world_id_, source, KURL(), kNotSharableCrossOrigin) + world_id_, source, KURL(), kSharableCrossOrigin) : frame->GetScriptController() .ExecuteScriptInMainWorldAndReturnValue( - source, KURL(), kNotSharableCrossOrigin); + source, KURL(), kSharableCrossOrigin); results.push_back(script_value); }
diff --git a/third_party/blink/renderer/core/frame/web_local_frame_impl.cc b/third_party/blink/renderer/core/frame/web_local_frame_impl.cc index 0d021c6..00a4cd8 100644 --- a/third_party/blink/renderer/core/frame/web_local_frame_impl.cc +++ b/third_party/blink/renderer/core/frame/web_local_frame_impl.cc
@@ -680,8 +680,8 @@ void WebLocalFrameImpl::ExecuteScript(const WebScriptSource& source) { DCHECK(GetFrame()); v8::HandleScope handle_scope(ToIsolate(GetFrame())); - GetFrame()->GetScriptController().ExecuteScriptInMainWorld( - source, KURL(), kNotSharableCrossOrigin); + GetFrame()->GetScriptController().ExecuteScriptInMainWorld(source, KURL(), + kOpaqueResource); } void WebLocalFrameImpl::ExecuteScriptInIsolatedWorld( @@ -691,9 +691,11 @@ CHECK_GT(world_id, 0); CHECK_LT(world_id, DOMWrapperWorld::kEmbedderWorldIdLimit); + // Note: An error event in an isolated world will never be dispatched to + // a foreign world. v8::HandleScope handle_scope(ToIsolate(GetFrame())); GetFrame()->GetScriptController().ExecuteScriptInIsolatedWorld( - world_id, source_in, KURL(), kNotSharableCrossOrigin); + world_id, source_in, KURL(), kSharableCrossOrigin); } v8::Local<v8::Value> @@ -704,8 +706,10 @@ CHECK_GT(world_id, 0); CHECK_LT(world_id, DOMWrapperWorld::kEmbedderWorldIdLimit); + // Note: An error event in an isolated world will never be dispatched to + // a foreign world. return GetFrame()->GetScriptController().ExecuteScriptInIsolatedWorld( - world_id, source_in, KURL(), kNotSharableCrossOrigin); + world_id, source_in, KURL(), kSharableCrossOrigin); } void WebLocalFrameImpl::SetIsolatedWorldSecurityOrigin( @@ -801,8 +805,7 @@ return GetFrame() ->GetScriptController() - .ExecuteScriptInMainWorldAndReturnValue(source, KURL(), - kNotSharableCrossOrigin); + .ExecuteScriptInMainWorldAndReturnValue(source, KURL(), kOpaqueResource); } void WebLocalFrameImpl::RequestExecuteScriptAndReturnValue( @@ -2111,7 +2114,7 @@ v8::Local<v8::Value> result = GetFrame()->GetScriptController().ExecuteScriptInMainWorldAndReturnValue( ScriptSourceCode(script, ScriptSourceLocationType::kJavascriptUrl), - KURL(), kNotSharableCrossOrigin); + KURL(), kOpaqueResource); if (result.IsEmpty() || !result->IsString()) return; String script_result = ToCoreString(v8::Local<v8::String>::Cast(result));
diff --git a/third_party/blink/renderer/core/html/canvas/canvas_context_creation_attributes_core.h b/third_party/blink/renderer/core/html/canvas/canvas_context_creation_attributes_core.h index bbb5f2f..afb709b 100644 --- a/third_party/blink/renderer/core/html/canvas/canvas_context_creation_attributes_core.h +++ b/third_party/blink/renderer/core/html/canvas/canvas_context_creation_attributes_core.h
@@ -32,7 +32,7 @@ bool preserve_drawing_buffer = false; bool stencil = false; - // This attribute is of type XRDevice, defined in modules/xr/XRDevice.h + // This attribute is of type XRDevice, defined in modules/xr/xr_device.h Member<ScriptWrappable> compatible_xr_device; void Trace(blink::Visitor*);
diff --git a/third_party/blink/renderer/core/html/canvas/canvas_rendering_context.cc b/third_party/blink/renderer/core/html/canvas/canvas_rendering_context.cc index bcde1d0e..3ee397d3 100644 --- a/third_party/blink/renderer/core/html/canvas/canvas_rendering_context.cc +++ b/third_party/blink/renderer/core/html/canvas/canvas_rendering_context.cc
@@ -61,8 +61,8 @@ if (!OriginTrials::LowLatencyCanvasEnabled(host->GetTopExecutionContext())) creation_attributes_.low_latency = false; - // Make m_creationAttributes reflect the effective colorSpace and pixelFormat - // rather than the requested one. + // Make creation_attributes_ reflect the effective color_space and + // pixel_format rather than the requested one. creation_attributes_.color_space = ColorSpaceAsString(); creation_attributes_.pixel_format = PixelFormatAsString(); }
diff --git a/third_party/blink/renderer/core/html/canvas/html_canvas_element.idl b/third_party/blink/renderer/core/html/canvas/html_canvas_element.idl index 0fee23b..609b8bd 100644 --- a/third_party/blink/renderer/core/html/canvas/html_canvas_element.idl +++ b/third_party/blink/renderer/core/html/canvas/html_canvas_element.idl
@@ -29,7 +29,7 @@ interface HTMLCanvasElement : HTMLElement { // Note: Due to dependecies on modules, getContext is defined in a partial - // interface in HTMLCanvasElementModule.idl + // interface in html_canvas_element_module.idl [RaisesException=Setter, CEReactions] attribute unsigned long width; [RaisesException=Setter, CEReactions] attribute unsigned long height;
diff --git a/third_party/blink/renderer/core/html/custom/v0_custom_element_processing_stack.h b/third_party/blink/renderer/core/html/custom/v0_custom_element_processing_stack.h index 0563687..a2a799e 100644 --- a/third_party/blink/renderer/core/html/custom/v0_custom_element_processing_stack.h +++ b/third_party/blink/renderer/core/html/custom/v0_custom_element_processing_stack.h
@@ -81,11 +81,11 @@ } // The start of the element queue on the top of the processing - // stack. An offset into instance().m_flattenedProcessingStack. + // stack. An offset into Instance().flattened_processing_stack_. static wtf_size_t element_queue_start_; // The end of the element queue on the top of the processing - // stack. A cache of instance().m_flattenedProcessingStack.size(). + // stack. A cache of Instance().flattened_processing_stack_.size(). static wtf_size_t element_queue_end_; static V0CustomElementCallbackQueue::ElementQueueId CurrentElementQueue() {
diff --git a/third_party/blink/renderer/core/html/forms/base_text_input_type.h b/third_party/blink/renderer/core/html/forms/base_text_input_type.h index 2d252058..9e82080 100644 --- a/third_party/blink/renderer/core/html/forms/base_text_input_type.h +++ b/third_party/blink/renderer/core/html/forms/base_text_input_type.h
@@ -55,7 +55,7 @@ bool SupportsPlaceholder() const final; bool SupportsSelectionAPI() const override; - // m_regexp and m_patternForRegexp are mutable because they are kinds of + // regexp_ and pattern_for_regexp_ are mutable because they are kinds of // cache. mutable std::unique_ptr<ScriptRegexp> regexp_; mutable AtomicString pattern_for_regexp_;
diff --git a/third_party/blink/renderer/core/html/forms/color_chooser_popup_ui_controller.cc b/third_party/blink/renderer/core/html/forms/color_chooser_popup_ui_controller.cc index 3ea98fad9..340e62e 100644 --- a/third_party/blink/renderer/core/html/forms/color_chooser_popup_ui_controller.cc +++ b/third_party/blink/renderer/core/html/forms/color_chooser_popup_ui_controller.cc
@@ -54,9 +54,9 @@ ColorChooserPopupUIController::~ColorChooserPopupUIController() = default; void ColorChooserPopupUIController::Dispose() { - // Finalized earlier so as to access m_chromeClient while alive. + // Finalized earlier so as to access chrome_client_ while alive. ClosePopup(); - // ~ColorChooserUIController calls endChooser(). + // ~ColorChooserUIController calls EndChooser(). } void ColorChooserPopupUIController::Trace(blink::Visitor* visitor) {
diff --git a/third_party/blink/renderer/core/html/forms/form_data.h b/third_party/blink/renderer/core/html/forms/form_data.h index 5ef582cf..75cd949f 100644 --- a/third_party/blink/renderer/core/html/forms/form_data.h +++ b/third_party/blink/renderer/core/html/forms/form_data.h
@@ -45,7 +45,7 @@ class HTMLFormElement; class ScriptState; -// Typedef from FormData.idl: +// Typedef from form_data.idl: typedef FileOrUSVString FormDataEntryValue; class CORE_EXPORT FormData final @@ -104,7 +104,7 @@ IterationSource* StartIteration(ScriptState*, ExceptionState&) override; WTF::TextEncoding encoding_; - // Entry pointers in m_entries never be nullptr. + // Entry pointers in entries_ never be nullptr. HeapVector<Member<const Entry>> entries_; bool contains_password_data_ = false; };
diff --git a/third_party/blink/renderer/core/html/forms/html_form_control_element.cc b/third_party/blink/renderer/core/html/forms/html_form_control_element.cc index 85a3af99..bd5a3f6 100644 --- a/third_party/blink/renderer/core/html/forms/html_form_control_element.cc +++ b/third_party/blink/renderer/core/html/forms/html_form_control_element.cc
@@ -456,17 +456,17 @@ return; will_validate_initialized_ = true; will_validate_ = new_will_validate; - // Needs to force setNeedsValidityCheck() to invalidate validity state of + // Needs to force SetNeedsValidityCheck() to invalidate validity state of // FORM/FIELDSET. If this element updates willValidate twice and - // isValidElement() is not called between them, the second call of this - // function still has m_validityIsDirty==true, which means - // setNeedsValidityCheck() doesn't invalidate validity state of + // IsValidElement() is not called between them, the second call of this + // function still has validity_is_dirty_==true, which means + // SetNeedsValidityCheck() doesn't invalidate validity state of // FORM/FIELDSET. validity_is_dirty_ = false; SetNeedsValidityCheck(); // No need to trigger style recalculation here because - // setNeedsValidityCheck() does it in the right away. This relies on - // the assumption that valid() is always true if willValidate() is false. + // SetNeedsValidityCheck() does it in the right away. This relies on + // the assumption that Valid() is always true if willValidate() is false. if (!will_validate_) HideVisibleValidationMessage();
diff --git a/third_party/blink/renderer/core/html/forms/html_form_control_element.h b/third_party/blink/renderer/core/html/forms/html_form_control_element.h index 7245757ad..0ec0570 100644 --- a/third_party/blink/renderer/core/html/forms/html_form_control_element.h +++ b/third_party/blink/renderer/core/html/forms/html_form_control_element.h
@@ -220,9 +220,9 @@ mutable bool may_have_field_set_ancestor_ : 1; bool has_validation_message_ : 1; - // The initial value of m_willValidate depends on the derived class. We can't - // initialize it with a virtual function in the constructor. m_willValidate - // is not deterministic as long as m_willValidateInitialized is false. + // The initial value of will_validate_ depends on the derived class. We can't + // initialize it with a virtual function in the constructor. will_validate_ + // is not deterministic as long as will_validate_initialized_ is false. mutable bool will_validate_initialized_ : 1; mutable bool will_validate_ : 1;
diff --git a/third_party/blink/renderer/core/html/forms/html_form_element.h b/third_party/blink/renderer/core/html/forms/html_form_element.h index 9dcf98152..14cefa21 100644 --- a/third_party/blink/renderer/core/html/forms/html_form_element.h +++ b/third_party/blink/renderer/core/html/forms/html_form_element.h
@@ -158,10 +158,9 @@ RadioButtonGroupScope radio_button_group_scope_; - // Do not access m_listedElements directly. Use listedElements() - // instead. + // Do not access listed_elements_ directly. Use ListedElements() instead. ListedElement::List listed_elements_; - // Do not access m_imageElements directly. Use imageElements() instead. + // Do not access image_elements_ directly. Use ImageElements() instead. HeapVector<Member<HTMLImageElement>> image_elements_; // https://html.spec.whatwg.org/multipage/forms.html#planned-navigation
diff --git a/third_party/blink/renderer/core/html/forms/html_opt_group_element.cc b/third_party/blink/renderer/core/html/forms/html_opt_group_element.cc index 873fe56..f04ceb6 100644 --- a/third_party/blink/renderer/core/html/forms/html_opt_group_element.cc +++ b/third_party/blink/renderer/core/html/forms/html_opt_group_element.cc
@@ -42,9 +42,9 @@ inline HTMLOptGroupElement::HTMLOptGroupElement(Document& document) : HTMLElement(optgroupTag, document) {} -// An explicit empty destructor should be in HTMLOptGroupElement.cpp, because +// An explicit empty destructor should be in html_opt_group_element.cc, because // if an implicit destructor is used or an empty destructor is defined in -// HTMLOptGroupElement.h, when including HTMLOptGroupElement.h, +// html_opt_group_element.h, when including html_opt_group_element.h, // msvc tries to expand the destructor and causes // a compile error because of lack of ComputedStyle definition. HTMLOptGroupElement::~HTMLOptGroupElement() = default;
diff --git a/third_party/blink/renderer/core/html/forms/html_option_element.cc b/third_party/blink/renderer/core/html/forms/html_option_element.cc index 7b5479e..d1c3e09 100644 --- a/third_party/blink/renderer/core/html/forms/html_option_element.cc +++ b/third_party/blink/renderer/core/html/forms/html_option_element.cc
@@ -49,9 +49,9 @@ HTMLOptionElement::HTMLOptionElement(Document& document) : HTMLElement(optionTag, document), is_selected_(false) {} -// An explicit empty destructor should be in HTMLOptionElement.cpp, because +// An explicit empty destructor should be in html_option_element.cc, because // if an implicit destructor is used or an empty destructor is defined in -// HTMLOptionElement.h, when including HTMLOptionElement.h, +// html_option_element.h, when including html_option_element.h, // msvc tries to expand the destructor and causes // a compile error because of lack of ComputedStyle definition. HTMLOptionElement::~HTMLOptionElement() = default;
diff --git a/third_party/blink/renderer/core/html/forms/html_select_element.cc b/third_party/blink/renderer/core/html/forms/html_select_element.cc index 0e4ef963..464037d 100644 --- a/third_party/blink/renderer/core/html/forms/html_select_element.cc +++ b/third_party/blink/renderer/core/html/forms/html_select_element.cc
@@ -79,7 +79,7 @@ using namespace HTMLNames; -// Upper limit of m_listItems. According to the HTML standard, options larger +// Upper limit of list_items_. According to the HTML standard, options larger // than this limit doesn't work well because |selectedIndex| IDL attribute is // signed. static const unsigned kMaxListItems = INT_MAX; @@ -523,7 +523,7 @@ HTMLOptionElement* start_option, SkipDirection direction) const { const ListItems& items = GetListItems(); - // Can't use m_size because layoutObject forces a minimum size. + // Can't use size_ because LayoutObject forces a minimum size. int page_size = 0; if (GetLayoutObject()->IsListBox()) { // -1 so we still show context. @@ -585,12 +585,14 @@ // selection pivots around this anchor index. // Example: // 1. Press the mouse button on the second OPTION - // m_activeSelectionAnchorIndex = 1 + // active_selection_anchor_ points the second OPTION. // 2. Drag the mouse pointer onto the fifth OPTION - // m_activeSelectionEndIndex = 4, options at 1-4 indices are selected. + // active_selection_end_ points the fifth OPTION, OPTIONs at 1-4 indices + // are selected. // 3. Drag the mouse pointer onto the fourth OPTION - // m_activeSelectionEndIndex = 3, options at 1-3 indices are selected. - // updateListBoxSelection needs to clear selection of the fifth OPTION. + // active_selection_end_ points the fourth OPTION, OPTIONs at 1-3 indices + // are selected. + // UpdateListBoxSelection needs to clear selection of the fifth OPTION. cached_state_for_active_selection_.resize(0); for (auto* const option : GetOptionList()) { cached_state_for_active_selection_.push_back(option->Selected()); @@ -654,7 +656,7 @@ return; } - // Update m_lastOnChangeSelection and fire dispatchFormControlChangeEvent. + // Update last_on_change_selection_ and fire a 'change' event. bool fire_on_change = false; for (unsigned i = 0; i < items.size(); ++i) { HTMLElement* element = items[i]; @@ -903,7 +905,7 @@ HTMLOptionElement* option = option_to_scroll_to_.Release(); if (!option || !isConnected()) return; - // optionRemoved() makes sure m_optionToScrollTo doesn't have an option with + // OptionRemoved() makes sure option_to_scroll_to_ doesn't have an option with // another owner. DCHECK_EQ(option->OwnerSelectElement(), this); GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets(); @@ -999,7 +1001,7 @@ bool should_update_popup = false; - // selectedOption() is O(N). + // SelectedOption() is O(N). if (IsAutofilled() && SelectedOption() != element) SetAutofillState(WebAutofillState::kNotFilled); @@ -1011,7 +1013,7 @@ element->SetDirty(true); } - // deselectItemsWithoutValidation() is O(N). + // DeselectItemsWithoutValidation() is O(N). if (flags & kDeselectOtherOptions) should_update_popup |= DeselectItemsWithoutValidation(element); @@ -1027,8 +1029,8 @@ SetActiveSelectionEnd(element); } - // Need to update m_lastOnChangeOption before - // LayoutMenuList::updateFromElement. + // Need to update last_on_change_option_ before + // LayoutMenuList::UpdateFromElement. bool should_dispatch_events = false; if (UsesMenuList()) { should_dispatch_events = (flags & kDispatchInputAndChangeEvent) && @@ -1039,7 +1041,7 @@ // For the menu list case, this is what makes the selected element appear. if (LayoutObject* layout_object = GetLayoutObject()) layout_object->UpdateFromElement(); - // PopupMenu::updateFromElement() posts an O(N) task. + // PopupMenu::UpdateFromElement() posts an O(N) task. if (PopupIsVisible() && should_update_popup) popup_->UpdateFromElement(PopupMenu::kBySelectionChange); @@ -1052,10 +1054,10 @@ DispatchChangeEvent(); } if (LayoutObject* layout_object = GetLayoutObject()) { - // Need to check usesMenuList() again because event handlers might + // Need to check UsesMenuList() again because event handlers might // change the status. if (UsesMenuList()) { - // didSelectOption() is O(N) because of HTMLOptionElement::index(). + // DidSelectOption() is O(N) because of HTMLOptionElement::index(). ToLayoutMenuList(layout_object)->DidSelectOption(element); } }
diff --git a/third_party/blink/renderer/core/html/forms/html_select_element.h b/third_party/blink/renderer/core/html/forms/html_select_element.h index ab8d832..eab2da2 100644 --- a/third_party/blink/renderer/core/html/forms/html_select_element.h +++ b/third_party/blink/renderer/core/html/forms/html_select_element.h
@@ -285,7 +285,7 @@ void ObserveTreeMutation(); void UnobserveTreeMutation(); - // m_listItems contains HTMLOptionElement, HTMLOptGroupElement, and + // list_items_ contains HTMLOptionElement, HTMLOptGroupElement, and // HTMLHRElement objects. mutable ListItems list_items_; Vector<bool> last_on_change_selection_;
diff --git a/third_party/blink/renderer/core/html/forms/html_select_element_test.cc b/third_party/blink/renderer/core/html/forms/html_select_element_test.cc index ab10bd5..ba3bf95 100644 --- a/third_party/blink/renderer/core/html/forms/html_select_element_test.cc +++ b/third_party/blink/renderer/core/html/forms/html_select_element_test.cc
@@ -91,9 +91,9 @@ } TEST_F(HTMLSelectElementTest, RestoreUnmatchedFormControlState) { - // We had a bug that selectedOption() and m_lastOnChangeOption were - // mismatched in optionToBeShown(). It happened when - // restoreFormControlState() couldn't find matched OPTIONs. + // We had a bug that SelectedOption() and last_on_change_option_ were + // mismatched in OptionToBeShown(). It happened when + // RestoreFormControlState() couldn't find matched OPTIONs. // crbug.com/627833. SetHtmlInnerHTML(R"HTML(
diff --git a/third_party/blink/renderer/core/html/forms/internal_popup_menu.cc b/third_party/blink/renderer/core/html/forms/internal_popup_menu.cc index f92cc421..56bfa62 100644 --- a/third_party/blink/renderer/core/html/forms/internal_popup_menu.cc +++ b/third_party/blink/renderer/core/html/forms/internal_popup_menu.cc
@@ -464,7 +464,7 @@ } void InternalPopupMenu::DidClosePopup() { - // Clearing m_popup first to prevent from trying to close the popup again. + // Clearing popup_ first to prevent from trying to close the popup again. popup_ = nullptr; if (owner_element_) owner_element_->PopupDidHide();
diff --git a/third_party/blink/renderer/core/html/forms/listed_element.h b/third_party/blink/renderer/core/html/forms/listed_element.h index d7ba4cd..0da13d5 100644 --- a/third_party/blink/renderer/core/html/forms/listed_element.h +++ b/third_party/blink/renderer/core/html/forms/listed_element.h
@@ -123,7 +123,7 @@ Member<HTMLFormElement> form_; Member<ValidityState> validity_state_; String custom_validation_message_; - // If m_formWasSetByParser is true, m_form is always non-null. + // If form_was_set_by_parser_ is true, form_ is always non-null. bool form_was_set_by_parser_; };
diff --git a/third_party/blink/renderer/core/html/forms/option_list.cc b/third_party/blink/renderer/core/html/forms/option_list.cc index 5beee4e..b6c0994 100644 --- a/third_party/blink/renderer/core/html/forms/option_list.cc +++ b/third_party/blink/renderer/core/html/forms/option_list.cc
@@ -12,8 +12,8 @@ void OptionListIterator::Advance(HTMLOptionElement* previous) { // This function returns only - // - An OPTION child of m_select, or - // - An OPTION child of an OPTGROUP child of m_select. + // - An OPTION child of select_, or + // - An OPTION child of an OPTGROUP child of select_. Element* current; if (previous) {
diff --git a/third_party/blink/renderer/core/html/forms/radio_button_group_scope.cc b/third_party/blink/renderer/core/html/forms/radio_button_group_scope.cc index 2b5a590..52fa2712 100644 --- a/third_party/blink/renderer/core/html/forms/radio_button_group_scope.cc +++ b/third_party/blink/renderer/core/html/forms/radio_button_group_scope.cc
@@ -288,7 +288,7 @@ return; group->Remove(element); if (group->IsEmpty()) { - // We don't remove an empty RadioButtonGroup from m_nameToGroupMap for + // We don't remove an empty RadioButtonGroup from name_to_group_map_ for // better performance. DCHECK(!group->IsRequired()); SECURITY_DCHECK(!group->CheckedButton());
diff --git a/third_party/blink/renderer/core/html/forms/resources/calendarPicker.js b/third_party/blink/renderer/core/html/forms/resources/calendarPicker.js index 250b55c..faf40b2 100644 --- a/third_party/blink/renderer/core/html/forms/resources/calendarPicker.js +++ b/third_party/blink/renderer/core/html/forms/resources/calendarPicker.js
@@ -352,11 +352,11 @@ return Day.formatter.format(this.startDate()); }; -// See WebCore/platform/DateComponents.h. +// See platform/date_components.h. Day.Minimum = Day.createFromValue(-62135596800000.0); Day.Maximum = Day.createFromValue(8640000000000000.0); -// See WebCore/html/DayInputType.cpp. +// See core/html/forms/date_input_type.cc. Day.DefaultStep = 86400000; Day.DefaultStepBase = 0; @@ -387,11 +387,11 @@ Week.ISOStringRegExp = /^(\d+)-[wW](\d+)$/; -// See WebCore/platform/DateComponents.h. +// See platform/date_components.h. Week.Minimum = new Week(1, 1); Week.Maximum = new Week(275760, 37); -// See WebCore/html/WeekInputType.cpp. +// See core/html/forms/week_input_type.cc. Week.DefaultStep = 604800000; Week.DefaultStepBase = -259200000; @@ -609,11 +609,11 @@ Month.ISOStringRegExp = /^(\d+)-(\d+)$/; -// See WebCore/platform/DateComponents.h. +// See platform/date_components.h. Month.Minimum = new Month(1, 0); Month.Maximum = new Month(275760, 8); -// See WebCore/html/MonthInputType.cpp. +// See core/html/forms/month_input_type.cc. Month.DefaultStep = 1; Month.DefaultStepBase = 0;
diff --git a/third_party/blink/renderer/core/html/forms/slider_thumb_element.cc b/third_party/blink/renderer/core/html/forms/slider_thumb_element.cc index bcaf25d..42355024 100644 --- a/third_party/blink/renderer/core/html/forms/slider_thumb_element.cc +++ b/third_party/blink/renderer/core/html/forms/slider_thumb_element.cc
@@ -404,7 +404,7 @@ sliding_direction_ = GetDirection(current_point, start_point_); } - // m_slidingDirection has been updated, so check whether it's okay to + // sliding_direction_ has been updated, so check whether it's okay to // slide again. if (CanSlide()) { thumb->SetPositionFromPoint(touches->item(0)->AbsoluteLocation());
diff --git a/third_party/blink/renderer/core/html/forms/step_range.cc b/third_party/blink/renderer/core/html/forms/step_range.cc index 63a3a36d..3507a85 100644 --- a/third_party/blink/renderer/core/html/forms/step_range.cc +++ b/third_party/blink/renderer/core/html/forms/step_range.cc
@@ -90,7 +90,7 @@ rounded_value > maximum_ ? rounded_value - step_ : (rounded_value < minimum_ ? rounded_value + step_ : rounded_value); - // clampedValue can be outside of [m_minimum, m_maximum] if m_step is huge. + // clamped_value can be outside of [minimum_, maximum_] if step_ is huge. if (clamped_value < minimum_ || clamped_value > maximum_) return in_range_value; return clamped_value;
diff --git a/third_party/blink/renderer/core/html/forms/text_control_element.cc b/third_party/blink/renderer/core/html/forms/text_control_element.cc index d5de47f..411880b4 100644 --- a/third_party/blink/renderer/core/html/forms/text_control_element.cc +++ b/third_party/blink/renderer/core/html/forms/text_control_element.cc
@@ -492,8 +492,8 @@ return CreateVisiblePosition(it.EndPosition(), TextAffinity::kUpstream); } -// TODO(yosin): We should move |TextControlElement::indexForVisiblePosition()| -// to "AXLayoutObject.cpp" since this funciton is used only there. +// TODO(yosin): We should move |TextControlElement::IndexForVisiblePosition()| +// to "ax_layout_object.cc" since this function is used only there. int TextControlElement::IndexForVisiblePosition( const VisiblePosition& pos) const { Position index_position = pos.DeepEquivalent().ParentAnchoredEquivalent();
diff --git a/third_party/blink/renderer/core/html/forms/text_control_element.h b/third_party/blink/renderer/core/html/forms/text_control_element.h index d0e6821..46a16b2 100644 --- a/third_party/blink/renderer/core/html/forms/text_control_element.h +++ b/third_party/blink/renderer/core/html/forms/text_control_element.h
@@ -214,9 +214,9 @@ // creating a number of TreeScope data structures to track elements by ID. Member<TextControlInnerEditorElement> inner_editor_; - // In m_valueBeforeFirstUserEdit, we distinguish a null String and zero-length - // String. Null String means the field doesn't have any data yet, and - // zero-length String is a valid data. + // In value_before_first_user_edit_, we distinguish a null String and + // zero-length String. Null String means the field doesn't have any data yet, + // and zero-length String is a valid data. String value_before_first_user_edit_; bool last_change_was_user_edit_;
diff --git a/third_party/blink/renderer/core/html/html_area_element.cc b/third_party/blink/renderer/core/html/html_area_element.cc index 0c1e2a29..e7f42538 100644 --- a/third_party/blink/renderer/core/html/html_area_element.cc +++ b/third_party/blink/renderer/core/html/html_area_element.cc
@@ -47,9 +47,9 @@ inline HTMLAreaElement::HTMLAreaElement(Document& document) : HTMLAnchorElement(areaTag, document), shape_(kRect) {} -// An explicit empty destructor should be in HTMLAreaElement.cpp, because +// An explicit empty destructor should be in html_area_element.cc, because // if an implicit destructor is used or an empty destructor is defined in -// HTMLAreaElement.h, when including HTMLAreaElement.h, msvc tries to expand +// html_area_element.h, when including html_area_element.h, msvc tries to expand // the destructor and causes a compile error because of lack of blink::Path // definition. HTMLAreaElement::~HTMLAreaElement() = default;
diff --git a/third_party/blink/renderer/core/html/html_embed_element.cc b/third_party/blink/renderer/core/html/html_embed_element.cc index eb45fcb..99907cd 100644 --- a/third_party/blink/renderer/core/html/html_embed_element.cc +++ b/third_party/blink/renderer/core/html/html_embed_element.cc
@@ -140,8 +140,8 @@ plugin_params.AppendAttribute(attribute); } -// FIXME: This should be unified with HTMLObjectElement::updatePlugin and -// moved down into HTMLPluginElement.cpp +// FIXME: This should be unified with HTMLObjectElement::UpdatePlugin and +// moved down into html_plugin_element.cc void HTMLEmbedElement::UpdatePluginInternal() { DCHECK(!GetLayoutEmbeddedObject()->ShowsUnavailablePluginIndicator()); DCHECK(NeedsPluginUpdate()); @@ -150,7 +150,7 @@ if (url_.IsEmpty() && service_type_.IsEmpty()) return; - // Note these pass m_url and m_serviceType to allow better code sharing with + // Note these pass url_ and service_type_ to allow better code sharing with // <object> which modifies url and serviceType before calling these. if (!AllowedToLoadFrameURL(url_)) return; @@ -158,8 +158,8 @@ PluginParameters plugin_params; ParametersForPlugin(plugin_params); - // FIXME: Can we not have layoutObject here now that beforeload events are - // gone? + // FIXME: Can we not have GetLayoutObject() here now that beforeload events + // are gone? if (!GetLayoutObject()) return;
diff --git a/third_party/blink/renderer/core/html/html_html_element.cc b/third_party/blink/renderer/core/html/html_html_element.cc index e245adb..eb9f3b1 100644 --- a/third_party/blink/renderer/core/html/html_html_element.cc +++ b/third_party/blink/renderer/core/html/html_html_element.cc
@@ -59,7 +59,8 @@ if (GetDocument().GetFrame()) { GetDocument().GetFrame()->Loader().DispatchDocumentElementAvailable(); GetDocument().GetFrame()->Loader().RunScriptsAtDocumentElementAvailable(); - // runScriptsAtDocumentElementAvailable might have invalidated m_document. + // RunScriptsAtDocumentElementAvailable might have invalidated + // GetDocument(). } }
diff --git a/third_party/blink/renderer/core/html/html_image_element.cc b/third_party/blink/renderer/core/html/html_image_element.cc index 0f32114..b7a6fe8 100644 --- a/third_party/blink/renderer/core/html/html_image_element.cc +++ b/third_party/blink/renderer/core/html/html_image_element.cc
@@ -796,9 +796,9 @@ } void HTMLImageElement::EnsureFallbackForGeneratedContent() { - // The special casing for generated content in createLayoutObject breaks the + // The special casing for generated content in CreateLayoutObject breaks the // invariant that the layout object attached to this element will always be - // appropriate for |m_layoutDisposition|. Force recreate it. + // appropriate for |layout_disposition_|. Force recreate it. // TODO(engedy): Remove this hack. See: https://crbug.com/671953. SetLayoutDisposition(LayoutDisposition::kFallbackContent, true /* force_reattach */);
diff --git a/third_party/blink/renderer/core/html/html_object_element.cc b/third_party/blink/renderer/core/html/html_object_element.cc index e71c7db..9babda6 100644 --- a/third_party/blink/renderer/core/html/html_object_element.cc +++ b/third_party/blink/renderer/core/html/html_object_element.cc
@@ -241,7 +241,7 @@ } // TODO(schenney): crbug.com/572908 This should be unified with -// HTMLEmbedElement::updatePlugin and moved down into HTMLPluginElement.cpp +// HTMLEmbedElement::UpdatePlugin and moved down into html_plugin_element.cc void HTMLObjectElement::UpdatePluginInternal() { DCHECK(!GetLayoutEmbeddedObject()->ShowsUnavailablePluginIndicator()); DCHECK(NeedsPluginUpdate());
diff --git a/third_party/blink/renderer/core/html/html_plugin_element.cc b/third_party/blink/renderer/core/html/html_plugin_element.cc index 61718697..8547bc0 100644 --- a/third_party/blink/renderer/core/html/html_plugin_element.cc +++ b/third_party/blink/renderer/core/html/html_plugin_element.cc
@@ -114,10 +114,10 @@ PreferPlugInsForImagesOption prefer_plug_ins_for_images_option) : HTMLFrameOwnerElement(tag_name, doc), is_delaying_load_event_(false), - // m_needsPluginUpdate(!createdByParser) allows HTMLObjectElement to delay - // EmbeddedContentView updates until after all children are parsed. For - // HTMLEmbedElement this delay is unnecessary, but it is simpler to make - // both classes share the same codepath in this class. + // needs_plugin_update_(!IsCreatedByParser) allows HTMLObjectElement to + // delay EmbeddedContentView updates until after all children are + // parsed. For HTMLEmbedElement this delay is unnecessary, but it is + // simpler to make both classes share the same codepath in this class. needs_plugin_update_(!flags.IsCreatedByParser()), should_prefer_plug_ins_for_images_(prefer_plug_ins_for_images_option == kShouldPreferPlugInsForImages) { @@ -553,7 +553,7 @@ return ToLayoutEmbeddedObject(GetLayoutObject()); } -// We don't use m_url, as it may not be the final URL that the object loads, +// We don't use url_, as it may not be the final URL that the object loads, // depending on <param> values. bool HTMLPlugInElement::AllowedToLoadFrameURL(const String& url) { KURL complete_url = GetDocument().CompleteURL(url);
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 5b0d0f1..1f73df3 100644 --- a/third_party/blink/renderer/core/html/html_slot_element.cc +++ b/third_party/blink/renderer/core/html/html_slot_element.cc
@@ -314,7 +314,7 @@ if (SupportsAssignment()) { AttachContext children_context(context); - for (auto& node : ChildrenInFlatTreeIfAssignmentIsSupported()) { + for (auto& node : AssignedNodes()) { if (node->NeedsAttach()) node->AttachLayoutTree(children_context); } @@ -323,14 +323,6 @@ } } -// TODO(hayato): Rename this function once we enable IncrementalShadowDOM -// by default because this function doesn't consider fallback elements in case -// of IncementalShadowDOM. -const HeapVector<Member<Node>>& -HTMLSlotElement::ChildrenInFlatTreeIfAssignmentIsSupported() { - return AssignedNodes(); -} - void HTMLSlotElement::DetachLayoutTree(const AttachContext& context) { if (SupportsAssignment()) { const HeapVector<Member<Node>>& flat_tree_children = assigned_nodes_; @@ -345,13 +337,11 @@ if (!SupportsAssignment()) return; - const HeapVector<Member<Node>>& flat_tree_children = - ChildrenInFlatTreeIfAssignmentIsSupported(); + const HeapVector<Member<Node>>& assigned_nodes = AssignedNodes(); // This loop traverses the nodes from right to left for the same reason as the // one described in ContainerNode::RebuildChildrenLayoutTrees(). - for (auto it = flat_tree_children.rbegin(); it != flat_tree_children.rend(); - ++it) { + for (auto it = assigned_nodes.rbegin(); it != assigned_nodes.rend(); ++it) { RebuildLayoutTreeForChild(*it, whitespace_attacher); } } @@ -627,9 +617,6 @@ void HTMLSlotElement::Trace(blink::Visitor* visitor) { visitor->Trace(assigned_nodes_); visitor->Trace(flat_tree_children_); - visitor->Trace(distributed_nodes_); - visitor->Trace(old_distributed_nodes_); - visitor->Trace(distributed_indices_); visitor->Trace(assigned_nodes_candidates_); HTMLElement::Trace(visitor); }
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 6d1f69c..3e03242 100644 --- a/third_party/blink/renderer/core/html/html_slot_element.h +++ b/third_party/blink/renderer/core/html/html_slot_element.h
@@ -53,19 +53,6 @@ const HeapVector<Member<Element>> AssignedElementsForBinding( const AssignedNodesOptions&); - HeapVector<Member<Node>> DeleteCommonAssignedNodeAndReturnAddedAssignedNode( - const HeapVector<Member<Node>>& new_assigned_nodes); - - void assign(HeapVector<Member<Node>> nodes); - bool ContainsInAssignedNodesCandidates(Node&) const; - HeapHashSet<Member<Node>>& AssignedNodesCandidate() { - return assigned_nodes_candidates_; - } - void SignalSlotChange(); - void SignalSlotChangeAfterRemoved(); - - const HeapVector<Member<Node>> FlattenedAssignedNodes(); - Node* FirstAssignedNode() const { auto& nodes = AssignedNodes(); return nodes.IsEmpty() ? nullptr : nodes.front().Get(); @@ -79,6 +66,10 @@ Node* AssignedNodePreviousTo(const Node&) const; void AppendAssignedNode(Node&); + void ClearAssignedNodes(); + + const HeapVector<Member<Node>> FlattenedAssignedNodes(); + void RecalcFlatTreeChildren(); void AttachLayoutTree(AttachContext&) final; void DetachLayoutTree(const AttachContext& = AttachContext()) final; @@ -112,10 +103,18 @@ static const AtomicString& UserAgentCustomAssignSlotName(); static const AtomicString& UserAgentDefaultSlotName(); - void Trace(blink::Visitor*) override; + // For imperative Shadow DOM distribution APIs + HeapVector<Member<Node>> DeleteCommonAssignedNodeAndReturnAddedAssignedNode( + const HeapVector<Member<Node>>& new_assigned_nodes); + void assign(HeapVector<Member<Node>> nodes); + bool ContainsInAssignedNodesCandidates(Node&) const; + HeapHashSet<Member<Node>>& AssignedNodesCandidate() { + return assigned_nodes_candidates_; + } + void SignalSlotChange(); + void SignalSlotChangeAfterRemoved(); - void ClearAssignedNodes(); - void RecalcFlatTreeChildren(); + void Trace(blink::Visitor*) override; private: HTMLSlotElement(Document&); @@ -128,8 +127,6 @@ bool HasSlotableChild() const; - const HeapVector<Member<Node>>& ChildrenInFlatTreeIfAssignmentIsSupported(); - void LazyReattachNodesIfNeeded(const HeapVector<Member<Node>>& nodes1, const HeapVector<Member<Node>>& nodes2); static void LazyReattachNodesNaive(const HeapVector<Member<Node>>& nodes1, @@ -145,17 +142,12 @@ void ClearAssignedNodesAndFlatTreeChildren(); HeapVector<Member<Node>> assigned_nodes_; - bool slotchange_event_enqueued_ = false; - - HeapHashSet<Member<Node>> assigned_nodes_candidates_; - - // For IncrementalShadowDOM HeapVector<Member<Node>> flat_tree_children_; - // For Non-IncrmentalShadowDOM. IncremntalShadowDOM never use these members. - HeapVector<Member<Node>> distributed_nodes_; - HeapVector<Member<Node>> old_distributed_nodes_; - HeapHashMap<Member<const Node>, wtf_size_t> distributed_indices_; + bool slotchange_event_enqueued_ = false; + + // For imperative Shadow DOM distribution APIs + HeapHashSet<Member<Node>> assigned_nodes_candidates_; // TODO(hayato): Move this to more appropriate directory (e.g. platform/wtf) // if there are more than one usages.
diff --git a/third_party/blink/renderer/core/html/html_table_element.cc b/third_party/blink/renderer/core/html/html_table_element.cc index 54fa5ee..bcf1f640 100644 --- a/third_party/blink/renderer/core/html/html_table_element.cc +++ b/third_party/blink/renderer/core/html/html_table_element.cc
@@ -59,10 +59,10 @@ rules_attr_(kUnsetRules), padding_(1) {} -// An explicit empty destructor should be in HTMLTableElement.cpp, because +// An explicit empty destructor should be in html_table_element.cc, because // if an implicit destructor is used or an empty destructor is defined in -// HTMLTableElement.h, when including HTMLTableElement, msvc tries to expand -// the destructor and causes a compile error because of lack of +// html_table_element.h, when including html_table_element.h, msvc tries to +// expand the destructor and causes a compile error because of lack of // CSSPropertyValueSet definition. HTMLTableElement::~HTMLTableElement() = default;
diff --git a/third_party/blink/renderer/core/html/image_document.h b/third_party/blink/renderer/core/html/image_document.h index 6732122..36c0114 100644 --- a/third_party/blink/renderer/core/html/image_document.h +++ b/third_party/blink/renderer/core/html/image_document.h
@@ -67,7 +67,7 @@ // Calculates how large the div needs to be to properly center the image. int CalculateDivWidth(); - // These methods are for m_shrinkToFitMode == Desktop. + // These methods are for shrink_to_fit_mode_ == kDesktop. void ResizeImageToFit(); void RestoreImageSize(); bool ImageFitsInWindow() const;
diff --git a/third_party/blink/renderer/core/html/imports/html_import.cc b/third_party/blink/renderer/core/html/imports/html_import.cc index a9fd490..655f35e4 100644 --- a/third_party/blink/renderer/core/html/imports/html_import.cc +++ b/third_party/blink/renderer/core/html/imports/html_import.cc
@@ -89,10 +89,10 @@ } // The post-visit DFS order matters here because - // HTMLImportStateResolver in recalcState() Depends on - // |m_state| of its children and precedents of ancestors. + // HTMLImportStateResolver in RecalcState() Depends on + // |state_| of its children and precedents of ancestors. // Accidental cycle dependency of state computation is prevented - // by invalidateCachedState() and isStateCacheValid() check. + // by InvalidateCachedState() and IsStateCacheValid() check. for (HTMLImport* i = TraverseFirstPostOrder(root); i; i = TraverseNextPostOrder(i)) { DCHECK(!i->state_.IsValid());
diff --git a/third_party/blink/renderer/core/html/link_style.cc b/third_party/blink/renderer/core/html/link_style.cc index 86d9cc8..fbec39a5 100644 --- a/third_party/blink/renderer/core/html/link_style.cc +++ b/third_party/blink/renderer/core/html/link_style.cc
@@ -70,7 +70,7 @@ } CSSStyleSheetResource* cached_style_sheet = ToCSSStyleSheetResource(resource); - // See the comment in PendingScript.cpp about why this check is necessary + // See the comment in pending_script.cc about why this check is necessary // here, instead of in the resource fetcher. https://crbug.com/500701. if (!cached_style_sheet->ErrorOccurred() && !owner_->FastGetAttribute(integrityAttr).IsEmpty() && @@ -192,7 +192,7 @@ if (type == kNone) return; if (type == kNonBlocking) { - // Tell StyleEngine to re-compute styleSheets of this m_owner's treescope. + // Tell StyleEngine to re-compute styleSheets of this owner_'s treescope. GetDocument().GetStyleEngine().ModifiedStyleSheetCandidateNode(*owner_); return; }
diff --git a/third_party/blink/renderer/core/html/media/html_video_element.cc b/third_party/blink/renderer/core/html/media/html_video_element.cc index bd6bc6b..fb5b158 100644 --- a/third_party/blink/renderer/core/html/media/html_video_element.cc +++ b/third_party/blink/renderer/core/html/media/html_video_element.cc
@@ -190,8 +190,8 @@ // In case the poster attribute is set after playback, don't update the // display state, post playback the correct state will be picked up. if (GetDisplayMode() < kVideo || !HasAvailableVideoFrame()) { - // Force a poster recalc by setting m_displayMode to Unknown directly - // before calling updateDisplayState. + // Force a poster recalc by setting display_mode_ to kUnknown directly + // before calling UpdateDisplayState. HTMLMediaElement::SetDisplayMode(kUnknown); UpdateDisplayState(); }
diff --git a/third_party/blink/renderer/core/html/parser/atomic_html_token.cc b/third_party/blink/renderer/core/html/parser/atomic_html_token.cc index 24671e6..419fbf3f 100644 --- a/third_party/blink/renderer/core/html/parser/atomic_html_token.cc +++ b/third_party/blink/renderer/core/html/parser/atomic_html_token.cc
@@ -56,7 +56,7 @@ default: break; } - // TODO(kouhei): print m_attributes? + // TODO(kouhei): print attributes_? printf("\n"); } #endif
diff --git a/third_party/blink/renderer/core/html/parser/background_html_parser.h b/third_party/blink/renderer/core/html/parser/background_html_parser.h index 1b14977d..5579a54 100644 --- a/third_party/blink/renderer/core/html/parser/background_html_parser.h +++ b/third_party/blink/renderer/core/html/parser/background_html_parser.h
@@ -124,8 +124,8 @@ DocumentEncodingData last_seen_encoding_data_; scoped_refptr<base::SingleThreadTaskRunner> loading_task_runner_; - // Index into |m_pendingTokens| of the last <meta> csp token found. Will be - // |TokenizedChunk::noPendingToken| if none have been found. + // Index into |pending_tokens_| of the last <meta> csp token found. Will be + // |TokenizedChunk::kNoPendingToken| if none have been found. int pending_csp_meta_token_index_; bool starting_script_;
diff --git a/third_party/blink/renderer/core/html/parser/compact_html_token.cc b/third_party/blink/renderer/core/html/parser/compact_html_token.cc index 291a648..8291327 100644 --- a/third_party/blink/renderer/core/html/parser/compact_html_token.cc +++ b/third_party/blink/renderer/core/html/parser/compact_html_token.cc
@@ -54,7 +54,7 @@ data_ = AttemptStaticStringCreation(token->GetName(), kLikely8Bit); // There is only 1 DOCTYPE token per document, so to avoid increasing the - // size of CompactHTMLToken, we just use the m_attributes vector. + // size of CompactHTMLToken, we just use the attributes_ vector. attributes_.push_back(Attribute( AttemptStaticStringCreation(token->PublicIdentifier(), kLikely8Bit), String(token->SystemIdentifier())));
diff --git a/third_party/blink/renderer/core/html/parser/compact_html_token.h b/third_party/blink/renderer/core/html/parser/compact_html_token.h index 176f1ec..ccb3c6f 100644 --- a/third_party/blink/renderer/core/html/parser/compact_html_token.h +++ b/third_party/blink/renderer/core/html/parser/compact_html_token.h
@@ -71,7 +71,7 @@ const TextPosition& GetTextPosition() const { return text_position_; } // There is only 1 DOCTYPE token per document, so to avoid increasing the - // size of CompactHTMLToken, we just use the m_attributes vector. + // size of CompactHTMLToken, we just use the attributes_ vector. const String& PublicIdentifier() const { return attributes_[0].GetName(); } const String& SystemIdentifier() const { return attributes_[0].Value(); } bool DoctypeForcesQuirks() const { return doctype_forces_quirks_; } @@ -82,7 +82,7 @@ unsigned is_all8_bit_data_ : 1; unsigned doctype_forces_quirks_ : 1; - String data_; // "name", "characters", or "data" depending on m_type + String data_; // "name", "characters", or "data" depending on type_ Vector<Attribute> attributes_; TextPosition text_position_; };
diff --git a/third_party/blink/renderer/core/html/parser/html_document_parser.cc b/third_party/blink/renderer/core/html/parser/html_document_parser.cc index b784db02..b57759975 100644 --- a/third_party/blink/renderer/core/html/parser/html_document_parser.cc +++ b/third_party/blink/renderer/core/html/parser/html_document_parser.cc
@@ -110,7 +110,7 @@ : HTMLDocumentParser(fragment->GetDocument(), parser_content_policy, kForceSynchronousParsing) { - // No m_scriptRunner in fragment parser. + // No script_runner_ in fragment parser. tree_builder_ = HTMLTreeBuilder::Create(this, fragment, context_element, parser_content_policy, options_); @@ -191,10 +191,10 @@ parser_scheduler_->Detach(); parser_scheduler_.Clear(); } - // Oilpan: It is important to clear m_token to deallocate backing memory of - // HTMLToken::m_data and let the allocator reuse the memory for - // HTMLToken::m_data of a next HTMLDocumentParser. We need to clear - // m_tokenizer first because m_tokenizer has a raw pointer to m_token. + // Oilpan: It is important to clear token_ to deallocate backing memory of + // HTMLToken::data_ and let the allocator reuse the memory for + // HTMLToken::data_ of a next HTMLDocumentParser. We need to clear + // tokenizer_ first because tokenizer_ has a raw pointer to token_. tokenizer_.reset(); token_.reset(); } @@ -370,14 +370,14 @@ std::unique_ptr<TokenizedChunk> chunk) { DCHECK(chunk); // TODO(kouhei): We should simplify codepath here by disallowing - // validateSpeculations - // while isPaused, and m_lastChunkBeforePause can simply be - // pushed to m_speculations. + // ValidateSpeculations + // while IsPaused, and last_chunk_before_pause_ can simply be + // pushed to speculations_. if (IsPaused()) { // We're waiting on a network script or stylesheet, just save the chunk, - // we'll get a second validateSpeculations call after the script or + // we'll get a second ValidateSpeculations call after the script or // stylesheet completes. This call should have been made immediately after - // runScriptsForPausedTreeBuilder in the script case which may have started + // RunScriptsForPausedTreeBuilder in the script case which may have started // a network load and left us waiting. DCHECK(!last_chunk_before_pause_); last_chunk_before_pause_ = std::move(chunk); @@ -561,8 +561,8 @@ } void HTMLDocumentParser::PumpPendingSpeculations() { - // If this assert fails, you need to call validateSpeculations to make sure - // m_tokenizer and m_token don't have state that invalidates m_speculations. + // If this assert fails, you need to call ValidateSpeculations to make sure + // tokenizer_ and token_ don't have state that invalidates speculations_. DCHECK(!tokenizer_); DCHECK(!token_); DCHECK(!last_chunk_before_pause_); @@ -593,9 +593,9 @@ ProcessTokenizedChunkFromBackgroundParser(speculations_.TakeFirst()); session.AddedElementTokens(element_token_count); - // Always check isParsing first as m_document may be null. Surprisingly, - // isScheduledForUnpause() may be set here as a result of - // processTokenizedChunkFromBackgroundParser running arbitrary javascript + // Always check IsParsing first as document_ may be null. Surprisingly, + // IsScheduledForUnpause() may be set here as a result of + // ProcessTokenizedChunkFromBackgroundParser running arbitrary javascript // which invokes nested event loops. (e.g. inspector breakpoints) CheckIfBodyStylesheetAdded(); if (!IsParsing() || IsPaused() || IsScheduledForUnpause()) @@ -632,9 +632,9 @@ // We tell the InspectorInstrumentation about every pump, even if we end up // pumping nothing. It can filter out empty pumps itself. - // FIXME: m_input.current().length() is only accurate if we end up parsing the + // FIXME: input_.Current().length() is only accurate if we end up parsing the // whole buffer in this pump. We should pass how much we parsed as part of - // didWriteHTML instead of willWriteHTML. + // DidWriteHTML instead of WillWriteHTML. probe::ParseHTML probe(GetDocument(), this); if (!IsParsingFragment()) @@ -684,7 +684,7 @@ DCHECK_EQ(tokenizer_->GetState(), HTMLTokenizer::kDataState); DCHECK(preloader_); - // TODO(kouhei): m_preloader should be always available for synchronous + // TODO(kouhei): preloader_ should be always available for synchronous // parsing case, adding paranoia if for speculative crash fix for // crbug.com/465478 if (preloader_) { @@ -702,23 +702,23 @@ DCHECK(!GetDocument()->IsPrefetchOnly()); AtomicHTMLToken atomic_token(Token()); - // We clear the m_token in case constructTreeFromAtomicToken + // We clear the token_ in case ConstructTreeFromAtomicToken // synchronously re-enters the parser. We don't clear the token immedately - // for Character tokens because the AtomicHTMLToken avoids copying the + // for kCharacter tokens because the AtomicHTMLToken avoids copying the // characters by keeping a pointer to the underlying buffer in the - // HTMLToken. Fortunately, Character tokens can't cause us to re-enter + // HTMLToken. Fortunately, kCharacter tokens can't cause us to re-enter // the parser. // - // FIXME: Stop clearing the m_token once we start running the parser off + // FIXME: Stop clearing the token_ once we start running the parser off // the main thread or once we stop allowing synchronous JavaScript - // execution from parseAttribute. + // execution from ParseAttribute. if (Token().GetType() != HTMLToken::kCharacter) Token().Clear(); tree_builder_->ConstructTree(&atomic_token); CheckIfBodyStylesheetAdded(); - // FIXME: constructTree may synchronously cause Document to be detached. + // FIXME: ConstructTree may synchronously cause Document to be detached. if (!token_) return; @@ -931,9 +931,9 @@ } void HTMLDocumentParser::Finish() { - // FIXME: We should DCHECK(!m_parserStopped) here, since it does not makes + // FIXME: We should DCHECK(!parser_stopped_) here, since it does not makes // sense to call any methods on DocumentParser once it's been stopped. - // However, FrameLoader::stop calls DocumentParser::finish unconditionally. + // However, FrameLoader::Stop calls DocumentParser::Finish unconditionally. Flush(); if (IsDetached())
diff --git a/third_party/blink/renderer/core/html/parser/html_document_parser.h b/third_party/blink/renderer/core/html/parser/html_document_parser.h index 171f7eb4..342b24a 100644 --- a/third_party/blink/renderer/core/html/parser/html_document_parser.h +++ b/third_party/blink/renderer/core/html/parser/html_document_parser.h
@@ -223,7 +223,7 @@ TokenPreloadScanner::ScannerType); // Let the given HTMLPreloadScanner scan the input it has, and then preloads - // resources using the resulting PreloadRequests and |m_preloader|. + // resources using the resulting PreloadRequests and |preloader_|. void ScanAndPreload(HTMLPreloadScanner*); void FetchQueuedPreloads(); @@ -249,7 +249,7 @@ XSSAuditor xss_auditor_; XSSAuditorDelegate xss_auditor_delegate_; - // FIXME: m_lastChunkBeforePause, m_tokenizer, m_token, and m_input should be + // FIXME: last_chunk_before_pause_, tokenizer_, token_, and input_ should be // combined into a single state object so they can be set and cleared together // and passed between threads together. std::unique_ptr<TokenizedChunk> last_chunk_before_pause_;
diff --git a/third_party/blink/renderer/core/html/parser/html_formatting_element_list.h b/third_party/blink/renderer/core/html/parser/html_formatting_element_list.h index 074b2a76..fe0a6e3 100644 --- a/third_party/blink/renderer/core/html/parser/html_formatting_element_list.h +++ b/third_party/blink/renderer/core/html/parser/html_formatting_element_list.h
@@ -61,8 +61,8 @@ HTMLStackItem* StackItem() const { return item_; } Element* GetElement() const { - // The fact that !m_item == isMarker() is an implementation detail callers - // should check isMarker() before calling element(). + // The fact that !item_ == IsMarker() is an implementation detail callers + // should check IsMarker() before calling GetElement(). DCHECK(item_); return item_->GetElement(); }
diff --git a/third_party/blink/renderer/core/html/parser/html_input_stream.h b/third_party/blink/renderer/core/html/parser/html_input_stream.h index 32bc77a8..e0c6415 100644 --- a/third_party/blink/renderer/core/html/parser/html_input_stream.h +++ b/third_party/blink/renderer/core/html/parser/html_input_stream.h
@@ -36,7 +36,7 @@ // The InputStream is made up of a sequence of SegmentedStrings: // // [--current--][--next--][--next--] ... [--next--] -// /\ (also called m_last) +// /\ (also called last_) // L_ current insertion point // // The current segmented string is stored in InputStream. Each of the @@ -46,7 +46,7 @@ // document.write() will add characters at the current insertion point, which // appends them to the "current" string. // -// m_last is a pointer to the last of the afterInsertionPoint strings. The +// last_ is a pointer to the last of the afterInsertionPoint strings. The // network adds data at the end of the InputStream, which appends them to the // "last" string. class HTMLInputStream { @@ -80,7 +80,7 @@ first_ = SegmentedString(); if (last_ == &first_) { // We used to only have one SegmentedString in the InputStream but now we - // have two. That means m_first is no longer also the m_last string, + // have two. That means first_ is no longer also the last_ string, // |next| is now the last one. last_ = &next; } @@ -90,13 +90,13 @@ first_.Append(next); if (last_ == &next) { // The string |next| used to be the last SegmentedString in - // the InputStream. Now that it's been merged into m_first, - // that makes m_first the last one. + // the InputStream. Now that it's been merged into first_, + // that makes first_ the last one. last_ = &first_; } if (next.IsClosed()) { - // We also need to merge the "closed" state from next to m_first. - // Arguably, this work could be done in append(). + // We also need to merge the "closed" state from next to first_. + // Arguably, this work could be done in Append(). first_.Close(); } }
diff --git a/third_party/blink/renderer/core/html/parser/html_preload_scanner.cc b/third_party/blink/renderer/core/html/parser/html_preload_scanner.cc index f3c1555..8ff868d 100644 --- a/third_party/blink/renderer/core/html/parser/html_preload_scanner.cc +++ b/third_party/blink/renderer/core/html/parser/html_preload_scanner.cc
@@ -200,11 +200,11 @@ void HandlePictureSourceURL(PictureData& picture_data) { if (Match(tag_impl_, sourceTag) && matched_ && picture_data.source_url.IsEmpty()) { - // Must create an isolatedCopy() since the srcset attribute value will get + // Must create an IsolatedCopy() since the srcset attribute value will get // sent back to the main thread between when we set this, and when we - // process the closing tag which would clear m_pictureData. Having any ref + // process the closing tag which would clear picture_data_. Having any ref // to a string we're going to send will fail - // isSafeToSendToAnotherThread(). + // IsSafeToSendToAnotherThread(). picture_data.source_url = srcset_image_candidate_.ToString().IsolatedCopy(); picture_data.source_size_set = source_size_set_;
diff --git a/third_party/blink/renderer/core/html/parser/html_token.h b/third_party/blink/renderer/core/html/parser/html_token.h index de0d0e1..3176a0d 100644 --- a/third_party/blink/renderer/core/html/parser/html_token.h +++ b/third_party/blink/renderer/core/html/parser/html_token.h
@@ -451,7 +451,7 @@ bool self_closing_; AttributeList attributes_; - // A pointer into m_attributes used during lexing. + // A pointer into attributes_ used during lexing. Attribute* current_attribute_; // For DOCTYPE
diff --git a/third_party/blink/renderer/core/html/parser/html_tokenizer.cc b/third_party/blink/renderer/core/html/parser/html_tokenizer.cc index d2e8e49..83353e4 100644 --- a/third_party/blink/renderer/core/html/parser/html_tokenizer.cc +++ b/third_party/blink/renderer/core/html/parser/html_tokenizer.cc
@@ -871,7 +871,7 @@ // We're supposed to switch back to the attribute value state that // we were in when we were switched into this state. Rather than // keeping track of this explictly, we observe that the previous - // state can be determined by m_additionalAllowedCharacter. + // state can be determined by additional_allowed_character_. if (additional_allowed_character_ == '"') HTML_SWITCH_TO(kAttributeValueDoubleQuotedState); else if (additional_allowed_character_ == '\'') @@ -1444,7 +1444,7 @@ } String HTMLTokenizer::BufferedCharacters() const { - // FIXME: Add an assert about m_state. + // FIXME: Add a DCHECK about state_. StringBuilder characters; characters.ReserveCapacity(NumberOfBufferedCharacters()); characters.Append('<');
diff --git a/third_party/blink/renderer/core/html/parser/html_tokenizer.h b/third_party/blink/renderer/core/html/parser/html_tokenizer.h index a44d76ced..ca69ee9 100644 --- a/third_party/blink/renderer/core/html/parser/html_tokenizer.h +++ b/third_party/blink/renderer/core/html/parser/html_tokenizer.h
@@ -139,8 +139,8 @@ String BufferedCharacters() const; wtf_size_t NumberOfBufferedCharacters() const { - // Notice that we add 2 to the length of the m_temporaryBuffer to - // account for the "</" characters, which are effecitvely buffered in + // Notice that we add 2 to the length of the temporary_buffer_ to + // account for the "</" characters, which are effectively buffered in // the tokenizer's state machine. return temporary_buffer_.size() ? temporary_buffer_.size() + 2 : 0; } @@ -260,7 +260,7 @@ bool force_null_character_replacement_; bool should_allow_cdata_; - // m_token is owned by the caller. If nextToken is not on the stack, + // token_ is owned by the caller. If NextToken is not on the stack, // this member might be pointing to unallocated memory. HTMLToken* token_;
diff --git a/third_party/blink/renderer/core/html/parser/html_tree_builder.cc b/third_party/blink/renderer/core/html/parser/html_tree_builder.cc index bbfd0b70..214c26e 100644 --- a/third_party/blink/renderer/core/html/parser/html_tree_builder.cc +++ b/third_party/blink/renderer/core/html/parser/html_tree_builder.cc
@@ -283,11 +283,11 @@ void HTMLTreeBuilder::Detach() { #if DCHECK_IS_ON() // This call makes little sense in fragment mode, but for consistency - // DocumentParser expects detach() to always be called before it's destroyed. + // DocumentParser expects Detach() to always be called before it's destroyed. is_attached_ = false; #endif - // HTMLConstructionSite might be on the callstack when detach() is called - // otherwise we'd just call m_tree.clear() here instead. + // HTMLConstructionSite might be on the callstack when Detach() is called + // otherwise we'd just call tree_.Clear() here instead. tree_.Detach(); } @@ -1816,7 +1816,7 @@ return false; } tree_.GenerateImpliedEndTags(); - // FIXME: parse error if (!m_tree.currentStackItem()->hasTagName(captionTag)) + // FIXME: parse error if (!tree_.CurrentStackItem()->HasTagName(captionTag)) tree_.OpenElements()->PopUntilPopped(captionTag.LocalName()); tree_.ActiveFormattingElements()->ClearToLastMarker(); SetInsertionMode(kInTableMode);
diff --git a/third_party/blink/renderer/core/html/parser/text_resource_decoder.cc b/third_party/blink/renderer/core/html/parser/text_resource_decoder.cc index 87c2953..23d1073a 100644 --- a/third_party/blink/renderer/core/html/parser/text_resource_decoder.cc +++ b/third_party/blink/renderer/core/html/parser/text_resource_decoder.cc
@@ -369,7 +369,7 @@ // the encoding of the parent frame, which is also auto-detected. // Note that condition #2 is NOT satisfied unless parent-child frame // relationship is compliant to the same-origin policy. If they're from -// different domains, |m_source| would not be set to EncodingFromParentFrame +// different domains, |source_| would not be set to EncodingFromParentFrame // in the first place. void TextResourceDecoder::AutoDetectEncodingIfAllowed(const char* data, wtf_size_t len) {
diff --git a/third_party/blink/renderer/core/html/parser/xss_auditor.cc b/third_party/blink/renderer/core/html/parser/xss_auditor.cc index 23883ed..c9117fe 100644 --- a/third_party/blink/renderer/core/html/parser/xss_auditor.cc +++ b/third_party/blink/renderer/core/html/parser/xss_auditor.cc
@@ -150,7 +150,7 @@ } // If other files need this, we should move this to -// core/html/parser/HTMLParserIdioms.h +// core/html/parser/html_parser_idioms.h template <wtf_size_t inlineCapacity> bool ThreadSafeMatch(const Vector<UChar, inlineCapacity>& vector, const QualifiedName& qname) { @@ -204,8 +204,8 @@ static inline String DecodeStandardURLEscapeSequences( const String& string, const WTF::TextEncoding& encoding) { - // We use decodeEscapeSequences() instead of decodeURLEscapeSequences() - // (declared in weborigin/KURL.h) to avoid platform-specific URL decoding + // We use DecodeEscapeSequences() instead of DecodeURLEscapeSequences() + // (declared in weborigin/kurl.h) to avoid platform-specific URL decoding // differences (e.g. KURLGoogle). return DecodeEscapeSequences<URLEscapeSequence>(string, encoding); }
diff --git a/third_party/blink/renderer/core/html/track/html_track_element.cc b/third_party/blink/renderer/core/html/track/html_track_element.cc index fbe8ffce..ba60beff 100644 --- a/third_party/blink/renderer/core/html/track/html_track_element.cc +++ b/third_party/blink/renderer/core/html/track/html_track_element.cc
@@ -250,7 +250,7 @@ // track element. This task must use the DOM manipulation task source. // // (Note: We don't "queue a task" here because this method will only be called - // from a timer - m_loadTimer or TextTrackLoader::m_cueLoadTimer - which + // from a timer - load_timer_ or TextTrackLoader::cue_load_timer_ - which // should be a reasonable, and hopefully non-observable, approximation of the // spec text. I.e we could consider this to be run from the "networking task // source".)
diff --git a/third_party/blink/renderer/core/html/track/text_track_container.cc b/third_party/blink/renderer/core/html/track/text_track_container.cc index bec2694..f2b58c04b 100644 --- a/third_party/blink/renderer/core/html/track/text_track_container.cc +++ b/third_party/blink/renderer/core/html/track/text_track_container.cc
@@ -118,9 +118,9 @@ // Avoid excessive FP precision issue. // C11 5.2.4.2.2:9 requires assignment and cast to remove extra precision, but - // the behavior is currently not portable. fontSize may have precision higher - // than m_fontSize thus straight comparison can fail despite they cast to the - // same float value. + // the behavior is currently not portable. font_size may have precision higher + // than default_font_size_ thus straight comparison can fail despite they cast + // to the same float value. volatile float& current_font_size = default_font_size_; float old_font_size = current_font_size; current_font_size = font_size;
diff --git a/third_party/blink/renderer/core/html/track/text_track_cue_list.cc b/third_party/blink/renderer/core/html/track/text_track_cue_list.cc index b22c47c0..64d5936 100644 --- a/third_party/blink/renderer/core/html/track/text_track_cue_list.cc +++ b/third_party/blink/renderer/core/html/track/text_track_cue_list.cc
@@ -126,13 +126,13 @@ // cueIndex(list[index-1]) + 1 == cueIndex(list[index]) [index > 0] // This is a stronger requirement than we need, but it's easier to maintain. // We can then check if a cue's index is valid by comparing it with - // |m_firstInvalidIndex| - if it's strictly less it is valid. + // |first_invalid_index_| - if it's strictly less it is valid. first_invalid_index_ = std::min(first_invalid_index_, index); } void TextTrackCueList::ValidateCueIndexes() { // Compute new index values for the cues starting at - // |m_firstInvalidIndex|. If said index is beyond the end of the list, no + // |first_invalid_index_|. If said index is beyond the end of the list, no // cues will need to be updated. for (wtf_size_t i = first_invalid_index_; i < list_.size(); ++i) list_[i]->UpdateCueIndex(i);
diff --git a/third_party/blink/renderer/core/html/track/vtt/buffered_line_reader.cc b/third_party/blink/renderer/core/html/track/vtt/buffered_line_reader.cc index 1039224..9aaff444 100644 --- a/third_party/blink/renderer/core/html/track/vtt/buffered_line_reader.cc +++ b/third_party/blink/renderer/core/html/track/vtt/buffered_line_reader.cc
@@ -43,7 +43,7 @@ ScanCharacter(kNewlineCharacter); maybe_skip_lf_ = false; } - // If there was no (new) data available, then keep m_maybeSkipLF set, + // If there was no (new) data available, then keep maybe_skip_lf_ set, // and fall through all the way down to the EOS check at the end of // the method. }
diff --git a/third_party/blink/renderer/core/html/track/vtt/vtt_cue.cc b/third_party/blink/renderer/core/html/track/vtt/vtt_cue.cc index 53b4e16..a147bf0f 100644 --- a/third_party/blink/renderer/core/html/track/vtt/vtt_cue.cc +++ b/third_party/blink/renderer/core/html/track/vtt/vtt_cue.cc
@@ -535,7 +535,7 @@ } }; -// Almost the same as determineDirectionality in core/html/HTMLElement.cpp, but +// Almost the same as determineDirectionality in core/html/html_element.cc, but // that one uses a "plain" TextRunIterator (which only checks for '\n'). static TextDirection DetermineDirectionality(const String& value, bool& has_strong_directionality) { @@ -692,7 +692,7 @@ NOTREACHED(); } } else { - // Cases for m_writingDirection being VerticalGrowing{Left|Right} + // Cases for writing_direction_ being kVerticalGrowing{Left|Right} switch (computed_cue_alignment) { case kStart: display_parameters.position.SetY(computed_text_position);
diff --git a/third_party/blink/renderer/core/html/track/vtt/vtt_parser.cc b/third_party/blink/renderer/core/html/track/vtt/vtt_parser.cc index 671f13c1..4a36c646 100644 --- a/third_party/blink/renderer/core/html/track/vtt/vtt_parser.cc +++ b/third_party/blink/renderer/core/html/track/vtt/vtt_parser.cc
@@ -564,7 +564,7 @@ break; // The only non-VTTElement would be the DocumentFragment root. (Text - // nodes and PIs will never appear as m_currentNode.) + // nodes and PIs will never appear as current_node_.) if (!current_node_->IsVTTElement()) break;
diff --git a/third_party/blink/renderer/core/html/track/vtt/vtt_scanner.h b/third_party/blink/renderer/core/html/track/vtt/vtt_scanner.h index cc5667c..2532e7c 100644 --- a/third_party/blink/renderer/core/html/track/vtt/vtt_scanner.h +++ b/third_party/blink/renderer/core/html/track/vtt/vtt_scanner.h
@@ -148,7 +148,7 @@ UChar CurrentChar() const; void Advance(unsigned amount = 1); // Adapt a UChar-predicate to an LChar-predicate. - // (For use with skipWhile/Until from ParsingUtilities.h). + // (For use with SkipWhile/Until from parsing_utilities.h). template <bool characterPredicate(UChar)> static inline bool LCharPredicateAdapter(LChar c) { return characterPredicate(c);
diff --git a/third_party/blink/renderer/core/inspector/inspector_overlay_agent.cc b/third_party/blink/renderer/core/inspector/inspector_overlay_agent.cc index 59b9423..632c6a6 100644 --- a/third_party/blink/renderer/core/inspector/inspector_overlay_agent.cc +++ b/third_party/blink/renderer/core/inspector/inspector_overlay_agent.cc
@@ -903,7 +903,7 @@ ->GetScriptController() .ExecuteScriptInMainWorldAndReturnValue( ScriptSourceCode(script, ScriptSourceLocationType::kInspector), - KURL(), kNotSharableCrossOrigin, ScriptFetchOptions(), + KURL(), kOpaqueResource, ScriptFetchOptions(), ScriptController::kExecuteScriptWhenScriptsDisabled); return ToCoreStringWithUndefinedOrNullCheck(string); }
diff --git a/third_party/blink/renderer/core/inspector/inspector_page_agent.cc b/third_party/blink/renderer/core/inspector/inspector_page_agent.cc index c238218..83e35ee4 100644 --- a/third_party/blink/renderer/core/inspector/inspector_page_agent.cc +++ b/third_party/blink/renderer/core/inspector/inspector_page_agent.cc
@@ -879,9 +879,11 @@ security_origin); } + // Note: An error event in an isolated world will never be dispatched to + // a foreign world. v8::HandleScope handle_scope(V8PerIsolateData::MainThreadIsolate()); frame->GetScriptController().ExecuteScriptInIsolatedWorld( - world_id, source, KURL(), kNotSharableCrossOrigin); + world_id, source, KURL(), kOpaqueResource); } if (!script_to_evaluate_on_load_once_.IsEmpty()) {
diff --git a/third_party/blink/renderer/core/layout/layout_flexible_box.cc b/third_party/blink/renderer/core/layout/layout_flexible_box.cc index b136f89..f1415c0 100644 --- a/third_party/blink/renderer/core/layout/layout_flexible_box.cc +++ b/third_party/blink/renderer/core/layout/layout_flexible_box.cc
@@ -437,14 +437,6 @@ return StyleRef().FlexWrap() != EFlexWrap::kNowrap; } -bool LayoutFlexibleBox::ShouldApplyMinSizeAutoForChild( - const LayoutBox& child) const { - Length min = IsHorizontalFlow() ? child.StyleRef().MinWidth() - : child.StyleRef().MinHeight(); - return min.IsAuto() && !child.ShouldApplySizeContainment() && - MainAxisOverflowForChild(child) == EOverflow::kVisible; -} - Length LayoutFlexibleBox::FlexBasisForChild(const LayoutBox& child) const { Length flex_length = child.StyleRef().FlexBasis(); if (flex_length.IsAuto()) { @@ -1005,7 +997,14 @@ // computeMainAxisExtentForChild can return -1 when the child has a // percentage min size, but we have an indefinite size in that axis. sizes.min_size = std::max(LayoutUnit(), sizes.min_size); - } else if (ShouldApplyMinSizeAutoForChild(child)) { + } else if (min.IsAuto() && !child.ShouldApplySizeContainment() && + MainAxisOverflowForChild(child) == EOverflow::kVisible && + !(IsColumnFlow() && child.IsFlexibleBox())) { + // TODO(cbiesinger): For now, we do not handle min-height: auto for nested + // column flexboxes. We need to implement + // https://drafts.csswg.org/css-flexbox/#intrinsic-sizes before that + // produces reasonable results. Tracking bug: https://crbug.com/581553 + // css-flexbox section 4.5 LayoutUnit content_size = ComputeMainAxisExtentForChild(child, kMinSize, Length(kMinContent)); DCHECK_GE(content_size, LayoutUnit()); @@ -1125,14 +1124,6 @@ DISABLE_CFI_PERF FlexItem LayoutFlexibleBox::ConstructFlexItem(LayoutBox& child, ChildLayoutType layout_type) { - if (layout_type == kLayoutIfNeeded && IsColumnFlow() && - child.IsFlexibleBox() && ShouldApplyMinSizeAutoForChild(child)) { - // In this case, we have to force-layout to update the intrinsic height of - // our child; otherwise, it may be too big because it is based on previous - // flexing of a descendant, which would be a problem for applying - // min-size: auto. - layout_type = kForceLayout; - } if (layout_type != kNeverLayout && ChildHasIntrinsicMainAxisSize(child)) { // If this condition is true, then ComputeMainAxisExtentForChild will call // child.IntrinsicContentLogicalHeight() and
diff --git a/third_party/blink/renderer/core/layout/layout_flexible_box.h b/third_party/blink/renderer/core/layout/layout_flexible_box.h index 156ca0fa..a2eb5329 100644 --- a/third_party/blink/renderer/core/layout/layout_flexible_box.h +++ b/third_party/blink/renderer/core/layout/layout_flexible_box.h
@@ -111,7 +111,6 @@ bool IsColumnFlow() const; bool IsLeftToRightFlow() const; bool IsMultiline() const; - bool ShouldApplyMinSizeAutoForChild(const LayoutBox& child) const; Length FlexBasisForChild(const LayoutBox& child) const; LayoutUnit CrossAxisExtentForChild(const LayoutBox& child) const; LayoutUnit CrossAxisIntrinsicExtentForChild(const LayoutBox& child) const;
diff --git a/third_party/blink/renderer/core/layout/layout_grid.cc b/third_party/blink/renderer/core/layout/layout_grid.cc index aa0d5c3..f4abe07c 100644 --- a/third_party/blink/renderer/core/layout/layout_grid.cc +++ b/third_party/blink/renderer/core/layout/layout_grid.cc
@@ -2109,8 +2109,8 @@ LayoutUnit& start, LayoutUnit& end) const { DCHECK(!child.IsOutOfFlowPositioned()); - const GridSpan& span = - track_sizing_algorithm_.GetGrid().GridItemSpan(child, direction); + const Grid& grid = track_sizing_algorithm_.GetGrid(); + const GridSpan& span = grid.GridItemSpan(child, direction); // TODO (lajava): This is a common pattern, why not defining a function like // positions(direction) ? auto& positions = @@ -2120,8 +2120,11 @@ // The 'positions' vector includes distribution offset (because of content // alignment) and gutters so we need to subtract them to get the actual // end position for a given track (this does not have to be done for the - // last track as there are no more positions's elements after it). - if (span.EndLine() < positions.size() - 1) + // last track as there are no more positions's elements after it, nor for + // collapsed tracks). + if (span.EndLine() < positions.size() - 1 && + !(grid.HasAutoRepeatEmptyTracks(direction) && + grid.IsEmptyAutoRepeatTrack(direction, span.EndLine()))) end -= GridGap(direction) + GridItemOffset(direction); }
diff --git a/third_party/blink/renderer/core/layout/layout_text.cc b/third_party/blink/renderer/core/layout/layout_text.cc index 72d5bf83..e2cde875 100644 --- a/third_party/blink/renderer/core/layout/layout_text.cc +++ b/third_party/blink/renderer/core/layout/layout_text.cc
@@ -217,7 +217,9 @@ for (InlineTextBox* box : TextBoxes()) box->Remove(); } else if (Parent()) { - Parent()->DirtyLinesFromChangedChild(this); + if (!FirstInlineFragment() || + !NGPaintFragment::TryMarkLineBoxDirtyFor(*this)) + Parent()->DirtyLinesFromChangedChild(this); } } DeleteTextBoxes();
diff --git a/third_party/blink/renderer/core/layout/ng/ng_block_node.cc b/third_party/blink/renderer/core/layout/ng/ng_block_node.cc index f5c1a3d..1b686252 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_block_node.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_block_node.cc
@@ -676,6 +676,7 @@ FloatingObject* floating_object = ToLayoutBlockFlow(containing_block)->InsertFloatingObject(*layout_box); floating_object->SetIsInPlacedTree(false); + floating_object->SetShouldPaint(!layout_box->HasSelfPaintingLayer()); LayoutUnit horizontal_margin_edge_offset = horizontal_offset; if (has_flipped_x_axis) horizontal_margin_edge_offset -= layout_box->MarginRight();
diff --git a/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.cc b/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.cc index 8fe5749..7abb0f8e 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h" #include "third_party/blink/renderer/core/editing/position_with_affinity.h" -#include "third_party/blink/renderer/core/layout/layout_box.h" +#include "third_party/blink/renderer/core/layout/layout_block_flow.h" #include "third_party/blink/renderer/core/layout/layout_inline.h" #include "third_party/blink/renderer/core/layout/layout_object.h" #include "third_party/blink/renderer/core/layout/layout_object_inlines.h" @@ -77,6 +77,12 @@ ToLayoutBox(layout_object)->ShouldClipOverflow(); } +bool NGPhysicalBoxFragment::HasControlClip() const { + const LayoutObject* layout_object = GetLayoutObject(); + DCHECK(layout_object); + return layout_object->IsBox() && ToLayoutBox(layout_object)->HasControlClip(); +} + LayoutRect NGPhysicalBoxFragment::OverflowClipRect( const LayoutPoint& location, OverlayScrollbarClipBehavior overlay_scrollbar_clip_behavior) const { @@ -150,14 +156,11 @@ Vector<LayoutRect>* outline_rects, const LayoutPoint& additional_offset, NGOutlineType outline_type) const { - DCHECK(GetLayoutObject()); + // TODO(kojii): Needs inline_element_continuation logic from + // LayoutBlockFlow::AddOutlineRects? const LayoutObject* layout_object = GetLayoutObject(); - if (!layout_object->IsAnonymousBlock() && !layout_object->IsLayoutInline()) { - LayoutRect outline_rect(additional_offset, Size().ToLayoutSize()); - outline_rects->push_back(outline_rect); - } - + DCHECK(layout_object); if (layout_object->IsLayoutInline()) { Vector<LayoutRect> blockflow_outline_rects; ToLayoutInline(layout_object) @@ -174,46 +177,24 @@ } return; } - if (!layout_object->IsBox()) - return; - if (outline_type == NGOutlineType::kDontIncludeBlockVisualOverflow) - return; - if (HasOverflowClip() && ToLayoutBox(layout_object)->HasControlClip()) - return; + DCHECK(layout_object->IsBox()); - for (const auto& child : Children()) { - // List markers have no outline - if (child->IsListMarker()) - continue; - - if (child->IsLineBox()) { - // Traverse children of the linebox - Vector<NGPhysicalFragmentWithOffset> line_children = - NGInlineFragmentTraversal::DescendantsOf( - ToNGPhysicalLineBoxFragment(*child)); - for (const auto& line_child : line_children) { - Vector<LayoutRect> line_child_rects; - line_child_rects.push_back( - line_child.RectInContainerBox().ToLayoutRect()); - DCHECK(line_child.fragment->GetLayoutObject()); - line_child.fragment->GetLayoutObject()->LocalToAncestorRects( - line_child_rects, ToLayoutBoxModelObject(GetLayoutObject()), - child.Offset().ToLayoutPoint(), additional_offset); - if (!line_child_rects.IsEmpty()) - outline_rects->push_back(line_child_rects[0]); - } - } else { - DCHECK(child->GetLayoutObject()); - LayoutObject* child_layout = child->GetLayoutObject(); - Vector<LayoutRect> child_rects; - child_rects.push_back(child->InkOverflow().ToLayoutRect()); - child_layout->LocalToAncestorRects( - child_rects, ToLayoutBoxModelObject(GetLayoutObject()), LayoutPoint(), - additional_offset); - if (!child_rects.IsEmpty()) - outline_rects->push_back(child_rects[0]); - } + // For anonymous blocks, the children add outline rects. + if (!layout_object->IsAnonymous()) { + outline_rects->emplace_back(additional_offset, Size().ToLayoutSize()); } + + if (outline_type == NGOutlineType::kIncludeBlockVisualOverflow && + !HasOverflowClip() && !HasControlClip()) { + AddOutlineRectsForNormalChildren(outline_rects, additional_offset, + outline_type); + + // TODO(kojii): LayoutBlock::AddOutlineRects handles positioned objects + // here. Do we need it? + } + + // TODO(kojii): Needs inline_element_continuation logic from + // LayoutBlockFlow::AddOutlineRects? } NGPhysicalOffsetRect NGPhysicalBoxFragment::InkOverflow(bool apply_clip) const {
diff --git a/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h b/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h index f6c1380..dc530ca5 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h +++ b/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h
@@ -49,6 +49,7 @@ // overflow clip; i.e., AllowOverflowClip() returns false. bool HasOverflowClip() const; bool ShouldClipOverflow() const; + bool HasControlClip() const; NGPhysicalOffsetRect ScrollableOverflow() const;
diff --git a/third_party/blink/renderer/core/layout/ng/ng_physical_container_fragment.cc b/third_party/blink/renderer/core/layout/ng/ng_physical_container_fragment.cc index f7faaeb..9262a11a 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_physical_container_fragment.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_physical_container_fragment.cc
@@ -4,6 +4,13 @@ #include "third_party/blink/renderer/core/layout/ng/ng_physical_container_fragment.h" +#include "third_party/blink/renderer/core/layout/layout_block_flow.h" +#include "third_party/blink/renderer/core/layout/layout_inline.h" +#include "third_party/blink/renderer/core/layout/ng/inline/ng_physical_line_box_fragment.h" +#include "third_party/blink/renderer/core/layout/ng/ng_outline_utils.h" +#include "third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h" +#include "third_party/blink/renderer/platform/geometry/layout_rect.h" + namespace blink { NGPhysicalContainerFragment::NGPhysicalContainerFragment( @@ -28,4 +35,91 @@ DCHECK(children.IsEmpty()); // Ensure move semantics is used. } +void NGPhysicalContainerFragment::AddOutlineRectsForNormalChildren( + Vector<LayoutRect>* outline_rects, + const LayoutPoint& additional_offset, + NGOutlineType outline_type) const { + for (const auto& child : Children()) { + // Outlines of out-of-flow positioned descendants are handled in + // NGPhysicalBoxFragment::AddSelfOutlineRects(). + if (child->IsOutOfFlowPositioned()) + continue; + + // Outline of an element continuation or anonymous block continuation is + // added when we iterate the continuation chain. + // See NGPhysicalBoxFragment::AddSelfOutlineRects(). + if (LayoutObject* child_layout_object = child->GetLayoutObject()) { + if (child_layout_object->IsElementContinuation() || + (child_layout_object->IsLayoutBlockFlow() && + ToLayoutBlockFlow(child_layout_object) + ->IsAnonymousBlockContinuation())) + continue; + } + + AddOutlineRectsForDescendant(child, outline_rects, additional_offset, + outline_type); + } +} + +void NGPhysicalContainerFragment::AddOutlineRectsForDescendant( + const NGLink& descendant, + Vector<LayoutRect>* outline_rects, + const LayoutPoint& additional_offset, + NGOutlineType outline_type) const { + if (descendant->IsText() || descendant->IsListMarker()) + return; + + if (const NGPhysicalBoxFragment* descendant_box = + ToNGPhysicalBoxFragmentOrNull(descendant.get())) { + LayoutObject* descendant_layout_object = descendant_box->GetLayoutObject(); + DCHECK(descendant_layout_object); + + if (descendant_box->HasLayer()) { + Vector<LayoutRect> layer_outline_rects; + descendant_box->AddSelfOutlineRects(&layer_outline_rects, LayoutPoint(), + outline_type); + descendant_layout_object->LocalToAncestorRects( + layer_outline_rects, ToLayoutBoxModelObject(GetLayoutObject()), + LayoutPoint(), additional_offset); + outline_rects->AppendVector(layer_outline_rects); + return; + } + + if (descendant_layout_object->IsBox()) { + descendant_box->AddSelfOutlineRects( + outline_rects, + additional_offset + descendant.Offset().ToLayoutPoint(), + outline_type); + return; + } + + DCHECK(descendant_layout_object->IsLayoutInline()); + LayoutInline* descendant_layout_inline = + ToLayoutInline(descendant_layout_object); + // As an optimization, an ancestor has added rects for its line boxes + // covering descendants' line boxes, so descendants don't need to add line + // boxes again. For example, if the parent is a LayoutBlock, it adds rects + // for its line box which cover the line boxes of this LayoutInline. So + // the LayoutInline needs to add rects for children and continuations + // only. + if (!NGOutlineUtils::IsInlineOutlineNonpaintingFragment(*descendant)) { + descendant_layout_inline->AddOutlineRectsForChildrenAndContinuations( + *outline_rects, additional_offset, outline_type); + } + return; + } + + if (const NGPhysicalLineBoxFragment* descendant_line_box = + ToNGPhysicalLineBoxFragmentOrNull(descendant.get())) { + descendant_line_box->AddOutlineRectsForNormalChildren( + outline_rects, additional_offset + descendant.Offset().ToLayoutPoint(), + outline_type); + + if (!descendant_line_box->Size().IsEmpty()) { + outline_rects->emplace_back(additional_offset, + descendant_line_box->Size().ToLayoutSize()); + } + } +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/ng_physical_container_fragment.h b/third_party/blink/renderer/core/layout/ng/ng_physical_container_fragment.h index 1f9d364..97a7f37 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_physical_container_fragment.h +++ b/third_party/blink/renderer/core/layout/ng/ng_physical_container_fragment.h
@@ -13,6 +13,8 @@ namespace blink { +enum class NGOutlineType; + class CORE_EXPORT NGPhysicalContainerFragment : public NGPhysicalFragment { public: const Vector<NGLink>& Children() const { return children_; } @@ -22,6 +24,14 @@ return contents_ink_overflow_; } + void AddOutlineRectsForNormalChildren(Vector<LayoutRect>* outline_rects, + const LayoutPoint& additional_offset, + NGOutlineType outline_type) const; + void AddOutlineRectsForDescendant(const NGLink& descendant, + Vector<LayoutRect>* rects, + const LayoutPoint& additional_offset, + NGOutlineType outline_type) const; + protected: // This modifies the passed-in children vector. NGPhysicalContainerFragment(LayoutObject*,
diff --git a/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.cc b/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.cc index 1527997d..ca6df77 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.cc
@@ -278,7 +278,7 @@ } bool NGPhysicalFragment::HasLayer() const { - return layout_object_->HasLayer(); + return layout_object_ && layout_object_->HasLayer(); } PaintLayer* NGPhysicalFragment::Layer() const {
diff --git a/third_party/blink/renderer/core/mojo/tests/js_to_cpp_test.cc b/third_party/blink/renderer/core/mojo/tests/js_to_cpp_test.cc index fd2df2bf..cb5c811 100644 --- a/third_party/blink/renderer/core/mojo/tests/js_to_cpp_test.cc +++ b/third_party/blink/renderer/core/mojo/tests/js_to_cpp_test.cc
@@ -74,7 +74,7 @@ scoped_refptr<SharedBuffer> script_src = test::ReadFromFile(script_path); return frame.GetScriptController().ExecuteScriptInMainWorldAndReturnValue( ScriptSourceCode(String(script_src->Data(), script_src->size())), KURL(), - kNotSharableCrossOrigin); + kOpaqueResource); } void CheckDataPipe(mojo::DataPipeConsumerHandle data_pipe_handle) {
diff --git a/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.cc b/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.cc index f839265..c65e8e9 100644 --- a/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.cc +++ b/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.cc
@@ -334,6 +334,9 @@ ToNGPhysicalContainerFragment(fragment); children_.ReserveCapacity(container.Children().size()); + bool children_are_inline = + !fragment.IsBox() || ToNGPhysicalBoxFragment(fragment).ChildrenInline(); + unsigned child_index = 0; for (const NGLink& child_fragment : container.Children()) { bool populate_children = child_fragment->IsContainer() && @@ -344,20 +347,21 @@ : nullptr, &populate_children); - if (!child_fragment->IsFloating() && - !child_fragment->IsOutOfFlowPositioned() && - !child_fragment->IsListMarker()) { - if (LayoutObject* layout_object = child_fragment->GetLayoutObject()) { - child->AssociateWithLayoutObject(layout_object, last_fragment_map); + if (children_are_inline) { + if (!child_fragment->IsFloating() && + !child_fragment->IsOutOfFlowPositioned() && + !child_fragment->IsListMarker()) { + if (LayoutObject* layout_object = child_fragment->GetLayoutObject()) + child->AssociateWithLayoutObject(layout_object, last_fragment_map); + + child->inline_offset_to_container_box_ = + inline_offset_to_container_box + child_fragment.Offset(); } - child->inline_offset_to_container_box_ = - inline_offset_to_container_box + child_fragment.Offset(); - } - - if (populate_children) { - child->PopulateDescendants(child->inline_offset_to_container_box_, - last_fragment_map); + if (populate_children) { + child->PopulateDescendants(child->inline_offset_to_container_box_, + last_fragment_map); + } } if (child_index < children_.size()) @@ -377,15 +381,7 @@ HashMap<const LayoutObject*, NGPaintFragment*>* last_fragment_map) { DCHECK(layout_object); DCHECK(!next_for_same_layout_object_); - - // TODO(kojii): The LayoutObject is inline, except for column container - // fragment. We should have better way to distinguish it, probably after we - // determined the generated fragment tree for multicol with fragmentations - // supported. - if (!layout_object->IsInline()) { - DCHECK(Parent() && layout_object == Parent()->GetLayoutObject()); - return; - } + DCHECK(layout_object->IsInline()); auto add_result = last_fragment_map->insert(layout_object, this); if (add_result.is_new_entry) { @@ -554,31 +550,16 @@ if (marked) return; } - // Since |layout_object| isn't in fragment tree, check both following and - // preceding siblings. - bool marked = false; - for (LayoutObject* next = layout_object.NextSibling(); next; - next = next->NextSibling()) { - if (next->IsFloatingOrOutOfFlowPositioned()) - continue; - // |next| may not be in inline formatting context, e.g. <object>. - if (TryMarkLineBoxDirtyFor(*next)) { - marked = true; - break; - } - } + // Since |layout_object| isn't in fragment tree, check preceding siblings. + // Note: Once we reuse lines below dirty lines, we should check next siblings. for (LayoutObject* previous = layout_object.PreviousSibling(); previous; previous = previous->PreviousSibling()) { if (previous->IsFloatingOrOutOfFlowPositioned()) continue; // |previous| may not be in inline formatting context, e.g. <object>. - if (TryMarkLineBoxDirtyFor(*previous)) { - marked = true; - break; - } + if (TryMarkLineBoxDirtyFor(*previous)) + return; } - if (marked) - return; // There is no siblings, try parent. const LayoutObject& parent = *layout_object.Parent(); if (parent.IsInline())
diff --git a/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h b/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h index 8495ce7..0c8167bd 100644 --- a/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h +++ b/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h
@@ -167,6 +167,9 @@ return ShouldPaintCursorCaret() || ShouldPaintDragCaret(); } + // Returns true when associated fragment of |layout_object| has line box. + static bool TryMarkLineBoxDirtyFor(const LayoutObject& layout_object); + // A range of fragments for |FragmentsFor()|. class CORE_EXPORT FragmentRange { public: @@ -280,9 +283,6 @@ // formatting context. void MarkLineBoxDirty(); - // Returns true when associated fragment of |layout_object| has line box. - static bool TryMarkLineBoxDirtyFor(const LayoutObject& layout_object); - // // Following fields are computed in the layout phase. //
diff --git a/third_party/blink/renderer/core/paint/ng/ng_paint_fragment_test.cc b/third_party/blink/renderer/core/paint/ng/ng_paint_fragment_test.cc index 359f408..33781b4 100644 --- a/third_party/blink/renderer/core/paint/ng/ng_paint_fragment_test.cc +++ b/third_party/blink/renderer/core/paint/ng/ng_paint_fragment_test.cc
@@ -490,7 +490,7 @@ const NGPaintFragment& container = *GetPaintFragmentByElementId("container"); EXPECT_FALSE(container.Children()[0]->IsDirty()); EXPECT_TRUE(container.Children()[1]->IsDirty()); - EXPECT_TRUE(container.Children()[2]->IsDirty()); + EXPECT_FALSE(container.Children()[2]->IsDirty()); } TEST_F(NGPaintFragmentTest, MarkLineBoxesDirtyByInsertAtStart) { @@ -510,7 +510,7 @@ GetDocument().UpdateStyleAndLayout(); EXPECT_TRUE(line1->IsDirty()); - EXPECT_TRUE(line2->IsDirty()); + EXPECT_FALSE(line2->IsDirty()); EXPECT_FALSE(line3->IsDirty()); } @@ -551,7 +551,7 @@ GetDocument().UpdateStyleAndLayout(); EXPECT_TRUE(line1->IsDirty()); - EXPECT_TRUE(line2->IsDirty()); + EXPECT_FALSE(line2->IsDirty()); EXPECT_FALSE(line3->IsDirty()); }
diff --git a/third_party/blink/renderer/core/resize_observer/resize_observer_test.cc b/third_party/blink/renderer/core/resize_observer/resize_observer_test.cc index 1da861aa..1dfe3f98 100644 --- a/third_party/blink/renderer/core/resize_observer/resize_observer_test.cc +++ b/third_party/blink/renderer/core/resize_observer/resize_observer_test.cc
@@ -117,11 +117,11 @@ // script_controller.ExecuteScriptInMainWorldAndReturnValue( ScriptSourceCode("var ro = new ResizeObserver( entries => {});"), KURL(), - kNotSharableCrossOrigin, ScriptFetchOptions(), + kOpaqueResource, ScriptFetchOptions(), ScriptController::kExecuteScriptWhenScriptsDisabled); ASSERT_EQ(observers.size(), 1U); script_controller.ExecuteScriptInMainWorldAndReturnValue( - ScriptSourceCode("ro = undefined;"), KURL(), kNotSharableCrossOrigin, + ScriptSourceCode("ro = undefined;"), KURL(), kOpaqueResource, ScriptFetchOptions(), ScriptController::kExecuteScriptWhenScriptsDisabled); V8GCController::CollectAllGarbageForTesting(v8::Isolate::GetCurrent()); @@ -136,14 +136,14 @@ "var el = document.createElement('div');" "ro.observe(el);" "ro = undefined;"), - KURL(), kNotSharableCrossOrigin, ScriptFetchOptions(), + KURL(), kOpaqueResource, ScriptFetchOptions(), ScriptController::kExecuteScriptWhenScriptsDisabled); ASSERT_EQ(observers.size(), 1U); V8GCController::CollectAllGarbageForTesting(v8::Isolate::GetCurrent()); WebHeap::CollectAllGarbageForTesting(); ASSERT_EQ(observers.size(), 1U); script_controller.ExecuteScriptInMainWorldAndReturnValue( - ScriptSourceCode("el = undefined;"), KURL(), kNotSharableCrossOrigin, + ScriptSourceCode("el = undefined;"), KURL(), kOpaqueResource, ScriptFetchOptions(), ScriptController::kExecuteScriptWhenScriptsDisabled); V8GCController::CollectAllGarbageForTesting(v8::Isolate::GetCurrent());
diff --git a/third_party/blink/renderer/core/scheduler/frame_throttling_test.cc b/third_party/blink/renderer/core/scheduler/frame_throttling_test.cc index cd6ef5e..1893df4 100644 --- a/third_party/blink/renderer/core/scheduler/frame_throttling_test.cc +++ b/third_party/blink/renderer/core/scheduler/frame_throttling_test.cc
@@ -1197,7 +1197,7 @@ v8::HandleScope scope(v8::Isolate::GetCurrent()); v8::Local<v8::Value> result = local_frame->GetScriptController().ExecuteScriptInMainWorldAndReturnValue( - ScriptSourceCode("window.didRaf;"), KURL(), kNotSharableCrossOrigin); + ScriptSourceCode("window.didRaf;"), KURL(), kOpaqueResource); EXPECT_TRUE(result->IsTrue()); }
diff --git a/third_party/blink/renderer/core/xml/document_xml_tree_viewer.cc b/third_party/blink/renderer/core/xml/document_xml_tree_viewer.cc index 30055a0..0a5b1213 100644 --- a/third_party/blink/renderer/core/xml/document_xml_tree_viewer.cc +++ b/third_party/blink/renderer/core/xml/document_xml_tree_viewer.cc
@@ -26,7 +26,7 @@ document.GetFrame()->GetScriptController().ExecuteScriptInIsolatedWorld( IsolatedWorldId::kDocumentXMLTreeViewerWorldId, ScriptSourceCode(script_string, ScriptSourceLocationType::kInternal), - KURL(), kNotSharableCrossOrigin); + KURL(), kOpaqueResource); Element* element = document.getElementById("xml-viewer-style"); if (element) {
diff --git a/third_party/blink/renderer/modules/service_worker/service_worker_registration.idl b/third_party/blink/renderer/modules/service_worker/service_worker_registration.idl index a50faeb..2179593 100644 --- a/third_party/blink/renderer/modules/service_worker/service_worker_registration.idl +++ b/third_party/blink/renderer/modules/service_worker/service_worker_registration.idl
@@ -3,9 +3,7 @@ // found in the LICENSE file. // https://w3c.github.io/ServiceWorker/#enumdef-serviceworkerupdateviacache -[ - RuntimeEnabled=ServiceWorkerUpdateViaCache -] enum ServiceWorkerUpdateViaCache { +enum ServiceWorkerUpdateViaCache { "imports", "all", "none" @@ -23,7 +21,7 @@ readonly attribute NavigationPreloadManager navigationPreload; readonly attribute USVString scope; - [RuntimeEnabled=ServiceWorkerUpdateViaCache] readonly attribute ServiceWorkerUpdateViaCache updateViaCache; + readonly attribute ServiceWorkerUpdateViaCache updateViaCache; [CallWith=ScriptState] Promise<ServiceWorkerRegistration> update(); [CallWith=ScriptState] Promise<boolean> unregister();
diff --git a/third_party/blink/renderer/platform/exported/platform.cc b/third_party/blink/renderer/platform/exported/platform.cc index 67423a3..afd51a49 100644 --- a/third_party/blink/renderer/platform/exported/platform.cc +++ b/third_party/blink/renderer/platform/exported/platform.cc
@@ -36,6 +36,7 @@ #include "base/synchronization/waitable_event.h" #include "base/threading/thread_task_runner_handle.h" #include "base/trace_event/memory_dump_manager.h" +#include "build/build_config.h" #include "services/service_manager/public/cpp/connector.h" #include "services/service_manager/public/cpp/interface_provider.h" #include "third_party/blink/public/platform/interface_provider.h" @@ -341,20 +342,32 @@ event->Signal(); } -void Platform::InitializeCompositorThread( - const WebThreadCreationParams& params) { +void Platform::InitializeCompositorThread() { DCHECK(!compositor_thread_); + + WebThreadCreationParams params(WebThreadType::kCompositorThread); +#if defined(OS_ANDROID) + params.thread_options.priority = base::ThreadPriority::DISPLAY; +#endif std::unique_ptr<scheduler::WebThreadBase> compositor_thread = scheduler::WebThreadBase::CreateCompositorThread(params); compositor_thread->Init(); WaitUntilWebThreadTLSUpdate(compositor_thread.get()); compositor_thread_ = std::move(compositor_thread); + SetDisplayThreadPriority(compositor_thread_->ThreadId()); } WebThread* Platform::CompositorThread() { return compositor_thread_.get(); } +scoped_refptr<base::SingleThreadTaskRunner> +Platform::CompositorThreadTaskRunner() { + if (WebThread* compositor_thread = CompositorThread()) + return compositor_thread->GetTaskRunner(); + return nullptr; +} + std::unique_ptr<WebGraphicsContext3DProvider> Platform::CreateOffscreenGraphicsContext3DProvider( const Platform::ContextAttributes&,
diff --git a/third_party/blink/renderer/platform/loader/fetch/access_control_status.h b/third_party/blink/renderer/platform/loader/fetch/access_control_status.h index bd8d945..56de552 100644 --- a/third_party/blink/renderer/platform/loader/fetch/access_control_status.h +++ b/third_party/blink/renderer/platform/loader/fetch/access_control_status.h
@@ -8,7 +8,6 @@ namespace blink { enum AccessControlStatus { - kNotSharableCrossOrigin, kSharableCrossOrigin, kOpaqueResource };
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5 index 5313537..e454e517 100644 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -1143,10 +1143,6 @@ name: "ServiceWorkerScriptFullCodeCache", }, { - name: "ServiceWorkerUpdateViaCache", - status: "stable", - }, - { name: "SetRootScroller", status: "experimental", },
diff --git a/third_party/webrtc_overrides/BUILD.gn b/third_party/webrtc_overrides/BUILD.gn index 7923d5de..60ea96f 100644 --- a/third_party/webrtc_overrides/BUILD.gn +++ b/third_party/webrtc_overrides/BUILD.gn
@@ -39,7 +39,7 @@ ] } -static_library("webrtc") { +source_set("webrtc") { public_deps = [ ":jingle_deps", @@ -57,29 +57,22 @@ cflags = [ "/wd4005" ] } - # When WebRTC is built as part of Chromium it should exclude the default - # implementation of field_trial unless it is building for NACL or Chromecast. + # When Chromium is built for NACL or Chromecast, WebRTC provides a + # field_trial implementation so there is no need to depend on + # ":field_trial". # This configuration happens here: # https://cs.chromium.org/chromium/src/third_party/webrtc/webrtc.gni?l=44-51&rcl=95c56eebe0a2b31ad5752138d15b431124e17d36 if (is_nacl) { deps += [ "//native_client_sdk/src/libraries/nacl_io", - "//third_party/webrtc/system_wrappers:runtime_enabled_features_default", ] - } else if (is_chromecast) { - deps += [ - "//third_party/webrtc/system_wrappers:runtime_enabled_features_default", - ] - } else { - # Otherwise, we just add the field_trial which redirects to base and - # runtime_enabled_features which redirects to content/public/common. - sources = [ - "runtime_enabled_features.cc", - ] + } else if (!is_chromecast) { + # When Chromium doesn't build for NaCL or Chromecast, WebRTC doesn't + # provide an implementation for field_trial and a custom one (that uses + # base/metrics/field_trial.h is provided). deps += [ ":field_trial", "//base", - "//third_party/webrtc/system_wrappers:runtime_enabled_features_api", ] }
diff --git a/third_party/webrtc_overrides/runtime_enabled_features.cc b/third_party/webrtc_overrides/runtime_enabled_features.cc deleted file mode 100644 index bbb5deba..0000000 --- a/third_party/webrtc_overrides/runtime_enabled_features.cc +++ /dev/null
@@ -1,26 +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. -// -// Define webrtc::runtime_features::IsFeatureEnabled to provide webrtc with a -// chromium runtime flags access. - -#include "base/feature_list.h" -#include "third_party/webrtc/system_wrappers/include/runtime_enabled_features.h" - -namespace webrtc { - -namespace runtime_enabled_features { - -const base::Feature kWebRtcDualStreamMode{"WebRTC-DualStreamMode", - base::FEATURE_DISABLED_BY_DEFAULT}; - -bool IsFeatureEnabled(std::string feature_name) { - if (feature_name == kDualStreamModeFeatureName) - return base::FeatureList::IsEnabled(kWebRtcDualStreamMode); - return false; -} - -} // namespace runtime_enabled_features - -} // namespace webrtc
diff --git a/third_party/widevine/cdm/BUILD.gn b/third_party/widevine/cdm/BUILD.gn index 6f8f50c3..aa21ecb 100644 --- a/third_party/widevine/cdm/BUILD.gn +++ b/third_party/widevine/cdm/BUILD.gn
@@ -15,6 +15,7 @@ flags = [ "ENABLE_WIDEVINE=$enable_widevine", "SHOULD_BUNDLE_WIDEVINE_CDM=$should_bundle_widevine_cdm", + "ENABLE_WIDEVINE_CDM_COMPONENT=$enable_widevine_cdm_component", ] }
diff --git a/third_party/widevine/cdm/widevine.gni b/third_party/widevine/cdm/widevine.gni index 15c8328..e925eed 100644 --- a/third_party/widevine/cdm/widevine.gni +++ b/third_party/widevine/cdm/widevine.gni
@@ -11,14 +11,21 @@ enable_widevine = is_chrome_branded || is_android } -enable_widevine_cdm_host_verification = - enable_widevine && enable_cdm_host_verification +# The Widevine CDM can be updated as a component. This only applies to platforms +# where the CDM is a standalone library (enable_library_cdms == true). Currently +# it's only supported on Windows and Mac. The CDM can still be bundled when it's +# a component, see below. +enable_widevine_cdm_component = + enable_widevine && enable_library_cdms && (is_win || is_mac) -# Only bundle Widevine CDM in Google Chrome builds. -# TODO: Provide prebuilt libraries for ARM64. +# The Widevine CDM is bundled as part of Google Chrome builds. +# TODO(hmchen): Provide prebuilt libraries for ARM64. should_bundle_widevine_cdm = enable_widevine && is_chrome_branded && enable_library_cdms && target_cpu != "arm64" +enable_widevine_cdm_host_verification = + enable_widevine && enable_cdm_host_verification + template("widevine_sign_file") { # For official builds, generate a signature file for |file| which will # be used by Widevine. If |signature_file| is not specified, the signature
diff --git a/third_party/widevine/cdm/widevine_cdm_common.h b/third_party/widevine/cdm/widevine_cdm_common.h index a8c1faf4..53317f04 100644 --- a/third_party/widevine/cdm/widevine_cdm_common.h +++ b/third_party/widevine/cdm/widevine_cdm_common.h
@@ -5,8 +5,6 @@ #ifndef WIDEVINE_CDM_WIDEVINE_CDM_COMMON_H_ #define WIDEVINE_CDM_WIDEVINE_CDM_COMMON_H_ -#include "media/media_buildflags.h" - // This file defines constants common to all Widevine CDM versions. // "alpha" is a temporary name until a convention is defined. @@ -24,7 +22,6 @@ const char kWidevineCdmDisplayName[] = "Widevine Content Decryption Module"; -#if BUILDFLAG(ENABLE_LIBRARY_CDMS) // Identifier used by the PluginPrivateFileSystem to identify the files stored // for the Widevine CDM. This is used to store persistent files. As the files // were initially used by the CDM running as a pepper plugin, this ID is based @@ -35,10 +32,4 @@ // Name of the CDM library. const char kWidevineCdmLibraryName[] = "widevinecdm"; -#if defined(OS_MACOSX) || defined(OS_WIN) -// CDM is installed by the component installer instead of the Chrome installer. -#define WIDEVINE_CDM_IS_COMPONENT -#endif // defined(OS_MACOSX) || defined(OS_WIN) -#endif // BUILDFLAG(ENABLE_LIBRARY_CDMS) - #endif // WIDEVINE_CDM_WIDEVINE_CDM_COMMON_H_
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl index 524d4fbe..75cdcb8 100644 --- a/tools/mb/mb_config.pyl +++ b/tools/mb/mb_config.pyl
@@ -352,7 +352,7 @@ }, 'chromium.mac': { - 'Mac Builder': 'gpu_tests_release_bot', + 'Mac Builder': 'gpu_tests_release_bot_minimal_symbols', 'Mac Builder (dbg)': 'gpu_tests_debug_bot', 'mac-jumbo-rel': 'jumbo_release_bot_minimal_symbols', 'ios-device': 'ios', @@ -468,19 +468,6 @@ }, 'chromium.webrtc.fyi': { - 'Android Builder': 'android_release_bot_minimal_symbols', - 'Android Builder (dbg)': 'android_debug_static_bot', - 'Android Builder ARM64 (dbg)': 'android_debug_static_bot_arm64', - 'Linux Builder': 'gpu_tests_release_bot', - 'Linux Builder (dbg)': 'debug_bot', - 'Mac Builder': 'gpu_tests_release_bot', - 'Mac Builder (dbg)': 'debug_bot', - 'Win Builder': 'release_bot_x86_minimal_symbols_no_com_init_hooks_with_codecs', - 'Win Builder (dbg)': 'debug_bot_x86_minimal_symbols_no_com_init_hooks_with_codecs', - }, - - # TODO(crbug.com/877018): Remove once experimental configs are verified. - 'chromium.webrtc.fyi.experimental': { 'WebRTC Chromium FYI Android Builder': 'android_release_bot_minimal_symbols', 'WebRTC Chromium FYI Android Builder (dbg)': 'android_debug_static_bot', 'WebRTC Chromium FYI Android Builder ARM64 (dbg)': 'android_debug_static_bot_arm64',
diff --git a/tools/metrics/actions/actions.xml b/tools/metrics/actions/actions.xml index fd245de..309c71bf 100644 --- a/tools/metrics/actions/actions.xml +++ b/tools/metrics/actions/actions.xml
@@ -18669,6 +18669,35 @@ <description>Please enter the description of this user action.</description> </action> +<action name="StatusArea_NightLight_Disabled"> + <owner>tetsui@chromium.org</owner> + <description> + User disabled NightLight from the feature button in the system menu. + </description> +</action> + +<action name="StatusArea_NightLight_Enabled"> + <owner>tetsui@chromium.org</owner> + <description> + User enabled NightLight from the feature button in the system menu. + </description> +</action> + +<action name="StatusArea_NightLight_Settings"> + <owner>tetsui@chromium.org</owner> + <description> + User opened NightLight WebUI settings from the feature button in the system + menu. + </description> +</action> + +<action name="StatusArea_Notifications_ClearAll"> + <owner>tetsui@chromium.org</owner> + <description> + User removed all notifications from the Clear All button in the system menu. + </description> +</action> + <action name="StatusArea_OS_Update_Default_Selected"> <owner>bruthig@chromium.org</owner> <owner>tbuckley@chromium.org</owner> @@ -18678,6 +18707,22 @@ </description> </action> +<action name="StatusArea_QuietMode_Disabled"> + <owner>tetsui@chromium.org</owner> + <description> + User disabled Quiet Mode (Do not disturb) from the feature button in the + system menu. + </description> +</action> + +<action name="StatusArea_QuietMode_Enabled"> + <owner>tetsui@chromium.org</owner> + <description> + User enabled Quiet Mode (Do not disturb) from the feature button in the + system menu. + </description> +</action> + <action name="StatusArea_ScreenCapture_Default_Stop"> <owner>bruthig@chromium.org</owner> <owner>tbuckley@chromium.org</owner>
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index bd6488f3..11f8dcc1 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -47926,6 +47926,8 @@ <int value="23" label="Tracing"/> <int value="24" label="User"/> <int value="25" label="VPN"/> + <int value="26" label="Night light"/> + <int value="27" label="Do not disturb"/> </enum> <enum name="SystemNotificationType">
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 980e688..0d7799e 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -12589,6 +12589,14 @@ </summary> </histogram> +<histogram name="ChromeOS.SystemTray.IsExpandedOnOpen" enum="Boolean"> + <owner>tetsui@chromium.org</owner> + <summary> + If the value is true, SystemTray is expanded when it's opened. Otherwise, + it's closed when it's opened. + </summary> +</histogram> + <histogram name="ChromeOS.SystemTray.TimeToClick" units="ms"> <owner>tetsui@chromium.org</owner> <summary>
diff --git a/tools/traffic_annotation/summary/annotations.xml b/tools/traffic_annotation/summary/annotations.xml index ed07de7..6146e8d 100644 --- a/tools/traffic_annotation/summary/annotations.xml +++ b/tools/traffic_annotation/summary/annotations.xml
@@ -282,4 +282,5 @@ <item id="webstore_installer" hash_code="18764319" type="0" content_hash_code="11030110" os_list="linux,windows" file_path="chrome/browser/extensions/webstore_installer.cc"/> <item id="webui_content_scripts_download" hash_code="100545943" type="0" content_hash_code="119898059" os_list="linux,windows" file_path="extensions/browser/guest_view/web_view/web_ui/web_ui_url_fetcher.cc"/> <item id="xmpp_signal_strategy" hash_code="88906454" type="0" content_hash_code="88958321" os_list="linux,windows" file_path="remoting/signaling/xmpp_signal_strategy.cc"/> + <item id="service_worker_update_checker" hash_code="130931413" type="0" content_hash_code="46608086" os_list="linux,mac,windows" file_path="content/browser/service_worker/service_worker_single_script_update_checker.cc"/> </annotations>
diff --git a/ui/android/delegated_frame_host_android.cc b/ui/android/delegated_frame_host_android.cc index 1c4fb2cc2..74162a94 100644 --- a/ui/android/delegated_frame_host_android.cc +++ b/ui/android/delegated_frame_host_android.cc
@@ -177,7 +177,9 @@ } bool DelegatedFrameHostAndroid::CanCopyFromCompositingSurface() const { - return pending_local_surface_id_.is_valid() && view_->GetWindowAndroid() && + return content_layer_ && content_layer_->fallback_surface_id() && + content_layer_->fallback_surface_id()->is_valid() && + view_->GetWindowAndroid() && view_->GetWindowAndroid()->GetCompositor(); } @@ -403,6 +405,7 @@ return; } + content_layer_->SetFallbackSurfaceId(surface_info.id()); active_local_surface_id_ = surface_info.id().local_surface_id(); active_device_scale_factor_ = surface_info.device_scale_factor(); @@ -462,7 +465,9 @@ } viz::SurfaceId DelegatedFrameHostAndroid::SurfaceId() const { - return viz::SurfaceId(frame_sink_id_, active_local_surface_id_); + return content_layer_ && content_layer_->fallback_surface_id() + ? *content_layer_->fallback_surface_id() + : viz::SurfaceId(); } bool DelegatedFrameHostAndroid::HasPrimarySurface() const {
diff --git a/ui/aura/mus/window_port_mus.cc b/ui/aura/mus/window_port_mus.cc index 75b1099..c91999eb 100644 --- a/ui/aura/mus/window_port_mus.cc +++ b/ui/aura/mus/window_port_mus.cc
@@ -6,12 +6,12 @@ #include "base/auto_reset.h" #include "cc/mojo_embedder/async_layer_tree_frame_sink.h" +#include "components/viz/client/hit_test_data_provider_draw_quad.h" #include "components/viz/client/local_surface_id_provider.h" #include "components/viz/host/host_frame_sink_manager.h" #include "ui/aura/client/aura_constants.h" #include "ui/aura/client/transient_window_client.h" #include "ui/aura/env.h" -#include "ui/aura/hit_test_data_provider_aura.h" #include "ui/aura/mus/client_surface_embedder.h" #include "ui/aura/mus/property_converter.h" #include "ui/aura/mus/window_tree_client.h" @@ -126,7 +126,7 @@ params.pipes.compositor_frame_sink_info = std::move(sink_info); params.pipes.client_request = std::move(client_request); params.hit_test_data_provider = - std::make_unique<HitTestDataProviderAura>(window_); + std::make_unique<viz::HitTestDataProviderDrawQuad>(window_); params.local_surface_id_provider = std::make_unique<viz::DefaultLocalSurfaceIdProvider>(); params.enable_surface_synchronization = true;
diff --git a/ui/events/event_unittest.cc b/ui/events/event_unittest.cc index 6c40d31..7c7dbf9 100644 --- a/ui/events/event_unittest.cc +++ b/ui/events/event_unittest.cc
@@ -25,7 +25,6 @@ #if defined(USE_X11) #include "ui/events/test/events_test_utils_x11.h" -#include "ui/events/x/events_x_utils.h" // nogncheck #include "ui/gfx/x/x11.h" // nogncheck #include "ui/gfx/x/x11_types.h" // nogncheck #endif @@ -431,15 +430,6 @@ #if defined(USE_X11) namespace { -class MockTimestampServer : public ui::TimestampServer { - public: - Time GetCurrentServerTime() override { return base_time_; } - void SetBaseTime(Time time) { base_time_ = time; } - - private: - Time base_time_ = 0; -}; - void SetKeyEventTimestamp(XEvent* event, int64_t time) { event->xkey.time = time & UINT32_MAX; } @@ -450,23 +440,7 @@ } // namespace -class X11EventTest : public testing::Test { - public: - X11EventTest() {} - ~X11EventTest() override {} - - void SetUp() override { SetTimestampServer(&server_); } - - void TearDown() override { SetTimestampServer(nullptr); } - - protected: - MockTimestampServer server_; - - private: - DISALLOW_COPY_AND_ASSIGN(X11EventTest); -}; - -TEST_F(X11EventTest, AutoRepeat) { +TEST(EventTest, AutoRepeat) { const uint16_t kNativeCodeA = ui::KeycodeConverter::DomCodeToNativeKeycode(DomCode::US_A); const uint16_t kNativeCodeB = @@ -494,7 +468,6 @@ int64_t ticks_base = (base::TimeTicks::Now() - base::TimeTicks()).InMilliseconds() - 5000; - server_.SetBaseTime(static_cast<Time>(ticks_base)); SetKeyEventTimestamp(native_event_a_pressed, ticks_base); SetKeyEventTimestamp(native_event_a_pressed_1500, ticks_base + 1500); SetKeyEventTimestamp(native_event_a_pressed_3000, ticks_base + 3000); @@ -565,14 +538,12 @@ EXPECT_FALSE(key_a4_pressed_nonstandard_state.is_repeat()); } - // The nonstandard event from above was ignored, so the last event pressed was - // |native_event_a_pressed|. These are both repeats. { KeyEvent key_a1(native_event_a_pressed); - EXPECT_TRUE(key_a1.is_repeat()); + EXPECT_FALSE(key_a1.is_repeat()); KeyEvent key_a1_with_same_event(native_event_a_pressed); - EXPECT_TRUE(key_a1_with_same_event.is_repeat()); + EXPECT_FALSE(key_a1_with_same_event.is_repeat()); } } #endif // USE_X11
diff --git a/ui/events/platform/x11/x11_event_source.cc b/ui/events/platform/x11/x11_event_source.cc index a68188d..7e9f6df 100644 --- a/ui/events/platform/x11/x11_event_source.cc +++ b/ui/events/platform/x11/x11_event_source.cc
@@ -100,7 +100,6 @@ distribution_(0, 999) { DCHECK(!instance_); instance_ = this; - SetTimestampServer(this); DCHECK(delegate_); DCHECK(display_); @@ -111,7 +110,6 @@ X11EventSource::~X11EventSource() { DCHECK_EQ(this, instance_); instance_ = nullptr; - SetTimestampServer(nullptr); if (dummy_initialized_) XDestroyWindow(display_, dummy_window_); }
diff --git a/ui/events/platform/x11/x11_event_source.h b/ui/events/platform/x11/x11_event_source.h index c2ee795..e818c4ac 100644 --- a/ui/events/platform/x11/x11_event_source.h +++ b/ui/events/platform/x11/x11_event_source.h
@@ -14,7 +14,6 @@ #include "base/optional.h" #include "build/build_config.h" #include "ui/events/events_export.h" -#include "ui/events/x/events_x_utils.h" #include "ui/gfx/x/x11_types.h" using Time = unsigned long; @@ -47,7 +46,7 @@ // Receives X11 events and sends them to X11EventSourceDelegate. Handles // receiving, pre-process and post-processing XEvents. -class EVENTS_EXPORT X11EventSource : TimestampServer { +class EVENTS_EXPORT X11EventSource { public: X11EventSource(X11EventSourceDelegate* delegate, XDisplay* display); ~X11EventSource(); @@ -83,7 +82,7 @@ // Explicitly asks the X11 server for the current timestamp, and updates // |last_seen_server_time_| with this value. - Time GetCurrentServerTime() override; + Time GetCurrentServerTime(); protected: // Extracts cookie data from |xevent| if it's of GenericType, and dispatches
diff --git a/ui/events/x/events_x.cc b/ui/events/x/events_x.cc index 6253031..b8df7b0 100644 --- a/ui/events/x/events_x.cc +++ b/ui/events/x/events_x.cc
@@ -81,7 +81,9 @@ } base::TimeTicks EventTimeFromNative(const PlatformEvent& native_event) { - return EventTimeFromXEvent(*native_event); + base::TimeTicks timestamp = EventTimeFromXEvent(*native_event); + ValidateEventTimeClock(×tamp); + return timestamp; } gfx::PointF EventLocationFromNative(const PlatformEvent& native_event) {
diff --git a/ui/events/x/events_x_unittest.cc b/ui/events/x/events_x_unittest.cc index 3419309..897c5c5 100644 --- a/ui/events/x/events_x_unittest.cc +++ b/ui/events/x/events_x_unittest.cc
@@ -76,15 +76,6 @@ return rotation_angle; } -class MockTimestampServer : public ui::TimestampServer { - public: - Time GetCurrentServerTime() override { return base_time_; } - void SetBaseTime(Time time) { base_time_ = time; } - - private: - Time base_time_ = 0; -}; - } // namespace class EventsXTest : public testing::Test { @@ -93,15 +84,13 @@ ~EventsXTest() override {} void SetUp() override { - SetTimestampServer(&server_); DeviceDataManagerX11::CreateInstance(); ui::TouchFactory::GetInstance()->ResetForTest(); + ResetTimestampRolloverCountersForTesting(); } - - void TearDown() override { SetTimestampServer(nullptr); } + void TearDown() override { ResetTimestampRolloverCountersForTesting(); } private: - MockTimestampServer server_; DISALLOW_COPY_AND_ASSIGN(EventsXTest); }; @@ -553,4 +542,52 @@ EXPECT_EQ(ui::ET_UNKNOWN, ui::EventTypeFromNative(xev)); } +namespace { + +// Returns a fake TimeTicks based on the given millisecond offset. +base::TimeTicks TimeTicksFromMillis(int64_t millis) { + return base::TimeTicks() + base::TimeDelta::FromMilliseconds(millis); +} + +} // namespace + +TEST_F(EventsXTest, TimestampRolloverAndAdjustWhenDecreasing) { + XEvent event; + InitButtonEvent(&event, true, gfx::Point(5, 10), 1, 0); + + test::ScopedEventTestTickClock clock; + clock.SetNowTicks(TimeTicksFromMillis(0x100000001)); + ResetTimestampRolloverCountersForTesting(); + + event.xbutton.time = 0xFFFFFFFF; + EXPECT_EQ(TimeTicksFromMillis(0xFFFFFFFF), ui::EventTimeFromNative(&event)); + + clock.SetNowTicks(TimeTicksFromMillis(0x100000007)); + ResetTimestampRolloverCountersForTesting(); + + event.xbutton.time = 3; + EXPECT_EQ(TimeTicksFromMillis(0x100000000 + 3), + ui::EventTimeFromNative(&event)); +} + +TEST_F(EventsXTest, NoTimestampRolloverWhenMonotonicIncreasing) { + XEvent event; + InitButtonEvent(&event, true, gfx::Point(5, 10), 1, 0); + + test::ScopedEventTestTickClock clock; + clock.SetNowTicks(TimeTicksFromMillis(10)); + ResetTimestampRolloverCountersForTesting(); + + event.xbutton.time = 6; + EXPECT_EQ(TimeTicksFromMillis(6), ui::EventTimeFromNative(&event)); + event.xbutton.time = 7; + EXPECT_EQ(TimeTicksFromMillis(7), ui::EventTimeFromNative(&event)); + + clock.SetNowTicks(TimeTicksFromMillis(0x100000005)); + ResetTimestampRolloverCountersForTesting(); + + event.xbutton.time = 0xFFFFFFFF; + EXPECT_EQ(TimeTicksFromMillis(0xFFFFFFFF), ui::EventTimeFromNative(&event)); +} + } // namespace ui
diff --git a/ui/events/x/events_x_utils.cc b/ui/events/x/events_x_utils.cc index be8256c..86fbd19 100644 --- a/ui/events/x/events_x_utils.cc +++ b/ui/events/x/events_x_utils.cc
@@ -27,24 +27,6 @@ namespace { -ui::TimestampServer* g_timestamp_server = nullptr; - -// Clamps a TimeDelta to be within [0 seconds, 30 seconds]. -base::TimeDelta ClampDeltaFromExternalSource(const base::TimeDelta& delta) { - // Ignore pathologically long deltas. External source is probably having - // issues. - constexpr base::TimeDelta pathologically_long_duration = - base::TimeDelta::FromSeconds(30); - if (delta > pathologically_long_duration) - return base::TimeDelta(); - - // Ignore negative deltas. External source is probably having issues. - if (delta < base::TimeDelta()) - return base::TimeDelta(); - - return delta; -} - // Scroll amount for each wheelscroll event. 53 is also the value used for GTK+. const int kWheelScrollAmount = 53; @@ -326,29 +308,40 @@ return true; } +int64_t g_last_seen_timestamp_ms = 0; +int64_t g_rollover_ms = 0; + +// Takes Xlib Time and returns a time delta that is immune to timer rollover. +// This function is not thread safe as we do not use a lock. base::TimeTicks TimeTicksFromXEventTime(Time timestamp) { - // There's no way to convert from an X time to a base::TimeTicks without - // knowing the current X server time. - if (!g_timestamp_server) - return base::TimeTicks(); + int64_t timestamp64 = timestamp; - // X11 uses a uint32_t on the wire protocol. Xlib casts this to an unsigned - // long by prepending with 0s. We cast back to a uint32_t so that subtraction - // works properly when the timestamp overflows back to 0. - uint32_t event_server_time_ms = static_cast<uint32_t>(timestamp); - uint32_t current_server_time_ms = - static_cast<uint32_t>(g_timestamp_server->GetCurrentServerTime()); + if (!timestamp) + return ui::EventTimeForNow(); - // On X11, event times are in X11 Server time. To convert to base::TimeTicks, - // we perform a round-trip to the X11 Server, subtract the two times to get a - // TimeDelta, and then subtract that from base::TimeTicks::Now(). Since we're - // working with units of time from an external source, we clamp the TimeDelta - // to reasonable values. - uint32_t delta_ms = current_server_time_ms - event_server_time_ms; - base::TimeDelta delta = base::TimeDelta::FromMilliseconds(delta_ms); - base::TimeDelta sanitized = ClampDeltaFromExternalSource(delta); + // If this is the first event that we get, assume the time stamp roll-over + // might have happened before the process was started. + // Register a rollover if the distance between last timestamp and current one + // is larger than half the width. This avoids false rollovers even in a case + // where X server delivers reasonably close events out-of-order. + bool had_recent_rollover = + !g_last_seen_timestamp_ms || + g_last_seen_timestamp_ms - timestamp64 > (UINT32_MAX >> 1); - return base::TimeTicks::Now() - sanitized; + g_last_seen_timestamp_ms = timestamp64; + if (!had_recent_rollover) + return base::TimeTicks() + + base::TimeDelta::FromMilliseconds(g_rollover_ms + timestamp); + + DCHECK(timestamp64 <= UINT32_MAX) + << "X11 Time does not roll over 32 bit, the below logic is likely wrong"; + + base::TimeTicks now_ticks = ui::EventTimeForNow(); + int64_t now_ms = (now_ticks - base::TimeTicks()).InMilliseconds(); + + g_rollover_ms = now_ms & ~static_cast<int64_t>(UINT32_MAX); + uint32_t delta = static_cast<uint32_t>(now_ms - timestamp); + return base::TimeTicks() + base::TimeDelta::FromMilliseconds(now_ms - delta); } } // namespace @@ -838,12 +831,9 @@ return XModifierStateWatcher::GetInstance()->state() & Mod1Mask; } -void SetTimestampServer(TimestampServer* server) { - // This method must be setting or unsetting a timestamp server. It should - // never replace an existing timestamp server, nor change from - // nullptr->nullptr. - CHECK(!!g_timestamp_server ^ !!server); - g_timestamp_server = server; +void ResetTimestampRolloverCountersForTesting() { + g_last_seen_timestamp_ms = 0; + g_rollover_ms = 0; } } // namespace ui
diff --git a/ui/events/x/events_x_utils.h b/ui/events/x/events_x_utils.h index df210f2..64814e87 100644 --- a/ui/events/x/events_x_utils.h +++ b/ui/events/x/events_x_utils.h
@@ -16,8 +16,6 @@ #include "ui/gfx/geometry/point.h" #include "ui/gfx/x/x11_types.h" -using Time = unsigned long; - namespace ui { // Gets the EventType from a XEvent. @@ -93,15 +91,6 @@ EVENTS_X_EXPORT void ResetTimestampRolloverCountersForTesting(); -// Conversion from X Time to base::TimeTicks requires checking the current X -// Server Time. This functionality is provided by X11EventSource, but due to odd -// layering that cannot be referenced directly. -class TimestampServer { - public: - virtual Time GetCurrentServerTime() = 0; -}; -EVENTS_X_EXPORT void SetTimestampServer(TimestampServer* server); - } // namespace ui #endif // UI_EVENTS_X_EVENTS_X_UTILS_H_
diff --git a/ui/file_manager/audio_player/js/BUILD.gn b/ui/file_manager/audio_player/js/BUILD.gn index bcfcc90..08c3cc9 100644 --- a/ui/file_manager/audio_player/js/BUILD.gn +++ b/ui/file_manager/audio_player/js/BUILD.gn
@@ -18,7 +18,6 @@ sources = [] externs_list = [ "$externs_path/chrome_extensions.js", - "$externs_path/command_line_private.js", "$externs_path/metrics_private.js", "../../externs/audio_player_foreground.js", "../../externs/entry_location.js",
diff --git a/ui/file_manager/file_manager/background/js/BUILD.gn b/ui/file_manager/file_manager/background/js/BUILD.gn index 6ce1485b..a645f68 100644 --- a/ui/file_manager/file_manager/background/js/BUILD.gn +++ b/ui/file_manager/file_manager/background/js/BUILD.gn
@@ -55,7 +55,6 @@ js_library("closure_compile_externs") { sources = [] externs_list = [ - "$externs_path/command_line_private.js", "$externs_path/metrics_private.js", "../../../externs/background/file_browser_background.js", "../../../externs/background/file_browser_background_full.js",
diff --git a/ui/file_manager/file_manager/common/js/BUILD.gn b/ui/file_manager/file_manager/common/js/BUILD.gn index 72772a1..30d6647 100644 --- a/ui/file_manager/file_manager/common/js/BUILD.gn +++ b/ui/file_manager/file_manager/common/js/BUILD.gn
@@ -101,6 +101,7 @@ deps = [ "//ui/webui/resources/js:webui_resource_test", ] + externs_list = [ "$externs_path/command_line_private.js" ] } js_library("util") {
diff --git a/ui/file_manager/file_manager/common/js/unittest_util.js b/ui/file_manager/file_manager/common/js/unittest_util.js index 2bdfc03..cf7b20b 100644 --- a/ui/file_manager/file_manager/common/js/unittest_util.js +++ b/ui/file_manager/file_manager/common/js/unittest_util.js
@@ -12,12 +12,14 @@ * test failed. */ function reportPromise(promise, callback) { - promise.then(function() { - callback(/* error */ false); - }, function(error) { - console.error(error.stack || error); - callback(/* error */ true); - }); + promise.then( + function() { + callback(/* error */ false); + }, + function(/** @type {Error} */ error) { + console.error(error.stack || error); + callback(/* error */ true); + }); } /**
diff --git a/ui/file_manager/file_manager/foreground/js/metadata/BUILD.gn b/ui/file_manager/file_manager/foreground/js/metadata/BUILD.gn index b66e809..f686653 100644 --- a/ui/file_manager/file_manager/foreground/js/metadata/BUILD.gn +++ b/ui/file_manager/file_manager/foreground/js/metadata/BUILD.gn
@@ -38,7 +38,6 @@ js_library("closure_compile_externs") { sources = [] externs_list = [ - "$externs_path/command_line_private.js", "../../../../externs/app_window_common.js", "../../../../externs/entry_location.js", "../../../../externs/platform.js",
diff --git a/ui/file_manager/file_manager/foreground/js/ui/BUILD.gn b/ui/file_manager/file_manager/foreground/js/ui/BUILD.gn index 724d7e76..d66b4acb 100644 --- a/ui/file_manager/file_manager/foreground/js/ui/BUILD.gn +++ b/ui/file_manager/file_manager/foreground/js/ui/BUILD.gn
@@ -45,7 +45,6 @@ js_library("closure_compile_externs") { sources = [] externs_list = [ - "$externs_path/command_line_private.js", "$externs_path/metrics_private.js", "$externs_path/web_animations.js", "../../../../externs/app_window_common.js",
diff --git a/ui/file_manager/file_manager/foreground/js/ui/location_line.js b/ui/file_manager/file_manager/foreground/js/ui/location_line.js index da6a68f..183ca78 100644 --- a/ui/file_manager/file_manager/foreground/js/ui/location_line.js +++ b/ui/file_manager/file_manager/foreground/js/ui/location_line.js
@@ -89,8 +89,13 @@ } if (locationInfo.rootType === VolumeManagerCommon.RootType.DRIVE_OTHER) { // When target path is a shared directory, volume should be shared with me. - displayRootUrl = this.replaceRootName_(displayRootUrl, '/other'); - displayRootFullPath = '/other'; + const match = entry.fullPath.match(/\/\.files-by-id\/\d+\//); + if (match) { + displayRootFullPath = match[0]; + } else { + displayRootFullPath = '/other'; + } + displayRootUrl = this.replaceRootName_(displayRootUrl, displayRootFullPath); var sharedWithMeFakeEntry = locationInfo.volumeInfo.fakeEntries[ VolumeManagerCommon.RootType.DRIVE_SHARED_WITH_ME]; components.push(new LocationLine.PathComponent(
diff --git a/ui/file_manager/image_loader/BUILD.gn b/ui/file_manager/image_loader/BUILD.gn index 8c5fdb5..f883211 100644 --- a/ui/file_manager/image_loader/BUILD.gn +++ b/ui/file_manager/image_loader/BUILD.gn
@@ -102,7 +102,6 @@ ":piex_loader", "../file_manager/common/js:unittest_util", "//ui/webui/resources/js:webui_resource_test", - "//ui/webui/resources/js/cr:ui", ] } @@ -126,8 +125,7 @@ } js_unit_tests("unit_tests") { - # TODO(tapted): Uncomment the next line. - # closure_flags = default_closure_args + [ "jscomp_error=strictCheckTypes" ] + closure_flags = default_closure_args + [ "jscomp_error=strictCheckTypes" ] deps = [ ":cache_unittest", ":image_loader_client_unittest",
diff --git a/ui/file_manager/image_loader/piex_loader_unittest.js b/ui/file_manager/image_loader/piex_loader_unittest.js index 9d09aea..4f69e74c 100644 --- a/ui/file_manager/image_loader/piex_loader_unittest.js +++ b/ui/file_manager/image_loader/piex_loader_unittest.js
@@ -8,36 +8,37 @@ } }; -/** - * @constructor - * @extends {HTMLDivElement} - */ -var MockModule = /** @type{function(new:MockModule)}*/ (cr.ui.define('div')); -MockModule.prototype = Object.create(HTMLDivElement.prototype); -MockModule.prototype.constructor = MockModule; +class MockModule extends HTMLDivElement { + constructor() { + super(); + /** @type{?function()} */ + this.onBeforeMessageCallback_ = null; + setTimeout(() => { + this.dispatchEvent(new Event('load', {bubbles: true})); + }); + } -MockModule.prototype.setBeforeMessageCallback = function(callback) { - this.onBeforeMessageCallback_ = callback; -}; + setBeforeMessageCallback(callback) { + this.onBeforeMessageCallback_ = callback; + } -MockModule.prototype.decorate = function() { - this.onBeforeMessageCallback_ = null; - setTimeout(function() { - this.dispatchEvent(new Event('load', {bubbles: true})); - }.bind(this)); -}; + postMessage(message) { + setTimeout(() => { + this.dispatchEvent(new Event('load', {bubbles: true})); + if (this.onBeforeMessageCallback_) + this.onBeforeMessageCallback_(); -MockModule.prototype.postMessage = function(message) { - setTimeout(function() { - this.dispatchEvent(new Event('load', {bubbles: true})); - if (this.onBeforeMessageCallback_) - this.onBeforeMessageCallback_(); + let e = new Event('message', {bubbles: true}); + // Cast to a MessageEvent to write to |data|. We can't use + // `new MessageEvent` since its |data| property is read-only. + /** @type{MessageEvent} */ (e) + .data = {id: message.id, thumbnail: 'thumbnail-data', orientation: 1}; + this.dispatchEvent(e); + }); + } +} - var e = new CustomEvent('message', {bubbles: true}); - e.data = {id: message.id, thumbnail: 'thumbnail-data', orientation: 1}; - this.dispatchEvent(e); - }.bind(this)); -}; +customElements.define('mock-module', MockModule, {extends: 'div'}); function testUnloadingAfterTimeout(callback) { var loadCount = 0;
diff --git a/ui/file_manager/integration_tests/file_manager/drive_specific.js b/ui/file_manager/integration_tests/file_manager/drive_specific.js index 4dc1dda..d2c93b3 100644 --- a/ui/file_manager/integration_tests/file_manager/drive_specific.js +++ b/ui/file_manager/integration_tests/file_manager/drive_specific.js
@@ -119,10 +119,20 @@ * "shared-with-me" should be shown. */ testcase.driveOpenSidebarSharedWithMe = function() { - var appId; + let appId; + let isDriveFsEnabled; StepsRunner.run([ function() { - setupAndWaitUntilReady(null, RootPath.DRIVE, this.next); + sendTestMessage({name: 'getDriveFsEnabled'}).then(this.next); + }, + function(result) { + isDriveFsEnabled = result === 'true'; + + setupAndWaitUntilReady( + null, RootPath.DRIVE, this.next, [], BASIC_DRIVE_ENTRY_SET.concat([ + ENTRIES.sharedDirectory, + ENTRIES.sharedDirectoryFile, + ])); }, // Click the icon of the Shared With Me volume. function(results) { @@ -132,17 +142,45 @@ appId, ['drive_shared_with_me'], this.next); }, - // Wait until the file list is updated. + // Wait until the breadcrumb path is updated. function(result) { chrome.test.assertFalse(!result); - remoteCall.waitForFileListChange(appId, BASIC_DRIVE_ENTRY_SET.length). - then(this.next); + remoteCall.waitUntilCurrentDirectoryIsChanged(appId, '/Shared with me') + .then(this.next); }, // Verify the file list. - function(actualFilesAfter) { - chrome.test.assertEq( - TestEntryInfo.getExpectedRows(SHARED_WITH_ME_ENTRY_SET).sort(), - actualFilesAfter); + function() { + remoteCall + .waitForFiles( + appId, + TestEntryInfo.getExpectedRows( + SHARED_WITH_ME_ENTRY_SET.concat([ENTRIES.sharedDirectory]))) + .then(this.next); + }, + // Navigate to the directory within Shared with me. + function() { + remoteCall.callRemoteTestUtil('openFile', appId, ['Shared Directory']) + .then(this.next); + }, + // Wait until the breadcrumb path is updated. + function(result) { + chrome.test.assertFalse(!result); + remoteCall + .waitUntilCurrentDirectoryIsChanged( + appId, + isDriveFsEnabled ? '/Shared with me/Shared Directory' : + '/My Drive/Shared Directory') + .then(this.next); + }, + // Verify the file list. + function() { + remoteCall + .waitForFiles( + appId, + TestEntryInfo.getExpectedRows([ENTRIES.sharedDirectoryFile])) + .then(this.next); + }, + function() { checkIfNoErrorsOccured(this.next); } ]);
diff --git a/ui/file_manager/integration_tests/test_util.js b/ui/file_manager/integration_tests/test_util.js index b499fcc1..82235ef 100644 --- a/ui/file_manager/integration_tests/test_util.js +++ b/ui/file_manager/integration_tests/test_util.js
@@ -209,7 +209,9 @@ */ var SharedOption = Object.freeze({ NONE: 'none', - SHARED: 'shared' + SHARED: 'shared', + SHARED_WITH_ME: 'sharedWithMe', + NESTED_SHARED_WITH_ME: 'nestedSharedWithMe', }); /** @@ -818,4 +820,26 @@ sizeText: '51 bytes', typeText: 'Plain text' }), + + sharedDirectory: new TestEntryInfo({ + type: EntryType.DIRECTORY, + targetPath: 'Shared Directory', + sharedOption: SharedOption.SHARED_WITH_ME, + lastModifiedTime: 'Jan 1, 2000, 1:00 AM', + nameText: 'Shared Directory', + sizeText: '--', + typeText: 'Folder' + }), + + sharedDirectoryFile: new TestEntryInfo({ + type: EntryType.FILE, + sourceFileName: 'text.txt', + targetPath: 'Shared Directory/file.txt', + mimeType: 'text/plain', + sharedOption: SharedOption.NESTED_SHARED_WITH_ME, + lastModifiedTime: 'Jan 1, 2000, 1:00 AM', + nameText: 'file.txt', + sizeText: '51 bytes', + typeText: 'Plain text' + }), };
diff --git a/ui/file_manager/video_player/js/BUILD.gn b/ui/file_manager/video_player/js/BUILD.gn index 359597a..1ac9457 100644 --- a/ui/file_manager/video_player/js/BUILD.gn +++ b/ui/file_manager/video_player/js/BUILD.gn
@@ -20,7 +20,6 @@ sources = [] externs_list = [ "$externs_path/chrome_extensions.js", - "$externs_path/command_line_private.js", "$externs_path/media_player_private.js", "$externs_path/metrics_private.js", "../../externs/chrome_cast.js",
diff --git a/ui/file_manager/video_player/js/cast/BUILD.gn b/ui/file_manager/video_player/js/cast/BUILD.gn index b0ca2c8..aaa6a83 100644 --- a/ui/file_manager/video_player/js/cast/BUILD.gn +++ b/ui/file_manager/video_player/js/cast/BUILD.gn
@@ -18,7 +18,6 @@ sources = [] externs_list = [ "$externs_path/chrome_extensions.js", - "$externs_path/command_line_private.js", "$externs_path/media_player_private.js", "$externs_path/metrics_private.js", "../../../externs/app_window_common.js",
diff --git a/ui/gfx/BUILD.gn b/ui/gfx/BUILD.gn index 4f727ce..02bc6279 100644 --- a/ui/gfx/BUILD.gn +++ b/ui/gfx/BUILD.gn
@@ -220,6 +220,9 @@ "shadow_util.h", "skia_paint_util.cc", "skia_paint_util.h", + "skia_vector_animation.cc", + "skia_vector_animation.h", + "skia_vector_animation_observer.h", ] } @@ -686,6 +689,7 @@ "sequential_id_generator_unittest.cc", "shadow_value_unittest.cc", "skbitmap_operations_unittest.cc", + "skia_vector_animation_unittest.cc", "skrect_conversion_unittest.cc", "transform_util_unittest.cc", "utf16_indexing_unittest.cc",
diff --git a/ui/gfx/skia_vector_animation.cc b/ui/gfx/skia_vector_animation.cc new file mode 100644 index 0000000..191e327 --- /dev/null +++ b/ui/gfx/skia_vector_animation.cc
@@ -0,0 +1,269 @@ +// 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/gfx/skia_vector_animation.h" + +#include "base/trace_event/trace_event.h" +#include "third_party/skia/include/core/SkBitmap.h" +#include "third_party/skia/include/core/SkCanvas.h" +#include "third_party/skia/include/core/SkImage.h" +#include "ui/gfx/canvas.h" +#include "ui/gfx/geometry/size_conversions.h" +#include "ui/gfx/image/image_skia.h" +#include "ui/gfx/skia_util.h" +#include "ui/gfx/skia_vector_animation_observer.h" + +namespace gfx { + +SkiaVectorAnimation::TimerControl::TimerControl( + const base::TimeDelta& offset, + const base::TimeDelta& cycle_duration, + const base::TimeDelta& total_duration, + const base::TimeTicks& start_timestamp, + bool should_reverse) + : start_offset_(offset), + end_offset_((offset + cycle_duration)), + cycle_duration_(end_offset_ - start_offset_), + progress_per_millisecond_(1.0 / total_duration.InMillisecondsF()), + previous_tick_(start_timestamp), + progress_(base::TimeDelta::FromMilliseconds(0)), + current_cycle_progress_(start_offset_), + should_reverse_(should_reverse) {} + +void SkiaVectorAnimation::TimerControl::Step(const base::TimeTicks& timestamp) { + progress_ += timestamp - previous_tick_; + previous_tick_ = timestamp; + + base::TimeDelta completed_cycles_duration = + completed_cycles_ * cycle_duration_; + if (progress_ >= completed_cycles_duration + cycle_duration_) { + completed_cycles_++; + completed_cycles_duration += cycle_duration_; + } + + current_cycle_progress_ = + start_offset_ + progress_ - completed_cycles_duration; + if (should_reverse_ && completed_cycles_ % 2) { + current_cycle_progress_ = + end_offset_ - (current_cycle_progress_ - start_offset_); + } +} + +void SkiaVectorAnimation::TimerControl::Resume( + const base::TimeTicks& timestamp) { + previous_tick_ = timestamp; +} + +double SkiaVectorAnimation::TimerControl::GetNormalizedCurrentCycleProgress() + const { + return current_cycle_progress_.InMillisecondsF() * progress_per_millisecond_; +} + +double SkiaVectorAnimation::TimerControl::GetNormalizedStartOffset() const { + return start_offset_.InMillisecondsF() * progress_per_millisecond_; +} + +double SkiaVectorAnimation::TimerControl::GetNormalizedEndOffset() const { + return end_offset_.InMillisecondsF() * progress_per_millisecond_; +} + +SkiaVectorAnimation::SkiaVectorAnimation( + const scoped_refptr<base::RefCountedMemory>& data_stream) { + TRACE_EVENT0("ui", "SkiaVectorAnimation Parse"); + SkMemoryStream sk_stream(data_stream->front(), data_stream->size()); + animation_ = skottie::Animation::Make(&sk_stream); +} + +SkiaVectorAnimation::SkiaVectorAnimation(std::unique_ptr<SkMemoryStream> stream) + : animation_(skottie::Animation::Make(stream.get())) {} + +SkiaVectorAnimation::~SkiaVectorAnimation() {} + +void SkiaVectorAnimation::SetAnimationObserver( + SkiaVectorAnimationObserver* observer) { + DCHECK(!observer_ || !observer); + observer_ = observer; +} + +base::TimeDelta SkiaVectorAnimation::GetAnimationDuration() const { + return base::TimeDelta::FromMilliseconds( + std::floor(SkScalarToFloat(animation_->duration()) * 1000.f)); +} + +gfx::Size SkiaVectorAnimation::GetOriginalSize() const { +#if DCHECK_IS_ON() + // The size should have no fractional component. + gfx::SizeF float_size = gfx::SkSizeToSizeF(animation_->size()); + gfx::Size rounded_size = gfx::ToRoundedSize(float_size); + + float height_diff = std::abs(float_size.height() - rounded_size.height()); + float width_diff = std::abs(float_size.width() - rounded_size.width()); + + DCHECK_LE(height_diff, std::numeric_limits<float>::epsilon()); + DCHECK_LE(width_diff, std::numeric_limits<float>::epsilon()); +#endif + return gfx::ToRoundedSize(gfx::SkSizeToSizeF(animation_->size())); +} + +void SkiaVectorAnimation::Start(Style style) { + DCHECK_NE(state_, PlayState::kPaused); + DCHECK_NE(state_, PlayState::kPlaying); + StartSubsection(base::TimeDelta(), GetAnimationDuration(), style); +} + +void SkiaVectorAnimation::StartSubsection(base::TimeDelta start_offset, + base::TimeDelta duration, + Style style) { + DCHECK(state_ == PlayState::kStopped || state_ == PlayState::kEnded); + DCHECK_LE(start_offset + duration, GetAnimationDuration()); + + style_ = style; + + // Reset the |timer_control_| object for a new animation play. + timer_control_.reset(nullptr); + + // Schedule a play for the animation and store the necessary information + // needed to start playing. + state_ = PlayState::kSchedulePlay; + scheduled_start_offset_ = start_offset; + scheduled_duration_ = duration; +} + +void SkiaVectorAnimation::Pause() { + DCHECK(state_ == PlayState::kPlaying || state_ == PlayState::kSchedulePlay); + state_ = PlayState::kPaused; +} + +void SkiaVectorAnimation::ResumePlaying() { + DCHECK(state_ == PlayState::kPaused); + state_ = PlayState::kScheduleResume; +} + +void SkiaVectorAnimation::Stop() { + state_ = PlayState::kStopped; + timer_control_.reset(nullptr); +} + +float SkiaVectorAnimation::GetCurrentProgress() const { + switch (state_) { + case PlayState::kStopped: + return 0; + case PlayState::kEnded: + DCHECK(timer_control_); + return timer_control_->GetNormalizedEndOffset(); + case PlayState::kPaused: + if (timer_control_) { + return timer_control_->GetNormalizedCurrentCycleProgress(); + } else { + // It may be that the timer hasn't been initialized which may happen if + // the animation was paused while it was in |kScheculePlay| state. + return scheduled_start_offset_.InMillisecondsF() / + animation_->duration(); + } + case PlayState::kSchedulePlay: + case PlayState::kPlaying: + case PlayState::kScheduleResume: + // The timer control needs to be initialized before making this call. It + // may not have been initialized if OnAnimationStep has not been called + // yet + DCHECK(timer_control_); + return timer_control_->GetNormalizedCurrentCycleProgress(); + } +} + +void SkiaVectorAnimation::Paint(gfx::Canvas* canvas, + const base::TimeTicks& timestamp, + const gfx::Size& size) { + switch (state_) { + case PlayState::kStopped: + return; + case PlayState::kSchedulePlay: + InitTimer(timestamp); + state_ = PlayState::kPlaying; + if (observer_) + observer_->AnimationWillStartPlaying(this); + break; + case PlayState::kPlaying: + UpdateState(timestamp); + break; + case PlayState::kPaused: + break; + case PlayState::kScheduleResume: + state_ = PlayState::kPlaying; + if (timer_control_) { + timer_control_->Resume(timestamp); + } else { + // The animation may have been paused after a play was scheduled but + // before it started playing. + InitTimer(timestamp); + } + if (observer_) + observer_->AnimationResuming(this); + break; + case PlayState::kEnded: + break; + } + PaintFrame(canvas, GetCurrentProgress(), size); +} + +void SkiaVectorAnimation::PaintFrame(gfx::Canvas* canvas, + float t, + const gfx::Size& size) { + TRACE_EVENT0("ui", "SkiaVectorAnimation Paint"); + DCHECK_GE(t, 0.f); + DCHECK_LE(t, 1.f); + + animation_->seek(t); + float scale = canvas->UndoDeviceScaleFactor(); + + SkBitmap bitmap; + bitmap.allocN32Pixels(std::round(size.width() * scale), + std::round(size.height() * scale), false); + SkCanvas skcanvas(bitmap); + skcanvas.clear(SK_ColorTRANSPARENT); + SkRect dst = SkRect::MakeXYWH(0, 0, std::round(size.width() * scale), + std::round(size.height() * scale)); + animation_->render(&skcanvas, &dst); + + canvas->DrawImageInt(gfx::ImageSkia::CreateFrom1xBitmap(bitmap), 0, 0); +} + +void SkiaVectorAnimation::InitTimer(const base::TimeTicks& timestamp) { + DCHECK(!timer_control_); + timer_control_ = std::make_unique<TimerControl>( + scheduled_start_offset_, scheduled_duration_, GetAnimationDuration(), + timestamp, style_ == Style::kThrobbing); +} + +void SkiaVectorAnimation::UpdateState(const base::TimeTicks& timestamp) { + DCHECK(timer_control_); + int cycles = timer_control_->completed_cycles(); + timer_control_->Step(timestamp); + + if (cycles == timer_control_->completed_cycles()) + return; + + bool inform_observer = true; + switch (style_) { + case Style::kLoop: + break; + case Style::kThrobbing: + // For a throbbing animation, the animation cycle ends when the timer + // goes from 0 to 1 and then back to 0. So the number of timer cycles + // must be even at the end of one throbbing animation cycle. + if (timer_control_->completed_cycles() % 2 != 0) + inform_observer = false; + break; + case Style::kLinear: + state_ = PlayState::kEnded; + break; + } + + // Inform observer if the cycle has ended. + if (observer_ && inform_observer) { + observer_->AnimationCycleEnded(this); + } +} + +} // namespace gfx
diff --git a/ui/gfx/skia_vector_animation.h b/ui/gfx/skia_vector_animation.h new file mode 100644 index 0000000..f0c133f --- /dev/null +++ b/ui/gfx/skia_vector_animation.h
@@ -0,0 +1,239 @@ +// 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 UI_GFX_SKIA_VECTOR_ANIMATION_H_ +#define UI_GFX_SKIA_VECTOR_ANIMATION_H_ + +#include <memory> + +#include "base/macros.h" +#include "base/memory/ref_counted_memory.h" +#include "base/memory/scoped_refptr.h" +#include "base/time/time.h" +#include "third_party/skia/include/core/SkStream.h" +#include "third_party/skia/modules/skottie/include/Skottie.h" +#include "ui/gfx/geometry/size.h" +#include "ui/gfx/gfx_export.h" + +namespace gfx { +class Canvas; +class SkiaVectorAnimationTest; +class SkiaVectorAnimationObserver; + +// This class is a wrapper over the Skia object for lottie vector graphic +// animations. It has its own timeline manager for the animation controls. The +// framerate of the animation and the animation ticks are controlled externally +// and hence the consumer must manage the timer and call paint at the desired +// frame per second. +// This helps keep multiple animations be synchronized by having a common +// external tick clock. +// In general you want to use the view framework integrated class that we have +// for SkiaVectorAnimation instead of this class. +// +// Usage example: +// 1. Rendering a single frame on the canvas: +// SkiaVectorAnimation animation_ = SkiaVectorAnimation(data); +// animation_.Paint(canvas, t); +// +// 2. Playing the animation and rendering each frame: +// void SampleClient::Init() { +// SkiaVectorAnimation animation_ = SkiaVectorAnimation(data); +// animation_.Start(SkiaVectorAnimation::Style::LINEAR); +// } +// +// // overrides cc::CompositorAnimationObserver +// void SampleClient::OnAnimationStep(TimeTicks* timestamp) { +// timestamp_ = timestamp; +// SchedulePaint(); +// } +// +// void SampleClient::OnPaint(Canvas* canvas) { +// animation_.Paint(canvas, timestamp_); +// } +// +// 2. If you only want to play a subsection of the animation: +// void SampleClient::Init() { +// // This will seek to the 1st second of the animation and from there +// // play it for 5 seconds. +// SkiaVectorAnimation animation_ = SkiaVectorAnimation(data); +// animation_.Start(TimeDelta::FromSeconds(1), +// TimeDelta::FromSeconds(5)); +// } +// +// // overrides cc::CompositorAnimationObserver +// void SampleClient::OnAnimationStep(TimeTicks*) { +// timestamp_ = timestamp; +// SchedulePaint(); +// } +// +// void SampleClient::OnPaint(Canvas* canvas) { +// animation_.Paint(canvas, timestamp_, gfx::Size(10, 10)); +// } +// +class GFX_EXPORT SkiaVectorAnimation { + public: + enum class Style { + kLinear = 0, // The animation plays from one time instant to another. + kThrobbing, // The animation plays from one time instant to another and + // then back. The animation plays in loop until stopped. + kLoop // Same as LINEAR, except the animation repeats after it ends. + }; + + explicit SkiaVectorAnimation( + const scoped_refptr<base::RefCountedMemory>& data_stream); + explicit SkiaVectorAnimation(std::unique_ptr<SkMemoryStream> stream); + ~SkiaVectorAnimation(); + + void SetAnimationObserver(SkiaVectorAnimationObserver* Observer); + + // Animation properties ------------------------------------------------------ + // Returns the total duration of the animation as reported by |animation_|. + base::TimeDelta GetAnimationDuration() const; + + // Returns the size of the vector graphic as reported by |animation_|. This is + // constant for a given |animation_|. + gfx::Size GetOriginalSize() const; + + // Animation controls -------------------------------------------------------- + // This is an asynchronous call that would start playing the animation on the + // next animation step. On a successful start the |observer_| would be + // notified. Use this if you want to play the entire animation. + void Start(Style style = Style::kLoop); + + // This is an asynchronous call that would start playing the animation on the + // next animation step. On a successful start the |observer_| would be + // notified. + // The animation will be scheduled to play from the |start_offset| to + // |start_offset| + |duration|. The values will be clamped so as to not go out + // of bounds. + void StartSubsection(base::TimeDelta start_offset, + base::TimeDelta duration, + Style style = Style::kLoop); + + // Pauses the animation. + void Pause(); + + // This is an asynchronous call that would resume playing a paused animation + // on the next animation step. + void ResumePlaying(); + + // Resets the animation to the first frame and stops. + void Stop(); + + // Returns the current normalized [0..1] value at which the animation frame + // is. + // 0 -> first frame and 1 -> last frame. + float GetCurrentProgress() const; + + // Paint operations ---------------------------------------------------------- + // Paints the frame of the animation for the given |timestamp| at the given + // |size|. + void Paint(gfx::Canvas* canvas, + const base::TimeTicks& timestamp, + const gfx::Size& size); + + // Paints the frame of the animation for the normalized time instance |t|. Use + // this for special cases when you want to manually manage which frame to + // paint. + void PaintFrame(gfx::Canvas* canvas, float t, const gfx::Size& size); + + private: + friend class SkiaVectorAnimationTest; + + enum class PlayState { + kStopped = 0, // Animation is stopped. + kSchedulePlay, // Animation will start playing on the next animatin step. + kPlaying, // Animation is playing. + kPaused, // Animation is paused. + kScheduleResume, // Animation will resume playing on the next animation + // step + kEnded // Animation has ended. + }; + + // Class to manage the timeline when playing the animation. Manages the + // normalized progress [0..1] between the given start and end offset. If the + // reverse flag is set, the progress runs in reverse. + class GFX_EXPORT TimerControl { + public: + TimerControl(const base::TimeDelta& offset, + const base::TimeDelta& cycle_duration, + const base::TimeDelta& total_duration, + const base::TimeTicks& start_timestamp, + bool should_reverse); + ~TimerControl() = default; + + // Update timeline progress based on the new timetick |timestamp|. + void Step(const base::TimeTicks& timestamp); + + // Resumes the timer. + void Resume(const base::TimeTicks& timestamp); + + double GetNormalizedCurrentCycleProgress() const; + double GetNormalizedStartOffset() const; + double GetNormalizedEndOffset() const; + int completed_cycles() const { return completed_cycles_; } + + private: + friend class SkiaVectorAnimationTest; + + // Time duration from 0 which marks the beginning of a cycle. + const base::TimeDelta start_offset_; + + // Time duration from 0 which marks the end of a cycle. + const base::TimeDelta end_offset_; + + // Time duration for one cycle. This is essentially a cache of the + // difference between |end_offset_| - |start_offset_|. + const base::TimeDelta cycle_duration_; + + // Normalized animation progress delta per millisecond, that is, the + // normalized progress in per millisecond of time duration. + const double progress_per_millisecond_; + + // The timetick at which |progress_| was updated last. + base::TimeTicks previous_tick_; + + // The progress of the timer. This is a monotonically increasing value. + base::TimeDelta progress_; + + // This is the progress of the timer in the current cycle. + base::TimeDelta current_cycle_progress_; + + // If true, the progress will go into reverse after each cycle. This is used + // for throbbing animations. + bool should_reverse_ = false; + + // The number of times each |cycle_duration_| is covered by the timer. + int completed_cycles_ = 0; + + DISALLOW_COPY_AND_ASSIGN(TimerControl); + }; + + void InitTimer(const base::TimeTicks& timestamp); + void UpdateState(const base::TimeTicks& timestamp); + + // Manages the timeline for the current playing animation. + std::unique_ptr<TimerControl> timer_control_; + + // The style of animation to play. + Style style_ = Style::kLoop; + + // The current state of animation. + PlayState state_ = PlayState::kStopped; + + // The below values of scheduled_* are set when we have scheduled a play. + // These will be used to initialize |timer_control_|. + base::TimeDelta scheduled_start_offset_; + base::TimeDelta scheduled_duration_; + + SkiaVectorAnimationObserver* observer_ = nullptr; + + sk_sp<skottie::Animation> animation_; + + DISALLOW_COPY_AND_ASSIGN(SkiaVectorAnimation); +}; + +} // namespace gfx + +#endif // UI_GFX_SKIA_VECTOR_ANIMATION_H_
diff --git a/ui/gfx/skia_vector_animation_observer.h b/ui/gfx/skia_vector_animation_observer.h new file mode 100644 index 0000000..1e6e479a --- /dev/null +++ b/ui/gfx/skia_vector_animation_observer.h
@@ -0,0 +1,33 @@ +// 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 UI_GFX_SKIA_VECTOR_ANIMATION_OBSERVER_H_ +#define UI_GFX_SKIA_VECTOR_ANIMATION_OBSERVER_H_ + +#include "ui/gfx/gfx_export.h" + +namespace gfx { +class SkiaVectorAnimation; + +class GFX_EXPORT SkiaVectorAnimationObserver { + public: + // Called when the animation started playing. + virtual void AnimationWillStartPlaying(const SkiaVectorAnimation* animation) { + } + + // Called when one animation cycle has completed. This happens when a linear + // animation has reached its end, or a loop/throbbing animation has finished + // a cycle. + virtual void AnimationCycleEnded(const SkiaVectorAnimation* animation) {} + + // Called when the animation has successfully resumed. + virtual void AnimationResuming(const SkiaVectorAnimation* animation) {} + + protected: + virtual ~SkiaVectorAnimationObserver() = default; +}; + +} // namespace gfx + +#endif // UI_GFX_SKIA_VECTOR_ANIMATION_OBSERVER_H_
diff --git a/ui/gfx/skia_vector_animation_unittest.cc b/ui/gfx/skia_vector_animation_unittest.cc new file mode 100644 index 0000000..f9d9737 --- /dev/null +++ b/ui/gfx/skia_vector_animation_unittest.cc
@@ -0,0 +1,852 @@ +// 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/gfx/skia_vector_animation.h" + +#include <string> + +#include "base/macros.h" +#include "base/memory/ref_counted_memory.h" +#include "base/memory/scoped_refptr.h" +#include "base/test/simple_test_tick_clock.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/skia/include/core/SkBitmap.h" +#include "third_party/skia/include/core/SkStream.h" +#include "ui/gfx/canvas.h" +#include "ui/gfx/skia_vector_animation_observer.h" + +namespace gfx { +namespace { + +// A skottie animation with solid green color for the first 2.5 seconds and then +// a solid blue color for the next 2.5 seconds. +constexpr char kData[] = + "{" + " \"v\" : \"4.12.0\"," + " \"fr\": 30," + " \"w\" : 400," + " \"h\" : 200," + " \"ip\": 0," + " \"op\": 150," + " \"assets\": []," + + " \"layers\": [" + " {" + " \"ty\": 1," + " \"sw\": 400," + " \"sh\": 200," + " \"sc\": \"#00ff00\"," + " \"ip\": 0," + " \"op\": 75" + " }," + " {" + " \"ty\": 1," + " \"sw\": 400," + " \"sh\": 200," + " \"sc\": \"#0000ff\"," + " \"ip\": 76," + " \"op\": 150" + " }" + " ]" + "}"; +constexpr float kAnimationWidth = 400.f; +constexpr float kAnimationHeight = 200.f; +constexpr float kAnimationDuration = 5.f; + +class TestAnimationObserver : public SkiaVectorAnimationObserver { + public: + TestAnimationObserver() = default; + + void AnimationWillStartPlaying( + const SkiaVectorAnimation* animation) override { + animation_will_start_playing_ = true; + } + + void AnimationCycleEnded(const SkiaVectorAnimation* animation) override { + animation_cycle_ended_ = true; + } + + void AnimationResuming(const SkiaVectorAnimation* animation) override { + animation_resuming_ = true; + } + + void Reset() { + animation_cycle_ended_ = false; + animation_will_start_playing_ = false; + animation_resuming_ = false; + } + + bool animation_cycle_ended() const { return animation_cycle_ended_; } + bool animation_will_start_playing() const { + return animation_will_start_playing_; + } + bool animation_resuming() const { return animation_resuming_; } + + private: + bool animation_cycle_ended_ = false; + bool animation_will_start_playing_ = false; + bool animation_resuming_ = false; + + DISALLOW_COPY_AND_ASSIGN(TestAnimationObserver); +}; + +} // namespace + +class SkiaVectorAnimationTest : public testing::Test { + public: + SkiaVectorAnimationTest() = default; + ~SkiaVectorAnimationTest() override {} + + void SetUp() override { + canvas_.reset(new gfx::Canvas(gfx::Size(kAnimationWidth, kAnimationHeight), + 1.f, false)); + } + + void TearDown() override { animation_.reset(nullptr); } + + Canvas* canvas() { return canvas_.get(); } + + SkiaVectorAnimation::Style GetStyle() const { return animation_->style_; } + + SkiaVectorAnimation::PlayState GetState() const { return animation_->state_; } + + bool IsStopped() const { + return GetState() == SkiaVectorAnimation::PlayState::kStopped; + } + + bool IsScheduledToPlay() const { + return GetState() == SkiaVectorAnimation::PlayState::kSchedulePlay; + } + + bool IsPlaying() const { + return GetState() == SkiaVectorAnimation::PlayState::kPlaying; + } + + bool IsScheduledToResume() const { + return GetState() == SkiaVectorAnimation::PlayState::kScheduleResume; + } + + bool HasAnimationEnded() const { + return GetState() == SkiaVectorAnimation::PlayState::kEnded; + } + + bool IsPaused() const { + return GetState() == SkiaVectorAnimation::PlayState::kPaused; + } + + const SkiaVectorAnimation::TimerControl* GetTimerControl() const { + return animation_->timer_control_.get(); + } + + const base::TickClock* test_clock() const { return &test_clock_; } + + void AdvanceClock(int64_t ms) { + test_clock_.Advance(base::TimeDelta::FromMilliseconds(ms)); + } + + base::TimeDelta TimeDeltaSince(const base::TimeTicks& ticks) const { + return test_clock_.NowTicks() - ticks; + } + + const base::TimeTicks NowTicks() const { return test_clock_.NowTicks(); } + + double GetTimerStartOffset() const { + return animation_->timer_control_->GetNormalizedStartOffset(); + } + + double GetTimerEndOffset() const { + return animation_->timer_control_->GetNormalizedEndOffset(); + } + + const base::TimeTicks& GetTimerPreviousTick() const { + return animation_->timer_control_->previous_tick_; + } + + double GetTimerProgressPerMs() const { + return animation_->timer_control_->progress_per_millisecond_; + } + + int GetTimerCycles() const { + return animation_->timer_control_->completed_cycles(); + } + + void IsAllSameColor(SkColor color, const SkBitmap& bitmap) const { + if (bitmap.colorType() == kBGRA_8888_SkColorType) { + const SkColor* pixels = reinterpret_cast<SkColor*>(bitmap.getPixels()); + const int num_pixels = bitmap.width() * bitmap.height(); + for (int i = 0; i < num_pixels; i++) + EXPECT_EQ(pixels[i], color); + } else { + for (int x = 0; x < bitmap.width(); x++) + for (int y = 0; y < bitmap.height(); y++) + EXPECT_EQ(bitmap.getColor(x, y), color); + } + } + + protected: + std::unique_ptr<SkiaVectorAnimation> animation_; + + private: + std::unique_ptr<gfx::Canvas> canvas_; + base::SimpleTestTickClock test_clock_; + + DISALLOW_COPY_AND_ASSIGN(SkiaVectorAnimationTest); +}; + +TEST_F(SkiaVectorAnimationTest, InitializationAndLoadingData) { + auto bytes = base::MakeRefCounted<base::RefCountedBytes>( + std::vector<unsigned char>(kData, kData + std::strlen(kData))); + animation_ = std::make_unique<SkiaVectorAnimation>(bytes.get()); + EXPECT_FLOAT_EQ(animation_->GetOriginalSize().width(), kAnimationWidth); + EXPECT_FLOAT_EQ(animation_->GetOriginalSize().height(), kAnimationHeight); + EXPECT_FLOAT_EQ(animation_->GetAnimationDuration().InSecondsF(), + kAnimationDuration); + EXPECT_TRUE(IsStopped()); + + animation_ = std::make_unique<SkiaVectorAnimation>( + std::make_unique<SkMemoryStream>(kData, std::strlen(kData))); + EXPECT_FLOAT_EQ(animation_->GetOriginalSize().width(), kAnimationWidth); + EXPECT_FLOAT_EQ(animation_->GetOriginalSize().height(), kAnimationHeight); + EXPECT_FLOAT_EQ(animation_->GetAnimationDuration().InSecondsF(), + kAnimationDuration); + EXPECT_TRUE(IsStopped()); +} + +TEST_F(SkiaVectorAnimationTest, PlayLinearAnimation) { + TestAnimationObserver observer; + animation_ = std::make_unique<SkiaVectorAnimation>( + std::make_unique<SkMemoryStream>(kData, std::strlen(kData))); + animation_->SetAnimationObserver(&observer); + + // Advance clock by 300 milliseconds. + AdvanceClock(300); + + EXPECT_TRUE(IsStopped()); + animation_->Start(SkiaVectorAnimation::Style::kLinear); + EXPECT_TRUE(IsScheduledToPlay()); + EXPECT_FALSE(observer.animation_will_start_playing()); + + animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize()); + EXPECT_FALSE(IsScheduledToPlay()); + EXPECT_TRUE(IsPlaying()); + EXPECT_TRUE(observer.animation_will_start_playing()); + + EXPECT_FLOAT_EQ(animation_->GetCurrentProgress(), 0); + EXPECT_FLOAT_EQ(GetTimerStartOffset(), 0); + EXPECT_FLOAT_EQ(GetTimerEndOffset(), 1.f); + + EXPECT_FLOAT_EQ(GetTimerProgressPerMs(), 1.f / 5000.f); + + AdvanceClock(50); + EXPECT_EQ(TimeDeltaSince(GetTimerPreviousTick()).InMilliseconds(), 50); + + animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize()); + EXPECT_FLOAT_EQ(animation_->GetCurrentProgress(), 50.f / 5000.f); + EXPECT_EQ(TimeDeltaSince(GetTimerPreviousTick()).InMilliseconds(), 0); + + // Advance the clock to the end of the animation. + AdvanceClock(4951); + EXPECT_EQ(TimeDeltaSince(GetTimerPreviousTick()).InMilliseconds(), 4951); + animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize()); + EXPECT_FLOAT_EQ(animation_->GetCurrentProgress(), 1.f); + EXPECT_TRUE(HasAnimationEnded()); + EXPECT_TRUE(observer.animation_cycle_ended()); +} + +TEST_F(SkiaVectorAnimationTest, StopLinearAnimation) { + TestAnimationObserver observer; + animation_ = std::make_unique<SkiaVectorAnimation>( + std::make_unique<SkMemoryStream>(kData, std::strlen(kData))); + animation_->SetAnimationObserver(&observer); + + // Advance clock by 300 milliseconds. + AdvanceClock(300); + + animation_->Start(SkiaVectorAnimation::Style::kLinear); + + animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize()); + EXPECT_TRUE(IsPlaying()); + EXPECT_FLOAT_EQ(animation_->GetCurrentProgress(), 0); + + AdvanceClock(50); + animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize()); + EXPECT_FLOAT_EQ(animation_->GetCurrentProgress(), 50.f / 5000.f); + + animation_->Stop(); + EXPECT_FLOAT_EQ(animation_->GetCurrentProgress(), 0.f); + EXPECT_TRUE(IsStopped()); +} + +TEST_F(SkiaVectorAnimationTest, PlaySubsectionOfLinearAnimation) { + const int start_time_ms = 400; + const int duration_ms = 1000; + const float total_duration_ms = kAnimationDuration * 1000.f; + + TestAnimationObserver observer; + + animation_ = std::make_unique<SkiaVectorAnimation>( + std::make_unique<SkMemoryStream>(kData, std::strlen(kData))); + animation_->SetAnimationObserver(&observer); + + // Advance clock by 300 milliseconds. + AdvanceClock(300); + + EXPECT_FALSE(observer.animation_cycle_ended()); + animation_->StartSubsection(base::TimeDelta::FromMilliseconds(start_time_ms), + base::TimeDelta::FromMilliseconds(duration_ms), + SkiaVectorAnimation::Style::kLinear); + + EXPECT_TRUE(IsScheduledToPlay()); + EXPECT_FALSE(observer.animation_will_start_playing()); + + animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize()); + + EXPECT_FALSE(IsScheduledToPlay()); + EXPECT_TRUE(IsPlaying()); + EXPECT_TRUE(observer.animation_will_start_playing()); + + EXPECT_FLOAT_EQ(animation_->GetCurrentProgress(), GetTimerStartOffset()); + EXPECT_FLOAT_EQ(GetTimerEndOffset(), + (start_time_ms + duration_ms) / total_duration_ms); + + EXPECT_FLOAT_EQ(GetTimerProgressPerMs(), 1.f / total_duration_ms); + + AdvanceClock(100); + EXPECT_EQ(TimeDeltaSince(GetTimerPreviousTick()).InMilliseconds(), 100); + + animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize()); + EXPECT_EQ(TimeDeltaSince(GetTimerPreviousTick()).InMilliseconds(), 0); + EXPECT_FLOAT_EQ(animation_->GetCurrentProgress(), + (100.f + start_time_ms) / total_duration_ms); + EXPECT_FALSE(observer.animation_cycle_ended()); + + // Advance clock another 300 ms. + AdvanceClock(300); + EXPECT_EQ(TimeDeltaSince(GetTimerPreviousTick()).InMilliseconds(), 300); + + animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize()); + EXPECT_EQ(TimeDeltaSince(GetTimerPreviousTick()).InMilliseconds(), 0); + EXPECT_FLOAT_EQ(animation_->GetCurrentProgress(), + (100.f + 300.f + start_time_ms) / total_duration_ms); + EXPECT_FALSE(observer.animation_cycle_ended()); + + // Reach the end of animation. + AdvanceClock(601); + EXPECT_EQ(TimeDeltaSince(GetTimerPreviousTick()).InMilliseconds(), 601); + animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize()); + EXPECT_FLOAT_EQ(animation_->GetCurrentProgress(), GetTimerEndOffset()); + EXPECT_TRUE(observer.animation_cycle_ended()); + EXPECT_TRUE(HasAnimationEnded()); +} + +TEST_F(SkiaVectorAnimationTest, PausingLinearAnimation) { + const int start_time_ms = 400; + const int duration_ms = 1000; + const float total_duration_ms = kAnimationDuration * 1000.f; + animation_ = std::make_unique<SkiaVectorAnimation>( + std::make_unique<SkMemoryStream>(kData, std::strlen(kData))); + TestAnimationObserver observer; + animation_->SetAnimationObserver(&observer); + + AdvanceClock(200); + + animation_->StartSubsection(base::TimeDelta::FromMilliseconds(start_time_ms), + base::TimeDelta::FromMilliseconds(duration_ms), + SkiaVectorAnimation::Style::kLinear); + animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize()); + + AdvanceClock(100); + animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize()); + + EXPECT_FLOAT_EQ(animation_->GetCurrentProgress(), 500.f / total_duration_ms); + + AdvanceClock(100); + animation_->Pause(); + EXPECT_TRUE(IsPaused()); + + // Advancing clock and stepping animation should have no effect when animation + // is paused. + AdvanceClock(5000); + animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize()); + EXPECT_FLOAT_EQ(animation_->GetCurrentProgress(), 500.f / total_duration_ms); + + // Resume playing the animation. + animation_->ResumePlaying(); + EXPECT_TRUE(IsScheduledToResume()); + + // There should be no progress, since we haven't advanced the clock yet. + animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize()); + EXPECT_TRUE(IsPlaying()); + EXPECT_FLOAT_EQ(animation_->GetCurrentProgress(), 500.f / total_duration_ms); + + AdvanceClock(100); + animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize()); + EXPECT_FLOAT_EQ(animation_->GetCurrentProgress(), 600.f / total_duration_ms); + + AdvanceClock(801); + animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize()); +} + +TEST_F(SkiaVectorAnimationTest, PlayLoopAnimation) { + TestAnimationObserver observer; + animation_ = std::make_unique<SkiaVectorAnimation>( + std::make_unique<SkMemoryStream>(kData, std::strlen(kData))); + animation_->SetAnimationObserver(&observer); + + // Advance clock by 300 milliseconds. + AdvanceClock(300); + + EXPECT_TRUE(IsStopped()); + animation_->Start(SkiaVectorAnimation::Style::kLoop); + EXPECT_TRUE(IsScheduledToPlay()); + EXPECT_FALSE(observer.animation_will_start_playing()); + + animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize()); + + EXPECT_FALSE(IsScheduledToPlay()); + EXPECT_TRUE(IsPlaying()); + EXPECT_TRUE(observer.animation_will_start_playing()); + + EXPECT_FLOAT_EQ(animation_->GetCurrentProgress(), 0); + EXPECT_FLOAT_EQ(GetTimerStartOffset(), 0); + EXPECT_FLOAT_EQ(GetTimerEndOffset(), 1.f); + + EXPECT_FLOAT_EQ(GetTimerProgressPerMs(), 1.f / 5000.f); + + AdvanceClock(50); + EXPECT_EQ(TimeDeltaSince(GetTimerPreviousTick()).InMilliseconds(), 50); + + animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize()); + EXPECT_FLOAT_EQ(animation_->GetCurrentProgress(), 50.f / 5000.f); + EXPECT_EQ(TimeDeltaSince(GetTimerPreviousTick()).InMilliseconds(), 0); + + // Advance the clock to the end of the animation. + AdvanceClock(4950); + EXPECT_EQ(TimeDeltaSince(GetTimerPreviousTick()).InMilliseconds(), 4950); + animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize()); + EXPECT_EQ(GetTimerCycles(), 1); + EXPECT_TRUE(std::abs(animation_->GetCurrentProgress() - 0.f) < 0.0001f); + EXPECT_TRUE(observer.animation_cycle_ended()); + EXPECT_TRUE(IsPlaying()); +} + +TEST_F(SkiaVectorAnimationTest, PlaySubsectionOfLoopAnimation) { + const int start_time_ms = 400; + const int duration_ms = 1000; + const float total_duration_ms = kAnimationDuration * 1000.f; + + animation_ = std::make_unique<SkiaVectorAnimation>( + std::make_unique<SkMemoryStream>(kData, std::strlen(kData))); + + TestAnimationObserver observer; + animation_->SetAnimationObserver(&observer); + + // Advance clock by 300 milliseconds. + AdvanceClock(300); + EXPECT_TRUE(IsStopped()); + animation_->StartSubsection(base::TimeDelta::FromMilliseconds(start_time_ms), + base::TimeDelta::FromMilliseconds(duration_ms), + SkiaVectorAnimation::Style::kLoop); + EXPECT_TRUE(IsScheduledToPlay()); + EXPECT_FALSE(observer.animation_will_start_playing()); + + animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize()); + + EXPECT_FALSE(IsScheduledToPlay()); + EXPECT_TRUE(IsPlaying()); + EXPECT_TRUE(observer.animation_will_start_playing()); + + EXPECT_FALSE(observer.animation_cycle_ended()); + EXPECT_FLOAT_EQ(GetTimerStartOffset(), 400.f / total_duration_ms); + EXPECT_FLOAT_EQ(animation_->GetCurrentProgress(), GetTimerStartOffset()); + EXPECT_FLOAT_EQ(GetTimerEndOffset(), + (start_time_ms + duration_ms) / total_duration_ms); + + EXPECT_FLOAT_EQ(GetTimerProgressPerMs(), 1.f / total_duration_ms); + + AdvanceClock(100); + EXPECT_EQ(TimeDeltaSince(GetTimerPreviousTick()).InMilliseconds(), 100); + EXPECT_FALSE(observer.animation_cycle_ended()); + + animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize()); + EXPECT_EQ(TimeDeltaSince(GetTimerPreviousTick()).InMilliseconds(), 0); + EXPECT_FLOAT_EQ(animation_->GetCurrentProgress(), + (100.f + start_time_ms) / total_duration_ms); + + // Advance clock another 300 ms. + AdvanceClock(300); + EXPECT_EQ(TimeDeltaSince(GetTimerPreviousTick()).InMilliseconds(), 300); + + animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize()); + EXPECT_EQ(TimeDeltaSince(GetTimerPreviousTick()).InMilliseconds(), 0); + EXPECT_FLOAT_EQ(animation_->GetCurrentProgress(), + (100.f + 300.f + start_time_ms) / total_duration_ms); + EXPECT_FALSE(observer.animation_cycle_ended()); + + // Reach the end of animation. + AdvanceClock(600); + EXPECT_EQ(TimeDeltaSince(GetTimerPreviousTick()).InMilliseconds(), 600); + + animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize()); + EXPECT_TRUE(observer.animation_cycle_ended()); + EXPECT_TRUE(IsPlaying()); + EXPECT_FLOAT_EQ(animation_->GetCurrentProgress(), GetTimerStartOffset()); +} + +TEST_F(SkiaVectorAnimationTest, PausingLoopAnimation) { + const int start_time_ms = 400; + const int duration_ms = 1000; + const float total_duration_ms = kAnimationDuration * 1000.f; + animation_ = std::make_unique<SkiaVectorAnimation>( + std::make_unique<SkMemoryStream>(kData, std::strlen(kData))); + + TestAnimationObserver observer; + animation_->SetAnimationObserver(&observer); + + AdvanceClock(200); + + animation_->StartSubsection(base::TimeDelta::FromMilliseconds(start_time_ms), + base::TimeDelta::FromMilliseconds(duration_ms), + SkiaVectorAnimation::Style::kLoop); + animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize()); + + EXPECT_FLOAT_EQ(animation_->GetCurrentProgress(), 400.f / total_duration_ms); + + AdvanceClock(100); + animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize()); + + EXPECT_FLOAT_EQ(animation_->GetCurrentProgress(), 500.f / total_duration_ms); + + AdvanceClock(100); + animation_->Pause(); + EXPECT_TRUE(IsPaused()); + + // Advancing clock and stepping animation should have no effect when animation + // is paused. + AdvanceClock(5000); + animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize()); + EXPECT_FLOAT_EQ(animation_->GetCurrentProgress(), 500.f / total_duration_ms); + + // Resume playing the animation. + animation_->ResumePlaying(); + EXPECT_TRUE(IsScheduledToResume()); + + // There should be no progress, since we haven't advanced the clock yet. + animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize()); + EXPECT_TRUE(IsPlaying()); + EXPECT_FLOAT_EQ(animation_->GetCurrentProgress(), 500.f / total_duration_ms); + + AdvanceClock(100); + animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize()); + EXPECT_FLOAT_EQ(animation_->GetCurrentProgress(), 600.f / total_duration_ms); + EXPECT_FALSE(observer.animation_cycle_ended()); + + AdvanceClock(800); + animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize()); + EXPECT_FLOAT_EQ(animation_->GetCurrentProgress(), GetTimerStartOffset()); + EXPECT_TRUE(IsPlaying()); + EXPECT_TRUE(observer.animation_cycle_ended()); +} + +TEST_F(SkiaVectorAnimationTest, PlayThrobbingAnimation) { + animation_ = std::make_unique<SkiaVectorAnimation>( + std::make_unique<SkMemoryStream>(kData, std::strlen(kData))); + + TestAnimationObserver observer; + animation_->SetAnimationObserver(&observer); + // Advance clock by 300 milliseconds. + AdvanceClock(300); + + animation_->Start(SkiaVectorAnimation::Style::kThrobbing); + EXPECT_TRUE(IsScheduledToPlay()); + EXPECT_FALSE(observer.animation_will_start_playing()); + + animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize()); + + EXPECT_FALSE(IsScheduledToPlay()); + EXPECT_TRUE(IsPlaying()); + EXPECT_TRUE(observer.animation_will_start_playing()); + + EXPECT_FLOAT_EQ(animation_->GetCurrentProgress(), 0); + EXPECT_FLOAT_EQ(GetTimerStartOffset(), 0); + EXPECT_FLOAT_EQ(GetTimerEndOffset(), 1.f); + + EXPECT_FLOAT_EQ(GetTimerProgressPerMs(), 1.f / 5000.f); + + AdvanceClock(50); + EXPECT_EQ(TimeDeltaSince(GetTimerPreviousTick()).InMilliseconds(), 50); + + animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize()); + EXPECT_FLOAT_EQ(animation_->GetCurrentProgress(), 50.f / 5000.f); + EXPECT_EQ(TimeDeltaSince(GetTimerPreviousTick()).InMilliseconds(), 0); + + // Advance the clock to the end of the animation. + AdvanceClock(4950); + EXPECT_EQ(TimeDeltaSince(GetTimerPreviousTick()).InMilliseconds(), 4950); + animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize()); + EXPECT_FLOAT_EQ(animation_->GetCurrentProgress(), 1.f); + EXPECT_TRUE(IsPlaying()); + EXPECT_FALSE(observer.animation_cycle_ended()); + + AdvanceClock(2500); + animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize()); + EXPECT_FLOAT_EQ(animation_->GetCurrentProgress(), 0.5f); + EXPECT_TRUE(IsPlaying()); + EXPECT_FALSE(observer.animation_cycle_ended()); + + AdvanceClock(2500); + animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize()); + EXPECT_FLOAT_EQ(animation_->GetCurrentProgress(), 0); + EXPECT_TRUE(IsPlaying()); + EXPECT_TRUE(observer.animation_cycle_ended()); +} + +TEST_F(SkiaVectorAnimationTest, PlaySubsectionOfThrobbingAnimation) { + const int start_time_ms = 400; + const int duration_ms = 1000; + const float total_duration_ms = kAnimationDuration * 1000.f; + + animation_ = std::make_unique<SkiaVectorAnimation>( + std::make_unique<SkMemoryStream>(kData, std::strlen(kData))); + + TestAnimationObserver observer; + animation_->SetAnimationObserver(&observer); + + // Advance clock by 300 milliseconds. + AdvanceClock(300); + + animation_->StartSubsection(base::TimeDelta::FromMilliseconds(start_time_ms), + base::TimeDelta::FromMilliseconds(duration_ms), + SkiaVectorAnimation::Style::kThrobbing); + EXPECT_TRUE(IsScheduledToPlay()); + EXPECT_FALSE(observer.animation_will_start_playing()); + + animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize()); + + EXPECT_FALSE(IsScheduledToPlay()); + EXPECT_TRUE(IsPlaying()); + EXPECT_TRUE(observer.animation_will_start_playing()); + + EXPECT_FLOAT_EQ(GetTimerStartOffset(), 400.f / total_duration_ms); + EXPECT_FLOAT_EQ(animation_->GetCurrentProgress(), GetTimerStartOffset()); + EXPECT_FLOAT_EQ(GetTimerEndOffset(), + (start_time_ms + duration_ms) / total_duration_ms); + + EXPECT_FLOAT_EQ(GetTimerProgressPerMs(), 1.f / total_duration_ms); + + AdvanceClock(100); + EXPECT_EQ(TimeDeltaSince(GetTimerPreviousTick()).InMilliseconds(), 100); + + animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize()); + EXPECT_FALSE(observer.animation_cycle_ended()); + EXPECT_EQ(TimeDeltaSince(GetTimerPreviousTick()).InMilliseconds(), 0); + EXPECT_FLOAT_EQ(animation_->GetCurrentProgress(), + (100.f + start_time_ms) / total_duration_ms); + + // Advance clock another 300 ms. + AdvanceClock(300); + EXPECT_EQ(TimeDeltaSince(GetTimerPreviousTick()).InMilliseconds(), 300); + + animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize()); + EXPECT_FALSE(observer.animation_cycle_ended()); + EXPECT_EQ(TimeDeltaSince(GetTimerPreviousTick()).InMilliseconds(), 0); + EXPECT_FLOAT_EQ(animation_->GetCurrentProgress(), + (100.f + 300.f + start_time_ms) / total_duration_ms); + + // Reach the end of animation. + AdvanceClock(600); + EXPECT_EQ(TimeDeltaSince(GetTimerPreviousTick()).InMilliseconds(), 600); + + animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize()); + EXPECT_TRUE(IsPlaying()); + EXPECT_FLOAT_EQ(animation_->GetCurrentProgress(), GetTimerEndOffset()); + EXPECT_FALSE(observer.animation_cycle_ended()); + + AdvanceClock(500); + animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize()); + EXPECT_FLOAT_EQ(animation_->GetCurrentProgress(), 900.f / total_duration_ms); + EXPECT_TRUE(IsPlaying()); + EXPECT_FALSE(observer.animation_cycle_ended()); + + AdvanceClock(500); + animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize()); + EXPECT_FLOAT_EQ(animation_->GetCurrentProgress(), GetTimerStartOffset()); + EXPECT_TRUE(IsPlaying()); + EXPECT_TRUE(observer.animation_cycle_ended()); + + observer.Reset(); + + AdvanceClock(100); + animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize()); + EXPECT_FLOAT_EQ(animation_->GetCurrentProgress(), + (start_time_ms + 100.f) / total_duration_ms); + EXPECT_TRUE(IsPlaying()); +} + +TEST_F(SkiaVectorAnimationTest, PausingThrobbingAnimation) { + const int start_time_ms = 400; + const int duration_ms = 1000; + const float total_duration_ms = kAnimationDuration * 1000.f; + animation_ = std::make_unique<SkiaVectorAnimation>( + std::make_unique<SkMemoryStream>(kData, std::strlen(kData))); + + AdvanceClock(200); + + animation_->StartSubsection(base::TimeDelta::FromMilliseconds(start_time_ms), + base::TimeDelta::FromMilliseconds(duration_ms), + SkiaVectorAnimation::Style::kThrobbing); + animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize()); + + EXPECT_TRUE(IsPlaying()); + + EXPECT_FLOAT_EQ(animation_->GetCurrentProgress(), + start_time_ms / total_duration_ms); + + AdvanceClock(100); + animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize()); + + EXPECT_FLOAT_EQ(animation_->GetCurrentProgress(), + (start_time_ms + 100.f) / total_duration_ms); + + AdvanceClock(100); + animation_->Pause(); + EXPECT_TRUE(IsPaused()); + + // Advancing clock and stepping animation should have no effect when animation + // is paused. + AdvanceClock(5000); + animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize()); + EXPECT_FLOAT_EQ(animation_->GetCurrentProgress(), + (start_time_ms + 100.f) / total_duration_ms); + + // Resume playing the animation. + animation_->ResumePlaying(); + EXPECT_TRUE(IsScheduledToResume()); + + // There should be no progress, since we haven't advanced the clock yet. + animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize()); + EXPECT_TRUE(IsPlaying()); + EXPECT_FLOAT_EQ(animation_->GetCurrentProgress(), + (start_time_ms + 100.f) / total_duration_ms); + + AdvanceClock(100); + animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize()); + EXPECT_FLOAT_EQ(animation_->GetCurrentProgress(), + (start_time_ms + 200.f) / total_duration_ms); + + AdvanceClock(800); + animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize()); + EXPECT_FLOAT_EQ(animation_->GetCurrentProgress(), GetTimerEndOffset()); + EXPECT_TRUE(IsPlaying()); + + AdvanceClock(100); + animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize()); + EXPECT_FLOAT_EQ(animation_->GetCurrentProgress(), + (start_time_ms + 900.f) / total_duration_ms); + EXPECT_TRUE(IsPlaying()); + + animation_->Pause(); + EXPECT_TRUE(IsPaused()); + + AdvanceClock(10000); + animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize()); + EXPECT_FLOAT_EQ(animation_->GetCurrentProgress(), + (start_time_ms + 900.f) / total_duration_ms); + + // Resume playing the animation. + animation_->ResumePlaying(); + EXPECT_TRUE(IsScheduledToResume()); + + animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize()); + EXPECT_TRUE(IsPlaying()); + + AdvanceClock(500); + animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize()); + EXPECT_FLOAT_EQ(animation_->GetCurrentProgress(), + (start_time_ms + 400.f) / total_duration_ms); + + AdvanceClock(400); + animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize()); + EXPECT_FLOAT_EQ(animation_->GetCurrentProgress(), GetTimerStartOffset()); + + AdvanceClock(100); + animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize()); + EXPECT_FLOAT_EQ(animation_->GetCurrentProgress(), + (start_time_ms + 100.f) / total_duration_ms); + EXPECT_TRUE(IsPlaying()); +} + +TEST_F(SkiaVectorAnimationTest, PauseBeforePlay) { + const float total_duration_ms = kAnimationDuration * 1000.f; + + // Test to see if the race condition is handled correctly. It may happen that + // we pause the video before it even starts playing. + animation_ = std::make_unique<SkiaVectorAnimation>( + std::make_unique<SkMemoryStream>(kData, std::strlen(kData))); + + TestAnimationObserver observer; + animation_->SetAnimationObserver(&observer); + + AdvanceClock(300); + + animation_->Start(); + EXPECT_TRUE(IsScheduledToPlay()); + + animation_->Pause(); + EXPECT_TRUE(IsPaused()); + + AdvanceClock(100); + animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize()); + + animation_->ResumePlaying(); + EXPECT_TRUE(IsScheduledToResume()); + + AdvanceClock(100); + animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize()); + EXPECT_TRUE(IsPlaying()); + + AdvanceClock(100); + animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize()); + EXPECT_FLOAT_EQ(animation_->GetCurrentProgress(), 100.f / total_duration_ms); +} + +TEST_F(SkiaVectorAnimationTest, PaintTest) { + std::unique_ptr<gfx::Canvas> canvas(new gfx::Canvas( + gfx::Size(kAnimationWidth, kAnimationHeight), 1.f, false)); + animation_ = std::make_unique<SkiaVectorAnimation>( + std::make_unique<SkMemoryStream>(kData, std::strlen(kData))); + + // Advance clock by 300 milliseconds. + AdvanceClock(300); + + animation_->Start(SkiaVectorAnimation::Style::kLinear); + animation_->Paint(canvas.get(), NowTicks(), animation_->GetOriginalSize()); + + AdvanceClock(50); + animation_->Paint(canvas.get(), NowTicks(), animation_->GetOriginalSize()); + SkBitmap bitmap = canvas->GetBitmap(); + IsAllSameColor(SK_ColorGREEN, bitmap); + + AdvanceClock(2450); + animation_->Paint(canvas.get(), NowTicks(), animation_->GetOriginalSize()); + bitmap = canvas->GetBitmap(); + IsAllSameColor(SK_ColorGREEN, bitmap); + + AdvanceClock(50); + animation_->Paint(canvas.get(), NowTicks(), animation_->GetOriginalSize()); + bitmap = canvas->GetBitmap(); + IsAllSameColor(SK_ColorBLUE, bitmap); + + AdvanceClock(1000); + animation_->Paint(canvas.get(), NowTicks(), animation_->GetOriginalSize()); + bitmap = canvas->GetBitmap(); + IsAllSameColor(SK_ColorBLUE, bitmap); + + AdvanceClock(1400); + animation_->Paint(canvas.get(), NowTicks(), animation_->GetOriginalSize()); + bitmap = canvas->GetBitmap(); + IsAllSameColor(SK_ColorBLUE, bitmap); +} + +} // namespace gfx
diff --git a/ui/views/cocoa/bridge_factory_host.cc b/ui/views/cocoa/bridge_factory_host.cc index 4fafac5..a660a20b 100644 --- a/ui/views/cocoa/bridge_factory_host.cc +++ b/ui/views/cocoa/bridge_factory_host.cc
@@ -4,10 +4,18 @@ #include "ui/views/cocoa/bridge_factory_host.h" +#include "mojo/public/cpp/bindings/interface_request.h" + namespace views { +namespace { +// Start the ids at something far from zero to help in debugging. +uint64_t g_next_bridge_factory_host_id_ = 0x1000; +} // namespace + BridgeFactoryHost::BridgeFactoryHost( - views_bridge_mac::mojom::BridgeFactoryRequest* request) { + views_bridge_mac::mojom::BridgeFactoryRequest* request) + : host_id_(g_next_bridge_factory_host_id_++) { *request = mojo::MakeRequest(&bridge_factory_ptr_); }
diff --git a/ui/views/cocoa/bridge_factory_host.h b/ui/views/cocoa/bridge_factory_host.h index c5c68fe..e8027a4 100644 --- a/ui/views/cocoa/bridge_factory_host.h +++ b/ui/views/cocoa/bridge_factory_host.h
@@ -24,11 +24,18 @@ BridgeFactoryHost(views_bridge_mac::mojom::BridgeFactoryRequest* request); ~BridgeFactoryHost(); + + // Return an id for the host process. This can be used to look up other + // factories to create NSViews (e.g in content). + uint64_t GetHostId() const { return host_id_; } + views_bridge_mac::mojom::BridgeFactory* GetFactory(); + void AddObserver(Observer* observer); void RemoveObserver(const Observer* observer); private: + const uint64_t host_id_; views_bridge_mac::mojom::BridgeFactoryPtr bridge_factory_ptr_; base::ObserverList<Observer> observers_; };
diff --git a/ui/webui/resources/cr_components/chromeos/multidevice_setup/multidevice_setup.html b/ui/webui/resources/cr_components/chromeos/multidevice_setup/multidevice_setup.html index f9968ae6..bf8f4c1 100644 --- a/ui/webui/resources/cr_components/chromeos/multidevice_setup/multidevice_setup.html +++ b/ui/webui/resources/cr_components/chromeos/multidevice_setup/multidevice_setup.html
@@ -25,7 +25,11 @@ margin: auto; max-height: 640px; max-width: 768px; - padding: 60px 64px 32px 64px; + padding: 60px 32px 32px 32px; + } + + iron-pages { + padding: 0 32px; } </style> <iron-pages attr-for-selected="is"
diff --git a/ui/webui/resources/cr_components/chromeos/multidevice_setup/start_setup_page.html b/ui/webui/resources/cr_components/chromeos/multidevice_setup/start_setup_page.html index d9a187b6..7a3325d24 100644 --- a/ui/webui/resources/cr_components/chromeos/multidevice_setup/start_setup_page.html +++ b/ui/webui/resources/cr_components/chromeos/multidevice_setup/start_setup_page.html
@@ -13,6 +13,7 @@ #selector-and-details-container { @apply --layout-horizontal; margin-top: 48px; + min-height: 246px; } #singleDeviceName { @@ -42,6 +43,8 @@ } #feature-details-container { + @apply --layout-vertical; + @apply --layout-center-justified; border-left: 1px solid rgb(218, 220, 224); padding-left: 24px; } @@ -53,22 +56,24 @@ .feature-detail { @apply --layout-horizontal; @apply --layout-center; - padding-bottom: 28px; - padding-top: 21px; + box-sizing: border-box; + min-height: 64px; + padding: 10px 0; } .feature-detail iron-icon { --iron-icon-height: 20px; --iron-icon-width: 20px; - position: fixed; + min-width: 20px; } .feature-detail span { - padding-left: 28px; + margin-left: 8px; } #footnote { color: var(--paper-grey-600); + margin-top: 12px; } </style>