diff --git a/DEPS b/DEPS index 1ed31a1..8ea0118 100644 --- a/DEPS +++ b/DEPS
@@ -314,15 +314,15 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': 'eff8446c42f8a260eae298c67322cce684ec9669', + 'skia_revision': 'aa208c8a2d60b087ef74d35737b037cfe85a4fc4', # 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': 'ad0956c177c9a6990e78dc061c9b8d83a6320b1a', + 'v8_revision': '40cb2f6d823b5dc2c8a5e920574932cce2ea7af1', # 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': '27836f2181738a69543f657898f4cd6994c4c4d7', + 'angle_revision': '823de3a30c4fccae5f67aa99f4ee9f4847e3b2e3', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. @@ -385,7 +385,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': '19ad1237e35315125d897f6f438b3cd2798fc133', + 'catapult_revision': 'e8ae187c6dbdb2de0c4c673307c1c259ef6eb0e8', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling chromium_variations # and whatever else without interference from each other. @@ -445,11 +445,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'dawn_revision': '1244719685f0df31ffecea8cad822540cc9d96bf', + 'dawn_revision': '092f3f12f369fe3d894f17bca1e9ed40a98bf3f5', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'quiche_revision': 'ed310679f2d91e0908e9f898ac4995d1e1eb0102', + 'quiche_revision': 'ba658fc677a78c2515fd1851526be5bea8fc74c4', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ios_webkit # and whatever else without interference from each other. @@ -837,12 +837,12 @@ 'src/clank': { 'url': Var('chrome_git') + '/clank/internal/apps.git' + '@' + - 'ce4f375bbbfa4e53c4a7aee65f0025ca475a2064', + '446cc4c9eea2d0582c8e0900c4a73e4b9a38d1dc', 'condition': 'checkout_android and checkout_src_internal', }, 'src/docs/website': { - 'url': Var('chromium_git') + '/website.git' + '@' + '4816910e134254e7155c90dcbf9f5055ce8b4099', + 'url': Var('chromium_git') + '/website.git' + '@' + '27038fe25a6108105f3d923d11044574152f901e', }, 'src/ios/third_party/earl_grey2/src': { @@ -1032,7 +1032,7 @@ 'packages': [ { 'package': 'chromium/third_party/androidx', - 'version': 'QMx7KoZ2HCGl36cSVOPb3d3ye56TrMPDi4RwOdTA7UQC', + 'version': '0jZE2CS4pOwZI_V9z1wPVlX8BC0SZAJW7Q8EqaMtObsC', }, ], 'condition': 'checkout_android', @@ -1276,7 +1276,7 @@ }, 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '2c3875ea1c41b98c8e5467bb7a56d27c97f30ae8', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'a1cfc693af3505461fea2a59eaf484720c897c4f', 'src/third_party/devtools-frontend/src': Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'),
diff --git a/ash/BUILD.gn b/ash/BUILD.gn index f38b6a2..11ffa2ea 100644 --- a/ash/BUILD.gn +++ b/ash/BUILD.gn
@@ -4013,6 +4013,8 @@ "//ash/public/cpp", "//ash/public/cpp:test_support", "//base/test:test_support", + "//chromeos/ash/components/audio", + "//chromeos/ash/components/dbus/audio", "//chromeos/ash/services/assistant/public/cpp", "//chromeos/ash/services/bluetooth_config:test_support", "//chromeos/dbus/power:power",
diff --git a/ash/ash_strings.grd b/ash/ash_strings.grd index cef8a568..b3fa78c 100644 --- a/ash/ash_strings.grd +++ b/ash/ash_strings.grd
@@ -2519,17 +2519,14 @@ Last desk can't be removed. </message> <message name="IDS_ASH_DESKS_ACTIVE_DESK_MINIVIEW_A11Y_EXTRA_TIP" desc="The accessibility tooltip read by screen readers for a highlighted active desk mini_view."> - active desk + Active desk. </message> <message name="IDS_ASH_DESKS_INACTIVE_DESK_MINIVIEW_A11Y_EXTRA_TIP" desc="The accessibility tooltip read by screen readers for a highlighted inactive desk mini_view."> - inactive desk + Inactive desk. </message> <message name="IDS_ASH_DESKS_DESK_ACCESSIBLE_NAME" desc="The full accessible desk name"> Desk: <ph name="DESK_NAME">$1</ph> </message> - <message name="IDS_ASH_DESKS_DESK_PREVIEW_A11Y_NAME" desc="The full accessible desk name"> - Go to <ph name="ACTIVE_STATE">$1</ph> <ph name="DESK_NAME">$2</ph> button. - </message> <message name="IDS_ASH_DESKS_DESK_NAME_COMMIT" desc="Alert when the desk name is committed"> Desk name was changed to <ph name="DESK_NAME">$1</ph> </message>
diff --git a/ash/ash_strings_grd/IDS_ASH_DESKS_ACTIVE_DESK_MINIVIEW_A11Y_EXTRA_TIP.png.sha1 b/ash/ash_strings_grd/IDS_ASH_DESKS_ACTIVE_DESK_MINIVIEW_A11Y_EXTRA_TIP.png.sha1 deleted file mode 100644 index b9e56f1..0000000 --- a/ash/ash_strings_grd/IDS_ASH_DESKS_ACTIVE_DESK_MINIVIEW_A11Y_EXTRA_TIP.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -f0ab6cae002646d549b453d8462bb660fa4f46b2 \ No newline at end of file
diff --git a/ash/ash_strings_grd/IDS_ASH_DESKS_DESK_PREVIEW_A11Y_NAME.png.sha1 b/ash/ash_strings_grd/IDS_ASH_DESKS_DESK_PREVIEW_A11Y_NAME.png.sha1 deleted file mode 100644 index 9b94ed2..0000000 --- a/ash/ash_strings_grd/IDS_ASH_DESKS_DESK_PREVIEW_A11Y_NAME.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -828c0f8080f2886b58e92b5ce5de44366924f884 \ No newline at end of file
diff --git a/ash/ash_strings_grd/IDS_ASH_DESKS_INACTIVE_DESK_MINIVIEW_A11Y_EXTRA_TIP.png.sha1 b/ash/ash_strings_grd/IDS_ASH_DESKS_INACTIVE_DESK_MINIVIEW_A11Y_EXTRA_TIP.png.sha1 index c61e9381..13f2b42 100644 --- a/ash/ash_strings_grd/IDS_ASH_DESKS_INACTIVE_DESK_MINIVIEW_A11Y_EXTRA_TIP.png.sha1 +++ b/ash/ash_strings_grd/IDS_ASH_DESKS_INACTIVE_DESK_MINIVIEW_A11Y_EXTRA_TIP.png.sha1
@@ -1 +1 @@ -052eae4fae5a6f4cfec48cce64759f0a3e615d7d \ No newline at end of file +c0011f1a7d59d0e49a62cc6be9fe822a6a1cd403 \ No newline at end of file
diff --git a/ash/components/arc/chrome_feature_flags/arc_chrome_feature_flags_bridge.cc b/ash/components/arc/chrome_feature_flags/arc_chrome_feature_flags_bridge.cc index 181a2b1..e54831d8 100644 --- a/ash/components/arc/chrome_feature_flags/arc_chrome_feature_flags_bridge.cc +++ b/ash/components/arc/chrome_feature_flags/arc_chrome_feature_flags_bridge.cc
@@ -91,6 +91,7 @@ : mojom::RoundedWindowCompatStrategy::kDisabled; flags->rounded_window_radius = chromeos::features::RoundedWindowsRadius(); flags->xdg_mode = base::FeatureList::IsEnabled(kXdgMode); + flags->enable_pip_double_tap = ash::features::IsPipDoubleTapToResizeEnabled(); chrome_feature_flags_instance->NotifyFeatureFlags(std::move(flags)); }
diff --git a/ash/components/arc/chrome_feature_flags/arc_chrome_feature_flags_bridge_unittest.cc b/ash/components/arc/chrome_feature_flags/arc_chrome_feature_flags_bridge_unittest.cc index 6f20f8f..b71cbc5 100644 --- a/ash/components/arc/chrome_feature_flags/arc_chrome_feature_flags_bridge_unittest.cc +++ b/ash/components/arc/chrome_feature_flags/arc_chrome_feature_flags_bridge_unittest.cc
@@ -184,5 +184,19 @@ EXPECT_FALSE(instance()->flags_called_value()->xdg_mode); } +TEST_F(ArcChromeFeatureFlagsBridgeTest, NotifyPipDoubleTapToResize_Enabled) { + scoped_feature_list()->InitAndEnableFeature( + ash::features::kPipDoubleTapToResize); + Connect(); + EXPECT_TRUE(instance()->flags_called_value()->enable_pip_double_tap); +} + +TEST_F(ArcChromeFeatureFlagsBridgeTest, NotifyPipDoubleTapToResize_Disabled) { + scoped_feature_list()->InitAndDisableFeature( + ash::features::kPipDoubleTapToResize); + Connect(); + EXPECT_FALSE(instance()->flags_called_value()->enable_pip_double_tap); +} + } // namespace } // namespace arc
diff --git a/ash/components/arc/mojom/chrome_feature_flags.mojom b/ash/components/arc/mojom/chrome_feature_flags.mojom index bd292045..ab47ab88 100644 --- a/ash/components/arc/mojom/chrome_feature_flags.mojom +++ b/ash/components/arc/mojom/chrome_feature_flags.mojom
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Next MinVersion: 5 +// Next MinVersion: 6 module arc.mojom; @@ -31,6 +31,8 @@ [MinVersion=3] int32 rounded_window_radius; // chrome://flags#arc-xdg-mode [MinVersion=4] bool xdg_mode; + // chrome://flags#enable-pip-double-tap-to-resize; + [MinVersion=5] bool enable_pip_double_tap; }; // This interface provides methods to propagate the feature flag status to
diff --git a/ash/constants/ash_features.cc b/ash/constants/ash_features.cc index 8b32c0c4..9e6c8fe 100644 --- a/ash/constants/ash_features.cc +++ b/ash/constants/ash_features.cc
@@ -2230,11 +2230,6 @@ "ScreenSaverDuration", base::FEATURE_DISABLED_BY_DEFAULT); -// Enables the "Preview" button for screensaver. -BASE_FEATURE(kScreenSaverPreview, - "ScreenSaverPreview", - base::FEATURE_ENABLED_BY_DEFAULT); - // Enables the system tray to show more information in larger screen. BASE_FEATURE(kSeamlessRefreshRateSwitching, "SeamlessRefreshRateSwitching", @@ -3337,10 +3332,6 @@ return base::FeatureList::IsEnabled(kScreenSaverDuration); } -bool IsScreenSaverPreviewEnabled() { - return base::FeatureList::IsEnabled(kScreenSaverPreview); -} - bool IsSnoopingProtectionEnabled() { return base::FeatureList::IsEnabled(kSnoopingProtection) && switches::HasHps();
diff --git a/ash/constants/ash_features.h b/ash/constants/ash_features.h index 79d824c9..1c18609 100644 --- a/ash/constants/ash_features.h +++ b/ash/constants/ash_features.h
@@ -665,7 +665,6 @@ COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kScalableIph); COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kScanningAppJelly); COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kScreenSaverDuration); -COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kScreenSaverPreview); COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kSeamlessRefreshRateSwitching); COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kSeparateNetworkIcons); @@ -1077,7 +1076,6 @@ bool IsSamlNotificationOnPasswordChangeSuccessEnabled(); COMPONENT_EXPORT(ASH_CONSTANTS) bool IsScalableIphEnabled(); COMPONENT_EXPORT(ASH_CONSTANTS) bool IsScreenSaverDurationEnabled(); -COMPONENT_EXPORT(ASH_CONSTANTS) bool IsScreenSaverPreviewEnabled(); COMPONENT_EXPORT(ASH_CONSTANTS) bool IsSeparateNetworkIconsEnabled(); COMPONENT_EXPORT(ASH_CONSTANTS) bool IsSettingsAppNotificationSettingsEnabled();
diff --git a/ash/constants/ash_switches.cc b/ash/constants/ash_switches.cc index e86ffae..d39e66d 100644 --- a/ash/constants/ash_switches.cc +++ b/ash/constants/ash_switches.cc
@@ -337,6 +337,10 @@ // file). const char kDefaultWallpaperSmall[] = "default-wallpaper-small"; +// Interval in seconds to wait for a display to reconnect while unlocking or +// logging in with a closed lid. +const char kDeferExternalDisplayTimeout[] = "defer-external-display-timeout"; + // Test Organization Unit (OU) user to use for demo mode. Only pass the part // before "@cros-demo-mode.com". const char kDemoModeEnrollingUsername[] = "demo-mode-enrolling-username";
diff --git a/ash/constants/ash_switches.h b/ash/constants/ash_switches.h index d03ba30ce..b45a7c5 100644 --- a/ash/constants/ash_switches.h +++ b/ash/constants/ash_switches.h
@@ -107,6 +107,8 @@ COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kDefaultWallpaperLarge[]; COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kDefaultWallpaperSmall[]; COMPONENT_EXPORT(ASH_CONSTANTS) +extern const char kDeferExternalDisplayTimeout[]; +COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kDemoModeEnrollingUsername[]; COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kDemoModeForceArcOfflineProvision[];
diff --git a/ash/fast_ink/cursor/cursor_view.cc b/ash/fast_ink/cursor/cursor_view.cc index 03634539..949db6e 100644 --- a/ash/fast_ink/cursor/cursor_view.cc +++ b/ash/fast_ink/cursor/cursor_view.cc
@@ -399,11 +399,8 @@ bool is_motion_blur_enabled) : painter_(std::make_unique<Painter>(this, initial_location, - is_motion_blur_enabled)), - ui_task_runner_(base::SingleThreadTaskRunner::GetCurrentDefault()) { + is_motion_blur_enabled)) { DCHECK_CALLED_ON_VALID_SEQUENCE(ui_sequence_checker_); - - ui::CursorController::GetInstance()->AddCursorObserver(this); } CursorView::~CursorView() { @@ -419,10 +416,17 @@ views::UniqueWidgetPtr CursorView::Create(const gfx::Point& initial_location, bool is_motion_blur_enabled, aura::Window* container) { - return FastInkView::CreateWidgetWithContents( - base::WrapUnique( - new CursorView(initial_location, is_motion_blur_enabled)), - container); + CursorView* cursor_view = + new CursorView(initial_location, is_motion_blur_enabled); + auto widget = FastInkView::CreateWidgetWithContents( + base::WrapUnique(cursor_view), container); + + // Initialize after FaskInkHost is set on `cursor_view` and it is attached to + // a widget. So that it could get `buffer_to_screen_transform_` and be able to + // initialize `painter_`. + cursor_view->Init(); + + return widget; } void CursorView::SetCursorImage(const gfx::ImageSkia& cursor_image, @@ -437,20 +441,7 @@ // ui::CursorController::CursorObserver overrides: void CursorView::OnCursorLocationChanged(const gfx::PointF& location) { - if (!buffer_to_screen_transform_) { - if (!ui_task_runner_->BelongsToCurrentThread()) { - // If it is not called from ui thread, post it to ui thread. - ui_task_runner_->PostTask( - FROM_HERE, base::BindOnce(&CursorView::OnCursorLocationChanged, - weak_ptr_factory_.GetWeakPtr(), location)); - return; - } - // Create transform used to convert cursor controller coordinates to screen - // coordinates. - buffer_to_screen_transform_ = - this->host()->window_to_buffer_transform().GetCheckedInverse(); - } - gfx::PointF new_location_f = buffer_to_screen_transform_->MapPoint(location); + gfx::PointF new_location_f = buffer_to_screen_transform_.MapPoint(location); gfx::Point new_location = gfx::ToRoundedPoint(new_location_f); painter_->SetCursorLocation(new_location); @@ -465,15 +456,17 @@ } //////////////////////////////////////////////////////////////////////////////// -// views::View overrides: +// CursorView, private: -void CursorView::AddedToWidget() { +void CursorView::Init() { + buffer_to_screen_transform_ = + host()->window_to_buffer_transform().GetCheckedInverse(); + painter_->Init(base::BindRepeating(&CursorView::UpdateSurface, weak_ptr_factory_.GetWeakPtr())); -} -//////////////////////////////////////////////////////////////////////////////// -// CursorView, private: + ui::CursorController::GetInstance()->AddCursorObserver(this); +} void CursorView::DidPresentCompositorFrame( const gfx::PresentationFeedback& feedback) {
diff --git a/ash/fast_ink/cursor/cursor_view.h b/ash/fast_ink/cursor/cursor_view.h index 9341d1c..ed40c7a 100644 --- a/ash/fast_ink/cursor/cursor_view.h +++ b/ash/fast_ink/cursor/cursor_view.h
@@ -47,26 +47,26 @@ // ash::FastInkView overrides: FastInkHost::PresentationCallback GetPresentationCallback() override; - // views::View overrides: - void AddedToWidget() override; - private: // Paints cursor on the paint thread. class Painter; CursorView(const gfx::Point& initial_location, bool is_motion_blur_enabled); + // Initialize CursorView after FaskInkHost is setup. + void Init(); + + // Invoked when a frame is presented. void DidPresentCompositorFrame(const gfx::PresentationFeedback& feedback); // Constants that can be used on any thread. - absl::optional<gfx::Transform> buffer_to_screen_transform_; + gfx::Transform buffer_to_screen_transform_; std::unique_ptr<Painter> painter_; // UI thread state. raw_ptr<ui::Compositor, ExperimentalAsh> compositor_ = nullptr; SEQUENCE_CHECKER(ui_sequence_checker_); - const scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_; base::WeakPtrFactory<CursorView> weak_ptr_factory_{this}; };
diff --git a/ash/system/audio/audio_detailed_view.cc b/ash/system/audio/audio_detailed_view.cc index 0aaa156..240d3114 100644 --- a/ash/system/audio/audio_detailed_view.cc +++ b/ash/system/audio/audio_detailed_view.cc
@@ -75,7 +75,7 @@ constexpr auto kLiveCaptionContainerMargins = gfx::Insets::TLBR(0, 0, 8, 0); constexpr auto kToggleButtonRowLabelPadding = gfx::Insets::TLBR(16, 0, 15, 0); constexpr auto kToggleButtonRowViewPadding = gfx::Insets::TLBR(0, 56, 8, 0); -constexpr auto kQsToggleButtonRowViewPadding = gfx::Insets::VH(0, 32); +constexpr auto kQsToggleButtonRowViewPadding = gfx::Insets::TLBR(0, 32, 0, 24); constexpr auto kQsToggleButtonRowPreferredSize = gfx::Size(0, 32); constexpr auto kQsToggleButtonRowLabelPadding = gfx::Insets::VH(8, 12); constexpr auto kQsToggleButtonRowMargins = gfx::Insets::VH(4, 0);
diff --git a/ash/system/audio/audio_detailed_view_pixeltest.cc b/ash/system/audio/audio_detailed_view_pixeltest.cc index 1dfefecc..4906b87 100644 --- a/ash/system/audio/audio_detailed_view_pixeltest.cc +++ b/ash/system/audio/audio_detailed_view_pixeltest.cc
@@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include <vector> + #include "ash/constants/ash_features.h" #include "ash/system/tray/tray_detailed_view.h" #include "ash/system/unified/unified_system_tray.h" @@ -10,12 +12,17 @@ #include "ash/test/pixel/ash_pixel_differ.h" #include "ash/test/pixel/ash_pixel_test_init_params.h" #include "base/test/scoped_feature_list.h" +#include "chromeos/ash/components/audio/cras_audio_handler.h" +#include "chromeos/ash/components/dbus/audio/audio_node.h" +#include "chromeos/ash/components/dbus/audio/fake_cras_audio_client.h" #include "chromeos/constants/chromeos_features.h" #include "ui/views/view.h" #include "ui/views/widget/widget.h" namespace ash { +constexpr uint64_t kInternalMicId = 10003; + // Pixel tests for the quick settings audio detailed view. class AudioDetailedViewPixelTest : public AshTestBase { public: @@ -52,4 +59,37 @@ /*revision_number=*/6, detailed_view)); } +TEST_F(AudioDetailedViewPixelTest, ShowNoiseCancellationButton) { + // Setup for showing noise cancellation button. + auto* client = FakeCrasAudioClient::Get(); + auto* audio_handler = CrasAudioHandler::Get(); + auto internal_mic_node = AudioNode( + true, kInternalMicId, false, kInternalMicId, 0, "Fake Mic", + "INTERNAL_MIC", "Internal Mic", false /* is_active*/, 0 /* pluged_time */, + 1, cras::EFFECT_TYPE_NOISE_CANCELLATION, 0); + AudioNodeList node_list; + node_list.push_back(internal_mic_node); + client->SetAudioNodesAndNotifyObserversForTesting(node_list); + client->SetNoiseCancellationSupported(true); + audio_handler->RequestNoiseCancellationSupported(base::DoNothing()); + audio_handler->SwitchToDevice(AudioDevice(internal_mic_node), true, + CrasAudioHandler::ACTIVATE_BY_USER); + + UnifiedSystemTray* system_tray = GetPrimaryUnifiedSystemTray(); + system_tray->ShowBubble(); + ASSERT_TRUE(system_tray->bubble()); + + system_tray->bubble() + ->unified_system_tray_controller() + ->ShowAudioDetailedView(); + + TrayDetailedView* detailed_view = + system_tray->bubble()->quick_settings_view()->GetDetailedViewForTest(); + ASSERT_TRUE(detailed_view); + + EXPECT_TRUE(GetPixelDiffer()->CompareUiComponentsOnPrimaryScreen( + "qs_audio_detailed_view", + /*revision_number=*/0, detailed_view)); +} + } // namespace ash
diff --git a/ash/system/audio/audio_effects_controller.cc b/ash/system/audio/audio_effects_controller.cc index abf16f9..2218ee9 100644 --- a/ash/system/audio/audio_effects_controller.cc +++ b/ash/system/audio/audio_effects_controller.cc
@@ -139,6 +139,14 @@ } void AudioEffectsController::OnActiveInputNodeChanged() { + RefreshNoiseCancellationSupported(); +} + +void AudioEffectsController::OnAudioNodesChanged() { + RefreshNoiseCancellationSupported(); +} + +void AudioEffectsController::RefreshNoiseCancellationSupported() { const bool noise_cancellation_supported = IsNoiseCancellationSupported(); if (noise_cancellation_supported_ == noise_cancellation_supported) {
diff --git a/ash/system/audio/audio_effects_controller.h b/ash/system/audio/audio_effects_controller.h index d37aa3e..d4d85ca8 100644 --- a/ash/system/audio/audio_effects_controller.h +++ b/ash/system/audio/audio_effects_controller.h
@@ -44,6 +44,10 @@ private: // CrasAudioHandler::AudioObserver: void OnActiveInputNodeChanged() override; + void OnAudioNodesChanged() override; + + // Refresh noise cancellation supported status. + void RefreshNoiseCancellationSupported(); // Construct effect for noise cancellation. void AddNoiseCancellationEffect(); @@ -62,4 +66,4 @@ } // namespace ash -#endif // ASH_SYSTEM_AUDIO_AUDIO_EFFECTS_CONTROLLER_H_ \ No newline at end of file +#endif // ASH_SYSTEM_AUDIO_AUDIO_EFFECTS_CONTROLLER_H_
diff --git a/ash/system/message_center/ash_message_popup_collection.cc b/ash/system/message_center/ash_message_popup_collection.cc index 8b73fc4..cf37093 100644 --- a/ash/system/message_center/ash_message_popup_collection.cc +++ b/ash/system/message_center/ash_message_popup_collection.cc
@@ -117,6 +117,8 @@ DCHECK_GE(baseline_offset_, 0); if (baseline_offset_ != 0) { baseline_offset_ += message_center::kMarginBetweenPopups; + + RecordPopupOnTopOfBubbleCount(); } if (old_baseline_offset != baseline_offset_) { @@ -517,4 +519,15 @@ } } +void AshMessagePopupCollection::RecordPopupOnTopOfBubbleCount() { + int popup_items_count = popup_items().size(); + if (!features::IsNotifierCollisionEnabled() || popup_items_count == 0) { + return; + } + + // Record the number of popups that are moved up. + base::UmaHistogramCounts100("Ash.NotificationPopup.OnTopOfBubbleCount", + popup_items_count); +} + } // namespace ash
diff --git a/ash/system/message_center/ash_message_popup_collection.h b/ash/system/message_center/ash_message_popup_collection.h index dde7b8a..a12e2afd 100644 --- a/ash/system/message_center/ash_message_popup_collection.h +++ b/ash/system/message_center/ash_message_popup_collection.h
@@ -170,6 +170,9 @@ void UpdateExpandCollapseEnabledForPopups(bool shelf_bubble_open, int available_space_above_popups); + // Records the metric for the count of popups that are on top of a bubble. + void RecordPopupOnTopOfBubbleCount(); + absl::optional<display::ScopedDisplayObserver> display_observer_; raw_ptr<display::Screen, ExperimentalAsh> screen_;
diff --git a/ash/system/message_center/ash_message_popup_collection_unittest.cc b/ash/system/message_center/ash_message_popup_collection_unittest.cc index 236d559..8184a3ec 100644 --- a/ash/system/message_center/ash_message_popup_collection_unittest.cc +++ b/ash/system/message_center/ash_message_popup_collection_unittest.cc
@@ -35,6 +35,7 @@ #include "ash/wm/overview/overview_controller.h" #include "ash/wm/tablet_mode/tablet_mode_controller.h" #include "base/command_line.h" +#include "base/test/metrics/histogram_tester.h" #include "base/test/scoped_feature_list.h" #include "chromeos/ash/components/phonehub/fake_phone_hub_manager.h" #include "chromeos/ash/components/phonehub/feature_status.h" @@ -992,6 +993,56 @@ } } +TEST_P(AshMessagePopupCollectionTest, AdjustBaselineHistogramRecorded) { + base::HistogramTester histogram_tester; + auto* unified_system_tray = GetPrimaryUnifiedSystemTray(); + unified_system_tray->ShowBubble(); + + AddNotification(); + auto* popup = GetLastPopUpAdded(); + + const std::string histogram_name = "Ash.NotificationPopup.OnTopOfBubbleCount"; + + if (!IsQsRevampEnabled()) { + EXPECT_FALSE(popup); + histogram_tester.ExpectBucketCount(histogram_name, 1, 0); + return; + } + + ASSERT_TRUE(popup); + + auto* bubble_view = unified_system_tray->bubble()->GetBubbleView(); + auto* popup_collection = GetPrimaryPopupCollection(); + + if (IsNotifierCollisionEnabled()) { + // The added popup should appears on top of the tray bubble and histogram is + // recorded. + EXPECT_EQ(bubble_view->height() + message_center::kMarginBetweenPopups, + popup_collection->baseline_offset_for_test()); + histogram_tester.ExpectBucketCount(histogram_name, 1, 1); + } else { + // The popup stays the same if the feature is disabled. + EXPECT_EQ(0, popup_collection->baseline_offset_for_test()); + histogram_tester.ExpectBucketCount(histogram_name, 1, 0); + } + + // Add another notification. Histogram should also be recorded with the + // correct bucket for 2 notifications. + AddNotification(); + AnimateUntilIdle(); + + histogram_tester.ExpectBucketCount(histogram_name, 2, + IsNotifierCollisionEnabled() ? 1 : 0); + + // Close and re-open the bubble. Histogram should be recorded again. + auto* bubble_widget = unified_system_tray->bubble()->GetBubbleWidget(); + bubble_widget->CloseNow(); + unified_system_tray->ShowBubble(); + + histogram_tester.ExpectBucketCount(histogram_name, 2, + IsNotifierCollisionEnabled() ? 2 : 0); +} + TEST_P(AshMessagePopupCollectionTest, NotificationAddedOnTrayBubbleOpen) { if (!IsQsRevampEnabled()) { return;
diff --git a/ash/system/power/power_event_observer.cc b/ash/system/power/power_event_observer.cc index ada456fa..f094e82 100644 --- a/ash/system/power/power_event_observer.cc +++ b/ash/system/power/power_event_observer.cc
@@ -8,6 +8,7 @@ #include <memory> #include <utility> +#include "ash/constants/ash_switches.h" #include "ash/display/projecting_observer.h" #include "ash/login_status.h" #include "ash/root_window_controller.h" @@ -18,6 +19,7 @@ #include "ash/wallpaper/views/wallpaper_widget_controller.h" #include "ash/wm/lock_state_controller.h" #include "ash/wm/lock_state_observer.h" +#include "base/command_line.h" #include "base/functional/bind.h" #include "base/location.h" #include "base/scoped_multi_source_observation.h" @@ -256,6 +258,19 @@ if (Shell::Get()->session_controller()->CanLockScreen()) lock_on_suspend_usage_ = std::make_unique<LockOnSuspendUsage>(); + + const std::string flag_value = + base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( + switches::kDeferExternalDisplayTimeout); + if (!flag_value.empty()) { + int seconds = -1; + if (base::StringToInt(flag_value, &seconds) && seconds > 0) { + defer_external_display_timeout_s_ = seconds; + } else { + LOG(WARNING) << "Ignoring bad value \"" << flag_value << "\" in --" + << switches::kDeferExternalDisplayTimeout; + } + } } PowerEventObserver::~PowerEventObserver() { @@ -369,6 +384,11 @@ } void PowerEventObserver::SetIsProjecting(bool is_projecting) { + // If we know we're projecting successfully, we no longer + // need to wait for external displays. + if (is_projecting) { + wait_for_external_display_timer_.Stop(); + } MaybeLockOnLidClose(is_projecting); } @@ -382,14 +402,15 @@ if (lid_state_ == chromeos::PowerManagerClient::LidState::CLOSED && lock_state_ == LockState::kUnlocked && !is_projecting && controller->ShouldLockScreenAutomatically() && - controller->CanLockScreen()) { + controller->CanLockScreen() && + !wait_for_external_display_timer_.IsRunning()) { VLOG(1) << "Screen locked due to lid close"; lock_state_ = LockState::kLocking; Shell::Get()->lock_state_controller()->LockWithoutAnimation(); } } -void PowerEventObserver::OnLoginStatusChanged(LoginStatus) { +void PowerEventObserver::OnLoginStatusChanged(LoginStatus login_status) { VLOG(1) << "PowerEventObserver::OnLoginStatusChanged"; // Bail if usage tracker is already created. if (lock_on_suspend_usage_) @@ -398,6 +419,11 @@ if (!ash::Shell::Get()->session_controller()->CanLockScreen()) return; lock_on_suspend_usage_ = std::make_unique<LockOnSuspendUsage>(); + + if (login_status != LoginStatus::NOT_LOGGED_IN && + login_status != LoginStatus::LOCKED) { + StartExternalDisplayTimer(); + } } void PowerEventObserver::OnLockStateChanged(bool locked) { @@ -432,6 +458,8 @@ } else if (block_suspend_token_) { StopCompositingAndSuspendDisplays(); } + } else { + StartExternalDisplayTimer(); } } VLOG(1) << "PowerEventObserver::OnLockStateChanged finished, new lock_state=" @@ -484,4 +512,16 @@ StopCompositingAndSuspendDisplays(); } +void PowerEventObserver::StartExternalDisplayTimer() { + // If the Lid is closed during a unlock/login, give a bit more time for + // displays to re-enumerate (as a result of a DisplayPort -> Thunderbolt mode + // switch). + if (lid_state_ == chromeos::PowerManagerClient::LidState::CLOSED && + defer_external_display_timeout_s_ > 0) { + wait_for_external_display_timer_.Start( + FROM_HERE, base::Seconds(defer_external_display_timeout_s_), + base::DoNothing()); + } +} + } // namespace ash
diff --git a/ash/system/power/power_event_observer.h b/ash/system/power/power_event_observer.h index 0a16a855..044cde61 100644 --- a/ash/system/power/power_event_observer.h +++ b/ash/system/power/power_event_observer.h
@@ -11,6 +11,7 @@ #include "ash/login_status.h" #include "ash/public/cpp/session/session_observer.h" #include "base/compiler_specific.h" +#include "base/timer/timer.h" #include "base/unguessable_token.h" #include "chromeos/dbus/power/power_manager_client.h" @@ -116,6 +117,9 @@ // can be stopped for all root windows when device suspends. void OnCompositorsReadyForSuspend(); + // Starts |wait_for_external_display_timer_|. + void StartExternalDisplayTimer(); + LockState lock_state_ = LockState::kUnlocked; chromeos::PowerManagerClient::LidState lid_state_ = chromeos::PowerManagerClient::LidState::OPEN; @@ -139,6 +143,11 @@ std::unique_ptr<LockOnSuspendUsage> lock_on_suspend_usage_; + // Amount of time (in seconds) to wait for external displays when a display + // mode change occurs and the lid is closed. + int defer_external_display_timeout_s_ = 0; + base::OneShotTimer wait_for_external_display_timer_; + base::WeakPtrFactory<PowerEventObserver> weak_factory_{this}; };
diff --git a/ash/system/unified/date_tray.h b/ash/system/unified/date_tray.h index acee21e..db66847 100644 --- a/ash/system/unified/date_tray.h +++ b/ash/system/unified/date_tray.h
@@ -65,6 +65,7 @@ private: friend class DateTrayTest; friend class GlanceablesPixelTest; + friend class GlanceablesV2BrowserTest; // Owned by the views hierarchy. raw_ptr<TimeTrayItemView, ExperimentalAsh> time_view_ = nullptr;
diff --git a/ash/webui/personalization_app/personalization_app_ui.cc b/ash/webui/personalization_app/personalization_app_ui.cc index feab0370..66c9ddf 100644 --- a/ash/webui/personalization_app/personalization_app_ui.cc +++ b/ash/webui/personalization_app/personalization_app_ui.cc
@@ -486,9 +486,6 @@ source->AddBoolean("isScreenSaverDurationEnabled", features::IsScreenSaverDurationEnabled()); - source->AddBoolean("isScreenSaverPreviewEnabled", - features::IsScreenSaverPreviewEnabled()); - source->AddBoolean("isPersonalizationJellyEnabled", features::IsPersonalizationJellyEnabled());
diff --git a/ash/webui/personalization_app/resources/js/ambient/ambient_preview_small_element.html b/ash/webui/personalization_app/resources/js/ambient/ambient_preview_small_element.html index 1808543..0697697d 100644 --- a/ash/webui/personalization_app/resources/js/ambient/ambient_preview_small_element.html +++ b/ash/webui/personalization_app/resources/js/ambient/ambient_preview_small_element.html
@@ -126,7 +126,7 @@ [[getAlbumDescription_(topicSource_, previewAlbums_)]] </span> </h3> - <div id="buttonContainer" hidden$="[[!isScreenSaverPreviewEnabled_]]"> + <div id="buttonContainer"> <cr-button class$="[[getScreenSaverPreviewClass_(ambientUiVisibility_)]]" aria-label$="[[getScreenSaverPreviewAriaLabel_(ambientUiVisibility_)]]"
diff --git a/ash/webui/personalization_app/resources/js/ambient/ambient_preview_small_element.ts b/ash/webui/personalization_app/resources/js/ambient/ambient_preview_small_element.ts index e906df0c..2c325c0 100644 --- a/ash/webui/personalization_app/resources/js/ambient/ambient_preview_small_element.ts +++ b/ash/webui/personalization_app/resources/js/ambient/ambient_preview_small_element.ts
@@ -18,7 +18,7 @@ import {assert} from 'chrome://resources/js/assert_ts.js'; import {AmbientUiVisibility} from '../../personalization_app.mojom-webui.js'; -import {isAmbientModeAllowed, isScreenSaverPreviewEnabled} from '../load_time_booleans.js'; +import {isAmbientModeAllowed} from '../load_time_booleans.js'; import {startScreenSaverPreview} from './ambient_controller.js'; import {getAmbientProvider} from './ambient_interface_provider.js'; @@ -50,18 +50,11 @@ type: Number, value: null, }, - isScreenSaverPreviewEnabled_: { - type: Boolean, - value() { - return isScreenSaverPreviewEnabled(); - }, - }, }; } private screenSaverPreviewActive_: boolean; private ambientUiVisibility_: AmbientUiVisibility|null; - private isScreenSaverPreviewEnabled_: boolean; override connectedCallback() { assert(
diff --git a/ash/webui/personalization_app/resources/js/load_time_booleans.ts b/ash/webui/personalization_app/resources/js/load_time_booleans.ts index 17f7e83d3..c3a4ef8 100644 --- a/ash/webui/personalization_app/resources/js/load_time_booleans.ts +++ b/ash/webui/personalization_app/resources/js/load_time_booleans.ts
@@ -31,10 +31,6 @@ return loadTimeData.getBoolean('isScreenSaverDurationEnabled'); } -export function isScreenSaverPreviewEnabled() { - return loadTimeData.getBoolean('isScreenSaverPreviewEnabled'); -} - export function isPersonalizationJellyEnabled() { return loadTimeData.getBoolean('isPersonalizationJellyEnabled'); }
diff --git a/ash/wm/desks/desk_mini_view.cc b/ash/wm/desks/desk_mini_view.cc index f1dd6c5..3f23410 100644 --- a/ash/wm/desks/desk_mini_view.cc +++ b/ash/wm/desks/desk_mini_view.cc
@@ -505,6 +505,39 @@ desk_name_view_->GetPreferredSize().height()}; } +void DeskMiniView::GetAccessibleNodeData(ui::AXNodeData* node_data) { + desk_preview_->GetAccessibleNodeData(node_data); + + // Note that the desk may have already been destroyed. + if (desk_) { + // Announce desk name. + node_data->AddStringAttribute( + ax::mojom::StringAttribute::kName, + l10n_util::GetStringFUTF8(IDS_ASH_DESKS_DESK_ACCESSIBLE_NAME, + desk_->name())); + + node_data->AddStringAttribute( + ax::mojom::StringAttribute::kValue, + l10n_util::GetStringUTF8( + desk_->is_active() + ? IDS_ASH_DESKS_ACTIVE_DESK_MINIVIEW_A11Y_EXTRA_TIP + : IDS_ASH_DESKS_INACTIVE_DESK_MINIVIEW_A11Y_EXTRA_TIP)); + } + + // If the desk can be combined or closed, add a tip to let the user know they + // can use an accelerator. + if (!DesksController::Get()->CanRemoveDesks()) + return; + + const std::u16string target_desk_name = + DesksController::Get()->GetCombineDesksTargetName(desk_); + const std::string extra_tip = l10n_util::GetStringFUTF8( + IDS_ASH_OVERVIEW_CLOSABLE_DESK_MINIVIEW_A11Y_EXTRA_TIP, target_desk_name); + + node_data->AddStringAttribute(ax::mojom::StringAttribute::kDescription, + extra_tip); +} + void DeskMiniView::OnThemeChanged() { views::View::OnThemeChanged(); UpdateFocusColor();
diff --git a/ash/wm/desks/desk_mini_view.h b/ash/wm/desks/desk_mini_view.h index 652a4f5..a7d58aaa 100644 --- a/ash/wm/desks/desk_mini_view.h +++ b/ash/wm/desks/desk_mini_view.h
@@ -138,6 +138,7 @@ const char* GetClassName() const override; void Layout() override; gfx::Size CalculatePreferredSize() const override; + void GetAccessibleNodeData(ui::AXNodeData* node_data) override; void OnThemeChanged() override; // Desk::Observer:
diff --git a/ash/wm/desks/desk_preview_view.cc b/ash/wm/desks/desk_preview_view.cc index 4496207..4d67d933 100644 --- a/ash/wm/desks/desk_preview_view.cc +++ b/ash/wm/desks/desk_preview_view.cc
@@ -10,7 +10,6 @@ #include "ash/public/cpp/window_properties.h" #include "ash/shell.h" -#include "ash/strings/grit/ash_strings.h" #include "ash/style/style_util.h" #include "ash/wallpaper/views/wallpaper_base_view.h" #include "ash/wm/desks/desk.h" @@ -34,7 +33,6 @@ #include "chromeos/constants/chromeos_features.h" #include "chromeos/ui/wm/features.h" #include "ui/accessibility/ax_node_data.h" -#include "ui/base/l10n/l10n_util.h" #include "ui/base/metadata/metadata_impl_macros.h" #include "ui/color/color_provider.h" #include "ui/compositor/layer.h" @@ -506,35 +504,6 @@ views::Button::GetAccessibleNodeData(node_data); if (GetAccessibleName().empty()) node_data->SetNameExplicitlyEmpty(); - - // Note that the desk may have already been destroyed. - Desk* desk = mini_view_->desk(); - if (desk) { - // Announce desk name. - node_data->AddStringAttribute( - ax::mojom::StringAttribute::kRoleDescription, - l10n_util::GetStringFUTF8( - IDS_ASH_DESKS_DESK_PREVIEW_A11Y_NAME, - l10n_util::GetStringUTF16( - desk->is_active() - ? IDS_ASH_DESKS_ACTIVE_DESK_MINIVIEW_A11Y_EXTRA_TIP - : IDS_ASH_DESKS_INACTIVE_DESK_MINIVIEW_A11Y_EXTRA_TIP), - desk->name())); - } - - // If the desk can be combined or closed, add a tip to let the user know they - // can use an accelerator. - if (!DesksController::Get()->CanRemoveDesks()) { - return; - } - - const std::u16string target_desk_name = - DesksController::Get()->GetCombineDesksTargetName(desk); - const std::string extra_tip = l10n_util::GetStringFUTF8( - IDS_ASH_OVERVIEW_CLOSABLE_DESK_MINIVIEW_A11Y_EXTRA_TIP, target_desk_name); - - node_data->AddStringAttribute(ax::mojom::StringAttribute::kDescription, - extra_tip); } void DeskPreviewView::Layout() {
diff --git a/ash/wm/snap_group/snap_group_unittest.cc b/ash/wm/snap_group/snap_group_unittest.cc index ce7deb2..fde9079a 100644 --- a/ash/wm/snap_group/snap_group_unittest.cc +++ b/ash/wm/snap_group/snap_group_unittest.cc
@@ -32,6 +32,7 @@ #include "ash/wm/tablet_mode/tablet_mode_controller_test_api.h" #include "ash/wm/window_cycle/window_cycle_controller.h" #include "ash/wm/window_cycle/window_cycle_list.h" +#include "ash/wm/window_cycle/window_cycle_view.h" #include "ash/wm/window_state.h" #include "ash/wm/window_util.h" #include "ash/wm/wm_event.h" @@ -494,6 +495,7 @@ WindowCycleController* window_cycle_controller = Shell::Get()->window_cycle_controller(); window_cycle_controller->CompleteCycling(); + EXPECT_FALSE(window_cycle_controller->IsCycling()); } void CycleWindow(WindowCyclingDirection direction, int steps) { @@ -1098,8 +1100,6 @@ // Test that the two windows in a snap group are reordered to be adjacent // with each other to reflect the window layout with the revised order as : // window2 --> window0--> window1. - // TODO(b/293365678): `cycle_list` should contain two items, update the test - // when the container view is implemented. ASSERT_EQ(windows.size(), 3u); EXPECT_EQ(windows.at(0), window2.get()); EXPECT_EQ(windows.at(1), window0.get()); @@ -1116,6 +1116,65 @@ EXPECT_TRUE(wm::IsActiveWindow(window2.get())); } +// Tests that the number of views to be cycled through inside the mirror +// container view of window cycle view will be the number of free-form windows +// plus snap groups. +TEST_F(SnapGroupEntryPointArm1Test, WindowCycleViewTest) { + std::unique_ptr<aura::Window> window0(CreateTestWindowInShellWithId(0)); + std::unique_ptr<aura::Window> window1(CreateTestWindowInShellWithId(1)); + std::unique_ptr<aura::Window> window2(CreateTestWindowInShellWithId(2)); + SnapTwoTestWindowsInArm1(window0.get(), window1.get()); + + WindowCycleController* window_cycle_controller = + Shell::Get()->window_cycle_controller(); + CycleWindow(WindowCyclingDirection::kForward, /*steps=*/3); + const auto* window_cycle_list = window_cycle_controller->window_cycle_list(); + const auto& windows = window_cycle_list->windows_for_testing(); + EXPECT_EQ(windows.size(), 3u); + + const WindowCycleView* cycle_view = window_cycle_list->cycle_view(); + ASSERT_TRUE(cycle_view); + EXPECT_EQ(cycle_view->mirror_container_for_testing()->children().size(), 2u); + CompleteWindowCycling(); +} + +// Tests that on window that belongs to a snap group destroying while cycling +// the window list with Alt + Tab, there will be no crash. The corresponding +// child mini view hosted by the group container view will be destroyed, the +// group container view will host the other child mini view. +TEST_F(SnapGroupEntryPointArm1Test, WindowInSnapGroupDestructionInAltTab) { + std::unique_ptr<aura::Window> window0(CreateTestWindowInShellWithId(0)); + std::unique_ptr<aura::Window> window1(CreateTestWindowInShellWithId(1)); + std::unique_ptr<aura::Window> window2(CreateTestWindowInShellWithId(2)); + SnapTwoTestWindowsInArm1(window0.get(), window1.get()); + + WindowCycleController* window_cycle_controller = + Shell::Get()->window_cycle_controller(); + CycleWindow(WindowCyclingDirection::kForward, /*steps=*/3); + const auto* window_cycle_list = window_cycle_controller->window_cycle_list(); + const auto& windows = window_cycle_list->windows_for_testing(); + EXPECT_EQ(windows.size(), 3u); + + const WindowCycleView* cycle_view = window_cycle_list->cycle_view(); + ASSERT_TRUE(cycle_view); + // Verify that the number of child views hosted by mirror container is two at + // the beginning. + EXPECT_EQ(cycle_view->mirror_container_for_testing()->children().size(), 2u); + + // Destroy `window0` which belongs to a snap group. + window0.reset(); + const auto* updated_window_cycle_list = + window_cycle_controller->window_cycle_list(); + const auto& updated_windows = + updated_window_cycle_list->windows_for_testing(); + // Verify that the updated windows list size decreased. + EXPECT_EQ(updated_windows.size(), 2u); + + // Verify that the number of child views hosted by mirror container will still + // be two. + EXPECT_EQ(cycle_view->mirror_container_for_testing()->children().size(), 2u); +} + // Tests that after creating a snap group in clamshell, transition to tablet // mode won't crash (b/288179725). TEST_F(SnapGroupEntryPointArm1Test, NoCrashWhenRemovingGroupInTabletMode) {
diff --git a/ash/wm/window_cycle/window_cycle_controller.cc b/ash/wm/window_cycle/window_cycle_controller.cc index 0fe6a8b..707e8f1 100644 --- a/ash/wm/window_cycle/window_cycle_controller.cc +++ b/ash/wm/window_cycle/window_cycle_controller.cc
@@ -4,15 +4,12 @@ #include "ash/wm/window_cycle/window_cycle_controller.h" -#include "ash/accelerators/accelerator_controller_impl.h" #include "ash/accessibility/accessibility_controller_impl.h" #include "ash/constants/ash_pref_names.h" #include "ash/events/event_rewriter_controller_impl.h" #include "ash/metrics/task_switch_metrics_recorder.h" #include "ash/metrics/task_switch_source.h" #include "ash/metrics/user_metrics_recorder.h" -#include "ash/public/cpp/accelerators.h" -#include "ash/public/cpp/window_properties.h" #include "ash/session/session_controller_impl.h" #include "ash/shell.h" #include "ash/strings/grit/ash_strings.h" @@ -25,7 +22,6 @@ #include "ash/wm/snap_group/snap_group.h" #include "ash/wm/window_cycle/window_cycle_event_filter.h" #include "ash/wm/window_cycle/window_cycle_list.h" -#include "ash/wm/window_state.h" #include "ash/wm/window_util.h" #include "base/check.h" #include "base/containers/contains.h"
diff --git a/ash/wm/window_cycle/window_cycle_item_view.cc b/ash/wm/window_cycle/window_cycle_item_view.cc index fff8da0..fcad3b3 100644 --- a/ash/wm/window_cycle/window_cycle_item_view.cc +++ b/ash/wm/window_cycle/window_cycle_item_view.cc
@@ -144,7 +144,7 @@ BEGIN_METADATA(WindowCycleItemView, WindowMiniView) END_METADATA -GroupContainerView::GroupContainerView(SnapGroup* snap_group) { +GroupContainerCycleView::GroupContainerCycleView(SnapGroup* snap_group) { mini_view1_ = AddChildView( std::make_unique<WindowCycleItemView>(snap_group->window1())); mini_view2_ = AddChildView( @@ -153,7 +153,6 @@ SetFocusBehavior(FocusBehavior::ALWAYS); SetPaintToLayer(); layer()->SetFillsBoundsOpaquely(false); - SetAccessibleName(u"Group container view"); // TODO(michelefan@): Orientation should correspond to the window layout. views::BoxLayout* layout = @@ -164,15 +163,19 @@ views::BoxLayout::CrossAxisAlignment::kCenter); } -GroupContainerView::~GroupContainerView() = default; +GroupContainerCycleView::~GroupContainerCycleView() = default; -bool GroupContainerView::Contains(aura::Window* window) const { - return mini_view1_->Contains(window) || mini_view2_->Contains(window); +bool GroupContainerCycleView::Contains(aura::Window* window) const { + return (mini_view1_ && mini_view1_->Contains(window)) || + (mini_view2_ && mini_view2_->Contains(window)); } -aura::Window* GroupContainerView::GetWindowAtPoint( +aura::Window* GroupContainerCycleView::GetWindowAtPoint( const gfx::Point& screen_point) const { for (auto mini_view : {mini_view1_, mini_view2_}) { + if (!mini_view) { + continue; + } if (auto* window = mini_view->GetWindowAtPoint(screen_point)) { return window; } @@ -180,7 +183,42 @@ return nullptr; } -BEGIN_METADATA(GroupContainerView, WindowMiniViewBase) +void GroupContainerCycleView::RefreshItemVisuals() { + for (auto mini_view : {mini_view1_, mini_view2_}) { + if (mini_view) { + mini_view->RefreshItemVisuals(); + } + } +} + +int GroupContainerCycleView::TryRemovingChildItem( + aura::Window* destroying_window) { + std::vector<raw_ptr<WindowCycleItemView>*> mini_views_ptrs = {&mini_view1_, + &mini_view2_}; + for (auto* mini_view_ptr : mini_views_ptrs) { + if (auto& mini_view = *mini_view_ptr; + mini_view && mini_view->Contains(destroying_window)) { + auto* temp = mini_view.get(); + // Explicitly reset the `mini_view` to avoid dangling pointer detection. + mini_view = nullptr; + RemoveChildViewT(temp); + } + } + + return base::ranges::count_if( + mini_views_ptrs, + [](raw_ptr<WindowCycleItemView>* ptr) { return *ptr != nullptr; }); +} + +void GroupContainerCycleView::GetAccessibleNodeData(ui::AXNodeData* node_data) { + views::View::GetAccessibleNodeData(node_data); + node_data->role = ax::mojom::Role::kGroup; + // TODO(b/297062026): Update the string after been finalized by consulting + // with a11y team. + node_data->SetName(u"Group container view"); +} + +BEGIN_METADATA(GroupContainerCycleView, WindowMiniViewBase) END_METADATA } // namespace ash
diff --git a/ash/wm/window_cycle/window_cycle_item_view.h b/ash/wm/window_cycle/window_cycle_item_view.h index 62055bb2..d0e6558 100644 --- a/ash/wm/window_cycle/window_cycle_item_view.h +++ b/ash/wm/window_cycle/window_cycle_item_view.h
@@ -10,12 +10,15 @@ #include "base/memory/raw_ptr.h" #include "ui/base/metadata/metadata_header_macros.h" #include "ui/events/event.h" -#include "ui/gfx/geometry/size.h" namespace aura { class Window; } // namespace aura +namespace gfx { +class Size; +} // namespace gfx + namespace ash { class SnapGroup; @@ -49,22 +52,29 @@ // Container view used to host multiple `WindowCycleItemView`s and be the focus // target for window groups while tabbing in window cycle view. -class GroupContainerView : public WindowMiniViewBase { +class GroupContainerCycleView : public WindowMiniViewBase { public: - METADATA_HEADER(GroupContainerView); + METADATA_HEADER(GroupContainerCycleView); - explicit GroupContainerView(SnapGroup* snap_group); - GroupContainerView(const GroupContainerView&) = delete; - GroupContainerView& operator=(const GroupContainerView&) = delete; - ~GroupContainerView() override; + explicit GroupContainerCycleView(SnapGroup* snap_group); + GroupContainerCycleView(const GroupContainerCycleView&) = delete; + GroupContainerCycleView& operator=(const GroupContainerCycleView&) = delete; + ~GroupContainerCycleView() override; // WindowMiniViewBase: bool Contains(aura::Window* window) const override; aura::Window* GetWindowAtPoint(const gfx::Point& screen_point) const override; + void RefreshItemVisuals() override; + int TryRemovingChildItem(aura::Window* destroying_window) override; + + // views::View: + void GetAccessibleNodeData(ui::AXNodeData* node_data) override; private: - raw_ptr<WindowCycleItemView, ExperimentalAsh> mini_view1_; - raw_ptr<WindowCycleItemView, ExperimentalAsh> mini_view2_; + // TODO(b/297070130): Use vector store the child `WindowCycleItemView` hosted + // by this. + raw_ptr<WindowCycleItemView> mini_view1_; + raw_ptr<WindowCycleItemView> mini_view2_; }; } // namespace ash
diff --git a/ash/wm/window_cycle/window_cycle_list.cc b/ash/wm/window_cycle/window_cycle_list.cc index 49e5624..04d0634 100644 --- a/ash/wm/window_cycle/window_cycle_list.cc +++ b/ash/wm/window_cycle/window_cycle_list.cc
@@ -6,7 +6,6 @@ #include "ash/accessibility/accessibility_controller_impl.h" #include "ash/app_list/app_list_controller_impl.h" -#include "ash/constants/ash_features.h" #include "ash/frame_throttler/frame_throttling_controller.h" #include "ash/public/cpp/shell_window_ids.h" #include "ash/public/cpp/window_properties.h" @@ -16,12 +15,12 @@ #include "ash/system/tray/tray_background_view.h" #include "ash/wm/mru_window_tracker.h" #include "ash/wm/tablet_mode/tablet_mode_controller.h" +#include "ash/wm/window_cycle/window_cycle_view.h" #include "ash/wm/window_state.h" #include "ash/wm/window_util.h" #include "base/check.h" #include "base/location.h" #include "base/metrics/histogram_functions.h" -#include "base/metrics/user_metrics.h" #include "base/ranges/algorithm.h" #include "ui/aura/scoped_window_targeter.h" #include "ui/aura/window.h" @@ -283,7 +282,6 @@ window->RemoveObserver(this); WindowList::iterator i = base::ranges::find(windows_, window); - // TODO(oshima): Change this back to DCHECK once crbug.com/483491 is fixed. CHECK(i != windows_.end()); int removed_index = static_cast<int>(i - windows_.begin()); windows_.erase(i);
diff --git a/ash/wm/window_cycle/window_cycle_list.h b/ash/wm/window_cycle/window_cycle_list.h index 836059d..970c6864 100644 --- a/ash/wm/window_cycle/window_cycle_list.h +++ b/ash/wm/window_cycle/window_cycle_list.h
@@ -10,14 +10,11 @@ #include "ash/ash_export.h" #include "ash/wm/window_cycle/window_cycle_controller.h" -#include "ash/wm/window_cycle/window_cycle_view.h" #include "base/memory/raw_ptr.h" #include "base/timer/timer.h" #include "ui/aura/window_observer.h" #include "ui/display/display_observer.h" -#include "ui/display/screen.h" -#include "ui/views/controls/label.h" -#include "ui/views/view.h" +#include "ui/events/event.h" namespace aura { class ScopedWindowTargeter; @@ -30,6 +27,8 @@ namespace ash { +class WindowCycleView; + // Tracks a set of Windows that can be stepped through. This class is used by // the WindowCycleController. class ASH_EXPORT WindowCycleList : public aura::WindowObserver,
diff --git a/ash/wm/window_cycle/window_cycle_view.cc b/ash/wm/window_cycle/window_cycle_view.cc index 086b7c8..c0610dd 100644 --- a/ash/wm/window_cycle/window_cycle_view.cc +++ b/ash/wm/window_cycle/window_cycle_view.cc
@@ -16,6 +16,8 @@ #include "ash/style/system_shadow.h" #include "ash/style/tab_slider.h" #include "ash/style/tab_slider_button.h" +#include "ash/wm/snap_group/snap_group.h" +#include "ash/wm/snap_group/snap_group_controller.h" #include "ash/wm/window_cycle/window_cycle_controller.h" #include "ash/wm/window_cycle/window_cycle_item_view.h" #include "ash/wm/window_mini_view.h" @@ -105,6 +107,34 @@ // modes. constexpr base::TimeDelta kToggleModeScaleDuration = base::Milliseconds(150); +// Builds the item view for window cycling for the given `window` with the +// correct parent. If the given `window` is a free-form window, the direct +// parent will be `mirror_container`. For `window` that belongs to a snap group, +// however, a `GroupContainerCycleView` will be added. +WindowMiniViewBase* BuildAndConfigureCycleView( + aura::Window* window, + views::View* mirror_container, + std::vector<WindowMiniViewBase*>& cycle_views) { + if (auto* snap_group_controller = SnapGroupController::Get()) { + if (auto* snap_group = + snap_group_controller->GetSnapGroupForGivenWindow(window)) { + // Create `GroupContainerCycleView` if `window` is primary snapped, + // which adds two child views subsequently. Skip adding + // `GroupContainerCycleView` if `window` is secondary snapped since the + // corresponding container view has been built. + return window == snap_group->window1() + ? mirror_container->AddChildView( + std::make_unique<GroupContainerCycleView>(snap_group)) + : nullptr; + } + } + + // `mirror_container_` owns `view`. The `preview_view_` in `view` will use + // trilinear filtering in InitLayerOwner(). + return mirror_container->AddChildView( + std::make_unique<WindowCycleItemView>(window)); +} + } // namespace WindowCycleView::WindowCycleView(aura::Window* root_window, @@ -228,12 +258,11 @@ } for (auto* window : windows) { - // |mirror_container_| owns |view|. The |preview_view_| in |view| will - // use trilinear filtering in InitLayerOwner(). - auto* view = mirror_container_->AddChildView( - std::make_unique<WindowCycleItemView>(window)); - cycle_views_.push_back(view); - no_previews_list_.push_back(view); + if (auto* view = BuildAndConfigureCycleView(window, mirror_container_, + cycle_views_)) { + cycle_views_.push_back(view); + no_previews_list_.push_back(view); + } } // The insets in the WindowCycleItemView are coming from its border, which @@ -328,10 +357,11 @@ return; for (auto* window : windows) { - auto* view = mirror_container_->AddChildView( - std::make_unique<WindowCycleItemView>(window)); - cycle_views_.push_back(view); - no_previews_list_.push_back(view); + if (auto* view = BuildAndConfigureCycleView(window, mirror_container_, + cycle_views_)) { + cycle_views_.push_back(view); + no_previews_list_.push_back(view); + } } // If there was an ongoing drag session, it's now been completed so reset @@ -376,7 +406,7 @@ Layout(); } -void WindowCycleView::SetTargetWindow(aura::Window* target) { +void WindowCycleView::SetTargetWindow(aura::Window* new_target) { // Hide the focus border of the previous target window and show the focus // border of the new one. if (target_window_) { @@ -385,7 +415,7 @@ } } - target_window_ = target; + target_window_ = new_target; if (auto* view = GetCycleViewForWindow(target_window_)) { view->UpdateFocusState(/*focus=*/true); } @@ -428,11 +458,16 @@ CHECK(preview); views::View* parent = preview->parent(); CHECK_EQ(mirror_container_, parent); - base::Erase(cycle_views_, preview); - base::Erase(no_previews_list_, preview); - delete preview; - // With one of its children now gone, we must re-layout |mirror_container_|. + if (preview->TryRemovingChildItem(destroying_window) == 0) { + // With no remaining child mini views contained in `preview`, we need to + // remove `preview` and clean up the `preview` in `cycle_views_` and + // `no_previews_list_`. + base::Erase(cycle_views_, preview); + base::Erase(no_previews_list_, preview); + parent->RemoveChildViewT(preview); + } + // With one of its children now gone, we must re-layout `mirror_container_`. // This must happen before ScrollToWindow() to make sure our own Layout() // works correctly when it's calculating highlight bounds. parent->Layout();
diff --git a/ash/wm/window_cycle/window_cycle_view.h b/ash/wm/window_cycle/window_cycle_view.h index ef6ac200..c1c8178 100644 --- a/ash/wm/window_cycle/window_cycle_view.h +++ b/ash/wm/window_cycle/window_cycle_view.h
@@ -26,6 +26,7 @@ namespace views { class Label; +class View; } // namespace views namespace ash { @@ -66,7 +67,7 @@ // the root window's bounds. gfx::Rect GetTargetBounds() const; - // Recreates the `WindowCycleView` with the provided `windows`. + // Recreates the `WindowCycleView` with the given `windows`. void UpdateWindows(const WindowList& windows); // Fades the `WindowCycleView` in. @@ -75,9 +76,12 @@ // Scrolls the `WindowCycleView` to `target`. void ScrollToWindow(aura::Window* target); - // Makes `target` the new `target_window_`, moving the focus ring to its - // respective `WindowCycleItemView`. - void SetTargetWindow(aura::Window* target); + // Refreshes the `target_window_` with the `new_target`. Updates the focus + // state of the focus ring by hiding the focus ring on the previously + // focused item and painting the focus ring on the currently focused item. + // The focus target will be a single `WindowCycleItemView` for free-form + // window and a `GroupContainerCycleView` for snap group. + void SetTargetWindow(aura::Window* new_target); // Removes the `destroying_window`'s respective `WindowCycleItemView` and sets // `new_target` as the new `target_window_`. @@ -129,6 +133,10 @@ // Returns the maximum width of the cycle view. int CalculateMaxWidth() const; + const views::View* mirror_container_for_testing() const { + return mirror_container_; + } + private: friend class WindowCycleListTestApi;
diff --git a/ash/wm/window_mini_view.cc b/ash/wm/window_mini_view.cc index 54227abe..3fbc0f3d 100644 --- a/ash/wm/window_mini_view.cc +++ b/ash/wm/window_mini_view.cc
@@ -207,6 +207,10 @@ return GetBoundsInScreen().Contains(screen_point) ? source_window_ : nullptr; } +int WindowMiniView::TryRemovingChildItem(aura::Window* destroying_window) { + return 0; +} + gfx::Rect WindowMiniView::GetHeaderBounds() const { gfx::Rect header_bounds = GetContentsBounds(); header_bounds.set_height(kHeaderHeightDp);
diff --git a/ash/wm/window_mini_view.h b/ash/wm/window_mini_view.h index 3a0a24e..fa80e122 100644 --- a/ash/wm/window_mini_view.h +++ b/ash/wm/window_mini_view.h
@@ -27,7 +27,7 @@ // Defines the interface that extracts the window, visual updates, focus // installation and update logic to be used or implemented by `WindowMiniView` -// and `GroupContainerView`. +// and `GroupContainerCycleView`. class WindowMiniViewBase : public views::View { public: METADATA_HEADER(WindowMiniViewBase); @@ -49,6 +49,12 @@ // of `this`. virtual void RefreshItemVisuals() = 0; + // Try removing the mini view representation of the `destroying_window`. + // Returns the number of remaining child items that represent windows within + // `this`. Returns 0, if `destroying_window` is represented by `this` itself + // rather than a child item. + virtual int TryRemovingChildItem(aura::Window* destroying_window) = 0; + // Shows or hides a focus ring around this. void UpdateFocusState(bool focus); @@ -106,6 +112,7 @@ // WindowMiniViewBase: bool Contains(aura::Window* window) const override; aura::Window* GetWindowAtPoint(const gfx::Point& screen_point) const override; + int TryRemovingChildItem(aura::Window* destroying_window) override; protected: explicit WindowMiniView(aura::Window* source_window);
diff --git a/cc/test/DEPS b/cc/test/DEPS index 8941ec0b..1a2bc067 100644 --- a/cc/test/DEPS +++ b/cc/test/DEPS
@@ -25,5 +25,9 @@ ], "pixel_test\.cc": [ "+gpu/command_buffer/service/service_utils.h", + "+gpu/config/gpu_switches.h", + ], + "layer_tree_test\.cc": [ + "+gpu/config/gpu_switches.h", ], }
diff --git a/cc/test/layer_tree_test.cc b/cc/test/layer_tree_test.cc index 52a0f67..280e3f1 100644 --- a/cc/test/layer_tree_test.cc +++ b/cc/test/layer_tree_test.cc
@@ -51,6 +51,7 @@ #include "components/viz/test/test_context_provider.h" #include "gpu/command_buffer/service/gpu_switches.h" #include "gpu/config/gpu_finch_features.h" +#include "gpu/config/gpu_switches.h" #include "testing/gmock/include/gmock/gmock.h" #include "ui/base/ui_base_features.h" #include "ui/gfx/animation/keyframe/timing_function.h" @@ -58,6 +59,11 @@ #include "ui/gl/gl_implementation.h" #include "ui/gl/gl_switches.h" +#if BUILDFLAG(SKIA_USE_DAWN) +#include "third_party/dawn/include/dawn/dawn_proc.h" +#include "third_party/dawn/include/dawn/native/DawnNative.h" // nogncheck +#endif + namespace cc { namespace { @@ -718,11 +724,16 @@ // Check if the graphics backend needs to initialize Vulkan. bool init_vulkan = false; + bool init_dawn = false; if (renderer_type_ == viz::RendererType::kSkiaVk) { scoped_feature_list_.InitAndEnableFeature(features::kVulkan); init_vulkan = true; } else if (renderer_type_ == viz::RendererType::kSkiaGraphite) { scoped_feature_list_.InitAndEnableFeature(features::kSkiaGraphite); + // Force the use of Graphite even if disallowed for other reasons e.g. ANGLE + // Metal is not enabled on Mac. + command_line->AppendSwitch(::switches::kSkiaGraphiteBackend); + init_dawn = true; #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) init_vulkan = true; #endif @@ -735,6 +746,12 @@ use_gpu ? ::switches::kVulkanImplementationNameNative : ::switches::kVulkanImplementationNameSwiftshader); } + + if (init_dawn) { +#if BUILDFLAG(SKIA_USE_DAWN) + dawnProcSetProcs(&dawn::native::GetProcs()); +#endif + } } LayerTreeTest::~LayerTreeTest() {
diff --git a/cc/test/pixel_test.cc b/cc/test/pixel_test.cc index 47dd797..6801925 100644 --- a/cc/test/pixel_test.cc +++ b/cc/test/pixel_test.cc
@@ -75,6 +75,12 @@ init_vulkan = true; } else if (backend == kSkiaGraphite) { scoped_feature_list_.InitAndEnableFeature(features::kSkiaGraphite); + + // Force the use of Graphite even if disallowed for other reasons e.g. ANGLE + // Metal is not enabled on Mac. + auto* command_line = base::CommandLine::ForCurrentProcess(); + command_line->AppendSwitch(::switches::kSkiaGraphiteBackend); + init_dawn = true; #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) init_vulkan = true; @@ -82,7 +88,8 @@ } else { // Ensure that we don't accidentally have vulkan or graphite enabled. scoped_feature_list_.InitWithFeatures( - {}, {features::kVulkan, features::kSkiaGraphite}); + /*enabled_features=*/{}, + /*disabled_features=*/{features::kVulkan, features::kSkiaGraphite}); } if (init_vulkan) {
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index 5a1bb18..6ed06c14 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn
@@ -261,7 +261,6 @@ "//chrome/browser/readaloud/android:hooks_public_impl_java", "//chrome/browser/supervised_user:parent_auth_delegate_impl_java", "//chrome/browser/touch_to_fill/android/internal:resource_provider_public_impl_java", - "//chrome/browser/ui/android/cars:delegate_public_impl_java", "//chrome/browser/ui/android/hats/internal:provider_public_impl_java", "//chrome/browser/xsurface_provider:hooks_public_impl_java", "//components/environment_integrity/android:integrity_service_bridge_public_impl_java",
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ReadingListSectionHeader.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ReadingListSectionHeader.java index 41c98b1..6be2af79f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ReadingListSectionHeader.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ReadingListSectionHeader.java
@@ -80,11 +80,11 @@ // Sort by read status first. if (lhsItem.isRead() != rhsItem.isRead()) { - return lhsItem.isRead() ? 1 : -1; + return Boolean.compare(lhsItem.isRead(), rhsItem.isRead()); } // Sort by creation timestamp descending for items with the same read status. - return lhsItem.getDateAdded() <= rhsItem.getDateAdded() ? 1 : -1; + return Long.compare(rhsItem.getDateAdded(), lhsItem.getDateAdded()); }); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabActivity.java index 98f008a..0398dca 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabActivity.java
@@ -447,6 +447,7 @@ protected boolean handleBackPressed() { if (!BackPressManager.isEnabled() && getTabModalLifetimeHandler() != null && getTabModalLifetimeHandler().onBackPressed()) { + BackPressManager.record(BackPressHandler.Type.TAB_MODAL_HANDLER); return true; } if (BackPressManager.correctTabNavigationOnFallback()) {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTest.java index 442ce29..371f921 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTest.java
@@ -105,6 +105,7 @@ import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.DoNotBatch; import org.chromium.base.test.util.Feature; +import org.chromium.base.test.util.HistogramWatcher; import org.chromium.base.test.util.MinAndroidSdkLevel; import org.chromium.base.test.util.Restriction; import org.chromium.chrome.browser.AppHooks; @@ -115,6 +116,7 @@ import org.chromium.chrome.browser.LaunchIntentDispatcher; import org.chromium.chrome.browser.TabsOpenedFromExternalAppTest; import org.chromium.chrome.browser.WarmupManager; +import org.chromium.chrome.browser.back_press.BackPressManager; import org.chromium.chrome.browser.browserservices.SessionDataHolder; import org.chromium.chrome.browser.browserservices.intents.BrowserServicesIntentDataProvider; import org.chromium.chrome.browser.browserservices.verification.ChromeOriginVerifier; @@ -161,6 +163,7 @@ import org.chromium.chrome.test.util.browser.Features.EnableFeatures; import org.chromium.chrome.test.util.browser.contextmenu.ContextMenuUtils; import org.chromium.components.browser_ui.widget.CoordinatorLayoutForPointer; +import org.chromium.components.browser_ui.widget.gesture.BackPressHandler; import org.chromium.components.content_settings.CookieControlsMode; import org.chromium.components.embedder_support.util.Origin; import org.chromium.components.prefs.PrefService; @@ -2522,6 +2525,11 @@ }); CriteriaHelper.pollUiThread(() -> dialogManager.isShowing(), "Dialog should be displayed"); + HistogramWatcher histogramWatcher = + HistogramWatcher.newSingleRecordWatcher("Android.BackPress.Intercept", + BackPressManager.getHistogramValueForTesting( + BackPressHandler.Type.TAB_MODAL_HANDLER)); + TestThreadUtils.runOnUiThreadBlocking(() -> { mCustomTabActivityTestRule.getActivity().getOnBackPressedDispatcher().onBackPressed(); }); @@ -2534,6 +2542,7 @@ is(mTestPage2)); }); + histogramWatcher.assertExpected("Dialog should be dismissed by back press"); CriteriaHelper.pollUiThread( () -> !dialogManager.isShowing(), "Dialog should be dismissed by back press"); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/WebXrGvrPermissionTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/WebXrGvrPermissionTest.java index 1690855..28f85fa 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/WebXrGvrPermissionTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/WebXrGvrPermissionTest.java
@@ -24,6 +24,7 @@ import org.chromium.base.test.params.ParameterizedRunner; import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.DisableIf; +import org.chromium.base.test.util.DisabledTest; import org.chromium.chrome.browser.flags.ChromeSwitches; import org.chromium.chrome.browser.vr.rules.XrActivityRestriction; import org.chromium.chrome.browser.vr.util.GvrTestRuleUtils; @@ -130,10 +131,8 @@ @Test @MediumTest @XrActivityRestriction({XrActivityRestriction.SupportedActivity.ALL}) - @DisableIf.Build(message = "crbug.com/1429697", hardware_is = "marlin", - sdk_is_greater_than = 28, sdk_is_less_than = 30) - public void - testPermissionPersistsAfterReload() { + @DisabledTest(message = "crbug.com/1429697") + public void testPermissionPersistsAfterReload() { mWebXrVrPermissionTestFramework.loadFileAndAwaitInitialization( "generic_webxr_page", PAGE_LOAD_TIMEOUT_S);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/WebXrVrCardboardPermissionTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/WebXrVrCardboardPermissionTest.java index 98d467e..6201453 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/WebXrVrCardboardPermissionTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/WebXrVrCardboardPermissionTest.java
@@ -22,6 +22,7 @@ import org.chromium.base.test.params.ParameterSet; import org.chromium.base.test.params.ParameterizedRunner; import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Restriction; import org.chromium.chrome.browser.flags.ChromeSwitches; import org.chromium.chrome.browser.vr.rules.XrActivityRestriction; @@ -133,6 +134,7 @@ @MediumTest @Restriction({RESTRICTION_TYPE_VIEWER_NON_DAYDREAM}) @XrActivityRestriction({XrActivityRestriction.SupportedActivity.ALL}) + @DisabledTest(message = "crbug.com/1429697") public void testPermissionPersistsAfterReload() { mWebXrVrPermissionTestFramework.loadFileAndAwaitInitialization( "generic_webxr_page", PAGE_LOAD_TIMEOUT_S);
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/ReadingListSectionHeaderTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/ReadingListSectionHeaderTest.java index 3caa5f7..7d92f5de 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/ReadingListSectionHeaderTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/ReadingListSectionHeaderTest.java
@@ -160,4 +160,19 @@ assertSectionHeader(listItems.get(1), R.string.reading_list_read, R.dimen.bookmark_reading_list_section_header_padding_top); } + + @Test + public void testReadAndUnreadItems_equalCreationTime() { + List<BookmarkListEntry> listItems = new ArrayList<>(); + listItems.add(createReadingListEntry(1, false, OLDER_CREATION_TIMESTAMP)); + listItems.add(createReadingListEntry(2, false, OLDER_CREATION_TIMESTAMP)); + listItems.add(createReadingListEntry(3, true, OLDER_CREATION_TIMESTAMP)); + listItems.add(createReadingListEntry(4, true, OLDER_CREATION_TIMESTAMP)); + ReadingListSectionHeader.maybeSortAndInsertSectionHeaders(listItems); + + assertEquals("Incorrect number of items in the adapter", 6, listItems.size()); + assertSectionHeader(listItems.get(0), R.string.reading_list_unread, 0); + assertSectionHeader(listItems.get(3), R.string.reading_list_read, + R.dimen.bookmark_reading_list_section_header_padding_top); + } }
diff --git a/chrome/android/profiles/newest.txt b/chrome/android/profiles/newest.txt index 358ab0bb..5fcce3f2 100644 --- a/chrome/android/profiles/newest.txt +++ b/chrome/android/profiles/newest.txt
@@ -1 +1 @@ -chromeos-chrome-amd64-117.0.5911.0_rc-r1-merged.afdo.bz2 +chromeos-chrome-amd64-118.0.5963.0_rc-r1-merged.afdo.bz2
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 2ebd4f7..6f1b5e53 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -4439,9 +4439,6 @@ {"screen-saver-duration", flag_descriptions::kScreenSaverDurationName, flag_descriptions::kScreenSaverDurationDescription, kOsCrOS, FEATURE_VALUE_TYPE(ash::features::kScreenSaverDuration)}, - {"screen-saver-preview", flag_descriptions::kScreenSaverPreviewName, - flag_descriptions::kScreenSaverPreviewDescription, kOsCrOS, - FEATURE_VALUE_TYPE(ash::features::kScreenSaverPreview)}, {"multi-zone-rgb-keyboard", flag_descriptions::kMultiZoneRgbKeyboardName, flag_descriptions::kMultiZoneRgbKeyboardDescription, kOsCrOS, FEATURE_VALUE_TYPE(ash::features::kMultiZoneRgbKeyboard)}, @@ -8126,11 +8123,6 @@ FEATURE_VALUE_TYPE(ash::features::kUseWallpaperStagingUrl)}, #endif // BUILDFLAG(IS_CHROMEOS_ASH) - {"autofill-enable-virtual-card", - flag_descriptions::kAutofillEnableVirtualCardName, - flag_descriptions::kAutofillEnableVirtualCardDescription, kOsDesktop, - FEATURE_VALUE_TYPE(autofill::features::kAutofillEnableVirtualCard)}, - #if BUILDFLAG(IS_ANDROID) {"autofill-enable-manual-fallback-for-virtual-cards", flag_descriptions::kAutofillEnableManualFallbackForVirtualCardsName, @@ -10840,6 +10832,13 @@ FEATURE_VALUE_TYPE(ash::features::kFloatingWorkspaceV2)}, #endif +#if BUILDFLAG(IS_ANDROID) + {"draw-immediately-when-interactive", + flag_descriptions::kDrawImmediatelyWhenInteractiveName, + flag_descriptions::kDrawImmediatelyWhenInteractiveDescription, kOsAndroid, + FEATURE_VALUE_TYPE(features::kDrawImmediatelyWhenInteractive)}, +#endif + #if BUILDFLAG(IS_CHROMEOS_ASH) {"almanac-game-migration", flag_descriptions::kAlmanacGameMigrationName, flag_descriptions::kAlmanacGameMigrationDescription, kOsCrOS,
diff --git a/chrome/browser/ash/app_list/app_service/app_service_shortcut_context_menu.cc b/chrome/browser/ash/app_list/app_service/app_service_shortcut_context_menu.cc index 168bba3..1609d7c5 100644 --- a/chrome/browser/ash/app_list/app_service/app_service_shortcut_context_menu.cc +++ b/chrome/browser/ash/app_list/app_service/app_service_shortcut_context_menu.cc
@@ -59,6 +59,11 @@ ui::ImageModel::FromVectorIcon(vector_icons::kLaunchIcon, ui::kColorAshSystemUIMenuIcon, ash::kAppContextMenuIconSize)); + + AddContextMenuOption(menu_model.get(), + static_cast<ash::CommandId>(ash::CommandId::TOGGLE_PIN), + IDS_APP_LIST_CONTEXT_MENU_PIN); + std::move(callback).Run(std::move(menu_model)); } @@ -67,5 +72,8 @@ switch (command_id) { case ash::LAUNCH_NEW: delegate()->ExecuteLaunchCommand(event_flags); + break; + default: + AppContextMenu::ExecuteCommand(command_id, event_flags); } }
diff --git a/chrome/browser/ash/app_list/app_service/app_service_shortcut_item_browsertest.cc b/chrome/browser/ash/app_list/app_service/app_service_shortcut_item_browsertest.cc index cf9c619b..c8ce840 100644 --- a/chrome/browser/ash/app_list/app_service/app_service_shortcut_item_browsertest.cc +++ b/chrome/browser/ash/app_list/app_service/app_service_shortcut_item_browsertest.cc
@@ -22,6 +22,7 @@ #include "chrome/browser/web_applications/test/web_app_install_test_utils.h" #include "chrome/common/chrome_features.h" #include "chrome/common/pref_names.h" +#include "chrome/grit/generated_resources.h" #include "chrome/test/base/ui_test_utils.h" #include "components/app_constants/constants.h" #include "components/services/app_service/public/cpp/app_types.h" @@ -34,6 +35,8 @@ #include "content/public/browser/notification_service.h" #include "content/public/test/browser_test.h" #include "testing/gtest/include/gtest/gtest.h" +#include "ui/base/l10n/l10n_util.h" +#include "ui/views/vector_icons.h" namespace apps { @@ -186,4 +189,52 @@ url_observer.Wait(); } +IN_PROC_BROWSER_TEST_F(AppServiceShortcutItemBrowserTest, + ContextMenuTooglePin) { + GURL app_url = GURL("https://example.org/"); + std::u16string shortcut_name = u"Example"; + apps::ShortcutId shortcut_id = + CreateWebAppBasedShortcut(app_url, shortcut_name); + + AppListClientImpl* client = AppListClientImpl::GetInstance(); + AppListModelUpdater* model_updater = test::GetModelUpdater(client); + ChromeAppListItem* item = model_updater->FindItem(shortcut_id.value()); + ASSERT_TRUE(item); + + base::test::TestFuture<std::unique_ptr<ui::SimpleMenuModel>> future; + item->GetContextMenuModel(ash::AppListItemContext::kNone, + future.GetCallback()); + + std::unique_ptr<ui::SimpleMenuModel> menu_model = future.Take(); + + auto tootle_pin_command_index = + menu_model->GetIndexOfCommandId(ash::CommandId::TOGGLE_PIN); + ASSERT_TRUE(tootle_pin_command_index); + EXPECT_EQ(tootle_pin_command_index.value(), 1u); + + EXPECT_EQ(l10n_util::GetStringUTF16(IDS_APP_LIST_CONTEXT_MENU_PIN), + menu_model->GetLabelAt(tootle_pin_command_index.value())); + EXPECT_EQ(&views::kPinIcon, + menu_model->GetIconAt(tootle_pin_command_index.value()) + .GetVectorIcon() + .vector_icon()); + + menu_model->ActivatedAt(tootle_pin_command_index.value()); + + EXPECT_EQ(l10n_util::GetStringUTF16(IDS_APP_LIST_CONTEXT_MENU_UNPIN), + menu_model->GetLabelAt(tootle_pin_command_index.value())); + EXPECT_EQ(&views::kUnpinIcon, + menu_model->GetIconAt(tootle_pin_command_index.value()) + .GetVectorIcon() + .vector_icon()); + + menu_model->ActivatedAt(tootle_pin_command_index.value()); + EXPECT_EQ(l10n_util::GetStringUTF16(IDS_APP_LIST_CONTEXT_MENU_PIN), + menu_model->GetLabelAt(tootle_pin_command_index.value())); + EXPECT_EQ(&views::kPinIcon, + menu_model->GetIconAt(tootle_pin_command_index.value()) + .GetVectorIcon() + .vector_icon()); +} + } // namespace apps
diff --git a/chrome/browser/ash/crosapi/browser_manager.cc b/chrome/browser/ash/crosapi/browser_manager.cc index d6267e35..9442e9a9 100644 --- a/chrome/browser/ash/crosapi/browser_manager.cc +++ b/chrome/browser/ash/crosapi/browser_manager.cc
@@ -161,9 +161,16 @@ constexpr char kLacrosLauncherNotifierID[] = "lacros_launcher"; base::FilePath LacrosLogDirectory() { + // When pre-launching Lacros at login screen is enabled: + // - In test images, we always save Lacros logs in /var/log/lacros. + // - In non-test images, we save Lacros logs in /var/log/lacros + // only when Lacros is running at login screen. Lacros will + // redirect user-specific logs to the cryptohome after login. if (base::FeatureList::IsEnabled(kLacrosLaunchAtLoginScreen) && - session_manager::SessionManager::Get()->session_state() == - session_manager::SessionState::LOGIN_PRIMARY) { + (base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kDisableLoggingRedirect) || + session_manager::SessionManager::Get()->session_state() == + session_manager::SessionState::LOGIN_PRIMARY)) { return base::FilePath("/var/log/lacros"); } return browser_util::GetUserDataDir();
diff --git a/chrome/browser/ash/device_sync/device_sync_client_factory.cc b/chrome/browser/ash/device_sync/device_sync_client_factory.cc index 324413f..776dfc6e 100644 --- a/chrome/browser/ash/device_sync/device_sync_client_factory.cc +++ b/chrome/browser/ash/device_sync/device_sync_client_factory.cc
@@ -143,12 +143,13 @@ return instance.get(); } -KeyedService* DeviceSyncClientFactory::BuildServiceInstanceFor( +std::unique_ptr<KeyedService> +DeviceSyncClientFactory::BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const { // TODO(crbug.com/848347): Check prohibited by policy in services that depend // on this Factory, not here. if (IsEnrollmentAllowedByPolicy(context)) - return new DeviceSyncClientHolder(context); + return std::make_unique<DeviceSyncClientHolder>(context); return nullptr; }
diff --git a/chrome/browser/ash/device_sync/device_sync_client_factory.h b/chrome/browser/ash/device_sync/device_sync_client_factory.h index 50e1c21..effc5a73 100644 --- a/chrome/browser/ash/device_sync/device_sync_client_factory.h +++ b/chrome/browser/ash/device_sync/device_sync_client_factory.h
@@ -33,7 +33,7 @@ ~DeviceSyncClientFactory() override; // BrowserContextKeyedServiceFactory: - KeyedService* BuildServiceInstanceFor( + std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const override; bool ServiceIsNULLWhileTesting() const override; };
diff --git a/chrome/browser/ash/drive/file_system_util.cc b/chrome/browser/ash/drive/file_system_util.cc index 856e051..6c19216 100644 --- a/chrome/browser/ash/drive/file_system_util.cc +++ b/chrome/browser/ash/drive/file_system_util.cc
@@ -216,6 +216,7 @@ } running_size += file_info.GetSize(); } + LOG(ERROR) << "ComputeDriveFsContentCacheSize: " << running_size; return running_size; }
diff --git a/chrome/browser/ash/extensions/install_limiter_factory.cc b/chrome/browser/ash/extensions/install_limiter_factory.cc index 951454f0..9e39e0e 100644 --- a/chrome/browser/ash/extensions/install_limiter_factory.cc +++ b/chrome/browser/ash/extensions/install_limiter_factory.cc
@@ -37,9 +37,10 @@ InstallLimiterFactory::~InstallLimiterFactory() = default; -KeyedService* InstallLimiterFactory::BuildServiceInstanceFor( +std::unique_ptr<KeyedService> +InstallLimiterFactory::BuildServiceInstanceForBrowserContext( content::BrowserContext* profile) const { - return new InstallLimiter(); + return std::make_unique<InstallLimiter>(); } } // namespace extensions
diff --git a/chrome/browser/ash/extensions/install_limiter_factory.h b/chrome/browser/ash/extensions/install_limiter_factory.h index c625a71..5dc9a13 100644 --- a/chrome/browser/ash/extensions/install_limiter_factory.h +++ b/chrome/browser/ash/extensions/install_limiter_factory.h
@@ -31,7 +31,7 @@ ~InstallLimiterFactory() override; // BrowserContextKeyedServiceFactory overrides: - KeyedService* BuildServiceInstanceFor( + std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( content::BrowserContext* profile) const override; };
diff --git a/chrome/browser/ash/file_manager/file_manager_jstest.cc b/chrome/browser/ash/file_manager/file_manager_jstest.cc index 2c95f19..39bd9ee 100644 --- a/chrome/browser/ash/file_manager/file_manager_jstest.cc +++ b/chrome/browser/ash/file_manager/file_manager_jstest.cc
@@ -352,7 +352,7 @@ } IN_PROC_BROWSER_TEST_F(FileManagerJsTest, ReducerUiEntries) { - RunTestURL("state/reducers/ui_entries_unittest.js"); + RunTestURL("state/ducks/ui_entries_unittest.js"); } IN_PROC_BROWSER_TEST_F(FileManagerJsTest, ReducerVolumes) {
diff --git a/chrome/browser/ash/multidevice_setup/auth_token_validator_factory.cc b/chrome/browser/ash/multidevice_setup/auth_token_validator_factory.cc index 2297aa0..da61708f5 100644 --- a/chrome/browser/ash/multidevice_setup/auth_token_validator_factory.cc +++ b/chrome/browser/ash/multidevice_setup/auth_token_validator_factory.cc
@@ -37,9 +37,10 @@ AuthTokenValidatorFactory::~AuthTokenValidatorFactory() = default; -KeyedService* AuthTokenValidatorFactory::BuildServiceInstanceFor( +std::unique_ptr<KeyedService> +AuthTokenValidatorFactory::BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const { - return new AuthTokenValidatorImpl( + return std::make_unique<AuthTokenValidatorImpl>( quick_unlock::QuickUnlockFactory::GetForProfile( Profile::FromBrowserContext(context))); }
diff --git a/chrome/browser/ash/multidevice_setup/auth_token_validator_factory.h b/chrome/browser/ash/multidevice_setup/auth_token_validator_factory.h index f3250d7..d563c9f 100644 --- a/chrome/browser/ash/multidevice_setup/auth_token_validator_factory.h +++ b/chrome/browser/ash/multidevice_setup/auth_token_validator_factory.h
@@ -34,7 +34,7 @@ ~AuthTokenValidatorFactory() override; // BrowserContextKeyedServiceFactory: - KeyedService* BuildServiceInstanceFor( + std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const override; };
diff --git a/chrome/browser/ash/multidevice_setup/multidevice_setup_client_factory.cc b/chrome/browser/ash/multidevice_setup/multidevice_setup_client_factory.cc index c55be4e..e8ba140 100644 --- a/chrome/browser/ash/multidevice_setup/multidevice_setup_client_factory.cc +++ b/chrome/browser/ash/multidevice_setup/multidevice_setup_client_factory.cc
@@ -122,12 +122,13 @@ return instance.get(); } -KeyedService* MultiDeviceSetupClientFactory::BuildServiceInstanceFor( +std::unique_ptr<KeyedService> +MultiDeviceSetupClientFactory::BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const { if (IsAllowedByPolicy(context)) { PA_LOG(INFO) << "Allowed by policy. Returning new MultiDeviceSetupClientHolder"; - return new MultiDeviceSetupClientHolder(context); + return std::make_unique<MultiDeviceSetupClientHolder>(context); } PA_LOG(INFO) << "NOT allowed by policy. Unable to return "
diff --git a/chrome/browser/ash/multidevice_setup/multidevice_setup_client_factory.h b/chrome/browser/ash/multidevice_setup/multidevice_setup_client_factory.h index 4197745c..91abc7b 100644 --- a/chrome/browser/ash/multidevice_setup/multidevice_setup_client_factory.h +++ b/chrome/browser/ash/multidevice_setup/multidevice_setup_client_factory.h
@@ -45,7 +45,7 @@ } // BrowserContextKeyedServiceFactory: - KeyedService* BuildServiceInstanceFor( + std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const override; bool ServiceIsNULLWhileTesting() const override; bool service_is_null_while_testing_ = true;
diff --git a/chrome/browser/ash/printing/cups_printers_manager_factory.cc b/chrome/browser/ash/printing/cups_printers_manager_factory.cc index 27aa1b6c..4afd80b 100644 --- a/chrome/browser/ash/printing/cups_printers_manager_factory.cc +++ b/chrome/browser/ash/printing/cups_printers_manager_factory.cc
@@ -47,7 +47,8 @@ return proxy_.get(); } -KeyedService* CupsPrintersManagerFactory::BuildServiceInstanceFor( +std::unique_ptr<KeyedService> +CupsPrintersManagerFactory::BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const { auto* profile = Profile::FromBrowserContext(context); // This condition still needs to be explicitly stated here despite having @@ -61,11 +62,12 @@ return nullptr; } - auto manager = CupsPrintersManager::Create(profile); + std::unique_ptr<CupsPrintersManager> manager = + CupsPrintersManager::Create(profile); if (ProfileHelper::IsPrimaryProfile(profile)) { proxy_->SetManager(manager.get()); } - return manager.release(); + return manager; } void CupsPrintersManagerFactory::BrowserContextShutdown(
diff --git a/chrome/browser/ash/printing/cups_printers_manager_factory.h b/chrome/browser/ash/printing/cups_printers_manager_factory.h index 862a5c919a7..b8a1832 100644 --- a/chrome/browser/ash/printing/cups_printers_manager_factory.h +++ b/chrome/browser/ash/printing/cups_printers_manager_factory.h
@@ -43,7 +43,7 @@ ~CupsPrintersManagerFactory() override; // BrowserContextKeyedServiceFactory overrides: - KeyedService* BuildServiceInstanceFor( + std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const override; void BrowserContextShutdown(content::BrowserContext* context) override; bool ServiceIsCreatedWithBrowserContext() const override;
diff --git a/chrome/browser/ash/printing/cups_proxy_service_manager_factory.cc b/chrome/browser/ash/printing/cups_proxy_service_manager_factory.cc index 9df2bd3..c5b413a 100644 --- a/chrome/browser/ash/printing/cups_proxy_service_manager_factory.cc +++ b/chrome/browser/ash/printing/cups_proxy_service_manager_factory.cc
@@ -37,7 +37,8 @@ CupsProxyServiceManagerFactory::~CupsProxyServiceManagerFactory() = default; -KeyedService* CupsProxyServiceManagerFactory::BuildServiceInstanceFor( +std::unique_ptr<KeyedService> +CupsProxyServiceManagerFactory::BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const { // Only create the service for the primary user. Profile* profile = Profile::FromBrowserContext(context); @@ -47,7 +48,7 @@ return nullptr; } - return new CupsProxyServiceManager(profile); + return std::make_unique<CupsProxyServiceManager>(profile); } bool CupsProxyServiceManagerFactory::ServiceIsCreatedWithBrowserContext()
diff --git a/chrome/browser/ash/printing/cups_proxy_service_manager_factory.h b/chrome/browser/ash/printing/cups_proxy_service_manager_factory.h index ff273e7c..ef896599 100644 --- a/chrome/browser/ash/printing/cups_proxy_service_manager_factory.h +++ b/chrome/browser/ash/printing/cups_proxy_service_manager_factory.h
@@ -34,7 +34,7 @@ ~CupsProxyServiceManagerFactory() override; // BrowserContextKeyedServiceFactory overrides: - KeyedService* BuildServiceInstanceFor( + std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const override; bool ServiceIsCreatedWithBrowserContext() const override; bool ServiceIsNULLWhileTesting() const override;
diff --git a/chrome/browser/ash/printing/history/print_job_reporting_service_factory.cc b/chrome/browser/ash/printing/history/print_job_reporting_service_factory.cc index 966ddc5..eab7d4a 100644 --- a/chrome/browser/ash/printing/history/print_job_reporting_service_factory.cc +++ b/chrome/browser/ash/printing/history/print_job_reporting_service_factory.cc
@@ -35,11 +35,10 @@ PrintJobReportingServiceFactory::~PrintJobReportingServiceFactory() = default; -KeyedService* PrintJobReportingServiceFactory::BuildServiceInstanceFor( +std::unique_ptr<KeyedService> +PrintJobReportingServiceFactory::BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const { - auto reporting_service = PrintJobReportingService::Create(); - - return reporting_service.release(); + return PrintJobReportingService::Create(); } bool PrintJobReportingServiceFactory::ServiceIsNULLWhileTesting() const {
diff --git a/chrome/browser/ash/printing/history/print_job_reporting_service_factory.h b/chrome/browser/ash/printing/history/print_job_reporting_service_factory.h index 49b6dd2..965ee772 100644 --- a/chrome/browser/ash/printing/history/print_job_reporting_service_factory.h +++ b/chrome/browser/ash/printing/history/print_job_reporting_service_factory.h
@@ -37,7 +37,7 @@ ~PrintJobReportingServiceFactory() override; // BrowserContextKeyedServiceFactory: - KeyedService* BuildServiceInstanceFor( + std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const override; bool ServiceIsNULLWhileTesting() const override; };
diff --git a/chrome/browser/ash/printing/oauth2/authorization_zones_manager_factory.cc b/chrome/browser/ash/printing/oauth2/authorization_zones_manager_factory.cc index d025528..575d907 100644 --- a/chrome/browser/ash/printing/oauth2/authorization_zones_manager_factory.cc +++ b/chrome/browser/ash/printing/oauth2/authorization_zones_manager_factory.cc
@@ -39,10 +39,11 @@ AuthorizationZonesManagerFactory::~AuthorizationZonesManagerFactory() = default; -KeyedService* AuthorizationZonesManagerFactory::BuildServiceInstanceFor( +std::unique_ptr<KeyedService> +AuthorizationZonesManagerFactory::BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const { - return AuthorizationZonesManager::Create(Profile::FromBrowserContext(context)) - .release(); + return AuthorizationZonesManager::Create( + Profile::FromBrowserContext(context)); } } // namespace oauth2
diff --git a/chrome/browser/ash/printing/oauth2/authorization_zones_manager_factory.h b/chrome/browser/ash/printing/oauth2/authorization_zones_manager_factory.h index c8e157f1..94e45a2 100644 --- a/chrome/browser/ash/printing/oauth2/authorization_zones_manager_factory.h +++ b/chrome/browser/ash/printing/oauth2/authorization_zones_manager_factory.h
@@ -36,7 +36,7 @@ ~AuthorizationZonesManagerFactory() override; // BrowserContextKeyedServiceFactory overrides: - KeyedService* BuildServiceInstanceFor( + std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const override; };
diff --git a/chrome/browser/ash/printing/print_management/printing_manager_factory.cc b/chrome/browser/ash/printing/print_management/printing_manager_factory.cc index d7b2858..e3fcf3e 100644 --- a/chrome/browser/ash/printing/print_management/printing_manager_factory.cc +++ b/chrome/browser/ash/printing/print_management/printing_manager_factory.cc
@@ -53,10 +53,10 @@ PrintingManagerFactory::~PrintingManagerFactory() = default; // static -KeyedService* PrintingManagerFactory::BuildInstanceFor( +std::unique_ptr<KeyedService> PrintingManagerFactory::BuildInstanceFor( content::BrowserContext* context) { Profile* profile = Profile::FromBrowserContext(context); - return new PrintingManager( + return std::make_unique<PrintingManager>( PrintJobHistoryServiceFactory::GetForBrowserContext(context), HistoryServiceFactory::GetForProfile(profile, ServiceAccessType::EXPLICIT_ACCESS), @@ -88,7 +88,8 @@ std::make_unique<ash::print_management::PrintManagementDelegateImpl>()); } -KeyedService* PrintingManagerFactory::BuildServiceInstanceFor( +std::unique_ptr<KeyedService> +PrintingManagerFactory::BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const { return BuildInstanceFor(context); }
diff --git a/chrome/browser/ash/printing/print_management/printing_manager_factory.h b/chrome/browser/ash/printing/print_management/printing_manager_factory.h index b3166cf..0c4403f4 100644 --- a/chrome/browser/ash/printing/print_management/printing_manager_factory.h +++ b/chrome/browser/ash/printing/print_management/printing_manager_factory.h
@@ -33,7 +33,8 @@ public: static PrintingManager* GetForProfile(Profile* profile); static PrintingManagerFactory* GetInstance(); - static KeyedService* BuildInstanceFor(content::BrowserContext* profile); + static std::unique_ptr<KeyedService> BuildInstanceFor( + content::BrowserContext* profile); static void MaybeBindPrintManagementForWebUI( Profile* profile, mojo::PendingReceiver< @@ -52,7 +53,7 @@ PrintingManagerFactory& operator=(const PrintingManagerFactory&) = delete; // BrowserContextKeyedServiceFactory: - KeyedService* BuildServiceInstanceFor( + std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const override; void RegisterProfilePrefs( user_prefs::PrefRegistrySyncable* registry) override;
diff --git a/chrome/browser/ash/printing/print_management/printing_manager_factory_unittest.cc b/chrome/browser/ash/printing/print_management/printing_manager_factory_unittest.cc index 25a8427..7270f6e5 100644 --- a/chrome/browser/ash/printing/print_management/printing_manager_factory_unittest.cc +++ b/chrome/browser/ash/printing/print_management/printing_manager_factory_unittest.cc
@@ -23,8 +23,7 @@ std::unique_ptr<KeyedService> BuildPrintingManager( content::BrowserContext* context) { - return std::unique_ptr<KeyedService>( - PrintingManagerFactory::BuildInstanceFor(context)); + return PrintingManagerFactory::BuildInstanceFor(context); } std::unique_ptr<Profile> CreateProfile(std::string file_path) {
diff --git a/chrome/browser/extensions/api/settings_private/settings_private_event_router.cc b/chrome/browser/extensions/api/settings_private/settings_private_event_router.cc index 41813714..a8b7d850 100644 --- a/chrome/browser/extensions/api/settings_private/settings_private_event_router.cc +++ b/chrome/browser/extensions/api/settings_private/settings_private_event_router.cc
@@ -167,9 +167,9 @@ event_router->BroadcastEvent(std::move(extension_event)); } -SettingsPrivateEventRouter* SettingsPrivateEventRouter::Create( +std::unique_ptr<SettingsPrivateEventRouter> SettingsPrivateEventRouter::Create( content::BrowserContext* context) { - return new SettingsPrivateEventRouter(context); + return std::make_unique<SettingsPrivateEventRouter>(context); } } // namespace extensions
diff --git a/chrome/browser/extensions/api/settings_private/settings_private_event_router.h b/chrome/browser/extensions/api/settings_private/settings_private_event_router.h index 7d2c5543..a16221f 100644 --- a/chrome/browser/extensions/api/settings_private/settings_private_event_router.h +++ b/chrome/browser/extensions/api/settings_private/settings_private_event_router.h
@@ -35,9 +35,10 @@ public EventRouter::Observer, public settings_private::GeneratedPref::Observer { public: - static SettingsPrivateEventRouter* Create( + static std::unique_ptr<SettingsPrivateEventRouter> Create( content::BrowserContext* browser_context); + explicit SettingsPrivateEventRouter(content::BrowserContext* context); SettingsPrivateEventRouter(const SettingsPrivateEventRouter&) = delete; SettingsPrivateEventRouter& operator=(const SettingsPrivateEventRouter&) = delete; @@ -50,8 +51,6 @@ content::BrowserContext* context_for_test() { return context_; } protected: - explicit SettingsPrivateEventRouter(content::BrowserContext* context); - // KeyedService overrides: void Shutdown() override;
diff --git a/chrome/browser/extensions/api/settings_private/settings_private_event_router_factory.cc b/chrome/browser/extensions/api/settings_private/settings_private_event_router_factory.cc index bf49f8d..24c742f 100644 --- a/chrome/browser/extensions/api/settings_private/settings_private_event_router_factory.cc +++ b/chrome/browser/extensions/api/settings_private/settings_private_event_router_factory.cc
@@ -46,7 +46,8 @@ SettingsPrivateEventRouterFactory::~SettingsPrivateEventRouterFactory() = default; -KeyedService* SettingsPrivateEventRouterFactory::BuildServiceInstanceFor( +std::unique_ptr<KeyedService> +SettingsPrivateEventRouterFactory::BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const { return SettingsPrivateEventRouter::Create(context); }
diff --git a/chrome/browser/extensions/api/settings_private/settings_private_event_router_factory.h b/chrome/browser/extensions/api/settings_private/settings_private_event_router_factory.h index a16216ac..d831a361 100644 --- a/chrome/browser/extensions/api/settings_private/settings_private_event_router_factory.h +++ b/chrome/browser/extensions/api/settings_private/settings_private_event_router_factory.h
@@ -42,7 +42,7 @@ ~SettingsPrivateEventRouterFactory() override; // BrowserContextKeyedServiceFactory: - KeyedService* BuildServiceInstanceFor( + std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( content::BrowserContext* profile) const override; };
diff --git a/chrome/browser/extensions/chrome_app_icon_service_factory.cc b/chrome/browser/extensions/chrome_app_icon_service_factory.cc index f6921e9..864a7cd 100644 --- a/chrome/browser/extensions/chrome_app_icon_service_factory.cc +++ b/chrome/browser/extensions/chrome_app_icon_service_factory.cc
@@ -36,9 +36,10 @@ ChromeAppIconServiceFactory::~ChromeAppIconServiceFactory() = default; -KeyedService* ChromeAppIconServiceFactory::BuildServiceInstanceFor( +std::unique_ptr<KeyedService> +ChromeAppIconServiceFactory::BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const { - return new ChromeAppIconService(context); + return std::make_unique<ChromeAppIconService>(context); } } // namespace extensions
diff --git a/chrome/browser/extensions/chrome_app_icon_service_factory.h b/chrome/browser/extensions/chrome_app_icon_service_factory.h index 477d273..bfec8cf 100644 --- a/chrome/browser/extensions/chrome_app_icon_service_factory.h +++ b/chrome/browser/extensions/chrome_app_icon_service_factory.h
@@ -31,7 +31,7 @@ ChromeAppIconServiceFactory(); ~ChromeAppIconServiceFactory() override; - KeyedService* BuildServiceInstanceFor( + std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const override; };
diff --git a/chrome/browser/feed/android/BUILD.gn b/chrome/browser/feed/android/BUILD.gn index 2d43ffc..7b65c8f 100644 --- a/chrome/browser/feed/android/BUILD.gn +++ b/chrome/browser/feed/android/BUILD.gn
@@ -25,6 +25,7 @@ "java/src/org/chromium/chrome/browser/feed/FeedProcessScopeDependencyProvider.java", "java/src/org/chromium/chrome/browser/feed/FeedReliabilityLogger.java", "java/src/org/chromium/chrome/browser/feed/FeedReliabilityLoggingBridge.java", + "java/src/org/chromium/chrome/browser/feed/FeedResourceFetcher.java", "java/src/org/chromium/chrome/browser/feed/FeedScrollState.java", "java/src/org/chromium/chrome/browser/feed/FeedServiceBridge.java", "java/src/org/chromium/chrome/browser/feed/FeedServiceDependencyProviderFactory.java",
diff --git a/chrome/browser/feed/android/feed_surface_renderer_bridge.cc b/chrome/browser/feed/android/feed_surface_renderer_bridge.cc index 26c08a2..1e5babc 100644 --- a/chrome/browser/feed/android/feed_surface_renderer_bridge.cc +++ b/chrome/browser/feed/android/feed_surface_renderer_bridge.cc
@@ -46,6 +46,23 @@ return feed::SurfaceId::FromUnsafeValue(surface_id); } +ScopedJavaLocalRef<jobject> ToJava(JNIEnv* env, + const NetworkResponse& response) { + return Java_NetworkResponse_Constructor( + env, response.status_code == 200, response.status_code, + base::android::ToJavaArrayOfStrings( + env, response.response_header_names_and_values), + base::android::ToJavaByteArray( + env, reinterpret_cast<const uint8_t*>(response.response_bytes.data()), + response.response_bytes.size())); +} + +void OnFetchResourceFinished(JNIEnv* env, + const JavaRef<jobject>& callback, + NetworkResponse response) { + base::android::RunObjectCallbackAndroid(callback, ToJava(env, response)); +} + } // namespace static jlong JNI_FeedSurfaceRendererBridge_Init( @@ -167,6 +184,30 @@ ScopedJavaGlobalRef<jobject>(callback_obj))); } +void FeedSurfaceRendererBridge::FetchResource( + JNIEnv* env, + const JavaParamRef<jobject>& j_url, + const JavaParamRef<jstring>& j_method, + const JavaParamRef<jobjectArray>& j_header_name_and_values, + const JavaParamRef<jbyteArray>& j_post_data, + const base::android::JavaParamRef<jobject>& callback_obj) { + if (!feed_stream_api_) { + return; + } + std::unique_ptr<GURL> url = url::GURLAndroid::ToNativeGURL(env, j_url); + std::vector<std::string> header_name_and_values; + AppendJavaStringArrayToStringVector(env, j_header_name_and_values, + &header_name_and_values); + std::string post_data; + base::android::JavaByteArrayToString(env, j_post_data, &post_data); + feed_stream_api_->FetchResource( + url ? *url : GURL(), + base::android::ConvertJavaStringToUTF8(env, j_method), + header_name_and_values, post_data, + base::BindOnce(&OnFetchResourceFinished, env, + ScopedJavaGlobalRef<jobject>(callback_obj))); +} + static void JNI_FeedSurfaceRendererBridge_ProcessThereAndBackAgain( JNIEnv* env, const JavaParamRef<jbyteArray>& data,
diff --git a/chrome/browser/feed/android/feed_surface_renderer_bridge.h b/chrome/browser/feed/android/feed_surface_renderer_bridge.h index 87e901b..fa8f81ae 100644 --- a/chrome/browser/feed/android/feed_surface_renderer_bridge.h +++ b/chrome/browser/feed/android/feed_surface_renderer_bridge.h
@@ -52,6 +52,13 @@ void ManualRefresh(JNIEnv* env, const base::android::JavaParamRef<jobject>& callback_obj); + void FetchResource( + JNIEnv* env, + const base::android::JavaParamRef<jobject>& j_url, + const base::android::JavaParamRef<jstring>& j_method, + const base::android::JavaParamRef<jobjectArray>& j_header_name_and_values, + const base::android::JavaParamRef<jbyteArray>& j_post_data, + const base::android::JavaParamRef<jobject>& callback_obj); void SurfaceOpened(JNIEnv* env); void SurfaceClosed(JNIEnv* env);
diff --git a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/FeedResourceFetcher.java b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/FeedResourceFetcher.java new file mode 100644 index 0000000..20b4983 --- /dev/null +++ b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/FeedResourceFetcher.java
@@ -0,0 +1,88 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.feed; + +import androidx.annotation.Nullable; + +import org.chromium.base.annotations.CalledByNative; +import org.chromium.base.annotations.JNINamespace; +import org.chromium.chrome.browser.feed.FeedSurfaceRendererBridge.NetworkResponse; +import org.chromium.chrome.browser.xsurface.feed.ResourceFetcher; +import org.chromium.chrome.browser.xsurface.feed.ResourceFetcher.Header; +import org.chromium.chrome.browser.xsurface.feed.ResourceFetcher.Request; +import org.chromium.chrome.browser.xsurface.feed.ResourceFetcher.Response; +import org.chromium.chrome.browser.xsurface.feed.ResourceFetcher.ResponseCallback; +import org.chromium.url.GURL; + +import java.util.ArrayList; +import java.util.List; + +/** + * Implementation of ResourceFetcher methods. + */ +public class FeedResourceFetcher implements ResourceFetcher { + @JNINamespace("feed::android") + public static class FeedResponse implements Response { + private final @Nullable byte[] mRawData; + private final boolean mSuccess; + private final int mStatusCode; + private final List<Header> mHeaders; + + public FeedResponse( + boolean success, int statusCode, List<Header> headers, @Nullable byte[] rawData) { + mSuccess = success; + mStatusCode = statusCode; + mHeaders = headers; + mRawData = rawData; + } + + @Override + public boolean getSuccess() { + return mSuccess; + } + + @Override + public int getStatusCode() { + return mStatusCode; + } + + @Override + public List<Header> getHeaders() { + return mHeaders; + } + + @Override + public @Nullable byte[] getRawData() { + return mRawData; + } + + @CalledByNative + static FeedResponse create( + boolean success, int statusCode, List<Header> headers, @Nullable byte[] rawData) { + return new FeedResponse(success, statusCode, headers, rawData); + } + } + + private FeedSurfaceRendererBridge mBridge; + + public FeedResourceFetcher(FeedSurfaceRendererBridge bridge) { + mBridge = bridge; + } + + @Override + public void fetch(Request request, ResponseCallback responseCallback) { + List<String> headerNamesAndValues = new ArrayList<String>(request.headers.size() * 2); + for (Header header : request.headers) { + headerNamesAndValues.add(header.name); + headerNamesAndValues.add(header.value); + } + mBridge.fetchResource(new GURL(request.uri), request.method, + headerNamesAndValues.toArray(new String[headerNamesAndValues.size()]), + request.postData, (NetworkResponse response) -> { + responseCallback.onResponse(new FeedResponse( + response.success, response.statusCode, null, response.rawData)); + }); + } +}
diff --git a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/FeedStream.java b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/FeedStream.java index ab23592..a8b6e119 100644 --- a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/FeedStream.java +++ b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/FeedStream.java
@@ -54,6 +54,7 @@ import org.chromium.chrome.browser.xsurface.feed.FeedActionsHandler; import org.chromium.chrome.browser.xsurface.feed.FeedSurfaceScope; import org.chromium.chrome.browser.xsurface.feed.FeedUserInteractionReliabilityLogger.ClosedReason; +import org.chromium.chrome.browser.xsurface.feed.ResourceFetcher; import org.chromium.chrome.browser.xsurface.feed.StreamType; import org.chromium.components.browser_ui.bottomsheet.BottomSheetContent; import org.chromium.components.browser_ui.bottomsheet.BottomSheetController; @@ -549,6 +550,11 @@ mBridge.reportOtherUserAction(FeedUserActionType.NON_SWIPE_MANUAL_REFRESH); mStreamsMediator.refreshStream(); } + + @Override + public ResourceFetcher getAsyncDataFetcher() { + return new FeedResourceFetcher(mBridge); + } } private class RotationObserver implements DisplayAndroid.DisplayAndroidObserver {
diff --git a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/FeedSurfaceRendererBridge.java b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/FeedSurfaceRendererBridge.java index bf587dd..02c24576 100644 --- a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/FeedSurfaceRendererBridge.java +++ b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/FeedSurfaceRendererBridge.java
@@ -4,6 +4,7 @@ package org.chromium.chrome.browser.feed; +import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; import org.chromium.base.Callback; @@ -39,6 +40,22 @@ } } + public static class NetworkResponse { + public boolean success; + public int statusCode; + public String[] headerNameAndValues; + public @Nullable byte[] rawData; + + @CalledByNative("NetworkResponse") + public NetworkResponse(boolean success, int statusCode, String[] headerNameAndValues, + @Nullable byte[] rawData) { + this.success = success; + this.statusCode = statusCode; + this.headerNameAndValues = headerNameAndValues; + this.rawData = rawData; + } + } + public FeedSurfaceRendererBridge(Renderer renderer, FeedReliabilityLoggingBridge reliabilityLoggingBridge, @StreamKind int streamKind, SingleWebFeedParameters webFeedParameters) { @@ -108,6 +125,16 @@ } FeedSurfaceRendererBridgeJni.get().manualRefresh(mNativeSurfaceRenderer, callback); } + void fetchResource(GURL url, String method, String[] headerNameAndValues, byte[] postData, + Callback<NetworkResponse> callback) { + // Cancel if destroyed. + if (mRenderer == null) { + return; + } + FeedSurfaceRendererBridgeJni.get().fetchResource( + mNativeSurfaceRenderer, url, method, headerNameAndValues, postData, callback); + } + void surfaceOpened() { // Cancel if destroyed. if (mRenderer == null) { @@ -122,7 +149,6 @@ } FeedSurfaceRendererBridgeJni.get().surfaceClosed(mNativeSurfaceRenderer); } - // // Methods which may be called after destroy(). // @@ -210,6 +236,8 @@ void destroy(long nativeFeedSurfaceRendererBridge); void loadMore(long nativeFeedSurfaceRendererBridge, Callback<Boolean> callback); void manualRefresh(long nativeFeedSurfaceRendererBridge, Callback<Boolean> callback); + void fetchResource(long nativeFeedSurfaceRendererBridge, GURL url, String method, + String[] headerNameAndValues, byte[] postData, Callback<NetworkResponse> callback); int getSurfaceId(long nativeFeedSurfaceRendererBridge); void surfaceOpened(long nativeFeedSurfaceRendererBridge); void surfaceClosed(long nativeFeedSurfaceRendererBridge);
diff --git a/chrome/browser/feedback/show_feedback_page_lacros_browsertest.cc b/chrome/browser/feedback/show_feedback_page_lacros_browsertest.cc index 55b8719..22c4abbe 100644 --- a/chrome/browser/feedback/show_feedback_page_lacros_browsertest.cc +++ b/chrome/browser/feedback/show_feedback_page_lacros_browsertest.cc
@@ -20,16 +20,13 @@ protected: void SetUp() override { - // TODO(crbug.com/1473375): Check against the exact ash version with ash - // browser window API support in crosapi::mojom::TestController once the - // implementation cl has landed. - if (IsRunningAgainstOlderAsh()) { + if (GetAshChromeVersion() < base::Version({118, 0, 5962})) { // For the older ash version without the ash browser window API // support in crosapi::mojom::TestController, we can't verify and close // feedback SWA in ash. Therefore, it still needs to run against the // unique ash. - // TODO(crbug/1446083): Remove the unique ash code once ash browser window - // API is supported in stable ash. + // TODO(crbug/1446083): Remove the unique ash code once ash stable + // version >= 118.0.5962.0. StartUniqueAshChrome( {}, {}, {}, "crbug.com/1446083 The test leaves Ash windows behind"); }
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index 6d8ac2a1..207e3581 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -667,11 +667,6 @@ "expiry_milestone": 120 }, { - "name": "autofill-enable-virtual-card", - "owners": [ "siyua", "jsaul@google.com", "aneeshali@google.com" ], - "expiry_milestone": 112 - }, - { "name": "autofill-enable-virtual-card-fido-enrollment", "owners": [ "siyua", "jsaul@google.com"], "expiry_milestone": 120 @@ -1877,6 +1872,11 @@ "expiry_milestone": 120 }, { + "name": "draw-immediately-when-interactive", + "owners": [ "vollick" ], + "expiry_milestone": 125 + }, + { "name": "draw-predicted-ink-point", "owners": [ "joalmei@microsoft.com" ], "expiry_milestone": 98 @@ -7164,11 +7164,6 @@ "expiry_milestone": 122 }, { - "name": "screen-saver-preview", - "owners": [ "safarli", "assistive-eng@google.com" ], - "expiry_milestone": 116 - }, - { "name": "screen-time-integration-ios", "owners": [ "edchin", "bling-flags@google.com" ], "expiry_milestone": 92
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index df53300..a32e6b2 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -548,12 +548,6 @@ "card is FIDO eligible the user will be prompted to register the virtual " "card into FIDO."; -const char kAutofillEnableVirtualCardName[] = - "Offer to use cloud token virtual card in Autofill"; -const char kAutofillEnableVirtualCardDescription[] = - "When enabled, if all requirements are met, Autofill will offer to use " - "virtual credit cards in form filling."; - const char kAutofillEnableNewSaveCardBubbleUiName[] = "Update UI messaging and banner image for credit card upload save"; const char kAutofillEnableNewSaveCardBubbleUiDescription[] = @@ -1713,6 +1707,11 @@ const char kFillingAcrossAffiliatedWebsitesDescription[] = "Enables filling password on a website when there is saved " "password on affiliated website."; +const char kDrawImmediatelyWhenInteractiveName[] = + "Enable Immediate Draw When Interactive"; +const char kDrawImmediatelyWhenInteractiveDescription[] = + "Causes viz to activate and draw frames immediately during a touch " + "interaction or scroll."; #endif const char kFillingAcrossGroupedSitesName[] = @@ -3011,11 +3010,6 @@ const char kScreenSaverDurationDescription[] = "Allow users to customize screen saver running time."; -const char kScreenSaverPreviewName[] = "Screen saver preview"; -const char kScreenSaverPreviewDescription[] = - "Enables the screen saver preview feature which allows the users to " - "preview current screen saver."; - const char kScrollableTabStripFlagId[] = "scrollable-tabstrip"; const char kScrollableTabStripName[] = "Tab Scrolling"; const char kScrollableTabStripDescription[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index e7c04e8..17fd2931 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -313,9 +313,6 @@ extern const char kAutofillEnableVirtualCardFidoEnrollmentName[]; extern const char kAutofillEnableVirtualCardFidoEnrollmentDescription[]; -extern const char kAutofillEnableVirtualCardName[]; -extern const char kAutofillEnableVirtualCardDescription[]; - extern const char kAutofillEnableNewSaveCardBubbleUiName[]; extern const char kAutofillEnableNewSaveCardBubbleUiDescription[]; @@ -966,6 +963,9 @@ #if BUILDFLAG(IS_ANDROID) extern const char kFillingAcrossAffiliatedWebsitesName[]; extern const char kFillingAcrossAffiliatedWebsitesDescription[]; + +extern const char kDrawImmediatelyWhenInteractiveName[]; +extern const char kDrawImmediatelyWhenInteractiveDescription[]; #endif extern const char kFillingAcrossGroupedSitesName[]; @@ -1722,9 +1722,6 @@ extern const char kScreenSaverDurationName[]; extern const char kScreenSaverDurationDescription[]; -extern const char kScreenSaverPreviewName[]; -extern const char kScreenSaverPreviewDescription[]; - extern const char kScrollableTabStripFlagId[]; extern const char kScrollableTabStripName[]; extern const char kScrollableTabStripDescription[];
diff --git a/chrome/browser/ip_protection/blind_sign_http_impl.cc b/chrome/browser/ip_protection/blind_sign_http_impl.cc index a30e296..362a739 100644 --- a/chrome/browser/ip_protection/blind_sign_http_impl.cc +++ b/chrome/browser/ip_protection/blind_sign_http_impl.cc
@@ -9,6 +9,7 @@ #include "base/strings/strcat.h" #include "base/strings/string_split.h" #include "base/strings/string_util.h" +#include "net/base/features.h" #include "services/network/public/cpp/resource_request.h" #include "services/network/public/cpp/shared_url_loader_factory.h" #include "services/network/public/cpp/simple_url_loader.h" @@ -57,7 +58,11 @@ BlindSignHttpImpl::BlindSignHttpImpl( scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) : url_loader_factory_(std::move(url_loader_factory)), - ip_protection_server_url_(BlindSignHttpImpl::kIpProtectionServerUrl) { + ip_protection_server_url_(net::features::kIpPrivacyTokenServer.Get()), + ip_protection_server_get_initial_data_path_( + net::features::kIpPrivacyTokenServerGetInitialDataPath.Get()), + ip_protection_server_get_tokens_path_( + net::features::kIpPrivacyTokenServerGetTokensPath.Get()) { CHECK(url_loader_factory_); } @@ -72,18 +77,24 @@ GURL::Replacements replacements; switch (request_type) { case quiche::BlindSignHttpRequestType::kGetInitialData: - replacements.SetPathStr(kIpProtectionServerGetInitialDataPath); + replacements.SetPathStr(ip_protection_server_get_initial_data_path_); break; case quiche::BlindSignHttpRequestType::kAuthAndSign: - replacements.SetPathStr(kIpProtectionServerAuthAndSignPath); + replacements.SetPathStr(ip_protection_server_get_tokens_path_); break; case quiche::BlindSignHttpRequestType::kUnknown: NOTREACHED_NORETURN(); } + GURL request_url = ip_protection_server_url_.ReplaceComponents(replacements); + if (!request_url.is_valid()) { + std::move(callback_)( + absl::InternalError("Invalid IP Protection Token URL")); + return; + } + auto resource_request = std::make_unique<network::ResourceRequest>(); - resource_request->url = - ip_protection_server_url_.ReplaceComponents(replacements); + resource_request->url = std::move(request_url); resource_request->method = net::HttpRequestHeaders::kPostMethod; resource_request->credentials_mode = network::mojom::CredentialsMode::kOmit; resource_request->headers.SetHeader(
diff --git a/chrome/browser/ip_protection/blind_sign_http_impl.h b/chrome/browser/ip_protection/blind_sign_http_impl.h index 9625cbd..aa567c3 100644 --- a/chrome/browser/ip_protection/blind_sign_http_impl.h +++ b/chrome/browser/ip_protection/blind_sign_http_impl.h
@@ -18,14 +18,6 @@ } // namespace network class BlindSignHttpImpl : public quiche::BlindSignHttpInterface { public: - // TODO(https://crbug.com/1444621): Make these configurable via Finch. - static constexpr char kIpProtectionServerUrl[] = - "https://autopush-phosphor-pa.sandbox.googleapis.com"; - static constexpr char kIpProtectionServerGetInitialDataPath[] = - "/v1/getInitialData"; - static constexpr char kIpProtectionServerAuthAndSignPath[] = - "/v1/authWithHeaderCreds"; - explicit BlindSignHttpImpl( scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory); ~BlindSignHttpImpl() override; @@ -42,6 +34,8 @@ quiche::BlindSignHttpCallback callback_; const GURL ip_protection_server_url_; + const std::string ip_protection_server_get_initial_data_path_; + const std::string ip_protection_server_get_tokens_path_; base::WeakPtrFactory<BlindSignHttpImpl> weak_ptr_factory_{this}; };
diff --git a/chrome/browser/ip_protection/blind_sign_http_impl_unittest.cc b/chrome/browser/ip_protection/blind_sign_http_impl_unittest.cc index 85a790e5..1797b96 100644 --- a/chrome/browser/ip_protection/blind_sign_http_impl_unittest.cc +++ b/chrome/browser/ip_protection/blind_sign_http_impl_unittest.cc
@@ -5,11 +5,13 @@ #include "base/strings/strcat.h" #include "base/test/bind.h" +#include "base/test/scoped_feature_list.h" #include "base/test/task_environment.h" #include "base/test/test_future.h" #include "chrome/browser/signin/identity_test_environment_profile_adaptor.h" #include "chrome/test/base/testing_profile.h" #include "chrome/test/base/testing_profile_manager.h" +#include "net/base/features.h" #include "net/traffic_annotation/network_traffic_annotation_test_helper.h" #include "services/network/public/cpp/resource_request.h" #include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h" @@ -23,6 +25,14 @@ http_fetcher_ = std::make_unique<BlindSignHttpImpl>( base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>( &test_url_loader_factory_)); + token_server_get_initial_data_url_ = GURL(base::StrCat( + {net::features::kIpPrivacyTokenServer.Get(), + net::features::kIpPrivacyTokenServerGetInitialDataPath.Get()})); + ASSERT_TRUE(token_server_get_initial_data_url_.is_valid()); + token_server_get_tokens_url_ = GURL(base::StrCat( + {net::features::kIpPrivacyTokenServer.Get(), + net::features::kIpPrivacyTokenServerGetTokensPath.Get()})); + ASSERT_TRUE(token_server_get_tokens_url_.is_valid()); } base::test::TaskEnvironment task_environment_; @@ -30,6 +40,8 @@ std::unique_ptr<BlindSignHttpImpl> http_fetcher_; std::unique_ptr<IdentityTestEnvironmentProfileAdaptor> identity_test_env_adaptor_; + GURL token_server_get_initial_data_url_; + GURL token_server_get_tokens_url_; }; TEST_F(BlindSignHttpImplTest, DoRequestSendsCorrectRequest) { @@ -40,11 +52,8 @@ // Set up the response to return from the mock. auto head = network::mojom::URLResponseHead::New(); std::string response_body = "Response body"; - GURL test_url = GURL( - base::StrCat({BlindSignHttpImpl::kIpProtectionServerUrl, - BlindSignHttpImpl::kIpProtectionServerGetInitialDataPath})); test_url_loader_factory_.AddResponse( - test_url, std::move(head), response_body, + token_server_get_initial_data_url_, std::move(head), response_body, network::URLLoaderCompletionStatus(net::OK)); base::test::TestFuture<absl::StatusOr<quiche::BlindSignHttpResponse>> @@ -75,11 +84,8 @@ // Mock no response from Authentication Server (such as a network error). std::string response_body; auto head = network::mojom::URLResponseHead::New(); - GURL test_url = GURL( - base::StrCat({BlindSignHttpImpl::kIpProtectionServerUrl, - BlindSignHttpImpl::kIpProtectionServerAuthAndSignPath})); test_url_loader_factory_.AddResponse( - test_url, std::move(head), response_body, + token_server_get_tokens_url_, std::move(head), response_body, network::URLLoaderCompletionStatus(net::ERR_FAILED)); base::test::TestFuture<absl::StatusOr<quiche::BlindSignHttpResponse>> @@ -99,6 +105,41 @@ EXPECT_EQ(absl::StatusCode::kInternal, result.status().code()); } +TEST_F(BlindSignHttpImplTest, DoRequestInvalidFinchParametersFailsGracefully) { + std::map<std::string, std::string> parameters; + parameters["IpPrivacyTokenServer"] = "<(^_^)>"; + parameters["IpPrivacyTokenServerGetInitialDataPath"] = "(>_<)"; + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitAndEnableFeatureWithParameters( + net::features::kEnableIpProtectionProxy, std::move(parameters)); + + // Create a new BlindSignHttpImpl for this test so that the new FeatureParams + // get used. + std::unique_ptr<BlindSignHttpImpl> http_fetcher = + std::make_unique<BlindSignHttpImpl>( + base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>( + &test_url_loader_factory_)); + + auto request_type = quiche::BlindSignHttpRequestType::kGetInitialData; + std::string authorization_header = "token"; + std::string body = "body"; + + base::test::TestFuture<absl::StatusOr<quiche::BlindSignHttpResponse>> + result_future; + auto callback = + [&result_future](absl::StatusOr<quiche::BlindSignHttpResponse> response) { + result_future.SetValue(std::move(response)); + }; + + http_fetcher->DoRequest(request_type, authorization_header, body, + std::move(callback)); + + absl::StatusOr<quiche::BlindSignHttpResponse> result = result_future.Get(); + + EXPECT_EQ("Invalid IP Protection Token URL", result.status().message()); + EXPECT_EQ(absl::StatusCode::kInternal, result.status().code()); +} + TEST_F(BlindSignHttpImplTest, DoRequestHttpFailureStatus) { auto request_type = quiche::BlindSignHttpRequestType::kAuthAndSign; std::string authorization_header = "token"; @@ -107,11 +148,8 @@ // Mock a non-200 HTTP response from Authentication Server. std::string response_body; auto head = network::mojom::URLResponseHead::New(); - GURL test_url = GURL( - base::StrCat({BlindSignHttpImpl::kIpProtectionServerUrl, - BlindSignHttpImpl::kIpProtectionServerAuthAndSignPath})); - test_url_loader_factory_.AddResponse(test_url.spec(), response_body, - net::HTTP_BAD_REQUEST); + test_url_loader_factory_.AddResponse(token_server_get_tokens_url_.spec(), + response_body, net::HTTP_BAD_REQUEST); base::test::TestFuture<absl::StatusOr<quiche::BlindSignHttpResponse>> result_future;
diff --git a/chrome/browser/lacros/lacros_extension_apps_publisher.cc b/chrome/browser/lacros/lacros_extension_apps_publisher.cc index 10a33a7..7eff9752 100644 --- a/chrome/browser/lacros/lacros_extension_apps_publisher.cc +++ b/chrome/browser/lacros/lacros_extension_apps_publisher.cc
@@ -17,13 +17,18 @@ #include "chrome/browser/extensions/extension_ui_util.h" #include "chrome/browser/extensions/launch_util.h" #include "chrome/browser/lacros/lacros_extensions_util.h" +#include "chrome/browser/media/webrtc/media_capture_devices_dispatcher.h" #include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/ui/lacros/window_utility.h" +#include "chrome/browser/web_applications/web_app_tab_helper.h" #include "chromeos/crosapi/mojom/app_window_tracker.mojom.h" #include "chromeos/lacros/lacros_service.h" +#include "components/app_constants/constants.h" +#include "components/services/app_service/public/cpp/app_capability_access_cache.h" #include "components/services/app_service/public/cpp/app_types.h" #include "components/services/app_service/public/cpp/icon_types.h" #include "components/services/app_service/public/cpp/intent_filter.h" +#include "content/public/browser/web_contents.h" #include "extensions/browser/app_window/app_window.h" #include "extensions/browser/app_window/app_window_registry.h" #include "extensions/browser/extension_prefs.h" @@ -403,6 +408,13 @@ profile_trackers_[profile] = std::make_unique<ProfileTracker>(profile, this, which_type_); } + + // Only track the media usage for the chrome apps. + if (which_type_.IsChromeApps()) { + media_dispatcher_.Observe(MediaCaptureDevicesDispatcher::GetInstance() + ->GetMediaStreamCaptureIndicator() + .get()); + } } bool LacrosExtensionAppsPublisher::InitializeCrosapi() { @@ -442,6 +454,11 @@ publisher_->OnApps(std::move(apps)); } +void LacrosExtensionAppsPublisher::PublishCapabilityAccesses( + std::vector<apps::CapabilityAccessPtr> accesses) { + publisher_->OnCapabilityAccesses(std::move(accesses)); +} + void LacrosExtensionAppsPublisher::OnAppWindowAdded( const std::string& app_id, const std::string& window_id) { @@ -501,3 +518,63 @@ DCHECK(matched != profile_trackers_.end()); matched->second->Publish(extension, apps::Readiness::kReady); } + +void LacrosExtensionAppsPublisher::OnIsCapturingVideoChanged( + content::WebContents* web_contents, + bool is_capturing_video) { + auto app_id = MaybeGetAppId(web_contents); + if (!app_id.has_value()) { + return; + } + + auto result = media_requests_.UpdateCameraState(app_id.value(), web_contents, + is_capturing_video); + ModifyCapabilityAccess(app_id.value(), result.camera, result.microphone); +} + +void LacrosExtensionAppsPublisher::OnIsCapturingAudioChanged( + content::WebContents* web_contents, + bool is_capturing_audio) { + auto app_id = MaybeGetAppId(web_contents); + if (!app_id.has_value()) { + return; + } + + auto result = media_requests_.UpdateMicrophoneState( + app_id.value(), web_contents, is_capturing_audio); + ModifyCapabilityAccess(app_id.value(), result.camera, result.microphone); +} + +absl::optional<std::string> LacrosExtensionAppsPublisher::MaybeGetAppId( + content::WebContents* web_contents) { + // The web app publisher is responsible to handle `web_contents` for web + // apps. + const web_app::AppId* web_app_id = + web_app::WebAppTabHelper::GetAppId(web_contents); + if (web_app_id) { + return absl::nullopt; + } + + const auto* extension = + lacros_extensions_util::MaybeGetExtension(web_contents); + return (extension && which_type_.Matches(extension)) + ? absl::make_optional<std::string>(extension->id()) + : absl::nullopt; +} + +void LacrosExtensionAppsPublisher::ModifyCapabilityAccess( + const std::string& app_id, + absl::optional<bool> accessing_camera, + absl::optional<bool> accessing_microphone) { + if (!accessing_camera.has_value() && !accessing_microphone.has_value()) { + return; + } + + std::vector<apps::CapabilityAccessPtr> capability_accesses; + auto capability_access = std::make_unique<apps::CapabilityAccess>(app_id); + capability_access->camera = accessing_camera; + capability_access->microphone = accessing_microphone; + capability_accesses.push_back(std::move(capability_access)); + + PublishCapabilityAccesses(std::move(capability_accesses)); +}
diff --git a/chrome/browser/lacros/lacros_extension_apps_publisher.h b/chrome/browser/lacros/lacros_extension_apps_publisher.h index 3f13ae4..a4e125d 100644 --- a/chrome/browser/lacros/lacros_extension_apps_publisher.h +++ b/chrome/browser/lacros/lacros_extension_apps_publisher.h
@@ -10,13 +10,21 @@ #include <vector> #include "base/scoped_observation.h" +#include "chrome/browser/apps/app_service/media_requests.h" #include "chrome/browser/lacros/for_which_extension_type.h" +#include "chrome/browser/media/webrtc/media_stream_capture_indicator.h" #include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/profiles/profile_manager_observer.h" #include "chrome/browser/profiles/profile_observer.h" #include "chromeos/crosapi/mojom/app_service.mojom.h" +#include "components/services/app_service/public/cpp/app_capability_access_cache.h" #include "components/services/app_service/public/cpp/app_types.h" #include "mojo/public/cpp/bindings/remote.h" +#include "third_party/abseil-cpp/absl/types/optional.h" + +namespace content { +class WebContents; +} // namespace content // This class tracks Chrome apps [i.e. extension-based apps, AKA v2 packaged // apps] or extensions running in Lacros, and forwards metadata about these @@ -39,7 +47,9 @@ // // See LacrosExtensionAppsController for the class responsible for receiving // events from Ash. -class LacrosExtensionAppsPublisher : public ProfileManagerObserver { +class LacrosExtensionAppsPublisher + : public ProfileManagerObserver, + public MediaStreamCaptureIndicator::Observer { public: static std::unique_ptr<LacrosExtensionAppsPublisher> MakeForChromeApps(); static std::unique_ptr<LacrosExtensionAppsPublisher> MakeForExtensions(); @@ -71,6 +81,11 @@ // Virtual for testing. virtual void Publish(std::vector<apps::AppPtr> apps); + // Publishes differential CapabilityAccess updates to the App_Service in Ash + // via crosapi. Virtual for testing. + virtual void PublishCapabilityAccesses( + std::vector<apps::CapabilityAccessPtr> accesses); + // Notifies Ash's app window tracker of an app window construction. For Chrome // apps only. Virtual for testing. virtual void OnAppWindowAdded(const std::string& app_id, @@ -95,6 +110,18 @@ void OnProfileMarkedForPermanentDeletion(Profile* profile) override; void OnProfileManagerDestroying() override; + // MediaStreamCaptureIndicator::Observer + void OnIsCapturingVideoChanged(content::WebContents* web_contents, + bool is_capturing_video) override; + void OnIsCapturingAudioChanged(content::WebContents* web_contents, + bool is_capturing_audio) override; + + absl::optional<std::string> MaybeGetAppId(content::WebContents* web_contents); + + void ModifyCapabilityAccess(const std::string& app_id, + absl::optional<bool> accessing_camera, + absl::optional<bool> accessing_microphone); + // State to decide which extension type (e.g., Chrome Apps vs. Extensions) // to support. const ForWhichExtensionType which_type_; @@ -108,6 +135,15 @@ // Scoped observer for the ProfileManager. base::ScopedObservation<ProfileManager, ProfileManagerObserver> profile_manager_observation_{this}; + + // Scoped observer for the MediaStreamCaptureIndicator. + base::ScopedObservation<MediaStreamCaptureIndicator, + MediaStreamCaptureIndicator::Observer> + media_dispatcher_{this}; + + // Tracks the media usage for each app (e.g. accessing camera, microphone) on + // a per-WebContents basis. + apps::MediaRequests media_requests_; }; #endif // CHROME_BROWSER_LACROS_LACROS_EXTENSION_APPS_PUBLISHER_H_
diff --git a/chrome/browser/lacros/lacros_extension_apps_publisher_browsertest.cc b/chrome/browser/lacros/lacros_extension_apps_publisher_browsertest.cc index aa1fcde..32ee0384 100644 --- a/chrome/browser/lacros/lacros_extension_apps_publisher_browsertest.cc +++ b/chrome/browser/lacros/lacros_extension_apps_publisher_browsertest.cc
@@ -11,9 +11,14 @@ #include "chrome/browser/extensions/extension_keeplist_chromeos.h" #include "chrome/browser/lacros/for_which_extension_type.h" #include "chrome/browser/lacros/lacros_extensions_util.h" +#include "chrome/browser/media/webrtc/media_capture_devices_dispatcher.h" +#include "chrome/browser/media/webrtc/media_stream_capture_indicator.h" #include "chrome/browser/ui/lacros/window_utility.h" #include "chrome/test/base/in_process_browser_test.h" +#include "chrome/test/base/ui_test_utils.h" #include "chromeos/crosapi/mojom/app_service_types.mojom.h" +#include "components/app_constants/constants.h" +#include "components/services/app_service/public/cpp/app_capability_access_cache.h" #include "components/services/app_service/public/cpp/app_types.h" #include "content/public/test/browser_test.h" #include "extensions/browser/app_window/app_window.h" @@ -21,11 +26,15 @@ #include "extensions/browser/app_window/native_app_window.h" #include "extensions/common/constants.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/abseil-cpp/absl/types/optional.h" +#include "third_party/blink/public/common/mediastream/media_stream_request.h" +#include "third_party/blink/public/mojom/mediastream/media_stream.mojom.h" #include "ui/aura/window.h" namespace { using Apps = std::vector<apps::AppPtr>; +using Accesses = std::vector<apps::CapabilityAccessPtr>; // This fake intercepts and tracks all calls to Publish(). class LacrosExtensionAppsPublisherFake : public LacrosExtensionAppsPublisher { @@ -45,14 +54,45 @@ LacrosExtensionAppsPublisherFake& operator=( const LacrosExtensionAppsPublisherFake&) = delete; + void VerifyAppCapabilityAccess(const std::string& app_id, + size_t count, + absl::optional<bool> accessing_camera, + absl::optional<bool> accessing_microphone) { + ASSERT_EQ(count, accesses_history().size()); + Accesses& accesses = accesses_history().back(); + ASSERT_EQ(1u, accesses.size()); + EXPECT_EQ(app_id, accesses[0]->app_id); + + if (accessing_camera.has_value()) { + ASSERT_TRUE(accesses[0]->camera.has_value()); + EXPECT_EQ(accessing_camera.value(), accesses[0]->camera.value()); + } else { + ASSERT_FALSE(accesses[0]->camera.has_value()); + } + + if (accessing_microphone.has_value()) { + ASSERT_TRUE(accesses[0]->microphone.has_value()); + EXPECT_EQ(accessing_microphone.value(), accesses[0]->microphone.value()); + } else { + ASSERT_FALSE(accesses[0]->microphone.has_value()); + } + } + std::vector<Apps>& apps_history() { return apps_history_; } + std::vector<Accesses>& accesses_history() { return accesses_history_; } + std::map<std::string, std::string>& app_windows() { return app_windows_; } private: // Override to intercept calls to Publish(). void Publish(Apps apps) override { apps_history_.push_back(std::move(apps)); } + // Override to intercept calls to PublishCapabilityAccesses(). + void PublishCapabilityAccesses(Accesses accesses) override { + accesses_history_.push_back(std::move(accesses)); + } + // Override to intercept calls to OnAppWindowAdded(). void OnAppWindowAdded(const std::string& app_id, const std::string& window_id) override { @@ -73,6 +113,10 @@ // Holds the contents of all calls to Publish() in chronological order. std::vector<Apps> apps_history_; + // Holds the contents of all calls to PublishCapabilityAccesses() in + // chronological order. + std::vector<Accesses> accesses_history_; + // Holds the list of currently showing app windows, as seen by // OnAppWindowAdded() and OnAppWindowRemoved(). The key is the window_id and // the value is the app_id. @@ -103,6 +147,34 @@ ASSERT_FALSE(default_app->is_platform_app.value()); } +// Adds a fake media device with the specified `stream_type` and starts +// capturing. Returns a closure to stop the capturing. +base::OnceClosure StartMediaCapture(content::WebContents* web_contents, + blink::mojom::MediaStreamType stream_type) { + blink::mojom::StreamDevices fake_devices; + blink::MediaStreamDevice device(stream_type, "fake_device", "fake_device"); + + if (blink::IsAudioInputMediaType(stream_type)) { + fake_devices.audio_device = device; + } else { + fake_devices.video_device = device; + } + + std::unique_ptr<content::MediaStreamUI> ui = + MediaCaptureDevicesDispatcher::GetInstance() + ->GetMediaStreamCaptureIndicator() + ->RegisterMediaStream(web_contents, fake_devices); + + ui->OnStarted(base::RepeatingClosure(), + content::MediaStreamUI::SourceCallback(), + /*label=*/std::string(), /*screen_capture_ids=*/{}, + content::MediaStreamUI::StateChangeCallback()); + + return base::BindOnce( + [](std::unique_ptr<content::MediaStreamUI> ui) { ui.reset(); }, + std::move(ui)); +} + using LacrosExtensionAppsPublisherTest = extensions::ExtensionBrowserTest; // When publisher is created and initialized, only chrome default apps @@ -302,4 +374,44 @@ } } +IN_PROC_BROWSER_TEST_F(LacrosExtensionAppsPublisherTest, + RequestAccessingForPlatformApp) { + const extensions::Extension* extension = + LoadAndLaunchApp(test_data_dir_.AppendASCII("platform_apps/minimal")); + ASSERT_TRUE(extension); + + std::unique_ptr<LacrosExtensionAppsPublisherFake> publisher = + std::make_unique<LacrosExtensionAppsPublisherFake>(); + publisher->Initialize(); + + auto* registry = extensions::AppWindowRegistry::Get(profile()); + extensions::AppWindow* app_window = + registry->GetCurrentAppWindowForApp(extension->id()); + ASSERT_TRUE(app_window); + content::WebContents* web_contents = app_window->web_contents(); + ASSERT_TRUE(web_contents); + + // Request accessing the camera for `web_contents`. + base::OnceClosure video_closure = StartMediaCapture( + web_contents, blink::mojom::MediaStreamType::DEVICE_VIDEO_CAPTURE); + publisher->VerifyAppCapabilityAccess(extension->id(), 1u, true, + absl::nullopt); + + // Request accessing the microphone for `web_contents`. + base::OnceClosure audio_closure = StartMediaCapture( + web_contents, blink::mojom::MediaStreamType::DEVICE_AUDIO_CAPTURE); + publisher->VerifyAppCapabilityAccess(extension->id(), 2u, absl::nullopt, + true); + + // Stop accessing the microphone for `web_contents`. + std::move(audio_closure).Run(); + publisher->VerifyAppCapabilityAccess(extension->id(), 3u, absl::nullopt, + false); + + // Stop accessing the camera for `web_contents`. + std::move(video_closure).Run(); + publisher->VerifyAppCapabilityAccess(extension->id(), 4u, false, + absl::nullopt); +} + } // namespace
diff --git a/chrome/browser/lacros/lacros_extensions_util.cc b/chrome/browser/lacros/lacros_extensions_util.cc index 1f8d2fad..77336d24 100644 --- a/chrome/browser/lacros/lacros_extensions_util.cc +++ b/chrome/browser/lacros/lacros_extensions_util.cc
@@ -15,6 +15,7 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_manager.h" #include "chrome/common/chrome_features.h" +#include "content/public/browser/web_contents.h" #include "extensions/browser/extension_registry.h" #include "extensions/common/extension.h" @@ -35,6 +36,19 @@ return registry->GetInstalledExtension(extension_id); } +const extensions::Extension* MaybeGetExtension( + content::WebContents* web_contents) { + if (!web_contents) { + return nullptr; + } + + extensions::ExtensionRegistry* registry = extensions::ExtensionRegistry::Get( + Profile::FromBrowserContext(web_contents->GetBrowserContext())); + DCHECK(registry); + const extensions::ExtensionSet& extensions = registry->enabled_extensions(); + return extensions.GetAppByURL(web_contents->GetVisibleURL()); +} + bool GetProfileAndExtension(const std::string& extension_id, Profile** output_profile, const extensions::Extension** output_extension) {
diff --git a/chrome/browser/lacros/lacros_extensions_util.h b/chrome/browser/lacros/lacros_extensions_util.h index f01dc18..f71f737 100644 --- a/chrome/browser/lacros/lacros_extensions_util.h +++ b/chrome/browser/lacros/lacros_extensions_util.h
@@ -9,6 +9,10 @@ class Profile; +namespace content { +class WebContents; +} // namespace content + namespace extensions { class Extension; } // namespace extensions @@ -26,6 +30,10 @@ const extensions::Extension* MaybeGetExtension(Profile* profile, const std::string& extension_id); +// Returns the extension pointer for |web_contents|, or null if nonexistent. +const extensions::Extension* MaybeGetExtension( + content::WebContents* web_contents); + // Gets the profile and extension from |extension_id|. On success, returns true // and populates variables |output_profile| and |output_extension|. We pass a // Profile** and an Extension** instead of Profile*& and Extension*& for clarity
diff --git a/chrome/browser/media/router/chrome_media_router_factory.cc b/chrome/browser/media/router/chrome_media_router_factory.cc index 4b4568f5..28f1f34 100644 --- a/chrome/browser/media/router/chrome_media_router_factory.cc +++ b/chrome/browser/media/router/chrome_media_router_factory.cc
@@ -67,14 +67,15 @@ : chrome::GetBrowserContextRedirectedInIncognito(context); } -KeyedService* ChromeMediaRouterFactory::BuildServiceInstanceFor( +std::unique_ptr<KeyedService> +ChromeMediaRouterFactory::BuildServiceInstanceForBrowserContext( BrowserContext* context) const { CHECK(MediaRouterEnabled(context)); - MediaRouterBase* media_router = nullptr; + std::unique_ptr<MediaRouterBase> media_router = nullptr; #if BUILDFLAG(IS_ANDROID) - media_router = new MediaRouterAndroid(); + media_router = std::make_unique<MediaRouterAndroid>(); #else - media_router = new MediaRouterDesktop(context); + media_router = std::make_unique<MediaRouterDesktop>(context); #endif // BUILDFLAG(IS_ANDROID) media_router->Initialize(); return media_router;
diff --git a/chrome/browser/media/router/chrome_media_router_factory.h b/chrome/browser/media/router/chrome_media_router_factory.h index c185b9d5..09f718de9 100644 --- a/chrome/browser/media/router/chrome_media_router_factory.h +++ b/chrome/browser/media/router/chrome_media_router_factory.h
@@ -36,7 +36,7 @@ // BrowserContextKeyedServiceFactory interface. content::BrowserContext* GetBrowserContextToUse( content::BrowserContext* context) const override; - KeyedService* BuildServiceInstanceFor( + std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const override; };
diff --git a/chrome/browser/metrics/ukm_background_recorder_service.cc b/chrome/browser/metrics/ukm_background_recorder_service.cc index b2588d28..8356f8d 100644 --- a/chrome/browser/metrics/ukm_background_recorder_service.cc +++ b/chrome/browser/metrics/ukm_background_recorder_service.cc
@@ -83,9 +83,11 @@ UkmBackgroundRecorderFactory::~UkmBackgroundRecorderFactory() = default; -KeyedService* UkmBackgroundRecorderFactory::BuildServiceInstanceFor( +std::unique_ptr<KeyedService> +UkmBackgroundRecorderFactory::BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const { - return new UkmBackgroundRecorderService(Profile::FromBrowserContext(context)); + return std::make_unique<UkmBackgroundRecorderService>( + Profile::FromBrowserContext(context)); } } // namespace ukm
diff --git a/chrome/browser/metrics/ukm_background_recorder_service.h b/chrome/browser/metrics/ukm_background_recorder_service.h index a24ff05..3b8b470 100644 --- a/chrome/browser/metrics/ukm_background_recorder_service.h +++ b/chrome/browser/metrics/ukm_background_recorder_service.h
@@ -91,7 +91,7 @@ UkmBackgroundRecorderFactory(); ~UkmBackgroundRecorderFactory() override; - KeyedService* BuildServiceInstanceFor( + std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const override; };
diff --git a/chrome/browser/nearby_sharing/OWNERS b/chrome/browser/nearby_sharing/OWNERS index 82175ada..f195cc3 100644 --- a/chrome/browser/nearby_sharing/OWNERS +++ b/chrome/browser/nearby_sharing/OWNERS
@@ -1,7 +1,8 @@ +cclem@google.com crisrael@google.com +dclasson@google.com hansberry@chromium.org hansenmichael@google.com -pushi@google.com -cclem@google.com jackshira@google.com -dclasson@google.com +julietlevesque@google.com +pushi@google.com
diff --git a/chrome/browser/new_tab_page/modules/v2/history_clusters/history_clusters_page_handler_v2.cc b/chrome/browser/new_tab_page/modules/v2/history_clusters/history_clusters_page_handler_v2.cc index e795108a..df6d68d 100644 --- a/chrome/browser/new_tab_page/modules/v2/history_clusters/history_clusters_page_handler_v2.cc +++ b/chrome/browser/new_tab_page/modules/v2/history_clusters/history_clusters_page_handler_v2.cc
@@ -42,7 +42,7 @@ // visit. constexpr int kMinRequiredVisits = 3; -constexpr int kMinRequiredRelatedSearches = 2; +constexpr int kMinRequiredRelatedSearches = 0; } // namespace
diff --git a/chrome/browser/new_tab_page/one_google_bar/one_google_bar_service_factory.cc b/chrome/browser/new_tab_page/one_google_bar/one_google_bar_service_factory.cc index 1728403..a442a4f 100644 --- a/chrome/browser/new_tab_page/one_google_bar/one_google_bar_service_factory.cc +++ b/chrome/browser/new_tab_page/one_google_bar/one_google_bar_service_factory.cc
@@ -49,7 +49,8 @@ OneGoogleBarServiceFactory::~OneGoogleBarServiceFactory() = default; -KeyedService* OneGoogleBarServiceFactory::BuildServiceInstanceFor( +std::unique_ptr<KeyedService> +OneGoogleBarServiceFactory::BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const { Profile* profile = Profile::FromBrowserContext(context); signin::IdentityManager* identity_manager = @@ -58,7 +59,7 @@ CookieSettingsFactory::GetForProfile(profile); auto url_loader_factory = context->GetDefaultStoragePartition() ->GetURLLoaderFactoryForBrowserProcess(); - return new OneGoogleBarService( + return std::make_unique<OneGoogleBarService>( identity_manager, std::make_unique<OneGoogleBarLoaderImpl>( url_loader_factory, g_browser_process->GetApplicationLocale(),
diff --git a/chrome/browser/new_tab_page/one_google_bar/one_google_bar_service_factory.h b/chrome/browser/new_tab_page/one_google_bar/one_google_bar_service_factory.h index 84c3e5b8..7517907 100644 --- a/chrome/browser/new_tab_page/one_google_bar/one_google_bar_service_factory.h +++ b/chrome/browser/new_tab_page/one_google_bar/one_google_bar_service_factory.h
@@ -29,7 +29,7 @@ ~OneGoogleBarServiceFactory() override; // Overridden from BrowserContextKeyedServiceFactory: - KeyedService* BuildServiceInstanceFor( + std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( content::BrowserContext* profile) const override; };
diff --git a/chrome/browser/offline_pages/android/offline_page_auto_fetcher_service_factory.cc b/chrome/browser/offline_pages/android/offline_page_auto_fetcher_service_factory.cc index 5279f44..8a92f60 100644 --- a/chrome/browser/offline_pages/android/offline_page_auto_fetcher_service_factory.cc +++ b/chrome/browser/offline_pages/android/offline_page_auto_fetcher_service_factory.cc
@@ -63,14 +63,15 @@ OfflinePageAutoFetcherServiceFactory::~OfflinePageAutoFetcherServiceFactory() = default; -KeyedService* OfflinePageAutoFetcherServiceFactory::BuildServiceInstanceFor( +std::unique_ptr<KeyedService> +OfflinePageAutoFetcherServiceFactory::BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const { RequestCoordinator* coordinator = RequestCoordinatorFactory::GetForBrowserContext(context); OfflinePageModel* model = OfflinePageModelFactory::GetForBrowserContext(context); - return new OfflinePageAutoFetcherService(coordinator, model, - service_delegate_.get()); + return std::make_unique<OfflinePageAutoFetcherService>( + coordinator, model, service_delegate_.get()); } } // namespace offline_pages
diff --git a/chrome/browser/offline_pages/android/offline_page_auto_fetcher_service_factory.h b/chrome/browser/offline_pages/android/offline_page_auto_fetcher_service_factory.h index 22f3b85..0f5973d9 100644 --- a/chrome/browser/offline_pages/android/offline_page_auto_fetcher_service_factory.h +++ b/chrome/browser/offline_pages/android/offline_page_auto_fetcher_service_factory.h
@@ -36,7 +36,7 @@ OfflinePageAutoFetcherServiceFactory(); ~OfflinePageAutoFetcherServiceFactory() override; - KeyedService* BuildServiceInstanceFor( + std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const override; std::unique_ptr<ServiceDelegate> service_delegate_;
diff --git a/chrome/browser/offline_pages/android/request_coordinator_factory.cc b/chrome/browser/offline_pages/android/request_coordinator_factory.cc index 10cf16f..f8927982 100644 --- a/chrome/browser/offline_pages/android/request_coordinator_factory.cc +++ b/chrome/browser/offline_pages/android/request_coordinator_factory.cc
@@ -89,7 +89,8 @@ GetInstance()->GetServiceForBrowserContext(context, true)); } -KeyedService* RequestCoordinatorFactory::BuildServiceInstanceFor( +std::unique_ptr<KeyedService> +RequestCoordinatorFactory::BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const { std::unique_ptr<OfflinerPolicy> policy(new OfflinerPolicy()); std::unique_ptr<Offliner> offliner; @@ -115,12 +116,10 @@ scheduler(new android::BackgroundSchedulerBridge()); network::NetworkQualityTracker* network_quality_tracker = g_browser_process->network_quality_tracker(); - RequestCoordinator* request_coordinator = new RequestCoordinator( + return std::make_unique<RequestCoordinator>( std::move(policy), std::move(offliner), std::move(queue), std::move(scheduler), network_quality_tracker, std::make_unique<ActiveTabInfo>(profile)); - - return request_coordinator; } } // namespace offline_pages
diff --git a/chrome/browser/offline_pages/request_coordinator_factory.h b/chrome/browser/offline_pages/request_coordinator_factory.h index 7d68579..b9e9e90 100644 --- a/chrome/browser/offline_pages/request_coordinator_factory.h +++ b/chrome/browser/offline_pages/request_coordinator_factory.h
@@ -34,7 +34,7 @@ RequestCoordinatorFactory(); ~RequestCoordinatorFactory() override {} - KeyedService* BuildServiceInstanceFor( + std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const override; };
diff --git a/chrome/browser/password_manager/affiliation_service_factory.cc b/chrome/browser/password_manager/affiliation_service_factory.cc index 79fe9652..5f7f24a 100644 --- a/chrome/browser/password_manager/affiliation_service_factory.cc +++ b/chrome/browser/password_manager/affiliation_service_factory.cc
@@ -34,7 +34,8 @@ GetInstance()->GetServiceForBrowserContext(profile, true)); } -KeyedService* AffiliationServiceFactory::BuildServiceInstanceFor( +std::unique_ptr<KeyedService> +AffiliationServiceFactory::BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const { Profile* profile = Profile::FromBrowserContext(context); scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory = @@ -42,8 +43,9 @@ ->GetURLLoaderFactoryForBrowserProcess(); auto backend_task_runner = base::ThreadPool::CreateSequencedTaskRunner( {base::MayBlock(), base::TaskPriority::USER_VISIBLE}); - auto* affiliation_service = new password_manager::AffiliationServiceImpl( - url_loader_factory, backend_task_runner); + auto affiliation_service = + std::make_unique<password_manager::AffiliationServiceImpl>( + url_loader_factory, backend_task_runner); base::FilePath database_path = profile->GetPath().Append(password_manager::kAffiliationDatabaseFileName);
diff --git a/chrome/browser/password_manager/affiliation_service_factory.h b/chrome/browser/password_manager/affiliation_service_factory.h index 027900f..7fcc731 100644 --- a/chrome/browser/password_manager/affiliation_service_factory.h +++ b/chrome/browser/password_manager/affiliation_service_factory.h
@@ -27,7 +27,7 @@ static password_manager::AffiliationService* GetForProfile(Profile* profile); private: - KeyedService* BuildServiceInstanceFor( + std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const override; };
diff --git a/chrome/browser/recovery/recovery_install_global_error_factory.cc b/chrome/browser/recovery/recovery_install_global_error_factory.cc index d827844..0e4da97 100644 --- a/chrome/browser/recovery/recovery_install_global_error_factory.cc +++ b/chrome/browser/recovery/recovery_install_global_error_factory.cc
@@ -39,10 +39,12 @@ return instance.get(); } -KeyedService* RecoveryInstallGlobalErrorFactory::BuildServiceInstanceFor( +std::unique_ptr<KeyedService> +RecoveryInstallGlobalErrorFactory::BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const { #if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) - return new RecoveryInstallGlobalError(static_cast<Profile*>(context)); + return std::make_unique<RecoveryInstallGlobalError>( + static_cast<Profile*>(context)); #else return NULL; #endif
diff --git a/chrome/browser/recovery/recovery_install_global_error_factory.h b/chrome/browser/recovery/recovery_install_global_error_factory.h index 5b07b79..72dc4953 100644 --- a/chrome/browser/recovery/recovery_install_global_error_factory.h +++ b/chrome/browser/recovery/recovery_install_global_error_factory.h
@@ -35,7 +35,7 @@ ~RecoveryInstallGlobalErrorFactory() override; // BrowserContextKeyedServiceFactory: - KeyedService* BuildServiceInstanceFor( + std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( content::BrowserContext* profile) const override; };
diff --git a/chrome/browser/resources/ash/settings/date_time_page/date_time_card.html b/chrome/browser/resources/ash/settings/date_time_page/date_time_card.html index 1b03774..e917388 100644 --- a/chrome/browser/resources/ash/settings/date_time_page/date_time_card.html +++ b/chrome/browser/resources/ash/settings/date_time_page/date_time_card.html
@@ -23,7 +23,6 @@ label="$i18n{timeZoneButton}" sub-label="[[timeZoneSettingSublabel_]]" role-description="$i18n{subpageArrowRoleDescription}"> - <div class="flex"></div> <cr-policy-pref-indicator pref="[[prefs.generated.resolve_timezone_by_geolocation_on_off]]"> </cr-policy-pref-indicator>
diff --git a/chrome/browser/resources/ash/settings/os_bluetooth_page/os_bluetooth_page.ts b/chrome/browser/resources/ash/settings/os_bluetooth_page/os_bluetooth_page.ts index ab60a76dd..0c24444c 100644 --- a/chrome/browser/resources/ash/settings/os_bluetooth_page/os_bluetooth_page.ts +++ b/chrome/browser/resources/ash/settings/os_bluetooth_page/os_bluetooth_page.ts
@@ -32,7 +32,8 @@ const SettingsBluetoothPageElementBase = PrefsMixin(I18nMixin(PolymerElement)); -class SettingsBluetoothPageElement extends SettingsBluetoothPageElementBase { +export class SettingsBluetoothPageElement extends + SettingsBluetoothPageElementBase { static get is() { return 'os-settings-bluetooth-page' as const; }
diff --git a/chrome/browser/resources/ash/settings/os_bluetooth_page/os_bluetooth_pairing_dialog.ts b/chrome/browser/resources/ash/settings/os_bluetooth_page/os_bluetooth_pairing_dialog.ts index 3eb8a22e..e5e710f 100644 --- a/chrome/browser/resources/ash/settings/os_bluetooth_page/os_bluetooth_pairing_dialog.ts +++ b/chrome/browser/resources/ash/settings/os_bluetooth_page/os_bluetooth_pairing_dialog.ts
@@ -16,11 +16,11 @@ import {getTemplate} from './os_bluetooth_pairing_dialog.html.js'; -interface SettingsBluetoothPairingDialogElement { +export interface SettingsBluetoothPairingDialogElement { $: {dialog: CrDialogElement}; } -class SettingsBluetoothPairingDialogElement extends PolymerElement { +export class SettingsBluetoothPairingDialogElement extends PolymerElement { static get is() { return 'os-settings-bluetooth-pairing-dialog' as const; }
diff --git a/chrome/browser/resources/ash/settings/os_files_page/google_drive_subpage.ts b/chrome/browser/resources/ash/settings/os_files_page/google_drive_subpage.ts index 2ed5490..945d745 100644 --- a/chrome/browser/resources/ash/settings/os_files_page/google_drive_subpage.ts +++ b/chrome/browser/resources/ash/settings/os_files_page/google_drive_subpage.ts
@@ -459,7 +459,8 @@ private shouldEnableCleanUpStorageButton_() { return !this.getPref(GOOGLE_DRIVE_BULK_PINNING_PREF).value && this.contentCacheSize_ !== ContentCacheSizeType.UNKNOWN && - this.contentCacheSize_ !== ContentCacheSizeType.CALCULATING; + this.contentCacheSize_ !== ContentCacheSizeType.CALCULATING && + this.contentCacheSize_ !== '0 B'; } /**
diff --git a/chrome/browser/resources/ash/settings/os_settings.ts b/chrome/browser/resources/ash/settings/os_settings.ts index 6cdb4c5..82bf926 100644 --- a/chrome/browser/resources/ash/settings/os_settings.ts +++ b/chrome/browser/resources/ash/settings/os_settings.ts
@@ -121,6 +121,7 @@ export {PaperTooltipElement} from 'chrome://resources/polymer/v3_0/paper-tooltip/paper-tooltip.js'; export {LacrosExtensionControlBrowserProxy, LacrosExtensionControlBrowserProxyImpl} from './common/lacros_extension_control_browser_proxy.js'; export {LacrosExtensionControlledIndicatorElement} from './common/lacros_extension_controlled_indicator.js'; +export {PrefsState} from './common/types.js'; export {SettingsAudioElement} from './device_page/audio.js'; export {setCrosAudioConfigForTesting} from './device_page/cros_audio_config.js'; export {DevicePageBrowserProxy, DevicePageBrowserProxyImpl, IdleBehavior, LidClosedBehavior, NoteAppInfo, NoteAppLockScreenSupport, setDisplayApiForTesting, StorageSpaceState} from './device_page/device_page_browser_proxy.js'; @@ -189,6 +190,8 @@ export {AppManagementStoreMixin} from './os_apps_page/app_management_page/store_mixin.js'; export {setAppNotificationProviderForTesting} from './os_apps_page/app_notifications_page/mojo_interface_provider.js'; export {OsBluetoothDevicesSubpageBrowserProxy, OsBluetoothDevicesSubpageBrowserProxyImpl} from './os_bluetooth_page/os_bluetooth_devices_subpage_browser_proxy.js'; +export {SettingsBluetoothPageElement} from './os_bluetooth_page/os_bluetooth_page.js'; +export {SettingsBluetoothPairingDialogElement} from './os_bluetooth_page/os_bluetooth_pairing_dialog.js'; export {FastPairSavedDevice, FastPairSavedDevicesOptInStatus} from './os_bluetooth_page/settings_fast_pair_constants.js'; export {GoogleDriveBrowserProxy, GoogleDrivePageCallbackRouter, GoogleDrivePageHandlerRemote, GoogleDrivePageRemote, Stage} from './os_files_page/google_drive_browser_proxy.js'; export {ConfirmationDialogType, SettingsGoogleDriveSubpageElement} from './os_files_page/google_drive_subpage.js';
diff --git a/chrome/browser/resources/settings/safety_hub/unused_site_permissions_module.ts b/chrome/browser/resources/settings/safety_hub/unused_site_permissions_module.ts index 26c09c4..78a3b0b 100644 --- a/chrome/browser/resources/settings/safety_hub/unused_site_permissions_module.ts +++ b/chrome/browser/resources/settings/safety_hub/unused_site_permissions_module.ts
@@ -168,8 +168,7 @@ const permissionsI18n = permissions.map(permission => { const localizationString = getLocalizationStringForContentType(permission); - assert(localizationString !== null); - return this.i18n(localizationString); + return localizationString ? this.i18n(localizationString) : ''; }); switch (permissionsI18n.length) {
diff --git a/chrome/browser/resources/settings/site_settings_page/unused_site_permissions.ts b/chrome/browser/resources/settings/site_settings_page/unused_site_permissions.ts index d9fbe17..1757c375 100644 --- a/chrome/browser/resources/settings/site_settings_page/unused_site_permissions.ts +++ b/chrome/browser/resources/settings/site_settings_page/unused_site_permissions.ts
@@ -213,8 +213,7 @@ const permissionsI18n = permissions.map(permission => { const localizationString = getLocalizationStringForContentType(permission); - assert(localizationString !== null); - return this.i18n(localizationString); + return localizationString ? this.i18n(localizationString) : ''; }); if (permissionsI18n.length === 1) {
diff --git a/chrome/browser/search/instant_service_factory.cc b/chrome/browser/search/instant_service_factory.cc index 0b32940d..630b0dfa 100644 --- a/chrome/browser/search/instant_service_factory.cc +++ b/chrome/browser/search/instant_service_factory.cc
@@ -55,10 +55,11 @@ InstantServiceFactory::~InstantServiceFactory() = default; -KeyedService* InstantServiceFactory::BuildServiceInstanceFor( +std::unique_ptr<KeyedService> +InstantServiceFactory::BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const { DCHECK(search::IsInstantExtendedAPIEnabled()); - return new InstantService(Profile::FromBrowserContext(context)); + return std::make_unique<InstantService>(Profile::FromBrowserContext(context)); } void InstantServiceFactory::BrowserContextDestroyed(
diff --git a/chrome/browser/search/instant_service_factory.h b/chrome/browser/search/instant_service_factory.h index deb9a777..427b2f22 100644 --- a/chrome/browser/search/instant_service_factory.h +++ b/chrome/browser/search/instant_service_factory.h
@@ -34,7 +34,7 @@ ~InstantServiceFactory() override; // Overridden from BrowserContextKeyedServiceFactory: - KeyedService* BuildServiceInstanceFor( + std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const override; void BrowserContextDestroyed( content::BrowserContext* browser_context) override;
diff --git a/chrome/browser/segmentation_platform/segmentation_platform_service_factory_unittest.cc b/chrome/browser/segmentation_platform/segmentation_platform_service_factory_unittest.cc new file mode 100644 index 0000000..cf2264de --- /dev/null +++ b/chrome/browser/segmentation_platform/segmentation_platform_service_factory_unittest.cc
@@ -0,0 +1,244 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/segmentation_platform/segmentation_platform_service_factory.h" + +#include "base/files/scoped_temp_dir.h" +#include "base/functional/bind.h" +#include "base/memory/scoped_refptr.h" +#include "base/test/scoped_command_line.h" +#include "base/test/scoped_feature_list.h" +#include "base/test/task_environment.h" +#include "chrome/test/base/testing_profile.h" +#include "components/optimization_guide/core/optimization_guide_features.h" +#include "components/prefs/pref_change_registrar.h" +#include "components/prefs/pref_observer.h" +#include "components/prefs/pref_service.h" +#include "components/segmentation_platform/internal/constants.h" +#include "components/segmentation_platform/internal/database/client_result_prefs.h" +#include "components/segmentation_platform/public/constants.h" +#include "components/segmentation_platform/public/features.h" +#include "components/segmentation_platform/public/prediction_options.h" +#include "components/segmentation_platform/public/result.h" +#include "components/segmentation_platform/public/segment_selection_result.h" +#include "components/segmentation_platform/public/segmentation_platform_service.h" +#include "components/segmentation_platform/public/service_proxy.h" +#include "content/public/test/browser_task_environment.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "testing/platform_test.h" + +namespace segmentation_platform { +namespace { + +// Observer that waits for service_ initialization. +class WaitServiceInitializedObserver : public ServiceProxy::Observer { + public: + explicit WaitServiceInitializedObserver(base::OnceClosure closure) + : closure_(std::move(closure)) {} + void OnServiceStatusChanged(bool initialized, int status_flags) override { + if (initialized) { + std::move(closure_).Run(); + } + } + + private: + base::OnceClosure closure_; +}; + +} // namespace + +class SegmentationPlatformServiceFactoryTest : public testing::Test { + protected: + SegmentationPlatformServiceFactoryTest() { + scoped_command_line_.GetProcessCommandLine()->AppendSwitch( + kSegmentationPlatformRefreshResultsSwitch); + } + + ~SegmentationPlatformServiceFactoryTest() override = default; + + void TearDown() override { + service_ = nullptr; + testing_profile_.reset(); + task_environment_.RunUntilIdle(); + } + + void InitServiceAndCacheResults(const std::string& segmentation_key) { + scoped_feature_list_.InitWithFeaturesAndParameters( + {{optimization_guide::features::kOptimizationTargetPrediction, {}}, + {features::kSegmentationPlatformFeature, {}}, + {features::kSegmentationPlatformUkmEngine, {}}}, + {}); + + // Creating profile and initialising segmentation service. + TestingProfile::Builder profile_builder; + testing_profile_ = profile_builder.Build(); + service_ = SegmentationPlatformServiceFactory::GetForProfile( + testing_profile_.get()); + WaitForServiceInit(); + WaitForClientResultPrefUpdate(segmentation_key); + // Getting the updated prefs from this session to be copied to the next + // session. In the test environment, new session doesn't have prefs from + // previous session, hence copying is required to get the cached result from + // last session. + const std::string output = + testing_profile_->GetPrefs()->GetString(kSegmentationClientResultPrefs); + + // TODO(b/297091996): Remove this when leak is fixed. + task_environment_.RunUntilIdle(); + + service_ = nullptr; + testing_profile_ = nullptr; + + // Creating profile and initialising segmentation service again with prefs + // from the last session. + TestingProfile::Builder profile_builder1; + testing_profile_ = profile_builder1.Build(); + // Copying the prefs from last session. + testing_profile_->GetPrefs()->SetString(kSegmentationClientResultPrefs, + output); + service_ = SegmentationPlatformServiceFactory::GetForProfile( + testing_profile_.get()); + WaitForServiceInit(); + // TODO(b/297091996): Remove this when leak is fixed. + task_environment_.RunUntilIdle(); + } + + void ExpectGetClassificationResult( + const std::string& segmentation_key, + const PredictionOptions& prediction_options, + scoped_refptr<InputContext> input_context, + segmentation_platform::PredictionStatus expected_status, + absl::optional<std::vector<std::string>> expected_labels) { + base::RunLoop loop; + service_->GetClassificationResult( + segmentation_key, prediction_options, input_context, + base::BindOnce( + &SegmentationPlatformServiceFactoryTest::OnGetClassificationResult, + base::Unretained(this), loop.QuitClosure(), expected_status, + expected_labels)); + loop.Run(); + } + + void OnGetClassificationResult( + base::RepeatingClosure closure, + segmentation_platform::PredictionStatus expected_status, + absl::optional<std::vector<std::string>> expected_labels, + const ClassificationResult& actual_result) { + ASSERT_EQ(expected_status, actual_result.status); + if (expected_labels.has_value()) { + ASSERT_EQ(expected_labels.value().size(), + actual_result.ordered_labels.size()); + ASSERT_EQ(expected_labels.value(), actual_result.ordered_labels); + } + std::move(closure).Run(); + } + + void WaitForServiceInit() { + base::RunLoop wait_for_init; + WaitServiceInitializedObserver wait_observer(wait_for_init.QuitClosure()); + service_->GetServiceProxy()->AddObserver(&wait_observer); + + wait_for_init.Run(); + ASSERT_TRUE(service_->IsPlatformInitialized()); + service_->GetServiceProxy()->RemoveObserver(&wait_observer); + } + + bool HasClientResultPref(const std::string& segmentation_key) { + PrefService* pref_service_ = testing_profile_->GetPrefs(); + std::unique_ptr<ClientResultPrefs> result_prefs_ = + std::make_unique<ClientResultPrefs>(pref_service_); + return result_prefs_->ReadClientResultFromPrefs(segmentation_key) + .has_value(); + } + + void OnClientResultPrefUpdated(const std::string& segmentation_key) { + if (!wait_for_pref_callback_.is_null() && + HasClientResultPref(segmentation_key)) { + std::move(wait_for_pref_callback_).Run(); + } + } + + void WaitForClientResultPrefUpdate(const std::string& segmentation_key) { + if (HasClientResultPref(segmentation_key)) { + return; + } + + base::RunLoop wait_for_pref; + wait_for_pref_callback_ = wait_for_pref.QuitClosure(); + pref_registrar_.Init(testing_profile_->GetPrefs()); + pref_registrar_.Add( + kSegmentationClientResultPrefs, + base::BindRepeating( + &SegmentationPlatformServiceFactoryTest::OnClientResultPrefUpdated, + base::Unretained(this), segmentation_key)); + wait_for_pref.Run(); + + pref_registrar_.RemoveAll(); + } + + content::BrowserTaskEnvironment task_environment_; + base::test::ScopedFeatureList scoped_feature_list_; + base::test::ScopedCommandLine scoped_command_line_; + PrefChangeRegistrar pref_registrar_; + base::OnceClosure wait_for_pref_callback_; + std::unique_ptr<TestingProfile> testing_profile_; + raw_ptr<SegmentationPlatformService> service_; +}; + +TEST_F(SegmentationPlatformServiceFactoryTest, TestPasswordManagerUserSegment) { + InitServiceAndCacheResults(segmentation_platform::kPasswordManagerUserKey); + + segmentation_platform::PredictionOptions prediction_options; + + ExpectGetClassificationResult( + segmentation_platform::kPasswordManagerUserKey, prediction_options, + nullptr, + /*expected_status=*/segmentation_platform::PredictionStatus::kSucceeded, + /*expected_labels=*/ + std::vector<std::string>(1, "Not_PasswordManagerUser")); +} + +TEST_F(SegmentationPlatformServiceFactoryTest, TestSearchUserModel) { + InitServiceAndCacheResults(segmentation_platform::kSearchUserKey); + + segmentation_platform::PredictionOptions prediction_options; + + ExpectGetClassificationResult( + segmentation_platform::kSearchUserKey, prediction_options, nullptr, + /*expected_status=*/segmentation_platform::PredictionStatus::kSucceeded, + /*expected_labels=*/ + std::vector<std::string>( + 1, segmentation_platform::kSearchUserModelLabelNone)); +} + +#if BUILDFLAG(IS_ANDROID) +// Tests for models in android platform. +TEST_F(SegmentationPlatformServiceFactoryTest, TestDeviceTierSegment) { + InitServiceAndCacheResults(segmentation_platform::kDeviceTierKey); + + segmentation_platform::PredictionOptions prediction_options; + + ExpectGetClassificationResult( + segmentation_platform::kDeviceTierKey, prediction_options, nullptr, + /*expected_status=*/segmentation_platform::PredictionStatus::kSucceeded, + /*expected_labels=*/absl::nullopt); +} + +TEST_F(SegmentationPlatformServiceFactoryTest, + TestTabletProductivityUserModel) { + InitServiceAndCacheResults(segmentation_platform::kTabletProductivityUserKey); + + segmentation_platform::PredictionOptions prediction_options; + + ExpectGetClassificationResult( + segmentation_platform::kTabletProductivityUserKey, prediction_options, + nullptr, + /*expected_status=*/segmentation_platform::PredictionStatus::kSucceeded, + /*expected_labels=*/ + std::vector<std::string>( + 1, segmentation_platform::kTabletProductivityUserModelLabelNone)); +} +#endif // BUILDFLAG(IS_ANDROID) + +} // namespace segmentation_platform
diff --git a/chrome/browser/sharing/sharing_service_factory.cc b/chrome/browser/sharing/sharing_service_factory.cc index b5142370..7e00ff3 100644 --- a/chrome/browser/sharing/sharing_service_factory.cc +++ b/chrome/browser/sharing/sharing_service_factory.cc
@@ -91,7 +91,8 @@ SharingServiceFactory::~SharingServiceFactory() = default; -KeyedService* SharingServiceFactory::BuildServiceInstanceFor( +std::unique_ptr<KeyedService> +SharingServiceFactory::BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const { Profile* profile = Profile::FromBrowserContext(context); syncer::SyncService* sync_service = @@ -153,7 +154,7 @@ auto fcm_handler = std::make_unique<SharingFCMHandler>( gcm_driver, device_info_tracker, fcm_sender_ptr, handler_registry.get()); - return new SharingService( + return std::make_unique<SharingService>( std::move(sync_prefs), std::move(vapid_key_manager), std::move(sharing_device_registration), std::move(sharing_message_sender), std::move(device_source), std::move(handler_registry),
diff --git a/chrome/browser/sharing/sharing_service_factory.h b/chrome/browser/sharing/sharing_service_factory.h index 5a210bbd..cd775df2 100644 --- a/chrome/browser/sharing/sharing_service_factory.h +++ b/chrome/browser/sharing/sharing_service_factory.h
@@ -37,7 +37,7 @@ ~SharingServiceFactory() override; // BrowserContextKeyedServiceFactory overrides: - KeyedService* BuildServiceInstanceFor( + std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const override; bool ServiceIsNULLWhileTesting() const override; };
diff --git a/chrome/browser/sync_file_system/sync_file_system_service.h b/chrome/browser/sync_file_system/sync_file_system_service.h index 60323f5..06e1529 100644 --- a/chrome/browser/sync_file_system/sync_file_system_service.h +++ b/chrome/browser/sync_file_system/sync_file_system_service.h
@@ -63,6 +63,9 @@ using ExtensionStatusMapCallback = base::OnceCallback<void(const RemoteFileSyncService::OriginStatusMap&)>; + // Uses SyncFileSystemServiceFactory instead. + explicit SyncFileSystemService(Profile* profile); + ~SyncFileSystemService() override; SyncFileSystemService(const SyncFileSystemService&) = delete; SyncFileSystemService& operator=(const SyncFileSystemService&) = delete; @@ -108,9 +111,6 @@ friend class LocalSyncRunner; friend class RemoteSyncRunner; - explicit SyncFileSystemService(Profile* profile); - ~SyncFileSystemService() override; - void Initialize(std::unique_ptr<LocalFileSyncService> local_file_service, std::unique_ptr<RemoteFileSyncService> remote_file_service);
diff --git a/chrome/browser/sync_file_system/sync_file_system_service_factory.cc b/chrome/browser/sync_file_system/sync_file_system_service_factory.cc index 26c1fdc8..b93d8c9 100644 --- a/chrome/browser/sync_file_system/sync_file_system_service_factory.cc +++ b/chrome/browser/sync_file_system/sync_file_system_service_factory.cc
@@ -66,11 +66,13 @@ SyncFileSystemServiceFactory::~SyncFileSystemServiceFactory() = default; -KeyedService* SyncFileSystemServiceFactory::BuildServiceInstanceFor( +std::unique_ptr<KeyedService> +SyncFileSystemServiceFactory::BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const { Profile* profile = Profile::FromBrowserContext(context); - SyncFileSystemService* service = new SyncFileSystemService(profile); + std::unique_ptr<SyncFileSystemService> service = + std::make_unique<SyncFileSystemService>(profile); service->Initialize(LocalFileSyncService::Create(profile), RemoteFileSyncService::CreateForBrowserContext( context, service->task_logger()));
diff --git a/chrome/browser/sync_file_system/sync_file_system_service_factory.h b/chrome/browser/sync_file_system/sync_file_system_service_factory.h index b5c7bd9..7796593 100644 --- a/chrome/browser/sync_file_system/sync_file_system_service_factory.h +++ b/chrome/browser/sync_file_system/sync_file_system_service_factory.h
@@ -33,7 +33,7 @@ ~SyncFileSystemServiceFactory() override; // BrowserContextKeyedServiceFactory overrides. - KeyedService* BuildServiceInstanceFor( + std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const override; };
diff --git a/chrome/browser/ui/android/cars/BUILD.gn b/chrome/browser/ui/android/cars/BUILD.gn index 56a2f62e..8851af9 100644 --- a/chrome/browser/ui/android/cars/BUILD.gn +++ b/chrome/browser/ui/android/cars/BUILD.gn
@@ -5,33 +5,12 @@ import("//build/config/android/rules.gni") android_library("java") { - sources = [ "java/src/org/chromium/chrome/browser/ui/cars/DrivingRestrictionsManager.java" ] - - deps = [ "//base:base_java" ] - - public_deps = [ ":delegate_java" ] -} - -android_library("delegate_java") { sources = [ "java/src/org/chromium/chrome/browser/ui/cars/DrivingRestrictionsDelegate.java", - "java/src/org/chromium/chrome/browser/ui/cars/DrivingRestrictionsDelegateImpl.java", + "java/src/org/chromium/chrome/browser/ui/cars/DrivingRestrictionsManager.java", ] deps = [ "//base:base_java" ] - - # Add the actual implementation where necessary so that downstream targets - # can provide their own implementations. - jar_excluded_patterns = [ "*/DrivingRestrictionsDelegateImpl.class" ] -} - -android_library("delegate_public_impl_java") { - sources = [ "java/src/org/chromium/chrome/browser/ui/cars/DrivingRestrictionsDelegateImpl.java" ] - - deps = [ - ":delegate_java", - "//base:base_java", - ] } robolectric_library("junit") {
diff --git a/chrome/browser/ui/android/cars/java/src/org/chromium/chrome/browser/ui/cars/DrivingRestrictionsDelegateImpl.java b/chrome/browser/ui/android/cars/java/src/org/chromium/chrome/browser/ui/cars/DrivingRestrictionsDelegateImpl.java deleted file mode 100644 index f209ac7a..0000000 --- a/chrome/browser/ui/android/cars/java/src/org/chromium/chrome/browser/ui/cars/DrivingRestrictionsDelegateImpl.java +++ /dev/null
@@ -1,19 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.chrome.browser.ui.cars; - -import org.chromium.base.Callback; - -/** - * Instantiable version of {@link DrivingRestrictionsDelegate}, don't add anything to this class. - * Downstream targets may provide a different implementation. In GN, we specify that - * {@link DrivingRestrictionsDelegate} is compiled separately from its implementation; other - * projects may specify a different DrivingRestrictionsDelegate via GN. - */ -class DrivingRestrictionsDelegateImpl extends DrivingRestrictionsDelegate { - DrivingRestrictionsDelegateImpl(Callback<Boolean> requiresDrivingOptimizationsCallback) { - super(requiresDrivingOptimizationsCallback); - } -}
diff --git a/chrome/browser/ui/android/cars/java/src/org/chromium/chrome/browser/ui/cars/DrivingRestrictionsManager.java b/chrome/browser/ui/android/cars/java/src/org/chromium/chrome/browser/ui/cars/DrivingRestrictionsManager.java index 0c7b759..bb02d3b 100644 --- a/chrome/browser/ui/android/cars/java/src/org/chromium/chrome/browser/ui/cars/DrivingRestrictionsManager.java +++ b/chrome/browser/ui/android/cars/java/src/org/chromium/chrome/browser/ui/cars/DrivingRestrictionsManager.java
@@ -15,7 +15,7 @@ public class DrivingRestrictionsManager { private static DrivingRestrictionsManager sInstance; - private DrivingRestrictionsDelegateImpl mDelegate; + private DrivingRestrictionsDelegate mDelegate; private boolean mMonitoring; /** @@ -26,8 +26,7 @@ } DrivingRestrictionsManager() { - mDelegate = - new DrivingRestrictionsDelegateImpl(this::onRequiresDistractionOptimizationChanged); + mDelegate = new DrivingRestrictionsDelegate(this::onRequiresDistractionOptimizationChanged); updateMonitoring(ApplicationStatus.getStateForApplication()); ApplicationStatus.registerApplicationStateListener(newState -> updateMonitoring(newState)); @@ -51,15 +50,11 @@ } } - void setDelegateForTesting(DrivingRestrictionsDelegateImpl delegate) { + void setDelegateForTesting(DrivingRestrictionsDelegate delegate) { mDelegate = delegate; } - DrivingRestrictionsDelegateImpl getDelegateForTesting() { + DrivingRestrictionsDelegate getDelegateForTesting() { return mDelegate; } - - static DrivingRestrictionsManager getInstanceForTesting() { - return sInstance; - } }
diff --git a/chrome/browser/ui/android/cars/java/src/org/chromium/chrome/browser/ui/cars/DrivingRestrictionsManagerTest.java b/chrome/browser/ui/android/cars/java/src/org/chromium/chrome/browser/ui/cars/DrivingRestrictionsManagerTest.java index 6aa3145d..1edea52e 100644 --- a/chrome/browser/ui/android/cars/java/src/org/chromium/chrome/browser/ui/cars/DrivingRestrictionsManagerTest.java +++ b/chrome/browser/ui/android/cars/java/src/org/chromium/chrome/browser/ui/cars/DrivingRestrictionsManagerTest.java
@@ -28,7 +28,7 @@ public class DrivingRestrictionsManagerTest { private DrivingRestrictionsManager mManager; @Spy - private DrivingRestrictionsDelegateImpl mSpyDelegate; + private DrivingRestrictionsDelegate mSpyDelegate; @Before public void setUp() {
diff --git a/chrome/browser/ui/ash/glanceables/glanceables_browsertest.cc b/chrome/browser/ui/ash/glanceables/glanceables_browsertest.cc index 4666657..ca02ad0d 100644 --- a/chrome/browser/ui/ash/glanceables/glanceables_browsertest.cc +++ b/chrome/browser/ui/ash/glanceables/glanceables_browsertest.cc
@@ -8,11 +8,22 @@ #include "ash/constants/ash_features.h" #include "ash/constants/ash_switches.h" #include "ash/glanceables/classroom/glanceables_classroom_client.h" +#include "ash/glanceables/common/glanceables_view_id.h" #include "ash/glanceables/glanceables_controller.h" #include "ash/glanceables/glanceables_v2_controller.h" +#include "ash/glanceables/tasks/fake_glanceables_tasks_client.h" +#include "ash/glanceables/tasks/glanceables_task_view.h" +#include "ash/public/cpp/shell_window_ids.h" #include "ash/shell.h" +#include "ash/style/combobox.h" +#include "ash/system/status_area_widget_test_helper.h" +#include "ash/system/unified/date_tray.h" +#include "ash/system/unified/glanceable_tray_bubble.h" +#include "ash/system/unified/tasks_bubble_view.h" +#include "ash/test/ash_test_util.h" #include "base/memory/raw_ptr.h" #include "base/test/scoped_feature_list.h" +#include "base/types/cxx23_to_underlying.h" #include "chrome/browser/ash/profiles/profile_helper.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/profiles/profile.h" @@ -32,13 +43,60 @@ #include "components/user_manager/user_manager.h" #include "content/public/test/browser_test.h" #include "testing/gtest/include/gtest/gtest.h" +#include "ui/events/test/event_generator.h" +#include "ui/views/controls/menu/menu_item_view.h" +#include "ui/views/view_utils.h" #include "url/gurl.h" +namespace ash { namespace { constexpr char kTestUserName[] = "test@test.test"; constexpr char kTestUserGaiaId[] = "123456"; +constexpr char kDueDate[] = "2 Aug 2025 10:00 GMT"; + +views::Label* FindViewWithLabel(views::View* search_root, + const std::u16string& label) { + if (views::Label* const label_view = + views::AsViewClass<views::Label>(search_root); + label_view && label_view->GetText() == label) { + return label_view; + } + + // Keep searching in children views. + for (views::View* const child : search_root->children()) { + if (views::Label* const found = FindViewWithLabel(child, label)) { + return found; + } + } + + return nullptr; +} + +views::Label* FindViewWithLabelFromWindow(aura::Window* search_root, + const std::u16string& label) { + if (views::Widget* const root_widget = + views::Widget::GetWidgetForNativeWindow(search_root)) { + return FindViewWithLabel(root_widget->GetRootView(), label); + } + + for (aura::Window* const child : search_root->children()) { + if (auto* found = FindViewWithLabelFromWindow(child, label)) { + return found; + } + } + + return nullptr; +} + +views::Label* FindMenuItemLabelWithString(const std::u16string& label) { + return FindViewWithLabelFromWindow( + Shell::GetContainer(Shell::GetPrimaryRootWindow(), + kShellWindowId_MenuContainer), + label); +} + } // namespace // Tests for the glanceables feature, which adds a "welcome back" screen on @@ -49,16 +107,16 @@ InProcessBrowserTest::SetUpDefaultCommandLine(command_line); // The test harness adds --no-first-run. Remove it so glanceables show up. - command_line->RemoveSwitch(switches::kNoFirstRun); + command_line->RemoveSwitch(::switches::kNoFirstRun); // Don't open a browser window, because doing so would hide glanceables. // Note that InProcessBrowserTest::browser() will be null. - command_line->AppendSwitch(switches::kNoStartupWindow); + command_line->AppendSwitch(::switches::kNoStartupWindow); - command_line->AppendSwitch(ash::switches::kLoginManager); - command_line->AppendSwitchASCII(ash::switches::kLoginProfile, + command_line->AppendSwitch(switches::kLoginManager); + command_line->AppendSwitchASCII(switches::kLoginProfile, TestingProfile::kTestUserProfileDir); - command_line->AppendSwitch(ash::switches::kAllowFailedPolicyFetchForTest); + command_line->AppendSwitch(switches::kAllowFailedPolicyFetchForTest); } void CreateAndStartUserSession() { @@ -69,7 +127,7 @@ profile_ = &profiles::testing::CreateProfileSync( g_browser_process->profile_manager(), - ash::ProfileHelper::GetProfilePathByUserIdHash( + ProfileHelper::GetProfilePathByUserIdHash( user_manager::UserManager::Get() ->FindUser(account_id) ->username_hash())); @@ -78,8 +136,8 @@ session_manager->SessionStarted(); } - ash::GlanceablesController* glanceables_controller() { - return ash::Shell::Get()->glanceables_controller(); + GlanceablesController* glanceables_controller() { + return Shell::Get()->glanceables_controller(); } signin::IdentityManager* identity_manager() { @@ -87,7 +145,7 @@ } protected: - base::test::ScopedFeatureList features_{ash::features::kGlanceables}; + base::test::ScopedFeatureList features_{features::kGlanceables}; raw_ptr<Profile, ExperimentalAsh> profile_ = nullptr; }; @@ -117,12 +175,90 @@ class GlanceablesV2BrowserTest : public InProcessBrowserTest { public: - ash::GlanceablesV2Controller* glanceables_controller() { - return ash::Shell::Get()->glanceables_v2_controller(); + GlanceablesV2Controller* glanceables_controller() { + return Shell::Get()->glanceables_v2_controller(); + } + + void SetUpOnMainThread() override { + InProcessBrowserTest::SetUpOnMainThread(); + + base::Time date; + ASSERT_TRUE(base::Time::FromString(kDueDate, &date)); + fake_glanceables_tasks_client_ = + std::make_unique<FakeGlanceablesTasksClient>(date); + Shell::Get()->glanceables_v2_controller()->UpdateClientsRegistration( + account_id_, + GlanceablesV2Controller::ClientsRegistration{ + .classroom_client = glanceables_controller()->GetClassroomClient(), + .tasks_client = fake_glanceables_tasks_client_.get()}); + Shell::Get()->glanceables_v2_controller()->OnActiveUserSessionChanged( + account_id_); + + date_tray_ = StatusAreaWidgetTestHelper::GetStatusAreaWidget()->date_tray(); + event_generator_ = std::make_unique<ui::test::EventGenerator>( + Shell::GetPrimaryRootWindow()); + } + + DateTray* GetDateTray() const { return date_tray_; } + + ui::test::EventGenerator* GetEventGenerator() const { + return event_generator_.get(); + } + + GlanceableTrayBubble* GetGlanceableTrayBubble() const { + return date_tray_->bubble_.get(); + } + + FakeGlanceablesTasksClient* fake_glanceables_tasks_client() const { + return fake_glanceables_tasks_client_.get(); + } + + TasksBubbleView* GetTasksView() const { + return GetGlanceableTrayBubble()->GetTasksView(); + } + + Combobox* GetTasksComboBoxView() const { + return views::AsViewClass<Combobox>(GetTasksView()->GetViewByID( + base::to_underlying(GlanceablesViewId::kTasksBubbleComboBox))); + } + + views::View* GetTasksItemContainerView() const { + return views::AsViewClass<views::View>(GetTasksView()->GetViewByID( + base::to_underlying(GlanceablesViewId::kTasksBubbleListContainer))); + } + + views::LabelButton* GetTaskListFooterSeeAllButton() const { + return views::AsViewClass<views::LabelButton>(GetTasksView()->GetViewByID( + base::to_underlying(GlanceablesViewId::kListFooterSeeAllButton))); + } + + std::vector<std::string> GetCurrentTaskListItemTitles() const { + std::vector<std::string> current_items; + for (views::View* child : GetTasksItemContainerView()->children()) { + if (views::View* task_item = views::AsViewClass<views::View>(child)) { + current_items.push_back( + base::UTF16ToUTF8(views::AsViewClass<views::Label>( + task_item->GetViewByID(base::to_underlying( + GlanceablesViewId::kTaskItemTitleLabel))) + ->GetText())); + } + } + return current_items; + } + + GlanceablesTaskView* GetTaskItemView(int item_index) { + return views::AsViewClass<GlanceablesTaskView>( + GetTasksItemContainerView()->children()[item_index]); } private: - base::test::ScopedFeatureList features_{ash::features::kGlanceablesV2}; + raw_ptr<DateTray, ExperimentalAsh> date_tray_; + std::unique_ptr<ui::test::EventGenerator> event_generator_; + AccountId account_id_ = + AccountId::FromUserEmailGaiaId(kTestUserName, kTestUserGaiaId); + std::unique_ptr<FakeGlanceablesTasksClient> fake_glanceables_tasks_client_; + + base::test::ScopedFeatureList features_{features::kGlanceablesV2}; }; IN_PROC_BROWSER_TEST_F(GlanceablesV2BrowserTest, OpensClassroomUrlInBrowser) { @@ -135,3 +271,125 @@ browser()->tab_strip_model()->GetActiveWebContents()->GetVisibleURL(), classroom_url); } + +IN_PROC_BROWSER_TEST_F(GlanceablesV2BrowserTest, ViewAndSwitchTaskLists) { + ASSERT_TRUE(glanceables_controller()->GetTasksClient()); + EXPECT_FALSE(GetGlanceableTrayBubble()); + + GetEventGenerator()->MoveMouseTo( + GetDateTray()->GetBoundsInScreen().CenterPoint()); + GetEventGenerator()->ClickLeftButton(); + + EXPECT_TRUE(GetGlanceableTrayBubble()); + EXPECT_TRUE(GetTasksView()); + + // Check that the tasks glanceable is completely shown on the primary screen. + EXPECT_TRUE( + Shell::Get()->GetPrimaryRootWindow()->GetBoundsInScreen().Contains( + GetTasksView()->GetBoundsInScreen())); + + // Check that task list items from the first list are shown. + EXPECT_EQ(GetCurrentTaskListItemTitles(), + std::vector<std::string>( + {"Task List 1 Item 1 Title", "Task List 1 Item 2 Title"})); + + // Click on the combo box to show the task lists. + GetEventGenerator()->MoveMouseTo( + GetTasksComboBoxView()->GetBoundsInScreen().CenterPoint()); + GetEventGenerator()->ClickLeftButton(); + + views::Label* second_menu_item_label = + FindMenuItemLabelWithString(u"Task List 2 Title"); + + // Click on the second menu item label to switch to the second task list. + ASSERT_TRUE(second_menu_item_label); + GetEventGenerator()->MoveMouseTo( + second_menu_item_label->GetBoundsInScreen().CenterPoint()); + GetEventGenerator()->ClickLeftButton(); + + // Make sure that task list items from the second list are shown. + EXPECT_EQ(GetCurrentTaskListItemTitles(), + std::vector<std::string>({"Task List 2 Item 1 Title", + "Task List 2 Item 2 Title", + "Task List 2 Item 3 Title"})); +} + +IN_PROC_BROWSER_TEST_F(GlanceablesV2BrowserTest, ClickSeeAllTasksButton) { + ASSERT_TRUE(glanceables_controller()->GetTasksClient()); + EXPECT_FALSE(GetGlanceableTrayBubble()); + + // Click the date tray to show the glanceable bubbles. + GetEventGenerator()->MoveMouseTo( + GetDateTray()->GetBoundsInScreen().CenterPoint()); + GetEventGenerator()->ClickLeftButton(); + + EXPECT_TRUE(GetGlanceableTrayBubble()); + EXPECT_TRUE(GetTasksView()); + + // Check that the tasks glanceable is completely shown on the primary screen. + EXPECT_TRUE( + Shell::Get()->GetPrimaryRootWindow()->GetBoundsInScreen().Contains( + GetTasksView()->GetBoundsInScreen())); + + // Check that task list items from the first list are shown. + EXPECT_EQ(GetCurrentTaskListItemTitles(), + std::vector<std::string>( + {"Task List 1 Item 1 Title", "Task List 1 Item 2 Title"})); + + // Click the "See All" button in the tasks glanceable footer, and check that + // the correct URL is opened. + GetEventGenerator()->MoveMouseTo( + GetTaskListFooterSeeAllButton()->GetBoundsInScreen().CenterPoint()); + GetEventGenerator()->ClickLeftButton(); + EXPECT_EQ( + browser()->tab_strip_model()->GetActiveWebContents()->GetURL().spec(), + "https://calendar.google.com/calendar/u/0/r/week?opentasks=1"); +} + +IN_PROC_BROWSER_TEST_F(GlanceablesV2BrowserTest, CheckOffTaskItems) { + ASSERT_TRUE(glanceables_controller()->GetTasksClient()); + EXPECT_FALSE(GetGlanceableTrayBubble()); + + // Click the date tray to show the glanceable bubbles. + GetEventGenerator()->MoveMouseTo( + GetDateTray()->GetBoundsInScreen().CenterPoint()); + GetEventGenerator()->ClickLeftButton(); + + EXPECT_TRUE(GetGlanceableTrayBubble()); + EXPECT_TRUE(GetTasksView()); + + // Check that the tasks glanceable is completely shown on the primary screen. + EXPECT_TRUE( + Shell::Get()->GetPrimaryRootWindow()->GetBoundsInScreen().Contains( + GetTasksView()->GetBoundsInScreen())); + + // Check that task list items from the first list are shown. + EXPECT_EQ(GetCurrentTaskListItemTitles(), + std::vector<std::string>( + {"Task List 1 Item 1 Title", "Task List 1 Item 2 Title"})); + + EXPECT_FALSE(GetTaskItemView(/*item_index=*/0)->GetCompletedForTest()); + EXPECT_FALSE(GetTaskItemView(/*item_index=*/1)->GetCompletedForTest()); + + // Click to check off the first task item and check that it has been marked + // complete. + GetEventGenerator()->MoveMouseTo(GetTaskItemView(/*item_index=*/0) + ->GetButtonForTest() + ->GetBoundsInScreen() + .CenterPoint()); + GetEventGenerator()->ClickLeftButton(); + EXPECT_TRUE(GetTaskItemView(/*item_index=*/0)->GetCompletedForTest()); + EXPECT_FALSE(GetTaskItemView(/*item_index=*/1)->GetCompletedForTest()); + + // Click to check off the second task item and check that it has been marked + // complete. + GetEventGenerator()->MoveMouseTo(GetTaskItemView(/*item_index=*/1) + ->GetButtonForTest() + ->GetBoundsInScreen() + .CenterPoint()); + GetEventGenerator()->ClickLeftButton(); + EXPECT_TRUE(GetTaskItemView(/*item_index=*/0)->GetCompletedForTest()); + EXPECT_TRUE(GetTaskItemView(/*item_index=*/1)->GetCompletedForTest()); +} + +} // namespace ash
diff --git a/chrome/browser/ui/ash/global_media_controls/cast_media_notification_producer_keyed_service_factory.cc b/chrome/browser/ui/ash/global_media_controls/cast_media_notification_producer_keyed_service_factory.cc index c34d7790..ec207f9 100644 --- a/chrome/browser/ui/ash/global_media_controls/cast_media_notification_producer_keyed_service_factory.cc +++ b/chrome/browser/ui/ash/global_media_controls/cast_media_notification_producer_keyed_service_factory.cc
@@ -43,13 +43,13 @@ GetInstance()->GetServiceForBrowserContext(profile, true)); } -KeyedService* -CastMediaNotificationProducerKeyedServiceFactory::BuildServiceInstanceFor( - content::BrowserContext* context) const { +std::unique_ptr<KeyedService> CastMediaNotificationProducerKeyedServiceFactory:: + BuildServiceInstanceForBrowserContext( + content::BrowserContext* context) const { if (!media_router::MediaRouterEnabled(context)) { return nullptr; } - return new CastMediaNotificationProducerKeyedService( + return std::make_unique<CastMediaNotificationProducerKeyedService>( Profile::FromBrowserContext(context)); }
diff --git a/chrome/browser/ui/ash/global_media_controls/cast_media_notification_producer_keyed_service_factory.h b/chrome/browser/ui/ash/global_media_controls/cast_media_notification_producer_keyed_service_factory.h index 06bdd2a..5edc4882 100644 --- a/chrome/browser/ui/ash/global_media_controls/cast_media_notification_producer_keyed_service_factory.h +++ b/chrome/browser/ui/ash/global_media_controls/cast_media_notification_producer_keyed_service_factory.h
@@ -30,7 +30,7 @@ private: // BrowserContextKeyedServiceFactory: - KeyedService* BuildServiceInstanceFor( + std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const override; bool ServiceIsCreatedWithBrowserContext() const override; bool ServiceIsNULLWhileTesting() const override;
diff --git a/chrome/browser/ui/ash/holding_space/holding_space_keyed_service_factory.cc b/chrome/browser/ui/ash/holding_space/holding_space_keyed_service_factory.cc index 07c85d6..e166d55 100644 --- a/chrome/browser/ui/ash/holding_space/holding_space_keyed_service_factory.cc +++ b/chrome/browser/ui/ash/holding_space/holding_space_keyed_service_factory.cc
@@ -38,7 +38,7 @@ BrowserContextKeyedServiceFactory::TestingFactory HoldingSpaceKeyedServiceFactory::GetDefaultTestingFactory() { return base::BindRepeating([](content::BrowserContext* context) { - return base::WrapUnique(BuildServiceInstanceForInternal(context)); + return BuildServiceInstanceForInternal(context); }); } @@ -77,15 +77,17 @@ return profile->IsOffTheRecord() ? nullptr : context; } -KeyedService* HoldingSpaceKeyedServiceFactory::BuildServiceInstanceFor( +std::unique_ptr<KeyedService> +HoldingSpaceKeyedServiceFactory::BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const { TestingFactory* testing_factory = GetTestingFactory(); return testing_factory->is_null() ? BuildServiceInstanceForInternal(context) - : testing_factory->Run(context).release(); + : testing_factory->Run(context); } // static -KeyedService* HoldingSpaceKeyedServiceFactory::BuildServiceInstanceForInternal( +std::unique_ptr<KeyedService> +HoldingSpaceKeyedServiceFactory::BuildServiceInstanceForInternal( content::BrowserContext* context) { Profile* const profile = Profile::FromBrowserContext(context); DCHECK_EQ(profile->IsGuestSession(), profile->IsOffTheRecord()); @@ -97,7 +99,8 @@ if (user->GetType() == user_manager::USER_TYPE_KIOSK_APP) return nullptr; - return new HoldingSpaceKeyedService(profile, user->GetAccountId()); + return std::make_unique<HoldingSpaceKeyedService>(profile, + user->GetAccountId()); } void HoldingSpaceKeyedServiceFactory::RegisterProfilePrefs(
diff --git a/chrome/browser/ui/ash/holding_space/holding_space_keyed_service_factory.h b/chrome/browser/ui/ash/holding_space/holding_space_keyed_service_factory.h index ef283b0..f4e899d4 100644 --- a/chrome/browser/ui/ash/holding_space/holding_space_keyed_service_factory.h +++ b/chrome/browser/ui/ash/holding_space/holding_space_keyed_service_factory.h
@@ -31,7 +31,7 @@ // BrowserContextKeyedServiceFactory: content::BrowserContext* GetBrowserContextToUse( content::BrowserContext* context) const override; - KeyedService* BuildServiceInstanceFor( + std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const override; void RegisterProfilePrefs( user_prefs::PrefRegistrySyncable* registry) override; @@ -45,7 +45,7 @@ HoldingSpaceKeyedServiceFactory& operator=( const HoldingSpaceKeyedServiceFactory& other) = delete; - static KeyedService* BuildServiceInstanceForInternal( + static std::unique_ptr<KeyedService> BuildServiceInstanceForInternal( content::BrowserContext* context); };
diff --git a/chrome/browser/ui/autofill/payments/save_card_bubble_controller_impl.cc b/chrome/browser/ui/autofill/payments/save_card_bubble_controller_impl.cc index 8b69b0b..de0c0e6 100644 --- a/chrome/browser/ui/autofill/payments/save_card_bubble_controller_impl.cc +++ b/chrome/browser/ui/autofill/payments/save_card_bubble_controller_impl.cc
@@ -200,6 +200,13 @@ if (current_bubble_type_ == BubbleType::FAILURE) return l10n_util::GetStringUTF16(IDS_AUTOFILL_FAILURE_BUBBLE_EXPLANATION); + if (current_bubble_type_ == BubbleType::LOCAL_SAVE && + base::FeatureList::IsEnabled( + features::kAutofillEnableCvcStorageAndFilling)) { + return l10n_util::GetStringUTF16( + IDS_AUTOFILL_SAVE_CARD_PROMPT_EXPLANATION_LOCAL); + } + if (current_bubble_type_ == BubbleType::LOCAL_CVC_SAVE) { return l10n_util::GetStringUTF16( IDS_AUTOFILL_SAVE_CVC_PROMPT_EXPLANATION_LOCAL);
diff --git a/chrome/browser/ui/autofill/payments/save_card_bubble_controller_impl_unittest.cc b/chrome/browser/ui/autofill/payments/save_card_bubble_controller_impl_unittest.cc index 76d6ab2..bb77a30a 100644 --- a/chrome/browser/ui/autofill/payments/save_card_bubble_controller_impl_unittest.cc +++ b/chrome/browser/ui/autofill/payments/save_card_bubble_controller_impl_unittest.cc
@@ -624,6 +624,56 @@ autofill_metrics::SaveCardPromptResult::kUnknown, 1); } +TEST_F(SaveCardBubbleControllerImplTest, LocalCardSaveDialogContent) { + scoped_feature_list_.InitAndEnableFeature( + features::kAutofillEnableCvcStorageAndFilling); + + // Show the local card save bubble. + ShowLocalBubble( + /*card=*/nullptr, + /*options=*/AutofillClient::SaveCreditCardOptions() + .with_cvc_save_only(false) + .with_show_prompt(true)); + + ASSERT_EQ(BubbleType::LOCAL_SAVE, controller()->GetBubbleType()); + ASSERT_NE(nullptr, controller()->GetPaymentBubbleView()); + EXPECT_EQ(controller()->GetWindowTitle(), u"Save card?"); + EXPECT_EQ(controller()->GetExplanatoryMessage(), + u"To pay faster next time, save your card to your device"); +} + +TEST_F(SaveCardBubbleControllerImplTest, LocalCvcOnlySaveDialogContent) { + // Show the local CVC save bubble. + ShowLocalBubble( + /*card=*/nullptr, + /*options=*/AutofillClient::SaveCreditCardOptions() + .with_cvc_save_only(true) + .with_show_prompt(true)); + + ASSERT_EQ(BubbleType::LOCAL_CVC_SAVE, controller()->GetBubbleType()); + ASSERT_NE(nullptr, controller()->GetPaymentBubbleView()); + EXPECT_EQ(controller()->GetWindowTitle(), u"Save security code?"); + EXPECT_EQ(controller()->GetExplanatoryMessage(), + u"For faster checkout, save the CVC for this card to your device"); +} + +TEST_F(SaveCardBubbleControllerImplTest, UploadCardSaveDialogContent) { + scoped_feature_list_.InitAndEnableFeature( + features::kAutofillEnableNewSaveCardBubbleUi); + + // Show the server card save bubble. + ShowUploadBubble( + /*options=*/AutofillClient::SaveCreditCardOptions().with_show_prompt( + true)); + + ASSERT_EQ(BubbleType::UPLOAD_SAVE, controller()->GetBubbleType()); + ASSERT_NE(nullptr, controller()->GetPaymentBubbleView()); + EXPECT_EQ(controller()->GetWindowTitle(), u"Save card?"); + EXPECT_EQ(controller()->GetExplanatoryMessage(), + u"Pay faster next time and protect your card with Google’s " + u"industry-leading security."); +} + TEST_F(SaveCardBubbleControllerImplTest, LocalCard_FirstShow_SaveButton_SigninPromo_Close_Reshow_ManageCards) { EXPECT_CALL(*mock_sentiment_service_, SavedCard()).Times(1); @@ -638,8 +688,8 @@ // After closing the sign-in promo, clicking the icon should bring up the // Manage cards bubble. Verify that the icon tooltip, the title for the // bubble, and the save animation reflect the correct info. - EXPECT_EQ(BubbleType::MANAGE_CARDS, controller()->GetBubbleType()); - EXPECT_NE(nullptr, controller()->GetPaymentBubbleView()); + ASSERT_EQ(BubbleType::MANAGE_CARDS, controller()->GetBubbleType()); + ASSERT_NE(nullptr, controller()->GetPaymentBubbleView()); EXPECT_EQ(controller()->GetWindowTitle(), u"Card saved"); EXPECT_EQ(controller()->GetSavePaymentIconTooltipText(), u"Save card"); EXPECT_EQ(controller()->GetSaveSuccessAnimationStringId(), @@ -660,8 +710,8 @@ // After closing the sign-in promo, clicking the icon should bring up the // Manage cards bubble. Verify that the icon tooltip, the title for the // bubble, and the save animation reflect the correct info. - EXPECT_EQ(BubbleType::MANAGE_CARDS, controller()->GetBubbleType()); - EXPECT_NE(nullptr, controller()->GetPaymentBubbleView()); + ASSERT_EQ(BubbleType::MANAGE_CARDS, controller()->GetBubbleType()); + ASSERT_NE(nullptr, controller()->GetPaymentBubbleView()); EXPECT_EQ(controller()->GetWindowTitle(), u"CVC saved"); EXPECT_EQ(controller()->GetSavePaymentIconTooltipText(), u"Save CVC"); EXPECT_EQ(controller()->GetSaveSuccessAnimationStringId(), @@ -675,7 +725,7 @@ ShowLocalBubble(); ClickSaveButton(); CloseAndReshowBubble(); - EXPECT_EQ(BubbleType::MANAGE_CARDS, controller()->GetBubbleType()); + ASSERT_EQ(BubbleType::MANAGE_CARDS, controller()->GetBubbleType()); ClickSaveButton(); EXPECT_THAT(
diff --git a/chrome/browser/ui/cocoa/screentime/history_bridge_factory.h b/chrome/browser/ui/cocoa/screentime/history_bridge_factory.h index 6ae32ed84..cf2cd8a 100644 --- a/chrome/browser/ui/cocoa/screentime/history_bridge_factory.h +++ b/chrome/browser/ui/cocoa/screentime/history_bridge_factory.h
@@ -25,7 +25,7 @@ static bool IsEnabled(); // BrowserContextKeyedServiceFactory: - KeyedService* BuildServiceInstanceFor( + std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const override; bool ServiceIsCreatedWithBrowserContext() const override; bool ServiceIsNULLWhileTesting() const override;
diff --git a/chrome/browser/ui/cocoa/screentime/history_bridge_factory.mm b/chrome/browser/ui/cocoa/screentime/history_bridge_factory.mm index c8617c30..a2cefb3 100644 --- a/chrome/browser/ui/cocoa/screentime/history_bridge_factory.mm +++ b/chrome/browser/ui/cocoa/screentime/history_bridge_factory.mm
@@ -28,7 +28,8 @@ return base::FeatureList::IsEnabled(kScreenTime); } -KeyedService* HistoryBridgeFactory::BuildServiceInstanceFor( +std::unique_ptr<KeyedService> +HistoryBridgeFactory::BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const { auto* profile = Profile::FromBrowserContext(context); auto* service = HistoryServiceFactory::GetForProfile( @@ -36,7 +37,7 @@ auto deleter = HistoryDeleterImpl::Create(); - return new HistoryBridge(service, std::move(deleter)); + return std::make_unique<HistoryBridge>(service, std::move(deleter)); } bool HistoryBridgeFactory::ServiceIsCreatedWithBrowserContext() const {
diff --git a/chrome/browser/ui/extensions/application_launch.cc b/chrome/browser/ui/extensions/application_launch.cc index 1073123..42a4d919 100644 --- a/chrome/browser/ui/extensions/application_launch.cc +++ b/chrome/browser/ui/extensions/application_launch.cc
@@ -7,6 +7,7 @@ #include <memory> #include <string> #include <utility> +#include <vector> #include "apps/launcher.h" #include "base/command_line.h" @@ -59,10 +60,6 @@ #include "ui/display/scoped_display_for_new_windows.h" #include "ui/gfx/geometry/rect.h" -#if BUILDFLAG(IS_MAC) -#include "chrome/browser/ui/browser_commands_mac.h" -#endif - using content::WebContents; using extensions::Extension; using extensions::ExtensionPrefs; @@ -89,7 +86,7 @@ EnableViaDialogFlow(const EnableViaDialogFlow&) = delete; EnableViaDialogFlow& operator=(const EnableViaDialogFlow&) = delete; - ~EnableViaDialogFlow() override {} + ~EnableViaDialogFlow() override = default; void Run() { DCHECK(!service_->IsExtensionEnabled(extension_id_)); @@ -111,9 +108,9 @@ void ExtensionEnableFlowAborted(bool user_initiated) override { delete this; } - raw_ptr<ExtensionService> service_; - raw_ptr<ExtensionRegistry> registry_; - raw_ptr<Profile> profile_; + const raw_ptr<ExtensionService> service_; + const raw_ptr<ExtensionRegistry> registry_; + const raw_ptr<Profile> profile_; extensions::ExtensionId extension_id_; base::OnceClosure callback_; std::unique_ptr<ExtensionEnableFlow> flow_; @@ -183,10 +180,12 @@ // LAUNCH_TYPE_WINDOW launches in a default app window. extensions::LaunchType launch_type = extensions::GetLaunchType(ExtensionPrefs::Get(profile), extension); - if (launch_type == extensions::LAUNCH_TYPE_FULLSCREEN) + if (launch_type == extensions::LAUNCH_TYPE_FULLSCREEN) { return ui::SHOW_STATE_MAXIMIZED; - else if (launch_type == extensions::LAUNCH_TYPE_WINDOW) + } + if (launch_type == extensions::LAUNCH_TYPE_WINDOW) { return ui::SHOW_STATE_DEFAULT; + } #endif return ui::SHOW_STATE_DEFAULT; @@ -569,13 +568,12 @@ if (!service->IsExtensionEnabled(extension->id()) || registry->GetExtensionById(extension->id(), ExtensionRegistry::TERMINATED)) { - // TODO(pkotwicz): Figure out which window should be used as the parent for - // the "enable application" dialog in Athena. - (new EnableViaDialogFlow( - service, registry, profile, extension->id(), - base::BindOnce(base::IgnoreResult(OpenEnabledApplication), profile, - std::move(params)))) - ->Run(); + // Self deleting. + auto* flow = new EnableViaDialogFlow( + service, registry, profile, extension->id(), + base::BindOnce(base::IgnoreResult(OpenEnabledApplication), profile, + std::move(params))); + flow->Run(); return; } @@ -589,12 +587,7 @@ WindowOpenDisposition::NEW_WINDOW, apps::LaunchSource::kFromCommandLine); launch_params.override_url = url; - WebContents* tab = OpenApplicationWindow(profile, launch_params, url); - - if (!tab) - return nullptr; - - return tab; + return OpenApplicationWindow(profile, launch_params, url); } bool CanLaunchViaEvent(const extensions::Extension* extension) { @@ -628,20 +621,22 @@ bool ShowBrowserForProfile(Profile* profile, const apps::AppLaunchParams& params) { Browser* browser = chrome::FindTabbedBrowser( - profile, /*match_original_profiles*/ false, params.display_id); + profile, /*match_original_profiles=*/false, params.display_id); if (browser) { // For existing browser, ensure its window is shown and activated. browser->window()->Show(); browser->window()->Activate(); - } else { - // No browser for this profile, need to open a new one. - if (Browser::GetCreationStatusForProfile(profile) != - Browser::CreationStatus::kOk) { - return false; - } + return true; + } + + // No browser for this profile, need to open a new one. + if (Browser::GetCreationStatusForProfile(profile) == + Browser::CreationStatus::kOk) { browser = Browser::Create( Browser::CreateParams(Browser::TYPE_NORMAL, profile, true)); browser->window()->Show(); + return true; } - return true; + + return false; }
diff --git a/chrome/browser/ui/safety_hub/unused_site_permissions_service.cc b/chrome/browser/ui/safety_hub/unused_site_permissions_service.cc index feaff77..029b567 100644 --- a/chrome/browser/ui/safety_hub/unused_site_permissions_service.cc +++ b/chrome/browser/ui/safety_hub/unused_site_permissions_service.cc
@@ -362,7 +362,9 @@ } DCHECK_EQ(entry.source.primary_pattern, primary_pattern); - DCHECK_EQ(entry.source.secondary_pattern, secondary_pattern); + DCHECK(entry.source.secondary_pattern == + ContentSettingsPattern::Wildcard() || + entry.source.secondary_pattern == entry.source.primary_pattern); // Reset the permission to default if the site is visited before // threshold. Also, the secondary pattern should be wildcard.
diff --git a/chrome/browser/ui/safety_hub/unused_site_permissions_service_browsertest.cc b/chrome/browser/ui/safety_hub/unused_site_permissions_service_browsertest.cc index 6d0bd47..84c7036 100644 --- a/chrome/browser/ui/safety_hub/unused_site_permissions_service_browsertest.cc +++ b/chrome/browser/ui/safety_hub/unused_site_permissions_service_browsertest.cc
@@ -14,6 +14,7 @@ #include "chrome/browser/ui/safety_hub/unused_site_permissions_service_factory.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" +#include "components/content_settings/core/browser/content_settings_registry.h" #include "components/content_settings/core/browser/content_settings_utils.h" #include "components/content_settings/core/browser/host_content_settings_map.h" #include "components/content_settings/core/common/content_settings.h" @@ -138,3 +139,52 @@ EXPECT_EQ(CONTENT_SETTING_ASK, map->GetContentSetting(url, url, ContentSettingsType::GEOLOCATION)); } + +// Test that revocation happens correctly for all content setting types. +IN_PROC_BROWSER_TEST_F(UnusedSitePermissionsServiceBrowserTest, + RevokeAllContentSettingTypes) { + auto* map = + HostContentSettingsMapFactory::GetForProfile(browser()->profile()); + auto* service = + UnusedSitePermissionsServiceFactory::GetForProfile(browser()->profile()); + + base::Time time; + ASSERT_TRUE(base::Time::FromString("2022-09-07 13:00", &time)); + base::SimpleTestClock clock; + clock.SetNow(time); + map->SetClockForTesting(&clock); + service->SetClockForTesting(&clock); + + // Allow all content settings in the content setting registry. + auto* content_settings_registry = + content_settings::ContentSettingsRegistry::GetInstance(); + for (const content_settings::ContentSettingsInfo* info : + *content_settings_registry) { + ContentSettingsType type = info->website_settings_info()->type(); + + // Add last visited timestamp if the setting can be tracked. + content_settings::ContentSettingConstraints constraint; + if (content_settings::CanTrackLastVisit(type)) { + constraint.set_track_last_visit_for_autoexpiration(true); + } + + if (!content_settings_registry->Get(type)->IsSettingValid( + ContentSetting::CONTENT_SETTING_ALLOW)) { + continue; + } + + const GURL url("https://example1.com"); + map->SetContentSettingDefaultScope(GURL(url), GURL(url), type, + ContentSetting::CONTENT_SETTING_ALLOW, + constraint); + } + + // Travel through time for 70 days to make permissions be revoked. + clock.Advance(base::Days(70)); + service->UpdateUnusedPermissionsForTesting(); + ASSERT_EQ(GetRevokedUnusedPermissions(map).size(), 1u); + + // Navigate to content settings page. + ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), + GURL("chrome://settings/content"))); +}
diff --git a/chrome/browser/ui/views/autofill/popup/popup_view_utils.cc b/chrome/browser/ui/views/autofill/popup/popup_view_utils.cc index 56a76c1..51e219c 100644 --- a/chrome/browser/ui/views/autofill/popup/popup_view_utils.cc +++ b/chrome/browser/ui/views/autofill/popup/popup_view_utils.cc
@@ -551,7 +551,6 @@ case PopupItemId::kPasswordAccountStorageReSignin: case PopupItemId::kPasswordAccountStorageOptInAndGenerate: case PopupItemId::kShowAccountCards: - case PopupItemId::kUseVirtualCard: case PopupItemId::kAllSavedPasswordsEntry: case PopupItemId::kFillEverythingFromAddressProfile: case PopupItemId::kClearForm:
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view_chromeos.cc b/chrome/browser/ui/views/frame/browser_non_client_frame_view_chromeos.cc index f8356be..135da3cd 100644 --- a/chrome/browser/ui/views/frame/browser_non_client_frame_view_chromeos.cc +++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view_chromeos.cc
@@ -16,6 +16,7 @@ #include "chrome/browser/themes/theme_properties.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/color/chrome_color_id.h" +#include "chrome/browser/ui/sad_tab_helper.h" #include "chrome/browser/ui/views/frame/browser_frame.h" #include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/browser/ui/views/frame/immersive_mode_controller.h" @@ -23,6 +24,7 @@ #include "chrome/browser/ui/views/frame/tab_strip_region_view.h" #include "chrome/browser/ui/views/frame/top_container_view.h" #include "chrome/browser/ui/views/profiles/profile_indicator_icon.h" +#include "chrome/browser/ui/views/sad_tab_view.h" #include "chrome/browser/ui/views/side_panel/side_panel.h" #include "chrome/browser/ui/views/tab_icon_view.h" #include "chrome/browser/ui/views/tabs/tab_strip.h" @@ -1051,11 +1053,31 @@ ? 0 : corner_radius); + // SideTabView is shown when the renderer crashes. Initially the SabTabView + // gets the same corners as the contents webview it gets attached to but its + // radii needs to be updated as it is unaware of the client view layout + // changes. + bool sad_tab_showing = false; + if (contents_webview->web_contents()) { + if (auto* sad_tab_helper = + SadTabHelper::FromWebContents(contents_webview->web_contents()); + sad_tab_helper->sad_tab()) { + static_cast<SadTabView*>(sad_tab_helper->sad_tab()) + ->SetBackgroundRadii(contents_webview_radii); + sad_tab_showing = true; + } + } + CHECK(contents_webview); CHECK(contents_webview->holder()); contents_webview->SetBackgroundRadii(contents_webview_radii); - contents_webview->holder()->SetCornerRadii(contents_webview_radii); + + // We do not need to round contents_webview, if SadTabView is shown instead of + // contents_webview. + if (!sad_tab_showing) { + contents_webview->holder()->SetCornerRadii(contents_webview_radii); + } } void BrowserNonClientFrameViewChromeOS::LayoutProfileIndicator() {
diff --git a/chrome/browser/ui/views/frame/contents_web_view.h b/chrome/browser/ui/views/frame/contents_web_view.h index 399109e..c454b81 100644 --- a/chrome/browser/ui/views/frame/contents_web_view.h +++ b/chrome/browser/ui/views/frame/contents_web_view.h
@@ -38,6 +38,9 @@ // Toggles whether the background is visible. void SetBackgroundVisible(bool background_visible); + const gfx::RoundedCornersF& background_radii() const { + return background_radii_; + } void SetBackgroundRadii(const gfx::RoundedCornersF& radii); // WebView overrides:
diff --git a/chrome/browser/ui/views/sad_tab_view.cc b/chrome/browser/ui/views/sad_tab_view.cc index 36e1077..b6b07ee 100644 --- a/chrome/browser/ui/views/sad_tab_view.cc +++ b/chrome/browser/ui/views/sad_tab_view.cc
@@ -6,7 +6,6 @@ #include <string> -#include "base/metrics/histogram_macros.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" #include "build/build_config.h" @@ -22,6 +21,7 @@ #include "ui/base/metadata/metadata_impl_macros.h" #include "ui/base/resource/resource_bundle.h" #include "ui/color/color_id.h" +#include "ui/compositor/layer.h" #include "ui/gfx/color_palette.h" #include "ui/gfx/paint_vector_icon.h" #include "ui/native_theme/common_theme.h" @@ -571,9 +571,15 @@ // Needed to ensure this View is drawn even if a sibling (such as dev tools) // has a z-order. SetPaintToLayer(); - AttachToWebView(); + if (owner_) { + // If the `owner_` ContentsWebView has a rounded background, the sad tab + // should also have matching rounded corners as well. + SetBackgroundRadii( + static_cast<ContentsWebView*>(owner_)->background_radii()); + } + // Make the accessibility role of this view an alert dialog, and // put focus on the action button. This causes screen readers to // immediately announce the text of this view. @@ -595,6 +601,15 @@ AttachToWebView(); } +void SadTabView::SetBackgroundRadii(const gfx::RoundedCornersF& radii) { + // Since SadTabView paints onto its own layer and it is leaf layer, we can + // round the background by applying rounded corners to the layer without + // clipping any other browser content. + CHECK(layer()); + layer()->SetRoundedCornerRadius(radii); + layer()->SetIsFastRoundedCorner(/*enable=*/true); +} + void SadTabView::OnPaint(gfx::Canvas* canvas) { if (!painted_) { RecordFirstPaint();
diff --git a/chrome/browser/ui/views/sad_tab_view.h b/chrome/browser/ui/views/sad_tab_view.h index cd168c1..656c336 100644 --- a/chrome/browser/ui/views/sad_tab_view.h +++ b/chrome/browser/ui/views/sad_tab_view.h
@@ -22,7 +22,11 @@ namespace test { class SadTabViewTestApi; -} +} // namespace test + +namespace gfx { +class RoundedCornersF; +} // namespace gfx /////////////////////////////////////////////////////////////////////////////// // @@ -43,6 +47,8 @@ ~SadTabView() override; + void SetBackgroundRadii(const gfx::RoundedCornersF& radii); + // Overridden from SadTab: void ReinstallInWebView() override;
diff --git a/chrome/browser/ui/webui/new_tab_page/new_tab_page_handler.cc b/chrome/browser/ui/webui/new_tab_page/new_tab_page_handler.cc index c42edcb..d12c86a 100644 --- a/chrome/browser/ui/webui/new_tab_page/new_tab_page_handler.cc +++ b/chrome/browser/ui/webui/new_tab_page/new_tab_page_handler.cc
@@ -865,9 +865,6 @@ void NewTabPageHandler::MaybeShowCustomizeChromeFeaturePromo() { CHECK(profile_); CHECK(profile_->GetPrefs()); - const auto customize_chrome_button_open_count = - profile_->GetPrefs()->GetInteger( - prefs::kNtpCustomizeChromeButtonOpenCount); // If a sign-in dialog is being currently displayed, the promo should not be // shown to avoid conflict. The sign-in dialog would be shown as soon as the @@ -875,9 +872,22 @@ bool is_signin_modal_dialog_open = customize_chrome_feature_promo_helper_->IsSigninModalDialogOpen( web_contents_.get()); - if (customize_chrome_button_open_count == 0 && !is_signin_modal_dialog_open) { + if (is_signin_modal_dialog_open) { + return; + } + + if (features::IsChromeRefresh2023()) { customize_chrome_feature_promo_helper_ ->MaybeShowCustomizeChromeFeaturePromo(web_contents_.get()); + } else { + const auto customize_chrome_button_open_count = + profile_->GetPrefs()->GetInteger( + prefs::kNtpCustomizeChromeButtonOpenCount); + + if (customize_chrome_button_open_count == 0) { + customize_chrome_feature_promo_helper_ + ->MaybeShowCustomizeChromeFeaturePromo(web_contents_.get()); + } } }
diff --git a/chrome/browser/ui/webui/ntp/ntp_resource_cache_factory.cc b/chrome/browser/ui/webui/ntp/ntp_resource_cache_factory.cc index d00d56c..ed4ce701 100644 --- a/chrome/browser/ui/webui/ntp/ntp_resource_cache_factory.cc +++ b/chrome/browser/ui/webui/ntp/ntp_resource_cache_factory.cc
@@ -36,7 +36,8 @@ NTPResourceCacheFactory::~NTPResourceCacheFactory() = default; -KeyedService* NTPResourceCacheFactory::BuildServiceInstanceFor( +std::unique_ptr<KeyedService> +NTPResourceCacheFactory::BuildServiceInstanceForBrowserContext( content::BrowserContext* profile) const { - return new NTPResourceCache(static_cast<Profile*>(profile)); + return std::make_unique<NTPResourceCache>(static_cast<Profile*>(profile)); }
diff --git a/chrome/browser/ui/webui/ntp/ntp_resource_cache_factory.h b/chrome/browser/ui/webui/ntp/ntp_resource_cache_factory.h index ec61148b..6925580 100644 --- a/chrome/browser/ui/webui/ntp/ntp_resource_cache_factory.h +++ b/chrome/browser/ui/webui/ntp/ntp_resource_cache_factory.h
@@ -27,7 +27,7 @@ ~NTPResourceCacheFactory() override; // BrowserContextKeyedServiceFactory: - KeyedService* BuildServiceInstanceFor( + std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( content::BrowserContext* profile) const override; };
diff --git a/chrome/browser/ui/webui/settings/ash/files_page/google_drive_handler_browsertest.cc b/chrome/browser/ui/webui/settings/ash/files_page/google_drive_handler_browsertest.cc index 2fc7551..e70dfc0 100644 --- a/chrome/browser/ui/webui/settings/ash/files_page/google_drive_handler_browsertest.cc +++ b/chrome/browser/ui/webui/settings/ash/files_page/google_drive_handler_browsertest.cc
@@ -129,6 +129,29 @@ }); } + base::FilePath CreateFileInContentCache(int file_size_in_bytes) { + auto* const service = + drive::util::GetIntegrationServiceByProfile(browser()->profile()); + { + // Ensure the content cache directory exists. + base::ScopedAllowBlockingForTesting allow_blocking; + if (!base::DirectoryExists(service->GetDriveFsContentCachePath())) { + EXPECT_TRUE( + base::CreateDirectory(service->GetDriveFsContentCachePath())); + } + } + std::string foo_contents = base::RandBytesAsString(file_size_in_bytes); + const base::FilePath file_path = + service->GetDriveFsContentCachePath().Append("foo.txt"); + { + // Create a file of 32 bytes in the content_cache directory. + base::ScopedAllowBlockingForTesting allow_blocking; + EXPECT_TRUE(base::WriteFile(file_path, foo_contents)); + } + + return file_path; + } + protected: OSSettingsBrowserTestMixin os_settings_mixin_{&mixin_host_}; FakeSearchQuery fake_search_query_; @@ -145,10 +168,6 @@ SetUpSearchResultExpectations(); fake_search_query_.SetSearchResults({}); - auto* fake_drivefs = GetFakeDriveFsForProfile(browser()->profile()); - EXPECT_CALL(*fake_drivefs, GetOfflineFilesSpaceUsage(_)) - .WillRepeatedly(RunOnceCallback<0>(drive::FILE_ERROR_OK, 1)); - // Expect the free space to be 1 GB (1,073,741,824 bytes), the required space // to be 0 KB (0 items). int64_t free_space = 1024 * 1024 * 1024; @@ -167,9 +186,6 @@ OnlyUnpinnedResultsUpdateTheSpaceRequirements) { SetUpSearchResultExpectations(); - auto* fake_drivefs = GetFakeDriveFsForProfile(browser()->profile()); - EXPECT_CALL(*fake_drivefs, GetOfflineFilesSpaceUsage(_)) - .WillRepeatedly(RunOnceCallback<0>(drive::FILE_ERROR_OK, 1)); // Each item is 125 MB in size, total required space should be 500 MB. int64_t file_size = 125 * 1024 * 1024; @@ -196,21 +212,7 @@ ash::FakeSpacedClient::Get()->set_free_disk_space(int64_t(3) << 30); constexpr int file_size_in_bytes = 32; - auto* const service = - drive::util::GetIntegrationServiceByProfile(browser()->profile()); - { - // Ensure the content cache directory exists. - base::ScopedAllowBlockingForTesting allow_blocking; - ASSERT_TRUE(base::CreateDirectory(service->GetDriveFsContentCachePath())); - } - std::string foo_contents = base::RandBytesAsString(file_size_in_bytes); - const base::FilePath file_path = - service->GetDriveFsContentCachePath().Append("foo.txt"); - { - // Create a file of 32 bytes in the content_cache directory. - base::ScopedAllowBlockingForTesting allow_blocking; - ASSERT_TRUE(base::WriteFile(file_path, foo_contents)); - } + CreateFileInContentCache(file_size_in_bytes); auto google_drive_settings = OpenGoogleDriveSettings(); google_drive_settings.AssertBulkPinningPinnedSize( @@ -219,13 +221,25 @@ IN_PROC_BROWSER_TEST_F(GoogleDriveHandlerTest, ClearingOfflineFilesCallsProperMethods) { - SetUpSearchResultExpectations(); - // Mock no search results are returned (this avoids the call to // `CalculateRequiredSpace` from being ran here). fake_search_query_.SetSearchResults({}); ash::FakeSpacedClient::Get()->set_free_disk_space(int64_t(3) << 30); + const base::FilePath file_path = CreateFileInContentCache(32); + + auto* fake_drivefs = GetFakeDriveFsForProfile(browser()->profile()); + EXPECT_CALL(*fake_drivefs, ClearOfflineFiles(_)) + .WillOnce( + [&file_path]( + drivefs::mojom::DriveFs::ClearOfflineFilesCallback callback) { + { + base::ScopedAllowBlockingForTesting allow_blocking; + ASSERT_TRUE(base::DeleteFile(file_path)); + } + std::move(callback).Run(drive::FILE_ERROR_OK); + }); + auto google_drive_settings = OpenGoogleDriveSettings(); google_drive_settings.ClickClearOfflineFilesAndAssertNewSize( FormatBytesToString(0));
diff --git a/chrome/browser/ui/webui/settings/ash/os_settings_password_setup_browsertest.cc b/chrome/browser/ui/webui/settings/ash/os_settings_password_setup_browsertest.cc deleted file mode 100644 index c9883ed..0000000 --- a/chrome/browser/ui/webui/settings/ash/os_settings_password_setup_browsertest.cc +++ /dev/null
@@ -1,57 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/webui/ash/settings/test_support/os_settings_lock_screen_browser_test_base.h" -#include "chrome/test/data/webui/settings/chromeos/os_people_page/password_settings_api.test-mojom-test-utils.h" -#include "chrome/test/data/webui/settings/chromeos/test_api.test-mojom-test-utils.h" -#include "content/public/test/browser_test.h" - -namespace ash::settings { - -class OSSettingsPasswordSetupTest : public OSSettingsLockScreenBrowserTestBase { - using OSSettingsLockScreenBrowserTestBase:: - OSSettingsLockScreenBrowserTestBase; - - public: - mojom::PasswordSettingsApiAsyncWaiter GoToPasswordSettings( - mojom::LockScreenSettingsAsyncWaiter& lock_screen_settings) { - password_settings_remote_ = - mojo::Remote(lock_screen_settings.GoToPasswordSettings()); - return mojom::PasswordSettingsApiAsyncWaiter( - password_settings_remote_.get()); - } - - private: - mojo::Remote<mojom::PasswordSettingsApi> password_settings_remote_; -}; - -class OSSettingsPasswordSetupTestWithGaiaPassword - : public OSSettingsPasswordSetupTest { - public: - OSSettingsPasswordSetupTestWithGaiaPassword() - : OSSettingsPasswordSetupTest(PasswordType::kGaia) {} -}; -class OSSettingsPasswordSetupTestWithLocalPassword - : public OSSettingsPasswordSetupTest { - public: - OSSettingsPasswordSetupTestWithLocalPassword() - : OSSettingsPasswordSetupTest(PasswordType::kLocal) {} -}; - -IN_PROC_BROWSER_TEST_F(OSSettingsPasswordSetupTestWithGaiaPassword, NotShown) { - mojom::LockScreenSettingsAsyncWaiter lock_screen_settings = - OpenLockScreenSettingsAndAuthenticate(); - lock_screen_settings.AssertPasswordControlVisibility(false); -} - -IN_PROC_BROWSER_TEST_F(OSSettingsPasswordSetupTestWithLocalPassword, Selected) { - mojom::LockScreenSettingsAsyncWaiter lock_screen_settings = - OpenLockScreenSettingsAndAuthenticate(); - mojom::PasswordSettingsApiAsyncWaiter password_settings = - GoToPasswordSettings(lock_screen_settings); - - password_settings.AssertSelectedPasswordType(mojom::PasswordType::kLocal); -} - -} // namespace ash::settings
diff --git a/chrome/browser/ui/webui/settings/safety_hub_handler.cc b/chrome/browser/ui/webui/settings/safety_hub_handler.cc index 0c3854ee..345dc34 100644 --- a/chrome/browser/ui/webui/settings/safety_hub_handler.cc +++ b/chrome/browser/ui/webui/settings/safety_hub_handler.cc
@@ -209,9 +209,21 @@ stored_value.GetDict().FindList(permissions::kRevokedKey)->Clone(); base::Value::List permissions_value_list; for (base::Value& type : type_list) { - permissions_value_list.Append( + base::StringPiece permission_str = site_settings::ContentSettingsTypeToGroupName( - static_cast<ContentSettingsType>(type.GetInt()))); + static_cast<ContentSettingsType>(type.GetInt())); + if (!permission_str.empty()) { + permissions_value_list.Append(permission_str); + } + } + + // Some permissions have no readable name, although Safety Hub revokes them. + // To prevent crashes, if there is no permission to be shown in the UI, the + // origin will not be added to the revoked permissions list. + // TODO(crbug.com/1459305): Remove this after adding check for + // ContentSettingsTypeToGroupName. + if (permissions_value_list.empty()) { + continue; } revoked_permission_value.Set(
diff --git a/chrome/browser/ui/webui/settings/safety_hub_handler.h b/chrome/browser/ui/webui/settings/safety_hub_handler.h index c09f3d64..2d9b928 100644 --- a/chrome/browser/ui/webui/settings/safety_hub_handler.h +++ b/chrome/browser/ui/webui/settings/safety_hub_handler.h
@@ -64,6 +64,7 @@ FRIEND_TEST_ALL_PREFIXES( SafetyHubHandlerTest, SendNotificationPermissionReviewList_FeatureDisabled); + FRIEND_TEST_ALL_PREFIXES(SafetyHubHandlerTest, RevokeAllContentSettingTypes); // SettingsPageUIHandler implementation. void OnJavascriptAllowed() override;
diff --git a/chrome/browser/ui/webui/settings/safety_hub_handler_unittest.cc b/chrome/browser/ui/webui/settings/safety_hub_handler_unittest.cc index de6a1f7d..e55124f 100644 --- a/chrome/browser/ui/webui/settings/safety_hub_handler_unittest.cc +++ b/chrome/browser/ui/webui/settings/safety_hub_handler_unittest.cc
@@ -17,6 +17,7 @@ #include "chrome/browser/ui/webui/settings/site_settings_helper.h" #include "chrome/common/chrome_features.h" #include "chrome/test/base/testing_profile.h" +#include "components/content_settings/core/browser/content_settings_registry.h" #include "components/content_settings/core/browser/host_content_settings_map.h" #include "components/content_settings/core/common/content_settings.h" #include "components/content_settings/core/common/content_settings_pattern.h" @@ -424,3 +425,58 @@ SetPrefsForSafeBrowsing(false, true, SettingManager::USER); ValidateHandleSafeBrowsingState(SafeBrowsingState::kDisabledByUser); } + +// Test that revocation is happen correctly for all content setting types. +TEST_F(SafetyHubHandlerTest, RevokeAllContentSettingTypes) { + // TODO(crbug.com/1459305): Remove this after adding names for those + // types. + std::list<ContentSettingsType> no_name_types = { + ContentSettingsType::MIDI, + ContentSettingsType::DURABLE_STORAGE, + ContentSettingsType::ACCESSIBILITY_EVENTS, + ContentSettingsType::NFC, + ContentSettingsType::FILE_SYSTEM_READ_GUARD, + ContentSettingsType::CAMERA_PAN_TILT_ZOOM, + ContentSettingsType::TOP_LEVEL_STORAGE_ACCESS}; + + // Add all content settings in the content setting registry to revoked + // permissions list. + auto* content_settings_registry = + content_settings::ContentSettingsRegistry::GetInstance(); + for (const content_settings::ContentSettingsInfo* info : + *content_settings_registry) { + ContentSettingsType type = info->website_settings_info()->type(); + + // If the permission can not be tracked, then also can not be revoked. + if (!content_settings::CanTrackLastVisit(type)) { + continue; + } + + // If the permission can not set to ALLOW, then also can not be revoked. + if (!content_settings_registry->Get(type)->IsSettingValid( + ContentSetting::CONTENT_SETTING_ALLOW)) { + continue; + } + + // Add the permission to revoked permission list. + auto dict = base::Value::Dict().Set( + permissions::kRevokedKey, + base::Value::List().Append(static_cast<int32_t>(type))); + hcsm()->SetWebsiteSettingDefaultScope( + GURL(kUnusedTestSite), GURL(kUnusedTestSite), + ContentSettingsType::REVOKED_UNUSED_SITE_PERMISSIONS, + base::Value(dict.Clone())); + + // Unless the permission in no_name_types, it should be shown on the UI. + const auto& revoked_permissions = + handler()->PopulateUnusedSitePermissionsData(); + bool is_no_name_type = + (std::find(no_name_types.begin(), no_name_types.end(), type) != + no_name_types.end()); + if (is_no_name_type) { + EXPECT_EQ(revoked_permissions.size(), 0U); + } else { + EXPECT_EQ(revoked_permissions.size(), 1U); + } + } +}
diff --git a/chrome/browser/ui/webui/settings/site_settings_helper.cc b/chrome/browser/ui/webui/settings/site_settings_helper.cc index c0ffb1b..e1f9f394 100644 --- a/chrome/browser/ui/webui/settings/site_settings_helper.cc +++ b/chrome/browser/ui/webui/settings/site_settings_helper.cc
@@ -474,12 +474,18 @@ } base::StringPiece ContentSettingsTypeToGroupName(ContentSettingsType type) { - for (size_t i = 0; i < std::size(kContentSettingsTypeGroupNames); ++i) { - if (type == kContentSettingsTypeGroupNames[i].type) { - const char* name = kContentSettingsTypeGroupNames[i].name; - if (name) - return name; - break; + for (const auto& entry : kContentSettingsTypeGroupNames) { + if (type == entry.type) { + // Content setting types that aren't represented in the settings UI + // will have `nullptr` as their `name`. Although they are valid content + // settings types, they don't have a readable name. + // TODO(crbug.com/1459305): Replace LOG with CHECK. + if (!entry.name) { + LOG(ERROR) << static_cast<int32_t>(type) + << " does not have a readable name."; + } + + return entry.name ? entry.name : base::StringPiece(); } }
diff --git a/chrome/browser/usb/usb_connection_tracker_factory.cc b/chrome/browser/usb/usb_connection_tracker_factory.cc index 627386f8..598ed588 100644 --- a/chrome/browser/usb/usb_connection_tracker_factory.cc +++ b/chrome/browser/usb/usb_connection_tracker_factory.cc
@@ -37,9 +37,11 @@ UsbConnectionTrackerFactory::~UsbConnectionTrackerFactory() = default; -KeyedService* UsbConnectionTrackerFactory::BuildServiceInstanceFor( +std::unique_ptr<KeyedService> +UsbConnectionTrackerFactory::BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const { - return new UsbConnectionTracker(Profile::FromBrowserContext(context)); + return std::make_unique<UsbConnectionTracker>( + Profile::FromBrowserContext(context)); } void UsbConnectionTrackerFactory::BrowserContextShutdown(
diff --git a/chrome/browser/usb/usb_connection_tracker_factory.h b/chrome/browser/usb/usb_connection_tracker_factory.h index db14652..39ccebb 100644 --- a/chrome/browser/usb/usb_connection_tracker_factory.h +++ b/chrome/browser/usb/usb_connection_tracker_factory.h
@@ -26,7 +26,7 @@ ~UsbConnectionTrackerFactory() override; // BrowserContextKeyedBaseFactory: - KeyedService* BuildServiceInstanceFor( + std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( content::BrowserContext* profile) const override; void BrowserContextShutdown(content::BrowserContext* context) override; };
diff --git a/chrome/build/android-arm32.pgo.txt b/chrome/build/android-arm32.pgo.txt index 7c72f82..2a7ebf9 100644 --- a/chrome/build/android-arm32.pgo.txt +++ b/chrome/build/android-arm32.pgo.txt
@@ -1 +1 @@ -chrome-android32-main-1692727167-dc84bea84ee06c549525c89af7566751f980169a.profdata +chrome-android32-main-1692748490-c06965b816013a4530a30c49c3ef6541b61e2179.profdata
diff --git a/chrome/build/android-arm64.pgo.txt b/chrome/build/android-arm64.pgo.txt index 5d03925..953d934 100644 --- a/chrome/build/android-arm64.pgo.txt +++ b/chrome/build/android-arm64.pgo.txt
@@ -1 +1 @@ -chrome-android64-main-1692727167-55886d71ecef8bda4393c4413b8017b9ff68c0f2.profdata +chrome-android64-main-1692748490-b387ab6f3f76466e74b286346b2717c68fd7add7.profdata
diff --git a/chrome/build/mac-arm.pgo.txt b/chrome/build/mac-arm.pgo.txt index 68e35fe..94e5e4f 100644 --- a/chrome/build/mac-arm.pgo.txt +++ b/chrome/build/mac-arm.pgo.txt
@@ -1 +1 @@ -chrome-mac-arm-main-1692734385-f8b5079f20fb00dbba55ed2baea8500132f74f1e.profdata +chrome-mac-arm-main-1692741483-70c10d25884f445c21d557791fa3d363734ac012.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt index 1288bc5c..a617603 100644 --- a/chrome/build/win64.pgo.txt +++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@ -chrome-win64-main-1692727167-c621730366ff87856ecd365d1b271cfe13482c28.profdata +chrome-win64-main-1692737847-5f2e9348dec0a0a0ca265724b1abb08da009c83e.profdata
diff --git a/chrome/services/printing/public/mojom/pdf_nup_converter.mojom b/chrome/services/printing/public/mojom/pdf_nup_converter.mojom index 1546899..da290f2 100644 --- a/chrome/services/printing/public/mojom/pdf_nup_converter.mojom +++ b/chrome/services/printing/public/mojom/pdf_nup_converter.mojom
@@ -8,20 +8,9 @@ import "ui/gfx/geometry/mojom/geometry.mojom"; import "url/mojom/url.mojom"; -// This set of interfaces is used to do Nup PDF conversion. -// Usage: -// - generate a PdfNupConverter. -// -// - call PdfNupConverter.NupPageConvert() to import N PDF pages into one N-up -// PDF page. -// -// - call PdfNupConverter.NupDocumentConvert() to convert a PDF document to a -// N-up PDF document. -// -// - call PdfNupConverter.SetWebContentsURL() to set the URL that is committed -// in the main frame of the WebContents for crash diagnosis. +// Used by the browser process to perform N-up PDF conversion in a separate +// sandboxed service process, as the PDF data is untrusted user input. interface PdfNupConverter { - // The status of PDF conversion execution. enum Status { SUCCESS = 0, @@ -29,7 +18,7 @@ HANDLE_MAP_ERROR = 2, }; - // Convert a list of PDF pages to a N-up PDF. + // Converts a list of PDF pages to a N-up PDF. // `pages_per_sheet` is the number of pages to put on a single sheet. // `page_size` is the output page size, measured in PDF "user space" units. // `printable_area` is the printable area of the output page, measured in @@ -45,7 +34,7 @@ array<mojo_base.mojom.ReadOnlySharedMemoryRegion> pdf_page_regions) => (Status status, mojo_base.mojom.ReadOnlySharedMemoryRegion? pdf_region); - // Convert a PDF document to a N-up PDF document. + // Converts a PDF document to a N-up PDF document. // `pages_per_sheet` is the number of pages to put on a single sheet. // `page_size` is the output page size, measured in PDF "user space" units. // `printable_area` is the printable area of the output page, measured in @@ -56,8 +45,8 @@ mojo_base.mojom.ReadOnlySharedMemoryRegion src_pdf_region) => (Status status, mojo_base.mojom.ReadOnlySharedMemoryRegion? pdf_region); - // Sets the URL which is committed in the main frame of the WebContents, - // for use in crash diagnosis. + // Tells the service what URL is committed in the main frame of the + // WebContents that is printing, for use in crash diagnosis. SetWebContentsURL(url.mojom.Url url); // Sets the status for enterprise policy `kPdfUseSkiaRendererEnabled`. It
diff --git a/chrome/services/sharing/nearby/platform/BUILD.gn b/chrome/services/sharing/nearby/platform/BUILD.gn index 74aaf5d..5fb40f4 100644 --- a/chrome/services/sharing/nearby/platform/BUILD.gn +++ b/chrome/services/sharing/nearby/platform/BUILD.gn
@@ -69,6 +69,7 @@ ] public_deps = [ + "//third_party/nearby:connections_local_credential_proto", "//third_party/nearby:platform_api_platform", "//third_party/nearby:platform_impl_shared_file", ] @@ -77,6 +78,7 @@ "//ash/constants", "//base", "//chrome/services/sharing/webrtc", + "//chromeos/ash/components/nearby/presence/conversions:conversions", "//chromeos/ash/services/nearby/public/cpp:tcp_server_socket_port", "//chromeos/ash/services/nearby/public/mojom", "//chromeos/services/network_config/public/mojom",
diff --git a/chrome/services/sharing/nearby/platform/DEPS b/chrome/services/sharing/nearby/platform/DEPS index c2af5ef..936d5a33 100644 --- a/chrome/services/sharing/nearby/platform/DEPS +++ b/chrome/services/sharing/nearby/platform/DEPS
@@ -8,12 +8,14 @@ '+services/network/public', '+third_party/abseil-cpp/absl/strings/string_view.h', '+third_party/abseil-cpp/absl/time/time.h', + '+third_party/nearby', '+unicode/locid.h', '+chromeos/ash/components/login/login_state/login_state.h', '+chromeos/ash/components/network/proxy/ui_proxy_config_service.h', '+chromeos/ash/components/network/managed_network_configuration_handler.h', '+chromeos/ash/components/network/network_configuration_handler.h', '+chromeos/ash/components/network/network_profile_handler.h', + '+chromeos/ash/components/nearby/presence/conversions/proto_conversions.h', '+components/onc/onc_constants.h', '+components/onc/onc_pref_names.h', '+components/prefs/testing_pref_service.h',
diff --git a/chrome/services/sharing/nearby/platform/credential_storage.cc b/chrome/services/sharing/nearby/platform/credential_storage.cc index d38c659..c85cd93 100644 --- a/chrome/services/sharing/nearby/platform/credential_storage.cc +++ b/chrome/services/sharing/nearby/platform/credential_storage.cc
@@ -3,6 +3,8 @@ // found in the LICENSE file. #include "chrome/services/sharing/nearby/platform/credential_storage.h" +#include "chromeos/ash/components/nearby/presence/conversions/proto_conversions.h" +#include "chromeos/ash/services/nearby/public/mojom/nearby_presence.mojom.h" namespace nearby::chrome { @@ -21,7 +23,19 @@ const std::vector<LocalCredential>& private_credentials, const std::vector<SharedCredential>& public_credentials, PublicCredentialType public_credential_type, - SaveCredentialsResultCallback callback) {} + SaveCredentialsResultCallback callback) { + std::vector<ash::nearby::presence::mojom::LocalCredentialPtr> + local_credentials_mojom; + for (const auto& local_credential : private_credentials) { + local_credentials_mojom.push_back( + ash::nearby::presence::proto::LocalCredentialToMojom(local_credential)); + } + + nearby_presence_credential_storage_->SaveCredentials( + std::move(local_credentials_mojom), + base::BindOnce(&CredentialStorage::OnCredentialsSaved, + weak_ptr_factory_.GetWeakPtr(), std::move(callback))); +} // TODO(b/287334012): Implement. void CredentialStorage::UpdateLocalCredential( @@ -41,4 +55,20 @@ PublicCredentialType public_credential_type, GetPublicCredentialsResultCallback callback) {} +void CredentialStorage::OnCredentialsSaved( + nearby::presence::SaveCredentialsResultCallback + on_credentials_saved_callback, + ash::nearby::presence::mojom::StatusCode credential_save_result) { + // TODO(b/297097956): Use AbslStatusCode in callback rather than StatusCode + // once NP migration to this type lands. + if (credential_save_result == ash::nearby::presence::mojom::StatusCode::kOk) { + std::move(on_credentials_saved_callback) + .credentials_saved_cb(absl::OkStatus()); + } else { + std::move(on_credentials_saved_callback) + .credentials_saved_cb(absl::Status(absl::StatusCode::kUnknown, + "Failed to save to database.")); + } +} + } // namespace nearby::chrome
diff --git a/chrome/services/sharing/nearby/platform/credential_storage.h b/chrome/services/sharing/nearby/platform/credential_storage.h index f2ac3949..e84d125 100644 --- a/chrome/services/sharing/nearby/platform/credential_storage.h +++ b/chrome/services/sharing/nearby/platform/credential_storage.h
@@ -46,9 +46,15 @@ GetPublicCredentialsResultCallback callback) override; private: + void OnCredentialsSaved( + nearby::presence::SaveCredentialsResultCallback + on_credentials_saved_callback, + ash::nearby::presence::mojom::StatusCode credential_save_result); + const mojo::SharedRemote< ash::nearby::presence::mojom::NearbyPresenceCredentialStorage> nearby_presence_credential_storage_; + base::WeakPtrFactory<CredentialStorage> weak_ptr_factory_{this}; }; } // namespace nearby::chrome
diff --git a/chrome/services/sharing/nearby/platform/credential_storage_unittest.cc b/chrome/services/sharing/nearby/platform/credential_storage_unittest.cc index e26ff8a4..87c16284 100644 --- a/chrome/services/sharing/nearby/platform/credential_storage_unittest.cc +++ b/chrome/services/sharing/nearby/platform/credential_storage_unittest.cc
@@ -3,9 +3,114 @@ // found in the LICENSE file. #include "chrome/services/sharing/nearby/platform/credential_storage.h" +#include "base/test/bind.h" +#include "base/test/task_environment.h" #include "chromeos/ash/services/nearby/public/mojom/nearby_presence_credential_storage.mojom.h" +#include "mojo/public/cpp/bindings/self_owned_receiver.h" #include "mojo/public/cpp/bindings/shared_remote.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/nearby/internal/proto/local_credential.pb.h" +#include "third_party/nearby/src/internal/platform/implementation/credential_callbacks.h" + +namespace { + +const char kManagerAppName[] = "test_manager_app_id"; +const char kAccountName[] = "test_account_name"; + +const std::vector<uint8_t> kSecretId_1 = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16}; +const std::vector<uint8_t> kKeySeed_1 = {0x21, 0x22, 0x23, 0x24, 0x25, 0x26}; +const std::vector<uint8_t> kMetadataEncryptionKeyV0_1 = { + 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e}; +constexpr int64_t kStartTimeMillis_1 = 255486129307; +const char AdvertisementSigningKeyCertificateAlias_1[] = + "NearbySharingABCDEF123456"; +const std::vector<uint8_t> kAdvertisementPrivateKey_1 = {0x41, 0x42, 0x43, + 0x44, 0x45, 0x46}; +const char ConnectionSigningKeyCertificateAlias_1[] = "NearbySharingXYZ789"; +const std::vector<uint8_t> kConnectionPrivateKey_1 = {0x51, 0x52, 0x53, + 0x54, 0x55, 0x56}; +const std::vector<uint8_t> kMetadataEncryptionKeyV1_1 = { + 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, + 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70}; +const base::flat_map<uint32_t, bool> kConsumedSalts_1 = {{0xb412, true}, + {0x34b2, false}, + {0x5171, false}}; + +::nearby::internal::LocalCredential CreateLocalCredentialProto( + const std::vector<uint8_t>& secret_id, + const std::vector<uint8_t>& key_seed, + int64_t start_time_millis, + const std::vector<uint8_t>& metadata_encryption_key_v0, + const std::string& advertisement_signing_key_certificate_alias, + const std::vector<uint8_t>& advertisement_private_key, + const std::string& connection_signing_key_certificate_alias, + const std::vector<uint8_t>& connection_private_key, + const base::flat_map<uint32_t, bool>& consumed_salts, + const std::vector<uint8_t>& metadata_encryption_key_v1) { + ::nearby::internal::LocalCredential proto; + + proto.set_secret_id(std::string(secret_id.begin(), secret_id.end())); + proto.set_key_seed(std::string(key_seed.begin(), key_seed.end())); + proto.set_start_time_millis(start_time_millis); + proto.set_metadata_encryption_key_v0(std::string( + metadata_encryption_key_v0.begin(), metadata_encryption_key_v0.end())); + + proto.mutable_advertisement_signing_key()->set_certificate_alias( + advertisement_signing_key_certificate_alias); + proto.mutable_advertisement_signing_key()->set_key(std::string( + advertisement_private_key.begin(), advertisement_private_key.end())); + + proto.mutable_connection_signing_key()->set_certificate_alias( + connection_signing_key_certificate_alias); + proto.mutable_connection_signing_key()->set_key(std::string( + connection_private_key.begin(), connection_private_key.end())); + + // All local credentials have IdentityType of kIdentityTypePrivate. + proto.set_identity_type( + ::nearby::internal::IdentityType::IDENTITY_TYPE_PRIVATE); + + for (const auto& pair : consumed_salts) { + auto map_pair = + ::google::protobuf::MapPair<uint32_t, bool>(pair.first, pair.second); + proto.mutable_consumed_salts()->insert(map_pair); + } + + proto.set_metadata_encryption_key_v1(std::string( + metadata_encryption_key_v1.begin(), metadata_encryption_key_v1.end())); + + return proto; +} + +class FakeNearbyPresenceCredentialStorage + : public ash::nearby::presence::mojom::NearbyPresenceCredentialStorage { + public: + FakeNearbyPresenceCredentialStorage() = default; + ~FakeNearbyPresenceCredentialStorage() override = default; + + // mojom::NearbyPresenceCredentialStorage: + void SaveCredentials( + std::vector<ash::nearby::presence::mojom::LocalCredentialPtr> + local_credentials, + ash::nearby::presence::mojom::NearbyPresenceCredentialStorage:: + SaveCredentialsCallback callback) override { + if (should_credentials_successfully_save_) { + std::move(callback).Run(ash::nearby::presence::mojom::StatusCode::kOk); + } else { + std::move(callback).Run( + ash::nearby::presence::mojom::StatusCode::kFailure); + } + } + + void SetShouldCredentialsSuccessfullySave(bool should_succeed) { + should_credentials_successfully_save_ = should_succeed; + } + + private: + bool should_credentials_successfully_save_ = true; +}; + +} // namespace namespace nearby::chrome { @@ -17,19 +122,106 @@ // testing::Test: void SetUp() override { + auto fake_credential_storage = + std::make_unique<FakeNearbyPresenceCredentialStorage>(); + fake_credential_storage_ = fake_credential_storage.get(); + + mojo::PendingRemote< + ash::nearby::presence::mojom::NearbyPresenceCredentialStorage> + pending_remote; + mojo::MakeSelfOwnedReceiver( + std::move(fake_credential_storage), + pending_remote.InitWithNewPipeAndPassReceiver()); + + remote_credential_storage_.Bind(std::move(pending_remote), + /*bind_task_runner=*/nullptr); + credential_storage_ = - std::make_unique<CredentialStorage>(remote_credential_storage); + std::make_unique<CredentialStorage>(remote_credential_storage_); + } + + void TearDown() override { + // Prevent dangling raw pointer once 'remote_credential_storage_' is + // deconstructed. + fake_credential_storage_ = nullptr; } protected: + base::test::SingleThreadTaskEnvironment task_environment_; + mojo::SharedRemote< ash::nearby::presence::mojom::NearbyPresenceCredentialStorage> - remote_credential_storage; + remote_credential_storage_; std::unique_ptr<CredentialStorage> credential_storage_; + raw_ptr<FakeNearbyPresenceCredentialStorage> fake_credential_storage_; }; TEST_F(CredentialStorageTest, Initialize) { EXPECT_TRUE(credential_storage_); } +TEST_F(CredentialStorageTest, SaveCredentials_Succeed) { + std::vector<::nearby::internal::LocalCredential> local_credentials; + + local_credentials.emplace_back(CreateLocalCredentialProto( + kSecretId_1, kKeySeed_1, kStartTimeMillis_1, kMetadataEncryptionKeyV0_1, + AdvertisementSigningKeyCertificateAlias_1, kAdvertisementPrivateKey_1, + ConnectionSigningKeyCertificateAlias_1, kConnectionPrivateKey_1, + kConsumedSalts_1, kMetadataEncryptionKeyV1_1)); + + // TODO(b/287334195): Populate and save public credentials once + // CredentialStorage has public credential support. + std::vector<::nearby::internal::SharedCredential> shared_credentials; + + base::RunLoop run_loop; + + nearby::presence::SaveCredentialsResultCallback callback; + callback.credentials_saved_cb = + absl::AnyInvocable<void(absl::Status)>([&](const absl::Status& status) { + EXPECT_TRUE(status.ok()); + run_loop.Quit(); + }); + + fake_credential_storage_->SetShouldCredentialsSuccessfullySave( + /*should_succeed=*/true); + credential_storage_->SaveCredentials( + kManagerAppName, kAccountName, local_credentials, shared_credentials, + ::nearby::presence::PublicCredentialType::kLocalPublicCredential, + std::move(callback)); + + run_loop.Run(); +} + +TEST_F(CredentialStorageTest, SaveCredentials_Fail) { + std::vector<::nearby::internal::LocalCredential> local_credentials; + + local_credentials.emplace_back(CreateLocalCredentialProto( + kSecretId_1, kKeySeed_1, kStartTimeMillis_1, kMetadataEncryptionKeyV0_1, + AdvertisementSigningKeyCertificateAlias_1, kAdvertisementPrivateKey_1, + ConnectionSigningKeyCertificateAlias_1, kConnectionPrivateKey_1, + kConsumedSalts_1, kMetadataEncryptionKeyV1_1)); + + // TODO(b/287334195): Populate and save public credentials once + // CredentialStorage has public credential support. + std::vector<::nearby::internal::SharedCredential> shared_credentials; + + base::RunLoop run_loop; + + nearby::presence::SaveCredentialsResultCallback callback; + callback.credentials_saved_cb = + absl::AnyInvocable<void(absl::Status)>([&](const absl::Status& status) { + EXPECT_FALSE(status.ok()); + run_loop.Quit(); + }); + + fake_credential_storage_->SetShouldCredentialsSuccessfullySave( + /*should_succeed=*/false); + credential_storage_->SaveCredentials( + kManagerAppName, kAccountName, local_credentials, shared_credentials, + ::nearby::presence::PublicCredentialType::kLocalPublicCredential, + std::move(callback)); + + run_loop.Run(); +} + } // namespace nearby::chrome
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 7aa0a83..8580574 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -3058,6 +3058,7 @@ "//chromeos/ui/base", "//chromeos/ui/frame:test_support", "//components/account_manager_core:test_support", + "//components/app_constants", "//components/services/app_service", "//components/webapk:proto", "//ui/wm:wm", @@ -4525,7 +4526,6 @@ "../browser/ui/webui/settings/ash/os_settings_auto_screen_lock_browsertest.cc", "../browser/ui/webui/settings/ash/os_settings_lock_screen_authentication_browsertest.cc", "../browser/ui/webui/settings/ash/os_settings_notification_settings_browsertest.cc", - "../browser/ui/webui/settings/ash/os_settings_password_setup_browsertest.cc", "../browser/ui/webui/settings/ash/os_settings_pin_setup_browsertest.cc", "../browser/ui/webui/settings/ash/os_settings_recovery_browsertest.cc", "../browser/ui/webui/signin/ash/inline_login_dialog_browsertest.cc", @@ -5209,7 +5209,6 @@ "../browser/accessibility/live_caption/live_caption_surface_browsertest.cc", "../browser/chromeos/extensions/contact_center_insights/contact_center_insights_extension_manager_lacros_browsertest.cc", "../browser/chromeos/reporting/network/network_bandwidth_sampler_lacros_browsertest.cc", - "../browser/ui/autofill/autofill_context_menu_manager_lacros_browsertest.cc", # dlp_content_manager_lacros_browsertest.cc should become a unit test. "../browser/chromeos/policy/dlp/dlp_content_manager_lacros_browsertest.cc", @@ -5341,6 +5340,7 @@ "../browser/metrics/structured/lacros_structured_metrics_recorder_browsertest.cc", "../browser/payments/webapps/payment_request_lacros_browsertest.cc", "../browser/speech/extension_api/tts_extension_api_lacros_browsertest.cc", + "../browser/ui/autofill/autofill_context_menu_manager_lacros_browsertest.cc", "../browser/ui/browser_navigator_browsertest.cc", "../browser/ui/browser_navigator_browsertest.h", "../browser/ui/browser_navigator_browsertest_chromeos.cc", @@ -6056,6 +6056,7 @@ "../browser/security_events/security_event_recorder_impl_unittest.cc", "../browser/segmentation_platform/segmentation_platform_config_unittest.cc", "../browser/segmentation_platform/segmentation_platform_profile_observer_unittest.cc", + "../browser/segmentation_platform/segmentation_platform_service_factory_unittest.cc", "../browser/signin/e2e_tests/test_accounts_util_unittest.cc", # TODO(hashimoto): those tests should be componentized and moved to
diff --git a/chrome/test/data/webui/chromeos/personalization_app/ambient_subpage_element_test.ts b/chrome/test/data/webui/chromeos/personalization_app/ambient_subpage_element_test.ts index 509becf9..c1ea169 100644 --- a/chrome/test/data/webui/chromeos/personalization_app/ambient_subpage_element_test.ts +++ b/chrome/test/data/webui/chromeos/personalization_app/ambient_subpage_element_test.ts
@@ -44,7 +44,6 @@ loadTimeData.overrideValues({ isAmbientModeAllowed: true, isPersonalizationJellyEnabled: true, - isScreenSaverPreviewEnabled: true, isScreenSaverDurationEnabled: true, }); const mocks = baseSetup();
diff --git a/chrome/test/data/webui/settings/chromeos/BUILD.gn b/chrome/test/data/webui/settings/chromeos/BUILD.gn index 1d7cf13..1ab5664 100644 --- a/chrome/test/data/webui/settings/chromeos/BUILD.gn +++ b/chrome/test/data/webui/settings/chromeos/BUILD.gn
@@ -9,7 +9,6 @@ mojom("test_api_mojom") { testonly = true sources = [ - "os_people_page/password_settings_api.test-mojom", "os_people_page/pin_settings_api.test-mojom", "test_api.test-mojom", ] @@ -91,6 +90,7 @@ "app_management/test_util.js", "app_management/toggle_row_test.ts", + "date_time_page/date_time_card_test.ts", "date_time_page/date_time_page_test.ts", "date_time_page/test_timezone_browser_proxy.ts", "date_time_page/timezone_selector_test.ts", @@ -205,8 +205,8 @@ "os_bluetooth_page/os_bluetooth_change_device_name_dialog_test.ts", "os_bluetooth_page/os_bluetooth_device_detail_subpage_tests.js", "os_bluetooth_page/os_bluetooth_devices_subpage_tests.js", - "os_bluetooth_page/os_bluetooth_page_tests.js", - "os_bluetooth_page/os_bluetooth_pairing_dialog_tests.js", + "os_bluetooth_page/os_bluetooth_page_test.ts", + "os_bluetooth_page/os_bluetooth_pairing_dialog_test.ts", "os_bluetooth_page/os_bluetooth_summary_tests.js", "os_bluetooth_page/os_bluetooth_true_wireless_images_tests.js", "os_bluetooth_page/os_paired_bluetooth_list_test.ts", @@ -232,7 +232,6 @@ "os_people_page/os_people_page_test.ts", "os_people_page/os_sync_controls_subpage_test.ts", "os_people_page/personalization_options_test.ts", - "os_people_page/password_settings_api.ts", "os_people_page/pin_dialog_api.ts", "os_people_page/pin_settings_api.ts", "os_people_page/test_account_manager_browser_proxy.ts", @@ -293,7 +292,6 @@ mojo_files = [ "$root_gen_dir/mojom-webui/chrome/test/data/webui/settings/chromeos/test_api.test-mojom-webui.js", - "$root_gen_dir/mojom-webui/chrome/test/data/webui/settings/chromeos/os_people_page/password_settings_api.test-mojom-webui.js", "$root_gen_dir/mojom-webui/chrome/test/data/webui/settings/chromeos/os_people_page/pin_settings_api.test-mojom-webui.js", ]
diff --git a/chrome/test/data/webui/settings/chromeos/date_time_page/date_time_card_test.ts b/chrome/test/data/webui/settings/chromeos/date_time_page/date_time_card_test.ts new file mode 100644 index 0000000..0ce77ab --- /dev/null +++ b/chrome/test/data/webui/settings/chromeos/date_time_page/date_time_card_test.ts
@@ -0,0 +1,293 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'chrome://os-settings/lazy_load.js'; + +import {SettingsDateTimeCardElement, TimeZoneAutoDetectMethod, TimeZoneBrowserProxyImpl, TimezoneSelectorElement} from 'chrome://os-settings/lazy_load.js'; +import {CrLinkRowElement, CrSettingsPrefs, PrefsState, Router, routes, settingMojom, SettingsDropdownMenuElement, SettingsToggleButtonElement} from 'chrome://os-settings/os_settings.js'; +import {webUIListenerCallback} from 'chrome://resources/js/cr.js'; +import {loadTimeData} from 'chrome://resources/js/load_time_data.js'; +import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js'; +import {flushTasks, waitAfterNextRender} from 'chrome://webui-test/polymer_test_util.js'; +import {eventToPromise, isVisible} from 'chrome://webui-test/test_util.js'; + +import {TestTimeZoneBrowserProxy} from './test_timezone_browser_proxy.js'; + +// CrOS sends time zones as [id, friendly name] pairs. +const FAKE_TIMEZONES = [ + ['Westeros/Highgarden', '(KNG-2:00) The Reach Time (Highgarden)'], + ['Westeros/Winterfell', '(KNG-1:00) The North Time (Winterfell)'], + [ + 'Westeros/Kings_Landing', + '(KNG+0:00) Westeros Standard Time (King\'s Landing)', + ], + ['Westeros/TheEyrie', '(KNG+1:00) The Vale Time (The Eyrie)'], + ['Westeros/Sunspear', '(KNG+2:00) Dorne Time (Sunspear)'], + ['FreeCities/Pentos', '(KNG+6:00) Pentos Time (Pentos)'], + ['FreeCities/Volantis', '(KNG+9:00) Volantis Time (Volantis)'], + ['BayOfDragons/Daenerys', '(KNG+14:00) Daenerys Free Time (Meereen)'], +]; + +function getFakePrefs() { + return { + cros: { + system: { + timezone: { + key: 'cros.system.timezone', + type: chrome.settingsPrivate.PrefType.STRING, + value: 'Westeros/Kings_Landing', + }, + }, + flags: { + // TODO(alemate): This test should be run for all possible + // combinations of values of these options. + per_user_timezone_enabled: { + key: 'cros.flags.per_user_timezone_enabled', + type: chrome.settingsPrivate.PrefType.BOOLEAN, + value: true, + }, + fine_grained_time_zone_detection_enabled: { + key: 'cros.flags.fine_grained_time_zone_detection_enabled', + type: chrome.settingsPrivate.PrefType.BOOLEAN, + value: true, + }, + }, + }, + settings: { + clock: { + use_24hour_clock: { + key: 'settings.clock.use_24hour_clock', + type: chrome.settingsPrivate.PrefType.BOOLEAN, + value: false, + }, + }, + timezone: { + key: 'settings.timezone', + type: chrome.settingsPrivate.PrefType.STRING, + value: 'Westeros/Kings_Landing', + }, + }, + generated: { + resolve_timezone_by_geolocation_method_short: { + key: 'generated.resolve_timezone_by_geolocation_method_short', + type: chrome.settingsPrivate.PrefType.NUMBER, + value: TimeZoneAutoDetectMethod.IP_ONLY, + }, + resolve_timezone_by_geolocation_on_off: { + key: 'generated.resolve_timezone_by_geolocation_on_off', + type: chrome.settingsPrivate.PrefType.BOOLEAN, + value: true, + }, + }, + }; +} + +suite('<settings-date-time-card>', () => { + const isRevampWayfindingEnabled = + loadTimeData.getBoolean('isRevampWayfindingEnabled'); + const route = + isRevampWayfindingEnabled ? routes.SYSTEM_PREFERENCES : routes.DATETIME; + + let dateTimeCard: SettingsDateTimeCardElement; + let testBrowserProxy: TestTimeZoneBrowserProxy; + + setup(() => { + testBrowserProxy = new TestTimeZoneBrowserProxy(); + testBrowserProxy.setTimeZones(FAKE_TIMEZONES); + TimeZoneBrowserProxyImpl.setInstanceForTesting(testBrowserProxy); + CrSettingsPrefs.resetForTesting(); + }); + + teardown(() => { + dateTimeCard.remove(); + testBrowserProxy.reset(); + Router.getInstance().resetRouteForTesting(); + }); + + function createDateTimeCard(prefs: PrefsState): void { + const initialTimezoneDisplayName = prefs['cros'].system.timezone.value; + + // Find the desired initial timezone by ID. + const timeZone = FAKE_TIMEZONES.find( + (timeZonePair) => timeZonePair[0] === initialTimezoneDisplayName); + assertTrue(!!timeZone); + const [timeZoneID, timeZoneName] = timeZone; + loadTimeData.overrideValues({ + timeZoneID, + timeZoneName, + }); + + dateTimeCard = document.createElement('settings-date-time-card'); + dateTimeCard.prefs = prefs; + dateTimeCard.activeTimeZoneDisplayName = initialTimezoneDisplayName; + CrSettingsPrefs.setInitialized(); + document.body.appendChild(dateTimeCard); + flush(); + } + + function getTimezoneAutoDetectToggle(): SettingsToggleButtonElement { + const element = + dateTimeCard.shadowRoot!.querySelector<SettingsToggleButtonElement>( + '#timeZoneAutoDetectToggle'); + assertTrue(!!element); + return element; + } + + function getTimeZoneSelector(): TimezoneSelectorElement { + const timezoneSelector = + dateTimeCard.shadowRoot!.querySelector('timezone-selector'); + assertTrue(!!timezoneSelector); + return timezoneSelector; + } + + function getUserTimezoneDropdown(): SettingsDropdownMenuElement { + const timezoneSelector = getTimeZoneSelector(); + const userTimezoneDropdown = + timezoneSelector.shadowRoot!.querySelector<SettingsDropdownMenuElement>( + '#userTimeZoneSelector'); + assertTrue(!!userTimezoneDropdown); + return userTimezoneDropdown; + } + + function assertTimezonesPopulated(isPopulated: boolean): void { + const timezoneDropdown = getUserTimezoneDropdown(); + const numExpected = isPopulated ? FAKE_TIMEZONES.length : 1; + assertEquals(numExpected, timezoneDropdown.menuOptions.length); + } + + test('Set date and time row only shows if editable', async () => { + const prefs = getFakePrefs(); + createDateTimeCard(prefs); + + const setDateTimeRow = + dateTimeCard.shadowRoot!.querySelector<CrLinkRowElement>( + '#setDateTimeRow'); + assertFalse(isVisible(setDateTimeRow)); + + // Make the date and time editable. + webUIListenerCallback('can-set-date-time-changed', true); + await flushTasks(); + assertTrue(isVisible(setDateTimeRow)); + + assertEquals(0, testBrowserProxy.getCallCount('showSetDateTimeUi')); + setDateTimeRow!.click(); + assertEquals(1, testBrowserProxy.getCallCount('showSetDateTimeUi')); + + // Make the date and time not editable. + webUIListenerCallback('can-set-date-time-changed', false); + assertFalse(isVisible(setDateTimeRow)); + }); + + suite('When timezone detection is enabled', () => { + setup(() => { + const prefs = getFakePrefs(); + prefs.cros.flags.fine_grained_time_zone_detection_enabled.value = true; + createDateTimeCard(prefs); + }); + + test('Timezone selector is hidden', () => { + const timezoneSelector = + dateTimeCard.shadowRoot!.querySelector('timezone-selector'); + assertFalse(isVisible(timezoneSelector)); + }); + + test('Timezone auto-detect toggle is hidden', () => { + const toggle = + dateTimeCard.shadowRoot!.querySelector<SettingsToggleButtonElement>( + '#timeZoneAutoDetectToggle'); + assertFalse(isVisible(toggle)); + }); + + test('Timezone subpage row is visible', () => { + const rowElement = dateTimeCard.shadowRoot!.querySelector<HTMLElement>( + '#timeZoneSettingsTrigger'); + assertTrue(isVisible(rowElement)); + }); + + test( + 'Timezone subpage row is focused after returning from subpage', + async () => { + const triggerSelector = '#timeZoneSettingsTrigger'; + const rowElement = + dateTimeCard.shadowRoot!.querySelector<HTMLElement>( + triggerSelector); + assertTrue(!!rowElement); + rowElement.click(); + flush(); + + const popStateEventPromise = eventToPromise('popstate', window); + Router.getInstance().navigateToPreviousRoute(); + await popStateEventPromise; + await waitAfterNextRender(dateTimeCard); + + assertEquals( + rowElement, dateTimeCard.shadowRoot!.activeElement, + `${triggerSelector} should be focused.`); + }); + }); + + suite('When timezone detection is disabled', () => { + setup(() => { + const prefs = getFakePrefs(); + prefs.cros.flags.fine_grained_time_zone_detection_enabled.value = false; + createDateTimeCard(prefs); + }); + + test('Timezone selector is visible', () => { + const timezoneSelector = + dateTimeCard.shadowRoot!.querySelector('timezone-selector'); + assertTrue(isVisible(timezoneSelector)); + }); + + test('Timezone auto-detect toggle is visible', () => { + const toggle = getTimezoneAutoDetectToggle(); + assertTrue(isVisible(toggle)); + }); + + test('Timezone detect toggle is deep linkable', async () => { + const params = new URLSearchParams(); + const settingId = settingMojom.Setting.kChangeTimeZone.toString(); + params.append('settingId', settingId); + Router.getInstance().navigateTo(route, params); + flush(); + + const toggle = getTimezoneAutoDetectToggle(); + await waitAfterNextRender(toggle); + assertEquals( + toggle, dateTimeCard.shadowRoot!.activeElement, + `Auto set time zone toggle should be focused for settingId=${ + settingId}.`); + }); + + test('Turning off timezone auto-detection loads timezones', async () => { + assertEquals(0, testBrowserProxy.getCallCount('getTimeZones')); + + const autodetectToggle = getTimezoneAutoDetectToggle(); + assertTrue( + autodetectToggle.checked, 'Expected auto-detect toggle to be on'); + assertTimezonesPopulated(false); + + autodetectToggle.click(); + assertFalse( + autodetectToggle.checked, 'Expected auto-detect toggle to be off'); + await testBrowserProxy.whenCalled('getTimeZones'); + assertTimezonesPopulated(true); + }); + + test('Auto-detect toggle controls pref', () => { + const autodetectToggle = getTimezoneAutoDetectToggle(); + assertTrue( + autodetectToggle.checked, 'Expected auto-detect toggle to be on'); + assertTrue(dateTimeCard.get( + 'prefs.generated.resolve_timezone_by_geolocation_on_off.value')); + + autodetectToggle.click(); + assertFalse( + autodetectToggle.checked, 'Expected auto-detect toggle to be off'); + assertFalse(dateTimeCard.get( + 'prefs.generated.resolve_timezone_by_geolocation_on_off.value')); + }); + }); +});
diff --git a/chrome/test/data/webui/settings/chromeos/date_time_page/date_time_page_test.ts b/chrome/test/data/webui/settings/chromeos/date_time_page/date_time_page_test.ts index 992d21b..aaf9abb 100644 --- a/chrome/test/data/webui/settings/chromeos/date_time_page/date_time_page_test.ts +++ b/chrome/test/data/webui/settings/chromeos/date_time_page/date_time_page_test.ts
@@ -5,14 +5,11 @@ import 'chrome://os-settings/lazy_load.js'; import {SettingsDateTimeCardElement, SettingsDateTimePageElement, TimeZoneAutoDetectMethod, TimeZoneBrowserProxyImpl, TimezoneSubpageElement} from 'chrome://os-settings/lazy_load.js'; -import {ControlledRadioButtonElement, CrLinkRowElement, CrSettingsPrefs, Router, routes, SettingsDropdownMenuElement, SettingsToggleButtonElement} from 'chrome://os-settings/os_settings.js'; +import {ControlledRadioButtonElement, CrSettingsPrefs, Router, routes, SettingsDropdownMenuElement, SettingsToggleButtonElement} from 'chrome://os-settings/os_settings.js'; import {webUIListenerCallback} from 'chrome://resources/js/cr.js'; import {loadTimeData} from 'chrome://resources/js/load_time_data.js'; -import {getDeepActiveElement} from 'chrome://resources/js/util_ts.js'; import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; -import {assertEquals, assertFalse, assertGT, assertTrue} from 'chrome://webui-test/chai_assert.js'; -import {flushTasks, waitAfterNextRender} from 'chrome://webui-test/polymer_test_util.js'; -import {eventToPromise} from 'chrome://webui-test/test_util.js'; +import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js'; import {TestTimeZoneBrowserProxy} from './test_timezone_browser_proxy.js'; @@ -349,28 +346,6 @@ assertFalse(resolveMethodDropdown.disabled); }); - test('Deep link to auto set time zone on main page', async () => { - const prefs = getFakePrefs(); - // Set fine grained time zone off so that toggle appears on this page. - prefs.cros.flags.fine_grained_time_zone_detection_enabled.value = false; - dateTime = initializeDateTime(prefs, false); - - const params = new URLSearchParams(); - params.append('settingId', '1001'); - Router.getInstance().navigateTo(routes.DATETIME, params); - - flush(); - - const timeZoneAutoDetectToggle = getTimeZoneAutoDetectToggle(); - const deepLinkElement = - timeZoneAutoDetectToggle.shadowRoot!.querySelector('cr-toggle'); - assertTrue(!!deepLinkElement); - await waitAfterNextRender(deepLinkElement); - assertEquals( - deepLinkElement, getDeepActiveElement(), - 'Auto set time zone toggle should be focused for settingId=1001.'); - }); - test('auto-detect forced on', async () => { testBrowserProxy.setTimeZones(fakeTimeZones); const prefs = getFakePrefs(); @@ -530,65 +505,4 @@ assertFalse(timeZoneAutoDetectOff.disabled); assertFalse(timezoneSelector.disabled); }); - - test('set date and time button', async () => { - const prefs = getFakePrefs(); - // Set fine grained time zone off so that toggle appears on this page. - prefs.cros.flags.fine_grained_time_zone_detection_enabled.value = false; - dateTime = initializeDateTime(prefs, false); - - const setDateTimeButton = - getDateTimeCard().shadowRoot!.querySelector<CrLinkRowElement>( - '#setDateTimeRow'); - assertTrue(!!setDateTimeButton); - assertEquals(0, setDateTimeButton.offsetHeight); - - // Make the date and time editable. - webUIListenerCallback('can-set-date-time-changed', true); - await flushTasks(); - assertGT(setDateTimeButton.offsetHeight, 0); - - assertEquals(0, testBrowserProxy.getCallCount('showSetDateTimeUi')); - setDateTimeButton.click(); - - assertEquals(1, testBrowserProxy.getCallCount('showSetDateTimeUi')); - - // Make the date and time not editable. - webUIListenerCallback('can-set-date-time-changed', false); - assertEquals(0, setDateTimeButton.offsetHeight); - }); - - test( - 'Timezone subpage trigger is focused after returning from subpage', - async () => { - // Create settings-date-time-page element - Router.getInstance().navigateTo(routes.DATETIME); - const prefs = getFakePrefs(); - prefs.cros.flags.fine_grained_time_zone_detection_enabled.value = false; - dateTime = initializeDateTime(prefs, false); - flush(); - - // Show timezone subpage trigger element - dateTime.set( - 'prefs.cros.flags.fine_grained_time_zone_detection_enabled.value', - true); - flush(); - - const triggerSelector = '#timeZoneSettingsTrigger'; - const dateTimeCard = getDateTimeCard(); - const triggerEl = dateTimeCard.shadowRoot!.querySelector<HTMLElement>( - triggerSelector); - assertTrue(!!triggerEl); - triggerEl.click(); - flush(); - - const popStateEventPromise = eventToPromise('popstate', window); - Router.getInstance().navigateToPreviousRoute(); - await popStateEventPromise; - await waitAfterNextRender(dateTime); - - assertEquals( - triggerEl, dateTimeCard.shadowRoot!.activeElement, - `${triggerSelector} should be focused.`); - }); });
diff --git a/chrome/test/data/webui/settings/chromeos/os_bluetooth_page/os_bluetooth_page_tests.js b/chrome/test/data/webui/settings/chromeos/os_bluetooth_page/os_bluetooth_page_test.ts similarity index 61% rename from chrome/test/data/webui/settings/chromeos/os_bluetooth_page/os_bluetooth_page_tests.js rename to chrome/test/data/webui/settings/chromeos/os_bluetooth_page/os_bluetooth_page_test.ts index c8a4e3e..f99838a4 100644 --- a/chrome/test/data/webui/settings/chromeos/os_bluetooth_page/os_bluetooth_page_tests.js +++ b/chrome/test/data/webui/settings/chromeos/os_bluetooth_page/os_bluetooth_page_test.ts
@@ -2,33 +2,24 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'chrome://os-settings/strings.m.js'; +import 'chrome://os-settings/os_settings.js'; -import {OsBluetoothDevicesSubpageBrowserProxyImpl, Router, routes} from 'chrome://os-settings/os_settings.js'; +import {OsBluetoothDevicesSubpageBrowserProxyImpl, Router, routes, SettingsBluetoothPageElement} from 'chrome://os-settings/os_settings.js'; import {setBluetoothConfigForTesting} from 'chrome://resources/ash/common/bluetooth/cros_bluetooth_config.js'; import {BluetoothSystemState} from 'chrome://resources/mojo/chromeos/ash/services/bluetooth_config/public/mojom/cros_bluetooth_config.mojom-webui.js'; import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; -import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js'; +import {assertEquals, assertNull, assertTrue} from 'chrome://webui-test/chai_assert.js'; import {FakeBluetoothConfig} from 'chrome://webui-test/cr_components/chromeos/bluetooth/fake_bluetooth_config.js'; +import {flushTasks} from 'chrome://webui-test/polymer_test_util.js'; import {TestOsBluetoothDevicesSubpageBrowserProxy} from './test_os_bluetooth_subpage_browser_proxy.js'; -suite('OsBluetoothPageTest', function() { - /** @type {!FakeBluetoothConfig} */ - let bluetoothConfig; +suite('<os-settings-bluetooth-page>', () => { + let bluetoothConfig: FakeBluetoothConfig; + let bluetoothPage: SettingsBluetoothPageElement; + let browserProxy: TestOsBluetoothDevicesSubpageBrowserProxy; - /** @type {!SettingsBluetoothPageElement|undefined} */ - let bluetoothPage; - - /** @type {?OsBluetoothDevicesSubpageBrowserProxy} */ - let browserProxy = null; - - function flushAsync() { - flush(); - return new Promise(resolve => setTimeout(resolve)); - } - - setup(function() { + setup(() => { browserProxy = new TestOsBluetoothDevicesSubpageBrowserProxy(); OsBluetoothDevicesSubpageBrowserProxyImpl.setInstanceForTesting( browserProxy); @@ -40,55 +31,62 @@ flush(); }); - test('Show bluetooth pairing UI', async function() { - const getBluetoothPairingUi = () => bluetoothPage.shadowRoot.querySelector( + teardown(() => { + bluetoothPage.remove(); + browserProxy.reset(); + Router.getInstance().resetRouteForTesting(); + }); + + test('Show bluetooth pairing UI', async () => { + const getBluetoothPairingUi = () => bluetoothPage.shadowRoot!.querySelector( 'os-settings-bluetooth-pairing-dialog'); - const bluetoothSummary = - bluetoothPage.shadowRoot.querySelector('os-settings-bluetooth-summary'); + const bluetoothSummary = bluetoothPage.shadowRoot!.querySelector( + 'os-settings-bluetooth-summary'); const getPairNewDevice = () => - bluetoothPage.shadowRoot.querySelector('#pairNewDevice'); + bluetoothPage.shadowRoot!.querySelector<HTMLButtonElement>( + '#pairNewDevice'); assertTrue(!!bluetoothSummary); - assertFalse(!!getBluetoothPairingUi()); + assertNull(getBluetoothPairingUi()); assertEquals(0, browserProxy.getShowBluetoothRevampHatsSurveyCount()); bluetoothSummary.dispatchEvent(new CustomEvent('start-pairing')); - await flushAsync(); + await flushTasks(); assertTrue(!!getBluetoothPairingUi()); assertEquals( 1, browserProxy.getShowBluetoothRevampHatsSurveyCount(), 'Count failed to increase'); - getBluetoothPairingUi().dispatchEvent(new CustomEvent('close')); + getBluetoothPairingUi()!.dispatchEvent(new CustomEvent('close')); - await flushAsync(); - assertFalse(!!getBluetoothPairingUi()); + await flushTasks(); + assertNull(getBluetoothPairingUi()); - Router.getInstance().navigateTo(routes.BLUETOOTH_DEVICES, null); + Router.getInstance().navigateTo(routes.BLUETOOTH_DEVICES); bluetoothConfig.setSystemState(BluetoothSystemState.kEnabled); - await flushAsync(); + await flushTasks(); assertTrue(!!getPairNewDevice()); // Simulate Bluetooth disabled bluetoothConfig.setSystemState(BluetoothSystemState.kDisabled); - await flushAsync(); - assertFalse(!!getPairNewDevice()); + await flushTasks(); + assertNull(getPairNewDevice()); // Simulate Bluetooth unavailable bluetoothConfig.setSystemState(BluetoothSystemState.kUnavailable); - await flushAsync(); - assertFalse(!!getPairNewDevice()); + await flushTasks(); + assertNull(getPairNewDevice()); // Simulate Bluetooth enabled bluetoothConfig.setSystemState(BluetoothSystemState.kEnabling); - await flushAsync(); + await flushTasks(); assertTrue(!!getPairNewDevice()); - getPairNewDevice().click(); + getPairNewDevice()!.click(); - await flushAsync(); + await flushTasks(); assertTrue(!!getBluetoothPairingUi()); }); });
diff --git a/chrome/test/data/webui/settings/chromeos/os_bluetooth_page/os_bluetooth_pairing_dialog_tests.js b/chrome/test/data/webui/settings/chromeos/os_bluetooth_page/os_bluetooth_pairing_dialog_test.ts similarity index 69% rename from chrome/test/data/webui/settings/chromeos/os_bluetooth_page/os_bluetooth_pairing_dialog_tests.js rename to chrome/test/data/webui/settings/chromeos/os_bluetooth_page/os_bluetooth_pairing_dialog_test.ts index f3c2c5e5..599fd4a 100644 --- a/chrome/test/data/webui/settings/chromeos/os_bluetooth_page/os_bluetooth_pairing_dialog_tests.js +++ b/chrome/test/data/webui/settings/chromeos/os_bluetooth_page/os_bluetooth_pairing_dialog_test.ts
@@ -3,22 +3,19 @@ // found in the LICENSE file. import 'chrome://os-settings/os_settings.js'; -import 'chrome://os-settings/strings.m.js'; +import {SettingsBluetoothPairingDialogElement} from 'chrome://os-settings/os_settings.js'; import {setBluetoothConfigForTesting} from 'chrome://resources/ash/common/bluetooth/cros_bluetooth_config.js'; import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {assertTrue} from 'chrome://webui-test/chai_assert.js'; import {FakeBluetoothConfig} from 'chrome://webui-test/cr_components/chromeos/bluetooth/fake_bluetooth_config.js'; import {eventToPromise} from 'chrome://webui-test/test_util.js'; -suite('OsBluetoothPairingDialogTest', function() { - /** @type {?SettingsBluetoothPairingDialogElement} */ - let bluetoothPairingDialog; +suite('<os-settings-bluetooth-pairing-dialog>', () => { + let bluetoothPairingDialog: SettingsBluetoothPairingDialogElement; + let bluetoothConfig: FakeBluetoothConfig; - /** @type {!FakeBluetoothConfig} */ - let bluetoothConfig; - - setup(function() { + setup(() => { bluetoothConfig = new FakeBluetoothConfig(); setBluetoothConfigForTesting(bluetoothConfig); @@ -28,9 +25,13 @@ flush(); }); - test('Finished event is fired on close', async function() { - const pairingDialog = - bluetoothPairingDialog.shadowRoot.querySelector('bluetooth-pairing-ui'); + teardown(() => { + bluetoothPairingDialog.remove(); + }); + + test('Finished event is fired on close', async () => { + const pairingDialog = bluetoothPairingDialog.shadowRoot!.querySelector( + 'bluetooth-pairing-ui'); assertTrue(!!pairingDialog); const closeBluetoothPairingUiPromise =
diff --git a/chrome/test/data/webui/settings/chromeos/os_files_page/google_drive_page_test.ts b/chrome/test/data/webui/settings/chromeos/os_files_page/google_drive_page_test.ts index cee18e6..2fa62df1 100644 --- a/chrome/test/data/webui/settings/chromeos/os_files_page/google_drive_page_test.ts +++ b/chrome/test/data/webui/settings/chromeos/os_files_page/google_drive_page_test.ts
@@ -141,7 +141,7 @@ 'Remove Drive access', connectDisconnectButton!.textContent!.trim()); }); - test('confirming drive disconnect updates pref', async function() { + test('confirming drive disconnect updates pref', async () => { page.setPrefValue('gdata.disabled', false); flush(); @@ -158,7 +158,7 @@ test( 'cancelling drive disconnect confirmation dialog doesnt update pref', - async function() { + async () => { page.setPrefValue('gdata.disabled', false); flush(); @@ -173,7 +173,7 @@ }); - test('free space shows the offline value returned', async function() { + test('free space shows the offline value returned', async () => { // Send back a normal pinned size result. testBrowserProxy.handler.setResultFor( 'getContentCacheSize', {size: '100 MB'}); @@ -188,7 +188,7 @@ }); - test('when clear offline files clicked show dialog', async function() { + test('when clear offline files clicked show dialog', async () => { page.setPrefValue('drivefs.bulk_pinning_enabled', false); testBrowserProxy.handler.setResultFor( 'getContentCacheSize', {size: '100 MB'}); @@ -214,6 +214,23 @@ () => testBrowserProxy.handler.getCallCount('clearPinnedFiles') === 1); }); + + test('clean up storage button is disabled at 0 B', async () => { + testBrowserProxy.handler.setResultFor( + 'getContentCacheSize', {size: '0 B'}); + page.onNavigated(); + await assertAsync(() => clearOfflineStorageButton.disabled); + + testBrowserProxy.handler.setResultFor( + 'getContentCacheSize', {size: '100 MB'}); + page.onNavigated(); + await assertAsync(() => !clearOfflineStorageButton.disabled); + + testBrowserProxy.handler.setResultFor( + 'getContentCacheSize', {size: '0 B'}); + page.onNavigated(); + await assertAsync(() => clearOfflineStorageButton.disabled); + }); }); suite('with bulk pinning enabled', () => { @@ -224,7 +241,7 @@ }); }); - test('removing drive access also disables bulk pinning', async function() { + test('removing drive access also disables bulk pinning', async () => { page.setPrefValue('gdata.disabled', false); page.setPrefValue('drivefs.bulk_pinning_enabled', true); flush(); @@ -242,8 +259,7 @@ }); test( - 'clicking the toggle updates the bulk pinning preference', - async function() { + 'clicking the toggle updates the bulk pinning preference', async () => { page.setPrefValue('drivefs.bulk_pinning_enabled', false); flush(); @@ -257,7 +273,7 @@ test( 'progress sent via the browser proxy updates the sub title text', - async function() { + async () => { page.setPrefValue('drivefs.bulk_pinning_enabled', false); /** @@ -311,7 +327,7 @@ subTitle => !subTitle.includes(requiredSpaceText)); }); - test('disabling bulk pinning shows confirmation dialog', async function() { + test('disabling bulk pinning shows confirmation dialog', async () => { page.setPrefValue('drivefs.bulk_pinning_enabled', true); flush(); @@ -345,7 +361,7 @@ test( 'atempting to enable bulk pinning when no free space shows dialog', - async function() { + async () => { page.setPrefValue('drivefs.bulk_pinning_enabled', false); // Mock space values and the `kNotEnoughSpace` stage via the browser @@ -389,7 +405,7 @@ test( 'attempting to enable bulk pinning when no free space shows dialog', - async function() { + async () => { page.setPrefValue('drivefs.bulk_pinning_enabled', false); // Mock space values and the `kNotEnoughSpace` stage via the browser @@ -431,34 +447,32 @@ 'Pinning toggle should not be toggled'); }); - test( - 'clear offline files disabled when bulk pinning enabled', - async function() { - page.setPrefValue('drivefs.bulk_pinning_enabled', false); - testBrowserProxy.handler.setResultFor( - 'getContentCacheSize', {size: '100 MB'}); - page.onNavigated(); - testBrowserProxy.observerRemote.onProgress({ - freeSpace: 'x', - requiredSpace: 'y', - stage: Stage.kStopped, - isError: false, - }); - testBrowserProxy.observerRemote.$.flushForTesting(); - await assertAsync(() => !clearOfflineStorageButton.disabled); + test('clear offline files disabled when bulk pinning enabled', async () => { + page.setPrefValue('drivefs.bulk_pinning_enabled', false); + testBrowserProxy.handler.setResultFor( + 'getContentCacheSize', {size: '100 MB'}); + page.onNavigated(); + testBrowserProxy.observerRemote.onProgress({ + freeSpace: 'x', + requiredSpace: 'y', + stage: Stage.kStopped, + isError: false, + }); + testBrowserProxy.observerRemote.$.flushForTesting(); + await assertAsync(() => !clearOfflineStorageButton.disabled); - page.setPrefValue('drivefs.bulk_pinning_enabled', true); - testBrowserProxy.handler.setResultFor( - 'getContentCacheSize', {size: '100 MB'}); - page.onNavigated(); - testBrowserProxy.observerRemote.onProgress({ - freeSpace: 'x', - requiredSpace: 'y', - stage: Stage.kSyncing, - isError: false, - }); - testBrowserProxy.observerRemote.$.flushForTesting(); - await assertAsync(() => clearOfflineStorageButton.disabled); - }); + page.setPrefValue('drivefs.bulk_pinning_enabled', true); + testBrowserProxy.handler.setResultFor( + 'getContentCacheSize', {size: '100 MB'}); + page.onNavigated(); + testBrowserProxy.observerRemote.onProgress({ + freeSpace: 'x', + requiredSpace: 'y', + stage: Stage.kSyncing, + isError: false, + }); + testBrowserProxy.observerRemote.$.flushForTesting(); + await assertAsync(() => clearOfflineStorageButton.disabled); + }); }); });
diff --git a/chrome/test/data/webui/settings/chromeos/os_people_page/password_settings_api.test-mojom b/chrome/test/data/webui/settings/chromeos/os_people_page/password_settings_api.test-mojom deleted file mode 100644 index 670d8713..0000000 --- a/chrome/test/data/webui/settings/chromeos/os_people_page/password_settings_api.test-mojom +++ /dev/null
@@ -1,16 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -module ash.settings.mojom; - -enum PasswordType { - kGaia, - kLocal, -}; - -// The test API for the settings-password-settings element. -interface PasswordSettingsApi { - // Verifies that the given password type is selected. - AssertSelectedPasswordType(PasswordType? password_type) => (); -};
diff --git a/chrome/test/data/webui/settings/chromeos/os_people_page/password_settings_api.ts b/chrome/test/data/webui/settings/chromeos/os_people_page/password_settings_api.ts deleted file mode 100644 index d01c58e..0000000 --- a/chrome/test/data/webui/settings/chromeos/os_people_page/password_settings_api.ts +++ /dev/null
@@ -1,68 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import {assertTrue} from 'chrome://webui-test/chai_assert.js'; - -import {PasswordSettingsApiInterface, PasswordSettingsApiReceiver, PasswordSettingsApiRemote, PasswordType} from '../password_settings_api.test-mojom-webui.js'; -import {assertAsync, assertForDuration, hasBooleanProperty} from '../utils.js'; - -// The test API for the settings-password-settings element. -export class PasswordSettingsApi implements PasswordSettingsApiInterface { - private element: HTMLElement; - - constructor(element: HTMLElement) { - this.element = element; - assertTrue(this.element.shadowRoot !== null); - } - - public newRemote(): PasswordSettingsApiRemote { - const receiver = new PasswordSettingsApiReceiver(this); - return receiver.$.bindNewPipeAndPassRemote(); - } - - private shadowRoot(): ShadowRoot { - const shadowRoot = this.element.shadowRoot; - assertTrue(shadowRoot !== null); - return shadowRoot; - } - - private queryGaiaRadio(): {checked: boolean}&HTMLElement { - const el = this.shadowRoot().querySelector('*[name="gaia"]'); - assertTrue(el instanceof HTMLElement); - assertTrue(hasBooleanProperty(el, 'checked')); - return el; - } - - private queryLocalRadio(): {checked: boolean}&HTMLElement { - const el = this.shadowRoot().querySelector('*[name="local"]'); - assertTrue(el instanceof HTMLElement); - assertTrue(hasBooleanProperty(el, 'checked')); - return el; - } - - selectedPasswordType(): PasswordType|null { - const gaiaRadio = this.queryGaiaRadio(); - const localRadio = this.queryLocalRadio(); - - assertTrue( - !(gaiaRadio.checked && localRadio.checked), - 'There must be at most one selected password type'); - - if (gaiaRadio.checked) { - return PasswordType.kGaia; - } - if (localRadio.checked) { - return PasswordType.kLocal; - } - - return null; - } - - async assertSelectedPasswordType(passwordType: PasswordType| - null): Promise<void> { - const isSelected = () => this.selectedPasswordType() === passwordType; - await assertAsync(isSelected); - await assertForDuration(isSelected); - } -}
diff --git a/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js b/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js index c127ab68..7efc6b9 100644 --- a/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js +++ b/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js
@@ -195,6 +195,11 @@ ['CellularNetworksList', 'cellular_networks_list_test.js'], ['CellularRoamingToggleButton', 'cellular_roaming_toggle_button_test.js'], ['DateTimePage', 'date_time_page/date_time_page_test.js'], + [ + 'DateTimePageDateTimeCard', + 'date_time_page/date_time_card_test.js', + {disabled: ['ash::features::kOsSettingsRevampWayfinding']}, + ], ['DateTimePageTimezoneSelector', 'date_time_page/timezone_selector_test.js'], ['DateTimePageTimezoneSubpage', 'date_time_page/timezone_subpage_test.js'], ['DevicePageAudioPage', 'device_page/audio_page_test.js'], @@ -600,7 +605,7 @@ 'OsAppsPageAppNotificationsPageAppNotificationsSubpage', 'os_apps_page/app_notifications_page/app_notifications_subpage_test.js' ], - ['OsBluetoothPage', 'os_bluetooth_page/os_bluetooth_page_tests.js'], + ['OsBluetoothPage', 'os_bluetooth_page/os_bluetooth_page_test.js'], [ 'OsBluetoothPageOsBluetoothChangeDeviceNameDialog', 'os_bluetooth_page/os_bluetooth_change_device_name_dialog_test.js', @@ -612,7 +617,7 @@ ], [ 'OsBluetoothPageOsBluetoothPairingDialog', - 'os_bluetooth_page/os_bluetooth_pairing_dialog_tests.js' + 'os_bluetooth_page/os_bluetooth_pairing_dialog_test.js' ], [ 'OsBluetoothPageOsBluetoothSummary', @@ -836,6 +841,11 @@ }, ], [ + 'SystemPreferencesPageDateTimeCard', + 'date_time_page/date_time_card_test.js', + {enabled: ['ash::features::kOsSettingsRevampWayfinding']}, + ], + [ 'SystemPreferencesPageResetCard', 'os_reset_page/reset_card_test.js', {enabled: ['ash::features::kOsSettingsRevampWayfinding']},
diff --git a/chrome/test/data/webui/settings/chromeos/test_api.test-mojom b/chrome/test/data/webui/settings/chromeos/test_api.test-mojom index 98f2781d..fd6ca41 100644 --- a/chrome/test/data/webui/settings/chromeos/test_api.test-mojom +++ b/chrome/test/data/webui/settings/chromeos/test_api.test-mojom
@@ -4,7 +4,6 @@ module ash.settings.mojom; -import "chrome/test/data/webui/settings/chromeos/os_people_page/password_settings_api.test-mojom"; import "chrome/test/data/webui/settings/chromeos/os_people_page/pin_settings_api.test-mojom"; // This file contains the definition of the mojo service that can be used in @@ -30,14 +29,6 @@ // Crashes if authentication succeeds. AuthenticateIncorrectly(string password) => (); - // Checks whether a control for changing passwords is visible or not. - AssertPasswordControlVisibility(bool is_visible) => (); - - // Navigates to password settings. Crashes if no password settings control is - // visible. The return value can be used to interact with password settings. - GoToPasswordSettings() => - (pending_remote<PasswordSettingsApi> password_settings); - // Checks whether a control for recovery is available or not. AssertRecoveryControlAvailability(bool is_available) => ();
diff --git a/chrome/test/data/webui/settings/chromeos/test_api.ts b/chrome/test/data/webui/settings/chromeos/test_api.ts index 948f73a7..eef42f1 100644 --- a/chrome/test/data/webui/settings/chromeos/test_api.ts +++ b/chrome/test/data/webui/settings/chromeos/test_api.ts
@@ -9,9 +9,7 @@ import {CrButtonElement, SettingsGoogleDriveSubpageElement, SettingsToggleButtonElement} from 'chrome://os-settings/os_settings.js'; import {assertTrue} from 'chrome://webui-test/chai_assert.js'; -import {PasswordSettingsApi} from './os_people_page/password_settings_api.js'; import {PinSettingsApi} from './os_people_page/pin_settings_api.js'; -import {PasswordSettingsApiRemote} from './password_settings_api.test-mojom-webui.js'; import {PinSettingsApiRemote} from './pin_settings_api.test-mojom-webui.js'; import {GoogleDriveSettingsInterface, GoogleDriveSettingsReceiver, GoogleDriveSettingsRemote, LockScreenSettings_RecoveryDialogAction as RecoveryDialogAction, LockScreenSettingsInterface, LockScreenSettingsReceiver, LockScreenSettingsRemote, OSSettingsBrowserProcess, OSSettingsDriverInterface, OSSettingsDriverReceiver} from './test_api.test-mojom-webui.js'; import {assertAsync, assertForDuration, hasBooleanProperty, hasProperty, Lazy, querySelectorShadow, retry, retryUntilSome} from './utils.js'; @@ -130,35 +128,6 @@ await this.authenticate(password, false); } - private queryPasswordSettings(): PasswordSettingsApi|null { - const el = this.shadowRoot().getElementById('passwordSettings'); - if (!(el instanceof HTMLElement)) { - return null; - } - if (el.hidden) { - return null; - } - - return new PasswordSettingsApi(el); - } - - async assertPasswordControlVisibility(isVisible: boolean): Promise<void> { - const property = () => { - const settings = this.queryPasswordSettings(); - return (settings !== null) === isVisible; - }; - - await assertAsync(property); - await assertForDuration(property); - } - - public async goToPasswordSettings(): - Promise<{passwordSettings: PasswordSettingsApiRemote}> { - const passwordSettings = - await retryUntilSome(() => this.queryPasswordSettings()); - return {passwordSettings: passwordSettings.newRemote()}; - } - private recoveryToggle(): HTMLElement&{checked: boolean}|null { const toggle = this.shadowRoot().getElementById('recoveryToggle'); if (toggle === null) {
diff --git a/chrome/updater/policy/service.cc b/chrome/updater/policy/service.cc index 15436b8..c8903ad 100644 --- a/chrome/updater/policy/service.cc +++ b/chrome/updater/policy/service.cc
@@ -82,6 +82,7 @@ should_take_policy_critical_section, external_constants->IsMachineManaged()); if (group_policy_manager->CloudPolicyOverridesPlatformPolicy()) { + VLOG(1) << __func__ << ": CloudPolicyOverridesPlatformPolicy=1"; managers.push_back(std::move(group_policy_manager)); } else { managers.insert(managers.begin(), std::move(group_policy_manager));
diff --git a/chrome/updater/test/integration_tests.cc b/chrome/updater/test/integration_tests.cc index cf1742df..eb1d165 100644 --- a/chrome/updater/test/integration_tests.cc +++ b/chrome/updater/test/integration_tests.cc
@@ -111,6 +111,8 @@ protected: void SetUp() override { + VLOG(2) << __func__ << " entered."; + ASSERT_NO_FATAL_FAILURE(CleanProcesses()); ASSERT_TRUE(WaitForUpdaterExit()); ASSERT_NO_FATAL_FAILURE(Clean()); @@ -139,9 +141,13 @@ // Mark the device as de-registered. This stops sending DM requests // that mess up the request expectations in the mock server. ASSERT_NO_FATAL_FAILURE(DMDeregisterDevice()); + + VLOG(2) << __func__ << "completed."; } void TearDown() override { + VLOG(2) << __func__ << " entered."; + ExitTestMode(); if (!HasFailure()) { ExpectClean(); @@ -156,6 +162,8 @@ // Updater process must not be running for `Clean()` to succeed. ASSERT_TRUE(WaitForUpdaterExit()); Clean(); + + VLOG(2) << __func__ << "completed."; } void ExpectNoCrashes() { test_commands_->ExpectNoCrashes(); } @@ -531,7 +539,6 @@ ASSERT_NO_FATAL_FAILURE(InstallApp("test")); ASSERT_TRUE(WaitForUpdaterExit()); - ASSERT_NO_FATAL_FAILURE(ExpectInstalled()); ASSERT_NO_FATAL_FAILURE(ExpectVersionActive(kUpdaterVersion)); ASSERT_NO_FATAL_FAILURE(ExpectRegistered("test")); @@ -1572,6 +1579,32 @@ &exit_code)); EXPECT_EQ(0, exit_code); }); + + ExpectAppInstalled(app_id, version); + } + + void SetUpdateDefaultGroupPolicy(int policy) { + EXPECT_EQ(ERROR_SUCCESS, + base::win::RegKey(HKEY_LOCAL_MACHINE, UPDATER_POLICIES_KEY, + Wow6432(KEY_WRITE)) + .WriteValue(L"UpdateDefault", policy)); + } + + void SetAppUpdateGroupPolicy(const std::string& appid, int policy) { + EXPECT_EQ(ERROR_SUCCESS, + base::win::RegKey(HKEY_LOCAL_MACHINE, UPDATER_POLICIES_KEY, + Wow6432(KEY_WRITE)) + .WriteValue(base::ASCIIToWide( + base::StringPrintf("Update%s", appid.c_str())) + .c_str(), + policy)); + } + + void SetCloudPolicyOverridesPlatformPolicy() { + EXPECT_EQ(ERROR_SUCCESS, + base::win::RegKey(HKEY_LOCAL_MACHINE, UPDATER_POLICIES_KEY, + Wow6432(KEY_WRITE)) + .WriteValue(L"CloudPolicyOverridesPlatformPolicy", 1)); } void ExpectAppInstalled(const std::string& appid, @@ -1642,22 +1675,11 @@ const base::Version kApp3UpdatedVersion = base::Version("1.1"); ASSERT_NO_FATAL_FAILURE(Install()); + ASSERT_NO_FATAL_FAILURE(ExpectInstalled()); ASSERT_NO_FATAL_FAILURE(InstallAppWithVersion(kAppId1, kApp1InitialVersion)); ASSERT_NO_FATAL_FAILURE(InstallAppWithVersion(kAppId2, kApp2InitialVersion)); ASSERT_NO_FATAL_FAILURE(InstallAppWithVersion(kAppId3, kApp3InitialVersion)); - ASSERT_NO_FATAL_FAILURE(ExpectInstalled()); - ASSERT_NO_FATAL_FAILURE(ExpectAppInstalled(kAppId1, kApp1InitialVersion)); - ASSERT_NO_FATAL_FAILURE(ExpectAppInstalled(kAppId2, kApp2InitialVersion)); - ASSERT_NO_FATAL_FAILURE(ExpectAppInstalled(kAppId3, kApp3InitialVersion)); - - // Group policy sets app2 to auto-update. - base::win::RegKey key(HKEY_LOCAL_MACHINE, UPDATER_POLICIES_KEY, - Wow6432(KEY_WRITE)); - EXPECT_EQ( - ERROR_SUCCESS, - key.WriteValue( - base::ASCIIToWide(base::StringPrintf("Update%s", kAppId2)).c_str(), - kPolicyEnabled)); + ASSERT_NO_FATAL_FAILURE(SetAppUpdateGroupPolicy(kAppId2, kPolicyEnabled)); // Cloud policy sets update default to disabled, app1 to auto-update, and // app2 to manual-update. @@ -1696,7 +1718,66 @@ ASSERT_NO_FATAL_FAILURE(ExpectAppInstalled(kAppId1, kApp1UpdatedVersion)); ASSERT_NO_FATAL_FAILURE(ExpectAppInstalled(kAppId2, kApp2UpdatedVersion)); ASSERT_NO_FATAL_FAILURE(ExpectAppInstalled(kAppId3, kApp3InitialVersion)); + ASSERT_NO_FATAL_FAILURE(ExpectUninstallPing(test_server_.get())); + ASSERT_NO_FATAL_FAILURE(Uninstall()); +} +TEST_F(IntegrationTestDeviceManagement, CloudPolicyOverridesPlatformPolicy) { + ASSERT_NO_FATAL_FAILURE(SetCloudPolicyOverridesPlatformPolicy()); + + const base::Version kApp1InitialVersion = base::Version("1.2.3.4"); + const base::Version kApp1UpdatedVersion = base::Version("2.3.4.5"); + const base::Version kApp2InitialVersion = base::Version("100.0.0.0"); + const base::Version kApp2UpdatedVersion = base::Version("101.0.0.0"); + const base::Version kApp3InitialVersion = base::Version("1.0"); + const base::Version kApp3UpdatedVersion = base::Version("1.1"); + + ASSERT_NO_FATAL_FAILURE(Install()); + ASSERT_NO_FATAL_FAILURE(ExpectInstalled()); + ASSERT_NO_FATAL_FAILURE(InstallAppWithVersion(kAppId1, kApp1InitialVersion)); + ASSERT_NO_FATAL_FAILURE(InstallAppWithVersion(kAppId2, kApp2InitialVersion)); + ASSERT_NO_FATAL_FAILURE(InstallAppWithVersion(kAppId3, kApp3InitialVersion)); + + ASSERT_NO_FATAL_FAILURE(SetUpdateDefaultGroupPolicy(kPolicyDisabled)); + ASSERT_NO_FATAL_FAILURE(SetAppUpdateGroupPolicy(kAppId1, kPolicyDisabled)); + ASSERT_NO_FATAL_FAILURE(SetAppUpdateGroupPolicy(kAppId2, kPolicyEnabled)); + ASSERT_NO_FATAL_FAILURE(SetAppUpdateGroupPolicy(kAppId3, kPolicyEnabled)); + + // Overrides app1 to auto-update, app2 to manual-update with cloud policy. + PushEnrollmentToken(kEnrollmentToken); + ExpectDeviceManagementRegistrationRequest(test_server_.get(), + kEnrollmentToken, kDMToken); + OmahaSettingsClientProto omaha_settings; + ApplicationSettings app1; + app1.set_app_guid(kAppId1); + app1.set_update(enterprise_management::AUTOMATIC_UPDATES_ONLY); + omaha_settings.mutable_application_settings()->Add(std::move(app1)); + ApplicationSettings app2; + app2.set_app_guid(kAppId2); + app2.set_update(enterprise_management::MANUAL_UPDATES_ONLY); + omaha_settings.mutable_application_settings()->Add(std::move(app2)); + ExpectDeviceManagementPolicyFetchRequest(test_server_.get(), kDMToken, + omaha_settings); + + const base::FilePath crx_path = GetInstallerPath(kAppCRX); + ExpectAppsUpdateSequence( + UpdaterScope::kSystem, test_server_.get(), + { + AppUpdateExpectation({kAppId1, kApp1InitialVersion, + kApp1UpdatedVersion, + /*should_update=*/true, false, "", crx_path}), + AppUpdateExpectation({kAppId2, kApp2InitialVersion, + kApp2InitialVersion, + /*should_update=*/false, false, "", crx_path}), + AppUpdateExpectation({kAppId3, kApp3InitialVersion, + kApp3UpdatedVersion, + /*should_update=*/true, false, "", crx_path}), + }); + ASSERT_NO_FATAL_FAILURE(RunWake(0)); + ASSERT_TRUE(WaitForUpdaterExit()); + ASSERT_NO_FATAL_FAILURE(ExpectAppInstalled(kAppId1, kApp1UpdatedVersion)); + ASSERT_NO_FATAL_FAILURE(ExpectAppInstalled(kAppId2, kApp2InitialVersion)); + ASSERT_NO_FATAL_FAILURE(ExpectAppInstalled(kAppId3, kApp3UpdatedVersion)); ASSERT_NO_FATAL_FAILURE(ExpectUninstallPing(test_server_.get())); ASSERT_NO_FATAL_FAILURE(Uninstall()); }
diff --git a/chromeos/ash/components/drivefs/fake_drivefs.cc b/chromeos/ash/components/drivefs/fake_drivefs.cc index 007dd7de8..95c3ccb 100644 --- a/chromeos/ash/components/drivefs/fake_drivefs.cc +++ b/chromeos/ash/components/drivefs/fake_drivefs.cc
@@ -710,11 +710,6 @@ std::move(callback).Run(drive::FILE_ERROR_OK); } -void FakeDriveFs::ClearOfflineFiles( - drivefs::mojom::DriveFs::ClearOfflineFilesCallback callback) { - std::move(callback).Run(drive::FILE_ERROR_OK); -} - void FakeDriveFs::GetDocsOfflineStats( drivefs::mojom::DriveFs::GetDocsOfflineStatsCallback callback) { drivefs::mojom::DocsOfflineStatsPtr stats =
diff --git a/chromeos/ash/components/drivefs/fake_drivefs.h b/chromeos/ash/components/drivefs/fake_drivefs.h index fa3e46d..c4d24ec 100644 --- a/chromeos/ash/components/drivefs/fake_drivefs.h +++ b/chromeos/ash/components/drivefs/fake_drivefs.h
@@ -107,6 +107,11 @@ (override)); MOCK_METHOD(void, + ClearOfflineFiles, + (drivefs::mojom::DriveFs::ClearOfflineFilesCallback callback), + (override)); + + MOCK_METHOD(void, ImmediatelyUpload, (const base::FilePath& path, drivefs::mojom::DriveFs::ImmediatelyUploadCallback callback), @@ -260,9 +265,6 @@ bool enabled, drivefs::mojom::DriveFs::SetDocsOfflineEnabledCallback callback) override; - void ClearOfflineFiles( - drivefs::mojom::DriveFs::ClearOfflineFilesCallback) override; - void GetDocsOfflineStats( drivefs::mojom::DriveFs::GetDocsOfflineStatsCallback) override;
diff --git a/chromeos/ash/components/nearby/presence/credentials/nearby_presence_credential_manager_impl.cc b/chromeos/ash/components/nearby/presence/credentials/nearby_presence_credential_manager_impl.cc index 32c31d232..0af4362 100644 --- a/chromeos/ash/components/nearby/presence/credentials/nearby_presence_credential_manager_impl.cc +++ b/chromeos/ash/components/nearby/presence/credentials/nearby_presence_credential_manager_impl.cc
@@ -680,7 +680,8 @@ request, base::BindOnce( &NearbyPresenceCredentialManagerImpl::OnUploadCredentialsSuccess, - weak_ptr_factory_.GetWeakPtr(), upload_credentials_result_callback), + weak_ptr_factory_.GetWeakPtr(), upload_credentials_result_callback, + /*upload_request_start_time=*/base::TimeTicks::Now()), base::BindOnce( &NearbyPresenceCredentialManagerImpl::OnUploadCredentialsFailure, weak_ptr_factory_.GetWeakPtr(), upload_credentials_result_callback)); @@ -734,11 +735,15 @@ void NearbyPresenceCredentialManagerImpl::OnUploadCredentialsSuccess( base::RepeatingCallback<void(bool)> upload_credentials_callback, + base::TimeTicks upload_request_start_time, const ash::nearby::proto::UpdateDeviceResponse& response) { // TODO(b/276307539): Log response and check for changes in user name and // image url returned from the server. server_response_timer_.Stop(); + base::TimeDelta upload_request_duration = + base::TimeTicks::Now() - upload_request_start_time; + metrics::RecordSharedCredentialUploadDuration(upload_request_duration); HandleUploadCredentialsResult( upload_credentials_callback, /*result=*/ash::nearby::NearbyHttpResult::kSuccess); @@ -779,7 +784,8 @@ request, base::BindOnce( &NearbyPresenceCredentialManagerImpl::OnDownloadCredentialsSuccess, - weak_ptr_factory_.GetWeakPtr(), download_credentials_result_callback), + weak_ptr_factory_.GetWeakPtr(), download_credentials_result_callback, + /*download_request_start_time=*/base::TimeTicks::Now()), base::BindOnce( &NearbyPresenceCredentialManagerImpl::OnDownloadCredentialsFailure, weak_ptr_factory_.GetWeakPtr(), @@ -843,8 +849,12 @@ base::RepeatingCallback< void(std::vector<::nearby::internal::SharedCredential>, bool)> download_credentials_result_callback, + base::TimeTicks download_request_start_time, const ash::nearby::proto::ListPublicCertificatesResponse& response) { server_response_timer_.Stop(); + base::TimeDelta download_request_duration = + base::TimeTicks::Now() - download_request_start_time; + metrics::RecordSharedCredentialDownloadDuration(download_request_duration); std::vector<::nearby::internal::SharedCredential> remote_credentials; for (auto public_certificate : response.public_certificates()) {
diff --git a/chromeos/ash/components/nearby/presence/credentials/nearby_presence_credential_manager_impl.h b/chromeos/ash/components/nearby/presence/credentials/nearby_presence_credential_manager_impl.h index 5637082..4c8bcaf 100644 --- a/chromeos/ash/components/nearby/presence/credentials/nearby_presence_credential_manager_impl.h +++ b/chromeos/ash/components/nearby/presence/credentials/nearby_presence_credential_manager_impl.h
@@ -9,6 +9,7 @@ #include "base/memory/raw_ptr.h" #include "base/no_destructor.h" +#include "base/time/time.h" #include "base/timer/timer.h" #include "chromeos/ash/components/nearby/common/client/nearby_http_result.h" #include "chromeos/ash/components/nearby/presence/metrics/nearby_presence_metrics.h" @@ -220,6 +221,7 @@ base::RepeatingCallback<void(bool)> upload_credentials_callback); void OnUploadCredentialsSuccess( base::RepeatingCallback<void(bool)> upload_credentials_callback, + base::TimeTicks upload_request_start_time, const ash::nearby::proto::UpdateDeviceResponse& response); void OnUploadCredentialsFailure( base::RepeatingCallback<void(bool)> upload_credentials_callback, @@ -242,6 +244,7 @@ base::RepeatingCallback< void(std::vector<::nearby::internal::SharedCredential>, bool)> download_credentials_result_callback, + base::TimeTicks download_request_start_time, const ash::nearby::proto::ListPublicCertificatesResponse& response); void OnDownloadCredentialsFailure( base::RepeatingCallback<
diff --git a/chromeos/ash/components/nearby/presence/credentials/nearby_presence_credential_manager_impl_unittest.cc b/chromeos/ash/components/nearby/presence/credentials/nearby_presence_credential_manager_impl_unittest.cc index 2aea932..982e198 100644 --- a/chromeos/ash/components/nearby/presence/credentials/nearby_presence_credential_manager_impl_unittest.cc +++ b/chromeos/ash/components/nearby/presence/credentials/nearby_presence_credential_manager_impl_unittest.cc
@@ -405,6 +405,8 @@ histogram_tester_.ExpectBucketCount( "Nearby.Presence.Credentials.Upload.AttemptsNeededCount", /*bucket: attempt_count=*/1, 1); + histogram_tester_.ExpectTotalCount( + "Nearby.Presence.Credentials.Upload.ServerRequestDuration", 1); histogram_tester_.ExpectBucketCount( "Nearby.Presence.Credentials.Download.Result", /*bucket: success=*/true, 1); @@ -413,6 +415,8 @@ histogram_tester_.ExpectBucketCount( "Nearby.Presence.Credentials.Download.AttemptsNeededCount", /*bucket: attempt_count=*/1, 1); + histogram_tester_.ExpectTotalCount( + "Nearby.Presence.Credentials.Download.ServerRequestDuration", 1); } TEST_F(NearbyPresenceCredentialManagerImplTest, ServerRegistrationTimeout) { @@ -525,6 +529,8 @@ "Nearby.Presence.Credentials.Upload.FailureReason", /*bucket: NearbyHttpResult::kTimeout*/ ash::nearby::NearbyHttpResult::kTimeout, 1); + histogram_tester_.ExpectTotalCount( + "Nearby.Presence.Credentials.Upload.ServerRequestDuration", 0); } TEST_F(NearbyPresenceCredentialManagerImplTest, UploadCredentialsFailure) { @@ -565,6 +571,8 @@ "Nearby.Presence.Credentials.Upload.FailureReason", /*bucket: NearbyHttpResult::kHttpErrorInternalServerError*/ ash::nearby::NearbyHttpResult::kHttpErrorInternalServerError, 1); + histogram_tester_.ExpectTotalCount( + "Nearby.Presence.Credentials.Upload.ServerRequestDuration", 0); } TEST_F(NearbyPresenceCredentialManagerImplTest, DownloadCredentialsFailure) { @@ -718,6 +726,8 @@ histogram_tester_.ExpectBucketCount( "Nearby.Presence.Credentials.Upload.AttemptsNeededCount", /*bucket: attempt_count=*/1, 1); + histogram_tester_.ExpectTotalCount( + "Nearby.Presence.Credentials.Upload.ServerRequestDuration", 1); histogram_tester_.ExpectBucketCount( "Nearby.Presence.Credentials.Download.Result", /*bucket: success=*/true, 1); @@ -726,6 +736,8 @@ histogram_tester_.ExpectBucketCount( "Nearby.Presence.Credentials.Download.AttemptsNeededCount", /*bucket: attempt_count=*/1, 1); + histogram_tester_.ExpectTotalCount( + "Nearby.Presence.Credentials.Download.ServerRequestDuration", 1); } TEST_F(NearbyPresenceCredentialManagerImplTest, @@ -765,6 +777,8 @@ "Nearby.Presence.Credentials.Upload.FailureReason", 0); histogram_tester_.ExpectTotalCount( "Nearby.Presence.Credentials.Upload.AttemptsNeededCount", 0); + histogram_tester_.ExpectTotalCount( + "Nearby.Presence.Credentials.Upload.ServerRequestDuration", 0); histogram_tester_.ExpectBucketCount( "Nearby.Presence.Credentials.Download.Result", /*bucket: success=*/true, 1); @@ -773,6 +787,8 @@ histogram_tester_.ExpectBucketCount( "Nearby.Presence.Credentials.Download.AttemptsNeededCount", /*bucket: attempt_count=*/1, 1); + histogram_tester_.ExpectTotalCount( + "Nearby.Presence.Credentials.Download.ServerRequestDuration", 1); } TEST_F(NearbyPresenceCredentialManagerImplTest, @@ -826,6 +842,8 @@ ash::nearby::NearbyHttpResult::kHttpErrorInternalServerError, 1); histogram_tester_.ExpectTotalCount( "Nearby.Presence.Credentials.Upload.AttemptsNeededCount", 0); + histogram_tester_.ExpectTotalCount( + "Nearby.Presence.Credentials.Upload.ServerRequestDuration", 0); } TEST_F(NearbyPresenceCredentialManagerImplTest, @@ -861,6 +879,8 @@ ash::nearby::NearbyHttpResult::kHttpErrorInternalServerError, 1); histogram_tester_.ExpectTotalCount( "Nearby.Presence.Credentials.Download.AttemptsNeededCount", 0); + histogram_tester_.ExpectTotalCount( + "Nearby.Presence.Credentials.Download.ServerRequestDuration", 0); } TEST_F(NearbyPresenceCredentialManagerImplTest, @@ -920,6 +940,8 @@ "Nearby.Presence.Credentials.Upload.FailureReason", 0); histogram_tester_.ExpectTotalCount( "Nearby.Presence.Credentials.Upload.AttemptsNeededCount", 0); + histogram_tester_.ExpectTotalCount( + "Nearby.Presence.Credentials.Upload.ServerRequestDuration", 0); histogram_tester_.ExpectBucketCount( "Nearby.Presence.Credentials.Download.Result", /*bucket: success=*/true, 7); @@ -928,6 +950,8 @@ histogram_tester_.ExpectBucketCount( "Nearby.Presence.Credentials.Download.AttemptsNeededCount", /*bucket: attempt_count=*/1, 7); + histogram_tester_.ExpectTotalCount( + "Nearby.Presence.Credentials.Download.ServerRequestDuration", 7); } } // namespace ash::nearby::presence
diff --git a/chromeos/ash/components/nearby/presence/metrics/nearby_presence_metrics.cc b/chromeos/ash/components/nearby/presence/metrics/nearby_presence_metrics.cc index 50165885..5faa05e 100644 --- a/chromeos/ash/components/nearby/presence/metrics/nearby_presence_metrics.cc +++ b/chromeos/ash/components/nearby/presence/metrics/nearby_presence_metrics.cc
@@ -25,6 +25,12 @@ success); } +void RecordSharedCredentialUploadDuration(base::TimeDelta upload_duration) { + base::UmaHistogramTimes( + "Nearby.Presence.Credentials.Upload.ServerRequestDuration", + upload_duration); +} + void RecordSharedCredentialDownloadFailureReason( ash::nearby::NearbyHttpResult failure_reason) { base::UmaHistogramEnumeration( @@ -47,6 +53,12 @@ "Nearby.Presence.Credentials.FirstTimeRegistration.Result", result); } +void RecordSharedCredentialDownloadDuration(base::TimeDelta download_duration) { + base::UmaHistogramTimes( + "Nearby.Presence.Credentials.Download.ServerRequestDuration", + download_duration); +} + void RecordFirstTimeServerRegistrationFailureReason( ash::nearby::NearbyHttpResult failure_reason) { base::UmaHistogramEnumeration(
diff --git a/chromeos/ash/components/nearby/presence/metrics/nearby_presence_metrics.h b/chromeos/ash/components/nearby/presence/metrics/nearby_presence_metrics.h index 093fb95..895b3c4 100644 --- a/chromeos/ash/components/nearby/presence/metrics/nearby_presence_metrics.h +++ b/chromeos/ash/components/nearby/presence/metrics/nearby_presence_metrics.h
@@ -5,6 +5,7 @@ #ifndef CHROMEOS_ASH_COMPONENTS_NEARBY_PRESENCE_METRICS_NEARBY_PRESENCE_METRICS_H_ #define CHROMEOS_ASH_COMPONENTS_NEARBY_PRESENCE_METRICS_NEARBY_PRESENCE_METRICS_H_ +#include "base/time/time.h" #include "chromeos/ash/components/nearby/common/client/nearby_http_result.h" namespace ash::nearby::presence::metrics { @@ -13,15 +14,22 @@ ash::nearby::NearbyHttpResult failure_reason); void RecordSharedCredentialUploadTotalAttemptsNeededCount(int attempt_count); void RecordSharedCredentialUploadResult(bool success); - +void RecordSharedCredentialUploadDuration(base::TimeDelta upload_duration); void RecordSharedCredentialDownloadFailureReason( ash::nearby::NearbyHttpResult failure_reason); void RecordSharedCredentialDownloadTotalAttemptsNeededCount(int attempt_count); void RecordSharedCredentialDownloadResult(bool success); +void RecordSharedCredentialDownloadDuration(base::TimeDelta download_duration); +void RecordFirstTimeRegistrationFlowResult(bool success); +void RecordFirstTimeServerRegistrationFailureReason( + ash::nearby::NearbyHttpResult failure_reason); +void RecordFirstTimeServerRegistrationTotalAttemptsNeededCount( + int attempt_count); // These values are persisted to logs. Entries should not be renumbered and // numeric values should never be reused. This enum should be kept in sync with -// the FastPairPairFailure enum in src/tools/metrics/histograms/enums.xml. +// the FirstTimeRegistrationResult enum in +// src/tools/metrics/histograms/enums.xml. enum class FirstTimeRegistrationResult { kSuccess = 0, kRegistrationWithServerFailure = 1,
diff --git a/components/autofill/core/browser/autofill_browser_util.cc b/components/autofill/core/browser/autofill_browser_util.cc index 55af9f2..013511c8 100644 --- a/components/autofill/core/browser/autofill_browser_util.cc +++ b/components/autofill/core/browser/autofill_browser_util.cc
@@ -51,20 +51,4 @@ return !IsFormOrClientNonSecure(client, form); } -bool IsCompleteCreditCardFormIncludingCvcField( - const FormStructure& form_structure) { - // If card number field or expiration date field is not detected, return - // false. - if (!form_structure.IsCompleteCreditCardForm()) - return false; - - // If CVC field is detected, then all requirements are met, otherwise return - // false. - for (auto& field : form_structure) { - if (field->Type().GetStorableType() == CREDIT_CARD_VERIFICATION_CODE) - return true; - } - return false; -} - } // namespace autofill
diff --git a/components/autofill/core/browser/autofill_browser_util.h b/components/autofill/core/browser/autofill_browser_util.h index eca5f33..a933408 100644 --- a/components/autofill/core/browser/autofill_browser_util.h +++ b/components/autofill/core/browser/autofill_browser_util.h
@@ -31,11 +31,6 @@ bool ShouldAllowCreditCardFallbacks(const AutofillClient& client, const FormData& form); -// Returns whether the form is a complete credit card form with card number -// field, card expiration date field and card CVC field detected. -bool IsCompleteCreditCardFormIncludingCvcField( - const FormStructure& form_structure); - } // namespace autofill #endif // COMPONENTS_AUTOFILL_CORE_BROWSER_AUTOFILL_BROWSER_UTIL_H_
diff --git a/components/autofill/core/browser/autofill_external_delegate.cc b/components/autofill/core/browser/autofill_external_delegate.cc index 8b92adf..8ca2e37 100644 --- a/components/autofill/core/browser/autofill_external_delegate.cc +++ b/components/autofill/core/browser/autofill_external_delegate.cc
@@ -356,13 +356,6 @@ case PopupItemId::kShowAccountCards: manager_->OnUserAcceptedCardsFromAccountOption(); break; - case PopupItemId::kUseVirtualCard: -#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) - manager_->FetchVirtualCardCandidates(); -#else - NOTREACHED(); -#endif - break; case PopupItemId::kVirtualCreditCardEntry: // There can be multiple virtual credit cards that all rely on // PopupItemId::kVirtualCreditCardEntry as a `popup_item_id`. In this
diff --git a/components/autofill/core/browser/browser_autofill_manager.cc b/components/autofill/core/browser/browser_autofill_manager.cc index 78d34a7f..a84f2ad3 100644 --- a/components/autofill/core/browser/browser_autofill_manager.cc +++ b/components/autofill/core/browser/browser_autofill_manager.cc
@@ -267,7 +267,6 @@ case PopupItemId::kGeneratePasswordEntry: case PopupItemId::kShowAccountCards: case PopupItemId::kPasswordAccountStorageOptIn: - case PopupItemId::kUseVirtualCard: case PopupItemId::kPasswordAccountStorageOptInAndGenerate: case PopupItemId::kAccountStoragePasswordEntry: case PopupItemId::kAccountStorageUsernameEntry: @@ -459,39 +458,6 @@ }); } -#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) -// Retrieves all valid credit card candidates for virtual card selection. A -// valid candidate must have exactly one cloud token. -std::vector<CreditCard*> GetVirtualCardCandidates( - PersonalDataManager* personal_data_manager) { - DCHECK(personal_data_manager); - std::vector<CreditCard*> candidates = - personal_data_manager->GetServerCreditCards(); - const std::vector<CreditCardCloudTokenData*> cloud_token_data = - personal_data_manager->GetCreditCardCloudTokenData(); - - // Constructs map. - std::unordered_map<std::string, int> id_count; - for (CreditCardCloudTokenData* data : cloud_token_data) { - const auto& iterator = id_count.find(data->masked_card_id); - if (iterator == id_count.end()) - id_count.emplace(data->masked_card_id, 1); - else - iterator->second += 1; - } - - // Remove the card from the vector that either has multiple cloud token data - // or has no cloud token data. - base::EraseIf(candidates, [&](const auto& card) { - const auto& iterator = id_count.find(card->server_id()); - return iterator == id_count.end() || iterator->second > 1; - }); - - // Returns the remaining valid cards. - return candidates; -} -#endif - const char* SubmissionSourceToString(SubmissionSource source) { switch (source) { case SubmissionSource::NONE: @@ -760,29 +726,6 @@ should_display_gpay_logo); } -#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) -void BrowserAutofillManager::FetchVirtualCardCandidates() { - const std::vector<CreditCard*>& candidates = - GetVirtualCardCandidates(client().GetPersonalDataManager()); - // Make sure the |candidates| is not empty, otherwise the check in - // ShouldShowVirtualCardOption() should fail. - DCHECK(!candidates.empty()); - - client().OfferVirtualCardOptions( - candidates, - base::BindOnce(&BrowserAutofillManager::OnVirtualCardCandidateSelected, - weak_ptr_factory_.GetWeakPtr())); -} - -void BrowserAutofillManager::OnVirtualCardCandidateSelected( - const std::string& selected_card_id) { - // TODO(crbug.com/1020740): Implement this and the following flow in a - // separate CL. The following flow will be sending a request to Payments - // to fetched the up-to-date cloud token data for the selected card and fill - // the information in the form. -} -#endif - bool BrowserAutofillManager::ShouldParseForms() { bool autofill_enabled = IsAutofillEnabled(); // If autofill is disabled but the password manager is enabled, we still @@ -3634,16 +3577,6 @@ if (suggestions->empty() || !context->is_filling_credit_card) return; -#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) - // This section adds the "Use a virtual card number" option in the autofill - // dropdown menu, if applicable. - if (ShouldShowVirtualCardOption(context->form_structure)) { - suggestions->emplace_back(l10n_util::GetStringUTF16( - IDS_AUTOFILL_CLOUD_TOKEN_DROPDOWN_OPTION_LABEL)); - suggestions->back().popup_item_id = PopupItemId::kUseVirtualCard; - } -#endif - // Don't provide credit card suggestions for non-secure pages, but do // provide them for secure pages with passive mixed content (see // implementation of IsContextSecure). @@ -3659,40 +3592,6 @@ } } -#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) -// TODO(crbug.com/1020740): Add metrics logging. -bool BrowserAutofillManager::ShouldShowVirtualCardOption( - FormStructure* form_structure) { - // If experiment is disabled, return false. - if (!base::FeatureList::IsEnabled(features::kAutofillEnableVirtualCard)) - return false; - - // If credit card upload is disabled, return false. - if (!IsAutofillCreditCardEnabled()) - return false; - - // If merchant is not allowed, return false. - std::vector<std::string> allowed_merchants = - client().GetAllowedMerchantsForVirtualCards(); - if (!base::Contains(allowed_merchants, form_structure->source_url().spec())) { - return false; - } - - // If no credit card candidate has related cloud token data available, - // return false. - if (GetVirtualCardCandidates(client().GetPersonalDataManager()).empty()) { - return false; - } - - // If not all of card number field, expiration date field and CVC field are - // detected, return false. - if (!IsCompleteCreditCardFormIncludingCvcField(*form_structure)) - return false; - - return true; -} -#endif - autofill_metrics::FormEventLoggerBase* BrowserAutofillManager::GetEventFormLogger(const AutofillField& field) const { if (field.ShouldSuppressSuggestionsAndFillingByDefault()) {
diff --git a/components/autofill/core/browser/browser_autofill_manager.h b/components/autofill/core/browser/browser_autofill_manager.h index a20e40c..920b1d2 100644 --- a/components/autofill/core/browser/browser_autofill_manager.h +++ b/components/autofill/core/browser/browser_autofill_manager.h
@@ -135,20 +135,6 @@ virtual void RefetchCardsAndUpdatePopup(const FormData& form, const FormFieldData& field_data); -#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) - // Returns the list of credit cards that have associated cloud token data. - virtual void FetchVirtualCardCandidates(); - - // Callback invoked when an actual card is selected. |selected_card_id| will - // be used to identify the card. The selected card's cloud token data will be - // fetched from the server. - // TODO(crbug.com/1020740): Passes card server id for now. In the future when - // one actual credit card can have multiple virtual cards, passes instrument - // token instead. Design TBD. - virtual void OnVirtualCardCandidateSelected( - const std::string& selected_card_id); -#endif - // Called from our external delegate so they cannot be private. // TODO(crbug.com/1330108): Clean up the API. virtual void FillOrPreviewForm( @@ -703,11 +689,6 @@ const std::vector<AutofillProfile>& profiles, FormStructure* form_structure); -#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) - // Whether to show the option to use virtual card in the autofill popup. - bool ShouldShowVirtualCardOption(FormStructure* form_structure); -#endif - // Returns an appropriate EventFormLogger, depending on the given `field`'s // type. May return nullptr. autofill_metrics::FormEventLoggerBase* GetEventFormLogger(
diff --git a/components/autofill/core/browser/browser_autofill_manager_unittest.cc b/components/autofill/core/browser/browser_autofill_manager_unittest.cc index 9a27db2..80dfedd 100644 --- a/components/autofill/core/browser/browser_autofill_manager_unittest.cc +++ b/components/autofill/core/browser/browser_autofill_manager_unittest.cc
@@ -10166,258 +10166,6 @@ Suggestion("theking@gmail.com", "", "", PopupItemId::kAddressEntry)); } -// Desktop only tests. -#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) -class BrowserAutofillManagerTestForVirtualCardOption - : public BrowserAutofillManagerTest { - protected: - BrowserAutofillManagerTestForVirtualCardOption() = default; - ~BrowserAutofillManagerTestForVirtualCardOption() override = default; - - void SetUp() override { - BrowserAutofillManagerTest::SetUp(); - - // The URL should always match the form URL in - // CreateTestCreditCardFormData() to have the allowlist work correctly. - autofill_client_.set_allowed_merchants({"https://myform.com/form.html"}); - - scoped_feature_list_.InitAndEnableFeature( - features::kAutofillEnableVirtualCard); - - // Add only one server card so the second suggestion (if any) must be the - // "Use a virtual card number" option. - personal_data().ClearCreditCards(); - CreditCard masked_server_card(CreditCard::RecordType::kMaskedServerCard, - /*server_id=*/"a123"); - // TODO(crbug.com/1020740): Replace all the hard-coded expiration year in - // this file with NextYear(). - test::SetCreditCardInfo(&masked_server_card, "Elvis Presley", - "4234567890123456", // Visa - "04", "2999", "1"); - masked_server_card.SetNetworkForMaskedCard(kVisaCard); - masked_server_card.set_guid(MakeGuid(7)); - personal_data().AddServerCreditCard(masked_server_card); - } - - FieldGlobalId CreateCompleteFormAndGetSuggestions() { - FormData form; - CreateTestCreditCardFormData(&form, /*is_https=*/true, - /*use_month_type=*/false); - FormsSeen({form}); - GetAutofillSuggestions(form, form.fields[1]); // Card number field. - return form.fields[1].global_id(); - } - - // Adds a CreditCardCloudTokenData to PersonalDataManager. This needs to be - // called before suggestions are fetched. - void CreateCloudTokenDataForDefaultCard() { - personal_data().ClearCloudTokenData(); - CreditCardCloudTokenData data1 = test::GetCreditCardCloudTokenData1(); - data1.masked_card_id = "a123"; - personal_data().AddCloudTokenData(data1); - } - - void VerifyNoVirtualCardSuggestions(FieldGlobalId field_id) { - external_delegate()->CheckSuggestionCount(field_id, 1); - // Suggestion details need to match the credit card added in the SetUp() - // above. - CheckSuggestions(field_id, Suggestion(std::string("Visa ") + - test::ObfuscatedCardDigitsAsUTF8( - "3456", ObfuscationLength()), - "Expires on 04/99", kVisaCard, - PopupItemId::kCreditCardEntry)); - } - - private: - base::test::ScopedFeatureList scoped_feature_list_; -}; - -// Ensures the "Use a virtual card number" option should not be shown when -// experiment is disabled. -TEST_F(BrowserAutofillManagerTestForVirtualCardOption, - ShouldNotShowDueToExperimentDisabled) { - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitAndDisableFeature( - features::kAutofillEnableVirtualCard); - FieldGlobalId field_id = CreateCompleteFormAndGetSuggestions(); - VerifyNoVirtualCardSuggestions(field_id); -} - -// Ensures the "Use a virtual card number" option should not be shown when the -// preference for credit card upload is set to disabled. -TEST_F(BrowserAutofillManagerTestForVirtualCardOption, - ShouldNotShowDueToCreditCardUploadPrefDisabled) { - browser_autofill_manager_->SetAutofillCreditCardEnabled(autofill_client_, - false); - FieldGlobalId field_id = CreateCompleteFormAndGetSuggestions(); - external_delegate()->CheckSuggestionCount(field_id, 0); -} - -// Ensures the "Use a virtual card number" option should not be shown when -// merchant is not allowlisted. -TEST_F(BrowserAutofillManagerTestForVirtualCardOption, - ShouldNotShowDueToMerchantNotAllowlisted) { - // Adds a different URL in the allowlist. - autofill_client_.set_allowed_merchants( - {"https://myform.anotherallowlist.com/form.html"}); - FieldGlobalId field_id = CreateCompleteFormAndGetSuggestions(); - VerifyNoVirtualCardSuggestions(field_id); -} - -// Ensures the "Use a virtual card number" option should not be shown when card -// number field is not detected. -TEST_F(BrowserAutofillManagerTestForVirtualCardOption, - ShouldNotShowDueToFormNotHavingCardNumberField) { - // Creates an incomplete form without card number field. - FormData form; - form.name = u"MyForm"; - form.url = GURL("https://myform.com/form.html"); - form.action = GURL("https://myform.com/submit.html"); - form.main_frame_origin = - url::Origin::Create(GURL("https://myform_root.com/form.html")); - form.fields = {CreateTestFormField("Name on Card", "nameoncard", "", "text"), - CreateTestFormField("Expiration Date", "ccmonth", "", "text"), - CreateTestFormField("", "ccyear", "", "text"), - CreateTestFormField("CVC", "cvc", "", "text")}; - - FormsSeen({form}); - GetAutofillSuggestions(form, form.fields[0]); // Cardholder name field. - - external_delegate()->CheckSuggestionCount(form.fields[0].global_id(), 1); - const std::string visa_label = base::JoinString( - {"Visa ", test::ObfuscatedCardDigitsAsUTF8("3456", ObfuscationLength()), - ", expires on 04/99"}, - ""); - CheckSuggestions(form.fields[0].global_id(), - Suggestion("Elvis Presley", visa_label, kVisaCard, - PopupItemId::kCreditCardEntry)); -} - -// Ensures the "Use a virtual card number" option should not be shown when there -// is no cloud token data for the card. -TEST_F(BrowserAutofillManagerTestForVirtualCardOption, - ShouldNotShowDueToNoCloudTokenData) { - FieldGlobalId field_id = CreateCompleteFormAndGetSuggestions(); - VerifyNoVirtualCardSuggestions(field_id); -} - -// Ensures the "Use a virtual card number" option should not be shown when there -// is multiple cloud token data for the card. -TEST_F(BrowserAutofillManagerTestForVirtualCardOption, - ShouldNotShowDueToMultipleCloudTokenData) { - CreateCloudTokenDataForDefaultCard(); - CreditCardCloudTokenData data2 = test::GetCreditCardCloudTokenData2(); - data2.masked_card_id = "a123"; - personal_data().AddCloudTokenData(data2); - FieldGlobalId field_id = CreateCompleteFormAndGetSuggestions(); - VerifyNoVirtualCardSuggestions(field_id); -} - -// Ensures the "Use a virtual card number" option should not be shown when card -// expiration date field is not detected. -TEST_F(BrowserAutofillManagerTestForVirtualCardOption, - ShouldNotShowDueToFormNotHavingExpirationDateField) { - // Creates an incomplete form without expiration date field. - FormData form; - form.name = u"MyForm"; - form.url = GURL("https://myform.com/form.html"); - form.action = GURL("https://myform.com/submit.html"); - form.main_frame_origin = - url::Origin::Create(GURL("https://myform_root.com/form.html")); - form.fields = {CreateTestFormField("Name on Card", "nameoncard", "", "text"), - CreateTestFormField("Card Number", "cardnumber", "", "text"), - CreateTestFormField("CVC", "cvc", "", "text")}; - - FormsSeen({form}); - GetAutofillSuggestions(form, form.fields[1]); // Card number field. - - VerifyNoVirtualCardSuggestions(form.fields[1].global_id()); -} - -// Ensures the "Use a virtual card number" option should not be shown when card -// cvc field is not detected. -TEST_F(BrowserAutofillManagerTestForVirtualCardOption, - ShouldNotShowDueToFormNotHavingCvcField) { - // Creates an incomplete form without cvc field. - FormData form; - form.name = u"MyForm"; - form.url = GURL("https://myform.com/form.html"); - form.action = GURL("https://myform.com/submit.html"); - form.main_frame_origin = - url::Origin::Create(GURL("https://myform_root.com/form.html")); - form.fields = {CreateTestFormField("Name on Card", "nameoncard", "", "text"), - CreateTestFormField("Card Number", "cardnumber", "", "text"), - CreateTestFormField("Expiration Date", "ccmonth", "", "text"), - CreateTestFormField("", "ccyear", "", "text")}; - - FormsSeen({form}); - GetAutofillSuggestions(form, form.fields[1]); // Card number field. - - VerifyNoVirtualCardSuggestions(form.fields[1].global_id()); -} - -// Ensures the "Use a virtual card number" option should be shown when all -// requirements are met. -TEST_F(BrowserAutofillManagerTestForVirtualCardOption, - ShouldShowVirtualCardOption_OneCard) { - CreateCloudTokenDataForDefaultCard(); - FieldGlobalId field_id = CreateCompleteFormAndGetSuggestions(); - - // Ensures the card suggestion and the virtual card suggestion are shown. - external_delegate()->CheckSuggestionCount(field_id, 2); - CheckSuggestions( - field_id, - Suggestion(std::string("Visa ") + test::ObfuscatedCardDigitsAsUTF8( - "3456", ObfuscationLength()), - "Expires on 04/99", kVisaCard, PopupItemId::kCreditCardEntry), - Suggestion(l10n_util::GetStringUTF8( - IDS_AUTOFILL_CLOUD_TOKEN_DROPDOWN_OPTION_LABEL), - "", "", PopupItemId::kUseVirtualCard)); -} - -// Ensures the "Use a virtual card number" option should be shown when there are -// multiple cards and at least one card meets requirements. -TEST_F(BrowserAutofillManagerTestForVirtualCardOption, - ShouldShowVirtualCardOption_MultipleCards) { - CreateCloudTokenDataForDefaultCard(); - - // Adds another card which does not meet the requirements (has two cloud - // tokens). - CreditCard masked_server_card(CreditCard::RecordType::kMaskedServerCard, - /*server_id=*/"a456"); - // TODO(crbug.com/1020740): Replace all the hard-coded expiration year in - // this file with NextYear(). - test::SetCreditCardInfo(&masked_server_card, "Elvis Presley", - "4111111111111111", // Visa - "04", "2999", "1"); - masked_server_card.SetNetworkForMaskedCard(kVisaCard); - masked_server_card.set_guid(MakeGuid(8)); - personal_data().AddServerCreditCard(masked_server_card); - CreditCardCloudTokenData data1 = test::GetCreditCardCloudTokenData1(); - data1.masked_card_id = "a456"; - personal_data().AddCloudTokenData(data1); - CreditCardCloudTokenData data2 = test::GetCreditCardCloudTokenData2(); - data2.masked_card_id = "a456"; - personal_data().AddCloudTokenData(data2); - - FieldGlobalId field_id = CreateCompleteFormAndGetSuggestions(); - - // Ensures the card suggestion and the virtual card suggestion are shown. - external_delegate()->CheckSuggestionCount(field_id, 3); - CheckSuggestions( - field_id, - Suggestion(std::string("Visa ") + test::ObfuscatedCardDigitsAsUTF8( - "1111", ObfuscationLength()), - "Expires on 04/99", kVisaCard, PopupItemId::kCreditCardEntry), - Suggestion(std::string("Visa ") + test::ObfuscatedCardDigitsAsUTF8( - "3456", ObfuscationLength()), - "Expires on 04/99", kVisaCard, PopupItemId::kCreditCardEntry), - Suggestion(l10n_util::GetStringUTF8( - IDS_AUTOFILL_CLOUD_TOKEN_DROPDOWN_OPTION_LABEL), - "", "", PopupItemId::kUseVirtualCard)); -} -#endif - // Test param indicates if there is an active screen reader. class OnFocusOnFormFieldTest : public BrowserAutofillManagerTest, public testing::WithParamInterface<bool> {
diff --git a/components/autofill/core/browser/ui/popup_item_ids.h b/components/autofill/core/browser/ui/popup_item_ids.h index 3ce4988..9bcc31e 100644 --- a/components/autofill/core/browser/ui/popup_item_ids.h +++ b/components/autofill/core/browser/ui/popup_item_ids.h
@@ -43,7 +43,6 @@ kGeneratePasswordEntry, kShowAccountCards, kPasswordAccountStorageOptIn, - kUseVirtualCard, kPasswordAccountStorageOptInAndGenerate, kAccountStoragePasswordEntry, kAccountStorageUsernameEntry,
diff --git a/components/autofill/core/common/autofill_payments_features.cc b/components/autofill/core/common/autofill_payments_features.cc index 8a4e09f..efe5cc1 100644 --- a/components/autofill/core/common/autofill_payments_features.cc +++ b/components/autofill/core/common/autofill_payments_features.cc
@@ -167,12 +167,6 @@ #endif ); -// When enabled, the option of using cloud token virtual card will be offered -// when all requirements are met. -BASE_FEATURE(kAutofillEnableVirtualCard, - "AutofillEnableVirtualCard", - base::FEATURE_DISABLED_BY_DEFAULT); - // When enabled, after a successful authentication to autofill a virtual card, // the user will be prompted to opt-in to FIDO if the user is not currently // opted-in, and if the user is opted-in already and the virtual card is FIDO
diff --git a/components/autofill/core/common/autofill_payments_features.h b/components/autofill/core/common/autofill_payments_features.h index d69e661a..90f95896 100644 --- a/components/autofill/core/common/autofill_payments_features.h +++ b/components/autofill/core/common/autofill_payments_features.h
@@ -39,7 +39,6 @@ BASE_DECLARE_FEATURE(kAutofillEnableServerIban); BASE_DECLARE_FEATURE(kAutofillEnableStickyManualFallbackForCards); BASE_DECLARE_FEATURE(kAutofillEnableUpdateVirtualCardEnrollment); -BASE_DECLARE_FEATURE(kAutofillEnableVirtualCard); BASE_DECLARE_FEATURE(kAutofillEnableVirtualCardFidoEnrollment); BASE_DECLARE_FEATURE(kAutofillEnableVirtualCardManagementInDesktopSettingsPage); BASE_DECLARE_FEATURE(kAutofillEnableVirtualCardMetadata);
diff --git a/components/autofill_payments_strings.grdp b/components/autofill_payments_strings.grdp index 823fc29..e807a85 100644 --- a/components/autofill_payments_strings.grdp +++ b/components/autofill_payments_strings.grdp
@@ -112,9 +112,12 @@ </message> </else> </if> - <message name="IDS_AUTOFILL_SAVE_CARD_PROMPT_TITLE_LOCAL" desc="Title text for the Autofill save card prompt when the card is to be saved locally. The prompt can be either a bubble or an infobar."> + <message name="IDS_AUTOFILL_SAVE_CARD_PROMPT_TITLE_LOCAL" desc="Title text for the Autofill save card prompt to save a card locally. It is shown when a new card is used during checkout, and Chrome sync is not enabled. This prompt title is shown on both the Desktop bubble and the Android infobar."> Save card? </message> + <message name="IDS_AUTOFILL_SAVE_CARD_PROMPT_EXPLANATION_LOCAL" desc="Explanation text for the Autofill save card prompt to save a card locally. It is shown when a new card is used during checkout, and Chrome sync is not enabled. This prompt title is shown on both the Desktop bubble and the Android infobar."> + To pay faster next time, save your card to your device + </message> <message name="IDS_AUTOFILL_SAVE_CVC_PROMPT_TITLE_LOCAL" desc="Title text for the Autofill save CVC prompt that offers to save CVC for existing local cards. This prompt is shown if a CVC is detected for an existing local card on form submission."> Save security code? </message> @@ -624,9 +627,6 @@ <!-- virtual cards related strings - start --> <if expr="not is_ios and not is_android"> - <message name="IDS_AUTOFILL_CLOUD_TOKEN_DROPDOWN_OPTION_LABEL" desc="Text shown in the button in the Autofill dropdown menu when a credit card form field is queried, to offer the option to use a virtual card."> - Use a virtual card number... - </message> <message name="IDS_AUTOFILL_VIRTUAL_CARD_ENROLLMENT_FALLBACK_ICON_TOOLTIP" desc="The tooltip message for the omnibox icon for the virtual card enroll bubble on Desktop. This bubble prompts users if they would like to enroll in a virtual card."> Add virtual card </message>
diff --git a/components/autofill_payments_strings_grdp/IDS_AUTOFILL_SAVE_CARD_PROMPT_EXPLANATION_LOCAL.png.sha1 b/components/autofill_payments_strings_grdp/IDS_AUTOFILL_SAVE_CARD_PROMPT_EXPLANATION_LOCAL.png.sha1 new file mode 100644 index 0000000..69f92cb --- /dev/null +++ b/components/autofill_payments_strings_grdp/IDS_AUTOFILL_SAVE_CARD_PROMPT_EXPLANATION_LOCAL.png.sha1
@@ -0,0 +1 @@ +095cf3325bcf917ac1bd516fe23fc50579295b46 \ No newline at end of file
diff --git a/components/feature_engagement/public/feature_configurations.cc b/components/feature_engagement/public/feature_configurations.cc index 3d48652b..1b587b9 100644 --- a/components/feature_engagement/public/feature_configurations.cc +++ b/components/feature_engagement/public/feature_configurations.cc
@@ -376,13 +376,12 @@ config->availability = Comparator(ANY, 0); config->session_rate = Comparator(ANY, 0); config->session_rate_impact.type = SessionRateImpact::Type::NONE; - // Used to increase the usage of Customize Chrome for users who have opened - // it 0 times in the last 360 days. + // Show IPH regardless of customize_chrome usage config->used = - EventConfig("customize_chrome_opened", Comparator(EQUAL, 0), 360, 360); - // Triggered when IPH hasn't been shown in the past day. - config->trigger = EventConfig("iph_customize_chrome_triggered", - Comparator(EQUAL, 0), 1, 360); + EventConfig("customize_chrome_opened", Comparator(ANY, 0), 360, 360); + // Triggered when IPH has been shown less than twice this year. + config->trigger = EventConfig("iph_customize_chrome_refresh_triggered", + Comparator(LESS_THAN, 2), 360, 360); config->snooze_params.max_limit = 4; return config; }
diff --git a/components/feed/core/v2/api_test/feed_api_test.cc b/components/feed/core/v2/api_test/feed_api_test.cc index 440c012..b33e7588 100644 --- a/components/feed/core/v2/api_test/feed_api_test.cc +++ b/components/feed/core/v2/api_test/feed_api_test.cc
@@ -1013,7 +1013,7 @@ chrome_info.start_surface = start_surface; stream_ = std::make_unique<FeedStream>( &refresh_scheduler_, metrics_reporter_.get(), this, &profile_prefs_, - &network_, image_fetcher_.get(), store_.get(), + &network_, image_fetcher_.get(), nullptr, store_.get(), persistent_key_value_store_.get(), template_url_service_.get(), chrome_info); stream_->SetWireResponseTranslatorForTesting(&response_translator_);
diff --git a/components/feed/core/v2/feed_stream.cc b/components/feed/core/v2/feed_stream.cc index e55f1f4..05bc4e3 100644 --- a/components/feed/core/v2/feed_stream.cc +++ b/components/feed/core/v2/feed_stream.cc
@@ -50,6 +50,7 @@ #include "components/feed/core/v2/public/stream_type.h" #include "components/feed/core/v2/public/types.h" #include "components/feed/core/v2/public/unread_content_observer.h" +#include "components/feed/core/v2/resource_fetcher.h" #include "components/feed/core/v2/scheduling.h" #include "components/feed/core/v2/stream/unread_content_notifier.h" #include "components/feed/core/v2/stream_model.h" @@ -139,6 +140,7 @@ PrefService* profile_prefs, FeedNetwork* feed_network, ImageFetcher* image_fetcher, + ResourceFetcher* resource_fetcher, FeedStore* feed_store, PersistentKeyValueStoreImpl* persistent_key_value_store, TemplateURLService* template_url_service, @@ -149,6 +151,7 @@ profile_prefs_(profile_prefs), feed_network_(feed_network), image_fetcher_(image_fetcher), + resource_fetcher_(resource_fetcher), store_(feed_store), persistent_key_value_store_(persistent_key_value_store), template_url_service_(template_url_service), @@ -721,6 +724,19 @@ stream.content_ids); } +void FeedStream::FetchResource( + const GURL& url, + const std::string& method, + const std::vector<std::string>& header_name_and_values, + const std::string& post_data, + base::OnceCallback<void(NetworkResponse)> callback) { + if (!resource_fetcher_) { + return; + } + resource_fetcher_->Fetch(url, method, header_name_and_values, post_data, + std::move(callback)); +} + void FeedStream::ExecuteOperations( SurfaceId surface_id, std::vector<feedstore::DataOperation> operations) {
diff --git a/components/feed/core/v2/feed_stream.h b/components/feed/core/v2/feed_stream.h index a5ccb3a..7623367 100644 --- a/components/feed/core/v2/feed_stream.h +++ b/components/feed/core/v2/feed_stream.h
@@ -63,6 +63,7 @@ class MetricsReporter; class RefreshTaskScheduler; class PersistentKeyValueStoreImpl; +class ResourceFetcher; class StreamModel; class SurfaceUpdater; @@ -101,6 +102,7 @@ PrefService* profile_prefs, FeedNetwork* feed_network, ImageFetcher* image_fetcher, + ResourceFetcher* resource_fetcher, FeedStore* feed_store, PersistentKeyValueStoreImpl* persistent_key_value_store, TemplateURLService* template_url_service, @@ -138,6 +140,12 @@ base::OnceCallback<void(bool)> callback) override; void ManualRefresh(SurfaceId surface_id, base::OnceCallback<void(bool)> callback) override; + void FetchResource( + const GURL& url, + const std::string& method, + const std::vector<std::string>& header_name_and_values, + const std::string& post_data, + base::OnceCallback<void(NetworkResponse)> callback) override; void ExecuteOperations( SurfaceId surface_id, std::vector<feedstore::DataOperation> operations) override; @@ -459,6 +467,7 @@ raw_ptr<PrefService> profile_prefs_; // May be null. raw_ptr<FeedNetwork> feed_network_; raw_ptr<ImageFetcher> image_fetcher_; + raw_ptr<ResourceFetcher> resource_fetcher_; raw_ptr<FeedStore, DanglingUntriaged> store_; raw_ptr<PersistentKeyValueStoreImpl, DanglingUntriaged> persistent_key_value_store_;
diff --git a/components/feed/core/v2/public/feed_api.h b/components/feed/core/v2/public/feed_api.h index d9b038e1..c86799a 100644 --- a/components/feed/core/v2/public/feed_api.h +++ b/components/feed/core/v2/public/feed_api.h
@@ -108,6 +108,15 @@ virtual void ManualRefresh(SurfaceId surface_id, base::OnceCallback<void(bool)> callback) = 0; + // Request to fetch a URL resource. Calls |callback| with the network response + // when complete. + virtual void FetchResource( + const GURL& url, + const std::string& method, + const std::vector<std::string>& header_name_and_values, + const std::string& post_data, + base::OnceCallback<void(NetworkResponse)> callback) = 0; + // Request to fetch and image for use in the feed. Calls |callback| // with the network response when complete. The returned ImageFetchId can be // passed to CancelImageFetch() to cancel the request.
diff --git a/components/feed/core/v2/public/feed_service.cc b/components/feed/core/v2/public/feed_service.cc index 530dde3..7f2f6e1 100644 --- a/components/feed/core/v2/public/feed_service.cc +++ b/components/feed/core/v2/public/feed_service.cc
@@ -25,6 +25,7 @@ #include "components/feed/core/v2/persistent_key_value_store_impl.h" #include "components/feed/core/v2/prefs.h" #include "components/feed/core/v2/public/refresh_task_scheduler.h" +#include "components/feed/core/v2/resource_fetcher.h" #include "components/feed/feed_feature_list.h" #include "components/history/core/browser/history_service.h" #include "components/history/core/browser/history_service_observer.h" @@ -257,6 +258,7 @@ network_delegate_.get(), identity_manager, api_key, url_loader_factory, profile_prefs); image_fetcher_ = std::make_unique<ImageFetcher>(url_loader_factory); + resource_fetcher_ = std::make_unique<ResourceFetcher>(url_loader_factory); store_ = std::make_unique<FeedStore>(std::move(database)); persistent_key_value_store_ = std::make_unique<PersistentKeyValueStoreImpl>( std::move(key_value_store_database)); @@ -264,8 +266,8 @@ stream_ = std::make_unique<FeedStream>( refresh_task_scheduler_.get(), metrics_reporter_.get(), stream_delegate_.get(), profile_prefs, feed_network_.get(), - image_fetcher_.get(), store_.get(), persistent_key_value_store_.get(), - template_url_service, chrome_info); + image_fetcher_.get(), resource_fetcher_.get(), store_.get(), + persistent_key_value_store_.get(), template_url_service, chrome_info); api_ = stream_.get(); history_observer_ = std::make_unique<HistoryObserverImpl>(
diff --git a/components/feed/core/v2/public/feed_service.h b/components/feed/core/v2/public/feed_service.h index 15c006a7..ff0ed7d 100644 --- a/components/feed/core/v2/public/feed_service.h +++ b/components/feed/core/v2/public/feed_service.h
@@ -52,6 +52,7 @@ class FeedStream; class PersistentKeyValueStoreImpl; class ImageFetcher; +class ResourceFetcher; namespace internal { bool ShouldClearFeed(bool is_signed_in, @@ -151,6 +152,7 @@ std::unique_ptr<NetworkDelegateImpl> network_delegate_; std::unique_ptr<FeedNetwork> feed_network_; std::unique_ptr<ImageFetcher> image_fetcher_; + std::unique_ptr<ResourceFetcher> resource_fetcher_; std::unique_ptr<FeedStore> store_; std::unique_ptr<PersistentKeyValueStoreImpl> persistent_key_value_store_; std::unique_ptr<RefreshTaskScheduler> refresh_task_scheduler_;
diff --git a/components/feed/core/v2/public/test/stub_feed_api.h b/components/feed/core/v2/public/test/stub_feed_api.h index ae76161..79870cb4 100644 --- a/components/feed/core/v2/public/test/stub_feed_api.h +++ b/components/feed/core/v2/public/test/stub_feed_api.h
@@ -51,6 +51,12 @@ base::OnceCallback<void(bool)> callback) override {} void ManualRefresh(SurfaceId surface_id, base::OnceCallback<void(bool)> callback) override {} + void FetchResource( + const GURL& url, + const std::string& method, + const std::vector<std::string>& header_name_and_values, + const std::string& post_data, + base::OnceCallback<void(NetworkResponse)> callback) override {} ImageFetchId FetchImage( const GURL& url, base::OnceCallback<void(NetworkResponse)> callback) override;
diff --git a/components/media_router/browser/presentation/local_presentation_manager.h b/components/media_router/browser/presentation/local_presentation_manager.h index d52f8a7..c3c362ec 100644 --- a/components/media_router/browser/presentation/local_presentation_manager.h +++ b/components/media_router/browser/presentation/local_presentation_manager.h
@@ -110,6 +110,9 @@ // thread. class LocalPresentationManager : public KeyedService { public: + // Used by + // LocalPresentationManagerFactory::BuildServiceInstanceForBrowserContext. + LocalPresentationManager(); LocalPresentationManager(const LocalPresentationManager&) = delete; LocalPresentationManager& operator=(const LocalPresentationManager&) = delete; @@ -251,15 +254,11 @@ }; private: - friend class LocalPresentationManagerFactory; friend class LocalPresentationManagerTest; friend class MockLocalPresentationManager; FRIEND_TEST_ALL_PREFIXES(PresentationServiceDelegateImplTest, ConnectToLocalPresentation); - // Used by LocalPresentationManagerFactory::GetOrCreateForBrowserContext. - LocalPresentationManager(); - using LocalPresentationMap = std::map<std::string, std::unique_ptr<LocalPresentation>>;
diff --git a/components/media_router/browser/presentation/local_presentation_manager_factory.cc b/components/media_router/browser/presentation/local_presentation_manager_factory.cc index e891605..1f34594 100644 --- a/components/media_router/browser/presentation/local_presentation_manager_factory.cc +++ b/components/media_router/browser/presentation/local_presentation_manager_factory.cc
@@ -46,9 +46,10 @@ g_instance = nullptr; } -KeyedService* LocalPresentationManagerFactory::BuildServiceInstanceFor( +std::unique_ptr<KeyedService> +LocalPresentationManagerFactory::BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const { - return new LocalPresentationManager; + return std::make_unique<LocalPresentationManager>(); } } // namespace media_router
diff --git a/components/media_router/browser/presentation/local_presentation_manager_factory.h b/components/media_router/browser/presentation/local_presentation_manager_factory.h index c52320e..13fd0e0 100644 --- a/components/media_router/browser/presentation/local_presentation_manager_factory.h +++ b/components/media_router/browser/presentation/local_presentation_manager_factory.h
@@ -39,7 +39,7 @@ ~LocalPresentationManagerFactory() override; // BrowserContextKeyedServiceFactory interface. - KeyedService* BuildServiceInstanceFor( + std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const override; };
diff --git a/components/pdf/renderer/pdf_accessibility_tree.h b/components/pdf/renderer/pdf_accessibility_tree.h index 52f2f723..aa36140e 100644 --- a/components/pdf/renderer/pdf_accessibility_tree.h +++ b/components/pdf/renderer/pdf_accessibility_tree.h
@@ -130,9 +130,7 @@ } private: - // TODO(crbug.com/1443341): Increase initial value after batching issue is - // fixed. - uint32_t pages_per_batch_ = 1u; + uint32_t pages_per_batch_ = 20u; void OcrNextImage(); void ReceiveOcrResultsForImage(PdfOcrRequest request,
diff --git a/components/pdf/renderer/pdf_accessibility_tree_browsertest.cc b/components/pdf/renderer/pdf_accessibility_tree_browsertest.cc index d2ea6507..2f3ed0e3 100644 --- a/components/pdf/renderer/pdf_accessibility_tree_browsertest.cc +++ b/components/pdf/renderer/pdf_accessibility_tree_browsertest.cc
@@ -151,6 +151,10 @@ return child_tree_update; } + +uint32_t CalculateBatchCount(uint32_t page_count, uint32_t batch_size) { + return (page_count + batch_size - 1) / batch_size; +} #endif // BUILDFLAG(ENABLE_SCREEN_AI_SERVICE) // This class overrides PdfAccessibilityActionHandler to record received @@ -2304,8 +2308,7 @@ ASSERT_NO_FATAL_FAILURE(CreateInaccessiblePdfAndOcrService( page_count, is_ocr_service_started_before_pdf_loads, kPagesPerBatch, /*create_empty_results=*/false)); - const uint32_t kBatchCount = (page_count / kPagesPerBatch) + - ((page_count % kPagesPerBatch == 0u) ? 0u : 1u); + const uint32_t kBatchCount = CalculateBatchCount(page_count, kPagesPerBatch); ui::AXNode* root_node = pdf_accessibility_tree_->GetRoot(); // The first node of the root node's children is a status node. There @@ -2406,7 +2409,7 @@ TEST_P(PdfOcrServiceTest, UMAMetrics) { CreatePdfAccessibilityTree(); - constexpr uint32_t kPagesPerBatch = 1u; + constexpr uint32_t kPagesPerBatch = 20u; base::HistogramTester histograms; bool is_ocr_service_started_before_pdf_loads; uint32_t page_count; @@ -2443,11 +2446,9 @@ WaitForThreadTasks(); } - ASSERT_EQ(pdf_accessibility_tree_->GetTreeUpdates().size(), page_count); - for (uint32_t i = 0; i < page_count; ++i) { - // There are two mock images per page. - ASSERT_EQ(pdf_accessibility_tree_->GetTreeUpdates()[i].size(), 2u); - } + const auto& tree_updates = pdf_accessibility_tree_->GetTreeUpdates(); + const uint32_t kBatchCount = CalculateBatchCount(page_count, kPagesPerBatch); + ASSERT_EQ(kBatchCount, tree_updates.size()); histograms.ExpectBucketCount( "Accessibility.PdfOcr.ActiveWhenInaccessiblePdfOpened",
diff --git a/components/segmentation_platform/components_unittests.filter b/components/segmentation_platform/components_unittests.filter index fba20d9..6c748df 100644 --- a/components/segmentation_platform/components_unittests.filter +++ b/components/segmentation_platform/components_unittests.filter
@@ -6,7 +6,6 @@ CrossDeviceUserModelTest.* CustomInputProcessorTest.* DatabaseMaintenanceImplTest.* -DefaultModelManagerTest.* DeviceSwitcherModelTest.* DeviceSwitcherResultDispatcherTest.* DeviceTierSegmentTest.*
diff --git a/components/segmentation_platform/internal/BUILD.gn b/components/segmentation_platform/internal/BUILD.gn index 6170c69e..ea427bc7 100644 --- a/components/segmentation_platform/internal/BUILD.gn +++ b/components/segmentation_platform/internal/BUILD.gn
@@ -71,8 +71,6 @@ "dummy_segmentation_platform_service.h", "dummy_ukm_data_manager.cc", "dummy_ukm_data_manager.h", - "execution/default_model_manager.cc", - "execution/default_model_manager.h", "execution/execution_request.cc", "execution/execution_request.h", "execution/model_execution_status.h", @@ -267,7 +265,6 @@ "database/ukm_metrics_table_unittest.cc", "database/ukm_url_table_unittest.cc", "dummy_segmentation_platform_service_unittest.cc", - "execution/default_model_manager_unittest.cc", "execution/model_executor_impl_unittest.cc", "execution/model_manager_impl_unittest.cc", "execution/processing/custom_input_processor_unittest.cc",
diff --git a/components/segmentation_platform/internal/data_collection/training_data_collector_impl_unittest.cc b/components/segmentation_platform/internal/data_collection/training_data_collector_impl_unittest.cc index f72d26f..49fa06ac 100644 --- a/components/segmentation_platform/internal/data_collection/training_data_collector_impl_unittest.cc +++ b/components/segmentation_platform/internal/data_collection/training_data_collector_impl_unittest.cc
@@ -177,8 +177,6 @@ storage_service_ = std::make_unique<StorageService>( std::move(test_segment_info_db), nullptr, std::move(signal_storage_config), - std::make_unique<DefaultModelManager>(nullptr, - base::flat_set<SegmentId>()), std::make_unique<MockModelManager>(), std::make_unique<ConfigHolder>(std::move(configs_)), &ukm_data_manager_);
diff --git a/components/segmentation_platform/internal/database/segment_info_cache.cc b/components/segmentation_platform/internal/database/segment_info_cache.cc index 3794959..203e31323 100644 --- a/components/segmentation_platform/internal/database/segment_info_cache.cc +++ b/components/segmentation_platform/internal/database/segment_info_cache.cc
@@ -64,8 +64,12 @@ segment_info_cache_[std::make_pair(segment_id, model_source)] = std::move(segment_info.value()); } else { - segment_info_cache_.erase( - segment_info_cache_.find(std::make_pair(segment_id, model_source))); + auto iter = + segment_info_cache_.find(std::make_pair(segment_id, model_source)); + if (iter == segment_info_cache_.end()) { + return; + } + segment_info_cache_.erase(iter); } }
diff --git a/components/segmentation_platform/internal/database/segment_info_cache_unittest.cc b/components/segmentation_platform/internal/database/segment_info_cache_unittest.cc index 0b207d8..da25455 100644 --- a/components/segmentation_platform/internal/database/segment_info_cache_unittest.cc +++ b/components/segmentation_platform/internal/database/segment_info_cache_unittest.cc
@@ -281,6 +281,9 @@ EXPECT_TRUE(segment_info_.has_value()); EXPECT_EQ(kSegmentId, segment_info_.value().segment_id()); EXPECT_EQ(2, segment_info_.value().model_version()); + // Deleting a non existing entry. + segment_info_cache_->UpdateSegmentInfo(kSegmentId3, kServerModelSource, + absl::nullopt); } TEST_F(SegmentInfoCacheTest, GetSegmentInfoForBothModelsWithEmptyDatabase) {
diff --git a/components/segmentation_platform/internal/database/storage_service.cc b/components/segmentation_platform/internal/database/storage_service.cc index 4cd2d8a..3ef0438 100644 --- a/components/segmentation_platform/internal/database/storage_service.cc +++ b/components/segmentation_platform/internal/database/storage_service.cc
@@ -83,15 +83,11 @@ signal_storage_config_(std::make_unique<SignalStorageConfig>( std::move(signal_storage_config_db), clock)), - default_model_manager_(std::make_unique<DefaultModelManager>( - model_provider_factory, - config_holder_->all_segment_ids())), model_manager_( std::make_unique<ModelManagerImpl>(config_holder_->all_segment_ids(), model_provider_factory, clock, segment_info_database_.get(), - default_model_manager_.get(), model_updated_callback)), ukm_data_manager_(ukm_data_manager), database_maintenance_(std::make_unique<DatabaseMaintenanceImpl>( @@ -108,7 +104,6 @@ std::unique_ptr<SegmentInfoDatabase> segment_info_database, std::unique_ptr<SignalDatabase> signal_database, std::unique_ptr<SignalStorageConfig> signal_storage_config, - std::unique_ptr<DefaultModelManager> default_model_manager, std::unique_ptr<ModelManager> model_manager, std::unique_ptr<ConfigHolder> config_holder, UkmDataManager* ukm_data_manager) @@ -116,7 +111,6 @@ segment_info_database_(std::move(segment_info_database)), signal_database_(std::move(signal_database)), signal_storage_config_(std::move(signal_storage_config)), - default_model_manager_(std::move(default_model_manager)), model_manager_(std::move(model_manager)), ukm_data_manager_(ukm_data_manager) {}
diff --git a/components/segmentation_platform/internal/database/storage_service.h b/components/segmentation_platform/internal/database/storage_service.h index 69f125a..022ef5bb 100644 --- a/components/segmentation_platform/internal/database/storage_service.h +++ b/components/segmentation_platform/internal/database/storage_service.h
@@ -41,7 +41,6 @@ } // namespace proto class DatabaseMaintenanceImpl; -class DefaultModelManager; class ModelManager; class ModelProviderFactory; class SegmentInfoDatabase; @@ -98,7 +97,6 @@ StorageService(std::unique_ptr<SegmentInfoDatabase> segment_info_database, std::unique_ptr<SignalDatabase> signal_database, std::unique_ptr<SignalStorageConfig> signal_storage_config, - std::unique_ptr<DefaultModelManager> default_model_manager, std::unique_ptr<ModelManager> model_manager, std::unique_ptr<ConfigHolder> config_holder, UkmDataManager* ukm_data_manager); @@ -130,11 +128,6 @@ return cached_result_writer_.get(); } - DefaultModelManager* default_model_manager() { - DCHECK(default_model_manager_); - return default_model_manager_.get(); - } - ModelManager* model_manager() { DCHECK(model_manager_); return model_manager_.get(); @@ -182,8 +175,6 @@ std::unique_ptr<SignalDatabase> signal_database_; std::unique_ptr<SignalStorageConfig> signal_storage_config_; - // Default models. - std::unique_ptr<DefaultModelManager> default_model_manager_; // Provides provider for default and server models. std::unique_ptr<ModelManager> model_manager_;
diff --git a/components/segmentation_platform/internal/execution/default_model_manager.cc b/components/segmentation_platform/internal/execution/default_model_manager.cc deleted file mode 100644 index 89a5c3a..0000000 --- a/components/segmentation_platform/internal/execution/default_model_manager.cc +++ /dev/null
@@ -1,62 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/segmentation_platform/internal/execution/default_model_manager.h" - -#include "base/task/single_thread_task_runner.h" -#include "components/segmentation_platform/internal/database/segment_info_database.h" - -namespace segmentation_platform { - -DefaultModelManager::SegmentInfoWrapper::SegmentInfoWrapper() = default; -DefaultModelManager::SegmentInfoWrapper::~SegmentInfoWrapper() = default; - -DefaultModelManager::DefaultModelManager( - ModelProviderFactory* model_provider_factory, - const base::flat_set<SegmentId>& segment_ids) - : model_provider_factory_(model_provider_factory) { - for (SegmentId segment_id : segment_ids) { - std::unique_ptr<DefaultModelProvider> provider = - model_provider_factory->CreateDefaultProvider(segment_id); - if (!provider) - continue; - default_model_providers_.emplace(segment_id, std::move(provider)); - } -} - -DefaultModelManager::~DefaultModelManager() = default; - -DefaultModelProvider* DefaultModelManager::GetDefaultProvider( - SegmentId segment_id) { - auto it = default_model_providers_.find(segment_id); - if (it != default_model_providers_.end()) - return it->second.get(); - return nullptr; -} - -void DefaultModelManager::GetAllSegmentInfoFromBothModels( - const base::flat_set<SegmentId>& segment_ids, - SegmentInfoDatabase* segment_database, - MultipleSegmentInfoCallback callback) { - std::unique_ptr<SegmentInfoDatabase::SegmentInfoList> available_segments = - segment_database->GetSegmentInfoForBothModels(segment_ids); - - SegmentInfoList results; - for (auto it : *available_segments) { - results.push_back(std::make_unique<SegmentInfoWrapper>()); - results.back()->segment_source = - it.second.model_source() == proto::ModelSource::DEFAULT_MODEL_SOURCE - ? SegmentSource::DEFAULT_MODEL - : SegmentSource::DATABASE; - results.back()->segment_info.Swap(&it.second); - } - std::move(callback).Run(std::move(results)); -} - -void DefaultModelManager::SetDefaultProvidersForTesting( - std::map<SegmentId, std::unique_ptr<DefaultModelProvider>>&& providers) { - default_model_providers_ = std::move(providers); -} - -} // namespace segmentation_platform
diff --git a/components/segmentation_platform/internal/execution/default_model_manager.h b/components/segmentation_platform/internal/execution/default_model_manager.h deleted file mode 100644 index 380b5c7..0000000 --- a/components/segmentation_platform/internal/execution/default_model_manager.h +++ /dev/null
@@ -1,83 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_SEGMENTATION_PLATFORM_INTERNAL_EXECUTION_DEFAULT_MODEL_MANAGER_H_ -#define COMPONENTS_SEGMENTATION_PLATFORM_INTERNAL_EXECUTION_DEFAULT_MODEL_MANAGER_H_ - -#include <deque> -#include <map> -#include <memory> -#include <set> -#include <vector> - -#include "base/functional/callback.h" -#include "base/logging.h" -#include "components/segmentation_platform/internal/database/segment_info_database.h" -#include "components/segmentation_platform/internal/proto/model_prediction.pb.h" -#include "components/segmentation_platform/public/model_provider.h" -#include "components/segmentation_platform/public/proto/model_metadata.pb.h" - -namespace segmentation_platform { -using proto::SegmentId; - -class SegmentInfoDatabase; - -// DefaultModelManager provides support to query all default models available. -// It also provides useful methods to combine results from both the database and -// the default model. -class DefaultModelManager { - public: - DefaultModelManager(ModelProviderFactory* model_provider_factory, - const base::flat_set<SegmentId>& segment_ids); - virtual ~DefaultModelManager(); - - // Disallow copy/assign. - DefaultModelManager(const DefaultModelManager&) = delete; - DefaultModelManager& operator=(const DefaultModelManager&) = delete; - - // Callback for returning a list of segment infos associated with IDs. - // The same segment ID can be repeated multiple times. - enum class SegmentSource { - DATABASE, - DEFAULT_MODEL, - }; - struct SegmentInfoWrapper { - SegmentInfoWrapper(); - ~SegmentInfoWrapper(); - SegmentInfoWrapper(const SegmentInfoWrapper&) = delete; - SegmentInfoWrapper& operator=(const SegmentInfoWrapper&) = delete; - - SegmentSource segment_source; - proto::SegmentInfo segment_info; - }; - using SegmentInfoList = std::vector<std::unique_ptr<SegmentInfoWrapper>>; - using MultipleSegmentInfoCallback = base::OnceCallback<void(SegmentInfoList)>; - - // Utility function to get the segment info from both the database and the - // default model for a given set of segment IDs. The result can contain - // the same segment ID multiple times. - virtual void GetAllSegmentInfoFromBothModels( - const base::flat_set<SegmentId>& segment_ids, - SegmentInfoDatabase* segment_database, - MultipleSegmentInfoCallback callback); - - // Returns the default provider or `nulllptr` when unavailable. - DefaultModelProvider* GetDefaultProvider(SegmentId segment_id); - - void SetDefaultProvidersForTesting( - std::map<SegmentId, std::unique_ptr<DefaultModelProvider>>&& providers); - - private: - // Default model providers. - std::map<SegmentId, std::unique_ptr<DefaultModelProvider>> - default_model_providers_; - const raw_ptr<ModelProviderFactory, DanglingUntriaged> - model_provider_factory_; - - base::WeakPtrFactory<DefaultModelManager> weak_ptr_factory_{this}; -}; - -} // namespace segmentation_platform - -#endif // COMPONENTS_SEGMENTATION_PLATFORM_INTERNAL_EXECUTION_DEFAULT_MODEL_MANAGER_H_
diff --git a/components/segmentation_platform/internal/execution/default_model_manager_unittest.cc b/components/segmentation_platform/internal/execution/default_model_manager_unittest.cc deleted file mode 100644 index e6c21358..0000000 --- a/components/segmentation_platform/internal/execution/default_model_manager_unittest.cc +++ /dev/null
@@ -1,154 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/segmentation_platform/internal/execution/default_model_manager.h" - -#include <memory> -#include <vector> - -#include "base/memory/weak_ptr.h" -#include "base/test/gmock_callback_support.h" -#include "base/test/task_environment.h" -#include "components/segmentation_platform/internal/database/test_segment_info_database.h" -#include "components/segmentation_platform/internal/execution/mock_model_provider.h" -#include "components/segmentation_platform/public/model_provider.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "third_party/abseil-cpp/absl/types/optional.h" - -using base::test::RunOnceCallback; -using testing::_; - -namespace segmentation_platform { - -using proto::SegmentId; - -class DefaultModelManagerTest : public testing::Test { - public: - DefaultModelManagerTest() : model_provider_factory_(&model_provider_data_) {} - ~DefaultModelManagerTest() override = default; - - MockDefaultModelProvider& FindHandler(proto::SegmentId segment_id) { - return *(*model_provider_data_.default_model_providers.find(segment_id)) - .second; - } - - void OnGetAllSegments(DefaultModelManager::SegmentInfoList entries) { - get_all_segment_result_.swap(entries); - } - - const DefaultModelManager::SegmentInfoList& get_all_segment_result() const { - return get_all_segment_result_; - } - - base::test::TaskEnvironment task_environment_; - test::TestSegmentInfoDatabase segment_database_; - TestModelProviderFactory::Data model_provider_data_; - TestModelProviderFactory model_provider_factory_; - std::unique_ptr<DefaultModelManager> default_model_manager_; - DefaultModelManager::SegmentInfoList get_all_segment_result_; - base::WeakPtrFactory<DefaultModelManagerTest> weak_ptr_factory_{this}; -}; - -TEST_F(DefaultModelManagerTest, BasicTest) { - const auto segment_1 = SegmentId::OPTIMIZATION_TARGET_SEGMENTATION_NEW_TAB; - const auto segment_2 = SegmentId::OPTIMIZATION_TARGET_SEGMENTATION_SHARE; - const auto segment_3 = SegmentId::OPTIMIZATION_TARGET_SEGMENTATION_VOICE; - const auto segment_4 = - SegmentId::OPTIMIZATION_TARGET_SEGMENTATION_QUERY_TILES; - - // Set some model versions. - const int model_version_db = 4; - // This version is set by - // MockDefaultModelProvider::MockDefaultModelProvider(). - const int model_version_default = 1; - - // Initialize DB and default models with 1 and 2 segments respectively. - model_provider_data_.segments_supporting_default_model = {segment_1, - segment_2}; - default_model_manager_ = std::make_unique<DefaultModelManager>( - &model_provider_factory_, - model_provider_data_.segments_supporting_default_model); - - // Set up models 1 and 3 in DB (Server models). - proto::SegmentInfo* segment_1_from_db = - segment_database_.FindOrCreateSegment(segment_1); - segment_1_from_db->set_model_version(model_version_db); - proto::SegmentInfo* segment_3_from_db = - segment_database_.FindOrCreateSegment(segment_3); - segment_3_from_db->set_model_version(model_version_db); - - // Set up default models 1 and 2. - proto::SegmentationModelMetadata metadata_1; - proto::SegmentationModelMetadata metadata_2; - model_provider_data_.default_provider_metadata[segment_1] = metadata_1; - model_provider_data_.default_provider_metadata[segment_2] = metadata_2; - proto::SegmentInfo* segment_1_default_from_db = - segment_database_.FindOrCreateSegment( - segment_1, proto::ModelSource::DEFAULT_MODEL_SOURCE); - segment_1_default_from_db->set_model_version(model_version_default); - proto::SegmentInfo* segment_2_from_db = segment_database_.FindOrCreateSegment( - segment_2, proto::ModelSource::DEFAULT_MODEL_SOURCE); - segment_2_from_db->set_model_version(model_version_default); - - // Query models. - default_model_manager_->GetAllSegmentInfoFromBothModels( - {segment_1, segment_2}, &segment_database_, - base::BindOnce(&DefaultModelManagerTest::OnGetAllSegments, - weak_ptr_factory_.GetWeakPtr())); - task_environment_.RunUntilIdle(); - - // Verify that model exists from both sources in order: segment_1 from db both - // for server and default, segment_2 from db for default. - EXPECT_EQ(3u, get_all_segment_result().size()); - EXPECT_EQ(segment_1, get_all_segment_result()[0]->segment_info.segment_id()); - EXPECT_EQ(model_version_db, - get_all_segment_result()[0]->segment_info.model_version()); - EXPECT_EQ(proto::ModelSource::SERVER_MODEL_SOURCE, - get_all_segment_result()[0]->segment_info.model_source()); - EXPECT_EQ(segment_1, get_all_segment_result()[1]->segment_info.segment_id()); - EXPECT_EQ(model_version_default, - get_all_segment_result()[1]->segment_info.model_version()); - EXPECT_EQ(proto::ModelSource::DEFAULT_MODEL_SOURCE, - get_all_segment_result()[1]->segment_info.model_source()); - EXPECT_EQ(segment_2, get_all_segment_result()[2]->segment_info.segment_id()); - EXPECT_EQ(model_version_default, - get_all_segment_result()[2]->segment_info.model_version()); - EXPECT_EQ(proto::ModelSource::DEFAULT_MODEL_SOURCE, - get_all_segment_result()[2]->segment_info.model_source()); - - // Query again, this time with a segment ID that doesn't exist in either - // sources. - default_model_manager_->GetAllSegmentInfoFromBothModels( - {segment_4}, &segment_database_, - base::BindOnce(&DefaultModelManagerTest::OnGetAllSegments, - weak_ptr_factory_.GetWeakPtr())); - task_environment_.RunUntilIdle(); - EXPECT_EQ(0u, get_all_segment_result().size()); - - // Query for a model only available in the default model. - model_provider_data_.default_provider_metadata[segment_2] = metadata_2; - default_model_manager_->GetAllSegmentInfoFromBothModels( - {segment_2}, &segment_database_, - base::BindOnce(&DefaultModelManagerTest::OnGetAllSegments, - weak_ptr_factory_.GetWeakPtr())); - task_environment_.RunUntilIdle(); - EXPECT_EQ(1u, get_all_segment_result().size()); - EXPECT_EQ(segment_2, get_all_segment_result()[0]->segment_info.segment_id()); - EXPECT_EQ(proto::ModelSource::DEFAULT_MODEL_SOURCE, - get_all_segment_result()[0]->segment_info.model_source()); - - // Query for a model only available in the database. - default_model_manager_->GetAllSegmentInfoFromBothModels( - {segment_3}, &segment_database_, - base::BindOnce(&DefaultModelManagerTest::OnGetAllSegments, - weak_ptr_factory_.GetWeakPtr())); - task_environment_.RunUntilIdle(); - EXPECT_EQ(1u, get_all_segment_result().size()); - EXPECT_EQ(segment_3, get_all_segment_result()[0]->segment_info.segment_id()); - EXPECT_EQ(proto::ModelSource::SERVER_MODEL_SOURCE, - get_all_segment_result()[0]->segment_info.model_source()); -} - -} // namespace segmentation_platform
diff --git a/components/segmentation_platform/internal/execution/model_manager_impl.cc b/components/segmentation_platform/internal/execution/model_manager_impl.cc index e144eef8..991c520 100644 --- a/components/segmentation_platform/internal/execution/model_manager_impl.cc +++ b/components/segmentation_platform/internal/execution/model_manager_impl.cc
@@ -36,13 +36,11 @@ ModelProviderFactory* model_provider_factory, base::Clock* clock, SegmentInfoDatabase* segment_database, - DefaultModelManager* default_model_manager, const SegmentationModelUpdatedCallback& model_updated_callback) : segment_ids_(segment_ids), model_provider_factory_(model_provider_factory), clock_(clock), segment_database_(segment_database), - default_model_manager_(default_model_manager), model_updated_callback_(model_updated_callback) {} void ModelManagerImpl::Initialize() { @@ -58,13 +56,19 @@ std::move(provider)); // Default models - auto* default_provider = - default_model_manager_->GetDefaultProvider(segment_id); + std::unique_ptr<DefaultModelProvider> default_provider = + model_provider_factory_->CreateDefaultProvider(segment_id); if (!default_provider) { + segment_database_->UpdateSegment(segment_id, + ModelSource::DEFAULT_MODEL_SOURCE, + absl::nullopt, base::DoNothing()); continue; } std::unique_ptr<DefaultModelProvider::ModelConfig> model_config = default_provider->GetModelConfig(); + model_providers_.emplace( + std::make_pair(segment_id, ModelSource::DEFAULT_MODEL_SOURCE), + std::move(default_provider)); OnSegmentationModelUpdated(ModelSource::DEFAULT_MODEL_SOURCE, segment_id, model_config->metadata, model_config->model_version); @@ -76,13 +80,10 @@ ModelProvider* ModelManagerImpl::GetModelProvider( proto::SegmentId segment_id, proto::ModelSource model_source) { - // TODO(ritikagup) : Remove the explicit check once default models are stored - // in `model_providers_`. - if (model_source == ModelSource::DEFAULT_MODEL_SOURCE) { - return default_model_manager_->GetDefaultProvider(segment_id); - } auto it = model_providers_.find(std::make_pair(segment_id, model_source)); - DCHECK(it != model_providers_.end()); + if (it == model_providers_.end()) { + return nullptr; + } return it->second.get(); }
diff --git a/components/segmentation_platform/internal/execution/model_manager_impl.h b/components/segmentation_platform/internal/execution/model_manager_impl.h index 44d567d..2ed5e0ef 100644 --- a/components/segmentation_platform/internal/execution/model_manager_impl.h +++ b/components/segmentation_platform/internal/execution/model_manager_impl.h
@@ -14,7 +14,6 @@ #include "base/memory/raw_ptr.h" #include "base/memory/weak_ptr.h" #include "components/segmentation_platform/internal/database/segment_info_database.h" -#include "components/segmentation_platform/internal/execution/default_model_manager.h" #include "components/segmentation_platform/internal/execution/model_manager.h" #include "components/segmentation_platform/public/proto/segmentation_platform.pb.h" #include "third_party/abseil-cpp/absl/types/optional.h" @@ -43,7 +42,6 @@ ModelProviderFactory* model_provider_factory, base::Clock* clock, SegmentInfoDatabase* segment_database, - DefaultModelManager* default_model_manager, const SegmentationModelUpdatedCallback& model_updated_callback); ~ModelManagerImpl() override; @@ -107,9 +105,6 @@ // Database for segment information and metadata. raw_ptr<SegmentInfoDatabase> segment_database_; - // Class to get segment info from default models. - const raw_ptr<DefaultModelManager> default_model_manager_; - // Invoked whenever there is an update to any of the relevant ML models. SegmentationModelUpdatedCallback model_updated_callback_;
diff --git a/components/segmentation_platform/internal/execution/model_manager_impl_unittest.cc b/components/segmentation_platform/internal/execution/model_manager_impl_unittest.cc index c1a01349..5630aa5 100644 --- a/components/segmentation_platform/internal/execution/model_manager_impl_unittest.cc +++ b/components/segmentation_platform/internal/execution/model_manager_impl_unittest.cc
@@ -21,7 +21,6 @@ #include "components/segmentation_platform/internal/database/mock_signal_database.h" #include "components/segmentation_platform/internal/database/signal_database.h" #include "components/segmentation_platform/internal/database/test_segment_info_database.h" -#include "components/segmentation_platform/internal/execution/default_model_manager.h" #include "components/segmentation_platform/internal/execution/mock_model_provider.h" #include "components/segmentation_platform/internal/execution/model_execution_status.h" #include "components/segmentation_platform/internal/execution/model_manager.h" @@ -50,6 +49,9 @@ constexpr SegmentId kSearchUserSegmentId = SegmentId::OPTIMIZATION_TARGET_SEGMENTATION_SEARCH_USER; +constexpr SegmentId kPasswordManagerUserSegmentId = + SegmentId::PASSWORD_MANAGER_USER; + using Sample = SignalDatabase::Sample; class MockSegmentInfoDatabase : public test::TestSegmentInfoDatabase { @@ -95,10 +97,7 @@ clock_.SetNow(base::Time::Now()); // Initialize DB and default models. model_provider_data_.segments_supporting_default_model = { - kSearchUserSegmentId}; - default_model_manager_ = std::make_unique<DefaultModelManager>( - &model_provider_factory_, - model_provider_data_.segments_supporting_default_model); + kSearchUserSegmentId, kPasswordManagerUserSegmentId}; } void TearDown() override { @@ -113,7 +112,7 @@ const ModelManager::SegmentationModelUpdatedCallback& callback) { model_manager_ = std::make_unique<ModelManagerImpl>( segment_ids, &model_provider_factory_, &clock_, segment_database_.get(), - default_model_manager_.get(), callback); + callback); model_manager_->Initialize(); } @@ -132,8 +131,6 @@ base::SimpleTestClock clock_; std::unique_ptr<test::TestSegmentInfoDatabase> segment_database_; std::unique_ptr<MockSignalDatabase> signal_database_; - std::unique_ptr<DefaultModelManager> default_model_manager_; - std::unique_ptr<ModelManagerImpl> model_manager_; }; @@ -308,7 +305,7 @@ } TEST_F(ModelManagerTest, DatabaseUpdateForDefaultModel) { - auto segment_id = SegmentId::OPTIMIZATION_TARGET_SEGMENTATION_SEARCH_USER; + auto segment_id = kSearchUserSegmentId; // Fill in old data for default model in the SegmentInfo database. segment_database_->SetBucketDuration( segment_id, 456, proto::TimeUnit::MONTH, @@ -373,4 +370,17 @@ segment_info_from_db_2->model_metadata().time_unit()); } +TEST_F(ModelManagerTest, GetModelProvider) { + CreateModelManager({kSearchUserSegmentId, kPasswordManagerUserSegmentId}, + base::DoNothing()); + ASSERT_TRUE(model_manager_->GetModelProvider( + kSearchUserSegmentId, proto::ModelSource::DEFAULT_MODEL_SOURCE)); + ASSERT_TRUE(model_manager_->GetModelProvider( + kPasswordManagerUserSegmentId, proto::ModelSource::DEFAULT_MODEL_SOURCE)); + ASSERT_TRUE(model_manager_->GetModelProvider( + kSearchUserSegmentId, proto::ModelSource::SERVER_MODEL_SOURCE)); + ASSERT_TRUE(model_manager_->GetModelProvider( + kPasswordManagerUserSegmentId, proto::ModelSource::SERVER_MODEL_SOURCE)); +} + } // namespace segmentation_platform
diff --git a/components/segmentation_platform/internal/execution/processing/feature_list_query_processor_unittest.cc b/components/segmentation_platform/internal/execution/processing/feature_list_query_processor_unittest.cc index b5367915..5ac9748 100644 --- a/components/segmentation_platform/internal/execution/processing/feature_list_query_processor_unittest.cc +++ b/components/segmentation_platform/internal/execution/processing/feature_list_query_processor_unittest.cc
@@ -16,7 +16,6 @@ #include "components/segmentation_platform/internal/database/segment_info_database.h" #include "components/segmentation_platform/internal/database/signal_storage_config.h" #include "components/segmentation_platform/internal/database/storage_service.h" -#include "components/segmentation_platform/internal/execution/default_model_manager.h" #include "components/segmentation_platform/internal/execution/processing/mock_feature_aggregator.h" #include "components/segmentation_platform/internal/mock_ukm_data_manager.h" #include "components/segmentation_platform/public/input_delegate.h" @@ -43,7 +42,7 @@ auto moved_signal_db = std::make_unique<MockSignalDatabase>(); signal_database_ = moved_signal_db.get(); storage_service_ = std::make_unique<StorageService>( - nullptr, std::move(moved_signal_db), nullptr, nullptr, nullptr, nullptr, + nullptr, std::move(moved_signal_db), nullptr, nullptr, nullptr, &ukm_data_manager_); clock_.SetNow(base::Time::Now()); segment_id_ = SegmentId::OPTIMIZATION_TARGET_SEGMENTATION_NEW_TAB;
diff --git a/components/segmentation_platform/internal/scheduler/execution_service.cc b/components/segmentation_platform/internal/scheduler/execution_service.cc index 9e5ec4b7..9ae589c 100644 --- a/components/segmentation_platform/internal/scheduler/execution_service.cc +++ b/components/segmentation_platform/internal/scheduler/execution_service.cc
@@ -8,7 +8,6 @@ #include "components/prefs/pref_service.h" #include "components/segmentation_platform/internal/database/cached_result_provider.h" #include "components/segmentation_platform/internal/database/storage_service.h" -#include "components/segmentation_platform/internal/execution/default_model_manager.h" #include "components/segmentation_platform/internal/execution/execution_request.h" #include "components/segmentation_platform/internal/execution/model_executor_impl.h" #include "components/segmentation_platform/internal/execution/processing/feature_aggregator_impl.h"
diff --git a/components/segmentation_platform/internal/segmentation_platform_service_impl.cc b/components/segmentation_platform/internal/segmentation_platform_service_impl.cc index 38f0fbd..4b95b8b 100644 --- a/components/segmentation_platform/internal/segmentation_platform_service_impl.cc +++ b/components/segmentation_platform/internal/segmentation_platform_service_impl.cc
@@ -114,8 +114,7 @@ storage_service_->segment_info_database(), storage_service_->signal_storage_config(), init_params->profile_prefs, config.get(), - field_trial_register_.get(), init_params->clock, platform_options_, - storage_service_->default_model_manager()); + field_trial_register_.get(), init_params->clock, platform_options_); } proxy_ = std::make_unique<ServiceProxyImpl>(
diff --git a/components/segmentation_platform/internal/segmentation_platform_service_impl_unittest.cc b/components/segmentation_platform/internal/segmentation_platform_service_impl_unittest.cc index 70d2d775..0108ff9f 100644 --- a/components/segmentation_platform/internal/segmentation_platform_service_impl_unittest.cc +++ b/components/segmentation_platform/internal/segmentation_platform_service_impl_unittest.cc
@@ -93,8 +93,6 @@ SegmentationPlatformServiceTestBase::InitPlatform( ukm_data_manager_.get(), /*history_service=*/nullptr); - SetUpDefaultModelProviders(); - segmentation_platform_service_impl_->GetServiceProxy()->AddObserver( &observer_); } @@ -326,6 +324,7 @@ // segment on demand is executed. EXPECT_TRUE(segmentation_platform_service_impl_->IsPlatformInitialized()); EXPECT_EQ(pending_queue_size, GetPendingActionsQueueSize()); + SetUpDefaultModelProviders(); AssertSelectedSegmentOnDemand( kTestSegmentationKey4, /*is_ready=*/true, SegmentId::OPTIMIZATION_TARGET_SEGMENTATION_SHOPPING_USER);
diff --git a/components/segmentation_platform/internal/selection/request_dispatcher.cc b/components/segmentation_platform/internal/selection/request_dispatcher.cc index 3204e3b..34ab4ac 100644 --- a/components/segmentation_platform/internal/selection/request_dispatcher.cc +++ b/components/segmentation_platform/internal/selection/request_dispatcher.cc
@@ -10,6 +10,7 @@ #include "base/containers/circular_deque.h" #include "base/functional/callback_forward.h" #include "base/location.h" +#include "base/logging.h" #include "base/memory/scoped_refptr.h" #include "base/task/single_thread_task_runner.h" #include "base/time/time.h"
diff --git a/components/segmentation_platform/internal/selection/request_dispatcher_unittest.cc b/components/segmentation_platform/internal/selection/request_dispatcher_unittest.cc index 4ecc345..83ffc9f 100644 --- a/components/segmentation_platform/internal/selection/request_dispatcher_unittest.cc +++ b/components/segmentation_platform/internal/selection/request_dispatcher_unittest.cc
@@ -110,7 +110,7 @@ std::make_unique<ClientResultPrefs>(&prefs_), &clock_); cached_result_writer_ = cached_result_writer.get(); storage_service_ = std::make_unique<StorageService>( - nullptr, nullptr, nullptr, nullptr, nullptr, std::move(config_holder), + nullptr, nullptr, nullptr, nullptr, std::move(config_holder), &ukm_data_manager_); storage_service_->set_cached_result_writer_for_testing( std::move(cached_result_writer));
diff --git a/components/segmentation_platform/internal/selection/segment_selector_impl.cc b/components/segmentation_platform/internal/selection/segment_selector_impl.cc index 5bdca298..6ace8c5 100644 --- a/components/segmentation_platform/internal/selection/segment_selector_impl.cc +++ b/components/segmentation_platform/internal/selection/segment_selector_impl.cc
@@ -81,8 +81,7 @@ const Config* config, FieldTrialRegister* field_trial_register, base::Clock* clock, - const PlatformOptions& platform_options, - DefaultModelManager* default_model_manager) + const PlatformOptions& platform_options) : SegmentSelectorImpl( segment_database, signal_storage_config, @@ -90,8 +89,7 @@ config, field_trial_register, clock, - platform_options, - default_model_manager) {} + platform_options) {} SegmentSelectorImpl::SegmentSelectorImpl( SegmentInfoDatabase* segment_database, @@ -100,12 +98,10 @@ const Config* config, FieldTrialRegister* field_trial_register, base::Clock* clock, - const PlatformOptions& platform_options, - DefaultModelManager* default_model_manager) + const PlatformOptions& platform_options) : result_prefs_(std::move(prefs)), segment_database_(segment_database), signal_storage_config_(signal_storage_config), - default_model_manager_(default_model_manager), config_(config), field_trial_register_(field_trial_register), clock_(clock),
diff --git a/components/segmentation_platform/internal/selection/segment_selector_impl.h b/components/segmentation_platform/internal/selection/segment_selector_impl.h index 9ea0c155..478cc6d7 100644 --- a/components/segmentation_platform/internal/selection/segment_selector_impl.h +++ b/components/segmentation_platform/internal/selection/segment_selector_impl.h
@@ -26,7 +26,6 @@ namespace segmentation_platform { struct Config; -class DefaultModelManager; class ExperimentalGroupRecorder; class FieldTrialRegister; class SegmentationResultPrefs; @@ -40,8 +39,7 @@ const Config* config, FieldTrialRegister* field_trial_register, base::Clock* clock, - const PlatformOptions& platform_options, - DefaultModelManager* default_model_manager); + const PlatformOptions& platform_options); SegmentSelectorImpl(SegmentInfoDatabase* segment_database, SignalStorageConfig* signal_storage_config, @@ -49,8 +47,7 @@ const Config* config, FieldTrialRegister* field_trial_register, base::Clock* clock, - const PlatformOptions& platform_options, - DefaultModelManager* default_model_manager); + const PlatformOptions& platform_options); ~SegmentSelectorImpl() override; @@ -131,9 +128,6 @@ // The database to determine whether the signal storage requirements are met. const raw_ptr<SignalStorageConfig> signal_storage_config_; - // The default model manager is used for the default model fallbacks. - const raw_ptr<DefaultModelManager> default_model_manager_; - // The config for providing configuration params. const raw_ptr<const Config, DanglingUntriaged> config_;
diff --git a/components/segmentation_platform/internal/selection/segment_selector_unittest.cc b/components/segmentation_platform/internal/selection/segment_selector_unittest.cc index 63cb919..e69e61a 100644 --- a/components/segmentation_platform/internal/selection/segment_selector_unittest.cc +++ b/components/segmentation_platform/internal/selection/segment_selector_unittest.cc
@@ -12,7 +12,6 @@ #include "components/segmentation_platform/internal/database/mock_signal_storage_config.h" #include "components/segmentation_platform/internal/database/segment_info_database.h" #include "components/segmentation_platform/internal/database/test_segment_info_database.h" -#include "components/segmentation_platform/internal/execution/default_model_manager.h" #include "components/segmentation_platform/internal/execution/mock_model_provider.h" #include "components/segmentation_platform/internal/execution/model_executor_impl.h" #include "components/segmentation_platform/internal/execution/processing/mock_feature_list_query_processor.h" @@ -128,15 +127,13 @@ std::vector<proto::SegmentId> all_segments; for (const auto& it : config_->segments) all_segments.push_back(it.first); - default_manager_ = - std::make_unique<DefaultModelManager>(&provider_factory_, all_segments); segment_database_ = std::make_unique<test::TestSegmentInfoDatabase>(); auto prefs_moved = std::make_unique<TestSegmentationResultPrefs>(); prefs_ = prefs_moved.get(); segment_selector_ = std::make_unique<SegmentSelectorImpl>( segment_database_.get(), &signal_storage_config_, std::move(prefs_moved), config_.get(), &field_trial_register_, &clock_, - PlatformOptions::CreateDefault(), default_manager_.get()); + PlatformOptions::CreateDefault()); segment_selector_->set_training_data_collector_for_testing( &training_data_collector_); segment_selector_->OnPlatformInitialized(nullptr); @@ -204,7 +201,6 @@ base::SimpleTestClock clock_; std::unique_ptr<test::TestSegmentInfoDatabase> segment_database_; MockSignalStorageConfig signal_storage_config_; - std::unique_ptr<DefaultModelManager> default_manager_; raw_ptr<TestSegmentationResultPrefs, DanglingUntriaged> prefs_; std::unique_ptr<SegmentSelectorImpl> segment_selector_; MockTrainingDataCollector training_data_collector_; @@ -475,7 +471,7 @@ segment_selector_ = std::make_unique<SegmentSelectorImpl>( segment_database_.get(), &signal_storage_config_, std::move(prefs_moved), config_.get(), &field_trial_register_, &clock_, - PlatformOptions::CreateDefault(), default_manager_.get()); + PlatformOptions::CreateDefault()); segment_selector_->set_training_data_collector_for_testing( &training_data_collector_); segment_selector_->OnPlatformInitialized(execution_service_.get()); @@ -520,7 +516,7 @@ segment_selector_ = std::make_unique<SegmentSelectorImpl>( segment_database_.get(), &signal_storage_config_, std::move(prefs_moved), config_.get(), &field_trial_register_, &clock_, - PlatformOptions::CreateDefault(), default_manager_.get()); + PlatformOptions::CreateDefault()); segment_selector_->set_training_data_collector_for_testing( &training_data_collector_); segment_selector_->OnPlatformInitialized(execution_service_.get()); @@ -660,7 +656,7 @@ segment_selector_ = std::make_unique<SegmentSelectorImpl>( segment_database_.get(), &signal_storage_config_, std::move(prefs_moved), config_.get(), &field_trial_register_, &clock_, - PlatformOptions::CreateDefault(), default_manager_.get()); + PlatformOptions::CreateDefault()); // When segment result is missing, unknown subsegment is recorded, otherwise // record metrics based on the subsegment mapping.
diff --git a/components/segmentation_platform/internal/service_proxy_impl_unittest.cc b/components/segmentation_platform/internal/service_proxy_impl_unittest.cc index 8c7e5194..eb13eb4 100644 --- a/components/segmentation_platform/internal/service_proxy_impl_unittest.cc +++ b/components/segmentation_platform/internal/service_proxy_impl_unittest.cc
@@ -11,7 +11,6 @@ #include "components/prefs/testing_pref_service.h" #include "components/segmentation_platform/internal/constants.h" #include "components/segmentation_platform/internal/database/test_segment_info_database.h" -#include "components/segmentation_platform/internal/execution/default_model_manager.h" #include "components/segmentation_platform/internal/execution/mock_model_provider.h" #include "components/segmentation_platform/internal/execution/model_executor.h" #include "components/segmentation_platform/internal/execution/processing/feature_list_query_processor.h" @@ -98,8 +97,7 @@ config, nullptr, nullptr, - PlatformOptions::CreateDefault(), - nullptr) {} + PlatformOptions::CreateDefault()) {} ~FakeSegmentSelectorImpl() override = default; void UpdateSelectedSegment(SegmentId new_selection, float) override {
diff --git a/components/segmentation_platform/internal/signals/signal_filter_processor.h b/components/segmentation_platform/internal/signals/signal_filter_processor.h index b548bb2..ed1b8206 100644 --- a/components/segmentation_platform/internal/signals/signal_filter_processor.h +++ b/components/segmentation_platform/internal/signals/signal_filter_processor.h
@@ -5,9 +5,11 @@ #ifndef COMPONENTS_SEGMENTATION_PLATFORM_INTERNAL_SIGNALS_SIGNAL_FILTER_PROCESSOR_H_ #define COMPONENTS_SEGMENTATION_PLATFORM_INTERNAL_SIGNALS_SIGNAL_FILTER_PROCESSOR_H_ +#include <set> + #include "base/memory/raw_ptr.h" #include "base/memory/weak_ptr.h" -#include "components/segmentation_platform/internal/execution/default_model_manager.h" +#include "components/segmentation_platform/internal/database/segment_info_database.h" #include "components/segmentation_platform/public/proto/segmentation_platform.pb.h" namespace segmentation_platform {
diff --git a/components/segmentation_platform/internal/signals/signal_filter_processor_unittest.cc b/components/segmentation_platform/internal/signals/signal_filter_processor_unittest.cc index 13392bf..09fb328 100644 --- a/components/segmentation_platform/internal/signals/signal_filter_processor_unittest.cc +++ b/components/segmentation_platform/internal/signals/signal_filter_processor_unittest.cc
@@ -15,7 +15,6 @@ #include "components/segmentation_platform/internal/database/signal_storage_config.h" #include "components/segmentation_platform/internal/database/storage_service.h" #include "components/segmentation_platform/internal/database/test_segment_info_database.h" -#include "components/segmentation_platform/internal/execution/default_model_manager.h" #include "components/segmentation_platform/internal/execution/mock_model_provider.h" #include "components/segmentation_platform/internal/mock_ukm_data_manager.h" #include "components/segmentation_platform/internal/signals/histogram_signal_handler.h" @@ -53,36 +52,6 @@ void(base::flat_set<proto::SegmentId> history_based_segments)); }; -// Noop version. For database calls, just passes the calls to the DB. -class TestDefaultModelManager : public DefaultModelManager { - public: - TestDefaultModelManager() - : DefaultModelManager(nullptr, base::flat_set<SegmentId>()) {} - ~TestDefaultModelManager() override = default; - - void GetAllSegmentInfoFromBothModels( - const base::flat_set<SegmentId>& segment_ids, - SegmentInfoDatabase* segment_database, - MultipleSegmentInfoCallback callback) override { - segment_database->GetSegmentInfoForSegments( - segment_ids, - base::BindOnce( - [](DefaultModelManager::MultipleSegmentInfoCallback callback, - std::unique_ptr<SegmentInfoDatabase::SegmentInfoList> db_list) { - DefaultModelManager::SegmentInfoList list; - for (auto& pair : *db_list) { - list.push_back(std::make_unique< - DefaultModelManager::SegmentInfoWrapper>()); - list.back()->segment_source = - DefaultModelManager::SegmentSource::DATABASE; - list.back()->segment_info.Swap(&pair.second); - } - std::move(callback).Run(std::move(list)); - }, - std::move(callback))); - } -}; - class SignalFilterProcessorTest : public testing::Test { public: SignalFilterProcessorTest() = default; @@ -106,14 +75,12 @@ auto moved_signal_config = std::make_unique<MockSignalStorageConfig>(); signal_storage_config_ = moved_signal_config.get(); ukm_data_manager_ = std::make_unique<MockUkmDataManager>(); - auto default_model_manager = std::make_unique<TestDefaultModelManager>(); - default_model_manager_ = default_model_manager.get(); storage_service_ = std::make_unique<StorageService>( std::move(moved_segment_database), nullptr, - std::move(moved_signal_config), std::move(default_model_manager), - std::make_unique<ModelManagerImpl>( - segment_ids, nullptr, nullptr, segment_database_, - default_model_manager_, base::DoNothing()), + std::move(moved_signal_config), + std::make_unique<ModelManagerImpl>(segment_ids, nullptr, nullptr, + segment_database_, + base::DoNothing()), nullptr, ukm_data_manager_.get()); signal_filter_processor_ = std::make_unique<SignalFilterProcessor>( @@ -129,7 +96,6 @@ std::unique_ptr<MockUkmDataManager> ukm_data_manager_; std::unique_ptr<StorageService> storage_service_; raw_ptr<test::TestSegmentInfoDatabase> segment_database_; - raw_ptr<TestDefaultModelManager> default_model_manager_; raw_ptr<MockSignalStorageConfig> signal_storage_config_; };
diff --git a/components/services/print_compositor/public/mojom/print_compositor.mojom b/components/services/print_compositor/public/mojom/print_compositor.mojom index 6457cf8..249466316 100644 --- a/components/services/print_compositor/public/mojom/print_compositor.mojom +++ b/components/services/print_compositor/public/mojom/print_compositor.mojom
@@ -83,8 +83,8 @@ => (Status status, mojo_base.mojom.ReadOnlySharedMemoryRegion? pdf_region); - // Sets the URL which is committed in the main frame of the WebContents, - // for use in crash diagnosis. + // Tells the service what URL is committed in the main frame of the + // WebContents that is printing, for use in crash diagnosis. SetWebContentsURL(url.mojom.Url url); // Sets the user-agent string for the document.
diff --git a/content/browser/gpu/gpu_process_host.cc b/content/browser/gpu/gpu_process_host.cc index 9d7e978..6b2f1af 100644 --- a/content/browser/gpu/gpu_process_host.cc +++ b/content/browser/gpu/gpu_process_host.cc
@@ -296,6 +296,7 @@ switches::kGpuWatchdogTimeoutSeconds, switches::kUseCmdDecoder, switches::kForceVideoOverlays, + switches::kSkiaGraphiteBackend, #if BUILDFLAG(IS_ANDROID) switches::kEnableReachedCodeProfiler, switches::kReachedCodeSamplingIntervalUs,
diff --git a/content/browser/hid/hid_test_utils.cc b/content/browser/hid/hid_test_utils.cc index 5a43f5d..052ad1f 100644 --- a/content/browser/hid/hid_test_utils.cc +++ b/content/browser/hid/hid_test_utils.cc
@@ -26,11 +26,17 @@ void MockHidDelegate::AddObserver(BrowserContext* browser_context, Observer* observer) { + if (assert_browser_context_) { + ASSERT_TRUE(browser_context); + } observer_list_.AddObserver(observer); } void MockHidDelegate::RemoveObserver(BrowserContext* browser_context, Observer* observer) { + if (assert_browser_context_) { + ASSERT_TRUE(browser_context); + } observer_list_.RemoveObserver(observer); } @@ -63,6 +69,10 @@ } } +void MockHidDelegate::SetAssertBrowserContext(bool assert_browser_context) { + assert_browser_context_ = assert_browser_context; +} + HidTestContentBrowserClient::HidTestContentBrowserClient() = default; HidTestContentBrowserClient::~HidTestContentBrowserClient() = default;
diff --git a/content/browser/hid/hid_test_utils.h b/content/browser/hid/hid_test_utils.h index 9aeff38..b361ab0 100644 --- a/content/browser/hid/hid_test_utils.h +++ b/content/browser/hid/hid_test_utils.h
@@ -81,8 +81,11 @@ const base::ObserverList<Observer>& observer_list() { return observer_list_; } + void SetAssertBrowserContext(bool assert_browser_context); + private: base::ObserverList<Observer> observer_list_; + bool assert_browser_context_ = false; }; // Test implementation of ContentBrowserClient for HID tests. The test client
diff --git a/content/browser/interest_group/auction_worklet_manager_unittest.cc b/content/browser/interest_group/auction_worklet_manager_unittest.cc index fbcc283c..12f23830 100644 --- a/content/browser/interest_group/auction_worklet_manager_unittest.cc +++ b/content/browser/interest_group/auction_worklet_manager_unittest.cc
@@ -206,7 +206,11 @@ const absl::optional<std::string>& auction_signals_json, const absl::optional<std::string>& per_buyer_signals_json, const absl::optional<GURL>& direct_from_seller_per_buyer_signals, + const absl::optional<std::string>& + direct_from_seller_per_buyer_signals_header_ad_slot, const absl::optional<GURL>& direct_from_seller_auction_signals, + const absl::optional<std::string>& + direct_from_seller_auction_signals_header_ad_slot, const std::string& seller_signals_json, auction_worklet::mojom::KAnonymityBidMode kanon_mode, bool bid_is_kanon, @@ -337,7 +341,11 @@ const blink::AuctionConfig::NonSharedParams& auction_ad_config_non_shared_params, const absl::optional<GURL>& direct_from_seller_seller_signals, + const absl::optional<std::string>& + direct_from_seller_seller_signals_header_ad_slot, const absl::optional<GURL>& direct_from_seller_auction_signals, + const absl::optional<std::string>& + direct_from_seller_auction_signals_header_ad_slot, auction_worklet::mojom::ComponentAuctionOtherSellerPtr browser_signals_other_seller, const absl::optional<blink::AdCurrency>& component_expect_bid_currency, @@ -364,7 +372,11 @@ const blink::AuctionConfig::NonSharedParams& auction_ad_config_non_shared_params, const absl::optional<GURL>& direct_from_seller_seller_signals, + const absl::optional<std::string>& + direct_from_seller_seller_signals_header_ad_slot, const absl::optional<GURL>& direct_from_seller_auction_signals, + const absl::optional<std::string>& + direct_from_seller_auction_signals_header_ad_slot, auction_worklet::mojom::ComponentAuctionOtherSellerPtr browser_signals_other_seller, const url::Origin& browser_signal_interest_group_owner,
diff --git a/content/browser/interest_group/header_direct_from_seller_signals.h b/content/browser/interest_group/header_direct_from_seller_signals.h index 3a4a764..1e8cd85 100644 --- a/content/browser/interest_group/header_direct_from_seller_signals.h +++ b/content/browser/interest_group/header_direct_from_seller_signals.h
@@ -71,17 +71,17 @@ CompletionCallback callback); // Results of the `sellerSignals` JSON dictionary field. - const absl::optional<std::string>& seller_signals() { + const absl::optional<std::string>& seller_signals() const { return seller_signals_; } // Results of the `auctionSignals` JSON dictionary field. - const absl::optional<std::string>& auction_signals() { + const absl::optional<std::string>& auction_signals() const { return auction_signals_; } // Results of the `perBuyerSignals` JSON dictionary field. - const base::flat_map<url::Origin, std::string>& per_buyer_signals() { + const base::flat_map<url::Origin, std::string>& per_buyer_signals() const { return per_buyer_signals_; }
diff --git a/content/browser/interest_group/interest_group_auction.cc b/content/browser/interest_group/interest_group_auction.cc index d8561da..bb384cf 100644 --- a/content/browser/interest_group/interest_group_auction.cc +++ b/content/browser/interest_group/interest_group_auction.cc
@@ -1333,7 +1333,12 @@ PerBuyerCurrency(owner_, *auction_->config_), GetDirectFromSellerPerBuyerSignals( url_builder, bid_state->bidder->interest_group.owner), - GetDirectFromSellerAuctionSignals(url_builder)); + GetDirectFromSellerPerBuyerSignalsHeaderAdSlot( + *auction_->direct_from_seller_signals_header_ad_slot(), + bid_state->bidder->interest_group.owner), + GetDirectFromSellerAuctionSignals(url_builder), + GetDirectFromSellerAuctionSignalsHeaderAdSlot( + *auction_->direct_from_seller_signals_header_ad_slot())); bid_state->bid_finalizer.reset(); } @@ -2105,6 +2110,7 @@ bidding_and_scoring_phase_start_time_ = base::TimeTicks::Now(); + CHECK_EQ(num_scoring_dependencies_, 0); num_scoring_dependencies_ = buyer_helpers_.size() + component_auctions_.size(); @@ -2113,6 +2119,11 @@ ++num_scoring_dependencies_; } + // Also wait for directFromSellerSignalsHeaderAdSlot to finish JSON parsing. + if (direct_from_seller_signals_header_ad_slot_pending_) { + ++num_scoring_dependencies_; + } + // TODO(morlovich): If the config already resolved additional_bids here, // may start work on it. @@ -2301,8 +2312,11 @@ top_level_seller_winning_bid_info; top_level_seller_winning_bid_info.auction_config = config_; DCHECK(subresource_url_builder_); // Must have been created by scoring. + CHECK(direct_from_seller_signals_header_ad_slot_); // Should never be null. top_level_seller_winning_bid_info.subresource_url_builder = std::move(subresource_url_builder_); + top_level_seller_winning_bid_info.direct_from_seller_signals_header_ad_slot = + std::move(direct_from_seller_signals_header_ad_slot_); top_level_seller_winning_bid_info.bid = winner->bid->bid; if (winner->bid->auction == this) { @@ -2353,8 +2367,13 @@ component_seller_winning_bid_info->auction_config = component_auction->config_; DCHECK(component_auction->subresource_url_builder_); + // Should never be null. + CHECK(component_auction->direct_from_seller_signals_header_ad_slot_); component_seller_winning_bid_info->subresource_url_builder = std::move(component_auction->subresource_url_builder_); + component_seller_winning_bid_info + ->direct_from_seller_signals_header_ad_slot = std::move( + component_auction->direct_from_seller_signals_header_ad_slot_); const LeaderInfo& component_leader = component_auction->leader_info(); component_seller_winning_bid_info->bid = component_leader.top_bid->bid->bid; // The bidder in this auction was the actual bidder, so the currency comes @@ -2500,10 +2519,13 @@ AdAuctionPageData* auction_page_data, const absl::optional<std::string>& direct_from_seller_signals_header_ad_slot) { + CHECK(!direct_from_seller_signals_header_ad_slot_pending_); if (!direct_from_seller_signals_header_ad_slot) { return; } - + if (started_bidding_and_scoring_phase_) { + ++num_scoring_dependencies_; + } direct_from_seller_signals_header_ad_slot_pending_ = true; HeaderDirectFromSellerSignals::ParseAndFind( auction_page_data->GetAuctionSignalsForOrigin(config_->seller), @@ -3098,6 +3120,12 @@ return absl::nullopt; } +absl::optional<std::string> +InterestGroupAuction::GetDirectFromSellerAuctionSignalsHeaderAdSlot( + const HeaderDirectFromSellerSignals& signals) { + return signals.auction_signals(); +} + absl::optional<GURL> InterestGroupAuction::GetDirectFromSellerPerBuyerSignals( const SubresourceUrlBuilder* subresource_url_builder, const url::Origin& owner) { @@ -3112,6 +3140,17 @@ return it->second.subresource_url; } +absl::optional<std::string> +InterestGroupAuction::GetDirectFromSellerPerBuyerSignalsHeaderAdSlot( + const HeaderDirectFromSellerSignals& signals, + const url::Origin& owner) { + auto it = signals.per_buyer_signals().find(owner); + if (it == signals.per_buyer_signals().end()) { + return absl::nullopt; + } + return it->second; +} + absl::optional<GURL> InterestGroupAuction::GetDirectFromSellerSellerSignals( const SubresourceUrlBuilder* subresource_url_builder) { if (subresource_url_builder && subresource_url_builder->seller_signals()) { @@ -3120,6 +3159,12 @@ return absl::nullopt; } +absl::optional<std::string> +InterestGroupAuction::GetDirectFromSellerSellerSignalsHeaderAdSlot( + const HeaderDirectFromSellerSignals& signals) { + return signals.seller_signals(); +} + InterestGroupAuction::LeaderInfo::LeaderInfo() = default; InterestGroupAuction::LeaderInfo::~LeaderInfo() = default; @@ -3527,7 +3572,11 @@ seller_worklet_handle_->GetSellerWorklet()->ScoreAd( bid_raw->ad_metadata, bid_raw->bid, bid_raw->bid_currency, config_->non_shared_params, GetDirectFromSellerSellerSignals(url_builder), + GetDirectFromSellerSellerSignalsHeaderAdSlot( + *direct_from_seller_signals_header_ad_slot_), GetDirectFromSellerAuctionSignals(url_builder), + GetDirectFromSellerAuctionSignalsHeaderAdSlot( + *direct_from_seller_signals_header_ad_slot_), GetOtherSellerParam(*bid_raw), parent_ ? PerBuyerCurrency(config_->seller, *parent_->config_) : absl::nullopt, @@ -4133,12 +4182,19 @@ void InterestGroupAuction::OnDirectFromSellerSignalHeaderAdSlotResolved( std::unique_ptr<HeaderDirectFromSellerSignals> signals, std::vector<std::string> errors) { + CHECK(direct_from_seller_signals_header_ad_slot_pending_); + CHECK(direct_from_seller_signals_header_ad_slot_); direct_from_seller_signals_header_ad_slot_ = std::move(signals); errors_.insert(errors_.end(), errors.begin(), errors.end()); direct_from_seller_signals_header_ad_slot_pending_ = false; - for (const auto& buyer_helper : buyer_helpers_) { - buyer_helper->NotifyConfigDependencyResolved(); + + if (started_bidding_and_scoring_phase_) { + for (const auto& buyer_helper : buyer_helpers_) { + buyer_helper->NotifyConfigDependencyResolved(); + } + OnScoringDependencyDone(); + ScoreQueuedBidsIfReady(); } }
diff --git a/content/browser/interest_group/interest_group_auction.h b/content/browser/interest_group/interest_group_auction.h index dda380b..ae4a142 100644 --- a/content/browser/interest_group/interest_group_auction.h +++ b/content/browser/interest_group/interest_group_auction.h
@@ -710,22 +710,41 @@ const blink::AuctionConfig& config, const url::Origin& buyer); - // Gets the buyer DirectFromSellerSignals auction-signals in `config` for - // buyer. Public so that InterestGroupAuctionReporter can use it. + // Gets the DirectFromSellerSignals auction-signals. Public so that + // InterestGroupAuctionReporter can use it. static absl::optional<GURL> GetDirectFromSellerAuctionSignals( const SubresourceUrlBuilder* subresource_url_builder); + // Gets the DirectFromSellerSignalsHeaderAdSlot auction-signals. Public so + // that InterestGroupAuctionReporter can use it. + static absl::optional<std::string> + GetDirectFromSellerAuctionSignalsHeaderAdSlot( + const HeaderDirectFromSellerSignals& signals); + // Gets the buyer DirectFromSellerSignals per-buyer-signals in `config` for // buyer. Public so that InterestGroupAuctionReporter can use it. static absl::optional<GURL> GetDirectFromSellerPerBuyerSignals( const SubresourceUrlBuilder* subresource_url_builder, const url::Origin& owner); - // Gets the buyer DirectFromSellerSignals seller-signals in `config` for - // buyer. Public so that InterestGroupAuctionReporter can use it. + // Gets the buyer DirectFromSellerSignalsHeaderAdSlot per-buyer-signals + // for `owner`. Public so that InterestGroupAuctionReporter can use it. + static absl::optional<std::string> + GetDirectFromSellerPerBuyerSignalsHeaderAdSlot( + const HeaderDirectFromSellerSignals& signals, + const url::Origin& owner); + + // Gets DirectFromSellerSignals seller-signals. Public so that + // InterestGroupAuctionReporter can use it. static absl::optional<GURL> GetDirectFromSellerSellerSignals( const SubresourceUrlBuilder* subresource_url_builder); + // Gets DirectFromSellerSignalsHeaderAdSlot seller-signals. Public so that + // InterestGroupAuctionReporter can use it. + static absl::optional<std::string> + GetDirectFromSellerSellerSignalsHeaderAdSlot( + const HeaderDirectFromSellerSignals& signals); + // Replaces `${}` placeholders in a debug report URL's query string for post // auction signals if exist. Only replaces unescaped placeholder ${}, but // not escaped placeholder (i.e., %24%7B%7D). @@ -821,7 +840,8 @@ // True if all async prerequisites for calling ScoreBid on the SellerWorklet // are done. bool ReadyToScoreBids() const { - return seller_worklet_received_ && config_promises_resolved_; + return seller_worklet_received_ && config_promises_resolved_ && + !direct_from_seller_signals_header_ad_slot_pending_; } // Called when RequestSellerWorklet() returns. Starts scoring bids, if there @@ -842,6 +862,7 @@ // True if all bids have been generated (or decoded from additional_bids) and // scored and all config promises resolved. bool IsBiddingAndScoringPhaseComplete() const { + CHECK(started_bidding_and_scoring_phase_); return num_scoring_dependencies_ == 0 && bids_being_scored_ == 0 && unscored_bids_.empty(); } @@ -1007,6 +1028,11 @@ // creating it if needed. SubresourceUrlBuilder* SubresourceUrlBuilderIfReady(); + const HeaderDirectFromSellerSignals* + direct_from_seller_signals_header_ad_slot() const { + return direct_from_seller_signals_header_ad_slot_.get(); + } + void OnDecompressedServerResponse( std::unique_ptr<data_decoder::DataDecoder> decoder, AdAuctionRequestContext* request_context, @@ -1110,7 +1136,8 @@ // This includes bidders that are still attempting to generate bids --- // both BuyerHelpers and component auctions. BuyerHelpers may generate // multiple bids (or no bids). It also includes waiting for promises in - // configuration to resolve. + // configuration to resolve, and waiting for + // directFromSellerSignalsHeaderAdSlot to parse. // TODO(morlovich): And will wait for additional_bids. // // When this reaches 0, the SellerWorklet's SendPendingSignalsRequests() @@ -1161,7 +1188,7 @@ std::unique_ptr<SubresourceUrlBuilder> subresource_url_builder_; // Stores the loaded HeaderDirectFromSellerSignals, if there were any. Should - // never be null. + // never be null until moved to the reporter. // // After `direct_from_seller_signals_header_ad_slot_` has been // set to true, the default constructed value gets replaced with the found
diff --git a/content/browser/interest_group/interest_group_auction_reporter.cc b/content/browser/interest_group/interest_group_auction_reporter.cc index 4ba47e1..b8398d63 100644 --- a/content/browser/interest_group/interest_group_auction_reporter.cc +++ b/content/browser/interest_group/interest_group_auction_reporter.cc
@@ -456,8 +456,12 @@ seller_info->auction_config->non_shared_params, InterestGroupAuction::GetDirectFromSellerSellerSignals( seller_info->subresource_url_builder.get()), + InterestGroupAuction::GetDirectFromSellerSellerSignalsHeaderAdSlot( + *seller_info->direct_from_seller_signals_header_ad_slot), InterestGroupAuction::GetDirectFromSellerAuctionSignals( seller_info->subresource_url_builder.get()), + InterestGroupAuction::GetDirectFromSellerAuctionSignalsHeaderAdSlot( + *seller_info->direct_from_seller_signals_header_ad_slot), std::move(other_seller), winning_bid_info_.storage_interest_group->interest_group.owner, /*browser_signal_buyer_and_seller_reporting_id=*/ @@ -718,8 +722,13 @@ InterestGroupAuction::GetDirectFromSellerPerBuyerSignals( seller_info.subresource_url_builder.get(), winning_bid_info_.storage_interest_group->interest_group.owner), + InterestGroupAuction::GetDirectFromSellerPerBuyerSignalsHeaderAdSlot( + *seller_info.direct_from_seller_signals_header_ad_slot, + winning_bid_info_.storage_interest_group->interest_group.owner), InterestGroupAuction::GetDirectFromSellerAuctionSignals( seller_info.subresource_url_builder.get()), + InterestGroupAuction::GetDirectFromSellerAuctionSignalsHeaderAdSlot( + *seller_info.direct_from_seller_signals_header_ad_slot), signals_for_winner, kanon_mode_, bid_is_kanon_, winning_bid_info_.render_url, RoundStochasticallyToKBits(winning_bid_info_.bid,
diff --git a/content/browser/interest_group/interest_group_auction_reporter.h b/content/browser/interest_group/interest_group_auction_reporter.h index d5a88e2..fbe1f1b 100644 --- a/content/browser/interest_group/interest_group_auction_reporter.h +++ b/content/browser/interest_group/interest_group_auction_reporter.h
@@ -46,6 +46,7 @@ class AuctionWorkletManager; struct BiddingAndAuctionResponse; class BrowserContext; +class HeaderDirectFromSellerSignals; class InterestGroupManagerImpl; class PrivateAggregationManager; @@ -118,6 +119,8 @@ auction_config; std::unique_ptr<SubresourceUrlBuilder> subresource_url_builder; + std::unique_ptr<HeaderDirectFromSellerSignals> + direct_from_seller_signals_header_ad_slot; // Bid fed as input to the seller. If this is the top level seller and the // bid came from a component auction, it's the (optionally) modified bid
diff --git a/content/browser/interest_group/interest_group_auction_reporter_unittest.cc b/content/browser/interest_group/interest_group_auction_reporter_unittest.cc index 8cc4909..dc0013d 100644 --- a/content/browser/interest_group/interest_group_auction_reporter_unittest.cc +++ b/content/browser/interest_group/interest_group_auction_reporter_unittest.cc
@@ -25,6 +25,7 @@ #include "base/test/scoped_feature_list.h" #include "content/browser/fenced_frame/fenced_frame_reporter.h" #include "content/browser/interest_group/auction_worklet_manager.h" +#include "content/browser/interest_group/header_direct_from_seller_signals.h" #include "content/browser/interest_group/interest_group_k_anonymity_manager.h" #include "content/browser/interest_group/interest_group_manager_impl.h" #include "content/browser/interest_group/mock_auction_process_manager.h" @@ -65,6 +66,9 @@ // return nothing, though. out.subresource_url_builder = std::make_unique<SubresourceUrlBuilder>( /*direct_from_seller_signals=*/absl::nullopt); + // Also must not be null. + out.direct_from_seller_signals_header_ad_slot = + std::make_unique<HeaderDirectFromSellerSignals>(); // The specific values these are assigned to don't matter for these tests, but // they don't have default initializers, so have to set them to placate memory
diff --git a/content/browser/interest_group/interest_group_browsertest.cc b/content/browser/interest_group/interest_group_browsertest.cc index 45c4932..cc92844 100644 --- a/content/browser/interest_group/interest_group_browsertest.cc +++ b/content/browser/interest_group/interest_group_browsertest.cc
@@ -5270,6 +5270,60 @@ JsReplace(kAuctionConfigTemplate, test_origin, decision_url))); } +IN_PROC_BROWSER_TEST_F( + InterestGroupBrowserTest, + RunAdAuctionRejectPromiseDirectFromSellerSignalsHeaderAdSlot) { + GURL test_url = https_server_->GetURL("a.test", "/echo"); + url::Origin test_origin = url::Origin::Create(test_url); + ASSERT_TRUE(NavigateToURL(shell(), test_url)); + GURL decision_url = + https_server_->GetURL("a.test", "/interest_group/decision_logic.js"); + + const char kAuctionConfigTemplate[] = R"({ + seller: $1, + decisionLogicUrl: $2, + directFromSellerSignalsHeaderAdSlot: new Promise((resolve, reject) => { + setTimeout(() => { reject('boo'); }, 10) }), + interestGroupBuyers: [] + })"; + + EXPECT_EQ("Promise argument rejected or resolved to invalid value.", + RunAuctionAndWait( + JsReplace(kAuctionConfigTemplate, test_origin, decision_url))); +} + +IN_PROC_BROWSER_TEST_F( + InterestGroupBrowserTest, + RunAdAuctionMissingDirectFromSellerSignalsHeaderAdSlotLogged) { + GURL test_url = https_server_->GetURL("a.test", "/echo"); + url::Origin test_origin = url::Origin::Create(test_url); + ASSERT_TRUE(NavigateToURL(shell(), test_url)); + GURL decision_url = + https_server_->GetURL("a.test", "/interest_group/decision_logic.js"); + + // Fetch a URL with adAuctionHeaders: true. The response has no + // Ad-Auction-Signals header, so signals aren't found. An error should be + // logged to devtools. + EXPECT_TRUE(ExecJs( + web_contents()->GetPrimaryMainFrame(), + content::JsReplace("fetch($1, {adAuctionHeaders: true})", test_url))); + + const char kAuctionConfigTemplate[] = R"({ + seller: $1, + decisionLogicUrl: $2, + directFromSellerSignalsHeaderAdSlot: "notFound", + interestGroupBuyers: [] + })"; + + WebContentsConsoleObserver console_observer(shell()->web_contents()); + console_observer.SetPattern( + "Worklet error: When looking for directFromSellerSignalsHeaderAdSlot " + "notFound, failed to find a matching response."); + EXPECT_EQ(nullptr, RunAuctionAndWait(JsReplace(kAuctionConfigTemplate, + test_origin, decision_url))); + EXPECT_TRUE(console_observer.Wait()); +} + IN_PROC_BROWSER_TEST_F(InterestGroupBrowserTest, RunAdAuctionPromiseInvalidDirectFromSellerSignals) { GURL test_url = https_server_->GetURL("a.test", "/echo"); @@ -5768,6 +5822,164 @@ } } +// Create a cross origin iframe, and load header-based directFromSellerSignals +// in that frame. Then, in the main frame, run an auction using the loaded +// signals. +IN_PROC_BROWSER_TEST_F( + InterestGroupBrowserTest, + DirectFromSellerSignalsHeaderAdSlotFromCrossOriginIframe) { + constexpr char kBidderHost[] = "a.test"; + constexpr char kTopFrameHost[] = "c.test"; + constexpr char kSellerHost[] = "b.test"; + constexpr char kIframeHost[] = "d.test"; + url::Origin seller_origin = + url::Origin::Create(https_server_->GetURL(kSellerHost, "/echo")); + url::Origin iframe_origin = + url::Origin::Create(https_server_->GetURL(kIframeHost, "/echo")); + + GURL bidder_url = https_server_->GetURL(kBidderHost, "/echo"); + ASSERT_TRUE(NavigateToURL(shell(), bidder_url)); + url::Origin bidder_origin = url::Origin::Create(bidder_url); + + ASSERT_EQ(kSuccess, + JoinInterestGroupAndVerify( + /*owner=*/bidder_origin, /*name=*/"cars", /*priority=*/0.0, + blink::InterestGroup::ExecutionMode::kCompatibilityMode, + /*bidding_url=*/ + https_server_->GetURL(kBidderHost, + "/interest_group/bidding_logic.js"), + /*ads=*/ + {{{GURL("https://example.com/render"), + /*metadata=*/absl::nullopt}}})); + + GURL top_frame_url = https_server_->GetURL( + kTopFrameHost, + base::StringPrintf( + "/cross_site_iframe_factory.html?%s(%s)", kTopFrameHost, + https_server_->GetURL(kIframeHost, "/echo").spec().c_str())); + + ASSERT_TRUE(NavigateToURL(shell(), top_frame_url)); + RenderFrameHost* const iframe_host = + ChildFrameAt(web_contents()->GetPrimaryMainFrame(), /*index=*/0); + + const char kHeaderSignalsPath[] = "/header_direct_from_seller_signals.json"; + // The actual body of the request is just an empty JSON dict for the test, + // but it could be any arbitrary payload that the server wants to deliver + // with the header signals. + const char kHeaderSignalsBodyResponse[] = "{}"; + const char kHeaderSignalsResponse[] = R"([{ + "adSlot": "adSlot1", + "sellerSignals": {"json": "for", "the": ["seller"]} + }])"; + network_responder_->RegisterNetworkResponse( + kHeaderSignalsPath, kHeaderSignalsBodyResponse, "application/json", + /*extra_response_headers=*/ + {{"Access-Control-Allow-Origin", iframe_origin.Serialize()}, + {"Ad-Auction-Signals", kHeaderSignalsResponse}}); + EXPECT_TRUE(ExecJs(iframe_host, + content::JsReplace("fetch($1, {adAuctionHeaders: true})", + https_server_->GetURL( + kSellerHost, kHeaderSignalsPath)))); + + TestFencedFrameURLMappingResultObserver observer; + ConvertFencedFrameURNToURL( + GURL(EvalJs(web_contents()->GetPrimaryMainFrame(), + JsReplace( + R"( +(async function() { + return await navigator.runAdAuction({ + seller: $1, + decisionLogicUrl: $2, + interestGroupBuyers: [$3], + directFromSellerSignalsHeaderAdSlot: "adSlot1" + }); +})())", + seller_origin.Serialize().c_str(), + https_server_->GetURL(kSellerHost, + "/interest_group/" + "decision_simple_direct_from_" + "seller_signals_validator.js"), + bidder_origin.Serialize().c_str())) + .ExtractString()), + &observer); + EXPECT_EQ(GURL("https://example.com/render"), observer.mapped_url()); +} + +// Start an auction using directFromSellerSignalsHeaderAdSlot, but navigate away +// immediately after starting the auction. +IN_PROC_BROWSER_TEST_F( + InterestGroupBrowserTest, + DirectFromSellerSignalsHeaderAdSlotNavigateAwayDuringAuction) { + constexpr char kBidderHost[] = "a.test"; + constexpr char kTopFrameHost[] = "c.test"; + constexpr char kSellerHost[] = "b.test"; + constexpr char kNewTopFrameHost[] = "d.test"; + url::Origin seller_origin = + url::Origin::Create(https_server_->GetURL(kSellerHost, "/echo")); + const url::Origin top_frame_origin = + url::Origin::Create(https_server_->GetURL(kTopFrameHost, "/echo")); + + GURL bidder_url = https_server_->GetURL(kBidderHost, "/echo"); + ASSERT_TRUE(NavigateToURL(shell(), bidder_url)); + url::Origin bidder_origin = url::Origin::Create(bidder_url); + + ASSERT_EQ(kSuccess, + JoinInterestGroupAndVerify( + /*owner=*/bidder_origin, /*name=*/"cars", /*priority=*/0.0, + blink::InterestGroup::ExecutionMode::kCompatibilityMode, + /*bidding_url=*/ + https_server_->GetURL(kBidderHost, + "/interest_group/bidding_logic.js"), + /*ads=*/ + {{{GURL("https://example.com/render"), + /*metadata=*/absl::nullopt}}})); + + GURL top_frame_url = https_server_->GetURL(kTopFrameHost, "/echo"); + ASSERT_TRUE(NavigateToURL(shell(), top_frame_url)); + + const char kHeaderSignalsPath[] = "/header_direct_from_seller_signals.json"; + // The actual body of the request is just an empty JSON dict for the test, + // but it could be any arbitrary payload that the server wants to deliver + // with the header signals. + const char kHeaderSignalsBodyResponse[] = "{}"; + const char kHeaderSignalsResponse[] = R"([{ + "adSlot": "adSlot1", + "sellerSignals": {"json": "for", "the": ["seller"]} + }])"; + network_responder_->RegisterNetworkResponse( + kHeaderSignalsPath, kHeaderSignalsBodyResponse, "application/json", + /*extra_response_headers=*/ + {{"Access-Control-Allow-Origin", top_frame_origin.Serialize()}, + {"Ad-Auction-Signals", kHeaderSignalsResponse}}); + EXPECT_TRUE(ExecJs(web_contents()->GetPrimaryMainFrame(), + content::JsReplace("fetch($1, {adAuctionHeaders: true})", + https_server_->GetURL( + kSellerHost, kHeaderSignalsPath)))); + + ExecuteScriptAsync(web_contents()->GetPrimaryMainFrame(), + JsReplace( + R"( +(async function() { + return await navigator.runAdAuction({ + seller: $1, + decisionLogicUrl: $2, + interestGroupBuyers: [$3], + directFromSellerSignalsHeaderAdSlot: "adSlot1" + }); +})())", + seller_origin.Serialize().c_str(), + https_server_->GetURL(kSellerHost, + "/interest_group/" + "decision_simple_direct_from_" + "seller_signals_validator.js"), + bidder_origin.Serialize().c_str())); + + // Navigate away without waiting for the auction to complete. Nothing should + // crash. + ASSERT_TRUE( + NavigateToURL(shell(), https_server_->GetURL(kNewTopFrameHost, "/echo"))); +} + IN_PROC_BROWSER_TEST_F(InterestGroupBrowserTest, InvalidDirectFromSellerSignalsHeaderAdSlot) { GURL test_url = https_server_->GetURL("a.test", "/echo"); @@ -9951,9 +10163,17 @@ EXPECT_EQ(nullptr, RunAuctionAndWait(auction_config)); } +class InterestGroupWorkletValidationBrowserTest + : public InterestGroupBrowserTest, + public testing::WithParamInterface<bool> { + public: + bool UseHeaderDirectFromSellerSignals() const { return GetParam(); } +}; + // Use bidder and seller worklet files that validate their arguments all have // the expected values. -IN_PROC_BROWSER_TEST_F(InterestGroupBrowserTest, ValidateWorkletParameters) { +IN_PROC_BROWSER_TEST_P(InterestGroupWorkletValidationBrowserTest, + ValidateWorkletParameters) { // Use different hostnames for each participant, since // `trusted_bidding_signals` only checks the hostname of certain parameters. constexpr char kBidderHost[] = "a.test"; @@ -10022,44 +10242,82 @@ /*ad_sizes=*/{}, /*size_groups=*/{}, /*auction_server_request_flags=*/{}))); - // For `directFromSellerSignals` to work, we need to navigate to a page that - // declares the subresource bundle resources we pass to those fields. GURL seller_script_url = https_server_->GetURL( kSellerHost, "/interest_group/decision_argument_validator.js"); url::Origin seller_origin = url::Origin::Create(seller_script_url); - std::vector<NetworkResponder::SubresourceResponse> subresource_responses = { - NetworkResponder::SubresourceResponse( - /*subresource_url=*/ - "/direct_from_seller_signals?sellerSignals", - /*payload=*/ - R"({"json": "for", "the": ["seller"]})"), - NetworkResponder::SubresourceResponse( - /*subresource_url=*/"/direct_from_seller_signals?auctionSignals", - /*payload=*/ - R"({"json": "for", "all": ["parties"]})"), - NetworkResponder::DirectFromSellerPerBuyerSignals( - bidder_origin, /*payload=*/ - R"({"json": "for", "buyer": [1]})"), - NetworkResponder::DirectFromSellerPerBuyerSignals( - second_bidder_origin, /*payload=*/ - R"({"json": "for", "buyer": [2]})"), - }; - std::vector<NetworkResponder::SubresourceBundle> bundles = { - NetworkResponder::SubresourceBundle( - /*bundle_url=*/https_server_->GetURL(kSellerHost, - "/generated_bundle.wbn"), - /*subresources=*/subresource_responses)}; - network_responder_->RegisterDirectFromSellerSignalsResponse( - /*bundles=*/bundles, - /*allow_origin=*/top_frame_origin.Serialize()); - constexpr char kPagePath[] = "/page-with-bundles.html"; - network_responder_->RegisterHtmlWithSubresourceBundles( - /*bundles=*/bundles, - /*page_url=*/kPagePath); + if (UseHeaderDirectFromSellerSignals()) { + // For `directFromSellerSignalsHeaderAdSlot`, we need to make a network + // request to a resource that has signals in the Ad-Auction-Signals header + // value. + ASSERT_TRUE( + NavigateToURL(shell(), https_server_->GetURL(kTopFrameHost, "/echo"))); + const char kHeaderSignalsPath[] = "/header_direct_from_seller_signals.json"; + // The actual body of the request is just an empty JSON dict for the test, + // but it could be any arbitrary payload that the server wants to deliver + // with the header signals. + const char kHeaderSignalsBodyResponse[] = "{}"; + const std::string kHeaderSignalsResponse = + base::StringPrintf(R"([{ + "adSlot": "adSlot1", + "sellerSignals": {"json": "for", "the": ["seller"]}, + "auctionSignals": {"json": "for", "all": ["parties"]}, + "perBuyerSignals": { + "%s": {"json": "for", "buyer": [1]}, + "%s": {"json": "for", "buyer": [2]} + } + }])", + bidder_origin.Serialize().c_str(), + second_bidder_origin.Serialize().c_str()); + network_responder_->RegisterNetworkResponse( + kHeaderSignalsPath, kHeaderSignalsBodyResponse, "application/json", + /*extra_response_headers=*/ + {{"Access-Control-Allow-Origin", top_frame_origin.Serialize()}, + {"Ad-Auction-Signals", kHeaderSignalsResponse}}); + EXPECT_TRUE( + ExecJs(web_contents()->GetPrimaryMainFrame(), + content::JsReplace( + "fetch($1, {adAuctionHeaders: true})", + https_server_->GetURL(kSellerHost, kHeaderSignalsPath)))); + } else { + // For subresource bundle `directFromSellerSignals` to work, we need to + // navigate to a page that declares the subresource bundle resources we pass + // to those fields. + std::vector<NetworkResponder::SubresourceResponse> subresource_responses = { + NetworkResponder::SubresourceResponse( + /*subresource_url=*/ + "/direct_from_seller_signals?sellerSignals", + /*payload=*/ + R"({"json": "for", "the": ["seller"]})"), + NetworkResponder::SubresourceResponse( + /*subresource_url=*/"/direct_from_seller_signals?auctionSignals", + /*payload=*/ + R"({"json": "for", "all": ["parties"]})"), + NetworkResponder::DirectFromSellerPerBuyerSignals( + bidder_origin, /*payload=*/ + R"({"json": "for", "buyer": [1]})"), + NetworkResponder::DirectFromSellerPerBuyerSignals( + second_bidder_origin, /*payload=*/ + R"({"json": "for", "buyer": [2]})"), + }; + std::vector<NetworkResponder::SubresourceBundle> bundles = { + NetworkResponder::SubresourceBundle( + /*bundle_url=*/https_server_->GetURL(kSellerHost, + "/generated_bundle.wbn"), + /*subresources=*/subresource_responses)}; - ASSERT_TRUE( - NavigateToURL(shell(), https_server_->GetURL(kTopFrameHost, kPagePath))); + network_responder_->RegisterDirectFromSellerSignalsResponse( + /*bundles=*/bundles, + /*allow_origin=*/top_frame_origin.Serialize()); + constexpr char kPagePath[] = "/page-with-bundles.html"; + network_responder_->RegisterHtmlWithSubresourceBundles( + /*bundles=*/bundles, + /*page_url=*/kPagePath); + + ASSERT_TRUE(NavigateToURL(shell(), + https_server_->GetURL(kTopFrameHost, kPagePath))); + } + TestFencedFrameURLMappingResultObserver observer; ConvertFencedFrameURNToURL( GURL(EvalJs(shell(), @@ -10073,7 +10331,7 @@ interestGroupBuyers: [$4, $5], auctionSignals: {so: 'I', hear: ['you', 'like', 'json']}, sellerSignals: {signals: 'from', the: ['seller']}, - directFromSellerSignals: $6, + $6: $7, sellerTimeout: 200, perBuyerSignals: {$4: {signalsForBuyer: 1}, $5: {signalsForBuyer: 2}}, perBuyerTimeouts: {$4: 110, $5: 120, '*': 150}, @@ -10089,8 +10347,15 @@ kSellerHost, "/interest_group/trusted_scoring_signals.json"), bidder_origin, second_bidder_origin, - https_server_->GetURL(kSellerHost, - "/direct_from_seller_signals"))) + UseHeaderDirectFromSellerSignals() + ? "directFromSellerSignalsHeaderAdSlot" + : "directFromSellerSignals", + UseHeaderDirectFromSellerSignals() + ? "adSlot1" + : https_server_ + ->GetURL(kSellerHost, + "/direct_from_seller_signals") + .spec())) .ExtractString()), &observer); EXPECT_EQ(GURL("https://example.com/render"), observer.mapped_url()); @@ -10105,6 +10370,16 @@ WaitForUrl(https_server_->GetURL(kSellerHost, "/echo?report_bidder")); } +INSTANTIATE_TEST_SUITE_P( + All, + InterestGroupWorkletValidationBrowserTest, + testing::Bool(), + [](const testing::TestParamInfo<bool>& info) { + return base::StringPrintf( + "%s", info.param ? "header_direct_from_seller_signals" + : "subresource_bundle_direct_from_seller_signals"); + }); + // Same as above test, but leaves out the extra bidder and uses the older // version 1 bidding signals format. IN_PROC_BROWSER_TEST_F(InterestGroupBrowserTest, @@ -10240,9 +10515,22 @@ WaitForUrl(https_server_->GetURL(kSellerHost, "/echo?report_bidder")); } +class InterestGroupComponentWorkletValidationBrowserTest + : public InterestGroupBrowserTest, + public testing::WithParamInterface<std::tuple<bool, bool>> { + public: + bool TopLevelUseHeaderDirectFromSellerSignals() const { + return std::get<0>(GetParam()); + } + + bool ComponentUseHeaderDirectFromSellerSignals() const { + return std::get<1>(GetParam()); + } +}; + // Use bidder and seller worklet files that validate their arguments all have // the expected values, in the case of an auction with one component auction. -IN_PROC_BROWSER_TEST_F(InterestGroupBrowserTest, +IN_PROC_BROWSER_TEST_P(InterestGroupComponentWorkletValidationBrowserTest, ComponentAuctionValidateWorkletParameters) { // Use different hostnames for each participant. // @@ -10308,8 +10596,6 @@ /*ad_sizes=*/{}, /*size_groups=*/{}, /*auction_server_request_flags=*/{}))); - // For `directFromSellerSignals` to work, we need to navigate to a page that - // declares the subresource bundle resources we pass to those fields. GURL top_level_seller_script_url = https_server_->GetURL( kTopLevelSellerHost, "/interest_group/" @@ -10322,6 +10608,10 @@ url::Origin::Create(top_level_seller_script_url); const url::Origin component_seller_origin = url::Origin::Create(component_seller_script_url); + + // For subresource bundle `directFromSellerSignals` to work, we need to + // navigate to a page that declares the subresource bundle resources we pass + // to those fields. std::vector<NetworkResponder::SubresourceResponse> top_level_subresource_responses = { NetworkResponder::SubresourceResponse( @@ -10372,6 +10662,58 @@ ASSERT_TRUE(NavigateToURL(shell(), https_server_->GetURL(kTopFrameHost, kPagePath))); + // For `directFromSellerSignalsHeaderAdSlot`, we need to make a network + // request to a resource that has signals in the Ad-Auction-Signals header + // value. We do this for both the top-level seller and the component seller. + const char kTopLevelHeaderSignalsPath[] = + "/top_level_header_direct_from_seller_signals.json"; + const char kComponentHeaderSignalsPath[] = + "/component_header_direct_from_seller_signals.json"; + // The actual body of both requests is just an empty JSON dict for the test, + // but it could be any arbitrary payload that the server wants to deliver + // with the header signals. + const char kHeaderSignalsBodyResponse[] = "{}"; + // Intentionally use the same adSlot name for both responses -- responses + // from different sellers shouldn't conflict. + const char kTopLevelHeaderSignalsResponse[] = R"([{ + "adSlot": "adSlot1", + "sellerSignals": {"json": "for", "the": ["seller"]}, + "auctionSignals": {"json": "for", "all": ["parties"]} + }])"; + const std::string kComponentHeaderSignalsResponse = + base::StringPrintf(R"([{ + "adSlot": "adSlot1", + "sellerSignals": {"from": "component", "json": "for", "the": ["seller"]}, + "auctionSignals": { + "from": "component", "json": "for", "all": ["parties"]}, + "perBuyerSignals": { + "%s": {"from": "component", "json": "for", "buyer": [1]} + } + }])", + bidder_origin.Serialize().c_str()); + network_responder_->RegisterNetworkResponse( + kTopLevelHeaderSignalsPath, kHeaderSignalsBodyResponse, + "application/json", + /*extra_response_headers=*/ + {{"Access-Control-Allow-Origin", top_frame_origin.Serialize()}, + {"Ad-Auction-Signals", kTopLevelHeaderSignalsResponse}}); + network_responder_->RegisterNetworkResponse( + kComponentHeaderSignalsPath, kHeaderSignalsBodyResponse, + "application/json", + /*extra_response_headers=*/ + {{"Access-Control-Allow-Origin", top_frame_origin.Serialize()}, + {"Ad-Auction-Signals", kComponentHeaderSignalsResponse}}); + EXPECT_TRUE(ExecJs( + web_contents()->GetPrimaryMainFrame(), + content::JsReplace("fetch($1, {adAuctionHeaders: true})", + https_server_->GetURL(kTopLevelSellerHost, + kTopLevelHeaderSignalsPath)))); + EXPECT_TRUE(ExecJs(web_contents()->GetPrimaryMainFrame(), + content::JsReplace("fetch($1, {adAuctionHeaders: true})", + https_server_->GetURL( + kComponentSellerHost, + kComponentHeaderSignalsPath)))); + // TODO(caraitto): Instead of StringPrintf(), we can pass a single large // base::Value to JsReplace(). TestFencedFrameURLMappingResultObserver observer; @@ -10391,7 +10733,7 @@ trustedScoringSignalsURL: "%s", auctionSignals: maybePromise(["top-level auction signals"]), sellerSignals: maybePromise(["top-level seller signals"]), - directFromSellerSignals: maybePromise("%s"), + %s: maybePromise("%s"), sellerTimeout: 300, perBuyerSignals: maybePromise( {[componentBuyer]: ["top-level buyer signals"]}), @@ -10407,7 +10749,7 @@ interestGroupBuyers: [componentBuyer], auctionSignals: maybePromise(["component auction signals"]), sellerSignals: maybePromise(["component seller signals"]), - directFromSellerSignals: maybePromise("%s"), + %s: maybePromise("%s"), sellerTimeout: 200, perBuyerSignals: maybePromise( {[componentBuyer]: ["component buyer signals"]}), @@ -10432,11 +10774,16 @@ "/interest_group/trusted_scoring_signals.json") .spec() .c_str(), - https_server_ - ->GetURL(kTopLevelSellerHost, - "/direct_from_seller_signals") - .spec() - .c_str(), + TopLevelUseHeaderDirectFromSellerSignals() + ? "directFromSellerSignalsHeaderAdSlot" + : "directFromSellerSignals", + TopLevelUseHeaderDirectFromSellerSignals() + ? "adSlot1" + : https_server_ + ->GetURL(kTopLevelSellerHost, + "/direct_from_seller_signals") + .spec() + .c_str(), component_seller_script_url.spec().c_str(), https_server_ ->GetURL( @@ -10444,11 +10791,16 @@ "/interest_group/trusted_scoring_signals2.json") .spec() .c_str(), - https_server_ - ->GetURL(kComponentSellerHost, - "/direct_from_seller_signals") - .spec() - .c_str())) + ComponentUseHeaderDirectFromSellerSignals() + ? "directFromSellerSignalsHeaderAdSlot" + : "directFromSellerSignals", + ComponentUseHeaderDirectFromSellerSignals() + ? "adSlot1" + : https_server_ + ->GetURL(kComponentSellerHost, + "/direct_from_seller_signals") + .spec() + .c_str())) .ExtractString()), &observer); EXPECT_EQ(GURL("https://example.com/render"), observer.mapped_url()); @@ -10467,6 +10819,21 @@ } } +INSTANTIATE_TEST_SUITE_P( + All, + InterestGroupComponentWorkletValidationBrowserTest, + testing::Combine(testing::Bool(), testing::Bool()), + [](const testing::TestParamInfo<std::tuple<bool, bool>>& info) { + return base::StringPrintf( + "%s_%s", + std::get<0>(info.param) + ? "top_level_header_direct_from_seller_signals" + : "top_level_subresource_bundle_direct_from_seller_signals", + std::get<1>(info.param) + ? "component_header_direct_from_seller_signals" + : "component_subresource_bundle_direct_from_seller_signals"); + }); + // TODO(crbug.com/1441988): Remove this test once old names are no longer // supported. // Same as ComponentAuctionValidateWorkletParameters, but using deprecated names @@ -11311,6 +11678,13 @@ ASSERT_TRUE(NavigateToURL(shell(), test_url)); url::Origin test_origin = url::Origin::Create(test_url); + // Need to fetch a URL with adAuctionHeaders: true for the auction to succeed + // when using directFromSellerSignalsHeaderAdSlot -- it doesn't matter which + // resource is fetched. + EXPECT_TRUE(ExecJs( + web_contents()->GetPrimaryMainFrame(), + content::JsReplace("fetch($1, {adAuctionHeaders: true})", test_url))); + constexpr char kBiddingLogicScript[] = R"( function generateBid( interestGroup, auctionSignals, perBuyerSignals, trustedBiddingSignals, @@ -11408,11 +11782,13 @@ test_origin, https_server_->GetURL("a.test", kBiddingLogicPath)))); - TestFencedFrameURLMappingResultObserver observer; - ConvertFencedFrameURNToURL( - GURL(EvalJs(shell(), - JsReplace( - R"( + for (bool header_direct_from_seller_signals : {false, true}) { + SCOPED_TRACE(header_direct_from_seller_signals); + TestFencedFrameURLMappingResultObserver observer; + ConvertFencedFrameURNToURL( + GURL(EvalJs(shell(), + JsReplace( + R"( (async function() { return await navigator.runAdAuction({ seller: $1, @@ -11430,18 +11806,22 @@ setTimeout( () => { resolve(undefined); }, 1) }), - directFromSellerSignals: new Promise((resolve, reject) => { + $3: new Promise((resolve, reject) => { setTimeout( - () => { resolve("null"); }, 1) + () => { resolve(null); }, 1) }), }); })())", - test_origin, - https_server_->GetURL("a.test", kDecisionLogicPath))) - .ExtractString()), - &observer); + test_origin, + https_server_->GetURL("a.test", kDecisionLogicPath), + header_direct_from_seller_signals + ? "directFromSellerSignalsHeaderAdSlot" + : "directFromSellerSignals")) + .ExtractString()), + &observer); - EXPECT_EQ(GURL("https://example.com/render"), observer.mapped_url()); + EXPECT_EQ(GURL("https://example.com/render"), observer.mapped_url()); + } } // Test for perBuyerTimeouts and perBuyerCumulativeTimeouts being passed to
diff --git a/content/browser/interest_group/mock_auction_process_manager.cc b/content/browser/interest_group/mock_auction_process_manager.cc index b147513..b27e37a 100644 --- a/content/browser/interest_group/mock_auction_process_manager.cc +++ b/content/browser/interest_group/mock_auction_process_manager.cc
@@ -122,7 +122,11 @@ const absl::optional<std::string>& auction_signals_json, const absl::optional<std::string>& per_buyer_signals_json, const absl::optional<GURL>& direct_from_seller_per_buyer_signals, + const absl::optional<std::string>& + direct_from_seller_per_buyer_signals_header_ad_slot, const absl::optional<GURL>& direct_from_seller_auction_signals, + const absl::optional<std::string>& + direct_from_seller_auction_signals_header_ad_slot, const std::string& seller_signals_json, auction_worklet::mojom::KAnonymityBidMode kanon_mode, bool bid_is_kanon, @@ -164,7 +168,11 @@ const absl::optional<base::TimeDelta> per_buyer_timeout, const absl::optional<blink::AdCurrency>& per_buyer_currency, const absl::optional<GURL>& direct_from_seller_per_buyer_signals, - const absl::optional<GURL>& direct_from_seller_auction_signals) { + const absl::optional<std::string>& + direct_from_seller_per_buyer_signals_header_ad_slot, + const absl::optional<GURL>& direct_from_seller_auction_signals, + const absl::optional<std::string>& + direct_from_seller_auction_signals_header_ad_slot) { // per_buyer_timeout passed to GenerateBid() should not be empty, because // auction_config's all_buyers_timeout (which is the key of '*' in // perBuyerTimeouts) is set in the AuctionRunnerTest. @@ -342,7 +350,11 @@ const blink::AuctionConfig::NonSharedParams& auction_ad_config_non_shared_params, const absl::optional<GURL>& direct_from_seller_seller_signals, + const absl::optional<std::string>& + direct_from_seller_seller_signals_header_ad_slot, const absl::optional<GURL>& direct_from_seller_auction_signals, + const absl::optional<std::string>& + direct_from_seller_auction_signals_header_ad_slot, auction_worklet::mojom::ComponentAuctionOtherSellerPtr browser_signals_other_seller, const absl::optional<blink::AdCurrency>& component_expect_bid_currency, @@ -386,7 +398,11 @@ const blink::AuctionConfig::NonSharedParams& auction_ad_config_non_shared_params, const absl::optional<GURL>& direct_from_seller_seller_signals, + const absl::optional<std::string>& + direct_from_seller_seller_signals_header_ad_slot, const absl::optional<GURL>& direct_from_seller_auction_signals, + const absl::optional<std::string>& + direct_from_seller_auction_signals_header_ad_slot, auction_worklet::mojom::ComponentAuctionOtherSellerPtr browser_signals_other_seller, const url::Origin& browser_signal_interest_group_owner,
diff --git a/content/browser/interest_group/mock_auction_process_manager.h b/content/browser/interest_group/mock_auction_process_manager.h index a613a7f..610aa585 100644 --- a/content/browser/interest_group/mock_auction_process_manager.h +++ b/content/browser/interest_group/mock_auction_process_manager.h
@@ -84,7 +84,11 @@ const absl::optional<std::string>& auction_signals_json, const absl::optional<std::string>& per_buyer_signals_json, const absl::optional<GURL>& direct_from_seller_per_buyer_signals, + const absl::optional<std::string>& + direct_from_seller_per_buyer_signals_header_ad_slot, const absl::optional<GURL>& direct_from_seller_auction_signals, + const absl::optional<std::string>& + direct_from_seller_auction_signals_header_ad_slot, const std::string& seller_signals_json, auction_worklet::mojom::KAnonymityBidMode kanon_mode, bool bid_is_kanon, @@ -116,7 +120,11 @@ const absl::optional<base::TimeDelta> per_buyer_timeout, const absl::optional<blink::AdCurrency>& per_buyer_currency, const absl::optional<GURL>& direct_from_seller_per_buyer_signals, - const absl::optional<GURL>& direct_from_seller_auction_signals) override; + const absl::optional<std::string>& + direct_from_seller_per_buyer_signals_header_ad_slot, + const absl::optional<GURL>& direct_from_seller_auction_signals, + const absl::optional<std::string>& + direct_from_seller_auction_signals_header_ad_slot) override; // Waits for GenerateBid() to be invoked. void WaitForGenerateBid(); @@ -243,7 +251,11 @@ const blink::AuctionConfig::NonSharedParams& auction_ad_config_non_shared_params, const absl::optional<GURL>& direct_from_seller_seller_signals, + const absl::optional<std::string>& + direct_from_seller_seller_signals_header_ad_slot, const absl::optional<GURL>& direct_from_seller_auction_signals, + const absl::optional<std::string>& + direct_from_seller_auction_signals_header_ad_slot, auction_worklet::mojom::ComponentAuctionOtherSellerPtr browser_signals_other_seller, const absl::optional<blink::AdCurrency>& component_expect_bid_currency, @@ -260,7 +272,11 @@ const blink::AuctionConfig::NonSharedParams& auction_ad_config_non_shared_params, const absl::optional<GURL>& direct_from_seller_seller_signals, + const absl::optional<std::string>& + direct_from_seller_seller_signals_header_ad_slot, const absl::optional<GURL>& direct_from_seller_auction_signals, + const absl::optional<std::string>& + direct_from_seller_auction_signals_header_ad_slot, auction_worklet::mojom::ComponentAuctionOtherSellerPtr browser_signals_other_seller, const url::Origin& browser_signal_interest_group_owner,
diff --git a/content/browser/renderer_host/input/touch_selection_controller_client_aura.cc b/content/browser/renderer_host/input/touch_selection_controller_client_aura.cc index 18c228a..d2aa512 100644 --- a/content/browser/renderer_host/input/touch_selection_controller_client_aura.cc +++ b/content/browser/renderer_host/input/touch_selection_controller_client_aura.cc
@@ -101,7 +101,7 @@ } } - selection_controller_->HideAndDisallowShowingAutomatically(); + selection_controller_->OnSessionEndEvent(event); } raw_ptr<ui::TouchSelectionController> selection_controller_; @@ -562,10 +562,11 @@ void TouchSelectionControllerClientAura::ExecuteCommand(int command_id, int event_flags) { - if (command_id != ui::TouchEditable::kSelectAll && - command_id != ui::TouchEditable::kSelectWord) { - rwhva_->selection_controller()->HideAndDisallowShowingAutomatically(); - } + const bool should_dismiss_handles = + command_id != ui::TouchEditable::kSelectAll && + command_id != ui::TouchEditable::kSelectWord; + rwhva_->selection_controller()->OnMenuCommand(should_dismiss_handles); + RenderWidgetHostDelegate* host_delegate = rwhva_->host()->delegate(); if (!host_delegate) return;
diff --git a/content/browser/renderer_host/input/touch_selection_controller_client_aura_browsertest.cc b/content/browser/renderer_host/input/touch_selection_controller_client_aura_browsertest.cc index e184d4d..724dd2de 100644 --- a/content/browser/renderer_host/input/touch_selection_controller_client_aura_browsertest.cc +++ b/content/browser/renderer_host/input/touch_selection_controller_client_aura_browsertest.cc
@@ -1378,6 +1378,11 @@ ui::TouchSelectionDragType::kDoublePressDrag, 1); histogram_tester.ExpectTotalCount(ui::kTouchSelectionDragTypeHistogramName, 2); + + // Start typing to end the touch selection session. + generator.PressAndReleaseKey(ui::VKEY_A); + histogram_tester.ExpectUniqueSample( + ui::kTouchSelectionSessionTouchDownCountHistogramName, 3, 1); } #endif // BUILDFLAG(IS_CHROMEOS_ASH)
diff --git a/content/browser/renderer_host/input/touch_selection_controller_client_child_frame.cc b/content/browser/renderer_host/input/touch_selection_controller_client_child_frame.cc index 573c31d..573c0fd2 100644 --- a/content/browser/renderer_host/input/touch_selection_controller_client_child_frame.cc +++ b/content/browser/renderer_host/input/touch_selection_controller_client_child_frame.cc
@@ -206,11 +206,12 @@ void TouchSelectionControllerClientChildFrame::ExecuteCommand(int command_id, int event_flags) { - if (command_id != ui::TouchEditable::kSelectAll && - command_id != ui::TouchEditable::kSelectWord) { - manager_->GetTouchSelectionController() - ->HideAndDisallowShowingAutomatically(); - } + const bool should_dismiss_handles = + command_id != ui::TouchEditable::kSelectAll && + command_id != ui::TouchEditable::kSelectWord; + manager_->GetTouchSelectionController()->OnMenuCommand( + should_dismiss_handles); + RenderWidgetHostDelegate* host_delegate = rwhv_->host()->delegate(); if (!host_delegate) return;
diff --git a/content/browser/renderer_host/render_frame_host_impl_browsertest.cc b/content/browser/renderer_host/render_frame_host_impl_browsertest.cc index 7869e23..df149dd 100644 --- a/content/browser/renderer_host/render_frame_host_impl_browsertest.cc +++ b/content/browser/renderer_host/render_frame_host_impl_browsertest.cc
@@ -4942,11 +4942,12 @@ EXPECT_EQ(main_frame_url, main_document->GetLastCommittedURL()); // Execute script in an isolated world to avoid causing a Trusted Types // violation due to eval. - EXPECT_EQ("Graphics Feature Status", - EvalJs(main_document, - "document.querySelector('info-view').shadowRoot" - ".querySelector('h3').textContent", - EXECUTE_SCRIPT_DEFAULT_OPTIONS, /*world_id=*/1)); + EXPECT_THAT(EvalJs(main_document, + "document.querySelector('info-view').shadowRoot" + ".querySelector('h3').textContent", + EXECUTE_SCRIPT_DEFAULT_OPTIONS, /*world_id=*/1) + .ExtractString(), + testing::StartsWith("Graphics Feature Status")); } // Start with A(B), navigate A to C. By emulating a slow unload handler B, check
diff --git a/content/browser/resources/gpu/BUILD.gn b/content/browser/resources/gpu/BUILD.gn index 1078ac5..0e8785f 100644 --- a/content/browser/resources/gpu/BUILD.gn +++ b/content/browser/resources/gpu/BUILD.gn
@@ -9,11 +9,7 @@ static_files = [ "gpu_internals.html" ] - web_component_files = [ - "info_view.ts", - "info_view_table.ts", - "info_view_table_row.ts", - ] + web_component_files = [ "info_view.ts" ] non_web_component_files = [ "browser_bridge.ts",
diff --git a/content/browser/resources/gpu/gpu_internals.ts b/content/browser/resources/gpu/gpu_internals.ts index 36efe9c..2349cb7 100644 --- a/content/browser/resources/gpu/gpu_internals.ts +++ b/content/browser/resources/gpu/gpu_internals.ts
@@ -20,11 +20,17 @@ document.querySelector('info-view')!.addBrowserBridgeListeners(browserBridge); // Because of inherent raciness (between the deprecated DevTools API which - // telemtry uses to drive the relevant tests, and the asynchronous loading of - // JS modules like this one) it's possible for telemetry tests to inject code - // *before* `browserBridge` is set and the DOM is populated. This flag is used - // to synchronize script injection by tests to prevent such races. - Object.assign(window, {gpuPagePopulated: true}); + // telemetry uses to drive the relevant tests, and the asynchronous + // loading of JS modules like this one) it's possible for telemetry tests + // to inject code *before* `browserBridge` is set and the DOM is + // populated. This flag is used to synchronize script injection by tests + // to prevent such races. + Object.assign(window, { + gpuPagePopulated: true, + getGPUInfo(category: string, feature = '') { + return document.querySelector('info-view')!.getInfo(category, feature); + }, + }); } document.addEventListener('DOMContentLoaded', onLoad);
diff --git a/content/browser/resources/gpu/info_view.html b/content/browser/resources/gpu/info_view.html index ce3643da..7d25830 100644 --- a/content/browser/resources/gpu/info_view.html +++ b/content/browser/resources/gpu/info_view.html
@@ -42,7 +42,8 @@ margin-top: 0; } - #content > div { + #content > div, + #download-to-file { margin-bottom: 1em; } @@ -72,9 +73,7 @@ #download-to-file { font: inherit; - margin: 0 1px 0 0; min-height: 2em; - padding: 1px 10px; user-select: none; } @@ -83,12 +82,41 @@ margin-bottom: 2px; margin-top: 10px; } -</style> + + table.info-table { + border-collapse: collapse; + table-layout: fixed; + width: 100%; + } + .info-table td { + border: 1px solid #777; + vertical-align: top; + overflow-x: auto; + } + .info-table td:nth-child(1) { + font-weight: bold; + width: 25%; + } + .info-table td:nth-child(2) { + font-weight: bold; + width: 75%; + } -<div id="content"> + /* + This class is used to show text that is only available + when the user copies text or downloads the report to a file. + We insert extra but hidden text to make plain text formatting + look better, at copy/download time we make the text visible + */ + .copy { + display: none; + } +</style> +<style id="dynamic-style"></style> <div> <button id="download-to-file">Download Report to File</button> </div> +<div id="content"> <div> <h3>Graphics Feature Status</h3> <ul class="feature-status-list"></ul>
diff --git a/content/browser/resources/gpu/info_view.ts b/content/browser/resources/gpu/info_view.ts index 96c08f7..0492ab76 100644 --- a/content/browser/resources/gpu/info_view.ts +++ b/content/browser/resources/gpu/info_view.ts
@@ -2,14 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import './info_view_table.js'; - import {assert} from 'chrome://resources/js/assert_ts.js'; import {CustomElement} from 'chrome://resources/js/custom_element.js'; import {AngleFeature, BrowserBridge, ClientInfo, FeatureStatus, Problem} from './browser_bridge.js'; import {getTemplate} from './info_view.html.js'; -import {ArrayData, Data} from './info_view_table_row.js'; import {VulkanInfo} from './vulkan_info.js'; /** @@ -28,12 +25,307 @@ }; }()); +function getProblemTextAndUrl(problem: Problem) { + let text = problem.description; + let url = ''; + const pattern = ' Please update your graphics driver via this link: '; + const pos = text.search(pattern); + if (pos > 0) { + url = text.substring(pos + pattern.length); + text = text.substring(0, pos); + } + return {text, url}; +} + +function formatANGLEBug(bug: string) { + if (bug.includes('crbug.com/')) { + return bug.match(/\d+/)!.toString(); + } else if (bug.includes('anglebug.com/')) { + return `anglebug:${bug.match(/\d+/)}`; + } else { + return bug; + } +} + +/** + * Calls a function to insert an element between every element + * of an existing array + */ +function insertBetweenElements<Type>( + array: Type[], fn: (i: number) => Type): Type[] { + const newArray = array.slice(0, 1); + for (let i = 1; i < array.length; ++i) { + newArray.push(fn(i), array[i] as Type); + } + return newArray; +} + +/** Inserts <span>, </span> between every element in array */ +function separateByCommas(array: HTMLElement[], comma = ', ') { + return insertBetweenElements(array, () => createElem('span', comma)); +} + +/** + * Conditionally add elements to an array + * + * ```js + * const array = [ + * "carrots", + * "potatoes", + * ...addIf(haveFruit, () => ["apple", "cherry"]), + * ] + * ``` + * + * The function is not called if `cond` is false. + */ +function addIf<T>(cond: boolean, fn: () => T[]) { + return cond ? fn() : []; +} + +/** + * Word wraps a string, prefixing each line. + */ +function wordWrap(s: string, prefix = ' ', maxLength?: number) { + maxLength = maxLength || (80 - prefix.length); + const lines: string[] = []; + const words = s.split(' '); + const line: string[] = []; + let length = 0; + for (const word of words) { + if (length + word.length + 1 >= maxLength) { + lines.push(line.join(' ')); + line.length = 0; + length = 0; + } + line.push(word); + length += word.length + 1; + } + if (line.length) { + lines.push(line.join(' ')); + } + return lines.map(s => `${prefix}${s}`).join('\n'); +} + +interface Attributes { + [key: string]: string|Attributes; +} + +/** + * Creates an HTMLElement with optional attributes and children + * + * Examples: + * + * ```js + * br = createElem('br'); + * p = createElem('p', 'hello world'); + * a = createElem('a', {href: 'https://google.com', textContent: 'Google'}); + * ul = createElement('ul', {}, [ + * createElem('li', 'apple'), + * createElem('li', 'banana'), + * ]); + * h1 = createElem('h1', { style: { color: 'red' }, textContent: 'Title'}) + * ``` + */ +function createElem( + tag: string, attrs: Attributes|string = {}, children: HTMLElement[] = []) { + const elem = document.createElement(tag) as HTMLElement; + if (typeof attrs === 'string') { + elem.textContent = attrs; + } else { + const elemAsAttribs = elem as unknown as Attributes; + for (const [key, value] of Object.entries(attrs)) { + if (typeof value === 'function' && key.startsWith('on')) { + const eventName = key.substring(2).toLowerCase(); + elem.addEventListener(eventName, value, {passive: false}); + } else if (typeof value === 'object') { + for (const [k, v] of Object.entries(value)) { + (elemAsAttribs[key] as Attributes)[k] = v; + } + } else if (elemAsAttribs[key] === undefined) { + elem.setAttribute(key, value); + } else { + elemAsAttribs[key] = value; + } + } + } + for (const child of children) { + elem.appendChild(child); + } + return elem; +} + +export interface Data { + description: string; + id?: string; + value: string; +} + +export interface ArrayData { + description: string; + value: Data[]; +} + +/** Creates the td elements for a table row */ +function createInfoElements( + data: Data|ArrayData, padSize: number): HTMLElement[] { + const desc = createElem('td', {}, [ + createElem('span', data.description.padEnd(padSize)), + createHidden(':'), + ]); + + if (Array.isArray(data.value)) { + return [ + desc, + createElem('td', {}, [createInfoTable((data as ArrayData).value)]), + ]; + } else { + return [ + desc, + createElem('td', { + textContent: data.value.toString().trim(), + id: (data as Data).id!, + }), + ]; + } +} + +/** Creates a table from the given data */ +function createInfoTable(data: Data[]|ArrayData[]) { + const longestDesc = Math.min( + 32, + (data as Data[]) + .reduce( + (longest, {description}) => Math.max(longest, description.length), + 0)); + return createElem('table', {className: 'info-table'}, [ + createElem( + 'tbody', {}, + data.map( + data => createElem('tr', {}, createInfoElements(data, longestDesc)), + )), + ]); +} + +/** + * Creates a hidden span that will only be used when the when + * the user copies or downloads text. + */ +function createHidden(textContent: string) { + return createElem('span', {className: 'copy', textContent}); +} + +/** + * Given a string or Attributes returns the `textContent` + * and the attributes with `textContent` removed + */ +function separateTextContentFromAttributes(attrs: Attributes|string = {}) { + return typeof attrs === 'string' ? {textContent: attrs, attribs: {}} : { + textContent: attrs['textContent'] as string || '', + attribs: {...attrs, textContent: ''}, + }; +} + +/** + * Creates a list item with a hidden `* ` span prepended for copy + */ +function createLi(attrs: Attributes|string = {}, children: HTMLElement[] = []) { + const {textContent, attribs} = separateTextContentFromAttributes(attrs); + return createElem('li', attribs, [ + createHidden('* '), + createElem('span', textContent), + ...children, + ]); +} + +/** + * Creates a heading tag with hidden text for copying + * so the copy will be like markdown. + */ +function createHeading( + tag: string, padChar: string, attrs: Attributes|string = {}, + children: HTMLElement[] = []) { + const {textContent, attribs} = separateTextContentFromAttributes(attrs); + return createElem(tag, attribs, [ + createHidden('\n\n'), + createElem('span', textContent), + createHidden(`\n${''.padEnd(textContent.length, padChar)}`), + ...children, + ]); +} + +/** + * Creates a link pair with an anchor tag that is visible + * in the page and hidden text for copying so the copy + * will appear as (href) + */ +function createLinkPair(textContent: string, href: string) { + return [ + createElem('a', { + className: 'hide-on-copy', + textContent, + href, + }), + createHidden(`(${href})`), + ]; +} + +/** + * Adds hidden spans to an existing heading. Used when the text is + * copied to make the heading appear like markdown + */ +function addMarkdownHeading(padChar: string) { + return function(el: Element) { + el.appendChild( + createHidden(`\n${''.padEnd(el.textContent!.length, padChar)}`)); + }; +} + +/** + * Get a string data value + */ +function getDataValue(data: Data|ArrayData): string { + return Array.isArray(data.value) ? + data.value.map(data => getDataValue(data)).join(',') : + data.value; +} + +/** + * Go through Datas and find ones that start with 'GPUx' + * return the first with who's value ends itn '*ACTIVE*' + * or else the first one. + * @param data + * @returns + */ +function getActiveGPU(data: Data[]|ArrayData[]) { + // get list of GPUs + const gpus = + [...data].filter(({description}) => /^GPU\d+$/.test(description)); + // get list of active GPUs + const active = gpus.filter(data => getDataValue(data).endsWith('*ACTIVE*')); + const all = [...active, ...gpus]; + // get the first one + if (all.length > 0) { + const gpu = getDataValue(all[0]!); + const parts = gpu.split(', ')[0]!.split('='); + return parts.length === 2 && parts[0]! === 'VENDOR' ? parseInt(parts[1]!) : + 0; + } + return 0; +} + +/** convert a value to a string or empty string if null or undefined */ +function safeString(value: any) { + return typeof value === 'undefined' || value === null ? '' : value.toString(); +} + /** * @fileoverview This view displays information on the current GPU * hardware. Its primary usefulness is to allow users to copy-paste * their data in an easy to read format for bug reports. */ export class InfoViewElement extends CustomElement { + browserBridge?: BrowserBridge; + static override get template() { return getTemplate(); } @@ -48,34 +340,132 @@ this.refresh(browserBridge); } + /** + * public interface for testing + */ + getInfo(category: string, feature: string = ''): string|string[] { + const gpuInfo = this.browserBridge?.gpuInfo; + if (!gpuInfo) { + throw new Error('no gpuInfo'); + } + + switch (category) { + case 'feature-status-for-hardware-gpu-list': + return safeString( + gpuInfo.featureStatusForHardwareGpu?.featureStatus[feature]); + case 'feature-status-list': + return safeString(gpuInfo.featureStatus?.featureStatus[feature]); + case 'active-gpu-for-hardware': + return safeString(getActiveGPU(gpuInfo.basicInfoForHardwareGpu)); + case 'active-gpu': + return safeString(getActiveGPU(gpuInfo.basicInfo)); + case 'workarounds': + return (gpuInfo.featureStatus || gpuInfo.featureStatusForHardwareGpu) + ?.workarounds || + []; + default: + throw new Error(`unknown category: ${category}`); + } + } + + getSelectionText(all: boolean) { + const dynamicStyle = this.getRequiredElement('#dynamic-style')!; + dynamicStyle.textContent = ` + #content { white-space: pre !important; } + .copy { display: initial; } + .hide-on-copy { display: none; } + `; + const contentDiv = this.getRequiredElement('#content')!; + + // document.getSelection doesn't work through shadowDom + // and shadowRoot getSelection is non-standard chromium + const shadowDoc = this.shadowRoot! as unknown as Document; + const selection = shadowDoc.getSelection()!; + + if (all) { + selection.removeAllRanges(); + selection.selectAllChildren(contentDiv); + } else { + const position = + selection.anchorNode?.compareDocumentPosition(selection.focusNode!); + const [startNode, startOffset, endNode, endOffset] = + ((position || 0) & Node.DOCUMENT_POSITION_FOLLOWING) ? + [ + selection.anchorNode!, + selection.anchorOffset, + selection.focusNode!, + selection.focusOffset, + ] : + [ + selection.focusNode!, + selection.focusOffset, + selection.anchorNode!, + selection.anchorOffset, + ]; + if (startOffset === 0) { + // Given the selection between > and < + // + // * >abc + // * def< + // + // We need to move the start of the selection back to the parent + // otherwise the selection above will copied as + // + // abc + // * def + // + // since the * (the list item's bullet) is not selectable directly. + const li = startNode.parentElement?.closest('li'); + selection.setBaseAndExtent( + li || startNode.parentNode!, 0, endNode, endOffset); + } + } + + // Get text and remove superfluous lines and whitespace. + const text = selection.toString() + .replace(/\s*\n\s*\n\s*\n+/g, '\n\n') + .replace(/\t/g, ' ') + .trim(); + + if (all) { + shadowDoc.getSelection()?.removeAllRanges(); + } + + dynamicStyle.textContent = ''; + return text; + } + + connectedCallback() { // Add handler to 'download report to clipboard' button - const downloadButton = - this.shadowRoot!.querySelector<HTMLElement>('#download-to-file')!; + const downloadButton = this.getRequiredElement('#download-to-file'); assert(downloadButton); downloadButton.onclick = (() => { - // Make sure nothing is selected - const s = window.getSelection()!; - s.removeAllRanges(); - - // Select everything - s.selectAllChildren(this.shadowRoot!); - const text = s.toString(); - - // And deselect everything at the end. - window.getSelection()!.removeAllRanges(); - + const text = this.getSelectionText(true); const blob = new Blob([text], {type: 'text/text'}); const filename = `about-gpu-${ new Date().toISOString().replace(/[^a-z0-9-]/ig, '-')}.txt`; saveData(blob, filename); }); + + // Add a copy handler to massage the text for plain text. + document.addEventListener('copy', (event) => { + const text = this.getSelectionText(false); + event!.clipboardData!.setData('text/plain', text); + event.preventDefault(); + }); + + this.shadowRoot!.querySelectorAll('h1, h2, h3') + .forEach(addMarkdownHeading('=')); + this.shadowRoot!.querySelectorAll('h4, h5, h6') + .forEach(addMarkdownHeading('-')); } /** * Updates the view based on its currently known data */ refresh(browserBridge: BrowserBridge) { + this.browserBridge = browserBridge; let clientInfo: ClientInfo; function createSourcePermalink( revisionIdentifier: string, filepath: string): string { @@ -134,6 +524,8 @@ const dawnInfoDiv = this.getRequiredElement('.dawn-info-div'); const dawnInfoList = this.getRequiredElement('.dawn-info-list'); + + const basicInfoForHardwareGpuDiv = this.getRequiredElement('.basic-info-for-hardware-gpu-div'); const featureStatusForHardwareGpuDiv = @@ -173,12 +565,8 @@ featureStatusForHardwareGpuList, problemsForHardwareGpuDiv, problemsForHardwareGpuList, workaroundsForHardwareGpuDiv, workaroundsForHardwareGpuList); - if (gpuInfo.basicInfoForHardwareGpu) { - this.setTable_( - 'basic-info-for-hardware-gpu', gpuInfo.basicInfoForHardwareGpu); - } else { - this.setTable_('basic-info-for-hardware-gpu', []); - } + this.setTable_( + 'basic-info-for-hardware-gpu', gpuInfo.basicInfoForHardwareGpu); } else { basicInfoForHardwareGpuDiv.hidden = true; featureStatusForHardwareGpuDiv.hidden = true; @@ -186,44 +574,19 @@ workaroundsForHardwareGpuDiv.hidden = true; } - if (gpuInfo.basicInfo) { - this.setTable_('basic-info', gpuInfo.basicInfo); - } else { - this.setTable_('basic-info', []); - } - - if (gpuInfo.compositorInfo) { - this.setTable_('compositor-info', gpuInfo.compositorInfo); - } else { - this.setTable_('compositor-info', []); - } - - if (gpuInfo.gpuMemoryBufferInfo) { - this.setTable_('gpu-memory-buffer-info', gpuInfo.gpuMemoryBufferInfo); - } else { - this.setTable_('gpu-memory-buffer-info', []); - } - - if (gpuInfo.displayInfo) { - this.setTable_('display-info', gpuInfo.displayInfo); - } else { - this.setTable_('display-info', []); - } - - if (gpuInfo.videoAcceleratorsInfo) { - this.setTable_( - 'video-acceleration-info', gpuInfo.videoAcceleratorsInfo); - } else { - this.setTable_('video-acceleration-info', []); - } + this.setTable_('basic-info', gpuInfo.basicInfo); + this.setTable_('compositor-info', gpuInfo.compositorInfo); + this.setTable_('gpu-memory-buffer-info', gpuInfo.gpuMemoryBufferInfo); + this.setTable_('display-info', gpuInfo.displayInfo); + this.setTable_('video-acceleration-info', gpuInfo.videoAcceleratorsInfo); if (gpuInfo.ANGLEFeatures) { if (gpuInfo.ANGLEFeatures.length) { angleFeaturesDiv.hidden = false; angleFeaturesList.textContent = ''; for (const angleFeature of gpuInfo.ANGLEFeatures) { - const angleFeatureEl = this.createAngleFeatureEl_(angleFeature); - angleFeaturesList.appendChild(angleFeatureEl); + angleFeaturesList.appendChild( + this.createAngleFeatureEl_(angleFeature)); } } else { angleFeaturesDiv.hidden = true; @@ -253,23 +616,16 @@ diagnosticsDiv.hidden = true; } - if (gpuInfo.vulkanInfo) { - const vulkanInfo = new VulkanInfo(gpuInfo.vulkanInfo); - const data = [{ - 'description': 'info', - 'value': vulkanInfo.toString(), - 'id': 'vulkan-info-value', - }]; - this.setTable_('vulkan-info', data); - } else { - this.setTable_('vulkan-info', []); - } + this.setTable_( + 'vulkan-info', + gpuInfo.vulkanInfo ? [{ + 'description': 'info', + 'value': new VulkanInfo(gpuInfo.vulkanInfo).toString(), + 'id': 'vulkan-info-value', + }] : + []); - if (gpuInfo.devicePerfInfo) { - this.setTable_('device-perf-info', gpuInfo.devicePerfInfo); - } else { - this.setTable_('device-perf-info', []); - } + this.setTable_('device-perf-info', gpuInfo.devicePerfInfo); } else { this.setText_('basic-info', '... loading ...'); diagnosticsDiv.hidden = true; @@ -282,11 +638,8 @@ const messageList = this.getRequiredElement('#log-messages > ul'); messageList.innerHTML = window.trustedTypes!.emptyHTML; browserBridge.logMessages.forEach(messageObj => { - const messageEl = document.createElement('span'); - messageEl.textContent = `${messageObj.header}: ${messageObj.message}`; - const li = document.createElement('li'); - li.appendChild(messageEl); - messageList.appendChild(li); + messageList.appendChild( + createElem('li', `${messageObj.header}: ${messageObj.message}`)); }); } @@ -333,7 +686,10 @@ 'class': 'feature-yellow', }, 'unavailable_off': {'label': 'Unavailable', 'class': 'feature-red'}, - 'unavailable_off_ok': {'label': 'Unavailable', 'class': 'feature-yellow'}, + 'unavailable_off_ok': { + 'label': 'Unavailable', + 'class': 'feature-yellow', + }, 'enabled_readback': { 'label': 'Hardware accelerated but at reduced performance', 'class': 'feature-yellow', @@ -351,28 +707,32 @@ featureStatusList.textContent = ''; for (const featureName in featureInfo.featureStatus) { const featureStatus = featureInfo.featureStatus[featureName]!; - const featureEl = document.createElement('li'); - const nameEl = document.createElement('span'); - if (!featureLabelMap[featureName]) { + const label = featureLabelMap[featureName]; + if (!label) { console.info('Missing featureLabel for', featureName); } - nameEl.textContent = featureLabelMap[featureName] + ': '; - featureEl.appendChild(nameEl); - const statusEl = document.createElement('span'); const statusInfo = statusMap[featureStatus]; if (!statusInfo) { console.info('Missing status for ', featureStatus); - statusEl.textContent = 'Unknown'; - statusEl.className = 'feature-red'; - } else { - statusEl.textContent = statusInfo['label']; - statusEl.className = statusInfo['class']; } - featureEl.appendChild(statusEl); - featureStatusList.appendChild(featureEl); + featureStatusList.appendChild(createLi({}, [ + createElem('span', `${label}: `), + + createElem( + 'span', + statusInfo ? { + textContent: statusInfo['label'], + className: statusInfo['class'], + } : + { + textContent: 'Unknown', + className: 'feature-red', + }, + ), + ])); } // problems list @@ -380,8 +740,7 @@ problemsDiv.hidden = false; problemsList.textContent = ''; for (const problem of featureInfo.problems) { - const problemEl = this.createProblemEl_(problem); - problemsList.appendChild(problemEl); + problemsList.appendChild(this.createProblemEl_(problem)); } } else { problemsDiv.hidden = true; @@ -392,9 +751,7 @@ workaroundsDiv.hidden = false; workaroundsList.textContent = ''; for (const workaround of featureInfo.workarounds) { - const workaroundEl = document.createElement('li'); - workaroundEl.textContent = workaround; - workaroundsList.appendChild(workaroundEl); + workaroundsList.appendChild(createLi(workaround)); } } else { workaroundsDiv.hidden = true; @@ -402,189 +759,134 @@ } private createProblemEl_(problem: Problem): HTMLElement { - const problemEl = document.createElement('li'); + const {text, url} = getProblemTextAndUrl(problem); + return createLi({}, [ + createElem('span', text), - // Description of issue - const desc = document.createElement('a'); - let text = problem.description; - const pattern = ' Please update your graphics driver via this link: '; - const pos = text.search(pattern); - let url = ''; - if (pos > 0) { - url = text.substring(pos + pattern.length); - text = text.substring(0, pos); - } - desc.textContent = text; - problemEl.appendChild(desc); + // add bug separator + ...addIf( + problem.crBugs.length > 0, () => [createElem('span', ':\n ')]), - // Spacing ':' element - if (problem.crBugs.length > 0) { - const tmp = document.createElement('span'); - tmp.textContent = ': '; - problemEl.appendChild(tmp); - } + // add bugs + ...separateByCommas(problem.crBugs.map((id) => { + const bugId = parseInt(id); + const href = `http://crbug.com/${bugId}`; + return createElem('span', {}, createLinkPair(bugId.toString(), href)); + })), - let nbugs = 0; - let j; + // add affectedGpuSettings + ...addIf( + problem.affectedGpuSettings.length > 0, + () => + [createElem('br'), + createHidden(' '), + createElem( + 'i', {}, + [ + createElem( + 'span', + problem.tag === 'disabledFeatures' ? + 'Disabled Features: ' : + 'Applied Workarounds: '), + ...separateByCommas( + problem.affectedGpuSettings.map( + (textContent) => createElem('span', { + textContent, + className: problem.tag === 'disabledFeatures' ? + 'feature-red' : + 'feature-yellow', + }), + ), + ',\n '), + ]), + ]), - // crBugs - for (j = 0; j < problem.crBugs.length; ++j) { - if (nbugs > 0) { - const tmp = document.createElement('span'); - tmp.textContent = ', '; - problemEl.appendChild(tmp); - } + // add driver update link + ...addIf( + !!url, + () => + [createElem('br'), + createHidden(' '), + createElem( + 'b', {className: 'bg-yellow'}, + [ + createElem( + 'span', 'Please update your graphics drive via '), + createElem('a', {textContent: 'this link', href: url}), + ]), + ]), - const link = document.createElement('a'); - const bugid = parseInt(problem.crBugs[j]!); - link.textContent = bugid.toString(); - link.href = 'http://crbug.com/' + bugid; - problemEl.appendChild(link); - nbugs++; - } + // for copy spacing + createElem('span', '\n\n'), - if (problem.affectedGpuSettings.length > 0) { - const brNode = document.createElement('br'); - problemEl.appendChild(brNode); - - const iNode = document.createElement('i'); - problemEl.appendChild(iNode); - - const headNode = document.createElement('span'); - if (problem.tag === 'disabledFeatures') { - headNode.textContent = 'Disabled Features: '; - } else { // problem.tag === 'workarounds' - headNode.textContent = 'Applied Workarounds: '; - } - iNode.appendChild(headNode); - for (j = 0; j < problem.affectedGpuSettings.length; ++j) { - if (j > 0) { - const separateNode = document.createElement('span'); - separateNode.textContent = ', '; - iNode.appendChild(separateNode); - } - const nameNode = document.createElement('span'); - if (problem.tag === 'disabledFeatures') { - nameNode.classList.add('feature-red'); - } else { // problem.tag === 'workarounds' - nameNode.classList.add('feature-yellow'); - } - nameNode.textContent = problem.affectedGpuSettings[j]!; - iNode.appendChild(nameNode); - } - } - - // Append driver update link. - if (pos > 0) { - const brNode = document.createElement('br'); - problemEl.appendChild(brNode); - - const bNode = document.createElement('b'); - bNode.classList.add('bg-yellow'); - problemEl.appendChild(bNode); - - const tmp = document.createElement('span'); - tmp.textContent = 'Please update your graphics driver via '; - bNode.appendChild(tmp); - - const link = document.createElement('a'); - link.textContent = 'this link'; - link.href = url; - bNode.appendChild(link); - } - - return problemEl; + ]); } private createAngleFeatureEl_(angleFeature: AngleFeature) { - const angleFeatureEl = document.createElement('li'); + return createLi({}, [ + // Name comes first, bolded + createElem('b', angleFeature.name), - // Name comes first, bolded - const name = document.createElement('b'); - name.textContent = angleFeature.name; - angleFeatureEl.appendChild(name); + // If there's a category, it follows the name in parentheses + ...addIf( + !!angleFeature.category, + () => + [createElem('span', ` (${angleFeature.category})`), + ]), - // If there's a category, it follows the name in parentheses - if (angleFeature.category) { - const separator = document.createElement('span'); - separator.textContent = ' '; - angleFeatureEl.appendChild(separator); + // If there's a bug link, try to parse the crbug/anglebug number + ...addIf( + !!angleFeature.bug, + () => + [createElem('span', ' '), + ...createLinkPair( + formatANGLEBug(angleFeature.bug), angleFeature.bug), + ]), - const category = document.createElement('span'); - category.textContent = '(' + angleFeature.category + ')'; - angleFeatureEl.appendChild(category); - } + // Follow with a colon, and the status (colored) + createElem('span', ': '), + createElem( + 'span', + angleFeature.status === 'enabled' ? + {className: 'feature-green', textContent: 'Enabled'} : + {className: 'feature-red', textContent: 'Disabled'}), - // If there's a bug link, try to parse the crbug/anglebug number - if (angleFeature.bug) { - const separator = document.createElement('span'); - separator.textContent = ' '; - angleFeatureEl.appendChild(separator); + ...addIf( + !!angleFeature.condition, + () => + [createHidden('\n condition'), + createElem('span', { + className: 'feature-gray', + textContent: `: ${angleFeature.condition}`, + }), + ]), - const bug = document.createElement('a'); - if (angleFeature.bug.includes('crbug.com/')) { - bug.textContent = angleFeature.bug.match(/\d+/)!.toString(); - } else if (angleFeature.bug.includes('anglebug.com/')) { - bug.textContent = 'anglebug:' + angleFeature.bug.match(/\d+/); - } else { - bug.textContent = angleFeature.bug; - } - bug.href = angleFeature.bug; - angleFeatureEl.appendChild(bug); - } + ...addIf( + !!angleFeature.description, + () => + [createElem('br'), + createElem('i', wordWrap(angleFeature.description!)), + ]), - // Follow with a colon, and the status (colored) - const separator = document.createElement('span'); - separator.textContent = ': '; - angleFeatureEl.appendChild(separator); - - const status = document.createElement('span'); - if (angleFeature.status === 'enabled') { - status.textContent = 'Enabled'; - status.classList.add('feature-green'); - } else { - status.textContent = 'Disabled'; - status.classList.add('feature-red'); - } - angleFeatureEl.appendChild(status); - - if (angleFeature.condition) { - const condition = document.createElement('span'); - condition.textContent = ': ' + angleFeature.condition; - condition.classList.add('feature-gray'); - angleFeatureEl.appendChild(condition); - } - - // if there's a description, put on new line, italicized - if (angleFeature.description) { - const brNode = document.createElement('br'); - angleFeatureEl.appendChild(brNode); - - const iNode = document.createElement('i'); - angleFeatureEl.appendChild(iNode); - - const description = document.createElement('span'); - description.textContent = angleFeature.description; - iNode.appendChild(description); - } - - return angleFeatureEl; + // for copy spacing + createElem('span', '\n\n'), + ]); } private setText_(outputElementId: string, text: string) { this.getRequiredElement(`#${outputElementId}`).textContent = text; } - private setTable_(outputElementId: string, inputData: Data[]|ArrayData[]) { - const table = document.createElement('info-view-table'); - table.setData(inputData); + private setTable_( + outputElementId: string, inputData: Data[]|ArrayData[]|undefined) { + const table = createInfoTable(inputData || []); const peg = this.$(`#${outputElementId}`); if (!peg) { throw new Error('Node ' + outputElementId + ' not found'); } - peg.innerHTML = window.trustedTypes!.emptyHTML; + peg.textContent = ''; peg.appendChild(table); } @@ -593,26 +895,23 @@ let inProcessingToggles = false; for (let i = 0; i < gpuDawnInfo.length; ++i) { - let infoString = gpuDawnInfo[i]!; + const infoString = gpuDawnInfo[i]!; let infoEl: HTMLElement; if (infoString.startsWith('<')) { // GPU type and backend type. // Add an empty line for the next adaptor. - const separator = document.createElement('br'); - separator.textContent = ''; - dawnInfoList.appendChild(separator); + dawnInfoList.appendChild(createElem('br')); // e.g. <Discrete GPU> D3D12 backend - infoEl = document.createElement('h3'); - infoEl.textContent = infoString; - dawnInfoList.appendChild(infoEl); + infoEl = createHeading('h3', '-', infoString); inProcessingToggles = false; } else if (infoString.startsWith('[')) { // e.g. [Default Toggle Names] - infoEl = document.createElement('h4'); - infoEl.classList.add('dawn-info-header'); - infoEl.textContent = infoString; + infoEl = createHeading('h4', '-', { + className: 'dawn-info-header', + textContent: infoString, + }); if (infoString === '[WebGPU Status]' || infoString === '[Default Supported Features]') { @@ -622,29 +921,22 @@ } } else if (inProcessingToggles) { // Each toggle takes 3 strings - infoEl = document.createElement('li'); + infoEl = createLi({}, [ + // The toggle name comes first, bolded. + createElem('b', `${infoString}: \n `), - // The toggle name comes first, bolded. - const name = document.createElement('b'); - name.textContent = infoString + ': '; - infoEl.appendChild(name); + // URL + ...createLinkPair(gpuDawnInfo[++i]!, gpuDawnInfo[i]!), - // URL - infoString = gpuDawnInfo[++i]!; - const url = document.createElement('a'); - url.textContent = infoString; - url.href = infoString; - infoEl.appendChild(url); + // Description, italicized + createElem('i', `:\n${wordWrap(gpuDawnInfo[++i]!)}`), - // Description, italicized - infoString = gpuDawnInfo[++i]!; - const description = document.createElement('i'); - description.textContent = ': ' + infoString; - infoEl.appendChild(description); + // for copy spacing + createElem('span', '\n\n'), + ]); } else { // Display supported extensions - infoEl = document.createElement('li'); - infoEl.textContent = infoString; + infoEl = createLi(infoString); } dawnInfoList.appendChild(infoEl);
diff --git a/content/browser/resources/gpu/info_view_table.html b/content/browser/resources/gpu/info_view_table.html deleted file mode 100644 index a29cbd35..0000000 --- a/content/browser/resources/gpu/info_view_table.html +++ /dev/null
@@ -1,12 +0,0 @@ -<style> - :host { - display: flex; - cursor: auto; - width: 100%; - } - - div { - width: 100%; - } -</style> -<div id="info-view-table"></div>
diff --git a/content/browser/resources/gpu/info_view_table.ts b/content/browser/resources/gpu/info_view_table.ts deleted file mode 100644 index fa098cc..0000000 --- a/content/browser/resources/gpu/info_view_table.ts +++ /dev/null
@@ -1,32 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import './info_view_table_row.js'; - -import {CustomElement} from 'chrome://resources/js/custom_element.js'; - -import {getTemplate} from './info_view_table.html.js'; -import {ArrayData, Data} from './info_view_table_row.js'; - -export class InfoViewTableElement extends CustomElement { - static override get template() { - return getTemplate(); - } - - setData(dataArray: Data[]|ArrayData[]) { - dataArray.forEach(data => { - const row = document.createElement('info-view-table-row'); - row.setData(data); - this.shadowRoot!.querySelector('#info-view-table')!.appendChild(row); - }); - } -} - -declare global { - interface HTMLElementTagNameMap { - 'info-view-table': InfoViewTableElement; - } -} - -customElements.define('info-view-table', InfoViewTableElement);
diff --git a/content/browser/resources/gpu/info_view_table_row.html b/content/browser/resources/gpu/info_view_table_row.html deleted file mode 100644 index 4fd6046..0000000 --- a/content/browser/resources/gpu/info_view_table_row.html +++ /dev/null
@@ -1,48 +0,0 @@ -<style> - :host { - border: none; - display: flex; - } - - #array { - width: 100%; - } - - #title { - overflow-x: auto; - width: 25%; - } - - #value { - overflow-x: auto; - width: 75%; - } - - :host(:not([is-array])) #array { - display: none; - } - - :host([is-array]) #title, - :host([is-array]) #value { - display: none; - } - - div { - border: 1px solid #777; - margin-inline-end: -1px; - margin-top: -1px; - } - - .row-title { - font-weight: bold; - } -</style> -<div id="title"> - <span class="row-title">title</span> -</div> -<div id="value"> - <span>value</span> -</div> -<div id="array"> - <span class="row-title"></span> -</div>
diff --git a/content/browser/resources/gpu/info_view_table_row.ts b/content/browser/resources/gpu/info_view_table_row.ts deleted file mode 100644 index f36b487..0000000 --- a/content/browser/resources/gpu/info_view_table_row.ts +++ /dev/null
@@ -1,53 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import {CustomElement} from 'chrome://resources/js/custom_element.js'; - -import {getTemplate} from './info_view_table_row.html.js'; - -export interface Data { - description: string; - id?: string; - value: string; -} - -export interface ArrayData { - description: string; - value: Data[]; -} - -export class InfoViewTableRowElement extends CustomElement { - static override get template() { - return getTemplate(); - } - - setData(data: Data|ArrayData) { - const isArray = data.value instanceof Array; - this.toggleAttribute('is-array', isArray); - if (!isArray) { - this.shadowRoot!.querySelector('.row-title')!.textContent = - data.description; - this.shadowRoot!.querySelector('#value > span')!.textContent = - (data as Data).value; - this.shadowRoot!.querySelector('#value > span')!.id = - String((data as Data).id); - } else { - const array = this.shadowRoot!.querySelector('#array')!; - array.querySelector('span')!.textContent = data.description; - (data as ArrayData).value.forEach(value => { - const row = document.createElement('info-view-table-row'); - row.setData(value); - array.appendChild(row); - }); - } - } -} - -declare global { - interface HTMLElementTagNameMap { - 'info-view-table-row': InfoViewTableRowElement; - } -} - -customElements.define('info-view-table-row', InfoViewTableRowElement);
diff --git a/content/browser/service_worker/service_worker_browsertest.cc b/content/browser/service_worker/service_worker_browsertest.cc index 8caacbd..b03b3b2 100644 --- a/content/browser/service_worker/service_worker_browsertest.cc +++ b/content/browser/service_worker/service_worker_browsertest.cc
@@ -6123,6 +6123,113 @@ EXPECT_EQ(1, GetRequestCount(relative_url)); } +class ServiceWorkerAutoPreloadBrowserTest + : public ServiceWorkerRaceNetworkRequestBrowserTest { + public: + ServiceWorkerAutoPreloadBrowserTest() { + feature_list_.InitWithFeatures( + {kServiceWorkerAutoPreload}, + {features::kServiceWorkerBypassFetchHandler}); + } + + private: + base::test::ScopedFeatureList feature_list_; +}; + +IN_PROC_BROWSER_TEST_F(ServiceWorkerAutoPreloadBrowserTest, + NetworkRequestRepliedFirstButFetchHandlerResultIsUsed) { + // Register the ServiceWorker and navigate to the in scope URL. + SetupAndRegisterServiceWorker(); + const std::string relative_url = + "/service_worker/mock_response?sw_slow&sw_respond"; + const GURL test_url = embedded_test_server()->GetURL(relative_url); + NavigationHandleObserver observer(web_contents(), test_url); + WorkerRunningStatusObserver service_worker_running_status_observer( + public_context()); + NavigateToURLBlockUntilNavigationsComplete(shell(), test_url, 1); + EXPECT_TRUE(observer.has_committed()); + service_worker_running_status_observer.WaitUntilRunning(); + + // ServiceWorker will respond after the delay, so we expect the network + // request initiated by the RaceNetworkRequest is requested to the server + // although it's not actually used. + while (GetRequestCount(relative_url) != 1) { + base::RunLoop().RunUntilIdle(); + } + EXPECT_EQ(1, GetRequestCount(relative_url)); + + // Unlike RaceNetworkRequest, AutoPreload always waits for the response is + // from the fetch handler. + EXPECT_EQ("[ServiceWorkerRaceNetworkRequest] Response from the fetch handler", + GetInnerText()); + + // Check the response header. "X-Response-From: fetch-handler" is returned + // when the result from the fetch handler is used. + EXPECT_EQ("fetch-handler", + observer.GetNormalizedResponseHeader("X-Response-From")); +} + +IN_PROC_BROWSER_TEST_F(ServiceWorkerAutoPreloadBrowserTest, PassThrough) { + // Register the ServiceWorker and navigate to the in scope URL. + SetupAndRegisterServiceWorker(); + // Capture the response head. + const std::string relative_url = + "/service_worker/mock_response?sw_pass_through"; + const GURL test_url = embedded_test_server()->GetURL(relative_url); + + WorkerRunningStatusObserver service_worker_running_status_observer( + public_context()); + NavigationHandleObserver observer(web_contents(), test_url); + NavigateToURLBlockUntilNavigationsComplete(shell(), test_url, 1); + EXPECT_TRUE(observer.has_committed()); + service_worker_running_status_observer.WaitUntilRunning(); + + // Request count should be 1. RaceNetworkRequest + pass through request from + // fetch handler but the fetch handler request will reuse the response from + // RaceNetworkRequest. + while (GetRequestCount(relative_url) != 1) { + base::RunLoop().RunUntilIdle(); + } + EXPECT_EQ(1, GetRequestCount(relative_url)); +} + +IN_PROC_BROWSER_TEST_F(ServiceWorkerAutoPreloadBrowserTest, + NetworkRequest_Wins_FetchHandler_Fallback) { + // Register the ServiceWorker and navigate to the in scope URL. + SetupAndRegisterServiceWorker(); + const std::string relative_url = + "/service_worker/mock_response?sw_slow&sw_fallback"; + NavigateToURLBlockUntilNavigationsComplete( + shell(), embedded_test_server()->GetURL(relative_url), 1); + + // ServiceWorker will respond after the delay, so we expect the network + // request initiated by the RaceNetworkRequest responds first, then get a + // fallback result from the fetch handler. In that case AutoPreload doesn't + // send another network request for the fallback, but reuses the + // RaceNetworkRequest. + EXPECT_EQ("[ServiceWorkerRaceNetworkRequest] Response from the network", + GetInnerText()); + EXPECT_EQ(1, GetRequestCount(relative_url)); +} + +IN_PROC_BROWSER_TEST_F(ServiceWorkerAutoPreloadBrowserTest, + FetchHandler_Wins_Fallback) { + // Register the ServiceWorker and navigate to the in scope URL. + SetupAndRegisterServiceWorker(); + const std::string relative_url = + "/service_worker/mock_response?server_slow&sw_fallback"; + NavigateToURLBlockUntilNavigationsComplete( + shell(), embedded_test_server()->GetURL(relative_url), 1); + + // Server will respond after the delay, so we expect the fetch handler + // responds first and the result is fallback. In that case AutoPreload doesn't + // send another network request for the fallback, but reuses the + // RaceNetworkRequest. + EXPECT_EQ("[ServiceWorkerRaceNetworkRequest] Slow response from the network", + GetInnerText()); + EXPECT_EQ(1, GetRequestCount(relative_url)); +} + class ServiceWorkerRaceNetworkRequestOriginTrialBrowserTest : public ServiceWorkerRaceNetworkRequestBrowserTest { public:
diff --git a/content/browser/service_worker/service_worker_context_wrapper.cc b/content/browser/service_worker/service_worker_context_wrapper.cc index 0d1a5e08..f910fae 100644 --- a/content/browser/service_worker/service_worker_context_wrapper.cc +++ b/content/browser/service_worker/service_worker_context_wrapper.cc
@@ -300,9 +300,11 @@ ClearRunningServiceWorkers(); storage_partition_ = nullptr; - process_manager_->Shutdown(); storage_control_.reset(); context_core_.reset(); + // Shutdown the `process_manager_` at the end so that the steps above can have + // a valid browser context pointer through `process_manager_`. + process_manager_->Shutdown(); } void ServiceWorkerContextWrapper::DeleteAndStartOver() {
diff --git a/content/browser/service_worker/service_worker_hid_delegate_observer_unittest.cc b/content/browser/service_worker/service_worker_hid_delegate_observer_unittest.cc index a0c5d969..80b0c490 100644 --- a/content/browser/service_worker/service_worker_hid_delegate_observer_unittest.cc +++ b/content/browser/service_worker/service_worker_hid_delegate_observer_unittest.cc
@@ -164,6 +164,7 @@ void SetUp() override { ServiceWorkerDeviceDelegateObserverTest::SetUp(); + hid_delegate().SetAssertBrowserContext(true); ON_CALL(hid_delegate(), GetHidManager).WillByDefault(Return(&hid_manager_)); ON_CALL(hid_delegate(), IsFidoAllowedForOrigin) .WillByDefault(Return(false)); @@ -916,4 +917,22 @@ context()->hid_delegate_observer()->registration_id_map().empty()); } +// Shutdown the service worker context and make sure that +// ServiceWorkerHidDelegateObserver removes itself from the hid delegate +// properly. +TEST_F(ServiceWorkerHidDelegateObserverTest, ShutdownServiceWorkerContext) { + const GURL origin(kTestUrl); + auto registration = InstallServiceWorker(origin); + auto* version = registration->newest_installed_version(); + ASSERT_NE(version, nullptr); + StartServiceWorker(version); + CreateHidService(version); + EXPECT_TRUE(context()->hid_delegate_observer()->GetHidServiceForTesting( + registration->id())); + + EXPECT_FALSE(hid_delegate().observer_list().empty()); + helper()->ShutdownContext(); + EXPECT_TRUE(hid_delegate().observer_list().empty()); +} + } // namespace content
diff --git a/content/browser/service_worker/service_worker_main_resource_loader.cc b/content/browser/service_worker/service_worker_main_resource_loader.cc index 569e2c5d..40179971 100644 --- a/content/browser/service_worker/service_worker_main_resource_loader.cc +++ b/content/browser/service_worker/service_worker_main_resource_loader.cc
@@ -343,6 +343,16 @@ } else if (race_network_request_mode != kSkipped && MaybeStartRaceNetworkRequest(context, active_worker)) { dispatched_preload_type_ = DispatchedPreloadType::kRaceNetworkRequest; + } else if (MaybeStartAutoPreload(context, active_worker)) { + // When the AutoPreload is triggered, set the commit responsibility + // because the response is always committed by the fetch handler + // regardless of the race result, except for the case when the fetch + // handler result is fallback. The fallback case is handled after + // receiving the fetch handler result. + SetCommitResponsibility(FetchResponseFrom::kServiceWorker); + dispatched_preload_type_ = DispatchedPreloadType::kAutoPreload; + active_worker->set_fetch_handler_bypass_option( + blink::mojom::ServiceWorkerFetchHandlerBypassOption::kAutoPreload); } else if (fetch_dispatcher_->MaybeStartNavigationPreload( resource_request_, context, frame_tree_node_id_)) { dispatched_preload_type_ = DispatchedPreloadType::kNavigationPreload; @@ -356,6 +366,16 @@ fetch_dispatcher_->Run(); } +bool ServiceWorkerMainResourceLoader::MaybeStartAutoPreload( + scoped_refptr<ServiceWorkerContextWrapper> context, + scoped_refptr<ServiceWorkerVersion> version) { + if (!base::FeatureList::IsEnabled(kServiceWorkerAutoPreload)) { + return false; + } + + return StartRaceNetworkRequest(context, version); +} + bool ServiceWorkerMainResourceLoader::MaybeStartRaceNetworkRequest( scoped_refptr<ServiceWorkerContextWrapper> context, scoped_refptr<ServiceWorkerVersion> version) { @@ -504,6 +524,7 @@ switch (commit_responsibility()) { case FetchResponseFrom::kNoResponseYet: case FetchResponseFrom::kSubresourceLoaderIsHandlingRedirect: + case FetchResponseFrom::kAutoPreloadHandlingFallback: NOTREACHED(); break; case FetchResponseFrom::kServiceWorker: @@ -549,20 +570,49 @@ blink::ServiceWorkerStatusToString(status), "result", ComposeFetchEventResultString(fetch_result, *response)); + // Transition the state if the fetch result is fallback. This is a special + // treatment for RaceNetworkRequest and AutoPreload. + if (fetch_result == + ServiceWorkerFetchDispatcher::FetchEventResult::kShouldFallback) { + switch (commit_responsibility()) { + case FetchResponseFrom::kNoResponseYet: + // If the RaceNetworkRequest or AutoPreload is triggered but the + // response is not handled yet, ask RaceNetworkRequestURLLoaderClient to + // handle the response regardless of the response status not to dispatch + // additional network request for fallback. + switch (dispatched_preload_type_) { + case DispatchedPreloadType::kRaceNetworkRequest: + case DispatchedPreloadType::kAutoPreload: + SetCommitResponsibility(FetchResponseFrom::kWithoutServiceWorker); + break; + default: + break; + } + break; + case FetchResponseFrom::kServiceWorker: + switch (dispatched_preload_type_) { + case DispatchedPreloadType::kAutoPreload: + // If the AutoPreload is triggered and the response is already + // received, but the fetch result is fallback, set the intermediate + // state to let RaceNetworkRequestURLLoaderClient to commit the + // response. + SetCommitResponsibility( + FetchResponseFrom::kAutoPreloadHandlingFallback); + break; + default: + break; + } + break; + case FetchResponseFrom::kWithoutServiceWorker: + break; + case FetchResponseFrom::kSubresourceLoaderIsHandlingRedirect: + case FetchResponseFrom::kAutoPreloadHandlingFallback: + NOTREACHED_NORETURN(); + } + } + switch (commit_responsibility()) { case FetchResponseFrom::kNoResponseYet: - // If the RaceNetworkRequest is triggered but the response is not handled - // yet, and the fetch handler result is FetchEventResult::kShouldFallback, - // ask RaceNetworkRequestURLLoaderClient to handle the response regardless - // of the response status not to dispatch additional network request for - // fallback. - if (dispatched_preload_type_ == - DispatchedPreloadType::kRaceNetworkRequest && - fetch_result == - ServiceWorkerFetchDispatcher::FetchEventResult::kShouldFallback) { - SetCommitResponsibility(FetchResponseFrom::kWithoutServiceWorker); - return; - } SetCommitResponsibility(FetchResponseFrom::kServiceWorker); break; case FetchResponseFrom::kServiceWorker: @@ -577,6 +627,20 @@ std::move(body_as_stream->stream)); } return; + case FetchResponseFrom::kAutoPreloadHandlingFallback: + // |kAutoPreloadHandlingFallback| is the intermediate state to transfer + // the commit responsibility from the fetch handler to the network + // request (kServiceWorker). If the fetch handler result is fallback, + // manually set the network request (kWithoutServiceWorker). + SetCommitResponsibility(FetchResponseFrom::kWithoutServiceWorker); + // If the network request is faster than the fetch handler, the response + // from the network is processed but not committed. We have to explicitly + // commit and complete the response. Otherwise + // |ServiceWorkerRaceNetworkRequestURLLoaderClient::CommitResponse()| will + // be called. + race_network_request_url_loader_client_ + ->CommitAndCompleteResponseIfDataTransferFinished(); + return; case FetchResponseFrom::kSubresourceLoaderIsHandlingRedirect: NOTREACHED_NORETURN(); }
diff --git a/content/browser/service_worker/service_worker_main_resource_loader.h b/content/browser/service_worker/service_worker_main_resource_loader.h index 55a06b7..a0dde1cd 100644 --- a/content/browser/service_worker/service_worker_main_resource_loader.h +++ b/content/browser/service_worker/service_worker_main_resource_loader.h
@@ -126,10 +126,14 @@ // the corresponding request from the ServiceWorker. // kNavigationPreload: // Enabled when Navigation Preload is triggered. + // kAutoPreload: + // AutoPreload is triggered. This is consumed in the fetch handler or + // the fallback request. enum class DispatchedPreloadType { kNone, kRaceNetworkRequest, - kNavigationPreload + kNavigationPreload, + kAutoPreload, }; void DidPrepareFetchEvent(scoped_refptr<ServiceWorkerVersion> version, @@ -239,6 +243,14 @@ scoped_refptr<ServiceWorkerContextWrapper> context_wrapper, scoped_refptr<ServiceWorkerVersion> version); + // If the feature is enabled, invoke the preload network request. + // See this doc for the high-level code flow in + // ServiceWorkerMainResourceLoader. + // https://docs.google.com/presentation/d/13A54OUqaBPrgkIQZE3a3CnhT3pe3C70j07HCisjNZlI/edit#slide=id.g2753dd0eed3_0_0 + bool MaybeStartAutoPreload( + scoped_refptr<ServiceWorkerContextWrapper> context_wrapper, + scoped_refptr<ServiceWorkerVersion> version); + NavigationLoaderInterceptor::FallbackCallback fallback_callback_; network::ResourceRequest resource_request_;
diff --git a/content/common/service_worker/race_network_request_url_loader_client.cc b/content/common/service_worker/race_network_request_url_loader_client.cc index a241cdf..35c3907 100644 --- a/content/common/service_worker/race_network_request_url_loader_client.cc +++ b/content/common/service_worker/race_network_request_url_loader_client.cc
@@ -3,11 +3,14 @@ // found in the LICENSE file. #include "content/common/service_worker/race_network_request_url_loader_client.h" + +#include "base/feature_list.h" #include "base/metrics/field_trial_params.h" #include "base/metrics/histogram_functions.h" #include "base/notreached.h" #include "base/strings/strcat.h" #include "base/trace_event/trace_event.h" +#include "content/common/features.h" #include "content/common/service_worker/service_worker_resource_loader.h" #include "content/public/common/content_features.h" #include "mojo/public/c/system/data_pipe.h" @@ -156,6 +159,8 @@ // fallback request. owner_->HandleRedirect(redirect_info, head); break; + case FetchResponseFrom::kAutoPreloadHandlingFallback: + NOTREACHED_NORETURN(); } redirected_ = true; } @@ -216,6 +221,9 @@ // instead because it may have a response from the cache. // TODO(crbug.com/1420517): More comprehensive error handling may be // needed, especially the case when HTTP cache hit or redirect happened. + // + // When the AutoPreload is enabled, RaceNetworkRequest works just for the + // dedupe purpose. The fetch handler should always commit the response. if (head_->headers->response_code() != net::HttpStatusCode::HTTP_OK) { owner_->SetCommitResponsibility(FetchResponseFrom::kServiceWorker); } else { @@ -226,8 +234,9 @@ break; case FetchResponseFrom::kServiceWorker: // If commit responsibility is FetchResponseFrom::kServiceWorker, that - // means the response was already received from the fetch handler. The - // response from RaceNetworkRequest is simply discarded in that case. + // means the response was already received from the fetch handler, or the + // AutoPreload is enabled. The response from RaceNetworkRequest is + // consumed only for the dedupe purpose. break; case FetchResponseFrom::kWithoutServiceWorker: // kWithoutServiceWorker is set When the fetch handler response comes @@ -235,6 +244,8 @@ // response. CommitResponse(); break; + case FetchResponseFrom::kAutoPreloadHandlingFallback: + NOTREACHED_NORETURN(); } forwarding_client_->OnReceiveResponse( @@ -260,7 +271,6 @@ if (!owner_) { return; } - TransitionState(State::kCompleted); switch (owner_->commit_responsibility()) { case FetchResponseFrom::kNoResponseYet: case FetchResponseFrom::kSubresourceLoaderIsHandlingRedirect: @@ -274,9 +284,12 @@ // RaceNetworkRequest, do nothing. Defer the handling to the owner. break; case FetchResponseFrom::kWithoutServiceWorker: + TransitionState(State::kCompleted); owner_->CommitCompleted(completion_status_->error_code, "RaceNetworkRequest has completed."); break; + case FetchResponseFrom::kAutoPreloadHandlingFallback: + NOTREACHED_NORETURN(); } data_pipe_for_race_network_request_.producer.reset(); forwarding_client_->OnComplete(completion_status_.value()); @@ -288,6 +301,14 @@ body_consumer_watcher_.Cancel(); } +void ServiceWorkerRaceNetworkRequestURLLoaderClient:: + CommitAndCompleteResponseIfDataTransferFinished() { + if (state_ == State::kDataTransferFinished) { + CommitResponse(); + CompleteResponse(); + } +} + void ServiceWorkerRaceNetworkRequestURLLoaderClient::OnDataTransferComplete() { MaybeCommitResponse(); TRACE_EVENT0(
diff --git a/content/common/service_worker/race_network_request_url_loader_client.h b/content/common/service_worker/race_network_request_url_loader_client.h index 3b19f2e..6ef1ce0 100644 --- a/content/common/service_worker/race_network_request_url_loader_client.h +++ b/content/common/service_worker/race_network_request_url_loader_client.h
@@ -134,6 +134,9 @@ // pipe may be stacked. So this method provides a way to just consume data. void DrainData(mojo::ScopedDataPipeConsumerHandle source); + // Commit and complete the response. Those can be called from |owner_|. + void CommitAndCompleteResponseIfDataTransferFinished(); + private: struct DataPipeInfo { mojo::ScopedDataPipeProducerHandle producer;
diff --git a/content/common/service_worker/service_worker_resource_loader.cc b/content/common/service_worker/service_worker_resource_loader.cc index 0f581af..7dc3222 100644 --- a/content/common/service_worker/service_worker_resource_loader.cc +++ b/content/common/service_worker/service_worker_resource_loader.cc
@@ -3,7 +3,11 @@ // found in the LICENSE file. #include "content/common/service_worker/service_worker_resource_loader.h" + #include "base/check_op.h" +#include "base/feature_list.h" +#include "base/trace_event/trace_event.h" +#include "content/common/features.h" namespace content { ServiceWorkerResourceLoader::ServiceWorkerResourceLoader() = default; @@ -11,6 +15,11 @@ void ServiceWorkerResourceLoader::SetCommitResponsibility( FetchResponseFrom fetch_response_from) { + TRACE_EVENT_WITH_FLOW2( + "ServiceWorker", "ServiceWorkerResourceLoader::SetCommitResponsibility", + this, TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, + "commit_responsibility_", commit_responsibility_, "fetch_response_from", + fetch_response_from); switch (fetch_response_from) { case FetchResponseFrom::kNoResponseYet: NOTREACHED_NORETURN(); @@ -19,10 +28,12 @@ CHECK(!IsMainResourceLoader()); CHECK(commit_responsibility_ == FetchResponseFrom::kServiceWorker || commit_responsibility_ == FetchResponseFrom::kWithoutServiceWorker); - commit_responsibility_ = fetch_response_from; + break; + case FetchResponseFrom::kAutoPreloadHandlingFallback: + CHECK(base::FeatureList::IsEnabled(kServiceWorkerAutoPreload)); + CHECK_EQ(commit_responsibility_, FetchResponseFrom::kServiceWorker); break; case FetchResponseFrom::kServiceWorker: - case FetchResponseFrom::kWithoutServiceWorker: if (IsMainResourceLoader()) { CHECK_EQ(commit_responsibility_, FetchResponseFrom::kNoResponseYet); } else { @@ -30,9 +41,20 @@ commit_responsibility_ == FetchResponseFrom::kSubresourceLoaderIsHandlingRedirect); } - commit_responsibility_ = fetch_response_from; + break; + case FetchResponseFrom::kWithoutServiceWorker: + if (IsMainResourceLoader()) { + CHECK(commit_responsibility_ == FetchResponseFrom::kNoResponseYet || + commit_responsibility_ == + FetchResponseFrom::kAutoPreloadHandlingFallback); + } else { + CHECK(commit_responsibility_ == FetchResponseFrom::kNoResponseYet || + commit_responsibility_ == + FetchResponseFrom::kSubresourceLoaderIsHandlingRedirect); + } break; } + commit_responsibility_ = fetch_response_from; } void ServiceWorkerResourceLoader::RecordFetchResponseFrom() {
diff --git a/content/common/service_worker/service_worker_resource_loader.h b/content/common/service_worker/service_worker_resource_loader.h index 7b0e9b0..0ca7d3e 100644 --- a/content/common/service_worker/service_worker_resource_loader.h +++ b/content/common/service_worker/service_worker_resource_loader.h
@@ -35,7 +35,16 @@ // to be updated to either |kServiceWorker| or |kWithoutServiceWorker| after // receiving the final response. kSubresourceLoaderIsHandlingRedirect = 3, - kMaxValue = kSubresourceLoaderIsHandlingRedirect, + // When ServiceWorkerAutoPreload is enabled, in most cases the response from + // |kServiceWorker| is expected. However, when the fetch handler result is + // fallback, the browser tries to use the response from the network request. + // In this case |commit_responsibility_| is transitioned from + // |kServiceWorker| to |kWithoutServiceWorker|, but we don't want to permit + // that transition in normal cases. This state is a special intermediate + // state to bridge those states, which is used only to handle fallback with + // ServiceWorkerAutoPreload. + kAutoPreloadHandlingFallback = 4, + kMaxValue = kAutoPreloadHandlingFallback, }; ServiceWorkerResourceLoader();
diff --git a/content/renderer/service_worker/service_worker_subresource_loader.cc b/content/renderer/service_worker/service_worker_subresource_loader.cc index 5eab9616..08e729ad 100644 --- a/content/renderer/service_worker/service_worker_subresource_loader.cc +++ b/content/renderer/service_worker/service_worker_subresource_loader.cc
@@ -531,6 +531,8 @@ // If the fetch request is already handled by RaceNetworkRequest, no // need to call CommitCompleted here. return; + case FetchResponseFrom::kAutoPreloadHandlingFallback: + NOTREACHED_NORETURN(); } } fetch_request_restarted_ = true; @@ -630,6 +632,8 @@ // fallback. The response from RaceNetworkRequest is currently handled by // the code path for the non-fallback case. return; + case FetchResponseFrom::kAutoPreloadHandlingFallback: + NOTREACHED_NORETURN(); } // Hand over to the network loader. @@ -697,6 +701,8 @@ std::move(body_as_stream->stream)); } return; + case FetchResponseFrom::kAutoPreloadHandlingFallback: + NOTREACHED_NORETURN(); } RecordFetchResponseFrom(); @@ -842,6 +848,7 @@ switch (commit_responsibility()) { case FetchResponseFrom::kNoResponseYet: case FetchResponseFrom::kSubresourceLoaderIsHandlingRedirect: + case FetchResponseFrom::kAutoPreloadHandlingFallback: NOTREACHED(); break; case FetchResponseFrom::kServiceWorker:
diff --git a/content/services/auction_worklet/auction_v8_helper_unittest.cc b/content/services/auction_worklet/auction_v8_helper_unittest.cc index f00fbb10..1ac107e9 100644 --- a/content/services/auction_worklet/auction_v8_helper_unittest.cc +++ b/content/services/auction_worklet/auction_v8_helper_unittest.cc
@@ -94,7 +94,11 @@ const absl::optional<std::string>& auction_signals_json, const absl::optional<std::string>& per_buyer_signals_json, const absl::optional<GURL>& direct_from_seller_per_buyer_signals, + const absl::optional<std::string>& + direct_from_seller_per_buyer_signals_header_ad_slot, const absl::optional<GURL>& direct_from_seller_auction_signals, + const absl::optional<std::string>& + direct_from_seller_auction_signals_header_ad_slot, const std::string& seller_signals_json, mojom::KAnonymityBidMode kanon_mode, bool bid_is_kanon,
diff --git a/content/services/auction_worklet/bidder_worklet.cc b/content/services/auction_worklet/bidder_worklet.cc index 0f8808e..5a2b687 100644 --- a/content/services/auction_worklet/bidder_worklet.cc +++ b/content/services/auction_worklet/bidder_worklet.cc
@@ -99,6 +99,29 @@ return true; } +// Checks both types of DirectFromSellerSignals results (subresource bundle +// based and header based) -- at most one of these should be non-null. +// +// Returns the V8 conversion of the in-use version of DirectFromSellerSignals, +// or v8::Null() if both types of DirectFromSellerSignals are null. +v8::Local<v8::Value> GetDirectFromSellerSignals( + const DirectFromSellerSignalsRequester::Result& subresource_bundle_result, + const absl::optional<std::string>& header_result, + AuctionV8Helper& v8_helper, + v8::Local<v8::Context> context, + std::vector<std::string>& errors) { + CHECK(subresource_bundle_result.IsNull() || !header_result); + + if (header_result) { + // `header_result` JSON was validated, parsed and reconstructed into a + // string by the browser process, so CHECK it is valid JSON. + return v8_helper.CreateValueFromJson(context, *header_result) + .ToLocalChecked(); + } + + return subresource_bundle_result.GetSignals(v8_helper, context, errors); +} + // TODO(crbug.com/1441988): Remove this code after rename. These functions allow // having multiple dictionary keys (e.g. renderUrl and renderURL) share the same // V8 value. @@ -445,7 +468,11 @@ const absl::optional<std::string>& auction_signals_json, const absl::optional<std::string>& per_buyer_signals_json, const absl::optional<GURL>& direct_from_seller_per_buyer_signals, + const absl::optional<std::string>& + direct_from_seller_per_buyer_signals_header_ad_slot, const absl::optional<GURL>& direct_from_seller_auction_signals, + const absl::optional<std::string>& + direct_from_seller_auction_signals_header_ad_slot, const std::string& seller_signals_json, mojom::KAnonymityBidMode kanon_mode, bool bid_is_kanon, @@ -467,6 +494,10 @@ uint64_t trace_id, ReportWinCallback report_win_callback) { DCHECK_CALLED_ON_VALID_SEQUENCE(user_sequence_checker_); + CHECK((!direct_from_seller_per_buyer_signals && + !direct_from_seller_auction_signals) || + (!direct_from_seller_per_buyer_signals_header_ad_slot && + !direct_from_seller_auction_signals_header_ad_slot)); report_win_tasks_.emplace_front(); auto report_win_task = report_win_tasks_.begin(); @@ -535,6 +566,10 @@ DirectFromSellerSignalsRequester::Result(); } report_win_task->trace_wait_deps_start = base::TimeTicks::Now(); + report_win_task->direct_from_seller_per_buyer_signals_header_ad_slot = + direct_from_seller_per_buyer_signals_header_ad_slot; + report_win_task->direct_from_seller_auction_signals_header_ad_slot = + direct_from_seller_auction_signals_header_ad_slot; TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("fledge", "wait_report_win_deps", trace_id); RunReportWinIfReady(report_win_task); @@ -555,13 +590,26 @@ const absl::optional<base::TimeDelta> per_buyer_timeout, const absl::optional<blink::AdCurrency>& expected_buyer_currency, const absl::optional<GURL>& direct_from_seller_per_buyer_signals, - const absl::optional<GURL>& direct_from_seller_auction_signals) { + const absl::optional<std::string>& + direct_from_seller_per_buyer_signals_header_ad_slot, + const absl::optional<GURL>& direct_from_seller_auction_signals, + const absl::optional<std::string>& + direct_from_seller_auction_signals_header_ad_slot) { + CHECK((!direct_from_seller_per_buyer_signals && + !direct_from_seller_auction_signals) || + (!direct_from_seller_per_buyer_signals_header_ad_slot && + !direct_from_seller_auction_signals_header_ad_slot)); + GenerateBidTaskList::iterator task = finalize_receiver_set_.current_context(); task->auction_signals_json = auction_signals_json; task->per_buyer_signals_json = per_buyer_signals_json; task->per_buyer_timeout = per_buyer_timeout; task->expected_buyer_currency = expected_buyer_currency; task->finalize_generate_bid_called = true; + task->direct_from_seller_per_buyer_signals_header_ad_slot = + direct_from_seller_per_buyer_signals_header_ad_slot; + task->direct_from_seller_auction_signals_header_ad_slot = + direct_from_seller_auction_signals_header_ad_slot; HandleDirectFromSellerForGenerateBid(direct_from_seller_per_buyer_signals, direct_from_seller_auction_signals, task); @@ -658,8 +706,12 @@ const absl::optional<std::string>& per_buyer_signals_json, DirectFromSellerSignalsRequester::Result direct_from_seller_result_per_buyer_signals, + const absl::optional<std::string>& + direct_from_seller_per_buyer_signals_header_ad_slot, DirectFromSellerSignalsRequester::Result direct_from_seller_result_auction_signals, + const absl::optional<std::string>& + direct_from_seller_auction_signals_header_ad_slot, const std::string& seller_signals_json, mojom::KAnonymityBidMode kanon_mode, bool bid_is_kanon, @@ -807,12 +859,14 @@ v8::Local<v8::Object> direct_from_seller_signals = v8::Object::New(isolate); gin::Dictionary direct_from_seller_signals_dict(isolate, direct_from_seller_signals); - v8::Local<v8::Value> per_buyer_signals = - direct_from_seller_result_per_buyer_signals.GetSignals( - *v8_helper_, context, errors_out); - v8::Local<v8::Value> auction_signals = - direct_from_seller_result_auction_signals.GetSignals(*v8_helper_, context, - errors_out); + v8::Local<v8::Value> per_buyer_signals = GetDirectFromSellerSignals( + direct_from_seller_result_per_buyer_signals, + direct_from_seller_per_buyer_signals_header_ad_slot, *v8_helper_, context, + errors_out); + v8::Local<v8::Value> auction_signals = GetDirectFromSellerSignals( + direct_from_seller_result_auction_signals, + direct_from_seller_auction_signals_header_ad_slot, *v8_helper_, context, + errors_out); if (!direct_from_seller_signals_dict.Set("perBuyerSignals", per_buyer_signals) || !direct_from_seller_signals_dict.Set("auctionSignals", auction_signals)) { @@ -901,8 +955,12 @@ const absl::optional<std::string>& per_buyer_signals_json, DirectFromSellerSignalsRequester::Result direct_from_seller_result_per_buyer_signals, + const absl::optional<std::string>& + direct_from_seller_per_buyer_signals_header_ad_slot, DirectFromSellerSignalsRequester::Result direct_from_seller_result_auction_signals, + const absl::optional<std::string>& + direct_from_seller_auction_signals_header_ad_slot, const absl::optional<base::TimeDelta> per_buyer_timeout, const absl::optional<blink::AdCurrency>& expected_buyer_currency, const url::Origin& browser_signal_seller_origin, @@ -928,7 +986,9 @@ base::OptionalToPtr(auction_signals_json), base::OptionalToPtr(per_buyer_signals_json), direct_from_seller_result_per_buyer_signals, - direct_from_seller_result_auction_signals, per_buyer_timeout, + direct_from_seller_per_buyer_signals_header_ad_slot, + direct_from_seller_result_auction_signals, + direct_from_seller_auction_signals_header_ad_slot, per_buyer_timeout, expected_buyer_currency, browser_signal_seller_origin, base::OptionalToPtr(browser_signal_top_level_seller_origin), browser_signal_recency, bidding_browser_signals, auction_start_time, @@ -965,8 +1025,11 @@ base::OptionalToPtr(auction_signals_json), base::OptionalToPtr(per_buyer_signals_json), direct_from_seller_result_per_buyer_signals, - direct_from_seller_result_auction_signals, per_buyer_timeout, - expected_buyer_currency, browser_signal_seller_origin, + direct_from_seller_per_buyer_signals_header_ad_slot, + direct_from_seller_result_auction_signals, + direct_from_seller_auction_signals_header_ad_slot, + per_buyer_timeout, expected_buyer_currency, + browser_signal_seller_origin, base::OptionalToPtr(browser_signal_top_level_seller_origin), browser_signal_recency, bidding_browser_signals, auction_start_time, requested_ad_size, @@ -1027,8 +1090,12 @@ const std::string* per_buyer_signals_json, const DirectFromSellerSignalsRequester::Result& direct_from_seller_result_per_buyer_signals, + const absl::optional<std::string>& + direct_from_seller_per_buyer_signals_header_ad_slot, const DirectFromSellerSignalsRequester::Result& direct_from_seller_result_auction_signals, + const absl::optional<std::string>& + direct_from_seller_auction_signals_header_ad_slot, const absl::optional<base::TimeDelta> per_buyer_timeout, const absl::optional<blink::AdCurrency>& expected_buyer_currency, const url::Origin& browser_signal_seller_origin, @@ -1293,12 +1360,14 @@ v8::Local<v8::Object> direct_from_seller_signals = v8::Object::New(isolate); gin::Dictionary direct_from_seller_signals_dict(isolate, direct_from_seller_signals); - v8::Local<v8::Value> per_buyer_signals = - direct_from_seller_result_per_buyer_signals.GetSignals( - *v8_helper_, context, errors_out); - v8::Local<v8::Value> auction_signals = - direct_from_seller_result_auction_signals.GetSignals(*v8_helper_, context, - errors_out); + v8::Local<v8::Value> per_buyer_signals = GetDirectFromSellerSignals( + direct_from_seller_result_per_buyer_signals, + direct_from_seller_per_buyer_signals_header_ad_slot, *v8_helper_, context, + errors_out); + v8::Local<v8::Value> auction_signals = GetDirectFromSellerSignals( + direct_from_seller_result_auction_signals, + direct_from_seller_auction_signals_header_ad_slot, *v8_helper_, context, + errors_out); if (!direct_from_seller_signals_dict.Set("perBuyerSignals", per_buyer_signals) || !direct_from_seller_signals_dict.Set("auctionSignals", auction_signals)) { @@ -1838,7 +1907,9 @@ std::move(task->auction_signals_json), std::move(task->per_buyer_signals_json), std::move(task->direct_from_seller_result_per_buyer_signals), + std::move(task->direct_from_seller_per_buyer_signals_header_ad_slot), std::move(task->direct_from_seller_result_auction_signals), + std::move(task->direct_from_seller_auction_signals_header_ad_slot), std::move(task->per_buyer_timeout), std::move(task->expected_buyer_currency), std::move(task->browser_signal_seller_origin), @@ -1921,7 +1992,9 @@ std::move(task->auction_signals_json), std::move(task->per_buyer_signals_json), std::move(task->direct_from_seller_result_per_buyer_signals), + std::move(task->direct_from_seller_per_buyer_signals_header_ad_slot), std::move(task->direct_from_seller_result_auction_signals), + std::move(task->direct_from_seller_auction_signals_header_ad_slot), std::move(task->seller_signals_json), std::move(task->kanon_mode), std::move(task->bid_is_kanon), std::move(task->browser_signal_render_url),
diff --git a/content/services/auction_worklet/bidder_worklet.h b/content/services/auction_worklet/bidder_worklet.h index ac70d60..4aa2aef 100644 --- a/content/services/auction_worklet/bidder_worklet.h +++ b/content/services/auction_worklet/bidder_worklet.h
@@ -149,7 +149,11 @@ const absl::optional<std::string>& auction_signals_json, const absl::optional<std::string>& per_buyer_signals_json, const absl::optional<GURL>& direct_from_seller_per_buyer_signals, + const absl::optional<std::string>& + direct_from_seller_per_buyer_signals_header_ad_slot, const absl::optional<GURL>& direct_from_seller_auction_signals, + const absl::optional<std::string>& + direct_from_seller_auction_signals_header_ad_slot, const std::string& seller_signals_json, mojom::KAnonymityBidMode kanon_mode, bool bid_is_kanon, @@ -181,7 +185,11 @@ const absl::optional<base::TimeDelta> per_buyer_timeout, const absl::optional<blink::AdCurrency>& expected_buyer_currency, const absl::optional<GURL>& direct_from_seller_per_buyer_signals, - const absl::optional<GURL>& direct_from_seller_auction_signals) override; + const absl::optional<std::string>& + direct_from_seller_per_buyer_signals_header_ad_slot, + const absl::optional<GURL>& direct_from_seller_auction_signals, + const absl::optional<std::string>& + direct_from_seller_auction_signals_header_ad_slot) override; private: struct GenerateBidTask { @@ -249,6 +257,12 @@ // DirectFromSellerSignals errors are fatal, so no error information is // stored here. + // Header-based DirectFromSellerSignals. + absl::optional<std::string> + direct_from_seller_per_buyer_signals_header_ad_slot; + absl::optional<std::string> + direct_from_seller_auction_signals_header_ad_slot; + mojo::AssociatedRemote<mojom::GenerateBidClient> generate_bid_client; }; @@ -300,6 +314,12 @@ // DirectFromSellerSignals errors are fatal, so no error information is // stored here. + // Header-based DirectFromSellerSignals. + absl::optional<std::string> + direct_from_seller_per_buyer_signals_header_ad_slot; + absl::optional<std::string> + direct_from_seller_auction_signals_header_ad_slot; + ReportWinCallback callback; }; @@ -398,8 +418,12 @@ const absl::optional<std::string>& per_buyer_signals_json, DirectFromSellerSignalsRequester::Result direct_from_seller_result_per_buyer_signals, + const absl::optional<std::string>& + direct_from_seller_per_buyer_signals_header_ad_slot, DirectFromSellerSignalsRequester::Result direct_from_seller_result_auction_signals, + const absl::optional<std::string>& + direct_from_seller_auction_signals_header_ad_slot, const std::string& seller_signals_json, mojom::KAnonymityBidMode kanon_mode, bool bid_is_kanon, @@ -429,8 +453,12 @@ const absl::optional<std::string>& per_buyer_signals_json, DirectFromSellerSignalsRequester::Result direct_from_seller_result_per_buyer_signals, + const absl::optional<std::string>& + direct_from_seller_per_buyer_signals_header_ad_slot, DirectFromSellerSignalsRequester::Result direct_from_seller_result_auction_signals, + const absl::optional<std::string>& + direct_from_seller_auction_signals_header_ad_slot, const absl::optional<base::TimeDelta> per_buyer_timeout, const absl::optional<blink::AdCurrency>& expected_buyer_currency, const url::Origin& browser_signal_seller_origin, @@ -463,8 +491,12 @@ const std::string* per_buyer_signals_json, const DirectFromSellerSignalsRequester::Result& direct_from_seller_result_per_buyer_signals, + const absl::optional<std::string>& + direct_from_seller_per_buyer_signals_header_ad_slot, const DirectFromSellerSignalsRequester::Result& direct_from_seller_result_auction_signals, + const absl::optional<std::string>& + direct_from_seller_auction_signals_header_ad_slot, const absl::optional<base::TimeDelta> per_buyer_timeout, const absl::optional<blink::AdCurrency>& expected_buyer_currency, const url::Origin& browser_signal_seller_origin,
diff --git a/content/services/auction_worklet/bidder_worklet_unittest.cc b/content/services/auction_worklet/bidder_worklet_unittest.cc index 2de1580..54fb06f6 100644 --- a/content/services/auction_worklet/bidder_worklet_unittest.cc +++ b/content/services/auction_worklet/bidder_worklet_unittest.cc
@@ -538,9 +538,12 @@ bidder_worklet->ReportWin( reporting_id_field_, reporting_id_, auction_signals_, per_buyer_signals_, direct_from_seller_per_buyer_signals_, - direct_from_seller_auction_signals_, seller_signals_, kanon_mode_, - bid_is_kanon_, browser_signal_render_url_, browser_signal_bid_, - browser_signal_bid_currency_, browser_signal_highest_scoring_other_bid_, + direct_from_seller_per_buyer_signals_header_ad_slot_, + direct_from_seller_auction_signals_, + direct_from_seller_auction_signals_header_ad_slot_, seller_signals_, + kanon_mode_, bid_is_kanon_, browser_signal_render_url_, + browser_signal_bid_, browser_signal_bid_currency_, + browser_signal_highest_scoring_other_bid_, browser_signal_highest_scoring_other_bid_currency_, browser_signal_made_highest_scoring_other_bid_, browser_signal_ad_cost_, browser_signal_modeling_signals_, browser_signal_join_count_, @@ -709,14 +712,17 @@ BeginGenerateBid(bidder_worklet, bid_finalizer.BindNewEndpointAndPassReceiver(), std::move(generate_bid_client)); - bid_finalizer->FinishGenerateBid(auction_signals_, per_buyer_signals_, - per_buyer_timeout_, per_buyer_currency_, - provide_direct_from_seller_signals_late_ - ? direct_from_seller_per_buyer_signals_ - : absl::nullopt, - provide_direct_from_seller_signals_late_ - ? direct_from_seller_auction_signals_ - : absl::nullopt); + bid_finalizer->FinishGenerateBid( + auction_signals_, per_buyer_signals_, per_buyer_timeout_, + per_buyer_currency_, + provide_direct_from_seller_signals_late_ + ? direct_from_seller_per_buyer_signals_ + : absl::nullopt, + direct_from_seller_per_buyer_signals_header_ad_slot_, + provide_direct_from_seller_signals_late_ + ? direct_from_seller_auction_signals_ + : absl::nullopt, + direct_from_seller_auction_signals_header_ad_slot_); } // Calls BeginGenerateBid()/FinishGenerateBid(), expecting the @@ -739,7 +745,9 @@ auction_signals_, per_buyer_signals_, per_buyer_timeout_, per_buyer_currency_, /*direct_from_seller_per_buyer_signals=*/absl::nullopt, - /*direct_from_seller_auction_signals=*/absl::nullopt); + /*direct_from_seller_per_buyer_signals_header_ad_slot=*/absl::nullopt, + /*direct_from_seller_auction_signals=*/absl::nullopt, + /*direct_from_seller_auction_signals_header_ad_slot=*/absl::nullopt); } // Create a BidderWorklet and invokes BeginGenerateBid()/FinishGenerateBid(), @@ -892,7 +900,11 @@ absl::optional<std::string> auction_signals_; absl::optional<std::string> per_buyer_signals_; absl::optional<GURL> direct_from_seller_per_buyer_signals_; + absl::optional<std::string> + direct_from_seller_per_buyer_signals_header_ad_slot_; absl::optional<GURL> direct_from_seller_auction_signals_; + absl::optional<std::string> + direct_from_seller_auction_signals_header_ad_slot_; absl::optional<base::TimeDelta> per_buyer_timeout_; absl::optional<blink::AdCurrency> per_buyer_currency_; url::Origin top_window_origin_; @@ -2610,7 +2622,9 @@ /*auction_signals_json=*/base::NumberToString(bid_value), per_buyer_signals_, per_buyer_timeout_, per_buyer_currency_, /*direct_from_seller_per_buyer_signals=*/absl::nullopt, - /*direct_from_seller_auction_signals=*/absl::nullopt); + /*direct_from_seller_per_buyer_signals_header_ad_slot=*/absl::nullopt, + /*direct_from_seller_auction_signals=*/absl::nullopt, + /*direct_from_seller_auction_signals_header_ad_slot=*/absl::nullopt); } // If this is the first loop iteration, wait for all the Mojo calls to @@ -2726,7 +2740,9 @@ auction_signals_, per_buyer_signals_, per_buyer_timeout_, per_buyer_currency_, /*direct_from_seller_per_buyer_signals=*/absl::nullopt, - /*direct_from_seller_auction_signals=*/absl::nullopt); + /*direct_from_seller_per_buyer_signals_header_ad_slot=*/absl::nullopt, + /*direct_from_seller_auction_signals=*/absl::nullopt, + /*direct_from_seller_auction_signals_header_ad_slot=*/absl::nullopt); } // This should trigger a single network request for all needed signals. bidder_worklet->SendPendingSignalsRequests(); @@ -2851,7 +2867,9 @@ auction_signals_, per_buyer_signals_, per_buyer_timeout_, per_buyer_currency_, /*direct_from_seller_per_buyer_signals=*/absl::nullopt, - /*direct_from_seller_auction_signals=*/absl::nullopt); + /*direct_from_seller_per_buyer_signals_header_ad_slot=*/absl::nullopt, + /*direct_from_seller_auction_signals=*/absl::nullopt, + /*direct_from_seller_auction_signals_header_ad_slot=*/absl::nullopt); } // This should trigger a single network request for all needed signals. bidder_worklet->SendPendingSignalsRequests(); @@ -2982,7 +3000,9 @@ auction_signals_, per_buyer_signals_, per_buyer_timeout_, per_buyer_currency_, /*direct_from_seller_per_buyer_signals=*/absl::nullopt, - /*direct_from_seller_auction_signals=*/absl::nullopt); + /*direct_from_seller_per_buyer_signals_header_ad_slot=*/absl::nullopt, + /*direct_from_seller_auction_signals=*/absl::nullopt, + /*direct_from_seller_auction_signals_header_ad_slot=*/absl::nullopt); } // This should trigger a single network request for all needed signals. bidder_worklet->SendPendingSignalsRequests(); @@ -3096,7 +3116,9 @@ auction_signals_, per_buyer_signals_, per_buyer_timeout_, per_buyer_currency_, /*direct_from_seller_per_buyer_signals=*/absl::nullopt, - /*direct_from_seller_auction_signals=*/absl::nullopt); + /*direct_from_seller_per_buyer_signals_header_ad_slot=*/absl::nullopt, + /*direct_from_seller_auction_signals=*/absl::nullopt, + /*direct_from_seller_auction_signals_header_ad_slot=*/absl::nullopt); } // Calling FinishGenerateBid() shouldn't cause any callbacks to be invoked - @@ -3359,6 +3381,58 @@ /*modeling_signals=*/absl::nullopt, base::TimeDelta())); } +TEST_F(BidderWorkletTest, + GenerateBidDirectFromSellerSignalsHeaderAdSlotAuctionSignals) { + const std::string kGenerateBidBody = + R"({ad: directFromSellerSignals.auctionSignals, + bid:1, render:"https://response.test/"})"; + + direct_from_seller_auction_signals_header_ad_slot_ = R"("foo")"; + RunGenerateBidWithReturnValueExpectingResult( + kGenerateBidBody, + mojom::BidderWorkletBid::New( + R"("foo")", 1, /*bid_currency=*/absl::nullopt, + /*ad_cost=*/absl::nullopt, + blink::AdDescriptor(GURL("https://response.test/")), + /*ad_component_descriptors=*/absl::nullopt, + /*modeling_signals=*/absl::nullopt, base::TimeDelta())); + + direct_from_seller_auction_signals_header_ad_slot_ = "[1]"; + RunGenerateBidWithReturnValueExpectingResult( + kGenerateBidBody, + mojom::BidderWorkletBid::New( + "[1]", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, + blink::AdDescriptor(GURL("https://response.test/")), + /*ad_component_descriptors=*/absl::nullopt, + /*modeling_signals=*/absl::nullopt, base::TimeDelta())); +} + +TEST_F(BidderWorkletTest, + GenerateBidDirectFromSellerSignalsHeaderAdSlotPerBuyerSignals) { + const std::string kGenerateBidBody = + R"({ad: directFromSellerSignals.perBuyerSignals, + bid:1, render:"https://response.test/"})"; + + direct_from_seller_per_buyer_signals_header_ad_slot_ = R"("foo")"; + RunGenerateBidWithReturnValueExpectingResult( + kGenerateBidBody, + mojom::BidderWorkletBid::New( + R"("foo")", 1, /*bid_currency=*/absl::nullopt, + /*ad_cost=*/absl::nullopt, + blink::AdDescriptor(GURL("https://response.test/")), + /*ad_component_descriptors=*/absl::nullopt, + /*modeling_signals=*/absl::nullopt, base::TimeDelta())); + + direct_from_seller_per_buyer_signals_header_ad_slot_ = "[1]"; + RunGenerateBidWithReturnValueExpectingResult( + kGenerateBidBody, + mojom::BidderWorkletBid::New( + "[1]", 1, /*bid_currency=*/absl::nullopt, /*ad_cost=*/absl::nullopt, + blink::AdDescriptor(GURL("https://response.test/")), + /*ad_component_descriptors=*/absl::nullopt, + /*modeling_signals=*/absl::nullopt, base::TimeDelta())); +} + TEST_F(BidderWorkletTest, GenerateBidBrowserSignalSellerOrigin) { browser_signal_seller_origin_ = url::Origin::Create(GURL("https://foo.test/")); @@ -3696,9 +3770,12 @@ bidder_worklet->ReportWin( reporting_id_field_, reporting_id_, /*auction_signals_json=*/"0", per_buyer_signals_, direct_from_seller_per_buyer_signals_, - direct_from_seller_auction_signals_, seller_signals_, kanon_mode_, - bid_is_kanon_, browser_signal_render_url_, browser_signal_bid_, - browser_signal_bid_currency_, browser_signal_highest_scoring_other_bid_, + direct_from_seller_per_buyer_signals_header_ad_slot_, + direct_from_seller_auction_signals_, + direct_from_seller_auction_signals_header_ad_slot_, seller_signals_, + kanon_mode_, bid_is_kanon_, browser_signal_render_url_, + browser_signal_bid_, browser_signal_bid_currency_, + browser_signal_highest_scoring_other_bid_, browser_signal_highest_scoring_other_bid_currency_, browser_signal_made_highest_scoring_other_bid_, browser_signal_ad_cost_, browser_signal_modeling_signals_, browser_signal_join_count_, @@ -5091,9 +5168,12 @@ bidder_worklet->ReportWin( reporting_id_field_, reporting_id_, auction_signals_, per_buyer_signals_, direct_from_seller_per_buyer_signals_, - direct_from_seller_auction_signals_, seller_signals_, kanon_mode_, - bid_is_kanon_, browser_signal_render_url_, browser_signal_bid_, - browser_signal_bid_currency_, browser_signal_highest_scoring_other_bid_, + direct_from_seller_per_buyer_signals_header_ad_slot_, + direct_from_seller_auction_signals_, + direct_from_seller_auction_signals_header_ad_slot_, seller_signals_, + kanon_mode_, bid_is_kanon_, browser_signal_render_url_, + browser_signal_bid_, browser_signal_bid_currency_, + browser_signal_highest_scoring_other_bid_, browser_signal_highest_scoring_other_bid_currency_, browser_signal_made_highest_scoring_other_bid_, browser_signal_ad_cost_, browser_signal_modeling_signals_, browser_signal_join_count_, @@ -5143,9 +5223,11 @@ reporting_id_field_, reporting_id_, /*auction_signals_json=*/base::NumberToString(i), per_buyer_signals_, direct_from_seller_per_buyer_signals_, - direct_from_seller_auction_signals_, seller_signals_, kanon_mode_, - bid_is_kanon_, browser_signal_render_url_, browser_signal_bid_, - browser_signal_bid_currency_, + direct_from_seller_per_buyer_signals_header_ad_slot_, + direct_from_seller_auction_signals_, + direct_from_seller_auction_signals_header_ad_slot_, seller_signals_, + kanon_mode_, bid_is_kanon_, browser_signal_render_url_, + browser_signal_bid_, browser_signal_bid_currency_, browser_signal_highest_scoring_other_bid_, browser_signal_highest_scoring_other_bid_currency_, browser_signal_made_highest_scoring_other_bid_, @@ -5197,9 +5279,12 @@ reporting_id_field_, reporting_id_, /*auction_signals_json=*/base::NumberToString(i), per_buyer_signals_, direct_from_seller_per_buyer_signals_, - direct_from_seller_auction_signals_, seller_signals_, kanon_mode_, - bid_is_kanon_, browser_signal_render_url_, browser_signal_bid_, - browser_signal_bid_currency_, browser_signal_highest_scoring_other_bid_, + direct_from_seller_per_buyer_signals_header_ad_slot_, + direct_from_seller_auction_signals_, + direct_from_seller_auction_signals_header_ad_slot_, seller_signals_, + kanon_mode_, bid_is_kanon_, browser_signal_render_url_, + browser_signal_bid_, browser_signal_bid_currency_, + browser_signal_highest_scoring_other_bid_, browser_signal_highest_scoring_other_bid_currency_, browser_signal_made_highest_scoring_other_bid_, browser_signal_ad_cost_, browser_signal_modeling_signals_, browser_signal_join_count_, @@ -5379,6 +5464,36 @@ "sendReportTo(sellerSignals)", GURL("https://interest.group.name.test/")); } +TEST_F(BidderWorkletTest, + ReportWinDirectFromSellerSignalsHeaderAdSlotAuctionSignals) { + direct_from_seller_auction_signals_header_ad_slot_ = + R"("https://interest.group.name.test/")"; + RunReportWinWithFunctionBodyExpectingResult( + "sendReportTo(directFromSellerSignals.auctionSignals)", + GURL("https://interest.group.name.test/")); + + direct_from_seller_auction_signals_header_ad_slot_ = absl::nullopt; + RunReportWinWithFunctionBodyExpectingResult( + R"(sendReportTo("https://" + + (directFromSellerSignals.auctionSignals === null)))", + GURL("https://true/")); +} + +TEST_F(BidderWorkletTest, + ReportWinDirectFromSellerSignalsHeaderAdSlotPerBuyerSignals) { + direct_from_seller_per_buyer_signals_header_ad_slot_ = + R"("https://interest.group.name.test/")"; + RunReportWinWithFunctionBodyExpectingResult( + "sendReportTo(directFromSellerSignals.perBuyerSignals)", + GURL("https://interest.group.name.test/")); + + direct_from_seller_per_buyer_signals_header_ad_slot_ = absl::nullopt; + RunReportWinWithFunctionBodyExpectingResult( + R"(sendReportTo("https://" + + (directFromSellerSignals.perBuyerSignals === null)))", + GURL("https://true/")); +} + TEST_F(BidderWorkletTest, ReportWinInterestGroupOwner) { interest_group_bidding_url_ = GURL("https://foo.test/bar"); // Add an extra ".test" because origin's shouldn't have a terminal slash, @@ -5622,9 +5737,12 @@ bidder_worklet->ReportWin( reporting_id_field_, reporting_id_, auction_signals_, per_buyer_signals_, direct_from_seller_per_buyer_signals_, - direct_from_seller_auction_signals_, seller_signals_, kanon_mode_, - bid_is_kanon_, browser_signal_render_url_, browser_signal_bid_, - browser_signal_bid_currency_, browser_signal_highest_scoring_other_bid_, + direct_from_seller_per_buyer_signals_header_ad_slot_, + direct_from_seller_auction_signals_, + direct_from_seller_auction_signals_header_ad_slot_, seller_signals_, + kanon_mode_, bid_is_kanon_, browser_signal_render_url_, + browser_signal_bid_, browser_signal_bid_currency_, + browser_signal_highest_scoring_other_bid_, browser_signal_highest_scoring_other_bid_currency_, browser_signal_made_highest_scoring_other_bid_, browser_signal_ad_cost_, browser_signal_modeling_signals_, browser_signal_join_count_, @@ -6386,9 +6504,12 @@ bidder_worklet->ReportWin( reporting_id_field_, reporting_id_, auction_signals_, per_buyer_signals_, direct_from_seller_per_buyer_signals_, - direct_from_seller_auction_signals_, seller_signals_, kanon_mode_, - bid_is_kanon_, browser_signal_render_url_, browser_signal_bid_, - browser_signal_bid_currency_, browser_signal_highest_scoring_other_bid_, + direct_from_seller_per_buyer_signals_header_ad_slot_, + direct_from_seller_auction_signals_, + direct_from_seller_auction_signals_header_ad_slot_, seller_signals_, + kanon_mode_, bid_is_kanon_, browser_signal_render_url_, + browser_signal_bid_, browser_signal_bid_currency_, + browser_signal_highest_scoring_other_bid_, browser_signal_highest_scoring_other_bid_currency_, browser_signal_made_highest_scoring_other_bid_, browser_signal_ad_cost_, browser_signal_modeling_signals_, browser_signal_join_count_, @@ -8127,7 +8248,9 @@ auction_signals_, per_buyer_signals_, per_buyer_timeout_, per_buyer_currency_, /*direct_from_seller_per_buyer_signals=*/absl::nullopt, - /*direct_from_seller_auction_signals=*/absl::nullopt); + /*direct_from_seller_per_buyer_signals_header_ad_slot=*/absl::nullopt, + /*direct_from_seller_auction_signals=*/absl::nullopt, + /*direct_from_seller_auction_signals_header_ad_slot=*/absl::nullopt); load_script_run_loop_ = std::make_unique<base::RunLoop>(); load_script_run_loop_->Run(); ASSERT_TRUE(bid_); @@ -8166,7 +8289,9 @@ auction_signals_, per_buyer_signals_, per_buyer_timeout_, per_buyer_currency_, /*direct_from_seller_per_buyer_signals=*/absl::nullopt, - /*direct_from_seller_auction_signals=*/absl::nullopt); + /*direct_from_seller_per_buyer_signals_header_ad_slot=*/absl::nullopt, + /*direct_from_seller_auction_signals=*/absl::nullopt, + /*direct_from_seller_auction_signals_header_ad_slot=*/absl::nullopt); task_environment_.RunUntilIdle(); EXPECT_FALSE(bid_); @@ -8233,7 +8358,9 @@ auction_signals_, per_buyer_signals_, per_buyer_timeout_, per_buyer_currency_, /*direct_from_seller_per_buyer_signals=*/absl::nullopt, - /*direct_from_seller_auction_signals=*/absl::nullopt); + /*direct_from_seller_per_buyer_signals_header_ad_slot=*/absl::nullopt, + /*direct_from_seller_auction_signals=*/absl::nullopt, + /*direct_from_seller_auction_signals_header_ad_slot=*/absl::nullopt); load_script_run_loop_ = std::make_unique<base::RunLoop>(); load_script_run_loop_->Run(); ASSERT_TRUE(bid_);
diff --git a/content/services/auction_worklet/direct_from_seller_signals_requester.cc b/content/services/auction_worklet/direct_from_seller_signals_requester.cc index 68c619f..879b2a82 100644 --- a/content/services/auction_worklet/direct_from_seller_signals_requester.cc +++ b/content/services/auction_worklet/direct_from_seller_signals_requester.cc
@@ -132,6 +132,18 @@ return v8_result.ToLocalChecked(); } +bool DirectFromSellerSignalsRequester::Result::IsNull() const { + if (absl::holds_alternative<ErrorString>(response_or_error_)) { + return false; + } + + DCHECK(absl::holds_alternative<scoped_refptr<ResponseString>>( + response_or_error_)); + scoped_refptr<ResponseString> response = + absl::get<scoped_refptr<ResponseString>>(response_or_error_); + return response == nullptr; +} + DirectFromSellerSignalsRequester::Result::ResponseString::ResponseString( std::string&& other) : value_(std::move(other)) {}
diff --git a/content/services/auction_worklet/direct_from_seller_signals_requester.h b/content/services/auction_worklet/direct_from_seller_signals_requester.h index 91959cb..c46223e 100644 --- a/content/services/auction_worklet/direct_from_seller_signals_requester.h +++ b/content/services/auction_worklet/direct_from_seller_signals_requester.h
@@ -68,6 +68,10 @@ v8::Local<v8::Context> context, std::vector<std::string>& errors) const; + // Returns true if this Result is a null value, and false otherwise. Returns + // false if Result is an error. + bool IsNull() const; + private: // Private methods are called by DirectFromSellerSignalsRequester. friend DirectFromSellerSignalsRequester;
diff --git a/content/services/auction_worklet/public/mojom/bidder_worklet.mojom b/content/services/auction_worklet/public/mojom/bidder_worklet.mojom index 51957f058..1fd6214 100644 --- a/content/services/auction_worklet/public/mojom/bidder_worklet.mojom +++ b/content/services/auction_worklet/public/mojom/bidder_worklet.mojom
@@ -322,15 +322,27 @@ // page. Null will be passed to the worklet in that case. // // See BeginGenerateBid for description of - // `direct_from_seller_per_buyer_signals`, ` + // `direct_from_seller_per_buyer_signals`, // `direct_from_seller_auction_signals` + // + // `direct_from_seller_per_buyer_signals_header_ad_slot` A JSON string of the + // DirectFromSellerSignals for this specific buyer. Must not be passed if + // `direct_from_seller_per_buyer_signals` or + // `direct_from_seller_auction_signals` is passed. + // + // `direct_from_seller_auction_signals_header_ad_slot` A JSON string of the + // DirectFromSellerSignals for the seller and all buyers. Must not be passed + // if `direct_from_seller_auction_signals` or + // `direct_from_seller_per_buyer_signals` is passed. FinishGenerateBid( string? auction_signals_json, string? per_buyer_signals_json, mojo_base.mojom.TimeDelta? per_buyer_timeout, blink.mojom.AdCurrency? expected_buyer_currency, url.mojom.Url? direct_from_seller_per_buyer_signals, - url.mojom.Url? direct_from_seller_auction_signals); + string? direct_from_seller_per_buyer_signals_header_ad_slot, + url.mojom.Url? direct_from_seller_auction_signals, + string? direct_from_seller_auction_signals_header_ad_slot); }; // Manages the auction workflow for one loaded FLEDGE bidder worklet. @@ -369,19 +381,19 @@ // was joined; can affect context reuse in certain execution modes. // // `direct_from_seller_per_buyer_signals` The subresource URL of the - // DirectFromSellerSignals for the specific owner of this interest group, as - // produced by concatenating the `directFromSellerSignals` URL prefix field - // passed from runAdAuction() with "?perBuyerSignals=[buyer]" for the - // URL-encoded buyer origin for this buyer. Since this is fetched from a - // subresource bundle, it may only be fetched using the URLLoaderFactory - // passed in when creating the worklet. + // DirectFromSellerSignals for the specific owner of this interest group, as + // produced by concatenating the `directFromSellerSignals` URL prefix field + // passed from runAdAuction() with "?perBuyerSignals=[buyer]" for the + // URL-encoded buyer origin for this buyer. Since this is fetched from a + // subresource bundle, it may only be fetched using the URLLoaderFactory + // passed in when creating the worklet. // // `direct_from_seller_auction_signals` The subresource URL of the - // DirectFromSellerSignals for the seller and all buyers, as produced by - // concatenating the `directFromSellerSignals` URL prefix field passed from - // runAdAuction() with "?auctionSignals". Since this is fetched from a - // subresource bundle, it may only be fetched using the URLLoaderFactory - // passed in when creating the worklet. + // DirectFromSellerSignals for the seller and all buyers, as produced by + // concatenating the `directFromSellerSignals` URL prefix field passed from + // runAdAuction() with "?auctionSignals". Since this is fetched from a + // subresource bundle, it may only be fetched using the URLLoaderFactory + // passed in when creating the worklet. // // Both `direct_from_seller_auction_signals` and // `direct_from_seller_per_buyer_signals` can alternatively be passed as @@ -472,6 +484,11 @@ // subresource bundle, it may only be fetched using the URLLoaderFactory // passed in when creating the worklet. // + // `direct_from_seller_per_buyer_signals_header_ad_slot` A JSON string of the + // DirectFromSellerSignals for this specific buyer. Must not be passed if + // `direct_from_seller_per_buyer_signals` or + // `direct_from_seller_auction_signals` is passed. + // // `direct_from_seller_auction_signals` The subresource URL of the // DirectFromSellerSignals for the seller and all buyers, as produced by // concatenating the `directFromSellerSignals` URL prefix field passed from @@ -479,6 +496,11 @@ // subresource bundle, it may only be fetched using the URLLoaderFactory // passed in when creating the worklet. // + // `direct_from_seller_auction_signals_header_ad_slot` A JSON string of the + // DirectFromSellerSignals for the seller and all buyers. Must not be passed + // if `direct_from_seller_auction_signals` or + // `direct_from_seller_per_buyer_signals` is passed. + // // `seller_signals_json` is a JSON representation of the object returned by // the seller worklet's ReportResult method. // @@ -571,7 +593,9 @@ string? auction_signals_json, string? per_buyer_signals_json, url.mojom.Url? direct_from_seller_per_buyer_signals, + string? direct_from_seller_per_buyer_signals_header_ad_slot, url.mojom.Url? direct_from_seller_auction_signals, + string? direct_from_seller_auction_signals_header_ad_slot, string seller_signals_json, KAnonymityBidMode kanon_mode, bool bid_is_kanon,
diff --git a/content/services/auction_worklet/public/mojom/seller_worklet.mojom b/content/services/auction_worklet/public/mojom/seller_worklet.mojom index f61806a9..0688a40 100644 --- a/content/services/auction_worklet/public/mojom/seller_worklet.mojom +++ b/content/services/auction_worklet/public/mojom/seller_worklet.mojom
@@ -167,18 +167,28 @@ // vary between auctions that can share a SellerWorklet. // // `direct_from_seller_seller_signals` The subresource URL of the - // DirectFromSellerSignals for the seller, as produced by concatenating the - // `directFromSellerSignals` URL prefix field passed from runAdAuction() with - // "?sellerSignals". Since this is fetched from a subresource bundle, it may - // only be fetched using the URLLoaderFactory passed in when creating the - // worklet. + // DirectFromSellerSignals for the seller, as produced by concatenating the + // `directFromSellerSignals` URL prefix field passed from runAdAuction() with + // "?sellerSignals". Since this is fetched from a subresource bundle, it may + // only be fetched using the URLLoaderFactory passed in when creating the + // worklet. + // + // `direct_from_seller_seller_signals_header_ad_slot` A JSON string of the + // DirectFromSellerSignals for the seller. Must not be passed if + // `direct_from_seller_seller_signals` or + // `direct_from_seller_auction_signals` is passed. // // `direct_from_seller_auction_signals` The subresource URL of the - // directFromSellerSignals for the seller and all buyers, as produced by - // concatenating the `directFromSellerSignals` URL prefix field passed from - // runAdAuction() with "?auctionSignals". Since this is fetched from a - // subresource bundle, it may only be fetched using the URLLoaderFactory - // passed in when creating the worklet. + // directFromSellerSignals for the seller and all buyers, as produced by + // concatenating the `directFromSellerSignals` URL prefix field passed from + // runAdAuction() with "?auctionSignals". Since this is fetched from a + // subresource bundle, it may only be fetched using the URLLoaderFactory + // passed in when creating the worklet. + // + // `direct_from_seller_auction_signals_header_ad_slot` A JSON string of the + // DirectFromSellerSignals for the seller and all buyers. Must not be passed + // if `direct_from_seller_auction_signals` or + // `direct_from_seller_seller_signals` is passed. // // `browser_signals_other_seller` The origin of the other seller associated // with the bid. If this is a component seller worklet, it's the @@ -219,7 +229,9 @@ blink.mojom.AuctionAdConfigNonSharedParams auction_ad_config_non_shared_params, url.mojom.Url? direct_from_seller_seller_signals, + string? direct_from_seller_seller_signals_header_ad_slot, url.mojom.Url? direct_from_seller_auction_signals, + string? direct_from_seller_auction_signals_header_ad_slot, ComponentAuctionOtherSeller? browser_signals_other_seller, blink.mojom.AdCurrency? component_expect_bid_currency, url.mojom.Origin browser_signal_interest_group_owner, @@ -252,18 +264,28 @@ // vary between auctions that can share a SellerWorklet. // // `direct_from_seller_seller_signals` The subresource URL of the - // DirectFromSellerSignals for the seller, as produced by concatenating the - // `directFromSellerSignals` URL prefix field passed from runAdAuction() with - // "?sellerSignals". Since this is fetched from a subresource bundle, it may - // only be fetched using the URLLoaderFactory passed in when creating the - // worklet. + // DirectFromSellerSignals for the seller, as produced by concatenating the + // `directFromSellerSignals` URL prefix field passed from runAdAuction() with + // "?sellerSignals". Since this is fetched from a subresource bundle, it may + // only be fetched using the URLLoaderFactory passed in when creating the + // worklet. + // + // `direct_from_seller_seller_signals_header_ad_slot` A JSON string of the + // DirectFromSellerSignals for the seller. Must not be passed if + // `direct_from_seller_seller_signals` or + // `direct_from_seller_auction_signals` is passed. // // `direct_from_seller_auction_signals` The subresource URL of the - // directFromSellerSignals for the seller and all buyers, as produced by - // concatenating the `directFromSellerSignals` URL prefix field passed from - // runAdAuction() with "?auctionSignals". Since this is fetched from a - // subresource bundle, it may only be fetched using the URLLoaderFactory - // passed in when creating the worklet. + // directFromSellerSignals for the seller and all buyers, as produced by + // concatenating the `directFromSellerSignals` URL prefix field passed from + // runAdAuction() with "?auctionSignals". Since this is fetched from a + // subresource bundle, it may only be fetched using the URLLoaderFactory + // passed in when creating the worklet. + // + // `direct_from_seller_auction_signals_header_ad_slot` A JSON string of the + // DirectFromSellerSignals for the seller and all buyers. Must not be passed + // if `direct_from_seller_auction_signals` or + // `direct_from_seller_seller_signals` is passed. // // `browser_signals_other_seller` The origin of the other seller associated // with the bid. If this is a component seller worklet, it's the @@ -339,7 +361,9 @@ blink.mojom.AuctionAdConfigNonSharedParams auction_ad_config_non_shared_params, url.mojom.Url? direct_from_seller_seller_signals, + string? direct_from_seller_seller_signals_header_ad_slot, url.mojom.Url? direct_from_seller_auction_signals, + string? direct_from_seller_auction_signals_header_ad_slot, ComponentAuctionOtherSeller? browser_signals_other_seller, url.mojom.Origin browser_signal_interest_group_owner, string? browser_signal_buyer_and_seller_reporting_id,
diff --git a/content/services/auction_worklet/seller_worklet.cc b/content/services/auction_worklet/seller_worklet.cc index 4533e682..4c3a667a 100644 --- a/content/services/auction_worklet/seller_worklet.cc +++ b/content/services/auction_worklet/seller_worklet.cc
@@ -60,6 +60,29 @@ namespace { +// Checks both types of DirectFromSellerSignals results (subresource bundle +// based and header based) -- at most one of these should be non-null. +// +// Returns the V8 conversion of the in-use version of DirectFromSellerSignals, +// or v8::Null() if both types of DirectFromSellerSignals are null. +v8::Local<v8::Value> GetDirectFromSellerSignals( + const DirectFromSellerSignalsRequester::Result& subresource_bundle_result, + const absl::optional<std::string>& header_result, + AuctionV8Helper& v8_helper, + v8::Local<v8::Context> context, + std::vector<std::string>& errors) { + CHECK(subresource_bundle_result.IsNull() || !header_result); + + if (header_result) { + // `header_result` JSON was validated, parsed and reconstructed into a + // string by the browser process, so CHECK it is valid JSON. + return v8_helper.CreateValueFromJson(context, *header_result) + .ToLocalChecked(); + } + + return subresource_bundle_result.GetSignals(v8_helper, context, errors); +} + // TODO(crbug.com/1441988): Remove this code after rename. These functions allow // having multiple dictionary keys (e.g. renderUrl and renderURL) share the same // V8 value. @@ -596,7 +619,11 @@ const blink::AuctionConfig::NonSharedParams& auction_ad_config_non_shared_params, const absl::optional<GURL>& direct_from_seller_seller_signals, + const absl::optional<std::string>& + direct_from_seller_seller_signals_header_ad_slot, const absl::optional<GURL>& direct_from_seller_auction_signals, + const absl::optional<std::string>& + direct_from_seller_auction_signals_header_ad_slot, mojom::ComponentAuctionOtherSellerPtr browser_signals_other_seller, const absl::optional<blink::AdCurrency>& component_expect_bid_currency, const url::Origin& browser_signal_interest_group_owner, @@ -607,6 +634,10 @@ uint64_t trace_id, mojo::PendingRemote<auction_worklet::mojom::ScoreAdClient> score_ad_client) { + CHECK((!direct_from_seller_seller_signals && + !direct_from_seller_auction_signals) || + (!direct_from_seller_seller_signals_header_ad_slot && + !direct_from_seller_auction_signals_header_ad_slot)); DCHECK_CALLED_ON_VALID_SEQUENCE(user_sequence_checker_); score_ad_tasks_.emplace_front(); @@ -668,6 +699,10 @@ score_ad_task->direct_from_seller_result_auction_signals = DirectFromSellerSignalsRequester::Result(); } + score_ad_task->direct_from_seller_seller_signals_header_ad_slot = + direct_from_seller_seller_signals_header_ad_slot; + score_ad_task->direct_from_seller_auction_signals_header_ad_slot = + direct_from_seller_auction_signals_header_ad_slot; score_ad_task->trace_wait_deps_start = base::TimeTicks::Now(); TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("fledge", "wait_score_ad_deps", trace_id); @@ -697,7 +732,11 @@ const blink::AuctionConfig::NonSharedParams& auction_ad_config_non_shared_params, const absl::optional<GURL>& direct_from_seller_seller_signals, + const absl::optional<std::string>& + direct_from_seller_seller_signals_header_ad_slot, const absl::optional<GURL>& direct_from_seller_auction_signals, + const absl::optional<std::string>& + direct_from_seller_auction_signals_header_ad_slot, mojom::ComponentAuctionOtherSellerPtr browser_signals_other_seller, const url::Origin& browser_signal_interest_group_owner, const absl::optional<std::string>& @@ -715,6 +754,10 @@ bool has_scoring_signals_data_version, uint64_t trace_id, ReportResultCallback callback) { + CHECK((!direct_from_seller_seller_signals && + !direct_from_seller_auction_signals) || + (!direct_from_seller_seller_signals_header_ad_slot && + !direct_from_seller_auction_signals_header_ad_slot)); DCHECK_CALLED_ON_VALID_SEQUENCE(user_sequence_checker_); // `browser_signals_component_auction_report_result_params` should only be // populated for sellers in component auctions, which are the only case where @@ -786,6 +829,10 @@ report_result_task->direct_from_seller_result_auction_signals = DirectFromSellerSignalsRequester::Result(); } + report_result_task->direct_from_seller_seller_signals_header_ad_slot = + direct_from_seller_seller_signals_header_ad_slot; + report_result_task->direct_from_seller_auction_signals_header_ad_slot = + direct_from_seller_auction_signals_header_ad_slot; report_result_task->trace_wait_deps_start = base::TimeTicks::Now(); TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("fledge", "wait_report_result_deps", @@ -848,8 +895,12 @@ auction_ad_config_non_shared_params, DirectFromSellerSignalsRequester::Result direct_from_seller_result_seller_signals, + const absl::optional<std::string>& + direct_from_seller_seller_signals_header_ad_slot, DirectFromSellerSignalsRequester::Result direct_from_seller_result_auction_signals, + const absl::optional<std::string>& + direct_from_seller_auction_signals_header_ad_slot, scoped_refptr<TrustedSignals::Result> trusted_scoring_signals, mojom::ComponentAuctionOtherSellerPtr browser_signals_other_seller, const absl::optional<blink::AdCurrency>& component_expect_bid_currency, @@ -953,12 +1004,14 @@ gin::Dictionary direct_from_seller_signals_dict(isolate, direct_from_seller_signals); std::vector<std::string> errors_out; - v8::Local<v8::Value> seller_signals = - direct_from_seller_result_seller_signals.GetSignals(*v8_helper_, context, - errors_out); - v8::Local<v8::Value> auction_signals = - direct_from_seller_result_auction_signals.GetSignals(*v8_helper_, context, - errors_out); + v8::Local<v8::Value> seller_signals = GetDirectFromSellerSignals( + direct_from_seller_result_seller_signals, + direct_from_seller_seller_signals_header_ad_slot, *v8_helper_, context, + errors_out); + v8::Local<v8::Value> auction_signals = GetDirectFromSellerSignals( + direct_from_seller_result_auction_signals, + direct_from_seller_auction_signals_header_ad_slot, *v8_helper_, context, + errors_out); if (!direct_from_seller_signals_dict.Set("sellerSignals", seller_signals) || !direct_from_seller_signals_dict.Set("auctionSignals", auction_signals)) { PostScoreAdCallbackToUserThreadOnError( @@ -1297,8 +1350,12 @@ auction_ad_config_non_shared_params, DirectFromSellerSignalsRequester::Result direct_from_seller_result_seller_signals, + const absl::optional<std::string>& + direct_from_seller_seller_signals_header_ad_slot, DirectFromSellerSignalsRequester::Result direct_from_seller_result_auction_signals, + const absl::optional<std::string>& + direct_from_seller_auction_signals_header_ad_slot, mojom::ComponentAuctionOtherSellerPtr browser_signals_other_seller, const url::Origin& browser_signal_interest_group_owner, const absl::optional<std::string>& @@ -1408,12 +1465,14 @@ v8::Local<v8::Object> direct_from_seller_signals = v8::Object::New(isolate); gin::Dictionary direct_from_seller_signals_dict(isolate, direct_from_seller_signals); - v8::Local<v8::Value> seller_signals = - direct_from_seller_result_seller_signals.GetSignals(*v8_helper_, context, - errors_out); - v8::Local<v8::Value> auction_signals = - direct_from_seller_result_auction_signals.GetSignals(*v8_helper_, context, - errors_out); + v8::Local<v8::Value> seller_signals = GetDirectFromSellerSignals( + direct_from_seller_result_seller_signals, + direct_from_seller_seller_signals_header_ad_slot, *v8_helper_, context, + errors_out); + v8::Local<v8::Value> auction_signals = GetDirectFromSellerSignals( + direct_from_seller_result_auction_signals, + direct_from_seller_auction_signals_header_ad_slot, *v8_helper_, context, + errors_out); if (!direct_from_seller_signals_dict.Set("sellerSignals", seller_signals) || !direct_from_seller_signals_dict.Set("auctionSignals", auction_signals)) { PostReportResultCallbackToUserThread(std::move(callback), @@ -1778,7 +1837,9 @@ task->ad_metadata_json, task->bid, std::move(task->bid_currency), std::move(task->auction_ad_config_non_shared_params), std::move(task->direct_from_seller_result_seller_signals), + std::move(task->direct_from_seller_seller_signals_header_ad_slot), std::move(task->direct_from_seller_result_auction_signals), + std::move(task->direct_from_seller_auction_signals_header_ad_slot), std::move(task->trusted_scoring_signals_result), std::move(task->browser_signals_other_seller), std::move(task->component_expect_bid_currency), @@ -1904,7 +1965,9 @@ base::Unretained(v8_state_.get()), std::move(task->auction_ad_config_non_shared_params), std::move(task->direct_from_seller_result_seller_signals), + std::move(task->direct_from_seller_seller_signals_header_ad_slot), std::move(task->direct_from_seller_result_auction_signals), + std::move(task->direct_from_seller_auction_signals_header_ad_slot), std::move(task->browser_signals_other_seller), std::move(task->browser_signal_interest_group_owner), std::move(task->browser_signal_buyer_and_seller_reporting_id),
diff --git a/content/services/auction_worklet/seller_worklet.h b/content/services/auction_worklet/seller_worklet.h index 58664341..fb52af8 100644 --- a/content/services/auction_worklet/seller_worklet.h +++ b/content/services/auction_worklet/seller_worklet.h
@@ -100,7 +100,11 @@ const blink::AuctionConfig::NonSharedParams& auction_ad_config_non_shared_params, const absl::optional<GURL>& direct_from_seller_seller_signals, + const absl::optional<std::string>& + direct_from_seller_seller_signals_header_ad_slot, const absl::optional<GURL>& direct_from_seller_auction_signals, + const absl::optional<std::string>& + direct_from_seller_auction_signals_header_ad_slot, mojom::ComponentAuctionOtherSellerPtr browser_signals_other_seller, const absl::optional<blink::AdCurrency>& component_expect_bid_currency, const url::Origin& browser_signal_interest_group_owner, @@ -116,7 +120,11 @@ const blink::AuctionConfig::NonSharedParams& auction_ad_config_non_shared_params, const absl::optional<GURL>& direct_from_seller_seller_signals, + const absl::optional<std::string>& + direct_from_seller_seller_signals_header_ad_slot, const absl::optional<GURL>& direct_from_seller_auction_signals, + const absl::optional<std::string>& + direct_from_seller_auction_signals_header_ad_slot, mojom::ComponentAuctionOtherSellerPtr browser_signals_other_seller, const url::Origin& browser_signal_interest_group_owner, const absl::optional<std::string>& @@ -196,6 +204,12 @@ direct_from_seller_result_auction_signals; // DirectFromSellerSignals errors are fatal, so no error information is // stored here. + + // Header-based DirectFromSellerSignals. + absl::optional<std::string> + direct_from_seller_seller_signals_header_ad_slot; + absl::optional<std::string> + direct_from_seller_auction_signals_header_ad_slot; }; using ScoreAdTaskList = std::list<ScoreAdTask>; @@ -244,6 +258,12 @@ // DirectFromSellerSignals errors are fatal, so no error information is // stored here. + // Header-based DirectFromSellerSignals. + absl::optional<std::string> + direct_from_seller_seller_signals_header_ad_slot; + absl::optional<std::string> + direct_from_seller_auction_signals_header_ad_slot; + ReportResultCallback callback; }; @@ -299,8 +319,12 @@ auction_ad_config_non_shared_params, DirectFromSellerSignalsRequester::Result direct_from_seller_result_seller_signals, + const absl::optional<std::string>& + direct_from_seller_seller_signals_header_ad_slot, DirectFromSellerSignalsRequester::Result direct_from_seller_result_auction_signals, + const absl::optional<std::string>& + direct_from_seller_auction_signals_header_ad_slot, scoped_refptr<TrustedSignals::Result> trusted_scoring_signals, mojom::ComponentAuctionOtherSellerPtr browser_signals_other_seller, const absl::optional<blink::AdCurrency>& component_expect_bid_currency, @@ -318,8 +342,12 @@ auction_ad_config_non_shared_params, DirectFromSellerSignalsRequester::Result direct_from_seller_result_seller_signals, + const absl::optional<std::string>& + direct_from_seller_seller_signals_header_ad_slot, DirectFromSellerSignalsRequester::Result direct_from_seller_result_auction_signals, + const absl::optional<std::string>& + direct_from_seller_auction_signals_header_ad_slot, mojom::ComponentAuctionOtherSellerPtr browser_signals_other_seller, const url::Origin& browser_signal_interest_group_owner, const absl::optional<std::string>&
diff --git a/content/services/auction_worklet/seller_worklet_unittest.cc b/content/services/auction_worklet/seller_worklet_unittest.cc index abc7fc3..f8d6377 100644 --- a/content/services/auction_worklet/seller_worklet_unittest.cc +++ b/content/services/auction_worklet/seller_worklet_unittest.cc
@@ -366,7 +366,10 @@ base::OnceClosure done_closure) { seller_worklet->ScoreAd( ad_metadata_, bid_, bid_currency_, auction_ad_config_non_shared_params_, - direct_from_seller_seller_signals_, direct_from_seller_auction_signals_, + direct_from_seller_seller_signals_, + direct_from_seller_seller_signals_header_ad_slot_, + direct_from_seller_auction_signals_, + direct_from_seller_auction_signals_header_ad_slot_, browser_signals_other_seller_.Clone(), component_expect_bid_currency_, browser_signal_interest_group_owner_, browser_signal_render_url_, browser_signal_ad_components_, browser_signal_bidding_duration_msecs_, @@ -458,7 +461,10 @@ mojom::SellerWorklet* seller_worklet) { seller_worklet->ScoreAd( ad_metadata_, bid_, bid_currency_, auction_ad_config_non_shared_params_, - direct_from_seller_seller_signals_, direct_from_seller_auction_signals_, + direct_from_seller_seller_signals_, + direct_from_seller_seller_signals_header_ad_slot_, + direct_from_seller_auction_signals_, + direct_from_seller_auction_signals_header_ad_slot_, browser_signals_other_seller_.Clone(), component_expect_bid_currency_, browser_signal_interest_group_owner_, browser_signal_render_url_, browser_signal_ad_components_, browser_signal_bidding_duration_msecs_, @@ -579,7 +585,10 @@ base::OnceClosure done_closure) { seller_worklet->ReportResult( auction_ad_config_non_shared_params_, - direct_from_seller_seller_signals_, direct_from_seller_auction_signals_, + direct_from_seller_seller_signals_, + direct_from_seller_seller_signals_header_ad_slot_, + direct_from_seller_auction_signals_, + direct_from_seller_auction_signals_header_ad_slot_, browser_signals_other_seller_.Clone(), browser_signal_interest_group_owner_, browser_signal_buyer_and_seller_reporting_id_, @@ -637,7 +646,10 @@ mojom::SellerWorklet* seller_worklet) { seller_worklet->ReportResult( auction_ad_config_non_shared_params_, - direct_from_seller_seller_signals_, direct_from_seller_auction_signals_, + direct_from_seller_seller_signals_, + direct_from_seller_seller_signals_header_ad_slot_, + direct_from_seller_auction_signals_, + direct_from_seller_auction_signals_header_ad_slot_, browser_signals_other_seller_.Clone(), browser_signal_interest_group_owner_, browser_signal_buyer_and_seller_reporting_id_, @@ -768,7 +780,10 @@ absl::optional<GURL> trusted_scoring_signals_url_; blink::AuctionConfig::NonSharedParams auction_ad_config_non_shared_params_; absl::optional<GURL> direct_from_seller_seller_signals_; + absl::optional<std::string> direct_from_seller_seller_signals_header_ad_slot_; absl::optional<GURL> direct_from_seller_auction_signals_; + absl::optional<std::string> + direct_from_seller_auction_signals_header_ad_slot_; url::Origin top_window_origin_; mojom::AuctionWorkletPermissionsPolicyStatePtr permissions_policy_state_; absl::optional<uint16_t> experiment_group_id_; @@ -1579,6 +1594,18 @@ RunScoreAdWithReturnValueExpectingResult( "auctionConfig.decisionLogicUrl.length", decision_logic_url_.spec().length()); + + direct_from_seller_auction_signals_header_ad_slot_ = R"("abcde")"; + RunScoreAdWithReturnValueExpectingResult( + "directFromSellerSignals.auctionSignals.length", + direct_from_seller_auction_signals_header_ad_slot_->length() - + std::string(R"("")").length()); + + direct_from_seller_seller_signals_header_ad_slot_ = R"("abcdefg")"; + RunScoreAdWithReturnValueExpectingResult( + "directFromSellerSignals.sellerSignals.length", + direct_from_seller_seller_signals_header_ad_slot_->length() - + std::string(R"("")").length()); } TEST_F(SellerWorkletTest, ScoreAdExperimentGroupIdParam) { @@ -3084,6 +3111,19 @@ /*expected_report_url=*/absl::nullopt); } +TEST_F(SellerWorkletTest, + ReportResultDirectFromSellerSignalsHeaderAdSlotParam) { + direct_from_seller_auction_signals_header_ad_slot_ = R"("abcde")"; + direct_from_seller_seller_signals_header_ad_slot_ = R"("abcdefg")"; + + const char kExpectedJson[] = + R"({"auctionSignals":"abcde", "sellerSignals":"abcdefg"})"; + + RunReportResultCreatedScriptExpectingResult( + "directFromSellerSignals", /*extra_code=*/std::string(), kExpectedJson, + /*expected_report_url=*/absl::nullopt); +} + TEST_F(SellerWorkletTest, ReportResultAuctionConfigParamPerBuyerTimeouts) { // Empty AuctionAdConfig, with nothing filled in, except the seller and // decision logic URL. @@ -3250,7 +3290,9 @@ ad_metadata_, bid_, bid_currency_, auction_ad_config_non_shared_params_, direct_from_seller_seller_signals_, + direct_from_seller_seller_signals_header_ad_slot_, direct_from_seller_auction_signals_, + direct_from_seller_auction_signals_header_ad_slot_, browser_signals_other_seller_.Clone(), component_expect_bid_currency_, browser_signal_interest_group_owner_, browser_signal_render_url_, browser_signal_ad_components_, browser_signal_bidding_duration_msecs_, @@ -3282,7 +3324,9 @@ seller_worklet->ReportResult( auction_ad_config_non_shared_params_, direct_from_seller_seller_signals_, + direct_from_seller_seller_signals_header_ad_slot_, direct_from_seller_auction_signals_, + direct_from_seller_auction_signals_header_ad_slot_, browser_signals_other_seller_.Clone(), browser_signal_interest_group_owner_, browser_signal_buyer_and_seller_reporting_id_, @@ -3320,7 +3364,10 @@ base::WaitableEvent* event_handle = WedgeV8Thread(v8_helper_.get()); seller_worklet->ScoreAd( ad_metadata_, bid_, bid_currency_, auction_ad_config_non_shared_params_, - direct_from_seller_seller_signals_, direct_from_seller_auction_signals_, + direct_from_seller_seller_signals_, + direct_from_seller_seller_signals_header_ad_slot_, + direct_from_seller_auction_signals_, + direct_from_seller_auction_signals_header_ad_slot_, browser_signals_other_seller_.Clone(), component_expect_bid_currency_, browser_signal_interest_group_owner_, browser_signal_render_url_, browser_signal_ad_components_, browser_signal_bidding_duration_msecs_, @@ -3346,7 +3393,9 @@ base::WaitableEvent* event_handle = WedgeV8Thread(v8_helper_.get()); seller_worklet->ReportResult( auction_ad_config_non_shared_params_, direct_from_seller_seller_signals_, + direct_from_seller_seller_signals_header_ad_slot_, direct_from_seller_auction_signals_, + direct_from_seller_auction_signals_header_ad_slot_, browser_signals_other_seller_.Clone(), browser_signal_interest_group_owner_, browser_signal_buyer_and_seller_reporting_id_, browser_signal_render_url_, @@ -3991,7 +4040,10 @@ seller_worklet->ScoreAd( ad_metadata_, bid_, bid_currency_, auction_ad_config_non_shared_params_, - direct_from_seller_seller_signals_, direct_from_seller_auction_signals_, + direct_from_seller_seller_signals_, + direct_from_seller_seller_signals_header_ad_slot_, + direct_from_seller_auction_signals_, + direct_from_seller_auction_signals_header_ad_slot_, browser_signals_other_seller_.Clone(), component_expect_bid_currency_, browser_signal_interest_group_owner_, browser_signal_render_url_, browser_signal_ad_components_, browser_signal_bidding_duration_msecs_, @@ -4049,7 +4101,10 @@ seller_worklet->ScoreAd( ad_metadata_, bid_, bid_currency_, auction_ad_config_non_shared_params_, - direct_from_seller_seller_signals_, direct_from_seller_auction_signals_, + direct_from_seller_seller_signals_, + direct_from_seller_seller_signals_header_ad_slot_, + direct_from_seller_auction_signals_, + direct_from_seller_auction_signals_header_ad_slot_, browser_signals_other_seller_.Clone(), component_expect_bid_currency_, browser_signal_interest_group_owner_, browser_signal_render_url_, browser_signal_ad_components_, browser_signal_bidding_duration_msecs_, @@ -4712,7 +4767,10 @@ seller_worklet->ScoreAd( ad_metadata_, i + 1, bid_currency_, auction_ad_config_non_shared_params_, - direct_from_seller_seller_signals_, direct_from_seller_auction_signals_, + direct_from_seller_seller_signals_, + direct_from_seller_seller_signals_header_ad_slot_, + direct_from_seller_auction_signals_, + direct_from_seller_auction_signals_header_ad_slot_, browser_signals_other_seller_.Clone(), component_expect_bid_currency_, browser_signal_interest_group_owner_, browser_signal_render_url_, browser_signal_ad_components_, browser_signal_bidding_duration_msecs_,
diff --git a/content/test/data/interest_group/bidding_argument_validator.js b/content/test/data/interest_group/bidding_argument_validator.js index 7cdf4129..0ac3bae9 100644 --- a/content/test/data/interest_group/bidding_argument_validator.js +++ b/content/test/data/interest_group/bidding_argument_validator.js
@@ -170,13 +170,15 @@ function validateDirectFromSellerSignals(directFromSellerSignals) { const perBuyerSignalsJSON = JSON.stringify(directFromSellerSignals.perBuyerSignals); - if (perBuyerSignalsJSON !== '{"json":"for","buyer":[1]}') { + if (perBuyerSignalsJSON !== '{"json":"for","buyer":[1]}' && + perBuyerSignalsJSON !== '{"buyer":[1],"json":"for"}') { throw 'Wrong directFromSellerSignals.perBuyerSignals ' + perBuyerSignalsJSON; } const auctionSignalsJSON = JSON.stringify(directFromSellerSignals.auctionSignals); - if (auctionSignalsJSON !== '{"json":"for","all":["parties"]}') { + if (auctionSignalsJSON !== '{"json":"for","all":["parties"]}' && + auctionSignalsJSON !== '{"all":["parties"],"json":"for"}') { throw 'Wrong directFromSellerSignals.auctionSignals ' + auctionSignalsJSON; }
diff --git a/content/test/data/interest_group/component_auction_bidding_argument_validator.js b/content/test/data/interest_group/component_auction_bidding_argument_validator.js index a7ac46f..2ea02c0 100644 --- a/content/test/data/interest_group/component_auction_bidding_argument_validator.js +++ b/content/test/data/interest_group/component_auction_bidding_argument_validator.js
@@ -231,14 +231,17 @@ function validateDirectFromSellerSignals(directFromSellerSignals) { const perBuyerSignalsJSON = JSON.stringify(directFromSellerSignals.perBuyerSignals); - if (perBuyerSignalsJSON !== '{"from":"component","json":"for","buyer":[1]}') { + if (perBuyerSignalsJSON !== '{"from":"component","json":"for","buyer":[1]}' && + perBuyerSignalsJSON !== '{"buyer":[1],"from":"component","json":"for"}') { throw 'Wrong directFromSellerSignals.perBuyerSignals ' + perBuyerSignalsJSON; } const auctionSignalsJSON = JSON.stringify(directFromSellerSignals.auctionSignals); if (auctionSignalsJSON !== - '{"from":"component","json":"for","all":["parties"]}') { + '{"from":"component","json":"for","all":["parties"]}' && + auctionSignalsJSON !== + '{"all":["parties"],"from":"component","json":"for"}') { throw 'Wrong directFromSellerSignals.auctionSignals ' + auctionSignalsJSON; }
diff --git a/content/test/data/interest_group/component_auction_component_decision_argument_validator.js b/content/test/data/interest_group/component_auction_component_decision_argument_validator.js index aa86253a..c07843a 100644 --- a/content/test/data/interest_group/component_auction_component_decision_argument_validator.js +++ b/content/test/data/interest_group/component_auction_component_decision_argument_validator.js
@@ -221,7 +221,9 @@ const auctionSignalsJSON = JSON.stringify(directFromSellerSignals.auctionSignals); if (auctionSignalsJSON !== - '{"from":"component","json":"for","all":["parties"]}') { + '{"from":"component","json":"for","all":["parties"]}' && + auctionSignalsJSON !== + '{"all":["parties"],"from":"component","json":"for"}') { throw 'Wrong directFromSellerSignals.auctionSignals ' + auctionSignalsJSON; }
diff --git a/content/test/data/interest_group/component_auction_top_level_decision_argument_validator.js b/content/test/data/interest_group/component_auction_top_level_decision_argument_validator.js index 93b918c..fe20c805 100644 --- a/content/test/data/interest_group/component_auction_top_level_decision_argument_validator.js +++ b/content/test/data/interest_group/component_auction_top_level_decision_argument_validator.js
@@ -228,7 +228,8 @@ } const auctionSignalsJSON = JSON.stringify(directFromSellerSignals.auctionSignals); - if (auctionSignalsJSON !== '{"json":"for","all":["parties"]}') { + if (auctionSignalsJSON !== '{"json":"for","all":["parties"]}' && + auctionSignalsJSON !== '{"all":["parties"],"json":"for"}') { throw 'Wrong directFromSellerSignals.auctionSignals ' + auctionSignalsJSON; }
diff --git a/content/test/data/interest_group/decision_argument_validator.js b/content/test/data/interest_group/decision_argument_validator.js index 41ed09d..4f87ffe6 100644 --- a/content/test/data/interest_group/decision_argument_validator.js +++ b/content/test/data/interest_group/decision_argument_validator.js
@@ -226,7 +226,8 @@ } const auctionSignalsJSON = JSON.stringify(directFromSellerSignals.auctionSignals); - if (auctionSignalsJSON !== '{"json":"for","all":["parties"]}') { + if (auctionSignalsJSON !== '{"json":"for","all":["parties"]}' && + auctionSignalsJSON !== '{"all":["parties"],"json":"for"}') { throw 'Wrong directFromSellerSignals.auctionSignals ' + auctionSignalsJSON; }
diff --git a/content/test/gpu/gpu_tests/context_lost_integration_test.py b/content/test/gpu/gpu_tests/context_lost_integration_test.py index 6fde3bdb..ab0f12d 100644 --- a/content/test/gpu/gpu_tests/context_lost_integration_test.py +++ b/content/test/gpu/gpu_tests/context_lost_integration_test.py
@@ -57,58 +57,17 @@ feature_query_script = """ function GetFeatureStatus(feature_name, for_hardware_gpu) { - let query_result; - const infoView = document.querySelector('info-view'); - if (for_hardware_gpu) { - query_result = infoView.shadowRoot.querySelector( - '.feature-status-for-hardware-gpu-list'); - } else { - query_result = infoView.shadowRoot.querySelector('.feature-status-list'); - } - for (let i = 0; i < query_result.childElementCount; i++) { - let feature_status = query_result.children[i].textContent.split(': '); - if (feature_status.length == 2 && feature_status[0] == feature_name) - return feature_status[1]; - } - return ""; + return getGPUInfo(for_hardware_gpu + ? 'feature-status-for-hardware-gpu-list' + : 'feature-status-list', feature_name); } """ vendor_id_query_script = """ function GetActiveVendorId(for_hardware_gpu) { - let div; - const infoView = document.querySelector('info-view'); - if (for_hardware_gpu) { - div = infoView.shadowRoot.querySelector( - '.basic-info-for-hardware-gpu-div'); - } else { - div = infoView.shadowRoot.querySelector('#basic-info'); - } - const table = div.querySelector('info-view-table'); - let trs = table.shadowRoot.querySelectorAll('info-view-table-row'); - let vendor_id = 0; - // The first four rows are "Initialization time", "In-process GPU", - // "Passthrough Command Decoder", and "Sandboxed". - for (let i = 4; i < trs.length; i++) { - let tds = trs[i].shadowRoot.querySelectorAll('div'); - let token = tds[0].textContent.trim(); - if (!token.startsWith('GPU')) - break; - if (i == 4 && token != 'GPU0') - break; - let gpu_string = tds[1].textContent.trim(); - let vendor_info = gpu_string.split(', ')[0].split('= '); - if (vendor_info.length != 2 || vendor_info[0] != 'VENDOR') - break; - let id = parseInt(vendor_info[1]); - if (vendor_id == 0) - vendor_id = id; - if (gpu_string.endsWith('*ACTIVE*')) { - vendor_id = id; - break; - } - } - return vendor_id; + return getGPUInfo(for_hardware_gpu + ? 'active-gpu-for-hardware' + : 'active-gpu'); } """ @@ -322,7 +281,7 @@ tab.Navigate('chrome:gpu', script_to_evaluate_on_commit=feature_query_script) tab.WaitForJavaScriptCondition('window.gpuPagePopulated', timeout=10) - status = (tab.EvaluateJavaScript('GetFeatureStatus("WebGL", %s)' % + status = (tab.EvaluateJavaScript('GetFeatureStatus("webgl", %s)' % ('true' if for_hardware_gpu else 'false'))) tab.Close() return status @@ -671,7 +630,7 @@ self._NavigateAndWaitForLoad(test_path) # Check WebGL status at browser startup. webgl_status = self._GetWebGLFeatureStatus(False) - if webgl_status != 'Hardware accelerated': + if webgl_status != 'enabled': self.fail('WebGL should be hardware accelerated initially, but got %s' % webgl_status) webgl_status_for_hardware_gpu = self._GetWebGLFeatureStatus(True) @@ -681,12 +640,12 @@ # Check WebGL status after three GPU crashes - fallback to SwiftShader. self._KillGPUProcess(3, True) webgl_status = self._GetWebGLFeatureStatus(False) - if webgl_status != 'Software only, hardware acceleration unavailable': + if webgl_status != 'unavailable_software': self.fail('WebGL should be software only with SwiftShader, but got %s' % webgl_status) webgl_status_for_hardware_gpu = self._GetWebGLFeatureStatus(True) - if webgl_status_for_hardware_gpu != 'Hardware accelerated': - self.fail('WebGL status for hardware gpu should be "accelerated", ' + if webgl_status_for_hardware_gpu != 'enabled': + self.fail('WebGL status for hardware gpu should be "enabled", ' 'but got %s' % webgl_status_for_hardware_gpu) self._RestartBrowser('must restart after tests that kill the GPU process')
diff --git a/content/test/gpu/gpu_tests/gpu_process_integration_test.py b/content/test/gpu/gpu_tests/gpu_process_integration_test.py index cabc13a7..c2f5ca6 100644 --- a/content/test/gpu/gpu_tests/gpu_process_integration_test.py +++ b/content/test/gpu/gpu_tests/gpu_process_integration_test.py
@@ -38,12 +38,7 @@ window.domAutomationController = domAutomationController; function GetDriverBugWorkarounds() { - var query_result = document.querySelector('info-view').shadowRoot - .querySelector('.workarounds-list'); - var browser_list = [] - for (var i=0; i < query_result.childElementCount; i++) - browser_list.push(query_result.children[i].textContent); - return browser_list; + return getGPUInfo('workarounds'); }; """
diff --git a/content/test/gpu/gpu_tests/hardware_accelerated_feature_integration_test.py b/content/test/gpu/gpu_tests/hardware_accelerated_feature_integration_test.py index 8971385..54e6778 100644 --- a/content/test/gpu/gpu_tests/hardware_accelerated_feature_integration_test.py +++ b/content/test/gpu/gpu_tests/hardware_accelerated_feature_integration_test.py
@@ -14,19 +14,7 @@ test_harness_script = r""" function VerifyHardwareAccelerated(feature) { - feature += ': ' - var list = document.querySelector('info-view').shadowRoot.querySelector( - '.feature-status-list'); - for (var i=0; i < list.childElementCount; i++) { - var span_list = list.children[i].getElementsByTagName('span'); - var feature_str = span_list[0].textContent; - var value_str = span_list[1].textContent; - if ((feature_str == feature) && - (value_str == 'Hardware accelerated')) { - return true; - } - } - return false; + return getGPUInfo('feature-status-list', feature) === 'enabled'; }; """ @@ -61,7 +49,7 @@ @classmethod def GenerateGpuTests(cls, options: ct.ParsedCmdArgs) -> ct.TestGenerator: - tests = ('WebGL', 'Canvas') + tests = ('webgl', '2d_canvas') for feature in tests: yield ('HardwareAcceleratedFeature_%s_accelerated' % safe_feature_name(feature), 'chrome://gpu', [feature])
diff --git a/extensions/browser/api/device_permissions_manager.cc b/extensions/browser/api/device_permissions_manager.cc index 794b733..01b50d10 100644 --- a/extensions/browser/api/device_permissions_manager.cc +++ b/extensions/browser/api/device_permissions_manager.cc
@@ -679,9 +679,10 @@ DevicePermissionsManagerFactory::~DevicePermissionsManagerFactory() { } -KeyedService* DevicePermissionsManagerFactory::BuildServiceInstanceFor( +std::unique_ptr<KeyedService> +DevicePermissionsManagerFactory::BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const { - return new DevicePermissionsManager(context); + return std::make_unique<DevicePermissionsManager>(context); } BrowserContext* DevicePermissionsManagerFactory::GetBrowserContextToUse(
diff --git a/extensions/browser/api/device_permissions_manager.h b/extensions/browser/api/device_permissions_manager.h index 0135321c..611a977 100644 --- a/extensions/browser/api/device_permissions_manager.h +++ b/extensions/browser/api/device_permissions_manager.h
@@ -141,6 +141,9 @@ // Manages saved device permissions for all extensions. class DevicePermissionsManager : public KeyedService { public: + explicit DevicePermissionsManager(content::BrowserContext* context); + ~DevicePermissionsManager() override; + DevicePermissionsManager(const DevicePermissionsManager&) = delete; DevicePermissionsManager& operator=(const DevicePermissionsManager&) = delete; @@ -187,9 +190,6 @@ friend class DevicePermissionsManagerFactory; FRIEND_TEST_ALL_PREFIXES(DevicePermissionsManagerTest, SuspendExtension); - explicit DevicePermissionsManager(content::BrowserContext* context); - ~DevicePermissionsManager() override; - DevicePermissions* GetInternal(const std::string& extension_id) const; base::ThreadChecker thread_checker_; @@ -216,7 +216,7 @@ ~DevicePermissionsManagerFactory() override; // BrowserContextKeyedServiceFactory implementation - KeyedService* BuildServiceInstanceFor( + std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const override; content::BrowserContext* GetBrowserContextToUse( content::BrowserContext* context) const override;
diff --git a/extensions/browser/event_router_factory.cc b/extensions/browser/event_router_factory.cc index 86ec42d..20f68c6 100644 --- a/extensions/browser/event_router_factory.cc +++ b/extensions/browser/event_router_factory.cc
@@ -38,9 +38,10 @@ EventRouterFactory::~EventRouterFactory() { } -KeyedService* EventRouterFactory::BuildServiceInstanceFor( +std::unique_ptr<KeyedService> +EventRouterFactory::BuildServiceInstanceForBrowserContext( BrowserContext* context) const { - return new EventRouter(context, ExtensionPrefs::Get(context)); + return std::make_unique<EventRouter>(context, ExtensionPrefs::Get(context)); } BrowserContext* EventRouterFactory::GetBrowserContextToUse(
diff --git a/extensions/browser/event_router_factory.h b/extensions/browser/event_router_factory.h index d2f0c47..9e37a9d7 100644 --- a/extensions/browser/event_router_factory.h +++ b/extensions/browser/event_router_factory.h
@@ -27,7 +27,7 @@ ~EventRouterFactory() override; // BrowserContextKeyedServiceFactory implementation - KeyedService* BuildServiceInstanceFor( + std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const override; content::BrowserContext* GetBrowserContextToUse( content::BrowserContext* context) const override;
diff --git a/extensions/browser/mock_extension_system.h b/extensions/browser/mock_extension_system.h index a90472d0..ba0f529d 100644 --- a/extensions/browser/mock_extension_system.h +++ b/extensions/browser/mock_extension_system.h
@@ -88,9 +88,9 @@ ~MockExtensionSystemFactory() override = default; // BrowserContextKeyedServiceFactory overrides: - KeyedService* BuildServiceInstanceFor( + std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const override { - return new T(context); + return std::make_unique<T>(context); } content::BrowserContext* GetBrowserContextToUse( content::BrowserContext* context) const override {
diff --git a/extensions/browser/updater/update_service.h b/extensions/browser/updater/update_service.h index 4fc2522..d779515 100644 --- a/extensions/browser/updater/update_service.h +++ b/extensions/browser/updater/update_service.h
@@ -65,7 +65,6 @@ UpdateFoundCallback update_found_callback, base::OnceClosure callback); - protected: UpdateService(content::BrowserContext* context, scoped_refptr<update_client::UpdateClient> update_client); ~UpdateService() override;
diff --git a/extensions/browser/updater/update_service_factory.cc b/extensions/browser/updater/update_service_factory.cc index 84fceb3..849168c 100644 --- a/extensions/browser/updater/update_service_factory.cc +++ b/extensions/browser/updater/update_service_factory.cc
@@ -4,6 +4,8 @@ #include "extensions/browser/updater/update_service_factory.h" +#include <memory> + #include "components/keyed_service/content/browser_context_dependency_manager.h" #include "components/update_client/update_client.h" #include "extensions/browser/extension_registry_factory.h" @@ -32,9 +34,10 @@ UpdateServiceFactory::~UpdateServiceFactory() = default; -KeyedService* UpdateServiceFactory::BuildServiceInstanceFor( +std::unique_ptr<KeyedService> +UpdateServiceFactory::BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const { - return new UpdateService( + return std::make_unique<UpdateService>( context, ExtensionsBrowserClient::Get()->CreateUpdateClient(context)); }
diff --git a/extensions/browser/updater/update_service_factory.h b/extensions/browser/updater/update_service_factory.h index e314db89..152e515 100644 --- a/extensions/browser/updater/update_service_factory.h +++ b/extensions/browser/updater/update_service_factory.h
@@ -5,6 +5,8 @@ #ifndef EXTENSIONS_BROWSER_UPDATER_UPDATE_SERVICE_FACTORY_H_ #define EXTENSIONS_BROWSER_UPDATER_UPDATE_SERVICE_FACTORY_H_ +#include <memory> + #include "base/memory/singleton.h" #include "components/keyed_service/content/browser_context_keyed_service_factory.h" @@ -29,7 +31,7 @@ ~UpdateServiceFactory() override; // BrowserContextKeyedServiceFactory: - KeyedService* BuildServiceInstanceFor( + std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const override; content::BrowserContext* GetBrowserContextToUse( content::BrowserContext* context) const override;
diff --git a/gpu/command_buffer/service/service_utils.cc b/gpu/command_buffer/service/service_utils.cc index f8deb87d..7e7ab4f 100644 --- a/gpu/command_buffer/service/service_utils.cc +++ b/gpu/command_buffer/service/service_utils.cc
@@ -203,7 +203,8 @@ } GrContextType ParseGrContextType(const base::CommandLine* command_line) { - if (base::FeatureList::IsEnabled(features::kSkiaGraphite)) { + if (base::FeatureList::IsEnabled(features::kSkiaGraphite) || + command_line->HasSwitch(switches::kSkiaGraphiteBackend)) { [[maybe_unused]] auto value = command_line->GetSwitchValueASCII(switches::kSkiaGraphiteBackend); #if BUILDFLAG(SKIA_USE_DAWN)
diff --git a/gpu/ipc/service/gpu_channel_manager.cc b/gpu/ipc/service/gpu_channel_manager.cc index d1aebd6..fb2bfc5d 100644 --- a/gpu/ipc/service/gpu_channel_manager.cc +++ b/gpu/ipc/service/gpu_channel_manager.cc
@@ -35,6 +35,7 @@ #include "gpu/command_buffer/service/sync_point_manager.h" #include "gpu/config/gpu_crash_keys.h" #include "gpu/config/gpu_finch_features.h" +#include "gpu/config/gpu_switches.h" #include "gpu/ipc/common/gpu_client_ids.h" #include "gpu/ipc/common/memory_stats.h" #include "gpu/ipc/service/gpu_channel.h" @@ -85,7 +86,7 @@ const int kMaxKeepAliveTimeMs = 200; #endif #if BUILDFLAG(IS_WIN) -void TrimD3DResources() { +void TrimD3DResources(const scoped_refptr<SharedContextState>& context_state) { // Graphics drivers periodically allocate internal memory buffers in // order to speed up subsequent rendering requests. These memory allocations // in general lead to increased memory usage by the overall system. @@ -98,13 +99,22 @@ // apps should only call Trim when going idle for a period of time or during // low memory conditions. Microsoft::WRL::ComPtr<ID3D11Device> d3d11_device = - gl::QueryD3D11DeviceObjectFromANGLE(); + context_state->GetD3D11Device(); if (d3d11_device) { Microsoft::WRL::ComPtr<IDXGIDevice3> dxgi_device; if (SUCCEEDED(d3d11_device.As(&dxgi_device))) { dxgi_device->Trim(); } } + + Microsoft::WRL::ComPtr<ID3D11Device> angle_d3d11_device = + gl::QueryD3D11DeviceObjectFromANGLE(); + if (angle_d3d11_device && angle_d3d11_device != d3d11_device) { + Microsoft::WRL::ComPtr<IDXGIDevice3> dxgi_device; + if (SUCCEEDED(angle_d3d11_device.As(&dxgi_device))) { + dxgi_device->Trim(); + } + } } #endif @@ -858,7 +868,7 @@ if (gr_shader_cache_) gr_shader_cache_->PurgeMemory(memory_pressure_level); #if BUILDFLAG(IS_WIN) - TrimD3DResources(); + TrimD3DResources(shared_context_state_); #endif } @@ -976,10 +986,12 @@ #if BUILDFLAG(IS_APPLE) const bool want_graphite = gr_context_type == GrContextType::kGraphiteDawn || gr_context_type == GrContextType::kGraphiteMetal; + const bool force_graphite = base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kSkiaGraphiteBackend); const bool is_angle_metal = gl::GetANGLEImplementation() == gl::ANGLEImplementation::kMetal; // Fallback from Graphite to Ganesh/GL if ANGLE is not using Metal too. - if (want_graphite && !is_angle_metal) { + if (want_graphite && !force_graphite && !is_angle_metal) { gr_context_type = GrContextType::kGL; } #endif
diff --git a/headless/lib/browser/headless_browser_main_parts_posix.cc b/headless/lib/browser/headless_browser_main_parts_posix.cc index 7677c5c..4823468 100644 --- a/headless/lib/browser/headless_browser_main_parts_posix.cc +++ b/headless/lib/browser/headless_browser_main_parts_posix.cc
@@ -4,15 +4,17 @@ #include "headless/lib/browser/headless_browser_main_parts.h" +#include <errno.h> #include <signal.h> #include <unistd.h> +#include "base/files/file_descriptor_watcher_posix.h" #include "base/functional/bind.h" #include "base/functional/callback.h" #include "base/logging.h" #include "base/memory/scoped_refptr.h" #include "base/no_destructor.h" -#include "base/task/single_thread_task_runner.h" +#include "base/posix/eintr_wrapper.h" #include "build/build_config.h" #include "build/chromeos_buildflags.h" #include "content/public/browser/browser_task_traits.h" @@ -35,6 +37,26 @@ namespace { +int g_read_fd = 0; +int g_write_fd = 0; + +bool CreatePipe() { + CHECK(!g_read_fd); + CHECK(!g_write_fd); + + int pipe_fd[2]; + int result = pipe(pipe_fd); + if (result < 0) { + PLOG(ERROR) << "Could not create signal pipe"; + return false; + } + + g_read_fd = pipe_fd[0]; + g_write_fd = pipe_fd[1]; + + return true; +} + class BrowserShutdownHandler { public: typedef base::OnceCallback<void(int)> ShutdownCallback; @@ -75,19 +97,32 @@ } void Init(ShutdownCallback shutdown_callback) { - task_runner_ = content::GetUIThreadTaskRunner({}); shutdown_callback_ = std::move(shutdown_callback); + + // We cannot just PostTask from a signal handler, so route the signal + // through a pipe. + CHECK(CreatePipe()); + + file_descriptor_watcher_controller_ = + base::FileDescriptorWatcher::WatchReadable( + g_read_fd, + base::BindRepeating( + &BrowserShutdownHandler::OnFileCanReadWithoutBlocking, + base::Unretained(this))); + } + + // This is called whenever data is available in |g_read_fd|. + void OnFileCanReadWithoutBlocking() { + int pipe_data; + if (HANDLE_EINTR(read(g_read_fd, &pipe_data, sizeof(pipe_data))) > 0) { + Shutdown(pipe_data); + } } void Shutdown(int signal) { if (shutdown_callback_) { int exit_code = 0x80u + signal; - if (!task_runner_->PostTask( - FROM_HERE, - base::BindOnce(std::move(shutdown_callback_), exit_code))) { - RAW_LOG(WARNING, "No valid task runner, exiting ungracefully."); - kill(getpid(), signal); - } + std::move(shutdown_callback_).Run(exit_code); } } @@ -114,11 +149,14 @@ action.sa_handler = SIG_DFL; RAW_CHECK(sigaction(signal, &action, nullptr) == 0); - GetInstance().Shutdown(signal); + // Send signal number through the pipe. + int pipe_data = signal; + std::ignore = write(g_write_fd, &pipe_data, sizeof(pipe_data)); } - scoped_refptr<base::SingleThreadTaskRunner> task_runner_; ShutdownCallback shutdown_callback_; + std::unique_ptr<base::FileDescriptorWatcher::Controller> + file_descriptor_watcher_controller_; }; } // namespace
diff --git a/infra/config/lib/bootstrap.star b/infra/config/lib/bootstrap.star index e6dd602..4b117ac 100644 --- a/infra/config/lib/bootstrap.star +++ b/infra/config/lib/bootstrap.star
@@ -22,6 +22,7 @@ //recipes.star for more information on bootstrappable recipes. """ +load("./chrome_settings.star", "per_builder_outputs_config") load("./nodes.star", "nodes") load("//project.star", "settings") @@ -163,7 +164,9 @@ if builder_shadow_properties != None: non_bootstrapped_shadow_properties = get_non_bootstrapped_properties(builder_shadow_properties) - properties_file = "builders/{}/{}/properties.json".format(bucket_name, builder_name) + root_out_dir = per_builder_outputs_config().root_dir + out_dir = "{}/{}/{}".format(root_out_dir, bucket_name, builder_name) + properties_file = "{}/properties.json".format(out_dir) bootstrap_property = { "top_level_project": { "repo": { @@ -175,7 +178,7 @@ "properties_file": "infra/config/generated/{}".format(properties_file), } if builder_shadow_properties: - shadow_properties_file = "builders/{}/{}/shadow-properties.json".format(bucket_name, builder_name) + shadow_properties_file = "{}/shadow-properties.json".format(out_dir) bootstrap_property["shadow_properties_file"] = "infra/config/generated/{}".format(shadow_properties_file) ctx.output[shadow_properties_file] = json.indent(json.encode(builder_shadow_properties), indent = " ")
diff --git a/infra/config/lib/chrome_settings.star b/infra/config/lib/chrome_settings.star new file mode 100644 index 0000000..1473991 --- /dev/null +++ b/infra/config/lib/chrome_settings.star
@@ -0,0 +1,49 @@ +# Copyright 2023 The Chromium Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. +"""Library for configuring global defaults for CBI libs. + +Generators can't access lucicfg vars, so in order to provide +configuration for generators, the information must be present in the +lucicfg graph. This file provides the chrome_settings struct that +can be used to configure project-wide defaults. For generators to access +this information, separate functions are provided for reading the +information from the graph. +""" + +load("./nodes.star", "nodes") + +_PER_BUILDER_OUTPUTS = nodes.create_singleton_node_type("per_builder_outputs") + +def _per_builder_outputs(*, root_dir): + """Configure per-builder outputs for the project. + + Generators can get the config values using per_builder_outputs_config. + + Args: + root_dir: The root directory in the generated output directory under + which per-builder outputs will be generated. Must be a non-empty + string. + """ + if not root_dir or type(root_dir) != type(""): + fail("root_dir") + _PER_BUILDER_OUTPUTS.add(props = dict( + root_dir = root_dir, + )) + +def per_builder_outputs_config(): + """Get the per-builder outputs config. + + Returns: + A struct with the following attributes: + * root_dir: The name of the root directory to generate + per-builder outputs to. + """ + node = _PER_BUILDER_OUTPUTS.get() + if node == None: + fail("In order to generate per-builder outputs, project.per_builder_outputs must be called") + return node.props + +chrome_settings = struct( + per_builder_outputs = _per_builder_outputs, +)
diff --git a/infra/config/lib/nodes.star b/infra/config/lib/nodes.star index b80a08e..d873bcdc 100644 --- a/infra/config/lib/nodes.star +++ b/infra/config/lib/nodes.star
@@ -10,6 +10,51 @@ _CHROMIUM_NS_KIND = "@chromium" +def _create_singleton_node_type(kind): + """Create a singleton node type. + + Singleton nodes types only allow for a single node of the type to exist. + This can be used for creating configuration nodes for generators since + generators are unable to access lucicfg vars. + + Args: + kind: (str) An identifier for the kind of the node. Must be unique + within the chromium namespace. + + Returns: + A node type that can be used for creating and getting a node of + the given kind. + + The type has the following properties: + * kind: The kind of node of the type. + + The node type has the following methods: + * key(): Creates a key for the node. + * add(**kwargs): Adds a node with a key created via `key()`. + `graph.add_node` will be called with the key and `**kwargs`. + Returns the key. + * get(): Gets the node with the key given by + `key(bucket_name, key_value)`. + """ + + def key(): + return graph.key(_CHROMIUM_NS_KIND, "", kind, "") + + def add(**kwargs): + k = key() + graph.add_node(k, **kwargs) + return k + + def get(): + return graph.node(key()) + + return struct( + kind = kind, + key = key, + add = add, + get = get, + ) + def _create_unscoped_node_type(kind, allow_unnamed = False): """Create an unscoped node type. @@ -340,6 +385,7 @@ nodes = struct( BUILDER = _BUILDER, + create_singleton_node_type = _create_singleton_node_type, create_unscoped_node_type = _create_unscoped_node_type, create_bucket_scoped_node_type = _create_bucket_scoped_node_type, create_node_type_with_builder_ref = _create_node_type_with_builder_ref,
diff --git a/infra/config/main.star b/infra/config/main.star index d3579f12..56cf2f6 100755 --- a/infra/config/main.star +++ b/infra/config/main.star
@@ -7,6 +7,7 @@ # for information on starlark/lucicfg load("//lib/branches.star", "branches") +load("//lib/chrome_settings.star", "chrome_settings") load("//project.star", "settings") lucicfg.check_version( @@ -140,6 +141,10 @@ tree_closing_enabled = True, ) +chrome_settings.per_builder_outputs( + root_dir = "builders", +) + # An all-purpose public realm. luci.realm( name = "public",
diff --git a/ios/chrome/app/strings/ios_strings.grd b/ios/chrome/app/strings/ios_strings.grd index 6059595..3495d4e 100644 --- a/ios/chrome/app/strings/ios_strings.grd +++ b/ios/chrome/app/strings/ios_strings.grd
@@ -2193,8 +2193,12 @@ <message name="IDS_IOS_LOCKDOWN_MODE_INFO_BUTTON_TITLE" desc="Title for Lockdown Mode."> This setting is enabled on your device </message> - <message name="IDS_IOS_LOCKDOWN_MODE_INFO_BUTTON_SUMMARY" desc="Title for Lockdown Mode."> - To disable Lockdown Mode in Chrome turn it off on your device. + + <message name="IDS_IOS_LOCKDOWN_MODE_INFO_BUTTON_SUMMARY_FOR_IPAD" desc="iPad summary for lockdown mode info button"> + To disable Lockdown Mode in Chrome turn it off on your iPad. + </message> + <message name="IDS_IOS_LOCKDOWN_MODE_INFO_BUTTON_SUMMARY_FOR_IPHONE" desc="iPhone summary for lockdown mode info button"> + To disable Lockdown Mode in Chrome turn it off on your iPhone. </message> <message name="IDS_IOS_LOCKDOWN_MODE_FOOTER" desc="Title for Lockdown Mode."> When turned on, certain web technologies are blocked, which might cause some websites to load more slowly or not operate correctly.
diff --git a/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_LOCKDOWN_MODE_INFO_BUTTON_SUMMARY.png.sha1 b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_LOCKDOWN_MODE_INFO_BUTTON_SUMMARY.png.sha1 deleted file mode 100644 index 65e7d063..0000000 --- a/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_LOCKDOWN_MODE_INFO_BUTTON_SUMMARY.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -b12b0cc061d65f65e17170b8c8e8af7c5a4f3a5c \ No newline at end of file
diff --git a/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_LOCKDOWN_MODE_INFO_BUTTON_SUMMARY_FOR_IPAD.png.sha1 b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_LOCKDOWN_MODE_INFO_BUTTON_SUMMARY_FOR_IPAD.png.sha1 new file mode 100644 index 0000000..ce0f02e --- /dev/null +++ b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_LOCKDOWN_MODE_INFO_BUTTON_SUMMARY_FOR_IPAD.png.sha1
@@ -0,0 +1 @@ +16c4baf639ae094467377e2ee3af89fbd7b582bb \ No newline at end of file
diff --git a/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_LOCKDOWN_MODE_INFO_BUTTON_SUMMARY_FOR_IPHONE.png.sha1 b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_LOCKDOWN_MODE_INFO_BUTTON_SUMMARY_FOR_IPHONE.png.sha1 new file mode 100644 index 0000000..1c8704d --- /dev/null +++ b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_LOCKDOWN_MODE_INFO_BUTTON_SUMMARY_FOR_IPHONE.png.sha1
@@ -0,0 +1 @@ +820831f8c416a5d89f132fa9c4b0fe8aaffb6d27 \ No newline at end of file
diff --git a/ios/chrome/browser/ui/content_suggestions/cells/magic_stack_module_container.mm b/ios/chrome/browser/ui/content_suggestions/cells/magic_stack_module_container.mm index 9d20316a..0666f8a1 100644 --- a/ios/chrome/browser/ui/content_suggestions/cells/magic_stack_module_container.mm +++ b/ios/chrome/browser/ui/content_suggestions/cells/magic_stack_module_container.mm
@@ -225,6 +225,7 @@ return l10n_util::GetNSString(IDS_IOS_SET_UP_LIST_TITLE); case ContentSuggestionsModuleType::kSafetyCheck: case ContentSuggestionsModuleType::kSafetyCheckMultiRow: + case ContentSuggestionsModuleType::kSafetyCheckMultiRowOverflow: return l10n_util::GetNSString(IDS_IOS_SAFETY_CHECK_TITLE); default: NOTREACHED(); @@ -247,6 +248,7 @@ case ContentSuggestionsModuleType::kMostVisited: case ContentSuggestionsModuleType::kShortcuts: case ContentSuggestionsModuleType::kSafetyCheckMultiRow: + case ContentSuggestionsModuleType::kSafetyCheckMultiRowOverflow: contentMargins.bottom = kReducedContentBottomInset; break; default: @@ -342,6 +344,7 @@ - (BOOL)shouldShowSeeMore { switch (_type) { case ContentSuggestionsModuleType::kCompactedSetUpList: + case ContentSuggestionsModuleType::kSafetyCheckMultiRowOverflow: return YES; default: return NO;
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_constants.h b/ios/chrome/browser/ui/content_suggestions/content_suggestions_constants.h index 193c97d..5565159 100644 --- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_constants.h +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_constants.h
@@ -23,7 +23,8 @@ kSetUpListAllSet = 6, kSafetyCheck = 7, kSafetyCheckMultiRow = 8, - kMaxValue = kSafetyCheckMultiRow, + kSafetyCheckMultiRowOverflow = 9, + kMaxValue = kSafetyCheckMultiRowOverflow, }; // Represents the content suggestions collection view.
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 f60d74f..c697202 100644 --- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_mediator.mm +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_mediator.mm
@@ -975,16 +975,21 @@ // different places in the Magic Stack depending on the Safety Check state(s). // However, for now, the module will simply be inserted at the front of the // Magic Stack. + int moduleIndex = 0; - int check_issues_count = CheckIssuesCount(_safetyCheckState); + int checkIssuesCount = CheckIssuesCount(_safetyCheckState); - if (check_issues_count > 1) { + if (checkIssuesCount > 2) { + [order insertObject:@(int(ContentSuggestionsModuleType:: + kSafetyCheckMultiRowOverflow)) + atIndex:moduleIndex]; + } else if (checkIssuesCount > 1) { [order insertObject:@(int(ContentSuggestionsModuleType::kSafetyCheckMultiRow)) - atIndex:0]; + atIndex:moduleIndex]; } else { [order insertObject:@(int(ContentSuggestionsModuleType::kSafetyCheck)) - atIndex:0]; + atIndex:moduleIndex]; } }
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_metrics_recorder.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_metrics_recorder.mm index d7c022a9..6c164bf 100644 --- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_metrics_recorder.mm +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_metrics_recorder.mm
@@ -76,6 +76,7 @@ case ContentSuggestionsModuleType::kSetUpListAllSet: case ContentSuggestionsModuleType::kSafetyCheck: case ContentSuggestionsModuleType::kSafetyCheckMultiRow: + case ContentSuggestionsModuleType::kSafetyCheckMultiRowOverflow: break; } UMA_HISTOGRAM_ENUMERATION(kMagicStackTopModuleImpressionHistogram, type);
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 ea9637a5..ef8b104d 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
@@ -38,6 +38,7 @@ #import "ios/chrome/browser/ui/content_suggestions/ntp_home_constant.h" #import "ios/chrome/browser/ui/content_suggestions/safety_check/safety_check_state.h" #import "ios/chrome/browser/ui/content_suggestions/safety_check/safety_check_view.h" +#import "ios/chrome/browser/ui/content_suggestions/safety_check/types.h" #import "ios/chrome/browser/ui/content_suggestions/safety_check/utils.h" #import "ios/chrome/browser/ui/content_suggestions/set_up_list/set_up_list_item_view.h" #import "ios/chrome/browser/ui/content_suggestions/set_up_list/set_up_list_item_view_data.h" @@ -672,8 +673,13 @@ int checkIssuesCount = CheckIssuesCount(state); ContentSuggestionsModuleType type = - checkIssuesCount > 1 ? ContentSuggestionsModuleType::kSafetyCheckMultiRow - : ContentSuggestionsModuleType::kSafetyCheck; + ContentSuggestionsModuleType::kSafetyCheck; + + if (checkIssuesCount > 2) { + type = ContentSuggestionsModuleType::kSafetyCheckMultiRowOverflow; + } else if (checkIssuesCount > 1) { + type = ContentSuggestionsModuleType::kSafetyCheckMultiRow; + } [_magicStack insertArrangedSubview:self.safetyCheckModuleContainer atIndex:[self indexForMagicStackModule:type]]; @@ -830,7 +836,15 @@ } - (void)seeMoreWasTappedForModuleType:(ContentSuggestionsModuleType)type { - [self.audience showSetUpListShowMoreMenu]; + if (type == ContentSuggestionsModuleType::kSafetyCheckMultiRowOverflow) { + [self.audience didSelectSafetyCheckItem:SafetyCheckItemType::kDefault]; + return; + } + + if (type == ContentSuggestionsModuleType::kCompactedSetUpList) { + [self.audience showSetUpListShowMoreMenu]; + return; + } } - (void)neverShowModuleType:(ContentSuggestionsModuleType)type { @@ -927,8 +941,13 @@ int checkIssuesCount = CheckIssuesCount(state); ContentSuggestionsModuleType type = - checkIssuesCount > 1 ? ContentSuggestionsModuleType::kSafetyCheckMultiRow - : ContentSuggestionsModuleType::kSafetyCheck; + ContentSuggestionsModuleType::kSafetyCheck; + + if (checkIssuesCount > 2) { + type = ContentSuggestionsModuleType::kSafetyCheckMultiRowOverflow; + } else if (checkIssuesCount > 1) { + type = ContentSuggestionsModuleType::kSafetyCheckMultiRow; + } self.safetyCheckModuleContainer = [[MagicStackModuleContainer alloc] initWithContentView:self.safetyCheckView @@ -1076,7 +1095,8 @@ break; } case ContentSuggestionsModuleType::kSafetyCheck: - case ContentSuggestionsModuleType::kSafetyCheckMultiRow: { + case ContentSuggestionsModuleType::kSafetyCheckMultiRow: + case ContentSuggestionsModuleType::kSafetyCheckMultiRowOverflow: { if (IsSafetyCheckMagicStackEnabled()) { [_magicStack addArrangedSubview:self.safetyCheckModuleContainer]; }
diff --git a/ios/chrome/browser/ui/settings/privacy/lockdown_mode/lockdown_mode_egtest.mm b/ios/chrome/browser/ui/settings/privacy/lockdown_mode/lockdown_mode_egtest.mm index 84e4ca0..d84afd51 100644 --- a/ios/chrome/browser/ui/settings/privacy/lockdown_mode/lockdown_mode_egtest.mm +++ b/ios/chrome/browser/ui/settings/privacy/lockdown_mode/lockdown_mode_egtest.mm
@@ -14,6 +14,7 @@ #import "ios/chrome/test/earl_grey/chrome_matchers.h" #import "ios/chrome/test/earl_grey/chrome_test_case.h" #import "ios/testing/earl_grey/earl_grey_test.h" +#import "ui/base/device_form_factor.h" #import "ui/base/l10n/l10n_util.h" using chrome_test_util::ButtonWithAccessibilityLabelId; @@ -117,10 +118,18 @@ GREYAssert(WaitForPopupDisplay(l10n_util::GetNSString( IDS_IOS_LOCKDOWN_MODE_INFO_BUTTON_TITLE)), @"Lockdown mode 'i' button wasn't tapped"); - [[EarlGrey - selectElementWithMatcher:grey_text(l10n_util::GetNSString( - IDS_IOS_LOCKDOWN_MODE_INFO_BUTTON_SUMMARY))] - assertWithMatcher:grey_notNil()]; + + if (ui::GetDeviceFormFactor() == ui::DEVICE_FORM_FACTOR_TABLET) { + [[EarlGrey selectElementWithMatcher: + grey_text(l10n_util::GetNSString( + IDS_IOS_LOCKDOWN_MODE_INFO_BUTTON_SUMMARY_FOR_IPAD))] + assertWithMatcher:grey_notNil()]; + } else { + [[EarlGrey selectElementWithMatcher: + grey_text(l10n_util::GetNSString( + IDS_IOS_LOCKDOWN_MODE_INFO_BUTTON_SUMMARY_FOR_IPHONE))] + assertWithMatcher:grey_notNil()]; + } } #pragma mark - Helpers
diff --git a/ios/chrome/browser/ui/settings/privacy/lockdown_mode/lockdown_mode_view_controller.mm b/ios/chrome/browser/ui/settings/privacy/lockdown_mode/lockdown_mode_view_controller.mm index dbe106d..148f222 100644 --- a/ios/chrome/browser/ui/settings/privacy/lockdown_mode/lockdown_mode_view_controller.mm +++ b/ios/chrome/browser/ui/settings/privacy/lockdown_mode/lockdown_mode_view_controller.mm
@@ -12,11 +12,11 @@ #import "ios/chrome/browser/shared/ui/table_view/cells/table_view_info_button_item.h" #import "ios/chrome/browser/shared/ui/table_view/cells/table_view_switch_cell.h" #import "ios/chrome/browser/shared/ui/table_view/cells/table_view_switch_item.h" - #import "ios/chrome/browser/ui/settings/elements/info_popover_view_controller.h" #import "ios/chrome/common/string_util.h" #import "ios/chrome/common/ui/colors/semantic_color_names.h" #import "ios/chrome/grit/ios_strings.h" +#import "ui/base/device_form_factor.h" #import "ui/base/l10n/l10n_util_mac.h" namespace { @@ -134,7 +134,13 @@ }; NSString* message; - message = l10n_util::GetNSString(IDS_IOS_LOCKDOWN_MODE_INFO_BUTTON_SUMMARY); + if (ui::GetDeviceFormFactor() == ui::DEVICE_FORM_FACTOR_TABLET) { + message = l10n_util::GetNSString( + IDS_IOS_LOCKDOWN_MODE_INFO_BUTTON_SUMMARY_FOR_IPAD); + } else { + message = l10n_util::GetNSString( + IDS_IOS_LOCKDOWN_MODE_INFO_BUTTON_SUMMARY_FOR_IPHONE); + } NSAttributedString* attributedString = [[NSAttributedString alloc] initWithString:message attributes:textAttributes];
diff --git a/media/capture/README.md b/media/capture/README.md new file mode 100644 index 0000000..ea2439e2 --- /dev/null +++ b/media/capture/README.md
@@ -0,0 +1 @@ +See [docs/media/capture/README.md](../../docs/media/capture/README.md)
diff --git a/media/gpu/vaapi/test/h265_decoder.cc b/media/gpu/vaapi/test/h265_decoder.cc index 7e519e90..3d8b9c95 100644 --- a/media/gpu/vaapi/test/h265_decoder.cc +++ b/media/gpu/vaapi/test/h265_decoder.cc
@@ -121,10 +121,10 @@ state_ = kAfterReset; } -H265Decoder::DecodeResult H265Decoder::Decode() { +H265Decoder::DecodeResult H265Decoder::DecodeNALUs() { DCHECK(state_ != kError) << "Decoder in error state"; - while (true) { + while (output_queue.empty()) { H265Parser::Result par_res; if (!curr_nalu_) { @@ -293,6 +293,8 @@ << static_cast<int>(curr_nalu_->nal_unit_type); curr_nalu_.reset(); } + + return kOk; } bool H265Decoder::ProcessPPS(int pps_id, bool* need_new_buffers) { @@ -876,7 +878,7 @@ VideoDecoder::Result H265Decoder::DecodeNextFrame() { while (!is_stream_over_ && output_queue.empty()) - Decode(); + DecodeNALUs(); if (is_stream_over_) OutputAllRemainingPics();
diff --git a/media/gpu/vaapi/test/h265_decoder.h b/media/gpu/vaapi/test/h265_decoder.h index 0b55398..03c9e49 100644 --- a/media/gpu/vaapi/test/h265_decoder.h +++ b/media/gpu/vaapi/test/h265_decoder.h
@@ -79,6 +79,7 @@ // properly (e.g. allocate buffers with the new // resolution). kRanOutOfStreamData, // Need more stream data to proceed. + kOk, // Decoded a frame successfully. }; // Process H265 stream structures. @@ -142,9 +143,9 @@ bool PerformDpbOperations(const H265SPS* sps); // This is the main method used for running the decode loop. It will try to - // decode all frames in the stream until there is a configuration change, - // error or the end of the stream is reached. - DecodeResult Decode(); + // decode a single frame in the stream, or up until it reaches either a + // configuration change, or the end of the stream. + DecodeResult DecodeNALUs(); // Decoder state. State state_;
diff --git a/media/remoting/README b/media/remoting/README.md similarity index 100% rename from media/remoting/README rename to media/remoting/README.md
diff --git a/net/base/features.cc b/net/base/features.cc index d600558..5569670 100644 --- a/net/base/features.cc +++ b/net/base/features.cc
@@ -369,6 +369,19 @@ &kEnableIpProtectionProxy, /*name=*/"IpPrivacyProxyAllowlist", /*default_value=*/""}; +const base::FeatureParam<std::string> kIpPrivacyTokenServer{ + &kEnableIpProtectionProxy, /*name=*/"IpPrivacyTokenServer", + /*default_value=*/"https://autopush-phosphor-pa.sandbox.googleapis.com"}; + +const base::FeatureParam<std::string> kIpPrivacyTokenServerGetInitialDataPath{ + &kEnableIpProtectionProxy, + /*name=*/"IpPrivacyTokenServerGetInitialDataPath", + /*default_value=*/"/v1/getInitialData"}; + +const base::FeatureParam<std::string> kIpPrivacyTokenServerGetTokensPath{ + &kEnableIpProtectionProxy, /*name=*/"IpPrivacyTokenServerGetTokensPath", + /*default_value=*/"/v1/authWithHeaderCreds"}; + const base::FeatureParam<int> kIpPrivacyAuthTokenCacheBatchSize{ &kEnableIpProtectionProxy, /*name=*/"IpPrivacyAuthTokenCacheBatchSize", /*default_value=*/64};
diff --git a/net/base/features.h b/net/base/features.h index de2a3f7..c22eb086 100644 --- a/net/base/features.h +++ b/net/base/features.h
@@ -385,6 +385,19 @@ NET_EXPORT extern const base::FeatureParam<std::string> kIpPrivacyProxyAllowlist; +// Sets the name of the IP protection auth token server. +NET_EXPORT extern const base::FeatureParam<std::string> kIpPrivacyTokenServer; + +// Sets the path component of the IP protection auth token server URL used for +// getting initial token signing data. +NET_EXPORT extern const base::FeatureParam<std::string> + kIpPrivacyTokenServerGetInitialDataPath; + +// Sets the path component of the IP protection auth token server URL used for +// getting blind-signed tokens. +NET_EXPORT extern const base::FeatureParam<std::string> + kIpPrivacyTokenServerGetTokensPath; + // Sets the batch size to fetch new auth tokens for IP protection. NET_EXPORT extern const base::FeatureParam<int> kIpPrivacyAuthTokenCacheBatchSize;
diff --git a/printing/backend/cups_helper.cc b/printing/backend/cups_helper.cc index ac026d7e..7d908c8 100644 --- a/printing/backend/cups_helper.cc +++ b/printing/backend/cups_helper.cc
@@ -403,6 +403,36 @@ return true; } +bool GetHpPjlColorAsGrayModeSettings(ppd_file_t* ppd, + mojom::ColorModel* color_model_for_black, + mojom::ColorModel* color_model_for_color, + bool* color_is_default) { + // Some HP printers use "HPPJLColorAsGray" attribute in their PPDs. + ppd_option_t* color_mode_option = ppdFindOption(ppd, kCUPSHpPjlColorAsGray); + if (!color_mode_option) { + return false; + } + + if (ppdFindChoice(color_mode_option, kHpPjlColorAsGrayYes)) { + *color_model_for_black = mojom::ColorModel::kHpPjlColorAsGrayYes; + } + + if (ppdFindChoice(color_mode_option, kHpPjlColorAsGrayNo)) { + *color_model_for_color = mojom::ColorModel::kHpPjlColorAsGrayNo; + } + + ppd_choice_t* marked_choice = ppdFindMarkedChoice(ppd, kCUPSHpPjlColorAsGray); + if (!marked_choice) { + marked_choice = + ppdFindChoice(color_mode_option, color_mode_option->defchoice); + } + if (marked_choice) { + *color_is_default = + EqualsCaseInsensitiveASCII(marked_choice->choice, kHpPjlColorAsGrayNo); + } + return true; +} + bool GetCanonCNColorModeSettings(ppd_file_t* ppd, mojom::ColorModel* color_model_for_black, mojom::ColorModel* color_model_for_color, @@ -707,6 +737,7 @@ GetColorModeSettings(ppd, cm_black, cm_color, is_color) || GetHPColorSettings(ppd, cm_black, cm_color, is_color) || GetHPColorModeSettings(ppd, cm_black, cm_color, is_color) || + GetHpPjlColorAsGrayModeSettings(ppd, cm_black, cm_color, is_color) || GetBrotherColorSettings(ppd, cm_black, cm_color, is_color) || GetCanonCNColorModeSettings(ppd, cm_black, cm_color, is_color) || GetCanonCNIJGrayscaleSettings(ppd, cm_black, cm_color, is_color) ||
diff --git a/printing/backend/cups_helper_unittest.cc b/printing/backend/cups_helper_unittest.cc index c44fa3c..8b2774d5 100644 --- a/printing/backend/cups_helper_unittest.cc +++ b/printing/backend/cups_helper_unittest.cc
@@ -419,8 +419,9 @@ } TEST(PrintBackendCupsHelperTest, PpdParsingHpPrinters) { - constexpr char kTestPpdData[] = - R"(*PPD-Adobe: "4.3" + { + constexpr char kTestPpdData[] = + R"(*PPD-Adobe: "4.3" *ColorDevice: True *OpenUI *HPColorMode/Mode: PickOne *DefaultHPColorMode: ColorPrint @@ -430,14 +431,35 @@ << /ProcessColorModel /DeviceGray >> setpagedevice" *CloseUI: *HPColorMode)"; - PrinterSemanticCapsAndDefaults caps; - EXPECT_TRUE(ParsePpdCapabilities(/*dest=*/nullptr, /*locale=*/"", - kTestPpdData, &caps)); - EXPECT_TRUE(caps.color_changeable); - EXPECT_TRUE(caps.color_default); - EXPECT_EQ(mojom::ColorModel::kHPColorColor, caps.color_model); - EXPECT_EQ(mojom::ColorModel::kHPColorBlack, caps.bw_model); - VerifyCapabilityColorModels(caps); + PrinterSemanticCapsAndDefaults caps; + EXPECT_TRUE(ParsePpdCapabilities(/*dest=*/nullptr, /*locale=*/"", + kTestPpdData, &caps)); + EXPECT_TRUE(caps.color_changeable); + EXPECT_TRUE(caps.color_default); + EXPECT_EQ(mojom::ColorModel::kHPColorColor, caps.color_model); + EXPECT_EQ(mojom::ColorModel::kHPColorBlack, caps.bw_model); + VerifyCapabilityColorModels(caps); + } + + { + constexpr char kTestPpdData[] = + R"(*PPD-Adobe: "4.3" +*ColorDevice: True +*OpenUI *HPPJLColorAsGray/Print Color as Gray: PickOne +*DefaultHPPJLColorAsGray: no +*HPPJLColorAsGray yes/On: " " +*HPPJLColorAsGray no/Off: " " +*CloseUI: *HPPJLColorAsGray)"; + + PrinterSemanticCapsAndDefaults caps; + EXPECT_TRUE(ParsePpdCapabilities(/*dest=*/nullptr, /*locale=*/"", + kTestPpdData, &caps)); + EXPECT_TRUE(caps.color_changeable); + EXPECT_TRUE(caps.color_default); + EXPECT_EQ(mojom::ColorModel::kHpPjlColorAsGrayNo, caps.color_model); + EXPECT_EQ(mojom::ColorModel::kHpPjlColorAsGrayYes, caps.bw_model); + VerifyCapabilityColorModels(caps); + } } TEST(PrintBackendCupsHelperTest, PpdParsingCanonPrinters) {
diff --git a/printing/mojom/print.mojom b/printing/mojom/print.mojom index 6c007213..b39b1f9a 100644 --- a/printing/mojom/print.mojom +++ b/printing/mojom/print.mojom
@@ -51,6 +51,8 @@ // Used in Xerox printer PPDs. [MinVersion=1] kXeroxXROutputColorPrintAsColor, [MinVersion=1] kXeroxXROutputColorPrintAsGrayscale, + [MinVersion=2] kHpPjlColorAsGrayNo, // Used in HP printer PPDs. + [MinVersion=2] kHpPjlColorAsGrayYes, // Used in HP printer PPDs. }; // Print job duplex mode values.
diff --git a/printing/print_job_constants_cups.cc b/printing/print_job_constants_cups.cc index fc8084c7..a5a2e6e 100644 --- a/printing/print_job_constants_cups.cc +++ b/printing/print_job_constants_cups.cc
@@ -19,6 +19,7 @@ const char kCUPSCanonCNIJGrayScale[] = "CNIJGrayScale"; const char kCUPSEpsonInk[] = "Ink"; const char kCUPSHpColorMode[] = "HPColorMode"; +const char kCUPSHpPjlColorAsGray[] = "HPPJLColorAsGray"; const char kCUPSKonicaMinoltaSelectColor[] = "SelectColor"; const char kCUPSLexmarkBLW[] = "BLW"; const char kCUPSOkiControl[] = "OKControl"; @@ -44,6 +45,8 @@ const char kHighGray[] = "High.Gray"; const char kHpColorPrint[] = "ColorPrint"; const char kHpGrayscalePrint[] = "GrayscalePrint"; +const char kHpPjlColorAsGrayNo[] = "no"; +const char kHpPjlColorAsGrayYes[] = "yes"; const char kLexmarkBLWFalse[] = "FalseM"; const char kLexmarkBLWTrue[] = "TrueM"; const char kMono[] = "Mono"; @@ -75,6 +78,7 @@ {kCUPSColorModel, kGray, kColor}, // Generic {kCUPSEpsonInk, kEpsonMono, kEpsonColor}, // Epson {kCUPSHpColorMode, kHpGrayscalePrint, kHpColorPrint}, // HP + {kCUPSHpPjlColorAsGray, kHpPjlColorAsGrayYes, kHpPjlColorAsGrayNo}, // HP {kCUPSKonicaMinoltaSelectColor, kGrayscale, kColor}, // Konica Minolta {kCUPSLexmarkBLW, kLexmarkBLWTrue, kLexmarkBLWFalse}, // Lexmark {kCUPSOkiControl, kGray, kAuto}, // Oki
diff --git a/printing/print_job_constants_cups.h b/printing/print_job_constants_cups.h index 716db7b..cdd2619 100644 --- a/printing/print_job_constants_cups.h +++ b/printing/print_job_constants_cups.h
@@ -31,6 +31,7 @@ COMPONENT_EXPORT(PRINTING_BASE) extern const char kCUPSCanonCNIJGrayScale[]; COMPONENT_EXPORT(PRINTING_BASE) extern const char kCUPSEpsonInk[]; COMPONENT_EXPORT(PRINTING_BASE) extern const char kCUPSHpColorMode[]; +COMPONENT_EXPORT(PRINTING_BASE) extern const char kCUPSHpPjlColorAsGray[]; COMPONENT_EXPORT(PRINTING_BASE) extern const char kCUPSKonicaMinoltaSelectColor[]; COMPONENT_EXPORT(PRINTING_BASE) extern const char kCUPSLexmarkBLW[]; @@ -57,6 +58,8 @@ COMPONENT_EXPORT(PRINTING_BASE) extern const char kHighGray[]; COMPONENT_EXPORT(PRINTING_BASE) extern const char kHpColorPrint[]; COMPONENT_EXPORT(PRINTING_BASE) extern const char kHpGrayscalePrint[]; +COMPONENT_EXPORT(PRINTING_BASE) extern const char kHpPjlColorAsGrayNo[]; +COMPONENT_EXPORT(PRINTING_BASE) extern const char kHpPjlColorAsGrayYes[]; COMPONENT_EXPORT(PRINTING_BASE) extern const char kKonicaMinoltaColor[]; COMPONENT_EXPORT(PRINTING_BASE) extern const char kKonicaMinoltaGrayscale[]; COMPONENT_EXPORT(PRINTING_BASE) extern const char kLexmarkBLWFalse[];
diff --git a/printing/print_settings.cc b/printing/print_settings.cc index e6f6692..8f75e613 100644 --- a/printing/print_settings.cc +++ b/printing/print_settings.cc
@@ -93,6 +93,14 @@ *color_setting_name = kColor; *color_value = kBlack; break; + case mojom::ColorModel::kHpPjlColorAsGrayNo: + *color_setting_name = kCUPSHpPjlColorAsGray; + *color_value = kHpPjlColorAsGrayNo; + break; + case mojom::ColorModel::kHpPjlColorAsGrayYes: + *color_setting_name = kCUPSHpPjlColorAsGray; + *color_value = kHpPjlColorAsGrayYes; + break; case mojom::ColorModel::kPrintoutModeNormal: *color_setting_name = kCUPSPrintoutMode; *color_value = kNormal; @@ -223,6 +231,7 @@ case mojom::ColorModel::kRGBA: case mojom::ColorModel::kColorModeColor: case mojom::ColorModel::kHPColorColor: + case mojom::ColorModel::kHpPjlColorAsGrayNo: case mojom::ColorModel::kPrintoutModeNormal: case mojom::ColorModel::kProcessColorModelCMYK: case mojom::ColorModel::kProcessColorModelRGB: @@ -242,6 +251,7 @@ case mojom::ColorModel::kGrayscale: case mojom::ColorModel::kColorModeMonochrome: case mojom::ColorModel::kHPColorBlack: + case mojom::ColorModel::kHpPjlColorAsGrayYes: case mojom::ColorModel::kPrintoutModeNormalGray: case mojom::ColorModel::kProcessColorModelGreyscale: case mojom::ColorModel::kBrotherCUPSMono:
diff --git a/services/device/generic_sensor/fake_platform_sensor_and_provider.cc b/services/device/generic_sensor/fake_platform_sensor_and_provider.cc index c382f97..7d1df16 100644 --- a/services/device/generic_sensor/fake_platform_sensor_and_provider.cc +++ b/services/device/generic_sensor/fake_platform_sensor_and_provider.cc
@@ -70,6 +70,10 @@ UpdateSharedBufferAndNotifyClients(reading); } +void FakePlatformSensor::TriggerError() { + NotifySensorError(); +} + FakePlatformSensorProvider::FakePlatformSensorProvider() { ON_CALL(*this, DoCreateSensorInternal(_, _, _)) .WillByDefault(
diff --git a/services/device/generic_sensor/fake_platform_sensor_and_provider.h b/services/device/generic_sensor/fake_platform_sensor_and_provider.h index ca906bb..3e0e2f3 100644 --- a/services/device/generic_sensor/fake_platform_sensor_and_provider.h +++ b/services/device/generic_sensor/fake_platform_sensor_and_provider.h
@@ -33,6 +33,9 @@ // Public interface to UpdateSharedBufferAndNotifyClients(). void AddNewReading(const SensorReading& reading); + // Public interface to NotifySensorError(). + void TriggerError(); + protected: void StopSensor() override {}
diff --git a/services/device/generic_sensor/generic_sensor_service_unittest.cc b/services/device/generic_sensor/generic_sensor_service_unittest.cc index fb39afa..2b866b5 100644 --- a/services/device/generic_sensor/generic_sensor_service_unittest.cc +++ b/services/device/generic_sensor/generic_sensor_service_unittest.cc
@@ -4,6 +4,7 @@ #include "base/barrier_closure.h" #include "base/functional/bind.h" +#include "base/functional/callback_forward.h" #include "base/functional/callback_helpers.h" #include "base/memory/ptr_util.h" #include "base/memory/raw_ptr.h" @@ -51,7 +52,11 @@ std::move(on_reading_changed_callback_).Run(reading_data_.als.value); } } - void RaiseError() override {} + void RaiseError() override { + if (on_error_callback_) { + std::move(on_error_callback_).Run(); + } + } double WaitForReading() { base::test::TestFuture<double> future; @@ -95,6 +100,11 @@ on_reading_changed_callback_ = std::move(callback); } + // For RaiseError(). + void SetOnErrorCallback(base::OnceClosure callback) { + on_error_callback_ = std::move(callback); + } + mojom::Sensor* sensor() { return sensor_.get(); } void ResetSensor() { sensor_.reset(); } @@ -108,6 +118,9 @@ // |on_reading_changed_callback_| is called to verify the data is same as we // expected in SensorReadingChanged(). base::OnceCallback<void(double)> on_reading_changed_callback_; + + base::OnceClosure on_error_callback_; + SensorType type_; }; @@ -317,6 +330,39 @@ EXPECT_TRUE(client->AddConfigurationSync(PlatformSensorConfiguration(31.0))); } +// Tests that error notifications are delivered even if a sensor is suspended. +TEST_F(GenericSensorServiceTest, ErrorWhileSuspendedTest) { + auto client = std::make_unique<TestSensorClient>(SensorType::AMBIENT_LIGHT); + { + base::RunLoop run_loop; + sensor_provider_->GetSensor( + SensorType::AMBIENT_LIGHT, + base::BindOnce(&TestSensorClient::OnSensorCreated, + base::Unretained(client.get()), run_loop.QuitClosure())); + run_loop.Run(); + } + + client->sensor()->Suspend(); + + // Expect that SensorReadingChanged() will not be called. + client->SetOnReadingChangedCallback( + base::BindOnce([](double) { ADD_FAILURE() << "Unexpected reading."; })); + + EXPECT_TRUE(client->AddConfigurationSync(PlatformSensorConfiguration(30.0))); + + // Expect that RaiseError() will be called. + base::test::TestFuture<void> error_future; + client->SetOnErrorCallback(error_future.GetCallback()); + + auto scoped_sensor = + fake_platform_sensor_provider_->GetSensor(SensorType::AMBIENT_LIGHT); + auto* fake_platform_sensor = + static_cast<FakePlatformSensor*>(scoped_sensor.get()); + fake_platform_sensor->TriggerError(); + + EXPECT_TRUE(error_future.Wait()); +} + // Test suspend and resume. After resuming, client can add configuration and // be notified by SensorReadingChanged() as usual. TEST_F(GenericSensorServiceTest, SuspendThenResumeTest) {
diff --git a/services/device/generic_sensor/sensor_impl.cc b/services/device/generic_sensor/sensor_impl.cc index ad65fe3a..1887960 100644 --- a/services/device/generic_sensor/sensor_impl.cc +++ b/services/device/generic_sensor/sensor_impl.cc
@@ -64,7 +64,6 @@ } void SensorImpl::OnSensorError() { - DCHECK(!suspended_); if (client_) client_->RaiseError(); }
diff --git a/services/network/network_service_proxy_allow_list.cc b/services/network/network_service_proxy_allow_list.cc index db249bc..c6860b9 100644 --- a/services/network/network_service_proxy_allow_list.cc +++ b/services/network/network_service_proxy_allow_list.cc
@@ -4,8 +4,6 @@ // #include "services/network/network_service_proxy_allow_list.h" -#include <memory> - #include "base/command_line.h" #include "base/strings/strcat.h" #include "components/privacy_sandbox/masked_domain_list/masked_domain_list.pb.h" @@ -15,6 +13,30 @@ #include "services/network/public/cpp/network_switches.h" namespace network { +namespace { + +void AddBypassRulesForDomain(net::ProxyBypassRules& bypass_rules, + const std::string& domain) { + CHECK(bypass_rules.AddRuleFromString(domain)); + if (!(domain.starts_with(".") || domain.starts_with("*"))) { + // Also bypass proxy for any subdomains. + CHECK(bypass_rules.AddRuleFromString("." + domain)); + } +} + +net::ProxyBypassRules BuildBypassRules( + const masked_domain_list::ResourceOwner& resource_owner) { + net::ProxyBypassRules bypass_rules; + for (auto resource : resource_owner.owned_resources()) { + AddBypassRulesForDomain(bypass_rules, resource.domain()); + } + for (auto property : resource_owner.owned_properties()) { + AddBypassRulesForDomain(bypass_rules, property); + } + return bypass_rules; +} + +} // namespace NetworkServiceProxyAllowList::NetworkServiceProxyAllowList() { custom_proxy_config_ = network::mojom::CustomProxyConfig::New(); @@ -161,14 +183,8 @@ // domains that will allow proxy bypass. allow_list_with_bypass_map_.clear(); for (auto owner : mdl.resource_owners()) { - net::ProxyBypassRules bypass_rules; + net::ProxyBypassRules bypass_rules = BuildBypassRules(owner); for (auto resource : owner.owned_resources()) { - for (auto property : owner.owned_properties()) { - CHECK(bypass_rules.AddRuleFromString(property)); - // Also bypass proxy for any subdomains. - CHECK(bypass_rules.AddRuleFromString("." + property)); - } - AddDomainRules(resource.domain(), bypass_rules); } }
diff --git a/services/network/network_service_proxy_allow_list_unittest.cc b/services/network/network_service_proxy_allow_list_unittest.cc index e4c9bcf2..17554b89 100644 --- a/services/network/network_service_proxy_allow_list_unittest.cc +++ b/services/network/network_service_proxy_allow_list_unittest.cc
@@ -185,7 +185,11 @@ // subdomains) in the MDL should be not be proxied when the top-level site // is a property with the same owner as the resource. MatchTest{"3PRsrcInPropSameOwner", "acme-ra.com", "acme-pa.com", false}, - MatchTest{"3PRsrcInRsrcSameOwner", "acme-ra.com", "acme-rb.co.uk", true}, + MatchTest{"3PRsrcInRsrcSameOwner", "acme-ra.com", "acme-rb.co.uk", false}, + MatchTest{"3PRsrcInSubRsrcSameOwner", "acme-ra.com", "sub.acme-rb.co.uk", + false}, + MatchTest{"3PSubRsrcInSubRsrcSameOwner", "sub.acme-ra.com", + "sub.acme-rb.co.uk", false}, MatchTest{"3PSubSameOwner", "sub.acme-ra.com", "acme-pa.com", false}, MatchTest{"3PSubSubSameOwner", "sub.sub.acme-ra.com", "acme-pa.com", false}, };
diff --git a/testing/buildbot/filters/android.emulator_o.chrome_public_test_apk.filter b/testing/buildbot/filters/android.emulator_o.chrome_public_test_apk.filter index 88fcba9..2eb5e465 100644 --- a/testing/buildbot/filters/android.emulator_o.chrome_public_test_apk.filter +++ b/testing/buildbot/filters/android.emulator_o.chrome_public_test_apk.filter
@@ -4,8 +4,5 @@ # TODO(crbug/1345504) -org.chromium.chrome.browser.shape_detection.ShapeDetectionTest.testTextDetection -# TODO(crbug/1465894) --org.chromium.chrome.browser.keyboard_accessory.sheet_tabs.PasswordAccessoryIntegrationTest.testPasswordSheetDisplaysProvidedItems - # TODO(crbug/1469692) -org.chromium.chrome.browser.browsing_data.ClearBrowsingDataFragmentBasicTest.testRenderSearchHistoryLinkSignedOutKnownNonGoogleDSE
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index 79ff961..ddfc5ca 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -13181,6 +13181,21 @@ ] } ], + "RestoreTabsOnFRE": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "RestoreTabsOnFRE" + ] + } + ] + } + ], "RestoreUmaClientIdIndependentLogs": [ { "platforms": [
diff --git a/third_party/blink/public/mojom/service_worker/service_worker_fetch_handler_bypass_option.mojom b/third_party/blink/public/mojom/service_worker/service_worker_fetch_handler_bypass_option.mojom index 66a7a69..434cbf4 100644 --- a/third_party/blink/public/mojom/service_worker/service_worker_fetch_handler_bypass_option.mojom +++ b/third_party/blink/public/mojom/service_worker/service_worker_fetch_handler_bypass_option.mojom
@@ -15,4 +15,5 @@ kBypassOnlyIfServiceWorkerNotStarted, kRaceNetworkRequest, kRaceNetworkRequestHoldback, + kAutoPreload, };
diff --git a/third_party/blink/renderer/build/scripts/core/style/make_computed_style_base.py b/third_party/blink/renderer/build/scripts/core/style/make_computed_style_base.py index ec263718..053b5f02 100755 --- a/third_party/blink/renderer/build/scripts/core/style/make_computed_style_base.py +++ b/third_party/blink/renderer/build/scripts/core/style/make_computed_style_base.py
@@ -30,6 +30,8 @@ 'RotateTransformOperation', 'TranslateTransformOperation', 'NGGridTrackList', + 'StyleHighlightData', + 'FilterOperations', 'ComputedGridTrackList', 'absl::optional<gfx::Size>', 'double', @@ -46,7 +48,6 @@ 'ScrollStartData', 'AtomicString', 'scoped_refptr', - 'Persistent', 'std::unique_ptr', 'Vector<String>', 'Font', @@ -59,6 +60,8 @@ 'StyleIntrinsicLength', 'absl::optional<StyleScrollbarColor>', 'absl::optional<StyleOverflowClipMargin>', + # Compressed builds a Member can be 32 bits, vs. a pointer will be 64. + 'Member', # Aligns like float 'absl::optional<Length>', 'StyleInitialLetter',
diff --git a/third_party/blink/renderer/build/scripts/core/style/templates/computed_style_base.cc.tmpl b/third_party/blink/renderer/build/scripts/core/style/templates/computed_style_base.cc.tmpl index 097b0f2..ce5a872 100644 --- a/third_party/blink/renderer/build/scripts/core/style/templates/computed_style_base.cc.tmpl +++ b/third_party/blink/renderer/build/scripts/core/style/templates/computed_style_base.cc.tmpl
@@ -15,21 +15,6 @@ namespace blink { -struct SameSizeVerifierForComputedStyleBase { - {% if computed_style.subgroups is defined %} - void* data_refs[{{computed_style.subgroups|length}}]; - {% endif %} - {% for field in computed_style.fields|rejectattr("is_bit_field") %} - {{field.type_name}} {{field.name}}; - {% endfor %} - unsigned bit_fields[{{computed_style.num_32_bit_words_for_bit_fields}}]; -}; - -// If this fails, the packing algorithm in make_computed_style_base.py has -// failed to produce the optimal packed size. To fix, update the algorithm to -// ensure that the buckets are placed so that each takes up at most 1 word. -ASSERT_SIZE(ComputedStyleBase, SameSizeVerifierForComputedStyleBase); - // Constructor and destructor are protected so that only the parent class ComputedStyle // can instantiate this class. ComputedStyleBase::ComputedStyleBase() : @@ -69,6 +54,10 @@ {% endfor %} } +void ComputedStyleBase::Trace(Visitor* visitor) const { + static_cast<const ComputedStyle*>(this)->TraceAfterDispatch(visitor); +} + {% for name, groups_to_diff in diff_functions_map.items() %} bool ComputedStyleBase::{{name}}(const ComputedStyle& a, const ComputedStyle& b) { {{fieldwise_diff(groups_to_diff)|indent(4)}}
diff --git a/third_party/blink/renderer/build/scripts/core/style/templates/computed_style_base.h.tmpl b/third_party/blink/renderer/build/scripts/core/style/templates/computed_style_base.h.tmpl index 1882284..7f9bc91 100644 --- a/third_party/blink/renderer/build/scripts/core/style/templates/computed_style_base.h.tmpl +++ b/third_party/blink/renderer/build/scripts/core/style/templates/computed_style_base.h.tmpl
@@ -13,6 +13,7 @@ #include "third_party/blink/renderer/core/style/data_ref.h" #include "third_party/blink/renderer/core/style/member_copy.h" #include "third_party/blink/renderer/core/style/computed_style_initial_values.h" +#include "third_party/blink/renderer/core/style/style_cached_data.h" {% for path in include_paths %} #include "{{path}}" {% endfor %} @@ -90,7 +91,7 @@ // example, a field with the 'keyword' template has only one setter, whereas an // 'external' field has an extra setter that takes an rvalue reference. A list // of the available templates can be found in css_properties.json5. -class ComputedStyleBase { +class ComputedStyleBase : public GarbageCollected<ComputedStyleBase> { // Properties with protected accessors must be friends because // Longhand::Apply* functions typically need the "raw" computed value: {% for property in longhands %} @@ -192,6 +193,18 @@ CORE_EXPORT Vector<DebugDiff> DebugDiffFields(const ComputedStyleBase& o) const; #endif // DCHECK_IS_ON() + CORE_EXPORT void Trace(Visitor* visitor) const; + void TraceAfterDispatch(Visitor* visitor) const { + {% for subgroup in computed_style.subgroups %} + visitor->Trace({{subgroup.member_name}}); + {% endfor %} + {% for field in computed_style.fields %} + {% if field.wrapper_pointer_name == 'Member' %} + visitor->Trace({{field.name}}); + {% endif %} + {% endfor %} + } + private: {% for subgroup in computed_style.subgroups %} {{declare_field_group_class(subgroup)|indent(2)}} @@ -215,8 +228,6 @@ {% endif %} {% endfor %} - ~ComputedStyleBase() = default; - private: friend class ComputedStyleBuilder; friend class ComputedStyleBuilderBase; @@ -296,4 +307,21 @@ } // namespace blink +namespace blink { +{% for group in computed_style.all_subgroups|sort(attribute='name') %} +template <typename T> +struct ThreadingTrait< + T, + std::enable_if_t<std::is_base_of<blink::ComputedStyleBase::{{group.type_name}}, T>::value>> { + static constexpr ThreadAffinity kAffinity = kMainThreadOnly; +}; +{% endfor %} +template <typename T> +struct ThreadingTrait< + T, + std::enable_if_t<std::is_base_of<blink::ComputedStyleBase, T>::value>> { + static constexpr ThreadAffinity kAffinity = kMainThreadOnly; +}; +} // namespace blink + #endif // THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_COMPUTED_STYLE_BASE_H_
diff --git a/third_party/blink/renderer/build/scripts/templates/fields/field.tmpl b/third_party/blink/renderer/build/scripts/templates/fields/field.tmpl index af753cd..f70dbfd 100644 --- a/third_party/blink/renderer/build/scripts/templates/fields/field.tmpl +++ b/third_party/blink/renderer/build/scripts/templates/fields/field.tmpl
@@ -210,7 +210,7 @@ {% else -%} {{comma()}}{{member}}({{parent}} == {{noninherited}} ? {{parent}} - : DataRef(base::AdoptRef(new {{subgroup.type_name}}(*{{noninherited}}, *{{parent}})))) + : DataRef(MakeGarbageCollected<{{subgroup.type_name}}>(*{{noninherited}}, *{{parent}}))) {% endif %} {% endfor %} {% for field in group.fields %}
diff --git a/third_party/blink/renderer/build/scripts/templates/fields/group.tmpl b/third_party/blink/renderer/build/scripts/templates/fields/group.tmpl index 780a2d1..167771d 100644 --- a/third_party/blink/renderer/build/scripts/templates/fields/group.tmpl +++ b/third_party/blink/renderer/build/scripts/templates/fields/group.tmpl
@@ -5,13 +5,16 @@ {{declare_field_group_class(subgroup)}} {% endfor %} -class {{group.type_name}} : public RefCounted<{{group.type_name}}> { +class {{group.type_name}} : public GarbageCollected<{{group.type_name}}> { public: - static scoped_refptr<{{group.type_name}}> Create() { - return base::AdoptRef(new {{group.type_name}}); + explicit {{group.type_name}}(); + CORE_EXPORT {{group.type_name}}(const {{group.type_name}}&); + + static {{group.type_name}}* Create() { + return MakeGarbageCollected<{{group.type_name}}>(); } - scoped_refptr<{{group.type_name}}> Copy() const { - return base::AdoptRef(new {{group.type_name}}(*this)); + {{group.type_name}}* Copy() const { + return MakeGarbageCollected<{{group.type_name}}>(*this); } {% if group.all_fields|selectattr("is_inherited")|list|length > 0 and @@ -25,23 +28,17 @@ } {% endif %} - // See comments in ComputedStyle. - void* operator new(size_t size) { - DCHECK(IsMainThread()); - if (freelist_ != nullptr) { - {{group.type_name}}* ret = freelist_; - freelist_ = nullptr; - return ret; - } - return ::WTF::Partitions::FastMalloc(size, "{{group.type_name}}"); - } - void operator delete(void* p) { - DCHECK(IsMainThread()); - if (freelist_ == nullptr) { - freelist_ = static_cast<{{group.type_name}}*>(p); - } else { - ::WTF::Partitions::FastFree(p); - } + CORE_EXPORT void Trace(Visitor* visitor) const { + {% for subgroup in group.subgroups %} + visitor->Trace({{subgroup.member_name}}); + {% endfor %} + {% for field in group.fields %} + {% if field.wrapper_pointer_name == 'Member' %} + visitor->Trace({{field.name}}); + {% elif not field.size and not field.wrapper_pointer_name %} + TraceIfNeeded<{{field.type_name}}>::Trace(visitor, {{field.name}}); + {% endif %} + {% endfor %} } bool operator==(const {{group.type_name}}& other) const { @@ -63,12 +60,6 @@ {% for field in group.fields %} {{declare_storage(field)}} {% endfor %} - - private: - {{group.type_name}}(); - CORE_EXPORT {{group.type_name}}(const {{group.type_name}}&); - - CORE_EXPORT static {{group.type_name}}* freelist_; }; {%- endmacro %} @@ -100,7 +91,4 @@ {% endif %} {% endfor %} {} - -CORE_EXPORT ComputedStyleBase::{{group.type_name}}* -ComputedStyleBase::{{group.type_name}}::freelist_ = nullptr; {%- endmacro %}
diff --git a/third_party/blink/renderer/core/animation/animation_utils.cc b/third_party/blink/renderer/core/animation/animation_utils.cc index 0b7ced5..f689901d 100644 --- a/third_party/blink/renderer/core/animation/animation_utils.cc +++ b/third_party/blink/renderer/core/animation/animation_utils.cc
@@ -37,7 +37,7 @@ return; StyleResolver& resolver = target->GetDocument().GetStyleResolver(); - scoped_refptr<const ComputedStyle> style = + const ComputedStyle* style = resolver.StyleForInterpolations(*target, interpolations); for (const auto& property : properties) {
diff --git a/third_party/blink/renderer/core/animation/compositor_animations_test.cc b/third_party/blink/renderer/core/animation/compositor_animations_test.cc index 08ede45..2a53bd2 100644 --- a/third_party/blink/renderer/core/animation/compositor_animations_test.cc +++ b/third_party/blink/renderer/core/animation/compositor_animations_test.cc
@@ -200,7 +200,7 @@ const Timing& timing, const KeyframeEffectModelBase& effect) { // TODO(crbug.com/725385): Remove once compositor uses InterpolationTypes. - auto style = GetDocument().GetStyleResolver().ResolveStyle( + const auto* style = GetDocument().GetStyleResolver().ResolveStyle( element_, StyleRecalcContext()); effect.SnapshotAllCompositorKeyframesIfNecessary(*element_.Get(), *style, nullptr); @@ -500,7 +500,7 @@ // As the compositor code only understands CompositorKeyframeValues, we must // snapshot the effect to make those available. // TODO(crbug.com/725385): Remove once compositor uses InterpolationTypes. - auto style = GetDocument().GetStyleResolver().ResolveStyle( + const auto* style = GetDocument().GetStyleResolver().ResolveStyle( element_, StyleRecalcContext()); effect.SnapshotAllCompositorKeyframesIfNecessary(*element_.Get(), *style, nullptr); @@ -672,7 +672,7 @@ SetCustomProperty("--x", "5"); UpdateAllLifecyclePhasesForTest(); - auto style = GetDocument().GetStyleResolver().ResolveStyle( + const auto* style = GetDocument().GetStyleResolver().ResolveStyle( element_, StyleRecalcContext()); EXPECT_TRUE(style->NonInheritedVariables()); EXPECT_TRUE(style->NonInheritedVariables()
diff --git a/third_party/blink/renderer/core/animation/css/css_animation_update.cc b/third_party/blink/renderer/core/animation/css/css_animation_update.cc index 4b14fb2..50aca22 100644 --- a/third_party/blink/renderer/core/animation/css/css_animation_update.cc +++ b/third_party/blink/renderer/core/animation/css/css_animation_update.cc
@@ -52,19 +52,14 @@ void CSSAnimationUpdate::StartTransition( const PropertyHandle& property, - scoped_refptr<const ComputedStyle> from, - scoped_refptr<const ComputedStyle> to, - scoped_refptr<const ComputedStyle> reversing_adjusted_start_value, + const ComputedStyle* from, + const ComputedStyle* to, + const ComputedStyle* reversing_adjusted_start_value, double reversing_shortening_factor, const InertEffect& effect) { - NewTransition* new_transition = MakeGarbageCollected<NewTransition>(); - new_transition->property = property; - new_transition->from = std::move(from); - new_transition->to = std::move(to); - new_transition->reversing_adjusted_start_value = - std::move(reversing_adjusted_start_value); - new_transition->reversing_shortening_factor = reversing_shortening_factor; - new_transition->effect = &effect; + NewTransition* new_transition = MakeGarbageCollected<NewTransition>( + property, from, to, reversing_adjusted_start_value, + reversing_shortening_factor, &effect); new_transitions_.Set(property, new_transition); } @@ -72,7 +67,4 @@ new_transitions_.erase(property); } -CSSAnimationUpdate::NewTransition::NewTransition() = default; -CSSAnimationUpdate::NewTransition::~NewTransition() = default; - } // namespace blink
diff --git a/third_party/blink/renderer/core/animation/css/css_animation_update.h b/third_party/blink/renderer/core/animation/css/css_animation_update.h index b472dedd..131b682 100644 --- a/third_party/blink/renderer/core/animation/css/css_animation_update.h +++ b/third_party/blink/renderer/core/animation/css/css_animation_update.h
@@ -19,6 +19,7 @@ #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/css/css_keyframes_rule.h" #include "third_party/blink/renderer/core/css/css_property_equality.h" +#include "third_party/blink/renderer/core/style/computed_style.h" #include "third_party/blink/renderer/core/style/scoped_css_name.h" #include "third_party/blink/renderer/platform/heap/collection_support/heap_hash_map.h" #include "third_party/blink/renderer/platform/heap/collection_support/heap_hash_set.h" @@ -180,13 +181,12 @@ updated_compositor_keyframes_.push_back(animation); } - void StartTransition( - const PropertyHandle&, - scoped_refptr<const ComputedStyle> from, - scoped_refptr<const ComputedStyle> to, - scoped_refptr<const ComputedStyle> reversing_adjusted_start_value, - double reversing_shortening_factor, - const InertEffect&); + void StartTransition(const PropertyHandle&, + const ComputedStyle* from, + const ComputedStyle* to, + const ComputedStyle* reversing_adjusted_start_value, + double reversing_shortening_factor, + const InertEffect&); void UnstartTransition(const PropertyHandle&); void CancelTransition(const PropertyHandle& property) { cancelled_transitions_.insert(property); @@ -232,14 +232,29 @@ struct NewTransition : public GarbageCollected<NewTransition> { public: - NewTransition(); - virtual ~NewTransition(); - void Trace(Visitor* visitor) const { visitor->Trace(effect); } + NewTransition(const PropertyHandle& property, + const ComputedStyle* from, + const ComputedStyle* to, + const ComputedStyle* reversing_adjusted_start_value, + double reversing_shortening_factor, + const InertEffect* effect) + : property(property), + from(from), + to(to), + reversing_adjusted_start_value(reversing_adjusted_start_value), + reversing_shortening_factor(reversing_shortening_factor), + effect(effect) {} + void Trace(Visitor* visitor) const { + visitor->Trace(from); + visitor->Trace(to); + visitor->Trace(reversing_adjusted_start_value); + visitor->Trace(effect); + } PropertyHandle property = HashTraits<blink::PropertyHandle>::EmptyValue(); - scoped_refptr<const ComputedStyle> from; - scoped_refptr<const ComputedStyle> to; - scoped_refptr<const ComputedStyle> reversing_adjusted_start_value; + Member<const ComputedStyle> from; + Member<const ComputedStyle> to; + Member<const ComputedStyle> reversing_adjusted_start_value; double reversing_shortening_factor; Member<const InertEffect> effect; };
diff --git a/third_party/blink/renderer/core/animation/css/css_animations.cc b/third_party/blink/renderer/core/animation/css/css_animations.cc index 88c9f7b..3e6e056 100644 --- a/third_party/blink/renderer/core/animation/css/css_animations.cc +++ b/third_party/blink/renderer/core/animation/css/css_animations.cc
@@ -2132,15 +2132,6 @@ if (suppressed_transitions.Contains(property)) continue; - RunningTransition* running_transition = - MakeGarbageCollected<RunningTransition>(); - running_transition->from = new_transition->from; - running_transition->to = new_transition->to; - running_transition->reversing_adjusted_start_value = - new_transition->reversing_adjusted_start_value; - running_transition->reversing_shortening_factor = - new_transition->reversing_shortening_factor; - const InertEffect* inert_animation = new_transition->effect.Get(); TransitionEventDelegate* event_delegate = MakeGarbageCollected<TransitionEventDelegate>(element, property); @@ -2164,7 +2155,12 @@ ASSERT_NO_EXCEPTION); } animation->Update(kTimingUpdateOnDemand); - running_transition->animation = animation; + + RunningTransition* running_transition = + MakeGarbageCollected<RunningTransition>( + animation, new_transition->from, new_transition->to, + new_transition->reversing_adjusted_start_value, + new_transition->reversing_shortening_factor); transitions_.Set(property, running_transition); } ClearPendingUpdate(); @@ -2371,14 +2367,14 @@ } const ComputedStyle* reversing_adjusted_start_value = - state.before_change_style.get(); + state.before_change_style; double reversing_shortening_factor = 1; if (interrupted_transition) { AnimationEffect* effect = interrupted_transition->animation->effect(); const absl::optional<double> interrupted_progress = effect ? effect->Progress() : absl::nullopt; if (interrupted_progress) { - reversing_adjusted_start_value = interrupted_transition->to.get(); + reversing_adjusted_start_value = interrupted_transition->to; reversing_shortening_factor = ClampTo((interrupted_progress.value() * interrupted_transition->reversing_shortening_factor) + @@ -2596,7 +2592,7 @@ CalculateTransitionActiveInterpolations(update, animating_element); } -scoped_refptr<const ComputedStyle> CSSAnimations::CalculateBeforeChangeStyle( +const ComputedStyle* CSSAnimations::CalculateBeforeChangeStyle( Element& animating_element, const ComputedStyle& base_style) { ActiveInterpolationsMap interpolations_map;
diff --git a/third_party/blink/renderer/core/animation/css/css_animations.h b/third_party/blink/renderer/core/animation/css/css_animations.h index 74bd117..887ea64 100644 --- a/third_party/blink/renderer/core/animation/css/css_animations.h +++ b/third_party/blink/renderer/core/animation/css/css_animations.h
@@ -188,14 +188,28 @@ struct RunningTransition : public GarbageCollected<RunningTransition> { public: - virtual ~RunningTransition() = default; + RunningTransition(Animation* animation, + const ComputedStyle* from, + const ComputedStyle* to, + const ComputedStyle* reversing_adjusted_start_value, + double reversing_shortening_factor) + : animation(animation), + from(from), + to(to), + reversing_adjusted_start_value(reversing_adjusted_start_value), + reversing_shortening_factor(reversing_shortening_factor) {} - void Trace(Visitor* visitor) const { visitor->Trace(animation); } + void Trace(Visitor* visitor) const { + visitor->Trace(animation); + visitor->Trace(from); + visitor->Trace(to); + visitor->Trace(reversing_adjusted_start_value); + } Member<Animation> animation; - scoped_refptr<const ComputedStyle> from; - scoped_refptr<const ComputedStyle> to; - scoped_refptr<const ComputedStyle> reversing_adjusted_start_value; + Member<const ComputedStyle> from; + Member<const ComputedStyle> to; + Member<const ComputedStyle> reversing_adjusted_start_value; double reversing_shortening_factor; }; @@ -261,7 +275,7 @@ Element& animating_element; const ComputedStyle& old_style; const ComputedStyle& base_style; - scoped_refptr<const ComputedStyle> before_change_style; + const ComputedStyle* before_change_style; const TransitionMap* active_transitions; HashSet<PropertyHandle>* listed_properties; const CSSTransitionData* transition_data; @@ -380,7 +394,7 @@ // on the element as of the previous style change event, except with any // styles derived from declarative animations updated to the current time. // https://drafts.csswg.org/css-transitions-1/#before-change-style - static scoped_refptr<const ComputedStyle> CalculateBeforeChangeStyle( + static const ComputedStyle* CalculateBeforeChangeStyle( Element& animating_element, const ComputedStyle& base_style);
diff --git a/third_party/blink/renderer/core/animation/css_length_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_length_interpolation_type.cc index 3b306be..156630c1 100644 --- a/third_party/blink/renderer/core/animation/css_length_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_length_interpolation_type.cc
@@ -137,7 +137,7 @@ .CreateLength(conversion_data, value_range_); if (LengthPropertyFunctions::SetLength(CssProperty(), builder, length)) { #if DCHECK_IS_ON() - scoped_refptr<const ComputedStyle> before_style = builder.CloneStyle(); + const ComputedStyle* before_style = builder.CloneStyle(); // Assert that setting the length on ComputedStyle directly is identical to // the StyleBuilder code path. This check is useful for catching differences // in clamping behavior. @@ -147,7 +147,7 @@ before)); StyleBuilder::ApplyProperty(GetProperty().GetCSSProperty(), state, *CSSValue::Create(length, zoom)); - scoped_refptr<const ComputedStyle> after_style = builder.CloneStyle(); + const ComputedStyle* after_style = builder.CloneStyle(); DCHECK( LengthPropertyFunctions::GetLength(CssProperty(), *after_style, after)); DCHECK(before.IsSpecified());
diff --git a/third_party/blink/renderer/core/animation/keyframe_effect_model_test.cc b/third_party/blink/renderer/core/animation/keyframe_effect_model_test.cc index 763ffc06..9060b83 100644 --- a/third_party/blink/renderer/core/animation/keyframe_effect_model_test.cc +++ b/third_party/blink/renderer/core/animation/keyframe_effect_model_test.cc
@@ -165,7 +165,7 @@ auto* effect = MakeGarbageCollected<StringKeyframeEffectModel>(keyframes); - auto style = + const auto* style = document->GetStyleResolver().ResolveStyle(element, StyleRecalcContext()); // Snapshot should update first time after construction @@ -642,7 +642,7 @@ KeyframesAtZeroAndOne(CSSPropertyID::kOpacity, "0", "1"); auto* effect = MakeGarbageCollected<StringKeyframeEffectModel>(keyframes); - auto style = GetDocument().GetStyleResolver().ResolveStyle( + const auto* style = GetDocument().GetStyleResolver().ResolveStyle( element, StyleRecalcContext()); const CompositorKeyframeValue* value; @@ -679,7 +679,7 @@ auto* effect = MakeGarbageCollected<StringKeyframeEffectModel>(opacity_keyframes); - auto style = GetDocument().GetStyleResolver().ResolveStyle( + const auto* style = GetDocument().GetStyleResolver().ResolveStyle( element, StyleRecalcContext()); EXPECT_TRUE(effect->SnapshotAllCompositorKeyframesIfNecessary(
diff --git a/third_party/blink/renderer/core/animation/scroll_timeline_util_test.cc b/third_party/blink/renderer/core/animation/scroll_timeline_util_test.cc index 5ec41d6..6f6c5303 100644 --- a/third_party/blink/renderer/core/animation/scroll_timeline_util_test.cc +++ b/third_party/blink/renderer/core/animation/scroll_timeline_util_test.cc
@@ -114,10 +114,10 @@ GetDocument().GetStyleResolver().CreateComputedStyleBuilder(); style_builder.SetWritingMode(writing_mode); style_builder.SetDirection(direction); - scoped_refptr<const ComputedStyle> style = style_builder.TakeStyle(); - EXPECT_EQ(ConvertOrientation(ScrollTimeline::ScrollAxis::kY, style.get()), + const ComputedStyle* style = style_builder.TakeStyle(); + EXPECT_EQ(ConvertOrientation(ScrollTimeline::ScrollAxis::kY, style), CompositorScrollTimeline::ScrollDown); - EXPECT_EQ(ConvertOrientation(ScrollTimeline::ScrollAxis::kX, style.get()), + EXPECT_EQ(ConvertOrientation(ScrollTimeline::ScrollAxis::kX, style), CompositorScrollTimeline::ScrollRight); } } @@ -129,67 +129,61 @@ GetDocument().GetStyleResolver().CreateComputedStyleBuilder(); builder.SetWritingMode(WritingMode::kHorizontalTb); builder.SetDirection(TextDirection::kLtr); - scoped_refptr<const ComputedStyle> style = builder.TakeStyle(); - EXPECT_EQ(ConvertOrientation(ScrollTimeline::ScrollAxis::kBlock, style.get()), + const ComputedStyle* style = builder.TakeStyle(); + EXPECT_EQ(ConvertOrientation(ScrollTimeline::ScrollAxis::kBlock, style), CompositorScrollTimeline::ScrollDown); - EXPECT_EQ( - ConvertOrientation(ScrollTimeline::ScrollAxis::kInline, style.get()), - CompositorScrollTimeline::ScrollRight); + EXPECT_EQ(ConvertOrientation(ScrollTimeline::ScrollAxis::kInline, style), + CompositorScrollTimeline::ScrollRight); // vertical-lr, ltr builder = GetDocument().GetStyleResolver().CreateComputedStyleBuilder(); builder.SetWritingMode(WritingMode::kVerticalLr); builder.SetDirection(TextDirection::kLtr); style = builder.TakeStyle(); - EXPECT_EQ(ConvertOrientation(ScrollTimeline::ScrollAxis::kBlock, style.get()), + EXPECT_EQ(ConvertOrientation(ScrollTimeline::ScrollAxis::kBlock, style), CompositorScrollTimeline::ScrollRight); - EXPECT_EQ( - ConvertOrientation(ScrollTimeline::ScrollAxis::kInline, style.get()), - CompositorScrollTimeline::ScrollDown); + EXPECT_EQ(ConvertOrientation(ScrollTimeline::ScrollAxis::kInline, style), + CompositorScrollTimeline::ScrollDown); // vertical-rl, ltr builder = GetDocument().GetStyleResolver().CreateComputedStyleBuilder(); builder.SetWritingMode(WritingMode::kVerticalRl); builder.SetDirection(TextDirection::kLtr); style = builder.TakeStyle(); - EXPECT_EQ(ConvertOrientation(ScrollTimeline::ScrollAxis::kBlock, style.get()), + EXPECT_EQ(ConvertOrientation(ScrollTimeline::ScrollAxis::kBlock, style), CompositorScrollTimeline::ScrollLeft); - EXPECT_EQ( - ConvertOrientation(ScrollTimeline::ScrollAxis::kInline, style.get()), - CompositorScrollTimeline::ScrollDown); + EXPECT_EQ(ConvertOrientation(ScrollTimeline::ScrollAxis::kInline, style), + CompositorScrollTimeline::ScrollDown); // horizontal-tb, rtl builder = GetDocument().GetStyleResolver().CreateComputedStyleBuilder(); builder.SetWritingMode(WritingMode::kHorizontalTb); builder.SetDirection(TextDirection::kRtl); style = builder.TakeStyle(); - EXPECT_EQ(ConvertOrientation(ScrollTimeline::ScrollAxis::kBlock, style.get()), + EXPECT_EQ(ConvertOrientation(ScrollTimeline::ScrollAxis::kBlock, style), CompositorScrollTimeline::ScrollDown); - EXPECT_EQ( - ConvertOrientation(ScrollTimeline::ScrollAxis::kInline, style.get()), - CompositorScrollTimeline::ScrollLeft); + EXPECT_EQ(ConvertOrientation(ScrollTimeline::ScrollAxis::kInline, style), + CompositorScrollTimeline::ScrollLeft); // vertical-lr, rtl builder = GetDocument().GetStyleResolver().CreateComputedStyleBuilder(); builder.SetWritingMode(WritingMode::kVerticalLr); builder.SetDirection(TextDirection::kRtl); style = builder.TakeStyle(); - EXPECT_EQ(ConvertOrientation(ScrollTimeline::ScrollAxis::kBlock, style.get()), + EXPECT_EQ(ConvertOrientation(ScrollTimeline::ScrollAxis::kBlock, style), CompositorScrollTimeline::ScrollRight); - EXPECT_EQ( - ConvertOrientation(ScrollTimeline::ScrollAxis::kInline, style.get()), - CompositorScrollTimeline::ScrollUp); + EXPECT_EQ(ConvertOrientation(ScrollTimeline::ScrollAxis::kInline, style), + CompositorScrollTimeline::ScrollUp); // vertical-rl, rtl builder = GetDocument().GetStyleResolver().CreateComputedStyleBuilder(); builder.SetWritingMode(WritingMode::kVerticalRl); builder.SetDirection(TextDirection::kRtl); style = builder.TakeStyle(); - EXPECT_EQ(ConvertOrientation(ScrollTimeline::ScrollAxis::kBlock, style.get()), + EXPECT_EQ(ConvertOrientation(ScrollTimeline::ScrollAxis::kBlock, style), CompositorScrollTimeline::ScrollLeft); - EXPECT_EQ( - ConvertOrientation(ScrollTimeline::ScrollAxis::kInline, style.get()), - CompositorScrollTimeline::ScrollUp); + EXPECT_EQ(ConvertOrientation(ScrollTimeline::ScrollAxis::kInline, style), + CompositorScrollTimeline::ScrollUp); } TEST_F(ScrollTimelineUtilTest, ConvertOrientationNullStyle) {
diff --git a/third_party/blink/renderer/core/animation/transition_keyframe.cc b/third_party/blink/renderer/core/animation/transition_keyframe.cc index 2a623d91..64784cf 100644 --- a/third_party/blink/renderer/core/animation/transition_keyframe.cc +++ b/third_party/blink/renderer/core/animation/transition_keyframe.cc
@@ -51,7 +51,7 @@ value_->GetType().Apply(value_->GetInterpolableValue(), value_->GetNonInterpolableValue(), environment); - scoped_refptr<const ComputedStyle> style = state.TakeStyle(); + const ComputedStyle* style = state.TakeStyle(); String property_value = AnimationUtils::KeyframeValueFromComputedStyle( property_, *style, document, element->GetLayoutObject())
diff --git a/third_party/blink/renderer/core/css/container_query_evaluator_test.cc b/third_party/blink/renderer/core/css/container_query_evaluator_test.cc index b4b1f35..966407f 100644 --- a/third_party/blink/renderer/core/css/container_query_evaluator_test.cc +++ b/third_party/blink/renderer/core/css/container_query_evaluator_test.cc
@@ -298,7 +298,7 @@ ComputedStyleBuilder builder( *GetDocument().GetStyleResolver().InitialStyleForElement()); builder.SetContainerType(type_inline_size); - scoped_refptr<const ComputedStyle> style = builder.TakeStyle(); + const ComputedStyle* style = builder.TakeStyle(); container_element.SetComputedStyle(style); ContainerQueryEvaluator* evaluator = CreateEvaluatorForType(type_inline_size);
diff --git a/third_party/blink/renderer/core/css/css_math_expression_node_test.cc b/third_party/blink/renderer/core/css/css_math_expression_node_test.cc index d2f12e2b..16aea16 100644 --- a/third_party/blink/renderer/core/css/css_math_expression_node_test.cc +++ b/third_party/blink/renderer/core/css/css_math_expression_node_test.cc
@@ -96,11 +96,10 @@ TEST(CSSCalculationValue, AccumulatePixelsAndPercent) { ComputedStyleBuilder builder(*ComputedStyle::CreateInitialStyleSingleton()); builder.SetEffectiveZoom(5); - scoped_refptr<const ComputedStyle> style = builder.TakeStyle(); + const ComputedStyle* style = builder.TakeStyle(); CSSToLengthConversionData::Flags ignored_flags = 0; CSSToLengthConversionData conversion_data( - *style, style.get(), style.get(), - CSSToLengthConversionData::ViewportSize(nullptr), + *style, style, style, CSSToLengthConversionData::ViewportSize(nullptr), CSSToLengthConversionData::ContainerSizes(), style->EffectiveZoom(), ignored_flags);
diff --git a/third_party/blink/renderer/core/css/css_properties.json5 b/third_party/blink/renderer/core/css/css_properties.json5 index 2ca88ab..7195166d 100644 --- a/third_party/blink/renderer/core/css/css_properties.json5 +++ b/third_party/blink/renderer/core/css/css_properties.json5
@@ -292,7 +292,7 @@ // Name of the pointer type that wraps this field (e.g. scoped_refptr). wrapper_pointer_name: { valid_type: "str", - valid_values: ["scoped_refptr", "Persistent", "std::unique_ptr"], + valid_values: ["scoped_refptr", "Member", "std::unique_ptr"], }, // - keywords: ["keyword1", "keyword2"] @@ -1613,7 +1613,7 @@ property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal" ], include_paths: ["third_party/blink/renderer/core/style/scoped_css_name.h"], type_name: "ScopedCSSName", - wrapper_pointer_name: "Persistent", + wrapper_pointer_name: "Member", default_value: "nullptr", field_group: "*", field_template: "external", @@ -1627,7 +1627,7 @@ property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal" ], include_paths: ["third_party/blink/renderer/core/style/scoped_css_name.h"], type_name: "ScopedCSSName", - wrapper_pointer_name: "Persistent", + wrapper_pointer_name: "Member", default_value: "nullptr", field_group: "*", field_template: "external", @@ -1656,11 +1656,10 @@ compositable: true, field_group: "*", field_template: "external", - include_paths: ["third_party/blink/renderer/core/style/style_filter_data.h"], - wrapper_pointer_name: "Persistent", - default_value: "MakeGarbageCollected<StyleFilterData>()", - type_name: "StyleFilterData", - computed_style_custom_functions: ["initial", "getter","setter"], + include_paths: ["third_party/blink/renderer/core/style/filter_operations.h"], + default_value: "FilterOperations()", + type_name: "FilterOperations", + computed_style_custom_functions: ["initial"], style_builder_custom_functions: ["value"], keywords: ["none"], typedom_types: ["Keyword"], @@ -2558,7 +2557,7 @@ name: "container-name", property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal"], type_name: "ScopedCSSNameList", - wrapper_pointer_name: "Persistent", + wrapper_pointer_name: "Member", default_value: "nullptr", field_group: "*", field_template: "external", @@ -2584,7 +2583,7 @@ field_group: "*", field_template: "external", include_paths: ["third_party/blink/renderer/core/style/content_data.h"], - wrapper_pointer_name: "Persistent", + wrapper_pointer_name: "Member", default_value: "nullptr", separator: ",", type_name: "ContentData", @@ -2774,11 +2773,10 @@ compositable: true, field_group: "*", field_template: "external", - include_paths: ["third_party/blink/renderer/core/style/style_filter_data.h"], - wrapper_pointer_name: "Persistent", - default_value: "MakeGarbageCollected<StyleFilterData>()", - type_name: "StyleFilterData", - computed_style_custom_functions: ["initial", "getter", "setter"], + include_paths: ["third_party/blink/renderer/core/style/filter_operations.h"], + default_value: "FilterOperations()", + type_name: "FilterOperations", + computed_style_custom_functions: ["initial"], style_builder_custom_functions: ["value"], keywords: ["none"], typedom_types: ["Keyword"], @@ -3240,7 +3238,7 @@ field_group: "*", field_template: "external", include_paths: ["third_party/blink/renderer/core/style/style_image.h"], - wrapper_pointer_name: "Persistent", + wrapper_pointer_name: "Member", default_value: "nullptr", typedom_types: ["Keyword", "Image"], type_name: "StyleImage", @@ -3265,7 +3263,7 @@ field_template: "external", include_paths: ["third_party/blink/renderer/core/keywords.h", "third_party/blink/renderer/core/style/list_style_type_data.h"], - wrapper_pointer_name: "Persistent", + wrapper_pointer_name: "Member", default_value: "ListStyleTypeData::CreateCounterStyle(keywords::kDisc, nullptr)", type_name: "ListStyleTypeData", keywords: [ @@ -4056,7 +4054,7 @@ property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal" ], include_paths: ["third_party/blink/renderer/core/style/scoped_css_name.h"], type_name: "ScopedCSSName", - wrapper_pointer_name: "Persistent", + wrapper_pointer_name: "Member", default_value: "nullptr", field_group: "*", field_template: "external", @@ -4070,7 +4068,7 @@ property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal" ], include_paths: ["third_party/blink/renderer/core/style/scoped_css_name.h"], type_name: "ScopedCSSName", - wrapper_pointer_name: "Persistent", + wrapper_pointer_name: "Member", default_value: "nullptr", field_group: "*", field_template: "external", @@ -4620,7 +4618,7 @@ field_template: "external", default_value: "nullptr", type_name: "ScopedCSSNameList", - wrapper_pointer_name: "Persistent", + wrapper_pointer_name: "Member", converter: "ConvertViewTimelineName", separator: ",", runtime_flag: "ScrollTimeline", @@ -4655,7 +4653,7 @@ field_group: "*", field_template: "external", include_paths: ["third_party/blink/renderer/core/style/shape_value.h"], - wrapper_pointer_name: "Persistent", + wrapper_pointer_name: "Member", default_value: "nullptr", typedom_types: ["Keyword", "Image"], type_name: "ShapeValue", @@ -5145,7 +5143,7 @@ field_template: "external", default_value: "nullptr", type_name: "ScopedCSSNameList", - wrapper_pointer_name: "Persistent", + wrapper_pointer_name: "Member", converter: "ConvertTimelineScope", separator: ",", runtime_flag: "TimelineScope", @@ -5416,7 +5414,7 @@ field_template: "external", default_value: "nullptr", type_name: "ScopedCSSNameList", - wrapper_pointer_name: "Persistent", + wrapper_pointer_name: "Member", converter: "ConvertViewTimelineName", separator: ",", runtime_flag: "ScrollTimeline",
diff --git a/third_party/blink/renderer/core/css/font_face_set_document.cc b/third_party/blink/renderer/core/css/font_face_set_document.cc index 09c5ebd..8702bc4c5 100644 --- a/third_party/blink/renderer/core/css/font_face_set_document.cc +++ b/third_party/blink/renderer/core/css/font_face_set_document.cc
@@ -200,7 +200,7 @@ default_font_description.SetComputedSize(FontFaceSet::kDefaultFontSize); builder.SetFontDescription(default_font_description); - scoped_refptr<const ComputedStyle> style = builder.TakeStyle(); + const ComputedStyle* style = builder.TakeStyle(); font = GetDocument()->GetStyleEngine().ComputeFont( *GetDocument()->documentElement(), *style, *parsed_style);
diff --git a/third_party/blink/renderer/core/css/post_style_update_scope.cc b/third_party/blink/renderer/core/css/post_style_update_scope.cc index 2ba34f22..6baae4d 100644 --- a/third_party/blink/renderer/core/css/post_style_update_scope.cc +++ b/third_party/blink/renderer/core/css/post_style_update_scope.cc
@@ -97,9 +97,8 @@ void PostStyleUpdateScope::AnimationData::StoreOldStyleIfNeeded( Element& element) { - old_styles_.insert( - &element, scoped_refptr<const ComputedStyle>( - ComputedStyle::NullifyEnsured(element.GetComputedStyle()))); + old_styles_.insert(&element, + ComputedStyle::NullifyEnsured(element.GetComputedStyle())); } const ComputedStyle* PostStyleUpdateScope::AnimationData::GetOldStyle( @@ -108,7 +107,7 @@ if (iter == old_styles_.end()) { return ComputedStyle::NullifyEnsured(element.GetComputedStyle()); } - return iter->value.get(); + return iter->value.Get(); } void PostStyleUpdateScope::PseudoData::AddPendingBackdrop(
diff --git a/third_party/blink/renderer/core/css/post_style_update_scope.h b/third_party/blink/renderer/core/css/post_style_update_scope.h index 424679c..984975b 100644 --- a/third_party/blink/renderer/core/css/post_style_update_scope.h +++ b/third_party/blink/renderer/core/css/post_style_update_scope.h
@@ -65,8 +65,7 @@ friend class ContainerQueryTest; HeapHashSet<Member<Element>> elements_with_pending_updates_; - HeapHashMap<Member<const Element>, scoped_refptr<const ComputedStyle>> - old_styles_; + HeapHashMap<Member<const Element>, Member<const ComputedStyle>> old_styles_; }; class PseudoData {
diff --git a/third_party/blink/renderer/core/css/properties/css_property_test.cc b/third_party/blink/renderer/core/css/properties/css_property_test.cc index eb0d691..ced127d0 100644 --- a/third_party/blink/renderer/core/css/properties/css_property_test.cc +++ b/third_party/blink/renderer/core/css/properties/css_property_test.cc
@@ -36,9 +36,8 @@ return &set->PropertyAt(0).Value(); } - scoped_refptr<const ComputedStyle> ComputedStyleWithValue( - const CSSProperty& property, - const CSSValue& value) { + const ComputedStyle* ComputedStyleWithValue(const CSSProperty& property, + const CSSValue& value) { StyleResolverState state(GetDocument(), *GetDocument().body()); state.SetStyle(GetDocument().GetStyleResolver().InitialStyle());
diff --git a/third_party/blink/renderer/core/css/properties/longhands/custom_property_test.cc b/third_party/blink/renderer/core/css/properties/longhands/custom_property_test.cc index 73dbfbd..e6d10a2dd 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/custom_property_test.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/custom_property_test.cc
@@ -303,7 +303,7 @@ /* StyleRecalcContext */ nullptr, StyleRequest()); state.SetStyle(*GetDocument().GetStyleResolver().InitialStyleForElement()); property.ApplyValue(state, *declaration, CSSProperty::ValueMode::kNormal); - scoped_refptr<const ComputedStyle> style = state.TakeStyle(); + const ComputedStyle* style = state.TakeStyle(); ASSERT_TRUE(style->GetVariableData(AtomicString("--x"))); EXPECT_FALSE( style->GetVariableData(AtomicString("--x"))->IsAnimationTainted()); @@ -315,7 +315,7 @@ /* StyleRecalcContext */ nullptr, StyleRequest()); state.SetStyle(*GetDocument().GetStyleResolver().InitialStyleForElement()); property.ApplyValue(state, *declaration, CSSProperty::ValueMode::kAnimated); - scoped_refptr<const ComputedStyle> style = state.TakeStyle(); + const ComputedStyle* style = state.TakeStyle(); ASSERT_TRUE(style->GetVariableData(AtomicString("--x"))); EXPECT_TRUE( style->GetVariableData(AtomicString("--x"))->IsAnimationTainted());
diff --git a/third_party/blink/renderer/core/css/resolver/element_resolve_context.cc b/third_party/blink/renderer/core/css/resolver/element_resolve_context.cc index b23d6e4..ca187f4 100644 --- a/third_party/blink/renderer/core/css/resolver/element_resolve_context.cc +++ b/third_party/blink/renderer/core/css/resolver/element_resolve_context.cc
@@ -31,8 +31,6 @@ ElementResolveContext::ElementResolveContext(Element& element) : element_(&element), - parent_node_(nullptr), - layout_parent_(nullptr), element_link_state_( element.GetDocument().GetVisitedLinkState().DetermineLinkState( element)) {
diff --git a/third_party/blink/renderer/core/css/resolver/element_resolve_context.h b/third_party/blink/renderer/core/css/resolver/element_resolve_context.h index ea35607..4dcc62a 100644 --- a/third_party/blink/renderer/core/css/resolver/element_resolve_context.h +++ b/third_party/blink/renderer/core/css/resolver/element_resolve_context.h
@@ -45,9 +45,7 @@ Element& GetElement() const { return *element_; } const ContainerNode* ParentNode() const { return parent_node_; } const ContainerNode* LayoutParent() const { return layout_parent_; } - const ComputedStyle* RootElementStyle() const { - return root_element_style_.get(); - } + const ComputedStyle* RootElementStyle() const { return root_element_style_; } const ComputedStyle* ParentStyle() const { return ParentNode() && ParentNode()->IsElementNode() ? ParentNode()->GetComputedStyle() @@ -60,9 +58,9 @@ private: Element* element_; - ContainerNode* parent_node_; - ContainerNode* layout_parent_; - scoped_refptr<const ComputedStyle> root_element_style_; + ContainerNode* parent_node_{nullptr}; + ContainerNode* layout_parent_{nullptr}; + const ComputedStyle* root_element_style_{nullptr}; EInsideLink element_link_state_; };
diff --git a/third_party/blink/renderer/core/css/resolver/element_style_resources.cc b/third_party/blink/renderer/core/css/resolver/element_style_resources.cc index d0183390..2878021 100644 --- a/third_party/blink/renderer/core/css/resolver/element_style_resources.cc +++ b/third_party/blink/renderer/core/css/resolver/element_style_resources.cc
@@ -286,11 +286,11 @@ for (CSSPropertyID property : pending_svg_resource_properties_) { switch (property) { case CSSPropertyID::kBackdropFilter: - LoadResourcesForFilter(builder.MutableBackdropFilter().Operations(), + LoadResourcesForFilter(builder.MutableBackdropFilterOperations(), document); break; case CSSPropertyID::kFilter: - LoadResourcesForFilter(builder.MutableFilter().Operations(), document); + LoadResourcesForFilter(builder.MutableFilterOperations(), document); break; default: NOTREACHED();
diff --git a/third_party/blink/renderer/core/css/resolver/font_builder_test.cc b/third_party/blink/renderer/core/css/resolver/font_builder_test.cc index 8803cdc..97df08f9 100644 --- a/third_party/blink/renderer/core/css/resolver/font_builder_test.cc +++ b/third_party/blink/renderer/core/css/resolver/font_builder_test.cc
@@ -75,7 +75,7 @@ ComputedStyleBuilder builder = GetDocument().GetStyleResolver().CreateComputedStyleBuilder(); builder.SetFontDescription(parent_description); - scoped_refptr<const ComputedStyle> parent_style = builder.TakeStyle(); + const ComputedStyle* parent_style = builder.TakeStyle(); builder = GetDocument().GetStyleResolver().CreateComputedStyleBuilderInheritingFrom( @@ -83,9 +83,9 @@ FontBuilder font_builder(&GetDocument()); funcs.set_value(font_builder); - font_builder.CreateFont(builder, parent_style.get()); + font_builder.CreateFont(builder, parent_style); - scoped_refptr<const ComputedStyle> style = builder.TakeStyle(); + const ComputedStyle* style = builder.TakeStyle(); FontDescription output_description = style->GetFontDescription(); // FontBuilder should have overwritten our base value set in the parent,
diff --git a/third_party/blink/renderer/core/css/resolver/matched_properties_cache.cc b/third_party/blink/renderer/core/css/resolver/matched_properties_cache.cc index 038d137f..8fff50db 100644 --- a/third_party/blink/renderer/core/css/resolver/matched_properties_cache.cc +++ b/third_party/blink/renderer/core/css/resolver/matched_properties_cache.cc
@@ -51,20 +51,31 @@ return hash; } -void CachedMatchedProperties::Set( - scoped_refptr<const ComputedStyle>&& style, - scoped_refptr<const ComputedStyle>&& parent_style, - const MatchedPropertiesVector& properties) { +CachedMatchedProperties::CachedMatchedProperties( + const ComputedStyle* style, + const ComputedStyle* parent_style, + const MatchedPropertiesVector& properties) + : computed_style(style), parent_computed_style(parent_style) { + matched_properties.ReserveInitialCapacity(properties.size()); + matched_properties_types.ReserveInitialCapacity(properties.size()); for (const auto& new_matched_properties : properties) { matched_properties.push_back(new_matched_properties.properties); matched_properties_types.push_back(new_matched_properties.types_); } +} - // Note that we don't cache the original ComputedStyle instance. It may be - // further modified. The ComputedStyle in the cache is really just a holder - // for the substructures and never used as-is. - this->computed_style = style; - this->parent_computed_style = parent_style; +void CachedMatchedProperties::Set(const ComputedStyle* style, + const ComputedStyle* parent_style, + const MatchedPropertiesVector& properties) { + computed_style = style; + parent_computed_style = parent_style; + + matched_properties.clear(); + matched_properties_types.clear(); + for (const auto& new_matched_properties : properties) { + matched_properties.push_back(new_matched_properties.properties); + matched_properties_types.push_back(new_matched_properties.types_); + } } void CachedMatchedProperties::Clear() { @@ -191,23 +202,20 @@ return !(*this == properties); } -void MatchedPropertiesCache::Add( - const Key& key, - scoped_refptr<const ComputedStyle>&& style, - scoped_refptr<const ComputedStyle>&& parent_style) { +void MatchedPropertiesCache::Add(const Key& key, + const ComputedStyle* style, + const ComputedStyle* parent_style) { DCHECK(key.IsValid()); Member<CachedMatchedProperties>& cache_item = cache_.insert(key.hash_, nullptr).stored_value->value; if (!cache_item) { - cache_item = MakeGarbageCollected<CachedMatchedProperties>(); + cache_item = MakeGarbageCollected<CachedMatchedProperties>( + style, parent_style, key.result_.GetMatchedProperties()); } else { - cache_item->Clear(); + cache_item->Set(style, parent_style, key.result_.GetMatchedProperties()); } - - cache_item->Set(std::move(style), std::move(parent_style), - key.result_.GetMatchedProperties()); } void MatchedPropertiesCache::Clear() {
diff --git a/third_party/blink/renderer/core/css/resolver/matched_properties_cache.h b/third_party/blink/renderer/core/css/resolver/matched_properties_cache.h index a3843ad..a549917 100644 --- a/third_party/blink/renderer/core/css/resolver/matched_properties_cache.h +++ b/third_party/blink/renderer/core/css/resolver/matched_properties_cache.h
@@ -49,17 +49,27 @@ Vector<UntracedMember<CSSPropertyValueSet>> matched_properties; Vector<MatchedProperties::Data> matched_properties_types; - scoped_refptr<const ComputedStyle> computed_style; - scoped_refptr<const ComputedStyle> parent_computed_style; + // Note that we don't cache the original ComputedStyle instance. It may be + // further modified. The ComputedStyle in the cache is really just a holder + // for the substructures and never used as-is. + Member<const ComputedStyle> computed_style; + Member<const ComputedStyle> parent_computed_style; - void Set(scoped_refptr<const ComputedStyle>&& style, - scoped_refptr<const ComputedStyle>&& parent_style, + CachedMatchedProperties(const ComputedStyle* style, + const ComputedStyle* parent_style, + const MatchedPropertiesVector&); + + void Set(const ComputedStyle* style, + const ComputedStyle* parent_style, const MatchedPropertiesVector&); void Clear(); bool DependenciesEqual(const StyleResolverState&); - void Trace(Visitor*) const {} + void Trace(Visitor* visitor) const { + visitor->Trace(computed_style); + visitor->Trace(parent_computed_style); + } bool operator==(const MatchedPropertiesVector& properties); bool operator!=(const MatchedPropertiesVector& properties); @@ -99,9 +109,7 @@ }; const CachedMatchedProperties* Find(const Key&, const StyleResolverState&); - void Add(const Key&, - scoped_refptr<const ComputedStyle>&&, - scoped_refptr<const ComputedStyle>&& parent_style); + void Add(const Key&, const ComputedStyle*, const ComputedStyle* parent_style); void Clear(); void ClearViewportDependent();
diff --git a/third_party/blink/renderer/core/css/resolver/matched_properties_cache_test.cc b/third_party/blink/renderer/core/css/resolver/matched_properties_cache_test.cc index 39f6b46..7b93679 100644 --- a/third_party/blink/renderer/core/css/resolver/matched_properties_cache_test.cc +++ b/third_party/blink/renderer/core/css/resolver/matched_properties_cache_test.cc
@@ -150,8 +150,7 @@ const auto& parent = InitialStyle(); ComputedStyleBuilder ensured_parent_builder = CreateStyleBuilder(); ensured_parent_builder.SetIsEnsuredInDisplayNone(); - scoped_refptr<const ComputedStyle> ensured_parent = - ensured_parent_builder.TakeStyle(); + const auto* ensured_parent = ensured_parent_builder.TakeStyle(); TestKey key1("display:block", 1, GetDocument()); @@ -171,7 +170,7 @@ const auto& parent = InitialStyle(); auto builder = CreateStyleBuilder(); builder.SetIsEnsuredOutsideFlatTree(); - auto ensured_style = builder.TakeStyle(); + const auto* ensured_style = builder.TakeStyle(); TestKey key1("display:block", 1, GetDocument()); StyleRecalcContext context; @@ -194,11 +193,11 @@ auto builder = CreateStyleBuilder(); builder.SetIsEnsuredInDisplayNone(); - auto parent_none = builder.TakeStyle(); + const auto* parent_none = builder.TakeStyle(); builder = CreateStyleBuilder(); builder.SetIsEnsuredOutsideFlatTree(); - auto style_flat = builder.TakeStyle(); + const auto* style_flat = builder.TakeStyle(); StyleRecalcContext context; context.is_outside_flat_tree = true; @@ -220,8 +219,8 @@ auto parent_builder_b = CreateStyleBuilder(); parent_builder_b.SetWritingMode(WritingMode::kVerticalRl); - auto parent_a = parent_builder_a.TakeStyle(); - auto parent_b = parent_builder_b.TakeStyle(); + const auto* parent_a = parent_builder_a.TakeStyle(); + const auto* parent_b = parent_builder_b.TakeStyle(); const auto& style_a = InitialStyle(); const auto& style_b = InitialStyle(); @@ -242,8 +241,8 @@ auto parent_builder_b = CreateStyleBuilder(); parent_builder_b.SetDirection(TextDirection::kRtl); - auto parent_a = parent_builder_a.TakeStyle(); - auto parent_b = parent_builder_b.TakeStyle(); + const auto* parent_a = parent_builder_a.TakeStyle(); + const auto* parent_b = parent_builder_b.TakeStyle(); const auto& style_a = InitialStyle(); const auto& style_b = InitialStyle(); @@ -261,11 +260,11 @@ auto builder = CreateStyleBuilder(); builder.SetDarkColorScheme(false); - auto parent_a = builder.TakeStyle(); + const auto* parent_a = builder.TakeStyle(); builder = CreateStyleBuilder(); builder.SetDarkColorScheme(true); - auto parent_b = builder.TakeStyle(); + const auto* parent_b = builder.TakeStyle(); const auto& style_a = InitialStyle(); const auto& style_b = InitialStyle(); @@ -287,15 +286,15 @@ CreateVariableData("1px"), true); parent_builder_b.SetVariableData(AtomicString("--x"), CreateVariableData("2px"), true); - auto parent_a = parent_builder_a.TakeStyle(); - auto parent_b = parent_builder_b.TakeStyle(); + const auto* parent_a = parent_builder_a.TakeStyle(); + const auto* parent_b = parent_builder_b.TakeStyle(); auto style_builder_a = CreateStyleBuilder(); auto style_builder_b = CreateStyleBuilder(); style_builder_a.SetHasVariableReferenceFromNonInheritedProperty(); style_builder_b.SetHasVariableReferenceFromNonInheritedProperty(); - auto style_a = style_builder_a.TakeStyle(); - auto style_b = style_builder_b.TakeStyle(); + const auto* style_a = style_builder_a.TakeStyle(); + const auto* style_b = style_builder_b.TakeStyle(); TestKey key("top:var(--x)", 1, GetDocument()); cache.Add(key, *style_a, *parent_a); @@ -314,8 +313,8 @@ auto style_builder_b = CreateStyleBuilder(); style_builder_a.SetHasVariableReferenceFromNonInheritedProperty(); style_builder_b.SetHasVariableReferenceFromNonInheritedProperty(); - auto style_a = style_builder_a.TakeStyle(); - auto style_b = style_builder_b.TakeStyle(); + const auto* style_a = style_builder_a.TakeStyle(); + const auto* style_b = style_builder_b.TakeStyle(); TestKey key("top:var(--x)", 1, GetDocument()); @@ -335,8 +334,8 @@ CreateVariableData("1px"), true); parent_builder_b.SetVariableData(AtomicString("--x"), CreateVariableData("2px"), true); - auto parent_a = parent_builder_a.TakeStyle(); - auto parent_b = parent_builder_b.TakeStyle(); + const auto* parent_a = parent_builder_a.TakeStyle(); + const auto* parent_b = parent_builder_b.TakeStyle(); const auto& style_a = InitialStyle(); const auto& style_b = InitialStyle();
diff --git a/third_party/blink/renderer/core/css/resolver/style_adjuster.cc b/third_party/blink/renderer/core/css/resolver/style_adjuster.cc index 753b4c25..4dadf96 100644 --- a/third_party/blink/renderer/core/css/resolver/style_adjuster.cc +++ b/third_party/blink/renderer/core/css/resolver/style_adjuster.cc
@@ -304,7 +304,7 @@ #if DCHECK_IS_ON() DCHECK_EQ(builder.GetFont().GetFontDescription().Orientation(), FontOrientation::kHorizontal); - scoped_refptr<const ComputedStyle> cloned_style = builder.CloneStyle(); + const ComputedStyle* cloned_style = builder.CloneStyle(); LayoutNGTextCombine::AssertStyleIsValid(*cloned_style); #endif } @@ -895,7 +895,7 @@ // it to have a backdrop filter either. if (is_document_element && is_in_main_frame && builder.HasBackdropFilter()) { - builder.MutableBackdropFilter().clear(); + builder.SetBackdropFilter(FilterOperations()); } } else { AdjustStyleForFirstLetter(builder);
diff --git a/third_party/blink/renderer/core/css/resolver/style_builder_test.cc b/third_party/blink/renderer/core/css/resolver/style_builder_test.cc index 875fa500..7f9ee5f 100644 --- a/third_party/blink/renderer/core/css/resolver/style_builder_test.cc +++ b/third_party/blink/renderer/core/css/resolver/style_builder_test.cc
@@ -127,9 +127,6 @@ nullptr /* StyleRecalcContext */, StyleRequest(&parent_style)); - scoped_refptr<const ComputedStyle> style1; - scoped_refptr<const ComputedStyle> style2; - // grid-template-areas applied first. state.SetStyle(parent_style); StyleBuilder::ApplyProperty(grid_template_areas, state, @@ -138,7 +135,7 @@ *grid_template_columns_value); StyleBuilder::ApplyProperty(grid_template_rows, state, *grid_template_rows_value); - style1 = state.TakeStyle(); + const ComputedStyle* style1 = state.TakeStyle(); // grid-template-areas applied last. state.SetStyle(parent_style); @@ -148,7 +145,7 @@ *grid_template_rows_value); StyleBuilder::ApplyProperty(grid_template_areas, state, *grid_template_areas_value); - style2 = state.TakeStyle(); + const ComputedStyle* style2 = state.TakeStyle(); ASSERT_TRUE(style1); ASSERT_TRUE(style2);
diff --git a/third_party/blink/renderer/core/css/resolver/style_cascade_test.cc b/third_party/blink/renderer/core/css/resolver/style_cascade_test.cc index 0cf89eb..f2c377e 100644 --- a/third_party/blink/renderer/core/css/resolver/style_cascade_test.cc +++ b/third_party/blink/renderer/core/css/resolver/style_cascade_test.cc
@@ -92,12 +92,12 @@ cascade_(InitState(state_, nullptr)) {} TestCascade(Document& document, - scoped_refptr<const ComputedStyle> parent_style, + const ComputedStyle* parent_style, Element* target = nullptr) : state_(document, target ? *target : *document.body()), cascade_(InitState(state_, parent_style)) {} - scoped_refptr<const ComputedStyle> TakeStyle() { return state_.TakeStyle(); } + const ComputedStyle* TakeStyle() { return state_.TakeStyle(); } StyleResolverState& State() { return state_; } StyleCascade& InnerCascade() { return cascade_; } @@ -163,8 +163,7 @@ DCHECK(ref.IsValid()); const LayoutObject* layout_object = nullptr; bool allow_visited_style = false; - scoped_refptr<const ComputedStyle> style = - state_.StyleBuilder().CloneStyle(); + const ComputedStyle* style = state_.StyleBuilder().CloneStyle(); const CSSValue* value = ref.GetProperty().CSSValueFromComputedStyle( *style, layout_object, allow_visited_style); return value ? value->CssText() : g_null_atom; @@ -225,9 +224,8 @@ Document& GetDocument() const { return state_.GetDocument(); } Element* Body() const { return GetDocument().body(); } - static StyleResolverState& InitState( - StyleResolverState& state, - scoped_refptr<const ComputedStyle> parent_style) { + static StyleResolverState& InitState(StyleResolverState& state, + const ComputedStyle* parent_style) { state.GetDocument().GetStyleEngine().UpdateViewportSize(); if (parent_style) { state.CreateNewStyle(*InitialStyle(state.GetDocument()), *parent_style); @@ -240,7 +238,7 @@ return state; } - static scoped_refptr<const ComputedStyle> InitialStyle(Document& document) { + static const ComputedStyle* InitialStyle(Document& document) { return document.GetStyleResolver().InitialStyleForElement(); } @@ -2550,7 +2548,7 @@ cascade.Apply(); EXPECT_EQ("rgb(150, 150, 150)", cascade.ComputedValue("background-color")); - auto style = cascade.TakeStyle(); + const auto* style = cascade.TakeStyle(); ComputedStyleBuilder builder(*style); builder.SetInsideLink(EInsideLink::kInsideVisitedLink); @@ -2582,7 +2580,7 @@ cascade.Apply(); EXPECT_EQ("rgb(150, 150, 150)", cascade.ComputedValue("color")); - auto style = cascade.TakeStyle(); + const auto* style = cascade.TakeStyle(); ComputedStyleBuilder builder(*style); builder.SetInsideLink(EInsideLink::kInsideVisitedLink); @@ -3060,7 +3058,7 @@ cascade.Add("--x", "1px"); cascade.Add("width", "var(--x)"); cascade.Apply(); - auto style = cascade.TakeStyle(); + const auto* style = cascade.TakeStyle(); EXPECT_TRUE(style->HasVariableReferenceFromNonInheritedProperty()); } @@ -3069,7 +3067,7 @@ cascade.Add("--x", "1px"); cascade.Add("margin", "var(--x)"); cascade.Apply(); - auto style = cascade.TakeStyle(); + const auto* style = cascade.TakeStyle(); EXPECT_TRUE(style->HasVariableReferenceFromNonInheritedProperty()); } @@ -3077,7 +3075,7 @@ TestCascade cascade(GetDocument()); cascade.Add("width", "var(--x)"); cascade.Apply(); - auto style = cascade.TakeStyle(); + const auto* style = cascade.TakeStyle(); EXPECT_TRUE(style->HasVariableReferenceFromNonInheritedProperty()); } @@ -3085,7 +3083,7 @@ TestCascade cascade(GetDocument()); cascade.Add("margin", "var(--x)"); cascade.Apply(); - auto style = cascade.TakeStyle(); + const auto* style = cascade.TakeStyle(); EXPECT_TRUE(style->HasVariableReferenceFromNonInheritedProperty()); } @@ -3093,7 +3091,7 @@ TestCascade cascade(GetDocument()); cascade.Add("color", "var(--x)"); cascade.Apply(); - auto style = cascade.TakeStyle(); + const auto* style = cascade.TakeStyle(); EXPECT_FALSE(style->HasVariableReferenceFromNonInheritedProperty()); } @@ -3101,7 +3099,7 @@ TestCascade cascade(GetDocument()); cascade.Add("width", "1px"); cascade.Apply(); - auto style = cascade.TakeStyle(); + const auto* style = cascade.TakeStyle(); EXPECT_FALSE(style->HasVariableReferenceFromNonInheritedProperty()); } @@ -3231,7 +3229,7 @@ cascade.Add("border-block-start-color", "red", Origin::kUserAgent); cascade.Add("border-block-start-color", "green", Origin::kAuthor); cascade.Apply(); - auto style = cascade.TakeStyle(); + const auto* style = cascade.TakeStyle(); EXPECT_TRUE(style->HasAuthorBorder()); } @@ -3243,7 +3241,7 @@ cascade.Add("background-clip", "padding-box", Origin::kUser); cascade.Add("border-right-color", "green", Origin::kUser); cascade.Apply(); - auto style = cascade.TakeStyle(); + const auto* style = cascade.TakeStyle(); EXPECT_FALSE(style->HasAuthorBackground()); EXPECT_FALSE(style->HasAuthorBorder()); } @@ -3254,7 +3252,7 @@ cascade.Add("background-color", "red", Origin::kUserAgent); cascade.Add("background-color", "revert", Origin::kAuthor); cascade.Apply(); - auto style = cascade.TakeStyle(); + const auto* style = cascade.TakeStyle(); EXPECT_FALSE(style->HasAuthorBackground()); } @@ -3264,7 +3262,7 @@ cascade.Add("border-top-color", "red", Origin::kUserAgent); cascade.Add("border-top-color", "revert", Origin::kAuthor); cascade.Apply(); - auto style = cascade.TakeStyle(); + const auto* style = cascade.TakeStyle(); EXPECT_FALSE(style->HasAuthorBorder()); } @@ -3274,7 +3272,7 @@ cascade.Add("border-block-start-color", "red", Origin::kUserAgent); cascade.Add("border-block-start-color", "revert", Origin::kAuthor); cascade.Apply(); - auto style = cascade.TakeStyle(); + const auto* style = cascade.TakeStyle(); EXPECT_FALSE(style->HasAuthorBorder()); } @@ -3459,7 +3457,7 @@ cascade.Add("display:block"); cascade.Apply(); // Should not affect 'color'. - auto style = cascade.TakeStyle(); + const auto* style = cascade.TakeStyle(); ComputedStyleBuilder builder(*style); builder.SetInsideLink(EInsideLink::kInsideVisitedLink); @@ -3491,7 +3489,7 @@ cascade.Apply(); - auto style = cascade.TakeStyle(); + const auto* style = cascade.TakeStyle(); ComputedStyleBuilder builder(*style); builder.SetInsideLink(EInsideLink::kInsideVisitedLink);
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 07a03a6..dfbe152 100644 --- a/third_party/blink/renderer/core/css/resolver/style_resolver.cc +++ b/third_party/blink/renderer/core/css/resolver/style_resolver.cc
@@ -122,12 +122,12 @@ namespace { -scoped_refptr<const ComputedStyle> BuildInitialStyleForImg( - const scoped_refptr<const ComputedStyle>& initial_style) { +const ComputedStyle* BuildInitialStyleForImg( + const ComputedStyle& initial_style) { // This matches the img {} declarations in html.css to avoid copy-on-write // when only UA styles apply for these properties. See crbug.com/1369454 // for details. - ComputedStyleBuilder builder(*initial_style); + ComputedStyleBuilder builder(initial_style); builder.SetOverflowX(EOverflow::kClip); builder.SetOverflowY(EOverflow::kClip); builder.SetOverflowClipMargin(StyleOverflowClipMargin::CreateContent()); @@ -464,7 +464,7 @@ StyleResolver::StyleResolver(Document& document) : initial_style_(ComputedStyle::CreateInitialStyleSingleton()), - initial_style_for_img_(BuildInitialStyleForImg(initial_style_)), + initial_style_for_img_(BuildInitialStyleForImg(*initial_style_)), document_(document) { UpdateMediaType(); } @@ -472,7 +472,6 @@ StyleResolver::~StyleResolver() = default; void StyleResolver::Dispose() { - initial_style_.reset(); matched_properties_cache_.Clear(); } @@ -923,7 +922,7 @@ } } -scoped_refptr<const ComputedStyle> StyleResolver::StyleForViewport() { +const ComputedStyle* StyleResolver::StyleForViewport() { ComputedStyleBuilder builder = InitialStyleBuilderForElement(); builder.SetZIndex(0); @@ -948,7 +947,7 @@ return nullptr; } auto* old_style = animating_element->GetComputedStyle(); - return old_style ? old_style->BaseData().get() : nullptr; + return old_style ? old_style->BaseData().Get() : nullptr; } static const ComputedStyle* CachedAnimationBaseComputedStyle( @@ -986,7 +985,7 @@ // any other properties or elements. (The exceptions can be found in // CanReuseBaseComputedStyle().) This is known as the “base computed style // optimization”. -scoped_refptr<const ComputedStyle> StyleResolver::ResolveStyle( +const ComputedStyle* StyleResolver::ResolveStyle( Element* element, const StyleRecalcContext& style_recalc_context, const StyleRequest& style_request) { @@ -1527,15 +1526,13 @@ // optimization was sound. ApplyBaseStyleNoCache(element, style_recalc_context, style_request, state, cascade); - scoped_refptr<const ComputedStyle> style_snapshot = - state.StyleBuilder().CloneStyle(); + const ComputedStyle* style_snapshot = state.StyleBuilder().CloneStyle(); DCHECK_EQ(g_null_atom, ComputeBaseComputedStyleDiff( animation_base_computed_style, *style_snapshot)); #endif state.SetStyle(*animation_base_computed_style); - state.StyleBuilder().SetBaseData( - scoped_refptr<StyleBaseData>(GetBaseData(state))); + state.StyleBuilder().SetBaseData(GetBaseData(state)); state.StyleBuilder().SetStyleType(style_request.pseudo_id); if (!state.ParentStyle()) { state.SetParentStyle(InitialStyleForElement()); @@ -1582,7 +1579,7 @@ #if DCHECK_IS_ON() // Verify that we got the right answer. - scoped_refptr<const ComputedStyle> incremental_style = state.TakeStyle(); + const ComputedStyle* incremental_style = state.TakeStyle(); ApplyBaseStyleNoCache(element, style_recalc_context, style_request, state, cascade); @@ -1602,10 +1599,9 @@ state.StyleBuilder().ViewportUnitFlags() | incremental_style->ViewportUnitFlags()); - scoped_refptr<const ComputedStyle> style_snapshot = - state.StyleBuilder().CloneStyle(); - DCHECK_EQ(g_null_atom, ComputeBaseComputedStyleDiff(incremental_style.get(), - *style_snapshot)); + const ComputedStyle* style_snapshot = state.StyleBuilder().CloneStyle(); + DCHECK_EQ(g_null_atom, + ComputeBaseComputedStyleDiff(incremental_style, *style_snapshot)); // The incremental style must not contain BaseData, otherwise we'd risk // creating an infinite chain of BaseData/ComputedStyle in // ApplyAnimatedStyle. @@ -1643,14 +1639,14 @@ CascadeOrigin::kAuthor); cascade.Apply(); } - scoped_refptr<const ComputedStyle> style = state.TakeStyle(); + const ComputedStyle* style = state.TakeStyle(); return CompositorKeyframeValueFactory::Create(property, *style, offset); } -scoped_refptr<const ComputedStyle> StyleResolver::StyleForPage( +const ComputedStyle* StyleResolver::StyleForPage( uint32_t page_index, const AtomicString& page_name) { - scoped_refptr<const ComputedStyle> initial_style = InitialStyleForElement(); + const ComputedStyle* initial_style = InitialStyleForElement(); if (!GetDocument().documentElement()) { return initial_style; } @@ -1658,7 +1654,7 @@ const ComputedStyle* document_style = GetDocument().GetComputedStyle(); StyleResolverState state(GetDocument(), *GetDocument().documentElement(), nullptr /* StyleRecalcContext */, - StyleRequest(initial_style.get())); + StyleRequest(initial_style)); state.CreateNewStyle(*initial_style, *document_style); STACK_UNINITIALIZED StyleCascade cascade(state); @@ -1739,8 +1735,7 @@ return builder; } -scoped_refptr<const ComputedStyle> StyleResolver::StyleForText( - Text* text_node) { +const ComputedStyle* StyleResolver::StyleForText(Text* text_node) { DCHECK(text_node); if (Node* parent_node = LayoutTreeBuilderTraversal::Parent(*text_node)) { const ComputedStyle* style = parent_node->GetComputedStyle(); @@ -2088,11 +2083,11 @@ !IsForcedColorsModeEnabled() || is_inherited_cache_hit; const ComputedStyle* parent_style = - is_inherited_cache_hit ? cached_matched_properties->computed_style.get() + is_inherited_cache_hit ? cached_matched_properties->computed_style.Get() : state.ParentStyle(); const ComputedStyle& source_for_noninherited = is_non_inherited_cache_hit - ? *cached_matched_properties->computed_style.get() + ? *cached_matched_properties->computed_style.Get() : initial_style; InitStyle(element, style_request, source_for_noninherited, parent_style, @@ -2245,7 +2240,7 @@ cascade.Apply(); CSSPropertyRef property_ref(property_name, element->GetDocument()); - scoped_refptr<const ComputedStyle> style = state.TakeStyle(); + const ComputedStyle* style = state.TakeStyle(); return ComputedStyleUtils::ComputedPropertyValue(property_ref.GetProperty(), *style); } @@ -2256,11 +2251,11 @@ const CSSValue& filter_value) { ComputedStyleBuilder parent_builder = CreateComputedStyleBuilder(); parent_builder.SetFont(font); - scoped_refptr<const ComputedStyle> parent = parent_builder.TakeStyle(); + const ComputedStyle* parent = parent_builder.TakeStyle(); StyleResolverState state(GetDocument(), *element, nullptr /* StyleRecalcContext */, - StyleRequest(parent.get())); + StyleRequest(parent)); GetDocument().GetStyleEngine().UpdateViewportSize(); state.SetStyle(*parent); @@ -2270,11 +2265,11 @@ state.LoadPendingResources(); - scoped_refptr<const ComputedStyle> style = state.TakeStyle(); + const ComputedStyle* style = state.TakeStyle(); return style->Filter(); } -scoped_refptr<const ComputedStyle> StyleResolver::StyleForInterpolations( +const ComputedStyle* StyleResolver::StyleForInterpolations( Element& element, ActiveInterpolationsMap& interpolations) { StyleRecalcContext style_recalc_context = @@ -2300,8 +2295,7 @@ cascade.Apply(); } -scoped_refptr<const ComputedStyle> -StyleResolver::BeforeChangeStyleForTransitionUpdate( +const ComputedStyle* StyleResolver::BeforeChangeStyleForTransitionUpdate( Element& element, const ComputedStyle& base_style, ActiveInterpolationsMap& transition_interpolations) { @@ -2342,13 +2336,11 @@ } #if DCHECK_IS_ON() // Verify that our application went as planned. - scoped_refptr<const ComputedStyle> applied_style = - state.StyleBuilder().CloneStyle(); + const ComputedStyle* applied_style = state.StyleBuilder().CloneStyle(); cascade.Apply(filter); - scoped_refptr<const ComputedStyle> correct_style = - state.StyleBuilder().CloneStyle(); - DCHECK_EQ(g_null_atom, ComputeBaseComputedStyleDiff(applied_style.get(), - *correct_style)); + const ComputedStyle* correct_style = state.StyleBuilder().CloneStyle(); + DCHECK_EQ(g_null_atom, + ComputeBaseComputedStyleDiff(applied_style, *correct_style)); #endif } else { cascade.Apply(filter); @@ -2363,8 +2355,7 @@ apply(CascadeFilter(CSSProperty::kLegacyOverlapping, true)); if (state.RejectedLegacyOverlapping()) { - scoped_refptr<const ComputedStyle> non_legacy_style = - state.StyleBuilder().CloneStyle(); + const ComputedStyle* non_legacy_style = state.StyleBuilder().CloneStyle(); // Re-apply all overlapping properties (both legacy and non-legacy). apply(CascadeFilter(CSSProperty::kOverlapping, false)); UseCountLegacyOverlapping(GetDocument(), *non_legacy_style, @@ -2460,7 +2451,7 @@ ->EnsureScopedValue(&GetDocument())); } state.UpdateFont(); - scoped_refptr<const ComputedStyle> font_style = state.TakeStyle(); + const ComputedStyle* font_style = state.TakeStyle(); return font_style->GetFont(); } @@ -2477,6 +2468,8 @@ void StyleResolver::Trace(Visitor* visitor) const { visitor->Trace(matched_properties_cache_); + visitor->Trace(initial_style_); + visitor->Trace(initial_style_for_img_); visitor->Trace(selector_filter_); visitor->Trace(document_); visitor->Trace(tracker_); @@ -2496,8 +2489,7 @@ return builder; } -scoped_refptr<const ComputedStyle> -StyleResolver::CreateInheritedDisplayContentsStyleIfNeeded( +const ComputedStyle* StyleResolver::CreateInheritedDisplayContentsStyleIfNeeded( const ComputedStyle& parent_style, const ComputedStyle& layout_parent_style) { if (parent_style.InheritedEqual(layout_parent_style)) { @@ -2787,7 +2779,7 @@ #undef PROPAGATE_VALUE #undef PROPAGATE_FROM -scoped_refptr<const ComputedStyle> StyleResolver::StyleForFormattedText( +const ComputedStyle* StyleResolver::StyleForFormattedText( bool is_text_run, const FontDescription& default_font, const CSSPropertyValueSet* css_property_value_set) { @@ -2796,7 +2788,7 @@ css_property_value_set); } -scoped_refptr<const ComputedStyle> StyleResolver::StyleForFormattedText( +const ComputedStyle* StyleResolver::StyleForFormattedText( bool is_text_run, const ComputedStyle& parent_style, const CSSPropertyValueSet* css_property_value_set) { @@ -2804,7 +2796,7 @@ &parent_style, css_property_value_set); } -scoped_refptr<const ComputedStyle> StyleResolver::StyleForFormattedText( +const ComputedStyle* StyleResolver::StyleForFormattedText( bool is_text_run, const FontDescription* default_font, const ComputedStyle* parent_style, @@ -2893,7 +2885,7 @@ // * inline-sizing. // Additionally, all of the sizing properties and box-sizing also apply to // initial letters (see [css-sizing-3]). -scoped_refptr<const ComputedStyle> StyleResolver::StyleForInitialLetterText( +const ComputedStyle* StyleResolver::StyleForInitialLetterText( const ComputedStyle& initial_letter_box_style, const ComputedStyle& paragraph_style) { DCHECK(paragraph_style.InitialLetter().IsNormal()); @@ -2948,7 +2940,7 @@ return position_fallback_rule; } -scoped_refptr<const ComputedStyle> StyleResolver::ResolvePositionFallbackStyle( +const ComputedStyle* StyleResolver::ResolvePositionFallbackStyle( Element& element, unsigned index) { const ComputedStyle& base_style = element.ComputedStyleRef();
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 5567e70..b3058f2 100644 --- a/third_party/blink/renderer/core/css/resolver/style_resolver.h +++ b/third_party/blink/renderer/core/css/resolver/style_resolver.h
@@ -24,7 +24,6 @@ #define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_RESOLVER_STYLE_RESOLVER_H_ #include "base/gtest_prod_util.h" -#include "base/memory/scoped_refptr.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/core_export.h" @@ -66,10 +65,9 @@ ~StyleResolver(); void Dispose(); - scoped_refptr<const ComputedStyle> ResolveStyle( - Element*, - const StyleRecalcContext&, - const StyleRequest& = StyleRequest()); + const ComputedStyle* ResolveStyle(Element*, + const StyleRecalcContext&, + const StyleRequest& = StyleRequest()); // Return a reference to the initial style singleton. const ComputedStyle& InitialStyle() const; @@ -85,7 +83,7 @@ // root element style. In addition to initial values things like zoom, font, // forced color mode etc. is set. ComputedStyleBuilder InitialStyleBuilderForElement() const; - scoped_refptr<const ComputedStyle> InitialStyleForElement() const { + const ComputedStyle* InitialStyleForElement() const { return InitialStyleBuilderForElement().TakeStyle(); } @@ -99,23 +97,22 @@ const CSSValue*, double offset); - scoped_refptr<const ComputedStyle> StyleForPage( - uint32_t page_index, - const AtomicString& page_name); - scoped_refptr<const ComputedStyle> StyleForText(Text*); - scoped_refptr<const ComputedStyle> StyleForViewport(); - scoped_refptr<const ComputedStyle> StyleForFormattedText( + const ComputedStyle* StyleForPage(uint32_t page_index, + const AtomicString& page_name); + const ComputedStyle* StyleForText(Text*); + const ComputedStyle* StyleForViewport(); + const ComputedStyle* StyleForFormattedText( bool is_text_run, const ComputedStyle& parent_style, const CSSPropertyValueSet* css_property_value_set); - scoped_refptr<const ComputedStyle> StyleForFormattedText( + const ComputedStyle* StyleForFormattedText( bool is_text_run, const FontDescription& default_font, const CSSPropertyValueSet* css_property_value_set); // Returns `ComputedStyle` for rendering initial letter text. // `initial_letter_box_style` should have non-normal `initial-letter` // property. - scoped_refptr<const ComputedStyle> StyleForInitialLetterText( + const ComputedStyle* StyleForInitialLetterText( const ComputedStyle& initial_letter_box_style, const ComputedStyle& paragraph_style); @@ -127,7 +124,7 @@ ComputedStyleBuilder CreateAnonymousStyleBuilderWithDisplay( const ComputedStyle& parent_style, EDisplay); - scoped_refptr<const ComputedStyle> CreateAnonymousStyleWithDisplay( + const ComputedStyle* CreateAnonymousStyleWithDisplay( const ComputedStyle& parent_style, EDisplay display) { return CreateAnonymousStyleBuilderWithDisplay(parent_style, display) @@ -136,8 +133,7 @@ // Create ComputedStyle for anonymous wrappers between text boxes and // display:contents elements. - scoped_refptr<const ComputedStyle> - CreateInheritedDisplayContentsStyleIfNeeded( + const ComputedStyle* CreateInheritedDisplayContentsStyleIfNeeded( const ComputedStyle& parent_style, const ComputedStyle& layout_parent_style); @@ -208,7 +204,7 @@ const Font&, const CSSValue&); - scoped_refptr<const ComputedStyle> StyleForInterpolations( + const ComputedStyle* StyleForInterpolations( Element& element, ActiveInterpolationsMap& animations); @@ -217,16 +213,14 @@ // ticked to the current time. Ticking the animations is required to ensure // smooth retargeting of transitions. // https://drafts.csswg.org/css-transitions-1/#before-change-style - scoped_refptr<const ComputedStyle> BeforeChangeStyleForTransitionUpdate( + const ComputedStyle* BeforeChangeStyleForTransitionUpdate( Element& element, const ComputedStyle& base_style, ActiveInterpolationsMap& transition_interpolations); StyleRulePositionFallback* ResolvePositionFallbackRule( const TreeScope* tree_scope, AtomicString position_fallback_name); - scoped_refptr<const ComputedStyle> ResolvePositionFallbackStyle( - Element&, - unsigned index); + const ComputedStyle* ResolvePositionFallbackStyle(Element&, unsigned index); // Check if the BODY or HTML element's display or containment stops // propagation of BODY style to HTML and viewport. @@ -345,8 +339,10 @@ Functor& func) const; MatchedPropertiesCache matched_properties_cache_; - scoped_refptr<const ComputedStyle> initial_style_; - scoped_refptr<const ComputedStyle> initial_style_for_img_; + + // Both these members are on a hot-path for creating ComputedStyle objects. + subtle::UncompressedMember<const ComputedStyle> initial_style_; + subtle::UncompressedMember<const ComputedStyle> initial_style_for_img_; SelectorFilter selector_filter_; Member<Document> document_; @@ -364,7 +360,7 @@ FRIEND_TEST_ALL_PREFIXES(StyleResolverTest, TreeScopedReferences); Element& EnsureElementForFormattedText(); - scoped_refptr<const ComputedStyle> StyleForFormattedText( + const ComputedStyle* StyleForFormattedText( bool is_text_run, const FontDescription* default_font, const ComputedStyle* parent_style,
diff --git a/third_party/blink/renderer/core/css/resolver/style_resolver_state.cc b/third_party/blink/renderer/core/css/resolver/style_resolver_state.cc index a3d212d2..a4b5514 100644 --- a/third_party/blink/renderer/core/css/resolver/style_resolver_state.cc +++ b/third_party/blink/renderer/core/css/resolver/style_resolver_state.cc
@@ -145,7 +145,7 @@ return *inside_link_; } -scoped_refptr<const ComputedStyle> StyleResolverState::TakeStyle() { +const ComputedStyle* StyleResolverState::TakeStyle() { if (had_no_matched_properties_ && pseudo_request_type_ == StyleRequest::kForRenderer) { return nullptr; @@ -190,8 +190,7 @@ return UnzoomedLengthConversionData(style_builder_->GetFontSizeStyle()); } -void StyleResolverState::SetParentStyle( - scoped_refptr<const ComputedStyle> parent_style) { +void StyleResolverState::SetParentStyle(const ComputedStyle* parent_style) { parent_style_ = std::move(parent_style); if (style_builder_) { // Need to update conversion data for 'lh' units. @@ -200,8 +199,8 @@ } void StyleResolverState::SetLayoutParentStyle( - scoped_refptr<const ComputedStyle> parent_style) { - layout_parent_style_ = std::move(parent_style); + const ComputedStyle* parent_style) { + layout_parent_style_ = parent_style; } void StyleResolverState::LoadPendingResources() {
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 ddb0484..978cfb2 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
@@ -112,7 +112,7 @@ } ComputedStyleBuilder& StyleBuilder() { return *style_builder_; } const ComputedStyleBuilder& StyleBuilder() const { return *style_builder_; } - scoped_refptr<const ComputedStyle> TakeStyle(); + const ComputedStyle* TakeStyle(); const CSSToLengthConversionData& CssToLengthConversionData() const { return css_to_length_conversion_data_; @@ -145,18 +145,16 @@ // element, null otherwise. PseudoElement* GetPseudoElement() const; - void SetParentStyle(scoped_refptr<const ComputedStyle>); - const ComputedStyle* ParentStyle() const { return parent_style_.get(); } + void SetParentStyle(const ComputedStyle*); + const ComputedStyle* ParentStyle() const { return parent_style_; } - void SetLayoutParentStyle(scoped_refptr<const ComputedStyle>); + void SetLayoutParentStyle(const ComputedStyle*); const ComputedStyle* LayoutParentStyle() const { - return layout_parent_style_.get(); + return layout_parent_style_; } - void SetOldStyle(scoped_refptr<const ComputedStyle> old_style) { - old_style_ = std::move(old_style); - } - const ComputedStyle* OldStyle() const { return old_style_.get(); } + void SetOldStyle(const ComputedStyle* old_style) { old_style_ = old_style; } + const ComputedStyle* OldStyle() const { return old_style_; } ElementStyleResources& GetElementStyleResources() { return element_style_resources_; @@ -193,7 +191,7 @@ const CSSValue& ResolveLightDarkPair(const CSSValue&); const ComputedStyle* OriginatingElementStyle() const { - return originating_element_style_.get(); + return originating_element_style_; } bool IsForHighlight() const { return is_for_highlight_; } bool UsesHighlightPseudoInheritance() const { @@ -269,14 +267,14 @@ // parent_style_ is not always just ElementResolveContext::ParentStyle(), // so we keep it separate. - scoped_refptr<const ComputedStyle> parent_style_; + const ComputedStyle* parent_style_; // This will almost-always be the same that parent_style_, except in the // presence of display: contents. This is the style against which we have to // do adjustment. - scoped_refptr<const ComputedStyle> layout_parent_style_; + const ComputedStyle* layout_parent_style_; // The ComputedStyle stored on the element before the current lifecycle update // started. - scoped_refptr<const ComputedStyle> old_style_; + const ComputedStyle* old_style_; CSSAnimationUpdate animation_update_; StyleRequest::RequestType pseudo_request_type_; @@ -303,7 +301,7 @@ // This is computed only once, lazily (thus the absl::optional). mutable absl::optional<EInsideLink> inside_link_; - scoped_refptr<const ComputedStyle> originating_element_style_; + const ComputedStyle* originating_element_style_; // True if we are resolving styles for a highlight pseudo-element. const bool is_for_highlight_; // True if this is a highlight style request, and highlight inheritance
diff --git a/third_party/blink/renderer/core/css/resolver/style_resolver_test.cc b/third_party/blink/renderer/core/css/resolver/style_resolver_test.cc index 5a46eb0..61918a1c 100644 --- a/third_party/blink/renderer/core/css/resolver/style_resolver_test.cc +++ b/third_party/blink/renderer/core/css/resolver/style_resolver_test.cc
@@ -50,11 +50,11 @@ class StyleResolverTest : public PageTestBase { protected: - scoped_refptr<const ComputedStyle> StyleForId(const char* id) { + const ComputedStyle* StyleForId(const char* id) { Element* element = GetElementById(id); StyleRecalcContext recalc_context; recalc_context.old_style = element->GetComputedStyle(); - auto style = GetStyleEngine().GetStyleResolver().ResolveStyle( + const auto* style = GetStyleEngine().GetStyleResolver().ResolveStyle( element, recalc_context); DCHECK(style); return style; @@ -149,7 +149,7 @@ StyleResolver& resolver = GetStyleEngine().GetStyleResolver(); StyleRecalcContext recalc_context; recalc_context.old_style = div->GetComputedStyle(); - auto style1 = resolver.ResolveStyle(div, recalc_context); + const auto* style1 = resolver.ResolveStyle(div, recalc_context); ASSERT_TRUE(style1); EXPECT_EQ(20, style1->FontSize()); ASSERT_TRUE(style1->GetBaseComputedStyle()); @@ -225,7 +225,7 @@ div->SetNeedsAnimationStyleRecalc(); GetDocument().Lifecycle().AdvanceTo(DocumentLifecycle::kInStyleRecalc); - auto style = StyleForId("div"); + const auto* style = StyleForId("div"); const CSSBitset* bitset = style->GetBaseImportantSet(); EXPECT_FALSE(CSSAnimations::IsAnimatingStandardProperties( @@ -295,7 +295,7 @@ div->SetNeedsAnimationStyleRecalc(); GetDocument().Lifecycle().AdvanceTo(DocumentLifecycle::kInStyleRecalc); - auto style = StyleForId("div"); + const auto* style = StyleForId("div"); EXPECT_TRUE(style->GetBaseComputedStyle()); EXPECT_TRUE(style->GetBaseImportantSet()); @@ -372,7 +372,7 @@ div->SetNeedsAnimationStyleRecalc(); GetDocument().Lifecycle().AdvanceTo(DocumentLifecycle::kInStyleRecalc); - auto computed_style = StyleForId("div"); + const auto* computed_style = StyleForId("div"); EXPECT_TRUE(computed_style->HasFontRelativeUnits()); EXPECT_TRUE(computed_style->GetBaseComputedStyle()); @@ -396,7 +396,7 @@ div->SetNeedsAnimationStyleRecalc(); GetDocument().Lifecycle().AdvanceTo(DocumentLifecycle::kInStyleRecalc); - auto computed_style = StyleForId("div"); + const auto* computed_style = StyleForId("div"); EXPECT_TRUE(computed_style->HasFontRelativeUnits()); EXPECT_TRUE(computed_style->GetBaseComputedStyle()); @@ -610,7 +610,7 @@ )HTML"); GetDocument().GetStyleEngine().UpdateActiveStyle(); - scoped_refptr<const ComputedStyle> page_style = + const ComputedStyle* page_style = GetDocument().GetStyleResolver().StyleForPage(0, g_empty_atom); ASSERT_TRUE(page_style); const CSSValue* computed_value = ComputedStyleUtils::ComputedPropertyValue( @@ -646,7 +646,7 @@ StyleRequest target_text_style_request = pseudo_style_request; target_text_style_request.pseudo_id = kPseudoIdTargetText; - scoped_refptr<const ComputedStyle> target_text_style = + const ComputedStyle* target_text_style = GetDocument().GetStyleResolver().ResolveStyle(GetDocument().body(), StyleRecalcContext(), target_text_style_request); @@ -655,7 +655,7 @@ StyleRequest selection_style_style_request = pseudo_style_request; selection_style_style_request.pseudo_id = kPseudoIdSelection; - scoped_refptr<const ComputedStyle> selection_style = + const ComputedStyle* selection_style = GetDocument().GetStyleResolver().ResolveStyle( GetDocument().body(), StyleRecalcContext(), selection_style_style_request); @@ -671,8 +671,7 @@ CursorList* cursor_list = target_text_style->Cursors(); ASSERT_FALSE(cursor_list); - for (const auto* pseudo_style : - {target_text_style.get(), selection_style.get()}) { + for (const auto* pseudo_style : {target_text_style, selection_style}) { // Check that the color applies. EXPECT_EQ(Color(0, 128, 0), pseudo_style->VisitedDependentColor(GetCSSPropertyColor())); @@ -1025,9 +1024,9 @@ c->EnsureComputedStyle(); - scoped_refptr<const ComputedStyle> a_style = a->GetComputedStyle(); - scoped_refptr<const ComputedStyle> b_style = b->GetComputedStyle(); - scoped_refptr<const ComputedStyle> c_style = c->GetComputedStyle(); + const ComputedStyle* a_style = a->GetComputedStyle(); + const ComputedStyle* b_style = b->GetComputedStyle(); + const ComputedStyle* c_style = c->GetComputedStyle(); ASSERT_TRUE(a_style); ASSERT_TRUE(b_style); @@ -1050,9 +1049,9 @@ EXPECT_TRUE(c->GetComputedStyle()); EXPECT_TRUE(d->GetComputedStyle()); EXPECT_TRUE(e->GetComputedStyle()); - EXPECT_NE(a_style.get(), a->GetComputedStyle()); - EXPECT_NE(b_style.get(), b->GetComputedStyle()); - EXPECT_NE(c_style.get(), c->GetComputedStyle()); + EXPECT_NE(a_style, a->GetComputedStyle()); + EXPECT_NE(b_style, b->GetComputedStyle()); + EXPECT_NE(c_style, c->GetComputedStyle()); } TEST_F(StyleResolverTest, ComputeValueStandardProperty) { @@ -1309,7 +1308,7 @@ pseudo_style_request.layout_parent_override = element_style; pseudo_style_request.originating_element_style = element_style; pseudo_style_request.pseudo_id = kPseudoIdSelection; - scoped_refptr<const ComputedStyle> selection_style = + const ComputedStyle* selection_style = GetDocument().GetStyleResolver().ResolveStyle( target, StyleRecalcContext(), pseudo_style_request); ASSERT_FALSE(selection_style); @@ -1350,7 +1349,7 @@ pseudo_style_request.layout_parent_override = element_style; pseudo_style_request.originating_element_style = element_style; pseudo_style_request.pseudo_id = kPseudoIdSelection; - scoped_refptr<const ComputedStyle> selection_style = + const ComputedStyle* selection_style = GetDocument().GetStyleResolver().ResolveStyle( target, StyleRecalcContext(), pseudo_style_request); ASSERT_TRUE(selection_style); @@ -1390,7 +1389,7 @@ pseudo_style_request.layout_parent_override = element_style; pseudo_style_request.originating_element_style = element_style; pseudo_style_request.pseudo_id = kPseudoIdSelection; - scoped_refptr<const ComputedStyle> selection_style = + const ComputedStyle* selection_style = GetDocument().GetStyleResolver().ResolveStyle( target, StyleRecalcContext(), pseudo_style_request); ASSERT_TRUE(selection_style); @@ -1427,7 +1426,7 @@ pseudo_style_request.layout_parent_override = element_style; pseudo_style_request.originating_element_style = element_style; pseudo_style_request.pseudo_id = kPseudoIdSelection; - scoped_refptr<const ComputedStyle> selection_style = + const ComputedStyle* selection_style = GetDocument().GetStyleResolver().ResolveStyle( target, StyleRecalcContext(), pseudo_style_request); ASSERT_TRUE(selection_style); @@ -1467,7 +1466,7 @@ pseudo_style_request.layout_parent_override = element_style; pseudo_style_request.originating_element_style = element_style; pseudo_style_request.pseudo_id = kPseudoIdSelection; - scoped_refptr<const ComputedStyle> selection_style = + const ComputedStyle* selection_style = GetDocument().GetStyleResolver().ResolveStyle( target, StyleRecalcContext(), pseudo_style_request); ASSERT_TRUE(selection_style);
diff --git a/third_party/blink/renderer/core/css/style_engine.cc b/third_party/blink/renderer/core/css/style_engine.cc index a3fb49e..615f1ed 100644 --- a/third_party/blink/renderer/core/css/style_engine.cc +++ b/third_party/blink/renderer/core/css/style_engine.cc
@@ -3744,12 +3744,11 @@ return; } - scoped_refptr<const ComputedStyle> viewport_style = - resolver_->StyleForViewport(); + const ComputedStyle* viewport_style = resolver_->StyleForViewport(); if (ComputedStyle::ComputeDifference( - viewport_style.get(), GetDocument().GetLayoutView()->Style()) != + viewport_style, GetDocument().GetLayoutView()->Style()) != ComputedStyle::Difference::kEqual) { - GetDocument().GetLayoutView()->SetStyle(std::move(viewport_style)); + GetDocument().GetLayoutView()->SetStyle(viewport_style); } }
diff --git a/third_party/blink/renderer/core/css/style_engine_test.cc b/third_party/blink/renderer/core/css/style_engine_test.cc index c0186d9..81b6fca 100644 --- a/third_party/blink/renderer/core/css/style_engine_test.cc +++ b/third_party/blink/renderer/core/css/style_engine_test.cc
@@ -2749,8 +2749,8 @@ EXPECT_FALSE(innermost->GetComputedStyle()); inner->EnsureComputedStyle(); - scoped_refptr<const ComputedStyle> outer_style = outer->GetComputedStyle(); - scoped_refptr<const ComputedStyle> inner_style = inner->GetComputedStyle(); + const ComputedStyle* outer_style = outer->GetComputedStyle(); + const ComputedStyle* inner_style = inner->GetComputedStyle(); ASSERT_TRUE(outer_style); ASSERT_TRUE(inner_style); @@ -3920,8 +3920,7 @@ auto* inner_editor = DynamicTo<HTMLInputElement>(input)->InnerEditorElement(); ASSERT_TRUE(inner_editor); - scoped_refptr<const ComputedStyle> old_inner_style = - inner_editor->GetComputedStyle(); + const ComputedStyle* old_inner_style = inner_editor->GetComputedStyle(); EXPECT_TRUE(old_inner_style); unsigned start_count = GetStyleEngine().StyleForElementCount(); @@ -4787,14 +4786,14 @@ // with ChildNeedsStyleRecalc(), but the child needs to be marked dirty to // make sure the next EnsureComputedStyle updates the style to reflect the // changes. - scoped_refptr<const ComputedStyle> old_style = span->EnsureComputedStyle(); + const ComputedStyle* old_style = span->EnsureComputedStyle(); span->SetInlineStyleProperty(CSSPropertyID::kColor, "green"); EXPECT_FALSE(host->ChildNeedsStyleRecalc()); EXPECT_TRUE(span->NeedsStyleRecalc()); UpdateAllLifecyclePhases(); EXPECT_EQ(span->GetComputedStyle(), old_style); - scoped_refptr<const ComputedStyle> new_style = span->EnsureComputedStyle(); + const ComputedStyle* new_style = span->EnsureComputedStyle(); EXPECT_NE(new_style, old_style); EXPECT_EQ(Color::FromRGB(255, 0, 0),
diff --git a/third_party/blink/renderer/core/display_lock/display_lock_context.cc b/third_party/blink/renderer/core/display_lock/display_lock_context.cc index b0b50d6..0bc6e7e 100644 --- a/third_party/blink/renderer/core/display_lock/display_lock_context.cc +++ b/third_party/blink/renderer/core/display_lock/display_lock_context.cc
@@ -145,7 +145,7 @@ element_.Get()); } -scoped_refptr<const ComputedStyle> DisplayLockContext::AdjustElementStyle( +const ComputedStyle* DisplayLockContext::AdjustElementStyle( const ComputedStyle* style) const { if (IsAlwaysVisible()) return style;
diff --git a/third_party/blink/renderer/core/display_lock/display_lock_context.h b/third_party/blink/renderer/core/display_lock/display_lock_context.h index b5e9e66a..05b9ec0 100644 --- a/third_party/blink/renderer/core/display_lock/display_lock_context.h +++ b/third_party/blink/renderer/core/display_lock/display_lock_context.h
@@ -107,8 +107,7 @@ void SetRequestedState(EContentVisibility state, const AtomicString& toggle_visibility); // Called by style to adjust the element's style based on the current state. - scoped_refptr<const ComputedStyle> AdjustElementStyle( - const ComputedStyle*) const; + const ComputedStyle* AdjustElementStyle(const ComputedStyle*) const; // Is called by the intersection observer callback to inform us of the // intersection state.
diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc index c6bb820..3973509 100644 --- a/third_party/blink/renderer/core/dom/document.cc +++ b/third_party/blink/renderer/core/dom/document.cc
@@ -2724,16 +2724,15 @@ focused_element_->blur(); } -scoped_refptr<const ComputedStyle> Document::StyleForPage(uint32_t page_index) { +const ComputedStyle* Document::StyleForPage(uint32_t page_index) { AtomicString page_name; if (const LayoutView* layout_view = GetLayoutView()) page_name = layout_view->NamedPageAtIndex(page_index); return StyleForPage(page_index, page_name); } -scoped_refptr<const ComputedStyle> Document::StyleForPage( - uint32_t page_index, - const AtomicString& page_name) { +const ComputedStyle* Document::StyleForPage(uint32_t page_index, + const AtomicString& page_name) { GetStyleEngine().UpdateViewportSize(); GetStyleEngine().UpdateActiveStyle(); return GetStyleEngine().GetStyleResolver().StyleForPage(page_index, @@ -2874,8 +2873,7 @@ DCHECK(!ax_object_cache_ || this != &AXObjectCacheOwner()); UpdateForcedColors(); - scoped_refptr<const ComputedStyle> style = - GetStyleResolver().StyleForViewport(); + const ComputedStyle* style = GetStyleResolver().StyleForViewport(); layout_view_ = MakeGarbageCollected<LayoutNGView>(this); SetLayoutObject(layout_view_);
diff --git a/third_party/blink/renderer/core/dom/document.h b/third_party/blink/renderer/core/dom/document.h index 848a685..56ecb26 100644 --- a/third_party/blink/renderer/core/dom/document.h +++ b/third_party/blink/renderer/core/dom/document.h
@@ -740,10 +740,9 @@ // Get the computed style for a given page and name. Note that when using the // function that doesn't provide a page name, layout needs to be complete, // since page names are determined during layout. - scoped_refptr<const ComputedStyle> StyleForPage(uint32_t page_index); - scoped_refptr<const ComputedStyle> StyleForPage( - uint32_t page_index, - const AtomicString& page_name); + const ComputedStyle* StyleForPage(uint32_t page_index); + const ComputedStyle* StyleForPage(uint32_t page_index, + const AtomicString& page_name); // Ensures that location-based data will be valid for a given node. //
diff --git a/third_party/blink/renderer/core/dom/element.cc b/third_party/blink/renderer/core/dom/element.cc index 62c2ef2b..e135f19a 100644 --- a/third_party/blink/renderer/core/dom/element.cc +++ b/third_party/blink/renderer/core/dom/element.cc
@@ -3085,7 +3085,7 @@ ClearNeedsReattachLayoutTree(); } -scoped_refptr<const ComputedStyle> Element::StyleForLayoutObject( +const ComputedStyle* Element::StyleForLayoutObject( const StyleRecalcContext& style_recalc_context) { DCHECK(GetDocument().InStyleRecalc()); @@ -3105,7 +3105,7 @@ } new_style_recalc_context.old_style = PostStyleUpdateScope::GetOldStyle(*this); - scoped_refptr<const ComputedStyle> style = + const ComputedStyle* style = HasCustomStyleCallbacks() ? CustomStyleForLayoutObject(new_style_recalc_context) : OriginalStyleForLayoutObject(new_style_recalc_context); @@ -3118,7 +3118,7 @@ // time to compute the actual style and trigger transitions starting from // style with @starting-style applied. new_style_recalc_context.old_style = - style->Display() == EDisplay::kNone ? nullptr : style.get(); + style->Display() == EDisplay::kNone ? nullptr : style; style = HasCustomStyleCallbacks() ? CustomStyleForLayoutObject(new_style_recalc_context) : OriginalStyleForLayoutObject(new_style_recalc_context); @@ -3142,7 +3142,7 @@ } } context->SetRequestedState(style->ContentVisibility(), toggle_visibility); - style = context->AdjustElementStyle(style.get()); + style = context->AdjustElementStyle(style); } if (style->DependsOnSizeContainerQueries()) { @@ -3157,7 +3157,7 @@ AdjustStyle(builder); } -scoped_refptr<const ComputedStyle> Element::OriginalStyleForLayoutObject( +const ComputedStyle* Element::OriginalStyleForLayoutObject( const StyleRecalcContext& style_recalc_context) { return GetDocument().GetStyleResolver().ResolveStyle(this, style_recalc_context); @@ -3427,7 +3427,7 @@ } } -scoped_refptr<const ComputedStyle> Element::PropagateInheritedProperties() { +const ComputedStyle* Element::PropagateInheritedProperties() { if (IsPseudoElement()) { return nullptr; } @@ -3550,8 +3550,8 @@ new_style_recalc_context.parent_forces_recalc = true; } - scoped_refptr<const ComputedStyle> new_style; - scoped_refptr<const ComputedStyle> old_style = GetComputedStyle(); + const ComputedStyle* new_style = nullptr; + const ComputedStyle* old_style = GetComputedStyle(); StyleRecalcChange child_change = change.ForChildren(*this); @@ -3592,7 +3592,7 @@ } if (HighlightRecalc highlight_recalc = - CalculateHighlightRecalc(old_style.get(), new_style.get()); + CalculateHighlightRecalc(old_style, new_style); highlight_recalc != HighlightRecalc::kNone) { DCHECK(new_style); @@ -3605,48 +3605,48 @@ DCHECK_EQ(highlight_recalc, HighlightRecalc::kFull); const StyleHighlightData* parent_highlights = - parent_style ? parent_style->HighlightData().get() : nullptr; + parent_style ? &parent_style->HighlightData() : nullptr; if (UsesHighlightPseudoInheritance(kPseudoIdSelection) && new_style->HasPseudoElementStyle(kPseudoIdSelection)) { - StyleHighlightData& highlights = builder.MutableHighlightData(); + StyleHighlightData& highlights = builder.AccessHighlightData(); const ComputedStyle* highlight_parent = parent_highlights ? parent_highlights->Selection() : nullptr; StyleRequest style_request{kPseudoIdSelection, highlight_parent}; - style_request.originating_element_style = new_style.get(); + style_request.originating_element_style = new_style; highlights.SetSelection( StyleForPseudoElement(new_style_recalc_context, style_request)); } if (UsesHighlightPseudoInheritance(kPseudoIdTargetText) && new_style->HasPseudoElementStyle(kPseudoIdTargetText)) { - StyleHighlightData& highlights = builder.MutableHighlightData(); + StyleHighlightData& highlights = builder.AccessHighlightData(); const ComputedStyle* highlight_parent = parent_highlights ? parent_highlights->TargetText() : nullptr; StyleRequest style_request{kPseudoIdTargetText, highlight_parent}; - style_request.originating_element_style = new_style.get(); + style_request.originating_element_style = new_style; highlights.SetTargetText( StyleForPseudoElement(new_style_recalc_context, style_request)); } if (UsesHighlightPseudoInheritance(kPseudoIdSpellingError) && new_style->HasPseudoElementStyle(kPseudoIdSpellingError)) { - StyleHighlightData& highlights = builder.MutableHighlightData(); + StyleHighlightData& highlights = builder.AccessHighlightData(); const ComputedStyle* highlight_parent = parent_highlights ? parent_highlights->SpellingError() : nullptr; StyleRequest style_request{kPseudoIdSpellingError, highlight_parent}; - style_request.originating_element_style = new_style.get(); + style_request.originating_element_style = new_style; highlights.SetSpellingError( StyleForPseudoElement(new_style_recalc_context, style_request)); } if (UsesHighlightPseudoInheritance(kPseudoIdGrammarError) && new_style->HasPseudoElementStyle(kPseudoIdGrammarError)) { - StyleHighlightData& highlights = builder.MutableHighlightData(); + StyleHighlightData& highlights = builder.AccessHighlightData(); const ComputedStyle* highlight_parent = parent_highlights ? parent_highlights->GrammarError() : nullptr; StyleRequest style_request{kPseudoIdGrammarError, highlight_parent}; - style_request.originating_element_style = new_style.get(); + style_request.originating_element_style = new_style; highlights.SetGrammarError( StyleForPseudoElement(new_style_recalc_context, style_request)); } @@ -3658,14 +3658,14 @@ if (custom_highlight_names) { for (const AtomicString& custom_highlight_name : *custom_highlight_names) { - StyleHighlightData& highlights = builder.MutableHighlightData(); + StyleHighlightData& highlights = builder.AccessHighlightData(); const ComputedStyle* highlight_parent = parent_highlights ? parent_highlights->CustomHighlight(custom_highlight_name) : nullptr; StyleRequest style_request{kPseudoIdHighlight, highlight_parent, custom_highlight_name}; - style_request.originating_element_style = new_style.get(); + style_request.originating_element_style = new_style; highlights.SetCustomHighlight( custom_highlight_name, StyleForPseudoElement(new_style_recalc_context, style_request)); @@ -3678,7 +3678,7 @@ } ComputedStyle::Difference diff = - ComputedStyle::ComputeDifference(old_style.get(), new_style.get()); + ComputedStyle::ComputeDifference(old_style, new_style); if (old_style && old_style->IsEnsuredInDisplayNone()) { // Make sure we traverse children for clearing ensured computed styles @@ -3727,8 +3727,7 @@ if (!child_change.ReattachLayoutTree() && (GetForceReattachLayoutTree() || NeedsReattachLayoutTree() || - ComputedStyle::NeedsReattachLayoutTree(*this, old_style.get(), - new_style.get()))) { + ComputedStyle::NeedsReattachLayoutTree(*this, old_style, new_style))) { child_change = child_change.ForceReattachLayoutTree(); } @@ -3742,10 +3741,10 @@ } else { INCREMENT_STYLE_STATS_COUNTER(GetDocument().GetStyleEngine(), styles_changed, 1); - probe::DidUpdateComputedStyle(this, old_style.get(), new_style.get()); + probe::DidUpdateComputedStyle(this, old_style, new_style); if (this == GetDocument().documentElement()) { if (GetDocument().GetStyleEngine().UpdateRootFontRelativeUnits( - old_style.get(), new_style.get())) { + old_style, new_style)) { // Trigger a full document recalc on root font units changes. We could // keep track of which elements depend on root font units like we do for // viewport styles, but we assume root font size changes are rare and @@ -3755,9 +3754,8 @@ } } child_change = ApplyComputedStyleDiff(child_change, diff); - UpdateCallbackSelectors(old_style.get(), new_style.get()); - NotifyIfMatchedDocumentRulesSelectorsChanged(old_style.get(), - new_style.get()); + UpdateCallbackSelectors(old_style, new_style); + NotifyIfMatchedDocumentRulesSelectorsChanged(old_style, new_style); } if (auto* context = GetDisplayLockContext()) { @@ -3848,7 +3846,7 @@ ? LayoutObject::ApplyStyleChanges::kNo : LayoutObject::ApplyStyleChanges::kYes; - scoped_refptr<const ComputedStyle> layout_style(std::move(new_style)); + const ComputedStyle* layout_style = new_style; if (auto* pseudo_element = DynamicTo<PseudoElement>(this)) { if (layout_style->Display() == EDisplay::kContents) { layout_style = @@ -3870,7 +3868,7 @@ apply_changes = LayoutObject::ApplyStyleChanges::kYes; } } - layout_object->SetStyle(layout_style.get(), apply_changes); + layout_object->SetStyle(layout_style, apply_changes); } return child_change; } @@ -6357,7 +6355,7 @@ if (!element_style) { StyleRecalcContext local_style_recalc_context = style_recalc_context; local_style_recalc_context.is_ensuring_style = true; - scoped_refptr<const ComputedStyle> new_style = nullptr; + const ComputedStyle* new_style = nullptr; // TODO(crbug.com/953707): Avoid setting inline style during // HTMLImageElement::CustomStyleForLayoutObject. if (HasCustomStyleCallbacks() && !IsA<HTMLImageElement>(*this)) { @@ -6365,8 +6363,8 @@ } else { new_style = OriginalStyleForLayoutObject(local_style_recalc_context); } - element_style = new_style.get(); - SetComputedStyle(std::move(new_style)); + element_style = new_style; + SetComputedStyle(new_style); } } @@ -6395,9 +6393,9 @@ if (UsesHighlightPseudoInheritance(pseudo_element_specifier)) { const ComputedStyle* highlight_element_style = nullptr; ContainerNode* parent = LayoutTreeBuilderTraversal::Parent(*this); - if (parent && parent->GetComputedStyle()->HighlightData()) { + if (parent) { highlight_element_style = - parent->GetComputedStyle()->HighlightData()->Style( + parent->GetComputedStyle()->HighlightData().Style( pseudo_element_specifier, pseudo_argument); } style_request.parent_override = highlight_element_style; @@ -6418,12 +6416,11 @@ child_recalc_context.container = this; } - scoped_refptr<const ComputedStyle> result = - GetDocument().GetStyleResolver().ResolveStyle(this, child_recalc_context, - style_request); + const ComputedStyle* result = GetDocument().GetStyleResolver().ResolveStyle( + this, child_recalc_context, style_request); DCHECK(result); return element_style->AddCachedPseudoElementStyle( - std::move(result), pseudo_element_specifier, pseudo_argument); + result, pseudo_element_specifier, pseudo_argument); } bool Element::HasDisplayContentsStyle() const { @@ -6642,10 +6639,10 @@ // RemainingTextLayoutObject should have been cleared from DetachLayoutTree. DCHECK(!To<FirstLetterPseudoElement>(element)->RemainingTextLayoutObject()); DCHECK(text_node_changed); - scoped_refptr<const ComputedStyle> pseudo_style = + const ComputedStyle* pseudo_style = element->StyleForLayoutObject(style_recalc_context); - if (PseudoElementLayoutObjectIsNeeded(pseudo_style.get(), this)) { - element->SetComputedStyle(std::move(pseudo_style)); + if (PseudoElementLayoutObjectIsNeeded(pseudo_style, this)) { + element->SetComputedStyle(pseudo_style); } else { GetElementRareData()->SetPseudoElement(kPseudoIdFirstLetter, nullptr); } @@ -6727,9 +6724,9 @@ view_transition_name); pseudo_element->InsertedInto(*this); - scoped_refptr<const ComputedStyle> pseudo_style = + const ComputedStyle* pseudo_style = pseudo_element->StyleForLayoutObject(style_recalc_context); - if (!PseudoElementLayoutObjectIsNeeded(pseudo_style.get(), this)) { + if (!PseudoElementLayoutObjectIsNeeded(pseudo_style, this)) { GetElementRareData()->SetPseudoElement(pseudo_id, nullptr, view_transition_name); return nullptr; @@ -6866,16 +6863,16 @@ return cached; } - scoped_refptr<const ComputedStyle> result = UncachedStyleForPseudoElement( + const ComputedStyle* result = UncachedStyleForPseudoElement( StyleRequest(pseudo_id, style, pseudo_argument)); if (result) { - return style->AddCachedPseudoElementStyle(std::move(result), pseudo_id, + return style->AddCachedPseudoElementStyle(result, pseudo_id, pseudo_argument); } return nullptr; } -scoped_refptr<const ComputedStyle> Element::UncachedStyleForPseudoElement( +const ComputedStyle* Element::UncachedStyleForPseudoElement( const StyleRequest& request) { // Highlight pseudos are resolved into StyleHighlightData during originating // style recalc, where we have the actual StyleRecalcContext. @@ -6885,7 +6882,7 @@ StyleRecalcContext::FromInclusiveAncestors(*this), request); } -scoped_refptr<const ComputedStyle> Element::StyleForPseudoElement( +const ComputedStyle* Element::StyleForPseudoElement( const StyleRecalcContext& style_recalc_context, const StyleRequest& request) { GetDocument().GetStyleEngine().UpdateViewportSize(); @@ -6910,9 +6907,8 @@ } StyleRequest before_after_request = request; before_after_request.layout_parent_override = layout_parent_style; - scoped_refptr<const ComputedStyle> result = - GetDocument().GetStyleResolver().ResolveStyle( - this, style_recalc_context, before_after_request); + const ComputedStyle* result = GetDocument().GetStyleResolver().ResolveStyle( + this, style_recalc_context, before_after_request); if (result) { if (auto* quote = DynamicTo<HTMLQuoteElement>(this)) { ComputedStyleBuilder builder(*result); @@ -6932,9 +6928,8 @@ StyleRecalcContext local_recalc_context(style_recalc_context); local_recalc_context.old_style = PostStyleUpdateScope::GetOldStyle(*this); Element* target = IsPseudoElement() ? parentElement() : this; - scoped_refptr<const ComputedStyle> result = - GetDocument().GetStyleResolver().ResolveStyle( - target, local_recalc_context, first_line_inherited_request); + const ComputedStyle* result = GetDocument().GetStyleResolver().ResolveStyle( + target, local_recalc_context, first_line_inherited_request); if (result) { ComputedStyleBuilder builder(*result); builder.SetStyleType(kPseudoIdFirstLineInherited); @@ -7663,7 +7658,7 @@ DCHECK(HasCustomStyleCallbacks()); } -scoped_refptr<const ComputedStyle> Element::CustomStyleForLayoutObject( +const ComputedStyle* Element::CustomStyleForLayoutObject( const StyleRecalcContext& style_recalc_context) { DCHECK(HasCustomStyleCallbacks()); return OriginalStyleForLayoutObject(style_recalc_context); @@ -8838,13 +8833,13 @@ return cached_style; } - scoped_refptr<const ComputedStyle> style = + const ComputedStyle* style = GetDocument().GetStyleResolver().ResolvePositionFallbackStyle(*this, index); if (!style) { return nullptr; } - return base_style->AddCachedPositionFallbackStyle(std::move(style), index); + return base_style->AddCachedPositionFallbackStyle(style, index); } CSSToggleMap* Element::GetToggleMap() {
diff --git a/third_party/blink/renderer/core/dom/element.h b/third_party/blink/renderer/core/dom/element.h index 03f0bbfa..86512ba 100644 --- a/third_party/blink/renderer/core/dom/element.h +++ b/third_party/blink/renderer/core/dom/element.h
@@ -903,17 +903,15 @@ // // This is appropriate to use if the cached version is invalid in a given // situation. - scoped_refptr<const ComputedStyle> UncachedStyleForPseudoElement( - const StyleRequest&); + const ComputedStyle* UncachedStyleForPseudoElement(const StyleRequest&); // This is the same as UncachedStyleForPseudoElement, except that the caller // must provide an appropriate StyleRecalcContext such that e.g. @container // queries are evaluated correctly. // // See StyleRecalcContext for more information. - scoped_refptr<const ComputedStyle> StyleForPseudoElement( - const StyleRecalcContext&, - const StyleRequest&); + const ComputedStyle* StyleForPseudoElement(const StyleRecalcContext&, + const StyleRequest&); // Returns the ComputedStyle after applying the declarations in the @try block // at the given index. Returns nullptr if the current element doesn't use @@ -1011,8 +1009,7 @@ bool IsSpellCheckingEnabled() const; // FIXME: public for LayoutTreeBuilder, we shouldn't expose this though. - scoped_refptr<const ComputedStyle> StyleForLayoutObject( - const StyleRecalcContext&); + const ComputedStyle* StyleForLayoutObject(const StyleRecalcContext&); // Called by StyleAdjuster during style resolution. Provides an opportunity to // make final Element-specific adjustments to the ComputedStyle. @@ -1242,7 +1239,7 @@ virtual void WillRecalcStyle(const StyleRecalcChange); virtual void DidRecalcStyle(const StyleRecalcChange); - virtual scoped_refptr<const ComputedStyle> CustomStyleForLayoutObject( + virtual const ComputedStyle* CustomStyleForLayoutObject( const StyleRecalcContext&); virtual void AdjustStyle(ComputedStyleBuilder&); @@ -1283,8 +1280,7 @@ static bool AttributeValueIsJavaScriptURL(const Attribute&); - scoped_refptr<const ComputedStyle> OriginalStyleForLayoutObject( - const StyleRecalcContext&); + const ComputedStyle* OriginalStyleForLayoutObject(const StyleRecalcContext&); // Step 4 of http://domparsing.spec.whatwg.org/#insertadjacenthtml() Node* InsertAdjacent(const String& where, Node* new_child, ExceptionState&); @@ -1344,7 +1340,7 @@ // these changes can be directly propagated to this element (the child). // If these conditions are met, propagates the changes to the current style // and returns the new style. Otherwise, returns null. - scoped_refptr<const ComputedStyle> PropagateInheritedProperties(); + const ComputedStyle* PropagateInheritedProperties(); const ComputedStyle* EnsureOwnComputedStyle( const StyleRecalcContext&,
diff --git a/third_party/blink/renderer/core/dom/first_letter_pseudo_element.cc b/third_party/blink/renderer/core/dom/first_letter_pseudo_element.cc index cddfabf..918fad6b 100644 --- a/third_party/blink/renderer/core/dom/first_letter_pseudo_element.cc +++ b/third_party/blink/renderer/core/dom/first_letter_pseudo_element.cc
@@ -342,8 +342,7 @@ return PseudoElement::CreateLayoutObject(style); } -scoped_refptr<const ComputedStyle> -FirstLetterPseudoElement::CustomStyleForLayoutObject( +const ComputedStyle* FirstLetterPseudoElement::CustomStyleForLayoutObject( const StyleRecalcContext& style_recalc_context) { LayoutObject* first_letter_text = FirstLetterPseudoElement::FirstLetterTextLayoutObject(*this); @@ -418,7 +417,7 @@ // compute initial-letter font during layout to take proper effective style. const ComputedStyle& paragraph_style = paragraph.EffectiveStyle(NGStyleVariant::kFirstLine); - scoped_refptr<const ComputedStyle> initial_letter_text_style = + const ComputedStyle* initial_letter_text_style = GetDocument().GetStyleResolver().StyleForInitialLetterText( *letter_style, paragraph_style); letter->SetStyle(std::move(initial_letter_text_style));
diff --git a/third_party/blink/renderer/core/dom/first_letter_pseudo_element.h b/third_party/blink/renderer/core/dom/first_letter_pseudo_element.h index 8bd93e34..9134025 100644 --- a/third_party/blink/renderer/core/dom/first_letter_pseudo_element.h +++ b/third_party/blink/renderer/core/dom/first_letter_pseudo_element.h
@@ -62,7 +62,7 @@ private: LayoutObject* CreateLayoutObject(const ComputedStyle&) override; - scoped_refptr<const ComputedStyle> CustomStyleForLayoutObject( + const ComputedStyle* CustomStyleForLayoutObject( const StyleRecalcContext&) override; void AttachFirstLetterTextLayoutObjects(LayoutText* first_letter_text);
diff --git a/third_party/blink/renderer/core/dom/layout_tree_builder.cc b/third_party/blink/renderer/core/dom/layout_tree_builder.cc index 5a0d727..80aeee9 100644 --- a/third_party/blink/renderer/core/dom/layout_tree_builder.cc +++ b/third_party/blink/renderer/core/dom/layout_tree_builder.cc
@@ -128,7 +128,7 @@ parent_layout_object->AddChild(new_layout_object, next_layout_object); } -scoped_refptr<const ComputedStyle> +const ComputedStyle* LayoutTreeBuilderForText::CreateInlineWrapperStyleForDisplayContentsIfNeeded() const { // If the parent element is not a display:contents element, the style and the @@ -164,20 +164,20 @@ } void LayoutTreeBuilderForText::CreateLayoutObject() { - const ComputedStyle* style = style_.get(); + const ComputedStyle* style = style_; LayoutObject* layout_object_parent = context_.parent; LayoutObject* next_layout_object = NextLayoutObject(); - scoped_refptr<const ComputedStyle> nullable_wrapper_style = + const ComputedStyle* nullable_wrapper_style = CreateInlineWrapperStyleForDisplayContentsIfNeeded(); if (LayoutObject* wrapper = CreateInlineWrapperForDisplayContentsIfNeeded( - nullable_wrapper_style.get())) { + nullable_wrapper_style)) { layout_object_parent = wrapper; next_layout_object = nullptr; } // SVG <text> doesn't accept anonymous LayoutInlines. But the Text should have // the adjusted ComputedStyle. if (nullable_wrapper_style) - style = nullable_wrapper_style.get(); + style = nullable_wrapper_style; LayoutText* new_layout_object = node_->CreateTextLayoutObject(); if (!layout_object_parent->IsChildAllowed(new_layout_object, *style)) {
diff --git a/third_party/blink/renderer/core/dom/layout_tree_builder.h b/third_party/blink/renderer/core/dom/layout_tree_builder.h index bf88e493..47a42f1 100644 --- a/third_party/blink/renderer/core/dom/layout_tree_builder.h +++ b/third_party/blink/renderer/core/dom/layout_tree_builder.h
@@ -102,7 +102,7 @@ NodeType* node_; Node::AttachContext& context_; - scoped_refptr<const ComputedStyle> style_; + const ComputedStyle* style_; }; class LayoutTreeBuilderForElement : public LayoutTreeBuilder<Element> { @@ -128,8 +128,8 @@ void CreateLayoutObject(); private: - scoped_refptr<const ComputedStyle> - CreateInlineWrapperStyleForDisplayContentsIfNeeded() const; + const ComputedStyle* CreateInlineWrapperStyleForDisplayContentsIfNeeded() + const; LayoutObject* CreateInlineWrapperForDisplayContentsIfNeeded( const ComputedStyle* wrapper_style) const; };
diff --git a/third_party/blink/renderer/core/dom/node.cc b/third_party/blink/renderer/core/dom/node.cc index 8ce18ca..1b732fe 100644 --- a/third_party/blink/renderer/core/dom/node.cc +++ b/third_party/blink/renderer/core/dom/node.cc
@@ -1052,7 +1052,7 @@ data_ = MakeGarbageCollected<NodeData>(layout_object, nullptr); } -void Node::SetComputedStyle(scoped_refptr<const ComputedStyle> computed_style) { +void Node::SetComputedStyle(const ComputedStyle* computed_style) { // We don't set computed style for text nodes. DCHECK(IsElementNode());
diff --git a/third_party/blink/renderer/core/dom/node.h b/third_party/blink/renderer/core/dom/node.h index 19eaab2e..e8511e5 100644 --- a/third_party/blink/renderer/core/dom/node.h +++ b/third_party/blink/renderer/core/dom/node.h
@@ -325,7 +325,7 @@ bool SupportsAltText(); - void SetComputedStyle(scoped_refptr<const ComputedStyle> computed_style); + void SetComputedStyle(const ComputedStyle* computed_style); // Other methods (not part of DOM) ALWAYS_INLINE NodeType getNodeType() const {
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 7d8145d2..0634a5c 100644 --- a/third_party/blink/renderer/core/dom/node_rare_data.cc +++ b/third_party/blink/renderer/core/dom/node_rare_data.cc
@@ -80,7 +80,7 @@ } NodeData::NodeData(LayoutObject* layout_object, - scoped_refptr<const ComputedStyle> computed_style) + const ComputedStyle* computed_style) : computed_style_(computed_style), layout_object_(layout_object), bit_field_(RestyleFlags::encode(0) | @@ -91,8 +91,7 @@ NodeData::NodeData(blink::NodeData&&) = default; NodeData::~NodeData() = default; -void NodeData::SetComputedStyle( - scoped_refptr<const ComputedStyle> computed_style) { +void NodeData::SetComputedStyle(const ComputedStyle* computed_style) { DCHECK_NE(&SharedEmptyData(), this); computed_style_ = computed_style; } @@ -103,6 +102,7 @@ return *shared_empty_data; } void NodeData::Trace(Visitor* visitor) const { + visitor->Trace(computed_style_); visitor->Trace(layout_object_); }
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 0fe9a9f..87752b62d 100644 --- a/third_party/blink/renderer/core/dom/node_rare_data.h +++ b/third_party/blink/renderer/core/dom/node_rare_data.h
@@ -94,8 +94,7 @@ virtual ~NodeData(); virtual void Trace(Visitor*) const; - CORE_EXPORT NodeData(LayoutObject*, - scoped_refptr<const ComputedStyle> computed_style); + CORE_EXPORT NodeData(LayoutObject*, const ComputedStyle* computed_style); NodeData(const NodeData&) = delete; NodeData(NodeData&&); @@ -106,9 +105,9 @@ } const ComputedStyle* GetComputedStyle() const { - return computed_style_.get(); + return computed_style_.Get(); } - void SetComputedStyle(scoped_refptr<const ComputedStyle> computed_style); + void SetComputedStyle(const ComputedStyle* computed_style); void SetIsPseudoElement(bool value) { is_pseudo_element_ = value; } bool IsPseudoElement() const { return is_pseudo_element_; } @@ -134,7 +133,7 @@ } protected: - scoped_refptr<const ComputedStyle> computed_style_; + subtle::UncompressedMember<const ComputedStyle> computed_style_; Member<LayoutObject> layout_object_; BitField bit_field_; bool is_pseudo_element_ = false;
diff --git a/third_party/blink/renderer/core/dom/pseudo_element.cc b/third_party/blink/renderer/core/dom/pseudo_element.cc index bbaf844..4b29808c 100644 --- a/third_party/blink/renderer/core/dom/pseudo_element.cc +++ b/third_party/blink/renderer/core/dom/pseudo_element.cc
@@ -196,7 +196,7 @@ } } -scoped_refptr<const ComputedStyle> PseudoElement::CustomStyleForLayoutObject( +const ComputedStyle* PseudoElement::CustomStyleForLayoutObject( const StyleRecalcContext& style_recalc_context) { Element* parent = ParentOrShadowHostElement(); return parent->StyleForPseudoElement( @@ -204,7 +204,7 @@ view_transition_name_)); } -scoped_refptr<const ComputedStyle> PseudoElement::LayoutStyleForDisplayContents( +const ComputedStyle* PseudoElement::LayoutStyleForDisplayContents( const ComputedStyle& style) { // For display:contents we should not generate a box, but we generate a non- // observable inline box for pseudo elements to be able to locate the
diff --git a/third_party/blink/renderer/core/dom/pseudo_element.h b/third_party/blink/renderer/core/dom/pseudo_element.h index 3c49ef1..ff7149f8 100644 --- a/third_party/blink/renderer/core/dom/pseudo_element.h +++ b/third_party/blink/renderer/core/dom/pseudo_element.h
@@ -54,7 +54,7 @@ const AtomicString& view_transition_name() const { return view_transition_name_; } - scoped_refptr<const ComputedStyle> CustomStyleForLayoutObject( + const ComputedStyle* CustomStyleForLayoutObject( const StyleRecalcContext&) override; void AttachLayoutTree(AttachContext&) override; bool LayoutObjectIsNeeded(const DisplayStyle&) const override; @@ -63,8 +63,7 @@ bool CanStartSelection() const override { return false; } bool CanContainRangeEndPoint() const override { return false; } PseudoId GetPseudoId() const override { return pseudo_id_; } - scoped_refptr<const ComputedStyle> LayoutStyleForDisplayContents( - const ComputedStyle&); + const ComputedStyle* LayoutStyleForDisplayContents(const ComputedStyle&); static AtomicString PseudoElementNameForEvents(Element*); static bool IsWebExposed(PseudoId, const Node*); @@ -94,7 +93,7 @@ private: PseudoElement* element_; - scoped_refptr<const ComputedStyle> original_style_; + const ComputedStyle* original_style_{nullptr}; }; PseudoId pseudo_id_;
diff --git a/third_party/blink/renderer/core/dom/text.cc b/third_party/blink/renderer/core/dom/text.cc index 8b75f4c..96c0449 100644 --- a/third_party/blink/renderer/core/dom/text.cc +++ b/third_party/blink/renderer/core/dom/text.cc
@@ -389,7 +389,7 @@ } // namespace void Text::RecalcTextStyle(const StyleRecalcChange change) { - scoped_refptr<const ComputedStyle> new_style = + const ComputedStyle* new_style = GetDocument().GetStyleResolver().StyleForText(this); if (LayoutText* layout_text = GetLayoutObject()) { const ComputedStyle* layout_parent_style = @@ -401,7 +401,7 @@ // display:contents text child changed. SetNeedsReattachLayoutTree(); } else { - layout_text->SetStyle(std::move(new_style)); + layout_text->SetStyle(new_style); if (NeedsStyleRecalc()) layout_text->SetTextIfNeeded(data()); }
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 584fa082..3c8c305ba 100644 --- a/third_party/blink/renderer/core/frame/local_frame_view.cc +++ b/third_party/blink/renderer/core/frame/local_frame_view.cc
@@ -117,7 +117,6 @@ #include "third_party/blink/renderer/core/layout/ng/legacy_layout_tree_walking.h" #include "third_party/blink/renderer/core/layout/ng/ng_block_node.h" #include "third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h" -#include "third_party/blink/renderer/core/layout/style_retain_scope.h" #include "third_party/blink/renderer/core/layout/svg/layout_svg_root.h" #include "third_party/blink/renderer/core/layout/text_autosizer.h" #include "third_party/blink/renderer/core/layout/traced_layout_object.h" @@ -698,7 +697,6 @@ LayoutObject* root_for_this_layout = GetLayoutView(); FontCachePurgePreventer font_cache_purge_preventer; - StyleRetainScope style_retain_scope; bool in_subtree_layout = false; base::AutoReset<bool> change_scheduling_enabled(&layout_scheduling_enabled_, false);
diff --git a/third_party/blink/renderer/core/highlight/highlight_style_utils.cc b/third_party/blink/renderer/core/highlight/highlight_style_utils.cc index b0b83fa..b1db0c92 100644 --- a/third_party/blink/renderer/core/highlight/highlight_style_utils.cc +++ b/third_party/blink/renderer/core/highlight/highlight_style_utils.cc
@@ -204,8 +204,7 @@ // Returns highlight styles for the given node, inheriting from the originating // element only, like most impls did before highlights were added to css-pseudo. -scoped_refptr<const ComputedStyle> -HighlightPseudoStyleWithOriginatingInheritance( +const ComputedStyle* HighlightPseudoStyleWithOriginatingInheritance( Node* node, PseudoId pseudo, const AtomicString& pseudo_argument = g_null_atom) { @@ -317,7 +316,7 @@ // Returns highlight styles for the given node, inheriting through the “tree” of // highlight pseudo styles mirroring the originating element tree. None of the // returned styles are influenced by originating elements or pseudo-elements. -scoped_refptr<const ComputedStyle> HighlightStyleUtils::HighlightPseudoStyle( +const ComputedStyle* HighlightStyleUtils::HighlightPseudoStyle( Node* node, const ComputedStyle& style, PseudoId pseudo, @@ -327,21 +326,17 @@ pseudo_argument); } - if (!style.HighlightData()) { - return nullptr; - } - switch (pseudo) { case kPseudoIdSelection: - return style.HighlightData()->Selection(); + return style.HighlightData().Selection(); case kPseudoIdTargetText: - return style.HighlightData()->TargetText(); + return style.HighlightData().TargetText(); case kPseudoIdSpellingError: - return style.HighlightData()->SpellingError(); + return style.HighlightData().SpellingError(); case kPseudoIdGrammarError: - return style.HighlightData()->GrammarError(); + return style.HighlightData().GrammarError(); case kPseudoIdHighlight: - return style.HighlightData()->CustomHighlight(pseudo_argument); + return style.HighlightData().CustomHighlight(pseudo_argument); default: NOTREACHED(); return nullptr; @@ -361,10 +356,10 @@ } } - scoped_refptr<const ComputedStyle> pseudo_style = + const ComputedStyle* pseudo_style = HighlightPseudoStyle(node, style, pseudo, pseudo_argument); Color result = - ResolveColor(document, style, pseudo_style.get(), pseudo, + ResolveColor(document, style, pseudo_style, pseudo, GetCSSPropertyBackgroundColor(), previous_layer_color); if (pseudo == kPseudoIdSelection && NodeIsReplaced(node)) { // Avoid that ::selection full obscures selected replaced elements like @@ -417,24 +412,24 @@ // specified on the originating element (or the other highlight overlays). highlight_style.shadow = nullptr; - scoped_refptr<const ComputedStyle> pseudo_style = + const ComputedStyle* pseudo_style = HighlightPseudoStyle(node, style, pseudo, pseudo_argument); Color previous_layer_current_color = previous_layer_text_style.current_color; if (!uses_text_as_clip && !ignored_selection) { highlight_style.current_color = - ResolveColor(document, style, pseudo_style.get(), pseudo, + ResolveColor(document, style, pseudo_style, pseudo, GetCSSPropertyColor(), previous_layer_current_color); highlight_style.fill_color = ResolveColor( - document, style, pseudo_style.get(), pseudo, + document, style, pseudo_style, pseudo, GetCSSPropertyWebkitTextFillColor(), previous_layer_current_color); // TODO(crbug.com/1147859) ignore highlight ‘text-emphasis-color’ // https://github.com/w3c/csswg-drafts/issues/7101 highlight_style.emphasis_mark_color = ResolveColor( - document, style, pseudo_style.get(), pseudo, + document, style, pseudo_style, pseudo, GetCSSPropertyTextEmphasisColor(), previous_layer_current_color); highlight_style.stroke_color = ResolveColor( - document, style, pseudo_style.get(), pseudo, + document, style, pseudo_style, pseudo, GetCSSPropertyWebkitTextStrokeColor(), previous_layer_current_color); } @@ -472,9 +467,9 @@ return absl::nullopt; } - if (scoped_refptr<const ComputedStyle> pseudo_style = + if (const ComputedStyle* pseudo_style = HighlightPseudoStyle(node, style, pseudo)) { - return ResolveColor(document, style, pseudo_style.get(), pseudo, + return ResolveColor(document, style, pseudo_style, pseudo, GetCSSPropertyTextDecorationColor(), previous_layer_color); } @@ -490,14 +485,14 @@ // RuntimeEnabledFeatures::HighlightInheritanceEnabled() is true to avoid // needing a non-const node. const ComputedStyle* style = node.GetComputedStyle(); - if (!style || !style->HighlightData()) { + if (!style) { return false; } const ComputedStyle* pseudo_style = nullptr; switch (type) { case DocumentMarker::kTextFragment: if (RuntimeEnabledFeatures::HighlightOverlayPaintingEnabled()) { - pseudo_style = style->HighlightData()->TargetText(); + pseudo_style = style->HighlightData().TargetText(); } break; @@ -505,7 +500,7 @@ if (RuntimeEnabledFeatures::CSSSpellingGrammarErrorsEnabled() || RuntimeEnabledFeatures:: CSSPaintingForSpellingGrammarErrorsEnabled()) { - pseudo_style = style->HighlightData()->SpellingError(); + pseudo_style = style->HighlightData().SpellingError(); } break; @@ -513,7 +508,7 @@ if (RuntimeEnabledFeatures::CSSSpellingGrammarErrorsEnabled() || RuntimeEnabledFeatures:: CSSPaintingForSpellingGrammarErrorsEnabled()) { - pseudo_style = style->HighlightData()->GrammarError(); + pseudo_style = style->HighlightData().GrammarError(); } break; @@ -531,11 +526,11 @@ const Node* node, const AtomicString& pseudo_argument) { const ComputedStyle* style = node->GetComputedStyle(); - if (!style || !style->HighlightData()) { + if (!style) { return false; } const ComputedStyle* pseudo_style = - style->HighlightData()->CustomHighlight(pseudo_argument); + style->HighlightData().CustomHighlight(pseudo_argument); if (!pseudo_style) { return false; }
diff --git a/third_party/blink/renderer/core/highlight/highlight_style_utils.h b/third_party/blink/renderer/core/highlight/highlight_style_utils.h index a8ad2fd..3da2399 100644 --- a/third_party/blink/renderer/core/highlight/highlight_style_utils.h +++ b/third_party/blink/renderer/core/highlight/highlight_style_utils.h
@@ -61,7 +61,7 @@ absl::optional<Color> previous_layer_color, PseudoId); - static scoped_refptr<const ComputedStyle> HighlightPseudoStyle( + static const ComputedStyle* HighlightPseudoStyle( Node* node, const ComputedStyle& style, PseudoId pseudo,
diff --git a/third_party/blink/renderer/core/highlight/highlight_style_utils_test.cc b/third_party/blink/renderer/core/highlight/highlight_style_utils_test.cc index 833b447..4285756 100644 --- a/third_party/blink/renderer/core/highlight/highlight_style_utils_test.cc +++ b/third_party/blink/renderer/core/highlight/highlight_style_utils_test.cc
@@ -26,11 +26,10 @@ Color SelectionWebkitTextFillColor(const Document& document, Node* node, const ComputedStyle& originating_style) { - scoped_refptr<const ComputedStyle> pseudo_style = - HighlightStyleUtils::HighlightPseudoStyle(node, originating_style, - kPseudoIdSelection); + const ComputedStyle* pseudo_style = HighlightStyleUtils::HighlightPseudoStyle( + node, originating_style, kPseudoIdSelection); return HighlightStyleUtils::ResolveColor( - document, originating_style, pseudo_style.get(), kPseudoIdSelection, + document, originating_style, pseudo_style, kPseudoIdSelection, GetCSSPropertyWebkitTextFillColor(), Color::kBlack); }
diff --git a/third_party/blink/renderer/core/html/canvas/canvas_font_cache.cc b/third_party/blink/renderer/core/html/canvas/canvas_font_cache.cc index bbccd42..7726ed0b 100644 --- a/third_party/blink/renderer/core/html/canvas/canvas_font_cache.cc +++ b/third_party/blink/renderer/core/html/canvas/canvas_font_cache.cc
@@ -16,6 +16,8 @@ #include "third_party/blink/renderer/platform/heap/garbage_collected.h" #include "third_party/blink/renderer/platform/instrumentation/memory_pressure_listener.h" +namespace blink { + namespace { const unsigned CanvasFontCacheMaxFonts = 50; @@ -24,12 +26,8 @@ const unsigned CanvasFontCacheHardMaxFontsLowEnd = 20; const unsigned CanvasFontCacheHiddenMaxFonts = 1; const int defaultFontSize = 10; -} -namespace blink { - -CanvasFontCache::CanvasFontCache(Document& document) - : document_(&document), pruning_scheduled_(false) { +const ComputedStyle* CreateDefaultFontStyle(const Document& document) { const AtomicString& default_font_family = font_family_names::kSansSerif; FontFamily font_family; font_family.SetFamily(default_font_family, @@ -43,9 +41,16 @@ ? document.GetStyleResolver().CreateComputedStyleBuilder() : ComputedStyleBuilder(*ComputedStyle::CreateInitialStyleSingleton()); builder.SetFontDescription(default_font_description); - default_font_style_ = builder.TakeStyle(); + return builder.TakeStyle(); } +} // namespace + +CanvasFontCache::CanvasFontCache(Document& document) + : document_(&document), + default_font_style_(CreateDefaultFontStyle(document)), + pruning_scheduled_(false) {} + CanvasFontCache::~CanvasFontCache() { } @@ -164,6 +169,7 @@ void CanvasFontCache::Trace(Visitor* visitor) const { visitor->Trace(fetched_fonts_); visitor->Trace(document_); + visitor->Trace(default_font_style_); } void CanvasFontCache::Dispose() {
diff --git a/third_party/blink/renderer/core/html/canvas/canvas_font_cache.h b/third_party/blink/renderer/core/html/canvas/canvas_font_cache.h index 8f32137..b033fd7 100644 --- a/third_party/blink/renderer/core/html/canvas/canvas_font_cache.h +++ b/third_party/blink/renderer/core/html/canvas/canvas_font_cache.h
@@ -68,7 +68,7 @@ LinkedHashSet<String> font_lru_list_; std::unique_ptr<FontCachePurgePreventer> main_cache_purge_preventer_; Member<Document> document_; - scoped_refptr<const ComputedStyle> default_font_style_; + Member<const ComputedStyle> default_font_style_; bool pruning_scheduled_; };
diff --git a/third_party/blink/renderer/core/html/forms/date_time_edit_element.cc b/third_party/blink/renderer/core/html/forms/date_time_edit_element.cc index 3526a38..b3607a4 100644 --- a/third_party/blink/renderer/core/html/forms/date_time_edit_element.cc +++ b/third_party/blink/renderer/core/html/forms/date_time_edit_element.cc
@@ -580,12 +580,11 @@ field->blur(); } -scoped_refptr<const ComputedStyle> -DateTimeEditElement::CustomStyleForLayoutObject( +const ComputedStyle* DateTimeEditElement::CustomStyleForLayoutObject( const StyleRecalcContext& style_recalc_context) { // TODO(crbug.com/1181868): This is a kind of layout. We might want to // introduce new LayoutObject. - scoped_refptr<const ComputedStyle> original_style = + const ComputedStyle* original_style = OriginalStyleForLayoutObject(style_recalc_context); float width = 0; for (Node* child = FieldsWrapperElement()->firstChild(); child;
diff --git a/third_party/blink/renderer/core/html/forms/date_time_edit_element.h b/third_party/blink/renderer/core/html/forms/date_time_edit_element.h index 028dacd8..a1765e96 100644 --- a/third_party/blink/renderer/core/html/forms/date_time_edit_element.h +++ b/third_party/blink/renderer/core/html/forms/date_time_edit_element.h
@@ -140,7 +140,7 @@ void UpdateUIState(); // Element function. - scoped_refptr<const ComputedStyle> CustomStyleForLayoutObject( + const ComputedStyle* CustomStyleForLayoutObject( const StyleRecalcContext&) override; bool IsDateTimeEditElement() const override;
diff --git a/third_party/blink/renderer/core/html/forms/html_select_list_element.cc b/third_party/blink/renderer/core/html/forms/html_select_list_element.cc index f6bae89..9f2b75db 100644 --- a/third_party/blink/renderer/core/html/forms/html_select_list_element.cc +++ b/third_party/blink/renderer/core/html/forms/html_select_list_element.cc
@@ -47,7 +47,7 @@ } private: - scoped_refptr<const ComputedStyle> CustomStyleForLayoutObject( + const ComputedStyle* CustomStyleForLayoutObject( const StyleRecalcContext& style_recalc_context) override { HTMLSelectListElement* selectlist = DynamicTo<HTMLSelectListElement>(OwnerShadowHost()); @@ -57,7 +57,7 @@ const ComputedStyle& button_style = selectlist->ButtonPart()->ComputedStyleRef(); - scoped_refptr<const ComputedStyle> original_style = + const ComputedStyle* original_style = OriginalStyleForLayoutObject(style_recalc_context); ComputedStyleBuilder style_builder(*original_style); if (button_style.HasAuthorBorderRadius()) {
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 3f1cc7b..2bd93d3 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
@@ -108,18 +108,16 @@ return kNoPart; } -scoped_refptr<const ComputedStyle> StyleForHoveredScrollbarPart( - HTMLSelectElement& element, - const ComputedStyle* style, - Scrollbar* scrollbar, - PseudoId target_id) { +const ComputedStyle* StyleForHoveredScrollbarPart(HTMLSelectElement& element, + const ComputedStyle* style, + Scrollbar* scrollbar, + PseudoId target_id) { ScrollbarPart part = ScrollbarPartFromPseudoId(target_id); if (part == kNoPart) return nullptr; scrollbar->SetHoveredPart(part); - scoped_refptr<const ComputedStyle> part_style = - element.UncachedStyleForPseudoElement( - StyleRequest(target_id, To<CustomScrollbar>(scrollbar), part, style)); + const ComputedStyle* part_style = element.UncachedStyleForPseudoElement( + StyleRequest(target_id, To<CustomScrollbar>(scrollbar), part, style)); return part_style; } @@ -325,10 +323,9 @@ } // For Pseudo-class styles, Style should be calculated via that status. if (temp_scrollbar) { - scoped_refptr<const ComputedStyle> part_style = - StyleForHoveredScrollbarPart(owner_element, - owner_element.GetComputedStyle(), - temp_scrollbar, target.first); + const ComputedStyle* part_style = StyleForHoveredScrollbarPart( + owner_element, owner_element.GetComputedStyle(), temp_scrollbar, + target.first); if (part_style) { AppendOwnerElementPseudoStyles(target.second + ":hover", data, *part_style);
diff --git a/third_party/blink/renderer/core/html/forms/menu_list_inner_element.cc b/third_party/blink/renderer/core/html/forms/menu_list_inner_element.cc index 43dd290..5701027 100644 --- a/third_party/blink/renderer/core/html/forms/menu_list_inner_element.cc +++ b/third_party/blink/renderer/core/html/forms/menu_list_inner_element.cc
@@ -17,8 +17,7 @@ SetHasCustomStyleCallbacks(); } -scoped_refptr<const ComputedStyle> -MenuListInnerElement::CustomStyleForLayoutObject( +const ComputedStyle* MenuListInnerElement::CustomStyleForLayoutObject( const StyleRecalcContext& style_recalc_context) { const ComputedStyle& parent_style = OwnerShadowHost()->ComputedStyleRef(); ComputedStyleBuilder style_builder =
diff --git a/third_party/blink/renderer/core/html/forms/menu_list_inner_element.h b/third_party/blink/renderer/core/html/forms/menu_list_inner_element.h index 2308152b60..ec80202 100644 --- a/third_party/blink/renderer/core/html/forms/menu_list_inner_element.h +++ b/third_party/blink/renderer/core/html/forms/menu_list_inner_element.h
@@ -14,7 +14,7 @@ explicit MenuListInnerElement(Document& document); private: - scoped_refptr<const ComputedStyle> CustomStyleForLayoutObject( + const ComputedStyle* CustomStyleForLayoutObject( const StyleRecalcContext&) override; };
diff --git a/third_party/blink/renderer/core/html/forms/select_type.cc b/third_party/blink/renderer/core/html/forms/select_type.cc index 6b32e4b..19fb45ff 100644 --- a/third_party/blink/renderer/core/html/forms/select_type.cc +++ b/third_party/blink/renderer/core/html/forms/select_type.cc
@@ -94,7 +94,7 @@ void UpdateTextStyleAndContent() override; HTMLOptionElement* OptionToBeShown() const override; const ComputedStyle* OptionStyle() const override { - return option_style_.get(); + return option_style_.Get(); } void MaximumOptionWidthMightBeChanged() const override; @@ -123,7 +123,7 @@ Member<PopupMenu> popup_; Member<PopupUpdater> popup_updater_; - scoped_refptr<const ComputedStyle> option_style_; + Member<const ComputedStyle> option_style_; int ax_menulist_last_active_index_ = -1; bool has_updated_menulist_active_option_ = false; bool popup_is_visible_ = false; @@ -133,6 +133,7 @@ void MenuListSelectType::Trace(Visitor* visitor) const { visitor->Trace(popup_); visitor->Trace(popup_updater_); + visitor->Trace(option_style_); SelectType::Trace(visitor); } @@ -516,10 +517,10 @@ builder.SetDirection(option_style->Direction()); builder.SetUnicodeBidi(option_style->GetUnicodeBidi()); builder.SetTextAlign(option_style->GetTextAlign(true)); - scoped_refptr<const ComputedStyle> new_style = builder.TakeStyle(); + const ComputedStyle* new_style = builder.TakeStyle(); if (auto* inner_layout = inner_element.GetLayoutObject()) { inner_layout->SetModifiedStyleOutsideStyleRecalc( - std::move(new_style), LayoutObject::ApplyStyleChanges::kYes); + new_style, LayoutObject::ApplyStyleChanges::kYes); } else { inner_element.SetComputedStyle(std::move(new_style)); }
diff --git a/third_party/blink/renderer/core/html/forms/text_control_inner_elements.cc b/third_party/blink/renderer/core/html/forms/text_control_inner_elements.cc index 9d398e4..83eab9d 100644 --- a/third_party/blink/renderer/core/html/forms/text_control_inner_elements.cc +++ b/third_party/blink/renderer/core/html/forms/text_control_inner_elements.cc
@@ -47,8 +47,8 @@ setAttribute(html_names::kIdAttr, shadow_element_names::kIdEditingViewPort); } -scoped_refptr<const ComputedStyle> -EditingViewPortElement::CustomStyleForLayoutObject(const StyleRecalcContext&) { +const ComputedStyle* EditingViewPortElement::CustomStyleForLayoutObject( + const StyleRecalcContext&) { // FXIME: Move these styles to html.css. ComputedStyleBuilder style_builder = @@ -127,8 +127,7 @@ return MakeGarbageCollected<LayoutNGTextControlInnerEditor>(this); } -scoped_refptr<const ComputedStyle> -TextControlInnerEditorElement::CustomStyleForLayoutObject( +const ComputedStyle* TextControlInnerEditorElement::CustomStyleForLayoutObject( const StyleRecalcContext&) { Element* host = OwnerShadowHost(); DCHECK(host); @@ -199,7 +198,7 @@ if (!is_visible_) style_builder.SetOpacity(0); - scoped_refptr<const ComputedStyle> style = style_builder.TakeStyle(); + const ComputedStyle* style = style_builder.TakeStyle(); if (style->HasPseudoElementStyle(kPseudoIdScrollbar)) { ComputedStyleBuilder no_scrollbar_style_builder =
diff --git a/third_party/blink/renderer/core/html/forms/text_control_inner_elements.h b/third_party/blink/renderer/core/html/forms/text_control_inner_elements.h index 988a027e..eccfa1f 100644 --- a/third_party/blink/renderer/core/html/forms/text_control_inner_elements.h +++ b/third_party/blink/renderer/core/html/forms/text_control_inner_elements.h
@@ -37,7 +37,7 @@ explicit EditingViewPortElement(Document&); protected: - scoped_refptr<const ComputedStyle> CustomStyleForLayoutObject( + const ComputedStyle* CustomStyleForLayoutObject( const StyleRecalcContext&) override; private: @@ -55,7 +55,7 @@ private: LayoutObject* CreateLayoutObject(const ComputedStyle&) override; - scoped_refptr<const ComputedStyle> CustomStyleForLayoutObject( + const ComputedStyle* CustomStyleForLayoutObject( const StyleRecalcContext&) override; bool SupportsFocus() const override { return false; } bool is_visible_ = true;
diff --git a/third_party/blink/renderer/core/html/html_element.cc b/third_party/blink/renderer/core/html/html_element.cc index 9ea9f6d..88f2125 100644 --- a/third_party/blink/renderer/core/html/html_element.cc +++ b/third_party/blink/renderer/core/html/html_element.cc
@@ -3134,6 +3134,13 @@ bool is_old_auto = SelfOrAncestorHasDirAutoAttribute(); bool is_new_auto = HasDirectionAuto(); + + if (is_new_auto) { + if (auto* input_element = DynamicTo<HTMLInputElement>(*this)) { + input_element->EnsureShadowSubtree(); + } + } + bool needs_slot_assignment_recalc = false; auto* parent = GetParentForDirectionality(*this, needs_slot_assignment_recalc);
diff --git a/third_party/blink/renderer/core/html/html_embed_element_test.cc b/third_party/blink/renderer/core/html/html_embed_element_test.cc index dfba53e8..8117b38 100644 --- a/third_party/blink/renderer/core/html/html_embed_element_test.cc +++ b/third_party/blink/renderer/core/html/html_embed_element_test.cc
@@ -49,7 +49,7 @@ UpdateAllLifecyclePhasesForTest(); - scoped_refptr<const ComputedStyle> initial_style = + const ComputedStyle* initial_style = GetDocument().GetStyleResolver().InitialStyleForElement(); // We should get |true| as a result and don't trigger a DCHECK.
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 e0ed9164..dd52fe89 100644 --- a/third_party/blink/renderer/core/html/html_html_element.cc +++ b/third_party/blink/renderer/core/html/html_html_element.cc
@@ -95,9 +95,8 @@ layout_style.Direction() != propagated_style.Direction(); } -scoped_refptr<const ComputedStyle> CreateLayoutStyle( - const ComputedStyle& style, - const ComputedStyle& propagated_style) { +const ComputedStyle* CreateLayoutStyle(const ComputedStyle& style, + const ComputedStyle& propagated_style) { ComputedStyleBuilder builder(style); builder.SetDirection(propagated_style.Direction()); builder.SetWritingMode(propagated_style.GetWritingMode()); @@ -107,8 +106,8 @@ } // namespace -scoped_refptr<const ComputedStyle> HTMLHtmlElement::LayoutStyleForElement( - scoped_refptr<const ComputedStyle> style) { +const ComputedStyle* HTMLHtmlElement::LayoutStyleForElement( + const ComputedStyle* style) { DCHECK(style); DCHECK(GetDocument().InStyleRecalc()); DCHECK(GetLayoutObject()); @@ -144,7 +143,7 @@ return; const ComputedStyle* const old_style = layout_object->Style(); - scoped_refptr<const ComputedStyle> new_style = + const ComputedStyle* new_style = LayoutStyleForElement(layout_object->Style()); if (old_style == new_style)
diff --git a/third_party/blink/renderer/core/html/html_html_element.h b/third_party/blink/renderer/core/html/html_html_element.h index 410a459..53fa5b1 100644 --- a/third_party/blink/renderer/core/html/html_html_element.h +++ b/third_party/blink/renderer/core/html/html_html_element.h
@@ -41,8 +41,7 @@ void ParseAttribute(const AttributeModificationParams&) override; bool HasNonInBodyInsertionMode() const override { return true; } void PropagateWritingModeAndDirectionFromBody(); - scoped_refptr<const ComputedStyle> LayoutStyleForElement( - scoped_refptr<const ComputedStyle> style); + const ComputedStyle* LayoutStyleForElement(const ComputedStyle* style); BlockingAttribute& blocking() const { return *blocking_attribute_; } bool IsPotentiallyRenderBlocking() const override {
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 72579eef..8d902623 100644 --- a/third_party/blink/renderer/core/html/html_plugin_element.cc +++ b/third_party/blink/renderer/core/html/html_plugin_element.cc
@@ -920,10 +920,9 @@ } } -scoped_refptr<const ComputedStyle> -HTMLPlugInElement::CustomStyleForLayoutObject( +const ComputedStyle* HTMLPlugInElement::CustomStyleForLayoutObject( const StyleRecalcContext& style_recalc_context) { - scoped_refptr<const ComputedStyle> style = + const ComputedStyle* style = OriginalStyleForLayoutObject(style_recalc_context); if (IsImageType() && !GetLayoutObject() && style && LayoutObjectIsNeeded(*style)) {
diff --git a/third_party/blink/renderer/core/html/html_plugin_element.h b/third_party/blink/renderer/core/html/html_plugin_element.h index 5451bed..7be0d5c 100644 --- a/third_party/blink/renderer/core/html/html_plugin_element.h +++ b/third_party/blink/renderer/core/html/html_plugin_element.h
@@ -161,7 +161,7 @@ bool IsFocusableStyle() const final; bool IsKeyboardFocusable() const final; void DidAddUserAgentShadowRoot(ShadowRoot&) final; - scoped_refptr<const ComputedStyle> CustomStyleForLayoutObject( + const ComputedStyle* CustomStyleForLayoutObject( const StyleRecalcContext&) final; // HTMLElement overrides:
diff --git a/third_party/blink/renderer/core/html/shadow/meter_shadow_element_test.cc b/third_party/blink/renderer/core/html/shadow/meter_shadow_element_test.cc index d039a171e..67eac58 100644 --- a/third_party/blink/renderer/core/html/shadow/meter_shadow_element_test.cc +++ b/third_party/blink/renderer/core/html/shadow/meter_shadow_element_test.cc
@@ -45,7 +45,7 @@ GetDocument().GetStyleEngine().RecalcStyle(); EXPECT_FALSE(shadow_element->GetComputedStyle()); - scoped_refptr<const ComputedStyle> style = + const ComputedStyle* style = shadow_element->StyleForLayoutObject(StyleRecalcContext()); EXPECT_FALSE(shadow_element->LayoutObjectIsNeeded(*style)); }
diff --git a/third_party/blink/renderer/core/html/shadow/progress_shadow_element_test.cc b/third_party/blink/renderer/core/html/shadow/progress_shadow_element_test.cc index 43c08b51..eb41e0a 100644 --- a/third_party/blink/renderer/core/html/shadow/progress_shadow_element_test.cc +++ b/third_party/blink/renderer/core/html/shadow/progress_shadow_element_test.cc
@@ -45,7 +45,7 @@ GetDocument().GetStyleEngine().RecalcStyle(); EXPECT_TRUE(shadow_element->GetComputedStyle()); - scoped_refptr<const ComputedStyle> style = + const ComputedStyle* style = shadow_element->StyleForLayoutObject(StyleRecalcContext()); EXPECT_TRUE(shadow_element->LayoutObjectIsNeeded(*style)); }
diff --git a/third_party/blink/renderer/core/inspector/inspector_dom_snapshot_agent.cc b/third_party/blink/renderer/core/inspector/inspector_dom_snapshot_agent.cc index 8d38d043..c5894bbc 100644 --- a/third_party/blink/renderer/core/inspector/inspector_dom_snapshot_agent.cc +++ b/third_party/blink/renderer/core/inspector/inspector_dom_snapshot_agent.cc
@@ -822,6 +822,7 @@ visitor->Trace(paint_order_map_); visitor->Trace(document_order_map_); visitor->Trace(css_value_cache_); + visitor->Trace(style_cache_); InspectorBaseAgent::Trace(visitor); }
diff --git a/third_party/blink/renderer/core/inspector/inspector_dom_snapshot_agent.h b/third_party/blink/renderer/core/inspector/inspector_dom_snapshot_agent.h index 6b85a72..2181637 100644 --- a/third_party/blink/renderer/core/inspector/inspector_dom_snapshot_agent.h +++ b/third_party/blink/renderer/core/inspector/inspector_dom_snapshot_agent.h
@@ -118,8 +118,7 @@ WTF::HashMap<String, int> string_table_; HeapHashMap<Member<const CSSValue>, int> css_value_cache_; - HashMap<scoped_refptr<const ComputedStyle>, protocol::Array<int>*> - style_cache_; + HeapHashMap<Member<const ComputedStyle>, protocol::Array<int>*> style_cache_; std::unique_ptr<protocol::Array<protocol::DOMSnapshot::DocumentSnapshot>> documents_;
diff --git a/third_party/blink/renderer/core/layout/build.gni b/third_party/blink/renderer/core/layout/build.gni index bbd8f715..03918712 100644 --- a/third_party/blink/renderer/core/layout/build.gni +++ b/third_party/blink/renderer/core/layout/build.gni
@@ -575,8 +575,6 @@ "shapes/shape_interval.h", "shapes/shape_outside_info.cc", "shapes/shape_outside_info.h", - "style_retain_scope.cc", - "style_retain_scope.h", "svg/layout_svg_block.cc", "svg/layout_svg_block.h", "svg/layout_svg_container.cc", @@ -803,7 +801,6 @@ "selection_state_test.cc", "shapes/box_shape_test.cc", "shapes/ellipse_shape_test.cc", - "style_retain_scope_test.cc", "svg/layout_svg_container_test.cc", "svg/layout_svg_inline_test.cc", "svg/layout_svg_root_test.cc",
diff --git a/third_party/blink/renderer/core/layout/custom_scrollbar.cc b/third_party/blink/renderer/core/layout/custom_scrollbar.cc index 5f989975..c23a254 100644 --- a/third_party/blink/renderer/core/layout/custom_scrollbar.cc +++ b/third_party/blink/renderer/core/layout/custom_scrollbar.cc
@@ -131,9 +131,9 @@ PositionScrollbarParts(); } -scoped_refptr<const ComputedStyle> -CustomScrollbar::GetScrollbarPseudoElementStyle(ScrollbarPart part_type, - PseudoId pseudo_id) { +const ComputedStyle* CustomScrollbar::GetScrollbarPseudoElementStyle( + ScrollbarPart part_type, + PseudoId pseudo_id) { Element* element = StyleSource(); DCHECK(element); Document& document = element->GetDocument(); @@ -150,9 +150,8 @@ if (!element->GetLayoutObject()) return nullptr; const ComputedStyle* source_style = StyleSource()->GetLayoutObject()->Style(); - scoped_refptr<const ComputedStyle> part_style = - element->UncachedStyleForPseudoElement( - StyleRequest(pseudo_id, this, part_type, source_style)); + const ComputedStyle* part_style = element->UncachedStyleForPseudoElement( + StyleRequest(pseudo_id, this, part_type, source_style)); if (!part_style) return nullptr; if (part_style->DependsOnFontMetrics()) { @@ -240,9 +239,8 @@ if (part_type == kNoPart) return; - scoped_refptr<const ComputedStyle> part_style = - GetScrollbarPseudoElementStyle(part_type, - PseudoForScrollbarPart(part_type)); + const ComputedStyle* part_style = GetScrollbarPseudoElementStyle( + part_type, PseudoForScrollbarPart(part_type)); bool need_layout_object = part_style && part_style->Display() != EDisplay::kNone; @@ -283,7 +281,7 @@ } if (part_layout_object) - part_layout_object->SetStyle(std::move(part_style)); + part_layout_object->SetStyle(part_style); } gfx::Rect CustomScrollbar::ButtonRect(ScrollbarPart part_type) const {
diff --git a/third_party/blink/renderer/core/layout/custom_scrollbar.h b/third_party/blink/renderer/core/layout/custom_scrollbar.h index 7ef76bed..16a42c9 100644 --- a/third_party/blink/renderer/core/layout/custom_scrollbar.h +++ b/third_party/blink/renderer/core/layout/custom_scrollbar.h
@@ -97,9 +97,7 @@ void DestroyScrollbarParts(); void UpdateScrollbarParts(); - scoped_refptr<const ComputedStyle> GetScrollbarPseudoElementStyle( - ScrollbarPart, - PseudoId); + const ComputedStyle* GetScrollbarPseudoElementStyle(ScrollbarPart, PseudoId); void UpdateScrollbarPart(ScrollbarPart); HeapHashMap<ScrollbarPart, Member<LayoutCustomScrollbarPart>> parts_;
diff --git a/third_party/blink/renderer/core/layout/flexible_box_algorithm.cc b/third_party/blink/renderer/core/layout/flexible_box_algorithm.cc index 68d13dc..9ae023a2 100644 --- a/third_party/blink/renderer/core/layout/flexible_box_algorithm.cc +++ b/third_party/blink/renderer/core/layout/flexible_box_algorithm.cc
@@ -109,7 +109,7 @@ } bool FlexItem::MainAxisIsInlineAxis() const { - return algorithm_->IsHorizontalFlow() == style_.IsHorizontalWritingMode(); + return algorithm_->IsHorizontalFlow() == style_->IsHorizontalWritingMode(); } LayoutUnit FlexItem::FlowAwareMarginStart() const { @@ -202,22 +202,26 @@ } ItemPosition FlexItem::Alignment() const { - return FlexLayoutAlgorithm::AlignmentForChild(*algorithm_->Style(), style_); + return FlexLayoutAlgorithm::AlignmentForChild(*algorithm_->Style(), *style_); } void FlexItem::UpdateAutoMarginsInMainAxis(LayoutUnit auto_margin_offset) { DCHECK_GE(auto_margin_offset, LayoutUnit()); if (algorithm_->IsHorizontalFlow()) { - if (style_.MarginLeft().IsAuto()) + if (style_->MarginLeft().IsAuto()) { physical_margins_.left = auto_margin_offset; - if (style_.MarginRight().IsAuto()) + } + if (style_->MarginRight().IsAuto()) { physical_margins_.right = auto_margin_offset; + } } else { - if (style_.MarginTop().IsAuto()) + if (style_->MarginTop().IsAuto()) { physical_margins_.top = auto_margin_offset; - if (style_.MarginBottom().IsAuto()) + } + if (style_->MarginBottom().IsAuto()) { physical_margins_.bottom = auto_margin_offset; + } } } @@ -227,9 +231,9 @@ bool is_horizontal = algorithm_->IsHorizontalFlow(); const Length& top_or_left = - is_horizontal ? style_.MarginTop() : style_.MarginLeft(); + is_horizontal ? style_->MarginTop() : style_->MarginLeft(); const Length& bottom_or_right = - is_horizontal ? style_.MarginBottom() : style_.MarginRight(); + is_horizontal ? style_->MarginBottom() : style_->MarginRight(); if (top_or_left.IsAuto() && bottom_or_right.IsAuto()) { offset_->cross_axis_offset += available_alignment_space / 2; if (is_horizontal) { @@ -242,13 +246,13 @@ return true; } bool should_adjust_top_or_left = true; - if (algorithm_->IsColumnFlow() && !style_.IsLeftToRightDirection()) { + if (algorithm_->IsColumnFlow() && !style_->IsLeftToRightDirection()) { // For column flows, only make this adjustment if topOrLeft corresponds to // the "before" margin, so that flipForRightToLeftColumn will do the right // thing. should_adjust_top_or_left = false; } - if (!algorithm_->IsColumnFlow() && style_.IsFlippedBlocksWritingMode()) { + if (!algorithm_->IsColumnFlow() && style_->IsFlippedBlocksWritingMode()) { // If we are a flipped writing mode, we need to adjust the opposite side. // This is only needed for row flows because this only affects the // block-direction axis. @@ -284,14 +288,15 @@ std::max(cross_axis_border_padding_, Line()->cross_axis_extent_ - CrossAxisMarginExtent()); - if ((MainAxisIsInlineAxis() && style_.LogicalHeight().IsAuto()) || - (!MainAxisIsInlineAxis() && style_.LogicalWidth().IsAuto())) { + if ((MainAxisIsInlineAxis() && style_->LogicalHeight().IsAuto()) || + (!MainAxisIsInlineAxis() && style_->LogicalWidth().IsAuto())) { cross_axis_size_ = min_max_cross_sizes_->ClampSizeToMinAndMax(stretched_size); } } void FlexItem::Trace(Visitor* visitor) const { + visitor->Trace(style_); visitor->Trace(ng_input_node_); visitor->Trace(layout_result_); } @@ -345,7 +350,7 @@ const ComputedStyle& flex_box_style = algorithm_->StyleRef(); for (wtf_size_t i = 0; i < violations.size(); ++i) { DCHECK(!violations[i]->frozen_) << i; - const ComputedStyle& child_style = violations[i]->style_; + const ComputedStyle& child_style = *violations[i]->style_; LayoutUnit child_size = violations[i]->flexed_content_size_; remaining_free_space_ -= child_size - violations[i]->flex_base_content_size_; @@ -378,8 +383,8 @@ DCHECK(!flex_item.frozen_) << i; float flex_factor = (flex_sign == kPositiveFlexibility) - ? flex_item.style_.ResolvedFlexGrow(flex_box_style) - : flex_item.style_.ResolvedFlexShrink(flex_box_style); + ? flex_item.style_->ResolvedFlexGrow(flex_box_style) + : flex_item.style_->ResolvedFlexShrink(flex_box_style); if (flex_factor == 0 || (flex_sign == kPositiveFlexibility && flex_item.flex_base_content_size_ > @@ -425,14 +430,14 @@ if (remaining_free_space_ > 0 && total_flex_grow_ > 0 && flex_sign == kPositiveFlexibility && std::isfinite(total_flex_grow_)) { extra_space = remaining_free_space_ * - flex_item.style_.ResolvedFlexGrow(flex_box_style) / + flex_item.style_->ResolvedFlexGrow(flex_box_style) / total_flex_grow_; } else if (remaining_free_space_ < 0 && total_weighted_flex_shrink_ > 0 && flex_sign == kNegativeFlexibility && std::isfinite(total_weighted_flex_shrink_) && - flex_item.style_.ResolvedFlexShrink(flex_box_style)) { + flex_item.style_->ResolvedFlexShrink(flex_box_style)) { extra_space = remaining_free_space_ * - flex_item.style_.ResolvedFlexShrink(flex_box_style) * + flex_item.style_->ResolvedFlexShrink(flex_box_style) * flex_item.flex_base_content_size_ / total_weighted_flex_shrink_; } @@ -467,8 +472,8 @@ int number_of_auto_margins = 0; bool is_horizontal = algorithm_->IsHorizontalFlow(); - for (wtf_size_t i = 0; i < line_items_.size(); ++i) { - const ComputedStyle& style = line_items_[i].style_; + for (const auto& line_item : line_items_) { + const ComputedStyle& style = *line_item.style_; if (is_horizontal) { if (style.MarginLeft().IsAuto()) ++number_of_auto_margins; @@ -686,8 +691,8 @@ line_has_in_flow_item = true; sum_flex_base_size += flex_item.FlexBaseMarginBoxSize() + gap_between_items_; - total_flex_grow += flex_item.style_.ResolvedFlexGrow(StyleRef()); - const float flex_shrink = flex_item.style_.ResolvedFlexShrink(StyleRef()); + total_flex_grow += flex_item.style_->ResolvedFlexGrow(StyleRef()); + const float flex_shrink = flex_item.style_->ResolvedFlexShrink(StyleRef()); total_flex_shrink += flex_shrink; total_weighted_flex_shrink += flex_shrink * flex_item.flex_base_content_size_; @@ -865,7 +870,7 @@ LayoutUnit available_space = flex_item.AvailableAlignmentSpace(); if (!is_webkit_box && flex_item.style_ - .ResolvedAlignSelf(ItemPosition::kStretch, &StyleRef()) + ->ResolvedAlignSelf(ItemPosition::kStretch, &StyleRef()) .Overflow() == OverflowAlignment::kSafe) { available_space = available_space.ClampNegativeToZero(); } @@ -1221,6 +1226,7 @@ } void FlexLayoutAlgorithm::Trace(Visitor* visitor) const { + visitor->Trace(style_); visitor->Trace(all_items_); }
diff --git a/third_party/blink/renderer/core/layout/flexible_box_algorithm.h b/third_party/blink/renderer/core/layout/flexible_box_algorithm.h index 36b9773..b5fd5b6 100644 --- a/third_party/blink/renderer/core/layout/flexible_box_algorithm.h +++ b/third_party/blink/renderer/core/layout/flexible_box_algorithm.h
@@ -151,7 +151,7 @@ const FlexLayoutAlgorithm* algorithm_; wtf_size_t line_number_; - const ComputedStyle& style_; + Member<const ComputedStyle> style_; const LayoutUnit flex_base_content_size_; const MinMaxSizes min_max_main_sizes_; const absl::optional<MinMaxSizes> min_max_cross_sizes_; @@ -430,7 +430,7 @@ friend class NGFlexLayoutAlgorithm; EOverflow MainAxisOverflowForChild(const LayoutBox& child) const; - const ComputedStyle* style_; + Member<const ComputedStyle> style_; const LayoutUnit line_break_length_; FlexItemVector all_items_; Vector<FlexLine> flex_lines_;
diff --git a/third_party/blink/renderer/core/layout/layout_block.cc b/third_party/blink/renderer/core/layout/layout_block.cc index 0861a869..24b539b4 100644 --- a/third_party/blink/renderer/core/layout/layout_block.cc +++ b/third_party/blink/renderer/core/layout/layout_block.cc
@@ -765,7 +765,7 @@ new_display); parent->UpdateAnonymousChildStyle(nullptr, new_style_builder); - scoped_refptr<const ComputedStyle> new_style = new_style_builder.TakeStyle(); + const ComputedStyle* new_style = new_style_builder.TakeStyle(); LayoutBlock* layout_block; if (new_display == EDisplay::kFlex) { @@ -782,7 +782,7 @@ layout_block = MakeGarbageCollected<LayoutNGBlockFlow>(nullptr); } layout_block->SetDocumentForAnonymous(&parent->GetDocument()); - layout_block->SetStyle(std::move(new_style)); + layout_block->SetStyle(new_style); return layout_block; }
diff --git a/third_party/blink/renderer/core/layout/layout_block_flow.cc b/third_party/blink/renderer/core/layout/layout_block_flow.cc index 722b3de..f1e1095 100644 --- a/third_party/blink/renderer/core/layout/layout_block_flow.cc +++ b/third_party/blink/renderer/core/layout/layout_block_flow.cc
@@ -85,9 +85,8 @@ LayoutBlockFlow::~LayoutBlockFlow() = default; -LayoutBlockFlow* LayoutBlockFlow::CreateAnonymous( - Document* document, - scoped_refptr<const ComputedStyle> style) { +LayoutBlockFlow* LayoutBlockFlow::CreateAnonymous(Document* document, + const ComputedStyle* style) { auto* layout_block_flow = MakeGarbageCollected<LayoutNGBlockFlow>(nullptr); layout_block_flow->SetDocumentForAnonymous(document); layout_block_flow->SetStyle(style);
diff --git a/third_party/blink/renderer/core/layout/layout_block_flow.h b/third_party/blink/renderer/core/layout/layout_block_flow.h index 770ff9ae..b69ebca4 100644 --- a/third_party/blink/renderer/core/layout/layout_block_flow.h +++ b/third_party/blink/renderer/core/layout/layout_block_flow.h
@@ -67,8 +67,7 @@ ~LayoutBlockFlow() override; void Trace(Visitor*) const override; - static LayoutBlockFlow* CreateAnonymous(Document*, - scoped_refptr<const ComputedStyle>); + static LayoutBlockFlow* CreateAnonymous(Document*, const ComputedStyle*); bool IsLayoutBlockFlow() const final { NOT_DESTROYED();
diff --git a/third_party/blink/renderer/core/layout/layout_box.cc b/third_party/blink/renderer/core/layout/layout_box.cc index fccb566..dc047820 100644 --- a/third_party/blink/renderer/core/layout/layout_box.cc +++ b/third_party/blink/renderer/core/layout/layout_box.cc
@@ -136,9 +136,8 @@ LayoutUnit intrinsic_logical_widths_initial_block_size; Member<void*> result; HeapVector<Member<const NGLayoutResult>, 1> layout_results; - void* pointers[1]; wtf_size_t first_fragment_item_index_; - Member<void*> rare_data; + Member<void*> members[2]; }; ASSERT_SIZE(LayoutBox, SameSizeAsLayoutBox); @@ -473,6 +472,7 @@ void LayoutBox::Trace(Visitor* visitor) const { visitor->Trace(measure_result_); visitor->Trace(layout_results_); + visitor->Trace(overflow_); visitor->Trace(rare_data_); LayoutBoxModelObject::Trace(visitor); } @@ -3532,7 +3532,7 @@ DCHECK(!LayoutOverflowIsSet()); if (!overflow_) - overflow_ = std::make_unique<BoxOverflowModel>(); + overflow_ = MakeGarbageCollected<BoxOverflowModel>(); overflow_->layout_overflow.emplace(layout_overflow->ToLayoutRect()); } @@ -3657,7 +3657,7 @@ if (!VisualOverflowIsSet()) { if (!overflow_) - overflow_ = std::make_unique<BoxOverflowModel>(); + overflow_ = MakeGarbageCollected<BoxOverflowModel>(); overflow_->visual_overflow.emplace(border_box); } @@ -3681,7 +3681,7 @@ if (!VisualOverflowIsSet()) { if (!overflow_) - overflow_ = std::make_unique<BoxOverflowModel>(); + overflow_ = MakeGarbageCollected<BoxOverflowModel>(); overflow_->visual_overflow.emplace(border_box); } @@ -4208,7 +4208,7 @@ void LayoutBox::MutableForPainting::SavePreviousOverflowData() { if (!GetLayoutBox().overflow_) - GetLayoutBox().overflow_ = std::make_unique<BoxOverflowModel>(); + GetLayoutBox().overflow_ = MakeGarbageCollected<BoxOverflowModel>(); auto& previous_overflow = GetLayoutBox().overflow_->previous_overflow_data; if (!previous_overflow) previous_overflow.emplace(); @@ -4230,7 +4230,7 @@ return; if (!GetLayoutBox().overflow_) - GetLayoutBox().overflow_ = std::make_unique<BoxOverflowModel>(); + GetLayoutBox().overflow_ = MakeGarbageCollected<BoxOverflowModel>(); auto& previous_overflow = GetLayoutBox().overflow_->previous_overflow_data; if (!previous_overflow) previous_overflow.emplace();
diff --git a/third_party/blink/renderer/core/layout/layout_box.h b/third_party/blink/renderer/core/layout/layout_box.h index 1815bf14..8a3813d 100644 --- a/third_party/blink/renderer/core/layout/layout_box.h +++ b/third_party/blink/renderer/core/layout/layout_box.h
@@ -1283,7 +1283,7 @@ void ClearPreviousOverflowData() { DCHECK(!GetLayoutBox().HasVisualOverflow()); DCHECK(!GetLayoutBox().HasLayoutOverflow()); - GetLayoutBox().overflow_.reset(); + GetLayoutBox().overflow_ = nullptr; } void SavePreviousContentBoxRect() { auto& rare_data = GetLayoutBox().EnsureRareData(); @@ -1660,13 +1660,12 @@ friend class LayoutBoxTest; private: - std::unique_ptr<BoxOverflowModel> overflow_; - // The index of the first fragment item associated with this object in // |NGFragmentItems::Items()|. Zero means there are no such item. // Valid only when IsInLayoutNGInlineFormattingContext(). wtf_size_t first_fragment_item_index_ = 0u; + Member<BoxOverflowModel> overflow_; Member<LayoutBoxRareData> rare_data_; FRIEND_TEST_ALL_PREFIXES(LayoutMultiColumnSetTest, ScrollAnchroingCrash);
diff --git a/third_party/blink/renderer/core/layout/layout_object.cc b/third_party/blink/renderer/core/layout/layout_object.cc index 53fb6bd..53174aa2 100644 --- a/third_party/blink/renderer/core/layout/layout_object.cc +++ b/third_party/blink/renderer/core/layout/layout_object.cc
@@ -223,8 +223,8 @@ } StyleDifference AdjustForCompositableAnimationPaint( - scoped_refptr<const ComputedStyle> old_style, - scoped_refptr<const ComputedStyle> new_style, + const ComputedStyle* old_style, + const ComputedStyle* new_style, Node* node, StyleDifference diff) { DCHECK(new_style); @@ -320,7 +320,7 @@ unsigned bitfields_; unsigned bitfields2_; unsigned bitfields3_; - void* pointers[1]; + subtle::UncompressedMember<void*> uncompressed_member; Member<void*> members[5]; #if DCHECK_IS_ON() bool is_destroyed_; @@ -2479,9 +2479,8 @@ return diff; } -void LayoutObject::SetPseudoElementStyle( - scoped_refptr<const ComputedStyle> pseudo_style, - bool match_parent_size) { +void LayoutObject::SetPseudoElementStyle(const ComputedStyle* pseudo_style, + bool match_parent_size) { NOT_DESTROYED(); DCHECK(pseudo_style->StyleType() == kPseudoIdBefore || pseudo_style->StyleType() == kPseudoIdAfter || @@ -2515,7 +2514,7 @@ if (IsText() && Parent() && UNLIKELY(Parent()->IsInitialLetterBox())) { // Note: `Parent()` can be null for text for generated contents. // See "accessibility/css-generated-content.html" - scoped_refptr<const ComputedStyle> initial_letter_text_style = + const ComputedStyle* initial_letter_text_style = GetDocument().GetStyleResolver().StyleForInitialLetterText( *pseudo_style, Parent()->ContainingBlock()->StyleRef()); SetStyle(std::move(initial_letter_text_style)); @@ -2537,7 +2536,7 @@ } DISABLE_CFI_PERF -void LayoutObject::SetStyle(scoped_refptr<const ComputedStyle> style, +void LayoutObject::SetStyle(const ComputedStyle* style, ApplyStyleChanges apply_changes) { NOT_DESTROYED(); if (style_ == style) @@ -2572,11 +2571,9 @@ if (style_->HasPseudoElementStyle(pseudo) || style->HasPseudoElementStyle(pseudo)) { const ComputedStyle* pseudo_old_style = - style_->HighlightData() ? style_->HighlightData()->Style(pseudo) - : nullptr; + style_->HighlightData().Style(pseudo); const ComputedStyle* pseudo_new_style = - style->HighlightData() ? style->HighlightData()->Style(pseudo) - : nullptr; + style->HighlightData().Style(pseudo); if (pseudo_old_style && pseudo_new_style) { diff.Merge(pseudo_old_style->VisualInvalidationDiff( @@ -2611,17 +2608,17 @@ StyleWillChange(diff, *style); - scoped_refptr<const ComputedStyle> old_style = std::move(style_); + const ComputedStyle* old_style = std::move(style_); SetStyleInternal(std::move(style)); if (!IsText()) - UpdateImageObservers(old_style.get(), style_.get()); + UpdateImageObservers(old_style, style_.Get()); - CheckCounterChanges(old_style.get(), style_.get()); + CheckCounterChanges(old_style, style_.Get()); bool does_not_need_layout_or_paint_invalidation = !parent_; - StyleDidChange(diff, old_style.get()); + StyleDidChange(diff, old_style); // FIXME: |this| might be destroyed here. This can currently happen for a // LayoutTextFragment when its first-letter block gets an update in @@ -2733,8 +2730,8 @@ !has_new_first_line_style) return; - using FirstLineStyleMap = HeapHashMap<WeakMember<const LayoutObject>, - scoped_refptr<const ComputedStyle>>; + using FirstLineStyleMap = + HeapHashMap<WeakMember<const LayoutObject>, Member<const ComputedStyle>>; DEFINE_STATIC_LOCAL(Persistent<FirstLineStyleMap>, first_line_style_map, (MakeGarbageCollected<FirstLineStyleMap>())); DCHECK_EQ(bitfields_.RegisteredAsFirstLineImageObserver(), @@ -2747,7 +2744,7 @@ // UpdateFillImages() may indirectly call LayoutBlock::ImageChanged() which // will invalidate the first line style cache and remove a reference to // new_first_line_style, so hold a reference here. - scoped_refptr<const ComputedStyle> new_first_line_style = + const ComputedStyle* new_first_line_style = has_new_first_line_style ? FirstLineStyleWithoutFallback() : nullptr; if (new_first_line_style && !new_first_line_style->HasBackgroundImage()) @@ -3690,7 +3687,7 @@ // Remove this object as ImageResourceObserver. if (style_ && !IsText()) - UpdateImageObservers(style_.get(), nullptr); + UpdateImageObservers(style_.Get(), nullptr); // We must have removed all image observers. SECURITY_CHECK(!bitfields_.RegisteredAsFirstLineImageObserver()); @@ -4135,7 +4132,7 @@ // it's based on first_line_block's style. We need to get the uncached // first line style based on this object's style and cache the result in // it. - if (scoped_refptr<const ComputedStyle> first_line_style = + if (const ComputedStyle* first_line_style = first_line_block->GetUncachedPseudoElementStyle( StyleRequest(kPseudoIdFirstLine, Style()))) { return StyleRef().ReplaceCachedPseudoElementStyle( @@ -4152,7 +4149,7 @@ Parent()->FirstLineStyleWithoutFallback()) { // A first-line style is in effect. Get uncached first line style based on // parent_first_line_style and cache the result in this object's style. - if (scoped_refptr<const ComputedStyle> first_line_style = + if (const ComputedStyle* first_line_style = GetUncachedPseudoElementStyle(StyleRequest( kPseudoIdFirstLineInherited, parent_first_line_style))) { return StyleRef().AddCachedPseudoElementStyle( @@ -4179,7 +4176,7 @@ return element->CachedStyleForPseudoElement(pseudo); } -scoped_refptr<const ComputedStyle> LayoutObject::GetUncachedPseudoElementStyle( +const ComputedStyle* LayoutObject::GetUncachedPseudoElementStyle( const StyleRequest& request) const { NOT_DESTROYED(); DCHECK_NE(request.pseudo_id, kPseudoIdBefore); @@ -4199,10 +4196,7 @@ const ComputedStyle* LayoutObject::GetSelectionStyle() const { if (UsesHighlightPseudoInheritance(kPseudoIdSelection)) { - if (!StyleRef().HighlightData()) { - return nullptr; - } - return StyleRef().HighlightData()->Selection(); + return StyleRef().HighlightData().Selection(); } return GetCachedPseudoElementStyle(kPseudoIdSelection); } @@ -4960,7 +4954,7 @@ } void LayoutObject::SetModifiedStyleOutsideStyleRecalc( - scoped_refptr<const ComputedStyle> style, + const ComputedStyle* style, ApplyStyleChanges apply_changes) { NOT_DESTROYED(); SetStyle(style, apply_changes);
diff --git a/third_party/blink/renderer/core/layout/layout_object.h b/third_party/blink/renderer/core/layout/layout_object.h index dfbc6e0..953647d 100644 --- a/third_party/blink/renderer/core/layout/layout_object.h +++ b/third_party/blink/renderer/core/layout/layout_object.h
@@ -1760,8 +1760,7 @@ // from the originating element's style (because we can cache only one // version), while the uncached pseudo style can inherit from any style. const ComputedStyle* GetCachedPseudoElementStyle(PseudoId) const; - scoped_refptr<const ComputedStyle> GetUncachedPseudoElementStyle( - const StyleRequest&) const; + const ComputedStyle* GetUncachedPseudoElementStyle(const StyleRequest&) const; // Returns the ::selection style, which may be stored in StyleCachedData (old // impl) or StyleHighlightData (new impl). @@ -2303,11 +2302,11 @@ // and new ComputedStyle like paint and size invalidations. If kNo, just set // the ComputedStyle member. enum class ApplyStyleChanges { kNo, kYes }; - void SetStyle(scoped_refptr<const ComputedStyle>, + void SetStyle(const ComputedStyle*, ApplyStyleChanges = ApplyStyleChanges::kYes); // Set the style of the object if it's generated content. - void SetPseudoElementStyle(scoped_refptr<const ComputedStyle>, + void SetPseudoElementStyle(const ComputedStyle*, bool match_parent_size = false); // In some cases we modify the ComputedStyle after the style recalc, either @@ -2317,7 +2316,7 @@ // that node with the new ComputedStyle. Modifying the ComputedStyle of a node // outside of style recalc can break invariants in the style engine, so this // function must not gain any new call sites. - void SetModifiedStyleOutsideStyleRecalc(scoped_refptr<const ComputedStyle>, + void SetModifiedStyleOutsideStyleRecalc(const ComputedStyle*, ApplyStyleChanges); // This function returns an enclosing non-anonymous LayoutBlock for this @@ -2547,7 +2546,7 @@ const ComputedStyle* Style() const { NOT_DESTROYED(); - return style_.get(); + return style_.Get(); } // style_ can only be nullptr before the first style is set, thus most @@ -3595,7 +3594,7 @@ // Updates only the local style ptr of the object. Does not update the state // of the object, and so only should be called when the style is known not to // have changed (or from SetStyle). - void SetStyleInternal(scoped_refptr<const ComputedStyle> style) { + void SetStyleInternal(const ComputedStyle* style) { NOT_DESTROYED(); style_ = std::move(style); } @@ -4307,7 +4306,7 @@ friend class LineLayoutItem; friend class LocalFrameView; - scoped_refptr<const ComputedStyle> style_; + subtle::UncompressedMember<const ComputedStyle> style_; Member<Node> node_;
diff --git a/third_party/blink/renderer/core/layout/layout_object_hot.cc b/third_party/blink/renderer/core/layout/layout_object_hot.cc index 87df0c9..56319de 100644 --- a/third_party/blink/renderer/core/layout/layout_object_hot.cc +++ b/third_party/blink/renderer/core/layout/layout_object_hot.cc
@@ -18,6 +18,7 @@ namespace blink { void LayoutObject::Trace(Visitor* visitor) const { + visitor->Trace(style_); visitor->Trace(node_); visitor->Trace(parent_); visitor->Trace(previous_);
diff --git a/third_party/blink/renderer/core/layout/layout_text.cc b/third_party/blink/renderer/core/layout/layout_text.cc index c716a74d..26435996 100644 --- a/third_party/blink/renderer/core/layout/layout_text.cc +++ b/third_party/blink/renderer/core/layout/layout_text.cc
@@ -190,18 +190,17 @@ LayoutObject::Trace(visitor); } -LayoutText* LayoutText::CreateEmptyAnonymous( - Document& doc, - scoped_refptr<const ComputedStyle> style) { +LayoutText* LayoutText::CreateEmptyAnonymous(Document& doc, + const ComputedStyle* style) { auto* text = MakeGarbageCollected<LayoutText>(nullptr, StringImpl::empty_); text->SetDocumentForAnonymous(&doc); - text->SetStyle(std::move(style)); + text->SetStyle(style); return text; } LayoutText* LayoutText::CreateAnonymousForFormattedText( Document& doc, - scoped_refptr<const ComputedStyle> style, + const ComputedStyle* style, String text) { auto* layout_text = MakeGarbageCollected<LayoutText>(nullptr, std::move(text));
diff --git a/third_party/blink/renderer/core/layout/layout_text.h b/third_party/blink/renderer/core/layout/layout_text.h index ccc4a30..c95806c 100644 --- a/third_party/blink/renderer/core/layout/layout_text.h +++ b/third_party/blink/renderer/core/layout/layout_text.h
@@ -80,13 +80,11 @@ void Trace(Visitor*) const override; - static LayoutText* CreateEmptyAnonymous(Document&, - scoped_refptr<const ComputedStyle>); + static LayoutText* CreateEmptyAnonymous(Document&, const ComputedStyle*); - static LayoutText* CreateAnonymousForFormattedText( - Document&, - scoped_refptr<const ComputedStyle>, - String); + static LayoutText* CreateAnonymousForFormattedText(Document&, + const ComputedStyle*, + String); const char* GetName() const override { NOT_DESTROYED();
diff --git a/third_party/blink/renderer/core/layout/layout_view.cc b/third_party/blink/renderer/core/layout/layout_view.cc index 9d25cd80..3fa6668 100644 --- a/third_party/blink/renderer/core/layout/layout_view.cc +++ b/third_party/blink/renderer/core/layout/layout_view.cc
@@ -679,7 +679,7 @@ PhysicalSize LayoutView::PageAreaSize(wtf_size_t page_index, const AtomicString& page_name) const { NOT_DESTROYED(); - scoped_refptr<const ComputedStyle> page_style = + const ComputedStyle* page_style = GetDocument().StyleForPage(page_index, page_name); WebPrintPageDescription description = default_page_description_; GetDocument().GetPageDescription(*page_style, &description);
diff --git a/third_party/blink/renderer/core/layout/list_marker.cc b/third_party/blink/renderer/core/layout/list_marker.cc index 0bbe769..451ac6c6 100644 --- a/third_party/blink/renderer/core/layout/list_marker.cc +++ b/third_party/blink/renderer/core/layout/list_marker.cc
@@ -259,7 +259,7 @@ if (!child) { LayoutListMarkerImage* image = LayoutListMarkerImage::CreateAnonymous(&marker.GetDocument()); - scoped_refptr<const ComputedStyle> image_style = + const ComputedStyle* image_style = marker.GetDocument() .GetStyleResolver() .CreateAnonymousStyleWithDisplay(marker.StyleRef(), @@ -284,7 +284,7 @@ // |LayoutObject::PropagateStyleToAnonymousChildren()| to avoid unexpected // full layout due by style difference. See http://crbug.com/980399 const auto& style_parent = child ? *child->Parent() : marker; - scoped_refptr<const ComputedStyle> text_style = + const ComputedStyle* text_style = marker.GetDocument().GetStyleResolver().CreateAnonymousStyleWithDisplay( style_parent.StyleRef(), marker.StyleRef().Display()); if (IsA<LayoutTextFragment>(child))
diff --git a/third_party/blink/renderer/core/layout/ng/flex/ng_flex_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/flex/ng_flex_layout_algorithm.cc index 5a6930a0..2d2b356 100644 --- a/third_party/blink/renderer/core/layout/ng/flex/ng_flex_layout_algorithm.cc +++ b/third_party/blink/renderer/core/layout/ng/flex/ng_flex_layout_algorithm.cc
@@ -2216,7 +2216,7 @@ min_max_content_contributions.depends_on_block_constraints; MinMaxSizes item_final_contribution; - const ComputedStyle& child_style = item.style_; + const ComputedStyle& child_style = *item.style_; const LayoutUnit flex_base_size_border_box = item.flex_base_content_size_ + item.main_axis_border_padding_; const LayoutUnit hypothetical_main_size_border_box =
diff --git a/third_party/blink/renderer/core/layout/ng/grid/ng_grid_line_resolver.h b/third_party/blink/renderer/core/layout/ng/grid/ng_grid_line_resolver.h index 1970a8d..61d89c31 100644 --- a/third_party/blink/renderer/core/layout/ng/grid/ng_grid_line_resolver.h +++ b/third_party/blink/renderer/core/layout/ng/grid/ng_grid_line_resolver.h
@@ -10,6 +10,7 @@ #include "third_party/blink/renderer/core/style/grid_area.h" #include "third_party/blink/renderer/core/style/grid_enums.h" #include "third_party/blink/renderer/core/style/named_grid_lines_map.h" +#include "third_party/blink/renderer/platform/heap/persistent.h" #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" #include "third_party/blink/renderer/platform/wtf/wtf_size_t.h" @@ -130,7 +131,9 @@ bool IsSubgridded(GridTrackSizingDirection track_direction) const; - scoped_refptr<const ComputedStyle> style_; + // This doesn't create a cycle as ComputeStyle doesn't have any references to + // layout-time objects. + Persistent<const ComputedStyle> style_; wtf_size_t column_auto_repetitions_{1}; wtf_size_t row_auto_repetitions_{1};
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.h b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.h index 35339904..e7a99e0 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.h +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.h
@@ -14,6 +14,7 @@ #include "third_party/blink/renderer/platform/fonts/font_height.h" #include "third_party/blink/renderer/platform/geometry/layout_unit.h" #include "third_party/blink/renderer/platform/wtf/vector.h" +#include "third_party/blink/renderer/platform/wtf/vector_traits.h" namespace blink { @@ -41,7 +42,7 @@ public: unsigned fragment_start = 0; const NGInlineItem* item = nullptr; - const ComputedStyle* style = nullptr; + Member<const ComputedStyle> style; // Points to style->GetFont(), or |scaled_font| in an SVG <text>. const Font* font; @@ -95,6 +96,8 @@ NGInlineBoxState(const NGInlineBoxState&) = delete; NGInlineBoxState& operator=(const NGInlineBoxState&) = delete; + void Trace(Visitor* visitor) const { visitor->Trace(style); } + // Reset |style|, |is_svg_text|, |font|, |scaled_font|, |scaling_factor|, and // |alignment_type|. void ResetStyle(const ComputedStyle& style_ref, @@ -311,7 +314,7 @@ // Update edges of inline fragmented boxes. void UpdateFragmentedBoxDataEdges(Vector<BoxData>* fragmented_boxes); - Vector<NGInlineBoxState, 4> stack_; + HeapVector<NGInlineBoxState, 4> stack_; Vector<BoxData, 4> box_data_list_; bool is_empty_line_ = false; @@ -321,4 +324,6 @@ } // namespace blink +WTF_ALLOW_CLEAR_UNUSED_SLOTS_WITH_MEM_FUNCTIONS(blink::NGInlineBoxState) + #endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_INLINE_NG_INLINE_BOX_STATE_H_
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_break_token.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_break_token.cc index 2560892..b281107 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_break_token.cc +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_break_token.cc
@@ -13,7 +13,7 @@ namespace { struct SameSizeAsNGInlineBreakToken : NGBreakToken { - scoped_refptr<const ComputedStyle> style_; + Member<const ComputedStyle> style; unsigned numbers[2]; }; @@ -122,6 +122,7 @@ // in ctor. if (flags_ & kHasSubBreakToken) visitor->Trace(*sub_break_token_); + visitor->Trace(style_); NGBreakToken::TraceAfterDispatch(visitor); }
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_break_token.h b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_break_token.h index 01b6603a..76c484e 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_break_token.h +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_break_token.h
@@ -40,7 +40,7 @@ // The style at the end of this break token. The next line should start with // this style. - const ComputedStyle* Style() const { return style_.get(); } + const ComputedStyle* Style() const { return style_.Get(); } // The point where the next layout should start, or where the previous layout // ended. @@ -95,7 +95,7 @@ private: const Member<const NGBreakToken>* SubBreakTokenAddress() const; - scoped_refptr<const ComputedStyle> style_; + Member<const ComputedStyle> style_; NGInlineItemTextIndex start_; // This is an array of one item if |kHasSubBreakToken|, or zero.
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder.cc index a81fab1..8a0a319b 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder.cc +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder.cc
@@ -195,8 +195,8 @@ : style(*item.Style()), item_index(item_index), should_create_box_fragment(item.ShouldCreateBoxFragment()), - text_metrics(style.GetFontHeight()) { - DCHECK(&style); + text_metrics(style->GetFontHeight()) { + DCHECK(style); } // True if this inline box should create a box fragment when it has |child|. @@ -205,7 +205,7 @@ ShouldCreateBoxFragmentForChild(const BoxInfo& child) const { // When a child inline box has margins, the parent has different width/height // from the union of children. - const ComputedStyle& child_style = child.style; + const ComputedStyle& child_style = *child.style; if (child_style.MayHaveMargin()) return true;
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder.h b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder.h index ed32d5d..b889dee 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder.h +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder.h
@@ -150,7 +150,7 @@ void ClearNeedsLayout(LayoutObject*); void UpdateShouldCreateBoxFragment(LayoutInline*); - // In public to modify VectorTraits<BidiContext> in WTF namespace. + // The following structs are public to modify VectorTraits in WTF namespace. struct BidiContext { DISALLOW_NEW(); @@ -162,6 +162,22 @@ UChar exit; }; + // Keep track of inline boxes to compute ShouldCreateBoxFragment. + struct BoxInfo { + DISALLOW_NEW(); + + Member<const ComputedStyle> style; + unsigned item_index; + bool should_create_box_fragment; + FontHeight text_metrics; + + void Trace(Visitor* visitor) const { visitor->Trace(style); } + + BoxInfo(unsigned item_index, const NGInlineItem& item); + bool ShouldCreateBoxFragmentForChild(const BoxInfo& child) const; + void SetShouldCreateBoxFragment(HeapVector<NGInlineItem>* items); + }; + private: static bool NeedsBoxInfo(); @@ -174,21 +190,7 @@ // white space is collapsed. OffsetMappingBuilder mapping_builder_; - // Keep track of inline boxes to compute ShouldCreateBoxFragment. - struct BoxInfo { - DISALLOW_NEW(); - - const ComputedStyle& style; - unsigned item_index; - bool should_create_box_fragment; - FontHeight text_metrics; - - BoxInfo(unsigned item_index, const NGInlineItem& item); - bool ShouldCreateBoxFragmentForChild(const BoxInfo& child) const; - void SetShouldCreateBoxFragment(HeapVector<NGInlineItem>* items); - }; - Vector<BoxInfo> boxes_; - + HeapVector<BoxInfo> boxes_; HeapVector<BidiContext> bidi_context_; const SvgTextChunkOffsets* text_chunk_offsets_; @@ -298,5 +300,9 @@ blink::NGInlineItemsBuilder::BidiContext) WTF_ALLOW_CLEAR_UNUSED_SLOTS_WITH_MEM_FUNCTIONS( blink::NGInlineItemsBuilderForOffsetMapping::BidiContext) +WTF_ALLOW_CLEAR_UNUSED_SLOTS_WITH_MEM_FUNCTIONS( + blink::NGInlineItemsBuilder::BoxInfo) +WTF_ALLOW_CLEAR_UNUSED_SLOTS_WITH_MEM_FUNCTIONS( + blink::NGInlineItemsBuilderForOffsetMapping::BoxInfo) #endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_INLINE_NG_INLINE_ITEMS_BUILDER_H_
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder_test.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder_test.cc index 881c643..8a3ef11a 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder_test.cc +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder_test.cc
@@ -52,7 +52,7 @@ block_flow_->SetStyle(style_, LayoutObject::ApplyStyleChanges::kNo); } - scoped_refptr<const ComputedStyle> GetStyle(EWhiteSpace whitespace) { + const ComputedStyle* GetStyle(EWhiteSpace whitespace) { if (whitespace == EWhiteSpace::kNormal) return style_; ComputedStyleBuilder builder = @@ -67,7 +67,7 @@ void AppendText(const String& text, NGInlineItemsBuilder* builder) { LayoutText* layout_text = - LayoutText::CreateEmptyAnonymous(GetDocument(), style_.get()); + LayoutText::CreateEmptyAnonymous(GetDocument(), style_); anonymous_objects_->push_back(layout_text); builder->AppendText(text, layout_text); } @@ -190,7 +190,7 @@ Persistent<LayoutBlockFlow> block_flow_; Persistent<HeapVector<NGInlineItem>> items_; String text_; - scoped_refptr<const ComputedStyle> style_; + Persistent<const ComputedStyle> style_; Persistent<HeapVector<Member<LayoutObject>>> anonymous_objects_; }; @@ -423,9 +423,9 @@ TEST_F(NGInlineItemsBuilderTest, Empty) { HeapVector<NGInlineItem> items; NGInlineItemsBuilder builder(GetLayoutBlockFlow(), &items); - scoped_refptr<const ComputedStyle> block_style = + const ComputedStyle* block_style = &GetDocument().GetStyleResolver().InitialStyle(); - builder.EnterBlock(block_style.get()); + builder.EnterBlock(block_style); builder.ExitBlock(); EXPECT_EQ("", builder.ToString()); @@ -470,9 +470,8 @@ GetDocument().GetStyleResolver().InitialStyle()); block_style_builder.SetUnicodeBidi(UnicodeBidi::kBidiOverride); block_style_builder.SetDirection(TextDirection::kRtl); - scoped_refptr<const ComputedStyle> block_style = - block_style_builder.TakeStyle(); - builder.EnterBlock(block_style.get()); + const ComputedStyle* block_style = block_style_builder.TakeStyle(); + builder.EnterBlock(block_style); AppendText("Hello", &builder); builder.ExitBlock();
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.cc index 2e3f2857..cc09be5 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.cc +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.cc
@@ -1689,7 +1689,7 @@ EFloat previous_float_type = EFloat::kNone; for (const auto& floating_object : floating_objects_) { const EClear float_clear = - floating_object.float_style.Clear(floating_object.style); + floating_object.float_style->Clear(*floating_object.style); // If this float clears the previous float we start a new "line". // This is subtly different to block layout which will only reset either @@ -1708,7 +1708,7 @@ floats_inline_size_ += floating_object.float_inline_max_size_with_margin .ClampNegativeToZero(); previous_float_type = - floating_object.float_style.Floating(floating_object.style); + floating_object.float_style->Floating(*floating_object.style); } max_inline_size = std::max(max_inline_size, line_inline_size + floats_inline_size_);
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.h b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.h index 9290d1a..6258644d 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.h +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.h
@@ -136,10 +136,13 @@ struct FloatingObject { DISALLOW_NEW(); - void Trace(Visitor* visitor) const {} + void Trace(Visitor* visitor) const { + visitor->Trace(float_style); + visitor->Trace(style); + } - const ComputedStyle& float_style; - const ComputedStyle& style; + Member<const ComputedStyle> float_style; + Member<const ComputedStyle> style; LayoutUnit float_inline_max_size_with_margin; };
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_line_box_fragment_builder.h b/third_party/blink/renderer/core/layout/ng/inline/ng_line_box_fragment_builder.h index dc47069..4f431ab3 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_line_box_fragment_builder.h +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_line_box_fragment_builder.h
@@ -28,7 +28,7 @@ public: NGLineBoxFragmentBuilder(NGInlineNode node, - scoped_refptr<const ComputedStyle> style, + const ComputedStyle* style, const NGConstraintSpace& space, WritingDirectionMode writing_direction) : NGFragmentBuilder(
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.cc index e1f110a..bd28956 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.cc +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.cc
@@ -3078,7 +3078,7 @@ } continue; } - scoped_refptr<const ComputedStyle> was_current_style = current_style_; + const ComputedStyle* was_current_style = current_style_; SetCurrentStyle(*item.Style()); const NGInlineItemResult item_result_before = *item_result; BreakText(item_result, item, *item.TextShapeResult(), @@ -3424,7 +3424,7 @@ } void NGLineBreaker::SetCurrentStyle(const ComputedStyle& style) { - if (&style == current_style_.get()) { + if (&style == current_style_) { #if EXPENSIVE_DCHECKS_ARE_ON() // Check that cache fields are already setup correctly. DCHECK_EQ(auto_wrap_, ShouldAutoWrap(style)); @@ -3592,7 +3592,7 @@ // in inline in the current fragmentainer (and the block-in-inline part // won't be seen there). sub_break_token = NGInlineBreakToken::Create( - node_, current_style_.get(), current_, flags, sub_break_token); + node_, current_style_, current_, flags, sub_break_token); // Move past the block in inline, since we stopped at it. This is where // regular inline content will resume. @@ -3600,8 +3600,8 @@ MoveToNextOf(items[current_.item_index]); } - return NGInlineBreakToken::Create(node_, current_style_.get(), current_, - flags, sub_break_token); + return NGInlineBreakToken::Create(node_, current_style_, current_, flags, + sub_break_token); } } // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.h b/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.h index 5a3f60b1..6426df4a 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.h +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.h
@@ -355,7 +355,7 @@ NGExclusionSpace* exclusion_space_; const NGInlineBreakToken* break_token_; const NGColumnSpannerPath* column_spanner_path_; - scoped_refptr<const ComputedStyle> current_style_; + const ComputedStyle* current_style_ = nullptr; LazyLineBreakIterator break_iterator_; HarfBuzzShaper shaper_;
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_line_info.h b/third_party/blink/renderer/core/layout/ng/inline/ng_line_info.h index 1809b549..6afe231 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_line_info.h +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_line_info.h
@@ -247,7 +247,7 @@ unsigned* end_offset_out = nullptr) const; const NGInlineItemsData* items_data_ = nullptr; - scoped_refptr<const ComputedStyle> line_style_; + const ComputedStyle* line_style_{nullptr}; NGInlineItemResults results_; NGBfcOffset bfc_offset_;
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_line_truncator.h b/third_party/blink/renderer/core/layout/ng/inline/ng_line_truncator.h index 6a32d94..0cf101ae9 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_line_truncator.h +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_line_truncator.h
@@ -85,7 +85,7 @@ TextDirection direction); void HideChild(NGLogicalLineItem* child); - scoped_refptr<const ComputedStyle> line_style_; + const ComputedStyle* line_style_; LayoutUnit available_width_; TextDirection line_direction_;
diff --git a/third_party/blink/renderer/core/layout/ng/layout_ng_ruby_run.cc b/third_party/blink/renderer/core/layout/ng/layout_ng_ruby_run.cc index 6ddf69c..4523a81e 100644 --- a/third_party/blink/renderer/core/layout/ng/layout_ng_ruby_run.cc +++ b/third_party/blink/renderer/core/layout/ng/layout_ng_ruby_run.cc
@@ -196,12 +196,12 @@ DCHECK(parent_ruby->IsRuby()); LayoutNGRubyRun* rr = MakeGarbageCollected<LayoutNGRubyRun>(); rr->SetDocumentForAnonymous(&parent_ruby->GetDocument()); - scoped_refptr<const ComputedStyle> new_style = + const ComputedStyle* new_style = parent_ruby->GetDocument() .GetStyleResolver() .CreateAnonymousStyleWithDisplay(parent_ruby->StyleRef(), EDisplay::kInlineBlock); - rr->SetStyle(std::move(new_style)); + rr->SetStyle(new_style); return *rr; }
diff --git a/third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.h b/third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.h index ab581eab..7b1d7dc 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.h +++ b/third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.h
@@ -39,16 +39,16 @@ public: NGBoxFragmentBuilder(NGLayoutInputNode node, - scoped_refptr<const ComputedStyle> style, + const ComputedStyle* style, const NGConstraintSpace& space, WritingDirectionMode writing_direction) - : NGFragmentBuilder(node, std::move(style), space, writing_direction), + : NGFragmentBuilder(node, style, space, writing_direction), is_inline_formatting_context_(node.IsInline()) {} // Build a fragment for LayoutObject without NGLayoutInputNode. LayoutInline // has NGInlineItem but does not have corresponding NGLayoutInputNode. NGBoxFragmentBuilder(LayoutObject* layout_object, - scoped_refptr<const ComputedStyle> style, + const ComputedStyle* style, const NGConstraintSpace& space, WritingDirectionMode writing_direction) : NGFragmentBuilder(/* node */ nullptr, @@ -723,7 +723,7 @@ // Table specific types. absl::optional<LogicalRect> table_grid_rect_; NGTableFragmentData::ColumnGeometries table_column_geometries_; - scoped_refptr<const NGTableBorders> table_collapsed_borders_; + const NGTableBorders* table_collapsed_borders_ = nullptr; std::unique_ptr<NGTableFragmentData::CollapsedBordersGeometry> table_collapsed_borders_geometry_; absl::optional<wtf_size_t> table_column_count_;
diff --git a/third_party/blink/renderer/core/layout/ng/ng_fragment_builder.h b/third_party/blink/renderer/core/layout/ng/ng_fragment_builder.h index 423ea65..ee6305f 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_fragment_builder.h +++ b/third_party/blink/renderer/core/layout/ng/ng_fragment_builder.h
@@ -458,12 +458,12 @@ protected: NGFragmentBuilder(const NGLayoutInputNode& node, - scoped_refptr<const ComputedStyle> style, + const ComputedStyle* style, const NGConstraintSpace& space, WritingDirectionMode writing_direction) : node_(node), space_(space), - style_(std::move(style)), + style_(style), writing_direction_(writing_direction), style_variant_(NGStyleVariant::kStandard) { DCHECK(style_); @@ -504,7 +504,7 @@ NGLayoutInputNode node_; const NGConstraintSpace& space_; - scoped_refptr<const ComputedStyle> style_; + const ComputedStyle* style_; WritingDirectionMode writing_direction_; NGStyleVariant style_variant_; NGPhysicalFragment::NGBoxType box_type_ =
diff --git a/third_party/blink/renderer/core/layout/ng/ng_ink_overflow.cc b/third_party/blink/renderer/core/layout/ng/ng_ink_overflow.cc index d820814..00f3a63 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_ink_overflow.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_ink_overflow.cc
@@ -666,7 +666,7 @@ const LogicalRect& ink_overflow, const NGInlinePaintContext* inline_context) { LogicalRect accumulated_bound; - auto pseudo_style = + auto* pseudo_style = fragment_item->Type() == NGFragmentItem::kSvgText ? nullptr : HighlightStyleUtils::HighlightPseudoStyle( @@ -726,11 +726,11 @@ const CustomHighlightMarker& highlight_marker = To<CustomHighlightMarker>(*marker); - auto pseudo_style = fragment_item->Type() == NGFragmentItem::kSvgText - ? nullptr - : HighlightStyleUtils::HighlightPseudoStyle( - text_node, style, kPseudoIdHighlight, - highlight_marker.GetHighlightName()); + const auto* pseudo_style = fragment_item->Type() == NGFragmentItem::kSvgText + ? nullptr + : HighlightStyleUtils::HighlightPseudoStyle( + text_node, style, kPseudoIdHighlight, + highlight_marker.GetHighlightName()); LogicalRect decoration_bound; if (pseudo_style && pseudo_style->HasAppliedTextDecorations()) {
diff --git a/third_party/blink/renderer/core/layout/ng/ng_layout_algorithm.h b/third_party/blink/renderer/core/layout/ng/ng_layout_algorithm.h index eac9de7..658af80 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_layout_algorithm.h +++ b/third_party/blink/renderer/core/layout/ng/ng_layout_algorithm.h
@@ -73,7 +73,7 @@ STACK_ALLOCATED(); public: NGLayoutAlgorithm(NGInputNodeType node, - scoped_refptr<const ComputedStyle> style, + const ComputedStyle* style, const NGConstraintSpace& space, TextDirection direction, const NGBreakTokenType* break_token)
diff --git a/third_party/blink/renderer/core/layout/ng/ng_length_utils_test.cc b/third_party/blink/renderer/core/layout/ng/ng_length_utils_test.cc index a3fba88..bb69f1b1 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_length_utils_test.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_length_utils_test.cc
@@ -4,7 +4,6 @@ #include "third_party/blink/renderer/core/layout/ng/ng_length_utils.h" -#include "base/memory/scoped_refptr.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/renderer/core/css/resolver/style_resolver.h" #include "third_party/blink/renderer/core/layout/ng/ng_block_node.h" @@ -88,7 +87,7 @@ length, content_size); } - scoped_refptr<const ComputedStyle> initial_style_; + Persistent<const ComputedStyle> initial_style_; }; class NGLengthUtilsTestWithNode : public RenderingTest { @@ -477,7 +476,7 @@ builder.SetMarginRight(Length::Fixed(52)); builder.SetMarginBottom(Length::Auto()); builder.SetMarginLeft(Length::Percent(11)); - scoped_refptr<const ComputedStyle> style = builder.TakeStyle(); + const ComputedStyle* style = builder.TakeStyle(); NGConstraintSpace constraint_space = ConstructConstraintSpace(200, 300); @@ -500,7 +499,7 @@ builder.SetBorderBottomStyle(EBorderStyle::kSolid); builder.SetBorderLeftStyle(EBorderStyle::kSolid); builder.SetWritingMode(WritingMode::kVerticalLr); - scoped_refptr<const ComputedStyle> style = builder.TakeStyle(); + const ComputedStyle* style = builder.TakeStyle(); NGBoxStrut borders = ComputeBordersForTest(*style); @@ -517,7 +516,7 @@ builder.SetPaddingBottom(Length::Auto()); builder.SetPaddingLeft(Length::Percent(11)); builder.SetWritingMode(WritingMode::kVerticalRl); - scoped_refptr<const ComputedStyle> style = builder.TakeStyle(); + const ComputedStyle* style = builder.TakeStyle(); NGConstraintSpace constraint_space = ConstructConstraintSpace( 200, 300, false, false, WritingMode::kVerticalRl); @@ -534,7 +533,7 @@ ComputedStyleBuilder builder(*initial_style_); builder.SetMarginRight(Length::Auto()); builder.SetMarginLeft(Length::Auto()); - scoped_refptr<const ComputedStyle> style = builder.TakeStyle(); + const ComputedStyle* style = builder.TakeStyle(); LayoutUnit kInlineSize(150); LayoutUnit kAvailableInlineSize(200);
diff --git a/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.cc b/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.cc index 9306d839..daf4dfc0 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.cc
@@ -123,7 +123,7 @@ return true; } -scoped_refptr<const ComputedStyle> CreateFlippedAutoAnchorStyle( +const ComputedStyle* CreateFlippedAutoAnchorStyle( const ComputedStyle& base_style, bool flip_block, bool flip_inline) { @@ -264,7 +264,7 @@ } void ClearAutoAnchorFallbackData() { - auto_anchor_style_.reset(); + auto_anchor_style_ = nullptr; auto_anchor_flippable_in_block_ = false; auto_anchor_flippable_in_inline_ = false; auto_anchor_flip_block_ = false; @@ -284,7 +284,7 @@ // Created when the current style is generated by auto anchor positioning // and has any axis flipped compared to the base style. // https://drafts.csswg.org/css-anchor-position-1/#automatic-anchor-fallbacks - scoped_refptr<const ComputedStyle> auto_anchor_style_; + const ComputedStyle* auto_anchor_style_ = nullptr; bool auto_anchor_flippable_in_block_ = false; bool auto_anchor_flippable_in_inline_ = false;
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 75027e4..499360c 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
@@ -172,10 +172,7 @@ } const NGTableBorders* TableCollapsedBorders() const { - if (const auto* field = GetRareField(FieldId::kTableCollapsedBorders)) { - return field->table_collapsed_borders.get(); - } - return nullptr; + return rare_data_ ? rare_data_->table_collapsed_borders_ : nullptr; } const NGTableFragmentData::CollapsedBordersGeometry*
diff --git a/third_party/blink/renderer/core/layout/ng/ng_relative_utils_test.cc b/third_party/blink/renderer/core/layout/ng/ng_relative_utils_test.cc index 47bcf89..7297e58 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_relative_utils_test.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_relative_utils_test.cc
@@ -25,10 +25,10 @@ initial_style_ = ComputedStyle::CreateInitialStyleSingleton(); } - scoped_refptr<const ComputedStyle> CreateStyle(LayoutUnit top, - LayoutUnit right, - LayoutUnit bottom, - LayoutUnit left) { + const ComputedStyle* CreateStyle(LayoutUnit top, + LayoutUnit right, + LayoutUnit bottom, + LayoutUnit left) { ComputedStyleBuilder builder(*initial_style_); builder.SetPosition(EPosition::kRelative); builder.SetTop(top == kAuto ? Length::Auto() : Length::Fixed(top.ToInt())); @@ -41,7 +41,7 @@ return builder.TakeStyle(); } - scoped_refptr<const ComputedStyle> initial_style_; + Persistent<const ComputedStyle> initial_style_; LogicalSize container_size_; }; @@ -49,8 +49,7 @@ LogicalOffset offset; // Everything auto defaults to kZero,kZero - scoped_refptr<const ComputedStyle> style = - CreateStyle(kAuto, kAuto, kAuto, kAuto); + const ComputedStyle* style = CreateStyle(kAuto, kAuto, kAuto, kAuto); offset = ComputeRelativeOffset( *style, {WritingMode::kHorizontalTb, TextDirection::kLtr}, container_size_); @@ -87,8 +86,7 @@ LogicalOffset offset; // Set all sides - scoped_refptr<const ComputedStyle> style = - CreateStyle(kTop, kRight, kBottom, kLeft); + const ComputedStyle* style = CreateStyle(kTop, kRight, kBottom, kLeft); // kLtr offset = ComputeRelativeOffset( @@ -114,8 +112,7 @@ LogicalOffset offset; // Set all sides - scoped_refptr<const ComputedStyle> style = - CreateStyle(kTop, kRight, kBottom, kLeft); + const ComputedStyle* style = CreateStyle(kTop, kRight, kBottom, kLeft); // kLtr offset = ComputeRelativeOffset(
diff --git a/third_party/blink/renderer/core/layout/ng/physical_fragment_rare_data.cc b/third_party/blink/renderer/core/layout/ng/physical_fragment_rare_data.cc index 1dd7e3ee..af7ab92 100644 --- a/third_party/blink/renderer/core/layout/ng/physical_fragment_rare_data.cc +++ b/third_party/blink/renderer/core/layout/ng/physical_fragment_rare_data.cc
@@ -50,10 +50,6 @@ SetField(FieldId::kTableGridRect).table_grid_rect = *builder.table_grid_rect_; } - if (builder.table_collapsed_borders_) { - SetField(FieldId::kTableCollapsedBorders).table_collapsed_borders = - std::move(builder.table_collapsed_borders_); - } if (builder.table_collapsed_borders_geometry_) { SetField(FieldId::kTableCollapsedBordersGeometry) .table_collapsed_borders_geometry = @@ -73,6 +69,7 @@ SetField(FieldId::kPageName).page_name = builder.page_name_; } + table_collapsed_borders_ = builder.table_collapsed_borders_; if (!builder.table_column_geometries_.empty()) { table_column_geometries_ = MakeGarbageCollected<NGTableFragmentData::ColumnGeometries>( @@ -96,7 +93,8 @@ PhysicalFragmentRareData::PhysicalFragmentRareData( const PhysicalFragmentRareData& other) - : table_column_geometries_(other.table_column_geometries_) { + : table_collapsed_borders_(other.table_collapsed_borders_), + table_column_geometries_(other.table_column_geometries_) { field_list_.ReserveInitialCapacity(other.field_list_.capacity()); // Each field should be processed in order of FieldId to avoid vector @@ -109,7 +107,6 @@ CLONE_IF_EXISTS(kFrameSetLayoutData, frame_set_layout_data, other); CLONE_IF_EXISTS(kMathMLPaintInfo, mathml_paint_info, other); SET_IF_EXISTS(kTableGridRect, table_grid_rect, other); - SET_IF_EXISTS(kTableCollapsedBorders, table_collapsed_borders, other); CLONE_IF_EXISTS(kTableCollapsedBordersGeometry, table_collapsed_borders_geometry, other); SET_IF_EXISTS(kTableCellColumnIndex, table_cell_column_index, other); @@ -138,7 +135,6 @@ FUNC(kFrameSetLayoutData, frame_set_layout_data); \ FUNC(kMathMLPaintInfo, mathml_paint_info); \ FUNC(kTableGridRect, table_grid_rect); \ - FUNC(kTableCollapsedBorders, table_collapsed_borders); \ FUNC(kTableCollapsedBordersGeometry, table_collapsed_borders_geometry); \ FUNC(kTableCellColumnIndex, table_cell_column_index); \ FUNC(kTableSectionStartRowIndex, table_section_start_row_index); \
diff --git a/third_party/blink/renderer/core/layout/ng/physical_fragment_rare_data.h b/third_party/blink/renderer/core/layout/ng/physical_fragment_rare_data.h index ac97d24..30aba53d 100644 --- a/third_party/blink/renderer/core/layout/ng/physical_fragment_rare_data.h +++ b/third_party/blink/renderer/core/layout/ng/physical_fragment_rare_data.h
@@ -45,6 +45,7 @@ ~PhysicalFragmentRareData(); void Trace(Visitor* visitor) const { + visitor->Trace(table_collapsed_borders_); visitor->Trace(table_column_geometries_); } @@ -63,7 +64,6 @@ kFrameSetLayoutData, kMathMLPaintInfo, kTableGridRect, - kTableCollapsedBorders, kTableCollapsedBordersGeometry, kTableCellColumnIndex, kTableSectionStartRowIndex, @@ -157,7 +157,8 @@ RareBitFieldType bit_field_; // A garbage-collected field is not stored in the Vector in order to avoid // troublesome conditional tracing. - Member<NGTableFragmentData::ColumnGeometries> table_column_geometries_; + Member<const NGTableBorders> table_collapsed_borders_; + Member<const NGTableFragmentData::ColumnGeometries> table_column_geometries_; }; } // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table.cc b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table.cc index b1a0a05..3235559 100644 --- a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table.cc +++ b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table.cc
@@ -42,15 +42,20 @@ LayoutNGTable::~LayoutNGTable() = default; +void LayoutNGTable::Trace(Visitor* visitor) const { + visitor->Trace(cached_table_borders_); + LayoutNGBlock::Trace(visitor); +} + LayoutNGTable* LayoutNGTable::CreateAnonymousWithParent( const LayoutObject& parent) { - scoped_refptr<const ComputedStyle> new_style = + const ComputedStyle* new_style = parent.GetDocument().GetStyleResolver().CreateAnonymousStyleWithDisplay( parent.StyleRef(), parent.IsLayoutInline() ? EDisplay::kInlineTable : EDisplay::kTable); auto* new_table = MakeGarbageCollected<LayoutNGTable>(nullptr); new_table->SetDocumentForAnonymous(&parent.GetDocument()); - new_table->SetStyle(std::move(new_style)); + new_table->SetStyle(new_style); return new_table; } @@ -189,10 +194,9 @@ return cached_table_borders_ && cached_table_borders_->IsCollapsed(); } -void LayoutNGTable::SetCachedTableBorders( - scoped_refptr<const NGTableBorders> table_borders) { +void LayoutNGTable::SetCachedTableBorders(const NGTableBorders* table_borders) { NOT_DESTROYED(); - cached_table_borders_ = std::move(table_borders); + cached_table_borders_ = table_borders; } void LayoutNGTable::InvalidateCachedTableBorders() { @@ -200,7 +204,7 @@ // TODO(layout-dev) When cached borders are invalidated, we could do a // special kind of relayout where fragments can replace only TableBorders, // keep the geometry, and repaint. - cached_table_borders_.reset(); + cached_table_borders_ = nullptr; } const NGTableTypes::Columns* LayoutNGTable::GetCachedTableColumnConstraints() { @@ -393,7 +397,7 @@ NOT_DESTROYED(); // DCHECK(cached_table_borders_.get()) // ScrollAnchoring fails this DCHECK. - if (ShouldCollapseBorders() && cached_table_borders_.get()) { + if (ShouldCollapseBorders() && cached_table_borders_) { return cached_table_borders_->TableBorder() .ConvertToPhysical(Style()->GetWritingDirection()) .left; @@ -405,7 +409,7 @@ NOT_DESTROYED(); // DCHECK(cached_table_borders_.get()) // ScrollAnchoring fails this DCHECK. - if (ShouldCollapseBorders() && cached_table_borders_.get()) { + if (ShouldCollapseBorders() && cached_table_borders_) { return cached_table_borders_->TableBorder() .ConvertToPhysical(Style()->GetWritingDirection()) .right; @@ -417,7 +421,7 @@ NOT_DESTROYED(); // DCHECK(cached_table_borders_.get()) // ScrollAnchoring fails this DCHECK. - if (ShouldCollapseBorders() && cached_table_borders_.get()) { + if (ShouldCollapseBorders() && cached_table_borders_) { return cached_table_borders_->TableBorder() .ConvertToPhysical(Style()->GetWritingDirection()) .top; @@ -429,7 +433,7 @@ NOT_DESTROYED(); // DCHECK(cached_table_borders_.get()) // ScrollAnchoring fails this DCHECK. - if (ShouldCollapseBorders() && cached_table_borders_.get()) { + if (ShouldCollapseBorders() && cached_table_borders_) { return cached_table_borders_->TableBorder() .ConvertToPhysical(Style()->GetWritingDirection()) .bottom;
diff --git a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table.h b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table.h index a4222cbd..9a9f9c3d 100644 --- a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table.h +++ b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table.h
@@ -101,6 +101,8 @@ explicit LayoutNGTable(Element*); ~LayoutNGTable() override; + void Trace(Visitor*) const override; + static LayoutNGTable* CreateAnonymousWithParent(const LayoutObject&); bool IsFirstCell(const LayoutNGTableCell&) const; @@ -118,10 +120,10 @@ const NGTableBorders* GetCachedTableBorders() const { NOT_DESTROYED(); - return cached_table_borders_.get(); + return cached_table_borders_.Get(); } - void SetCachedTableBorders(scoped_refptr<const NGTableBorders>); + void SetCachedTableBorders(const NGTableBorders*); const NGTableTypes::Columns* GetCachedTableColumnConstraints(); @@ -225,7 +227,7 @@ void InvalidateCachedTableBorders(); // Table borders are cached because computing collapsed borders is expensive. - scoped_refptr<const NGTableBorders> cached_table_borders_; + Member<const NGTableBorders> cached_table_borders_; // Table columns do not depend on any outside data (e.g. NGConstraintSpace). // They are cached because computing them is expensive.
diff --git a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_cell.cc b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_cell.cc index 264778c9..2707f5c 100644 --- a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_cell.cc +++ b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_cell.cc
@@ -27,12 +27,12 @@ LayoutNGTableCell* LayoutNGTableCell::CreateAnonymousWithParent( const LayoutObject& parent) { - scoped_refptr<const ComputedStyle> new_style = + const ComputedStyle* new_style = parent.GetDocument().GetStyleResolver().CreateAnonymousStyleWithDisplay( parent.StyleRef(), EDisplay::kTableCell); auto* new_cell = MakeGarbageCollected<LayoutNGTableCell>(nullptr); new_cell->SetDocumentForAnonymous(&parent.GetDocument()); - new_cell->SetStyle(std::move(new_style)); + new_cell->SetStyle(new_style); return new_cell; }
diff --git a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_row.cc b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_row.cc index bbc86dae..92e380e 100644 --- a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_row.cc +++ b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_row.cc
@@ -18,12 +18,12 @@ LayoutNGTableRow* LayoutNGTableRow::CreateAnonymousWithParent( const LayoutObject& parent) { - scoped_refptr<const ComputedStyle> new_style = + const ComputedStyle* new_style = parent.GetDocument().GetStyleResolver().CreateAnonymousStyleWithDisplay( parent.StyleRef(), EDisplay::kTableRow); auto* new_row = MakeGarbageCollected<LayoutNGTableRow>(nullptr); new_row->SetDocumentForAnonymous(&parent.GetDocument()); - new_row->SetStyle(std::move(new_style)); + new_row->SetStyle(new_style); return new_row; }
diff --git a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_section.cc b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_section.cc index 82c01af0..124d3be 100644 --- a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_section.cc +++ b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_section.cc
@@ -16,12 +16,12 @@ LayoutNGTableSection* LayoutNGTableSection::CreateAnonymousWithParent( const LayoutObject& parent) { - scoped_refptr<const ComputedStyle> new_style = + const ComputedStyle* new_style = parent.GetDocument().GetStyleResolver().CreateAnonymousStyleWithDisplay( parent.StyleRef(), EDisplay::kTableRowGroup); auto* new_section = MakeGarbageCollected<LayoutNGTableSection>(nullptr); new_section->SetDocumentForAnonymous(&parent.GetDocument()); - new_section->SetStyle(std::move(new_style)); + new_section->SetStyle(new_style); return new_section; }
diff --git a/third_party/blink/renderer/core/layout/ng/table/ng_table_borders.cc b/third_party/blink/renderer/core/layout/ng/table/ng_table_borders.cc index b5edd253..7814b589 100644 --- a/third_party/blink/renderer/core/layout/ng/table/ng_table_borders.cc +++ b/third_party/blink/renderer/core/layout/ng/table/ng_table_borders.cc
@@ -32,12 +32,12 @@ return true; EBorderStyle edge_border_style = - NGTableBorders::BorderStyle(edge.style.get(), edge.edge_side); + NGTableBorders::BorderStyle(edge.style.Get(), edge.edge_side); if (edge_border_style == EBorderStyle::kHidden) return false; LayoutUnit edge_width = - NGTableBorders::BorderWidth(edge.style.get(), edge.edge_side); + NGTableBorders::BorderWidth(edge.style.Get(), edge.edge_side); if (source_width < edge_width) return false; if (source_width > edge_width) @@ -112,14 +112,13 @@ } // namespace -scoped_refptr<NGTableBorders> NGTableBorders::ComputeTableBorders( +const NGTableBorders* NGTableBorders::ComputeTableBorders( const NGBlockNode& table) { const ComputedStyle& table_style = table.Style(); const bool is_collapsed = table_style.BorderCollapse() == EBorderCollapse::kCollapse; - scoped_refptr<NGTableBorders> table_borders = - base::MakeRefCounted<NGTableBorders>( - ComputeNonCollapsedTableBorders(table_style), is_collapsed); + NGTableBorders* table_borders = MakeGarbageCollected<NGTableBorders>( + ComputeNonCollapsedTableBorders(table_style), is_collapsed); if (!is_collapsed) return table_borders; @@ -230,14 +229,12 @@ // COL borders have precedence over COLGROUP borders. // We have to traverse COL first, then COLGROUP. ColBordersMarker col_borders_marker(table_row_count, ++box_order, - table_writing_direction, - *table_borders.get()); + table_writing_direction, *table_borders); VisitLayoutNGTableColumn( const_cast<HeapVector<NGBlockNode>&>(grouped_children.columns), table_column_count, &col_borders_marker); - ColgroupBordersMarker colgroup_borders_marker(table_row_count, ++box_order, - table_writing_direction, - *table_borders.get()); + ColgroupBordersMarker colgroup_borders_marker( + table_row_count, ++box_order, table_writing_direction, *table_borders); VisitLayoutNGTableColumn( const_cast<HeapVector<NGBlockNode>&>(grouped_children.columns), table_column_count, &colgroup_borders_marker);
diff --git a/third_party/blink/renderer/core/layout/ng/table/ng_table_borders.h b/third_party/blink/renderer/core/layout/ng/table/ng_table_borders.h index 290e60d5..ba9259ba 100644 --- a/third_party/blink/renderer/core/layout/ng/table/ng_table_borders.h +++ b/third_party/blink/renderer/core/layout/ng/table/ng_table_borders.h
@@ -59,12 +59,14 @@ // | | | | // |9 |11 |13 |15 -class NGTableBorders : public RefCounted<NGTableBorders> { +class NGTableBorders : public GarbageCollected<NGTableBorders> { public: - static scoped_refptr<NGTableBorders> ComputeTableBorders(const NGBlockNode&); + static const NGTableBorders* ComputeTableBorders(const NGBlockNode&); NGTableBorders(const NGBoxStrut& table_border, const bool is_collapsed); + void Trace(Visitor* visitor) const { visitor->Trace(edges_); } + #if DCHECK_IS_ON() String DumpEdges(); void ShowEdges(); @@ -81,13 +83,15 @@ // style border defines the edge. struct Edge { DISALLOW_NEW(); - scoped_refptr<const ComputedStyle> style; + Member<const ComputedStyle> style; EdgeSide edge_side; // Box order is used to compute edge painting precedence. // Lower box order has precedence. - // The order value is defined as "box visited index" while - // computing collapsed edges. + // The order value is defined as "box visited index" while computing + // collapsed edges. wtf_size_t box_order; + + void Trace(Visitor* visitor) const { visitor->Trace(style); } }; static LayoutUnit BorderWidth(const ComputedStyle* style, @@ -152,17 +156,17 @@ } LayoutUnit BorderWidth(wtf_size_t edge_index) const { - return BorderWidth(edges_[edge_index].style.get(), + return BorderWidth(edges_[edge_index].style.Get(), edges_[edge_index].edge_side); } EBorderStyle BorderStyle(wtf_size_t edge_index) const { - return BorderStyle(edges_[edge_index].style.get(), + return BorderStyle(edges_[edge_index].style.Get(), edges_[edge_index].edge_side); } Color BorderColor(wtf_size_t edge_index) const { - return BorderColor(edges_[edge_index].style.get(), + return BorderColor(edges_[edge_index].style.Get(), edges_[edge_index].edge_side); } @@ -170,7 +174,7 @@ return edges_[edge_index].box_order; } - using Edges = Vector<Edge>; + using Edges = HeapVector<Edge>; struct Section { wtf_size_t start_row;
diff --git a/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm.cc index be81175..4f1f1d7 100644 --- a/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm.cc +++ b/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm.cc
@@ -533,7 +533,7 @@ const LogicalSize border_spacing = table.Style().TableBorderSpacing(); NGTableGroupedChildren grouped_children(table); - scoped_refptr<const NGTableBorders> table_borders = table.GetTableBorders(); + const NGTableBorders* table_borders = table.GetTableBorders(); // Compute min/max inline constraints. const scoped_refptr<const NGTableTypes::Columns> column_constraints = @@ -585,9 +585,8 @@ const bool is_fixed_layout = Style().IsFixedTableLayout(); const LogicalSize border_spacing = Style().TableBorderSpacing(); NGTableGroupedChildren grouped_children(Node()); - const scoped_refptr<const NGTableBorders> table_borders = - Node().GetTableBorders(); - DCHECK(table_borders.get()); + const NGTableBorders* table_borders = Node().GetTableBorders(); + DCHECK(table_borders); const NGBoxStrut border_padding = container_builder_.BorderPadding(); // Algorithm: @@ -715,10 +714,8 @@ text_autosizer.emplace(To<LayoutNGTable>(Node().GetLayoutBox())); const LogicalSize border_spacing = Style().TableBorderSpacing(); - NGTableGroupedChildren grouped_children(Node()); - const scoped_refptr<const NGTableBorders> table_borders = - Node().GetTableBorders(); const NGBoxStrut border_padding = container_builder_.BorderPadding(); + NGTableGroupedChildren grouped_children(Node()); const scoped_refptr<const NGTableTypes::Columns> column_constraints = Node().GetColumnConstraints(grouped_children, border_padding);
diff --git a/third_party/blink/renderer/core/layout/ng/table/ng_table_node.cc b/third_party/blink/renderer/core/layout/ng/table/ng_table_node.cc index 80af97d..3b957bc2 100644 --- a/third_party/blink/renderer/core/layout/ng/table/ng_table_node.cc +++ b/third_party/blink/renderer/core/layout/ng/table/ng_table_node.cc
@@ -10,17 +10,16 @@ namespace blink { -scoped_refptr<const NGTableBorders> NGTableNode::GetTableBorders() const { +const NGTableBorders* NGTableNode::GetTableBorders() const { LayoutNGTable* layout_table = To<LayoutNGTable>(box_.Get()); - scoped_refptr<const NGTableBorders> table_borders = - layout_table->GetCachedTableBorders(); + const NGTableBorders* table_borders = layout_table->GetCachedTableBorders(); if (!table_borders) { table_borders = NGTableBorders::ComputeTableBorders(*this); - layout_table->SetCachedTableBorders(table_borders.get()); + layout_table->SetCachedTableBorders(table_borders); } else { #if DCHECK_IS_ON() // TODO(crbug.com/1191742) remove these DCHECKs as soon as bug is found. - auto duplicate_table_borders = NGTableBorders::ComputeTableBorders(*this); + auto* duplicate_table_borders = NGTableBorders::ComputeTableBorders(*this); DCHECK(*duplicate_table_borders == *table_borders); #endif } @@ -39,7 +38,7 @@ layout_table->GetCachedTableColumnConstraints(); if (!column_constraints) { column_constraints = NGTableAlgorithmUtils::ComputeColumnConstraints( - *this, grouped_children, *GetTableBorders().get(), border_padding); + *this, grouped_children, *GetTableBorders(), border_padding); layout_table->SetCachedTableColumnConstraints(column_constraints.get()); } return column_constraints;
diff --git a/third_party/blink/renderer/core/layout/ng/table/ng_table_node.h b/third_party/blink/renderer/core/layout/ng/table/ng_table_node.h index 70edb7ca..8b3d08c 100644 --- a/third_party/blink/renderer/core/layout/ng/table/ng_table_node.h +++ b/third_party/blink/renderer/core/layout/ng/table/ng_table_node.h
@@ -20,7 +20,7 @@ const NGBoxStrut& GetTableBordersStrut() const; - scoped_refptr<const NGTableBorders> GetTableBorders() const; + const NGTableBorders* GetTableBorders() const; LayoutUnit ComputeCaptionBlockSize(const NGConstraintSpace& space) const;
diff --git a/third_party/blink/renderer/core/layout/overflow_model.h b/third_party/blink/renderer/core/layout/overflow_model.h index 7962eb07..c2f3f7f 100644 --- a/third_party/blink/renderer/core/layout/overflow_model.h +++ b/third_party/blink/renderer/core/layout/overflow_model.h
@@ -25,6 +25,7 @@ #include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/blink/renderer/core/layout/geometry/physical_rect.h" #include "third_party/blink/renderer/platform/geometry/layout_rect.h" +#include "third_party/blink/renderer/platform/heap/garbage_collected.h" namespace blink { @@ -168,7 +169,7 @@ bool has_subpixel_visual_effect_outsets_ = false; }; -struct BoxOverflowModel { +struct BoxOverflowModel : public GarbageCollected<BoxOverflowModel> { absl::optional<BoxLayoutOverflowModel> layout_overflow; absl::optional<BoxVisualOverflowModel> visual_overflow; @@ -181,7 +182,7 @@ }; absl::optional<PreviousOverflowData> previous_overflow_data; - USING_FAST_MALLOC(BoxOverflowModel); + void Trace(Visitor*) const {} }; } // namespace blink
diff --git a/third_party/blink/renderer/core/layout/style_retain_scope.cc b/third_party/blink/renderer/core/layout/style_retain_scope.cc deleted file mode 100644 index 6ec3cf6e..0000000 --- a/third_party/blink/renderer/core/layout/style_retain_scope.cc +++ /dev/null
@@ -1,28 +0,0 @@ -// Copyright 2019 The Chromium Authors -// 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/layout/style_retain_scope.h" - -#include "third_party/abseil-cpp/absl/base/attributes.h" -#include "third_party/blink/renderer/core/style/computed_style.h" - -namespace blink { - -namespace { - -ABSL_CONST_INIT thread_local StyleRetainScope* current = nullptr; - -} // namespace - -StyleRetainScope::StyleRetainScope() : resetter_(¤t, this) {} - -StyleRetainScope::~StyleRetainScope() { - DCHECK_EQ(current, this); -} - -StyleRetainScope* StyleRetainScope::Current() { - return current; -} - -} // namespace blink
diff --git a/third_party/blink/renderer/core/layout/style_retain_scope.h b/third_party/blink/renderer/core/layout/style_retain_scope.h deleted file mode 100644 index e09cf3f..0000000 --- a/third_party/blink/renderer/core/layout/style_retain_scope.h +++ /dev/null
@@ -1,39 +0,0 @@ -// Copyright 2019 The Chromium Authors -// 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_LAYOUT_STYLE_RETAIN_SCOPE_H_ -#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_STYLE_RETAIN_SCOPE_H_ - -#include "base/auto_reset.h" -#include "third_party/blink/renderer/core/core_export.h" -#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" -#include "third_party/blink/renderer/platform/wtf/vector.h" - -namespace blink { - -class ComputedStyle; - -// This class retains references to temporary styles during layout. -class CORE_EXPORT StyleRetainScope { - STACK_ALLOCATED(); - - public: - StyleRetainScope(); - ~StyleRetainScope(); - - static StyleRetainScope* Current(); - - // Retain a reference to |style| for the lifetime of |this|. - void Retain(const ComputedStyle& style) { - styles_retained_during_layout_.push_back(&style); - } - - private: - Vector<scoped_refptr<const ComputedStyle>> styles_retained_during_layout_; - const base::AutoReset<StyleRetainScope*> resetter_; -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_STYLE_RETAIN_SCOPE_H_
diff --git a/third_party/blink/renderer/core/layout/style_retain_scope_test.cc b/third_party/blink/renderer/core/layout/style_retain_scope_test.cc deleted file mode 100644 index 84d7b96..0000000 --- a/third_party/blink/renderer/core/layout/style_retain_scope_test.cc +++ /dev/null
@@ -1,41 +0,0 @@ -// Copyright 2019 The Chromium Authors -// 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/layout/style_retain_scope.h" - -#include "testing/gtest/include/gtest/gtest.h" -#include "third_party/blink/renderer/core/style/computed_style.h" -#include "third_party/blink/renderer/platform/wtf/thread_specific.h" - -namespace blink { - -TEST(StyleRetainScopeTest, Current) { - EXPECT_EQ(StyleRetainScope::Current(), nullptr); - { - StyleRetainScope scope; - EXPECT_EQ(StyleRetainScope::Current(), &scope); - { - StyleRetainScope scope2; - EXPECT_EQ(StyleRetainScope::Current(), &scope2); - } - EXPECT_EQ(StyleRetainScope::Current(), &scope); - } - EXPECT_EQ(StyleRetainScope::Current(), nullptr); -} - -TEST(StyleRetainScopeTest, Retain) { - scoped_refptr<const ComputedStyle> style = - ComputedStyle::CreateInitialStyleSingleton(); - EXPECT_TRUE(style->HasOneRef()); - { - StyleRetainScope scope; - scope.Retain(*style); - - EXPECT_FALSE(style->HasOneRef()); - EXPECT_TRUE(style->HasAtLeastOneRef()); - } - EXPECT_TRUE(style->HasOneRef()); -} - -} // namespace blink
diff --git a/third_party/blink/renderer/core/layout/text_autosizer.cc b/third_party/blink/renderer/core/layout/text_autosizer.cc index 9567e3e..d2240e58 100644 --- a/third_party/blink/renderer/core/layout/text_autosizer.cc +++ b/third_party/blink/renderer/core/layout/text_autosizer.cc
@@ -54,7 +54,6 @@ #include "third_party/blink/renderer/core/layout/ng/table/layout_ng_table_cell.h" #include "third_party/blink/renderer/core/layout/ng/table/layout_ng_table_row.h" #include "third_party/blink/renderer/core/layout/ng/table/layout_ng_table_section.h" -#include "third_party/blink/renderer/core/layout/style_retain_scope.h" #include "third_party/blink/renderer/core/page/chrome_client.h" #include "third_party/blink/renderer/core/page/page.h" #include "third_party/blink/renderer/platform/network/network_utils.h" @@ -1224,7 +1223,7 @@ ComputedStyleBuilder builder(current_style); builder.SetTextAutosizingMultiplier(multiplier); - scoped_refptr<const ComputedStyle> style = builder.TakeStyle(); + const ComputedStyle* style = builder.TakeStyle(); if (multiplier > 1 && !did_check_cross_site_use_count_) { ReportIfCrossSiteFrame(); @@ -1233,16 +1232,8 @@ switch (relayout_behavior) { case kAlreadyInLayout: - // Don't free current_style until the end of the layout pass. This allows - // other parts of the system to safely hold raw ComputedStyle* pointers - // during layout, e.g. BreakingContext::current_style_. - if (auto* scope = StyleRetainScope::Current()) - scope->Retain(current_style); - else - DCHECK(false); - layout_object->SetModifiedStyleOutsideStyleRecalc( - std::move(style), LayoutObject::ApplyStyleChanges::kNo); + style, LayoutObject::ApplyStyleChanges::kNo); if (layout_object->IsText()) To<LayoutText>(layout_object)->AutosizingMultiplerChanged(); layout_object->SetNeedsLayoutAndFullPaintInvalidation( @@ -1251,7 +1242,7 @@ case kLayoutNeeded: layout_object->SetModifiedStyleOutsideStyleRecalc( - std::move(style), LayoutObject::ApplyStyleChanges::kYes); + style, LayoutObject::ApplyStyleChanges::kYes); break; }
diff --git a/third_party/blink/renderer/core/page/print_context.cc b/third_party/blink/renderer/core/page/print_context.cc index 4f4b221..193638d 100644 --- a/third_party/blink/renderer/core/page/print_context.cc +++ b/third_party/blink/renderer/core/page/print_context.cc
@@ -252,8 +252,7 @@ // want to collect @page rules and figure out what declarations apply on a // given page (that may or may not exist). print_context->BeginPrintMode(WebPrintParams(gfx::SizeF(800, 1000))); - scoped_refptr<const ComputedStyle> style = - document->StyleForPage(page_number); + const ComputedStyle* style = document->StyleForPage(page_number); // Implement formatters for properties we care about. if (!strcmp(property_name, "margin-left")) { @@ -294,7 +293,7 @@ // Named pages aren't supported here, because this function may be called // without laying out first. - scoped_refptr<const ComputedStyle> style = frame->GetDocument()->StyleForPage( + const ComputedStyle* style = frame->GetDocument()->StyleForPage( page_number, /* page_name */ AtomicString()); frame->GetDocument()->GetPageDescription(*style, &description);
diff --git a/third_party/blink/renderer/core/paint/ng/ng_decorating_box.h b/third_party/blink/renderer/core/paint/ng/ng_decorating_box.h index e4a79fa6..fbd1ed4 100644 --- a/third_party/blink/renderer/core/paint/ng/ng_decorating_box.h +++ b/third_party/blink/renderer/core/paint/ng/ng_decorating_box.h
@@ -37,6 +37,8 @@ explicit NGDecoratingBox(const NGFragmentItem& item) : NGDecoratingBox(item, item.Style(), /* decorations */ nullptr) {} + void Trace(Visitor* visitor) const { visitor->Trace(style_); } + const PhysicalOffset& ContentOffsetInContainer() const { return content_offset_in_container_; } @@ -47,10 +49,12 @@ private: PhysicalOffset content_offset_in_container_; - const ComputedStyle* style_; + Member<const ComputedStyle> style_; const Vector<AppliedTextDecoration, 1>* decorations_; }; } // namespace blink +WTF_ALLOW_CLEAR_UNUSED_SLOTS_WITH_MEM_FUNCTIONS(blink::NGDecoratingBox) + #endif // THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_NG_NG_DECORATING_BOX_H_
diff --git a/third_party/blink/renderer/core/paint/ng/ng_highlight_painter.cc b/third_party/blink/renderer/core/paint/ng/ng_highlight_painter.cc index cc671bb..de62c21 100644 --- a/third_party/blink/renderer/core/paint/ng/ng_highlight_painter.cc +++ b/third_party/blink/renderer/core/paint/ng/ng_highlight_painter.cc
@@ -162,28 +162,28 @@ const ComputedStyle& originating_style, PseudoId pseudo) { DCHECK(pseudo == kPseudoIdSpellingError || pseudo == kPseudoIdGrammarError); - if (scoped_refptr<const ComputedStyle> pseudo_style = + if (const ComputedStyle* pseudo_style = HighlightStyleUtils::HighlightPseudoStyle(node, originating_style, pseudo)) { const Document& document = node->GetDocument(); // If the ‘color’, ‘-webkit-text-fill-color’, ‘-webkit-text-stroke-color’, // or ‘-webkit-text-stroke-width’ differs from the originating style. Color pseudo_color = HighlightStyleUtils::ResolveColor( - document, originating_style, pseudo_style.get(), pseudo, + document, originating_style, pseudo_style, pseudo, GetCSSPropertyColor(), {}); if (pseudo_color != originating_style.VisitedDependentColor(GetCSSPropertyColor())) { return true; } if (HighlightStyleUtils::ResolveColor( - document, originating_style, pseudo_style.get(), pseudo, + document, originating_style, pseudo_style, pseudo, GetCSSPropertyWebkitTextFillColor(), {}) != originating_style.VisitedDependentColor( GetCSSPropertyWebkitTextFillColor())) { return true; } if (HighlightStyleUtils::ResolveColor( - document, originating_style, pseudo_style.get(), pseudo, + document, originating_style, pseudo_style, pseudo, GetCSSPropertyWebkitTextStrokeColor(), {}) != originating_style.VisitedDependentColor( GetCSSPropertyWebkitTextStrokeColor())) { @@ -193,7 +193,7 @@ return true; // If there is a background color. if (!HighlightStyleUtils::ResolveColor(document, originating_style, - pseudo_style.get(), pseudo, + pseudo_style, pseudo, GetCSSPropertyBackgroundColor(), {}) .IsFullyTransparent()) { return true; @@ -227,7 +227,7 @@ // https://github.com/w3c/csswg-drafts/issues/7101 if (originating_style.GetTextEmphasisMark() != TextEmphasisMark::kNone && HighlightStyleUtils::ResolveColor( - document, originating_style, pseudo_style.get(), pseudo, + document, originating_style, pseudo_style, pseudo, GetCSSPropertyTextEmphasisColor(), {}) != originating_style.VisitedDependentColor( GetCSSPropertyTextEmphasisColor())) { @@ -650,7 +650,7 @@ highlight_pseudo_marker.GetPseudoId(), text_style, paint_info_, highlight_pseudo_marker.GetPseudoArgument()); - scoped_refptr<const ComputedStyle> pseudo_style = + const ComputedStyle* pseudo_style = HighlightStyleUtils::HighlightPseudoStyle( node_, originating_style_, highlight_pseudo_marker.GetPseudoId(), @@ -699,7 +699,7 @@ return kOverlay; if (selection_ && spelling_.empty() && grammar_.empty()) { - scoped_refptr<const ComputedStyle> pseudo_style = + const ComputedStyle* pseudo_style = HighlightStyleUtils::HighlightPseudoStyle(node_, originating_style_, kPseudoIdSelection); @@ -789,7 +789,7 @@ } if (!text_painter_.GetSvgState()) { - if (auto pseudo_style = HighlightStyleUtils::HighlightPseudoStyle( + if (const auto* pseudo_style = HighlightStyleUtils::HighlightPseudoStyle( node_, originating_style_, PseudoFor(type))) { const TextPaintStyle text_style = HighlightStyleUtils::HighlightPaintingStyle( @@ -1140,7 +1140,7 @@ decoration_info->SetHighlightOverrideColor( HighlightStyleUtils::ResolveColor( layout_object_->GetDocument(), originating_style_, - decoration_layer.style.get(), decoration_layer.id.PseudoId(), + decoration_layer.style.Get(), decoration_layer.id.PseudoId(), GetCSSPropertyTextDecorationColor(), layers_[decoration_layer_index - 1].text_style.current_color)); } @@ -1205,7 +1205,7 @@ decoration_info->SetHighlightOverrideColor( HighlightStyleUtils::ResolveColor( layout_object_->GetDocument(), originating_style_, - decoration_layer.style.get(), decoration_layer.id.PseudoId(), + decoration_layer.style.Get(), decoration_layer.id.PseudoId(), GetCSSPropertyTextDecorationColor(), layers_[decoration_layer_index - 1].text_style.current_color)); } @@ -1267,14 +1267,14 @@ NGHighlightPainter::LayerPaintState::LayerPaintState( NGHighlightOverlay::HighlightLayer id, - const scoped_refptr<const ComputedStyle> style, + const ComputedStyle* style, TextPaintStyle text_style) : id(id), style(style), text_style(text_style), decorations_in_effect(style && style->HasAppliedTextDecorations() - ? style->TextDecorationsInEffect() - : TextDecorationLine::kNone) {} + ? style->TextDecorationsInEffect() + : TextDecorationLine::kNone) {} bool NGHighlightPainter::LayerPaintState::operator==( const HighlightLayer& other) const {
diff --git a/third_party/blink/renderer/core/paint/ng/ng_highlight_painter.h b/third_party/blink/renderer/core/paint/ng/ng_highlight_painter.h index 24124c6..3fc4ef8 100644 --- a/third_party/blink/renderer/core/paint/ng/ng_highlight_painter.h +++ b/third_party/blink/renderer/core/paint/ng/ng_highlight_painter.h
@@ -206,15 +206,16 @@ SelectionPaintState* Selection() { return selection_; } - private: struct LayerPaintState { DISALLOW_NEW(); public: LayerPaintState(NGHighlightOverlay::HighlightLayer id, - const scoped_refptr<const ComputedStyle> style, + const ComputedStyle* style, TextPaintStyle text_style); + void Trace(Visitor* visitor) const { visitor->Trace(style); } + // Equality on HighlightLayer id only, for Vector::Find. bool operator==(const LayerPaintState&) const = delete; bool operator!=(const LayerPaintState&) const = delete; @@ -222,11 +223,12 @@ bool operator!=(const NGHighlightOverlay::HighlightLayer&) const; const NGHighlightOverlay::HighlightLayer id; - const scoped_refptr<const ComputedStyle> style; + const Member<const ComputedStyle> style; const TextPaintStyle text_style; const TextDecorationLine decorations_in_effect; }; + private: Case ComputePaintCase() const; void FastPaintSpellingGrammarDecorations(const Text& text_node, const StringView& text, @@ -275,7 +277,7 @@ DocumentMarkerVector spelling_; DocumentMarkerVector grammar_; DocumentMarkerVector custom_; - Vector<LayerPaintState> layers_; + HeapVector<LayerPaintState> layers_; Vector<NGHighlightOverlay::HighlightPart> parts_; const bool skip_backgrounds_; Case paint_case_; @@ -283,4 +285,7 @@ } // namespace blink +WTF_ALLOW_CLEAR_UNUSED_SLOTS_WITH_MEM_FUNCTIONS( + blink::NGHighlightPainter::LayerPaintState) + #endif // THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_NG_NG_HIGHLIGHT_PAINTER_H_
diff --git a/third_party/blink/renderer/core/paint/ng/ng_inline_paint_context.h b/third_party/blink/renderer/core/paint/ng/ng_inline_paint_context.h index 0976ae0b..dad361eb 100644 --- a/third_party/blink/renderer/core/paint/ng/ng_inline_paint_context.h +++ b/third_party/blink/renderer/core/paint/ng/ng_inline_paint_context.h
@@ -19,7 +19,7 @@ STACK_ALLOCATED(); public: - using DecoratingBoxList = Vector<NGDecoratingBox, 4>; + using DecoratingBoxList = HeapVector<NGDecoratingBox, 4>; const DecoratingBoxList& DecoratingBoxes() const { return decorating_boxes_; } NGInlineCursor CursorForDescendantsOfLine() const {
diff --git a/third_party/blink/renderer/core/paint/outline_painter_test.cc b/third_party/blink/renderer/core/paint/outline_painter_test.cc index 380af31..94cacbdb 100644 --- a/third_party/blink/renderer/core/paint/outline_painter_test.cc +++ b/third_party/blink/renderer/core/paint/outline_painter_test.cc
@@ -15,11 +15,11 @@ using OutlinePainterTest = RenderingTest; TEST_F(OutlinePainterTest, FocusRingOutset) { - auto initial_style = ComputedStyle::CreateInitialStyleSingleton(); + const auto* initial_style = ComputedStyle::CreateInitialStyleSingleton(); ComputedStyleBuilder builder(*initial_style); builder.SetOutlineStyle(EBorderStyle::kSolid); builder.SetOutlineStyleIsAuto(true); - auto style = builder.TakeStyle(); + const auto* style = builder.TakeStyle(); LayoutObject::OutlineInfo info = LayoutObject::OutlineInfo::GetFromStyle(*style); EXPECT_EQ(2, OutlinePainter::OutlineOutsetExtent(*style, info));
diff --git a/third_party/blink/renderer/core/paint/paint_layer.cc b/third_party/blink/renderer/core/paint/paint_layer.cc index a9d2bd5..8787a76 100644 --- a/third_party/blink/renderer/core/paint/paint_layer.cc +++ b/third_party/blink/renderer/core/paint/paint_layer.cc
@@ -2037,7 +2037,7 @@ const ComputedStyle& new_style) { if (!filter_on_effect_node_dirty_) { filter_on_effect_node_dirty_ = - old_style ? !old_style->FilterDataEquivalent(new_style) || + old_style ? old_style->Filter() != new_style.Filter() || !old_style->ReflectionDataEquivalent(new_style) : new_style.HasFilterInducingProperty(); } @@ -2057,7 +2057,7 @@ const ComputedStyle& new_style) { if (!backdrop_filter_on_effect_node_dirty_) { backdrop_filter_on_effect_node_dirty_ = - old_style ? !old_style->BackdropFilterDataEquivalent(new_style) + old_style ? old_style->BackdropFilter() != new_style.BackdropFilter() : new_style.HasBackdropFilter(); } }
diff --git a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc index 8954b0b..eafd87d 100644 --- a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc +++ b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc
@@ -2060,11 +2060,11 @@ const LayoutObject& style_source = ScrollbarStyleSource(*GetLayoutBox()); bool uses_standard_scrollbar_style = style_source.StyleRef().UsesStandardScrollbarStyle(); - scoped_refptr<const ComputedStyle> corner = + const ComputedStyle* corner = (GetLayoutBox()->IsScrollContainer() && !uses_standard_scrollbar_style) ? style_source.GetUncachedPseudoElementStyle( StyleRequest(kPseudoIdScrollbarCorner, style_source.Style())) - : scoped_refptr<ComputedStyle>(nullptr); + : nullptr; if (corner) { if (!scroll_corner_) { scroll_corner_ = LayoutCustomScrollbarPart::CreateAnonymous( @@ -2199,11 +2199,11 @@ // Update custom resizer style. const LayoutObject& style_source = ScrollbarStyleSource(*GetLayoutBox()); - scoped_refptr<const ComputedStyle> resizer = + const ComputedStyle* resizer = GetLayoutBox()->IsScrollContainer() ? style_source.GetUncachedPseudoElementStyle( StyleRequest(kPseudoIdResizer, style_source.Style())) - : scoped_refptr<ComputedStyle>(nullptr); + : nullptr; if (resizer) { if (!resizer_) { resizer_ = LayoutCustomScrollbarPart::CreateAnonymous(
diff --git a/third_party/blink/renderer/core/style/build.gni b/third_party/blink/renderer/core/style/build.gni index bcd1f4b..d94aff4 100644 --- a/third_party/blink/renderer/core/style/build.gni +++ b/third_party/blink/renderer/core/style/build.gni
@@ -79,8 +79,6 @@ "style_difference.h", "style_fetched_image.cc", "style_fetched_image.h", - "style_filter_data.cc", - "style_filter_data.h", "style_generated_image.cc", "style_generated_image.h", "style_highlight_data.cc",
diff --git a/third_party/blink/renderer/core/style/computed_style.cc b/third_party/blink/renderer/core/style/computed_style.cc index 2459cfb..83eb3fa 100644 --- a/third_party/blink/renderer/core/style/computed_style.cc +++ b/third_party/blink/renderer/core/style/computed_style.cc
@@ -113,7 +113,8 @@ // inheritance structure. Make sure the fields have the same access specifiers // as in the "real" class since it can affect the layout. Reference the fields // so that they are not seen as unused (-Wunused-private-field). -struct SameSizeAsComputedStyleBase { +struct SameSizeAsComputedStyleBase + : public GarbageCollected<SameSizeAsComputedStyleBase> { SameSizeAsComputedStyleBase() { base::debug::Alias(&data_refs); base::debug::Alias(&pointers); @@ -122,16 +123,15 @@ private: void* data_refs[8]; - void* pointers[1]; + Member<void*> pointers[1]; unsigned bitfields[5]; }; -struct SameSizeAsComputedStyle : public SameSizeAsComputedStyleBase, - public RefCounted<SameSizeAsComputedStyle> { +struct SameSizeAsComputedStyle : public SameSizeAsComputedStyleBase { SameSizeAsComputedStyle() { base::debug::Alias(&own_ptrs); } private: - void* own_ptrs[1]; + Member<void*> own_ptrs[1]; }; // If this assert fails, it means that size of ComputedStyle has changed. Please @@ -142,7 +142,7 @@ StyleCachedData& ComputedStyle::EnsureCachedData() const { if (!cached_data_) { - cached_data_ = std::make_unique<StyleCachedData>(); + cached_data_ = MakeGarbageCollected<StyleCachedData>(); } return *cached_data_; } @@ -154,7 +154,7 @@ PseudoElementStyleCache* ComputedStyle::GetPseudoElementStyleCache() const { if (cached_data_) { - return cached_data_->pseudo_element_styles_.get(); + return cached_data_->pseudo_element_styles_.Get(); } return nullptr; } @@ -162,13 +162,13 @@ PseudoElementStyleCache& ComputedStyle::EnsurePseudoElementStyleCache() const { if (!cached_data_ || !cached_data_->pseudo_element_styles_) { EnsureCachedData().pseudo_element_styles_ = - std::make_unique<PseudoElementStyleCache>(); + MakeGarbageCollected<PseudoElementStyleCache>(); } return *cached_data_->pseudo_element_styles_; } -scoped_refptr<ComputedStyle> ComputedStyle::CreateInitialStyleSingleton() { - return base::MakeRefCounted<ComputedStyle>(PassKey()); +const ComputedStyle* ComputedStyle::CreateInitialStyleSingleton() { + return MakeGarbageCollected<ComputedStyle>(PassKey()); } Vector<AtomicString>* ComputedStyle::GetVariableNamesCache() const { @@ -187,10 +187,10 @@ } const ComputedStyle* ComputedStyle::AddCachedPositionFallbackStyle( - scoped_refptr<const ComputedStyle> style, + const ComputedStyle* style, unsigned index) const { - EnsurePositionFallbackStyleCache(index + 1)[index] = std::move(style); - return (*cached_data_->position_fallback_styles_)[index].get(); + EnsurePositionFallbackStyleCache(index + 1)[index] = style; + return (*cached_data_->position_fallback_styles_)[index].Get(); } const ComputedStyle* ComputedStyle::GetCachedPositionFallbackStyle( @@ -199,14 +199,14 @@ index >= cached_data_->position_fallback_styles_->size()) { return nullptr; } - return (*cached_data_->position_fallback_styles_)[index].get(); + return (*cached_data_->position_fallback_styles_)[index].Get(); } PositionFallbackStyleCache& ComputedStyle::EnsurePositionFallbackStyleCache( unsigned ensure_size) const { if (!cached_data_ || !cached_data_->position_fallback_styles_) { EnsureCachedData().position_fallback_styles_ = - std::make_unique<PositionFallbackStyleCache>(); + MakeGarbageCollected<PositionFallbackStyleCache>(); } if (cached_data_->position_fallback_styles_->size() < ensure_size) { cached_data_->position_fallback_styles_->resize(ensure_size); @@ -214,24 +214,23 @@ return *cached_data_->position_fallback_styles_; } -ALWAYS_INLINE ComputedStyle::ComputedStyle() : RefCounted<ComputedStyle>() {} +ALWAYS_INLINE ComputedStyle::ComputedStyle() = default; ALWAYS_INLINE ComputedStyle::ComputedStyle(const ComputedStyle& initial_style) - : ComputedStyleBase(initial_style), RefCounted<ComputedStyle>() {} + : ComputedStyleBase(initial_style) {} ALWAYS_INLINE ComputedStyle::ComputedStyle(const ComputedStyle& initial_style, const ComputedStyle& parent_style, ComputedStyleAccessFlags& access) - : ComputedStyleBase(initial_style, parent_style, access), - RefCounted<ComputedStyle>() {} + : ComputedStyleBase(initial_style, parent_style, access) {} ALWAYS_INLINE ComputedStyle::ComputedStyle(PassKey key) : ComputedStyle() {} -ALWAYS_INLINE ComputedStyle::ComputedStyle(PassKey key, +ALWAYS_INLINE ComputedStyle::ComputedStyle(BuilderPassKey key, const ComputedStyle& initial_style) : ComputedStyle(initial_style) {} -ALWAYS_INLINE ComputedStyle::ComputedStyle(PassKey key, +ALWAYS_INLINE ComputedStyle::ComputedStyle(BuilderPassKey key, const ComputedStyle& initial_style, const ComputedStyle& parent_style, ComputedStyleAccessFlags& access) @@ -605,7 +604,7 @@ if (pseudo_style->StyleType() == pseudo_id && (!PseudoElementHasArguments(pseudo_id) || pseudo_style->PseudoArgument() == pseudo_argument)) { - return pseudo_style.get(); + return pseudo_style.Get(); } } @@ -629,7 +628,7 @@ } const ComputedStyle* ComputedStyle::AddCachedPseudoElementStyle( - scoped_refptr<const ComputedStyle> pseudo, + const ComputedStyle* pseudo, PseudoId pseudo_id, const AtomicString& pseudo_argument) const { DCHECK(pseudo); @@ -646,7 +645,7 @@ DCHECK(!GetCachedPseudoElementStyle(pseudo->StyleType(), pseudo->PseudoArgument())); - const ComputedStyle* result = pseudo.get(); + const ComputedStyle* result = pseudo; EnsurePseudoElementStyleCache().push_back(std::move(pseudo)); @@ -654,7 +653,7 @@ } const ComputedStyle* ComputedStyle::ReplaceCachedPseudoElementStyle( - scoped_refptr<const ComputedStyle> pseudo_style, + const ComputedStyle* pseudo_style, PseudoId pseudo_id, const AtomicString& pseudo_argument) const { DCHECK(pseudo_style->StyleType() != kPseudoIdNone && @@ -666,7 +665,7 @@ cached_style->PseudoArgument() == pseudo_argument)) { SECURITY_CHECK(cached_style->IsEnsuredInDisplayNone()); cached_style = pseudo_style; - return pseudo_style.get(); + return pseudo_style; } } } @@ -680,14 +679,14 @@ } const ComputedStyle* ComputedStyle::GetBaseComputedStyle() const { - if (auto* base_data = BaseData().get()) { + if (auto* base_data = BaseData().Get()) { return base_data->GetBaseComputedStyle(); } return nullptr; } const CSSBitset* ComputedStyle::GetBaseImportantSet() const { - if (auto* base_data = BaseData().get()) { + if (auto* base_data = BaseData().Get()) { return base_data->GetBaseImportantSet(); } return nullptr; @@ -1152,7 +1151,7 @@ ContainsPaint() != other.ContainsPaint() || IsOverflowVisibleAlongBothAxes() != other.IsOverflowVisibleAlongBothAxes() || - !BackdropFilterDataEquivalent(other) || + BackdropFilter() != other.BackdropFilter() || PotentialCompositingReasonsFor3DTransformChanged(other)) { diff.SetCompositingReasonsChanged(); } @@ -1414,10 +1413,6 @@ } } -bool ComputedStyle::HasFilters() const { - return FilterInternal().Get() && !FilterInternal()->operations_.IsEmpty(); -} - namespace { gfx::RectF GetReferenceBox(const LayoutBox* box, CoordBox coord_box) { @@ -2612,7 +2607,8 @@ } ComputedStyleBuilder::ComputedStyleBuilder(const ComputedStyle& style) { - style_ = base::AdoptRef(new ComputedStyle(style)); + style_ = MakeGarbageCollected<ComputedStyle>(ComputedStyle::BuilderPassKey(), + style); SetStyleBase(*style_); } @@ -2620,8 +2616,9 @@ const ComputedStyle& initial_style, const ComputedStyle& parent_style, IsAtShadowBoundary is_at_shadow_boundary) { - style_ = base::AdoptRef(new ComputedStyle(initial_style, parent_style, - GetAccessFlagsForConstructor())); + style_ = MakeGarbageCollected<ComputedStyle>(ComputedStyle::BuilderPassKey(), + initial_style, parent_style, + GetAccessFlagsForConstructor()); SetStyleBase(*style_); // Even if surrounding content is user-editable, shadow DOM should act as a @@ -2640,10 +2637,11 @@ SetBaseTextDecorationData(parent_style.AppliedTextDecorationData()); } -scoped_refptr<const ComputedStyle> ComputedStyleBuilder::CloneStyle() const { +const ComputedStyle* ComputedStyleBuilder::CloneStyle() const { DCHECK(style_); ResetAccess(); - return base::AdoptRef(new ComputedStyle(*style_)); + return MakeGarbageCollected<ComputedStyle>(ComputedStyle::BuilderPassKey(), + *style_); } void ComputedStyleBuilder::PropagateIndependentInheritedProperties( @@ -2686,16 +2684,6 @@ return true; } -StyleHighlightData& ComputedStyleBuilder::MutableHighlightData() { - scoped_refptr<StyleHighlightData>& data = MutableHighlightDataInternal(); - if (!data) { - data = StyleHighlightData::Create(); - } else if (!data->HasOneRef()) { - data = data->Copy(); - } - return *data; -} - // Compute the FontOrientation from this style. It's derived from WritingMode // and TextOrientation. FontOrientation ComputedStyleBuilder::ComputeFontOrientation() const { @@ -2832,6 +2820,4 @@ STATIC_ASSERT_ENUM(cc::OverscrollBehavior::Type::kNone, EOverscrollBehavior::kNone); -CORE_EXPORT ComputedStyle* ComputedStyle::freelist_ = nullptr; - } // namespace blink
diff --git a/third_party/blink/renderer/core/style/computed_style.h b/third_party/blink/renderer/core/style/computed_style.h index 79b63df6..58be381 100644 --- a/third_party/blink/renderer/core/style/computed_style.h +++ b/third_party/blink/renderer/core/style/computed_style.h
@@ -55,6 +55,7 @@ #include "third_party/blink/renderer/core/style/cursor_list.h" #include "third_party/blink/renderer/core/style/data_ref.h" #include "third_party/blink/renderer/core/style/display_style.h" +#include "third_party/blink/renderer/core/style/filter_operations.h" #include "third_party/blink/renderer/core/style/font_size_style.h" #include "third_party/blink/renderer/core/style/style_cached_data.h" #include "third_party/blink/renderer/core/style/style_highlight_data.h" @@ -72,6 +73,7 @@ #include "third_party/blink/renderer/platform/text/writing_direction_mode.h" #include "third_party/blink/renderer/platform/text/writing_mode_utils.h" #include "third_party/blink/renderer/platform/transforms/transform_operations.h" +#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" #include "third_party/blink/renderer/platform/wtf/forward.h" #include "third_party/blink/renderer/platform/wtf/leak_annotations.h" #include "third_party/blink/renderer/platform/wtf/ref_counted.h" @@ -94,7 +96,6 @@ class FloodColor; class CSSTransitionData; class CSSVariableData; -class FilterOperations; class Font; class Hyphenation; class LayoutBox; @@ -213,8 +214,7 @@ // // Since this class is huge, do not mark all of it CORE_EXPORT. Instead, // export only the methods you need below. -class ComputedStyle : public ComputedStyleBase, - public RefCounted<ComputedStyle> { +class ComputedStyle final : public ComputedStyleBase { // Needed to allow access to private/protected getters of fields to allow diff // generation friend class ComputedStyleBase; @@ -299,7 +299,7 @@ using ComputedStyleBase::Resize; protected: - mutable std::unique_ptr<StyleCachedData> cached_data_; + mutable Member<StyleCachedData> cached_data_; StyleCachedData& EnsureCachedData() const; @@ -326,36 +326,24 @@ public: using PassKey = base::PassKey<ComputedStyle>; + using BuilderPassKey = base::PassKey<ComputedStyleBuilder>; - // See comment on freelist_. - void* operator new(size_t size) { - DCHECK(IsMainThread()); - if (freelist_ != nullptr) { - ComputedStyle* ret = freelist_; - freelist_ = nullptr; - return ret; - } - return ::WTF::Partitions::FastMalloc(size, "ComputedStyle"); - } - void operator delete(void* p) { - DCHECK(IsMainThread()); - if (freelist_ == nullptr) { - freelist_ = static_cast<ComputedStyle*>(p); - } else { - ::WTF::Partitions::FastFree(p); - } - } - - ALWAYS_INLINE ComputedStyle(PassKey, const ComputedStyle& initial_style); - ALWAYS_INLINE ComputedStyle(PassKey, + ALWAYS_INLINE ComputedStyle(BuilderPassKey, + const ComputedStyle& initial_style); + ALWAYS_INLINE ComputedStyle(BuilderPassKey, const ComputedStyle& initial_style, const ComputedStyle& parent_style, ComputedStyleAccessFlags& access); ALWAYS_INLINE explicit ComputedStyle(PassKey); + void TraceAfterDispatch(Visitor* visitor) const { + visitor->Trace(cached_data_); + ComputedStyleBase::TraceAfterDispatch(visitor); + } + // Create the per-document/context singleton that is used for shallow-copying // into new instances. - CORE_EXPORT static scoped_refptr<ComputedStyle> CreateInitialStyleSingleton(); + CORE_EXPORT static const ComputedStyle* CreateInitialStyleSingleton(); static const ComputedStyle* NullifyEnsured(const ComputedStyle* style) { if (!style) { @@ -447,20 +435,18 @@ CORE_EXPORT const ComputedStyle* GetCachedPseudoElementStyle( PseudoId, const AtomicString& pseudo_argument = g_null_atom) const; - const ComputedStyle* AddCachedPseudoElementStyle( - scoped_refptr<const ComputedStyle>, - PseudoId, - const AtomicString&) const; + const ComputedStyle* AddCachedPseudoElementStyle(const ComputedStyle*, + PseudoId, + const AtomicString&) const; const ComputedStyle* ReplaceCachedPseudoElementStyle( - scoped_refptr<const ComputedStyle> pseudo_style, + const ComputedStyle* pseudo_style, PseudoId pseudo_id, const AtomicString& pseudo_argument) const; void ClearCachedPseudoElementStyles() const; const ComputedStyle* GetCachedPositionFallbackStyle(unsigned index) const; - const ComputedStyle* AddCachedPositionFallbackStyle( - scoped_refptr<const ComputedStyle>, - unsigned index) const; + const ComputedStyle* AddCachedPositionFallbackStyle(const ComputedStyle*, + unsigned index) const; // If this ComputedStyle is affected by animation/transitions, then the // unanimated "base" style can be retrieved with this function. @@ -520,38 +506,17 @@ return base::ValuesEquivalent(AnchorName(), o.AnchorName()); } - const FilterOperations& BackdropFilter() const { - DCHECK(BackdropFilterInternal().Get()); - return BackdropFilterInternal()->operations_; - } // For containing blocks, use |HasNonInitialBackdropFilter()| which includes // will-change: backdrop-filter. - static bool HasBackdropFilter(const StyleFilterData* backdrop_filter) { - DCHECK(backdrop_filter); - return !backdrop_filter->operations_.Operations().empty(); + static bool HasBackdropFilter(const FilterOperations& backdrop_filter) { + return !backdrop_filter.Operations().empty(); } - bool HasBackdropFilter() const { - return HasBackdropFilter(BackdropFilterInternal()); - } - bool BackdropFilterDataEquivalent(const ComputedStyle& o) const { - return base::ValuesEquivalent(BackdropFilterInternal(), - o.BackdropFilterInternal()); - } + bool HasBackdropFilter() const { return HasBackdropFilter(BackdropFilter()); } // filter (aka -webkit-filter) - const FilterOperations& Filter() const { - DCHECK(FilterInternal().Get()); - return FilterInternal()->operations_; - } // For containing blocks, use |HasNonInitialFilter()| which includes // will-change: filter. - bool HasFilter() const { - DCHECK(FilterInternal().Get()); - return !FilterInternal()->operations_.Operations().empty(); - } - bool FilterDataEquivalent(const ComputedStyle& o) const { - return base::ValuesEquivalent(FilterInternal(), o.FilterInternal()); - } + bool HasFilter() const { return !Filter().Operations().empty(); } // background-image bool HasBackgroundImage() const { @@ -2158,8 +2123,6 @@ ApplyMotionPath, ApplyIndependentTransformProperties) const; - bool HasFilters() const; - // Returns |true| if any property that renders using filter operations is // used (including, but not limited to, 'filter' and 'box-reflect'). bool HasFilterInducingProperty() const { @@ -2767,16 +2730,6 @@ // Derived flags: bool CalculateIsStackingContextWithoutContainment() const; - // A one-element freelist that we can use to get fewer calls to new/delete - // when recalculating style; the new and delete calls usually come in - // exact pairs, so barring DCHECK verification, a single-element list - // is usually sufficient to get rid of nearly all such calls, and we don't - // need anything longer or more complex. (We still run the constructors and - // destructors, though; it's only the memory that is reused, not the object.) - // - // Subobjects in generated code use exactly the same pattern (see group.tmpl). - CORE_EXPORT static ComputedStyle* freelist_; - FRIEND_TEST_ALL_PREFIXES( ComputedStyleTest, UpdatePropertySpecificDifferencesRespectsTransformAnimation); @@ -2896,10 +2849,10 @@ ComputedStyleBuilder& operator=(const ComputedStyleBuilder&) = delete; ComputedStyleBuilder& operator=(ComputedStyleBuilder&&) = default; - scoped_refptr<const ComputedStyle> TakeStyle() { return std::move(style_); } + const ComputedStyle* TakeStyle() { return std::move(style_); } // NOTE: Prefer `TakeStyle()` if possible. - CORE_EXPORT scoped_refptr<const ComputedStyle> CloneStyle() const; + CORE_EXPORT const ComputedStyle* CloneStyle() const; // Copies the values of any independent inherited properties from the parent // that are not explicitly set in this style. @@ -2930,18 +2883,11 @@ } // backdrop-filter - FilterOperations& MutableBackdropFilter() { - DCHECK(BackdropFilterInternal().Get()); - return MutableBackdropFilterInternal()->operations_; - } - void SetBackdropFilter(const FilterOperations& ops) { - DCHECK(BackdropFilterInternal().Get()); - if (BackdropFilterInternal()->operations_ != ops) { - MutableBackdropFilterInternal()->operations_ = ops; - } + FilterOperations::FilterOperationVector& MutableBackdropFilterOperations() { + return MutableBackdropFilterInternal().Operations(); } bool HasBackdropFilter() const { - return ComputedStyle::HasBackdropFilter(BackdropFilterInternal()); + return ComputedStyle::HasBackdropFilter(BackdropFilter()); } // background @@ -3138,15 +3084,8 @@ } // filter - FilterOperations& MutableFilter() { - DCHECK(FilterInternal().Get()); - return MutableFilterInternal()->operations_; - } - void SetFilter(const FilterOperations& v) { - DCHECK(FilterInternal().Get()); - if (FilterInternal()->operations_ != v) { - MutableFilterInternal()->operations_ = v; - } + FilterOperations::FilterOperationVector& MutableFilterOperations() { + return MutableFilterInternal().Operations(); } // float @@ -3422,7 +3361,7 @@ // BaseData const ComputedStyle* GetBaseComputedStyle() const { - if (auto* base_data = BaseData().get()) { + if (auto* base_data = BaseData().Get()) { return base_data->GetBaseComputedStyle(); } return nullptr; @@ -3445,7 +3384,9 @@ } // ::selection, etc - StyleHighlightData& MutableHighlightData(); + StyleHighlightData& AccessHighlightData() { + return MutableHighlightDataInternal(); + } // CustomHighlightNames void SetCustomHighlightNames( @@ -3561,7 +3502,7 @@ } private: - scoped_refptr<ComputedStyle> style_; + ComputedStyle* style_; }; } // namespace blink
diff --git a/third_party/blink/renderer/core/style/computed_style_diff_functions.json5 b/third_party/blink/renderer/core/style/computed_style_diff_functions.json5 index 5870aec..17061e0b 100644 --- a/third_party/blink/renderer/core/style/computed_style_diff_functions.json5 +++ b/third_party/blink/renderer/core/style/computed_style_diff_functions.json5
@@ -402,15 +402,12 @@ }, { name: "UpdatePropertySpecificDifferencesFilter", + fields_to_diff: ["filter"], predicates_to_test: [ { predicate: "a.ReflectionDataEquivalent(b)", field_dependencies: ["-webkit-box-reflect"] }, - { - predicate: "a.FilterDataEquivalent(b)", - field_dependencies: ["filter"] - }, ] }, {
diff --git a/third_party/blink/renderer/core/style/computed_style_extra_fields.json5 b/third_party/blink/renderer/core/style/computed_style_extra_fields.json5 index 8b246c3..4b69237 100644 --- a/third_party/blink/renderer/core/style/computed_style_extra_fields.json5 +++ b/third_party/blink/renderer/core/style/computed_style_extra_fields.json5
@@ -327,7 +327,7 @@ type_name: "FillLayer", default_value: "FillLayer(EFillLayerType::kBackground, true)", field_group: "background", - computed_style_custom_functions: ["getter", "setter"], + computed_style_custom_functions: ["initial", "getter", "setter"], }, { name: "HasClipPath", @@ -377,7 +377,7 @@ type_name: "CursorList", include_paths: ["third_party/blink/renderer/core/style/cursor_list.h"], default_value: "nullptr", - wrapper_pointer_name: "Persistent", + wrapper_pointer_name: "Member", field_group: "*", computed_style_custom_functions: ["getter", "setter"], }, @@ -481,9 +481,8 @@ field_template: "external", type_name: "StyleHighlightData", include_paths: ["third_party/blink/renderer/core/style/style_highlight_data.h"], - default_value: "nullptr", - wrapper_pointer_name: "scoped_refptr", - field_group: "*", + default_value: "StyleHighlightData()", + field_group: "*->highlight-data", computed_style_custom_functions: [], }, { @@ -503,7 +502,7 @@ type_name: "FillLayer", field_group: "*", default_value: "FillLayer(EFillLayerType::kMask, true)", - computed_style_custom_functions: ["getter", "setter"], + computed_style_custom_functions: ["initial", "getter", "setter"], }, { name: "CounterDirectives", @@ -573,7 +572,7 @@ name: "DocumentRulesSelectors", field_template: "external", type_name: "HeapHashSet<WeakMember<StyleRule>>", - wrapper_pointer_name: "Persistent", + wrapper_pointer_name: "Member", field_group: "*", default_value: "nullptr", include_paths: ["third_party/blink/renderer/platform/heap/collection_support/heap_hash_set.h", @@ -1129,7 +1128,7 @@ type_name: "StyleBaseData", include_paths: ["third_party/blink/renderer/core/style/style_base_data.h"], default_value: "nullptr", - wrapper_pointer_name: "scoped_refptr", + wrapper_pointer_name: "Member", custom_compare: true, reset_on_new_style: true, },
diff --git a/third_party/blink/renderer/core/style/computed_style_test.cc b/third_party/blink/renderer/core/style/computed_style_test.cc index 5757f3b..7d4c552 100644 --- a/third_party/blink/renderer/core/style/computed_style_test.cc +++ b/third_party/blink/renderer/core/style/computed_style_test.cc
@@ -52,9 +52,7 @@ initial_style_ = ComputedStyle::CreateInitialStyleSingleton(); } - scoped_refptr<const ComputedStyle> InitialComputedStyle() { - return initial_style_; - } + const ComputedStyle* InitialComputedStyle() { return initial_style_; } ComputedStyleBuilder CreateComputedStyleBuilder() { return ComputedStyleBuilder(*initial_style_); @@ -66,7 +64,7 @@ } private: - scoped_refptr<const ComputedStyle> initial_style_; + Persistent<const ComputedStyle> initial_style_; }; TEST_F(ComputedStyleTest, ShapeOutsideBoxEqual) { @@ -109,7 +107,7 @@ TEST_F(ComputedStyleTest, ForcesStackingContext) { ComputedStyleBuilder builder = CreateComputedStyleBuilder(); builder.SetForcesStackingContext(true); - scoped_refptr<const ComputedStyle> style = builder.TakeStyle(); + const ComputedStyle* style = builder.TakeStyle(); EXPECT_TRUE(style->IsStackingContextWithoutContainment()); } @@ -118,13 +116,13 @@ builder.SetTransformStyle3D(ETransformStyle3D::kPreserve3d); builder.SetOverflowX(EOverflow::kHidden); builder.SetOverflowY(EOverflow::kHidden); - scoped_refptr<const ComputedStyle> style = builder.TakeStyle(); + const ComputedStyle* style = builder.TakeStyle(); EXPECT_EQ(ETransformStyle3D::kFlat, style->UsedTransformStyle3D()); EXPECT_TRUE(style->IsStackingContextWithoutContainment()); } TEST_F(ComputedStyleTest, LayoutContainmentStackingContext) { - scoped_refptr<const ComputedStyle> style = InitialComputedStyle(); + const ComputedStyle* style = InitialComputedStyle(); EXPECT_FALSE(style->IsStackingContextWithoutContainment()); ComputedStyleBuilder builder(*style); @@ -137,18 +135,18 @@ TEST_F(ComputedStyleTest, IsStackingContextWithoutContainmentAfterClone) { ComputedStyleBuilder builder1 = CreateComputedStyleBuilder(); builder1.SetForcesStackingContext(true); - scoped_refptr<const ComputedStyle> style1 = builder1.TakeStyle(); + const ComputedStyle* style1 = builder1.TakeStyle(); EXPECT_TRUE(style1->IsStackingContextWithoutContainment()); ComputedStyleBuilder builder2(*style1); - scoped_refptr<const ComputedStyle> style2 = builder2.TakeStyle(); + const ComputedStyle* style2 = builder2.TakeStyle(); EXPECT_TRUE(style2->IsStackingContextWithoutContainment()); // Verify that the cached value for IsStackingContextWithoutContainment // isn't copied from `style1`. ComputedStyleBuilder builder3(*style1); builder3.SetForcesStackingContext(false); - scoped_refptr<const ComputedStyle> style3 = builder3.TakeStyle(); + const ComputedStyle* style3 = builder3.TakeStyle(); EXPECT_FALSE(style3->IsStackingContextWithoutContainment()); } @@ -156,13 +154,13 @@ { ComputedStyleBuilder builder1 = CreateComputedStyleBuilder(); builder1.SetForcesStackingContext(true); - scoped_refptr<const ComputedStyle> style1 = builder1.TakeStyle(); + const ComputedStyle* style1 = builder1.TakeStyle(); EXPECT_TRUE(style1->IsStackingContextWithoutContainment()); // Whether the style is a stacking context or not should not be copied // from the style we're cloning. ComputedStyleBuilder builder2 = CreateComputedStyleBuilderFrom(*style1); - scoped_refptr<const ComputedStyle> style2 = builder2.TakeStyle(); + const ComputedStyle* style2 = builder2.TakeStyle(); EXPECT_TRUE(style2->IsStackingContextWithoutContainment()); } @@ -170,11 +168,11 @@ // expected to be false. { ComputedStyleBuilder builder1 = CreateComputedStyleBuilder(); - scoped_refptr<const ComputedStyle> style1 = builder1.TakeStyle(); + const ComputedStyle* style1 = builder1.TakeStyle(); EXPECT_FALSE(style1->IsStackingContextWithoutContainment()); ComputedStyleBuilder builder2 = CreateComputedStyleBuilderFrom(*style1); - scoped_refptr<const ComputedStyle> style2 = builder2.TakeStyle(); + const ComputedStyle* style2 = builder2.TakeStyle(); EXPECT_FALSE(style2->IsStackingContextWithoutContainment()); } @@ -183,12 +181,12 @@ { ComputedStyleBuilder builder1 = CreateComputedStyleBuilder(); builder1.SetForcesStackingContext(true); - scoped_refptr<const ComputedStyle> style1 = builder1.TakeStyle(); + const ComputedStyle* style1 = builder1.TakeStyle(); EXPECT_TRUE(style1->IsStackingContextWithoutContainment()); ComputedStyleBuilder builder2 = CreateComputedStyleBuilderFrom(*style1); builder2.SetForcesStackingContext(false); - scoped_refptr<const ComputedStyle> style2 = builder2.TakeStyle(); + const ComputedStyle* style2 = builder2.TakeStyle(); // Value copied from 'style1' must not persist. EXPECT_FALSE(style2->IsStackingContextWithoutContainment()); } @@ -203,7 +201,7 @@ ComputedStyleBuilder builder = CreateComputedStyleBuilder(); builder.SetPseudoElementStyles(match_result.PseudoElementStyles()); - scoped_refptr<const ComputedStyle> style = builder.TakeStyle(); + const ComputedStyle* style = builder.TakeStyle(); EXPECT_TRUE(style->HasPseudoElementStyle(pseudo_id)); EXPECT_TRUE(style->HasAnyPseudoElementStyles()); @@ -212,10 +210,10 @@ TEST_F(ComputedStyleTest, UpdatePropertySpecificDifferencesRespectsTransformAnimation) { - scoped_refptr<const ComputedStyle> style = InitialComputedStyle(); + const ComputedStyle* style = InitialComputedStyle(); ComputedStyleBuilder builder(*style); builder.SetHasCurrentTransformAnimation(true); - scoped_refptr<const ComputedStyle> other = builder.TakeStyle(); + const ComputedStyle* other = builder.TakeStyle(); StyleDifference diff; style->UpdatePropertySpecificDifferences(*other, diff); @@ -232,11 +230,11 @@ ComputedStyleBuilder builder = CreateComputedStyleBuilder(); builder.SetTransform(operations); - scoped_refptr<const ComputedStyle> style = builder.TakeStyle(); + const ComputedStyle* style = builder.TakeStyle(); builder = ComputedStyleBuilder(*style); builder.SetHasCurrentTransformAnimation(true); - scoped_refptr<const ComputedStyle> other = builder.TakeStyle(); + const ComputedStyle* other = builder.TakeStyle(); StyleDifference diff; style->UpdatePropertySpecificDifferences(*other, diff); @@ -246,10 +244,10 @@ TEST_F(ComputedStyleTest, UpdatePropertySpecificDifferencesRespectsScaleAnimation) { - scoped_refptr<const ComputedStyle> style = InitialComputedStyle(); + const ComputedStyle* style = InitialComputedStyle(); ComputedStyleBuilder builder(*style); builder.SetHasCurrentScaleAnimation(true); - scoped_refptr<const ComputedStyle> other = builder.TakeStyle(); + const ComputedStyle* other = builder.TakeStyle(); StyleDifference diff; style->UpdatePropertySpecificDifferences(*other, diff); @@ -258,10 +256,10 @@ TEST_F(ComputedStyleTest, UpdatePropertySpecificDifferencesRespectsRotateAnimation) { - scoped_refptr<const ComputedStyle> style = InitialComputedStyle(); + const ComputedStyle* style = InitialComputedStyle(); ComputedStyleBuilder builder(*style); builder.SetHasCurrentRotateAnimation(true); - scoped_refptr<const ComputedStyle> other = builder.TakeStyle(); + const ComputedStyle* other = builder.TakeStyle(); StyleDifference diff; style->UpdatePropertySpecificDifferences(*other, diff); @@ -270,10 +268,10 @@ TEST_F(ComputedStyleTest, UpdatePropertySpecificDifferencesRespectsTranslateAnimation) { - scoped_refptr<const ComputedStyle> style = InitialComputedStyle(); + const ComputedStyle* style = InitialComputedStyle(); ComputedStyleBuilder builder(*style); builder.SetHasCurrentTranslateAnimation(true); - scoped_refptr<const ComputedStyle> other = builder.TakeStyle(); + const ComputedStyle* other = builder.TakeStyle(); StyleDifference diff; style->UpdatePropertySpecificDifferences(*other, diff); @@ -282,10 +280,10 @@ TEST_F(ComputedStyleTest, UpdatePropertySpecificDifferencesCompositingReasonsOpacity) { - scoped_refptr<const ComputedStyle> style = InitialComputedStyle(); + const ComputedStyle* style = InitialComputedStyle(); ComputedStyleBuilder builder(*style); builder.SetHasCurrentOpacityAnimation(true); - scoped_refptr<const ComputedStyle> other = builder.TakeStyle(); + const ComputedStyle* other = builder.TakeStyle(); StyleDifference diff; style->UpdatePropertySpecificDifferences(*other, diff); @@ -294,10 +292,10 @@ TEST_F(ComputedStyleTest, UpdatePropertySpecificDifferencesCompositingReasonsFilter) { - scoped_refptr<const ComputedStyle> style = InitialComputedStyle(); + const ComputedStyle* style = InitialComputedStyle(); ComputedStyleBuilder builder(*style); builder.SetHasCurrentFilterAnimation(true); - scoped_refptr<const ComputedStyle> other = builder.TakeStyle(); + const ComputedStyle* other = builder.TakeStyle(); StyleDifference diff; style->UpdatePropertySpecificDifferences(*other, diff); @@ -306,10 +304,10 @@ TEST_F(ComputedStyleTest, UpdatePropertySpecificDifferencesCompositingReasonsBackdropFilter) { - scoped_refptr<const ComputedStyle> style = InitialComputedStyle(); + const ComputedStyle* style = InitialComputedStyle(); ComputedStyleBuilder builder(*style); builder.SetHasCurrentBackdropFilterAnimation(true); - scoped_refptr<const ComputedStyle> other = builder.TakeStyle(); + const ComputedStyle* other = builder.TakeStyle(); StyleDifference diff; style->UpdatePropertySpecificDifferences(*other, diff); @@ -318,10 +316,10 @@ TEST_F(ComputedStyleTest, UpdatePropertySpecificDifferencesCompositingReasonsBackfaceVisibility) { - scoped_refptr<const ComputedStyle> style = InitialComputedStyle(); + const ComputedStyle* style = InitialComputedStyle(); ComputedStyleBuilder builder(*style); builder.SetBackfaceVisibility(EBackfaceVisibility::kHidden); - scoped_refptr<const ComputedStyle> other = builder.TakeStyle(); + const ComputedStyle* other = builder.TakeStyle(); StyleDifference diff; style->UpdatePropertySpecificDifferences(*other, diff); @@ -330,11 +328,11 @@ TEST_F(ComputedStyleTest, UpdatePropertySpecificDifferencesCompositingReasonsWillChange) { - scoped_refptr<const ComputedStyle> style = InitialComputedStyle(); + const ComputedStyle* style = InitialComputedStyle(); ComputedStyleBuilder builder(*style); builder.SetBackfaceVisibility(EBackfaceVisibility::kHidden); builder.SetWillChangeProperties({CSSPropertyID::kOpacity}); - scoped_refptr<const ComputedStyle> other = builder.TakeStyle(); + const ComputedStyle* other = builder.TakeStyle(); StyleDifference diff; style->UpdatePropertySpecificDifferences(*other, diff); @@ -345,12 +343,12 @@ UpdatePropertySpecificDifferencesCompositingReasonsUsedStylePreserve3D) { ComputedStyleBuilder builder = CreateComputedStyleBuilder(); builder.SetTransformStyle3D(ETransformStyle3D::kPreserve3d); - scoped_refptr<const ComputedStyle> style = builder.TakeStyle(); + const ComputedStyle* style = builder.TakeStyle(); builder = ComputedStyleBuilder(*style); // This induces a flat used transform style. builder.SetOpacity(0.5); - scoped_refptr<const ComputedStyle> other = builder.TakeStyle(); + const ComputedStyle* other = builder.TakeStyle(); StyleDifference diff; style->UpdatePropertySpecificDifferences(*other, diff); @@ -359,10 +357,10 @@ TEST_F(ComputedStyleTest, UpdatePropertySpecificDifferencesCompositingReasonsOverflow) { - scoped_refptr<const ComputedStyle> style = InitialComputedStyle(); + const ComputedStyle* style = InitialComputedStyle(); ComputedStyleBuilder builder(*style); builder.SetOverflowX(EOverflow::kHidden); - scoped_refptr<const ComputedStyle> other = builder.TakeStyle(); + const ComputedStyle* other = builder.TakeStyle(); StyleDifference diff; style->UpdatePropertySpecificDifferences(*other, diff); @@ -371,11 +369,11 @@ TEST_F(ComputedStyleTest, UpdatePropertySpecificDifferencesCompositingReasonsContainsPaint) { - scoped_refptr<const ComputedStyle> style = InitialComputedStyle(); + const ComputedStyle* style = InitialComputedStyle(); ComputedStyleBuilder builder(*style); // This induces a flat used transform style. builder.SetContain(kContainsPaint); - scoped_refptr<const ComputedStyle> other = builder.TakeStyle(); + const ComputedStyle* other = builder.TakeStyle(); StyleDifference diff; style->UpdatePropertySpecificDifferences(*other, diff); @@ -384,7 +382,7 @@ TEST_F(ComputedStyleTest, HasOutlineWithCurrentColor) { ComputedStyleBuilder builder = CreateComputedStyleBuilder(); - scoped_refptr<const ComputedStyle> style = builder.TakeStyle(); + const ComputedStyle* style = builder.TakeStyle(); EXPECT_FALSE(style->HasOutline()); EXPECT_FALSE(style->HasOutlineWithCurrentColor()); @@ -405,7 +403,7 @@ TEST_F(ComputedStyleTest, BorderWidth) { ComputedStyleBuilder builder = CreateComputedStyleBuilder(); builder.SetBorderBottomWidth(LayoutUnit(5)); - scoped_refptr<const ComputedStyle> style = builder.TakeStyle(); + const ComputedStyle* style = builder.TakeStyle(); EXPECT_EQ(style->BorderBottomWidth(), 0); EXPECT_EQ(style->BorderBottom().Width(), 5); @@ -429,11 +427,11 @@ ComputedStyleBuilder builder = CreateComputedStyleBuilder(); builder.AddCursor(image_value, false); - scoped_refptr<const ComputedStyle> style = builder.TakeStyle(); + const ComputedStyle* style = builder.TakeStyle(); builder = CreateComputedStyleBuilder(); builder.AddCursor(other_image_value, false); - scoped_refptr<const ComputedStyle> other = builder.TakeStyle(); + const ComputedStyle* other = builder.TakeStyle(); EXPECT_EQ(*style, *other); } @@ -450,8 +448,8 @@ builder.SetBorderTopStyle(EBorderStyle::kSolid); builder.SetBorderRightStyle(EBorderStyle::kSolid); builder.SetBorderBottomStyle(EBorderStyle::kSolid); - scoped_refptr<const ComputedStyle> style = builder.CloneStyle(); - scoped_refptr<const ComputedStyle> other = builder.TakeStyle(); + const ComputedStyle* style = builder.CloneStyle(); + const ComputedStyle* other = builder.TakeStyle(); EXPECT_TRUE(style->BorderSizeEquals(*other)); UPDATE_STYLE(style, SetBorderLeftWidth, LayoutUnit(1)); @@ -541,34 +539,34 @@ EXPECT_FALSE(style->HasBorder()); } -#define TEST_ANIMATION_FLAG(flag, inherited) \ - do { \ - auto builder = CreateComputedStyleBuilder(); \ - builder.Set##flag(true); \ - auto style = builder.TakeStyle(); \ - EXPECT_TRUE(style->flag()); \ - auto other = InitialComputedStyle(); \ - EXPECT_FALSE(other->flag()); \ - EXPECT_EQ(ComputedStyle::Difference::inherited, \ - ComputedStyle::ComputeDifference(style.get(), other.get())); \ - auto diff = style->VisualInvalidationDiff(*document, *other); \ - EXPECT_TRUE(diff.HasDifference()); \ - EXPECT_TRUE(diff.CompositingReasonsChanged()); \ +#define TEST_ANIMATION_FLAG(flag, inherited) \ + do { \ + auto builder = CreateComputedStyleBuilder(); \ + builder.Set##flag(true); \ + const auto* style = builder.TakeStyle(); \ + EXPECT_TRUE(style->flag()); \ + const auto* other = InitialComputedStyle(); \ + EXPECT_FALSE(other->flag()); \ + EXPECT_EQ(ComputedStyle::Difference::inherited, \ + ComputedStyle::ComputeDifference(style, other)); \ + auto diff = style->VisualInvalidationDiff(*document, *other); \ + EXPECT_TRUE(diff.HasDifference()); \ + EXPECT_TRUE(diff.CompositingReasonsChanged()); \ } while (false) -#define TEST_ANIMATION_FLAG_NO_DIFF(flag) \ - do { \ - auto builder = CreateComputedStyleBuilder(); \ - builder.Set##flag(true); \ - auto style = builder.TakeStyle(); \ - EXPECT_TRUE(style->flag()); \ - auto other = InitialComputedStyle(); \ - EXPECT_FALSE(other->flag()); \ - EXPECT_EQ(ComputedStyle::Difference::kEqual, \ - ComputedStyle::ComputeDifference(style.get(), other.get())); \ - auto diff = style->VisualInvalidationDiff(*document, *other); \ - EXPECT_FALSE(diff.HasDifference()); \ - EXPECT_FALSE(diff.CompositingReasonsChanged()); \ +#define TEST_ANIMATION_FLAG_NO_DIFF(flag) \ + do { \ + auto builder = CreateComputedStyleBuilder(); \ + builder.Set##flag(true); \ + const auto* style = builder.TakeStyle(); \ + EXPECT_TRUE(style->flag()); \ + const auto* other = InitialComputedStyle(); \ + EXPECT_FALSE(other->flag()); \ + EXPECT_EQ(ComputedStyle::Difference::kEqual, \ + ComputedStyle::ComputeDifference(style, other)); \ + auto diff = style->VisualInvalidationDiff(*document, *other); \ + EXPECT_FALSE(diff.HasDifference()); \ + EXPECT_FALSE(diff.CompositingReasonsChanged()); \ } while (false) TEST_F(ComputedStyleTest, AnimationFlags) { @@ -597,9 +595,6 @@ css_test_helpers::RegisterProperty(dummy->GetDocument(), "--x", "<length>", "0px", false); - scoped_refptr<const ComputedStyle> style1; - scoped_refptr<const ComputedStyle> style2; - using UnitType = CSSPrimitiveValue::UnitType; const auto* value1 = CSSNumericLiteralValue::Create(1.0, UnitType::kPixels); @@ -611,11 +606,11 @@ ComputedStyleBuilder builder = CreateComputedStyleBuilder(); builder.SetVariableValue(AtomicString("--x"), value1, false); - style1 = builder.TakeStyle(); + const ComputedStyle* style1 = builder.TakeStyle(); builder = CreateComputedStyleBuilder(); builder.SetVariableValue(AtomicString("--x"), value1, false); - style2 = builder.TakeStyle(); + const ComputedStyle* style2 = builder.TakeStyle(); EXPECT_TRUE(style1->CustomPropertiesEqual(properties, *style2)); builder = CreateComputedStyleBuilder(); @@ -634,8 +629,8 @@ css_test_helpers::RegisterProperty(dummy->GetDocument(), "--x", "<length>", "0px", false); - scoped_refptr<const ComputedStyle> style1; - scoped_refptr<const ComputedStyle> style2; + const ComputedStyle* style1; + const ComputedStyle* style2; auto value1 = css_test_helpers::CreateVariableData("foo"); auto value2 = css_test_helpers::CreateVariableData("bar"); @@ -677,8 +672,8 @@ const auto* value1 = CSSNumericLiteralValue::Create(1.0, UnitType::kPixels); const auto* value2 = CSSNumericLiteralValue::Create(2.0, UnitType::kPixels); - scoped_refptr<const ComputedStyle> old_style = old_builder.TakeStyle(); - scoped_refptr<const ComputedStyle> new_style = new_builder.TakeStyle(); + const ComputedStyle* old_style = old_builder.TakeStyle(); + const ComputedStyle* new_style = new_builder.TakeStyle(); EXPECT_FALSE(old_style->HasVariableDeclaration()); EXPECT_FALSE(old_style->HasVariableReference()); EXPECT_FALSE(new_style->HasVariableReference()); @@ -689,7 +684,7 @@ old_builder.SetVariableValue(AtomicString("--x"), value1, true); old_style = old_builder.TakeStyle(); EXPECT_EQ(ComputedStyle::Difference::kIndependentInherited, - ComputedStyle::ComputeDifference(old_style.get(), new_style.get())); + ComputedStyle::ComputeDifference(old_style, new_style)); old_builder = CreateComputedStyleBuilder(); new_builder = CreateComputedStyleBuilder(); @@ -699,7 +694,7 @@ old_style = old_builder.TakeStyle(); new_style = new_builder.TakeStyle(); EXPECT_EQ(ComputedStyle::Difference::kIndependentInherited, - ComputedStyle::ComputeDifference(old_style.get(), new_style.get())); + ComputedStyle::ComputeDifference(old_style, new_style)); // Change value of variable old_builder = CreateComputedStyleBuilder(); @@ -712,7 +707,7 @@ EXPECT_FALSE(new_style->HasVariableDeclaration()); EXPECT_TRUE(new_style->HasVariableReference()); EXPECT_EQ(ComputedStyle::Difference::kIndependentInherited, - ComputedStyle::ComputeDifference(old_style.get(), new_style.get())); + ComputedStyle::ComputeDifference(old_style, new_style)); old_builder = CreateComputedStyleBuilder(); new_builder = CreateComputedStyleBuilder(); @@ -726,7 +721,7 @@ EXPECT_TRUE(new_style->HasVariableDeclaration()); EXPECT_FALSE(new_style->HasVariableReference()); EXPECT_EQ(ComputedStyle::Difference::kIndependentInherited, - ComputedStyle::ComputeDifference(old_style.get(), new_style.get())); + ComputedStyle::ComputeDifference(old_style, new_style)); old_builder = CreateComputedStyleBuilder(); new_builder = CreateComputedStyleBuilder(); @@ -741,7 +736,7 @@ EXPECT_TRUE(new_style->HasVariableDeclaration()); EXPECT_TRUE(new_style->HasVariableReference()); EXPECT_EQ(ComputedStyle::Difference::kIndependentInherited, - ComputedStyle::ComputeDifference(old_style.get(), new_style.get())); + ComputedStyle::ComputeDifference(old_style, new_style)); } TEST_F(ComputedStyleTest, CustomPropertiesInheritance_StyleRecalc) { @@ -757,8 +752,8 @@ const auto* value1 = CSSNumericLiteralValue::Create(1.0, UnitType::kPixels); const auto* value2 = CSSNumericLiteralValue::Create(2.0, UnitType::kPixels); - scoped_refptr<const ComputedStyle> old_style = old_builder.TakeStyle(); - scoped_refptr<const ComputedStyle> new_style = new_builder.TakeStyle(); + const ComputedStyle* old_style = old_builder.TakeStyle(); + const ComputedStyle* new_style = new_builder.TakeStyle(); EXPECT_FALSE(old_style->HasVariableDeclaration()); EXPECT_FALSE(old_style->HasVariableReference()); EXPECT_FALSE(new_style->HasVariableReference()); @@ -772,7 +767,7 @@ old_style = old_builder.TakeStyle(); EXPECT_TRUE(old_style->HasVariableReference()); EXPECT_EQ(ComputedStyle::Difference::kInherited, - ComputedStyle::ComputeDifference(old_style.get(), new_style.get())); + ComputedStyle::ComputeDifference(old_style, new_style)); old_builder = CreateComputedStyleBuilder(); new_builder = CreateComputedStyleBuilder(); @@ -785,7 +780,7 @@ new_style = new_builder.TakeStyle(); EXPECT_TRUE(old_style->HasVariableDeclaration()); EXPECT_EQ(ComputedStyle::Difference::kInherited, - ComputedStyle::ComputeDifference(old_style.get(), new_style.get())); + ComputedStyle::ComputeDifference(old_style, new_style)); old_builder = CreateComputedStyleBuilder(); new_builder = CreateComputedStyleBuilder(); @@ -799,7 +794,7 @@ new_style = new_builder.TakeStyle(); EXPECT_TRUE(old_style->HasVariableDeclaration()); EXPECT_EQ(ComputedStyle::Difference::kInherited, - ComputedStyle::ComputeDifference(old_style.get(), new_style.get())); + ComputedStyle::ComputeDifference(old_style, new_style)); old_builder = CreateComputedStyleBuilder(); new_builder = CreateComputedStyleBuilder(); @@ -813,14 +808,14 @@ new_style = new_builder.TakeStyle(); EXPECT_TRUE(old_style->HasVariableReference()); EXPECT_EQ(ComputedStyle::Difference::kInherited, - ComputedStyle::ComputeDifference(old_style.get(), new_style.get())); + ComputedStyle::ComputeDifference(old_style, new_style)); } TEST_F(ComputedStyleTest, ApplyColorSchemeLightOnDark) { std::unique_ptr<DummyPageHolder> dummy_page_holder = std::make_unique<DummyPageHolder>(gfx::Size(0, 0), nullptr); Document& document = dummy_page_holder->GetDocument(); - scoped_refptr<const ComputedStyle> initial = + const ComputedStyle* initial = document.GetStyleResolver().InitialStyleForElement(); ColorSchemeHelper color_scheme_helper(document); @@ -828,7 +823,7 @@ mojom::blink::PreferredColorScheme::kDark); StyleResolverState state(document, *document.documentElement(), nullptr /* StyleRecalcContext */, - StyleRequest(initial.get())); + StyleRequest(initial)); state.SetStyle(*initial); @@ -857,7 +852,7 @@ std::unique_ptr<DummyPageHolder> dummy_page_holder = std::make_unique<DummyPageHolder>(gfx::Size(0, 0), nullptr); Document& document = dummy_page_holder->GetDocument(); - scoped_refptr<const ComputedStyle> initial = + const ComputedStyle* initial = document.GetStyleResolver().InitialStyleForElement(); ColorSchemeHelper color_scheme_helper(document); @@ -865,7 +860,7 @@ mojom::blink::PreferredColorScheme::kDark); StyleResolverState state(document, *document.documentElement(), nullptr /* StyleRecalcContext */, - StyleRequest(initial.get())); + StyleRequest(initial)); state.SetStyle(*initial); @@ -886,7 +881,7 @@ cascade1.MutableMatchResult().AddMatchedProperties(dark_declaration, CascadeOrigin::kNone); cascade1.Apply(); - scoped_refptr<const ComputedStyle> style = state.StyleBuilder().CloneStyle(); + const ComputedStyle* style = state.StyleBuilder().CloneStyle(); EXPECT_EQ(Color::kWhite, style->VisitedDependentColor(GetCSSPropertyColor())); StyleCascade cascade2(state); @@ -905,7 +900,7 @@ std::unique_ptr<DummyPageHolder> dummy_page_holder = std::make_unique<DummyPageHolder>(gfx::Size(0, 0), nullptr); Document& document = dummy_page_holder->GetDocument(); - scoped_refptr<const ComputedStyle> initial = + const ComputedStyle* initial = document.GetStyleResolver().InitialStyleForElement(); ColorSchemeHelper color_scheme_helper(document); @@ -913,7 +908,7 @@ mojom::blink::PreferredColorScheme::kDark); StyleResolverState state(document, *document.documentElement(), nullptr /* StyleRecalcContext */, - StyleRequest(initial.get())); + StyleRequest(initial)); state.SetStyle(*initial); @@ -946,12 +941,12 @@ std::unique_ptr<DummyPageHolder> dummy_page_holder = std::make_unique<DummyPageHolder>(gfx::Size(0, 0), nullptr); Document& document = dummy_page_holder->GetDocument(); - scoped_refptr<const ComputedStyle> initial = + const ComputedStyle* initial = document.GetStyleResolver().InitialStyleForElement(); StyleResolverState state(document, *document.documentElement(), nullptr /* StyleRecalcContext */, - StyleRequest(initial.get())); + StyleRequest(initial)); state.SetStyle(*initial); state.StyleBuilder().SetEffectiveZoom(1.5); @@ -962,7 +957,7 @@ To<Longhand>(GetCSSPropertyStrokeWidth()) .ApplyValue(state, *calc_value, CSSProperty::ValueMode::kNormal); - scoped_refptr<const ComputedStyle> style = state.TakeStyle(); + const ComputedStyle* style = state.TakeStyle(); auto* computed_value = To<Longhand>(GetCSSPropertyStrokeWidth()) .CSSValueFromComputedStyleInternal( *style, nullptr /* layout_object */, @@ -972,7 +967,7 @@ } TEST_F(ComputedStyleTest, InitialVariableNamesEmpty) { - scoped_refptr<const ComputedStyle> style = InitialComputedStyle(); + const ComputedStyle* style = InitialComputedStyle(); EXPECT_TRUE(style->GetVariableNames().empty()); } @@ -990,7 +985,7 @@ builder.SetInitialData(StyleInitialData::Create( *Document::CreateForTest(execution_context.GetExecutionContext()), *registry)); - scoped_refptr<const ComputedStyle> style = builder.TakeStyle(); + const ComputedStyle* style = builder.TakeStyle(); EXPECT_EQ(2u, style->GetVariableNames().size()); EXPECT_TRUE(style->GetVariableNames().Contains("--x")); @@ -1006,7 +1001,7 @@ inherited); builder.SetVariableData(AtomicString("--b"), CreateVariableData("bar"), inherited); - scoped_refptr<const ComputedStyle> style = builder.TakeStyle(); + const ComputedStyle* style = builder.TakeStyle(); EXPECT_EQ(2u, style->GetVariableNames().size()); EXPECT_TRUE(style->GetVariableNames().Contains("--a")); @@ -1022,7 +1017,7 @@ !inherited); builder.SetVariableData(AtomicString("--b"), CreateVariableData("bar"), !inherited); - scoped_refptr<const ComputedStyle> style = builder.TakeStyle(); + const ComputedStyle* style = builder.TakeStyle(); EXPECT_EQ(2u, style->GetVariableNames().size()); EXPECT_TRUE(style->GetVariableNames().Contains("--a")); @@ -1042,7 +1037,7 @@ !inherited); builder.SetVariableData(AtomicString("--c"), CreateVariableData("baz"), !inherited); - scoped_refptr<const ComputedStyle> style = builder.TakeStyle(); + const ComputedStyle* style = builder.TakeStyle(); EXPECT_EQ(4u, style->GetVariableNames().size()); EXPECT_TRUE(style->GetVariableNames().Contains("--a")); @@ -1076,7 +1071,7 @@ !inherited); builder.SetVariableData(AtomicString("--c"), CreateVariableData("baz"), !inherited); - scoped_refptr<const ComputedStyle> style = builder.TakeStyle(); + const ComputedStyle* style = builder.TakeStyle(); EXPECT_EQ(5u, style->GetVariableNames().size()); EXPECT_TRUE(style->GetVariableNames().Contains("--a")); @@ -1087,7 +1082,7 @@ } TEST_F(ComputedStyleTest, GetVariableNamesCount_Invalidation) { - scoped_refptr<const ComputedStyle> style = InitialComputedStyle(); + const ComputedStyle* style = InitialComputedStyle(); EXPECT_EQ(style->GetVariableNamesCount(), 0u); auto data = css_test_helpers::CreateVariableData("foo"); @@ -1108,7 +1103,7 @@ } TEST_F(ComputedStyleTest, GetVariableNames_Invalidation) { - scoped_refptr<const ComputedStyle> style; + const ComputedStyle* style; auto data = css_test_helpers::CreateVariableData("foo"); ComputedStyleBuilder builder = CreateComputedStyleBuilder(); @@ -1136,7 +1131,7 @@ TEST_F(ComputedStyleTest, GetVariableNamesWithInitialData_Invalidation) { using css_test_helpers::CreateLengthRegistration; - scoped_refptr<const ComputedStyle> style; + const ComputedStyle* style; ScopedNullExecutionContext execution_context; { @@ -1487,7 +1482,7 @@ auto& animations = builder.AccessAnimations(); animations.DelayStartList().clear(); animations.DelayStartList().push_back(CSSAnimationData::InitialDelayStart()); - scoped_refptr<const ComputedStyle> style = builder.TakeStyle(); + const ComputedStyle* style = builder.TakeStyle(); EXPECT_EQ(1u, style->Animations()->DelayStartList().size()); builder = ComputedStyleBuilder(*style); @@ -1495,7 +1490,7 @@ EXPECT_EQ(1u, cloned_style_animations.DelayStartList().size()); cloned_style_animations.DelayStartList().push_back( CSSAnimationData::InitialDelayStart()); - scoped_refptr<const ComputedStyle> cloned_style = builder.TakeStyle(); + const ComputedStyle* cloned_style = builder.TakeStyle(); EXPECT_EQ(2u, cloned_style->Animations()->DelayStartList().size()); EXPECT_EQ(1u, style->Animations()->DelayStartList().size()); @@ -1507,7 +1502,7 @@ auto& transitions = builder.AccessTransitions(); transitions.PropertyList().clear(); transitions.PropertyList().push_back(CSSTransitionData::InitialProperty()); - scoped_refptr<const ComputedStyle> style = builder.TakeStyle(); + const ComputedStyle* style = builder.TakeStyle(); EXPECT_EQ(1u, style->Transitions()->PropertyList().size()); builder = ComputedStyleBuilder(*style); @@ -1515,7 +1510,7 @@ EXPECT_EQ(1u, cloned_style_transitions.PropertyList().size()); cloned_style_transitions.PropertyList().push_back( CSSTransitionData::InitialProperty()); - scoped_refptr<const ComputedStyle> cloned_style = builder.TakeStyle(); + const ComputedStyle* cloned_style = builder.TakeStyle(); EXPECT_EQ(2u, cloned_style->Transitions()->PropertyList().size()); EXPECT_EQ(1u, style->Transitions()->PropertyList().size()); @@ -1525,14 +1520,13 @@ std::unique_ptr<DummyPageHolder> dummy_page_holder = std::make_unique<DummyPageHolder>(gfx::Size(0, 0), nullptr); Document& document = dummy_page_holder->GetDocument(); - scoped_refptr<const ComputedStyle> initial = + const ComputedStyle* initial = document.GetStyleResolver().InitialStyleForElement(); StyleResolverState state(document, *document.documentElement(), nullptr /* StyleRecalcContext */, - StyleRequest(initial.get())); + StyleRequest(initial)); - scoped_refptr<const ComputedStyle> style = InitialComputedStyle(); state.SetStyle(*initial); EXPECT_FALSE(state.StyleBuilder().Animations()); EXPECT_FALSE(state.StyleBuilder().Transitions()); @@ -1543,18 +1537,18 @@ EXPECT_FALSE(state.StyleBuilder().Transitions()); } -#define TEST_STYLE_VALUE_NO_DIFF(field_name) \ - { \ - ComputedStyleBuilder builder1 = CreateComputedStyleBuilder(); \ - ComputedStyleBuilder builder2 = CreateComputedStyleBuilder(); \ - builder1.Set##field_name( \ - ComputedStyleInitialValues::Initial##field_name()); \ - builder2.Set##field_name( \ - ComputedStyleInitialValues::Initial##field_name()); \ - scoped_refptr<const ComputedStyle> style1 = builder1.TakeStyle(); \ - scoped_refptr<const ComputedStyle> style2 = builder2.TakeStyle(); \ - auto diff = style1->VisualInvalidationDiff(*document, *style2); \ - EXPECT_FALSE(diff.HasDifference()); \ +#define TEST_STYLE_VALUE_NO_DIFF(field_name) \ + { \ + ComputedStyleBuilder builder1 = CreateComputedStyleBuilder(); \ + ComputedStyleBuilder builder2 = CreateComputedStyleBuilder(); \ + builder1.Set##field_name( \ + ComputedStyleInitialValues::Initial##field_name()); \ + builder2.Set##field_name( \ + ComputedStyleInitialValues::Initial##field_name()); \ + const ComputedStyle* style1 = builder1.TakeStyle(); \ + const ComputedStyle* style2 = builder2.TakeStyle(); \ + auto diff = style1->VisualInvalidationDiff(*document, *style2); \ + EXPECT_FALSE(diff.HasDifference()); \ } // Ensures ref-counted values are compared by their values, not by pointers. @@ -1566,8 +1560,8 @@ scoped_refptr<type> value2 = base::MakeRefCounted<type>(value1->data); \ builder1.Set##field_name(value1); \ builder2.Set##field_name(value2); \ - scoped_refptr<const ComputedStyle> style1 = builder1.TakeStyle(); \ - scoped_refptr<const ComputedStyle> style2 = builder2.TakeStyle(); \ + const ComputedStyle* style1 = builder1.TakeStyle(); \ + const ComputedStyle* style2 = builder2.TakeStyle(); \ auto diff = style1->VisualInvalidationDiff(*document, *style2); \ EXPECT_FALSE(diff.HasDifference()); \ } @@ -1681,8 +1675,8 @@ builder1.SetWidth(Length(100.0, Length::kFixed)); builder2.SetWidth(Length(200.0, Length::kFixed)); - scoped_refptr<const ComputedStyle> style1 = builder1.TakeStyle(); - scoped_refptr<const ComputedStyle> style2 = builder2.TakeStyle(); + const ComputedStyle* style1 = builder1.TakeStyle(); + const ComputedStyle* style2 = builder2.TakeStyle(); EXPECT_EQ(0u, style1->DebugDiffFields(*style1).size()); EXPECT_EQ(0u, style2->DebugDiffFields(*style2).size()); @@ -1708,8 +1702,8 @@ builder1.SetForcesStackingContext(true); - scoped_refptr<const ComputedStyle> style1 = builder1.TakeStyle(); - scoped_refptr<const ComputedStyle> style2 = builder2.TakeStyle(); + const ComputedStyle* style1 = builder1.TakeStyle(); + const ComputedStyle* style2 = builder2.TakeStyle(); ASSERT_EQ(2u, style1->DebugDiffFields(*style2).size()); @@ -1728,8 +1722,8 @@ ComputedStyleBuilder builder1 = CreateComputedStyleBuilder(); ComputedStyleBuilder builder2 = CreateComputedStyleBuilder(); - scoped_refptr<const ComputedStyle> style1 = builder1.TakeStyle(); - scoped_refptr<const ComputedStyle> style2 = builder2.TakeStyle(); + const ComputedStyle* style1 = builder1.TakeStyle(); + const ComputedStyle* style2 = builder2.TakeStyle(); // Trigger lazy-evaluation of the field on *one* of the styles. EXPECT_FALSE(style1->IsStackingContextWithoutContainment()); @@ -1758,7 +1752,7 @@ builder.SetDirection(TextDirection::kLtr); builder.SetWritingMode(WritingMode::kHorizontalTb); - scoped_refptr<const ComputedStyle> style = builder.TakeStyle(); + const ComputedStyle* style = builder.TakeStyle(); EXPECT_EQ(left, style->ScrollPaddingInlineStart()); EXPECT_EQ(right, style->ScrollPaddingInlineEnd()); EXPECT_EQ(top, style->ScrollPaddingBlockStart()); @@ -1813,7 +1807,7 @@ } TEST_F(ComputedStyleTest, BasicBuilder) { - scoped_refptr<const ComputedStyle> original = InitialComputedStyle(); + const ComputedStyle* original = InitialComputedStyle(); Length left = Length::Fixed(1.0f); Length right = Length::Fixed(2.0f); @@ -1822,7 +1816,7 @@ builder.SetScrollPaddingLeft(left); builder.SetScrollPaddingRight(right); - scoped_refptr<const ComputedStyle> style = builder.TakeStyle(); + const ComputedStyle* style = builder.TakeStyle(); EXPECT_NE(left, original->ScrollPaddingLeft()); EXPECT_NE(right, original->ScrollPaddingRight()); @@ -1839,9 +1833,7 @@ ComputedStyleBuilder builder2(std::move(builder1)); - EXPECT_FALSE(builder1.TakeStyle()); - - scoped_refptr<const ComputedStyle> style2 = builder2.TakeStyle(); + const ComputedStyle* style2 = builder2.TakeStyle(); ASSERT_TRUE(style2); EXPECT_EQ(one, style2->ScrollPaddingLeft()); } @@ -1855,9 +1847,7 @@ ComputedStyleBuilder builder2(*InitialComputedStyle()); builder2 = std::move(builder1); - EXPECT_FALSE(builder1.TakeStyle()); - - scoped_refptr<const ComputedStyle> style2 = builder2.TakeStyle(); + const ComputedStyle* style2 = builder2.TakeStyle(); ASSERT_TRUE(style2); EXPECT_EQ(one, style2->ScrollPaddingLeft()); } @@ -1875,11 +1865,11 @@ 1u, MakeGarbageCollected<ScopedCSSName>(AtomicString("test"), /* tree_scope */ nullptr)))); - scoped_refptr<const ComputedStyle> style1 = builder1.TakeStyle(); - scoped_refptr<const ComputedStyle> style2 = builder2.TakeStyle(); + const ComputedStyle* style1 = builder1.TakeStyle(); + const ComputedStyle* style2 = builder2.TakeStyle(); EXPECT_EQ(ComputedStyle::Difference::kEqual, - ComputedStyle::ComputeDifference(style1.get(), style2.get())); + ComputedStyle::ComputeDifference(style1, style2)); } TEST_F(ComputedStyleTest, ScrollTimelineAxisNoDiff) { @@ -1889,11 +1879,11 @@ builder1.SetScrollTimelineAxis(Vector<TimelineAxis>(1u, TimelineAxis::kY)); builder2.SetScrollTimelineAxis(Vector<TimelineAxis>(1u, TimelineAxis::kY)); - scoped_refptr<const ComputedStyle> style1 = builder1.TakeStyle(); - scoped_refptr<const ComputedStyle> style2 = builder2.TakeStyle(); + const ComputedStyle* style1 = builder1.TakeStyle(); + const ComputedStyle* style2 = builder2.TakeStyle(); EXPECT_EQ(ComputedStyle::Difference::kEqual, - ComputedStyle::ComputeDifference(style1.get(), style2.get())); + ComputedStyle::ComputeDifference(style1, style2)); } TEST_F(ComputedStyleTest, ViewTimelineNameNoDiff) { @@ -1909,11 +1899,11 @@ 1u, MakeGarbageCollected<ScopedCSSName>(AtomicString("test"), /* tree_scope */ nullptr)))); - scoped_refptr<const ComputedStyle> style1 = builder1.TakeStyle(); - scoped_refptr<const ComputedStyle> style2 = builder2.TakeStyle(); + const ComputedStyle* style1 = builder1.TakeStyle(); + const ComputedStyle* style2 = builder2.TakeStyle(); EXPECT_EQ(ComputedStyle::Difference::kEqual, - ComputedStyle::ComputeDifference(style1.get(), style2.get())); + ComputedStyle::ComputeDifference(style1, style2)); } TEST_F(ComputedStyleTest, ViewTimelineAxisNoDiff) { @@ -1923,11 +1913,11 @@ builder1.SetViewTimelineAxis(Vector<TimelineAxis>(1u, TimelineAxis::kY)); builder2.SetViewTimelineAxis(Vector<TimelineAxis>(1u, TimelineAxis::kY)); - scoped_refptr<const ComputedStyle> style1 = builder1.TakeStyle(); - scoped_refptr<const ComputedStyle> style2 = builder2.TakeStyle(); + const ComputedStyle* style1 = builder1.TakeStyle(); + const ComputedStyle* style2 = builder2.TakeStyle(); EXPECT_EQ(ComputedStyle::Difference::kEqual, - ComputedStyle::ComputeDifference(style1.get(), style2.get())); + ComputedStyle::ComputeDifference(style1, style2)); } TEST_F(ComputedStyleTest, ViewTimelineInsetNoDiff) { @@ -1939,11 +1929,11 @@ builder2.SetViewTimelineInset(Vector<TimelineInset>( 1u, TimelineInset(Length::Fixed(1.0f), Length::Fixed(1.0f)))); - scoped_refptr<const ComputedStyle> style1 = builder1.TakeStyle(); - scoped_refptr<const ComputedStyle> style2 = builder2.TakeStyle(); + const ComputedStyle* style1 = builder1.TakeStyle(); + const ComputedStyle* style2 = builder2.TakeStyle(); EXPECT_EQ(ComputedStyle::Difference::kEqual, - ComputedStyle::ComputeDifference(style1.get(), style2.get())); + ComputedStyle::ComputeDifference(style1, style2)); } TEST_F(ComputedStyleTest, ContainerNameNoDiff) { @@ -1961,11 +1951,11 @@ /* tree_scope */ nullptr)))); builder2.SetContainerType(kContainerTypeSize); - scoped_refptr<const ComputedStyle> style1 = builder1.TakeStyle(); - scoped_refptr<const ComputedStyle> style2 = builder2.TakeStyle(); + const ComputedStyle* style1 = builder1.TakeStyle(); + const ComputedStyle* style2 = builder2.TakeStyle(); EXPECT_EQ(ComputedStyle::Difference::kEqual, - ComputedStyle::ComputeDifference(style1.get(), style2.get())); + ComputedStyle::ComputeDifference(style1, style2)); } } // namespace blink
diff --git a/third_party/blink/renderer/core/style/data_ref.h b/third_party/blink/renderer/core/style/data_ref.h index 2a1782b0..72e29c6 100644 --- a/third_party/blink/renderer/core/style/data_ref.h +++ b/third_party/blink/renderer/core/style/data_ref.h
@@ -24,19 +24,18 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_DATA_REF_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_DATA_REF_H_ -#include "base/memory/scoped_refptr.h" #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" namespace blink { template <typename T> class DataRef { - USING_FAST_MALLOC(DataRef); + DISALLOW_NEW(); public: - explicit DataRef(scoped_refptr<T>&& data) : data_(data) {} + explicit DataRef(T* data) : data_(data) {} - const T* Get() const { return data_.get(); } + const T* Get() const { return data_.Get(); } const T& operator*() const { return *Get(); } const T* operator->() const { return Get(); } @@ -46,7 +45,7 @@ access_flag = true; data_ = data_->Copy(); } - return data_.get(); + return data_.Get(); } bool operator==(const DataRef<T>& o) const { @@ -63,8 +62,12 @@ void operator=(std::nullptr_t) { data_ = nullptr; } + void Trace(Visitor* visitor) const { visitor->Trace(data_); } + private: - scoped_refptr<T> data_; + // These ComputedStyle sub-objects are heavily inlined, and on relatively hot + // codepaths. Disable pointer-compression. + subtle::UncompressedMember<T> data_; }; } // namespace blink
diff --git a/third_party/blink/renderer/core/style/fill_layer.cc b/third_party/blink/renderer/core/style/fill_layer.cc index 2591edc8..2698335 100644 --- a/third_party/blink/renderer/core/style/fill_layer.cc +++ b/third_party/blink/renderer/core/style/fill_layer.cc
@@ -30,9 +30,8 @@ namespace blink { struct SameSizeAsFillLayer { - FillLayer* next_; - - Persistent<StyleImage> image_; + Member<FillLayerWrapper> next_; + Member<StyleImage> image_; Length position_x_; Length position_y_; @@ -88,7 +87,8 @@ cached_properties_computed_(false) {} FillLayer::FillLayer(const FillLayer& o) - : next_(o.next_ ? new FillLayer(*o.next_) : nullptr), + : next_(o.next_ ? MakeGarbageCollected<FillLayerWrapper>(*o.next_) + : nullptr), image_(o.image_), position_x_(o.position_x_), position_y_(o.position_y_), @@ -125,14 +125,15 @@ any_layer_has_default_attachment_image_(false), cached_properties_computed_(false) {} -FillLayer::~FillLayer() { - delete next_; +void FillLayer::Trace(Visitor* visitor) const { + visitor->Trace(next_); + visitor->Trace(image_); } FillLayer& FillLayer::operator=(const FillLayer& o) { if (next_ != o.next_) { - delete next_; - next_ = o.next_ ? new FillLayer(*o.next_) : nullptr; + next_ = + o.next_ ? MakeGarbageCollected<FillLayerWrapper>(*o.next_) : nullptr; } image_ = o.image_; @@ -184,7 +185,7 @@ bool FillLayer::operator==(const FillLayer& o) const { return LayerPropertiesEqual(o) && - ((next_ && o.next_) ? *next_ == *o.next_ : next_ == o.next_); + ((Next() && o.Next()) ? *Next() == *o.Next() : Next() == o.Next()); } bool FillLayer::VisuallyEqual(const FillLayer& o) const { @@ -196,7 +197,7 @@ return false; } if (next_ && o.next_) { - return next_->VisuallyEqual(*o.next_); + return next_->layer.VisuallyEqual(o.next_->layer); } return next_ == o.next_; } @@ -350,9 +351,8 @@ void FillLayer::CullEmptyLayers() { FillLayer* next; for (FillLayer* p = this; p; p = next) { - next = p->next_; + next = p->Next(); if (next && !next->IsImageSet()) { - delete next; p->next_ = nullptr; break; } @@ -378,19 +378,19 @@ To<StyleGeneratedImage>(image_.Get())->IsUsingCurrentColor()); cached_properties_computed_ = true; - if (next_) { - next_->ComputeCachedPropertiesIfNeeded(); + if (auto* next = Next()) { + next->ComputeCachedPropertiesIfNeeded(); layers_clip_max_ = static_cast<unsigned>( - EnclosingFillBox(LayersClipMax(), next_->LayersClipMax())); - any_layer_uses_content_box_ |= next_->any_layer_uses_content_box_; - any_layer_has_image_ |= next_->any_layer_has_image_; - any_layer_has_url_image_ |= next_->any_layer_has_url_image_; - any_layer_has_local_attachment_ |= next_->any_layer_has_local_attachment_; + EnclosingFillBox(LayersClipMax(), next->LayersClipMax())); + any_layer_uses_content_box_ |= next->any_layer_uses_content_box_; + any_layer_has_image_ |= next->any_layer_has_image_; + any_layer_has_url_image_ |= next->any_layer_has_url_image_; + any_layer_has_local_attachment_ |= next->any_layer_has_local_attachment_; any_layer_has_fixed_attachment_image_ |= - next_->any_layer_has_fixed_attachment_image_; + next->any_layer_has_fixed_attachment_image_; any_layer_has_default_attachment_image_ |= - next_->any_layer_has_default_attachment_image_; - any_layer_uses_current_color_ |= next_->any_layer_uses_current_color_; + next->any_layer_has_default_attachment_image_; + any_layer_uses_current_color_ |= next->any_layer_uses_current_color_; } }
diff --git a/third_party/blink/renderer/core/style/fill_layer.h b/third_party/blink/renderer/core/style/fill_layer.h index 883abec2..4f2c024e 100644 --- a/third_party/blink/renderer/core/style/fill_layer.h +++ b/third_party/blink/renderer/core/style/fill_layer.h
@@ -32,6 +32,7 @@ #include "third_party/blink/renderer/platform/geometry/length.h" #include "third_party/blink/renderer/platform/geometry/length_size.h" #include "third_party/blink/renderer/platform/graphics/graphics_types.h" +#include "third_party/blink/renderer/platform/heap/member.h" #include "third_party/blink/renderer/platform/heap/persistent.h" #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" @@ -52,13 +53,15 @@ LengthSize size; }; -// FIXME(Oilpan): Move FillLayer to Oilpan's heap. +class FillLayerWrapper; + class CORE_EXPORT FillLayer { - USING_FAST_MALLOC(FillLayer); + DISALLOW_NEW(); public: - FillLayer(EFillLayerType, bool use_initial_values = false); - ~FillLayer(); + explicit FillLayer(EFillLayerType, bool use_initial_values = false); + + void Trace(Visitor* visitor) const; StyleImage* GetImage() const { return image_.Get(); } const Length& PositionX() const { return position_x_; } @@ -88,14 +91,9 @@ return FillSize(static_cast<EFillSizeType>(size_type_), size_length_); } - const FillLayer* Next() const { return next_; } - FillLayer* Next() { return next_; } - FillLayer* EnsureNext() { - if (!next_) { - next_ = new FillLayer(GetType()); - } - return next_; - } + const FillLayer* Next() const; + FillLayer* Next(); + FillLayer* EnsureNext(); bool IsImageSet() const { return image_set_; } bool IsPositionXSet() const { return pos_x_set_; } @@ -307,9 +305,8 @@ } void ComputeCachedProperties() const; - FillLayer* next_; - - Persistent<StyleImage> image_; + Member<FillLayerWrapper> next_; + Member<StyleImage> image_; Length position_x_; Length position_y_; @@ -364,6 +361,27 @@ mutable unsigned cached_properties_computed_ : 1; }; +class FillLayerWrapper : public GarbageCollected<FillLayerWrapper> { + public: + explicit FillLayerWrapper(EFillLayerType type) : layer(type) {} + + void Trace(Visitor* visitor) const { visitor->Trace(layer); } + FillLayer layer; +}; + +inline const FillLayer* FillLayer::Next() const { + return next_ ? &next_->layer : nullptr; +} +inline FillLayer* FillLayer::Next() { + return next_ ? &next_->layer : nullptr; +} +inline FillLayer* FillLayer::EnsureNext() { + if (!next_) { + next_ = MakeGarbageCollected<FillLayerWrapper>(GetType()); + } + return &next_->layer; +} + } // namespace blink #endif // THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_FILL_LAYER_H_
diff --git a/third_party/blink/renderer/core/style/list_style_type_data.h b/third_party/blink/renderer/core/style/list_style_type_data.h index 4bef084f..5e0cac5 100644 --- a/third_party/blink/renderer/core/style/list_style_type_data.h +++ b/third_party/blink/renderer/core/style/list_style_type_data.h
@@ -6,6 +6,7 @@ #define THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_LIST_STYLE_TYPE_DATA_H_ #include "base/check_op.h" +#include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/style/computed_style_constants.h" #include "third_party/blink/renderer/platform/heap/garbage_collected.h" #include "third_party/blink/renderer/platform/heap/member.h" @@ -20,7 +21,7 @@ class ListStyleTypeData final : public GarbageCollected<ListStyleTypeData> { public: ~ListStyleTypeData() = default; - void Trace(Visitor*) const; + CORE_EXPORT void Trace(Visitor*) const; enum class Type { kCounterStyle, kString };
diff --git a/third_party/blink/renderer/core/style/member_copy.h b/third_party/blink/renderer/core/style/member_copy.h index 6ec461e..86ad5ad3 100644 --- a/third_party/blink/renderer/core/style/member_copy.h +++ b/third_party/blink/renderer/core/style/member_copy.h
@@ -9,7 +9,6 @@ #include "base/memory/scoped_refptr.h" #include "third_party/blink/renderer/core/style/content_data.h" #include "third_party/blink/renderer/core/style/data_ref.h" -#include "third_party/blink/renderer/core/style/style_filter_data.h" #include "third_party/blink/renderer/platform/heap/persistent.h" namespace blink { @@ -20,7 +19,7 @@ } template <typename T> -Persistent<T> MemberCopy(const Persistent<T>& v) { +Member<T> MemberCopy(const Member<T>& v) { return v; } @@ -29,15 +28,10 @@ return v ? v->Clone() : nullptr; } -inline Persistent<ContentData> MemberCopy(const Persistent<ContentData>& v) { +inline Member<ContentData> MemberCopy(const Member<ContentData>& v) { return v ? v->Clone() : nullptr; } -inline Persistent<StyleFilterData> MemberCopy( - const Persistent<StyleFilterData>& v) { - return v->Copy(); -} - } // namespace blink #endif // THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_MEMBER_COPY_H_
diff --git a/third_party/blink/renderer/core/style/style_base_data.cc b/third_party/blink/renderer/core/style/style_base_data.cc index 9db06b9..afda4a7 100644 --- a/third_party/blink/renderer/core/style/style_base_data.cc +++ b/third_party/blink/renderer/core/style/style_base_data.cc
@@ -7,7 +7,7 @@ namespace blink { -StyleBaseData::StyleBaseData(scoped_refptr<const ComputedStyle> style, +StyleBaseData::StyleBaseData(const ComputedStyle* style, std::unique_ptr<CSSBitset> set) : computed_style_(style), important_set_(std::move(set)) {}
diff --git a/third_party/blink/renderer/core/style/style_base_data.h b/third_party/blink/renderer/core/style/style_base_data.h index 8b38973..02c8945 100644 --- a/third_party/blink/renderer/core/style/style_base_data.h +++ b/third_party/blink/renderer/core/style/style_base_data.h
@@ -7,6 +7,9 @@ #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/css/properties/css_bitset.h" +#include "third_party/blink/renderer/platform/heap/garbage_collected.h" +#include "third_party/blink/renderer/platform/heap/member.h" +#include "third_party/blink/renderer/platform/heap/visitor.h" #include "third_party/blink/renderer/platform/wtf/forward.h" #include "third_party/blink/renderer/platform/wtf/ref_counted.h" @@ -14,25 +17,23 @@ class ComputedStyle; -class CORE_EXPORT StyleBaseData : public RefCounted<StyleBaseData> { - USING_FAST_MALLOC(StyleBaseData); - +class CORE_EXPORT StyleBaseData : public GarbageCollected<StyleBaseData> { public: - static scoped_refptr<StyleBaseData> Create( - scoped_refptr<const ComputedStyle> style, - std::unique_ptr<CSSBitset> important_set) { - return base::AdoptRef(new StyleBaseData(style, std::move(important_set))); + static StyleBaseData* Create(const ComputedStyle* style, + std::unique_ptr<CSSBitset> important_set) { + return MakeGarbageCollected<StyleBaseData>(style, std::move(important_set)); } + StyleBaseData(const ComputedStyle*, std::unique_ptr<CSSBitset>); const ComputedStyle* GetBaseComputedStyle() const { - return computed_style_.get(); + return computed_style_.Get(); } const CSSBitset* GetBaseImportantSet() const { return important_set_.get(); } - private: - StyleBaseData(scoped_refptr<const ComputedStyle>, std::unique_ptr<CSSBitset>); + void Trace(Visitor* visitor) const { visitor->Trace(computed_style_); } - scoped_refptr<const ComputedStyle> computed_style_; + private: + Member<const ComputedStyle> computed_style_; // Keeps track of the !important declarations used to build the base // computed style. These declarations must not be overwritten by animation
diff --git a/third_party/blink/renderer/core/style/style_cached_data.h b/third_party/blink/renderer/core/style/style_cached_data.h index 43de9f1e..d29988d 100644 --- a/third_party/blink/renderer/core/style/style_cached_data.h +++ b/third_party/blink/renderer/core/style/style_cached_data.h
@@ -13,10 +13,17 @@ class ComputedStyle; -using PositionFallbackStyleCache = Vector<scoped_refptr<const ComputedStyle>>; -using PseudoElementStyleCache = Vector<scoped_refptr<const ComputedStyle>, 4>; +using PositionFallbackStyleCache = HeapVector<Member<const ComputedStyle>>; +using PseudoElementStyleCache = HeapVector<Member<const ComputedStyle>, 4>; -class CORE_EXPORT StyleCachedData final { +class CORE_EXPORT StyleCachedData final + : public GarbageCollected<StyleCachedData> { + public: + void Trace(Visitor* visitor) const { + visitor->Trace(pseudo_element_styles_); + visitor->Trace(position_fallback_styles_); + } + private: friend class ComputedStyle; friend class ComputedStyleBuilder; @@ -39,13 +46,13 @@ // <script> // getComputedStyle(div, "::before").color // still green. // </script> - std::unique_ptr<PseudoElementStyleCache> pseudo_element_styles_; + Member<PseudoElementStyleCache> pseudo_element_styles_; // This cache stores the ComputedStyles for an anchor-positioned element after // applying each @try block in the @position-fallback rule. Note that this is // not the computed style of any element, but used when laying out an // anchor-positioned element with fallback positions only. - std::unique_ptr<PositionFallbackStyleCache> position_fallback_styles_; + Member<PositionFallbackStyleCache> position_fallback_styles_; // Stores the names of of all custom properties on a given ComputedStyle. std::unique_ptr<Vector<AtomicString>> variable_names_;
diff --git a/third_party/blink/renderer/core/style/style_filter_data.cc b/third_party/blink/renderer/core/style/style_filter_data.cc deleted file mode 100644 index 9468cfe..0000000 --- a/third_party/blink/renderer/core/style/style_filter_data.cc +++ /dev/null
@@ -1,39 +0,0 @@ -/* - * Copyright (C) 2011 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "third_party/blink/renderer/core/style/style_filter_data.h" - -namespace blink { - -StyleFilterData::StyleFilterData() : operations_() {} - -StyleFilterData::StyleFilterData(const StyleFilterData& o) - : operations_(o.operations_) {} - -bool StyleFilterData::operator==(const StyleFilterData& o) const { - return operations_ == o.operations_; -} - -} // namespace blink
diff --git a/third_party/blink/renderer/core/style/style_filter_data.h b/third_party/blink/renderer/core/style/style_filter_data.h deleted file mode 100644 index 5ba02b6..0000000 --- a/third_party/blink/renderer/core/style/style_filter_data.h +++ /dev/null
@@ -1,60 +0,0 @@ -/* - * Copyright (C) 2011 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_STYLE_FILTER_DATA_H_ -#define THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_STYLE_FILTER_DATA_H_ - -#include "third_party/blink/renderer/core/style/filter_operations.h" -#include "third_party/blink/renderer/platform/heap/garbage_collected.h" - -#include <iosfwd> - -namespace blink { - -class StyleFilterData final : public GarbageCollected<StyleFilterData> { - public: - StyleFilterData(); - explicit StyleFilterData(const StyleFilterData&); - - StyleFilterData* Copy() const { - return MakeGarbageCollected<StyleFilterData>(*this); - } - - bool operator==(const StyleFilterData&) const; - bool operator!=(const StyleFilterData& o) const { return !(*this == o); } - - void Trace(Visitor* visitor) const { visitor->Trace(operations_); } - - FilterOperations operations_; -}; - -inline std::ostream& operator<<(std::ostream& stream, - const StyleFilterData& style_filter_data) { - return stream << style_filter_data.operations_; -} - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_STYLE_FILTER_DATA_H_
diff --git a/third_party/blink/renderer/core/style/style_highlight_data.cc b/third_party/blink/renderer/core/style/style_highlight_data.cc index afa8ad1..3c7ff0a 100644 --- a/third_party/blink/renderer/core/style/style_highlight_data.cc +++ b/third_party/blink/renderer/core/style/style_highlight_data.cc
@@ -9,22 +9,6 @@ namespace blink { -scoped_refptr<StyleHighlightData> StyleHighlightData::Create() { - return base::AdoptRef(new StyleHighlightData); -} -scoped_refptr<StyleHighlightData> StyleHighlightData::Copy() const { - return base::AdoptRef(new StyleHighlightData(*this)); -} - -StyleHighlightData::StyleHighlightData() = default; - -StyleHighlightData::StyleHighlightData(const StyleHighlightData& other) - : selection_(other.selection_), - target_text_(other.target_text_), - spelling_error_(other.spelling_error_), - grammar_error_(other.grammar_error_), - custom_highlights_(other.custom_highlights_) {} - // Compares two CustomHighlightsStyleMaps with base::ValuesEquivalent as // comparison function on the values. bool HighlightStyleMapEquals(const CustomHighlightsStyleMap& a, @@ -76,19 +60,19 @@ } const ComputedStyle* StyleHighlightData::Selection() const { - return selection_.get(); + return selection_.Get(); } const ComputedStyle* StyleHighlightData::TargetText() const { - return target_text_.get(); + return target_text_.Get(); } const ComputedStyle* StyleHighlightData::SpellingError() const { - return spelling_error_.get(); + return spelling_error_.Get(); } const ComputedStyle* StyleHighlightData::GrammarError() const { - return grammar_error_.get(); + return grammar_error_.Get(); } const ComputedStyle* StyleHighlightData::CustomHighlight( @@ -96,37 +80,40 @@ if (highlight_name) { auto iter = custom_highlights_.find(highlight_name); if (iter != custom_highlights_.end()) { - return iter->value.get(); + return iter->value.Get(); } } return nullptr; } -void StyleHighlightData::SetSelection( - scoped_refptr<const ComputedStyle>&& style) { - selection_ = std::move(style); +void StyleHighlightData::SetSelection(const ComputedStyle* style) { + selection_ = style; } -void StyleHighlightData::SetTargetText( - scoped_refptr<const ComputedStyle>&& style) { - target_text_ = std::move(style); +void StyleHighlightData::SetTargetText(const ComputedStyle* style) { + target_text_ = style; } -void StyleHighlightData::SetSpellingError( - scoped_refptr<const ComputedStyle>&& style) { - spelling_error_ = std::move(style); +void StyleHighlightData::SetSpellingError(const ComputedStyle* style) { + spelling_error_ = style; } -void StyleHighlightData::SetGrammarError( - scoped_refptr<const ComputedStyle>&& style) { - grammar_error_ = std::move(style); +void StyleHighlightData::SetGrammarError(const ComputedStyle* style) { + grammar_error_ = style; } -void StyleHighlightData::SetCustomHighlight( - const AtomicString& highlight_name, - scoped_refptr<const ComputedStyle>&& style) { +void StyleHighlightData::SetCustomHighlight(const AtomicString& highlight_name, + const ComputedStyle* style) { DCHECK(highlight_name); - custom_highlights_.Set(highlight_name, std::move(style)); + custom_highlights_.Set(highlight_name, style); +} + +void StyleHighlightData::Trace(Visitor* visitor) const { + visitor->Trace(selection_); + visitor->Trace(target_text_); + visitor->Trace(spelling_error_); + visitor->Trace(grammar_error_); + visitor->Trace(custom_highlights_); } } // namespace blink
diff --git a/third_party/blink/renderer/core/style/style_highlight_data.h b/third_party/blink/renderer/core/style/style_highlight_data.h index 433fcd17b..b6a80cf 100644 --- a/third_party/blink/renderer/core/style/style_highlight_data.h +++ b/third_party/blink/renderer/core/style/style_highlight_data.h
@@ -9,6 +9,8 @@ #include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/style/computed_style_constants.h" +#include "third_party/blink/renderer/platform/heap/collection_support/heap_hash_map.h" +#include "third_party/blink/renderer/platform/heap/member.h" #include "third_party/blink/renderer/platform/wtf/hash_map.h" #include "third_party/blink/renderer/platform/wtf/ref_counted.h" #include "third_party/blink/renderer/platform/wtf/text/atomic_string.h" @@ -18,18 +20,12 @@ class ComputedStyle; using CustomHighlightsStyleMap = - HashMap<AtomicString, scoped_refptr<const ComputedStyle>>; + HeapHashMap<AtomicString, Member<const ComputedStyle>>; -class CORE_EXPORT StyleHighlightData final - : public RefCounted<StyleHighlightData> { +class CORE_EXPORT StyleHighlightData final { + DISALLOW_NEW(); + public: - StyleHighlightData(StyleHighlightData&& other) = delete; - StyleHighlightData& operator=(const StyleHighlightData& other) = delete; - StyleHighlightData& operator=(StyleHighlightData&& other) = delete; - - static scoped_refptr<StyleHighlightData> Create(); - scoped_refptr<StyleHighlightData> Copy() const; - bool operator==(const StyleHighlightData&) const; const ComputedStyle* Style( @@ -43,21 +39,19 @@ const CustomHighlightsStyleMap& CustomHighlights() const { return custom_highlights_; } - void SetSelection(scoped_refptr<const ComputedStyle>&&); - void SetTargetText(scoped_refptr<const ComputedStyle>&&); - void SetSpellingError(scoped_refptr<const ComputedStyle>&&); - void SetGrammarError(scoped_refptr<const ComputedStyle>&&); - void SetCustomHighlight(const AtomicString&, - scoped_refptr<const ComputedStyle>&&); + void SetSelection(const ComputedStyle*); + void SetTargetText(const ComputedStyle*); + void SetSpellingError(const ComputedStyle*); + void SetGrammarError(const ComputedStyle*); + void SetCustomHighlight(const AtomicString&, const ComputedStyle*); + + void Trace(Visitor*) const; private: - StyleHighlightData(); - StyleHighlightData(const StyleHighlightData& other); - - scoped_refptr<const ComputedStyle> selection_; - scoped_refptr<const ComputedStyle> target_text_; - scoped_refptr<const ComputedStyle> spelling_error_; - scoped_refptr<const ComputedStyle> grammar_error_; + Member<const ComputedStyle> selection_; + Member<const ComputedStyle> target_text_; + Member<const ComputedStyle> spelling_error_; + Member<const ComputedStyle> grammar_error_; CustomHighlightsStyleMap custom_highlights_; };
diff --git a/third_party/blink/renderer/core/svg/svg_element.cc b/third_party/blink/renderer/core/svg/svg_element.cc index dcec4d8..7aa8b69 100644 --- a/third_party/blink/renderer/core/svg/svg_element.cc +++ b/third_party/blink/renderer/core/svg/svg_element.cc
@@ -1059,7 +1059,7 @@ // attributes that didn't change. } -scoped_refptr<const ComputedStyle> SVGElement::CustomStyleForLayoutObject( +const ComputedStyle* SVGElement::CustomStyleForLayoutObject( const StyleRecalcContext& style_recalc_context) { SVGElement* corresponding_element = CorrespondingElement(); if (!corresponding_element) {
diff --git a/third_party/blink/renderer/core/svg/svg_element.h b/third_party/blink/renderer/core/svg/svg_element.h index 3b0240b..36802ac 100644 --- a/third_party/blink/renderer/core/svg/svg_element.h +++ b/third_party/blink/renderer/core/svg/svg_element.h
@@ -170,7 +170,7 @@ void CollectExtraStyleForPresentationAttribute( MutableCSSPropertyValueSet*) override; - scoped_refptr<const ComputedStyle> CustomStyleForLayoutObject( + const ComputedStyle* CustomStyleForLayoutObject( const StyleRecalcContext&) final; bool LayoutObjectIsNeeded(const DisplayStyle&) const override;
diff --git a/third_party/blink/renderer/core/svg/svg_element_rare_data.cc b/third_party/blink/renderer/core/svg/svg_element_rare_data.cc index ca9bbbe..d879e559 100644 --- a/third_party/blink/renderer/core/svg/svg_element_rare_data.cc +++ b/third_party/blink/renderer/core/svg/svg_element_rare_data.cc
@@ -53,7 +53,7 @@ needs_override_computed_style_update_ = false; } DCHECK(override_computed_style_); - return override_computed_style_.get(); + return override_computed_style_.Get(); } void SVGElementRareData::ClearOverriddenComputedStyle() { @@ -71,6 +71,7 @@ visitor->Trace(outgoing_references_); visitor->Trace(incoming_references_); visitor->Trace(animated_smil_style_properties_); + visitor->Trace(override_computed_style_); visitor->Trace(element_instances_); visitor->Trace(corresponding_element_); visitor->Trace(resource_client_);
diff --git a/third_party/blink/renderer/core/svg/svg_element_rare_data.h b/third_party/blink/renderer/core/svg/svg_element_rare_data.h index eb13b0c..ae3838b 100644 --- a/third_party/blink/renderer/core/svg/svg_element_rare_data.h +++ b/third_party/blink/renderer/core/svg/svg_element_rare_data.h
@@ -115,7 +115,7 @@ bool web_animated_attributes_dirty_ : 1; HashSet<QualifiedName> web_animated_attributes_; Member<MutableCSSPropertyValueSet> animated_smil_style_properties_; - scoped_refptr<const ComputedStyle> override_computed_style_; + Member<const ComputedStyle> override_computed_style_; // Used by <animateMotion> AffineTransform animate_motion_transform_; };
diff --git a/third_party/blink/renderer/core/testing/internals.cc b/third_party/blink/renderer/core/testing/internals.cc index de67f86..cc490b81 100644 --- a/third_party/blink/renderer/core/testing/internals.cc +++ b/third_party/blink/renderer/core/testing/internals.cc
@@ -2547,7 +2547,7 @@ DCHECK(document); // Named pages aren't supported here, because this function may be called // without laying out first. - scoped_refptr<const ComputedStyle> style = + const ComputedStyle* style = document->StyleForPage(page_number, /* page_name */ AtomicString()); return style->Visibility() != EVisibility::kHidden; // display property doesn't apply to @page.
diff --git a/third_party/blink/renderer/core/view_transition/view_transition_pseudo_element_base.cc b/third_party/blink/renderer/core/view_transition/view_transition_pseudo_element_base.cc index 151ab7a9..84c0599 100644 --- a/third_party/blink/renderer/core/view_transition/view_transition_pseudo_element_base.cc +++ b/third_party/blink/renderer/core/view_transition/view_transition_pseudo_element_base.cc
@@ -41,7 +41,7 @@ } } -scoped_refptr<const ComputedStyle> +const ComputedStyle* ViewTransitionPseudoElementBase::CustomStyleForLayoutObject( const StyleRecalcContext& style_recalc_context) { // Set the parent style to the style of our parent.
diff --git a/third_party/blink/renderer/core/view_transition/view_transition_pseudo_element_base.h b/third_party/blink/renderer/core/view_transition/view_transition_pseudo_element_base.h index 868d10f..8ee0060c 100644 --- a/third_party/blink/renderer/core/view_transition/view_transition_pseudo_element_base.h +++ b/third_party/blink/renderer/core/view_transition/view_transition_pseudo_element_base.h
@@ -21,7 +21,7 @@ ~ViewTransitionPseudoElementBase() override = default; bool CanGeneratePseudoElement(PseudoId) const override; - scoped_refptr<const ComputedStyle> CustomStyleForLayoutObject( + const ComputedStyle* CustomStyleForLayoutObject( const StyleRecalcContext&) override; void Trace(Visitor* visitor) const override;
diff --git a/third_party/blink/renderer/modules/animationworklet/worklet_animation_test.cc b/third_party/blink/renderer/modules/animationworklet/worklet_animation_test.cc index 06ea9ea..c228b7d3 100644 --- a/third_party/blink/renderer/modules/animationworklet/worklet_animation_test.cc +++ b/third_party/blink/renderer/modules/animationworklet/worklet_animation_test.cc
@@ -155,18 +155,12 @@ } TEST_F(WorkletAnimationTest, StyleHasCurrentAnimation) { - scoped_refptr<const ComputedStyle> style1 = - GetDocument() - .GetStyleResolver() - .ResolveStyle(element_, StyleRecalcContext()) - .get(); + const ComputedStyle* style1 = GetDocument().GetStyleResolver().ResolveStyle( + element_, StyleRecalcContext()); EXPECT_FALSE(style1->HasCurrentOpacityAnimation()); worklet_animation_->play(ASSERT_NO_EXCEPTION); - scoped_refptr<const ComputedStyle> style2 = - GetDocument() - .GetStyleResolver() - .ResolveStyle(element_, StyleRecalcContext()) - .get(); + const ComputedStyle* style2 = GetDocument().GetStyleResolver().ResolveStyle( + element_, StyleRecalcContext()); EXPECT_TRUE(style2->HasCurrentOpacityAnimation()); }
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc index a05357a4..27babcb 100644 --- a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc +++ b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc
@@ -524,8 +524,7 @@ element_font_description.SpecifiedSize()); font_style_builder.SetFontDescription(element_font_description); - scoped_refptr<const ComputedStyle> font_style = - font_style_builder.TakeStyle(); + const ComputedStyle* font_style = font_style_builder.TakeStyle(); Font font = canvas()->GetDocument().GetStyleEngine().ComputeFont( *canvas(), *font_style, *parsed_style);
diff --git a/third_party/blink/renderer/modules/csspaint/nativepaint/background_color_paint_definition_test.cc b/third_party/blink/renderer/modules/csspaint/nativepaint/background_color_paint_definition_test.cc index accba71..6ebc0ad 100644 --- a/third_party/blink/renderer/modules/csspaint/nativepaint/background_color_paint_definition_test.cc +++ b/third_party/blink/renderer/modules/csspaint/nativepaint/background_color_paint_definition_test.cc
@@ -462,9 +462,8 @@ Element* element = GetElementById("target"); StyleRecalcContext style_recalc_context; style_recalc_context.old_style = element->GetComputedStyle(); - scoped_refptr<const ComputedStyle> style = - GetDocument().GetStyleResolver().ResolveStyle(element, - style_recalc_context); + const ComputedStyle* style = GetDocument().GetStyleResolver().ResolveStyle( + element, style_recalc_context); EXPECT_FALSE(style->HasCurrentBackgroundColorAnimation()); NonThrowableExceptionState exception_state; @@ -537,9 +536,8 @@ Element* element = GetElementById("target"); StyleRecalcContext style_recalc_context; style_recalc_context.old_style = element->GetComputedStyle(); - scoped_refptr<const ComputedStyle> style = - GetDocument().GetStyleResolver().ResolveStyle(element, - style_recalc_context); + const ComputedStyle* style = GetDocument().GetStyleResolver().ResolveStyle( + element, style_recalc_context); EXPECT_FALSE(style->HasCurrentBackgroundColorAnimation()); NonThrowableExceptionState exception_state;
diff --git a/third_party/blink/renderer/modules/formatted_text/formatted_text.cc b/third_party/blink/renderer/modules/formatted_text/formatted_text.cc index 113aa6d..ba79702 100644 --- a/third_party/blink/renderer/modules/formatted_text/formatted_text.cc +++ b/third_party/blink/renderer/modules/formatted_text/formatted_text.cc
@@ -53,8 +53,9 @@ void FormattedText::UpdateComputedStylesIfNeeded( Document& document, const FontDescription& defaultFont) { - auto style = document.GetStyleResolver().StyleForFormattedText( - /*is_text_run*/ false, defaultFont, GetCssPropertySet()); + const ComputedStyle* style = + document.GetStyleResolver().StyleForFormattedText( + /*is_text_run*/ false, defaultFont, GetCssPropertySet()); block_->SetStyle(style, LayoutObject::ApplyStyleChanges::kNo); block_->SetHorizontalWritingMode(style->IsHorizontalWritingMode()); for (auto& text_run : text_runs_)
diff --git a/third_party/blink/renderer/modules/formatted_text/formatted_text_run.cc b/third_party/blink/renderer/modules/formatted_text/formatted_text_run.cc index 23b03b6..6b7151c 100644 --- a/third_party/blink/renderer/modules/formatted_text/formatted_text_run.cc +++ b/third_party/blink/renderer/modules/formatted_text/formatted_text_run.cc
@@ -27,8 +27,9 @@ void FormattedTextRunInternal::UpdateStyle(Document& document, const ComputedStyle& parent_style) { - auto style = document.GetStyleResolver().StyleForFormattedText( - /*is_text_run*/ true, parent_style, GetCssPropertySet()); + const ComputedStyle* style = + document.GetStyleResolver().StyleForFormattedText( + /*is_text_run*/ true, parent_style, GetCssPropertySet()); layout_text_->SetStyle(style, LayoutObject::ApplyStyleChanges::kNo); }
diff --git a/third_party/blink/renderer/modules/webcodecs/video_encoder_test.cc b/third_party/blink/renderer/modules/webcodecs/video_encoder_test.cc index f1b3fa6..7a37f84 100644 --- a/third_party/blink/renderer/modules/webcodecs/video_encoder_test.cc +++ b/third_party/blink/renderer/modules/webcodecs/video_encoder_test.cc
@@ -33,52 +33,31 @@ namespace { using testing::_; +using testing::Invoke; using testing::Return; -using testing::Unused; +using testing::WithArgs; -class FakeVideoEncoder : public VideoEncoder { +class MockVideoEncoder : public VideoEncoder { public: - FakeVideoEncoder(ScriptState* script_state, + MockVideoEncoder(ScriptState* script_state, const VideoEncoderInit* init, ExceptionState& exception_state) : VideoEncoder(script_state, init, exception_state) {} - ~FakeVideoEncoder() override = default; + ~MockVideoEncoder() override = default; - void SetupMockEncoderCreation(bool is_hw_accelerated, - base::RepeatingClosure quit_closure) { - next_mock_encoder_ = std::make_unique<media::MockVideoEncoder>(); - mock_encoder_is_hw_ = is_hw_accelerated; - SetupExpectations(quit_closure); + MOCK_METHOD(std::unique_ptr<media::VideoEncoder>, + CreateMediaVideoEncoder, + (const ParsedConfig& config, + media::GpuVideoAcceleratorFactories* gpu_factories), + (override)); + + // CallOnMediaENcoderInfoChanged() is necessary for VideoEncoderTest to call + // VideoEncoder::OnMediaEncoderInfoChanged() because the function is a private + // and VideoEncoderTest is not a friend of VideoEncoder. + void CallOnMediaEncoderInfoChanged( + const media::VideoEncoderInfo& encoder_info) { + VideoEncoder::OnMediaEncoderInfoChanged(encoder_info); } - - private: - void SetupExpectations(base::RepeatingClosure quit_closure) { - EXPECT_CALL(*next_mock_encoder_, Initialize(_, _, _, _, _)) - .WillOnce([quit_closure](Unused, Unused, Unused, Unused, - media::VideoEncoder::EncoderStatusCB done_cb) { - scheduler::GetSequencedTaskRunnerForTesting()->PostTask( - FROM_HERE, WTF::BindOnce(std::move(done_cb), - media::EncoderStatus::Codes::kOk)); - scheduler::GetSequencedTaskRunnerForTesting()->PostTask( - FROM_HERE, std::move(quit_closure)); - }); - } - - std::unique_ptr<media::VideoEncoder> CreateMediaVideoEncoder( - const ParsedConfig& config, - media::GpuVideoAcceleratorFactories* gpu_factories) override { - EXPECT_TRUE(next_mock_encoder_); - - media::VideoEncoderInfo info; - info.implementation_name = "MockEncoderName"; - info.is_hardware_accelerated = mock_encoder_is_hw_; - OnMediaEncoderInfoChanged(info); - - return std::move(next_mock_encoder_); - } - - bool mock_encoder_is_hw_; - std::unique_ptr<media::MockVideoEncoder> next_mock_encoder_; }; class VideoEncoderTest : public testing::Test { @@ -102,10 +81,10 @@ exception_state); } -FakeVideoEncoder* CreateFakeEncoder(ScriptState* script_state, +MockVideoEncoder* CreateMockEncoder(ScriptState* script_state, VideoEncoderInit* init, ExceptionState& exception_state) { - return MakeGarbageCollected<FakeVideoEncoder>(script_state, init, + return MakeGarbageCollected<MockVideoEncoder>(script_state, init, exception_state); } @@ -201,7 +180,7 @@ // Create a video encoder. auto* init = CreateInit(mock_function.ExpectNoCall(), mock_function.ExpectNoCall()); - auto* encoder = CreateFakeEncoder(script_state, init, es); + auto* encoder = CreateMockEncoder(script_state, init, es); ASSERT_FALSE(es.HadException()); // Simulate backgrounding to enable reclamation. @@ -219,7 +198,29 @@ auto* config = CreateConfig(); { base::RunLoop run_loop; - encoder->SetupMockEncoderCreation(true, run_loop.QuitClosure()); + auto media_encoder = std::make_unique<media::MockVideoEncoder>(); + media::MockVideoEncoder* mock_media_encoder = media_encoder.get(); + + EXPECT_CALL(*encoder, CreateMediaVideoEncoder(_, _)) + .WillOnce(::testing::DoAll( + ::testing::Invoke([encoder = encoder]() { + media::VideoEncoderInfo info; + info.implementation_name = "MockEncoderName"; + info.is_hardware_accelerated = true; + encoder->CallOnMediaEncoderInfoChanged(info); + }), + ::testing::Return(::testing::ByMove(std::move(media_encoder))))); + + EXPECT_CALL(*mock_media_encoder, Initialize(_, _, _, _, _)) + .WillOnce(WithArgs<4>( + Invoke([quit_closure = run_loop.QuitClosure()]( + media::VideoEncoder::EncoderStatusCB done_cb) { + scheduler::GetSequencedTaskRunnerForTesting()->PostTask( + FROM_HERE, WTF::BindOnce(std::move(done_cb), + media::EncoderStatus::Codes::kOk)); + scheduler::GetSequencedTaskRunnerForTesting()->PostTask( + FROM_HERE, std::move(quit_closure)); + }))); encoder->configure(config, es); ASSERT_FALSE(es.HadException()); @@ -235,7 +236,30 @@ config->setCodec("avc1.42001E"); { base::RunLoop run_loop; - encoder->SetupMockEncoderCreation(false, run_loop.QuitClosure()); + + auto media_encoder = std::make_unique<media::MockVideoEncoder>(); + media::MockVideoEncoder* mock_media_encoder = media_encoder.get(); + + EXPECT_CALL(*encoder, CreateMediaVideoEncoder(_, _)) + .WillOnce(::testing::DoAll( + ::testing::Invoke([encoder = encoder]() { + media::VideoEncoderInfo info; + info.implementation_name = "MockEncoderName"; + info.is_hardware_accelerated = false; + encoder->CallOnMediaEncoderInfoChanged(info); + }), + ::testing::Return(::testing::ByMove(std::move(media_encoder))))); + + EXPECT_CALL(*mock_media_encoder, Initialize(_, _, _, _, _)) + .WillOnce(WithArgs<4>( + Invoke([quit_closure = run_loop.QuitClosure()]( + media::VideoEncoder::EncoderStatusCB done_cb) { + scheduler::GetSequencedTaskRunnerForTesting()->PostTask( + FROM_HERE, WTF::BindOnce(std::move(done_cb), + media::EncoderStatus::Codes::kOk)); + scheduler::GetSequencedTaskRunnerForTesting()->PostTask( + FROM_HERE, std::move(quit_closure)); + }))); encoder->configure(config, es); ASSERT_FALSE(es.HadException());
diff --git a/third_party/blink/renderer/platform/image-decoders/avif/avif_image_decoder.cc b/third_party/blink/renderer/platform/image-decoders/avif/avif_image_decoder.cc index c9f1b18..809128c 100644 --- a/third_party/blink/renderer/platform/image-decoders/avif/avif_image_decoder.cc +++ b/third_party/blink/renderer/platform/image-decoders/avif/avif_image_decoder.cc
@@ -1326,10 +1326,8 @@ out_gainmap_data = CreateGainmapSegmentReader(features, data_.get()); // Parse gainmap image to get gainmap XMP. - AvifIOData gainmap_avif_io_data = { - .reader = out_gainmap_data.get(), - .all_data_received = IsAllDataReceived(), - }; + AvifIOData gainmap_avif_io_data(out_gainmap_data.get(), IsAllDataReceived()); + avifIO gainmap_avif_io = {.destroy = nullptr, .read = ReadFromSegmentReader, .write = nullptr, @@ -1372,4 +1370,10 @@ return true; } +AVIFImageDecoder::AvifIOData::AvifIOData() = default; +AVIFImageDecoder::AvifIOData::AvifIOData(const SegmentReader* reader, + bool all_data_received) + : reader(reader), all_data_received(all_data_received) {} +AVIFImageDecoder::AvifIOData::~AvifIOData() = default; + } // namespace blink
diff --git a/third_party/blink/renderer/platform/image-decoders/avif/avif_image_decoder.h b/third_party/blink/renderer/platform/image-decoders/avif/avif_image_decoder.h index c99e73b..ab282e4 100644 --- a/third_party/blink/renderer/platform/image-decoders/avif/avif_image_decoder.h +++ b/third_party/blink/renderer/platform/image-decoders/avif/avif_image_decoder.h
@@ -75,6 +75,10 @@ }; struct AvifIOData { + AvifIOData(); + AvifIOData(const SegmentReader* reader, bool all_data_received); + ~AvifIOData(); + const SegmentReader* reader = nullptr; std::vector<uint8_t> buffer ALLOW_DISCOURAGED_TYPE("Required by libavif"); bool all_data_received = false;
diff --git a/third_party/blink/renderer/platform/image-decoders/segment_reader.cc b/third_party/blink/renderer/platform/image-decoders/segment_reader.cc index 76df7d39..58ace0db6 100644 --- a/third_party/blink/renderer/platform/image-decoders/segment_reader.cc +++ b/third_party/blink/renderer/platform/image-decoders/segment_reader.cc
@@ -72,6 +72,7 @@ sk_sp<SkData> GetAsSkData() const override; private: + ~SharedBufferSegmentReader() override = default; scoped_refptr<SharedBuffer> shared_buffer_; }; @@ -119,6 +120,7 @@ sk_sp<SkData> GetAsSkData() const override; private: + ~DataSegmentReader() override = default; sk_sp<SkData> data_; }; @@ -156,6 +158,7 @@ sk_sp<SkData> GetAsSkData() const override; private: + ~ROBufferSegmentReader() override = default; scoped_refptr<ROBuffer> ro_buffer_; mutable base::Lock read_lock_; // Position of the first char in the current block of iter_. @@ -226,7 +229,6 @@ class ParkableImageSegmentReader : public SegmentReader { public: explicit ParkableImageSegmentReader(scoped_refptr<ParkableImage> image); - ~ParkableImageSegmentReader() override = default; size_t size() const override; size_t GetSomeData(const char*& data, size_t position) const override; sk_sp<SkData> GetAsSkData() const override; @@ -234,6 +236,7 @@ void UnlockData() override; private: + ~ParkableImageSegmentReader() override = default; scoped_refptr<ParkableImage> parkable_image_; size_t available_; };
diff --git a/third_party/blink/tools/blinkpy/wpt_tests/wpt_adapter.py b/third_party/blink/tools/blinkpy/wpt_tests/wpt_adapter.py index 180bf34d..570f2dc 100644 --- a/third_party/blink/tools/blinkpy/wpt_tests/wpt_adapter.py +++ b/third_party/blink/tools/blinkpy/wpt_tests/wpt_adapter.py
@@ -538,6 +538,8 @@ 'flag_specific': self.port.flag_specific_config_name() or '', 'used_upstream': self.options.use_upstream_wpt, 'sanitizer_enabled': self.options.enable_sanitizer, + # TODO(crbug.com/1152503): Fully support virtual suites. + 'virtual_suite': '', } if self.options.use_upstream_wpt: # `run_wpt_tests` does not run in the upstream checkout's git
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index 15130a81..c1d7c59 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -6770,12 +6770,6 @@ crbug.com/1472721 [ Linux ] virtual/scalefactor200/fast/hidpi/static/pointerevents/pointerevent_touch-adjustment_click_target.html [ Failure Pass ] # Gardener 2023-08-16 -crbug.com/1473373 [ Mac11 ] wpt_internal/scheduler/task-signal-any-memory-abort.any.worker.html [ Pass Timeout ] -crbug.com/1473373 [ Mac11-arm64 ] wpt_internal/scheduler/task-signal-any-memory-abort.any.worker.html [ Pass Timeout ] -crbug.com/1473373 [ Mac12 ] wpt_internal/scheduler/task-signal-any-memory-abort.any.worker.html [ Pass Timeout ] -crbug.com/1473373 [ Mac12-arm64 ] wpt_internal/scheduler/task-signal-any-memory-abort.any.worker.html [ Pass Timeout ] -crbug.com/1473373 [ Mac13 ] wpt_internal/scheduler/task-signal-any-memory-abort.any.worker.html [ Pass Timeout ] -crbug.com/1473373 [ Mac13-arm64 ] wpt_internal/scheduler/task-signal-any-memory-abort.any.worker.html [ Pass Timeout ] crbug.com/1473474 [ Mac13 ] wpt_internal/mediastream/mediastreamtrackprocessor-transfer-to-worker.html [ Failure Pass ] # Disable the following tests to land and reenable after the land.
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json index bc38835a..ab5ebf1 100644 --- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json +++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
@@ -258396,7 +258396,7 @@ }, "text": { "2d.text.fontVariantCaps1.html": [ - "b610c2240ffe96c7fe747a0db55c5bda51802e38", + "56acfc61f47c32092db1793eb2f4a9966fde04ef", [ null, [ @@ -258408,21 +258408,8 @@ {} ] ], - "2d.text.fontVariantCaps2.html": [ - "f9d42ac3a60eb9f2a62ea2343c9f17a450713b71", - [ - null, - [ - [ - "/html/canvas/element/text/2d.text.fontVariantCaps2-unexpected.html", - "!=" - ] - ], - {} - ] - ], "2d.text.fontVariantCaps3.html": [ - "a90e0c29b3dd1aa0176dabb653cd36d07abfadf4", + "c3d80d3e56caf84b9e5e1d7ab294300d722275cb", [ null, [ @@ -258435,7 +258422,7 @@ ] ], "2d.text.fontVariantCaps4.html": [ - "b598fb60baf2d5126571eb020306cc57fd603464", + "1ee9053b4d9bc06343394cdae54950283873ed44", [ null, [ @@ -258448,7 +258435,7 @@ ] ], "2d.text.fontVariantCaps5.html": [ - "b871f7c062409ffc0b263594c495bc0d5bde3896", + "d80de4ea31873274d14761cb9b1f171a4eb9b208", [ null, [ @@ -258461,7 +258448,7 @@ ] ], "2d.text.fontVariantCaps6.html": [ - "e7bbd29341dcc6755848672047c3263cf4196fdd", + "c17fac18b773da2e581c5e55fb0d04dc64deafab", [ null, [ @@ -259627,7 +259614,7 @@ }, "text": { "2d.text.fontVariantCaps1.html": [ - "a2da7f557ce7c10d4b4dac0d9cd351fe11c062f1", + "3c216f07daac09924ae79221b05665ea0510000b", [ null, [ @@ -259639,21 +259626,34 @@ {} ] ], - "2d.text.fontVariantCaps2.html": [ - "8a644fbb616bc42d223093b70a54fb6653c6b6d4", + "2d.text.fontVariantCaps1.w.html": [ + "4bc1b36e17576a6ef35f75783e5ffd4fb16c0ffb", [ null, [ [ - "/html/canvas/offscreen/text/2d.text.fontVariantCaps2-unexpected.html", - "!=" + "/html/canvas/offscreen/text/2d.text.fontVariantCaps1-expected.html", + "==" ] ], {} ] ], "2d.text.fontVariantCaps3.html": [ - "665a176087fba458e1b7708486d869ebd6862ce1", + "48699a640fe1f792ed275908b3b167e5e19aa01b", + [ + null, + [ + [ + "/html/canvas/offscreen/text/2d.text.fontVariantCaps3-expected.html", + "==" + ] + ], + {} + ] + ], + "2d.text.fontVariantCaps3.w.html": [ + "cd5c1db818fcbf9c827cf3554d1ddd767ce2dac2", [ null, [ @@ -259666,7 +259666,20 @@ ] ], "2d.text.fontVariantCaps4.html": [ - "84c5fbb4469f1ce6c844850dce34f79dbee62870", + "b1b81b81e28747f9ec671a63eefcc2cb13d3c5bd", + [ + null, + [ + [ + "/html/canvas/offscreen/text/2d.text.fontVariantCaps4-expected.html", + "==" + ] + ], + {} + ] + ], + "2d.text.fontVariantCaps4.w.html": [ + "0bae66fcd46b3e2903a1ce2350f571224efeb591", [ null, [ @@ -259679,7 +259692,20 @@ ] ], "2d.text.fontVariantCaps5.html": [ - "877d890ccc6d114fb70fa3df850366bd9a5bbe14", + "2a6f7b5f737ca8c549ae88d413241ada90543049", + [ + null, + [ + [ + "/html/canvas/offscreen/text/2d.text.fontVariantCaps5-expected.html", + "==" + ] + ], + {} + ] + ], + "2d.text.fontVariantCaps5.w.html": [ + "8c59f5b517d4b8bd07b2d057a44792614eb55103", [ null, [ @@ -259692,7 +259718,20 @@ ] ], "2d.text.fontVariantCaps6.html": [ - "08c70a3a2e2fd0b60020a21877575d10108a06c0", + "c33684d38869cd1fed409d44dc6bb1c6cfecf3e5", + [ + null, + [ + [ + "/html/canvas/offscreen/text/2d.text.fontVariantCaps6-expected.html", + "==" + ] + ], + {} + ] + ], + "2d.text.fontVariantCaps6.w.html": [ + "47f70d812b6664c19fb424102df09d4960caad97", [ null, [ @@ -305956,13 +305995,17 @@ [] ], "color-computed-relative-color-expected.txt": [ - "be758f7252ef8c9d11323f1bdf07440132acb172", + "1e3f263447cecc562b28641a015d16762f79487a", [] ], "color-computed-relative-color.html.ini": [ "cd52a07975a7b0d3aaba0c37a1d2f8eef7b47142", [] ], + "color-invalid-relative-color-expected.txt": [ + "a518847d1a98c25f6fdb2ff807955d28e7d636d1", + [] + ], "color-valid-color-function.html.ini": [ "9f2446cc0e3668b8d01feaf7fe1f4db0c2ce2c0b", [] @@ -305980,7 +306023,7 @@ [] ], "color-valid-relative-color-expected.txt": [ - "ff73eaaad050a55ba85ffbfe5b802b46f463710e", + "0e9c4e7240a216285748a5658fa2269de307c6b3", [] ], "color-valid-relative-color.html.ini": [ @@ -311133,7 +311176,7 @@ [] ], "flexbox-align-self-baseline-horiz-006-ref.xhtml": [ - "248ca88a2f2dfb1627bf99b06585f3e2c6986dae", + "9b38d0955b6cf2f70151268454f0753d5f219021", [] ], "flexbox-align-self-baseline-horiz-006.xhtml.ini": [ @@ -367689,7 +367732,7 @@ [] ], "empty-elements-insertion-expected.txt": [ - "6bff876fb8662b5106e6e1f5f71793df0bfe2c00", + "74501eab59da19551d8500949035f9ab32db747e", [] ], "empty-elements-insertion.html.ini": [ @@ -381671,15 +381714,11 @@ [] ], "2d.text.fontVariantCaps1-expected.html": [ - "8ea3c22be13dd3bf1421c3f80b121edcc8b2d3bc", - [] - ], - "2d.text.fontVariantCaps2-unexpected.html": [ - "c64f5d0ec2aea8307ea4ba5257498f2f236186e6", + "e2cef0d77a64b17657bdfe99194930c5328cc3e8", [] ], "2d.text.fontVariantCaps3-expected.html": [ - "069fbfba8823e3e0f5fcf7ada4bd600b6dce1bbd", + "cf2d5ae119b549803b48521003d394313159944a", [] ], "2d.text.fontVariantCaps3.html.ini": [ @@ -381687,7 +381726,7 @@ [] ], "2d.text.fontVariantCaps4-expected.html": [ - "069fbfba8823e3e0f5fcf7ada4bd600b6dce1bbd", + "3813fd3684e8c94887337a551727e068469a66c5", [] ], "2d.text.fontVariantCaps4.html.ini": [ @@ -381695,11 +381734,11 @@ [] ], "2d.text.fontVariantCaps5-expected.html": [ - "8ea3c22be13dd3bf1421c3f80b121edcc8b2d3bc", + "4bda4ec4b5dc522b400df462b8a13b2fc7a9be8a", [] ], "2d.text.fontVariantCaps6-expected.html": [ - "c64f5d0ec2aea8307ea4ba5257498f2f236186e6", + "af9c736aea7f9b20f4fd09522a8aa2dd25a11ef1", [] ], "2d.text.measure.baselines-expected.txt": [ @@ -382269,7 +382308,7 @@ [] ], "2d.text.fontVariantCaps1-expected.html": [ - "942bcdec9cb938536738ef1f71a60cd1c85c9086", + "e2cef0d77a64b17657bdfe99194930c5328cc3e8", [] ], "2d.text.fontVariantCaps1.html.ini": [ @@ -382281,7 +382320,7 @@ [] ], "2d.text.fontVariantCaps3-expected.html": [ - "8d96d0ab0320ea8412e0045f59b6a3ca18260242", + "cf2d5ae119b549803b48521003d394313159944a", [] ], "2d.text.fontVariantCaps3.html.ini": [ @@ -382289,7 +382328,7 @@ [] ], "2d.text.fontVariantCaps4-expected.html": [ - "8d96d0ab0320ea8412e0045f59b6a3ca18260242", + "3813fd3684e8c94887337a551727e068469a66c5", [] ], "2d.text.fontVariantCaps4.html.ini": [ @@ -382297,7 +382336,7 @@ [] ], "2d.text.fontVariantCaps5-expected.html": [ - "942bcdec9cb938536738ef1f71a60cd1c85c9086", + "4bda4ec4b5dc522b400df462b8a13b2fc7a9be8a", [] ], "2d.text.fontVariantCaps5.html.ini": [ @@ -382305,7 +382344,7 @@ [] ], "2d.text.fontVariantCaps6-expected.html": [ - "dbcb8abd76a544d8a5ab48b1f477fc54c7ba008f", + "af9c736aea7f9b20f4fd09522a8aa2dd25a11ef1", [] ], "2d.text.fontVariantCaps6.html.ini": [ @@ -382551,7 +382590,7 @@ [] ], "text.yaml": [ - "93c86b8b5e59e4c9817698d248e3b670c69c9528", + "0e69cf2ccb9b6501877bb92c88045245b2f970b7", [] ], "the-canvas-state.yaml": [ @@ -392677,7 +392716,7 @@ ] }, "selection-pointer-expected.txt": [ - "a46cb70594b81466ca0c856428b12ce23e940d36", + "92255d9932e6a679b84e2b8f9100dc6183f29e47", [] ], "selection-pointer.html.ini": [ @@ -401425,7 +401464,7 @@ ] }, "lint.ignore": [ - "489c717cd6a715ce07dea9421863d3b69ad42cc9", + "761380e5356657d20a76c31e0e18ab94e4527d38", [] ], "loading": { @@ -401699,6 +401738,10 @@ "9d761b6de5ee65c9067a4c576c90eb9e7dd6ef05", [] ], + "busy_in_promise.js": [ + "2eab6b6b8fd1df45df14ab7972a8ff774c3f4ec9", + [] + ], "utils.js": [ "8781252e9411fcb3bf2423347e185e2633ef0140", [] @@ -474526,6 +474569,13 @@ {} ] ], + "content-visibility-087.html": [ + "f2faa45774cde805a295f3376b87444091500f47", + [ + null, + {} + ] + ], "content-visibility-auto-first-observation-immediate.html": [ "5a177d6ea98f15315db595d6bc7b0e8f2da5ac4e", [ @@ -560477,6 +560527,13 @@ {} ] ], + "2d.text.fontVariantCaps2.html": [ + "56efbb6fd3a990b04163889dcd0010538c714a5f", + [ + null, + {} + ] + ], "2d.text.measure.actualBoundingBox.html": [ "d0672b23dcd3f4902f1ca6375a3be62560f96902", [ @@ -572999,6 +573056,20 @@ {} ] ], + "2d.text.fontVariantCaps2.html": [ + "e5bcff1831689321a0bd23983780769cce4e0669", + [ + null, + {} + ] + ], + "2d.text.fontVariantCaps2.worker.js": [ + "89f4f48c7371f119098789c44d46e7a611664519", + [ + "html/canvas/offscreen/text/2d.text.fontVariantCaps2.worker.html", + {} + ] + ], "2d.text.measure.actualBoundingBox.html": [ "105efc07948a4de537689bb8bbc7ee1548f187bf", [ @@ -606664,6 +606735,15 @@ } ] ], + "loaf-source-location-promise-resolver.html": [ + "353b4160751cb125e3b203f604405474c3715ec6", + [ + null, + { + "timeout": "long" + } + ] + ], "loaf-source-location.html": [ "1065564206fc151e9690aca9bf512f7d48016099", [ @@ -619534,9 +619614,9 @@ ] ], "pointerevent_attributes_nohover_pointers.html": [ - "d501ae0afd45612f5bad13d08cdd7cb2646a38d9", + "374279135d0c182e605cb7e661d89b1a8e27ca6a", [ - null, + "pointerevents/pointerevent_attributes_nohover_pointers.html?touch", { "testdriver": true } @@ -679398,6 +679478,15 @@ } ] ], + "RTCEncodedAudioFrame-receive-cloned.https.html": [ + "5a3bfeaf0aca51ae03f7244ff892035031720e74", + [ + null, + { + "testdriver": true + } + ] + ], "RTCEncodedAudioFrame-serviceworker-failure.https.html": [ "d6d8578dbdf5385f4f1ba85f68f610ce3727cd38", [
diff --git a/third_party/blink/web_tests/external/wpt/css/css-contain/content-visibility/content-visibility-087.html b/third_party/blink/web_tests/external/wpt/css/css-contain/content-visibility/content-visibility-087.html new file mode 100644 index 0000000..f2faa45 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-contain/content-visibility/content-visibility-087.html
@@ -0,0 +1,26 @@ +<!doctype HTML> +<html> +<meta charset="utf8"> +<title>Content visibility: focus does not target nested c-v: hidden/auto subtree"</title> +<link rel="author" title="Rob Buis" href="mailto:rbuis@igalia.com"> +<link rel="help" href="https://drafts.csswg.org/css-contain/#content-visibility"> +<meta name="assert" content="focus does not target nested c-v: hidden/auto subtree"> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<div style="content-visibility: hidden"> + <div style="content-visibility: auto"> + <div id="focusable" tabIndex="0"> + focusable thing + </div> + </div> +</div> + +<script> +test(() => { + focusable.focus(); + assert_not_equals(document.activeElement, focusable); +}, "Trying to focus on an element in a nested hidden/auto subtree will not work"); +</script> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-flexbox/flexbox-align-self-baseline-horiz-006-ref.xhtml b/third_party/blink/web_tests/external/wpt/css/css-flexbox/flexbox-align-self-baseline-horiz-006-ref.xhtml index 248ca88..9b38d095 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-flexbox/flexbox-align-self-baseline-horiz-006-ref.xhtml +++ b/third_party/blink/web_tests/external/wpt/css/css-flexbox/flexbox-align-self-baseline-horiz-006-ref.xhtml
@@ -11,16 +11,28 @@ <title>CSS Reftest Reference</title> <link rel="author" title="Brad Werth" href="mailto:bwerth@mozilla.com"/> <style> - .container { + .container, + .containerEndAlign { border: 1px dashed blue; font: 14px sans-serif; height: 50px; } - .container > div { + .container > div, + .wrapper > div{ display: inline-block; } + .containerEndAlign { + display: flex; + align-items: end; + } + .wrapper { + /* This accounts for the 'margin-bottom: 3px' on the 'offset' element + in the last-baseline-aligned part of the testcase: */ + margin-bottom: 3px; + } + .ortho { writing-mode: vertical-rl; width: 17px; @@ -40,11 +52,21 @@ ><div class="orange" style="display: inline-flex;">two<br/>lines</div ><div class="pink">offset</div> </div> - <div class="container"> - <div class="lime ortho" style="margin-top: 4px;">ortho</div - ><div class="yellow">one line</div - ><div class="orange">two<br/>lines</div - ><div class="pink">offset</div> + + <!-- Note: in the testcase, there's a flex container here, whose flex items + are 'last baseline'-aligned and collectively snapped to the end + (bottom) edge. To mock that up, we use a simple flex container with a + single end-aligned 'display:block' flex item; and that item has + inline-block children, which are mockups of the testcase's flex items. + (These inline-blocks get automatically 'last-baseline' aligned to each + other, as part of regular inline-block layout behavior.) --> + <div class="containerEndAlign"> + <div class="wrapper"> + <div class="lime ortho">ortho</div + ><div class="yellow">one line</div + ><div class="orange">two<br/>lines</div + ><div class="pink">offset</div> + </div> </div> </body> </html>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-input-element/auto-direction-dynamic.html b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-input-element/auto-direction-dynamic.html new file mode 100644 index 0000000..68ea511 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-input-element/auto-direction-dynamic.html
@@ -0,0 +1,12 @@ +<!DOCTYPE html> +<html> +<link rel="match" href="auto-direction-ref.html"> +<body> +<script> +const dirInput = document.createElement('input') +dirInput.setAttribute('dir', 'auto') +dirInput.setAttribute('value', 'شنينسنمس') +document.body.appendChild(dirInput) +</script> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-input-element/auto-direction-ref.html b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-input-element/auto-direction-ref.html new file mode 100644 index 0000000..675ba50 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-input-element/auto-direction-ref.html
@@ -0,0 +1,2 @@ +<!DOCTYPE html> +<input dir="auto" value="شنينسنمس">
diff --git a/third_party/blink/web_tests/wpt_internal/dom/abort/abort-signal-memory-tests.https.any.js b/third_party/blink/web_tests/wpt_internal/dom/abort/abort-signal-memory-tests.https.any.js index 9beb627c..3a7f8e69 100644 --- a/third_party/blink/web_tests/wpt_internal/dom/abort/abort-signal-memory-tests.https.any.js +++ b/third_party/blink/web_tests/wpt_internal/dom/abort/abort-signal-memory-tests.https.any.js
@@ -1,15 +1,16 @@ +// META: script=./resources/run-async-gc.js // META: script=./resources/abort-signal-any-memory-tests.js abortSignalAnyMemoryTests(AbortSignal, AbortController); -test(t => { +promise_test(async t => { let count = 0; const controller = new AbortController(); const signal = controller.signal; addEventListener('test', () => { ++count; }, {signal}); // GC should not affect the event dispatch or listener removal below. - gc(); + await runAsyncGC(); dispatchEvent(new Event('test')); dispatchEvent(new Event('test')); @@ -21,7 +22,7 @@ assert_equals(count, 2); }, 'AbortSignalRegistry tracks algorithm handles for event listeners'); -test(t => { +promise_test(async t => { let count = 0; const controller = new AbortController(); @@ -39,14 +40,14 @@ // GC should not affect the listener removal below. The composite signal // above is not held onto by JS, so this test will fail if nothing is // holding a reference to it. - gc(); + await runAsyncGC(); controller.abort(); dispatchEvent(new Event('test2')); assert_equals(count, 2); }, 'AbortSignalRegistry tracks algorithm handles for event listeners (composite signal)'); -promise_test(t => { +promise_test(async t => { const controller = new AbortController(); let promise; @@ -58,7 +59,9 @@ // Make sure the composite signal isn't GCed even though the lock request // doesn't hold onto it. - gc(); + // Note: use high priority GC tasks to ensure they're scheduled before the + // locks request promise is resolved. + await runAsyncGC({priority: 'user-blocking'}); controller.abort(); return promise_rejects_dom(t, 'AbortError', promise);
diff --git a/third_party/blink/web_tests/wpt_internal/dom/abort/resources/abort-signal-any-memory-tests.js b/third_party/blink/web_tests/wpt_internal/dom/abort/resources/abort-signal-any-memory-tests.js index 4b1e2f9..5814a5aa 100644 --- a/third_party/blink/web_tests/wpt_internal/dom/abort/resources/abort-signal-any-memory-tests.js +++ b/third_party/blink/web_tests/wpt_internal/dom/abort/resources/abort-signal-any-memory-tests.js
@@ -1,5 +1,4 @@ // Global state that should be prevented from being garbage collected. -let gRegistry; let gController; let gController2; let gSignals = []; @@ -7,356 +6,306 @@ function abortSignalAnyMemoryTests(signalInterface, controllerInterface) { const suffix = `(using ${signalInterface.name} and ${controllerInterface.name})`; - // Schedules a GC to run before any pending finalization registry callbacks. - // This depends on user-blocking tasks running at a higher priority than - // main-thread V8 tasks. - const scheduleHighPriorityGC = () => scheduler.postTask(() => { gc(); }, {priority: 'user-blocking'}); - // Use promise tests so tests are not interleaved (to prevent global state // from getting clobbered). - promise_test(t => { - return new Promise((resolve) => { - let tokens = []; - gRegistry = new FinalizationRegistry(t.step_func(function(token) { - tokens.push(token); - if (tokens.length == 2) { - assert_in_array(1, tokens); - assert_in_array(2, tokens); - resolve(); - } - })); + promise_test(async t => { + let wr1; + let wr2; - (function() { - let controller1 = new controllerInterface(); - let controller2 = new controllerInterface(); + (function() { + let controller1 = new controllerInterface(); + let controller2 = new controllerInterface(); - gSignals.push(controller1.signal); - gSignals.push(controller2.signal); + gSignals.push(controller1.signal); + gSignals.push(controller2.signal); - signal = signalInterface.any(gSignals); - gSignals.push(signal); + signal = signalInterface.any(gSignals); + gSignals.push(signal); - gRegistry.register(controller1, 1); - gRegistry.register(controller2, 2); - controller1 = null; - controller2 = null; - })(); + wr1 = new WeakRef(controller1); + wr2 = new WeakRef(controller2); + controller1 = null; + controller2 = null; + })(); - gc(); - }); + await runAsyncGC(); + + assert_equals(wr1.deref(), undefined, 'controller1 should be GCed'); + assert_equals(wr2.deref(), undefined, 'controller2 should be GCed'); }, `Controllers can be GCed when their signals are being followed ${suffix}`); - promise_test(t => { - return new Promise((resolve) => { - let tokens = []; - gRegistry = new FinalizationRegistry(t.step_func(function(token) { - tokens.push(token); - if (tokens.length == 3) { - assert_in_array(1, tokens); - assert_in_array(2, tokens); - assert_in_array(3, tokens); - resolve(); - } - })); + promise_test(async t => { + let wr1; + let wr2; + let wr3; - (function() { - let controller1 = new controllerInterface(); - let controller2 = new controllerInterface(); - let signal = signalInterface.any([controller1.signal, controller2.signal]); + (function() { + let controller1 = new controllerInterface(); + let controller2 = new controllerInterface(); + let signal = signalInterface.any([controller1.signal, controller2.signal]); - gRegistry.register(controller1, 1); - gRegistry.register(controller2, 2); - gRegistry.register(signal, 3); + wr1 = new WeakRef(controller1); + wr2 = new WeakRef(controller2); + wr3 = new WeakRef(signal); - controller1 = null; - controller2 = null; - signal = null; - })(); + controller1 = null; + controller2 = null; + signal = null; + })(); - gc(); - }); + await runAsyncGC(); + + assert_equals(wr1.deref(), undefined, 'controller1 should be GCed'); + assert_equals(wr2.deref(), undefined, 'controller2 should be GCed'); + assert_equals(wr3.deref(), undefined, 'signal should be GCed'); }, `Signals can be GCed when all abort sources have been GCed ${suffix}`); - promise_test(t => { - return new Promise((resolve) => { - let tokens = []; - gController = new controllerInterface(); - gRegistry = new FinalizationRegistry(t.step_func(function(token) { - tokens.push(token); - if (tokens.length == 2) { - assert_false(gController.signal.aborted); - assert_in_array(1, tokens); - assert_in_array(2, tokens); - resolve(); - } - })); + promise_test(async t => { + let wr1; + let wr2; - (function() { - let signal1 = signalInterface.any([gController.signal]); - let signal2 = signalInterface.any([signal1]); + gController = new controllerInterface(); - gRegistry.register(signal1, 1); - gRegistry.register(signal2, 2); + (function() { + let signal1 = signalInterface.any([gController.signal]); + let signal2 = signalInterface.any([signal1]); - signal1 = null; - signal2 = null; - })(); + wr1 = new WeakRef(signal1); + wr2 = new WeakRef(signal2); - gc(); - }); + signal1 = null; + signal2 = null; + })(); + + await runAsyncGC(); + + assert_equals(wr1.deref(), undefined, 'signal1 should be GCed'); + assert_equals(wr2.deref(), undefined, 'signal2 should be GCed'); }, `Signals can be GCed when they have no references or event listeners ${suffix}`); - promise_test(t => { - return new Promise((resolve) => { - let tokens = []; - gController = new controllerInterface(); - gRegistry = new FinalizationRegistry(t.step_func(function(token) { - tokens.push(token); - if (tokens.length == 2) { - assert_false(gController.signal.aborted); - assert_in_array(1, tokens); - assert_in_array(2, tokens); - resolve(); - } - })); + promise_test(async t => { + let wr1; + let wr2; - (function() { - let signal1 = signalInterface.any([gController.signal]); - signal1.addEventListener('event', () => {}); + gController = new controllerInterface(); - let signal2 = signalInterface.any([signal1]); - signal2.addEventListener('event', () => {}); + (function() { + let signal1 = signalInterface.any([gController.signal]); + signal1.addEventListener('event', () => {}); - gRegistry.register(signal1, 1); - gRegistry.register(signal2, 2); + let signal2 = signalInterface.any([signal1]); + signal2.addEventListener('event', () => {}); - signal1 = null; - signal2 = null; - })(); + wr1 = new WeakRef(signal1); + wr2 = new WeakRef(signal2); - gc(); - }); + signal1 = null; + signal2 = null; + })(); + + await runAsyncGC(); + + assert_equals(wr1.deref(), undefined, 'signal1 should be GCed'); + assert_equals(wr2.deref(), undefined, 'signal2 should be GCed'); }, `Signals can be GCed when they have no references or relevant event listeners ${suffix}`); - promise_test(t => { - return new Promise((resolve) => { - let tokens = []; + promise_test(async t => { + let wr1; + let wr2; - gRegistry = new FinalizationRegistry(t.step_func(function(token) { - tokens.push(token); - if (tokens.length == 2) { - assert_in_array(1, tokens); - assert_in_array(2, tokens); - resolve(); - } - })); + gController = new controllerInterface(); - gController = new controllerInterface(); + (function() { + let signal1 = signalInterface.any([gController.signal]); + let signal2 = signalInterface.any([signal1]); - (function() { - let signal1 = signalInterface.any([gController.signal]); - let signal2 = signalInterface.any([signal1]); + wr1 = new WeakRef(signal1); + wr2 = new WeakRef(signal2); - gRegistry.register(signal1, 1); - gRegistry.register(signal2, 2); + const abortCallback1 = () => {}; + const abortCallback2 = () => {}; - const abortCallback1 = () => {}; - const abortCallback2 = () => {}; + signal1.addEventListener('abort', abortCallback1); + signal1.addEventListener('abort', abortCallback2); - signal1.addEventListener('abort', abortCallback1); - signal1.addEventListener('abort', abortCallback2); + signal2.addEventListener('abort', abortCallback1); + signal2.addEventListener('abort', abortCallback2); - signal2.addEventListener('abort', abortCallback1); - signal2.addEventListener('abort', abortCallback2); + signal1.removeEventListener('abort', abortCallback1); + signal1.removeEventListener('abort', abortCallback2); - signal1.removeEventListener('abort', abortCallback1); - signal1.removeEventListener('abort', abortCallback2); + signal2.removeEventListener('abort', abortCallback1); + signal2.removeEventListener('abort', abortCallback2); - signal2.removeEventListener('abort', abortCallback1); - signal2.removeEventListener('abort', abortCallback2); + signal1 = null; + signal2 = null; + })(); - signal1 = null; - signal2 = null; - })(); + await runAsyncGC(); - gc(); - }); + assert_equals(wr1.deref(), undefined, 'signal1 should be GCed'); + assert_equals(wr2.deref(), undefined, 'signal2 should be GCed'); }, `Signals can be GCed when all abort event listeners have been removed ${suffix}`); - promise_test(t => { - return new Promise((resolve) => { - let tokenCount = 0; - let fired = false; + promise_test(async t => { + let fired = false; - gController = new controllerInterface(); + gController = new controllerInterface(); - (function() { - let signal = signalInterface.any([gController.signal]); - signal.onabort = t.step_func((e) => { - assert_true(e.target.aborted); - resolve(); - }); + (function() { + let signal = signalInterface.any([gController.signal]); + signal.onabort = t.step_func((e) => { + fired = true; + assert_true(e.target.aborted); + }); - signal = null; - })(); + signal = null; + })(); - gc(); - gController.abort(); - }); + await runAsyncGC(); + + gController.abort(); + assert_true(fired, 'signal should not be GCed before being aborted'); }, `Signals are not GCed before being aborted by a controller when they have abort event listeners ${suffix}`); - promise_test(t => { - return new Promise((resolve) => { - gController = new controllerInterface(); - gRegistry = new FinalizationRegistry(t.step_func(function(token) { - assert_equals(token, 1); - assert_true(fired, 'The abort listener should not run before the signal is GCed'); - resolve(); - })); + promise_test(async t => { + let fired = false; + let wr; - (function() { - let signal = signalInterface.any([AbortSignal.timeout(20)]); - signal.onabort = t.step_func(() => { - fired = true; - // GC could also be triggered in this timeout task, so run GC at high - // priority to ensure the task finishes before the test. - scheduleHighPriorityGC(); - }); - gRegistry.register(signal, 1); - signal = null; - })(); + gController = new controllerInterface(); - gc(); - }); + (function() { + let signal = signalInterface.any([AbortSignal.timeout(20)]); + signal.onabort = t.step_func(() => { + fired = true; + }); + wr = new WeakRef(signal); + signal = null; + })(); + + await runAsyncGC(); + await t.step_wait(() => fired, 'The abort listener should run before the signal is GCed', 500, 20); + await runAsyncGC(); + assert_equals(wr.deref(), undefined, 'signal should be GCed'); }, `Composite signals are not GCed before being aborted by timeout when they have abort event listeners ${suffix}`); - promise_test(t => { - return new Promise((resolve) => { - let tokenCount = 0; - let fired = false; + promise_test(async t => { + let fired = false; + let wr1; + let wr2; - gController = new controllerInterface(); - gRegistry = new FinalizationRegistry(t.step_func(function(token) { - ++tokenCount; - if (tokenCount == 1) { - assert_equals(token, 1, 'tempCompositeSignal should be GCed first'); - assert_false(fired, 'The abort listener should not run before tempCompositeSignal is GCed'); - gController.abort(); - gc(); - } + gController = new controllerInterface(); - if (tokenCount == 2) { - assert_equals(token, 2, 'compositeSignal should be GCed second'); - assert_true(fired, 'The abort listener should run before compositeSignal is GCed'); - resolve(); - } - })); + (function() { + // `tempCompositeSignal` can be GCed after this function because it is + // only used to construct `compositeSignal`. + let tempCompositeSignal = signalInterface.any([gController.signal]); + wr1 = new WeakRef(tempCompositeSignal); - (function() { - // `tempCompositeSignal` can be GCed after this function because it is - // only used to construct `compositeSignal`. - let tempCompositeSignal = signalInterface.any([gController.signal]); - gRegistry.register(tempCompositeSignal, 1); + let compositeSignal = signalInterface.any([tempCompositeSignal]); + compositeSignal.onabort = t.step_func(() => { + fired = true; + }); + wr2 = new WeakRef(compositeSignal); - let compositeSignal = signalInterface.any([tempCompositeSignal]); - compositeSignal.onabort = t.step_func(() => { - fired = true; - }); - gRegistry.register(compositeSignal, 2); + tempCompositeSignal = null; + compositeSignal = null; + })(); - tempCompositeSignal = null; - compositeSignal = null; - })(); + await runAsyncGC(); - gc(); - }); + assert_equals(wr1.deref(), undefined, 'tempCompositeSignal should be GCed'); + assert_not_equals(wr2.deref(), undefined, 'compositeSignal shound not be GCed yet'); + assert_false(fired, 'The abort listener should not run before tempCompositeSignal is GCed'); + + gController.abort(); + + await runAsyncGC(); + + assert_equals(wr2.deref(), undefined, 'compositeSignal should be GCed'); + assert_true(fired, 'The abort listener should run before compositeSignal is GCed'); }, `Temporary composite signals used for constructing other composite signals can be GCed ${suffix}`); - promise_test(t => { - return new Promise((resolve) => { - let tokenCount = 0; - let fired = false; - let tokens = []; + promise_test(async t => { + let fired = false; + let wr1; + let wr2; + let wr3; + let wr4; + let wr5; - gController = new controllerInterface(); - gController2 = new controllerInterface(); - gRegistry = new FinalizationRegistry(t.step_func(function(token) { - ++tokenCount; - tokens.push(token); + gController = new controllerInterface(); + gController2 = new controllerInterface(); - if (tokenCount == 3) { - assert_array_equals(tokens.sort(), [1, 2, 3], 'The temporary signals should be GCed first'); - assert_false(fired, 'The temporary signals should be GCed before the abort event listener fires'); - } + (function() { + // These signals should be GCed after this function runs, before the + // timeout aborts `testSignal`. + let signal1 = signalInterface.any([gController.signal]); + let signal2 = signalInterface.any([gController2.signal]); + let signal3 = signalInterface.any([signal1, signal2]); - if (tokenCount == 5) { - assert_true(fired, 'The abort listener should run before compositeSignal is GCed'); - resolve(); - } - })); + wr1 = new WeakRef(signal1); + wr2 = new WeakRef(signal2); + wr3 = new WeakRef(signal3); - (function() { - // These signals should be GCed after this function runs, before the - // timeout aborts `testSignal`. - let signal1 = signalInterface.any([gController.signal]); - let signal2 = signalInterface.any([gController2.signal]); - let signal3 = signalInterface.any([signal1, signal2]); + let timeoutSignal = AbortSignal.timeout(20); + // This and `timeoutSignal` must remain alive until the timeout fires. + let testSignal = signalInterface.any([signal3, timeoutSignal]); + testSignal.onabort = t.step_func(() => { + fired = true; + }); - let timeoutSignal = AbortSignal.timeout(20); - // This and `timeoutSignal` must remain alive until the timeout fires. - let testSignal = signalInterface.any([signal3, timeoutSignal]); - testSignal.onabort = t.step_func(() => { - fired = true; - scheduleHighPriorityGC(); - }); + wr4 = new WeakRef(timeoutSignal); + wr5 = new WeakRef(testSignal); - gRegistry.register(signal1, 1); - gRegistry.register(signal2, 2); - gRegistry.register(signal3, 3); - gRegistry.register(timeoutSignal, 4); - gRegistry.register(testSignal, 5); + signal1 = null; + signal2 = null; + signal3 = null; + timeoutSignal = null; + testSignal = null; + })(); - signal1 = null; - signal2 = null; - signal3 = null; - timeoutSignal = null; - testSignal = null; - })(); + // Running GC async in high priority tasks should complete before the timeout. + await runAsyncGC({priority: 'user-blocking'}); + assert_false(fired, 'GC should complete before the timeout fires'); + assert_equals(wr1.deref(), undefined, 'signal1 should be GCed'); + assert_equals(wr2.deref(), undefined, 'signal2 should be GCed'); + assert_equals(wr3.deref(), undefined, 'signal3 should be GCed'); + assert_not_equals(wr4.deref(), undefined, 'timeoutSignal should not be GCed before the timeout'); + assert_not_equals(wr5.deref(), undefined, 'testSignal should not be GCed before the timeout'); - gc(); - }); + await t.step_wait(() => fired, 'The abort listener should run before the signal is GCed', 500, 20); + + await runAsyncGC(); + assert_equals(wr4.deref(), undefined, 'timeoutSignal should be GCed'); + assert_equals(wr5.deref(), undefined, 'testSignal should be GCed'); }, `Nested and intermediate composite signals can be GCed when expected ${suffix}`); - promise_test(t => { - return new Promise((resolve) => { - let tokenCount = 0; - gRegistry = new FinalizationRegistry(t.step_func(function(token) { - ++tokenCount; - if (tokenCount == 2) { - resolve(); - } - })); + promise_test(async t => { + let wr1; + let wr2; - (function() { - let signal1 = signalInterface.any([]); - signal1.addEventListener('abort', () => {}); - // For plain AbortSignals, this should not be a no-op. For TaskSignals, - // this will test the settling logic. - signal1.addEventListener('prioritychange', () => {}); - gRegistry.register(signal1, 1); + (function() { + let signal1 = signalInterface.any([]); + signal1.addEventListener('abort', () => {}); + // For plain AbortSignals, this should not be a no-op. For TaskSignals, + // this will test the settling logic. + signal1.addEventListener('prioritychange', () => {}); + wr1 = new WeakRef(signal1); - let controller = new controllerInterface(); - let signal2 = signalInterface.any([controller.signal]); - signal2.addEventListener('abort', () => {}); - signal2.addEventListener('prioritychange', () => {}); - gRegistry.register(signal2, 2); + let controller = new controllerInterface(); + let signal2 = signalInterface.any([controller.signal]); + signal2.addEventListener('abort', () => {}); + signal2.addEventListener('prioritychange', () => {}); + wr2 = new WeakRef(signal2); - signal1 = null; - signal2 = null; - controller = null; - })(); + signal1 = null; + signal2 = null; + controller = null; + })(); - gc(); - }); + await runAsyncGC(); + assert_equals(wr1.deref(), undefined, 'signal1 should be GCed'); + assert_equals(wr2.deref(), undefined, 'signal2 should be GCed'); }, `Settled composite signals with event listeners can be GCed ${suffix}`); }
diff --git a/third_party/blink/web_tests/wpt_internal/dom/abort/resources/run-async-gc.js b/third_party/blink/web_tests/wpt_internal/dom/abort/resources/run-async-gc.js new file mode 100644 index 0000000..548645da --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/dom/abort/resources/run-async-gc.js
@@ -0,0 +1,11 @@ +async function runAsyncGC(args = {}) { + // Run gc in a loop to ensure anything needing more than one cycle can be + // collected, e.g. due to dependencies. Note this is similar to + // ThreadState::CollectAllGarbageForTesting, but async and with 2 less + // iterations. + for (let i = 0; i < 3; i++) { + // crbug.com/1474629: invoking gc({execution: 'async'}) trips leak + // detection, so use postTask and run sync gc() to do async GC. + await scheduler.postTask(() => { gc(); }, args); + } +}
diff --git a/third_party/blink/web_tests/wpt_internal/scheduler/task-signal-any-memory-abort.any.js b/third_party/blink/web_tests/wpt_internal/scheduler/task-signal-any-memory-abort-1.any.js similarity index 69% rename from third_party/blink/web_tests/wpt_internal/scheduler/task-signal-any-memory-abort.any.js rename to third_party/blink/web_tests/wpt_internal/scheduler/task-signal-any-memory-abort-1.any.js index 09c5b39a..f7ab2148 100644 --- a/third_party/blink/web_tests/wpt_internal/scheduler/task-signal-any-memory-abort.any.js +++ b/third_party/blink/web_tests/wpt_internal/scheduler/task-signal-any-memory-abort-1.any.js
@@ -1,4 +1,4 @@ +// META: script=../dom/abort/resources/run-async-gc.js // META: script=../dom/abort/resources/abort-signal-any-memory-tests.js abortSignalAnyMemoryTests(TaskSignal, AbortController); -abortSignalAnyMemoryTests(TaskSignal, TaskController);
diff --git a/third_party/blink/web_tests/wpt_internal/scheduler/task-signal-any-memory-abort.any.js b/third_party/blink/web_tests/wpt_internal/scheduler/task-signal-any-memory-abort-2.any.js similarity index 69% copy from third_party/blink/web_tests/wpt_internal/scheduler/task-signal-any-memory-abort.any.js copy to third_party/blink/web_tests/wpt_internal/scheduler/task-signal-any-memory-abort-2.any.js index 09c5b39a..125b3d4 100644 --- a/third_party/blink/web_tests/wpt_internal/scheduler/task-signal-any-memory-abort.any.js +++ b/third_party/blink/web_tests/wpt_internal/scheduler/task-signal-any-memory-abort-2.any.js
@@ -1,4 +1,4 @@ +// META: script=../dom/abort/resources/run-async-gc.js // META: script=../dom/abort/resources/abort-signal-any-memory-tests.js -abortSignalAnyMemoryTests(TaskSignal, AbortController); abortSignalAnyMemoryTests(TaskSignal, TaskController);
diff --git a/third_party/blink/web_tests/wpt_internal/scheduler/task-signal-any-memory-priority.any.js b/third_party/blink/web_tests/wpt_internal/scheduler/task-signal-any-memory-priority.any.js index ee28c3a..19b5237 100644 --- a/third_party/blink/web_tests/wpt_internal/scheduler/task-signal-any-memory-priority.any.js +++ b/third_party/blink/web_tests/wpt_internal/scheduler/task-signal-any-memory-priority.any.js
@@ -1,157 +1,152 @@ +// META: script=../dom/abort/resources/run-async-gc.js + // Global state that should be prevented from being garbage collected. -let gRegistry; let gController; let gSignals = []; // The tests below rely on the same global state, which each test manipulates. // Use promise_tests so tests are not interleaved, otherwise the global state // can change unexpectedly. -promise_test(t => { - return new Promise((resolve) => { - let tokens = []; - gController = new TaskController(); - gRegistry = new FinalizationRegistry(t.step_func(function(token) { - tokens.push(token); - if (tokens.length == 3) { - assert_in_array(1, tokens); - assert_in_array(2, tokens); - assert_in_array(3, tokens); - resolve(); - } - })); +promise_test(async t => { + let wr1; + let wr2; + let wr3; - (function() { - let signal1 = TaskSignal.any([], {priority: gController.signal}); - let signal2 = TaskSignal.any([gController.signal], {priority: gController.signal}); - let signal3 = TaskSignal.any([signal2]); + gController = new TaskController(); - gRegistry.register(signal1, 1); - gRegistry.register(signal2, 2); - gRegistry.register(signal3, 3); + (function() { + let signal1 = TaskSignal.any([], {priority: gController.signal}); + let signal2 = TaskSignal.any([gController.signal], {priority: gController.signal}); + let signal3 = TaskSignal.any([signal2]); - signal1 = null; - signal2 = null; - signal3 = null; - })(); + wr1 = new WeakRef(signal1); + wr2 = new WeakRef(signal2); + wr3 = new WeakRef(signal3); - gc(); - }); + signal1 = null; + signal2 = null; + signal3 = null; + })(); + + await runAsyncGC(); + + assert_equals(wr1.deref(), undefined, 'signal1 should be GCed'); + assert_equals(wr2.deref(), undefined, 'signal2 should be GCed'); + assert_equals(wr3.deref(), undefined, 'signal3 should be GCed'); }, "TaskSignals can be GCed when they have no references or event listeners"); -promise_test(t => { - return new Promise((resolve) => { - let tokens = []; - gRegistry = new FinalizationRegistry(t.step_func(function(token) { - tokens.push(token); - if (tokens.length == 2) { - assert_in_array(1, tokens); - assert_in_array(2, tokens); - resolve(); - } - })); +promise_test(async t => { + let wr1; + let wr2; - (function() { - let controller = new TaskController(); - let signal = TaskSignal.any([], {priority: controller.signal}); - signal.onprioritychange = () => {}; + (function() { + let controller = new TaskController(); + let signal = TaskSignal.any([], {priority: controller.signal}); + signal.onprioritychange = () => {}; - gRegistry.register(controller, 1); - gRegistry.register(signal, 2); + wr1 = new WeakRef(controller); + wr2 = new WeakRef(signal); - controller = null; - signal = null; - })(); + controller = null; + signal = null; + })(); - gc(); - }); + await runAsyncGC(); + assert_equals(wr1.deref(), undefined, 'controller should be GCed'); + assert_equals(wr2.deref(), undefined, 'signal should be GCed'); }, "A TaskSignal with a prioritychange listener can be GCed when its priority source has been GCed"); -promise_test(t => { - return new Promise((resolve) => { - (function() { - gController = new TaskController(); - let signal = TaskSignal.any([], {priority: gController.signal}); - signal.onprioritychange = t.step_func((e) => { - assert_equals(e.target.priority, 'background'); - resolve(); - }); - signal = null; - })(); +promise_test(async t => { + let fired = false; - gc(); - gController.setPriority('background'); - }); + (function() { + gController = new TaskController(); + let signal = TaskSignal.any([], {priority: gController.signal}); + signal.onprioritychange = t.step_func((e) => { + assert_equals(e.target.priority, 'background', 'Priority should change to background'); + fired = true; + }); + signal = null; + })(); + + await runAsyncGC(); + gController.setPriority('background'); + assert_true(fired, 'prioritchange event should fire'); }, "TaskSignals with prioritychange listeners are not GCed if their priority source is alive"); -promise_test(t => { - return new Promise((resolve) => { - (function() { - gController = new TaskController(); - let controller = new AbortController(); - let signal = TaskSignal.any([controller.signal], {priority: gController.signal}); - signal.onprioritychange = t.step_func((e) => { - assert_equals(e.target.priority, 'background'); - resolve(); - }); - signal = null; - controller = null; - })(); +promise_test(async t => { + (function() { + gController = new TaskController(); + let controller = new AbortController(); + let signal = TaskSignal.any([controller.signal], {priority: gController.signal}); + signal.onprioritychange = t.step_func((e) => { + assert_equals(e.target.priority, 'background', 'Priority should change to background'); + fired = true; + }); + signal = null; + controller = null; + })(); - gc(); - gController.setPriority('background'); - }); + await runAsyncGC(); + gController.setPriority('background'); + assert_true(fired, 'prioritchange event should fire'); }, "TaskSignals with prioritychange listeners are not GCed after their abort source is GCed if their priority source is alive"); -promise_test(t => { - return new Promise((resolve) => { - (function() { - gController = new TaskController(); - let controller = new AbortController(); - let signal = TaskSignal.any([controller.signal], {priority: gController.signal}); - signal.onprioritychange = t.step_func((e) => { - assert_equals(e.target.priority, 'background'); - resolve(); - }); +promise_test(async t => { + let fired = true; - let abortFired = false; - signal.onabort = t.step_func(() => { - abortFired = true; - }); - controller.abort(); - assert_true(abortFired); + (function() { + gController = new TaskController(); + let controller = new AbortController(); + let signal = TaskSignal.any([controller.signal], {priority: gController.signal}); + signal.onprioritychange = t.step_func((e) => { + assert_equals(e.target.priority, 'background'); + fired = true; + }); - signal = null; - controller = null; - })(); + let abortFired = false; + signal.onabort = t.step_func(() => { + abortFired = true; + }); + controller.abort(); + assert_true(abortFired); - gc(); - gController.setPriority('background'); - }); + signal = null; + controller = null; + })(); + + await runAsyncGC(); + gController.setPriority('background'); + assert_true(fired, 'prioritchange event should fire'); }, "TaskSignals with prioritychange listeners are not GCed after they are aborted if their priority source is alive"); -promise_test(t => { - return new Promise((resolve) => { - let runCount = 0; - gRegistry = new FinalizationRegistry(t.step_func(function(token) { - assert_equals(token, 1); - assert_equals(runCount, 3); - resolve(); - })); - gController = new TaskController({priority: 'background'}); +promise_test(async t => { + let runCount = 0; + gController = new TaskController({priority: 'background'}); + const tasks = []; - (function() { - let signal = TaskSignal.any([], {priority: gController.signal}); - scheduler.postTask(() => { ++runCount; }, {signal}); - scheduler.postTask(() => { ++runCount; }, {signal}); - scheduler.postTask(() => { ++runCount; }, {signal}); + (function() { + let signal = TaskSignal.any([], {priority: gController.signal}); + scheduler.postTask(() => { ++runCount; }, {signal}); + scheduler.postTask(() => { ++runCount; }, {signal}); + scheduler.postTask(() => { ++runCount; }, {signal}); - // Finally, gc in a separate task so `signal` can be GCed. - scheduler.postTask(() => { gc(); }, {priority: 'background'}); + wr = new WeakRef(signal); + signal = null; + })(); - gRegistry.register(signal, 1); - signal = null; - })(); + // Since this runs at higher than background priority, nothing should have + // happened yet. + await runAsyncGC(); + assert_not_equals(wr.deref(), undefined, 'signal should not have been GCed yet'); - gc(); - }); + // Let the background tasks run. + // NB: we don't use the task promises since the signal will be propagated for + // yield inheritance. + await scheduler.postTask(() => {}, {priority: 'background'}); + assert_equals(runCount, 3, '3 tasks should have run'); + + // Finally, run gc so `signal` can be GCed. + await runAsyncGC(); + assert_equals(wr.deref(), undefined, 'signal should have been GCed'); }, "Composite TaskSignals with pending tasks are not GCed if their priority source is alive");
diff --git a/tools/clang/plugins/tests/bad_raw_ptr_cast_kinds.txt b/tools/clang/plugins/tests/bad_raw_ptr_cast_kinds.txt index 43f9b2a2..3523478 100644 --- a/tools/clang/plugins/tests/bad_raw_ptr_cast_kinds.txt +++ b/tools/clang/plugins/tests/bad_raw_ptr_cast_kinds.txt
@@ -6,8 +6,10 @@ ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ./base/allocator/partition_allocator/pointers/raw_ptr.h:11:7: note: candidate constructor (the implicit copy constructor) not viable: no known conversion from 'RawPtrWrapper' to 'const raw_ptr<int>' for 1st argument class raw_ptr { - ^ + ^~~~~~~ ./base/allocator/partition_allocator/pointers/raw_ptr.h:11:7: note: candidate constructor (the implicit move constructor) not viable: no known conversion from 'RawPtrWrapper' to 'raw_ptr<int>' for 1st argument +class raw_ptr { + ^~~~~~~ ./base/allocator/partition_allocator/pointers/raw_ptr.h:11:7: note: candidate constructor (the implicit default constructor) not viable: requires 0 arguments, but 1 was provided bad_raw_ptr_cast_kinds.cpp:57:9: error: cannot cast from type 'RawPtrWrapper' to pointer type 'int *' (void)static_cast<int*>(wrapped);
diff --git a/tools/licenses/licenses.py b/tools/licenses/licenses.py index d2827cfc..ffc4f24 100755 --- a/tools/licenses/licenses.py +++ b/tools/licenses/licenses.py
@@ -17,6 +17,8 @@ import argparse import codecs +import csv +import io import json import logging import os @@ -1073,16 +1075,90 @@ args.spdx_doc_namespace) elif args.format == 'txt': license_txt = GenerateLicenseFilePlainText(metadatas) + + elif args.format == 'csv': + license_txt = GenerateLicenseFileCsv(metadatas) + else: raise ValueError(f'Unknown license format: {args.format}') if args.output_file: with open(args.output_file, 'w', encoding='utf-8') as f: f.write(license_txt) + print(f"\n ---- \nWrote license data to file {args.output_file}") else: print(license_txt) +def GenerateLicenseFileCsv( + metadata: Dict[str, Dict[str, Any]], + repo_root: str = _REPOSITORY_ROOT, +) -> str: + """Generates a CSV formatted file which contains license data to be used as + part of the submission to the Open Source Licensing Review process. + """ + csv_content = io.StringIO() + csv_writer = csv.writer(csv_content, quoting=csv.QUOTE_NONNUMERIC) + + # These values are applied statically to all dependencies which are included + # in the exported CSV. + # Static fields: + # * Name of binary which uses dependency, + # * License text for library included in product, + # * Mirrored source for reciprocal licences. + # * Signoff date. + static_data = ["Chromium", "Yes", "Yes", "N/A"] + + # Add informative CSV header row to make it clear which columns represent + # which data in the review spreadsheet. + csv_writer.writerow([ + "Library Name", "Link to LICENSE file", "License Name", + "Binary which uses library", "License text for library included?", + "Source code for library includes the mirrored source?", + "Authorization date" + ]) + + # Start with Chromium's LICENSE file + csv_writer.writerow([ + "Chromium", + "https://chromium.googlesource.com/chromium/src.git/+/refs/heads/main/LICENSE", + "Chromium" + ] + static_data) + + # Add necessary third_party. + for directory in sorted(metadata): + dir_metadata = metadata[directory] + + # Only third party libraries which are shipped as part of a final product + # are in scope for license review. + if dir_metadata['Shipped'] == NO: + continue + + data_row = [dir_metadata['Name'] or "UNKNOWN"] + + urls = [] + for lic in dir_metadata['License File']: + # The review process requires that a link is provided to each license + # which is included. We can achieve this by combining a static + # Chromium googlesource URL with the relative path to the license + # file from the top level Chromium src directory. + lic_url = ( + "https://chromium.googlesource.com/chromium/src.git/+/refs/heads/main/" + + os.path.relpath(lic, repo_root)) + + # Since these are URLs and not paths, replace any Windows path `\` + # separators with a `/` + urls.append(lic_url.replace("\\", "/")) + + data_row.append(", ".join(urls) or "UNKNOWN") + data_row.append(dir_metadata["License"] or "UNKNOWN") + + # Join the default data which applies to each row + csv_writer.writerow(data_row + static_data) + + return csv_content.getvalue() + + def GenerateLicenseFilePlainText( metadata: Dict[str, Dict[str, Any]], repo_root: str = _REPOSITORY_ROOT, @@ -1175,7 +1251,7 @@ parser.add_argument('--gn-target', help='GN target to scan for dependencies.') parser.add_argument('--format', default='txt', - choices=['txt', 'spdx'], + choices=['txt', 'spdx', 'csv'], help='What format to output in') parser.add_argument('--spdx-root', default=_REPOSITORY_ROOT,
diff --git a/tools/licenses/licenses_test.py b/tools/licenses/licenses_test.py index 77e900d..67d54a8 100755 --- a/tools/licenses/licenses_test.py +++ b/tools/licenses/licenses_test.py
@@ -5,6 +5,8 @@ """Unit tests for //tools/licenses/licenses.py. """ +import csv +import io import os import pathlib import sys @@ -28,6 +30,7 @@ os.path.join('third_party', 'lib1'): { 'Name': 'lib1', 'Shipped': 'yes', + 'License': 'MIT', 'License File': [os.path.join('third_party', 'lib1', 'LICENSE')], }, os.path.join('third_party', 'lib2'): { @@ -35,6 +38,8 @@ 'lib2', 'Shipped': 'yes', + 'License': + 'MIT, Apache 2.0', 'License File': [ os.path.join('third_party', 'lib2', 'LICENSE-A'), os.path.join('third_party', 'lib2', 'LICENSE-B'), @@ -50,6 +55,8 @@ 'lib_unshipped', 'Shipped': 'no', + 'License': + '', 'License File': [ os.path.join('third_party', 'lib_unshipped', 'LICENSE'), ], @@ -57,18 +64,21 @@ os.path.join('third_party', 'lib3'): { 'Name': 'lib3', 'Shipped': 'yes', + 'License': '', 'License File': [os.path.join('third_party', 'lib3', 'LICENSE')], }, os.path.join('third_party', 'lib3-v1'): { # Test SPDX license file dedup. (different name, same license file) 'Name': 'lib3-v1', 'Shipped': 'yes', + 'License': 'Apache 2.0', 'License File': [os.path.join('third_party', 'lib3', 'LICENSE')], }, os.path.join('third_party', 'lib3-v2'): { # Test SPDX id dedup. (same name, different license file) 'Name': 'lib3', 'Shipped': 'yes', + 'License': 'BSD', 'License File': [os.path.join('third_party', 'lib3-v2', 'LICENSE')], }, } @@ -128,6 +138,78 @@ os.path.join('external', 'somelib'), ])) + def test_generate_license_file_csv(self): + # This is the same for all the links and prevents wildly long strings. + prefix = "https://chromium.googlesource.com/chromium/src.git/+/refs/heads/main/" + + csv_file = io.StringIO(licenses.GenerateLicenseFileCsv( + self._get_metadata())) + csv_rows = [row for row in csv.DictReader(csv_file)] + + expected = [{ + 'Library Name': 'Chromium', + 'Link to LICENSE file': f'{prefix}LICENSE', + 'License Name': 'Chromium', + 'Binary which uses library': 'Chromium', + 'License text for library included?': 'Yes', + 'Source code for library includes the mirrored source?': 'Yes', + 'Authorization date': 'N/A' + }, { + 'Library Name': 'lib1', + 'Link to LICENSE file': + f'{prefix}tools/licenses/third_party/lib1/LICENSE', + 'License Name': 'MIT', + 'Binary which uses library': 'Chromium', + 'License text for library included?': 'Yes', + 'Source code for library includes the mirrored source?': 'Yes', + 'Authorization date': 'N/A' + }, { + 'Library Name': + 'lib2', + 'Link to LICENSE file': + (f'{prefix}tools/licenses/third_party/lib2/LICENSE-A, ' + f'{prefix}tools/licenses/third_party/lib2/LICENSE-B'), + 'License Name': + 'MIT, Apache 2.0', + 'Binary which uses library': + 'Chromium', + 'License text for library included?': + 'Yes', + 'Source code for library includes the mirrored source?': + 'Yes', + 'Authorization date': + 'N/A' + }, { + 'Library Name': 'lib3', + 'Link to LICENSE file': + f'{prefix}tools/licenses/third_party/lib3/LICENSE', + 'License Name': 'UNKNOWN', + 'Binary which uses library': 'Chromium', + 'License text for library included?': 'Yes', + 'Source code for library includes the mirrored source?': 'Yes', + 'Authorization date': 'N/A' + }, { + 'Library Name': 'lib3-v1', + 'Link to LICENSE file': + f'{prefix}tools/licenses/third_party/lib3/LICENSE', + 'License Name': 'Apache 2.0', + 'Binary which uses library': 'Chromium', + 'License text for library included?': 'Yes', + 'Source code for library includes the mirrored source?': 'Yes', + 'Authorization date': 'N/A' + }, { + 'Library Name': 'lib3', + 'Link to LICENSE file': + f'{prefix}tools/licenses/third_party/lib3-v2/LICENSE', + 'License Name': 'BSD', + 'Binary which uses library': 'Chromium', + 'License text for library included?': 'Yes', + 'Source code for library includes the mirrored source?': 'Yes', + 'Authorization date': 'N/A' + }] + + self.assertEqual(csv_rows, expected) + def test_generate_license_file_txt(self): read_file_vals = [ 'root license text\n',
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 9ecbaf45..9f4110b 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -64050,6 +64050,7 @@ <int value="-180056644" label="HomeButtonWithText:disabled"/> <int value="-179580377" label="CrossOriginOpenerPolicy:enabled"/> <int value="-178364053" label="TerminalSystemAppLegacySettings:enabled"/> + <int value="-178359490" label="DrawImmediatelyWhenInteractive:enabled"/> <int value="-177974995" label="CrostiniShowMicSetting:disabled"/> <int value="-177085741" label="EnableEphemeralGuestProfilesOnDesktop:disabled"/> @@ -64886,6 +64887,7 @@ label="FriendlierSafeBrowsingSettingsStandardProtection:disabled"/> <int value="240856309" label="MimeHandlerViewInCrossProcessFrame:enabled"/> <int value="241187301" label="BrowserTouchBar:disabled"/> + <int value="244040049" label="DrawImmediatelyWhenInteractive:disabled"/> <int value="244697230" label="enable-theme-color-in-tabbed-mode"/> <int value="245100553" label="PcieBillboardNotification:enabled"/> <int value="245896533" label="SearchSuggestionsOnLocalNtp:enabled"/> @@ -96663,6 +96665,7 @@ <int value="1" label="ServiceWorker"/> <int value="2" label="Without ServiceWorker"/> <int value="3" label="SubresourceLoader is handling redirect"/> + <int value="4" label="AutoPreload is handling fallback"/> </enum> <enum name="ServiceWorkerInstalledScriptsManager.FinishedReason">
diff --git a/tools/metrics/histograms/metadata/ash/histograms.xml b/tools/metrics/histograms/metadata/ash/histograms.xml index 9f0c925..b6d0bed 100644 --- a/tools/metrics/histograms/metadata/ash/histograms.xml +++ b/tools/metrics/histograms/metadata/ash/histograms.xml
@@ -4464,6 +4464,17 @@ </summary> </histogram> +<histogram name="Ash.NotificationPopup.OnTopOfBubbleCount" units="popups" + expires_after="2024-08-22"> + <owner>leandre@chromium.org</owner> + <owner>cros-status-area-eng@google.com</owner> + <summary> + Record the number of popups that show up on top of a tray bubble. Emitted + when a tray bubble is shown or change height, and when there's a new + notification popup added when a tray bubble is open. + </summary> +</histogram> + <histogram name="Ash.NotificationView.ConvertSingleToGroup.{Animation}.AnimationSmoothness" units="%" expires_after="2024-05-14">
diff --git a/tools/metrics/histograms/metadata/input/histograms.xml b/tools/metrics/histograms/metadata/input/histograms.xml index 0681af2..e9dcd3e 100644 --- a/tools/metrics/histograms/metadata/input/histograms.xml +++ b/tools/metrics/histograms/metadata/input/histograms.xml
@@ -1475,6 +1475,26 @@ </summary> </histogram> +<histogram + name="InputMethod.TouchSelection.{TouchSelectionResult}Session.TouchDownCount" + units="units" expires_after="2024-02-02"> + <owner>michellegc@google.com</owner> + <owner>essential-inputs-team@google.com</owner> + <summary> + The number of touch down movements made by a user in a 'successful' + {TouchSelectionResult} session. A session starts from the first touch down + that activates touch selection and ends 'successfully' if an editing action + occurs after {TouchSelectionResult}, e.g. typing a character or using the + menu cut, copy or paste actions. The touch down count is recorded at the end + of a successful session (and is not recorded for sessions that end due to + the window closing, timing out after 10s of inactivity, etc.). + </summary> + <token key="TouchSelectionResult"> + <variant name="Cursor" summary="cursor placement"/> + <variant name="Selection" summary="text selection"/> + </token> +</histogram> + <histogram name="InputMethod.VirtualKeyboard.BackspaceCount" units="units" expires_after="2023-12-24"> <owner>shend@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/nearby/histograms.xml b/tools/metrics/histograms/metadata/nearby/histograms.xml index cef83c0..280f2db 100644 --- a/tools/metrics/histograms/metadata/nearby/histograms.xml +++ b/tools/metrics/histograms/metadata/nearby/histograms.xml
@@ -353,6 +353,18 @@ </summary> </histogram> +<histogram name="Nearby.Presence.Credentials.Download.ServerRequestDuration" + units="ms" expires_after="2024-01-05"> + <owner>julietlevesque@google.com</owner> + <owner>chromeos-cross-device-eng@google.com</owner> + <summary> + Records time spent in milliseconds to receive a response from the Nearby + Presence Web Server after a download request for remote devices' + credentials. Emitted after a successful response from the server. Note that + there is a timeout at 5 seconds. + </summary> +</histogram> + <histogram name="Nearby.Presence.Credentials.FirstTimeRegistration.Result" enum="NearbyPresenceFirstTimeRegistrationResult" expires_after="2024-01-05"> <owner>julietlevesque@google.com</owner> @@ -428,6 +440,18 @@ </summary> </histogram> +<histogram name="Nearby.Presence.Credentials.Upload.ServerRequestDuration" + units="ms" expires_after="2024-01-05"> + <owner>julietlevesque@google.com</owner> + <owner>chromeos-cross-device-eng@google.com</owner> + <summary> + Records time spent in milliseconds to receive a response from the Nearby + Presence Web Server after an upload request for the local device's + credentials. Emitted after a successful response from the server. Note that + there is a timeout at 5 seconds. + </summary> +</histogram> + <histogram name="Nearby.Share.BackgroundScanning.DeviceNearbySharing.Notification.Flow" enum="NearbyShareBackgroundScanningDeviceNearbySharingNotificationFlowEvent"
diff --git a/ui/accessibility/accessibility_features.cc b/ui/accessibility/accessibility_features.cc index 5464fdf9..f776049 100644 --- a/ui/accessibility/accessibility_features.cc +++ b/ui/accessibility/accessibility_features.cc
@@ -328,6 +328,14 @@ return base::FeatureList::IsEnabled(::features::kReadAnythingWebUIToolbar); } +BASE_FEATURE(kReadAnythingReadAloud, + "ReadAnythingReadAloud", + base::FEATURE_DISABLED_BY_DEFAULT); + +bool IsReadAnythingReadAloudEnabled() { + return base::FeatureList::IsEnabled(::features::kReadAnythingReadAloud); +} + BASE_FEATURE(kPdfOcr, "PdfOcr", base::FEATURE_DISABLED_BY_DEFAULT); bool IsPdfOcrEnabled() {
diff --git a/ui/accessibility/accessibility_features.h b/ui/accessibility/accessibility_features.h index 846fb8e..99a3ae3 100644 --- a/ui/accessibility/accessibility_features.h +++ b/ui/accessibility/accessibility_features.h
@@ -240,6 +240,11 @@ // If enabled, use the WebUI toolbar in Read Anything. AX_BASE_EXPORT bool IsReadAnythingWebUIToolbarEnabled(); +AX_BASE_EXPORT BASE_DECLARE_FEATURE(kReadAnythingReadAloud); + +// If enabled, show the Read Aloud feature in Read Anything. +AX_BASE_EXPORT bool IsReadAnythingReadAloudEnabled(); + // Enables a feature whereby inaccessible (i.e. untagged) PDFs are made // accessible using an optical character recognition service. Due to the size of // the OCR component, this feature targets desktop versions of Chrome for now.
diff --git a/ui/file_manager/file_manager/foreground/js/crostini_controller.js b/ui/file_manager/file_manager/foreground/js/crostini_controller.js index aa08ba24..e076b2b 100644 --- a/ui/file_manager/file_manager/foreground/js/crostini_controller.js +++ b/ui/file_manager/file_manager/foreground/js/crostini_controller.js
@@ -8,7 +8,7 @@ import {str, strf, util} from '../../common/js/util.js'; import {VolumeManagerCommon} from '../../common/js/volume_manager_types.js'; import {Crostini} from '../../externs/background/crostini.js'; -import {addUiEntry, removeUiEntry} from '../../state/actions/ui_entries.js'; +import {addUiEntry, removeUiEntry} from '../../state/ducks/ui_entries.js'; import {crostiniPlaceHolderKey} from '../../state/ducks/volumes.js'; import {getStore} from '../../state/store.js';
diff --git a/ui/file_manager/file_manager/foreground/js/file_manager.js b/ui/file_manager/file_manager/foreground/js/file_manager.js index 8f41eb3..0cf374c2 100644 --- a/ui/file_manager/file_manager/foreground/js/file_manager.js +++ b/ui/file_manager/file_manager/foreground/js/file_manager.js
@@ -33,9 +33,9 @@ import {PropStatus} from '../../externs/ts/state.js'; import {Store} from '../../externs/ts/store.js'; import {updatePreferences} from '../../state/actions/preferences.js'; -import {addUiEntry, removeUiEntry} from '../../state/actions/ui_entries.js'; import {updateBulkPinProgress} from '../../state/ducks/bulk_pinning.js'; import {updateSearch} from '../../state/ducks/search.js'; +import {addUiEntry, removeUiEntry} from '../../state/ducks/ui_entries.js'; import {trashRootKey} from '../../state/ducks/volumes.js'; import {getMyFiles} from '../../state/reducers/all_entries.js'; import {getEmptyState, getStore} from '../../state/store.js';
diff --git a/ui/file_manager/file_manager/foreground/js/guest_os_controller.js b/ui/file_manager/file_manager/foreground/js/guest_os_controller.js index ad8e7ca..070a09a 100644 --- a/ui/file_manager/file_manager/foreground/js/guest_os_controller.js +++ b/ui/file_manager/file_manager/foreground/js/guest_os_controller.js
@@ -7,7 +7,7 @@ import {util} from '../../common/js/util.js'; import {VolumeManagerCommon} from '../../common/js/volume_manager_types.js'; import {VolumeManager} from '../../externs/volume_manager.js'; -import {addUiEntry, removeUiEntry} from '../../state/actions/ui_entries.js'; +import {addUiEntry, removeUiEntry} from '../../state/ducks/ui_entries.js'; import {getEntry, getStore} from '../../state/store.js'; import {DirectoryModel} from './directory_model.js'; @@ -69,23 +69,20 @@ } } - const newGuestOsPlaceholders = - guests.map(guest => { - const guestOsEntry = - new GuestOsPlaceholder(guest.displayName, guest.id, guest.vmType); - const navigationModelItem = new NavigationModelFakeItem( - guest.displayName, NavigationModelItemType.GUEST_OS, - guestOsEntry); - const volumeType = - guest.vmType == chrome.fileManagerPrivate.VmType.ARCVM ? - VolumeManagerCommon.VolumeType.ANDROID_FILES : - VolumeManagerCommon.VolumeType.GUEST_OS; + const newGuestOsPlaceholders = guests.map(guest => { + const guestOsEntry = + new GuestOsPlaceholder(guest.displayName, guest.id, guest.vmType); + const navigationModelItem = new NavigationModelFakeItem( + guest.displayName, NavigationModelItemType.GUEST_OS, guestOsEntry); + const volumeType = + guest.vmType == chrome.fileManagerPrivate.VmType.ARCVM ? + VolumeManagerCommon.VolumeType.ANDROID_FILES : + VolumeManagerCommon.VolumeType.GUEST_OS; - navigationModelItem.disabled = - this.volumeManager_.isDisabled(volumeType); - store.dispatch(addUiEntry({entry: guestOsEntry})); - return navigationModelItem; - }); + navigationModelItem.disabled = this.volumeManager_.isDisabled(volumeType); + store.dispatch(addUiEntry({entry: guestOsEntry})); + return navigationModelItem; + }); if (!util.isFilesAppExperimental()) { this.directoryTree_.dataModel.guestOsPlaceholders =
diff --git a/ui/file_manager/file_manager/state/actions.ts b/ui/file_manager/file_manager/state/actions.ts index 74571c2..20e3526 100644 --- a/ui/file_manager/file_manager/state/actions.ts +++ b/ui/file_manager/file_manager/state/actions.ts
@@ -8,9 +8,9 @@ import {AddFolderShortcutAction, RefreshFolderShortcutAction, RemoveFolderShortcutAction} from './actions/folder_shortcuts.js'; import {RefreshNavigationRootsAction, UpdateNavigationEntryAction} from './actions/navigation.js'; import {UpdatePreferencesAction} from './actions/preferences.js'; -import {AddUiEntryAction, RemoveUiEntryAction} from './actions/ui_entries.js'; import {UpdateBulkPinProgressAction} from './ducks/bulk_pinning.js'; import {SearchAction} from './ducks/search.js'; +import {AddUiEntryAction, RemoveUiEntryAction} from './ducks/ui_entries.js'; import {AddVolumeAction, RemoveVolumeAction, UpdateIsInteractiveVolumeAction} from './ducks/volumes.js'; /**
diff --git a/ui/file_manager/file_manager/state/actions/ui_entries.ts b/ui/file_manager/file_manager/state/actions/ui_entries.ts deleted file mode 100644 index 32b5f13a..0000000 --- a/ui/file_manager/file_manager/state/actions/ui_entries.ts +++ /dev/null
@@ -1,51 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import {FakeEntryImpl} from '../../common/js/files_app_entry_types.js'; -import {FileKey} from '../../externs/ts/state.js'; -import {BaseAction} from '../../lib/base_store.js'; -import {ActionType} from '../actions.js'; - -/** - * Actions for UI entries. - * - * UI entries represents entries shown on UI only (aka FakeEntry, e.g. - * Recents/Trash/Google Drive wrapper), they don't have a real entry backup in - * the file system. - */ - - -/** Action add single UI entry into the store. */ -export interface AddUiEntryAction extends BaseAction { - type: ActionType.ADD_UI_ENTRY; - payload: { - entry: FakeEntryImpl, - }; -} - -/** Action remove single UI entry from the store. */ -export interface RemoveUiEntryAction extends BaseAction { - type: ActionType.REMOVE_UI_ENTRY; - payload: { - key: FileKey, - }; -} - -/** Action factory to add single UI entry into the store. */ -export function addUiEntry(payload: AddUiEntryAction['payload']): - AddUiEntryAction { - return { - type: ActionType.ADD_UI_ENTRY, - payload, - }; -} - -/** Action factory to remove single UI entry from the store. */ -export function removeUiEntry(payload: RemoveUiEntryAction['payload']): - RemoveUiEntryAction { - return { - type: ActionType.REMOVE_UI_ENTRY, - payload, - }; -}
diff --git a/ui/file_manager/file_manager/state/reducers/ui_entries.ts b/ui/file_manager/file_manager/state/ducks/ui_entries.ts similarity index 67% rename from ui/file_manager/file_manager/state/reducers/ui_entries.ts rename to ui/file_manager/file_manager/state/ducks/ui_entries.ts index 012ee48..0e795c7c 100644 --- a/ui/file_manager/file_manager/state/reducers/ui_entries.ts +++ b/ui/file_manager/file_manager/state/ducks/ui_entries.ts
@@ -6,11 +6,23 @@ import {FakeEntryImpl} from '../../common/js/files_app_entry_types.js'; import {util} from '../../common/js/util.js'; import {VolumeManagerCommon} from '../../common/js/volume_manager_types.js'; -import {State} from '../../externs/ts/state.js'; -import {AddUiEntryAction, RemoveUiEntryAction} from '../actions/ui_entries.js'; +import {FileKey, State} from '../../externs/ts/state.js'; +import {addReducer, BaseAction, Reducer, ReducersMap} from '../../lib/base_store.js'; +import {Action, ActionType} from '../actions.js'; +import {getMyFiles} from '../reducers/all_entries.js'; import {getEntry, getFileData} from '../store.js'; -import {getMyFiles} from './all_entries.js'; +/** + * Actions and reducers for UI entries. + * + * UI entries represents entries shown on UI only (aka FakeEntry, e.g. + * Recents/Trash/Google Drive wrapper), they don't have a real entry backup in + * the file system. + */ + + +/** Map of actions to reducers for the UI entries slice. */ +export const uiEntriesReducersMap: ReducersMap<State, Action> = new Map(); const uiEntryRootTypesInMyFiles = new Set([ VolumeManagerCommon.RootType.ANDROID_FILES, @@ -18,9 +30,18 @@ VolumeManagerCommon.RootType.GUEST_OS, ]); -export function addUiEntry( - currentState: State, action: AddUiEntryAction): State { - const {entry} = action.payload; + +/** Action add single UI entry into the store. */ +export interface AddUiEntryAction extends BaseAction { + type: ActionType.ADD_UI_ENTRY; + payload: { + entry: FakeEntryImpl, + }; +} + +export function addUiEntryReducer( + currentState: State, payload: AddUiEntryAction['payload']): State { + const {entry} = payload; const key = entry.toURL(); let isVolumeEntryExistedInMyFiles = false; @@ -70,9 +91,22 @@ }; } -export function removeUiEntry( - currentState: State, action: RemoveUiEntryAction): State { - const key = action.payload.key; +/** Action factory to add single UI entry into the store. */ +export const addUiEntry = addReducer( + ActionType.ADD_UI_ENTRY, addUiEntryReducer as Reducer<State, Action>, + uiEntriesReducersMap); + +/** Action remove single UI entry from the store. */ +export interface RemoveUiEntryAction extends BaseAction { + type: ActionType.REMOVE_UI_ENTRY; + payload: { + key: FileKey, + }; +} + +export function removeUiEntryReducer( + currentState: State, payload: RemoveUiEntryAction['payload']): State { + const {key} = payload; const entry = getEntry(currentState, key) as FakeEntryImpl | null; if (currentState.uiEntries.find(k => k === key)) { // Shallow copy. @@ -102,3 +136,8 @@ ...currentState, }; } + +/** Action factory to remove single UI entry from the store. */ +export const removeUiEntry = addReducer( + ActionType.REMOVE_UI_ENTRY, removeUiEntryReducer as Reducer<State, Action>, + uiEntriesReducersMap);
diff --git a/ui/file_manager/file_manager/state/reducers/ui_entries_unittest.ts b/ui/file_manager/file_manager/state/ducks/ui_entries_unittest.ts similarity index 98% rename from ui/file_manager/file_manager/state/reducers/ui_entries_unittest.ts rename to ui/file_manager/file_manager/state/ducks/ui_entries_unittest.ts index a36ef624..89ccd89f 100644 --- a/ui/file_manager/file_manager/state/reducers/ui_entries_unittest.ts +++ b/ui/file_manager/file_manager/state/ducks/ui_entries_unittest.ts
@@ -13,12 +13,12 @@ import {VolumeManagerCommon} from '../../common/js/volume_manager_types.js'; import {FileData, State} from '../../externs/ts/state.js'; import {VolumeInfo} from '../../externs/volume_info.js'; -import {addUiEntry, removeUiEntry} from '../actions/ui_entries.js'; import {createFakeVolumeMetadata, setUpFileManagerOnWindow, setupStore, waitDeepEquals} from '../for_tests.js'; +import {convertEntryToFileData} from '../reducers/all_entries.js'; import {getEmptyState} from '../store.js'; -import {convertEntryToFileData} from './all_entries.js'; -import {convertVolumeInfoAndMetadataToVolume} from '../ducks/volumes.js'; +import {addUiEntry, removeUiEntry} from './ui_entries.js'; +import {convertVolumeInfoAndMetadataToVolume} from './volumes.js'; export function setUp() { // sortEntries() from addUiEntry() reducer requires volumeManager and
diff --git a/ui/file_manager/file_manager/state/reducers/root.ts b/ui/file_manager/file_manager/state/reducers/root.ts index 360198d..11a41218 100644 --- a/ui/file_manager/file_manager/state/reducers/root.ts +++ b/ui/file_manager/file_manager/state/reducers/root.ts
@@ -6,6 +6,7 @@ import {Action, ActionType} from '../actions.js'; import {bulkPinningReducersMap} from '../ducks/bulk_pinning.js'; import {searchReducersMap} from '../ducks/search.js'; +import {uiEntriesReducersMap} from '../ducks/ui_entries.js'; import {volumesReducersMap} from '../ducks/volumes.js'; import {addChildEntries, cacheEntries, clearCachedEntries, updateMetadata} from './all_entries.js'; @@ -14,11 +15,14 @@ import {addFolderShortcut, refreshFolderShortcut, removeFolderShortcut} from './folder_shortcuts.js'; import {refreshNavigationRoots, updateNavigationEntry} from './navigation.js'; import {updatePreferences} from './preferences.js'; -import {addUiEntry, removeUiEntry} from './ui_entries.js'; // Reducers map created from merging together each slice's exported reducersMap. -const rootReducersMap = new Map( - [...searchReducersMap, ...volumesReducersMap, ...bulkPinningReducersMap]); +const rootReducersMap = new Map([ + ...searchReducersMap, + ...volumesReducersMap, + ...bulkPinningReducersMap, + ...uiEntriesReducersMap, +]); /** * Root reducer for the State for Files app. @@ -56,10 +60,6 @@ return refreshNavigationRoots(currentState, action); case ActionType.UPDATE_NAVIGATION_ENTRY: return updateNavigationEntry(currentState, action); - case ActionType.ADD_UI_ENTRY: - return addUiEntry(currentState, action); - case ActionType.REMOVE_UI_ENTRY: - return removeUiEntry(currentState, action); case ActionType.REFRESH_FOLDER_SHORTCUT: return refreshFolderShortcut(currentState, action); case ActionType.ADD_FOLDER_SHORTCUT:
diff --git a/ui/file_manager/file_names.gni b/ui/file_manager/file_names.gni index 2b2e7d81..4eacbe6 100644 --- a/ui/file_manager/file_names.gni +++ b/ui/file_manager/file_names.gni
@@ -258,7 +258,6 @@ "file_manager/state/actions/folder_shortcuts.ts", "file_manager/state/actions/navigation.ts", "file_manager/state/actions/preferences.ts", - "file_manager/state/actions/ui_entries.ts", # ActionsProducers. "file_manager/state/actions_producers/all_entries.ts", @@ -272,11 +271,11 @@ "file_manager/state/reducers/folder_shortcuts.ts", "file_manager/state/reducers/navigation.ts", "file_manager/state/reducers/preferences.ts", - "file_manager/state/reducers/ui_entries.ts", # Ducks. "file_manager/state/ducks/bulk_pinning.ts", "file_manager/state/ducks/search.ts", + "file_manager/state/ducks/ui_entries.ts", "file_manager/state/ducks/volumes.ts", # Containers. @@ -406,12 +405,12 @@ "file_manager/state/reducers/folder_shortcuts_unittest.ts", "file_manager/state/reducers/navigation_unittest.ts", "file_manager/state/reducers/preferences_unittest.ts", - "file_manager/state/reducers/ui_entries_unittest.ts", # Ducks: "file_manager/state/ducks/bulk_pinning_unittest.ts", "file_manager/state/ducks/search_unittest.ts", "file_manager/state/ducks/volumes_unittest.ts", + "file_manager/state/ducks/ui_entries_unittest.ts", # Widgets: "file_manager/widgets/xf_breadcrumb_unittest.ts",
diff --git a/ui/gtk/gtk_util.cc b/ui/gtk/gtk_util.cc index 1c23c0f..01f5411 100644 --- a/ui/gtk/gtk_util.cc +++ b/ui/gtk/gtk_util.cc
@@ -31,6 +31,7 @@ #include "ui/linux/linux_ui.h" #include "ui/native_theme/common_theme.h" #include "ui/ozone/public/ozone_platform.h" +#include "ui/views/widget/desktop_aura/desktop_window_tree_host_linux.h" namespace gtk { @@ -174,6 +175,13 @@ return GetOpacityFromRenderNode(GetRenderNodeChild(node)); } +// Runs DesktopWindowTreeHostLinux::EnableEventListening() when the dialog is +// closed. +void OnDialogDestroy(base::OnceClosure* callback_raw) { + std::unique_ptr<base::OnceClosure> callback = base::WrapUnique(callback_raw); + std::move(*callback).Run(); +} + } // namespace const char* GtkCssMenu() { @@ -224,6 +232,30 @@ parent->GetHost()->GetAcceleratedWidget()); } +void DisableHostInputHandling(GtkWidget* dialog, aura::Window* parent) { + if (!parent) { + return; + } + auto* host = + static_cast<views::DesktopWindowTreeHostLinux*>(parent->GetHost()); + if (!host) { + return; + } + + // In some circumstances the mouse has been captured and by turning off event + // listening, it is never released. So we manually ensure there is no current + // capture. + host->ReleaseCapture(); + auto callback = + std::make_unique<base::OnceClosure>(host->DisableEventListening()); + // OnDialogDestroy() is called when |dialog| destroyed, which allows + // to invoke the callback function to re-enable event handling on the + // owning window. + g_object_set_data_full(G_OBJECT(dialog), "callback", callback.release(), + reinterpret_cast<GDestroyNotify>(OnDialogDestroy)); + gtk_window_set_modal(GTK_WINDOW(dialog), TRUE); +} + void ParseButtonLayout(const std::string& button_string, std::vector<views::FrameButton>* leading_buttons, std::vector<views::FrameButton>* trailing_buttons) {
diff --git a/ui/gtk/gtk_util.h b/ui/gtk/gtk_util.h index 10487a2..0366678 100644 --- a/ui/gtk/gtk_util.h +++ b/ui/gtk/gtk_util.h
@@ -42,6 +42,9 @@ // Clears the transient parent for |dialog|. void ClearAuraTransientParent(GtkWidget* dialog, aura::Window* parent); +// Disable input events handling on `parent` to make `dialog` modal. +void DisableHostInputHandling(GtkWidget* dialog, aura::Window* parent); + // Parses |button_string| into |leading_buttons| and // |trailing_buttons|. The string is of the format // "<button>*:<button*>", for example, "close:minimize:maximize".
diff --git a/ui/gtk/printing/print_dialog_gtk.cc b/ui/gtk/printing/print_dialog_gtk.cc index 4e2c27c..154082c8 100644 --- a/ui/gtk/printing/print_dialog_gtk.cc +++ b/ui/gtk/printing/print_dialog_gtk.cc
@@ -391,8 +391,9 @@ gtk_print_settings_set_print_pages(gtk_settings_, GTK_PRINT_PAGES_ALL); } - // Set modal so user cannot focus the same tab and press print again. - gtk_window_set_modal(GTK_WINDOW(dialog_), TRUE); + // Disable input handling so the user cannot focus the same tab and press + // print again. + gtk::DisableHostInputHandling(dialog_, parent_view); // Since we only generate PDF, only show printers that support PDF. // TODO(thestig) Add more capabilities to support?
diff --git a/ui/gtk/select_file_dialog_linux_gtk.cc b/ui/gtk/select_file_dialog_linux_gtk.cc index c1b1b1b3..a9ee144 100644 --- a/ui/gtk/select_file_dialog_linux_gtk.cc +++ b/ui/gtk/select_file_dialog_linux_gtk.cc
@@ -74,13 +74,6 @@ return save; } -// Runs DesktopWindowTreeHostLinux::EnableEventListening() when the file-picker -// is closed. -void OnFilePickerDestroy(base::OnceClosure* callback_raw) { - std::unique_ptr<base::OnceClosure> callback = base::WrapUnique(callback_raw); - std::move(*callback).Run(); -} - void GtkFileChooserSetFilename(GtkFileChooser* dialog, const base::FilePath& path) { if (GtkCheckVersion(4)) { @@ -271,27 +264,7 @@ params_map_[dialog] = params; - // Disable input events handling in the host window to make this dialog modal. - if (owning_window) { - views::DesktopWindowTreeHostLinux* host = - static_cast<views::DesktopWindowTreeHostLinux*>( - owning_window->GetHost()); - if (host) { - // In some circumstances (e.g. dialog from flash plugin) the mouse has - // been captured and by turning off event listening, it is never - // released. So we manually ensure there is no current capture. - host->ReleaseCapture(); - std::unique_ptr<base::OnceClosure> callback = - std::make_unique<base::OnceClosure>(host->DisableEventListening()); - // OnFilePickerDestroy() is called when |dialog| destroyed, which allows - // to invoke the callback function to re-enable event handling on the - // owning window. - g_object_set_data_full( - G_OBJECT(dialog), "callback", callback.release(), - reinterpret_cast<GDestroyNotify>(OnFilePickerDestroy)); - gtk_window_set_modal(GTK_WINDOW(dialog), TRUE); - } - } + DisableHostInputHandling(dialog, owning_window); if (!GtkCheckVersion(4)) gtk_widget_show_all(dialog);
diff --git a/ui/touch_selection/BUILD.gn b/ui/touch_selection/BUILD.gn index 074bcc0..3e218b15 100644 --- a/ui/touch_selection/BUILD.gn +++ b/ui/touch_selection/BUILD.gn
@@ -85,12 +85,14 @@ "longpress_drag_selector_unittest.cc", "touch_handle_unittest.cc", "touch_selection_controller_unittest.cc", + "touch_selection_metrics_unittest.cc", ] deps = [ ":test_support", ":touch_selection", "//base/test:run_all_unittests", + "//base/test:test_support", "//testing/gmock:gmock", "//testing/gtest:gtest", "//ui/base:base",
diff --git a/ui/touch_selection/touch_selection_controller.cc b/ui/touch_selection/touch_selection_controller.cc index a2fcf10b..813000c 100644 --- a/ui/touch_selection/touch_selection_controller.cc +++ b/ui/touch_selection/touch_selection_controller.cc
@@ -173,6 +173,8 @@ } bool TouchSelectionController::WillHandleTouchEvent(const MotionEvent& event) { + const bool is_down_event = event.GetAction() == MotionEvent::Action::DOWN; + session_metrics_recorder_.OnTouchEvent(is_down_event); bool handled = WillHandleTouchEventImpl(event); // If Action::DOWN is consumed, the rest of touch sequence should be consumed, // too, regardless of value of |handled|. @@ -180,8 +182,9 @@ // Ideally we should consume until the final Action::UP/Action::CANCEL. // But, apparently, we can't reliably determine the final Action::CANCEL in a // multi-touch scenario. See https://crbug.com/653212. - if (event.GetAction() == MotionEvent::Action::DOWN) + if (is_down_event) { consume_touch_sequence_ = handled; + } return handled || consume_touch_sequence_; } @@ -225,6 +228,18 @@ response_pending_input_event_ = INPUT_EVENT_TYPE_NONE; } +void TouchSelectionController::OnMenuCommand(bool should_dismiss_handles) { + session_metrics_recorder_.OnMenuCommand(should_dismiss_handles); + if (should_dismiss_handles) { + HideAndDisallowShowingAutomatically(); + } +} + +void TouchSelectionController::OnSessionEndEvent(const Event& event) { + session_metrics_recorder_.OnSessionEndEvent(event); + HideAndDisallowShowingAutomatically(); +} + void TouchSelectionController::HideHandles() { response_pending_input_event_ = INPUT_EVENT_TYPE_NONE; DeactivateInsertion(); @@ -236,6 +251,7 @@ } void TouchSelectionController::HideAndDisallowShowingAutomatically() { + session_metrics_recorder_.ResetMetrics(); HideHandles(); show_touch_handles_ = false; } @@ -571,6 +587,7 @@ bool TouchSelectionController::ActivateInsertionIfNecessary() { DCHECK_NE(SELECTION_ACTIVE, active_status_); + session_metrics_recorder_.OnCursorActivationEvent(); if (!insertion_handle_) { insertion_handle_ = std::make_unique<TouchHandle>( @@ -599,6 +616,7 @@ bool TouchSelectionController::ActivateSelectionIfNecessary() { DCHECK_NE(INSERTION_ACTIVE, active_status_); + session_metrics_recorder_.OnSelectionActivationEvent(); if (!start_selection_handle_) { start_selection_handle_ =
diff --git a/ui/touch_selection/touch_selection_controller.h b/ui/touch_selection/touch_selection_controller.h index 4fb88a6c6..3333724 100644 --- a/ui/touch_selection/touch_selection_controller.h +++ b/ui/touch_selection/touch_selection_controller.h
@@ -16,10 +16,12 @@ #include "ui/touch_selection/selection_event_type.h" #include "ui/touch_selection/touch_handle.h" #include "ui/touch_selection/touch_handle_orientation.h" +#include "ui/touch_selection/touch_selection_metrics.h" #include "ui/touch_selection/ui_touch_selection_export.h" namespace ui { class MotionEvent; +class Event; // Interface through which |TouchSelectionController| issues selection-related // commands, notifications and requests. @@ -111,6 +113,13 @@ // long-press drag. void OnScrollBeginEvent(); + // To be called when a menu command has been requested, to dismiss touch + // handles and record metrics if needed. + void OnMenuCommand(bool should_dismiss_handles); + + // To be called when an event occurs to deactivate touch selection. + void OnSessionEndEvent(const Event& event); + // Hide the handles and suppress bounds updates until the next explicit // showing allowance. void HideAndDisallowShowingAutomatically(); @@ -267,6 +276,8 @@ bool consume_touch_sequence_; bool show_touch_handles_; + + TouchSelectionSessionMetricsRecorder session_metrics_recorder_; }; } // namespace ui
diff --git a/ui/touch_selection/touch_selection_metrics.cc b/ui/touch_selection/touch_selection_metrics.cc index cf8729d1..72ce3ae2 100644 --- a/ui/touch_selection/touch_selection_metrics.cc +++ b/ui/touch_selection/touch_selection_metrics.cc
@@ -5,29 +5,52 @@ #include "ui/touch_selection/touch_selection_metrics.h" #include "base/metrics/histogram_functions.h" +#include "base/time/time.h" #include "ui/base/pointer/touch_editing_controller.h" +#include "ui/events/event.h" namespace ui { namespace { +constexpr int kSessionTouchDownCountMin = 1; +constexpr int kSessionTouchDownCountMax = 20; +constexpr int kSessionTouchDownCountBuckets = 20; + +// Duration of inactivity after which we consider a touch selection session to +// have timed out for the purpose of determining session action count metrics. +constexpr base::TimeDelta kSessionTimeoutDuration = base::Seconds(10); + TouchSelectionMenuAction MapCommandIdToMenuAction(int command_id) { switch (command_id) { - case ui::TouchEditable::kCut: + case TouchEditable::kCut: return TouchSelectionMenuAction::kCut; - case ui::TouchEditable::kCopy: + case TouchEditable::kCopy: return TouchSelectionMenuAction::kCopy; - case ui::TouchEditable::kPaste: + case TouchEditable::kPaste: return TouchSelectionMenuAction::kPaste; - case ui::TouchEditable::kSelectAll: + case TouchEditable::kSelectAll: return TouchSelectionMenuAction::kSelectAll; - case ui::TouchEditable::kSelectWord: + case TouchEditable::kSelectWord: return TouchSelectionMenuAction::kSelectWord; default: NOTREACHED_NORETURN() << "Invalid command id: " << command_id; } } +// We want to record the touch down count required to get to a successful cursor +// placement or selection, but it's hard to know if this has happened. We'll +// just consider a session to be successful if it ends in a character key event +// or an IME fabricated key event (e.g. from the ChromeOS virtual keyboard). +bool IsSuccessfulSessionEndEvent(const Event& session_end_event) { + if (!session_end_event.IsKeyEvent()) { + return false; + } + + return session_end_event.AsKeyEvent()->GetDomKey().IsCharacter() || + session_end_event.flags() & EF_IME_FABRICATED_KEY; +} + } // namespace void RecordTouchSelectionDrag(TouchSelectionDragType drag_type) { @@ -50,4 +73,109 @@ TouchSelectionMenuAction::kSmartAction); } +TouchSelectionSessionMetricsRecorder::TouchSelectionSessionMetricsRecorder() = + default; + +TouchSelectionSessionMetricsRecorder::~TouchSelectionSessionMetricsRecorder() = + default; + +void TouchSelectionSessionMetricsRecorder::OnCursorActivationEvent() { + if (!IsSessionActive()) { + // We assume that an initial activation event occurs after a single touch + // down movement (from a tap or long press). This is not always correct, + // e.g. if the user double taps quickly enough then the cursor event from + // the first tap might occur after the second tap was already detected. But + // it should be ok to assume that this won't be a problem most of the time. + session_touch_down_count_ = 1; + } + + active_status_ = ActiveStatus::kActiveCursor; +} + +void TouchSelectionSessionMetricsRecorder::OnSelectionActivationEvent() { + if (!IsSessionActive()) { + // We assume that an initial activation event occurs after a single touch + // down movement (from a long press), since a selection event from a + // repeated tap would usually only occur after a cursor event from the + // first tap has already started the session. + session_touch_down_count_ = 1; + } + + active_status_ = ActiveStatus::kActiveSelection; +} + +void TouchSelectionSessionMetricsRecorder::OnTouchEvent(bool is_down_event) { + RefreshSessionStatus(); + if (!IsSessionActive()) { + return; + } + + session_touch_down_count_ += is_down_event; +} + +void TouchSelectionSessionMetricsRecorder::OnMenuCommand( + bool should_end_session) { + RefreshSessionStatus(); + if (!IsSessionActive()) { + return; + } + + // We assume that a menu button was tapped, but only include this in the touch + // down count if the session continues (since we want to know the touch down + // count required to get to a successful cursor placement or selection, which + // would have occurred before the menu button was tapped). + if (should_end_session) { + RecordSessionMetrics(); + ResetMetrics(); + } else { + session_touch_down_count_++; + } +} + +void TouchSelectionSessionMetricsRecorder::OnSessionEndEvent( + const Event& session_end_event) { + RefreshSessionStatus(); + if (!IsSessionActive()) { + return; + } + + if (IsSuccessfulSessionEndEvent(session_end_event)) { + RecordSessionMetrics(); + } + ResetMetrics(); +} + +void TouchSelectionSessionMetricsRecorder::ResetMetrics() { + active_status_ = ActiveStatus::kInactive; + last_activity_time_ = base::TimeTicks(); + session_touch_down_count_ = 0; +} + +void TouchSelectionSessionMetricsRecorder::RefreshSessionStatus() { + // After a period of inactivity, we consider a session to have timed out since + // the user intent has probably changed. + if (last_activity_time_ + kSessionTimeoutDuration < base::TimeTicks::Now()) { + ResetMetrics(); + } + + last_activity_time_ = base::TimeTicks::Now(); +} + +bool TouchSelectionSessionMetricsRecorder::IsSessionActive() const { + return active_status_ != ActiveStatus::kInactive; +} + +void TouchSelectionSessionMetricsRecorder::RecordSessionMetrics() const { + if (!IsSessionActive()) { + return; + } + + base::UmaHistogramCustomCounts( + active_status_ == ActiveStatus::kActiveCursor + ? kTouchCursorSessionTouchDownCountHistogramName + : kTouchSelectionSessionTouchDownCountHistogramName, + session_touch_down_count_, kSessionTouchDownCountMin, + kSessionTouchDownCountMax, kSessionTouchDownCountBuckets); +} + } // namespace ui
diff --git a/ui/touch_selection/touch_selection_metrics.h b/ui/touch_selection/touch_selection_metrics.h index fb99da2e..19d8a1f 100644 --- a/ui/touch_selection/touch_selection_metrics.h +++ b/ui/touch_selection/touch_selection_metrics.h
@@ -5,9 +5,11 @@ #ifndef UI_TOUCH_SELECTION_TOUCH_SELECTION_METRICS_H_ #define UI_TOUCH_SELECTION_TOUCH_SELECTION_METRICS_H_ +#include "base/time/time.h" #include "ui/touch_selection/ui_touch_selection_export.h" namespace ui { +class Event; inline constexpr char kTouchSelectionDragTypeHistogramName[] = "InputMethod.TouchSelection.DragType"; @@ -15,6 +17,12 @@ inline constexpr char kTouchSelectionMenuActionHistogramName[] = "InputMethod.TouchSelection.MenuAction"; +inline constexpr char kTouchCursorSessionTouchDownCountHistogramName[] = + "InputMethod.TouchSelection.CursorSession.TouchDownCount"; + +inline constexpr char kTouchSelectionSessionTouchDownCountHistogramName[] = + "InputMethod.TouchSelection.SelectionSession.TouchDownCount"; + // These values are persisted to logs. Entries should not be renumbered and // numeric values should never be reused. enum class TouchSelectionDragType { @@ -47,6 +55,69 @@ UI_TOUCH_SELECTION_EXPORT void RecordTouchSelectionMenuEllipsisAction(); UI_TOUCH_SELECTION_EXPORT void RecordTouchSelectionMenuSmartAction(); +// Helper class for tracking the state of touch selection sessions and recording +// session related metrics. +class UI_TOUCH_SELECTION_EXPORT TouchSelectionSessionMetricsRecorder { + public: + TouchSelectionSessionMetricsRecorder(); + + TouchSelectionSessionMetricsRecorder( + const TouchSelectionSessionMetricsRecorder&) = delete; + TouchSelectionSessionMetricsRecorder& operator=( + const TouchSelectionSessionMetricsRecorder&) = delete; + + ~TouchSelectionSessionMetricsRecorder(); + + // Called when the cursor or selection handles are shown or moved. This starts + // the session if it is not yet active and updates the session type (cursor or + // selection) if needed. + void OnCursorActivationEvent(); + void OnSelectionActivationEvent(); + + // Called when a touch event occurs, to update the session status and touch + // down count. We assume this is only called for touch events targeting the + // touch selection context window (e.g. for tapping on the text or dragging + // touch handles, but not for tapping popup menu buttons). + void OnTouchEvent(bool is_down_event); + + // Called when a menu command has been requested. If `should_end_session` is + // true, the session ends and metrics are recorded. Otherwise, the touch down + // count is incremented (since we assume a menu button was tapped) and the + // session continues. + void OnMenuCommand(bool should_end_session); + + // Called when an event occurs to deactivate touch selection. This ends the + // session and records metrics if the session is deemed successful. + void OnSessionEndEvent(const Event& session_end_event); + + // Resets the session state, effectively ending the session without recording + // metrics. + void ResetMetrics(); + + private: + enum class ActiveStatus { + kInactive, + kActiveCursor, + kActiveSelection, + }; + + // Helper to be called when user activity is detected (e.g. touch event or + // menu action), to check whether the session should continue or be considered + // timed out. + void RefreshSessionStatus(); + + bool IsSessionActive() const; + + void RecordSessionMetrics() const; + + ActiveStatus active_status_ = ActiveStatus::kInactive; + + // The time of the most recently detected user activity. + base::TimeTicks last_activity_time_ = base::TimeTicks(); + + int session_touch_down_count_ = 0; +}; + } // namespace ui #endif // UI_TOUCH_SELECTION_TOUCH_SELECTION_METRICS_H_
diff --git a/ui/touch_selection/touch_selection_metrics_unittest.cc b/ui/touch_selection/touch_selection_metrics_unittest.cc new file mode 100644 index 0000000..f9d5944 --- /dev/null +++ b/ui/touch_selection/touch_selection_metrics_unittest.cc
@@ -0,0 +1,171 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/touch_selection/touch_selection_metrics.h" + +#include "base/test/metrics/histogram_tester.h" +#include "base/test/task_environment.h" +#include "base/time/time.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "ui/events/base_event_utils.h" +#include "ui/events/event.h" +#include "ui/events/event_constants.h" +#include "ui/events/keycodes/dom/dom_code.h" +#include "ui/events/keycodes/keyboard_codes.h" +#include "ui/events/types/event_type.h" + +namespace ui { + +namespace { + +TEST(TouchSelectionSessionMetricsTest, RecordsSuccessfulCursorSession) { + base::HistogramTester histogram_tester; + TouchSelectionSessionMetricsRecorder session_metrics_recorder; + + // Activate cursor, then end session successfully with a menu command. + session_metrics_recorder.OnTouchEvent(true); + session_metrics_recorder.OnCursorActivationEvent(); + session_metrics_recorder.OnMenuCommand(true); + + histogram_tester.ExpectUniqueSample( + kTouchCursorSessionTouchDownCountHistogramName, 1, 1); +} + +TEST(TouchSelectionSessionMetricsTest, RecordsSuccessfulSelectionSession) { + base::HistogramTester histogram_tester; + TouchSelectionSessionMetricsRecorder session_metrics_recorder; + + // Activate selection, then end session successfully with a menu command. + session_metrics_recorder.OnTouchEvent(true); + session_metrics_recorder.OnSelectionActivationEvent(); + session_metrics_recorder.OnMenuCommand(true); + + histogram_tester.ExpectUniqueSample( + kTouchSelectionSessionTouchDownCountHistogramName, 1, 1); +} + +TEST(TouchSelectionSessionMetricsTest, DoesNotRecordDismissedSession) { + base::HistogramTester histogram_tester; + TouchSelectionSessionMetricsRecorder session_metrics_recorder; + + // Activate selection, then dismiss session. + session_metrics_recorder.OnTouchEvent(true); + session_metrics_recorder.OnSelectionActivationEvent(); + session_metrics_recorder.ResetMetrics(); + + histogram_tester.ExpectTotalCount( + kTouchSelectionSessionTouchDownCountHistogramName, 0); +} + +TEST(TouchSelectionSessionMetricsTest, MultipleSessions) { + base::HistogramTester histogram_tester; + TouchSelectionSessionMetricsRecorder session_metrics_recorder; + + // Activate, then end session successfully with a menu command. + session_metrics_recorder.OnTouchEvent(true); + session_metrics_recorder.OnSelectionActivationEvent(); + session_metrics_recorder.OnMenuCommand(true); + // Activate, then dismiss session. + session_metrics_recorder.OnTouchEvent(true); + session_metrics_recorder.OnSelectionActivationEvent(); + session_metrics_recorder.ResetMetrics(); + // Activate, then end another session successfully. + session_metrics_recorder.OnTouchEvent(true); + session_metrics_recorder.OnSelectionActivationEvent(); + session_metrics_recorder.OnTouchEvent(true); + session_metrics_recorder.OnMenuCommand(true); + + histogram_tester.ExpectTotalCount( + kTouchSelectionSessionTouchDownCountHistogramName, 2); + // First session. + histogram_tester.ExpectBucketCount( + kTouchSelectionSessionTouchDownCountHistogramName, 1, 1); + // Third session. + histogram_tester.ExpectBucketCount( + kTouchSelectionSessionTouchDownCountHistogramName, 2, 1); +} + +TEST(TouchSelectionSessionMetricsTest, MultipleActivationEvents) { + base::HistogramTester histogram_tester; + TouchSelectionSessionMetricsRecorder session_metrics_recorder; + + // Activate cursor. + session_metrics_recorder.OnTouchEvent(true); + session_metrics_recorder.OnCursorActivationEvent(); + // Activate selection within the same session. + session_metrics_recorder.OnTouchEvent(true); + session_metrics_recorder.OnSelectionActivationEvent(); + // Perform some touch events. + session_metrics_recorder.OnTouchEvent(false); + session_metrics_recorder.OnTouchEvent(true); + // End session successfully with a menu command. + session_metrics_recorder.OnMenuCommand(true); + + // Selection session metrics should be recorded, since there was an active + // selection when the session ended. + histogram_tester.ExpectUniqueSample( + kTouchSelectionSessionTouchDownCountHistogramName, 3, 1); +} + +TEST(TouchSelectionSessionMetricsTest, RecordsAfterCharacterKeyEvent) { + base::HistogramTester histogram_tester; + TouchSelectionSessionMetricsRecorder session_metrics_recorder; + + // Activate cursor. + session_metrics_recorder.OnTouchEvent(true); + session_metrics_recorder.OnCursorActivationEvent(); + // End session successfully by typing a character key. + const KeyEvent key_event(ET_KEY_PRESSED, VKEY_A, DomCode::US_A, EF_NONE, + DomKey::FromCharacter('a'), EventTimeForNow()); + session_metrics_recorder.OnSessionEndEvent(key_event); + + histogram_tester.ExpectUniqueSample( + kTouchCursorSessionTouchDownCountHistogramName, 1, 1); +} + +TEST(TouchSelectionSessionMetricsTest, DoesNotRecordTimedOutSession) { + base::HistogramTester histogram_tester; + TouchSelectionSessionMetricsRecorder session_metrics_recorder; + base::test::TaskEnvironment task_environment( + base::test::TaskEnvironment::TimeSource::MOCK_TIME); + + // Activate selection. + session_metrics_recorder.OnTouchEvent(true); + session_metrics_recorder.OnSelectionActivationEvent(); + // Time out the session. + task_environment.FastForwardBy(base::Seconds(50)); + session_metrics_recorder.OnMenuCommand(true); + + // The session timed out and wasn't activated again, so we don't record touch + // down count metrics. + histogram_tester.ExpectTotalCount( + kTouchSelectionSessionTouchDownCountHistogramName, 0); +} + +TEST(TouchSelectionSessionMetricsTest, ActivationAfterTimeOut) { + base::HistogramTester histogram_tester; + TouchSelectionSessionMetricsRecorder session_metrics_recorder; + base::test::TaskEnvironment task_environment( + base::test::TaskEnvironment::TimeSource::MOCK_TIME); + + // Activate selection. + session_metrics_recorder.OnTouchEvent(true); + session_metrics_recorder.OnSelectionActivationEvent(); + // Time out the session. + task_environment.FastForwardBy(base::Seconds(50)); + // Activate selection again. + session_metrics_recorder.OnTouchEvent(true); + session_metrics_recorder.OnSelectionActivationEvent(); + session_metrics_recorder.OnMenuCommand(true); + + // Metrics should be recorded for the selection session that started from the + // activation event after the timeout. + histogram_tester.ExpectUniqueSample( + kTouchSelectionSessionTouchDownCountHistogramName, 1, 1); +} + +} // namespace + +} // namespace ui
diff --git a/weblayer/browser/reduce_accept_language_factory.cc b/weblayer/browser/reduce_accept_language_factory.cc index c916c27a..827f34dd 100644 --- a/weblayer/browser/reduce_accept_language_factory.cc +++ b/weblayer/browser/reduce_accept_language_factory.cc
@@ -34,9 +34,10 @@ ReduceAcceptLanguageFactory::~ReduceAcceptLanguageFactory() = default; -KeyedService* ReduceAcceptLanguageFactory::BuildServiceInstanceFor( +std::unique_ptr<KeyedService> +ReduceAcceptLanguageFactory::BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const { - return new reduce_accept_language::ReduceAcceptLanguageService( + return std::make_unique<reduce_accept_language::ReduceAcceptLanguageService>( HostContentSettingsMapFactory::GetForBrowserContext(context), static_cast<BrowserContextImpl*>(context)->pref_service(), context->IsOffTheRecord()); @@ -47,4 +48,4 @@ return context; } -} // namespace weblayer \ No newline at end of file +} // namespace weblayer
diff --git a/weblayer/browser/reduce_accept_language_factory.h b/weblayer/browser/reduce_accept_language_factory.h index 264adb2e..9dedb359 100644 --- a/weblayer/browser/reduce_accept_language_factory.h +++ b/weblayer/browser/reduce_accept_language_factory.h
@@ -31,7 +31,7 @@ ~ReduceAcceptLanguageFactory() override; // BrowserContextKeyedServiceFactory methods: - KeyedService* BuildServiceInstanceFor( + std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const override; content::BrowserContext* GetBrowserContextToUse( content::BrowserContext* context) const override;
diff --git a/weblayer/browser/safe_browsing/real_time_url_lookup_service_factory.cc b/weblayer/browser/safe_browsing/real_time_url_lookup_service_factory.cc index 64b200fe..5c7782e 100644 --- a/weblayer/browser/safe_browsing/real_time_url_lookup_service_factory.cc +++ b/weblayer/browser/safe_browsing/real_time_url_lookup_service_factory.cc
@@ -42,7 +42,8 @@ "RealTimeUrlLookupService", BrowserContextDependencyManager::GetInstance()) {} -KeyedService* RealTimeUrlLookupServiceFactory::BuildServiceInstanceFor( +std::unique_ptr<KeyedService> +RealTimeUrlLookupServiceFactory::BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const { auto url_loader_factory = std::make_unique<network::CrossThreadPendingSharedURLLoaderFactory>( @@ -50,7 +51,7 @@ ->GetSafeBrowsingService() ->GetURLLoaderFactory()); - return new safe_browsing::RealTimeUrlLookupService( + return std::make_unique<safe_browsing::RealTimeUrlLookupService>( network::SharedURLLoaderFactory::Create(std::move(url_loader_factory)), VerdictCacheManagerFactory::GetForBrowserContext(context), base::BindRepeating(&GetUserPopulationForBrowserContext, context),
diff --git a/weblayer/browser/safe_browsing/real_time_url_lookup_service_factory.h b/weblayer/browser/safe_browsing/real_time_url_lookup_service_factory.h index d85d198..55a8d54 100644 --- a/weblayer/browser/safe_browsing/real_time_url_lookup_service_factory.h +++ b/weblayer/browser/safe_browsing/real_time_url_lookup_service_factory.h
@@ -50,7 +50,7 @@ const RealTimeUrlLookupServiceFactory&) = delete; // BrowserContextKeyedServiceFactory: - KeyedService* BuildServiceInstanceFor( + std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const override; // TODO(crbug.com/1171215): Remove this once browsertests can enable this