diff --git a/DEPS b/DEPS index c578451..a89a24f 100644 --- a/DEPS +++ b/DEPS
@@ -305,11 +305,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. - 'src_internal_revision': 'f68388b45b21d640b546f3d9d7db07836f1eb45c', + 'src_internal_revision': '226326934fb1466c7a57898dbd24c922e173702c', # 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': 'f9e9bff1714a2746d19107b2f6623aebcee16527', + 'skia_revision': '343b249b2cacaa694a07ca7430b1881274417da0', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. @@ -317,7 +317,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ANGLE # and whatever else without interference from each other. - 'angle_revision': '88f7a65d598abf65dd1cba481e18e1775c27beee', + 'angle_revision': '98d79260fa0ebfcd5a4d959c9c21bf44071a00e6', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. @@ -380,7 +380,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': 'e04aba79979be87883ec296d65d2b77f88a55821', + 'catapult_revision': 'bd17576ac2d58104cb43d375ff282fde394ecb44', # 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. @@ -400,7 +400,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling devtools-frontend # and whatever else without interference from each other. - 'devtools_frontend_revision': '654a23c7ade29e732bfa4f0d10eacea5a81098d2', + 'devtools_frontend_revision': '45123813f5cb7335dc4a7e5151931dbe451b742c', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libprotobuf-mutator # and whatever else without interference from each other. @@ -424,7 +424,7 @@ # 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': 'ead8a043e377273b24e6c788007e6a7d15cf1093', + 'dawn_revision': 'bfb695dd9b62203f1b8fdaf7998e5681c38bd3b9', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -476,11 +476,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. - 'libcxxabi_revision': '79413b1359092d6feb34874e9a819466518b7262', + 'libcxxabi_revision': '371593893aeee51ecfb785093115fd846c3b73ca', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'libunwind_revision': '668c76fe4d440ee5e36971c9ca39f1b616af8078', + 'libunwind_revision': '85df028e4c5e8a3eaa38fe75e0d78157bee2d668', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -500,10 +500,10 @@ # If you change this, also update the libc++ revision in # //buildtools/deps_revisions.gni. - 'libcxx_revision': '038521e9561dab50fc8b50ef987e87225f39c8f6', + 'libcxx_revision': 'a96e76348a51cb38e2120a7333c49884e5737768', # GN CIPD package version. - 'gn_version': 'git_revision:bc5744174d9ea1c292f3f08cfb95fa97ea5c595e', + 'gn_version': 'git_revision:c7b223bfb225ce87a72a244d016ffdfcf227fa5e', # ninja CIPD package version. # https://chrome-infra-packages.appspot.com/p/infra/3pp/tools/ninja @@ -824,7 +824,7 @@ 'src/clank': { 'url': Var('chrome_git') + '/clank/internal/apps.git' + '@' + - 'd084593f4010d6bb4b4b141439462e5b5f18a878', + '545e490705f01ebb699f788c8eadb47a77a4fa6c', 'condition': 'checkout_android and checkout_src_internal', }, @@ -1224,7 +1224,7 @@ Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'), 'src/third_party/devtools-frontend-internal': { - 'url': Var('chrome_git') + '/devtools/devtools-internal.git' + '@' + 'b233f938697334c3b9cc718869672d2971668800', + 'url': Var('chrome_git') + '/devtools/devtools-internal.git' + '@' + '1c042a68ac0552324f7105843936b0f0218099f2', 'condition': 'checkout_src_internal', }, @@ -1557,7 +1557,7 @@ }, 'src/third_party/libvpx/source/libvpx': - Var('chromium_git') + '/webm/libvpx.git' + '@' + '0d3ef6ffd22bda0ba1ec1bf9c7a24852e4a1d111', + Var('chromium_git') + '/webm/libvpx.git' + '@' + '9142314c2cec2be364e6844d1630a056e7b0a3c8', 'src/third_party/libwebm/source': Var('chromium_git') + '/webm/libwebm.git' + '@' + 'e4fbea0c9751ae8aa86629b197a28d8276a2b0da', @@ -1834,7 +1834,7 @@ 'dep_type': 'cipd', }, - 'src/third_party/vulkan-deps': '{chromium_git}/vulkan-deps@ca747870c6137423c2a1c8730171993065bfc608', + 'src/third_party/vulkan-deps': '{chromium_git}/vulkan-deps@63bb05a5e0adc21e2436613b6452a7b5cc61ae54', 'src/third_party/vulkan_memory_allocator': Var('chromium_git') + '/external/github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator.git' + '@' + '56300b29fbfcc693ee6609ddad3fdd5b7a449a21', @@ -1997,7 +1997,7 @@ 'packages': [ { 'package': 'chromeos_internal/apps/help_app/app', - 'version': '2csM5_LEcmJ4trFGxO6q4Qlu3EaWjtoaLRTlgquRa90C', + 'version': 'Nlaon0avuWo3iySHPjsF1qnYPZMTWqDjkKHMgRnNQ6MC', }, ], 'condition': 'checkout_chromeos and checkout_src_internal', @@ -2008,7 +2008,7 @@ 'packages': [ { 'package': 'chromeos_internal/apps/media_app/app', - 'version': 'lljhrMxHsaH-YZVvNoj5KRBOPyruvwvT670mhGUhTM8C', + 'version': '-Sl0qrqXWKSz-0vAUifCPxmok67CpTeecSM7BtQqm6IC', }, ], 'condition': 'checkout_chromeos and checkout_src_internal', @@ -2041,7 +2041,7 @@ 'packages': [ { 'package': 'chromeos_internal/apps/projector_app/app', - 'version': 'Vt8OgHcm5ezLM91wWpVXvfDghRQm5Ny1E_HBDSgtUjkC', + 'version': 'ENdl4n5RLbvdjA0T0scu8P_TDJyKPC0Qe-eVIIIRvWYC', }, ], 'condition': 'checkout_chromeos and checkout_src_internal', @@ -4031,7 +4031,7 @@ 'src/ios_internal': { 'url': Var('chrome_git') + '/chrome/ios_internal.git' + '@' + - '5668f2d0e7ec4291e224096e8dbe8ea636e698a4', + 'eb61322a92140850bf94cb6e7a2511743c80ade5', 'condition': 'checkout_ios and checkout_src_internal', },
diff --git a/android_webview/renderer/aw_content_settings_client.cc b/android_webview/renderer/aw_content_settings_client.cc index 86bd305f..69cfefb 100644 --- a/android_webview/renderer/aw_content_settings_client.cc +++ b/android_webview/renderer/aw_content_settings_client.cc
@@ -35,22 +35,6 @@ AwContentSettingsClient::~AwContentSettingsClient() { } -bool AwContentSettingsClient::AllowImage(bool enabled_per_settings, - const blink::WebURL& image_url) { - if (ShouldAllowlistForContentSettings()) { - return true; - } - return blink::WebContentSettingsClient::AllowImage(enabled_per_settings, - image_url); -} - -bool AwContentSettingsClient::AllowScript(bool enabled_per_settings) { - if (ShouldAllowlistForContentSettings()) { - return true; - } - return blink::WebContentSettingsClient::AllowScript(enabled_per_settings); -} - bool AwContentSettingsClient::AllowRunningInsecureContent( bool enabled_per_settings, const blink::WebURL& url) { @@ -65,9 +49,4 @@ delete this; } -bool AwContentSettingsClient::ShouldAllowlistForContentSettings() const { - return render_frame()->GetWebFrame()->GetDocument().Url().GetString() == - content::kUnreachableWebDataURL; -} - } // namespace android_webview
diff --git a/android_webview/renderer/aw_content_settings_client.h b/android_webview/renderer/aw_content_settings_client.h index 2e7594c..b3a624f 100644 --- a/android_webview/renderer/aw_content_settings_client.h +++ b/android_webview/renderer/aw_content_settings_client.h
@@ -26,14 +26,9 @@ void OnDestruct() override; // blink::WebContentSettingsClient implementation. - bool AllowImage(bool enabled_per_settings, - const blink::WebURL& image_url) override; - bool AllowScript(bool enabled_per_settings) override; bool AllowRunningInsecureContent(bool enabled_per_settings, const blink::WebURL& url) override; bool ShouldAutoupgradeMixedContent() override; - - bool ShouldAllowlistForContentSettings() const; }; } // namespace android_webview
diff --git a/ash/BUILD.gn b/ash/BUILD.gn index 5107b7c4..05237027 100644 --- a/ash/BUILD.gn +++ b/ash/BUILD.gn
@@ -931,6 +931,12 @@ "multi_user/multi_user_window_manager_impl.h", "multi_user/user_switch_animator.cc", "multi_user/user_switch_animator.h", + "picker/picker_controller.cc", + "picker/picker_controller.h", + "picker/views/picker_search_field_view.cc", + "picker/views/picker_search_field_view.h", + "picker/views/picker_view.cc", + "picker/views/picker_view.h", "policy/policy_recommendation_restorer.cc", "policy/policy_recommendation_restorer.h", "power/hid_battery_util.cc", @@ -2820,7 +2826,6 @@ "//ash/in_session_auth", "//ash/keyboard/ui", "//ash/login/resources:resources_grit", - "//ash/picker", "//ash/public/cpp/ambient/proto", "//ash/quick_pair", "//ash/quick_pair/companion_app", @@ -3355,6 +3360,9 @@ "metrics/ui_metrics_recorder_unittest.cc", "metrics/user_metrics_recorder_unittest.cc", "multi_device_setup/multi_device_notification_presenter_unittest.cc", + "picker/picker_controller_unittest.cc", + "picker/views/picker_search_field_view_unittest.cc", + "picker/views/picker_view_unittest.cc", "policy/policy_recommendation_restorer_unittest.cc", "power/hid_battery_util_unittest.cc", "projector/model/projector_session_impl_unittest.cc", @@ -3857,7 +3865,6 @@ "//ash/in_session_auth", "//ash/keyboard/ui", "//ash/keyboard/ui:test_support", - "//ash/picker:unit_tests", "//ash/public/cpp", "//ash/public/cpp:test_support", "//ash/public/cpp:unit_tests",
diff --git a/ash/picker/BUILD.gn b/ash/picker/BUILD.gn deleted file mode 100644 index e0b5924..0000000 --- a/ash/picker/BUILD.gn +++ /dev/null
@@ -1,46 +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("//build/config/chromeos/ui_mode.gni") - -assert(is_chromeos_ash) - -source_set("picker") { - sources = [ - "picker_controller.cc", - "picker_controller.h", - "views/picker_view.cc", - "views/picker_view.h", - ] - - public_deps = [ - "//base", - "//ui/base", - "//ui/views", - ] - - deps = [ - "//ash/constants", - "//ui/chromeos/styles:cros_tokens_color_mappings", - "//ui/gfx", - ] -} - -source_set("unit_tests") { - testonly = true - - sources = [ - "picker_controller_unittest.cc", - "views/picker_view_unittest.cc", - ] - - deps = [ - ":picker", - "//ash:test_support", - "//base/test:test_support", - "//testing/gtest", - "//ui/chromeos/styles:cros_tokens_color_mappings", - "//ui/views:test_support", - ] -}
diff --git a/ash/picker/picker_controller.h b/ash/picker/picker_controller.h index 4338243..bef51e7 100644 --- a/ash/picker/picker_controller.h +++ b/ash/picker/picker_controller.h
@@ -5,12 +5,13 @@ #ifndef ASH_PICKER_PICKER_CONTROLLER_H_ #define ASH_PICKER_PICKER_CONTROLLER_H_ +#include "ash/ash_export.h" #include "ui/views/widget/unique_widget_ptr.h" namespace ash { // Controls a Picker widget. -class PickerController { +class ASH_EXPORT PickerController { public: // Whether the provided feature key for Picker can enable the feature. static bool IsFeatureKeyMatched();
diff --git a/ash/picker/views/picker_search_field_view.cc b/ash/picker/views/picker_search_field_view.cc new file mode 100644 index 0000000..0e2d096 --- /dev/null +++ b/ash/picker/views/picker_search_field_view.cc
@@ -0,0 +1,52 @@ +// 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 "ash/picker/views/picker_search_field_view.h" + +#include <string> + +#include "ash/style/typography.h" +#include "ui/base/metadata/metadata_impl_macros.h" +#include "ui/views/controls/textfield/textfield.h" +#include "ui/views/layout/fill_layout.h" +#include "ui/views/layout/layout_manager.h" +#include "ui/views/view_class_properties.h" + +namespace ash { + +PickerSearchFieldView::PickerSearchFieldView(SearchCallback search_callback) + : search_callback_(std::move(search_callback)) { + SetLayoutManager(std::make_unique<views::FillLayout>()); + + textfield_ = AddChildView(std::make_unique<views::Textfield>()); + textfield_->set_controller(this); + textfield_->SetFontList(TypographyProvider::Get()->ResolveTypographyToken( + TypographyToken::kCrosBody2)); + // TODO(b/309706053): Replace this once the strings are finalized. + textfield_->SetAccessibleName(u"placeholder"); + + search_callback_.Run(u""); +} + +PickerSearchFieldView::~PickerSearchFieldView() = default; + +void PickerSearchFieldView::RequestFocus() { + textfield_->RequestFocus(); +} + +void PickerSearchFieldView::ContentsChanged( + views::Textfield* sender, + const std::u16string& new_contents) { + search_callback_.Run(new_contents); +} + +void PickerSearchFieldView::SetPlaceholderText( + base::StringPiece16 new_placeholder_text) { + textfield_->SetPlaceholderText(std::u16string(new_placeholder_text)); +} + +BEGIN_METADATA(PickerSearchFieldView, views::View) +END_METADATA + +} // namespace ash
diff --git a/ash/picker/views/picker_search_field_view.h b/ash/picker/views/picker_search_field_view.h new file mode 100644 index 0000000..10580c8e --- /dev/null +++ b/ash/picker/views/picker_search_field_view.h
@@ -0,0 +1,55 @@ +// 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. + +#ifndef ASH_PICKER_VIEWS_PICKER_SEARCH_FIELD_VIEW_H_ +#define ASH_PICKER_VIEWS_PICKER_SEARCH_FIELD_VIEW_H_ + +#include "ash/ash_export.h" +#include "base/functional/callback_forward.h" +#include "ui/views/controls/textfield/textfield_controller.h" +#include "ui/views/view.h" + +namespace views { +class Textfield; +} + +namespace ash { + +// View for the Picker search field. +class ASH_EXPORT PickerSearchFieldView : public views::View, + public views::TextfieldController { + public: + METADATA_HEADER(PickerSearchFieldView); + + using SearchCallback = + base::RepeatingCallback<void(const std::u16string& query)>; + + // `search_callback` is called synchronously whenever the contents of the + // search field changes. It is also called synchronously with the empty string + // when this view is constructed. + explicit PickerSearchFieldView(SearchCallback search_callback); + PickerSearchFieldView(const PickerSearchFieldView&) = delete; + PickerSearchFieldView& operator=(const PickerSearchFieldView&) = delete; + ~PickerSearchFieldView() override; + + // views::View: + void RequestFocus() override; + + // views::TextfieldController: + void ContentsChanged(views::Textfield* sender, + const std::u16string& new_contents) override; + + // Set the placeholder text to show when the textfield is empty. + void SetPlaceholderText(base::StringPiece16 new_placeholder_text); + + const views::Textfield& textfield_for_testing() const { return *textfield_; } + + private: + SearchCallback search_callback_; + raw_ptr<views::Textfield> textfield_ = nullptr; +}; + +} // namespace ash + +#endif // ASH_PICKER_VIEWS_PICKER_SEARCH_FIELD_VIEW_H_
diff --git a/ash/picker/views/picker_search_field_view_unittest.cc b/ash/picker/views/picker_search_field_view_unittest.cc new file mode 100644 index 0000000..a529309 --- /dev/null +++ b/ash/picker/views/picker_search_field_view_unittest.cc
@@ -0,0 +1,51 @@ +// 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 "ash/picker/views/picker_search_field_view.h" + +#include <string> + +#include "ash/test/ash_test_base.h" +#include "base/test/test_future.h" +#include "testing/gmock/include/gmock/gmock-matchers.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "ui/views/controls/textfield/textfield.h" +#include "ui/views/view.h" +#include "ui/views/widget/widget.h" + +namespace ash { +namespace { + +using PickerSearchFieldViewTest = AshTestBase; + +TEST_F(PickerSearchFieldViewTest, TriggersSearchOnConstruction) { + base::test::TestFuture<const std::u16string&> future; + PickerSearchFieldView view(future.GetRepeatingCallback()); + + EXPECT_EQ(future.Get(), u""); +} + +TEST_F(PickerSearchFieldViewTest, TriggersSearchOnContentsChange) { + std::unique_ptr<views::Widget> widget = CreateFramelessTestWidget(); + base::test::TestFuture<const std::u16string&> future; + auto* view = widget->SetContentsView( + std::make_unique<PickerSearchFieldView>(future.GetRepeatingCallback())); + future.Clear(); + + view->RequestFocus(); + PressAndReleaseKey(ui::KeyboardCode::VKEY_A, ui::EF_NONE); + + EXPECT_EQ(future.Get(), u"a"); +} + +TEST_F(PickerSearchFieldViewTest, SetPlaceholderText) { + PickerSearchFieldView view(base::DoNothing()); + + view.SetPlaceholderText(u"hello"); + + EXPECT_EQ(view.textfield_for_testing().GetPlaceholderText(), u"hello"); +} + +} // namespace +} // namespace ash
diff --git a/ash/picker/views/picker_view.cc b/ash/picker/views/picker_view.cc index 0e111e56..20ea7b0 100644 --- a/ash/picker/views/picker_view.cc +++ b/ash/picker/views/picker_view.cc
@@ -6,6 +6,7 @@ #include <memory> +#include "ash/picker/views/picker_search_field_view.h" #include "ui/base/metadata/metadata_impl_macros.h" #include "ui/base/ui_base_types.h" #include "ui/chromeos/styles/cros_tokens_color_mappings.h" @@ -13,6 +14,7 @@ #include "ui/views/background.h" #include "ui/views/bubble/bubble_border.h" #include "ui/views/bubble/bubble_frame_view.h" +#include "ui/views/layout/flex_layout.h" #include "ui/views/widget/unique_widget_ptr.h" #include "ui/views/widget/widget.h" #include "ui/views/window/non_client_view.h" @@ -24,6 +26,7 @@ constexpr int kBorderRadius = 20; constexpr int kShadowElevation = 3; constexpr ui::ColorId kBackgroundColor = cros_tokens::kCrosSysBaseElevated; +constexpr auto kSearchFieldMargins = gfx::Insets::TLBR(16, 16, 8, 16); std::unique_ptr<views::BubbleBorder> CreateBorder() { auto border = std::make_unique<views::BubbleBorder>( @@ -39,6 +42,16 @@ SetShowCloseButton(false); SetBackground(views::CreateThemedSolidBackground(kBackgroundColor)); SetPreferredSize(kPickerSize); + + SetLayoutManager(std::make_unique<views::FlexLayout>()) + ->SetOrientation(views::LayoutOrientation::kVertical); + // TODO(b/310088250): Perform a search when the search callback is called. + search_field_view_ = + AddChildView(std::make_unique<PickerSearchFieldView>(base::DoNothing())); + search_field_view_->SetProperty(views::kMarginsKey, kSearchFieldMargins); + + // Automatically focus on the search field. + SetInitiallyFocusedView(search_field_view_); } PickerView::~PickerView() = default; @@ -54,7 +67,10 @@ // TODO(b/309706053): Replace this with the finalized string. params.name = "Picker"; - return std::make_unique<views::Widget>(std::move(params)); + auto widget = std::make_unique<views::Widget>(std::move(params)); + widget->SetVisibilityAnimationTransition( + views::Widget::VisibilityTransition::ANIMATE_HIDE); + return widget; } std::unique_ptr<views::NonClientFrameView> PickerView::CreateNonClientFrameView(
diff --git a/ash/picker/views/picker_view.h b/ash/picker/views/picker_view.h index 70151568..6d09e77 100644 --- a/ash/picker/views/picker_view.h +++ b/ash/picker/views/picker_view.h
@@ -5,6 +5,7 @@ #ifndef ASH_PICKER_VIEWS_PICKER_VIEW_H_ #define ASH_PICKER_VIEWS_PICKER_VIEW_H_ +#include "ash/ash_export.h" #include "ui/base/metadata/metadata_header_macros.h" #include "ui/views/view.h" #include "ui/views/widget/unique_widget_ptr.h" @@ -17,8 +18,10 @@ namespace ash { +class PickerSearchFieldView; + // View for the Picker widget. -class PickerView : public views::WidgetDelegateView { +class ASH_EXPORT PickerView : public views::WidgetDelegateView { public: METADATA_HEADER(PickerView); @@ -32,6 +35,9 @@ // views::WidgetDelegateView: std::unique_ptr<views::NonClientFrameView> CreateNonClientFrameView( views::Widget* widget) override; + + private: + raw_ptr<PickerSearchFieldView> search_field_view_ = nullptr; }; } // namespace ash
diff --git a/ash/strings/ash_strings_si.xtb b/ash/strings/ash_strings_si.xtb index 7eb88ad..4e96ea0 100644 --- a/ash/strings/ash_strings_si.xtb +++ b/ash/strings/ash_strings_si.xtb
@@ -1683,6 +1683,13 @@ <translation id="7893503627044934815">මෙම ගොනුව පෙන්වීමට අවශ්ය නැත</translation> <translation id="7895348134893321514">Tote</translation> <translation id="7897375687985782769">ඔබ තිරයේ කරකැවීම සඳහා යතුරුපුවරු කෙටිමඟ ඔබා ඇත. ඔබට එය සක්රීය කළ යුතුද?</translation> +<translation id="7897626842031123113">තත්ත්ව තැටිය, වේලාව <ph name="TIME" />, + <ph name="BATTERY" /> + <ph name="CHANNEL" /> + <ph name="NETWORK" />, + <ph name="MANAGED" /> + <ph name="IME" /> + <ph name="LOCALE" /></translation> <translation id="7901190436359881020">කවුළු මාරු කරන්න</translation> <translation id="7901405293566323524">දුරකථන මධ්යස්ථානය</translation> <translation id="7902625623987030061">ඇඟිලි සලකුණු සංවේදකය ස්පර්ශ කරන්න</translation>
diff --git a/ash/test/ash_test_base.cc b/ash/test/ash_test_base.cc index 531dd22..f8ae4bfc 100644 --- a/ash/test/ash_test_base.cc +++ b/ash/test/ash_test_base.cc
@@ -248,9 +248,11 @@ return absl::nullopt; } -void AshTestBase::UpdateDisplay(const std::string& display_specs) { +void AshTestBase::UpdateDisplay(const std::string& display_specs, + bool from_native_platform, + bool generate_new_ids) { display::test::DisplayManagerTestApi(Shell::Get()->display_manager()) - .UpdateDisplay(display_specs); + .UpdateDisplay(display_specs, from_native_platform, generate_new_ids); ScreenOrientationControllerTestApi( Shell::Get()->screen_orientation_controller()) .UpdateNaturalOrientation();
diff --git a/ash/test/ash_test_base.h b/ash/test/ash_test_base.h index 51363d9..530e303 100644 --- a/ash/test/ash_test_base.h +++ b/ash/test/ash_test_base.h
@@ -126,7 +126,9 @@ // See ash::DisplayManagerTestApi::UpdateDisplay for more details. // Note: To properly specify the radii of display's panel upon startup, set it // via specifying the command line switch `ash-host-window-bounds`. - void UpdateDisplay(const std::string& display_specs); + void UpdateDisplay(const std::string& display_specs, + bool from_native_platform = false, + bool generate_new_ids = false); // Returns a root Window. Usually this is the active root Window, but that // method can return NULL sometimes, and in those cases, we fall back on the
diff --git a/base/allocator/partition_allocator/src/partition_alloc/partition_alloc_base/bits.h b/base/allocator/partition_allocator/src/partition_alloc/partition_alloc_base/bits.h index 6ebccbbd..93b8784c 100644 --- a/base/allocator/partition_allocator/src/partition_alloc/partition_alloc_base/bits.h +++ b/base/allocator/partition_allocator/src/partition_alloc/partition_alloc_base/bits.h
@@ -7,19 +7,30 @@ #ifndef BASE_ALLOCATOR_PARTITION_ALLOCATOR_SRC_PARTITION_ALLOC_PARTITION_ALLOC_BASE_BITS_H_ #define BASE_ALLOCATOR_PARTITION_ALLOCATOR_SRC_PARTITION_ALLOC_PARTITION_ALLOC_BASE_BITS_H_ -#include <bit> -#include <cstddef> -#include <cstdint> -#include <type_traits> +#include <stddef.h> +#include <stdint.h> -#include "build/build_config.h" +#include <bit> +#include <concepts> + #include "partition_alloc/partition_alloc_base/check.h" -#include "partition_alloc/partition_alloc_base/compiler_specific.h" namespace partition_alloc::internal::base::bits { +// Bit functions in <bit> are restricted to a specific set of types of unsigned +// integer; restrict functions in this file that are related to those in that +// header to match for consistency. +template <typename T> +concept UnsignedInteger = + std::unsigned_integral<T> && !std::same_as<T, bool> && + !std::same_as<T, char> && !std::same_as<T, char8_t> && + !std::same_as<T, char16_t> && !std::same_as<T, char32_t> && + !std::same_as<T, wchar_t>; + // Returns true iff |value| is a power of 2. -template <typename T, typename = std::enable_if_t<std::is_integral_v<T>>> +// +// TODO(https://crbug.com/1414634): Replace with std::has_single_bit(). +template <UnsignedInteger T> constexpr bool IsPowerOfTwo(T value) { // From "Hacker's Delight": Section 2.1 Manipulating Rightmost Bits. // @@ -31,28 +42,32 @@ } // Round down |size| to a multiple of alignment, which must be a power of two. -inline constexpr size_t AlignDown(size_t size, size_t alignment) { +template <UnsignedInteger T> +inline constexpr T AlignDown(T size, T alignment) { PA_BASE_DCHECK(IsPowerOfTwo(alignment)); return size & ~(alignment - 1); } // Move |ptr| back to the previous multiple of alignment, which must be a power // of two. Defined for types where sizeof(T) is one byte. -template <typename T, typename = typename std::enable_if<sizeof(T) == 1>::type> +template <typename T> + requires(sizeof(T) == 1) inline T* AlignDown(T* ptr, size_t alignment) { return reinterpret_cast<T*>( - AlignDown(reinterpret_cast<size_t>(ptr), alignment)); + AlignDown(reinterpret_cast<uintptr_t>(ptr), alignment)); } // Round up |size| to a multiple of alignment, which must be a power of two. -inline constexpr size_t AlignUp(size_t size, size_t alignment) { +template <UnsignedInteger T> +inline constexpr T AlignUp(T size, T alignment) { PA_BASE_DCHECK(IsPowerOfTwo(alignment)); return (size + alignment - 1) & ~(alignment - 1); } // Advance |ptr| to the next multiple of alignment, which must be a power of // two. Defined for types where sizeof(T) is one byte. -template <typename T, typename = typename std::enable_if<sizeof(T) == 1>::type> +template <typename T> + requires(sizeof(T) == 1) inline T* AlignUp(T* ptr, size_t alignment) { return reinterpret_cast<T*>( AlignUp(reinterpret_cast<size_t>(ptr), alignment)); @@ -60,14 +75,24 @@ // Returns the integer i such as 2^i <= n < 2^(i+1). // -// There is a common `BitLength` function, which returns the number of bits -// required to represent a value. Rather than implement that function, -// use `Log2Floor` and add 1 to the result. +// A common use for this function is to measure the number of bits required to +// contain a value; for that case use std::bit_width(). +// +// A common use for this function is to shift a bit by its result; instead of +// doing so, use std::bit_floor(). TODO(https://crbug.com/1414634): Replace +// existing uses that do that. constexpr int Log2Floor(uint32_t n) { return 31 - std::countl_zero(n); } // Returns the integer i such as 2^(i-1) < n <= 2^i. +// +// A common use for this function is to measure the number of bits required to +// contain a value; for that case use std::bit_width(). +// +// A common use for this function is to shift a bit by its result; instead of +// doing so, use std::bit_ceil(). TODO(https://crbug.com/1414634): Replace +// existing uses that do that. constexpr int Log2Ceiling(uint32_t n) { // When n == 0, we want the function to return -1. // When n == 0, (n - 1) will underflow to 0xFFFFFFFF, which is @@ -76,11 +101,10 @@ } // Returns a value of type T with a single bit set in the left-most position. -// Can be used instead of manually shifting a 1 to the left. -template <typename T> +// Can be used instead of manually shifting a 1 to the left. Unlike the other +// functions in this file, usable for any integral type. +template <std::integral T> constexpr T LeftmostBit() { - static_assert(std::is_integral_v<T>, - "This function can only be used with integral types."); T one(1u); return one << (8 * sizeof(T) - 1); }
diff --git a/base/allocator/partition_allocator/src/partition_alloc/partition_alloc_base/bits_pa_unittest.cc b/base/allocator/partition_allocator/src/partition_alloc/partition_alloc_base/bits_pa_unittest.cc index 33c0717..c6ff097 100644 --- a/base/allocator/partition_allocator/src/partition_alloc/partition_alloc_base/bits_pa_unittest.cc +++ b/base/allocator/partition_allocator/src/partition_alloc/partition_alloc_base/bits_pa_unittest.cc
@@ -6,10 +6,10 @@ #include "partition_alloc/partition_alloc_base/bits.h" -#include <cstddef> +#include <stddef.h> + #include <limits> -#include "build/build_config.h" #include "testing/gtest/include/gtest/gtest.h" namespace partition_alloc::internal::base::bits { @@ -50,14 +50,14 @@ TEST(BitsTestPA, AlignUp) { static constexpr size_t kSizeTMax = std::numeric_limits<size_t>::max(); - EXPECT_EQ(0ul, AlignUp(0, 4)); - EXPECT_EQ(4ul, AlignUp(1, 4)); - EXPECT_EQ(4096ul, AlignUp(1, 4096)); - EXPECT_EQ(4096ul, AlignUp(4096, 4096)); - EXPECT_EQ(4096ul, AlignUp(4095, 4096)); - EXPECT_EQ(8192ul, AlignUp(4097, 4096)); - EXPECT_EQ(kSizeTMax - 31, AlignUp(kSizeTMax - 62, 32)); - EXPECT_EQ(kSizeTMax / 2 + 1, AlignUp(1, kSizeTMax / 2 + 1)); + EXPECT_EQ(0u, AlignUp(0u, 4u)); + EXPECT_EQ(4u, AlignUp(1u, 4u)); + EXPECT_EQ(4096u, AlignUp(1u, 4096u)); + EXPECT_EQ(4096u, AlignUp(4096u, 4096u)); + EXPECT_EQ(4096u, AlignUp(4095u, 4096u)); + EXPECT_EQ(8192u, AlignUp(4097u, 4096u)); + EXPECT_EQ(kSizeTMax - 31, AlignUp(kSizeTMax - 62, size_t{32})); + EXPECT_EQ(kSizeTMax / 2 + 1, AlignUp(size_t{1}, kSizeTMax / 2 + 1)); } TEST(BitsTestPA, AlignUpPointer) { @@ -83,15 +83,15 @@ TEST(BitsTestPA, AlignDown) { static constexpr size_t kSizeTMax = std::numeric_limits<size_t>::max(); - EXPECT_EQ(0ul, AlignDown(0, 4)); - EXPECT_EQ(0ul, AlignDown(1, 4)); - EXPECT_EQ(0ul, AlignDown(1, 4096)); - EXPECT_EQ(4096ul, AlignDown(4096, 4096)); - EXPECT_EQ(0ul, AlignDown(4095, 4096)); - EXPECT_EQ(4096ul, AlignDown(4097, 4096)); - EXPECT_EQ(kSizeTMax - 63, AlignDown(kSizeTMax - 62, 32)); - EXPECT_EQ(kSizeTMax - 31, AlignDown(kSizeTMax, 32)); - EXPECT_EQ(0ul, AlignDown(1, kSizeTMax / 2 + 1)); + EXPECT_EQ(0u, AlignDown(0u, 4u)); + EXPECT_EQ(0u, AlignDown(1u, 4u)); + EXPECT_EQ(0u, AlignDown(1u, 4096u)); + EXPECT_EQ(4096u, AlignDown(4096u, 4096u)); + EXPECT_EQ(0u, AlignDown(4095u, 4096u)); + EXPECT_EQ(4096u, AlignDown(4097u, 4096u)); + EXPECT_EQ(kSizeTMax - 63, AlignDown(kSizeTMax - 62, size_t{32})); + EXPECT_EQ(kSizeTMax - 31, AlignDown(kSizeTMax, size_t{32})); + EXPECT_EQ(0ul, AlignDown(size_t{1}, kSizeTMax / 2 + 1)); } TEST(BitsTestPA, AlignDownPointer) { @@ -118,10 +118,9 @@ } TEST(BitsTestPA, PowerOfTwo) { - EXPECT_FALSE(IsPowerOfTwo(-1)); - EXPECT_FALSE(IsPowerOfTwo(0)); - EXPECT_TRUE(IsPowerOfTwo(1)); - EXPECT_TRUE(IsPowerOfTwo(2)); + EXPECT_FALSE(IsPowerOfTwo(0u)); + EXPECT_TRUE(IsPowerOfTwo(1u)); + EXPECT_TRUE(IsPowerOfTwo(2u)); // Unsigned 64 bit cases. for (uint32_t i = 2; i < 64; i++) { const uint64_t val = uint64_t{1} << i; @@ -129,15 +128,6 @@ EXPECT_TRUE(IsPowerOfTwo(val)); EXPECT_FALSE(IsPowerOfTwo(val + 1)); } - // Signed 64 bit cases. - for (uint32_t i = 2; i < 63; i++) { - const int64_t val = int64_t{1} << i; - EXPECT_FALSE(IsPowerOfTwo(val - 1)); - EXPECT_TRUE(IsPowerOfTwo(val)); - EXPECT_FALSE(IsPowerOfTwo(val + 1)); - } - // Signed integers with only the last bit set are negative, not powers of two. - EXPECT_FALSE(IsPowerOfTwo(int64_t{1} << 63)); } TEST(BitsTestPA, LeftMostBit) {
diff --git a/base/allocator/partition_allocator/src/partition_alloc/partition_alloc_base/strings/cstring_builder.cc b/base/allocator/partition_allocator/src/partition_alloc/partition_alloc_base/strings/cstring_builder.cc index 4e8262d..59225b6 100644 --- a/base/allocator/partition_allocator/src/partition_alloc/partition_alloc_base/strings/cstring_builder.cc +++ b/base/allocator/partition_allocator/src/partition_alloc/partition_alloc_base/strings/cstring_builder.cc
@@ -14,6 +14,7 @@ #include <cmath> #include <cstring> +#include <limits> #if BUILDFLAG(PA_DCHECK_IS_ON) #include "partition_alloc/partition_alloc_base/check.h"
diff --git a/base/allocator/partition_allocator/src/partition_alloc/partition_ref_count.h b/base/allocator/partition_allocator/src/partition_alloc/partition_ref_count.h index eef678da2..230b8cc4 100644 --- a/base/allocator/partition_allocator/src/partition_alloc/partition_ref_count.h +++ b/base/allocator/partition_allocator/src/partition_alloc/partition_ref_count.h
@@ -5,8 +5,10 @@ #ifndef BASE_ALLOCATOR_PARTITION_ALLOCATOR_SRC_PARTITION_ALLOC_PARTITION_REF_COUNT_H_ #define BASE_ALLOCATOR_PARTITION_ALLOCATOR_SRC_PARTITION_ALLOC_PARTITION_REF_COUNT_H_ +#include <stddef.h> +#include <stdint.h> + #include <atomic> -#include <cstdint> #include "build/build_config.h" #include "partition_alloc/dangling_raw_ptr_checks.h" @@ -40,7 +42,7 @@ #if BUILDFLAG(IS_MAC) if (internal::base::mac::MacOSMajorVersion() == 13 || internal::base::mac::MacOSMajorVersion() == 14) { - return internal::base::bits::AlignUp(ref_count_size, 8); + return internal::base::bits::AlignUp<size_t>(ref_count_size, 8); } #endif // BUILDFLAG(IS_MAC) return ref_count_size;
diff --git a/base/allocator/partition_allocator/src/partition_alloc/tagging.h b/base/allocator/partition_allocator/src/partition_alloc/tagging.h index 2d3e9e0..5e261fa7 100644 --- a/base/allocator/partition_allocator/src/partition_alloc/tagging.h +++ b/base/allocator/partition_allocator/src/partition_alloc/tagging.h
@@ -41,7 +41,7 @@ namespace internal { -constexpr int kMemTagGranuleSize = 16u; +constexpr uint64_t kMemTagGranuleSize = 16u; #if PA_CONFIG(HAS_MEMORY_TAGGING) constexpr uint64_t kPtrTagMask = 0xff00000000000000uLL; #else
diff --git a/buildtools/deps_revisions.gni b/buildtools/deps_revisions.gni index 413d460..90dc163 100644 --- a/buildtools/deps_revisions.gni +++ b/buildtools/deps_revisions.gni
@@ -5,5 +5,5 @@ declare_args() { # Used to cause full rebuilds on libc++ rolls. This should be kept in sync # with the libcxx_revision vars in //DEPS. - libcxx_revision = "038521e9561dab50fc8b50ef987e87225f39c8f6" + libcxx_revision = "a96e76348a51cb38e2120a7333c49884e5737768" }
diff --git a/chrome/VERSION b/chrome/VERSION index 5a57ff6..5391372a 100644 --- a/chrome/VERSION +++ b/chrome/VERSION
@@ -1,4 +1,4 @@ MAJOR=121 MINOR=0 -BUILD=6137 +BUILD=6138 PATCH=0
diff --git a/chrome/android/profiles/arm.newest.txt b/chrome/android/profiles/arm.newest.txt index 3be149f2..fb8102c 100644 --- a/chrome/android/profiles/arm.newest.txt +++ b/chrome/android/profiles/arm.newest.txt
@@ -1 +1 @@ -chromeos-chrome-arm-121.0.6128.0_rc-r1-merged.afdo.bz2 +chromeos-chrome-arm-121.0.6136.0_rc-r1-merged.afdo.bz2
diff --git a/chrome/android/profiles/newest.txt b/chrome/android/profiles/newest.txt index db15c3a0a..84149719f9 100644 --- a/chrome/android/profiles/newest.txt +++ b/chrome/android/profiles/newest.txt
@@ -1 +1 @@ -chromeos-chrome-amd64-121.0.6128.0_rc-r1-merged.afdo.bz2 +chromeos-chrome-amd64-121.0.6136.0_rc-r1-merged.afdo.bz2
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index 2e05ab9..3896fdde 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -16419,10 +16419,10 @@ <!-- Promise icon status labels. --> <message name="IDS_PROMISE_STATUS_WAITING" desc="Text label for a promise icon in the Launcher or Shelf to indicate that the app is pending installation"> - waiting... + Waiting... </message> <message name="IDS_PROMISE_STATUS_INSTALLING" desc="Text label for a promise icon in the Launcher or Shelf to indicate that the app is currently downloading or installing"> - installing... + Installing... </message> <message name="IDS_PROMISE_APP_ACCESSIBLE_LABEL_WAITING" desc="Accessibility label for a promise icon in the Launcher or Shelf to indicate that the app is pending installation"> <ph name="APP_NAME">$1<ex>Gmail</ex></ph>, waiting
diff --git a/chrome/app/generated_resources_grd/IDS_PROMISE_STATUS_INSTALLING.png.sha1 b/chrome/app/generated_resources_grd/IDS_PROMISE_STATUS_INSTALLING.png.sha1 index 29d9a6b..e1afc3a9 100644 --- a/chrome/app/generated_resources_grd/IDS_PROMISE_STATUS_INSTALLING.png.sha1 +++ b/chrome/app/generated_resources_grd/IDS_PROMISE_STATUS_INSTALLING.png.sha1
@@ -1 +1 @@ -fd0b02978fae5620695cfe5a1c61cb738c74f972 \ No newline at end of file +1ec427e088816ef9edd1aa5b44751c2307704356 \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_PROMISE_STATUS_WAITING.png.sha1 b/chrome/app/generated_resources_grd/IDS_PROMISE_STATUS_WAITING.png.sha1 index 93a3748..a2c2475 100644 --- a/chrome/app/generated_resources_grd/IDS_PROMISE_STATUS_WAITING.png.sha1 +++ b/chrome/app/generated_resources_grd/IDS_PROMISE_STATUS_WAITING.png.sha1
@@ -1 +1 @@ -55da9f7c0e97b2fb80f74dfd1e601bfc7d55a052 \ No newline at end of file +3195c470864edd1bf19bd9afa67a8a00340b76ee \ No newline at end of file
diff --git a/chrome/app/resources/chromium_strings_si.xtb b/chrome/app/resources/chromium_strings_si.xtb index 766ef9c94..1a15189 100644 --- a/chrome/app/resources/chromium_strings_si.xtb +++ b/chrome/app/resources/chromium_strings_si.xtb
@@ -277,6 +277,7 @@ <translation id="6129621093834146363"><ph name="FILE_NAME" /> අනතුරුදායකයි, එම නිසා Chromium එය අවහිර කර ඇත.</translation> <translation id="6132897690380286411">Chromium ඉක්මනින් වසා දත්ත මකනු ඇත</translation> <translation id="6134968993075716475">සුරක්ෂිත පිරික්සුම ක්රියාවිරහිතයි. එය ක්රියාත්මක කිරීමට Chromium නිර්දේශ කරයි.</translation> +<translation id="6144416395842701622">Chromium වෙතින් උපරිම ඵලය ලබා ගැනීමට පුරන්න</translation> <translation id="6145820983052037069">ඔබට මෙහිදී Chromium පැතිකඩවල් අතර මාරු විය හැකිය</translation> <translation id="615103374448673771">ඔබ කුකීවලට ඉඩ දෙන්නේ නම්, පූර්ව පූරණය කිරීමේ දී Chromium ඒවා භාවිත කිරීමට ඉඩ ඇත.</translation> <translation id="6175304430031192654">ඔබේ සැකසීම් මත පදනම්ව, Chromium කුකී සහ ඔබේ වත්මන් URL ද යවාවි</translation> @@ -435,6 +436,7 @@ <translation id="8648201657708811153">පරීක්ෂණ සඳහා Google Chrome ඔබේ පෙරනිමි බ්රව්සරය බවට පත් කළ නොහැක.</translation> <translation id="8697124171261953979">තවද එය ඔබ Chromium විවෘත කරන විට හෝ Omnibox වෙතින් සොයන විට පෙන්වන වෙබ් පිටුව නිර්ණය කරයි.</translation> <translation id="8704119203788522458">මෙය ඔබේ Chromium වේ</translation> +<translation id="8719993436687031146">Chromium වෙත පුරන්නද?</translation> <translation id="878572486461146056">ස්ථාපන දෝෂය: ඔබේ ජාල පරිපාලකයා ස්ථාපනය කිරීම වළක්වන සමූහ ප්රතිපත්තියක් යොදවා ඇත: <ph name="INSTALL_ERROR" /></translation> <translation id="8796602469536043152">Chromium හට මෙම අඩවිය සදහා ඔබේ කැමරාවට සහ මයික්රෆෝනයට ප්රවේශ වීමට අවසර අවශ්යයි</translation> <translation id="8826492472752484139">“මුරපද කළමනාකරු” ක්ලික් කරන්න</translation>
diff --git a/chrome/app/resources/generated_resources_fa.xtb b/chrome/app/resources/generated_resources_fa.xtb index 8ca2ee1..b1d1835 100644 --- a/chrome/app/resources/generated_resources_fa.xtb +++ b/chrome/app/resources/generated_resources_fa.xtb
@@ -1856,6 +1856,7 @@ <translation id="2402226831639195063">صداها</translation> <translation id="2405887402346713222">شمارههای سریال دستگاه و قطعات</translation> <translation id="2406153734066939945">این نمایه و دادههای آن حذف شود؟</translation> +<translation id="2407671304279211586">انتخاب رساننده ساناد</translation> <translation id="2408018932941436077">درحال ذخیره کارت</translation> <translation id="2408955596600435184">پین را وارد کنید</translation> <translation id="2409268599591722235">بیایید شروع کنیم</translation>
diff --git a/chrome/app/resources/generated_resources_si.xtb b/chrome/app/resources/generated_resources_si.xtb index 8738066b..cd9fece 100644 --- a/chrome/app/resources/generated_resources_si.xtb +++ b/chrome/app/resources/generated_resources_si.xtb
@@ -2679,6 +2679,7 @@ <translation id="3021065318976393105">බැටරිය මත සිටින විට</translation> <translation id="3021066826692793094">සමනළයා</translation> <translation id="3021678814754966447">රාමු මූලය දර්ශනය (&V)</translation> +<translation id="3021902017511220299">ස්කෑන් අසමත් විය. මෙම ක්රියාව ඔබේ පරිපාලකයා විසින් අවහිර කරනු ලබයි.</translation> <translation id="3022361196600037287">මෙම Chromebook වෙතින් <ph name="DEVICE" /> ඉවත් කරනු ලබන අතර <ph name="PRIMARY_EMAIL" /> වෙත සුරැකෙන්නේ නැත.</translation> <translation id="3022978424994383087">එය ලබා ගත්තේ නැත.</translation> <translation id="3023464535986383522">කථා කිරීමට තෝරන්න</translation> @@ -9049,6 +9050,7 @@ <translation id="811994229154425014">නැවතීමේ තිත ටයිප් කිරීමට ස්පේස් බාර් එක දෙවරක් ඔබන්න</translation> <translation id="8120505434908124087">eSIM පැතිකඩ ස්ථාපනය කරන්න</translation> <translation id="8121750884985440809">ඔබ දැනට ඔබේ තිරය විකාශය කරමින් සිටී</translation> +<translation id="8122898034710982882">දුරකථන මධ්යස්ථානය, <ph name="FEATURE_NAME" /></translation> <translation id="81238879832906896">කහ සහ සුදු මල</translation> <translation id="8123975449645947908">පසුපසට අනුචලන කරන්න</translation> <translation id="8124313775439841391">පාලිත ONC</translation> @@ -9084,6 +9086,7 @@ <translation id="8148760431881541277">පුරනය සීමා කරන්න</translation> <translation id="8149564499626272569">USB කේබලයක් සමඟ ඔබගේ දුරකථනය හරහා සත්යාපනය කරන්න</translation> <translation id="8149870652370242480">ඔබේ දුරකථනයෙහි සුරකින ලද මුරපද භාවිත කිරීමට iOS සඳහා Chrome බා ගෙන ඔබේ Google ගිණුමට පුරන්න.</translation> +<translation id="8151057139207656239">පිටපත් කළ තැනුම් විස්තර</translation> <translation id="815114315010033526">ඒ වෙනුවට QR කේතය භාවිත කරන්න</translation> <translation id="8151638057146502721">වින්යාස කරන්න</translation> <translation id="8154790740888707867">ගොනු නොමැත</translation>
diff --git a/chrome/app/resources/generated_resources_sl.xtb b/chrome/app/resources/generated_resources_sl.xtb index 7f80d1eb..e810725 100644 --- a/chrome/app/resources/generated_resources_sl.xtb +++ b/chrome/app/resources/generated_resources_sl.xtb
@@ -1862,6 +1862,7 @@ <translation id="2402226831639195063">Toni</translation> <translation id="2405887402346713222">Serijske številke naprav in komponent</translation> <translation id="2406153734066939945">Želite izbrisati ta profil in podatke v njem?</translation> +<translation id="2407671304279211586">Izbira ponudnika DNS-ja</translation> <translation id="2408018932941436077">Shranjevanje kartice</translation> <translation id="2408955596600435184">Vnos kode PIN</translation> <translation id="2409268599591722235">Pa začnimo</translation>
diff --git a/chrome/app/resources/google_chrome_strings_si.xtb b/chrome/app/resources/google_chrome_strings_si.xtb index 9d6fc46..1d580f0 100644 --- a/chrome/app/resources/google_chrome_strings_si.xtb +++ b/chrome/app/resources/google_chrome_strings_si.xtb
@@ -26,6 +26,7 @@ <translation id="139993653570221430">ඔබට Chrome සැකසීම් තුළ ඕනෑම වේලාවක ඔබගේ අදහස වෙනස් කළ හැකිය. අත්හදා බැලීම් වත්මන් වෙළඳ දැන්වීම් සපයන ආකාරය සමඟ ක්රියාත්මක වේ, එබැවින් ඔබ වෙනස් කිරීම් වහාම නොදකිනු ඇත.</translation> <translation id="1425903838053942728">{COUNT,plural, =0{Chrome යාවත්කාලීන කර අවසන්. ඔබ යළි දියත් කළ වහාම ඔබට නවතම අනුවාදය භාවිත කළ හැක. පසුව, ඔබේ වත්මන් පටිති යළි විවෘත වෙයි.}=1{Chrome යාවත්කාලීන කර අවසන්. ඔබ යළි දියත් කළ වහාම ඔබට නවතම අනුවාදය භාවිත කළ හැක. පසුව, ඔබේ වත්මන් පටිති යළි විවෘත වෙයි. ඔබේ අප්රසිද්ධ කවුළුව යළි විවෘත නොවෙයි.}one{Chrome යාවත්කාලීන කර අවසන්. ඔබ යළි දියත් කළ වහාම ඔබට නවතම අනුවාදය භාවිත කළ හැක. පසුව, ඔබේ වත්මන් පටිති යළි විවෘත වෙයි. ඔබේ අප්රසිද්ධ කවුළු # යළි විවෘත නොවෙයි.}other{Chrome යාවත්කාලීන කර අවසන්. ඔබ යළි දියත් කළ වහාම ඔබට නවතම අනුවාදය භාවිත කළ හැක. පසුව, ඔබේ වත්මන් පටිති යළි විවෘත වෙයි. ඔබේ අප්රසිද්ධ කවුළු # යළි විවෘත නොවෙයි.}}</translation> <translation id="1434626383986940139">Chrome Canary යෙදුම්</translation> +<translation id="146866447420868597">Chrome වෙත පුරන්නද?</translation> <translation id="1492280395845991349">Chrome යාවත්කාලීන කිරීම අවසන් කිරීමට යළි දියත් කරන්න</translation> <translation id="1497802159252041924">ස්ථාපනය කිරීමේ දෝෂයක්: <ph name="INSTALL_ERROR" /></translation> <translation id="1507198376417198979">ඔබගේ නව Chrome පැතිකඩ අභිරුචිකරණය කරන්න</translation>
diff --git a/chrome/browser/ash/BUILD.gn b/chrome/browser/ash/BUILD.gn index b728432b..74bd178 100644 --- a/chrome/browser/ash/BUILD.gn +++ b/chrome/browser/ash/BUILD.gn
@@ -4086,6 +4086,7 @@ "//chromeos/ash/components/early_prefs:writer", "//chromeos/ash/components/fwupd", "//chromeos/ash/components/growth", + "//chromeos/ash/components/language_packs", "//chromeos/ash/components/local_search_service/public/cpp", "//chromeos/ash/components/login/hibernate:hibernate_manager", "//chromeos/ash/components/mojo_service_manager",
diff --git a/chrome/browser/ash/app_list/app_service/app_service_promise_app_item_browsertest.cc b/chrome/browser/ash/app_list/app_service/app_service_promise_app_item_browsertest.cc index caa2fbf..868f4fb 100644 --- a/chrome/browser/ash/app_list/app_service/app_service_promise_app_item_browsertest.cc +++ b/chrome/browser/ash/app_list/app_service/app_service_promise_app_item_browsertest.cc
@@ -896,7 +896,7 @@ ChromeAppListItem* item = GetChromeAppListItem(kTestPackageId); ASSERT_TRUE(item); EXPECT_EQ(item->app_status(), ash::AppStatus::kPending); - ASSERT_EQ(item->name(), "waiting…"); + ASSERT_EQ(item->name(), "Waiting…"); ASSERT_EQ(item->accessible_name(), "Long Name, waiting"); // Update the promise app in the promise app registry cache. @@ -907,7 +907,7 @@ // Promise app item should have updated fields. EXPECT_EQ(item->app_status(), ash::AppStatus::kInstalling); - EXPECT_EQ(item->name(), "installing…"); + EXPECT_EQ(item->name(), "Installing…"); ASSERT_EQ(item->accessible_name(), "Long Name, installing"); } @@ -1047,7 +1047,7 @@ // icon in the positions indicated by the sync data. ash::AppListItem* launcher_item = GetAppListItem(package_id.ToString()); ASSERT_TRUE(launcher_item); - EXPECT_EQ(launcher_item->name(), "waiting…"); + EXPECT_EQ(launcher_item->name(), "Waiting…"); EXPECT_EQ(launcher_item->progress(), 0); EXPECT_EQ(launcher_item->position(), launcher_ordinal); EXPECT_TRUE(IsItemPinned(package_id.ToString())); @@ -1063,7 +1063,7 @@ // Confirm the promise icon fields. launcher_item = GetAppListItem(package_id.ToString()); - EXPECT_EQ(launcher_item->name(), "installing…"); + EXPECT_EQ(launcher_item->name(), "Installing…"); EXPECT_FLOAT_EQ(launcher_item->progress(), 0.2f); EXPECT_EQ(launcher_item->position(), launcher_ordinal); EXPECT_TRUE(IsItemPinned(package_id.ToString()));
diff --git a/chrome/browser/ash/chrome_browser_main_parts_ash.cc b/chrome/browser/ash/chrome_browser_main_parts_ash.cc index e77b57b4..b0c8259 100644 --- a/chrome/browser/ash/chrome_browser_main_parts_ash.cc +++ b/chrome/browser/ash/chrome_browser_main_parts_ash.cc
@@ -249,6 +249,7 @@ #include "components/language/core/browser/pref_names.h" #include "components/metrics/metrics_service.h" #include "components/ownership/owner_key_util.h" +#include "components/policy/core/common/cloud/cloud_policy_constants.h" #include "components/prefs/pref_service.h" #include "components/quirks/quirks_manager.h" #include "components/safe_browsing/core/common/safe_browsing_prefs.h" @@ -303,6 +304,29 @@ base::SetLinuxDistro("CrOS " + version.value_or("0.0.0.0")); } +#if BUILDFLAG(GOOGLE_CHROME_BRANDING) + +// Returns the device mode. For Chrome OS this function will return the mode +// stored in the lockbox, or DEVICE_MODE_CONSUMER if the lockbox has been +// locked empty, or DEVICE_MODE_UNKNOWN if the device has not been owned yet. +// For other OSes the function will always return DEVICE_MODE_CONSUMER. +policy::DeviceMode GetDeviceMode() { + return g_browser_process->platform_part() + ->browser_policy_connector_ash() + ->GetDeviceMode(); +} + +// Returns device's market segment if enterprise enrolled, as delivered by the +// device management server. If the device is not enterprise-enrolled, +// it will return UNKNOWN. +policy::MarketSegment GetEnterpriseMarketSegment() { + return g_browser_process->platform_part() + ->browser_policy_connector_ash() + ->GetEnterpriseMarketSegment(); +} + +#endif // BUILDFLAG(GOOGLE_CHROME_BRANDING) + // Creates an instance of the NetworkPortalDetector implementation or a stub. void InitializeNetworkPortalDetector() { if (network_portal_detector::SetForTesting()) { @@ -1799,8 +1823,7 @@ // When status is PERMANENTLY_UNTRUSTED, client assumes this status is final // until browser restarts. Client does not proceed without signature // verification, so retry is not attempted. This status may be caused - // if device is running pre-OOBE, or if the policy proto blob fails the - // signature check. + // if the policy proto blob fails the signature check. return; } @@ -1809,28 +1832,30 @@ base::RepeatingCallback<base::TimeDelta()> check_oobe_completed_callback = base::BindRepeating(&StartupUtils::GetTimeSinceOobeFlagFileCreation); + // Create callbacks to retrieve the policy device mode and market segment. + // These callbacks are executed after oobe is completed to get correct values. + base::RepeatingCallback<policy::DeviceMode()> check_device_mode_callback = + base::BindRepeating(&GetDeviceMode); + base::RepeatingCallback<policy::MarketSegment()> + check_market_segment_callback = + base::BindRepeating(&GetEnterpriseMarketSegment); + // CrosSettingsProvider::TRUSTED: device policies are loaded and trusted. report_controller_ = std::make_unique<report::ReportController>( ash::report::device_metrics::ChromeDeviceMetadataParameters{ - chrome::GetChannel() /* chromeos_channel */, - report::ReportController::GetMarketSegment( - g_browser_process->platform_part() - ->browser_policy_connector_ash() - ->GetDeviceMode(), - g_browser_process->platform_part() - ->browser_policy_connector_ash() - ->GetEnterpriseMarketSegment()) /* market_segment */, - }, + chrome::GetChannel() /* chromeos_channel */}, g_browser_process->local_state(), g_browser_process->system_network_context_manager() ->GetSharedURLLoaderFactory(), first_run::GetFirstRunSentinelCreationTime(), std::move(check_oobe_completed_callback), + std::move(check_device_mode_callback), + std::move(check_market_segment_callback), std::make_unique<ash::report::device_metrics::PsmClientManager>( std::make_unique< report::device_metrics::RealPsmClientManagerDelegate>())); -#endif +#endif // BUILDFLAG(GOOGLE_CHROME_BRANDING) } } // namespace ash
diff --git a/chrome/browser/ash/dbus/ash_dbus_helper.cc b/chrome/browser/ash/dbus/ash_dbus_helper.cc index ed6ecac..55a3c76 100644 --- a/chrome/browser/ash/dbus/ash_dbus_helper.cc +++ b/chrome/browser/ash/dbus/ash_dbus_helper.cc
@@ -79,6 +79,7 @@ #include "chromeos/ash/components/dbus/virtual_file_provider/virtual_file_provider_client.h" #include "chromeos/ash/components/dbus/vm_plugin_dispatcher/vm_plugin_dispatcher_client.h" #include "chromeos/ash/components/install_attributes/install_attributes.h" +#include "chromeos/ash/components/language_packs/language_pack_manager.h" #include "chromeos/dbus/constants/dbus_paths.h" #include "chromeos/dbus/dlp/dlp_client.h" #include "chromeos/dbus/init/initialize_dbus_client.h" @@ -216,6 +217,9 @@ DeviceSettingsService::Initialize(); InstallAttributes::Initialize(); + // Depends on `DlcserviceClient`. + language_packs::LanguagePackManager::Initialise(); + if (g_dbus_helper_observer) { g_dbus_helper_observer->PostInitializeDBus(); } @@ -294,6 +298,10 @@ } else { bluez::BluezDBusManager::Shutdown(); } + + // Depends on `DlcserviceClient`. + language_packs::LanguagePackManager::Shutdown(); + // Other D-Bus clients are shut down, also in reverse order of initialization. VmPluginDispatcherClient::Shutdown(); VirtualFileProviderClient::Shutdown();
diff --git a/chrome/browser/ash/extensions/file_manager/private_api_drive.cc b/chrome/browser/ash/extensions/file_manager/private_api_drive.cc index 1ba6412..216ce57 100644 --- a/chrome/browser/ash/extensions/file_manager/private_api_drive.cc +++ b/chrome/browser/ash/extensions/file_manager/private_api_drive.cc
@@ -663,6 +663,7 @@ void FileManagerPrivateSearchDriveFunction::OnSearchDriveFs( absl::optional<base::Value::List> results) { + using api::file_manager_private::SearchDriveResponse; if (!results) { UmaEmitSearchOutcome( false, !is_offline_, @@ -672,14 +673,18 @@ return; } - api::file_manager_private::SearchDriveResponse response; + SearchDriveResponse response; // Search queries are capped at 100 of items anyway and pagination is // never actually used, so no need to fill this. response.next_feed = ""; + response.entries.reserve(results.value().size()); for (const auto& e : results.value()) { - auto& entry = response.entries.emplace_back(); - api::file_manager_private::SearchDriveResponse::EntriesType::Populate( - e, entry); + auto entry = SearchDriveResponse::EntriesType::FromValue(e); + if (!entry) { + LOG(ERROR) << "Failed to convert entry: " << e.DebugString(); + continue; + } + response.entries.push_back(std::move(entry.value())); } UmaEmitSearchOutcome(
diff --git a/chrome/browser/ash/file_manager/file_manager_browsertest.cc b/chrome/browser/ash/file_manager/file_manager_browsertest.cc index b8f3bf46..452573e 100644 --- a/chrome/browser/ash/file_manager/file_manager_browsertest.cc +++ b/chrome/browser/ash/file_manager/file_manager_browsertest.cc
@@ -929,8 +929,7 @@ TestCase("dirContextMenuSharedDrive").NewDirectoryTree(), TestCase("dirContextMenuSharedWithMe").NewDirectoryTree(), TestCase("dirContextMenuOffline").NewDirectoryTree(), - // TODO(b/301340154): should Computers allow rename? - // TestCase("dirContextMenuComputers").NewDirectoryTree(), + TestCase("dirContextMenuComputers").NewDirectoryTree(), TestCase("dirContextMenuTrash").NewDirectoryTree(), TestCase("dirContextMenuShortcut").NewDirectoryTree(), TestCase("dirContextMenuFocus").NewDirectoryTree(), @@ -1891,17 +1890,16 @@ Recents, /* recents.js */ FilesAppBrowserTest, ::testing::Values( - // TODO(b/307657164): enable the test - // TestCase("recentsNested").NewDirectoryTree(), + TestCase("recentsNested").NewDirectoryTree(), TestCase("recentsFilterResetToAll").NewDirectoryTree(), TestCase("recentsA11yMessages") .NewDirectoryTree() .FeatureIds({"screenplay-af443ca0-6d9f-4cb3-af8f-0939c37833db"}), TestCase("recentsReadOnlyHidden").NewDirectoryTree(), - // TestCase("recentsAllowDeletion").EnableArc().NewDirectoryTree(), - // TestCase("recentsAllowMultipleFilesDeletion") - // .EnableArc() - // .NewDirectoryTree(), + TestCase("recentsAllowDeletion").EnableArc().NewDirectoryTree(), + TestCase("recentsAllowMultipleFilesDeletion") + .EnableArc() + .NewDirectoryTree(), TestCase("recentsAllowRename") .EnableArc() .NewDirectoryTree() @@ -1909,7 +1907,7 @@ TestCase("recentsNoRenameForPlayFiles").EnableArc().NewDirectoryTree(), TestCase("recentsAllowCutForDownloads").NewDirectoryTree(), TestCase("recentsAllowCutForDrive").NewDirectoryTree(), - // TestCase("recentsAllowCutForPlayFiles").EnableArc().NewDirectoryTree(), + TestCase("recentsAllowCutForPlayFiles").EnableArc().NewDirectoryTree(), TestCase("recentsTimePeriodHeadings").NewDirectoryTree(), TestCase("recentsEmptyFolderMessage").NewDirectoryTree(), TestCase("recentsEmptyFolderMessageAfterDeletion").NewDirectoryTree(),
diff --git a/chrome/browser/extensions/external_pref_loader.cc b/chrome/browser/extensions/external_pref_loader.cc index 90894bb..93a3a15 100644 --- a/chrome/browser/extensions/external_pref_loader.cc +++ b/chrome/browser/extensions/external_pref_loader.cc
@@ -299,9 +299,6 @@ ReadStandaloneExtensionPrefFiles(prefs); } - if (base_path_id_ == chrome::DIR_EXTERNAL_EXTENSIONS) - UMA_HISTOGRAM_COUNTS_100("Extensions.ExternalJsonCount", prefs.size()); - // If we have any records to process, then we must have // read at least one .json file. If so, then we should have // set |base_path_|.
diff --git a/chrome/browser/file_system_access/chrome_file_system_access_permission_context_unittest.cc b/chrome/browser/file_system_access/chrome_file_system_access_permission_context_unittest.cc index 5468816..9ff2d3b8 100644 --- a/chrome/browser/file_system_access/chrome_file_system_access_permission_context_unittest.cc +++ b/chrome/browser/file_system_access/chrome_file_system_access_permission_context_unittest.cc
@@ -615,36 +615,39 @@ TEST_F(ChromeFileSystemAccessPermissionContextTest, ConfirmSensitiveEntryAccess_DangerousFile) { + base::FilePath home_dir = temp_dir_.GetPath().AppendASCII("home"); + base::ScopedPathOverride home_override(base::DIR_HOME, home_dir, true, true); + // Saving files with a harmless extension should be allowed. - EXPECT_EQ(ConfirmSensitiveEntryAccessSync( - permission_context(), PathType::kLocal, - temp_dir_.GetPath().AppendASCII("test.txt"), HandleType::kFile, - UserAction::kSave), - SensitiveDirectoryResult::kAllowed); + EXPECT_EQ( + ConfirmSensitiveEntryAccessSync(permission_context(), PathType::kLocal, + home_dir.AppendASCII("test.txt"), + HandleType::kFile, UserAction::kSave), + SensitiveDirectoryResult::kAllowed); // Saving files with a dangerous extension should show a prompt. - EXPECT_EQ(ConfirmSensitiveEntryAccessSync( - permission_context(), PathType::kLocal, - temp_dir_.GetPath().AppendASCII("test.swf"), HandleType::kFile, - UserAction::kSave), - SensitiveDirectoryResult::kAbort); + EXPECT_EQ( + ConfirmSensitiveEntryAccessSync(permission_context(), PathType::kLocal, + home_dir.AppendASCII("test.swf"), + HandleType::kFile, UserAction::kSave), + SensitiveDirectoryResult::kAbort); // Files with a dangerous extension from no user action should be allowed. - EXPECT_EQ(ConfirmSensitiveEntryAccessSync( - permission_context(), PathType::kLocal, - temp_dir_.GetPath().AppendASCII("test.swf"), HandleType::kFile, - UserAction::kNone), - SensitiveDirectoryResult::kAllowed); + EXPECT_EQ( + ConfirmSensitiveEntryAccessSync(permission_context(), PathType::kLocal, + home_dir.AppendASCII("test.swf"), + HandleType::kFile, UserAction::kNone), + SensitiveDirectoryResult::kAllowed); // Opening files with a dangerous extension should be allowed. - EXPECT_EQ(ConfirmSensitiveEntryAccessSync( - permission_context(), PathType::kLocal, - temp_dir_.GetPath().AppendASCII("test.swf"), HandleType::kFile, - UserAction::kOpen), - SensitiveDirectoryResult::kAllowed); + EXPECT_EQ( + ConfirmSensitiveEntryAccessSync(permission_context(), PathType::kLocal, + home_dir.AppendASCII("test.swf"), + HandleType::kFile, UserAction::kOpen), + SensitiveDirectoryResult::kAllowed); // Opening files with a dangerous compound extension should show a prompt. - EXPECT_EQ(ConfirmSensitiveEntryAccessSync( - permission_context(), PathType::kLocal, - temp_dir_.GetPath().AppendASCII("test.txt.swf"), - HandleType::kFile, UserAction::kSave), - SensitiveDirectoryResult::kAbort); + EXPECT_EQ( + ConfirmSensitiveEntryAccessSync(permission_context(), PathType::kLocal, + home_dir.AppendASCII("test.txt.swf"), + HandleType::kFile, UserAction::kSave), + SensitiveDirectoryResult::kAbort); } TEST_F(ChromeFileSystemAccessPermissionContextTest,
diff --git a/chrome/browser/installable/ml_promotion_browsertest.cc b/chrome/browser/installable/ml_promotion_browsertest.cc index acd9c729..ef2ba8a 100644 --- a/chrome/browser/installable/ml_promotion_browsertest.cc +++ b/chrome/browser/installable/ml_promotion_browsertest.cc
@@ -698,7 +698,7 @@ web_contents()); views::NamedWidgetShownWaiter waiter(views::test::AnyWidgetTestPasskey{}, - "WebAppConfirmationView"); + "CreateShortcutConfirmationView"); chrome::ExecuteCommand(browser(), IDC_CREATE_SHORTCUT); views::Widget* widget = waiter.WaitIfNeededAndGet(); EXPECT_TRUE(widget != nullptr); @@ -728,7 +728,7 @@ case InstallDialogState::kDetailedInstallDialog: return "WebAppDetailedInstallDialog"; case InstallDialogState::kCreateShortcutDialog: - return "WebAppConfirmationView"; + return "CreateShortcutConfirmationView"; } }
diff --git a/chrome/browser/performance_manager/metrics/page_timeline_cpu_monitor.cc b/chrome/browser/performance_manager/metrics/page_timeline_cpu_monitor.cc index 70daa327..ff8dc28d 100644 --- a/chrome/browser/performance_manager/metrics/page_timeline_cpu_monitor.cc +++ b/chrome/browser/performance_manager/metrics/page_timeline_cpu_monitor.cc
@@ -61,7 +61,7 @@ if (features::kUseResourceAttributionCPUMonitor.Get()) { CHECK(cached_cpu_measurements_.empty()); - cpu_query_ = std::make_unique<resource_attribution::ScopedCPUQuery>(graph); + cpu_query_ = std::make_unique<resource_attribution::ScopedCPUQuery>(); return; }
diff --git a/chrome/browser/performance_manager/metrics/page_timeline_monitor.h b/chrome/browser/performance_manager/metrics/page_timeline_monitor.h index 6104daf..63148ce 100644 --- a/chrome/browser/performance_manager/metrics/page_timeline_monitor.h +++ b/chrome/browser/performance_manager/metrics/page_timeline_monitor.h
@@ -266,7 +266,7 @@ std::unique_ptr<CpuProbe> system_cpu_probe_ GUARDED_BY_CONTEXT(sequence_checker_); std::unique_ptr<CpuProbe> delayed_system_cpu_probe_ - GUARDED_BY_CONTEXT(sequence_checker_) = nullptr; + GUARDED_BY_CONTEXT(sequence_checker_); // WeakPtrFactory for the RepeatingTimer to call a method on this object. base::WeakPtrFactory<PageTimelineMonitor> weak_factory_{this};
diff --git a/chrome/browser/performance_manager/metrics/page_timeline_monitor_browsertest.cc b/chrome/browser/performance_manager/metrics/page_timeline_monitor_browsertest.cc index 458910b7..4002d8e8 100644 --- a/chrome/browser/performance_manager/metrics/page_timeline_monitor_browsertest.cc +++ b/chrome/browser/performance_manager/metrics/page_timeline_monitor_browsertest.cc
@@ -167,7 +167,7 @@ EXPECT_TRUE(page_node); static_cast<PageNodeImpl*>(page_node.get()) - ->GetMainFrameNodeImpl() + ->main_frame_node() ->SetLifecycleState(mojom::LifecycleState::kFrozen); mechanism::PageDiscarder discarder;
diff --git a/chrome/browser/predictors/loading_predictor_browsertest.cc b/chrome/browser/predictors/loading_predictor_browsertest.cc index b37b7c9..7774cac 100644 --- a/chrome/browser/predictors/loading_predictor_browsertest.cc +++ b/chrome/browser/predictors/loading_predictor_browsertest.cc
@@ -139,7 +139,7 @@ void OnPredictorInitialized() override { run_loop_.Quit(); } private: - raw_ptr<ResourcePrefetchPredictor> predictor_; + raw_ptr<ResourcePrefetchPredictor> predictor_ = nullptr; base::RunLoop run_loop_; }; @@ -173,10 +173,11 @@ bool success) override { ResolveHostRequestInfo preconnect_info{url.host(), network_anonymization_key}; - if (success) + if (success) { successful_dns_lookups_.insert(preconnect_info); - else + } else { unsuccessful_dns_lookups_.insert(preconnect_info); + } CheckForWaitingLoop(); } @@ -186,10 +187,11 @@ bool success) override { ResolveProxyRequestInfo resolve_info{url::Origin::Create(url), network_anonymization_key}; - if (success) + if (success) { successful_proxy_lookups_.insert(resolve_info); - else + } else { unsuccessful_proxy_lookups_.insert(resolve_info); + } CheckForWaitingLoop(); } @@ -307,8 +309,9 @@ waiting_on_dns_ = ResolveHostRequestInfo(); break; case WaitEvent::kProxy: - if (!HasProxyBeenLookedUp(waiting_on_proxy_)) + if (!HasProxyBeenLookedUp(waiting_on_proxy_)) { return; + } waiting_on_proxy_ = ResolveProxyRequestInfo(); break; } @@ -365,8 +368,9 @@ void WaitForPrefetchesForNavigation(const GURL& url) { DCHECK(waiting_url_.is_empty()); DCHECK(!url.is_empty()); - if (done_urls_.find(url) != done_urls_.end()) + if (done_urls_.find(url) != done_urls_.end()) { return; + } waiting_url_ = url; base::RunLoop loop; done_callback_ = loop.QuitClosure(); @@ -445,6 +449,8 @@ initializer.EnsurePredictorInitialized(); } + void TearDownOnMainThread() override { loading_predictor_ = nullptr; } + // Navigates to an URL without blocking until the navigation finishes. // Returns an observer that can be used to wait for the navigation // completion. @@ -487,8 +493,9 @@ auto prediction = std::make_unique<PreconnectPrediction>(); bool has_prediction = loading_predictor_->resource_prefetch_predictor() ->PredictPreconnectOrigins(url, prediction.get()); - if (!has_prediction) + if (!has_prediction) { return nullptr; + } return prediction; } @@ -513,8 +520,9 @@ static std::unique_ptr<net::test_server::HttpResponse> HandleFaviconRequest( const net::test_server::HttpRequest& request) { - if (request.relative_url != "/favicon.ico") + if (request.relative_url != "/favicon.ico") { return nullptr; + } auto http_response = std::make_unique<net::test_server::BasicHttpResponse>(); @@ -552,7 +560,7 @@ net::EmbeddedTestServer preconnecting_test_server_; private: - raw_ptr<LoadingPredictor, DanglingUntriaged> loading_predictor_ = nullptr; + raw_ptr<LoadingPredictor> loading_predictor_ = nullptr; std::unique_ptr<net::test_server::ConnectionTracker> connection_tracker_; std::unique_ptr<net::test_server::ConnectionTracker> preconnecting_server_connection_tracker_; @@ -1267,8 +1275,9 @@ // Verify that the redirect from |redirecting_url| to |destination_url| was // learned and preconnected to. - if (i == 1) + if (i == 1) { preconnecting_server_connection_tracker()->WaitForAcceptedConnections(1); + } EXPECT_EQ(0u, connection_tracker()->GetReadSocketCount()); // Verify that the preconnects to |embedded_test_server| were made using @@ -1980,8 +1989,9 @@ // Returns once all expected requests have been received. void WaitForRequests() { - if (expected_requests_.empty()) + if (expected_requests_.empty()) { return; + } base::RunLoop loop; quit_ = loop.QuitClosure(); loop.Run(); @@ -2000,8 +2010,9 @@ // (which includes host+port). GURL url = request.GetURL(); auto host_iter = request.headers.find("Host"); - if (host_iter != request.headers.end()) + if (host_iter != request.headers.end()) { url = GURL("http://" + host_iter->second + request.relative_url); + } // Remove the expected request. auto it = expected_requests_.find(url); @@ -2010,8 +2021,9 @@ expected_requests_.erase(it); // Finish if done. - if (expected_requests_.empty() && quit_) + if (expected_requests_.empty() && quit_) { std::move(quit_).Run(); + } } base::flat_set<GURL> expected_requests_; @@ -2021,8 +2033,9 @@ // Tests that the LoadingPredictor performs prefetching // for a navigation which it has a prediction for and there isn't a local // prediction available. -IN_PROC_BROWSER_TEST_P(LoadingPredictorPrefetchBrowserTest, - DISABLED_PrepareForPageLoadWithPredictionForPrefetchNoLocalHint) { +IN_PROC_BROWSER_TEST_P( + LoadingPredictorPrefetchBrowserTest, + DISABLED_PrepareForPageLoadWithPredictionForPrefetchNoLocalHint) { GURL url = embedded_test_server()->GetURL( "test.com", GetPathWithPortReplacement(kHtmlSubresourcesPath, embedded_test_server()->port())); @@ -2315,6 +2328,8 @@ web_contents_ = browser()->tab_strip_model()->GetActiveWebContents(); } + void TearDownOnMainThread() override { web_contents_ = nullptr; } + content::WebContents* web_contents() { return web_contents_; } content::test::PrerenderTestHelper prerender_test_helper_; @@ -2323,7 +2338,7 @@ content::WebContents* GetWebContents() { return web_contents_; } net::test_server::EmbeddedTestServerHandle test_server_handle_; - raw_ptr<content::WebContents, AcrossTasksDanglingUntriaged> web_contents_; + raw_ptr<content::WebContents> web_contents_ = nullptr; }; IN_PROC_BROWSER_TEST_F(MultiPageBrowserTest, LoadingPredictor) {
diff --git a/chrome/browser/tpcd/http_error_observer/js_error_ukm_browsertest.cc b/chrome/browser/tpcd/http_error_observer/js_error_ukm_browsertest.cc index 3b51e7e9..720fd08 100644 --- a/chrome/browser/tpcd/http_error_observer/js_error_ukm_browsertest.cc +++ b/chrome/browser/tpcd/http_error_observer/js_error_ukm_browsertest.cc
@@ -103,7 +103,8 @@ } // Test that JS Error is registered on Iframe containing uncaught JS error -IN_PROC_BROWSER_TEST_F(JSErrProcBrowserTest, IframeJSErr) { +// Flaky: https://crbug.com/1503531. +IN_PROC_BROWSER_TEST_F(JSErrProcBrowserTest, DISABLED_IframeJSErr) { ukm::TestAutoSetUkmRecorder ukm_recorder; ASSERT_TRUE(ui_test_utils::NavigateToURL(
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index f7fe559..205c709f 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -5942,6 +5942,8 @@ "views/user_education/browser_help_bubble.h", "views/user_education/browser_user_education_service.cc", "views/user_education/browser_user_education_service.h", + "views/web_apps/create_shortcut_confirmation_view.cc", + "views/web_apps/create_shortcut_confirmation_view.h", "views/web_apps/file_handler_launch_dialog_view.cc", "views/web_apps/file_handler_launch_dialog_view.h", "views/web_apps/frame_toolbar/system_app_accessible_name.cc", @@ -5979,8 +5981,6 @@ "views/web_apps/pwa_confirmation_bubble_view.cc", "views/web_apps/pwa_confirmation_bubble_view.h", "views/web_apps/sub_apps_install_dialog.cc", - "views/web_apps/web_app_confirmation_view.cc", - "views/web_apps/web_app_confirmation_view.h", "views/web_apps/web_app_detailed_install_dialog.cc", "views/web_apps/web_app_detailed_install_dialog.h", "views/web_apps/web_app_identity_update_confirmation_view.cc",
diff --git a/chrome/browser/ui/views/payments/payment_request_use_stats_browsertest.cc b/chrome/browser/ui/views/payments/payment_request_use_stats_browsertest.cc index f686072..7ef312af 100644 --- a/chrome/browser/ui/views/payments/payment_request_use_stats_browsertest.cc +++ b/chrome/browser/ui/views/payments/payment_request_use_stats_browsertest.cc
@@ -33,7 +33,9 @@ // Tests that use stats for the shipping address used in a Payment Request are // properly updated upon completion. -IN_PROC_BROWSER_TEST_F(PaymentRequestShippingAddressUseStatsTest, RecordUse) { +// Flaky. https://crbug.com/1495539. +IN_PROC_BROWSER_TEST_F(PaymentRequestShippingAddressUseStatsTest, + DISABLED_RecordUse) { std::string payment_method_name; InstallPaymentApp("a.com", "/payment_request_success_responder.js", &payment_method_name); @@ -78,7 +80,9 @@ // Tests that use stats for the contact address used in a Payment Request are // properly updated upon completion. -IN_PROC_BROWSER_TEST_F(PaymentRequestContactAddressUseStatsTest, RecordUse) { +// Flaky. https://crbug.com/1495539. +IN_PROC_BROWSER_TEST_F(PaymentRequestContactAddressUseStatsTest, + DISABLED_RecordUse) { std::string payment_method_name; InstallPaymentApp("a.com", "/payment_request_success_responder.js", &payment_method_name); @@ -123,8 +127,9 @@ // Tests that use stats for an address that was used both as a shipping and // contact address in a Payment Request are properly updated upon completion. +// Flaky. https://crbug.com/1495539. IN_PROC_BROWSER_TEST_F(PaymentRequestSameShippingAndContactAddressUseStatsTest, - RecordUse) { + DISABLED_RecordUse) { std::string payment_method_name; InstallPaymentApp("a.com", "/payment_request_success_responder.js", &payment_method_name);
diff --git a/chrome/browser/ui/views/side_panel/read_later_side_panel_web_view.cc b/chrome/browser/ui/views/side_panel/read_later_side_panel_web_view.cc index 37e6828..c204843 100644 --- a/chrome/browser/ui/views/side_panel/read_later_side_panel_web_view.cc +++ b/chrome/browser/ui/views/side_panel/read_later_side_panel_web_view.cc
@@ -76,3 +76,6 @@ void ReadLaterSidePanelWebView::UpdateActiveURLToActiveTab() { UpdateActiveURL(browser_->tab_strip_model()->GetActiveWebContents()); } + +BEGIN_METADATA(ReadLaterSidePanelWebView) +END_METADATA
diff --git a/chrome/browser/ui/views/side_panel/read_later_side_panel_web_view.h b/chrome/browser/ui/views/side_panel/read_later_side_panel_web_view.h index b936728..5f8adfa 100644 --- a/chrome/browser/ui/views/side_panel/read_later_side_panel_web_view.h +++ b/chrome/browser/ui/views/side_panel/read_later_side_panel_web_view.h
@@ -11,12 +11,16 @@ #include "chrome/browser/ui/views/bubble/bubble_contents_wrapper.h" #include "chrome/browser/ui/views/side_panel/side_panel_web_ui_view.h" #include "chrome/browser/ui/webui/side_panel/reading_list/reading_list_ui.h" +#include "ui/base/metadata/metadata_header_macros.h" #include "ui/views/controls/webview/webview.h" class Browser; class ReadLaterSidePanelWebView : public SidePanelWebUIViewT<ReadingListUI>, public TabStripModelObserver { + using SidePanelWebUIViewT_ReadingListUI = SidePanelWebUIViewT<ReadingListUI>; + METADATA_HEADER(ReadLaterSidePanelWebView, SidePanelWebUIViewT_ReadingListUI) + public: ReadLaterSidePanelWebView(Browser* browser, base::RepeatingClosure close_cb); ReadLaterSidePanelWebView(const ReadLaterSidePanelWebView&) = delete;
diff --git a/chrome/browser/ui/views/web_apps/web_app_confirmation_view.cc b/chrome/browser/ui/views/web_apps/create_shortcut_confirmation_view.cc similarity index 87% rename from chrome/browser/ui/views/web_apps/web_app_confirmation_view.cc rename to chrome/browser/ui/views/web_apps/create_shortcut_confirmation_view.cc index c0cc762..2e6074d 100644 --- a/chrome/browser/ui/views/web_apps/web_app_confirmation_view.cc +++ b/chrome/browser/ui/views/web_apps/create_shortcut_confirmation_view.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/ui/views/web_apps/web_app_confirmation_view.h" +#include "chrome/browser/ui/views/web_apps/create_shortcut_confirmation_view.h" #include <memory> #include <string> @@ -43,7 +43,7 @@ namespace { -WebAppConfirmationView* g_dialog_for_testing = nullptr; +CreateShortcutConfirmationView* g_dialog_for_testing = nullptr; bool g_auto_accept_web_app_for_testing = false; bool g_auto_check_open_in_window_for_testing = false; const char* g_title_to_use_for_app = nullptr; @@ -92,13 +92,14 @@ } // namespace // static -WebAppConfirmationView* WebAppConfirmationView::GetDialogForTesting() { +CreateShortcutConfirmationView* +CreateShortcutConfirmationView::GetDialogForTesting() { return g_dialog_for_testing; } -WebAppConfirmationView::~WebAppConfirmationView() = default; +CreateShortcutConfirmationView::~CreateShortcutConfirmationView() = default; -WebAppConfirmationView::WebAppConfirmationView( +CreateShortcutConfirmationView::CreateShortcutConfirmationView( std::unique_ptr<web_app::WebAppInstallInfo> web_app_info, std::unique_ptr<webapps::MlInstallOperationTracker> install_tracker, web_app::AppInstallationAcceptanceCallback callback) @@ -137,18 +138,21 @@ // Builds the header row child views. auto builder = - views::Builder<WebAppConfirmationView>(this) + views::Builder<CreateShortcutConfirmationView>(this) .SetButtonLabel( ui::DIALOG_BUTTON_OK, l10n_util::GetStringUTF16(IDS_CREATE_SHORTCUTS_BUTTON_LABEL)) .SetModalType(ui::MODAL_TYPE_CHILD) .SetTitle(IDS_ADD_TO_OS_LAUNCH_SURFACE_BUBBLE_TITLE) - .SetAcceptCallback(base::BindOnce(&WebAppConfirmationView::OnAccept, - weak_ptr_factory_.GetWeakPtr())) - .SetCloseCallback(base::BindOnce(&WebAppConfirmationView::OnClose, - weak_ptr_factory_.GetWeakPtr())) - .SetCancelCallback(base::BindOnce(&WebAppConfirmationView::OnCancel, - weak_ptr_factory_.GetWeakPtr())) + .SetAcceptCallback( + base::BindOnce(&CreateShortcutConfirmationView::OnAccept, + weak_ptr_factory_.GetWeakPtr())) + .SetCloseCallback( + base::BindOnce(&CreateShortcutConfirmationView::OnClose, + weak_ptr_factory_.GetWeakPtr())) + .SetCancelCallback( + base::BindOnce(&CreateShortcutConfirmationView::OnCancel, + weak_ptr_factory_.GetWeakPtr())) .set_margins(layout_provider->GetDialogInsetsForContentType( views::DialogContentType::kControl, views::DialogContentType::kText)) @@ -221,33 +225,33 @@ title_tf_->SelectAll(true); } -views::View* WebAppConfirmationView::GetInitiallyFocusedView() { +views::View* CreateShortcutConfirmationView::GetInitiallyFocusedView() { return title_tf_; } -bool WebAppConfirmationView::ShouldShowCloseButton() const { +bool CreateShortcutConfirmationView::ShouldShowCloseButton() const { return false; } -bool WebAppConfirmationView::IsDialogButtonEnabled( +bool CreateShortcutConfirmationView::IsDialogButtonEnabled( ui::DialogButton button) const { return button == ui::DIALOG_BUTTON_OK ? !GetTrimmedTitle().empty() : true; } -void WebAppConfirmationView::ContentsChanged( +void CreateShortcutConfirmationView::ContentsChanged( views::Textfield* sender, const std::u16string& new_contents) { DCHECK_EQ(title_tf_, sender); DialogModelChanged(); } -std::u16string WebAppConfirmationView::GetTrimmedTitle() const { +std::u16string CreateShortcutConfirmationView::GetTrimmedTitle() const { std::u16string title(title_tf_->GetText()); base::TrimWhitespace(title, base::TRIM_ALL, &title); return title; } -void WebAppConfirmationView::OnAccept() { +void CreateShortcutConfirmationView::OnAccept() { CHECK(web_app_info_); web_app_info_->title = GetTrimmedTitle(); if (AllowOpenInWindowOptions()) { @@ -278,32 +282,32 @@ std::move(callback_).Run(true, std::move(web_app_info_)); } -void WebAppConfirmationView::OnClose() { +void CreateShortcutConfirmationView::OnClose() { CHECK(install_tracker_); install_tracker_->ReportResult(webapps::MlInstallUserResponse::kIgnored); RunCloseCallbackIfExists(); } -void WebAppConfirmationView::OnCancel() { +void CreateShortcutConfirmationView::OnCancel() { CHECK(install_tracker_); install_tracker_->ReportResult(webapps::MlInstallUserResponse::kCancelled); RunCloseCallbackIfExists(); } -void WebAppConfirmationView::RunCloseCallbackIfExists() { +void CreateShortcutConfirmationView::RunCloseCallbackIfExists() { if (callback_) { CHECK(web_app_info_); std::move(callback_).Run(false, std::move(web_app_info_)); } } -BEGIN_METADATA(WebAppConfirmationView, views::DialogDelegateView) +BEGIN_METADATA(CreateShortcutConfirmationView, views::DialogDelegateView) ADD_READONLY_PROPERTY_METADATA(std::u16string, TrimmedTitle) END_METADATA namespace web_app { -void ShowWebAppInstallDialog( +void ShowCreateShortcutDialog( content::WebContents* web_contents, std::unique_ptr<web_app::WebAppInstallInfo> web_app_info, std::unique_ptr<webapps::MlInstallOperationTracker> install_tracker, @@ -311,7 +315,7 @@ CHECK(web_app_info); CHECK(web_app_info->manifest_id.is_valid()); CHECK(install_tracker); - auto* dialog = new WebAppConfirmationView( + auto* dialog = new CreateShortcutConfirmationView( std::move(web_app_info), std::move(install_tracker), std::move(callback)); constrained_window::ShowWebModalDialogViews(dialog, web_contents); @@ -322,7 +326,7 @@ } } -void SetAutoAcceptWebAppDialogForTesting(bool auto_accept, +void SetAutoAcceptWebAppDialogForTesting(bool auto_accept, // IN-TEST bool auto_open_in_window) { g_auto_accept_web_app_for_testing = auto_accept; g_auto_check_open_in_window_for_testing = auto_open_in_window;
diff --git a/chrome/browser/ui/views/web_apps/web_app_confirmation_view.h b/chrome/browser/ui/views/web_apps/create_shortcut_confirmation_view.h similarity index 73% rename from chrome/browser/ui/views/web_apps/web_app_confirmation_view.h rename to chrome/browser/ui/views/web_apps/create_shortcut_confirmation_view.h index 26cef93..5bf7bac 100644 --- a/chrome/browser/ui/views/web_apps/web_app_confirmation_view.h +++ b/chrome/browser/ui/views/web_apps/create_shortcut_confirmation_view.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_UI_VIEWS_WEB_APPS_WEB_APP_CONFIRMATION_VIEW_H_ -#define CHROME_BROWSER_UI_VIEWS_WEB_APPS_WEB_APP_CONFIRMATION_VIEW_H_ +#ifndef CHROME_BROWSER_UI_VIEWS_WEB_APPS_CREATE_SHORTCUT_CONFIRMATION_VIEW_H_ +#define CHROME_BROWSER_UI_VIEWS_WEB_APPS_CREATE_SHORTCUT_CONFIRMATION_VIEW_H_ #include <memory> #include <string> @@ -27,22 +27,24 @@ class MlInstallOperationTracker; } // namespace webapps -// WebAppConfirmationView provides views for editing the details to -// create a web app with. (More tools > Add to desktop) -class WebAppConfirmationView : public views::DialogDelegateView, +// CreateShortcutConfirmationView provides views for editing the details to +// create a "shortcut" web app with (More tools > Create Shortcut). +class CreateShortcutConfirmationView : public views::DialogDelegateView, public views::TextfieldController { public: - METADATA_HEADER(WebAppConfirmationView); + METADATA_HEADER(CreateShortcutConfirmationView); - static WebAppConfirmationView* GetDialogForTesting(); + static CreateShortcutConfirmationView* GetDialogForTesting(); - WebAppConfirmationView( + CreateShortcutConfirmationView( std::unique_ptr<web_app::WebAppInstallInfo> web_app_info, std::unique_ptr<webapps::MlInstallOperationTracker> install_tracker, web_app::AppInstallationAcceptanceCallback callback); - WebAppConfirmationView(const WebAppConfirmationView&) = delete; - WebAppConfirmationView& operator=(const WebAppConfirmationView&) = delete; - ~WebAppConfirmationView() override; + CreateShortcutConfirmationView(const CreateShortcutConfirmationView&) = + delete; + CreateShortcutConfirmationView& operator=( + const CreateShortcutConfirmationView&) = delete; + ~CreateShortcutConfirmationView() override; views::Checkbox* GetOpenAsWindowCheckboxForTesting() { return open_as_window_checkbox_.get(); @@ -98,12 +100,12 @@ // Textfield showing the title of the app. raw_ptr<views::Textfield> title_tf_ = nullptr; - base::WeakPtrFactory<WebAppConfirmationView> weak_ptr_factory_{this}; + base::WeakPtrFactory<CreateShortcutConfirmationView> weak_ptr_factory_{this}; }; -BEGIN_VIEW_BUILDER(, WebAppConfirmationView, views::DialogDelegateView) +BEGIN_VIEW_BUILDER(, CreateShortcutConfirmationView, views::DialogDelegateView) END_VIEW_BUILDER -DEFINE_VIEW_BUILDER(, WebAppConfirmationView) +DEFINE_VIEW_BUILDER(, CreateShortcutConfirmationView) -#endif // CHROME_BROWSER_UI_VIEWS_WEB_APPS_WEB_APP_CONFIRMATION_VIEW_H_ +#endif // CHROME_BROWSER_UI_VIEWS_WEB_APPS_CREATE_SHORTCUT_CONFIRMATION_VIEW_H_
diff --git a/chrome/browser/ui/views/web_apps/web_app_confirmation_view_browsertest.cc b/chrome/browser/ui/views/web_apps/create_shortcut_confirmation_view_browsertest.cc similarity index 85% rename from chrome/browser/ui/views/web_apps/web_app_confirmation_view_browsertest.cc rename to chrome/browser/ui/views/web_apps/create_shortcut_confirmation_view_browsertest.cc index 2b55cc5..ba6b589 100644 --- a/chrome/browser/ui/views/web_apps/web_app_confirmation_view_browsertest.cc +++ b/chrome/browser/ui/views/web_apps/create_shortcut_confirmation_view_browsertest.cc
@@ -8,7 +8,7 @@ #include "base/test/test_future.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/test/test_browser_dialog.h" -#include "chrome/browser/ui/views/web_apps/web_app_confirmation_view.h" +#include "chrome/browser/ui/views/web_apps/create_shortcut_confirmation_view.h" #include "chrome/browser/ui/web_applications/web_app_dialogs.h" #include "chrome/browser/web_applications/web_app_helpers.h" #include "chrome/browser/web_applications/web_app_install_info.h" @@ -31,14 +31,15 @@ bool tab_strip_enabled; }; -class WebAppConfirmViewBrowserTest +class CreateShortcutConfirmationViewBrowserTest : public DialogBrowserTest, public ::testing::WithParamInterface<Params> { public: - WebAppConfirmViewBrowserTest() = default; - WebAppConfirmViewBrowserTest(const WebAppConfirmViewBrowserTest&) = delete; - WebAppConfirmViewBrowserTest& operator=(const WebAppConfirmViewBrowserTest&) = - delete; + CreateShortcutConfirmationViewBrowserTest() = default; + CreateShortcutConfirmationViewBrowserTest( + const CreateShortcutConfirmationViewBrowserTest&) = delete; + CreateShortcutConfirmationViewBrowserTest& operator=( + const CreateShortcutConfirmationViewBrowserTest&) = delete; // DialogBrowserTest: void ShowUi(const std::string& name) override { @@ -58,7 +59,7 @@ ->RegisterCurrentInstallForWebContents( webapps::WebappInstallSource::MENU_CREATE_SHORTCUT); - web_app::ShowWebAppInstallDialog(web_contents, std::move(app_info), + web_app::ShowCreateShortcutDialog(web_contents, std::move(app_info), std::move(install_tracker), base::BindLambdaForTesting(callback)); } @@ -94,7 +95,8 @@ base::test::ScopedFeatureList feature_list; }; -IN_PROC_BROWSER_TEST_P(WebAppConfirmViewBrowserTest, ShowWebAppInstallDialog) { +IN_PROC_BROWSER_TEST_P(CreateShortcutConfirmationViewBrowserTest, + ShowCreateShortcutDialog) { auto app_info = std::make_unique<web_app::WebAppInstallInfo>( web_app::GenerateManifestIdFromStartUrlOnly(GURL("https://example.com"))); app_info->title = u"Test app"; @@ -118,7 +120,7 @@ ->RegisterCurrentInstallForWebContents( webapps::WebappInstallSource::MENU_CREATE_SHORTCUT); - web_app::ShowWebAppInstallDialog(web_contents, std::move(app_info), + web_app::ShowCreateShortcutDialog(web_contents, std::move(app_info), std::move(install_tracker), base::BindLambdaForTesting(callback)); EXPECT_TRUE(is_accepted); @@ -132,8 +134,8 @@ } } -IN_PROC_BROWSER_TEST_P(WebAppConfirmViewBrowserTest, - VerifyWebAppInstallDialogContents) { +IN_PROC_BROWSER_TEST_P(CreateShortcutConfirmationViewBrowserTest, + VerifyCreateShortcutDialogContents) { auto app_info = std::make_unique<web_app::WebAppInstallInfo>( web_app::GenerateManifestIdFromStartUrlOnly(GURL("https://example.com"))); app_info->title = u"Test app"; @@ -151,12 +153,12 @@ ->RegisterCurrentInstallForWebContents( webapps::WebappInstallSource::MENU_CREATE_SHORTCUT); - web_app::ShowWebAppInstallDialog(web_contents, std::move(app_info), + web_app::ShowCreateShortcutDialog(web_contents, std::move(app_info), std::move(install_tracker), install_result.GetCallback()); - WebAppConfirmationView* dialog = - WebAppConfirmationView::GetDialogForTesting(); + CreateShortcutConfirmationView* dialog = + CreateShortcutConfirmationView::GetDialogForTesting(); ASSERT_TRUE(dialog); EXPECT_TRUE(dialog->GetVisible()); @@ -177,11 +179,13 @@ web_app::mojom::UserDisplayMode::kBrowser); } -IN_PROC_BROWSER_TEST_P(WebAppConfirmViewBrowserTest, InvokeUi_default) { +IN_PROC_BROWSER_TEST_P(CreateShortcutConfirmationViewBrowserTest, + InvokeUi_default) { ShowAndVerifyUi(); } -IN_PROC_BROWSER_TEST_P(WebAppConfirmViewBrowserTest, NormalizeTitles) { +IN_PROC_BROWSER_TEST_P(CreateShortcutConfirmationViewBrowserTest, + NormalizeTitles) { web_app::SetAutoAcceptWebAppDialogForTesting(/*auto_accept=*/true, /*auto_open_in_window=*/true); @@ -217,7 +221,7 @@ ->RegisterCurrentInstallForWebContents( webapps::WebappInstallSource::MENU_CREATE_SHORTCUT); - web_app::ShowWebAppInstallDialog(web_contents, std::move(app_info), + web_app::ShowCreateShortcutDialog(web_contents, std::move(app_info), std::move(install_tracker), base::BindLambdaForTesting(callback)); EXPECT_TRUE(is_accepted) << test_case.input; @@ -226,7 +230,7 @@ } INSTANTIATE_TEST_SUITE_P(All, - WebAppConfirmViewBrowserTest, + CreateShortcutConfirmationViewBrowserTest, ::testing::Values(Params{false, false}, Params{false, true}, Params{true, false},
diff --git a/chrome/browser/ui/web_applications/web_app_dialog_utils.cc b/chrome/browser/ui/web_applications/web_app_dialog_utils.cc index 2b892f5..ec9e5da 100644 --- a/chrome/browser/ui/web_applications/web_app_dialog_utils.cc +++ b/chrome/browser/ui/web_applications/web_app_dialog_utils.cc
@@ -115,9 +115,9 @@ } #endif - ShowWebAppInstallDialog(initiator_web_contents, std::move(web_app_info), - std::move(install_tracker), - std::move(web_app_acceptance_callback)); + ShowCreateShortcutDialog(initiator_web_contents, std::move(web_app_info), + std::move(install_tracker), + std::move(web_app_acceptance_callback)); return; case WebAppInstallFlow::kUnknown: NOTREACHED();
diff --git a/chrome/browser/ui/web_applications/web_app_dialogs.h b/chrome/browser/ui/web_applications/web_app_dialogs.h index 8a7d9fb..f9a99bb 100644 --- a/chrome/browser/ui/web_applications/web_app_dialogs.h +++ b/chrome/browser/ui/web_applications/web_app_dialogs.h
@@ -54,12 +54,10 @@ using AppInstallationAcceptanceCallback = base::OnceCallback<void(bool, std::unique_ptr<WebAppInstallInfo>)>; -// Shows the Web App install bubble. +// Shows the Create Shortcut confirmation dialog. // // |web_app_info| is the WebAppInstallInfo being converted into an app. -// |web_app_info.app_url| should contain a start url from a web app manifest -// (for a Desktop PWA), or the current url (when creating a shortcut app). -void ShowWebAppInstallDialog( +void ShowCreateShortcutDialog( content::WebContents* web_contents, std::unique_ptr<WebAppInstallInfo> web_app_info, std::unique_ptr<webapps::MlInstallOperationTracker> install_tracker,
diff --git a/chrome/browser/ui/webui/discards/graph_dump_impl_unittest.cc b/chrome/browser/ui/webui/discards/graph_dump_impl_unittest.cc index 7efd3658..3a575a65 100644 --- a/chrome/browser/ui/webui/discards/graph_dump_impl_unittest.cc +++ b/chrome/browser/ui/webui/discards/graph_dump_impl_unittest.cc
@@ -205,7 +205,7 @@ mock_graph.other_page->OnMainFrameNavigationCommitted( false, now, next_navigation_id++, kExampleUrl, kHtmlMimeType); - auto* main_frame = mock_graph.page->GetMainFrameNodeImpl(); + auto* main_frame = mock_graph.page->main_frame_node(); main_frame->OnNavigationCommitted(kExampleUrl, /* same_document */ false); std::unique_ptr<DiscardsGraphDumpImpl> impl =
diff --git a/chrome/build/android-arm32.pgo.txt b/chrome/build/android-arm32.pgo.txt index 098b6dd..cea0d444 100644 --- a/chrome/build/android-arm32.pgo.txt +++ b/chrome/build/android-arm32.pgo.txt
@@ -1 +1 @@ -chrome-android32-main-1700304503-4c92600cb58ad59a66583876119ce0082ada5ba0.profdata +chrome-android32-main-1700438073-b700ac64e357f6edfde004f5fe7052dd22cfc71e.profdata
diff --git a/chrome/build/android-arm64.pgo.txt b/chrome/build/android-arm64.pgo.txt index c1f86a9..2aeee2a 100644 --- a/chrome/build/android-arm64.pgo.txt +++ b/chrome/build/android-arm64.pgo.txt
@@ -1 +1 @@ -chrome-android64-main-1700304503-6830d19ed1105b43cf4fb7270428f296f88f16ce.profdata +chrome-android64-main-1700438073-bfe0fbd10fedb26cd5c558cb8d1da1b51637c67a.profdata
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt index e3fe5b4..0e5fd35 100644 --- a/chrome/build/linux.pgo.txt +++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@ -chrome-linux-main-1700304503-e7e79e5f3491a979c24b823618112a3ed7ea4968.profdata +chrome-linux-main-1700438073-8c2b1ed47a172b736e943ea2202594b436e05975.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt index 52da8cf0..eb4c60c3 100644 --- a/chrome/build/mac.pgo.txt +++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@ -chrome-mac-main-1700304503-fa40e23be1924696f2b6468bda707ea7abfbedef.profdata +chrome-mac-main-1700438073-932d511927ea9d2cc26366780ad0a740210963ef.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt index ba31d5f3..4160ebe 100644 --- a/chrome/build/win32.pgo.txt +++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@ -chrome-win32-main-1700304503-5da51015a9536d45ef004315b1eee6b0fce5fb15.profdata +chrome-win32-main-1700438073-af3bf248ea36afa4e8d90781d503d82ec2732aa8.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt index 97bc350..39e9723 100644 --- a/chrome/build/win64.pgo.txt +++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@ -chrome-win64-main-1700304503-3229d7cfff22e5eaca9f44fb7ce63c84dfd80d92.profdata +chrome-win64-main-1700438073-c5bde7e805c54c4720d2a6df06816d77c949c292.profdata
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 2b9d255..73de8df 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -3748,8 +3748,8 @@ "../browser/preloading/prefetch/no_state_prefetch/no_state_prefetch_test_utils.cc", "../browser/preloading/prefetch/no_state_prefetch/no_state_prefetch_test_utils.h", "../browser/safe_browsing/extension_telemetry/extension_telemetry_service_browsertest.cc", + "../browser/ui/views/web_apps/create_shortcut_confirmation_view_browsertest.cc", "../browser/ui/views/web_apps/pwa_confirmation_bubble_view_browsertest.cc", - "../browser/ui/views/web_apps/web_app_confirmation_view_browsertest.cc", "../browser/ui/views/web_apps/web_app_identity_update_confirmation_view_browsertest.cc", "../browser/user_bypass/user_bypass_web_contents_observer_browsertest.cc", ] @@ -5447,8 +5447,8 @@ "../browser/apps/platform_apps/api/sync_file_system/sync_file_system_apitest.cc", "../browser/apps/platform_apps/api/sync_file_system/sync_file_system_browsertest.cc", "../browser/apps/platform_apps/audio_focus_web_contents_observer_browsertest.cc", + "../browser/ui/views/web_apps/create_shortcut_confirmation_view_browsertest.cc", "../browser/ui/views/web_apps/pwa_confirmation_bubble_view_browsertest.cc", - "../browser/ui/views/web_apps/web_app_confirmation_view_browsertest.cc", "../browser/ui/views/web_apps/web_app_identity_update_confirmation_view_browsertest.cc", # Exclude tests that depend on native messaging.
diff --git a/chromeos/CHROMEOS_LKGM b/chromeos/CHROMEOS_LKGM index 128757c..635fac8 100644 --- a/chromeos/CHROMEOS_LKGM +++ b/chromeos/CHROMEOS_LKGM
@@ -1 +1 @@ -15681.0.0 \ No newline at end of file +15683.0.0 \ No newline at end of file
diff --git a/chromeos/ash/components/language_packs/language_pack_manager.cc b/chromeos/ash/components/language_packs/language_pack_manager.cc index 87e5722..e78c2db 100644 --- a/chromeos/ash/components/language_packs/language_pack_manager.cc +++ b/chromeos/ash/components/language_packs/language_pack_manager.cc
@@ -30,6 +30,8 @@ namespace ash::language_packs { namespace { +LanguagePackManager* g_instance = nullptr; + const base::flat_map<std::string, std::string>& GetAllBasePackDlcIds() { // Map of all features and corresponding Base Pack DLC IDs. static const base::NoDestructor<base::flat_map<std::string, std::string>> @@ -493,19 +495,33 @@ } LanguagePackManager::LanguagePackManager() { + CHECK(!g_instance); + g_instance = this; obs_.Observe(DlcserviceClient::Get()); } -LanguagePackManager::~LanguagePackManager() {} +LanguagePackManager::~LanguagePackManager() { + CHECK_EQ(g_instance, this); + g_instance = nullptr; +} -void LanguagePackManager::ResetForTesting() { - observers_.Clear(); +void LanguagePackManager::Initialise() { + // Heap-allocates an instance, which is then set in `g_instance` in the + // constructor. + // This instance will be cleaned up in `Shutdown()`. + // Calling this while `g_instance` is set will result in a `CHECK` failure + // instead of a memory leak. + new LanguagePackManager(); +} + +void LanguagePackManager::Shutdown() { + CHECK(g_instance); + delete g_instance; } // static LanguagePackManager* LanguagePackManager::GetInstance() { - static base::NoDestructor<LanguagePackManager> instance; - return instance.get(); + return g_instance; } } // namespace ash::language_packs
diff --git a/chromeos/ash/components/language_packs/language_pack_manager.h b/chromeos/ash/components/language_packs/language_pack_manager.h index 7b0bd75..9dfb44e 100644 --- a/chromeos/ash/components/language_packs/language_pack_manager.h +++ b/chromeos/ash/components/language_packs/language_pack_manager.h
@@ -10,7 +10,6 @@ #include "base/containers/flat_map.h" #include "base/functional/callback.h" -#include "base/no_destructor.h" #include "base/observer_list.h" #include "base/scoped_observation.h" #include "base/strings/strcat.h" @@ -182,10 +181,18 @@ virtual void OnPackStateChanged(const PackResult& pack_result) = 0; }; + // Do not use unless in tests. + // Only one `LanguagePackManager` can be instantiated at any time. + // Use `GetInstance()` instead to obtain the currently instantiated instance, + // likely instantiated by `Initialise()`. + LanguagePackManager(); + // Disallow copy and assign. LanguagePackManager(const LanguagePackManager&) = delete; LanguagePackManager& operator=(const LanguagePackManager&) = delete; + ~LanguagePackManager() override; + // Returns true if the given Language Pack exists and can be installed on // this device. // TODO(claudiomagni): Check per board. @@ -235,20 +242,33 @@ // Removes an observer from the observer list. void RemoveObserver(Observer* observer); - // Testing only: called to free up resources since this object should never - // be destroyed. - void ResetForTesting(); + // Initialises the global instance. This is typically called from + // ash_dbus_helper.h's `InitializeDBus()`, which is called from + // `ChromeMainDelegate::PostEarlyInitialization()`. + // Cannot be called multiple times - `GetInstance()` must return `nullptr` + // before this static method is called. + // Requires the global `DlcserviceClient` to be initialised. + // Do not use this in tests, instantiate a test-local `LanguagePackManager` + // instead. + static void Initialise(); - // Returns the global instance.. + // Shuts down the global instance. This is typically called from + // ash_dbus_helper.h's `ShutdownDBus()`, which is called from + // `ChromeBrowserMainPartsAsh::PostDestroyThreads()`. + // Cannot be called multiple times - `GetInstance()` must return a non-null + // pointer before this static method is called. + // The global `DlcserviceClient` at the time of initialisation must still + // exist when this is called. + // Do not use this in tests, the destructor of the test-local + // `LanguagePackManager` will correctly unset the currently instantiated + // instance. + static void Shutdown(); + + // Returns the currently instantiated instance. This is typically the global + // instance, but may be a test-local `LanguagePackManager` during tests. static LanguagePackManager* GetInstance(); private: - friend base::NoDestructor<LanguagePackManager>; - - // This class should be accessed only via GetInstance(); - LanguagePackManager(); - ~LanguagePackManager() override; - // Retrieves the list of installed DLCs and updates Packs accordingly. // This function should be called when LPM initializes and then each time // Prefs change.
diff --git a/chromeos/ash/components/language_packs/language_pack_manager_unittest.cc b/chromeos/ash/components/language_packs/language_pack_manager_unittest.cc index a4c3fe8..880c3dfb 100644 --- a/chromeos/ash/components/language_packs/language_pack_manager_unittest.cc +++ b/chromeos/ash/components/language_packs/language_pack_manager_unittest.cc
@@ -88,25 +88,13 @@ class LanguagePackManagerTest : public testing::Test { public: void SetUp() override { - // The Fake DLC Service needs to be initialized before we instantiate - // LanguagePackManager. - DlcserviceClient::InitializeFake(); - dlcservice_client_ = - static_cast<FakeDlcserviceClient*>(DlcserviceClient::Get()); - session_manager_ = std::make_unique<session_manager::SessionManager>(); - manager_ = LanguagePackManager::GetInstance(); ResetPackResult(); base::RunLoop().RunUntilIdle(); } - void TearDown() override { - manager_->ResetForTesting(); - DlcserviceClient::Shutdown(); - } - void InstallTestCallback(const PackResult& pack_result) { pack_result_ = pack_result; } @@ -124,10 +112,8 @@ } protected: - raw_ptr<LanguagePackManager, ExperimentalAsh> manager_; PackResult pack_result_; - raw_ptr<FakeDlcserviceClient, DanglingUntriaged | ExperimentalAsh> - dlcservice_client_; + FakeDlcserviceClient dlcservice_client_; std::unique_ptr<session_manager::SessionManager> session_manager_; private: @@ -140,8 +126,8 @@ }; TEST_F(LanguagePackManagerTest, InstallSuccessTest) { - dlcservice_client_->set_install_error(dlcservice::kErrorNone); - dlcservice_client_->set_install_root_path("/path"); + dlcservice_client_.set_install_error(dlcservice::kErrorNone); + dlcservice_client_.set_install_root_path("/path"); // Test UMA metrics: pre-condition. base::HistogramTester histogram_tester; @@ -171,7 +157,7 @@ } TEST_F(LanguagePackManagerTest, InstallFailureTest) { - dlcservice_client_->set_install_error(dlcservice::kErrorInternal); + dlcservice_client_.set_install_error(dlcservice::kErrorInternal); // Test UMA metrics: pre-condition. base::HistogramTester histogram_tester; @@ -213,8 +199,8 @@ // Check that the callback is actually called. TEST_F(LanguagePackManagerTest, InstallCallbackTest) { - dlcservice_client_->set_install_error(dlcservice::kErrorNone); - dlcservice_client_->set_install_root_path("/path"); + dlcservice_client_.set_install_error(dlcservice::kErrorNone); + dlcservice_client_.set_install_root_path("/path"); testing::StrictMock<CallbackForTesting> callback; EXPECT_CALL(callback, Callback(_)); @@ -225,12 +211,12 @@ } TEST_F(LanguagePackManagerTest, GetPackStateSuccessTest) { - dlcservice_client_->set_get_dlc_state_error(dlcservice::kErrorNone); + dlcservice_client_.set_get_dlc_state_error(dlcservice::kErrorNone); dlcservice::DlcState dlc_state; dlc_state.set_state(dlcservice::DlcState_State_INSTALLED); dlc_state.set_is_verified(true); dlc_state.set_root_path("/path"); - dlcservice_client_->set_dlc_state(dlc_state); + dlcservice_client_.set_dlc_state(dlc_state); // Test UMA metrics: pre-condition. base::HistogramTester histogram_tester; @@ -256,7 +242,7 @@ } TEST_F(LanguagePackManagerTest, GetPackStateFailureTest) { - dlcservice_client_->set_get_dlc_state_error(dlcservice::kErrorInternal); + dlcservice_client_.set_get_dlc_state_error(dlcservice::kErrorInternal); // Test UMA metrics: pre-condition. base::HistogramTester histogram_tester; @@ -294,7 +280,7 @@ // Check that the callback is actually called. TEST_F(LanguagePackManagerTest, GetPackStateCallbackTest) { - dlcservice_client_->set_get_dlc_state_error(dlcservice::kErrorNone); + dlcservice_client_.set_get_dlc_state_error(dlcservice::kErrorNone); testing::StrictMock<CallbackForTesting> callback; EXPECT_CALL(callback, Callback(_)); @@ -305,7 +291,7 @@ } TEST_F(LanguagePackManagerTest, RemovePackSuccessTest) { - dlcservice_client_->set_uninstall_error(dlcservice::kErrorNone); + dlcservice_client_.set_uninstall_error(dlcservice::kErrorNone); // Test UMA metrics: pre-condition. base::HistogramTester histogram_tester; @@ -334,7 +320,7 @@ } TEST_F(LanguagePackManagerTest, RemovePackFailureTest) { - dlcservice_client_->set_uninstall_error(dlcservice::kErrorInternal); + dlcservice_client_.set_uninstall_error(dlcservice::kErrorInternal); // Test UMA metrics: pre-condition. base::HistogramTester histogram_tester; @@ -376,7 +362,7 @@ // Check that the callback is actually called. TEST_F(LanguagePackManagerTest, RemovePackCallbackTest) { - dlcservice_client_->set_uninstall_error(dlcservice::kErrorNone); + dlcservice_client_.set_uninstall_error(dlcservice::kErrorNone); testing::StrictMock<CallbackForTesting> callback; EXPECT_CALL(callback, Callback(_)); @@ -387,45 +373,49 @@ } TEST_F(LanguagePackManagerTest, InstallObserverTest) { - dlcservice_client_->set_install_error(dlcservice::kErrorNone); - dlcservice_client_->set_install_root_path("/path"); + LanguagePackManager manager; + + dlcservice_client_.set_install_error(dlcservice::kErrorNone); + dlcservice_client_.set_install_root_path("/path"); const DlcState dlc_state = CreateInstalledState(); MockObserver observer; EXPECT_CALL(observer, OnPackStateChanged(_)).Times(0); - dlcservice_client_->NotifyObserversForTest(dlc_state); + dlcservice_client_.NotifyObserversForTest(dlc_state); // Add an Observer and expect it to be notified. - manager_->AddObserver(&observer); + manager.AddObserver(&observer); EXPECT_CALL(observer, OnPackStateChanged(_)) .With( FieldsAre(AllOf(Field(&PackResult::feature_id, kHandwritingFeatureId), Field(&PackResult::language_code, "de")))) .Times(1); - dlcservice_client_->NotifyObserversForTest(dlc_state); + dlcservice_client_.NotifyObserversForTest(dlc_state); base::RunLoop().RunUntilIdle(); } TEST_F(LanguagePackManagerTest, RemoveObserverTest) { - dlcservice_client_->set_install_error(dlcservice::kErrorNone); - dlcservice_client_->set_install_root_path("/path"); + LanguagePackManager manager; + + dlcservice_client_.set_install_error(dlcservice::kErrorNone); + dlcservice_client_.set_install_root_path("/path"); const DlcState dlc_state = CreateInstalledState(); MockObserver observer; // Add an Observer and expect it to be notified. - manager_->AddObserver(&observer); + manager.AddObserver(&observer); EXPECT_CALL(observer, OnPackStateChanged(_)) .With( FieldsAre(AllOf(Field(&PackResult::feature_id, kHandwritingFeatureId), Field(&PackResult::language_code, "de")))) .Times(1); - dlcservice_client_->NotifyObserversForTest(dlc_state); + dlcservice_client_.NotifyObserversForTest(dlc_state); // Remove the Observer and there should be no more notifications. - manager_->RemoveObserver(&observer); + manager.RemoveObserver(&observer); EXPECT_CALL(observer, OnPackStateChanged(_)).Times(0); - dlcservice_client_->NotifyObserversForTest(dlc_state); + dlcservice_client_.NotifyObserversForTest(dlc_state); base::RunLoop().RunUntilIdle(); } @@ -471,8 +461,8 @@ } TEST_F(LanguagePackManagerTest, InstallBasePackSuccess) { - dlcservice_client_->set_install_error(dlcservice::kErrorNone); - dlcservice_client_->set_install_root_path("/path"); + dlcservice_client_.set_install_error(dlcservice::kErrorNone); + dlcservice_client_.set_install_root_path("/path"); // Test UMA metrics: pre-condition. base::HistogramTester histogram_tester; @@ -497,7 +487,7 @@ } TEST_F(LanguagePackManagerTest, InstallBasePackFailureTestFailure) { - dlcservice_client_->set_install_error(dlcservice::kErrorInternal); + dlcservice_client_.set_install_error(dlcservice::kErrorInternal); // Test UMA metrics: pre-condition. base::HistogramTester histogram_tester; @@ -523,8 +513,8 @@ TEST_F(LanguagePackManagerTest, UpdatePacksForOobeNotOobeTest) { // Set session as user logged in. session_manager_->SetSessionState(session_manager::SessionState::ACTIVE); - dlcservice_client_->set_install_error(dlcservice::kErrorNone); - dlcservice_client_->set_install_root_path("/path"); + dlcservice_client_.set_install_error(dlcservice::kErrorNone); + dlcservice_client_.set_install_root_path("/path"); testing::StrictMock<CallbackForTesting> callback; EXPECT_CALL(callback, Callback(_)).Times(0); @@ -537,8 +527,8 @@ TEST_F(LanguagePackManagerTest, UpdatePacksForOobeSuccessTest) { session_manager_->SetSessionState(session_manager::SessionState::OOBE); - dlcservice_client_->set_install_error(dlcservice::kErrorNone); - dlcservice_client_->set_install_root_path("/path"); + dlcservice_client_.set_install_error(dlcservice::kErrorNone); + dlcservice_client_.set_install_root_path("/path"); // Test UMA metrics: pre-condition. base::HistogramTester histogram_tester; @@ -568,8 +558,8 @@ TEST_F(LanguagePackManagerTest, UpdatePacksForOobeSuccess2Test) { session_manager_->SetSessionState(session_manager::SessionState::OOBE); - dlcservice_client_->set_install_error(dlcservice::kErrorNone); - dlcservice_client_->set_install_root_path("/path"); + dlcservice_client_.set_install_error(dlcservice::kErrorNone); + dlcservice_client_.set_install_root_path("/path"); // Test UMA metrics: pre-condition. base::HistogramTester histogram_tester; @@ -599,8 +589,8 @@ TEST_F(LanguagePackManagerTest, UpdatePacksForOobeWrongLocaleTest) { session_manager_->SetSessionState(session_manager::SessionState::OOBE); - dlcservice_client_->set_install_error(dlcservice::kErrorNone); - dlcservice_client_->set_install_root_path("/path"); + dlcservice_client_.set_install_error(dlcservice::kErrorNone); + dlcservice_client_.set_install_root_path("/path"); // Test UMA metrics: pre-condition. base::HistogramTester histogram_tester; @@ -627,7 +617,7 @@ TEST_F(LanguagePackManagerTest, UpdatePacksForOobeFailureTest) { session_manager_->SetSessionState(session_manager::SessionState::OOBE); - dlcservice_client_->set_install_error(dlcservice::kErrorInternal); + dlcservice_client_.set_install_error(dlcservice::kErrorInternal); LanguagePackManager::UpdatePacksForOobe( "es-es", base::BindOnce(&LanguagePackManagerTest::OobeTestCallback,
diff --git a/chromeos/ash/components/report/report_controller.cc b/chromeos/ash/components/report/report_controller.cc index 213601a..4a298e7 100644 --- a/chromeos/ash/components/report/report_controller.cc +++ b/chromeos/ash/components/report/report_controller.cc
@@ -195,11 +195,15 @@ scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, base::Time chrome_first_run_time, base::RepeatingCallback<base::TimeDelta()> check_oobe_completed_callback, + base::RepeatingCallback<policy::DeviceMode()> device_mode_callback, + base::RepeatingCallback<policy::MarketSegment()> market_segment_callback, std::unique_ptr<device_metrics::PsmClientManager> psm_client_manager) : chrome_device_params_(chrome_device_params), local_state_(local_state), url_loader_factory_(url_loader_factory), chrome_first_run_time_(chrome_first_run_time), + device_mode_callback_(std::move(device_mode_callback)), + market_segment_callback_(std::move(market_segment_callback)), report_timer_(std::make_unique<base::RepeatingTimer>()), network_state_handler_(NetworkHandler::Get()->network_state_handler()), statistics_provider_(system::StatisticsProvider::GetInstance()), @@ -311,6 +315,11 @@ return; } + // Set the market segment since we know OOBE was completed and the + // .oobe_completed file existed for more than 1 minute. + chrome_device_params_.market_segment = GetMarketSegment( + device_mode_callback_.Run(), market_segment_callback_.Run()); + // Wrap with callback from |psm_device_active_secret_| retrieval using // |SessionManagerClient| DBus. SessionManagerClient::Get()->GetPsmDeviceActiveSecret(
diff --git a/chromeos/ash/components/report/report_controller.h b/chromeos/ash/components/report/report_controller.h index 8245fb0..58623805 100644 --- a/chromeos/ash/components/report/report_controller.h +++ b/chromeos/ash/components/report/report_controller.h
@@ -84,6 +84,8 @@ scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, base::Time chrome_first_run_time, base::RepeatingCallback<base::TimeDelta()> check_oobe_completed_callback, + base::RepeatingCallback<policy::DeviceMode()> device_mode_callback, + base::RepeatingCallback<policy::MarketSegment()> market_segment_callback, std::unique_ptr<device_metrics::PsmClientManager> psm_client_manager); ReportController(const ReportController&) = delete; ReportController& operator=(const ReportController&) = delete; @@ -155,7 +157,9 @@ void StartReport(); // Chrome browser passed parameters that live throughout this class lifetime. - const device_metrics::ChromeDeviceMetadataParameters chrome_device_params_; + // Market segment field is only assigned after oobe is completed and the + // market segment is known. + device_metrics::ChromeDeviceMetadataParameters chrome_device_params_; // Update relevant pref keys with preserved file data if missing. // Pref keys are found in //report/prefs/fresnel_pref_names.h @@ -168,6 +172,13 @@ // The chrome first run sentinel creation time. base::Time chrome_first_run_time_; + // Store callbacks to retrieve the policy device mode and market segment. + // Method should be called after oobe is successfully completed, and the + // .oobe_completed file is written. + // Callback will outlive this class, and is managed by ash-chrome. + base::RepeatingCallback<policy::DeviceMode()> device_mode_callback_; + base::RepeatingCallback<policy::MarketSegment()> market_segment_callback_; + // Try report metrics every |kTimeToRepeat|. std::unique_ptr<base::RepeatingTimer> report_timer_;
diff --git a/chromeos/ash/components/report/report_controller_unittest.cc b/chromeos/ash/components/report/report_controller_unittest.cc index ac5d9c7..fe5e0f6 100644 --- a/chromeos/ash/components/report/report_controller_unittest.cc +++ b/chromeos/ash/components/report/report_controller_unittest.cc
@@ -244,7 +244,6 @@ public: static constexpr ChromeDeviceMetadataParameters kFakeChromeParameters = { version_info::Channel::STABLE /* chromeos_channel */, - MarketSegment::MARKET_SEGMENT_CONSUMER /* market_segment */, }; void SetUp() override { @@ -274,6 +273,9 @@ report_controller_ = std::make_unique<ReportController>( kFakeChromeParameters, GetLocalState(), GetUrlLoaderFactory(), base::Time(), base::BindRepeating([]() { return base::Minutes(1); }), + base::BindRepeating( + []() { return policy::DeviceMode::DEVICE_MODE_NOT_SET; }), + base::BindRepeating([]() { return policy::MarketSegment::UNKNOWN; }), std::make_unique<PsmClientManager>(std::move(psm_client_delegate))); task_environment_.RunUntilIdle(); @@ -582,8 +584,7 @@ : public ReportControllerTestBase { public: static constexpr ChromeDeviceMetadataParameters kFakeChromeParameters = { - version_info::Channel::STABLE /* chromeos_channel */, - MarketSegment::MARKET_SEGMENT_CONSUMER /* market_segment */, + version_info::Channel::STABLE /* chromeos_channel */ }; void SetUp() override { @@ -617,6 +618,9 @@ report_controller_ = std::make_unique<ReportController>( kFakeChromeParameters, GetLocalState(), GetUrlLoaderFactory(), base::Time(), base::BindRepeating([]() { return base::Minutes(1); }), + base::BindRepeating( + []() { return policy::DeviceMode::DEVICE_MODE_NOT_SET; }), + base::BindRepeating([]() { return policy::MarketSegment::UNKNOWN; }), std::make_unique<PsmClientManager>(std::move(psm_client_delegate))); task_environment_.RunUntilIdle(); @@ -684,7 +688,6 @@ public: static constexpr ChromeDeviceMetadataParameters kFakeChromeParameters = { version_info::Channel::STABLE /* chromeos_channel */, - MarketSegment::MARKET_SEGMENT_CONSUMER /* market_segment */, }; void SetUp() override { @@ -718,6 +721,9 @@ report_controller_ = std::make_unique<ReportController>( kFakeChromeParameters, GetLocalState(), GetUrlLoaderFactory(), base::Time(), base::BindRepeating([]() { return base::Minutes(1); }), + base::BindRepeating( + []() { return policy::DeviceMode::DEVICE_MODE_NOT_SET; }), + base::BindRepeating([]() { return policy::MarketSegment::UNKNOWN; }), std::make_unique<PsmClientManager>(std::move(psm_client_delegate))); task_environment_.RunUntilIdle();
diff --git a/chromeos/profiles/arm-exp.afdo.newest.txt b/chromeos/profiles/arm-exp.afdo.newest.txt index ec7cfa523..bb7f4ee4 100644 --- a/chromeos/profiles/arm-exp.afdo.newest.txt +++ b/chromeos/profiles/arm-exp.afdo.newest.txt
@@ -1 +1 @@ -chromeos-chrome-arm-exp-121-6099.13-1699874308-benchmark-121.0.6126.0-r1-redacted.afdo.xz +chromeos-chrome-arm-exp-121-6099.13-1699874308-benchmark-121.0.6128.0-r1-redacted.afdo.xz
diff --git a/chromeos/profiles/arm.afdo.newest.txt b/chromeos/profiles/arm.afdo.newest.txt index b18b870..9c55ca1 100644 --- a/chromeos/profiles/arm.afdo.newest.txt +++ b/chromeos/profiles/arm.afdo.newest.txt
@@ -1 +1 @@ -chromeos-chrome-arm-none-121-6085.0-1699879816-benchmark-121.0.6128.0-r1-redacted.afdo.xz +chromeos-chrome-arm-none-121-6085.0-1699879816-benchmark-121.0.6136.0-r1-redacted.afdo.xz
diff --git a/chromeos/profiles/atom.afdo.newest.txt b/chromeos/profiles/atom.afdo.newest.txt index ddeb3fc..9380372 100644 --- a/chromeos/profiles/atom.afdo.newest.txt +++ b/chromeos/profiles/atom.afdo.newest.txt
@@ -1 +1 @@ -chromeos-chrome-amd64-atom-121-6099.13-1699874308-benchmark-121.0.6128.0-r1-redacted.afdo.xz +chromeos-chrome-amd64-atom-121-6099.13-1699874308-benchmark-121.0.6136.0-r1-redacted.afdo.xz
diff --git a/chromeos/profiles/bigcore.afdo.newest.txt b/chromeos/profiles/bigcore.afdo.newest.txt index dbec141..ea26047 100644 --- a/chromeos/profiles/bigcore.afdo.newest.txt +++ b/chromeos/profiles/bigcore.afdo.newest.txt
@@ -1 +1 @@ -chromeos-chrome-amd64-bigcore-121-6099.8-1699872611-benchmark-121.0.6128.0-r1-redacted.afdo.xz +chromeos-chrome-amd64-bigcore-121-6099.8-1699872611-benchmark-121.0.6136.0-r1-redacted.afdo.xz
diff --git a/chromeos/strings/chromeos_strings_or.xtb b/chromeos/strings/chromeos_strings_or.xtb index de7ab1b3..6086a40 100644 --- a/chromeos/strings/chromeos_strings_or.xtb +++ b/chromeos/strings/chromeos_strings_or.xtb
@@ -261,7 +261,7 @@ <translation id="2874939134665556319">ପୂର୍ବବର୍ତ୍ତୀ ଟ୍ରାକ୍</translation> <translation id="2878387241690264070"><ph name="NUM_SECONDS" /> ସେକେଣ୍ଡରେ <ph name="RATE" /> ଡିସଚାର୍ଜ ହୋଇଛି।</translation> <translation id="2880569433548999039">କ୍ଲାଉଡ ଫ୍ଲୋ ସ୍କ୍ରିନ ସେଭର</translation> -<translation id="2926057806159140518">ଆପଣଙ୍କ ଉପଯୋଗକର୍ତ୍ତା ନାମ ଏବଂ ପାସୱାର୍ଡ ଲେଖନ୍ତୁ କିମ୍ବା ଆପଣଙ୍କର QR କୋଡ ସ୍କାନ କରନ୍ତୁ</translation> +<translation id="2926057806159140518">ଆପଣଙ୍କ ୟୁଜରନେମ ଏବଂ ପାସୱାର୍ଡ ଲେଖନ୍ତୁ କିମ୍ବା ଆପଣଙ୍କର QR କୋଡ ସ୍କାନ କରନ୍ତୁ</translation> <translation id="2940811910881150316">ଡିଭାଇସକୁ ଟେଷ୍ଟ କରାଯାଇପାରିବ ନାହିଁ। ଟେଷ୍ଟ କରିବକୁ ଲିଡ ପୁଣି ଖୋଲନ୍ତୁ।</translation> <translation id="2941112035454246133">କମ୍</translation> <translation id="3008341117444806826">ରିଫ୍ରେଶ୍ କରନ୍ତୁ</translation>
diff --git a/chromeos/tast_control.gni b/chromeos/tast_control.gni index 145617b..968222c 100644 --- a/chromeos/tast_control.gni +++ b/chromeos/tast_control.gni
@@ -133,14 +133,6 @@ # crbug.com/1500320 "lacros.ShelfLaunch", - # b/309858762 - "login.AuthError", - "login.Offline", - - # b/311116565 - "wmp.DesksTemplatesBasic", - "wmp.DesksTemplatesLaunch", - # READ COMMENT AT TOP BEFORE ADDING NEW TESTS HERE. ]
diff --git a/clank b/clank index d084593..545e490 160000 --- a/clank +++ b/clank
@@ -1 +1 @@ -Subproject commit d084593f4010d6bb4b4b141439462e5b5f18a878 +Subproject commit 545e490705f01ebb699f788c8eadb47a77a4fa6c
diff --git a/components/browser_ui/strings/android/translations/browser_ui_strings_si.xtb b/components/browser_ui/strings/android/translations/browser_ui_strings_si.xtb index db79ace..c4c28a5 100644 --- a/components/browser_ui/strings/android/translations/browser_ui_strings_si.xtb +++ b/components/browser_ui/strings/android/translations/browser_ui_strings_si.xtb
@@ -31,6 +31,7 @@ <translation id="1633720957382884102">අදාළ අඩවි</translation> <translation id="1644574205037202324">ඉතිහාසය</translation> <translation id="1647582022260550163">ඔබට අවසර යළි සැකසීමට සහ කුකී සහ අඩවි දත්ත ඉවත් කිරීමට අවශ්ය බව විශ්වාසද?</translation> +<translation id="1652197001188145583">සක්රීය වූ විට, අඩවිවලට NFC උපාංග භාවිත කිරීමට ඉල්ලිය හැක. අක්රිය වූ විට, අඩවිවලට NFC උපාංග භාවිත කළ නොහැක.</translation> <translation id="1660204651932907780">අඩවිවලට ශබ්දය වාදනය කිරීමට ඉඩ දෙන්න (නිර්දේශිතයි)</translation> <translation id="1677097821151855053">ඔබව මතක තබා ගැනීමට කුකි සහ වෙනත් අඩවි දත්ත භාවිත කරයි, උදාහරණයක් ලෙස ඔබව පිරීමට හෝ වෙළඳ දැන්වීම් පුද්ගලිකකරණය කිරීමට. සියලුම වෙබ් අඩවි සඳහා කුකී කළමනාකරණය කිරීමට, <ph name="BEGIN_LINK" />සැකසීම්<ph name="END_LINK" /> බලන්න.</translation> <translation id="169515064810179024">වෙබ් අඩවි චලන සංවේදක වෙත ප්රවේශ වීම අවහිර කරන්න</translation> @@ -46,6 +47,7 @@ <translation id="1923695749281512248"><ph name="BYTES_DOWNLOADED_WITH_UNITS" /> / <ph name="FILE_SIZE_WITH_UNITS" /></translation> <translation id="1979673356880165407">ඔබ පිවිසෙන සියලු අඩවි සඳහා පෙළ සහ රූප විශාල හෝ කුඩා කරන්න</translation> <translation id="1984937141057606926">අනුමතයි, තෙවන පාර්ශව හැර</translation> +<translation id="1985247341569771101">සක්රීය වූ විට, අඩවිවලට ඔබේ උපාංගයේ චලන සංවේදක භාවිත කළ හැක. අක්රිය වූ විට, අඩවිවලට චලන සංවේදක භාවිත කළ නොහැක.</translation> <translation id="1989112275319619282">බ්රවුස් කරන්න</translation> <translation id="1994173015038366702">අඩවි URL</translation> <translation id="2004697686368036666">සමහර අඩවිවල විශේෂාංග ක්රියා නොකළ හැකිය</translation> @@ -106,6 +108,7 @@ <translation id="2713106313042589954">කැමරාව ක්රියාවිරහිත කරන්න</translation> <translation id="2717722538473713889">ඉ-තැපැල් ලිපින</translation> <translation id="2750481671343847896">අඩවිවලට අනන්යතා සේවාවලින් පිරීමේ ප්රේරක පෙන්විය හැකිය.</translation> +<translation id="2790501146643349491">සක්රීය වූ විට, මෑතදී වසන ලද අඩවිවලට දත්ත යැවීම සහ ලැබීම අවසන් කළ හැක. අක්රිය වූ විට, මෑතදී වසන ලද අඩවිවලට දත්ත යැවීම හෝ ලැබීම අවසන් කළ නොහැක.</translation> <translation id="2822354292072154809">ඔබට <ph name="CHOSEN_OBJECT_NAME" /> සඳහා සියලුම වෙබ් අඩවි අවසර යළි සැකසිය යුතු බව ඔබට තහවුරුද?</translation> <translation id="2850913818900871965">ජංගම දසුන ඉල්ලන්න</translation> <translation id="2870560284913253234">අඩවිය</translation> @@ -114,6 +117,7 @@ <translation id="2903493209154104877">ලිපින</translation> <translation id="2910701580606108292">ආරක්ෂිත අන්තර්ගත වාදනය කිරීමට ඉඩ දීමට පෙර විමසන්න (නිර්දේශිතයි)</translation> <translation id="2932883381142163287">අපහරණය වාර්තා කරන්න</translation> +<translation id="2939338015096024043">සක්රීය වූ විට, අඩවිවලට ඔබේ කැමරා ස්ථානය හඹා යාමටත් ඔබේ වටපිටාව ගැන දැන ගැනීමටත් ඉල්ලිය හැක. අක්රිය වූ විට, අඩවිවලට ඔබේ කැමරා ස්ථානය හඹා යාමට හෝ ඔබේ වටපිටාව ගැන දැන ගැනීමට නොහැකිය.</translation> <translation id="2968755619301702150">සහතික දක්වනය</translation> <translation id="2979365474350987274">තුන් වන පාර්ශ්ව කුකී සීමිතයි</translation> <translation id="3008272652534848354">අවසර යළි සකසන්න</translation> @@ -132,6 +136,7 @@ <translation id="3198916472715691905"><ph name="STORAGE_AMOUNT" /> ගබඩා කළ දත්ත</translation> <translation id="321187648315454507"><ph name="APP_NAME" /> හට ඔබට දැනුම්දීම් එවීමට ඉඩ දීමට <ph name="BEGIN_LINK" />Android සැකසීම්<ph name="END_LINK" /> තුළ දැනුම්දීම්ද ක්රියාත්මක කරන්න.</translation> <translation id="3227137524299004712">මයික්රෆෝනය:</translation> +<translation id="3242646949159196181">සක්රීය වූ විට, අඩවිවලට ශබ්ද ධාවන කළ හැක. අක්රිය වූ විට, අඩවිවලට ශබ්ද ධාවන කළ නොහැක.</translation> <translation id="3277252321222022663">වෙබ් අඩවිවලට සංවේදක වෙත ප්රවේශ වීමට ඉඩ දෙන්න (නිර්දේශිතයි)</translation> <translation id="3285500645985761267">සමූහය තුළ ඔබේ ක්රියාකාරකම් බැලීමට අදාළ වෙබ් අඩවිවලට ඉඩ දෙන්න</translation> <translation id="3295019059349372795">11වන පරිච්ඡේදය: The Wonderful Emerald City of Oz</translation> @@ -142,6 +147,7 @@ <translation id="3386292677130313581">අඩවි වලට ඔබගේ ස්ථානය දැන ගැනීමට ඉඩ දීමට පෙර විමසන්න (නිර්දේශිතයි)</translation> <translation id="3403537308306431953"><ph name="ZOOM_LEVEL" /> %%</translation> <translation id="344449859752187052">තෙවන පාර්ශ්ව කුකීස් අවහිර කර ඇත</translation> +<translation id="3448554387819310837">සක්රීය වූ විට, අඩවිවලට ඔබේ කැමරාව භාවිත කිරීමට ඉල්ලිය හැක. අක්රිය වූ විට, අඩවිවලට ඔබේ කැමරාව භාවිත කළ නොහැක.</translation> <translation id="3465378418721443318">{DAYS,plural, =1{Chrome හෙට නැවතත් කුකී අවහිර කරයි}one{Chrome දින # ක් දක්වා නැවතත් කුකී අවහිර කරයි}other{Chrome දින # ක් දක්වා නැවතත් කුකී අවහිර කරයි}}</translation> <translation id="3521663503435878242"><ph name="DOMAIN" /> යටතේ ඇති අඩවි</translation> <translation id="3538390592868664640">වෙබ් අඩවිය ඔබේ වටපිටාවේ ත්රිමාන සිතියමක් සෑදීමෙන් හෝ කැමරා ස්ථානය හඹා යෑමෙන් අවහිර කරන්න</translation> @@ -154,6 +160,7 @@ <translation id="3600792891314830896">ශබ්දය වාදනය කරන අඩවි නිහඬ කරන්න</translation> <translation id="3602290021589620013">පෙරදසුන</translation> <translation id="3628308229821498208">යෝජිත සෙවීම්</translation> +<translation id="3697164069658504920">සක්රීය වූ විට, අඩවිවලට USB උපාංග භාවිත කිරීමට ඉල්ලිය හැක. අක්රිය වූ විට, අඩවිවලට USB උපාංග භාවිත කළ නොහැක.</translation> <translation id="3707034683772193706">ඔබ පිවිසෙන අඩවියකට ප්රධාන වශයෙන් ඔබ බොට් කෙනෙක් නොවන බව වලංගු කිරීමට, Chrome සමග කුඩා තතු ප්රමාණයක් සුරැකීමට හැක</translation> <translation id="3721953990244350188">අස් කර මීළඟ පවතින ක්රියාව පෙන්වන්න</translation> <translation id="3744111561329211289">පසුබිමෙහි සමමුහුර්තකරණය</translation> @@ -191,6 +198,7 @@ <translation id="4278390842282768270">ඉඩ දුන්</translation> <translation id="429312253194641664">වෙබ් අඩවියක් මාධ්ය ධාවන කරයි</translation> <translation id="42981349822642051">දිගහරින්න</translation> +<translation id="4336566011000459927">Chrome අද නැවතත් කුකී සීමා කරයි</translation> <translation id="4338831206024587507"><ph name="DOMAIN" /> යටතේ සියලු අඩවි</translation> <translation id="4402755511846832236">ඔබ මෙම උපාංගය සක්රියව භාවිත කරන විට දැන ගැනීමෙන් අඩවි අවහිර කරන්න</translation> <translation id="4412992751769744546">තෙවන පාර්ශව කුකී වලට ඉඩ දෙන්න</translation> @@ -209,12 +217,14 @@ <translation id="4645575059429386691">ඔබේ දෙමව්පියන් පාලනය කරයි</translation> <translation id="4670064810192446073">අතත්ය යථාර්ථය</translation> <translation id="4751476147751820511">චලිත හෝ ආලෝක සංවේදක</translation> +<translation id="4755971844837804407">සක්රීය වූ විට, අඩවිවලට ඔබ වෙත ඕනෑම දැන්වීමක් පෙන්විය හැක. අක්රිය වූ විට, අඩවිවලට ආගන්තුක හෝ නොමඟ යවන දැන්වීම් පෙන්විය නොහැක.</translation> <translation id="4779083564647765204">විශාලනය</translation> <translation id="4811450222531576619">එහි මූලාශ්රය සහ මාතෘකාව පිළිබඳව දැන ගන්න</translation> <translation id="4836046166855586901">ඔබ මෙම උපාංගය සක්රියව භාවිත කරන අවස්ථාව අඩවියකට දැන ගැනීමට අවශ්ය විට විමසන්න</translation> <translation id="483914009762354899">මෙම වසම යටතේ සියලු අඩවි ඇතුළත් කරන්න</translation> <translation id="4883854917563148705">කළමනා කෙරෙන සැකසීම් යළි සැකසිය නොහැක</translation> <translation id="4887024562049524730">වෙබ් අඩවිවලට ඔබේ අතත්ය යථාර්ථ උපාංගය සහ දත්ත භාවිත කිරීමට ඉඩ දීමට පෙර අසන්න (නිර්දේශිතයි)</translation> +<translation id="4953688446973710931">සක්රීය වූ විට, අඩවිවලට ගොනු කිහිපයක් ස්වයංක්රීයව බා ගැනීමට ඉල්ලිය හැක. අක්රිය වූ විට, අඩවිවලට ගොනු කිහිපයක් ස්වයංක්රීයව බා ගත නොහැක.</translation> <translation id="4955223779495905865">ඔබ පිවිසෙන වෙබ් අඩවියකට වෙනත් වෙබ් අඩවි වලින් අන්තර්ගතය කාවැද්දීමට හැකිය, උදාහරණයක් ලෙස රූප, දැන්වීම් සහ පාඨය. මෙම ඕනෑම වෙබ් අඩවියකට ඔබේ අත්දැකීම පුද්ගලායන කිරීමට කුකී සහ අනෙකුත් දත්ත සුරැකිය හැකි ය.</translation> <translation id="4962975101802056554">උපාංගය සඳහා සියලුම අවසර අහෝසි කරන්න</translation> <translation id="497421865427891073">ඉදිරියට යන්න</translation> @@ -229,6 +239,7 @@ <translation id="5063480226653192405">භාවිතය</translation> <translation id="5091013926750941408">ජංගම අඩවිය</translation> <translation id="509133520954049755">ඩෙස්ක්ටොප් දසුන ඉල්ලන්න</translation> +<translation id="5091663350197390230">සක්රීය වූ විට, අඩවිවලට ජාවාස්ක්රිප්ට් භාවිත කළ හැක. අක්රිය වූ විට, අඩවිවලට ජාවාස්ක්රිප්ට් භාවිත කළ නොහැක.</translation> <translation id="5099358668261120049">මෙය ඔබේ මුල් තිරයෙහි <ph name="ORIGIN" /> හෝ එහි යෙදුම මගින් ගබඩා කර ඇති සියලු දත්ත සහ කුකීස් මකනු ඇත.</translation> <translation id="5100237604440890931">හකුළන ලදි - දිග හැරීමට ක්ලික් කරන්න</translation> <translation id="5123685120097942451">අප්රකට පටිත්ත</translation> @@ -240,6 +251,7 @@ <translation id="5246825184569358663">මෙම ක්රියාව කුකීස් ඇතුළුව, සියලු ස්ථානීය දත්ත හිස් කර <ph name="DOMAIN" /> සහ ඒ යටතේ ඇති සියලු අඩවි සඳහා සියලු අවසර මකනු ඇත</translation> <translation id="5264323282659631142">'<ph name="CHIP_LABEL" />' ඉවත් කරන්න</translation> <translation id="528192093759286357">ඉහළින් ඇද, පූර්ණ තිරයෙන් ඉවත් වීමට පිටුපස බොත්තම ස්පර්ශ කරන්න.</translation> +<translation id="5295729974480418933">සක්රීය වූ විට, අඩවිවලට ඔවුන් ඔබ ගැන සුරැකී ඇති තොරතුරු භාවිත කිරීමට ඉල්ලිය හැක. අක්රිය වූ විට, අඩවිවලට ඔවුන් ඔබ ගැන සුරැකී ඇති තොරතුරු භාවිත කිරීමට ඉල්ලිය නොහැක.</translation> <translation id="5300589172476337783">පෙන්වන්න</translation> <translation id="5301954838959518834">හරි, එය තේරුණා</translation> <translation id="5317780077021120954">සුරකින්න</translation> @@ -250,6 +262,7 @@ <translation id="5394307150471348411">{DETAIL_COUNT,plural, =1{(තවත් + 1ක්)}one{(තවත් + #ක්)}other{(තවත් + #ක්)}}</translation> <translation id="5403592356182871684">නම්</translation> <translation id="5438097262470833822">මෙම තේරීම <ph name="WEBSITE" /> සඳහා අවසර යළි සකසනු ඇත</translation> +<translation id="5459413148890178711">සක්රීය වූ විට, අඩවිවලට ඔබේ ස්ථානය ඉල්ලිය හැක. අක්රිය වූ විට, අඩවිවලට ඔබේ ස්ථානය බැලිය නොහැක.</translation> <translation id="5489227211564503167">ගත වූ කාලය <ph name="TOTAL_TIME" /> න් <ph name="ELAPSED_TIME" />.</translation> <translation id="5502860503640766021"><ph name="PERMISSION_1" /> ඉඩ දෙන ලදි, <ph name="PERMISSION_2" /> අවහිර කරන ලදි</translation> <translation id="5505264765875738116">වෙබ් අඩවිවලට දැනුම්දීම් යැවීමට ඉල්ලිය නොහැක</translation> @@ -270,6 +283,8 @@ <translation id="5740126560802162366">අඩවිවලට ඔබේ උපාංගයෙහි දත්ත සුරැකිය හැක</translation> <translation id="5771720122942595109"><ph name="PERMISSION_1" /> අවහිර කරන ලදී</translation> <translation id="5804241973901381774">අවසර</translation> +<translation id="5844448279347999754">සක්රීය වූ විට, අඩවිවලට ඔබේ පසුරුපුවරුවට සුරකින ලද පාඨ සහ රූප බැලීමට ඉල්ලිය හැක. අක්රිය වූ විට, අඩවිවලට ඔබේ පසුරුපුවරුවට සුරකින ලද පාඨ සහ රූප බැලිය නොහැක.</translation> +<translation id="5853982612236235577">සක්රීය වූ විට, අඩවිවලට දැනුම් දීම් යැවීමට ඉල්ලිය හැක. අක්රිය වූ විට, අඩවිවලට දැනුම් දීම් යැවිය නොහැක.</translation> <translation id="5860033963881614850">අක්රීය</translation> <translation id="5876056640971328065">විඩියෝව විරාම කරන්න</translation> <translation id="5884085660368669834">අඩවි මනාපය</translation> @@ -288,11 +303,14 @@ <translation id="6042308850641462728">වැඩිදුර</translation> <translation id="6064125863973209585">සම්පූර්ණ කළ බාගැනීම්</translation> <translation id="6071501408666570960">ඔබ මෙම අඩවියෙන් වරනු ලැබේවි</translation> +<translation id="6120483543004435978">සක්රීය වූ විට, අඩවිවලට ඔබ ඔබේ උපාංගය ක්රියාකාරීව භාවිත කරන අවස්ථාව දැන ගැනීමට ඉල්ලිය හැක. අක්රිය වූ විට, අඩවිවලට ඔබ ඔබේ උපාංගය ක්රියාකාරීම භාවිත කරන අවස්ථාව දැන ගත නොහැක.</translation> <translation id="6165508094623778733">තව දැන ගන්න</translation> +<translation id="6171020522141473435">සක්රීය වූ විට, අඩවිවලට බ්ලූටූත් උපාංග භාවිත කිරීමට ඉල්ලිය හැක. අක්රිය වූ විට, අඩවිවලට බ්ලූටූත් උපාංග භාවිත කළ නොහැක.</translation> <translation id="6177111841848151710">වත්මන් සෙවුම් යන්ත්රය සඳහා අවහිරයි</translation> <translation id="6177128806592000436">මෙම අඩවිය වෙත ඔබගේ සම්බන්ධතාවය සුරක්ෂිත නොවේ</translation> <translation id="6181444274883918285">අඩවි ව්යතිරේකයක් එක් කරන්න</translation> <translation id="6192792657125177640">විකල්පයන්</translation> +<translation id="6194967801833346599">{DAYS,plural, =1{Chrome හෙට නැවතත් කුකී අවහිර කරයි}one{කුකීස් නැවත අවහිර වන තෙක් දින # යි}other{කුකීස් නැවත අවහිර වන තෙක් දින # යි}}</translation> <translation id="6195163219142236913">තෙවන පාර්ශ්ව කුකීස් සීමිතයි</translation> <translation id="6196640612572343990">තෙවන-පාර්ශ්ව කුකී අවහිර කරන්න</translation> <translation id="6205314730813004066">දැන්වීම් පෞද්ගලිකත්වය</translation> @@ -313,6 +331,7 @@ <translation id="6500423977866688905">කවුළුව පටු වූ විට, ජංගම දසුන ඉල්ලා සිටින්න</translation> <translation id="6527303717912515753">බෙදාගන්න</translation> <translation id="652937045869844725">තෙවන පාර්ශ්ව කුකීස්වලට ඉඩ දීමට උත්සාහ කරන්න, එයින් අඩු ආරක්ෂණයක් අදහස් වන නමුත් අඩවි විශේෂාංග වැඩ කිරීමට වැඩි ඉඩක් ඇත</translation> +<translation id="6530703012083415527">සක්රීය වූ විට, අඩවිවලට උත්පතන සහ ප්රතියොමු කිරීම් භාවිත කළ හැක. අක්රිය වූ විට, අඩවිවලට උත්පතන සහ ප්රතියොමු කිරීම් භාවිත කළ නොහැක.</translation> <translation id="6545864417968258051">බ්ලූටූත් ස්කෑන් කිරීම</translation> <translation id="6552800053856095716">{PERMISSIONS_SUMMARY_BLOCKED,plural, =1{<ph name="PERMISSION_1" />, <ph name="PERMISSION_2" /> සහ තව <ph name="NUM_MORE" />ක් අවහිර කරන ලදි}one{<ph name="PERMISSION_1" />, <ph name="PERMISSION_2" /> සහ තව <ph name="NUM_MORE" />ක් අවහිර කරන ලදි}other{<ph name="PERMISSION_1" />, <ph name="PERMISSION_2" /> සහ තව <ph name="NUM_MORE" />ක් අවහිර කරන ලදි}}</translation> <translation id="6554732001434021288">දින <ph name="NUM_DAYS" />කට පෙර අවසන් වරට පිවිසි</translation> @@ -356,6 +375,7 @@ <translation id="7243308994586599757">තිරයේ පහළට ආසන්නව විකල්ප ලබා ගත හැකිය</translation> <translation id="7250468141469952378"><ph name="ITEM_COUNT" /> ක් තෝරන ලදී</translation> <translation id="7260727271532453612"><ph name="PERMISSION_1" /> සහ <ph name="PERMISSION_2" /> ඉඩ දෙන ලදි</translation> +<translation id="7276071417425470385">සක්රීය වූ විට, අඩවිවලට අතථ්ය යථාර්ථ උපාංග භාවිත කිරීමට ඉල්ලිය හැක. අක්රිය වූ විට, අඩවිවලට අතථ්ය යථාර්ථ උපාංග භාවිත කළ නොහැක.</translation> <translation id="7284451015630589124">ඔබ බ්රවුස් කරන විට ඔබව හඹා යාමට තුන්වන පාර්ශ්ව කුකීස් භාවිතා කිරීමෙන් ඔබ අඩවි අවහිර කර ඇත. <ph name="BEGIN_LINK" />ඔබේ ලුහුබැඳීමේ ආරක්ෂණ කළමනාකරණය කිරීමට<ph name="END_LINK" /> සැකසීම් වෙත පිවිසෙන්න.</translation> <translation id="7302486331832100261">ඔබ සාමාන්යයෙන් දැනුම් දීම් අවහිර කරයි. අවසර දීමට, විස්තර තට්ටු කරන්න.</translation> <translation id="7366415735885268578">අඩවියක් එක් කරන්න</translation> @@ -367,6 +387,7 @@ <translation id="7425915948813553151">අඩවි සඳහා අඳුරු තේමාව</translation> <translation id="7474522811371247902">තුන්වන පාර්ශ්ව කුකීස් භාවිතා කිරීමෙන් Chrome බොහෝ අඩවි සීමා කරයි. නමුත් මෙම වෙබ් අඩවියේ තුන්වන පාර්ශ්ව කුකීස් වලට එය මූලික සේවා සැපයීම සඳහා ඒවා මත රඳා පවතින නිසා ඉඩ දෙනු ලැබේ.\n\n<ph name="BEGIN_LINK" />ඔබේ නිරීක්ෂණ ආරක්ෂණ කළමනාකරණය කිරීම<ph name="END_LINK" /> සඳහා සැකසීම් වෙත පිවිසෙන්න.</translation> <translation id="7521387064766892559">JavaScript</translation> +<translation id="7547989957535180761">සක්රීය වූ විට, අඩවිවලට පුරන ප්රේරක පෙන්විය හැක. අක්රිය වූ විට, අඩවිවලට පුරන ප්රේරක පෙන්විය නොහැක.</translation> <translation id="7554752735887601236">වෙබ් අඩවියක් ඔබේ මයික්රොෆෝනය භාවිත කරයි</translation> <translation id="7561196759112975576">සැමවිටම</translation> <translation id="757524316907819857">ආරක්ෂිත අන්තර්ගත වාදනය කරමින් තිබෙන අඩවි තහනම් කිරීම</translation> @@ -382,6 +403,7 @@ <translation id="780301667611848630">එපා, ස්තූතියි</translation> <translation id="7804248752222191302">වෙබ් අඩවියක් ඔබේ කැමරාව භාවිත කරයි</translation> <translation id="7807060072011926525">Google විසින් සපයනු ලැබේ</translation> +<translation id="7822573154188733812">Chrome ඔබ බ්රවුස් කරන විට අඩවි ඔබ නිරීක්ෂණ කිරීමට තුන් වන පාර්ශ්ව කුකී භාවිත කිරීම අවහිර කරයි. <ph name="BEGIN_LINK" />ඔබේ හඹා යාම ආරක්ෂණ කළමනා කිරීමට<ph name="END_LINK" /> සැකසීම් වෙත පැමිණෙන්න.</translation> <translation id="7835852323729233924">මාධ්ය ධාවනය</translation> <translation id="783819812427904514">වීඩියෝව නිහඬ නොකරන්න</translation> <translation id="7846076177841592234">තේරීම අවලංගු කරන්න</translation> @@ -390,6 +412,7 @@ <translation id="7940722705963108451">මට සිහිකැඳවන්න</translation> <translation id="7974024493641668069">{COUNT,plural, =1{සමූහය තුළ ඔබේ ක්රියාකාරකම් දැකිය හැකි <ph name="FPS_OWNER" /> ගේ වෙබ් අඩවි සමූහයේ <ph name="FPS_MEMBERS_COUNT" /> වෙබ් අඩවියක්}one{සමූහය තුළ ඔබේ ක්රියාකාරකම් දැකිය හැකි <ph name="FPS_OWNER" /> ගේ වෙබ් අඩවි සමූහයේ වෙබ් අඩවි <ph name="FPS_MEMBERS_COUNT" /> ක්}other{සමූහය තුළ ඔබේ ක්රියාකාරකම් දැකිය හැකි <ph name="FPS_OWNER" /> ගේ වෙබ් අඩවි සමූහයේ වෙබ් අඩවි <ph name="FPS_MEMBERS_COUNT" /> ක්}}</translation> <translation id="7986741934819883144">සම්බන්ධතාවක් තෝරාගන්න</translation> +<translation id="7990211076305263060">සක්රීය වූ විට, අඩවිවලට ඔබේ මයික්රොෆෝනය භාවිත කිරීමට ඉල්ලිය හැක. අක්රිය වූ විට, අඩවිවලට ඔබේ මයික්රොෆෝනය භාවිත කළ නොහැක.</translation> <translation id="8007176423574883786">මෙම උපාංගය සඳහා ක්රියාවිරහිත කරන ලදී.</translation> <translation id="802154636333426148">බාගැනීම අසමත් විය</translation> <translation id="8042586301629853791">අනුපිළිවෙළට සකසන්න:</translation> @@ -398,7 +421,9 @@ <translation id="8077120325605624147">ඔබ පිවිසෙන ඕනෑම අඩවියක් ඔබට ඕනෑම දැන්වීමක් පෙන්විය හැක</translation> <translation id="8087000398470557479">මෙම අන්තර්ගතය Google විසින් බෙදාහරින, <ph name="DOMAIN_NAME" /> වෙතින් වේ.</translation> <translation id="8088603949666785339"><ph name="BANNER_TITLE" /> තුළ තවත් විකල්ප</translation> +<translation id="8113501330600751161">{DAYS,plural, =1{Chrome හෙට නැවතත් කුකී සීමා කරයි}one{Chrome නැවත කුකී සීමා කරන තෙක් දින # යි}other{Chrome නැවත කුකී සීමා කරන තෙක් දින # යි}}</translation> <translation id="8116925261070264013">නිහඬයි</translation> +<translation id="8117244575099414087">සක්රීය වූ විට, අඩවිවලට ඔබේ උපාංගයේ සංවේදක භාවිත කළ හැක. අක්රිය වූ විට, අඩවිවලට සංවේදක භාවිත කළ නොහැක.</translation> <translation id="813082847718468539">අඩවි තොරතුරු පෙන්වන්න</translation> <translation id="8131740175452115882">තහවුරු කරන්න</translation> <translation id="8154912474061769055">බොහෝ අඩවිවල විශේෂාංග ක්රියා නොකළ හැකිය</translation> @@ -436,12 +461,14 @@ <translation id="8564613706851221529">{COUNT,plural, =1{<ph name="FPS_MEMBERS_COUNT" /> <ph name="FPS_OWNER" /> වෙබ් අඩවියක් සඳහා කුකීවලට ඉඩ දී ඇත}one{වෙබ් අඩවි <ph name="FPS_MEMBERS_COUNT" /> <ph name="FPS_OWNER" />කට කුකීවලට ඉඩ දී ඇත}other{වෙබ් අඩවි <ph name="FPS_MEMBERS_COUNT" /> <ph name="FPS_OWNER" />කට කුකීවලට ඉඩ දී ඇත}}</translation> <translation id="857943718398505171">ඉඩ දේ (නිර්දේශිතයි)</translation> <translation id="8609465669617005112">ඉහළට යන්න</translation> +<translation id="8617611086246832542">සක්රීය වූ විට, වෙබ් අඩවියේ ඩෙස්ක්ටොප් දසුන පෙන්වනු ලැබේ. අක්රිය වූ විට, වෙබ් අඩවියේ ජංගම දසුන පෙන්වනු ලැබේ.</translation> <translation id="8649036394979866943">ඔබ බ්රවුස් කරන විට ඔබව හඹා යාමට තුන්වන පාර්ශ්ව කුකීස් භාවිතා කිරීමෙන් Chrome බොහෝ අඩවි සීමා කරයි. <ph name="BEGIN_LINK" />ඔබේ ලුහුබැඳීමේ ආරක්ෂණ කළමනාකරණය කිරීමට<ph name="END_LINK" /> සැකසීම් වෙත පිවිසෙන්න</translation> <translation id="8676374126336081632">ආදානය හිස් කරන්න</translation> <translation id="8681886425883659911">ආක්රමණශීලී හෝ නොමඟ යවන දැන්වීම් පෙන්වීමට දන්නා අඩවිවල දැන්වීම් අවහිර කර ඇත</translation> <translation id="868929229000858085">ඔබේ සම්බන්ධතා සොයන්න</translation> <translation id="8712637175834984815">එය ලැබුණා</translation> <translation id="8719283222052720129"><ph name="APP_NAME" /> සඳහා අවසරය <ph name="BEGIN_LINK" />Android සැකසීම්<ph name="END_LINK" /> තුළ ක්රියාත්මක කරන්න.</translation> +<translation id="8721719390026067591">සක්රීය වූ විට, අඩවිවලට බ්ලූටූත් උපාංග සොයා බැලීමට ඉල්ලිය හැක. අක්රිය වූ විට, අඩවිවලට බ්ලූටූත් උපාංග සොයා බැලිය නොහැක.</translation> <translation id="8725066075913043281">නැවත උත්සහ කරන්න</translation> <translation id="8730621377337864115">අවසන්</translation> <translation id="8736193154595564524">{NUM_SELECTED,plural, =1{1 වෙබ් අඩවියකට ඉඩ දී ඇත}one{වෙබ් අඩවි #කට ඉඩ දී ඇත}other{වෙබ් අඩවි #කට ඉඩ දී ඇත}}</translation> @@ -465,6 +492,7 @@ <translation id="8959122750345127698">සංචාලනය වෙත ළඟා විය නොහැකිය: <ph name="URL" /></translation> <translation id="8986362086234534611">අමතක</translation> <translation id="8990043154272859344">ඔබ සියලු අඩවිවලින් වරනු ලැබේ</translation> +<translation id="9002538116239926534">සක්රීය වූ විට, අඩවිවලට ඔබේ උපාංගය මත දත්ත සුරැකිය හැක. අක්රිය වූ විට, අඩවිවලට ඔබේ උපාංගය මත දත්ත සුරැකිය නොහැක.</translation> <translation id="9011903857143958461"><ph name="SITE_NAME" /> ඉඩ දෙන ලදි</translation> <translation id="9019902583201351841">ඔබේ දෙමව්පියන් පාලනය කරයි</translation> <translation id="9039697262778250930">ඔබ මෙම අඩවිවලින් වරනය විය හැක</translation>
diff --git a/components/certificate_transparency/data/log_list.json b/components/certificate_transparency/data/log_list.json index f7fbb1d..d3e46997 100644 --- a/components/certificate_transparency/data/log_list.json +++ b/components/certificate_transparency/data/log_list.json
@@ -1,6 +1,6 @@ { - "version": "26.48", - "log_list_timestamp": "2023-11-18T12:56:18Z", + "version": "26.49", + "log_list_timestamp": "2023-11-19T12:54:56Z", "operators": [ { "name": "Google",
diff --git a/components/content_settings/browser/page_specific_content_settings.cc b/components/content_settings/browser/page_specific_content_settings.cc index 15c1540..e35e7202 100644 --- a/components/content_settings/browser/page_specific_content_settings.cc +++ b/components/content_settings/browser/page_specific_content_settings.cc
@@ -424,12 +424,7 @@ map_->GetContentSetting(primary_url, secondary_url, ContentSettingsType::POPUPS) == CONTENT_SETTING_ALLOW; -#if BUILDFLAG(IS_ANDROID) - content_settings->allow_auto_dark = - map_->GetContentSetting(primary_url, secondary_url, - ContentSettingsType::AUTO_DARK_WEB_CONTENT) == - CONTENT_SETTING_ALLOW; -#else +#if !BUILDFLAG(IS_ANDROID) content_settings->allow_image = map_->GetContentSetting(primary_url, secondary_url, ContentSettingsType::IMAGES) ==
diff --git a/components/content_settings/renderer/content_settings_agent_impl.cc b/components/content_settings/renderer/content_settings_agent_impl.cc index a0bb429de..c62382c0 100644 --- a/components/content_settings/renderer/content_settings_agent_impl.cc +++ b/components/content_settings/renderer/content_settings_agent_impl.cc
@@ -340,21 +340,6 @@ return allow || IsAllowlistedForContentSettings(); } -bool ContentSettingsAgentImpl::AllowAutoDarkWebContent( - bool enabled_per_settings) { - if (!enabled_per_settings) - return false; - - bool allow = true; - if (content_setting_rules_) { - ContentSetting setting = GetContentSettingFromRules( - content_setting_rules_->auto_dark_content_rules, GURL()); - allow = setting != CONTENT_SETTING_BLOCK; - } - allow = allow || IsAllowlistedForContentSettings(); - return allow; -} - bool ContentSettingsAgentImpl::AllowReadFromClipboard(bool default_value) { return delegate_->AllowReadFromClipboard().value_or(default_value); }
diff --git a/components/content_settings/renderer/content_settings_agent_impl.h b/components/content_settings/renderer/content_settings_agent_impl.h index 28f178b..403617b 100644 --- a/components/content_settings/renderer/content_settings_agent_impl.h +++ b/components/content_settings/renderer/content_settings_agent_impl.h
@@ -84,7 +84,6 @@ bool AllowScript(bool enabled_per_settings) override; bool AllowScriptFromSource(bool enabled_per_settings, const blink::WebURL& script_url) override; - bool AllowAutoDarkWebContent(bool enabled_per_settings) override; bool AllowReadFromClipboard(bool default_value) override; bool AllowWriteToClipboard(bool default_value) override; bool AllowMutationEvents(bool default_value) override;
diff --git a/components/content_settings/renderer/content_settings_agent_impl_browsertest.cc b/components/content_settings/renderer/content_settings_agent_impl_browsertest.cc index 13ed07b..ec8ed46 100644 --- a/components/content_settings/renderer/content_settings_agent_impl_browsertest.cc +++ b/components/content_settings/renderer/content_settings_agent_impl_browsertest.cc
@@ -515,57 +515,4 @@ EXPECT_TRUE(agent->ShouldAutoupgradeMixedContent()); } -TEST_P(ContentSettingsAgentImplBrowserTest, ContentSettingsAllowedAutoDark) { - MockContentSettingsAgentImpl mock_agent(GetMainRenderFrame()); - - // Load some HTML. - LoadHTMLWithUrlOverride("<html></html>", "https://example.com/"); - - // Set the default auto dark mode setting. - RendererContentSettingRules content_setting_rules; - ContentSettingsForOneType& auto_dark_content_rules = - content_setting_rules.auto_dark_content_rules; - auto_dark_content_rules.push_back(ContentSettingPatternSource( - ContentSettingsPattern::Wildcard(), ContentSettingsPattern::Wildcard(), - content_settings::ContentSettingToValue(CONTENT_SETTING_ALLOW), - std::string(), false)); - - ContentSettingsAgentImpl* agent = - ContentSettingsAgentImpl::Get(GetMainRenderFrame()); - agent->SetRendererContentSettingRulesForTest(content_setting_rules); - EXPECT_TRUE(agent->AllowAutoDarkWebContent(true)); - - // Create an exception which blocked the auto dark. - auto_dark_content_rules.insert( - auto_dark_content_rules.begin(), - ContentSettingPatternSource( - ContentSettingsPattern::FromString("https://example.com/"), - ContentSettingsPattern::Wildcard(), - content_settings::ContentSettingToValue(CONTENT_SETTING_BLOCK), - std::string(), false)); - agent->SetRendererContentSettingRulesForTest(content_setting_rules); - EXPECT_FALSE(agent->AllowAutoDarkWebContent(true)); -} - -TEST_P(ContentSettingsAgentImplBrowserTest, ContentSettingsDisabledAutoDark) { - MockContentSettingsAgentImpl mock_agent(GetMainRenderFrame()); - - // Load some HTML. - LoadHTMLWithUrlOverride("<html></html>", "https://example.com/"); - - // Set the default auto dark mode setting. - RendererContentSettingRules content_setting_rules; - ContentSettingsForOneType& auto_dark_content_rules = - content_setting_rules.auto_dark_content_rules; - auto_dark_content_rules.push_back(ContentSettingPatternSource( - ContentSettingsPattern::Wildcard(), ContentSettingsPattern::Wildcard(), - content_settings::ContentSettingToValue(CONTENT_SETTING_BLOCK), - std::string(), false)); - - ContentSettingsAgentImpl* agent = - ContentSettingsAgentImpl::Get(GetMainRenderFrame()); - agent->SetRendererContentSettingRulesForTest(content_setting_rules); - EXPECT_FALSE(agent->AllowAutoDarkWebContent(true)); -} - } // namespace content_settings
diff --git a/components/exo/extended_drag_source_unittest.cc b/components/exo/extended_drag_source_unittest.cc index d21de0f..0d26e10 100644 --- a/components/exo/extended_drag_source_unittest.cc +++ b/components/exo/extended_drag_source_unittest.cc
@@ -698,7 +698,8 @@ auto configure_callback = base::BindLambdaForTesting( [&](const gfx::Rect& bounds, chromeos::WindowStateType state_type, bool resizing, bool activated, const gfx::Vector2d& origin_offset, - float raster_scale) { + float raster_scale, + std::optional<chromeos::WindowStateType> restore_state_type) { drop_bounds = bounds; return ++serial; });
diff --git a/components/exo/shell_surface.cc b/components/exo/shell_surface.cc index f04d8413..869d69c4 100644 --- a/components/exo/shell_surface.cc +++ b/components/exo/shell_surface.cc
@@ -4,6 +4,8 @@ #include "components/exo/shell_surface.h" +#include <optional> + #include "ash/frame/non_client_frame_view_ash.h" #include "ash/public/cpp/shell_window_ids.h" #include "ash/scoped_animation_disabler.h" @@ -919,15 +921,18 @@ if (!configure_callback_.is_null()) { if (window_state) { - serial = configure_callback_.Run(GetClientBoundsInScreen(widget_), - window_state->GetStateType(), - IsResizing(), widget_->IsActive(), - origin_offset, pending_raster_scale_); + auto restore_state_type = std::optional<chromeos::WindowStateType>{ + window_state->GetRestoreWindowState()}; + serial = configure_callback_.Run( + GetClientBoundsInScreen(widget_), window_state->GetStateType(), + IsResizing(), widget_->IsActive(), origin_offset, + pending_raster_scale_, restore_state_type); } else { auto state = chromeos::ToWindowStateType(initial_show_state_); gfx::Rect bounds = GetInitialBoundsForState(state); - serial = configure_callback_.Run(bounds, state, false, false, - origin_offset, pending_raster_scale_); + serial = + configure_callback_.Run(bounds, state, false, false, origin_offset, + pending_raster_scale_, std::nullopt); } }
diff --git a/components/exo/shell_surface.h b/components/exo/shell_surface.h index f45e01c..7614f47 100644 --- a/components/exo/shell_surface.h +++ b/components/exo/shell_surface.h
@@ -5,6 +5,8 @@ #ifndef COMPONENTS_EXO_SHELL_SURFACE_H_ #define COMPONENTS_EXO_SHELL_SURFACE_H_ +#include <optional> + #include "ash/focus_cycler.h" #include "ash/wm/toplevel_window_event_handler.h" #include "ash/wm/window_state_observer.h" @@ -49,13 +51,14 @@ // The size is a hint, in the sense that the client is free to ignore it if // it doesn't resize, pick a smaller size (to satisfy aspect ratio or resize // in steps of NxM pixels). - using ConfigureCallback = - base::RepeatingCallback<uint32_t(const gfx::Rect& bounds, - chromeos::WindowStateType state_type, - bool resizing, - bool activated, - const gfx::Vector2d& origin_offset, - float raster_scale)>; + using ConfigureCallback = base::RepeatingCallback<uint32_t( + const gfx::Rect& bounds, + chromeos::WindowStateType state_type, + bool resizing, + bool activated, + const gfx::Vector2d& origin_offset, + float raster_scale, + std::optional<chromeos::WindowStateType> restore_state_type)>; using OriginChangeCallback = base::RepeatingCallback<void(const gfx::Point& origin)>; using RotateFocusCallback =
diff --git a/components/exo/shell_surface_unittest.cc b/components/exo/shell_surface_unittest.cc index c5a7406d..22c2686b 100644 --- a/components/exo/shell_surface_unittest.cc +++ b/components/exo/shell_surface_unittest.cc
@@ -80,13 +80,15 @@ return !!ash::WorkspaceControllerTestApi(wc).GetBackdropWindow(); } -uint32_t ConfigureFullscreen(uint32_t serial, - const gfx::Rect& bounds, - chromeos::WindowStateType state_type, - bool resizing, - bool activated, - const gfx::Vector2d& origin_offset, - float raster_scale) { +uint32_t ConfigureFullscreen( + uint32_t serial, + const gfx::Rect& bounds, + chromeos::WindowStateType state_type, + bool resizing, + bool activated, + const gfx::Vector2d& origin_offset, + float raster_scale, + std::optional<chromeos::WindowStateType> restore_state_type) { EXPECT_EQ(chromeos::WindowStateType::kFullscreen, state_type); return serial; } @@ -118,22 +120,27 @@ chromeos::WindowStateType state_type = chromeos::WindowStateType::kDefault; bool is_resizing = false; bool is_active = false; + std::optional<chromeos::WindowStateType> restore_state_type = std::nullopt; float raster_scale = 1.0f; + size_t count = 0; }; -uint32_t Configure(ConfigureData* config_data, - const gfx::Rect& bounds, - chromeos::WindowStateType state_type, - bool resizing, - bool activated, - const gfx::Vector2d& origin_offset, - float raster_scale) { +uint32_t Configure( + ConfigureData* config_data, + const gfx::Rect& bounds, + chromeos::WindowStateType state_type, + bool resizing, + bool activated, + const gfx::Vector2d& origin_offset, + float raster_scale, + std::optional<chromeos::WindowStateType> restore_state_type) { config_data->suggested_bounds = bounds; config_data->state_type = state_type; config_data->is_resizing = resizing; config_data->is_active = activated; config_data->raster_scale = raster_scale; + config_data->restore_state_type = restore_state_type; config_data->count++; return 0; } @@ -1269,8 +1276,8 @@ auto configure_callback = base::BindRepeating( [](uint32_t* const serial_ptr, const gfx::Rect& bounds, chromeos::WindowStateType state_type, bool resizing, bool activated, - const gfx::Vector2d& origin_offset, - float raster_scale) { return ++(*serial_ptr); }, + const gfx::Vector2d& origin_offset, float raster_scale, + std::optional<chromeos::WindowStateType>) { return ++(*serial_ptr); }, &serial); // Map shell surface. @@ -1290,7 +1297,7 @@ shell_surface->set_configure_callback(base::BindRepeating( [](const gfx::Rect& bounds, chromeos::WindowStateType state_type, bool resizing, bool activated, const gfx::Vector2d& origin_offset, - float raster_scale) { + float raster_scale, std::optional<chromeos::WindowStateType>) { ADD_FAILURE() << "Configure Should not be called"; return uint32_t{0}; })); @@ -1458,6 +1465,24 @@ EXPECT_FALSE(shell_surface.get()); } +TEST_F(ShellSurfaceTest, ConfigureCallbackSendsRestoreState) { + ConfigureData config_data; + auto shell_surface = test::ShellSurfaceBuilder({256, 256}) + .SetMaximumSize(gfx::Size(10, 10)) + .BuildShellSurface(); + shell_surface->set_configure_callback( + base::BindRepeating(&Configure, base::Unretained(&config_data))); + + shell_surface->root_surface()->Commit(); + shell_surface->Maximize(); + shell_surface->root_surface()->Commit(); + shell_surface->SetFullscreen(true, display::kInvalidDisplayId); + shell_surface->root_surface()->Commit(); + EXPECT_EQ(chromeos::WindowStateType::kFullscreen, config_data.state_type); + EXPECT_EQ(chromeos::WindowStateType::kMaximized, + config_data.restore_state_type.value()); +} + TEST_F(ShellSurfaceTest, ConfigureCallback) { // Must be before shell_surface so it outlives it, for shell_surface's // destructor calls Configure() referencing these 4 variables. @@ -2453,7 +2478,7 @@ shell_surface->set_configure_callback(base::BindLambdaForTesting( [&](const gfx::Rect& bounds, chromeos::WindowStateType state, bool resizing, bool activated, const gfx::Vector2d& origin_offset, - float raster_scale) { + float raster_scale, std::optional<chromeos::WindowStateType>) { configured_state = state; return uint32_t{0}; })); @@ -2671,8 +2696,8 @@ auto configure_callback = base::BindRepeating( [](uint32_t* const serial_ptr, const gfx::Rect& bounds, chromeos::WindowStateType state_type, bool resizing, bool activated, - const gfx::Vector2d& origin_offset, - float raster_scale) { return ++(*serial_ptr); }, + const gfx::Vector2d& origin_offset, float raster_scale, + std::optional<chromeos::WindowStateType>) { return ++(*serial_ptr); }, &serial); ui::test::EventGenerator* event_generator = GetEventGenerator(); @@ -2946,8 +2971,8 @@ auto configure_callback = base::BindRepeating( [](uint32_t* const serial_ptr, const gfx::Rect& bounds, chromeos::WindowStateType state_type, bool resizing, bool activated, - const gfx::Vector2d& origin_offset, - float raster_scale) { return ++(*serial_ptr); }, + const gfx::Vector2d& origin_offset, float raster_scale, + std::optional<chromeos::WindowStateType>) { return ++(*serial_ptr); }, &serial); shell_surface->set_configure_callback(configure_callback); @@ -3390,12 +3415,14 @@ bool activated; }; - uint32_t OnConfigure(const gfx::Rect& bounds, - chromeos::WindowStateType state_type, - bool resizing, - bool activated, - const gfx::Vector2d& origin_offset, - float raster_scale) { + uint32_t OnConfigure( + const gfx::Rect& bounds, + chromeos::WindowStateType state_type, + bool resizing, + bool activated, + const gfx::Vector2d& origin_offset, + float raster_scale, + std::optional<chromeos::WindowStateType> restore_state_type) { configure_state.emplace(); *configure_state = {bounds, state_type, resizing, activated}; return ++serial; @@ -3636,7 +3663,7 @@ auto test_callback = base::BindRepeating( [](chromeos::WindowStateType* state_type, const gfx::Rect&, chromeos::WindowStateType new_type, bool, bool, const gfx::Vector2d&, - float) -> uint32_t { + float, std::optional<chromeos::WindowStateType>) -> uint32_t { *state_type = new_type; return 0; }, @@ -3669,7 +3696,7 @@ auto test_callback = base::BindRepeating( [](int* times_configured, const gfx::Rect&, chromeos::WindowStateType new_type, bool, bool, const gfx::Vector2d&, - float) -> uint32_t { + float, std::optional<chromeos::WindowStateType>) -> uint32_t { ++(*times_configured); return 0; }, @@ -3702,7 +3729,7 @@ auto test_callback = base::BindRepeating( [](int* times_configured, const gfx::Rect&, chromeos::WindowStateType new_type, bool, bool, const gfx::Vector2d&, - float) -> uint32_t { + float, std::optional<chromeos::WindowStateType>) -> uint32_t { ++(*times_configured); return 0; },
diff --git a/components/exo/wayland/server.cc b/components/exo/wayland/server.cc index a13734130..404ba9ae 100644 --- a/components/exo/wayland/server.cc +++ b/components/exo/wayland/server.cc
@@ -40,6 +40,7 @@ #include <utility> #include "ash/constants/ash_features.h" +#include "ash/shell.h" #include "base/command_line.h" #include "base/files/file_path.h" #include "base/files/file_util.h" @@ -261,6 +262,7 @@ wl_display_.reset(wl_display_create()); SetSecurityDelegate(wl_display_.get(), security_delegate_.get()); + display_manager_observation_.Observe(ash::Shell::Get()->display_manager()); client_tracker_ = std::make_unique<ClientTracker>(wl_display_.get()); } @@ -289,9 +291,10 @@ kZAuraOutputManagerVersion, this, bind_aura_output_manager); wl_global_create(wl_display_.get(), &wl_subcompositor_interface, /*version=*/1, display_, bind_subcompositor); - for (const auto& display : display::Screen::GetScreen()->GetAllDisplays()) { - OnDisplayAdded(display); - } + OnDidProcessDisplayChanges( + {ash::Shell::Get()->display_manager()->active_display_list(), + Displays(), + {}}); wl_global_create(wl_display_.get(), &zcr_vsync_feedback_v1_interface, /*version=*/1, display_, bind_vsync_feedback); @@ -498,21 +501,35 @@ wl_display_flush_clients(wl_display_.get()); } -void Server::OnDisplayAdded(const display::Display& new_display) { - auto output = std::make_unique<WaylandDisplayOutput>(new_display.id()); - output->set_global(wl_global_create(wl_display_.get(), &wl_output_interface, - kWlOutputVersion, output.get(), - bind_output)); - DCHECK_EQ(outputs_.count(new_display.id()), 0u); - outputs_.insert(std::make_pair(new_display.id(), std::move(output))); -} +void Server::OnDidProcessDisplayChanges( + const DisplayConfigurationChange& configuration_change) { + // Process added displays before removed displays to ensure exo does not leave + // clients in a temporary state where no outputs are present. + for (const display::Display& added_display : + configuration_change.added_displays) { + auto output = std::make_unique<WaylandDisplayOutput>(added_display.id()); + output->set_global(wl_global_create(wl_display_.get(), &wl_output_interface, + kWlOutputVersion, output.get(), + bind_output)); + CHECK_EQ(outputs_.count(added_display.id()), 0u); + outputs_.insert(std::make_pair(added_display.id(), std::move(output))); + } -void Server::OnDisplayRemoved(const display::Display& old_display) { - DCHECK_EQ(outputs_.count(old_display.id()), 1u); - std::unique_ptr<WaylandDisplayOutput> output = - std::move(outputs_[old_display.id()]); - outputs_.erase(old_display.id()); - output.release()->OnDisplayRemoved(); + for (const display::Display& removed_display : + configuration_change.removed_displays) { + // There should always be at least one display tracked by Exo. + CHECK(outputs_.size() > 1); + CHECK_EQ(outputs_.count(removed_display.id()), 1u); + std::unique_ptr<WaylandDisplayOutput> output = + std::move(outputs_[removed_display.id()]); + outputs_.erase(removed_display.id()); + output.release()->OnDisplayRemoved(); + } + + // Flush updated outputs to clients immediately. + // TODO(crbug.com/1502682): Exo should be updated to automatically flush + // buffers at the end of task processing if necessary. + Flush(); } wl_resource* Server::GetOutputResource(wl_client* client, int64_t display_id) {
diff --git a/components/exo/wayland/server.h b/components/exo/wayland/server.h index 2ba3507..1d280a9 100644 --- a/components/exo/wayland/server.h +++ b/components/exo/wayland/server.h
@@ -14,9 +14,11 @@ #include "base/files/scoped_temp_dir.h" #include "base/functional/callback.h" #include "base/memory/raw_ptr.h" +#include "base/scoped_observation.h" #include "base/time/time.h" #include "components/exo/wayland/scoped_wl.h" -#include "ui/display/display_observer.h" +#include "ui/display/manager/display_manager.h" +#include "ui/display/manager/display_manager_observer.h" struct wl_resource; struct wl_client; @@ -44,7 +46,7 @@ // This class is a thin wrapper around a Wayland display server. All Wayland // requests are dispatched into the given Exosphere display. -class Server : public display::DisplayObserver { +class Server : public display::DisplayManagerObserver { public: using ServerGetter = base::RepeatingCallback<Server*(wl_display*)>; using StartCallback = base::OnceCallback<void(bool)>; @@ -94,9 +96,9 @@ // Send all buffered events to the clients. void Flush(); - // Overridden from display::DisplayObserver: - void OnDisplayAdded(const display::Display& new_display) override; - void OnDisplayRemoved(const display::Display& old_display) override; + // display::DisplayManagerObserver: + void OnDidProcessDisplayChanges( + const DisplayConfigurationChange& configuration_change) override; wl_resource* GetOutputResource(wl_client* client, int64_t display_id); @@ -129,7 +131,6 @@ base::flat_map<int64_t, std::unique_ptr<WaylandDisplayOutput>> outputs_; std::unique_ptr<WaylandDataDeviceManager> data_device_manager_data_; std::unique_ptr<WaylandSeat> seat_data_; - display::ScopedDisplayObserver display_observer_{this}; std::unique_ptr<wayland::WaylandWatcher> wayland_watcher_; std::unique_ptr<WaylandDmabufFeedbackManager> wayland_feedback_manager_; @@ -140,6 +141,10 @@ std::unique_ptr<WaylandRemoteShellData> remote_shell_data_; std::unique_ptr<UiControls> ui_controls_holder_; std::unique_ptr<ClientTracker> client_tracker_; + + base::ScopedObservation<display::DisplayManager, + display::DisplayManagerObserver> + display_manager_observation_{this}; }; } // namespace wayland
diff --git a/components/exo/wayland/wayland_display_output_unittest.cc b/components/exo/wayland/wayland_display_output_unittest.cc index 85d4960..007c5850 100644 --- a/components/exo/wayland/wayland_display_output_unittest.cc +++ b/components/exo/wayland/wayland_display_output_unittest.cc
@@ -124,4 +124,18 @@ WaylandDisplayOutput::kDeleteRetries); } +// Tests to ensure exo processes added displays before removed displays for +// display configuration updates. This ensures exo's clients always see a valid +// Output during such configuration updates. +TEST_F(WaylandDisplayOutputTest, MaintainsNonEmptyOutputList) { + // Start with 2 displays. + UpdateDisplay("300x400,500x600"); + + // Update to a new display configuration. The total global Outputs maintained + // by exo should remain non-zero while processing the change (exo will CHECK + // crash if it enters a zero output state). + UpdateDisplay("700x800,900x1000", /*from_native_platform=*/false, + /*generate_new_ids=*/true); +} + } // namespace exo::wayland
diff --git a/components/exo/wayland/wl_shell.cc b/components/exo/wayland/wl_shell.cc index 0bb22a1..347b91e 100644 --- a/components/exo/wayland/wl_shell.cc +++ b/components/exo/wayland/wl_shell.cc
@@ -134,7 +134,8 @@ bool resizing, bool activated, const gfx::Vector2d& origin_offset, - float raster_scale) { + float raster_scale, + std::optional<chromeos::WindowStateType> restore_state_type) { wl_shell_surface_send_configure(resource, WL_SHELL_SURFACE_RESIZE_NONE, bounds.width(), bounds.height()); wl_client_flush(wl_resource_get_client(resource));
diff --git a/components/exo/wayland/xdg_shell.cc b/components/exo/wayland/xdg_shell.cc index 12f913a..ae02b814 100644 --- a/components/exo/wayland/xdg_shell.cc +++ b/components/exo/wayland/xdg_shell.cc
@@ -8,6 +8,7 @@ #include <wayland-server-protocol-core.h> #include <xdg-decoration-unstable-v1-server-protocol.h> #include <xdg-shell-server-protocol.h> +#include <optional> #include "ash/public/cpp/shell_window_ids.h" #include "ash/public/cpp/window_properties.h" @@ -142,11 +143,12 @@ } } -using XdgSurfaceConfigureCallback = - base::RepeatingCallback<void(const gfx::Size& size, - chromeos::WindowStateType state_type, - bool resizing, - bool activated)>; +using XdgSurfaceConfigureCallback = base::RepeatingCallback<void( + const gfx::Size& size, + chromeos::WindowStateType state_type, + bool resizing, + bool activated, + std::optional<chromeos::WindowStateType> restore_state_type)>; uint32_t HandleXdgSurfaceConfigureCallback( wl_resource* resource, @@ -157,10 +159,12 @@ bool resizing, bool activated, const gfx::Vector2d& origin_offset, - float raster_scale) { + float raster_scale, + std::optional<chromeos::WindowStateType> restore_state_type) { uint32_t serial = serial_tracker->GetNextSerial(SerialTracker::EventType::OTHER_EVENT); - callback.Run(bounds.size(), state_type, resizing, activated); + callback.Run(bounds.size(), state_type, resizing, activated, + restore_state_type); xdg_surface_send_configure(resource, serial); wl_client_flush(wl_resource_get_client(resource)); return serial; @@ -295,10 +299,12 @@ *value = state; } - void OnConfigure(const gfx::Size& size, - chromeos::WindowStateType state_type, - bool resizing, - bool activated) { + void OnConfigure( + const gfx::Size& size, + chromeos::WindowStateType state_type, + bool resizing, + bool activated, + std::optional<chromeos::WindowStateType> restore_state_type) { wl_array states; wl_array_init(&states); if (state_type == chromeos::WindowStateType::kMaximized) @@ -306,6 +312,14 @@ // TODO(crbug/1250129): Pinned states need to be handled properly. if (IsFullscreenOrPinnedWindowStateType(state_type)) { AddState(&states, XDG_TOPLEVEL_STATE_FULLSCREEN); + // If the window was maxmized before it is fullscreened, we should + // keep this state while it is fullscreened. This is what X11 apps, and + // thus standard wayland apps expect, and they may rely on this behavior + // even though this is not explicitly specified in the protocol spec. + if (restore_state_type.has_value() && + restore_state_type.value() == chromeos::WindowStateType::kMaximized) { + AddState(&states, XDG_TOPLEVEL_STATE_MAXIMIZED); + } } if (resizing) AddState(&states, XDG_TOPLEVEL_STATE_RESIZING); @@ -560,10 +574,12 @@ wl_client_flush(wl_resource_get_client(resource_)); } - void OnConfigure(const gfx::Size& size, - chromeos::WindowStateType state_type, - bool resizing, - bool activated) { + void OnConfigure( + const gfx::Size& size, + chromeos::WindowStateType state_type, + bool resizing, + bool activated, + std::optional<chromeos::WindowStateType> restore_state_type) { // Nothing to do here as popups don't have additional configure state. }
diff --git a/components/exo/wayland/zaura_shell.cc b/components/exo/wayland/zaura_shell.cc index a0647fdd..0c9bf7ed 100644 --- a/components/exo/wayland/zaura_shell.cc +++ b/components/exo/wayland/zaura_shell.cc
@@ -746,12 +746,13 @@ return chromeos::OrientationType::kAny; } -using AuraSurfaceConfigureCallback = - base::RepeatingCallback<void(const gfx::Rect& bounds, - chromeos::WindowStateType state_type, - bool resizing, - bool activated, - float raster_scale)>; +using AuraSurfaceConfigureCallback = base::RepeatingCallback<void( + const gfx::Rect& bounds, + chromeos::WindowStateType state_type, + bool resizing, + bool activated, + float raster_scale, + std::optional<chromeos::WindowStateType> restore_state_type)>; uint32_t HandleAuraSurfaceConfigureCallback( wl_resource* resource, @@ -762,10 +763,12 @@ bool resizing, bool activated, const gfx::Vector2d& origin_offset, - float raster_scale) { + float raster_scale, + std::optional<chromeos::WindowStateType> restore_state_type) { uint32_t serial = serial_tracker->GetNextSerial(SerialTracker::EventType::OTHER_EVENT); - callback.Run(bounds, state_type, resizing, activated, raster_scale); + callback.Run(bounds, state_type, resizing, activated, raster_scale, + restore_state_type); xdg_surface_send_configure(resource, serial); wl_client_flush(wl_resource_get_client(resource)); return serial; @@ -1010,11 +1013,13 @@ *value = state; } -void AuraToplevel::OnConfigure(const gfx::Rect& bounds, - chromeos::WindowStateType state_type, - bool resizing, - bool activated, - float raster_scale) { +void AuraToplevel::OnConfigure( + const gfx::Rect& bounds, + chromeos::WindowStateType state_type, + bool resizing, + bool activated, + float raster_scale, + std::optional<chromeos::WindowStateType> restore_state_type) { wl_array states; wl_array_init(&states); if (state_type == chromeos::WindowStateType::kMaximized) @@ -1030,6 +1035,14 @@ // Investigate and fix. AddState(&states, ZAURA_TOPLEVEL_STATE_IMMERSIVE); } + // If the window was maxmized before it is fullscreened, we should + // keep this state while it is fullscreened. This is what X11 apps, and + // thus standard wayland apps expect, and they may rely on this behavior + // even though this is not explicitly specified in the protocol spec. + if (restore_state_type.has_value() && + restore_state_type.value() == chromeos::WindowStateType::kMaximized) { + AddState(&states, XDG_TOPLEVEL_STATE_MAXIMIZED); + } } if (resizing) AddState(&states, XDG_TOPLEVEL_STATE_RESIZING);
diff --git a/components/exo/wayland/zaura_shell.h b/components/exo/wayland/zaura_shell.h index c3ec7f3..a2664477 100644 --- a/components/exo/wayland/zaura_shell.h +++ b/components/exo/wayland/zaura_shell.h
@@ -166,7 +166,8 @@ chromeos::WindowStateType state_type, bool resizing, bool activated, - float raster_scale); + float raster_scale, + std::optional<chromeos::WindowStateType> restore_state_type); virtual void OnOriginChange(const gfx::Point& origin); void OnOverviewChange(bool in_overview); void SetDecoration(SurfaceFrameType type);
diff --git a/components/manta/proto/manta.proto b/components/manta/proto/manta.proto index 579a470..3070b9c 100644 --- a/components/manta/proto/manta.proto +++ b/components/manta/proto/manta.proto
@@ -8,10 +8,9 @@ package manta.proto; enum FeatureName { - reserved 1 to 4; - reserved 6 to 300, 303; + reserved 1 to 299; - IMAGE_TEST = 5; + CHROMEOS_VC_BACKGROUNDS = 300; CHROMEOS_WALLPAPER = 301; TEXT_TEST = 302; }
diff --git a/components/performance_manager/decorators/frame_visibility_decorator.cc b/components/performance_manager/decorators/frame_visibility_decorator.cc index 6f07c4b..d303c10 100644 --- a/components/performance_manager/decorators/frame_visibility_decorator.cc +++ b/components/performance_manager/decorators/frame_visibility_decorator.cc
@@ -137,7 +137,7 @@ PageNodeImpl* page_node_impl = PageNodeImpl::FromNode(page_node); // A page can sometimes have no main frame. - FrameNodeImpl* main_frame_node = page_node_impl->GetMainFrameNodeImpl(); + FrameNodeImpl* main_frame_node = page_node_impl->main_frame_node(); if (!main_frame_node) { return; }
diff --git a/components/performance_manager/decorators/page_load_tracker_decorator.cc b/components/performance_manager/decorators/page_load_tracker_decorator.cc index 4352ae6..a408640 100644 --- a/components/performance_manager/decorators/page_load_tracker_decorator.cc +++ b/components/performance_manager/decorators/page_load_tracker_decorator.cc
@@ -357,7 +357,7 @@ // static bool PageLoadTrackerDecorator::IsIdling(const PageNodeImpl* page_node) { // Get the frame node for the main frame associated with this page. - const FrameNodeImpl* main_frame_node = page_node->GetMainFrameNodeImpl(); + const FrameNodeImpl* main_frame_node = page_node->main_frame_node(); if (!main_frame_node) return false; @@ -373,7 +373,7 @@ // of session restore this is mitigated by having a timeout while waiting for // this signal. return main_frame_node->GetNetworkAlmostIdle() && - process_node->main_thread_task_load_is_low(); + process_node->GetMainThreadTaskLoadIsLow(); } // static
diff --git a/components/performance_manager/decorators/process_hosted_content_types_aggregator_unittest.cc b/components/performance_manager/decorators/process_hosted_content_types_aggregator_unittest.cc index a3ca761..08188f1 100644 --- a/components/performance_manager/decorators/process_hosted_content_types_aggregator_unittest.cc +++ b/components/performance_manager/decorators/process_hosted_content_types_aggregator_unittest.cc
@@ -28,7 +28,7 @@ bool IsHosting(const TestNodeWrapper<ProcessNodeImpl>& process_node, ContentType content_type) { - return process_node->hosted_content_types().Has(content_type); + return process_node->GetHostedContentTypes().Has(content_type); } }; @@ -90,7 +90,7 @@ // Create a main frame in a first process. auto process_node_1 = CreateNode<ProcessNodeImpl>(); - EXPECT_TRUE(process_node_1->hosted_content_types().Empty()); + EXPECT_TRUE(process_node_1->GetHostedContentTypes().Empty()); auto main_frame_node = CreateFrameNodeAutoId(process_node_1.get(), page_node.get()); @@ -103,7 +103,7 @@ // Create a child frame node in another process. auto process_node_2 = CreateNode<ProcessNodeImpl>(); - EXPECT_TRUE(process_node_2->hosted_content_types().Empty()); + EXPECT_TRUE(process_node_2->GetHostedContentTypes().Empty()); auto child_frame_node = CreateFrameNodeAutoId( process_node_2.get(), page_node.get(), main_frame_node.get());
diff --git a/components/performance_manager/decorators/process_priority_aggregator.cc b/components/performance_manager/decorators/process_priority_aggregator.cc index 5b9aa22..0d11409 100644 --- a/components/performance_manager/decorators/process_priority_aggregator.cc +++ b/components/performance_manager/decorators/process_priority_aggregator.cc
@@ -168,7 +168,7 @@ DCHECK(!DataImpl::Get(process_node_impl)); DataImpl* data = DataImpl::GetOrCreate(process_node_impl); DCHECK(data->IsEmpty()); - DCHECK_EQ(base::TaskPriority::LOWEST, process_node_impl->priority()); + DCHECK_EQ(base::TaskPriority::LOWEST, process_node_impl->GetPriority()); DCHECK_EQ(base::TaskPriority::LOWEST, data->GetPriority()); }
diff --git a/components/performance_manager/decorators/process_priority_aggregator_unittest.cc b/components/performance_manager/decorators/process_priority_aggregator_unittest.cc index dae6545..a6e1c76a 100644 --- a/components/performance_manager/decorators/process_priority_aggregator_unittest.cc +++ b/components/performance_manager/decorators/process_priority_aggregator_unittest.cc
@@ -66,24 +66,24 @@ auto& worker1 = mock_graph.worker; auto& worker2 = mock_graph.other_worker; - EXPECT_EQ(base::TaskPriority::LOWEST, proc1->priority()); - EXPECT_EQ(base::TaskPriority::LOWEST, proc2->priority()); + EXPECT_EQ(base::TaskPriority::LOWEST, proc1->GetPriority()); + EXPECT_EQ(base::TaskPriority::LOWEST, proc2->GetPriority()); ExpectPriorityCounts(proc1.get(), 0, 0); ExpectPriorityCounts(proc2.get(), 0, 0); // Set the priority of a frame in process 1 to USER_VISIBLE. frame1_1->SetPriorityAndReason( PriorityAndReason(base::TaskPriority::USER_VISIBLE, kReason)); - EXPECT_EQ(base::TaskPriority::USER_VISIBLE, proc1->priority()); - EXPECT_EQ(base::TaskPriority::LOWEST, proc2->priority()); + EXPECT_EQ(base::TaskPriority::USER_VISIBLE, proc1->GetPriority()); + EXPECT_EQ(base::TaskPriority::LOWEST, proc2->GetPriority()); ExpectPriorityCounts(proc1.get(), 1, 0); ExpectPriorityCounts(proc2.get(), 0, 0); // Set the priority of a frame in process 2 to USER_VISIBLE. frame2_1->SetPriorityAndReason( PriorityAndReason(base::TaskPriority::USER_VISIBLE, kReason)); - EXPECT_EQ(base::TaskPriority::USER_VISIBLE, proc1->priority()); - EXPECT_EQ(base::TaskPriority::USER_VISIBLE, proc2->priority()); + EXPECT_EQ(base::TaskPriority::USER_VISIBLE, proc1->GetPriority()); + EXPECT_EQ(base::TaskPriority::USER_VISIBLE, proc2->GetPriority()); ExpectPriorityCounts(proc1.get(), 1, 0); ExpectPriorityCounts(proc2.get(), 1, 0); @@ -91,8 +91,8 @@ // overwrites the vote from the first frame. frame1_2->SetPriorityAndReason( PriorityAndReason(base::TaskPriority::USER_BLOCKING, kReason)); - EXPECT_EQ(base::TaskPriority::USER_BLOCKING, proc1->priority()); - EXPECT_EQ(base::TaskPriority::USER_VISIBLE, proc2->priority()); + EXPECT_EQ(base::TaskPriority::USER_BLOCKING, proc1->GetPriority()); + EXPECT_EQ(base::TaskPriority::USER_VISIBLE, proc2->GetPriority()); ExpectPriorityCounts(proc1.get(), 1, 1); ExpectPriorityCounts(proc2.get(), 1, 0); @@ -100,8 +100,8 @@ // the vote from the sole frame in this process. worker2->SetPriorityAndReason( PriorityAndReason(base::TaskPriority::USER_BLOCKING, kReason)); - EXPECT_EQ(base::TaskPriority::USER_BLOCKING, proc1->priority()); - EXPECT_EQ(base::TaskPriority::USER_BLOCKING, proc2->priority()); + EXPECT_EQ(base::TaskPriority::USER_BLOCKING, proc1->GetPriority()); + EXPECT_EQ(base::TaskPriority::USER_BLOCKING, proc2->GetPriority()); ExpectPriorityCounts(proc1.get(), 1, 1); ExpectPriorityCounts(proc2.get(), 1, 1); @@ -109,8 +109,8 @@ // both frames in this process are at USER_VISIBLE. frame1_2->SetPriorityAndReason( PriorityAndReason(base::TaskPriority::USER_VISIBLE, kReason)); - EXPECT_EQ(base::TaskPriority::USER_VISIBLE, proc1->priority()); - EXPECT_EQ(base::TaskPriority::USER_BLOCKING, proc2->priority()); + EXPECT_EQ(base::TaskPriority::USER_VISIBLE, proc1->GetPriority()); + EXPECT_EQ(base::TaskPriority::USER_BLOCKING, proc2->GetPriority()); ExpectPriorityCounts(proc1.get(), 2, 0); ExpectPriorityCounts(proc2.get(), 1, 1); @@ -118,8 +118,8 @@ // execution context priority of that process is now due to the sole frame. worker2->SetPriorityAndReason( PriorityAndReason(base::TaskPriority::LOWEST, kReason)); - EXPECT_EQ(base::TaskPriority::USER_VISIBLE, proc1->priority()); - EXPECT_EQ(base::TaskPriority::USER_VISIBLE, proc2->priority()); + EXPECT_EQ(base::TaskPriority::USER_VISIBLE, proc1->GetPriority()); + EXPECT_EQ(base::TaskPriority::USER_VISIBLE, proc2->GetPriority()); ExpectPriorityCounts(proc1.get(), 2, 0); ExpectPriorityCounts(proc2.get(), 1, 0); @@ -127,8 +127,8 @@ // execution contexts in this process are now at LOWEST. frame2_1->SetPriorityAndReason( PriorityAndReason(base::TaskPriority::LOWEST, kReason)); - EXPECT_EQ(base::TaskPriority::USER_VISIBLE, proc1->priority()); - EXPECT_EQ(base::TaskPriority::LOWEST, proc2->priority()); + EXPECT_EQ(base::TaskPriority::USER_VISIBLE, proc1->GetPriority()); + EXPECT_EQ(base::TaskPriority::LOWEST, proc2->GetPriority()); ExpectPriorityCounts(proc1.get(), 2, 0); ExpectPriorityCounts(proc2.get(), 0, 0); @@ -136,8 +136,8 @@ // execution priority of that process is now due to the second frame. frame1_1->SetPriorityAndReason( PriorityAndReason(base::TaskPriority::LOWEST, kReason)); - EXPECT_EQ(base::TaskPriority::USER_VISIBLE, proc1->priority()); - EXPECT_EQ(base::TaskPriority::LOWEST, proc2->priority()); + EXPECT_EQ(base::TaskPriority::USER_VISIBLE, proc1->GetPriority()); + EXPECT_EQ(base::TaskPriority::LOWEST, proc2->GetPriority()); ExpectPriorityCounts(proc1.get(), 1, 0); ExpectPriorityCounts(proc2.get(), 0, 0); @@ -145,8 +145,8 @@ // execution contexts in this process are now at LOWEST. frame1_2->SetPriorityAndReason( PriorityAndReason(base::TaskPriority::LOWEST, kReason)); - EXPECT_EQ(base::TaskPriority::LOWEST, proc1->priority()); - EXPECT_EQ(base::TaskPriority::LOWEST, proc2->priority()); + EXPECT_EQ(base::TaskPriority::LOWEST, proc1->GetPriority()); + EXPECT_EQ(base::TaskPriority::LOWEST, proc2->GetPriority()); ExpectPriorityCounts(proc1.get(), 0, 0); ExpectPriorityCounts(proc2.get(), 0, 0); @@ -154,8 +154,8 @@ // with the highest priority and thus dictates the priority of this process. worker1->SetPriorityAndReason( PriorityAndReason(base::TaskPriority::USER_VISIBLE, kReason)); - EXPECT_EQ(base::TaskPriority::USER_VISIBLE, proc1->priority()); - EXPECT_EQ(base::TaskPriority::LOWEST, proc2->priority()); + EXPECT_EQ(base::TaskPriority::USER_VISIBLE, proc1->GetPriority()); + EXPECT_EQ(base::TaskPriority::LOWEST, proc2->GetPriority()); ExpectPriorityCounts(proc1.get(), 1, 0); ExpectPriorityCounts(proc2.get(), 0, 0); @@ -163,8 +163,8 @@ // contexts in this process are now at LOWEST. worker1->SetPriorityAndReason( PriorityAndReason(base::TaskPriority::LOWEST, kReason)); - EXPECT_EQ(base::TaskPriority::LOWEST, proc1->priority()); - EXPECT_EQ(base::TaskPriority::LOWEST, proc2->priority()); + EXPECT_EQ(base::TaskPriority::LOWEST, proc1->GetPriority()); + EXPECT_EQ(base::TaskPriority::LOWEST, proc2->GetPriority()); ExpectPriorityCounts(proc1.get(), 0, 0); ExpectPriorityCounts(proc2.get(), 0, 0); }
diff --git a/components/performance_manager/graph/frame_node_impl.cc b/components/performance_manager/graph/frame_node_impl.cc index 7aae44f..57cde76 100644 --- a/components/performance_manager/graph/frame_node_impl.cc +++ b/components/performance_manager/graph/frame_node_impl.cc
@@ -42,9 +42,7 @@ browsing_instance_id_(browsing_instance_id), site_instance_id_(site_instance_id), render_frame_host_proxy_(content::GlobalRenderFrameHostId( - process_node->render_process_host_proxy() - .render_process_host_id() - .value(), + process_node->GetRenderProcessHostId().value(), render_frame_id)) { // Nodes are created on the UI thread, then accessed on the PM sequence. // `weak_this_` can be returned from GetWeakPtrOnUIThread() and dereferenced @@ -666,7 +664,7 @@ DCHECK(GetWeakPtr().get()); // Enable querying this node using process and frame routing ids. - graph()->RegisterFrameNodeForId(process_node_->GetRenderProcessId(), + graph()->RegisterFrameNodeForId(process_node_->GetRenderProcessHostId(), render_frame_id_, this); // Notify the initializing observers. @@ -704,7 +702,7 @@ graph()->NotifyFrameNodeTearingDown(this); // Disable querying this node using process and frame routing ids. - graph()->UnregisterFrameNodeForId(process_node_->GetRenderProcessId(), + graph()->UnregisterFrameNodeForId(process_node_->GetRenderProcessHostId(), render_frame_id_, this); }
diff --git a/components/performance_manager/graph/frame_node_impl_unittest.cc b/components/performance_manager/graph/frame_node_impl_unittest.cc index 3327eef..71d161a 100644 --- a/components/performance_manager/graph/frame_node_impl_unittest.cc +++ b/components/performance_manager/graph/frame_node_impl_unittest.cc
@@ -78,13 +78,13 @@ auto frame_a2 = CreateFrameNodeAutoId(process_a.get(), page.get()); auto frame_b1 = CreateFrameNodeAutoId(process_b.get(), page.get()); - EXPECT_EQ(graph()->GetFrameNodeById(process_a->GetRenderProcessId(), + EXPECT_EQ(graph()->GetFrameNodeById(process_a->GetRenderProcessHostId(), frame_a1->render_frame_id()), frame_a1.get()); - EXPECT_EQ(graph()->GetFrameNodeById(process_a->GetRenderProcessId(), + EXPECT_EQ(graph()->GetFrameNodeById(process_a->GetRenderProcessHostId(), frame_a2->render_frame_id()), frame_a2.get()); - EXPECT_EQ(graph()->GetFrameNodeById(process_b->GetRenderProcessId(), + EXPECT_EQ(graph()->GetFrameNodeById(process_b->GetRenderProcessHostId(), frame_b1->render_frame_id()), frame_b1.get()); }
diff --git a/components/performance_manager/graph/page_node_impl.cc b/components/performance_manager/graph/page_node_impl.cc index be8c576..ae272a3 100644 --- a/components/performance_manager/graph/page_node_impl.cc +++ b/components/performance_manager/graph/page_node_impl.cc
@@ -197,10 +197,10 @@ uint64_t PageNodeImpl::EstimateMainFramePrivateFootprintSize() const { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); uint64_t total = 0; - FrameNodeImpl* main_frame_node = GetMainFrameNodeImpl(); - if (main_frame_node) { + FrameNodeImpl* main_frame = main_frame_node(); + if (main_frame) { performance_manager::GraphImplOperations::VisitFrameAndChildrenPreOrder( - main_frame_node, [&total](FrameNodeImpl* frame_node) { + main_frame, [&total](FrameNodeImpl* frame_node) { total += frame_node->GetPrivateFootprintKbEstimate(); return true; }); @@ -389,7 +389,18 @@ observer->OnMainFrameDocumentChanged(this); } -FrameNodeImpl* PageNodeImpl::GetMainFrameNodeImpl() const { +FrameNodeImpl* PageNodeImpl::opener_frame_node() const { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + return opener_frame_node_; +} + +FrameNodeImpl* PageNodeImpl::embedder_frame_node() const { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(embedder_frame_node_ || embedding_type_ == EmbeddingType::kInvalid); + return embedder_frame_node_; +} + +FrameNodeImpl* PageNodeImpl::main_frame_node() const { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (main_frame_nodes_.empty()) return nullptr; @@ -406,17 +417,6 @@ return *main_frame_nodes_.begin(); } -FrameNodeImpl* PageNodeImpl::opener_frame_node() const { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - return opener_frame_node_; -} - -FrameNodeImpl* PageNodeImpl::embedder_frame_node() const { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - DCHECK(embedder_frame_node_ || embedding_type_ == EmbeddingType::kInvalid); - return embedder_frame_node_; -} - PageNode::LoadingState PageNodeImpl::loading_state() const { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); return loading_state_.value(); @@ -614,7 +614,7 @@ } const FrameNode* PageNodeImpl::GetMainFrameNode() const { - return GetMainFrameNodeImpl(); + return main_frame_node(); } bool PageNodeImpl::VisitMainFrameNodes(const FrameNodeVisitor& visitor) const {
diff --git a/components/performance_manager/graph/page_node_impl.h b/components/performance_manager/graph/page_node_impl.h index 205a68fe..097ff87 100644 --- a/components/performance_manager/graph/page_node_impl.h +++ b/components/performance_manager/graph/page_node_impl.h
@@ -129,14 +129,10 @@ const GURL& url, const std::string& contents_mime_type); - // Returns the current main frame node (if there is one), otherwise returns - // any of the potentially multiple main frames that currently exist. If there - // are no main frames at the moment, returns nullptr. - FrameNodeImpl* GetMainFrameNodeImpl() const; - // Accessors. FrameNodeImpl* opener_frame_node() const; FrameNodeImpl* embedder_frame_node() const; + FrameNodeImpl* main_frame_node() const; LoadingState loading_state() const; ukm::SourceId ukm_source_id() const; LifecycleState lifecycle_state() const;
diff --git a/components/performance_manager/graph/policies/process_priority_policy_unittest.cc b/components/performance_manager/graph/policies/process_priority_policy_unittest.cc index 47782e16..6df12dbd8 100644 --- a/components/performance_manager/graph/policies/process_priority_policy_unittest.cc +++ b/components/performance_manager/graph/policies/process_priority_policy_unittest.cc
@@ -45,7 +45,7 @@ PerformanceManager::CallOnGraph( FROM_HERE, base::BindLambdaForTesting([process_node]() { process_node->set_priority( - GetOppositePriority(process_node->priority())); + GetOppositePriority(process_node->GetPriority())); })); }
diff --git a/components/performance_manager/graph/process_node_impl.cc b/components/performance_manager/graph/process_node_impl.cc index 3921ffc3..7afda651 100644 --- a/components/performance_manager/graph/process_node_impl.cc +++ b/components/performance_manager/graph/process_node_impl.cc
@@ -198,12 +198,13 @@ const std::string& ProcessNodeImpl::GetMetricsName() const { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - return metrics_name(); + return metrics_name_; } bool ProcessNodeImpl::GetMainThreadTaskLoadIsLow() const { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - return main_thread_task_load_is_low(); + DCHECK_EQ(process_type_, content::PROCESS_TYPE_RENDERER); + return main_thread_task_load_is_low_.value(); } uint64_t ProcessNodeImpl::GetPrivateFootprintKb() const { @@ -217,15 +218,13 @@ } RenderProcessHostId ProcessNodeImpl::GetRenderProcessHostId() const { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - return GetRenderProcessId(); + return GetRenderProcessHostProxy().render_process_host_id(); } const RenderProcessHostProxy& ProcessNodeImpl::GetRenderProcessHostProxy() const { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_EQ(process_type_, content::PROCESS_TYPE_RENDERER); - return render_process_host_proxy(); + return absl::get<RenderProcessHostProxy>(child_process_host_proxy_); } const BrowserChildProcessHostProxy& @@ -233,18 +232,30 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_NE(process_type_, content::PROCESS_TYPE_BROWSER); DCHECK_NE(process_type_, content::PROCESS_TYPE_RENDERER); - return browser_child_process_host_proxy(); + return absl::get<BrowserChildProcessHostProxy>(child_process_host_proxy_); } base::TaskPriority ProcessNodeImpl::GetPriority() const { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - return priority(); + return priority_.value(); } ProcessNode::ContentTypes ProcessNodeImpl::GetHostedContentTypes() const { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_EQ(process_type_, content::PROCESS_TYPE_RENDERER); - return hosted_content_types(); + return hosted_content_types_; +} + +const base::flat_set<FrameNodeImpl*>& ProcessNodeImpl::frame_nodes() const { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK_EQ(process_type_, content::PROCESS_TYPE_RENDERER); + return frame_nodes_; +} + +const base::flat_set<WorkerNodeImpl*>& ProcessNodeImpl::worker_nodes() const { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK_EQ(process_type_, content::PROCESS_TYPE_RENDERER); + return worker_nodes_; } void ProcessNodeImpl::SetProcessExitStatus(int32_t exit_status) { @@ -278,37 +289,6 @@ SetProcessImpl(std::move(process), pid, launch_time); } -const base::flat_set<FrameNodeImpl*>& ProcessNodeImpl::frame_nodes() const { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - DCHECK_EQ(process_type_, content::PROCESS_TYPE_RENDERER); - return frame_nodes_; -} - -const base::flat_set<WorkerNodeImpl*>& ProcessNodeImpl::worker_nodes() const { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - DCHECK_EQ(process_type_, content::PROCESS_TYPE_RENDERER); - return worker_nodes_; -} - -PageNodeImpl* ProcessNodeImpl::GetPageNodeIfExclusive() const { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - DCHECK_EQ(process_type_, content::PROCESS_TYPE_RENDERER); - - PageNodeImpl* page_node = nullptr; - for (auto* frame_node : frame_nodes_) { - if (!page_node) - page_node = frame_node->page_node(); - if (page_node != frame_node->page_node()) - return nullptr; - } - return page_node; -} - -RenderProcessHostId ProcessNodeImpl::GetRenderProcessId() const { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - return render_process_host_proxy().render_process_host_id(); -} - void ProcessNodeImpl::AddFrame(FrameNodeImpl* frame_node) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_EQ(process_type_, content::PROCESS_TYPE_RENDERER);
diff --git a/components/performance_manager/graph/process_node_impl.h b/components/performance_manager/graph/process_node_impl.h index 41b391d4..f16ebcd 100644 --- a/components/performance_manager/graph/process_node_impl.h +++ b/components/performance_manager/graph/process_node_impl.h
@@ -111,11 +111,14 @@ base::TaskPriority GetPriority() const override; ContentTypes GetHostedContentTypes() const override; + // Private implementation properties. + const base::flat_set<FrameNodeImpl*>& frame_nodes() const; + const base::flat_set<WorkerNodeImpl*>& worker_nodes() const; + void SetProcessExitStatus(int32_t exit_status); void SetProcessMetricsName(const std::string& metrics_name); void SetProcess(base::Process process, base::TimeTicks launch_time); - // Private implementation properties. void set_private_footprint_kb(uint64_t private_footprint_kb) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); private_footprint_kb_ = private_footprint_kb; @@ -125,50 +128,6 @@ resident_set_kb_ = resident_set_kb; } - const base::flat_set<FrameNodeImpl*>& frame_nodes() const; - const base::flat_set<WorkerNodeImpl*>& worker_nodes() const; - - // Returns the render process id (equivalent to RenderProcessHost::GetID()), - // or ChildProcessHost::kInvalidUniqueID if this is not a renderer. - RenderProcessHostId GetRenderProcessId() const; - - // If this process is associated with only one page, returns that page. - // Otherwise, returns nullptr. - PageNodeImpl* GetPageNodeIfExclusive() const; - - const std::string& metrics_name() const { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - return metrics_name_; - } - - bool main_thread_task_load_is_low() const { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - DCHECK_EQ(process_type_, content::PROCESS_TYPE_RENDERER); - return main_thread_task_load_is_low_.value(); - } - - const RenderProcessHostProxy& render_process_host_proxy() const { - DCHECK_EQ(process_type_, content::PROCESS_TYPE_RENDERER); - return absl::get<RenderProcessHostProxy>(child_process_host_proxy_); - } - - const BrowserChildProcessHostProxy& browser_child_process_host_proxy() const { - DCHECK_NE(process_type_, content::PROCESS_TYPE_BROWSER); - DCHECK_NE(process_type_, content::PROCESS_TYPE_RENDERER); - return absl::get<BrowserChildProcessHostProxy>(child_process_host_proxy_); - } - - base::TaskPriority priority() const { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - return priority_.value(); - } - - ContentTypes hosted_content_types() const { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - DCHECK_EQ(process_type_, content::PROCESS_TYPE_RENDERER); - return hosted_content_types_; - } - // Add |frame_node| to this process. void AddFrame(FrameNodeImpl* frame_node); // Removes |frame_node| from the set of frames hosted by this process. Invoked
diff --git a/components/performance_manager/graph/process_node_impl_describer.cc b/components/performance_manager/graph/process_node_impl_describer.cc index a4899f4..b600c634 100644 --- a/components/performance_manager/graph/process_node_impl_describer.cc +++ b/components/performance_manager/graph/process_node_impl_describer.cc
@@ -166,11 +166,11 @@ ret.Set("exit_status", impl->GetExitStatus().value()); } - if (!impl->metrics_name().empty()) { - ret.Set("metrics_name", impl->metrics_name()); + if (!impl->GetMetricsName().empty()) { + ret.Set("metrics_name", impl->GetMetricsName()); } - ret.Set("priority", base::TaskPriorityToString(impl->priority())); + ret.Set("priority", base::TaskPriorityToString(impl->GetPriority())); if (impl->GetPrivateFootprintKb()) { ret.Set("private_footprint_kb", @@ -193,17 +193,16 @@ if (impl->GetProcessType() == content::PROCESS_TYPE_RENDERER) { // Renderer-only properties. - ret.Set("render_process_id", impl->GetRenderProcessId().value()); + ret.Set("render_process_id", impl->GetRenderProcessHostId().value()); - ret.Set("main_thread_task_load_is_low", - impl->main_thread_task_load_is_low()); + ret.Set("main_thread_task_load_is_low", impl->GetMainThreadTaskLoadIsLow()); ret.Set("hosted_content_types", - HostedProcessTypesToString(impl->hosted_content_types())); + HostedProcessTypesToString(impl->GetHostedContentTypes())); } else if (impl->GetProcessType() != content::PROCESS_TYPE_BROWSER) { // Non-renderer child process properties. ret.Set("browser_child_process_host_id", - impl->browser_child_process_host_proxy() + impl->GetBrowserChildProcessHostProxy() .browser_child_process_host_id() .value()); }
diff --git a/components/performance_manager/graph/process_node_impl_unittest.cc b/components/performance_manager/graph/process_node_impl_unittest.cc index 137bd98..65c0530a6 100644 --- a/components/performance_manager/graph/process_node_impl_unittest.cc +++ b/components/performance_manager/graph/process_node_impl_unittest.cc
@@ -92,30 +92,6 @@ EXPECT_EQ(0U, process_node->GetResidentSetKb()); } -TEST_F(ProcessNodeImplTest, GetPageNodeIfExclusive) { - { - MockSinglePageInSingleProcessGraph g(graph()); - EXPECT_EQ(g.page.get(), g.process.get()->GetPageNodeIfExclusive()); - } - - { - MockSinglePageWithMultipleProcessesGraph g(graph()); - EXPECT_EQ(g.page.get(), g.process.get()->GetPageNodeIfExclusive()); - } - - { - MockMultiplePagesInSingleProcessGraph g(graph()); - EXPECT_FALSE(g.process.get()->GetPageNodeIfExclusive()); - } - - { - MockMultiplePagesWithMultipleProcessesGraph g(graph()); - EXPECT_FALSE(g.process.get()->GetPageNodeIfExclusive()); - EXPECT_EQ(g.other_page.get(), - g.other_process.get()->GetPageNodeIfExclusive()); - } -} - namespace { class LenientMockObserver : public ProcessNodeImpl::Observer { @@ -177,7 +153,7 @@ EXPECT_EQ(raw_process_node, obs.TakeNotifiedProcessNode()); // This call does nothing as the priority is always at LOWEST. - EXPECT_EQ(base::TaskPriority::LOWEST, process_node->priority()); + EXPECT_EQ(base::TaskPriority::LOWEST, process_node->GetPriority()); process_node->set_priority(base::TaskPriority::LOWEST); // This call should fire a notification. @@ -239,14 +215,16 @@ auto child_frame_node = CreateFrameNodeAutoId( process_node.get(), page_node.get(), main_frame_node.get()); - // Simply test that the public interface impls yield the same result as their - // private counterpart. const std::string kMetricsName("TestUtilityProcess"); process_node->SetProcessMetricsName(kMetricsName); - EXPECT_EQ(process_node->metrics_name(), kMetricsName); - EXPECT_EQ(process_node->metrics_name(), - public_process_node->GetMetricsName()); + EXPECT_EQ(process_node->GetMetricsName(), kMetricsName); + + process_node->SetMainThreadTaskLoadIsLow(true); + EXPECT_TRUE(process_node->GetMainThreadTaskLoadIsLow()); + + // For properties returning nodes, simply test that the public interface impls + // yield the same result as their private counterpart. const auto& frame_nodes = process_node->frame_nodes(); auto public_frame_nodes = public_process_node->GetFrameNodes(); @@ -263,10 +241,6 @@ return true; }); EXPECT_EQ(public_frame_nodes, visited_frame_nodes); - - process_node->SetMainThreadTaskLoadIsLow(true); - EXPECT_EQ(process_node->main_thread_task_load_is_low(), - public_process_node->GetMainThreadTaskLoadIsLow()); } namespace {
diff --git a/components/performance_manager/graph/worker_node_impl.cc b/components/performance_manager/graph/worker_node_impl.cc index 364afd95..da4346d 100644 --- a/components/performance_manager/graph/worker_node_impl.cc +++ b/components/performance_manager/graph/worker_node_impl.cc
@@ -44,12 +44,12 @@ WorkerNode::WorkerType WorkerNodeImpl::GetWorkerType() const { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - return worker_type(); + return worker_type_; } const std::string& WorkerNodeImpl::GetBrowserContextID() const { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - return browser_context_id(); + return browser_context_id_; } const blink::WorkerToken& WorkerNodeImpl::GetWorkerToken() const { @@ -112,7 +112,7 @@ case WorkerType::kDedicated: // Nested dedicated workers are only available from other dedicated // workers in Chrome. - DCHECK_EQ(worker_node->worker_type(), WorkerType::kDedicated); + DCHECK_EQ(worker_node->GetWorkerType(), WorkerType::kDedicated); break; case WorkerType::kShared: // Nested shared workers are not available in Chrome. @@ -120,7 +120,7 @@ break; case WorkerType::kService: // A service worker may not control another service worker. - DCHECK_NE(worker_node->worker_type(), WorkerType::kService); + DCHECK_NE(worker_node->GetWorkerType(), WorkerType::kService); break; } @@ -170,16 +170,6 @@ observer->OnFinalResponseURLDetermined(this); } -const std::string& WorkerNodeImpl::browser_context_id() const { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - return browser_context_id_; -} - -WorkerNode::WorkerType WorkerNodeImpl::worker_type() const { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - return worker_type_; -} - ProcessNodeImpl* WorkerNodeImpl::process_node() const { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); return process_node_;
diff --git a/components/performance_manager/graph/worker_node_impl.h b/components/performance_manager/graph/worker_node_impl.h index 0210afd1..8ea3f6f 100644 --- a/components/performance_manager/graph/worker_node_impl.h +++ b/components/performance_manager/graph/worker_node_impl.h
@@ -71,8 +71,6 @@ void OnFinalResponseURLDetermined(const GURL& url); // Getters for const properties. - const std::string& browser_context_id() const; - WorkerType worker_type() const; ProcessNodeImpl* process_node() const; // Getters for non-const properties. These are not thread safe.
diff --git a/components/performance_manager/graph/worker_node_impl_describer.cc b/components/performance_manager/graph/worker_node_impl_describer.cc index e77de24b..99fa33a 100644 --- a/components/performance_manager/graph/worker_node_impl_describer.cc +++ b/components/performance_manager/graph/worker_node_impl_describer.cc
@@ -47,8 +47,8 @@ return base::Value::Dict(); base::Value::Dict ret; - ret.Set("worker_type", WorkerTypeToString(impl->worker_type())); - ret.Set("browser_context_id", impl->browser_context_id()); + ret.Set("worker_type", WorkerTypeToString(impl->GetWorkerType())); + ret.Set("browser_context_id", impl->GetBrowserContextID()); ret.Set("worker_token", impl->GetWorkerToken().ToString()); ret.Set("resource_context", impl->GetResourceContext().ToString()); ret.Set("url", impl->GetURL().spec());
diff --git a/components/performance_manager/graph/worker_node_impl_unittest.cc b/components/performance_manager/graph/worker_node_impl_unittest.cc index 30bf898..65261e3 100644 --- a/components/performance_manager/graph/worker_node_impl_unittest.cc +++ b/components/performance_manager/graph/worker_node_impl_unittest.cc
@@ -54,8 +54,6 @@ kWorkerType, process.get(), kTestBrowserContextId, kTestWorkerToken); // Test private interface. - EXPECT_EQ(worker_impl->browser_context_id(), kTestBrowserContextId); - EXPECT_EQ(worker_impl->worker_type(), kWorkerType); EXPECT_EQ(worker_impl->process_node(), process.get()); // Test public interface.
diff --git a/components/performance_manager/performance_manager_tab_helper_unittest.cc b/components/performance_manager/performance_manager_tab_helper_unittest.cc index dd75b01..4755073 100644 --- a/components/performance_manager/performance_manager_tab_helper_unittest.cc +++ b/components/performance_manager/performance_manager_tab_helper_unittest.cc
@@ -125,7 +125,7 @@ EXPECT_EQ(4u, GraphImplOperations::GetFrameNodes(page).size()); ASSERT_EQ(1u, page->main_frame_nodes().size()); - auto* main_frame = page->GetMainFrameNodeImpl(); + auto* main_frame = page->main_frame_node(); EXPECT_EQ(kParentUrl, main_frame->GetURL().spec()); EXPECT_EQ(2u, main_frame->child_frame_nodes().size());
diff --git a/components/performance_manager/public/resource_attribution/queries.h b/components/performance_manager/public/resource_attribution/queries.h index 3d5c590..70fa5eb 100644 --- a/components/performance_manager/public/resource_attribution/queries.h +++ b/components/performance_manager/public/resource_attribution/queries.h
@@ -7,10 +7,12 @@ #include <memory> +#include "base/functional/callback_forward.h" #include "base/gtest_prod_util.h" #include "base/memory/scoped_refptr.h" #include "base/observer_list_threadsafe.h" #include "base/sequence_checker.h" +#include "base/task/sequenced_task_runner.h" #include "base/types/pass_key.h" #include "base/types/variant_util.h" #include "components/performance_manager/public/resource_attribution/query_results.h" @@ -37,7 +39,8 @@ // Repeatedly makes resource attribution queries on a schedule as long as it's // in scope. // TODO(crbug.com/1471683): Unfinished. This registers on create and delete, -// which may have important side effects, but doesn't make any queries yet. +// which may have important side effects, but doesn't make scheduled queries +// yet. Use QueryOnce for now. class ScopedResourceUsageQuery { public: ~ScopedResourceUsageQuery(); @@ -56,6 +59,17 @@ // AddObserver(). void RemoveObserver(QueryResultObserver* observer); + // Starts sending scheduled queries. They will repeat as long as the + // ScopedResourceUsageQuery object exists. This must be called on the sequence + // the object was created on. + // TODO(crbug.com/1471683): Implement this. + void Start(); + + // Sends an immediate query, in addition to the schedule of repeated queries + // triggered by Start(). This must be called on the sequence the + // ScopedResourceUsageQuery object was created on. + void QueryOnce(); + // Restricted implementation methods: // Gives tests access to validate the implementation. @@ -71,8 +85,11 @@ QueryResultObserver, base::RemoveObserverPolicy::kAddingSequenceOnly>; - FRIEND_TEST_ALL_PREFIXES(ResourceAttrScopedQueryTest, Movable); - FRIEND_TEST_ALL_PREFIXES(ResourceAttrScopedQueryTest, Observers); + FRIEND_TEST_ALL_PREFIXES(ResourceAttrQueriesPMTest, ScopedQueryIsMovable); + + // Notifies `observer_list` that `results` were received. + static void NotifyObservers(scoped_refptr<ObserverList> observer_list, + const QueryResultMap& results); SEQUENCE_CHECKER(sequence_checker_); @@ -87,7 +104,12 @@ // Creates a query to request resource usage measurements on a schedule. // // Use CreateScopedQuery() to return an object that makes repeated measurements -// as long as it's in scope, or QueryOnce() to take a single measurement. +// as long as it's in scope, or QueryOnce() to take a single measurement. Before +// calling either of these, the query must specify: +// +// * At least one resource type to measure, with AddResourceType(). +// * At least one resource context to attribute the measurements to, with +// AddResourceContext() or AddAllContextsOfType(). // // Example usage: // @@ -99,9 +121,6 @@ // // QueryBuilder is move-only to prevent accidentally copying large state. Use // Clone() to make an explicit copy. -// -// TODO(crbug.com/1471683): Unfinished. This collects parameters but doesn't -// make any queries yet. class QueryBuilder { public: QueryBuilder(); @@ -136,6 +155,15 @@ // invalid. ScopedResourceUsageQuery CreateScopedQuery(); + // Runs the query and calls `callback` with the result. `callback` will be + // invoked on `task_runner`. Once this is called the QueryBuilder becomes + // invalid. + // TODO(crbug.com/1471683): This takes an immediate measurement. Implement + // more notification schedules. + void QueryOnce(base::OnceCallback<void(const QueryResultMap&)> callback, + scoped_refptr<base::TaskRunner> task_runner = + base::SequencedTaskRunner::GetCurrentDefault()); + // Makes a copy of the QueryBuilder to use as a base for similar queries. QueryBuilder Clone() const; @@ -151,6 +179,9 @@ // Implementation of AddAllContextsOfType(). QueryBuilder& AddAllContextsWithTypeIndex(size_t index); + // Asserts all members needed for QueryOnce() or CreateScopedQuery() are set. + void ValidateQuery() const; + SEQUENCE_CHECKER(sequence_checker_); // Parameters built up by the builder.
diff --git a/components/performance_manager/public/resource_attribution/scoped_cpu_query.h b/components/performance_manager/public/resource_attribution/scoped_cpu_query.h index 5ac7dbc5..158e952 100644 --- a/components/performance_manager/public/resource_attribution/scoped_cpu_query.h +++ b/components/performance_manager/public/resource_attribution/scoped_cpu_query.h
@@ -5,46 +5,42 @@ #ifndef COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_RESOURCE_ATTRIBUTION_SCOPED_CPU_QUERY_H_ #define COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_RESOURCE_ATTRIBUTION_SCOPED_CPU_QUERY_H_ +#include <vector> + #include "base/functional/callback_forward.h" -#include "base/memory/scoped_refptr.h" -#include "base/memory/weak_ptr.h" -#include "base/task/sequenced_task_runner.h" +#include "base/sequence_checker.h" +#include "components/performance_manager/public/resource_attribution/queries.h" #include "components/performance_manager/public/resource_attribution/query_results.h" -namespace base { -class TaskRunner; -} - -namespace performance_manager { -class Graph; -} - namespace performance_manager::resource_attribution { -class QueryScheduler; - // A temporary public interface to request CPU measurements. As soon as a // ScopedCPUQuery instance is created, CPUMeasurementMonitor will begin // monitoring CPU usage. When no more instances exist, it will stop. // // TODO(crbug.com/1471683): Replace this with the full Resource Attribution // query API described in bit.ly/resource-attribution-api. -class ScopedCPUQuery { +class ScopedCPUQuery final : public QueryResultObserver { public: - explicit ScopedCPUQuery(Graph* graph); - ~ScopedCPUQuery(); + using ResultCallback = base::OnceCallback<void(const QueryResultMap&)>; + + ScopedCPUQuery(); + ~ScopedCPUQuery() final; ScopedCPUQuery(const ScopedCPUQuery&) = delete; ScopedCPUQuery& operator=(const ScopedCPUQuery&) = delete; - // Requests the current CPU measurements to be passed to `callback` on - // `task_runner`. - void QueryOnce(base::OnceCallback<void(const QueryResultMap&)> callback, - scoped_refptr<base::TaskRunner> task_runner = - base::SequencedTaskRunner::GetCurrentDefault()); + // Requests the current CPU measurements to be passed to `callback`. + void QueryOnce(ResultCallback callback); + + // QueryResultObserver: + void OnResourceUsageUpdated(const QueryResultMap& results) final; private: - base::WeakPtr<QueryScheduler> scheduler_; + SEQUENCE_CHECKER(sequence_checker_); + + ScopedResourceUsageQuery wrapped_query_ GUARDED_BY_CONTEXT(sequence_checker_); + std::vector<ResultCallback> callbacks_ GUARDED_BY_CONTEXT(sequence_checker_); }; } // namespace performance_manager::resource_attribution
diff --git a/components/performance_manager/resource_attribution/frame_context.cc b/components/performance_manager/resource_attribution/frame_context.cc index 23158098..19d39ce 100644 --- a/components/performance_manager/resource_attribution/frame_context.cc +++ b/components/performance_manager/resource_attribution/frame_context.cc
@@ -90,7 +90,7 @@ auto* node_impl = FrameNodeImpl::FromNode(node); CHECK(node_impl->process_node()); content::GlobalRenderFrameHostId global_id( - node_impl->process_node()->GetRenderProcessId().GetUnsafeValue(), + node_impl->process_node()->GetRenderProcessHostId().GetUnsafeValue(), node_impl->render_frame_id()); CHECK(IsValidId(global_id)); return FrameContext(global_id, node_impl->GetWeakPtr());
diff --git a/components/performance_manager/resource_attribution/graph_change.h b/components/performance_manager/resource_attribution/graph_change.h index 331250e9..48426cd 100644 --- a/components/performance_manager/resource_attribution/graph_change.h +++ b/components/performance_manager/resource_attribution/graph_change.h
@@ -17,9 +17,6 @@ // Graph changes that can affect resource measurement distribution. // These are all passed on the stack so don't need to use raw_ptr. -// -// TODO(crbug.com/1471683): This should be private, but it's referenced from the -// public cpu_measurement_monitor.h struct NoGraphChange {}; struct GraphChangeAddFrame {
diff --git a/components/performance_manager/resource_attribution/process_context.cc b/components/performance_manager/resource_attribution/process_context.cc index 5494914..9866581 100644 --- a/components/performance_manager/resource_attribution/process_context.cc +++ b/components/performance_manager/resource_attribution/process_context.cc
@@ -140,11 +140,11 @@ id = BrowserProcessTag{}; break; case content::PROCESS_TYPE_RENDERER: - id = node_impl->render_process_host_proxy().render_process_host_id(); + id = node_impl->GetRenderProcessHostId(); CHECK(!absl::get<RenderProcessHostId>(id).is_null()); break; default: - id = node_impl->browser_child_process_host_proxy() + id = node_impl->GetBrowserChildProcessHostProxy() .browser_child_process_host_id(); CHECK(!absl::get<BrowserChildProcessHostId>(id).is_null()); break;
diff --git a/components/performance_manager/resource_attribution/queries.cc b/components/performance_manager/resource_attribution/queries.cc index ccca88b..9e3c33d 100644 --- a/components/performance_manager/resource_attribution/queries.cc +++ b/components/performance_manager/resource_attribution/queries.cc
@@ -11,6 +11,9 @@ #include "base/check.h" #include "base/containers/enum_set.h" #include "base/functional/bind.h" +#include "base/functional/callback.h" +#include "base/notreached.h" +#include "base/task/bind_post_task.h" #include "components/performance_manager/resource_attribution/query_params.h" #include "components/performance_manager/resource_attribution/query_scheduler.h" @@ -30,6 +33,13 @@ scheduler->RemoveScopedQuery(std::move(query_params)); } +void RequestResultsFromScheduler( + QueryParams* query_params, + base::OnceCallback<void(const QueryResultMap&)> callback, + QueryScheduler* scheduler) { + scheduler->RequestResults(*query_params, std::move(callback)); +} + } // namespace ScopedResourceUsageQuery::~ScopedResourceUsageQuery() { @@ -41,7 +51,7 @@ // Notify the scheduler this query no longer exists. Sends the QueryParams to // the scheduler to delete to be sure they're valid until the scheduler reads // them. - QueryScheduler::CallOnGraphWithScheduler( + QueryScheduler::CallWithScheduler( base::BindOnce(&RemoveScopedQueryFromScheduler, std::move(params_))); } @@ -62,7 +72,22 @@ observer_list_->RemoveObserver(observer); } -internal::QueryParams* ScopedResourceUsageQuery::GetParamsForTesting() const { +void ScopedResourceUsageQuery::Start() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + NOTIMPLEMENTED(); +} + +void ScopedResourceUsageQuery::QueryOnce() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + // Unretained is safe because the destructor passes `params_` to the scheduler + // sequence to delete. + QueryScheduler::CallWithScheduler(base::BindOnce( + &RequestResultsFromScheduler, base::Unretained(params_.get()), + base::BindOnce(&ScopedResourceUsageQuery::NotifyObservers, + observer_list_))); +} + +QueryParams* ScopedResourceUsageQuery::GetParamsForTesting() const { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); return params_.get(); } @@ -71,9 +96,18 @@ base::PassKey<QueryBuilder>, std::unique_ptr<QueryParams> params) : params_(std::move(params)) { - // Notify the scheduler this query exists. - QueryScheduler::CallOnGraphWithScheduler( - base::BindOnce(&AddScopedQueryToScheduler, params_.get())); + // Unretained is safe because the destructor passes `params_` to the scheduler + // sequence to delete. + QueryScheduler::CallWithScheduler(base::BindOnce( + &AddScopedQueryToScheduler, base::Unretained(params_.get()))); +} + +// static +void ScopedResourceUsageQuery::NotifyObservers( + scoped_refptr<ObserverList> observer_list, + const QueryResultMap& results) { + observer_list->Notify(FROM_HERE, &QueryResultObserver::OnResourceUsageUpdated, + results); } QueryBuilder::QueryBuilder() : params_(std::make_unique<QueryParams>()) {} @@ -100,12 +134,26 @@ ScopedResourceUsageQuery QueryBuilder::CreateScopedQuery() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + ValidateQuery(); // Pass ownership of `params_` to the scoped query, to avoid copying the // parameter contents. return ScopedResourceUsageQuery(base::PassKey<QueryBuilder>(), std::move(params_)); } +void QueryBuilder::QueryOnce( + base::OnceCallback<void(const QueryResultMap&)> callback, + scoped_refptr<base::TaskRunner> task_runner) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + ValidateQuery(); + // Pass ownership of `params_` to the scheduler, to avoid copying the + // parameter contents. QueryScheduler::RequestResult() will consume what it + // needs from the params, which will then be deleted by the Owned() wrapper. + QueryScheduler::CallWithScheduler(base::BindOnce( + &RequestResultsFromScheduler, base::Owned(params_.release()), + base::BindPostTask(task_runner, std::move(callback)))); +} + QueryBuilder QueryBuilder::Clone() const { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); // Clone the parameter contents to a newly-allocated QueryParams with the copy @@ -114,12 +162,12 @@ return QueryBuilder(std::move(cloned_params)); } -internal::QueryParams* QueryBuilder::GetParamsForTesting() const { +QueryParams* QueryBuilder::GetParamsForTesting() const { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); return params_.get(); } -QueryBuilder::QueryBuilder(std::unique_ptr<internal::QueryParams> params) +QueryBuilder::QueryBuilder(std::unique_ptr<QueryParams> params) : params_(std::move(params)) {} QueryBuilder& QueryBuilder::AddAllContextsWithTypeIndex(size_t index) { @@ -129,4 +177,12 @@ return *this; } +void QueryBuilder::ValidateQuery() const { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + CHECK(params_); + CHECK(!params_->resource_contexts.empty() || + !params_->all_context_types.none()); + CHECK(!params_->resource_types.Empty()); +} + } // namespace performance_manager::resource_attribution
diff --git a/components/performance_manager/resource_attribution/queries_unittest.cc b/components/performance_manager/resource_attribution/queries_unittest.cc index 72f83f63..56b4de5e 100644 --- a/components/performance_manager/resource_attribution/queries_unittest.cc +++ b/components/performance_manager/resource_attribution/queries_unittest.cc
@@ -12,11 +12,14 @@ #include "base/barrier_closure.h" #include "base/containers/enum_set.h" -#include "base/dcheck_is_on.h" #include "base/functional/callback.h" +#include "base/memory/raw_ptr.h" #include "base/memory/scoped_refptr.h" #include "base/observer_list_threadsafe.h" #include "base/run_loop.h" +#include "base/task/sequenced_task_runner.h" +#include "base/test/bind.h" +#include "base/test/task_environment.h" #include "base/time/time.h" #include "components/performance_manager/embedder/graph_features.h" #include "components/performance_manager/public/graph/graph.h" @@ -31,6 +34,8 @@ #include "components/performance_manager/test_support/graph_test_harness.h" #include "components/performance_manager/test_support/mock_graphs.h" #include "components/performance_manager/test_support/performance_manager_test_harness.h" +#include "components/performance_manager/test_support/resource_attribution/gmock_matchers.h" +#include "components/performance_manager/test_support/resource_attribution/simulated_cpu_measurement_delegate.h" #include "components/performance_manager/test_support/run_in_graph.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/web_contents.h" @@ -45,6 +50,7 @@ namespace { +using ::testing::ElementsAre; using QueryParams = internal::QueryParams; class LenientMockQueryResultObserver : public QueryResultObserver { @@ -57,36 +63,67 @@ using MockQueryResultObserver = ::testing::StrictMock<LenientMockQueryResultObserver>; -// Test QueryBuilder using mock graphs. -using ResourceAttrQueryBuilderTest = GraphTestHarness; +using ResourceAttrQueriesTest = GraphTestHarness; -// Test ScopedResourceUsageQuery with PerformanceManagerTestHarness to test its -// interactions on the PM sequence. -class ResourceAttrScopedQueryTest : public PerformanceManagerTestHarness { +// Tests that interact with the QueryScheduler use PerformanceManagerTestHarness +// to test its interactions on the PM sequence. +class ResourceAttrQueriesPMTest : public PerformanceManagerTestHarness { protected: using Super = PerformanceManagerTestHarness; + ResourceAttrQueriesPMTest() + : Super(base::test::TaskEnvironment::TimeSource::MOCK_TIME) {} + void SetUp() override { GetGraphFeatures().EnableResourceAttributionScheduler(); Super::SetUp(); + RunInGraph([&](Graph* graph) { + graph_ = graph; + CPUMeasurementDelegate::SetDelegateFactoryForTesting(graph, + &delegate_factory_); + }); + // Navigate to an initial page. SetContents(CreateTestWebContents()); content::RenderFrameHost* rfh = content::NavigationSimulator::NavigateAndCommitFromBrowser( web_contents(), GURL("https://a.com/")); ASSERT_TRUE(rfh); - main_frame_context = FrameContext::FromRenderFrameHost(rfh); - ASSERT_TRUE(main_frame_context.has_value()); + main_frame_context_ = FrameContext::FromRenderFrameHost(rfh); + ASSERT_TRUE(main_frame_context_.has_value()); } + void TearDown() override { + graph_ = nullptr; + Super::TearDown(); + } + + void TearDownGraph() { + graph_ = nullptr; + Super::TearDownNow(); + } + + Graph* graph() { return graph_.get(); } + // A ResourceContext for the main frame. - absl::optional<FrameContext> main_frame_context; + ResourceContext main_frame_context() const { + return main_frame_context_.value(); + } + + private: + raw_ptr<Graph> graph_ = nullptr; + + absl::optional<FrameContext> main_frame_context_; + + // This must be deleted after TearDown() so that it outlives the + // CPUMeasurementMonitor. + SimulatedCPUMeasurementDelegateFactory delegate_factory_; }; } // namespace -TEST_F(ResourceAttrQueryBuilderTest, Params) { +TEST_F(ResourceAttrQueriesTest, QueryBuilderParams) { MockSinglePageInSingleProcessGraph mock_graph(graph()); QueryBuilder builder; @@ -133,7 +170,7 @@ EXPECT_EQ(*scoped_query.GetParamsForTesting(), expected_params); } -TEST_F(ResourceAttrQueryBuilderTest, Clone) { +TEST_F(ResourceAttrQueriesTest, QueryBuilderClone) { MockSinglePageInSingleProcessGraph mock_graph(graph()); QueryBuilder builder; builder.AddResourceContext(mock_graph.page->GetResourceContext()) @@ -162,7 +199,48 @@ expected_cloned_contexts); } -TEST_F(ResourceAttrScopedQueryTest, AddRemoveScopedQuery) { +TEST_F(ResourceAttrQueriesPMTest, QueryBuilderQueryOnce) { + base::RunLoop run_loop; + QueryBuilder() + .AddResourceContext(main_frame_context()) + .AddResourceType(ResourceType::kCPUTime) + .QueryOnce(base::BindLambdaForTesting([](const QueryResultMap& results) { + // CPU measurements need to cover a period of time, so + // without a scoped query to start the monitoring period + // there will be no results. This just tests that the query + // request and empty result are delivered to and from the + // scheduler. + EXPECT_TRUE(results.empty()); + }).Then(run_loop.QuitClosure())); + run_loop.Run(); +} + +TEST_F(ResourceAttrQueriesPMTest, QueryBuilderQueryOnceWithTaskRunner) { + auto main_thread_task_runner = base::SequencedTaskRunner::GetCurrentDefault(); + base::RunLoop run_loop; + auto expect_empty_on_main_thread = + [main_thread_task_runner, + quit_closure = run_loop.QuitClosure()](const QueryResultMap& results) { + EXPECT_TRUE(results.empty()); + EXPECT_TRUE(main_thread_task_runner->RunsTasksInCurrentSequence()); + std::move(quit_closure).Run(); + }; + + // Create the query on the graph sequence, but tell it to run the result + // callback on the main thread. + RunInGraph([&] { + QueryBuilder() + .AddResourceContext(main_frame_context()) + .AddResourceType(ResourceType::kCPUTime) + .QueryOnce(base::BindLambdaForTesting(expect_empty_on_main_thread), + main_thread_task_runner); + }); + + // Block the main thread until the result is received. + run_loop.Run(); +} + +TEST_F(ResourceAttrQueriesPMTest, AddRemoveScopedQuery) { QueryScheduler* scheduler = nullptr; RunInGraph([&](Graph* graph) { scheduler = QueryScheduler::GetFromGraph(graph); @@ -174,6 +252,7 @@ absl::optional<ScopedResourceUsageQuery> scoped_query = QueryBuilder() + .AddResourceContext(main_frame_context()) .AddResourceType(ResourceType::kCPUTime) .CreateScopedQuery(); RunInGraph([&] { @@ -185,7 +264,7 @@ }); } -TEST_F(ResourceAttrScopedQueryTest, Movable) { +TEST_F(ResourceAttrQueriesPMTest, ScopedQueryIsMovable) { QueryScheduler* scheduler = nullptr; RunInGraph([&](Graph* graph) { scheduler = QueryScheduler::GetFromGraph(graph); @@ -199,6 +278,7 @@ { ScopedResourceUsageQuery inner_query = QueryBuilder() + .AddResourceContext(main_frame_context()) .AddResourceType(ResourceType::kCPUTime) .CreateScopedQuery(); RunInGraph([&] { @@ -232,79 +312,100 @@ }); } -TEST_F(ResourceAttrScopedQueryTest, Observers) { +TEST_F(ResourceAttrQueriesPMTest, Observers) { ScopedResourceUsageQuery scoped_query = QueryBuilder() - .AddResourceContext(main_frame_context.value()) + .AddResourceContext(main_frame_context()) .AddResourceType(ResourceType::kCPUTime) .CreateScopedQuery(); - const QueryResultMap test_results{ - {main_frame_context.value(), - {CPUTimeResult{.cumulative_cpu = base::Minutes(1)}}}, - }; + // Allow some time to pass to measure. + task_environment()->FastForwardBy(base::Minutes(1)); // Safely do nothing when no observers are registered. - Graph* graph_ptr = nullptr; - RunInGraph([&](Graph* graph) { - graph_ptr = graph; - // TODO(crbug.com/1471683): QueryScheduler should be notifying the - // observers. - scoped_query.observer_list_->Notify( - FROM_HERE, &QueryResultObserver::OnResourceUsageUpdated, test_results); - }); - ASSERT_TRUE(graph_ptr); + scoped_query.QueryOnce(); + // Post an empty task to the graph sequence to give time for the query to run + // there. Nothing should happen. + RunInGraph([] {}); // Observer can be notified from the graph sequence when installed on any // thread. MockQueryResultObserver main_thread_observer; - MockQueryResultObserver graph_sequence_observer; scoped_query.AddObserver(&main_thread_observer); - RunInGraph([&] { scoped_query.AddObserver(&graph_sequence_observer); }); + auto main_thread_task_runner = base::SequencedTaskRunner::GetCurrentDefault(); - auto check_graph_sequence = [&](bool expect_on_graph_sequence) { -#if DCHECK_IS_ON() - EXPECT_EQ(graph_ptr->IsOnGraphSequence(), expect_on_graph_sequence); -#endif - }; - - // Quit the RunLoop when both observers receive results. - base::RunLoop run_loop; - auto quit_closure = base::BarrierClosure(2, run_loop.QuitClosure()); - EXPECT_CALL(main_thread_observer, OnResourceUsageUpdated(test_results)) - .WillOnce([&] { - check_graph_sequence(false); - quit_closure.Run(); - }); - EXPECT_CALL(graph_sequence_observer, OnResourceUsageUpdated(test_results)) - .WillOnce([&] { - check_graph_sequence(true); - quit_closure.Run(); - }); - + MockQueryResultObserver graph_sequence_observer; + scoped_refptr<base::SequencedTaskRunner> graph_sequence_task_runner; RunInGraph([&] { - scoped_query.observer_list_->Notify( - FROM_HERE, &QueryResultObserver::OnResourceUsageUpdated, test_results); + scoped_query.AddObserver(&graph_sequence_observer); + graph_sequence_task_runner = base::SequencedTaskRunner::GetCurrentDefault(); }); - // Wait for all notifications. + // Quit the RunLoop when both observers receive results. Expect each result to + // contain a single ResourceContext with a CPUTimeResult. + base::RunLoop run_loop; + auto barrier_closure = base::BarrierClosure(2, run_loop.QuitClosure()); + EXPECT_CALL( + main_thread_observer, + OnResourceUsageUpdated(ElementsAre( + QueryResultMapEntryMatches<CPUTimeResult>(main_frame_context())))) + .WillOnce([&] { + EXPECT_TRUE(main_thread_task_runner->RunsTasksInCurrentSequence()); + barrier_closure.Run(); + }); + EXPECT_CALL( + graph_sequence_observer, + OnResourceUsageUpdated(ElementsAre( + QueryResultMapEntryMatches<CPUTimeResult>(main_frame_context())))) + .WillOnce([&] { + EXPECT_TRUE(graph_sequence_task_runner->RunsTasksInCurrentSequence()); + barrier_closure.Run(); + }); + scoped_query.QueryOnce(); run_loop.Run(); } -TEST_F(ResourceAttrScopedQueryTest, GraphTeardown) { +TEST_F(ResourceAttrQueriesPMTest, GraphTeardown) { // ScopedResourceUsageQuery registers with the QueryScheduler on creation and // unregisters on destruction. Make sure it's safe for it to outlive the // scheduler, which is deleted during graph teardown. absl::optional<ScopedResourceUsageQuery> scoped_query = QueryBuilder() - .AddResourceContext(main_frame_context.value()) + .AddResourceContext(main_frame_context()) .AddResourceType(ResourceType::kCPUTime) .CreateScopedQuery(); + MockQueryResultObserver observer; + scoped_query->AddObserver(&observer); - TearDownNow(); + TearDownGraph(); - // The test passes as long as this doesn't crash. + // The test passes as long as these don't crash. `observer` should not be + // notified (StrictMock will test this). + scoped_query->QueryOnce(); scoped_query.reset(); } +TEST_F(ResourceAttrQueriesPMTest, ScopedQueryAndQueryOnce) { + QueryBuilder builder; + builder.AddResourceContext(main_frame_context()) + .AddResourceType(ResourceType::kCPUTime); + + // Create a scoped query to start the CPU monitor. + auto scoped_query = builder.Clone().CreateScopedQuery(); + + // Allow some time to pass to measure. + task_environment()->FastForwardBy(base::Minutes(1)); + + base::RunLoop run_loop; + builder.Clone().QueryOnce( + base::BindLambdaForTesting([&](const QueryResultMap& results) { + // QueryOnce should get measurements that were collected for + // `scoped_query`. + EXPECT_THAT(results, + ElementsAre(QueryResultMapEntryMatches<CPUTimeResult>( + main_frame_context()))); + }).Then(run_loop.QuitClosure())); + run_loop.Run(); +} + } // namespace performance_manager::resource_attribution
diff --git a/components/performance_manager/resource_attribution/query_scheduler.cc b/components/performance_manager/resource_attribution/query_scheduler.cc index 1779244..6537621 100644 --- a/components/performance_manager/resource_attribution/query_scheduler.cc +++ b/components/performance_manager/resource_attribution/query_scheduler.cc
@@ -4,14 +4,20 @@ #include "components/performance_manager/resource_attribution/query_scheduler.h" +#include <bitset> #include <utility> +#include <vector> #include "base/check_op.h" +#include "base/containers/contains.h" #include "base/containers/enum_set.h" #include "base/functional/bind.h" #include "base/functional/callback.h" -#include "base/task/task_runner.h" -#include "components/performance_manager/public/performance_manager.h" +#include "base/memory/scoped_refptr.h" +#include "base/no_destructor.h" +#include "base/synchronization/lock.h" +#include "base/task/sequenced_task_runner.h" +#include "components/performance_manager/public/resource_attribution/resource_types.h" #include "components/performance_manager/resource_attribution/query_params.h" namespace performance_manager::resource_attribution { @@ -20,10 +26,85 @@ using QueryParams = internal::QueryParams; -QueryScheduler* GetSchedulerFromGraph(Graph* graph) { - auto* scheduler = QueryScheduler::GetFromGraph(graph); - CHECK(scheduler); - return scheduler; +// A global singleton that holds the TaskRunner the QueryScheduler runs on. In +// production this is the PM graph sequence, but in unit tests it can be the +// main thread. The TaskRunner is set when the QueryScheduler is passed to the +// PM graph, so it will be reset between tests and can be null during graph +// teardown. +// +// This is used instead of CallOnGraph because there are many +// resource attribution tests that use GraphTestHarness and mock graphs instead +// of PerformanceManagerTestHarness, that don't use any PerformanceManager hooks +// except for the QueryScheduler. +class SchedulerTaskRunner { + public: + SchedulerTaskRunner(const SchedulerTaskRunner&) = delete; + SchedulerTaskRunner operator=(const SchedulerTaskRunner&) = delete; + + static SchedulerTaskRunner* GetInstance(); + + // Registers the current sequence's TaskRunner as the QueryScheduler + // TaskRunner. + void OnSchedulerPassedToGraph(Graph* graph); + + // Clears the QueryScheduler TaskRunner. + void OnSchedulerTakenFromGraph(Graph* graph); + + // Returns the QueryScheduler TaskRunner, or null if there is none. + scoped_refptr<base::SequencedTaskRunner> GetTaskRunner(); + + // Looks up the QueryScheduler and passes it to `callback`. This must run on + // the TaskRunner returned by GetTaskRunner(). If there is no QueryScheduler + // (which can happen if the scheduler is deleted after the CallWithScheduler + // task is posted), `callback` is dropped. + void CallWithScheduler(base::OnceCallback<void(QueryScheduler*)> callback); + + private: + friend class base::NoDestructor<SchedulerTaskRunner>; + + SchedulerTaskRunner() = default; + ~SchedulerTaskRunner() = default; + + base::Lock task_runner_lock_; + + scoped_refptr<base::SequencedTaskRunner> task_runner_ + GUARDED_BY(task_runner_lock_); + + raw_ptr<Graph> graph_ = nullptr; +}; + +// static +SchedulerTaskRunner* SchedulerTaskRunner::GetInstance() { + static base::NoDestructor<SchedulerTaskRunner> instance; + return instance.get(); +} + +void SchedulerTaskRunner::OnSchedulerPassedToGraph(Graph* graph) { + base::AutoLock lock(task_runner_lock_); + CHECK(!task_runner_); + task_runner_ = base::SequencedTaskRunner::GetCurrentDefault(); + CHECK(!graph_); + graph_ = graph; +} + +void SchedulerTaskRunner::OnSchedulerTakenFromGraph(Graph* graph) { + base::AutoLock lock(task_runner_lock_); + CHECK_EQ(task_runner_, base::SequencedTaskRunner::GetCurrentDefault()); + task_runner_.reset(); + CHECK_EQ(graph_.get(), graph); + graph_ = nullptr; +} + +scoped_refptr<base::SequencedTaskRunner> SchedulerTaskRunner::GetTaskRunner() { + base::AutoLock lock(task_runner_lock_); + return task_runner_; +} + +void SchedulerTaskRunner::CallWithScheduler( + base::OnceCallback<void(QueryScheduler*)> callback) { + if (graph_) { + std::move(callback).Run(QueryScheduler::GetFromGraph(graph_.get())); + } } } // namespace @@ -37,34 +118,18 @@ } // static -void QueryScheduler::CallOnGraphWithScheduler( +void QueryScheduler::CallWithScheduler( base::OnceCallback<void(QueryScheduler*)> callback, const base::Location& location) { - PerformanceManager::CallOnGraph( - location, - base::BindOnce(&GetSchedulerFromGraph).Then(std::move(callback))); -} - -void QueryScheduler::AddCPUQuery() { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - CHECK_NE(graph_, nullptr); - cpu_query_count_ += 1; - // Check for overflow. - CHECK_GT(cpu_query_count_, 0U); - if (cpu_query_count_ == 1) { - CHECK(!cpu_monitor_.IsMonitoring()); - cpu_monitor_.StartMonitoring(graph_); - } -} - -void QueryScheduler::RemoveCPUQuery() { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - CHECK_NE(graph_, nullptr); - CHECK_GE(cpu_query_count_, 1U); - cpu_query_count_ -= 1; - if (cpu_query_count_ == 0) { - CHECK(cpu_monitor_.IsMonitoring()); - cpu_monitor_.StopMonitoring(); + auto* scheduler_and_task_runner = SchedulerTaskRunner::GetInstance(); + scoped_refptr<base::SequencedTaskRunner> task_runner = + scheduler_and_task_runner->GetTaskRunner(); + if (task_runner) { + // Unretained is safe because SchedulerTaskRunner is a leaked singleton. + task_runner->PostTask( + location, base::BindOnce(&SchedulerTaskRunner::CallWithScheduler, + base::Unretained(scheduler_and_task_runner), + std::move(callback))); } } @@ -90,20 +155,30 @@ // `query_params` goes out of scope and is deleted here. } -void QueryScheduler::RequestCPUResults( - base::OnceCallback<void(const QueryResultMap&)> callback, - scoped_refptr<base::TaskRunner> task_runner) { +void QueryScheduler::RequestResults( + const QueryParams& query_params, + base::OnceCallback<void(const QueryResultMap&)> callback) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - CHECK(cpu_monitor_.IsMonitoring()); QueryResultMap results; - for (auto& [context, cpu_time_result] : - cpu_monitor_.UpdateAndGetCPUMeasurements()) { - // TODO(crbug.com/1471683): Filter the results by ResourceContexts in the - // request. - results[context].push_back(std::move(cpu_time_result)); + // If no scoped query is keeping the CPU monitor running, just return empty + // results. + // TODO(crbug.com/1471683): Could run the CPU monitor for a few seconds + // instead. + if (query_params.resource_types.Has(ResourceType::kCPUTime) && + cpu_monitor_.IsMonitoring()) { + // TODO(crbug.com/1471683): Pass the contexts of interest into + // `cpu_monitor_` so it doesn't have to do work measuring contexts that will + // be filtered out. + for (auto& [context, cpu_time_result] : + cpu_monitor_.UpdateAndGetCPUMeasurements()) { + // index() gets context's type index in the ResourceContext variant. + if (query_params.all_context_types.test(context.index()) || + base::Contains(query_params.resource_contexts, context)) { + results[context].push_back(std::move(cpu_time_result)); + } + } } - task_runner->PostTask( - FROM_HERE, base::BindOnce(std::move(callback), std::move(results))); + std::move(callback).Run(results); } CPUMeasurementMonitor& QueryScheduler::GetCPUMonitorForTesting() { @@ -116,6 +191,7 @@ CHECK_EQ(graph_, nullptr); graph_ = graph; graph_->RegisterObject(this); + SchedulerTaskRunner::GetInstance()->OnSchedulerPassedToGraph(graph); } void QueryScheduler::OnTakenFromGraph(Graph* graph) { @@ -123,9 +199,33 @@ CHECK_EQ(graph_, graph); graph_->UnregisterObject(this); graph_ = nullptr; + SchedulerTaskRunner::GetInstance()->OnSchedulerTakenFromGraph(graph); if (cpu_query_count_ > 0) { cpu_monitor_.StopMonitoring(); } } +void QueryScheduler::AddCPUQuery() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + CHECK_NE(graph_, nullptr); + cpu_query_count_ += 1; + // Check for overflow. + CHECK_GT(cpu_query_count_, 0U); + if (cpu_query_count_ == 1) { + CHECK(!cpu_monitor_.IsMonitoring()); + cpu_monitor_.StartMonitoring(graph_); + } +} + +void QueryScheduler::RemoveCPUQuery() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + CHECK_NE(graph_, nullptr); + CHECK_GE(cpu_query_count_, 1U); + cpu_query_count_ -= 1; + if (cpu_query_count_ == 0) { + CHECK(cpu_monitor_.IsMonitoring()); + cpu_monitor_.StopMonitoring(); + } +} + } // namespace performance_manager::resource_attribution
diff --git a/components/performance_manager/resource_attribution/query_scheduler.h b/components/performance_manager/resource_attribution/query_scheduler.h index 505d248..2df56647 100644 --- a/components/performance_manager/resource_attribution/query_scheduler.h +++ b/components/performance_manager/resource_attribution/query_scheduler.h
@@ -10,7 +10,6 @@ #include "base/functional/callback_forward.h" #include "base/location.h" #include "base/memory/raw_ptr.h" -#include "base/memory/scoped_refptr.h" #include "base/memory/weak_ptr.h" #include "base/sequence_checker.h" #include "components/performance_manager/public/graph/graph.h" @@ -18,10 +17,6 @@ #include "components/performance_manager/public/resource_attribution/query_results.h" #include "components/performance_manager/resource_attribution/cpu_measurement_monitor.h" -namespace base { -class TaskRunner; -} - namespace performance_manager::resource_attribution { namespace internal { @@ -43,22 +38,10 @@ // Invokes `callback` on the PM sequence with a pointer to the registered // QueryScheduler. - static void CallOnGraphWithScheduler( + static void CallWithScheduler( base::OnceCallback<void(QueryScheduler*)> callback, const base::Location& location = base::Location::Current()); - // Increases the CPU query count. `cpu_monitor_` will start monitoring CPU - // usage when the count > 0. - // TODO(crbug.com/1471683): Make this private. It should only be called by - // AddScopedQuery(). - void AddCPUQuery(); - - // Decreases the CPU query count. `cpu_monitor_` will stop monitoring CPU - // usage when the count == 0. - // TODO(crbug.com/1471683): Make this private. It should only be called by - // RemoveScopedQuery(). - void RemoveCPUQuery(); - // Adds a scoped query for `query_params`. Increases the query count for all // resource types and contexts referenced in `query_params`. void AddScopedQuery(internal::QueryParams* query_params); @@ -67,13 +50,10 @@ // `query_params` and deletes `query_params`. void RemoveScopedQuery(std::unique_ptr<internal::QueryParams> query_params); - // Requests the latest CPU measurements from `cpu_monitor_`, and posts them - // to `callback` on `task_runner`. Asserts that the CPU query count > 0. - // TODO(crbug.com/1471683): Replace with a general RequestResults that handles - // any QueryParams. - void RequestCPUResults( - base::OnceCallback<void(const QueryResultMap&)> callback, - scoped_refptr<base::TaskRunner> task_runner); + // Requests the latest results for the given `query_params`, and passes them + // to `callback`. + void RequestResults(const internal::QueryParams& query_params, + base::OnceCallback<void(const QueryResultMap&)> callback); // Gives tests direct access to `cpu_monitor_`. CPUMeasurementMonitor& GetCPUMonitorForTesting(); @@ -83,6 +63,14 @@ void OnTakenFromGraph(Graph* graph) final; private: + // Increases the CPU query count. `cpu_monitor_` will start monitoring CPU + // usage when the count > 0. + void AddCPUQuery(); + + // Decreases the CPU query count. `cpu_monitor_` will stop monitoring CPU + // usage when the count == 0. + void RemoveCPUQuery(); + SEQUENCE_CHECKER(sequence_checker_); raw_ptr<Graph> graph_ GUARDED_BY_CONTEXT(sequence_checker_);
diff --git a/components/performance_manager/resource_attribution/query_scheduler_unittest.cc b/components/performance_manager/resource_attribution/query_scheduler_unittest.cc index b7c6f8e..d819ca7f 100644 --- a/components/performance_manager/resource_attribution/query_scheduler_unittest.cc +++ b/components/performance_manager/resource_attribution/query_scheduler_unittest.cc
@@ -4,25 +4,28 @@ #include "components/performance_manager/resource_attribution/query_scheduler.h" +#include <bitset> #include <memory> +#include <set> #include <utility> #include "base/containers/enum_set.h" #include "base/dcheck_is_on.h" -#include "base/functional/bind.h" #include "base/functional/callback.h" -#include "base/functional/callback_helpers.h" -#include "base/memory/weak_ptr.h" #include "base/run_loop.h" +#include "base/task/sequenced_task_runner.h" #include "base/test/bind.h" #include "base/test/task_environment.h" #include "base/time/time.h" +#include "base/types/variant_util.h" #include "components/performance_manager/embedder/graph_features.h" #include "components/performance_manager/public/graph/graph.h" #include "components/performance_manager/public/graph/process_node.h" +#include "components/performance_manager/public/performance_manager.h" #include "components/performance_manager/public/resource_attribution/cpu_measurement_delegate.h" -#include "components/performance_manager/public/resource_attribution/process_context.h" +#include "components/performance_manager/public/resource_attribution/queries.h" #include "components/performance_manager/public/resource_attribution/query_results.h" +#include "components/performance_manager/public/resource_attribution/resource_contexts.h" #include "components/performance_manager/public/resource_attribution/resource_types.h" #include "components/performance_manager/public/resource_attribution/scoped_cpu_query.h" #include "components/performance_manager/resource_attribution/cpu_measurement_monitor.h" @@ -30,6 +33,7 @@ #include "components/performance_manager/test_support/graph_test_harness.h" #include "components/performance_manager/test_support/mock_graphs.h" #include "components/performance_manager/test_support/performance_manager_test_harness.h" +#include "components/performance_manager/test_support/resource_attribution/gmock_matchers.h" #include "components/performance_manager/test_support/resource_attribution/simulated_cpu_measurement_delegate.h" #include "components/performance_manager/test_support/run_in_graph.h" #include "testing/gmock/include/gmock/gmock.h" @@ -39,20 +43,50 @@ namespace { -using ::testing::Contains; -using ::testing::Key; +using ::testing::UnorderedElementsAre; using QueryParams = internal::QueryParams; -std::unique_ptr<QueryParams> CreateQueryParams(ResourceTypeSet resource_types) { +// A QueryResultObserver that passes the result to a callback. +class CallbackQueryResultObserver final : public QueryResultObserver { + public: + CallbackQueryResultObserver() = default; + ~CallbackQueryResultObserver() final = default; + + CallbackQueryResultObserver(const CallbackQueryResultObserver&) = delete; + CallbackQueryResultObserver operator=(const CallbackQueryResultObserver&) = + delete; + + void SetCallback(base::OnceCallback<void(const QueryResultMap&)> callback) { + callback_ = std::move(callback); + } + + // QueryResultObserver: + void OnResourceUsageUpdated(const QueryResultMap& results) final { + if (callback_) { + std::move(callback_).Run(results); + } + } + + private: + base::OnceCallback<void(const QueryResultMap&)> callback_; +}; + +std::unique_ptr<QueryParams> CreateQueryParams( + ResourceTypeSet resource_types = {}, + std::set<ResourceContext> resource_contexts = {}) { auto params = std::make_unique<QueryParams>(); params->resource_types = std::move(resource_types); + params->resource_contexts = std::move(resource_contexts); return params; } // Waits for a result from `query` and tests that it matches `matcher`. -void ExpectQueryResult(ScopedCPUQuery* query, auto matcher) { +void ExpectQueryResult(QueryScheduler* scheduler, + QueryParams* query, + auto matcher) { base::RunLoop run_loop; - query->QueryOnce( + scheduler->RequestResults( + *query, base::BindLambdaForTesting([&](const QueryResultMap& query_results) { EXPECT_THAT(query_results, matcher); }).Then(run_loop.QuitClosure())); @@ -80,85 +114,63 @@ using ResourceAttrQuerySchedulerPMTest = PerformanceManagerTestHarness; TEST_F(ResourceAttrQuerySchedulerTest, CPUQueries) { - MockSinglePageInSingleProcessGraph mock_graph(graph()); + MockMultiplePagesWithMultipleProcessesGraph mock_graph(graph()); auto* scheduler = QueryScheduler::GetFromGraph(graph()); ASSERT_TRUE(scheduler); EXPECT_FALSE(scheduler->GetCPUMonitorForTesting().IsMonitoring()); - auto cpu_query1 = std::make_unique<ScopedCPUQuery>(graph()); - // First query created should start CPU monitoring. + // Query without kCPUTime should not start CPU monitoring. + auto no_cpu_query = + CreateQueryParams({}, {mock_graph.process->GetResourceContext()}); + scheduler->AddScopedQuery(no_cpu_query.get()); + EXPECT_FALSE(scheduler->GetCPUMonitorForTesting().IsMonitoring()); + + // First kCPUTime query should start CPU monitoring. + auto cpu_query1 = CreateQueryParams( + {ResourceType::kCPUTime}, {mock_graph.process->GetResourceContext()}); + scheduler->AddScopedQuery(cpu_query1.get()); EXPECT_TRUE(scheduler->GetCPUMonitorForTesting().IsMonitoring()); + auto cpu_query2 = CreateQueryParams({ResourceType::kCPUTime}, {}); + cpu_query2->all_context_types.set( + base::VariantIndexOfType<ResourceContext, ProcessContext>()); + scheduler->AddScopedQuery(cpu_query2.get()); + // Allow some time to pass to measure. task_env().FastForwardBy(base::Minutes(1)); - ExpectQueryResult(cpu_query1.get(), - Contains(Key(mock_graph.process->GetResourceContext()))); - // CPU monitoring should not stop until the last query is deleted. - auto cpu_query2 = std::make_unique<ScopedCPUQuery>(graph()); - cpu_query1.reset(); - EXPECT_TRUE(scheduler->GetCPUMonitorForTesting().IsMonitoring()); - ExpectQueryResult(cpu_query2.get(), - Contains(Key(mock_graph.process->GetResourceContext()))); - - cpu_query2.reset(); - EXPECT_FALSE(scheduler->GetCPUMonitorForTesting().IsMonitoring()); -} - -TEST_F(ResourceAttrQuerySchedulerTest, ScopedQueries) { - auto* scheduler = QueryScheduler::GetFromGraph(graph()); - ASSERT_TRUE(scheduler); - - // Query without kCPUTime should not start CPU monitoring. - auto no_cpu_params = CreateQueryParams({}); - scheduler->AddScopedQuery(no_cpu_params.get()); - EXPECT_FALSE(scheduler->GetCPUMonitorForTesting().IsMonitoring()); - - // First kCPUTime query should start monitoring. - auto cpu_params1 = CreateQueryParams({ResourceType::kCPUTime}); - scheduler->AddScopedQuery(cpu_params1.get()); - EXPECT_TRUE(scheduler->GetCPUMonitorForTesting().IsMonitoring()); + // Only the kCPUTime queries should receive CPU results. `cpu_query1` should + // only get results for `process`. + ExpectQueryResult(scheduler, no_cpu_query.get(), + UnorderedElementsAre(/*none*/)); + ExpectQueryResult( + scheduler, cpu_query1.get(), + UnorderedElementsAre(QueryResultMapEntryMatches<CPUTimeResult>( + mock_graph.process->GetResourceContext()))); + ExpectQueryResult(scheduler, cpu_query2.get(), + UnorderedElementsAre( + QueryResultMapEntryMatches<CPUTimeResult>( + mock_graph.process->GetResourceContext()), + QueryResultMapEntryMatches<CPUTimeResult>( + mock_graph.other_process->GetResourceContext()))); // Removing non-CPU query should not affect CPU monitoring. - scheduler->RemoveScopedQuery(std::move(no_cpu_params)); + scheduler->RemoveScopedQuery(std::move(no_cpu_query)); EXPECT_TRUE(scheduler->GetCPUMonitorForTesting().IsMonitoring()); - // CPU monitoring should not stop until the last CPU query is deleted. - auto cpu_params2 = CreateQueryParams({ResourceType::kCPUTime}); - scheduler->AddScopedQuery(cpu_params2.get()); - scheduler->RemoveScopedQuery(std::move(cpu_params1)); + // CPU monitoring should not stop until the last query is deleted. + scheduler->RemoveScopedQuery(std::move(cpu_query1)); EXPECT_TRUE(scheduler->GetCPUMonitorForTesting().IsMonitoring()); - scheduler->RemoveScopedQuery(std::move(cpu_params2)); + scheduler->RemoveScopedQuery(std::move(cpu_query2)); EXPECT_FALSE(scheduler->GetCPUMonitorForTesting().IsMonitoring()); } -TEST_F(ResourceAttrQuerySchedulerTest, GraphTeardown) { - // Make sure queries that still exist when the scheduler is deleted during - // graph teardown safely return no data. - auto* scheduler = QueryScheduler::GetFromGraph(graph()); - ASSERT_TRUE(scheduler); - auto weak_scheduler = scheduler->GetWeakPtr(); - - ScopedCPUQuery query(graph()); - - TearDownAndDestroyGraph(); - - EXPECT_FALSE(weak_scheduler); - - base::RunLoop run_loop; - query.QueryOnce(base::BindOnce( - [](base::ScopedClosureRunner closure_runner, const QueryResultMap&) { - // The result callback should never run since the scheduler is - // unavailable. The ScopedClosureRunner will run when the result - // callback is deleted with all its bound parameters though. - FAIL(); - }, - base::ScopedClosureRunner(run_loop.QuitClosure()))); -} - -TEST_F(ResourceAttrQuerySchedulerPMTest, CallOnGraphWithScheduler) { +TEST_F(ResourceAttrQuerySchedulerPMTest, CallWithScheduler) { + // Tests that CallWithScheduler works from PerformanceManagerTestHarness, + // where the scheduler runs on the PM sequence as in production. + EXPECT_TRUE(PerformanceManager::IsAvailable()); QueryScheduler* scheduler_ptr = nullptr; Graph* graph_ptr = nullptr; RunInGraph([&](Graph* graph) { @@ -170,7 +182,7 @@ ASSERT_TRUE(scheduler_ptr); ASSERT_TRUE(graph_ptr); base::RunLoop run_loop; - QueryScheduler::CallOnGraphWithScheduler( + QueryScheduler::CallWithScheduler( base::BindLambdaForTesting([&](QueryScheduler* scheduler) { #if DCHECK_IS_ON() EXPECT_TRUE(graph_ptr->IsOnGraphSequence()); @@ -180,4 +192,18 @@ run_loop.Run(); } +TEST_F(ResourceAttrQuerySchedulerTest, CallWithScheduler) { + // Tests that CallWithScheduler works from GraphTestHarness which doesn't set + // up the PerformanceManager sequence. It's convenient to use GraphTestHarness + // with mock graphs to test resource attribution queries. + EXPECT_FALSE(PerformanceManager::IsAvailable()); + base::RunLoop run_loop; + QueryScheduler::CallWithScheduler( + base::BindLambdaForTesting([&](QueryScheduler* scheduler) { + // The QueryScheduler was installed on the graph in SetUp(). + EXPECT_EQ(scheduler, graph()->GetRegisteredObjectAs<QueryScheduler>()); + }).Then(run_loop.QuitClosure())); + run_loop.Run(); +} + } // namespace performance_manager::resource_attribution
diff --git a/components/performance_manager/resource_attribution/scoped_cpu_query.cc b/components/performance_manager/resource_attribution/scoped_cpu_query.cc index 00ad1070..20c4b11 100644 --- a/components/performance_manager/resource_attribution/scoped_cpu_query.cc +++ b/components/performance_manager/resource_attribution/scoped_cpu_query.cc
@@ -8,32 +8,44 @@ #include "base/check.h" #include "base/functional/callback.h" -#include "components/performance_manager/resource_attribution/query_scheduler.h" +#include "components/performance_manager/public/resource_attribution/resource_contexts.h" +#include "components/performance_manager/public/resource_attribution/resource_types.h" namespace performance_manager::resource_attribution { -ScopedCPUQuery::ScopedCPUQuery(Graph* graph) { - auto* scheduler = QueryScheduler::GetFromGraph(graph); - CHECK(scheduler); - scheduler->AddCPUQuery(); - scheduler_ = scheduler->GetWeakPtr(); +ScopedCPUQuery::ScopedCPUQuery() + : wrapped_query_(QueryBuilder() + .AddResourceType(ResourceType::kCPUTime) + .AddAllContextsOfType<FrameContext>() + .AddAllContextsOfType<PageContext>() + .AddAllContextsOfType<ProcessContext>() + .AddAllContextsOfType<WorkerContext>() + .CreateScopedQuery()) { + wrapped_query_.AddObserver(this); } ScopedCPUQuery::~ScopedCPUQuery() { - if (scheduler_) { - scheduler_->RemoveCPUQuery(); - } + wrapped_query_.RemoveObserver(this); } -void ScopedCPUQuery::QueryOnce( - base::OnceCallback<void(const QueryResultMap&)> callback, - scoped_refptr<base::TaskRunner> task_runner) { - if (scheduler_) { - scheduler_->RequestCPUResults(std::move(callback), task_runner); +void ScopedCPUQuery::QueryOnce(ScopedCPUQuery::ResultCallback callback) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + if (callbacks_.empty()) { + // No queries in flight, so start a new query. Further QueryOnce() calls + // before OnResourceUsageUpdate() clears the callback list will use the same + // query. + wrapped_query_.QueryOnce(); } - // Drop the callback if the scheduler is unavailable, since this means - // PerformanceManager is being torn down so queries sent to the PM sequence - // would be dropped. + callbacks_.push_back(std::move(callback)); +} + +void ScopedCPUQuery::OnResourceUsageUpdated(const QueryResultMap& results) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + CHECK(!callbacks_.empty()); + for (ResultCallback& callback : callbacks_) { + std::move(callback).Run(results); + } + callbacks_.clear(); } } // namespace performance_manager::resource_attribution
diff --git a/components/performance_manager/test_support/BUILD.gn b/components/performance_manager/test_support/BUILD.gn index 9f2684a3..d3c3912 100644 --- a/components/performance_manager/test_support/BUILD.gn +++ b/components/performance_manager/test_support/BUILD.gn
@@ -48,6 +48,7 @@ "mock_graphs.h", "performance_manager_test_harness.cc", "performance_manager_test_harness.h", + "resource_attribution/gmock_matchers.h", "resource_attribution/simulated_cpu_measurement_delegate.cc", "resource_attribution/simulated_cpu_measurement_delegate.h", "test_worker_node_factory.cc",
diff --git a/components/performance_manager/test_support/mock_graphs_unittest.cc b/components/performance_manager/test_support/mock_graphs_unittest.cc index 3b181d6..10c8b7b9 100644 --- a/components/performance_manager/test_support/mock_graphs_unittest.cc +++ b/components/performance_manager/test_support/mock_graphs_unittest.cc
@@ -44,11 +44,11 @@ // Make sure the ProcessNodes have valid RenderProcessHostId's or // BrowserChildProcessHostId's. const RenderProcessHostProxy& process_proxy = - mock_graph.process->render_process_host_proxy(); + mock_graph.process->GetRenderProcessHostProxy(); const RenderProcessHostProxy& other_process_proxy = - mock_graph.other_process->render_process_host_proxy(); + mock_graph.other_process->GetRenderProcessHostProxy(); const BrowserChildProcessHostProxy& utility_process_proxy = - mock_graph.utility_process->browser_child_process_host_proxy(); + mock_graph.utility_process->GetBrowserChildProcessHostProxy(); EXPECT_FALSE(process_proxy.render_process_host_id().is_null()); EXPECT_FALSE(other_process_proxy.render_process_host_id().is_null()); EXPECT_NE(process_proxy.render_process_host_id(), @@ -59,7 +59,7 @@ const auto custom_process = TestNodeWrapper<TestProcessNodeImpl>::Create( graph(), content::ProcessType::PROCESS_TYPE_GPU); const BrowserChildProcessHostProxy& custom_process_proxy = - custom_process->browser_child_process_host_proxy(); + custom_process->GetBrowserChildProcessHostProxy(); EXPECT_FALSE(custom_process_proxy.browser_child_process_host_id().is_null()); EXPECT_NE(utility_process_proxy.browser_child_process_host_id(), custom_process_proxy.browser_child_process_host_id());
diff --git a/components/performance_manager/test_support/resource_attribution/gmock_matchers.h b/components/performance_manager/test_support/resource_attribution/gmock_matchers.h new file mode 100644 index 0000000..cb958aa7 --- /dev/null +++ b/components/performance_manager/test_support/resource_attribution/gmock_matchers.h
@@ -0,0 +1,37 @@ +// 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. + +#ifndef COMPONENTS_PERFORMANCE_MANAGER_TEST_SUPPORT_RESOURCE_ATTRIBUTION_GMOCK_MATCHERS_H_ +#define COMPONENTS_PERFORMANCE_MANAGER_TEST_SUPPORT_RESOURCE_ATTRIBUTION_GMOCK_MATCHERS_H_ + +#include "components/performance_manager/public/resource_attribution/query_results.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace performance_manager::resource_attribution { + +// GMock matcher expecting that a given QueryResultMap entry has a key of +// `resource_context` whose value contains a result of type ResultType. +// +// Usage: +// +// // Tests that the map contains `context1` and possibly other elements. +// EXPECT_THAT(result_map, ::testing::Contains( +// QueryResultMapEntryMatches<CPUTimeResult>(context1)); +// +// // Tests that the map contains exactly `context1` and `context2`. +// EXPECT_THAT(result_map, ::testing::UnorderedElementsAre( +// QueryResultMapEntryMatches<CPUTimeResult>(context1), +// QueryResultMapEntryMatches<CPUTimeResult>(context2)); +template <typename ResultType> +auto QueryResultMapEntryMatches(const ResourceContext& resource_context) { + return ::testing::Pair( + resource_context, + ::testing::ResultOf("contains correct QueryResult type", + ContainsResult<ResultType>, ::testing::IsTrue())); +} + +} // namespace performance_manager::resource_attribution + +#endif // COMPONENTS_PERFORMANCE_MANAGER_TEST_SUPPORT_RESOURCE_ATTRIBUTION_GMOCK_MATCHERS_H_
diff --git a/components/performance_manager/v8_memory/v8_context_tracker.cc b/components/performance_manager/v8_memory/v8_context_tracker.cc index 709095d..cebcbad 100644 --- a/components/performance_manager/v8_memory/v8_context_tracker.cc +++ b/components/performance_manager/v8_memory/v8_context_tracker.cc
@@ -277,9 +277,7 @@ }); // Posts |on_ui_thread| to the UI sequence. - auto rph_id = parent_frame_node->process_node() - ->render_process_host_proxy() - .render_process_host_id(); + auto rph_id = parent_frame_node->process_node()->GetRenderProcessHostId(); content::GetUIThreadTaskRunner({})->PostTask( FROM_HERE, base::BindOnce(std::move(on_ui_thread), std::move(on_pm_seq), std::move(data), rph_id));
diff --git a/components/performance_manager/worker_watcher_unittest.cc b/components/performance_manager/worker_watcher_unittest.cc index 1614947..a86d637 100644 --- a/components/performance_manager/worker_watcher_unittest.cc +++ b/components/performance_manager/worker_watcher_unittest.cc
@@ -829,7 +829,7 @@ client_frame_node = frame_node_source()->GetFrameNode( render_frame_host_id)](GraphImpl* graph) { EXPECT_TRUE(graph->NodeInGraph(worker_node)); - EXPECT_EQ(worker_node->worker_type(), + EXPECT_EQ(worker_node->GetWorkerType(), WorkerNode::WorkerType::kDedicated); EXPECT_EQ(worker_node->process_node(), process_node); EXPECT_TRUE(IsWorkerClient(worker_node, client_frame_node)); @@ -868,7 +868,8 @@ client_frame_node = frame_node_source()->GetFrameNode( render_frame_host_id)](GraphImpl* graph) { EXPECT_TRUE(graph->NodeInGraph(worker_node)); - EXPECT_EQ(worker_node->worker_type(), WorkerNode::WorkerType::kShared); + EXPECT_EQ(worker_node->GetWorkerType(), + WorkerNode::WorkerType::kShared); EXPECT_EQ(worker_node->process_node(), process_node); EXPECT_TRUE(IsWorkerClient(worker_node, client_frame_node)); })); @@ -908,7 +909,8 @@ process_node = process_node_source()->GetProcessNode(render_process_id), &token](GraphImpl* graph) { EXPECT_TRUE(graph->NodeInGraph(worker_node)); - EXPECT_EQ(worker_node->worker_type(), WorkerNode::WorkerType::kService); + EXPECT_EQ(worker_node->GetWorkerType(), + WorkerNode::WorkerType::kService); EXPECT_EQ(worker_node->process_node(), process_node); // The frame can not be connected to the service worker until its @@ -936,7 +938,8 @@ client_frame_node = frame_node_source()->GetFrameNode( render_frame_host_id)](GraphImpl* graph) { EXPECT_TRUE(graph->NodeInGraph(worker_node)); - EXPECT_EQ(worker_node->worker_type(), WorkerNode::WorkerType::kService); + EXPECT_EQ(worker_node->GetWorkerType(), + WorkerNode::WorkerType::kService); EXPECT_EQ(worker_node->process_node(), process_node); EXPECT_TRUE(IsWorkerClient(worker_node, client_frame_node)); })); @@ -985,14 +988,14 @@ second_worker_node = GetServiceWorkerNode( second_service_worker_version_id)](GraphImpl* graph) { EXPECT_TRUE(graph->NodeInGraph(first_worker_node)); - EXPECT_EQ(first_worker_node->worker_type(), + EXPECT_EQ(first_worker_node->GetWorkerType(), WorkerNode::WorkerType::kService); EXPECT_EQ(first_worker_node->process_node(), process_node); // The frame was never added as a client of the service worker. EXPECT_TRUE(first_worker_node->client_frames().empty()); EXPECT_TRUE(graph->NodeInGraph(second_worker_node)); - EXPECT_EQ(second_worker_node->worker_type(), + EXPECT_EQ(second_worker_node->GetWorkerType(), WorkerNode::WorkerType::kService); EXPECT_EQ(second_worker_node->process_node(), process_node); // The frame was never added as a client of the service worker. @@ -1036,7 +1039,8 @@ worker_node = GetServiceWorkerNode(service_worker_version_id)](GraphImpl* graph) { EXPECT_TRUE(graph->NodeInGraph(worker_node)); - EXPECT_EQ(worker_node->worker_type(), WorkerNode::WorkerType::kService); + EXPECT_EQ(worker_node->GetWorkerType(), + WorkerNode::WorkerType::kService); // The frame was not yet added as a client. EXPECT_TRUE(worker_node->client_frames().empty()); })); @@ -1059,7 +1063,7 @@ client_frame_node = frame_node_source()->GetFrameNode( render_frame_host_id)](GraphImpl* graph) { EXPECT_TRUE(graph->NodeInGraph(service_worker_node)); - EXPECT_EQ(service_worker_node->worker_type(), + EXPECT_EQ(service_worker_node->GetWorkerType(), WorkerNode::WorkerType::kService); EXPECT_EQ(1u, service_worker_node->client_frames().size()); EXPECT_TRUE(IsWorkerClient(service_worker_node, client_frame_node)); @@ -1075,7 +1079,7 @@ client_frame_node = frame_node_source()->GetFrameNode( render_frame_host_id)](GraphImpl* graph) { EXPECT_TRUE(graph->NodeInGraph(service_worker_node)); - EXPECT_EQ(service_worker_node->worker_type(), + EXPECT_EQ(service_worker_node->GetWorkerType(), WorkerNode::WorkerType::kService); EXPECT_EQ(1u, service_worker_node->client_frames().size()); EXPECT_TRUE(IsWorkerClient(service_worker_node, client_frame_node)); @@ -1091,7 +1095,7 @@ client_frame_node = frame_node_source()->GetFrameNode( render_frame_host_id)](GraphImpl* graph) { EXPECT_TRUE(graph->NodeInGraph(service_worker_node)); - EXPECT_EQ(service_worker_node->worker_type(), + EXPECT_EQ(service_worker_node->GetWorkerType(), WorkerNode::WorkerType::kService); EXPECT_EQ(1u, service_worker_node->client_frames().size()); EXPECT_TRUE(IsWorkerClient(service_worker_node, client_frame_node)); @@ -1126,7 +1130,8 @@ worker_node = GetServiceWorkerNode(service_worker_version_id)](GraphImpl* graph) { EXPECT_TRUE(graph->NodeInGraph(worker_node)); - EXPECT_EQ(worker_node->worker_type(), WorkerNode::WorkerType::kService); + EXPECT_EQ(worker_node->GetWorkerType(), + WorkerNode::WorkerType::kService); EXPECT_EQ(worker_node->process_node(), process_node); // The frame was never added as a client of the service worker. @@ -1283,7 +1288,7 @@ shared_worker_node = GetSharedWorkerNode(shared_worker_token)](GraphImpl* graph) { EXPECT_TRUE(graph->NodeInGraph(service_worker_node)); - EXPECT_EQ(service_worker_node->worker_type(), + EXPECT_EQ(service_worker_node->GetWorkerType(), WorkerNode::WorkerType::kService); EXPECT_EQ(service_worker_node->process_node(), process_node); @@ -1361,7 +1366,8 @@ client_frame_node = frame_node_source()->GetFrameNode( render_frame_host_id)](GraphImpl* graph) { EXPECT_TRUE(graph->NodeInGraph(worker_node)); - EXPECT_EQ(worker_node->worker_type(), WorkerNode::WorkerType::kShared); + EXPECT_EQ(worker_node->GetWorkerType(), + WorkerNode::WorkerType::kShared); EXPECT_EQ(worker_node->process_node(), worker_process_node); EXPECT_TRUE(IsWorkerClient(worker_node, client_frame_node)); })); @@ -1417,7 +1423,7 @@ service_worker_node = GetServiceWorkerNode(service_worker_version_id)](GraphImpl* graph) { EXPECT_TRUE(graph->NodeInGraph(service_worker_node)); - EXPECT_EQ(service_worker_node->worker_type(), + EXPECT_EQ(service_worker_node->GetWorkerType(), WorkerNode::WorkerType::kService); EXPECT_EQ(service_worker_node->process_node(), process_node); EXPECT_TRUE(service_worker_node->child_workers().empty()); @@ -1435,7 +1441,7 @@ service_worker_node = GetServiceWorkerNode(service_worker_version_id)](GraphImpl* graph) { EXPECT_TRUE(graph->NodeInGraph(service_worker_node)); - EXPECT_EQ(service_worker_node->worker_type(), + EXPECT_EQ(service_worker_node->GetWorkerType(), WorkerNode::WorkerType::kService); EXPECT_EQ(service_worker_node->process_node(), process_node); EXPECT_TRUE(service_worker_node->child_workers().empty()); @@ -1466,10 +1472,10 @@ shared_worker_node = GetSharedWorkerNode(shared_worker_token)](GraphImpl* graph) { EXPECT_TRUE(graph->NodeInGraph(service_worker_node)); - EXPECT_EQ(service_worker_node->worker_type(), + EXPECT_EQ(service_worker_node->GetWorkerType(), WorkerNode::WorkerType::kService); EXPECT_TRUE(graph->NodeInGraph(shared_worker_node)); - EXPECT_EQ(shared_worker_node->worker_type(), + EXPECT_EQ(shared_worker_node->GetWorkerType(), WorkerNode::WorkerType::kShared); EXPECT_TRUE(IsWorkerClient(service_worker_node, shared_worker_node)); })); @@ -1483,7 +1489,7 @@ [service_worker_node = GetServiceWorkerNode(service_worker_version_id)](GraphImpl* graph) { EXPECT_TRUE(graph->NodeInGraph(service_worker_node)); - EXPECT_EQ(service_worker_node->worker_type(), + EXPECT_EQ(service_worker_node->GetWorkerType(), WorkerNode::WorkerType::kService); EXPECT_TRUE(service_worker_node->client_workers().empty()); })); @@ -1523,7 +1529,8 @@ client_frame_node_2 = frame_node_source()->GetFrameNode( render_frame_host_id_2)](GraphImpl* graph) { EXPECT_TRUE(graph->NodeInGraph(worker_node)); - EXPECT_EQ(worker_node->worker_type(), WorkerNode::WorkerType::kShared); + EXPECT_EQ(worker_node->GetWorkerType(), + WorkerNode::WorkerType::kShared); // Check frame 1. EXPECT_TRUE(IsWorkerClient(worker_node, client_frame_node_1)); @@ -1568,13 +1575,13 @@ render_frame_host_id)](GraphImpl* graph) { // Check worker 1. EXPECT_TRUE(graph->NodeInGraph(worker_node_1)); - EXPECT_EQ(worker_node_1->worker_type(), + EXPECT_EQ(worker_node_1->GetWorkerType(), WorkerNode::WorkerType::kShared); EXPECT_TRUE(IsWorkerClient(worker_node_1, client_frame_node)); // Check worker 2. EXPECT_TRUE(graph->NodeInGraph(worker_node_2)); - EXPECT_EQ(worker_node_2->worker_type(), + EXPECT_EQ(worker_node_2->GetWorkerType(), WorkerNode::WorkerType::kShared); EXPECT_TRUE(IsWorkerClient(worker_node_2, client_frame_node)); }));
diff --git a/content/browser/loader/navigation_url_loader_impl.cc b/content/browser/loader/navigation_url_loader_impl.cc index 8a8c673..48cee47 100644 --- a/content/browser/loader/navigation_url_loader_impl.cc +++ b/content/browser/loader/navigation_url_loader_impl.cc
@@ -392,8 +392,8 @@ // because the two parsing results mismatch in this expected way. network::mojom::ParsedHeadersPtr adjusted_lhs = lhs->Clone(); if (rhs->client_hints_ignored_due_to_clear_site_data_header) { - DCHECK(!rhs->accept_ch); - DCHECK(!rhs->critical_ch); + CHECK(!rhs->accept_ch); + CHECK(!rhs->critical_ch); adjusted_lhs->accept_ch = absl::nullopt; adjusted_lhs->critical_ch = absl::nullopt; adjusted_lhs->client_hints_ignored_due_to_clear_site_data_header = true; @@ -401,29 +401,31 @@ if (mojo::Equals(adjusted_lhs, rhs)) { return; } - DCHECK(mojo::Equals(adjusted_lhs->content_security_policy, - rhs->content_security_policy)); - DCHECK(mojo::Equals(adjusted_lhs->allow_csp_from, rhs->allow_csp_from)); - DCHECK(mojo::Equals(adjusted_lhs->cross_origin_embedder_policy, - rhs->cross_origin_embedder_policy)); - DCHECK(mojo::Equals(adjusted_lhs->cross_origin_opener_policy, - rhs->cross_origin_opener_policy)); - DCHECK(mojo::Equals(adjusted_lhs->origin_agent_cluster, - rhs->origin_agent_cluster)); - DCHECK(mojo::Equals(adjusted_lhs->accept_ch, rhs->accept_ch)); - DCHECK(mojo::Equals(adjusted_lhs->critical_ch, rhs->critical_ch)); + CHECK(mojo::Equals(adjusted_lhs->content_security_policy, + rhs->content_security_policy)); + CHECK(mojo::Equals(adjusted_lhs->allow_csp_from, rhs->allow_csp_from)); + CHECK(mojo::Equals(adjusted_lhs->cross_origin_embedder_policy, + rhs->cross_origin_embedder_policy)); + CHECK(mojo::Equals(adjusted_lhs->cross_origin_opener_policy, + rhs->cross_origin_opener_policy)); + CHECK(mojo::Equals(adjusted_lhs->origin_agent_cluster, + rhs->origin_agent_cluster)); + CHECK(mojo::Equals(adjusted_lhs->accept_ch, rhs->accept_ch)); + CHECK(mojo::Equals(adjusted_lhs->critical_ch, rhs->critical_ch)); DCHECK_EQ(adjusted_lhs->xfo, rhs->xfo); - DCHECK(mojo::Equals(adjusted_lhs->link_headers, rhs->link_headers)); - DCHECK(mojo::Equals(adjusted_lhs->supports_loading_mode, - rhs->supports_loading_mode)); - DCHECK(mojo::Equals(adjusted_lhs->timing_allow_origin, - rhs->timing_allow_origin)); - DCHECK(mojo::Equals(adjusted_lhs->reporting_endpoints, - rhs->reporting_endpoints)); - DCHECK(mojo::Equals(adjusted_lhs->variants_headers, rhs->variants_headers)); - DCHECK(mojo::Equals(adjusted_lhs->content_language, rhs->content_language)); - DCHECK(mojo::Equals(adjusted_lhs->no_vary_search_with_parse_error, - rhs->no_vary_search_with_parse_error)); + CHECK(mojo::Equals(adjusted_lhs->link_headers, rhs->link_headers)); + CHECK(mojo::Equals(adjusted_lhs->timing_allow_origin, + rhs->timing_allow_origin)); + CHECK(mojo::Equals(adjusted_lhs->supports_loading_mode, + rhs->supports_loading_mode)); + CHECK(mojo::Equals(adjusted_lhs->reporting_endpoints, + rhs->reporting_endpoints)); + CHECK(mojo::Equals(adjusted_lhs->variants_headers, rhs->variants_headers)); + CHECK(mojo::Equals(adjusted_lhs->content_language, rhs->content_language)); + CHECK(mojo::Equals(adjusted_lhs->no_vary_search_with_parse_error, + rhs->no_vary_search_with_parse_error)); + CHECK(mojo::Equals(adjusted_lhs->observe_browsing_topics, + rhs->observe_browsing_topics)); NOTREACHED() << "The parsed headers don't match, but we don't know which " "field does not match. Please add a DCHECK before this one " "checking for the missing field.";
diff --git a/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt index 1d856dc..e8cef270 100644 --- a/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt +++ b/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt
@@ -358,7 +358,6 @@ # WebGPU interop fails -- pixel color diff crbug.com/1395227 [ amd-0x7340 no-clang-coverage release-x64 target-cpu-64 win ] Pixel_WebGPUImportVideoFrameUnaccelerated [ Failure ] -crbug.com/1395227 [ amd-0x7340 no-clang-coverage release-x64 target-cpu-64 win ] Pixel_WebGPUImportVideoFrameUnacceleratedOffscreenCanvas [ Failure ] crbug.com/1372144 [ android android-sm-a135m ] Pixel_CanvasDisplaySRGBAccelerated2D [ Failure ] crbug.com/1372144 [ android android-sm-a135m ] Pixel_CanvasLowLatencyWebGLAlphaFalse [ Failure ]
diff --git a/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt index daba339..c65ef47 100644 --- a/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt +++ b/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt
@@ -856,7 +856,6 @@ crbug.com/1492257 [ chromeos cros-chrome chromeos-board-jacuzzi ] conformance2/glsl3/tricky-loop-conditions.html [ Failure ] crbug.com/1492258 [ chromeos cros-chrome chromeos-board-jacuzzi ] conformance2/glsl3/uninitialized-local-global-variables.html [ Failure ] crbug.com/1492270 [ chromeos cros-chrome chromeos-board-jacuzzi ] conformance2/reading/read-pixels-pack-parameters.html [ Failure ] -crbug.com/1499514 [ chromeos cros-chrome chromeos-board-jacuzzi ] conformance/textures/webgl_canvas/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html [ RetryOnFailure ] crbug.com/1499516 [ chromeos cros-chrome chromeos-board-jacuzzi ] conformance2/transform_feedback/transform_feedback.html [ Failure ] crbug.com/1499523 [ chromeos cros-chrome chromeos-board-jacuzzi ] deqp/data/gles3/shaders/arrays.html [ Failure ] crbug.com/1499527 [ chromeos cros-chrome chromeos-board-jacuzzi ] deqp/functional/gles3/shadermatrix/inverse.html [ Failure ]
diff --git a/extensions/browser/content_verifier.cc b/extensions/browser/content_verifier.cc index f2c17a55..23dc9db 100644 --- a/extensions/browser/content_verifier.cc +++ b/extensions/browser/content_verifier.cc
@@ -18,7 +18,6 @@ #include "base/metrics/histogram_macros.h" #include "base/strings/string_util.h" #include "base/threading/thread_restrictions.h" -#include "base/timer/elapsed_timer.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/storage_partition.h" @@ -288,13 +287,10 @@ void Cancel() { cancelled_checker->Cancel(); } - base::TimeDelta elapsed() const { return elapsed_timer.Elapsed(); } - scoped_refptr<IsCancelledChecker> cancelled_checker; // TODO(lazyboy): Use std::list? std::vector<ContentHashCallback> callbacks; bool force_missing_computed_hashes_creation = false; - base::ElapsedTimer elapsed_timer; }; using IsCancelledCallback = base::RepeatingCallback<bool(void)>; @@ -387,8 +383,6 @@ auto iter = callback_infos_.find(key); DCHECK(iter != callback_infos_.end()); auto& callback_info = iter->second; - UMA_HISTOGRAM_TIMES("Extensions.ContentVerification.ReadContentHashTime", - callback_info.elapsed()); for (auto& callback : callback_info.callbacks) std::move(callback).Run(content_hash);
diff --git a/extensions/browser/content_verify_job.cc b/extensions/browser/content_verify_job.cc index 4df438f..52a6749c 100644 --- a/extensions/browser/content_verify_job.cc +++ b/extensions/browser/content_verify_job.cc
@@ -77,10 +77,7 @@ failure_callback_(std::move(failure_callback)), failed_(false) {} -ContentVerifyJob::~ContentVerifyJob() { - UMA_HISTOGRAM_COUNTS_1M("ExtensionContentVerifyJob.TimeSpentUS", - time_spent_.InMicroseconds()); -} +ContentVerifyJob::~ContentVerifyJob() = default; void ContentVerifyJob::Start(ContentVerifier* verifier) { DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
diff --git a/extensions/browser/sandboxed_unpacker.cc b/extensions/browser/sandboxed_unpacker.cc index a0cc5c1..ef9100a 100644 --- a/extensions/browser/sandboxed_unpacker.cc +++ b/extensions/browser/sandboxed_unpacker.cc
@@ -953,8 +953,6 @@ switch (result) { case crx_file::VerifierResult::OK_FULL: { - if (!expected_hash.empty()) - UMA_HISTOGRAM_BOOLEAN("Extensions.SandboxUnpackHashCheck", true); return true; } case crx_file::VerifierResult::OK_DELTA: @@ -989,7 +987,6 @@ // We should never get this result unless we had specifically asked for // verification of the crx file's hash. CHECK(!expected_hash.empty()); - UMA_HISTOGRAM_BOOLEAN("Extensions.SandboxUnpackHashCheck", false); FailWithPackageError( SandboxedUnpackerFailureReason::CRX_HASH_VERIFICATION_FAILED); break;
diff --git a/infra/config/generated/builders/try/android-arm64-siso-rel-compilator/properties.json b/infra/config/generated/builders/try/android-arm64-siso-rel-compilator/properties.json index 1f259fd..7bc03af2 100644 --- a/infra/config/generated/builders/try/android-arm64-siso-rel-compilator/properties.json +++ b/infra/config/generated/builders/try/android-arm64-siso-rel-compilator/properties.json
@@ -81,7 +81,8 @@ "builder": "android-pie-arm64-rel", "project": "chromium" } - ] + ], + "is_compile_only": true } }, "$build/code_coverage": {
diff --git a/infra/config/generated/builders/try/android-arm64-siso-rel/properties.json b/infra/config/generated/builders/try/android-arm64-siso-rel/properties.json index 98197e2..cc6c54d 100644 --- a/infra/config/generated/builders/try/android-arm64-siso-rel/properties.json +++ b/infra/config/generated/builders/try/android-arm64-siso-rel/properties.json
@@ -85,7 +85,8 @@ "builder": "android-pie-arm64-rel", "project": "chromium" } - ] + ], + "is_compile_only": true } }, "$build/code_coverage": {
diff --git a/infra/config/generated/cq-builders.md b/infra/config/generated/cq-builders.md index cda0db9..e0997ab 100644 --- a/infra/config/generated/cq-builders.md +++ b/infra/config/generated/cq-builders.md
@@ -595,7 +595,7 @@ ### chromium * [android-arm64-siso-rel](https://ci.chromium.org/p/chromium/builders/try/android-arm64-siso-rel) ([definition](https://cs.chromium.org/search?q=+file:/try/.*\.star$+""android-arm64-siso-rel"")) - * Experiment percentage: 5.0 + * Experiment percentage: 10.0 * [android-binary-size-siso](https://ci.chromium.org/p/chromium/builders/try/android-binary-size-siso) ([definition](https://cs.chromium.org/search?q=+file:/try/.*\.star$+""android-binary-size-siso"")) * Experiment percentage: 10.0
diff --git a/infra/config/generated/luci/commit-queue.cfg b/infra/config/generated/luci/commit-queue.cfg index b28ee267..15a8832 100644 --- a/infra/config/generated/luci/commit-queue.cfg +++ b/infra/config/generated/luci/commit-queue.cfg
@@ -507,7 +507,7 @@ } builders { name: "chromium/try/android-arm64-siso-rel" - experiment_percentage: 5 + experiment_percentage: 10 location_filters { gerrit_host_regexp: ".*" gerrit_project_regexp: ".*"
diff --git a/infra/config/generated/testing/variants.pyl b/infra/config/generated/testing/variants.pyl index 4c646e7..cef03f5 100644 --- a/infra/config/generated/testing/variants.pyl +++ b/infra/config/generated/testing/variants.pyl
@@ -70,16 +70,16 @@ }, 'LACROS_VERSION_SKEW_CANARY': { 'identifier': 'Lacros version skew testing ash canary', - 'description': 'Run with ash-chrome version 121.0.6135.0', + 'description': 'Run with ash-chrome version 121.0.6136.0', 'args': [ - '--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6135.0/test_ash_chrome', + '--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6136.0/test_ash_chrome', ], 'swarming': { 'cipd_packages': [ { 'cipd_package': 'chromium/testing/linux-ash-chromium/x86_64/ash.zip', - 'location': 'lacros_version_skew_tests_v121.0.6135.0', - 'revision': 'version:121.0.6135.0', + 'location': 'lacros_version_skew_tests_v121.0.6136.0', + 'revision': 'version:121.0.6136.0', }, ], }, @@ -620,7 +620,7 @@ 'identifier': 'EVE_PUBLIC_LKGM', 'skylab': { 'cros_board': 'eve', - 'cros_img': 'eve-public/R121-15681.0.0', + 'cros_img': 'eve-public/R121-15683.0.0', 'bucket': 'chromiumos-image-archive', 'dut_pool': 'chromium', 'public_builder': 'cros_test_platform_public', @@ -712,7 +712,7 @@ 'identifier': 'TROGDOR_PUBLIC_LKGM', 'skylab': { 'cros_board': 'trogdor', - 'cros_img': 'trogdor-public/R121-15681.0.0', + 'cros_img': 'trogdor-public/R121-15683.0.0', 'bucket': 'chromiumos-image-archive', }, }, @@ -720,7 +720,7 @@ 'identifier': 'OCTOPUS_PUBLIC_LKGM', 'skylab': { 'cros_board': 'octopus', - 'cros_img': 'octopus-public/R121-15681.0.0', + 'cros_img': 'octopus-public/R121-15683.0.0', 'bucket': 'chromiumos-image-archive', }, }, @@ -799,7 +799,7 @@ 'skylab': { 'cros_board': 'volteer', 'cros_model': 'voxel', - 'cros_img': 'volteer-public/R121-15681.0.0', + 'cros_img': 'volteer-public/R121-15683.0.0', 'bucket': 'chromiumos-image-archive', 'dut_pool': 'chromium', 'public_builder': 'cros_test_platform_public',
diff --git a/infra/config/subprojects/chromium/try/tryserver.chromium.android.star b/infra/config/subprojects/chromium/try/tryserver.chromium.android.star index 21fe10f..e0941f4 100644 --- a/infra/config/subprojects/chromium/try/tryserver.chromium.android.star +++ b/infra/config/subprojects/chromium/try/tryserver.chromium.android.star
@@ -199,12 +199,17 @@ This builder should be removed after migrating android-arm64-rel from Ninja to Siso. b/277863839 """, mirrors = builder_config.copy_from("try/android-arm64-rel"), + try_settings = builder_config.try_settings( + # TODO: b/294287964 - waiting test devices to be allocated to handle + # extra traffic. + is_compile_only = True, + ), compilator = "android-arm64-siso-rel-compilator", coverage_test_types = ["unit", "overall"], gn_args = "try/android-arm64-rel", main_list_view = "try", tryjob = try_.job( - experiment_percentage = 5, + experiment_percentage = 10, ), use_clang_coverage = True, )
diff --git a/infra/config/targets/cros-skylab-variants.json b/infra/config/targets/cros-skylab-variants.json index 7f5d0741..f8f01f8 100644 --- a/infra/config/targets/cros-skylab-variants.json +++ b/infra/config/targets/cros-skylab-variants.json
@@ -201,8 +201,8 @@ "CROS_EVE_PUBLIC_LKGM": { "skylab": { "cros_board": "eve", - "cros_chrome_version": "121.0.6126.0", - "cros_img": "eve-public/R121-15681.0.0", + "cros_chrome_version": "121.0.6136.0", + "cros_img": "eve-public/R121-15683.0.0", "bucket": "chromiumos-image-archive", "dut_pool": "chromium", "public_builder": "cros_test_platform_public", @@ -313,8 +313,8 @@ "CROS_TROGDOR_PUBLIC_LKGM": { "skylab": { "cros_board": "trogdor", - "cros_chrome_version": "121.0.6126.0", - "cros_img": "trogdor-public/R121-15681.0.0", + "cros_chrome_version": "121.0.6136.0", + "cros_img": "trogdor-public/R121-15683.0.0", "bucket": "chromiumos-image-archive" }, "enabled": true, @@ -323,8 +323,8 @@ "CROS_OCTOPUS_PUBLIC_LKGM": { "skylab": { "cros_board": "octopus", - "cros_chrome_version": "121.0.6126.0", - "cros_img": "octopus-public/R121-15681.0.0", + "cros_chrome_version": "121.0.6136.0", + "cros_img": "octopus-public/R121-15683.0.0", "bucket": "chromiumos-image-archive" }, "enabled": true, @@ -418,8 +418,8 @@ "skylab": { "cros_board": "volteer", "cros_model": "voxel", - "cros_chrome_version": "121.0.6126.0", - "cros_img": "volteer-public/R121-15681.0.0", + "cros_chrome_version": "121.0.6136.0", + "cros_img": "volteer-public/R121-15683.0.0", "bucket": "chromiumos-image-archive", "dut_pool": "chromium", "public_builder": "cros_test_platform_public",
diff --git a/infra/config/targets/lacros-version-skew-variants.json b/infra/config/targets/lacros-version-skew-variants.json index f6d4d74..70ed284 100644 --- a/infra/config/targets/lacros-version-skew-variants.json +++ b/infra/config/targets/lacros-version-skew-variants.json
@@ -1,16 +1,16 @@ { "LACROS_VERSION_SKEW_CANARY": { "args": [ - "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6135.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6136.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 121.0.6135.0", + "description": "Run with ash-chrome version 121.0.6136.0", "identifier": "Lacros version skew testing ash canary", "swarming": { "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v121.0.6135.0", - "revision": "version:121.0.6135.0" + "location": "lacros_version_skew_tests_v121.0.6136.0", + "revision": "version:121.0.6136.0" } ] }
diff --git a/internal b/internal index f68388b..2263269 160000 --- a/internal +++ b/internal
@@ -1 +1 @@ -Subproject commit f68388b45b21d640b546f3d9d7db07836f1eb45c +Subproject commit 226326934fb1466c7a57898dbd24c922e173702c
diff --git a/ios/chrome/app/strings/resources/ios_strings_fa.xtb b/ios/chrome/app/strings/resources/ios_strings_fa.xtb index d86dfce..febc7d0 100644 --- a/ios/chrome/app/strings/resources/ios_strings_fa.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_fa.xtb
@@ -733,6 +733,7 @@ <translation id="4856841893565072365">نوار منو مرتبسازی هوشمند</translation> <translation id="4860895144060829044">تماس</translation> <translation id="4881695831933465202">باز کردن</translation> +<translation id="4883824756452868502">شناسایی واحدها</translation> <translation id="488785315393301722">نمایش جزئیات</translation> <translation id="4894963374040315706">با این اجازه میتوانید با صدایتان جستجو کنید</translation> <translation id="489903206070130262">آخرین برگه باز</translation> @@ -855,8 +856,10 @@ <translation id="5551897871312988470">پیشنهاد برای ترجمه</translation> <translation id="5556459405103347317">بار کردن مجدد</translation> <translation id="555749644339804659">درحال بررسی گذرواژهها…</translation> +<translation id="5559567453458728487">تبدیل واحدهای اندازهگیری پیداشده در وب</translation> <translation id="556042886152191864">دکمه</translation> <translation id="5572684875078967866">ذخیرهسازی اطلاعات</translation> +<translation id="5591792606924434384">{COUNT,plural, =1{پیگیری این بسته}one{پیگیری همه بستهها}other{پیگیری همه بستهها}}</translation> <translation id="5597915316964418992">باز کردن شبکه برگه</translation> <translation id="560322036295180549">سازمانتان آن را خاموش کرده است.</translation> <translation id="5614553682702429503">گذرواژه ذخیره شود؟</translation> @@ -1119,6 +1122,7 @@ <translation id="6781260999953472352">«همگامسازی» روشن شود؟</translation> <translation id="6781405765516175232">برای گزینههای مسیر، روی «دریافت مسیر» ضربه بزنید.</translation> <translation id="6785453220513215166">در حال ارسال گزارش خرابی...</translation> +<translation id="6788698206356268539">{COUNT,plural, =1{لغو پیگیری این بسته}one{لغو پیگیری همه بستهها}other{لغو پیگیری همه بستهها}}</translation> <translation id="6790502149545262384">بهزودی وقتی برگه جدیدی باز میکنید، داستانهایی از <ph name="CHANNEL_NAME" /> خواهید دید.</translation> <translation id="6797885426782475225">جستجوی گفتاری</translation> <translation id="6800349425672670802">از «تعویضکننده برگه» میتوانید به همه برگههای باز خود دسترسی داشته باشید.</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_sl.xtb b/ios/chrome/app/strings/resources/ios_strings_sl.xtb index 70636cc..450bff4 100644 --- a/ios/chrome/app/strings/resources/ios_strings_sl.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_sl.xtb
@@ -733,6 +733,7 @@ <translation id="4856841893565072365">Menijska vrstica za pametno razvrščanje</translation> <translation id="4860895144060829044">Pokličite</translation> <translation id="4881695831933465202">Odpri</translation> +<translation id="4883824756452868502">Zaznavanje enot</translation> <translation id="488785315393301722">Pokaži podrobnosti</translation> <translation id="4894963374040315706">To vam omogoča iskanje z glasom.</translation> <translation id="489903206070130262">Zadnji odprti zavihek</translation> @@ -855,8 +856,10 @@ <translation id="5551897871312988470">Ponudi prevajanje</translation> <translation id="5556459405103347317">Znova naloži</translation> <translation id="555749644339804659">Preverjanje gesel …</translation> +<translation id="5559567453458728487">Pretvorba merskih enot, najdenih v spletu</translation> <translation id="556042886152191864">Gumb</translation> <translation id="5572684875078967866">Količina podatkov</translation> +<translation id="5591792606924434384">{COUNT,plural, =1{Sledi temu paketu}one{Sledi vsem paketom}two{Sledi vsem paketom}few{Sledi vsem paketom}other{Sledi vsem paketom}}</translation> <translation id="5597915316964418992">Odprite mrežo zavihkov</translation> <translation id="560322036295180549">Izklopila organizacija.</translation> <translation id="5614553682702429503">Želite shraniti geslo?</translation> @@ -1119,6 +1122,7 @@ <translation id="6781260999953472352">Želite vklopiti sinhronizacijo?</translation> <translation id="6781405765516175232">Če želite možnosti poti, se dotaknite možnosti »Get Directions« (Navodila za pot).</translation> <translation id="6785453220513215166">Pošiljanje poročila o zrušitvi ...</translation> +<translation id="6788698206356268539">{COUNT,plural, =1{Prekliči sledenje temu paketu}one{Prekliči sledenje vsem paketom}two{Prekliči sledenje vsem paketom}few{Prekliči sledenje vsem paketom}other{Prekliči sledenje vsem paketom}}</translation> <translation id="6790502149545262384">Kmalu bodo prikazane novice s spletnega mesta <ph name="CHANNEL_NAME" />, ko boste odprli nov zavihek.</translation> <translation id="6797885426782475225">Glasovno iskanje</translation> <translation id="6800349425672670802">Do vseh odprtih zavihkov lahko dostopate s preklopom med zavihki.</translation>
diff --git a/ios_internal b/ios_internal index 5668f2d..eb61322 160000 --- a/ios_internal +++ b/ios_internal
@@ -1 +1 @@ -Subproject commit 5668f2d0e7ec4291e224096e8dbe8ea636e698a4 +Subproject commit eb61322a92140850bf94cb6e7a2511743c80ade5
diff --git a/media/mojo/services/BUILD.gn b/media/mojo/services/BUILD.gn index 778b1b9b..f7eea73 100644 --- a/media/mojo/services/BUILD.gn +++ b/media/mojo/services/BUILD.gn
@@ -329,9 +329,10 @@ "//base", "//base/test:test_support", "//components/leveldb_proto:test_support", - "//content/public/browser", "//media", "//media/capabilities:webrtc_video_stats_proto", + "//third_party/blink/public:blink", + "//third_party/blink/public/common", "//third_party/libprotobuf-mutator", ] }
diff --git a/net/base/transport_info.cc b/net/base/transport_info.cc index 73c70f07..8ed9479 100644 --- a/net/base/transport_info.cc +++ b/net/base/transport_info.cc
@@ -36,10 +36,12 @@ TransportInfo::TransportInfo(TransportType type_arg, IPEndPoint endpoint_arg, - std::string accept_ch_frame_arg) + std::string accept_ch_frame_arg, + bool cert_is_issued_by_known_root) : type(type_arg), endpoint(std::move(endpoint_arg)), - accept_ch_frame(std::move(accept_ch_frame_arg)) { + accept_ch_frame(std::move(accept_ch_frame_arg)), + cert_is_issued_by_known_root(cert_is_issued_by_known_root) { switch (type) { case TransportType::kCached: case TransportType::kCachedFromProxy: @@ -58,14 +60,7 @@ TransportInfo::~TransportInfo() = default; -bool TransportInfo::operator==(const TransportInfo& other) const { - return type == other.type && endpoint == other.endpoint && - accept_ch_frame == other.accept_ch_frame; -} - -bool TransportInfo::operator!=(const TransportInfo& other) const { - return !(*this == other); -} +bool TransportInfo::operator==(const TransportInfo& other) const = default; std::string TransportInfo::ToString() const { return base::StrCat({ @@ -75,6 +70,8 @@ endpoint.ToString(), ", accept_ch_frame = ", accept_ch_frame, + ", cert_is_issued_by_known_root = ", + cert_is_issued_by_known_root ? "true" : "false", " }", }); }
diff --git a/net/base/transport_info.h b/net/base/transport_info.h index dcc2e80a..3608a17 100644 --- a/net/base/transport_info.h +++ b/net/base/transport_info.h
@@ -35,13 +35,13 @@ TransportInfo(); TransportInfo(TransportType type_arg, IPEndPoint endpoint_arg, - std::string accept_ch_frame_arg); + std::string accept_ch_frame_arg, + bool cert_is_issued_by_known_root); TransportInfo(const TransportInfo&); ~TransportInfo(); // Instances of this type are comparable for equality. bool operator==(const TransportInfo& other) const; - bool operator!=(const TransportInfo& other) const; // Returns a string representation of this struct, suitable for debugging. std::string ToString() const; @@ -62,6 +62,13 @@ // Invariant: if `type` is `kCached` or `kCachedFromProxy`, then this is // empty. std::string accept_ch_frame; + + // True if the transport layer was secure and the certificate was rooted at a + // standard CA root. (As opposed to a user-installed root.) + // + // Invariant: if `type` is `kCached` or `kCachedFromProxy`, then this is + // always false. + bool cert_is_issued_by_known_root = false; }; // Instances of these types are streamable for easier debugging.
diff --git a/net/http/http_basic_stream.cc b/net/http/http_basic_stream.cc index 429c89e..a124097 100644 --- a/net/http/http_basic_stream.cc +++ b/net/http/http_basic_stream.cc
@@ -163,11 +163,10 @@ } void HttpBasicStream::GetSSLInfo(SSLInfo* ssl_info) { - if (!state_.connection()->socket()) { + if (!state_.connection()->socket() || + !state_.connection()->socket()->GetSSLInfo(ssl_info)) { ssl_info->Reset(); - return; } - parser()->GetSSLInfo(ssl_info); } void HttpBasicStream::GetSSLCertRequestInfo(
diff --git a/net/http/http_cache_transaction.cc b/net/http/http_cache_transaction.cc index 8b5581c..2dc6a81 100644 --- a/net/http/http_cache_transaction.cc +++ b/net/http/http_cache_transaction.cc
@@ -3218,7 +3218,9 @@ auto type = response_.was_fetched_via_proxy ? TransportType::kCachedFromProxy : TransportType::kCached; return connected_callback_.Run( - TransportInfo(type, response_.remote_endpoint, ""), io_callback_); + TransportInfo(type, response_.remote_endpoint, /*accept_ch_frame_arg=*/"", + /*cert_is_issued_by_known_root=*/false), + io_callback_); } int HttpCache::Transaction::DoConnectedCallbackComplete(int result) {
diff --git a/net/http/http_network_transaction.cc b/net/http/http_network_transaction.cc index 8c8dddf..53de7c2 100644 --- a/net/http/http_network_transaction.cc +++ b/net/http/http_network_transaction.cc
@@ -981,9 +981,19 @@ if (!proxy_info_.is_direct()) { type = TransportType::kProxied; } + + bool is_issued_by_known_root = false; + if (IsSecureRequest()) { + SSLInfo ssl_info; + CHECK(stream_); + stream_->GetSSLInfo(&ssl_info); + is_issued_by_known_root = ssl_info.is_issued_by_known_root; + } + return connected_callback_.Run( TransportInfo(type, remote_endpoint_, - std::string{stream_->GetAcceptChViaAlps()}), + std::string{stream_->GetAcceptChViaAlps()}, + is_issued_by_known_root), base::BindOnce(&HttpNetworkTransaction::ResumeAfterConnected, base::Unretained(this))); }
diff --git a/net/http/http_stream_parser.cc b/net/http/http_stream_parser.cc index bbb365d..380216a 100644 --- a/net/http/http_stream_parser.cc +++ b/net/http/http_stream_parser.cc
@@ -1137,13 +1137,6 @@ stream_socket_ = nullptr; } -void HttpStreamParser::GetSSLInfo(SSLInfo* ssl_info) { - if (!request_->url.SchemeIsCryptographic() || - !stream_socket_->GetSSLInfo(ssl_info)) { - ssl_info->Reset(); - } -} - void HttpStreamParser::GetSSLCertRequestInfo( SSLCertRequestInfo* cert_request_info) { cert_request_info->Reset();
diff --git a/net/http/http_stream_parser.h b/net/http/http_stream_parser.h index f5965ac..c8e56124 100644 --- a/net/http/http_stream_parser.h +++ b/net/http/http_stream_parser.h
@@ -34,7 +34,6 @@ class HttpResponseInfo; class IOBuffer; class SSLCertRequestInfo; -class SSLInfo; class StreamSocket; class UploadDataStream; @@ -110,8 +109,6 @@ } base::TimeTicks first_early_hints_time() { return first_early_hints_time_; } - void GetSSLInfo(SSLInfo* ssl_info); - void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info); // Encodes the given |payload| in the chunked format to |output|.
diff --git a/net/http/http_transaction_test_util.cc b/net/http/http_transaction_test_util.cc index 4a4ecea..eb07ea5d 100644 --- a/net/http/http_transaction_test_util.cc +++ b/net/http/http_transaction_test_util.cc
@@ -45,7 +45,9 @@ TransportInfo DefaultTransportInfo() { return TransportInfo(TransportType::kDirect, - IPEndPoint(IPAddress::IPv4Localhost(), 80), ""); + IPEndPoint(IPAddress::IPv4Localhost(), 80), + /*accept_ch_frame_arg=*/"", + /*cert_is_issued_by_known_root=*/false); } //-----------------------------------------------------------------------------
diff --git a/net/http/transport_security_state_static.pins b/net/http/transport_security_state_static.pins index 571cc1100..314377dc 100644 --- a/net/http/transport_security_state_static.pins +++ b/net/http/transport_security_state_static.pins
@@ -43,9 +43,9 @@ # hash function for preloaded entries again (we have already done so once). # -# Last updated: 2023-11-18 12:56 UTC +# Last updated: 2023-11-19 12:54 UTC PinsListTimestamp -1700312178 +1700398496 TestSPKI sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
diff --git a/net/http/transport_security_state_static_pins.json b/net/http/transport_security_state_static_pins.json index d6579b9..6c3c4cc2 100644 --- a/net/http/transport_security_state_static_pins.json +++ b/net/http/transport_security_state_static_pins.json
@@ -31,7 +31,7 @@ // the 'static_spki_hashes' and 'bad_static_spki_hashes' fields in 'pinsets' // refer to, and the timestamp at which the pins list was last updated. // -// Last updated: 2023-11-18 12:56 UTC +// Last updated: 2023-11-19 12:54 UTC // { "pinsets": [
diff --git a/net/websockets/websocket_basic_handshake_stream.cc b/net/websockets/websocket_basic_handshake_stream.cc index ad014d8f..d8c018b 100644 --- a/net/websockets/websocket_basic_handshake_stream.cc +++ b/net/websockets/websocket_basic_handshake_stream.cc
@@ -352,11 +352,10 @@ } void WebSocketBasicHandshakeStream::GetSSLInfo(SSLInfo* ssl_info) { - if (!state_.connection()->socket()) { + if (!state_.connection()->socket() || + !state_.connection()->socket()->GetSSLInfo(ssl_info)) { ssl_info->Reset(); - return; } - parser()->GetSSLInfo(ssl_info); } void WebSocketBasicHandshakeStream::GetSSLCertRequestInfo(
diff --git a/services/network/private_network_access_checker_unittest.cc b/services/network/private_network_access_checker_unittest.cc index 09d32634..122c504c 100644 --- a/services/network/private_network_access_checker_unittest.cc +++ b/services/network/private_network_access_checker_unittest.cc
@@ -55,22 +55,26 @@ net::TransportInfo DirectTransport(const net::IPEndPoint& endpoint) { return net::TransportInfo(net::TransportType::kDirect, endpoint, - kNoAcceptChFrame); + kNoAcceptChFrame, + /*cert_is_issued_by_known_root=*/false); } net::TransportInfo ProxiedTransport(const net::IPEndPoint& endpoint) { return net::TransportInfo(net::TransportType::kProxied, endpoint, - kNoAcceptChFrame); + kNoAcceptChFrame, + /*cert_is_issued_by_known_root=*/false); } net::TransportInfo CachedTransport(const net::IPEndPoint& endpoint) { return net::TransportInfo(net::TransportType::kCached, endpoint, - kNoAcceptChFrame); + kNoAcceptChFrame, + /*cert_is_issued_by_known_root=*/false); } net::TransportInfo MakeTransport(net::TransportType type, const net::IPEndPoint& endpoint) { - return net::TransportInfo(type, endpoint, kNoAcceptChFrame); + return net::TransportInfo(type, endpoint, kNoAcceptChFrame, + /*cert_is_issued_by_known_root=*/false); } TEST(PrivateNetworkAccessCheckerTest, ClientSecurityStateNull) {
diff --git a/services/network/public/mojom/parsed_headers.mojom b/services/network/public/mojom/parsed_headers.mojom index 3d948a3e..338cd94 100644 --- a/services/network/public/mojom/parsed_headers.mojom +++ b/services/network/public/mojom/parsed_headers.mojom
@@ -129,4 +129,6 @@ // The parsed value of the Observe-Browsing-Topics header. See: // https://patcg-individual-drafts.github.io/topics/#the-observe-browsing-topics-http-response-header-header bool observe_browsing_topics; + + // Please update `CheckParsedHeadersEquals` after adding new fields. };
diff --git a/services/network/url_loader_unittest.cc b/services/network/url_loader_unittest.cc index b3d9214..8444d0c 100644 --- a/services/network/url_loader_unittest.cc +++ b/services/network/url_loader_unittest.cc
@@ -2182,7 +2182,9 @@ static net::TransportInfo FakeTransportInfo( const URLLoaderFakeTransportInfoTestParams& params) { return net::TransportInfo(params.transport_type, - FakeEndpoint(params.endpoint_address_space), ""); + FakeEndpoint(params.endpoint_address_space), + /*accept_ch_frame_arg=*/"", + /*cert_is_issued_by_known_root=*/false); } };
diff --git a/testing/buildbot/chromium.chromiumos.json b/testing/buildbot/chromium.chromiumos.json index 61502be..696c444e1 100644 --- a/testing/buildbot/chromium.chromiumos.json +++ b/testing/buildbot/chromium.chromiumos.json
@@ -2168,7 +2168,7 @@ "autotest_name": "chromium", "bucket": "chromiumos-image-archive", "cros_board": "volteer", - "cros_img": "volteer-public/R121-15681.0.0", + "cros_img": "volteer-public/R121-15683.0.0", "cros_model": "voxel", "dut_pool": "chromium", "name": "chromeos_integration_tests VOLTEER_PUBLIC_LKGM", @@ -2182,7 +2182,7 @@ "autotest_name": "tast.lacros-from-gcs", "bucket": "chromiumos-image-archive", "cros_board": "volteer", - "cros_img": "volteer-public/R121-15681.0.0", + "cros_img": "volteer-public/R121-15683.0.0", "cros_model": "voxel", "dut_pool": "chromium", "name": "lacros_all_tast_tests VOLTEER_PUBLIC_LKGM", @@ -2566,7 +2566,7 @@ "autotest_name": "tast.lacros-from-gcs", "bucket": "chromiumos-image-archive", "cros_board": "trogdor", - "cros_img": "trogdor-public/R121-15681.0.0", + "cros_img": "trogdor-public/R121-15683.0.0", "name": "lacros_all_tast_tests TROGDOR_PUBLIC_LKGM", "resultdb": { "enable": true, @@ -6093,9 +6093,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6135.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6136.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 121.0.6135.0", + "description": "Run with ash-chrome version 121.0.6136.0", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -6105,8 +6105,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v121.0.6135.0", - "revision": "version:121.0.6135.0" + "location": "lacros_version_skew_tests_v121.0.6136.0", + "revision": "version:121.0.6136.0" } ], "dimensions": { @@ -6243,9 +6243,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.filter;../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6135.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6136.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 121.0.6135.0", + "description": "Run with ash-chrome version 121.0.6136.0", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -6255,8 +6255,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v121.0.6135.0", - "revision": "version:121.0.6135.0" + "location": "lacros_version_skew_tests_v121.0.6136.0", + "revision": "version:121.0.6136.0" } ], "dimensions": {
diff --git a/testing/buildbot/chromium.coverage.json b/testing/buildbot/chromium.coverage.json index 04ebecd..08ca59a 100644 --- a/testing/buildbot/chromium.coverage.json +++ b/testing/buildbot/chromium.coverage.json
@@ -20442,9 +20442,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6135.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6136.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 121.0.6135.0", + "description": "Run with ash-chrome version 121.0.6136.0", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -20454,8 +20454,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v121.0.6135.0", - "revision": "version:121.0.6135.0" + "location": "lacros_version_skew_tests_v121.0.6136.0", + "revision": "version:121.0.6136.0" } ], "dimensions": { @@ -20592,9 +20592,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.filter;../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6135.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6136.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 121.0.6135.0", + "description": "Run with ash-chrome version 121.0.6136.0", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -20604,8 +20604,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v121.0.6135.0", - "revision": "version:121.0.6135.0" + "location": "lacros_version_skew_tests_v121.0.6136.0", + "revision": "version:121.0.6136.0" } ], "dimensions": {
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json index 929916f..43104c8 100644 --- a/testing/buildbot/chromium.fyi.json +++ b/testing/buildbot/chromium.fyi.json
@@ -41233,7 +41233,7 @@ "autotest_name": "tast.lacros-from-gcs", "bucket": "chromiumos-image-archive", "cros_board": "eve", - "cros_img": "eve-public/R121-15681.0.0", + "cros_img": "eve-public/R121-15683.0.0", "dut_pool": "chromium", "name": "lacros_all_tast_tests EVE_PUBLIC_LKGM", "public_builder": "cros_test_platform_public", @@ -41254,7 +41254,7 @@ "autotest_name": "tast.lacros-from-gcs", "bucket": "chromiumos-image-archive", "cros_board": "octopus", - "cros_img": "octopus-public/R121-15681.0.0", + "cros_img": "octopus-public/R121-15683.0.0", "name": "lacros_all_tast_tests OCTOPUS_PUBLIC_LKGM", "resultdb": { "enable": true, @@ -41297,7 +41297,7 @@ "autotest_name": "tast.lacros-from-gcs", "bucket": "chromiumos-image-archive", "cros_board": "trogdor", - "cros_img": "trogdor-public/R121-15681.0.0", + "cros_img": "trogdor-public/R121-15683.0.0", "name": "lacros_all_tast_tests TROGDOR_PUBLIC_LKGM", "resultdb": { "enable": true, @@ -41360,7 +41360,7 @@ "autotest_name": "tast.lacros-from-gcs", "bucket": "chromiumos-image-archive", "cros_board": "trogdor", - "cros_img": "trogdor-public/R121-15681.0.0", + "cros_img": "trogdor-public/R121-15683.0.0", "name": "lacros_all_tast_tests TROGDOR_PUBLIC_LKGM", "resultdb": { "enable": true, @@ -43585,9 +43585,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6135.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6136.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 121.0.6135.0", + "description": "Run with ash-chrome version 121.0.6136.0", "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -43596,8 +43596,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v121.0.6135.0", - "revision": "version:121.0.6135.0" + "location": "lacros_version_skew_tests_v121.0.6136.0", + "revision": "version:121.0.6136.0" } ], "dimensions": { @@ -43735,9 +43735,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.filter;../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6135.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6136.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 121.0.6135.0", + "description": "Run with ash-chrome version 121.0.6136.0", "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -43746,8 +43746,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v121.0.6135.0", - "revision": "version:121.0.6135.0" + "location": "lacros_version_skew_tests_v121.0.6136.0", + "revision": "version:121.0.6136.0" } ], "dimensions": { @@ -45044,9 +45044,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6135.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6136.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 121.0.6135.0", + "description": "Run with ash-chrome version 121.0.6136.0", "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -45055,8 +45055,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v121.0.6135.0", - "revision": "version:121.0.6135.0" + "location": "lacros_version_skew_tests_v121.0.6136.0", + "revision": "version:121.0.6136.0" } ], "dimensions": { @@ -45194,9 +45194,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.filter;../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6135.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6136.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 121.0.6135.0", + "description": "Run with ash-chrome version 121.0.6136.0", "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -45205,8 +45205,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v121.0.6135.0", - "revision": "version:121.0.6135.0" + "location": "lacros_version_skew_tests_v121.0.6136.0", + "revision": "version:121.0.6136.0" } ], "dimensions": { @@ -45889,9 +45889,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6135.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6136.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 121.0.6135.0", + "description": "Run with ash-chrome version 121.0.6136.0", "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -45900,8 +45900,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v121.0.6135.0", - "revision": "version:121.0.6135.0" + "location": "lacros_version_skew_tests_v121.0.6136.0", + "revision": "version:121.0.6136.0" } ], "dimensions": {
diff --git a/testing/buildbot/chromium.memory.json b/testing/buildbot/chromium.memory.json index 3ef9afb..89c6722 100644 --- a/testing/buildbot/chromium.memory.json +++ b/testing/buildbot/chromium.memory.json
@@ -16151,12 +16151,12 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6135.0/test_ash_chrome", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6136.0/test_ash_chrome", "--test-launcher-print-test-stdio=always", "--combine-ash-logs-on-bots", "--asan-symbolize-output" ], - "description": "Run with ash-chrome version 121.0.6135.0", + "description": "Run with ash-chrome version 121.0.6136.0", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -16166,8 +16166,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v121.0.6135.0", - "revision": "version:121.0.6135.0" + "location": "lacros_version_skew_tests_v121.0.6136.0", + "revision": "version:121.0.6136.0" } ], "dimensions": { @@ -16321,12 +16321,12 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.filter;../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6135.0/test_ash_chrome", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6136.0/test_ash_chrome", "--test-launcher-print-test-stdio=always", "--combine-ash-logs-on-bots", "--asan-symbolize-output" ], - "description": "Run with ash-chrome version 121.0.6135.0", + "description": "Run with ash-chrome version 121.0.6136.0", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -16336,8 +16336,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v121.0.6135.0", - "revision": "version:121.0.6135.0" + "location": "lacros_version_skew_tests_v121.0.6136.0", + "revision": "version:121.0.6136.0" } ], "dimensions": {
diff --git a/testing/buildbot/tryserver.chromium.chromiumos.json b/testing/buildbot/tryserver.chromium.chromiumos.json index e6a43d9..277dff1 100644 --- a/testing/buildbot/tryserver.chromium.chromiumos.json +++ b/testing/buildbot/tryserver.chromium.chromiumos.json
@@ -10,7 +10,7 @@ "autotest_name": "chromium", "bucket": "chromiumos-image-archive", "cros_board": "volteer", - "cros_img": "volteer-public/R121-15681.0.0", + "cros_img": "volteer-public/R121-15683.0.0", "cros_model": "voxel", "dut_pool": "chromium", "name": "chromeos_integration_tests VOLTEER_PUBLIC_LKGM", @@ -24,7 +24,7 @@ "autotest_name": "tast.lacros-from-gcs", "bucket": "chromiumos-image-archive", "cros_board": "volteer", - "cros_img": "volteer-public/R121-15681.0.0", + "cros_img": "volteer-public/R121-15683.0.0", "cros_model": "voxel", "dut_pool": "chromium", "name": "lacros_all_tast_tests VOLTEER_PUBLIC_LKGM",
diff --git a/testing/buildbot/variants.pyl b/testing/buildbot/variants.pyl index 4c646e7..cef03f5 100644 --- a/testing/buildbot/variants.pyl +++ b/testing/buildbot/variants.pyl
@@ -70,16 +70,16 @@ }, 'LACROS_VERSION_SKEW_CANARY': { 'identifier': 'Lacros version skew testing ash canary', - 'description': 'Run with ash-chrome version 121.0.6135.0', + 'description': 'Run with ash-chrome version 121.0.6136.0', 'args': [ - '--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6135.0/test_ash_chrome', + '--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6136.0/test_ash_chrome', ], 'swarming': { 'cipd_packages': [ { 'cipd_package': 'chromium/testing/linux-ash-chromium/x86_64/ash.zip', - 'location': 'lacros_version_skew_tests_v121.0.6135.0', - 'revision': 'version:121.0.6135.0', + 'location': 'lacros_version_skew_tests_v121.0.6136.0', + 'revision': 'version:121.0.6136.0', }, ], }, @@ -620,7 +620,7 @@ 'identifier': 'EVE_PUBLIC_LKGM', 'skylab': { 'cros_board': 'eve', - 'cros_img': 'eve-public/R121-15681.0.0', + 'cros_img': 'eve-public/R121-15683.0.0', 'bucket': 'chromiumos-image-archive', 'dut_pool': 'chromium', 'public_builder': 'cros_test_platform_public', @@ -712,7 +712,7 @@ 'identifier': 'TROGDOR_PUBLIC_LKGM', 'skylab': { 'cros_board': 'trogdor', - 'cros_img': 'trogdor-public/R121-15681.0.0', + 'cros_img': 'trogdor-public/R121-15683.0.0', 'bucket': 'chromiumos-image-archive', }, }, @@ -720,7 +720,7 @@ 'identifier': 'OCTOPUS_PUBLIC_LKGM', 'skylab': { 'cros_board': 'octopus', - 'cros_img': 'octopus-public/R121-15681.0.0', + 'cros_img': 'octopus-public/R121-15683.0.0', 'bucket': 'chromiumos-image-archive', }, }, @@ -799,7 +799,7 @@ 'skylab': { 'cros_board': 'volteer', 'cros_model': 'voxel', - 'cros_img': 'volteer-public/R121-15681.0.0', + 'cros_img': 'volteer-public/R121-15683.0.0', 'bucket': 'chromiumos-image-archive', 'dut_pool': 'chromium', 'public_builder': 'cros_test_platform_public',
diff --git a/third_party/angle b/third_party/angle index 88f7a65..98d7926 160000 --- a/third_party/angle +++ b/third_party/angle
@@ -1 +1 @@ -Subproject commit 88f7a65d598abf65dd1cba481e18e1775c27beee +Subproject commit 98d79260fa0ebfcd5a4d959c9c21bf44071a00e6
diff --git a/third_party/blink/common/navigation/navigation_params.cc b/third_party/blink/common/navigation/navigation_params.cc index 5a9aece..f0259cf2 100644 --- a/third_party/blink/common/navigation/navigation_params.cc +++ b/third_party/blink/common/navigation/navigation_params.cc
@@ -29,11 +29,15 @@ } mojom::RendererContentSettingsPtr CreateDefaultRendererContentSettings() { - // These defaults mirror - // components/content_settings/core/browser/content_settings_registry.cc. + // These defaults are used in exactly 2 places: + // (1) A new empty window does not go through "navigation" and thus needs + // default values. As this is an empty window, the values do not matter. + // (2) On navigation error, the renderer sets the URL to + // kUnreachableWebDataURL. This page does have script and images, which we + // always want to allow regardless of the user's content settings. return mojom::RendererContentSettings::New( /*allow_script=*/true, /*allow_image=*/true, /*allow_popup=*/false, - /*allow_mixed_content=*/false, /*allow_auto_dark=*/true); + /*allow_mixed_content=*/false); } } // namespace blink
diff --git a/third_party/blink/public/mojom/navigation/renderer_content_settings.mojom b/third_party/blink/public/mojom/navigation/renderer_content_settings.mojom index 9e765f9..a9f6398 100644 --- a/third_party/blink/public/mojom/navigation/renderer_content_settings.mojom +++ b/third_party/blink/public/mojom/navigation/renderer_content_settings.mojom
@@ -11,5 +11,4 @@ bool allow_image; bool allow_popup; bool allow_mixed_content; - bool allow_auto_dark; };
diff --git a/third_party/blink/public/platform/web_content_settings_client.h b/third_party/blink/public/platform/web_content_settings_client.h index 096cd6eb..f7a73c7f 100644 --- a/third_party/blink/public/platform/web_content_settings_client.h +++ b/third_party/blink/public/platform/web_content_settings_client.h
@@ -69,11 +69,6 @@ return enabled_per_settings; } - // Controls whether auto dark web content is allowed for this frame. - virtual bool AllowAutoDarkWebContent(bool enabled_per_settings) { - return enabled_per_settings; - } - // Controls whether access to read the clipboard is allowed for this frame. virtual bool AllowReadFromClipboard(bool default_value) { return default_value;
diff --git a/third_party/blink/renderer/core/display_lock/display_lock_document_state.cc b/third_party/blink/renderer/core/display_lock/display_lock_document_state.cc index b0ef9e8..3ac141c4 100644 --- a/third_party/blink/renderer/core/display_lock/display_lock_document_state.cc +++ b/third_party/blink/renderer/core/display_lock/display_lock_document_state.cc
@@ -120,17 +120,23 @@ // Paint containment requires using the overflow clip edge. To do otherwise // results in overflow-clip-margin not being painted in certain scenarios. intersection_observer_ = IntersectionObserver::Create( - {Length::Percent(kViewportMarginPercentage)}, - {std::numeric_limits<float>::min()}, document_, + /* (root) margin */ {Length::Percent(kViewportMarginPercentage)}, + /* scroll_margin */ Vector<Length>(), + /* thresholds */ {std::numeric_limits<float>::min()}, + /* document */ document_, + /* callback */ WTF::BindRepeating( &DisplayLockDocumentState::ProcessDisplayLockActivationObservation, WrapWeakPersistent(this)), + /* ukm_metric_id */ LocalFrameUkmAggregator::kDisplayLockIntersectionObserver, - IntersectionObserver::kDeliverDuringPostLayoutSteps, - IntersectionObserver::kFractionOfTarget, 0 /* delay */, - false /* track_visibility */, false /* always report_root_bounds */, - IntersectionObserver::kApplyMarginToTarget, - true /* use_overflow_clip_edge */); + /* behavior */ IntersectionObserver::kDeliverDuringPostLayoutSteps, + /* semantics */ IntersectionObserver::kFractionOfTarget, + /* delay */ 0, + /* track_visibility */ false, + /* always report_root_bounds */ false, + /* margin_target */ IntersectionObserver::kApplyMarginToTarget, + /* use_overflow_clip_edge */ true); } return *intersection_observer_; }
diff --git a/third_party/blink/renderer/core/frame/frame_view.cc b/third_party/blink/renderer/core/frame/frame_view.cc index 614d4e2..bdd3820 100644 --- a/third_party/blink/renderer/core/frame/frame_view.cc +++ b/third_party/blink/renderer/core/frame/frame_view.cc
@@ -60,19 +60,17 @@ return DisplayLockUtilities::LockedInclusiveAncestorPreventingPaint(*owner); } -gfx::Vector2dF FrameView::UpdateViewportIntersection( - unsigned flags, - bool needs_occlusion_tracking) { - if (!(flags & - IntersectionObservation::kFrameViewportIntersectionNeedsUpdate)) { - return min_scroll_delta_to_update_viewport_intersection_; +void FrameView::UpdateViewportIntersection(unsigned flags, + bool needs_occlusion_tracking) { + if (!(flags & IntersectionObservation::kImplicitRootObserversNeedUpdate)) { + return; } // This should only run in child frames. Frame& frame = GetFrame(); HTMLFrameOwnerElement* owner_element = frame.DeprecatedLocalOwner(); if (!owner_element) { - return gfx::Vector2dF(); + return; } Document& owner_document = owner_element->GetDocument(); @@ -98,8 +96,6 @@ // zero size, or it's display locked in parent frame; leave // viewport_intersection empty, and signal the frame as occluded if // necessary. - min_scroll_delta_to_update_viewport_intersection_ = - IntersectionGeometry::kInfiniteScrollDelta; occlusion_state = mojom::blink::FrameOcclusionState::kPossiblyOccluded; } else if (parent_lifecycle_state >= DocumentLifecycle::kLayoutClean && !owner_document.View()->NeedsLayout()) { @@ -117,8 +113,6 @@ /* target_margin */ {}, /* scroll_margin */ {}, geometry_flags, root_geometry); - min_scroll_delta_to_update_viewport_intersection_ = - geometry.MinScrollDeltaToUpdate(); PhysicalRect new_rect_in_parent = geometry.IntersectionRect(); // Convert to DIP @@ -295,7 +289,6 @@ } UpdateRenderThrottlingStatus(should_throttle, subtree_throttled, display_locked_in_parent_frame); - return min_scroll_delta_to_update_viewport_intersection_; } void FrameView::UpdateFrameVisibility(bool intersects_viewport) {
diff --git a/third_party/blink/renderer/core/frame/frame_view.h b/third_party/blink/renderer/core/frame/frame_view.h index 83bd8817..5f5ed527 100644 --- a/third_party/blink/renderer/core/frame/frame_view.h +++ b/third_party/blink/renderer/core/frame/frame_view.h
@@ -17,7 +17,6 @@ namespace blink { class Frame; -struct IntersectionUpdateResult; struct IntrinsicSizingInfo; class CORE_EXPORT FrameView : public EmbeddedContentView { @@ -28,7 +27,9 @@ // parent_flags is the result of calling GetIntersectionObservationFlags on // the LocalFrameView parent of this FrameView (if any). It contains dirty // bits based on whether geometry may have changed in the parent frame. - virtual IntersectionUpdateResult UpdateViewportIntersectionsForSubtree( + // Returns true if the frame needs occlusion tracking (i.e. trackVisibility() + // is true for any tracked observer in the frame subtree). + virtual bool UpdateViewportIntersectionsForSubtree( unsigned parent_flags, absl::optional<base::TimeTicks>& monotonic_time) = 0; @@ -78,17 +79,8 @@ const mojom::blink::ViewportIntersectionState& intersection_state) = 0; virtual void VisibilityForThrottlingChanged() = 0; virtual bool LifecycleUpdatesThrottled() const { return false; } - - // Returns the minimum scroll delta in the parent frame to update - // implicit-root intersection observers in this frame. This only affects - // when the parent frame propagates the kImplicitRootObserversNeedUpdate flag - // to this frame during UpdateViewportIntersectionForSubtree(), but doesn't - // affect the kFrameViewportIntersectionNeedsUpdate flag. The return value - // is only based on the intersection relationship between this frame's - // content rect and the viewport. The caller may disregard the result due to - // other constraints. - gfx::Vector2dF UpdateViewportIntersection(unsigned flags, - bool needs_occlusion_tracking); + void UpdateViewportIntersection(unsigned flags, + bool needs_occlusion_tracking); // FrameVisibility is tracked by the browser process, which may suppress // lifecycle updates for a frame outside the viewport. @@ -104,8 +96,6 @@ base::TimeTicks rect_in_parent_stable_since_; base::TimeTicks rect_in_parent_stable_since_for_iov2_; blink::mojom::FrameVisibility frame_visibility_; - // Caches the result of UpdateVIewportIntersection(). - gfx::Vector2dF min_scroll_delta_to_update_viewport_intersection_; bool hidden_for_throttling_ = false; bool subtree_throttled_ = false; bool display_locked_ = false;
diff --git a/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator_test.cc b/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator_test.cc index b078ede..60c4326 100644 --- a/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator_test.cc +++ b/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator_test.cc
@@ -12,6 +12,7 @@ #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/common/metrics/document_update_reason.h" #include "third_party/blink/renderer/bindings/core/v8/v8_intersection_observer_init.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_union_document_element.h" #include "third_party/blink/renderer/core/html/html_frame_owner_element.h" #include "third_party/blink/renderer/core/paint/timing/paint_timing.h" #include "third_party/blink/renderer/core/testing/intersection_observer_test_helper.h" @@ -691,6 +692,8 @@ // Create internal observer IntersectionObserverInit* observer_init = IntersectionObserverInit::Create(); + observer_init->setRoot( + MakeGarbageCollected<V8UnionDocumentOrElement>(&document)); TestIntersectionObserverDelegate* internal_delegate = MakeGarbageCollected<TestIntersectionObserverDelegate>( document, LocalFrameUkmAggregator::kLazyLoadIntersectionObserver); @@ -720,7 +723,7 @@ EXPECT_EQ( histogram_tester.GetTotalSum( "Blink.IntersectionObservationInternalCount.UpdateTime.PreFCP"), - 4); + RuntimeEnabledFeatures::IntersectionOptimizationEnabled() ? 2 : 4); EXPECT_EQ( histogram_tester.GetTotalSum( "Blink.IntersectionObservationJavascriptCount.UpdateTime.PreFCP"), @@ -734,12 +737,12 @@ base::TimeTicks(), base::TimeTicks() + base::Microseconds(10), 0, root_document->UkmSourceID(), root_document->UkmRecorder()); - target1->setAttribute(html_names::kStyleAttr, AtomicString("width: 60px")); + target1->setAttribute(html_names::kStyleAttr, AtomicString("height: 60px")); Compositor().BeginFrame(); EXPECT_EQ( histogram_tester.GetTotalSum( "Blink.IntersectionObservationInternalCount.UpdateTime.PreFCP"), - 4); + RuntimeEnabledFeatures::IntersectionOptimizationEnabled() ? 2 : 4); EXPECT_EQ( histogram_tester.GetTotalSum( "Blink.IntersectionObservationJavascriptCount.UpdateTime.PreFCP"),
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 31c71c02..31c862b 100644 --- a/third_party/blink/renderer/core/frame/local_frame_view.cc +++ b/third_party/blink/renderer/core/frame/local_frame_view.cc
@@ -1048,10 +1048,10 @@ // Populating monotonic_time may be expensive, and may be unnecessary, so // allow it to be populated on demand. absl::optional<base::TimeTicks> monotonic_time; - IntersectionUpdateResult result = + bool needs_occlusion_tracking = UpdateViewportIntersectionsForSubtree(0, monotonic_time); if (FrameOwner* owner = frame_->Owner()) - owner->SetNeedsOcclusionTracking(result.needs_occlusion_tracking); + owner->SetNeedsOcclusionTracking(needs_occlusion_tracking); #if DCHECK_IS_ON() DCHECK(was_dirty || !NeedsLayout()); #endif @@ -1067,8 +1067,7 @@ DocumentUpdateReason::kIntersectionObservation); absl::optional<base::TimeTicks> monotonic_time; UpdateViewportIntersectionsForSubtree( - IntersectionObservation::kFrameViewportIntersectionNeedsUpdate | - IntersectionObservation::kImplicitRootObserversNeedUpdate | + IntersectionObservation::kImplicitRootObserversNeedUpdate | IntersectionObservation::kIgnoreDelay, monotonic_time); } @@ -1413,7 +1412,10 @@ if (auto* controller = GetFrame().GetDocument()->GetIntersectionObserverController()) { - controller->ComputeIntersections(flags, GetUkmAggregator(), monotonic_time); + controller->ComputeIntersections( + flags, GetUkmAggregator(), monotonic_time, + accumulated_scroll_delta_since_last_intersection_update_); + accumulated_scroll_delta_since_last_intersection_update_ = gfx::Vector2dF(); } for (Frame* child = frame_->Tree().FirstChild(); child; @@ -4175,7 +4177,7 @@ CollectAnnotatedRegions(*curr, regions); } -IntersectionUpdateResult LocalFrameView::UpdateViewportIntersectionsForSubtree( +bool LocalFrameView::UpdateViewportIntersectionsForSubtree( unsigned parent_flags, absl::optional<base::TimeTicks>& monotonic_time) { // TODO(dcheng): Since LocalFrameView tree updates are deferred, FrameViews @@ -4184,41 +4186,20 @@ // in lifecycle updates are still needed when there are no more deferred // LocalFrameView updates: https://crbug.com/561683 if (!GetFrame().GetDocument()->IsActive()) { - return IntersectionUpdateResult(); + return false; } unsigned flags = GetIntersectionObservationFlags(parent_flags); - IntersectionUpdateResult result; - if (RuntimeEnabledFeatures::IntersectionOptimizationEnabled()) { - min_scroll_delta_to_update_intersection_ = - IntersectionGeometry::kInfiniteScrollDelta; - } else { - DCHECK_EQ(min_scroll_delta_to_update_intersection_, gfx::Vector2dF()); - } - - bool fully_updated = false; + bool needs_occlusion_tracking = false; if (!NeedsLayout() || IsDisplayLocked()) { // Notify javascript IntersectionObservers if (IntersectionObserverController* controller = GetFrame().GetDocument()->GetIntersectionObserverController()) { - IntersectionUpdateResult observers_result = - controller->ComputeIntersections(flags, GetUkmAggregator(), - monotonic_time); - result.needs_occlusion_tracking = - observers_result.needs_occlusion_tracking; - result.has_implicit_root_observer_with_margin = - observers_result.has_implicit_root_observer_with_margin; - // min_scroll_delta_to_update_intersection_ on this frame is composed - // from the result of updating the IntersectionObservers tracked by this - // frame, and the result of recursive calls to this method for subframes. - // The final value of result.min_scroll_delta_to_update which will be - // returned to the caller is based only on the call to - // UpdateViewportIntersection for this frame. - if (RuntimeEnabledFeatures::IntersectionOptimizationEnabled()) { - min_scroll_delta_to_update_intersection_ = - observers_result.min_scroll_delta_to_update; - } - fully_updated = intersection_observation_state_ >= kDesired; + needs_occlusion_tracking = controller->ComputeIntersections( + flags, GetUkmAggregator(), monotonic_time, + accumulated_scroll_delta_since_last_intersection_update_); + accumulated_scroll_delta_since_last_intersection_update_ = + gfx::Vector2dF(); } intersection_observation_state_ = kNotNeeded; } @@ -4227,40 +4208,22 @@ SCOPED_UMA_AND_UKM_TIMER( GetUkmAggregator(), LocalFrameUkmAggregator::kUpdateViewportIntersection); - // The result is the minimum scroll delta in the parent frame to update - // viewport intersection of this frame. - result.min_scroll_delta_to_update = - UpdateViewportIntersection(flags, result.needs_occlusion_tracking); + UpdateViewportIntersection(flags, needs_occlusion_tracking); } - auto update_result_from_subframe = - [this, &result](const IntersectionUpdateResult& subframe_result) { - result.needs_occlusion_tracking |= - subframe_result.needs_occlusion_tracking; - if (subframe_result.has_implicit_root_observer_with_margin) { - result.has_implicit_root_observer_with_margin = true; - // An implicit-root observer with margin in a subframe requires this - // frame to update intersection observers on every scroll. - min_scroll_delta_to_update_intersection_ = gfx::Vector2dF(); - } else { - min_scroll_delta_to_update_intersection_.SetToMin( - subframe_result.min_scroll_delta_to_update); - } - }; - for (Frame* child = frame_->Tree().FirstChild(); child; child = child->Tree().NextSibling()) { - update_result_from_subframe( + needs_occlusion_tracking |= child->View()->UpdateViewportIntersectionsForSubtree(flags, - monotonic_time)); + monotonic_time); } if (DocumentPortals* portals = DocumentPortals::Get(*frame_->GetDocument())) { for (PortalContents* portal : portals->GetPortals()) { if (Frame* frame = portal->GetFrame()) { - update_result_from_subframe( + needs_occlusion_tracking |= frame->View()->UpdateViewportIntersectionsForSubtree( - flags, monotonic_time)); + flags, monotonic_time); } } } @@ -4270,19 +4233,14 @@ for (HTMLFencedFrameElement* fenced_frame : fenced_frames->GetFencedFrames()) { if (Frame* frame = fenced_frame->ContentFrame()) { - update_result_from_subframe( + needs_occlusion_tracking |= frame->View()->UpdateViewportIntersectionsForSubtree( - flags, monotonic_time)); + flags, monotonic_time); } } } - if (RuntimeEnabledFeatures::IntersectionOptimizationEnabled() && - fully_updated) { - accumulated_scroll_delta_since_last_intersection_update_ = gfx::Vector2dF(); - } - - return result; + return needs_occlusion_tracking; } void LocalFrameView::DeliverSynchronousIntersectionObservations() { @@ -4412,27 +4370,7 @@ gfx::Vector2dF scroll_delta) { accumulated_scroll_delta_since_last_intersection_update_ += gfx::Vector2dF(std::abs(scroll_delta.x()), std::abs(scroll_delta.y())); - if (intersection_observation_state_ >= kDesired) { - return; - } - if (min_scroll_delta_to_update_intersection_.x() <= - accumulated_scroll_delta_since_last_intersection_update_.x() || - min_scroll_delta_to_update_intersection_.y() <= - accumulated_scroll_delta_since_last_intersection_update_.y()) { - // The accumulated scroll delta from all scrollers in this frame has - // exceeded min_scroll_delta_to_update_intersection_ since the last - // intersection observer update, which may change intersection status. - SetIntersectionObservationState(kDesired); - } else { - DCHECK(RuntimeEnabledFeatures::IntersectionOptimizationEnabled()); - // Frame viewport intersection is always updated on scroll, regardless of - // scroll_delta. Situations such as viewport and main frame intersection - // reporting and implicit-root intersection observers with margins in - // remote frames make the optimization not feasible. Nevertheless, frame - // viewport intersection updates are much faster than intersection - // observer updates, based on UMA data. - SetIntersectionObservationState(kFrameViewportIntersectionOnly); - } + SetIntersectionObservationState(kDesired); } void LocalFrameView::InvalidateIntersectionObservations() { @@ -4488,9 +4426,6 @@ // Observers with explicit roots only need to be checked on the same frame, // since in this case target and root must be in the same document. if (intersection_observation_state_ != kNotNeeded) { - flags |= IntersectionObservation::kFrameViewportIntersectionNeedsUpdate; - } - if (intersection_observation_state_ >= kDesired) { flags |= (IntersectionObservation::kExplicitRootObserversNeedUpdate | IntersectionObservation::kImplicitRootObserversNeedUpdate); } @@ -4498,8 +4433,7 @@ // For observers with implicit roots, we need to check state on the whole // local frame tree, as passed down from the parent. flags |= (parent_flags & - (IntersectionObservation::kFrameViewportIntersectionNeedsUpdate | - IntersectionObservation::kImplicitRootObserversNeedUpdate)); + IntersectionObservation::kImplicitRootObserversNeedUpdate); // The kIgnoreDelay parameter is used to force computation in an OOPIF which // is hidden in the parent document, thus not running lifecycle updates. It
diff --git a/third_party/blink/renderer/core/frame/local_frame_view.h b/third_party/blink/renderer/core/frame/local_frame_view.h index 0153d84..316f5b9e 100644 --- a/third_party/blink/renderer/core/frame/local_frame_view.h +++ b/third_party/blink/renderer/core/frame/local_frame_view.h
@@ -215,16 +215,11 @@ enum IntersectionObservationState { // The next painting frame does not need an intersection observation. kNotNeeded = 0, - // The next painting frame only needs to update frame viewport intersection, - // not intersection observations. Note that intersection observations in - // child remote frames happen during the parent frame's viewport - // intersection update, with kDesired or kRequired set on the child frames. - kFrameViewportIntersectionOnly = 1, // The next painting frame needs an intersection observation. - kDesired = 2, + kDesired = 1, // The next painting frame must be generated up to intersection observation // (even if frame is throttled). - kRequired = 3 + kRequired = 2 }; // Sets the internal IntersectionObservationState to the max of the @@ -243,10 +238,6 @@ void ForceUpdateViewportIntersections(); - gfx::Vector2dF MinScrollDeltaToUpdateIntersectionForTesting() const { - return min_scroll_delta_to_update_intersection_; - } - void SetPaintArtifactCompositorNeedsUpdate(); // Methods for getting/setting the size Blink should use to layout the @@ -956,7 +947,7 @@ void ForAllRemoteFrameViews(base::FunctionRef<void(RemoteFrameView&)>); - IntersectionUpdateResult UpdateViewportIntersectionsForSubtree( + bool UpdateViewportIntersectionsForSubtree( unsigned parent_flags, absl::optional<base::TimeTicks>& monotonic_time) override; void DeliverSynchronousIntersectionObservations(); @@ -1112,7 +1103,6 @@ #endif IntersectionObservationState intersection_observation_state_; - gfx::Vector2dF min_scroll_delta_to_update_intersection_; gfx::Vector2dF accumulated_scroll_delta_since_last_intersection_update_; mojom::blink::ViewportIntersectionState last_intersection_state_;
diff --git a/third_party/blink/renderer/core/frame/remote_frame_view.cc b/third_party/blink/renderer/core/frame/remote_frame_view.cc index 496c327..2816c04 100644 --- a/third_party/blink/renderer/core/frame/remote_frame_view.cc +++ b/third_party/blink/renderer/core/frame/remote_frame_view.cc
@@ -15,7 +15,6 @@ #include "third_party/blink/renderer/core/frame/remote_frame.h" #include "third_party/blink/renderer/core/frame/remote_frame_client.h" #include "third_party/blink/renderer/core/html/html_frame_owner_element.h" -#include "third_party/blink/renderer/core/intersection_observer/intersection_observer_controller.h" #include "third_party/blink/renderer/core/layout/layout_embedded_content.h" #include "third_party/blink/renderer/core/layout/layout_view.h" #include "third_party/blink/renderer/core/page/page.h" @@ -99,11 +98,11 @@ SetAttached(false); } -IntersectionUpdateResult RemoteFrameView::UpdateViewportIntersectionsForSubtree( +bool RemoteFrameView::UpdateViewportIntersectionsForSubtree( unsigned parent_flags, absl::optional<base::TimeTicks>&) { UpdateViewportIntersection(parent_flags, needs_occlusion_tracking_); - return IntersectionUpdateResult{needs_occlusion_tracking_}; + return needs_occlusion_tracking_; } void RemoteFrameView::SetViewportIntersection(
diff --git a/third_party/blink/renderer/core/frame/remote_frame_view.h b/third_party/blink/renderer/core/frame/remote_frame_view.h index 38ee5765..6b442d8 100644 --- a/third_party/blink/renderer/core/frame/remote_frame_view.h +++ b/third_party/blink/renderer/core/frame/remote_frame_view.h
@@ -59,7 +59,7 @@ void Hide() override; void Show() override; - IntersectionUpdateResult UpdateViewportIntersectionsForSubtree( + bool UpdateViewportIntersectionsForSubtree( unsigned parent_flags, absl::optional<base::TimeTicks>&) override; void SetNeedsOcclusionTracking(bool);
diff --git a/third_party/blink/renderer/core/html/anchor_element_metrics_sender.cc b/third_party/blink/renderer/core/html/anchor_element_metrics_sender.cc index 4ac31322..2ed91f3 100644 --- a/third_party/blink/renderer/core/html/anchor_element_metrics_sender.cc +++ b/third_party/blink/renderer/core/html/anchor_element_metrics_sender.cc
@@ -159,12 +159,18 @@ DCHECK(clock_); intersection_observer_ = IntersectionObserver::Create( - {}, {INTERSECTION_RATIO_THRESHOLD}, &document, + /* (root) margin */ Vector<Length>(), + /* scroll_margin */ Vector<Length>(), + /* thresholds */ {INTERSECTION_RATIO_THRESHOLD}, + /* document */ &document, + /* callback */ WTF::BindRepeating(&AnchorElementMetricsSender::UpdateVisibleAnchors, WrapWeakPersistent(this)), + /* ukm_metric_id */ LocalFrameUkmAggregator::kAnchorElementMetricsIntersectionObserver, - IntersectionObserver::kDeliverDuringPostLifecycleSteps, - IntersectionObserver::kFractionOfTarget, 100 /* delay in ms */); + /* behavior */ IntersectionObserver::kDeliverDuringPostLifecycleSteps, + /* semantics */ IntersectionObserver::kFractionOfTarget, + /* delay */ 100); } void AnchorElementMetricsSender::SetNowAsNavigationStartForTesting() {
diff --git a/third_party/blink/renderer/core/html/anchor_element_observer_for_service_worker.cc b/third_party/blink/renderer/core/html/anchor_element_observer_for_service_worker.cc index d8c21d6..6767765 100644 --- a/third_party/blink/renderer/core/html/anchor_element_observer_for_service_worker.cc +++ b/third_party/blink/renderer/core/html/anchor_element_observer_for_service_worker.cc
@@ -61,14 +61,19 @@ CHECK(document.IsInOutermostMainFrame()); if (features::kSpeculativeServiceWorkerWarmUpIntersectionObserver.Get()) { intersection_observer_ = IntersectionObserver::Create( - {}, {std::numeric_limits<float>::min()}, &document, + /* (root) margin */ Vector<Length>(), + /* scroll_margin */ Vector<Length>(), + /* thresholds */ {std::numeric_limits<float>::min()}, + /* document */ &document, + /* callback */ WTF::BindRepeating( &AnchorElementObserverForServiceWorker::UpdateVisibleAnchors, WrapWeakPersistent(this)), + /* ukm_metric_id */ LocalFrameUkmAggregator::kAnchorElementMetricsIntersectionObserver, - IntersectionObserver::kPostTaskToDeliver, - IntersectionObserver::kFractionOfTarget, - /*delay=*/ + /* behavior */ IntersectionObserver::kPostTaskToDeliver, + /* semantics */ IntersectionObserver::kFractionOfTarget, + /* delay */ features::kSpeculativeServiceWorkerWarmUpIntersectionObserverDelay .Get()); }
diff --git a/third_party/blink/renderer/core/html/lazy_load_frame_observer.cc b/third_party/blink/renderer/core/html/lazy_load_frame_observer.cc index 2713163..36f4f985 100644 --- a/third_party/blink/renderer/core/html/lazy_load_frame_observer.cc +++ b/third_party/blink/renderer/core/html/lazy_load_frame_observer.cc
@@ -116,11 +116,16 @@ std::make_unique<LazyLoadRequestInfo>(resource_request, frame_load_type); lazy_load_intersection_observer_ = IntersectionObserver::Create( - {Length::Fixed(GetLazyFrameLoadingViewportDistanceThresholdPx( - element_->GetDocument()))}, - {std::numeric_limits<float>::min()}, &element_->GetDocument(), + /* (root) margin */ {Length::Fixed( + GetLazyFrameLoadingViewportDistanceThresholdPx( + element_->GetDocument()))}, + /* scroll_margin */ Vector<Length>(), + /* thresholds */ {std::numeric_limits<float>::min()}, + /* document */ &element_->GetDocument(), + /* callback */ WTF::BindRepeating(&LazyLoadFrameObserver::LoadIfHiddenOrNearViewport, WrapWeakPersistent(this)), + /* ukm_metric_id */ LocalFrameUkmAggregator::kLazyLoadIntersectionObserver); lazy_load_intersection_observer_->observe(element_);
diff --git a/third_party/blink/renderer/core/html/lazy_load_image_observer.cc b/third_party/blink/renderer/core/html/lazy_load_image_observer.cc index dc8f23f..64bd0768 100644 --- a/third_party/blink/renderer/core/html/lazy_load_image_observer.cc +++ b/third_party/blink/renderer/core/html/lazy_load_image_observer.cc
@@ -128,12 +128,32 @@ void LazyLoadImageObserver::StartMonitoringNearViewport(Document* root_document, Element* element) { if (!lazy_load_intersection_observer_) { - lazy_load_intersection_observer_ = IntersectionObserver::Create( - {Length::Fixed(GetLazyLoadingImageMarginPx(*root_document))}, - {std::numeric_limits<float>::min()}, root_document, - WTF::BindRepeating(&LazyLoadImageObserver::LoadIfNearViewport, - WrapWeakPersistent(this)), - LocalFrameUkmAggregator::kLazyLoadIntersectionObserver); + int margin = GetLazyLoadingImageMarginPx(*root_document); + if (RuntimeEnabledFeatures::LazyLoadScrollMarginEnabled()) { + lazy_load_intersection_observer_ = IntersectionObserver::Create( + /* (root) margin */ {Length::Fixed(0)}, + /* scroll_margin */ + {/* top & bottom */ Length::Fixed(margin), + /* right & left */ Length::Fixed(margin / 2)}, + /* thresholds */ {std::numeric_limits<float>::min()}, + /* document */ root_document, + /* callback */ + WTF::BindRepeating(&LazyLoadImageObserver::LoadIfNearViewport, + WrapWeakPersistent(this)), + /* ukm_metric_id */ + LocalFrameUkmAggregator::kLazyLoadIntersectionObserver); + } else { + lazy_load_intersection_observer_ = IntersectionObserver::Create( + /* (root) margin */ {Length::Fixed(margin)}, + /* scroll_margin */ {Length::Fixed(0)}, + /* thresholds */ {std::numeric_limits<float>::min()}, + /* document */ root_document, + /* callback */ + WTF::BindRepeating(&LazyLoadImageObserver::LoadIfNearViewport, + WrapWeakPersistent(this)), + /* ukm_metric_id */ + LocalFrameUkmAggregator::kLazyLoadIntersectionObserver); + } } lazy_load_intersection_observer_->observe(element); @@ -224,16 +244,21 @@ } if (!visibility_metrics_observer_) { visibility_metrics_observer_ = IntersectionObserver::Create( - {}, {std::numeric_limits<float>::min()}, root_document, + /* (root) margin */ Vector<Length>(), + /* scroll_margin */ Vector<Length>(), + /* thresholds */ {std::numeric_limits<float>::min()}, + /* document */ root_document, + /* callback */ WTF::BindRepeating(&LazyLoadImageObserver::OnVisibilityChanged, WrapWeakPersistent(this)), + /* ukm_metric_id */ LocalFrameUkmAggregator::kLazyLoadIntersectionObserver, - IntersectionObserver::kDeliverDuringPostLifecycleSteps, - IntersectionObserver::kFractionOfTarget, + /* behavior */ IntersectionObserver::kDeliverDuringPostLifecycleSteps, + /* semantics */ IntersectionObserver::kFractionOfTarget, /* delay */ 0, /* track_visibility */ false, /* always_report_root_bounds */ false, - IntersectionObserver::kApplyMarginToRoot, + /* margin_target */ IntersectionObserver::kApplyMarginToRoot, /* use_overflow_clip_edge */ false, /* needs_initial_observation_with_detached_target */ false); }
diff --git a/third_party/blink/renderer/core/html/lazy_load_image_observer_test.cc b/third_party/blink/renderer/core/html/lazy_load_image_observer_test.cc index 33e838e..85ffa94c 100644 --- a/third_party/blink/renderer/core/html/lazy_load_image_observer_test.cc +++ b/third_party/blink/renderer/core/html/lazy_load_image_observer_test.cc
@@ -678,8 +678,10 @@ "image/png"); // Scroll down so that all the images in the iframe are near the viewport. + // TODO(crbug.com/1503290): Change this back to 250 once scroll margin is + // fixed to walk through same-origin iframes. GetDocument().View()->LayoutViewport()->SetScrollOffset( - ScrollOffset(0, 250), mojom::blink::ScrollType::kProgrammatic); + ScrollOffset(0, 500), mojom::blink::ScrollType::kProgrammatic); Compositor().BeginFrame(); test::RunPendingTasks();
diff --git a/third_party/blink/renderer/core/html/media/autoplay_policy.cc b/third_party/blink/renderer/core/html/media/autoplay_policy.cc index 3a7a3d9..60e65e3f 100644 --- a/third_party/blink/renderer/core/html/media/autoplay_policy.cc +++ b/third_party/blink/renderer/core/html/media/autoplay_policy.cc
@@ -200,10 +200,14 @@ return; autoplay_intersection_observer_ = IntersectionObserver::Create( - {}, {IntersectionObserver::kMinimumThreshold}, &element_->GetDocument(), + /* (root) margin */ Vector<Length>(), + /* scroll_margin */ Vector<Length>(), + /* thresholds */ {IntersectionObserver::kMinimumThreshold}, + /* document */ &element_->GetDocument(), + /* callback */ WTF::BindRepeating(&AutoplayPolicy::OnIntersectionChangedForAutoplay, WrapWeakPersistent(this)), - LocalFrameUkmAggregator::kMediaIntersectionObserver); + /* ukm_metric_id */ LocalFrameUkmAggregator::kMediaIntersectionObserver); autoplay_intersection_observer_->observe(element_); }
diff --git a/third_party/blink/renderer/core/html/media/autoplay_uma_helper.cc b/third_party/blink/renderer/core/html/media/autoplay_uma_helper.cc index c2a6260..8716cee 100644 --- a/third_party/blink/renderer/core/html/media/autoplay_uma_helper.cc +++ b/third_party/blink/renderer/core/html/media/autoplay_uma_helper.cc
@@ -207,12 +207,16 @@ return; muted_video_play_method_intersection_observer_ = IntersectionObserver::Create( - {}, {IntersectionObserver::kMinimumThreshold}, &element_->GetDocument(), + /* (root) margin */ Vector<Length>(), + /* scroll_margin */ Vector<Length>(), + /* thresholds */ {IntersectionObserver::kMinimumThreshold}, + /* document */ &element_->GetDocument(), + /* callback */ WTF::BindRepeating( &AutoplayUmaHelper:: OnIntersectionChangedForMutedVideoPlayMethodBecomeVisible, WrapWeakPersistent(this)), - LocalFrameUkmAggregator::kMediaIntersectionObserver); + /* ukm_metric_id */ LocalFrameUkmAggregator::kMediaIntersectionObserver); muted_video_play_method_intersection_observer_->observe(element_); SetExecutionContext(element_->GetExecutionContext()); } @@ -240,12 +244,16 @@ is_visible_ = false; muted_video_offscreen_duration_intersection_observer_ = IntersectionObserver::Create( - {}, {IntersectionObserver::kMinimumThreshold}, - &element_->GetDocument(), + /* (root) margin */ Vector<Length>(), + /* scroll_margin */ Vector<Length>(), + /* thresholds */ {IntersectionObserver::kMinimumThreshold}, + /* document */ &element_->GetDocument(), + /* callback */ WTF::BindRepeating( &AutoplayUmaHelper:: OnIntersectionChangedForMutedVideoOffscreenDuration, WrapWeakPersistent(this)), + /* ukm_metric_id */ LocalFrameUkmAggregator::kMediaIntersectionObserver); muted_video_offscreen_duration_intersection_observer_->observe(element_); element_->addEventListener(event_type_names::kPause, this, false);
diff --git a/third_party/blink/renderer/core/html/media/html_video_element.cc b/third_party/blink/renderer/core/html/media/html_video_element.cc index 083112f2..533437e 100644 --- a/third_party/blink/renderer/core/html/media/html_video_element.cc +++ b/third_party/blink/renderer/core/html/media/html_video_element.cc
@@ -350,9 +350,14 @@ // element actually becomes visible to complete the load. if (web_media_player_->DidLazyLoad() && !PotentiallyPlaying()) { lazy_load_intersection_observer_ = IntersectionObserver::Create( - {}, {IntersectionObserver::kMinimumThreshold}, &GetDocument(), + /* (root) margin */ Vector<Length>(), + /* scroll_margin */ Vector<Length>(), + /* thresholds */ {IntersectionObserver::kMinimumThreshold}, + /* document */ &GetDocument(), + /* callback */ WTF::BindRepeating(&HTMLVideoElement::OnIntersectionChangedForLazyLoad, WrapWeakPersistent(this)), + /* ukm_metric_id */ LocalFrameUkmAggregator::kMediaIntersectionObserver); lazy_load_intersection_observer_->observe(this); }
diff --git a/third_party/blink/renderer/core/html/media/media_custom_controls_fullscreen_detector.cc b/third_party/blink/renderer/core/html/media/media_custom_controls_fullscreen_detector.cc index c01d2bb..679026e9 100644 --- a/third_party/blink/renderer/core/html/media/media_custom_controls_fullscreen_detector.cc +++ b/third_party/blink/renderer/core/html/media/media_custom_controls_fullscreen_detector.cc
@@ -107,13 +107,20 @@ 0.8, kMostlyFillViewportIntersectionThreshold}; viewport_intersection_observer_ = IntersectionObserver::Create( - {}, thresholds, &(video_element_->GetDocument()), + /* (root) margin */ Vector<Length>(), + /* scroll_margin */ Vector<Length>(), + /* thresholds */ thresholds, + /* document */ &(video_element_->GetDocument()), + /* callback */ WTF::BindRepeating( &MediaCustomControlsFullscreenDetector::OnIntersectionChanged, WrapWeakPersistent(this)), - LocalFrameUkmAggregator::kMediaIntersectionObserver, - IntersectionObserver::kDeliverDuringPostLifecycleSteps, - IntersectionObserver::kFractionOfRoot, 0, false, true); + /* ukm_metric_id */ LocalFrameUkmAggregator::kMediaIntersectionObserver, + /* behavior */ IntersectionObserver::kDeliverDuringPostLifecycleSteps, + /* semantics */ IntersectionObserver::kFractionOfRoot, + /* delay */ 0, + /* track_visibility */ false, + /* always report_root_bounds */ true); viewport_intersection_observer_->observe(&VideoElement()); }
diff --git a/third_party/blink/renderer/core/html/media/video_wake_lock.cc b/third_party/blink/renderer/core/html/media/video_wake_lock.cc index b201920..8d66010 100644 --- a/third_party/blink/renderer/core/html/media/video_wake_lock.cc +++ b/third_party/blink/renderer/core/html/media/video_wake_lock.cc
@@ -243,12 +243,17 @@ const auto kDelayMs = 0; visibility_observer_ = IntersectionObserver::Create( - {}, /*thresholds=*/{visibility_threshold_}, &VideoElement().GetDocument(), + /* (root) margin */ Vector<Length>(), + /* scroll_margin */ Vector<Length>(), + /* thresholds */ {visibility_threshold_}, + /* document */ &VideoElement().GetDocument(), + /* callback */ WTF::BindRepeating(&VideoWakeLock::OnVisibilityChanged, WrapWeakPersistent(this)), - LocalFrameUkmAggregator::kMediaIntersectionObserver, - IntersectionObserver::kDeliverDuringPostLifecycleSteps, - IntersectionObserver::kFractionOfTarget, kDelayMs); + /* ukm_metric_id */ LocalFrameUkmAggregator::kMediaIntersectionObserver, + /* behavior */ IntersectionObserver::kDeliverDuringPostLifecycleSteps, + /* semantics */ IntersectionObserver::kFractionOfTarget, + /* delay */ kDelayMs); visibility_observer_->observe(&VideoElement()); if (base::FeatureList::IsEnabled(kStrictVideoWakeLock)) { @@ -259,13 +264,17 @@ // iframes. The observer doesn't know the outermost viewport size when // running from within an iframe. size_observer_ = IntersectionObserver::Create( - {}, /*thresholds=*/{kSizeThreshold}, - &VideoElement().GetDocument().TopDocument(), + /* (root) margin */ Vector<Length>(), + /* scroll_margin */ Vector<Length>(), + /* thresholds */ {kSizeThreshold}, + /* document */ &VideoElement().GetDocument().TopDocument(), + /* callback */ WTF::BindRepeating(&VideoWakeLock::OnSizeChanged, WrapWeakPersistent(this)), - LocalFrameUkmAggregator::kMediaIntersectionObserver, - IntersectionObserver::kDeliverDuringPostLifecycleSteps, - IntersectionObserver::kFractionOfRoot, kDelayMs); + /* ukm_metric_id */ LocalFrameUkmAggregator::kMediaIntersectionObserver, + /* behavior */ IntersectionObserver::kDeliverDuringPostLifecycleSteps, + /* semantics */ IntersectionObserver::kFractionOfRoot, + /* delay */ kDelayMs); size_observer_->observe(&VideoElement()); } }
diff --git a/third_party/blink/renderer/core/intersection_observer/element_intersection_observer_data.cc b/third_party/blink/renderer/core/intersection_observer/element_intersection_observer_data.cc index 914369a..021aff1 100644 --- a/third_party/blink/renderer/core/intersection_observer/element_intersection_observer_data.cc +++ b/third_party/blink/renderer/core/intersection_observer/element_intersection_observer_data.cc
@@ -66,7 +66,9 @@ absl::optional<IntersectionGeometry::RootGeometry> root_geometry; for (auto& entry : observations_) { needs_occlusion_tracking |= entry.key->NeedsOcclusionTracking(); - entry.value->ComputeIntersection(flags, monotonic_time, root_geometry); + entry.value->ComputeIntersection(flags, + IntersectionGeometry::kInfiniteScrollDelta, + monotonic_time, root_geometry); } return needs_occlusion_tracking; }
diff --git a/third_party/blink/renderer/core/intersection_observer/intersection_geometry.cc b/third_party/blink/renderer/core/intersection_observer/intersection_geometry.cc index ac7c820..ce277b9 100644 --- a/third_party/blink/renderer/core/intersection_observer/intersection_geometry.cc +++ b/third_party/blink/renderer/core/intersection_observer/intersection_geometry.cc
@@ -222,7 +222,7 @@ } RootAndTarget root_and_target(root_node, target_element, - !scroll_margin.empty()); + !target_margin.empty(), !scroll_margin.empty()); UpdateShouldUseCachedRects(root_and_target, cached_rects); if (root_and_target.relationship == RootAndTarget::kInvalid) { return; @@ -241,10 +241,11 @@ IntersectionGeometry::RootAndTarget::RootAndTarget( const Node* root_node, const Element& target_element, + bool has_target_margin, bool has_scroll_margin) : target(GetTargetLayoutObject(target_element)), root(target ? GetRootLayoutObject(root_node) : nullptr) { - ComputeRelationship(!root_node, has_scroll_margin); + ComputeRelationship(!root_node, has_target_margin, has_scroll_margin); } bool IsAllowedLayoutObjectType(const LayoutObject& target) { @@ -294,6 +295,7 @@ void IntersectionGeometry::RootAndTarget::ComputeRelationship( bool root_is_implicit, + bool has_target_margin, bool has_scroll_margin) { if (!root || !target || root == target) { relationship = kInvalid; @@ -329,9 +331,9 @@ relationship = kInvalid; return; } - if (container != root && container->HasNonVisibleOverflow() && - // Non-scrollable scrollers are ignored. - To<LayoutBox>(container)->HasLayoutOverflow()) { + if (container != root && container->ShouldClipOverflowAlongEitherAxis() && + // Clippers that don't actually clip anything are ignored. + (To<LayoutBox>(container)->HasLayoutOverflow() || has_target_margin)) { has_intermediate_clippers = true; } if (container != root && has_scroll_margin && @@ -340,7 +342,7 @@ } } if (has_intermediate_clippers) { - relationship = kScrollableWithIntermediateClippers; + relationship = kHasIntermediateClippers; } else if (root->IsScrollContainer() && To<LayoutBox>(root)->HasLayoutOverflow()) { relationship = kScrollableByRootOnly; @@ -588,11 +590,10 @@ root_rect_ = PhysicalRect::EnclosingRect(root_float_rect); } - min_scroll_delta_to_update_ = ComputeMinScrollDeltaToUpdate( - root_and_target, target_to_document_transform, - root_geometry.root_to_document_transform, thresholds, scroll_margin); if (cached_rects) { - cached_rects->min_scroll_delta_to_update = min_scroll_delta_to_update_; + cached_rects->min_scroll_delta_to_update = ComputeMinScrollDeltaToUpdate( + root_and_target, target_to_document_transform, + root_geometry.root_to_document_transform, thresholds, scroll_margin); cached_rects->valid = true; } } @@ -808,7 +809,7 @@ } if (target_rect_.Contains(root_rect_) && root_and_target.relationship == - RootAndTarget::kScrollableWithIntermediateClippers) { + RootAndTarget::kHasIntermediateClippers) { // When target_rect_ fully contains root_rect_, whether the intersection // rect fully covers root_rect_ depends on intermediate clips, so there // is no minimum scroll delta. @@ -823,7 +824,7 @@ } if (root_rect_.Contains(target_rect_) && root_and_target.relationship == - RootAndTarget::kScrollableWithIntermediateClippers) { + RootAndTarget::kHasIntermediateClippers) { // When root_rect_ fully contains target_rect_, whether target_rect_ // is fully visible depends on intermediate clips, so there is no // minimum scroll delta. @@ -846,7 +847,7 @@ if (root_rect_.IntersectsInclusively(target_rect_) && (thresholds.size() != 1 || thresholds[0] > kMinimumThreshold || root_and_target.relationship == - RootAndTarget::kScrollableWithIntermediateClippers || + RootAndTarget::kHasIntermediateClippers || IsForFrameViewportIntersection())) { return gfx::Vector2dF(); }
diff --git a/third_party/blink/renderer/core/intersection_observer/intersection_geometry.h b/third_party/blink/renderer/core/intersection_observer/intersection_geometry.h index c8b2338..1cda23a 100644 --- a/third_party/blink/renderer/core/intersection_observer/intersection_geometry.h +++ b/third_party/blink/renderer/core/intersection_observer/intersection_geometry.h
@@ -73,8 +73,10 @@ // Target rect mapped up to the root's space, with intermediate clips // applied, but without applying the root's clip or scroll offset. PhysicalRect unscrolled_unclipped_intersection_rect; - // We only need to update intersection geometry on future scroll if - // the scroll delta >= this value in either direction. + // This is calculated basically based on the distance between the root rect + // and the target rect, when it's applicable. On each scroll, we subtract + // the absolute scroll delta from it, and only need to update intersection + // geometry if it becomes <= 0 along either axis. gfx::Vector2dF min_scroll_delta_to_update; // True iff unscrolled_unclipped_intersection_rect actually intersects the // root, as defined by edge-inclusive intersection rules. @@ -139,10 +141,6 @@ bool IsIntersecting() const { return threshold_index_ > 0; } bool IsVisible() const { return flags_ & kIsVisible; } - gfx::Vector2dF MinScrollDeltaToUpdate() const { - return min_scroll_delta_to_update_; - } - bool CanUseCachedRectsForTesting() const { return ShouldUseCachedRects(); } private: @@ -158,6 +156,7 @@ public: RootAndTarget(const Node* root_node, const Element& target_element, + bool has_target_margin, bool has_scroll_margin); const LayoutObject* target; const LayoutObject* root; @@ -165,14 +164,15 @@ kInvalid, // The target is in a sub-frame of the implicit root. kTargetInSubFrame, - // The target can't be scrolled in the root by any scroller. + // There are intermediate clippers (scroll containers or not) between the + // root and the target. The target is likely to be scrollable in root. + kHasIntermediateClippers, + // The target can't be scrolled in the root by any scroller, without any + // intermediate clippers. kNotScrollable, // The target can be scrolled in the root by the root only, without any - // intermediate clippers (scroll containers or not). + // intermediate clippers. kScrollableByRootOnly, - // The target can be scrolled in the root, with intermediate clippers - // (scroll containers or not). - kScrollableWithIntermediateClippers, }; Relationship relationship = kInvalid; // This is used only when relationship is kScrollable*. @@ -182,7 +182,9 @@ private: const LayoutObject* GetRootLayoutObject(const Node* root_node) const; - void ComputeRelationship(bool root_is_implicit, bool has_scroll_margin); + void ComputeRelationship(bool root_is_implicit, + bool has_target_margin, + bool has_scroll_margin); }; void UpdateShouldUseCachedRects(const RootAndTarget& root_and_target, @@ -226,7 +228,6 @@ PhysicalRect intersection_rect_; PhysicalRect unclipped_intersection_rect_; PhysicalRect root_rect_; - gfx::Vector2dF min_scroll_delta_to_update_; unsigned flags_; double intersection_ratio_ = 0; wtf_size_t threshold_index_ = 0;
diff --git a/third_party/blink/renderer/core/intersection_observer/intersection_observation.cc b/third_party/blink/renderer/core/intersection_observer/intersection_observation.cc index d549fb9..6cd2614d 100644 --- a/third_party/blink/renderer/core/intersection_observer/intersection_observation.cc +++ b/third_party/blink/renderer/core/intersection_observer/intersection_observation.cc
@@ -4,6 +4,7 @@ #include "third_party/blink/renderer/core/intersection_observer/intersection_observation.h" +#include "base/debug/stack_trace.h" #include "third_party/blink/renderer/core/dom/element_rare_data_vector.h" #include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/core/intersection_observer/element_intersection_observer_data.h" @@ -16,6 +17,8 @@ #include "third_party/blink/renderer/core/layout/layout_view.h" #include "third_party/blink/renderer/core/paint/paint_layer.h" +#define CHECK_SKIPPED_UPDATE_ON_SCROLL DCHECK_IS_ON() + namespace blink { namespace { @@ -36,9 +39,12 @@ int64_t IntersectionObservation::ComputeIntersection( unsigned compute_flags, + gfx::Vector2dF accumulated_scroll_delta_since_last_update, absl::optional<base::TimeTicks>& monotonic_time, absl::optional<IntersectionGeometry::RootGeometry>& root_geometry) { DCHECK(Observer()); + cached_rects_.min_scroll_delta_to_update -= + accumulated_scroll_delta_since_last_update; if (compute_flags & (observer_->RootIsImplicit() ? kImplicitRootObserversNeedUpdate : kExplicitRootObserversNeedUpdate)) { @@ -52,11 +58,35 @@ if (MaybeDelayAndReschedule(compute_flags, timestamp)) return 0; +#if CHECK_SKIPPED_UPDATE_ON_SCROLL + std::optional<IntersectionGeometry::CachedRects> cached_rects_backup; +#endif + if (RuntimeEnabledFeatures::IntersectionOptimizationEnabled() && + cached_rects_.valid && cached_rects_.min_scroll_delta_to_update.x() > 0 && + cached_rects_.min_scroll_delta_to_update.y() > 0) { +#if CHECK_SKIPPED_UPDATE_ON_SCROLL + cached_rects_backup.emplace(cached_rects_); +#else + return 0; +#endif + } + unsigned geometry_flags = GetIntersectionGeometryFlags(compute_flags); IntersectionGeometry geometry( observer_->root(), *Target(), observer_->RootMargin(), observer_->thresholds(), observer_->TargetMargin(), observer_->ScrollMargin(), geometry_flags, root_geometry, &cached_rects_); + +#if CHECK_SKIPPED_UPDATE_ON_SCROLL + if (cached_rects_backup) { + // A skipped update on scroll should generate the same result. + cached_rects_ = cached_rects_backup.value(); + CHECK_EQ(last_threshold_index_, geometry.ThresholdIndex()); + CHECK_EQ(last_is_visible_, geometry.IsVisible()); + return 0; + } +#endif + ProcessIntersectionGeometry(geometry, timestamp); last_run_time_ = timestamp; needs_update_ = false;
diff --git a/third_party/blink/renderer/core/intersection_observer/intersection_observation.h b/third_party/blink/renderer/core/intersection_observer/intersection_observation.h index d5b32e2..bb61d7b 100644 --- a/third_party/blink/renderer/core/intersection_observer/intersection_observation.h +++ b/third_party/blink/renderer/core/intersection_observer/intersection_observation.h
@@ -33,36 +33,30 @@ // root bounds (i.e., size of the top document's viewport) should be // included in any IntersectionObserverEntry objects created by Compute(). kReportImplicitRootBounds = 1 << 0, - // If this bit is set, we need to update frames' viewport intersection. - // This flag is used in Frame/FrameView only. It doesn't matter to - // intersection observations in the current local frame tree, while - // viewport intersection of the current frame can trigger intersection - // observation updates in child remote frames. - kFrameViewportIntersectionNeedsUpdate = 1 << 1, // If this bit is set, and observer_->RootIsImplicit() is false, then // Compute() should update the observation. - kExplicitRootObserversNeedUpdate = 1 << 2, + kExplicitRootObserversNeedUpdate = 1 << 1, // If this bit is set, and observer_->RootIsImplicit() is true, then // Compute() should update the observation. - kImplicitRootObserversNeedUpdate = 1 << 3, + kImplicitRootObserversNeedUpdate = 1 << 2, // If this bit is set, it indicates that at least one LocalFrameView // ancestor is detached from the LayoutObject tree of its parent. Usually, // this is unnecessary -- if an ancestor FrameView is detached, then all // descendant frames are detached. There is, however, at least one exception // to this rule; see crbug.com/749737 for details. - kAncestorFrameIsDetachedFromLayout = 1 << 4, + kAncestorFrameIsDetachedFromLayout = 1 << 3, // If this bit is set, then the observer.delay parameter is ignored; i.e., // the computation will run even if the previous run happened within the // delay parameter. - kIgnoreDelay = 1 << 5, + kIgnoreDelay = 1 << 4, // If this bit is set, we can skip tracking the sticky frame during // UpdateViewportIntersectionsForSubtree. - kCanSkipStickyFrameTracking = 1 << 6, + kCanSkipStickyFrameTracking = 1 << 5, // If this bit is set, we only process intersection observations that // require post-layout delivery. - kPostLayoutDeliveryOnly = 1 << 7, + kPostLayoutDeliveryOnly = 1 << 6, // If this is set, the overflow clip edge is used. - kUseOverflowClipEdge = 1 << 8, + kUseOverflowClipEdge = 1 << 7, }; IntersectionObservation(IntersectionObserver&, Element&); @@ -73,6 +67,7 @@ // bool, but int64_t matches IntersectionObserver::ComputeIntersections(). int64_t ComputeIntersection( unsigned flags, + gfx::Vector2dF accumulated_scroll_delta_since_last_update, absl::optional<base::TimeTicks>& monotonic_time, absl::optional<IntersectionGeometry::RootGeometry>& root_geometry); gfx::Vector2dF MinScrollDeltaToUpdate() const;
diff --git a/third_party/blink/renderer/core/intersection_observer/intersection_observer.cc b/third_party/blink/renderer/core/intersection_observer/intersection_observer.cc index 4bbae54..d4f9fdf 100644 --- a/third_party/blink/renderer/core/intersection_observer/intersection_observer.cc +++ b/third_party/blink/renderer/core/intersection_observer/intersection_observer.cc
@@ -324,6 +324,7 @@ IntersectionObserver* IntersectionObserver::Create( const Vector<Length>& margin, + const Vector<Length>& scroll_margin, const Vector<float>& thresholds, Document* document, EventCallback callback, @@ -342,10 +343,9 @@ document->GetExecutionContext(), std::move(callback), ukm_metric_id, behavior, needs_initial_observation_with_detached_target); return MakeGarbageCollected<IntersectionObserver>( - *intersection_observer_delegate, nullptr, margin, - /* scroll_margin */ Vector<Length>(), thresholds, semantics, delay, - track_visibility, always_report_root_bounds, margin_target, - use_overflow_clip_edge); + *intersection_observer_delegate, nullptr, margin, scroll_margin, + thresholds, semantics, delay, track_visibility, always_report_root_bounds, + margin_target, use_overflow_clip_edge); } IntersectionObserver::IntersectionObserver( @@ -449,7 +449,8 @@ (use_overflow_clip_edge_ ? IntersectionObservation::kUseOverflowClipEdge : 0), - monotonic_time, root_geometry); + IntersectionGeometry::kInfiniteScrollDelta, monotonic_time, + root_geometry); } } @@ -515,45 +516,45 @@ ->MonotonicTimeToDOMHighResTimeStamp(monotonic_time); } -bool IntersectionObserver::HasRootMargin() const { - if (margin_target_ == kApplyMarginToTarget) { - return false; - } - CHECK_EQ(margin_.size(), 4u); - return !margin_[0].IsZero() || !margin_[1].IsZero() || !margin_[2].IsZero() || - !margin_[3].IsZero(); -} - int64_t IntersectionObserver::ComputeIntersections( unsigned flags, - absl::optional<base::TimeTicks>& monotonic_time) { + absl::optional<base::TimeTicks>& monotonic_time, + gfx::Vector2dF accumulated_scroll_delta_since_last_update) { DCHECK(!RootIsImplicit()); if (!RootIsValid() || !GetExecutionContext() || observations_.empty()) return 0; - // If we're processing post-layout deliveries only and we're not a post-layout - // delivery observer, then return early. Likewise, return if we need to - // compute non-post-layout-delivery observations but the observer behavior is - // post-layout. - bool post_layout_delivery_only = - flags & IntersectionObservation::kPostLayoutDeliveryOnly; - bool is_post_layout_delivery_observer = - GetDeliveryBehavior() == - IntersectionObserver::kDeliverDuringPostLayoutSteps; - if (post_layout_delivery_only != is_post_layout_delivery_observer) - return 0; - if (use_overflow_clip_edge_) flags |= IntersectionObservation::kUseOverflowClipEdge; absl::optional<IntersectionGeometry::RootGeometry> root_geometry; - // TODO(szager): Is this copy necessary? - HeapVector<Member<IntersectionObservation>> observations_to_process( - observations_); int64_t result = 0; - for (auto& observation : observations_to_process) { - result += - observation->ComputeIntersection(flags, monotonic_time, root_geometry); + if (RuntimeEnabledFeatures::IntersectionOptimizationEnabled()) { + for (auto& observation : observations_) { + result += observation->ComputeIntersection( + flags, accumulated_scroll_delta_since_last_update, monotonic_time, + root_geometry); + } + } else { + // If we're processing post-layout deliveries only and we're not a + // post-layout delivery observer, then return early. Likewise, return if we + // need to compute non-post-layout-delivery observations but the observer + // behavior is post-layout. + bool post_layout_delivery_only = + flags & IntersectionObservation::kPostLayoutDeliveryOnly; + bool is_post_layout_delivery_observer = + GetDeliveryBehavior() == + IntersectionObserver::kDeliverDuringPostLayoutSteps; + if (post_layout_delivery_only != is_post_layout_delivery_observer) { + return 0; + } + // TODO(szager): Is this copy necessary? + HeapVector<Member<IntersectionObservation>> observations_to_process( + observations_); + for (auto& observation : observations_to_process) { + result += observation->ComputeIntersection(flags, gfx::Vector2dF(), + monotonic_time, root_geometry); + } } return result; }
diff --git a/third_party/blink/renderer/core/intersection_observer/intersection_observer.h b/third_party/blink/renderer/core/intersection_observer/intersection_observer.h index 6dc21a5..c886ee3 100644 --- a/third_party/blink/renderer/core/intersection_observer/intersection_observer.h +++ b/third_party/blink/renderer/core/intersection_observer/intersection_observer.h
@@ -107,6 +107,7 @@ // should be used instead of the bounding box if appropriate. static IntersectionObserver* Create( const Vector<Length>& margin, + const Vector<Length>& scroll_margin, const Vector<float>& thresholds, Document* document, EventCallback callback, @@ -172,13 +173,14 @@ Vector<Length> TargetMargin() const { return margin_target_ == kApplyMarginToTarget ? margin_ : Vector<Length>(); } - bool HasRootMargin() const; Vector<Length> ScrollMargin() const { return scroll_margin_; } // Returns the number of IntersectionObservations that recomputed geometry. - int64_t ComputeIntersections(unsigned flags, - absl::optional<base::TimeTicks>& monotonic_time); + int64_t ComputeIntersections( + unsigned flags, + absl::optional<base::TimeTicks>& monotonic_time, + gfx::Vector2dF accumulated_scroll_delta_since_last_update); gfx::Vector2dF MinScrollDeltaToUpdate() const; bool IsInternal() const; @@ -225,6 +227,7 @@ Vector<Length> margin_; Vector<Length> scroll_margin_; MarginTarget margin_target_; + gfx::Vector2dF accumulated_scroll_delta_since_last_update_; unsigned root_is_implicit_ : 1; unsigned track_visibility_ : 1; unsigned track_fraction_of_root_ : 1;
diff --git a/third_party/blink/renderer/core/intersection_observer/intersection_observer_controller.cc b/third_party/blink/renderer/core/intersection_observer/intersection_observer_controller.cc index dce7dd8..c4afd40 100644 --- a/third_party/blink/renderer/core/intersection_observer/intersection_observer_controller.cc +++ b/third_party/blink/renderer/core/intersection_observer/intersection_observer_controller.cc
@@ -60,20 +60,18 @@ } } -IntersectionUpdateResult IntersectionObserverController::ComputeIntersections( +bool IntersectionObserverController::ComputeIntersections( unsigned flags, LocalFrameUkmAggregator* metrics_aggregator, - absl::optional<base::TimeTicks>& monotonic_time) { + absl::optional<base::TimeTicks>& monotonic_time, + gfx::Vector2dF accumulated_scroll_delta_since_last_update) { needs_occlusion_tracking_ = false; if (!GetExecutionContext()) { - return IntersectionUpdateResult(); + return false; } TRACE_EVENT0("blink,devtools.timeline", "IntersectionObserverController::" "computeIntersections"); - bool has_implicit_root_observer_with_margin = false; - gfx::Vector2dF min_scroll_delta_to_update = - IntersectionGeometry::kInfiniteScrollDelta; HeapVector<Member<IntersectionObserver>> observers_to_process( tracked_explicit_root_observers_); HeapVector<Member<IntersectionObservation>> observations_to_process( @@ -89,13 +87,13 @@ if (observer->HasObservations()) { if (metrics_timer) metrics_timer->StartInterval(observer->GetUkmMetricId()); - int64_t count = observer->ComputeIntersections(flags, monotonic_time); + int64_t count = observer->ComputeIntersections( + flags, monotonic_time, accumulated_scroll_delta_since_last_update); if (observer->IsInternal()) internal_observation_count += count; else javascript_observation_count += count; needs_occlusion_tracking_ |= observer->trackVisibility(); - min_scroll_delta_to_update.SetToMin(observer->MinScrollDeltaToUpdate()); } else { tracked_explicit_root_observers_.erase(observer); } @@ -104,18 +102,14 @@ if (metrics_timer) metrics_timer->StartInterval(observation->Observer()->GetUkmMetricId()); absl::optional<IntersectionGeometry::RootGeometry> root_geometry; - int64_t count = observation->ComputeIntersection(flags, monotonic_time, - root_geometry); + int64_t count = observation->ComputeIntersection( + flags, accumulated_scroll_delta_since_last_update, monotonic_time, + root_geometry); if (observation->Observer()->IsInternal()) internal_observation_count += count; else javascript_observation_count += count; needs_occlusion_tracking_ |= observation->Observer()->trackVisibility(); - has_implicit_root_observer_with_margin |= - observation->Observer()->RootIsImplicit() && - observation->Observer()->HasRootMargin(); - min_scroll_delta_to_update.SetToMin( - observation->MinScrollDeltaToUpdate()); } } @@ -128,9 +122,7 @@ javascript_observation_count); } - return IntersectionUpdateResult{needs_occlusion_tracking_, - has_implicit_root_observer_with_margin, - min_scroll_delta_to_update}; + return needs_occlusion_tracking_; } void IntersectionObserverController::AddTrackedObserver(
diff --git a/third_party/blink/renderer/core/intersection_observer/intersection_observer_controller.h b/third_party/blink/renderer/core/intersection_observer/intersection_observer_controller.h index cb85860b..be32205 100644 --- a/third_party/blink/renderer/core/intersection_observer/intersection_observer_controller.h +++ b/third_party/blink/renderer/core/intersection_observer/intersection_observer_controller.h
@@ -18,18 +18,6 @@ class ExecutionContext; -struct IntersectionUpdateResult { - // True if trackVisibility() is true for any tracked observer. - bool needs_occlusion_tracking = false; - // If this is true, the parent frame will use zero min_scroll_delta_to_update, - // i.e. will update intersection on every scroll. - bool has_implicit_root_observer_with_margin = false; - // We only need to update intersection if the accumulated scroll delta in the - // frame exceeds this value in either direction. - gfx::Vector2dF min_scroll_delta_to_update = - IntersectionGeometry::kInfiniteScrollDelta; -}; - class IntersectionObserverController : public GarbageCollected<IntersectionObserverController>, public ExecutionContextClient, @@ -46,11 +34,14 @@ // The flags argument is composed of values from // IntersectionObservation::ComputeFlags. They are dirty bits that control - // whether an IntersectionObserver needs to do any work. - IntersectionUpdateResult ComputeIntersections( + // whether an IntersectionObserver needs to do any work. The return value + // communicates whether observer->trackVisibility() is true for any tracked + // observer. + bool ComputeIntersections( unsigned flags, LocalFrameUkmAggregator* metrics_aggregator, - absl::optional<base::TimeTicks>& monotonic_time); + absl::optional<base::TimeTicks>& monotonic_time, + gfx::Vector2dF accumulated_scroll_delta_since_last_update); // The second argument indicates whether the Element is a target of any // observers for which observer->trackVisibility() is true.
diff --git a/third_party/blink/renderer/core/intersection_observer/intersection_observer_test.cc b/third_party/blink/renderer/core/intersection_observer/intersection_observer_test.cc index 74d0c43..7d37451d 100644 --- a/third_party/blink/renderer/core/intersection_observer/intersection_observer_test.cc +++ b/third_party/blink/renderer/core/intersection_observer/intersection_observer_test.cc
@@ -1301,8 +1301,9 @@ ASSERT_FALSE(exception_state.HadException()); observer->observe(target, exception_state); ASSERT_FALSE(exception_state.HadException()); - EXPECT_EQ(gfx::Vector2dF(), - frame_view->MinScrollDeltaToUpdateIntersectionForTesting()); + const IntersectionObservation* observation = + target->IntersectionObserverData()->GetObservationFor(*observer); + EXPECT_EQ(gfx::Vector2dF(), observation->MinScrollDeltaToUpdate()); EXPECT_EQ(LocalFrameView::kRequired, frame_view->GetIntersectionObservationStateForTesting()); @@ -1312,7 +1313,7 @@ EXPECT_EQ(observer_delegate->EntryCount(), 1); EXPECT_FALSE(observer_delegate->LastEntry()->isIntersecting()); EXPECT_EQ(IntersectionGeometry::kInfiniteScrollDelta, - frame_view->MinScrollDeltaToUpdateIntersectionForTesting()); + observation->MinScrollDeltaToUpdate()); EXPECT_EQ(LocalFrameView::kNotNeeded, frame_view->GetIntersectionObservationStateForTesting()); } @@ -1346,8 +1347,9 @@ ASSERT_FALSE(exception_state.HadException()); observer->observe(target, exception_state); ASSERT_FALSE(exception_state.HadException()); - EXPECT_EQ(gfx::Vector2dF(), - frame_view->MinScrollDeltaToUpdateIntersectionForTesting()); + const IntersectionObservation* observation = + target->IntersectionObserverData()->GetObservationFor(*observer); + EXPECT_EQ(gfx::Vector2dF(), observation->MinScrollDeltaToUpdate()); EXPECT_EQ(LocalFrameView::kRequired, frame_view->GetIntersectionObservationStateForTesting()); @@ -1356,15 +1358,13 @@ EXPECT_EQ(observer_delegate->CallCount(), 1); EXPECT_EQ(observer_delegate->EntryCount(), 1); EXPECT_FALSE(observer_delegate->LastEntry()->isIntersecting()); - EXPECT_EQ(gfx::Vector2dF(50, 100), - frame_view->MinScrollDeltaToUpdateIntersectionForTesting()); + EXPECT_EQ(gfx::Vector2dF(50, 100), observation->MinScrollDeltaToUpdate()); EXPECT_EQ(LocalFrameView::kNotNeeded, frame_view->GetIntersectionObservationStateForTesting()); root->scrollTo(0, 50); - EXPECT_EQ(gfx::Vector2dF(50, 100), - frame_view->MinScrollDeltaToUpdateIntersectionForTesting()); - EXPECT_EQ(LocalFrameView::kFrameViewportIntersectionOnly, + EXPECT_EQ(gfx::Vector2dF(50, 100), observation->MinScrollDeltaToUpdate()); + EXPECT_EQ(LocalFrameView::kDesired, frame_view->GetIntersectionObservationStateForTesting()); Compositor().BeginFrame(); test::RunPendingTasks(); @@ -1373,8 +1373,7 @@ EXPECT_FALSE(observer_delegate->LastEntry()->isIntersecting()); root->scrollTo(0, 100); - EXPECT_EQ(gfx::Vector2dF(50, 100), - frame_view->MinScrollDeltaToUpdateIntersectionForTesting()); + EXPECT_EQ(gfx::Vector2dF(50, 50), observation->MinScrollDeltaToUpdate()); EXPECT_EQ(LocalFrameView::kDesired, frame_view->GetIntersectionObservationStateForTesting()); Compositor().BeginFrame(); @@ -1382,14 +1381,12 @@ EXPECT_EQ(observer_delegate->CallCount(), 2); EXPECT_EQ(observer_delegate->EntryCount(), 2); EXPECT_TRUE(observer_delegate->LastEntry()->isIntersecting()); - EXPECT_EQ(gfx::Vector2dF(50, 0), - frame_view->MinScrollDeltaToUpdateIntersectionForTesting()); + EXPECT_EQ(gfx::Vector2dF(50, 0), observation->MinScrollDeltaToUpdate()); EXPECT_EQ(LocalFrameView::kNotNeeded, frame_view->GetIntersectionObservationStateForTesting()); root->scrollTo(0, 101); - EXPECT_EQ(gfx::Vector2dF(50, 0), - frame_view->MinScrollDeltaToUpdateIntersectionForTesting()); + EXPECT_EQ(gfx::Vector2dF(50, 0), observation->MinScrollDeltaToUpdate()); EXPECT_EQ(LocalFrameView::kDesired, frame_view->GetIntersectionObservationStateForTesting()); Compositor().BeginFrame(); @@ -1397,14 +1394,12 @@ EXPECT_EQ(observer_delegate->CallCount(), 2); EXPECT_EQ(observer_delegate->EntryCount(), 2); EXPECT_TRUE(observer_delegate->LastEntry()->isIntersecting()); - EXPECT_EQ(gfx::Vector2dF(50, 1), - frame_view->MinScrollDeltaToUpdateIntersectionForTesting()); + EXPECT_EQ(gfx::Vector2dF(50, 1), observation->MinScrollDeltaToUpdate()); EXPECT_EQ(LocalFrameView::kNotNeeded, frame_view->GetIntersectionObservationStateForTesting()); root->scrollTo(51, 101); - EXPECT_EQ(gfx::Vector2dF(50, 1), - frame_view->MinScrollDeltaToUpdateIntersectionForTesting()); + EXPECT_EQ(gfx::Vector2dF(50, 1), observation->MinScrollDeltaToUpdate()); EXPECT_EQ(LocalFrameView::kDesired, frame_view->GetIntersectionObservationStateForTesting()); Compositor().BeginFrame(); @@ -1412,8 +1407,7 @@ EXPECT_EQ(observer_delegate->CallCount(), 3); EXPECT_EQ(observer_delegate->EntryCount(), 3); EXPECT_FALSE(observer_delegate->LastEntry()->isIntersecting()); - EXPECT_EQ(gfx::Vector2dF(1, 1), - frame_view->MinScrollDeltaToUpdateIntersectionForTesting()); + EXPECT_EQ(gfx::Vector2dF(1, 1), observation->MinScrollDeltaToUpdate()); EXPECT_EQ(LocalFrameView::kNotNeeded, frame_view->GetIntersectionObservationStateForTesting()); } @@ -1445,8 +1439,9 @@ ASSERT_FALSE(exception_state.HadException()); observer->observe(target, exception_state); ASSERT_FALSE(exception_state.HadException()); - EXPECT_EQ(gfx::Vector2dF(), - frame_view->MinScrollDeltaToUpdateIntersectionForTesting()); + const IntersectionObservation* observation = + target->IntersectionObserverData()->GetObservationFor(*observer); + EXPECT_EQ(gfx::Vector2dF(), observation->MinScrollDeltaToUpdate()); EXPECT_EQ(LocalFrameView::kRequired, frame_view->GetIntersectionObservationStateForTesting()); @@ -1455,25 +1450,25 @@ EXPECT_EQ(observer_delegate->CallCount(), 1); EXPECT_EQ(observer_delegate->EntryCount(), 1); EXPECT_FALSE(observer_delegate->LastEntry()->isIntersecting()); - EXPECT_EQ(gfx::Vector2dF(50, 100), - frame_view->MinScrollDeltaToUpdateIntersectionForTesting()); + EXPECT_EQ(gfx::Vector2dF(50, 100), observation->MinScrollDeltaToUpdate()); EXPECT_EQ(LocalFrameView::kNotNeeded, frame_view->GetIntersectionObservationStateForTesting()); window.scrollTo(0, 50); - EXPECT_EQ(gfx::Vector2dF(50, 100), - frame_view->MinScrollDeltaToUpdateIntersectionForTesting()); - EXPECT_EQ(LocalFrameView::kFrameViewportIntersectionOnly, + EXPECT_EQ(gfx::Vector2dF(50, 100), observation->MinScrollDeltaToUpdate()); + EXPECT_EQ(LocalFrameView::kDesired, frame_view->GetIntersectionObservationStateForTesting()); Compositor().BeginFrame(); test::RunPendingTasks(); EXPECT_EQ(observer_delegate->CallCount(), 1); EXPECT_EQ(observer_delegate->EntryCount(), 1); EXPECT_FALSE(observer_delegate->LastEntry()->isIntersecting()); + EXPECT_EQ(gfx::Vector2dF(50, 50), observation->MinScrollDeltaToUpdate()); + EXPECT_EQ(LocalFrameView::kNotNeeded, + frame_view->GetIntersectionObservationStateForTesting()); window.scrollTo(0, 100); - EXPECT_EQ(gfx::Vector2dF(50, 100), - frame_view->MinScrollDeltaToUpdateIntersectionForTesting()); + EXPECT_EQ(gfx::Vector2dF(50, 50), observation->MinScrollDeltaToUpdate()); EXPECT_EQ(LocalFrameView::kDesired, frame_view->GetIntersectionObservationStateForTesting()); Compositor().BeginFrame(); @@ -1481,14 +1476,12 @@ EXPECT_EQ(observer_delegate->CallCount(), 2); EXPECT_EQ(observer_delegate->EntryCount(), 2); EXPECT_TRUE(observer_delegate->LastEntry()->isIntersecting()); - EXPECT_EQ(gfx::Vector2dF(50, 0), - frame_view->MinScrollDeltaToUpdateIntersectionForTesting()); + EXPECT_EQ(gfx::Vector2dF(50, 0), observation->MinScrollDeltaToUpdate()); EXPECT_EQ(LocalFrameView::kNotNeeded, frame_view->GetIntersectionObservationStateForTesting()); window.scrollTo(0, 101); - EXPECT_EQ(gfx::Vector2dF(50, 0), - frame_view->MinScrollDeltaToUpdateIntersectionForTesting()); + EXPECT_EQ(gfx::Vector2dF(50, 0), observation->MinScrollDeltaToUpdate()); EXPECT_EQ(LocalFrameView::kDesired, frame_view->GetIntersectionObservationStateForTesting()); Compositor().BeginFrame(); @@ -1496,14 +1489,12 @@ EXPECT_EQ(observer_delegate->CallCount(), 2); EXPECT_EQ(observer_delegate->EntryCount(), 2); EXPECT_TRUE(observer_delegate->LastEntry()->isIntersecting()); - EXPECT_EQ(gfx::Vector2dF(50, 1), - frame_view->MinScrollDeltaToUpdateIntersectionForTesting()); + EXPECT_EQ(gfx::Vector2dF(50, 1), observation->MinScrollDeltaToUpdate()); EXPECT_EQ(LocalFrameView::kNotNeeded, frame_view->GetIntersectionObservationStateForTesting()); window.scrollTo(51, 101); - EXPECT_EQ(gfx::Vector2dF(50, 1), - frame_view->MinScrollDeltaToUpdateIntersectionForTesting()); + EXPECT_EQ(gfx::Vector2dF(50, 1), observation->MinScrollDeltaToUpdate()); EXPECT_EQ(LocalFrameView::kDesired, frame_view->GetIntersectionObservationStateForTesting()); Compositor().BeginFrame(); @@ -1511,8 +1502,7 @@ EXPECT_EQ(observer_delegate->CallCount(), 3); EXPECT_EQ(observer_delegate->EntryCount(), 3); EXPECT_FALSE(observer_delegate->LastEntry()->isIntersecting()); - EXPECT_EQ(gfx::Vector2dF(1, 1), - frame_view->MinScrollDeltaToUpdateIntersectionForTesting()); + EXPECT_EQ(gfx::Vector2dF(1, 1), observation->MinScrollDeltaToUpdate()); EXPECT_EQ(LocalFrameView::kNotNeeded, frame_view->GetIntersectionObservationStateForTesting()); } @@ -1549,8 +1539,9 @@ ASSERT_FALSE(exception_state.HadException()); observer->observe(target, exception_state); ASSERT_FALSE(exception_state.HadException()); - EXPECT_EQ(gfx::Vector2dF(), - frame_view->MinScrollDeltaToUpdateIntersectionForTesting()); + const IntersectionObservation* observation = + target->IntersectionObserverData()->GetObservationFor(*observer); + EXPECT_EQ(gfx::Vector2dF(), observation->MinScrollDeltaToUpdate()); EXPECT_EQ(LocalFrameView::kRequired, frame_view->GetIntersectionObservationStateForTesting()); @@ -1559,15 +1550,13 @@ EXPECT_EQ(observer_delegate->CallCount(), 1); EXPECT_EQ(observer_delegate->EntryCount(), 1); EXPECT_FALSE(observer_delegate->LastEntry()->isIntersecting()); - EXPECT_EQ(gfx::Vector2dF(50, 100), - frame_view->MinScrollDeltaToUpdateIntersectionForTesting()); + EXPECT_EQ(gfx::Vector2dF(50, 100), observation->MinScrollDeltaToUpdate()); EXPECT_EQ(LocalFrameView::kNotNeeded, frame_view->GetIntersectionObservationStateForTesting()); root->scrollTo(0, 50); - EXPECT_EQ(gfx::Vector2dF(50, 100), - frame_view->MinScrollDeltaToUpdateIntersectionForTesting()); - EXPECT_EQ(LocalFrameView::kFrameViewportIntersectionOnly, + EXPECT_EQ(gfx::Vector2dF(50, 100), observation->MinScrollDeltaToUpdate()); + EXPECT_EQ(LocalFrameView::kDesired, frame_view->GetIntersectionObservationStateForTesting()); Compositor().BeginFrame(); test::RunPendingTasks(); @@ -1576,8 +1565,7 @@ EXPECT_FALSE(observer_delegate->LastEntry()->isIntersecting()); root->scrollTo(0, 100); - EXPECT_EQ(gfx::Vector2dF(50, 100), - frame_view->MinScrollDeltaToUpdateIntersectionForTesting()); + EXPECT_EQ(gfx::Vector2dF(50, 50), observation->MinScrollDeltaToUpdate()); EXPECT_EQ(LocalFrameView::kDesired, frame_view->GetIntersectionObservationStateForTesting()); Compositor().BeginFrame(); @@ -1585,14 +1573,12 @@ EXPECT_EQ(observer_delegate->CallCount(), 2); EXPECT_EQ(observer_delegate->EntryCount(), 2); EXPECT_TRUE(observer_delegate->LastEntry()->isIntersecting()); - EXPECT_EQ(gfx::Vector2dF(), - frame_view->MinScrollDeltaToUpdateIntersectionForTesting()); + EXPECT_EQ(gfx::Vector2dF(), observation->MinScrollDeltaToUpdate()); EXPECT_EQ(LocalFrameView::kNotNeeded, frame_view->GetIntersectionObservationStateForTesting()); root->scrollTo(0, 101); - EXPECT_EQ(gfx::Vector2dF(), - frame_view->MinScrollDeltaToUpdateIntersectionForTesting()); + EXPECT_EQ(gfx::Vector2dF(), observation->MinScrollDeltaToUpdate()); EXPECT_EQ(LocalFrameView::kDesired, frame_view->GetIntersectionObservationStateForTesting()); Compositor().BeginFrame(); @@ -1600,8 +1586,7 @@ EXPECT_EQ(observer_delegate->CallCount(), 2); EXPECT_EQ(observer_delegate->EntryCount(), 2); EXPECT_TRUE(observer_delegate->LastEntry()->isIntersecting()); - EXPECT_EQ(gfx::Vector2dF(), - frame_view->MinScrollDeltaToUpdateIntersectionForTesting()); + EXPECT_EQ(gfx::Vector2dF(), observation->MinScrollDeltaToUpdate()); EXPECT_EQ(LocalFrameView::kNotNeeded, frame_view->GetIntersectionObservationStateForTesting()); } @@ -1638,8 +1623,9 @@ ASSERT_FALSE(exception_state.HadException()); observer->observe(target, exception_state); ASSERT_FALSE(exception_state.HadException()); - EXPECT_EQ(gfx::Vector2dF(), - frame_view->MinScrollDeltaToUpdateIntersectionForTesting()); + const IntersectionObservation* observation = + target->IntersectionObserverData()->GetObservationFor(*observer); + EXPECT_EQ(gfx::Vector2dF(), observation->MinScrollDeltaToUpdate()); EXPECT_EQ(LocalFrameView::kRequired, frame_view->GetIntersectionObservationStateForTesting()); @@ -1648,15 +1634,13 @@ EXPECT_EQ(observer_delegate->CallCount(), 1); EXPECT_EQ(observer_delegate->EntryCount(), 1); EXPECT_FALSE(observer_delegate->LastEntry()->isIntersecting()); - EXPECT_EQ(gfx::Vector2dF(50, 100), - frame_view->MinScrollDeltaToUpdateIntersectionForTesting()); + EXPECT_EQ(gfx::Vector2dF(50, 100), observation->MinScrollDeltaToUpdate()); EXPECT_EQ(LocalFrameView::kNotNeeded, frame_view->GetIntersectionObservationStateForTesting()); root->scrollTo(0, 50); - EXPECT_EQ(gfx::Vector2dF(50, 100), - frame_view->MinScrollDeltaToUpdateIntersectionForTesting()); - EXPECT_EQ(LocalFrameView::kFrameViewportIntersectionOnly, + EXPECT_EQ(gfx::Vector2dF(50, 100), observation->MinScrollDeltaToUpdate()); + EXPECT_EQ(LocalFrameView::kDesired, frame_view->GetIntersectionObservationStateForTesting()); Compositor().BeginFrame(); test::RunPendingTasks(); @@ -1665,8 +1649,7 @@ EXPECT_FALSE(observer_delegate->LastEntry()->isIntersecting()); root->scrollTo(0, 100); - EXPECT_EQ(gfx::Vector2dF(50, 100), - frame_view->MinScrollDeltaToUpdateIntersectionForTesting()); + EXPECT_EQ(gfx::Vector2dF(50, 50), observation->MinScrollDeltaToUpdate()); EXPECT_EQ(LocalFrameView::kDesired, frame_view->GetIntersectionObservationStateForTesting()); Compositor().BeginFrame(); @@ -1674,14 +1657,12 @@ EXPECT_EQ(observer_delegate->CallCount(), 1); EXPECT_EQ(observer_delegate->EntryCount(), 1); EXPECT_FALSE(observer_delegate->LastEntry()->isIntersecting()); - EXPECT_EQ(gfx::Vector2dF(50, 0), - frame_view->MinScrollDeltaToUpdateIntersectionForTesting()); + EXPECT_EQ(gfx::Vector2dF(50, 0), observation->MinScrollDeltaToUpdate()); EXPECT_EQ(LocalFrameView::kNotNeeded, frame_view->GetIntersectionObservationStateForTesting()); root->scrollTo(0, 101); - EXPECT_EQ(gfx::Vector2dF(50, 0), - frame_view->MinScrollDeltaToUpdateIntersectionForTesting()); + EXPECT_EQ(gfx::Vector2dF(50, 0), observation->MinScrollDeltaToUpdate()); EXPECT_EQ(LocalFrameView::kDesired, frame_view->GetIntersectionObservationStateForTesting()); Compositor().BeginFrame(); @@ -1689,14 +1670,12 @@ EXPECT_EQ(observer_delegate->CallCount(), 2); EXPECT_EQ(observer_delegate->EntryCount(), 2); EXPECT_TRUE(observer_delegate->LastEntry()->isIntersecting()); - EXPECT_EQ(gfx::Vector2dF(50, 1), - frame_view->MinScrollDeltaToUpdateIntersectionForTesting()); + EXPECT_EQ(gfx::Vector2dF(50, 1), observation->MinScrollDeltaToUpdate()); EXPECT_EQ(LocalFrameView::kNotNeeded, frame_view->GetIntersectionObservationStateForTesting()); root->scrollTo(51, 101); - EXPECT_EQ(gfx::Vector2dF(50, 1), - frame_view->MinScrollDeltaToUpdateIntersectionForTesting()); + EXPECT_EQ(gfx::Vector2dF(50, 1), observation->MinScrollDeltaToUpdate()); EXPECT_EQ(LocalFrameView::kDesired, frame_view->GetIntersectionObservationStateForTesting()); Compositor().BeginFrame(); @@ -1704,8 +1683,7 @@ EXPECT_EQ(observer_delegate->CallCount(), 3); EXPECT_EQ(observer_delegate->EntryCount(), 3); EXPECT_FALSE(observer_delegate->LastEntry()->isIntersecting()); - EXPECT_EQ(gfx::Vector2dF(1, 1), - frame_view->MinScrollDeltaToUpdateIntersectionForTesting()); + EXPECT_EQ(gfx::Vector2dF(1, 1), observation->MinScrollDeltaToUpdate()); EXPECT_EQ(LocalFrameView::kNotNeeded, frame_view->GetIntersectionObservationStateForTesting()); } @@ -1741,8 +1719,9 @@ ASSERT_FALSE(exception_state.HadException()); observer->observe(target, exception_state); ASSERT_FALSE(exception_state.HadException()); - EXPECT_EQ(gfx::Vector2dF(), - frame_view->MinScrollDeltaToUpdateIntersectionForTesting()); + const IntersectionObservation* observation = + target->IntersectionObserverData()->GetObservationFor(*observer); + EXPECT_EQ(gfx::Vector2dF(), observation->MinScrollDeltaToUpdate()); EXPECT_EQ(LocalFrameView::kRequired, frame_view->GetIntersectionObservationStateForTesting()); @@ -1751,25 +1730,12 @@ EXPECT_EQ(observer_delegate->CallCount(), 1); EXPECT_EQ(observer_delegate->EntryCount(), 1); EXPECT_FALSE(observer_delegate->LastEntry()->isIntersecting()); - EXPECT_EQ(gfx::Vector2dF(50, 100), - frame_view->MinScrollDeltaToUpdateIntersectionForTesting()); + EXPECT_EQ(gfx::Vector2dF(50, 100), observation->MinScrollDeltaToUpdate()); EXPECT_EQ(LocalFrameView::kNotNeeded, frame_view->GetIntersectionObservationStateForTesting()); root->scrollTo(0, 50); - EXPECT_EQ(gfx::Vector2dF(50, 100), - frame_view->MinScrollDeltaToUpdateIntersectionForTesting()); - EXPECT_EQ(LocalFrameView::kFrameViewportIntersectionOnly, - frame_view->GetIntersectionObservationStateForTesting()); - Compositor().BeginFrame(); - test::RunPendingTasks(); - EXPECT_EQ(observer_delegate->CallCount(), 1); - EXPECT_EQ(observer_delegate->EntryCount(), 1); - EXPECT_FALSE(observer_delegate->LastEntry()->isIntersecting()); - - root->scrollTo(0, 100); - EXPECT_EQ(gfx::Vector2dF(50, 100), - frame_view->MinScrollDeltaToUpdateIntersectionForTesting()); + EXPECT_EQ(gfx::Vector2dF(50, 100), observation->MinScrollDeltaToUpdate()); EXPECT_EQ(LocalFrameView::kDesired, frame_view->GetIntersectionObservationStateForTesting()); Compositor().BeginFrame(); @@ -1777,14 +1743,23 @@ EXPECT_EQ(observer_delegate->CallCount(), 1); EXPECT_EQ(observer_delegate->EntryCount(), 1); EXPECT_FALSE(observer_delegate->LastEntry()->isIntersecting()); - EXPECT_EQ(gfx::Vector2dF(), - frame_view->MinScrollDeltaToUpdateIntersectionForTesting()); + EXPECT_EQ(gfx::Vector2dF(50, 50), observation->MinScrollDeltaToUpdate()); + + root->scrollTo(0, 100); + EXPECT_EQ(gfx::Vector2dF(50, 50), observation->MinScrollDeltaToUpdate()); + EXPECT_EQ(LocalFrameView::kDesired, + frame_view->GetIntersectionObservationStateForTesting()); + Compositor().BeginFrame(); + test::RunPendingTasks(); + EXPECT_EQ(observer_delegate->CallCount(), 1); + EXPECT_EQ(observer_delegate->EntryCount(), 1); + EXPECT_FALSE(observer_delegate->LastEntry()->isIntersecting()); + EXPECT_EQ(gfx::Vector2dF(), observation->MinScrollDeltaToUpdate()); EXPECT_EQ(LocalFrameView::kNotNeeded, frame_view->GetIntersectionObservationStateForTesting()); root->scrollTo(0, 101); - EXPECT_EQ(gfx::Vector2dF(), - frame_view->MinScrollDeltaToUpdateIntersectionForTesting()); + EXPECT_EQ(gfx::Vector2dF(), observation->MinScrollDeltaToUpdate()); EXPECT_EQ(LocalFrameView::kDesired, frame_view->GetIntersectionObservationStateForTesting()); Compositor().BeginFrame(); @@ -1792,14 +1767,12 @@ EXPECT_EQ(observer_delegate->CallCount(), 1); EXPECT_EQ(observer_delegate->EntryCount(), 1); EXPECT_FALSE(observer_delegate->LastEntry()->isIntersecting()); - EXPECT_EQ(gfx::Vector2dF(), - frame_view->MinScrollDeltaToUpdateIntersectionForTesting()); + EXPECT_EQ(gfx::Vector2dF(), observation->MinScrollDeltaToUpdate()); EXPECT_EQ(LocalFrameView::kNotNeeded, frame_view->GetIntersectionObservationStateForTesting()); root->scrollTo(0, 151); - EXPECT_EQ(gfx::Vector2dF(), - frame_view->MinScrollDeltaToUpdateIntersectionForTesting()); + EXPECT_EQ(gfx::Vector2dF(), observation->MinScrollDeltaToUpdate()); EXPECT_EQ(LocalFrameView::kDesired, frame_view->GetIntersectionObservationStateForTesting()); Compositor().BeginFrame(); @@ -1807,8 +1780,7 @@ EXPECT_EQ(observer_delegate->CallCount(), 2); EXPECT_EQ(observer_delegate->EntryCount(), 2); EXPECT_TRUE(observer_delegate->LastEntry()->isIntersecting()); - EXPECT_EQ(gfx::Vector2dF(), - frame_view->MinScrollDeltaToUpdateIntersectionForTesting()); + EXPECT_EQ(gfx::Vector2dF(), observation->MinScrollDeltaToUpdate()); EXPECT_EQ(LocalFrameView::kNotNeeded, frame_view->GetIntersectionObservationStateForTesting()); } @@ -1845,8 +1817,9 @@ ASSERT_FALSE(exception_state.HadException()); observer->observe(target, exception_state); ASSERT_FALSE(exception_state.HadException()); - EXPECT_EQ(gfx::Vector2dF(), - frame_view->MinScrollDeltaToUpdateIntersectionForTesting()); + const IntersectionObservation* observation = + target->IntersectionObserverData()->GetObservationFor(*observer); + EXPECT_EQ(gfx::Vector2dF(), observation->MinScrollDeltaToUpdate()); EXPECT_EQ(LocalFrameView::kRequired, frame_view->GetIntersectionObservationStateForTesting()); @@ -1855,25 +1828,23 @@ EXPECT_EQ(observer_delegate->CallCount(), 1); EXPECT_EQ(observer_delegate->EntryCount(), 1); EXPECT_FALSE(observer_delegate->LastEntry()->isIntersecting()); - EXPECT_EQ(gfx::Vector2dF(20, 200), - frame_view->MinScrollDeltaToUpdateIntersectionForTesting()); + EXPECT_EQ(gfx::Vector2dF(20, 200), observation->MinScrollDeltaToUpdate()); EXPECT_EQ(LocalFrameView::kNotNeeded, frame_view->GetIntersectionObservationStateForTesting()); root->scrollTo(0, 100); - EXPECT_EQ(gfx::Vector2dF(20, 200), - frame_view->MinScrollDeltaToUpdateIntersectionForTesting()); - EXPECT_EQ(LocalFrameView::kFrameViewportIntersectionOnly, + EXPECT_EQ(gfx::Vector2dF(20, 200), observation->MinScrollDeltaToUpdate()); + EXPECT_EQ(LocalFrameView::kDesired, frame_view->GetIntersectionObservationStateForTesting()); Compositor().BeginFrame(); test::RunPendingTasks(); EXPECT_EQ(observer_delegate->CallCount(), 1); EXPECT_EQ(observer_delegate->EntryCount(), 1); EXPECT_FALSE(observer_delegate->LastEntry()->isIntersecting()); + EXPECT_EQ(gfx::Vector2dF(20, 100), observation->MinScrollDeltaToUpdate()); root->scrollTo(0, 200); - EXPECT_EQ(gfx::Vector2dF(20, 200), - frame_view->MinScrollDeltaToUpdateIntersectionForTesting()); + EXPECT_EQ(gfx::Vector2dF(20, 100), observation->MinScrollDeltaToUpdate()); EXPECT_EQ(LocalFrameView::kDesired, frame_view->GetIntersectionObservationStateForTesting()); Compositor().BeginFrame(); @@ -1881,14 +1852,12 @@ EXPECT_EQ(observer_delegate->CallCount(), 2); EXPECT_EQ(observer_delegate->EntryCount(), 2); EXPECT_TRUE(observer_delegate->LastEntry()->isIntersecting()); - EXPECT_EQ(gfx::Vector2dF(20, 0), - frame_view->MinScrollDeltaToUpdateIntersectionForTesting()); + EXPECT_EQ(gfx::Vector2dF(20, 0), observation->MinScrollDeltaToUpdate()); EXPECT_EQ(LocalFrameView::kNotNeeded, frame_view->GetIntersectionObservationStateForTesting()); root->scrollTo(20, 200); - EXPECT_EQ(gfx::Vector2dF(20, 0), - frame_view->MinScrollDeltaToUpdateIntersectionForTesting()); + EXPECT_EQ(gfx::Vector2dF(20, 0), observation->MinScrollDeltaToUpdate()); EXPECT_EQ(LocalFrameView::kDesired, frame_view->GetIntersectionObservationStateForTesting()); Compositor().BeginFrame(); @@ -1896,19 +1865,18 @@ EXPECT_EQ(observer_delegate->CallCount(), 2); EXPECT_EQ(observer_delegate->EntryCount(), 2); EXPECT_TRUE(observer_delegate->LastEntry()->isIntersecting()); - EXPECT_EQ(gfx::Vector2dF(10, 0), - frame_view->MinScrollDeltaToUpdateIntersectionForTesting()); + EXPECT_EQ(gfx::Vector2dF(10, 0), observation->MinScrollDeltaToUpdate()); EXPECT_EQ(LocalFrameView::kNotNeeded, frame_view->GetIntersectionObservationStateForTesting()); root->scrollTo(31, 201); + EXPECT_EQ(gfx::Vector2dF(10, 0), observation->MinScrollDeltaToUpdate()); Compositor().BeginFrame(); test::RunPendingTasks(); EXPECT_EQ(observer_delegate->CallCount(), 3); EXPECT_EQ(observer_delegate->EntryCount(), 3); EXPECT_FALSE(observer_delegate->LastEntry()->isIntersecting()); - EXPECT_EQ(gfx::Vector2dF(1, 1), - frame_view->MinScrollDeltaToUpdateIntersectionForTesting()); + EXPECT_EQ(gfx::Vector2dF(1, 1), observation->MinScrollDeltaToUpdate()); EXPECT_EQ(LocalFrameView::kNotNeeded, frame_view->GetIntersectionObservationStateForTesting()); } @@ -1952,8 +1920,9 @@ DummyExceptionStateForTesting exception_state; observer->observe(target, exception_state); ASSERT_FALSE(exception_state.HadException()); - EXPECT_EQ(gfx::Vector2dF(), - frame_view->MinScrollDeltaToUpdateIntersectionForTesting()); + const IntersectionObservation* observation = + target->IntersectionObserverData()->GetObservationFor(*observer); + EXPECT_EQ(gfx::Vector2dF(), observation->MinScrollDeltaToUpdate()); EXPECT_EQ(LocalFrameView::kRequired, frame_view->GetIntersectionObservationStateForTesting()); @@ -1962,25 +1931,23 @@ EXPECT_EQ(observer_delegate->CallCount(), 1); EXPECT_EQ(observer_delegate->EntryCount(), 1); EXPECT_FALSE(observer_delegate->LastEntry()->isIntersecting()); - EXPECT_EQ(gfx::Vector2dF(30, 200), - frame_view->MinScrollDeltaToUpdateIntersectionForTesting()); + EXPECT_EQ(gfx::Vector2dF(30, 200), observation->MinScrollDeltaToUpdate()); EXPECT_EQ(LocalFrameView::kNotNeeded, frame_view->GetIntersectionObservationStateForTesting()); root->scrollTo(0, 100); - EXPECT_EQ(gfx::Vector2dF(30, 200), - frame_view->MinScrollDeltaToUpdateIntersectionForTesting()); - EXPECT_EQ(LocalFrameView::kFrameViewportIntersectionOnly, + EXPECT_EQ(gfx::Vector2dF(30, 200), observation->MinScrollDeltaToUpdate()); + EXPECT_EQ(LocalFrameView::kDesired, frame_view->GetIntersectionObservationStateForTesting()); Compositor().BeginFrame(); test::RunPendingTasks(); EXPECT_EQ(observer_delegate->CallCount(), 1); EXPECT_EQ(observer_delegate->EntryCount(), 1); EXPECT_FALSE(observer_delegate->LastEntry()->isIntersecting()); + EXPECT_EQ(gfx::Vector2dF(30, 100), observation->MinScrollDeltaToUpdate()); root->scrollTo(30, 200); - EXPECT_EQ(gfx::Vector2dF(30, 200), - frame_view->MinScrollDeltaToUpdateIntersectionForTesting()); + EXPECT_EQ(gfx::Vector2dF(30, 100), observation->MinScrollDeltaToUpdate()); EXPECT_EQ(LocalFrameView::kDesired, frame_view->GetIntersectionObservationStateForTesting()); Compositor().BeginFrame(); @@ -1988,19 +1955,19 @@ EXPECT_EQ(observer_delegate->CallCount(), 2); EXPECT_EQ(observer_delegate->EntryCount(), 2); EXPECT_TRUE(observer_delegate->LastEntry()->isIntersecting()); - EXPECT_EQ(gfx::Vector2dF(), - frame_view->MinScrollDeltaToUpdateIntersectionForTesting()); + EXPECT_EQ(gfx::Vector2dF(), observation->MinScrollDeltaToUpdate()); + EXPECT_EQ(gfx::Vector2dF(0, 0), observation->MinScrollDeltaToUpdate()); EXPECT_EQ(LocalFrameView::kNotNeeded, frame_view->GetIntersectionObservationStateForTesting()); root->scrollTo(31, 201); + EXPECT_EQ(gfx::Vector2dF(0, 0), observation->MinScrollDeltaToUpdate()); Compositor().BeginFrame(); test::RunPendingTasks(); EXPECT_EQ(observer_delegate->CallCount(), 3); EXPECT_EQ(observer_delegate->EntryCount(), 3); EXPECT_FALSE(observer_delegate->LastEntry()->isIntersecting()); - EXPECT_EQ(gfx::Vector2dF(1, 1), - frame_view->MinScrollDeltaToUpdateIntersectionForTesting()); + EXPECT_EQ(gfx::Vector2dF(1, 1), observation->MinScrollDeltaToUpdate()); EXPECT_EQ(LocalFrameView::kNotNeeded, frame_view->GetIntersectionObservationStateForTesting()); } @@ -2036,15 +2003,15 @@ ASSERT_FALSE(exception_state.HadException()); observer->observe(target, exception_state); ASSERT_FALSE(exception_state.HadException()); - EXPECT_EQ(gfx::Vector2dF(), - frame_view->MinScrollDeltaToUpdateIntersectionForTesting()); + const IntersectionObservation* observation = + target->IntersectionObserverData()->GetObservationFor(*observer); + EXPECT_EQ(gfx::Vector2dF(), observation->MinScrollDeltaToUpdate()); EXPECT_EQ(LocalFrameView::kRequired, frame_view->GetIntersectionObservationStateForTesting()); Compositor().BeginFrame(); test::RunPendingTasks(); - EXPECT_EQ(gfx::Vector2dF(100, 100), - frame_view->MinScrollDeltaToUpdateIntersectionForTesting()); + EXPECT_EQ(gfx::Vector2dF(100, 100), observation->MinScrollDeltaToUpdate()); EXPECT_EQ(LocalFrameView::kNotNeeded, frame_view->GetIntersectionObservationStateForTesting()); } @@ -2081,15 +2048,15 @@ ASSERT_FALSE(exception_state.HadException()); observer->observe(target, exception_state); ASSERT_FALSE(exception_state.HadException()); - EXPECT_EQ(gfx::Vector2dF(), - frame_view->MinScrollDeltaToUpdateIntersectionForTesting()); + const IntersectionObservation* observation = + target->IntersectionObserverData()->GetObservationFor(*observer); + EXPECT_EQ(gfx::Vector2dF(), observation->MinScrollDeltaToUpdate()); EXPECT_EQ(LocalFrameView::kRequired, frame_view->GetIntersectionObservationStateForTesting()); Compositor().BeginFrame(); test::RunPendingTasks(); - EXPECT_EQ(gfx::Vector2dF(), - frame_view->MinScrollDeltaToUpdateIntersectionForTesting()); + EXPECT_EQ(gfx::Vector2dF(), observation->MinScrollDeltaToUpdate()); EXPECT_EQ(LocalFrameView::kNotNeeded, frame_view->GetIntersectionObservationStateForTesting()); } @@ -2127,15 +2094,15 @@ ASSERT_FALSE(exception_state.HadException()); observer->observe(target, exception_state); ASSERT_FALSE(exception_state.HadException()); - EXPECT_EQ(gfx::Vector2dF(), - frame_view->MinScrollDeltaToUpdateIntersectionForTesting()); + const IntersectionObservation* observation = + target->IntersectionObserverData()->GetObservationFor(*observer); + EXPECT_EQ(gfx::Vector2dF(), observation->MinScrollDeltaToUpdate()); EXPECT_EQ(LocalFrameView::kRequired, frame_view->GetIntersectionObservationStateForTesting()); Compositor().BeginFrame(); test::RunPendingTasks(); - EXPECT_EQ(gfx::Vector2dF(), - frame_view->MinScrollDeltaToUpdateIntersectionForTesting()); + EXPECT_EQ(gfx::Vector2dF(), observation->MinScrollDeltaToUpdate()); EXPECT_EQ(LocalFrameView::kNotNeeded, frame_view->GetIntersectionObservationStateForTesting()); } @@ -2175,15 +2142,15 @@ ASSERT_FALSE(exception_state.HadException()); observer->observe(target, exception_state); ASSERT_FALSE(exception_state.HadException()); - EXPECT_EQ(gfx::Vector2dF(), - frame_view->MinScrollDeltaToUpdateIntersectionForTesting()); + const IntersectionObservation* observation = + target->IntersectionObserverData()->GetObservationFor(*observer); + EXPECT_EQ(gfx::Vector2dF(), observation->MinScrollDeltaToUpdate()); EXPECT_EQ(LocalFrameView::kRequired, frame_view->GetIntersectionObservationStateForTesting()); Compositor().BeginFrame(); test::RunPendingTasks(); - EXPECT_EQ(gfx::Vector2dF(), - frame_view->MinScrollDeltaToUpdateIntersectionForTesting()); + EXPECT_EQ(gfx::Vector2dF(), observation->MinScrollDeltaToUpdate()); EXPECT_EQ(LocalFrameView::kNotNeeded, frame_view->GetIntersectionObservationStateForTesting()); }
diff --git a/third_party/blink/renderer/core/layout/layout_object.cc b/third_party/blink/renderer/core/layout/layout_object.cc index 628e9de..3ec72aa 100644 --- a/third_party/blink/renderer/core/layout/layout_object.cc +++ b/third_party/blink/renderer/core/layout/layout_object.cc
@@ -1624,8 +1624,8 @@ void LayoutObject::InvalidateIntersectionObserverCachedRects() { NOT_DESTROYED(); - if (GetNode() && GetNode()->IsElementNode()) { - if (auto* data = To<Element>(GetNode())->IntersectionObserverData()) { + if (const auto* element = DynamicTo<Element>(GetNode())) { + if (auto* data = element->IntersectionObserverData()) { data->InvalidateCachedRects(); } } @@ -4579,6 +4579,7 @@ DCHECK(IsLayoutFullPaintInvalidationReason(reason)); SetShouldCheckForPaintInvalidation(); SetShouldDoFullPaintInvalidationWithoutLayoutChangeInternal(reason); + InvalidateIntersectionObserverCachedRects(); } void LayoutObject::SetShouldDoFullPaintInvalidationWithoutLayoutChange(
diff --git a/third_party/blink/renderer/modules/media_controls/media_controls_rotate_to_fullscreen_delegate.cc b/third_party/blink/renderer/modules/media_controls/media_controls_rotate_to_fullscreen_delegate.cc index 25e9f1f2..a1e882e 100644 --- a/third_party/blink/renderer/modules/media_controls/media_controls_rotate_to_fullscreen_delegate.cc +++ b/third_party/blink/renderer/modules/media_controls/media_controls_rotate_to_fullscreen_delegate.cc
@@ -128,10 +128,15 @@ if (needs_intersection_observer && !intersection_observer_) { intersection_observer_ = IntersectionObserver::Create( - {}, {kIntersectionThreshold}, &video_element_->GetDocument(), + /* (root) margin */ Vector<Length>(), + /* scroll_margin */ Vector<Length>(), + /* thresholds */ {kIntersectionThreshold}, + /* document */ &video_element_->GetDocument(), + /* callback */ WTF::BindRepeating( &MediaControlsRotateToFullscreenDelegate::OnIntersectionChange, WrapWeakPersistent(this)), + /* ukm_metric_id */ LocalFrameUkmAggregator::kMediaIntersectionObserver); intersection_observer_->observe(video_element_); } else if (!needs_intersection_observer && intersection_observer_) {
diff --git a/third_party/blink/renderer/modules/ml/webnn/features.gni b/third_party/blink/renderer/modules/ml/webnn/features.gni index 03c1835..625c3b7e 100644 --- a/third_party/blink/renderer/modules/ml/webnn/features.gni +++ b/third_party/blink/renderer/modules/ml/webnn/features.gni
@@ -6,9 +6,9 @@ declare_args() { # This enables building WebNN with XNNPACK. Currently only available for # Windows, macOS and Linux on x64, x86 and arm64. - build_webnn_with_xnnpack = - (is_linux || is_win || is_mac) && - (current_cpu == "x64" || current_cpu == "x86" || current_cpu == "arm64") + build_webnn_with_xnnpack = (is_linux || is_win || is_mac) && + (current_cpu == "x64" || current_cpu == "x86" || + (current_cpu == "arm64" && !is_win)) # This build flag enables WebNN on ChromeOS platform to access hardware # acceleration by using ModelLoader mojo interface.
diff --git a/third_party/blink/web_tests/ChromeTestExpectations b/third_party/blink/web_tests/ChromeTestExpectations index 67ee384c..eab008d 100644 --- a/third_party/blink/web_tests/ChromeTestExpectations +++ b/third_party/blink/web_tests/ChromeTestExpectations
@@ -30,8 +30,12 @@ external/wpt/webdriver/tests/bidi/network/add_intercept/url_patterns.py [ Timeout ] # Chrome specific failures -crbug.com/1499775 external/wpt/soft-navigation-heuristics/keyup.tentative.html [ Timeout ] +crbug.com/1499775 external/wpt/css/css-text/text-transform/text-transform-capitalize-014.html [ Failure Pass ] +crbug.com/1499775 external/wpt/html/semantics/forms/the-selectlist-element/selectlist-option-arbitrary-content-not-displayed.tentative.html [ Failure Pass ] +crbug.com/1499775 external/wpt/html/semantics/embedded-content/the-img-element/image-loading-lazy-base-url-2.html [ Failure ] +crbug.com/1499775 external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-button-border-left-color-001.html [ Failure ] crbug.com/1499775 external/wpt/editing/other/join-pre-and-other-block.html?method=forwarddelete&block=blockquote [ Timeout ] +crbug.com/1499775 external/wpt/editing/other/join-pre-and-other-block.html?method=forwarddelete&block=p [ Pass Timeout ] crbug.com/1499775 external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-input-search-text-border-inline-start-color-001.html [ Failure ] crbug.com/1499775 external/wpt/document-policy/font-display/override-to-optional.tentative.html [ Failure ] crbug.com/1499775 external/wpt/css/css-layout-api/fallback-layout/constructor-error.https.html [ Failure ] @@ -46,11 +50,14 @@ crbug.com/1499775 external/wpt/css/css-inline/initial-letter/initial-letter-float-001.html [ Failure ] crbug.com/1499775 external/wpt/css/css-inline/initial-letter/initial-letter-float-002.html [ Failure ] crbug.com/1499775 external/wpt/css/css-inline/initial-letter/initial-letter-float-004.html [ Failure ] +crbug.com/1499775 external/wpt/css/css-images/object-view-box-fit-fill-img.html [ Failure ] crbug.com/1499775 external/wpt/css/css-inline/initial-letter/initial-letter-with-tab.html [ Failure ] crbug.com/1499775 external/wpt/css/css-layout-api/fallback-intrinsic-sizes/constructor-error.https.html [ Failure ] crbug.com/1499775 external/wpt/css/css-masking/clip-path/clip-path-inline-003.html [ Failure ] crbug.com/1499775 external/wpt/css/css-overflow/scrollable-overflow-input-001.html [ Failure ] crbug.com/1499775 external/wpt/css/css-overflow/scrollable-overflow-input-002.html [ Failure ] +crbug.com/1499775 external/wpt/css/css-paint-api/geometry-background-image-tiled-002.https.html [ Failure Pass ] +crbug.com/1499775 external/wpt/css/css-paint-api/paint-function-this-value.https.html [ Failure Pass ] crbug.com/1499775 external/wpt/css/css-pseudo/highlight-currentcolor-painting-properties-001.html [ Failure ] crbug.com/1499775 external/wpt/css/css-pseudo/highlight-currentcolor-painting-properties-002.html [ Failure ] crbug.com/1499775 external/wpt/css/css-pseudo/highlight-painting-003.html [ Failure ] @@ -62,8 +69,6 @@ crbug.com/1499775 external/wpt/svg/linking/reftests/view-viewbox-override.html [ Failure ] crbug.com/1499775 wpt_internal/css/css-pseudo/spelling-error-color-001.html [ Failure ] crbug.com/1499775 external/wpt/accessibility/crashtests/svg-mouse-listener.html [ Timeout ] -crbug.com/1499775 external/wpt/attribution-reporting/request-format.sub.https.html?method=fetch&eligible={"eventSourceEligible":true,"triggerEligible":false}&expected-eligible=event-source [ Failure ] # Flaky output -crbug.com/1499775 external/wpt/attribution-reporting/request-format.sub.https.html?method=xhr&eligible={"eventSourceEligible":true,"triggerEligible":false}&expected-eligible=event-source [ Failure ] # Flaky output crbug.com/1499775 external/wpt/background-fetch/abort.https.window.html [ Timeout ] crbug.com/1499775 external/wpt/background-fetch/fetch-uploads.https.window.html [ Timeout ] crbug.com/1499775 external/wpt/background-fetch/fetch.https.window.html [ Timeout ] @@ -370,8 +375,6 @@ crbug.com/1499775 external/wpt/signed-exchange/reporting/sxg-reporting-prefetch-signature_verification_error-downgraded.tentative.html [ Timeout ] crbug.com/1499775 external/wpt/signed-exchange/reporting/sxg-reporting-prefetch-signature_verification_error.tentative.html [ Timeout ] crbug.com/1499775 external/wpt/signed-exchange/subresource/sxg-subresource-header-integrity-mismatch.tentative.html [ Timeout ] # fail on wpt.fyi -crbug.com/1499775 external/wpt/soft-navigation-heuristics/keydown.tentative.html [ Timeout ] -crbug.com/1499775 external/wpt/soft-navigation-heuristics/keypress.tentative.html [ Timeout ] crbug.com/1499775 external/wpt/speculation-rules/prerender/response-code-successful.html?code=202 [ Failure ] # Flaky output crbug.com/1499775 external/wpt/storage-access-api/storage-access-permission.sub.https.window.html [ Timeout ] crbug.com/1499775 external/wpt/svg/text/reftests/lang-attribute.svg [ Failure ] # Reftest image failure @@ -433,6 +436,7 @@ crbug.com/1499775 external/wpt/css/css-scroll-anchoring/fullscreen-crash.html [ Timeout ] crbug.com/1499775 external/wpt/css/css-shadow-parts/interaction-with-nested-pseudo-class.html [ Timeout ] crbug.com/1499775 external/wpt/css/css-text-decor/invalidation/text-decoration-thickness.html [ Timeout ] +crbug.com/1499775 external/wpt/custom-elements/reactions/customized-builtins/HTMLMediaElement.html [ Pass Timeout ] crbug.com/1499775 external/wpt/fullscreen/api/document-exit-fullscreen-nested-shadow-dom.html [ Timeout ] crbug.com/1499775 external/wpt/fullscreen/api/document-exit-fullscreen-nested.html [ Timeout ] crbug.com/1499775 external/wpt/fullscreen/api/document-exit-fullscreen-timing.html [ Timeout ]
diff --git a/third_party/blink/web_tests/NeverFixTests b/third_party/blink/web_tests/NeverFixTests index bc004e0..e7faace3 100644 --- a/third_party/blink/web_tests/NeverFixTests +++ b/third_party/blink/web_tests/NeverFixTests
@@ -2081,6 +2081,7 @@ [ Chrome ] wpt_internal/import-maps/* [ Skip ] # many failures in the folders below, skip for now crbug.com/1499775 [ Chrome ] external/wpt/html/cross-origin-opener-policy/* [ Skip ] +crbug.com/1499775 [ Chrome ] external/wpt/attribution-reporting/* [ Skip ] [ Chrome ] external/wpt/speculation-rules/prerender/* [ Skip ] [ Chrome ] external/wpt/speculation-rules/prerender/credentialed-prerender-not-opt-in.html [ Pass ] [ Chrome ] external/wpt/speculation-rules/prerender/csp-script-src-self.html [ Pass ]
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index c7bb128..4079c4d 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -3837,18 +3837,6 @@ # Image decode failures due to document destruction. crbug.com/721435 external/wpt/html/semantics/embedded-content/the-img-element/decode/image-decode-iframe.html [ Crash Failure Pass Timeout ] -# Test times out for some reason on Chromium browsers -crbug.com/1357623 external/wpt/html/semantics/embedded-content/the-img-element/image-loading-lazy-zero-intersection-area.html [ Timeout ] - -# Implement lazy loading scroll margin -crbug.com/1391989 external/wpt/html/semantics/embedded-content/the-img-element/image-loading-lazy-in-scroller-horizontal.html [ Failure ] -crbug.com/1391989 external/wpt/html/semantics/embedded-content/the-img-element/image-loading-lazy-in-scroller-nested-2.html [ Failure ] -crbug.com/1391989 external/wpt/html/semantics/embedded-content/the-img-element/image-loading-lazy-in-scroller-nested-3.html [ Failure ] -crbug.com/1391989 external/wpt/html/semantics/embedded-content/the-img-element/image-loading-lazy-in-scroller-nested-4.html [ Failure ] -crbug.com/1391989 external/wpt/html/semantics/embedded-content/the-img-element/image-loading-lazy-in-scroller-nested-5.html [ Failure ] -crbug.com/1391989 external/wpt/html/semantics/embedded-content/the-img-element/image-loading-lazy-in-scroller-nested.html [ Failure ] -crbug.com/1391989 external/wpt/html/semantics/embedded-content/the-img-element/image-loading-lazy-in-scroller.html [ Failure ] - # Sheriff failures 2017-05-23 crbug.com/725470 editing/shadow/doubleclick-on-meter-in-shadow-crash.html [ Crash Failure Pass ]
diff --git a/third_party/blink/web_tests/platform/linux-chrome/external/wpt/FileAPI/url/url-lifetime-expected.txt b/third_party/blink/web_tests/platform/linux-chrome/external/wpt/FileAPI/url/url-lifetime-expected.txt new file mode 100644 index 0000000..aeb5606 --- /dev/null +++ b/third_party/blink/web_tests/platform/linux-chrome/external/wpt/FileAPI/url/url-lifetime-expected.txt
@@ -0,0 +1,5 @@ +This is a testharness.js-based test. +[FAIL PASS] Terminating worker revokes its URLs + promise_test: Unhandled rejection with value: object "TypeError: Failed to fetch" +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/platform/linux-chrome/external/wpt/cookie-store/cookieStore_subscribe_arguments.https.any-expected.txt b/third_party/blink/web_tests/platform/linux-chrome/external/wpt/cookie-store/cookieStore_subscribe_arguments.https.any-expected.txt new file mode 100644 index 0000000..32e27bd --- /dev/null +++ b/third_party/blink/web_tests/platform/linux-chrome/external/wpt/cookie-store/cookieStore_subscribe_arguments.https.any-expected.txt
@@ -0,0 +1,8 @@ +This is a testharness.js-based test. +Harness Error. harness_status.status = 1 , harness_status.message = Test named 'cookieStore.subscribe without url in option' specified 2 'cleanup' functions, and 1 failed. +[PASS] cookieStore.subscribe without url in option +[PASS NOTRUN] cookieStore.subscribe with invalid url path in option +[PASS NOTRUN] cookieStore.subscribe is idempotent +[PASS NOTRUN] CookieStore.unsubscribe is idempotent +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/platform/linux-chrome/wpt_internal/soft-navigation-heuristics/keydown-expected.txt b/third_party/blink/web_tests/platform/linux-chrome/wpt_internal/soft-navigation-heuristics/keydown-expected.txt new file mode 100644 index 0000000..00c54c5 --- /dev/null +++ b/third_party/blink/web_tests/platform/linux-chrome/wpt_internal/soft-navigation-heuristics/keydown-expected.txt
@@ -0,0 +1,5 @@ +This is a testharness.js-based test. +[FAIL] Detect keyboard-event based soft navigations. + promise_test: Unhandled rejection with value: object "TypeError: Cannot read properties of undefined (reading 'keyDownAsync')" +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/platform/linux-chrome/wpt_internal/soft-navigation-heuristics/keypress-expected.txt b/third_party/blink/web_tests/platform/linux-chrome/wpt_internal/soft-navigation-heuristics/keypress-expected.txt new file mode 100644 index 0000000..00c54c5 --- /dev/null +++ b/third_party/blink/web_tests/platform/linux-chrome/wpt_internal/soft-navigation-heuristics/keypress-expected.txt
@@ -0,0 +1,5 @@ +This is a testharness.js-based test. +[FAIL] Detect keyboard-event based soft navigations. + promise_test: Unhandled rejection with value: object "TypeError: Cannot read properties of undefined (reading 'keyDownAsync')" +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/platform/linux-chrome/wpt_internal/soft-navigation-heuristics/keyup-expected.txt b/third_party/blink/web_tests/platform/linux-chrome/wpt_internal/soft-navigation-heuristics/keyup-expected.txt new file mode 100644 index 0000000..00c54c5 --- /dev/null +++ b/third_party/blink/web_tests/platform/linux-chrome/wpt_internal/soft-navigation-heuristics/keyup-expected.txt
@@ -0,0 +1,5 @@ +This is a testharness.js-based test. +[FAIL] Detect keyboard-event based soft navigations. + promise_test: Unhandled rejection with value: object "TypeError: Cannot read properties of undefined (reading 'keyDownAsync')" +Harness: the test ran to completion. +
diff --git a/third_party/catapult b/third_party/catapult index e04aba7..bd17576 160000 --- a/third_party/catapult +++ b/third_party/catapult
@@ -1 +1 @@ -Subproject commit e04aba79979be87883ec296d65d2b77f88a55821 +Subproject commit bd17576ac2d58104cb43d375ff282fde394ecb44
diff --git a/third_party/dawn b/third_party/dawn index ead8a04..bfb695d 160000 --- a/third_party/dawn +++ b/third_party/dawn
@@ -1 +1 @@ -Subproject commit ead8a043e377273b24e6c788007e6a7d15cf1093 +Subproject commit bfb695dd9b62203f1b8fdaf7998e5681c38bd3b9
diff --git a/third_party/devtools-frontend-internal b/third_party/devtools-frontend-internal index b233f93..1c042a68 160000 --- a/third_party/devtools-frontend-internal +++ b/third_party/devtools-frontend-internal
@@ -1 +1 @@ -Subproject commit b233f938697334c3b9cc718869672d2971668800 +Subproject commit 1c042a68ac0552324f7105843936b0f0218099f2
diff --git a/third_party/devtools-frontend/src b/third_party/devtools-frontend/src index 654a23c..4512381 160000 --- a/third_party/devtools-frontend/src +++ b/third_party/devtools-frontend/src
@@ -1 +1 @@ -Subproject commit 654a23c7ade29e732bfa4f0d10eacea5a81098d2 +Subproject commit 45123813f5cb7335dc4a7e5151931dbe451b742c
diff --git a/third_party/libc++/src b/third_party/libc++/src index 038521e..a96e763 160000 --- a/third_party/libc++/src +++ b/third_party/libc++/src
@@ -1 +1 @@ -Subproject commit 038521e9561dab50fc8b50ef987e87225f39c8f6 +Subproject commit a96e76348a51cb38e2120a7333c49884e5737768
diff --git a/third_party/libc++abi/src b/third_party/libc++abi/src index 79413b1..37159389 160000 --- a/third_party/libc++abi/src +++ b/third_party/libc++abi/src
@@ -1 +1 @@ -Subproject commit 79413b1359092d6feb34874e9a819466518b7262 +Subproject commit 371593893aeee51ecfb785093115fd846c3b73ca
diff --git a/third_party/libunwind/src b/third_party/libunwind/src index 668c76f..85df028 160000 --- a/third_party/libunwind/src +++ b/third_party/libunwind/src
@@ -1 +1 @@ -Subproject commit 668c76fe4d440ee5e36971c9ca39f1b616af8078 +Subproject commit 85df028e4c5e8a3eaa38fe75e0d78157bee2d668
diff --git a/third_party/libvpx/README.chromium b/third_party/libvpx/README.chromium index 88de5e8..789b718 100644 --- a/third_party/libvpx/README.chromium +++ b/third_party/libvpx/README.chromium
@@ -1,7 +1,7 @@ Name: libvpx URL: https://chromium.googlesource.com/webm/libvpx Version: N/A -Revision: 0d3ef6ffd22bda0ba1ec1bf9c7a24852e4a1d111 +Revision: 9142314c2cec2be364e6844d1630a056e7b0a3c8 CPEPrefix: cpe:/a:webmproject:libvpx:1.13.1 License: BSD License File: source/libvpx/LICENSE
diff --git a/third_party/libvpx/source/config/vpx_version.h b/third_party/libvpx/source/config/vpx_version.h index 3a0fa4d0..f33dbee6 100644 --- a/third_party/libvpx/source/config/vpx_version.h +++ b/third_party/libvpx/source/config/vpx_version.h
@@ -2,8 +2,8 @@ #define VERSION_MAJOR 1 #define VERSION_MINOR 13 #define VERSION_PATCH 1 -#define VERSION_EXTRA "510-g0d3ef6ffd" +#define VERSION_EXTRA "530-g9142314c2" #define VERSION_PACKED \ ((VERSION_MAJOR << 16) | (VERSION_MINOR << 8) | (VERSION_PATCH)) -#define VERSION_STRING_NOSP "v1.13.1-510-g0d3ef6ffd" -#define VERSION_STRING " v1.13.1-510-g0d3ef6ffd" +#define VERSION_STRING_NOSP "v1.13.1-530-g9142314c2" +#define VERSION_STRING " v1.13.1-530-g9142314c2"
diff --git a/third_party/libvpx/source/libvpx b/third_party/libvpx/source/libvpx index 0d3ef6f..9142314 160000 --- a/third_party/libvpx/source/libvpx +++ b/third_party/libvpx/source/libvpx
@@ -1 +1 @@ -Subproject commit 0d3ef6ffd22bda0ba1ec1bf9c7a24852e4a1d111 +Subproject commit 9142314c2cec2be364e6844d1630a056e7b0a3c8
diff --git a/third_party/skia b/third_party/skia index f9e9bff..343b249 160000 --- a/third_party/skia +++ b/third_party/skia
@@ -1 +1 @@ -Subproject commit f9e9bff1714a2746d19107b2f6623aebcee16527 +Subproject commit 343b249b2cacaa694a07ca7430b1881274417da0
diff --git a/third_party/vulkan-deps b/third_party/vulkan-deps index ca74787..63bb05a 160000 --- a/third_party/vulkan-deps +++ b/third_party/vulkan-deps
@@ -1 +1 @@ -Subproject commit ca747870c6137423c2a1c8730171993065bfc608 +Subproject commit 63bb05a5e0adc21e2436613b6452a7b5cc61ae54
diff --git a/tools/metrics/histograms/metadata/extensions/histograms.xml b/tools/metrics/histograms/metadata/extensions/histograms.xml index 4e39e490..188b10a 100644 --- a/tools/metrics/histograms/metadata/extensions/histograms.xml +++ b/tools/metrics/histograms/metadata/extensions/histograms.xml
@@ -118,21 +118,6 @@ </summary> </histogram> -<histogram name="ExtensionContentVerifyJob.TimeSpentUS" units="microseconds" - expires_after="2020-11-30"> - <owner>lazyboy@chromium.org</owner> - <summary> - The time taken in computation (hashing actual bytes read and comparing - against expected computed hashes values) during an extension resource load. - - Warning: This metric may include reports from clients with low-resolution - clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports - will cause this metric to have an abnormal distribution. When considering - revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the - solution. - </summary> -</histogram> - <histogram name="Extensions.ActiveScriptController.DeniedExtensions" units="Extension Count" expires_after="2024-03-31"> <owner>rdevlin.cronin@chromium.org</owner> @@ -398,17 +383,6 @@ </summary> </histogram> -<histogram name="Extensions.ContentVerification.ReadContentHashTime" units="ms" - expires_after="2020-11-30"> - <owner>lazyboy@chromium.org</owner> - <owner>rdevlin.cronin@chromium.org</owner> - <summary> - Time spent by ContentVerifier for a request to create a ContentHash - instance. Recorded during an extension load completion or during an on - demand content verification that was triggered by ContentVerifyJob. - </summary> -</histogram> - <histogram name="Extensions.ContextMenuAction" enum="ExtensionContextMenuAction" expires_after="never"> <!-- expires-never: Monitoring extension usage. --> @@ -1551,15 +1525,6 @@ </summary> </histogram> -<histogram name="Extensions.ExternalJsonCount" units="units" - expires_after="M77"> - <owner>Please list the metric's owners. Add more owner tags as needed.</owner> - <summary> - Number of extensions referenced in the external extensions source at path - chrome::DIR_EXTERNAL_EXTENSIONS. - </summary> -</histogram> - <histogram name="Extensions.FaviconResourceRequested" enum="ExtensionType" expires_after="2021-01-31"> <owner>archanasimha@chromium.org</owner> @@ -3967,14 +3932,6 @@ </summary> </histogram> -<histogram name="Extensions.SandboxUnpackHashCheck" enum="BooleanValidHashSum" - expires_after="M85"> - <owner>achuith@chromium.org</owner> - <summary> - Whether a CRX file hash sum was the same as in an updater manifest. - </summary> -</histogram> - <histogram name="Extensions.SandboxUnpackSuccess" units="units" expires_after="never"> <!-- expires-never: Monitors core extension installation flows. -->
diff --git a/ui/display/test/display_manager_test_api.cc b/ui/display/test/display_manager_test_api.cc index 63e85ff..ec7387a 100644 --- a/ui/display/test/display_manager_test_api.cc +++ b/ui/display/test/display_manager_test_api.cc
@@ -15,7 +15,6 @@ #include "ui/display/manager/display_manager.h" #include "ui/display/manager/managed_display_info.h" #include "ui/display/manager/util/display_manager_test_util.h" -#include "ui/display/manager/util/display_manager_util.h" #include "ui/display/screen.h" #include "ui/display/util/display_util.h" @@ -26,9 +25,9 @@ // Indicates the default maximum of displays that chrome device can support. constexpr size_t kDefaultMaxSupportDisplayTest = 10; -DisplayInfoList CreateDisplayInfoListFromString( - const std::string specs, - DisplayManager* display_manager) { +DisplayInfoList CreateDisplayInfoListFromString(const std::string specs, + DisplayManager* display_manager, + bool generate_new_ids) { DisplayInfoList display_info_list; std::vector<std::string> parts = base::SplitString( specs, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); @@ -40,7 +39,9 @@ for (std::vector<std::string>::const_iterator iter = parts.begin(); iter != parts.end(); ++iter, ++index) { - int64_t id = (index < list.size()) ? list[index].id() : kInvalidDisplayId; + const int64_t id = (index < list.size() && !generate_new_ids) + ? list[index].id() + : kInvalidDisplayId; display_info_list.push_back( ManagedDisplayInfo::CreateFromSpecWithID(*iter, id)); } @@ -85,9 +86,10 @@ } void DisplayManagerTestApi::UpdateDisplay(const std::string& display_specs, - bool from_native_platform) { - DisplayInfoList display_info_list = - CreateDisplayInfoListFromString(display_specs, display_manager_); + bool from_native_platform, + bool generate_new_ids) { + DisplayInfoList display_info_list = CreateDisplayInfoListFromString( + display_specs, display_manager_, generate_new_ids); UpdateDisplayWithDisplayInfoList(display_info_list, from_native_platform); }
diff --git a/ui/display/test/display_manager_test_api.h b/ui/display/test/display_manager_test_api.h index eeeea6824..f6d402b 100644 --- a/ui/display/test/display_manager_test_api.h +++ b/ui/display/test/display_manager_test_api.h
@@ -15,6 +15,7 @@ #include "ui/display/display.h" #include "ui/display/display_export.h" #include "ui/display/display_layout.h" +#include "ui/display/manager/util/display_manager_util.h" #include "ui/display/types/display_constants.h" namespace gfx { @@ -48,9 +49,11 @@ // native information, such as display zoom, will be ignored and instead // copied from the current configuration. Note: To add rounded-corners // properly upon startup, set it via specifying the command line switch - // `ash-host-window-bounds`. + // `ash-host-window-bounds`. If `generate_new_ids` is true displays in + // `display_spec` will be created with new display ids. void UpdateDisplay(const std::string& display_specs, - bool from_native_platform = false); + bool from_native_platform = false, + bool generate_new_ids = false); void UpdateDisplayWithDisplayInfoList( const std::vector<ManagedDisplayInfo>& display_info_list,
diff --git a/ui/file_manager/file_manager/background/js/progress_center.js b/ui/file_manager/file_manager/background/js/progress_center.js index 1d97e2ce..7eebc015 100644 --- a/ui/file_manager/file_manager/background/js/progress_center.js +++ b/ui/file_manager/file_manager/background/js/progress_center.js
@@ -2,11 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import {AsyncQueue} from '../../common/js/async_util.js'; -import {notifications} from '../../common/js/notifications.js'; import {ProgressCenterItem, ProgressItemState, ProgressItemType} from '../../common/js/progress_center_common.js'; -import {str} from '../../common/js/translations.js'; -import {getFilesAppIconURL} from '../../common/js/url_constants.js'; import {ProgressCenter} from '../../externs/background/progress_center.js'; import {ProgressCenterPanelInterface} from '../../externs/progress_center_panel.js'; @@ -24,14 +20,6 @@ this.items_ = []; /** - * Map of progress ID and notification ID. - * @private @const @type {!ProgressCenterImpl.Notifications_} - */ - this.notifications_ = new ProgressCenterImpl.Notifications_( - this.requestCancel.bind(this), - this.onNotificationDismissed_.bind(this)); - - /** * List of panel UI managed by the progress center. * @private @const @type {!Array<ProgressCenterPanelInterface>} */ @@ -87,9 +75,6 @@ // @ts-ignore: error TS2532: Object is possibly 'undefined'. this.panels_[i].updateItem(item); } - - // Update notifications. - this.notifications_.updateItem(item, !this.panels_.length); } /** @@ -104,18 +89,6 @@ } /** - * Called when notification is dismissed. - * @param {string} id Item id. - * @private - */ - onNotificationDismissed_(id) { - const item = this.getItemById(id); - if (item && item.state === ProgressItemState.ERROR) { - this.dismissErrorItem_(id); - } - } - - /** * Adds a panel UI to the notification center. * @param {ProgressCenterPanelInterface} panel Panel UI. */ @@ -160,16 +133,6 @@ // @ts-ignore: error TS2339: Property 'cancelCallback' does not exist on // type 'ProgressCenterPanelInterface'. panel.cancelCallback = null; - - // If there is no panel, show the notifications. - if (this.panels_.length) { - return; - } - for (let i = 0; i < this.items_.length; i++) { - // @ts-ignore: error TS2345: Argument of type 'ProgressCenterItem | - // undefined' is not assignable to parameter of type 'ProgressCenterItem'. - this.notifications_.updateItem(this.items_[i], true); - } } /** @@ -209,8 +172,6 @@ this.items_.splice(index, 1); } - this.notifications_.dismissErrorItem(id); - for (let i = 0; i < this.panels_.length; i++) { // @ts-ignore: error TS2532: Object is possibly 'undefined'. this.panels_[i].dismissErrorItem(id); @@ -419,181 +380,3 @@ return item; } } - -/** - * Notifications created by progress center. - * @private - */ -// @ts-ignore: error TS2341: Property 'Notifications_' is private and only -// accessible within class 'ProgressCenterImpl'. -ProgressCenterImpl.Notifications_ = class { - /** - * @param {function(string):void} cancelCallback Callback to notify the - * progress center of cancel operation. - * @param {function(string):void} dismissCallback Callback to notify the - * progress center that a notification is dismissed. - */ - constructor(cancelCallback, dismissCallback) { - /** - * ID set of notifications that is progressing now. - * @private - * @const @type {Record<string, - * ProgressCenterImpl.Notifications_.NotificationState_>} - */ - this.ids_ = {}; - - /** - * Async queue. - * @private @const @type {AsyncQueue} - */ - this.queue_ = new AsyncQueue(); - - /** - * Callback to notify the progress center of cancel operation. - * @private @const @type {function(string):void} - */ - this.cancelCallback_ = cancelCallback; - - /** - * Callback to notify the progress center that a notification is dismissed. - * @private @type {function(string):void} - */ - this.dismissCallback_ = dismissCallback; - - notifications.onButtonClicked.addListener(this.onButtonClicked_.bind(this)); - notifications.onClosed.addListener(this.onClosed_.bind(this)); - } - - /** - * Updates the notification according to the item. - * @param {ProgressCenterItem} item Item to contain new information. - * @param {boolean} newItemAcceptable Whether to accept new item or not. - */ - updateItem(item, newItemAcceptable) { - const NotificationState = - // @ts-ignore: error TS2341: Property 'Notifications_' is private and - // only accessible within class 'ProgressCenterImpl'. - ProgressCenterImpl.Notifications_.NotificationState_; - const newlyAdded = !(item.id in this.ids_); - - // If new item is not acceptable, just return. - if (newlyAdded && !newItemAcceptable) { - return; - } - - // Update the ID map and return if we does not show a notification for the - // item. - if (item.state === ProgressItemState.PROGRESSING || - item.state === ProgressItemState.ERROR) { - if (newlyAdded) { - // @ts-ignore: error TS7053: Element implicitly has an 'any' type - // because expression of type 'string' can't be used to index type '{}'. - this.ids_[item.id] = NotificationState.VISIBLE; - // @ts-ignore: error TS7053: Element implicitly has an 'any' type - // because expression of type 'string' can't be used to index type '{}'. - } else if (this.ids_[item.id] === NotificationState.DISMISSED) { - return; - } - } else { - // This notification is no longer tracked. - // @ts-ignore: error TS7053: Element implicitly has an 'any' type because - // expression of type 'string' can't be used to index type '{}'. - const previousState = this.ids_[item.id]; - // @ts-ignore: error TS7053: Element implicitly has an 'any' type because - // expression of type 'string' can't be used to index type '{}'. - delete this.ids_[item.id]; - // Clear notifications for complete or canceled items. - if (item.state === ProgressItemState.CANCELED || - item.state === ProgressItemState.COMPLETED) { - if (previousState === NotificationState.VISIBLE) { - this.queue_.run(proceed => { - notifications.clear(item.id, proceed); - }); - } - return; - } - } - - // Create/update the notification with the item. - this.queue_.run(proceed => { - const params = { - title: str('FILEMANAGER_APP_NAME'), - iconUrl: getFilesAppIconURL().toString(), - type: item.state === ProgressItemState.PROGRESSING ? 'progress' : - 'basic', - message: item.message, - buttons: item.cancelable ? [{title: str('CANCEL_LABEL')}] : undefined, - progress: item.state === ProgressItemState.PROGRESSING ? - item.progressRateInPercent : - undefined, - priority: (item.state === ProgressItemState.ERROR || !item.quiet) ? 0 : - -1, - }; - - if (newlyAdded) { - notifications.create(item.id, params, proceed); - } else { - notifications.update(item.id, params, proceed); - } - }); - } - - /** - * Dismisses error item. - * @param {string} id Item ID. - */ - dismissErrorItem(id) { - // @ts-ignore: error TS7053: Element implicitly has an 'any' type because - // expression of type 'string' can't be used to index type '{}'. - if (!this.ids_[id]) { - return; - } - - // @ts-ignore: error TS7053: Element implicitly has an 'any' type because - // expression of type 'string' can't be used to index type '{}'. - delete this.ids_[id]; - - this.queue_.run(proceed => { - notifications.clear(id, proceed); - }); - } - - /** - * Handles cancel button click. - * @param {string} id Item ID. - * @private - */ - onButtonClicked_(id) { - if (id in this.ids_) { - this.cancelCallback_(id); - } - } - - /** - * Handles notification close. - * @param {string} id Item ID. - * @private - */ - onClosed_(id) { - if (id in this.ids_) { - // @ts-ignore: error TS7053: Element implicitly has an 'any' type because - // expression of type 'string' can't be used to index type '{}'. - this.ids_[id] = - // @ts-ignore: error TS2341: Property 'Notifications_' is private and - // only accessible within class 'ProgressCenterImpl'. - ProgressCenterImpl.Notifications_.NotificationState_.DISMISSED; - this.dismissCallback_(id); - } - } -}; - -/** - * State of notification. - * @private @const @enum {string} - */ -// @ts-ignore: error TS2341: Property 'Notifications_' is private and only -// accessible within class 'ProgressCenterImpl'. -ProgressCenterImpl.Notifications_.NotificationState_ = { - VISIBLE: 'visible', - DISMISSED: 'dismissed', -};
diff --git a/ui/file_manager/file_manager/common/js/dialog_type.ts b/ui/file_manager/file_manager/common/js/dialog_type.ts index c72d35d7..4610049 100644 --- a/ui/file_manager/file_manager/common/js/dialog_type.ts +++ b/ui/file_manager/file_manager/common/js/dialog_type.ts
@@ -2,20 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -/** - * List of dialog types. - * - * Keep this in sync with FileManagerDialog::GetDialogTypeAsString, except - * FULL_PAGE which is specific to this code. - */ -export enum DialogType { - SELECT_FOLDER = 'folder', - SELECT_UPLOAD_FOLDER = 'upload-folder', - SELECT_SAVEAS_FILE = 'saveas-file', - SELECT_OPEN_FILE = 'open-file', - SELECT_OPEN_MULTI_FILE = 'open-multi-file', - FULL_PAGE = 'full-page', -} +import {DialogType} from '../../externs/ts/state.js'; export function isModal(type: DialogType): boolean { return type == DialogType.SELECT_FOLDER ||
diff --git a/ui/file_manager/file_manager/common/js/entry_utils.ts b/ui/file_manager/file_manager/common/js/entry_utils.ts index bc26ea2..fe14d6fb 100644 --- a/ui/file_manager/file_manager/common/js/entry_utils.ts +++ b/ui/file_manager/file_manager/common/js/entry_utils.ts
@@ -863,14 +863,9 @@ */ export function isInteractiveVolume(volumeInfo: VolumeInfo) { const state = getStore().getState(); - const volumes = state.volumes; - if (!volumes) { - console.error('Expected volumes to exist in the store.'); - return true; - } - const volume = volumes[volumeInfo.volumeId]; + const volume = state.volumes[volumeInfo.volumeId]; if (!volume) { - console.error('Expected volume to be in the store.'); + console.warn('Expected volume to be in the store.'); return true; } return volume.isInteractive;
diff --git a/ui/file_manager/file_manager/common/js/files_app_state.ts b/ui/file_manager/file_manager/common/js/files_app_state.ts index 7a93f90..e4007e5 100644 --- a/ui/file_manager/file_manager/common/js/files_app_state.ts +++ b/ui/file_manager/file_manager/common/js/files_app_state.ts
@@ -2,7 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import {DialogType} from './dialog_type.js'; +import {DialogType} from '../../externs/ts/state.js'; + import {AllowedPaths} from './volume_manager_types.js'; /**
diff --git a/ui/file_manager/file_manager/common/js/notifications.js b/ui/file_manager/file_manager/common/js/notifications.js deleted file mode 100644 index 8ca09871..0000000 --- a/ui/file_manager/file_manager/common/js/notifications.js +++ /dev/null
@@ -1,184 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -/** - * @fileoverview A helper class used as a browser proxy for the - * chrome.notifications browser API. - */ - -/** @interface */ -export class NotificationsBrowserProxy { - /** - * @param {string} notificationId - * @param {function(boolean):void} callback - */ - // @ts-ignore: error TS6133: 'callback' is declared but its value is never - // read. - clear(notificationId, callback) {} - - /** - * @param {string} notificationId - * @param {NotificationOptions} options - * @param {function(string):void} callback - */ - // @ts-ignore: error TS6133: 'callback' is declared but its value is never - // read. - create(notificationId, options, callback) {} - - /** - * @param {function(Object):void} callback - */ - // @ts-ignore: error TS6133: 'callback' is declared but its value is never - // read. - getAll(callback) {} - - /** - * @param {function(string):void} callback - */ - // @ts-ignore: error TS6133: 'callback' is declared but its value is never - // read. - getPermissionLevel(callback) {} - - /** - * @param {string} notificationId - * @param {NotificationOptions} options - * @param {function(boolean):void} callback - */ - // @ts-ignore: error TS6133: 'callback' is declared but its value is never - // read. - update(notificationId, options, callback) {} - - /** - * @param {boolean} enabled - */ - // @ts-ignore: error TS6133: 'enabled' is declared but its value is never - // read. - setSystemNotificationEnabled(enabled) {} -} - -/** - * The events that we need to attach listeners to. - * @readonly - * @enum {string} - */ -const NotificationEventTypes = { - CLICKED: 'onClicked', - BUTTON_CLICKED: 'onButtonClicked', - CLOSED: 'onClosed', -}; - -Object.freeze(NotificationEventTypes); - -class SystemNotificationEvent { - // @ts-ignore: error TS7006: Parameter 'systemNotificationEnabled' implicitly - // has an 'any' type. - constructor(eventType, systemNotificationEnabled) { - this.eventType = eventType; - this.systemNotificationEnabled = systemNotificationEnabled; - } - - // @ts-ignore: error TS7006: Parameter 'callback' implicitly has an 'any' - // type. - addListener(callback) { - if (this.systemNotificationEnabled) { - switch (this.eventType) { - case NotificationEventTypes.CLICKED: - // @ts-ignore: error TS2339: Property 'notifications' does not exist - // on type 'typeof chrome'. - chrome.notifications.onClicked.addListener(callback); - break; - case NotificationEventTypes.BUTTON_CLICKED: - // @ts-ignore: error TS2339: Property 'notifications' does not exist - // on type 'typeof chrome'. - chrome.notifications.onButtonClicked.addListener(callback); - break; - case NotificationEventTypes.CLOSED: - // @ts-ignore: error TS2339: Property 'notifications' does not exist - // on type 'typeof chrome'. - chrome.notifications.onClosed.addListener(callback); - break; - } - } - } -} - -/** - * @implements {NotificationsBrowserProxy} - */ -export class NotificationsBrowserProxyImpl { - // @ts-ignore: error TS7006: Parameter 'systemNotificationEnabled' implicitly - // has an 'any' type. - constructor(systemNotificationEnabled) { - this.systemNotificationEnabled = systemNotificationEnabled; - this.onClicked = - new SystemNotificationEvent('onClicked', systemNotificationEnabled); - this.onButtonClicked = new SystemNotificationEvent( - 'onButtonClicked', systemNotificationEnabled); - this.onClosed = - new SystemNotificationEvent('onClosed', systemNotificationEnabled); - } - - /** @override */ - // @ts-ignore: error TS7006: Parameter 'callback' implicitly has an 'any' - // type. - clear(notificationId, callback) { - if (this.systemNotificationEnabled) { - // @ts-ignore: error TS2339: Property 'notifications' does not exist on - // type 'typeof chrome'. - chrome.notifications.clear(notificationId, callback); - } - } - - /** @override */ - // @ts-ignore: error TS7006: Parameter 'callback' implicitly has an 'any' - // type. - create(notificationId, options, callback) { - if (this.systemNotificationEnabled) { - // @ts-ignore: error TS2339: Property 'notifications' does not exist on - // type 'typeof chrome'. - chrome.notifications.create(notificationId, options, callback); - } - } - - /** @override */ - // @ts-ignore: error TS7006: Parameter 'callback' implicitly has an 'any' - // type. - getAll(callback) { - if (this.systemNotificationEnabled) { - // @ts-ignore: error TS2339: Property 'notifications' does not exist on - // type 'typeof chrome'. - chrome.notifications.getAll(callback); - } - } - - /** @override */ - // @ts-ignore: error TS7006: Parameter 'callback' implicitly has an 'any' - // type. - getPermissionLevel(callback) { - if (this.systemNotificationEnabled) { - // @ts-ignore: error TS2339: Property 'notifications' does not exist on - // type 'typeof chrome'. - chrome.notifications.getPermissionLevel(callback); - } - } - - /** @override */ - // @ts-ignore: error TS7006: Parameter 'callback' implicitly has an 'any' - // type. - update(notificationId, options, callback) { - if (this.systemNotificationEnabled) { - // @ts-ignore: error TS2339: Property 'notifications' does not exist on - // type 'typeof chrome'. - chrome.notifications.update(notificationId, options, callback); - } - } - - /** @override */ - // @ts-ignore: error TS7006: Parameter 'enabled' implicitly has an 'any' type. - setSystemNotificationEnabled(enabled) { - this.systemNotificationEnabled = enabled; - } -} - -export const notifications = new NotificationsBrowserProxyImpl(false);
diff --git a/ui/file_manager/file_manager/common/js/recent_date_bucket_unittest.js b/ui/file_manager/file_manager/common/js/recent_date_bucket_unittest.ts similarity index 100% rename from ui/file_manager/file_manager/common/js/recent_date_bucket_unittest.js rename to ui/file_manager/file_manager/common/js/recent_date_bucket_unittest.ts
diff --git a/ui/file_manager/file_manager/containers/directory_tree_container.ts b/ui/file_manager/file_manager/containers/directory_tree_container.ts index e17ed70e..13d3da2 100644 --- a/ui/file_manager/file_manager/containers/directory_tree_container.ts +++ b/ui/file_manager/file_manager/containers/directory_tree_container.ts
@@ -12,14 +12,14 @@ import {recordEnum, recordUserAction} from '../common/js/metrics.js'; import {str, strf} from '../common/js/translations.js'; import {VolumeManagerCommon} from '../common/js/volume_manager_types.js'; -import {AndroidApp, FileData, FileKey, NavigationKey, NavigationRoot, NavigationType, PropStatus, State} from '../externs/ts/state.js'; +import {AndroidApp, CurrentDirectory, FileData, FileKey, NavigationKey, NavigationRoot, NavigationType, PropStatus, State} from '../externs/ts/state.js'; import {VolumeManager} from '../externs/volume_manager.js'; import {constants} from '../foreground/js/constants.js'; import {DirectoryModel} from '../foreground/js/directory_model.js'; import {Command} from '../foreground/js/ui/command.js'; import {contextMenuHandler} from '../foreground/js/ui/context_menu_handler.js'; import {Menu} from '../foreground/js/ui/menu.js'; -import {convertEntryToFileData, readSubDirectories} from '../state/ducks/all_entries.js'; +import {convertEntryToFileData, readSubDirectories, traverseAndExpandPathEntries} from '../state/ducks/all_entries.js'; import {changeDirectory} from '../state/ducks/current_directory.js'; import {refreshNavigationRoots, updateNavigationEntry} from '../state/ducks/navigation.js'; import {driveRootEntryListKey} from '../state/ducks/volumes.js'; @@ -97,6 +97,16 @@ */ private shouldFocusOnNextSelectedItem_: boolean = false; + /** + * When current directory changes, if the corresponding tree item has not been + * rendered yet, an asynchronous read-sub-directory action will be dispatched + * to read the children until we could find the item. During this asynchronous + * process, the current directory might change again (either manually by user + * or other operations), we need this variable to see if we need to trigger + * another read-sub-directories call or not. + */ + private entryKeyToSelect_: FileKey|null = null; + private store_: Store; /** @@ -168,23 +178,13 @@ const {navigation: {roots}, androidApps, currentDirectory} = state; - // When current directory changes in the store, select the corresponding - // navigation item. + // When current directory changes in the store, and the selected item in the + // tree is different from that, select the corresponding navigation item. + const selectedItemKey = this.tree.selectedItem?.dataset['navigationKey']; if (currentDirectory?.key && - currentDirectory.status === PropStatus.SUCCESS) { - const element = - this.getNavigationDataFromKey_(currentDirectory.key)?.element; - if (element && !element.selected) { - element.selected = true; - if (this.shouldFocusOnNextSelectedItem_) { - this.shouldFocusOnNextSelectedItem_ = false; - this.tree.focusedItem = element; - // Wait for the selected change finishes (e.g. expand all its parents) - // before we can focus on the element below. - await element.updateComplete; - element.focus(); - } - } + currentDirectory.status === PropStatus.SUCCESS && + currentDirectory.key !== selectedItemKey) { + await this.selectCurrentDirectoryItem_(currentDirectory); } // When navigation roots data changes in the store, re-render all navigation @@ -367,6 +367,7 @@ // when refactoring the command part. (element as any).entry = fileData.entry; + element.expanded = fileData.expanded; element.label = fileData.label; if (navigationRoot) { element.separator = navigationRoot.separator; @@ -604,10 +605,6 @@ if (isMyFilesEntry(entry)) { element.mayHaveChildren = true; element.expanded = true; - this.store_.dispatch(updateNavigationEntry({ - key: entry.toURL(), - expanded: true, - })); return; } if (fileData.shouldDelayLoadingChildren) { @@ -1162,4 +1159,48 @@ return currentDirectory?.key === navigationKey && currentDirectory.status === PropStatus.SUCCESS; } + + private async selectCurrentDirectoryItem_(currentDirectory: CurrentDirectory): + Promise<void> { + const currentDirectoryKey = currentDirectory.key; + const navigationData = this.getNavigationDataFromKey_(currentDirectoryKey); + if (navigationData) { + const element = navigationData.element; + if (element && !element.selected) { + // Reset entryKeyToSelect_ because we already find the element which + // represents current directory. + this.entryKeyToSelect_ = null; + element.selected = true; + if (this.shouldFocusOnNextSelectedItem_) { + this.shouldFocusOnNextSelectedItem_ = false; + this.tree.focusedItem = element; + // Wait for the selected change finishes (e.g. expand all its parents) + // before we can focus on the element below. + await element.updateComplete; + element.focus(); + } + } + return; + } + // The item which represents the current directory can not be found in the + // tree, we need to read sub directory from the root recursively until we + // find the targeted current directory. + + if (this.entryKeyToSelect_ === currentDirectoryKey) { + // Do nothing because we already started a reading call to find this exact + // same "current directory" (see logic below.) + return; + } + + // Set the selected item to null before scanning for the target directory, + // if we couldn't find the target directory after scanning (e.g. "Go to + // file location" for Play files in recent view b/265101238), nothing + // should be selected in the tree. + this.tree.selectedItem = null; + + this.entryKeyToSelect_ = currentDirectoryKey; + const pathEntryKeys = + currentDirectory.pathComponents.map(pathComponent => pathComponent.key); + this.store_.dispatch(traverseAndExpandPathEntries(pathEntryKeys)); + } }
diff --git a/ui/file_manager/file_manager/externs/command_handler_deps.js b/ui/file_manager/file_manager/externs/command_handler_deps.js index 7431ab0..b8172fc 100644 --- a/ui/file_manager/file_manager/externs/command_handler_deps.js +++ b/ui/file_manager/file_manager/externs/command_handler_deps.js
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import {DialogType} from '../common/js/dialog_type.js'; import {FilesAppState} from '../common/js/files_app_state.js'; +import {DialogType} from '../externs/ts/state.js'; import {ActionsController} from '../foreground/js/actions_controller.js'; import {FileFilter} from '../foreground/js/directory_contents.js'; import {DirectoryModel} from '../foreground/js/directory_model.js';
diff --git a/ui/file_manager/file_manager/externs/ts/state.js b/ui/file_manager/file_manager/externs/ts/state.js index f5157c3..128edca 100644 --- a/ui/file_manager/file_manager/externs/ts/state.js +++ b/ui/file_manager/file_manager/externs/ts/state.js
@@ -2,12 +2,27 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import {DialogType} from '../../common/js/dialog_type.js'; import {VolumeManagerCommon} from '../../common/js/volume_manager_types.js'; import {MetadataItem} from '../../foreground/js/metadata/metadata_item.js'; import {FilesAppEntry} from '../files_app_entry_interfaces.js'; /** + * List of dialog types. + * + * Keep this in sync with FileManagerDialog::GetDialogTypeAsString, except + * FULL_PAGE which is specific to this code. + * @enum {string} + */ +export const DialogType = { + SELECT_FOLDER: 'folder', + SELECT_UPLOAD_FOLDER: 'upload-folder', + SELECT_SAVEAS_FILE: 'saveas-file', + SELECT_OPEN_FILE: 'open-file', + SELECT_OPEN_MULTI_FILE: 'open-multi-file', + FULL_PAGE: 'full-page', +}; + +/** * @enum {string} */ export const EntryType = {
diff --git a/ui/file_manager/file_manager/foreground/js/app_state_controller.js b/ui/file_manager/file_manager/foreground/js/app_state_controller.js index 12f4545..d5ae955a 100644 --- a/ui/file_manager/file_manager/foreground/js/app_state_controller.js +++ b/ui/file_manager/file_manager/foreground/js/app_state_controller.js
@@ -5,9 +5,9 @@ import {assert} from 'chrome://resources/ash/common/assert.js'; import {saveAppState, updateAppState} from '../../common/js/app_util.js'; -import {DialogType} from '../../common/js/dialog_type.js'; import {isRecentRoot} from '../../common/js/entry_utils.js'; import {storage} from '../../common/js/storage.js'; +import {DialogType} from '../../externs/ts/state.js'; import {DirectoryModel} from './directory_model.js'; import {GROUP_BY_FIELD_DIRECTORY, GROUP_BY_FIELD_MODIFICATION_TIME} from './file_list_model.js';
diff --git a/ui/file_manager/file_manager/foreground/js/banner_controller.ts b/ui/file_manager/file_manager/foreground/js/banner_controller.ts index 034c9e0..0a1d2a9a 100644 --- a/ui/file_manager/file_manager/foreground/js/banner_controller.ts +++ b/ui/file_manager/file_manager/foreground/js/banner_controller.ts
@@ -12,7 +12,6 @@ import {getDriveQuotaMetadata, getSizeStats} from '../../common/js/api.js'; import {RateLimiter} from '../../common/js/async_util.js'; -import {DialogType} from '../../common/js/dialog_type.js'; import {getTeamDriveName} from '../../common/js/entry_utils.js'; import {isGoogleOneOfferFilesBannerEligibleAndEnabled} from '../../common/js/flags.js'; import {storage} from '../../common/js/storage.js'; @@ -20,7 +19,7 @@ import {VolumeManagerCommon} from '../../common/js/volume_manager_types.js'; import {Crostini} from '../../externs/background/crostini.js'; import {FakeEntry, FilesAppDirEntry} from '../../externs/files_app_entry_interfaces.js'; -import {State} from '../../externs/ts/state.js'; +import {DialogType, State} from '../../externs/ts/state.js'; import {Store} from '../../externs/ts/store.js'; import type {VolumeInfo} from '../../externs/volume_info.js'; import {VolumeManager} from '../../externs/volume_manager.js';
diff --git a/ui/file_manager/file_manager/foreground/js/banner_controller_unittest.ts b/ui/file_manager/file_manager/foreground/js/banner_controller_unittest.ts index 5070fe2..883f8be 100644 --- a/ui/file_manager/file_manager/foreground/js/banner_controller_unittest.ts +++ b/ui/file_manager/file_manager/foreground/js/banner_controller_unittest.ts
@@ -4,13 +4,13 @@ import {assertDeepEquals, assertEquals} from 'chrome://webui-test/chromeos/chai_assert.js'; -import {DialogType} from '../../common/js/dialog_type.js'; import {FakeEntryImpl} from '../../common/js/files_app_entry_types.js'; import {installMockChrome, MockChromeFileManagerPrivateDirectoryChanged, MockChromeStorageAPI} from '../../common/js/mock_chrome.js'; import {storage} from '../../common/js/storage.js'; import {waitUntil} from '../../common/js/test_error_reporting.js'; import {VolumeManagerCommon} from '../../common/js/volume_manager_types.js'; import {Crostini} from '../../externs/background/crostini.js'; +import {DialogType} from '../../externs/ts/state.js'; import type {VolumeInfo} from '../../externs/volume_info.js'; import {VolumeManager} from '../../externs/volume_manager.js';
diff --git a/ui/file_manager/file_manager/foreground/js/dialog_action_controller.js b/ui/file_manager/file_manager/foreground/js/dialog_action_controller.js index d37913f..b467b83d 100644 --- a/ui/file_manager/file_manager/foreground/js/dialog_action_controller.js +++ b/ui/file_manager/file_manager/foreground/js/dialog_action_controller.js
@@ -5,11 +5,12 @@ import {assert, assertNotReached} from 'chrome://resources/ash/common/assert.js'; import {$} from 'chrome://resources/ash/common/util.js'; -import {DialogType, isFolderDialogType} from '../../common/js/dialog_type.js'; +import {isFolderDialogType} from '../../common/js/dialog_type.js'; import {recordEnum} from '../../common/js/metrics.js'; import {str} from '../../common/js/translations.js'; import {testSendMessage, UserCanceledError} from '../../common/js/util.js'; import {AllowedPaths, VolumeManagerCommon} from '../../common/js/volume_manager_types.js'; +import {DialogType} from '../../externs/ts/state.js'; import {VolumeManager} from '../../externs/volume_manager.js'; import {FileFilter} from './directory_contents.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 a8eb949..2821b5a 100644 --- a/ui/file_manager/file_manager/foreground/js/file_manager.js +++ b/ui/file_manager/file_manager/foreground/js/file_manager.js
@@ -19,7 +19,7 @@ import {getBulkPinProgress, getDialogCaller, getDlpBlockedComponents, getDriveConnectionState, getPreferences} from '../../common/js/api.js'; import {ArrayDataModel} from '../../common/js/array_data_model.js'; -import {DialogType, isFolderDialogType} from '../../common/js/dialog_type.js'; +import {isFolderDialogType} from '../../common/js/dialog_type.js'; import {getKeyModifiers, queryDecoratedElement, queryRequiredElement} from '../../common/js/dom_utils.js'; import {EntryList, FakeEntryImpl} from '../../common/js/files_app_entry_types.js'; import {FilesAppState} from '../../common/js/files_app_state.js'; @@ -39,7 +39,7 @@ import {CommandHandlerDeps} from '../../externs/command_handler_deps.js'; import {FakeEntry, FilesAppDirEntry} from '../../externs/files_app_entry_interfaces.js'; import {ForegroundWindow} from '../../externs/foreground_window.js'; -import {PropStatus} from '../../externs/ts/state.js'; +import {DialogType, PropStatus} from '../../externs/ts/state.js'; import {Store} from '../../externs/ts/store.js'; import {getMyFiles} from '../../state/ducks/all_entries.js'; import {updateBulkPinProgress} from '../../state/ducks/bulk_pinning.js';
diff --git a/ui/file_manager/file_manager/foreground/js/file_manager_commands.js b/ui/file_manager/file_manager/foreground/js/file_manager_commands.js index 236912e..d498273 100644 --- a/ui/file_manager/file_manager/foreground/js/file_manager_commands.js +++ b/ui/file_manager/file_manager/foreground/js/file_manager_commands.js
@@ -8,9 +8,9 @@ import {loadTimeData} from 'chrome://resources/ash/common/load_time_data.m.js'; import {getDlpRestrictionDetails, getHoldingSpaceState, startIOTask} from '../../common/js/api.js'; -import {DialogType, isModal} from '../../common/js/dialog_type.js'; +import {isModal} from '../../common/js/dialog_type.js'; import {getFocusedTreeItem, isDirectoryTree, isDirectoryTreeItem} from '../../common/js/dom_utils.js'; -import {entriesToURLs, isFakeEntry, isInteractiveVolume, isNonModifiable, isRecentRootType, isSameEntry, isSameVolume, isTeamDriveRoot, isTeamDrivesGrandRoot, isTrashEntry, isTrashRoot, isTrashRootType, unwrapEntry} from '../../common/js/entry_utils.js'; +import {entriesToURLs, isFakeEntry, isGrandRootEntryInDrives, isInteractiveVolume, isNonModifiable, isRecentRootType, isSameEntry, isSameVolume, isTeamDriveRoot, isTeamDrivesGrandRoot, isTrashEntry, isTrashRoot, isTrashRootType, unwrapEntry} from '../../common/js/entry_utils.js'; import {FileType} from '../../common/js/file_type.js'; import {EntryList} from '../../common/js/files_app_entry_types.js'; import {isDlpEnabled, isDriveFsBulkPinningEnabled, isMirrorSyncEnabled, isNewDirectoryTreeEnabled, isSinglePartitionFormatEnabled} from '../../common/js/flags.js'; @@ -21,7 +21,7 @@ import {VolumeManagerCommon} from '../../common/js/volume_manager_types.js'; import {CommandHandlerDeps} from '../../externs/command_handler_deps.js'; import {FakeEntry, FilesAppDirEntry, FilesAppEntry} from '../../externs/files_app_entry_interfaces.js'; -import {State} from '../../externs/ts/state.js'; +import {DialogType, State} from '../../externs/ts/state.js'; import {VolumeManager} from '../../externs/volume_manager.js'; import {readSubDirectories} from '../../state/ducks/all_entries.js'; import {changeDirectory} from '../../state/ducks/current_directory.js'; @@ -2264,8 +2264,13 @@ // @ts-ignore: error TS2345: Argument of type 'FileSystemEntry | undefined' // is not assignable to parameter of type 'FileSystemEntry | null'. const isRecentArcEntry = VolumeManagerCommon.isRecentArcEntry(entries[0]); + // Drive grand roots do not support rename. + // @ts-ignore: error TS2345: Argument of type 'FileSystemEntry | undefined' + // is not assignable to parameter of type 'FileSystemEntry | null'. + const isDriveGrandRoot = isGrandRootEntryInDrives(entries[0]); + event.canExecute = entries.length === 1 && volumeIsNotReadOnly && - !isRecentArcEntry && + !isRecentArcEntry && !isDriveGrandRoot && CommandUtil.hasCapability(fileManager, entries, 'canRename'); event.command.setHidden(false); }
diff --git a/ui/file_manager/file_manager/foreground/js/file_transfer_controller_unittest.ts b/ui/file_manager/file_manager/foreground/js/file_transfer_controller_unittest.ts index 2b1855b..9584333 100644 --- a/ui/file_manager/file_manager/foreground/js/file_transfer_controller_unittest.ts +++ b/ui/file_manager/file_manager/foreground/js/file_transfer_controller_unittest.ts
@@ -10,11 +10,11 @@ import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chromeos/chai_assert.js'; import {MockVolumeManager} from '../../background/js/mock_volume_manager.js'; -import {DialogType} from '../../common/js/dialog_type.js'; import {MockDirectoryEntry, MockFileEntry, MockFileSystem} from '../../common/js/mock_entry.js'; import {decorate} from '../../common/js/ui.js'; import {VolumeManagerCommon} from '../../common/js/volume_manager_types.js'; import {ProgressCenter} from '../../externs/background/progress_center.js'; +import {DialogType} from '../../externs/ts/state.js'; import {VolumeManager} from '../../externs/volume_manager.js'; import {FilesToast} from '../elements/files_toast.js';
diff --git a/ui/file_manager/file_manager/foreground/js/launch_param.ts b/ui/file_manager/file_manager/foreground/js/launch_param.ts index 131c546..c596891 100644 --- a/ui/file_manager/file_manager/foreground/js/launch_param.ts +++ b/ui/file_manager/file_manager/foreground/js/launch_param.ts
@@ -2,9 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import {DialogType} from '../../common/js/dialog_type.js'; import {FilesAppState} from '../../common/js/files_app_state.js'; import {AllowedPaths} from '../../common/js/volume_manager_types.js'; +import {DialogType} from '../../externs/ts/state.js'; /** * Parsed options used to launch a new Files app window.
diff --git a/ui/file_manager/file_manager/foreground/js/main_window_component.js b/ui/file_manager/file_manager/foreground/js/main_window_component.js index 1572edc..a7cd53d 100644 --- a/ui/file_manager/file_manager/foreground/js/main_window_component.js +++ b/ui/file_manager/file_manager/foreground/js/main_window_component.js
@@ -4,7 +4,7 @@ import {assertInstanceof} from 'chrome://resources/ash/common/assert.js'; -import {DialogType, isFolderDialogType} from '../../common/js/dialog_type.js'; +import {isFolderDialogType} from '../../common/js/dialog_type.js'; import {getFocusedTreeItem, getKeyModifiers} from '../../common/js/dom_utils.js'; import {isRecentRootType, isSameEntry, isTrashEntry} from '../../common/js/entry_utils.js'; import {isNewDirectoryTreeEnabled} from '../../common/js/flags.js'; @@ -13,6 +13,7 @@ import {TrashEntry} from '../../common/js/trash.js'; import {VolumeManagerCommon} from '../../common/js/volume_manager_types.js'; import {DirectoryChangeEvent} from '../../externs/directory_change_event.js'; +import {DialogType} from '../../externs/ts/state.js'; import {VolumeManager} from '../../externs/volume_manager.js'; import {changeDirectory} from '../../state/ducks/current_directory.js'; import {getStore} from '../../state/store.js';
diff --git a/ui/file_manager/file_manager/foreground/js/navigation_list_model.js b/ui/file_manager/file_manager/foreground/js/navigation_list_model.js index 246d5903..37ca392 100644 --- a/ui/file_manager/file_manager/foreground/js/navigation_list_model.js +++ b/ui/file_manager/file_manager/foreground/js/navigation_list_model.js
@@ -5,13 +5,13 @@ import {assertNotReached} from 'chrome://resources/ash/common/assert.js'; import {NativeEventTarget as EventTarget} from 'chrome://resources/ash/common/event_target.js'; -import {DialogType} from '../../common/js/dialog_type.js'; import {isOneDrive} from '../../common/js/entry_utils.js'; import {EntryList, VolumeEntry} from '../../common/js/files_app_entry_types.js'; import {isArcVmEnabled, isGuestOsEnabled, isSinglePartitionFormatEnabled} from '../../common/js/flags.js'; import {str} from '../../common/js/translations.js'; import {VolumeManagerCommon} from '../../common/js/volume_manager_types.js'; import {FilesAppEntry} from '../../externs/files_app_entry_interfaces.js'; +import {DialogType} from '../../externs/ts/state.js'; import {VolumeManager} from '../../externs/volume_manager.js'; import {getStore} from '../../state/store.js';
diff --git a/ui/file_manager/file_manager/foreground/js/navigation_list_model_unittest.js b/ui/file_manager/file_manager/foreground/js/navigation_list_model_unittest.js index 321c9c13..373ec0f 100644 --- a/ui/file_manager/file_manager/foreground/js/navigation_list_model_unittest.js +++ b/ui/file_manager/file_manager/foreground/js/navigation_list_model_unittest.js
@@ -7,7 +7,6 @@ import {fakeDriveVolumeId, MockVolumeManager} from '../../background/js/mock_volume_manager.js'; import {VolumeInfoImpl} from '../../background/js/volume_info_impl.js'; -import {DialogType} from '../../common/js/dialog_type.js'; import {EntryList, FakeEntryImpl, VolumeEntry} from '../../common/js/files_app_entry_types.js'; import {isSinglePartitionFormatEnabled} from '../../common/js/flags.js'; import {MockCommandLinePrivate} from '../../common/js/mock_chrome.js'; @@ -17,6 +16,7 @@ import {TrashRootEntry} from '../../common/js/trash.js'; import {VolumeManagerCommon} from '../../common/js/volume_manager_types.js'; import {FilesAppEntry} from '../../externs/files_app_entry_interfaces.js'; +import {DialogType} from '../../externs/ts/state.js'; import {AndroidAppListModel} from './android_app_list_model.js'; import {constants} from './constants.js';
diff --git a/ui/file_manager/file_manager/foreground/js/quick_view_controller.ts b/ui/file_manager/file_manager/foreground/js/quick_view_controller.ts index 4736f4b..755eae9 100644 --- a/ui/file_manager/file_manager/foreground/js/quick_view_controller.ts +++ b/ui/file_manager/file_manager/foreground/js/quick_view_controller.ts
@@ -12,13 +12,14 @@ import {LoadImageRequest, LoadImageResponse, LoadImageResponseStatus} from 'chrome-extension://pmfjbimdmchhbnneeidfognadeopoehp/load_image_request.js'; import {assert} from 'chrome://resources/js/assert.js'; -import {DialogType, isModal} from '../../common/js/dialog_type.js'; +import {isModal} from '../../common/js/dialog_type.js'; import {isSameEntry} from '../../common/js/entry_utils.js'; import {parseActionId} from '../../common/js/file_tasks.js'; import {FileType} from '../../common/js/file_type.js'; import {getEntryLabel, str} from '../../common/js/translations.js'; import {VolumeManagerCommon} from '../../common/js/volume_manager_types.js'; import {CommandHandlerDeps} from '../../externs/command_handler_deps.js'; +import {DialogType} from '../../externs/ts/state.js'; import {VolumeManager} from '../../externs/volume_manager.js'; import {FilesQuickView} from '../elements/files_quick_view.js'; import type {FilesTooltip} from '../elements/files_tooltip.js';
diff --git a/ui/file_manager/file_manager/foreground/js/quick_view_uma.ts b/ui/file_manager/file_manager/foreground/js/quick_view_uma.ts index b760f98..e913ba0 100644 --- a/ui/file_manager/file_manager/foreground/js/quick_view_uma.ts +++ b/ui/file_manager/file_manager/foreground/js/quick_view_uma.ts
@@ -2,10 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import {DialogType} from '../../common/js/dialog_type.js'; import {FileType} from '../../common/js/file_type.js'; import {recordEnum} from '../../common/js/metrics.js'; import {VolumeManagerCommon} from '../../common/js/volume_manager_types.js'; +import {DialogType} from '../../externs/ts/state.js'; import {VolumeManager} from '../../externs/volume_manager.js'; import {UMA_INDEX_KNOWN_EXTENSIONS} from './uma_enums.gen.js';
diff --git a/ui/file_manager/file_manager/foreground/js/toolbar_controller.js b/ui/file_manager/file_manager/foreground/js/toolbar_controller.ts similarity index 65% rename from ui/file_manager/file_manager/foreground/js/toolbar_controller.js rename to ui/file_manager/file_manager/foreground/js/toolbar_controller.ts index dcc795a8..d376457b 100644 --- a/ui/file_manager/file_manager/foreground/js/toolbar_controller.js +++ b/ui/file_manager/file_manager/foreground/js/toolbar_controller.ts
@@ -2,16 +2,19 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import {assert, assertInstanceof} from 'chrome://resources/ash/common/assert.js'; +import {assertInstanceof} from 'chrome://resources/js/assert.js'; +import type {Switch} from 'chrome://resources/cros_components/switch/switch.js'; +import type {CrToggleElement} from 'chrome://resources/cr_elements/cr_toggle/cr_toggle.js'; -import {queryRequiredElement, queryRequiredExactlyOne} from '../../common/js/dom_utils.js'; + +import {queryRequiredElement} from '../../common/js/dom_utils.js'; import {isNonModifiable} from '../../common/js/entry_utils.js'; import {isCrosComponentsEnabled} from '../../common/js/flags.js'; import {str, strf} from '../../common/js/translations.js'; import {canBulkPinningCloudPanelShow} from '../../common/js/util.js'; import {VolumeManagerCommon} from '../../common/js/volume_manager_types.js'; +import {DirectoryChangeEvent} from '../../externs/directory_change_event.js'; import {State} from '../../externs/ts/state.js'; -// @ts-ignore: error TS6133: 'Store' is declared but its value is never read. import {Store} from '../../externs/ts/store.js'; import {VolumeManager} from '../../externs/volume_manager.js'; import {getStore} from '../../state/store.js'; @@ -25,248 +28,95 @@ import {FileListSelectionModel} from './ui/file_list_selection_model.js'; import {ListContainer} from './ui/list_container.js'; +// Helper function that extract common pattern for getting commands associated +// with the toolbar and also deals with lack of return type information in +// assertInstaneof function. +function getCommand(selector: string, body: HTMLBodyElement): Command { + const element = queryRequiredElement(selector, body); + assertInstanceof(element, Command); + return element as Command; +} + /** * This class controls wires toolbar UI and selection model. When selection * status is changed, this class changes the view of toolbar. If cancel * selection button is pressed, this class clears the selection. */ export class ToolbarController { - /** - * @param {!HTMLElement} toolbar Toolbar element which contains controls. - * @param {!HTMLElement} navigationList Navigation list on the left pane. The - * position of silesSelectedLabel depends on the navitaion list's width. - * @param {!ListContainer} listContainer List container. - * @param {!FileSelectionHandler} selectionHandler - * @param {!DirectoryModel} directoryModel - * @param {!VolumeManager} volumeManager - * @param {!A11yAnnounce} a11y - */ - constructor( - toolbar, navigationList, listContainer, selectionHandler, directoryModel, - volumeManager, a11y) { - /** - * @private @type {!HTMLElement} - * @const - */ - this.toolbar_ = toolbar; + // HTML Elements + private readonly cancelSelectionButton_: HTMLElement; + private readonly filesSelectedLabel_: HTMLElement; + private readonly deleteButton_: HTMLElement; + private readonly moveToTrashButton_: HTMLElement; + private readonly restoreFromTrashButton_: HTMLElement; + private readonly sharesheetButton_: HTMLElement; + private readonly readOnlyIndicator_: HTMLElement; + private readonly pinnedToggleWrapper_: HTMLElement; + private readonly pinnedToggle_: CrToggleElement|null; + private readonly pinnedToggleJelly_: Switch|null; + private readonly cloudButton_: HTMLElement; + private readonly cloudStatusIcon_: HTMLElement; + private readonly cloudButtonIcon_: HTMLElement; + // Commands + private readonly deleteCommand_: Command; + private readonly moveToTrashCommand: Command; + private readonly restoreFromTrashCommand_: Command; + private readonly refreshCommand_: Command; + private readonly newFolderCommand_: Command; + private readonly invokeSharesheetCommand_: Command; + private readonly togglePinnedCommand_: Command; + // Other + private bulkPinningEnabled_: boolean; + private store_: Store; - /** - * @private @type {!HTMLElement} - * @const - */ + constructor( + private toolbar_: HTMLElement, _navigationList: HTMLElement, + private listContainer_: ListContainer, + private selectionHandler_: FileSelectionHandler, + private directoryModel_: DirectoryModel, + private volumeManager_: VolumeManager, + private a11y_: A11yAnnounce) { + // HTML elements. this.cancelSelectionButton_ = queryRequiredElement('#cancel-selection-button', this.toolbar_); - - /** - * @private @type {!HTMLElement} - * @const - */ - this.cancelSelectionButtonWrapper_ = - queryRequiredElement('#cancel-selection-button-wrapper', this.toolbar_); - - /** - * @private @type {!HTMLElement} - * @const - */ this.filesSelectedLabel_ = queryRequiredElement('#files-selected-label', this.toolbar_); - - /** - * @private @type {!HTMLElement} - * @const - */ this.deleteButton_ = queryRequiredElement('#delete-button', this.toolbar_); - - /** - * @private @type {!HTMLElement} - * @const - */ this.moveToTrashButton_ = queryRequiredElement('#move-to-trash-button', this.toolbar_); - - /** - * @private @type {!HTMLElement} - * @const - */ this.restoreFromTrashButton_ = queryRequiredElement('#restore-from-trash-button', this.toolbar_); - - /** - * @private @type {!HTMLElement} - * @const - */ this.sharesheetButton_ = queryRequiredElement('#sharesheet-button', this.toolbar_); - - /** - * @private @type {!HTMLElement} - * @const - */ this.readOnlyIndicator_ = queryRequiredElement('#read-only-indicator', this.toolbar_); - - /** - * @private @type {!HTMLElement} - * @const - */ this.pinnedToggleWrapper_ = queryRequiredElement('#pinned-toggle-wrapper', this.toolbar_); - - /** - * @private @type {HTMLElement} - * @const - */ - // @ts-ignore: error TS2339: Property 'pinnedToggle_' does not exist on type - // 'ToolbarController'. - this.pinnedToggle_; - - /** - * @private @type {HTMLElement} - * @const - */ - // @ts-ignore: error TS2339: Property 'pinnedToggleJelly_' does not exist on - // type 'ToolbarController'. - this.pinnedToggleJelly_; - - // @ts-ignore: error TS2339: Property 'pinnedToggleJelly_' does not exist on - // type 'ToolbarController'. - [this.pinnedToggle_, this.pinnedToggleJelly_] = queryRequiredExactlyOne( - ['#pinned-toggle', '#pinned-toggle-jelly'], this.toolbar_); - - /** - * @private @type {!HTMLElement} - * @const - */ + if (isCrosComponentsEnabled()) { + this.pinnedToggle_ = null; + this.pinnedToggleJelly_ = queryRequiredElement('#pinned-toggle-jelly', this.toolbar_) as Switch; + } else { + this.pinnedToggle_ = queryRequiredElement('#pinned-toggle', this.toolbar_) as CrToggleElement; + this.pinnedToggleJelly_ = null; + } this.cloudButton_ = queryRequiredElement('#cloud-button', this.toolbar_); - - /** - * @private @type {!HTMLElement} - * @const - */ this.cloudStatusIcon_ = queryRequiredElement( '#cloud-button > xf-icon[slot="suffix-icon"]', this.toolbar_); - - /** - * @private @type {!HTMLElement} - * @const - */ this.cloudButtonIcon_ = queryRequiredElement( '#cloud-button > xf-icon[slot="prefix-icon"]', this.toolbar_); - /** - * @private @type {!Command} - * @const - */ - this.deleteCommand_ = assertInstanceof( - queryRequiredElement( - '#delete', assert(this.toolbar_.ownerDocument.body)), - Command); + // Commands. + const body = this.toolbar_.ownerDocument.body as HTMLBodyElement; + this.deleteCommand_ = getCommand('command#delete', body); + this.moveToTrashCommand = getCommand('#move-to-trash', body); + this.restoreFromTrashCommand_ = getCommand('#restore-from-trash', body); + this.refreshCommand_ = getCommand('#refresh', body); + this.newFolderCommand_ = getCommand('#new-folder', body); + this.invokeSharesheetCommand_ = getCommand('#invoke-sharesheet', body); + this.togglePinnedCommand_ = getCommand('#toggle-pinned', body); - /** - * @type {!Command} - * @const - */ - this.moveToTrashCommand = assertInstanceof( - queryRequiredElement( - '#move-to-trash', assert(this.toolbar_.ownerDocument.body)), - Command); - - /** - * @private @type {!Command} - * @const - */ - this.restoreFromTrashCommand_ = assertInstanceof( - queryRequiredElement( - '#restore-from-trash', assert(this.toolbar_.ownerDocument.body)), - Command); - - /** - * @private @type {!Command} - * @const - */ - this.emptyTrashCommand_ = assertInstanceof( - queryRequiredElement( - '#empty-trash', assert(this.toolbar_.ownerDocument.body)), - Command); - - /** - * @private @type {!Command} - * @const - */ - this.refreshCommand_ = assertInstanceof( - queryRequiredElement( - '#refresh', assert(this.toolbar_.ownerDocument.body)), - Command); - - /** - * @private @type {!Command} - * @const - */ - this.newFolderCommand_ = assertInstanceof( - queryRequiredElement( - '#new-folder', assert(this.toolbar_.ownerDocument.body)), - Command); - - /** - * @private @type {!Command} - * @const - */ - this.invokeSharesheetCommand_ = assertInstanceof( - queryRequiredElement( - '#invoke-sharesheet', assert(this.toolbar_.ownerDocument.body)), - Command); - - /** - * @private @type {!Command} - * @const - */ - this.togglePinnedCommand_ = assertInstanceof( - queryRequiredElement( - '#toggle-pinned', assert(this.toolbar_.ownerDocument.body)), - Command); - - /** - * @private @type {!HTMLElement} - * @const - */ - this.navigationList_ = navigationList; - - /** - * @private @type {!ListContainer} - * @const - */ - this.listContainer_ = listContainer; - - /** - * @private @type {!FileSelectionHandler} - * @const - */ - this.selectionHandler_ = selectionHandler; - - /** - * @private @type {!DirectoryModel} - * @const - */ - this.directoryModel_ = directoryModel; - - /** - * @private @type {!VolumeManager} - * @const - */ - this.volumeManager_ = volumeManager; - - /** - * @private @type {!A11yAnnounce} - * @const - */ - this.a11y_ = a11y; - - /** @private @type {boolean} */ this.bulkPinningEnabled_ = false; - /** - * @private @type {!Store} - */ this.store_ = getStore(); this.store_.subscribe(this); @@ -299,12 +149,10 @@ this.sharesheetButton_.addEventListener( 'click', this.onSharesheetButtonClicked_.bind(this)); - const cloudPanel = queryRequiredElement('xf-cloud-panel'); + const cloudPanel = queryRequiredElement('xf-cloud-panel') as XfCloudPanel; this.cloudButton_.addEventListener('click', () => { this.cloudButton_.toggleAttribute('menu-shown', true); this.cloudButton_.toggleAttribute('aria-expanded', true); - // @ts-ignore: error TS2339: Property 'showAt' does not exist on type - // 'HTMLElement'. cloudPanel.showAt(this.cloudButton_); }); cloudPanel.addEventListener(XfCloudPanel.events.PANEL_CLOSED, () => { @@ -327,10 +175,8 @@ this.togglePinnedCommand_.addEventListener( 'hiddenChange', this.updatePinnedToggle_.bind(this)); - // @ts-ignore: error TS2339: Property 'pinnedToggle_' does not exist on type - // 'ToolbarController'. - (this.pinnedToggleJelly_ || this.pinnedToggle_) - .addEventListener('change', this.onPinnedToggleChanged_.bind(this)); + (this.pinnedToggleJelly_ || this.pinnedToggle_)!.addEventListener( + 'change', this.onPinnedToggleChanged_.bind(this)); this.directoryModel_.addEventListener( 'directory-changed', this.updateCurrentDirectoryButtons_.bind(this)); @@ -338,10 +184,8 @@ /** * Updates toolbar's UI elements which are related to current directory. - * @private */ - // @ts-ignore: error TS7006: Parameter 'event' implicitly has an 'any' type. - updateCurrentDirectoryButtons_(event) { + private updateCurrentDirectoryButtons_(event: Event) { this.updateRefreshCommand_(); this.newFolderCommand_.canExecuteChange(this.listContainer_.currentList); @@ -361,7 +205,7 @@ locationInfo.rootType !== VolumeManagerCommon.RootType.CROSTINI && locationInfo.rootType !== VolumeManagerCommon.RootType.GUEST_OS); - const newDirectory = event.newDirEntry; + const newDirectory = (event as DirectoryChangeEvent).newDirEntry; if (newDirectory) { const locationInfo = this.volumeManager_.getLocationInfo(newDirectory); const bodyClassList = @@ -375,21 +219,19 @@ } } - /** @private */ - updateRefreshCommand_() { + private updateRefreshCommand_() { this.refreshCommand_.canExecuteChange(this.listContainer_.currentList); } /** * Handles selection's change event to update the UI. - * @private */ - onSelectionChanged_() { + private onSelectionChanged_() { const selection = this.selectionHandler_.selection; this.updateRefreshCommand_(); // Update the label "x files selected." on the header. - let text; + let text: string = ''; if (selection.totalCount === 0) { text = ''; } else if (selection.totalCount === 1) { @@ -407,8 +249,6 @@ text = strf('MANY_ENTRIES_SELECTED', selection.totalCount); } } - // @ts-ignore: error TS2322: Type 'string | undefined' is not assignable to - // type 'string | null'. this.filesSelectedLabel_.textContent = text; // Update visibility of the delete and move to trash buttons. @@ -446,8 +286,9 @@ this.filesSelectedLabel_.ownerDocument.body.classList; bodyClassList.toggle('selecting', selection.totalCount > 0); if (bodyClassList.contains('check-select') != - /** @type {!FileListSelectionModel} */ - (this.directoryModel_.getFileListSelection()).getCheckSelectMode()) { + (this.directoryModel_.getFileListSelection() as + FileListSelectionModel) + .getCheckSelectMode()) { bodyClassList.toggle('check-select'); bodyClassList.toggle('check-select-v1'); } @@ -456,18 +297,16 @@ /** * Handles click event for cancel button to change the selection state. - * @private */ - onCancelSelectionButtonClicked_() { + private onCancelSelectionButtonClicked_() { this.directoryModel_.selectEntries([]); this.a11y_.speakA11yMessage(str('SELECTION_CANCELLATION')); } /** * Handles click event for delete button to execute the delete command. - * @private */ - onDeleteButtonClicked_() { + private onDeleteButtonClicked_() { this.deleteCommand_.canExecuteChange(this.listContainer_.currentList); this.deleteCommand_.execute(this.listContainer_.currentList); } @@ -475,9 +314,8 @@ /** * Handles click event for move to trash button to execute the move to trash * command. - * @private */ - onMoveToTrashButtonClicked_() { + private onMoveToTrashButtonClicked_() { this.moveToTrashCommand.canExecuteChange(this.listContainer_.currentList); this.moveToTrashCommand.execute(this.listContainer_.currentList); } @@ -485,9 +323,8 @@ /** * Handles click event for restore from trash button to execute the restore * command. - * @private */ - onRestoreFromTrashButtonClicked_() { + private onRestoreFromTrashButtonClicked_() { this.restoreFromTrashCommand_.canExecuteChange( this.listContainer_.currentList); this.restoreFromTrashCommand_.execute(this.listContainer_.currentList); @@ -495,59 +332,41 @@ /** * Handles click event for sharesheet button to set button background color. - * @private */ - onSharesheetButtonClicked_() { + private onSharesheetButtonClicked_() { this.sharesheetButton_.setAttribute('menu-shown', ''); - // @ts-ignore: error TS6133: 'e' is declared but its value is never read. - this.toolbar_.ownerDocument.body.addEventListener('focusin', (e) => { + this.toolbar_.ownerDocument.body.addEventListener('focusin', () => { this.sharesheetButton_.removeAttribute('menu-shown'); }, {once: true}); } - /** @private */ - updateSharesheetCommand_() { + private updateSharesheetCommand_() { this.invokeSharesheetCommand_.canExecuteChange( this.listContainer_.currentList); } - /** @private */ - updatePinnedToggle_() { + private updatePinnedToggle_() { this.pinnedToggleWrapper_.hidden = this.togglePinnedCommand_.hidden; if (isCrosComponentsEnabled()) { - // @ts-ignore: error TS2339: Property 'pinnedToggleJelly_' does not exist - // on type 'ToolbarController'. - this.pinnedToggleJelly_.selected = this.togglePinnedCommand_.checked; - // @ts-ignore: error TS2339: Property 'pinnedToggleJelly_' does not exist - // on type 'ToolbarController'. - this.pinnedToggleJelly_.disabled = this.togglePinnedCommand_.disabled; + this.pinnedToggleJelly_!.selected = this.togglePinnedCommand_.checked; + this.pinnedToggleJelly_!.disabled = this.togglePinnedCommand_.disabled; } else { - // @ts-ignore: error TS2339: Property 'pinnedToggle_' does not exist on - // type 'ToolbarController'. - this.pinnedToggle_.checked = this.togglePinnedCommand_.checked; - // @ts-ignore: error TS2339: Property 'pinnedToggle_' does not exist on - // type 'ToolbarController'. - this.pinnedToggle_.disabled = this.togglePinnedCommand_.disabled; + this.pinnedToggle_!.checked = this.togglePinnedCommand_.checked; + this.pinnedToggle_!.disabled = this.togglePinnedCommand_.disabled; } } - /** @private */ - onPinnedToggleChanged_() { + private onPinnedToggleChanged_() { this.togglePinnedCommand_.execute(this.listContainer_.currentList); // Optimistally update the command's properties so we get notified if they // change back. this.togglePinnedCommand_.checked = isCrosComponentsEnabled() ? - // @ts-ignore: error TS2339: Property 'pinnedToggleJelly_' does not - // exist on type 'ToolbarController'. - this.pinnedToggleJelly_.selected : - // @ts-ignore: error TS2339: Property 'pinnedToggle_' does not exist on - // type 'ToolbarController'. - this.pinnedToggle_.checked; + this.pinnedToggleJelly_!.selected : + this.pinnedToggle_!.checked; } - /** @private */ - updateMoveToTrashCommand_() { + private updateMoveToTrashCommand_() { if (!this.deleteButton_.hidden) { this.deleteButton_.hidden = !this.moveToTrashCommand.disabled; this.moveToTrashButton_.hidden = this.moveToTrashCommand.disabled; @@ -557,19 +376,16 @@ /** * Checks if the cloud icon should be showing or not based on the enablement * of the user preferences, the feature flag and the existing stage. - * @param {!State} state latest state from the store. */ - onStateChanged(state) { + onStateChanged(state: State) { this.updateBulkPinning_(state); } /** * Updates the visibility of the cloud button and the "Available offline" * toggle based on whether the bulk pinning is enabled or not. - * @param {!State} state latest state from the store. - * @private */ - updateBulkPinning_(state) { + private updateBulkPinning_(state: State) { const enabled = !!state.preferences?.driveFsBulkPinningEnabled; const bulkPinning = state.bulkPinning; const isNetworkMetered = state.drive?.connectionType === @@ -594,10 +410,10 @@ /** * Encapsulates the logic to update the bulk pinning cloud icon and the sub * icons that indicate the current stage it is in. - * @param {chrome.fileManagerPrivate.BulkPinProgress|undefined} progress - * @param {boolean} isNetworkMetered */ - updateBulkPinningIcon_(progress, isNetworkMetered) { + private updateBulkPinningIcon_( + progress: chrome.fileManagerPrivate.BulkPinProgress|undefined, + isNetworkMetered: boolean) { if (isNetworkMetered) { this.cloudButton_.ariaLabel = str('BULK_PINNING_BUTTON_LABEL_PAUSED'); this.cloudButtonIcon_.setAttribute('type', constants.ICON_TYPES.CLOUD);
diff --git a/ui/file_manager/file_manager/foreground/js/ui/banners/dlp_restricted_banner.ts b/ui/file_manager/file_manager/foreground/js/ui/banners/dlp_restricted_banner.ts index 85556e0..34edbd54 100644 --- a/ui/file_manager/file_manager/foreground/js/ui/banners/dlp_restricted_banner.ts +++ b/ui/file_manager/file_manager/foreground/js/ui/banners/dlp_restricted_banner.ts
@@ -8,9 +8,9 @@ * @suppress {checkTypes} */ -import {DialogType} from '../../../../common/js/dialog_type.js'; import {str} from '../../../../common/js/translations.js'; import {VolumeManagerCommon} from '../../../../common/js/volume_manager_types.js'; +import {DialogType} from '../../../../externs/ts/state.js'; import {getTemplate} from './dlp_restricted_banner.html.js'; import {StateBanner} from './state_banner.js';
diff --git a/ui/file_manager/file_manager/foreground/js/ui/dialog_footer.js b/ui/file_manager/file_manager/foreground/js/ui/dialog_footer.js index f7d0440a..0964670b 100644 --- a/ui/file_manager/file_manager/foreground/js/ui/dialog_footer.js +++ b/ui/file_manager/file_manager/foreground/js/ui/dialog_footer.js
@@ -4,10 +4,10 @@ import 'chrome://resources/cr_elements/cr_input/cr_input.js'; -import {DialogType} from '../../../common/js/dialog_type.js'; import {getKeyModifiers, queryRequiredElement} from '../../../common/js/dom_utils.js'; import {getFileTypeForName} from '../../../common/js/file_types_base.js'; import {str} from '../../../common/js/translations.js'; +import {DialogType} from '../../../externs/ts/state.js'; import {FileListModel} from '../file_list_model.js'; /**
diff --git a/ui/file_manager/file_manager/foreground/js/ui/directory_tree_unittest.js b/ui/file_manager/file_manager/foreground/js/ui/directory_tree_unittest.js index 0864fac..91a74660 100644 --- a/ui/file_manager/file_manager/foreground/js/ui/directory_tree_unittest.js +++ b/ui/file_manager/file_manager/foreground/js/ui/directory_tree_unittest.js
@@ -7,13 +7,13 @@ import {assertArrayEquals, assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chromeos/chai_assert.js'; import {MockVolumeManager} from '../../../background/js/mock_volume_manager.js'; -import {DialogType} from '../../../common/js/dialog_type.js'; import {EntryList} from '../../../common/js/files_app_entry_types.js'; import {installMockChrome, MockCommandLinePrivate} from '../../../common/js/mock_chrome.js'; import {MockDirectoryEntry} from '../../../common/js/mock_entry.js'; import {reportPromise, waitUntil} from '../../../common/js/test_error_reporting.js'; import {str} from '../../../common/js/translations.js'; import {VolumeManagerCommon} from '../../../common/js/volume_manager_types.js'; +import {DialogType} from '../../../externs/ts/state.js'; import {DirectoryModel} from '../directory_model.js'; import {createFakeAndroidAppListModel} from '../fake_android_app_list_model.js'; import {MetadataModel} from '../metadata/metadata_model.js';
diff --git a/ui/file_manager/file_manager/foreground/js/ui/file_manager_ui.js b/ui/file_manager/file_manager/foreground/js/ui/file_manager_ui.js index 5541daa6..6a194ab 100644 --- a/ui/file_manager/file_manager/foreground/js/ui/file_manager_ui.js +++ b/ui/file_manager/file_manager/foreground/js/ui/file_manager_ui.js
@@ -6,7 +6,6 @@ import {assertInstanceof} from 'chrome://resources/ash/common/assert.js'; -import {DialogType} from '../../../common/js/dialog_type.js'; import {queryDecoratedElement, queryRequiredElement} from '../../../common/js/dom_utils.js'; import {isDlpEnabled, isNewDirectoryTreeEnabled} from '../../../common/js/flags.js'; import {str, strf} from '../../../common/js/translations.js'; @@ -17,6 +16,7 @@ import {DirectoryTreeContainer} from '../../../containers/directory_tree_container.js'; import {NudgeContainer} from '../../../containers/nudge_container.js'; import {SearchContainer} from '../../../containers/search_container.js'; +import {DialogType} from '../../../externs/ts/state.js'; import {VolumeManager} from '../../../externs/volume_manager.js'; import {XfConflictDialog} from '../../../widgets/xf_conflict_dialog.js'; import {XfDlpRestrictionDetailsDialog} from '../../../widgets/xf_dlp_restriction_details_dialog.js';
diff --git a/ui/file_manager/file_manager/foreground/js/ui/list_container.ts b/ui/file_manager/file_manager/foreground/js/ui/list_container.ts index f0561e9..6ba04c5 100644 --- a/ui/file_manager/file_manager/foreground/js/ui/list_container.ts +++ b/ui/file_manager/file_manager/foreground/js/ui/list_container.ts
@@ -5,8 +5,8 @@ import {dispatchSimpleEvent} from 'chrome://resources/ash/common/cr_deprecated.js'; import {assert, assertInstanceof, assertNotReached} from 'chrome://resources/js/assert.js'; -import {DialogType} from '../../../common/js/dialog_type.js'; import {queryRequiredElement} from '../../../common/js/dom_utils.js'; +import {DialogType} from '../../../externs/ts/state.js'; import {FileListModel, GROUP_BY_FIELD_DIRECTORY, GROUP_BY_FIELD_MODIFICATION_TIME} from '../file_list_model.js'; import {ListThumbnailLoader} from '../list_thumbnail_loader.js';
diff --git a/ui/file_manager/file_manager/state/ducks/all_entries.ts b/ui/file_manager/file_manager/state/ducks/all_entries.ts index 624635f8..3f3d397 100644 --- a/ui/file_manager/file_manager/state/ducks/all_entries.ts +++ b/ui/file_manager/file_manager/state/ducks/all_entries.ts
@@ -3,7 +3,6 @@ // found in the LICENSE file. import {getParentEntry} from '../../common/js/api.js'; -import {DialogType} from '../../common/js/dialog_type.js'; import {isDriveRootEntryList, isEntryInsideDrive, isFakeEntryInDrives, isGrandRootEntryInDrives, isVolumeEntry, shouldSupportDriveSpecificIcons, sortEntries} from '../../common/js/entry_utils.js'; import {FileType} from '../../common/js/file_type.js'; import {EntryList, VolumeEntry} from '../../common/js/files_app_entry_types.js'; @@ -13,16 +12,18 @@ import {VolumeManagerCommon} from '../../common/js/volume_manager_types.js'; import {EntryLocation} from '../../externs/entry_location.js'; import {FilesAppDirEntry, FilesAppEntry} from '../../externs/files_app_entry_interfaces.js'; -import {CurrentDirectory, EntryType, FileData, State, Volume, VolumeMap} from '../../externs/ts/state.js'; +import {CurrentDirectory, DialogType, EntryType, FileData, State, Volume, VolumeMap} from '../../externs/ts/state.js'; import type {VolumeInfo} from '../../externs/volume_info.js'; import {constants} from '../../foreground/js/constants.js'; import {MetadataItem} from '../../foreground/js/metadata/metadata_item.js'; import type {ActionsProducerGen} from '../../lib/actions_producer.js'; import {Slice} from '../../lib/base_store.js'; +import {keepLatest} from '../../lib/concurrency_models.js'; import type {FileKey} from '../file_key.js'; -import {getEntry, getFileData, getStore} from '../store.js'; +import {getEntry, getFileData, getStore, getVolume} from '../store.js'; import {hasDlpDisabledFiles} from './current_directory.js'; +import {updateNavigationEntry} from './navigation.js'; import {driveRootEntryListKey, myFilesEntryListKey, recentRootKey} from './volumes.js'; /** @@ -570,7 +571,7 @@ if (fileData?.expanded) { for (const childEntry of childEntriesToReadDeeper) { for await (const action of readSubDirectories( - childEntry, /* recursive */ true)) { + childEntry, /* recursive= */ true)) { yield action; } } @@ -679,3 +680,85 @@ yield action; } } + +/** + * Traverse each entry in the `pathEntryKeys`: if the entry doesn't exist in the + * store, read sub directories for its parent. After all entries exist in the + * store, expand all parent entries. + * + * @param pathEntryKeys An array of FileKey starts from ancestor to child, e.g. + * [A, B, C] A is the parent entry of B, B is the parent entry of C. + */ +export async function* + traverseAndExpandPathEntriesInternal(pathEntryKeys: FileKey[]): + ActionsProducerGen { + if (pathEntryKeys.length === 0) { + return; + } + const childEntryKey = pathEntryKeys[pathEntryKeys.length - 1]!; + const state = getStore().getState(); + const childEntryFileData = getFileData(state, childEntryKey); + if (!childEntryFileData) { + console.warn(`Can not find the child entry: ${childEntryKey}`); + return; + } + const volume = getVolume(state, childEntryFileData); + if (!volume) { + console.warn( + `Can not find the volume root for the child entry: ${childEntryKey}`); + return; + } + const volumeEntry = getEntry(state, volume.rootKey!); + if (!volumeEntry) { + console.warn(`Can not find the volume root entry: ${volume.rootKey}`); + return; + } + + for (let i = 1; i < pathEntryKeys.length; i++) { + // We need to getStore() for each loop because the below `yield action` will + // add new entries to the store. + const state = getStore().getState(); + const currentEntryKey = pathEntryKeys[i]!; + const parentEntryKey = pathEntryKeys[i - 1]!; + const parentEntry = getEntry(state, parentEntryKey)!; + const parentFileData = getFileData(state, parentEntryKey)!; + const fileData = getFileData(state, currentEntryKey); + // Read sub directories if the child entry doesn't exist or it's not in + // parent entry's children. + if (!fileData || !parentFileData.children.includes(currentEntryKey)) { + let foundCurrentEntry = false; + for await (const action of readSubDirectories(parentEntry)) { + yield action; + const childEntries: Array<Entry|FilesAppEntry> = + action?.payload.entries || []; + foundCurrentEntry = + !!childEntries.find(entry => entry.toURL() === currentEntryKey); + if (foundCurrentEntry) { + break; + } + } + if (!foundCurrentEntry) { + console.warn(`Failed to find entry "${ + currentEntryKey}" from its parent "${parentEntryKey}"`); + return; + } + } + } + // Now all entries on `pathEntryKeys` are found, we can expand all of them + // now. Note: if any entry on the path can't be found, we don't expand + // anything because we don't want to expand half-way, e.g. if `pathEntryKeys = + // [entryA, entryB, entryC]` but somehow entryB doesn't exist, we don't want + // to expand `entryA`. + for (let i = 0; i < pathEntryKeys.length - 1; i++) { + yield updateNavigationEntry({key: pathEntryKeys[i]!, expanded: true}); + } +} + +/** + * `traverseAndExpandPathEntries` is mainly used to traverse and expand the + * `pathComponent` for current directory, if concurrent requests happen (e.g. + * current directory changes too quickly while we are still resolving the + * previous one), we just ditch the previous request and only keep the latest. + */ +export const traverseAndExpandPathEntries = + keepLatest(traverseAndExpandPathEntriesInternal);
diff --git a/ui/file_manager/file_manager/state/ducks/all_entries_unittest.ts b/ui/file_manager/file_manager/state/ducks/all_entries_unittest.ts index 32f4ddb0..dd6170a 100644 --- a/ui/file_manager/file_manager/state/ducks/all_entries_unittest.ts +++ b/ui/file_manager/file_manager/state/ducks/all_entries_unittest.ts
@@ -15,7 +15,7 @@ import {constants} from '../../foreground/js/constants.js'; import {MetadataItem} from '../../foreground/js/metadata/metadata_item.js'; import {MockMetadataModel} from '../../foreground/js/metadata/mock_metadata.js'; -import {addChildEntries} from '../ducks/all_entries.js'; +import {addChildEntries, traverseAndExpandPathEntriesInternal} from '../ducks/all_entries.js'; import {allEntriesSize, assertAllEntriesEqual, cd, changeSelection, createFakeVolumeMetadata, setUpFileManagerOnWindow, setupStore, updMetadata, waitDeepEquals} from '../for_tests.js'; import {getEmptyState, type Store} from '../store.js'; @@ -37,13 +37,15 @@ .getCurrentProfileVolumeInfo( VolumeManagerCommon.VolumeType.DOWNLOADS)!.fileSystem as MockFileSystem; - fileSystem.populate([ - '/dir-1/', - '/dir-2/sub-dir/', - '/dir-2/file-1.txt', - '/dir-2/file-2.txt', - '/dir-3/', - ]); + fileSystem.populate( + [ + '/dir-1/', + '/dir-2/sub-dir/', + '/dir-2/file-1.txt', + '/dir-2/file-2.txt', + '/dir-3/', + ], + /* opt_clear= */ true); } /** Generate MyFiles entry with fake entry list. */ @@ -269,12 +271,14 @@ const initialState = getEmptyState(); // Add parent/children entries to the store. - fileSystem.populate([ - '/a/', - '/a/1/', - '/a/2/', - '/a/2/b/', - ]); + fileSystem.populate( + [ + '/a/', + '/a/1/', + '/a/2/', + '/a/2/b/', + ], + /* opt_clear= */ true); const aEntry = fileSystem.entries['/a']!; initialState.allEntries[aEntry.toURL()] = convertEntryToFileData(aEntry); // Make sure aEntry won't be cleared. @@ -521,12 +525,14 @@ const downloadsVolumeInfo = volumeManager.getCurrentProfileVolumeInfo( VolumeManagerCommon.VolumeType.DOWNLOADS)!; const fakeFs = downloadsVolumeInfo.fileSystem as MockFileSystem; - fakeFs.populate([ - '/Downloads/', - '/Downloads/c/', - '/Downloads/b.txt', - '/Downloads/a/', - ]); + fakeFs.populate( + [ + '/Downloads/', + '/Downloads/c/', + '/Downloads/b.txt', + '/Downloads/a/', + ], + /* opt_clear= */ true); const downloadsEntry = fakeFs.entries['/Downloads']!; // The entry to be read should be in the store before reading. const downloadsEntryFileData = convertEntryToFileData(downloadsEntry); @@ -565,13 +571,15 @@ const downloadsVolumeInfo = volumeManager.getCurrentProfileVolumeInfo( VolumeManagerCommon.VolumeType.DOWNLOADS)!; const fakeFs = downloadsVolumeInfo.fileSystem as MockFileSystem; - fakeFs.populate([ - '/Downloads/', - '/Downloads/a/', - '/Downloads/b/', - '/Downloads/a/111/', - '/Downloads/b/222/', - ]); + fakeFs.populate( + [ + '/Downloads/', + '/Downloads/a/', + '/Downloads/b/', + '/Downloads/a/111/', + '/Downloads/b/222/', + ], + /* opt_clear= */ true); const downloadsEntry = fakeFs.entries['/Downloads']!; const bDirEntry = fakeFs.entries['/Downloads/b']!; // The entry to be read should be in the store before reading. @@ -624,9 +632,11 @@ // Populate a fake file entry in the file system. const fakeFs = new MockFileSystem('fake-fs'); - fakeFs.populate([ - '/a.txt', - ]); + fakeFs.populate( + [ + '/a.txt', + ], + /* opt_clear= */ true); // Check reading non directory entry will do nothing. store.dispatch(readSubDirectories(fakeFs.entries['/a.txt']!)); @@ -685,11 +695,13 @@ driveRootEntryList.addEntry(sharedWithMeEntry); driveRootEntryList.addEntry(offlineEntry); // Add child entries. - driveFs.populate([ - '/root/a/', - '/root/b.txt', - '/Computers/c.txt', - ]); + driveFs.populate( + [ + '/root/a/', + '/root/b.txt', + '/Computers/c.txt', + ], + /* opt_clear= */ true); // Drive root entry list needs to be in the store before reading. const fakeDriveEntryFileData = convertEntryToFileData(driveRootEntryList); initialState.allEntries[driveRootEntryList.toURL()] = fakeDriveEntryFileData; @@ -722,3 +734,145 @@ done(); } + +/** + * Tests that traverse path entries will read entries for each parent and + * expand them if the child entry could be found. + */ +export async function testTraverseAndExpandPathEntriesFound( + done: VoidCallback) { + const initialState = getEmptyState(); + const {volumeManager} = window.fileManager; + // Populate some fake entries. + const downloadsVolumeInfo = volumeManager.getCurrentProfileVolumeInfo( + VolumeManagerCommon.VolumeType.DOWNLOADS)!; + const fakeFs = downloadsVolumeInfo.fileSystem as MockFileSystem; + fakeFs.populate( + [ + '/a/', + '/a/b/', + '/a/b/c/', + ], + /* opt_clear= */ true); + const volumeRootEntry = fakeFs.entries['/']!; + const dirA = fakeFs.entries['/a']!; + const dirB = fakeFs.entries['/a/b']!; + const dirC = fakeFs.entries['/a/b/c']!; + + // Put the volume root and the last child entry in the store. + const volumeRootEntryFileData = convertEntryToFileData(volumeRootEntry); + initialState.allEntries[volumeRootEntry.toURL()] = volumeRootEntryFileData; + initialState.volumes[downloadsVolumeInfo.volumeId] = + convertVolumeInfoAndMetadataToVolume( + downloadsVolumeInfo, createFakeVolumeMetadata(downloadsVolumeInfo)); + const dirCEntryFileData = convertEntryToFileData(dirC); + initialState.allEntries[dirC.toURL()] = dirCEntryFileData; + + const store = setupStore(initialState); + + // Dispatch action producer to traverse on the entry path. + store.dispatch(traverseAndExpandPathEntriesInternal([ + volumeRootEntry.toURL(), + dirA.toURL(), + dirB.toURL(), + dirC.toURL(), + ])); + + // Expect dirA and dirB will be in the store and expanded. + const want: State['allEntries'] = { + [volumeRootEntry.toURL()]: { + ...volumeRootEntryFileData, + expanded: true, + children: [dirA.toURL()], + }, + [dirA.toURL()]: { + ...convertEntryToFileData(dirA), + expanded: true, + children: [dirB.toURL()], + }, + [dirB.toURL()]: { + ...convertEntryToFileData(dirB), + expanded: true, + children: [dirC.toURL()], + }, + [dirC.toURL()]: { + ...convertEntryToFileData(dirC), + expanded: false, + children: [], + }, + }; + + await waitDeepEquals(store, want, (state) => state.allEntries); + + done(); +} + +/** + * Tests that traverse path entries will read entries for each parent, it + * won't expand any parent entry if the child entry can not be found. + */ +export async function testTraverseAndExpandPathEntriesNotFound( + done: VoidCallback) { + const initialState = getEmptyState(); + const {volumeManager} = window.fileManager; + // Populate some fake entries. + const downloadsVolumeInfo = volumeManager.getCurrentProfileVolumeInfo( + VolumeManagerCommon.VolumeType.DOWNLOADS)!; + const fakeFs = downloadsVolumeInfo.fileSystem as MockFileSystem; + fakeFs.populate( + [ + '/a/', + '/a/b/', + '/a/b/c/', + ], + /* opt_clear= */ true); + const volumeRootEntry = fakeFs.entries['/']!; + const dirA = fakeFs.entries['/a']!; + const dirB = fakeFs.entries['/a/b']!; + const dirC = fakeFs.entries['/a/b/c']!; + + // Put the volume root and the last child entry in the store. + const volumeRootEntryFileData = convertEntryToFileData(volumeRootEntry); + initialState.allEntries[volumeRootEntry.toURL()] = volumeRootEntryFileData; + initialState.volumes[downloadsVolumeInfo.volumeId] = + convertVolumeInfoAndMetadataToVolume( + downloadsVolumeInfo, createFakeVolumeMetadata(downloadsVolumeInfo)); + const dirCEntryFileData = convertEntryToFileData(dirC); + initialState.allEntries[dirC.toURL()] = dirCEntryFileData; + + const store = setupStore(initialState); + + // Dispatch action producer to traverse on the entry path. + store.dispatch(traverseAndExpandPathEntriesInternal([ + volumeRootEntry.toURL(), + dirA.toURL(), + 'not-exist-url', + dirC.toURL(), + ])); + + // Expect dirA and dirB will be in the store but no entry is expanded. + const want: State['allEntries'] = { + [volumeRootEntry.toURL()]: { + ...volumeRootEntryFileData, + expanded: false, + children: [dirA.toURL()], + }, + [dirA.toURL()]: { + ...convertEntryToFileData(dirA), + expanded: false, + children: [dirB.toURL()], + }, + [dirB.toURL()]: { + ...convertEntryToFileData(dirB), + expanded: false, + // dirB's children is not being read because read stops when non-exist-url + // is encountered. + children: [], + }, + // dirC is cleared because it's not referenced by any other entries. + }; + + await waitDeepEquals(store, want, (state) => state.allEntries); + + done(); +}
diff --git a/ui/file_manager/file_manager/state/ducks/current_directory.ts b/ui/file_manager/file_manager/state/ducks/current_directory.ts index a2b7987..9b092d7 100644 --- a/ui/file_manager/file_manager/state/ducks/current_directory.ts +++ b/ui/file_manager/file_manager/state/ducks/current_directory.ts
@@ -3,13 +3,12 @@ // found in the LICENSE file. import {getFileTasks} from '../../common/js/api.js'; -import {DialogType} from '../../common/js/dialog_type.js'; import {getNativeEntry} from '../../common/js/entry_utils.js'; import {annotateTasks, getDefaultTask, INSTALL_LINUX_PACKAGE_TASK_DESCRIPTOR} from '../../common/js/file_tasks.js'; import {descriptorEqual} from '../../common/js/util.js'; import {VolumeManagerCommon} from '../../common/js/volume_manager_types.js'; import {FakeEntry, FilesAppDirEntry, FilesAppEntry} from '../../externs/files_app_entry_interfaces.js'; -import {CurrentDirectory, DirectoryContent, FileData, FileKey, FileTask, FileTasks, PropStatus, Selection, State} from '../../externs/ts/state.js'; +import {CurrentDirectory, DialogType, DirectoryContent, FileData, FileKey, FileTask, FileTasks, PropStatus, Selection, State} from '../../externs/ts/state.js'; import {constants} from '../../foreground/js/constants.js'; import {PathComponent} from '../../foreground/js/path_component.js'; import type {ActionsProducerGen} from '../../lib/actions_producer.js';
diff --git a/ui/file_manager/file_manager/state/ducks/launch_params_unittest.ts b/ui/file_manager/file_manager/state/ducks/launch_params_unittest.ts index dd460f66..4b17858 100644 --- a/ui/file_manager/file_manager/state/ducks/launch_params_unittest.ts +++ b/ui/file_manager/file_manager/state/ducks/launch_params_unittest.ts
@@ -4,8 +4,7 @@ import {assertDeepEquals} from 'chrome://webui-test/chromeos/chai_assert.js'; -import {DialogType} from '../../common/js/dialog_type.js'; -import {LaunchParams} from '../../externs/ts/state.js'; +import {DialogType, LaunchParams} from '../../externs/ts/state.js'; import {getEmptyState, getStore, type Store} from '../store.js'; import {setLaunchParameters} from './launch_params.js';
diff --git a/ui/file_manager/file_manager/state/ducks/navigation.ts b/ui/file_manager/file_manager/state/ducks/navigation.ts index 574028dd..b8d172f 100644 --- a/ui/file_manager/file_manager/state/ducks/navigation.ts +++ b/ui/file_manager/file_manager/state/ducks/navigation.ts
@@ -2,12 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import {DialogType} from '../../common/js/dialog_type.js'; import {isOneDriveId} from '../../common/js/entry_utils.js'; import {EntryList, VolumeEntry} from '../../common/js/files_app_entry_types.js'; import {VolumeManagerCommon} from '../../common/js/volume_manager_types.js'; import {FilesAppEntry} from '../../externs/files_app_entry_interfaces.js'; -import {AndroidApp, NavigationKey, NavigationRoot, NavigationSection, NavigationType, State, Volume} from '../../externs/ts/state.js'; +import {AndroidApp, DialogType, NavigationKey, NavigationRoot, NavigationSection, NavigationType, State, Volume} from '../../externs/ts/state.js'; import {Slice} from '../../lib/base_store.js'; import {getMyFiles} from '../ducks/all_entries.js'; import {driveRootEntryListKey, recentRootKey, trashRootKey} from '../ducks/volumes.js';
diff --git a/ui/file_manager/file_manager/state/for_tests.ts b/ui/file_manager/file_manager/state/for_tests.ts index e701843..5075d1fe 100644 --- a/ui/file_manager/file_manager/state/for_tests.ts +++ b/ui/file_manager/file_manager/state/for_tests.ts
@@ -5,10 +5,9 @@ import {assertDeepEquals} from 'chrome://webui-test/chromeos/chai_assert.js'; import {MockVolumeManager} from '../background/js/mock_volume_manager.js'; -import {DialogType} from '../common/js/dialog_type.js'; import {Crostini} from '../externs/background/crostini.js'; import {FilesAppDirEntry} from '../externs/files_app_entry_interfaces.js'; -import {FileKey, PropStatus, State} from '../externs/ts/state.js'; +import {DialogType, FileKey, PropStatus, State} from '../externs/ts/state.js'; import type {VolumeInfo} from '../externs/volume_info.js'; import {DirectoryTreeNamingController} from '../foreground/js/directory_tree_naming_controller.js'; import {FakeFileSelectionHandler} from '../foreground/js/fake_file_selection_handler.js';
diff --git a/ui/file_manager/file_names.gni b/ui/file_manager/file_names.gni index 5cde7afc..8890c2be 100644 --- a/ui/file_manager/file_names.gni +++ b/ui/file_manager/file_names.gni
@@ -31,7 +31,6 @@ "file_manager/common/js/filtered_volume_manager.js", "file_manager/common/js/mock_chrome.js", "file_manager/common/js/mock_entry.js", - "file_manager/common/js/notifications.js", "file_manager/common/js/progress_center_common.js", "file_manager/common/js/storage.js", "file_manager/common/js/ui.js", @@ -101,7 +100,6 @@ "file_manager/foreground/js/spinner_controller.js", "file_manager/foreground/js/task_history.js", "file_manager/foreground/js/thumbnail_loader.js", - "file_manager/foreground/js/toolbar_controller.js", # Metadata: "file_manager/foreground/js/metadata/dlp_metadata_provider.js", @@ -334,6 +332,7 @@ "file_manager/foreground/js/quick_view_uma.ts", "file_manager/foreground/js/sort_menu_controller.ts", "file_manager/foreground/js/task_controller.ts", + "file_manager/foreground/js/toolbar_controller.ts", "file_manager/foreground/js/uma_enums.gen.ts", # 3-line header to avoid conflict. @@ -427,6 +426,7 @@ "file_manager/common/js/entry_utils_unittest.ts", "file_manager/common/js/file_types_base_unittest.ts", "file_manager/common/js/lru_cache_unittest.ts", + "file_manager/common/js/recent_date_bucket_unittest.ts", "file_manager/common/js/translations_unittest.ts", "file_manager/common/js/volume_manager_types_unittest.ts", "file_manager/common/js/util_unittest.ts", @@ -605,7 +605,6 @@ "file_manager/common/js/file_type_unittest.js", "file_manager/common/js/files_app_entry_types_unittest.js", "file_manager/common/js/filtered_volume_manager_unittest.js", - "file_manager/common/js/recent_date_bucket_unittest.js", "file_manager/common/js/storage_unittest.js", "file_manager/common/js/test_error_reporting.js", "file_manager/common/js/unittest_util.js",
diff --git a/ui/file_manager/integration_tests/file_manager/directory_tree_context_menu.js b/ui/file_manager/integration_tests/file_manager/directory_tree_context_menu.js index d41227d..683876d 100644 --- a/ui/file_manager/integration_tests/file_manager/directory_tree_context_menu.js +++ b/ui/file_manager/integration_tests/file_manager/directory_tree_context_menu.js
@@ -1611,7 +1611,7 @@ ['#cut', true], ['#copy', true], ['#paste-into-folder', false], - ['#rename', true], + ['#rename', false], ['#delete', false], ['#new-folder', false], ];
diff --git a/ui/file_manager/integration_tests/file_manager/recents.js b/ui/file_manager/integration_tests/file_manager/recents.js index e86f211a..eae8ebe 100644 --- a/ui/file_manager/integration_tests/file_manager/recents.js +++ b/ui/file_manager/integration_tests/file_manager/recents.js
@@ -509,6 +509,8 @@ // Check: The directory should be highlighted in the directory tree. const directoryTree = await DirectoryTreePageObject.create(appId, remoteCall); await directoryTree.waitForSelectedItemByLabel('C'); + // Focus on the tree first before using the ":focus" selector below. + await directoryTree.focusTree(); await directoryTree.waitForFocusedItemByLabel('C'); };