diff --git a/BUILD.gn b/BUILD.gn index 6b729528..6617382 100644 --- a/BUILD.gn +++ b/BUILD.gn
@@ -199,6 +199,7 @@ "//third_party/blink/renderer/platform/wtf:wtf_unittests", "//third_party/libjingle_xmpp:libjingle_xmpp_unittests", "//tools/imagediff", + "//tools/memory:all", "//ui/display:display_unittests", "//ui/gl:gl_unittests", "//ui/latency:latency_unittests", @@ -436,10 +437,6 @@ ] } - if (is_linux || is_chromeos || is_android || is_mac) { - deps += [ "//tools/memory/partition_allocator:all" ] - } - if (is_chromeos_ash) { deps += [ "//ash:ash_unittests", @@ -1031,10 +1028,10 @@ if (use_v4l2_codec || use_vaapi) { data_deps += [ "//components/chromeos_camera:jpeg_encode_accelerator_unittest", - "//media/gpu:video_decode_accelerator_perf_tests", - "//media/gpu:video_decode_accelerator_tests", - "//media/gpu:video_encode_accelerator_perf_tests", - "//media/gpu:video_encode_accelerator_tests", + "//media/gpu/test/:video_decode_accelerator_perf_tests", + "//media/gpu/test/:video_decode_accelerator_tests", + "//media/gpu/test/:video_encode_accelerator_perf_tests", + "//media/gpu/test/:video_encode_accelerator_tests", "//media/gpu/chromeos:image_processor_test", ] if (use_vaapi) {
diff --git a/DEPS b/DEPS index b6b3534..af17a5d9 100644 --- a/DEPS +++ b/DEPS
@@ -304,15 +304,15 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': '89849a32bdd7b8260bea688e9708729818576c16', + 'skia_revision': '528ff00a3637f6fef419b69392c803f8f2a1e778', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. - 'v8_revision': 'fe05deddba8ac73e115a9327728219b609aec6a5', + 'v8_revision': '5f7f064aee9828f22e29abdc45b63e6c9b854298', # 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': 'afc1e5dcc130971988aa012a1d8be5412a7df88f', + 'angle_revision': 'fbb16d64636b352e2a6c68b8dfc8bbd5e5918585', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. @@ -331,7 +331,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Fuchsia sdk # and whatever else without interference from each other. - 'fuchsia_version': 'version:12.20230327.0.1', + 'fuchsia_version': 'version:12.20230327.2.1', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling google-toolbox-for-mac # and whatever else without interference from each other. @@ -375,7 +375,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': '9d41f74af7343a821aa418f8140e204814f92139', + 'catapult_revision': 'e838386fa052bd38ad2f7f46fd04e451ce110324', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling CrossBench # and whatever else without interference from each other. @@ -391,7 +391,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': 'e6e6905f99923a12713b1ee0443fcccf4eaef736', + 'devtools_frontend_revision': 'a09c4de27878ff6f526c3b78f53bf99e6495f1d3', # 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. @@ -495,7 +495,7 @@ # If you change this, also update the libc++ revision in # //buildtools/deps_revisions.gni. - 'libcxx_revision': '79a510511b03dc9a9f378ebe07c18c622b5bf349', + 'libcxx_revision': '26ace673c4b9c7a352fa9db182256bb341b6c44f', # GN CIPD package version. 'gn_version': 'git_revision:41fef642de70ecdcaaa26be96d56a0398f95abd4', @@ -794,7 +794,7 @@ 'src/clank': { 'url': Var('chrome_git') + '/clank/internal/apps.git' + '@' + - 'f6c0952bdff6acffb8d5d143b07be668c236359a', + '3935d163b8c4d7775a19b87a678849992e18f255', 'condition': 'checkout_android and checkout_src_internal', }, @@ -1202,7 +1202,7 @@ # Tools used when building Chrome for Chrome OS. This affects both the Simple # Chrome workflow, as well as the chromeos-chrome ebuild. 'src/third_party/chromite': { - 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'de3428b38fe70dd593c66c0988472f649f948b36', + 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '8b9b1646b44ebf6946de4392abeaf6d7e14c15a0', 'condition': 'checkout_chromeos', }, @@ -1234,13 +1234,13 @@ }, 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'd9717259ee7ecbe8de97b75a264f5edc18224ab2', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '33a8f072364d819b69cfb45958e17aca021150ad', 'src/third_party/devtools-frontend/src': Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'), 'src/third_party/devtools-frontend-internal': { - 'url': Var('chrome_git') + '/devtools/devtools-internal.git' + '@' + '50e5383c45b884a15b380dbb62a86e9a6a2e758a', + 'url': Var('chrome_git') + '/devtools/devtools-internal.git' + '@' + '1edfd44e2837c5219e24e004e31602c19ca6a9c2', 'condition': 'checkout_src_internal', }, @@ -1706,7 +1706,7 @@ }, 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + '084059ccadd42d5cee0c03931d09dd96ed6b7a99', + Var('android_git') + '/platform/external/perfetto.git' + '@' + 'e904de5554bd8af597344c98aefd940a6a7d00fb', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3', @@ -1851,7 +1851,7 @@ 'dep_type': 'cipd', }, - 'src/third_party/vulkan-deps': '{chromium_git}/vulkan-deps@d56f491466de515bec780ad1d70e53e523ab6e65', + 'src/third_party/vulkan-deps': '{chromium_git}/vulkan-deps@2f3f68dfda8b45bb661cf28637c09509917c7a4d', 'src/third_party/vulkan_memory_allocator': Var('chromium_git') + '/external/github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator.git' + '@' + 'ebe84bec02c041d28f902da0214bf442743fc907', @@ -1888,10 +1888,10 @@ Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + 'd1b65aa5a88f6efd900604dfcda840154e9f16e2', 'src/third_party/webgpu-cts/src': - Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '904c74af6fee0530ce33434974aa0df6316fdef1', + Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '7e014d4d99cdacd0c08a711d379fcb7886ed66d2', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + '8e781a1bb17647d249ac233dfd99ba92b3c69fcb', + Var('webrtc_git') + '/src.git' + '@' + '90d5e7d65520656ddec367cd454bffc16d55c423', # Wuffs' canonical repository is at github.com/google/wuffs, but we use # Skia's mirror of Wuffs, the same as in upstream Skia's DEPS file. @@ -1925,7 +1925,7 @@ 'packages': [ { 'package': 'skia/tools/goldctl/linux-amd64', - 'version': 'iQ7zKud-gha6r9hEdwqYWRdOpeAs6gFfDxnviDUt4FQC', + 'version': 'HkmOI1AX5KQdM4e3VR1v5kN_kJWirqdbUeY0lEj93FcC', }, ], 'dep_type': 'cipd', @@ -1935,7 +1935,7 @@ 'packages': [ { 'package': 'skia/tools/goldctl/windows-amd64', - 'version': 'we56UJIWxJJ2GkQ_ne0o3oGAr7FBJa5T5Jr1xguLn-gC', + 'version': 'pUOVquC14y84RkNMzEAPw_7tztey-kvH7KBwGsFViuIC', }, ], 'dep_type': 'cipd', @@ -1946,7 +1946,7 @@ 'packages': [ { 'package': 'skia/tools/goldctl/mac-amd64', - 'version': '9Wfje1bt82IO9pJokAt9lboy59X_Pe-s0b4EpmH7RT4C', + 'version': 'enC5EfEkxcrBLcpjtbBzQmOsnYRzN43BtNoPNzoyjekC', }, ], 'dep_type': 'cipd', @@ -1957,7 +1957,7 @@ 'packages': [ { 'package': 'skia/tools/goldctl/mac-arm64', - 'version': 'zihT2Lk2afg0XzIZozuGcZXWv7RJujaDEi_6q7QL4DgC', + 'version': 'Jh19SHnigVXYxpk7Fp4ZDMF_ZvLpQUie2NMaK5aEISMC', }, ], 'dep_type': 'cipd', @@ -1968,7 +1968,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': Var('chrome_git') + '/chrome/src-internal.git@afe6094e9777a02fa5a5784d4275860cc598de61', + 'url': Var('chrome_git') + '/chrome/src-internal.git@24d159fca4f5a3e4a816bfab61767356a578dfa5', 'condition': 'checkout_src_internal', }, @@ -2016,6 +2016,17 @@ 'dep_type': 'cipd', }, + 'src/ash/webui/personalization_app/resources': { + 'packages': [ + { + 'package': 'chromeos_internal/assistant/time_of_day', + 'version': '7okw0Y1HdRp76vhM8AGsWOloCQ83hwMd7Y1k2sDYMJcC', + }, + ], + 'condition': 'checkout_chromeos and checkout_src_internal', + 'dep_type': 'cipd', + }, + 'src/ash/webui/projector_app/resources/prod': { 'packages': [ {
diff --git a/PRESUBMIT.py b/PRESUBMIT.py index 86e53e01..6d37b2a 100644 --- a/PRESUBMIT.py +++ b/PRESUBMIT.py
@@ -6844,6 +6844,9 @@ def CheckLibcxxRevisionsMatch(input_api, output_api): """Check to make sure the libc++ version matches across deps files.""" + # Disable check for changes to sub-repositories. + if input_api.PresubmitLocalPath() != input_api.change.RepositoryRoot(): + return [] DEPS_FILES = [ 'DEPS', 'buildtools/deps_revisions.gni' ]
diff --git a/android_webview/java/src/org/chromium/android_webview/metrics/AwMetricsLogUploader.java b/android_webview/java/src/org/chromium/android_webview/metrics/AwMetricsLogUploader.java index c695564..c3dc893 100644 --- a/android_webview/java/src/org/chromium/android_webview/metrics/AwMetricsLogUploader.java +++ b/android_webview/java/src/org/chromium/android_webview/metrics/AwMetricsLogUploader.java
@@ -95,6 +95,7 @@ private final boolean mUseDefaultUploadQos; private final @NonNull byte[] mData; private final CompletableFuture<Integer> mResult; + private final AtomicBoolean mPosted = new AtomicBoolean(); public MetricsLogUploaderServiceConnection(boolean useDefaultUploadQos, @NonNull byte[] data, @NonNull CompletableFuture<Integer> resultFuture) { @@ -105,6 +106,11 @@ @Override public void onServiceConnected(ComponentName name, IBinder service) { + // We want to avoid re-posting if the service connection dies + // and reconnects. + if (mPosted.getAndSet(true)) { + return; + } // onServiceConnected is called on the app main looper so post it to a background thread // for execution. No need to enforce the order in which the logs are sent to the service // as this isn't required/enforced by UMA.
diff --git a/android_webview/lib/aw_main_delegate.cc b/android_webview/lib/aw_main_delegate.cc index 49886ae..1e68fd5 100644 --- a/android_webview/lib/aw_main_delegate.cc +++ b/android_webview/lib/aw_main_delegate.cc
@@ -70,7 +70,6 @@ #include "services/network/public/cpp/features.h" #include "third_party/abseil-cpp/absl/types/variant.h" #include "third_party/blink/public/common/features.h" -#include "third_party/blink/public/common/switches.h" #include "tools/v8_context_snapshot/buildflags.h" #include "ui/base/ui_base_paths.h" #include "ui/base/ui_base_switches.h" @@ -316,13 +315,6 @@ features.DisableIfNotSet(::features::kFedCm); } - // Enable Event.path on Beta and Stable. The feature has been deprecated and - // removed on other platforms, but needs more time on WebView. - // See crbug.com/1277431 for more details. - if (version_info::android::GetChannel() >= version_info::Channel::BETA) { - cl->AppendSwitch(blink::switches::kEventPathEnabledByDefault); - } - android_webview::RegisterPathProvider(); // Used only if the argument filter is enabled in tracing config,
diff --git a/ash/accelerators/accelerator_commands.cc b/ash/accelerators/accelerator_commands.cc index 7b69894d..1fdd21e8 100644 --- a/ash/accelerators/accelerator_commands.cc +++ b/ash/accelerators/accelerator_commands.cc
@@ -1571,7 +1571,8 @@ } void VolumeMute() { - CrasAudioHandler::Get()->SetOutputMute(true); + CrasAudioHandler::Get()->SetOutputMute( + true, CrasAudioHandler::AudioSettingsChangeSource::kAccelerator); } void VolumeUp() {
diff --git a/ash/public/cpp/window_properties.cc b/ash/public/cpp/window_properties.cc index f36af76..d3d9f96 100644 --- a/ash/public/cpp/window_properties.cc +++ b/ash/public/cpp/window_properties.cc
@@ -70,5 +70,6 @@ DEFINE_UI_CLASS_PROPERTY_KEY(ResizeShadowType, kResizeShadowTypeKey, ResizeShadowType::kUnlock) +DEFINE_OWNED_UI_CLASS_PROPERTY_KEY(std::string, kDeskGuidKey, nullptr) } // namespace ash
diff --git a/ash/public/cpp/window_properties.h b/ash/public/cpp/window_properties.h index 016e36d..711a86f 100644 --- a/ash/public/cpp/window_properties.h +++ b/ash/public/cpp/window_properties.h
@@ -200,6 +200,11 @@ ASH_PUBLIC_EXPORT extern const aura::WindowProperty<gfx::Rect*>* const kWindowPipResizeHandleBoundsKey; +// A property key to indicate a desk guid of a workspace this window belongs +// to. +ASH_PUBLIC_EXPORT extern const aura::WindowProperty<std::string*>* const + kDeskGuidKey; + // Alphabetical sort. } // namespace ash
diff --git a/ash/shelf/drag_window_from_shelf_controller_unittest.cc b/ash/shelf/drag_window_from_shelf_controller_unittest.cc index 592902a2..bdecbff 100644 --- a/ash/shelf/drag_window_from_shelf_controller_unittest.cc +++ b/ash/shelf/drag_window_from_shelf_controller_unittest.cc
@@ -1575,6 +1575,7 @@ // does nothing. GetEventGenerator()->PressTouch(drag_point_under_float); GetEventGenerator()->MoveTouchBy(0, -200); + GetEventGenerator()->ReleaseTouch(); EXPECT_FALSE(GetDragWindowFromShelfController()->drag_started()); }
diff --git a/ash/shelf/shelf_layout_manager.cc b/ash/shelf/shelf_layout_manager.cc index 1a518201..a17d081 100644 --- a/ash/shelf/shelf_layout_manager.cc +++ b/ash/shelf/shelf_layout_manager.cc
@@ -244,6 +244,32 @@ return app_list_visible ? -offset : offset; } +// The floated window is the dragged window if it is not tucked, magnetized to +// the bottom, and above the event. +bool CanDragFloatedWindowFromShelf(aura::Window* floated_window, + const gfx::Point& location_in_screen) { + if (!Shell::Get()->float_controller()->IsFloatedWindowAlignedWithShelf( + floated_window)) { + return false; + } + DCHECK(floated_window->IsVisible()); + const gfx::Rect floated_window_bounds = floated_window->GetBoundsInScreen(); + return location_in_screen.x() <= floated_window_bounds.right() && + location_in_screen.x() >= floated_window_bounds.x(); +} + +// Checks if the only visible window is floated and not the dragged window, in +// which case we treat it as swipe home to overview. +bool IsDragOverShelfWithFloatedWindow(const gfx::Point& location_in_screen) { + aura::Window* top_window = window_util::GetTopNonFloatedWindow(); + if (top_window && top_window->IsVisible()) { + return false; + } + aura::Window* floated_window = window_util::GetFloatedWindowForActiveDesk(); + return floated_window && + !CanDragFloatedWindowFromShelf(floated_window, location_in_screen); +} + // Returns the window that can be dragged from shelf into home screen or // overview at |location_in_screen|. Returns nullptr if there is no such // window. @@ -267,20 +293,11 @@ return nullptr; } - // Checks for a floated window. The floated window is the dragged window if it - // is not tucked, magnetized to the bottom, and above the event. if (aura::Window* floated_window = - window_util::GetFloatedWindowForActiveDesk()) { - if (Shell::Get()->float_controller()->IsFloatedWindowAlignedWithShelf( - floated_window)) { - const gfx::Rect floated_window_bounds = - floated_window->GetBoundsInScreen(); - if (location_in_screen.x() <= floated_window_bounds.right() && - location_in_screen.x() >= floated_window_bounds.x()) { - DCHECK(floated_window->IsVisible()); - return floated_window; - } - } + window_util::GetFloatedWindowForActiveDesk(); + floated_window && + CanDragFloatedWindowFromShelf(floated_window, location_in_screen)) { + return floated_window; } // If split view mode is not active, use the first MRU window. @@ -2448,8 +2465,10 @@ // In tablet mode, let swipe_home_to_overview_controller handle swipe up // gestures on the home launcher screen. if (Shell::Get()->IsInTabletMode() && - Shell::Get()->app_list_controller()->IsVisible(display_.id()) && - Shell::Get()->app_list_controller()->GetTargetVisibility(display_.id()) && + ((Shell::Get()->app_list_controller()->IsVisible(display_.id()) && + Shell::Get()->app_list_controller()->GetTargetVisibility( + display_.id())) || + IsDragOverShelfWithFloatedWindow(gesture_in_screen.location())) && scroll_y_hint < 0) { drag_status_ = kDragHomeToOverviewInProgress; swipe_home_to_overview_controller_ =
diff --git a/ash/style/color_palette_controller.cc b/ash/style/color_palette_controller.cc index 88326966..2d747a76 100644 --- a/ash/style/color_palette_controller.cc +++ b/ash/style/color_palette_controller.cc
@@ -71,7 +71,9 @@ WallpaperControllerImpl* wallpaper_controller) : wallpaper_controller_(wallpaper_controller), dark_light_mode_controller_(dark_light_mode_controller) { + dark_light_observation_.Observe(dark_light_mode_controller); wallpaper_observation_.Observe(wallpaper_controller); + wallpaper_color_[ColorMode::kDark] = SK_ColorTRANSPARENT; wallpaper_color_[ColorMode::kLight] = SK_ColorTRANSPARENT; } @@ -139,12 +141,25 @@ return seed; } + ColorPaletteSeed GetCurrentSeed() const override { + const auto* session = GetActiveUserSession(); + if (!session) { + return {}; + } + + return GetColorPaletteSeed(AccountFromSession(session)); + } + bool UsesWallpaperSeedColor(const AccountId& account_id) const override { // Scheme tracks if wallpaper color is used. return GetColorScheme(account_id) != ColorScheme::kStatic; } ColorScheme GetColorScheme(const AccountId& account_id) const override { + if (!chromeos::features::IsJellyEnabled()) { + // Pre-Jelly, this is always Tonal Spot. + return ColorScheme::kTonalSpot; + } PrefService* pref_service = GetUserPrefService(account_id); if (!pref_service) { DVLOG(1) @@ -249,6 +264,9 @@ base::flat_map<ui::ColorProviderManager::ColorMode, SkColor> wallpaper_color_; + base::ScopedObservation<DarkLightModeController, ColorModeObserver> + dark_light_observation_{this}; + base::ScopedObservation<WallpaperController, WallpaperControllerObserver> wallpaper_observation_{this};
diff --git a/ash/style/color_palette_controller.h b/ash/style/color_palette_controller.h index b7a82502..0edfc4f 100644 --- a/ash/style/color_palette_controller.h +++ b/ash/style/color_palette_controller.h
@@ -5,6 +5,8 @@ #ifndef ASH_STYLE_COLOR_PALETTE_CONTROLLER_H_ #define ASH_STYLE_COLOR_PALETTE_CONTROLLER_H_ +#include <tuple> + #include "ash/ash_export.h" #include "base/containers/span.h" #include "base/observer_list_types.h" @@ -13,6 +15,7 @@ #include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/skia/include/core/SkColor.h" #include "ui/color/color_provider_manager.h" +#include "ui/gfx/color_palette.h" class PrefRegistrySimple; @@ -35,11 +38,17 @@ // palette. struct ASH_EXPORT ColorPaletteSeed { // The color which the palette is generated from. - SkColor seed_color; + SkColor seed_color = gfx::kGoogleBlue400; // The type of palette which is being generated. - ColorScheme scheme; + ColorScheme scheme = ColorScheme::kStatic; // Dark or light palette. - ui::ColorProviderManager::ColorMode color_mode; + ui::ColorProviderManager::ColorMode color_mode = + ui::ColorProviderManager::ColorMode::kLight; + + bool operator==(const ColorPaletteSeed& other) const { + return std::tie(seed_color, scheme, color_mode) == + std::tie(other.seed_color, other.scheme, other.color_mode); + } }; // Samples of color schemes for the tri-color scheme previews. @@ -108,6 +117,9 @@ virtual ColorPaletteSeed GetColorPaletteSeed( const AccountId& account_id) const = 0; + // Returns the current seed for the current user. + virtual ColorPaletteSeed GetCurrentSeed() const = 0; + // Returns true if using a color scheme based on the current wallpaper. virtual bool UsesWallpaperSeedColor(const AccountId& account_id) const = 0;
diff --git a/ash/style/color_palette_controller_unittest.cc b/ash/style/color_palette_controller_unittest.cc index 7bd5ae7..78fbc31 100644 --- a/ash/style/color_palette_controller_unittest.cc +++ b/ash/style/color_palette_controller_unittest.cc
@@ -8,7 +8,12 @@ #include "ash/style/dark_light_mode_controller_impl.h" #include "ash/test/ash_test_base.h" #include "ash/wallpaper/wallpaper_controller_impl.h" +#include "ash/wallpaper/wallpaper_controller_test_api.h" +#include "ash/wallpaper/wallpaper_utils/wallpaper_calculated_colors.h" #include "base/functional/callback_helpers.h" +#include "base/test/scoped_feature_list.h" +#include "chromeos/constants/chromeos_features.h" +#include "testing/gmock/include/gmock/gmock.h" #include "third_party/skia/include/core/SkColor.h" namespace ash { @@ -18,6 +23,18 @@ const char kUser[] = "user@gmail.com"; const AccountId kAccountId = AccountId::FromUserEmailGaiaId(kUser, kUser); +// A nice magenta that is in the acceptable lightness range for dark and light. +// Hue: 281, Saturation: 100, Lightness: 50%. +constexpr SkColor kKMeanColor = SkColorSetRGB(0xae, 0x00, 0xff); + +class MockPaletteObserver : public ColorPaletteController::Observer { + public: + MOCK_METHOD(void, + OnColorPaletteChanging, + (const ColorPaletteSeed& seed), + (override)); +}; + } // namespace class ColorPaletteControllerTest : public NoSessionAshTestBase { @@ -26,24 +43,31 @@ NoSessionAshTestBase::SetUp(); GetSessionControllerClient()->Reset(); GetSessionControllerClient()->AddUserSession(kAccountId, kUser); - color_palette_controller_ = ColorPaletteController::Create( - Shell::Get()->dark_light_mode_controller(), - Shell::Get()->wallpaper_controller()); + dark_light_mode_controller_ = Shell::Get()->dark_light_mode_controller(); + wallpaper_controller_ = Shell::Get()->wallpaper_controller(); + color_palette_controller_ = Shell::Get()->color_palette_controller(); } - void TearDown() override { - // Must release the controller before Shell is destructed. - color_palette_controller_.reset(); - - NoSessionAshTestBase::TearDown(); - } + void TearDown() override { NoSessionAshTestBase::TearDown(); } ColorPaletteController* color_palette_controller() { - return color_palette_controller_.get(); + return color_palette_controller_; + } + + DarkLightModeControllerImpl* dark_light_controller() { + return dark_light_mode_controller_; + } + + WallpaperControllerImpl* wallpaper_controller() { + return wallpaper_controller_; } private: - std::unique_ptr<ColorPaletteController> color_palette_controller_; + base::raw_ptr<DarkLightModeControllerImpl> + dark_light_mode_controller_; // unowned + base::raw_ptr<WallpaperControllerImpl> wallpaper_controller_; // unowned + + base::raw_ptr<ColorPaletteController> color_palette_controller_; }; TEST_F(ColorPaletteControllerTest, ExpectedEmptyValues) { @@ -53,7 +77,24 @@ color_palette_controller()->GetStaticColor(kAccountId)); } +TEST_F(ColorPaletteControllerTest, SetColorScheme_JellyDisabled_AlwaysTonal) { + base::test::ScopedFeatureList feature_list; + feature_list.InitAndDisableFeature(chromeos::features::kJelly); + + color_palette_controller()->SetColorScheme(ColorScheme::kStatic, kAccountId, + base::DoNothing()); + EXPECT_EQ(ColorScheme::kTonalSpot, + color_palette_controller()->GetColorPaletteSeed(kAccountId).scheme); + + color_palette_controller()->SetColorScheme(ColorScheme::kExpressive, + kAccountId, base::DoNothing()); + EXPECT_EQ(ColorScheme::kTonalSpot, + color_palette_controller()->GetColorPaletteSeed(kAccountId).scheme); +} + TEST_F(ColorPaletteControllerTest, SetColorScheme) { + base::test::ScopedFeatureList feature_list(chromeos::features::kJelly); + ColorScheme color_scheme = ColorScheme::kExpressive; color_palette_controller()->SetColorScheme(color_scheme, kAccountId, @@ -69,6 +110,7 @@ } TEST_F(ColorPaletteControllerTest, SetStaticColor) { + base::test::ScopedFeatureList feature_list(chromeos::features::kJelly); SkColor static_color = SK_ColorGRAY; color_palette_controller()->SetStaticColor(static_color, kAccountId, @@ -84,4 +126,43 @@ EXPECT_EQ(static_color, color_palette_seed.seed_color); } +// If the Jelly flag is off, we always return the KMeans color from the +// wallpaper controller regardless of scheme. +TEST_F(ColorPaletteControllerTest, SetStaticColor_JellyDisabled_AlwaysKMeans) { + base::test::ScopedFeatureList feature_list; + feature_list.InitAndDisableFeature(chromeos::features::kJelly); + + WallpaperControllerTestApi wallpaper(wallpaper_controller()); + wallpaper.SetCalculatedColors( + WallpaperCalculatedColors({}, kKMeanColor, SK_ColorWHITE)); + + color_palette_controller()->SetColorScheme(ColorScheme::kStatic, kAccountId, + base::DoNothing()); + color_palette_controller()->SetStaticColor(SK_ColorRED, kAccountId, + base::DoNothing()); + + // TODO(skau): Check that this matches kKMean after color blending has been + // moved. + EXPECT_NE( + SK_ColorWHITE, + color_palette_controller()->GetColorPaletteSeed(kAccountId).seed_color); +} + +TEST_F(ColorPaletteControllerTest, ColorModeTriggersObserver) { + // Initialize Dark mode to a known state. + dark_light_controller()->SetDarkModeEnabledForTest(false); + + MockPaletteObserver observer; + base::ScopedObservation<ColorPaletteController, + ColorPaletteController::Observer> + observation(&observer); + observation.Observe(color_palette_controller()); + + EXPECT_CALL(observer, OnColorPaletteChanging(testing::Field( + &ColorPaletteSeed::color_mode, + ui::ColorProviderManager::ColorMode::kDark))) + .Times(1); + dark_light_controller()->SetDarkModeEnabledForTest(true); +} + } // namespace ash
diff --git a/ash/style/dark_light_mode_controller_impl.cc b/ash/style/dark_light_mode_controller_impl.cc index cb75246..e105f8f 100644 --- a/ash/style/dark_light_mode_controller_impl.cc +++ b/ash/style/dark_light_mode_controller_impl.cc
@@ -294,8 +294,14 @@ void DarkLightModeControllerImpl::NotifyColorModeChanges() { const bool is_enabled = IsDarkModeEnabled(); cros_styles::SetDarkModeEnabled(is_enabled); - for (auto& observer : observers_) + if (last_value_ == is_enabled) { + // Updating the pref causes a notification. Skip it if it happens. + return; + } + last_value_ = is_enabled; + for (auto& observer : observers_) { observer.OnColorModeChanged(is_enabled); + } RefreshColorsOnColorMode(IsDarkModeEnabled()); }
diff --git a/ash/style/dark_light_mode_controller_impl.h b/ash/style/dark_light_mode_controller_impl.h index ed95350..788b14a 100644 --- a/ash/style/dark_light_mode_controller_impl.h +++ b/ash/style/dark_light_mode_controller_impl.h
@@ -109,6 +109,10 @@ OobeDialogState oobe_state_ = OobeDialogState::HIDDEN; + // Keep track of the last value that was sent to avoid multiple + // notifications. + absl::optional<bool> last_value_; + // absl::nullopt in case no user pod is focused. absl::optional<bool> is_dark_mode_enabled_for_focused_pod_;
diff --git a/ash/system/audio/mic_gain_slider_controller.cc b/ash/system/audio/mic_gain_slider_controller.cc index 0946618..e8be696 100644 --- a/ash/system/audio/mic_gain_slider_controller.cc +++ b/ash/system/audio/mic_gain_slider_controller.cc
@@ -93,8 +93,9 @@ TrackToggleUMA(/*target_toggle_state=*/mute); - audio_handler->SetMuteForDevice(audio_handler->GetPrimaryActiveInputNode(), - mute); + audio_handler->SetMuteForDevice( + audio_handler->GetPrimaryActiveInputNode(), mute, + CrasAudioHandler::AudioSettingsChangeSource::kSystemTray); } void MicGainSliderController::RecordGainChanged() {
diff --git a/ash/system/audio/mic_gain_slider_controller_unittest.cc b/ash/system/audio/mic_gain_slider_controller_unittest.cc index 8f0d6ff..fbb26fc 100644 --- a/ash/system/audio/mic_gain_slider_controller_unittest.cc +++ b/ash/system/audio/mic_gain_slider_controller_unittest.cc
@@ -4,6 +4,8 @@ #include "ash/system/audio/mic_gain_slider_controller.h" +#include <memory> + #include "ash/constants/ash_features.h" #include "ash/shell.h" #include "ash/system/audio/mic_gain_slider_view.h" @@ -14,6 +16,7 @@ #include "base/time/time.h" #include "chromeos/ash/components/audio/cras_audio_handler.h" #include "ui/views/controls/slider.h" +#include "ui/views/widget/widget.h" namespace ash { @@ -35,6 +38,20 @@ ~MicGainSliderControllerTest() override = default; + void SetUp() override { + AshTestBase::SetUp(); + widget_ = CreateFramelessTestWidget(); + widget_->SetFullscreen(true); + slider_view_ = static_cast<MicGainSliderView*>( + mic_gain_slider_controller_.CreateView()); + widget_->SetContentsView(slider_view_); + } + + void TearDown() override { + widget_.reset(); + AshTestBase::TearDown(); + } + bool IsQsRevampEnabled() const { return GetParam(); } views::View* GetMuteToastView() { @@ -48,11 +65,15 @@ /*old_value=*/0, views::SliderChangeReason::kByUser); } + void PressSliderButton() { LeftClickOn(slider_view_->button()); } + base::HistogramTester histogram_tester_; private: base::test::ScopedFeatureList feature_list_; MicGainSliderController mic_gain_slider_controller_; + MicGainSliderView* slider_view_ = nullptr; + std::unique_ptr<views::Widget> widget_; }; INSTANTIATE_TEST_SUITE_P(QsRevamp, @@ -117,4 +138,12 @@ delete toast_view; } +// Verify pressing the mute button is recorded to metrics. +TEST_P(MicGainSliderControllerTest, RecordInputGainMuteSource) { + PressSliderButton(); + histogram_tester_.ExpectBucketCount( + CrasAudioHandler::kInputGainMuteSourceHistogramName, + CrasAudioHandler::AudioSettingsChangeSource::kSystemTray, 1); +} + } // namespace ash
diff --git a/ash/system/audio/unified_volume_slider_controller.cc b/ash/system/audio/unified_volume_slider_controller.cc index 04031af..2a7a24f 100644 --- a/ash/system/audio/unified_volume_slider_controller.cc +++ b/ash/system/audio/unified_volume_slider_controller.cc
@@ -101,7 +101,8 @@ TrackToggleUMA(/*target_toggle_state=*/mute); - audio_handler->SetOutputMute(mute); + audio_handler->SetOutputMute( + mute, CrasAudioHandler::AudioSettingsChangeSource::kSystemTray); } void UnifiedVolumeSliderController::RecordVolumeSourceMetric() {
diff --git a/ash/system/audio/unified_volume_slider_controller_unittest.cc b/ash/system/audio/unified_volume_slider_controller_unittest.cc index 40b7ea6..ddccda47 100644 --- a/ash/system/audio/unified_volume_slider_controller_unittest.cc +++ b/ash/system/audio/unified_volume_slider_controller_unittest.cc
@@ -4,16 +4,28 @@ #include "ash/system/audio/unified_volume_slider_controller.h" +#include <memory> + #include "ash/shell.h" +#include "ash/system/audio/unified_volume_view.h" #include "ash/test/ash_test_base.h" #include "base/test/metrics/histogram_tester.h" #include "base/test/task_environment.h" #include "base/time/time.h" #include "chromeos/ash/components/audio/cras_audio_handler.h" #include "ui/views/controls/slider.h" +#include "ui/views/widget/widget.h" namespace ash { +class FakeDelegate : public UnifiedVolumeSliderController::Delegate { + public: + FakeDelegate() = default; + ~FakeDelegate() override = default; + + void OnAudioSettingsButtonClicked() override {} +}; + class UnifiedVolumeSliderControllerTest : public AshTestBase { public: UnifiedVolumeSliderControllerTest() @@ -26,17 +38,40 @@ ~UnifiedVolumeSliderControllerTest() override = default; + void SetUp() override { + AshTestBase::SetUp(); + delegate_ = std::make_unique<FakeDelegate>(); + unified_volume_slider_controller_ = + std::make_unique<UnifiedVolumeSliderController>(delegate_.get()); + widget_ = CreateFramelessTestWidget(); + widget_->SetFullscreen(true); + slider_view_ = static_cast<UnifiedVolumeView*>( + unified_volume_slider_controller_->CreateView()); + widget_->SetContentsView(slider_view_); + } + + void TearDown() override { + widget_.reset(); + AshTestBase::TearDown(); + } + protected: void UpdateSliderValue(float new_value) { - unified_volume_slider_controller_.SliderValueChanged( + unified_volume_slider_controller_->SliderValueChanged( /*sender=*/nullptr, new_value, /*old_value=*/0, views::SliderChangeReason::kByUser); } + void PressSliderButton() { LeftClickOn(slider_view_->button()); } + base::HistogramTester histogram_tester_; private: - UnifiedVolumeSliderController unified_volume_slider_controller_; + std::unique_ptr<UnifiedVolumeSliderController> + unified_volume_slider_controller_; + std::unique_ptr<FakeDelegate> delegate_; + UnifiedVolumeView* slider_view_ = nullptr; + std::unique_ptr<views::Widget> widget_; }; // Verify moving the slider and changing the output volume is recorded to @@ -78,4 +113,12 @@ CrasAudioHandler::AudioSettingsChangeSource::kSystemTray, 2); } +// Verify pressing the mute button is recorded to metrics. +TEST_F(UnifiedVolumeSliderControllerTest, RecordOuptputVolumeMuteSource) { + PressSliderButton(); + histogram_tester_.ExpectBucketCount( + CrasAudioHandler::kOutputVolumeMuteSourceHistogramName, + CrasAudioHandler::AudioSettingsChangeSource::kSystemTray, 1); +} + } // namespace ash
diff --git a/ash/system/time/calendar_view.cc b/ash/system/time/calendar_view.cc index 97f7d31..513a1ee 100644 --- a/ash/system/time/calendar_view.cc +++ b/ash/system/time/calendar_view.cc
@@ -62,7 +62,6 @@ kContentHorizontalPadding - calendar_utils::kDateHorizontalPadding; constexpr int kExpandedCalendarPadding = 11; constexpr int kChevronPadding = calendar_utils::kColumnSetPadding - 1; -constexpr int kEventListViewVerticalPadding = 6; constexpr int kMonthHeaderLabelTopPadding = 14; constexpr int kMonthHeaderLabelBottomPadding = 2; constexpr int kEventListViewHorizontalOffset = 1; @@ -2042,9 +2041,9 @@ const int x_position = scroll_view_->x() + kEventListViewHorizontalOffset; const int width = scroll_view_->GetVisibleRect().width() - kEventListViewHorizontalOffset * 2; - const int event_list_view_height = - GetBoundsInScreen().bottom() - scroll_view_->GetBoundsInScreen().y() - - calendar_view_controller_->row_height() + kEventListViewVerticalPadding; + const int event_list_view_height = GetBoundsInScreen().bottom() - + scroll_view_->GetBoundsInScreen().y() - + calendar_view_controller_->row_height(); // If the event list view is showing, position the calendar sliding surface // where the opened event list view will be.
diff --git a/ash/webui/personalization_app/resources/BUILD.gn b/ash/webui/personalization_app/resources/BUILD.gn index 9fc3bfb..1b16a1d 100644 --- a/ash/webui/personalization_app/resources/BUILD.gn +++ b/ash/webui/personalization_app/resources/BUILD.gn
@@ -169,5 +169,17 @@ optimize_webui_in_files = [ "js/personalization_app.js" ] } + # Time of day assets cannot be made public until after the feature is + # released. Thus, they are currently hosted in CIPD and downloaded to + # this directory only if an internal chrome-branded checkout is being used. + # TODO(b/275379819): Create a custom GN arg like "tod_screensaver_enabled" and set it based + # on "feature_management" use flag in chromeos-chrome.ebuild. + if (is_chrome_branded) { + static_files += [ + "time_of_day/thumbnails/clouds.jpg", + "time_of_day/thumbnails/new_mexico.jpg", + ] + } + grit_output_dir = "$root_gen_dir/ash/webui" }
diff --git a/ash/webui/personalization_app/resources/README b/ash/webui/personalization_app/resources/README new file mode 100644 index 0000000..16568c9 --- /dev/null +++ b/ash/webui/personalization_app/resources/README
@@ -0,0 +1,15 @@ +The time-of-day resources cannot be made public until after the feature has been +launched. Thus, they are currently hosted in CIPD and downloaded to this +directory only if an internal chrome-branded checkout is being used. To update +the assets in cipd: +* `cd` to this directory in your local checkout +* Update the time_of_day/ directory locally with desired changes. +* Rebuild and test it. +* `cipd auth-login` +* `cipd create -pkg-def=cipd_time_of_day.yaml`. Outputs something like this: + +Instance: chromeos_internal/assistant/time_of_day:<version_id> + • Instance chromeos_internal/assistant/time_of_day:<version_id> was successfully registered + +* Open chromium/src/DEPS and find "src/ash/webui/personalization_app/resources". + Update the "version" field to the <version_id> printed above.
diff --git a/ash/webui/personalization_app/resources/cipd_time_of_day.yaml b/ash/webui/personalization_app/resources/cipd_time_of_day.yaml new file mode 100644 index 0000000..16129bcb --- /dev/null +++ b/ash/webui/personalization_app/resources/cipd_time_of_day.yaml
@@ -0,0 +1,4 @@ +package: chromeos_internal/assistant/time_of_day +description: Resources for time-of-day wallpaper and screensaver. +data: + - dir: time_of_day
diff --git a/ash/webui/projector_app/BUILD.gn b/ash/webui/projector_app/BUILD.gn index 7b2aa84..52df83d 100644 --- a/ash/webui/projector_app/BUILD.gn +++ b/ash/webui/projector_app/BUILD.gn
@@ -10,8 +10,6 @@ static_library("projector_app") { sources = [ - "annotator_page_handler_impl.cc", - "annotator_page_handler_impl.h", "projector_app_client.cc", "projector_app_client.h", "projector_message_handler.cc", @@ -22,10 +20,10 @@ "projector_screencast.h", "projector_xhr_sender.cc", "projector_xhr_sender.h", - "trusted_projector_annotator_ui.cc", - "trusted_projector_annotator_ui.h", "trusted_projector_ui.cc", "trusted_projector_ui.h", + "untrusted_annotator_page_handler_impl.cc", + "untrusted_annotator_page_handler_impl.h", "untrusted_projector_annotator_ui.cc", "untrusted_projector_annotator_ui.h", "untrusted_projector_ui.cc", @@ -39,7 +37,6 @@ "//ash/webui/projector_app/mojom:annotator_mojo_bindings", "//ash/webui/projector_app/public/mojom:annotator_mojo_bindings", "//ash/webui/resources:media_app_bundle_resources", - "//ash/webui/resources:projector_annotator_trusted_resources", "//ash/webui/resources:projector_annotator_untrusted_resources", "//ash/webui/resources:projector_app_bundle_resources", "//ash/webui/resources:projector_app_trusted_resources", @@ -82,10 +79,10 @@ source_set("unit_tests") { testonly = true sources = [ - "test/annotator_page_handler_impl_unittest.cc", "test/projector_message_handler_unittest.cc", "test/projector_oauth_token_fetcher_unittest.cc", "test/projector_xhr_sender_unittest.cc", + "test/untrusted_annotator_page_handler_impl_unittest.cc", ] deps = [
diff --git a/ash/webui/projector_app/annotator_page_handler_impl.h b/ash/webui/projector_app/annotator_page_handler_impl.h deleted file mode 100644 index 8808cef0..0000000 --- a/ash/webui/projector_app/annotator_page_handler_impl.h +++ /dev/null
@@ -1,64 +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. - -#ifndef ASH_WEBUI_PROJECTOR_APP_ANNOTATOR_PAGE_HANDLER_IMPL_H_ -#define ASH_WEBUI_PROJECTOR_APP_ANNOTATOR_PAGE_HANDLER_IMPL_H_ - -#include "ash/public/cpp/projector/projector_annotator_controller.h" -#include "ash/webui/projector_app/mojom/annotator.mojom.h" -#include "base/functional/callback.h" -#include "base/values.h" -#include "mojo/public/cpp/bindings/pending_receiver.h" -#include "mojo/public/cpp/bindings/pending_remote.h" -#include "mojo/public/cpp/bindings/receiver.h" -#include "mojo/public/cpp/bindings/remote.h" - -namespace content { -class WebUI; -} // namespace content - -namespace ash { - -struct AnnotatorTool; - -// Handles communication with the Annotator WebUI (i.e. -// chrome://projector/annotator/annotator_embedder.html). -class AnnotatorPageHandlerImpl : public annotator::mojom::AnnotatorPageHandler { - public: - AnnotatorPageHandlerImpl( - mojo::PendingReceiver<annotator::mojom::AnnotatorPageHandler> - annotator_handler, - mojo::PendingRemote<annotator::mojom::AnnotatorPage> annotator, - content::WebUI* web_ui); - AnnotatorPageHandlerImpl(const AnnotatorPageHandlerImpl&) = delete; - AnnotatorPageHandlerImpl& operator=(const AnnotatorPageHandlerImpl&) = delete; - ~AnnotatorPageHandlerImpl() override; - - // Called by ProjectorAppClient. - void SetTool(const AnnotatorTool& tool); - void Undo(); - void Redo(); - void Clear(); - - // annotator::mojom::AnnotatorHandler: - void OnUndoRedoAvailabilityChanged(bool undo_available, - bool redo_available) override; - void OnCanvasInitialized(bool success) override; - void OnError(const std::vector<std::string>& messages) override; - - content::WebUI* get_web_ui_for_test() { return web_ui_; } - - private: - mojo::Remote<annotator::mojom::AnnotatorPage> annotator_remote_; - mojo::Receiver<annotator::mojom::AnnotatorPageHandler> - annotator_handler_receiver_; - - // The WebUI that owns the TrustedProjectorAnnotatorUI that owns this - // instance. - content::WebUI* const web_ui_; -}; - -} // namespace ash - -#endif // ASH_WEBUI_PROJECTOR_APP_ANNOTATOR_PAGE_HANDLER_IMPL_H_
diff --git a/ash/webui/projector_app/mojom/BUILD.gn b/ash/webui/projector_app/mojom/BUILD.gn index 95890cd..2ee3298 100644 --- a/ash/webui/projector_app/mojom/BUILD.gn +++ b/ash/webui/projector_app/mojom/BUILD.gn
@@ -10,7 +10,7 @@ cur_dir = rebase_path(".", "//") mojom("annotator_mojo_bindings") { - sources = [ "annotator.mojom" ] + sources = [ "untrusted_annotator.mojom" ] deps = [ "//ash/webui/projector_app/public/mojom:annotator_mojo_bindings" ] webui_module_path = "/$cur_dir" }
diff --git a/ash/webui/projector_app/mojom/annotator.mojom b/ash/webui/projector_app/mojom/untrusted_annotator.mojom similarity index 78% rename from ash/webui/projector_app/mojom/annotator.mojom rename to ash/webui/projector_app/mojom/untrusted_annotator.mojom index fca08dc..2059657c 100644 --- a/ash/webui/projector_app/mojom/annotator.mojom +++ b/ash/webui/projector_app/mojom/untrusted_annotator.mojom
@@ -8,7 +8,7 @@ // AnnotatorPage interface implemented in the Javascript. Used by the browser // process to send events to Javascript. -interface AnnotatorPage { +interface UntrustedAnnotatorPage { // Clears the annotations on the annotator canvas. Clear(); // Undo the last stroke on the annotator canvas. @@ -21,7 +21,7 @@ // AnnotatoPagerHandler interface implemented in C++ in the browser process. // Used by Javascript to communicate with the browser process. -interface AnnotatorPageHandler { +interface UntrustedAnnotatorPageHandler { // Notifies the browser that that undo/redo availability // changed for annotator. OnUndoRedoAvailabilityChanged(bool undo_available, @@ -30,17 +30,13 @@ // Notifies the browser process that the annotation canvas // has been initialized. OnCanvasInitialized(bool success); - - // Notifies the browser process that an error has occurred - // in the renderer and sends the error messages to it. - OnError(array<string> errors); }; // Interface used to setup the communication between Javascript and C++ // in the browser process. -interface AnnotatorPageHandlerFactory { +interface UntrustedAnnotatorPageHandlerFactory { // Creates the AnnotatorPageHandler in the browser process and binds it // to receive calls from Javascript. - Create(pending_receiver<AnnotatorPageHandler> handler, - pending_remote<AnnotatorPage> annotator); + Create(pending_receiver<UntrustedAnnotatorPageHandler> handler, + pending_remote<UntrustedAnnotatorPage> annotator); };
diff --git a/ash/webui/projector_app/projector_app_client.h b/ash/webui/projector_app/projector_app_client.h index f59e2dc..96a51d0b 100644 --- a/ash/webui/projector_app/projector_app_client.h +++ b/ash/webui/projector_app/projector_app_client.h
@@ -25,7 +25,7 @@ namespace ash { -class AnnotatorPageHandlerImpl; +class UntrustedAnnotatorPageHandlerImpl; struct AnnotatorTool; struct ProjectorScreencastVideo; struct NewScreencastPrecondition; @@ -160,11 +160,13 @@ // Registers the AnnotatorPageHandlerImpl that is owned by the WebUI that // contains the Projector annotator. - virtual void SetAnnotatorPageHandler(AnnotatorPageHandlerImpl* handler) = 0; + virtual void SetAnnotatorPageHandler( + UntrustedAnnotatorPageHandlerImpl* handler) = 0; // Resets the stored AnnotatorPageHandlerImpl if it matches the one that is // passed in. - virtual void ResetAnnotatorPageHandler(AnnotatorPageHandlerImpl* handler) = 0; + virtual void ResetAnnotatorPageHandler( + UntrustedAnnotatorPageHandlerImpl* handler) = 0; // Sets the tool inside the annotator WebUI. virtual void SetTool(const AnnotatorTool& tool) = 0;
diff --git a/ash/webui/projector_app/public/cpp/projector_app_constants.cc b/ash/webui/projector_app/public/cpp/projector_app_constants.cc index 8fa9675..eaaa2443 100644 --- a/ash/webui/projector_app/public/cpp/projector_app_constants.cc +++ b/ash/webui/projector_app/public/cpp/projector_app_constants.cc
@@ -15,7 +15,6 @@ "https://screencast.apps.chrome"; const char kChromeUITrustedProjectorUrl[] = "chrome://projector/"; -const char kChromeUITrustedAnnotatorUrl[] = "chrome://projector-annotator/"; const char kChromeUIUntrustedAnnotatorUrl[] = "chrome-untrusted://projector-annotator/";
diff --git a/ash/webui/projector_app/public/cpp/projector_app_constants.h b/ash/webui/projector_app/public/cpp/projector_app_constants.h index ee43ff1..8108b594 100644 --- a/ash/webui/projector_app/public/cpp/projector_app_constants.h +++ b/ash/webui/projector_app/public/cpp/projector_app_constants.h
@@ -16,7 +16,6 @@ extern const char kChromeUIUntrustedProjectorPwaUrl[]; extern const char kChromeUITrustedProjectorUrl[]; -extern const char kChromeUITrustedAnnotatorUrl[]; extern const char kChromeUIUntrustedAnnotatorUrl[]; extern const char kChromeUITrustedProjectorSwaAppId[];
diff --git a/ash/webui/projector_app/resources/BUILD.gn b/ash/webui/projector_app/resources/BUILD.gn index 0cae46dc..989adb1d 100644 --- a/ash/webui/projector_app/resources/BUILD.gn +++ b/ash/webui/projector_app/resources/BUILD.gn
@@ -11,7 +11,6 @@ js_type_check("closure_compile") { is_polymer3 = true deps = [ - "//ash/webui/projector_app/resources/annotator/trusted:trusted_annotator_library", "//ash/webui/projector_app/resources/annotator/untrusted:untrusted_annotator_library", "//ash/webui/projector_app/resources/app/trusted:trusted_app", "//ash/webui/projector_app/resources/app/untrusted:untrusted_app",
diff --git a/ash/webui/projector_app/resources/annotator/trusted/BUILD.gn b/ash/webui/projector_app/resources/annotator/trusted/BUILD.gn deleted file mode 100644 index 88d8fbd..0000000 --- a/ash/webui/projector_app/resources/annotator/trusted/BUILD.gn +++ /dev/null
@@ -1,49 +0,0 @@ -# Copyright 2022 The Chromium Authors -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -import("//chrome/common/features.gni") -import("//third_party/closure_compiler/compile_js.gni") -import("//ui/webui/resources/tools/generate_grd.gni") - -assert(is_chromeos_ash, "Projector Annotator is ChromeOS only") - -js_library("trusted_annotator_library") { - sources = [ - "annotator_browser_proxy.js", - "annotator_embedder_impl.js", - "trusted_annotator_comm_factory.js", - ] - deps = [ - "//ash/webui/common/resources:cr_deprecated", - "//ash/webui/common/resources/post_message_api:post_message_api_client", - "//ash/webui/common/resources/post_message_api:post_message_api_request_handler", - "//ash/webui/projector_app/mojom:annotator_mojo_bindings_webui_js", - "//ash/webui/projector_app/public/mojom:annotator_mojo_bindings_webui_js", - "//ash/webui/projector_app/resources/common:message_types", - ] - externs_list = [ "../../common/projector_app.externs.js" ] -} - -generate_grd("build_trusted_grd") { - input_files = [ - "annotator_embedder.html", - "annotator_embedder.css", - "annotator_browser_proxy.js", - "trusted_annotator_comm_factory.js", - "annotator_embedder_impl.js", - ] - - manifest_files = [] - input_files_base_dir = rebase_path(".", "//") - grd_prefix = "ash_projector_annotator_trusted" - out_grd = "$target_gen_dir/${grd_prefix}_resources.grd" - deps = [ - "//ash/webui/projector_app/mojom:annotator_mojo_bindings_webui_grdp", - "//ash/webui/projector_app/public/mojom:annotator_mojo_bindings_webui_grdp", - ] - grdp_files = [ - "$target_gen_dir/../../../mojom/annotator_mojo_bindings_webui_resources.grdp", - "$target_gen_dir/../../../public/mojom/annotator_mojo_bindings_webui_resources.grdp", - ] -}
diff --git a/ash/webui/projector_app/resources/annotator/trusted/annotator_embedder.css b/ash/webui/projector_app/resources/annotator/trusted/annotator_embedder.css deleted file mode 100644 index 0cd16f1..0000000 --- a/ash/webui/projector_app/resources/annotator/trusted/annotator_embedder.css +++ /dev/null
@@ -1,19 +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. */ - -body { - background-color: transparent; - height: 100vh; - margin: 0; - overflow: hidden; - width: 100vw; -} - -.marker-iframe { - border: none; - height: 100vh; - margin: 0; - overflow: hidden; - width: 100vw; -}
diff --git a/ash/webui/projector_app/resources/annotator/trusted/annotator_embedder.html b/ash/webui/projector_app/resources/annotator/trusted/annotator_embedder.html deleted file mode 100644 index 105c6d3..0000000 --- a/ash/webui/projector_app/resources/annotator/trusted/annotator_embedder.html +++ /dev/null
@@ -1,20 +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. ---> - -<!DOCTYPE html> -<html> -<head> - <link rel="stylesheet" href="annotator_embedder.css"> - <script type="module" src="annotator_embedder_impl.js"></script> - </head> - <body> - <iframe - class="marker-iframe" - src="chrome-untrusted://projector-annotator" - allow="cross-origin-isolated"> - </iframe> - </body> -</html>
diff --git a/ash/webui/projector_app/resources/annotator/trusted/annotator_embedder_impl.js b/ash/webui/projector_app/resources/annotator/trusted/annotator_embedder_impl.js deleted file mode 100644 index 97652a40..0000000 --- a/ash/webui/projector_app/resources/annotator/trusted/annotator_embedder_impl.js +++ /dev/null
@@ -1,64 +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. - -import {AnnotatorBrowserProxyImpl} from './annotator_browser_proxy.js'; -import {AnnotatorPageCallbackRouter} from './ash/webui/projector_app/mojom/annotator.mojom-webui.js'; -import {AnnotatorTrustedCommFactory} from './trusted_annotator_comm_factory.js'; - -/** - * Enum for passing annotator error message to the browser process. - * @enum {string} - */ -const AnnotatorToolErrorType = { - UNDO_ERROR: 'UNDO_ERROR', - REDO_ERROR: 'REDO_ERROR', - CLEAR_ERROR: 'CLEAR_ERROR', - SET_TOOL_ERROR: 'SET_TOOL_ERROR', -}; - - -/* @type {UntrustedAnnotatorClient} */ -const client = AnnotatorTrustedCommFactory.getPostMessageAPIClient(); - -/* @type {AnnotatorPageCallbackRouter} */ -const annotatorPageRouter = - AnnotatorBrowserProxyImpl.getInstance().getAnnotatorCallbackRouter(); - -annotatorPageRouter.undo.addListener(() => { - try { - client.undo(); - } catch (error) { - AnnotatorBrowserProxyImpl.getInstance().onError( - [AnnotatorToolErrorType.UNDO_ERROR]); - } -}); - -annotatorPageRouter.redo.addListener(() => { - try { - client.redo(); - } catch (error) { - AnnotatorBrowserProxyImpl.getInstance().onError( - [AnnotatorToolErrorType.REDO_ERROR]); - } -}); - - -annotatorPageRouter.clear.addListener(() => { - try { - client.clear(); - } catch (error) { - AnnotatorBrowserProxyImpl.getInstance().onError( - [AnnotatorToolErrorType.CLEAR_ERROR]); - } -}); - - -annotatorPageRouter.setTool.addListener((tool) => { - try { - client.setTool(tool); - } catch (error) { - AnnotatorBrowserProxyImpl.getInstance().onError( - [AnnotatorToolErrorType.SET_TOOL_ERROR]); - } -}); \ No newline at end of file
diff --git a/ash/webui/projector_app/resources/annotator/trusted/trusted_annotator_comm_factory.js b/ash/webui/projector_app/resources/annotator/trusted/trusted_annotator_comm_factory.js deleted file mode 100644 index bb2bcb4..0000000 --- a/ash/webui/projector_app/resources/annotator/trusted/trusted_annotator_comm_factory.js +++ /dev/null
@@ -1,134 +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. - -import {PostMessageAPIClient} from 'chrome://resources/ash/common/post_message_api/post_message_api_client.js'; -import {RequestHandler} from 'chrome://resources/ash/common/post_message_api/post_message_api_request_handler.js'; - -import {AnnotatorBrowserProxy, AnnotatorBrowserProxyImpl} from './annotator_browser_proxy.js'; - -const TARGET_URL = 'chrome-untrusted://projector-annotator/'; - -// A PostMessageAPIClient that sends messages to chrome-untrusted://projector. -export class UntrustedAnnotatorClient extends PostMessageAPIClient { - /** - * @param {!Window} targetWindow - */ - constructor(targetWindow) { - super(TARGET_URL, targetWindow); - } - - /** - * Notifies the Annotator tool to update the tool. - * @param {!projectorApp.AnnotatorToolParams} tool - * @return {Promise<boolean>} - */ - setTool(tool) { - return this.callApiFn('setTool', [tool]); - } - - /** - * Notifies the Annotator to undo the last stroke. - * @return {Promise<boolean>} - */ - undo() { - return this.callApiFn('undo', []); - } - - /** - * Notifies the Annotator to redo the last stroke. - * @return {Promise<boolean>} - */ - redo() { - return this.callApiFn('redo', []); - } - - /** - * Notifies the Annotator to clear the screen. - * @return {Promise<boolean>} - */ - clear() { - return this.callApiFn('clear', []); - } -} - -/** - * Class that implements the RequestHandler inside the Projector trusted scheme - * for Annotator. - */ -class TrustedAnnotatorRequestHandler extends RequestHandler { - /* - * @param {!Element} iframeElement The <iframe> element to listen to as a - * client. - * @param {AnnotatorBrowserProxy} browserProxy The browser proxy that will - * be used to handle the messages. - */ - constructor(iframeElement, browserProxy) { - super(iframeElement, TARGET_URL, TARGET_URL); - this.browserProxy_ = browserProxy; - - this.registerMethod('onUndoRedoAvailabilityChanged', (values) => { - if (!values || values.length != 2) { - return; - } - return this.browserProxy_.onUndoRedoAvailabilityChanged( - values[0], values[1]); - }); - - this.registerMethod('onCanvasInitialized', (values) => { - if (!values || values.length != 1) { - return; - } - return this.browserProxy_.onCanvasInitialized(values[0]); - }); - } -} - -/** - * This is a class that is used to setup the duplex communication - * channels between this origin, chrome://projector/* and the iframe embedded - * inside the document. - */ -export class AnnotatorTrustedCommFactory { - /** - * Creates the instances of PostMessageAPIClient and RequestHandler if they - * have not been created already. - */ - static maybeCreateInstances() { - if (AnnotatorTrustedCommFactory.client_ || - AnnotatorTrustedCommFactory.requestHandler_) { - return; - } - - const iframeElement = document.getElementsByTagName('iframe')[0]; - - AnnotatorTrustedCommFactory.client_ = - new UntrustedAnnotatorClient(iframeElement.contentWindow); - - AnnotatorTrustedCommFactory.requestHandler_ = - new TrustedAnnotatorRequestHandler( - iframeElement, AnnotatorBrowserProxyImpl.getInstance()); - } - - /** - * In order to use this class, please do the following - * (e.g. to set the tool do the following): - * const success = await - * AnnotatorTrustedCommFactory.getPostMessageAPIClient().setTool(tool); - * - * @return {!UntrustedAnnotatorClient} - */ - static getPostMessageAPIClient() { - // AnnotatorTrustedCommFactory.client_ should be available. However to be on - // the cautious side create an instance here if getPostMessageAPIClient is - // triggered before the page finishes loading. - AnnotatorTrustedCommFactory.maybeCreateInstances(); - return AnnotatorTrustedCommFactory.client_; - } -} - -document.addEventListener('DOMContentLoaded', () => { - // Create instances of the singletons(PostMessageAPIClient and - // RequestHandler) when the document has finished loading. - AnnotatorTrustedCommFactory.maybeCreateInstances(); -});
diff --git a/ash/webui/projector_app/resources/annotator/untrusted/BUILD.gn b/ash/webui/projector_app/resources/annotator/untrusted/BUILD.gn index 088d9cd0e..53efe48f 100644 --- a/ash/webui/projector_app/resources/annotator/untrusted/BUILD.gn +++ b/ash/webui/projector_app/resources/annotator/untrusted/BUILD.gn
@@ -9,10 +9,13 @@ assert(is_chromeos_ash, "Projector Annotator is ChromeOS only") js_library("untrusted_annotator_library") { - sources = [ "untrusted_annotator_comm_factory.js" ] + sources = [ + "annotator_browser_proxy.js", + "untrusted_annotator_comm_factory.js", + ] deps = [ - "//ash/webui/common/resources/post_message_api:post_message_api_client", - "//ash/webui/common/resources/post_message_api:post_message_api_request_handler", + "//ash/webui/projector_app/mojom:annotator_mojo_bindings_webui_js", + "//ash/webui/projector_app/public/mojom:annotator_mojo_bindings_webui_js", "//ash/webui/projector_app/resources/common:message_types", ] externs_list = [ "../../common/projector_app.externs.js" ] @@ -20,6 +23,7 @@ generate_grd("build_untrusted_grd") { input_files = [ + "annotator_browser_proxy.js", "annotator.html", "untrusted_annotator_comm_factory.js", ] @@ -27,4 +31,13 @@ input_files_base_dir = rebase_path(".", "//") grd_prefix = "ash_projector_annotator_untrusted" out_grd = "$target_gen_dir/${grd_prefix}_resources.grd" + + deps = [ + "//ash/webui/projector_app/mojom:annotator_mojo_bindings_webui_grdp", + "//ash/webui/projector_app/public/mojom:annotator_mojo_bindings_webui_grdp", + ] + grdp_files = [ + "$target_gen_dir/../../../mojom/annotator_mojo_bindings_webui_resources.grdp", + "$target_gen_dir/../../../public/mojom/annotator_mojo_bindings_webui_resources.grdp", + ] }
diff --git a/ash/webui/projector_app/resources/annotator/trusted/annotator_browser_proxy.js b/ash/webui/projector_app/resources/annotator/untrusted/annotator_browser_proxy.js similarity index 62% rename from ash/webui/projector_app/resources/annotator/trusted/annotator_browser_proxy.js rename to ash/webui/projector_app/resources/annotator/untrusted/annotator_browser_proxy.js index 322941c5..11310906 100644 --- a/ash/webui/projector_app/resources/annotator/trusted/annotator_browser_proxy.js +++ b/ash/webui/projector_app/resources/annotator/untrusted/annotator_browser_proxy.js
@@ -1,9 +1,8 @@ // Copyright 2022 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import {addSingletonGetter} from 'chrome://resources/ash/common/cr_deprecated.js'; -import {AnnotatorPageCallbackRouter, AnnotatorPageHandlerFactory, AnnotatorPageHandlerRemote, AnnotatorPageRemote} from './ash/webui/projector_app/mojom/annotator.mojom-webui.js'; +import {UntrustedAnnotatorPageCallbackRouter, UntrustedAnnotatorPageHandlerFactory, UntrustedAnnotatorPageHandlerRemote, UntrustedAnnotatorPageRemote} from './ash/webui/projector_app/mojom/untrusted_annotator.mojom-webui.js'; /** * To use the annotator proxy, please import this module and call @@ -28,14 +27,6 @@ * @param {boolean} success */ onCanvasInitialized(success) {} - - /** - * Sends 'error' message to handler. - * The Handler will log the message. If the error is not a recoverable error, - * the handler closes the corresponding WebUI. - * @param {!Array<string>} msg Error messages. - */ - onError(msg) {} } /** @@ -43,9 +34,9 @@ */ export class AnnotatorBrowserProxyImpl { constructor() { - this.pageHandlerFactory = AnnotatorPageHandlerFactory.getRemote(); - this.pageHandlerRemote = new AnnotatorPageHandlerRemote(); - this.annotatorCallbackRouter = new AnnotatorPageCallbackRouter(); + this.pageHandlerFactory = UntrustedAnnotatorPageHandlerFactory.getRemote(); + this.pageHandlerRemote = new UntrustedAnnotatorPageHandlerRemote(); + this.annotatorCallbackRouter = new UntrustedAnnotatorPageCallbackRouter(); this.pageHandlerFactory.create( this.pageHandlerRemote.$.bindNewPipeAndPassReceiver(), @@ -66,11 +57,9 @@ onCanvasInitialized(success) { this.pageHandlerRemote.onCanvasInitialized(success); } - - /** @override */ - onError(msgs) { - this.pageHandlerRemote.onError(msgs); - } } -addSingletonGetter(AnnotatorBrowserProxyImpl); \ No newline at end of file +/** + * @type {AnnotatorBrowserProxyImpl} + */ +export const browserProxy = new AnnotatorBrowserProxyImpl();
diff --git a/ash/webui/projector_app/resources/annotator/untrusted/untrusted_annotator_comm_factory.js b/ash/webui/projector_app/resources/annotator/untrusted/untrusted_annotator_comm_factory.js index 8775c9d..f780a39 100644 --- a/ash/webui/projector_app/resources/annotator/untrusted/untrusted_annotator_comm_factory.js +++ b/ash/webui/projector_app/resources/annotator/untrusted/untrusted_annotator_comm_factory.js
@@ -2,10 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import {PostMessageAPIClient} from '//resources/ash/common/post_message_api/post_message_api_client.js'; -import {RequestHandler} from '//resources/ash/common/post_message_api/post_message_api_request_handler.js'; - -const TARGET_URL = 'chrome://projector-annotator/'; +import {AnnotatorBrowserProxyImpl, browserProxy} from './annotator_browser_proxy.js'; +import {UntrustedAnnotatorPageCallbackRouter} from './ash/webui/projector_app/mojom/untrusted_annotator.mojom-webui.js'; /** * Returns the projector app element inside this current DOM. @@ -16,129 +14,56 @@ document.querySelector('projector-ink-canvas-wrapper')); } - -// A client that sends messages to the chrome://projector embedder. -export class TrustedAnnotatorClient extends PostMessageAPIClient { - /** - * @param {!Window} parentWindow The embedder window from which requests - * come. - */ - constructor(parentWindow) { - super(TARGET_URL, parentWindow); - } - - /** - * Notifies the native ui that undo/redo has become available. - * @param {boolean} undoAvailable - * @param {boolean} redoAvailable - * @return {Promise} - */ - onUndoRedoAvailabilityChanged(undoAvailable, redoAvailable) { - return this.callApiFn( - 'onUndoRedoAvailabilityChanged', [undoAvailable, redoAvailable]); - } - - /** - * Notifies the native UI that the canvas has initialized. - * @param {boolean} success - * @return {Promise} - */ - onCanvasInitialized(success) { - return this.callApiFn('onCanvasInitialized', [success]); - } -} - -/** - * Class that implements the RequestHandler inside the Projector untrusted - * scheme for Annotator. - */ -export class UntrustedAnnotatorRequestHandler extends RequestHandler { - /** - * @param {!Window} parentWindow The embedder window from which requests - * come. - */ - constructor(parentWindow) { - super(null, TARGET_URL, TARGET_URL); - this.targetWindow_ = parentWindow; - - this.registerMethod('setTool', (args) => { - getAnnotatorElement().setTool(args[0]); - return true; - }); - - this.registerMethod('undo', () => { - getAnnotatorElement().undo(); - return true; - }); - - this.registerMethod('redo', () => { - getAnnotatorElement().redo(); - return true; - }); - - this.registerMethod('clear', () => { - getAnnotatorElement().clear(); - return true; - }); - } - - /** @override */ - targetWindow() { - return this.targetWindow_; - } -} - -/** - * This is a class that is used to setup the duplex communication channels - * between this origin, chrome-untrusted://projector/* and the embedder content. - */ -export class AnnotatorUntrustedCommFactory { - /** - * Creates the instances of PostMessageAPIClient and Requesthandler. - */ - static maybeCreateInstances() { - if (AnnotatorUntrustedCommFactory.client_ || - AnnotatorUntrustedCommFactory.requestHandler_) { - return; - } - - AnnotatorUntrustedCommFactory.client_ = - new TrustedAnnotatorClient(window.parent); - - AnnotatorUntrustedCommFactory.requestHandler_ = - new UntrustedAnnotatorRequestHandler(window.parent); - const elem = getAnnotatorElement(); - elem.addUndoRedoListener((undoAvailable, redoAvailable) => { - AnnotatorUntrustedCommFactory.client_.onUndoRedoAvailabilityChanged( - undoAvailable, redoAvailable); - }); - elem.addCanvasInitializationCallback((success) => { - AnnotatorUntrustedCommFactory.client_.onCanvasInitialized(success); - }); - } - - /** - * In order to use this class, please do the following (e.g. To notify when - * undo-redo becomes available): - * AnnotatorUntrustedCommFactory. - * getPostMessageAPIClient(). - * onUndoRedoAvailabilityChanged(true, true); - * @return {!TrustedAnnotatorClient} - */ - static getPostMessageAPIClient() { - // AnnotatorUntrustedCommFactory.client_ should be available. However to be - // on the cautious side create an instance here if getPostMessageAPIClient - // is triggered before the page finishes loading. - AnnotatorUntrustedCommFactory.maybeCreateInstances(); - return AnnotatorUntrustedCommFactory.client_; - } -} +/* @type {AnnotatorPageCallbackRouter} */ +let annotatorPageRouter = null; const observer = new MutationObserver(() => { if (getAnnotatorElement()) { - // Create instances of the singletons(PostMessageAPIClient and - // RequestHandler) when the annotator element has been added to DOM tree. - AnnotatorUntrustedCommFactory.maybeCreateInstances(); + if (annotatorPageRouter) { + // We have already registered. Therefore, return early. + return; + } + + annotatorPageRouter = browserProxy.getAnnotatorCallbackRouter(); + + // Register for callbacks from the browser process. + annotatorPageRouter.undo.addListener(() => { + try { + getAnnotatorElement().undo(); + } catch (error) { + console.error('AnnotatorToolErrorType.UNDO_ERROR', error); + } + }); + annotatorPageRouter.redo.addListener(() => { + try { + getAnnotatorElement().redo(); + } catch (error) { + console.error('AnnotatorToolErrorType.REDO_ERROR', error); + } + }); + annotatorPageRouter.clear.addListener(() => { + try { + getAnnotatorElement().clear(); + } catch (error) { + console.error('AnnotatorToolErrorType.CLEAR_ERROR', error); + } + }); + annotatorPageRouter.setTool.addListener((tool) => { + try { + getAnnotatorElement().setTool(tool); + } catch (error) { + console.error('AnnotatorToolErrorType.SET_TOOL_ERROR', error); + } + }); + + // Pass calls to the browser process. + const elem = getAnnotatorElement(); + elem.addUndoRedoListener((undoAvailable, redoAvailable) => { + browserProxy.onUndoRedoAvailabilityChanged(undoAvailable, redoAvailable); + }); + elem.addCanvasInitializationCallback((success) => { + browserProxy.onCanvasInitialized(success); + }); } });
diff --git a/ash/webui/projector_app/resources/app/trusted/projector_browser_proxy.js b/ash/webui/projector_app/resources/app/trusted/projector_browser_proxy.js index 600c9f3..05d6833 100644 --- a/ash/webui/projector_app/resources/app/trusted/projector_browser_proxy.js +++ b/ash/webui/projector_app/resources/app/trusted/projector_browser_proxy.js
@@ -3,7 +3,6 @@ // found in the LICENSE file. import {sendWithPromise} from 'chrome://resources/ash/common/cr.m.js'; -import {addSingletonGetter} from 'chrome://resources/ash/common/cr_deprecated.js'; /** * To use the browser proxy, please import this module and call @@ -125,9 +124,24 @@ } /** + * @type {ProjectorBrowserProxyImpl} + */ +let browserProxy; + +/** * @implements {ProjectorBrowserProxy} */ export class ProjectorBrowserProxyImpl { + /** + * @returns {ProjectorBrowserProxyImpl} + */ + static getInstance() { + if (!browserProxy) { + browserProxy = new ProjectorBrowserProxyImpl(); + } + return browserProxy; + } + /** @override */ getAccounts() { return sendWithPromise('getAccounts'); @@ -202,5 +216,3 @@ return sendWithPromise('getVideo', [videoFileId, resourceKey]); } } - -addSingletonGetter(ProjectorBrowserProxyImpl);
diff --git a/ash/webui/projector_app/test/mock_app_client.h b/ash/webui/projector_app/test/mock_app_client.h index 1a6b57fb..f1ca1498 100644 --- a/ash/webui/projector_app/test/mock_app_client.h +++ b/ash/webui/projector_app/test/mock_app_client.h
@@ -55,8 +55,10 @@ void(const std::string&, const std::string&, ProjectorAppClient::OnGetVideoCallback)); - MOCK_METHOD1(SetAnnotatorPageHandler, void(AnnotatorPageHandlerImpl*)); - MOCK_METHOD1(ResetAnnotatorPageHandler, void(AnnotatorPageHandlerImpl*)); + MOCK_METHOD1(SetAnnotatorPageHandler, + void(UntrustedAnnotatorPageHandlerImpl*)); + MOCK_METHOD1(ResetAnnotatorPageHandler, + void(UntrustedAnnotatorPageHandlerImpl*)); MOCK_METHOD1(SetTool, void(const AnnotatorTool&)); MOCK_METHOD0(Clear, void()); MOCK_METHOD1(NotifyAppUIActive, void(bool active));
diff --git a/ash/webui/projector_app/test/annotator_page_handler_impl_unittest.cc b/ash/webui/projector_app/test/untrusted_annotator_page_handler_impl_unittest.cc similarity index 65% rename from ash/webui/projector_app/test/annotator_page_handler_impl_unittest.cc rename to ash/webui/projector_app/test/untrusted_annotator_page_handler_impl_unittest.cc index c0ecb750..b9aaf28 100644 --- a/ash/webui/projector_app/test/annotator_page_handler_impl_unittest.cc +++ b/ash/webui/projector_app/test/untrusted_annotator_page_handler_impl_unittest.cc
@@ -2,11 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "ash/webui/projector_app/annotator_page_handler_impl.h" +#include "ash/webui/projector_app/untrusted_annotator_page_handler_impl.h" #include "ash/public/cpp/projector/annotator_tool.h" #include "ash/public/cpp/test/mock_projector_controller.h" -#include "ash/webui/projector_app/mojom/annotator.mojom.h" +#include "ash/webui/projector_app/mojom/untrusted_annotator.mojom.h" #include "ash/webui/projector_app/public/mojom/annotator_structs.mojom.h" #include "ash/webui/projector_app/test/mock_app_client.h" #include "base/test/task_environment.h" @@ -23,12 +23,14 @@ namespace { // MOCK the annotator instance in the WebUI renderer. -class MockAnnotatorPage : public annotator::mojom::AnnotatorPage { +class MockUntrustedAnnotatorPage + : public annotator::mojom::UntrustedAnnotatorPage { public: - MockAnnotatorPage() = default; - MockAnnotatorPage(const MockAnnotatorPage&) = delete; - MockAnnotatorPage& operator=(const MockAnnotatorPage&) = delete; - ~MockAnnotatorPage() override = default; + MockUntrustedAnnotatorPage() = default; + MockUntrustedAnnotatorPage(const MockUntrustedAnnotatorPage&) = delete; + MockUntrustedAnnotatorPage& operator=(const MockUntrustedAnnotatorPage&) = + delete; + ~MockUntrustedAnnotatorPage() override = default; MOCK_METHOD0(Clear, void()); MOCK_METHOD0(Undo, void()); @@ -47,32 +49,33 @@ remote_->OnCanvasInitialized(success); } - mojo::Receiver<annotator::mojom::AnnotatorPage>& receiver() { + mojo::Receiver<annotator::mojom::UntrustedAnnotatorPage>& receiver() { return receiver_; } - mojo::Remote<annotator::mojom::AnnotatorPageHandler>& remote() { + mojo::Remote<annotator::mojom::UntrustedAnnotatorPageHandler>& remote() { return remote_; } private: - mojo::Receiver<annotator::mojom::AnnotatorPage> receiver_{this}; - mojo::Remote<annotator::mojom::AnnotatorPageHandler> remote_; + mojo::Receiver<annotator::mojom::UntrustedAnnotatorPage> receiver_{this}; + mojo::Remote<annotator::mojom::UntrustedAnnotatorPageHandler> remote_; }; } // namespace -class AnnotatorPageHandlerImplTest : public testing::Test { +class UntrustedAnnotatorPageHandlerImplTest : public testing::Test { public: - AnnotatorPageHandlerImplTest() = default; - AnnotatorPageHandlerImplTest(const AnnotatorPageHandlerImplTest&) = delete; - AnnotatorPageHandlerImplTest& operator=(const AnnotatorPageHandlerImplTest&) = - delete; - ~AnnotatorPageHandlerImplTest() override = default; + UntrustedAnnotatorPageHandlerImplTest() = default; + UntrustedAnnotatorPageHandlerImplTest( + const UntrustedAnnotatorPageHandlerImplTest&) = delete; + UntrustedAnnotatorPageHandlerImplTest& operator=( + const UntrustedAnnotatorPageHandlerImplTest&) = delete; + ~UntrustedAnnotatorPageHandlerImplTest() override = default; // testing::Test: void SetUp() override { - annotator_ = std::make_unique<MockAnnotatorPage>(); - handler_ = std::make_unique<AnnotatorPageHandlerImpl>( + annotator_ = std::make_unique<MockUntrustedAnnotatorPage>(); + handler_ = std::make_unique<UntrustedAnnotatorPageHandlerImpl>( annotator().remote().BindNewPipeAndPassReceiver(), annotator().receiver().BindNewPipeAndPassRemote(), /*web_ui=*/nullptr); @@ -83,9 +86,9 @@ handler_.reset(); } - AnnotatorPageHandlerImpl& handler() { return *handler_; } + UntrustedAnnotatorPageHandlerImpl& handler() { return *handler_; } MockProjectorController& controller() { return controller_; } - MockAnnotatorPage& annotator() { return *annotator_; } + MockUntrustedAnnotatorPage& annotator() { return *annotator_; } base::test::SingleThreadTaskEnvironment& task_environment() { return task_environment_; } @@ -93,13 +96,13 @@ private: base::test::SingleThreadTaskEnvironment task_environment_; - std::unique_ptr<MockAnnotatorPage> annotator_; - std::unique_ptr<AnnotatorPageHandlerImpl> handler_; + std::unique_ptr<MockUntrustedAnnotatorPage> annotator_; + std::unique_ptr<UntrustedAnnotatorPageHandlerImpl> handler_; MockProjectorController controller_; MockAppClient client_; }; -TEST_F(AnnotatorPageHandlerImplTest, SetTool) { +TEST_F(UntrustedAnnotatorPageHandlerImplTest, SetTool) { AnnotatorTool expected_tool; expected_tool.color = SkColorSetARGB(0xA1, 0xB2, 0xC3, 0xD4); expected_tool.size = 5; @@ -115,25 +118,25 @@ annotator().FlushReceiverForTesting(); } -TEST_F(AnnotatorPageHandlerImplTest, Undo) { +TEST_F(UntrustedAnnotatorPageHandlerImplTest, Undo) { EXPECT_CALL(annotator(), Undo()); handler().Undo(); annotator().FlushReceiverForTesting(); } -TEST_F(AnnotatorPageHandlerImplTest, Redo) { +TEST_F(UntrustedAnnotatorPageHandlerImplTest, Redo) { EXPECT_CALL(annotator(), Redo()); handler().Redo(); annotator().FlushReceiverForTesting(); } -TEST_F(AnnotatorPageHandlerImplTest, Clear) { +TEST_F(UntrustedAnnotatorPageHandlerImplTest, Clear) { EXPECT_CALL(annotator(), Clear()); handler().Clear(); annotator().FlushReceiverForTesting(); } -TEST_F(AnnotatorPageHandlerImplTest, UndoRedoAvailabilityChanged) { +TEST_F(UntrustedAnnotatorPageHandlerImplTest, UndoRedoAvailabilityChanged) { EXPECT_CALL(controller(), OnUndoRedoAvailabilityChanged(false, false)); annotator().SendUndoRedoAvailableChanged(false, false); @@ -145,7 +148,7 @@ annotator().FlushRemoteForTesting(); } -TEST_F(AnnotatorPageHandlerImplTest, CanvasInitialized) { +TEST_F(UntrustedAnnotatorPageHandlerImplTest, CanvasInitialized) { EXPECT_CALL(controller(), OnCanvasInitialized(true)); annotator().SendCanvasInitialized(true);
diff --git a/ash/webui/projector_app/trusted_projector_annotator_ui.cc b/ash/webui/projector_app/trusted_projector_annotator_ui.cc deleted file mode 100644 index d8c2b3e9..0000000 --- a/ash/webui/projector_app/trusted_projector_annotator_ui.cc +++ /dev/null
@@ -1,96 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ash/webui/projector_app/trusted_projector_annotator_ui.h" - -#include "ash/public/cpp/projector/projector_annotator_controller.h" -#include "ash/webui/grit/ash_projector_annotator_trusted_resources.h" -#include "ash/webui/grit/ash_projector_annotator_trusted_resources_map.h" -#include "ash/webui/grit/ash_projector_common_resources.h" -#include "ash/webui/grit/ash_projector_common_resources_map.h" -#include "ash/webui/projector_app/annotator_page_handler_impl.h" -#include "ash/webui/projector_app/public/cpp/projector_app_constants.h" -#include "components/prefs/pref_service.h" -#include "content/public/browser/web_contents.h" -#include "content/public/browser/web_ui.h" -#include "content/public/browser/web_ui_data_source.h" -#include "content/public/common/url_constants.h" -#include "mojo/public/cpp/bindings/pending_receiver.h" -#include "services/network/public/mojom/content_security_policy.mojom.h" -#include "url/gurl.h" - -namespace ash { - -namespace { - -void CreateAndAddProjectorAnnotatorHTMLSource(content::WebUI* web_ui) { - content::WebUIDataSource* source = content::WebUIDataSource::CreateAndAdd( - web_ui->GetWebContents()->GetBrowserContext(), - kChromeUIProjectorAnnotatorHost); - - // TODO(b/216523790): Split trusted annotator resources into a separate - // bundle. - source->AddResourcePaths( - base::make_span(kAshProjectorAnnotatorTrustedResources, - kAshProjectorAnnotatorTrustedResourcesSize)); - source->AddResourcePaths(base::make_span(kAshProjectorCommonResources, - kAshProjectorCommonResourcesSize)); - source->AddResourcePath( - "", IDR_ASH_PROJECTOR_ANNOTATOR_TRUSTED_ANNOTATOR_EMBEDDER_HTML); - - std::string csp = - std::string("frame-src ") + kChromeUIUntrustedAnnotatorUrl + ";"; - // Allow use of SharedArrayBuffer (required by wasm code in the iframe guest). - source->OverrideCrossOriginOpenerPolicy("same-origin"); - source->OverrideCrossOriginEmbedderPolicy("require-corp"); - - source->OverrideContentSecurityPolicy( - network::mojom::CSPDirectiveName::FrameSrc, csp); - - source->OverrideContentSecurityPolicy( - network::mojom::CSPDirectiveName::TrustedTypes, - "trusted-types polymer-html-literal " - "polymer-template-event-attribute-policy;"); -} - -} // namespace - -TrustedProjectorAnnotatorUI::TrustedProjectorAnnotatorUI( - content::WebUI* web_ui, - const GURL& url, - PrefService* pref_service) - : MojoBubbleWebUIController(web_ui, /*enable_chrome_send=*/false) { - CreateAndAddProjectorAnnotatorHTMLSource(web_ui); - - // The Annotator and Projector SWA embed contents in a sandboxed - // chrome-untrusted:// iframe. - web_ui->AddRequestableScheme(content::kChromeUIUntrustedScheme); -} - -TrustedProjectorAnnotatorUI::~TrustedProjectorAnnotatorUI() = default; - -void TrustedProjectorAnnotatorUI::BindInterface( - mojo::PendingReceiver<annotator::mojom::AnnotatorPageHandlerFactory> - receiver) { - if (receiver_.is_bound()) { - receiver_.reset(); - } - receiver_.Bind(std::move(receiver)); -} - -void TrustedProjectorAnnotatorUI::Create( - mojo::PendingReceiver<annotator::mojom::AnnotatorPageHandler> - annotator_handler, - mojo::PendingRemote<annotator::mojom::AnnotatorPage> annotator) { - // Multiple WebUIs (and therefore TrustedProjectorAnnotatorUIs) are created - // for a single Projector recording session, so a new AnnotatorMessageHandler - // needs to be created each time and attached to the new WebUI. The new - // handler is then referenced in ProjectorClientImpl. - handler_ = std::make_unique<AnnotatorPageHandlerImpl>( - std::move(annotator_handler), std::move(annotator), web_ui()); -} - -WEB_UI_CONTROLLER_TYPE_IMPL(TrustedProjectorAnnotatorUI) - -} // namespace ash
diff --git a/ash/webui/projector_app/trusted_projector_annotator_ui.h b/ash/webui/projector_app/trusted_projector_annotator_ui.h deleted file mode 100644 index ea79b58..0000000 --- a/ash/webui/projector_app/trusted_projector_annotator_ui.h +++ /dev/null
@@ -1,57 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef ASH_WEBUI_PROJECTOR_APP_TRUSTED_PROJECTOR_ANNOTATOR_UI_H_ -#define ASH_WEBUI_PROJECTOR_APP_TRUSTED_PROJECTOR_ANNOTATOR_UI_H_ - -#include "ash/webui/projector_app/mojom/annotator.mojom.h" -#include "content/public/browser/web_ui_controller.h" -#include "mojo/public/cpp/bindings/pending_receiver.h" -#include "mojo/public/cpp/bindings/pending_remote.h" -#include "mojo/public/cpp/bindings/receiver.h" -#include "ui/webui/mojo_bubble_web_ui_controller.h" - -class GURL; -class PrefService; - -namespace ash { - -class AnnotatorPageHandlerImpl; - -// The implementation for the Projector annotator for screen recording -// annotations. -class TrustedProjectorAnnotatorUI - : public ui::MojoBubbleWebUIController, - annotator::mojom::AnnotatorPageHandlerFactory { - public: - TrustedProjectorAnnotatorUI(content::WebUI* web_ui, - const GURL& url, - PrefService* pref_service); - ~TrustedProjectorAnnotatorUI() override; - TrustedProjectorAnnotatorUI(const TrustedProjectorAnnotatorUI&) = delete; - TrustedProjectorAnnotatorUI& operator=(const TrustedProjectorAnnotatorUI&) = - delete; - - void BindInterface( - mojo::PendingReceiver<annotator::mojom::AnnotatorPageHandlerFactory> - factory); - - private: - WEB_UI_CONTROLLER_TYPE_DECL(); - - // annotator::mojom::AnnotatorPageHandlerFactory: - void Create( - mojo::PendingReceiver<annotator::mojom::AnnotatorPageHandler> - annotator_handler, - mojo::PendingRemote<annotator::mojom::AnnotatorPage> annotator) override; - - mojo::Receiver<annotator::mojom::AnnotatorPageHandlerFactory> receiver_{this}; - - // Handler for requests coming from the web_ui. - std::unique_ptr<AnnotatorPageHandlerImpl> handler_; -}; - -} // namespace ash - -#endif // ASH_WEBUI_PROJECTOR_APP_TRUSTED_PROJECTOR_ANNOTATOR_UI_H_
diff --git a/ash/webui/projector_app/annotator_page_handler_impl.cc b/ash/webui/projector_app/untrusted_annotator_page_handler_impl.cc similarity index 67% rename from ash/webui/projector_app/annotator_page_handler_impl.cc rename to ash/webui/projector_app/untrusted_annotator_page_handler_impl.cc index 4beb9ec3..3328a30b1 100644 --- a/ash/webui/projector_app/annotator_page_handler_impl.cc +++ b/ash/webui/projector_app/untrusted_annotator_page_handler_impl.cc
@@ -2,13 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "ash/webui/projector_app/annotator_page_handler_impl.h" +#include "ash/webui/projector_app/untrusted_annotator_page_handler_impl.h" #include <memory> #include "ash/public/cpp/projector/annotator_tool.h" #include "ash/public/cpp/projector/projector_controller.h" -#include "ash/webui/projector_app/mojom/annotator.mojom.h" +#include "ash/webui/projector_app/mojom/untrusted_annotator.mojom.h" #include "ash/webui/projector_app/projector_app_client.h" #include "ash/webui/projector_app/public/mojom/annotator_structs.mojom.h" #include "base/check.h" @@ -18,10 +18,10 @@ namespace ash { -AnnotatorPageHandlerImpl::AnnotatorPageHandlerImpl( - mojo::PendingReceiver<annotator::mojom::AnnotatorPageHandler> +UntrustedAnnotatorPageHandlerImpl::UntrustedAnnotatorPageHandlerImpl( + mojo::PendingReceiver<annotator::mojom::UntrustedAnnotatorPageHandler> annotator_handler, - mojo::PendingRemote<annotator::mojom::AnnotatorPage> annotator, + mojo::PendingRemote<annotator::mojom::UntrustedAnnotatorPage> annotator, content::WebUI* web_ui) : annotator_remote_(std::move(annotator)), annotator_handler_receiver_(this, std::move(annotator_handler)), @@ -29,11 +29,11 @@ ProjectorAppClient::Get()->SetAnnotatorPageHandler(this); } -AnnotatorPageHandlerImpl::~AnnotatorPageHandlerImpl() { +UntrustedAnnotatorPageHandlerImpl::~UntrustedAnnotatorPageHandlerImpl() { ProjectorAppClient::Get()->ResetAnnotatorPageHandler(this); } -void AnnotatorPageHandlerImpl::SetTool(const AnnotatorTool& tool) { +void UntrustedAnnotatorPageHandlerImpl::SetTool(const AnnotatorTool& tool) { auto mojo_tool = annotator::mojom::AnnotatorTool::New(); mojo_tool->color = tool.GetColorHexString(); mojo_tool->tool = tool.GetToolString(); @@ -41,19 +41,19 @@ annotator_remote_->SetTool(std::move(mojo_tool)); } -void AnnotatorPageHandlerImpl::Undo() { +void UntrustedAnnotatorPageHandlerImpl::Undo() { annotator_remote_->Undo(); } -void AnnotatorPageHandlerImpl::Redo() { +void UntrustedAnnotatorPageHandlerImpl::Redo() { annotator_remote_->Redo(); } -void AnnotatorPageHandlerImpl::Clear() { +void UntrustedAnnotatorPageHandlerImpl::Clear() { annotator_remote_->Clear(); } -void AnnotatorPageHandlerImpl::OnUndoRedoAvailabilityChanged( +void UntrustedAnnotatorPageHandlerImpl::OnUndoRedoAvailabilityChanged( bool undo_available, bool redo_available) { // ProjectorController is created when ash::Shell::Init is called and is @@ -63,20 +63,11 @@ redo_available); } -void AnnotatorPageHandlerImpl::OnCanvasInitialized(bool success) { +void UntrustedAnnotatorPageHandlerImpl::OnCanvasInitialized(bool success) { // ProjectorController is created when ash::Shell::Init is called and is // destroyed when ash::Shell is destroyed. Therefore, ProjectorController // is available when this WebUI is showing. ProjectorController::Get()->OnCanvasInitialized(success); } -void AnnotatorPageHandlerImpl::OnError( - const std::vector<std::string>& messages) { - for (const auto& message : messages) { - LOG(ERROR) << message; - } - - // TODO(b/239979179): Consider reloading the webcontent. -} - } // namespace ash
diff --git a/ash/webui/projector_app/untrusted_annotator_page_handler_impl.h b/ash/webui/projector_app/untrusted_annotator_page_handler_impl.h new file mode 100644 index 0000000..9f194f0 --- /dev/null +++ b/ash/webui/projector_app/untrusted_annotator_page_handler_impl.h
@@ -0,0 +1,66 @@ +// 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_WEBUI_PROJECTOR_APP_UNTRUSTED_ANNOTATOR_PAGE_HANDLER_IMPL_H_ +#define ASH_WEBUI_PROJECTOR_APP_UNTRUSTED_ANNOTATOR_PAGE_HANDLER_IMPL_H_ + +#include "ash/public/cpp/projector/projector_annotator_controller.h" +#include "ash/webui/projector_app/mojom/untrusted_annotator.mojom.h" +#include "base/functional/callback.h" +#include "base/values.h" +#include "mojo/public/cpp/bindings/pending_receiver.h" +#include "mojo/public/cpp/bindings/pending_remote.h" +#include "mojo/public/cpp/bindings/receiver.h" +#include "mojo/public/cpp/bindings/remote.h" + +namespace content { +class WebUI; +} // namespace content + +namespace ash { + +struct AnnotatorTool; + +// Handles communication with the Annotator WebUI (i.e. +// chrome-untrusted://projector/annotator/annotator_embedder.html) +class UntrustedAnnotatorPageHandlerImpl + : public annotator::mojom::UntrustedAnnotatorPageHandler { + public: + UntrustedAnnotatorPageHandlerImpl( + mojo::PendingReceiver<annotator::mojom::UntrustedAnnotatorPageHandler> + annotator_handler, + mojo::PendingRemote<annotator::mojom::UntrustedAnnotatorPage> annotator, + content::WebUI* web_ui); + UntrustedAnnotatorPageHandlerImpl(const UntrustedAnnotatorPageHandlerImpl&) = + delete; + UntrustedAnnotatorPageHandlerImpl& operator=( + const UntrustedAnnotatorPageHandlerImpl&) = delete; + ~UntrustedAnnotatorPageHandlerImpl() override; + + // Called by ProjectorAppClient. + void SetTool(const AnnotatorTool& tool); + void Undo(); + void Redo(); + void Clear(); + + // annotator::mojom::AnnotatorHandler: + void OnUndoRedoAvailabilityChanged(bool undo_available, + bool redo_available) override; + void OnCanvasInitialized(bool success) override; + + content::WebUI* get_web_ui_for_test() { return web_ui_; } + + private: + mojo::Remote<annotator::mojom::UntrustedAnnotatorPage> annotator_remote_; + mojo::Receiver<annotator::mojom::UntrustedAnnotatorPageHandler> + annotator_handler_receiver_; + + // The WebUI that owns the TrustedProjectorAnnotatorUI that owns this + // instance. + content::WebUI* const web_ui_; +}; + +} // namespace ash + +#endif // ASH_WEBUI_PROJECTOR_APP_UNTRUSTED_ANNOTATOR_PAGE_HANDLER_IMPL_H_
diff --git a/ash/webui/projector_app/untrusted_projector_annotator_ui.cc b/ash/webui/projector_app/untrusted_projector_annotator_ui.cc index 10bab51d..3cb065d 100644 --- a/ash/webui/projector_app/untrusted_projector_annotator_ui.cc +++ b/ash/webui/projector_app/untrusted_projector_annotator_ui.cc
@@ -10,6 +10,7 @@ #include "ash/webui/grit/ash_projector_common_resources_map.h" #include "ash/webui/media_app_ui/buildflags.h" #include "ash/webui/projector_app/public/cpp/projector_app_constants.h" +#include "ash/webui/projector_app/untrusted_annotator_page_handler_impl.h" #include "chromeos/grit/chromeos_projector_app_bundle_resources.h" #include "chromeos/grit/chromeos_projector_app_bundle_resources_map.h" #include "content/public/browser/web_contents.h" @@ -87,9 +88,6 @@ // Loading WASM in chrome-untrusted://projector-annotator/annotator/ink.js is // not compatible with trusted types. source->DisableTrustedTypesCSP(); - - source->AddFrameAncestor(GURL(kChromeUITrustedAnnotatorUrl)); - delegate->PopulateLoadTimeData(source); source->UseStringsJs(); } @@ -105,4 +103,23 @@ UntrustedProjectorAnnotatorUI::~UntrustedProjectorAnnotatorUI() = default; +void UntrustedProjectorAnnotatorUI::BindInterface( + mojo::PendingReceiver< + annotator::mojom::UntrustedAnnotatorPageHandlerFactory> factory) { + if (receiver_.is_bound()) { + receiver_.reset(); + } + receiver_.Bind(std::move(factory)); +} + +void UntrustedProjectorAnnotatorUI::Create( + mojo::PendingReceiver<annotator::mojom::UntrustedAnnotatorPageHandler> + annotator_handler, + mojo::PendingRemote<annotator::mojom::UntrustedAnnotatorPage> annotator) { + handler_ = std::make_unique<UntrustedAnnotatorPageHandlerImpl>( + std::move(annotator_handler), std::move(annotator), web_ui()); +} + +WEB_UI_CONTROLLER_TYPE_IMPL(UntrustedProjectorAnnotatorUI) + } // namespace ash
diff --git a/ash/webui/projector_app/untrusted_projector_annotator_ui.h b/ash/webui/projector_app/untrusted_projector_annotator_ui.h index ead7586e..3616ac5 100644 --- a/ash/webui/projector_app/untrusted_projector_annotator_ui.h +++ b/ash/webui/projector_app/untrusted_projector_annotator_ui.h
@@ -5,6 +5,10 @@ #ifndef ASH_WEBUI_PROJECTOR_APP_UNTRUSTED_PROJECTOR_ANNOTATOR_UI_H_ #define ASH_WEBUI_PROJECTOR_APP_UNTRUSTED_PROJECTOR_ANNOTATOR_UI_H_ +#include "ash/webui/projector_app/mojom/untrusted_annotator.mojom.h" +#include "mojo/public/cpp/bindings/pending_receiver.h" +#include "mojo/public/cpp/bindings/pending_remote.h" +#include "mojo/public/cpp/bindings/receiver.h" #include "ui/webui/untrusted_web_ui_controller.h" namespace content { @@ -13,6 +17,8 @@ namespace ash { +class UntrustedAnnotatorPageHandlerImpl; + // A delegate used during data source creation to expose some //chrome // functionality to the data source class UntrustedProjectorAnnotatorUIDelegate { @@ -23,7 +29,9 @@ }; // The webui for chrome-untrusted://projector-annotator. -class UntrustedProjectorAnnotatorUI : public ui::UntrustedWebUIController { +class UntrustedProjectorAnnotatorUI + : public ui::UntrustedWebUIController, + public annotator::mojom::UntrustedAnnotatorPageHandlerFactory { public: // UntrustedProjectorAnnotatorUI does not store the passed in // `UntrustedProjectorAnnotatorUIDelegate`. @@ -34,6 +42,26 @@ UntrustedProjectorAnnotatorUI& operator=( const UntrustedProjectorAnnotatorUI&) = delete; ~UntrustedProjectorAnnotatorUI() override; + + void BindInterface( + mojo::PendingReceiver< + annotator::mojom::UntrustedAnnotatorPageHandlerFactory> factory); + + private: + // annotator::mojom::UntrustedAnnotatorPageHandlerFactory: + void Create( + mojo::PendingReceiver<annotator::mojom::UntrustedAnnotatorPageHandler> + annotator_handler, + mojo::PendingRemote<annotator::mojom::UntrustedAnnotatorPage> annotator) + override; + + mojo::Receiver<annotator::mojom::UntrustedAnnotatorPageHandlerFactory> + receiver_{this}; + + // Handler for requests coming from the web_ui. + std::unique_ptr<UntrustedAnnotatorPageHandlerImpl> handler_; + + WEB_UI_CONTROLLER_TYPE_DECL(); }; } // namespace ash
diff --git a/ash/webui/resources/BUILD.gn b/ash/webui/resources/BUILD.gn index 04dd34df..f162d1f 100644 --- a/ash/webui/resources/BUILD.gn +++ b/ash/webui/resources/BUILD.gn
@@ -330,14 +330,6 @@ deps = [ "//ash/webui/projector_app/resources/annotator/untrusted:build_untrusted_grd" ] } -# Resources used by chrome://projector-annotator SWA. -ash_generated_grit("projector_annotator_trusted_resources") { - source = "$root_gen_dir/ash/webui/projector_app/resources/annotator/trusted/ash_projector_annotator_trusted_resources.grd" - deps = [ - "//ash/webui/projector_app/resources/annotator/trusted:build_trusted_grd", - ] -} - # Resources used by chrome://projector and chrome://projector-annotator SWA. ash_generated_grit("projector_common_resources") { source = "$root_gen_dir/ash/webui/projector_app/resources/common/ash_projector_common_resources.grd"
diff --git a/ash/webui/shortcut_customization_ui/backend/accelerator_configuration_provider.cc b/ash/webui/shortcut_customization_ui/backend/accelerator_configuration_provider.cc index b73522c..4e80071 100644 --- a/ash/webui/shortcut_customization_ui/backend/accelerator_configuration_provider.cc +++ b/ash/webui/shortcut_customization_ui/backend/accelerator_configuration_provider.cc
@@ -42,6 +42,25 @@ using ::ash::shortcut_customization::mojom::SimpleAccelerator; using ::ash::shortcut_customization::mojom::SimpleAcceleratorPtr; using mojom::AcceleratorConfigResult; +using HiddenAcceleratorMap = + std::map<AcceleratorActionId, std::vector<ui::Accelerator>>; + +// Raw accelerator data may result in the same shortcut being displayed multiple +// times in the frontend. GetHiddenAcceleratorMap() is used to collect such +// accelerators and hide them from display. +const HiddenAcceleratorMap& GetHiddenAcceleratorMap() { + static auto hiddenAcceleratorMap = base::NoDestructor<HiddenAcceleratorMap>( + {{TOGGLE_APP_LIST, + {ui::Accelerator(ui::VKEY_BROWSER_SEARCH, ui::EF_NONE, + ui::Accelerator::KeyState::PRESSED), + ui::Accelerator(ui::VKEY_BROWSER_SEARCH, ui::EF_SHIFT_DOWN, + ui::Accelerator::KeyState::PRESSED), + ui::Accelerator(ui::VKEY_LWIN, ui::EF_NONE, + ui::Accelerator::KeyState::RELEASED), + ui::Accelerator(ui::VKEY_LWIN, ui::EF_SHIFT_DOWN, + ui::Accelerator::KeyState::RELEASED)}}}); + return *hiddenAcceleratorMap; +} // Gets the parts of the string that don't contain replacements. // Ex: "Press and " -> ["Press ", " and "] @@ -126,6 +145,17 @@ return result; } +bool IsAcceleratorHidden(AcceleratorActionId action_id, + const ui::Accelerator& accelerator) { + const auto& iter = GetHiddenAcceleratorMap().find(action_id); + if (iter == GetHiddenAcceleratorMap().end()) { + return false; + } + const std::vector<ui::Accelerator>& hidden_accelerators = iter->second; + return std::find(hidden_accelerators.begin(), hidden_accelerators.end(), + accelerator) != hidden_accelerators.end(); +} + mojom::StandardAcceleratorPropertiesPtr CreateStandardAcceleratorProps( const ui::Accelerator& accelerator) { return mojom::StandardAcceleratorProperties::New( @@ -535,6 +565,9 @@ } for (const auto& accelerator : accelerators) { + if (IsAcceleratorHidden(layout_info.action_id, accelerator)) { + continue; + } // TODO(jimmyxgong): Check pref storage to determine whether the // AcceleratorType was user-added or default. CreateAndAppendAliasedAccelerators(
diff --git a/ash/webui/shortcut_customization_ui/backend/accelerator_configuration_provider_unittest.cc b/ash/webui/shortcut_customization_ui/backend/accelerator_configuration_provider_unittest.cc index 35134b1..28cdebf 100644 --- a/ash/webui/shortcut_customization_ui/backend/accelerator_configuration_provider_unittest.cc +++ b/ash/webui/shortcut_customization_ui/backend/accelerator_configuration_provider_unittest.cc
@@ -533,6 +533,44 @@ ValidateAcceleratorLayouts(provider_->GetAcceleratorLayoutInfos()); } +TEST_F(AcceleratorConfigurationProviderTest, FilterOutHiddenAccelerators) { + FakeAcceleratorsUpdatedMojoObserver mojo_observer; + SetUpObserver(&mojo_observer); + EXPECT_EQ(0, mojo_observer.num_times_notified()); + EXPECT_EQ(0, observer_.num_times_notified()); + + const AcceleratorData test_data[] = { + {/*trigger_on_press=*/true, ui::VKEY_TAB, ui::EF_ALT_DOWN, + CYCLE_FORWARD_MRU}, + {/*trigger_on_press=*/true, ui::VKEY_ESCAPE, ui::EF_COMMAND_DOWN, + SHOW_TASK_MANAGER}, + // Accelerators that should be hidden from display. + {/*trigger_on_press=*/true, ui::VKEY_BROWSER_SEARCH, ui::EF_NONE, + TOGGLE_APP_LIST}, + {/*trigger_on_press=*/true, ui::VKEY_BROWSER_SEARCH, ui::EF_SHIFT_DOWN, + TOGGLE_APP_LIST}, + {/*trigger_on_press=*/false, ui::VKEY_LWIN, ui::EF_NONE, TOGGLE_APP_LIST}, + {/*trigger_on_press=*/false, ui::VKEY_LWIN, ui::EF_SHIFT_DOWN, + TOGGLE_APP_LIST}, + }; + + // Initialize with a set of accelerators that include hidden accelerators. + Shell::Get()->ash_accelerator_configuration()->Initialize(test_data); + base::RunLoop().RunUntilIdle(); + + const AcceleratorData expected_test_data[]{ + {/*trigger_on_press=*/true, ui::VKEY_TAB, ui::EF_ALT_DOWN, + CYCLE_FORWARD_MRU}, + {/*trigger_on_press=*/true, ui::VKEY_ESCAPE, ui::EF_COMMAND_DOWN, + SHOW_TASK_MANAGER}, + }; + EXPECT_EQ(1, observer_.num_times_notified()); + + // Verify observer won't receive hidden accelerators. + ExpectMojomAcceleratorsEqual(mojom::AcceleratorSource::kAsh, + expected_test_data, mojo_observer.config()); +} + TEST_F(AcceleratorConfigurationProviderTest, TopRowKeyAcceleratorRemapped) { // Add a fake layout2 keyboard. ui::InputDevice fake_keyboard(
diff --git a/ash/webui/shortcut_customization_ui/resources/js/accelerator_row.ts b/ash/webui/shortcut_customization_ui/resources/js/accelerator_row.ts index ada8008..08076fa 100644 --- a/ash/webui/shortcut_customization_ui/resources/js/accelerator_row.ts +++ b/ash/webui/shortcut_customization_ui/resources/js/accelerator_row.ts
@@ -9,14 +9,14 @@ import 'chrome://resources/cr_elements/cr_input/cr_input.js'; import 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js'; -import {assert} from 'chrome://resources/js/assert_ts.js'; import {PolymerElementProperties} from 'chrome://resources/polymer/v3_0/polymer/interfaces.js'; import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {getTemplate} from './accelerator_row.html.js'; import {getShortcutProvider} from './mojo_interface_provider.js'; -import {AcceleratorInfo, AcceleratorSource, LayoutStyle, ShortcutProviderInterface, TextAcceleratorPart} from './shortcut_types.js'; -import {isCustomizationDisabled, isTextAcceleratorInfo} from './shortcut_utils.js'; +import {AcceleratorInfo, AcceleratorSource, LayoutStyle, ShortcutProviderInterface, TextAcceleratorInfo, TextAcceleratorPart} from './shortcut_types.js'; +import {isCustomizationDisabled} from './shortcut_utils.js'; +import {TextAcceleratorElement} from './text_accelerator.js'; export type ShowEditDialogEvent = CustomEvent<{ description: string, @@ -138,14 +138,9 @@ )); } - protected getTextAcceleratorParts(info: AcceleratorInfo[]): + protected getTextAcceleratorParts(infos: TextAcceleratorInfo[]): TextAcceleratorPart[] { - // For text based layout accelerators, we always expect this to be an array - // with a single element. - assert(info.length === 1); - const textAcceleratorInfo = info[0]; - assert(isTextAcceleratorInfo(textAcceleratorInfo)); - return textAcceleratorInfo.layoutProperties.textAccelerator.parts; + return TextAcceleratorElement.getTextAcceleratorParts(infos); } static get template(): HTMLTemplateElement {
diff --git a/ash/webui/shortcut_customization_ui/resources/js/fake_data.ts b/ash/webui/shortcut_customization_ui/resources/js/fake_data.ts index 72e1ea2..a442b6ce 100644 --- a/ash/webui/shortcut_customization_ui/resources/js/fake_data.ts +++ b/ash/webui/shortcut_customization_ui/resources/js/fake_data.ts
@@ -12,7 +12,7 @@ internalValue: BigInt(0), }; -const newTabAccelerator: MojoAcceleratorInfo = { +const newTabAcceleratorInfo: MojoAcceleratorInfo = { type: AcceleratorType.kDefault, state: AcceleratorState.kEnabled, locked: true, @@ -31,7 +31,7 @@ }, }; -const cycleTabsAccelerator: MojoAcceleratorInfo = { +const cycleTabsAcceleratorInfo: MojoAcceleratorInfo = { type: AcceleratorType.kDefault, state: AcceleratorState.kEnabled, locked: true, @@ -145,15 +145,15 @@ // TODO(michaelcheco): Separate Browser and Ambient accelerators. [AcceleratorSource.kAmbient]: { // New Tab - [0]: [newTabAccelerator], - [1]: [cycleTabsAccelerator], + [0]: [newTabAcceleratorInfo], + [1]: [cycleTabsAcceleratorInfo], }, }; export const fakeAmbientConfig: MojoAcceleratorConfig = { [AcceleratorSource.kAmbient]: { - [0]: [newTabAccelerator], - [1]: [cycleTabsAccelerator], + [0]: [newTabAcceleratorInfo], + [1]: [cycleTabsAcceleratorInfo], }, }; @@ -298,6 +298,19 @@ export const SnapWindowLeftSearchResult: MojoSearchResult = fakeSearchResults[0]; +export const CycleTabsTextSearchResult: MojoSearchResult = { + acceleratorLayoutInfo: { + category: AcceleratorCategory.kGeneral, + subCategory: AcceleratorSubcategory.kApps, + description: stringToMojoString16('Click or tap shelf icons 1-8'), + style: LayoutStyle.kText, + source: AcceleratorSource.kAsh, + action: 1, + }, + acceleratorInfos: [cycleTabsAcceleratorInfo], + relevanceScore: 0.95, +}; + // The following code is used to add fake accelerator entries for each icon. // When useFakeProvider is true, this will display all available icons for // the purposes of debugging.
diff --git a/ash/webui/shortcut_customization_ui/resources/js/input_key.html b/ash/webui/shortcut_customization_ui/resources/js/input_key.html index 1b1b460..d3fcd20 100644 --- a/ash/webui/shortcut_customization_ui/resources/js/input_key.html +++ b/ash/webui/shortcut_customization_ui/resources/js/input_key.html
@@ -12,6 +12,11 @@ padding-inline: 8px; } + :host([narrow]) .key-container { + margin-inline-end: 4px; + padding-inline: 4px; + } + #key-text { color: var(--cros-text-color-secondary); } @@ -35,6 +40,18 @@ box-shadow: 0 1px 1px var(--cros-bg-color-dropped-elevation-1); } + :host([highlighted][key-state='modifier-selected']) div.key-container { + background-color: var(--cros-color-prominent); + } + + :host([highlighted][key-state='modifier-selected']) #key-text { + color: var(--cros-button-label-color-primary); + } + + :host([highlighted][key-state='alpha-numeric-selected']) div.key-container { + background-color: var(--cros-bg-color); + } + :host(#ctrlKey) .key-container, :host(#altKey) .key-container, :host(#shiftKey) .key-container,
diff --git a/ash/webui/shortcut_customization_ui/resources/js/input_key.ts b/ash/webui/shortcut_customization_ui/resources/js/input_key.ts index 6f0c7c9..79c9ccc 100644 --- a/ash/webui/shortcut_customization_ui/resources/js/input_key.ts +++ b/ash/webui/shortcut_customization_ui/resources/js/input_key.ts
@@ -94,11 +94,29 @@ value: KeyInputState.NOT_SELECTED, reflectToAttribute: true, }, + + // If this property is true, the spacing between keys will be narrower + // than usual. + narrow: { + type: Boolean, + value: false, + reflectToAttribute: true, + }, + + // If this property is true, keys will be styled with the bolder highlight + // background. + highlighted: { + type: Boolean, + value: false, + reflectToAttribute: true, + }, }; } key: string; keyState: KeyInputState; + narrow: boolean; + highlighted: boolean; private lookupManager: AcceleratorLookupManager = AcceleratorLookupManager.getInstance();
diff --git a/ash/webui/shortcut_customization_ui/resources/js/search/search_box.html b/ash/webui/shortcut_customization_ui/resources/js/search/search_box.html index 5b491db..fc5f529 100644 --- a/ash/webui/shortcut_customization_ui/resources/js/search/search_box.html +++ b/ash/webui/shortcut_customization_ui/resources/js/search/search_box.html
@@ -2,6 +2,8 @@ :host { --cr-toolbar-search-field-background: var(--cros-toolbar-search-bg-color); + --cr-toolbar-icon-container-size: 32px; + --cr-toolbar-icon-margin: 8px 16px; --separator-height: 8px; -webkit-tap-highlight-color: transparent; @@ -56,7 +58,7 @@ border-radius: 0 0 20px 20px; box-shadow: var(--cr-elevation-3); display: table; - padding-bottom: 8px; + padding-bottom: 16px; width: var(--cr-toolbar-field-width); }
diff --git a/ash/webui/shortcut_customization_ui/resources/js/search/search_result_row.html b/ash/webui/shortcut_customization_ui/resources/js/search/search_result_row.html index 0e94abd..611fa9cf 100644 --- a/ash/webui/shortcut_customization_ui/resources/js/search/search_result_row.html +++ b/ash/webui/shortcut_customization_ui/resources/js/search/search_result_row.html
@@ -13,23 +13,65 @@ #searchResultRow { align-items: center; + cursor: pointer; display: flex; height: 48px; justify-content: center; } - #searchResultText { + #searchResultRowInner { align-items: center; display: flex; - flex-grow: 1; + flex-direction: row; height: 100%; - padding-inline-start: 24px; + padding-inline-start: 16px; + width: 100%; + } + + #description { + /* Fade out long descriptions. */ + -webkit-mask-image: linear-gradient(to left, transparent, white 32px); + flex: 1; + margin-inline-end: 16px; + overflow: hidden; + white-space: nowrap; + } + + #accelerators { + /* Fade out long accelerators. */ + -webkit-mask-image: linear-gradient(to left, transparent, white 32px); + align-items: center; + display: flex; + flex: 1; + height: 100%; + overflow: hidden; + } + + #actionIcon { + margin: var(--cr-toolbar-icon-margin); + width: var(--cr-toolbar-icon-container-size); } </style> <div id="searchResultRow" focus-row-container> - <div id="searchResultText" aria-disabled="true" selectable focus-row-control - focus-type="rowWrapper"> - [[getSearchResultText(searchResult)]] - </div> + <div focus-row-control + focus-type="rowWrapper" + id="searchResultRowInner" + aria-disabled="true" + selectable> + <div id="description">[[getSearchResultDescription(searchResult)]]</div> + <div id="accelerators"> + <template is="dom-if" if="[[isDefaultLayout(searchResult)]]"> + <!-- TODO(cambickel) Add standard accelerator keys here. --> + <div></div> + </template> + <template is="dom-if" if="[[isTextLayout(searchResult)]]"> + <text-accelerator parts="[[getTextAcceleratorParts(searchResult)]]" + highlighted="[[selected]]" narrow> + </text-accelerator> + </template> + <div id="gradient"></div> + </div> + <iron-icon id="actionIcon" icon="cr:arrow-forward"></iron-icon> + </div> </div>
diff --git a/ash/webui/shortcut_customization_ui/resources/js/search/search_result_row.ts b/ash/webui/shortcut_customization_ui/resources/js/search/search_result_row.ts index 878c43e..387306d 100644 --- a/ash/webui/shortcut_customization_ui/resources/js/search/search_result_row.ts +++ b/ash/webui/shortcut_customization_ui/resources/js/search/search_result_row.ts
@@ -2,13 +2,17 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. import 'chrome://resources/cr_elements/cr_shared_style.css.js'; +import '../text_accelerator.js'; import {FocusRowMixin} from 'chrome://resources/cr_elements/focus_row_mixin.js'; +import {assert} from 'chrome://resources/js/assert_ts.js'; import {PolymerElementProperties} from 'chrome://resources/polymer/v3_0/polymer/interfaces.js'; import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; -import {MojoSearchResult} from 'js/shortcut_types.js'; import {mojoString16ToString} from '../mojo_utils.js'; +import {LayoutStyle, MojoSearchResult, TextAcceleratorInfo, TextAcceleratorPart} from '../shortcut_types.js'; +import {isTextAcceleratorInfo} from '../shortcut_utils.js'; +import {TextAcceleratorElement} from '../text_accelerator.js'; import {getTemplate} from './search_result_row.html.js'; @@ -26,7 +30,6 @@ static get properties(): PolymerElementProperties { return { - // TODO(longbowei): This is an incomplete type. Update it in the future. searchResult: { type: Object, }, @@ -42,13 +45,28 @@ searchResult: MojoSearchResult; selected: boolean; - private getSearchResultText(): string { + static get template(): HTMLTemplateElement { + return getTemplate(); + } + + private getSearchResultDescription(): string { return mojoString16ToString( this.searchResult.acceleratorLayoutInfo.description); } - static get template(): HTMLTemplateElement { - return getTemplate(); + private isDefaultLayout(): boolean { + return this.searchResult.acceleratorLayoutInfo.style === + LayoutStyle.kDefault; + } + + private isTextLayout(): boolean { + return !this.isDefaultLayout(); + } + + private getTextAcceleratorParts(): TextAcceleratorPart[] { + assert(isTextAcceleratorInfo(this.searchResult.acceleratorInfos[0])); + return TextAcceleratorElement.getTextAcceleratorParts( + this.searchResult.acceleratorInfos as TextAcceleratorInfo[]); } }
diff --git a/ash/webui/shortcut_customization_ui/resources/js/text_accelerator.html b/ash/webui/shortcut_customization_ui/resources/js/text_accelerator.html index 32df5f5..a4d4ded7 100644 --- a/ash/webui/shortcut_customization_ui/resources/js/text_accelerator.html +++ b/ash/webui/shortcut_customization_ui/resources/js/text_accelerator.html
@@ -3,6 +3,10 @@ margin-inline-end: 8px; } + :host([narrow]) .spacing { + margin-inline-end: 4px; + } + #text-wrapper { align-items: center; display: flex; @@ -15,6 +19,11 @@ flex-wrap: wrap; } + :host([narrow]) .parts-container { + flex-wrap: nowrap; + white-space: nowrap; + } + iron-icon { --iron-icon-width: 16px; }
diff --git a/ash/webui/shortcut_customization_ui/resources/js/text_accelerator.ts b/ash/webui/shortcut_customization_ui/resources/js/text_accelerator.ts index ca0a969b..5ee831ab 100644 --- a/ash/webui/shortcut_customization_ui/resources/js/text_accelerator.ts +++ b/ash/webui/shortcut_customization_ui/resources/js/text_accelerator.ts
@@ -5,14 +5,15 @@ import './input_key.js'; import 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js'; +import {assert} from 'chrome://resources/js/assert_ts.js'; import {IronIconElement} from 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js'; import {PolymerElementProperties} from 'chrome://resources/polymer/v3_0/polymer/interfaces.js'; import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {InputKeyElement, KeyInputState} from './input_key.js'; import {mojoString16ToString} from './mojo_utils.js'; -import {TextAcceleratorPart, TextAcceleratorPartType} from './shortcut_types.js'; -import {isCustomizationDisabled} from './shortcut_utils.js'; +import {TextAcceleratorInfo, TextAcceleratorPart, TextAcceleratorPartType} from './shortcut_types.js'; +import {isCustomizationDisabled, isTextAcceleratorInfo} from './shortcut_utils.js'; import {getTemplate} from './text_accelerator.html.js'; /** @@ -32,10 +33,40 @@ type: Array, observer: TextAcceleratorElement.prototype.parseAndDisplayTextParts, }, + + // If this property is true, the spacing between keys will be narrower + // than usual. + narrow: { + type: Boolean, + value: false, + reflectToAttribute: true, + }, + + // If this property is true, keys will be styled with the bolder highlight + // background. + highlighted: { + type: Boolean, + value: false, + // Update the parts when the highlighted status changes so their style + // can be updated. + observer: TextAcceleratorElement.prototype.parseAndDisplayTextParts, + }, }; } parts: TextAcceleratorPart[]; + narrow: boolean; + highlighted: boolean; + + static getTextAcceleratorParts(info: TextAcceleratorInfo[]): + TextAcceleratorPart[] { + // For text based layout accelerators, we always expect this to be an array + // with a single element. + assert(info.length === 1); + const textAcceleratorInfo = info[0]; + assert(isTextAcceleratorInfo(textAcceleratorInfo)); + return textAcceleratorInfo.layoutProperties.textAccelerator.parts; + } private parseAndDisplayTextParts(): void { const container = @@ -72,6 +103,8 @@ const key = document.createElement('input-key'); key.key = keyText; key.keyState = keyState; + key.narrow = this.narrow; + key.highlighted = this.highlighted; return key; }
diff --git a/ash/wm/desks/desk.cc b/ash/wm/desks/desk.cc index 1f55151..ae3b32d 100644 --- a/ash/wm/desks/desk.cc +++ b/ash/wm/desks/desk.cc
@@ -395,8 +395,21 @@ auto* desks_controller = DesksController::Get(); if (!is_desk_being_removed_ && !desks_util::IsWindowVisibleOnAllWorkspaces(window)) { - window->SetProperty(aura::client::kWindowWorkspaceKey, - desks_controller->GetDeskIndex(this)); + // Setting the property for `kWindowWorkspaceKey` or + // `kDeskGuidKey` will trigger a save for the window state. To + // avoid doing this twice, we tell the window state to hold off on saving + // until we save the `kDeskGuidKey` value. + // TODO(b/265490703): We should eventually clean up this and + // `GetScopedIgnorePropertyChange` when unit tests no longer need this + // scoping to prevent double saves. + { + auto scoped_ignore_property_changes = + WindowState::Get(window)->GetScopedIgnorePropertyChange(); + window->SetProperty(aura::client::kWindowWorkspaceKey, + desks_controller->GetDeskIndex(this)); + } + + window->SetProperty(kDeskGuidKey, uuid_.AsLowercaseString()); } MaybeIncrementWeeklyActiveDesks();
diff --git a/ash/wm/desks/desks_controller.cc b/ash/wm/desks/desks_controller.cc index 06b352f..00cfa1c 100644 --- a/ash/wm/desks/desks_controller.cc +++ b/ash/wm/desks/desks_controller.cc
@@ -298,6 +298,7 @@ .enabled()), source_(source), desk_close_type_(type) { + full_restore::SaveRemovingDeskGuid(desk_->uuid()); desk_->set_is_desk_being_removed(true); } @@ -312,6 +313,7 @@ toast_manager->Cancel(toast_id_); DesksController::Get()->FinalizeDeskRemoval(this); } + full_restore::ResetRemovingDeskGuid(); } const std::string& toast_id() const { return toast_id_; } @@ -1698,6 +1700,10 @@ } // Keep the removed desk's data alive until at least the end of this function. + // `MaybeCommitPendingDeskRemoval` at this point should have cleared + // `temporary_removed_desk_`. Otherwise, we may be resetting the wrong + // removing desk GUID in restore data. + CHECK(!temporary_removed_desk_); auto temporary_removed_desk = std::make_unique<RemovedDeskData>( std::move(*iter), removed_desk_index, source, close_type); auto* temporary_removed_desk_ptr = temporary_removed_desk.get();
diff --git a/ash/wm/window_restore/window_restore_util.cc b/ash/wm/window_restore/window_restore_util.cc index 4f0f4324..028ab76 100644 --- a/ash/wm/window_restore/window_restore_util.cc +++ b/ash/wm/window_restore/window_restore_util.cc
@@ -62,6 +62,12 @@ window_info->activation_index = window_activation_index; window_info->window = window; window_info->desk_id = window->GetProperty(aura::client::kWindowWorkspaceKey); + const std::string* desk_guid = window->GetProperty(kDeskGuidKey); + + // It's possible for the desk to no longer exist or not be found in the case of + // CloseAll. + window_info->desk_guid = + desk_guid ? base::GUID::ParseLowercase(*desk_guid) : base::GUID(); // If override bounds and window state are available (in tablet mode), save // those bounds.
diff --git a/ash/wm/window_state.cc b/ash/wm/window_state.cc index 0b88722..34b3df19 100644 --- a/ash/wm/window_state.cc +++ b/ash/wm/window_state.cc
@@ -853,6 +853,10 @@ &WindowState::CheckAndRecordDragMaximizedBehavior); } +base::AutoReset<bool> WindowState::GetScopedIgnorePropertyChange() { + return base::AutoReset<bool>(&ignore_property_change_, true); +} + void WindowState::CreateDragDetails(const gfx::PointF& point_in_parent, int window_component, ::wm::WindowMoveSource source) { @@ -1362,7 +1366,7 @@ } return; } - if (key == aura::client::kWindowWorkspaceKey) { + if (key == aura::client::kWindowWorkspaceKey || key == kDeskGuidKey) { // Save the window for window restore purposes unless // |ignore_property_change_| is true. Note that moving windows across // displays will also trigger a kWindowWorkspaceKey change, even if the
diff --git a/ash/wm/window_state.h b/ash/wm/window_state.h index 56acc20..414d63b 100644 --- a/ash/wm/window_state.h +++ b/ash/wm/window_state.h
@@ -14,6 +14,7 @@ #include "ash/wm/drag_details.h" #include "ash/wm/multi_display/persistent_window_info.h" #include "ash/wm/wm_metrics.h" +#include "base/auto_reset.h" #include "base/gtest_prod_util.h" #include "base/observer_list.h" #include "base/time/time.h" @@ -441,6 +442,9 @@ // mis-triggered drag to maximize behavior. void TrackDragToMaximizeBehavior(); + // Allows for caller to prevent property changes within scope. + base::AutoReset<bool> GetScopedIgnorePropertyChange(); + // Returns a pointer to DragDetails during drag operations. const DragDetails* drag_details() const { return drag_details_.get(); } DragDetails* drag_details() { return drag_details_.get(); }
diff --git a/base/allocator/partition_allocator/page_allocator.h b/base/allocator/partition_allocator/page_allocator.h index cdeebe8a..e134744f 100644 --- a/base/allocator/partition_allocator/page_allocator.h +++ b/base/allocator/partition_allocator/page_allocator.h
@@ -66,6 +66,7 @@ // these tags are used to name anonymous mappings. enum class PageTag { kFirst = 240, // Minimum tag value. + kSimulation = 251, // Memory simulator tool. kBlinkGC = 252, // Blink GC pages. kPartitionAlloc = 253, // PartitionAlloc, no matter the partition. kChromium = 254, // Chromium page. @@ -73,6 +74,12 @@ kLast = kV8 // Maximum tag value. }; +// See +// https://github.com/apple-oss-distributions/xnu/blob/5c2921b07a2480ab43ec66f5b9e41cb872bc554f/osfmk/mach/vm_statistics.h#L687 +static_assert( + static_cast<int>(PageTag::kLast) < 256, + "Tags are only 1 byte long on macOS, see vm_statistics.h in XNU."); + PA_COMPONENT_EXPORT(PARTITION_ALLOC) uintptr_t NextAlignedWithOffset(uintptr_t ptr, uintptr_t alignment,
diff --git a/base/fuchsia/fidl_event_handler_unittest.cc b/base/fuchsia/fidl_event_handler_unittest.cc index 8f194da..3283c981 100644 --- a/base/fuchsia/fidl_event_handler_unittest.cc +++ b/base/fuchsia/fidl_event_handler_unittest.cc
@@ -6,7 +6,6 @@ #include <fidl/base.testfidl/cpp/fidl.h> #include <fidl/fuchsia.logger/cpp/fidl.h> -#include <lib/async/default.h> #include <lib/sys/cpp/component_context.h> #include "base/fuchsia/fuchsia_component_connect.h" @@ -99,8 +98,7 @@ { ScopedNaturalServiceBinding<base_testfidl::TestInterface> binding( - ComponentContextForProcess()->outgoing().get(), &test_service_, - async_get_default_dispatcher()); + ComponentContextForProcess()->outgoing().get(), &test_service_); ASSERT_EQ(ZX_OK, VerifyTestInterface(client)); }; @@ -155,8 +153,7 @@ { TestInterfaceNaturalImpl test_service; ScopedNaturalServiceBinding<base_testfidl::TestInterface> binding( - ComponentContextForProcess()->outgoing().get(), &test_service, - async_get_default_dispatcher()); + ComponentContextForProcess()->outgoing().get(), &test_service); ASSERT_EQ(ZX_OK, VerifyTestInterface(client)); } @@ -200,8 +197,7 @@ { ScopedNaturalServiceBinding<base_testfidl::TestInterface> binding( - ComponentContextForProcess()->outgoing().get(), &test_service_, - async_get_default_dispatcher()); + ComponentContextForProcess()->outgoing().get(), &test_service_); ASSERT_EQ(ZX_OK, VerifyTestInterface(client)); };
diff --git a/base/fuchsia/scoped_natural_service_binding_unittest.cc b/base/fuchsia/scoped_natural_service_binding_unittest.cc index e5de263..a99a340 100644 --- a/base/fuchsia/scoped_natural_service_binding_unittest.cc +++ b/base/fuchsia/scoped_natural_service_binding_unittest.cc
@@ -34,8 +34,7 @@ // client. TEST_F(ScopedNaturalServiceBindingTest, ConnectTwice) { ScopedNaturalServiceBinding<base_testfidl::TestInterface> binding( - ComponentContextForProcess()->outgoing().get(), &test_service_, - async_get_default_dispatcher()); + ComponentContextForProcess()->outgoing().get(), &test_service_); auto stub = CreateTestInterfaceClient(test_context_.published_services_natural()); @@ -52,7 +51,7 @@ ScopedNaturalServiceBinding<base_testfidl::TestInterface> new_service_binding( ComponentContextForProcess()->outgoing().get(), &test_service_, - async_get_default_dispatcher(), kInterfaceName); + kInterfaceName); auto stub = CreateTestInterfaceClient( test_context_.published_services_natural(), kInterfaceName); @@ -69,8 +68,7 @@ // Publish the test service to the "debug" directory. ScopedNaturalServiceBinding<base_testfidl::TestInterface> - debug_service_binding(debug_dir, &test_service_, - async_get_default_dispatcher()); + debug_service_binding(debug_dir, &test_service_); // Connect a `ClientEnd` to the "debug" subdirectory. auto debug_directory_endpoints = @@ -97,8 +95,7 @@ // clients reaches 0. TEST_F(ScopedNaturalServiceBindingTest, MultipleLastClientCallback) { ScopedNaturalServiceBinding<base_testfidl::TestInterface> binding( - ComponentContextForProcess()->outgoing().get(), &test_service_, - async_get_default_dispatcher()); + ComponentContextForProcess()->outgoing().get(), &test_service_); int disconnect_count = 0; binding.SetOnLastClientCallback( BindLambdaForTesting([&disconnect_count]() { ++disconnect_count; })); @@ -132,8 +129,7 @@ // clients reaches 0. TEST_F(ScopedNaturalServiceBindingTest, LastClientCallbackOnlyForLastClient) { ScopedNaturalServiceBinding<base_testfidl::TestInterface> binding( - ComponentContextForProcess()->outgoing().get(), &test_service_, - async_get_default_dispatcher()); + ComponentContextForProcess()->outgoing().get(), &test_service_); int disconnect_count = 0; binding.SetOnLastClientCallback( BindLambdaForTesting([&disconnect_count]() { ++disconnect_count; }));
diff --git a/base/fuchsia/scoped_service_binding.h b/base/fuchsia/scoped_service_binding.h index 540021b..3ddc6269 100644 --- a/base/fuchsia/scoped_service_binding.h +++ b/base/fuchsia/scoped_service_binding.h
@@ -7,6 +7,9 @@ #include <utility> +// TODO(crbug.com/1427626): Remove this include once the explicit +// async_get_default_dispatcher() is no longer needed. +#include <lib/async/default.h> #include <lib/fidl/cpp/binding.h> #include <lib/fidl/cpp/binding_set.h> #include <lib/fidl/cpp/interface_request.h> @@ -74,26 +77,32 @@ ScopedNaturalServiceBinding( sys::OutgoingDirectory* outgoing_directory, fidl::Server<Protocol>* impl, - async_dispatcher_t* dispatcher, base::StringPiece name = fidl::DiscoverableProtocolName<Protocol>) - : publisher_(outgoing_directory, - bindings_.CreateHandler(impl, - dispatcher, - [](fidl::UnbindInfo info) {}), - name) {} + : publisher_( + outgoing_directory, + bindings_.CreateHandler( + impl, + // TODO(crbug.com/1427626): Remove this param once there's an + // overload of `CreateHandler` that doesn't require it. + async_get_default_dispatcher(), + [](fidl::UnbindInfo info) {}), + name) {} // Publishes a service in the specified |pseudo_dir|. |pseudo_dir| and |impl| // must outlive the binding. The service is unpublished on destruction. ScopedNaturalServiceBinding( vfs::PseudoDir* pseudo_dir, fidl::Server<Protocol>* impl, - async_dispatcher_t* dispatcher, base::StringPiece name = fidl::DiscoverableProtocolName<Protocol>) - : publisher_(pseudo_dir, - bindings_.CreateHandler(impl, - dispatcher, - [](fidl::UnbindInfo info) {}), - name) {} + : publisher_( + pseudo_dir, + bindings_.CreateHandler( + impl, + // TODO(crbug.com/1427626): Remove this param once there's an + // overload of `CreateHandler` that doesn't require it. + async_get_default_dispatcher(), + [](fidl::UnbindInfo info) {}), + name) {} ScopedNaturalServiceBinding(const ScopedNaturalServiceBinding&) = delete; ScopedNaturalServiceBinding& operator=(const ScopedNaturalServiceBinding&) =
diff --git a/base/fuchsia/system_product_info_unittest.cc b/base/fuchsia/system_product_info_unittest.cc index 1c2cc87ac..518f2e3 100644 --- a/base/fuchsia/system_product_info_unittest.cc +++ b/base/fuchsia/system_product_info_unittest.cc
@@ -38,7 +38,7 @@ sys::OutgoingDirectory* outgoing_services) : model_(model), manufacturer_(manufacturer), - binding_(outgoing_services, this, async_get_default_dispatcher()) {} + binding_(outgoing_services, this) {} FakeHardwareInfoProduct(const FakeHardwareInfoProduct&) = delete; FakeHardwareInfoProduct& operator=(const FakeHardwareInfoProduct&) = delete; ~FakeHardwareInfoProduct() override = default;
diff --git a/base/rand_util.h b/base/rand_util.h index 0402453..38be943 100644 --- a/base/rand_util.h +++ b/base/rand_util.h
@@ -20,6 +20,10 @@ #include "third_party/boringssl/src/include/openssl/rand.h" #endif +namespace memory_simulator { +class MemoryHolder; +} + namespace base { namespace internal { @@ -168,6 +172,10 @@ // base::Rand*() is too high, using something more representative than a // microbenchmark. + // Uses the generator to fill memory pages with random content to make them + // hard to compress, in a simulation tool not bundled with Chrome. CPU + // overhead must be minimized to correctly measure memory effects. + friend class memory_simulator::MemoryHolder; // Uses the generator to sub-sample metrics. friend class MetricsSubSampler;
diff --git a/build/config/rust.gni b/build/config/rust.gni index 2f4fe215..68949af 100644 --- a/build/config/rust.gni +++ b/build/config/rust.gni
@@ -25,7 +25,7 @@ # slowly and carefully and there may be no actual bugs there. enable_rust = is_linux && !is_official_build && !using_sanitizer && target_cpu != "x86" && !use_clang_coverage && is_clang && - !is_castos && target_os == host_os + target_os == host_os # As we incrementally enable Rust on mainstream builders, we want to enable # the toolchain (by switching 'enable_rust' to true) while still disabling @@ -47,13 +47,6 @@ # on supported platforms and GN targets. enable_local_libstd = true - # When true, uses the locally-built std in all Rust targets. - # - # As an internal implementation detail this can be overridden on specific - # targets (e.g. to run build.rs scripts while building std), but this - # generally should not be done. - use_local_std_by_default = false - # Chromium currently has a Rust toolchain for Android and Linux, but # if you wish to experiment on more platforms you can use this # argument to specify an alternative toolchain. @@ -90,8 +83,17 @@ } declare_args() { - # Individual Rust components. A separate declare_args so it can depend - # on the previous args. + # Use a separate declare_args so these variables' defaults can depend on the + # ones above. + + # When true, uses the locally-built std in all Rust targets. + # + # As an internal implementation detail this can be overridden on specific + # targets (e.g. to run build.rs scripts while building std), but this + # generally should not be done. + use_local_std_by_default = enable_local_libstd && use_chromium_rust_toolchain + + # Individual Rust components. # Conversions between Rust types and C++ types. enable_rust_base_conversions = enable_all_rust_features
diff --git a/build/fuchsia/linux_internal.sdk.sha1 b/build/fuchsia/linux_internal.sdk.sha1 index 788ae34..97488c08 100644 --- a/build/fuchsia/linux_internal.sdk.sha1 +++ b/build/fuchsia/linux_internal.sdk.sha1
@@ -1 +1 @@ -12.20230327.1.1 +12.20230327.2.1
diff --git a/buildtools/deps_revisions.gni b/buildtools/deps_revisions.gni index 5c7613d5..58ebf32 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 = "79a510511b03dc9a9f378ebe07c18c622b5bf349" + libcxx_revision = "26ace673c4b9c7a352fa9db182256bb341b6c44f" }
diff --git a/cc/slim/layer.cc b/cc/slim/layer.cc index ea96843..948c633 100644 --- a/cc/slim/layer.cc +++ b/cc/slim/layer.cc
@@ -14,7 +14,6 @@ #include "base/ranges/algorithm.h" #include "cc/layers/layer.h" #include "cc/paint/filter_operation.h" -#include "cc/paint/filter_operations.h" #include "cc/slim/features.h" #include "cc/slim/layer_tree.h" #include "cc/slim/layer_tree_impl.h" @@ -445,6 +444,10 @@ return !filters_.empty(); } +cc::FilterOperations Layer::GetFilters() const { + return ToCcFilters(filters_); +} + int Layer::GetNumDrawingLayersInSubtree() const { return num_descendants_that_draw_content_ + (draws_content_ ? 1 : 0); } @@ -463,8 +466,6 @@ const gfx::Rect* clip_in_target, const gfx::Rect& visible_rect, float opacity) { - DCHECK(!HasFilters() || render_pass.filters.IsEmpty()); - render_pass.filters = ToCcFilters(filters_); viz::SharedQuadState* quad_state = render_pass.CreateAndAppendSharedQuadState(); const gfx::Rect layer_rect{bounds()};
diff --git a/cc/slim/layer.h b/cc/slim/layer.h index 5fd3b501..8229599 100644 --- a/cc/slim/layer.h +++ b/cc/slim/layer.h
@@ -11,6 +11,7 @@ #include "base/memory/raw_ptr.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_refptr.h" +#include "cc/paint/filter_operations.h" #include "cc/slim/filter.h" #include "cc/slim/frame_data.h" #include "third_party/abseil-cpp/absl/types/optional.h" @@ -202,6 +203,7 @@ gfx::Transform ComputeTransformToParent() const; absl::optional<gfx::Transform> ComputeTransformFromParent() const; bool HasFilters() const; + cc::FilterOperations GetFilters() const; // This method counts this layer, This is different from // `NumDescendantsThatDrawContent` which counts descendent layers only. int GetNumDrawingLayersInSubtree() const;
diff --git a/cc/slim/layer_tree_impl.cc b/cc/slim/layer_tree_impl.cc index e700d775..1ca2a620 100644 --- a/cc/slim/layer_tree_impl.cc +++ b/cc/slim/layer_tree_impl.cc
@@ -431,6 +431,7 @@ /*parent_transform_to_target=*/gfx::Transform(), /*parent_clip_in_target=*/nullptr, gfx::RectF(device_viewport_rect_), /*opacity=*/1.0f); + render_pass->filters = root_->GetFilters(); if (background_color_.fA && !frame_data.occlusion_in_target.Contains(device_viewport_rect_)) { @@ -560,7 +561,7 @@ } std::unique_ptr<viz::CompositorRenderPass> new_pass; - gfx::Rect new_pass_content_bounds; + gfx::Rect new_pass_clip; // Scale can be applied when drawing layers into the new pass, or when // drawing the new pass into its target pass. Generally prefer the former to // avoid visual artifacts when scaling the output of the new pass. Therefore @@ -596,23 +597,16 @@ gfx::Transform::MakeScale(scale_to_new_pass.x(), scale_to_new_pass.y()); // First clip in layer space, then transform to parent target space. - new_pass_content_bounds.set_size(layer.bounds()); - new_pass_content_bounds.Intersect(gfx::ToEnclosedRect(clip_in_layer)); - new_pass_content_bounds = - transform_to_target.MapRect(new_pass_content_bounds); - // Clip to max texture size. - int max_texture_size = frame_sink_->GetMaxTextureSize(); - new_pass_content_bounds.set_width( - std::min(new_pass_content_bounds.width(), max_texture_size)); - new_pass_content_bounds.set_height( - std::min(new_pass_content_bounds.height(), max_texture_size)); - + new_pass_clip = gfx::ToEnclosedRect(clip_in_layer); + if (layer.masks_to_bounds()) { + new_pass_clip.Intersect(gfx::Rect(layer.bounds())); + } + new_pass_clip = transform_to_target.MapRect(new_pass_clip); new_pass = viz::CompositorRenderPass::Create(); - // Note output_rect and damage_rect are updated below. + // Note output_rect and damage_rect are further updated below. viz::CompositorRenderPassId new_pass_id(layer.id()); - new_pass->SetNew(new_pass_id, /*output_rect=*/new_pass_content_bounds, - /*damage_rect=*/new_pass_content_bounds, - new_pass_transform_to_root); + new_pass->SetNew(new_pass_id, /*output_rect=*/new_pass_clip, + /*damage_rect=*/new_pass_clip, new_pass_transform_to_root); } // If a new pass is created, then there is no target clip when drawing into @@ -650,22 +644,6 @@ } viz::SharedQuadState* shared_quad_state = parent_pass.CreateAndAppendSharedQuadState(); - // Any clip introduced by this layer is already applied by the bounds of the - // new pass, so only need to apply any clips in parents target that came - // from parent. - absl::optional<gfx::Rect> clip_opt; - if (parent_clip_in_target) { - clip_opt = gfx::ToEnclosingRect(*parent_clip_in_target); - } - const bool new_pass_contents_opaque = - occlusion_in_new_pass.Contains(new_pass_content_bounds); - shared_quad_state->SetAll( - transform_new_pass_to_parent_target, new_pass_content_bounds, - new_pass_content_bounds, gfx::MaskFilterInfo(), clip_opt, - new_pass_contents_opaque, parent_opacity * layer.opacity(), - SkBlendMode::kSrcOver, 0); - auto* quad = - parent_pass.CreateAndAppendDrawQuad<viz::CompositorRenderPassDrawQuad>(); // Union through quad list in new pass to compute content rect. gfx::Rect content_rect; @@ -674,7 +652,27 @@ new_pass_quad->shared_quad_state->quad_to_target_transform.MapRect( new_pass_quad->rect)); } - content_rect.Intersect(new_pass_content_bounds); + content_rect.Intersect(new_pass_clip); + // Clip to max texture size. + int max_texture_size = frame_sink_->GetMaxTextureSize(); + content_rect.set_width(std::min(content_rect.width(), max_texture_size)); + content_rect.set_height(std::min(content_rect.height(), max_texture_size)); + + // Any clip introduced by this layer is already applied by the bounds of the + // new pass, so only need to apply any clips in parents target that came + // from parent. + absl::optional<gfx::Rect> clip_opt; + if (parent_clip_in_target) { + clip_opt = gfx::ToEnclosingRect(*parent_clip_in_target); + } + const bool new_pass_contents_opaque = + occlusion_in_new_pass.Contains(content_rect); + shared_quad_state->SetAll( + transform_new_pass_to_parent_target, content_rect, content_rect, + gfx::MaskFilterInfo(), clip_opt, new_pass_contents_opaque, + parent_opacity * layer.opacity(), SkBlendMode::kSrcOver, 0); + auto* quad = + parent_pass.CreateAndAppendDrawQuad<viz::CompositorRenderPassDrawQuad>(); gfx::RectF tex_coord_rect(gfx::Rect(content_rect.size())); quad->SetAll(shared_quad_state, content_rect, content_rect, @@ -692,6 +690,7 @@ // `has_damage_from_contributing_content`. new_pass->output_rect = content_rect; new_pass->damage_rect = content_rect; + new_pass->filters = layer.GetFilters(); data.frame.render_pass_list.push_back(std::move(new_pass)); }
diff --git a/cc/slim/slim_layer_tree_compositor_frame_unittest.cc b/cc/slim/slim_layer_tree_compositor_frame_unittest.cc index 996acb97..8ce6c0362 100644 --- a/cc/slim/slim_layer_tree_compositor_frame_unittest.cc +++ b/cc/slim/slim_layer_tree_compositor_frame_unittest.cc
@@ -1168,8 +1168,9 @@ auto* render_pass_quad = viz::CompositorRenderPassDrawQuad::MaterialCast( root_pass->quad_list.ElementAt(0)); auto* shared_quad_state = render_pass_quad->shared_quad_state; - EXPECT_EQ(shared_quad_state->quad_layer_rect, gfx::Rect(50, 50)); - EXPECT_EQ(shared_quad_state->visible_quad_layer_rect, gfx::Rect(50, 50)); + EXPECT_EQ(shared_quad_state->quad_layer_rect, gfx::Rect(20, 20, 30, 30)); + EXPECT_EQ(shared_quad_state->visible_quad_layer_rect, + gfx::Rect(20, 20, 30, 30)); EXPECT_EQ(shared_quad_state->clip_rect, absl::nullopt); } } @@ -1239,6 +1240,71 @@ } } +TEST_F(SlimLayerTreeCompositorFrameTest, FiltersOnNonDrawingLayer) { + auto root_layer = CreateSolidColorLayer(viewport_.size(), SkColors::kGray); + layer_tree_->SetRoot(root_layer); + + auto filter_layer = cc::slim::Layer::Create(); + filter_layer->SetFilters({cc::slim::Filter::CreateBrightness(0.5f)}); + auto solid_color_layer = + CreateSolidColorLayer(gfx::Size(50, 50), SkColors::kRed); + filter_layer->AddChild(solid_color_layer); + root_layer->AddChild(filter_layer); + + { + viz::CompositorFrame frame = ProduceFrame(); + ASSERT_EQ(frame.render_pass_list.size(), 2u); + auto& child_pass = frame.render_pass_list.front(); + ASSERT_THAT(child_pass->quad_list, + ElementsAre(AllOf(viz::IsSolidColorQuad(SkColors::kRed), + viz::HasRect(gfx::Rect(50, 50)), + viz::HasVisibleRect(gfx::Rect(50, 50))))); + EXPECT_EQ(child_pass->output_rect, gfx::Rect(50, 50)); + EXPECT_THAT(child_pass->filters.operations(), + ElementsAre(cc::FilterOperation::CreateBrightnessFilter(0.5f))); + auto& root_pass = frame.render_pass_list.back(); + ASSERT_THAT( + root_pass->quad_list, + ElementsAre(AllOf(viz::IsCompositorRenderPassQuad(child_pass->id), + viz::HasRect(gfx::Rect(50, 50)), + viz::HasVisibleRect(gfx::Rect(50, 50))), + viz::IsSolidColorQuad(SkColors::kGray))); + } + + // Clip the child pass. + filter_layer->SetBounds(gfx::Size(25, 25)); + filter_layer->SetMasksToBounds(true); + { + viz::CompositorFrame frame = ProduceFrame(); + ASSERT_EQ(frame.render_pass_list.size(), 2u); + auto& child_pass = frame.render_pass_list.front(); + ASSERT_THAT(child_pass->quad_list, + ElementsAre(AllOf(viz::IsSolidColorQuad(SkColors::kRed), + viz::HasRect(gfx::Rect(50, 50)), + viz::HasVisibleRect(gfx::Rect(25, 25))))); + EXPECT_EQ(child_pass->output_rect, gfx::Rect(25, 25)); + EXPECT_THAT(child_pass->filters.operations(), + ElementsAre(cc::FilterOperation::CreateBrightnessFilter(0.5f))); + auto& root_pass = frame.render_pass_list.back(); + ASSERT_THAT( + root_pass->quad_list, + ElementsAre(AllOf(viz::IsCompositorRenderPassQuad(child_pass->id), + viz::HasRect(gfx::Rect(25, 25)), + viz::HasVisibleRect(gfx::Rect(25, 25))), + viz::IsSolidColorQuad(SkColors::kGray))); + } + + // Completely clip the child pass. + filter_layer->SetBounds(gfx::Size(0, 0)); + { + viz::CompositorFrame frame = ProduceFrame(); + ASSERT_EQ(frame.render_pass_list.size(), 1u); + auto& root_pass = frame.render_pass_list.back(); + ASSERT_THAT(root_pass->quad_list, + ElementsAre(viz::IsSolidColorQuad(SkColors::kGray))); + } +} + TEST_F(SlimLayerTreeCompositorFrameTest, Opacity) { auto root_layer = CreateSolidColorLayer(viewport_.size(), SkColors::kGray); layer_tree_->SetRoot(root_layer); @@ -1443,17 +1509,20 @@ ASSERT_THAT( root_pass->quad_list, ElementsAre(AllOf(viz::IsCompositorRenderPassQuad(child_pass->id), - // RenderPassQuad is not fully covered. - viz::AreContentsOpaque(false)), + // Pass rects shrinks to content rect. + viz::HasRect(gfx::Rect(100, 25)), + viz::HasVisibleRect(gfx::Rect(100, 25)), + viz::AreContentsOpaque(true)), AllOf(viz::IsSolidColorQuad(SkColors::kGray), viz::HasRect(viewport_), // Occluded by child pass. viz::HasVisibleRect(gfx::Rect(0, 25, 100, 75))))); } - // Add another layer to fully cover the child quad. + // Add another layer so that the bottom right corner of the render pass is not + // covered. auto child_pass_layer_2 = - CreateSolidColorLayer(gfx::Size(200, 50), SkColors::kBlue); + CreateSolidColorLayer(gfx::Size(100, 50), SkColors::kGreen); child_pass_layer_2->SetPosition(gfx::PointF(0.0f, 50.0f)); child_pass_root->AddChild(child_pass_layer_2); { @@ -1461,9 +1530,9 @@ ASSERT_EQ(frame.render_pass_list.size(), 2u); auto& child_pass = frame.render_pass_list.front(); ASSERT_THAT(child_pass->quad_list, - ElementsAre(AllOf(viz::IsSolidColorQuad(SkColors::kBlue), - viz::HasRect(gfx::Rect(200, 50)), - viz::HasVisibleRect(gfx::Rect(200, 50))), + ElementsAre(AllOf(viz::IsSolidColorQuad(SkColors::kGreen), + viz::HasRect(gfx::Rect(100, 50)), + viz::HasVisibleRect(gfx::Rect(100, 50))), AllOf(viz::IsSolidColorQuad(SkColors::kRed), viz::HasRect(gfx::Rect(200, 50)), viz::HasVisibleRect(gfx::Rect(200, 50))))); @@ -1472,6 +1541,42 @@ ASSERT_THAT( root_pass->quad_list, ElementsAre(AllOf(viz::IsCompositorRenderPassQuad(child_pass->id), + viz::HasRect(gfx::Rect(100, 50)), + viz::HasVisibleRect(gfx::Rect(100, 50)), + // RenderPassQuad is fully covered. + viz::AreContentsOpaque(false)), + AllOf(viz::IsSolidColorQuad(SkColors::kGray), + viz::HasRect(viewport_), + // Occluded by child pass. + viz::HasVisibleRect(gfx::Rect(0, 25, 100, 75))))); + } + + // Add another layer to fully cover the child pass. + auto child_pass_layer_3 = + CreateSolidColorLayer(gfx::Size(100, 50), SkColors::kBlue); + child_pass_layer_3->SetPosition(gfx::PointF(100.0f, 50.0f)); + child_pass_root->AddChild(child_pass_layer_3); + { + viz::CompositorFrame frame = ProduceFrame(); + ASSERT_EQ(frame.render_pass_list.size(), 2u); + auto& child_pass = frame.render_pass_list.front(); + ASSERT_THAT(child_pass->quad_list, + ElementsAre(AllOf(viz::IsSolidColorQuad(SkColors::kBlue), + viz::HasRect(gfx::Rect(100, 50)), + viz::HasVisibleRect(gfx::Rect(100, 50))), + AllOf(viz::IsSolidColorQuad(SkColors::kGreen), + viz::HasRect(gfx::Rect(100, 50)), + viz::HasVisibleRect(gfx::Rect(100, 50))), + AllOf(viz::IsSolidColorQuad(SkColors::kRed), + viz::HasRect(gfx::Rect(200, 50)), + viz::HasVisibleRect(gfx::Rect(200, 50))))); + + auto& root_pass = frame.render_pass_list.back(); + ASSERT_THAT( + root_pass->quad_list, + ElementsAre(AllOf(viz::IsCompositorRenderPassQuad(child_pass->id), + viz::HasRect(gfx::Rect(100, 50)), + viz::HasVisibleRect(gfx::Rect(100, 50)), // RenderPassQuad is fully covered. viz::AreContentsOpaque(true)), AllOf(viz::IsSolidColorQuad(SkColors::kGray), @@ -1480,7 +1585,7 @@ viz::HasVisibleRect(gfx::Rect(0, 50, 100, 50))))); } - // Expand child layer so it's partially occluded by child layer 2. + // Expand child layer so it's partially occluded by child layer 2 and 3. child_pass_layer->SetBounds(gfx::Size(200, 100)); { viz::CompositorFrame frame = ProduceFrame(); @@ -1488,8 +1593,11 @@ auto& child_pass = frame.render_pass_list.front(); ASSERT_THAT(child_pass->quad_list, ElementsAre(AllOf(viz::IsSolidColorQuad(SkColors::kBlue), - viz::HasRect(gfx::Rect(200, 50)), - viz::HasVisibleRect(gfx::Rect(200, 50))), + viz::HasRect(gfx::Rect(100, 50)), + viz::HasVisibleRect(gfx::Rect(100, 50))), + AllOf(viz::IsSolidColorQuad(SkColors::kGreen), + viz::HasRect(gfx::Rect(100, 50)), + viz::HasVisibleRect(gfx::Rect(100, 50))), AllOf(viz::IsSolidColorQuad(SkColors::kRed), viz::HasRect(gfx::Rect(200, 100)), // Partially occluded.
diff --git a/chrome/android/chrome_java_resources.gni b/chrome/android/chrome_java_resources.gni index 48cfd34..6d09bd0 100644 --- a/chrome/android/chrome_java_resources.gni +++ b/chrome/android/chrome_java_resources.gni
@@ -468,10 +468,10 @@ "java/res/layout/autofill_server_data_text_label.xml", "java/res/layout/autofill_update_address_profile_prompt.xml", "java/res/layout/bookmark_edit.xml", - "java/res/layout/bookmark_folder_row.xml", "java/res/layout/bookmark_folder_select_activity.xml", - "java/res/layout/bookmark_item_row.xml", "java/res/layout/bookmark_main.xml", + "java/res/layout/bookmark_row_layout.xml", + "java/res/layout/bookmark_row_layout_visual.xml", "java/res/layout/bookmark_save_flow.xml", "java/res/layout/bookmark_section_header.xml", "java/res/layout/bookmark_toolbar.xml", @@ -561,7 +561,6 @@ "java/res/layout/password_no_result.xml", "java/res/layout/passwords_error_dialog.xml", "java/res/layout/passwords_progress_dialog.xml", - "java/res/layout/power_bookmark_shopping_item_row.xml", "java/res/layout/power_bookmark_tag_chip_list.xml", "java/res/layout/powered_by_chrome_footer.xml", "java/res/layout/radio_button_group_homepage_preference.xml",
diff --git a/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/TabSwitcherAndStartSurfaceLayout.java b/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/TabSwitcherAndStartSurfaceLayout.java index c7dafce..fc24112 100644 --- a/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/TabSwitcherAndStartSurfaceLayout.java +++ b/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/TabSwitcherAndStartSurfaceLayout.java
@@ -897,6 +897,11 @@ return super.canHostBeFocusable(); } + @Override + public boolean isRunningAnimations() { + return mDeferredAnimationRunnable != null || mTabToSwitcherAnimation != null; + } + /** * Shrink/Expand animation is disabled for Tablet TabSwitcher launch polish. * @return Whether shrink/expand animation is enabled.
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabManagementDelegateImpl.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabManagementDelegateImpl.java index 64dece91..e3cd69d 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabManagementDelegateImpl.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabManagementDelegateImpl.java
@@ -13,7 +13,6 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import org.chromium.base.SysUtils; import org.chromium.base.jank_tracker.JankTracker; import org.chromium.base.supplier.ObservableSupplier; import org.chromium.base.supplier.OneshotSupplier; @@ -82,8 +81,7 @@ tabContentManager, browserControlsStateProvider, tabCreatorManager, menuOrKeyboardActionController, containerView, multiWindowModeStateDispatcher, scrimCoordinator, - TabUiFeatureUtilities.isTabGroupsAndroidContinuationEnabled(activity) - && SysUtils.isLowEndDevice() + TabUiFeatureUtilities.shouldUseListMode(activity) ? TabListCoordinator.TabListMode.LIST : TabListCoordinator.TabListMode.GRID, rootView, dynamicResourceLoaderSupplier, snackbarManager, modalDialogManager,
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherLayout.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherLayout.java index dd15d7d..5eff80bf 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherLayout.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherLayout.java
@@ -728,6 +728,11 @@ return super.canHostBeFocusable(); } + @Override + public boolean isRunningAnimations() { + return mDeferredAnimationRunnable != null || mTabToSwitcherAnimation != null; + } + /** * Shrink/Expand animation is disabled for Tablet TabSwitcher launch polish. * @return Whether shrink/expand animation is enabled.
diff --git a/chrome/android/features/vr/java/src/org/chromium/chrome/browser/vr/VrShellDelegate.java b/chrome/android/features/vr/java/src/org/chromium/chrome/browser/vr/VrShellDelegate.java index 1c141be8..79058636 100644 --- a/chrome/android/features/vr/java/src/org/chromium/chrome/browser/vr/VrShellDelegate.java +++ b/chrome/android/features/vr/java/src/org/chromium/chrome/browser/vr/VrShellDelegate.java
@@ -33,8 +33,10 @@ import org.chromium.base.metrics.RecordUserAction; import org.chromium.base.supplier.ObservableSupplier; import org.chromium.base.supplier.ObservableSupplierImpl; +import org.chromium.base.supplier.Supplier; import org.chromium.chrome.browser.ChromeTabbedActivity; import org.chromium.chrome.browser.app.ChromeActivity; +import org.chromium.chrome.browser.compositor.CompositorViewHolder; import org.chromium.chrome.browser.customtabs.CustomTabActivity; import org.chromium.chrome.browser.tabmodel.TabModelSelector; import org.chromium.chrome.browser.webapps.WebappActivity; @@ -383,6 +385,12 @@ // Hide system UI. VrModuleProvider.getDelegate().setSystemUiVisibilityForVr(mActivity); + Supplier<CompositorViewHolder> compositorViewHolderSupplier = + mActivity.getCompositorViewHolderSupplier(); + if (compositorViewHolderSupplier.hasValue()) { + compositorViewHolderSupplier.get().getCompositorView().setOverlayVrMode(true); + } + // Set correct orientation. if (mRestoreOrientation == null) { mRestoreOrientation = mActivity.getRequestedOrientation(); @@ -409,7 +417,11 @@ flags & ~VrDelegate.VR_SYSTEM_UI_FLAGS); } mRestoreSystemUiVisibility = false; - + Supplier<CompositorViewHolder> compositorViewHolderSupplier = + mActivity.getCompositorViewHolderSupplier(); + if (compositorViewHolderSupplier.hasValue()) { + compositorViewHolderSupplier.get().getCompositorView().setOverlayVrMode(false); + } mActivity.getWindow().getAttributes().rotationAnimation = WindowManager.LayoutParams.ROTATION_ANIMATION_ROTATE; }
diff --git a/chrome/android/java/res/layout/autofill_card_unmask_prompt_card_details.xml b/chrome/android/java/res/layout/autofill_card_unmask_prompt_card_details.xml index 55dc07c..71ed01da 100644 --- a/chrome/android/java/res/layout/autofill_card_unmask_prompt_card_details.xml +++ b/chrome/android/java/res/layout/autofill_card_unmask_prompt_card_details.xml
@@ -12,8 +12,8 @@ <org.chromium.ui.widget.ChromeImageView android:id="@+id/card_icon" - android:layout_width="32dp" - android:layout_height="20dp" + android:layout_width="wrap_content" + android:layout_height="wrap_content" android:layout_alignParentStart="true" android:layout_centerVertical="true" android:layout_marginEnd="16dp"
diff --git a/chrome/android/java/res/layout/bookmark_folder_row.xml b/chrome/android/java/res/layout/bookmark_folder_row.xml deleted file mode 100644 index 196cb4a3..0000000 --- a/chrome/android/java/res/layout/bookmark_folder_row.xml +++ /dev/null
@@ -1,11 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - Copyright 2015 The Chromium Authors - Use of this source code is governed by a BSD-style license that can be - found in the LICENSE file. ---> - -<view class="org.chromium.chrome.browser.bookmarks.BookmarkFolderRow" - xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="match_parent" - android:layout_height="wrap_content" /> \ No newline at end of file
diff --git a/chrome/android/java/res/layout/bookmark_item_row.xml b/chrome/android/java/res/layout/bookmark_item_row.xml deleted file mode 100644 index 9e3109d6..0000000 --- a/chrome/android/java/res/layout/bookmark_item_row.xml +++ /dev/null
@@ -1,12 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - Copyright 2015 The Chromium Authors - Use of this source code is governed by a BSD-style license that can be - found in the LICENSE file. ---> - -<view class="org.chromium.chrome.browser.bookmarks.BookmarkItemRow" - xmlns:android="http://schemas.android.com/apk/res/android" - android:id="@+id/bookmark_item_row" - android:layout_width="match_parent" - android:layout_height="wrap_content" />
diff --git a/chrome/android/java/res/layout/bookmark_row_layout.xml b/chrome/android/java/res/layout/bookmark_row_layout.xml new file mode 100644 index 0000000..2f20503 --- /dev/null +++ b/chrome/android/java/res/layout/bookmark_row_layout.xml
@@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +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. +--> + +<LinearLayout + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + android:id="@+id/content" + style="@style/ListItemContainer"> + + <ImageView + android:id="@+id/start_icon" + android:background="@drawable/list_item_icon_modern_bg" + style="@style/ListItemStartIcon" + android:importantForAccessibility="no" /> + + <!-- Common title/description shared between list item views. --> + <include layout="@layout/title_and_description_layout" /> + + <org.chromium.ui.widget.ChromeImageButton + android:id="@+id/end_icon" + android:visibility="gone" + style="@style/ListItemEndIcon" /> + + <!-- List menu button used for contextual options. --> + <include layout="@layout/list_menu_button" /> + + <!-- TODO(crbug.com/1424835): Move drag handle to a vector drawable. --> + <!-- TODO(crbug.com/1424837): Support dynamic colors for drag handle. --> + <org.chromium.ui.widget.ChromeImageButton + android:id="@+id/drag_handle" + android:visibility="gone" + android:src="@drawable/ic_drag_handle_grey600_24dp" + android:tint="@color/default_icon_color_tint_list" + style="@style/ListItemEndIcon" /> +</LinearLayout> \ No newline at end of file
diff --git a/components/browser_ui/widget/android/java/res/layout/modern_list_item_view_v2.xml b/chrome/android/java/res/layout/bookmark_row_layout_visual.xml similarity index 64% rename from components/browser_ui/widget/android/java/res/layout/modern_list_item_view_v2.xml rename to chrome/android/java/res/layout/bookmark_row_layout_visual.xml index 4002ccd..217c0c0a 100644 --- a/components/browser_ui/widget/android/java/res/layout/modern_list_item_view_v2.xml +++ b/chrome/android/java/res/layout/bookmark_row_layout_visual.xml
@@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <!-- -Copyright 2021 The Chromium Authors +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. --> @@ -13,22 +13,25 @@ <ImageView android:id="@+id/start_icon" + android:background="@drawable/list_item_icon_modern_bg_rect" style="@style/ListItemStartIconV2" android:importantForAccessibility="no" /> <!-- Common title/description shared between list item views. --> <include layout="@layout/title_and_description_layout" /> - <!-- TODO(crbug.com/1241509): Allow an arbitrary amount of buttons to be added here. --> <org.chromium.ui.widget.ChromeImageButton - android:id="@+id/optional_button" + android:id="@+id/end_icon" android:visibility="gone" style="@style/ListItemEndIconV2" /> - <org.chromium.ui.widget.ChromeImageButton - android:id="@+id/end_button" - android:visibility="gone" - style="@style/ListItemEndIconV2" - android:layout_marginEnd="4dp" /> + <!-- List menu button used for contextual options. --> + <include layout="@layout/list_menu_button" /> + <org.chromium.ui.widget.ChromeImageButton + android:id="@+id/drag_handle" + android:visibility="gone" + android:src="@drawable/ic_drag_handle_grey600_24dp" + android:tint="@color/default_icon_color_tint_list" + style="@style/ListItemEndIconV2" /> </LinearLayout> \ No newline at end of file
diff --git a/chrome/android/java/res/layout/compact_price_drop_view.xml b/chrome/android/java/res/layout/compact_price_drop_view.xml index e0d0bc9..0c22d69b 100644 --- a/chrome/android/java/res/layout/compact_price_drop_view.xml +++ b/chrome/android/java/res/layout/compact_price_drop_view.xml
@@ -11,13 +11,18 @@ android:layout_width="wrap_content" android:layout_height="wrap_content"> <TextView - android:id="@+id/primary_text" + android:id="@+id/normal_price_text" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:textAppearance="@style/TextAppearance.TextMedium.Secondary" /> + <TextView + android:id="@+id/price_drop_primary_text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textAppearance="@style/TextAppearance.TextMedium.Secondary" android:layout_marginEnd="8dp" /> <TextView - android:id="@+id/secondary_text" + android:id="@+id/price_drop_secondary_text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textAppearance="@style/TextAppearance.TextMedium.Secondary" />
diff --git a/chrome/android/java/res/layout/power_bookmark_shopping_item_row.xml b/chrome/android/java/res/layout/power_bookmark_shopping_item_row.xml deleted file mode 100644 index 4fbff78..0000000 --- a/chrome/android/java/res/layout/power_bookmark_shopping_item_row.xml +++ /dev/null
@@ -1,12 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - 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. ---> - -<view class="org.chromium.chrome.browser.bookmarks.PowerBookmarkShoppingItemRow" - xmlns:android="http://schemas.android.com/apk/res/android" - android:id="@+id/power_bookmark_shopping_row" - android:layout_width="match_parent" - android:layout_height="wrap_content" />
diff --git a/chrome/android/java/res/values/dimens.xml b/chrome/android/java/res/values/dimens.xml index 928b987..2ca7427 100644 --- a/chrome/android/java/res/values/dimens.xml +++ b/chrome/android/java/res/values/dimens.xml
@@ -399,8 +399,4 @@ <!-- Price Drop dimensions --> <dimen name="price_drop_spotted_iph_ntp_tabswitcher_y_inset">4dp</dimen> - - <!-- Card Unmask dialog --> - <dimen name="card_unmask_dialog_credit_card_icon_width">32dp</dimen> - <dimen name="card_unmask_dialog_credit_card_icon_height">20dp</dimen> </resources>
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/bookmarks/BookmarkFolderSelectActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/app/bookmarks/BookmarkFolderSelectActivity.java index 89b585f..8f7aa7c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/app/bookmarks/BookmarkFolderSelectActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/app/bookmarks/BookmarkFolderSelectActivity.java
@@ -28,6 +28,7 @@ import org.chromium.base.IntentUtils; import org.chromium.chrome.R; import org.chromium.chrome.browser.SynchronousInitializationActivity; +import org.chromium.chrome.browser.bookmarks.BookmarkFolderRow; import org.chromium.chrome.browser.bookmarks.BookmarkModel; import org.chromium.chrome.browser.bookmarks.BookmarkModelObserver; import org.chromium.chrome.browser.bookmarks.BookmarkUtils; @@ -36,7 +37,6 @@ import org.chromium.components.bookmarks.BookmarkId; import org.chromium.components.bookmarks.BookmarkItem; import org.chromium.components.browser_ui.util.TraceEventVectorDrawableCompat; -import org.chromium.components.browser_ui.widget.selectable_list.SelectableItemView; import java.util.ArrayList; import java.util.List; @@ -428,7 +428,7 @@ iconDrawable = vectorDrawable; } - SelectableItemView.applyModernIconStyle(startIcon, iconDrawable, entry.mIsSelected); + BookmarkFolderRow.applyModernIconStyle(startIcon, iconDrawable, entry.mIsSelected); } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/omnibox/ActionChipsDelegateImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/app/omnibox/ActionChipsDelegateImpl.java index 47749af..dd19522 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/app/omnibox/ActionChipsDelegateImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/app/omnibox/ActionChipsDelegateImpl.java
@@ -61,15 +61,9 @@ mModalDialogManagerSupplier = modalDialogManagerSupplier; } - @Override - public void execute(OmniboxPedal omniboxPedal) { - if (omniboxPedal.hasActionId()) { - executeNonPedalAction(omniboxPedal); - return; - } - + private void executePedalAction(OmniboxPedal omniboxPedal) { @OmniboxPedalType - int omniboxPedalType = omniboxPedal.getPedalID(); + int omniboxPedalType = omniboxPedal.getPedalId(); SettingsLauncher settingsLauncher = new SettingsLauncherImpl(); switch (omniboxPedalType) { case OmniboxPedalType.CLEAR_BROWSING_DATA: @@ -139,8 +133,13 @@ return; } - private void executeNonPedalAction(OmniboxPedal omniboxPedal) { - switch (omniboxPedal.getActionID()) { + @Override + public void execute(OmniboxPedal omniboxPedal) { + switch (omniboxPedal.getActionId()) { + case OmniboxActionType.PEDAL: + executePedalAction(omniboxPedal); + break; + case OmniboxActionType.HISTORY_CLUSTERS: if (mHistoryClustersCoordinator != null) { assert omniboxPedal instanceof HistoryClustersAction; @@ -186,12 +185,12 @@ @Override public @NonNull ChipIcon getIcon(OmniboxPedal omniboxPedal) { - if (!omniboxPedal.hasPedalId()) { + if (omniboxPedal.getActionId() != OmniboxActionType.PEDAL) { return getActionIcon(omniboxPedal); } @OmniboxPedalType - int omniboxPedalType = omniboxPedal.getPedalID(); + int omniboxPedalType = omniboxPedal.getPedalId(); switch (omniboxPedalType) { case OmniboxPedalType.CLEAR_BROWSING_DATA: @@ -218,7 +217,7 @@ /** Returns the icon for an action that's not a pedal. */ private ChipIcon getActionIcon(OmniboxPedal omniboxPedal) { - int omniboxActionType = omniboxPedal.getActionID(); + int omniboxActionType = omniboxPedal.getActionId(); switch (omniboxActionType) { case OmniboxActionType.HISTORY_CLUSTERS:
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/CardUnmaskPrompt.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/CardUnmaskPrompt.java index 4364b16..4393556 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/CardUnmaskPrompt.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/CardUnmaskPrompt.java
@@ -165,8 +165,7 @@ // Populate card details. ChromeImageView cardIconView = (ChromeImageView) mMainView.findViewById(R.id.card_icon); cardIconView.setImageDrawable(AutofillUiUtils.getCardIcon(context, cardArtUrl, - cardIconId, R.dimen.card_unmask_dialog_credit_card_icon_width, - R.dimen.card_unmask_dialog_credit_card_icon_height, + cardIconId, getCardIconWidthId(), getCardIconHeightId(), isVirtualCard || ChromeFeatureList.isEnabled( ChromeFeatureList.AUTOFILL_ENABLE_CARD_ART_IMAGE))); @@ -604,4 +603,20 @@ public String getErrorMessage() { return mErrorMessage.getText().toString(); } + + public static int getCardIconWidthId() { + if (ChromeFeatureList.isEnabled( + ChromeFeatureList.AUTOFILL_ENABLE_NEW_CARD_ART_AND_NETWORK_IMAGES)) { + return R.dimen.card_unmask_dialog_credit_card_icon_width_new; + } + return R.dimen.card_unmask_dialog_credit_card_icon_width; + } + + public static int getCardIconHeightId() { + if (ChromeFeatureList.isEnabled( + ChromeFeatureList.AUTOFILL_ENABLE_NEW_CARD_ART_AND_NETWORK_IMAGES)) { + return R.dimen.card_unmask_dialog_credit_card_icon_height_new; + } + return R.dimen.card_unmask_dialog_credit_card_icon_height; + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkFolderRow.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkFolderRow.java index 22a2b044..a0049231 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkFolderRow.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkFolderRow.java
@@ -6,7 +6,9 @@ import android.content.Context; import android.content.res.ColorStateList; +import android.graphics.drawable.Drawable; import android.util.AttributeSet; +import android.widget.ImageView; import androidx.appcompat.content.res.AppCompatResources; @@ -14,23 +16,29 @@ import org.chromium.components.bookmarks.BookmarkId; import org.chromium.components.bookmarks.BookmarkItem; import org.chromium.components.bookmarks.BookmarkType; +import org.chromium.components.browser_ui.styles.SemanticColorUtils; +import org.chromium.components.browser_ui.widget.TintedDrawable; /** * A row view that shows folder info in the bookmarks UI. */ public class BookmarkFolderRow extends BookmarkRow { - /** - * Constructor for inflating from XML. + * Factory constructor for building the view programmatically. + * @param context The calling context, usually the parent view. + * @param isVisualRefreshEnabled Whether to show the visual or compact bookmark row. */ - public BookmarkFolderRow(Context context, AttributeSet attrs) { - super(context, attrs); + public static BookmarkFolderRow buildView(Context context, boolean isVisualRefreshEnabled) { + BookmarkFolderRow row = new BookmarkFolderRow(context, null); + BookmarkRow.buildView(row, context, isVisualRefreshEnabled); + return row; } - @Override - protected void onFinishInflate() { - super.onFinishInflate(); - setStartIconDrawable(BookmarkUtils.getFolderIcon(getContext(), BookmarkType.NORMAL)); + /** Constructor for inflating from XML. */ + public BookmarkFolderRow(Context context, AttributeSet attrs) { + super(context, attrs); + + setIconDrawable(BookmarkUtils.getFolderIcon(getContext(), BookmarkType.NORMAL)); } // BookmarkRow implementation. @@ -62,15 +70,41 @@ : getResources().getString(R.string.no_bookmarks)); } - setStartIconDrawable(BookmarkUtils.getFolderIcon(getContext(), item.getId().getType())); + setIconDrawable(BookmarkUtils.getFolderIcon(getContext(), item.getId().getType())); return item; } + // CheckableSelectableItemView implementation. + @Override - protected ColorStateList getDefaultStartIconTint() { + protected ColorStateList getDefaultIconTint() { @BookmarkType int type = (mBookmarkId == null) ? BookmarkType.NORMAL : mBookmarkId.getType(); return AppCompatResources.getColorStateList( getContext(), BookmarkUtils.getFolderIconTint(type)); } + + /** + * Sets the icon for the image view: the default icon if unselected, the check mark if selected. + * + * @param imageView The image view in which the icon will be presented. + * @param defaultIcon The default icon that will be displayed if not selected. + * @param isSelected Whether the item is selected or not. + */ + public static void applyModernIconStyle( + ImageView imageView, Drawable defaultIcon, boolean isSelected) { + imageView.setBackgroundResource(R.drawable.list_item_icon_modern_bg); + Drawable drawable; + if (isSelected) { + drawable = TintedDrawable.constructTintedDrawable( + imageView.getContext(), R.drawable.ic_check_googblue_24dp); + drawable.setTint(SemanticColorUtils.getDefaultIconColorInverse(imageView.getContext())); + } else { + drawable = defaultIcon; + } + imageView.setImageDrawable(drawable); + imageView.getBackground().setLevel(isSelected + ? imageView.getResources().getInteger(R.integer.list_item_level_selected) + : imageView.getResources().getInteger(R.integer.list_item_level_default)); + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkItemRow.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkItemRow.java index ce9ad5c..5a70e9d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkItemRow.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkItemRow.java
@@ -22,6 +22,7 @@ /** * A row view that shows bookmark info in the bookmarks UI. */ +// TODO (crbug.com/1424431): Make this class more extensible. public class BookmarkItemRow extends BookmarkRow implements LargeIconCallback { private GURL mUrl; private RoundedIconGenerator mIconGenerator; @@ -30,19 +31,30 @@ private boolean mFaviconCancelled; /** - * Constructor for inflating from XML. + * Factory constructor for building the view programmatically. + * @param context The calling context, usually the parent view. + * @param isVisualRefreshEnabled Whether to show the visual or compact bookmark row. */ + public static BookmarkItemRow buildView(Context context, boolean isVisualRefreshEnabled) { + BookmarkItemRow row = new BookmarkItemRow(context, null); + BookmarkRow.buildView(row, context, isVisualRefreshEnabled); + return row; + } + + /** Constructor for inflating from XML. */ public BookmarkItemRow(Context context, AttributeSet attrs) { super(context, attrs); - mMinIconSize = isVisualRefreshEnabled() + + boolean isVisualRefreshEnabled = BookmarkFeatures.isBookmarksVisualRefreshEnabled(); + mMinIconSize = isVisualRefreshEnabled ? getResources().getDimensionPixelSize(R.dimen.bookmark_refresh_min_start_icon_size) : getResources().getDimensionPixelSize(R.dimen.default_favicon_min_size); - mDisplayedIconSize = isVisualRefreshEnabled() + mDisplayedIconSize = isVisualRefreshEnabled ? getResources().getDimensionPixelSize( R.dimen.bookmark_refresh_preferred_start_icon_size) : getResources().getDimensionPixelSize(R.dimen.default_favicon_size); - if (isVisualRefreshEnabled()) { + if (isVisualRefreshEnabled) { mIconGenerator = new RoundedIconGenerator(mDisplayedIconSize, mDisplayedIconSize, mDisplayedIconSize / 2, getContext().getColor(R.color.default_favicon_background_color), @@ -98,7 +110,7 @@ if (mFaviconCancelled) return; Drawable iconDrawable = FaviconUtils.getIconDrawableWithoutFilter( icon, mUrl, fallbackColor, mIconGenerator, getResources(), mDisplayedIconSize); - setStartIconDrawable(iconDrawable); + setIconDrawable(iconDrawable); } protected boolean getFaviconCancelledForTesting() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkManagerCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkManagerCoordinator.java index e171a57..4b39ea7 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkManagerCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkManagerCoordinator.java
@@ -13,6 +13,7 @@ import androidx.annotation.LayoutRes; import androidx.annotation.NonNull; +import androidx.annotation.VisibleForTesting; import androidx.recyclerview.widget.RecyclerView; import org.chromium.base.ContextUtils; @@ -247,11 +248,19 @@ case ViewType.SECTION_HEADER: return buildSectionHeaderView(parent); case ViewType.FOLDER: - return buildBookmarkFolderView(parent); + BookmarkFolderRow folderRow = buildBookmarkFolderView(parent); + folderRow.onDelegateInitialized(mMediator); + return folderRow; case ViewType.BOOKMARK: - return buildBookmarkItemView(parent); + BookmarkItemRow itemRow = buildBookmarkItemView(parent); + itemRow.onDelegateInitialized(mMediator); + return itemRow; case ViewType.SHOPPING_POWER_BOOKMARK: - return buildShoppingItemView(parent); + PowerBookmarkShoppingItemRow shoppingItemRow = buildShoppingItemView(parent); + shoppingItemRow.onDelegateInitialized(mMediator); + // TODO(https://crbug.com/1416611): Move init to view binding. + shoppingItemRow.init(mImageFetcher, mBookmarkModel, mSnackbarManager, mProfile); + return shoppingItemRow; case ViewType.DIVIDER: return buildDividerView(parent); case ViewType.SHOPPING_FILTER: @@ -308,20 +317,22 @@ return inflate(parent, org.chromium.chrome.R.layout.bookmark_section_header); } - private View buildBookmarkFolderView(ViewGroup parent) { - return inflateBookmarkRow(parent, org.chromium.chrome.R.layout.bookmark_folder_row); + @VisibleForTesting + static BookmarkFolderRow buildBookmarkFolderView(ViewGroup parent) { + return BookmarkFolderRow.buildView( + parent.getContext(), BookmarkFeatures.isBookmarksVisualRefreshEnabled()); } - private View buildBookmarkItemView(ViewGroup parent) { - return inflateBookmarkRow(parent, org.chromium.chrome.R.layout.bookmark_item_row); + @VisibleForTesting + static BookmarkItemRow buildBookmarkItemView(ViewGroup parent) { + return BookmarkItemRow.buildView( + parent.getContext(), BookmarkFeatures.isBookmarksVisualRefreshEnabled()); } - private View buildShoppingItemView(ViewGroup parent) { - PowerBookmarkShoppingItemRow row = (PowerBookmarkShoppingItemRow) inflateBookmarkRow( - parent, org.chromium.chrome.R.layout.power_bookmark_shopping_item_row); - // TODO(https://crbug.com/1416611): Move init to view binding. - row.init(mImageFetcher, mBookmarkModel, mSnackbarManager, mProfile); - return row; + @VisibleForTesting + static PowerBookmarkShoppingItemRow buildShoppingItemView(ViewGroup parent) { + return PowerBookmarkShoppingItemRow.buildView( + parent.getContext(), BookmarkFeatures.isBookmarksVisualRefreshEnabled()); } private View buildDividerView(ViewGroup parent) { @@ -337,13 +348,6 @@ return LayoutInflater.from(context).inflate(layoutId, parent, false); } - private View inflateBookmarkRow(ViewGroup parent, @LayoutRes int layoutId) { - BookmarkRow row = (BookmarkRow) inflate(parent, layoutId); - // TODO(https://crbug.com/1416611): Move onDelegateInitialized to view binding. - (row).onDelegateInitialized(/*delegate=*/mMediator); - return row; - } - // Testing methods. public BookmarkToolbar getToolbarForTesting() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkRow.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkRow.java index f58ffc35..0cdba36 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkRow.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkRow.java
@@ -7,15 +7,18 @@ import static org.chromium.components.browser_ui.widget.listmenu.BasicListMenu.buildMenuListItem; import android.content.Context; +import android.content.res.ColorStateList; import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.View; +import android.view.ViewGroup; +import android.widget.FrameLayout; import android.widget.ImageView; +import android.widget.TextView; import androidx.annotation.IntDef; +import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; -import androidx.appcompat.content.res.AppCompatResources; -import androidx.core.widget.ImageViewCompat; import org.chromium.base.metrics.RecordUserAction; import org.chromium.chrome.R; @@ -31,7 +34,7 @@ import org.chromium.components.browser_ui.widget.listmenu.ListMenuButton.PopupMenuShownListener; import org.chromium.components.browser_ui.widget.listmenu.ListMenuButtonDelegate; import org.chromium.components.browser_ui.widget.listmenu.ListMenuItemProperties; -import org.chromium.components.browser_ui.widget.selectable_list.SelectableItemView; +import org.chromium.components.browser_ui.widget.selectable_list.CheckableSelectableItemView; import org.chromium.components.browser_ui.widget.selectable_list.SelectableListUtils; import org.chromium.ui.modelutil.MVCListAdapter.ModelList; @@ -43,15 +46,27 @@ * Common logic for bookmark and folder rows. */ public abstract class BookmarkRow - extends SelectableItemView<BookmarkId> implements BookmarkUiObserver { - protected ListMenuButton mMoreIcon; + extends CheckableSelectableItemView<BookmarkId> implements BookmarkUiObserver { + // The start icon view which is shows the favicon and the checkmark. + protected ImageView mStartIconView; + // 3-dot menu which displays contextual actions. + protected ListMenuButton mMoreButton; + // Image shown in selection mode which starts drag/drop. protected ImageView mDragHandle; + // Displays the title of the bookmark. + protected TextView mTitleView; + // Displays the url of the bookmark. + protected TextView mDescriptionView; + protected BookmarkDelegate mDelegate; protected BookmarkId mBookmarkId; + + /** Levels for the background. */ + private final int mDefaultLevel; + private final int mSelectedLevel; private boolean mIsAttachedToWindow; private PopupMenuShownListener mPopupListener; - @Location - private int mLocation; + private @Location int mLocation; private boolean mFromFilterView; @IntDef({Location.TOP, Location.MIDDLE, Location.BOTTOM, Location.SOLO}) @@ -64,13 +79,46 @@ } /** - * Constructor for inflating from XML. + * Factory constructor for building the view programmatically. + * @param row The BookmarkRow to build. + * @param context The calling context, usually the parent view. + * @param isVisualRefreshEnabled Whether to show the visual or compact bookmark row. */ + protected static void buildView( + BookmarkRow row, Context context, boolean isVisualRefreshEnabled) { + row.setLayoutParams(new FrameLayout.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); + LayoutInflater.from(context).inflate(isVisualRefreshEnabled + ? org.chromium.chrome.R.layout.bookmark_row_layout_visual + : org.chromium.chrome.R.layout.bookmark_row_layout, + row); + row.onFinishInflate(); + } + + /** Constructor for inflating from XML. */ public BookmarkRow(Context context, AttributeSet attrs) { super(context, attrs); - if (BookmarkFeatures.isBookmarksVisualRefreshEnabled()) { - enableVisualRefresh(); - } + + mDefaultLevel = getResources().getInteger(R.integer.list_item_level_default); + mSelectedLevel = getResources().getInteger(R.integer.list_item_level_selected); + } + + // FrameLayout implementation. + + @Override + protected void onFinishInflate() { + super.onFinishInflate(); + + mStartIconView = findViewById(R.id.start_icon); + + mDragHandle = findViewById(R.id.drag_handle); + + mMoreButton = findViewById(R.id.more); + mMoreButton.setDelegate(getListMenuButtonDelegate()); + mMoreButton.setVisibility(View.GONE); + + mTitleView = findViewById(R.id.title); + mDescriptionView = findViewById(R.id.description); } /** @@ -89,8 +137,8 @@ mBookmarkId = bookmarkId; mFromFilterView = fromFilterView; BookmarkItem bookmarkItem = mDelegate.getModel().getBookmarkById(bookmarkId); - mMoreIcon.dismiss(); - SelectableListUtils.setContentDescriptionContext(getContext(), mMoreIcon, + mMoreButton.dismiss(); + SelectableListUtils.setContentDescriptionContext(getContext(), mMoreButton, bookmarkItem.getTitle(), SelectableListUtils.ContentDescriptionSource.MENU_BUTTON); setChecked(isItemSelected()); @@ -119,17 +167,17 @@ // If the visibility of the drag handle or more icon is not set later, it will be gone. mDragHandle.setVisibility(GONE); - mMoreIcon.setVisibility(GONE); + mMoreButton.setVisibility(GONE); if (mDelegate.getDragStateDelegate().getDragActive()) { mDragHandle.setVisibility( bookmarkItem.isReorderable() && !mFromFilterView ? VISIBLE : GONE); mDragHandle.setEnabled(isItemSelected()); } else { - mMoreIcon.setVisibility(bookmarkItem.isEditable() ? VISIBLE : GONE); - mMoreIcon.setClickable(!isSelectionModeActive()); - mMoreIcon.setEnabled(mMoreIcon.isClickable()); - mMoreIcon.setImportantForAccessibility(mMoreIcon.isClickable() + mMoreButton.setVisibility(bookmarkItem.isEditable() ? VISIBLE : GONE); + mMoreButton.setClickable(!isSelectionModeActive()); + mMoreButton.setEnabled(mMoreButton.isClickable()); + mMoreButton.setImportantForAccessibility(mMoreButton.isClickable() ? IMPORTANT_FOR_ACCESSIBILITY_YES : IMPORTANT_FOR_ACCESSIBILITY_NO); } @@ -149,12 +197,12 @@ private void initialize() { mDelegate.addUiObserver(this); mPopupListener = () -> mDelegate.onBookmarkItemMenuOpened(); - mMoreIcon.addPopupListener(mPopupListener); + mMoreButton.addPopupListener(mPopupListener); } private void cleanup() { - mMoreIcon.dismiss(); - mMoreIcon.removePopupListener(mPopupListener); + mMoreButton.dismiss(); + mMoreButton.removePopupListener(mPopupListener); if (mDelegate != null) mDelegate.removeUiObserver(this); } @@ -263,20 +311,6 @@ } // FrameLayout implementation. - @Override - protected void onFinishInflate() { - super.onFinishInflate(); - - LayoutInflater.from(getContext()).inflate(R.layout.list_menu_button, mContentView); - mMoreIcon = findViewById(R.id.more); - mMoreIcon.setDelegate(getListMenuButtonDelegate()); - - mDragHandle = mEndButtonView; - mDragHandle.setImageResource(R.drawable.ic_drag_handle_grey600_24dp); - ImageViewCompat.setImageTintList(mDragHandle, - AppCompatResources.getColorStateList( - getContext(), R.color.default_icon_color_tint_list)); - } private ListMenuButtonDelegate getListMenuButtonDelegate() { return this::getListMenu; @@ -298,14 +332,36 @@ cleanup(); } - // SelectableItem implementation. + // CheckableSelectableItemView implementation. + + @Override + protected ImageView getIconView() { + return mStartIconView; + } + + @Override + protected @Nullable ColorStateList getDefaultIconTint() { + return null; + } + + @Override + protected int getSelectedLevel() { + return mSelectedLevel; + } + + @Override + protected int getDefaultLevel() { + return mDefaultLevel; + } + + // BookmarkUiObserver implementation. + @Override public void onSelectionStateChange(List<BookmarkId> selectedBookmarks) { super.onSelectionStateChange(selectedBookmarks); updateVisualState(); } - // BookmarkUiObserver implementation. @Override public void onDestroy() { cleanup(); @@ -321,7 +377,7 @@ return mDelegate.getSelectionDelegate().isItemSelected(mBookmarkId); } - void setDragHandleOnTouchListener(OnTouchListener l) { + void setDragHandleOnTouchListener(View.OnTouchListener l) { mDragHandle.setOnTouchListener(l); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/PowerBookmarkShoppingItemRow.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/PowerBookmarkShoppingItemRow.java index 0d71a25..653d922 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/PowerBookmarkShoppingItemRow.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/PowerBookmarkShoppingItemRow.java
@@ -10,12 +10,12 @@ import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.View; -import android.view.ViewGroup; +import android.widget.FrameLayout; +import android.widget.ImageView; import android.widget.TextView; import androidx.annotation.VisibleForTesting; -import org.chromium.base.ApiCompatibilityUtils; import org.chromium.base.Callback; import org.chromium.chrome.R; import org.chromium.chrome.browser.bookmarks.PowerBookmarkMetrics.PriceTrackingState; @@ -38,6 +38,15 @@ public class PowerBookmarkShoppingItemRow extends BookmarkItemRow { private static final long MICRO_CURRENCY_QUOTIENT = 1000000; + // UI elements. + // Allows subclasses to add special views below the description (e.g. the price for shopping). + protected FrameLayout mCustomTextContainer; + private ImageView mPriceTrackingButton; + private TextView mNormalPriceText; + private TextView mPriceDropPrimaryText; + private TextView mPriceDropSecondaryText; + + // Dependencies. private ImageFetcher mImageFetcher; private BookmarkModel mBookmarkModel; @@ -48,11 +57,44 @@ private SnackbarManager mSnackbarManager; private Profile mProfile; + private final int mPreferredImageSize; + /** - * Constructor for inflating from XML. + * Factory constructor for building the view programmatically. + * @param context The calling context, usually the parent view. + * @param isVisualRefreshEnabled Whether to show the visual or compact bookmark row. */ + public static PowerBookmarkShoppingItemRow buildView( + Context context, boolean isVisualRefreshEnabled) { + PowerBookmarkShoppingItemRow row = new PowerBookmarkShoppingItemRow(context, null); + BookmarkRow.buildView(row, context, isVisualRefreshEnabled); + return row; + } + + /** Constructor for inflating from XML. */ public PowerBookmarkShoppingItemRow(Context context, AttributeSet attrs) { super(context, attrs); + + mPreferredImageSize = getResources().getDimensionPixelSize( + R.dimen.bookmark_refresh_preferred_start_icon_size); + } + + // FrameLayout implementation. + + @Override + protected void onFinishInflate() { + super.onFinishInflate(); + + mPriceTrackingButton = findViewById(R.id.end_icon); + mPriceTrackingButton.setVisibility(View.GONE); + + mCustomTextContainer = findViewById(R.id.custom_content_container); + + LayoutInflater.from(getContext()) + .inflate(R.layout.compact_price_drop_view, mCustomTextContainer); + mNormalPriceText = findViewById(R.id.normal_price_text); + mPriceDropPrimaryText = findViewById(R.id.price_drop_primary_text); + mPriceDropSecondaryText = findViewById(R.id.price_drop_secondary_text); } /** @@ -68,7 +110,8 @@ mProfile = profile; } - // BookmarkItemRow overrides: + // BookmarkItemRow implementation. + @Override BookmarkItem setBookmarkId( BookmarkId bookmarkId, @Location int location, boolean fromFilterView) { @@ -106,24 +149,24 @@ long currentPrice) { assert mCurrencyFormatter != null; - mStartIconView.setOutlineProvider( + getIconView().setOutlineProvider( new RoundedCornerOutlineProvider(getResources().getDimensionPixelSize( R.dimen.list_item_v2_start_icon_corner_radius))); - mStartIconView.setClipToOutline(true); + getIconView().setClipToOutline(true); mImageFetcher.fetchImage( ImageFetcher.Params.create(leadImageUrl, ImageFetcher.POWER_BOOKMARKS_CLIENT_NAME, - mStartIconViewSize, mStartIconViewSize), + mPreferredImageSize, mPreferredImageSize), (image) -> { if (image == null) return; // We've successfully fetched an image. Cancel any pending requests for the // favicon. cancelFavicon(); - setStartIconDrawable(new BitmapDrawable(getResources(), image)); + setIconDrawable(new BitmapDrawable(getResources(), image)); }); setPriceInfoChip(originalPrice, currentPrice); setPriceTrackingButton(priceTrackingEnabled); - mTitleView.setLabelFor(mEndStartButtonView.getId()); + mTitleView.setLabelFor(mPriceTrackingButton.getId()); PowerBookmarkMetrics.reportBookmarkShoppingItemRowPriceTrackingState( PriceTrackingState.PRICE_TRACKING_SHOWN); } @@ -133,20 +176,16 @@ String formattedCurrentPrice = getFormattedCurrencyStringForPrice(currentPrice); // Note: chips should only be shown for price drops if (originalPrice <= currentPrice) { - TextView textView = new TextView(getContext(), null); - ApiCompatibilityUtils.setTextAppearance( - textView, R.styleable.ChipView_primaryTextAppearance); - textView.setText(formattedCurrentPrice); - setCustomContent(textView); + mNormalPriceText.setText(formattedCurrentPrice); + mNormalPriceText.setVisibility(View.VISIBLE); + mPriceDropPrimaryText.setVisibility(View.GONE); + mPriceDropSecondaryText.setVisibility(View.GONE); } else { - ViewGroup row = (ViewGroup) LayoutInflater.from(getContext()) - .inflate(R.layout.compact_price_drop_view, null, false); - TextView primaryText = row.findViewById(R.id.primary_text); - TextView secondaryText = row.findViewById(R.id.secondary_text); - setCustomContent(row); - - assignPriceDropProperties(primaryText, secondaryText, + assignPriceDropProperties(mPriceDropPrimaryText, mPriceDropSecondaryText, getFormattedCurrencyStringForPrice(originalPrice), formattedCurrentPrice); + mNormalPriceText.setVisibility(View.GONE); + mPriceDropPrimaryText.setVisibility(View.VISIBLE); + mPriceDropSecondaryText.setVisibility(View.VISIBLE); } } @@ -164,10 +203,10 @@ /** Sets up the button that allows you to un/subscribe to price-tracking updates. */ private void setPriceTrackingButton(boolean priceTrackingEnabled) { mIsPriceTrackingEnabled = priceTrackingEnabled; - mEndStartButtonView.setContentDescription(getContext().getResources().getString( + mPriceTrackingButton.setContentDescription(getContext().getResources().getString( priceTrackingEnabled ? R.string.disable_price_tracking_menu_item : R.string.enable_price_tracking_menu_item)); - mEndStartButtonView.setVisibility(View.VISIBLE); + mPriceTrackingButton.setVisibility(View.VISIBLE); updatePriceTrackingImageForCurrentState(); Callback<Boolean> subscriptionCallback = (success) -> { mSubscriptionChangeInProgress = false; @@ -176,7 +215,7 @@ mIsPriceTrackingEnabled = !mIsPriceTrackingEnabled; updatePriceTrackingImageForCurrentState(); }; - mEndStartButtonView.setOnClickListener((v) -> { + mPriceTrackingButton.setOnClickListener((v) -> { if (mSubscriptionChangeInProgress) return; mSubscriptionChangeInProgress = true; @@ -190,7 +229,7 @@ } private void updatePriceTrackingImageForCurrentState() { - mEndStartButtonView.setImageResource(mIsPriceTrackingEnabled + mPriceTrackingButton.setImageResource(mIsPriceTrackingEnabled ? R.drawable.price_tracking_enabled_filled : R.drawable.price_tracking_disabled); } @@ -205,6 +244,6 @@ } View getPriceTrackingButtonForTesting() { - return mEndStartButtonView; + return mPriceTrackingButton; } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/CompositorView.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/CompositorView.java index a781fc59..bdd368b5 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/CompositorView.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/CompositorView.java
@@ -375,6 +375,18 @@ createCompositorSurfaceManager(); } + /** + * Enables/disables immersive VR overlay mode, a variant of overlay video mode. + * @param enabled Whether to enter or leave overlay immersive vr mode. + */ + public void setOverlayVrMode(boolean enabled) { + mIsInXr = enabled; + + // We're essentially entering OverlayVideo mode because we're going to be rendering to an + // overlay, but we don't actually need a new composite or to adjust the alpha blend. + mCompositorSurfaceManager.requestSurface(getSurfacePixelFormat()); + } + private int getSurfacePixelFormat() { if (mOverlayVideoEnabled || mAlwaysTranslucent) { return PixelFormat.TRANSLUCENT;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/CompositorViewHolder.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/CompositorViewHolder.java index f719731..7605581 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/CompositorViewHolder.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/CompositorViewHolder.java
@@ -67,6 +67,7 @@ import org.chromium.chrome.browser.tabmodel.TabModelSelectorObserver; import org.chromium.chrome.browser.theme.TopUiThemeColorProvider; import org.chromium.chrome.browser.toolbar.ControlContainer; +import org.chromium.chrome.browser.toolbar.ToolbarFeatures; import org.chromium.chrome.browser.util.ChromeAccessibilityUtil; import org.chromium.chrome.features.start_surface.StartSurfaceUserData; import org.chromium.components.browser_ui.widget.TouchEventObserver; @@ -1370,7 +1371,16 @@ if (mUrlBar != null && mUrlBar.isFocused()) mUrlBar.clearFocus(); boolean wasVisible = false; if (hasFocus()) { - wasVisible = KeyboardVisibilityDelegate.getInstance().hideKeyboard(this); + if (ToolbarFeatures.shouldDelayTransitionsForAnimation()) { + KeyboardVisibilityDelegate keyboardVisibilityDelegate = + KeyboardVisibilityDelegate.getInstance(); + wasVisible = keyboardVisibilityDelegate.isKeyboardShowing(getContext(), this); + if (wasVisible) { + keyboardVisibilityDelegate.hideKeyboard(this); + } + } else { + wasVisible = KeyboardVisibilityDelegate.getInstance().hideKeyboard(this); + } } if (wasVisible) { mPostHideKeyboardTask = postHideTask;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/Layout.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/Layout.java index 2809004c..42a95d63 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/Layout.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/Layout.java
@@ -793,4 +793,9 @@ */ @LayoutType public abstract int getLayoutType(); + + /** Returns whether the layout is currently running animations. */ + public boolean isRunningAnimations() { + return false; + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerImpl.java index f05ff8b..3a22616 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerImpl.java
@@ -59,6 +59,7 @@ import org.chromium.chrome.browser.theme.ThemeUtils; import org.chromium.chrome.browser.theme.TopUiThemeColorProvider; import org.chromium.chrome.browser.toolbar.ControlContainer; +import org.chromium.chrome.browser.toolbar.ToolbarFeatures; import org.chromium.chrome.browser.toolbar.bottom.ScrollingBottomViewSceneLayer; import org.chromium.chrome.browser.toolbar.top.TopToolbarOverlayCoordinator; import org.chromium.chrome.browser.ui.native_page.NativePage; @@ -473,14 +474,17 @@ } mUpdateRequested = false; - // TODO(mdjones): Remove the time related params from this method. The new animation system - // has its own timer. - boolean areAnimatorsComplete = mAnimationHandler.pushUpdate(); - // TODO(crbug.com/1070281): Remove after the FrameRequestSupplier migrates to the animation // system. final Layout layout = getActiveLayout(); + // TODO(mdjones): Remove the time related params from this method. The new animation system + // has its own timer. + boolean areAnimatorsComplete = mAnimationHandler.pushUpdate(); + if (layout != null && ToolbarFeatures.shouldDelayTransitionsForAnimation()) { + areAnimatorsComplete &= !layout.isRunningAnimations(); + } + // TODO(crbug.com/1070281): Layout itself should decide when it's done hiding and done // showing. if (layout != null && layout.onUpdate(timeMs, dtMs) && areAnimatorsComplete) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/feedback/HelpAndFeedbackLauncherImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/feedback/HelpAndFeedbackLauncherImpl.java index e588431f..5c58cc8 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/feedback/HelpAndFeedbackLauncherImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/feedback/HelpAndFeedbackLauncherImpl.java
@@ -38,6 +38,7 @@ private static final String TAG = "HelpAndFeedback"; private static ProfileKeyedMap<HelpAndFeedbackLauncher> sProfileToLauncherMap; + private final HelpAndFeedbackLauncherDelegate mDelegate; private Profile mProfile; @@ -61,6 +62,12 @@ }); } + // TODO(tedchoc): Reduce visibility to private and pass in the Profile once the de-AppHooks + // changes land. + public HelpAndFeedbackLauncherImpl() { + mDelegate = new HelpAndFeedbackLauncherDelegateImpl(); + } + /** * Starts an activity showing a help page for the specified context ID. * @@ -70,6 +77,7 @@ * context and will be used to show a more relevant help page. * @param collector the {@link FeedbackCollector} to use for extra data. Must not be null. */ + // TODO(tedchoc): Remove once the de-AppHooks changes land. protected void show( Activity activity, String helpContext, @Nonnull FeedbackCollector collector) { Log.d(TAG, "Feedback data: " + collector.getBundle()); @@ -83,6 +91,7 @@ * screenshot of. * @param collector the {@link FeedbackCollector} to use for extra data. Must not be null. */ + // TODO(tedchoc): Remove once the de-AppHooks changes land. protected void showFeedback(Activity activity, @Nonnull FeedbackCollector collector) { Log.d(TAG, "Feedback data: " + collector.getBundle()); launchFallbackSupportUri(activity); @@ -103,7 +112,7 @@ new ChromeFeedbackCollector(activity, null /* categoryTag */, null /* description */, new ScreenshotTask(activity), new ChromeFeedbackCollector.InitParams(mProfile, url, helpContext), - collector -> show(activity, helpContext, collector), mProfile); + collector -> mDelegate.show(activity, helpContext, collector), mProfile); } /** @@ -128,7 +137,7 @@ -> { RecordHistogram.recordLongTimesHistogram("Feedback.Duration.FormOpenToSubmit", SystemClock.elapsedRealtime() - startTime); - showFeedback(activity, collector); + mDelegate.showFeedback(activity, collector); }, mProfile); } @@ -161,7 +170,7 @@ new FeedFeedbackCollector(activity, categoryTag, null /* description */, new ScreenshotTask(activity), new FeedFeedbackCollector.InitParams(mProfile, url, feedContext), - collector -> showFeedback(activity, collector), mProfile); + collector -> mDelegate.showFeedback(activity, collector), mProfile); } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryItemView.java b/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryItemView.java index 5912e96..0b00207 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryItemView.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryItemView.java
@@ -5,7 +5,6 @@ package org.chromium.chrome.browser.history; import android.content.Context; -import android.content.res.ColorStateList; import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.view.View; @@ -23,7 +22,6 @@ import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.ui.favicon.FaviconHelper.DefaultFaviconHelper; import org.chromium.chrome.browser.ui.favicon.FaviconUtils; -import org.chromium.components.browser_ui.styles.SemanticColorUtils; import org.chromium.components.browser_ui.util.TraceEventVectorDrawableCompat; import org.chromium.components.browser_ui.widget.RoundedIconGenerator; import org.chromium.components.browser_ui.widget.selectable_list.SelectableItemView; @@ -56,9 +54,6 @@ mIconGenerator = FaviconUtils.createCircularIconGenerator(context); mEndPadding = context.getResources().getDimensionPixelSize(R.dimen.default_list_row_padding); - - mStartIconSelectedColorList = - ColorStateList.valueOf(SemanticColorUtils.getDefaultIconColorInverse(context)); } @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java index b7064c0..a023668 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java
@@ -933,6 +933,9 @@ if (layoutType == LayoutType.TAB_SWITCHER) { mToolbar.onTabSwitcherTransitionFinished(); } + if (ToolbarFeatures.shouldDelayTransitionsForAnimation()) { + mToolbar.onTransitionEnd(); + } } @Override @@ -947,6 +950,9 @@ mControlContainer.invalidateBitmap(); } } + if (ToolbarFeatures.shouldDelayTransitionsForAnimation()) { + mToolbar.onTransitionStart(); + } } @Override
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkItemRowTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkItemRowTest.java index 5afec90..b6cd095 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkItemRowTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkItemRowTest.java
@@ -97,10 +97,7 @@ ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); getActivity().setContentView(mContentView, params); - mBookmarkItemRow = (BookmarkItemRow) getActivity() - .getLayoutInflater() - .inflate(R.layout.bookmark_item_row, mContentView, true) - .findViewById(R.id.bookmark_item_row); + mBookmarkItemRow = BookmarkManagerCoordinator.buildBookmarkItemView(mContentView); mBookmarkItemRow.setRoundedIconGeneratorForTesting(mRoundedIconGenerator); mBookmarkItemRow.onDelegateInitialized(mDelegate); });
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/PowerBookmarkShoppingItemRowRenderTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/PowerBookmarkShoppingItemRowRenderTest.java index fbdb916..d53d98e 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/PowerBookmarkShoppingItemRowRenderTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/PowerBookmarkShoppingItemRowRenderTest.java
@@ -9,6 +9,7 @@ import android.graphics.Bitmap; import android.graphics.Color; +import android.view.View; import android.view.ViewGroup; import android.widget.FrameLayout; import android.widget.LinearLayout; @@ -95,7 +96,7 @@ private Bitmap mBitmap; private PowerBookmarkShoppingItemRow mPowerBookmarkShoppingItemRow; - private ViewGroup mContentView; + private LinearLayout mContentView; public PowerBookmarkShoppingItemRowRenderTest(boolean nightModeEnabled) { // Sets a fake background color to make the screenshots easier to compare with bare eyes. @@ -133,19 +134,18 @@ FrameLayout.LayoutParams params = new FrameLayout.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); - mActivityTestRule.getActivity().setContentView(mContentView, params); + mPowerBookmarkShoppingItemRow = - (PowerBookmarkShoppingItemRow) mActivityTestRule.getActivity() - .getLayoutInflater() - .inflate(R.layout.power_bookmark_shopping_item_row, mContentView, true) - .findViewById(R.id.power_bookmark_shopping_row); + BookmarkManagerCoordinator.buildShoppingItemView(mContentView); + mContentView.addView(mPowerBookmarkShoppingItemRow); mPowerBookmarkShoppingItemRow.setBackgroundColor( SemanticColorUtils.getDefaultBgColor(mActivityTestRule.getActivity())); ((TextView) mPowerBookmarkShoppingItemRow.findViewById(R.id.title)) .setText("Test Bookmark"); ((TextView) mPowerBookmarkShoppingItemRow.findViewById(R.id.description)) .setText("http://google.com"); + mPowerBookmarkShoppingItemRow.findViewById(R.id.more).setVisibility(View.VISIBLE); mPowerBookmarkShoppingItemRow.init( mImageFetcher, mBookmarkModel, mSnackbarManager, mProfile); mPowerBookmarkShoppingItemRow.setCurrencyFormatterForTesting(mCurrencyFormatter);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/PowerBookmarkShoppingItemRowTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/PowerBookmarkShoppingItemRowTest.java index 38adeaa..55b66d3 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/PowerBookmarkShoppingItemRowTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/PowerBookmarkShoppingItemRowTest.java
@@ -95,10 +95,7 @@ getActivity().setContentView(mContentView, params); mPowerBookmarkShoppingItemRow = - (PowerBookmarkShoppingItemRow) getActivity() - .getLayoutInflater() - .inflate(R.layout.power_bookmark_shopping_item_row, mContentView, true) - .findViewById(R.id.power_bookmark_shopping_row); + BookmarkManagerCoordinator.buildShoppingItemView(mContentView); mPowerBookmarkShoppingItemRow.setBackgroundColor( SemanticColorUtils.getDefaultBgColor(getActivity())); ((TextView) mPowerBookmarkShoppingItemRow.findViewById(R.id.title))
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxPedalsRenderTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxPedalsRenderTest.java index b13c6f5..a4cc33d 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxPedalsRenderTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxPedalsRenderTest.java
@@ -23,6 +23,7 @@ import org.chromium.chrome.browser.flags.ChromeSwitches; import org.chromium.chrome.browser.night_mode.ChromeNightModeTestUtils; import org.chromium.chrome.browser.omnibox.OmniboxSuggestionType; +import org.chromium.chrome.browser.omnibox.action.OmniboxActionType; import org.chromium.chrome.browser.omnibox.action.OmniboxPedalType; import org.chromium.chrome.browser.omnibox.suggestions.base.BaseSuggestionView; import org.chromium.chrome.browser.tabmodel.IncognitoTabHostUtils; @@ -111,8 +112,9 @@ private AutocompleteMatch createDummyPedalSuggestion(String name, @OmniboxPedalType int id) { return AutocompleteMatchBuilder.searchWithType(OmniboxSuggestionType.SEARCH_SUGGEST) .setDisplayText(name) - .setActions(Arrays.asList(new OmniboxPedal(id, "hints", "suggestionContents", - "accessibilitySuffix", "accessibilityHint", GURL.emptyGURL()))) + .setActions(Arrays.asList( + new OmniboxPedal(OmniboxActionType.PEDAL, id, "hints", "suggestionContents", + "accessibilitySuffix", "accessibilityHint", GURL.emptyGURL()))) .build(); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxPedalsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxPedalsTest.java index e026c63b..28d0011f 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxPedalsTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxPedalsTest.java
@@ -164,7 +164,7 @@ for (int i = 0; i < coordinator.getSuggestionCount(); ++i) { AutocompleteMatch suggestion = coordinator.getSuggestionAt(i); if (suggestion != null && !suggestion.getActions().isEmpty() - && suggestion.getActions().get(0).getPedalID() == pedalType) { + && suggestion.getActions().get(0).getPedalId() == pedalType) { return suggestion; } } @@ -265,16 +265,16 @@ private AutocompleteMatch createDummyPedalSuggestion(String name, @OmniboxPedalType int id) { return AutocompleteMatchBuilder.searchWithType(OmniboxSuggestionType.SEARCH_SUGGEST) .setDisplayText(name) - .setActions(Arrays.asList(new OmniboxPedal(id, "hints", "suggestionContents", - "accessibilitySuffix", "accessibilityHint", GURL.emptyGURL()))) + .setActions(Arrays.asList( + new OmniboxPedal(OmniboxActionType.PEDAL, id, "hints", "suggestionContents", + "accessibilitySuffix", "accessibilityHint", GURL.emptyGURL()))) .build(); } private AutocompleteMatch createDummyHistoryClustersAction(String name) { return AutocompleteMatchBuilder.searchWithType(OmniboxSuggestionType.SEARCH_SUGGEST) .setDisplayText(name) - .setActions(Arrays.asList(new HistoryClustersAction( - OmniboxActionType.HISTORY_CLUSTERS, "hints", "suggestionContents", + .setActions(Arrays.asList(new HistoryClustersAction("hints", "suggestionContents", "accessibilitySuffix", "accessibilityHint", GURL.emptyGURL(), name))) .build(); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/sync/ui/SyncErrorMessageTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/sync/ui/SyncErrorMessageTest.java index ab86dcc..9600de1 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/sync/ui/SyncErrorMessageTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/sync/ui/SyncErrorMessageTest.java
@@ -59,7 +59,8 @@ */ @RunWith(ChromeJUnit4ClassRunner.class) @DoNotBatch(reason = "TODO(crbug.com/1168590): SyncTestRule doesn't support batching.") -@EnableFeatures({ChromeFeatureList.MESSAGES_FOR_ANDROID_INFRASTRUCTURE}) +@EnableFeatures({ChromeFeatureList.MESSAGES_FOR_ANDROID_INFRASTRUCTURE, + ChromeFeatureList.MESSAGES_FOR_ANDROID_SYNC_ERROR}) @CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE}) public class SyncErrorMessageTest { @Mock
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/app/omnibox/ActionChipsDelegateImplUnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/app/omnibox/ActionChipsDelegateImplUnitTest.java index b9fa114..2101d197 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/app/omnibox/ActionChipsDelegateImplUnitTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/app/omnibox/ActionChipsDelegateImplUnitTest.java
@@ -99,7 +99,7 @@ /** List of all supported OmniboxActionTypes. */ public static final Set<Integer> SUPPORTED_ACTIONS = - ImmutableSet.of(OmniboxActionType.HISTORY_CLUSTERS); + ImmutableSet.of(OmniboxActionType.PEDAL, OmniboxActionType.HISTORY_CLUSTERS); public @Rule MockitoRule mMockitoRule = MockitoJUnit.rule(); private @Mock HistoryClustersCoordinator mHistoryClustersCoordinator; @@ -162,38 +162,46 @@ } /** + * Create Omnibox Action action of a given type. + */ + private OmniboxPedal buildAction(@OmniboxActionType int type) { + return new OmniboxPedal(type, OmniboxPedalType.NONE, "hint", "contents", + "accessibility suffix", "accessibility hint", null); + } + + /** * Create Omnibox Pedal action of a given type. */ - private OmniboxPedal buildAction(@OmniboxPedalType int type) { - return new OmniboxPedal( - type, "hint", "contents", "accessibility suffix", "accessibility hint", null); + private OmniboxPedal buildPedal(@OmniboxPedalType int type) { + return new OmniboxPedal(OmniboxActionType.PEDAL, type, "hint", "contents", + "accessibility suffix", "accessibility hint", null); } /** * Create HistoryCluster Action with a supplied query. */ private HistoryClustersAction buildHistoryClustersAction(String query) { - return new HistoryClustersAction(OmniboxActionType.HISTORY_CLUSTERS, "hint", "contents", - "accessibility suffix", "accessibility hint", null, query); + return new HistoryClustersAction( + "hint", "contents", "accessibility suffix", "accessibility hint", null, query); } @Test public void executePedal_manageChromeSettings() { - mDelegate.execute(buildAction(OmniboxPedalType.MANAGE_CHROME_SETTINGS)); + mDelegate.execute(buildPedal(OmniboxPedalType.MANAGE_CHROME_SETTINGS)); checkSettingsActivityFragmentStarted(null); checkOmniboxPedalUsageRecorded(OmniboxPedalType.MANAGE_CHROME_SETTINGS); } @Test public void executePedal_clearBrowsingData() { - mDelegate.execute(buildAction(OmniboxPedalType.CLEAR_BROWSING_DATA)); + mDelegate.execute(buildPedal(OmniboxPedalType.CLEAR_BROWSING_DATA)); checkSettingsActivityFragmentStarted(ClearBrowsingDataTabsFragment.class); checkOmniboxPedalUsageRecorded(OmniboxPedalType.CLEAR_BROWSING_DATA); } @Test public void executePedal_managePasswords() { - mDelegate.execute(buildAction(OmniboxPedalType.MANAGE_PASSWORDS)); + mDelegate.execute(buildPedal(OmniboxPedalType.MANAGE_PASSWORDS)); assertTrue(ShadowPasswordManagerLauncher.sPasswordSettingsRequested); ShadowPasswordManagerLauncher.reset(); checkOmniboxPedalUsageRecorded(OmniboxPedalType.MANAGE_PASSWORDS); @@ -201,35 +209,35 @@ @Test public void executePedal_updateCreditCard() { - mDelegate.execute(buildAction(OmniboxPedalType.UPDATE_CREDIT_CARD)); + mDelegate.execute(buildPedal(OmniboxPedalType.UPDATE_CREDIT_CARD)); checkSettingsActivityFragmentStarted(AutofillPaymentMethodsFragment.class); checkOmniboxPedalUsageRecorded(OmniboxPedalType.UPDATE_CREDIT_CARD); } @Test public void executePedal_runChromeSafetyCheck() { - mDelegate.execute(buildAction(OmniboxPedalType.RUN_CHROME_SAFETY_CHECK)); + mDelegate.execute(buildPedal(OmniboxPedalType.RUN_CHROME_SAFETY_CHECK)); checkSettingsActivityFragmentStarted(SafetyCheckSettingsFragment.class); checkOmniboxPedalUsageRecorded(OmniboxPedalType.RUN_CHROME_SAFETY_CHECK); } @Test public void executePedal_manageSiteSettings() { - mDelegate.execute(buildAction(OmniboxPedalType.MANAGE_SITE_SETTINGS)); + mDelegate.execute(buildPedal(OmniboxPedalType.MANAGE_SITE_SETTINGS)); checkSettingsActivityFragmentStarted(SiteSettings.class); checkOmniboxPedalUsageRecorded(OmniboxPedalType.MANAGE_SITE_SETTINGS); } @Test public void executePedal_manageChromeAccessibility() { - mDelegate.execute(buildAction(OmniboxPedalType.MANAGE_CHROME_ACCESSIBILITY)); + mDelegate.execute(buildPedal(OmniboxPedalType.MANAGE_CHROME_ACCESSIBILITY)); checkSettingsActivityFragmentStarted(AccessibilitySettings.class); checkOmniboxPedalUsageRecorded(OmniboxPedalType.MANAGE_CHROME_ACCESSIBILITY); } @Test public void executePedal_launchIncognito_fromCustomActivity() { - mDelegate.execute(buildAction(OmniboxPedalType.LAUNCH_INCOGNITO)); + mDelegate.execute(buildPedal(OmniboxPedalType.LAUNCH_INCOGNITO)); var intent = mShadowActivity.getNextStartedActivity(); assertEquals(Intent.ACTION_VIEW, intent.getAction()); @@ -240,7 +248,7 @@ @Test public void executePedal_viewChromeHistory_fromCustomActivity() { - mDelegate.execute(buildAction(OmniboxPedalType.VIEW_CHROME_HISTORY)); + mDelegate.execute(buildPedal(OmniboxPedalType.VIEW_CHROME_HISTORY)); var intent = mShadowActivity.getNextStartedActivity(); assertEquals(HistoryActivity.class.getName(), intent.getComponent().getClassName()); @@ -251,7 +259,7 @@ @Test public void executePedal_playChromeDinoGame_fromCustomActivity() { - mDelegate.execute(buildAction(OmniboxPedalType.PLAY_CHROME_DINO_GAME)); + mDelegate.execute(buildPedal(OmniboxPedalType.PLAY_CHROME_DINO_GAME)); var intent = mShadowActivity.getNextStartedActivity(); assertEquals(Intent.ACTION_VIEW, intent.getAction()); @@ -288,7 +296,7 @@ ImmutableMap.of(OmniboxPedalType.PLAY_CHROME_DINO_GAME, R.drawable.ic_dino); for (var entry : SUPPORTED_PEDALS) { - var icon = mDelegate.getIcon(buildAction(entry)); + var icon = mDelegate.getIcon(buildPedal(entry)); var expectedIconRes = customResourceMap.getOrDefault(entry, R.drawable.fre_product_logo); @@ -312,13 +320,13 @@ // "Local variables referenced by lambda must be effectively final" final int pedalType = type; - assertThrows(AssertionError.class, () -> mDelegate.getIcon(buildAction(pedalType))); + assertThrows(AssertionError.class, () -> mDelegate.getIcon(buildPedal(pedalType))); } } @Test public void verifyDecorations_omniboxActions() { - var icon = mDelegate.getIcon(buildAction(OmniboxActionType.HISTORY_CLUSTERS)); + var icon = mDelegate.getIcon(buildHistoryClustersAction("test")); assertEquals(R.drawable.ic_journeys, icon.iconRes); assertTrue(icon.tintWithTextColor); } @@ -328,7 +336,7 @@ // This test catches introduction of any new action types to make sure we // account for these actions in the verifyDecorations_omniboxActions test. // Guarantees that no new actions can be enabled without proper test coverage. - for (int type = OmniboxActionType.FIRST; type < OmniboxActionType.LAST; type++) { + for (int type = OmniboxActionType.UNKNOWN; type <= OmniboxActionType.LAST; type++) { // Skip past actions we already know we support. if (SUPPORTED_ACTIONS.contains(type)) continue;
diff --git a/chrome/android/profiles/arm.newest.txt b/chrome/android/profiles/arm.newest.txt index 768eddf..9596e34 100644 --- a/chrome/android/profiles/arm.newest.txt +++ b/chrome/android/profiles/arm.newest.txt
@@ -1 +1 @@ -chromeos-chrome-arm-113.0.5635.0_rc-r1-merged.afdo.bz2 +chromeos-chrome-arm-114.0.5676.0_rc-r1-merged.afdo.bz2
diff --git a/chrome/app/chrome_exe_main_win.cc b/chrome/app/chrome_exe_main_win.cc index 2323e25..b98f498 100644 --- a/chrome/app/chrome_exe_main_win.cc +++ b/chrome/app/chrome_exe_main_win.cc
@@ -315,7 +315,7 @@ // emplaced. // Note: The DLL is patched separately, in chrome/app/chrome_main.cc. base::debug::HandleHooks::AddIATPatch(CURRENT_MODULE()); -#endif // !defined(COMPONENT_BUILD) && !DCHECK_IS_ON() +#endif // !defined(COMPONENT_BUILD) && DCHECK_IS_ON() // Confirm that an explicit prefetch profile is used for all process types // except for the browser process. Any new process type will have to assign
diff --git a/chrome/app/settings_chromium_strings.grdp b/chrome/app/settings_chromium_strings.grdp index f3d9170..850e42d6 100644 --- a/chrome/app/settings_chromium_strings.grdp +++ b/chrome/app/settings_chromium_strings.grdp
@@ -11,12 +11,6 @@ <message name="IDS_SETTINGS_ABOUT_PROGRAM" desc="Menu title for the About Chromium page."> About Chromium </message> - <message name="IDS_SETTINGS_GET_THE_MOST_OUT_OF_PROGRAM" desc="Section title for the 'Get the most out of Chromium' page."> - Get the most ouf of Chromium - </message> - <message name="IDS_SETTINGS_GET_THE_MOST_OUT_OF_PROGRAM_DESCRIPTION" desc="Explanatory text for the link to the 'Get the most out of Chromium' page."> - This guide helps you understand your choices, so that Chromium works the way you want to - </message> <message name="IDS_SETTINGS_GET_HELP_USING_CHROME" desc="Text of the button which takes the user to the Chrome help page."> Get help with Chromium </message>
diff --git a/chrome/app/settings_chromium_strings_grdp/IDS_SETTINGS_GET_THE_MOST_OUT_OF_PROGRAM.png.sha1 b/chrome/app/settings_chromium_strings_grdp/IDS_SETTINGS_GET_THE_MOST_OUT_OF_PROGRAM.png.sha1 deleted file mode 100644 index 9cdb789..0000000 --- a/chrome/app/settings_chromium_strings_grdp/IDS_SETTINGS_GET_THE_MOST_OUT_OF_PROGRAM.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -2eb8c42afba366b6db5ca4bf4043d5665f18cd74 \ No newline at end of file
diff --git a/chrome/app/settings_chromium_strings_grdp/IDS_SETTINGS_GET_THE_MOST_OUT_OF_PROGRAM_DESCRIPTION.png.sha1 b/chrome/app/settings_chromium_strings_grdp/IDS_SETTINGS_GET_THE_MOST_OUT_OF_PROGRAM_DESCRIPTION.png.sha1 deleted file mode 100644 index 9cdb789..0000000 --- a/chrome/app/settings_chromium_strings_grdp/IDS_SETTINGS_GET_THE_MOST_OUT_OF_PROGRAM_DESCRIPTION.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -2eb8c42afba366b6db5ca4bf4043d5665f18cd74 \ No newline at end of file
diff --git a/chrome/app/settings_google_chrome_strings.grdp b/chrome/app/settings_google_chrome_strings.grdp index 242c3c7..2fd0bbe 100644 --- a/chrome/app/settings_google_chrome_strings.grdp +++ b/chrome/app/settings_google_chrome_strings.grdp
@@ -11,12 +11,6 @@ <message name="IDS_SETTINGS_ABOUT_PROGRAM" desc="Menu title for the About Chrome page."> About Chrome </message> - <message name="IDS_SETTINGS_GET_THE_MOST_OUT_OF_PROGRAM" desc="Section title for the 'Get the most out of Chrome' page."> - Get the most ouf of Chrome - </message> - <message name="IDS_SETTINGS_GET_THE_MOST_OUT_OF_PROGRAM_DESCRIPTION" desc="Explanatory text for the link to the 'Get the most out of Chrome' page."> - This guide helps you understand your choices, so that Chrome works the way you want to - </message> <message name="IDS_SETTINGS_GET_HELP_USING_CHROME" desc="Text of the button which takes the user to the Chrome help page."> Get help with Chrome </message>
diff --git a/chrome/app/settings_strings.grdp b/chrome/app/settings_strings.grdp index a2e0a9e5..159a2cd 100644 --- a/chrome/app/settings_strings.grdp +++ b/chrome/app/settings_strings.grdp
@@ -50,6 +50,12 @@ <message name="IDS_SETTINGS_ABOUT_PAGE_SEND_FEEDBACK" desc="Text of the button which allows the user to send feedback with Chrome."> Send feedback </message> + <message name="IDS_SETTINGS_GET_THE_MOST_OUT_OF_CHROME" desc="Section title for the 'Get the most out of Chrome' page."> + Get the most ouf of Chrome + </message> + <message name="IDS_SETTINGS_GET_THE_MOST_OUT_OF_CHROME_DESCRIPTION" desc="Explanatory text for the link to the 'Get the most out of Chrome' page."> + This guide helps you understand your choices, so that Chrome works the way you want to + </message> </if> <if expr="is_macosx"> <message name="IDS_ABOUT_CHROME_AUTOUPDATE_ALL" desc="The 'Automatically update Chrome for all users.' button in the About window. Mac-only.">
diff --git a/chrome/app/settings_google_chrome_strings_grdp/IDS_SETTINGS_GET_THE_MOST_OUT_OF_PROGRAM.png.sha1 b/chrome/app/settings_strings_grdp/IDS_SETTINGS_GET_THE_MOST_OUT_OF_CHROME.png.sha1 similarity index 100% rename from chrome/app/settings_google_chrome_strings_grdp/IDS_SETTINGS_GET_THE_MOST_OUT_OF_PROGRAM.png.sha1 rename to chrome/app/settings_strings_grdp/IDS_SETTINGS_GET_THE_MOST_OUT_OF_CHROME.png.sha1
diff --git a/chrome/app/settings_google_chrome_strings_grdp/IDS_SETTINGS_GET_THE_MOST_OUT_OF_PROGRAM_DESCRIPTION.png.sha1 b/chrome/app/settings_strings_grdp/IDS_SETTINGS_GET_THE_MOST_OUT_OF_CHROME_DESCRIPTION.png.sha1 similarity index 100% rename from chrome/app/settings_google_chrome_strings_grdp/IDS_SETTINGS_GET_THE_MOST_OUT_OF_PROGRAM_DESCRIPTION.png.sha1 rename to chrome/app/settings_strings_grdp/IDS_SETTINGS_GET_THE_MOST_OUT_OF_CHROME_DESCRIPTION.png.sha1
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 6eee5f9..23e1682 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -1404,6 +1404,13 @@ kJourneysSearchVisitsWithPairwiseMergeParams, std::size(kJourneysSearchVisitsWithPairwiseMergeParams), nullptr}, }; +const FeatureEntry::FeatureParam kJourneysImagesCoverParams[] = { + {"JourneysImagesCover", "false"}, +}; +const FeatureEntry::FeatureVariation kJourneysImagesVariations[] = { + {"Image Does Not Cover Container", kJourneysImagesCoverParams, + std::size(kJourneysImagesCoverParams), nullptr}, +}; const FeatureEntry::FeatureParam kJourneysLabelsWithSearchVisitEntitiesParams[] = { {"labels_from_search_visit_entities", "true"}, @@ -5781,7 +5788,9 @@ {"history-journeys-images", flag_descriptions::kJourneysImagesName, flag_descriptions::kJourneysImagesDescription, kOsDesktop, - FEATURE_VALUE_TYPE(history_clusters::internal::kJourneysImages)}, + FEATURE_WITH_PARAMS_VALUE_TYPE(history_clusters::internal::kJourneysImages, + kJourneysImagesVariations, + "HistoryJourneysImages")}, {"history-journeys-labels", flag_descriptions::kJourneysLabelsName, flag_descriptions::kJourneysLabelsDescription, kOsDesktop | kOsAndroid, @@ -9842,11 +9851,11 @@ FEATURE_VALUE_TYPE(ash::features::kDeskButton)}, #endif -#if !BUILDFLAG(IS_ANDROID) - {"settings-enable-get-the-most-out-of-program", - flag_descriptions::kSettingsEnableGetTheMostOutOfProgramName, - flag_descriptions::kSettingsEnableGetTheMostOutOfProgramDescription, - kOsDesktop, FEATURE_VALUE_TYPE(::features::kGetTheMostOutOfProgram)}, +#if !BUILDFLAG(IS_ANDROID) && BUILDFLAG(GOOGLE_CHROME_BRANDING) + {"settings-enable-get-the-most-out-of-chrome", + flag_descriptions::kSettingsEnableGetTheMostOutOfChromeName, + flag_descriptions::kSettingsEnableGetTheMostOutOfChromeDescription, + kOsDesktop, FEATURE_VALUE_TYPE(::features::kGetTheMostOutOfChrome)}, #endif #if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_ANDROID) @@ -9858,6 +9867,13 @@ autofill::features::kAutofillEnablePaymentsMandatoryReauth)}, #endif // BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_ANDROID) + {"autofill-enable-email-otp-for-vcn-yellow-path", + flag_descriptions::kAutofillEnableEmailOtpForVcnYellowPathName, + flag_descriptions::kAutofillEnableEmailOtpForVcnYellowPathDescription, + kOsAll, + FEATURE_VALUE_TYPE( + autofill::features::kAutofillEnableEmailOtpForVcnYellowPath)}, + // NOTE: Adding a new flag requires adding a corresponding entry to enum // "LoginCustomFlags" in tools/metrics/histograms/enums.xml. See "Flag // Histograms" in tools/metrics/histograms/README.md (run the
diff --git a/chrome/browser/accessibility/live_caption/live_caption_speech_recognition_host.cc b/chrome/browser/accessibility/live_caption/live_caption_speech_recognition_host.cc index 144fb427..7373ba0 100644 --- a/chrome/browser/accessibility/live_caption/live_caption_speech_recognition_host.cc +++ b/chrome/browser/accessibility/live_caption/live_caption_speech_recognition_host.cc
@@ -5,17 +5,25 @@ #include "chrome/browser/accessibility/live_caption/live_caption_speech_recognition_host.h" #include <memory> +#include <string> #include <utility> +#include "base/feature_list.h" #include "base/functional/callback_forward.h" #include "build/build_config.h" #include "chrome/browser/accessibility/caption_bubble_context_browser.h" #include "chrome/browser/accessibility/live_caption/live_caption_controller_factory.h" +#include "chrome/browser/accessibility/live_translate_controller_factory.h" #include "chrome/browser/profiles/profile.h" #include "components/live_caption/live_caption_controller.h" +#include "components/live_caption/live_translate_controller.h" +#include "components/live_caption/pref_names.h" #include "components/live_caption/views/caption_bubble_model.h" +#include "components/prefs/pref_service.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/web_contents.h" +#include "media/base/media_switches.h" +#include "media/mojo/mojom/speech_recognition_result.h" #include "mojo/public/cpp/bindings/self_owned_receiver.h" namespace captions { @@ -42,6 +50,8 @@ if (!web_contents) return; Observe(web_contents); + prefs_ = Profile::FromBrowserContext(GetWebContents()->GetBrowserContext()) + ->GetPrefs(); context_ = CaptionBubbleContextBrowser::Create(web_contents); } @@ -59,8 +69,22 @@ std::move(reply).Run(false); return; } - std::move(reply).Run( - live_caption_controller->DispatchTranscription(context_.get(), result)); + + if (base::FeatureList::IsEnabled(media::kLiveTranslate) && + prefs_->GetBoolean(prefs::kLiveTranslateEnabled)) { + std::string source_language = + prefs_->GetString(prefs::kLiveCaptionLanguageCode); + std::string target_language = + prefs_->GetString(prefs::kLiveTranslateTargetLanguageCode); + GetLiveTranslateController()->GetTranslation( + result, source_language, target_language, + base::BindOnce(&LiveCaptionSpeechRecognitionHost::OnTranslationCallback, + weak_factory_.GetWeakPtr())); + std::move(reply).Run(!stop_transcriptions_); + } else { + std::move(reply).Run( + live_caption_controller->DispatchTranscription(context_.get(), result)); + } } void LiveCaptionSpeechRecognitionHost::OnLanguageIdentificationEvent( @@ -97,6 +121,13 @@ } #endif +void LiveCaptionSpeechRecognitionHost::OnTranslationCallback( + media::SpeechRecognitionResult result) { + LiveCaptionController* live_caption_controller = GetLiveCaptionController(); + stop_transcriptions_ = + !live_caption_controller->DispatchTranscription(context_.get(), result); +} + content::WebContents* LiveCaptionSpeechRecognitionHost::GetWebContents() { return content::WebContents::FromRenderFrameHost(&render_frame_host()); } @@ -113,4 +144,18 @@ return LiveCaptionControllerFactory::GetForProfile(profile); } +LiveTranslateController* +LiveCaptionSpeechRecognitionHost::GetLiveTranslateController() { + content::WebContents* web_contents = GetWebContents(); + if (!web_contents) { + return nullptr; + } + Profile* profile = + Profile::FromBrowserContext(web_contents->GetBrowserContext()); + if (!profile) { + return nullptr; + } + return LiveTranslateControllerFactory::GetForProfile(profile); +} + } // namespace captions
diff --git a/chrome/browser/accessibility/live_caption/live_caption_speech_recognition_host.h b/chrome/browser/accessibility/live_caption/live_caption_speech_recognition_host.h index e262f877..78458e1 100644 --- a/chrome/browser/accessibility/live_caption/live_caption_speech_recognition_host.h +++ b/chrome/browser/accessibility/live_caption/live_caption_speech_recognition_host.h
@@ -7,12 +7,15 @@ #include <memory> +#include "base/memory/weak_ptr.h" #include "build/build_config.h" #include "content/public/browser/document_service.h" #include "content/public/browser/web_contents_observer.h" #include "media/mojo/mojom/speech_recognition.mojom.h" #include "mojo/public/cpp/bindings/pending_receiver.h" +class PrefService; + namespace content { class RenderFrameHost; } @@ -21,6 +24,7 @@ class CaptionBubbleContextBrowser; class LiveCaptionController; +class LiveTranslateController; /////////////////////////////////////////////////////////////////////////////// // Live Caption Speech Recognition Host @@ -68,16 +72,30 @@ mojo::PendingReceiver<media::mojom::SpeechRecognitionRecognizerClient> pending_receiver); ~LiveCaptionSpeechRecognitionHost() override; + void OnTranslationCallback(media::SpeechRecognitionResult result); // Returns the WebContents if it exists. If it does not exist, sets the // RenderFrameHost reference to nullptr and returns nullptr. content::WebContents* GetWebContents(); // Returns the LiveCaptionController for frame_host_. Returns nullptr if it - // does not exist. + // does not exist. Lifetime is tied to the BrowserContext. LiveCaptionController* GetLiveCaptionController(); + // Returns the LiveTranslateController for frame_host_. Returns nullptr if it + // does not exist. Lifetime is tied to the BrowserContext. + LiveTranslateController* GetLiveTranslateController(); + std::unique_ptr<CaptionBubbleContextBrowser> context_; + + // A flag used by the Live Translate feature indicating whether transcriptions + // should stop. + bool stop_transcriptions_ = false; + + // The user preferences containing the target and source language codes. + PrefService* prefs_; + + base::WeakPtrFactory<LiveCaptionSpeechRecognitionHost> weak_factory_{this}; }; } // namespace captions
diff --git a/chrome/browser/accessibility/live_caption/live_caption_speech_recognition_host_browsertest.cc b/chrome/browser/accessibility/live_caption/live_caption_speech_recognition_host_browsertest.cc index 8b7ebd0..c1d8e3b 100644 --- a/chrome/browser/accessibility/live_caption/live_caption_speech_recognition_host_browsertest.cc +++ b/chrome/browser/accessibility/live_caption/live_caption_speech_recognition_host_browsertest.cc
@@ -243,4 +243,24 @@ } #endif +IN_PROC_BROWSER_TEST_F(LiveCaptionSpeechRecognitionHostTest, LiveTranslate) { + content::RenderFrameHost* frame_host = browser() + ->tab_strip_model() + ->GetActiveWebContents() + ->GetPrimaryMainFrame(); + CreateLiveCaptionSpeechRecognitionHost(frame_host); + + SetLiveCaptionEnabled(true); + SetLiveTranslateEnabled(true); + + // Dispatching the speech recognition should be successful, but the + // widget should remain hidden because the test does not fetch real + // translations. + OnSpeechRecognitionRecognitionEvent( + frame_host, "Elephants can live over 90 years in captivity.", + /* expected_success= */ true); + base::RunLoop().RunUntilIdle(); + ExpectIsWidgetVisible(false); +} + } // namespace captions
diff --git a/chrome/browser/accessibility/live_caption/live_caption_test_util.cc b/chrome/browser/accessibility/live_caption/live_caption_test_util.cc index ddc2b5e3..49cde9c 100644 --- a/chrome/browser/accessibility/live_caption/live_caption_test_util.cc +++ b/chrome/browser/accessibility/live_caption/live_caption_test_util.cc
@@ -33,7 +33,8 @@ // Chrome feature flags that gate Live Caption. std::vector<base::test::FeatureRef> RequiredFeatureFlags() { - std::vector<base::test::FeatureRef> features = {media::kLiveCaption}; + std::vector<base::test::FeatureRef> features = {media::kLiveCaption, + media::kLiveTranslate}; #if BUILDFLAG(IS_CHROMEOS_ASH) features.push_back(ash::features::kOnDeviceSpeechRecognition); #endif @@ -79,4 +80,9 @@ } } +void LiveCaptionBrowserTest::SetLiveTranslateEnabled(bool enabled) { + browser()->profile()->GetPrefs()->SetBoolean(prefs::kLiveTranslateEnabled, + enabled); +} + } // namespace captions
diff --git a/chrome/browser/accessibility/live_caption/live_caption_test_util.h b/chrome/browser/accessibility/live_caption/live_caption_test_util.h index ca529bd..6fc0121d 100644 --- a/chrome/browser/accessibility/live_caption/live_caption_test_util.h +++ b/chrome/browser/accessibility/live_caption/live_caption_test_util.h
@@ -29,8 +29,12 @@ // Enables/disables the live caption pref on the specified profile (or default // profile) and marks the SODA library as installed. void SetLiveCaptionEnabled(bool enabled); + void SetLiveCaptionEnabledOnProfile(bool enabled, Profile* profile); + // Enables/disables the live translate pref. + void SetLiveTranslateEnabled(bool enabled); + private: base::test::ScopedFeatureList scoped_feature_list_; };
diff --git a/chrome/browser/ash/BUILD.gn b/chrome/browser/ash/BUILD.gn index f6eced84..aa1ae38 100644 --- a/chrome/browser/ash/BUILD.gn +++ b/chrome/browser/ash/BUILD.gn
@@ -3102,8 +3102,8 @@ "wallpaper/wallpaper_drivefs_delegate_impl.h", "wallpaper/wallpaper_enumerator.cc", "wallpaper/wallpaper_enumerator.h", - "wallpaper_handlers/backdrop_fetcher_delegate.cc", - "wallpaper_handlers/backdrop_fetcher_delegate.h", + "wallpaper_handlers/wallpaper_fetcher_delegate.cc", + "wallpaper_handlers/wallpaper_fetcher_delegate.h", "wallpaper_handlers/wallpaper_handlers.cc", "wallpaper_handlers/wallpaper_handlers.h", "wallpaper_handlers/wallpaper_handlers_metric_utils.cc", @@ -4521,8 +4521,8 @@ "settings/scoped_testing_cros_settings.h", "wallpaper_handlers/mock_wallpaper_handlers.cc", "wallpaper_handlers/mock_wallpaper_handlers.h", - "wallpaper_handlers/test_backdrop_fetcher_delegate.cc", - "wallpaper_handlers/test_backdrop_fetcher_delegate.h", + "wallpaper_handlers/test_wallpaper_fetcher_delegate.cc", + "wallpaper_handlers/test_wallpaper_fetcher_delegate.h", "web_applications/personalization_app/personalization_app_browsertest_fixture.cc", "web_applications/personalization_app/personalization_app_browsertest_fixture.h", ]
diff --git a/chrome/browser/ash/arc/wallpaper/arc_wallpaper_service_unittest.cc b/chrome/browser/ash/arc/wallpaper/arc_wallpaper_service_unittest.cc index b11e4c2..32f9aad05 100644 --- a/chrome/browser/ash/arc/wallpaper/arc_wallpaper_service_unittest.cc +++ b/chrome/browser/ash/arc/wallpaper/arc_wallpaper_service_unittest.cc
@@ -17,7 +17,7 @@ #include "base/functional/bind.h" #include "base/memory/ptr_util.h" #include "chrome/browser/ash/login/users/fake_chrome_user_manager.h" -#include "chrome/browser/ash/wallpaper_handlers/test_backdrop_fetcher_delegate.h" +#include "chrome/browser/ash/wallpaper_handlers/test_wallpaper_fetcher_delegate.h" #include "chrome/browser/image_decoder/image_decoder.h" #include "chrome/browser/ui/ash/test_wallpaper_controller.h" #include "chrome/browser/ui/ash/wallpaper_controller_client_impl.h" @@ -88,7 +88,7 @@ // Wallpaper wallpaper_controller_client_ = std::make_unique< WallpaperControllerClientImpl>( - std::make_unique<wallpaper_handlers::TestBackdropFetcherDelegate>()); + std::make_unique<wallpaper_handlers::TestWallpaperFetcherDelegate>()); wallpaper_controller_client_->InitForTesting(&test_wallpaper_controller_); // Arc services
diff --git a/chrome/browser/ash/crosapi/wallpaper_ash_unittest.cc b/chrome/browser/ash/crosapi/wallpaper_ash_unittest.cc index 1b35b05..e223b85 100644 --- a/chrome/browser/ash/crosapi/wallpaper_ash_unittest.cc +++ b/chrome/browser/ash/crosapi/wallpaper_ash_unittest.cc
@@ -10,7 +10,7 @@ #include "chrome/browser/ash/crosapi/wallpaper_ash.h" #include "chrome/browser/ash/login/users/fake_chrome_user_manager.h" #include "chrome/browser/ash/profiles/profile_helper.h" -#include "chrome/browser/ash/wallpaper_handlers/test_backdrop_fetcher_delegate.h" +#include "chrome/browser/ash/wallpaper_handlers/test_wallpaper_fetcher_delegate.h" #include "chrome/browser/ui/ash/test_wallpaper_controller.h" #include "chrome/browser/ui/ash/wallpaper_controller_client_impl.h" #include "chrome/test/base/testing_browser_process.h" @@ -72,7 +72,7 @@ // Create Wallpaper Controller Client. wallpaper_controller_client_ = std::make_unique< WallpaperControllerClientImpl>( - std::make_unique<wallpaper_handlers::TestBackdropFetcherDelegate>()); + std::make_unique<wallpaper_handlers::TestWallpaperFetcherDelegate>()); wallpaper_controller_client_->InitForTesting(&test_wallpaper_controller_); }
diff --git a/chrome/browser/ash/login/demo_mode/demo_session_unittest.cc b/chrome/browser/ash/login/demo_mode/demo_session_unittest.cc index 25602e7..37735e9a 100644 --- a/chrome/browser/ash/login/demo_mode/demo_session_unittest.cc +++ b/chrome/browser/ash/login/demo_mode/demo_session_unittest.cc
@@ -17,7 +17,7 @@ #include "base/timer/mock_timer.h" #include "chrome/browser/ash/login/demo_mode/demo_components.h" #include "chrome/browser/ash/login/users/fake_chrome_user_manager.h" -#include "chrome/browser/ash/wallpaper_handlers/test_backdrop_fetcher_delegate.h" +#include "chrome/browser/ash/wallpaper_handlers/test_wallpaper_fetcher_delegate.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/browser_process_platform_part.h" #include "chrome/browser/component_updater/fake_cros_component_manager.h" @@ -75,7 +75,7 @@ session_manager_ = std::make_unique<session_manager::SessionManager>(); wallpaper_controller_client_ = std::make_unique< WallpaperControllerClientImpl>( - std::make_unique<wallpaper_handlers::TestBackdropFetcherDelegate>()); + std::make_unique<wallpaper_handlers::TestWallpaperFetcherDelegate>()); wallpaper_controller_client_->InitForTesting(&test_wallpaper_controller_); }
diff --git a/chrome/browser/ash/login/users/user_manager_unittest.cc b/chrome/browser/ash/login/users/user_manager_unittest.cc index 12b5d708..4b43ab8 100644 --- a/chrome/browser/ash/login/users/user_manager_unittest.cc +++ b/chrome/browser/ash/login/users/user_manager_unittest.cc
@@ -20,7 +20,7 @@ #include "chrome/browser/ash/policy/core/device_local_account.h" #include "chrome/browser/ash/profiles/profile_helper.h" #include "chrome/browser/ash/settings/scoped_cros_settings_test_helper.h" -#include "chrome/browser/ash/wallpaper_handlers/test_backdrop_fetcher_delegate.h" +#include "chrome/browser/ash/wallpaper_handlers/test_wallpaper_fetcher_delegate.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_manager.h" @@ -164,7 +164,7 @@ wallpaper_controller_client_ = std::make_unique< WallpaperControllerClientImpl>( - std::make_unique<wallpaper_handlers::TestBackdropFetcherDelegate>()); + std::make_unique<wallpaper_handlers::TestWallpaperFetcherDelegate>()); wallpaper_controller_client_->InitForTesting(&test_wallpaper_controller_); }
diff --git a/chrome/browser/ash/wallpaper_handlers/backdrop_fetcher_delegate.h b/chrome/browser/ash/wallpaper_handlers/backdrop_fetcher_delegate.h deleted file mode 100644 index e83712d..0000000 --- a/chrome/browser/ash/wallpaper_handlers/backdrop_fetcher_delegate.h +++ /dev/null
@@ -1,49 +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. - -#ifndef CHROME_BROWSER_ASH_WALLPAPER_HANDLERS_BACKDROP_FETCHER_DELEGATE_H_ -#define CHROME_BROWSER_ASH_WALLPAPER_HANDLERS_BACKDROP_FETCHER_DELEGATE_H_ - -#include <memory> -#include <string> - -namespace wallpaper_handlers { - -class BackdropCollectionInfoFetcher; -class BackdropImageInfoFetcher; - -// Delegate class for creating backdrop fetchers. Abstract class to allow -// mocking out in test. -class BackdropFetcherDelegate { - public: - virtual ~BackdropFetcherDelegate() = default; - - virtual std::unique_ptr<BackdropCollectionInfoFetcher> - CreateBackdropCollectionInfoFetcher() const = 0; - - virtual std::unique_ptr<BackdropImageInfoFetcher> - CreateBackdropImageInfoFetcher(const std::string& collection_id) const = 0; -}; - -class BackdropFetcherDelegateImpl : public BackdropFetcherDelegate { - public: - BackdropFetcherDelegateImpl(); - - BackdropFetcherDelegateImpl(const BackdropFetcherDelegateImpl&) = delete; - BackdropFetcherDelegateImpl& operator=(const BackdropFetcherDelegateImpl&) = - delete; - - ~BackdropFetcherDelegateImpl() override; - - // BackdropFetcherDelegate: - std::unique_ptr<BackdropCollectionInfoFetcher> - CreateBackdropCollectionInfoFetcher() const override; - - std::unique_ptr<BackdropImageInfoFetcher> CreateBackdropImageInfoFetcher( - const std::string& collection_id) const override; -}; - -} // namespace wallpaper_handlers - -#endif // CHROME_BROWSER_ASH_WALLPAPER_HANDLERS_BACKDROP_FETCHER_DELEGATE_H_
diff --git a/chrome/browser/ash/wallpaper_handlers/test_backdrop_fetcher_delegate.h b/chrome/browser/ash/wallpaper_handlers/test_backdrop_fetcher_delegate.h deleted file mode 100644 index 235ed40..0000000 --- a/chrome/browser/ash/wallpaper_handlers/test_backdrop_fetcher_delegate.h +++ /dev/null
@@ -1,36 +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. - -#ifndef CHROME_BROWSER_ASH_WALLPAPER_HANDLERS_TEST_BACKDROP_FETCHER_DELEGATE_H_ -#define CHROME_BROWSER_ASH_WALLPAPER_HANDLERS_TEST_BACKDROP_FETCHER_DELEGATE_H_ - -#include <memory> -#include <string> - -#include "chrome/browser/ash/wallpaper_handlers/backdrop_fetcher_delegate.h" - -namespace wallpaper_handlers { - -class BackdropCollectionInfoFetcher; -class BackdropImageInfoFetcher; - -class TestBackdropFetcherDelegate : public BackdropFetcherDelegate { - public: - TestBackdropFetcherDelegate(); - - TestBackdropFetcherDelegate(const TestBackdropFetcherDelegate&) = delete; - TestBackdropFetcherDelegate& operator=(const TestBackdropFetcherDelegate&) = - delete; - - ~TestBackdropFetcherDelegate() override; - - // BackdropFetcherDelegate: - std::unique_ptr<BackdropCollectionInfoFetcher> - CreateBackdropCollectionInfoFetcher() const override; - std::unique_ptr<BackdropImageInfoFetcher> CreateBackdropImageInfoFetcher( - const std::string& collection_id) const override; -}; - -} // namespace wallpaper_handlers -#endif // CHROME_BROWSER_ASH_WALLPAPER_HANDLERS_TEST_BACKDROP_FETCHER_DELEGATE_H_
diff --git a/chrome/browser/ash/wallpaper_handlers/test_backdrop_fetcher_delegate.cc b/chrome/browser/ash/wallpaper_handlers/test_wallpaper_fetcher_delegate.cc similarity index 67% rename from chrome/browser/ash/wallpaper_handlers/test_backdrop_fetcher_delegate.cc rename to chrome/browser/ash/wallpaper_handlers/test_wallpaper_fetcher_delegate.cc index 62fb88a..9e5c220 100644 --- a/chrome/browser/ash/wallpaper_handlers/test_backdrop_fetcher_delegate.cc +++ b/chrome/browser/ash/wallpaper_handlers/test_wallpaper_fetcher_delegate.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/ash/wallpaper_handlers/test_backdrop_fetcher_delegate.h" +#include "chrome/browser/ash/wallpaper_handlers/test_wallpaper_fetcher_delegate.h" #include <memory> #include <string> @@ -13,18 +13,18 @@ namespace wallpaper_handlers { -TestBackdropFetcherDelegate::TestBackdropFetcherDelegate() = default; +TestWallpaperFetcherDelegate::TestWallpaperFetcherDelegate() = default; -TestBackdropFetcherDelegate::~TestBackdropFetcherDelegate() = default; +TestWallpaperFetcherDelegate::~TestWallpaperFetcherDelegate() = default; std::unique_ptr<BackdropCollectionInfoFetcher> -TestBackdropFetcherDelegate::CreateBackdropCollectionInfoFetcher() const { +TestWallpaperFetcherDelegate::CreateBackdropCollectionInfoFetcher() const { return std::make_unique< testing::NiceMock<MockBackdropCollectionInfoFetcher>>(); } std::unique_ptr<BackdropImageInfoFetcher> -TestBackdropFetcherDelegate::CreateBackdropImageInfoFetcher( +TestWallpaperFetcherDelegate::CreateBackdropImageInfoFetcher( const std::string& collection_id) const { return std::make_unique<testing::NiceMock<MockBackdropImageInfoFetcher>>( collection_id);
diff --git a/chrome/browser/ash/wallpaper_handlers/test_wallpaper_fetcher_delegate.h b/chrome/browser/ash/wallpaper_handlers/test_wallpaper_fetcher_delegate.h new file mode 100644 index 0000000..b544537 --- /dev/null +++ b/chrome/browser/ash/wallpaper_handlers/test_wallpaper_fetcher_delegate.h
@@ -0,0 +1,36 @@ +// 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 CHROME_BROWSER_ASH_WALLPAPER_HANDLERS_TEST_WALLPAPER_FETCHER_DELEGATE_H_ +#define CHROME_BROWSER_ASH_WALLPAPER_HANDLERS_TEST_WALLPAPER_FETCHER_DELEGATE_H_ + +#include <memory> +#include <string> + +#include "chrome/browser/ash/wallpaper_handlers/wallpaper_fetcher_delegate.h" + +namespace wallpaper_handlers { + +class BackdropCollectionInfoFetcher; +class BackdropImageInfoFetcher; + +class TestWallpaperFetcherDelegate : public WallpaperFetcherDelegate { + public: + TestWallpaperFetcherDelegate(); + + TestWallpaperFetcherDelegate(const TestWallpaperFetcherDelegate&) = delete; + TestWallpaperFetcherDelegate& operator=(const TestWallpaperFetcherDelegate&) = + delete; + + ~TestWallpaperFetcherDelegate() override; + + // WallpaperFetcherDelegate: + std::unique_ptr<BackdropCollectionInfoFetcher> + CreateBackdropCollectionInfoFetcher() const override; + std::unique_ptr<BackdropImageInfoFetcher> CreateBackdropImageInfoFetcher( + const std::string& collection_id) const override; +}; + +} // namespace wallpaper_handlers +#endif // CHROME_BROWSER_ASH_WALLPAPER_HANDLERS_TEST_WALLPAPER_FETCHER_DELEGATE_H_
diff --git a/chrome/browser/ash/wallpaper_handlers/backdrop_fetcher_delegate.cc b/chrome/browser/ash/wallpaper_handlers/wallpaper_fetcher_delegate.cc similarity index 68% rename from chrome/browser/ash/wallpaper_handlers/backdrop_fetcher_delegate.cc rename to chrome/browser/ash/wallpaper_handlers/wallpaper_fetcher_delegate.cc index 21e5762c..3f20884 100644 --- a/chrome/browser/ash/wallpaper_handlers/backdrop_fetcher_delegate.cc +++ b/chrome/browser/ash/wallpaper_handlers/wallpaper_fetcher_delegate.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/ash/wallpaper_handlers/backdrop_fetcher_delegate.h" +#include "chrome/browser/ash/wallpaper_handlers/wallpaper_fetcher_delegate.h" #include <memory> #include <string> @@ -12,18 +12,18 @@ namespace wallpaper_handlers { -BackdropFetcherDelegateImpl::BackdropFetcherDelegateImpl() = default; +WallpaperFetcherDelegateImpl::WallpaperFetcherDelegateImpl() = default; -BackdropFetcherDelegateImpl::~BackdropFetcherDelegateImpl() = default; +WallpaperFetcherDelegateImpl::~WallpaperFetcherDelegateImpl() = default; std::unique_ptr<BackdropCollectionInfoFetcher> -BackdropFetcherDelegateImpl::CreateBackdropCollectionInfoFetcher() const { +WallpaperFetcherDelegateImpl::CreateBackdropCollectionInfoFetcher() const { // Use `WrapUnique` to access the protected constructor. return absl::WrapUnique(new BackdropCollectionInfoFetcher()); } std::unique_ptr<BackdropImageInfoFetcher> -BackdropFetcherDelegateImpl::CreateBackdropImageInfoFetcher( +WallpaperFetcherDelegateImpl::CreateBackdropImageInfoFetcher( const std::string& collection_id) const { // Use `WrapUnique` to access the protected constructor. return absl::WrapUnique(new BackdropImageInfoFetcher(collection_id));
diff --git a/chrome/browser/ash/wallpaper_handlers/wallpaper_fetcher_delegate.h b/chrome/browser/ash/wallpaper_handlers/wallpaper_fetcher_delegate.h new file mode 100644 index 0000000..0be12850 --- /dev/null +++ b/chrome/browser/ash/wallpaper_handlers/wallpaper_fetcher_delegate.h
@@ -0,0 +1,49 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_ASH_WALLPAPER_HANDLERS_WALLPAPER_FETCHER_DELEGATE_H_ +#define CHROME_BROWSER_ASH_WALLPAPER_HANDLERS_WALLPAPER_FETCHER_DELEGATE_H_ + +#include <memory> +#include <string> + +namespace wallpaper_handlers { + +class BackdropCollectionInfoFetcher; +class BackdropImageInfoFetcher; + +// Delegate class for creating backdrop fetchers. Abstract class to allow +// mocking out in test. +class WallpaperFetcherDelegate { + public: + virtual ~WallpaperFetcherDelegate() = default; + + virtual std::unique_ptr<BackdropCollectionInfoFetcher> + CreateBackdropCollectionInfoFetcher() const = 0; + + virtual std::unique_ptr<BackdropImageInfoFetcher> + CreateBackdropImageInfoFetcher(const std::string& collection_id) const = 0; +}; + +class WallpaperFetcherDelegateImpl : public WallpaperFetcherDelegate { + public: + WallpaperFetcherDelegateImpl(); + + WallpaperFetcherDelegateImpl(const WallpaperFetcherDelegateImpl&) = delete; + WallpaperFetcherDelegateImpl& operator=(const WallpaperFetcherDelegateImpl&) = + delete; + + ~WallpaperFetcherDelegateImpl() override; + + // WallpaperFetcherDelegate: + std::unique_ptr<BackdropCollectionInfoFetcher> + CreateBackdropCollectionInfoFetcher() const override; + + std::unique_ptr<BackdropImageInfoFetcher> CreateBackdropImageInfoFetcher( + const std::string& collection_id) const override; +}; + +} // namespace wallpaper_handlers + +#endif // CHROME_BROWSER_ASH_WALLPAPER_HANDLERS_WALLPAPER_FETCHER_DELEGATE_H_
diff --git a/chrome/browser/ash/wallpaper_handlers/wallpaper_handlers.h b/chrome/browser/ash/wallpaper_handlers/wallpaper_handlers.h index 82a897b..0a6da7a 100644 --- a/chrome/browser/ash/wallpaper_handlers/wallpaper_handlers.h +++ b/chrome/browser/ash/wallpaper_handlers/wallpaper_handlers.h
@@ -57,13 +57,13 @@ virtual void Start(OnCollectionsInfoFetched callback); protected: - // Protected constructor forces creation via `BackdropFetcherDelegate` to + // Protected constructor forces creation via `WallpaperFetcherDelegate` to // allow mocking in test code. BackdropCollectionInfoFetcher(); private: // Allow delegate to view the constructor. - friend class BackdropFetcherDelegateImpl; + friend class WallpaperFetcherDelegateImpl; // Called when the collections info download completes. void OnResponseFetched(const std::string& response); @@ -93,13 +93,13 @@ virtual void Start(OnImagesInfoFetched callback); protected: - // Protected constructor forces creation via `BackdropFetcherDelegate` to + // Protected constructor forces creation via `WallpaperFetcherDelegate` to // allow mocking in test code. explicit BackdropImageInfoFetcher(const std::string& collection_id); private: // Allow delegate to view the constructor. - friend class BackdropFetcherDelegateImpl; + friend class WallpaperFetcherDelegateImpl; // Called when the images info download completes. void OnResponseFetched(const std::string& response);
diff --git a/chrome/browser/ash/web_applications/personalization_app/personalization_app_browsertest_fixture.cc b/chrome/browser/ash/web_applications/personalization_app/personalization_app_browsertest_fixture.cc index d32ae73..b18e76d 100644 --- a/chrome/browser/ash/web_applications/personalization_app/personalization_app_browsertest_fixture.cc +++ b/chrome/browser/ash/web_applications/personalization_app/personalization_app_browsertest_fixture.cc
@@ -16,7 +16,7 @@ #include "ash/webui/personalization_app/test/fake_personalization_app_keyboard_backlight_provider.h" #include "ash/webui/personalization_app/test/fake_personalization_app_theme_provider.h" #include "ash/webui/personalization_app/test/fake_personalization_app_user_provider.h" -#include "chrome/browser/ash/wallpaper_handlers/test_backdrop_fetcher_delegate.h" +#include "chrome/browser/ash/wallpaper_handlers/test_wallpaper_fetcher_delegate.h" #include "chrome/browser/ash/web_applications/personalization_app/personalization_app_utils.h" #include "chrome/browser/ash/web_applications/personalization_app/personalization_app_wallpaper_provider_impl.h" #include "chrome/browser/profiles/profile.h" @@ -37,7 +37,7 @@ auto wallpaper_provider = std::make_unique<PersonalizationAppWallpaperProviderImpl>( web_ui, - std::make_unique<wallpaper_handlers::TestBackdropFetcherDelegate>()); + std::make_unique<wallpaper_handlers::TestWallpaperFetcherDelegate>()); auto user_provider = std::make_unique<FakePersonalizationAppUserProvider>(web_ui); return std::make_unique<PersonalizationAppUI>(
diff --git a/chrome/browser/ash/web_applications/personalization_app/personalization_app_utils.cc b/chrome/browser/ash/web_applications/personalization_app/personalization_app_utils.cc index 1b97a880..c83ab4f 100644 --- a/chrome/browser/ash/web_applications/personalization_app/personalization_app_utils.cc +++ b/chrome/browser/ash/web_applications/personalization_app/personalization_app_utils.cc
@@ -6,7 +6,7 @@ #include "base/notreached.h" #include "chrome/browser/ash/profiles/profile_helper.h" -#include "chrome/browser/ash/wallpaper_handlers/backdrop_fetcher_delegate.h" +#include "chrome/browser/ash/wallpaper_handlers/wallpaper_fetcher_delegate.h" #include "chrome/browser/ash/web_applications/personalization_app/personalization_app_ambient_provider_impl.h" #include "chrome/browser/ash/web_applications/personalization_app/personalization_app_keyboard_backlight_provider_impl.h" #include "chrome/browser/ash/web_applications/personalization_app/personalization_app_theme_provider_impl.h" @@ -33,7 +33,7 @@ auto wallpaper_provider = std::make_unique< ash::personalization_app::PersonalizationAppWallpaperProviderImpl>( web_ui, - std::make_unique<wallpaper_handlers::BackdropFetcherDelegateImpl>()); + std::make_unique<wallpaper_handlers::WallpaperFetcherDelegateImpl>()); return new ash::personalization_app::PersonalizationAppUI( web_ui, std::move(ambient_provider), std::move(keyboard_backlight_provider), std::move(theme_provider),
diff --git a/chrome/browser/ash/web_applications/personalization_app/personalization_app_wallpaper_provider_impl.cc b/chrome/browser/ash/web_applications/personalization_app/personalization_app_wallpaper_provider_impl.cc index eb05d4c..b325f44d 100644 --- a/chrome/browser/ash/web_applications/personalization_app/personalization_app_wallpaper_provider_impl.cc +++ b/chrome/browser/ash/web_applications/personalization_app/personalization_app_wallpaper_provider_impl.cc
@@ -42,7 +42,7 @@ #include "base/task/thread_pool.h" #include "base/unguessable_token.h" #include "chrome/browser/ash/wallpaper/wallpaper_enumerator.h" -#include "chrome/browser/ash/wallpaper_handlers/backdrop_fetcher_delegate.h" +#include "chrome/browser/ash/wallpaper_handlers/wallpaper_fetcher_delegate.h" #include "chrome/browser/ash/wallpaper_handlers/wallpaper_handlers.h" #include "chrome/browser/ash/web_applications/personalization_app/personalization_app_manager.h" #include "chrome/browser/ash/web_applications/personalization_app/personalization_app_manager_factory.h" @@ -128,11 +128,11 @@ PersonalizationAppWallpaperProviderImpl:: PersonalizationAppWallpaperProviderImpl( content::WebUI* web_ui, - std::unique_ptr<wallpaper_handlers::BackdropFetcherDelegate> - backdrop_fetcher_delegate) + std::unique_ptr<wallpaper_handlers::WallpaperFetcherDelegate> + wallpaper_fetcher_delegate) : web_ui_(web_ui), profile_(Profile::FromWebUI(web_ui)), - backdrop_fetcher_delegate_(std::move(backdrop_fetcher_delegate)) { + wallpaper_fetcher_delegate_(std::move(wallpaper_fetcher_delegate)) { content::URLDataSource::Add(profile_, std::make_unique<SanitizedImageSource>(profile_)); } @@ -222,7 +222,7 @@ } wallpaper_collection_info_fetcher_ = - backdrop_fetcher_delegate_->CreateBackdropCollectionInfoFetcher(); + wallpaper_fetcher_delegate_->CreateBackdropCollectionInfoFetcher(); // base::Unretained is safe to use because |this| outlives // |wallpaper_collection_info_fetcher_|. @@ -235,7 +235,8 @@ const std::string& collection_id, FetchImagesForCollectionCallback callback) { auto wallpaper_images_info_fetcher = - backdrop_fetcher_delegate_->CreateBackdropImageInfoFetcher(collection_id); + wallpaper_fetcher_delegate_->CreateBackdropImageInfoFetcher( + collection_id); auto* wallpaper_images_info_fetcher_ptr = wallpaper_images_info_fetcher.get(); wallpaper_images_info_fetcher_ptr->Start(base::BindOnce( @@ -997,7 +998,7 @@ std::size_t current_index = 0; wallpaper_attribution_info_fetcher_ = - backdrop_fetcher_delegate_->CreateBackdropImageInfoFetcher( + wallpaper_fetcher_delegate_->CreateBackdropImageInfoFetcher( collections->at(current_index).collection_id()); wallpaper_attribution_info_fetcher_->Start(base::BindOnce( @@ -1055,7 +1056,7 @@ return; } - auto fetcher = backdrop_fetcher_delegate_->CreateBackdropImageInfoFetcher( + auto fetcher = wallpaper_fetcher_delegate_->CreateBackdropImageInfoFetcher( collections->at(current_index).collection_id()); fetcher->Start(base::BindOnce( &PersonalizationAppWallpaperProviderImpl::FindImageMetadataInCollection,
diff --git a/chrome/browser/ash/web_applications/personalization_app/personalization_app_wallpaper_provider_impl.h b/chrome/browser/ash/web_applications/personalization_app/personalization_app_wallpaper_provider_impl.h index 1af69214..4c985f5 100644 --- a/chrome/browser/ash/web_applications/personalization_app/personalization_app_wallpaper_provider_impl.h +++ b/chrome/browser/ash/web_applications/personalization_app/personalization_app_wallpaper_provider_impl.h
@@ -22,7 +22,7 @@ #include "base/files/file.h" #include "base/memory/weak_ptr.h" #include "base/scoped_observation.h" -#include "chrome/browser/ash/wallpaper_handlers/backdrop_fetcher_delegate.h" +#include "chrome/browser/ash/wallpaper_handlers/wallpaper_fetcher_delegate.h" #include "content/public/browser/web_ui_data_source.h" #include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/pending_remote.h" @@ -46,7 +46,7 @@ namespace wallpaper_handlers { class BackdropCollectionInfoFetcher; -class BackdropFetcherDelegate; +class WallpaperFetcherDelegate; class BackdropImageInfoFetcher; class GooglePhotosAlbumsFetcher; class GooglePhotosSharedAlbumsFetcher; @@ -69,8 +69,8 @@ public: PersonalizationAppWallpaperProviderImpl( content::WebUI* web_ui, - std::unique_ptr<wallpaper_handlers::BackdropFetcherDelegate> - backdrop_fetcher_delegate); + std::unique_ptr<wallpaper_handlers::WallpaperFetcherDelegate> + wallpaper_fetcher_delegate); PersonalizationAppWallpaperProviderImpl( const PersonalizationAppWallpaperProviderImpl&) = delete; @@ -380,8 +380,8 @@ ash::WallpaperControllerObserver> wallpaper_controller_observer_{this}; - const std::unique_ptr<wallpaper_handlers::BackdropFetcherDelegate> - backdrop_fetcher_delegate_; + const std::unique_ptr<wallpaper_handlers::WallpaperFetcherDelegate> + wallpaper_fetcher_delegate_; // Place near bottom of class so this is cleaned up before any pending // callbacks are dropped.
diff --git a/chrome/browser/ash/web_applications/personalization_app/personalization_app_wallpaper_provider_impl_unittest.cc b/chrome/browser/ash/web_applications/personalization_app/personalization_app_wallpaper_provider_impl_unittest.cc index 78bcb37e..4fe9b5c 100644 --- a/chrome/browser/ash/web_applications/personalization_app/personalization_app_wallpaper_provider_impl_unittest.cc +++ b/chrome/browser/ash/web_applications/personalization_app/personalization_app_wallpaper_provider_impl_unittest.cc
@@ -32,7 +32,7 @@ #include "chrome/browser/ash/settings/device_settings_service.h" #include "chrome/browser/ash/settings/scoped_cros_settings_test_helper.h" #include "chrome/browser/ash/wallpaper_handlers/mock_wallpaper_handlers.h" -#include "chrome/browser/ash/wallpaper_handlers/test_backdrop_fetcher_delegate.h" +#include "chrome/browser/ash/wallpaper_handlers/test_wallpaper_fetcher_delegate.h" #include "chrome/browser/ash/web_applications/personalization_app/mock_personalization_app_manager.h" #include "chrome/browser/ash/web_applications/personalization_app/personalization_app_manager_factory.h" #include "chrome/browser/profiles/profile_attributes_storage.h" @@ -244,7 +244,7 @@ void SetUp() override { wallpaper_controller_client_ = std::make_unique< WallpaperControllerClientImpl>( - std::make_unique<wallpaper_handlers::TestBackdropFetcherDelegate>()); + std::make_unique<wallpaper_handlers::TestWallpaperFetcherDelegate>()); wallpaper_controller_client_->InitForTesting(&test_wallpaper_controller_); ASSERT_TRUE(profile_manager_.SetUp()); @@ -264,7 +264,7 @@ wallpaper_provider_ = std::make_unique< PersonalizationAppWallpaperProviderImpl>( &web_ui_, - std::make_unique<wallpaper_handlers::TestBackdropFetcherDelegate>()); + std::make_unique<wallpaper_handlers::TestWallpaperFetcherDelegate>()); wallpaper_provider_->BindInterface( wallpaper_provider_remote_.BindNewPipeAndPassReceiver());
diff --git a/chrome/browser/ash/web_applications/projector_app/projector_app_integration_browsertest.cc b/chrome/browser/ash/web_applications/projector_app/projector_app_integration_browsertest.cc index 91007c3..adade574 100644 --- a/chrome/browser/ash/web_applications/projector_app/projector_app_integration_browsertest.cc +++ b/chrome/browser/ash/web_applications/projector_app/projector_app_integration_browsertest.cc
@@ -15,19 +15,29 @@ #include "chrome/browser/ui/ash/projector/projector_app_client_impl.h" #include "chrome/browser/ui/ash/system_web_apps/system_web_app_ui_utils.h" #include "content/public/test/browser_test.h" +#include "content/public/test/browser_test_utils.h" namespace { #if BUILDFLAG(ENABLE_CROS_MEDIA_APP) && BUILDFLAG(ENABLE_CROS_PROJECTOR_APP) + +static content::EvalJsResult EvalJsInMainFrame(content::WebContents* web_ui, + const std::string& script) { + // Clients of this helper all run in the same isolated world. + constexpr int kWorldId = 1; + return EvalJs(web_ui->GetPrimaryMainFrame(), script, + content::EXECUTE_SCRIPT_DEFAULT_OPTIONS, kWorldId); +} + // File containing the test utility library constexpr base::FilePath::CharType kTestLibraryPath[] = FILE_PATH_LITERAL("ash/webui/system_apps/public/js/dom_testing_helpers.js"); -void PrepareAppForTest(content::WebContents* web_contents) { +void PrepareAnnotatorForTest(content::WebContents* web_contents) { EXPECT_TRUE(WaitForLoadStop(web_contents)); EXPECT_EQ(nullptr, - SandboxedWebUiAppTestBase::EvalJsInAppFrame( - web_contents, SandboxedWebUiAppTestBase::LoadJsTestLibrary( + EvalJsInMainFrame(web_contents, + SandboxedWebUiAppTestBase::LoadJsTestLibrary( base::FilePath(kTestLibraryPath)))); } #endif // BUILDFLAG(ENABLE_CROS_MEDIA_APP) && @@ -75,7 +85,7 @@ projector_app_client->get_annotator_handler_for_test() ->get_web_ui_for_test() ->GetWebContents(); - PrepareAppForTest(annotator_embedder); + PrepareAnnotatorForTest(annotator_embedder); // Checks ink is loaded by ensuring the ink engine canvas has a non zero width // and height attributes (checking <canvas.width/height is insufficient since @@ -92,9 +102,9 @@ inkCanvas.getAttribute('width') !== '0'; })(); )"; - EXPECT_EQ(true, SandboxedWebUiAppTestBase::EvalJsInAppFrame( - annotator_embedder, kCheckInkLoaded) - .ExtractBool()); + EXPECT_EQ( + true, + EvalJsInMainFrame(annotator_embedder, kCheckInkLoaded).ExtractBool()); } #endif // BUILDFLAG(ENABLE_CROS_MEDIA_APP) && // BUILDFLAG(ENABLE_CROS_PROJECTOR_APP)
diff --git a/chrome/browser/browsing_topics/browsing_topics_service_browsertest.cc b/chrome/browser/browsing_topics/browsing_topics_service_browsertest.cc index 62cbe42..c7717d0 100644 --- a/chrome/browser/browsing_topics/browsing_topics_service_browsertest.cc +++ b/chrome/browser/browsing_topics/browsing_topics_service_browsertest.cc
@@ -328,6 +328,24 @@ } protected: + void CreateIframe(const GURL& url, bool browsing_topics_attribute = false) { + content::TestNavigationObserver nav_observer(web_contents()); + + ExecuteScriptAsync(web_contents(), + content::JsReplace(R"( + { + const iframe = document.createElement("iframe"); + iframe.browsingTopics = $1; + iframe.src = $2; + document.body.appendChild(iframe); + } + )", + browsing_topics_attribute, url)); + + nav_observer.WaitForNavigationFinished(); + EXPECT_TRUE(nav_observer.last_navigation_succeeded()); + } + void ExpectResultTopicsEqual( const std::vector<TopicAndDomains>& result, std::vector<std::pair<Topic, std::set<HashedDomain>>> expected) { @@ -1991,4 +2009,293 @@ } } +// For a page that contains a static <iframe> with a "browsingtopics" +// attribute, the iframe navigation request should be eligible for topics. +IN_PROC_BROWSER_TEST_F(BrowsingTopicsBrowserTest, + CrossOriginStaticIframeWithTopicsAttribute) { + base::StringPairs replacement; + replacement.emplace_back(std::make_pair("{{STATUS}}", "200 OK")); + replacement.emplace_back(std::make_pair("{{OBSERVE_BROWSING_TOPICS_HEADER}}", + "Observe-Browsing-Topics: ?1")); + replacement.emplace_back(std::make_pair("{{REDIRECT_HEADER}}", "")); + + GURL subframe_url = https_server_.GetURL( + "a.test", net::test_server::GetFilePathWithReplacements( + "/browsing_topics/" + "page_with_custom_topics_header.html", + replacement)); + + base::StringPairs topics_attribute_replacement; + topics_attribute_replacement.emplace_back( + "{{MAYBE_BROWSING_TOPICS_ATTRIBUTE}}", "browsingtopics"); + + topics_attribute_replacement.emplace_back("{{SRC_URL}}", subframe_url.spec()); + + GURL main_frame_url = https_server_.GetURL( + "b.test", net::test_server::GetFilePathWithReplacements( + "/browsing_topics/page_with_custom_attribute_iframe.html", + topics_attribute_replacement)); + + ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_frame_url)); + + absl::optional<std::string> topics_header_value = + GetTopicsHeaderForRequestPath( + "/browsing_topics/page_with_custom_topics_header.html"); + EXPECT_TRUE(topics_header_value); + EXPECT_EQ(*topics_header_value, kExpectedHeaderValueForSiteB); + + // A new observation should have been recorded in addition to the pre-existing + // one. + std::vector<ApiUsageContext> api_usage_contexts = + content::GetBrowsingTopicsApiUsage(browsing_topics_site_data_manager()); + EXPECT_EQ(api_usage_contexts.size(), 2u); + EXPECT_EQ( + api_usage_contexts[0].hashed_main_frame_host, + HashMainFrameHostForStorage(https_server_.GetURL("b.test", "/").host())); + EXPECT_EQ(api_usage_contexts[0].hashed_context_domain, + GetHashedDomain("a.test")); + EXPECT_EQ(api_usage_contexts[1].hashed_main_frame_host, + HashMainFrameHostForStorage("foo1.com")); + EXPECT_EQ(api_usage_contexts[1].hashed_context_domain, HashedDomain(1)); +} + +// For a page that contains a static <iframe> without a "browsingtopics" +// attribute, the iframe navigation request should not be eligible for topics. +IN_PROC_BROWSER_TEST_F(BrowsingTopicsBrowserTest, + CrossOriginStaticIframeWithoutTopicsAttribute) { + base::StringPairs replacement; + replacement.emplace_back(std::make_pair("{{STATUS}}", "200 OK")); + replacement.emplace_back(std::make_pair("{{OBSERVE_BROWSING_TOPICS_HEADER}}", + "Observe-Browsing-Topics: ?1")); + replacement.emplace_back(std::make_pair("{{REDIRECT_HEADER}}", "")); + + GURL subframe_url = https_server_.GetURL( + "a.test", net::test_server::GetFilePathWithReplacements( + "/browsing_topics/" + "page_with_custom_topics_header.html", + replacement)); + + base::StringPairs topics_attribute_replacement; + topics_attribute_replacement.emplace_back( + "{{MAYBE_BROWSING_TOPICS_ATTRIBUTE}}", ""); + + topics_attribute_replacement.emplace_back("{{SRC_URL}}", subframe_url.spec()); + + GURL main_frame_url = https_server_.GetURL( + "b.test", net::test_server::GetFilePathWithReplacements( + "/browsing_topics/page_with_custom_attribute_iframe.html", + topics_attribute_replacement)); + + absl::optional<std::string> topics_header_value = + GetTopicsHeaderForRequestPath( + "/browsing_topics/page_with_custom_topics_header.html"); + EXPECT_FALSE(topics_header_value); + + // Since the request wasn't eligible for topics, no observation should have + // been recorded in addition to the pre-existing one, even though the response + // contains a `Observe-Browsing-Topics: ?1` header. + std::vector<ApiUsageContext> api_usage_contexts = + content::GetBrowsingTopicsApiUsage(browsing_topics_site_data_manager()); + EXPECT_EQ(api_usage_contexts.size(), 1u); +} + +// For a page with a dynamically appended iframe with iframe.browsingTopics set +// to true, the iframe navigation request should be eligible for topics. +IN_PROC_BROWSER_TEST_F(BrowsingTopicsBrowserTest, + CrossOriginDynamicIframeWithTopicsAttribute) { + GURL main_frame_url = + https_server_.GetURL("b.test", "/browsing_topics/empty_page.html"); + + ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_frame_url)); + + base::StringPairs replacement; + replacement.emplace_back(std::make_pair("{{STATUS}}", "200 OK")); + replacement.emplace_back(std::make_pair("{{OBSERVE_BROWSING_TOPICS_HEADER}}", + "Observe-Browsing-Topics: ?1")); + replacement.emplace_back(std::make_pair("{{REDIRECT_HEADER}}", "")); + + GURL subframe_url = https_server_.GetURL( + "a.test", net::test_server::GetFilePathWithReplacements( + "/browsing_topics/" + "page_with_custom_topics_header.html", + replacement)); + + CreateIframe(subframe_url, /*browsing_topics_attribute=*/true); + + absl::optional<std::string> topics_header_value = + GetTopicsHeaderForRequestPath( + "/browsing_topics/page_with_custom_topics_header.html"); + EXPECT_TRUE(topics_header_value); + EXPECT_EQ(*topics_header_value, kExpectedHeaderValueForSiteB); + + // A new observation should have been recorded in addition to the pre-existing + // one. + std::vector<ApiUsageContext> api_usage_contexts = + content::GetBrowsingTopicsApiUsage(browsing_topics_site_data_manager()); + EXPECT_EQ(api_usage_contexts.size(), 2u); + EXPECT_EQ( + api_usage_contexts[0].hashed_main_frame_host, + HashMainFrameHostForStorage(https_server_.GetURL("b.test", "/").host())); + EXPECT_EQ(api_usage_contexts[0].hashed_context_domain, + GetHashedDomain("a.test")); + EXPECT_EQ(api_usage_contexts[1].hashed_main_frame_host, + HashMainFrameHostForStorage("foo1.com")); + EXPECT_EQ(api_usage_contexts[1].hashed_context_domain, HashedDomain(1)); +} + +// For a page with a dynamically appended iframe with iframe.browsingTopics set +// to true, the iframe navigation request should not be eligible for topics. +IN_PROC_BROWSER_TEST_F(BrowsingTopicsBrowserTest, + CrossOriginDynamicIframeWithoutTopicsAttribute) { + GURL main_frame_url = + https_server_.GetURL("b.test", "/browsing_topics/empty_page.html"); + + ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_frame_url)); + + base::StringPairs replacement; + replacement.emplace_back(std::make_pair("{{STATUS}}", "200 OK")); + replacement.emplace_back(std::make_pair("{{OBSERVE_BROWSING_TOPICS_HEADER}}", + "Observe-Browsing-Topics: ?1")); + replacement.emplace_back(std::make_pair("{{REDIRECT_HEADER}}", "")); + + GURL subframe_url = https_server_.GetURL( + "a.test", net::test_server::GetFilePathWithReplacements( + "/browsing_topics/" + "page_with_custom_topics_header.html", + replacement)); + + CreateIframe(subframe_url); + + absl::optional<std::string> topics_header_value = + GetTopicsHeaderForRequestPath( + "/browsing_topics/page_with_custom_topics_header.html"); + EXPECT_FALSE(topics_header_value); + + // Since the request wasn't eligible for topics, no observation should have + // been recorded in addition to the pre-existing one, even though the response + // contains a `Observe-Browsing-Topics: ?1` header. + std::vector<ApiUsageContext> api_usage_contexts = + content::GetBrowsingTopicsApiUsage(browsing_topics_site_data_manager()); + EXPECT_EQ(api_usage_contexts.size(), 1u); +} + +// Only allow topics from origin c.test, and test <iframe browsingtopics> +// requests to b.test and c.test to verify that only c.test gets the header. +IN_PROC_BROWSER_TEST_F( + BrowsingTopicsBrowserTest, + CrossOriginIframe_TopicsNotEligibleDueToPermissionsPolicyAgainstRequestOrigin) { + base::StringPairs allowed_origin_replacement; + allowed_origin_replacement.emplace_back( + "{{ALLOWED_ORIGIN}}", https_server_.GetOrigin("c.test").Serialize()); + + GURL main_frame_url = https_server_.GetURL( + "a.test", net::test_server::GetFilePathWithReplacements( + "/browsing_topics/" + "one_iframe_page_browsing_topics_allow_certain_origin.html", + allowed_origin_replacement)); + + ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_frame_url)); + + { + GURL subframe_url = + https_server_.GetURL("b.test", "/browsing_topics/empty_page.html"); + + CreateIframe(subframe_url, /*browsing_topics_attribute=*/true); + + // No topics header was sent, as the permissions policy denied it. + absl::optional<std::string> topics_header_value = + GetTopicsHeaderForRequestPath("/browsing_topics/empty_page.html"); + EXPECT_FALSE(topics_header_value); + } + + { + GURL subframe_url = + https_server_.GetURL("c.test", "/browsing_topics/empty_page.html"); + + CreateIframe(subframe_url, /*browsing_topics_attribute=*/true); + + absl::optional<std::string> topics_header_value = + GetTopicsHeaderForRequestPath("/browsing_topics/empty_page.html"); + EXPECT_TRUE(topics_header_value); + } +} + +// On site b.test, test <iframe browsingtopics> request to a.test that gets +// redirected to c.test. The topics header should be calculated for them +// individually (i.e. given that only a.test has observed the candidate topics +// for site b.test, the request to a.test should have a non-empty topics header, +// while the redirected request to c.test should have an empty topics header.) +IN_PROC_BROWSER_TEST_F(BrowsingTopicsBrowserTest, + CrossOriginIframeWithRedirect) { + GURL main_frame_url = + https_server_.GetURL("b.test", "/browsing_topics/empty_page.html"); + + ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_frame_url)); + + base::StringPairs redirect_replacement; + redirect_replacement.emplace_back(std::make_pair("{{STATUS}}", "200 OK")); + redirect_replacement.emplace_back(std::make_pair( + "{{OBSERVE_BROWSING_TOPICS_HEADER}}", "Observe-Browsing-Topics: ?1")); + redirect_replacement.emplace_back(std::make_pair("{{REDIRECT_HEADER}}", "")); + + GURL redirect_url = https_server_.GetURL( + "c.test", net::test_server::GetFilePathWithReplacements( + "/browsing_topics/" + "page_with_custom_topics_header2.html", + redirect_replacement)); + + base::StringPairs replacement; + replacement.emplace_back( + std::make_pair("{{STATUS}}", "301 Moved Permanently")); + replacement.emplace_back(std::make_pair("{{OBSERVE_BROWSING_TOPICS_HEADER}}", + "Observe-Browsing-Topics: ?1")); + replacement.emplace_back(std::make_pair("{{REDIRECT_HEADER}}", + "Location: " + redirect_url.spec())); + + GURL subframe_url = https_server_.GetURL( + "a.test", net::test_server::GetFilePathWithReplacements( + "/browsing_topics/" + "page_with_custom_topics_header.html", + replacement)); + + CreateIframe(subframe_url, /*browsing_topics_attribute=*/true); + + { + absl::optional<std::string> topics_header_value = + GetTopicsHeaderForRequestPath( + "/browsing_topics/page_with_custom_topics_header.html"); + EXPECT_TRUE(topics_header_value); + EXPECT_EQ(*topics_header_value, kExpectedHeaderValueForSiteB); + } + { + absl::optional<std::string> topics_header_value = + GetTopicsHeaderForRequestPath( + "/browsing_topics/page_with_custom_topics_header2.html"); + EXPECT_TRUE(topics_header_value); + + // An empty topics header value was sent, because "c.test" did not observe + // the candidate topics. + EXPECT_TRUE(topics_header_value->empty()); + } + + // Two new observations should have been recorded in addition to the + // pre-existing one. + std::vector<ApiUsageContext> api_usage_contexts = + content::GetBrowsingTopicsApiUsage(browsing_topics_site_data_manager()); + EXPECT_EQ(api_usage_contexts.size(), 3u); + EXPECT_EQ( + api_usage_contexts[0].hashed_main_frame_host, + HashMainFrameHostForStorage(https_server_.GetURL("b.test", "/").host())); + EXPECT_EQ(api_usage_contexts[0].hashed_context_domain, + GetHashedDomain("c.test")); + EXPECT_EQ( + api_usage_contexts[1].hashed_main_frame_host, + HashMainFrameHostForStorage(https_server_.GetURL("b.test", "/").host())); + EXPECT_EQ(api_usage_contexts[1].hashed_context_domain, + GetHashedDomain("a.test")); + EXPECT_EQ(api_usage_contexts[2].hashed_main_frame_host, + HashMainFrameHostForStorage("foo1.com")); + EXPECT_EQ(api_usage_contexts[2].hashed_context_domain, HashedDomain(1)); +} + } // namespace browsing_topics
diff --git a/chrome/browser/chrome_browser_interface_binders.cc b/chrome/browser/chrome_browser_interface_binders.cc index cc05624..a5fe73d 100644 --- a/chrome/browser/chrome_browser_interface_binders.cc +++ b/chrome/browser/chrome_browser_interface_binders.cc
@@ -248,8 +248,8 @@ #include "ash/webui/personalization_app/personalization_app_ui.h" #include "ash/webui/personalization_app/search/search.mojom.h" #include "ash/webui/print_management/print_management_ui.h" -#include "ash/webui/projector_app/mojom/annotator.mojom.h" -#include "ash/webui/projector_app/trusted_projector_annotator_ui.h" +#include "ash/webui/projector_app/mojom/untrusted_annotator.mojom.h" +#include "ash/webui/projector_app/untrusted_projector_annotator_ui.h" #include "ash/webui/scanning/mojom/scanning.mojom.h" #include "ash/webui/scanning/scanning_ui.h" #include "ash/webui/shimless_rma/shimless_rma.h" @@ -1206,10 +1206,6 @@ ash::camera_app::mojom::CameraAppHelper, ash::CameraAppUI>(map); RegisterWebUIControllerInterfaceBinder< - ash::annotator::mojom::AnnotatorPageHandlerFactory, - ash::TrustedProjectorAnnotatorUI>(map); - - RegisterWebUIControllerInterfaceBinder< ash::help_app::mojom::PageHandlerFactory, ash::HelpAppUI>(map); RegisterWebUIControllerInterfaceBinder< @@ -1467,6 +1463,9 @@ #if BUILDFLAG(IS_CHROMEOS_ASH) registry.ForWebUI<ash::DemoModeAppUntrustedUI>() .Add<ash::mojom::demo_mode::UntrustedPageHandlerFactory>(); + + registry.ForWebUI<ash::UntrustedProjectorAnnotatorUI>() + .Add<ash::annotator::mojom::UntrustedAnnotatorPageHandlerFactory>(); #endif // BUILDFLAG(IS_CHROMEOS_ASH) #if BUILDFLAG(IS_CHROMEOS_ASH) && !defined(OFFICIAL_BUILD)
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index 0bf0370..bdef817 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc
@@ -13,6 +13,7 @@ #include "base/base_switches.h" #include "base/command_line.h" +#include "base/containers/fixed_flat_set.h" #include "base/dcheck_is_on.h" #include "base/feature_list.h" #include "base/functional/bind.h" @@ -1114,7 +1115,19 @@ process_map->Contains(extension->id(), render_process_id); } -#endif +// Returns true if |extension_id| is allowed to run as an Isolated Context, +// giving it access to additional APIs. +bool IsExtensionIdAllowedToUseIsolatedContext(base::StringPiece extension_id) { + static constexpr auto kAllowedIsolatedContextExtensionIds = + base::MakeFixedFlatSet<base::StringPiece>({ + "algkcnfjnajfhgimadimbjhmpaeohhln", // Secure Shell Extension (dev) + "iodihamcpbpeioajjeobimgagajmlibd", // Secure Shell Extension + // (stable) + }); + return base::Contains(kAllowedIsolatedContextExtensionIds, extension_id); +} + +#endif // BUILDFLAG(ENABLE_EXTENSIONS) mojo::PendingRemote<prerender::mojom::PrerenderCanceler> GetPrerenderCanceler( base::OnceCallback<content::WebContents*()> wc_getter) { @@ -2493,7 +2506,9 @@ auto* extension = extensions::ExtensionRegistry::Get(browser_context) ->enabled_extensions() .GetExtensionOrAppByURL(lock_url); - return extension && extension->is_platform_app(); + return extension && + (extension->is_platform_app() || + IsExtensionIdAllowedToUseIsolatedContext(extension->id())); #else return false; #endif
diff --git a/chrome/browser/devtools/devtools_browsertest.cc b/chrome/browser/devtools/devtools_browsertest.cc index b1faa9db..8d8bc53fb 100644 --- a/chrome/browser/devtools/devtools_browsertest.cc +++ b/chrome/browser/devtools/devtools_browsertest.cc
@@ -1769,7 +1769,7 @@ class DevToolsExtensionFileAccessTest : public DevToolsExtensionTest { protected: - void Run(bool allow_file_access) { + void Run(bool allow_file_access, const std::string& url_scheme) { extensions::TestExtensionDir dir; dir.WriteManifest(BuildExtensionManifest("File Access", "devtools.html")); @@ -1793,28 +1793,36 @@ .AppendASCII("content/test/data/devtools/navigation.html")) .spec(); - base::ReplaceFirstSubstringAfterOffset(&file_url, 0, "file:///", "file:"); - const Extension* extension = LoadExtensionFromPath(dir.UnpackedPath(), allow_file_access); ASSERT_TRUE(extension); std::string url = base::StringPrintf( - R"(data:text/html,<script>//%%23%%20sourceMappingURL=data:application/json,{"version":3,"sources":["file:%s"]}</script>)", - file_url.c_str()); + R"(data:text/html,<script>//%%23%%20sourceMappingURL=data:application/json,{"version":3,"sources":["%s:%s"]}</script>)", + url_scheme.c_str(), file_url.c_str() + strlen("file:///")); OpenDevToolsWindow(url, false); RunTestFunction(window_, "waitForTestResultsAsMessage"); } }; IN_PROC_BROWSER_TEST_F(DevToolsExtensionFileAccessTest, - CantGetFileResourceWithoutFileAccess) { - Run(false); + CanGetFileResourceWithFileAccess) { + Run(true, "file:///"); } IN_PROC_BROWSER_TEST_F(DevToolsExtensionFileAccessTest, - CanGetFileResourceWithFileAccess) { - Run(true); + CantGetFileResourceWithoutFileAccess) { + Run(false, "file:///"); +} + +IN_PROC_BROWSER_TEST_F(DevToolsExtensionFileAccessTest, + CantGetFileResourceWithoutFileAccessNoSlashes) { + Run(false, "file:"); +} + +IN_PROC_BROWSER_TEST_F(DevToolsExtensionFileAccessTest, + CantGetFileResourceWithoutFileAccessMixedCase) { + Run(false, "fILe:"); } // Tests that scripts are not duplicated after Scripts Panel switch.
diff --git a/chrome/browser/enterprise/connectors/analysis/content_analysis_delegate.cc b/chrome/browser/enterprise/connectors/analysis/content_analysis_delegate.cc index 6162047f..215c183 100644 --- a/chrome/browser/enterprise/connectors/analysis/content_analysis_delegate.cc +++ b/chrome/browser/enterprise/connectors/analysis/content_analysis_delegate.cc
@@ -540,7 +540,7 @@ // MultiFileRequestHandler is owned by this class. files_request_handler_ = FilesRequestHandler::Create( GetBinaryUploadService(), profile_, data_.settings, url_, "", "", - user_action_id_, access_point_, data_.paths, + user_action_id_, title_, access_point_, data_.paths, base::BindOnce(&ContentAnalysisDelegate::FilesRequestCallback, GetWeakPtr())); files_request_complete_ = !files_request_handler_->UploadData();
diff --git a/chrome/browser/enterprise/connectors/analysis/fake_files_request_handler.cc b/chrome/browser/enterprise/connectors/analysis/fake_files_request_handler.cc index 73b31e6..a26eb67 100644 --- a/chrome/browser/enterprise/connectors/analysis/fake_files_request_handler.cc +++ b/chrome/browser/enterprise/connectors/analysis/fake_files_request_handler.cc
@@ -17,6 +17,7 @@ const std::string& source, const std::string& destination, const std::string& user_action_id, + const std::string& tab_title, safe_browsing::DeepScanAccessPoint access_point, const std::vector<base::FilePath>& paths, CompletionCallback callback) @@ -27,6 +28,7 @@ source, destination, user_action_id, + tab_title, access_point, paths, std::move(callback)), @@ -45,12 +47,13 @@ const std::string& source, const std::string& destination, const std::string& user_action_id, + const std::string& tab_title, safe_browsing::DeepScanAccessPoint access_point, const std::vector<base::FilePath>& paths, enterprise_connectors::FilesRequestHandler::CompletionCallback callback) { return std::make_unique<FakeFilesRequestHandler>( fake_file_upload_callback, upload_service, profile, analysis_settings, - url, source, destination, user_action_id, access_point, paths, + url, source, destination, user_action_id, tab_title, access_point, paths, std::move(callback)); }
diff --git a/chrome/browser/enterprise/connectors/analysis/fake_files_request_handler.h b/chrome/browser/enterprise/connectors/analysis/fake_files_request_handler.h index 1f1bd632..2cc129f 100644 --- a/chrome/browser/enterprise/connectors/analysis/fake_files_request_handler.h +++ b/chrome/browser/enterprise/connectors/analysis/fake_files_request_handler.h
@@ -33,6 +33,7 @@ const std::string& source, const std::string& destination, const std::string& user_action_id, + const std::string& tab_title, safe_browsing::DeepScanAccessPoint access_point, const std::vector<base::FilePath>& paths, CompletionCallback callback); @@ -48,6 +49,7 @@ const std::string& source, const std::string& destination, const std::string& user_action_id, + const std::string& tab_title, safe_browsing::DeepScanAccessPoint access_point, const std::vector<base::FilePath>& paths, enterprise_connectors::FilesRequestHandler::CompletionCallback callback);
diff --git a/chrome/browser/enterprise/connectors/analysis/file_transfer_analysis_delegate.cc b/chrome/browser/enterprise/connectors/analysis/file_transfer_analysis_delegate.cc index 99b73d6..6147150 100644 --- a/chrome/browser/enterprise/connectors/analysis/file_transfer_analysis_delegate.cc +++ b/chrome/browser/enterprise/connectors/analysis/file_transfer_analysis_delegate.cc
@@ -342,9 +342,10 @@ profile_, source_url_.path()), SourceDestinationMatcherAsh::GetVolumeDescriptionFromPath( profile_, destination_url_.path()), - // User action id is only needed for local content analysis, leave it - // empty here. - /*user_action_id=*/std::string(), access_point_, std::move(paths), + // User action id and tab title are only needed for local content + // analysis, leave them empty here. + /*user_action_id=*/std::string(), /*tab_title=*/std::string(), + access_point_, std::move(paths), base::BindOnce(&FileTransferAnalysisDelegate::ContentAnalysisCompleted, weak_ptr_factory_.GetWeakPtr())); request_handler_->UploadData();
diff --git a/chrome/browser/enterprise/connectors/analysis/files_request_handler.cc b/chrome/browser/enterprise/connectors/analysis/files_request_handler.cc index 8148900..175daab 100644 --- a/chrome/browser/enterprise/connectors/analysis/files_request_handler.cc +++ b/chrome/browser/enterprise/connectors/analysis/files_request_handler.cc
@@ -77,6 +77,7 @@ const std::string& source, const std::string& destination, const std::string& user_action_id, + const std::string& tab_title, safe_browsing::DeepScanAccessPoint access_point, const std::vector<base::FilePath>& paths, CompletionCallback callback) @@ -87,6 +88,7 @@ source, destination, user_action_id, + tab_title, paths.size(), access_point), paths_(paths), @@ -105,18 +107,19 @@ const std::string& source, const std::string& destination, const std::string& user_action_id, + const std::string& tab_title, safe_browsing::DeepScanAccessPoint access_point, const std::vector<base::FilePath>& paths, CompletionCallback callback) { if (GetFactoryStorage()->is_null()) { return base::WrapUnique(new FilesRequestHandler( upload_service, profile, analysis_settings, url, source, destination, - user_action_id, access_point, paths, std::move(callback))); + user_action_id, tab_title, access_point, paths, std::move(callback))); } else { // Use the factory to create a fake FilesRequestHandler. - return GetFactoryStorage()->Run(upload_service, profile, analysis_settings, - url, source, destination, user_action_id, - access_point, paths, std::move(callback)); + return GetFactoryStorage()->Run( + upload_service, profile, analysis_settings, url, source, destination, + user_action_id, tab_title, access_point, paths, std::move(callback)); } }
diff --git a/chrome/browser/enterprise/connectors/analysis/files_request_handler.h b/chrome/browser/enterprise/connectors/analysis/files_request_handler.h index 61fc6bf..539b8e1 100644 --- a/chrome/browser/enterprise/connectors/analysis/files_request_handler.h +++ b/chrome/browser/enterprise/connectors/analysis/files_request_handler.h
@@ -59,6 +59,7 @@ const std::string& source, const std::string& destination, const std::string& user_action_id, + const std::string& tab_title, safe_browsing::DeepScanAccessPoint access_point, const std::vector<base::FilePath>& paths, CompletionCallback callback)>; @@ -76,6 +77,7 @@ const std::string& source, const std::string& destination, const std::string& user_action_id, + const std::string& tab_title, safe_browsing::DeepScanAccessPoint access_point, const std::vector<base::FilePath>& paths, CompletionCallback callback); @@ -98,6 +100,7 @@ const std::string& source, const std::string& destination, const std::string& user_action_id, + const std::string& tab_title, safe_browsing::DeepScanAccessPoint access_point, const std::vector<base::FilePath>& paths, CompletionCallback callback);
diff --git a/chrome/browser/enterprise/connectors/analysis/files_request_handler_unittest.cc b/chrome/browser/enterprise/connectors/analysis/files_request_handler_unittest.cc index da6d3c8..c1a30a0 100644 --- a/chrome/browser/enterprise/connectors/analysis/files_request_handler_unittest.cc +++ b/chrome/browser/enterprise/connectors/analysis/files_request_handler_unittest.cc
@@ -45,6 +45,7 @@ constexpr char kDmToken[] = "dm_token"; constexpr char kUserActionId[] = "123"; +constexpr char kTabTitle[] = "tab_title"; constexpr char kTestUrl[] = "http://example.com/"; base::TimeDelta kResponseDelay = base::Seconds(0); @@ -204,8 +205,8 @@ weak_ptr_factory_.GetWeakPtr(), settings.cloud_or_local_settings.is_cloud_analysis()), /*upload_service=*/nullptr, profile_, settings, GURL(kTestUrl), "", "", - kUserActionId, safe_browsing::DeepScanAccessPoint::UPLOAD, paths, - future.GetCallback()); + kUserActionId, kTabTitle, safe_browsing::DeepScanAccessPoint::UPLOAD, + paths, future.GetCallback()); fake_files_request_handler_->UploadData(); @@ -296,6 +297,7 @@ EXPECT_EQ(request->user_action_requests_count(), expected_user_action_requests_count_); EXPECT_EQ(request->user_action_id(), kUserActionId); + EXPECT_EQ(request->tab_title(), kTabTitle); } // Simulate a response.
diff --git a/chrome/browser/enterprise/connectors/analysis/request_handler_base.cc b/chrome/browser/enterprise/connectors/analysis/request_handler_base.cc index 00b47c3..fdafb4b 100644 --- a/chrome/browser/enterprise/connectors/analysis/request_handler_base.cc +++ b/chrome/browser/enterprise/connectors/analysis/request_handler_base.cc
@@ -15,6 +15,7 @@ const std::string& source, const std::string& destination, const std::string& user_action_id, + const std::string& tab_title, uint64_t user_action_requests_count, safe_browsing::DeepScanAccessPoint access_point) : upload_service_(upload_service ? upload_service->AsWeakPtr() : nullptr), @@ -24,6 +25,7 @@ source_(source), destination_(destination), user_action_id_(user_action_id), + tab_title_(tab_title), user_action_requests_count_(user_action_requests_count), access_point_(access_point) {} @@ -55,6 +57,7 @@ if (analysis_settings_->cloud_or_local_settings.is_local_analysis()) { request->set_user_action_id(user_action_id_); request->set_user_action_requests_count(user_action_requests_count_); + request->set_tab_title(tab_title_); } request->set_analysis_connector(connector);
diff --git a/chrome/browser/enterprise/connectors/analysis/request_handler_base.h b/chrome/browser/enterprise/connectors/analysis/request_handler_base.h index 0939abb..47bc824b 100644 --- a/chrome/browser/enterprise/connectors/analysis/request_handler_base.h +++ b/chrome/browser/enterprise/connectors/analysis/request_handler_base.h
@@ -39,6 +39,7 @@ const std::string& source, const std::string& destination, const std::string& user_action_id, + const std::string& tab_title, uint64_t user_action_requests_count, safe_browsing::DeepScanAccessPoint access_point); @@ -91,6 +92,7 @@ std::string source_; std::string destination_; std::string user_action_id_; + std::string tab_title_; uint64_t user_action_requests_count_; safe_browsing::DeepScanAccessPoint access_point_;
diff --git a/chrome/browser/extensions/api/runtime/runtime_apitest.cc b/chrome/browser/extensions/api/runtime/runtime_apitest.cc index de87c56..844e984e 100644 --- a/chrome/browser/extensions/api/runtime/runtime_apitest.cc +++ b/chrome/browser/extensions/api/runtime/runtime_apitest.cc
@@ -8,6 +8,7 @@ #include "base/run_loop.h" #include "base/test/bind.h" #include "base/test/simple_test_tick_clock.h" +#include "base/test/values_test_util.h" #include "base/time/time.h" #include "chrome/browser/apps/platform_apps/app_browsertest_util.h" #include "chrome/browser/extensions/api/runtime/chrome_runtime_api_delegate.h" @@ -15,10 +16,12 @@ #include "chrome/browser/extensions/extension_function_test_utils.h" #include "chrome/browser/extensions/extension_service.h" #include "chrome/test/base/ui_test_utils.h" +#include "components/version_info/channel.h" #include "content/public/test/browser_test.h" #include "content/public/test/browser_test_utils.h" #include "content/public/test/test_navigation_observer.h" #include "extensions/browser/api/runtime/runtime_api.h" +#include "extensions/browser/background_script_executor.h" #include "extensions/browser/blocklist_extension_prefs.h" #include "extensions/browser/blocklist_state.h" #include "extensions/browser/extension_dialog_auto_confirm.h" @@ -26,6 +29,8 @@ #include "extensions/browser/extension_prefs.h" #include "extensions/browser/extension_registry.h" #include "extensions/browser/test_extension_registry_observer.h" +#include "extensions/common/extension_features.h" +#include "extensions/common/features/feature_channel.h" #include "extensions/test/extension_test_message_listener.h" #include "extensions/test/result_catcher.h" #include "extensions/test/test_extension_dir.h" @@ -598,4 +603,77 @@ } } +class RuntimeGetContextsApiTest : public ExtensionApiTest { + public: + RuntimeGetContextsApiTest() { + feature_list_.InitAndEnableFeature( + extensions_features::kApiRuntimeGetContexts); + } + RuntimeGetContextsApiTest(const RuntimeGetContextsApiTest&) = delete; + RuntimeGetContextsApiTest& operator=(const RuntimeGetContextsApiTest&) = + delete; + ~RuntimeGetContextsApiTest() override = default; + + void SetUpOnMainThread() override { + ExtensionApiTest::SetUpOnMainThread(); + + static constexpr char kManifest[] = + R"({ + "name": "Get Contexts", + "version": "0.1", + "manifest_version": 3, + "background": { + "service_worker": "background.js" + } + })"; + test_dir_.WriteManifest(kManifest); + test_dir_.WriteFile(FILE_PATH_LITERAL("background.js"), + "// Intentionally blank"); + extension_ = LoadExtension(test_dir_.UnpackedPath()); + ASSERT_TRUE(extension_); + } + + // Runs `chrome.runtime.getContexts()` and returns the result as a + // base::Value. + base::Value GetContexts() { + static constexpr char kScript[] = + R"((async () => { + chrome.test.sendScriptResult( + await chrome.runtime.getContexts()); + })();)"; + return BackgroundScriptExecutor::ExecuteScript( + profile(), extension_->id(), kScript, + BackgroundScriptExecutor::ResultCapture::kSendScriptResult); + } + + private: + const Extension* extension_ = nullptr; + TestExtensionDir test_dir_; + ScopedCurrentChannel channel_override_{version_info::Channel::UNKNOWN}; + base::test::ScopedFeatureList feature_list_; +}; + +// Tests retrieving the background service worker context using +// `chrome.runtime.getContexts()`. +IN_PROC_BROWSER_TEST_F(RuntimeGetContextsApiTest, GetServiceWorkerContext) { + base::Value background_contexts = GetContexts(); + // Note: fields of `documentId`, `documentUrl`, and `documentOrigin` are + // undefined (service worker contexts don't have an associated document). + // `tabId`, `frameId`, and `windowId` are -1 for consistency with other + // APIs. + static constexpr char kExpected[] = + R"([{ + "contextType": "BACKGROUND", + "contextId": "", + "tabId": -1, + "windowId": -1, + "frameId": -1, + "incognito": false + }])"; + EXPECT_THAT(background_contexts, base::test::IsJson(kExpected)); + + // TODO(crbug/1426192): Add tests for retrieving a service worker context + // when there isn't an active worker. +} + } // namespace extensions
diff --git a/chrome/browser/extensions/extension_browsertest.h b/chrome/browser/extensions/extension_browsertest.h index 20ff4e9f..f8990a0 100644 --- a/chrome/browser/extensions/extension_browsertest.h +++ b/chrome/browser/extensions/extension_browsertest.h
@@ -343,9 +343,8 @@ base::Value ExecuteScriptInBackgroundPage( const std::string& extension_id, const std::string& script, - extensions::browsertest_util::ScriptUserActivation - script_user_activation = - extensions::browsertest_util::ScriptUserActivation::kActivate); + browsertest_util::ScriptUserActivation script_user_activation = + browsertest_util::ScriptUserActivation::kDontActivate); // Waits until |script| calls "window.domAutomationController.send(result)", // where |result| is a string, and returns |result|. Fails the test and @@ -356,9 +355,8 @@ std::string ExecuteScriptInBackgroundPageDeprecated( const std::string& extension_id, const std::string& script, - extensions::browsertest_util::ScriptUserActivation - script_user_activation = - extensions::browsertest_util::ScriptUserActivation::kActivate); + browsertest_util::ScriptUserActivation script_user_activation = + browsertest_util::ScriptUserActivation::kDontActivate); bool ExecuteScriptInBackgroundPageNoWait(const std::string& extension_id, const std::string& script);
diff --git a/chrome/browser/extensions/offscreen_document_browsertest.cc b/chrome/browser/extensions/offscreen_document_browsertest.cc index 412d752..9775674 100644 --- a/chrome/browser/extensions/offscreen_document_browsertest.cc +++ b/chrome/browser/extensions/offscreen_document_browsertest.cc
@@ -230,8 +230,11 @@ domAutomationController.send(JSON.stringify(keys.sort())); })"; static constexpr char kExpectedProperties[] = - R"(["OnInstalledReason","OnRestartRequiredReason","PlatformArch",)" - R"("PlatformNaclArch","PlatformOs","RequestUpdateCheckStatus",)" + // Enums. + R"(["ContextType","OnInstalledReason","OnRestartRequiredReason",)" + R"("PlatformArch","PlatformNaclArch","PlatformOs",)" + R"("RequestUpdateCheckStatus",)" + // Methods and events. R"("connect","getURL","id","onConnect","onConnectExternal",)" R"("onMessage","onMessageExternal","sendMessage"])"; EXPECT_EQ(kExpectedProperties, ExecuteScriptSync(contents, kScript));
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index 8f25970f..ef165e6 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -494,6 +494,11 @@ "expiry_milestone": 120 }, { + "name": "autofill-enable-email-otp-for-vcn-yellow-path", + "owners": ["junhuihe@google.com"], + "expiry_milestone": 125 + }, + { "name": "autofill-enable-fido-progress-dialog", "owners": [ "siashah", "yiian" ], "expiry_milestone": 120 @@ -920,7 +925,7 @@ { "name": "captive-portal-error-page", "owners": [ "stevenjb", "cros-network-health-team@google.com" ], - "expiry_milestone": 114 + "expiry_milestone": 120 }, { "name": "cast-streaming-hardware-h264", @@ -1950,7 +1955,7 @@ { "name": "enable-commerce-developer", "owners": [ "chrome-shopping@google.com" ], - "expiry_milestone": 110 + "expiry_milestone": 125 }, { "name": "enable-commerce-hint-android", @@ -2556,17 +2561,17 @@ { "name": "enable-holding-space-predictability", "owners": [ "//ash/public/cpp/holding_space/OWNERS" ], - "expiry_milestone": 114 + "expiry_milestone": 116 }, { "name": "enable-holding-space-refresh", "owners": [ "//ash/public/cpp/holding_space/OWNERS" ], - "expiry_milestone": 114 + "expiry_milestone": 116 }, { "name": "enable-holding-space-suggestions", "owners": [ "//ash/public/cpp/holding_space/OWNERS" ], - "expiry_milestone": 114 + "expiry_milestone": 116 }, { "name": "enable-hostname-setting", @@ -6485,7 +6490,7 @@ "expiry_milestone": 96 }, { - "name": "settings-enable-get-the-most-out-of-program", + "name": "settings-enable-get-the-most-out-of-chrome", "owners": [ "jochen" ], "expiry_milestone": 130 },
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index 647c983..37ab5f81 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -400,6 +400,15 @@ "When enabled, card product name (instead of issuer network) will be shown " "in Payments Autofill UI."; +const char kAutofillEnableEmailOtpForVcnYellowPathName[] = + "Enable email OTP authentication in the yellow path of the VCN retrieval " + "flow"; +const char kAutofillEnableEmailOtpForVcnYellowPathDescription[] = + "When enabled, if the user encounters the yellow path (challenge path) in " + "the VCN retrieval flow and the server denotes that the card is eligible " + "for email OTP authentication, email OTP authentication will be offered as " + "one of the challenge options."; + const char kAutofillEnableNewCardArtAndNetworkImagesName[] = "Enable showing new card art and network images"; const char kAutofillEnableNewCardArtAndNetworkImagesDescription[] = @@ -4533,11 +4542,13 @@ "Enables SCT auditing for users who have opted in to Safe Browsing " "Extended Reporting."; -const char kSettingsEnableGetTheMostOutOfProgramName[] = +#if BUILDFLAG(GOOGLE_CHROME_BRANDING) +const char kSettingsEnableGetTheMostOutOfChromeName[] = "'Get the most out of Chrome' documentation"; -const char kSettingsEnableGetTheMostOutOfProgramDescription[] = +const char kSettingsEnableGetTheMostOutOfChromeDescription[] = "When enabled, the 'Get the most out of Chrome' documentation section " "will be available."; +#endif const char kSharingDesktopSharePreviewName[] = "Desktop share hub preview"; const char kSharingDesktopSharePreviewDescription[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index 1e0c244..332a2bb 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -232,6 +232,9 @@ extern const char kAutofillEnableCardProductNameName[]; extern const char kAutofillEnableCardProductNameDescription[]; +extern const char kAutofillEnableEmailOtpForVcnYellowPathName[]; +extern const char kAutofillEnableEmailOtpForVcnYellowPathDescription[]; + extern const char kAutofillEnableNewCardArtAndNetworkImagesName[]; extern const char kAutofillEnableNewCardArtAndNetworkImagesDescription[]; @@ -2606,8 +2609,10 @@ extern const char kSCTAuditingName[]; extern const char kSCTAuditingDescription[]; -extern const char kSettingsEnableGetTheMostOutOfProgramName[]; -extern const char kSettingsEnableGetTheMostOutOfProgramDescription[]; +#if BUILDFLAG(GOOGLE_CHROME_BRANDING) +extern const char kSettingsEnableGetTheMostOutOfChromeName[]; +extern const char kSettingsEnableGetTheMostOutOfChromeDescription[]; +#endif extern const char kSharingDesktopSharePreviewName[]; extern const char kSharingDesktopSharePreviewDescription[];
diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browser/flags/android/chrome_feature_list.cc index ebd0ad35..893a017 100644 --- a/chrome/browser/flags/android/chrome_feature_list.cc +++ b/chrome/browser/flags/android/chrome_feature_list.cc
@@ -229,6 +229,7 @@ &kContextualSearchThinWebViewImplementation, &kDeferKeepScreenOnDuringGesture, &kDeferNotifyInMotion, + &kDelayTransitionsForAnimation, &kExperimentsForAgsa, &kExploreSites, &kFocusOmniboxInIncognitoTabIntents, @@ -726,6 +727,10 @@ "DeferNotifyInMotion", base::FEATURE_DISABLED_BY_DEFAULT); +BASE_FEATURE(kDelayTransitionsForAnimation, + "DelayTransitionsForAnimation", + base::FEATURE_ENABLED_BY_DEFAULT); + BASE_FEATURE(kDownloadAutoResumptionThrottling, "DownloadAutoResumptionThrottling", base::FEATURE_ENABLED_BY_DEFAULT);
diff --git a/chrome/browser/flags/android/chrome_feature_list.h b/chrome/browser/flags/android/chrome_feature_list.h index 82e4cde..3e90bb1 100644 --- a/chrome/browser/flags/android/chrome_feature_list.h +++ b/chrome/browser/flags/android/chrome_feature_list.h
@@ -87,6 +87,7 @@ BASE_DECLARE_FEATURE(kContextualSearchThinWebViewImplementation); BASE_DECLARE_FEATURE(kDeferKeepScreenOnDuringGesture); BASE_DECLARE_FEATURE(kDeferNotifyInMotion); +BASE_DECLARE_FEATURE(kDelayTransitionsForAnimation); BASE_DECLARE_FEATURE(kDontPrefetchLibraries); BASE_DECLARE_FEATURE(kDownloadAutoResumptionThrottling); BASE_DECLARE_FEATURE(kDownloadHomeForExternalApp);
diff --git a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java index 79a5571a..94d0e799 100644 --- a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java +++ b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java
@@ -198,6 +198,8 @@ "AutofillEnableNewCardArtAndNetworkImages"; public static final String AUTOFILL_ENABLE_SUPPORT_FOR_HONORIFIC_PREFIXES = "AutofillEnableSupportForHonorificPrefixes"; + public static final String AUTOFILL_ENABLE_SUPPORT_FOR_MORE_STRUCTURE_IN_ADDRESSES = + "AutofillEnableSupportForMoreStructureInAddresses"; public static final String AUTOFILL_ENABLE_UPDATE_VIRTUAL_CARD_ENROLLMENT = "AutofillEnableUpdateVirtualCardEnrollment"; public static final String AUTOFILL_ENABLE_VIRTUAL_CARD_METADATA = @@ -213,6 +215,8 @@ public static final String BACK_GESTURE_REFACTOR_ACTIVITY = "BackGestureRefactorActivityAndroid"; public static final String BASELINE_GM3_SURFACE_COLORS = "BaselineGM3SurfaceColors"; + public static final String BIOMETRIC_TOUCH_TO_FILL = "BiometricTouchToFill"; + public static final String BOOKMARKS_IMPROVED_SAVE_FLOW = "BookmarksImprovedSaveFlow"; public static final String BOOKMARKS_REFRESH = "BookmarksRefresh"; public static final String CACHE_DEPRECATED_SYSTEM_LOCATION_SETTING = "CacheDeprecatedSystemLocationSetting"; @@ -221,6 +225,7 @@ public static final String CCT_ALLOW_CROSS_UID_ACTIVITY_SWITCH_FROM_BELOW = "CCTAllowCrossUidActivitySwitchFromBelow"; public static final String CCT_AUTO_TRANSLATE = "CCTAutoTranslate"; + public static final String CCT_BACKGROUND_TAB = "CCTBackgroundTab"; public static final String CCT_BOTTOM_BAR_SWIPE_UP_GESTURE = "CCTBottomBarSwipeUpGesture"; public static final String CCT_BRAND_TRANSPARENCY = "CCTBrandTransparency"; public static final String CCT_CLIENT_DATA_HEADER = "CCTClientDataHeader"; @@ -252,6 +257,7 @@ public static final String CCT_RESOURCE_PREFETCH = "CCTResourcePrefetch"; public static final String CCT_RETAINING_STATE_IN_MEMORY = "CCTRetainingStateInMemory"; public static final String CCT_TOOLBAR_CUSTOMIZATIONS = "CCTToolbarCustomizations"; + public static final String CHROME_NEW_DOWNLOAD_TAB = "ChromeNewDownloadTab"; public static final String CHROME_SHARING_HUB = "ChromeSharingHub"; public static final String CHROME_SHARING_HUB_LAUNCH_ADJACENT = "ChromeSharingHubLaunchAdjacent"; @@ -263,6 +269,7 @@ public static final String COMMERCE_COUPONS = "CommerceCoupons"; public static final String COMMERCE_MERCHANT_VIEWER = "CommerceMerchantViewer"; public static final String COMMERCE_PRICE_TRACKING = "CommercePriceTracking"; + public static final String CONTACTS_PICKER_SELECT_ALL = "ContactsPickerSelectAll"; public static final String CONTEXTUAL_PAGE_ACTIONS = "ContextualPageActions"; public static final String CONTEXTUAL_PAGE_ACTION_PRICE_TRACKING = "ContextualPageActionPriceTracking"; @@ -293,12 +300,17 @@ public static final String DEFER_KEEP_SCREEN_ON_DURING_GESTURE = "DeferKeepScreenOnDuringGesture"; public static final String DEFER_NOTIFY_IN_MOTION = "DeferNotifyInMotion"; + public static final String DELAY_TRANSITIONS_FOR_ANIMATION = "DelayTransitionsForAnimation"; public static final String DETAILED_LANGUAGE_SETTINGS = "DetailedLanguageSettings"; + public static final String DISCO_FEED_ENDPOINT = "DiscoFeedEndpoint"; public static final String DNS_OVER_HTTPS = "DnsOverHttps"; + public static final String DONT_AUTO_HIDE_BROWSER_CONTROLS = "DontAutoHideBrowserControls"; + public static final String DOWNLOADS_FOREGROUND = "DownloadsForeground"; public static final String DOWNLOAD_OFFLINE_CONTENT_PROVIDER = "UseDownloadOfflineContentProvider"; public static final String EARLY_LIBRARY_LOAD = "EarlyLibraryLoad"; public static final String ENABLE_IPH = "EnableIPH"; + public static final String ENABLE_PASSWORDS_ACCOUNT_STORAGE = "EnablePasswordsAccountStorage"; public static final String EXPERIMENTS_FOR_AGSA = "ExperimentsForAgsa"; public static final String EXPLICIT_LANGUAGE_ASK = "ExplicitLanguageAsk"; public static final String EXPLORE_SITES = "ExploreSites"; @@ -309,10 +321,14 @@ "FeedImageMemoryCacheSizePercentage"; public static final String FEED_LOADING_PLACEHOLDER = "FeedLoadingPlaceholder"; public static final String FEED_MULTI_COLUMN = "DiscoverFeedMultiColumn"; + public static final String FEED_NO_VIEW_CACHE = "FeedNoViewCache"; + public static final String FEED_INTERACTIVE_REFRESH = "FeedInteractiveRefresh"; + public static final String FEED_PERFORMANCE_STUDY = "FeedPerformanceStudy"; public static final String FEED_POSITION_ANDROID = "FeedPositionAndroid"; public static final String FEED_SHOW_SIGN_IN_COMMAND = "FeedShowSignInCommand"; public static final String FEED_BOC_SIGN_IN_INTERSTITIAL = "FeedBoCSigninInterstitial"; public static final String FILLING_PASSWORDS_FROM_ANY_ORIGIN = "FillingPasswordsFromAnyOrigin"; + public static final String FIXED_UMA_SESSION_RESUME_ORDER = "FixedUmaSessionResumeOrder"; public static final String FOCUS_OMNIBOX_IN_INCOGNITO_TAB_INTENTS = "FocusOmniboxInIncognitoTabIntents"; public static final String FOLDABLE_JANK_FIX = "FoldableJankFix"; @@ -338,6 +354,8 @@ public static final String INSTANCE_SWITCHER = "InstanceSwitcher"; public static final String INSTANT_START = "InstantStart"; public static final String INTEREST_FEED_CONTENT_SUGGESTIONS = "InterestFeedContentSuggestions"; + public static final String INTEREST_FEED_NOTICE_CARD_AUTO_DISMISS = + "InterestFeedNoticeCardAutoDismiss"; public static final String INTEREST_FEED_V2 = "InterestFeedV2"; public static final String INTEREST_FEED_V2_AUTOPLAY = "InterestFeedV2Autoplay"; public static final String INTEREST_FEED_V2_HEARTS = "InterestFeedV2Hearts"; @@ -348,12 +366,17 @@ public static final String LOCAL_WEB_APPROVALS = "LocalWebApprovals"; public static final String LOOKALIKE_NAVIGATION_URL_SUGGESTIONS_UI = "LookalikeUrlNavigationSuggestionsUI"; + public static final String MARK_HTTP_AS = "MarkHttpAs"; public static final String MESSAGES_FOR_ANDROID_ADS_BLOCKED = "MessagesForAndroidAdsBlocked"; public static final String MESSAGES_FOR_ANDROID_INFRASTRUCTURE = "MessagesForAndroidInfrastructure"; public static final String MESSAGES_FOR_ANDROID_PERMISSION_UPDATE = "MessagesForAndroidPermissionUpdate"; + public static final String MESSAGES_FOR_ANDROID_STACKING_ANIMATION = + "MessagesForAndroidStackingAnimation"; + public static final String MESSAGES_FOR_ANDROID_SYNC_ERROR = "MessagesForAndroidSyncError"; public static final String METRICS_SETTINGS_ANDROID = "MetricsSettingsAndroid"; + public static final String MODAL_PERMISSION_DIALOG_VIEW = "ModalPermissionDialogView"; public static final String NOTIFICATION_PERMISSION_VARIANT = "NotificationPermissionVariant"; public static final String NOTIFICATION_PERMISSION_BOTTOM_SHEET = "NotificationPermissionBottomSheet"; @@ -383,6 +406,7 @@ "OptimizationGuidePushNotifications"; public static final String OPTIMIZE_GEOLOCATION_HEADER_GENERATION = "OptimizeGeolocationHeaderGeneration"; + public static final String OVERLAY_NEW_LAYOUT = "OverlayNewLayout"; public static final String PAGE_ANNOTATIONS_SERVICE = "PageAnnotationsService"; public static final String PAGE_INFO_ABOUT_THIS_SITE_EN = "PageInfoAboutThisSiteEn"; public static final String PAGE_INFO_ABOUT_THIS_SITE_IMPROVED_BOTTOMSHEET = @@ -392,11 +416,15 @@ public static final String PAGE_INFO_ABOUT_THIS_SITE_NEW_ICON = "PageInfoAboutThisSiteNewIcon"; public static final String PAGE_INFO_ABOUT_THIS_SITE_NON_EN = "PageInfoAboutThisSiteNonEn"; public static final String PAINT_PREVIEW_DEMO = "PaintPreviewDemo"; + public static final String PAINT_PREVIEW_SHOW_ON_STARTUP = "PaintPreviewShowOnStartup"; public static final String PARTNER_HOMEPAGE_INITIAL_LOAD_IMPROVEMENT = "PartnerHomepageInitialLoadImprovement"; public static final String PASSKEY_MANAGEMENT_USING_ACCOUNT_SETTINGS_ANDROID = "PasskeyManagementUsingAccountSettingsAndroid"; + public static final String PASSWORD_DOMAIN_CAPABILITIES_FETCHING = + "PasswordDomainCapabilitiesFetching"; public static final String PASSWORD_EDIT_DIALOG_WITH_DETAILS = "PasswordEditDialogWithDetails"; + public static final String PERMISSION_DELEGATION = "PermissionDelegation"; public static final String PORTALS = "Portals"; public static final String PORTALS_CROSS_ORIGIN = "PortalsCrossOrigin"; public static final String POST_TASK_FOCUS_TAB = "PostTaskFocusTab"; @@ -429,6 +457,8 @@ public static final String RECOVER_FROM_NEVER_SAVE_ANDROID = "RecoverFromNeverSaveAndroid"; public static final String REENGAGEMENT_NOTIFICATION = "ReengagementNotification"; public static final String RELATED_SEARCHES = "RelatedSearches"; + public static final String REPORT_PARENTAL_CONTROL_SITES_CHILD = + "ReportParentalControlSitesChild"; public static final String REQUEST_DESKTOP_SITE_DEFAULTS = "RequestDesktopSiteDefaults"; public static final String REQUEST_DESKTOP_SITE_DEFAULTS_CONTROL = "RequestDesktopSiteDefaultsControl"; @@ -448,6 +478,7 @@ public static final String RESIZE_ONLY_ACTIVE_TAB = "ResizeOnlyActiveTab"; public static final String SAFE_BROWSING_DELAYED_WARNINGS = "SafeBrowsingDelayedWarnings"; public static final String SAFE_MODE_FOR_CACHED_FLAGS = "SafeModeForCachedFlags"; + public static final String SCREENSHOTS_FOR_ANDROID_V2 = "ScreenshotsForAndroidV2"; public static final String SEARCH_RESUMPTION_MODULE_ANDROID = "SearchResumptionModuleAndroid"; public static final String SHOULD_IGNORE_INTENT_SKIP_INTERNAL_CHECK = "ShouldIgnoreIntentSkipInternalCheck"; @@ -455,7 +486,10 @@ public static final String SEND_TAB_TO_SELF_SIGNIN_PROMO = "SendTabToSelfSigninPromo"; public static final String SEND_TAB_TO_SELF_V2 = "SendTabToSelfV2"; public static final String SHARED_HIGHLIGHTING_AMP = "SharedHighlightingAmp"; + public static final String SHARE_CROW_BUTTON = "ShareCrowButton"; + public static final String SHARE_CROW_BUTTON_LAUNCH_TAB = "ShareCrowLaunchTab"; public static final String SHOPPING_LIST = "ShoppingList"; + public static final String SHOW_EXTENDED_PRELOADING_SETTING = "ShowExtendedPreloadingSetting"; public static final String SHOW_SCROLLABLE_MVT_ON_NTP_ANDROID = "ShowScrollableMVTOnNTPAndroid"; public static final String SKIP_SERVICE_WORKER_FOR_INSTALL_PROMPT = "SkipServiceWorkerForInstallPromot"; @@ -507,13 +541,18 @@ "TrustedWebActivityQualityEnforcementForced"; public static final String TRUSTED_WEB_ACTIVITY_QUALITY_ENFORCEMENT_WARNING = "TrustedWebActivityQualityEnforcementWarning"; + public static final String UNIFIED_CREDENTIAL_MANAGER_DRY_RUN = + "UnifiedCredentialManagerDryRun"; public static final String UNIFIED_PASSWORD_MANAGER_ANDROID = "UnifiedPasswordManagerAndroid"; public static final String UNIFIED_PASSWORD_MANAGER_ANDROID_BRANDING = "UnifiedPasswordManagerAndroidBranding"; public static final String UNIFIED_PASSWORD_MANAGER_ERROR_MESSAGES = "UnifiedPasswordManagerErrorMessages"; public static final String UPCOMING_SHARING_FEATURES = "UpcomingSharingFeatures"; + public static final String UPDATE_NOTIFICATION_IMMEDIATE_SHOW_OPTION = + "UpdateNotificationScheduleServiceImmediateShowOption"; public static final String USE_CHIME_ANDROID_SDK = "UseChimeAndroidSdk"; + public static final String USE_CLIENT_CONFIG_IPH = "UseClientConfigIPH"; public static final String USE_LIBUNWINDSTACK_NATIVE_UNWINDER_ANDROID = "UseLibunwindstackNativeUnwinderAndroid"; public static final String VIDEO_TUTORIALS = "VideoTutorials"; @@ -521,6 +560,8 @@ public static final String VOICE_SEARCH_AUDIO_CAPTURE_POLICY = "VoiceSearchAudioCapturePolicy"; public static final String WEBNOTES_STYLIZE = "WebNotesStylize"; public static final String WEB_APK_ALLOW_ICON_UPDATA = "WebApkAllowIconUpdate"; + public static final String WEB_APK_INSTALL_COMPLETE_NOTIFICATION = + "WebApkInstallCompleteNotification"; public static final String WEB_APK_INSTALL_SERVICE = "WebApkInstallService"; public static final String WEB_APK_TRAMPOLINE_ON_INITIAL_INTENT = "WebApkTrampolineOnInitialIntent";
diff --git a/chrome/browser/history_clusters/java/src/org/chromium/chrome/browser/history_clusters/HistoryClusterView.java b/chrome/browser/history_clusters/java/src/org/chromium/chrome/browser/history_clusters/HistoryClusterView.java index 98ca850..086958b 100644 --- a/chrome/browser/history_clusters/java/src/org/chromium/chrome/browser/history_clusters/HistoryClusterView.java +++ b/chrome/browser/history_clusters/java/src/org/chromium/chrome/browser/history_clusters/HistoryClusterView.java
@@ -81,7 +81,7 @@ protected void onClick() {} @Override - protected @Nullable ColorStateList getDefaultStartIconTint() { + protected @Nullable ColorStateList getDefaultIconTint() { return ColorStateList.valueOf( SemanticColorUtils.getDefaultIconColorSecondary(getContext())); } @@ -94,13 +94,9 @@ mDescriptionView.setText(text); } - void setIconDrawable(Drawable drawable) { - super.setStartIconDrawable(drawable); - } - public void setStartIconBackgroundRes(@DrawableRes int resId) { mStartIconView.setBackgroundResource(resId); - ImageViewCompat.setImageTintList(mStartIconView, getDefaultStartIconTint()); + ImageViewCompat.setImageTintList(mStartIconView, getDefaultIconTint()); } void setEndButtonDrawable(Drawable drawable) {
diff --git a/chrome/browser/history_clusters/java/src/org/chromium/chrome/browser/history_clusters/HistoryClustersItemView.java b/chrome/browser/history_clusters/java/src/org/chromium/chrome/browser/history_clusters/HistoryClustersItemView.java index bb182274..7e5ea37 100644 --- a/chrome/browser/history_clusters/java/src/org/chromium/chrome/browser/history_clusters/HistoryClustersItemView.java +++ b/chrome/browser/history_clusters/java/src/org/chromium/chrome/browser/history_clusters/HistoryClustersItemView.java
@@ -5,7 +5,6 @@ package org.chromium.chrome.browser.history_clusters; import android.content.Context; -import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.view.View; import android.widget.ImageView; @@ -59,10 +58,6 @@ mDescriptionView.setText(text); } - void setIconDrawable(Drawable drawable) { - super.setStartIconDrawable(drawable); - } - void setEndButtonClickHandler(OnClickListener onClickListener) { mEndButtonView.setOnClickListener(onClickListener); }
diff --git a/chrome/browser/k_anonymity_service/k_anonymity_service_client.cc b/chrome/browser/k_anonymity_service/k_anonymity_service_client.cc index ef987a9a..393b8dd4b 100644 --- a/chrome/browser/k_anonymity_service/k_anonymity_service_client.cc +++ b/chrome/browser/k_anonymity_service/k_anonymity_service_client.cc
@@ -25,6 +25,7 @@ #include "google_apis/google_api_keys.h" #include "net/base/isolation_info.h" #include "net/base/load_flags.h" +#include "net/http/http_status_code.h" #include "net/traffic_annotation/network_traffic_annotation.h" #include "services/data_decoder/public/cpp/data_decoder.h" #include "services/network/public/cpp/resource_request.h" @@ -121,14 +122,28 @@ } } - void OnCompleted(const absl::optional<std::string>& response, - int net_error) override { + void OnCompleted( + network::mojom::ObliviousHttpCompletionResultPtr status) override { if (called_) { mojo::ReportBadMessage("OnCompleted called more than once"); return; } called_ = true; - std::move(callback_).Run(response, net_error); + if (status->is_net_error()) { + std::move(callback_).Run(absl::nullopt, status->get_net_error()); + } else if (status->is_outer_response_error_code()) { + std::move(callback_).Run(absl::nullopt, + net::ERR_HTTP_RESPONSE_CODE_FAILURE); + } else { + DCHECK(status->is_inner_response()); + if (status->get_inner_response()->response_code != net::HTTP_OK) { + std::move(callback_).Run(absl::nullopt, + net::ERR_HTTP_RESPONSE_CODE_FAILURE); + } else { + std::move(callback_).Run(status->get_inner_response()->response_body, + net::OK); + } + } } private:
diff --git a/chrome/browser/k_anonymity_service/k_anonymity_service_client_unittest.cc b/chrome/browser/k_anonymity_service/k_anonymity_service_client_unittest.cc index 265f723a..96772d8 100644 --- a/chrome/browser/k_anonymity_service/k_anonymity_service_client_unittest.cc +++ b/chrome/browser/k_anonymity_service/k_anonymity_service_client_unittest.cc
@@ -414,10 +414,29 @@ return; } if (error_) { - remote_->OnCompleted(absl::nullopt, error_.value()); + auto completion_result = + network::mojom::ObliviousHttpCompletionResult::NewNetError( + error_.value()); + remote_->OnCompleted(std::move(completion_result)); error_.reset(); + } else if (outer_response_error_code_) { + auto completion_result = network::mojom::ObliviousHttpCompletionResult:: + NewOuterResponseErrorCode(outer_response_error_code_.value()); + remote_->OnCompleted(std::move(completion_result)); + outer_response_error_code_.reset(); } else { - remote_->OnCompleted(body, net::OK); + auto response = network::mojom::ObliviousHttpResponse::New(); + if (inner_response_code_) { + response->response_code = inner_response_code_.value(); + inner_response_code_.reset(); + } else { + response->response_code = net::HTTP_OK; + } + response->response_body = std::move(body); + auto completion_result = + network::mojom::ObliviousHttpCompletionResult::NewInnerResponse( + std::move(response)); + remote_->OnCompleted(std::move(completion_result)); } remote_.reset(); pending_request_.reset(); @@ -425,9 +444,17 @@ void SetDropRequests(bool drop) { drop_requests_ = drop; } void SetErrorOnce(net::Error err) { error_ = err; } + void SetOuterResponseErrorOnce(int outer_response_error_code) { + outer_response_error_code_ = outer_response_error_code; + } + void SetInnerResponseErrorOnce(int inner_response_code) { + inner_response_code_ = inner_response_code; + } private: absl::optional<net::Error> error_; + absl::optional<int> outer_response_error_code_; + absl::optional<int> inner_response_code_; bool drop_requests_ = false; network::mojom::ObliviousHttpRequestPtr pending_request_; mojo::Remote<network::mojom::ObliviousHttpClient> remote_; @@ -501,6 +528,14 @@ void SetOhttpErrorOnce(net::Error err) { network_context_.SetErrorOnce(err); } + void SetOhttpOuterResponseErrorOnce(int outer_response_error_code) { + network_context_.SetOuterResponseErrorOnce(outer_response_error_code); + } + + void SetOhttpInnerResponseErrorOnce(int inner_response_code) { + network_context_.SetInnerResponseErrorOnce(inner_response_code); + } + private: OhttpTestNetworkContext network_context_; mojo::Receiver<network::mojom::NetworkContext> network_context_receiver_; @@ -597,7 +632,8 @@ {KAnonymityServiceJoinSetAction::kJoinSetSuccess, 1}}); } -TEST_F(KAnonymityServiceClientJoinQueryTest, TryJoinSetOtherErrorsNotRetried) { +TEST_F(KAnonymityServiceClientJoinQueryTest, + TryJoinSetOtherNetErrorsNotRetried) { InitializeIdentity(true); SetOhttpErrorOnce(net::ERR_FAILED); KAnonymityServiceClient k_service(profile()); @@ -621,6 +657,54 @@ } TEST_F(KAnonymityServiceClientJoinQueryTest, + TryJoinSetOtherOuterHttpStatusErrorNotRetried) { + InitializeIdentity(true); + SetOhttpOuterResponseErrorOnce(net::HTTP_NOT_FOUND); + KAnonymityServiceClient k_service(profile()); + base::HistogramTester hist; + base::RunLoop run_loop; + k_service.JoinSet("1", base::BindLambdaForTesting([&run_loop](bool result) { + EXPECT_FALSE(result); + run_loop.Quit(); + })); + RespondWithJoinKey(); + RespondWithTrustTokenNonUniqueUserID(2); + RespondWithTrustTokenKeys(2); + RespondWithTrustTokenIssued(2); + RespondWithJoin(); + run_loop.Run(); + CheckJoinSetHistogramActions( + hist, {{KAnonymityServiceJoinSetAction::kJoinSet, 1}, + {KAnonymityServiceJoinSetAction::kFetchJoinSetOHTTPKey, 1}, + {KAnonymityServiceJoinSetAction::kSendJoinSetRequest, 1}, + {KAnonymityServiceJoinSetAction::kJoinSetRequestFailed, 1}}); +} + +TEST_F(KAnonymityServiceClientJoinQueryTest, + TryJoinSetOtherInnerHttpStatusErrorNotRetried) { + InitializeIdentity(true); + SetOhttpInnerResponseErrorOnce(net::HTTP_NOT_FOUND); + KAnonymityServiceClient k_service(profile()); + base::HistogramTester hist; + base::RunLoop run_loop; + k_service.JoinSet("1", base::BindLambdaForTesting([&run_loop](bool result) { + EXPECT_FALSE(result); + run_loop.Quit(); + })); + RespondWithJoinKey(); + RespondWithTrustTokenNonUniqueUserID(2); + RespondWithTrustTokenKeys(2); + RespondWithTrustTokenIssued(2); + RespondWithJoin(); + run_loop.Run(); + CheckJoinSetHistogramActions( + hist, {{KAnonymityServiceJoinSetAction::kJoinSet, 1}, + {KAnonymityServiceJoinSetAction::kFetchJoinSetOHTTPKey, 1}, + {KAnonymityServiceJoinSetAction::kSendJoinSetRequest, 1}, + {KAnonymityServiceJoinSetAction::kJoinSetRequestFailed, 1}}); +} + +TEST_F(KAnonymityServiceClientJoinQueryTest, TryJoinSetTokenAlreadyRetriedTooMany) { InitializeIdentity(true); KAnonymityServiceClient k_service(profile());
diff --git a/chrome/browser/performance_manager/metrics/metrics_provider.cc b/chrome/browser/performance_manager/metrics/metrics_provider.cc index 18a234d2e..52fa7342 100644 --- a/chrome/browser/performance_manager/metrics/metrics_provider.cc +++ b/chrome/browser/performance_manager/metrics/metrics_provider.cc
@@ -5,6 +5,8 @@ #include "chrome/browser/performance_manager/metrics/metrics_provider.h" #include "base/metrics/histogram_functions.h" +#include "base/system/sys_info.h" +#include "base/timer/timer.h" #include "chrome/browser/performance_manager/public/user_tuning/user_performance_tuning_manager.h" #include "components/performance_manager/public/user_tuning/prefs.h" #include "components/prefs/pref_service.h" @@ -15,6 +17,7 @@ MetricsProvider* g_metrics_provider = nullptr; +uint64_t kBytesPerMb = 1024 * 1024; } // static @@ -65,6 +68,11 @@ : local_state_(local_state) { DCHECK(!g_metrics_provider); g_metrics_provider = this; + + available_memory_metrics_timer_.Start( + FROM_HERE, base::Minutes(2), + base::BindRepeating(&MetricsProvider::RecordAvailableMemoryMetrics, + base::Unretained(this))); } void MetricsProvider::OnBatterySaverModeChanged(bool is_active) { @@ -114,4 +122,14 @@ return EfficiencyMode::kNormal; } +void MetricsProvider::RecordAvailableMemoryMetrics() { + auto available_bytes = base::SysInfo::AmountOfAvailablePhysicalMemory(); + auto total_bytes = base::SysInfo::AmountOfPhysicalMemory(); + + base::UmaHistogramMemoryLargeMB("Memory.Experimental.AvailableMemoryMB", + available_bytes / kBytesPerMb); + base::UmaHistogramPercentage("Memory.Experimental.AvailableMemoryPercent", + available_bytes * 100 / total_bytes); +} + } // namespace performance_manager
diff --git a/chrome/browser/performance_manager/metrics/metrics_provider.h b/chrome/browser/performance_manager/metrics/metrics_provider.h index 5026639b..1cd8a98 100644 --- a/chrome/browser/performance_manager/metrics/metrics_provider.h +++ b/chrome/browser/performance_manager/metrics/metrics_provider.h
@@ -60,6 +60,8 @@ void OnTuningModesChanged(); EfficiencyMode ComputeCurrentMode() const; + void RecordAvailableMemoryMetrics(); + PrefChangeRegistrar pref_change_registrar_; const raw_ptr<PrefService> local_state_; EfficiencyMode current_mode_ = EfficiencyMode::kNormal; @@ -67,6 +69,8 @@ bool battery_saver_enabled_ = false; bool initialized_ = false; + + base::RepeatingTimer available_memory_metrics_timer_; }; } // namespace performance_manager
diff --git a/chrome/browser/profiles/profile_manager_unittest.cc b/chrome/browser/profiles/profile_manager_unittest.cc index 08e3ca7..73bd9bc 100644 --- a/chrome/browser/profiles/profile_manager_unittest.cc +++ b/chrome/browser/profiles/profile_manager_unittest.cc
@@ -74,7 +74,7 @@ #include "chrome/browser/ash/login/users/scoped_test_user_manager.h" #include "chrome/browser/ash/profiles/profile_helper.h" #include "chrome/browser/ash/settings/scoped_cros_settings_test_helper.h" -#include "chrome/browser/ash/wallpaper_handlers/test_backdrop_fetcher_delegate.h" +#include "chrome/browser/ash/wallpaper_handlers/test_wallpaper_fetcher_delegate.h" #include "chrome/browser/ui/ash/test_wallpaper_controller.h" #include "chrome/browser/ui/ash/wallpaper_controller_client_impl.h" #include "components/user_manager/fake_user_manager.h" @@ -164,7 +164,7 @@ ash::UserImageManagerImpl::SkipDefaultUserImageDownloadForTesting(); wallpaper_controller_client_ = std::make_unique< WallpaperControllerClientImpl>( - std::make_unique<wallpaper_handlers::TestBackdropFetcherDelegate>()); + std::make_unique<wallpaper_handlers::TestWallpaperFetcherDelegate>()); wallpaper_controller_client_->InitForTesting(&test_wallpaper_controller_); // Have to manually reset the session type in between test runs because
diff --git a/chrome/browser/resources/chromeos/accessibility/common/automation_predicate.js b/chrome/browser/resources/chromeos/accessibility/common/automation_predicate.js index bba9f7c..6eca586 100644 --- a/chrome/browser/resources/chromeos/accessibility/common/automation_predicate.js +++ b/chrome/browser/resources/chromeos/accessibility/common/automation_predicate.js
@@ -88,6 +88,9 @@ if (child.role !== Role.STATIC_TEXT) { return false; } + if (child.name === undefined) { + return false; + } if (name.substring(nameIndex, nameIndex + child.name.length) !== child.name) { return false;
diff --git a/chrome/browser/resources/settings/about_page/about_page.html b/chrome/browser/resources/settings/about_page/about_page.html index 13262ca..699bcdd 100644 --- a/chrome/browser/resources/settings/about_page/about_page.html +++ b/chrome/browser/resources/settings/about_page/about_page.html
@@ -129,13 +129,13 @@ hidden="[[!prefs.feedback_allowed.value]]" button-aria-description="$i18n{opensInNewTab}" label="$i18n{aboutReportAnIssue}" external></cr-link-row> -</if> - <cr-link-row class="hr" id="getTheMostOutOfProgram" - on-click="onGetTheMostOutOfProgramTap_" - label="$i18n{getTheMostOutOfProgram}" - sub-label="$i18n{getTheMostOutOfProgramDescription}" + <cr-link-row class="hr" id="getTheMostOutOfChrome" + on-click="onGetTheMostOutOfChromeTap_" + label="$i18n{getTheMostOutOfChrome}" + sub-label="$i18n{getTheMostOutOfChromeDescription}" role-description="$i18n{subpageArrowRoleDescription}" - hidden$="[[!showGetTheMostOutOfProgramSection_]]"></cr-link-row> + hidden$="[[!showGetTheMostOutOfChromeSection_]]"></cr-link-row> +</if> <cr-link-row class="hr" on-click="onManagementPageTap_" start-icon="cr:domain" label="$i18n{managementPage}" role-description="$i18n{subpageArrowRoleDescription}"
diff --git a/chrome/browser/resources/settings/about_page/about_page.ts b/chrome/browser/resources/settings/about_page/about_page.ts index cf1a524..b0ede74 100644 --- a/chrome/browser/resources/settings/about_page/about_page.ts +++ b/chrome/browser/resources/settings/about_page/about_page.ts
@@ -75,15 +75,17 @@ }, }, + // <if expr="_google_chrome"> /** * Whether to show the "Get the most out of Chrome" section. */ - showGetTheMostOutOfProgramSection_: { + showGetTheMostOutOfChromeSection_: { type: Boolean, value() { - return loadTimeData.getBoolean('showGetTheMostOutOfProgramSection'); + return loadTimeData.getBoolean('showGetTheMostOutOfChromeSection'); }, }, + // </if> // <if expr="_google_chrome and is_macosx"> promoteUpdaterStatus_: Object, @@ -128,7 +130,10 @@ private currentUpdateStatusEvent_: UpdateStatusChangedEvent|null; private isManaged_: boolean; - private showGetTheMostOutOfProgramSection_: boolean; + + // <if expr="_google_chrome"> + private showGetTheMostOutOfChromeSection_: boolean; + // </if> // <if expr="_google_chrome and is_macosx"> private promoteUpdaterStatus_: PromoteUpdaterStatus; @@ -213,10 +218,6 @@ this.performRestart(RestartType.RELAUNCH); } - private onGetTheMostOutOfProgramTap_() { - // TODO(crbug.com/1423278): implement. - } - // <if expr="not chromeos_ash"> private updateShowUpdateStatus_() { if (this.obsoleteSystemInfo_.endOfLine) { @@ -340,6 +341,10 @@ private onReportIssueTap_() { this.aboutBrowserProxy_.openFeedbackDialog(); } + + private onGetTheMostOutOfChromeTap_() { + // TODO(crbug.com/1423278): implement. + } // </if> // <if expr="not chromeos_ash">
diff --git a/chrome/browser/resources/settings/autofill_page/autofill_page.ts b/chrome/browser/resources/settings/autofill_page/autofill_page.ts index cfeb6dc6..407f8454 100644 --- a/chrome/browser/resources/settings/autofill_page/autofill_page.ts +++ b/chrome/browser/resources/settings/autofill_page/autofill_page.ts
@@ -18,7 +18,6 @@ import '../settings_shared.css.js'; import {CrLinkRowElement} from 'chrome://resources/cr_elements/cr_link_row/cr_link_row.js'; -import {OpenWindowProxyImpl} from 'chrome://resources/js/open_window_proxy.js'; import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {BaseMixin} from '../base_mixin.js'; @@ -29,7 +28,7 @@ import {getTemplate} from './autofill_page.html.js'; import {PasswordCheckMixin} from './password_check_mixin.js'; -import {PasswordManagerImpl} from './password_manager_proxy.js'; +import {PasswordManagerImpl, PasswordManagerPage} from './password_manager_proxy.js'; import {PasswordRequestorMixin} from './password_requestor_mixin.js'; import {PasswordViewPageInteractions, PasswordViewPageRequestedEvent, PasswordViewPageUrlParams, recordPasswordViewInteraction} from './password_view.js'; @@ -141,9 +140,8 @@ private onPasswordsClick_() { PasswordManagerImpl.getInstance().recordPasswordsPageAccessInSettings(); if (this.enableNewPasswordManagerPage_) { - // TODO(crbug.com/1416887): It will always open a new tab with Password - // Manager. Find a way to use chrome::ShowPasswordManager instead. - OpenWindowProxyImpl.getInstance().openUrl('chrome://password-manager'); + PasswordManagerImpl.getInstance().showPasswordManager( + PasswordManagerPage.PASSWORDS); return; } Router.getInstance().navigateTo(routes.PASSWORDS);
diff --git a/chrome/browser/resources/settings/autofill_page/password_manager_proxy.ts b/chrome/browser/resources/settings/autofill_page/password_manager_proxy.ts index 88def41..c63ab5f 100644 --- a/chrome/browser/resources/settings/autofill_page/password_manager_proxy.ts +++ b/chrome/browser/resources/settings/autofill_page/password_manager_proxy.ts
@@ -25,6 +25,13 @@ export type PasswordManagerAuthTimeoutListener = () => void; +// WARNING: Keep synced with +// chrome/browser/ui/webui/settings/password_manager_handler.cc. +export enum PasswordManagerPage { + PASSWORDS = 0, + CHECKUP = 1, +} + /** * Interface for all callbacks to the password API. */ @@ -316,6 +323,11 @@ * successful authentication. */ switchBiometricAuthBeforeFillingState(): void; + + /** + * Shows new Password Manager UI (chrome://password-manager). + */ + showPasswordManager(page: PasswordManagerPage): void; } /** @@ -587,6 +599,10 @@ PasswordCheckReferrer.COUNT); } + showPasswordManager(page: PasswordManagerPage) { + chrome.send('showPasswordManager', [page]); + } + static getInstance(): PasswordManagerProxy { return instance || (instance = new PasswordManagerImpl()); }
diff --git a/chrome/browser/resources/settings/safety_check_page/safety_check_passwords_child.ts b/chrome/browser/resources/settings/safety_check_page/safety_check_passwords_child.ts index 8ea58b6..46ec08eb 100644 --- a/chrome/browser/resources/settings/safety_check_page/safety_check_passwords_child.ts +++ b/chrome/browser/resources/settings/safety_check_page/safety_check_passwords_child.ts
@@ -10,10 +10,9 @@ import {I18nMixin} from 'chrome://resources/cr_elements/i18n_mixin.js'; import {WebUiListenerMixin} from 'chrome://resources/cr_elements/web_ui_listener_mixin.js'; import {assertNotReached} from 'chrome://resources/js/assert_ts.js'; -import {OpenWindowProxyImpl} from 'chrome://resources/js/open_window_proxy.js'; import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; -import {PasswordCheckReferrer, PasswordManagerImpl} from '../autofill_page/password_manager_proxy.js'; +import {PasswordCheckReferrer, PasswordManagerImpl, PasswordManagerPage} from '../autofill_page/password_manager_proxy.js'; import {loadTimeData} from '../i18n_setup.js'; import {MetricsBrowserProxy, MetricsBrowserProxyImpl, SafetyCheckInteractions} from '../metrics_browser_proxy.js'; import {routes} from '../route.js'; @@ -162,10 +161,8 @@ PasswordManagerImpl.getInstance().recordPasswordCheckReferrer( PasswordCheckReferrer.SAFETY_CHECK); if (this.enableNewPasswordManagerPage_) { - // TODO(crbug.com/1416887): It will always open a new tab with Password - // Manager. Find a way to use chrome::ShowPasswordCheck instead. - OpenWindowProxyImpl.getInstance().openUrl( - 'chrome://password-manager/checkup'); + PasswordManagerImpl.getInstance().showPasswordManager( + PasswordManagerPage.CHECKUP); return; } Router.getInstance().navigateTo(
diff --git a/chrome/browser/resources/settings/settings.ts b/chrome/browser/resources/settings/settings.ts index 22cc8c7f..423d5f4 100644 --- a/chrome/browser/resources/settings/settings.ts +++ b/chrome/browser/resources/settings/settings.ts
@@ -25,7 +25,7 @@ export {SettingsAppearancePageElement, SystemTheme} from './appearance_page/appearance_page.js'; export {HomeUrlInputElement} from './appearance_page/home_url_input.js'; export {SettingsAutofillPageElement} from './autofill_page/autofill_page.js'; -export {AccountStorageOptInStateChangedListener, CredentialsChangedListener, PasswordCheckInteraction, PasswordCheckReferrer, PasswordCheckStatusChangedListener, PasswordExceptionListChangedListener, PasswordManagerAuthTimeoutListener, PasswordManagerImpl, PasswordManagerProxy, PasswordsFileExportProgressListener, SavedPasswordListChangedListener} from './autofill_page/password_manager_proxy.js'; +export {AccountStorageOptInStateChangedListener, CredentialsChangedListener, PasswordCheckInteraction, PasswordCheckReferrer, PasswordCheckStatusChangedListener, PasswordExceptionListChangedListener, PasswordManagerAuthTimeoutListener, PasswordManagerImpl, PasswordManagerPage, PasswordManagerProxy, PasswordsFileExportProgressListener, SavedPasswordListChangedListener} from './autofill_page/password_manager_proxy.js'; export {BaseMixin} from './base_mixin.js'; export {SettingsBasicPageElement} from './basic_page/basic_page.js'; export {ControlledRadioButtonElement} from './controls/controlled_radio_button.js';
diff --git a/chrome/browser/safe_browsing/cloud_content_scanning/binary_upload_service.cc b/chrome/browser/safe_browsing/cloud_content_scanning/binary_upload_service.cc index 0b6065f6..75eae9e 100644 --- a/chrome/browser/safe_browsing/cloud_content_scanning/binary_upload_service.cc +++ b/chrome/browser/safe_browsing/cloud_content_scanning/binary_upload_service.cc
@@ -249,6 +249,10 @@ return content_analysis_request_.user_action_id(); } +const std::string& BinaryUploadService::Request::tab_title() const { + return content_analysis_request_.request_data().tab_title(); +} + uint64_t BinaryUploadService::Request::user_action_requests_count() const { return content_analysis_request_.user_action_requests_count(); }
diff --git a/chrome/browser/safe_browsing/cloud_content_scanning/binary_upload_service.h b/chrome/browser/safe_browsing/cloud_content_scanning/binary_upload_service.h index 6dd2703..e48ddd1d 100644 --- a/chrome/browser/safe_browsing/cloud_content_scanning/binary_upload_service.h +++ b/chrome/browser/safe_browsing/cloud_content_scanning/binary_upload_service.h
@@ -180,6 +180,7 @@ const std::string& digest() const; const std::string& content_type() const; const std::string& user_action_id() const; + const std::string& tab_title() const; uint64_t user_action_requests_count() const; GURL tab_url() const;
diff --git a/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_browsertest_base.cc b/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_browsertest_base.cc index bce2cec..290e911 100644 --- a/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_browsertest_base.cc +++ b/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_browsertest_base.cc
@@ -43,12 +43,13 @@ const std::string& source, const std::string& destination, const std::string& user_action_id, + const std::string& tab_title, safe_browsing::DeepScanAccessPoint access_point, const std::vector<base::FilePath>& paths, enterprise_connectors::FilesRequestHandler::CompletionCallback callback) { return base::WrapUnique(new UnresponsiveFilesRequestHandler( upload_service, profile, analysis_settings, url, source, destination, - user_action_id, access_point, paths, std::move(callback))); + user_action_id, tab_title, access_point, paths, std::move(callback))); } private:
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index 388396e..b35a81f 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -1640,6 +1640,8 @@ "webui/settings/metrics_reporting_handler.h", "webui/settings/on_startup_handler.cc", "webui/settings/on_startup_handler.h", + "webui/settings/password_manager_handler.cc", + "webui/settings/password_manager_handler.h", "webui/settings/people_handler.cc", "webui/settings/people_handler.h", "webui/settings/performance_handler.cc",
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/base/ActionChipsProcessor.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/base/ActionChipsProcessor.java index de080cc..08d382e 100644 --- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/base/ActionChipsProcessor.java +++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/base/ActionChipsProcessor.java
@@ -92,10 +92,9 @@ modelList.add(new ListItem(ActionChipsProperties.ViewType.CHIP, chipModel)); - if (chip.hasPedalId()) { - mLastVisiblePedals.add(chip.getPedalID()); - } else if (chip.hasActionId() - && chip.getActionID() == OmniboxActionType.HISTORY_CLUSTERS) { + if (chip.getActionId() == OmniboxActionType.PEDAL) { + mLastVisiblePedals.add(chip.getPedalId()); + } else if (chip.getActionId() == OmniboxActionType.HISTORY_CLUSTERS) { mJourneysActionShownPosition = position; } } @@ -108,8 +107,7 @@ } private void executeAction(@NonNull OmniboxPedal omniboxPedal, int position) { - if (omniboxPedal.hasActionId() - && omniboxPedal.getActionID() == OmniboxActionType.HISTORY_CLUSTERS) { + if (omniboxPedal.getActionId() == OmniboxActionType.HISTORY_CLUSTERS) { RecordHistogram.recordEnumeratedHistogram("Omnibox.SuggestionUsed.ResumeJourney", position, SuggestionsMetrics.MAX_AUTOCOMPLETE_POSITION); }
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/ToolbarFeatures.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/ToolbarFeatures.java index 70f44b2..c3c3f70 100644 --- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/ToolbarFeatures.java +++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/ToolbarFeatures.java
@@ -22,6 +22,8 @@ new MutableFlagWithSafeDefault(ChromeFeatureList.SUPPRESS_TOOLBAR_CAPTURES, false); private static final MutableFlagWithSafeDefault sRecordSuppressionMetrics = new MutableFlagWithSafeDefault(ChromeFeatureList.RECORD_SUPPRESSION_METRICS, true); + private static final MutableFlagWithSafeDefault sDelayTransitionsForAnimation = + new MutableFlagWithSafeDefault(ChromeFeatureList.DELAY_TRANSITIONS_FOR_ANIMATION, true); /** Private constructor to avoid instantiation. */ private ToolbarFeatures() {} @@ -43,6 +45,16 @@ } /** + * Returns whether the layout system will delay transitions between start/done hiding/showing + * for Android view animations or not. When this is delayed, the toolbar code will try to + * always draw itself from Android views during these transitions, to avoid letting the captured + * bitmap leak through during transitions. With suppression enabled, the captured bitmap is less + * reliable during these transitions. + */ + public static boolean shouldDelayTransitionsForAnimation() { + return sDelayTransitionsForAnimation.isEnabled(); + } + /** * Returns whether to record metrics from suppression experiment. This allows an arm of * suppression to run without the overhead from reporting any extra metrics in Java. Using a * feature instead of a param to utilize Java side caching.
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarLayout.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarLayout.java index 471af534..749048e 100644 --- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarLayout.java +++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarLayout.java
@@ -32,6 +32,7 @@ import org.chromium.base.lifetime.DestroyChecker; import org.chromium.base.lifetime.Destroyable; import org.chromium.chrome.browser.browser_controls.BrowserStateBrowserControlsVisibilityDelegate; +import org.chromium.chrome.browser.layouts.LayoutStateProvider; import org.chromium.chrome.browser.omnibox.LocationBar; import org.chromium.chrome.browser.omnibox.LocationBarCoordinator; import org.chromium.chrome.browser.omnibox.NewTabPageDelegate; @@ -877,4 +878,16 @@ shadow.setVisibility(isHairlineVisible ? VISIBLE : GONE); } } + + /** + * To be called indirectly by + * {@link LayoutStateProvider.LayoutStateObserver#onStartedHiding(int, boolean, boolean)}. + */ + public void onTransitionStart() {} + + /** + * To be called indirectly by + * {@link LayoutStateProvider.LayoutStateObserver#onFinishedShowing(int)}. + */ + public void onTransitionEnd() {} }
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhone.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhone.java index 4b47198..0bd8142 100644 --- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhone.java +++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhone.java
@@ -271,6 +271,9 @@ private boolean mDropdownListScrolled; + // If we're in a layout transition, between startHiding to doneShowing. + private boolean mInLayoutTransition; + // The following are some properties used during animation. We use explicit property classes // to avoid the cost of reflection for each animation setup. @@ -798,6 +801,10 @@ return ChromeColors.getDefaultThemeColor(getContext(), false); } + // During transition we cannot rely on the background to be opaque yet, so keep full + // alpha until the transition is over. + int alpha = mInLayoutTransition ? 255 : Math.round(mUrlExpansionFraction * 255); + // When the NTP fake search box is visible, the background color should be // transparent. When the location bar reaches the top of the screen (i.e. location // bar is fully expanded), the background needs to change back to the default @@ -805,8 +812,7 @@ // between the transition, we set a translucent default toolbar color based on // the expansion progress of the toolbar. return androidx.core.graphics.ColorUtils.setAlphaComponent( - ChromeColors.getDefaultThemeColor(getContext(), false), - Math.round(mUrlExpansionFraction * 255)); + ChromeColors.getDefaultThemeColor(getContext(), false), alpha); case VisualState.NORMAL: return ChromeColors.getDefaultThemeColor(getContext(), false); case VisualState.INCOGNITO: @@ -1404,8 +1410,14 @@ * toolbar. */ private boolean shouldDrawLocationBar() { - return mLocationBarBackground != null - && (mTabSwitcherState == STATIC_TAB || mTextureCaptureMode); + if (ToolbarFeatures.shouldDelayTransitionsForAnimation()) { + // The location bar should have alpha or clip+translation when its not supposed to be + // shown. Needs to be drawn during transitions, such as entering/exiting tab switcher. + return mLocationBarBackground != null; + } else { + return mLocationBarBackground != null + && (mTabSwitcherState == STATIC_TAB || mTextureCaptureMode); + } } private boolean drawLocationBar(Canvas canvas, long drawingTime) { @@ -1413,7 +1425,6 @@ boolean clipped = false; if (shouldDrawLocationBar()) { canvas.save(); - if (shouldDrawLocationBarBackground()) { if (mActiveLocationBarBackground instanceof NtpSearchBoxDrawable) { ((NtpSearchBoxDrawable) mActiveLocationBarBackground) @@ -1806,6 +1817,12 @@ updateViewsForTabSwitcherMode(); } + if (ToolbarFeatures.shouldDelayTransitionsForAnimation()) { + // Since mTabSwitcherState has changed, we need to also check if mVisualState should + // change. + updateVisualsForLocationBarState(); + } + updateButtonsTranslationY(); if (DeviceClassManager.enableAccessibilityLayout(getContext())) { @@ -2743,4 +2760,17 @@ private int calculateOnFocusHeightIncrease() { return (int) (mBackgroundHeightIncreaseWhenFocus * mUrlFocusChangeFraction / 2); } + + @Override + public void onTransitionStart() { + setVisibility(View.VISIBLE); + mInLayoutTransition = true; + updateToolbarBackgroundFromState(mVisualState); + } + + @Override + public void onTransitionEnd() { + mInLayoutTransition = false; + updateToolbarBackgroundFromState(mVisualState); + } }
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/TopToolbarCoordinator.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/TopToolbarCoordinator.java index 467f64e8..b07f98c58 100644 --- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/TopToolbarCoordinator.java +++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/TopToolbarCoordinator.java
@@ -806,4 +806,12 @@ public boolean isBrowsingModeToolbarVisible() { return mToolbarLayout.getVisibility() == View.VISIBLE; } + + public void onTransitionStart() { + mToolbarLayout.onTransitionStart(); + } + + public void onTransitionEnd() { + mToolbarLayout.onTransitionEnd(); + } }
diff --git a/chrome/browser/ui/ash/chrome_browser_main_extra_parts_ash.cc b/chrome/browser/ui/ash/chrome_browser_main_extra_parts_ash.cc index 6950312..407020b 100644 --- a/chrome/browser/ui/ash/chrome_browser_main_extra_parts_ash.cc +++ b/chrome/browser/ui/ash/chrome_browser_main_extra_parts_ash.cc
@@ -29,7 +29,7 @@ #include "chrome/browser/ash/privacy_hub/privacy_hub_util.h" #include "chrome/browser/ash/profiles/profile_helper.h" #include "chrome/browser/ash/sync/sync_error_notifier_factory.h" -#include "chrome/browser/ash/wallpaper_handlers/backdrop_fetcher_delegate.h" +#include "chrome/browser/ash/wallpaper_handlers/wallpaper_fetcher_delegate.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/browser_process_platform_part.h" #include "chrome/browser/chromeos/tablet_mode/tablet_mode_page_behavior.h" @@ -214,7 +214,7 @@ // ash::ChromeUserManagerImpl. wallpaper_controller_client_ = std::make_unique<WallpaperControllerClientImpl>( - std::make_unique<wallpaper_handlers::BackdropFetcherDelegateImpl>()); + std::make_unique<wallpaper_handlers::WallpaperFetcherDelegateImpl>()); wallpaper_controller_client_->Init(); session_controller_client_ = std::make_unique<SessionControllerClientImpl>();
diff --git a/chrome/browser/ui/ash/projector/projector_app_client_impl.cc b/chrome/browser/ui/ash/projector/projector_app_client_impl.cc index 3c5b06b..ec8185c 100644 --- a/chrome/browser/ui/ash/projector/projector_app_client_impl.cc +++ b/chrome/browser/ui/ash/projector/projector_app_client_impl.cc
@@ -9,8 +9,8 @@ #include "ash/constants/ash_features.h" #include "ash/constants/ash_pref_names.h" #include "ash/public/cpp/projector/annotator_tool.h" -#include "ash/webui/projector_app/annotator_page_handler_impl.h" #include "ash/webui/projector_app/public/cpp/projector_app_constants.h" +#include "ash/webui/projector_app/untrusted_annotator_page_handler_impl.h" #include "base/functional/bind.h" #include "chrome/browser/ash/profiles/profile_helper.h" #include "chrome/browser/browser_process.h" @@ -156,12 +156,12 @@ } void ProjectorAppClientImpl::SetAnnotatorPageHandler( - ash::AnnotatorPageHandlerImpl* handler) { + ash::UntrustedAnnotatorPageHandlerImpl* handler) { annotator_handler_ = handler; } void ProjectorAppClientImpl::ResetAnnotatorPageHandler( - ash::AnnotatorPageHandlerImpl* handler) { + ash::UntrustedAnnotatorPageHandlerImpl* handler) { if (annotator_handler_ == handler) { annotator_handler_ = nullptr; }
diff --git a/chrome/browser/ui/ash/projector/projector_app_client_impl.h b/chrome/browser/ui/ash/projector/projector_app_client_impl.h index a25a270..cfba1d4a 100644 --- a/chrome/browser/ui/ash/projector/projector_app_client_impl.h +++ b/chrome/browser/ui/ash/projector/projector_app_client_impl.h
@@ -8,8 +8,8 @@ #include <memory> #include "ash/public/cpp/projector/projector_annotator_controller.h" -#include "ash/webui/projector_app/annotator_page_handler_impl.h" #include "ash/webui/projector_app/projector_app_client.h" +#include "ash/webui/projector_app/untrusted_annotator_page_handler_impl.h" #include "base/observer_list.h" #include "chrome/browser/ui/ash/projector/pending_screencast_manager.h" #include "chrome/browser/ui/ash/projector/screencast_manager.h" @@ -52,9 +52,10 @@ const std::string& video_file_id, const std::string& resource_key, ash::ProjectorAppClient::OnGetVideoCallback callback) const override; - void SetAnnotatorPageHandler(ash::AnnotatorPageHandlerImpl* handler) override; + void SetAnnotatorPageHandler( + ash::UntrustedAnnotatorPageHandlerImpl* handler) override; void ResetAnnotatorPageHandler( - ash::AnnotatorPageHandlerImpl* handler) override; + ash::UntrustedAnnotatorPageHandlerImpl* handler) override; void SetTool(const ash::AnnotatorTool& tool) override; void Clear() override; void NotifyAppUIActive(bool active) override; @@ -62,7 +63,7 @@ const std::vector<base::FilePath>& screencast_paths, bool suppress) override; - ash::AnnotatorPageHandlerImpl* get_annotator_handler_for_test() { + ash::UntrustedAnnotatorPageHandlerImpl* get_annotator_handler_for_test() { return annotator_handler_; } PendingScreencastManager* get_pending_screencast_manager_for_test() { @@ -80,7 +81,7 @@ ash::ScreencastManager screencast_manager_; - ash::AnnotatorPageHandlerImpl* annotator_handler_ = nullptr; + ash::UntrustedAnnotatorPageHandlerImpl* annotator_handler_ = nullptr; }; #endif // CHROME_BROWSER_UI_ASH_PROJECTOR_PROJECTOR_APP_CLIENT_IMPL_H_
diff --git a/chrome/browser/ui/ash/projector/projector_client_impl.cc b/chrome/browser/ui/ash/projector/projector_client_impl.cc index 7bd0e908..57c6184 100644 --- a/chrome/browser/ui/ash/projector/projector_client_impl.cc +++ b/chrome/browser/ui/ash/projector/projector_client_impl.cc
@@ -103,7 +103,7 @@ // static void ProjectorClientImpl::InitForProjectorAnnotator(views::WebView* web_view) { - web_view->LoadInitialURL(GURL(ash::kChromeUITrustedAnnotatorUrl)); + web_view->LoadInitialURL(GURL(ash::kChromeUIUntrustedAnnotatorUrl)); } // Using base::Unretained for callback is safe since the ProjectorClientImpl
diff --git a/chrome/browser/ui/ash/projector/projector_client_impl_browsertest.cc b/chrome/browser/ui/ash/projector/projector_client_impl_browsertest.cc index dcfe2e4..9d90f10 100644 --- a/chrome/browser/ui/ash/projector/projector_client_impl_browsertest.cc +++ b/chrome/browser/ui/ash/projector/projector_client_impl_browsertest.cc
@@ -181,7 +181,6 @@ IN_PROC_BROWSER_TEST_F(ProjectorClientTest, AppUrlsValid) { VerifyUrlValid(kChromeUITrustedProjectorUrl); VerifyUrlValid(kChromeUIUntrustedProjectorUrl); - VerifyUrlValid(kChromeUITrustedAnnotatorUrl); VerifyUrlValid(kChromeUIUntrustedAnnotatorUrl); }
diff --git a/chrome/browser/ui/ash/projector/projector_navigation_throttle_browsertest.cc b/chrome/browser/ui/ash/projector/projector_navigation_throttle_browsertest.cc index 9d2e396c..bb82bc3 100644 --- a/chrome/browser/ui/ash/projector/projector_navigation_throttle_browsertest.cc +++ b/chrome/browser/ui/ash/projector/projector_navigation_throttle_browsertest.cc
@@ -390,21 +390,6 @@ EXPECT_EQ(tab->GetVisibleURL(), untrusted_annotator_url); } -// Verifies that chrome://projector-annotator is not accessible when the app is -// disabled. -IN_PROC_BROWSER_TEST_F(ProjectorNavigationThrottleDisabledTest, - TrustedAnnotatorNavigationInvalidUrl) { - GURL trusted_annotator_url(kChromeUITrustedAnnotatorUrl); - - ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), trusted_annotator_url)); - content::WebContents* tab = - browser()->tab_strip_model()->GetActiveWebContents(); - ASSERT_TRUE(tab); - EXPECT_EQ(tab->GetController().GetVisibleEntry()->GetPageType(), - content::PAGE_TYPE_ERROR); - EXPECT_EQ(tab->GetVisibleURL(), trusted_annotator_url); -} - class ProjectorNavigationThrottleLocaleTest : public ProjectorNavigationThrottleTest, public testing::WithParamInterface<std::string> {
diff --git a/chrome/browser/ui/ash/wallpaper_controller_client_impl.cc b/chrome/browser/ui/ash/wallpaper_controller_client_impl.cc index 282a9b8..3d605f57 100644 --- a/chrome/browser/ui/ash/wallpaper_controller_client_impl.cc +++ b/chrome/browser/ui/ash/wallpaper_controller_client_impl.cc
@@ -43,7 +43,7 @@ #include "chrome/browser/ash/login/wizard_controller.h" #include "chrome/browser/ash/policy/core/device_local_account.h" #include "chrome/browser/ash/wallpaper/wallpaper_drivefs_delegate_impl.h" -#include "chrome/browser/ash/wallpaper_handlers/backdrop_fetcher_delegate.h" +#include "chrome/browser/ash/wallpaper_handlers/wallpaper_fetcher_delegate.h" #include "chrome/browser/ash/wallpaper_handlers/wallpaper_handlers.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/profiles/profile_manager.h" @@ -180,9 +180,9 @@ } // namespace WallpaperControllerClientImpl::WallpaperControllerClientImpl( - std::unique_ptr<wallpaper_handlers::BackdropFetcherDelegate> - backdrop_fetcher_delegate) - : backdrop_fetcher_delegate_(std::move(backdrop_fetcher_delegate)) { + std::unique_ptr<wallpaper_handlers::WallpaperFetcherDelegate> + wallpaper_fetcher_delegate) + : wallpaper_fetcher_delegate_(std::move(wallpaper_fetcher_delegate)) { local_state_ = g_browser_process->local_state(); show_user_names_on_signin_subscription_ = ash::CrosSettings::Get()->AddSettingsObserver( @@ -556,7 +556,8 @@ const std::string& collection_id, FetchImagesForCollectionCallback callback) { auto images_info_fetcher = - backdrop_fetcher_delegate_->CreateBackdropImageInfoFetcher(collection_id); + wallpaper_fetcher_delegate_->CreateBackdropImageInfoFetcher( + collection_id); auto* images_info_fetcher_ptr = images_info_fetcher.get(); images_info_fetcher_ptr->Start( base::BindOnce(&WallpaperControllerClientImpl::OnFetchImagesForCollection,
diff --git a/chrome/browser/ui/ash/wallpaper_controller_client_impl.h b/chrome/browser/ui/ash/wallpaper_controller_client_impl.h index 584fc4f6..99a163b 100644 --- a/chrome/browser/ui/ash/wallpaper_controller_client_impl.h +++ b/chrome/browser/ui/ash/wallpaper_controller_client_impl.h
@@ -29,7 +29,7 @@ } namespace wallpaper_handlers { -class BackdropFetcherDelegate; +class WallpaperFetcherDelegate; } // namespace wallpaper_handlers // Handles chrome-side wallpaper control alongside the ash-side controller. @@ -39,8 +39,8 @@ public session_manager::SessionManagerObserver { public: explicit WallpaperControllerClientImpl( - std::unique_ptr<wallpaper_handlers::BackdropFetcherDelegate> - backdrop_fetcher_delegate); + std::unique_ptr<wallpaper_handlers::WallpaperFetcherDelegate> + wallpaper_fetcher_delegate); WallpaperControllerClientImpl(const WallpaperControllerClientImpl&) = delete; WallpaperControllerClientImpl& operator=( @@ -213,8 +213,8 @@ std::unique_ptr<wallpaper_handlers::GooglePhotosPhotosFetcher>> google_photos_photos_fetchers_; - const std::unique_ptr<wallpaper_handlers::BackdropFetcherDelegate> - backdrop_fetcher_delegate_; + const std::unique_ptr<wallpaper_handlers::WallpaperFetcherDelegate> + wallpaper_fetcher_delegate_; base::ScopedMultiSourceObservation<file_manager::VolumeManager, file_manager::VolumeManagerObserver>
diff --git a/chrome/browser/ui/ash/wallpaper_controller_client_impl_unittest.cc b/chrome/browser/ui/ash/wallpaper_controller_client_impl_unittest.cc index 00b7d4c..b05e0b9 100644 --- a/chrome/browser/ui/ash/wallpaper_controller_client_impl_unittest.cc +++ b/chrome/browser/ui/ash/wallpaper_controller_client_impl_unittest.cc
@@ -10,7 +10,7 @@ #include "base/test/bind.h" #include "base/test/task_environment.h" #include "chrome/browser/ash/settings/scoped_cros_settings_test_helper.h" -#include "chrome/browser/ash/wallpaper_handlers/test_backdrop_fetcher_delegate.h" +#include "chrome/browser/ash/wallpaper_handlers/test_wallpaper_fetcher_delegate.h" #include "chrome/browser/ui/ash/test_wallpaper_controller.h" #include "chrome/test/base/scoped_testing_local_state.h" #include "chrome/test/base/testing_browser_process.h" @@ -61,7 +61,7 @@ std::unique_ptr<user_manager::ScopedUserManager> user_manager_; TestWallpaperController controller_; WallpaperControllerClientImpl client_{ - std::make_unique<wallpaper_handlers::TestBackdropFetcherDelegate>()}; + std::make_unique<wallpaper_handlers::TestWallpaperFetcherDelegate>()}; }; TEST_F(WallpaperControllerClientImplTest, Construction) {
diff --git a/chrome/browser/ui/omnibox/omnibox_pedal_implementations.cc b/chrome/browser/ui/omnibox/omnibox_pedal_implementations.cc index 04946bb..1793c98 100644 --- a/chrome/browser/ui/omnibox/omnibox_pedal_implementations.cc +++ b/chrome/browser/ui/omnibox/omnibox_pedal_implementations.cc
@@ -88,7 +88,8 @@ // This method override enables this Pedal to spoof its ID for metrics // reporting, making it possible to distinguish incognito usage. OmniboxPedalId GetMetricsId() const override { - return incognito_ ? OmniboxPedalId::INCOGNITO_CLEAR_BROWSING_DATA : id(); + return incognito_ ? OmniboxPedalId::INCOGNITO_CLEAR_BROWSING_DATA + : PedalId(); } protected: @@ -2035,7 +2036,9 @@ std::unordered_map<OmniboxPedalId, scoped_refptr<OmniboxPedal>> pedals; const auto add = [&](OmniboxPedal* pedal) { const bool inserted = - pedals.insert(std::make_pair(pedal->id(), base::WrapRefCounted(pedal))) + pedals + .insert( + std::make_pair(pedal->PedalId(), base::WrapRefCounted(pedal))) .second; DCHECK(inserted); };
diff --git a/chrome/browser/ui/omnibox/omnibox_pedal_implementations_unittest.cc b/chrome/browser/ui/omnibox/omnibox_pedal_implementations_unittest.cc index 399b59d..2f16eb6915 100644 --- a/chrome/browser/ui/omnibox/omnibox_pedal_implementations_unittest.cc +++ b/chrome/browser/ui/omnibox/omnibox_pedal_implementations_unittest.cc
@@ -17948,13 +17948,13 @@ EXPECT_NE(iter, pedals.end()) << "Pedal not found for: " << expression; EXPECT_EQ(iter->second.get(), canonical_pedal) << "Found wrong Pedal for: " << expression; - const int found_id = static_cast<int>(iter->second->id()); + const int found_id = static_cast<int>(iter->second->PedalId()); std::advance(iter, 1); iter = std::find_if(iter, pedals.end(), is_match); EXPECT_EQ(iter, pedals.end()) << "Found more than one Pedal match for: " << expression << " -- IDs: first " << found_id << " then " - << static_cast<int>(iter->second->id()); + << static_cast<int>(iter->second->PedalId()); } } } @@ -17968,7 +17968,7 @@ TEST_F(OmniboxPedalImplementationsTest, PedalClearBrowsingDataExecutes) { const OmniboxPedal* pedal = provider()->FindPedalMatch(u"clear browser data"); - EXPECT_EQ(OmniboxPedalId::CLEAR_BROWSING_DATA, pedal->id()); + EXPECT_EQ(OmniboxPedalId::CLEAR_BROWSING_DATA, pedal->PedalId()); EXPECT_EQ(GURL("chrome://settings/clearBrowserData"), ExecuteContextAndReturnResult(pedal)); @@ -17981,7 +17981,7 @@ // Note, there is only one Pedal for clearing browser data but it behaves // differently depending on incognito status. The incognito behavior does // not navigate but the non-incognito behavior does navigate. - EXPECT_EQ(OmniboxPedalId::CLEAR_BROWSING_DATA, pedal->id()); + EXPECT_EQ(OmniboxPedalId::CLEAR_BROWSING_DATA, pedal->PedalId()); EXPECT_EQ(GURL(""), ExecuteContextAndReturnResult(pedal)); }
diff --git a/chrome/browser/ui/ui_features.cc b/chrome/browser/ui/ui_features.cc index 6673f990..75c0c67 100644 --- a/chrome/browser/ui/ui_features.cc +++ b/chrome/browser/ui/ui_features.cc
@@ -72,10 +72,10 @@ "EvDetailsInPageInfo", base::FEATURE_ENABLED_BY_DEFAULT); +#if !defined(ANDROID) && BUILDFLAG(GOOGLE_CHROME_BRANDING) // Enables showing the "Get the most out of Chrome" section in settings. -#if !defined(ANDROID) -BASE_FEATURE(kGetTheMostOutOfProgram, - "GetTheMostOutOfProgram", +BASE_FEATURE(kGetTheMostOutOfChrome, + "GetTheMostOutOfChrome", base::FEATURE_DISABLED_BY_DEFAULT); #endif
diff --git a/chrome/browser/ui/ui_features.h b/chrome/browser/ui/ui_features.h index 19b2a553..3300b89 100644 --- a/chrome/browser/ui/ui_features.h +++ b/chrome/browser/ui/ui_features.h
@@ -49,8 +49,8 @@ BASE_DECLARE_FEATURE(kEvDetailsInPageInfo); -#if !defined(ANDROID) -BASE_DECLARE_FEATURE(kGetTheMostOutOfProgram); +#if !defined(ANDROID) && BUILDFLAG(GOOGLE_CHROME_BRANDING) +BASE_DECLARE_FEATURE(kGetTheMostOutOfChrome); #endif #if BUILDFLAG(ENABLE_EXTENSIONS)
diff --git a/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_bar.cc b/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_bar.cc index d9d28bea..1f5135e 100644 --- a/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_bar.cc +++ b/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_bar.cc
@@ -570,7 +570,7 @@ } auto bubble_delegate = std::make_unique<views::BubbleDialogDelegate>( - this, views::BubbleBorder::TOP_RIGHT); + overflow_button_, views::BubbleBorder::TOP_LEFT); bubble_delegate_ = bubble_delegate.get(); bubble_delegate_->SetShowTitle(false); @@ -578,9 +578,12 @@ bubble_delegate_->SetButtons(ui::DIALOG_BUTTON_NONE); bubble_delegate_->set_margins(gfx::Insets()); bubble_delegate_->set_fixed_width(200); + bubble_delegate_->set_adjust_if_offscreen(true); + bubble_delegate_->set_close_on_deactivate(true); overflow_menu_ = bubble_delegate_->SetContentsView(std::make_unique<OverflowMenu>(*this)); + const gfx::Insets insets = gfx::Insets::TLBR(16, 16, 16, 48); auto box = std::make_unique<views::BoxLayout>( views::BoxLayout::Orientation::kVertical, insets,
diff --git a/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_button.cc b/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_button.cc index 68bad348..a67903c 100644 --- a/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_button.cc +++ b/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_button.cc
@@ -84,8 +84,12 @@ &SavedTabGroupButton::CreateDialogModelForContextMenu, base::Unretained(this)), views::MenuRunner::CONTEXT_MENU | views::MenuRunner::IS_NESTED) { + SetAccessibilityProperties( + ax::mojom::Role::kPopUpButton, group.title(), + /*description*/ absl::nullopt, + l10n_util::GetStringUTF16( + IDS_ACCNAME_SAVED_TAB_GROUP_BUTTON_ROLE_DESCRIPTION)); SetText(group.title()); - SetAccessibleName(group.title()); SetTooltipText(group.title()); SetID(VIEW_ID_BOOKMARK_BAR_ELEMENT); SetProperty(views::kElementIdentifierKey, kSavedTabGroupButtonElementId); @@ -157,17 +161,15 @@ } void SavedTabGroupButton::GetAccessibleNodeData(ui::AXNodeData* node_data) { + views::MenuButton::GetAccessibleNodeData(node_data); + + // TODO(crbug.com/1411342): Under what circumstances would there be no + // name? Please read the bug description and update accordingly. // If the button would have no name, avoid crashing by setting the name // explicitly empty. if (GetAccessibleName().empty()) { node_data->SetNameExplicitlyEmpty(); } - - views::MenuButton::GetAccessibleNodeData(node_data); - node_data->AddStringAttribute( - ax::mojom::StringAttribute::kRoleDescription, - l10n_util::GetStringUTF8( - IDS_ACCNAME_SAVED_TAB_GROUP_BUTTON_ROLE_DESCRIPTION)); } void SavedTabGroupButton::OnPaintBackground(gfx::Canvas* canvas) {
diff --git a/chrome/browser/ui/views/extensions/extensions_menu_item_unittest.cc b/chrome/browser/ui/views/extensions/extensions_menu_item_unittest.cc index 33ca236b..54753d0fe 100644 --- a/chrome/browser/ui/views/extensions/extensions_menu_item_unittest.cc +++ b/chrome/browser/ui/views/extensions/extensions_menu_item_unittest.cc
@@ -70,8 +70,7 @@ controller_->SetActionName(initial_extension_name_); controller_->SetTooltip(initial_tooltip_); auto menu_item = std::make_unique<ExtensionMenuItemView>( - browser(), std::move(controller), true, - /*is_site_permissions_button_visible=*/false); + browser(), std::move(controller), true); primary_button_ = menu_item->primary_action_button_for_testing(); pin_button_ = menu_item->pin_button_for_testing(); context_menu_button_ = menu_item->context_menu_button_for_testing();
diff --git a/chrome/browser/ui/views/extensions/extensions_menu_item_view.cc b/chrome/browser/ui/views/extensions/extensions_menu_item_view.cc index 5a13462..99c64538 100644 --- a/chrome/browser/ui/views/extensions/extensions_menu_item_view.cc +++ b/chrome/browser/ui/views/extensions/extensions_menu_item_view.cc
@@ -65,91 +65,48 @@ } } // namespace - ExtensionMenuItemView::ExtensionMenuItemView( Browser* browser, std::unique_ptr<ToolbarActionViewController> controller, - bool allow_pinning, - bool is_site_permissions_button_visible, - views::Button::PressedCallback site_permissions_button_callback) + bool allow_pinning) : browser_(browser), controller_(std::move(controller)), model_(ToolbarActionsModel::Get(browser_->profile())) { + CHECK(!base::FeatureList::IsEnabled( + extensions_features::kExtensionsMenuAccessControl)); + views::FlexSpecification stretch_specification = views::FlexSpecification(views::MinimumFlexSizeRule::kScaleToZero, views::MaximumFlexSizeRule::kUnbounded); - - views::View* main_row; auto builder = views::Builder<ExtensionMenuItemView>(this) // Set so the extension button receives enter/exit on children to // retain hover status when hovering child views. - .SetNotifyEnterExitOnChild(true); - - if (base::FeatureList::IsEnabled( - extensions_features::kExtensionsMenuAccessControl)) { - DCHECK(site_permissions_button_callback); - - ChromeLayoutProvider* const provider = ChromeLayoutProvider::Get(); - const int icon_size = provider->GetDistanceMetric( - DISTANCE_EXTENSIONS_MENU_EXTENSION_ICON_SIZE); - const int horizontal_inset = - provider->GetDistanceMetric(DISTANCE_EXTENSIONS_MENU_BUTTON_MARGIN); - const int icon_label_spacing = - provider->GetDistanceMetric(views::DISTANCE_RELATED_LABEL_HORIZONTAL); - - builder.SetOrientation(views::LayoutOrientation::kVertical) - .SetCrossAxisAlignment(views::LayoutAlignment::kStretch) - .SetProperty(views::kFlexBehaviorKey, stretch_specification) - .AddChildren( - // Main row. - views::Builder<views::FlexLayoutView>() - .CopyAddressTo(&main_row) - .SetOrientation(views::LayoutOrientation::kHorizontal) - .SetIgnoreDefaultMainAxisMargins(true), - // Secondary row. - views::Builder<views::FlexLayoutView>().AddChildren( - // Site permissions button. - // TODO(crbug.com/998298): Compute title based on the extension - // site access. - // TODO(crbug.com/998298): Add tooltip after UX provides it. - views::Builder<HoverButton>( - std::make_unique<HoverButton>( - site_permissions_button_callback, - /*icon_view=*/nullptr, u"site access", std::u16string(), - std::make_unique<views::ImageView>( - ui::ImageModel::FromVectorIcon( - vector_icons::kSubmenuArrowIcon, - ui::kColorIcon)))) - .CopyAddressTo(&site_permissions_button_) - .SetVisible(is_site_permissions_button_visible) - // Margin to align the main and secondary row text. Icon - // size and horizontal insets should be the values used by - // the extensions menu button. - .SetProperty( - views::kMarginsKey, - gfx::Insets::VH(0, icon_size + horizontal_inset)) - // Border should be the same as the icon label - // spacing used by the extensions menu button. - .SetBorder(views::CreateEmptyBorder( - gfx::Insets::VH(0, icon_label_spacing))))); - } else { - builder.CopyAddressTo(&main_row) - .SetOrientation(views::LayoutOrientation::kHorizontal) - .SetIgnoreDefaultMainAxisMargins(true); - } - - std::move(builder).BuildChildren(); - - main_row->AddChildView( - views::Builder<ExtensionsMenuButton>( - std::make_unique<ExtensionsMenuButton>(browser_, controller_.get())) - .CopyAddressTo(&primary_action_button_) - .SetProperty(views::kFlexBehaviorKey, stretch_specification) - .Build()); + .SetNotifyEnterExitOnChild(true) + .SetOrientation(views::LayoutOrientation::kHorizontal) + .SetIgnoreDefaultMainAxisMargins(true) + .AddChildren( + views::Builder<ExtensionsMenuButton>( + std::make_unique<ExtensionsMenuButton>(browser_, + controller_.get())) + .CopyAddressTo(&primary_action_button_) + .SetProperty(views::kFlexBehaviorKey, stretch_specification), + views::Builder<HoverButton>( + std::make_unique<HoverButton>( + views::Button::PressedCallback(), std::u16string())) + .CopyAddressTo(&context_menu_button_) + .SetID(EXTENSION_CONTEXT_MENU) + .SetBorder(views::CreateEmptyBorder( + ChromeLayoutProvider::Get()->GetDistanceMetric( + DISTANCE_EXTENSIONS_MENU_BUTTON_MARGIN))) + .SetTooltipText(l10n_util::GetStringUTF16( + IDS_EXTENSIONS_MENU_CONTEXT_MENU_TOOLTIP))); if (allow_pinning) { - main_row->AddChildView( + // Pin button should be in between `primary_action_button_` and + // `context_menu_button_`. + int index = 1; + builder.AddChildAt( views::Builder<HoverButton>( std::make_unique<HoverButton>( base::BindRepeating(&ExtensionMenuItemView::OnPinButtonPressed, @@ -159,35 +116,97 @@ .SetID(EXTENSION_PINNING) .SetBorder(views::CreateEmptyBorder( ChromeLayoutProvider::Get()->GetDistanceMetric( - DISTANCE_EXTENSIONS_MENU_BUTTON_MARGIN))) - .Build()); + DISTANCE_EXTENSIONS_MENU_BUTTON_MARGIN))), + index); } - main_row->AddChildView( - views::Builder<HoverButton>( - std::make_unique<HoverButton>(views::Button::PressedCallback(), - std::u16string())) - .CopyAddressTo(&context_menu_button_) - .SetID(EXTENSION_CONTEXT_MENU) - .SetBorder(views::CreateEmptyBorder( - ChromeLayoutProvider::Get()->GetDistanceMetric( - DISTANCE_EXTENSIONS_MENU_BUTTON_MARGIN))) - .SetTooltipText(l10n_util::GetStringUTF16( - IDS_EXTENSIONS_MENU_CONTEXT_MENU_TOOLTIP)) - .Build()); + std::move(builder).BuildChildren(); - // Add a controller to the context menu - context_menu_controller_ = std::make_unique<ExtensionContextMenuController>( - controller_.get(), - extensions::ExtensionContextMenuModel::ContextMenuSource::kMenuItem); + SetupContextMenuButton(); +} - context_menu_button_->SetButtonController( - std::make_unique<views::MenuButtonController>( - context_menu_button_.get(), - base::BindRepeating(&ExtensionMenuItemView::OnContextMenuPressed, - base::Unretained(this)), - std::make_unique<views::Button::DefaultButtonControllerDelegate>( - context_menu_button_.get()))); +ExtensionMenuItemView::ExtensionMenuItemView( + Browser* browser, + std::unique_ptr<ToolbarActionViewController> controller, + SitePermissionsButtonState site_permissions_button_state, + views::Button::PressedCallback site_permissions_button_callback) + : browser_(browser), + controller_(std::move(controller)), + model_(ToolbarActionsModel::Get(browser_->profile())) { + CHECK(base::FeatureList::IsEnabled( + extensions_features::kExtensionsMenuAccessControl)); + + views::FlexSpecification stretch_specification = + views::FlexSpecification(views::MinimumFlexSizeRule::kScaleToZero, + views::MaximumFlexSizeRule::kUnbounded); + ChromeLayoutProvider* const provider = ChromeLayoutProvider::Get(); + const int icon_size = + provider->GetDistanceMetric(DISTANCE_EXTENSIONS_MENU_EXTENSION_ICON_SIZE); + const int horizontal_inset = + provider->GetDistanceMetric(DISTANCE_EXTENSIONS_MENU_BUTTON_MARGIN); + const int icon_label_spacing = + provider->GetDistanceMetric(views::DISTANCE_RELATED_LABEL_HORIZONTAL); + + views::Builder<ExtensionMenuItemView>(this) + // Set so the extension button receives enter/exit on children to + // retain hover status when hovering child views. + .SetNotifyEnterExitOnChild(true) + .SetOrientation(views::LayoutOrientation::kVertical) + .SetCrossAxisAlignment(views::LayoutAlignment::kStretch) + .SetProperty(views::kFlexBehaviorKey, stretch_specification) + .AddChildren( + // Main row. + views::Builder<views::FlexLayoutView>() + .SetOrientation(views::LayoutOrientation::kHorizontal) + .SetIgnoreDefaultMainAxisMargins(true) + .AddChildren( + views::Builder<ExtensionsMenuButton>( + std::make_unique<ExtensionsMenuButton>(browser_, + controller_.get())) + .CopyAddressTo(&primary_action_button_) + .SetProperty(views::kFlexBehaviorKey, + stretch_specification), + views::Builder<HoverButton>( + std::make_unique<HoverButton>( + views::Button::PressedCallback(), std::u16string())) + .CopyAddressTo(&context_menu_button_) + .SetID(EXTENSION_CONTEXT_MENU) + .SetBorder(views::CreateEmptyBorder( + ChromeLayoutProvider::Get()->GetDistanceMetric( + DISTANCE_EXTENSIONS_MENU_BUTTON_MARGIN))) + .SetTooltipText(l10n_util::GetStringUTF16( + IDS_EXTENSIONS_MENU_CONTEXT_MENU_TOOLTIP))), + // Secondary row. + views::Builder<views::FlexLayoutView>().AddChildren( + // Site permissions button. + // TODO(crbug.com/998298): Compute title based on the + // extension site access. + // TODO(crbug.com/998298): Add tooltip after UX provides it. + views::Builder<HoverButton>( + std::make_unique<HoverButton>( + site_permissions_button_callback, + /*icon_view=*/nullptr, u"site access", std::u16string(), + std::make_unique<views::ImageView>( + ui::ImageModel::FromVectorIcon( + vector_icons::kSubmenuArrowIcon, + ui::kColorIcon)))) + .CopyAddressTo(&site_permissions_button_) + .SetVisible(site_permissions_button_state != + SitePermissionsButtonState::kHidden) + .SetEnabled(site_permissions_button_state == + SitePermissionsButtonState::kEnabled) + // Margin to align the main and secondary row text. Icon + // size and horizontal insets should be the values used by + // the extensions menu button. + .SetProperty(views::kMarginsKey, + gfx::Insets::VH(0, icon_size + horizontal_inset)) + // Border should be the same as the icon label + // spacing used by the extensions menu button. + .SetBorder(views::CreateEmptyBorder( + gfx::Insets::VH(0, icon_label_spacing))))) + .BuildChildren(); + + SetupContextMenuButton(); } ExtensionMenuItemView::~ExtensionMenuItemView() = default; @@ -207,9 +226,15 @@ UpdatePinButton(); } -void ExtensionMenuItemView::Update(bool is_site_permissions_button_visible) { +void ExtensionMenuItemView::Update( + SitePermissionsButtonState site_permissions_button_state) { if (site_permissions_button_) { - site_permissions_button_->SetVisible(is_site_permissions_button_visible); + site_permissions_button_->SetVisible(site_permissions_button_state != + SitePermissionsButtonState::kHidden); + site_permissions_button_->SetEnabled(site_permissions_button_state == + SitePermissionsButtonState::kEnabled); + // TODO(crbug.com/1390952): Display the arrow icon only when site + // permissions button is enabled. } view_controller()->UpdateState(); @@ -247,6 +272,21 @@ icon_color, disabled_icon_color); } +void ExtensionMenuItemView::SetupContextMenuButton() { + // Add a controller to the context menu + context_menu_controller_ = std::make_unique<ExtensionContextMenuController>( + controller_.get(), + extensions::ExtensionContextMenuModel::ContextMenuSource::kMenuItem); + + context_menu_button_->SetButtonController( + std::make_unique<views::MenuButtonController>( + context_menu_button_.get(), + base::BindRepeating(&ExtensionMenuItemView::OnContextMenuPressed, + base::Unretained(this)), + std::make_unique<views::Button::DefaultButtonControllerDelegate>( + context_menu_button_.get()))); +} + bool ExtensionMenuItemView::IsPinned() const { // |model_| can be null in unit tests. return model_ && model_->IsActionPinned(controller_->GetId());
diff --git a/chrome/browser/ui/views/extensions/extensions_menu_item_view.h b/chrome/browser/ui/views/extensions/extensions_menu_item_view.h index 36a5afdd..a609c34 100644 --- a/chrome/browser/ui/views/extensions/extensions_menu_item_view.h +++ b/chrome/browser/ui/views/extensions/extensions_menu_item_view.h
@@ -28,11 +28,24 @@ public: METADATA_HEADER(ExtensionMenuItemView); + enum class SitePermissionsButtonState { + // Button is not visible. + kHidden, + // Button is visible, but disabled. + kDisabled, + // Button is visible and enabled. + kEnabled, + }; + + ExtensionMenuItemView(Browser* browser, + std::unique_ptr<ToolbarActionViewController> controller, + bool allow_pinning); + + // Constructor for the kExtensionsMenuAccessControl feature. ExtensionMenuItemView( Browser* browser, std::unique_ptr<ToolbarActionViewController> controller, - bool allow_pinning, - bool is_site_permissions_button_visible, + SitePermissionsButtonState site_permissions_button_state, views::Button::PressedCallback site_permissions_button_callback = base::RepeatingClosure(base::NullCallback())); ExtensionMenuItemView(const ExtensionMenuItemView&) = delete; @@ -43,7 +56,7 @@ void OnThemeChanged() override; // Updates the controller and child views to be on sync with the parent views. - void Update(bool is_site_permissions_button_visible); + void Update(SitePermissionsButtonState site_permissions_button_state); // Updates the pin button. void UpdatePinButton(); @@ -66,6 +79,10 @@ } private: + // Sets ups the context menu button controllers. Must be called by the + // constructor. + void SetupContextMenuButton(); + // Returns whether the action corresponding to this view is pinned to the // toolbar. bool IsPinned() const;
diff --git a/chrome/browser/ui/views/extensions/extensions_menu_main_page_view.cc b/chrome/browser/ui/views/extensions/extensions_menu_main_page_view.cc index 1a6c40f..9d19bff 100644 --- a/chrome/browser/ui/views/extensions/extensions_menu_main_page_view.cc +++ b/chrome/browser/ui/views/extensions/extensions_menu_main_page_view.cc
@@ -224,12 +224,11 @@ void ExtensionsMenuMainPageView::CreateAndInsertMenuItem( std::unique_ptr<ExtensionActionViewController> action_controller, extensions::ExtensionId extension_id, - bool allow_pinning, - bool is_site_permissions_button_visible, + ExtensionMenuItemView::SitePermissionsButtonState + site_permissions_button_state, int index) { auto item = std::make_unique<ExtensionMenuItemView>( - browser_, std::move(action_controller), allow_pinning, - is_site_permissions_button_visible, + browser_, std::move(action_controller), site_permissions_button_state, base::BindRepeating( &ExtensionsMenuNavigationHandler::OpenSitePermissionsPage, base::Unretained(navigation_handler_), extension_id));
diff --git a/chrome/browser/ui/views/extensions/extensions_menu_main_page_view.h b/chrome/browser/ui/views/extensions/extensions_menu_main_page_view.h index 135307c..b7bced8 100644 --- a/chrome/browser/ui/views/extensions/extensions_menu_main_page_view.h +++ b/chrome/browser/ui/views/extensions/extensions_menu_main_page_view.h
@@ -7,6 +7,7 @@ #include "base/memory/raw_ptr_exclusion.h" #include "chrome/browser/ui/toolbar/toolbar_actions_model.h" +#include "chrome/browser/ui/views/extensions/extensions_menu_item_view.h" #include "ui/views/view.h" #include "ui/base/metadata/metadata_header_macros.h" @@ -44,8 +45,8 @@ void CreateAndInsertMenuItem( std::unique_ptr<ExtensionActionViewController> action_controller, extensions::ExtensionId extension_id, - bool allow_pinning, - bool is_site_permissions_button_visible, + ExtensionMenuItemView::SitePermissionsButtonState + site_permissions_button_state, int index); // Removes the menu item corresponding to `action_id`.
diff --git a/chrome/browser/ui/views/extensions/extensions_menu_main_page_view_unittest.cc b/chrome/browser/ui/views/extensions/extensions_menu_main_page_view_unittest.cc index 1c594531..de48d8a 100644 --- a/chrome/browser/ui/views/extensions/extensions_menu_main_page_view_unittest.cc +++ b/chrome/browser/ui/views/extensions/extensions_menu_main_page_view_unittest.cc
@@ -29,29 +29,6 @@ using PermissionsManager = extensions::PermissionsManager; -// A scoper that manages a Browser instance created by BrowserWithTestWindowTest -// beyond the default instance it creates in SetUp. -class AdditionalBrowser { - public: - explicit AdditionalBrowser(std::unique_ptr<Browser> browser) - : browser_(std::move(browser)), - browser_view_(BrowserView::GetBrowserViewForBrowser(browser_.get())) {} - - ~AdditionalBrowser() { - // Tear down `browser_`, similar to TestWithBrowserView::TearDown. - browser_.release(); - browser_view_->GetWidget()->CloseNow(); - } - - ExtensionsToolbarContainer* extensions_container() { - return browser_view_->toolbar()->extensions_container(); - } - - private: - std::unique_ptr<Browser> browser_; - raw_ptr<BrowserView> browser_view_; -}; - // Returns the extension names from the given `menu_items`. std::vector<std::string> GetNamesFromMenuItems( std::vector<ExtensionMenuItemView*> menu_items) { @@ -86,7 +63,6 @@ // nudge to re-layout the views. void LayoutMenuIfNecessary(); - void ClickPinButton(ExtensionMenuItemView* menu_item); void ClickSitePermissionsButton(ExtensionMenuItemView* menu_item); content::WebContentsTester* web_contents_tester() { @@ -127,12 +103,6 @@ menu_coordinator()->GetExtensionsMenuWidget()->LayoutRootViewIfNecessary(); } -void ExtensionsMenuMainPageViewUnitTest::ClickPinButton( - ExtensionMenuItemView* menu_item) { - ClickButton(menu_item->pin_button_for_testing()); - WaitForAnimation(); -} - void ExtensionsMenuMainPageViewUnitTest::ClickSitePermissionsButton( ExtensionMenuItemView* menu_item) { ClickButton(menu_item->site_permissions_button_for_testing()); @@ -188,144 +158,141 @@ EXPECT_EQ(GetNamesFromMenuItems(items), expected_items); } -TEST_F(ExtensionsMenuMainPageViewUnitTest, PinnedExtensionAppearsInToolbar) { - constexpr char kName[] = "Extension"; - const std::string& extension_id = InstallExtension(kName)->id(); - - ShowMenu(); - - ExtensionMenuItemView* menu_item = GetOnlyMenuItem(); - ASSERT_TRUE(menu_item); - EXPECT_FALSE(extensions_container()->IsActionVisibleOnToolbar(extension_id)); - EXPECT_THAT(GetPinnedExtensionNames(), testing::IsEmpty()); - - // Pin. - ClickPinButton(menu_item); - EXPECT_TRUE(extensions_container()->IsActionVisibleOnToolbar(extension_id)); - EXPECT_EQ(GetPinnedExtensionNames(), std::vector<std::string>{kName}); - - // Unpin. - ClickPinButton(menu_item); - EXPECT_FALSE(extensions_container()->IsActionVisibleOnToolbar(extension_id)); - EXPECT_THAT(GetPinnedExtensionNames(), testing::IsEmpty()); -} - +// Verifies that the permissions button for all extension menu items is always +// visible when user can customize site access by extension. However, enterprise +// extensions and extensions that don't request host permissions should have the +// button disabled as user cannot change their site access. TEST_F(ExtensionsMenuMainPageViewUnitTest, - NewPinnedExtensionAppearsToTheRightOfPinnedExtensions) { - constexpr char kExtensionA[] = "A Extension"; - InstallExtension(kExtensionA); - constexpr char kExtensionB[] = "B Extension"; - InstallExtension(kExtensionB); - constexpr char kExtensionC[] = "C Extension"; - InstallExtension(kExtensionC); - - ShowMenu(); - - std::vector<ExtensionMenuItemView*> items = menu_items(); - - // Verify the order of the extensions is A,B,C. - { - EXPECT_EQ(items.size(), 3u); - std::vector<std::string> expected_items{kExtensionA, kExtensionB, - kExtensionC}; - EXPECT_EQ(GetNamesFromMenuItems(items), expected_items); - } - - // Pinning an extension should add it to the toolbar. - { - ClickPinButton(items.at(0)); - std::vector<std::string> expected_names{kExtensionA}; - EXPECT_EQ(GetPinnedExtensionNames(), expected_names); - } - - // Pinning a second extension should add it to the right of the current pinned - // extensions. - { - ClickPinButton(items.at(1)); - std::vector<std::string> expected_names{kExtensionA, kExtensionB}; - EXPECT_EQ(GetPinnedExtensionNames(), expected_names); - } - - // Pinning a third extension should add it to the right of the current pinned - // extensions. - { - ClickPinButton(items.at(2)); - std::vector<std::string> expected_names{kExtensionA, kExtensionB, - kExtensionC}; - EXPECT_EQ(GetPinnedExtensionNames(), expected_names); - } - - // Unpinning the middle extension should remove it from the toolbar without - // affecting the order of the other pinned extensions. - { - ClickPinButton(items.at(1)); - std::vector<std::string> expected_names{kExtensionA, kExtensionC}; - EXPECT_EQ(GetPinnedExtensionNames(), expected_names); - } - - // Pinning an extension should add it to the right of the current pinned - // extensions, even if it was pinned and unpinned previously. - { - ClickPinButton(items.at(1)); - std::vector<std::string> expected_names{kExtensionA, kExtensionC, - kExtensionB}; - EXPECT_EQ(GetPinnedExtensionNames(), expected_names); - } -} - -TEST_F(ExtensionsMenuMainPageViewUnitTest, - PinnedExtensionAppearsInAnotherWindow) { - const std::string& extension_id = InstallExtension("Extension")->id(); - - ShowMenu(); - - AdditionalBrowser browser2( - CreateBrowser(browser()->profile(), browser()->type(), - /* hosted_app */ false, /* browser_window */ nullptr)); - - ExtensionMenuItemView* menu_item = GetOnlyMenuItem(); - ASSERT_TRUE(menu_item); - ClickPinButton(menu_item); - - // Window that was already open gets the pinned extension. - EXPECT_TRUE( - browser2.extensions_container()->IsActionVisibleOnToolbar(extension_id)); - - AdditionalBrowser browser3( - CreateBrowser(browser()->profile(), browser()->type(), - /* hosted_app */ false, /* browser_window */ nullptr)); - - // Brand-new window also gets the pinned extension. - EXPECT_TRUE( - browser3.extensions_container()->IsActionVisibleOnToolbar(extension_id)); -} - -// Verifies the extension site permissions button opens the site permissions -// page corresponding to the extension. -TEST_F(ExtensionsMenuMainPageViewUnitTest, - SitePermissionsButtonOpensSubpageForCorrectExtension) { - auto extensionA = - InstallExtensionWithHostPermissions("Extension A", {"<all_urls>"}); - InstallExtensionWithHostPermissions("Extension B", {"<all_urls>"}); + SitePermissionsButton_CustomizeByExtension) { + auto extension = InstallExtension("Extension A"); + auto extension_with_permissions = + InstallExtensionWithHostPermissions("Extension B", {"<all_urls>"}); + auto enterprise_extension = + InstallEnterpriseExtension("Extension C", + /*host_permissions=*/{"<all_urls>"}); // Navigate to a page that extensions request access, and open the menu. - web_contents_tester()->NavigateAndCommit(GURL("http://www.example.com")); + const GURL url("http://www.example.com"); + auto url_origin = url::Origin::Create(url); + web_contents_tester()->NavigateAndCommit(url); ShowMenu(); + // Verify menu items are in the expected order, so we can check their site + // permissions button correctly. std::vector<ExtensionMenuItemView*> items = menu_items(); - ASSERT_EQ(items.size(), 2u); - EXPECT_EQ(items[0]->view_controller()->GetId(), extensionA->id()); + ASSERT_EQ(items.size(), 3u); + ExtensionMenuItemView* extension_item = items[0]; + ExtensionMenuItemView* extension_with_permissions_item = items[1]; + ExtensionMenuItemView* enterprise_extension_item = items[2]; + ASSERT_EQ(extension_item->view_controller()->GetId(), extension->id()); + ASSERT_EQ(extension_with_permissions_item->view_controller()->GetId(), + extension_with_permissions->id()); + ASSERT_EQ(enterprise_extension_item->view_controller()->GetId(), + enterprise_extension->id()); - // Site permissions button should be visible for both extensions. - EXPECT_TRUE(items[0]->site_permissions_button_for_testing()->GetVisible()); - EXPECT_TRUE(items[1]->site_permissions_button_for_testing()->GetVisible()); + // By default, site settings is set to "customize by extension". + PermissionsManager* permissions_manager = PermissionsManager::Get(profile()); + EXPECT_EQ(permissions_manager->GetUserSiteSetting(url_origin), + PermissionsManager::UserSiteSetting::kCustomizeByExtension); - // Clicking on an extension's site permission button should open its site - // permission page in the menu. - ClickSitePermissionsButton(items[0]); + // Site permissions button should be visible for all extensions, and enabled + // only for the extension with host permissions. + EXPECT_TRUE( + extension_item->site_permissions_button_for_testing()->GetVisible()); + EXPECT_FALSE( + extension_item->site_permissions_button_for_testing()->GetEnabled()); + EXPECT_TRUE( + extension_with_permissions_item->site_permissions_button_for_testing() + ->GetVisible()); + EXPECT_TRUE( + extension_with_permissions_item->site_permissions_button_for_testing() + ->GetEnabled()); + EXPECT_TRUE(enterprise_extension_item->site_permissions_button_for_testing() + ->GetVisible()); + EXPECT_FALSE(enterprise_extension_item->site_permissions_button_for_testing() + ->GetEnabled()); + + // Clicking on an extension's site permission disabled button should do + // nothing. + ClickSitePermissionsButton(extension_item); + EXPECT_TRUE(main_page()); + EXPECT_FALSE(site_permissions_page()); + + // Clicking on an extension's site permission enabled button should open + // its site permission page in the menu. + ClickSitePermissionsButton(extension_with_permissions_item); + EXPECT_FALSE(main_page()); ExtensionsMenuSitePermissionsPageView* page = site_permissions_page(); ASSERT_TRUE(page); - EXPECT_EQ(page->extension_id(), extensionA->id()); + EXPECT_EQ(page->extension_id(), extension_with_permissions->id()); +} + +// Verifies that only the permission button of enterprise extensions is visible, +// but disabled, when user blocked all extensions on a site. +TEST_F(ExtensionsMenuMainPageViewUnitTest, + SitePermissionsButton_BlockAllExtensions) { + auto extension = + InstallExtensionWithHostPermissions("Extension A", {"<all_urls>"}); + auto enterprise_extension = + InstallEnterpriseExtension("Extension B", + /*host_permissions=*/{}); + auto enterprise_extension_with_permissions = + InstallEnterpriseExtension("Extension C", + /*host_permissions=*/{"<all_urls>"}); + + // Navigate to a page that extensions request access, and open the menu. + const GURL url(u"http://www.example.com"); + auto url_origin = url::Origin::Create(url); + web_contents_tester()->NavigateAndCommit(url); + ShowMenu(); + + // Verify menu items are in the expected order, so we can check their site + // permissions button correctly. + std::vector<ExtensionMenuItemView*> items = menu_items(); + ASSERT_EQ(items.size(), 3u); + ExtensionMenuItemView* extension_item = items[0]; + ExtensionMenuItemView* enterprise_extension_item = items[1]; + ExtensionMenuItemView* enterprise_extension_with_permissions_item = items[2]; + ASSERT_EQ(extension_item->view_controller()->GetId(), extension->id()); + ASSERT_EQ(enterprise_extension_item->view_controller()->GetId(), + enterprise_extension->id()); + ASSERT_EQ( + enterprise_extension_with_permissions_item->view_controller()->GetId(), + enterprise_extension_with_permissions->id()); + + // Update site setting to "block all extensions". + PermissionsManager* permissions_manager = PermissionsManager::Get(profile()); + extensions::PermissionsManagerWaiter waiter(permissions_manager); + permissions_manager->UpdateUserSiteSetting( + url_origin, PermissionsManager::UserSiteSetting::kBlockAllExtensions); + waiter.WaitForUserPermissionsSettingsChange(); + + // Since the user blocked extensions on this site, most extensions + // shouldn't display the site permissions button at all. There's an + // exception for the policy-installed extension, since it can still run + // on the site (because enterprise-installed extensions take priority over + // user settings). For this extension, the control should be visible + // (so the user can see that it can run), but not clickable (bceause + // the user can't modify the settings). + EXPECT_FALSE( + extension_item->site_permissions_button_for_testing()->GetVisible()); + EXPECT_FALSE( + extension_item->site_permissions_button_for_testing()->GetEnabled()); + EXPECT_FALSE(enterprise_extension_item->site_permissions_button_for_testing() + ->GetVisible()); + EXPECT_FALSE(enterprise_extension_item->site_permissions_button_for_testing() + ->GetEnabled()); + EXPECT_TRUE(enterprise_extension_with_permissions_item + ->site_permissions_button_for_testing() + ->GetVisible()); + EXPECT_FALSE(enterprise_extension_with_permissions_item + ->site_permissions_button_for_testing() + ->GetEnabled()); + + // Clicking on any of the button should do nothing since it is disabled. + ClickSitePermissionsButton(enterprise_extension_with_permissions_item); + EXPECT_TRUE(main_page()); + EXPECT_FALSE(site_permissions_page()); } TEST_F(ExtensionsMenuMainPageViewUnitTest, @@ -378,28 +345,25 @@ auto extension_id = InstallExtension(kName)->id(); ShowMenu(); - - ExtensionMenuItemView* menu_item = GetOnlyMenuItem(); EXPECT_EQ(menu_items().size(), 1u); - ClickPinButton(menu_item); DisableExtension(extension_id); LayoutMenuIfNecessary(); - WaitForAnimation(); EXPECT_EQ(menu_items().size(), 0u); - EXPECT_THAT(GetPinnedExtensionNames(), testing::IsEmpty()); EnableExtension(extension_id); LayoutMenuIfNecessary(); - WaitForAnimation(); EXPECT_EQ(menu_items().size(), 1u); - EXPECT_EQ(GetPinnedExtensionNames(), std::vector<std::string>{kName}); } -// Tests that when an extension is reloaded it remains visible in the toolbar -// and extensions menu. +// Tests that when an extension is reloaded it remains visible in the extensions +// menu. +// TODO(crbug.com/1390952): Verify context menu button shows the correct icon as +// pinned state is also preserved when a reload happens. Add this functionality +// when showing pin icon instead of context menu when extension is pinned is +// added. TEST_F(ExtensionsMenuMainPageViewUnitTest, ReloadExtension) { // The extension must have a manifest to be reloaded. extensions::TestExtensionDir extension_directory; @@ -414,14 +378,8 @@ loader.LoadExtension(extension_directory.UnpackedPath()); ShowMenu(); - - ExtensionMenuItemView* menu_item = GetOnlyMenuItem(); EXPECT_EQ(menu_items().size(), 1u); - ClickPinButton(menu_item); - EXPECT_TRUE( - extensions_container()->IsActionVisibleOnToolbar(extension->id())); - // Reload the extension. extensions::TestExtensionRegistryObserver registry_observer( extensions::ExtensionRegistry::Get(profile())); @@ -429,15 +387,12 @@ ASSERT_TRUE(registry_observer.WaitForExtensionLoaded()); LayoutMenuIfNecessary(); - // Verify the extension is visible in the menu and on the toolbar. - menu_item = GetOnlyMenuItem(); + // Verify the extension is visible in the menu. EXPECT_EQ(menu_items().size(), 1u); - EXPECT_TRUE( - extensions_container()->IsActionVisibleOnToolbar(extension->id())); } // Tests that a when an extension is reloaded with manifest errors, and -// therefore fails to be loaded into Chrome, it's removed from the toolbar and +// therefore fails to be loaded into Chrome, it's removed from the // extensions menu. TEST_F(ExtensionsMenuMainPageViewUnitTest, ReloadExtensionFailed) { extensions::TestExtensionDir extension_directory; @@ -452,14 +407,8 @@ loader.LoadExtension(extension_directory.UnpackedPath()); ShowMenu(); - - ExtensionMenuItemView* menu_item = GetOnlyMenuItem(); EXPECT_EQ(menu_items().size(), 1u); - ClickPinButton(menu_item); - EXPECT_TRUE( - extensions_container()->IsActionVisibleOnToolbar(extension->id())); - // Replace the extension's valid manifest with one containing errors. In this // case, 'version' keys is missing. constexpr char kManifestWithErrors[] = R"({ @@ -476,9 +425,6 @@ // Verify the extension is no longer visible in the menu or on the toolbar // since it was removed. EXPECT_EQ(menu_items().size(), 0u); - for (views::View* child : extensions_container()->children()) { - EXPECT_FALSE(views::IsViewClass<ToolbarActionView>(child)); - } } // Tests that extension's site permission button is always hidden when site is @@ -523,51 +469,3 @@ EXPECT_FALSE( menu_items()[1]->site_permissions_button_for_testing()->GetVisible()); } - -// Test that an enterprise extension's site permissions button is shown based on -// the user site setting and extension site interaction. -TEST_F(ExtensionsMenuMainPageViewUnitTest, EnterpriseExtension) { - constexpr char kExtension[] = "Enterprise extension"; - constexpr char kExtensionWithPermissions[] = - "Enterprise extension with host permissions"; - InstallEnterpriseExtension(kExtension, /*host_permissions=*/{}); - InstallEnterpriseExtension(kExtensionWithPermissions, - /*host_permissions=*/{"<all_urls>"}); - - const GURL url(u"http://www.example.com"); - auto url_origin = url::Origin::Create(url); - web_contents_tester()->NavigateAndCommit(url); - - // By default, user site setting is set to "customize by extension". - PermissionsManager* permissions_manager = PermissionsManager::Get(profile()); - EXPECT_EQ(permissions_manager->GetUserSiteSetting(url_origin), - PermissionsManager::UserSiteSetting::kCustomizeByExtension); - - // Open menu and verify extensions are in the expected order. - ShowMenu(); - ASSERT_EQ(menu_items().size(), 2u); - std::vector<std::string> expected_items{kExtension, - kExtensionWithPermissions}; - EXPECT_EQ(GetNamesFromMenuItems(menu_items()), expected_items); - - // Enterprise extension's site permission button is always visible when user - // can customize site access by extension. - EXPECT_TRUE( - menu_items()[0]->site_permissions_button_for_testing()->GetVisible()); - EXPECT_TRUE( - menu_items()[1]->site_permissions_button_for_testing()->GetVisible()); - - extensions::PermissionsManagerWaiter waiter( - PermissionsManager::Get(browser()->profile())); - permissions_manager->UpdateUserSiteSetting( - url_origin, PermissionsManager::UserSiteSetting::kBlockAllExtensions); - waiter.WaitForUserPermissionsSettingsChange(); - - // Enterprise extension's site permission button is still visible when - // user has blocked all extensions but enterprise extension still has access - // (policy his priority over user settings). - EXPECT_FALSE( - menu_items()[0]->site_permissions_button_for_testing()->GetVisible()); - EXPECT_TRUE( - menu_items()[1]->site_permissions_button_for_testing()->GetVisible()); -}
diff --git a/chrome/browser/ui/views/extensions/extensions_menu_site_permissions_page_view_unittest.cc b/chrome/browser/ui/views/extensions/extensions_menu_site_permissions_page_view_unittest.cc index 45cfe0b2..21562d6a 100644 --- a/chrome/browser/ui/views/extensions/extensions_menu_site_permissions_page_view_unittest.cc +++ b/chrome/browser/ui/views/extensions/extensions_menu_site_permissions_page_view_unittest.cc
@@ -29,7 +29,9 @@ ExtensionsSitePermissionsPageViewUnitTest& operator=( const ExtensionsSitePermissionsPageViewUnitTest&) = delete; - // Opens menu and navigates to site permissions page for `extension_id`. + // Opens menu and navigates to site permissions page for `extension_id`. This + // will CHECK if extension cannot have a site permissions page (e.g + // restricted site). void ShowSitePermissionsPage(extensions::ExtensionId extension_id); // Returns whether me menu has the main page opened. @@ -43,6 +45,9 @@ // toolbar. std::vector<extensions::ExtensionId> GetExtensionsShowingRequests(); + // Navigates to `string_url`. + void NavigateAndCommit(const std::string& string_url); + // Since this is a unittest, the extensions menu widget sometimes needs a // nudge to re-layout the views. void LayoutMenuIfNecessary(); @@ -90,6 +95,13 @@ ->GetExtensionIdsForTesting(); } +void ExtensionsSitePermissionsPageViewUnitTest::NavigateAndCommit( + const std::string& string_url) { + const GURL url(string_url); + web_contents_tester_->NavigateAndCommit(url); + WaitForAnimation(); +} + void ExtensionsSitePermissionsPageViewUnitTest::LayoutMenuIfNecessary() { menu_coordinator()->GetExtensionsMenuWidget()->LayoutRootViewIfNecessary(); } @@ -119,8 +131,10 @@ TEST_F(ExtensionsSitePermissionsPageViewUnitTest, AddAndRemoveExtensionWhenSitePermissionsPageIsOpen) { - auto extensionA = InstallExtension("A Extension"); + auto extensionA = + InstallExtensionWithHostPermissions("A Extension", {"<all_urls>"}); + NavigateAndCommit("http://www.url.com"); ShowSitePermissionsPage(extensionA->id()); // Verify site permissions page is open for extension A. @@ -128,7 +142,8 @@ // Adding a new extension doesn't affect the opened site permissions page for // extension A. - auto extensionB = InstallExtension("B Extension"); + auto extensionB = + InstallExtensionWithHostPermissions("B Extension", {"<all_urls>"}); EXPECT_TRUE(IsSitePermissionsPageOpened(extensionA->id())); // Removing extension B doesn't affect the opened site permissions page for @@ -146,8 +161,10 @@ // Tests that menu navigates back to the main page when an extension, whose site // permissions page is open, is disabled. TEST_F(ExtensionsSitePermissionsPageViewUnitTest, DisableAndEnableExtension) { - auto extension = InstallExtension("Test Extension"); + auto extension = + InstallExtensionWithHostPermissions("Test Extension", {"<all_urls>"}); + NavigateAndCommit("http://www.url.com"); ShowSitePermissionsPage(extension->id()); EXPECT_TRUE(IsSitePermissionsPageOpened(extension->id())); @@ -167,13 +184,17 @@ constexpr char kManifest[] = R"({ "name": "Test Extension", "version": "1", - "manifest_version": 3 + "manifest_version": 3, + "host_permissions": [ + "<all_urls>" + ] })"; extension_directory.WriteManifest(kManifest); extensions::ChromeTestExtensionLoader loader(profile()); scoped_refptr<const extensions::Extension> extension = loader.LoadExtension(extension_directory.UnpackedPath()); + NavigateAndCommit("http://www.url.com"); ShowSitePermissionsPage(extension->id()); EXPECT_TRUE(IsSitePermissionsPageOpened(extension->id())); @@ -191,9 +212,6 @@ // Tests that toggling the show requests button changes whether an extension can // show site access requests in the toolbar, and the UI is properly updated. TEST_F(ExtensionsSitePermissionsPageViewUnitTest, ShowRequestsTogglePressed) { - content::WebContentsTester* web_contents_tester = - AddWebContentsAndGetTester(); - auto extensionA = InstallExtensionWithHostPermissions("Extension A", {"<all_urls>"}); auto extensionB = @@ -201,10 +219,7 @@ WithholdHostPermissions(extensionA.get()); WithholdHostPermissions(extensionB.get()); - const GURL url("http://www.url.com"); - web_contents_tester->NavigateAndCommit(url); - WaitForAnimation(); - + NavigateAndCommit("http://www.url.com"); ShowSitePermissionsPage(extensionA->id()); EXPECT_TRUE(IsSitePermissionsPageOpened(extensionA->id())); @@ -233,17 +248,11 @@ // access requests in the toolbar changes while the menu is open. TEST_F(ExtensionsSitePermissionsPageViewUnitTest, ShowRequestsPrefChangedWithMenuOpen) { - content::WebContentsTester* web_contents_tester = - AddWebContentsAndGetTester(); - auto extension = InstallExtensionWithHostPermissions("Extension", {"<all_urls>"}); WithholdHostPermissions(extension.get()); - const GURL url("http://www.url.com"); - web_contents_tester->NavigateAndCommit(url); - WaitForAnimation(); - + NavigateAndCommit("http://www.url.com"); ShowSitePermissionsPage(extension->id()); EXPECT_TRUE(IsSitePermissionsPageOpened(extension->id()));
diff --git a/chrome/browser/ui/views/extensions/extensions_menu_view.cc b/chrome/browser/ui/views/extensions/extensions_menu_view.cc index e999cf6..8d1e081 100644 --- a/chrome/browser/ui/views/extensions/extensions_menu_view.cc +++ b/chrome/browser/ui/views/extensions/extensions_menu_view.cc
@@ -306,8 +306,7 @@ // be added to the view hierarchy, which takes ownership. auto* item = new ExtensionMenuItemView( browser_, std::move(controller), - extensions_container_->CanShowActionsInToolbar(), - /*is_site_permissions_button_visible=*/false); + extensions_container_->CanShowActionsInToolbar()); extensions_menu_items_.insert(item); InsertMenuItem(item); // Sanity check that the item was added.
diff --git a/chrome/browser/ui/views/extensions/extensions_menu_view_controller.cc b/chrome/browser/ui/views/extensions/extensions_menu_view_controller.cc index 91dbc2b..848a9f6 100644 --- a/chrome/browser/ui/views/extensions/extensions_menu_view_controller.cc +++ b/chrome/browser/ui/views/extensions/extensions_menu_view_controller.cc
@@ -30,6 +30,15 @@ using PermissionsManager = extensions::PermissionsManager; using SitePermissionsHelper = extensions::SitePermissionsHelper; +// Returns the extension for `extension_id`. +const extensions::Extension* GetExtension( + Browser* browser, + extensions::ExtensionId extension_id) { + return extensions::ExtensionRegistry::Get(browser->profile()) + ->enabled_extensions() + .GetByID(extension_id); +} + // Returns sorted extension ids based on their extensions name. std::vector<std::string> SortExtensionsByName( ToolbarActionsModel& toolbar_model) { @@ -132,6 +141,62 @@ } } +// Returns whether user can select the site access for `extension` on +// `web_contents`. +bool CanUserCustomizeExtensionSiteAccess( + const extensions::Extension& extension, + Profile& profile, + const ToolbarActionsModel& toolbar_model, + content::WebContents& web_contents) { + const GURL& url = web_contents.GetLastCommittedURL(); + if (toolbar_model.IsRestrictedUrl(url)) { + // We don't allow customization of restricted sites (e.g. + // chrome://settings). + return false; + } + + bool enterprise_forced_access = HasEnterpriseForcedAccess(extension, profile); + if (enterprise_forced_access) { + // Users can't customize the site access of enterprise-installed extensions. + return false; + } + + // The extension wants site access if it at least wants "on click" access. + auto* permissions_manager = extensions::PermissionsManager::Get(&profile); + bool extension_wants_access = permissions_manager->CanUserSelectSiteAccess( + extension, url, PermissionsManager::UserSiteAccess::kOnClick); + if (!extension_wants_access) { + // Users can't customize site access of extensions that don't want access to + // begin with. + return false; + } + + // Users can only customize site access when they have allowed all extensions + // to be customizable on the site. + return permissions_manager->GetUserSiteSetting( + web_contents.GetPrimaryMainFrame()->GetLastCommittedOrigin()) == + PermissionsManager::UserSiteSetting::kCustomizeByExtension; +} + +// Returns the state for the `extension`'s site permissions button. +ExtensionMenuItemView::SitePermissionsButtonState GetSitePermissionsButtonState( + const extensions::Extension& extension, + Profile& profile, + const ToolbarActionsModel& toolbar_model, + content::WebContents& web_contents) { + bool is_site_permissions_button_visible = IsSitePermissionsButtonVisible( + extension, profile, toolbar_model, web_contents); + if (!is_site_permissions_button_visible) { + return ExtensionMenuItemView::SitePermissionsButtonState::kHidden; + } + + bool is_site_permissions_button_enabled = CanUserCustomizeExtensionSiteAccess( + extension, profile, toolbar_model, web_contents); + return is_site_permissions_button_enabled + ? ExtensionMenuItemView::SitePermissionsButtonState::kEnabled + : ExtensionMenuItemView::SitePermissionsButtonState::kDisabled; +} + } // namespace ExtensionsMenuViewController::ExtensionsMenuViewController( @@ -173,6 +238,10 @@ void ExtensionsMenuViewController::OpenSitePermissionsPage( extensions::ExtensionId extension_id) { + CHECK(CanUserCustomizeExtensionSiteAccess( + *GetExtension(browser_, extension_id), *browser_->profile(), + *toolbar_model_, *GetActiveWebContents())); + const int icon_size = ChromeLayoutProvider::Get()->GetDistanceMetric( DISTANCE_EXTENSIONS_MENU_EXTENSION_ICON_SIZE); std::unique_ptr<ExtensionActionViewController> action_controller = @@ -238,10 +307,10 @@ .GetByID(menu_item->view_controller()->GetId()); CHECK(extension); - bool is_site_permissions_button_visible = IsSitePermissionsButtonVisible( - *extension, *browser_->profile(), *toolbar_model_, - *GetActiveWebContents()); - menu_item->Update(is_site_permissions_button_visible); + ExtensionMenuItemView::SitePermissionsButtonState + site_permissions_button_state = GetSitePermissionsButtonState( + *extension, *browser_->profile(), *toolbar_model_, *web_contents); + menu_item->Update(site_permissions_button_state); } } } @@ -264,14 +333,13 @@ std::unique_ptr<ExtensionActionViewController> action_controller = ExtensionActionViewController::Create(action_id, browser_, extensions_container_); - bool is_site_permissions_button_visible = IsSitePermissionsButtonVisible( - *action_controller->extension(), *browser_->profile(), *toolbar_model_, - *GetActiveWebContents()); + ExtensionMenuItemView::SitePermissionsButtonState + site_permissions_button_state = GetSitePermissionsButtonState( + *action_controller->extension(), *browser_->profile(), + *toolbar_model_, *GetActiveWebContents()); - main_page->CreateAndInsertMenuItem( - std::move(action_controller), action_id, - extensions_container_->CanShowActionsInToolbar(), - is_site_permissions_button_visible, index); + main_page->CreateAndInsertMenuItem(std::move(action_controller), action_id, + site_permissions_button_state, index); // TODO(crbug.com/1390952): Update requests access section once such section // is implemented (if the extension added requests site access, it needs to be @@ -412,7 +480,6 @@ void ExtensionsMenuViewController::PopulateMainPage( ExtensionsMenuMainPageView* main_page) { - bool allow_pinning = extensions_container_->CanShowActionsInToolbar(); std::vector<std::string> sorted_ids = SortExtensionsByName(*toolbar_model_); for (size_t i = 0; i < sorted_ids.size(); ++i) { // TODO(emiliapaz): Under MVC architecture, view should not own the view @@ -421,12 +488,14 @@ std::unique_ptr<ExtensionActionViewController> action_controller = ExtensionActionViewController::Create(sorted_ids[i], browser_, extensions_container_); - bool is_site_permissions_button_visible = IsSitePermissionsButtonVisible( - *action_controller->extension(), *browser_->profile(), *toolbar_model_, - *GetActiveWebContents()); + ExtensionMenuItemView::SitePermissionsButtonState + site_permissions_button_state = GetSitePermissionsButtonState( + *action_controller->extension(), *browser_->profile(), + *toolbar_model_, *GetActiveWebContents()); + main_page->CreateAndInsertMenuItem(std::move(action_controller), - sorted_ids[i], allow_pinning, - is_site_permissions_button_visible, i); + sorted_ids[i], + site_permissions_button_state, i); } }
diff --git a/chrome/browser/ui/views/extensions/extensions_toolbar_container_unittest.cc b/chrome/browser/ui/views/extensions/extensions_toolbar_container_unittest.cc index bcad771..e4b23aa 100644 --- a/chrome/browser/ui/views/extensions/extensions_toolbar_container_unittest.cc +++ b/chrome/browser/ui/views/extensions/extensions_toolbar_container_unittest.cc
@@ -6,16 +6,47 @@ #include "base/json/json_reader.h" #include "base/ranges/algorithm.h" +#include "chrome/browser/extensions/chrome_test_extension_loader.h" +#include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/ui/toolbar/toolbar_action_view_controller.h" #include "chrome/browser/ui/views/extensions/extensions_toolbar_unittest.h" #include "components/sync_preferences/testing_pref_service_syncable.h" #include "extensions/browser/pref_names.h" +#include "extensions/browser/test_extension_registry_observer.h" #include "extensions/common/extension_features.h" #include "extensions/common/extension_id.h" +#include "extensions/test/test_extension_dir.h" #include "testing/gmock/include/gmock/gmock.h" #include "ui/base/dragdrop/drag_drop_types.h" #include "ui/base/dragdrop/mojom/drag_drop_types.mojom.h" +namespace { + +// A scoper that manages a Browser instance created by BrowserWithTestWindowTest +// beyond the default instance it creates in SetUp. +class AdditionalBrowser { + public: + explicit AdditionalBrowser(std::unique_ptr<Browser> browser) + : browser_(std::move(browser)), + browser_view_(BrowserView::GetBrowserViewForBrowser(browser_.get())) {} + + ~AdditionalBrowser() { + // Tear down `browser_`, similar to TestWithBrowserView::TearDown. + browser_.release(); + browser_view_->GetWidget()->CloseNow(); + } + + ExtensionsToolbarContainer* extensions_container() { + return browser_view_->toolbar()->extensions_container(); + } + + private: + std::unique_ptr<Browser> browser_; + raw_ptr<BrowserView> browser_view_; +}; + +} // namespace + class ExtensionsToolbarContainerUnitTest : public ExtensionsToolbarUnitTest { public: ExtensionsToolbarContainerUnitTest(); @@ -138,6 +169,118 @@ drag_view, gfx::Point(), gfx::Point())); } +// Tests that when an extension is reloaded it remains visible in the toolbar. +TEST_F(ExtensionsToolbarContainerUnitTest, ReloadExtensionKeepsPinnedState) { + // The extension must have a manifest to be reloaded. + extensions::TestExtensionDir extension_directory; + constexpr char kManifest[] = R"({ + "name": "Test Extension", + "version": "1", + "manifest_version": 3 + })"; + extension_directory.WriteManifest(kManifest); + extensions::ChromeTestExtensionLoader loader(profile()); + scoped_refptr<const extensions::Extension> extension = + loader.LoadExtension(extension_directory.UnpackedPath()); + + // By default, extension on installation is unpinned. + EXPECT_FALSE( + extensions_container()->IsActionVisibleOnToolbar(extension->id())); + + // Pin extension and verify it is visible on the toolbar. + auto* toolbar_model = ToolbarActionsModel::Get(profile()); + ASSERT_TRUE(toolbar_model); + toolbar_model->SetActionVisibility(extension->id(), true); + EXPECT_TRUE( + extensions_container()->IsActionVisibleOnToolbar(extension->id())); + + // Reload the extension. + extensions::TestExtensionRegistryObserver registry_observer( + extensions::ExtensionRegistry::Get(profile())); + ReloadExtension(extension->id()); + ASSERT_TRUE(registry_observer.WaitForExtensionLoaded()); + WaitForAnimation(); + + // Verify the extension is visible on the toolbar. + EXPECT_TRUE( + extensions_container()->IsActionVisibleOnToolbar(extension->id())); +} + +// Tests that a when an extension is reloaded with manifest errors, and +// therefore fails to be loaded into Chrome, it's removed from the toolbar. +TEST_F(ExtensionsToolbarContainerUnitTest, ReloadExtensionFailed) { + extensions::TestExtensionDir extension_directory; + constexpr char kManifest[] = R"({ + "name": "Test Extension", + "version": "1", + "manifest_version": 3 + })"; + extension_directory.WriteManifest(kManifest); + extensions::ChromeTestExtensionLoader loader(profile()); + scoped_refptr<const extensions::Extension> extension = + loader.LoadExtension(extension_directory.UnpackedPath()); + + // By default, extension on installation is unpinned. + EXPECT_FALSE( + extensions_container()->IsActionVisibleOnToolbar(extension->id())); + + // Pin extension and verify it is visible on the toolbar. + auto* toolbar_model = ToolbarActionsModel::Get(profile()); + ASSERT_TRUE(toolbar_model); + toolbar_model->SetActionVisibility(extension->id(), true); + EXPECT_TRUE( + extensions_container()->IsActionVisibleOnToolbar(extension->id())); + + // Replace the extension's valid manifest with one containing errors. In this + // case, 'version' keys is missing. + constexpr char kManifestWithErrors[] = R"({ + "name": "Test", + "manifest_version": 3, + })"; + extension_directory.WriteManifest(kManifestWithErrors); + + // Reload the extension. It should fail due to the manifest errors. + extension_service()->ReloadExtensionWithQuietFailure(extension->id()); + base::RunLoop().RunUntilIdle(); + WaitForAnimation(); + + // Verify the extension is no longer visible on the toolbar. + EXPECT_FALSE( + extensions_container()->IsActionVisibleOnToolbar(extension->id())); +} + +TEST_F(ExtensionsToolbarContainerUnitTest, + PinnedExtensionAppearsInAnotherWindow) { + const std::string& extension_id = InstallExtension("Extension")->id(); + + AdditionalBrowser browser2( + CreateBrowser(browser()->profile(), browser()->type(), + /* hosted_app */ false, /* browser_window */ nullptr)); + + // Verify extension is unpinned in both windows. + EXPECT_FALSE(extensions_container()->IsActionVisibleOnToolbar(extension_id)); + EXPECT_FALSE( + browser2.extensions_container()->IsActionVisibleOnToolbar(extension_id)); + + // Pin extension in one window. + auto* toolbar_model = ToolbarActionsModel::Get(profile()); + ASSERT_TRUE(toolbar_model); + toolbar_model->SetActionVisibility(extension_id, true); + + // Both windows open get the pinned extension. + EXPECT_TRUE(extensions_container()->IsActionVisibleOnToolbar(extension_id)); + EXPECT_TRUE( + browser2.extensions_container()->IsActionVisibleOnToolbar(extension_id)); + + AdditionalBrowser browser3( + CreateBrowser(browser()->profile(), browser()->type(), + /* hosted_app */ false, /* browser_window */ nullptr)); + + // Brand-new window also gets the pinned extension. + EXPECT_TRUE( + browser3.extensions_container()->IsActionVisibleOnToolbar(extension_id)); +} + TEST_F(ExtensionsToolbarContainerUnitTest, PinnedExtensionsReorderOnPrefChange) { constexpr char kExtensionAName[] = "A Extension";
diff --git a/chrome/browser/ui/views/plugin_vm/plugin_vm_installer_view_browsertest.cc b/chrome/browser/ui/views/plugin_vm/plugin_vm_installer_view_browsertest.cc index b586884..21cb159bf 100644 --- a/chrome/browser/ui/views/plugin_vm/plugin_vm_installer_view_browsertest.cc +++ b/chrome/browser/ui/views/plugin_vm/plugin_vm_installer_view_browsertest.cc
@@ -242,12 +242,12 @@ auto* progress_view = view_->GetDownloadProgressMessageViewForTesting(); EXPECT_NE(nullptr, progress_view); - // The message and title labels should each have fired an accessibility event - // as a result of the introductory/set-up text being displayed. Because the - // download has not started, there should be no event from the download - // progress label. - EXPECT_EQ(1, counter.GetCount(ax::mojom::Event::kTextChanged, title_view)); - EXPECT_EQ(1, counter.GetCount(ax::mojom::Event::kTextChanged, message_view)); + // Views should only fire property-change events when the property changes; + // not when a value is initialized. As a result, there should not be any + // text-changed accessibility fired as a result of the introductory/set-up + // text being displayed. + EXPECT_EQ(0, counter.GetCount(ax::mojom::Event::kTextChanged, title_view)); + EXPECT_EQ(0, counter.GetCount(ax::mojom::Event::kTextChanged, message_view)); EXPECT_EQ(0, counter.GetCount(ax::mojom::Event::kTextChanged, progress_view)); counter.ResetAllCounts();
diff --git a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc index cc09e0be..54a2c46 100644 --- a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc +++ b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
@@ -216,7 +216,6 @@ #include "ash/webui/print_management/print_management_ui.h" #include "ash/webui/print_management/url_constants.h" #include "ash/webui/projector_app/public/cpp/projector_app_constants.h" // nogncheck -#include "ash/webui/projector_app/trusted_projector_annotator_ui.h" #include "ash/webui/projector_app/trusted_projector_ui.h" #include "ash/webui/scanning/scanning_ui.h" #include "ash/webui/scanning/url_constants.h" @@ -501,13 +500,6 @@ Profile::FromWebUI(web_ui)->GetPrefs()); } -template <> -WebUIController* NewWebUI<ash::TrustedProjectorAnnotatorUI>(WebUI* web_ui, - const GURL& url) { - return new ash::TrustedProjectorAnnotatorUI( - web_ui, url, Profile::FromWebUI(web_ui)->GetPrefs()); -} - void BindPrintManagement( Profile* profile, mojo::PendingReceiver< @@ -1037,10 +1029,6 @@ IsProjectorAppEnabled(profile)) { return &NewWebUI<ash::TrustedProjectorUI>; } - if (url.host_piece() == ash::kChromeUIProjectorAnnotatorHost && - IsProjectorAppEnabled(profile)) { - return &NewWebUI<ash::TrustedProjectorAnnotatorUI>; - } if (url.host_piece() == ash::eche_app::kChromeUIEcheAppHost && base::FeatureList::IsEnabled(ash::features::kEcheSWA)) { return &NewWebUI<ash::eche_app::EcheAppUI>;
diff --git a/chrome/browser/ui/webui/cr_components/history_clusters/history_clusters_util.cc b/chrome/browser/ui/webui/cr_components/history_clusters/history_clusters_util.cc index 49ce2f53..ed637b7 100644 --- a/chrome/browser/ui/webui/cr_components/history_clusters/history_clusters_util.cc +++ b/chrome/browser/ui/webui/cr_components/history_clusters/history_clusters_util.cc
@@ -49,6 +49,8 @@ source->AddString( "chromeRefresh2023Attribute", features::IsChromeRefresh2023() ? "chrome-refresh-2023" : ""); + source->AddBoolean("isHistoryClustersImageCover", + history_clusters::GetConfig().images_cover); static constexpr webui::LocalizedString kHistoryClustersStrings[] = { {"actionMenuDescription", IDS_HISTORY_CLUSTERS_ACTION_MENU_DESCRIPTION},
diff --git a/chrome/browser/ui/webui/omnibox/omnibox_page_handler.cc b/chrome/browser/ui/webui/omnibox/omnibox_page_handler.cc index c80c431..2bd1bad 100644 --- a/chrome/browser/ui/webui/omnibox/omnibox_page_handler.cc +++ b/chrome/browser/ui/webui/omnibox/omnibox_page_handler.cc
@@ -182,8 +182,9 @@ result->keyword = base::UTF16ToUTF8(input.keyword); result->duplicates = static_cast<int32_t>(input.duplicate_matches.size()); result->from_previous = input.from_previous; - const OmniboxAction* action = input.GetPrimaryAction(); - result->pedal_id = action ? action->GetID() : 0; + const auto* pedal = OmniboxPedal::FromAction(input.GetPrimaryAction()); + result->pedal_id = + pedal == nullptr ? 0 : static_cast<int32_t>(pedal->PedalId()); result->additional_info = mojo::ConvertTo<std::vector<mojom::AutocompleteAdditionalInfoPtr>>( input.additional_info);
diff --git a/chrome/browser/ui/webui/settings/password_manager_handler.cc b/chrome/browser/ui/webui/settings/password_manager_handler.cc new file mode 100644 index 0000000..0ce557ba --- /dev/null +++ b/chrome/browser/ui/webui/settings/password_manager_handler.cc
@@ -0,0 +1,56 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/webui/settings/password_manager_handler.h" + +#include "chrome/browser/ui/browser_finder.h" +#include "chrome/browser/ui/chrome_pages.h" + +namespace settings { + +namespace { + +// WARNING: Keep synced with +// chrome/browser/resources/settings/autofill_page/password_manager_proxy.ts. +enum class PasswordManagerPage { + kPasswords = 0, + kCheckup, + kLastItem = kCheckup +}; + +} // namespace + +PasswordManagerHandler::PasswordManagerHandler() = default; +PasswordManagerHandler::~PasswordManagerHandler() = default; + +void PasswordManagerHandler::RegisterMessages() { + web_ui()->RegisterMessageCallback( + "showPasswordManager", + base::BindRepeating(&PasswordManagerHandler::HandleShowPasswordManager, + base::Unretained(this))); +} + +void PasswordManagerHandler::HandleShowPasswordManager( + const base::Value::List& args) { + AllowJavascript(); + CHECK_EQ(1U, args.size()); + int page = args[0].GetInt(); + + Browser* current_broswer = + chrome::FindBrowserWithWebContents(web_ui()->GetWebContents()); + CHECK(current_broswer); + + switch (PasswordManagerPage(page)) { + case PasswordManagerPage::kPasswords: + chrome::ShowPasswordManager(current_broswer); + return; + case PasswordManagerPage::kCheckup: + chrome::ShowPasswordCheck(current_broswer); + return; + default: + NOTREACHED(); + } +} + +} // namespace settings
diff --git a/chrome/browser/ui/webui/settings/password_manager_handler.h b/chrome/browser/ui/webui/settings/password_manager_handler.h new file mode 100644 index 0000000..05fbc99 --- /dev/null +++ b/chrome/browser/ui/webui/settings/password_manager_handler.h
@@ -0,0 +1,32 @@ +// 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 CHROME_BROWSER_UI_WEBUI_SETTINGS_PASSWORD_MANAGER_HANDLER_H_ +#define CHROME_BROWSER_UI_WEBUI_SETTINGS_PASSWORD_MANAGER_HANDLER_H_ + +#include "base/values.h" +#include "content/public/browser/web_ui_message_handler.h" + +namespace settings { + +// A which enables interactions with Password Manager from settings. +class PasswordManagerHandler : public content::WebUIMessageHandler { + public: + explicit PasswordManagerHandler(); + + PasswordManagerHandler(const PasswordManagerHandler&) = delete; + PasswordManagerHandler& operator=(const PasswordManagerHandler&) = delete; + + ~PasswordManagerHandler() override; + + private: + // WebUIMessageHandler: + void RegisterMessages() override; + + void HandleShowPasswordManager(const base::Value::List& args); +}; + +} // namespace settings + +#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_PASSWORD_MANAGER_HANDLER_H_
diff --git a/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc b/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc index 5e3b521..276c72fb 100644 --- a/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc +++ b/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc
@@ -309,9 +309,11 @@ #if BUILDFLAG(IS_MAC) {"aboutLearnMoreUpdating", IDS_SETTINGS_ABOUT_PAGE_LEARN_MORE_UPDATING}, #endif - {"getTheMostOutOfProgram", IDS_SETTINGS_GET_THE_MOST_OUT_OF_PROGRAM}, - {"getTheMostOutOfProgramDescription", - IDS_SETTINGS_GET_THE_MOST_OUT_OF_PROGRAM_DESCRIPTION}, +#if BUILDFLAG(GOOGLE_CHROME_BRANDING) + {"getTheMostOutOfChrome", IDS_SETTINGS_GET_THE_MOST_OUT_OF_CHROME}, + {"getTheMostOutOfChromeDescription", + IDS_SETTINGS_GET_THE_MOST_OUT_OF_CHROME_DESCRIPTION}, +#endif }; html_source->AddLocalizedStrings(kLocalizedStrings); @@ -353,11 +355,10 @@ html_source->AddString("aboutTermsURL", chrome::kChromeUITermsURL); html_source->AddLocalizedString("aboutProductTos", IDS_ABOUT_TERMS_OF_SERVICE); -#endif - html_source->AddBoolean( - "showGetTheMostOutOfProgramSection", - base::FeatureList::IsEnabled(features::kGetTheMostOutOfProgram)); + "showGetTheMostOutOfChromeSection", + base::FeatureList::IsEnabled(features::kGetTheMostOutOfChrome)); +#endif } void AddAppearanceStrings(content::WebUIDataSource* html_source,
diff --git a/chrome/browser/ui/webui/settings/settings_ui.cc b/chrome/browser/ui/webui/settings/settings_ui.cc index 73a56a7..2bbba4c 100644 --- a/chrome/browser/ui/webui/settings/settings_ui.cc +++ b/chrome/browser/ui/webui/settings/settings_ui.cc
@@ -44,6 +44,7 @@ #include "chrome/browser/ui/webui/settings/import_data_handler.h" #include "chrome/browser/ui/webui/settings/metrics_reporting_handler.h" #include "chrome/browser/ui/webui/settings/on_startup_handler.h" +#include "chrome/browser/ui/webui/settings/password_manager_handler.h" #include "chrome/browser/ui/webui/settings/people_handler.h" #include "chrome/browser/ui/webui/settings/performance_handler.h" #include "chrome/browser/ui/webui/settings/privacy_sandbox_handler.h" @@ -242,6 +243,10 @@ std::make_unique<SecurityKeysBioEnrollmentHandler>()); AddSettingsPageUIHandler(std::make_unique<SecurityKeysPhonesHandler>()); + if (base::FeatureList::IsEnabled( + password_manager::features::kPasswordManagerRedesign)) { + AddSettingsPageUIHandler(std::make_unique<PasswordManagerHandler>()); + } #if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) AddSettingsPageUIHandler(std::make_unique<PasskeysHandler>()); #endif
diff --git a/chrome/build/mac-arm.pgo.txt b/chrome/build/mac-arm.pgo.txt index 7d6ed65..d6b77497 100644 --- a/chrome/build/mac-arm.pgo.txt +++ b/chrome/build/mac-arm.pgo.txt
@@ -1 +1 @@ -chrome-mac-arm-main-1679932723-c05931a5feded7bcf01a5176d8f691d0c8801047.profdata +chrome-mac-arm-main-1679947177-fb316e82e3ba3c9b100a4d9e87e5e8c76b5abc41.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt index 2552533..7f485c23 100644 --- a/chrome/build/mac.pgo.txt +++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@ -chrome-mac-main-1679918112-417d920a2afa99c2604497f2f3c2e011ee1bfa58.profdata +chrome-mac-main-1679939715-f2197e078da171c9a5b41d8a4444f02b40d1bd6a.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt index a9df734..1da1b6f7 100644 --- a/chrome/build/win32.pgo.txt +++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@ -chrome-win32-main-1679918112-3434798d3db2ecd76dfc1e78dbe255f6fe038068.profdata +chrome-win32-main-1679929060-34f29b821ee8e423dbbb3d45b09b0227d8306c7d.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt index d8b6613..30c09f5 100644 --- a/chrome/build/win64.pgo.txt +++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@ -chrome-win64-main-1679918112-4e49f4a193f7aef5137ab616e3255df467ae85da.profdata +chrome-win64-main-1679929060-4c299167367e97d7cb321c6c0cf68fb0c992c785.profdata
diff --git a/chrome/chrome_cleaner/os/file_path_sanitization_unittest.cc b/chrome/chrome_cleaner/os/file_path_sanitization_unittest.cc index ce0c69f..71c2f9c 100644 --- a/chrome/chrome_cleaner/os/file_path_sanitization_unittest.cc +++ b/chrome/chrome_cleaner/os/file_path_sanitization_unittest.cc
@@ -21,14 +21,12 @@ TEST(FilePathSanitizationTests, NormalizePath) { #if defined(ARCH_CPU_ARM64) - // on Win Arm64, ::GetLongPathName fails on c:\program files. - base::FilePath expected_path = - base::FilePath(L"c:\\program files (arm)\\desktop.ini"); - EXPECT_EQ(NormalizePath(base::FilePath(L"C:\\PROGRA~2\\DESKTOP.INI")), - expected_path); - EXPECT_EQ( - NormalizePath(base::FilePath(L"c:\\pRoGrAm FiLeS (Arm)\\desktop.INI")), - expected_path); + // desktop.ini is not in C:\Program Files on ARM64 devices and the directory + // where it does exist (C:\Program Files (Arm)) doesn't have an 8.3 name. + // So, this is the best normalization test we can do. + base::FilePath expected_path = base::FilePath(L"c:\\program files"); + EXPECT_EQ(NormalizePath(base::FilePath(L"C:\\PROGRA~1")), expected_path); + EXPECT_EQ(NormalizePath(base::FilePath(L"c:\\pRoGrAm FiLeS")), expected_path); #else base::FilePath expected_path = base::FilePath(L"c:\\program files\\desktop.ini");
diff --git a/chrome/chrome_paks.gni b/chrome/chrome_paks.gni index 84da6451..69782d1 100644 --- a/chrome/chrome_paks.gni +++ b/chrome/chrome_paks.gni
@@ -269,7 +269,6 @@ "$root_gen_dir/ash/webui/ash_os_feedback_untrusted_resources.pak", "$root_gen_dir/ash/webui/ash_personalization_app_resources.pak", "$root_gen_dir/ash/webui/ash_print_management_resources.pak", - "$root_gen_dir/ash/webui/ash_projector_annotator_trusted_resources.pak", "$root_gen_dir/ash/webui/ash_projector_annotator_untrusted_resources.pak", "$root_gen_dir/ash/webui/ash_projector_app_trusted_resources.pak", "$root_gen_dir/ash/webui/ash_projector_app_untrusted_resources.pak", @@ -352,7 +351,6 @@ "//ash/webui/resources:multidevice_debug_resources", "//ash/webui/resources:os_feedback_resources", "//ash/webui/resources:os_feedback_untrusted_resources", - "//ash/webui/resources:projector_annotator_trusted_resources", "//ash/webui/resources:projector_annotator_untrusted_resources", "//ash/webui/resources:projector_app_bundle_resources", "//ash/webui/resources:projector_app_trusted_resources",
diff --git a/chrome/test/chromedriver/chrome/web_view_impl_unittest.cc b/chrome/test/chromedriver/chrome/web_view_impl_unittest.cc index 78c941a..51fac952 100644 --- a/chrome/test/chromedriver/chrome/web_view_impl_unittest.cc +++ b/chrome/test/chromedriver/chrome/web_view_impl_unittest.cc
@@ -770,7 +770,6 @@ : public testing::TestWithParam<std::pair<std::string, bool>> { public: void SetUp() override { - BrowserInfo browser_info; std::unique_ptr<FakeDevToolsClient> client_uptr = std::make_unique<FakeDevToolsClient>("root"); client_ptr = client_uptr.get(); @@ -783,14 +782,15 @@ } void TearDown() override { - view.reset(); client_ptr = nullptr; + view.reset(); } bool IsW3C() { return GetParam().second; } std::string ElementKey() { return GetParam().first; } + BrowserInfo browser_info; std::unique_ptr<WebViewImpl> view; base::raw_ptr<FakeDevToolsClient> client_ptr; };
diff --git a/chrome/test/data/browsing_topics/page_with_custom_attribute_iframe.html b/chrome/test/data/browsing_topics/page_with_custom_attribute_iframe.html new file mode 100644 index 0000000..faffadb5 --- /dev/null +++ b/chrome/test/data/browsing_topics/page_with_custom_attribute_iframe.html
@@ -0,0 +1,6 @@ +<!DOCTYPE html> +<html> +<body> + <iframe {{MAYBE_BROWSING_TOPICS_ATTRIBUTE}} src="{{SRC_URL}}"></iframe> +</body> +</html>
diff --git a/chrome/test/data/extensions/api_test/stubs_app/background.js b/chrome/test/data/extensions/api_test/stubs_app/background.js index a4f7b6c..e9536c6 100644 --- a/chrome/test/data/extensions/api_test/stubs_app/background.js +++ b/chrome/test/data/extensions/api_test/stubs_app/background.js
@@ -24,12 +24,16 @@ return; // Pieces of the module don't inherit from Array/Object. Array.prototype.forEach.call(section, function(entry) { - // Skip idle.getAutoLockDelay() and power.reportActivity() since they - // are restricted to certain platforms. + let fullName = `${namespace}.${entry.name}`; + // Skip a few functions: + // - `idle.getAutoLockDelay()` (restricted to certain platforms) + // - `power.reportActivity()` (restricted to certain platforms) + // - `runtime.getContexts()` (restricted to MV3) // TODO(https://crbug.com/921466) - if (entry.name != 'getAutoLockDelay' && - entry.name != 'reportActivity') { - apiPaths.push(namespace + "." + entry.name); + const skipPaths = ['idle.getAutoLockDelay', 'power.reportActivity', + 'runtime.getContexts']; + if (!skipPaths.includes(fullName)) { + apiPaths.push(fullName); } }); });
diff --git a/chrome/test/data/updater/CountingMetrics.plist b/chrome/test/data/updater/CountingMetrics.plist new file mode 100644 index 0000000..d378bee6 --- /dev/null +++ b/chrome/test/data/updater/CountingMetrics.plist
@@ -0,0 +1,56 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>com.chromium.popularapp</key> + <dict> + <key>DayOfLastActive</key> + <integer>5921</integer> + <key>DayOfLastRollcall</key> + <integer>5922</integer> + <key>LastActivePingDate</key> + <date>2023-03-20T19:43:31Z</date> + <key>PingFreshness</key> + <string>53838040-FB56-40F8-8B50-244CEC1ADB40</string> + <key>ProductState</key> + <integer>1</integer> + </dict> + <key>om.chromium.kipple</key> + <dict> + <key>DayOfLastRollcall</key> + <string>5912</string> + <key>LastActivePingDate</key> + <date>2023-03-20T19:43:31Z</date> + <key>PingFreshness</key> + <string>CAC43E38-89E0-430F-92FB-0CA5B899B3C5</string> + <key>ProductState</key> + <integer>1</integer> + </dict> + <key>com.chromium.corruptedapp</key> + <dict> + <key>DayOfLastActive</key> + <integer>50001</integer> + <key>DayOfLastRollcall</key> + <integer>2999</integer> + <key>LastActivePingDate</key> + <date>2023-03-20T19:43:31Z</date> + <key>PingFreshness</key> + <string>CAC43E39-89E0-430F-92FB-0CA5B899B3C5</string> + <key>ProductState</key> + <integer>1</integer> + </dict> + <key>com.no.such.app</key> + <dict> + <key>DayOfLastActive</key> + <integer>5922</integer> + <key>DayOfLastRollcall</key> + <integer>5923</integer> + <key>LastActivePingDate</key> + <date>2023-03-20T19:43:31Z</date> + <key>PingFreshness</key> + <string>CAC43E48-89E0-430F-92FB-0CA5B899B3C5</string> + <key>ProductState</key> + <integer>1</integer> + </dict> +</dict> +</plist>
diff --git a/chrome/test/data/updater/Keystone.legacy.ticketstore b/chrome/test/data/updater/Keystone.legacy.ticketstore index 40788477..515d0b55 100644 --- a/chrome/test/data/updater/Keystone.legacy.ticketstore +++ b/chrome/test/data/updater/Keystone.legacy.ticketstore Binary files differ
diff --git a/chrome/test/data/webui/chromeos/shortcut_customization/search_result_row_test.ts b/chrome/test/data/webui/chromeos/shortcut_customization/search_result_row_test.ts index 22f25544..1210fb4 100644 --- a/chrome/test/data/webui/chromeos/shortcut_customization/search_result_row_test.ts +++ b/chrome/test/data/webui/chromeos/shortcut_customization/search_result_row_test.ts
@@ -4,10 +4,13 @@ import 'chrome://shortcut-customization/js/search/search_result_row.js'; import 'chrome://webui-test/mojo_webui_test_support.js'; +import {strictQuery} from 'chrome://resources/ash/common/typescript_utils/strict_query.js'; import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; -import {SnapWindowLeftSearchResult} from 'chrome://shortcut-customization/js/fake_data.js'; +import {CycleTabsTextSearchResult, SnapWindowLeftSearchResult} from 'chrome://shortcut-customization/js/fake_data.js'; import {SearchResultRowElement} from 'chrome://shortcut-customization/js/search/search_result_row.js'; +import {TextAcceleratorElement} from 'chrome://shortcut-customization/js/text_accelerator.js'; import {assertEquals, assertTrue} from 'chrome://webui-test/chai_assert.js'; +import {flushTasks} from 'chrome://webui-test/polymer_test_util.js'; function initSearchResultRowElement(): SearchResultRowElement { const element = document.createElement('search-result-row'); @@ -32,11 +35,11 @@ assertTrue(!!searchResultRowElement); }); - test('SearchResultTextDisplayed', async () => { + test('SearchResultDescriptionDisplayed', async () => { searchResultRowElement = initSearchResultRowElement(); await flush(); const searchResultTextElement = - searchResultRowElement!.shadowRoot!.querySelector('#searchResultText'); + searchResultRowElement!.shadowRoot!.querySelector('#description'); assertTrue(!!searchResultTextElement); searchResultRowElement.searchResult = SnapWindowLeftSearchResult; @@ -44,4 +47,28 @@ assertEquals( 'Snap Window Left', searchResultTextElement.textContent?.trim()); }); + + test('Text accelerators render correctly', async () => { + searchResultRowElement = initSearchResultRowElement(); + searchResultRowElement.searchResult = CycleTabsTextSearchResult; + await flush(); + assertEquals( + 'Click or tap shelf icons 1-8', + strictQuery( + '#description', searchResultRowElement.shadowRoot, HTMLDivElement) + .innerText); + + // Create a new TextAccelerator to compare against the one rendered by the + // SearchResultRow. + const textAccelElement = document.createElement('text-accelerator'); + textAccelElement.parts = CycleTabsTextSearchResult.acceleratorInfos[0] + ?.layoutProperties.textAccelerator?.parts!; + document.body.appendChild(textAccelElement); + await flushTasks(); + const searchResultRowTextAccelerator = strictQuery( + 'text-accelerator', searchResultRowElement.shadowRoot, + TextAcceleratorElement); + assertEquals( + textAccelElement.innerHTML, searchResultRowTextAccelerator.innerHTML); + }); });
diff --git a/chrome/test/data/webui/settings/autofill_page_test.ts b/chrome/test/data/webui/settings/autofill_page_test.ts index 91aef55..b16b0131 100644 --- a/chrome/test/data/webui/settings/autofill_page_test.ts +++ b/chrome/test/data/webui/settings/autofill_page_test.ts
@@ -7,7 +7,7 @@ import {DomIf, flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {AutofillManagerImpl, PasswordsSectionElement, PasswordListItemElement, PaymentsManagerImpl, SettingsAutofillSectionElement, SettingsPaymentsSectionElement} from 'chrome://settings/lazy_load.js'; import {buildRouter, Router, routes} from 'chrome://settings/settings.js'; -import {CrSettingsPrefs, OpenWindowProxyImpl, PasswordManagerImpl, SettingsAutofillPageElement, SettingsPluralStringProxyImpl, SettingsPrefsElement, SettingsRoutes} from 'chrome://settings/settings.js'; +import {CrSettingsPrefs, OpenWindowProxyImpl, PasswordManagerImpl, SettingsAutofillPageElement, SettingsPluralStringProxyImpl, SettingsPrefsElement, SettingsRoutes, PasswordManagerPage} from 'chrome://settings/settings.js'; import {assertDeepEquals, assertEquals, assertFalse, assertNotEquals, assertTrue} from 'chrome://webui-test/chai_assert.js'; import {TestPluralStringProxy} from 'chrome://webui-test/test_plural_string_proxy.js'; import {flushTasks} from 'chrome://webui-test/polymer_test_util.js'; @@ -511,8 +511,8 @@ assertTrue(autofillSection.$.passwordManagerButton.external); autofillSection.$.passwordManagerButton.click(); - const url = await openWindowProxy.whenCalled('openUrl'); - assertEquals(url, 'chrome://password-manager'); + const param = await passwordManager.whenCalled('showPasswordManager'); + assertEquals(PasswordManagerPage.PASSWORDS, param); }); test('New Password Manager UI disabled', async function() {
diff --git a/chrome/test/data/webui/settings/chromeos/BUILD.gn b/chrome/test/data/webui/settings/chromeos/BUILD.gn index c0899144..95d05c5 100644 --- a/chrome/test/data/webui/settings/chromeos/BUILD.gn +++ b/chrome/test/data/webui/settings/chromeos/BUILD.gn
@@ -125,7 +125,6 @@ "per_device_keyboard_test.js", "per_device_pointing_stick_subsection_test.js", "per_device_touchpad_subsection_test.js", - "per_device_touchpad_test.js", "personalization_page_with_personalization_hub_test.js", "privacy_hub_subpage_tests.js", "quick_unlock_authenticate_browsertest_chromeos.js", @@ -207,6 +206,7 @@ "device_page/per_device_mouse_subsection_test.ts", "device_page/per_device_mouse_test.ts", "device_page/per_device_pointing_stick_test.ts", + "device_page/per_device_touchpad_test.ts", "internet_page/tether_connection_dialog_test.ts",
diff --git a/chrome/test/data/webui/settings/chromeos/device_page/per_device_touchpad_test.ts b/chrome/test/data/webui/settings/chromeos/device_page/per_device_touchpad_test.ts new file mode 100644 index 0000000..c523affd --- /dev/null +++ b/chrome/test/data/webui/settings/chromeos/device_page/per_device_touchpad_test.ts
@@ -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. + +import {fakeTouchpads, fakeTouchpads2, SettingsPerDeviceTouchpadElement} from 'chrome://os-settings/chromeos/os_settings.js'; +import {assertEquals, assertTrue} from 'chrome://webui-test/chai_assert.js'; +import {flushTasks} from 'chrome://webui-test/polymer_test_util.js'; + +suite('<settings-per-device-touchpad>', () => { + let perDeviceTouchpadPage: SettingsPerDeviceTouchpadElement; + + setup(async () => { + perDeviceTouchpadPage = + document.createElement('settings-per-device-touchpad'); + perDeviceTouchpadPage.set('touchpads', fakeTouchpads); + document.body.appendChild(perDeviceTouchpadPage); + await flushTasks(); + }); + + teardown(() => { + perDeviceTouchpadPage.remove(); + }); + + test('Touchpad page updates with new touchpads', async () => { + let subsections = perDeviceTouchpadPage.shadowRoot!.querySelectorAll( + 'settings-per-device-touchpad-subsection'); + assertEquals(fakeTouchpads.length, subsections.length); + + // Check the number of subsections when the touchpad list is updated. + perDeviceTouchpadPage.set('touchpads', fakeTouchpads2); + await flushTasks(); + subsections = perDeviceTouchpadPage.shadowRoot!.querySelectorAll( + 'settings-per-device-touchpad-subsection'); + assertEquals(fakeTouchpads2.length, subsections.length); + }); + + test( + 'Display correct name used for internal/external touchpads', async () => { + const subsections = perDeviceTouchpadPage.shadowRoot!.querySelectorAll( + 'settings-per-device-touchpad-subsection'); + for (let i = 0; i < subsections.length; i++) { + const name = + subsections[i]!.shadowRoot!.querySelector('h2')!.textContent; + if (fakeTouchpads[i]!.isExternal) { + assertEquals(fakeTouchpads[i]!.name, name); + } else { + assertTrue(subsections[i]!.i18nExists('builtInTouchpadName')); + assertEquals('Built-in Touchpad', name); + } + } + }); +});
diff --git a/chrome/test/data/webui/settings/chromeos/os_settings_v3_browsertest.js b/chrome/test/data/webui/settings/chromeos/os_settings_v3_browsertest.js index 7304a94..3342b79 100644 --- a/chrome/test/data/webui/settings/chromeos/os_settings_v3_browsertest.js +++ b/chrome/test/data/webui/settings/chromeos/os_settings_v3_browsertest.js
@@ -280,6 +280,11 @@ {enabled: ['ash::features::kInputDeviceSettingsSplit']} ], [ + 'DevicePagePerDeviceTouchpad', + 'device_page/per_device_touchpad_test.js', + {enabled: ['ash::features::kInputDeviceSettingsSplit']}, + ], + [ 'DisplayAndMagnificationPage', 'display_and_magnification_page_tests.js', ], @@ -484,11 +489,6 @@ {enabled: ['ash::features::kInputDeviceSettingsSplit']} ], [ - 'PerDeviceTouchpad', - 'per_device_touchpad_test.js', - {enabled: ['ash::features::kInputDeviceSettingsSplit']}, - ], - [ 'PerDeviceTouchpadSubsection', 'per_device_touchpad_subsection_test.js', {enabled: ['ash::features::kInputDeviceSettingsSplit']} ],
diff --git a/chrome/test/data/webui/settings/chromeos/per_device_touchpad_test.js b/chrome/test/data/webui/settings/chromeos/per_device_touchpad_test.js deleted file mode 100644 index 3142373..0000000 --- a/chrome/test/data/webui/settings/chromeos/per_device_touchpad_test.js +++ /dev/null
@@ -1,62 +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 {fakeTouchpads, fakeTouchpads2, SettingsPerDeviceTouchpadElement} from 'chrome://os-settings/chromeos/os_settings.js'; -import {assertTrue} from 'chrome://webui-test/chai_assert.js'; -import {flushTasks} from 'chrome://webui-test/polymer_test_util.js'; - -suite('PerDeviceTouchpad', function() { - /** - * @type {?SettingsPerDeviceTouchpadElement} - */ - let perDeviceTouchpadPage = null; - - setup(() => { - PolymerTest.clearBody(); - }); - - teardown(() => { - perDeviceTouchpadPage = null; - }); - - function initializePerDeviceTouchpadPage(touchpads = fakeTouchpads) { - perDeviceTouchpadPage = - document.createElement('settings-per-device-touchpad'); - assertTrue(perDeviceTouchpadPage != null); - perDeviceTouchpadPage.touchpads = touchpads; - document.body.appendChild(perDeviceTouchpadPage); - return flushTasks(); - } - - test('Touchpad page updates with new touchpads', async () => { - await initializePerDeviceTouchpadPage(); - let subsections = perDeviceTouchpadPage.shadowRoot.querySelectorAll( - 'settings-per-device-touchpad-subsection'); - assertEquals(fakeTouchpads.length, subsections.length); - - // Check the number of subsections when the touchpad list is updated. - perDeviceTouchpadPage.touchpads = fakeTouchpads2; - await flushTasks(); - subsections = perDeviceTouchpadPage.shadowRoot.querySelectorAll( - 'settings-per-device-touchpad-subsection'); - assertEquals(fakeTouchpads2.length, subsections.length); - }); - - test( - 'Display correct name used for internal/external touchpads', async () => { - await initializePerDeviceTouchpadPage(); - const subsections = perDeviceTouchpadPage.shadowRoot.querySelectorAll( - 'settings-per-device-touchpad-subsection'); - for (let i = 0; i < subsections.length; i++) { - const name = - subsections[i].shadowRoot.querySelector('h2').textContent; - if (fakeTouchpads[i].isExternal) { - assertEquals(fakeTouchpads[i].name, name); - } else { - assertTrue(subsections[i].i18nExists('builtInTouchpadName')); - assertEquals('Built-in Touchpad', name); - } - } - }); -});
diff --git a/chrome/test/data/webui/settings/test_password_manager_proxy.ts b/chrome/test/data/webui/settings/test_password_manager_proxy.ts index 171ce12b..f66fedb 100644 --- a/chrome/test/data/webui/settings/test_password_manager_proxy.ts +++ b/chrome/test/data/webui/settings/test_password_manager_proxy.ts
@@ -5,7 +5,7 @@ /** @fileoverview Test implementation of PasswordManagerProxy. */ // clang-format off -import {AccountStorageOptInStateChangedListener, CredentialsChangedListener, HatsBrowserProxyImpl, PasswordCheckInteraction, PasswordCheckReferrer, PasswordCheckStatusChangedListener, PasswordExceptionListChangedListener, PasswordManagerProxy, PasswordsFileExportProgressListener, PasswordManagerAuthTimeoutListener, SavedPasswordListChangedListener, TrustSafetyInteraction} from 'chrome://settings/settings.js'; +import {AccountStorageOptInStateChangedListener, CredentialsChangedListener, HatsBrowserProxyImpl, PasswordCheckInteraction, PasswordCheckReferrer, PasswordCheckStatusChangedListener, PasswordExceptionListChangedListener, PasswordManagerProxy, PasswordsFileExportProgressListener, PasswordManagerAuthTimeoutListener, PasswordManagerPage, SavedPasswordListChangedListener, TrustSafetyInteraction} from 'chrome://settings/settings.js'; import {assertEquals} from 'chrome://webui-test/chai_assert.js'; import {TestBrowserProxy} from 'chrome://webui-test/test_browser_proxy.js'; @@ -116,6 +116,7 @@ 'recordChangePasswordFlowStarted', 'recordPasswordCheckInteraction', 'recordPasswordCheckReferrer', + 'showPasswordManager', 'removeException', 'removeSavedPassword', 'requestExportProgressStatus', @@ -444,5 +445,9 @@ this.methodCalled('switchBiometricAuthBeforeFillingState'); } + showPasswordManager(page: PasswordManagerPage) { + this.methodCalled('showPasswordManager', page); + } + undoRemoveSavedPasswordOrException() {} }
diff --git a/chrome/updater/BUILD.gn b/chrome/updater/BUILD.gn index d5fa1a8..3caa0307 100644 --- a/chrome/updater/BUILD.gn +++ b/chrome/updater/BUILD.gn
@@ -824,6 +824,7 @@ sources += [ "mac/keystone/ksadmin_unittest.cc", "mac/privileged_helper/privileged_helper_unittests.mm", + "mac/setup/keystone_unittest.cc", "mac/setup/ks_tickets_unittest.mm", "mac/setup/setup_unittest.mm", "policy/mac/managed_preference_policy_manager_impl_unittest.mm", @@ -841,6 +842,7 @@ ] data += [ + "//chrome/test/data/updater/CountingMetrics.plist", "//chrome/test/data/updater/Keystone.ticketstore", "//chrome/test/data/updater/Keystone.withlaunchservicechecker.ticketstore", "//chrome/test/data/updater/Keystone.legacy.ticketstore",
diff --git a/chrome/updater/app/server/posix/app_server_posix_mac.cc b/chrome/updater/app/server/posix/app_server_posix_mac.cc index 713915e4..5f445ad 100644 --- a/chrome/updater/app/server/posix/app_server_posix_mac.cc +++ b/chrome/updater/app/server/posix/app_server_posix_mac.cc
@@ -8,6 +8,7 @@ #include "base/memory/scoped_refptr.h" #include "chrome/updater/mac/setup/keystone.h" #include "chrome/updater/registration_data.h" +#include "chrome/updater/util/mac_util.h" namespace updater { @@ -15,7 +16,8 @@ base::RepeatingCallback<void(const RegistrationRequest&)> register_callback) { // TODO(crbug.com/1250524): This must not run concurrently with Keystone. - MigrateKeystoneTickets(updater_scope(), register_callback); + MigrateKeystoneApps(GetKeystoneFolderPath(updater_scope()).value(), + register_callback); return true; }
diff --git a/chrome/updater/mac/setup/keystone.h b/chrome/updater/mac/setup/keystone.h index 8c74044..13b8f046 100644 --- a/chrome/updater/mac/setup/keystone.h +++ b/chrome/updater/mac/setup/keystone.h
@@ -5,12 +5,13 @@ #ifndef CHROME_UPDATER_MAC_SETUP_KEYSTONE_H_ #define CHROME_UPDATER_MAC_SETUP_KEYSTONE_H_ -#include <string> -#include <vector> - #include "base/functional/callback_forward.h" #include "chrome/updater/updater_scope.h" +namespace base { +class FilePath; +} // namespace base + namespace updater { struct RegistrationRequest; @@ -24,18 +25,11 @@ // `Calls register_callback` with data from Keystone's ticket store if needed. // This is a best-effort operation, tickets with errors are not migrated. -void MigrateKeystoneTickets( - UpdaterScope scope, +void MigrateKeystoneApps( + const base::FilePath& keystone_path, base::RepeatingCallback<void(const RegistrationRequest&)> register_callback); -namespace internal { - -std::vector<RegistrationRequest> TicketsToMigrate( - const std::string& ksadmin_tickets); - -} // namespace internal - } // namespace updater #endif // CHROME_UPDATER_MAC_SETUP_KEYSTONE_H_
diff --git a/chrome/updater/mac/setup/keystone.mm b/chrome/updater/mac/setup/keystone.mm index 89bb729..17746d35 100644 --- a/chrome/updater/mac/setup/keystone.mm +++ b/chrome/updater/mac/setup/keystone.mm
@@ -15,6 +15,7 @@ #include "base/logging.h" #include "base/mac/bundle_locations.h" #include "base/mac/foundation_util.h" +#include "base/mac/scoped_nsobject.h" #include "base/process/launch.h" #include "base/process/process.h" #include "base/strings/string_split.h" @@ -30,6 +31,81 @@ #include "chrome/updater/util/util.h" #include "third_party/abseil-cpp/absl/types/optional.h" +// Class to read the Keystone apps' client-regulated-counting data. +@interface CountingMetricsStore : NSObject { + base::scoped_nsobject<NSDictionary<NSString*, NSDictionary<NSString*, id>*>> + _metrics; +} + ++ (instancetype)storeAtPath:(const base::FilePath&)path; + +- (absl::optional<int>)dateLastActiveForApp:(NSString*)appid; +- (absl::optional<int>)dateLastRollcallForApp:(NSString*)appid; + +@end + +@implementation CountingMetricsStore + ++ (instancetype)storeAtPath:(const base::FilePath&)path { + return [[[CountingMetricsStore alloc] + initWithURL:[base::mac::FilePathToNSURL(path) + URLByAppendingPathComponent:@"CountingMetrics.plist"]] + autorelease]; +} + +- (instancetype)initWithURL:(NSURL*)url { + if ((self = [super init])) { + NSError* error = nil; + _metrics.reset([[NSDictionary alloc] initWithContentsOfURL:url + error:&error]); + + if (error) { + LOG(WARNING) << "Failed to read client-regulated-counting data."; + [self release]; + return nil; + } + } + return self; +} + +- (absl::optional<int>)daynumValueOfKey:(NSString*)key forApp:(NSString*)appid { + id appObject = [_metrics objectForKey:appid.lowercaseString]; + if (![appObject isKindOfClass:[NSDictionary class]]) { + LOG(WARNING) << "Malformed input client-regulated-counting data."; + return absl::nullopt; + } + + id daynumObject = appObject[key]; + if (!daynumObject) { + return absl::nullopt; + } + + if (![daynumObject isKindOfClass:[NSNumber class]]) { + LOG(WARNING) << "daynum is not a number."; + return absl::nullopt; + } + + // daynum the number of days since January 1, 2007. The accepted range is + // between 3000 (maps to Mar 20, 2015) and 50000 (maps to Nov 24, 2143). + int daynum = [daynumObject intValue]; + if (daynum < 3000 || daynum > 50000) { + LOG(WARNING) << "Ignored out-of-range daynum: " << daynum; + return absl::nullopt; + } + + return daynum; +} + +- (absl::optional<int>)dateLastActiveForApp:(NSString*)appid { + return [self daynumValueOfKey:@"DayOfLastActive" forApp:appid]; +} + +- (absl::optional<int>)dateLastRollcallForApp:(NSString*)appid { + return [self daynumValueOfKey:@"DayOfLastRollcall" forApp:appid]; +} + +@end + namespace updater { namespace { @@ -204,19 +280,22 @@ } } -void MigrateKeystoneTickets( - UpdaterScope scope, +void MigrateKeystoneApps( + const base::FilePath& keystone_path, base::RepeatingCallback<void(const RegistrationRequest&)> register_callback) { @autoreleasepool { NSDictionary<NSString*, KSTicket*>* store = [KSTicketStore readStoreWithPath:base::SysUTF8ToNSString( - GetKeystoneFolderPath(scope) - ->Append(FILE_PATH_LITERAL("TicketStore")) + keystone_path + .Append(FILE_PATH_LITERAL("TicketStore")) .Append( FILE_PATH_LITERAL("Keystone.ticketstore")) .AsUTF8Unsafe())]; + CountingMetricsStore* metrics_store = + [CountingMetricsStore storeAtPath:keystone_path]; + for (NSString* key in store) { KSTicket* ticket = [store objectForKey:key]; @@ -248,6 +327,10 @@ continue; } + registration.dla = [metrics_store dateLastActiveForApp:ticket.productID]; + registration.dlrc = + [metrics_store dateLastRollcallForApp:ticket.productID]; + register_callback.Run(registration); } }
diff --git a/chrome/updater/mac/setup/keystone_unittest.cc b/chrome/updater/mac/setup/keystone_unittest.cc new file mode 100644 index 0000000..625f8ce --- /dev/null +++ b/chrome/updater/mac/setup/keystone_unittest.cc
@@ -0,0 +1,88 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/updater/mac/setup/keystone.h" + +#include <vector> + +#include "base/files/file_path.h" +#include "base/files/file_util.h" +#include "base/files/scoped_temp_dir.h" +#include "base/path_service.h" +#include "base/test/bind.h" +#include "base/version.h" +#include "chrome/common/chrome_paths.h" +#include "chrome/updater/registration_data.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace updater { + +class KeystoneTest : public testing::Test { + public: + ~KeystoneTest() override = default; + + void SetUp() override { + ASSERT_TRUE(temp_keystone_dir_.CreateUniqueTempDir()); + + base::FilePath ticket_path = + temp_keystone_dir_.GetPath().AppendASCII("TicketStore"); + ASSERT_TRUE(base::CreateDirectory(ticket_path)); + + base::FilePath test_data_path; + ASSERT_TRUE(base::PathService::Get(chrome::DIR_TEST_DATA, &test_data_path)); + test_data_path = test_data_path.AppendASCII("updater"); + + ASSERT_TRUE(base::CopyFile( + test_data_path.AppendASCII("Keystone.legacy.ticketstore"), + ticket_path.AppendASCII("Keystone.ticketstore"))); + ASSERT_TRUE(base::CopyFile( + test_data_path.AppendASCII("CountingMetrics.plist"), + temp_keystone_dir_.GetPath().AppendASCII("CountingMetrics.plist"))); + } + + protected: + base::ScopedTempDir temp_keystone_dir_; +}; + +TEST_F(KeystoneTest, MigrateKeystoneApps) { + std::vector<RegistrationRequest> registration_requests; + MigrateKeystoneApps( + temp_keystone_dir_.GetPath(), + base::BindLambdaForTesting( + [®istration_requests](const RegistrationRequest& request) { + registration_requests.push_back(request); + })); + + EXPECT_EQ(registration_requests.size(), 3u); + + EXPECT_EQ(registration_requests[0].app_id, "com.chromium.CorruptedApp"); + EXPECT_TRUE(registration_requests[0].brand_code.empty()); + EXPECT_TRUE(registration_requests[0].brand_path.empty()); + EXPECT_EQ(registration_requests[0].ap, "canary"); + EXPECT_EQ(registration_requests[0].version, base::Version("1.2.1")); + EXPECT_EQ(registration_requests[0].existence_checker_path, + base::FilePath("/")); + EXPECT_FALSE(registration_requests[0].dla); // Value is too big. + EXPECT_FALSE(registration_requests[0].dlrc); // Value is too small. + + EXPECT_EQ(registration_requests[1].app_id, "com.chromium.PopularApp"); + EXPECT_TRUE(registration_requests[1].brand_code.empty()); + EXPECT_EQ(registration_requests[1].brand_path, base::FilePath("/")); + EXPECT_EQ(registration_requests[1].ap, "GOOG"); + EXPECT_EQ(registration_requests[1].version, + base::Version("101.100.1000.9999")); + EXPECT_EQ(registration_requests[1].existence_checker_path, + base::FilePath("/")); + EXPECT_EQ(registration_requests[1].dla.value(), 5921); + EXPECT_EQ(registration_requests[1].dlrc.value(), 5922); + + EXPECT_EQ(registration_requests[2].app_id, "com.chromium.kipple"); + EXPECT_TRUE(registration_requests[2].brand_path.empty()); + EXPECT_EQ(registration_requests[2].existence_checker_path, + base::FilePath("/")); + EXPECT_FALSE(registration_requests[2].dla); // No data. + EXPECT_FALSE(registration_requests[2].dlrc); // String value is ignored. +} + +} // namespace updater
diff --git a/chrome/updater/persisted_data.cc b/chrome/updater/persisted_data.cc index 9dae89f..bc48822 100644 --- a/chrome/updater/persisted_data.cc +++ b/chrome/updater/persisted_data.cc
@@ -4,6 +4,7 @@ #include "chrome/updater/persisted_data.h" +#include <string> #include <vector> #include "base/base64.h" @@ -35,12 +36,14 @@ namespace { -constexpr char kPV[] = "pv"; // Key for storing product version. -constexpr char kFP[] = "fp"; // Key for storing fingerprint. -constexpr char kECP[] = "ecp"; // Key for storing existence checker path. -constexpr char kBC[] = "bc"; // Key for storing brand code. -constexpr char kBP[] = "bp"; // Key for storing brand path. -constexpr char kAP[] = "ap"; // Key for storing ap. +constexpr char kPV[] = "pv"; // Key for storing product version. +constexpr char kFP[] = "fp"; // Key for storing fingerprint. +constexpr char kECP[] = "ecp"; // Key for storing existence checker path. +constexpr char kBC[] = "bc"; // Key for storing brand code. +constexpr char kBP[] = "bp"; // Key for storing brand path. +constexpr char kAP[] = "ap"; // Key for storing ap. +constexpr char kDLA[] = "dla"; // Key for storing date-last-active. +constexpr char kDLRC[] = "dlrc"; // Key for storing date-last-rollcall. constexpr char kHadApps[] = "had_apps"; constexpr char kUsageStatsEnabledKey[] = "usage_stats_enabled"; @@ -145,6 +148,16 @@ #endif } +void PersistedData::SetDateLastActive(const std::string& id, int dla) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + SetInteger(id, kDLA, dla); +} + +void PersistedData::SetDateLastRollcall(const std::string& id, int dlrc) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + SetInteger(id, kDLRC, dlrc); +} + void PersistedData::RegisterApp(const RegistrationRequest& rq) { VLOG(2) << __func__ << ": Registering " << rq.app_id << " at version " << rq.version; @@ -163,6 +176,12 @@ if (!rq.ap.empty()) { SetAP(rq.app_id, rq.ap); } + if (rq.dla) { + SetDateLastActive(rq.app_id, rq.dla.value()); + } + if (rq.dlrc) { + SetDateLastRollcall(rq.app_id, rq.dlrc.value()); + } } bool PersistedData::RemoveApp(const std::string& id) { @@ -230,6 +249,18 @@ return app; } +void PersistedData::SetInteger(const std::string& id, + const std::string& key, + int value) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + if (!pref_service_) { + return; + } + ScopedDictPrefUpdate update(pref_service_, + update_client::kPersistedDataPreference); + GetOrCreateAppKey(id, update.Get())->Set(key, value); +} + void PersistedData::SetString(const std::string& id, const std::string& key, const std::string& value) {
diff --git a/chrome/updater/persisted_data.h b/chrome/updater/persisted_data.h index 7f25c13..656362051 100644 --- a/chrome/updater/persisted_data.h +++ b/chrome/updater/persisted_data.h
@@ -74,6 +74,11 @@ std::string GetAP(const std::string& id) const; void SetAP(const std::string& id, const std::string& ap); + // These functions set the client-regulated-counting data for the specified + // id. The functions are for app migration only. + void SetDateLastActive(const std::string& id, int dla); + void SetDateLastRollcall(const std::string& id, int dlrc); + // This function sets any non-empty field in the registration request object // into the persistent data store. void RegisterApp(const RegistrationRequest& rq); @@ -129,6 +134,7 @@ base::Value::Dict* GetOrCreateAppKey(const std::string& id, base::Value::Dict& root); + void SetInteger(const std::string& id, const std::string& key, int value); std::string GetString(const std::string& id, const std::string& key) const; void SetString(const std::string& id, const std::string& key,
diff --git a/chrome/updater/registration_data.h b/chrome/updater/registration_data.h index a659ceef..970bb544 100644 --- a/chrome/updater/registration_data.h +++ b/chrome/updater/registration_data.h
@@ -10,6 +10,7 @@ #include "base/files/file_path.h" #include "base/version.h" #include "chrome/updater/constants.h" +#include "third_party/abseil-cpp/absl/types/optional.h" namespace updater { @@ -47,6 +48,12 @@ // whether an app has been uninstalled via deletion. May be the empty // string; if so, the app is assumed to be installed unconditionally. base::FilePath existence_checker_path; + + // Date-last-active. The value is the number of days since Jan 1, 2007. + absl::optional<int> dla; + + // Date-last-rollcall. The value is the number of days since Jan 1, 2007. + absl::optional<int> dlrc; }; } // namespace updater
diff --git a/chromeos/CHROMEOS_LKGM b/chromeos/CHROMEOS_LKGM index d1bb1ff..1343102d 100644 --- a/chromeos/CHROMEOS_LKGM +++ b/chromeos/CHROMEOS_LKGM
@@ -1 +1 @@ -15398.0.0 \ No newline at end of file +15399.0.0 \ No newline at end of file
diff --git a/chromeos/ash/components/audio/cras_audio_handler.cc b/chromeos/ash/components/audio/cras_audio_handler.cc index 2b1e511..b2f3781 100644 --- a/chromeos/ash/components/audio/cras_audio_handler.cc +++ b/chromeos/ash/components/audio/cras_audio_handler.cc
@@ -18,6 +18,7 @@ #include "base/functional/bind.h" #include "base/functional/callback_helpers.h" #include "base/logging.h" +#include "base/metrics/histogram_functions.h" #include "base/strings/utf_string_conversions.h" #include "base/system/sys_info.h" #include "base/system/system_monitor.h" @@ -860,6 +861,14 @@ observer.OnOutputMuteChanged(output_mute_on_); } +void CrasAudioHandler::SetOutputMute( + bool mute_on, + CrasAudioHandler::AudioSettingsChangeSource source) { + SetOutputMute(mute_on); + base::UmaHistogramEnumeration( + CrasAudioHandler::kOutputVolumeMuteSourceHistogramName, source); +} + void CrasAudioHandler::SetOutputMuteLockedBySecurityCurtain(bool mute_on) { if (output_mute_forced_by_security_curtain_ == mute_on) return; @@ -904,6 +913,15 @@ } } +void CrasAudioHandler::SetInputMute( + bool mute_on, + InputMuteChangeMethod method, + CrasAudioHandler::AudioSettingsChangeSource source) { + SetInputMute(mute_on, method); + base::UmaHistogramEnumeration( + CrasAudioHandler::kInputGainMuteSourceHistogramName, source); +} + void CrasAudioHandler::SetActiveDevice(const AudioDevice& active_device, bool notify, DeviceActivateType activate_by) { @@ -1006,6 +1024,20 @@ audio_pref_handler_->SetMuteValue(*device, mute_on); } +void CrasAudioHandler::SetMuteForDevice( + uint64_t device_id, + bool mute_on, + CrasAudioHandler::AudioSettingsChangeSource source) { + SetMuteForDevice(device_id, mute_on); + if (device_id == active_output_node_id_) { + base::UmaHistogramEnumeration( + CrasAudioHandler::kOutputVolumeMuteSourceHistogramName, source); + } else if (device_id == active_input_node_id_) { + base::UmaHistogramEnumeration( + CrasAudioHandler::kInputGainMuteSourceHistogramName, source); + } +} + // If the HDMI device is the active output device, when the device enters/exits // docking mode, or HDMI display changes resolution, or chromeos device // suspends/resumes, cras will lose the HDMI output node for a short period of
diff --git a/chromeos/ash/components/audio/cras_audio_handler.h b/chromeos/ash/components/audio/cras_audio_handler.h index ad69c770..54d36503 100644 --- a/chromeos/ash/components/audio/cras_audio_handler.h +++ b/chromeos/ash/components/audio/cras_audio_handler.h
@@ -97,8 +97,12 @@ base::Seconds(2); static constexpr char kInputGainChangedSourceHistogramName[] = "Cras.InputGainChangedSource"; + static constexpr char kInputGainMuteSourceHistogramName[] = + "Cras.InputGainMutedSource"; static constexpr char kOutputVolumeChangedSourceHistogramName[] = "Cras.OutputVolumeChangedSource"; + static constexpr char kOutputVolumeMuteSourceHistogramName[] = + "Cras.OutputVolumeMutedSource"; class AudioObserver { public: @@ -379,12 +383,23 @@ // Mutes or unmutes audio output device. void SetOutputMute(bool mute_on); + // Mutes or unmutes audio output device including the `source` to record to + // metrics. + void SetOutputMute(bool mute_on, + CrasAudioHandler::AudioSettingsChangeSource source); + // Mutes or unmutes audio output device by security curtain void SetOutputMuteLockedBySecurityCurtain(bool mute_on); // Mutes or unmutes audio input device. void SetInputMute(bool mute_on, InputMuteChangeMethod method); + // Mutes or unmutes audio input device including the `source` to record to + // metrics. + void SetInputMute(bool mute_on, + InputMuteChangeMethod method, + CrasAudioHandler::AudioSettingsChangeSource source); + // Switches active audio device to |device|. |activate_by| indicates why // the device is switched to active: by user's manual choice, by priority, // or by restoring to its previous active state. @@ -398,6 +413,11 @@ // Sets the mute for device. void SetMuteForDevice(uint64_t device_id, bool mute_on); + // Sets the mute for device including the `source` to record to metrics. + void SetMuteForDevice(uint64_t device_id, + bool mute_on, + CrasAudioHandler::AudioSettingsChangeSource source); + // Activates or deactivates keyboard mic if there's one. void SetKeyboardMicActive(bool active);
diff --git a/chromeos/ash/components/audio/cras_audio_handler_unittest.cc b/chromeos/ash/components/audio/cras_audio_handler_unittest.cc index fee4cf4..b526dc0 100644 --- a/chromeos/ash/components/audio/cras_audio_handler_unittest.cc +++ b/chromeos/ash/components/audio/cras_audio_handler_unittest.cc
@@ -15,6 +15,7 @@ #include "base/run_loop.h" #include "base/system/system_monitor.h" #include "base/task/single_thread_task_runner.h" +#include "base/test/metrics/histogram_tester.h" #include "base/test/task_environment.h" #include "base/values.h" #include "chromeos/ash/components/audio/audio_devices_pref_handler.h" @@ -569,6 +570,7 @@ scoped_refptr<AudioDevicesPrefHandlerStub> audio_pref_handler_; std::unique_ptr<FakeMediaControllerManager> fake_manager_; std::unique_ptr<FakeVideoCaptureManager> video_capture_manager_; + base::HistogramTester histogram_tester_; }; class HDMIRediscoverWaiter { @@ -2173,6 +2175,25 @@ EXPECT_FALSE(audio_pref_handler_->GetMuteValue(speaker)); } +TEST_P(CrasAudioHandlerTest, SetOutputMuteWithSource) { + AudioNodeList audio_nodes = GenerateAudioNodeList({kInternalSpeaker}); + SetUpCrasAudioHandler(audio_nodes); + histogram_tester_.ExpectBucketCount( + CrasAudioHandler::kOutputVolumeMuteSourceHistogramName, + CrasAudioHandler::AudioSettingsChangeSource::kSystemTray, + /*expected_count=*/0); + + // Mute the device. + cras_audio_handler_->SetOutputMute( + true, CrasAudioHandler::AudioSettingsChangeSource::kSystemTray); + + // Verify mute source is recorded. + histogram_tester_.ExpectBucketCount( + CrasAudioHandler::kOutputVolumeMuteSourceHistogramName, + CrasAudioHandler::AudioSettingsChangeSource::kSystemTray, + /*expected_count=*/1); +} + TEST_P(CrasAudioHandlerTest, SetInputMute) { AudioNodeList audio_nodes = GenerateAudioNodeList({kInternalMic}); SetUpCrasAudioHandler(audio_nodes); @@ -2195,6 +2216,26 @@ EXPECT_EQ(2, test_observer_->input_mute_changed_count()); } +TEST_P(CrasAudioHandlerTest, SetInputMuteWithSource) { + AudioNodeList audio_nodes = GenerateAudioNodeList({kInternalMic}); + SetUpCrasAudioHandler(audio_nodes); + histogram_tester_.ExpectBucketCount( + CrasAudioHandler::kInputGainMuteSourceHistogramName, + CrasAudioHandler::AudioSettingsChangeSource::kSystemTray, + /*expected_count=*/0); + + // Mute the device. + cras_audio_handler_->SetInputMute( + true, CrasAudioHandler::InputMuteChangeMethod::kOther, + CrasAudioHandler::AudioSettingsChangeSource::kSystemTray); + + // Verify mute source is recorded. + histogram_tester_.ExpectBucketCount( + CrasAudioHandler::kInputGainMuteSourceHistogramName, + CrasAudioHandler::AudioSettingsChangeSource::kSystemTray, + /*expected_count=*/1); +} + TEST_P(CrasAudioHandlerTest, SetOutputVolumePercent) { AudioNodeList audio_nodes = GenerateAudioNodeList({kInternalSpeaker}); SetUpCrasAudioHandler(audio_nodes);
diff --git a/chromeos/ash/components/audio/cros_audio_config_impl.cc b/chromeos/ash/components/audio/cros_audio_config_impl.cc index 9374296..4f5756e8 100644 --- a/chromeos/ash/components/audio/cros_audio_config_impl.cc +++ b/chromeos/ash/components/audio/cros_audio_config_impl.cc
@@ -241,7 +241,8 @@ return; } - audio_handler->SetOutputMute(muted); + audio_handler->SetOutputMute( + muted, CrasAudioHandler::AudioSettingsChangeSource::kOsSettings); RecordMuteStateChanged(kOutputMuteChangeHistogramName, muted); } @@ -316,8 +317,9 @@ return; } - audio_handler->SetMuteForDevice(audio_handler->GetPrimaryActiveInputNode(), - muted); + audio_handler->SetMuteForDevice( + audio_handler->GetPrimaryActiveInputNode(), muted, + CrasAudioHandler::AudioSettingsChangeSource::kOsSettings); RecordMuteStateChanged(kInputMuteChangeHistogramName, muted); }
diff --git a/chromeos/ash/components/audio/cros_audio_config_impl_unittest.cc b/chromeos/ash/components/audio/cros_audio_config_impl_unittest.cc index a37e0ae..c91d042 100644 --- a/chromeos/ash/components/audio/cros_audio_config_impl_unittest.cc +++ b/chromeos/ash/components/audio/cros_audio_config_impl_unittest.cc
@@ -883,6 +883,9 @@ AudioMuteButtonAction::kMuted, 1); histogram_tester_.ExpectBucketCount(kOutputMuteChangeHistogramName, AudioMuteButtonAction::kUnmuted, 1); + histogram_tester_.ExpectBucketCount( + CrasAudioHandler::kOutputVolumeMuteSourceHistogramName, + CrasAudioHandler::AudioSettingsChangeSource::kOsSettings, 2); } TEST_F(CrosAudioConfigImplTest, SetInputMuted) { @@ -909,6 +912,9 @@ AudioMuteButtonAction::kMuted, 1); histogram_tester_.ExpectBucketCount(kInputMuteChangeHistogramName, AudioMuteButtonAction::kUnmuted, 1); + histogram_tester_.ExpectBucketCount( + CrasAudioHandler::kInputGainMuteSourceHistogramName, + CrasAudioHandler::AudioSettingsChangeSource::kOsSettings, 2); // Simulate turning physical switch on. SetInputMuteState(mojom::MuteState::kMutedExternally, /*switch_on=*/true); @@ -931,6 +937,9 @@ AudioMuteButtonAction::kMuted, 1); histogram_tester_.ExpectBucketCount(kInputMuteChangeHistogramName, AudioMuteButtonAction::kUnmuted, 1); + histogram_tester_.ExpectBucketCount( + CrasAudioHandler::kInputGainMuteSourceHistogramName, + CrasAudioHandler::AudioSettingsChangeSource::kOsSettings, 2); } // Verify merging front and rear mic into a single device returns expected
diff --git a/chromeos/ash/components/dbus/featured/BUILD.gn b/chromeos/ash/components/dbus/featured/BUILD.gn index e07a157..5061483 100644 --- a/chromeos/ash/components/dbus/featured/BUILD.gn +++ b/chromeos/ash/components/dbus/featured/BUILD.gn
@@ -11,8 +11,8 @@ defines = [ "IS_CHROMEOS_ASH_COMPONENTS_DBUS_FEATURED_IMPL" ] deps = [ + ":proto", "//base", - "//components/variations/proto:cros_safe_seed_proto", "//dbus", ] @@ -29,9 +29,9 @@ deps = [ ":featured", + ":proto", "//base", "//base/test:test_support", - "//components/variations/proto:cros_safe_seed_proto", "//dbus", "//dbus:test_support", "//testing/gmock", @@ -40,3 +40,9 @@ sources = [ "featured_client_unittest.cc" ] } + +proto_library("proto") { + sources = [ "//third_party/cros_system_api/dbus/featured/featured.proto" ] + + proto_out_dir = "chromeos/ash/components/dbus/featured" +}
diff --git a/chromeos/ash/components/dbus/featured/DEPS b/chromeos/ash/components/dbus/featured/DEPS deleted file mode 100644 index ab865764..0000000 --- a/chromeos/ash/components/dbus/featured/DEPS +++ /dev/null
@@ -1,3 +0,0 @@ -include_rules = [ - "+components/variations/proto/cros_safe_seed.pb.h", -]
diff --git a/chromeos/ash/components/dbus/featured/fake_featured_client.cc b/chromeos/ash/components/dbus/featured/fake_featured_client.cc index bd5a2d9..73e233ca 100644 --- a/chromeos/ash/components/dbus/featured/fake_featured_client.cc +++ b/chromeos/ash/components/dbus/featured/fake_featured_client.cc
@@ -8,7 +8,7 @@ #include "base/check_op.h" #include "base/functional/callback.h" -#include "components/variations/proto/cros_safe_seed.pb.h" +#include "chromeos/ash/components/dbus/featured/featured.pb.h" #include "dbus/object_proxy.h" namespace ash::featured { @@ -40,7 +40,7 @@ } void FakeFeaturedClient::HandleSeedFetched( - const variations::SeedDetails& safe_seed, + const ::featured::SeedDetails& safe_seed, base::OnceCallback<void(bool success)> callback) { std::move(callback).Run(success_); }
diff --git a/chromeos/ash/components/dbus/featured/fake_featured_client.h b/chromeos/ash/components/dbus/featured/fake_featured_client.h index 4182c10..2f204470 100644 --- a/chromeos/ash/components/dbus/featured/fake_featured_client.h +++ b/chromeos/ash/components/dbus/featured/fake_featured_client.h
@@ -7,8 +7,8 @@ #include "base/component_export.h" #include "base/functional/callback.h" +#include "chromeos/ash/components/dbus/featured/featured.pb.h" #include "chromeos/ash/components/dbus/featured/featured_client.h" -#include "components/variations/proto/cros_safe_seed.pb.h" namespace ash::featured { @@ -31,7 +31,7 @@ // |callback| is run with true by default. Call |SetCallbackSuccess| // to change the callback parameter. void HandleSeedFetched( - const variations::SeedDetails& safe_seed, + const ::featured::SeedDetails& safe_seed, base::OnceCallback<void(bool success)> callback) override; private:
diff --git a/chromeos/ash/components/dbus/featured/featured_client.cc b/chromeos/ash/components/dbus/featured/featured_client.cc index 47ab378..3e53148 100644 --- a/chromeos/ash/components/dbus/featured/featured_client.cc +++ b/chromeos/ash/components/dbus/featured/featured_client.cc
@@ -9,7 +9,7 @@ #include <base/logging.h> #include "base/functional/callback.h" #include "chromeos/ash/components/dbus/featured/fake_featured_client.h" -#include "components/variations/proto/cros_safe_seed.pb.h" +#include "chromeos/ash/components/dbus/featured/featured.pb.h" #include "dbus/bus.h" #include "dbus/message.h" #include "dbus/object_proxy.h" @@ -50,7 +50,7 @@ } void HandleSeedFetched( - const variations::SeedDetails& safe_seed, + const ::featured::SeedDetails& safe_seed, base::OnceCallback<void(bool success)> callback) override { dbus::MethodCall method_call(::featured::kFeaturedInterface, "HandleSeedFetched");
diff --git a/chromeos/ash/components/dbus/featured/featured_client.h b/chromeos/ash/components/dbus/featured/featured_client.h index fa91923..419500b 100644 --- a/chromeos/ash/components/dbus/featured/featured_client.h +++ b/chromeos/ash/components/dbus/featured/featured_client.h
@@ -7,7 +7,7 @@ #include "base/component_export.h" #include "base/functional/callback.h" -#include "components/variations/proto/cros_safe_seed.pb.h" +#include "chromeos/ash/components/dbus/featured/featured.pb.h" namespace dbus { class Bus; @@ -37,7 +37,7 @@ // Asynchronously calls featured's `HandleSeedFetched`. virtual void HandleSeedFetched( - const variations::SeedDetails& safe_seed, + const ::featured::SeedDetails& safe_seed, base::OnceCallback<void(bool success)> callback) = 0; protected:
diff --git a/chromeos/ash/components/dbus/featured/featured_client_unittest.cc b/chromeos/ash/components/dbus/featured/featured_client_unittest.cc index 967e4fdf..783e74b 100644 --- a/chromeos/ash/components/dbus/featured/featured_client_unittest.cc +++ b/chromeos/ash/components/dbus/featured/featured_client_unittest.cc
@@ -6,7 +6,7 @@ #include "base/check_op.h" #include "base/test/bind.h" #include "chromeos/ash/components/dbus/featured/fake_featured_client.h" -#include "components/variations/proto/cros_safe_seed.pb.h" +#include "chromeos/ash/components/dbus/featured/featured.pb.h" #include "dbus/message.h" #include "dbus/mock_bus.h" #include "dbus/mock_object_proxy.h" @@ -92,7 +92,7 @@ ASSERT_NE(client, nullptr); - variations::SeedDetails safe_seed; + ::featured::SeedDetails safe_seed; bool ran_callback = false; client->HandleSeedFetched( @@ -128,7 +128,7 @@ ASSERT_NE(client, nullptr); - variations::SeedDetails safe_seed; + ::featured::SeedDetails safe_seed; bool ran_callback = false; client->HandleSeedFetched( @@ -159,7 +159,7 @@ ASSERT_NE(client, nullptr); - variations::SeedDetails safe_seed; + ::featured::SeedDetails safe_seed; bool ran_callback = false; client->HandleSeedFetched( @@ -183,7 +183,7 @@ ASSERT_NE(client, nullptr); - variations::SeedDetails safe_seed; + ::featured::SeedDetails safe_seed; bool ran_callback = false; client->HandleSeedFetched( @@ -207,7 +207,7 @@ ASSERT_NE(client, nullptr); - variations::SeedDetails safe_seed; + ::featured::SeedDetails safe_seed; client->SetCallbackSuccess(false); bool ran_callback = false;
diff --git a/chromeos/services/network_config/OWNERS b/chromeos/services/network_config/OWNERS index 2abc848..ae7fad83 100644 --- a/chromeos/services/network_config/OWNERS +++ b/chromeos/services/network_config/OWNERS
@@ -1,4 +1,3 @@ -azeemarshad@chromium.org chadduffin@chromium.org jiajunz@google.com khorimoto@chromium.org
diff --git a/components/app_restore/app_restore_data.cc b/components/app_restore/app_restore_data.cc index 11814d84..98e03e49 100644 --- a/components/app_restore/app_restore_data.cc +++ b/components/app_restore/app_restore_data.cc
@@ -32,6 +32,7 @@ constexpr char kActivationIndexKey[] = "index"; constexpr char kFirstNonPinnedTabIndexKey[] = "first_non_pinned_tab_index"; constexpr char kDeskIdKey[] = "desk_id"; +constexpr char kDeskGuidKey[] = "desk_guid"; constexpr char kCurrentBoundsKey[] = "current_bounds"; constexpr char kWindowStateTypeKey[] = "window_state_type"; constexpr char kPreMinimizedShowStateTypeKey[] = "pre_min_state"; @@ -219,6 +220,14 @@ : absl::nullopt; } +base::GUID GetGuidValueFromDict(const base::Value::Dict& dict, + const std::string& key_name) { + if (const std::string* value = dict.FindString(key_name)) { + return base::GUID::ParseCaseInsensitive(*value); + } + return base::GUID(); +} + } // namespace AppRestoreData::AppRestoreData() = default; @@ -239,6 +248,7 @@ first_non_pinned_tab_index = GetIntValueFromDict(data, kFirstNonPinnedTabIndexKey); desk_id = GetIntValueFromDict(data, kDeskIdKey); + desk_guid = GetGuidValueFromDict(data, kDeskGuidKey); current_bounds = GetBoundsRectFromDict(data, kCurrentBoundsKey); window_state_type = GetWindowStateTypeFromDict(data); pre_minimized_show_state_type = GetPreMinimizedShowStateTypeFromDict(data); @@ -330,6 +340,10 @@ if (desk_id.has_value()) data->desk_id = desk_id.value(); + if (desk_guid.is_valid()) { + data->desk_guid = desk_guid; + } + if (current_bounds.has_value()) data->current_bounds = current_bounds.value(); @@ -427,6 +441,10 @@ if (desk_id.has_value()) launch_info_dict.Set(kDeskIdKey, desk_id.value()); + if (desk_guid.is_valid()) { + launch_info_dict.Set(kDeskGuidKey, desk_guid.AsLowercaseString()); + } + if (current_bounds.has_value()) { launch_info_dict.Set(kCurrentBoundsKey, ConvertRectToList(current_bounds.value())); @@ -483,6 +501,10 @@ if (window_info.desk_id.has_value()) desk_id = window_info.desk_id.value(); + if (window_info.desk_guid.is_valid()) { + desk_guid = window_info.desk_guid; + } + if (window_info.current_bounds.has_value()) current_bounds = window_info.current_bounds.value(); @@ -519,6 +541,7 @@ void AppRestoreData::ClearWindowInfo() { activation_index.reset(); desk_id.reset(); + desk_guid = base::GUID(); current_bounds.reset(); window_state_type.reset(); pre_minimized_show_state_type.reset(); @@ -562,6 +585,10 @@ if (desk_id.has_value()) window_info->desk_id = desk_id.value(); + if (desk_guid.is_valid()) { + window_info->desk_guid = desk_guid; + } + if (current_bounds.has_value()) window_info->current_bounds = current_bounds.value(); @@ -635,7 +662,8 @@ app_type_browser == other.app_type_browser && app_name == other.app_name && title == other.title && activation_index == other.activation_index && - desk_id == other.desk_id && current_bounds == other.current_bounds && + desk_id == other.desk_id && desk_guid == other.desk_guid && + current_bounds == other.current_bounds && window_state_type == other.window_state_type && pre_minimized_show_state_type == other.pre_minimized_show_state_type && snap_percentage == other.snap_percentage &&
diff --git a/components/app_restore/app_restore_data.h b/components/app_restore/app_restore_data.h index e7684d5..6db8382 100644 --- a/components/app_restore/app_restore_data.h +++ b/components/app_restore/app_restore_data.h
@@ -9,6 +9,7 @@ #include <vector> #include "base/component_export.h" +#include "base/guid.h" #include "base/values.h" #include "chromeos/ui/base/window_state_type.h" #include "components/services/app_service/public/cpp/app_launch_util.h" @@ -116,6 +117,8 @@ // in full restore are persistsed by sessions. This field is not converted to // base::value in base value conversions. absl::optional<std::vector<tab_groups::TabGroupInfo>> tab_group_infos; + // The GUID of the desk that this window was on. + base::GUID desk_guid; // Extra ARC window's information. absl::optional<gfx::Size> minimum_size;
diff --git a/components/app_restore/full_restore_read_and_save_unittest.cc b/components/app_restore/full_restore_read_and_save_unittest.cc index 3eb14e9..150c238 100644 --- a/components/app_restore/full_restore_read_and_save_unittest.cc +++ b/components/app_restore/full_restore_read_and_save_unittest.cc
@@ -27,6 +27,7 @@ #include "components/services/app_service/public/cpp/intent.h" #include "components/services/app_service/public/cpp/intent_util.h" #include "content/public/test/browser_task_environment.h" +#include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/aura/client/aura_constants.h" #include "ui/aura/test/aura_test_helper.h" @@ -41,6 +42,9 @@ namespace { +using testing::ElementsAre; +using testing::Pair; + constexpr char kAppId[] = "aaa"; constexpr int32_t kId1 = 100; @@ -69,6 +73,10 @@ constexpr uint32_t kBrowserSessionId = 56; +// Randomly generated desk GUID to test saving removing desk GUID. +const base::GUID kRemovingDeskGuid = base::GUID::GenerateRandomV4(); +const base::GUID kNonRemovingDeskGuid = base::GUID::GenerateRandomV4(); + } // namespace class FullRestoreReadHandlerTestApi { @@ -334,7 +342,8 @@ std::unique_ptr<aura::Window> CreateWindowInfo( int32_t id, int32_t index, - ash::AppType app_type = ash::AppType::BROWSER) { + ash::AppType app_type = ash::AppType::BROWSER, + base::GUID desk_guid = base::GUID()) { std::unique_ptr<aura::Window> window( aura::test::CreateTestWindowWithId(id, nullptr)); app_restore::WindowInfo window_info; @@ -342,6 +351,7 @@ window->SetProperty(aura::client::kAppType, static_cast<int>(app_type)); window->SetProperty(app_restore::kWindowIdKey, id); window_info.activation_index = index; + window_info.desk_guid = desk_guid; full_restore::SaveWindowInfo(window_info); return window; } @@ -1168,4 +1178,44 @@ EXPECT_TRUE(restore_data->app_id_to_launch_list().empty()); } +// Verifies that saving a removing desk's GUID in `RestoreData` allows for us to +// prevent the windows in that desk from being restored. +TEST_F(FullRestoreReadAndSaveTest, PreventWindowsOnRemovingDeskFromRestoring) { + FullRestoreSaveHandler* save_handler = GetSaveHandler(); + base::OneShotTimer* timer = save_handler->GetTimerForTesting(); + + // Add app launch info, and verify the timer starts. + AddAppLaunchInfo(GetPath(), kId1); + ASSERT_TRUE(timer->IsRunning()); + + // Add one more app launch info, and verify the timer is still running. + AddAppLaunchInfo(GetPath(), kId2); + ASSERT_TRUE(timer->IsRunning()); + + // Create two windows. Establish that `window1` will be on the removing desk + // and `window2` will be on the non-removing desk. + std::unique_ptr<aura::Window> window1 = CreateWindowInfo( + kId1, kActivationIndex1, ash::AppType::BROWSER, kRemovingDeskGuid); + std::unique_ptr<aura::Window> window2 = CreateWindowInfo( + kId2, kActivationIndex2, ash::AppType::BROWSER, kNonRemovingDeskGuid); + + // Establish that the desk with `kRemovingDeskGuid` as its GUID is being + // removed. + save_handler->SaveRemovingDeskGuid(kRemovingDeskGuid); + + // Simulate timeout, which should trigger a save, and verify the timer stops. + timer->FireNow(); + task_environment().RunUntilIdle(); + + ReadFromFile(GetPath()); + + // Verify the restore data can be read correctly. + const auto* restore_data = GetRestoreData(GetPath()); + ASSERT_TRUE(restore_data); + + // The launch list in `restore_data` should only have `window2`. + EXPECT_THAT(restore_data->app_id_to_launch_list(), + ElementsAre(Pair(kAppId, ElementsAre(Pair(kId2, testing::_))))); +} + } // namespace full_restore
diff --git a/components/app_restore/full_restore_save_handler.cc b/components/app_restore/full_restore_save_handler.cc index 0b8aaf5..32f7624ae 100644 --- a/components/app_restore/full_restore_save_handler.cc +++ b/components/app_restore/full_restore_save_handler.cc
@@ -326,6 +326,16 @@ ModifyWindowInfo(window_id, window_info); } +void FullRestoreSaveHandler::SaveRemovingDeskGuid( + const base::GUID& removing_desk_guid) { + profile_path_to_restore_data_[active_profile_path_].set_removing_desk_guid( + removing_desk_guid); + + pending_save_profile_paths_.insert(active_profile_path_); + + MaybeStartSaveTimer(active_profile_path_); +} + void FullRestoreSaveHandler::OnLacrosChromeAppWindowAdded( const std::string& app_id, const std::string& window_id) {
diff --git a/components/app_restore/full_restore_save_handler.h b/components/app_restore/full_restore_save_handler.h index 4c7d677..0be949ce 100644 --- a/components/app_restore/full_restore_save_handler.h +++ b/components/app_restore/full_restore_save_handler.h
@@ -13,6 +13,7 @@ #include "base/component_export.h" #include "base/containers/flat_map.h" +#include "base/guid.h" #include "base/memory/scoped_refptr.h" #include "base/memory/weak_ptr.h" #include "base/scoped_multi_source_observation.h" @@ -110,6 +111,10 @@ // Saves |window_info| to |profile_path_to_restore_data_|. void SaveWindowInfo(const app_restore::WindowInfo& window_info); + // Saves `removing_desk_guid` to the restore data for the currently active + // profile path. + void SaveRemovingDeskGuid(const base::GUID& removing_desk_guid); + // Invoked when an Chrome app Lacros window is created. `app_id` is the // AppService id, and `window_id` is the wayland app_id property for the // window.
diff --git a/components/app_restore/full_restore_utils.cc b/components/app_restore/full_restore_utils.cc index 9b0cc55..b5bf5117 100644 --- a/components/app_restore/full_restore_utils.cc +++ b/components/app_restore/full_restore_utils.cc
@@ -75,4 +75,13 @@ app_id, window_id); } +void SaveRemovingDeskGuid(const base::GUID& removing_desk_guid) { + FullRestoreSaveHandler::GetInstance()->SaveRemovingDeskGuid( + removing_desk_guid); +} + +void ResetRemovingDeskGuid() { + FullRestoreSaveHandler::GetInstance()->SaveRemovingDeskGuid(base::GUID()); +} + } // namespace full_restore
diff --git a/components/app_restore/full_restore_utils.h b/components/app_restore/full_restore_utils.h index b4d5bc69..d27d662 100644 --- a/components/app_restore/full_restore_utils.h +++ b/components/app_restore/full_restore_utils.h
@@ -8,6 +8,7 @@ #include <memory> #include "base/component_export.h" +#include "base/guid.h" #include "ui/base/class_property.h" #include "ui/views/widget/widget.h" @@ -77,6 +78,17 @@ void OnLacrosChromeAppWindowRemoved(const std::string& app_id, const std::string& window_id); +// Invoked when a desk is being removed. `removing_desk_guid` is the GUID for +// the removing desk. +COMPONENT_EXPORT(APP_RESTORE) +void SaveRemovingDeskGuid(const base::GUID& removing_desk_guid); + +// Invoked when desk removal is completed. The desk is either fully closed or +// the removal has been undone. In either case, the full restore service should +// no longer consider this desk to be in the process of removal. +COMPONENT_EXPORT(APP_RESTORE) +void ResetRemovingDeskGuid(); + } // namespace full_restore #endif // COMPONENTS_APP_RESTORE_FULL_RESTORE_UTILS_H_
diff --git a/components/app_restore/restore_data.cc b/components/app_restore/restore_data.cc index b50e79e..9cb6d6a 100644 --- a/components/app_restore/restore_data.cc +++ b/components/app_restore/restore_data.cc
@@ -25,6 +25,10 @@ // a valid RWID should not use. int32_t g_desk_template_window_restore_id = -1; +// Key used to record `removing_desk_guid_` when `RestoreData` is converted to +// JSON. +constexpr char kRemovingDeskGuidKey[] = "removing_desk_guid"; + } // namespace RestoreData::RestoreData() = default; @@ -37,9 +41,23 @@ return; } + if (auto* removing_desk_guid_string = + dict->FindString(kRemovingDeskGuidKey)) { + removing_desk_guid_ = + base::GUID::ParseLowercase(*removing_desk_guid_string); + } + for (auto iter : *dict) { - const std::string& app_id = iter.first; - base::Value::Dict* value = dict->FindDict(app_id); + // `key` can be an app ID or `kRemovingDeskGuidKey`. + const std::string& key = iter.first; + base::Value::Dict* value = iter.second.GetIfDict(); + + // Skip the removing desk GUID because we already covered this before the + // loop. + if (key == kRemovingDeskGuidKey) { + continue; + } + if (!value) { DVLOG(0) << "Fail to parse full restore data. " << "Cannot find the app restore data dict."; @@ -47,20 +65,32 @@ } for (auto data_iter : *value) { + const std::string& window_id_string = data_iter.first; + int window_id = 0; - if (!base::StringToInt(data_iter.first, &window_id)) { + if (!base::StringToInt(window_id_string, &window_id)) { DVLOG(0) << "Fail to parse full restore data. " << "Cannot find the valid id."; continue; } - base::Value::Dict* app_restore_data = value->FindDict(data_iter.first); - if (!app_restore_data) { + + base::Value::Dict* app_restore_data_dict = data_iter.second.GetIfDict(); + if (!app_restore_data_dict) { DVLOG(0) << "Fail to parse app restore data. " << "Cannot find the app restore data dict."; continue; } - app_id_to_launch_list_[app_id][window_id] = - std::make_unique<AppRestoreData>(std::move(*app_restore_data)); + + // If the data is for an app that was on a removing desk, then we can skip + // adding the data. + auto app_restore_data = + std::make_unique<AppRestoreData>(std::move(*app_restore_data_dict)); + if (removing_desk_guid_.is_valid() && + app_restore_data->desk_guid == removing_desk_guid_) { + continue; + } + + app_id_to_launch_list_[key][window_id] = std::move(app_restore_data); } } } @@ -75,6 +105,9 @@ data_it.second->Clone(); } } + if (removing_desk_guid_.is_valid()) { + restore_data->removing_desk_guid_ = removing_desk_guid_; + } return restore_data; } @@ -92,6 +125,12 @@ restore_data_dict.SetKey(it.first, std::move(info_dict)); } + + if (removing_desk_guid_.is_valid()) { + restore_data_dict.GetDict().Set(kRemovingDeskGuidKey, + removing_desk_guid_.AsLowercaseString()); + } + return restore_data_dict; } @@ -297,8 +336,9 @@ } std::string RestoreData::ToString() const { - if (app_id_to_launch_list_.empty()) + if (app_id_to_launch_list_.empty() && !removing_desk_guid_.is_valid()) { return "empty"; + } std::string result = "( "; for (const auto& entry : app_id_to_launch_list_) { @@ -313,7 +353,16 @@ windows.second->GetWindowInfo()->ToString(); } } - return result + " )"; + + result += " )"; + + if (removing_desk_guid_.is_valid()) { + result += + base::StringPrintf(" (Removing Desk GUID: %s)", + removing_desk_guid_.AsLowercaseString().c_str()); + } + + return result; } AppRestoreData* RestoreData::GetAppRestoreDataMutable(const std::string& app_id,
diff --git a/components/app_restore/restore_data.h b/components/app_restore/restore_data.h index 019d001..53b226c7 100644 --- a/components/app_restore/restore_data.h +++ b/components/app_restore/restore_data.h
@@ -9,6 +9,7 @@ #include <memory> #include "base/component_export.h" +#include "base/guid.h" #include "base/values.h" #include "components/app_restore/app_restore_data.h" @@ -40,7 +41,8 @@ std::unique_ptr<RestoreData> Clone() const; - // Converts |app_id_to_launch_list_| to base::Value, e.g.: + // Converts `app_id_to_launch_list_` and `removing_desk_guid_` to base::Value, + // e.g.: // { // "odknhmnlageboeamepcngndbggdpaobj": // app_id // { @@ -51,6 +53,7 @@ // "display_id": "22000000", // "index": 3, // "desk_id": 1, + // "desk_guid": "d782accb-232f-4f47-ad24-a7100f9c0ec0", // "restored_bounds": { 0, 100, 200, 300 }, // "current_bounds": { 100, 200, 200, 300 }, // "window_state_type": 256, @@ -70,6 +73,9 @@ // ... // }, // }, + // ... + // "removing_desk_guid": + // "d782accb-232f-4f47-ad24-a7100f9c0ec0" // removing_desk_guid // } base::Value ConvertToValue() const; @@ -187,6 +193,10 @@ return app_id_to_launch_list_; } + void set_removing_desk_guid(const base::GUID& removing_desk_guid) { + removing_desk_guid_ = removing_desk_guid; + } + private: // Returns the pointer to AppRestoreData for the given |app_id| and // |window_id|. Returns null if there is no AppRestoreData. @@ -197,6 +207,10 @@ // Saves the next restore window_id to be handled for each chrome app. std::map<std::string, int> chrome_app_id_to_current_window_id_; + + // The GUID of a desk that is being removed. This will only be valid if a desk + // is in the process of being removed. + base::GUID removing_desk_guid_; }; } // namespace app_restore
diff --git a/components/app_restore/restore_data_unittest.cc b/components/app_restore/restore_data_unittest.cc index 5afe53c..a0bdf05 100644 --- a/components/app_restore/restore_data_unittest.cc +++ b/components/app_restore/restore_data_unittest.cc
@@ -66,6 +66,10 @@ constexpr int32_t kDeskId3 = aura::client::kWindowWorkspaceVisibleOnAllWorkspaces; +const base::GUID kDeskGuid1 = base::GUID::GenerateRandomV4(); +const base::GUID kDeskGuid2 = base::GUID::GenerateRandomV4(); +const base::GUID kDeskGuid3 = base::GUID(); + constexpr gfx::Rect kCurrentBounds1(11, 21, 111, 121); constexpr gfx::Rect kCurrentBounds2(31, 41, 131, 141); constexpr gfx::Rect kCurrentBounds3(51, 61, 151, 161); @@ -184,6 +188,7 @@ WindowInfo window_info1; window_info1.activation_index = kActivationIndex1; window_info1.desk_id = kDeskId1; + window_info1.desk_guid = kDeskGuid1; window_info1.current_bounds = kCurrentBounds1; window_info1.window_state_type = kWindowStateType1; window_info1.display_id = kDisplayId2; @@ -196,6 +201,7 @@ WindowInfo window_info2; window_info2.activation_index = kActivationIndex2; window_info2.desk_id = kDeskId2; + window_info2.desk_guid = kDeskGuid2; window_info2.current_bounds = kCurrentBounds2; window_info2.window_state_type = kWindowStateType2; window_info2.pre_minimized_show_state_type = kPreMinimizedWindowStateType2; @@ -208,6 +214,7 @@ WindowInfo window_info3; window_info3.activation_index = kActivationIndex3; window_info3.desk_id = kDeskId3; + window_info3.desk_guid = kDeskGuid3; window_info3.current_bounds = kCurrentBounds3; window_info3.window_state_type = kWindowStateType3; window_info3.snap_percentage = kSnapPercentage; @@ -236,6 +243,7 @@ int32_t activation_index, int32_t first_non_pinned_tab_index, int32_t desk_id, + const base::GUID& desk_guid, const gfx::Rect& current_bounds, chromeos::WindowStateType window_state_type, ui::WindowShowState pre_minimized_show_state_type, @@ -283,6 +291,8 @@ EXPECT_TRUE(data->desk_id.has_value()); EXPECT_EQ(desk_id, data->desk_id.value()); + EXPECT_EQ(desk_guid, data->desk_guid); + EXPECT_TRUE(data->current_bounds.has_value()); EXPECT_EQ(current_bounds, data->current_bounds.value()); @@ -387,8 +397,8 @@ std::vector<base::FilePath>{base::FilePath(kFilePath1), base::FilePath(kFilePath2)}, MakeIntent(kIntentActionSend, kMimeType, kShareText1), kAppTypeBrower1, - kActivationIndex1, kFirstNonPinnedTabIndex, kDeskId1, kCurrentBounds1, - kWindowStateType1, kPreMinimizedWindowStateType1, + kActivationIndex1, kFirstNonPinnedTabIndex, kDeskId1, kDeskGuid1, + kCurrentBounds1, kWindowStateType1, kPreMinimizedWindowStateType1, /*snap_percentage=*/0, kMaxSize1, kMinSize1, std::u16string(kTitle1), kBoundsInRoot1, kPrimaryColor1, kStatusBarColor1, /*tab_group_infos=*/{}); @@ -403,8 +413,8 @@ WindowOpenDisposition::NEW_FOREGROUND_TAB, kDisplayId1, std::vector<base::FilePath>{base::FilePath(kFilePath2)}, MakeIntent(kIntentActionView, kMimeType, kShareText2), kAppTypeBrower2, - kActivationIndex2, kFirstNonPinnedTabIndex, kDeskId2, kCurrentBounds2, - kWindowStateType2, kPreMinimizedWindowStateType2, + kActivationIndex2, kFirstNonPinnedTabIndex, kDeskId2, kDeskGuid2, + kCurrentBounds2, kWindowStateType2, kPreMinimizedWindowStateType2, /*snap_percentage=*/0, absl::nullopt, kMinSize2, std::u16string(kTitle2), kBoundsInRoot2, kPrimaryColor2, kStatusBarColor2, std::move(expected_tab_group_infos), @@ -423,9 +433,10 @@ WindowOpenDisposition::NEW_POPUP, kDisplayId1, std::vector<base::FilePath>{base::FilePath(kFilePath1)}, MakeIntent(kIntentActionView, kMimeType, kShareText1), kAppTypeBrower3, - kActivationIndex3, kFirstNonPinnedTabIndex, kDeskId3, kCurrentBounds3, - kWindowStateType3, kPreMinimizedWindowStateType3, kSnapPercentage, - absl::nullopt, absl::nullopt, absl::nullopt, absl::nullopt, 0, 0, + kActivationIndex3, kFirstNonPinnedTabIndex, kDeskId3, kDeskGuid3, + kCurrentBounds3, kWindowStateType3, kPreMinimizedWindowStateType3, + kSnapPercentage, absl::nullopt, absl::nullopt, absl::nullopt, + absl::nullopt, 0, 0, /*expected_tab_group_infos=*/{}); } @@ -486,10 +497,10 @@ WindowOpenDisposition::NEW_FOREGROUND_TAB, kDisplayId1, std::vector<base::FilePath>{base::FilePath(kFilePath2)}, MakeIntent(kIntentActionView, kMimeType, kShareText2), kAppTypeBrower2, - kActivationIndex2, kFirstNonPinnedTabIndex, kDeskId2, kCurrentBounds2, - kWindowStateType2, kPreMinimizedWindowStateType2, /*snap_percentage=*/0, - absl::nullopt, kMinSize2, std::u16string(kTitle2), kBoundsInRoot2, - kPrimaryColor2, kStatusBarColor2, /*tab_group_infos=*/{}); + kActivationIndex2, kFirstNonPinnedTabIndex, kDeskId2, kDeskGuid2, + kCurrentBounds2, kWindowStateType2, kPreMinimizedWindowStateType2, + /*snap_percentage=*/0, absl::nullopt, kMinSize2, std::u16string(kTitle2), + kBoundsInRoot2, kPrimaryColor2, kStatusBarColor2, /*tab_group_infos=*/{}); // Verify the restore data for |kAppId2| still exists. const auto launch_list_it2 = @@ -570,6 +581,7 @@ EXPECT_TRUE(window_info->activation_index.has_value()); EXPECT_EQ(INT32_MAX, window_info->activation_index.value()); EXPECT_TRUE(window_info->desk_id.has_value()); + EXPECT_TRUE(window_info->desk_guid.is_valid()); EXPECT_TRUE(window_info->current_bounds.has_value()); EXPECT_TRUE(window_info->window_state_type.has_value()); EXPECT_TRUE(window_info->arc_extra_info.has_value()); @@ -675,6 +687,7 @@ EXPECT_TRUE(window_info); EXPECT_FALSE(window_info->activation_index.has_value()); EXPECT_FALSE(window_info->desk_id.has_value()); + EXPECT_FALSE(window_info->desk_guid.is_valid()); EXPECT_FALSE(window_info->current_bounds.has_value()); EXPECT_FALSE(window_info->window_state_type.has_value()); @@ -689,6 +702,9 @@ EXPECT_TRUE(window_info->desk_id.has_value()); EXPECT_EQ(kDeskId1, window_info->desk_id.value()); + EXPECT_TRUE(window_info->desk_guid.is_valid()); + EXPECT_EQ(kDeskGuid1, window_info->desk_guid); + EXPECT_TRUE(window_info->current_bounds.has_value()); EXPECT_EQ(kCurrentBounds1, window_info->current_bounds.value());
diff --git a/components/app_restore/window_info.cc b/components/app_restore/window_info.cc index c061a30d..cd791e59 100644 --- a/components/app_restore/window_info.cc +++ b/components/app_restore/window_info.cc
@@ -40,6 +40,11 @@ return prefix + ": " + base::UTF16ToASCII(val.value_or(u"")); } +std::string ToPrefixedString(base::GUID val, const std::string& prefix) { + return prefix + ": " + + (val.is_valid() ? val : base::GUID()).AsLowercaseString(); +} + } // namespace WindowInfo::ArcExtraInfo::ArcExtraInfo() = default; @@ -58,6 +63,7 @@ new_window_info->window = window; new_window_info->activation_index = activation_index; new_window_info->desk_id = desk_id; + new_window_info->desk_guid = desk_guid; new_window_info->current_bounds = current_bounds; new_window_info->window_state_type = window_state_type; new_window_info->pre_minimized_show_state_type = @@ -72,6 +78,7 @@ std::string WindowInfo::ToString() const { return ToPrefixedString(activation_index, "Activation index") + ToPrefixedString(desk_id, "Desk") + + ToPrefixedString(desk_guid, "Desk guid") + ToPrefixedString(current_bounds, "Current bounds") + ToPrefixedString(window_state_type, "Window state") + ToPrefixedString(pre_minimized_show_state_type,
diff --git a/components/app_restore/window_info.h b/components/app_restore/window_info.h index 83e57732..57bf6c8 100644 --- a/components/app_restore/window_info.h +++ b/components/app_restore/window_info.h
@@ -5,6 +5,7 @@ #ifndef COMPONENTS_APP_RESTORE_WINDOW_INFO_H_ #define COMPONENTS_APP_RESTORE_WINDOW_INFO_H_ +#include "base/guid.h" #include "chromeos/ui/base/window_state_type.h" #include "third_party/abseil-cpp/absl/types/optional.h" #include "ui/aura/window.h" @@ -45,6 +46,9 @@ // Virtual desk id. absl::optional<int32_t> desk_id; + // Virtual desk guid. + base::GUID desk_guid; + // Current bounds in screen in coordinates. If the window has restore bounds, // then this contains the restore bounds. absl::optional<gfx::Rect> current_bounds;
diff --git a/components/autofill/android/java/res/values/dimens.xml b/components/autofill/android/java/res/values/dimens.xml index 46634d4..97cfc4c 100644 --- a/components/autofill/android/java/res/values/dimens.xml +++ b/components/autofill/android/java/res/values/dimens.xml
@@ -52,4 +52,10 @@ <dimen name="settings_page_card_icon_height_new">24dp</dimen> <dimen name="settings_page_card_icon_end_margin">20dp</dimen> <dimen name="settings_page_margin_between_card_name_and_last_four_digits">4dp</dimen> + + <!-- Card Unmask dialog --> + <dimen name="card_unmask_dialog_credit_card_icon_width">32dp</dimen> + <dimen name="card_unmask_dialog_credit_card_icon_height">20dp</dimen> + <dimen name="card_unmask_dialog_credit_card_icon_width_new">40dp</dimen> + <dimen name="card_unmask_dialog_credit_card_icon_height_new">24dp</dimen> </resources>
diff --git a/components/autofill/core/common/autofill_payments_features.cc b/components/autofill/core/common/autofill_payments_features.cc index 8034d15..b4e9b57 100644 --- a/components/autofill/core/common/autofill_payments_features.cc +++ b/components/autofill/core/common/autofill_payments_features.cc
@@ -47,6 +47,14 @@ "AutofillEnableCardProductName", base::FEATURE_DISABLED_BY_DEFAULT); +// When enabled, if the user encounters the yellow path (challenge path) in the +// VCN retrieval flow and the server denotes that the card is eligible for email +// OTP authentication, email OTP authentication will be offered as one of the +// challenge options. +BASE_FEATURE(kAutofillEnableEmailOtpForVcnYellowPath, + "AutofillEnableEmailOtpForVcnYellowPath", + base::FEATURE_DISABLED_BY_DEFAULT); + // When enabled, user's will see network card art images and network icons which // are larger, having a white border, and don't have the standard grey overlay // applied to them.
diff --git a/components/autofill/core/common/autofill_payments_features.h b/components/autofill/core/common/autofill_payments_features.h index fcd0597..247fab5 100644 --- a/components/autofill/core/common/autofill_payments_features.h +++ b/components/autofill/core/common/autofill_payments_features.h
@@ -17,6 +17,7 @@ BASE_DECLARE_FEATURE(kAutofillAutoTriggerManualFallbackForCards); BASE_DECLARE_FEATURE(kAutofillEnableCardArtImage); BASE_DECLARE_FEATURE(kAutofillEnableCardProductName); +BASE_DECLARE_FEATURE(kAutofillEnableEmailOtpForVcnYellowPath); BASE_DECLARE_FEATURE(kAutofillEnableFIDOProgressDialog); BASE_DECLARE_FEATURE(kAutofillEnableIbanClientSideUrlFiltering); BASE_DECLARE_FEATURE(kAutofillEnableManualFallbackForVirtualCards);
diff --git a/components/browser_ui/widget/android/BUILD.gn b/components/browser_ui/widget/android/BUILD.gn index a7eba723..519b460 100644 --- a/components/browser_ui/widget/android/BUILD.gn +++ b/components/browser_ui/widget/android/BUILD.gn
@@ -98,6 +98,7 @@ "java/src/org/chromium/components/browser_ui/widget/scrim/ScrimProperties.java", "java/src/org/chromium/components/browser_ui/widget/scrim/ScrimView.java", "java/src/org/chromium/components/browser_ui/widget/scrim/ScrimViewBinder.java", + "java/src/org/chromium/components/browser_ui/widget/selectable_list/CheckableSelectableItemView.java", "java/src/org/chromium/components/browser_ui/widget/selectable_list/SelectableItemView.java", "java/src/org/chromium/components/browser_ui/widget/selectable_list/SelectableItemViewBase.java", "java/src/org/chromium/components/browser_ui/widget/selectable_list/SelectableItemViewHolder.java", @@ -239,7 +240,6 @@ "java/res/layout/indeterminate_progress_view.xml", "java/res/layout/list_menu_item.xml", "java/res/layout/modern_list_item_view.xml", - "java/res/layout/modern_list_item_view_v2.xml", "java/res/layout/more_progress_button.xml", "java/res/layout/number_roll_view.xml", "java/res/layout/promo_card_view_compact.xml",
diff --git a/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/selectable_list/CheckableSelectableItemView.java b/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/selectable_list/CheckableSelectableItemView.java new file mode 100644 index 0000000..3740b47 --- /dev/null +++ b/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/selectable_list/CheckableSelectableItemView.java
@@ -0,0 +1,119 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.components.browser_ui.widget.selectable_list; + +import android.content.Context; +import android.content.res.ColorStateList; +import android.graphics.drawable.Drawable; +import android.graphics.drawable.LevelListDrawable; +import android.util.AttributeSet; +import android.widget.ImageView; + +import androidx.annotation.Nullable; +import androidx.annotation.VisibleForTesting; +import androidx.core.widget.ImageViewCompat; +import androidx.vectordrawable.graphics.drawable.AnimatedVectorDrawableCompat; + +import org.chromium.components.browser_ui.styles.SemanticColorUtils; +import org.chromium.components.browser_ui.widget.R; + +/** + * Implementation of SelectableItemViewBase which requires the caller to inflate their own view. + * Useful for when you need to diverge from the built-in layout of SelectableItemView, but want + * the checkmark functionality. Backgrounds used for the #iconView should be instances of + * LevelListDrawable to properly interact with the checkmark behavior, see list_item_icon_modern_bg + * for an example of how to setup a new drawable. + * + * @param <E> The type of the item associated with this SelectableItemViewBase. + */ +public abstract class CheckableSelectableItemView<E> extends SelectableItemViewBase<E> { + private final AnimatedVectorDrawableCompat mCheckDrawable; + + /** The color state list for the start icon view when the item is selected. */ + private ColorStateList mIconSelectedColorList; + + /** Drawable for the start icon */ + private @Nullable Drawable mIconDrawable; + + /** Constructor for inflating from XML. */ + public CheckableSelectableItemView(Context context, AttributeSet attrs) { + super(context, attrs); + mIconSelectedColorList = + ColorStateList.valueOf(SemanticColorUtils.getDefaultIconColorInverse(context)); + mCheckDrawable = AnimatedVectorDrawableCompat.create( + getContext(), R.drawable.ic_check_googblue_24dp_animated); + } + + // Abstract methods. + + /** Returns the icon view used to show the checkmark when selected. */ + protected abstract ImageView getIconView(); + + /** + * Returns the default tint for the icon view, can be null. Will be swapped with a different + * tint when the checkmark is shown. + */ + protected abstract @Nullable ColorStateList getDefaultIconTint(); + + /** + * Returns the selected level for the icon view background. This level is used when the + * drawable set by #setIconDrawable is displayed. The background for the ImageView returned + * by #getIconView should be a LevelListDrawable that supports both the default and selected + * state. + */ + protected abstract int getDefaultLevel(); + + /** + * Returns the selected level for the icon view background. This level is used when the + * checkmark is displayed. The background for the ImageView returned by #getIconView should + * be a LevelListDrawable that supports both the default and selected state. + */ + protected abstract int getSelectedLevel(); + + /** + * Set drawable for the start icon view. Note that you may need to use this method instead of + * mIconView#setImageDrawable to ensure icon view is correctly set in selection mode. + */ + public void setIconDrawable(Drawable iconDrawable) { + mIconDrawable = iconDrawable; + updateView(false); + } + + /** Returns the drawable set for the start icon view, if any. */ + public Drawable getIconDrawable() { + return mIconDrawable; + } + + @Override + protected void updateView(boolean animate) { + ImageView iconView = getIconView(); + if (iconView == null) return; + Drawable iconViewBackground = iconView.getBackground(); + assert iconViewBackground instanceof LevelListDrawable; + + boolean levelMatches; + boolean levelChangeSuccess; + if (isChecked()) { + int level = getSelectedLevel(); + levelMatches = level == iconViewBackground.getLevel(); + levelChangeSuccess = iconViewBackground.setLevel(level); + iconView.setImageDrawable(mCheckDrawable); + ImageViewCompat.setImageTintList(iconView, mIconSelectedColorList); + if (animate) mCheckDrawable.start(); + } else { + int level = getDefaultLevel(); + levelMatches = level == iconViewBackground.getLevel(); + levelChangeSuccess = iconViewBackground.setLevel(level); + iconView.setImageDrawable(mIconDrawable); + ImageViewCompat.setImageTintList(iconView, getDefaultIconTint()); + } + assert levelMatches || levelChangeSuccess; + } + + @VisibleForTesting + public void endAnimationsForTests() { + mCheckDrawable.stop(); + } +}
diff --git a/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/selectable_list/SelectableItemView.java b/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/selectable_list/SelectableItemView.java index 20c3c87..5db0026 100644 --- a/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/selectable_list/SelectableItemView.java +++ b/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/selectable_list/SelectableItemView.java
@@ -9,22 +9,15 @@ import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; import androidx.annotation.Nullable; -import androidx.annotation.VisibleForTesting; import androidx.appcompat.widget.AppCompatImageButton; import androidx.core.widget.ImageViewCompat; -import androidx.vectordrawable.graphics.drawable.AnimatedVectorDrawableCompat; -import org.chromium.components.browser_ui.styles.SemanticColorUtils; import org.chromium.components.browser_ui.widget.R; -import org.chromium.components.browser_ui.widget.TintedDrawable; -import org.chromium.ui.base.ViewUtils; /** * Default implementation of SelectableItemViewBase. Contains a start icon, title, description, and @@ -32,111 +25,70 @@ * * @param <E> The type of the item associated with this SelectableItemViewBase. */ -public abstract class SelectableItemView<E> extends SelectableItemViewBase<E> { - protected final int mDefaultLevel; - protected final int mSelectedLevel; - protected final AnimatedVectorDrawableCompat mCheckDrawable; - - protected int mStartIconViewSize; - - /** - * The LinearLayout containing the rest of the views for the selectable item. - */ +public abstract class SelectableItemView<E> extends CheckableSelectableItemView<E> { + /** The LinearLayout containing the rest of the views for the selectable item. */ protected LinearLayout mContentView; - /** - * An icon displayed at the start of the item row. - */ + /** An icon displayed at the start of the item row. */ protected ImageView mStartIconView; - /** - * An optional button displayed at the before the end button, GONE by default. - */ - protected AppCompatImageButton mEndStartButtonView; - - /** - * An optional button displayed at the end of the item row, GONE by default. - */ + /** An optional button displayed at the end of the item row, GONE by default. */ protected AppCompatImageButton mEndButtonView; - /** - * A title line displayed between the start and (optional) end icon. - */ + /** A title line displayed between the start and (optional) end icon. */ protected TextView mTitleView; - /** - * A description line displayed below the title line. - */ + /** A description line displayed below the title line. */ protected TextView mDescriptionView; - /** - * The color state list for the start icon view when the item is selected. - */ - protected ColorStateList mStartIconSelectedColorList; - - private Drawable mStartIconDrawable; - - /** - * Layout res to be used when inflating the view, used to swap in the visual refresh. - */ + /** Layout res to be used when inflating the view, used to swap in the visual refresh. */ private int mLayoutRes; - - /** - * The resource for the start icon background. - */ + /** Levels for the background. */ + private final int mDefaultLevel; + private final int mSelectedLevel; + /** The resource for the start icon background. */ private int mStartIconBackgroundRes; /** - * Tracks if inflation is finished. - */ - private boolean mInflationFinished; - - /** - * Tracks if the visual refresh is enabled. - */ - private boolean mVisualRefreshEnabled; - - /** - * Container for custom content to be set on the view. - */ - private ViewGroup mCustomContentContainer; - - /** * Constructor for inflating from XML. */ public SelectableItemView(Context context, AttributeSet attrs) { super(context, attrs); - mStartIconSelectedColorList = - ColorStateList.valueOf(SemanticColorUtils.getDefaultIconColorInverse(context)); + + mLayoutRes = R.layout.modern_list_item_view; + mStartIconBackgroundRes = R.drawable.list_item_icon_modern_bg; mDefaultLevel = getResources().getInteger(R.integer.list_item_level_default); mSelectedLevel = getResources().getInteger(R.integer.list_item_level_selected); - mCheckDrawable = AnimatedVectorDrawableCompat.create( - getContext(), R.drawable.ic_check_googblue_24dp_animated); - mStartIconBackgroundRes = R.drawable.list_item_icon_modern_bg; - mLayoutRes = R.layout.modern_list_item_view; } - protected boolean isVisualRefreshEnabled() { - return mVisualRefreshEnabled; + // CheckableSelectableItemView implementation. + + @Override + protected ImageView getIconView() { + return mStartIconView; } - protected void enableVisualRefresh() { - mVisualRefreshEnabled = true; + @Override + protected @Nullable ColorStateList getDefaultIconTint() { + return null; + } - mStartIconBackgroundRes = R.drawable.list_item_icon_modern_bg_rect; - mLayoutRes = R.layout.modern_list_item_view_v2; - if (mInflationFinished) { - removeAllViews(); - inflateAndPopulateViewVariables(); - } + @Override + protected int getSelectedLevel() { + return mSelectedLevel; + } + + @Override + protected int getDefaultLevel() { + return mDefaultLevel; } // FrameLayout implementations. + @Override protected void onFinishInflate() { super.onFinishInflate(); inflateAndPopulateViewVariables(); - mInflationFinished = true; } private void inflateAndPopulateViewVariables() { @@ -150,14 +102,7 @@ if (mStartIconView != null) { mStartIconView.setBackgroundResource(mStartIconBackgroundRes); - ImageViewCompat.setImageTintList(mStartIconView, getDefaultStartIconTint()); - } - - if (isVisualRefreshEnabled()) { - mEndStartButtonView = findViewById(R.id.optional_button); - mCustomContentContainer = findViewById(R.id.custom_content_container); - ViewUtils.requestLayout( - mStartIconView, "SelectableItemView.inflateAndPopulateViewVariables"); + ImageViewCompat.setImageTintList(mStartIconView, getDefaultIconTint()); } } @@ -166,87 +111,13 @@ * mIconView#setImageDrawable to ensure icon view is correctly set in selection mode. */ protected void setStartIconDrawable(Drawable iconDrawable) { - mStartIconDrawable = iconDrawable; - updateView(false); + setIconDrawable(iconDrawable); } /** * Returns the drawable set for the start icon view, if any. */ protected Drawable getStartIconDrawable() { - return mStartIconDrawable; - } - - /** - * Sets a custom content view. - * @param view The custom view or null to clear it. - */ - protected void setCustomContent(@Nullable View view) { - assert isVisualRefreshEnabled() - : "Specifying custom content is only allowed when visual refresh is enabled"; - - // Custom content is allowed only with the visual refresh. - if (!isVisualRefreshEnabled()) return; - - mCustomContentContainer.removeAllViews(); - if (view == null) return; - mCustomContentContainer.addView(view); - } - - /** - * Update start icon image and background based on whether this item is selected. - */ - @Override - protected void updateView(boolean animate) { - // TODO(huayinz): Refactor this method so that mIconView is not exposed to subclass. - if (mStartIconView == null) return; - - if (isChecked()) { - mStartIconView.getBackground().setLevel(mSelectedLevel); - mStartIconView.setImageDrawable(mCheckDrawable); - ImageViewCompat.setImageTintList(mStartIconView, mStartIconSelectedColorList); - if (animate) mCheckDrawable.start(); - } else { - mStartIconView.getBackground().setLevel(mDefaultLevel); - mStartIconView.setImageDrawable(mStartIconDrawable); - ImageViewCompat.setImageTintList(mStartIconView, getDefaultStartIconTint()); - } - } - - /** - * @return The {@link ColorStateList} used to tint the start icon drawable set via - * {@link #setStartIconDrawable(Drawable)} when the item is not selected. - */ - protected @Nullable ColorStateList getDefaultStartIconTint() { - return null; - } - - @VisibleForTesting - public void endAnimationsForTests() { - mCheckDrawable.stop(); - } - - /** - * Sets the icon for the image view: the default icon if unselected, the check mark if selected. - * - * @param imageView The image view in which the icon will be presented. - * @param defaultIcon The default icon that will be displayed if not selected. - * @param isSelected Whether the item is selected or not. - */ - public static void applyModernIconStyle( - ImageView imageView, Drawable defaultIcon, boolean isSelected) { - imageView.setBackgroundResource(R.drawable.list_item_icon_modern_bg); - Drawable drawable; - if (isSelected) { - drawable = TintedDrawable.constructTintedDrawable( - imageView.getContext(), R.drawable.ic_check_googblue_24dp); - drawable.setTint(SemanticColorUtils.getDefaultIconColorInverse(imageView.getContext())); - } else { - drawable = defaultIcon; - } - imageView.setImageDrawable(drawable); - imageView.getBackground().setLevel(isSelected - ? imageView.getResources().getInteger(R.integer.list_item_level_selected) - : imageView.getResources().getInteger(R.integer.list_item_level_default)); + return getIconDrawable(); } }
diff --git a/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/selectable_list/SelectableItemViewBase.java b/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/selectable_list/SelectableItemViewBase.java index e5ed4840..1988e020 100644 --- a/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/selectable_list/SelectableItemViewBase.java +++ b/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/selectable_list/SelectableItemViewBase.java
@@ -55,6 +55,23 @@ */ public SelectableItemViewBase(Context context, AttributeSet attrs) { super(context, attrs); + + setOnTouchListener(this); + setOnClickListener(this); + setOnLongClickListener(this); + setAccessibilityDelegate(new AccessibilityDelegate() { + @Override + public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) { + super.onInitializeAccessibilityNodeInfo(host, info); + + // Announce checked state if selection mode is on. The actual read out from talkback + // is "checked/unchecked, {content description of this view.}" + boolean checkable = mSelectionDelegate != null + && mSelectionDelegate.isSelectionEnabled() && mItem != null; + info.setCheckable(checkable); + info.setChecked(isChecked()); + } + }); } /** @@ -103,29 +120,6 @@ return mItem; } - // FrameLayout implementations. - @Override - protected void onFinishInflate() { - super.onFinishInflate(); - - setOnTouchListener(this); - setOnClickListener(this); - setOnLongClickListener(this); - setAccessibilityDelegate(new AccessibilityDelegate() { - @Override - public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) { - super.onInitializeAccessibilityNodeInfo(host, info); - - // Announce checked state if selection mode is on. The actual read out from talkback - // is "checked/unchecked, {content description of this view.}" - boolean checkable = mSelectionDelegate != null - && mSelectionDelegate.isSelectionEnabled() && mItem != null; - info.setCheckable(checkable); - info.setChecked(isChecked()); - } - }); - } - @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); @@ -155,6 +149,7 @@ } // OnClickListener implementation. + @Override public void onClick(View view) { assert view == this;
diff --git a/components/browsing_topics/browsing_topics_service_impl.cc b/components/browsing_topics/browsing_topics_service_impl.cc index 347646c..78251208 100644 --- a/components/browsing_topics/browsing_topics_service_impl.cc +++ b/components/browsing_topics/browsing_topics_service_impl.cc
@@ -245,7 +245,14 @@ // request. kObserveViaFetchLikeApi = 3, - kMaxValue = kObserveViaFetchLikeApi, + // Get topics via <iframe src=[url] browsingtopics>. + kGetViaIframeAttributeApi = 4, + + // Observe topics via the "Sec-Browsing-Topics: ?1" response header for the + // <iframe src=[url] browsingtopics> request. + kObserveViaIframeAttributeApi = 5, + + kMaxValue = kObserveViaIframeAttributeApi, }; void RecordBrowsingTopicsApiActionTypeMetrics(ApiCallerSource caller_source, @@ -271,6 +278,24 @@ return; } + if (caller_source == ApiCallerSource::kIframeAttribute) { + if (get_topics) { + DCHECK(!observe); + + base::UmaHistogramEnumeration( + kBrowsingTopicsApiActionTypeHistogramId, + BrowsingTopicsApiActionType::kGetViaIframeAttributeApi); + return; + } + + DCHECK(observe); + base::UmaHistogramEnumeration( + kBrowsingTopicsApiActionTypeHistogramId, + BrowsingTopicsApiActionType::kObserveViaIframeAttributeApi); + + return; + } + DCHECK_EQ(caller_source, ApiCallerSource::kFetch); if (get_topics) {
diff --git a/components/browsing_topics/common/common_types.h b/components/browsing_topics/common/common_types.h index 8af8511..c5cd65aa 100644 --- a/components/browsing_topics/common/common_types.h +++ b/components/browsing_topics/common/common_types.h
@@ -26,6 +26,9 @@ // fetch(<url>, {browsingTopics: true}), or XMLHttpRequest.send() with the // `deprecatedBrowsingTopics` property set to true. kFetch, + + // The API usage is from <iframe src=[url] browsingtopics>. + kIframeAttribute, }; // Represents the different reasons why the topics API access is denied. These
diff --git a/components/history_clusters/core/config.cc b/components/history_clusters/core/config.cc index 56e59580..4401db2 100644 --- a/components/history_clusters/core/config.cc +++ b/components/history_clusters/core/config.cc
@@ -89,7 +89,12 @@ } // The `kJourneysImages` feature. - { images = base::FeatureList::IsEnabled(internal::kJourneysImages); } + { + images = base::FeatureList::IsEnabled(internal::kJourneysImages); + + images_cover = GetFieldTrialParamByFeatureAsBool( + internal::kJourneysImages, "JourneysImagesCover", images_cover); + } // The `kPersistedClusters` feature and child params. {
diff --git a/components/history_clusters/core/config.h b/components/history_clusters/core/config.h index 72a5730..f05060d 100644 --- a/components/history_clusters/core/config.h +++ b/components/history_clusters/core/config.h
@@ -90,6 +90,9 @@ // a proof of concept implementation for Entities only). bool images = false; + // Whether the image covers the whole icon container. + bool images_cover = true; + // The `kPersistedClusters` feature and child params. // If enabled, updating clusters will persist the results to the history DB
diff --git a/components/history_clusters/core/features.cc b/components/history_clusters/core/features.cc index 4089407..bcc9be32 100644 --- a/components/history_clusters/core/features.cc +++ b/components/history_clusters/core/features.cc
@@ -37,6 +37,9 @@ "JourneysImages", base::FEATURE_DISABLED_BY_DEFAULT); +const base::FeatureParam<bool> kJourneysImagesCover{ + &kJourneysImages, "JourneysImagesCover", true}; + BASE_FEATURE(kPersistedClusters, "HistoryClustersPersistedClusters", base::FEATURE_ENABLED_BY_DEFAULT);
diff --git a/components/history_clusters/core/features.h b/components/history_clusters/core/features.h index 5780e224..9e84061d 100644 --- a/components/history_clusters/core/features.h +++ b/components/history_clusters/core/features.h
@@ -24,6 +24,9 @@ // Enables images for Journeys in UI. BASE_DECLARE_FEATURE(kJourneysImages); +// Enables images to cover the full container for Journeys in UI. +extern const base::FeatureParam<bool> kJourneysImagesCover; + // Enables persisting and using persisted clusters. BASE_DECLARE_FEATURE(kPersistedClusters);
diff --git a/components/memory_pressure/system_memory_pressure_evaluator_win.h b/components/memory_pressure/system_memory_pressure_evaluator_win.h index d1419cac..3a0f8d5 100644 --- a/components/memory_pressure/system_memory_pressure_evaluator_win.h +++ b/components/memory_pressure/system_memory_pressure_evaluator_win.h
@@ -5,7 +5,6 @@ #ifndef COMPONENTS_MEMORY_PRESSURE_SYSTEM_MEMORY_PRESSURE_EVALUATOR_WIN_H_ #define COMPONENTS_MEMORY_PRESSURE_SYSTEM_MEMORY_PRESSURE_EVALUATOR_WIN_H_ -#include "base/base_export.h" #include "base/functional/callback_forward.h" #include "base/memory/memory_pressure_listener.h" #include "base/memory/weak_ptr.h"
diff --git a/components/mirroring/service/media_remoter.cc b/components/mirroring/service/media_remoter.cc index e372358..596c5116 100644 --- a/components/mirroring/service/media_remoter.cc +++ b/components/mirroring/service/media_remoter.cc
@@ -147,7 +147,11 @@ audio_config_ = absl::nullopt; video_config_ = absl::nullopt; - state_ = STOPPING_REMOTING; + // Don't change `state_` if remoting is disabled so that it won't attempt to + // start remoting again after mirroring resumed. + if (state_ != REMOTING_DISABLED) { + state_ = STOPPING_REMOTING; + } remoting_source_->OnStopped(reason); // Prevent the start of remoting until switching completes. remoting_source_->OnSinkGone();
diff --git a/components/mirroring/service/media_remoter_unittest.cc b/components/mirroring/service/media_remoter_unittest.cc index 75361fda..e6f3e0b 100644 --- a/components/mirroring/service/media_remoter_unittest.cc +++ b/components/mirroring/service/media_remoter_unittest.cc
@@ -233,8 +233,11 @@ } // Signals that mirroring is resumed successfully. - void MirroringResumed() { - EXPECT_CALL(remoting_source_, OnSinkAvailable(_)); + void MirroringResumed(bool is_remoting_disabled) { + // When MediaRemoter is in the REMOTING_DISABLED state, it should not notify + // its remoting_source_ about available sinks. + EXPECT_CALL(remoting_source_, OnSinkAvailable(_)) + .Times(is_remoting_disabled ? 0 : 1); media_remoter_->OnMirroringResumed(); task_environment_.RunUntilIdle(); Mock::VerifyAndClear(&remoting_source_); @@ -361,7 +364,7 @@ StopRemoting(); // Signals that successfully switch to mirroring. - MirroringResumed(); + MirroringResumed(/* is_remoting_disabled */ false); // Now remoting can be started again. StartRemoting(); } @@ -370,6 +373,8 @@ CreateRemoter(); StartRemoting(); RemotingStartFailed(); + StopRemoting(); + MirroringResumed(/* is_remoting_disabled */ true); } TEST_P(MediaRemoterTest, SwitchBetweenMultipleSessions) { @@ -386,7 +391,7 @@ // Stop the remoting session and switch to mirroring. StopRemoting(); - MirroringResumed(); + MirroringResumed(/* is_remoting_disabled */ false); // Switch to remoting again. StartRemoting(); @@ -396,7 +401,7 @@ // Switch to mirroring again. StopRemoting(); - MirroringResumed(); + MirroringResumed(/* is_remoting_disabled */ false); } INSTANTIATE_TEST_SUITE_P(MediaRemoter,
diff --git a/components/ntp_snippets/user_classifier.cc b/components/ntp_snippets/user_classifier.cc index 848b6a7..eb51742 100644 --- a/components/ntp_snippets/user_classifier.cc +++ b/components/ntp_snippets/user_classifier.cc
@@ -11,7 +11,6 @@ #include "base/cxx17_backports.h" #include "base/logging.h" #include "base/metrics/field_trial_params.h" -#include "base/metrics/histogram_macros.h" #include "base/strings/string_number_conversions.h" #include "base/time/clock.h" #include "components/ntp_snippets/features.h" @@ -54,14 +53,6 @@ const char kRareUserOpensNTPAtMostOncePerHoursParam[] = "user_classifier_rare_user_opens_ntp_at_most_once_per_hours"; -// Histograms for logging the estimated average hours to next event. -const char kHistogramAverageHoursToOpenNTP[] = - "NewTabPage.UserClassifier.AverageHoursToOpenNTP"; -const char kHistogramAverageHoursToShowSuggestions[] = - "NewTabPage.UserClassifier.AverageHoursToShowSuggestions"; -const char kHistogramAverageHoursToUseSuggestions[] = - "NewTabPage.UserClassifier.AverageHoursToUseSuggestions"; - // The enum used for iteration. const UserClassifier::Metric kMetrics[] = { UserClassifier::Metric::NTP_OPENED, @@ -238,29 +229,7 @@ void UserClassifier::OnEvent(Metric metric) { DCHECK_NE(metric, Metric::COUNT); - double metric_value = UpdateMetricOnEvent(metric); - - double avg = GetEstimateHoursBetweenEvents( - metric_value, discount_rate_per_hour_, min_hours_, max_hours_); - // We use kMaxHours as the max value below as the maximum value for the - // histograms must be constant. - switch (metric) { - case Metric::NTP_OPENED: - UMA_HISTOGRAM_CUSTOM_COUNTS(kHistogramAverageHoursToOpenNTP, avg, 1, - kMaxHours, 50); - break; - case Metric::SUGGESTIONS_SHOWN: - UMA_HISTOGRAM_CUSTOM_COUNTS(kHistogramAverageHoursToShowSuggestions, avg, - 1, kMaxHours, 50); - break; - case Metric::SUGGESTIONS_USED: - UMA_HISTOGRAM_CUSTOM_COUNTS(kHistogramAverageHoursToUseSuggestions, avg, - 1, kMaxHours, 50); - break; - case Metric::COUNT: - NOTREACHED(); - break; - } + UpdateMetricOnEvent(metric); } double UserClassifier::GetEstimatedAvgTime(Metric metric) const { @@ -314,17 +283,17 @@ } } -double UserClassifier::UpdateMetricOnEvent(Metric metric) { +void UserClassifier::UpdateMetricOnEvent(Metric metric) { // The pref_service_ can be null in tests. if (!pref_service_) { - return 0; + return; } double hours_since_last_time = std::min(max_hours_, GetHoursSinceLastTime(metric)); // Ignore events within the same "browsing session". if (hours_since_last_time < min_hours_) { - return GetUpToDateMetricValue(metric); + return; } SetLastTimeToNow(metric); @@ -335,7 +304,6 @@ 1 + DiscountMetric(metric_value, hours_since_last_time, discount_rate_per_hour_); SetMetricValue(metric, new_metric_value); - return new_metric_value; } double UserClassifier::GetUpToDateMetricValue(Metric metric) const {
diff --git a/components/ntp_snippets/user_classifier.h b/components/ntp_snippets/user_classifier.h index 4cbba3d..e1c3e18 100644 --- a/components/ntp_snippets/user_classifier.h +++ b/components/ntp_snippets/user_classifier.h
@@ -20,8 +20,8 @@ namespace ntp_snippets { // Collects data about user usage patterns of content suggestions, computes -// long-term user metrics locally using pref, and reports the metrics to UMA. -// Based on these long-term user metrics, it classifies the user in a UserClass. +// long-term user metrics locally using pref. Based on these long-term user +// metrics, it classifies the user in a UserClass. class UserClassifier { public: // Enumeration listing user classes @@ -40,8 +40,7 @@ // event in this time interval. // See https://en.wikipedia.org/wiki/Exponential_discounting for more details. // We keep track of the following events. - // NOTE: if you add any element, add it also in the static arrays in .cc and - // create another histogram. + // NOTE: if you add any element, add it also in the static arrays in .cc. enum class Metric { NTP_OPENED, // When the user opens a new NTP - this indicates potential // use of content suggestions. @@ -82,7 +81,7 @@ private: // The event has happened, recompute the metric accordingly. Then store and // return the new value. - double UpdateMetricOnEvent(Metric metric); + void UpdateMetricOnEvent(Metric metric); // No event has happened but we need to get up-to-date metric, recompute and // return the new value. This function does not store the recomputed metric. double GetUpToDateMetricValue(Metric metric) const;
diff --git a/components/ntp_snippets/user_classifier_unittest.cc b/components/ntp_snippets/user_classifier_unittest.cc index 694c8d7..1005a7b 100644 --- a/components/ntp_snippets/user_classifier_unittest.cc +++ b/components/ntp_snippets/user_classifier_unittest.cc
@@ -8,7 +8,6 @@ #include <string> #include <utility> -#include "base/test/metrics/histogram_tester.h" #include "base/test/scoped_feature_list.h" #include "base/test/simple_test_clock.h" #include "base/time/time.h" @@ -140,8 +139,7 @@ class UserClassifierMetricTest : public UserClassifierTest, - public ::testing::WithParamInterface< - std::pair<UserClassifier::Metric, std::string>> { + public ::testing::WithParamInterface<UserClassifier::Metric> { public: UserClassifierMetricTest() = default; UserClassifierMetricTest(const UserClassifierMetricTest&) = delete; @@ -149,7 +147,7 @@ }; TEST_P(UserClassifierMetricTest, ShouldDecreaseEstimateAfterEvent) { - UserClassifier::Metric metric = GetParam().first; + UserClassifier::Metric metric = GetParam(); UserClassifier* user_classifier = CreateUserClassifier(); // The initial event does not decrease the estimate. @@ -163,18 +161,8 @@ } } -TEST_P(UserClassifierMetricTest, ShouldReportToUmaOnEvent) { - UserClassifier::Metric metric = GetParam().first; - const std::string& histogram_name = GetParam().second; - base::HistogramTester histogram_tester; - UserClassifier* user_classifier = CreateUserClassifier(); - - user_classifier->OnEvent(metric); - EXPECT_THAT(histogram_tester.GetAllSamples(histogram_name), SizeIs(1)); -} - TEST_P(UserClassifierMetricTest, ShouldConvergeTowardsPattern) { - UserClassifier::Metric metric = GetParam().first; + UserClassifier::Metric metric = GetParam(); UserClassifier* user_classifier = CreateUserClassifier(); // Have the pattern of an event every five hours and start changing it towards @@ -199,7 +187,7 @@ } TEST_P(UserClassifierMetricTest, ShouldIgnoreSubsequentEventsForHalfAnHour) { - UserClassifier::Metric metric = GetParam().first; + UserClassifier::Metric metric = GetParam(); UserClassifier* user_classifier = CreateUserClassifier(); // The initial event @@ -220,7 +208,7 @@ TEST_P(UserClassifierMetricTest, ShouldIgnoreSubsequentEventsWithIncreasedLimit) { - UserClassifier::Metric metric = GetParam().first; + UserClassifier::Metric metric = GetParam(); // Increase the min_hours to 1.0, i.e. 60 minutes. base::test::ScopedFeatureList scoped_feature_list; scoped_feature_list.InitAndEnableFeatureWithParameters( @@ -244,7 +232,7 @@ } TEST_P(UserClassifierMetricTest, ShouldCapDelayBetweenEvents) { - UserClassifier::Metric metric = GetParam().first; + UserClassifier::Metric metric = GetParam(); UserClassifier* user_classifier = CreateUserClassifier(); // The initial event @@ -267,7 +255,7 @@ TEST_P(UserClassifierMetricTest, ShouldCapDelayBetweenEventsWithDecreasedLimit) { - UserClassifier::Metric metric = GetParam().first; + UserClassifier::Metric metric = GetParam(); // Decrease the max_hours to 72, i.e. 3 days. base::test::ScopedFeatureList scoped_feature_list; scoped_feature_list.InitAndEnableFeatureWithParameters( @@ -295,15 +283,9 @@ INSTANTIATE_TEST_SUITE_P( NTP, UserClassifierMetricTest, - testing::Values( - std::make_pair(UserClassifier::Metric::NTP_OPENED, - "NewTabPage.UserClassifier.AverageHoursToOpenNTP"), - std::make_pair( - UserClassifier::Metric::SUGGESTIONS_SHOWN, - "NewTabPage.UserClassifier.AverageHoursToShowSuggestions"), - std::make_pair( - UserClassifier::Metric::SUGGESTIONS_USED, - "NewTabPage.UserClassifier.AverageHoursToUseSuggestions"))); + testing::Values(UserClassifier::Metric::NTP_OPENED, + UserClassifier::Metric::SUGGESTIONS_SHOWN, + UserClassifier::Metric::SUGGESTIONS_USED)); } // namespace } // namespace ntp_snippets
diff --git a/components/omnibox/browser/actions/history_clusters_action.cc b/components/omnibox/browser/actions/history_clusters_action.cc index f256e83..5523153 100644 --- a/components/omnibox/browser/actions/history_clusters_action.cc +++ b/components/omnibox/browser/actions/history_clusters_action.cc
@@ -168,8 +168,8 @@ OmniboxAction::Execute(context); } -int32_t HistoryClustersAction::GetID() const { - return static_cast<int32_t>(OmniboxActionId::HISTORY_CLUSTERS); +OmniboxActionId HistoryClustersAction::ActionId() const { + return OmniboxActionId::HISTORY_CLUSTERS; } #if defined(SUPPORT_PEDALS_VECTOR_ICONS) @@ -186,7 +186,7 @@ void HistoryClustersAction::CreateOrUpdateJavaObject(const std::string& query) { j_omnibox_action_.Reset(BuildHistoryClustersAction( - GetID(), strings_.hint, strings_.suggestion_contents, + strings_.hint, strings_.suggestion_contents, strings_.accessibility_suffix, strings_.accessibility_hint, url_, query)); } #endif
diff --git a/components/omnibox/browser/actions/history_clusters_action.h b/components/omnibox/browser/actions/history_clusters_action.h index 41a3c5d..025b48d 100644 --- a/components/omnibox/browser/actions/history_clusters_action.h +++ b/components/omnibox/browser/actions/history_clusters_action.h
@@ -52,7 +52,7 @@ void RecordActionShown(size_t position, bool executed) const override; void Execute(ExecutionContext& context) const override; - int32_t GetID() const override; + OmniboxActionId ActionId() const override; #if defined(SUPPORT_PEDALS_VECTOR_ICONS) const gfx::VectorIcon& GetVectorIcon() const override; #endif
diff --git a/components/omnibox/browser/actions/history_clusters_action_unittest.cc b/components/omnibox/browser/actions/history_clusters_action_unittest.cc index e1aae3f..aea6f37c 100644 --- a/components/omnibox/browser/actions/history_clusters_action_unittest.cc +++ b/components/omnibox/browser/actions/history_clusters_action_unittest.cc
@@ -113,8 +113,8 @@ for (size_t i = 0; i < matches_data.size(); ++i) { bool has_history_clusters_action = result.match_at(i)->GetPrimaryAction() && - result.match_at(i)->GetPrimaryAction()->GetID() == - static_cast<int32_t>(OmniboxActionId::HISTORY_CLUSTERS); + result.match_at(i)->GetPrimaryAction()->ActionId() == + OmniboxActionId::HISTORY_CLUSTERS; EXPECT_EQ(has_history_clusters_action, matches_data[i].expect_history_clusters_action); }
diff --git a/components/omnibox/browser/actions/omnibox_action.cc b/components/omnibox/browser/actions/omnibox_action.cc index 33825542..7cd9693 100644 --- a/components/omnibox/browser/actions/omnibox_action.cc +++ b/components/omnibox/browser/actions/omnibox_action.cc
@@ -105,8 +105,8 @@ return total; } -int32_t OmniboxAction::GetID() const { - return 0; +OmniboxActionId OmniboxAction::ActionId() const { + return OmniboxActionId::UNKNOWN; } #if BUILDFLAG(IS_ANDROID)
diff --git a/components/omnibox/browser/actions/omnibox_action.h b/components/omnibox/browser/actions/omnibox_action.h index 295de70..e3fa9ba 100644 --- a/components/omnibox/browser/actions/omnibox_action.h +++ b/components/omnibox/browser/actions/omnibox_action.h
@@ -12,6 +12,7 @@ #include "base/memory/ref_counted.h" #include "base/time/time.h" #include "build/build_config.h" +#include "components/omnibox/browser/actions/omnibox_action_concepts.h" #include "components/omnibox/browser/autocomplete_match_type.h" #include "components/omnibox/browser/buildflags.h" #include "components/search_engines/template_url.h" @@ -164,7 +165,7 @@ virtual size_t EstimateMemoryUsage() const; // Returns an ID used to identify the action. - virtual int32_t GetID() const; + virtual OmniboxActionId ActionId() const; #if BUILDFLAG(IS_ANDROID) virtual base::android::ScopedJavaGlobalRef<jobject> GetJavaObject() const;
diff --git a/components/omnibox/browser/actions/omnibox_action_concepts.h b/components/omnibox/browser/actions/omnibox_action_concepts.h index 1c23ba7..ad0a965 100644 --- a/components/omnibox/browser/actions/omnibox_action_concepts.h +++ b/components/omnibox/browser/actions/omnibox_action_concepts.h
@@ -8,24 +8,19 @@ #include "components/omnibox/browser/actions/omnibox_pedal_concepts.h" // Unique identifiers for actions that aren't pedals, e.g. the history clusters -// action. Do not remove or reuse values. The values here must remain disjoint -// with the OmniboxPedalId enum so they start at 10000. +// action. Do not remove or reuse values. // // Automatically generate a corresponding Java enum: // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.chrome.browser.omnibox.action // GENERATED_JAVA_CLASS_NAME_OVERRIDE: OmniboxActionType enum class OmniboxActionId { - FIRST = 10000, - HISTORY_CLUSTERS = 10001, + UNKNOWN = 0, + PEDAL, + HISTORY_CLUSTERS, - // Last value, used to track the upper bound. This intentionally does not have - // an assigned value to ensure that it's always 1 greater than the last - // assigned value. + // Keep as a last item in the list, with ID one larger than the last valid + // Action Id. LAST }; -static_assert(static_cast<int32_t>(OmniboxActionId::FIRST) > - static_cast<int32_t>(OmniboxPedalId::TOTAL_COUNT), - "OmniboxPedalId and OmniboxActionId must remain disjoint"); - #endif // COMPONENTS_OMNIBOX_BROWSER_ACTIONS_OMNIBOX_ACTION_CONCEPTS_H_
diff --git a/components/omnibox/browser/actions/omnibox_pedal.cc b/components/omnibox/browser/actions/omnibox_pedal.cc index 2ef5e754..aef3b0ee 100644 --- a/components/omnibox/browser/actions/omnibox_pedal.cc +++ b/components/omnibox/browser/actions/omnibox_pedal.cc
@@ -236,6 +236,14 @@ #endif } +/* static */ const OmniboxPedal* OmniboxPedal::FromAction( + const OmniboxAction* action) { + if (action && action->ActionId() == OmniboxActionId::PEDAL) { + return static_cast<const OmniboxPedal*>(action); + } + return nullptr; +} + OmniboxPedal::~OmniboxPedal() = default; void OmniboxPedal::OnLoaded() { @@ -275,7 +283,7 @@ } OmniboxPedalId OmniboxPedal::GetMetricsId() const { - return id(); + return PedalId(); } bool OmniboxPedal::IsConceptMatch(TokenSequence& match_sequence) const { @@ -312,8 +320,8 @@ return total; } -int32_t OmniboxPedal::GetID() const { - return static_cast<int32_t>(id()); +OmniboxActionId OmniboxPedal::ActionId() const { + return OmniboxActionId::PEDAL; } #if BUILDFLAG(IS_ANDROID) @@ -324,7 +332,7 @@ void OmniboxPedal::CreateOrUpdateJavaObject() { j_omnibox_action_.Reset(BuildOmniboxPedal( - GetID(), strings_.hint, strings_.suggestion_contents, + PedalId(), strings_.hint, strings_.suggestion_contents, strings_.accessibility_suffix, strings_.accessibility_hint, url_)); } #endif
diff --git a/components/omnibox/browser/actions/omnibox_pedal.h b/components/omnibox/browser/actions/omnibox_pedal.h index e6c8f08d..b3cfcc2 100644 --- a/components/omnibox/browser/actions/omnibox_pedal.h +++ b/components/omnibox/browser/actions/omnibox_pedal.h
@@ -176,6 +176,10 @@ OmniboxPedal(OmniboxPedalId id, LabelStrings strings, GURL url); + // Return an OmniboxPedal instance if the supplied OmniboxAction instance + // represents one. + static const OmniboxPedal* FromAction(const OmniboxAction* action); + // Called after the OmniboxPedalProvider finishes loading all pedals data. // This can be used to override implementation bits based on flags, etc. virtual void OnLoaded(); @@ -208,7 +212,7 @@ virtual std::vector<SynonymGroupSpec> SpecifySynonymGroups( bool locale_is_english) const; - OmniboxPedalId id() const { return id_; } + OmniboxPedalId PedalId() const { return id_; } // Sometimes pedals report different IDs for metrics, either to enable // feature discrimination (e.g. incognito mode) or to unify metrics @@ -228,7 +232,7 @@ const gfx::VectorIcon& GetVectorIcon() const override; #endif size_t EstimateMemoryUsage() const override; - int32_t GetID() const override; + OmniboxActionId ActionId() const override; #if BUILDFLAG(IS_ANDROID) base::android::ScopedJavaGlobalRef<jobject> GetJavaObject() const override;
diff --git a/components/omnibox/browser/actions/omnibox_pedal_jni_wrapper.cc b/components/omnibox/browser/actions/omnibox_pedal_jni_wrapper.cc index 3681b5a2..6ae5bcd 100644 --- a/components/omnibox/browser/actions/omnibox_pedal_jni_wrapper.cc +++ b/components/omnibox/browser/actions/omnibox_pedal_jni_wrapper.cc
@@ -14,7 +14,7 @@ #include "url/android/gurl_android.h" base::android::ScopedJavaGlobalRef<jobject> BuildOmniboxPedal( - int id, + OmniboxPedalId pedal_id, std::u16string hint, std::u16string suggestion_contents, std::u16string accessibility_suffix, @@ -22,7 +22,8 @@ GURL url) { JNIEnv* env = base::android::AttachCurrentThread(); return base::android::ScopedJavaGlobalRef(Java_OmniboxPedal_build( - env, id, base::android::ConvertUTF16ToJavaString(env, hint), + env, static_cast<int32_t>(pedal_id), + base::android::ConvertUTF16ToJavaString(env, hint), base::android::ConvertUTF16ToJavaString(env, suggestion_contents), base::android::ConvertUTF16ToJavaString(env, accessibility_suffix), base::android::ConvertUTF16ToJavaString(env, accessibility_hint), @@ -30,7 +31,6 @@ } base::android::ScopedJavaGlobalRef<jobject> BuildHistoryClustersAction( - int id, std::u16string hint, std::u16string suggestion_contents, std::u16string accessibility_suffix, @@ -39,7 +39,7 @@ std::string query) { JNIEnv* env = base::android::AttachCurrentThread(); return base::android::ScopedJavaGlobalRef(Java_HistoryClustersAction_build( - env, id, base::android::ConvertUTF16ToJavaString(env, hint), + env, base::android::ConvertUTF16ToJavaString(env, hint), base::android::ConvertUTF16ToJavaString(env, suggestion_contents), base::android::ConvertUTF16ToJavaString(env, accessibility_suffix), base::android::ConvertUTF16ToJavaString(env, accessibility_hint),
diff --git a/components/omnibox/browser/actions/omnibox_pedal_jni_wrapper.h b/components/omnibox/browser/actions/omnibox_pedal_jni_wrapper.h index 7fdb62a2..998949c 100644 --- a/components/omnibox/browser/actions/omnibox_pedal_jni_wrapper.h +++ b/components/omnibox/browser/actions/omnibox_pedal_jni_wrapper.h
@@ -6,7 +6,7 @@ #define COMPONENTS_OMNIBOX_BROWSER_ACTIONS_OMNIBOX_PEDAL_JNI_WRAPPER_H_ base::android::ScopedJavaGlobalRef<jobject> BuildOmniboxPedal( - int id, + OmniboxPedalId pedal_id, std::u16string hint, std::u16string suggestion_contents, std::u16string accessibility_suffix, @@ -14,7 +14,6 @@ GURL url); base::android::ScopedJavaGlobalRef<jobject> BuildHistoryClustersAction( - int id, std::u16string hint, std::u16string suggestion_contents, std::u16string accessibility_suffix,
diff --git a/components/omnibox/browser/actions/omnibox_pedal_provider_unittest.cc b/components/omnibox/browser/actions/omnibox_pedal_provider_unittest.cc index 663db33..3d3a13e 100644 --- a/components/omnibox/browser/actions/omnibox_pedal_provider_unittest.cc +++ b/components/omnibox/browser/actions/omnibox_pedal_provider_unittest.cc
@@ -26,7 +26,8 @@ MockAutocompleteProviderClient client; std::unordered_map<OmniboxPedalId, scoped_refptr<OmniboxPedal>> pedals; const auto add = [&](OmniboxPedal* pedal) { - pedals.insert(std::make_pair(pedal->id(), base::WrapRefCounted(pedal))); + pedals.insert( + std::make_pair(pedal->PedalId(), base::WrapRefCounted(pedal))); }; add(new TestOmniboxPedalClearBrowsingData()); client.set_pedal_provider(
diff --git a/components/omnibox/browser/android/java/src/org/chromium/components/omnibox/action/HistoryClustersAction.java b/components/omnibox/browser/android/java/src/org/chromium/components/omnibox/action/HistoryClustersAction.java index 2c21d50..0953413 100644 --- a/components/omnibox/browser/android/java/src/org/chromium/components/omnibox/action/HistoryClustersAction.java +++ b/components/omnibox/browser/android/java/src/org/chromium/components/omnibox/action/HistoryClustersAction.java
@@ -8,6 +8,8 @@ import androidx.annotation.Nullable; import org.chromium.base.annotations.CalledByNative; +import org.chromium.chrome.browser.omnibox.action.OmniboxActionType; +import org.chromium.chrome.browser.omnibox.action.OmniboxPedalType; import org.chromium.url.GURL; /** @@ -17,10 +19,11 @@ public class HistoryClustersAction extends OmniboxPedal { private final String mQuery; - public HistoryClustersAction(int id, @NonNull String hint, @NonNull String suggestionContents, + public HistoryClustersAction(@NonNull String hint, @NonNull String suggestionContents, @NonNull String accessibilitySuffix, @NonNull String accessibilityHint, @Nullable GURL url, @NonNull String query) { - super(id, hint, suggestionContents, accessibilitySuffix, accessibilityHint, url); + super(OmniboxActionType.HISTORY_CLUSTERS, OmniboxPedalType.NONE, hint, suggestionContents, + accessibilitySuffix, accessibilityHint, url); mQuery = query; } @@ -29,10 +32,10 @@ } @CalledByNative - private static HistoryClustersAction build(int id, @NonNull String hint, + private static HistoryClustersAction build(@NonNull String hint, @NonNull String suggestionContents, @NonNull String accessibilitySuffix, @NonNull String accessibilityHint, @Nullable GURL url, @NonNull String query) { return new HistoryClustersAction( - id, hint, suggestionContents, accessibilitySuffix, accessibilityHint, url, query); + hint, suggestionContents, accessibilitySuffix, accessibilityHint, url, query); } }
diff --git a/components/omnibox/browser/android/java/src/org/chromium/components/omnibox/action/OmniboxPedal.java b/components/omnibox/browser/android/java/src/org/chromium/components/omnibox/action/OmniboxPedal.java index a2e495d..3c2cfc4 100644 --- a/components/omnibox/browser/android/java/src/org/chromium/components/omnibox/action/OmniboxPedal.java +++ b/components/omnibox/browser/android/java/src/org/chromium/components/omnibox/action/OmniboxPedal.java
@@ -17,17 +17,20 @@ * please check on OmniboxAction class definition on native side. */ public class OmniboxPedal { - private final @OmniboxPedalType int mId; + private final @OmniboxActionType int mActionId; + private final @OmniboxPedalType int mPedalId; private final @NonNull String mHint; private final @NonNull String mSuggestionContents; private final @NonNull String mAccessibilitySuffix; private final @NonNull String mAccessibilityHint; private final @Nullable GURL mUrl; - public OmniboxPedal(@OmniboxPedalType int id, @NonNull String hint, - @NonNull String suggestionContents, @NonNull String accessibilitySuffix, - @NonNull String accessibilityHint, @Nullable GURL url) { - mId = id; + public OmniboxPedal(@OmniboxActionType int actionId, @OmniboxPedalType int pedalId, + @NonNull String hint, @NonNull String suggestionContents, + @NonNull String accessibilitySuffix, @NonNull String accessibilityHint, + @Nullable GURL url) { + mActionId = actionId; + mPedalId = pedalId; mHint = hint; mSuggestionContents = suggestionContents; mAccessibilitySuffix = accessibilitySuffix; @@ -35,28 +38,18 @@ mUrl = url; } - public boolean hasPedalId() { - return (mId >= OmniboxPedalType.NONE) && mId < (OmniboxPedalType.TOTAL_COUNT); - } - - public boolean hasActionId() { - return (mId >= OmniboxActionType.FIRST) && mId < (OmniboxActionType.LAST); - } - /** * @return an ID used to identify the underlying pedal. */ - public @OmniboxPedalType int getPedalID() { - assert hasPedalId(); - return mId; + public @OmniboxPedalType int getPedalId() { + return mPedalId; } /** * @return an ID used to identify the underlying action. */ - public @OmniboxActionType int getActionID() { - assert hasActionId(); - return mId; + public @OmniboxActionType int getActionId() { + return mActionId; } /** @@ -98,7 +91,7 @@ private static OmniboxPedal build(int id, @NonNull String hint, @NonNull String suggestionContents, @NonNull String accessibilitySuffix, @NonNull String accessibilityHint, @Nullable GURL url) { - return new OmniboxPedal( - id, hint, suggestionContents, accessibilitySuffix, accessibilityHint, url); + return new OmniboxPedal(OmniboxActionType.PEDAL, id, hint, suggestionContents, + accessibilitySuffix, accessibilityHint, url); } -} \ No newline at end of file +}
diff --git a/components/omnibox/browser/autocomplete_result_unittest.cc b/components/omnibox/browser/autocomplete_result_unittest.cc index 820eaf8a..14ddc32 100644 --- a/components/omnibox/browser/autocomplete_result_unittest.cc +++ b/components/omnibox/browser/autocomplete_result_unittest.cc
@@ -2391,7 +2391,8 @@ FakeAutocompleteProviderClient client; std::unordered_map<OmniboxPedalId, scoped_refptr<OmniboxPedal>> pedals; const auto add = [&](OmniboxPedal* pedal) { - pedals.insert(std::make_pair(pedal->id(), base::WrapRefCounted(pedal))); + pedals.insert( + std::make_pair(pedal->PedalId(), base::WrapRefCounted(pedal))); }; add(new TestOmniboxPedalClearBrowsingData()); client.set_pedal_provider( @@ -2455,8 +2456,8 @@ return true; })); ASSERT_NE(nullptr, result.begin()->GetActionWhere([](const auto& action) { - return action->GetID() == - static_cast<int32_t>(OmniboxPedalId::CLEAR_BROWSING_DATA); + const auto* pedal = OmniboxPedal::FromAction(action.get()); + return pedal && pedal->PedalId() == OmniboxPedalId::CLEAR_BROWSING_DATA; })); }
diff --git a/components/previous_session_info/README b/components/previous_session_info/README deleted file mode 100644 index ea885d60c..0000000 --- a/components/previous_session_info/README +++ /dev/null
@@ -1,3 +0,0 @@ -# PreviousSessionInfo - -PreviousSessionInfo is a component to allow using this code in other components code on iOS.
diff --git a/components/previous_session_info/README.md b/components/previous_session_info/README.md new file mode 100644 index 0000000..e13319b --- /dev/null +++ b/components/previous_session_info/README.md
@@ -0,0 +1,8 @@ +# PreviousSessionInfo + +This component exposes a class `PreviousSessionInfo` which holds information +about the last application session and persists information about the current +session. + +PreviousSessionInfo is implemented as a component to allow using this code in +other components code on iOS.
diff --git a/components/safe_browsing/core/browser/hashprefix_realtime/hash_realtime_service.cc b/components/safe_browsing/core/browser/hashprefix_realtime/hash_realtime_service.cc index d7cddcf..e76de70 100644 --- a/components/safe_browsing/core/browser/hashprefix_realtime/hash_realtime_service.cc +++ b/components/safe_browsing/core/browser/hashprefix_realtime/hash_realtime_service.cc
@@ -71,25 +71,43 @@ class ObliviousHttpClient : public network::mojom::ObliviousHttpClient { public: using OnCompletedCallback = - base::OnceCallback<void(const absl::optional<std::string>&, int)>; + base::OnceCallback<void(const absl::optional<std::string>&, int, int)>; explicit ObliviousHttpClient(OnCompletedCallback callback) : callback_(std::move(callback)) {} ~ObliviousHttpClient() override { if (!called_) { - std::move(callback_).Run(absl::nullopt, net::ERR_FAILED); + std::move(callback_).Run(absl::nullopt, net::ERR_FAILED, + /*response_code=*/0); } } - void OnCompleted(const absl::optional<std::string>& response, - int net_error) override { + void OnCompleted( + network::mojom::ObliviousHttpCompletionResultPtr status) override { if (called_) { mojo::ReportBadMessage("OnCompleted called more than once"); return; } called_ = true; - std::move(callback_).Run(response, net_error); + if (status->is_net_error()) { + std::move(callback_).Run(absl::nullopt, status->get_net_error(), + /*response_code=*/0); + } else if (status->is_outer_response_error_code()) { + std::move(callback_).Run(absl::nullopt, + net::ERR_HTTP_RESPONSE_CODE_FAILURE, + status->get_outer_response_error_code()); + } else { + DCHECK(status->is_inner_response()); + if (status->get_inner_response()->response_code != net::HTTP_OK) { + std::move(callback_).Run(absl::nullopt, + net::ERR_HTTP_RESPONSE_CODE_FAILURE, + status->get_inner_response()->response_code); + } else { + std::move(callback_).Run(status->get_inner_response()->response_body, + net::OK, net::HTTP_OK); + } + } } private: @@ -361,19 +379,17 @@ HPRTLookupResponseCallback response_callback, SBThreatType locally_cached_results_threat_type, const absl::optional<std::string>& response_body, - int net_error) { + int net_error, + int response_code) { // TODO(crbug.com/1407283): Notify ohttp_key_service_ if the error is key // related. auto response_body_ptr = std::make_unique<std::string>(response_body.value_or("")); - // TODO(crbug.com/1407283): Set response_code when the mojo interface exposes - // response_code. OnURLLoaderComplete( url, std::move(hash_prefixes_in_request), std::move(result_full_hashes), request_start_time, std::move(response_callback_task_runner), std::move(response_callback), locally_cached_results_threat_type, - std::move(response_body_ptr), net_error, - /*response_code=*/net::HTTP_OK); + std::move(response_body_ptr), net_error, response_code); } void HashRealTimeService::OnDirectURLLoaderComplete( @@ -417,7 +433,6 @@ int net_error, int response_code) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - base::UmaHistogramTimes("SafeBrowsing.HPRT.Network.Time", base::TimeTicks::Now() - request_start_time); RecordHttpResponseOrErrorCode("SafeBrowsing.HPRT.Network.Result", net_error, @@ -544,7 +559,8 @@ return base::unexpected(OperationResult::kParseError); } else if (ErrorIsRetriable(net_error, response_code)) { return base::unexpected(OperationResult::kRetriableError); - } else if (net_error != net::OK) { + } else if (net_error != net::OK && + net_error != net::ERR_HTTP_RESPONSE_CODE_FAILURE) { return base::unexpected(OperationResult::kNetworkError); } else if (response_code != net::HTTP_OK) { return base::unexpected(OperationResult::kHttpError);
diff --git a/components/safe_browsing/core/browser/hashprefix_realtime/hash_realtime_service.h b/components/safe_browsing/core/browser/hashprefix_realtime/hash_realtime_service.h index c520f064..8c61832 100644 --- a/components/safe_browsing/core/browser/hashprefix_realtime/hash_realtime_service.h +++ b/components/safe_browsing/core/browser/hashprefix_realtime/hash_realtime_service.h
@@ -86,7 +86,13 @@ private: friend class HashRealTimeServiceTest; - FRIEND_TEST_ALL_PREFIXES(HashRealTimeServiceTest, TestLookupFailure_Error); + FRIEND_TEST_ALL_PREFIXES(HashRealTimeServiceTest, TestLookupFailure_NetError); + FRIEND_TEST_ALL_PREFIXES(HashRealTimeServiceTest, + TestLookupFailure_NetErrorHttpCodeFailure); + FRIEND_TEST_ALL_PREFIXES(HashRealTimeServiceTest, + TestLookupFailure_OuterResponseCodeError); + FRIEND_TEST_ALL_PREFIXES(HashRealTimeServiceTest, + TestLookupFailure_InnerResponseCodeError); FRIEND_TEST_ALL_PREFIXES(HashRealTimeServiceTest, TestLookupFailure_ParseResponse); FRIEND_TEST_ALL_PREFIXES(HashRealTimeServiceTest, @@ -157,8 +163,8 @@ // Callback for requests sent via OHTTP. Most parameters are used by // |OnURLLoaderComplete|, see the description above |OnURLLoaderComplete| for - // details. |response_body| and |net_error| are returned from the OHTTP - // client. + // details. |response_body|, |net_error| and |response_code| are returned from + // the OHTTP client. void OnOhttpComplete( const GURL& url, const std::vector<std::string>& hash_prefixes_in_request, @@ -168,7 +174,8 @@ HPRTLookupResponseCallback response_callback, SBThreatType locally_cached_results_threat_type, const absl::optional<std::string>& response_body, - int net_error); + int net_error, + int response_code); // Callback for requests sent directly to the Safe Browsing server. Most // parameters are used by |OnURLLoaderComplete|, see the description above
diff --git a/components/safe_browsing/core/browser/hashprefix_realtime/hash_realtime_service_unittest.cc b/components/safe_browsing/core/browser/hashprefix_realtime/hash_realtime_service_unittest.cc index fa7c52e..e210bfb0 100644 --- a/components/safe_browsing/core/browser/hashprefix_realtime/hash_realtime_service_unittest.cc +++ b/components/safe_browsing/core/browser/hashprefix_realtime/hash_realtime_service_unittest.cc
@@ -58,17 +58,43 @@ } auto it = responses_.find(resource_url); ASSERT_TRUE(it != responses_.end()); - remote_->OnCompleted(responses_[resource_url].body, - responses_[resource_url].net_error); + if (responses_[resource_url].net_error.has_value()) { + auto completion_result = + network::mojom::ObliviousHttpCompletionResult::NewNetError( + responses_[resource_url].net_error.value()); + remote_->OnCompleted(std::move(completion_result)); + } else if (responses_[resource_url].outer_response_error_code.has_value()) { + auto completion_result = network::mojom::ObliviousHttpCompletionResult:: + NewOuterResponseErrorCode( + responses_[resource_url].outer_response_error_code.value()); + remote_->OnCompleted(std::move(completion_result)); + } else { + auto response = network::mojom::ObliviousHttpResponse::New(); + response->response_body = std::move(responses_[resource_url].body); + if (responses_[resource_url].inner_response_code.has_value()) { + response->response_code = + responses_[resource_url].inner_response_code.value(); + } else { + response->response_code = net::HTTP_OK; + } + auto completion_result = + network::mojom::ObliviousHttpCompletionResult::NewInnerResponse( + std::move(response)); + remote_->OnCompleted(std::move(completion_result)); + } remote_.reset(); } void AddResponse(std::string resource_url, - absl::optional<std::string> body, - int net_error) { + std::string body, + absl::optional<int> net_error, + absl::optional<int> outer_response_error_code, + absl::optional<int> inner_response_code) { Response response; response.body = body; response.net_error = net_error; + response.outer_response_error_code = outer_response_error_code; + response.inner_response_code = inner_response_code; responses_[GURL(resource_url)] = std::move(response); } @@ -82,8 +108,10 @@ private: struct Response { - absl::optional<std::string> body; - int net_error; + std::string body; + absl::optional<int> net_error; + absl::optional<int> outer_response_error_code; + absl::optional<int> inner_response_code; }; std::map<GURL, Response> responses_; @@ -213,7 +241,10 @@ const std::unique_ptr<V5::SearchHashesResponse>& response) { std::string expected_response_str; response->SerializeToString(&expected_response_str); - network_context_.AddResponse(request_url, expected_response_str, net::OK); + network_context_.AddResponse(request_url, expected_response_str, + /*net_error=*/absl::nullopt, + /*outer_response_error_code=*/absl::nullopt, + /*inner_response_code=*/absl::nullopt); } void SetUpLookupResponse(const std::string& request_url, const std::vector<V5::FullHash>& full_hashes) { @@ -387,13 +418,16 @@ } // Starts a lookup on |url| that is expected to fail. The simulated server // response body can be specified either by |response_full_hashes| or by - // |custom_response|. |net_error| represents the simulated OHTTP handler error - // code. Confirms that the lookup fails. + // |custom_response|. |net_error|, |outer_response_error_code| and + // |inner_response_code| represent the simulated OHTTP handler error. + // Confirms that the lookup fails. void RunRequestFailureTest( const GURL& url, const absl::optional<std::vector<V5::FullHash>>& response_full_hashes, - const absl::optional<std::string>& custom_response, - net::Error net_error, + const std::string& custom_response, + absl::optional<net::Error> net_error, + absl::optional<int> outer_response_error_code, + absl::optional<int> inner_response_code, int expected_prefix_count, int expected_network_result, HashRealTimeService::OperationResult expected_operation_result) { @@ -409,11 +443,10 @@ SetUpLookupResponse( /*request_url=*/expected_url, /*full_hashes=*/response_full_hashes.value()); - } else if (custom_response.has_value()) { - network_context_.AddResponse(expected_url, custom_response.value(), - net_error); } else { - network_context_.AddResponse(expected_url, absl::nullopt, net_error); + network_context_.AddResponse(expected_url, custom_response, net_error, + outer_response_error_code, + inner_response_code); } // Start lookup. @@ -521,7 +554,9 @@ request->add_hash_prefixes(hash_prefix); } std::string expected_url = GetExpectedRequestUrl(request); - network_context_.AddResponse(expected_url, "", net::ERR_FAILED); + network_context_.AddResponse(expected_url, "", net::ERR_FAILED, + /*outer_response_error_code=*/absl::nullopt, + /*inner_response_code=*/absl::nullopt); // Start lookup. base::MockCallback<HPRTLookupResponseCallback> response_callback; @@ -921,22 +956,64 @@ /*expected_found_unmatched_full_hashes=*/false); } -TEST_F(HashRealTimeServiceTest, TestLookupFailure_Error) { +TEST_F(HashRealTimeServiceTest, TestLookupFailure_NetError) { GURL url = GURL("https://example.test"); RunRequestFailureTest( /*url=*/url, /*response_full_hashes=*/absl::nullopt, - /*custom_response=*/absl::nullopt, - /*net_error=*/net::ERR_FAILED, /*expected_prefix_count=*/1, + /*custom_response=*/"", + /*net_error=*/net::ERR_FAILED, + /*outer_response_error_code=*/absl::nullopt, + /*inner_response_code=*/absl::nullopt, + /*expected_prefix_count=*/1, /*expected_network_result=*/net::ERR_FAILED, /*expected_operation_result=*/ HashRealTimeService::OperationResult::kNetworkError); } +TEST_F(HashRealTimeServiceTest, TestLookupFailure_NetErrorHttpCodeFailure) { + GURL url = GURL("https://example.test"); + RunRequestFailureTest( + /*url=*/url, /*response_full_hashes=*/absl::nullopt, + /*custom_response=*/"", + /*net_error=*/net::ERR_HTTP_RESPONSE_CODE_FAILURE, + /*outer_response_error_code=*/absl::nullopt, + /*inner_response_code=*/absl::nullopt, + /*expected_prefix_count=*/1, + /*expected_network_result=*/0, + /*expected_operation_result=*/ + HashRealTimeService::OperationResult::kHttpError); +} +TEST_F(HashRealTimeServiceTest, TestLookupFailure_OuterResponseCodeError) { + GURL url = GURL("https://example.test"); + RunRequestFailureTest( + /*url=*/url, /*response_full_hashes=*/absl::nullopt, + /*custom_response=*/"", + /*net_error=*/absl::nullopt, + /*outer_response_error_code=*/net::HTTP_NOT_FOUND, + /*inner_response_code=*/absl::nullopt, + /*expected_prefix_count=*/1, + /*expected_network_result=*/net::HTTP_NOT_FOUND, + /*expected_operation_result=*/ + HashRealTimeService::OperationResult::kHttpError); +} +TEST_F(HashRealTimeServiceTest, TestLookupFailure_InnerResponseCodeError) { + GURL url = GURL("https://example.test"); + RunRequestFailureTest( + /*url=*/url, /*response_full_hashes=*/absl::nullopt, + /*custom_response=*/"", + /*net_error=*/absl::nullopt, /*outer_response_error_code=*/absl::nullopt, + /*inner_response_code=*/net::HTTP_UNAUTHORIZED, + /*expected_prefix_count=*/1, + /*expected_network_result=*/net::HTTP_UNAUTHORIZED, + /*expected_operation_result=*/ + HashRealTimeService::OperationResult::kHttpError); +} TEST_F(HashRealTimeServiceTest, TestLookupFailure_ParseResponse) { GURL url = GURL("https://example.test"); RunRequestFailureTest( /*url=*/url, /*response_full_hashes=*/absl::nullopt, /*custom_response=*/"howdy", - /*net_error=*/net::OK, /*expected_prefix_count=*/1, + /*net_error=*/absl::nullopt, /*outer_response_error_code=*/absl::nullopt, + /*inner_response_code=*/absl::nullopt, /*expected_prefix_count=*/1, /*expected_network_result=*/net::HTTP_OK, /*expected_operation_result=*/ HashRealTimeService::OperationResult::kParseError); @@ -948,8 +1025,9 @@ /*url=*/url, /*response_full_hashes=*/ absl::optional<std::vector<V5::FullHash>>({CreateFullHashProto( {V5::ThreatType::SOCIAL_ENGINEERING}, short_full_hash)}), - /*custom_response=*/absl::nullopt, - /*net_error=*/net::OK, /*expected_prefix_count=*/1, + /*custom_response=*/"", + /*net_error=*/absl::nullopt, /*outer_response_error_code=*/absl::nullopt, + /*inner_response_code=*/absl::nullopt, /*expected_prefix_count=*/1, /*expected_network_result=*/net::HTTP_OK, /*expected_operation_result=*/ HashRealTimeService::OperationResult::kIncorrectFullHashLengthError); @@ -963,7 +1041,8 @@ RunRequestFailureTest( /*url=*/url, /*response_full_hashes=*/{}, /*custom_response=*/response_str, - /*net_error=*/net::OK, + /*net_error=*/absl::nullopt, /*outer_response_error_code=*/absl::nullopt, + /*inner_response_code=*/absl::nullopt, /*expected_prefix_count=*/1, /*expected_network_result=*/net::HTTP_OK, /*expected_operation_result=*/
diff --git a/components/safe_browsing/core/browser/safe_browsing_metrics_collector.cc b/components/safe_browsing/core/browser/safe_browsing_metrics_collector.cc index 5317738..15e5bd5a 100644 --- a/components/safe_browsing/core/browser/safe_browsing_metrics_collector.cc +++ b/components/safe_browsing/core/browser/safe_browsing_metrics_collector.cc
@@ -127,21 +127,11 @@ if (IsBypassEventType(event_type)) { int bypass_count = GetEventCountSince(user_state, event_type, base::Time::Now() - base::Days(28)); - base::UmaHistogramCounts100("SafeBrowsing.Daily.BypassCountLast28Days." + - GetUserStateMetricSuffix(user_state) + - "." + - GetEventTypeMetricSuffix(event_type), - bypass_count); total_bypass_count += bypass_count; } if (IsSecuritySensitiveEventType(event_type)) { int security_sensitive_event_count = GetEventCountSince( user_state, event_type, base::Time::Now() - base::Days(28)); - base::UmaHistogramCounts100( - "SafeBrowsing.Daily.SecuritySensitiveCountLast28Days." + - GetUserStateMetricSuffix(user_state) + "." + - GetEventTypeMetricSuffix(event_type), - security_sensitive_event_count); total_security_sensitive_event_count += security_sensitive_event_count; } } @@ -160,13 +150,6 @@ prefs::kSafeBrowsingEventTimestamps); base::Value::Dict& mutable_state_dict = update.Get(); - // Histogram to check whether prefs::kSafeBrowsingEventTimestamp is a dict. - // Prefs DCHECKs if it's the wrong type, or not registered, so this is not - // actually needed. - // - // TODO(mmenke): Remove this histogram. - base::UmaHistogramBoolean("SafeBrowsing.MetricsCollector.IsPrefValid", true); - for (auto state_map : mutable_state_dict) { for (auto event_map : state_map.second.GetDict()) { event_map.second.GetList().EraseIf([&](const auto& timestamp) { @@ -356,25 +339,6 @@ return; } - for (int event_type_int = 0; event_type_int <= EventType::kMaxValue; - event_type_int += 1) { - EventType event_type = static_cast<EventType>(event_type_int); - if (IsBypassEventType(event_type)) { - base::UmaHistogramCounts100( - "SafeBrowsing.EsbDisabled.BypassCountLast28Days." + - GetEventTypeMetricSuffix(event_type), - GetEventCountSince(UserState::kEnhancedProtection, event_type, - base::Time::Now() - base::Days(28))); - } - if (IsSecuritySensitiveEventType(event_type)) { - base::UmaHistogramCounts100( - "SafeBrowsing.EsbDisabled.SecuritySensitiveCountLast28Days." + - GetEventTypeMetricSuffix(event_type), - GetEventCountSince(UserState::kEnhancedProtection, event_type, - base::Time::Now() - base::Days(28))); - } - } - absl::optional<SafeBrowsingMetricsCollector::Event> latest_bypass_event = GetLatestEventFromEventTypeFilter( UserState::kEnhancedProtection, @@ -384,12 +348,6 @@ base::UmaHistogramEnumeration( "SafeBrowsing.EsbDisabled.LastBypassEventType", latest_bypass_event->type); - base::UmaHistogramCustomTimes( - "SafeBrowsing.EsbDisabled.LastBypassEventInterval." + - GetEventTypeMetricSuffix(latest_bypass_event->type), - /* sample */ base::Time::Now() - latest_bypass_event->timestamp, - /* min */ base::Seconds(1), - /* max */ base::Days(1), /* buckets */ 50); } absl::optional<SafeBrowsingMetricsCollector::Event> @@ -401,13 +359,6 @@ base::UmaHistogramEnumeration( "SafeBrowsing.EsbDisabled.LastSecuritySensitiveEventType", latest_security_sensitive_event->type); - base::UmaHistogramCustomTimes( - "SafeBrowsing.EsbDisabled.LastSecuritySensitiveEventInterval." + - GetEventTypeMetricSuffix(latest_security_sensitive_event->type), - /* sample */ base::Time::Now() - - latest_security_sensitive_event->timestamp, - /* min */ base::Seconds(1), - /* max */ base::Days(1), /* buckets */ 50); } const absl::optional<Event> latest_enabled_event =
diff --git a/components/safe_browsing/core/browser/safe_browsing_metrics_collector_unittest.cc b/components/safe_browsing/core/browser/safe_browsing_metrics_collector_unittest.cc index d115494..07e6875 100644 --- a/components/safe_browsing/core/browser/safe_browsing_metrics_collector_unittest.cc +++ b/components/safe_browsing/core/browser/safe_browsing_metrics_collector_unittest.cc
@@ -264,25 +264,6 @@ histograms.ExpectUniqueSample("SafeBrowsing.EsbDisabled.LastBypassEventType", /* sample */ EventType::CSD_INTERSTITIAL_BYPASS, /* expected_count */ 1); - histograms.ExpectUniqueTimeSample( - "SafeBrowsing.EsbDisabled.LastBypassEventInterval.CsdInterstitialBypass", - /* sample */ base::Hours(1), - /* expected_count */ 1); - histograms.ExpectBucketCount( - "SafeBrowsing.EsbDisabled.BypassCountLast28Days." - "DatabaseInterstitialBypass", - /* sample */ 2, - /* expected_count */ 1); - histograms.ExpectBucketCount( - "SafeBrowsing.EsbDisabled.BypassCountLast28Days." - "CsdInterstitialBypass", - /* sample */ 2, - /* expected_count */ 1); - histograms.ExpectBucketCount( - "SafeBrowsing.EsbDisabled.BypassCountLast28Days." - "RealTimeInterstitialBypass", - /* sample */ 0, - /* expected_count */ 1); // Changing standard protection to enhanced protection shouldn't log the // metric. @@ -298,30 +279,6 @@ SetSafeBrowsingState(&pref_service_, SafeBrowsingState::NO_SAFE_BROWSING); histograms.ExpectTotalCount("SafeBrowsing.EsbDisabled.LastBypassEventType", /* expected_count */ 2); - histograms.ExpectBucketCount( - "SafeBrowsing.EsbDisabled.LastBypassEventType", - /* sample */ EventType::REAL_TIME_INTERSTITIAL_BYPASS, - /* expected_count */ 1); - histograms.ExpectTimeBucketCount( - "SafeBrowsing.EsbDisabled.LastBypassEventInterval." - "RealTimeInterstitialBypass", - /* sample */ base::Days(1), - /* expected_count */ 1); - histograms.ExpectBucketCount( - "SafeBrowsing.EsbDisabled.BypassCountLast28Days." - "DatabaseInterstitialBypass", - /* sample */ 2, - /* expected_count */ 2); - histograms.ExpectBucketCount( - "SafeBrowsing.EsbDisabled.BypassCountLast28Days." - "CsdInterstitialBypass", - /* sample */ 2, - /* expected_count */ 2); - histograms.ExpectBucketCount( - "SafeBrowsing.EsbDisabled.BypassCountLast28Days." - "RealTimeInterstitialBypass", - /* sample */ 1, - /* expected_count */ 1); // Changing no protection to enhanced protection shouldn't log the metric. SetSafeBrowsingState(&pref_service_, SafeBrowsingState::ENHANCED_PROTECTION); @@ -344,21 +301,6 @@ "SafeBrowsing.EsbDisabled.LastSecuritySensitiveEventType", /* sample */ EventType::SECURITY_SENSITIVE_SAFE_BROWSING_INTERSTITIAL, /* expected_count */ 1); - histograms.ExpectUniqueTimeSample( - "SafeBrowsing.EsbDisabled.LastSecuritySensitiveEventInterval." - "SafeBrowsingInterstitial", - /* sample */ base::Hours(1), - /* expected_count */ 1); - histograms.ExpectBucketCount( - "SafeBrowsing.EsbDisabled.SecuritySensitiveCountLast28Days." - "SafeBrowsingInterstitial", - /* sample */ 1, - /* expected_count */ 1); - histograms.ExpectBucketCount( - "SafeBrowsing.EsbDisabled.SecuritySensitiveCountLast28Days." - "SSLInterstitial", - /* sample */ 0, - /* expected_count */ 1); // Changing standard protection to enhanced protection shouldn't log the // metric. @@ -376,16 +318,6 @@ histograms.ExpectTotalCount( "SafeBrowsing.EsbDisabled.LastSecuritySensitiveEventType", /* expected_count */ 2); - histograms.ExpectTimeBucketCount( - "SafeBrowsing.EsbDisabled.LastSecuritySensitiveEventInterval." - "SafeBrowsingInterstitial", - /* sample */ base::Days(1), - /* expected_count */ 1); - histograms.ExpectBucketCount( - "SafeBrowsing.EsbDisabled.SecuritySensitiveCountLast28Days." - "SafeBrowsingInterstitial", - /* sample */ 2, - /* expected_count */ 1); // Changing no protection to enhanced protection shouldn't log the metric. SetSafeBrowsingState(&pref_service_, SafeBrowsingState::ENHANCED_PROTECTION); @@ -637,21 +569,6 @@ "SafeBrowsing.Daily.BypassCountLast28Days.EnhancedProtection.AllEvents", /* sample */ 4, /* expected_count */ 1); - histograms.ExpectBucketCount( - "SafeBrowsing.Daily.BypassCountLast28Days.EnhancedProtection." - "DatabaseInterstitialBypass", - /* sample */ 2, - /* expected_count */ 1); - histograms.ExpectBucketCount( - "SafeBrowsing.Daily.BypassCountLast28Days.EnhancedProtection." - "CsdInterstitialBypass", - /* sample */ 1, - /* expected_count */ 1); - histograms.ExpectBucketCount( - "SafeBrowsing.Daily.BypassCountLast28Days.EnhancedProtection." - "RealTimeInterstitialBypass", - /* sample */ 1, - /* expected_count */ 1); histograms.ExpectTotalCount( "SafeBrowsing.Daily.SecuritySensitiveCountLast28Days.EnhancedProtection." "AllEvents", @@ -661,11 +578,6 @@ "AllEvents", /* sample */ 2, /* expected_count */ 1); - histograms.ExpectBucketCount( - "SafeBrowsing.Daily.SecuritySensitiveCountLast28Days.EnhancedProtection." - "SafeBrowsingInterstitial", - /* sample */ 2, - /* expected_count */ 1); FastForwardAndAddEvent(base::Hours(1), EventType::CSD_INTERSTITIAL_BYPASS); task_environment_.FastForwardBy(base::Days(1)); @@ -676,11 +588,6 @@ "SafeBrowsing.Daily.BypassCountLast28Days.EnhancedProtection.AllEvents", /* sample */ 5, /* expected_count */ 1); - histograms.ExpectBucketCount( - "SafeBrowsing.Daily.BypassCountLast28Days.EnhancedProtection." - "CsdInterstitialBypass", - /* sample */ 2, - /* expected_count */ 1); task_environment_.FastForwardBy(base::Days(1)); histograms.ExpectTotalCount( @@ -690,11 +597,6 @@ "SafeBrowsing.Daily.BypassCountLast28Days.EnhancedProtection.AllEvents", /* sample */ 5, /* expected_count */ 2); - histograms.ExpectBucketCount( - "SafeBrowsing.Daily.BypassCountLast28Days.EnhancedProtection." - "CsdInterstitialBypass", - /* sample */ 2, - /* expected_count */ 2); } TEST_F(SafeBrowsingMetricsCollectorTest, @@ -715,16 +617,6 @@ "SafeBrowsing.Daily.BypassCountLast28Days.EnhancedProtection.AllEvents", /* sample */ 1, /* expected_count */ 1); - histograms.ExpectBucketCount( - "SafeBrowsing.Daily.BypassCountLast28Days.EnhancedProtection." - "DatabaseInterstitialBypass", - /* sample */ 0, - /* expected_count */ 0); - histograms.ExpectBucketCount( - "SafeBrowsing.Daily.BypassCountLast28Days.EnhancedProtection." - "DatabaseInterstitialBypass", - /* sample */ 1, - /* expected_count */ 1); task_environment_.FastForwardBy(base::Days(28)); // The event is older than 28 days, so it shouldn't be counted. @@ -732,11 +624,6 @@ "SafeBrowsing.Daily.BypassCountLast28Days.EnhancedProtection.AllEvents", /* sample */ 0, /* expected_count */ 1); - histograms.ExpectBucketCount( - "SafeBrowsing.Daily.BypassCountLast28Days.EnhancedProtection." - "DatabaseInterstitialBypass", - /* sample */ 0, - /* expected_count */ 1); } TEST_F(SafeBrowsingMetricsCollectorTest, @@ -790,10 +677,6 @@ task_environment_.FastForwardBy(base::Days(1)); // The CSD event is also removed because it was logged more than 30 days now. EXPECT_EQ(0u, csd_timestamps.size()); - - histograms.ExpectUniqueSample("SafeBrowsing.MetricsCollector.IsPrefValid", - /* sample */ 1, - /* expected_count */ 32); } TEST_F(SafeBrowsingMetricsCollectorTest, GetUserState) {
diff --git a/components/sessions/core/command_storage_backend.cc b/components/sessions/core/command_storage_backend.cc index a4d6d75..981a148 100644 --- a/components/sessions/core/command_storage_backend.cc +++ b/components/sessions/core/command_storage_backend.cc
@@ -19,6 +19,7 @@ #include "base/strings/string_util.h" #include "base/task/sequenced_task_runner.h" #include "base/task/single_thread_task_runner.h" +#include "base/time/default_clock.h" #include "build/build_config.h" #include "components/sessions/core/session_constants.h" #include "components/sessions/core/session_service_commands.h" @@ -423,6 +424,9 @@ // CommandStorageBackend // ------------------------------------------------------------- +CommandStorageBackend::OpenFile::OpenFile() = default; +CommandStorageBackend::OpenFile::~OpenFile() = default; + // static const int CommandStorageBackend::kFileReadBufferSize = 1024; @@ -434,12 +438,14 @@ scoped_refptr<base::SequencedTaskRunner> owning_task_runner, const base::FilePath& path, SessionType type, - const std::vector<uint8_t>& decryption_key) + const std::vector<uint8_t>& decryption_key, + base::Clock* clock) : RefCountedDeleteOnSequence(owning_task_runner), type_(type), supplied_path_(path), initial_decryption_key_(decryption_key), - callback_task_runner_(base::SingleThreadTaskRunner::GetCurrentDefault()) { + callback_task_runner_(base::SingleThreadTaskRunner::GetCurrentDefault()), + clock_(clock ? clock : base::DefaultClock::GetInstance()) { // This is invoked on the main thread, don't do file access here. } @@ -465,8 +471,9 @@ // initial state has been supplied. To do otherwise would mean the file never // contains the marker, and would not be considered // valid. This includes first time through. - if (!truncate && (!file_ || !file_->IsValid())) + if (!truncate && !open_file_) { return; + } if (truncate) { CloseFile(); @@ -485,30 +492,38 @@ DCHECK(crypto_key.empty()); } - // Make sure and check |file_|, if opening the file failed |file_| will be - // null. - if (truncate || !file_ || !file_->IsValid()) + // Make sure and check `open_file_`, if opening the file failed `open_file_` + // will be null. + if (truncate || !open_file_) { TruncateOrOpenFile(); + } - // Check |file_| again as TruncateOrOpenFile() may fail. - if (file_ && file_->IsValid() && - !AppendCommandsToFile(file_.get(), commands)) { + // Check `open_file_` again as TruncateOrOpenFile() may fail. + if (open_file_ && !AppendCommandsToFile(open_file_->file.get(), commands)) { CloseFile(); } - if (truncate && file_ && file_->IsValid()) { - did_write_marker_ = true; + if (truncate && open_file_) { + // When `truncate` is true, a new file should be created, which means + // `did_write_marker` should be false. + DCHECK(!open_file_->did_write_marker); + open_file_->did_write_marker = true; if (last_file_with_valid_marker_) { - DCHECK_NE(*last_file_with_valid_marker_, current_path_); + // `last_file_with_valid_marker_` is only set after a truncation, which + // signals a new path should be used and that the two paths should not + // be equal (TruncateOrOpenFile() assigns a new path every time it's + // called). + DCHECK_NE(*last_file_with_valid_marker_, open_file_->path); base::DeleteFile(*last_file_with_valid_marker_); last_file_with_valid_marker_.reset(); } - last_file_with_valid_marker_ = current_path_; + last_file_with_valid_marker_ = open_file_->path; } - // If `file_` is null, there was an error in writing. - if (!file_ && error_callback) + // If `open_file_` is null, there was an error in writing. + if (!open_file_ && error_callback) { callback_task_runner_->PostTask(FROM_HERE, std::move(error_callback)); + } } // static @@ -574,8 +589,6 @@ } last_session_info_ = new_last_session_info; - // This ensures TruncateOrOpenFile() opens the file. - current_path_.clear(); TruncateOrOpenFile(); } @@ -639,22 +652,27 @@ } void CommandStorageBackend::CloseFile() { - file_.reset(); + if (!open_file_) { + return; + } + + // Close the file first, so that if we delete the file we won't have it open + // for writing (which may cause deletion to fail). + open_file_->file.reset(); // If a marker wasn't written, no need to keep the current file. - if (!did_write_marker_ && !current_path_.empty()) - base::DeleteFile(current_path_); + if (!open_file_->did_write_marker) { + base::DeleteFile(open_file_->path); + } + + open_file_.reset(); } void CommandStorageBackend::TruncateOrOpenFile() { DCHECK(inited_); CloseFile(); - DCHECK(!file_); - base::Time new_timestamp = base::Time::Now(); - // Ensure we don't reuse the current file (this is extremely unlikely to - // ever be true). - if (new_timestamp == timestamp_) - new_timestamp += base::Microseconds(1); + DCHECK(!open_file_); + base::Time new_timestamp = clock_->Now(); if (last_session_info_) { // Ensure that the last session's timestamp is before the current file's. // This might not be true if the system clock has changed. @@ -662,11 +680,20 @@ new_timestamp = last_session_info_->timestamp + base::Microseconds(1); } } + // Ensure we don't reuse the timestamp, and that it's always increasing. If + // we didn't do this, and the clock time goes backwards, we could potentially + // reuse a filepath, resulting in writing on top of an existing file. + if (new_timestamp <= timestamp_) { + new_timestamp = timestamp_ + base::Microseconds(1); + } timestamp_ = new_timestamp; - current_path_ = FilePathFromTime(type_, supplied_path_, timestamp_); - file_ = OpenAndWriteHeader(current_path_); + std::unique_ptr<OpenFile> open_file = std::make_unique<OpenFile>(); + open_file->path = FilePathFromTime(type_, supplied_path_, timestamp_); + open_file->file = OpenAndWriteHeader(open_file->path); + if (open_file->file) { + open_file_ = std::move(open_file); + } commands_written_ = 0; - did_write_marker_ = false; } std::unique_ptr<base::File> CommandStorageBackend::OpenAndWriteHeader( @@ -769,8 +796,8 @@ absl::optional<CommandStorageBackend::SessionInfo> CommandStorageBackend::FindLastSessionFile() const { // Determine the session with the most recent timestamp. This is called - // at startup, before `current_path_` is set, so no need to check it. - DCHECK(current_path_.empty()); + // at startup, before a file has been opened for writing. + DCHECK(!open_file_); for (const SessionInfo& session : GetSessionFilesSortedByReverseTimestamp()) { if (CanUseFileForLastSession(session.path)) return session; @@ -788,8 +815,8 @@ void CommandStorageBackend::DeleteLastSessionFiles() const { // Delete session files whose paths do not match the last session path. This - // at startup, before `current_path_` is set, so no need to check it. - DCHECK(current_path_.empty()); + // is called at startup, before a file has been opened for writing. + DCHECK(!open_file_); for (const SessionInfo& session : GetSessionFilesSortedByReverseTimestamp()) { if (!last_session_info_ || session.path != last_session_info_->path) base::DeleteFile(session.path);
diff --git a/components/sessions/core/command_storage_backend.h b/components/sessions/core/command_storage_backend.h index fbb6601..2b24d894 100644 --- a/components/sessions/core/command_storage_backend.h +++ b/components/sessions/core/command_storage_backend.h
@@ -22,6 +22,7 @@ #include "third_party/abseil-cpp/absl/types/optional.h" namespace base { +class Clock; class File; } @@ -89,7 +90,8 @@ scoped_refptr<base::SequencedTaskRunner> owning_task_runner, const base::FilePath& path, CommandStorageManager::SessionType type, - const std::vector<uint8_t>& decryption_key = {}); + const std::vector<uint8_t>& decryption_key = {}, + base::Clock* clock = nullptr); CommandStorageBackend(const CommandStorageBackend&) = delete; CommandStorageBackend& operator=(const CommandStorageBackend&) = delete; @@ -97,7 +99,14 @@ static bool IsValidFile(const base::FilePath& path); // Returns the path the files are being written to. - const base::FilePath& current_path() const { return current_path_; } + const base::FilePath current_path() const { + return open_file_ ? open_file_->path : base::FilePath(); + } + + bool IsFileOpen() const { + return open_file_.get() != nullptr; + ; + } base::SequencedTaskRunner* owning_task_runner() { return base::RefCountedDeleteOnSequence< @@ -152,6 +161,16 @@ base::Time timestamp; }; + struct OpenFile { + OpenFile(); + ~OpenFile(); + + base::FilePath path; + std::unique_ptr<base::File> file; + // Set to true once `kInitialStateMarkerCommandId` is written. + bool did_write_marker = false; + }; + ~CommandStorageBackend(); // Performs initialization on the background task run, calling DoInit() if @@ -243,11 +262,10 @@ // TaskRunner that the callback is added to. scoped_refptr<base::SequencedTaskRunner> callback_task_runner_; - // Path commands are currently being saved to. - base::FilePath current_path_; + raw_ptr<base::Clock> clock_; - // This may be null, created as necessary. - std::unique_ptr<base::File> file_; + // File and path commands are being written. + std::unique_ptr<OpenFile> open_file_; // Whether DoInit() was called. DoInit() is called on the background task // runner. @@ -259,9 +277,6 @@ // Incremented every time a command is written. int commands_written_ = 0; - // Set to true once `kInitialStateMarkerCommandId` is written. - bool did_write_marker_ = false; - // Timestamp when this session was started. base::Time timestamp_;
diff --git a/components/sessions/core/command_storage_backend_unittest.cc b/components/sessions/core/command_storage_backend_unittest.cc index f9e3612..553cdbc1 100644 --- a/components/sessions/core/command_storage_backend_unittest.cc +++ b/components/sessions/core/command_storage_backend_unittest.cc
@@ -18,6 +18,7 @@ #include "base/run_loop.h" #include "base/strings/string_util.h" #include "base/test/bind.h" +#include "base/test/simple_test_clock.h" #include "base/test/task_environment.h" #include "base/time/time.h" #include "components/sessions/core/command_storage_manager.h" @@ -81,10 +82,11 @@ } scoped_refptr<CommandStorageBackend> CreateBackend( - const std::vector<uint8_t>& decryption_key = {}) { + const std::vector<uint8_t>& decryption_key = {}, + base::Clock* clock = nullptr) { return MakeRefCounted<CommandStorageBackend>( task_environment_.GetMainThreadTaskRunner(), file_path_, - CommandStorageManager::SessionType::kOther, decryption_key); + CommandStorageManager::SessionType::kOther, decryption_key, clock); } scoped_refptr<CommandStorageBackend> CreateBackendWithRestoreType() { @@ -780,19 +782,17 @@ SessionCommands commands; commands.push_back(CreateCommandFromData(data)); backend->AppendCommands(std::move(commands), true, base::DoNothing()); - const base::FilePath path1 = backend->current_path(); - EXPECT_FALSE(path1.empty()); + EXPECT_TRUE(backend->IsFileOpen()); // Make appending fail, which should close the file. backend->ForceAppendCommandsToFailForTesting(); backend->AppendCommands({}, false, base::DoNothing()); + EXPECT_FALSE(backend->IsFileOpen()); - // Append again, with another fail. Should attempt to reopen file. + // Append again, with another fail. Should attempt to reopen file and file. backend->ForceAppendCommandsToFailForTesting(); backend->AppendCommands({}, true, base::DoNothing()); - const base::FilePath path2 = backend->current_path(); - EXPECT_FALSE(path2.empty()); - EXPECT_NE(path1, path2); + EXPECT_FALSE(backend->IsFileOpen()); // Reopen and read last session. Should get `data` and marker. backend = nullptr; @@ -803,4 +803,35 @@ AssertCommandEqualsData(data, commands[0].get()); } +TEST_F(CommandStorageBackendTest, PathTimeIncreases) { + base::SimpleTestClock test_clock; + test_clock.SetNow(base::Time::Now()); + scoped_refptr<CommandStorageBackend> backend = CreateBackend({}, &test_clock); + // Write `data` and a marker. + struct TestData data = {11, "X"}; + SessionCommands commands; + commands.push_back(CreateCommandFromData(data)); + backend->AppendCommands(std::move(commands), true, base::DoNothing()); + const base::FilePath path1 = backend->current_path(); + EXPECT_FALSE(path1.empty()); + base::Time path1_time; + EXPECT_TRUE(CommandStorageBackend::TimestampFromPath(path1, path1_time)); + + test_clock.Advance(base::Seconds(-1)); + SessionCommands commands2; + commands2.push_back(CreateCommandFromData(data)); + backend->AppendCommands(std::move(commands2), true, base::DoNothing()); + const base::FilePath path2 = backend->current_path(); + EXPECT_FALSE(path2.empty()); + EXPECT_NE(path1, path2); + base::Time path2_time; + EXPECT_TRUE(CommandStorageBackend::TimestampFromPath(path2, path2_time)); + // Even though the current time is before the previous time, the timestamp + // of the file should increase. + EXPECT_GT(path2_time, path1_time); + // Backend needs to be destroyed before test_clock so we don't end up with + // dangling reference. + backend.reset(); +} + } // namespace sessions
diff --git a/components/signin/core/browser/chrome_connected_header_helper.cc b/components/signin/core/browser/chrome_connected_header_helper.cc index afa2234d..3eb6289 100644 --- a/components/signin/core/browser/chrome_connected_header_helper.cc +++ b/components/signin/core/browser/chrome_connected_header_helper.cc
@@ -6,7 +6,6 @@ #include <vector> -#include "base/feature_list.h" #include "base/logging.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" @@ -15,7 +14,6 @@ #include "build/chromeos_buildflags.h" #include "components/google/core/common/google_util.h" #include "components/signin/core/browser/cookie_settings_util.h" -#include "components/signin/public/base/signin_switches.h" #include "components/signin/public/identity_manager/tribool.h" #include "google_apis/gaia/gaia_auth_util.h" #include "net/base/registry_controlled_domains/registry_controlled_domain.h" @@ -63,13 +61,6 @@ return GAIA_SERVICE_TYPE_NONE; } -bool NewRequestHeaderCheckOrder() { - // The result is computed once and cached because the code is on the hot path. - static bool new_order = - base::FeatureList::IsEnabled(switches::kNewSigninRequestHeaderCheckOrder); - return new_order; -} - } // namespace const char kChromeConnectedCookieName[] = "CHROME_CONNECTED"; @@ -132,25 +123,13 @@ bool ChromeConnectedHeaderHelper::ShouldBuildRequestHeader( const GURL& url, const content_settings::CookieSettings* cookie_settings) { - // The 'new order' refers to the order of the two checks performed in this - // function. In the new order the less expensive URL-based check is performed - // first in the most common case (non-Google URLs), and the cookie-based - // check is performed second. - bool new_order = NewRequestHeaderCheckOrder(); - - // Check if url is eligible for the header. New order. - if (new_order && !IsUrlEligibleForRequestHeader(url)) + // Check if url is eligible for the header. + if (!IsUrlEligibleForRequestHeader(url)) { return false; + } // If signin cookies are not allowed, don't add the header. - if (!SettingsAllowSigninCookies(cookie_settings)) - return false; - - // Check if url is eligible for the header. Old order. - if (!new_order && !IsUrlEligibleForRequestHeader(url)) - return false; - - return true; + return SettingsAllowSigninCookies(cookie_settings); } bool ChromeConnectedHeaderHelper::IsUrlEligibleToIncludeGaiaId(
diff --git a/components/signin/public/base/signin_switches.cc b/components/signin/public/base/signin_switches.cc index 40dcd9d..cc3ab23 100644 --- a/components/signin/public/base/signin_switches.cc +++ b/components/signin/public/base/signin_switches.cc
@@ -17,13 +17,6 @@ base::FEATURE_DISABLED_BY_DEFAULT); #endif -// If enabled, performs the URL-based check first when proving that the -// X-Chrome-Connected header is not needed in request headers on HTTP -// redirects. The hypothesis is that this order of checks is faster to perform. -BASE_FEATURE(kNewSigninRequestHeaderCheckOrder, - "NewSigninRequestHeaderCheckOrder", - base::FEATURE_ENABLED_BY_DEFAULT); - // Clears the token service before using it. This allows simulating the // expiration of credentials during testing. const char kClearTokenService[] = "clear-token-service";
diff --git a/components/signin/public/base/signin_switches.h b/components/signin/public/base/signin_switches.h index 48419883..4edf49d 100644 --- a/components/signin/public/base/signin_switches.h +++ b/components/signin/public/base/signin_switches.h
@@ -23,8 +23,6 @@ BASE_DECLARE_FEATURE(kGaiaIdCacheInAccountManagerFacade); #endif -BASE_DECLARE_FEATURE(kNewSigninRequestHeaderCheckOrder); - extern const char kClearTokenService[]; extern const char kDisableSigninScopedDeviceId[];
diff --git a/components/translate/content/android/translate_message.cc b/components/translate/content/android/translate_message.cc index faece6a..aa3862a 100644 --- a/components/translate/content/android/translate_message.cc +++ b/components/translate/content/android/translate_message.cc
@@ -15,6 +15,7 @@ #include "base/android/jni_array.h" #include "base/android/jni_string.h" #include "base/containers/contains.h" +#include "base/debug/dump_without_crashing.h" #include "base/logging.h" #include "base/metrics/field_trial_params.h" #include "base/metrics/histogram_macros.h" @@ -312,6 +313,11 @@ ui_delegate_->Translate(); break; + case State::kTranslating: + // Should not happen, but per https://crbug.com/1409304 it may, so add + // logging. + base::debug::DumpWithoutCrashing(); + break; case State::kAfterTranslateWithAutoAlwaysConfirmation: // The user clicked "Undo" on a translated page when the // auto-always-translate confirmation message was showing, so turn off @@ -336,7 +342,11 @@ ui_delegate_->SetLanguageBlocked(false); bridge_->Dismiss(env); break; - + case State::kDismissed: + // Should not happen, but per https://crbug.com/1409304 it may, so add + // logging. + base::debug::DumpWithoutCrashing(); + break; default: NOTREACHED(); break;
diff --git a/components/user_education/common/tutorial_description.h b/components/user_education/common/tutorial_description.h index bec187a..774880a6 100644 --- a/components/user_education/common/tutorial_description.h +++ b/components/user_education/common/tutorial_description.h
@@ -236,12 +236,12 @@ } Step& InAnyContext() { - context_mode = TutorialDescription::ContextMode::kAny; + context_mode = ContextMode::kAny; return *this; } Step& InSameContext() { - context_mode = TutorialDescription::ContextMode::kFromPreviousStep; + context_mode = ContextMode::kFromPreviousStep; return *this; } }; @@ -369,6 +369,30 @@ event_type_) {} }; + // TutorialDescription::Create<"Prefix">(step1, step2, ...) + // + // Create a tutorial description with the given steps + // This will also generate the histograms with the given prefix + template <const char histogram_name[], typename... Args> + static TutorialDescription Create(Args&&... steps) { + TutorialDescription description; + description.steps = Steps(steps...); + description.histograms = + user_education::MakeTutorialHistograms<histogram_name>( + description.steps.size()); + return description; + } + + // TutorialDescription::Steps(step1, step2, {step3, step4}, ...) + // + // Turn steps and step vectors into a flattened vector of steps + template <typename... Args> + static std::vector<TutorialDescription::Step> Steps(Args&&... steps) { + std::vector<TutorialDescription::Step> flat_steps = {}; + (AddStep(flat_steps, std::forward<Args>(steps)), ...); + return flat_steps; + } + // the list of TutorialDescription steps std::vector<Step> steps; @@ -381,6 +405,16 @@ // cases this flag should be set to false so that the restart tutorial button // is not displayed. bool can_be_restarted = false; + + private: + static void AddStep(std::vector<Step>& dest, Step step) { + dest.emplace_back(step); + } + static void AddStep(std::vector<Step>& dest, const std::vector<Step>& src) { + for (auto& step : src) { + dest.emplace_back(step); + } + } }; } // namespace user_education
diff --git a/components/user_education/common/tutorial_unittest.cc b/components/user_education/common/tutorial_unittest.cc index e1b7b56..0091bd22 100644 --- a/components/user_education/common/tutorial_unittest.cc +++ b/components/user_education/common/tutorial_unittest.cc
@@ -694,4 +694,53 @@ EXPECT_CALL(aborted, Run).Times(1); } +TEST_F(TutorialTest, RegisterTutorialWithCreate) { + std::unique_ptr<TutorialRegistry> registry = + std::make_unique<TutorialRegistry>(); + + { + auto description = TutorialDescription::Create<kHistogramName1>( + TutorialDescription::BubbleStep(kTestIdentifier1) + .SetBubbleBodyText(IDS_OK)); + description.can_be_restarted = true; + EXPECT_TRUE(description.steps.size() == 1); + + registry->AddTutorial(kTestTutorial1, std::move(description)); + } + + std::unique_ptr<HelpBubbleFactoryRegistry> bubble_factory_registry = + std::make_unique<HelpBubbleFactoryRegistry>(); + + EXPECT_TRUE(registry->IsTutorialRegistered(kTestTutorial1)); +} + +TEST_F(TutorialTest, RegisterTutorialWithCreateFromVector) { + std::unique_ptr<TutorialRegistry> registry = + std::make_unique<TutorialRegistry>(); + + { + TutorialDescription::Step first_step = + TutorialDescription::BubbleStep(kTestIdentifier1) + .SetBubbleBodyText(IDS_OK); + + std::vector<TutorialDescription::Step> next_steps = { + TutorialDescription::BubbleStep(kTestIdentifier2) + .SetBubbleBodyText(IDS_OK), + TutorialDescription::BubbleStep(kTestIdentifier3) + .SetBubbleBodyText(IDS_OK)}; + + auto description = + TutorialDescription::Create<kHistogramName1>(first_step, next_steps); + description.can_be_restarted = true; + EXPECT_TRUE(description.steps.size() == 3); + + registry->AddTutorial(kTestTutorial1, std::move(description)); + } + + std::unique_ptr<HelpBubbleFactoryRegistry> bubble_factory_registry = + std::make_unique<HelpBubbleFactoryRegistry>(); + + EXPECT_TRUE(registry->IsTutorialRegistered(kTestTutorial1)); +} + } // namespace user_education
diff --git a/components/variations/cros/BUILD.gn b/components/variations/cros/BUILD.gn index d4440f4..2493c71 100644 --- a/components/variations/cros/BUILD.gn +++ b/components/variations/cros/BUILD.gn
@@ -19,13 +19,13 @@ "evaluate_seed.h", ] deps = [ + ":proto", "//base", "//build:branding_buildflags", "//chromeos/crosapi/cpp", "//chromeos/crosapi/cpp:crosapi_constants", "//components/variations", "//components/variations/proto", - "//components/variations/proto:cros_safe_seed_proto", "//components/variations/service", ] @@ -38,12 +38,12 @@ sources = [ "evaluate_seed_unittest.cc" ] deps = [ ":evaluate_seed_lib", + ":proto", "//base", "//base/test:test_support", "//build:branding_buildflags", "//components/test:test_support", "//components/variations", - "//components/variations/proto:cros_safe_seed_proto", "//testing/gmock", "//testing/gtest", ] @@ -56,3 +56,9 @@ "//components/test:test_support", ] } + +proto_library("proto") { + sources = [ "//third_party/cros_system_api/dbus/featured/featured.proto" ] + + proto_out_dir = "components/variations/cros" +}
diff --git a/components/variations/cros/evaluate_seed.cc b/components/variations/cros/evaluate_seed.cc index fa038ac..2065e16 100644 --- a/components/variations/cros/evaluate_seed.cc +++ b/components/variations/cros/evaluate_seed.cc
@@ -12,7 +12,7 @@ #include "build/branding_buildflags.h" #include "chromeos/crosapi/cpp/channel_to_enum.h" #include "chromeos/crosapi/cpp/crosapi_constants.h" -#include "components/variations/proto/cros_safe_seed.pb.h" +#include "components/variations/cros/featured.pb.h" #include "components/variations/proto/study.pb.h" #include "components/variations/service/variations_field_trial_creator.h" @@ -60,7 +60,7 @@ absl::optional<SafeSeed> GetSafeSeedData(const base::CommandLine* command_line, FILE* stream) { - variations::SeedDetails safe_seed; + featured::SeedDetails safe_seed; if (command_line->HasSwitch(kSafeSeedSwitch)) { // Read safe seed from |stream|. std::string safe_seed_data;
diff --git a/components/variations/cros/evaluate_seed.h b/components/variations/cros/evaluate_seed.h index 66194a6..7ed290a 100644 --- a/components/variations/cros/evaluate_seed.h +++ b/components/variations/cros/evaluate_seed.h
@@ -12,7 +12,7 @@ #include "base/command_line.h" #include "components/variations/client_filterable_state.h" -#include "components/variations/proto/cros_safe_seed.pb.h" +#include "components/variations/cros/featured.pb.h" #include "third_party/abseil-cpp/absl/types/optional.h" namespace variations::evaluate_seed { @@ -23,7 +23,7 @@ struct SafeSeed { bool use_safe_seed = false; - variations::SeedDetails seed_data; + featured::SeedDetails seed_data; }; // Read the safe seed data from |stream|, if and only if the |command_line|
diff --git a/components/variations/cros/evaluate_seed_unittest.cc b/components/variations/cros/evaluate_seed_unittest.cc index 52b9a36..c64d5376 100644 --- a/components/variations/cros/evaluate_seed_unittest.cc +++ b/components/variations/cros/evaluate_seed_unittest.cc
@@ -8,7 +8,7 @@ #include "base/test/scoped_chromeos_version_info.h" #include "build/branding_buildflags.h" #include "components/variations/client_filterable_state.h" -#include "components/variations/proto/cros_safe_seed.pb.h" +#include "components/variations/cros/featured.pb.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -99,7 +99,7 @@ // Should ignore data if flag is off. TEST(VariationsCrosEvaluateSeed, GetSafeSeedData_Off) { - variations::SeedDetails safe_seed; + featured::SeedDetails safe_seed; safe_seed.set_compressed_data("some text"); std::string text; safe_seed.SerializeToString(&text); @@ -108,7 +108,7 @@ base::CommandLine command_line({"evaluate_seed"}); auto data = GetSafeSeedData(&command_line, stream); - variations::SeedDetails empty_seed; + featured::SeedDetails empty_seed; ASSERT_TRUE(data.has_value()); EXPECT_FALSE(data.value().use_safe_seed); EXPECT_THAT(data.value().seed_data, EqualsProto(empty_seed)); @@ -116,7 +116,7 @@ // Should return specified data via stream if flag is on. TEST(VariationsCrosEvaluateSeed, GetSafeSeedData_On) { - variations::SeedDetails safe_seed; + featured::SeedDetails safe_seed; safe_seed.set_compressed_data("some text"); std::string text; safe_seed.SerializeToString(&text); @@ -132,7 +132,7 @@ // Should not attempt to read stream if flag is not on. TEST(VariationsCrosEvaluateSeed, GetSafeSeedData_Off_FailRead) { - variations::SeedDetails safe_seed; + featured::SeedDetails safe_seed; safe_seed.set_compressed_data("some text"); std::string text; safe_seed.SerializeToString(&text); @@ -141,7 +141,7 @@ base::CommandLine command_line({"evaluate_seed"}); auto data = GetSafeSeedData(&command_line, stream); - variations::SeedDetails empty_seed; + featured::SeedDetails empty_seed; ASSERT_TRUE(data.has_value()); EXPECT_FALSE(data.value().use_safe_seed); EXPECT_THAT(data.value().seed_data, EqualsProto(empty_seed)); @@ -149,7 +149,7 @@ // If flag is on and reading fails, should return nullopt. TEST(VariationsCrosEvaluateSeed, GetSafeSeedData_On_FailRead) { - variations::SeedDetails safe_seed; + featured::SeedDetails safe_seed; safe_seed.set_compressed_data("some text"); std::string text; safe_seed.SerializeToString(&text);
diff --git a/components/variations/proto/BUILD.gn b/components/variations/proto/BUILD.gn index 2cad9d17..8bedf01 100644 --- a/components/variations/proto/BUILD.gn +++ b/components/variations/proto/BUILD.gn
@@ -45,11 +45,3 @@ deps = [ "devtools" ] } } - -# This proto is only used on CrOS. Other platforms do not support this proto -# and should not use this library. -proto_library("cros_safe_seed_proto") { - sources = [ "cros_safe_seed.proto" ] - - proto_out_dir = "components/variations/proto" -}
diff --git a/components/variations/proto/OWNERS b/components/variations/proto/OWNERS deleted file mode 100644 index 27ba794..0000000 --- a/components/variations/proto/OWNERS +++ /dev/null
@@ -1 +0,0 @@ -per-file cros_safe_seed.proto=file://components/variations/cros/OWNERS
diff --git a/components/variations/proto/cros_safe_seed.proto b/components/variations/proto/cros_safe_seed.proto deleted file mode 100644 index cd8ce156..0000000 --- a/components/variations/proto/cros_safe_seed.proto +++ /dev/null
@@ -1,53 +0,0 @@ -// Copyright 2023 The ChromiumOS Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -syntax = "proto3"; - -option optimize_for = LITE_RUNTIME; - -// This file defines messages necessary for CrOS early boot experimentation -package variations; - -// Information about the last known "safe" seed. -// -// Any changes to this message must also be reflected in -// third_party/cros_system_api/dbus/featured/featured.proto. These messages must -// be kept in sync. -message SeedDetails { - // Last known "safe" seed represented as the base64-encoded gzip-compressed - // serialized form of the variations seed protobuf. - string compressed_data = 1; - // The active client locale that was successfully used in association with the - // last known "safe" seed. - string locale = 4; - // Milestone with which the last known "safe" seed was fetched. - int32 milestone = 5; - // String form of pair <Chrome version string, country code string> (eg. - // "106.0.5249.119,us") representing the country used for filtering permanent - // consistency studies until the next time Chrome is updated. - string permanent_consistency_country = 6; - // A country code string representing the country used for evaluating session - // consistency studies. - string session_consistency_country = 7; - // Digital signature of the last known "safe" seed's binary data. Empty if - // there is no known "safe" seed. - string signature = 8; - // The serialized base::Time used for safe seed expiry checks. This is usually - // the time at which the last known "safe" seed was received; however, it - // could be a build timestamp if the received date is unknown. An empty - // (default-constructed) base::Time if there is no known "safe" seed. This is - // a server-provided timestamp in milliseconds. - int64 date = 9; - // The serialized base::Time from the fetch corresponding to the last known - // "safe" seed. This is a client timestamp in milliseconds. - int64 fetch_time = 10; - - // Tags 2 and 3 are reserved since they have been deleted. - // These tags were used for older versions of the date and fetch_time fields, - // which were both of type google.protobuf.Timestamp. Importing - // google.protobuf.Timestamp is not supported in Chromium's - // third_party/cros_system_api, so both fields were changed to type int64 (the - // same data type finch protos use for dates). - reserved 2, 3; -}
diff --git a/components/viz/service/display/copy_output_scaling_pixeltest.cc b/components/viz/service/display/copy_output_scaling_pixeltest.cc index 06f842a..b709581 100644 --- a/components/viz/service/display/copy_output_scaling_pixeltest.cc +++ b/components/viz/service/display/copy_output_scaling_pixeltest.cc
@@ -216,7 +216,7 @@ gfx::Rect rect = smaller_pass_rects[i] - copy_rect.OffsetFromOrigin(); rect = copy_output::ComputeResultRect(rect, scale_from_, scale_to_); expected_bitmap.erase( - smaller_pass_colors[i], nullptr /* SkColorSpace* colorSpace */, + smaller_pass_colors[i], SkIRect{rect.x(), rect.y(), rect.right(), rect.bottom()}); }
diff --git a/components/viz/service/display/resolved_frame_data.cc b/components/viz/service/display/resolved_frame_data.cc index 641c102..3605f04 100644 --- a/components/viz/service/display/resolved_frame_data.cc +++ b/components/viz/service/display/resolved_frame_data.cc
@@ -166,6 +166,9 @@ } referenced_resources.push_back(resource_id); + + // Update `ResolvedQuadData::remapped_resources` to have the remapped + // display resource_id. resource_id = iter->second; } }
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl_unittest.cc b/components/viz/service/display_embedder/skia_output_surface_impl_unittest.cc index 341f90e7b..add6549 100644 --- a/components/viz/service/display_embedder/skia_output_surface_impl_unittest.cc +++ b/components/viz/service/display_embedder/skia_output_surface_impl_unittest.cc
@@ -132,7 +132,7 @@ SkBitmap expected; expected.allocPixels(SkImageInfo::MakeN32Premul( output_rect.width(), output_rect.height(), color_space.ToSkColorSpace())); - expected.eraseColor(kOutputColor, /*colorSpace=*/nullptr); + expected.eraseColor(kOutputColor); EXPECT_TRUE( cc::MatchesBitmap(result_bitmap, expected, cc::ExactPixelComparator()));
diff --git a/components/webapps/browser/installable/installable_data.h b/components/webapps/browser/installable/installable_data.h index 39bb991..e375f34 100644 --- a/components/webapps/browser/installable/installable_data.h +++ b/components/webapps/browser/installable/installable_data.h
@@ -13,6 +13,7 @@ #include "base/memory/raw_ptr.h" #include "base/memory/raw_ref.h" #include "components/webapps/browser/installable/installable_logging.h" +#include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/blink/public/mojom/manifest/manifest.mojom-forward.h" #include "third_party/skia/include/core/SkBitmap.h" #include "url/gurl.h"
diff --git a/components/webapps/browser/installable/installable_logging.cc b/components/webapps/browser/installable/installable_logging.cc index f976241..fbd38640 100644 --- a/components/webapps/browser/installable/installable_logging.cc +++ b/components/webapps/browser/installable/installable_logging.cc
@@ -11,6 +11,7 @@ #include "components/webapps/browser/installable/installable_manager.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/web_contents.h" +#include "third_party/blink/public/mojom/devtools/console_message.mojom.h" namespace webapps {
diff --git a/components/webapps/browser/installable/installable_logging.h b/components/webapps/browser/installable/installable_logging.h index e1e7aaa..fb380dbf 100644 --- a/components/webapps/browser/installable/installable_logging.h +++ b/components/webapps/browser/installable/installable_logging.h
@@ -7,7 +7,7 @@ #include <string> -#include "third_party/blink/public/mojom/devtools/console_message.mojom.h" +#include "third_party/blink/public/mojom/devtools/console_message.mojom-forward.h" namespace content { struct InstallabilityError;
diff --git a/content/browser/attribution_reporting/attribution_storage_sql.h b/content/browser/attribution_reporting/attribution_storage_sql.h index 265c179..d1d6df1 100644 --- a/content/browser/attribution_reporting/attribution_storage_sql.h +++ b/content/browser/attribution_reporting/attribution_storage_sql.h
@@ -64,7 +64,7 @@ // // Note that all versions >=15 were introduced during the transitional state // of the Attribution Reporting API and can be removed when done. - static constexpr int kDeprecatedVersionNumber = 34; + static constexpr int kDeprecatedVersionNumber = 35; static_assert(kCompatibleVersionNumber <= kCurrentVersionNumber); static_assert(kDeprecatedVersionNumber < kCompatibleVersionNumber);
diff --git a/content/browser/attribution_reporting/attribution_storage_sql_migrations.cc b/content/browser/attribution_reporting/attribution_storage_sql_migrations.cc index 6b05a944..7d2da08 100644 --- a/content/browser/attribution_reporting/attribution_storage_sql_migrations.cc +++ b/content/browser/attribution_reporting/attribution_storage_sql_migrations.cc
@@ -55,23 +55,6 @@ transaction.Commit(); } -bool To36(sql::Database& db) { - static constexpr char kDropOldIndexSql[] = "DROP INDEX sources_by_origin"; - if (!db.Execute(kDropOldIndexSql)) { - return false; - } - - static constexpr char kCreateNewIndexSql[] = - "CREATE INDEX active_sources_by_source_origin " - "ON sources(source_origin)" - "WHERE event_level_active=1 OR aggregatable_active=1"; - if (!db.Execute(kCreateNewIndexSql)) { - return false; - } - - return true; -} - bool To37(sql::Database& db) { static constexpr char kNewDedupKeyTableSql[] = "CREATE TABLE new_dedup_keys(" @@ -685,11 +668,10 @@ start_timestamp = base::ThreadTicks::Now(); } - static_assert(AttributionStorageSql::kDeprecatedVersionNumber + 1 == 35, + static_assert(AttributionStorageSql::kDeprecatedVersionNumber + 1 == 36, "Remove migration(s) below."); - bool ok = MaybeMigrate(db, meta_table, 35, &To36) && - MaybeMigrate(db, meta_table, 36, &To37) && + bool ok = MaybeMigrate(db, meta_table, 36, &To37) && MaybeMigrate(db, meta_table, 37, &To38) && MaybeMigrate(db, meta_table, 38, &To39) && MaybeMigrate(db, meta_table, 39, &To40) &&
diff --git a/content/browser/attribution_reporting/attribution_storage_sql_migrations_unittest.cc b/content/browser/attribution_reporting/attribution_storage_sql_migrations_unittest.cc index e4fe8bd..11c76be 100644 --- a/content/browser/attribution_reporting/attribution_storage_sql_migrations_unittest.cc +++ b/content/browser/attribution_reporting/attribution_storage_sql_migrations_unittest.cc
@@ -202,40 +202,6 @@ histograms.ExpectTotalCount("Conversions.Storage.MigrationTime", 0); } -TEST_F(AttributionStorageSqlMigrationsTest, MigrateVersion35ToCurrent) { - base::HistogramTester histograms; - LoadDatabase(GetVersionFilePath(35), DbPath()); - - // Verify pre-conditions. - { - sql::Database db; - ASSERT_TRUE(db.Open(DbPath())); - ASSERT_TRUE(db.DoesIndexExist("sources_by_origin")); - ASSERT_FALSE(db.DoesIndexExist("active_sources_by_source_origin")); - } - - MigrateDatabase(); - - // Verify schema is current. - { - sql::Database db; - ASSERT_TRUE(db.Open(DbPath())); - - CheckVersionNumbers(&db); - - // Compare normalized schemas - EXPECT_EQ(NormalizeSchema(GetCurrentSchema()), - NormalizeSchema(db.GetSchema())); - - ASSERT_FALSE(db.DoesIndexExist("sources_by_origin")); - ASSERT_TRUE(db.DoesIndexExist("active_sources_by_source_origin")); - } - - // DB creation histograms should be recorded. - histograms.ExpectTotalCount("Conversions.Storage.CreationTime", 0); - histograms.ExpectTotalCount("Conversions.Storage.MigrationTime", 1); -} - TEST_F(AttributionStorageSqlMigrationsTest, MigrateVersion36ToCurrent) { base::HistogramTester histograms; LoadDatabase(GetVersionFilePath(36), DbPath());
diff --git a/content/browser/browser_main_loop.cc b/content/browser/browser_main_loop.cc index 6dd8568..07bfa4b 100644 --- a/content/browser/browser_main_loop.cc +++ b/content/browser/browser_main_loop.cc
@@ -818,9 +818,10 @@ // while avoiding doing so in unit tests by making it explicitly enabled here. GpuDataManagerImpl::GetInstance()->StartUmaTimer(); -#if !BUILDFLAG(GOOGLE_CHROME_BRANDING) || BUILDFLAG(IS_ANDROID) +#if !BUILDFLAG(GOOGLE_CHROME_BRANDING) || BUILDFLAG(IS_ANDROID) || \ + BUILDFLAG(IS_IOS) // Single-process is an unsupported and not fully tested mode, so - // don't enable it for official Chrome builds (except on Android). + // don't enable it for official Chrome builds (except on Android and iOS). if (parsed_command_line_->HasSwitch(switches::kSingleProcess)) RenderProcessHost::SetRunRendererInProcess(true); #endif
diff --git a/content/browser/browsing_topics/header_util.cc b/content/browser/browsing_topics/header_util.cc index 1ee7793..0b2f24b2 100644 --- a/content/browser/browsing_topics/header_util.cc +++ b/content/browser/browsing_topics/header_util.cc
@@ -40,7 +40,8 @@ const url::Origin& caller_origin, RenderFrameHost& request_initiator_frame, browsing_topics::ApiCallerSource caller_source) { - DCHECK_EQ(caller_source, browsing_topics::ApiCallerSource::kFetch); + DCHECK(caller_source == browsing_topics::ApiCallerSource::kFetch || + caller_source == browsing_topics::ApiCallerSource::kIframeAttribute); std::string header_value; headers.GetNormalizedHeader("Observe-Browsing-Topics", &header_value);
diff --git a/content/browser/renderer_host/navigation_request.cc b/content/browser/renderer_host/navigation_request.cc index 09e2e34..a508bd0c 100644 --- a/content/browser/renderer_host/navigation_request.cc +++ b/content/browser/renderer_host/navigation_request.cc
@@ -43,6 +43,7 @@ #include "components/attribution_reporting/os_support.mojom.h" #include "content/browser/attribution_reporting/attribution_manager.h" #include "content/browser/blob_storage/chrome_blob_storage_context.h" +#include "content/browser/browsing_topics/header_util.h" #include "content/browser/child_process_security_policy_impl.h" #include "content/browser/client_hints/client_hints.h" #include "content/browser/devtools/devtools_instrumentation.h" @@ -1052,6 +1053,81 @@ tokens, base::Time::Now()); } +// Returns the topics header for a navigation request. Returns absl::nullopt if +// the request isn't eligible for topics. This should align with the handling in +// `GetTopicsHeaderValueForSubresourceRequest()`. +absl::optional<std::string> GetTopicsHeaderValueForNavigationRequest( + FrameTreeNode* frame_tree_node, + const GURL& url) { + // Skip if the <iframe> does not have the "browsingtopics" opt-in attribute. + if (!frame_tree_node->browsing_topics()) { + return absl::nullopt; + } + + RenderFrameHostImpl* rfh = frame_tree_node->current_frame_host(); + + // Skip top frame navigation. + // TODO(crbug.com/1424261): This should be checked at the mojom boundary of + // RenderFrameHostImpl::DidChangeIframeAttributes, and should be a DCHECK + // here. + if (rfh->is_main_frame()) { + return absl::nullopt; + } + + // Skip fenced frames. + if (rfh->IsNestedWithinFencedFrame()) { + return absl::nullopt; + } + + // Skip inactive pages (e.g. portal, prerendered pages). + if (!rfh->GetPage().IsPrimary()) { + return absl::nullopt; + } + + // TODO(crbug.com/1244137): IsPrimary() doesn't actually detect portals yet. + // Remove this when it does. + if (!static_cast<RenderFrameHostImpl*>(rfh->GetMainFrame()) + ->IsOutermostMainFrame()) { + return absl::nullopt; + } + + url::Origin origin = url::Origin::Create(url); + if (origin.opaque()) { + return absl::nullopt; + } + + if (!network::IsOriginPotentiallyTrustworthy(origin)) { + return absl::nullopt; + } + + const blink::PermissionsPolicy* parent_policy = + rfh->GetParent()->permissions_policy(); + + DCHECK(parent_policy); + + if (!parent_policy->IsFeatureEnabledForOrigin( + blink::mojom::PermissionsPolicyFeature::kBrowsingTopics, origin) || + !parent_policy->IsFeatureEnabledForOrigin( + blink::mojom::PermissionsPolicyFeature:: + kBrowsingTopicsBackwardCompatible, + origin)) { + return absl::nullopt; + } + + std::vector<blink::mojom::EpochTopicPtr> topics; + bool topics_eligible = GetContentClient()->browser()->HandleTopicsWebApi( + origin, rfh->GetMainFrame(), + browsing_topics::ApiCallerSource::kIframeAttribute, + /*get_topics=*/true, + /*observe=*/false, topics); + + if (!topics_eligible) { + return absl::nullopt; + } + + return DeriveTopicsHeaderValue(topics); +} + } // namespace NavigationRequest::PrerenderActivationNavigationState:: @@ -1865,6 +1941,16 @@ headers.GetHeader(net::HttpRequestHeaders::kContentType, &commit_params_->post_content_type); } + + absl::optional<std::string> topics_header_value = + GetTopicsHeaderValueForNavigationRequest(frame_tree_node, + common_params_->url); + + topics_eligible_ = topics_header_value.has_value(); + + if (topics_eligible_) { + headers.SetHeader(kBrowsingTopicsRequestHeaderKey, *topics_header_value); + } } begin_params_->headers = headers.ToString(); @@ -4923,6 +5009,44 @@ net::HttpRequestHeaders modified_headers = TakeModifiedRequestHeaders(); std::vector<std::string> removed_headers = TakeRemovedRequestHeaders(); + + // The topics a request is allowed to see can change within its redirect + // chain thus we need to recalculate them. For example, different caller + // origins (i.e. navigation URL's origin) may receive different topics, as the + // callers can only get the topics about the sites they were on. Besides, + // regardless of cross-origin-ness, the timestamp can also affect the + // candidate epochs where the topics are derived from, thus resulting in + // different topics across redirects. + if (topics_eligible_) { + topics_eligible_ = false; + + // Removes the topics header from the request that was passed on from the + // previous one. + removed_headers.push_back(kBrowsingTopicsRequestHeaderKey); + + // At this point we may not have a valid `GetRenderFrameHost()` if the + // navigation is during a cross-site redirect. Thus, pass in the current/old + // RenderFrameHost here. This is fine, because it should still give us the + // desired IsPrimary() status and the desired top-level frame that + // `HandleTopicsEligibleResponse()` is interested in knowing. + HandleTopicsEligibleResponse( + *commit_params_->redirect_response.back().get()->headers.get(), + url::Origin::Create(commit_params_->redirects.back()), + *frame_tree_node_->current_frame_host(), + browsing_topics::ApiCallerSource::kIframeAttribute); + } + + absl::optional<std::string> topics_header_value = + GetTopicsHeaderValueForNavigationRequest(frame_tree_node_, + common_params_->url); + + topics_eligible_ = topics_header_value.has_value(); + + if (topics_eligible_) { + modified_headers.SetHeader(kBrowsingTopicsRequestHeaderKey, + *topics_header_value); + } + // Removes all Client Hints from the request, that were passed on from the // previous one. for (const auto& elem : network::GetClientHintToNameMap()) { @@ -5295,6 +5419,10 @@ } } + if (topics_eligible_) { + topics_eligible_ = false; + } + ReadyToCommitNavigation(true /* is_error */); PopulateDocumentTokenForCrossDocumentNavigation(); @@ -5387,6 +5515,17 @@ frame_tree_node()->frame_tree().GetSessionStorageKey( commit_params_->storage_key); + if (topics_eligible_) { + topics_eligible_ = false; + + if (response()) { + HandleTopicsEligibleResponse( + *response()->headers.get(), url::Origin::Create(common_params_->url), + *GetRenderFrameHost(), + browsing_topics::ApiCallerSource::kIframeAttribute); + } + } + if (IsServedFromBackForwardCache() || IsPrerenderedPageActivation()) { CommitPageActivation(); return;
diff --git a/content/browser/renderer_host/navigation_request.h b/content/browser/renderer_host/navigation_request.h index a852b36..5d292fd 100644 --- a/content/browser/renderer_host/navigation_request.h +++ b/content/browser/renderer_host/navigation_request.h
@@ -2417,6 +2417,13 @@ // reset. bool force_new_browsing_instance_ = false; + // Whether the ongoing navigation resource request is eligible for topics + // calculation. This is set before the initial request and each subsequent + // redirect. If `topics_eligible_` is true, the request headers will contain + // the "Sec-Browsing-Topics" header, and if the corresponding response headers + // contain "Observe-Browsing-Topics: ?1", a topic observation will be stored. + bool topics_eligible_ = false; + // A WeakPtr for the BindContext associated with topics loader factory for the // committing document. This will be set in `CommitNavigation()`, and can // become null if the corresponding factory is destroyed. Upon
diff --git a/content/browser/site_per_process_browsertest.cc b/content/browser/site_per_process_browsertest.cc index d419704f..595efc8 100644 --- a/content/browser/site_per_process_browsertest.cc +++ b/content/browser/site_per_process_browsertest.cc
@@ -460,6 +460,17 @@ return visualizer_.DepictFrameTree(node); } +std::string SitePerProcessBrowserTestBase::WaitForMessageScript( + const std::string& result_expression) { + return base::StringPrintf( + "var onMessagePromise = new Promise(resolve => {" + " window.addEventListener('message', function(event) {" + " resolve(%s);" + " });" + "});", + result_expression.c_str()); +} + void SitePerProcessBrowserTestBase::SetUpCommandLine( base::CommandLine* command_line) { ContentBrowserTest::SetUpCommandLine(command_line); @@ -8370,26 +8381,29 @@ // Make sure the subframe can communicate to both the root remote frame // (where the postMessage should go to the current RenderFrameHost rather // than the pending one) and its sibling remote frame in the a.com process. - EXPECT_TRUE(ExecJs(child->current_frame_host(), - "window.addEventListener('message', function(event) {\n" - " domAutomationController.send(event.data);\n" - "});")); + EXPECT_TRUE( + ExecJs(child->current_frame_host(), WaitForMessageScript("event.data"))); + EXPECT_TRUE(ExecJs(child, "parent.postMessage('root-ping', '*')")); EXPECT_EQ("root-ping-reply", - EvalJs(child, "parent.postMessage('root-ping', '*')", - EXECUTE_SCRIPT_USE_MANUAL_REPLY)); + EvalJs(child->current_frame_host(), "onMessagePromise")); + EXPECT_TRUE( + ExecJs(child->current_frame_host(), WaitForMessageScript("event.data"))); + EXPECT_TRUE( + ExecJs(child, "parent.frames[1].postMessage('sibling-ping', '*')")); EXPECT_EQ("sibling-ping-subframe-reply", - EvalJs(child, "parent.frames[1].postMessage('sibling-ping', '*')", - EXECUTE_SCRIPT_USE_MANUAL_REPLY)); + EvalJs(child->current_frame_host(), "onMessagePromise")); // Cancel the pending main frame navigation, and verify that the subframe can // still communicate with the (old) main frame. root->navigator().CancelNavigation(root, NavigationDiscardReason::kCancelled); EXPECT_FALSE(root->render_manager()->speculative_frame_host()); + EXPECT_TRUE( + ExecJs(child->current_frame_host(), WaitForMessageScript("event.data"))); + EXPECT_TRUE(ExecJs(child, "parent.postMessage('root-ping', '*')")); EXPECT_EQ("root-ping-reply", - EvalJs(child, "parent.postMessage('root-ping', '*')", - EXECUTE_SCRIPT_USE_MANUAL_REPLY)); + EvalJs(child->current_frame_host(), "onMessagePromise")); } // Similar to TwoCrossSitePendingNavigations* tests above, but checks the case @@ -8438,25 +8452,25 @@ // Make sure the second tab can communicate to its (old) opener remote frame. // The postMessage should go to the current RenderFrameHost rather than the // pending one in the first tab's main frame. - EXPECT_TRUE(ExecJs(popup_shell->web_contents(), - "window.addEventListener('message', function(event) {\n" - " domAutomationController.send(event.data);\n" - "});")); + EXPECT_TRUE( + ExecJs(popup_shell->web_contents(), WaitForMessageScript("event.data"))); + EXPECT_TRUE(ExecJs(popup_shell->web_contents(), + "opener.postMessage('opener-ping', '*');")); EXPECT_EQ("opener-ping-reply", - EvalJs(popup_shell->web_contents(), - "opener.postMessage('opener-ping', '*');", - EXECUTE_SCRIPT_USE_MANUAL_REPLY)); + EvalJs(popup_shell->web_contents(), "onMessagePromise")); // Cancel the pending main frame navigation, and verify that the subframe can // still communicate with the (old) main frame. root->navigator().CancelNavigation(root, NavigationDiscardReason::kCancelled); EXPECT_FALSE(root->render_manager()->speculative_frame_host()); + EXPECT_TRUE( + ExecJs(popup_shell->web_contents(), WaitForMessageScript("event.data"))); + EXPECT_TRUE(ExecJs(popup_shell->web_contents(), + "opener.postMessage('opener-ping', '*')")); EXPECT_EQ("opener-ping-reply", - EvalJs(popup_shell->web_contents(), - "opener.postMessage('opener-ping', '*')", - EXECUTE_SCRIPT_USE_MANUAL_REPLY)); + EvalJs(popup_shell->web_contents(), "onMessagePromise")); } IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest, @@ -10714,20 +10728,18 @@ // Add an onmessage handler to the subframe to send back a bool of whether // the subframe has focus. - EXPECT_TRUE(ExecJs(root->child_at(0), - "window.addEventListener('message', function(event) {\n" - " domAutomationController.send(document.hasFocus());\n" - "});")); + EXPECT_TRUE( + ExecJs(root->child_at(0), WaitForMessageScript("document.hasFocus()"))); // Now, send a postMessage from main frame to subframe, and then focus the // subframe in the same script. postMessage should be scheduled after the // focus() call, so the IPC to focus the subframe should arrive before the // postMessage IPC, and the subframe should already know that it's focused in // the onmessage handler. - EXPECT_EQ(true, EvalJs(root, + EXPECT_EQ(true, ExecJs(root, "frames[0].postMessage('','*');\n" - "frames[0].focus();\n", - EXECUTE_SCRIPT_USE_MANUAL_REPLY)); + "frames[0].focus();\n")); + EXPECT_EQ(true, EvalJs(root->child_at(0), "onMessagePromise")); } // Ensure that if a cross-process postMessage is scheduled, and then the target
diff --git a/content/browser/site_per_process_browsertest.h b/content/browser/site_per_process_browsertest.h index 29c9eef..15a1392 100644 --- a/content/browser/site_per_process_browsertest.h +++ b/content/browser/site_per_process_browsertest.h
@@ -30,6 +30,8 @@ protected: std::string DepictFrameTree(FrameTreeNode* node); + std::string WaitForMessageScript(const std::string& result_expression); + void SetUpCommandLine(base::CommandLine* command_line) override; void SetUpOnMainThread() override;
diff --git a/content/browser/site_per_process_layout_browsertest.cc b/content/browser/site_per_process_layout_browsertest.cc index 923d031..a2b96ce 100644 --- a/content/browser/site_per_process_layout_browsertest.cc +++ b/content/browser/site_per_process_layout_browsertest.cc
@@ -441,21 +441,23 @@ // Wait until dppx becomes 2 if the frame's dpr hasn't beeen updated // to 2 yet. - const char kScript[] = - "function sendDpr() " - "{window.domAutomationController.send(window.devicePixelRatio);}; " - "if (window.devicePixelRatio == 2) sendDpr();" - "window.matchMedia('screen and " - "(min-resolution: 2dppx)').addListener(function(e) { if (e.matches) { " - "sendDpr();}})"; + const char kScript[] = R"( + new Promise(resolve => { + if (window.devicePixelRatio == 2) + resolve(window.devicePixelRatio); + window.matchMedia('screen and (min-resolution: 2dppx)') + .addListener(function(e) { + if (e.matches) { + resolve(window.devicePixelRatio); + } + }); + }); + )"; // Make sure that both main frame and iframe are updated to 2x. - EXPECT_EQ(expected_dip_scale, - EvalJs(child, kScript, content::EXECUTE_SCRIPT_USE_MANUAL_REPLY) - .ExtractDouble()); + EXPECT_EQ(expected_dip_scale, EvalJs(child, kScript).ExtractDouble()); - EXPECT_EQ(expected_dip_scale, EvalJs(web_contents(), kScript, - content::EXECUTE_SCRIPT_USE_MANUAL_REPLY) - .ExtractDouble()); + EXPECT_EQ(expected_dip_scale, + EvalJs(web_contents(), kScript).ExtractDouble()); } #endif @@ -2275,10 +2277,8 @@ FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root(); // Add an onmessage handler to the subframe to send back its width. - EXPECT_TRUE(ExecJs(root->child_at(0), R"( - window.addEventListener('message', function(event) { - domAutomationController.send(document.body.clientWidth); - });)")); + EXPECT_TRUE(ExecJs(root->child_at(0), + WaitForMessageScript("document.body.clientWidth"))); // Drop the visual properties ACKs from the child renderer. To do this, // unsubscribe the child's RenderWidgetHost from its @@ -2294,14 +2294,14 @@ // Now, resize the subframe twice from the main frame and send it a // postMessage. The postMessage handler should see the second updated size. - EXPECT_EQ(700, EvalJs(root, R"( + EXPECT_TRUE(ExecJs(root, R"( var f = document.querySelector('iframe'); f.width = 500; f.offsetTop; // force layout; this sends a resize IPC for width of 500. f.width = 700; f.offsetTop; // force layout; this sends a resize IPC for width of 700. - f.contentWindow.postMessage('foo', '*');)", - EXECUTE_SCRIPT_USE_MANUAL_REPLY)); + f.contentWindow.postMessage('foo', '*');)")); + EXPECT_EQ(700, EvalJs(root->child_at(0), "onMessagePromise")); } // This test verifies that when scrolling an OOPIF in a pinched-zoomed page,
diff --git a/content/browser/site_per_process_scroll_browsertest.cc b/content/browser/site_per_process_scroll_browsertest.cc index c134d45..584faab 100644 --- a/content/browser/site_per_process_scroll_browsertest.cc +++ b/content/browser/site_per_process_scroll_browsertest.cc
@@ -838,13 +838,7 @@ key_event.SetType(blink::WebKeyboardEvent::Type::kKeyUp); rwhv_child->GetRenderWidgetHost()->ForwardKeyboardEvent(key_event); - double scrolled_y = - EvalJs(root, - "waitForScrollDownPromise.then((scrolled_y) => {" - " window.domAutomationController.send(scrolled_y);" - "});", - content::EXECUTE_SCRIPT_USE_MANUAL_REPLY) - .ExtractDouble(); + double scrolled_y = EvalJs(root, "waitForScrollDownPromise").ExtractDouble(); EXPECT_GT(scrolled_y, 0.0); }
diff --git a/content/renderer/accessibility/render_accessibility_impl.cc b/content/renderer/accessibility/render_accessibility_impl.cc index 934a957b..969ac09 100644 --- a/content/renderer/accessibility/render_accessibility_impl.cc +++ b/content/renderer/accessibility/render_accessibility_impl.cc
@@ -1156,26 +1156,20 @@ void RenderAccessibilityImpl::AddImageAnnotations( const WebDocument& document, - std::vector<ui::AXNodeData>& nodes) { + std::vector<ui::AXNodeData*>& nodes) { if (accessibility_mode_.has_mode(ui::AXMode::kPDF)) return; - for (auto& node : nodes) { - WebAXObject src = WebAXObject::FromWebDocumentByID(document, node.id); + for (auto* node : nodes) { + WebAXObject src = WebAXObject::FromWebDocumentByID(document, node->id); - // This logic is equivalent to the early-outs in - // BlinkAXTreeSource::SerializeNode - if (src.IsDetached() || !src.AccessibilityIsIncludedInTree() || - (src.AccessibilityIsIgnored() && - !node.HasState(ax::mojom::State::kFocusable))) - continue; - - if (ui::IsImage(node.role)) { - AddImageAnnotationsForNode(src, &node); - } else if ((ui::IsLink(node.role) || ui::IsPlatformDocument(node.role)) && - node.GetNameFrom() != ax::mojom::NameFrom::kAttribute) { + if (ui::IsImage(node->role)) { + AddImageAnnotationsForNode(src, node); + } else { + DCHECK((ui::IsLink(node->role) || ui::IsPlatformDocument(node->role)) && + node->GetNameFrom() != ax::mojom::NameFrom::kAttribute); WebAXObject inner_image; if (FindExactlyOneInnerImageInMaxDepthThree(src, &inner_image)) - AddImageAnnotationsForNode(inner_image, &node); + AddImageAnnotationsForNode(inner_image, node); } } } @@ -1214,7 +1208,9 @@ AddPluginTreeToUpdate(&update, mark_plugin_subtree_dirty); } - AddImageAnnotations(document, update.nodes); + std::vector<ui::AXNodeData*> image_nodes; + ax_context_->GetImagesToAnnotate(update, image_nodes); + AddImageAnnotations(document, image_nodes); } if (had_end_of_test_event) {
diff --git a/content/renderer/accessibility/render_accessibility_impl.h b/content/renderer/accessibility/render_accessibility_impl.h index e2a8e4be..595080b 100644 --- a/content/renderer/accessibility/render_accessibility_impl.h +++ b/content/renderer/accessibility/render_accessibility_impl.h
@@ -261,7 +261,7 @@ bool mark_plugin_subtree_dirty); void AddImageAnnotations(const blink::WebDocument& document, - std::vector<ui::AXNodeData>&); + std::vector<ui::AXNodeData*>&); void AddImageAnnotationsForNode(blink::WebAXObject& src, ui::AXNodeData* dst); static void IgnoreProtocolChecksForTesting();
diff --git a/content/test/content_unittests_bundle_data.filelist b/content/test/content_unittests_bundle_data.filelist index dcd5f08..332c2f9 100644 --- a/content/test/content_unittests_bundle_data.filelist +++ b/content/test/content_unittests_bundle_data.filelist
@@ -40,7 +40,6 @@ data/attribution_reporting/aggregatable_report_goldens/version_/report_5_cleartext_payloads.json data/attribution_reporting/aggregatable_report_goldens/version_/report_6.json data/attribution_reporting/aggregatable_report_goldens/version_/report_6_cleartext_payloads.json -data/attribution_reporting/databases/version_34.sql data/attribution_reporting/databases/version_35.sql data/attribution_reporting/databases/version_36.sql data/attribution_reporting/databases/version_37.sql @@ -794,6 +793,8 @@ data/gpu/webcodecs/encode-decode.html data/gpu/webcodecs/encode.html data/gpu/webcodecs/encoding-modes.html +data/gpu/webcodecs/encoding-rate-control.html +data/gpu/webcodecs/encoding-rate-control.js data/gpu/webcodecs/svc.html data/gpu/webcodecs/tex-image-2d.html data/gpu/webcodecs/webcodecs_common.js
diff --git a/content/test/data/attribution_reporting/databases/version_34.sql b/content/test/data/attribution_reporting/databases/version_34.sql deleted file mode 100644 index a81bd0f2..0000000 --- a/content/test/data/attribution_reporting/databases/version_34.sql +++ /dev/null
@@ -1,55 +0,0 @@ -PRAGMA foreign_keys=OFF; - -BEGIN TRANSACTION; - -CREATE TABLE sources(source_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,source_event_id INTEGER NOT NULL,source_origin TEXT NOT NULL,destination_origin TEXT NOT NULL,reporting_origin TEXT NOT NULL,source_time INTEGER NOT NULL,expiry_time INTEGER NOT NULL,num_attributions INTEGER NOT NULL,event_level_active INTEGER NOT NULL,aggregatable_active INTEGER NOT NULL,destination_site TEXT NOT NULL,source_type INTEGER NOT NULL,attribution_logic INTEGER NOT NULL,priority INTEGER NOT NULL,source_site TEXT NOT NULL,debug_key INTEGER,aggregatable_budget_consumed INTEGER NOT NULL,aggregatable_source BLOB NOT NULL,filter_data BLOB NOT NULL); - -CREATE TABLE event_level_reports(report_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,source_id INTEGER NOT NULL,trigger_data INTEGER NOT NULL,trigger_time INTEGER NOT NULL,report_time INTEGER NOT NULL,priority INTEGER NOT NULL,failed_send_attempts INTEGER NOT NULL,external_report_id TEXT NOT NULL,debug_key INTEGER); - -CREATE TABLE rate_limits(id INTEGER PRIMARY KEY NOT NULL,scope INTEGER NOT NULL,source_id INTEGER NOT NULL,source_site TEXT NOT NULL,source_origin TEXT NOT NULL,destination_site TEXT NOT NULL,destination_origin TEXT NOT NULL,reporting_origin TEXT NOT NULL,time INTEGER NOT NULL); - -CREATE TABLE dedup_keys(source_id INTEGER NOT NULL,dedup_key INTEGER NOT NULL,PRIMARY KEY(source_id,dedup_key))WITHOUT ROWID; - -CREATE TABLE aggregatable_report_metadata(aggregation_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,source_id INTEGER NOT NULL,trigger_time INTEGER NOT NULL,debug_key INTEGER,external_report_id TEXT NOT NULL,report_time INTEGER NOT NULL,failed_send_attempts INTEGER NOT NULL,initial_report_time INTEGER NOT NULL); - -CREATE TABLE aggregatable_contributions(contribution_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,aggregation_id INTEGER NOT NULL,key_high_bits INTEGER NOT NULL,key_low_bits INTEGER NOT NULL,value INTEGER NOT NULL); - -CREATE TABLE meta(key LONGVARCHAR NOT NULL UNIQUE PRIMARY KEY, value LONGVARCHAR); - -INSERT INTO meta VALUES('mmap_status','-1'); -INSERT INTO meta VALUES('version','34'); -INSERT INTO meta VALUES('last_compatible_version','34'); - -CREATE INDEX sources_by_active_destination_site_reporting_origin ON sources(event_level_active,aggregatable_active,destination_site,reporting_origin); - -CREATE INDEX sources_by_expiry_time ON sources(expiry_time); - -CREATE INDEX sources_by_origin ON sources(source_origin); - -CREATE INDEX active_unattributed_sources_by_site_reporting_origin ON sources(source_site,reporting_origin)WHERE event_level_active=1 AND num_attributions=0 AND aggregatable_active=1 AND aggregatable_budget_consumed=0; - -CREATE INDEX event_level_reports_by_report_time ON event_level_reports(report_time); - -CREATE INDEX event_level_reports_by_source_id ON event_level_reports(source_id); - -CREATE INDEX rate_limit_attribution_idx ON rate_limits(destination_site,source_site,reporting_origin,time)WHERE scope=1; - -CREATE INDEX rate_limit_reporting_origin_idx ON rate_limits(scope,destination_site,source_site,time); - -CREATE INDEX rate_limit_time_idx ON rate_limits(time); - -CREATE INDEX rate_limit_source_id_idx ON rate_limits(source_id); - -CREATE INDEX aggregate_source_id_idx ON aggregatable_report_metadata(source_id); - -CREATE INDEX aggregate_trigger_time_idx ON aggregatable_report_metadata(trigger_time); - -CREATE INDEX aggregate_report_time_idx ON aggregatable_report_metadata(report_time); - -CREATE INDEX contribution_aggregation_id_idx ON aggregatable_contributions(aggregation_id); - -INSERT INTO sources VALUES(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19); - -INSERT INTO event_level_reports VALUES (0,1,2,3,4,5,6,7,8); - -COMMIT;
diff --git a/content/test/data/attribution_reporting/databases/version_35.sql b/content/test/data/attribution_reporting/databases/version_35.sql index b2da41a..07d380d 100644 --- a/content/test/data/attribution_reporting/databases/version_35.sql +++ b/content/test/data/attribution_reporting/databases/version_35.sql
@@ -48,4 +48,7 @@ CREATE INDEX contribution_aggregation_id_idx ON aggregatable_contributions(aggregation_id); +INSERT INTO sources VALUES(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19); +INSERT INTO event_level_reports VALUES (0,1,2,3,4,5,6,7,8); + COMMIT;
diff --git a/content/test/data/gpu/webcodecs/encoding-rate-control.html b/content/test/data/gpu/webcodecs/encoding-rate-control.html new file mode 100644 index 0000000..21e6bdf --- /dev/null +++ b/content/test/data/gpu/webcodecs/encoding-rate-control.html
@@ -0,0 +1,23 @@ +<!DOCTYPE html> +<!-- +Encodes several seconds of video and checks that the encoder adheres to the +specified bitrate. + +Each frame has a number of new gradient filled ellipses appearing on it. +We can control complexity of the video by changing the number of ellipses. +It's easier on encoders than pure white noise, but not as easy as some static or +a ffmpeg test input. +--> +<html> + +<head> + <title>Encoding bitrate test</title> + <script src="webcodecs_common.js"></script> + <script src="encoding-rate-control.js"></script> +</head> + +<body> + <canvas id="src"></canvas> +</body> + +</html>
diff --git a/content/test/data/gpu/webcodecs/encoding-rate-control.js b/content/test/data/gpu/webcodecs/encoding-rate-control.js new file mode 100644 index 0000000..290220902 --- /dev/null +++ b/content/test/data/gpu/webcodecs/encoding-rate-control.js
@@ -0,0 +1,139 @@ +// 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. + +'use strict'; + +function createRandomGenerator(seed) { + return function(max) { + seed = ((1 + seed) * 7 + 13) & 0x7fffffff; + return seed % max; + } +} + +// Draw pseudorandom animation on the canvas +function createDrawingFunction(cnv, changes_per_frame) { + var ctx = cnv.getContext('2d'); + let width = cnv.width; + let height = cnv.height; + let rnd = createRandomGenerator(425533); + const w = 35; + const h = 30; + const white_noise_img = ctx.createImageData(w, h); + self.crypto.getRandomValues(white_noise_img.data); + + return function() { + let x = 0, y = 0; + // Paint gradient filled ellipses + for (let i = 0; i < changes_per_frame; i++) { + x = rnd(width); + y = rnd(height); + + let a = + 'rgba(' + rnd(255) + ',' + rnd(255) + ',' + rnd(255) + ',' + 1 + ')'; + let b = + 'rgba(' + rnd(255) + ',' + rnd(255) + ',' + rnd(255) + ',' + 1 + ')'; + let c = + 'rgba(' + rnd(255) + ',' + rnd(255) + ',' + rnd(255) + ',' + 1 + ')'; + let gradient = ctx.createLinearGradient(x, y, x + w, y + h); + gradient.addColorStop(0, a); + gradient.addColorStop(0.5, b); + gradient.addColorStop(1, c); + + ctx.fillStyle = gradient; + ctx.beginPath(); + ctx.ellipse(x, y, w / 2, h / 2, 0.0, 0.0, 2 * Math.PI); + ctx.fill(); + } + + // Add a bit of white noise + ctx.putImageData(white_noise_img, x, y); + } +} + +async function main(arg) { + const width = 1280; + const height = 720; + const seconds = 5; + const fps = 30; + const frames_to_encode = fps * seconds; + let errors = 0; + let chunks = []; + + const encoder_config = { + codec: arg.codec, + hardwareAcceleration: arg.acceleration, + width: width, + height: height, + bitrate: arg.bitrate, + bitrateMode: arg.bitrate_mode, + framerate: fps + }; + + let support = await VideoEncoder.isConfigSupported(encoder_config); + if (!support.supported) { + TEST.skip('Unsupported codec: ' + arg.codec); + return; + } + + // Start drawing canvas animation that will be source of the frames + // for the test. + let cnv = document.getElementById('src'); + cnv.width = width; + cnv.height = height; + const changes_per_frame = 25; + const draw = createDrawingFunction(cnv, changes_per_frame); + + const init = { + output(chunk, metadata) { + chunks.push(chunk); + }, + error(e) { + errors++; + TEST.log(e); + } + }; + + let encoder = new VideoEncoder(init); + encoder.configure(encoder_config); + + // Take frames from the canvas and encoder them with a given bitrate + for (let i = 0; i < frames_to_encode; i++) { + const time_us = i / fps * 1_000_000; + draw(); + let frame = new VideoFrame(cnv, {timestamp: time_us}); + encoder.encode(frame, {keyFrame: false}); + frame.close(); + await waitForNextFrame(); + } + + await encoder.flush(); + TEST.log('Encoding completed'); + encoder.close(); + + TEST.assert(errors == 0, 'Encoding errors occurred during the test'); + TEST.assert( + chunks.length == frames_to_encode, + 'Output count mismatch: ' + chunks.length); + + // Calculate total size of the encoded video + let total_encoded_size = 0; + for (let chunk of chunks) { + total_encoded_size += chunk.byteLength; + } + + const actual_bitrate = total_encoded_size / seconds * 8 /* bits */; + const bitrate_mismatch = Math.abs(actual_bitrate - arg.bitrate) / arg.bitrate; + + // Check how far off expected encoded size from the ideal, CBR is + // supposed to be more strict that VBR. + let tolerance = (arg.bitrate_mode == 'constant') ? 0.15 : 0.30; + TEST.assert( + bitrate_mismatch < tolerance, + `Bitrate is too far off. Expected ${arg.bitrate}` + + ` Actual bitrate: ${actual_bitrate}` + + ` Tolerance: ${tolerance * arg.bitrate}` + + ` Mismatch: ${bitrate_mismatch}`); + + TEST.log('Test completed'); +}
diff --git a/content/test/gpu/gpu_tests/test_expectations/webcodecs_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/webcodecs_expectations.txt index f475c466..38e558b 100644 --- a/content/test/gpu/gpu_tests/test_expectations/webcodecs_expectations.txt +++ b/content/test/gpu/gpu_tests/test_expectations/webcodecs_expectations.txt
@@ -97,6 +97,11 @@ crbug.com/1409453 [ win amd ] WebCodecs_DrawImage_hw_decoder [ Failure ] crbug.com/1409453 [ win amd ] WebCodecs_TexImage2d_hw_decoder [ Failure ] +# Not all platform encoders are very good at adhering to specified bitrate +crbug.com/1368785 [ mac-x86_64 ] WebCodecs_EncodingRateControl_avc1.420034_prefer-hardware_constant_* [ Failure ] +# Android seems to be especially bad at rate control, let's wait and see what actually works +crbug.com/1368785 [ android ] WebCodecs_EncodingRateControl_* [ Failure ] + # The following expectations are added to enable WebCodecs tests on Sherlock. # unexpected_pass_finder is disabled so that the tool does not automatically remove these expectations. # TODO(crbug.com/1400465) Enable unexpected_pass_finder once test is running regularly on Sherlock.
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 6158138..6dc949c 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
@@ -224,10 +224,13 @@ crbug.com/1426916 [ chromeos chromeos-board-amd64-generic passthrough ] conformance/extensions/webgl-compressed-texture-astc.html [ Slow ] crbug.com/1426916 [ chromeos chromeos-board-amd64-generic passthrough ] conformance/extensions/s3tc-and-rgtc.html [ Slow ] crbug.com/1426916 [ chromeos chromeos-board-amd64-generic passthrough ] conformance/textures/canvas_sub_rectangle/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html [ Slow ] +crbug.com/1426916 [ chromeos chromeos-board-amd64-generic passthrough ] conformance/textures/misc/tex-image-and-sub-image-2d-with-array-buffer-view.html [ Slow ] crbug.com/1426916 [ chromeos chromeos-board-amd64-generic passthrough ] conformance2/extensions/webgl-multi-draw-instanced-base-vertex-base-instance.html [ Slow ] +crbug.com/1426916 [ chromeos chromeos-board-amd64-generic passthrough ] conformance2/sync/sync-webgl-specific.html [ Slow ] crbug.com/1426916 [ chromeos chromeos-board-amd64-generic passthrough ] conformance2/textures/canvas_sub_rectangle/tex-2d-rg32f-rg-float.html [ Slow ] crbug.com/1426916 [ chromeos chromeos-board-amd64-generic passthrough ] conformance2/textures/canvas_sub_rectangle/tex-2d-rg8ui-rg_integer-unsigned_byte.html [ Slow ] crbug.com/1426916 [ chromeos chromeos-board-amd64-generic passthrough ] conformance2/uniforms/incompatible-texture-type-for-sampler.html [ Slow ] +crbug.com/1426916 [ chromeos chromeos-board-amd64-generic passthrough ] deqp/functional/gles3/uniformapi/random.html [ Slow ] ################### # Failures/Flakes # @@ -749,8 +752,6 @@ crbug.com/1241183 [ chromeos chromeos-board-amd64-generic passthrough ] conformance2/textures/misc/immutable-tex-render-feedback.html [ Failure ] crbug.com/1399117 [ chromeos chromeos-board-amd64-generic passthrough ] WebglExtension_WEBGL_provoking_vertex [ Skip ] -crbug.com/1426913 [ chromeos chromeos-board-amd64-generic passthrough ] conformance2/sync/sync-webgl-specific.html [ RetryOnFailure ] - # Must investigate ChromeOS failures with passthrough command decoder. crbug.com/angleproject/5038 [ chromeos passthrough ] conformance/extensions/ext-color-buffer-half-float.html [ Failure ]
diff --git a/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt index 0c593354..9d6b907 100644 --- a/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt +++ b/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt
@@ -335,6 +335,8 @@ crbug.com/1426916 [ chromeos chromeos-board-amd64-generic no-passthrough ] conformance/extensions/webgl-compressed-texture-astc.html [ Slow ] crbug.com/1426916 [ chromeos chromeos-board-amd64-generic no-passthrough ] conformance/reading/read-pixels-test.html [ Slow ] crbug.com/1426916 [ chromeos chromeos-board-amd64-generic no-passthrough ] conformance/textures/misc/tex-image-and-sub-image-2d-with-array-buffer-view.html [ Slow ] +crbug.com/1427243 [ fuchsia fuchsia-board-astro ] conformance/glsl/bugs/complex-glsl-does-not-crash.html [ Slow ] +crbug.com/1427243 [ fuchsia fuchsia-board-sherlock ] conformance/glsl/bugs/complex-glsl-does-not-crash.html [ Slow ] ################### # Failures/Flakes #
diff --git a/content/test/gpu/gpu_tests/webcodecs_integration_test.py b/content/test/gpu/gpu_tests/webcodecs_integration_test.py index 48510a3..d281b16 100644 --- a/content/test/gpu/gpu_tests/webcodecs_integration_test.py +++ b/content/test/gpu/gpu_tests/webcodecs_integration_test.py
@@ -37,7 +37,7 @@ @classmethod def GenerateGpuTests(cls, options: ct.ParsedCmdArgs) -> ct.TestGenerator: tests = itertools.chain(cls.GenerateFrameTests(), cls.GenerateVideoTests(), - cls.GenerateAudioTests()) + cls.GenerateAudioTests(), cls.BitrateTests()) for test in tests: yield test @@ -81,6 +81,22 @@ }]) @classmethod + def BitrateTests(cls) -> ct.TestGenerator: + high_res_codecs = ['avc1.420034', 'vp8', 'vp09.00.10.08', 'av01.0.04M.08'] + for codec in high_res_codecs: + for acc in accelerations: + for bitrate_mode in ['constant', 'variable']: + for bitrate in [1500000, 2000000, 3000000]: + args = (codec, acc, bitrate_mode, bitrate) + yield ('WebCodecs_EncodingRateControl_%s_%s_%s_%s' % args, + 'encoding-rate-control.html', [{ + 'codec': codec, + 'acceleration': acc, + 'bitrate_mode': bitrate_mode, + 'bitrate': bitrate + }]) + + @classmethod def GenerateVideoTests(cls) -> ct.TestGenerator: yield ('WebCodecs_WebRTCPeerConnection_Window', 'webrtc-peer-connection.html', [{
diff --git a/device/bluetooth/floss/bluetooth_gatt_service_floss.cc b/device/bluetooth/floss/bluetooth_gatt_service_floss.cc index b7381431..4f23344a 100644 --- a/device/bluetooth/floss/bluetooth_gatt_service_floss.cc +++ b/device/bluetooth/floss/bluetooth_gatt_service_floss.cc
@@ -25,10 +25,12 @@ BluetoothAdapterFloss* adapter) : adapter_(adapter) { FlossDBusManager::Get()->GetGattManagerClient()->AddObserver(this); + FlossDBusManager::Get()->GetGattManagerClient()->AddServerObserver(this); } BluetoothGattServiceFloss::~BluetoothGattServiceFloss() { FlossDBusManager::Get()->GetGattManagerClient()->RemoveObserver(this); + FlossDBusManager::Get()->GetGattManagerClient()->RemoveServerObserver(this); } BluetoothAdapterFloss* BluetoothGattServiceFloss::GetAdapter() const { @@ -59,12 +61,31 @@ observer_by_handle_[handle] = observer; } +void BluetoothGattServiceFloss::AddServerObserverForHandle( + int32_t handle, + FlossGattServerObserver* observer) { + DCHECK(!base::Contains(server_observer_by_handle_, handle)); + DCHECK(observer); + + if (observer) { + server_observer_by_handle_[handle] = observer; + } +} + void BluetoothGattServiceFloss::RemoveObserverForHandle(int32_t handle) { DCHECK(base::Contains(observer_by_handle_, handle)); observer_by_handle_.erase(handle); } +void BluetoothGattServiceFloss::RemoveServerObserverForHandle(int32_t handle) { + if (!base::Contains(server_observer_by_handle_, handle)) { + return; + } + + server_observer_by_handle_.erase(handle); +} + void BluetoothGattServiceFloss::GattCharacteristicRead( std::string address, GattStatus status, @@ -111,4 +132,60 @@ } } +void BluetoothGattServiceFloss::GattServerCharacteristicReadRequest( + std::string address, + int32_t request_id, + int32_t offset, + bool is_long, + int32_t handle) { + if (base::Contains(server_observer_by_handle_, handle)) { + server_observer_by_handle_[handle]->GattServerCharacteristicReadRequest( + address, request_id, offset, is_long, handle); + } +} + +void BluetoothGattServiceFloss::GattServerDescriptorReadRequest( + std::string address, + int32_t request_id, + int32_t offset, + bool is_long, + int32_t handle) { + if (base::Contains(server_observer_by_handle_, handle)) { + server_observer_by_handle_[handle]->GattServerDescriptorReadRequest( + address, request_id, offset, is_long, handle); + } +} + +void BluetoothGattServiceFloss::GattServerCharacteristicWriteRequest( + std::string address, + int32_t request_id, + int32_t offset, + int32_t length, + bool is_prepared_write, + bool needs_response, + int32_t handle, + std::vector<uint8_t> value) { + if (base::Contains(server_observer_by_handle_, handle)) { + server_observer_by_handle_[handle]->GattServerCharacteristicWriteRequest( + address, request_id, offset, length, is_prepared_write, needs_response, + handle, value); + } +} + +void BluetoothGattServiceFloss::GattServerDescriptorWriteRequest( + std::string address, + int32_t request_id, + int32_t offset, + int32_t length, + bool is_prepared_write, + bool needs_response, + int32_t handle, + std::vector<uint8_t> value) { + if (base::Contains(server_observer_by_handle_, handle)) { + server_observer_by_handle_[handle]->GattServerDescriptorWriteRequest( + address, request_id, offset, length, is_prepared_write, needs_response, + handle, value); + } +} + } // namespace floss
diff --git a/device/bluetooth/floss/bluetooth_gatt_service_floss.h b/device/bluetooth/floss/bluetooth_gatt_service_floss.h index 0f02e26..afbf8b9 100644 --- a/device/bluetooth/floss/bluetooth_gatt_service_floss.h +++ b/device/bluetooth/floss/bluetooth_gatt_service_floss.h
@@ -16,7 +16,8 @@ // Subclass of |BluetoothGattService| for platforms that use Floss. class DEVICE_BLUETOOTH_EXPORT BluetoothGattServiceFloss : public device::BluetoothGattService, - public FlossGattClientObserver { + public FlossGattClientObserver, + public FlossGattServerObserver { public: BluetoothGattServiceFloss(const BluetoothGattServiceFloss&) = delete; BluetoothGattServiceFloss& operator=(const BluetoothGattServiceFloss&) = @@ -32,9 +33,12 @@ // Adds an observer for a specific handle. This observer will only get // callbacks invoked for that specific handle. void AddObserverForHandle(int32_t handle, FlossGattClientObserver* observer); + void AddServerObserverForHandle(int32_t handle, + FlossGattServerObserver* observer); // Removes the observer for a specific handle. void RemoveObserverForHandle(int32_t handle); + void RemoveServerObserverForHandle(int32_t handle); // FlossGattClientObserver overrides. void GattCharacteristicRead(std::string address, @@ -55,6 +59,35 @@ int32_t handle, const std::vector<uint8_t>& data) override; + // FlossGattServerObserver overrides. + void GattServerCharacteristicReadRequest(std::string address, + int32_t request_id, + int32_t offset, + bool is_long, + int32_t handle) override; + void GattServerDescriptorReadRequest(std::string address, + int32_t request_id, + int32_t offset, + bool is_long, + int32_t handle) override; + void GattServerCharacteristicWriteRequest( + std::string address, + int32_t request_id, + int32_t offset, + int32_t length, + bool is_prepared_write, + bool needs_response, + int32_t handle, + std::vector<uint8_t> value) override; + void GattServerDescriptorWriteRequest(std::string address, + int32_t request_id, + int32_t offset, + int32_t length, + bool is_prepared_write, + bool needs_response, + int32_t handle, + std::vector<uint8_t> value) override; + protected: explicit BluetoothGattServiceFloss(BluetoothAdapterFloss* adapter); ~BluetoothGattServiceFloss() override; @@ -63,6 +96,8 @@ // for a specific handle within this GATT service, it is dispatched here to // that specific observer. std::map<int32_t, raw_ptr<FlossGattClientObserver>> observer_by_handle_; + std::map<int32_t, raw_ptr<FlossGattServerObserver>> + server_observer_by_handle_; private: // The adapter associated with (and which indirectly owns) this service.
diff --git a/device/bluetooth/floss/floss_gatt_manager_client.cc b/device/bluetooth/floss/floss_gatt_manager_client.cc index f7fbb99c..fd8df95 100644 --- a/device/bluetooth/floss/floss_gatt_manager_client.cc +++ b/device/bluetooth/floss/floss_gatt_manager_client.cc
@@ -273,7 +273,8 @@ gatt_client_observers_.AddObserver(observer); } -void FlossGattManagerClient::AddObserver(FlossGattServerObserver* observer) { +void FlossGattManagerClient::AddServerObserver( + FlossGattServerObserver* observer) { gatt_server_observers_.AddObserver(observer); } @@ -281,7 +282,8 @@ gatt_client_observers_.RemoveObserver(observer); } -void FlossGattManagerClient::RemoveObserver(FlossGattServerObserver* observer) { +void FlossGattManagerClient::RemoveServerObserver( + FlossGattServerObserver* observer) { gatt_server_observers_.RemoveObserver(observer); }
diff --git a/device/bluetooth/floss/floss_gatt_manager_client.h b/device/bluetooth/floss/floss_gatt_manager_client.h index 22b6382..ac55dac5 100644 --- a/device/bluetooth/floss/floss_gatt_manager_client.h +++ b/device/bluetooth/floss/floss_gatt_manager_client.h
@@ -369,9 +369,9 @@ // Manage observers. void AddObserver(FlossGattClientObserver* observer); - void AddObserver(FlossGattServerObserver* observer); + void AddServerObserver(FlossGattServerObserver* observer); void RemoveObserver(FlossGattClientObserver* observer); - void RemoveObserver(FlossGattServerObserver* observer); + void RemoveServerObserver(FlossGattServerObserver* observer); // TODO(@sarveshkalwit): Rename client functions, ex. Connect->ClientConnect // Create a GATT client connection to a remote device on given transport.
diff --git a/extensions/browser/api/runtime/runtime_api.cc b/extensions/browser/api/runtime/runtime_api.cc index e0ad18ab..d112f7e 100644 --- a/extensions/browser/api/runtime/runtime_api.cc +++ b/extensions/browser/api/runtime/runtime_api.cc
@@ -33,6 +33,7 @@ #include "extensions/browser/lazy_context_task_queue.h" #include "extensions/browser/process_manager_factory.h" #include "extensions/common/api/runtime.h" +#include "extensions/common/constants.h" #include "extensions/common/extension.h" #include "extensions/common/manifest_handlers/background_info.h" #include "extensions/common/manifest_handlers/shared_module_info.h" @@ -744,4 +745,46 @@ return RespondNow(WithArguments(std::move(dict))); } +RuntimeGetContextsFunction::RuntimeGetContextsFunction() = default; +RuntimeGetContextsFunction::~RuntimeGetContextsFunction() = default; + +ExtensionFunction::ResponseAction RuntimeGetContextsFunction::Run() { + EXTENSION_FUNCTION_VALIDATE(extension()); + + std::vector<api::runtime::ExtensionContext> result; + if (absl::optional<api::runtime::ExtensionContext> worker = + GetWorkerContext()) { + result.push_back(std::move(*worker)); + } + + return RespondNow( + ArgumentList(api::runtime::GetContexts::Results::Create(result))); +} + +absl::optional<api::runtime::ExtensionContext> +RuntimeGetContextsFunction::GetWorkerContext() { + ProcessManager* const process_manager = + ProcessManager::Get(browser_context()); + DCHECK(process_manager); + + std::vector<WorkerId> active_workers = + process_manager->GetServiceWorkersForExtension(extension()->id()); + CHECK_LE(active_workers.size(), 1u); + + if (active_workers.empty()) { + return absl::nullopt; + } + + api::runtime::ExtensionContext context; + context.context_type = api::runtime::CONTEXT_TYPE_BACKGROUND; + // TODO(crbug/1426192): Add a real context id. + context.context_id = ""; + context.tab_id = extension_misc::kUnknownTabId; + context.window_id = extension_misc::kUnknownWindowId; + // TODO(devlin): Add extension_misc::kUnknownFrameId and use it here? + context.frame_id = -1; + context.incognito = browser_context()->IsOffTheRecord(); + return context; +} + } // namespace extensions
diff --git a/extensions/browser/api/runtime/runtime_api.h b/extensions/browser/api/runtime/runtime_api.h index 8845c8d..daa15c0f 100644 --- a/extensions/browser/api/runtime/runtime_api.h +++ b/extensions/browser/api/runtime/runtime_api.h
@@ -25,6 +25,7 @@ #include "extensions/browser/process_manager_observer.h" #include "extensions/browser/update_observer.h" #include "extensions/common/api/runtime.h" +#include "third_party/abseil-cpp/absl/types/optional.h" namespace base { class Version; @@ -319,6 +320,23 @@ ResponseAction Run() override; }; +class RuntimeGetContextsFunction : public ExtensionFunction { + public: + DECLARE_EXTENSION_FUNCTION("runtime.getContexts", RUNTIME_GETCONTEXTS) + + RuntimeGetContextsFunction(); + RuntimeGetContextsFunction(const RuntimeGetContextsFunction&) = delete; + RuntimeGetContextsFunction& operator=(const RuntimeGetContextsFunction&) = + delete; + + private: + // ExtensionFunction: + ~RuntimeGetContextsFunction() override; + ResponseAction Run() override; + + absl::optional<api::runtime::ExtensionContext> GetWorkerContext(); +}; + } // namespace extensions #endif // EXTENSIONS_BROWSER_API_RUNTIME_RUNTIME_API_H_
diff --git a/extensions/browser/browsertest_util.h b/extensions/browser/browsertest_util.h index edcb7b5b..797b83a 100644 --- a/extensions/browser/browsertest_util.h +++ b/extensions/browser/browsertest_util.h
@@ -37,7 +37,7 @@ const std::string& extension_id, const std::string& script, ScriptUserActivation script_user_activation = - ScriptUserActivation::kActivate); + ScriptUserActivation::kDontActivate); // Same as ExecuteScriptInBackgroundPage, but doesn't wait for the script // to return a result. Fails the test and returns false if |extension_id| @@ -58,7 +58,7 @@ const std::string& extension_id, const std::string& script, ScriptUserActivation script_user_activation = - ScriptUserActivation::kActivate); + ScriptUserActivation::kDontActivate); // Synchronously stops the service worker registered by the extension with the // given `extension_id` at global scope. The extension must be installed and
diff --git a/extensions/browser/extension_function_histogram_value.h b/extensions/browser/extension_function_histogram_value.h index a455a73..2fb379a 100644 --- a/extensions/browser/extension_function_histogram_value.h +++ b/extensions/browser/extension_function_histogram_value.h
@@ -1837,6 +1837,7 @@ PASSWORDSPRIVATE_CONTINUEIMPORT = 1774, PASSWORDSPRIVATE_RESETIMPORTER = 1775, SMARTCARDPROVIDERPRIVATE_REPORTCANCELRESULT = 1776, + RUNTIME_GETCONTEXTS = 1777, // Last entry: Add new entries above, then run: // tools/metrics/histograms/update_extension_histograms.py ENUM_BOUNDARY
diff --git a/extensions/common/api/_api_features.json b/extensions/common/api/_api_features.json index cb65bb9..4c990575 100644 --- a/extensions/common/api/_api_features.json +++ b/extensions/common/api/_api_features.json
@@ -543,6 +543,12 @@ "dependencies": ["permission:nativeMessaging"], "contexts": ["blessed_extension"] }, + "runtime.getContexts": { + "min_manifest_version": 3, + "contexts": ["blessed_extension"], + "channel": "trunk", + "feature_flag": "ApiRuntimeGetContexts" + }, "runtime.getURL": { "contexts": [ "blessed_extension",
diff --git a/extensions/common/api/runtime.json b/extensions/common/api/runtime.json index b43e0dd..13f0b63 100644 --- a/extensions/common/api/runtime.json +++ b/extensions/common/api/runtime.json
@@ -137,6 +137,57 @@ "type": "string", "description": "The reason that the event is being dispatched. 'app_update' is used when the restart is needed because the application is updated to a newer version. 'os_update' is used when the restart is needed because the browser/OS is updated to a newer version. 'periodic' is used when the system runs for more than the permitted uptime set in the enterprise policy.", "enum": ["app_update", "os_update", "periodic"] + }, + { + "id": "ContextType", + "type": "string", + "enum": ["TAB", "POPUP", "BACKGROUND", "OFFSCREEN_DOCUMENT"] + }, + { + "id": "ExtensionContext", + "type": "object", + "description": "A context hosting extension content.", + "properties": { + "contextType": { + "$ref": "ContextType", + "description": "The type of context this corresponds to." + }, + "contextId": { + "type": "string", + "description": "A unique identifier for this context" + }, + "tabId": { + "type": "integer", + "description": "The ID of the tab for this context, or -1 if this context is not hosted in a tab." + }, + "windowId": { + "type": "integer", + "description": "The ID of the window for this context, or -1 if this context is not hosted in a window." + }, + "documentId": { + "type": "string", + "optional": true, + "description": "A UUID for the document associated with this context, or undefined if this context is hosted not in a document." + }, + "frameId": { + "type": "integer", + "description": "The ID of the frame for this context, or -1 if this context is not hosted in a frame." + }, + "documentUrl": { + "type": "string", + "optional": true, + "description": "The URL of the document associated with this context, or undefined if the context is not hosted in a document." + }, + "documentOrigin": { + "type": "string", + "optional": true, + "description": "The origin of the document associated with this context, or undefined if the context is not hosted in a document." + }, + "incognito": { + "type": "boolean", + "description": "Whether the context is associated with an incognito profile." + } + } } ], "properties": { @@ -434,6 +485,26 @@ ] } ] + }, + { + "name": "getContexts", + "type": "function", + "description": "Fetches information about active contexts associated with this extension", + "parameters": [ + // TODO(crbug/1426192): Add a filter. + ], + "returns_async": { + "name": "callback", + "description": "Invoked with the matching contexts, if any.", + "parameters": [ + { + "name": "contexts", + "type": "array", + "description": "The matching contexts, if any.", + "items": { "$ref": "ExtensionContext" } + } + ] + } } ], "events": [
diff --git a/extensions/common/extension_features.cc b/extensions/common/extension_features.cc index 7bea9dd4..d87af4c7 100644 --- a/extensions/common/extension_features.cc +++ b/extensions/common/extension_features.cc
@@ -7,43 +7,20 @@ namespace extensions_features { -// Controls whether we show an install friction dialog when an Enhanced Safe -// Browsing user tries to install an extension that is not included in the -// Safe Browsing CRX allowlist. This feature also controls if we show a warning -// in 'chrome://extensions' for extensions not included in the allowlist. -BASE_FEATURE(kSafeBrowsingCrxAllowlistShowWarnings, - "SafeBrowsingCrxAllowlistShowWarnings", - base::FEATURE_ENABLED_BY_DEFAULT); +/////////////////////////////////////////////////////////////////////////////// +// API Features +/////////////////////////////////////////////////////////////////////////////// -// Automatically disable extensions not included in the Safe Browsing CRX -// allowlist if the user has turned on Enhanced Safe Browsing (ESB). The -// extensions can be disabled at ESB opt-in time or when an extension is moved -// out of the allowlist. -BASE_FEATURE(kSafeBrowsingCrxAllowlistAutoDisable, - "SafeBrowsingCrxAllowlistAutoDisable", +// Controls the availability of the runtime.getContexts() API. +BASE_FEATURE(kApiRuntimeGetContexts, + "ApiRuntimeGetContexts", base::FEATURE_DISABLED_BY_DEFAULT); -// Forces requests to go through WebRequestProxyingURLLoaderFactory. -BASE_FEATURE(kForceWebRequestProxyForTest, - "ForceWebRequestProxyForTest", - base::FEATURE_DISABLED_BY_DEFAULT); +/////////////////////////////////////////////////////////////////////////////// +// Other Features +/////////////////////////////////////////////////////////////////////////////// -// Enables the UI in the install prompt which lets a user choose to withhold -// requested host permissions by default. -BASE_FEATURE(kAllowWithholdingExtensionPermissionsOnInstall, - "AllowWithholdingExtensionPermissionsOnInstall", - base::FEATURE_DISABLED_BY_DEFAULT); - -// Enables support for the "match_origin_as_fallback" property in content -// scripts. -BASE_FEATURE(kContentScriptsMatchOriginAsFallback, - "ContentScriptsMatchOriginAsFallback", - base::FEATURE_ENABLED_BY_DEFAULT); - -// Reports Extensions.WebRequest.KeepaliveRequestFinished when enabled. -BASE_FEATURE(kReportKeepaliveUkm, - "ReportKeepaliveUkm", - base::FEATURE_ENABLED_BY_DEFAULT); +// For historical reasons, this includes some APIs. Please don't add more. // Whether extension contexts can use SharedArrayBuffers unconditionally (i.e. // without requiring cross origin isolation). @@ -52,18 +29,18 @@ "AllowSharedArrayBuffersUnconditionally", base::FEATURE_ENABLED_BY_DEFAULT); -// When enabled, causes Manifest V3 (and greater) extensions to use structured -// cloning (instead of JSON serialization) for extension messaging, except when -// communicating with native messaging hosts. -BASE_FEATURE(kStructuredCloningForMV3Messaging, - "StructuredCloningForMV3Messaging", +// Enables the UI in the install prompt which lets a user choose to withhold +// requested host permissions by default. +BASE_FEATURE(kAllowWithholdingExtensionPermissionsOnInstall, + "AllowWithholdingExtensionPermissionsOnInstall", base::FEATURE_DISABLED_BY_DEFAULT); -// When enabled, causes extensions to allow access to certain APIs only if the -// user is in the developer mode. -BASE_FEATURE(kRestrictDeveloperModeAPIs, - "RestrictDeveloperModeAPIs", - base::FEATURE_DISABLED_BY_DEFAULT); +// If enabled, calls RenderFrame::SetAllowsCrossBrowsingInstanceFrameLookup() in +// DidCreateScriptContext() instead of DidCommitProvisionalLoad() to avoid +// creating the script context too early which can be bad for performance. +BASE_FEATURE(kAvoidEarlyExtensionScriptContextCreation, + "AvoidEarlyExtensionScriptContextCreation", + base::FEATURE_ENABLED_BY_DEFAULT); // When enabled, then bad_message::ReceivedBadMessage will be called when // browser receives an IPC from a content script and the IPC that unexpectedly @@ -74,9 +51,10 @@ "EMF_NO_EXTENSION_ID_FOR_EXTENSION_SOURCE", base::FEATURE_ENABLED_BY_DEFAULT); -// Controls whether extensions can use the new favicon fetching in Manifest V3. -BASE_FEATURE(kNewExtensionFaviconHandling, - "ExtensionsNewFaviconHandling", +// Enables support for the "match_origin_as_fallback" property in content +// scripts. +BASE_FEATURE(kContentScriptsMatchOriginAsFallback, + "ContentScriptsMatchOriginAsFallback", base::FEATURE_ENABLED_BY_DEFAULT); // Determine if dynamic extension URLs are handled and redirected. @@ -84,52 +62,20 @@ "ExtensionDynamicURLRedirection", base::FEATURE_DISABLED_BY_DEFAULT); -// Enables enhanced site control for extensions and allowing the user to control -// site permissions. -BASE_FEATURE(kExtensionsMenuAccessControl, - "ExtensionsMenuAccessControl", - base::FEATURE_DISABLED_BY_DEFAULT); - -// If enabled, calls RenderFrame::SetAllowsCrossBrowsingInstanceFrameLookup() in -// DidCreateScriptContext() instead of DidCommitProvisionalLoad() to avoid -// creating the script context too early which can be bad for performance. -BASE_FEATURE(kAvoidEarlyExtensionScriptContextCreation, - "AvoidEarlyExtensionScriptContextCreation", - base::FEATURE_ENABLED_BY_DEFAULT); - -// The feature enabling offscreen documents in Manifest V3 extensions. -BASE_FEATURE(kExtensionsOffscreenDocuments, - "ExtensionsOffscreenDocuments", - base::FEATURE_ENABLED_BY_DEFAULT); - -// If enabled, allows APIs used by the webstore to be exposed on the URL for the -// new webstore. -BASE_FEATURE(kNewWebstoreDomain, - "NewWebstoreDomain", - base::FEATURE_ENABLED_BY_DEFAULT); - // Side panel API availability. BASE_FEATURE(kExtensionSidePanelIntegration, "ExtensionSidePanelIntegration", base::FEATURE_DISABLED_BY_DEFAULT); -// File Handlers. -BASE_FEATURE(kExtensionWebFileHandlers, - "ExtensionWebFileHandlers", - base::FEATURE_DISABLED_BY_DEFAULT); - // IsValidSourceUrl enforcement for ExtensionHostMsg_OpenChannelToExtension IPC. BASE_FEATURE(kExtensionSourceUrlEnforcement, "ExtensionSourceUrlEnforcement", base::FEATURE_ENABLED_BY_DEFAULT); -// Controls the <webview> tag behaviour changes proposed as part of the guest -// view MPArch migration. See -// https://docs.google.com/document/d/1RVbtvklXUg9QCNvMT0r-1qDwJNeQFGoTCOD1Ur9mDa4/edit?usp=sharing -// for details. -BASE_FEATURE(kWebviewTagMPArchBehavior, - "WebviewTagMPArchBehavior", - base::FEATURE_ENABLED_BY_DEFAULT); +// File Handlers. +BASE_FEATURE(kExtensionWebFileHandlers, + "ExtensionWebFileHandlers", + base::FEATURE_DISABLED_BY_DEFAULT); // If enabled, only manifest v3 extensions is allowed while v2 will be disabled. // Note that this feature is now only checked by `ExtensionManagement` which @@ -140,18 +86,10 @@ "ExtensionsManifestV3Only", base::FEATURE_DISABLED_BY_DEFAULT); -// If enabled, the minimum MV3 Content-Security-Policy will include -// 'inline-speculation-rules' source in the script-src. -// See https://crbug.com/1382361 to track the launch status. -BASE_FEATURE(kMinimumMV3CSPWithInlineSpeculationRules, - "MinimumMV3CSPWithInlineSpeculationRules", - base::FEATURE_ENABLED_BY_DEFAULT); - -// If enabled, APIs of the Telemetry Extension platform that have pending -// approval will be enabled. Read more about the platform here: -// https://chromium.googlesource.com/chromium/src/+/master/docs/telemetry_extension/README.md. -BASE_FEATURE(kTelemetryExtensionPendingApprovalApi, - "TelemetryExtensionPendingApprovalApi", +// Enables enhanced site control for extensions and allowing the user to control +// site permissions. +BASE_FEATURE(kExtensionsMenuAccessControl, + "ExtensionsMenuAccessControl", base::FEATURE_DISABLED_BY_DEFAULT); // If enabled, user permitted sites are granted access. This should only happen @@ -161,4 +99,81 @@ "ExtensionsMenuAccessControlWithPermittedSitesName", base::FEATURE_DISABLED_BY_DEFAULT); +// The feature enabling offscreen documents in Manifest V3 extensions. +BASE_FEATURE(kExtensionsOffscreenDocuments, + "ExtensionsOffscreenDocuments", + base::FEATURE_ENABLED_BY_DEFAULT); + +// Forces requests to go through WebRequestProxyingURLLoaderFactory. +BASE_FEATURE(kForceWebRequestProxyForTest, + "ForceWebRequestProxyForTest", + base::FEATURE_DISABLED_BY_DEFAULT); + +// If enabled, the minimum MV3 Content-Security-Policy will include +// 'inline-speculation-rules' source in the script-src. +// See https://crbug.com/1382361 to track the launch status. +BASE_FEATURE(kMinimumMV3CSPWithInlineSpeculationRules, + "MinimumMV3CSPWithInlineSpeculationRules", + base::FEATURE_ENABLED_BY_DEFAULT); + +// Controls whether extensions can use the new favicon fetching in Manifest V3. +BASE_FEATURE(kNewExtensionFaviconHandling, + "ExtensionsNewFaviconHandling", + base::FEATURE_ENABLED_BY_DEFAULT); + +// If enabled, allows APIs used by the webstore to be exposed on the URL for the +// new webstore. +BASE_FEATURE(kNewWebstoreDomain, + "NewWebstoreDomain", + base::FEATURE_ENABLED_BY_DEFAULT); + +BASE_FEATURE(kReportKeepaliveUkm, + "ReportKeepaliveUkm", + base::FEATURE_ENABLED_BY_DEFAULT); + +// When enabled, causes extensions to allow access to certain APIs only if the +// user is in the developer mode. +BASE_FEATURE(kRestrictDeveloperModeAPIs, + "RestrictDeveloperModeAPIs", + base::FEATURE_DISABLED_BY_DEFAULT); + +// Reports Extensions.WebRequest.KeepaliveRequestFinished when enabled. +// Automatically disable extensions not included in the Safe Browsing CRX +// allowlist if the user has turned on Enhanced Safe Browsing (ESB). The +// extensions can be disabled at ESB opt-in time or when an extension is moved +// out of the allowlist. +BASE_FEATURE(kSafeBrowsingCrxAllowlistAutoDisable, + "SafeBrowsingCrxAllowlistAutoDisable", + base::FEATURE_DISABLED_BY_DEFAULT); + +// Controls whether we show an install friction dialog when an Enhanced Safe +// Browsing user tries to install an extension that is not included in the +// Safe Browsing CRX allowlist. This feature also controls if we show a warning +// in 'chrome://extensions' for extensions not included in the allowlist. +BASE_FEATURE(kSafeBrowsingCrxAllowlistShowWarnings, + "SafeBrowsingCrxAllowlistShowWarnings", + base::FEATURE_ENABLED_BY_DEFAULT); + +// When enabled, causes Manifest V3 (and greater) extensions to use structured +// cloning (instead of JSON serialization) for extension messaging, except when +// communicating with native messaging hosts. +BASE_FEATURE(kStructuredCloningForMV3Messaging, + "StructuredCloningForMV3Messaging", + base::FEATURE_DISABLED_BY_DEFAULT); + +// If enabled, APIs of the Telemetry Extension platform that have pending +// approval will be enabled. Read more about the platform here: +// https://chromium.googlesource.com/chromium/src/+/master/docs/telemetry_extension/README.md. +BASE_FEATURE(kTelemetryExtensionPendingApprovalApi, + "TelemetryExtensionPendingApprovalApi", + base::FEATURE_DISABLED_BY_DEFAULT); + +// Controls the <webview> tag behaviour changes proposed as part of the guest +// view MPArch migration. See +// https://docs.google.com/document/d/1RVbtvklXUg9QCNvMT0r-1qDwJNeQFGoTCOD1Ur9mDa4/edit?usp=sharing +// for details. +BASE_FEATURE(kWebviewTagMPArchBehavior, + "WebviewTagMPArchBehavior", + base::FEATURE_ENABLED_BY_DEFAULT); + } // namespace extensions_features
diff --git a/extensions/common/extension_features.h b/extensions/common/extension_features.h index f71242d..376e089a 100644 --- a/extensions/common/extension_features.h +++ b/extensions/common/extension_features.h
@@ -9,52 +9,92 @@ namespace extensions_features { -BASE_DECLARE_FEATURE(kSafeBrowsingCrxAllowlistShowWarnings); -BASE_DECLARE_FEATURE(kSafeBrowsingCrxAllowlistAutoDisable); +/////////////////////////////////////////////////////////////////////////////// +// README! +// * Please keep these features alphabetized. One exception: API features go +// at the top so that they are visibly grouped together. +// * Adding a new feature for an extension API? Great! +// Please use the naming style `kApi<Namespace><Method>`, e.g. +// `kApiTabsCreate`. +// Note that if you are using the features.json files to restrict your +// API with the feature (which is usually best practice if you are introducing +// any new features), you will also have to add the feature entry to the list +// in extensions/common/features/feature_flags.cc so the features system can +// detect it. +// * Naming Tips: Even though this file is unique to extensions, base::Features +// have to be globally unique. Thus, it's often best to give features very +// specific names (often including "Extension", unlike many C++ class names) +// since namespacing doesn't otherwise exist. +/////////////////////////////////////////////////////////////////////////////// -BASE_DECLARE_FEATURE(kForceWebRequestProxyForTest); +/////////////////////////////////////////////////////////////////////////////// +// API Features +/////////////////////////////////////////////////////////////////////////////// -BASE_DECLARE_FEATURE(kAllowWithholdingExtensionPermissionsOnInstall); +// NOTE(devlin): If there are consistently enough of these in flux, it might +// make sense to have their own file. -BASE_DECLARE_FEATURE(kContentScriptsMatchOriginAsFallback); +BASE_DECLARE_FEATURE(kApiRuntimeGetContexts); -BASE_DECLARE_FEATURE(kReportKeepaliveUkm); +/////////////////////////////////////////////////////////////////////////////// +// Other Features +/////////////////////////////////////////////////////////////////////////////// + +// For historical reasons, this includes some APIs. Please don't add more. BASE_DECLARE_FEATURE(kAllowSharedArrayBuffersUnconditionally); -BASE_DECLARE_FEATURE(kStructuredCloningForMV3Messaging); - -BASE_DECLARE_FEATURE(kRestrictDeveloperModeAPIs); - -BASE_DECLARE_FEATURE(kCheckingNoExtensionIdInExtensionIpcs); - -BASE_DECLARE_FEATURE(kNewExtensionFaviconHandling); - -BASE_DECLARE_FEATURE(kExtensionDynamicURLRedirection); - -BASE_DECLARE_FEATURE(kExtensionsMenuAccessControl); +BASE_DECLARE_FEATURE(kAllowWithholdingExtensionPermissionsOnInstall); BASE_DECLARE_FEATURE(kAvoidEarlyExtensionScriptContextCreation); -BASE_DECLARE_FEATURE(kExtensionsOffscreenDocuments); +BASE_DECLARE_FEATURE(kCheckingNoExtensionIdInExtensionIpcs); -BASE_DECLARE_FEATURE(kNewWebstoreDomain); +BASE_DECLARE_FEATURE(kContentScriptsMatchOriginAsFallback); + +BASE_DECLARE_FEATURE(kExtensionDynamicURLRedirection); BASE_DECLARE_FEATURE(kExtensionSidePanelIntegration); -BASE_DECLARE_FEATURE(kExtensionWebFileHandlers); - BASE_DECLARE_FEATURE(kExtensionSourceUrlEnforcement); -BASE_DECLARE_FEATURE(kWebviewTagMPArchBehavior); +BASE_DECLARE_FEATURE(kExtensionWebFileHandlers); BASE_DECLARE_FEATURE(kExtensionsManifestV3Only); +BASE_DECLARE_FEATURE(kExtensionsMenuAccessControl); + +BASE_DECLARE_FEATURE(kExtensionsMenuAccessControlWithPermittedSites); + +BASE_DECLARE_FEATURE(kExtensionsOffscreenDocuments); + +BASE_DECLARE_FEATURE(kForceWebRequestProxyForTest); + BASE_DECLARE_FEATURE(kMinimumMV3CSPWithInlineSpeculationRules); +BASE_DECLARE_FEATURE(kNewExtensionFaviconHandling); + +BASE_DECLARE_FEATURE(kNewWebstoreDomain); + +BASE_DECLARE_FEATURE(kReportKeepaliveUkm); + +BASE_DECLARE_FEATURE(kRestrictDeveloperModeAPIs); + +BASE_DECLARE_FEATURE(kSafeBrowsingCrxAllowlistAutoDisable); + +BASE_DECLARE_FEATURE(kSafeBrowsingCrxAllowlistShowWarnings); + +BASE_DECLARE_FEATURE(kStructuredCloningForMV3Messaging); + BASE_DECLARE_FEATURE(kTelemetryExtensionPendingApprovalApi); -BASE_DECLARE_FEATURE(kExtensionsMenuAccessControlWithPermittedSites); +BASE_DECLARE_FEATURE(kWebviewTagMPArchBehavior); + +/////////////////////////////////////////////////////////////////////////////// +// STOP! +// Please don't just add your new feature down here. +// See the guidance at the top of this file. +/////////////////////////////////////////////////////////////////////////////// } // namespace extensions_features
diff --git a/extensions/common/features/feature_flags.cc b/extensions/common/features/feature_flags.cc index f1eab55e..62721e8 100644 --- a/extensions/common/features/feature_flags.cc +++ b/extensions/common/features/feature_flags.cc
@@ -20,6 +20,7 @@ // kill switches for extension features. Note any such feature flags must // generally be removed once the API has been stable for a few releases. const base::Feature* kFeatureFlags[] = { + &extensions_features::kApiRuntimeGetContexts, &extensions_features::kExtensionsOffscreenDocuments, &extensions_features::kNewWebstoreDomain, &extensions_features::kTelemetryExtensionPendingApprovalApi,
diff --git a/fuchsia_web/webengine/BUILD.gn b/fuchsia_web/webengine/BUILD.gn index f794ce2..2926894 100644 --- a/fuchsia_web/webengine/BUILD.gn +++ b/fuchsia_web/webengine/BUILD.gn
@@ -610,11 +610,10 @@ "//testing/gtest", "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.accessibility.semantics:fuchsia.accessibility.semantics_hlcpp", "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.element:fuchsia.element_hlcpp", - "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.input.virtualkeyboard:fuchsia.input.virtualkeyboard_cpp", "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.input.virtualkeyboard:fuchsia.input.virtualkeyboard_hlcpp", "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.mediacodec:fuchsia.mediacodec_hlcpp", "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.mem:fuchsia.mem_hlcpp", - "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.ui.input3:fuchsia.ui.input3_cpp", + "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.ui.input3:fuchsia.ui.input3_hlcpp", "//third_party/fuchsia-sdk/sdk/pkg/scenic_cpp", "//ui/gfx", "//ui/ozone",
diff --git a/fuchsia_web/webengine/browser/frame_impl_browsertest.cc b/fuchsia_web/webengine/browser/frame_impl_browsertest.cc index 3fb3885..e3cbd81e 100644 --- a/fuchsia_web/webengine/browser/frame_impl_browsertest.cc +++ b/fuchsia_web/webengine/browser/frame_impl_browsertest.cc
@@ -79,22 +79,6 @@ void(content::RenderViewHost* render_view_host)); }; -} // namespace - -// Defines a suite of tests that exercise Frame-level functionality, such as -// navigation commands and page events. -class FrameImplTest : public FrameImplTestBase { - public: - FrameImplTest() = default; - ~FrameImplTest() override = default; - - FrameImplTest(const FrameImplTest&) = delete; - FrameImplTest& operator=(const FrameImplTest&) = delete; - - MOCK_METHOD1(OnServeHttpRequest, - void(const net::test_server::HttpRequest& request)); -}; - std::string GetDocumentVisibilityState(fuchsia::web::Frame* frame) { auto visibility = base::MakeRefCounted<base::RefCountedData<std::string>>(); base::RunLoop loop; @@ -119,6 +103,22 @@ return dup; } +} // namespace + +// Defines a suite of tests that exercise Frame-level functionality, such as +// navigation commands and page events. +class FrameImplTest : public FrameImplTestBase { + public: + FrameImplTest() = default; + ~FrameImplTest() override = default; + + FrameImplTest(const FrameImplTest&) = delete; + FrameImplTest& operator=(const FrameImplTest&) = delete; + + MOCK_METHOD1(OnServeHttpRequest, + void(const net::test_server::HttpRequest& request)); +}; + // Verifies that Frames are initially "hidden", changes to "visible" once the // View is attached to a Presenter and back to "hidden" when the View is // detached from the Presenter. @@ -191,16 +191,6 @@ frame.navigation_listener().RunUntilTitleEquals("hidden"); } -void VerifyCanGoBackAndForward(FrameForTest& frame, - bool can_go_back_expected, - bool can_go_forward_expected) { - auto* state = frame.navigation_listener().current_state(); - EXPECT_TRUE(state->has_can_go_back()); - EXPECT_EQ(state->can_go_back(), can_go_back_expected); - EXPECT_TRUE(state->has_can_go_forward()); - EXPECT_EQ(state->can_go_forward(), can_go_forward_expected); -} - // Verifies that the browser will navigate and generate a navigation listener // event when LoadUrl() is called. IN_PROC_BROWSER_TEST_F(FrameImplTest, NavigateFrame) { @@ -364,6 +354,20 @@ frame.navigation_listener().RunUntilUrlAndTitleEquals(title3, kPage3Title); } +namespace { + +void VerifyCanGoBackAndForward(FrameForTest& frame, + bool can_go_back_expected, + bool can_go_forward_expected) { + auto* state = frame.navigation_listener().current_state(); + EXPECT_TRUE(state->has_can_go_back()); + EXPECT_EQ(state->can_go_back(), can_go_back_expected); + EXPECT_TRUE(state->has_can_go_forward()); + EXPECT_EQ(state->can_go_forward(), can_go_forward_expected); +} + +} // namespace + IN_PROC_BROWSER_TEST_F(FrameImplTest, GoBackAndForward) { auto frame = FrameForTest::Create(context(), {}); @@ -413,6 +417,8 @@ VerifyCanGoBackAndForward(frame, true, false); } +namespace { + // An HTTP response stream whose response payload can be sent as "chunks" // with indeterminate-length pauses in between. class ChunkedHttpTransaction { @@ -529,6 +535,8 @@ base::OnceClosure on_response_created_; }; +} // namespace + IN_PROC_BROWSER_TEST_F(FrameImplTest, NavigationEventDuringPendingLoad) { auto frame = FrameForTest::Create(context(), {}); @@ -797,6 +805,8 @@ frame.navigation_listener().RunUntilUrlAndTitleEquals(title1, kPage1Title); } +namespace { + // Observes events specific to the Stop() test case. struct WebContentsObserverForStop : public content::WebContentsObserver { using content::WebContentsObserver::Observe; @@ -804,6 +814,8 @@ MOCK_METHOD0(NavigationStopped, void()); }; +} // namespace + IN_PROC_BROWSER_TEST_F(FrameImplTest, Stop) { auto frame = FrameForTest::Create(context(), {}); base::RunLoop().RunUntilIdle(); @@ -1256,6 +1268,8 @@ loop.Run(); } +namespace { + // Helper class for `Frame.Close()` tests, that navigates the `Frame` to an // event-recording page, and connects to accumulate the list of events it // receives. @@ -1315,6 +1329,10 @@ const std::vector<std::string>& events() const { return events_; } + std::string EventsString() const { + return "[" + base::JoinString(events_, ", ") + "]"; + } + private: void OnMessage(fuchsia::web::WebMessage message) { events_.push_back(std::move(*base::StringFromMemBuffer(message.data()))); @@ -1328,6 +1346,12 @@ base::test::TestFuture<zx_status_t> epitaph_; }; +constexpr char kBeforeUnloadEventName[] = "window.beforeunload"; +constexpr char kUnloadEventName[] = "window.unload"; +constexpr char kPageHideEventName[] = "window.pagehide"; + +} // namespace + // Verifies that `Close()`ing a `Frame` without an explicit timeout allows // graceful teardown, including firing the expected set of events // ("beforeunload", "pagehide" and "onunload"). @@ -1346,10 +1370,10 @@ frame.RunUntilMessagePortClosed(); // Verify that the expected events were delivered! - ASSERT_EQ(frame.events().size(), 3u); - EXPECT_EQ(frame.events()[0], "window.beforeunload"); - EXPECT_EQ(frame.events()[1], "window.pagehide"); - EXPECT_EQ(frame.events()[2], "window.unload"); + ASSERT_EQ(frame.events().size(), 3u) << frame.EventsString(); + EXPECT_EQ(frame.events()[0], kBeforeUnloadEventName); + EXPECT_EQ(frame.events()[1], kPageHideEventName); + EXPECT_EQ(frame.events()[2], kUnloadEventName); EXPECT_EQ(frame.epitaph().Get(), ZX_OK); } @@ -1374,10 +1398,10 @@ frame.RunUntilMessagePortClosed(); // Verify that the expected events were delivered! - ASSERT_EQ(frame.events().size(), 3u); - EXPECT_EQ(frame.events()[0], "window.beforeunload"); - EXPECT_EQ(frame.events()[1], "window.pagehide"); - EXPECT_EQ(frame.events()[2], "window.unload"); + ASSERT_EQ(frame.events().size(), 3u) << frame.EventsString(); + EXPECT_EQ(frame.events()[0], kBeforeUnloadEventName); + EXPECT_EQ(frame.events()[1], kPageHideEventName); + EXPECT_EQ(frame.events()[2], kUnloadEventName); EXPECT_EQ(frame.epitaph().Get(), ZX_OK); } @@ -1396,7 +1420,7 @@ // Request to gracefully close the Frame, by specifying a non-zero timeout. // This can be arbitrarily short, since we are deliberately provoking timeout. frame->Close(std::move(fuchsia::web::FrameCloseRequest().set_timeout( - base::Milliseconds(1u).ToZxDuration()))); + base::Microseconds(1u).ToZxDuration()))); // Don't wait for the MessagePort to close, since that doesn't happen in // ASAN builds, for some reason (crbug.com/1400304). @@ -1421,8 +1445,10 @@ frame.RunUntilMessagePortClosed(); - // Verify that no events were observed. - EXPECT_EQ(frame.events().size(), 0u); + // In practice it is possible for content to have time to receive & process + // visibility and unload events, so just check for "beforeunload". + EXPECT_THAT(frame.events(), Not(Contains(kBeforeUnloadEventName))) + << frame.EventsString(); EXPECT_EQ(frame.epitaph().Get(), ZX_OK); } @@ -1441,6 +1467,8 @@ frame.RunUntilMessagePortClosed(); - // Verify that no events were observed. - EXPECT_EQ(frame.events().size(), 0u); + // In practice it is possible for content to have time to receive & process + // visibility and unload events, so just check for "beforeunload". + EXPECT_THAT(frame.events(), Not(Contains(kBeforeUnloadEventName))) + << frame.EventsString(); }
diff --git a/fuchsia_web/webengine/browser/input_browsertest.cc b/fuchsia_web/webengine/browser/input_browsertest.cc index 14342fe..4a153c48 100644 --- a/fuchsia_web/webengine/browser/input_browsertest.cc +++ b/fuchsia_web/webengine/browser/input_browsertest.cc
@@ -2,10 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include <fidl/fuchsia.input.virtualkeyboard/cpp/wire_messaging.h> -#include <fidl/fuchsia.ui.input3/cpp/fidl.h> -#include <lib/async/default.h> - +#include <fuchsia/input/virtualkeyboard/cpp/fidl.h> +#include <fuchsia/ui/input3/cpp/fidl.h> +#include <fuchsia/ui/input3/cpp/fidl_test_base.h> #include <memory> #include "base/fuchsia/scoped_service_binding.h" @@ -24,9 +23,11 @@ #include "fuchsia_web/webengine/test/web_engine_browser_test.h" #include "testing/gtest/include/gtest/gtest.h" -using fuchsia_input::Key; -using fuchsia_ui_input3::KeyEvent; -using fuchsia_ui_input3::KeyEventType; +using fuchsia::input::Key; +using fuchsia::ui::input3::KeyEvent; +using fuchsia::ui::input3::KeyEventType; +using fuchsia::ui::input3::KeyMeaning; +using fuchsia::ui::input3::NonPrintableKey; namespace { @@ -38,41 +39,42 @@ // Returns a KeyEvent with |key_meaning| set based on the supplied codepoint, // the |key| field left not set. KeyEvent CreateCharacterKeyEvent(uint32_t codepoint, KeyEventType event_type) { - return {{ - .timestamp = base::TimeTicks::Now().ToZxTime(), - .type = event_type, - .key_meaning = fuchsia_ui_input3::KeyMeaning::WithCodepoint(codepoint), - }}; + KeyEvent key_event; + + fuchsia::ui::input3::KeyMeaning meaning; + meaning.set_codepoint(codepoint); + key_event.set_key_meaning(std::move(meaning)); + key_event.set_type(event_type); + key_event.set_timestamp(base::TimeTicks::Now().ToZxTime()); + return key_event; } struct KeyEventOptions { bool repeat; - std::vector<fuchsia_ui_input3::Modifiers> modifiers; + std::vector<fuchsia::ui::input3::Modifiers> modifiers; }; // Returns a KeyEvent with both |key| and |key_meaning| set. KeyEvent CreateKeyEvent(Key key, - fuchsia_ui_input3::KeyMeaning key_meaning, + KeyMeaning key_meaning, KeyEventType event_type, KeyEventOptions options = {}) { - KeyEvent key_event{{ - .timestamp = base::TimeTicks::Now().ToZxTime(), - .type = event_type, - .key = key, - .key_meaning = std::move(key_meaning), - }}; - + KeyEvent key_event; + key_event.set_timestamp(base::TimeTicks::Now().ToZxTime()); + key_event.set_type(event_type); + key_event.set_key(key); + key_event.set_key_meaning(std::move(key_meaning)); if (options.repeat) { // Chromium doesn't look at the value of this, it just check if the field is // present. - key_event.repeat_sequence(1); + key_event.set_repeat_sequence(1); } if (!options.modifiers.empty()) { - fuchsia_ui_input3::Modifiers modifiers; + fuchsia::ui::input3::Modifiers modifiers; for (const auto modifier : options.modifiers) { modifiers |= modifier; } - key_event.modifiers(modifiers); + key_event.set_modifiers(modifiers); } return key_event; } @@ -80,39 +82,37 @@ uint32_t codepoint, KeyEventType event_type, KeyEventOptions options = {}) { - return CreateKeyEvent( - key, fuchsia_ui_input3::KeyMeaning::WithCodepoint(std::move(codepoint)), - event_type, options); + return CreateKeyEvent(key, KeyMeaning::WithCodepoint(std::move(codepoint)), + event_type, options); } KeyEvent CreateKeyEvent(Key key, - fuchsia_ui_input3::NonPrintableKey non_printable_key, + NonPrintableKey non_printable_key, KeyEventType event_type, KeyEventOptions options = {}) { - return CreateKeyEvent(key, - fuchsia_ui_input3::KeyMeaning::WithNonPrintableKey( - std::move(non_printable_key)), - event_type, options); + return CreateKeyEvent( + key, KeyMeaning::WithNonPrintableKey(std::move(non_printable_key)), + event_type, options); } base::Value::List FuchsiaModifiersToWebModifiers( - const std::vector<fuchsia_ui_input3::Modifiers> fuchsia_modifiers) { + const std::vector<fuchsia::ui::input3::Modifiers> fuchsia_modifiers) { base::Value::List web_modifiers; for (const auto modifier : fuchsia_modifiers) { - if (modifier == fuchsia_ui_input3::Modifiers::kAlt) { + if (modifier == fuchsia::ui::input3::Modifiers::ALT) { web_modifiers.Append("Alt"); - } else if (modifier == fuchsia_ui_input3::Modifiers::kAltGraph) { + } else if (modifier == fuchsia::ui::input3::Modifiers::ALT_GRAPH) { web_modifiers.Append("AltGraph"); - } else if (modifier == fuchsia_ui_input3::Modifiers::kCapsLock) { + } else if (modifier == fuchsia::ui::input3::Modifiers::CAPS_LOCK) { web_modifiers.Append("CapsLock"); - } else if (modifier == fuchsia_ui_input3::Modifiers::kCtrl) { + } else if (modifier == fuchsia::ui::input3::Modifiers::CTRL) { web_modifiers.Append("Control"); - } else if (modifier == fuchsia_ui_input3::Modifiers::kMeta) { + } else if (modifier == fuchsia::ui::input3::Modifiers::META) { web_modifiers.Append("Meta"); - } else if (modifier == fuchsia_ui_input3::Modifiers::kNumLock) { + } else if (modifier == fuchsia::ui::input3::Modifiers::NUM_LOCK) { web_modifiers.Append("NumLock"); - } else if (modifier == fuchsia_ui_input3::Modifiers::kScrollLock) { + } else if (modifier == fuchsia::ui::input3::Modifiers::SCROLL_LOCK) { web_modifiers.Append("ScrollLock"); - } else if (modifier == fuchsia_ui_input3::Modifiers::kShift) { + } else if (modifier == fuchsia::ui::input3::Modifiers::SHIFT) { web_modifiers.Append("Shift"); } else { NOTREACHED() << static_cast<uint64_t>(modifier) << " has no web mapping"; @@ -134,46 +134,49 @@ return base::Value(std::move(expected)); } -class FakeKeyboard : public fidl::Server<fuchsia_ui_input3::Keyboard> { +class FakeKeyboard : public fuchsia::ui::input3::testing::Keyboard_TestBase { public: explicit FakeKeyboard(sys::OutgoingDirectory* additional_services) - : binding_(additional_services, this, async_get_default_dispatcher()) {} + : binding_(additional_services, this) {} ~FakeKeyboard() override = default; FakeKeyboard(const FakeKeyboard&) = delete; FakeKeyboard& operator=(const FakeKeyboard&) = delete; - base::ScopedNaturalServiceBinding<fuchsia_ui_input3::Keyboard>* binding() { + base::ScopedServiceBinding<fuchsia::ui::input3::Keyboard>* binding() { return &binding_; } // Sends |key_event| to |listener_|; void SendKeyEvent(KeyEvent key_event) { - listener_->OnKeyEvent(std::move(key_event)) - .ThenExactlyOnce( - [num_sent_events = num_sent_events_, - this](const fidl::Result< - fuchsia_ui_input3::KeyboardListener::OnKeyEvent>& result) { - ASSERT_EQ(num_acked_events_, num_sent_events) - << "Key events are acked out of order"; - num_acked_events_++; - }); + listener_->OnKeyEvent(std::move(key_event), + [num_sent_events = num_sent_events_, + this](fuchsia::ui::input3::KeyEventStatus status) { + ASSERT_EQ(num_acked_events_, num_sent_events) + << "Key events are acked out of order"; + num_acked_events_++; + }); num_sent_events_++; } - // fuchsia_ui_input3::Keyboard implementation. - void AddListener(AddListenerRequest& request, - AddListenerCompleter::Sync& completer) final { + // fuchsia::ui::input3::Keyboard implementation. + void AddListener( + fuchsia::ui::views::ViewRef view_ref, + fidl::InterfaceHandle<::fuchsia::ui::input3::KeyboardListener> listener, + AddListenerCallback callback) final { // This implementation is only set up to have up to one listener. EXPECT_FALSE(listener_); - listener_.Bind(std::move(request.listener()), - async_get_default_dispatcher()); - completer.Reply(); + listener_ = listener.Bind(); + callback(); + } + + void NotImplemented_(const std::string& name) final { + NOTIMPLEMENTED() << name; } private: - fidl::Client<fuchsia_ui_input3::KeyboardListener> listener_; - base::ScopedNaturalServiceBinding<fuchsia_ui_input3::Keyboard> binding_; + fuchsia::ui::input3::KeyboardListenerPtr listener_; + base::ScopedServiceBinding<fuchsia::ui::input3::Keyboard> binding_; // Counters to make sure key events are acked in order. int num_sent_events_ = 0; @@ -211,8 +214,7 @@ component_context_.emplace( base::TestComponentContextForProcess::InitialState::kCloneAll); component_context_->additional_services() - ->RemovePublicService<fuchsia_ui_input3::Keyboard>( - fidl::DiscoverableProtocolName<fuchsia_ui_input3::Keyboard>); + ->RemovePublicService<fuchsia::ui::input3::Keyboard>(); SetUpService(); virtual_keyboard_checker_.emplace( component_context_->additional_services()); @@ -267,7 +269,7 @@ absl::optional<FakeKeyboard> keyboard_service_; base::test::ScopedFeatureList scoped_feature_list_; absl::optional< - NeverConnectedChecker<fuchsia_input_virtualkeyboard::ControllerCreator>> + NeverConnectedChecker<fuchsia::input::virtualkeyboard::ControllerCreator>> virtual_keyboard_checker_; }; @@ -277,13 +279,13 @@ // Pressing character keys will generate a JavaScript keydown event followed // by a keypress event. Releasing any key generates a keyup event. keyboard_service_->SendKeyEvent( - CreateKeyEvent(Key::kA, 'a', KeyEventType::kPressed)); + CreateKeyEvent(Key::A, 'a', KeyEventType::PRESSED)); keyboard_service_->SendKeyEvent( - CreateKeyEvent(Key::kKey8, '8', KeyEventType::kPressed)); + CreateKeyEvent(Key::KEY_8, '8', KeyEventType::PRESSED)); keyboard_service_->SendKeyEvent( - CreateKeyEvent(Key::kKey8, '8', KeyEventType::kReleased)); + CreateKeyEvent(Key::KEY_8, '8', KeyEventType::RELEASED)); keyboard_service_->SendKeyEvent( - CreateKeyEvent(Key::kA, 'a', KeyEventType::kReleased)); + CreateKeyEvent(Key::A, 'a', KeyEventType::RELEASED)); ExpectKeyEventsEqual(ExpectedKeyValue("KeyA", "a", kKeyDown), ExpectedKeyValue("KeyA", "a", kKeyPress), @@ -299,11 +301,11 @@ // Pressing character keys will generate a JavaScript keydown event followed // by a keypress event. Releasing any key generates a keyup event. keyboard_service_->SendKeyEvent( - CreateCharacterKeyEvent('A', KeyEventType::kPressed)); + CreateCharacterKeyEvent('A', KeyEventType::PRESSED)); keyboard_service_->SendKeyEvent( - CreateCharacterKeyEvent('A', KeyEventType::kReleased)); + CreateCharacterKeyEvent('A', KeyEventType::RELEASED)); keyboard_service_->SendKeyEvent( - CreateCharacterKeyEvent('b', KeyEventType::kPressed)); + CreateCharacterKeyEvent('b', KeyEventType::PRESSED)); ExpectKeyEventsEqual( ExpectedKeyValue("", "A", kKeyDown), ExpectedKeyValue("", "A", kKeyPress), @@ -316,13 +318,13 @@ // TODO(fxbug.dev/106600): Update the WithCodepoint(0)s when the platform is // fixed to provide valid KeyMeanings for these keys. keyboard_service_->SendKeyEvent( - CreateKeyEvent(Key::kLeftShift, 0, KeyEventType::kPressed)); + CreateKeyEvent(Key::LEFT_SHIFT, 0, KeyEventType::PRESSED)); keyboard_service_->SendKeyEvent( - CreateCharacterKeyEvent('a', KeyEventType::kPressed)); + CreateCharacterKeyEvent('a', KeyEventType::PRESSED)); keyboard_service_->SendKeyEvent( - CreateCharacterKeyEvent('a', KeyEventType::kReleased)); + CreateCharacterKeyEvent('a', KeyEventType::RELEASED)); keyboard_service_->SendKeyEvent( - CreateKeyEvent(Key::kLeftShift, 0, KeyEventType::kReleased)); + CreateKeyEvent(Key::LEFT_SHIFT, 0, KeyEventType::RELEASED)); ExpectKeyEventsEqual( ExpectedKeyValue("ShiftLeft", "Shift", kKeyDown), @@ -336,9 +338,9 @@ IN_PROC_BROWSER_TEST_F(KeyboardInputTest, CharacterInBmp) { const wchar_t kSigma = 0x03C3; keyboard_service_->SendKeyEvent( - CreateCharacterKeyEvent(kSigma, KeyEventType::kPressed)); + CreateCharacterKeyEvent(kSigma, KeyEventType::PRESSED)); keyboard_service_->SendKeyEvent( - CreateCharacterKeyEvent(kSigma, KeyEventType::kReleased)); + CreateCharacterKeyEvent(kSigma, KeyEventType::RELEASED)); std::string expected_utf8; ASSERT_TRUE(base::WideToUTF8(&kSigma, 1, &expected_utf8)); @@ -353,13 +355,13 @@ const uint32_t kRamenEmoji = 0x1F35C; keyboard_service_->SendKeyEvent( - CreateCharacterKeyEvent(kRamenEmoji, KeyEventType::kPressed)); + CreateCharacterKeyEvent(kRamenEmoji, KeyEventType::PRESSED)); keyboard_service_->SendKeyEvent( - CreateCharacterKeyEvent(kRamenEmoji, KeyEventType::kReleased)); + CreateCharacterKeyEvent(kRamenEmoji, KeyEventType::RELEASED)); keyboard_service_->SendKeyEvent( - CreateCharacterKeyEvent('a', KeyEventType::kPressed)); + CreateCharacterKeyEvent('a', KeyEventType::PRESSED)); keyboard_service_->SendKeyEvent( - CreateCharacterKeyEvent('a', KeyEventType::kReleased)); + CreateCharacterKeyEvent('a', KeyEventType::RELEASED)); ExpectKeyEventsEqual(ExpectedKeyValue("", "a", kKeyDown), ExpectedKeyValue("", "a", kKeyPress), @@ -368,17 +370,17 @@ IN_PROC_BROWSER_TEST_F(KeyboardInputTest, ShiftPrintableKeys) { keyboard_service_->SendKeyEvent( - CreateKeyEvent(Key::kLeftShift, 0, KeyEventType::kPressed)); + CreateKeyEvent(Key::LEFT_SHIFT, 0, KeyEventType::PRESSED)); keyboard_service_->SendKeyEvent( - CreateKeyEvent(Key::kB, 'B', KeyEventType::kPressed)); + CreateKeyEvent(Key::B, 'B', KeyEventType::PRESSED)); keyboard_service_->SendKeyEvent( - CreateKeyEvent(Key::kKey1, '!', KeyEventType::kPressed)); + CreateKeyEvent(Key::KEY_1, '!', KeyEventType::PRESSED)); keyboard_service_->SendKeyEvent( - CreateKeyEvent(Key::kSpace, ' ', KeyEventType::kPressed)); + CreateKeyEvent(Key::SPACE, ' ', KeyEventType::PRESSED)); keyboard_service_->SendKeyEvent( - CreateKeyEvent(Key::kLeftShift, 0, KeyEventType::kReleased)); + CreateKeyEvent(Key::LEFT_SHIFT, 0, KeyEventType::RELEASED)); keyboard_service_->SendKeyEvent( - CreateKeyEvent(Key::kDot, '.', KeyEventType::kPressed)); + CreateKeyEvent(Key::DOT, '.', KeyEventType::PRESSED)); // Note that non-character keys (e.g. shift, control) only generate key down // and key up web events. They do not generate key pressed events. @@ -396,14 +398,13 @@ IN_PROC_BROWSER_TEST_F(KeyboardInputTest, ShiftNonPrintableKeys) { keyboard_service_->SendKeyEvent( - CreateKeyEvent(Key::kRightShift, 0, KeyEventType::kPressed)); + CreateKeyEvent(Key::RIGHT_SHIFT, 0, KeyEventType::PRESSED)); + keyboard_service_->SendKeyEvent(CreateKeyEvent( + Key::ENTER, NonPrintableKey::ENTER, KeyEventType::PRESSED)); keyboard_service_->SendKeyEvent( - CreateKeyEvent(Key::kEnter, fuchsia_ui_input3::NonPrintableKey::kEnter, - KeyEventType::kPressed)); + CreateKeyEvent(Key::LEFT_CTRL, 0, KeyEventType::PRESSED)); keyboard_service_->SendKeyEvent( - CreateKeyEvent(Key::kLeftCtrl, 0, KeyEventType::kPressed)); - keyboard_service_->SendKeyEvent( - CreateKeyEvent(Key::kRightShift, 0, KeyEventType::kReleased)); + CreateKeyEvent(Key::RIGHT_SHIFT, 0, KeyEventType::RELEASED)); // Note that non-character keys (e.g. shift, control) only generate key down // and key up web events. They do not generate key pressed events. @@ -416,9 +417,9 @@ IN_PROC_BROWSER_TEST_F(KeyboardInputTest, RepeatedKeys) { keyboard_service_->SendKeyEvent( - CreateKeyEvent(Key::kA, 'a', KeyEventType::kPressed, {.repeat = true})); - keyboard_service_->SendKeyEvent(CreateKeyEvent( - Key::kKey8, '8', KeyEventType::kPressed, {.repeat = true})); + CreateKeyEvent(Key::A, 'a', KeyEventType::PRESSED, {.repeat = true})); + keyboard_service_->SendKeyEvent( + CreateKeyEvent(Key::KEY_8, '8', KeyEventType::PRESSED, {.repeat = true})); // Note that non-character keys (e.g. shift, control) only generate key down // and key up web events. They do not generate key pressed events. @@ -436,17 +437,17 @@ // * LEFT_*/RIGHT_* are not valid by themselves. // * FUNCTION and SYMBOL. See AllUnsupportedWebModifierKeys test. const std::vector kAllSupportedModifiers = { - fuchsia_ui_input3::Modifiers::kCapsLock, - fuchsia_ui_input3::Modifiers::kNumLock, - fuchsia_ui_input3::Modifiers::kScrollLock, - fuchsia_ui_input3::Modifiers::kShift, - fuchsia_ui_input3::Modifiers::kAlt, - fuchsia_ui_input3::Modifiers::kAltGraph, - fuchsia_ui_input3::Modifiers::kMeta, - fuchsia_ui_input3::Modifiers::kCtrl}; + fuchsia::ui::input3::Modifiers::CAPS_LOCK, + fuchsia::ui::input3::Modifiers::NUM_LOCK, + fuchsia::ui::input3::Modifiers::SCROLL_LOCK, + fuchsia::ui::input3::Modifiers::SHIFT, + fuchsia::ui::input3::Modifiers::ALT, + fuchsia::ui::input3::Modifiers::ALT_GRAPH, + fuchsia::ui::input3::Modifiers::META, + fuchsia::ui::input3::Modifiers::CTRL}; for (const auto& modifier : kAllSupportedModifiers) { keyboard_service_->SendKeyEvent(CreateKeyEvent( - Key::kM, 'm', KeyEventType::kPressed, {.modifiers = {modifier}})); + Key::M, 'm', KeyEventType::PRESSED, {.modifiers = {modifier}})); } base::Value::List expected_events; @@ -455,8 +456,8 @@ ExpectedKeyValue("KeyM", "m", kKeyDown, {.modifiers = {modifier}})); // Chrome doesn't emit keypress events when an ALT or CTRL modifier is // present. - if (modifier != fuchsia_ui_input3::Modifiers::kAlt && - modifier != fuchsia_ui_input3::Modifiers::kCtrl) { + if (modifier != fuchsia::ui::input3::Modifiers::ALT && + modifier != fuchsia::ui::input3::Modifiers::CTRL) { expected_events.Append( ExpectedKeyValue("KeyM", "m", kKeyPress, {.modifiers = {modifier}})); } @@ -470,11 +471,11 @@ // because they aren't included in // https://crsrc.org/c/ui/events/blink/blink_event_util.cc;l=268?q=EventFlagsToWebEventModifiers const std::vector kAllUnsupportedModifiers = { - fuchsia_ui_input3::Modifiers::kFunction, - fuchsia_ui_input3::Modifiers::kSymbol}; + fuchsia::ui::input3::Modifiers::FUNCTION, + fuchsia::ui::input3::Modifiers::SYMBOL}; for (const auto& modifier : kAllUnsupportedModifiers) { keyboard_service_->SendKeyEvent(CreateKeyEvent( - Key::kM, 'm', KeyEventType::kPressed, {.modifiers = {modifier}})); + Key::M, 'm', KeyEventType::PRESSED, {.modifiers = {modifier}})); } base::Value::List expected_events; @@ -491,75 +492,76 @@ IN_PROC_BROWSER_TEST_F(KeyboardInputTest, AssortedModifierKeyCombos) { // Test that sending LEFT/RIGHT SHIFT with agnostic SHIFT passes DCHECK. keyboard_service_->SendKeyEvent(CreateKeyEvent( - Key::kA, 'a', KeyEventType::kPressed, - {.modifiers = {fuchsia_ui_input3::Modifiers::kShift, - fuchsia_ui_input3::Modifiers::kLeftShift, - fuchsia_ui_input3::Modifiers::kRightShift}})); + Key::A, 'a', KeyEventType::PRESSED, + {.modifiers = {fuchsia::ui::input3::Modifiers::SHIFT, + fuchsia::ui::input3::Modifiers::LEFT_SHIFT, + fuchsia::ui::input3::Modifiers::RIGHT_SHIFT}})); // Test that sending LEFT/RIGHT ALT with agnostic ALT passes DCHECK. - keyboard_service_->SendKeyEvent( - CreateKeyEvent(Key::kKey8, '8', KeyEventType::kPressed, - {.modifiers = {fuchsia_ui_input3::Modifiers::kAlt, - fuchsia_ui_input3::Modifiers::kLeftAlt, - fuchsia_ui_input3::Modifiers::kRightAlt}})); + keyboard_service_->SendKeyEvent(CreateKeyEvent( + Key::KEY_8, '8', KeyEventType::PRESSED, + {.modifiers = {fuchsia::ui::input3::Modifiers::ALT, + fuchsia::ui::input3::Modifiers::LEFT_ALT, + fuchsia::ui::input3::Modifiers::RIGHT_ALT}})); // Test that sending LEFT/RIGHT META with agnostic META passes DCHECK. keyboard_service_->SendKeyEvent(CreateKeyEvent( - Key::kB, 'b', KeyEventType::kPressed, - {.modifiers = {fuchsia_ui_input3::Modifiers::kMeta, - fuchsia_ui_input3::Modifiers::kLeftMeta, - fuchsia_ui_input3::Modifiers::kRightMeta}})); + Key::B, 'b', KeyEventType::PRESSED, + {.modifiers = {fuchsia::ui::input3::Modifiers::META, + fuchsia::ui::input3::Modifiers::LEFT_META, + fuchsia::ui::input3::Modifiers::RIGHT_META}})); // Test that sending LEFT/RIGHT CTRL with agnostic CTRL passes DCHECK. keyboard_service_->SendKeyEvent(CreateKeyEvent( - Key::kLeft, 0, KeyEventType::kPressed, - {.modifiers = {fuchsia_ui_input3::Modifiers::kCtrl, - fuchsia_ui_input3::Modifiers::kLeftCtrl, - fuchsia_ui_input3::Modifiers::kRightCtrl}})); + Key::LEFT, 0, KeyEventType::PRESSED, + {.modifiers = {fuchsia::ui::input3::Modifiers::CTRL, + fuchsia::ui::input3::Modifiers::LEFT_CTRL, + fuchsia::ui::input3::Modifiers::RIGHT_CTRL}})); keyboard_service_->SendKeyEvent( - CreateKeyEvent(Key::kP, 'p', KeyEventType::kPressed, - {.modifiers = {fuchsia_ui_input3::Modifiers::kCtrl, - fuchsia_ui_input3::Modifiers::kShift}})); - keyboard_service_->SendKeyEvent( - CreateKeyEvent(Key::kRight, 0, KeyEventType::kPressed, - {.modifiers = {fuchsia_ui_input3::Modifiers::kAltGraph}})); - keyboard_service_->SendKeyEvent( - CreateKeyEvent(Key::kUp, 0, KeyEventType::kPressed, - {.modifiers = {fuchsia_ui_input3::Modifiers::kCapsLock}})); - keyboard_service_->SendKeyEvent( - CreateKeyEvent(Key::kDown, 0, KeyEventType::kPressed, - {.modifiers = {fuchsia_ui_input3::Modifiers::kNumLock}})); + CreateKeyEvent(Key::P, 'p', KeyEventType::PRESSED, + {.modifiers = {fuchsia::ui::input3::Modifiers::CTRL, + fuchsia::ui::input3::Modifiers::SHIFT}})); keyboard_service_->SendKeyEvent(CreateKeyEvent( - Key::kLeft, 0, KeyEventType::kPressed, - {.modifiers = {fuchsia_ui_input3::Modifiers::kScrollLock}})); + Key::RIGHT, 0, KeyEventType::PRESSED, + {.modifiers = {fuchsia::ui::input3::Modifiers::ALT_GRAPH}})); + keyboard_service_->SendKeyEvent(CreateKeyEvent( + Key::UP, 0, KeyEventType::PRESSED, + {.modifiers = {fuchsia::ui::input3::Modifiers::CAPS_LOCK}})); + keyboard_service_->SendKeyEvent(CreateKeyEvent( + Key::DOWN, 0, KeyEventType::PRESSED, + {.modifiers = {fuchsia::ui::input3::Modifiers::NUM_LOCK}})); + keyboard_service_->SendKeyEvent(CreateKeyEvent( + Key::LEFT, 0, KeyEventType::PRESSED, + {.modifiers = {fuchsia::ui::input3::Modifiers::SCROLL_LOCK}})); ExpectKeyEventsEqual( ExpectedKeyValue("KeyA", "a", kKeyDown, - {.modifiers = {fuchsia_ui_input3::Modifiers::kShift}}), + {.modifiers = {fuchsia::ui::input3::Modifiers::SHIFT}}), ExpectedKeyValue("KeyA", "a", kKeyPress, - {.modifiers = {fuchsia_ui_input3::Modifiers::kShift}}), + {.modifiers = {fuchsia::ui::input3::Modifiers::SHIFT}}), ExpectedKeyValue("Digit8", "8", kKeyDown, - {.modifiers = {fuchsia_ui_input3::Modifiers::kAlt}}), + {.modifiers = {fuchsia::ui::input3::Modifiers::ALT}}), ExpectedKeyValue("KeyB", "b", kKeyDown, - {.modifiers = {fuchsia_ui_input3::Modifiers::kMeta}}), + {.modifiers = {fuchsia::ui::input3::Modifiers::META}}), ExpectedKeyValue("KeyB", "b", kKeyPress, - {.modifiers = {fuchsia_ui_input3::Modifiers::kMeta}}), + {.modifiers = {fuchsia::ui::input3::Modifiers::META}}), ExpectedKeyValue("ArrowLeft", "ArrowLeft", kKeyDown, - {.modifiers = {fuchsia_ui_input3::Modifiers::kCtrl}}), + {.modifiers = {fuchsia::ui::input3::Modifiers::CTRL}}), ExpectedKeyValue("KeyP", "p", kKeyDown, - {.modifiers = {fuchsia_ui_input3::Modifiers::kCtrl, - fuchsia_ui_input3::Modifiers::kShift}}), + {.modifiers = {fuchsia::ui::input3::Modifiers::CTRL, + fuchsia::ui::input3::Modifiers::SHIFT}}), ExpectedKeyValue("KeyP", "p", kKeyPress, - {.modifiers = {fuchsia_ui_input3::Modifiers::kCtrl, - fuchsia_ui_input3::Modifiers::kShift}}), + {.modifiers = {fuchsia::ui::input3::Modifiers::CTRL, + fuchsia::ui::input3::Modifiers::SHIFT}}), ExpectedKeyValue( "ArrowRight", "ArrowRight", kKeyDown, - {.modifiers = {fuchsia_ui_input3::Modifiers::kAltGraph}}), + {.modifiers = {fuchsia::ui::input3::Modifiers::ALT_GRAPH}}), ExpectedKeyValue( "ArrowUp", "ArrowUp", kKeyDown, - {.modifiers = {fuchsia_ui_input3::Modifiers::kCapsLock}}), - ExpectedKeyValue("ArrowDown", "ArrowDown", kKeyDown, - {.modifiers = {fuchsia_ui_input3::Modifiers::kNumLock}}), + {.modifiers = {fuchsia::ui::input3::Modifiers::CAPS_LOCK}}), + ExpectedKeyValue( + "ArrowDown", "ArrowDown", kKeyDown, + {.modifiers = {fuchsia::ui::input3::Modifiers::NUM_LOCK}}), ExpectedKeyValue( "ArrowLeft", "ArrowLeft", kKeyDown, - {.modifiers = {fuchsia_ui_input3::Modifiers::kScrollLock}})); + {.modifiers = {fuchsia::ui::input3::Modifiers::SCROLL_LOCK}})); } IN_PROC_BROWSER_TEST_F(KeyboardInputTest, Disconnect) { @@ -588,7 +590,7 @@ keyboard_input_checker_.emplace(component_context_->additional_services()); } - absl::optional<NeverConnectedChecker<fuchsia_ui_input3::Keyboard>> + absl::optional<NeverConnectedChecker<fuchsia::ui::input3::Keyboard>> keyboard_input_checker_; };
diff --git a/fuchsia_web/webengine/browser/virtual_keyboard_browsertest.cc b/fuchsia_web/webengine/browser/virtual_keyboard_browsertest.cc index 7b239cf..6203645 100644 --- a/fuchsia_web/webengine/browser/virtual_keyboard_browsertest.cc +++ b/fuchsia_web/webengine/browser/virtual_keyboard_browsertest.cc
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include <fidl/fuchsia.ui.input3/cpp/fidl.h> #include <fuchsia/input/virtualkeyboard/cpp/fidl.h> +#include <fuchsia/ui/input3/cpp/fidl.h> #include <lib/fit/function.h> #include "base/fuchsia/fuchsia_logging.h" @@ -73,8 +73,7 @@ // Ensure that the fuchsia.ui.input3.Keyboard service is connected. component_context_->additional_services() - ->RemovePublicService<fuchsia_ui_input3::Keyboard>( - fidl::DiscoverableProtocolName<fuchsia_ui_input3::Keyboard>); + ->RemovePublicService<fuchsia::ui::input3::Keyboard>(); keyboard_input_checker_.emplace(component_context_->additional_services()); fuchsia::web::NavigationControllerPtr controller; @@ -135,7 +134,7 @@ ScenicTestHelper scenic_test_helper_; base::test::ScopedFeatureList scoped_feature_list_; - absl::optional<EnsureConnectedChecker<fuchsia_ui_input3::Keyboard>> + absl::optional<EnsureConnectedChecker<fuchsia::ui::input3::Keyboard>> keyboard_input_checker_; // Fake virtual keyboard services for the InputMethod to use.
diff --git a/fuchsia_web/webengine/test/scoped_connection_checker.h b/fuchsia_web/webengine/test/scoped_connection_checker.h index 9a6b313..8bc2441 100644 --- a/fuchsia_web/webengine/test/scoped_connection_checker.h +++ b/fuchsia_web/webengine/test/scoped_connection_checker.h
@@ -6,9 +6,7 @@ #define FUCHSIA_WEB_WEBENGINE_TEST_SCOPED_CONNECTION_CHECKER_H_ #include <lib/fdio/directory.h> -#include <lib/fidl/cpp/wire/connect_service.h> #include <lib/vfs/cpp/service.h> - #include <memory> #include <string> @@ -16,8 +14,8 @@ #include "testing/gtest/include/gtest/gtest.h" // Verifies that a connection was made, or never attempted, for a given -// `Protocol` without needing to provide an implementation. -template <typename Protocol, bool expect_connection> +// |Service| without needing to provide an implementation. +template <typename Service, bool expect_connection> class ScopedConnectionCheckerBase { public: explicit ScopedConnectionCheckerBase( @@ -27,7 +25,7 @@ [this](zx::channel channel, async_dispatcher_t*) { pending_channels_.push_back(std::move(channel)); }), - fidl::DiscoverableProtocolName<Protocol>); + std::string(Service::Name_)); ZX_CHECK(status == ZX_OK, status) << "OutgoingDirectory::AddPublicService"; } @@ -45,16 +43,16 @@ private: // Client channels are held in a pending (unconnected) state for the - // lifetime of `this`, so that the client never sees a disconnection event. + // lifetime of |this|, so that the client never sees a disconnection event. std::vector<zx::channel> pending_channels_; }; -// Checks that no client attempted to connect to `Protocol`. -template <typename Protocol> -using NeverConnectedChecker = ScopedConnectionCheckerBase<Protocol, false>; +// Checks that no client attempted to connect to |Service|. +template <typename Service> +using NeverConnectedChecker = ScopedConnectionCheckerBase<Service, false>; -// Checks that at least one client attempted to connect to `Protocol`. -template <typename Protocol> -using EnsureConnectedChecker = ScopedConnectionCheckerBase<Protocol, true>; +// Checks that at least one client attempted to connect to |Service|. +template <typename Service> +using EnsureConnectedChecker = ScopedConnectionCheckerBase<Service, true>; #endif // FUCHSIA_WEB_WEBENGINE_TEST_SCOPED_CONNECTION_CHECKER_H_
diff --git a/gpu/GLES2/gl2chromium_autogen.h b/gpu/GLES2/gl2chromium_autogen.h index fcf5beb4..8b5e858 100644 --- a/gpu/GLES2/gl2chromium_autogen.h +++ b/gpu/GLES2/gl2chromium_autogen.h
@@ -402,6 +402,10 @@ #define glEndPixelLocalStorageANGLE GLES2_GET_FUN(EndPixelLocalStorageANGLE) #define glPixelLocalStorageBarrierANGLE \ GLES2_GET_FUN(PixelLocalStorageBarrierANGLE) +#define glFramebufferPixelLocalStorageInterruptANGLE \ + GLES2_GET_FUN(FramebufferPixelLocalStorageInterruptANGLE) +#define glFramebufferPixelLocalStorageRestoreANGLE \ + GLES2_GET_FUN(FramebufferPixelLocalStorageRestoreANGLE) #define glGetFramebufferPixelLocalStorageParameterfvANGLE \ GLES2_GET_FUN(GetFramebufferPixelLocalStorageParameterfvANGLE) #define glGetFramebufferPixelLocalStorageParameterivANGLE \
diff --git a/gpu/GLES2/gl2extchromium.h b/gpu/GLES2/gl2extchromium.h index 4a5000b0..7d4909c 100644 --- a/gpu/GLES2/gl2extchromium.h +++ b/gpu/GLES2/gl2extchromium.h
@@ -385,6 +385,8 @@ GL_APICALL void GL_APIENTRY glEndPixelLocalStorageANGLE(GLsizei n, const GLenum storeops[]); GL_APICALL void GL_APIENTRY glPixelLocalStorageBarrierANGLE(void); +GL_APICALL void GL_APIENTRY glFramebufferPixelLocalStorageInterruptANGLE(void); +GL_APICALL void GL_APIENTRY glFramebufferPixelLocalStorageRestoreANGLE(void); GL_APICALL void GL_APIENTRY glGetFramebufferPixelLocalStorageParameterfvANGLE(GLint plane, GLenum pname,
diff --git a/gpu/command_buffer/build_gles2_cmd_buffer.py b/gpu/command_buffer/build_gles2_cmd_buffer.py index f533946..5121b34 100755 --- a/gpu/command_buffer/build_gles2_cmd_buffer.py +++ b/gpu/command_buffer/build_gles2_cmd_buffer.py
@@ -4164,6 +4164,20 @@ 'es3': True, 'decoder_func': 'DoPixelLocalStorageBarrierANGLE', }, + 'FramebufferPixelLocalStorageInterruptANGLE': { + 'extension': 'ANGLE_shader_pixel_local_storage', + 'extension_flag': 'angle_shader_pixel_local_storage', + 'unit_test': False, + 'es3': True, + 'decoder_func': 'DoFramebufferPixelLocalStorageInterruptANGLE', + }, + 'FramebufferPixelLocalStorageRestoreANGLE': { + 'extension': 'ANGLE_shader_pixel_local_storage', + 'extension_flag': 'angle_shader_pixel_local_storage', + 'unit_test': False, + 'es3': True, + 'decoder_func': 'DoFramebufferPixelLocalStorageRestoreANGLE', + }, 'GetFramebufferPixelLocalStorageParameterfvANGLE': { 'extension': 'ANGLE_shader_pixel_local_storage', 'extension_flag': 'angle_shader_pixel_local_storage',
diff --git a/gpu/command_buffer/client/gles2_c_lib_autogen.h b/gpu/command_buffer/client/gles2_c_lib_autogen.h index 38b2d92..67d4beb9 100644 --- a/gpu/command_buffer/client/gles2_c_lib_autogen.h +++ b/gpu/command_buffer/client/gles2_c_lib_autogen.h
@@ -1790,6 +1790,12 @@ void GL_APIENTRY GLES2PixelLocalStorageBarrierANGLE() { gles2::GetGLContext()->PixelLocalStorageBarrierANGLE(); } +void GL_APIENTRY GLES2FramebufferPixelLocalStorageInterruptANGLE() { + gles2::GetGLContext()->FramebufferPixelLocalStorageInterruptANGLE(); +} +void GL_APIENTRY GLES2FramebufferPixelLocalStorageRestoreANGLE() { + gles2::GetGLContext()->FramebufferPixelLocalStorageRestoreANGLE(); +} void GL_APIENTRY GLES2GetFramebufferPixelLocalStorageParameterfvANGLE(GLint plane, GLenum pname, @@ -3242,6 +3248,16 @@ reinterpret_cast<GLES2FunctionPointer>(glPixelLocalStorageBarrierANGLE), }, { + "glFramebufferPixelLocalStorageInterruptANGLE", + reinterpret_cast<GLES2FunctionPointer>( + glFramebufferPixelLocalStorageInterruptANGLE), + }, + { + "glFramebufferPixelLocalStorageRestoreANGLE", + reinterpret_cast<GLES2FunctionPointer>( + glFramebufferPixelLocalStorageRestoreANGLE), + }, + { "glGetFramebufferPixelLocalStorageParameterfvANGLE", reinterpret_cast<GLES2FunctionPointer>( glGetFramebufferPixelLocalStorageParameterfvANGLE),
diff --git a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h index 6f7ada2b..67f2d90 100644 --- a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h +++ b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h
@@ -3418,6 +3418,22 @@ } } +void FramebufferPixelLocalStorageInterruptANGLE() { + gles2::cmds::FramebufferPixelLocalStorageInterruptANGLE* c = + GetCmdSpace<gles2::cmds::FramebufferPixelLocalStorageInterruptANGLE>(); + if (c) { + c->Init(); + } +} + +void FramebufferPixelLocalStorageRestoreANGLE() { + gles2::cmds::FramebufferPixelLocalStorageRestoreANGLE* c = + GetCmdSpace<gles2::cmds::FramebufferPixelLocalStorageRestoreANGLE>(); + if (c) { + c->Init(); + } +} + void GetFramebufferPixelLocalStorageParameterfvANGLE( GLint plane, GLenum pname,
diff --git a/gpu/command_buffer/client/gles2_implementation_autogen.h b/gpu/command_buffer/client/gles2_implementation_autogen.h index 3348932..247757d 100644 --- a/gpu/command_buffer/client/gles2_implementation_autogen.h +++ b/gpu/command_buffer/client/gles2_implementation_autogen.h
@@ -1257,6 +1257,10 @@ void PixelLocalStorageBarrierANGLE() override; +void FramebufferPixelLocalStorageInterruptANGLE() override; + +void FramebufferPixelLocalStorageRestoreANGLE() override; + void GetFramebufferPixelLocalStorageParameterfvANGLE(GLint plane, GLenum pname, GLfloat* params) override;
diff --git a/gpu/command_buffer/client/gles2_implementation_impl_autogen.h b/gpu/command_buffer/client/gles2_implementation_impl_autogen.h index 1174f6f..eb3c94a 100644 --- a/gpu/command_buffer/client/gles2_implementation_impl_autogen.h +++ b/gpu/command_buffer/client/gles2_implementation_impl_autogen.h
@@ -3789,6 +3789,24 @@ CheckGLError(); } +void GLES2Implementation::FramebufferPixelLocalStorageInterruptANGLE() { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() + << "] glFramebufferPixelLocalStorageInterruptANGLE(" + << ")"); + helper_->FramebufferPixelLocalStorageInterruptANGLE(); + CheckGLError(); +} + +void GLES2Implementation::FramebufferPixelLocalStorageRestoreANGLE() { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() + << "] glFramebufferPixelLocalStorageRestoreANGLE(" + << ")"); + helper_->FramebufferPixelLocalStorageRestoreANGLE(); + CheckGLError(); +} + void GLES2Implementation::GetFramebufferPixelLocalStorageParameterfvANGLE( GLint plane, GLenum pname,
diff --git a/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h b/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h index 44f9d8c..2ac33f0 100644 --- a/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h +++ b/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h
@@ -3275,6 +3275,28 @@ EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); } +TEST_F(GLES2ImplementationTest, FramebufferPixelLocalStorageInterruptANGLE) { + struct Cmds { + cmds::FramebufferPixelLocalStorageInterruptANGLE cmd; + }; + Cmds expected; + expected.cmd.Init(); + + gl_->FramebufferPixelLocalStorageInterruptANGLE(); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); +} + +TEST_F(GLES2ImplementationTest, FramebufferPixelLocalStorageRestoreANGLE) { + struct Cmds { + cmds::FramebufferPixelLocalStorageRestoreANGLE cmd; + }; + Cmds expected; + expected.cmd.Init(); + + gl_->FramebufferPixelLocalStorageRestoreANGLE(); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); +} + TEST_F(GLES2ImplementationTest, GetFramebufferPixelLocalStorageParameterfvANGLE) { struct Cmds {
diff --git a/gpu/command_buffer/client/gles2_interface_autogen.h b/gpu/command_buffer/client/gles2_interface_autogen.h index c83502f9..3da4dc1c 100644 --- a/gpu/command_buffer/client/gles2_interface_autogen.h +++ b/gpu/command_buffer/client/gles2_interface_autogen.h
@@ -936,6 +936,8 @@ virtual void EndPixelLocalStorageANGLE(GLsizei count, const GLenum* storeops) = 0; virtual void PixelLocalStorageBarrierANGLE() = 0; +virtual void FramebufferPixelLocalStorageInterruptANGLE() = 0; +virtual void FramebufferPixelLocalStorageRestoreANGLE() = 0; virtual void GetFramebufferPixelLocalStorageParameterfvANGLE( GLint plane, GLenum pname,
diff --git a/gpu/command_buffer/client/gles2_interface_stub_autogen.h b/gpu/command_buffer/client/gles2_interface_stub_autogen.h index 989697a2..b53e704 100644 --- a/gpu/command_buffer/client/gles2_interface_stub_autogen.h +++ b/gpu/command_buffer/client/gles2_interface_stub_autogen.h
@@ -906,6 +906,8 @@ void BeginPixelLocalStorageANGLE(GLsizei count, const GLenum* loadops) override; void EndPixelLocalStorageANGLE(GLsizei count, const GLenum* storeops) override; void PixelLocalStorageBarrierANGLE() override; +void FramebufferPixelLocalStorageInterruptANGLE() override; +void FramebufferPixelLocalStorageRestoreANGLE() override; void GetFramebufferPixelLocalStorageParameterfvANGLE(GLint plane, GLenum pname, GLfloat* params) override;
diff --git a/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h b/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h index ef6c109..f033915f 100644 --- a/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h +++ b/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h
@@ -1223,6 +1223,8 @@ GLsizei /* count */, const GLenum* /* storeops */) {} void GLES2InterfaceStub::PixelLocalStorageBarrierANGLE() {} +void GLES2InterfaceStub::FramebufferPixelLocalStorageInterruptANGLE() {} +void GLES2InterfaceStub::FramebufferPixelLocalStorageRestoreANGLE() {} void GLES2InterfaceStub::GetFramebufferPixelLocalStorageParameterfvANGLE( GLint /* plane */, GLenum /* pname */,
diff --git a/gpu/command_buffer/client/gles2_trace_implementation_autogen.h b/gpu/command_buffer/client/gles2_trace_implementation_autogen.h index 3bb8137..db2feec1 100644 --- a/gpu/command_buffer/client/gles2_trace_implementation_autogen.h +++ b/gpu/command_buffer/client/gles2_trace_implementation_autogen.h
@@ -906,6 +906,8 @@ void BeginPixelLocalStorageANGLE(GLsizei count, const GLenum* loadops) override; void EndPixelLocalStorageANGLE(GLsizei count, const GLenum* storeops) override; void PixelLocalStorageBarrierANGLE() override; +void FramebufferPixelLocalStorageInterruptANGLE() override; +void FramebufferPixelLocalStorageRestoreANGLE() override; void GetFramebufferPixelLocalStorageParameterfvANGLE(GLint plane, GLenum pname, GLfloat* params) override;
diff --git a/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h b/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h index 915fe02..0da0851a 100644 --- a/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h +++ b/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h
@@ -2603,6 +2603,18 @@ gl_->PixelLocalStorageBarrierANGLE(); } +void GLES2TraceImplementation::FramebufferPixelLocalStorageInterruptANGLE() { + TRACE_EVENT_BINARY_EFFICIENT0( + "gpu", "GLES2Trace::FramebufferPixelLocalStorageInterruptANGLE"); + gl_->FramebufferPixelLocalStorageInterruptANGLE(); +} + +void GLES2TraceImplementation::FramebufferPixelLocalStorageRestoreANGLE() { + TRACE_EVENT_BINARY_EFFICIENT0( + "gpu", "GLES2Trace::FramebufferPixelLocalStorageRestoreANGLE"); + gl_->FramebufferPixelLocalStorageRestoreANGLE(); +} + void GLES2TraceImplementation::GetFramebufferPixelLocalStorageParameterfvANGLE( GLint plane, GLenum pname,
diff --git a/gpu/command_buffer/common/gles2_cmd_format_autogen.h b/gpu/command_buffer/common/gles2_cmd_format_autogen.h index 80d2fe78..8687b889 100644 --- a/gpu/command_buffer/common/gles2_cmd_format_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_format_autogen.h
@@ -16759,6 +16759,62 @@ static_assert(offsetof(PixelLocalStorageBarrierANGLE, header) == 0, "offset of PixelLocalStorageBarrierANGLE header should be 0"); +struct FramebufferPixelLocalStorageInterruptANGLE { + typedef FramebufferPixelLocalStorageInterruptANGLE ValueType; + static const CommandId kCmdId = kFramebufferPixelLocalStorageInterruptANGLE; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8_t cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init() { SetHeader(); } + + void* Set(void* cmd) { + static_cast<ValueType*>(cmd)->Init(); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; +}; + +static_assert(sizeof(FramebufferPixelLocalStorageInterruptANGLE) == 4, + "size of FramebufferPixelLocalStorageInterruptANGLE should be 4"); +static_assert( + offsetof(FramebufferPixelLocalStorageInterruptANGLE, header) == 0, + "offset of FramebufferPixelLocalStorageInterruptANGLE header should be 0"); + +struct FramebufferPixelLocalStorageRestoreANGLE { + typedef FramebufferPixelLocalStorageRestoreANGLE ValueType; + static const CommandId kCmdId = kFramebufferPixelLocalStorageRestoreANGLE; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8_t cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init() { SetHeader(); } + + void* Set(void* cmd) { + static_cast<ValueType*>(cmd)->Init(); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; +}; + +static_assert(sizeof(FramebufferPixelLocalStorageRestoreANGLE) == 4, + "size of FramebufferPixelLocalStorageRestoreANGLE should be 4"); +static_assert( + offsetof(FramebufferPixelLocalStorageRestoreANGLE, header) == 0, + "offset of FramebufferPixelLocalStorageRestoreANGLE header should be 0"); + struct GetFramebufferPixelLocalStorageParameterfvANGLE { typedef GetFramebufferPixelLocalStorageParameterfvANGLE ValueType; static const CommandId kCmdId =
diff --git a/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h b/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h index fb773ca..1eccc4f 100644 --- a/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h
@@ -5835,6 +5835,28 @@ CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); } +TEST_F(GLES2FormatTest, FramebufferPixelLocalStorageInterruptANGLE) { + cmds::FramebufferPixelLocalStorageInterruptANGLE& cmd = + *GetBufferAs<cmds::FramebufferPixelLocalStorageInterruptANGLE>(); + void* next_cmd = cmd.Set(&cmd); + EXPECT_EQ(static_cast<uint32_t>( + cmds::FramebufferPixelLocalStorageInterruptANGLE::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + +TEST_F(GLES2FormatTest, FramebufferPixelLocalStorageRestoreANGLE) { + cmds::FramebufferPixelLocalStorageRestoreANGLE& cmd = + *GetBufferAs<cmds::FramebufferPixelLocalStorageRestoreANGLE>(); + void* next_cmd = cmd.Set(&cmd); + EXPECT_EQ(static_cast<uint32_t>( + cmds::FramebufferPixelLocalStorageRestoreANGLE::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + TEST_F(GLES2FormatTest, GetFramebufferPixelLocalStorageParameterfvANGLE) { cmds::GetFramebufferPixelLocalStorageParameterfvANGLE& cmd = *GetBufferAs<cmds::GetFramebufferPixelLocalStorageParameterfvANGLE>();
diff --git a/gpu/command_buffer/common/gles2_cmd_ids_autogen.h b/gpu/command_buffer/common/gles2_cmd_ids_autogen.h index f20fe79..d14a63a 100644 --- a/gpu/command_buffer/common/gles2_cmd_ids_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_ids_autogen.h
@@ -349,8 +349,10 @@ OP(BeginPixelLocalStorageANGLEImmediate) /* 590 */ \ OP(EndPixelLocalStorageANGLEImmediate) /* 591 */ \ OP(PixelLocalStorageBarrierANGLE) /* 592 */ \ - OP(GetFramebufferPixelLocalStorageParameterfvANGLE) /* 593 */ \ - OP(GetFramebufferPixelLocalStorageParameterivANGLE) /* 594 */ + OP(FramebufferPixelLocalStorageInterruptANGLE) /* 593 */ \ + OP(FramebufferPixelLocalStorageRestoreANGLE) /* 594 */ \ + OP(GetFramebufferPixelLocalStorageParameterfvANGLE) /* 595 */ \ + OP(GetFramebufferPixelLocalStorageParameterivANGLE) /* 596 */ enum CommandId { kOneBeforeStartPoint =
diff --git a/gpu/command_buffer/gles2_cmd_buffer_functions.txt b/gpu/command_buffer/gles2_cmd_buffer_functions.txt index e960fba..97280f8 100644 --- a/gpu/command_buffer/gles2_cmd_buffer_functions.txt +++ b/gpu/command_buffer/gles2_cmd_buffer_functions.txt
@@ -406,5 +406,7 @@ GL_APICALL void GL_APIENTRY glBeginPixelLocalStorageANGLE (GLsizei count, const GLenum* loadops); GL_APICALL void GL_APIENTRY glEndPixelLocalStorageANGLE (GLsizei count, const GLenum* storeops); GL_APICALL void GL_APIENTRY glPixelLocalStorageBarrierANGLE (void); +GL_APICALL void GL_APIENTRY glFramebufferPixelLocalStorageInterruptANGLE (void); +GL_APICALL void GL_APIENTRY glFramebufferPixelLocalStorageRestoreANGLE (void); GL_APICALL void GL_APIENTRY glGetFramebufferPixelLocalStorageParameterfvANGLE (GLint plane, GLenum pname, GLfloat* params); GL_APICALL void GL_APIENTRY glGetFramebufferPixelLocalStorageParameterivANGLE (GLint plane, GLenum pname, GLint* params);
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc index fb425a2..bec9086 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -1313,6 +1313,8 @@ void DoBeginPixelLocalStorageANGLE(GLsizei n, const volatile GLenum* loadops); void DoEndPixelLocalStorageANGLE(GLsizei n, const volatile GLenum* storeops); void DoPixelLocalStorageBarrierANGLE(); + void DoFramebufferPixelLocalStorageInterruptANGLE(); + void DoFramebufferPixelLocalStorageRestoreANGLE(); void DoGetFramebufferPixelLocalStorageParameterfvANGLE(GLint plane, GLenum pname, GLfloat* params, @@ -19334,6 +19336,14 @@ NOTIMPLEMENTED(); } +void GLES2DecoderImpl::DoFramebufferPixelLocalStorageInterruptANGLE() { + NOTIMPLEMENTED(); +} + +void GLES2DecoderImpl::DoFramebufferPixelLocalStorageRestoreANGLE() { + NOTIMPLEMENTED(); +} + void GLES2DecoderImpl::DoGetFramebufferPixelLocalStorageParameterfvANGLE( GLint plane, GLenum pname,
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h index a733ac0..6fed48e 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h
@@ -5803,6 +5803,32 @@ return error::kNoError; } +error::Error GLES2DecoderImpl::HandleFramebufferPixelLocalStorageInterruptANGLE( + uint32_t immediate_data_size, + const volatile void* cmd_data) { + if (!feature_info_->IsWebGL2OrES3OrHigherContext()) + return error::kUnknownCommand; + if (!features().angle_shader_pixel_local_storage) { + return error::kUnknownCommand; + } + + DoFramebufferPixelLocalStorageInterruptANGLE(); + return error::kNoError; +} + +error::Error GLES2DecoderImpl::HandleFramebufferPixelLocalStorageRestoreANGLE( + uint32_t immediate_data_size, + const volatile void* cmd_data) { + if (!feature_info_->IsWebGL2OrES3OrHigherContext()) + return error::kUnknownCommand; + if (!features().angle_shader_pixel_local_storage) { + return error::kUnknownCommand; + } + + DoFramebufferPixelLocalStorageRestoreANGLE(); + return error::kNoError; +} + error::Error GLES2DecoderImpl::HandleGetFramebufferPixelLocalStorageParameterfvANGLE( uint32_t immediate_data_size,
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc index c48b0e2..3956ad8 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc
@@ -216,8 +216,8 @@ GLsizei samples, GLenum internal_format) { gl::GLApi* api = impl->api(); - GLES2DecoderPassthroughImpl::ScopedPixelLocalStorageDeactivate - scoped_pls_deactivate(impl); + GLES2DecoderPassthroughImpl::ScopedPixelLocalStorageInterrupt + scoped_pls_interrupt(impl); ScopedRenderbufferBindingReset scoped_renderbuffer_reset(api); api->glBindRenderbufferEXTFn(GL_RENDERBUFFER, renderbuffer); @@ -313,38 +313,19 @@ } // anonymous namespace -void GLES2DecoderPassthroughImpl::ScopedPixelLocalStorageDeactivate:: - StashIfNeeded(gl::GLApi* api, GLint active_plane_count) { - if (active_plane_count != 0) { - DCHECK_LE(active_plane_count, kPassthroughMaxPLSPlanes); - active_plane_count = std::min(active_plane_count, kPassthroughMaxPLSPlanes); - GLenum storeops[kPassthroughMaxPLSPlanes]; - std::fill(storeops, storeops + active_plane_count, GL_STORE_OP_STORE_ANGLE); - api->glEndPixelLocalStorageANGLEFn(active_plane_count, storeops); - } -} - -void GLES2DecoderPassthroughImpl::ScopedPixelLocalStorageDeactivate:: - RestoreIfNeeded(gl::GLApi* api, int stashed_plane_count) { - if (stashed_plane_count != 0) { - DCHECK_LE(stashed_plane_count, kPassthroughMaxPLSPlanes); - stashed_plane_count = - std::min(stashed_plane_count, kPassthroughMaxPLSPlanes); - GLenum loadops[kPassthroughMaxPLSPlanes]; - std::fill(loadops, loadops + stashed_plane_count, GL_LOAD_OP_LOAD_ANGLE); - api->glBeginPixelLocalStorageANGLEFn(stashed_plane_count, loadops); - } -} - -GLES2DecoderPassthroughImpl::ScopedPixelLocalStorageDeactivate:: - ScopedPixelLocalStorageDeactivate(const GLES2DecoderPassthroughImpl* impl) +GLES2DecoderPassthroughImpl::ScopedPixelLocalStorageInterrupt:: + ScopedPixelLocalStorageInterrupt(const GLES2DecoderPassthroughImpl* impl) : impl_(impl) { - StashIfNeeded(impl_->api(), impl_->active_pls_plane_count_); + if (impl_->has_activated_pixel_local_storage_) { + impl_->api()->glFramebufferPixelLocalStorageInterruptANGLEFn(); + } } -GLES2DecoderPassthroughImpl::ScopedPixelLocalStorageDeactivate:: - ~ScopedPixelLocalStorageDeactivate() { - RestoreIfNeeded(impl_->api(), impl_->active_pls_plane_count_); +GLES2DecoderPassthroughImpl::ScopedPixelLocalStorageInterrupt:: + ~ScopedPixelLocalStorageInterrupt() { + if (impl_->has_activated_pixel_local_storage_) { + impl_->api()->glFramebufferPixelLocalStorageRestoreANGLEFn(); + } } GLES2DecoderPassthroughImpl::TexturePendingBinding::TexturePendingBinding( @@ -517,8 +498,8 @@ // Back up all state we are about to change. gl::GLApi* api = impl->api(); - GLES2DecoderPassthroughImpl::ScopedPixelLocalStorageDeactivate - scoped_pls_deactivate(impl); + GLES2DecoderPassthroughImpl::ScopedPixelLocalStorageInterrupt + scoped_pls_interrupt(impl); ScopedFramebufferBindingReset fbo_reset( api, false /* supports_seperate_fbo_bindings */); ScopedTextureBindingReset texture_reset(api, texture->target()); @@ -647,7 +628,7 @@ GLES2DecoderPassthroughImpl::EmulatedColorBuffer::EmulatedColorBuffer( const GLES2DecoderPassthroughImpl* impl) : impl_(impl) { - ScopedPixelLocalStorageDeactivate scoped_pls_deactivate(impl_); + ScopedPixelLocalStorageInterrupt scoped_pls_interrupt(impl_); ScopedTextureBindingReset scoped_texture_reset(api(), GL_TEXTURE_2D); GLuint color_buffer_texture = 0; @@ -670,7 +651,7 @@ } size = new_size; - ScopedPixelLocalStorageDeactivate scoped_pls_deactivate(impl_); + ScopedPixelLocalStorageInterrupt scoped_pls_interrupt(impl_); ScopedTextureBindingReset scoped_texture_reset(api(), GL_TEXTURE_2D); DCHECK(texture); @@ -697,7 +678,7 @@ GLES2DecoderPassthroughImpl::EmulatedDefaultFramebuffer:: EmulatedDefaultFramebuffer(const GLES2DecoderPassthroughImpl* impl) : impl_(impl) { - ScopedPixelLocalStorageDeactivate scoped_pls_deactivate(impl_); + ScopedPixelLocalStorageInterrupt scoped_pls_interrupt(impl_); ScopedFramebufferBindingReset scoped_fbo_reset( api(), impl_->supports_separate_fbo_bindings_); ScopedRenderbufferBindingReset scoped_renderbuffer_reset(api()); @@ -772,7 +753,7 @@ color_texture = std::move(new_color_buffer); // Bind the new texture to this FBO - ScopedPixelLocalStorageDeactivate scoped_pls_deactivate(impl_); + ScopedPixelLocalStorageInterrupt scoped_pls_interrupt(impl_); ScopedFramebufferBindingReset scoped_fbo_reset( api(), impl_->supports_separate_fbo_bindings_); api()->glBindFramebufferEXTFn(GL_FRAMEBUFFER, framebuffer_service_id); @@ -788,7 +769,7 @@ DCHECK(target != nullptr); DCHECK_EQ(target->size, size); - ScopedPixelLocalStorageDeactivate scoped_pls_deactivate(impl_); + ScopedPixelLocalStorageInterrupt scoped_pls_interrupt(impl_); ScopedFramebufferBindingReset scoped_fbo_reset( api(), impl_->supports_separate_fbo_bindings_); @@ -840,7 +821,7 @@ // Check that the framebuffer is complete { - ScopedPixelLocalStorageDeactivate scoped_pls_deactivate(impl_); + ScopedPixelLocalStorageInterrupt scoped_pls_interrupt(impl_); ScopedFramebufferBindingReset scoped_fbo_reset( api(), impl_->supports_separate_fbo_bindings_); api()->glBindFramebufferEXTFn(GL_FRAMEBUFFER, framebuffer_service_id); @@ -2158,13 +2139,15 @@ it->second.command_processing_start_time = base::TimeTicks::Now(); } - ScopedPixelLocalStorageDeactivate::RestoreIfNeeded(api(), - active_pls_plane_count_); + if (has_activated_pixel_local_storage_) { + api()->glFramebufferPixelLocalStorageRestoreANGLEFn(); + } } void GLES2DecoderPassthroughImpl::EndDecoding() { - ScopedPixelLocalStorageDeactivate::StashIfNeeded(api(), - active_pls_plane_count_); + if (has_activated_pixel_local_storage_) { + api()->glFramebufferPixelLocalStorageInterruptANGLEFn(); + } #if BUILDFLAG(IS_WIN) resources_->SuspendSharedImageAccessIfNeeded(); @@ -2620,7 +2603,7 @@ GLES2DecoderPassthroughImpl::LazySharedContextState::~LazySharedContextState() { if (shared_context_state_) { - ScopedPixelLocalStorageDeactivate scoped_pls_deactivate(impl_); + ScopedPixelLocalStorageInterrupt scoped_pls_interrupt(impl_); ui::ScopedMakeCurrent smc(shared_context_state_->context(), shared_context_state_->surface()); shared_context_state_.reset(); @@ -2659,7 +2642,7 @@ } // Make current context using `gl_context` and `gl_surface` - ScopedPixelLocalStorageDeactivate scoped_pls_deactivate(impl_); + ScopedPixelLocalStorageInterrupt scoped_pls_interrupt(impl_); ui::ScopedMakeCurrent smc(gl_context.get(), gl_surface.get()); ContextGroup* group = impl_->GetContextGroup();
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.h b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.h index 7d650a8..4cb95db 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.h
@@ -428,13 +428,10 @@ return feature_info_->feature_flags(); } - class ScopedPixelLocalStorageDeactivate { + class ScopedPixelLocalStorageInterrupt { public: - static void StashIfNeeded(gl::GLApi*, GLint active_plane_count); - static void RestoreIfNeeded(gl::GLApi* api, GLint stashed_plane_count); - - ScopedPixelLocalStorageDeactivate(const GLES2DecoderPassthroughImpl*); - ~ScopedPixelLocalStorageDeactivate(); + ScopedPixelLocalStorageInterrupt(const GLES2DecoderPassthroughImpl*); + ~ScopedPixelLocalStorageInterrupt(); private: raw_ptr<const GLES2DecoderPassthroughImpl> impl_; @@ -965,9 +962,9 @@ // If this context supports both read and draw framebuffer bindings bool supports_separate_fbo_bindings_ = false; - // Tracks the number of ANGLE_shader_pixel_local_storage planes to turn off - // and back on in the event that a rendering pass gets interrupted. - GLint active_pls_plane_count_ = 0; + // Tracks if the context has ever called glBeginPixelLocalStorageANGLE. If it + // has, we need to start using the pixel local storage interrupt mechanism. + bool has_activated_pixel_local_storage_ = false; // Tracing std::unique_ptr<GPUTracer> gpu_tracer_;
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doer_prototypes.h b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doer_prototypes.h index 0a66fc2f..34ab38bf 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doer_prototypes.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doer_prototypes.h
@@ -1108,6 +1108,8 @@ error::Error DoEndPixelLocalStorageANGLE(GLsizei n, const volatile GLenum* storeops); error::Error DoPixelLocalStorageBarrierANGLE(); +error::Error DoFramebufferPixelLocalStorageInterruptANGLE(); +error::Error DoFramebufferPixelLocalStorageRestoreANGLE(); error::Error DoGetFramebufferPixelLocalStorageParameterfvANGLE(GLint plane, GLenum pname, GLsizei bufsize,
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc index c23cd37..eb222f2 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc
@@ -2512,7 +2512,7 @@ return error::kNoError; } } - ScopedPixelLocalStorageDeactivate scoped_pls_deactivate(this); + ScopedPixelLocalStorageInterrupt scoped_pls_interrupt(this); ui::ScopedMakeCurrent smc(lazy_context_->shared_context_state()->context(), lazy_context_->shared_context_state()->surface()); @@ -5119,7 +5119,7 @@ return error::kNoError; } } - ScopedPixelLocalStorageDeactivate scoped_pls_deactivate(this); + ScopedPixelLocalStorageInterrupt scoped_pls_interrupt(this); ui::ScopedMakeCurrent smc(lazy_context_->shared_context_state()->context(), lazy_context_->shared_context_state()->surface()); CopySharedImageHelper helper(group_->shared_image_representation_factory(), @@ -5143,7 +5143,7 @@ return error::kNoError; } } - ScopedPixelLocalStorageDeactivate scoped_pls_deactivate(this); + ScopedPixelLocalStorageInterrupt scoped_pls_interrupt(this); ui::ScopedMakeCurrent smc(lazy_context_->shared_context_state()->context(), lazy_context_->shared_context_state()->surface()); CopySharedImageHelper helper(group_->shared_image_representation_factory(), @@ -5171,7 +5171,7 @@ return error::kNoError; } } - ScopedPixelLocalStorageDeactivate scoped_pls_deactivate(this); + ScopedPixelLocalStorageInterrupt scoped_pls_interrupt(this); ui::ScopedMakeCurrent smc(lazy_context_->shared_context_state()->context(), lazy_context_->shared_context_state()->surface()); CopySharedImageHelper helper(group_->shared_image_representation_factory(), @@ -5201,7 +5201,7 @@ return error::kNoError; } } - ScopedPixelLocalStorageDeactivate scoped_pls_deactivate(this); + ScopedPixelLocalStorageInterrupt scoped_pls_interrupt(this); ui::ScopedMakeCurrent smc(lazy_context_->shared_context_state()->context(), lazy_context_->shared_context_state()->surface()); @@ -5333,10 +5333,7 @@ GLenum loadops_copy[kPassthroughMaxPLSPlanes]; std::copy(loadops, loadops + n, loadops_copy); api()->glBeginPixelLocalStorageANGLEFn(n, loadops_copy); - // Query GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE in case there was an error - // and the number of active planes isn't actually <n>. - api()->glGetIntegervFn(GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE, - &active_pls_plane_count_); + has_activated_pixel_local_storage_ = true; return error::kNoError; } @@ -5360,10 +5357,6 @@ GLenum storeops_copy[kPassthroughMaxPLSPlanes]; std::copy(storeops, storeops + n, storeops_copy); api()->glEndPixelLocalStorageANGLEFn(n, storeops_copy); - // Query GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE in case there was an error - // and the number of active planes isn't actually zero. - api()->glGetIntegervFn(GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE, - &active_pls_plane_count_); return error::kNoError; } @@ -5377,6 +5370,24 @@ } error::Error +GLES2DecoderPassthroughImpl::DoFramebufferPixelLocalStorageInterruptANGLE() { + if (IsEmulatedFramebufferBound(GL_DRAW_FRAMEBUFFER)) { + return error::kNoError; + } + api()->glFramebufferPixelLocalStorageInterruptANGLEFn(); + return error::kNoError; +} + +error::Error +GLES2DecoderPassthroughImpl::DoFramebufferPixelLocalStorageRestoreANGLE() { + if (IsEmulatedFramebufferBound(GL_DRAW_FRAMEBUFFER)) { + return error::kNoError; + } + api()->glFramebufferPixelLocalStorageRestoreANGLEFn(); + return error::kNoError; +} + +error::Error GLES2DecoderPassthroughImpl::DoGetFramebufferPixelLocalStorageParameterfvANGLE( GLint plane, GLenum pname,
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_handlers_autogen.cc b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_handlers_autogen.cc index 3fd480e..58607a2 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_handlers_autogen.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_handlers_autogen.cc
@@ -5130,6 +5130,40 @@ return error::kNoError; } +error::Error +GLES2DecoderPassthroughImpl::HandleFramebufferPixelLocalStorageInterruptANGLE( + uint32_t immediate_data_size, + const volatile void* cmd_data) { + if (!feature_info_->IsWebGL2OrES3OrHigherContext()) + return error::kUnknownCommand; + if (!features().angle_shader_pixel_local_storage) { + return error::kUnknownCommand; + } + + error::Error error = DoFramebufferPixelLocalStorageInterruptANGLE(); + if (error != error::kNoError) { + return error; + } + return error::kNoError; +} + +error::Error +GLES2DecoderPassthroughImpl::HandleFramebufferPixelLocalStorageRestoreANGLE( + uint32_t immediate_data_size, + const volatile void* cmd_data) { + if (!feature_info_->IsWebGL2OrES3OrHigherContext()) + return error::kUnknownCommand; + if (!features().angle_shader_pixel_local_storage) { + return error::kUnknownCommand; + } + + error::Error error = DoFramebufferPixelLocalStorageRestoreANGLE(); + if (error != error::kNoError) { + return error; + } + return error::kNoError; +} + error::Error GLES2DecoderPassthroughImpl:: HandleGetFramebufferPixelLocalStorageParameterfvANGLE( uint32_t immediate_data_size,
diff --git "a/infra/config/generated/builders/ci/Mac Builder \050dbg\051/properties.json" "b/infra/config/generated/builders/ci/Mac Builder \050dbg\051/properties.json" index b5a00e6..6616f414 100644 --- "a/infra/config/generated/builders/ci/Mac Builder \050dbg\051/properties.json" +++ "b/infra/config/generated/builders/ci/Mac Builder \050dbg\051/properties.json"
@@ -55,36 +55,6 @@ "project": "chromium" } } - }, - { - "builder_id": { - "bucket": "ci", - "builder": "mac-osxbeta-rel", - "project": "chromium" - }, - "builder_spec": { - "build_gs_bucket": "chromium-fyi-archive", - "builder_group": "chromium.fyi", - "execution_mode": "TEST", - "legacy_chromium_config": { - "apply_configs": [ - "mb", - "goma_use_local" - ], - "build_config": "Release", - "config": "chromium", - "target_bits": 64, - "target_platform": "mac" - }, - "legacy_gclient_config": { - "config": "chromium" - }, - "parent": { - "bucket": "ci", - "builder": "Mac Builder (dbg)", - "project": "chromium" - } - } } ] }, @@ -100,19 +70,10 @@ "bucket": "ci", "builder": "Mac12 Tests (dbg)", "project": "chromium" - }, - { - "bucket": "ci", - "builder": "mac-osxbeta-rel", - "project": "chromium" } ], "mirroring_builder_group_and_names": [ { - "builder": "mac-osxbeta-rel", - "group": "tryserver.chromium.mac" - }, - { "builder": "mac_chromium_compile_dbg_ng", "group": "tryserver.chromium.mac" },
diff --git a/infra/config/generated/builders/ci/mac-osxbeta-rel/properties.json b/infra/config/generated/builders/ci/mac-osxbeta-rel/properties.json index ce7b923..d5a3d73 100644 --- a/infra/config/generated/builders/ci/mac-osxbeta-rel/properties.json +++ b/infra/config/generated/builders/ci/mac-osxbeta-rel/properties.json
@@ -6,37 +6,13 @@ { "builder_id": { "bucket": "ci", - "builder": "Mac Builder (dbg)", - "project": "chromium" - }, - "builder_spec": { - "build_gs_bucket": "chromium-mac-archive", - "builder_group": "chromium.mac", - "execution_mode": "COMPILE_AND_TEST", - "legacy_chromium_config": { - "apply_configs": [ - "mb" - ], - "build_config": "Debug", - "config": "chromium", - "target_bits": 64, - "target_platform": "mac" - }, - "legacy_gclient_config": { - "config": "chromium" - } - } - }, - { - "builder_id": { - "bucket": "ci", "builder": "mac-osxbeta-rel", "project": "chromium" }, "builder_spec": { "build_gs_bucket": "chromium-fyi-archive", "builder_group": "chromium.fyi", - "execution_mode": "TEST", + "execution_mode": "COMPILE_AND_TEST", "legacy_chromium_config": { "apply_configs": [ "mb", @@ -49,11 +25,6 @@ }, "legacy_gclient_config": { "config": "chromium" - }, - "parent": { - "bucket": "ci", - "builder": "Mac Builder (dbg)", - "project": "chromium" } } } @@ -70,14 +41,16 @@ { "builder": "mac-osxbeta-rel", "group": "tryserver.chromium.mac" - }, - { - "builder": "mac_chromium_compile_dbg_ng", - "group": "tryserver.chromium.mac" } ] } }, + "$build/reclient": { + "instance": "rbe-chromium-trusted", + "jobs": 250, + "metrics_project": "chromium-reclient-metrics", + "scandeps_server": true + }, "$recipe_engine/resultdb/test_presentation": { "column_keys": [], "grouping_keys": [
diff --git a/infra/config/generated/builders/try/mac-osxbeta-rel/properties.json b/infra/config/generated/builders/try/mac-osxbeta-rel/properties.json index 8b1fed9..c70ba3a 100644 --- a/infra/config/generated/builders/try/mac-osxbeta-rel/properties.json +++ b/infra/config/generated/builders/try/mac-osxbeta-rel/properties.json
@@ -6,37 +6,13 @@ { "builder_id": { "bucket": "ci", - "builder": "Mac Builder (dbg)", - "project": "chromium" - }, - "builder_spec": { - "build_gs_bucket": "chromium-mac-archive", - "builder_group": "chromium.mac", - "execution_mode": "COMPILE_AND_TEST", - "legacy_chromium_config": { - "apply_configs": [ - "mb" - ], - "build_config": "Debug", - "config": "chromium", - "target_bits": 64, - "target_platform": "mac" - }, - "legacy_gclient_config": { - "config": "chromium" - } - } - }, - { - "builder_id": { - "bucket": "ci", "builder": "mac-osxbeta-rel", "project": "chromium" }, "builder_spec": { "build_gs_bucket": "chromium-fyi-archive", "builder_group": "chromium.fyi", - "execution_mode": "TEST", + "execution_mode": "COMPILE_AND_TEST", "legacy_chromium_config": { "apply_configs": [ "mb", @@ -49,11 +25,6 @@ }, "legacy_gclient_config": { "config": "chromium" - }, - "parent": { - "bucket": "ci", - "builder": "Mac Builder (dbg)", - "project": "chromium" } } } @@ -62,13 +33,6 @@ "builder_ids": [ { "bucket": "ci", - "builder": "Mac Builder (dbg)", - "project": "chromium" - } - ], - "builder_ids_in_scope_for_testing": [ - { - "bucket": "ci", "builder": "mac-osxbeta-rel", "project": "chromium" }
diff --git a/infra/config/generated/builders/try/mac_chromium_compile_dbg_ng/properties.json b/infra/config/generated/builders/try/mac_chromium_compile_dbg_ng/properties.json index d92dc124..2852506 100644 --- a/infra/config/generated/builders/try/mac_chromium_compile_dbg_ng/properties.json +++ b/infra/config/generated/builders/try/mac_chromium_compile_dbg_ng/properties.json
@@ -55,36 +55,6 @@ "project": "chromium" } } - }, - { - "builder_id": { - "bucket": "ci", - "builder": "mac-osxbeta-rel", - "project": "chromium" - }, - "builder_spec": { - "build_gs_bucket": "chromium-fyi-archive", - "builder_group": "chromium.fyi", - "execution_mode": "TEST", - "legacy_chromium_config": { - "apply_configs": [ - "mb", - "goma_use_local" - ], - "build_config": "Release", - "config": "chromium", - "target_bits": 64, - "target_platform": "mac" - }, - "legacy_gclient_config": { - "config": "chromium" - }, - "parent": { - "bucket": "ci", - "builder": "Mac Builder (dbg)", - "project": "chromium" - } - } } ] }, @@ -100,11 +70,6 @@ "bucket": "ci", "builder": "Mac12 Tests (dbg)", "project": "chromium" - }, - { - "bucket": "ci", - "builder": "mac-osxbeta-rel", - "project": "chromium" } ], "is_compile_only": true
diff --git a/infra/config/generated/luci/luci-scheduler.cfg b/infra/config/generated/luci/luci-scheduler.cfg index ed1682f..8ad4ca82 100644 --- a/infra/config/generated/luci/luci-scheduler.cfg +++ b/infra/config/generated/luci/luci-scheduler.cfg
@@ -6558,6 +6558,7 @@ triggers: "mac-backuprefptr-x64-fyi-rel" triggers: "mac-hermetic-upgrade-rel" triggers: "mac-official" + triggers: "mac-osxbeta-rel" triggers: "mac-rel-cft" triggers: "mac-rust-x64-rel" triggers: "mac-swangle-chromium-x64"
diff --git a/infra/config/generated/luci/realms.cfg b/infra/config/generated/luci/realms.cfg index 6f2ae2e..c6d146d 100644 --- a/infra/config/generated/luci/realms.cfg +++ b/infra/config/generated/luci/realms.cfg
@@ -164,7 +164,6 @@ values: "linux-updater-tester-dbg" values: "linux-updater-tester-rel" values: "mac-fieldtrial-tester" - values: "mac-osxbeta-rel" values: "mac10.13-updater-tester-dbg" values: "mac10.13-updater-tester-rel" values: "mac10.14-updater-tester-dbg"
diff --git a/infra/config/subprojects/chromium/ci/chromium.fyi.star b/infra/config/subprojects/chromium/ci/chromium.fyi.star index 96370e9c..1c6e550 100644 --- a/infra/config/subprojects/chromium/ci/chromium.fyi.star +++ b/infra/config/subprojects/chromium/ci/chromium.fyi.star
@@ -904,13 +904,9 @@ ), ) -# This is launching & collecting entirely isolated tests. -# OS shouldn't matter. -ci.thin_tester( +ci.builder( name = "mac-osxbeta-rel", - triggered_by = ["ci/Mac Builder (dbg)"], builder_spec = builder_config.builder_spec( - execution_mode = builder_config.execution_mode.TEST, gclient_config = builder_config.gclient_config( config = "chromium", ),
diff --git a/infra/config/subprojects/chromium/try/tryserver.chromium.mac.star b/infra/config/subprojects/chromium/try/tryserver.chromium.mac.star index ad4d30d..a136ba3 100644 --- a/infra/config/subprojects/chromium/try/tryserver.chromium.mac.star +++ b/infra/config/subprojects/chromium/try/tryserver.chromium.mac.star
@@ -52,7 +52,6 @@ try_.builder( name = "mac-osxbeta-rel", mirrors = [ - "ci/Mac Builder (dbg)", "ci/mac-osxbeta-rel", ], builderless = False,
diff --git a/ios/chrome/app/strings/ios_strings.grd b/ios/chrome/app/strings/ios_strings.grd index 7051d0f4..933fdf5b 100644 --- a/ios/chrome/app/strings/ios_strings.grd +++ b/ios/chrome/app/strings/ios_strings.grd
@@ -2859,6 +2859,15 @@ <message name="IDS_IOS_WEAK_PASSWORD_ISSUES_DESCRIPTION" desc="Header displayed on the password manager screen displaying credentials weak passwords [iOS only]" meaning="This header explains the risks of having weak passwords and provides a link to the support page explaining how create strong passwords."> Weak passwords are easy to guess. Make sure you’re creating strong passwords. <ph name="BEGIN_LINK">BEGIN_LINK</ph>See more security tips.<ph name="END_LINK">END_LINK</ph> </message> + <message name="IDS_IOS_REUSED_PASSWORD_ISSUES_GROUP_HEADER" desc="Header shown on top of a group of credentials sharing the same password, inside the password manager screen diplaying shared passswords. User can only have 2 or more reused passwords, so this string will always be plural. [iOS only]"> + <ph name="COUNT">$1<ex>2</ex></ph> accounts using same password + </message> + <message name="IDS_IOS_COMPROMISED_PASSWORD_ISSUES_LEAKED_DESCRIPTION" desc="Text explaining the user one of their credentials was found in a data breach. Displayed on the password manager screen showing credentials that have been leaked or phished. [iOS only]"> + Found in data breach + </message> + <message name="IDS_IOS_COMPROMISED_PASSWORD_ISSUES_PHISHED_DESCRIPTION" desc="Text explaining the user one of their credentials was phished. Displayed on the password manager screen showing credentials that have been leaked or phished. [iOS only]"> + Entered on deceptive site + </message> <message name="IDS_IOS_CHANGE_COMPROMISED_PASSWORD" desc="Button which is shown on Password Details Screen when password is compromised. [iOS only]" meaning="Telling user to change password on a website since it is compromised."> Change Password on Website </message>
diff --git a/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_COMPROMISED_PASSWORD_ISSUES_LEAKED_DESCRIPTION.png.sha1 b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_COMPROMISED_PASSWORD_ISSUES_LEAKED_DESCRIPTION.png.sha1 new file mode 100644 index 0000000..aca04c9b --- /dev/null +++ b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_COMPROMISED_PASSWORD_ISSUES_LEAKED_DESCRIPTION.png.sha1
@@ -0,0 +1 @@ +a7886b664e8d19953a5e9eded9478191b379f707 \ No newline at end of file
diff --git a/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_COMPROMISED_PASSWORD_ISSUES_PHISHED_DESCRIPTION.png.sha1 b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_COMPROMISED_PASSWORD_ISSUES_PHISHED_DESCRIPTION.png.sha1 new file mode 100644 index 0000000..aca04c9b --- /dev/null +++ b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_COMPROMISED_PASSWORD_ISSUES_PHISHED_DESCRIPTION.png.sha1
@@ -0,0 +1 @@ +a7886b664e8d19953a5e9eded9478191b379f707 \ No newline at end of file
diff --git a/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_REUSED_PASSWORD_ISSUES_GROUP_HEADER.png.sha1 b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_REUSED_PASSWORD_ISSUES_GROUP_HEADER.png.sha1 new file mode 100644 index 0000000..690d98f --- /dev/null +++ b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_REUSED_PASSWORD_ISSUES_GROUP_HEADER.png.sha1
@@ -0,0 +1 @@ +54265578927d0cec01086e41bc9d2889ddb2c968 \ No newline at end of file
diff --git a/ios/chrome/browser/autocomplete/omnibox_pedal_implementation.mm b/ios/chrome/browser/autocomplete/omnibox_pedal_implementation.mm index 5cdeb33a..878bdc2 100644 --- a/ios/chrome/browser/autocomplete/omnibox_pedal_implementation.mm +++ b/ios/chrome/browser/autocomplete/omnibox_pedal_implementation.mm
@@ -72,7 +72,8 @@ // This method override enables this Pedal to spoof its ID for metrics // reporting, making it possible to distinguish incognito usage. OmniboxPedalId GetMetricsId() const override { - return incognito_ ? OmniboxPedalId::INCOGNITO_CLEAR_BROWSING_DATA : id(); + return incognito_ ? OmniboxPedalId::INCOGNITO_CLEAR_BROWSING_DATA + : PedalId(); } protected: @@ -465,7 +466,8 @@ GetPedalImplementations(bool incognito, bool testing) { std::unordered_map<OmniboxPedalId, scoped_refptr<OmniboxPedal>> pedals; __unused const auto add = [&](OmniboxPedal* pedal) { - pedals.insert(std::make_pair(pedal->id(), base::WrapRefCounted(pedal))); + pedals.insert( + std::make_pair(pedal->PedalId(), base::WrapRefCounted(pedal))); }; if (!incognito) {
diff --git a/ios/chrome/browser/ui/omnibox/popup/omnibox_pedal_annotator.mm b/ios/chrome/browser/ui/omnibox/popup/omnibox_pedal_annotator.mm index 6883072d..49b8f309 100644 --- a/ios/chrome/browser/ui/omnibox/popup/omnibox_pedal_annotator.mm +++ b/ios/chrome/browser/ui/omnibox/popup/omnibox_pedal_annotator.mm
@@ -44,26 +44,22 @@ // predicate or iterating through `match.actions`. In that case, // the static_casts below should also be removed in favor of generic // use of the OmniboxAction base class. - const OmniboxAction* pedalAction = - match.GetActionWhere([](const auto& action) { - // Pedal action is a match action with an ID in - // 0 ..< OmniboxPedalId::TOTAL_COUNT range (and ID 0 is NONE). - return action->GetID() < static_cast<int>(OmniboxPedalId::TOTAL_COUNT); - }); - if (!pedalAction) { + const OmniboxPedal* omniboxPedal = + OmniboxPedal::FromAction(match.GetActionWhere([](const auto& action) { + return action->ActionId() == OmniboxActionId::PEDAL; + })); + if (!omniboxPedal) { return nil; } __weak id<ApplicationCommands> pedalsEndpoint = self.pedalsEndpoint; __weak id<OmniboxCommands> omniboxCommandHandler = self.omniboxCommandHandler; NSString* hint = - base::SysUTF16ToNSString(pedalAction->GetLabelStrings().hint); + base::SysUTF16ToNSString(omniboxPedal->GetLabelStrings().hint); NSString* suggestionContents = base::SysUTF16ToNSString( - pedalAction->GetLabelStrings().suggestion_contents); - NSInteger pedalType = static_cast<NSInteger>( - static_cast<const OmniboxPedal*>(pedalAction)->GetMetricsId()); - - OmniboxPedalId pedalId = static_cast<OmniboxPedalId>(pedalAction->GetID()); + omniboxPedal->GetLabelStrings().suggestion_contents); + NSInteger pedalType = static_cast<NSInteger>(omniboxPedal->GetMetricsId()); + OmniboxPedalId pedalId = omniboxPedal->PedalId(); UIImage* image;
diff --git a/ios/chrome/browser/ui/settings/password/password_checkup/BUILD.gn b/ios/chrome/browser/ui/settings/password/password_checkup/BUILD.gn index f99f4db2..2f43baf 100644 --- a/ios/chrome/browser/ui/settings/password/password_checkup/BUILD.gn +++ b/ios/chrome/browser/ui/settings/password/password_checkup/BUILD.gn
@@ -19,6 +19,7 @@ "//ios/chrome/browser/passwords", "//ios/chrome/browser/shared/coordinator/chrome_coordinator", "//ios/chrome/browser/shared/ui/table_view:utils", + "//ios/chrome/browser/ui/settings/password/password_issues", ] }
diff --git a/ios/chrome/browser/ui/settings/password/password_checkup/password_checkup_commands.h b/ios/chrome/browser/ui/settings/password/password_checkup/password_checkup_commands.h index 329122a0..76d10c4 100644 --- a/ios/chrome/browser/ui/settings/password/password_checkup/password_checkup_commands.h +++ b/ios/chrome/browser/ui/settings/password/password_checkup/password_checkup_commands.h
@@ -5,12 +5,21 @@ #ifndef IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_PASSWORD_CHECKUP_PASSWORD_CHECKUP_COMMANDS_H_ #define IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_PASSWORD_CHECKUP_PASSWORD_CHECKUP_COMMANDS_H_ +namespace password_manager { +enum class WarningType; +} + // Commands relative to the Password Checkup homepage. @protocol PasswordCheckupCommands // Called when view controller is removed. - (void)dismissPasswordCheckupViewController; +// Opens the Password Issues list displaying compromised, weak or reused +// credentials. +- (void)showPasswordIssuesWithWarningType: + (password_manager::WarningType)warningType; + @end #endif // IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_PASSWORD_CHECKUP_PASSWORD_CHECKUP_COMMANDS_H_
diff --git a/ios/chrome/browser/ui/settings/password/password_checkup/password_checkup_coordinator.h b/ios/chrome/browser/ui/settings/password/password_checkup/password_checkup_coordinator.h index babe3c91..e6f2dc197 100644 --- a/ios/chrome/browser/ui/settings/password/password_checkup/password_checkup_coordinator.h +++ b/ios/chrome/browser/ui/settings/password/password_checkup/password_checkup_coordinator.h
@@ -8,6 +8,7 @@ #import "ios/chrome/browser/shared/coordinator/chrome_coordinator/chrome_coordinator.h" @class PasswordCheckupCoordinator; +@class ReauthenticationModule; // Delegate for PasswordCheckupCoordinator. @protocol PasswordCheckupCoordinatorDelegate @@ -24,6 +25,8 @@ - (instancetype)initWithBaseNavigationController: (UINavigationController*)navigationController browser:(Browser*)browser + reauthModule: + (ReauthenticationModule*)reauthModule NS_DESIGNATED_INITIALIZER; - (instancetype)initWithBaseViewController:(UIViewController*)viewController
diff --git a/ios/chrome/browser/ui/settings/password/password_checkup/password_checkup_coordinator.mm b/ios/chrome/browser/ui/settings/password/password_checkup/password_checkup_coordinator.mm index d383316b..e7cf1e67 100644 --- a/ios/chrome/browser/ui/settings/password/password_checkup/password_checkup_coordinator.mm +++ b/ios/chrome/browser/ui/settings/password/password_checkup/password_checkup_coordinator.mm
@@ -11,12 +11,20 @@ #import "ios/chrome/browser/ui/settings/password/password_checkup/password_checkup_commands.h" #import "ios/chrome/browser/ui/settings/password/password_checkup/password_checkup_mediator.h" #import "ios/chrome/browser/ui/settings/password/password_checkup/password_checkup_view_controller.h" +#import "ios/chrome/browser/ui/settings/password/password_issues/password_issues_coordinator.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." #endif -@interface PasswordCheckupCoordinator () <PasswordCheckupCommands> +@interface PasswordCheckupCoordinator () <PasswordCheckupCommands, + PasswordIssuesCoordinatorDelegate> { + // Coordinator for password issues. + PasswordIssuesCoordinator* _passwordIssuesCoordinator; + + // Reauthentication module used by password issues coordinator. + ReauthenticationModule* _reauthModule; +} // Main view controller for this coordinator. @property(nonatomic, strong) PasswordCheckupViewController* viewController; @@ -32,11 +40,14 @@ - (instancetype)initWithBaseNavigationController: (UINavigationController*)navigationController - browser:(Browser*)browser { + browser:(Browser*)browser + reauthModule: + (ReauthenticationModule*)reauthModule { self = [super initWithBaseViewController:navigationController browser:browser]; if (self) { _baseNavigationController = navigationController; + _reauthModule = reauthModule; } return self; } @@ -61,6 +72,8 @@ self.mediator = nil; self.viewController.handler = nil; self.viewController = nil; + + [self stopPasswordIssuesCoordinator]; } #pragma mark - PasswordCheckupCommands @@ -69,4 +82,32 @@ [self.delegate passwordCheckupCoordinatorDidRemove:self]; } +- (void)showPasswordIssuesWithWarningType: + (password_manager::WarningType)warningType { + CHECK(!_passwordIssuesCoordinator); + _passwordIssuesCoordinator = [[PasswordIssuesCoordinator alloc] + initForWarningType:warningType + baseNavigationController:self.baseNavigationController + browser:self.browser]; + _passwordIssuesCoordinator.delegate = self; + _passwordIssuesCoordinator.reauthModule = _reauthModule; + [_passwordIssuesCoordinator start]; +} + +#pragma mark - PasswordIssuesCoordinatorDelegate + +- (void)passwordIssuesCoordinatorDidRemove: + (PasswordIssuesCoordinator*)coordinator { + CHECK_EQ(_passwordIssuesCoordinator, coordinator); + [self stopPasswordIssuesCoordinator]; +} + +#pragma mark - Private + +- (void)stopPasswordIssuesCoordinator { + [_passwordIssuesCoordinator stop]; + _passwordIssuesCoordinator.delegate = nil; + _passwordIssuesCoordinator = nil; +} + @end
diff --git a/ios/chrome/browser/ui/settings/password/password_checkup/password_checkup_view_controller.mm b/ios/chrome/browser/ui/settings/password/password_checkup/password_checkup_view_controller.mm index d73e66633..6d113b3 100644 --- a/ios/chrome/browser/ui/settings/password/password_checkup/password_checkup_view_controller.mm +++ b/ios/chrome/browser/ui/settings/password/password_checkup/password_checkup_view_controller.mm
@@ -26,6 +26,7 @@ #endif using password_manager::InsecurePasswordCounts; +using password_manager::WarningType; namespace { @@ -414,8 +415,16 @@ static_cast<ItemType>([model itemTypeForIndexPath:indexPath]); switch (itemType) { case ItemTypeCompromisedPasswords: + [self.handler showPasswordIssuesWithWarningType: + WarningType::kCompromisedPasswordsWarning]; + break; case ItemTypeReusedPasswords: + [self.handler showPasswordIssuesWithWarningType: + WarningType::kReusedPasswordsWarning]; + break; case ItemTypeWeakPasswords: + [self.handler + showPasswordIssuesWithWarningType:WarningType::kWeakPasswordsWarning]; break; case ItemTypePasswordCheckupTimestamp: break;
diff --git a/ios/chrome/browser/ui/settings/password/password_checkup/password_checkup_view_controller_unittest.mm b/ios/chrome/browser/ui/settings/password/password_checkup/password_checkup_view_controller_unittest.mm index b3c2d115..8aad824d 100644 --- a/ios/chrome/browser/ui/settings/password/password_checkup/password_checkup_view_controller_unittest.mm +++ b/ios/chrome/browser/ui/settings/password/password_checkup/password_checkup_view_controller_unittest.mm
@@ -23,6 +23,7 @@ #import "ios/chrome/browser/shared/ui/table_view/table_view_utils.h" #import "ios/chrome/browser/ui/icons/symbols.h" #import "ios/chrome/browser/ui/settings/cells/settings_check_item.h" +#import "ios/chrome/browser/ui/settings/password/password_checkup/password_checkup_commands.h" #import "ios/chrome/browser/ui/settings/password/password_checkup/password_checkup_constants.h" #import "ios/chrome/browser/ui/settings/password/password_checkup/password_checkup_mediator+private.h" #import "ios/chrome/browser/ui/settings/password/password_checkup/password_checkup_mediator.h" @@ -31,6 +32,8 @@ #import "ios/chrome/grit/ios_strings.h" #import "ios/web/public/test/web_task_environment.h" #import "testing/gtest_mac.h" +#import "third_party/ocmock/OCMock/OCMock.h" +#import "third_party/ocmock/gtest_support.h" #import "ui/base/l10n/l10n_util.h" #if !defined(__has_feature) || !__has_feature(objc_arc) @@ -41,6 +44,7 @@ using password_manager::InsecureType; using password_manager::PasswordForm; using password_manager::TestPasswordStore; +using password_manager::WarningType; // Test fixture for testing PasswordCheckupViewController class. class PasswordCheckupViewControllerTest : public ChromeTableViewControllerTest { @@ -80,6 +84,9 @@ view_controller.delegate = mediator_; mediator_.consumer = view_controller; + handler_ = OCMStrictProtocolMock(@protocol(PasswordCheckupCommands)); + view_controller.handler = handler_; + // Add a saved password since Password Checkup is not available when the // user doesn't have any saved passwords. AddSavedForm(); @@ -252,6 +259,13 @@ IDS_IOS_PASSWORD_CHECKUP_HOMEPAGE_NO_WEAK_PASSWORDS_SUBTITLE); } + // Simulates a tap on an item in the tableView. + void SimulateTap(int index, int section) { + [controller() tableView:controller().tableView + didSelectRowAtIndexPath:[NSIndexPath indexPathForItem:index + inSection:section]]; + } + void RunUntilIdle() { task_environment_.RunUntilIdle(); } web::WebTaskEnvironment task_environment_; @@ -259,6 +273,7 @@ std::unique_ptr<TestBrowser> browser_; PasswordCheckupMediator* mediator_; base::test::ScopedFeatureList feature_list; + id<PasswordCheckupCommands> handler_; // Strings for the insecure types section. NSString* compromised_text_; NSString* compromised_detail_text_; @@ -547,3 +562,47 @@ [GetPasswordCheckupViewController() settingsWillBeDismissed]; } + +// Verifies that tapping on the compromised passwords cell tells the handler to +// show compromised issues. +TEST_F(PasswordCheckupViewControllerTest, + TestTapCompromisedPasswordsNotifiesHandler) { + AddSavedInsecureForm(InsecureType::kLeaked); + ChangePasswordCheckupHomepageState(PasswordCheckupHomepageStateDone); + + OCMExpect([handler_ showPasswordIssuesWithWarningType: + WarningType::kCompromisedPasswordsWarning]); + + SimulateTap(/*index=*/0, /*section=*/0); + + EXPECT_OCMOCK_VERIFY((id)handler_); +} + +// Verifies that tapping on the reused passwords cell tells the handler to show +// reused issues. +TEST_F(PasswordCheckupViewControllerTest, + TestTapReusedPasswordsNotifiesHandler) { + AddSavedInsecureForm(InsecureType::kReused); + ChangePasswordCheckupHomepageState(PasswordCheckupHomepageStateDone); + + OCMExpect([handler_ + showPasswordIssuesWithWarningType:WarningType::kReusedPasswordsWarning]); + + SimulateTap(/*index=*/1, /*section=*/0); + + EXPECT_OCMOCK_VERIFY((id)handler_); +} + +// Verifies that tapping on the weak passwords cell tells the handler to +// show weak issues. +TEST_F(PasswordCheckupViewControllerTest, TestTapWeakPasswordsNotifiesHandler) { + AddSavedInsecureForm(InsecureType::kWeak); + ChangePasswordCheckupHomepageState(PasswordCheckupHomepageStateDone); + + OCMExpect([handler_ + showPasswordIssuesWithWarningType:WarningType::kWeakPasswordsWarning]); + + SimulateTap(/*index=*/2, /*section=*/0); + + EXPECT_OCMOCK_VERIFY((id)handler_); +}
diff --git a/ios/chrome/browser/ui/settings/password/password_issues/BUILD.gn b/ios/chrome/browser/ui/settings/password/password_issues/BUILD.gn index 0ebeada..5e35f5b 100644 --- a/ios/chrome/browser/ui/settings/password/password_issues/BUILD.gn +++ b/ios/chrome/browser/ui/settings/password/password_issues/BUILD.gn
@@ -55,12 +55,14 @@ deps = [ "//base", "//components/password_manager/core/browser", + "//components/password_manager/core/common:features", "//ios/chrome/app/strings", "//ios/chrome/browser/net:crurl", "//ios/chrome/browser/shared/ui/table_view", "//ios/chrome/browser/shared/ui/table_view/cells", "//ios/chrome/browser/ui/settings:settings_root", "//ios/chrome/browser/ui/settings/password:password_constants", + "//ios/chrome/common/ui/colors", "//ios/chrome/common/ui/favicon", "//ui/base", ]
diff --git a/ios/chrome/browser/ui/settings/password/password_issues/password_issue.h b/ios/chrome/browser/ui/settings/password/password_issues/password_issue.h index a3fb957..0dddd2d 100644 --- a/ios/chrome/browser/ui/settings/password/password_issues/password_issue.h +++ b/ios/chrome/browser/ui/settings/password/password_issues/password_issue.h
@@ -22,11 +22,20 @@ @property(nonatomic, copy, readonly) NSString* website; // Associated username. @property(nonatomic, copy, readonly) NSString* username; +// Description of type of compromised credential issue. +// Nil for non-compromised credentials. +@property(nonatomic, readonly) NSString* compromisedDescription; // Credential being displayed in Password Details screen. @property(nonatomic, readonly) password_manager::CredentialUIEntry credential; +// Initializes a PasswordIssue from a CredentialUIEntry. +// Pass `enableCompromisedDescription` as YES when the description of +// compromised issues should be displayed in the UX (e.g., When displaying +// compromised credentials in the Password Issues UX.). - (instancetype)initWithCredential: - (password_manager::CredentialUIEntry)credential NS_DESIGNATED_INITIALIZER; + (password_manager::CredentialUIEntry)credential + enableCompromisedDescription:(BOOL)enableCompromisedDescription + NS_DESIGNATED_INITIALIZER; - (instancetype)init NS_UNAVAILABLE;
diff --git a/ios/chrome/browser/ui/settings/password/password_issues/password_issue.mm b/ios/chrome/browser/ui/settings/password/password_issues/password_issue.mm index 79c663d..5a5bda9 100644 --- a/ios/chrome/browser/ui/settings/password/password_issues/password_issue.mm +++ b/ios/chrome/browser/ui/settings/password/password_issues/password_issue.mm
@@ -8,15 +8,24 @@ #import "components/password_manager/core/browser/password_ui_utils.h" #import "components/password_manager/core/browser/ui/credential_ui_entry.h" #import "ios/chrome/browser/net/crurl.h" +#import "ios/chrome/grit/ios_strings.h" +#import "ui/base/l10n/l10n_util_mac.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." #endif +@interface PasswordIssue () { + // Whether the description for compromised credentials should be displayed. + BOOL _compromisedDescriptionEnabled; +} +@end + @implementation PasswordIssue - (instancetype)initWithCredential: - (password_manager::CredentialUIEntry)credential { + (password_manager::CredentialUIEntry)credential + enableCompromisedDescription:(BOOL)enableCompromisedDescription { self = [super init]; if (self) { _credential = credential; @@ -24,8 +33,25 @@ base::SysUTF8ToNSString(password_manager::GetShownOrigin(credential)); _username = base::SysUTF16ToNSString(credential.username); _URL = [[CrURL alloc] initWithGURL:credential.GetURL()]; + _compromisedDescriptionEnabled = enableCompromisedDescription; } return self; } +- (NSString*)compromisedDescription { + if (_compromisedDescriptionEnabled) { + if (_credential.IsLeaked()) { + return l10n_util::GetNSString( + IDS_IOS_COMPROMISED_PASSWORD_ISSUES_LEAKED_DESCRIPTION); + } + + if (_credential.IsPhished()) { + return l10n_util::GetNSString( + IDS_IOS_COMPROMISED_PASSWORD_ISSUES_PHISHED_DESCRIPTION); + } + } + + return nil; +} + @end
diff --git a/ios/chrome/browser/ui/settings/password/password_issues/password_issue_content_item.mm b/ios/chrome/browser/ui/settings/password/password_issues/password_issue_content_item.mm index c05332f..8add46d 100644 --- a/ios/chrome/browser/ui/settings/password/password_issues/password_issue_content_item.mm +++ b/ios/chrome/browser/ui/settings/password/password_issues/password_issue_content_item.mm
@@ -18,6 +18,7 @@ self.title = password.website; self.detailText = password.username; self.URL = password.URL; + self.thirdRowText = password.compromisedDescription; } @end
diff --git a/ios/chrome/browser/ui/settings/password/password_issues/password_issues_mediator.mm b/ios/chrome/browser/ui/settings/password/password_issues/password_issues_mediator.mm index 9b1adbb..8c6b44e 100644 --- a/ios/chrome/browser/ui/settings/password/password_issues/password_issues_mediator.mm +++ b/ios/chrome/browser/ui/settings/password/password_issues/password_issues_mediator.mm
@@ -39,13 +39,22 @@ namespace { -// Maps CredentialUIEntry to PasswordIssue and sorts them by website and -// username. +// Creates PasswordIssues from CredentialUIEntry to display them in the Password +// Issues list UI for the given `warning_type`. PasswordIssues are sorted by +// website and username. NSArray<PasswordIssue*>* GetSortedPasswordIssues( + WarningType warning_type, const std::vector<CredentialUIEntry>& insecure_credentials) { NSMutableArray<PasswordIssue*>* passwords = [[NSMutableArray alloc] init]; + + BOOL enable_compromised_description = + IsPasswordCheckupEnabled() && + warning_type == WarningType::kCompromisedPasswordsWarning; + for (auto credential : insecure_credentials) { - [passwords addObject:[[PasswordIssue alloc] initWithCredential:credential]]; + [passwords addObject:[[PasswordIssue alloc] initWithCredential:credential + enableCompromisedDescription: + enable_compromised_description]]; } NSSortDescriptor* origin = [[NSSortDescriptor alloc] initWithKey:@"website" @@ -91,9 +100,11 @@ [same_password_issues enumerateObjectsUsingBlock:^(NSMutableArray<PasswordIssue*>* issues, NSUInteger index, BOOL* stop) { - // TODO(crbug.com/1406540): Add header for each group. + NSString* headerText = + l10n_util::GetNSStringF(IDS_IOS_REUSED_PASSWORD_ISSUES_GROUP_HEADER, + base::NumberToString16(issues.count)); [password_issue_groups - addObject:[[PasswordIssueGroup alloc] initWithHeaderText:nil + addObject:[[PasswordIssueGroup alloc] initWithHeaderText:headerText passwordIssues:issues]]; }]; @@ -111,7 +122,7 @@ // Sort by website and username. NSArray<PasswordIssue*>* sorted_issues = - GetSortedPasswordIssues(insecure_credentials); + GetSortedPasswordIssues(warning_type, insecure_credentials); // Reused issues are grouped by passwords. if (warning_type == WarningType::kReusedPasswordsWarning) {
diff --git a/ios/chrome/browser/ui/settings/password/password_issues/password_issues_table_view_controller.mm b/ios/chrome/browser/ui/settings/password/password_issues/password_issues_table_view_controller.mm index 93e4c9f..3d8fd0f 100644 --- a/ios/chrome/browser/ui/settings/password/password_issues/password_issues_table_view_controller.mm +++ b/ios/chrome/browser/ui/settings/password/password_issues/password_issues_table_view_controller.mm
@@ -6,11 +6,14 @@ #import <UIKit/UIKit.h> #import "base/mac/foundation_util.h" +#import "components/password_manager/core/common/password_manager_features.h" +#import "ios/chrome/browser/shared/ui/table_view/cells/table_view_text_item.h" #import "ios/chrome/browser/shared/ui/table_view/table_view_favicon_data_source.h" #import "ios/chrome/browser/ui/settings/password/password_issues/password_issue_content_item.h" #import "ios/chrome/browser/ui/settings/password/password_issues/password_issues_consumer.h" #import "ios/chrome/browser/ui/settings/password/password_issues/password_issues_presenter.h" #import "ios/chrome/browser/ui/settings/password/passwords_table_view_constants.h" +#import "ios/chrome/common/ui/colors/semantic_color_names.h" #import "ios/chrome/common/ui/favicon/favicon_view.h" #import "ios/chrome/grit/ios_strings.h" #import "ui/base/l10n/l10n_util_mac.h" @@ -19,15 +22,31 @@ #error "This file requires ARC support." #endif +using password_manager::features::IsPasswordCheckupEnabled; + namespace { +// Vertical spacing between password issue items. +constexpr CGFloat kVerticalSpacingBetweenItems = 8; + typedef NS_ENUM(NSInteger, SectionIdentifier) { - SectionIdentifierContent = kSectionIdentifierEnumZero, + SectionIdentifierHeader = kSectionIdentifierEnumZero, + SectionIdentifierContent, + // Identifier of the section containing the first password issue when Password + // Checkup is enabled. Subsequent password issues use incremental section + // identifiers, as each issue goes in a separate section. To avoid section + // identifiers collisions, `SectionIdentifierFirstPasswordIssue` should be + // the last value in `SectionIdentifier` and any new identifiers must be + // defined above it. + SectionIdentifierFirstPasswordIssue, + // Do not add more values here. See comment above. }; typedef NS_ENUM(NSInteger, ItemType) { ItemTypeHeader = kItemTypeEnumZero, - ItemTypePassword, // This is a repeated item type. + ItemTypePassword, // This is a repeated item type. + ItemTypePasswordHeader, // This is a repeated item type. + ItemTypeChangePassword, // This is a repeated item type. }; } // namespace @@ -37,10 +56,13 @@ NSString* _headerText; // URL of link in the page header. Nullable. CrURL* _headerURL; + // Insecure password issues displayed in the tableView. + // Reused password issues are displayed in groups of same-password credentials + // with a text header on top of the first password issue in the group. All + // other types of issues are displayed in the same group without header. + NSArray<PasswordIssueGroup*>* _passwordGroups; } -@property(nonatomic, strong) NSArray<PasswordIssue*>* passwords; - @end @implementation PasswordIssuesTableViewController @@ -66,18 +88,66 @@ - (void)loadModel { [super loadModel]; + if (!IsPasswordCheckupEnabled()) { + [self loadModelLegacy]; + return; + } + TableViewModel* model = self.tableViewModel; - [model addSectionWithIdentifier:SectionIdentifierContent]; TableViewLinkHeaderFooterItem* headerItem = [self headerItem]; if (headerItem) { - // Set header on top of first section. + [model addSectionWithIdentifier:SectionIdentifierHeader]; [model setHeader:headerItem - forSectionWithIdentifier:kSectionIdentifierEnumZero]; + forSectionWithIdentifier:SectionIdentifierHeader]; } - for (PasswordIssue* password in self.passwords) { + // Add password issues to their own separate sections. + __block NSInteger nextPasswordIssueSectionIdentifier = + SectionIdentifierFirstPasswordIssue; + for (PasswordIssueGroup* issueGroup in _passwordGroups) { + [issueGroup.passwordIssues + enumerateObjectsUsingBlock:^(PasswordIssue* passwordIssue, + NSUInteger index, BOOL* stop) { + // Create section for next password issue. + [model addSectionWithIdentifier:nextPasswordIssueSectionIdentifier]; + + // Add header on top of first issue if the issue group has a header. + if (index == 0 && issueGroup.headerText) { + [model setHeader:[self passwordIssueGroupHeaderItemWithText: + issueGroup.headerText] + forSectionWithIdentifier:nextPasswordIssueSectionIdentifier]; + } + + // Add password issue. + [model addItem:[self passwordIssueItem:passwordIssue] + toSectionWithIdentifier:nextPasswordIssueSectionIdentifier]; + + // Add change password button below password issue. + [model addItem:[self changePasswordItem] + toSectionWithIdentifier:nextPasswordIssueSectionIdentifier]; + + // Increment section identifier for next password issue. + nextPasswordIssueSectionIdentifier++; + }]; + } +} + +// Legacy loadModel logic used when Password Checkup Feature is not enabled. +- (void)loadModelLegacy { + CHECK(!IsPasswordCheckupEnabled()); + + TableViewModel* model = self.tableViewModel; + [model addSectionWithIdentifier:SectionIdentifierContent]; + TableViewLinkHeaderFooterItem* headerItem = [self headerItem]; + + if (headerItem) { + [model setHeader:headerItem + forSectionWithIdentifier:SectionIdentifierContent]; + } + + for (PasswordIssue* password in _passwordGroups.firstObject.passwordIssues) { [model addItem:[self passwordIssueItem:password] toSectionWithIdentifier:SectionIdentifierContent]; } @@ -110,6 +180,27 @@ return passwordItem; } +// Creates a header for displaying on top of a group of password issues. +- (TableViewLinkHeaderFooterItem*)passwordIssueGroupHeaderItemWithText: + (NSString*)headerText { + TableViewLinkHeaderFooterItem* groupHeaderItem = + [[TableViewLinkHeaderFooterItem alloc] + initWithType:ItemTypePasswordHeader]; + groupHeaderItem.text = headerText; + return groupHeaderItem; +} + +// Creates an item acting as a button for changing an insecure password in its +// corresponding website. +- (TableViewTextItem*)changePasswordItem { + TableViewTextItem* item = + [[TableViewTextItem alloc] initWithType:ItemTypeChangePassword]; + item.text = l10n_util::GetNSString(IDS_IOS_CHANGE_COMPROMISED_PASSWORD); + item.textColor = [UIColor colorNamed:kBlueColor]; + item.accessibilityTraits = UIAccessibilityTraitButton; + return item; +} + #pragma mark - UITableViewDelegate - (void)tableView:(UITableView*)tableView @@ -117,10 +208,12 @@ [super tableView:tableView didSelectRowAtIndexPath:indexPath]; TableViewModel* model = self.tableViewModel; - NSInteger itemType = [model itemTypeForIndexPath:indexPath]; + ItemType itemType = + static_cast<ItemType>([model itemTypeForIndexPath:indexPath]); switch (itemType) { case ItemTypeHeader: + case ItemTypePasswordHeader: break; case ItemTypePassword: { PasswordIssueContentItem* passwordIssue = @@ -129,6 +222,9 @@ [self.presenter presentPasswordIssueDetails:passwordIssue.password]; break; } + case ItemTypeChangePassword: + // TODO(crbug.com/1406540): Handle change password taps. + break; } [tableView deselectRowAtIndexPath:indexPath animated:YES]; @@ -165,6 +261,80 @@ return view; } +- (CGFloat)tableView:(UITableView*)tableView + heightForFooterInSection:(NSInteger)section { + TableViewModel* model = self.tableViewModel; + // Calculate the actual height of the footer view if there's one. + if ([model footerForSectionIndex:section]) { + return UITableViewAutomaticDimension; + } + + NSInteger sectionIdentifier = + [model sectionIdentifierForSectionIndex:section]; + switch (sectionIdentifier) { + case SectionIdentifierHeader: + // Add an empty footer of 8pt height so added up to the table view header + // bottom padding (8pt) and the first section's header (either an empty + // 8pt header or an actual header that has a 8pt top padding) achieves the + // desired 24pt spacing between the table view header and the next element + // below it. + return kVerticalSpacingBetweenItems; + + case SectionIdentifierContent: + // Vertical spacing between the last item and its container in the legacy + // layout. + return kVerticalSpacingBetweenItems; + + default: + // Handle password issue sections. + // All other sections should be handled by now. + CHECK_GE(sectionIdentifier, SectionIdentifierFirstPasswordIssue); + + if (section + 1 < model.numberOfSections) { + // When the next section doesn't have a header, the desired spacing is + // achieved via an empty header. If there's a header, it includes an 8pt + // top padding, so we add a 16pt empty footer to achieve the desired + // spacing of 24pt. + return [model headerForSectionIndex:section + 1] + ? kVerticalSpacingBetweenItems * 2 + : 0; + } + + // Vertical spacing between the last item and its container. + return kVerticalSpacingBetweenItems; + } +} + +- (CGFloat)tableView:(UITableView*)tableView + heightForHeaderInSection:(NSInteger)section { + TableViewModel* model = self.tableViewModel; + + // Calculate the actual height of the header view if there's one. + if ([model headerForSectionIndex:section]) { + return UITableViewAutomaticDimension; + } + + NSInteger sectionIdentifier = + [model sectionIdentifierForSectionIndex:section]; + switch (sectionIdentifier) { + case SectionIdentifierHeader: + // This section always has a header. + NOTREACHED_NORETURN(); + + case SectionIdentifierContent: + // Keep legacy spacing when no header. + return [super tableView:tableView heightForHeaderInSection:section]; + + default: + // Handle password issue sections. + // All other sections should be handled by now. + CHECK_GE(sectionIdentifier, SectionIdentifierFirstPasswordIssue); + // Add an empty header to achieve the desired spacing to the element + // above. + return kVerticalSpacingBetweenItems; + } +} + // Asynchronously loads favicon for given index path. The loads are cancelled // upon cell reuse automatically. - (void)loadFaviconAtIndexPath:(NSIndexPath*)indexPath @@ -192,10 +362,7 @@ #pragma mark - PasswordIssuesConsumer - (void)setPasswordIssues:(NSArray<PasswordIssueGroup*>*)passwordGroups { - // TODO(crbug.com/1406540): Replace passwords with passwordGroups to display - // all groups. - self.passwords = - passwordGroups.count == 0 ? @[] : passwordGroups[0].passwordIssues; + _passwordGroups = passwordGroups; [self reloadData]; }
diff --git a/ios/chrome/browser/ui/settings/password/password_issues/password_issues_table_view_controller_unittest.mm b/ios/chrome/browser/ui/settings/password/password_issues/password_issues_table_view_controller_unittest.mm index 7b2e5a5..0a10f044 100644 --- a/ios/chrome/browser/ui/settings/password/password_issues/password_issues_table_view_controller_unittest.mm +++ b/ios/chrome/browser/ui/settings/password/password_issues/password_issues_table_view_controller_unittest.mm
@@ -76,7 +76,8 @@ form.signon_realm = "http://www.example.com/"; form.scheme = password_manager::PasswordForm::Scheme::kHtml; PasswordIssue* password_issue = [[PasswordIssue alloc] - initWithCredential:password_manager::CredentialUIEntry(form)]; + initWithCredential:password_manager::CredentialUIEntry(form) + enableCompromisedDescription:NO]; PasswordIssueGroup* issue_group = [[PasswordIssueGroup alloc] initWithHeaderText:nil passwordIssues:@[ password_issue ]];
diff --git a/ios/chrome/browser/ui/settings/password/passwords_coordinator.mm b/ios/chrome/browser/ui/settings/password/passwords_coordinator.mm index de09eb2..cd2ca7c1 100644 --- a/ios/chrome/browser/ui/settings/password/passwords_coordinator.mm +++ b/ios/chrome/browser/ui/settings/password/passwords_coordinator.mm
@@ -211,7 +211,8 @@ DCHECK(!self.passwordCheckupCoordinator); self.passwordCheckupCoordinator = [[PasswordCheckupCoordinator alloc] initWithBaseNavigationController:self.baseNavigationController - browser:self.browser]; + browser:self.browser + reauthModule:self.reauthModule]; self.passwordCheckupCoordinator.delegate = self; [self.passwordCheckupCoordinator start]; }
diff --git a/ios/web/find_in_page/README.md b/ios/web/find_in_page/README.md new file mode 100644 index 0000000..772c614b --- /dev/null +++ b/ios/web/find_in_page/README.md
@@ -0,0 +1,2 @@ +This directory contains the implementation of searching for text on a web page. +The public API is exposed in //ios/web/public/find_in_page. \ No newline at end of file
diff --git a/ios/web/js_messaging/README.md b/ios/web/js_messaging/README.md new file mode 100644 index 0000000..c39c5fd --- /dev/null +++ b/ios/web/js_messaging/README.md
@@ -0,0 +1,2 @@ +Implementation of the JavaScript API for iOS features. See +//ios/web/public/js_messaging/README.md for details on using these APIs. \ No newline at end of file
diff --git a/ios/web/public/find_in_page/README.md b/ios/web/public/find_in_page/README.md index a539948b..dbfd382 100644 --- a/ios/web/public/find_in_page/README.md +++ b/ios/web/public/find_in_page/README.md
@@ -1 +1,17 @@ -This directory contains API to search for text on a web page. This directory does not support any UI API except content highlighting. +# Find in Page + +This directory contains API to search for text on a web page. This directory +does not support any UI API except content highlighting. + +## AbstractFindInPageManager + +This class exposes the primary Find in Page API. + +## JavaScriptFindInPageManager + +This class implements the `AbstractFindInPageManager` API using JavaScript. + +## FindInPageManager + +This class implements the `AbstractFindInPageManager` API using the iOS native +Find in Page API available starting in iOS 16.
diff --git a/ios/web/webui/README.md b/ios/web/webui/README.md new file mode 100644 index 0000000..6038178d --- /dev/null +++ b/ios/web/webui/README.md
@@ -0,0 +1,12 @@ +This directory contains the iOS specific implementation of WebUI pages. Note +that while other platforms use WebUI as part of the primary UI, iOS uses web UI +primarily for "debug" pages. (Pages which render in the web view at `chrome://` +URLs.) The most visible Web UI surface on iOS is currently "web interstitials" +which are shared across all platforms including iOS. + +WebUI on iOS uses mojo to communicate between the webpage JavaScript and the +native Web UI page controller code. This communication channel is implemented in +the MojoFacade class in this directory. + +For more details about webui itself, see the webui docs at `//docs/webui*.md` +and the shared code at `//ui/webui/`
diff --git a/ios/web_view/internal/cwv_user_content_controller.mm b/ios/web_view/internal/cwv_user_content_controller.mm index b91a043..aa1d2cb 100644 --- a/ios/web_view/internal/cwv_user_content_controller.mm +++ b/ios/web_view/internal/cwv_user_content_controller.mm
@@ -5,15 +5,38 @@ #import "ios/web_view/public/cwv_user_content_controller.h" #import "ios/web_view/internal/cwv_user_content_controller_internal.h" +#import "base/json/json_writer.h" +#import "base/mac/foundation_util.h" +#import "base/strings/sys_string_conversions.h" #import "ios/web_view/internal/cwv_web_view_configuration_internal.h" #include "ios/web_view/internal/web_view_browser_state.h" #import "ios/web_view/internal/web_view_early_page_script_provider.h" +#import "ios/web_view/internal/web_view_message_handler_java_script_feature.h" #import "ios/web_view/public/cwv_user_script.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." #endif +namespace { + +// Converts base::Value::Dict to NSDictionary. +NSDictionary* NSDictionaryFromDictValue(const base::Value::Dict& value) { + std::string json; + const bool success = base::JSONWriter::Write(value, &json); + DCHECK(success) << "Failed to convert base::Value to JSON"; + + NSData* json_data = [NSData dataWithBytes:json.c_str() length:json.length()]; + NSDictionary* ns_dictionary = base::mac::ObjCCastStrict<NSDictionary>( + [NSJSONSerialization JSONObjectWithData:json_data + options:kNilOptions + error:nil]); + DCHECK(ns_dictionary) << "Failed to convert JSON to NSDictionary"; + return ns_dictionary; +} + +} // namespace + @interface CWVUserContentController () @property(weak, nonatomic) CWVWebViewConfiguration* configuration; @end @@ -63,4 +86,23 @@ .SetScript(joinedScript); } +- (void)addMessageHandler:(void (^)(NSDictionary* payload))handler + forCommand:(NSString*)nsCommand { + DCHECK(handler); + std::string command = base::SysNSStringToUTF8(nsCommand); + WebViewMessageHandlerJavaScriptFeature::FromBrowserState( + _configuration.browserState) + ->RegisterHandler( + command, base::BindRepeating(^(const base::Value::Dict& payload) { + handler(NSDictionaryFromDictValue(payload)); + })); +} + +- (void)removeMessageHandlerForCommand:(NSString*)nsCommand { + std::string command = base::SysNSStringToUTF8(nsCommand); + WebViewMessageHandlerJavaScriptFeature::FromBrowserState( + _configuration.browserState) + ->UnregisterHandler(command); +} + @end
diff --git a/ios/web_view/internal/web_view_message_handler_java_script_feature.h b/ios/web_view/internal/web_view_message_handler_java_script_feature.h index 4a8c9c05..8ee996e 100644 --- a/ios/web_view/internal/web_view_message_handler_java_script_feature.h +++ b/ios/web_view/internal/web_view_message_handler_java_script_feature.h
@@ -10,9 +10,14 @@ #import "base/functional/callback.h" #import "base/no_destructor.h" +#import "base/supports_user_data.h" #import "base/values.h" #import "ios/web/public/js_messaging/java_script_feature.h" +namespace web { +class BrowserState; +} // namespace web + // A feature which listens for messages sent from the webpage to the // 'CWVWebViewMessage' message handler and routes them to the callback for the // associated command. `command` and `payload` are required top level keys. The @@ -28,10 +33,26 @@ // } // window.webkit.messageHandlers['CWVWebViewMessage'].postMessage(message); // -class WebViewMessageHandlerJavaScriptFeature : public web::JavaScriptFeature { +class WebViewMessageHandlerJavaScriptFeature + : public base::SupportsUserData::Data, + public web::JavaScriptFeature { public: + WebViewMessageHandlerJavaScriptFeature(); + ~WebViewMessageHandlerJavaScriptFeature() override; + + WebViewMessageHandlerJavaScriptFeature( + const WebViewMessageHandlerJavaScriptFeature&) = delete; + WebViewMessageHandlerJavaScriptFeature& operator=( + const WebViewMessageHandlerJavaScriptFeature&) = delete; + static WebViewMessageHandlerJavaScriptFeature* GetInstance(); + // Returns the WebViewMessageHandlerJavaScriptFeature associated with + // `browser_state`, creating one if necessary. `browser_state` must not be + // null. + static WebViewMessageHandlerJavaScriptFeature* FromBrowserState( + web::BrowserState* browser_state); + using WebViewMessageHandlerCallback = base::RepeatingCallback<void(const base::Value::Dict& payload)>; void RegisterHandler(std::string& command, @@ -46,13 +67,9 @@ void ScriptMessageReceived(web::WebState* web_state, const web::ScriptMessage& script_message) override; - WebViewMessageHandlerJavaScriptFeature(); - ~WebViewMessageHandlerJavaScriptFeature() override; - - WebViewMessageHandlerJavaScriptFeature( - const WebViewMessageHandlerJavaScriptFeature&) = delete; - WebViewMessageHandlerJavaScriptFeature& operator=( - const WebViewMessageHandlerJavaScriptFeature&) = delete; + // Notifies any handler registered in `handlers_` for the command specified in + // `message_body`. + void NotifyHandlers(const base::Value::Dict& message_body); std::map<std::string, WebViewMessageHandlerCallback> handlers_; };
diff --git a/ios/web_view/internal/web_view_message_handler_java_script_feature.mm b/ios/web_view/internal/web_view_message_handler_java_script_feature.mm index 8c94d22e..db341d20 100644 --- a/ios/web_view/internal/web_view_message_handler_java_script_feature.mm +++ b/ios/web_view/internal/web_view_message_handler_java_script_feature.mm
@@ -5,6 +5,7 @@ #import "ios/web_view/internal/web_view_message_handler_java_script_feature.h" #import "base/logging.h" +#import "ios/web/public/browser_state.h" #import "ios/web/public/js_messaging/script_message.h" #if !defined(__has_feature) || !__has_feature(objc_arc) @@ -13,6 +14,9 @@ namespace { +const char kWebViewMessageHandlerJavaScriptFeatureKeyName[] = + "web_view_message_handler_java_script_feature"; + const char kScriptName[] = "cwv_messaging"; const char kWebViewMessageHandlerName[] = "CWVWebViewMessage"; @@ -40,6 +44,24 @@ WebViewMessageHandlerJavaScriptFeature:: ~WebViewMessageHandlerJavaScriptFeature() = default; +// static +WebViewMessageHandlerJavaScriptFeature* +WebViewMessageHandlerJavaScriptFeature::FromBrowserState( + web::BrowserState* browser_state) { + DCHECK(browser_state); + + WebViewMessageHandlerJavaScriptFeature* feature = + static_cast<WebViewMessageHandlerJavaScriptFeature*>( + browser_state->GetUserData( + kWebViewMessageHandlerJavaScriptFeatureKeyName)); + if (!feature) { + feature = new WebViewMessageHandlerJavaScriptFeature(); + browser_state->SetUserData(kWebViewMessageHandlerJavaScriptFeatureKeyName, + base::WrapUnique(feature)); + } + return feature; +} + void WebViewMessageHandlerJavaScriptFeature::RegisterHandler( std::string& command, WebViewMessageHandlerCallback handler) { @@ -68,7 +90,22 @@ } base::Value::Dict message_body = std::move(script_message.body()->GetDict()); - std::string* command = message_body.FindString(kScriptMessageCommandKey); + // Pass messages from the non-static instances to the static instance during + // transition. + // TODO(crbug.com/1426917): Remove static instance of feature. + WebViewMessageHandlerJavaScriptFeature* static_instance = + WebViewMessageHandlerJavaScriptFeature::GetInstance(); + if (this != static_instance) { + static_instance->NotifyHandlers(message_body); + } + + NotifyHandlers(message_body); +} + +void WebViewMessageHandlerJavaScriptFeature::NotifyHandlers( + const base::Value::Dict& message_body) { + const std::string* command = + message_body.FindString(kScriptMessageCommandKey); if (!command) { return; } @@ -77,7 +114,8 @@ return; } - base::Value::Dict* payload = message_body.FindDict(kScriptMessagePayloadKey); + const base::Value::Dict* payload = + message_body.FindDict(kScriptMessagePayloadKey); if (!payload) { return; }
diff --git a/ios/web_view/internal/web_view_web_client.mm b/ios/web_view/internal/web_view_web_client.mm index dd84a526..bcb0ab5 100644 --- a/ios/web_view/internal/web_view_web_client.mm +++ b/ios/web_view/internal/web_view_web_client.mm
@@ -96,15 +96,16 @@ std::vector<web::JavaScriptFeature*> WebViewWebClient::GetJavaScriptFeatures( web::BrowserState* browser_state) const { - return {autofill::AutofillJavaScriptFeature::GetInstance(), - autofill::FormHandlersJavaScriptFeature::GetInstance(), - autofill::SuggestionControllerJavaScriptFeature::GetInstance(), - language::LanguageDetectionJavaScriptFeature::GetInstance(), - password_manager::PasswordManagerJavaScriptFeature::GetInstance(), - security_interstitials::IOSSecurityInterstitialJavaScriptFeature:: - GetInstance(), - translate::TranslateJavaScriptFeature::GetInstance(), - WebViewMessageHandlerJavaScriptFeature::GetInstance()}; + return { + autofill::AutofillJavaScriptFeature::GetInstance(), + autofill::FormHandlersJavaScriptFeature::GetInstance(), + autofill::SuggestionControllerJavaScriptFeature::GetInstance(), + language::LanguageDetectionJavaScriptFeature::GetInstance(), + password_manager::PasswordManagerJavaScriptFeature::GetInstance(), + security_interstitials::IOSSecurityInterstitialJavaScriptFeature:: + GetInstance(), + translate::TranslateJavaScriptFeature::GetInstance(), + WebViewMessageHandlerJavaScriptFeature::FromBrowserState(browser_state)}; } NSString* WebViewWebClient::GetDocumentStartScriptForMainFrame(
diff --git a/ios/web_view/public/cwv_defines.h b/ios/web_view/public/cwv_defines.h index afd683e..268d487 100644 --- a/ios/web_view/public/cwv_defines.h +++ b/ios/web_view/public/cwv_defines.h
@@ -72,4 +72,8 @@ // Supports -[CWVWebViewConfiguration leakCheckService]. #define IOS_WEB_VIEW_SUPPORTS_LEAK_CHECK_SERVICE 1 +// Supports -[CWVUserContentController addMessageHandler:forCommand:] and +// -[CWVUserContentController removeMessageHandlerForCommand] APIs. +#define IOS_WEB_VIEW_SUPPORTS_USER_CONTENT_CONTROLLER_MESSAGE_HANDLERS 1 + #endif // IOS_WEB_VIEW_PUBLIC_CWV_DEFINES_H_
diff --git a/ios/web_view/public/cwv_user_content_controller.h b/ios/web_view/public/cwv_user_content_controller.h index 11d33a62..9a66b7bf 100644 --- a/ios/web_view/public/cwv_user_content_controller.h +++ b/ios/web_view/public/cwv_user_content_controller.h
@@ -29,6 +29,33 @@ // Removes all associated user scripts. - (void)removeAllUserScripts; +// Adds a message handler for messages sent from JavaScript for all CWVWebViews +// associated with a CWVWebViewConfiguration referencing this +// `userContentController`. +// `handler` will be called each time a message is sent with the corresponding +// value of `command`. To send messages from JavaScript, use the WebKit +// message handler `CWVWebViewMessage` and provide values for the `command` and +// `payload` keys. +// `command` must be a string and match the registered handler `command` string +// `payload` must be a dictionary. +// +// Example call from JavaScript: +// +// let message = { +// 'command': 'myFeatureMessage', +// 'payload' : {'key1':'value1', 'key2':42} +// } +// window.webkit.messageHandlers['CWVWebViewMessage'].postMessage(message); +// +// NOTE: Only a single `handler` may be registered for a given `command` per +// user content controller. +- (void)addMessageHandler:(void (^)(NSDictionary* payload))handler + forCommand:(NSString*)command; + +// Removes the message handler associated with `command` previously added with +// `addMessageHandler:forCommand:`. +- (void)removeMessageHandlerForCommand:(NSString*)nsCommand; + @end NS_ASSUME_NONNULL_END
diff --git a/ios/web_view/public/cwv_web_view.h b/ios/web_view/public/cwv_web_view.h index 0877d95..62ecf0d 100644 --- a/ios/web_view/public/cwv_web_view.h +++ b/ios/web_view/public/cwv_web_view.h
@@ -228,7 +228,10 @@ - (void)evaluateJavaScript:(NSString*)javaScriptString completion:(void (^)(id result, NSError* error))completion; -// Adds a message handler for messages sent from JavaScript. +// DEPRECATED: Use `CWVUserContentController addMessageHandler:forCommand:` +// instead. +// Adds a message handler for messages sent from JavaScript from *any* +// CWVWebView. // `handler` will be called each time a message is sent with the corresponding // value of `command`. To send messages from JavaScript, use the WebKit // message handler `CWVWebViewMessage` and provide values for the `command` and @@ -248,6 +251,8 @@ - (void)addMessageHandler:(void (^)(NSDictionary* payload))handler forCommand:(NSString*)command; +// DEPRECATED: Use `CWVUserContentController removeMessageHandlerForCommand:` +// instead. // Removes the message handler associated with `command` previously added with // `addMessageHandler:forCommand:`. - (void)removeMessageHandlerForCommand:(NSString*)command;
diff --git a/ios/web_view/shell/shell_view_controller.m b/ios/web_view/shell/shell_view_controller.m index ef6d621..258ea3b 100644 --- a/ios/web_view/shell/shell_view_controller.m +++ b/ios/web_view/shell/shell_view_controller.m
@@ -287,6 +287,11 @@ [configuration.autofillDataManager addObserver:self]; configuration.syncController.delegate = self; [configuration.leakCheckService addObserver:self]; + [configuration.userContentController + addMessageHandler:^(NSDictionary* payload) { + NSLog(@"message handler payload received =\n%@", payload); + } + forCommand:@"messageHandlerCommand"]; self.webView = [self createWebViewWithConfiguration:configuration]; } @@ -1021,9 +1026,9 @@ [webView addMessageHandler:^(NSDictionary* payload) { - NSLog(@"message handler payload received =\n%@", payload); + NSLog(@"webview message handler payload received =\n%@", payload); } - forCommand:@"messageHandlerCommand"]; + forCommand:@"webViewMessageHandlerCommand"]; return webView; } @@ -1033,7 +1038,7 @@ [_webView removeObserver:self forKeyPath:@"canGoBack"]; [_webView removeObserver:self forKeyPath:@"canGoForward"]; [_webView removeObserver:self forKeyPath:@"loading"]; - [_webView removeMessageHandlerForCommand:@"messageHandlerCommand"]; + [_webView removeMessageHandlerForCommand:@"webViewMessageHandlerCommand"]; _webView = nil; } @@ -1042,7 +1047,7 @@ [_webView removeObserver:self forKeyPath:@"canGoBack"]; [_webView removeObserver:self forKeyPath:@"canGoForward"]; [_webView removeObserver:self forKeyPath:@"loading"]; - [_webView removeMessageHandlerForCommand:@"messageHandlerCommand"]; + [_webView removeMessageHandlerForCommand:@"webViewMessageHandlerCommand"]; } - (BOOL)textFieldShouldReturn:(UITextField*)field {
diff --git a/media/cast/sender/audio_sender_unittest.cc b/media/cast/sender/audio_sender_unittest.cc index bb08d45..96ce25e9 100644 --- a/media/cast/sender/audio_sender_unittest.cc +++ b/media/cast/sender/audio_sender_unittest.cc
@@ -94,12 +94,16 @@ class AudioSenderTest : public ::testing::Test { protected: - AudioSenderTest() { + AudioSenderTest() + : task_runner_( + base::MakeRefCounted<FakeSingleThreadTaskRunner>(&testing_clock_)), + cast_environment_(base::MakeRefCounted<CastEnvironment>(&testing_clock_, + task_runner_, + task_runner_, + task_runner_)) { InitializeMediaLibrary(); testing_clock_.Advance(base::TimeTicks::Now() - base::TimeTicks()); - task_runner_ = new FakeSingleThreadTaskRunner(&testing_clock_); - cast_environment_ = new CastEnvironment(&testing_clock_, task_runner_, - task_runner_, task_runner_); + audio_config_.codec = CODEC_AUDIO_OPUS; audio_config_.use_hardware_encoder = false; audio_config_.rtp_timebase = kDefaultAudioSamplingRate; @@ -107,10 +111,12 @@ audio_config_.max_bitrate = kDefaultAudioEncoderBitrate; audio_config_.rtp_payload_type = RtpPayloadType::AUDIO_OPUS; - transport_ = new TestPacketSender(); + auto sender = std::make_unique<TestPacketSender>(); + transport_ = sender.get(); transport_sender_ = std::make_unique<CastTransportImpl>( &testing_clock_, base::TimeDelta(), std::make_unique<TransportClient>(), - base::WrapUnique(transport_.get()), task_runner_); + std::move(sender), task_runner_); + OperationalStatus operational_status = STATUS_UNINITIALIZED; audio_sender_ = std::make_unique<AudioSender>( cast_environment_, audio_config_, @@ -123,11 +129,11 @@ ~AudioSenderTest() override = default; base::SimpleTestTickClock testing_clock_; - raw_ptr<TestPacketSender> transport_; // Owned by CastTransport. + const scoped_refptr<FakeSingleThreadTaskRunner> task_runner_; + const scoped_refptr<CastEnvironment> cast_environment_; std::unique_ptr<CastTransportImpl> transport_sender_; - scoped_refptr<FakeSingleThreadTaskRunner> task_runner_; + raw_ptr<TestPacketSender> transport_; // Owned by CastTransport. std::unique_ptr<AudioSender> audio_sender_; - scoped_refptr<CastEnvironment> cast_environment_; FrameSenderConfig audio_config_; };
diff --git a/media/cast/sender/video_sender_unittest.cc b/media/cast/sender/video_sender_unittest.cc index a4a9a5f9..d4f340e 100644 --- a/media/cast/sender/video_sender_unittest.cc +++ b/media/cast/sender/video_sender_unittest.cc
@@ -176,10 +176,11 @@ testing_clock_.Advance(base::TimeTicks::Now() - base::TimeTicks()); vea_factory_.SetAutoRespond(true); last_pixel_value_ = kPixelValue; - transport_ = new TestPacketSender(); + auto sender = std::make_unique<TestPacketSender>(); + transport_ = sender.get(); transport_sender_ = std::make_unique<CastTransportImpl>( &testing_clock_, base::TimeDelta(), std::make_unique<TransportClient>(), - base::WrapUnique(transport_.get()), task_runner_); + std::move(sender), task_runner_); } ~VideoSenderTest() override = default; @@ -248,8 +249,8 @@ const scoped_refptr<CastEnvironment> cast_environment_; OperationalStatus operational_status_; FakeVideoEncodeAcceleratorFactory vea_factory_; - raw_ptr<TestPacketSender> transport_; // Owned by CastTransport. std::unique_ptr<CastTransportImpl> transport_sender_; + raw_ptr<TestPacketSender> transport_; // Owned by CastTransport. std::unique_ptr<PeerVideoSender> video_sender_; int last_pixel_value_; base::TimeTicks first_frame_timestamp_;
diff --git a/media/gpu/BUILD.gn b/media/gpu/BUILD.gn index 0d6d7f93..b686cae 100644 --- a/media/gpu/BUILD.gn +++ b/media/gpu/BUILD.gn
@@ -627,77 +627,6 @@ } } -# TODO(crbug.com/1006266): consider using |use_chromeos_video_acceleration|. -if (enable_av1_decoder && (use_v4l2_codec || use_vaapi)) { - test("video_decode_accelerator_tests") { - testonly = true - sources = [ "video_decode_accelerator_tests.cc" ] - data = [ "//media/test/data/" ] - deps = [ - ":buildflags", - "test:frame_file_writer", - "test:frame_validator", - "test:helpers", - "test:test_helpers", - "test:video_player", - "test:video_player_test_environment", - "//media:test_support", - "//testing/gtest", - ] - } - - test("video_decode_accelerator_perf_tests") { - testonly = true - sources = [ "video_decode_accelerator_perf_tests.cc" ] - data = [ "//media/test/data/" ] - deps = [ - ":buildflags", - "test:helpers", - "test:video_player", - "test:video_player_test_environment", - "//media:test_support", - "//sandbox/linux:sandbox_services", - "//testing/gtest", - ] - } - - test("video_encode_accelerator_tests") { - testonly = true - sources = [ "video_encode_accelerator_tests.cc" ] - data = [ "//media/test/data/" ] - deps = [ - ":buildflags", - ":common", - "test:frame_file_writer", - "test:frame_validator", - "test:helpers", - "test:test_helpers", - "test:video_encoder", - "test:video_encoder_test_environment", - "//media:test_support", - "//testing/gtest", - ] - } - - test("video_encode_accelerator_perf_tests") { - testonly = true - sources = [ "video_encode_accelerator_perf_tests.cc" ] - data = [ "//media/test/data/" ] - deps = [ - ":buildflags", - ":common", - "test:frame_validator", - "test:helpers", - "test:test_helpers", - "test:video_encoder", - "test:video_encoder_test_environment", - "test:video_encoder_test_environment", - "//media:test_support", - "//testing/gtest", - ] - } -} - if (enable_hevc_parser_and_hw_decoder) { fuzzer_test("media_h265_decoder_fuzzer") { sources = [ "h265_decoder_fuzzertest.cc" ]
diff --git a/media/gpu/test/BUILD.gn b/media/gpu/test/BUILD.gn index 6c2eba6c..9beb7f7 100644 --- a/media/gpu/test/BUILD.gn +++ b/media/gpu/test/BUILD.gn
@@ -5,6 +5,78 @@ import("//build/config/chromeos/ui_mode.gni") import("//build/config/ui.gni") import("//media/gpu/args.gni") +import("//media/media_options.gni") + +# TODO(crbug.com/1006266): consider using |use_chromeos_video_acceleration|. +if (enable_av1_decoder && (use_v4l2_codec || use_vaapi)) { + test("video_decode_accelerator_tests") { + testonly = true + sources = [ "video_decode_accelerator_tests.cc" ] + data = [ "//media/test/data/" ] + deps = [ + ":frame_file_writer", + ":frame_validator", + ":helpers", + ":test_helpers", + ":video_player", + ":video_player_test_environment", + "//media:test_support", + "//media/gpu:buildflags", + "//testing/gtest", + ] + } + + test("video_decode_accelerator_perf_tests") { + testonly = true + sources = [ "video_decode_accelerator_perf_tests.cc" ] + data = [ "//media/test/data/" ] + deps = [ + ":helpers", + ":video_player", + ":video_player_test_environment", + "//media:test_support", + "//media/gpu:buildflags", + "//sandbox/linux:sandbox_services", + "//testing/gtest", + ] + } + + test("video_encode_accelerator_tests") { + testonly = true + sources = [ "video_encode_accelerator_tests.cc" ] + data = [ "//media/test/data/" ] + deps = [ + ":frame_file_writer", + ":frame_validator", + ":helpers", + ":test_helpers", + ":video_encoder", + ":video_encoder_test_environment", + "//media:test_support", + "//media/gpu:buildflags", + "//media/gpu:common", + "//testing/gtest", + ] + } + + test("video_encode_accelerator_perf_tests") { + testonly = true + sources = [ "video_encode_accelerator_perf_tests.cc" ] + data = [ "//media/test/data/" ] + deps = [ + ":frame_validator", + ":helpers", + ":test_helpers", + ":video_encoder", + ":video_encoder_test_environment", + ":video_encoder_test_environment", + "//media:test_support", + "//media/gpu:buildflags", + "//media/gpu:common", + "//testing/gtest", + ] + } +} source_set("helpers") { testonly = true
diff --git a/media/gpu/video_decode_accelerator_perf_tests.cc b/media/gpu/test/video_decode_accelerator_perf_tests.cc similarity index 100% rename from media/gpu/video_decode_accelerator_perf_tests.cc rename to media/gpu/test/video_decode_accelerator_perf_tests.cc
diff --git a/media/gpu/video_decode_accelerator_tests.cc b/media/gpu/test/video_decode_accelerator_tests.cc similarity index 100% rename from media/gpu/video_decode_accelerator_tests.cc rename to media/gpu/test/video_decode_accelerator_tests.cc
diff --git a/media/gpu/video_encode_accelerator_perf_tests.cc b/media/gpu/test/video_encode_accelerator_perf_tests.cc similarity index 100% rename from media/gpu/video_encode_accelerator_perf_tests.cc rename to media/gpu/test/video_encode_accelerator_perf_tests.cc
diff --git a/media/gpu/video_encode_accelerator_tests.cc b/media/gpu/test/video_encode_accelerator_tests.cc similarity index 100% rename from media/gpu/video_encode_accelerator_tests.cc rename to media/gpu/test/video_encode_accelerator_tests.cc
diff --git a/remoting/protocol/webrtc_video_stream.cc b/remoting/protocol/webrtc_video_stream.cc index ff44c45d..e84ad7c 100644 --- a/remoting/protocol/webrtc_video_stream.cc +++ b/remoting/protocol/webrtc_video_stream.cc
@@ -302,8 +302,8 @@ base::BindRepeating(&WebrtcVideoStream::OnSinkAddedOrUpdated, weak_factory_.GetWeakPtr())); rtc::scoped_refptr<webrtc::VideoTrackInterface> video_track = - peer_connection_factory->CreateVideoTrack(stream_name_, - video_track_source_.get()); + peer_connection_factory->CreateVideoTrack(video_track_source_, + stream_name_); webrtc::RtpTransceiverInit init; init.stream_ids = {stream_name_};
diff --git a/services/network/oblivious_http_request_handler.cc b/services/network/oblivious_http_request_handler.cc index a9d8bba1..c38af5a0 100644 --- a/services/network/oblivious_http_request_handler.cc +++ b/services/network/oblivious_http_request_handler.cc
@@ -13,6 +13,7 @@ #include "net/base/load_flags.h" #include "net/http/http_request_headers.h" #include "net/http/http_status_code.h" +#include "net/http/http_util.h" #include "net/log/net_log_capture_mode.h" #include "net/log/net_log_values.h" #include "net/log/net_log_with_source.h" @@ -27,6 +28,7 @@ #include "services/network/public/mojom/clear_data_filter.mojom.h" #include "services/network/public/mojom/oblivious_http_request.mojom.h" #include "services/network/public/mojom/url_loader_factory.mojom.h" +#include "services/network/public/mojom/url_response_head.mojom.h" #include "services/network/trust_tokens/trust_token_request_helper_factory.h" namespace network { @@ -43,8 +45,6 @@ 5 * 1024 * 1024; // Request size limit is 5MB constexpr size_t kMaxContentTypeSize = 256; // Per RFC6838 -const std::array<char, 2> kHeaderForbiddenChars = {'\n', '\r'}; - // Class wrapping quiche::ObliviousHttpClient. Should be created once for each // request/response pair. class StatefulObliviousHttpClient { @@ -133,6 +133,19 @@ return bhttp_request.Serialize().value(); } +scoped_refptr<net::HttpResponseHeaders> GetSyntheticBhttpResponseHeader( + const std::vector<quiche::BinaryHttpRequest::Field>& bhttp_headers) { + std::string synthetic_headers = "HTTP/1.1 200 Success\r\n"; + for (const auto& header : bhttp_headers) { + if (!net::HttpUtil::IsValidHeaderName(header.name) || + !net::HttpUtil::IsValidHeaderValue(header.value)) { + return nullptr; + } + synthetic_headers += header.name + ": " + header.value + "\r\n"; + } + return net::HttpResponseHeaders::TryToCreate(synthetic_headers); +} + } // namespace class ObliviousHttpRequestHandler::RequestState { @@ -242,7 +255,8 @@ mojo::RemoteSetElementId id, TrustTokenStatusOrRequestHelper status_or_helper) { if (!status_or_helper.ok()) { - RespondWithError(id, net::ERR_TRUST_TOKEN_OPERATION_FAILED); + RespondWithError(id, net::ERR_TRUST_TOKEN_OPERATION_FAILED, + /*outer_response_error_code=*/absl::nullopt); return; } @@ -264,7 +278,8 @@ absl::optional<net::HttpRequestHeaders> headers, mojom::TrustTokenOperationStatus status) { if (status != mojom::TrustTokenOperationStatus::kOk) { - RespondWithError(id, net::ERR_TRUST_TOKEN_OPERATION_FAILED); + RespondWithError(id, net::ERR_TRUST_TOKEN_OPERATION_FAILED, + /*outer_response_error_code=*/absl::nullopt); return; } ContinueHandlingRequest(std::move(headers), id); @@ -329,14 +344,16 @@ auto maybe_client = StatefulObliviousHttpClient::CreateFromKeyConfig( std::move(state->request->key_config)); if (!maybe_client) { - RespondWithError(id, net::ERR_INVALID_ARGUMENT); + RespondWithError(id, net::ERR_INVALID_ARGUMENT, + /*outer_response_error_code=*/absl::nullopt); return; } state->ohttp_client = std::move(maybe_client); auto maybe_encrypted_blob = state->ohttp_client->EncryptRequest(std::move(padded_payload)); if (!maybe_encrypted_blob) { - RespondWithError(id, net::ERR_FAILED); + RespondWithError(id, net::ERR_FAILED, + /*outer_response_error_code=*/absl::nullopt); return; } @@ -363,8 +380,10 @@ kMaxResponseSize); } -void ObliviousHttpRequestHandler::RespondWithError(mojo::RemoteSetElementId id, - int error_code) { +void ObliviousHttpRequestHandler::RespondWithError( + mojo::RemoteSetElementId id, + int error_code, + absl::optional<int> outer_response_error_code) { mojom::ObliviousHttpClient* client = clients_.Get(id); auto state_iter = client_state_.find(id); DCHECK(client); @@ -372,7 +391,18 @@ RequestState* state = state_iter->second.get(); state->net_log.EndEventWithIntParams( net::NetLogEventType::OBLIVIOUS_HTTP_REQUEST_END, "status", error_code); - client->OnCompleted(absl::nullopt, error_code); + + network::mojom::ObliviousHttpCompletionResultPtr response_result; + if (outer_response_error_code) { + DCHECK_NE(outer_response_error_code.value(), net::HTTP_OK); + response_result = network::mojom::ObliviousHttpCompletionResult:: + NewOuterResponseErrorCode(outer_response_error_code.value()); + } else { + response_result = + network::mojom::ObliviousHttpCompletionResult::NewNetError(error_code); + } + + client->OnCompleted(std::move(response_result)); clients_.Remove(id); DCHECK_EQ(1u, client_state_.count(id)); @@ -387,14 +417,22 @@ RequestState* state = state_iter->second.get(); if (!response) { - RespondWithError(id, state->loader->NetError()); + absl::optional<int> outer_response_error_code; + if (state->loader->NetError() == net::ERR_HTTP_RESPONSE_CODE_FAILURE && + state->loader->ResponseInfo() && + state->loader->ResponseInfo()->headers) { + outer_response_error_code = + state->loader->ResponseInfo()->headers->response_code(); + } + RespondWithError(id, state->loader->NetError(), outer_response_error_code); return; } auto maybe_payload = state->ohttp_client->DecryptResponse(std::move(*response)); if (!maybe_payload) { - RespondWithError(id, net::ERR_FAILED); + RespondWithError(id, net::ERR_INVALID_RESPONSE, + /*outer_response_error_code=*/absl::nullopt); return; } @@ -410,67 +448,70 @@ return dict; }); + // Parse the inner request. auto bhttp_response = quiche::BinaryHttpResponse::Create(*maybe_payload); if (!bhttp_response.ok()) { - RespondWithError(id, net::ERR_FAILED); + RespondWithError(id, net::ERR_INVALID_RESPONSE, + /*outer_response_error_code=*/absl::nullopt); return; } - // Check that the inner request was successful. - int status_code = bhttp_response->status_code(); - if (status_code / 100 != 2) { - RespondWithError(id, net::ERR_HTTP_RESPONSE_CODE_FAILURE); + int inner_status_code = bhttp_response->status_code(); + scoped_refptr<net::HttpResponseHeaders> headers = + GetSyntheticBhttpResponseHeader(bhttp_response->GetHeaderFields()); + // Check that the header is valid. + if (!headers) { + RespondWithError(id, net::ERR_INVALID_RESPONSE, + /*outer_response_error_code=*/absl::nullopt); return; } if (state->trust_token_helper) { - std::string synthetic_headers = "HTTP/1.1 200 Success\r\n"; - for (const auto& header : bhttp_response->GetHeaderFields()) { - // Header names and values can not contain embedded newlines. The rest of - // the constraints are handled by HttpResponseHeaders::TryToCreate. - if (base::ranges::find_first_of(header.name, kHeaderForbiddenChars) != - header.name.end() || - base::ranges::find_first_of(header.value, kHeaderForbiddenChars) != - header.value.end()) { - // Invalid header value - RespondWithError(id, net::ERR_INVALID_RESPONSE); - } - synthetic_headers += header.name + ": " + header.value + "\r\n"; - } - scoped_refptr<net::HttpResponseHeaders> headers = - net::HttpResponseHeaders::TryToCreate(synthetic_headers); - if (!headers) { - RespondWithError(id, net::ERR_INVALID_RESPONSE); - return; - } state->trust_token_helper->Finalize( *headers, base::BindOnce( &ObliviousHttpRequestHandler::OnDoneFinalizingTrustTokenOperation, - base::Unretained(this), id, std::string(bhttp_response->body()))); + base::Unretained(this), id, inner_status_code, std::move(headers), + std::string(bhttp_response->body()))); return; } - NotifyComplete(id, std::string(bhttp_response->body())); + NotifyComplete(id, inner_status_code, std::move(headers), + std::string(bhttp_response->body())); } void ObliviousHttpRequestHandler::OnDoneFinalizingTrustTokenOperation( mojo::RemoteSetElementId id, + int inner_response_code, + scoped_refptr<net::HttpResponseHeaders> headers, std::string body, mojom::TrustTokenOperationStatus status) { if (status != mojom::TrustTokenOperationStatus::kOk) { - RespondWithError(id, net::ERR_TRUST_TOKEN_OPERATION_FAILED); + RespondWithError(id, net::ERR_TRUST_TOKEN_OPERATION_FAILED, + /*outer_response_error_code=*/absl::nullopt); return; } - NotifyComplete(id, std::move(body)); + NotifyComplete(id, inner_response_code, std::move(headers), std::move(body)); } -void ObliviousHttpRequestHandler::NotifyComplete(mojo::RemoteSetElementId id, - std::string body) { +void ObliviousHttpRequestHandler::NotifyComplete( + mojo::RemoteSetElementId id, + int inner_response_code, + scoped_refptr<net::HttpResponseHeaders> headers, + std::string body) { mojom::ObliviousHttpClient* client = clients_.Get(id); DCHECK(client); - client->OnCompleted(std::move(body), net::OK); + network::mojom::ObliviousHttpResponsePtr response = + network::mojom::ObliviousHttpResponse::New(); + response->response_code = inner_response_code; + response->response_body = std::move(body); + response->headers = std::move(headers); + network::mojom::ObliviousHttpCompletionResultPtr response_result = + network::mojom::ObliviousHttpCompletionResult::NewInnerResponse( + std::move(response)); + + client->OnCompleted(std::move(response_result)); clients_.Remove(id); client_state_.erase(id); }
diff --git a/services/network/oblivious_http_request_handler.h b/services/network/oblivious_http_request_handler.h index 916529c..ee63858 100644 --- a/services/network/oblivious_http_request_handler.h +++ b/services/network/oblivious_http_request_handler.h
@@ -76,10 +76,12 @@ void ContinueHandlingRequest(absl::optional<net::HttpRequestHeaders> headers, mojo::RemoteSetElementId id); - // Calls the completed event with the specified error code on the - // corresponding client. The client with the specified id must be in the - // `clients_` set and the `client_state_` map. - void RespondWithError(mojo::RemoteSetElementId id, int error_code); + // Calls the completed event with the specified net error code and HTTP + // response error code on the corresponding client. The client with the + // specified id must be in the `clients_` set and the `client_state_` map. + void RespondWithError(mojo::RemoteSetElementId id, + int error_code, + absl::optional<int> outer_response_error_code); // Called by the SimpleURLLoader when the outer request has completed. // Performs steps 5 and 6 of the OHTTP request procedure above. @@ -91,12 +93,17 @@ // result. void OnDoneFinalizingTrustTokenOperation( mojo::RemoteSetElementId id, + int inner_response_code, + scoped_refptr<net::HttpResponseHeaders> headers, std::string body, mojom::TrustTokenOperationStatus status); // Notifies the client that the request completed successfully with the - // provided response body. - void NotifyComplete(mojo::RemoteSetElementId id, std::string body); + // provided response headers and body. + void NotifyComplete(mojo::RemoteSetElementId id, + int inner_response_code, + scoped_refptr<net::HttpResponseHeaders> headers, + std::string body); // Handles cleaning up when an ObliviousHttpClient disconnects. void OnClientDisconnect(mojo::RemoteSetElementId id);
diff --git a/services/network/oblivious_http_request_handler_unittest.cc b/services/network/oblivious_http_request_handler_unittest.cc index 33260fa5..708b034 100644 --- a/services/network/oblivious_http_request_handler_unittest.cc +++ b/services/network/oblivious_http_request_handler_unittest.cc
@@ -66,29 +66,81 @@ class TestOhttpClient : public network::mojom::ObliviousHttpClient { public: - TestOhttpClient(absl::optional<std::string> expected_body, - int expected_status) - : expected_body_(std::move(expected_body)), - expected_status_(expected_status), - receiver_(this) {} + enum class ResponseType { kSuccess, kNetError, kOuterResponseErrorCode }; + + TestOhttpClient() : receiver_(this) {} + + void SetExpectedNetError(int expected_net_error) { + expected_response_type_ = ResponseType::kNetError; + expected_net_error_ = expected_net_error; + } + + void SetExpectedOuterResponseErrorCode( + int expected_outer_response_error_code) { + expected_response_type_ = ResponseType::kOuterResponseErrorCode; + expected_outer_response_error_code_ = expected_outer_response_error_code; + } + + void SetExpectedInnerResponse( + int expected_inner_response_code, + std::string expected_body, + std::multimap<std::string, std::string> expected_headers) { + expected_response_type_ = ResponseType::kSuccess; + expected_inner_response_code_ = expected_inner_response_code; + expected_body_ = expected_body; + expected_headers_ = std::move(expected_headers); + } mojo::PendingRemote<network::mojom::ObliviousHttpClient> CreatePendingRemote() { return receiver_.BindNewPipeAndPassRemote(); } - void OnCompleted(const absl::optional<std::string>& response, - int net_error) override { - EXPECT_EQ(expected_body_, response); - EXPECT_EQ(expected_status_, net_error); + void OnCompleted( + network::mojom::ObliviousHttpCompletionResultPtr status) override { + switch (expected_response_type_) { + case ResponseType::kSuccess: { + ASSERT_TRUE(status->is_inner_response()); + EXPECT_EQ(expected_inner_response_code_, + status->get_inner_response()->response_code); + EXPECT_EQ(expected_body_, status->get_inner_response()->response_body); + // Verify headers. + size_t iter = 0; + std::string name; + std::string value; + std::multimap<std::string, std::string> actual_headers; + while (status->get_inner_response()->headers->EnumerateHeaderLines( + &iter, &name, &value)) { + actual_headers.insert( + std::pair<std::string, std::string>(name, value)); + } + EXPECT_EQ(expected_headers_, actual_headers); + break; + } + case ResponseType::kNetError: { + ASSERT_TRUE(status->is_net_error()); + EXPECT_EQ(expected_net_error_, status->get_net_error()); + break; + } + case ResponseType::kOuterResponseErrorCode: { + ASSERT_TRUE(status->is_outer_response_error_code()); + EXPECT_EQ(expected_outer_response_error_code_, + status->get_outer_response_error_code()); + break; + } + } run_loop_.Quit(); } void WaitForCall() { run_loop_.Run(); } private: - const absl::optional<std::string> expected_body_; - const int expected_status_; + ResponseType expected_response_type_; + int expected_inner_response_code_ = 0; + std::string expected_body_; + std::multimap<std::string, std::string> expected_headers_; + int expected_outer_response_error_code_ = 0; + int expected_net_error_ = 0; mojo::Receiver<network::mojom::ObliviousHttpClient> receiver_; base::RunLoop run_loop_; }; @@ -142,6 +194,7 @@ } void RespondToPendingRequest(std::string body, + std::multimap<std::string, std::string> headers, GURL relay_url = GURL(kRelayURL), net::HttpStatusCode status = net::HTTP_OK) { const network::ResourceRequest* pending_request; @@ -163,6 +216,9 @@ quiche::BinaryHttpResponse bhttp_response(status); bhttp_response.set_body(std::move(body)); + for (auto kv : headers) { + bhttp_response.AddHeaderField({kv.first, kv.second}); + } auto payload = bhttp_response.Serialize(); ASSERT_TRUE(payload.ok()) << payload.status(); @@ -227,22 +283,34 @@ std::unique_ptr<network::ObliviousHttpRequestHandler> handler = CreateHandler(); { - TestOhttpClient client("", net::OK); + TestOhttpClient client; + client.SetExpectedInnerResponse( + /*expected_inner_response_code=*/net::HTTP_OK, + /*expected_body=*/"", + /*expected_headers=*/{}); handler->StartRequest(CreateRequest(), client.CreatePendingRemote()); } { - TestOhttpClient client("", net::OK); + TestOhttpClient client; + client.SetExpectedInnerResponse( + /*expected_inner_response_code=*/net::HTTP_OK, + /*expected_body=*/"", + /*expected_headers=*/{}); handler->StartRequest(CreateRequest(), client.CreatePendingRemote()); - RespondToPendingRequest(""); + RespondToPendingRequest("", {}); client.WaitForCall(); } // Empty body { - TestOhttpClient client("", net::OK); + TestOhttpClient client; + client.SetExpectedInnerResponse( + /*expected_inner_response_code=*/net::HTTP_OK, + /*expected_body=*/"", + /*expected_headers=*/{}); handler->StartRequest(CreateRequestWithoutBody(), client.CreatePendingRemote()); - RespondToPendingRequest(""); + RespondToPendingRequest("", {}); client.WaitForCall(); } } @@ -253,7 +321,8 @@ { mojo::FakeMessageDispatchContext context; mojo::test::BadMessageObserver obs; - TestOhttpClient client(absl::nullopt, net::ERR_INVALID_URL); + TestOhttpClient client; + client.SetExpectedNetError(net::ERR_INVALID_URL); network::mojom::ObliviousHttpRequestPtr request = network::mojom::ObliviousHttpRequest::New(); @@ -263,7 +332,8 @@ { mojo::FakeMessageDispatchContext context; mojo::test::BadMessageObserver obs; - TestOhttpClient client(absl::nullopt, net::ERR_INVALID_URL); + TestOhttpClient client; + client.SetExpectedNetError(net::ERR_INVALID_URL); network::mojom::ObliviousHttpRequestPtr request = CreateRequest(); request->relay_url = GURL(); @@ -273,7 +343,8 @@ { mojo::FakeMessageDispatchContext context; mojo::test::BadMessageObserver obs; - TestOhttpClient client(absl::nullopt, net::ERR_INVALID_URL); + TestOhttpClient client; + client.SetExpectedNetError(net::ERR_INVALID_URL); network::mojom::ObliviousHttpRequestPtr request = CreateRequest(); request->resource_url = GURL(); @@ -283,7 +354,8 @@ { mojo::FakeMessageDispatchContext context; mojo::test::BadMessageObserver obs; - TestOhttpClient client(absl::nullopt, net::ERR_INVALID_ARGUMENT); + TestOhttpClient client; + client.SetExpectedNetError(net::ERR_INVALID_ARGUMENT); network::mojom::ObliviousHttpRequestPtr request = CreateRequest(); request->traffic_annotation = net::MutableNetworkTrafficAnnotationTag(); @@ -293,7 +365,8 @@ { mojo::FakeMessageDispatchContext context; mojo::test::BadMessageObserver obs; - TestOhttpClient client(absl::nullopt, net::ERR_INVALID_ARGUMENT); + TestOhttpClient client; + client.SetExpectedNetError(net::ERR_INVALID_ARGUMENT); network::mojom::ObliviousHttpRequestPtr request = CreateRequest(); request->method = std::string(17, 'A'); @@ -303,7 +376,8 @@ { mojo::FakeMessageDispatchContext context; mojo::test::BadMessageObserver obs; - TestOhttpClient client(absl::nullopt, net::ERR_INVALID_ARGUMENT); + TestOhttpClient client; + client.SetExpectedNetError(net::ERR_INVALID_ARGUMENT); network::mojom::ObliviousHttpRequestPtr request = CreateRequest(); request->request_body->content = std::string(5 * 1024 * 1024 + 1, ' '); @@ -313,7 +387,8 @@ { mojo::FakeMessageDispatchContext context; mojo::test::BadMessageObserver obs; - TestOhttpClient client(absl::nullopt, net::ERR_INVALID_ARGUMENT); + TestOhttpClient client; + client.SetExpectedNetError(net::ERR_INVALID_ARGUMENT); network::mojom::ObliviousHttpRequestPtr request = CreateRequest(); request->request_body->content_type = std::string(257, ' '); @@ -326,7 +401,12 @@ std::unique_ptr<network::ObliviousHttpRequestHandler> handler = CreateHandler(); { - TestOhttpClient client("response body", net::OK); + TestOhttpClient client; + client.SetExpectedInnerResponse( + /*expected_inner_response_code=*/net::HTTP_OK, + /*expected_body=*/"response body", + /*expected_headers=*/ + {{"cache-control", "s-maxage=3600"}, {"content-type", "text/html"}}); handler->StartRequest(CreateRequest(), client.CreatePendingRemote()); const network::ResourceRequest* pending_request; @@ -366,7 +446,9 @@ {"content-type", "application/testdata"}, })); EXPECT_EQ(request.body(), "test data"); - RespondToPendingRequest("response body"); + RespondToPendingRequest( + "response body", + {{"cache-control", "s-maxage=3600"}, {"content-type", "text/html"}}); client.WaitForCall(); } } @@ -376,7 +458,23 @@ CreateHandler(); { loader_factory()->AddResponse(kRelayURL, "", net::HTTP_NOT_FOUND); - TestOhttpClient client(absl::nullopt, net::ERR_HTTP_RESPONSE_CODE_FAILURE); + TestOhttpClient client; + client.SetExpectedOuterResponseErrorCode(net::HTTP_NOT_FOUND); + + handler->StartRequest(CreateRequest(), client.CreatePendingRemote()); + client.WaitForCall(); + } + { + loader_factory()->AddResponse( + GURL(kRelayURL), network::CreateURLResponseHead(net::HTTP_OK), "", + network::URLLoaderCompletionStatus(net::ERR_CONNECTION_RESET), + network::TestURLLoaderFactory::Redirects(), + network::TestURLLoaderFactory::ResponseProduceFlags:: + kSendHeadersOnNetworkError); + TestOhttpClient client; + // The outer HTTP error code should be set only when the net error is + // ERR_HTTP_RESPONSE_CODE_FAILURE. Otherwise, log the net error instead. + client.SetExpectedNetError(net::ERR_CONNECTION_RESET); handler->StartRequest(CreateRequest(), client.CreatePendingRemote()); client.WaitForCall(); @@ -387,10 +485,29 @@ std::unique_ptr<network::ObliviousHttpRequestHandler> handler = CreateHandler(); { - TestOhttpClient client(absl::nullopt, net::ERR_HTTP_RESPONSE_CODE_FAILURE); + TestOhttpClient client; + client.SetExpectedInnerResponse( + /*expected_inner_response_code=*/net::HTTP_NOT_FOUND, + /*expected_body=*/"", + /*expected_headers=*/ + {{"cache-control", "s-maxage=60"}}); handler->StartRequest(CreateRequest(), client.CreatePendingRemote()); - RespondToPendingRequest("", GURL(kRelayURL), net::HTTP_NOT_FOUND); + RespondToPendingRequest("", {{"cache-control", "s-maxage=60"}}, + GURL(kRelayURL), net::HTTP_NOT_FOUND); + client.WaitForCall(); + } + { + TestOhttpClient client; + client.SetExpectedNetError(net::ERR_INVALID_RESPONSE); + + handler->StartRequest(CreateRequest(), client.CreatePendingRemote()); + ASSERT_TRUE(loader_factory()->IsPending(kRelayURL)); + EXPECT_TRUE(loader_factory()->SimulateResponseForPendingRequest( + /*url=*/GURL(kRelayURL), + /*completion_status=*/network::URLLoaderCompletionStatus(), + /*response_head=*/network::CreateURLResponseHead(net::HTTP_OK), + /*content=*/"malformed inner response")); client.WaitForCall(); } } @@ -399,19 +516,28 @@ std::unique_ptr<network::ObliviousHttpRequestHandler> handler = CreateHandler(); { - TestOhttpClient client_a("Response a", net::OK); + TestOhttpClient client_a; + client_a.SetExpectedInnerResponse( + /*expected_inner_response_code=*/net::HTTP_OK, + /*expected_body=*/"Response a", + /*expected_headers=*/{{"cache-control", "s-maxage=60"}}); network::mojom::ObliviousHttpRequestPtr request_a = CreateRequest(); - TestOhttpClient client_b("Response b", net::OK); + TestOhttpClient client_b; + client_b.SetExpectedInnerResponse( + /*expected_inner_response_code=*/net::HTTP_OK, + /*expected_body=*/"Response b", + /*expected_headers=*/{{"cache-control", "s-maxage=600"}}); network::mojom::ObliviousHttpRequestPtr request_b = CreateRequest(); request_b->relay_url = GURL("https://another.relay.test"); handler->StartRequest(std::move(request_a), client_a.CreatePendingRemote()); handler->StartRequest(std::move(request_b), client_b.CreatePendingRemote()); - RespondToPendingRequest("Response b", GURL("https://another.relay.test")); + RespondToPendingRequest("Response b", {{"cache-control", "s-maxage=600"}}, + GURL("https://another.relay.test")); client_b.WaitForCall(); - RespondToPendingRequest("Response a"); + RespondToPendingRequest("Response a", {{"cache-control", "s-maxage=60"}}); client_a.WaitForCall(); } } @@ -420,7 +546,11 @@ std::unique_ptr<network::ObliviousHttpRequestHandler> handler = CreateHandler(); { - TestOhttpClient client("response body", net::OK); + TestOhttpClient client; + client.SetExpectedInnerResponse( + /*expected_inner_response_code=*/net::HTTP_OK, + /*expected_body=*/"response body", + /*expected_headers=*/{}); network::mojom::ObliviousHttpRequestPtr request = CreateRequest(); request->padding_params = network::mojom::ObliviousHttpPaddingParameters::New( @@ -448,7 +578,11 @@ std::unique_ptr<network::ObliviousHttpRequestHandler> handler = CreateHandler(); { - TestOhttpClient client("response body", net::OK); + TestOhttpClient client; + client.SetExpectedInnerResponse( + /*expected_inner_response_code=*/net::HTTP_OK, + /*expected_body=*/"response body", + /*expected_headers=*/{}); network::mojom::ObliviousHttpRequestPtr request = CreateRequest(); request->padding_params = network::mojom::ObliviousHttpPaddingParameters::New( @@ -483,7 +617,11 @@ double accum_size_squared = 0; for (size_t i = 0; i < kNumRuns; i++) { { - TestOhttpClient client("response body", net::OK); + TestOhttpClient client; + client.SetExpectedInnerResponse( + /*expected_inner_response_code=*/net::HTTP_OK, + /*expected_body=*/"response body", + /*expected_headers=*/{}); network::mojom::ObliviousHttpRequestPtr request = CreateRequest(); request->padding_params = network::mojom::ObliviousHttpPaddingParameters::New( @@ -522,7 +660,11 @@ CreateHandler(); base::flat_set<size_t> sizes_seen; while (sizes_seen.size() < 2) { - TestOhttpClient client("response body", net::OK); + TestOhttpClient client; + client.SetExpectedInnerResponse( + /*expected_inner_response_code=*/net::HTTP_OK, + /*expected_body=*/"response body", + /*expected_headers=*/{}); network::mojom::ObliviousHttpRequestPtr request = CreateRequest(); request->padding_params = network::mojom::ObliviousHttpPaddingParameters::New(
diff --git a/services/network/public/mojom/oblivious_http_request.mojom b/services/network/public/mojom/oblivious_http_request.mojom index f1490cb..24a40c9 100644 --- a/services/network/public/mojom/oblivious_http_request.mojom +++ b/services/network/public/mojom/oblivious_http_request.mojom
@@ -7,6 +7,7 @@ import "services/network/public/mojom/isolation_info.mojom"; import "services/network/public/mojom/mutable_network_traffic_annotation_tag.mojom"; +import "services/network/public/mojom/network_param.mojom"; import "services/network/public/mojom/trust_tokens.mojom"; import "url/mojom/url.mojom"; @@ -17,6 +18,33 @@ string content_type; }; +// The inner response wrapped in binary HTTP from the OHTTP gateway. +struct ObliviousHttpResponse { + // The response code of the inner gateway HTTP response. + int32 response_code; + // The headers of the inner gateway HTTP response. It should only be used to + // get header values. To get the response code, use `response_code` instead. + HttpResponseHeaders headers; + // The response code of the inner gateway HTTP response. It is empty if + // `response_code` is non-200. + string response_body; +}; + +// The structure used to deliver result to Oblivious HTTP clients. +union ObliviousHttpCompletionResult { + // A general net::Error code in case of failure. If the result is net::OK, one + // of the other fields in the union will be populated. + int32 net_error; + // The response code of the outer relay HTTP response, used to wrap the binary + // HTTP (bHTTP) response. This is set iff the result fails because the outer + // HTTP response status code is not HTTP_OK (200). The value will never be + // 200. + int32 outer_response_error_code; + // The inner gateway HTTP response. Parsed out from the binary HTTP (bHTTP) + // structure. + ObliviousHttpResponse inner_response; +}; + struct ObliviousHttpPaddingParameters { // Whether to add a random number of bytes following an exponential // probability distribution with mean `exponential_mean` extra bytes. @@ -57,8 +85,6 @@ // Callback interface for Oblivious HTTP Requests. interface ObliviousHttpClient { - // Called when the OHTTP request completes. `net_error` indicates the - // net::Error code for the operation. `response_body` will contain the body - // of the response. - OnCompleted(string? response_body, int32 net_error); + // Called when the OHTTP request completes. + OnCompleted(ObliviousHttpCompletionResult response); };
diff --git a/testing/buildbot/chromium.android.json b/testing/buildbot/chromium.android.json index 3b8236e..5f173e9 100644 --- a/testing/buildbot/chromium.android.json +++ b/testing/buildbot/chromium.android.json
@@ -11885,7 +11885,8 @@ "--gs-results-bucket=chromium-result-details", "--recover-devices", "--avd-config=../../tools/android/avd/proto/generic_android32_foldable.textpb", - "--git-revision=${got_revision}" + "--git-revision=${got_revision}", + "--test-launcher-filter-file=../../testing/buildbot/filters/android.emulator_12l.chrome_public_test_apk.filter" ], "merge": { "args": [
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json index 22268f8..946050d3 100644 --- a/testing/buildbot/chromium.fyi.json +++ b/testing/buildbot/chromium.fyi.json
@@ -20021,8518 +20021,6 @@ "ios15-sdk-simulator": { "additional_compile_targets": [ "all" - ], - "isolated_scripts": [ - { - "args": [ - "--platform", - "iPhone 6s", - "--version", - "14.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "absl_hardening_tests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "absl_hardening_tests iPhone 6s 14.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_14_5", - "path": "Runtime-ios-14.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://third_party/abseil-cpp:absl_hardening_tests/", - "variant_id": "iPhone 6s 14.5" - }, - { - "args": [ - "--platform", - "iPhone 6s", - "--version", - "15.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "absl_hardening_tests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "absl_hardening_tests iPhone 6s 15.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_15_5", - "path": "Runtime-ios-15.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://third_party/abseil-cpp:absl_hardening_tests/", - "variant_id": "iPhone 6s 15.5" - }, - { - "args": [ - "--platform", - "iPad Air 2", - "--version", - "14.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "base_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "base_unittests iPad Air 2 14.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_14_5", - "path": "Runtime-ios-14.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://base:base_unittests/", - "variant_id": "iPad Air 2 14.5" - }, - { - "args": [ - "--platform", - "iPad Air 2", - "--version", - "15.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "base_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "base_unittests iPad Air 2 15.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_15_5", - "path": "Runtime-ios-15.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://base:base_unittests/", - "variant_id": "iPad Air 2 15.5" - }, - { - "args": [ - "--platform", - "iPhone 6s", - "--version", - "14.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "base_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "base_unittests iPhone 6s 14.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_14_5", - "path": "Runtime-ios-14.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://base:base_unittests/", - "variant_id": "iPhone 6s 14.5" - }, - { - "args": [ - "--platform", - "iPhone 6s", - "--version", - "15.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "base_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "base_unittests iPhone 6s 15.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_15_5", - "path": "Runtime-ios-15.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://base:base_unittests/", - "variant_id": "iPhone 6s 15.5" - }, - { - "args": [ - "--platform", - "iPhone 6s Plus", - "--version", - "14.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "base_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "base_unittests iPhone 6s Plus 14.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_14_5", - "path": "Runtime-ios-14.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://base:base_unittests/", - "variant_id": "iPhone 6s Plus 14.5" - }, - { - "args": [ - "--platform", - "iPhone 6s Plus", - "--version", - "15.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "base_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "base_unittests iPhone 6s Plus 15.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_15_5", - "path": "Runtime-ios-15.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://base:base_unittests/", - "variant_id": "iPhone 6s Plus 15.5" - }, - { - "args": [ - "--platform", - "iPhone SE (1st generation)", - "--version", - "14.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "base_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "base_unittests iPhone SE (1st generation) 14.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_14_5", - "path": "Runtime-ios-14.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://base:base_unittests/", - "variant_id": "iPhone SE (1st generation) 14.5" - }, - { - "args": [ - "--platform", - "iPhone SE (1st generation)", - "--version", - "15.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "base_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "base_unittests iPhone SE (1st generation) 15.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_15_5", - "path": "Runtime-ios-15.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://base:base_unittests/", - "variant_id": "iPhone SE (1st generation) 15.5" - }, - { - "args": [ - "--platform", - "iPhone 6s", - "--version", - "14.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "boringssl_crypto_tests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "boringssl_crypto_tests iPhone 6s 14.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_14_5", - "path": "Runtime-ios-14.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://third_party/boringssl:boringssl_crypto_tests/", - "variant_id": "iPhone 6s 14.5" - }, - { - "args": [ - "--platform", - "iPhone 6s", - "--version", - "15.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "boringssl_crypto_tests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "boringssl_crypto_tests iPhone 6s 15.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_15_5", - "path": "Runtime-ios-15.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://third_party/boringssl:boringssl_crypto_tests/", - "variant_id": "iPhone 6s 15.5" - }, - { - "args": [ - "--platform", - "iPhone 6s", - "--version", - "14.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "boringssl_ssl_tests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "boringssl_ssl_tests iPhone 6s 14.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_14_5", - "path": "Runtime-ios-14.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://third_party/boringssl:boringssl_ssl_tests/", - "variant_id": "iPhone 6s 14.5" - }, - { - "args": [ - "--platform", - "iPhone 6s", - "--version", - "15.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "boringssl_ssl_tests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "boringssl_ssl_tests iPhone 6s 15.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_15_5", - "path": "Runtime-ios-15.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://third_party/boringssl:boringssl_ssl_tests/", - "variant_id": "iPhone 6s 15.5" - }, - { - "args": [ - "--platform", - "iPad Air 2", - "--version", - "14.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "components_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "components_unittests iPad Air 2 14.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_14_5", - "path": "Runtime-ios-14.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://components:components_unittests/", - "variant_id": "iPad Air 2 14.5" - }, - { - "args": [ - "--platform", - "iPad Air 2", - "--version", - "15.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "components_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "components_unittests iPad Air 2 15.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_15_5", - "path": "Runtime-ios-15.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://components:components_unittests/", - "variant_id": "iPad Air 2 15.5" - }, - { - "args": [ - "--platform", - "iPhone 6s", - "--version", - "14.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "components_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "components_unittests iPhone 6s 14.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_14_5", - "path": "Runtime-ios-14.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://components:components_unittests/", - "variant_id": "iPhone 6s 14.5" - }, - { - "args": [ - "--platform", - "iPhone 6s", - "--version", - "15.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "components_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "components_unittests iPhone 6s 15.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_15_5", - "path": "Runtime-ios-15.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://components:components_unittests/", - "variant_id": "iPhone 6s 15.5" - }, - { - "args": [ - "--platform", - "iPhone 6s Plus", - "--version", - "14.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "components_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "components_unittests iPhone 6s Plus 14.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_14_5", - "path": "Runtime-ios-14.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://components:components_unittests/", - "variant_id": "iPhone 6s Plus 14.5" - }, - { - "args": [ - "--platform", - "iPhone 6s Plus", - "--version", - "15.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "components_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "components_unittests iPhone 6s Plus 15.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_15_5", - "path": "Runtime-ios-15.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://components:components_unittests/", - "variant_id": "iPhone 6s Plus 15.5" - }, - { - "args": [ - "--platform", - "iPhone SE (1st generation)", - "--version", - "14.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "components_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "components_unittests iPhone SE (1st generation) 14.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_14_5", - "path": "Runtime-ios-14.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://components:components_unittests/", - "variant_id": "iPhone SE (1st generation) 14.5" - }, - { - "args": [ - "--platform", - "iPhone SE (1st generation)", - "--version", - "15.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "components_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "components_unittests iPhone SE (1st generation) 15.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_15_5", - "path": "Runtime-ios-15.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://components:components_unittests/", - "variant_id": "iPhone SE (1st generation) 15.5" - }, - { - "args": [ - "--platform", - "iPhone 6s", - "--version", - "14.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "crashpad_tests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "crashpad_tests iPhone 6s 14.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_14_5", - "path": "Runtime-ios-14.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://third_party/crashpad/crashpad:crashpad_tests/", - "variant_id": "iPhone 6s 14.5" - }, - { - "args": [ - "--platform", - "iPhone 6s", - "--version", - "15.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "crashpad_tests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "crashpad_tests iPhone 6s 15.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_15_5", - "path": "Runtime-ios-15.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://third_party/crashpad/crashpad:crashpad_tests/", - "variant_id": "iPhone 6s 15.5" - }, - { - "args": [ - "--platform", - "iPhone 6s", - "--version", - "14.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "crypto_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "crypto_unittests iPhone 6s 14.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_14_5", - "path": "Runtime-ios-14.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://crypto:crypto_unittests/", - "variant_id": "iPhone 6s 14.5" - }, - { - "args": [ - "--platform", - "iPhone 6s", - "--version", - "15.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "crypto_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "crypto_unittests iPhone 6s 15.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_15_5", - "path": "Runtime-ios-15.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://crypto:crypto_unittests/", - "variant_id": "iPhone 6s 15.5" - }, - { - "args": [ - "--platform", - "iPad Air 2", - "--version", - "14.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "gfx_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "gfx_unittests iPad Air 2 14.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_14_5", - "path": "Runtime-ios-14.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ui/gfx:gfx_unittests/", - "variant_id": "iPad Air 2 14.5" - }, - { - "args": [ - "--platform", - "iPad Air 2", - "--version", - "15.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "gfx_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "gfx_unittests iPad Air 2 15.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_15_5", - "path": "Runtime-ios-15.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ui/gfx:gfx_unittests/", - "variant_id": "iPad Air 2 15.5" - }, - { - "args": [ - "--platform", - "iPhone 6s", - "--version", - "14.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "gfx_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "gfx_unittests iPhone 6s 14.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_14_5", - "path": "Runtime-ios-14.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ui/gfx:gfx_unittests/", - "variant_id": "iPhone 6s 14.5" - }, - { - "args": [ - "--platform", - "iPhone 6s", - "--version", - "15.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "gfx_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "gfx_unittests iPhone 6s 15.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_15_5", - "path": "Runtime-ios-15.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ui/gfx:gfx_unittests/", - "variant_id": "iPhone 6s 15.5" - }, - { - "args": [ - "--platform", - "iPhone 6s Plus", - "--version", - "14.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "gfx_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "gfx_unittests iPhone 6s Plus 14.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_14_5", - "path": "Runtime-ios-14.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ui/gfx:gfx_unittests/", - "variant_id": "iPhone 6s Plus 14.5" - }, - { - "args": [ - "--platform", - "iPhone 6s Plus", - "--version", - "15.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "gfx_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "gfx_unittests iPhone 6s Plus 15.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_15_5", - "path": "Runtime-ios-15.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ui/gfx:gfx_unittests/", - "variant_id": "iPhone 6s Plus 15.5" - }, - { - "args": [ - "--platform", - "iPhone SE (1st generation)", - "--version", - "14.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "gfx_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "gfx_unittests iPhone SE (1st generation) 14.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_14_5", - "path": "Runtime-ios-14.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ui/gfx:gfx_unittests/", - "variant_id": "iPhone SE (1st generation) 14.5" - }, - { - "args": [ - "--platform", - "iPhone SE (1st generation)", - "--version", - "15.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "gfx_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "gfx_unittests iPhone SE (1st generation) 15.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_15_5", - "path": "Runtime-ios-15.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ui/gfx:gfx_unittests/", - "variant_id": "iPhone SE (1st generation) 15.5" - }, - { - "args": [ - "--platform", - "iPhone 6s", - "--version", - "14.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "google_apis_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "google_apis_unittests iPhone 6s 14.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_14_5", - "path": "Runtime-ios-14.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://google_apis:google_apis_unittests/", - "variant_id": "iPhone 6s 14.5" - }, - { - "args": [ - "--platform", - "iPhone 6s", - "--version", - "15.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "google_apis_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "google_apis_unittests iPhone 6s 15.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_15_5", - "path": "Runtime-ios-15.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://google_apis:google_apis_unittests/", - "variant_id": "iPhone 6s 15.5" - }, - { - "args": [ - "--platform", - "iPad Air 2", - "--version", - "14.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest", - "--xcode-parallelization" - ], - "isolate_name": "ios_chrome_bookmarks_eg2tests_module", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_bookmarks_eg2tests_module iPad Air 2 14.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_14_5", - "path": "Runtime-ios-14.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_bookmarks_eg2tests_module/", - "variant_id": "iPad Air 2 14.5" - }, - { - "args": [ - "--platform", - "iPad Air 2", - "--version", - "15.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest", - "--xcode-parallelization" - ], - "isolate_name": "ios_chrome_bookmarks_eg2tests_module", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_bookmarks_eg2tests_module iPad Air 2 15.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_15_5", - "path": "Runtime-ios-15.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_bookmarks_eg2tests_module/", - "variant_id": "iPad Air 2 15.5" - }, - { - "args": [ - "--platform", - "iPhone 7", - "--version", - "14.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest", - "--xcode-parallelization" - ], - "isolate_name": "ios_chrome_bookmarks_eg2tests_module", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_bookmarks_eg2tests_module iPhone 7 14.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_14_5", - "path": "Runtime-ios-14.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_bookmarks_eg2tests_module/", - "variant_id": "iPhone 7 14.5" - }, - { - "args": [ - "--platform", - "iPhone 7", - "--version", - "15.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest", - "--xcode-parallelization" - ], - "isolate_name": "ios_chrome_bookmarks_eg2tests_module", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_bookmarks_eg2tests_module iPhone 7 15.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_15_5", - "path": "Runtime-ios-15.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_bookmarks_eg2tests_module/", - "variant_id": "iPhone 7 15.5" - }, - { - "args": [ - "--platform", - "iPhone X", - "--version", - "14.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest", - "--xcode-parallelization" - ], - "isolate_name": "ios_chrome_bookmarks_eg2tests_module", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_bookmarks_eg2tests_module iPhone X 14.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_14_5", - "path": "Runtime-ios-14.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_bookmarks_eg2tests_module/", - "variant_id": "iPhone X 14.5" - }, - { - "args": [ - "--platform", - "iPhone X", - "--version", - "15.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest", - "--xcode-parallelization" - ], - "isolate_name": "ios_chrome_bookmarks_eg2tests_module", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_bookmarks_eg2tests_module iPhone X 15.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_15_5", - "path": "Runtime-ios-15.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_bookmarks_eg2tests_module/", - "variant_id": "iPhone X 15.5" - }, - { - "args": [ - "--platform", - "iPad Air 2", - "--version", - "14.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest", - "--xcode-parallelization" - ], - "isolate_name": "ios_chrome_integration_eg2tests_module", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_integration_eg2tests_module iPad Air 2 14.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_14_5", - "path": "Runtime-ios-14.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 8 - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_integration_eg2tests_module/", - "variant_id": "iPad Air 2 14.5" - }, - { - "args": [ - "--platform", - "iPad Air 2", - "--version", - "15.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest", - "--xcode-parallelization" - ], - "isolate_name": "ios_chrome_integration_eg2tests_module", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_integration_eg2tests_module iPad Air 2 15.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_15_5", - "path": "Runtime-ios-15.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 8 - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_integration_eg2tests_module/", - "variant_id": "iPad Air 2 15.5" - }, - { - "args": [ - "--platform", - "iPhone 7", - "--version", - "14.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest", - "--xcode-parallelization" - ], - "isolate_name": "ios_chrome_integration_eg2tests_module", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_integration_eg2tests_module iPhone 7 14.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_14_5", - "path": "Runtime-ios-14.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 8 - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_integration_eg2tests_module/", - "variant_id": "iPhone 7 14.5" - }, - { - "args": [ - "--platform", - "iPhone 7", - "--version", - "15.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest", - "--xcode-parallelization" - ], - "isolate_name": "ios_chrome_integration_eg2tests_module", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_integration_eg2tests_module iPhone 7 15.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_15_5", - "path": "Runtime-ios-15.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 8 - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_integration_eg2tests_module/", - "variant_id": "iPhone 7 15.5" - }, - { - "args": [ - "--platform", - "iPhone X", - "--version", - "14.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest", - "--xcode-parallelization" - ], - "isolate_name": "ios_chrome_integration_eg2tests_module", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_integration_eg2tests_module iPhone X 14.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_14_5", - "path": "Runtime-ios-14.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 8 - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_integration_eg2tests_module/", - "variant_id": "iPhone X 14.5" - }, - { - "args": [ - "--platform", - "iPhone X", - "--version", - "15.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest", - "--xcode-parallelization" - ], - "isolate_name": "ios_chrome_integration_eg2tests_module", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_integration_eg2tests_module iPhone X 15.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_15_5", - "path": "Runtime-ios-15.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 8 - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_integration_eg2tests_module/", - "variant_id": "iPhone X 15.5" - }, - { - "args": [ - "--platform", - "iPad Air 2", - "--version", - "14.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest", - "--xcode-parallelization" - ], - "isolate_name": "ios_chrome_settings_eg2tests_module", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_settings_eg2tests_module iPad Air 2 14.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_14_5", - "path": "Runtime-ios-14.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_settings_eg2tests_module/", - "variant_id": "iPad Air 2 14.5" - }, - { - "args": [ - "--platform", - "iPad Air 2", - "--version", - "15.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest", - "--xcode-parallelization" - ], - "isolate_name": "ios_chrome_settings_eg2tests_module", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_settings_eg2tests_module iPad Air 2 15.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_15_5", - "path": "Runtime-ios-15.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_settings_eg2tests_module/", - "variant_id": "iPad Air 2 15.5" - }, - { - "args": [ - "--platform", - "iPhone 7", - "--version", - "14.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest", - "--xcode-parallelization" - ], - "isolate_name": "ios_chrome_settings_eg2tests_module", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_settings_eg2tests_module iPhone 7 14.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_14_5", - "path": "Runtime-ios-14.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_settings_eg2tests_module/", - "variant_id": "iPhone 7 14.5" - }, - { - "args": [ - "--platform", - "iPhone 7", - "--version", - "15.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest", - "--xcode-parallelization" - ], - "isolate_name": "ios_chrome_settings_eg2tests_module", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_settings_eg2tests_module iPhone 7 15.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_15_5", - "path": "Runtime-ios-15.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_settings_eg2tests_module/", - "variant_id": "iPhone 7 15.5" - }, - { - "args": [ - "--platform", - "iPhone X", - "--version", - "14.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest", - "--xcode-parallelization" - ], - "isolate_name": "ios_chrome_settings_eg2tests_module", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_settings_eg2tests_module iPhone X 14.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_14_5", - "path": "Runtime-ios-14.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_settings_eg2tests_module/", - "variant_id": "iPhone X 14.5" - }, - { - "args": [ - "--platform", - "iPhone X", - "--version", - "15.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest", - "--xcode-parallelization" - ], - "isolate_name": "ios_chrome_settings_eg2tests_module", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_settings_eg2tests_module iPhone X 15.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_15_5", - "path": "Runtime-ios-15.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_settings_eg2tests_module/", - "variant_id": "iPhone X 15.5" - }, - { - "args": [ - "--platform", - "iPad Air 2", - "--version", - "14.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest", - "--xcode-parallelization" - ], - "isolate_name": "ios_chrome_signin_eg2tests_module", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_signin_eg2tests_module iPad Air 2 14.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_14_5", - "path": "Runtime-ios-14.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 6 - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_signin_eg2tests_module/", - "variant_id": "iPad Air 2 14.5" - }, - { - "args": [ - "--platform", - "iPad Air 2", - "--version", - "15.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest", - "--xcode-parallelization" - ], - "isolate_name": "ios_chrome_signin_eg2tests_module", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_signin_eg2tests_module iPad Air 2 15.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_15_5", - "path": "Runtime-ios-15.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 6 - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_signin_eg2tests_module/", - "variant_id": "iPad Air 2 15.5" - }, - { - "args": [ - "--platform", - "iPhone 7", - "--version", - "14.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest", - "--xcode-parallelization" - ], - "isolate_name": "ios_chrome_signin_eg2tests_module", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_signin_eg2tests_module iPhone 7 14.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_14_5", - "path": "Runtime-ios-14.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 6 - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_signin_eg2tests_module/", - "variant_id": "iPhone 7 14.5" - }, - { - "args": [ - "--platform", - "iPhone 7", - "--version", - "15.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest", - "--xcode-parallelization" - ], - "isolate_name": "ios_chrome_signin_eg2tests_module", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_signin_eg2tests_module iPhone 7 15.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_15_5", - "path": "Runtime-ios-15.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 6 - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_signin_eg2tests_module/", - "variant_id": "iPhone 7 15.5" - }, - { - "args": [ - "--platform", - "iPhone X", - "--version", - "14.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest", - "--xcode-parallelization" - ], - "isolate_name": "ios_chrome_signin_eg2tests_module", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_signin_eg2tests_module iPhone X 14.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_14_5", - "path": "Runtime-ios-14.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 6 - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_signin_eg2tests_module/", - "variant_id": "iPhone X 14.5" - }, - { - "args": [ - "--platform", - "iPhone X", - "--version", - "15.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest", - "--xcode-parallelization" - ], - "isolate_name": "ios_chrome_signin_eg2tests_module", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_signin_eg2tests_module iPhone X 15.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_15_5", - "path": "Runtime-ios-15.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 6 - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_signin_eg2tests_module/", - "variant_id": "iPhone X 15.5" - }, - { - "args": [ - "--platform", - "iPad Air 2", - "--version", - "14.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest", - "--xcode-parallelization" - ], - "isolate_name": "ios_chrome_smoke_eg2tests_module", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_smoke_eg2tests_module iPad Air 2 14.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_14_5", - "path": "Runtime-ios-14.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_smoke_eg2tests_module/", - "variant_id": "iPad Air 2 14.5" - }, - { - "args": [ - "--platform", - "iPad Air 2", - "--version", - "15.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest", - "--xcode-parallelization" - ], - "isolate_name": "ios_chrome_smoke_eg2tests_module", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_smoke_eg2tests_module iPad Air 2 15.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_15_5", - "path": "Runtime-ios-15.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_smoke_eg2tests_module/", - "variant_id": "iPad Air 2 15.5" - }, - { - "args": [ - "--platform", - "iPhone 7", - "--version", - "14.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest", - "--xcode-parallelization" - ], - "isolate_name": "ios_chrome_smoke_eg2tests_module", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_smoke_eg2tests_module iPhone 7 14.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_14_5", - "path": "Runtime-ios-14.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_smoke_eg2tests_module/", - "variant_id": "iPhone 7 14.5" - }, - { - "args": [ - "--platform", - "iPhone 7", - "--version", - "15.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest", - "--xcode-parallelization" - ], - "isolate_name": "ios_chrome_smoke_eg2tests_module", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_smoke_eg2tests_module iPhone 7 15.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_15_5", - "path": "Runtime-ios-15.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_smoke_eg2tests_module/", - "variant_id": "iPhone 7 15.5" - }, - { - "args": [ - "--platform", - "iPhone X", - "--version", - "14.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest", - "--xcode-parallelization" - ], - "isolate_name": "ios_chrome_smoke_eg2tests_module", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_smoke_eg2tests_module iPhone X 14.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_14_5", - "path": "Runtime-ios-14.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_smoke_eg2tests_module/", - "variant_id": "iPhone X 14.5" - }, - { - "args": [ - "--platform", - "iPhone X", - "--version", - "15.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest", - "--xcode-parallelization" - ], - "isolate_name": "ios_chrome_smoke_eg2tests_module", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_smoke_eg2tests_module iPhone X 15.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_15_5", - "path": "Runtime-ios-15.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_smoke_eg2tests_module/", - "variant_id": "iPhone X 15.5" - }, - { - "args": [ - "--platform", - "iPad Air 2", - "--version", - "14.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest", - "--xcode-parallelization" - ], - "isolate_name": "ios_chrome_ui_eg2tests_module", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_ui_eg2tests_module iPad Air 2 14.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_14_5", - "path": "Runtime-ios-14.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 12 - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_ui_eg2tests_module/", - "variant_id": "iPad Air 2 14.5" - }, - { - "args": [ - "--platform", - "iPad Air 2", - "--version", - "15.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest", - "--xcode-parallelization" - ], - "isolate_name": "ios_chrome_ui_eg2tests_module", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_ui_eg2tests_module iPad Air 2 15.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_15_5", - "path": "Runtime-ios-15.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 12 - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_ui_eg2tests_module/", - "variant_id": "iPad Air 2 15.5" - }, - { - "args": [ - "--platform", - "iPhone 7", - "--version", - "14.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest", - "--xcode-parallelization" - ], - "isolate_name": "ios_chrome_ui_eg2tests_module", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_ui_eg2tests_module iPhone 7 14.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_14_5", - "path": "Runtime-ios-14.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 12 - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_ui_eg2tests_module/", - "variant_id": "iPhone 7 14.5" - }, - { - "args": [ - "--platform", - "iPhone 7", - "--version", - "15.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest", - "--xcode-parallelization" - ], - "isolate_name": "ios_chrome_ui_eg2tests_module", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_ui_eg2tests_module iPhone 7 15.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_15_5", - "path": "Runtime-ios-15.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 12 - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_ui_eg2tests_module/", - "variant_id": "iPhone 7 15.5" - }, - { - "args": [ - "--platform", - "iPhone X", - "--version", - "14.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest", - "--xcode-parallelization" - ], - "isolate_name": "ios_chrome_ui_eg2tests_module", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_ui_eg2tests_module iPhone X 14.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_14_5", - "path": "Runtime-ios-14.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 12 - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_ui_eg2tests_module/", - "variant_id": "iPhone X 14.5" - }, - { - "args": [ - "--platform", - "iPhone X", - "--version", - "15.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest", - "--xcode-parallelization" - ], - "isolate_name": "ios_chrome_ui_eg2tests_module", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_ui_eg2tests_module iPhone X 15.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_15_5", - "path": "Runtime-ios-15.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 12 - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_ui_eg2tests_module/", - "variant_id": "iPhone X 15.5" - }, - { - "args": [ - "--platform", - "iPad Air 2", - "--version", - "14.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "ios_chrome_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_unittests iPad Air 2 14.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_14_5", - "path": "Runtime-ios-14.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test:ios_chrome_unittests/", - "variant_id": "iPad Air 2 14.5" - }, - { - "args": [ - "--platform", - "iPad Air 2", - "--version", - "15.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "ios_chrome_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_unittests iPad Air 2 15.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_15_5", - "path": "Runtime-ios-15.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test:ios_chrome_unittests/", - "variant_id": "iPad Air 2 15.5" - }, - { - "args": [ - "--platform", - "iPhone 6s", - "--version", - "14.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "ios_chrome_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_unittests iPhone 6s 14.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_14_5", - "path": "Runtime-ios-14.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test:ios_chrome_unittests/", - "variant_id": "iPhone 6s 14.5" - }, - { - "args": [ - "--platform", - "iPhone 6s", - "--version", - "15.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "ios_chrome_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_unittests iPhone 6s 15.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_15_5", - "path": "Runtime-ios-15.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test:ios_chrome_unittests/", - "variant_id": "iPhone 6s 15.5" - }, - { - "args": [ - "--platform", - "iPhone 6s Plus", - "--version", - "14.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "ios_chrome_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_unittests iPhone 6s Plus 14.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_14_5", - "path": "Runtime-ios-14.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test:ios_chrome_unittests/", - "variant_id": "iPhone 6s Plus 14.5" - }, - { - "args": [ - "--platform", - "iPhone 6s Plus", - "--version", - "15.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "ios_chrome_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_unittests iPhone 6s Plus 15.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_15_5", - "path": "Runtime-ios-15.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test:ios_chrome_unittests/", - "variant_id": "iPhone 6s Plus 15.5" - }, - { - "args": [ - "--platform", - "iPhone SE (1st generation)", - "--version", - "14.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "ios_chrome_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_unittests iPhone SE (1st generation) 14.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_14_5", - "path": "Runtime-ios-14.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test:ios_chrome_unittests/", - "variant_id": "iPhone SE (1st generation) 14.5" - }, - { - "args": [ - "--platform", - "iPhone SE (1st generation)", - "--version", - "15.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "ios_chrome_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_unittests iPhone SE (1st generation) 15.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_15_5", - "path": "Runtime-ios-15.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test:ios_chrome_unittests/", - "variant_id": "iPhone SE (1st generation) 15.5" - }, - { - "args": [ - "--platform", - "iPad Air 2", - "--version", - "14.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest", - "--xcode-parallelization" - ], - "isolate_name": "ios_chrome_web_eg2tests_module", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_web_eg2tests_module iPad Air 2 14.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_14_5", - "path": "Runtime-ios-14.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 2 - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_web_eg2tests_module/", - "variant_id": "iPad Air 2 14.5" - }, - { - "args": [ - "--platform", - "iPad Air 2", - "--version", - "15.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest", - "--xcode-parallelization" - ], - "isolate_name": "ios_chrome_web_eg2tests_module", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_web_eg2tests_module iPad Air 2 15.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_15_5", - "path": "Runtime-ios-15.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 2 - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_web_eg2tests_module/", - "variant_id": "iPad Air 2 15.5" - }, - { - "args": [ - "--platform", - "iPhone 7", - "--version", - "14.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest", - "--xcode-parallelization" - ], - "isolate_name": "ios_chrome_web_eg2tests_module", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_web_eg2tests_module iPhone 7 14.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_14_5", - "path": "Runtime-ios-14.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 2 - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_web_eg2tests_module/", - "variant_id": "iPhone 7 14.5" - }, - { - "args": [ - "--platform", - "iPhone 7", - "--version", - "15.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest", - "--xcode-parallelization" - ], - "isolate_name": "ios_chrome_web_eg2tests_module", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_web_eg2tests_module iPhone 7 15.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_15_5", - "path": "Runtime-ios-15.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 2 - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_web_eg2tests_module/", - "variant_id": "iPhone 7 15.5" - }, - { - "args": [ - "--platform", - "iPhone X", - "--version", - "14.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest", - "--xcode-parallelization" - ], - "isolate_name": "ios_chrome_web_eg2tests_module", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_web_eg2tests_module iPhone X 14.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_14_5", - "path": "Runtime-ios-14.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 2 - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_web_eg2tests_module/", - "variant_id": "iPhone X 14.5" - }, - { - "args": [ - "--platform", - "iPhone X", - "--version", - "15.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest", - "--xcode-parallelization" - ], - "isolate_name": "ios_chrome_web_eg2tests_module", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_web_eg2tests_module iPhone X 15.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_15_5", - "path": "Runtime-ios-15.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 2 - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_web_eg2tests_module/", - "variant_id": "iPhone X 15.5" - }, - { - "args": [ - "--platform", - "iPhone 6s", - "--version", - "14.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "ios_components_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_components_unittests iPhone 6s 14.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_14_5", - "path": "Runtime-ios-14.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/components:ios_components_unittests/", - "variant_id": "iPhone 6s 14.5" - }, - { - "args": [ - "--platform", - "iPhone 6s", - "--version", - "15.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "ios_components_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_components_unittests iPhone 6s 15.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_15_5", - "path": "Runtime-ios-15.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/components:ios_components_unittests/", - "variant_id": "iPhone 6s 15.5" - }, - { - "args": [ - "--platform", - "iPhone 6s", - "--version", - "14.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "ios_net_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_net_unittests iPhone 6s 14.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_14_5", - "path": "Runtime-ios-14.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 - }, - "test_id_prefix": "ninja://ios/net:ios_net_unittests/", - "variant_id": "iPhone 6s 14.5" - }, - { - "args": [ - "--platform", - "iPhone 6s", - "--version", - "15.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "ios_net_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_net_unittests iPhone 6s 15.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_15_5", - "path": "Runtime-ios-15.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 - }, - "test_id_prefix": "ninja://ios/net:ios_net_unittests/", - "variant_id": "iPhone 6s 15.5" - }, - { - "args": [ - "--platform", - "iPhone 6s", - "--version", - "14.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "ios_remoting_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_remoting_unittests iPhone 6s 14.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_14_5", - "path": "Runtime-ios-14.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://remoting/ios:ios_remoting_unittests/", - "variant_id": "iPhone 6s 14.5" - }, - { - "args": [ - "--platform", - "iPhone 6s", - "--version", - "15.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "ios_remoting_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_remoting_unittests iPhone 6s 15.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_15_5", - "path": "Runtime-ios-15.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://remoting/ios:ios_remoting_unittests/", - "variant_id": "iPhone 6s 15.5" - }, - { - "args": [ - "--platform", - "iPad Air 2", - "--version", - "14.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest", - "--xcode-parallelization" - ], - "isolate_name": "ios_showcase_eg2tests_module", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_showcase_eg2tests_module iPad Air 2 14.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_14_5", - "path": "Runtime-ios-14.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/showcase:ios_showcase_eg2tests_module/", - "variant_id": "iPad Air 2 14.5" - }, - { - "args": [ - "--platform", - "iPad Air 2", - "--version", - "15.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest", - "--xcode-parallelization" - ], - "isolate_name": "ios_showcase_eg2tests_module", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_showcase_eg2tests_module iPad Air 2 15.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_15_5", - "path": "Runtime-ios-15.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/showcase:ios_showcase_eg2tests_module/", - "variant_id": "iPad Air 2 15.5" - }, - { - "args": [ - "--platform", - "iPhone 7", - "--version", - "14.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest", - "--xcode-parallelization" - ], - "isolate_name": "ios_showcase_eg2tests_module", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_showcase_eg2tests_module iPhone 7 14.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_14_5", - "path": "Runtime-ios-14.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/showcase:ios_showcase_eg2tests_module/", - "variant_id": "iPhone 7 14.5" - }, - { - "args": [ - "--platform", - "iPhone 7", - "--version", - "15.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest", - "--xcode-parallelization" - ], - "isolate_name": "ios_showcase_eg2tests_module", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_showcase_eg2tests_module iPhone 7 15.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_15_5", - "path": "Runtime-ios-15.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/showcase:ios_showcase_eg2tests_module/", - "variant_id": "iPhone 7 15.5" - }, - { - "args": [ - "--platform", - "iPhone X", - "--version", - "14.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest", - "--xcode-parallelization" - ], - "isolate_name": "ios_showcase_eg2tests_module", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_showcase_eg2tests_module iPhone X 14.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_14_5", - "path": "Runtime-ios-14.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/showcase:ios_showcase_eg2tests_module/", - "variant_id": "iPhone X 14.5" - }, - { - "args": [ - "--platform", - "iPhone X", - "--version", - "15.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest", - "--xcode-parallelization" - ], - "isolate_name": "ios_showcase_eg2tests_module", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_showcase_eg2tests_module iPhone X 15.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_15_5", - "path": "Runtime-ios-15.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/showcase:ios_showcase_eg2tests_module/", - "variant_id": "iPhone X 15.5" - }, - { - "args": [ - "--platform", - "iPhone 6s", - "--version", - "14.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "ios_testing_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_testing_unittests iPhone 6s 14.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_14_5", - "path": "Runtime-ios-14.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/testing:ios_testing_unittests/", - "variant_id": "iPhone 6s 14.5" - }, - { - "args": [ - "--platform", - "iPhone 6s", - "--version", - "15.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "ios_testing_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_testing_unittests iPhone 6s 15.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_15_5", - "path": "Runtime-ios-15.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/testing:ios_testing_unittests/", - "variant_id": "iPhone 6s 15.5" - }, - { - "args": [ - "--platform", - "iPad Air 2", - "--version", - "14.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "ios_web_inttests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_web_inttests iPad Air 2 14.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_14_5", - "path": "Runtime-ios-14.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/web:ios_web_inttests/", - "variant_id": "iPad Air 2 14.5" - }, - { - "args": [ - "--platform", - "iPad Air 2", - "--version", - "15.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "ios_web_inttests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_web_inttests iPad Air 2 15.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_15_5", - "path": "Runtime-ios-15.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/web:ios_web_inttests/", - "variant_id": "iPad Air 2 15.5" - }, - { - "args": [ - "--platform", - "iPhone 6s", - "--version", - "14.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "ios_web_inttests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_web_inttests iPhone 6s 14.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_14_5", - "path": "Runtime-ios-14.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/web:ios_web_inttests/", - "variant_id": "iPhone 6s 14.5" - }, - { - "args": [ - "--platform", - "iPhone 6s", - "--version", - "15.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "ios_web_inttests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_web_inttests iPhone 6s 15.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_15_5", - "path": "Runtime-ios-15.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/web:ios_web_inttests/", - "variant_id": "iPhone 6s 15.5" - }, - { - "args": [ - "--platform", - "iPhone 6s Plus", - "--version", - "14.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "ios_web_inttests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_web_inttests iPhone 6s Plus 14.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_14_5", - "path": "Runtime-ios-14.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/web:ios_web_inttests/", - "variant_id": "iPhone 6s Plus 14.5" - }, - { - "args": [ - "--platform", - "iPhone 6s Plus", - "--version", - "15.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "ios_web_inttests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_web_inttests iPhone 6s Plus 15.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_15_5", - "path": "Runtime-ios-15.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/web:ios_web_inttests/", - "variant_id": "iPhone 6s Plus 15.5" - }, - { - "args": [ - "--platform", - "iPhone SE (1st generation)", - "--version", - "14.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "ios_web_inttests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_web_inttests iPhone SE (1st generation) 14.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_14_5", - "path": "Runtime-ios-14.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/web:ios_web_inttests/", - "variant_id": "iPhone SE (1st generation) 14.5" - }, - { - "args": [ - "--platform", - "iPhone SE (1st generation)", - "--version", - "15.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "ios_web_inttests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_web_inttests iPhone SE (1st generation) 15.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_15_5", - "path": "Runtime-ios-15.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/web:ios_web_inttests/", - "variant_id": "iPhone SE (1st generation) 15.5" - }, - { - "args": [ - "--platform", - "iPad Air 2", - "--version", - "14.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest", - "--xcode-parallelization" - ], - "isolate_name": "ios_web_shell_eg2tests_module", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_web_shell_eg2tests_module iPad Air 2 14.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_14_5", - "path": "Runtime-ios-14.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/web/shell/test:ios_web_shell_eg2tests_module/", - "variant_id": "iPad Air 2 14.5" - }, - { - "args": [ - "--platform", - "iPad Air 2", - "--version", - "15.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest", - "--xcode-parallelization" - ], - "isolate_name": "ios_web_shell_eg2tests_module", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_web_shell_eg2tests_module iPad Air 2 15.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_15_5", - "path": "Runtime-ios-15.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/web/shell/test:ios_web_shell_eg2tests_module/", - "variant_id": "iPad Air 2 15.5" - }, - { - "args": [ - "--platform", - "iPhone 7", - "--version", - "14.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest", - "--xcode-parallelization" - ], - "isolate_name": "ios_web_shell_eg2tests_module", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_web_shell_eg2tests_module iPhone 7 14.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_14_5", - "path": "Runtime-ios-14.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/web/shell/test:ios_web_shell_eg2tests_module/", - "variant_id": "iPhone 7 14.5" - }, - { - "args": [ - "--platform", - "iPhone 7", - "--version", - "15.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest", - "--xcode-parallelization" - ], - "isolate_name": "ios_web_shell_eg2tests_module", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_web_shell_eg2tests_module iPhone 7 15.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_15_5", - "path": "Runtime-ios-15.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/web/shell/test:ios_web_shell_eg2tests_module/", - "variant_id": "iPhone 7 15.5" - }, - { - "args": [ - "--platform", - "iPhone X", - "--version", - "14.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest", - "--xcode-parallelization" - ], - "isolate_name": "ios_web_shell_eg2tests_module", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_web_shell_eg2tests_module iPhone X 14.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_14_5", - "path": "Runtime-ios-14.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/web/shell/test:ios_web_shell_eg2tests_module/", - "variant_id": "iPhone X 14.5" - }, - { - "args": [ - "--platform", - "iPhone X", - "--version", - "15.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest", - "--xcode-parallelization" - ], - "isolate_name": "ios_web_shell_eg2tests_module", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_web_shell_eg2tests_module iPhone X 15.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_15_5", - "path": "Runtime-ios-15.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/web/shell/test:ios_web_shell_eg2tests_module/", - "variant_id": "iPhone X 15.5" - }, - { - "args": [ - "--platform", - "iPad Air 2", - "--version", - "14.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "ios_web_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_web_unittests iPad Air 2 14.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_14_5", - "path": "Runtime-ios-14.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/web:ios_web_unittests/", - "variant_id": "iPad Air 2 14.5" - }, - { - "args": [ - "--platform", - "iPad Air 2", - "--version", - "15.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "ios_web_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_web_unittests iPad Air 2 15.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_15_5", - "path": "Runtime-ios-15.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/web:ios_web_unittests/", - "variant_id": "iPad Air 2 15.5" - }, - { - "args": [ - "--platform", - "iPhone 6s", - "--version", - "14.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "ios_web_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_web_unittests iPhone 6s 14.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_14_5", - "path": "Runtime-ios-14.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/web:ios_web_unittests/", - "variant_id": "iPhone 6s 14.5" - }, - { - "args": [ - "--platform", - "iPhone 6s", - "--version", - "15.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "ios_web_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_web_unittests iPhone 6s 15.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_15_5", - "path": "Runtime-ios-15.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/web:ios_web_unittests/", - "variant_id": "iPhone 6s 15.5" - }, - { - "args": [ - "--platform", - "iPhone 6s Plus", - "--version", - "14.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "ios_web_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_web_unittests iPhone 6s Plus 14.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_14_5", - "path": "Runtime-ios-14.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/web:ios_web_unittests/", - "variant_id": "iPhone 6s Plus 14.5" - }, - { - "args": [ - "--platform", - "iPhone 6s Plus", - "--version", - "15.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "ios_web_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_web_unittests iPhone 6s Plus 15.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_15_5", - "path": "Runtime-ios-15.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/web:ios_web_unittests/", - "variant_id": "iPhone 6s Plus 15.5" - }, - { - "args": [ - "--platform", - "iPhone SE (1st generation)", - "--version", - "14.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "ios_web_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_web_unittests iPhone SE (1st generation) 14.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_14_5", - "path": "Runtime-ios-14.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/web:ios_web_unittests/", - "variant_id": "iPhone SE (1st generation) 14.5" - }, - { - "args": [ - "--platform", - "iPhone SE (1st generation)", - "--version", - "15.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "ios_web_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_web_unittests iPhone SE (1st generation) 15.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_15_5", - "path": "Runtime-ios-15.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/web:ios_web_unittests/", - "variant_id": "iPhone SE (1st generation) 15.5" - }, - { - "args": [ - "--platform", - "iPad Air 2", - "--version", - "14.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "ios_web_view_inttests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_web_view_inttests iPad Air 2 14.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_14_5", - "path": "Runtime-ios-14.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/web_view:ios_web_view_inttests/", - "variant_id": "iPad Air 2 14.5" - }, - { - "args": [ - "--platform", - "iPad Air 2", - "--version", - "15.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "ios_web_view_inttests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_web_view_inttests iPad Air 2 15.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_15_5", - "path": "Runtime-ios-15.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/web_view:ios_web_view_inttests/", - "variant_id": "iPad Air 2 15.5" - }, - { - "args": [ - "--platform", - "iPhone 6s", - "--version", - "14.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "ios_web_view_inttests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_web_view_inttests iPhone 6s 14.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_14_5", - "path": "Runtime-ios-14.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/web_view:ios_web_view_inttests/", - "variant_id": "iPhone 6s 14.5" - }, - { - "args": [ - "--platform", - "iPhone 6s", - "--version", - "15.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "ios_web_view_inttests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_web_view_inttests iPhone 6s 15.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_15_5", - "path": "Runtime-ios-15.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/web_view:ios_web_view_inttests/", - "variant_id": "iPhone 6s 15.5" - }, - { - "args": [ - "--platform", - "iPhone 6s Plus", - "--version", - "14.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "ios_web_view_inttests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_web_view_inttests iPhone 6s Plus 14.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_14_5", - "path": "Runtime-ios-14.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/web_view:ios_web_view_inttests/", - "variant_id": "iPhone 6s Plus 14.5" - }, - { - "args": [ - "--platform", - "iPhone 6s Plus", - "--version", - "15.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "ios_web_view_inttests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_web_view_inttests iPhone 6s Plus 15.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_15_5", - "path": "Runtime-ios-15.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/web_view:ios_web_view_inttests/", - "variant_id": "iPhone 6s Plus 15.5" - }, - { - "args": [ - "--platform", - "iPhone SE (1st generation)", - "--version", - "14.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "ios_web_view_inttests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_web_view_inttests iPhone SE (1st generation) 14.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_14_5", - "path": "Runtime-ios-14.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/web_view:ios_web_view_inttests/", - "variant_id": "iPhone SE (1st generation) 14.5" - }, - { - "args": [ - "--platform", - "iPhone SE (1st generation)", - "--version", - "15.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "ios_web_view_inttests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_web_view_inttests iPhone SE (1st generation) 15.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_15_5", - "path": "Runtime-ios-15.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/web_view:ios_web_view_inttests/", - "variant_id": "iPhone SE (1st generation) 15.5" - }, - { - "args": [ - "--platform", - "iPad Air 2", - "--version", - "14.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "ios_web_view_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_web_view_unittests iPad Air 2 14.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_14_5", - "path": "Runtime-ios-14.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/web_view:ios_web_view_unittests/", - "variant_id": "iPad Air 2 14.5" - }, - { - "args": [ - "--platform", - "iPad Air 2", - "--version", - "15.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "ios_web_view_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_web_view_unittests iPad Air 2 15.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_15_5", - "path": "Runtime-ios-15.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/web_view:ios_web_view_unittests/", - "variant_id": "iPad Air 2 15.5" - }, - { - "args": [ - "--platform", - "iPhone 6s", - "--version", - "14.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "ios_web_view_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_web_view_unittests iPhone 6s 14.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_14_5", - "path": "Runtime-ios-14.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/web_view:ios_web_view_unittests/", - "variant_id": "iPhone 6s 14.5" - }, - { - "args": [ - "--platform", - "iPhone 6s", - "--version", - "15.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "ios_web_view_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_web_view_unittests iPhone 6s 15.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_15_5", - "path": "Runtime-ios-15.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/web_view:ios_web_view_unittests/", - "variant_id": "iPhone 6s 15.5" - }, - { - "args": [ - "--platform", - "iPhone 6s Plus", - "--version", - "14.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "ios_web_view_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_web_view_unittests iPhone 6s Plus 14.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_14_5", - "path": "Runtime-ios-14.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/web_view:ios_web_view_unittests/", - "variant_id": "iPhone 6s Plus 14.5" - }, - { - "args": [ - "--platform", - "iPhone 6s Plus", - "--version", - "15.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "ios_web_view_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_web_view_unittests iPhone 6s Plus 15.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_15_5", - "path": "Runtime-ios-15.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/web_view:ios_web_view_unittests/", - "variant_id": "iPhone 6s Plus 15.5" - }, - { - "args": [ - "--platform", - "iPhone SE (1st generation)", - "--version", - "14.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "ios_web_view_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_web_view_unittests iPhone SE (1st generation) 14.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_14_5", - "path": "Runtime-ios-14.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/web_view:ios_web_view_unittests/", - "variant_id": "iPhone SE (1st generation) 14.5" - }, - { - "args": [ - "--platform", - "iPhone SE (1st generation)", - "--version", - "15.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "ios_web_view_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_web_view_unittests iPhone SE (1st generation) 15.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_15_5", - "path": "Runtime-ios-15.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/web_view:ios_web_view_unittests/", - "variant_id": "iPhone SE (1st generation) 15.5" - }, - { - "args": [ - "--platform", - "iPhone 6s", - "--version", - "14.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "net_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "net_unittests iPhone 6s 14.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_14_5", - "path": "Runtime-ios-14.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://net:net_unittests/", - "variant_id": "iPhone 6s 14.5" - }, - { - "args": [ - "--platform", - "iPhone 6s", - "--version", - "15.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "net_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "net_unittests iPhone 6s 15.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_15_5", - "path": "Runtime-ios-15.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://net:net_unittests/", - "variant_id": "iPhone 6s 15.5" - }, - { - "args": [ - "--platform", - "iPhone 6s", - "--version", - "14.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "services_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "services_unittests iPhone 6s 14.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_14_5", - "path": "Runtime-ios-14.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://services:services_unittests/", - "variant_id": "iPhone 6s 14.5" - }, - { - "args": [ - "--platform", - "iPhone 6s", - "--version", - "15.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "services_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "services_unittests iPhone 6s 15.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_15_5", - "path": "Runtime-ios-15.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://services:services_unittests/", - "variant_id": "iPhone 6s 15.5" - }, - { - "args": [ - "--platform", - "iPad Air 2", - "--version", - "14.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "skia_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "skia_unittests iPad Air 2 14.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_14_5", - "path": "Runtime-ios-14.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://skia:skia_unittests/", - "variant_id": "iPad Air 2 14.5" - }, - { - "args": [ - "--platform", - "iPad Air 2", - "--version", - "15.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "skia_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "skia_unittests iPad Air 2 15.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_15_5", - "path": "Runtime-ios-15.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://skia:skia_unittests/", - "variant_id": "iPad Air 2 15.5" - }, - { - "args": [ - "--platform", - "iPhone 6s", - "--version", - "14.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "skia_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "skia_unittests iPhone 6s 14.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_14_5", - "path": "Runtime-ios-14.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://skia:skia_unittests/", - "variant_id": "iPhone 6s 14.5" - }, - { - "args": [ - "--platform", - "iPhone 6s", - "--version", - "15.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "skia_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "skia_unittests iPhone 6s 15.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_15_5", - "path": "Runtime-ios-15.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://skia:skia_unittests/", - "variant_id": "iPhone 6s 15.5" - }, - { - "args": [ - "--platform", - "iPhone 6s Plus", - "--version", - "14.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "skia_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "skia_unittests iPhone 6s Plus 14.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_14_5", - "path": "Runtime-ios-14.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://skia:skia_unittests/", - "variant_id": "iPhone 6s Plus 14.5" - }, - { - "args": [ - "--platform", - "iPhone 6s Plus", - "--version", - "15.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "skia_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "skia_unittests iPhone 6s Plus 15.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_15_5", - "path": "Runtime-ios-15.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://skia:skia_unittests/", - "variant_id": "iPhone 6s Plus 15.5" - }, - { - "args": [ - "--platform", - "iPhone SE (1st generation)", - "--version", - "14.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "skia_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "skia_unittests iPhone SE (1st generation) 14.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_14_5", - "path": "Runtime-ios-14.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://skia:skia_unittests/", - "variant_id": "iPhone SE (1st generation) 14.5" - }, - { - "args": [ - "--platform", - "iPhone SE (1st generation)", - "--version", - "15.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "skia_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "skia_unittests iPhone SE (1st generation) 15.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_15_5", - "path": "Runtime-ios-15.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://skia:skia_unittests/", - "variant_id": "iPhone SE (1st generation) 15.5" - }, - { - "args": [ - "--platform", - "iPhone 6s", - "--version", - "14.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "sql_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "sql_unittests iPhone 6s 14.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_14_5", - "path": "Runtime-ios-14.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://sql:sql_unittests/", - "variant_id": "iPhone 6s 14.5" - }, - { - "args": [ - "--platform", - "iPhone 6s", - "--version", - "15.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "sql_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "sql_unittests iPhone 6s 15.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_15_5", - "path": "Runtime-ios-15.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://sql:sql_unittests/", - "variant_id": "iPhone 6s 15.5" - }, - { - "args": [ - "--platform", - "iPad Air 2", - "--version", - "14.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "ui_base_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ui_base_unittests iPad Air 2 14.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_14_5", - "path": "Runtime-ios-14.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ui/base:ui_base_unittests/", - "variant_id": "iPad Air 2 14.5" - }, - { - "args": [ - "--platform", - "iPad Air 2", - "--version", - "15.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "ui_base_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ui_base_unittests iPad Air 2 15.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_15_5", - "path": "Runtime-ios-15.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ui/base:ui_base_unittests/", - "variant_id": "iPad Air 2 15.5" - }, - { - "args": [ - "--platform", - "iPhone 6s", - "--version", - "14.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "ui_base_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ui_base_unittests iPhone 6s 14.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_14_5", - "path": "Runtime-ios-14.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ui/base:ui_base_unittests/", - "variant_id": "iPhone 6s 14.5" - }, - { - "args": [ - "--platform", - "iPhone 6s", - "--version", - "15.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "ui_base_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ui_base_unittests iPhone 6s 15.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_15_5", - "path": "Runtime-ios-15.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ui/base:ui_base_unittests/", - "variant_id": "iPhone 6s 15.5" - }, - { - "args": [ - "--platform", - "iPhone 6s Plus", - "--version", - "14.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "ui_base_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ui_base_unittests iPhone 6s Plus 14.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_14_5", - "path": "Runtime-ios-14.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ui/base:ui_base_unittests/", - "variant_id": "iPhone 6s Plus 14.5" - }, - { - "args": [ - "--platform", - "iPhone 6s Plus", - "--version", - "15.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "ui_base_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ui_base_unittests iPhone 6s Plus 15.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_15_5", - "path": "Runtime-ios-15.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ui/base:ui_base_unittests/", - "variant_id": "iPhone 6s Plus 15.5" - }, - { - "args": [ - "--platform", - "iPhone SE (1st generation)", - "--version", - "14.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "ui_base_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ui_base_unittests iPhone SE (1st generation) 14.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_14_5", - "path": "Runtime-ios-14.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ui/base:ui_base_unittests/", - "variant_id": "iPhone SE (1st generation) 14.5" - }, - { - "args": [ - "--platform", - "iPhone SE (1st generation)", - "--version", - "15.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "ui_base_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ui_base_unittests iPhone SE (1st generation) 15.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_15_5", - "path": "Runtime-ios-15.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ui/base:ui_base_unittests/", - "variant_id": "iPhone SE (1st generation) 15.5" - }, - { - "args": [ - "--platform", - "iPhone 6s", - "--version", - "14.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "url_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "url_unittests iPhone 6s 14.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_14_5", - "path": "Runtime-ios-14.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://url:url_unittests/", - "variant_id": "iPhone 6s 14.5" - }, - { - "args": [ - "--platform", - "iPhone 6s", - "--version", - "15.5", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "14c18", - "--xctest" - ], - "isolate_name": "url_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "url_unittests iPhone 6s 15.5", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Mac-13" - } - ], - "named_caches": [ - { - "name": "xcode_ios_14c18", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_15_5", - "path": "Runtime-ios-15.5" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://url:url_unittests/", - "variant_id": "iPhone 6s 15.5" - } ] }, "ios16-beta-simulator": { @@ -34128,6 +25616,114 @@ { "args": [ "--platform", + "iPad Air 2", + "--version", + "14.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest" + ], + "isolate_name": "base_unittests", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "base_unittests iPad Air 2 14.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_14_5", + "path": "Runtime-ios-14.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://base:base_unittests/", + "variant_id": "iPad Air 2 14.5" + }, + { + "args": [ + "--platform", + "iPad Air 2", + "--version", + "15.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest" + ], + "isolate_name": "base_unittests", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "base_unittests iPad Air 2 15.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_15_5", + "path": "Runtime-ios-15.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://base:base_unittests/", + "variant_id": "iPad Air 2 15.5" + }, + { + "args": [ + "--platform", "iPad Pro (12.9-inch) (3rd generation)", "--version", "16.2", @@ -34182,6 +25778,222 @@ { "args": [ "--platform", + "iPhone 6s", + "--version", + "14.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest" + ], + "isolate_name": "base_unittests", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "base_unittests iPhone 6s 14.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_14_5", + "path": "Runtime-ios-14.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://base:base_unittests/", + "variant_id": "iPhone 6s 14.5" + }, + { + "args": [ + "--platform", + "iPhone 6s", + "--version", + "15.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest" + ], + "isolate_name": "base_unittests", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "base_unittests iPhone 6s 15.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_15_5", + "path": "Runtime-ios-15.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://base:base_unittests/", + "variant_id": "iPhone 6s 15.5" + }, + { + "args": [ + "--platform", + "iPhone 6s Plus", + "--version", + "14.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest" + ], + "isolate_name": "base_unittests", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "base_unittests iPhone 6s Plus 14.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_14_5", + "path": "Runtime-ios-14.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://base:base_unittests/", + "variant_id": "iPhone 6s Plus 14.5" + }, + { + "args": [ + "--platform", + "iPhone 6s Plus", + "--version", + "15.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest" + ], + "isolate_name": "base_unittests", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "base_unittests iPhone 6s Plus 15.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_15_5", + "path": "Runtime-ios-15.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://base:base_unittests/", + "variant_id": "iPhone 6s Plus 15.5" + }, + { + "args": [ + "--platform", "iPhone 8", "--version", "16.2", @@ -34290,6 +26102,114 @@ { "args": [ "--platform", + "iPhone SE (1st generation)", + "--version", + "14.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest" + ], + "isolate_name": "base_unittests", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "base_unittests iPhone SE (1st generation) 14.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_14_5", + "path": "Runtime-ios-14.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://base:base_unittests/", + "variant_id": "iPhone SE (1st generation) 14.5" + }, + { + "args": [ + "--platform", + "iPhone SE (1st generation)", + "--version", + "15.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest" + ], + "isolate_name": "base_unittests", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "base_unittests iPhone SE (1st generation) 15.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_15_5", + "path": "Runtime-ios-15.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://base:base_unittests/", + "variant_id": "iPhone SE (1st generation) 15.5" + }, + { + "args": [ + "--platform", "iPhone SE (3rd generation)", "--version", "16.2", @@ -34722,6 +26642,114 @@ { "args": [ "--platform", + "iPad Air 2", + "--version", + "14.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest" + ], + "isolate_name": "components_unittests", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "components_unittests iPad Air 2 14.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_14_5", + "path": "Runtime-ios-14.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://components:components_unittests/", + "variant_id": "iPad Air 2 14.5" + }, + { + "args": [ + "--platform", + "iPad Air 2", + "--version", + "15.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest" + ], + "isolate_name": "components_unittests", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "components_unittests iPad Air 2 15.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_15_5", + "path": "Runtime-ios-15.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://components:components_unittests/", + "variant_id": "iPad Air 2 15.5" + }, + { + "args": [ + "--platform", "iPad Pro (12.9-inch) (3rd generation)", "--version", "16.2", @@ -34776,6 +26804,222 @@ { "args": [ "--platform", + "iPhone 6s", + "--version", + "14.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest" + ], + "isolate_name": "components_unittests", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "components_unittests iPhone 6s 14.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_14_5", + "path": "Runtime-ios-14.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://components:components_unittests/", + "variant_id": "iPhone 6s 14.5" + }, + { + "args": [ + "--platform", + "iPhone 6s", + "--version", + "15.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest" + ], + "isolate_name": "components_unittests", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "components_unittests iPhone 6s 15.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_15_5", + "path": "Runtime-ios-15.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://components:components_unittests/", + "variant_id": "iPhone 6s 15.5" + }, + { + "args": [ + "--platform", + "iPhone 6s Plus", + "--version", + "14.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest" + ], + "isolate_name": "components_unittests", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "components_unittests iPhone 6s Plus 14.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_14_5", + "path": "Runtime-ios-14.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://components:components_unittests/", + "variant_id": "iPhone 6s Plus 14.5" + }, + { + "args": [ + "--platform", + "iPhone 6s Plus", + "--version", + "15.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest" + ], + "isolate_name": "components_unittests", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "components_unittests iPhone 6s Plus 15.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_15_5", + "path": "Runtime-ios-15.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://components:components_unittests/", + "variant_id": "iPhone 6s Plus 15.5" + }, + { + "args": [ + "--platform", "iPhone 8", "--version", "16.2", @@ -34884,6 +27128,114 @@ { "args": [ "--platform", + "iPhone SE (1st generation)", + "--version", + "14.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest" + ], + "isolate_name": "components_unittests", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "components_unittests iPhone SE (1st generation) 14.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_14_5", + "path": "Runtime-ios-14.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://components:components_unittests/", + "variant_id": "iPhone SE (1st generation) 14.5" + }, + { + "args": [ + "--platform", + "iPhone SE (1st generation)", + "--version", + "15.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest" + ], + "isolate_name": "components_unittests", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "components_unittests iPhone SE (1st generation) 15.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_15_5", + "path": "Runtime-ios-15.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://components:components_unittests/", + "variant_id": "iPhone SE (1st generation) 15.5" + }, + { + "args": [ + "--platform", "iPhone SE (3rd generation)", "--version", "16.2", @@ -35316,6 +27668,114 @@ { "args": [ "--platform", + "iPad Air 2", + "--version", + "14.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest" + ], + "isolate_name": "gfx_unittests", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "gfx_unittests iPad Air 2 14.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_14_5", + "path": "Runtime-ios-14.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ui/gfx:gfx_unittests/", + "variant_id": "iPad Air 2 14.5" + }, + { + "args": [ + "--platform", + "iPad Air 2", + "--version", + "15.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest" + ], + "isolate_name": "gfx_unittests", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "gfx_unittests iPad Air 2 15.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_15_5", + "path": "Runtime-ios-15.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ui/gfx:gfx_unittests/", + "variant_id": "iPad Air 2 15.5" + }, + { + "args": [ + "--platform", "iPad Pro (12.9-inch) (3rd generation)", "--version", "16.2", @@ -35370,6 +27830,222 @@ { "args": [ "--platform", + "iPhone 6s", + "--version", + "14.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest" + ], + "isolate_name": "gfx_unittests", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "gfx_unittests iPhone 6s 14.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_14_5", + "path": "Runtime-ios-14.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ui/gfx:gfx_unittests/", + "variant_id": "iPhone 6s 14.5" + }, + { + "args": [ + "--platform", + "iPhone 6s", + "--version", + "15.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest" + ], + "isolate_name": "gfx_unittests", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "gfx_unittests iPhone 6s 15.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_15_5", + "path": "Runtime-ios-15.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ui/gfx:gfx_unittests/", + "variant_id": "iPhone 6s 15.5" + }, + { + "args": [ + "--platform", + "iPhone 6s Plus", + "--version", + "14.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest" + ], + "isolate_name": "gfx_unittests", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "gfx_unittests iPhone 6s Plus 14.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_14_5", + "path": "Runtime-ios-14.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ui/gfx:gfx_unittests/", + "variant_id": "iPhone 6s Plus 14.5" + }, + { + "args": [ + "--platform", + "iPhone 6s Plus", + "--version", + "15.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest" + ], + "isolate_name": "gfx_unittests", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "gfx_unittests iPhone 6s Plus 15.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_15_5", + "path": "Runtime-ios-15.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ui/gfx:gfx_unittests/", + "variant_id": "iPhone 6s Plus 15.5" + }, + { + "args": [ + "--platform", "iPhone 8", "--version", "16.2", @@ -35478,6 +28154,114 @@ { "args": [ "--platform", + "iPhone SE (1st generation)", + "--version", + "14.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest" + ], + "isolate_name": "gfx_unittests", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "gfx_unittests iPhone SE (1st generation) 14.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_14_5", + "path": "Runtime-ios-14.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ui/gfx:gfx_unittests/", + "variant_id": "iPhone SE (1st generation) 14.5" + }, + { + "args": [ + "--platform", + "iPhone SE (1st generation)", + "--version", + "15.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest" + ], + "isolate_name": "gfx_unittests", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "gfx_unittests iPhone SE (1st generation) 15.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_15_5", + "path": "Runtime-ios-15.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ui/gfx:gfx_unittests/", + "variant_id": "iPhone SE (1st generation) 15.5" + }, + { + "args": [ + "--platform", "iPhone SE (3rd generation)", "--version", "16.2", @@ -36093,6 +28877,63 @@ { "args": [ "--platform", + "iPhone 7", + "--version", + "15.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest", + "--xcode-parallelization", + "--record-video", + "failed_only" + ], + "isolate_name": "ios_chrome_bookmarks_eg2tests_module", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_chrome_bookmarks_eg2tests_module iPhone 7 15.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_15_5", + "path": "Runtime-ios-15.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_bookmarks_eg2tests_module/", + "variant_id": "iPhone 7 15.5" + }, + { + "args": [ + "--platform", "iPhone 8", "--version", "16.2", @@ -37365,6 +30206,64 @@ { "args": [ "--platform", + "iPhone 7", + "--version", + "15.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest", + "--xcode-parallelization", + "--record-video", + "failed_only" + ], + "isolate_name": "ios_chrome_settings_eg2tests_module", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_chrome_settings_eg2tests_module iPhone 7 15.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_15_5", + "path": "Runtime-ios-15.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 3 + }, + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_settings_eg2tests_module/", + "variant_id": "iPhone 7 15.5" + }, + { + "args": [ + "--platform", "iPhone 8", "--version", "16.2", @@ -38003,6 +30902,64 @@ { "args": [ "--platform", + "iPhone 7", + "--version", + "15.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest", + "--xcode-parallelization", + "--record-video", + "failed_only" + ], + "isolate_name": "ios_chrome_signin_eg2tests_module", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_chrome_signin_eg2tests_module iPhone 7 15.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_15_5", + "path": "Runtime-ios-15.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 6 + }, + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_signin_eg2tests_module/", + "variant_id": "iPhone 7 15.5" + }, + { + "args": [ + "--platform", "iPhone 8", "--version", "16.2", @@ -38634,6 +31591,63 @@ { "args": [ "--platform", + "iPhone 7", + "--version", + "15.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest", + "--xcode-parallelization", + "--record-video", + "failed_only" + ], + "isolate_name": "ios_chrome_smoke_eg2tests_module", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_chrome_smoke_eg2tests_module iPhone 7 15.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_15_5", + "path": "Runtime-ios-15.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_smoke_eg2tests_module/", + "variant_id": "iPhone 7 15.5" + }, + { + "args": [ + "--platform", "iPhone 8", "--version", "16.2", @@ -39268,6 +32282,64 @@ { "args": [ "--platform", + "iPhone 7", + "--version", + "15.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest", + "--xcode-parallelization", + "--record-video", + "failed_only" + ], + "isolate_name": "ios_chrome_ui_eg2tests_module", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_chrome_ui_eg2tests_module iPhone 7 15.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_15_5", + "path": "Runtime-ios-15.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 12 + }, + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_ui_eg2tests_module/", + "variant_id": "iPhone 7 15.5" + }, + { + "args": [ + "--platform", "iPhone 8", "--version", "16.2", @@ -39554,6 +32626,114 @@ { "args": [ "--platform", + "iPad Air 2", + "--version", + "14.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest" + ], + "isolate_name": "ios_chrome_unittests", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_chrome_unittests iPad Air 2 14.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_14_5", + "path": "Runtime-ios-14.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/chrome/test:ios_chrome_unittests/", + "variant_id": "iPad Air 2 14.5" + }, + { + "args": [ + "--platform", + "iPad Air 2", + "--version", + "15.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest" + ], + "isolate_name": "ios_chrome_unittests", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_chrome_unittests iPad Air 2 15.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_15_5", + "path": "Runtime-ios-15.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/chrome/test:ios_chrome_unittests/", + "variant_id": "iPad Air 2 15.5" + }, + { + "args": [ + "--platform", "iPad Pro (12.9-inch) (3rd generation)", "--version", "16.2", @@ -39608,6 +32788,222 @@ { "args": [ "--platform", + "iPhone 6s", + "--version", + "14.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest" + ], + "isolate_name": "ios_chrome_unittests", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_chrome_unittests iPhone 6s 14.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_14_5", + "path": "Runtime-ios-14.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/chrome/test:ios_chrome_unittests/", + "variant_id": "iPhone 6s 14.5" + }, + { + "args": [ + "--platform", + "iPhone 6s", + "--version", + "15.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest" + ], + "isolate_name": "ios_chrome_unittests", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_chrome_unittests iPhone 6s 15.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_15_5", + "path": "Runtime-ios-15.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/chrome/test:ios_chrome_unittests/", + "variant_id": "iPhone 6s 15.5" + }, + { + "args": [ + "--platform", + "iPhone 6s Plus", + "--version", + "14.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest" + ], + "isolate_name": "ios_chrome_unittests", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_chrome_unittests iPhone 6s Plus 14.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_14_5", + "path": "Runtime-ios-14.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/chrome/test:ios_chrome_unittests/", + "variant_id": "iPhone 6s Plus 14.5" + }, + { + "args": [ + "--platform", + "iPhone 6s Plus", + "--version", + "15.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest" + ], + "isolate_name": "ios_chrome_unittests", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_chrome_unittests iPhone 6s Plus 15.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_15_5", + "path": "Runtime-ios-15.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/chrome/test:ios_chrome_unittests/", + "variant_id": "iPhone 6s Plus 15.5" + }, + { + "args": [ + "--platform", "iPhone 8", "--version", "16.2", @@ -39716,6 +33112,114 @@ { "args": [ "--platform", + "iPhone SE (1st generation)", + "--version", + "14.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest" + ], + "isolate_name": "ios_chrome_unittests", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_chrome_unittests iPhone SE (1st generation) 14.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_14_5", + "path": "Runtime-ios-14.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/chrome/test:ios_chrome_unittests/", + "variant_id": "iPhone SE (1st generation) 14.5" + }, + { + "args": [ + "--platform", + "iPhone SE (1st generation)", + "--version", + "15.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest" + ], + "isolate_name": "ios_chrome_unittests", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_chrome_unittests iPhone SE (1st generation) 15.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_15_5", + "path": "Runtime-ios-15.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/chrome/test:ios_chrome_unittests/", + "variant_id": "iPhone SE (1st generation) 15.5" + }, + { + "args": [ + "--platform", "iPhone SE (3rd generation)", "--version", "16.2", @@ -40176,6 +33680,64 @@ { "args": [ "--platform", + "iPhone 7", + "--version", + "15.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest", + "--xcode-parallelization", + "--record-video", + "failed_only" + ], + "isolate_name": "ios_chrome_web_eg2tests_module", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_chrome_web_eg2tests_module iPhone 7 15.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_15_5", + "path": "Runtime-ios-15.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 2 + }, + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_web_eg2tests_module/", + "variant_id": "iPhone 7 15.5" + }, + { + "args": [ + "--platform", "iPhone 8", "--version", "16.2", @@ -41461,6 +35023,63 @@ { "args": [ "--platform", + "iPhone 7", + "--version", + "15.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest", + "--xcode-parallelization", + "--record-video", + "failed_only" + ], + "isolate_name": "ios_showcase_eg2tests_module", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_showcase_eg2tests_module iPhone 7 15.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_15_5", + "path": "Runtime-ios-15.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/showcase:ios_showcase_eg2tests_module/", + "variant_id": "iPhone 7 15.5" + }, + { + "args": [ + "--platform", "iPhone 8", "--version", "16.2", @@ -42015,6 +35634,114 @@ { "args": [ "--platform", + "iPad Air 2", + "--version", + "14.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest" + ], + "isolate_name": "ios_web_inttests", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_web_inttests iPad Air 2 14.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_14_5", + "path": "Runtime-ios-14.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/web:ios_web_inttests/", + "variant_id": "iPad Air 2 14.5" + }, + { + "args": [ + "--platform", + "iPad Air 2", + "--version", + "15.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest" + ], + "isolate_name": "ios_web_inttests", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_web_inttests iPad Air 2 15.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_15_5", + "path": "Runtime-ios-15.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/web:ios_web_inttests/", + "variant_id": "iPad Air 2 15.5" + }, + { + "args": [ + "--platform", "iPad Pro (12.9-inch) (3rd generation)", "--version", "16.2", @@ -42069,6 +35796,222 @@ { "args": [ "--platform", + "iPhone 6s", + "--version", + "14.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest" + ], + "isolate_name": "ios_web_inttests", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_web_inttests iPhone 6s 14.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_14_5", + "path": "Runtime-ios-14.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/web:ios_web_inttests/", + "variant_id": "iPhone 6s 14.5" + }, + { + "args": [ + "--platform", + "iPhone 6s", + "--version", + "15.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest" + ], + "isolate_name": "ios_web_inttests", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_web_inttests iPhone 6s 15.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_15_5", + "path": "Runtime-ios-15.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/web:ios_web_inttests/", + "variant_id": "iPhone 6s 15.5" + }, + { + "args": [ + "--platform", + "iPhone 6s Plus", + "--version", + "14.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest" + ], + "isolate_name": "ios_web_inttests", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_web_inttests iPhone 6s Plus 14.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_14_5", + "path": "Runtime-ios-14.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/web:ios_web_inttests/", + "variant_id": "iPhone 6s Plus 14.5" + }, + { + "args": [ + "--platform", + "iPhone 6s Plus", + "--version", + "15.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest" + ], + "isolate_name": "ios_web_inttests", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_web_inttests iPhone 6s Plus 15.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_15_5", + "path": "Runtime-ios-15.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/web:ios_web_inttests/", + "variant_id": "iPhone 6s Plus 15.5" + }, + { + "args": [ + "--platform", "iPhone 8", "--version", "16.2", @@ -42177,6 +36120,114 @@ { "args": [ "--platform", + "iPhone SE (1st generation)", + "--version", + "14.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest" + ], + "isolate_name": "ios_web_inttests", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_web_inttests iPhone SE (1st generation) 14.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_14_5", + "path": "Runtime-ios-14.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/web:ios_web_inttests/", + "variant_id": "iPhone SE (1st generation) 14.5" + }, + { + "args": [ + "--platform", + "iPhone SE (1st generation)", + "--version", + "15.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest" + ], + "isolate_name": "ios_web_inttests", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_web_inttests iPhone SE (1st generation) 15.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_15_5", + "path": "Runtime-ios-15.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/web:ios_web_inttests/", + "variant_id": "iPhone SE (1st generation) 15.5" + }, + { + "args": [ + "--platform", "iPhone SE (3rd generation)", "--version", "16.2", @@ -42912,6 +36963,114 @@ { "args": [ "--platform", + "iPad Air 2", + "--version", + "14.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest" + ], + "isolate_name": "ios_web_unittests", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_web_unittests iPad Air 2 14.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_14_5", + "path": "Runtime-ios-14.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/web:ios_web_unittests/", + "variant_id": "iPad Air 2 14.5" + }, + { + "args": [ + "--platform", + "iPad Air 2", + "--version", + "15.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest" + ], + "isolate_name": "ios_web_unittests", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_web_unittests iPad Air 2 15.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_15_5", + "path": "Runtime-ios-15.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/web:ios_web_unittests/", + "variant_id": "iPad Air 2 15.5" + }, + { + "args": [ + "--platform", "iPad Pro (12.9-inch) (3rd generation)", "--version", "16.2", @@ -42966,6 +37125,222 @@ { "args": [ "--platform", + "iPhone 6s", + "--version", + "14.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest" + ], + "isolate_name": "ios_web_unittests", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_web_unittests iPhone 6s 14.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_14_5", + "path": "Runtime-ios-14.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/web:ios_web_unittests/", + "variant_id": "iPhone 6s 14.5" + }, + { + "args": [ + "--platform", + "iPhone 6s", + "--version", + "15.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest" + ], + "isolate_name": "ios_web_unittests", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_web_unittests iPhone 6s 15.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_15_5", + "path": "Runtime-ios-15.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/web:ios_web_unittests/", + "variant_id": "iPhone 6s 15.5" + }, + { + "args": [ + "--platform", + "iPhone 6s Plus", + "--version", + "14.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest" + ], + "isolate_name": "ios_web_unittests", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_web_unittests iPhone 6s Plus 14.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_14_5", + "path": "Runtime-ios-14.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/web:ios_web_unittests/", + "variant_id": "iPhone 6s Plus 14.5" + }, + { + "args": [ + "--platform", + "iPhone 6s Plus", + "--version", + "15.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest" + ], + "isolate_name": "ios_web_unittests", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_web_unittests iPhone 6s Plus 15.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_15_5", + "path": "Runtime-ios-15.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/web:ios_web_unittests/", + "variant_id": "iPhone 6s Plus 15.5" + }, + { + "args": [ + "--platform", "iPhone 8", "--version", "16.2", @@ -43074,6 +37449,114 @@ { "args": [ "--platform", + "iPhone SE (1st generation)", + "--version", + "14.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest" + ], + "isolate_name": "ios_web_unittests", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_web_unittests iPhone SE (1st generation) 14.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_14_5", + "path": "Runtime-ios-14.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/web:ios_web_unittests/", + "variant_id": "iPhone SE (1st generation) 14.5" + }, + { + "args": [ + "--platform", + "iPhone SE (1st generation)", + "--version", + "15.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest" + ], + "isolate_name": "ios_web_unittests", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_web_unittests iPhone SE (1st generation) 15.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_15_5", + "path": "Runtime-ios-15.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/web:ios_web_unittests/", + "variant_id": "iPhone SE (1st generation) 15.5" + }, + { + "args": [ + "--platform", "iPhone SE (3rd generation)", "--version", "16.2", @@ -43182,6 +37665,114 @@ { "args": [ "--platform", + "iPad Air 2", + "--version", + "14.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest" + ], + "isolate_name": "ios_web_view_inttests", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_web_view_inttests iPad Air 2 14.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_14_5", + "path": "Runtime-ios-14.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/web_view:ios_web_view_inttests/", + "variant_id": "iPad Air 2 14.5" + }, + { + "args": [ + "--platform", + "iPad Air 2", + "--version", + "15.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest" + ], + "isolate_name": "ios_web_view_inttests", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_web_view_inttests iPad Air 2 15.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_15_5", + "path": "Runtime-ios-15.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/web_view:ios_web_view_inttests/", + "variant_id": "iPad Air 2 15.5" + }, + { + "args": [ + "--platform", "iPad Pro (12.9-inch) (3rd generation)", "--version", "16.2", @@ -43236,6 +37827,222 @@ { "args": [ "--platform", + "iPhone 6s", + "--version", + "14.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest" + ], + "isolate_name": "ios_web_view_inttests", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_web_view_inttests iPhone 6s 14.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_14_5", + "path": "Runtime-ios-14.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/web_view:ios_web_view_inttests/", + "variant_id": "iPhone 6s 14.5" + }, + { + "args": [ + "--platform", + "iPhone 6s", + "--version", + "15.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest" + ], + "isolate_name": "ios_web_view_inttests", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_web_view_inttests iPhone 6s 15.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_15_5", + "path": "Runtime-ios-15.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/web_view:ios_web_view_inttests/", + "variant_id": "iPhone 6s 15.5" + }, + { + "args": [ + "--platform", + "iPhone 6s Plus", + "--version", + "14.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest" + ], + "isolate_name": "ios_web_view_inttests", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_web_view_inttests iPhone 6s Plus 14.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_14_5", + "path": "Runtime-ios-14.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/web_view:ios_web_view_inttests/", + "variant_id": "iPhone 6s Plus 14.5" + }, + { + "args": [ + "--platform", + "iPhone 6s Plus", + "--version", + "15.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest" + ], + "isolate_name": "ios_web_view_inttests", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_web_view_inttests iPhone 6s Plus 15.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_15_5", + "path": "Runtime-ios-15.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/web_view:ios_web_view_inttests/", + "variant_id": "iPhone 6s Plus 15.5" + }, + { + "args": [ + "--platform", "iPhone 8", "--version", "16.2", @@ -43344,6 +38151,114 @@ { "args": [ "--platform", + "iPhone SE (1st generation)", + "--version", + "14.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest" + ], + "isolate_name": "ios_web_view_inttests", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_web_view_inttests iPhone SE (1st generation) 14.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_14_5", + "path": "Runtime-ios-14.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/web_view:ios_web_view_inttests/", + "variant_id": "iPhone SE (1st generation) 14.5" + }, + { + "args": [ + "--platform", + "iPhone SE (1st generation)", + "--version", + "15.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest" + ], + "isolate_name": "ios_web_view_inttests", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_web_view_inttests iPhone SE (1st generation) 15.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_15_5", + "path": "Runtime-ios-15.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/web_view:ios_web_view_inttests/", + "variant_id": "iPhone SE (1st generation) 15.5" + }, + { + "args": [ + "--platform", "iPhone SE (3rd generation)", "--version", "16.2", @@ -43452,6 +38367,114 @@ { "args": [ "--platform", + "iPad Air 2", + "--version", + "14.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest" + ], + "isolate_name": "ios_web_view_unittests", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_web_view_unittests iPad Air 2 14.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_14_5", + "path": "Runtime-ios-14.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/web_view:ios_web_view_unittests/", + "variant_id": "iPad Air 2 14.5" + }, + { + "args": [ + "--platform", + "iPad Air 2", + "--version", + "15.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest" + ], + "isolate_name": "ios_web_view_unittests", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_web_view_unittests iPad Air 2 15.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_15_5", + "path": "Runtime-ios-15.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/web_view:ios_web_view_unittests/", + "variant_id": "iPad Air 2 15.5" + }, + { + "args": [ + "--platform", "iPad Pro (12.9-inch) (3rd generation)", "--version", "16.2", @@ -43506,6 +38529,222 @@ { "args": [ "--platform", + "iPhone 6s", + "--version", + "14.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest" + ], + "isolate_name": "ios_web_view_unittests", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_web_view_unittests iPhone 6s 14.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_14_5", + "path": "Runtime-ios-14.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/web_view:ios_web_view_unittests/", + "variant_id": "iPhone 6s 14.5" + }, + { + "args": [ + "--platform", + "iPhone 6s", + "--version", + "15.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest" + ], + "isolate_name": "ios_web_view_unittests", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_web_view_unittests iPhone 6s 15.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_15_5", + "path": "Runtime-ios-15.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/web_view:ios_web_view_unittests/", + "variant_id": "iPhone 6s 15.5" + }, + { + "args": [ + "--platform", + "iPhone 6s Plus", + "--version", + "14.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest" + ], + "isolate_name": "ios_web_view_unittests", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_web_view_unittests iPhone 6s Plus 14.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_14_5", + "path": "Runtime-ios-14.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/web_view:ios_web_view_unittests/", + "variant_id": "iPhone 6s Plus 14.5" + }, + { + "args": [ + "--platform", + "iPhone 6s Plus", + "--version", + "15.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest" + ], + "isolate_name": "ios_web_view_unittests", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_web_view_unittests iPhone 6s Plus 15.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_15_5", + "path": "Runtime-ios-15.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/web_view:ios_web_view_unittests/", + "variant_id": "iPhone 6s Plus 15.5" + }, + { + "args": [ + "--platform", "iPhone 8", "--version", "16.2", @@ -43614,6 +38853,114 @@ { "args": [ "--platform", + "iPhone SE (1st generation)", + "--version", + "14.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest" + ], + "isolate_name": "ios_web_view_unittests", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_web_view_unittests iPhone SE (1st generation) 14.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_14_5", + "path": "Runtime-ios-14.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/web_view:ios_web_view_unittests/", + "variant_id": "iPhone SE (1st generation) 14.5" + }, + { + "args": [ + "--platform", + "iPhone SE (1st generation)", + "--version", + "15.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest" + ], + "isolate_name": "ios_web_view_unittests", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_web_view_unittests iPhone SE (1st generation) 15.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_15_5", + "path": "Runtime-ios-15.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/web_view:ios_web_view_unittests/", + "variant_id": "iPhone SE (1st generation) 15.5" + }, + { + "args": [ + "--platform", "iPhone SE (3rd generation)", "--version", "16.2", @@ -44046,6 +39393,114 @@ { "args": [ "--platform", + "iPad Air 2", + "--version", + "14.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest" + ], + "isolate_name": "skia_unittests", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "skia_unittests iPad Air 2 14.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_14_5", + "path": "Runtime-ios-14.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://skia:skia_unittests/", + "variant_id": "iPad Air 2 14.5" + }, + { + "args": [ + "--platform", + "iPad Air 2", + "--version", + "15.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest" + ], + "isolate_name": "skia_unittests", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "skia_unittests iPad Air 2 15.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_15_5", + "path": "Runtime-ios-15.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://skia:skia_unittests/", + "variant_id": "iPad Air 2 15.5" + }, + { + "args": [ + "--platform", "iPad Pro (12.9-inch) (3rd generation)", "--version", "16.2", @@ -44100,6 +39555,222 @@ { "args": [ "--platform", + "iPhone 6s", + "--version", + "14.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest" + ], + "isolate_name": "skia_unittests", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "skia_unittests iPhone 6s 14.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_14_5", + "path": "Runtime-ios-14.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://skia:skia_unittests/", + "variant_id": "iPhone 6s 14.5" + }, + { + "args": [ + "--platform", + "iPhone 6s", + "--version", + "15.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest" + ], + "isolate_name": "skia_unittests", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "skia_unittests iPhone 6s 15.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_15_5", + "path": "Runtime-ios-15.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://skia:skia_unittests/", + "variant_id": "iPhone 6s 15.5" + }, + { + "args": [ + "--platform", + "iPhone 6s Plus", + "--version", + "14.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest" + ], + "isolate_name": "skia_unittests", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "skia_unittests iPhone 6s Plus 14.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_14_5", + "path": "Runtime-ios-14.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://skia:skia_unittests/", + "variant_id": "iPhone 6s Plus 14.5" + }, + { + "args": [ + "--platform", + "iPhone 6s Plus", + "--version", + "15.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest" + ], + "isolate_name": "skia_unittests", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "skia_unittests iPhone 6s Plus 15.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_15_5", + "path": "Runtime-ios-15.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://skia:skia_unittests/", + "variant_id": "iPhone 6s Plus 15.5" + }, + { + "args": [ + "--platform", "iPhone 8", "--version", "16.2", @@ -44208,6 +39879,114 @@ { "args": [ "--platform", + "iPhone SE (1st generation)", + "--version", + "14.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest" + ], + "isolate_name": "skia_unittests", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "skia_unittests iPhone SE (1st generation) 14.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_14_5", + "path": "Runtime-ios-14.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://skia:skia_unittests/", + "variant_id": "iPhone SE (1st generation) 14.5" + }, + { + "args": [ + "--platform", + "iPhone SE (1st generation)", + "--version", + "15.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest" + ], + "isolate_name": "skia_unittests", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "skia_unittests iPhone SE (1st generation) 15.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_15_5", + "path": "Runtime-ios-15.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://skia:skia_unittests/", + "variant_id": "iPhone SE (1st generation) 15.5" + }, + { + "args": [ + "--platform", "iPhone SE (3rd generation)", "--version", "16.2", @@ -44478,6 +40257,114 @@ { "args": [ "--platform", + "iPad Air 2", + "--version", + "14.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest" + ], + "isolate_name": "ui_base_unittests", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ui_base_unittests iPad Air 2 14.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_14_5", + "path": "Runtime-ios-14.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ui/base:ui_base_unittests/", + "variant_id": "iPad Air 2 14.5" + }, + { + "args": [ + "--platform", + "iPad Air 2", + "--version", + "15.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest" + ], + "isolate_name": "ui_base_unittests", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ui_base_unittests iPad Air 2 15.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_15_5", + "path": "Runtime-ios-15.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ui/base:ui_base_unittests/", + "variant_id": "iPad Air 2 15.5" + }, + { + "args": [ + "--platform", "iPad Pro (12.9-inch) (3rd generation)", "--version", "16.2", @@ -44532,6 +40419,222 @@ { "args": [ "--platform", + "iPhone 6s", + "--version", + "14.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest" + ], + "isolate_name": "ui_base_unittests", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ui_base_unittests iPhone 6s 14.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_14_5", + "path": "Runtime-ios-14.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ui/base:ui_base_unittests/", + "variant_id": "iPhone 6s 14.5" + }, + { + "args": [ + "--platform", + "iPhone 6s", + "--version", + "15.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest" + ], + "isolate_name": "ui_base_unittests", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ui_base_unittests iPhone 6s 15.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_15_5", + "path": "Runtime-ios-15.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ui/base:ui_base_unittests/", + "variant_id": "iPhone 6s 15.5" + }, + { + "args": [ + "--platform", + "iPhone 6s Plus", + "--version", + "14.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest" + ], + "isolate_name": "ui_base_unittests", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ui_base_unittests iPhone 6s Plus 14.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_14_5", + "path": "Runtime-ios-14.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ui/base:ui_base_unittests/", + "variant_id": "iPhone 6s Plus 14.5" + }, + { + "args": [ + "--platform", + "iPhone 6s Plus", + "--version", + "15.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest" + ], + "isolate_name": "ui_base_unittests", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ui_base_unittests iPhone 6s Plus 15.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_15_5", + "path": "Runtime-ios-15.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ui/base:ui_base_unittests/", + "variant_id": "iPhone 6s Plus 15.5" + }, + { + "args": [ + "--platform", "iPhone 8", "--version", "16.2", @@ -44640,6 +40743,114 @@ { "args": [ "--platform", + "iPhone SE (1st generation)", + "--version", + "14.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest" + ], + "isolate_name": "ui_base_unittests", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ui_base_unittests iPhone SE (1st generation) 14.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_14_5", + "path": "Runtime-ios-14.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ui/base:ui_base_unittests/", + "variant_id": "iPhone SE (1st generation) 14.5" + }, + { + "args": [ + "--platform", + "iPhone SE (1st generation)", + "--version", + "15.5", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "14c18", + "--readline-timeout", + "600", + "--xctest" + ], + "isolate_name": "ui_base_unittests", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ui_base_unittests iPhone SE (1st generation) 15.5", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + } + ], + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Mac-13" + } + ], + "named_caches": [ + { + "name": "xcode_ios_14c18", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_15_5", + "path": "Runtime-ios-15.5" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ui/base:ui_base_unittests/", + "variant_id": "iPhone SE (1st generation) 15.5" + }, + { + "args": [ + "--platform", "iPhone SE (3rd generation)", "--version", "16.2",
diff --git a/testing/buildbot/chromium.gpu.fyi.json b/testing/buildbot/chromium.gpu.fyi.json index ebb1ff2..6e21bf0 100644 --- a/testing/buildbot/chromium.gpu.fyi.json +++ b/testing/buildbot/chromium.gpu.fyi.json
@@ -5298,7 +5298,7 @@ "autotest_name": "chromium_Graphics", "bucket": "chromiumos-image-archive", "cros_board": "kevin", - "cros_img": "kevin-public/R113-15384.0.0", + "cros_img": "kevin-public/R114-15397.0.0", "extra_browser_args": "--log-level=0 --js-flags=--expose-gc --use-cmd-decoder=validating", "merge": { "args": [], @@ -5329,7 +5329,7 @@ "autotest_name": "chromium_Graphics", "bucket": "chromiumos-image-archive", "cros_board": "kevin", - "cros_img": "kevin-public/R113-15384.0.0", + "cros_img": "kevin-public/R114-15397.0.0", "extra_browser_args": "--log-level=0 --js-flags=--expose-gc", "merge": { "args": [], @@ -5360,7 +5360,7 @@ "autotest_name": "chromium_Graphics", "bucket": "chromiumos-image-archive", "cros_board": "kevin", - "cros_img": "kevin-public/R113-15384.0.0", + "cros_img": "kevin-public/R114-15397.0.0", "extra_browser_args": "--log-level=0 --js-flags=--expose-gc", "merge": { "args": [], @@ -5395,7 +5395,7 @@ "autotest_name": "chromium_Graphics", "bucket": "chromiumos-image-archive", "cros_board": "kevin", - "cros_img": "kevin-public/R113-15384.0.0", + "cros_img": "kevin-public/R114-15397.0.0", "extra_browser_args": "--log-level=0 --js-flags=--expose-gc --force_high_performance_gpu", "merge": { "args": [], @@ -5431,7 +5431,7 @@ "autotest_name": "chromium_Graphics", "bucket": "chromiumos-image-archive", "cros_board": "kevin", - "cros_img": "kevin-public/R113-15384.0.0", + "cros_img": "kevin-public/R114-15397.0.0", "extra_browser_args": "--log-level=0 --js-flags=--expose-gc --use-cmd-decoder=validating", "merge": { "args": [], @@ -5467,7 +5467,7 @@ "autotest_name": "chromium_Graphics", "bucket": "chromiumos-image-archive", "cros_board": "kevin", - "cros_img": "kevin-public/R113-15384.0.0", + "cros_img": "kevin-public/R114-15397.0.0", "extra_browser_args": "--log-level=0 --js-flags=--expose-gc --force_higher_performance_gpu --use-cmd-decoder=validating", "merge": { "args": [], @@ -5503,7 +5503,7 @@ "autotest_name": "chromium_Graphics", "bucket": "chromiumos-image-archive", "cros_board": "kevin", - "cros_img": "kevin-public/R113-15384.0.0", + "cros_img": "kevin-public/R114-15397.0.0", "extra_browser_args": "--log-level=0 --js-flags=--expose-gc --use-cmd-decoder=validating", "merge": { "args": [], @@ -5540,7 +5540,7 @@ "autotest_name": "chromium_Graphics", "bucket": "chromiumos-image-archive", "cros_board": "kevin", - "cros_img": "kevin-public/R113-15384.0.0", + "cros_img": "kevin-public/R114-15397.0.0", "extra_browser_args": "--log-level=0 --js-flags=--expose-gc --use-cmd-decoder=validating", "merge": { "args": [], @@ -5571,7 +5571,7 @@ "autotest_name": "chromium_Graphics", "bucket": "chromiumos-image-archive", "cros_board": "kevin", - "cros_img": "kevin-public/R113-15384.0.0", + "cros_img": "kevin-public/R114-15397.0.0", "extra_browser_args": "--log-level=0 --js-flags=--expose-gc", "merge": { "args": [], @@ -5602,7 +5602,7 @@ "autotest_name": "chromium_Graphics", "bucket": "chromiumos-image-archive", "cros_board": "kevin", - "cros_img": "kevin-public/R113-15384.0.0", + "cros_img": "kevin-public/R114-15397.0.0", "extra_browser_args": "--log-level=0 --js-flags=--expose-gc --use-cmd-decoder=validating", "merge": { "args": [], @@ -5636,7 +5636,7 @@ "autotest_name": "chromium_Graphics", "bucket": "chromiumos-image-archive", "cros_board": "kevin", - "cros_img": "kevin-public/R113-15384.0.0", + "cros_img": "kevin-public/R114-15397.0.0", "extra_browser_args": "--log-level=0 --js-flags=--expose-gc --use-gl=angle --use-angle=gles --use-cmd-decoder=passthrough --force_high_performance_gpu", "merge": { "args": [], @@ -5670,7 +5670,7 @@ "autotest_name": "chromium_Graphics", "bucket": "chromiumos-image-archive", "cros_board": "kevin", - "cros_img": "kevin-public/R113-15384.0.0", + "cros_img": "kevin-public/R114-15397.0.0", "extra_browser_args": "--log-level=0 --js-flags=--expose-gc --use-cmd-decoder=validating --force_high_performance_gpu", "merge": { "args": [], @@ -5703,7 +5703,7 @@ "autotest_name": "chromium_Graphics", "bucket": "chromiumos-image-archive", "cros_board": "kevin", - "cros_img": "kevin-public/R113-15384.0.0", + "cros_img": "kevin-public/R114-15397.0.0", "extra_browser_args": "--log-level=0 --js-flags=--expose-gc --use-cmd-decoder=validating --force_high_performance_gpu", "merge": { "args": [],
diff --git a/testing/buildbot/filters/BUILD.gn b/testing/buildbot/filters/BUILD.gn index 7916ecb..b03b87fe 100644 --- a/testing/buildbot/filters/BUILD.gn +++ b/testing/buildbot/filters/BUILD.gn
@@ -87,6 +87,7 @@ "//testing/buildbot/filters/android.pie_arm64_rel.chrome_public_test_apk.filter", "//testing/buildbot/filters/android.emulator_11.chrome_public_test_apk.filter", "//testing/buildbot/filters/android.emulator_12.chrome_public_test_apk.filter", + "//testing/buildbot/filters/android.emulator_12l.chrome_public_test_apk.filter", "//testing/buildbot/filters/android.emulator_n.chrome_public_test_apk.filter", "//testing/buildbot/filters/android.emulator_p.chrome_public_test_apk.filter", ]
diff --git a/testing/buildbot/filters/android.emulator_12l.chrome_public_test_apk.filter b/testing/buildbot/filters/android.emulator_12l.chrome_public_test_apk.filter new file mode 100644 index 0000000..50320e04 --- /dev/null +++ b/testing/buildbot/filters/android.emulator_12l.chrome_public_test_apk.filter
@@ -0,0 +1,37 @@ +# crbug.com/1193745 +-org.chromium.chrome.browser.download.OMADownloadHandlerTest.testClearPendingOMADownloads +-org.chromium.chrome.browser.download.OMADownloadHandlerTest.testQueryDownloadResult + +# crbug.com/1036571 +-org.chromium.chrome.browser.shape_detection.ShapeDetectionTest.testTextDetection + +# crbug.com/1036556 +-org.chromium.chrome.browser.usage_stats.TabSuspensionTest.testMediaSuspension +-org.chromium.chrome.browser.usage_stats.TabSuspensionTest.testTabAddedFromCustomTab +-org.chromium.chrome.browser.usage_stats.TabSuspensionTest.testMultiWindow + +# crbug.com/1195097 +-org.chromium.chrome.browser.permissions.RuntimePermissionTest.testDenyRuntimeDownload + +# crbug.com/1225709 +-org.chromium.chrome.browser.contextmenu.ContextMenuTest.testSaveDataUrl +-org.chromium.chrome.browser.contextmenu.ContextMenuTest.testSaveImage +-org.chromium.chrome.browser.contextmenu.ContextMenuTest.testSaveVideo +-org.chromium.components.browser_ui.share.ShareImageFileUtilsTest.testSaveBitmapAndMediaStore + +# crbug.com/1225754 +-org.chromium.chrome.browser.offlinepages.OfflinePageBridgeTest.testGetLoadUrlParamsForOpeningMhtmlFileUrl + +# crbug.com/1231227 +-org.chromium.chrome.browser.webapps.WebappDisplayModeTest.testFullScreen +-org.chromium.chrome.browser.webapps.WebappDisplayModeTest.testFullScreenInFullscreen + +# crbug.com/1231652 +-org.chromium.chrome.browser.autofill.settings.AutofillProfilesFragmentTest.testKeyboardShownOnDpadCenter + +# crbug.com/1297370 +-org.chromium.chrome.browser.multiwindow.MultiWindowIntegrationTest.* +-org.chromium.chrome.browser.multiwindow.MultiWindowUtilsTest.* +-org.chromium.chrome.browser.tabmodel.TabModelMergingTest.* +-org.chromium.chrome.browser.tabmodel.UndoTabModelTest.testOpenRecentlyClosedTabMultiWindow +-org.chromium.chrome.browser.tabmodel.UndoTabModelTest.testOpenRecentlyClosedTabMultiWindowFallback
diff --git a/testing/buildbot/filters/android.emulator_12l_13.content_browsertests.filter b/testing/buildbot/filters/android.emulator_12l_13.content_browsertests.filter index 0195205..151cfec 100644 --- a/testing/buildbot/filters/android.emulator_12l_13.content_browsertests.filter +++ b/testing/buildbot/filters/android.emulator_12l_13.content_browsertests.filter
@@ -21,3 +21,10 @@ # crbug.com/1420817 -WebRtcMediaRecorderTest.PausePreventsDataavailableFromBeingFired -WebRtcMediaRecorderTest.Start + +# crbug.com/1428296 +-All/WebRtcCaptureFromElementBrowserTest.CaptureFromMediaElement/0 +-All/WebRtcCaptureFromElementBrowserTest.CaptureFromMediaElement/2 + +# crbug.com/1428300 +-OpenCodec/WebRtcMediaRecorderTest.StartAndDataAvailable/2
diff --git a/testing/buildbot/mixins.pyl b/testing/buildbot/mixins.pyl index 77b7890..cbb5d1d8 100644 --- a/testing/buildbot/mixins.pyl +++ b/testing/buildbot/mixins.pyl
@@ -416,7 +416,7 @@ }, 'chromeos-kevin-skylab': { 'cros_board': 'kevin', - 'cros_img': 'kevin-public/R113-15384.0.0', + 'cros_img': 'kevin-public/R114-15397.0.0', 'bucket': 'chromiumos-image-archive', 'timeout_sec': 10800, },
diff --git a/testing/buildbot/test_suite_exceptions.pyl b/testing/buildbot/test_suite_exceptions.pyl index 836605f..e982ac54 100644 --- a/testing/buildbot/test_suite_exceptions.pyl +++ b/testing/buildbot/test_suite_exceptions.pyl
@@ -1427,6 +1427,11 @@ 'ci_only': True, 'experiment_percentage': 100, }, + 'android-12l-x64-dbg-tests': { + 'args': [ + '--test-launcher-filter-file=../../testing/buildbot/filters/android.emulator_12l.chrome_public_test_apk.filter', + ], + }, 'android-arm64-proguard-rel': { 'swarming': { 'shards': 25,
diff --git a/testing/buildbot/test_suites.pyl b/testing/buildbot/test_suites.pyl index 2ab4355..d135a2a 100644 --- a/testing/buildbot/test_suites.pyl +++ b/testing/buildbot/test_suites.pyl
@@ -6949,49 +6949,6 @@ }, }, - 'ios15_sdk_simulator_tests': { - 'ios_common_tests': { - 'variants': [ - 'SIM_IPHONE_6S_15_5', - 'SIM_IPHONE_6S_14_5', - ], - }, - 'ios_eg2_tests': { - 'mixins': ['xcode_parallelization'], - 'variants': [ - 'SIM_IPHONE_7_15_5', - 'SIM_IPAD_AIR_2_15_5', - 'SIM_IPHONE_X_15_5', - 'SIM_IPHONE_7_14_5', - 'SIM_IPAD_AIR_2_14_5', - 'SIM_IPHONE_X_14_5', - ] - }, - 'ios_eg2_cq_tests': { - 'mixins': ['xcode_parallelization'], - 'variants': [ - 'SIM_IPHONE_7_15_5', - 'SIM_IPAD_AIR_2_15_5', - 'SIM_IPHONE_X_15_5', - 'SIM_IPHONE_7_14_5', - 'SIM_IPAD_AIR_2_14_5', - 'SIM_IPHONE_X_14_5', - ] - }, - 'ios_screen_size_dependent_tests': { - 'variants': [ - 'SIM_IPHONE_6S_PLUS_14_5', - 'SIM_IPHONE_6S_14_5', - 'SIM_IPHONE_SE_1ST_GEN_14_5', - 'SIM_IPAD_AIR_2_14_5', - 'SIM_IPHONE_6S_PLUS_15_5', - 'SIM_IPHONE_6S_15_5', - 'SIM_IPHONE_SE_1ST_GEN_15_5', - 'SIM_IPAD_AIR_2_15_5', - ], - }, - }, - 'ios16_beta_simulator_tests': { 'ios_common_tests': { 'variants': [ @@ -7066,6 +7023,7 @@ 'SIM_IPAD_AIR_2_15_5', 'SIM_IPHONE_X_15_5', 'SIM_IPHONE_7_14_5', + 'SIM_IPHONE_7_15_5', 'SIM_IPAD_AIR_2_14_5', 'SIM_IPHONE_X_14_5', 'SIM_IPAD_PRO_3RD_GEN_15_5', @@ -7095,6 +7053,14 @@ 'SIM_IPHONE_SE_3RD_GEN_16_2', 'SIM_IPAD_AIR_3RD_GEN_16_2', 'SIM_IPAD_PRO_3RD_GEN_16_2', + 'SIM_IPHONE_6S_PLUS_14_5', + 'SIM_IPHONE_6S_14_5', + 'SIM_IPHONE_SE_1ST_GEN_14_5', + 'SIM_IPAD_AIR_2_14_5', + 'SIM_IPHONE_6S_PLUS_15_5', + 'SIM_IPHONE_6S_15_5', + 'SIM_IPHONE_SE_1ST_GEN_15_5', + 'SIM_IPAD_AIR_2_15_5', ], }, 'ios_swift_interop_xcuitests': {
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl index 2a573c2..d8d1ff92 100644 --- a/testing/buildbot/waterfalls.pyl +++ b/testing/buildbot/waterfalls.pyl
@@ -3383,9 +3383,6 @@ 'xcode_14_main', 'xctest', ], - 'test_suites': { - 'isolated_scripts': 'ios15_sdk_simulator_tests' - }, }, # ios16-beta-sim compiles with xcode version n-1, but # runs testers with xcode n during an xcode roll.
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index 8a3fbf9a..7ad0648 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -374,7 +374,6 @@ "disable_features": [ "AndroidScrollOptimizations", "CacheSiteIsolationMemoryThreshold", - "NewSigninRequestHeaderCheckOrder", "UseGetrandomForRandBytes" ] } @@ -4789,6 +4788,24 @@ ] } ], + "EndOfLifeIncentive": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "EnabledOffer_20230324", + "params": { + "incentive_type": "offer" + }, + "enable_features": [ + "EolIncentive" + ] + } + ] + } + ], "EnterpriseReportingConnectorExtensionEvents": [ { "platforms": [
diff --git a/third_party/blink/public/web/web_ax_context.h b/third_party/blink/public/web/web_ax_context.h index b74820da..78f8f635 100644 --- a/third_party/blink/public/web/web_ax_context.h +++ b/third_party/blink/public/web/web_ax_context.h
@@ -70,6 +70,10 @@ bool& had_load_complete_messages, bool& need_to_send_location_changes); + // Returns a vector of the images found in |updates|. + void GetImagesToAnnotate(ui::AXTreeUpdate& updates, + std::vector<ui::AXNodeData*>&); + // Clears out the list of dirty AXObjects and of pending events. void ClearDirtyObjectsAndPendingEvents();
diff --git a/third_party/blink/renderer/core/accessibility/ax_object_cache.h b/third_party/blink/renderer/core/accessibility/ax_object_cache.h index ada944f..52484cc3 100644 --- a/third_party/blink/renderer/core/accessibility/ax_object_cache.h +++ b/third_party/blink/renderer/core/accessibility/ax_object_cache.h
@@ -245,6 +245,10 @@ bool& had_load_complete_messages, bool& need_to_send_location_changes) = 0; + // Returns a vector of the images found in |updates|. + virtual void GetImagesToAnnotate(ui::AXTreeUpdate& updates, + std::vector<ui::AXNodeData*>&) = 0; + virtual void ClearDirtyObjectsAndPendingEvents() = 0; // Note that any pending event also causes its corresponding object to
diff --git a/third_party/blink/renderer/core/animation/interpolable_grid_track_list.cc b/third_party/blink/renderer/core/animation/interpolable_grid_track_list.cc index d5effbf..d7255b8 100644 --- a/third_party/blink/renderer/core/animation/interpolable_grid_track_list.cc +++ b/third_party/blink/renderer/core/animation/interpolable_grid_track_list.cc
@@ -35,7 +35,8 @@ const NGGridTrackRepeater repeater( track_list.RepeatIndex(i), track_list.RepeatSize(i), - track_list.RepeatCount(i, 0), track_list.RepeatType(i)); + track_list.RepeatCount(i, 0), track_list.LineNameIndicesCount(i), + track_list.RepeatType(i)); std::unique_ptr<InterpolableGridTrackRepeater> result = InterpolableGridTrackRepeater::Create(repeater, repeater_track_sizes, zoom);
diff --git a/third_party/blink/renderer/core/css/properties/computed_style_utils.cc b/third_party/blink/renderer/core/css/properties/computed_style_utils.cc index 18690c3..ea9f5b1 100644 --- a/third_party/blink/renderer/core/css/properties/computed_style_utils.cc +++ b/third_party/blink/renderer/core/css/properties/computed_style_utils.cc
@@ -1411,22 +1411,21 @@ return nullptr; } -enum GridTrackListSerializationType { - kForGridElements, - kForNonGridElements, - kForRepeatNonGridElements, -}; - +enum class NamedLinesType { kNamedLines, kAutoRepeatNamedLines }; class OrderedNamedLinesCollector { STACK_ALLOCATED(); public: OrderedNamedLinesCollector( const OrderedNamedGridLines& ordered_named_grid_lines, - const OrderedNamedGridLines& ordered_named_auto_repeat_grid_lines) + const OrderedNamedGridLines& ordered_named_auto_repeat_grid_lines, + bool is_subgridded_track, + bool is_layout_grid) : ordered_named_grid_lines_(ordered_named_grid_lines), ordered_named_auto_repeat_grid_lines_( - ordered_named_auto_repeat_grid_lines) {} + ordered_named_auto_repeat_grid_lines), + is_subgridded_axis_(is_subgridded_track), + is_layout_grid_(is_layout_grid) {} OrderedNamedLinesCollector(const OrderedNamedLinesCollector&) = delete; OrderedNamedLinesCollector& operator=(const OrderedNamedLinesCollector&) = delete; @@ -1439,55 +1438,52 @@ bool IsSubgriddedAxis() const { return is_subgridded_axis_; } wtf_size_t InsertionPoint() const { return insertion_point_; } bool HasAutoRepeatNamedLinesSpecified() const { - return ordered_named_auto_repeat_grid_lines_.size() > 0; + return AutoRepeatNamedLinesCount() > 0; + } + wtf_size_t AutoRepeatNamedLinesCount() const { + return ordered_named_auto_repeat_grid_lines_.size(); } // A collapsed auto repeat track is a specified auto-repeat track that was // clamped to zero repeats. This can only happen for subgrids, as - // standalone grids guarantee a minimum of 1 repeat. + // standalone grids guarantee a minimum of 1 repeat. This also requires that + // auto repetitions were computed, which only happens for layout grids. bool HasCollapsedAutoRepeatNamedLines() const { - return IsSubgriddedAxis() && HasAutoRepeatNamedLinesSpecified() && - auto_repeat_total_tracks_ == 0; + return is_layout_grid_ && IsSubgriddedAxis() && + HasAutoRepeatNamedLinesSpecified() && auto_repeat_total_tracks_ == 0; } - virtual void CollectLineNamesForIndex( - cssvalue::CSSBracketedValueList&, - wtf_size_t index, - GridTrackListSerializationType named_line_type = kForGridElements) const; + virtual void CollectLineNamesForIndex(cssvalue::CSSBracketedValueList&, + wtf_size_t index, + NamedLinesType type, + bool is_in_repeat) const; protected: - enum NamedLinesType { kNamedLines, kAutoRepeatNamedLines }; - void AppendLines( - cssvalue::CSSBracketedValueList&, - wtf_size_t index, - NamedLinesType, - GridTrackListSerializationType named_line_type = kForGridElements) const; + void AppendLines(cssvalue::CSSBracketedValueList&, + wtf_size_t index, + NamedLinesType, + bool is_in_repeat = false) const; const OrderedNamedGridLines& ordered_named_grid_lines_; const OrderedNamedGridLines& ordered_named_auto_repeat_grid_lines_; + // The auto-repeat index. wtf_size_t insertion_point_{0}; + // The total number of auto-repeat tracks, factoring in the number of // repetitions (e.g. `repeat(auto-fit, [a][b])` with `auto-fit` calculated at // 3 repetitions would be 6). wtf_size_t auto_repeat_total_tracks_{0}; + // The size of one auto repeat track (e.g. `repeat(auto-fit, [a][b])` has an // auto repeat track list length of 2, regardless of the number of repetitions // computed for `auto-fit`). wtf_size_t auto_repeat_track_list_length_{0}; - bool is_subgridded_axis_{false}; -}; -class OrderedNamedLinesCollectorInsideAutoRepeat - : public OrderedNamedLinesCollector { - public: - OrderedNamedLinesCollectorInsideAutoRepeat( - const OrderedNamedGridLines& ordered_named_grid_lines, - const OrderedNamedGridLines& ordered_named_auto_repeat_grid_lines) - : OrderedNamedLinesCollector(ordered_named_grid_lines, - ordered_named_auto_repeat_grid_lines) {} - void CollectLineNamesForIndex(cssvalue::CSSBracketedValueList&, - wtf_size_t index, - GridTrackListSerializationType named_line_type = - kForGridElements) const override; + // Whether the track definition has `subgrid` specified. + bool is_subgridded_axis_{false}; + + // Whether the element associated with the track collection performs grid + // layout. + bool is_layout_grid_{false}; }; class OrderedNamedLinesCollectorInGridLayout @@ -1499,48 +1495,45 @@ wtf_size_t insertion_point, wtf_size_t auto_repeat_total_tracks, wtf_size_t auto_repeat_track_list_length, - bool is_subgridded_axis = false) + bool is_subgridded_track) : OrderedNamedLinesCollector(ordered_named_grid_lines, - ordered_named_auto_repeat_grid_lines) { + ordered_named_auto_repeat_grid_lines, + is_subgridded_track, + /* is_layout_grid */ true) { insertion_point_ = insertion_point; - is_subgridded_axis_ = is_subgridded_axis; auto_repeat_total_tracks_ = auto_repeat_total_tracks; auto_repeat_track_list_length_ = auto_repeat_track_list_length; } void CollectLineNamesForIndex(cssvalue::CSSBracketedValueList&, wtf_size_t index, - GridTrackListSerializationType named_line_type = - kForGridElements) const override; + NamedLinesType type, + bool is_in_repeat) const override; }; void OrderedNamedLinesCollector::AppendLines( cssvalue::CSSBracketedValueList& line_names_value, wtf_size_t index, NamedLinesType type, - GridTrackListSerializationType named_line_type) const { - auto iter = type == kNamedLines - ? ordered_named_grid_lines_.find(index) - : ordered_named_auto_repeat_grid_lines_.find(index); - auto end_iter = type == kNamedLines - ? ordered_named_grid_lines_.end() - : ordered_named_auto_repeat_grid_lines_.end(); + bool is_in_repeat) const { + const bool is_auto = type == NamedLinesType::kAutoRepeatNamedLines; + auto iter = is_auto ? ordered_named_auto_repeat_grid_lines_.find(index) + : ordered_named_grid_lines_.find(index); + auto end_iter = is_auto ? ordered_named_auto_repeat_grid_lines_.end() + : ordered_named_grid_lines_.end(); if (iter == end_iter) { return; } for (auto named_grid_line : iter->value) { - // A line name is appended when: - // 1. The layout object is the grid. - // 2. The layout object is not the grid and the named line isn't part of an - // integer repeat. - // 3. The layout object is not the grid, the named line is part of the - // repeat and is the first time it appears in |ordered_named_grid_lines_|. - const bool is_first_repeat = - named_grid_line.is_in_repeat && named_grid_line.is_first_repeat; - if (named_line_type == kForGridElements || - (named_line_type == kForNonGridElements && - !named_grid_line.is_in_repeat) || - (named_line_type == kForRepeatNonGridElements && is_first_repeat)) { + // For layout grids, insert all values. For non-layout grids, in order to + // round-trip repeaters, we need to prevent inserting certain line names. + // In particular, don't insert lines from repeaters if we're not in a + // repeater, and only add the first repeat. + const bool is_not_in_repeat = + !is_in_repeat && !named_grid_line.is_in_repeat; + const bool is_valid_repeat_line = + is_in_repeat && named_grid_line.is_first_repeat; + if (is_layout_grid_ || is_not_in_repeat || is_valid_repeat_line) { line_names_value.Append(*MakeGarbageCollected<CSSCustomIdentValue>( AtomicString(named_grid_line.line_name))); } @@ -1550,29 +1543,23 @@ void OrderedNamedLinesCollector::CollectLineNamesForIndex( cssvalue::CSSBracketedValueList& line_names_value, wtf_size_t i, - GridTrackListSerializationType named_line_type) const { + NamedLinesType type, + bool is_in_repeat) const { DCHECK(IsSubgriddedAxis() || !IsEmpty()); - AppendLines(line_names_value, i, kNamedLines, named_line_type); -} - -void OrderedNamedLinesCollectorInsideAutoRepeat::CollectLineNamesForIndex( - cssvalue::CSSBracketedValueList& line_names_value, - wtf_size_t i, - GridTrackListSerializationType named_line_type) const { - DCHECK(IsSubgriddedAxis() || !IsEmpty()); - AppendLines(line_names_value, i, kAutoRepeatNamedLines); + AppendLines(line_names_value, i, type, is_in_repeat); } void OrderedNamedLinesCollectorInGridLayout::CollectLineNamesForIndex( cssvalue::CSSBracketedValueList& line_names_value, wtf_size_t i, - GridTrackListSerializationType named_line_type) const { + NamedLinesType type, + bool is_in_repeat) const { DCHECK(IsSubgriddedAxis() || !IsEmpty()); // Handle lines before the auto repeat insertion point. If we don't have any // auto repeat tracks, we can skip all of the auto repeat logic below. if (auto_repeat_total_tracks_ == 0LU || i < insertion_point_) { - AppendLines(line_names_value, i, kNamedLines); + AppendLines(line_names_value, i, NamedLinesType::kNamedLines); return; } @@ -1581,22 +1568,23 @@ // Handle tracks after the auto repeaters. if (i > insertion_point_ + auto_repeat_total_tracks_) { AppendLines(line_names_value, i - (auto_repeat_total_tracks_ - 1), - kNamedLines); + NamedLinesType::kNamedLines); return; } // Handle the auto repeat track at the insertion point. if (i == insertion_point_) { - AppendLines(line_names_value, i, kNamedLines); - AppendLines(line_names_value, 0, kAutoRepeatNamedLines); + AppendLines(line_names_value, i, NamedLinesType::kNamedLines); + AppendLines(line_names_value, 0, NamedLinesType::kAutoRepeatNamedLines); return; } // Handle the final auto repeat track. if (i == insertion_point_ + auto_repeat_total_tracks_) { AppendLines(line_names_value, auto_repeat_track_list_length_, - kAutoRepeatNamedLines); - AppendLines(line_names_value, insertion_point_ + 1, kNamedLines); + NamedLinesType::kAutoRepeatNamedLines); + AppendLines(line_names_value, insertion_point_ + 1, + NamedLinesType::kNamedLines); return; } @@ -1605,17 +1593,17 @@ (i - insertion_point_) % auto_repeat_track_list_length_; if (!auto_repeat_index_in_first_repetition && i > insertion_point_) { AppendLines(line_names_value, auto_repeat_track_list_length_, - kAutoRepeatNamedLines); + NamedLinesType::kAutoRepeatNamedLines); } AppendLines(line_names_value, auto_repeat_index_in_first_repetition, - kAutoRepeatNamedLines); + NamedLinesType::kAutoRepeatNamedLines); } -void AddValuesForNamedGridLinesAtIndex( - OrderedNamedLinesCollector& collector, - wtf_size_t i, - CSSValueList& list, - GridTrackListSerializationType named_line_type = kForGridElements) { +void AddValuesForNamedGridLinesAtIndex(OrderedNamedLinesCollector& collector, + wtf_size_t i, + CSSValueList& list, + NamedLinesType type, + bool is_in_repeat = false) { if (collector.IsSubgriddedAxis()) { // Skip collapsed lines at the auto repeat insertion point. if (i == collector.InsertionPoint() && @@ -1627,7 +1615,7 @@ } auto* line_names = MakeGarbageCollected<cssvalue::CSSBracketedValueList>(); - collector.CollectLineNamesForIndex(*line_names, i, named_line_type); + collector.CollectLineNamesForIndex(*line_names, i, type, is_in_repeat); // Subgridded track listings include empty lines per // https://www.w3.org/TR/css-grid-2/#resolved-track-list-subgrid. @@ -1663,11 +1651,10 @@ return list; } -template <typename T, typename F> void PopulateGridTrackList(CSSValueList* list, OrderedNamedLinesCollector& collector, - const Vector<T, 1>& tracks, - F GetTrackSize, + const Vector<LayoutUnit, 1>& tracks, + const ComputedStyle& style, wtf_size_t start, wtf_size_t end, int offset) { @@ -1683,19 +1670,198 @@ } for (wtf_size_t i = start; i < end; ++i) { if (offset >= 0 || i >= static_cast<wtf_size_t>(-offset)) { - AddValuesForNamedGridLinesAtIndex(collector, i + offset, *list); + AddValuesForNamedGridLinesAtIndex(collector, i + offset, *list, + NamedLinesType::kNamedLines); } // Subgrids do not include sizes in the track listing. if (!collector.IsSubgriddedAxis()) { DCHECK_LE(i, tracks.size()); - list->Append(*GetTrackSize(tracks[i])); + list->Append(*ZoomAdjustedPixelValue(tracks[i], style)); } } // Subgrid track names are always relative to offset 0, so they can ignore the // tracks after the offset. if (!collector.IsSubgriddedAxis() && (offset >= 0 || end >= static_cast<wtf_size_t>(-offset))) { - AddValuesForNamedGridLinesAtIndex(collector, end + offset, *list); + AddValuesForNamedGridLinesAtIndex(collector, end + offset, *list, + NamedLinesType::kNamedLines); + } +} + +void PopulateNonRepeater(CSSValueList* list, + OrderedNamedLinesCollector& collector, + const blink::NGGridTrackList& track_list, + wtf_size_t repeater_index, + wtf_size_t track_index, + const ComputedStyle& style) { + DCHECK_EQ(track_list.RepeatType(repeater_index), + NGGridTrackRepeater::RepeatType::kNoRepeat); + + AddValuesForNamedGridLinesAtIndex(collector, track_index, *list, + NamedLinesType::kNamedLines); + // Subgrid definitions do not include track sizes. + if (!track_list.IsSubgriddedAxis()) { + list->Append(*ComputedStyleUtils::SpecifiedValueForGridTrackSize( + track_list.RepeatTrackSize(repeater_index, 0), style)); + } +} + +void PopulateAutoRepeater(CSSValueList* list, + OrderedNamedLinesCollector& collector, + const blink::NGGridTrackList& track_list, + wtf_size_t repeater_index, + const ComputedStyle& style) { + blink::NGGridTrackRepeater::RepeatType repeat_type = + track_list.RepeatType(repeater_index); + DCHECK(repeat_type == NGGridTrackRepeater::RepeatType::kAutoFill || + repeat_type == NGGridTrackRepeater::RepeatType::kAutoFit); + + const bool is_subgrid = track_list.IsSubgriddedAxis(); + CSSValueList* repeated_values; + wtf_size_t repeat_size = is_subgrid + ? track_list.LineNameIndicesCount(repeater_index) + : track_list.RepeatSize(repeater_index); + + repeated_values = MakeGarbageCollected<cssvalue::CSSGridAutoRepeatValue>( + repeat_type == NGGridTrackRepeater::RepeatType::kAutoFill + ? CSSValueID::kAutoFill + : CSSValueID::kAutoFit); + + // Unlike integer repeats, line names for auto repeats start at index 0 and go + // to `repeat_size`. This is because auto repeat named lines are in their own + // line name collection, while line names for integer repeats are expanded and + // interspersed with non-repeaters in the track list. + for (wtf_size_t i = 0; i < repeat_size; ++i) { + AddValuesForNamedGridLinesAtIndex(collector, i, *repeated_values, + NamedLinesType::kAutoRepeatNamedLines); + + // Subgrids do not support track sizes. + if (!is_subgrid) { + const GridTrackSize& track_size = + track_list.RepeatTrackSize(repeater_index, i); + repeated_values->Append( + *ComputedStyleUtils::SpecifiedValueForGridTrackSize(track_size, + style)); + } + } + + // Add any additional auto repeat line names after size definitions. + for (wtf_size_t i = repeat_size; i < collector.AutoRepeatNamedLinesCount(); + ++i) { + AddValuesForNamedGridLinesAtIndex(collector, i, *repeated_values, + NamedLinesType::kAutoRepeatNamedLines); + } + // Subgrids allow for empty line definitions. + if (is_subgrid && repeat_size == 0) { + repeated_values->Append( + *MakeGarbageCollected<cssvalue::CSSBracketedValueList>()); + } + + list->Append(*repeated_values); +} + +// Returns the number of tracks populated after expanding repetitions. +wtf_size_t PopulateIntegerRepeater(CSSValueList* list, + OrderedNamedLinesCollector& collector, + const blink::NGGridTrackList& track_list, + wtf_size_t repeater_index, + wtf_size_t track_index, + const ComputedStyle& style) { + const bool is_subgrid = track_list.IsSubgriddedAxis(); + CSSValueList* repeated_values; + wtf_size_t number_of_repetitions = track_list.RepeatCount(repeater_index, 0); + wtf_size_t repeat_size = is_subgrid + ? track_list.LineNameIndicesCount(repeater_index) + : track_list.RepeatSize(repeater_index); + + repeated_values = MakeGarbageCollected<cssvalue::CSSGridIntegerRepeatValue>( + number_of_repetitions); + + // Line names for integer repeats get expanded and interspersed with + // non-repeaters in the track list. + for (wtf_size_t i = 0; i < repeat_size; ++i) { + AddValuesForNamedGridLinesAtIndex( + collector, track_index + i, *repeated_values, + NamedLinesType::kNamedLines, /* is_in_repeat */ true); + + // Subgrids do not support track sizes. + if (!is_subgrid) { + const GridTrackSize& track_size = + track_list.RepeatTrackSize(repeater_index, i); + repeated_values->Append( + *ComputedStyleUtils::SpecifiedValueForGridTrackSize(track_size, + style)); + } + } + + // Standalone grids may have line names after track sizes. + if (!is_subgrid) { + AddValuesForNamedGridLinesAtIndex( + collector, track_index + repeat_size, *repeated_values, + NamedLinesType::kNamedLines, /* is_in_repeat */ true); + } else if (repeat_size == 0) { + // Subgrids allow for empty line definitions. + repeated_values->Append( + *MakeGarbageCollected<cssvalue::CSSBracketedValueList>()); + } + + list->Append(*repeated_values); + + return repeat_size * number_of_repetitions; +} + +void PopulateGridTrackListForNonGrid(CSSValueList* list, + OrderedNamedLinesCollector& collector, + const blink::NGGridTrackList& track_list, + const ComputedStyle& style) { + const bool is_subgrid = collector.IsSubgriddedAxis(); + wtf_size_t track_index = 0; + + // Iterate over each repeater. This will cover all tracks because even non + // repeats will add repeaters of type `kNoRepeat` to their track list. + for (wtf_size_t i = 0; i < track_list.RepeaterCount(); ++i) { + switch (track_list.RepeatType(i)) { + case NGGridTrackRepeater::RepeatType::kNoRepeat: + PopulateNonRepeater(list, collector, track_list, i, track_index, style); + + // Non repeaters always consume one track index. + ++track_index; + break; + + case NGGridTrackRepeater::RepeatType::kInteger: + // Standalone grids can have line names between sizes and repeaters. + if (!is_subgrid) { + AddValuesForNamedGridLinesAtIndex(collector, track_index, *list, + NamedLinesType::kNamedLines); + } + // `PopulateIntegerRepeater` will return the number of tracks populated. + // We need to update `track_index` by this value, as the track list + // has expanded integer repeaters and interspersed them with + // non-repeaters. + track_index += PopulateIntegerRepeater(list, collector, track_list, i, + track_index, style); + break; + + case NGGridTrackRepeater::RepeatType::kAutoFill: + case NGGridTrackRepeater::RepeatType::kAutoFit: + // Standalone grids can have line names between sizes and repeaters. + if (!is_subgrid) { + AddValuesForNamedGridLinesAtIndex(collector, track_index, *list, + NamedLinesType::kNamedLines); + } + PopulateAutoRepeater(list, collector, track_list, i, style); + + // Auto repeaters always consume one track index. + ++track_index; + break; + default: + NOTREACHED(); + } + } + // Standalone grids can have line names after sizes and repeaters. + if (!is_subgrid) { + AddValuesForNamedGridLinesAtIndex(collector, track_index, *list, + NamedLinesType::kNamedLines); } } @@ -1706,11 +1872,6 @@ const bool is_for_columns = direction == kForColumns; const ComputedGridTrackList& computed_grid_track_list = is_for_columns ? style.GridTemplateColumns() : style.GridTemplateRows(); - const Vector<GridTrackSize, 1>& legacy_track_sizes = - computed_grid_track_list.track_sizes.LegacyTrackList(); - const Vector<GridTrackSize, 1>& auto_repeat_track_sizes = - computed_grid_track_list.auto_repeat_track_sizes; - const bool is_layout_grid = layout_object && layout_object->IsLayoutNGGrid(); // Handle the 'none' case. @@ -1727,14 +1888,22 @@ is_track_list_empty = positions.size() == 1; } - if (is_track_list_empty) { + const bool is_subgrid = computed_grid_track_list.IsSubgriddedAxis(); + + // Even if the track list is empty or it's not actually a grid/subgrid in + // layout, if the author specified `subgrid`, the computed value should always + // begin with `subgrid` and cannot be `none`. + CSSValueList* list = CSSValueList::CreateSpaceSeparated(); + if (is_subgrid) { + list->Append( + *MakeGarbageCollected<CSSIdentifierValue>(CSSValueID::kSubgrid)); + } else if (is_track_list_empty) { return CSSIdentifierValue::Create(CSSValueID::kNone); } - CSSValueList* list = CSSValueList::CreateSpaceSeparated(); wtf_size_t auto_repeat_insertion_point = computed_grid_track_list.auto_repeat_insertion_point; - const bool is_subgrid = computed_grid_track_list.IsSubgriddedAxis(); + const NGGridTrackList& ng_track_list = computed_grid_track_list.TrackList(); if (is_layout_grid) { const auto* grid = ToInterface<LayoutNGGridInterface>(layout_object); @@ -1753,9 +1922,6 @@ wtf_size_t start_index = 0; wtf_size_t end_index = track_sizes.size(); if (is_subgrid) { - list->Append( - *MakeGarbageCollected<CSSIdentifierValue>(CSSValueID::kSubgrid)); - // For subgrids, track sizes are not supported. Instead, calculate the end // index by subtracting the grid end from its start. start_index = grid->ExplicitGridStartForDirection(direction); @@ -1771,9 +1937,6 @@ auto_repeat_insertion_point, grid->AutoRepeatCountForDirection(direction), auto_repeat_track_list_length, is_subgrid); - auto GetTrackSize = [&](const LayoutUnit& v) { - return ZoomAdjustedPixelValue(v, style); - }; // Named grid line indices are relative to the explicit grid, but we are // including all tracks. So we need to subtract the number of leading // implicit tracks in order to get the proper line index. This is ignored @@ -1781,97 +1944,17 @@ int offset = -base::checked_cast<int>( grid->ExplicitGridStartForDirection(direction)); - PopulateGridTrackList(list, collector, track_sizes, GetTrackSize, - start_index, end_index, offset); + PopulateGridTrackList(list, collector, track_sizes, style, start_index, + end_index, offset); return list; } // Otherwise, the resolved value is the computed value, preserving repeat(). OrderedNamedLinesCollector collector( computed_grid_track_list.ordered_named_grid_lines, - computed_grid_track_list.auto_repeat_ordered_named_grid_lines); - auto GetTrackSize = [&](const GridTrackSize& v) { - return SpecifiedValueForGridTrackSize(v, style); - }; - - if (auto_repeat_track_sizes.empty()) { - // TODO(ansollan): Add support for track lists with auto and integer - // repeaters. - wtf_size_t track_index = 0; - auto AppendValues = [&](CSSValueList* list, const GridTrackSize& track_size, - GridTrackListSerializationType named_line_type) { - AddValuesForNamedGridLinesAtIndex(collector, track_index, *list, - named_line_type); - list->Append(*GetTrackSize(track_size)); - ++track_index; - }; - - const NGGridTrackList& ng_track_list = computed_grid_track_list.TrackList(); - for (wtf_size_t i = 0; i < ng_track_list.RepeaterCount(); ++i) { - const auto repeat_type = ng_track_list.RepeatType(i); - - // Add the line names and track sizes that aren't part of the repeat. - if (repeat_type == NGGridTrackRepeater::RepeatType::kNoRepeat) { - AppendValues(list, ng_track_list.RepeatTrackSize(i, 0), - kForNonGridElements); - continue; - } - - // If a subgridded axis was specified, but the element is not part of a - // parent grid, only integer repeats are supported. - if (computed_grid_track_list.IsSubgriddedAxis() && - repeat_type != NGGridTrackRepeater::RepeatType::kInteger) { - continue; - } - DCHECK_EQ(repeat_type, NGGridTrackRepeater::RepeatType::kInteger); - - // Add a CSSGridIntegerRepeatValue with the contents of the repeat(). - const wtf_size_t number_of_repetitions = ng_track_list.RepeatCount(i, 0); - const wtf_size_t repeat_size = ng_track_list.RepeatSize(i); - CSSValueList* repeated_values = - MakeGarbageCollected<cssvalue::CSSGridIntegerRepeatValue>( - number_of_repetitions); - AddValuesForNamedGridLinesAtIndex(collector, track_index, *list, - kForNonGridElements); - for (wtf_size_t j = 0; j < repeat_size; ++j) { - AppendValues(repeated_values, ng_track_list.RepeatTrackSize(i, j), - kForRepeatNonGridElements); - } - AddValuesForNamedGridLinesAtIndex( - collector, track_index, *repeated_values, kForRepeatNonGridElements); - list->Append(*repeated_values); - // We need to update |track_index| to skip over added grid named lines - // that belong to the repeat we just found. - track_index += repeat_size * (number_of_repetitions - 1); - } - AddValuesForNamedGridLinesAtIndex(collector, track_index, *list, - kForNonGridElements); - return list; - } - // Add the line names and track sizes that precede the auto repeat(). - PopulateGridTrackList(list, collector, legacy_track_sizes, GetTrackSize, - /* start */ 0, - /* end */ auto_repeat_insertion_point, /* offset */ 0); - - // Add a CSSGridAutoRepeatValue with the contents of the auto repeat(). - CSSValueList* repeated_values = - MakeGarbageCollected<cssvalue::CSSGridAutoRepeatValue>( - computed_grid_track_list.auto_repeat_type == AutoRepeatType::kAutoFill - ? CSSValueID::kAutoFill - : CSSValueID::kAutoFit); - OrderedNamedLinesCollectorInsideAutoRepeat repeat_collector( - computed_grid_track_list.ordered_named_grid_lines, - computed_grid_track_list.auto_repeat_ordered_named_grid_lines); - PopulateGridTrackList(repeated_values, repeat_collector, - auto_repeat_track_sizes, GetTrackSize, /* start */ 0, - /* end */ auto_repeat_track_sizes.size(), - /* offset */ 0); - list->Append(*repeated_values); - - // Add the line names and track sizes that follow the auto repeat(). - PopulateGridTrackList(list, collector, legacy_track_sizes, GetTrackSize, - /* start */ auto_repeat_insertion_point, - /* end */ legacy_track_sizes.size(), /* offset */ 1); + computed_grid_track_list.auto_repeat_ordered_named_grid_lines, is_subgrid, + is_layout_grid); + PopulateGridTrackListForNonGrid(list, collector, ng_track_list, style); return list; }
diff --git a/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc b/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc index e6d7268b..f3180e5 100644 --- a/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc +++ b/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc
@@ -1286,10 +1286,12 @@ computed_grid_track_list.auto_repeat_track_sizes; wtf_size_t current_named_grid_line = 0; - auto ConvertLineNameOrTrackSize = [&](const CSSValue& curr_value, - bool is_in_repeat = false, - bool is_first_repeat = false) { + auto ConvertLineNameOrTrackSize = + [&](const CSSValue& curr_value, bool is_in_repeat = false, + bool is_first_repeat = false) -> wtf_size_t { + wtf_size_t line_name_indices_count = 0; if (curr_value.IsGridLineNamesValue()) { + ++line_name_indices_count; ConvertGridLineNamesList( curr_value, current_named_grid_line, computed_grid_track_list.named_grid_lines, @@ -1306,10 +1308,12 @@ track_sizes.LegacyTrackList().push_back( ConvertGridTrackSize(state, curr_value)); } + return line_name_indices_count; }; const auto& values = To<CSSValueList>(value); auto* curr_value = values.begin(); + bool is_subgrid = false; if (RuntimeEnabledFeatures::LayoutNGSubgridEnabled()) { auto* identifier_value = DynamicTo<CSSIdentifierValue>(curr_value->Get()); @@ -1317,6 +1321,7 @@ identifier_value->GetValueID() == CSSValueID::kSubgrid) { computed_grid_track_list.axis_type = GridAxisType::kSubgriddedAxis; track_list.SetAxisType(GridAxisType::kSubgriddedAxis); + is_subgrid = true; ++curr_value; } } @@ -1326,6 +1331,7 @@ DynamicTo<cssvalue::CSSGridAutoRepeatValue>(curr_value->Get())) { Vector<GridTrackSize, 1> repeated_track_sizes; wtf_size_t auto_repeat_index = 0; + wtf_size_t line_name_indices_count = 0; CSSValueID auto_repeat_id = grid_auto_repeat_value->AutoRepeatID(); DCHECK(auto_repeat_id == CSSValueID::kAutoFill || auto_repeat_id == CSSValueID::kAutoFit); @@ -1334,6 +1340,7 @@ : AutoRepeatType::kAutoFit; for (const CSSValue* auto_repeat_value : To<CSSValueList>(**curr_value)) { if (auto_repeat_value->IsGridLineNamesValue()) { + ++line_name_indices_count; ConvertGridLineNamesList( *auto_repeat_value, auto_repeat_index, computed_grid_track_list.auto_repeat_named_grid_lines, @@ -1351,7 +1358,8 @@ static_cast<NGGridTrackRepeater::RepeatType>( computed_grid_track_list.auto_repeat_type), /* repeat_count */ 1, - /* repeat_number_of_lines */ auto_repeat_index); + /* repeat_number_of_lines */ auto_repeat_index, + line_name_indices_count); DCHECK(auto_repeat_track_sizes.empty()); auto_repeat_track_sizes = std::move(repeated_track_sizes); computed_grid_track_list.auto_repeat_insertion_point = @@ -1362,33 +1370,49 @@ if (auto* grid_integer_repeat_value = DynamicTo<cssvalue::CSSGridIntegerRepeatValue>(curr_value->Get())) { const wtf_size_t repetitions = grid_integer_repeat_value->Repetitions(); + wtf_size_t line_name_indices_count = 0; for (wtf_size_t i = 0; i < repetitions; ++i) { + const bool is_first_repeat = i == 0; for (auto integer_repeat_value : *grid_integer_repeat_value) { - ConvertLineNameOrTrackSize(*integer_repeat_value, - /* is_inside_repeat */ true, - /* is_first_repeat */ i == 0); + wtf_size_t current_line_name_indices_count = + ConvertLineNameOrTrackSize(*integer_repeat_value, + /* is_inside_repeat */ true, + is_first_repeat); + // Only add to `line_name_indices_count` on the first iteration so it + // doesn't need to be divided by `repetitions`. + if (is_first_repeat) { + line_name_indices_count += current_line_name_indices_count; + } } } + Vector<GridTrackSize, 1> repeater_track_sizes; if (computed_grid_track_list.axis_type == GridAxisType::kStandaloneAxis) { - Vector<GridTrackSize, 1> repeater_track_sizes; for (auto integer_repeat_value : *grid_integer_repeat_value) { if (!integer_repeat_value->IsGridLineNamesValue()) { repeater_track_sizes.push_back( ConvertGridTrackSize(state, *integer_repeat_value)); } } - track_list.AddRepeater(repeater_track_sizes, - NGGridTrackRepeater::RepeatType::kInteger, - repetitions); } + track_list.AddRepeater(repeater_track_sizes, + NGGridTrackRepeater::RepeatType::kInteger, + repetitions, /* repeat_number_of_lines */ 1u, + line_name_indices_count); continue; } - ConvertLineNameOrTrackSize(**curr_value); + wtf_size_t line_name_indices_count = + ConvertLineNameOrTrackSize(**curr_value); if (!curr_value->Get()->IsGridLineNamesValue()) { track_list.AddRepeater({ConvertGridTrackSize(state, **curr_value)}); + } else if (is_subgrid) { + track_list.AddRepeater(/* repeater_track_sizes */ {}, + NGGridTrackRepeater::RepeatType::kNoRepeat, + /* repeat_count */ 1, + /* repeat_number_of_lines */ 1u, + line_name_indices_count); } } @@ -2569,7 +2593,7 @@ bool is_animation_tainted) { // TODO(andruud): Produce tokens directly from CSSValue. return CSSVariableData::Create(value.CssText(), is_animation_tainted, - /*needs_variable_resolution=*/false); + /* needs_variable_resolution */ false); } namespace {
diff --git a/third_party/blink/renderer/core/css/resolver/style_builder_converter.h b/third_party/blink/renderer/core/css/resolver/style_builder_converter.h index 4c0a2a6..02000cc8f0 100644 --- a/third_party/blink/renderer/core/css/resolver/style_builder_converter.h +++ b/third_party/blink/renderer/core/css/resolver/style_builder_converter.h
@@ -45,7 +45,6 @@ #include "third_party/blink/renderer/core/style/basic_shapes.h" #include "third_party/blink/renderer/core/style/computed_style.h" #include "third_party/blink/renderer/core/style/grid_area.h" -#include "third_party/blink/renderer/core/style/grid_positions_resolver.h" #include "third_party/blink/renderer/core/style/named_grid_lines_map.h" #include "third_party/blink/renderer/core/style/ordered_named_grid_lines.h" #include "third_party/blink/renderer/core/style/shadow_list.h"
diff --git a/third_party/blink/renderer/core/css/selector_checker.cc b/third_party/blink/renderer/core/css/selector_checker.cc index 2e8ec69..bbb0f734 100644 --- a/third_party/blink/renderer/core/css/selector_checker.cc +++ b/third_party/blink/renderer/core/css/selector_checker.cc
@@ -1691,6 +1691,9 @@ break; } case CSSSelector::kPseudoOpen: + if (auto* selectmenu = DynamicTo<HTMLSelectMenuElement>(element)) { + return selectmenu->open(); + } if (auto* html_element = DynamicTo<HTMLElement>(element); html_element && html_element->HasPopoverAttribute()) { return html_element->popoverOpen(); @@ -1704,6 +1707,9 @@ // important to *match* when the feature is *disabled*. return true; } + if (auto* selectmenu = DynamicTo<HTMLSelectMenuElement>(element)) { + return !selectmenu->open(); + } if (auto* html_element = DynamicTo<HTMLElement>(element); html_element && html_element->HasPopoverAttribute()) { return html_element->GetPopoverData()->visibilityState() ==
diff --git a/third_party/blink/renderer/core/exported/build.gni b/third_party/blink/renderer/core/exported/build.gni index b152ebe8..b3653a9 100644 --- a/third_party/blink/renderer/core/exported/build.gni +++ b/third_party/blink/renderer/core/exported/build.gni
@@ -79,6 +79,7 @@ "web_document_test.cc", "web_drag_data_test.cc", "web_element_test.cc", + "web_form_control_element_test.cc", "web_frame_serializer_sanitization_test.cc", "web_frame_serializer_test.cc", "web_frame_serializer_test_helper.cc",
diff --git a/third_party/blink/renderer/core/exported/web_form_control_element.cc b/third_party/blink/renderer/core/exported/web_form_control_element.cc index fcfad52..b256f0b2 100644 --- a/third_party/blink/renderer/core/exported/web_form_control_element.cc +++ b/third_party/blink/renderer/core/exported/web_form_control_element.cc
@@ -30,9 +30,13 @@ #include "third_party/blink/public/web/web_form_control_element.h" +#include "base/time/time.h" +#include "third_party/blink/public/common/input/web_input_event.h" +#include "third_party/blink/public/common/input/web_keyboard_event.h" #include "third_party/blink/public/mojom/input/focus_type.mojom-blink.h" #include "third_party/blink/renderer/core/dom/events/event.h" #include "third_party/blink/renderer/core/dom/node_computed_style.h" +#include "third_party/blink/renderer/core/events/keyboard_event.h" #include "third_party/blink/renderer/core/html/forms/html_form_control_element.h" #include "third_party/blink/renderer/core/html/forms/html_form_element.h" #include "third_party/blink/renderer/core/html/forms/html_input_element.h" @@ -40,6 +44,8 @@ #include "third_party/blink/renderer/core/html/forms/html_select_menu_element.h" #include "third_party/blink/renderer/core/html/forms/html_text_area_element.h" #include "third_party/blink/renderer/core/input_type_names.h" +#include "third_party/blink/renderer/platform/keyboard_codes.h" +#include "ui/events/keycodes/dom/dom_key.h" #include "base/memory/scoped_refptr.h" @@ -184,12 +190,33 @@ if (IsA<HTMLInputElement>(*private_) || IsA<HTMLTextAreaElement>(*private_)) { if (!Focused()) DispatchFocusEvent(); - Unwrap<Element>()->DispatchScopedEvent( - *Event::CreateBubble(event_type_names::kKeydown)); + + auto send_event = [local_dom_window = + Unwrap<Element>()->GetDocument().domWindow(), + this](WebInputEvent::Type event_type) { + WebKeyboardEvent web_event{event_type, WebInputEvent::kNoModifiers, + base::TimeTicks::Now()}; + web_event.dom_key = ui::DomKey::UNIDENTIFIED; + web_event.dom_code = static_cast<int>(ui::DomKey::UNIDENTIFIED); + web_event.native_key_code = blink::VKEY_UNKNOWN; + web_event.windows_key_code = blink::VKEY_UNKNOWN; + web_event.text[0] = blink::VKEY_UNKNOWN; + web_event.unmodified_text[0] = blink::VKEY_UNKNOWN; + + KeyboardEvent* event = KeyboardEvent::Create(web_event, local_dom_window); + Unwrap<Element>()->DispatchScopedEvent(*event); + }; + + // Simulate key events in case the website checks via JS that a keyboard + // interaction took place. + send_event(WebInputEvent::Type::kRawKeyDown); + Unwrap<TextControlElement>()->SetAutofillValue( value, value.IsEmpty() ? WebAutofillState::kNotFilled : autofill_state); - Unwrap<Element>()->DispatchScopedEvent( - *Event::CreateBubble(event_type_names::kKeyup)); + + send_event(WebInputEvent::Type::kChar); + send_event(WebInputEvent::Type::kKeyUp); + if (!Focused()) DispatchBlurEvent(); } else if (auto* select = ::blink::DynamicTo<HTMLSelectElement>(*private_)) {
diff --git a/third_party/blink/renderer/core/exported/web_form_control_element_test.cc b/third_party/blink/renderer/core/exported/web_form_control_element_test.cc new file mode 100644 index 0000000..1b849be3 --- /dev/null +++ b/third_party/blink/renderer/core/exported/web_form_control_element_test.cc
@@ -0,0 +1,91 @@ +// 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 "third_party/blink/public/web/web_form_control_element.h" + +#include <vector> + +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/web/web_autofill_state.h" +#include "third_party/blink/public/web/web_document.h" +#include "third_party/blink/renderer/core/dom/document.h" +#include "third_party/blink/renderer/core/dom/element.h" +#include "third_party/blink/renderer/core/dom/events/native_event_listener.h" +#include "third_party/blink/renderer/core/event_type_names.h" +#include "third_party/blink/renderer/core/events/keyboard_event.h" +#include "third_party/blink/renderer/core/execution_context/execution_context.h" +#include "third_party/blink/renderer/core/html/forms/html_form_control_element.h" +#include "third_party/blink/renderer/core/testing/page_test_base.h" + +namespace blink { + +namespace { + +using ::testing::ElementsAre; +using ::testing::Values; + +// A fake event listener that logs keys and codes of observed keyboard events. +class FakeEventListener final : public NativeEventListener { + public: + void Invoke(ExecutionContext*, Event* event) override { + KeyboardEvent* keyboard_event = DynamicTo<KeyboardEvent>(event); + if (!event) { + return; + } + codes_.push_back(keyboard_event->code()); + keys_.push_back(keyboard_event->key()); + } + + const std::vector<String>& codes() const { return codes_; } + const std::vector<String>& keys() const { return keys_; } + + private: + std::vector<String> codes_; + std::vector<String> keys_; +}; + +} // namespace + +class WebFormControlElementTest + : public PageTestBase, + public testing::WithParamInterface<const char*> { + protected: + void InsertHTML() { + GetDocument().documentElement()->setInnerHTML(GetParam()); + } + + WebFormControlElement TestElement() { + HTMLFormControlElement* control_element = DynamicTo<HTMLFormControlElement>( + GetDocument().getElementById("testElement")); + DCHECK(control_element); + return WebFormControlElement(control_element); + } +}; + +TEST_P(WebFormControlElementTest, SetAutofillValue) { + InsertHTML(); + WebFormControlElement element = TestElement(); + auto* keypress_handler = MakeGarbageCollected<FakeEventListener>(); + element.Unwrap<HTMLFormControlElement>()->addEventListener( + event_type_names::kKeydown, keypress_handler); + + EXPECT_EQ(TestElement().Value(), "test value"); + EXPECT_EQ(element.GetAutofillState(), WebAutofillState::kNotFilled); + + // We expect to see one "fake" key press event with an unidentified key. + element.SetAutofillValue("new value", WebAutofillState::kAutofilled); + EXPECT_EQ(element.Value(), "new value"); + EXPECT_EQ(element.GetAutofillState(), WebAutofillState::kAutofilled); + EXPECT_THAT(keypress_handler->codes(), ElementsAre("")); + EXPECT_THAT(keypress_handler->keys(), ElementsAre("Unidentified")); +} + +INSTANTIATE_TEST_SUITE_P( + All, + WebFormControlElementTest, + Values("<input type='text' id=testElement value='test value'>", + "<textarea id=testElement>test value</textarea>")); + +} // namespace blink
diff --git a/third_party/blink/renderer/core/exported/web_view_impl.cc b/third_party/blink/renderer/core/exported/web_view_impl.cc index bb5b2ec..4f99cf1 100644 --- a/third_party/blink/renderer/core/exported/web_view_impl.cc +++ b/third_party/blink/renderer/core/exported/web_view_impl.cc
@@ -3835,7 +3835,6 @@ if (args.page_scale_delta != 1) { double_tap_zoom_pending_ = false; - visual_viewport.UserDidChangeScale(); } elastic_overscroll_ += args.elastic_overscroll_delta;
diff --git a/third_party/blink/renderer/core/frame/visual_viewport.cc b/third_party/blink/renderer/core/frame/visual_viewport.cc index 0ffd6827..f2199e8 100644 --- a/third_party/blink/renderer/core/frame/visual_viewport.cc +++ b/third_party/blink/renderer/core/frame/visual_viewport.cc
@@ -95,8 +95,6 @@ scale_(1), is_pinch_gesture_active_(false), browser_controls_adjustment_(0), - max_page_scale_(-1), - track_pinch_zoom_stats_for_page_(false), needs_paint_property_update_(true), overscroll_type_(ComputeOverscrollType()) { UniqueObjectId unique_id = NewUniqueObjectId(); @@ -370,9 +368,7 @@ return change; } -VisualViewport::~VisualViewport() { - SendUMAMetrics(); -} +VisualViewport::~VisualViewport() = default; void VisualViewport::Trace(Visitor* visitor) const { visitor->Trace(page_); @@ -1074,48 +1070,6 @@ RootFrameToViewport(gfx::PointF(point_in_root_frame))); } -void VisualViewport::StartTrackingPinchStats() { - DCHECK(IsActiveViewport()); - - Document* document = LocalMainFrame().GetDocument(); - if (!document) - return; - - if (!document->Url().ProtocolIsInHTTPFamily()) - return; - - track_pinch_zoom_stats_for_page_ = !ShouldDisableDesktopWorkarounds(); -} - -void VisualViewport::UserDidChangeScale() { - DCHECK(IsActiveViewport()); - if (!track_pinch_zoom_stats_for_page_) - return; - - max_page_scale_ = std::max(max_page_scale_, scale_); -} - -void VisualViewport::SendUMAMetrics() { - if (track_pinch_zoom_stats_for_page_) { - bool did_scale = max_page_scale_ > 0; - - base::UmaHistogramBoolean("Viewport.DidScalePage", did_scale); - - if (did_scale) { - int zoom_percentage = floor(max_page_scale_ * 100); - - // Note: while defined as an exact linear histogram with 21 buckets here, - // the UMA itself is tagged as an enumeration (PageScaleFactor) in - // histograms.xml to make it easy to identify the buckets... - int bucket = floor(zoom_percentage / 25.f); - base::UmaHistogramExactLinear("Viewport.MaxPageScale", bucket, 21); - } - } - - max_page_scale_ = -1; - track_pinch_zoom_stats_for_page_ = false; -} - bool VisualViewport::ShouldDisableDesktopWorkarounds() const { DCHECK(IsActiveViewport());
diff --git a/third_party/blink/renderer/core/frame/visual_viewport.h b/third_party/blink/renderer/core/frame/visual_viewport.h index 68d1f97..594ac88 100644 --- a/third_party/blink/renderer/core/frame/visual_viewport.h +++ b/third_party/blink/renderer/core/frame/visual_viewport.h
@@ -260,11 +260,6 @@ double VisibleWidthCSSPx() const; double VisibleHeightCSSPx() const; - // Used for gathering data on user pinch-zoom statistics. - void UserDidChangeScale(); - void SendUMAMetrics(); - void StartTrackingPinchStats(); - // Heuristic-based function for determining if we should disable workarounds // for viewing websites that are not optimized for mobile devices. bool ShouldDisableDesktopWorkarounds() const; @@ -388,11 +383,6 @@ // they expand or shrink the visible content height. float browser_controls_adjustment_; - // The maximum page scale the user has zoomed to on the current page. Used - // only to report statistics about pinch-zoom usage. - float max_page_scale_; - bool track_pinch_zoom_stats_for_page_; - // For page scale animation on page_scale_node_. CompositorElementId page_scale_element_id_; // For scrolling, on scroll_layer_, scroll_node_, and scroll element ids of
diff --git a/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc b/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc index d0fa44b..ae1e869 100644 --- a/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc +++ b/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc
@@ -2680,10 +2680,6 @@ if (IsProvisional()) return WebInputEventResult::kHandledSuppressed; - // Only record metrics for the root frame. - if (ForTopMostMainFrame()) - GetPage()->GetVisualViewport().StartTrackingPinchStats(); - // If a drag-and-drop operation is in progress, ignore input events except // PointerCancel and GestureLongPress. if (doing_drag_and_drop_ &&
diff --git a/third_party/blink/renderer/core/html/forms/html_field_set_element.cc b/third_party/blink/renderer/core/html/forms/html_field_set_element.cc index df3d428..0805152 100644 --- a/third_party/blink/renderer/core/html/forms/html_field_set_element.cc +++ b/third_party/blink/renderer/core/html/forms/html_field_set_element.cc
@@ -168,4 +168,14 @@ return EnsureCachedCollection<HTMLCollection>(kFormControls); } +bool HTMLFieldSetElement::IsDisabledFormControl() const { + if (RuntimeEnabledFeatures::SendMouseEventsDisabledFormControlsEnabled()) { + // The fieldset element itself should never be considered disabled, it is + // only supposed to affect its descendants: + // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#concept-fe-disabled + return false; + } + return HTMLFormControlElement::IsDisabledFormControl(); +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/html/forms/html_field_set_element.h b/third_party/blink/renderer/core/html/forms/html_field_set_element.h index f812ff38..b90df5b 100644 --- a/third_party/blink/renderer/core/html/forms/html_field_set_element.h +++ b/third_party/blink/renderer/core/html/forms/html_field_set_element.h
@@ -40,6 +40,8 @@ HTMLLegendElement* Legend() const; HTMLCollection* elements(); + bool IsDisabledFormControl() const override; + protected: void DisabledAttributeChanged() override;
diff --git a/third_party/blink/renderer/core/html/forms/html_select_element.cc b/third_party/blink/renderer/core/html/forms/html_select_element.cc index 3bfef2a..2693c43 100644 --- a/third_party/blink/renderer/core/html/forms/html_select_element.cc +++ b/third_party/blink/renderer/core/html/forms/html_select_element.cc
@@ -63,6 +63,7 @@ #include "third_party/blink/renderer/core/layout/layout_block_flow.h" #include "third_party/blink/renderer/core/layout/layout_object_factory.h" #include "third_party/blink/renderer/core/layout/layout_theme.h" +#include "third_party/blink/renderer/core/layout/ng/flex/layout_ng_flexible_box.h" #include "third_party/blink/renderer/core/page/chrome_client.h" #include "third_party/blink/renderer/core/page/page.h" #include "third_party/blink/renderer/core/page/spatial_navigation.h" @@ -398,8 +399,9 @@ LayoutObject* HTMLSelectElement::CreateLayoutObject( const ComputedStyle& style, LegacyLayout legacy_layout) { - if (UsesMenuList()) - return LayoutObjectFactory::CreateFlexibleBox(*this, style, legacy_layout); + if (UsesMenuList()) { + return MakeGarbageCollected<LayoutNGFlexibleBox>(this); + } return LayoutObjectFactory::CreateBlockFlow(*this, style, legacy_layout); }
diff --git a/third_party/blink/renderer/core/html/forms/html_select_menu_element.cc b/third_party/blink/renderer/core/html/forms/html_select_menu_element.cc index 2bd4dba..141729f5 100644 --- a/third_party/blink/renderer/core/html/forms/html_select_menu_element.cc +++ b/third_party/blink/renderer/core/html/forms/html_select_menu_element.cc
@@ -368,6 +368,8 @@ void HTMLSelectMenuElement::OpenListbox() { if (listbox_part_ && !open()) { listbox_part_->showPopover(ASSERT_NO_EXCEPTION); + PseudoStateChanged(CSSSelector::kPseudoClosed); + PseudoStateChanged(CSSSelector::kPseudoOpen); if (selectedOption()) { selectedOption()->Focus(); } @@ -383,6 +385,8 @@ HidePopoverFocusBehavior::kNone, HidePopoverTransitionBehavior::kFireEventsAndWaitForTransitions, /*exception_state=*/nullptr); + PseudoStateChanged(CSSSelector::kPseudoClosed); + PseudoStateChanged(CSSSelector::kPseudoOpen); } if (button_part_) { button_part_->Focus();
diff --git a/third_party/blink/renderer/core/html/forms/listed_element.cc b/third_party/blink/renderer/core/html/forms/listed_element.cc index 8bd6ae7..6a572898 100644 --- a/third_party/blink/renderer/core/html/forms/listed_element.cc +++ b/third_party/blink/renderer/core/html/forms/listed_element.cc
@@ -119,7 +119,7 @@ void ListedElement::InsertedInto(ContainerNode& insertion_point) { ancestor_disabled_state_ = AncestorDisabledState::kUnknown; // Force traversal to find ancestor - may_have_field_set_ancestor_ = true; + may_have_fieldset_ancestor_ = true; data_list_ancestor_state_ = DataListAncestorState::kUnknown; UpdateWillValidateCache(); @@ -275,7 +275,7 @@ void ListedElement::FieldSetAncestorsSetNeedsValidityCheck(Node* node) { if (!node) return; - if (!may_have_field_set_ancestor_) + if (!may_have_fieldset_ancestor_) return; for (auto* field_set = Traversal<HTMLFieldSetElement>::FirstAncestorOrSelf(*node); @@ -593,11 +593,11 @@ } void ListedElement::UpdateAncestorDisabledState() const { - if (!may_have_field_set_ancestor_) { + if (!may_have_fieldset_ancestor_) { ancestor_disabled_state_ = AncestorDisabledState::kEnabled; return; } - may_have_field_set_ancestor_ = false; + may_have_fieldset_ancestor_ = false; // <fieldset> element of which |disabled| attribute affects the // target element. HTMLFieldSetElement* disabled_fieldset_ancestor = nullptr; @@ -608,15 +608,17 @@ last_legend_ancestor = ancestor; continue; } - if (!IsA<HTMLFieldSetElement>(*ancestor)) - continue; - may_have_field_set_ancestor_ = true; - if (ancestor->IsDisabledFormControl()) { - auto* fieldset = To<HTMLFieldSetElement>(ancestor); - if (last_legend_ancestor && last_legend_ancestor == fieldset->Legend()) - continue; - disabled_fieldset_ancestor = fieldset; - break; + if (HTMLFieldSetElement* fieldset_ancestor = + DynamicTo<HTMLFieldSetElement>(ancestor)) { + may_have_fieldset_ancestor_ = true; + if (fieldset_ancestor->is_element_disabled_) { + if (last_legend_ancestor && + last_legend_ancestor == fieldset_ancestor->Legend()) { + continue; + } + disabled_fieldset_ancestor = fieldset_ancestor; + break; + } } } ancestor_disabled_state_ = disabled_fieldset_ancestor
diff --git a/third_party/blink/renderer/core/html/forms/listed_element.h b/third_party/blink/renderer/core/html/forms/listed_element.h index ca6236d..98e9bba 100644 --- a/third_party/blink/renderer/core/html/forms/listed_element.h +++ b/third_party/blink/renderer/core/html/forms/listed_element.h
@@ -198,9 +198,9 @@ void SetCustomValidationMessage(const String& message); // False; There are no FIELDSET ancestors. - // True; There might be a FIELDSET ancestor, and thre might be no + // True; There might be a FIELDSET ancestor, and there might be no // FIELDSET ancestors. - mutable bool may_have_field_set_ancestor_ = true; + mutable bool may_have_fieldset_ancestor_ = true; private: void UpdateAncestorDisabledState() const;
diff --git a/third_party/blink/renderer/core/html/forms/range_input_type.cc b/third_party/blink/renderer/core/html/forms/range_input_type.cc index 8527ad3..6e31fa29b 100644 --- a/third_party/blink/renderer/core/html/forms/range_input_type.cc +++ b/third_party/blink/renderer/core/html/forms/range_input_type.cc
@@ -56,7 +56,7 @@ #include "third_party/blink/renderer/core/html_names.h" #include "third_party/blink/renderer/core/input_type_names.h" #include "third_party/blink/renderer/core/layout/layout_block.h" -#include "third_party/blink/renderer/core/layout/layout_object_factory.h" +#include "third_party/blink/renderer/core/layout/ng/flex/layout_ng_flexible_box.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/heap/garbage_collected.h" #include "third_party/blink/renderer/platform/instrumentation/use_counter.h" @@ -255,9 +255,8 @@ LayoutObject* RangeInputType::CreateLayoutObject(const ComputedStyle& style, LegacyLayout legacy) const { - // TODO(crbug.com/1131352): input[type=range] should not use - // LayoutFlexibleBox. - return LayoutObjectFactory::CreateFlexibleBox(GetElement(), style, legacy); + // TODO(crbug.com/1131352): input[type=range] should not use flexbox. + return MakeGarbageCollected<LayoutNGFlexibleBox>(&GetElement()); } Decimal RangeInputType::ParseToNumber(const String& src,
diff --git a/third_party/blink/renderer/core/html/forms/slider_thumb_element.cc b/third_party/blink/renderer/core/html/forms/slider_thumb_element.cc index 265ed91..0f6eb4b3 100644 --- a/third_party/blink/renderer/core/html/forms/slider_thumb_element.cc +++ b/third_party/blink/renderer/core/html/forms/slider_thumb_element.cc
@@ -46,6 +46,7 @@ #include "third_party/blink/renderer/core/layout/layout_block_flow.h" #include "third_party/blink/renderer/core/layout/layout_object_factory.h" #include "third_party/blink/renderer/core/layout/layout_theme.h" +#include "third_party/blink/renderer/core/layout/ng/flex/layout_ng_flexible_box.h" #include "ui/base/ui_base_features.h" namespace blink { @@ -317,7 +318,7 @@ LayoutObject* SliderContainerElement::CreateLayoutObject( const ComputedStyle& style, LegacyLayout legacy) { - return LayoutObjectFactory::CreateFlexibleBox(*this, style, legacy); + return MakeGarbageCollected<LayoutNGFlexibleBox>(this); } void SliderContainerElement::DefaultEventHandler(Event& event) {
diff --git a/third_party/blink/renderer/core/html/html_iframe_element.cc b/third_party/blink/renderer/core/html/html_iframe_element.cc index d04cf7f..320ebd8d 100644 --- a/third_party/blink/renderer/core/html/html_iframe_element.cc +++ b/third_party/blink/renderer/core/html/html_iframe_element.cc
@@ -285,7 +285,8 @@ UseCounter::Count(GetDocument(), WebFeature::kIFrameCSPAttribute); } } else if (name == html_names::kBrowsingtopicsAttr) { - if (RuntimeEnabledFeatures::TopicsAPIEnabled(GetExecutionContext())) { + if (RuntimeEnabledFeatures::TopicsAPIEnabled(GetExecutionContext()) && + GetExecutionContext()->IsSecureContext()) { bool old_browsing_topics = !params.old_value.IsNull(); bool new_browsing_topics = !params.new_value.IsNull(); @@ -585,8 +586,12 @@ auto attributes = mojom::blink::IframeAttributes::New(); attributes->parsed_csp_attribute = csp.empty() ? nullptr : std::move(csp[0]); attributes->credentialless = credentialless_; - attributes->browsing_topics = - !FastGetAttribute(html_names::kBrowsingtopicsAttr).IsNull(); + + if (RuntimeEnabledFeatures::TopicsAPIEnabled(GetExecutionContext()) && + GetExecutionContext()->IsSecureContext()) { + attributes->browsing_topics = + !FastGetAttribute(html_names::kBrowsingtopicsAttr).IsNull(); + } attributes->id = ConvertToReportValue(id_); attributes->name = ConvertToReportValue(name_);
diff --git a/third_party/blink/renderer/core/inspector/inspector_highlight.cc b/third_party/blink/renderer/core/inspector/inspector_highlight.cc index 1a69edfb..a8e50a6 100644 --- a/third_party/blink/renderer/core/inspector/inspector_highlight.cc +++ b/third_party/blink/renderer/core/inspector/inspector_highlight.cc
@@ -28,7 +28,6 @@ #include "third_party/blink/renderer/core/layout/adjust_for_absolute_zoom.h" #include "third_party/blink/renderer/core/layout/geometry/physical_offset.h" #include "third_party/blink/renderer/core/layout/layout_box.h" -#include "third_party/blink/renderer/core/layout/layout_flexible_box.h" #include "third_party/blink/renderer/core/layout/layout_inline.h" #include "third_party/blink/renderer/core/layout/layout_object.h" #include "third_party/blink/renderer/core/layout/layout_view.h" @@ -39,7 +38,6 @@ #include "third_party/blink/renderer/core/page/chrome_client.h" #include "third_party/blink/renderer/core/page/page.h" #include "third_party/blink/renderer/core/style/computed_style_constants.h" -#include "third_party/blink/renderer/core/style/grid_positions_resolver.h" #include "third_party/blink/renderer/platform/geometry/layout_unit.h" #include "third_party/blink/renderer/platform/graphics/path.h" #include "third_party/blink/renderer/platform/text/writing_mode.h"
diff --git a/third_party/blink/renderer/core/layout/build.gni b/third_party/blink/renderer/core/layout/build.gni index 0d82c1bd..127763c 100644 --- a/third_party/blink/renderer/core/layout/build.gni +++ b/third_party/blink/renderer/core/layout/build.gni
@@ -128,8 +128,6 @@ "layout_embedded_object.h", "layout_fieldset.cc", "layout_fieldset.h", - "layout_flexible_box.cc", - "layout_flexible_box.h", "layout_flow_thread.cc", "layout_flow_thread.h", "layout_frame.cc",
diff --git a/third_party/blink/renderer/core/layout/flexible_box_algorithm.cc b/third_party/blink/renderer/core/layout/flexible_box_algorithm.cc index 94dabe8..07972fa 100644 --- a/third_party/blink/renderer/core/layout/flexible_box_algorithm.cc +++ b/third_party/blink/renderer/core/layout/flexible_box_algorithm.cc
@@ -32,7 +32,6 @@ #include "third_party/blink/renderer/core/frame/web_feature.h" #include "third_party/blink/renderer/core/layout/layout_box.h" -#include "third_party/blink/renderer/core/layout/layout_flexible_box.h" #include "third_party/blink/renderer/core/layout/min_max_sizes.h" #include "third_party/blink/renderer/core/layout/ng/flex/ng_flex_line.h" #include "third_party/blink/renderer/core/layout/ng/ng_box_fragment.h" @@ -77,7 +76,6 @@ } // namespace FlexItem::FlexItem(const FlexLayoutAlgorithm* algorithm, - LayoutBox* box, const ComputedStyle& style, LayoutUnit flex_base_content_size, MinMaxSizes min_max_main_sizes, @@ -91,7 +89,6 @@ bool depends_on_min_max_sizes) : algorithm_(algorithm), line_number_(0), - box_(box), style_(style), flex_base_content_size_(flex_base_content_size), min_max_main_sizes_(min_max_main_sizes), @@ -182,13 +179,6 @@ LayoutUnit FlexItem::MarginBoxAscent(bool is_last_baseline, bool is_wrap_reverse) const { - if (box_) { - LayoutUnit ascent(box_->FirstLineBoxBaseline()); - if (ascent == -1) - ascent = cross_axis_size_; - return ascent + FlowAwareMarginBefore(); - } - DCHECK(layout_result_); NGBoxFragment baseline_fragment( baseline_writing_direction_, @@ -294,17 +284,6 @@ LayoutUnit stretched_size = std::max(cross_axis_border_padding_, Line()->cross_axis_extent_ - CrossAxisMarginExtent()); - if (box_) { - if (MainAxisIsInlineAxis() && style_.LogicalHeight().IsAuto()) { - cross_axis_size_ = box_->ConstrainLogicalHeightByMinMax( - stretched_size, box_->IntrinsicContentLogicalHeight()); - } else if (!MainAxisIsInlineAxis() && style_.LogicalWidth().IsAuto()) { - const auto* flexbox = To<LayoutFlexibleBox>(box_->Parent()); - cross_axis_size_ = box_->ConstrainLogicalWidthByMinMax( - stretched_size, flexbox->CrossAxisContentExtent(), flexbox); - } - return; - } if ((MainAxisIsInlineAxis() && style_.LogicalHeight().IsAuto()) || (!MainAxisIsInlineAxis() && style_.LogicalWidth().IsAuto())) { @@ -314,7 +293,6 @@ } void FlexItem::Trace(Visitor* visitor) const { - visitor->Trace(box_); visitor->Trace(ng_input_node_); visitor->Trace(layout_result_); }
diff --git a/third_party/blink/renderer/core/layout/flexible_box_algorithm.h b/third_party/blink/renderer/core/layout/flexible_box_algorithm.h index 3469508..50434562 100644 --- a/third_party/blink/renderer/core/layout/flexible_box_algorithm.h +++ b/third_party/blink/renderer/core/layout/flexible_box_algorithm.h
@@ -50,7 +50,6 @@ class FlexLine; class FlexLayoutAlgorithm; class NGFlexLayoutAlgorithm; -class LayoutBox; struct MinMaxSizes; struct NGFlexLine; @@ -68,52 +67,6 @@ typedef HeapVector<FlexItem, 8> FlexItemVector; -class AutoClearOverrideLogicalHeight { - STACK_ALLOCATED(); - - public: - explicit AutoClearOverrideLogicalHeight(LayoutBox* box) - : box_(box), old_override_height_(-1) { - if (box_ && box_->HasOverrideLogicalHeight()) { - old_override_height_ = box_->OverrideLogicalHeight(); - box_->ClearOverrideLogicalHeight(); - } - } - ~AutoClearOverrideLogicalHeight() { - if (old_override_height_ != LayoutUnit(-1)) { - DCHECK(box_); - box_->SetOverrideLogicalHeight(old_override_height_); - } - } - - private: - LayoutBox* box_; - LayoutUnit old_override_height_; -}; - -class AutoClearOverrideLogicalWidth { - STACK_ALLOCATED(); - - public: - explicit AutoClearOverrideLogicalWidth(LayoutBox* box) - : box_(box), old_override_width_(-1) { - if (box_ && box_->HasOverrideLogicalWidth()) { - old_override_width_ = box_->OverrideLogicalWidth(); - box_->ClearOverrideLogicalWidth(); - } - } - ~AutoClearOverrideLogicalWidth() { - if (old_override_width_ != LayoutUnit(-1)) { - DCHECK(box_); - box_->SetOverrideLogicalWidth(old_override_width_); - } - } - - private: - LayoutBox* box_; - LayoutUnit old_override_width_; -}; - class FlexItem { DISALLOW_NEW(); @@ -125,7 +78,6 @@ // border/padding. // |min_max_cross_sizes| does include cross_axis_border_padding. FlexItem(const FlexLayoutAlgorithm*, - LayoutBox*, const ComputedStyle& style, LayoutUnit flex_base_content_size, MinMaxSizes min_max_main_sizes, @@ -200,7 +152,6 @@ const FlexLayoutAlgorithm* algorithm_; wtf_size_t line_number_; - Member<LayoutBox> box_; const ComputedStyle& style_; const LayoutUnit flex_base_content_size_; const MinMaxSizes min_max_main_sizes_;
diff --git a/third_party/blink/renderer/core/layout/layout_block.cc b/third_party/blink/renderer/core/layout/layout_block.cc index bcf583d..70c2d01 100644 --- a/third_party/blink/renderer/core/layout/layout_block.cc +++ b/third_party/blink/renderer/core/layout/layout_block.cc
@@ -49,7 +49,6 @@ #include "third_party/blink/renderer/core/layout/box_layout_extra_input.h" #include "third_party/blink/renderer/core/layout/hit_test_location.h" #include "third_party/blink/renderer/core/layout/hit_test_result.h" -#include "third_party/blink/renderer/core/layout/layout_flexible_box.h" #include "third_party/blink/renderer/core/layout/layout_flow_thread.h" #include "third_party/blink/renderer/core/layout/layout_inline.h" #include "third_party/blink/renderer/core/layout/layout_multi_column_flow_thread.h" @@ -60,6 +59,7 @@ #include "third_party/blink/renderer/core/layout/layout_theme.h" #include "third_party/blink/renderer/core/layout/layout_view.h" #include "third_party/blink/renderer/core/layout/line/inline_text_box.h" +#include "third_party/blink/renderer/core/layout/ng/flex/layout_ng_flexible_box.h" #include "third_party/blink/renderer/core/layout/ng/legacy_layout_tree_walking.h" #include "third_party/blink/renderer/core/layout/ng/ng_constraint_space.h" #include "third_party/blink/renderer/core/layout/ng/ng_length_utils.h" @@ -962,30 +962,6 @@ if (positioned_object->NeedsLayout()) positioned_object->UpdateLayout(); - LayoutObject* parent = positioned_object->Parent(); - bool layout_changed = false; - if ((parent->IsLayoutNGFlexibleBox() && - !positioned_object->IsLayoutNGObject() && - LayoutFlexibleBox::SetStaticPositionForChildInFlexNGContainer( - *positioned_object, To<LayoutBlock>(parent))) || - (parent->IsFlexibleBox() && - To<LayoutFlexibleBox>(parent)->SetStaticPositionForPositionedLayout( - *positioned_object))) { - // The static position of an abspos child of a flexbox depends on its size - // (for example, they can be centered). So we may have to reposition the - // item after layout. - // TODO(cbiesinger): We could probably avoid a layout here and just - // reposition? - positioned_object->ForceLayout(); - layout_changed = true; - } - - // Lay out again if our estimate was wrong. - if (!layout_changed && needs_block_direction_location_set_before_layout && - logical_top_estimate != LogicalTopForChild(*positioned_object)) { - positioned_object->ForceLayout(); - } - if (is_paginated) UpdateFragmentationInfoForChild(*positioned_object); } @@ -1600,9 +1576,7 @@ // values for width. const ComputedStyle& style_to_use = StyleRef(); if (!IsTableCell() && style_to_use.LogicalWidth().IsFixed() && - style_to_use.LogicalWidth().Value() >= 0 && - !(IsFlexItemCommon() && Parent()->StyleRef().IsDeprecatedWebkitBox() && - !style_to_use.LogicalWidth().IntValue())) { + style_to_use.LogicalWidth().Value() >= 0) { sizes = AdjustBorderBoxLogicalWidthForBoxSizing( LayoutUnit(style_to_use.LogicalWidth().Value())); } else { @@ -2268,8 +2242,8 @@ LayoutBlock* layout_block; if (new_display == EDisplay::kFlex) { - layout_block = LayoutObjectFactory::CreateFlexibleBox(parent->GetDocument(), - *new_style, legacy); + layout_block = + MakeGarbageCollected<LayoutNGFlexibleBox>(/* element */ nullptr); } else if (new_display == EDisplay::kGrid) { layout_block = MakeGarbageCollected<LayoutNGGrid>(/* element */ nullptr); } else if (new_display == EDisplay::kBlockMath) { @@ -2475,11 +2449,7 @@ (!style.LogicalTop().IsAuto() && !style.LogicalBottom().IsAuto())); LayoutUnit stretched_flex_height(-1); - if (IsFlexItem()) { - const auto* flex_box = To<LayoutFlexibleBox>(Parent()); - if (flex_box->UseOverrideLogicalHeightForPerentageResolution(*this)) - stretched_flex_height = OverrideContentLogicalHeight(); - } else if (HasOverrideLogicalHeight() && IsOverrideLogicalHeightDefinite()) { + if (HasOverrideLogicalHeight() && IsOverrideLogicalHeightDefinite()) { stretched_flex_height = OverrideContentLogicalHeight(); } if (stretched_flex_height != LayoutUnit(-1)) {
diff --git a/third_party/blink/renderer/core/layout/layout_box.cc b/third_party/blink/renderer/core/layout/layout_box.cc index bf20e95..bc3776d 100644 --- a/third_party/blink/renderer/core/layout/layout_box.cc +++ b/third_party/blink/renderer/core/layout/layout_box.cc
@@ -66,7 +66,6 @@ #include "third_party/blink/renderer/core/layout/hit_test_result.h" #include "third_party/blink/renderer/core/layout/layout_embedded_content.h" #include "third_party/blink/renderer/core/layout/layout_fieldset.h" -#include "third_party/blink/renderer/core/layout/layout_flexible_box.h" #include "third_party/blink/renderer/core/layout/layout_inline.h" #include "third_party/blink/renderer/core/layout/layout_list_marker.h" #include "third_party/blink/renderer/core/layout/layout_multi_column_flow_thread.h" @@ -2639,6 +2638,7 @@ // rules if they can improve LCD text. bool LayoutBox::TextIsKnownToBeOnOpaqueBackground() const { NOT_DESTROYED(); + DCHECK(!RuntimeEnabledFeatures::CompositeScrollAfterPaintEnabled()); // Text may overflow the background area. if (!ShouldClipOverflowAlongEitherAxis()) return false; @@ -4407,18 +4407,6 @@ return true; } - // Flexible horizontal boxes lay out children at their intrinsic widths. Also - // vertical boxes that don't stretch their kids lay out their children at - // their intrinsic widths. - // FIXME: Think about writing-mode here. - // https://bugs.webkit.org/show_bug.cgi?id=46473 - if ((Parent()->StyleRef().IsDeprecatedWebkitBox() && - Parent()->IsFlexibleBox()) && - (Parent()->StyleRef().BoxOrient() == EBoxOrient::kHorizontal || - Parent()->StyleRef().BoxAlign() != EBoxAlignment::kStretch)) { - return true; - } - // Button, input, select, textarea, and legend treat width value of 'auto' as // 'intrinsic' unless it's in a stretching column flexbox. // FIXME: Think about writing-mode here. @@ -5229,11 +5217,6 @@ auto* block = DynamicTo<LayoutBlock>(cb); if (block) { block->AddPercentHeightDescendant(const_cast<LayoutBox*>(this)); - if (block->IsFlexItem()) { - const auto* flex_box = To<LayoutFlexibleBox>(block->Parent()); - if (flex_box->UseOverrideLogicalHeightForPerentageResolution(*block)) - stretched_height = block->OverrideContentLogicalHeight(); - } } LayoutUnit available_height; @@ -5318,12 +5301,8 @@ } if (IsFlexItemIncludingNG()) { - if (IsFlexItem()) { - const auto& flex_box = To<LayoutFlexibleBox>(*Parent()); - if (flex_box.UseOverrideLogicalHeightForPerentageResolution(*this)) - return OverrideContentLogicalHeight(); - } else if (HasOverrideContainingBlockContentLogicalWidth() && - IsOrthogonalWritingModeRoot()) { + if (HasOverrideContainingBlockContentLogicalWidth() && + IsOrthogonalWritingModeRoot()) { return OverrideContainingBlockContentLogicalWidth(); } else if (HasOverrideLogicalHeight() && IsOverrideLogicalHeightDefinite()) {
diff --git a/third_party/blink/renderer/core/layout/layout_box.h b/third_party/blink/renderer/core/layout/layout_box.h index 3503a81..1faf10a 100644 --- a/third_party/blink/renderer/core/layout/layout_box.h +++ b/third_party/blink/renderer/core/layout/layout_box.h
@@ -1732,20 +1732,11 @@ bool IsCustomItem() const; bool IsCustomItemShrinkToFit() const; - // TODO(dgrogan): Replace the rest of the calls to IsFlexItem with - // IsFlexItemIncludingNG when all the callsites can handle an item with an NG - // parent. - bool IsFlexItem() const { - NOT_DESTROYED(); - return IsFlexItemCommon() && Parent()->IsFlexibleBox(); - } + // TODO(1229581): Rename this function. bool IsFlexItemIncludingNG() const { NOT_DESTROYED(); - return IsFlexItemCommon() && Parent()->IsFlexibleBoxIncludingNG(); - } - bool IsFlexItemCommon() const { - NOT_DESTROYED(); - return !IsInline() && !IsOutOfFlowPositioned() && Parent(); + return !IsInline() && !IsOutOfFlowPositioned() && Parent() && + Parent()->IsFlexibleBoxIncludingNG(); } // TODO(1229581): Rename this function.
diff --git a/third_party/blink/renderer/core/layout/layout_box_model_object.cc b/third_party/blink/renderer/core/layout/layout_box_model_object.cc index 59acb303..ce1f50f0 100644 --- a/third_party/blink/renderer/core/layout/layout_box_model_object.cc +++ b/third_party/blink/renderer/core/layout/layout_box_model_object.cc
@@ -35,7 +35,6 @@ #include "third_party/blink/renderer/core/html/html_body_element.h" #include "third_party/blink/renderer/core/layout/geometry/transform_state.h" #include "third_party/blink/renderer/core/layout/layout_block.h" -#include "third_party/blink/renderer/core/layout/layout_flexible_box.h" #include "third_party/blink/renderer/core/layout/layout_inline.h" #include "third_party/blink/renderer/core/layout/layout_object_inlines.h" #include "third_party/blink/renderer/core/layout/layout_view.h" @@ -128,6 +127,8 @@ bool LayoutBoxModelObject::UsesCompositedScrolling() const { NOT_DESTROYED(); + // TODO(crbug.com/1414885): We may need to redefine this function for + // CompositeScrollAfterPaint. const auto* properties = FirstFragment().PaintProperties(); return properties && properties->ScrollTranslation() && properties->ScrollTranslation()->HasDirectCompositingReasons(); @@ -625,12 +626,8 @@ cb->AddPercentHeightDescendant(const_cast<LayoutBox*>(To<LayoutBox>(this))); } if (this_box && this_box->IsFlexItemIncludingNG()) { - if (this_box->IsFlexItem()) { - const auto& flex_box = To<LayoutFlexibleBox>(*Parent()); - if (flex_box.UseOverrideLogicalHeightForPerentageResolution(*this_box)) - return false; - } else if (const NGLayoutResult* result = - this_box->GetSingleCachedLayoutResult()) { + if (const NGLayoutResult* result = + this_box->GetSingleCachedLayoutResult()) { // TODO(dgrogan): We won't get here when laying out the FlexNG item and // its descendant(s) for the first time because the item (|this_box|) // doesn't have anything in its cache. That seems bad because this method
diff --git a/third_party/blink/renderer/core/layout/layout_box_model_object.h b/third_party/blink/renderer/core/layout/layout_box_model_object.h index 5ff6b21..15e9009 100644 --- a/third_party/blink/renderer/core/layout/layout_box_model_object.h +++ b/third_party/blink/renderer/core/layout/layout_box_model_object.h
@@ -533,6 +533,7 @@ // opaque background. virtual bool TextIsKnownToBeOnOpaqueBackground() const { NOT_DESTROYED(); + DCHECK(!RuntimeEnabledFeatures::CompositeScrollAfterPaintEnabled()); return false; }
diff --git a/third_party/blink/renderer/core/layout/layout_flexible_box.cc b/third_party/blink/renderer/core/layout/layout_flexible_box.cc deleted file mode 100644 index 0e2fed2..0000000 --- a/third_party/blink/renderer/core/layout/layout_flexible_box.cc +++ /dev/null
@@ -1,1885 +0,0 @@ -/* - * Copyright (C) 2011 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "third_party/blink/renderer/core/layout/layout_flexible_box.h" - -#include <limits> -#include "base/auto_reset.h" -#include "third_party/blink/renderer/core/frame/web_feature.h" -#include "third_party/blink/renderer/core/html/forms/html_input_element.h" -#include "third_party/blink/renderer/core/html/forms/html_select_element.h" -#include "third_party/blink/renderer/core/input_type_names.h" -#include "third_party/blink/renderer/core/layout/flexible_box_algorithm.h" -#include "third_party/blink/renderer/core/layout/layout_state.h" -#include "third_party/blink/renderer/core/layout/layout_video.h" -#include "third_party/blink/renderer/core/layout/layout_view.h" -#include "third_party/blink/renderer/core/layout/min_max_sizes.h" -#include "third_party/blink/renderer/core/layout/ng/layout_ng_mixin.h" -#include "third_party/blink/renderer/core/layout/ng/ng_constraint_space.h" -#include "third_party/blink/renderer/core/layout/ng/ng_length_utils.h" -#include "third_party/blink/renderer/core/layout/text_autosizer.h" -#include "third_party/blink/renderer/core/paint/block_painter.h" -#include "third_party/blink/renderer/core/paint/paint_layer.h" -#include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h" -#include "third_party/blink/renderer/core/style/computed_style.h" -#include "third_party/blink/renderer/platform/geometry/length_functions.h" -#include "third_party/blink/renderer/platform/instrumentation/use_counter.h" -#include "third_party/blink/renderer/platform/wtf/math_extras.h" - -namespace blink { - -static bool HasAspectRatio(const LayoutBox& child) { - return child.IsImage() || child.IsCanvas() || IsA<LayoutVideo>(child) || - !child.StyleRef().AspectRatio().IsAuto(); -} - -LayoutFlexibleBox::LayoutFlexibleBox(Element* element) - : LayoutBlock(element), - order_iterator_(this), - number_of_in_flow_children_on_first_line_(-1), - has_definite_height_(SizeDefiniteness::kUnknown), - in_layout_(false) { - DCHECK(!ChildrenInline()); -} - -LayoutFlexibleBox::~LayoutFlexibleBox() = default; - -void LayoutFlexibleBox::Trace(Visitor* visitor) const { - visitor->Trace(intrinsic_size_along_main_axis_); - visitor->Trace(relaid_out_children_); - visitor->Trace(order_iterator_); - LayoutBlock::Trace(visitor); -} - -bool LayoutFlexibleBox::IsChildAllowed(LayoutObject* object, - const ComputedStyle& style) const { - NOT_DESTROYED(); - const auto* select = DynamicTo<HTMLSelectElement>(GetNode()); - if (UNLIKELY(select && select->UsesMenuList())) { - // For a size=1 <select>, we only render the active option label through the - // InnerElement. We do not allow adding layout objects for options and - // optgroups. - return object->GetNode() == &select->InnerElement(); - } - return LayoutBlock::IsChildAllowed(object, style); -} - -MinMaxSizes LayoutFlexibleBox::ComputeIntrinsicLogicalWidths() const { - NOT_DESTROYED(); - MinMaxSizes sizes; - sizes += - BorderAndPaddingLogicalWidth() + ComputeLogicalScrollbars().InlineSum(); - - if (HasOverrideIntrinsicContentLogicalWidth()) { - sizes += OverrideIntrinsicContentLogicalWidth(); - return sizes; - } - LayoutUnit default_inline_size = DefaultIntrinsicContentInlineSize(); - if (default_inline_size != kIndefiniteSize) { - sizes.max_size += default_inline_size; - if (!StyleRef().LogicalWidth().IsPercentOrCalc()) - sizes.min_size = sizes.max_size; - return sizes; - } - if (ShouldApplySizeContainment()) - return sizes; - - MinMaxSizes child_sizes; - - // FIXME: We're ignoring flex-basis here and we shouldn't. We can't start - // honoring it though until the flex shorthand stops setting it to 0. See - // https://bugs.webkit.org/show_bug.cgi?id=116117 and - // https://crbug.com/240765. - float previous_max_content_flex_fraction = -1; - int number_of_items = 0; - for (LayoutBox* child = FirstChildBox(); child; - child = child->NextSiblingBox()) { - if (child->IsOutOfFlowPositioned()) - continue; - number_of_items++; - - LayoutUnit margin = MarginIntrinsicLogicalWidthForChild(*child); - - LayoutUnit min_preferred_logical_width; - LayoutUnit max_preferred_logical_width; - if (child->NeedsPreferredWidthsRecalculation()) - child->SetIntrinsicLogicalWidthsDirty(); - ComputeChildPreferredLogicalWidths(*child, min_preferred_logical_width, - max_preferred_logical_width); - DCHECK_GE(min_preferred_logical_width, LayoutUnit()); - DCHECK_GE(max_preferred_logical_width, LayoutUnit()); - min_preferred_logical_width += margin; - max_preferred_logical_width += margin; - if (!IsColumnFlow()) { - child_sizes.max_size += max_preferred_logical_width; - if (IsMultiline()) { - // For multiline, the min preferred width is if you put a break between - // each item. - child_sizes.min_size = - std::max(child_sizes.min_size, min_preferred_logical_width); - } else { - child_sizes.min_size += min_preferred_logical_width; - } - } else { - child_sizes.min_size = - std::max(min_preferred_logical_width, child_sizes.min_size); - child_sizes.max_size = - std::max(max_preferred_logical_width, child_sizes.max_size); - } - - previous_max_content_flex_fraction = CountIntrinsicSizeForAlgorithmChange( - max_preferred_logical_width, child, previous_max_content_flex_fraction); - } - - if (!IsColumnFlow() && number_of_items > 0) { - LayoutUnit gap_inline_size = - (number_of_items - 1) * - FlexLayoutAlgorithm::GapBetweenItems( - StyleRef(), - LogicalSize{ContentLogicalWidth(), - AvailableLogicalHeightForPercentageComputation()}); - child_sizes.max_size += gap_inline_size; - if (!IsMultiline()) { - child_sizes.min_size += gap_inline_size; - } - } - - child_sizes.max_size = std::max(child_sizes.min_size, child_sizes.max_size); - - // Due to negative margins, it is possible that we calculated a negative - // intrinsic width. Make sure that we never return a negative width. - child_sizes.min_size = std::max(LayoutUnit(), child_sizes.min_size); - child_sizes.max_size = std::max(LayoutUnit(), child_sizes.max_size); - - sizes += child_sizes; - return sizes; -} - -float LayoutFlexibleBox::CountIntrinsicSizeForAlgorithmChange( - LayoutUnit max_preferred_logical_width, - LayoutBox* child, - float previous_max_content_flex_fraction) const { - NOT_DESTROYED(); - // Determine whether the new version of the intrinsic size algorithm of the - // flexbox spec would produce a different result than our above algorithm. - // The algorithm produces a different result iff the max-content flex - // fraction (as defined in the new algorithm) is not identical for each flex - // item. - if (IsColumnFlow()) - return previous_max_content_flex_fraction; - const Length& flex_basis = child->StyleRef().FlexBasis(); - float flex_grow = child->StyleRef().FlexGrow(); - // A flex-basis of auto will lead to a max-content flex fraction of zero, so - // just like an inflexible item it would compute to a size of max-content, so - // we ignore it here. - if (flex_basis.IsAuto() || flex_grow == 0) - return previous_max_content_flex_fraction; - flex_grow = std::max(1.0f, flex_grow); - float max_content_flex_fraction = - max_preferred_logical_width.ToFloat() / flex_grow; - if (previous_max_content_flex_fraction != -1 && - max_content_flex_fraction != previous_max_content_flex_fraction) { - UseCounter::Count(GetDocument(), - WebFeature::kFlexboxIntrinsicSizeAlgorithmIsDifferent); - } - return max_content_flex_fraction; -} - -LayoutUnit LayoutFlexibleBox::SynthesizedBaselineFromBorderBox( - const LayoutBox& box, - LineDirectionMode direction) { - return direction == kHorizontalLine ? box.Size().Height() - : box.Size().Width(); -} - -LayoutUnit LayoutFlexibleBox::BaselinePosition(FontBaseline, - bool, - LineDirectionMode direction, - LinePositionMode mode) const { - NOT_DESTROYED(); - DCHECK_EQ(mode, kPositionOnContainingLine); - // TODO(crbug.com/1131352): input[type=range] should not use - // LayoutFlexibleBox. We should move out this code. - if (const auto* input = DynamicTo<HTMLInputElement>(GetNode())) { - if (input->type() == input_type_names::kRange) { - return SynthesizedBaselineFromBorderBox(*this, direction) + - MarginBefore(); - } - } - LayoutUnit baseline = FirstLineBoxBaseline(); - if (baseline == -1) { - return SynthesizedBaselineFromBorderBox(*this, direction) + - MarginLogicalHeight(); - } - - return BeforeMarginInLineDirection(direction) + baseline; -} - -LayoutUnit LayoutFlexibleBox::FirstLineBoxBaseline() const { - NOT_DESTROYED(); - if (IsWritingModeRoot() || number_of_in_flow_children_on_first_line_ <= 0 || - ShouldApplyLayoutContainment()) - return LayoutUnit(-1); - LayoutBox* baseline_child = nullptr; - int child_number = 0; - for (LayoutBox* child = order_iterator_.First(); child; - child = order_iterator_.Next()) { - if (child->IsOutOfFlowPositioned()) - continue; - if (FlexLayoutAlgorithm::AlignmentForChild(StyleRef(), child->StyleRef()) == - ItemPosition::kBaseline && - !HasAutoMarginsInCrossAxis(*child)) { - baseline_child = child; - break; - } - if (!baseline_child) - baseline_child = child; - - ++child_number; - if (child_number == number_of_in_flow_children_on_first_line_) - break; - } - - if (!baseline_child) - return LayoutUnit(-1); - - if (!IsColumnFlow() && !MainAxisIsInlineAxis(*baseline_child)) { - // TODO(cbiesinger): Should LogicalTop here be LogicalLeft? - return CrossAxisExtentForChild(*baseline_child) + - baseline_child->LogicalTop(); - } - if (IsColumnFlow() && MainAxisIsInlineAxis(*baseline_child)) { - return MainAxisExtentForChild(*baseline_child) + - baseline_child->LogicalTop(); - } - - LayoutUnit baseline = baseline_child->FirstLineBoxBaseline(); - if (baseline == -1) { - // FIXME: We should pass |direction| into firstLineBoxBaseline and stop - // bailing out if we're a writing mode root. This would also fix some - // cases where the flexbox is orthogonal to its container. - LineDirectionMode direction = - IsHorizontalWritingMode() ? kHorizontalLine : kVerticalLine; - return SynthesizedBaselineFromBorderBox(*baseline_child, direction) + - baseline_child->LogicalTop(); - } - - return baseline + baseline_child->LogicalTop(); -} - -LayoutUnit LayoutFlexibleBox::InlineBlockBaseline( - LineDirectionMode direction) const { - NOT_DESTROYED(); - return FirstLineBoxBaseline(); -} - -bool LayoutFlexibleBox::HasTopOverflow() const { - NOT_DESTROYED(); - if (IsHorizontalWritingMode()) - return StyleRef().ResolvedIsColumnReverseFlexDirection(); - return StyleRef().IsLeftToRightDirection() == - StyleRef().ResolvedIsRowReverseFlexDirection(); -} - -bool LayoutFlexibleBox::HasLeftOverflow() const { - NOT_DESTROYED(); - if (IsHorizontalWritingMode()) { - return StyleRef().IsLeftToRightDirection() == - StyleRef().ResolvedIsRowReverseFlexDirection(); - } - return (StyleRef().GetWritingMode() == WritingMode::kVerticalLr) == - StyleRef().ResolvedIsColumnReverseFlexDirection(); -} - -void LayoutFlexibleBox::MergeAnonymousFlexItems(LayoutObject* remove_child) { - NOT_DESTROYED(); - // When we remove a flex item, and the previous and next siblings of the item - // are text nodes wrapped in anonymous flex items, the adjacent text nodes - // need to be merged into the same flex item. - LayoutObject* prev = remove_child->PreviousSibling(); - if (!prev || !prev->IsAnonymousBlock()) - return; - LayoutObject* next = remove_child->NextSibling(); - if (!next || !next->IsAnonymousBlock()) - return; - To<LayoutBoxModelObject>(next)->MoveAllChildrenTo( - To<LayoutBoxModelObject>(prev)); - To<LayoutBlockFlow>(next)->DeleteLineBoxTree(); - next->Destroy(); - intrinsic_size_along_main_axis_.erase(next); -} - -void LayoutFlexibleBox::RemoveChild(LayoutObject* child) { - NOT_DESTROYED(); - if (!DocumentBeingDestroyed() && - !StyleRef().IsDeprecatedFlexboxUsingFlexLayout()) { - MergeAnonymousFlexItems(child); - } - - LayoutBlock::RemoveChild(child); - intrinsic_size_along_main_axis_.erase(child); -} - -bool LayoutFlexibleBox::HitTestChildren( - HitTestResult& result, - const HitTestLocation& hit_test_location, - const PhysicalOffset& accumulated_offset, - HitTestPhase phase) { - NOT_DESTROYED(); - if (phase != HitTestPhase::kForeground) - return false; - - PhysicalOffset scrolled_offset = accumulated_offset; - if (IsScrollContainer()) - scrolled_offset -= PhysicalOffset(PixelSnappedScrolledContentOffset()); - - for (LayoutBox* child = LastChildBox(); child; - child = child->PreviousSiblingBox()) { - if (child->HasSelfPaintingLayer()) - continue; - - PhysicalOffset child_accumulated_offset = - scrolled_offset + child->PhysicalLocation(this); - bool child_hit = child->HitTestAllPhases(result, hit_test_location, - child_accumulated_offset); - if (child_hit) { - UpdateHitTestResult(result, - hit_test_location.Point() - accumulated_offset); - return true; - } - } - return false; -} - -void LayoutFlexibleBox::StyleDidChange(StyleDifference diff, - const ComputedStyle* old_style) { - NOT_DESTROYED(); - LayoutBlock::StyleDidChange(diff, old_style); - - if (old_style && - old_style->ResolvedAlignItems(SelfAlignmentNormalBehavior()) - .GetPosition() == ItemPosition::kStretch && - diff.NeedsFullLayout()) { - // Flex items that were previously stretching need to be relayed out so we - // can compute new available cross axis space. This is only necessary for - // stretching since other alignment values don't change the size of the - // box. - for (LayoutBox* child = FirstChildBox(); child; - child = child->NextSiblingBox()) { - ItemPosition previous_alignment = - child->StyleRef() - .ResolvedAlignSelf(SelfAlignmentNormalBehavior(), old_style) - .GetPosition(); - if (previous_alignment == ItemPosition::kStretch && - previous_alignment != - child->StyleRef() - .ResolvedAlignSelf(SelfAlignmentNormalBehavior(), Style()) - .GetPosition()) - child->SetChildNeedsLayout(kMarkOnlyThis); - } - } -} - -void LayoutFlexibleBox::UpdateBlockLayout(bool relayout_children) { - NOT_DESTROYED(); - DCHECK(NeedsLayout()); - - if (!relayout_children && SimplifiedLayout()) - return; - - relaid_out_children_.clear(); - base::AutoReset<bool> reset1(&in_layout_, true); - DCHECK_EQ(has_definite_height_, SizeDefiniteness::kUnknown); - - if (UpdateLogicalWidthAndColumnWidth()) - relayout_children = true; - - SubtreeLayoutScope layout_scope(*this); - LayoutUnit previous_height = LogicalHeight(); - SetLogicalHeight(BorderAndPaddingLogicalHeight() + - ComputeLogicalScrollbars().BlockSum()); - - PaintLayerScrollableArea::DelayScrollOffsetClampScope delay_clamp_scope; - - { - TextAutosizer::LayoutScope text_autosizer_layout_scope(this, &layout_scope); - LayoutState state(*this); - - number_of_in_flow_children_on_first_line_ = -1; - - PrepareOrderIteratorAndMargins(); - - LayoutFlexItems(relayout_children, layout_scope); - if (PaintLayerScrollableArea::PreventRelayoutScope::RelayoutNeeded()) { - // Recompute the logical width, because children may have added or removed - // scrollbars. - UpdateLogicalWidthAndColumnWidth(); - PaintLayerScrollableArea::FreezeScrollbarsScope freeze_scrollbars_scope; - PrepareOrderIteratorAndMargins(); - LayoutFlexItems(true, layout_scope); - PaintLayerScrollableArea::PreventRelayoutScope::ResetRelayoutNeeded(); - } - - if (LogicalHeight() != previous_height) - relayout_children = true; - - LayoutPositionedObjects(relayout_children || IsDocumentElement()); - - // FIXME: css3/flexbox/repaint-rtl-column.html seems to issue paint - // invalidations for more overflow than it needs to. - ComputeLayoutOverflow(ClientLogicalBottomAfterRepositioning()); - } - - // We have to reset this, because changes to our ancestors' style can affect - // this value. Also, this needs to be before we call updateAfterLayout, as - // that function may re-enter this one. - has_definite_height_ = SizeDefiniteness::kUnknown; - - // Update our scroll information if we're overflow:auto/scroll/hidden now - // that we know if we overflow or not. - UpdateAfterLayout(); - - ClearNeedsLayout(); -} - -void LayoutFlexibleBox::PaintChildren(const PaintInfo& paint_info, - const PhysicalOffset&) const { - NOT_DESTROYED(); - BlockPainter(*this).PaintChildrenAtomically(this->GetOrderIterator(), - paint_info); -} - -void LayoutFlexibleBox::RepositionLogicalHeightDependentFlexItems( - FlexLayoutAlgorithm& algorithm) { - NOT_DESTROYED(); - Vector<FlexLine>& line_contexts = algorithm.FlexLines(); - LayoutUnit cross_axis_start_edge = line_contexts.empty() - ? LayoutUnit() - : line_contexts[0].cross_axis_offset_; - // If we have a single line flexbox, the line height is all the available - // space. For flex-direction: row, this means we need to use the height, so - // we do this after calling updateLogicalHeight. - if (!IsMultiline() && !line_contexts.empty()) { - line_contexts[0].cross_axis_extent_ = CrossAxisContentExtent(); - } - - AlignFlexLines(algorithm); - - AlignChildren(algorithm); - - if (StyleRef().FlexWrap() == EFlexWrap::kWrapReverse) { - algorithm.FlipForWrapReverse(cross_axis_start_edge, - CrossAxisContentExtent()); - for (FlexLine& line_context : line_contexts) { - for (FlexItem& flex_item : line_context.line_items_) { - ResetAlignmentForChild(*flex_item.box_, - flex_item.offset_->cross_axis_offset); - } - } - } - - // direction:rtl + flex-direction:column means the cross-axis direction is - // flipped. - FlipForRightToLeftColumn(line_contexts); -} - -DISABLE_CFI_PERF -LayoutUnit LayoutFlexibleBox::ClientLogicalBottomAfterRepositioning() { - NOT_DESTROYED(); - LayoutUnit max_child_logical_bottom; - for (LayoutBox* child = FirstChildBox(); child; - child = child->NextSiblingBox()) { - if (child->IsOutOfFlowPositioned()) - continue; - LayoutUnit child_logical_bottom = LogicalTopForChild(*child) + - LogicalHeightForChild(*child) + - MarginAfterForChild(*child); - max_child_logical_bottom = - std::max(max_child_logical_bottom, child_logical_bottom); - } - return std::max(ClientLogicalBottom(), - max_child_logical_bottom + PaddingAfter()); -} - -bool LayoutFlexibleBox::MainAxisIsInlineAxis(const LayoutBox& child) const { - NOT_DESTROYED(); - // If we have a horizontal flow, that means the main size is the width. - // That's the inline size for horizontal writing modes, and the block - // size in vertical writing modes. For a vertical flow, main size is the - // height, so it's the inverse. So we need the inline size if we have a - // horizontal flow and horizontal writing mode, or vertical flow and vertical - // writing mode. Otherwise we need the block size. - return IsHorizontalFlow() == child.IsHorizontalWritingMode(); -} - -bool LayoutFlexibleBox::IsColumnFlow() const { - NOT_DESTROYED(); - return StyleRef().ResolvedIsColumnFlexDirection(); -} - -bool LayoutFlexibleBox::IsHorizontalFlow() const { - NOT_DESTROYED(); - if (IsHorizontalWritingMode()) - return !IsColumnFlow(); - return IsColumnFlow(); -} - -bool LayoutFlexibleBox::IsLeftToRightFlow() const { - NOT_DESTROYED(); - if (IsColumnFlow()) { - return blink::IsHorizontalWritingMode(StyleRef().GetWritingMode()) || - IsFlippedLinesWritingMode(StyleRef().GetWritingMode()); - } - return StyleRef().IsLeftToRightDirection() ^ - StyleRef().ResolvedIsRowReverseFlexDirection(); -} - -bool LayoutFlexibleBox::IsMultiline() const { - NOT_DESTROYED(); - return StyleRef().FlexWrap() != EFlexWrap::kNowrap; -} - -Length LayoutFlexibleBox::FlexBasisForChild(const LayoutBox& child) const { - NOT_DESTROYED(); - Length flex_length = child.StyleRef().FlexBasis(); - if (flex_length.IsAuto()) { - flex_length = IsHorizontalFlow() ? child.StyleRef().Width() - : child.StyleRef().Height(); - } - return flex_length; -} - -LayoutUnit LayoutFlexibleBox::CrossAxisExtentForChild( - const LayoutBox& child) const { - NOT_DESTROYED(); - return IsHorizontalFlow() ? child.Size().Height() : child.Size().Width(); -} - -LayoutUnit LayoutFlexibleBox::ChildUnstretchedLogicalHeight( - const LayoutBox& child) const { - NOT_DESTROYED(); - // This should only be called if the logical height is the cross size - DCHECK(MainAxisIsInlineAxis(child)); - if (NeedToStretchChildLogicalHeight(child)) { - AutoClearOverrideLogicalHeight clear(const_cast<LayoutBox*>(&child)); - - LayoutUnit child_intrinsic_content_logical_height; - // If we have size containment specified, and are not overriding the - // intrinsic content height, then the height is LayoutUnit(). In all other - // cases, this if-condition will pass and set the intrinsic height. - if (!child.ShouldApplySizeContainment() || - child.HasOverrideIntrinsicContentLogicalHeight()) { - child_intrinsic_content_logical_height = - child.IntrinsicContentLogicalHeight(); - } - - LayoutUnit child_intrinsic_logical_height = - child_intrinsic_content_logical_height + - child.ComputeLogicalScrollbars().BlockSum() + - child.BorderAndPaddingLogicalHeight(); - LogicalExtentComputedValues values; - child.ComputeLogicalHeight(child_intrinsic_logical_height, LayoutUnit(), - values); - return values.extent_; - } - return child.LogicalHeight(); -} - -DISABLE_CFI_PERF -LayoutUnit LayoutFlexibleBox::ChildUnstretchedLogicalWidth( - const LayoutBox& child) const { - NOT_DESTROYED(); - // This should only be called if the logical width is the cross size - DCHECK(!MainAxisIsInlineAxis(child)); - - // We compute the width as if we were unstretched. Only the main axis - // override size is set at this point. - // However, if our cross axis length is definite we don't need to recompute - // and can just return the already-set logical width. - if (!CrossAxisLengthIsDefinite(child, child.StyleRef().LogicalWidth())) { - AutoClearOverrideLogicalWidth clear(const_cast<LayoutBox*>(&child)); - - LogicalExtentComputedValues values; - child.ComputeLogicalWidth(values); - return values.extent_; - } - - return child.LogicalWidth(); -} - -LayoutUnit LayoutFlexibleBox::CrossAxisUnstretchedExtentForChild( - const LayoutBox& child) const { - NOT_DESTROYED(); - return MainAxisIsInlineAxis(child) ? ChildUnstretchedLogicalHeight(child) - : ChildUnstretchedLogicalWidth(child); -} - -LayoutUnit LayoutFlexibleBox::MainAxisExtentForChild( - const LayoutBox& child) const { - NOT_DESTROYED(); - return IsHorizontalFlow() ? child.Size().Width() : child.Size().Height(); -} - -LayoutUnit LayoutFlexibleBox::MainAxisContentExtentForChild( - const LayoutBox& child) const { - NOT_DESTROYED(); - return IsHorizontalFlow() ? child.ContentWidth() : child.ContentHeight(); -} - -LayoutUnit LayoutFlexibleBox::MainAxisContentExtentForChildIncludingScrollbar( - const LayoutBox& child) const { - NOT_DESTROYED(); - return IsHorizontalFlow() - ? child.ContentWidth() + child.ComputeScrollbars().HorizontalSum() - : child.ContentHeight() + child.ComputeScrollbars().VerticalSum(); -} - -LayoutUnit LayoutFlexibleBox::CrossAxisExtent() const { - NOT_DESTROYED(); - return IsHorizontalFlow() ? Size().Height() : Size().Width(); -} - -LayoutUnit LayoutFlexibleBox::CrossAxisContentExtent() const { - NOT_DESTROYED(); - return IsHorizontalFlow() ? ContentHeight() : ContentWidth(); -} - -LayoutUnit LayoutFlexibleBox::MainAxisContentExtent( - LayoutUnit content_logical_height) { - NOT_DESTROYED(); - if (IsColumnFlow()) { - LogicalExtentComputedValues computed_values; - LayoutUnit border_padding_and_scrollbar = - BorderAndPaddingLogicalHeight() + ComputeLogicalScrollbars().BlockSum(); - LayoutUnit border_box_logical_height = - content_logical_height + border_padding_and_scrollbar; - ComputeLogicalHeight(border_box_logical_height, LogicalTop(), - computed_values); - if (computed_values.extent_ == LayoutUnit::Max()) - return computed_values.extent_; - return std::max(LayoutUnit(), - computed_values.extent_ - border_padding_and_scrollbar); - } - return ContentLogicalWidth(); -} - -LayoutUnit LayoutFlexibleBox::ComputeMainAxisExtentForChild( - const LayoutBox& child, - SizeType size_type, - const Length& size, - LayoutUnit border_and_padding) const { - NOT_DESTROYED(); - if (!MainAxisIsInlineAxis(child)) { - // We don't have to check for "auto" here - computeContentLogicalHeight - // will just return -1 for that case anyway. It's safe to access - // scrollbarLogicalHeight here because ComputeNextFlexLine will have - // already forced layout on the child. We previously layed out the child - // if necessary (see ComputeNextFlexLine and the call to - // childHasIntrinsicMainAxisSize) so we can be sure that the two height - // calls here will return up-to-date data. - LayoutUnit logical_height = child.ComputeContentLogicalHeight( - size_type, size, child.IntrinsicContentLogicalHeight()); - if (logical_height == -1) - return logical_height; - return logical_height + child.ComputeLogicalScrollbars().BlockSum(); - } - // computeLogicalWidth always re-computes the intrinsic widths. However, when - // our logical width is auto, we can just use our cached value. So let's do - // that here. (Compare code in LayoutBlock::computePreferredLogicalWidths) - if (child.StyleRef().LogicalWidth().IsAuto() && !HasAspectRatio(child)) { - if (size.IsMinContent() || size.IsMinIntrinsic()) - return child.PreferredLogicalWidths().min_size - border_and_padding; - if (size.IsMaxContent()) - return child.PreferredLogicalWidths().max_size - border_and_padding; - } - return child.ComputeLogicalWidthUsing(size_type, size, ContentLogicalWidth(), - this) - - border_and_padding; -} - -LayoutUnit LayoutFlexibleBox::ContentInsetRight() const { - NOT_DESTROYED(); - return BorderRight() + PaddingRight() + ComputeScrollbars().right; -} - -LayoutUnit LayoutFlexibleBox::ContentInsetBottom() const { - NOT_DESTROYED(); - return BorderBottom() + PaddingBottom() + ComputeScrollbars().bottom; -} - -LayoutUnit LayoutFlexibleBox::FlowAwareContentInsetStart() const { - NOT_DESTROYED(); - if (IsHorizontalFlow()) - return IsLeftToRightFlow() ? ContentLeft() : ContentInsetRight(); - return IsLeftToRightFlow() ? ContentTop() : ContentInsetBottom(); -} - -LayoutUnit LayoutFlexibleBox::FlowAwareContentInsetEnd() const { - NOT_DESTROYED(); - if (IsHorizontalFlow()) - return IsLeftToRightFlow() ? ContentInsetRight() : ContentLeft(); - return IsLeftToRightFlow() ? ContentInsetBottom() : ContentTop(); -} - -LayoutUnit LayoutFlexibleBox::FlowAwareContentInsetBefore() const { - NOT_DESTROYED(); - switch (FlexLayoutAlgorithm::GetTransformedWritingMode(StyleRef())) { - case TransformedWritingMode::kTopToBottomWritingMode: - return ContentTop(); - case TransformedWritingMode::kBottomToTopWritingMode: - return ContentInsetBottom(); - case TransformedWritingMode::kLeftToRightWritingMode: - return ContentLeft(); - case TransformedWritingMode::kRightToLeftWritingMode: - return ContentInsetRight(); - } - NOTREACHED(); -} - -DISABLE_CFI_PERF -LayoutUnit LayoutFlexibleBox::FlowAwareContentInsetAfter() const { - NOT_DESTROYED(); - switch (FlexLayoutAlgorithm::GetTransformedWritingMode(StyleRef())) { - case TransformedWritingMode::kTopToBottomWritingMode: - return ContentInsetBottom(); - case TransformedWritingMode::kBottomToTopWritingMode: - return ContentTop(); - case TransformedWritingMode::kLeftToRightWritingMode: - return ContentInsetRight(); - case TransformedWritingMode::kRightToLeftWritingMode: - return ContentLeft(); - } - NOTREACHED(); -} - -LayoutUnit LayoutFlexibleBox::CrossAxisScrollbarExtent() const { - NOT_DESTROYED(); - return IsHorizontalFlow() ? ComputeScrollbars().HorizontalSum() - : ComputeScrollbars().VerticalSum(); -} - -LayoutUnit LayoutFlexibleBox::CrossAxisScrollbarExtentForChild( - const LayoutBox& child) const { - NOT_DESTROYED(); - return IsHorizontalFlow() ? child.ComputeScrollbars().HorizontalSum() - : child.ComputeScrollbars().VerticalSum(); -} - -FlexOffset LayoutFlexibleBox::FlowAwareLocationForChild( - const LayoutBox& child) const { - NOT_DESTROYED(); - LayoutPoint location = IsHorizontalFlow() - ? child.Location() - : child.Location().TransposedPoint(); - return FlexOffset(location.X(), location.Y()); -} - -bool LayoutFlexibleBox::UseChildAspectRatio(const LayoutBox& child) const { - NOT_DESTROYED(); - if (!HasAspectRatio(child)) - return false; - if (child.StyleRef().AspectRatio().IsAuto() && - child.IntrinsicSize().Height() == 0) { - // We can't compute a ratio in this case. - return false; - } - const Length& cross_size = - IsHorizontalFlow() ? child.StyleRef().Height() : child.StyleRef().Width(); - return CrossAxisLengthIsDefinite(child, cross_size); -} - -LayoutUnit LayoutFlexibleBox::ComputeMainSizeFromAspectRatioUsing( - const LayoutBox& child, - const Length& cross_size_length, - LayoutUnit main_axis_border_and_padding, - LayoutUnit cross_axis_border_and_padding) const { - NOT_DESTROYED(); - DCHECK(HasAspectRatio(child)); - - LayoutUnit cross_size; - if (cross_size_length.IsFixed()) { - cross_size = LayoutUnit(cross_size_length.Value()); - } else { - DCHECK(cross_size_length.IsPercentOrCalc()); - cross_size = MainAxisIsInlineAxis(child) - ? child.ComputePercentageLogicalHeight(cross_size_length) - : AdjustBorderBoxLogicalWidthForBoxSizing( - ValueForLength(cross_size_length, ContentWidth())); - } - - LayoutSize aspect_ratio = child.IntrinsicSize(); - EAspectRatioType ar_type = child.StyleRef().AspectRatio().GetType(); - LayoutUnit border_and_padding; - if (ar_type == EAspectRatioType::kRatio || - (ar_type == EAspectRatioType::kAutoAndRatio && aspect_ratio.IsEmpty())) { - aspect_ratio = LayoutSize(child.StyleRef().AspectRatio().GetRatio()); - if (child.StyleRef().BoxSizingForAspectRatio() == EBoxSizing::kContentBox) { - cross_size -= cross_axis_border_and_padding; - border_and_padding = main_axis_border_and_padding; - } - } - // TODO(cbiesinger): box sizing? - double ratio = - aspect_ratio.Width().ToFloat() / aspect_ratio.Height().ToFloat(); - if (IsHorizontalFlow()) - return LayoutUnit(cross_size * ratio) + border_and_padding; - return LayoutUnit(cross_size / ratio) + border_and_padding; -} - -void LayoutFlexibleBox::SetFlowAwareLocationForChild( - LayoutBox& child, - const FlexOffset& flex_offset) { - NOT_DESTROYED(); - if (IsHorizontalFlow()) { - child.SetLocationAndUpdateOverflowControlsIfNeeded(LayoutPoint( - flex_offset.main_axis_offset, flex_offset.cross_axis_offset)); - } else { - child.SetLocationAndUpdateOverflowControlsIfNeeded(LayoutPoint( - flex_offset.cross_axis_offset, flex_offset.main_axis_offset)); - } -} - -bool LayoutFlexibleBox::MainAxisLengthIsDefinite(const LayoutBox& child, - const Length& flex_basis, - bool add_to_cb) const { - NOT_DESTROYED(); - // 'content' isn't actually supported in legacy flex. Checking IsContent() and - // returning false on the next line prevents a DCHECK though. - if (flex_basis.IsAuto() || flex_basis.IsContent()) - return false; - if (IsColumnFlow() && flex_basis.IsContentOrIntrinsicOrFillAvailable()) - return false; - if (flex_basis.IsPercentOrCalc()) { - if (!IsColumnFlow() || has_definite_height_ == SizeDefiniteness::kDefinite) - return true; - if (has_definite_height_ == SizeDefiniteness::kIndefinite) - return false; - if (child.HasOverrideContainingBlockContentLogicalHeight()) { - // We don't want to cache this. To be a bit more efficient, just check - // whether the override height is -1 or not and return the value based on - // that. - DCHECK(!add_to_cb); - LayoutUnit override_height = - child.OverrideContainingBlockContentLogicalHeight(); - return override_height == LayoutUnit(-1) ? false : true; - } - LayoutBlock* cb = nullptr; - bool definite = - child.ContainingBlockLogicalHeightForPercentageResolution(&cb) != -1; - if (add_to_cb) - cb->AddPercentHeightDescendant(const_cast<LayoutBox*>(&child)); - if (in_layout_) { - // We can reach this code even while we're not laying ourselves out, such - // as from mainSizeForPercentageResolution. - has_definite_height_ = definite ? SizeDefiniteness::kDefinite - : SizeDefiniteness::kIndefinite; - } - return definite; - } - return true; -} - -bool LayoutFlexibleBox::CrossAxisLengthIsDefinite(const LayoutBox& child, - const Length& length) const { - NOT_DESTROYED(); - if (length.IsAuto()) - return false; - if (length.IsPercentOrCalc()) { - if (!MainAxisIsInlineAxis(child) || - has_definite_height_ == SizeDefiniteness::kDefinite) - return true; - if (has_definite_height_ == SizeDefiniteness::kIndefinite) - return false; - bool definite = - child.ContainingBlockLogicalHeightForPercentageResolution() != -1; - has_definite_height_ = - definite ? SizeDefiniteness::kDefinite : SizeDefiniteness::kIndefinite; - return definite; - } - // TODO(cbiesinger): Eventually we should support other types of sizes here. - // Requires updating computeMainSizeFromAspectRatioUsing. - return length.IsFixed(); -} - -void LayoutFlexibleBox::CacheChildMainSize(const LayoutBox& child) { - NOT_DESTROYED(); - DCHECK(!child.SelfNeedsLayout()); - DCHECK(!child.NeedsLayout() || child.ChildLayoutBlockedByDisplayLock()); - LayoutUnit main_size; - if (MainAxisIsInlineAxis(child)) { - main_size = child.PreferredLogicalWidths().max_size; - } else { - if (FlexBasisForChild(child).IsPercentOrCalc() && - !MainAxisLengthIsDefinite(child, FlexBasisForChild(child))) { - main_size = child.IntrinsicContentLogicalHeight() + - child.BorderAndPaddingLogicalHeight() + - child.ComputeLogicalScrollbars().BlockSum(); - } else { - main_size = child.LogicalHeight(); - } - } - intrinsic_size_along_main_axis_.Set(&child, main_size); - relaid_out_children_.insert(&child); -} - -void LayoutFlexibleBox::ClearCachedMainSizeForChild(const LayoutBox& child) { - NOT_DESTROYED(); - intrinsic_size_along_main_axis_.erase(&child); -} - -bool LayoutFlexibleBox::CanAvoidLayoutForNGChild(const LayoutBox& child) const { - NOT_DESTROYED(); - if (!child.IsLayoutNGObject()) - return false; - - // If the last layout was done with a different override size, or different - // definite-ness, we need to force-relayout so that percentage sizes are - // resolved correctly. - const NGLayoutResult* cached_layout_result = - child.GetSingleCachedLayoutResult(); - if (!cached_layout_result) - return false; - - const NGConstraintSpace& old_space = - cached_layout_result->GetConstraintSpaceForCaching(); - if (old_space.IsFixedInlineSize() != child.HasOverrideLogicalWidth()) - return false; - if (old_space.IsFixedBlockSize() != child.HasOverrideLogicalHeight()) - return false; - if (!old_space.IsInitialBlockSizeIndefinite() != - UseOverrideLogicalHeightForPerentageResolution(child)) - return false; - if (child.HasOverrideLogicalWidth() && - old_space.AvailableSize().inline_size != child.OverrideLogicalWidth()) - return false; - if (child.HasOverrideLogicalHeight() && - old_space.AvailableSize().block_size != child.OverrideLogicalHeight()) - return false; - return true; -} - -DISABLE_CFI_PERF -LayoutUnit LayoutFlexibleBox::ComputeInnerFlexBaseSizeForChild( - LayoutBox& child, - LayoutUnit main_axis_border_and_padding, - LayoutUnit cross_axis_border_and_padding, - ChildLayoutType child_layout_type) { - NOT_DESTROYED(); - if (child.IsImage() || IsA<LayoutVideo>(child) || child.IsCanvas()) - UseCounter::Count(GetDocument(), WebFeature::kAspectRatioFlexItem); - - Length flex_basis = FlexBasisForChild(child); - // -webkit-box sizes as fit-content instead of max-content. - if (flex_basis.IsAuto() && - (StyleRef().IsDeprecatedWebkitBox() && - (StyleRef().BoxOrient() == EBoxOrient::kHorizontal || - StyleRef().BoxAlign() != EBoxAlignment::kStretch))) { - flex_basis = Length(Length::kFitContent); - } - if (MainAxisLengthIsDefinite(child, flex_basis)) { - return std::max(LayoutUnit(), ComputeMainAxisExtentForChild( - child, kMainOrPreferredSize, flex_basis, - main_axis_border_and_padding)); - } - - if (UseChildAspectRatio(child)) { - const Length& cross_size_length = IsHorizontalFlow() - ? child.StyleRef().Height() - : child.StyleRef().Width(); - LayoutUnit result = ComputeMainSizeFromAspectRatioUsing( - child, cross_size_length, main_axis_border_and_padding, - cross_axis_border_and_padding); - result = AdjustChildSizeForAspectRatioCrossAxisMinAndMax( - child, result, main_axis_border_and_padding, - cross_axis_border_and_padding); - return result - main_axis_border_and_padding; - } - - // The flex basis is indefinite (=auto), so we need to compute the actual - // width of the child. For the logical width axis we just use the preferred - // width; for the height we need to lay out the child. - LayoutUnit main_axis_extent; - if (MainAxisIsInlineAxis(child)) { - // We don't need to add ComputeLogicalScrollbars().InlineSum() here because - // the preferred width includes the scrollbar, even for overflow: auto. - main_axis_extent = child.PreferredLogicalWidths().max_size; - } else { - // The needed value here is the logical height. This value does not include - // the border/scrollbar/padding size, so we have to add the scrollbar. - if (child.HasOverrideIntrinsicContentLogicalHeight()) { - return child.OverrideIntrinsicContentLogicalHeight() + - LayoutUnit(child.ComputeLogicalScrollbars().BlockSum()); - } - if (child.ShouldApplySizeContainment()) - return LayoutUnit(child.ComputeLogicalScrollbars().BlockSum()); - - if (child_layout_type == kNeverLayout) - return LayoutUnit(); - - DCHECK(!child.NeedsLayout()); - DCHECK(intrinsic_size_along_main_axis_.Contains(&child)); - main_axis_extent = intrinsic_size_along_main_axis_.at(&child); - } - DCHECK_GE(main_axis_extent - main_axis_border_and_padding, LayoutUnit()) - << main_axis_extent << " - " << main_axis_border_and_padding; - return main_axis_extent - main_axis_border_and_padding; -} - -void LayoutFlexibleBox::LayoutFlexItems(bool relayout_children, - SubtreeLayoutScope& layout_scope) { - NOT_DESTROYED(); - PaintLayerScrollableArea::PreventRelayoutScope prevent_relayout_scope( - layout_scope); - - // Set up our list of flex items. All of the rest of the algorithm should - // work off this list of a subset. - ChildLayoutType layout_type = - relayout_children ? kForceLayout : kLayoutIfNeeded; - const LayoutUnit line_break_length = MainAxisContentExtent(LayoutUnit::Max()); - FlexLayoutAlgorithm flex_algorithm( - Style(), line_break_length, - LogicalSize{ContentLogicalWidth(), - AvailableLogicalHeightForPercentageComputation()}, - &GetDocument()); - order_iterator_.First(); - for (LayoutBox* child = order_iterator_.CurrentChild(); child; - child = order_iterator_.Next()) { - if (child->IsOutOfFlowPositioned()) { - // Out-of-flow children are not flex items, so we skip them here. - PrepareChildForPositionedLayout(*child); - continue; - } - - ConstructAndAppendFlexItem(&flex_algorithm, *child, layout_type); - } - // Because we set the override containing block logical height to -1 in - // ConstructAndAppendFlexItem, any value we may have cached for definiteness - // is incorrect; just reset it here. - has_definite_height_ = SizeDefiniteness::kUnknown; - - LayoutUnit cross_axis_offset = FlowAwareContentInsetBefore(); - LayoutUnit logical_width = LogicalWidth(); - FlexLine* current_line; - Vector<FlexOffset> item_offsets(flex_algorithm.NumItems()); - FlexOffset* current_item_offset = item_offsets.begin(); - while ((current_line = flex_algorithm.ComputeNextFlexLine(logical_width))) { - DCHECK_GE(current_line->line_items_.size(), 0ULL); - current_line->SetContainerMainInnerSize( - MainAxisContentExtent(current_line->sum_hypothetical_main_size_)); - current_line->FreezeInflexibleItems(); - - while (!current_line->ResolveFlexibleLengths()) { - DCHECK_GE(current_line->total_flex_grow_, 0); - DCHECK_GE(current_line->total_weighted_flex_shrink_, 0); - } - - LayoutLineItems(current_line, relayout_children, layout_scope, - ¤t_item_offset); - - current_line->ComputeLineItemsPosition(FlowAwareContentInsetStart(), - FlowAwareContentInsetEnd(), - cross_axis_offset); - ApplyLineItemsPosition(current_line); - if (number_of_in_flow_children_on_first_line_ == -1) { - number_of_in_flow_children_on_first_line_ = - current_line->line_items_.size(); - } - } - if (HasLineIfEmpty()) { - // Even if ComputeNextFlexLine returns true, the flexbox might not have - // a line because all our children might be out of flow positioned. - // Instead of just checking if we have a line, make sure the flexbox - // has at least a line's worth of height to cover this case. - LayoutUnit min_height = MinimumLogicalHeightForEmptyLine(); - if (Size().Height() < min_height) - SetLogicalHeight(min_height); - } - if (!IsColumnFlow()) { - SetLogicalHeight(LogicalHeight() + - flex_algorithm.gap_between_lines_ * - (flex_algorithm.FlexLines().size() - 1)); - } - UpdateLogicalHeight(); - if (!HasOverrideLogicalHeight() && IsColumnFlow()) { - SetIntrinsicContentLogicalHeight( - flex_algorithm.IntrinsicContentBlockSize()); - } - RepositionLogicalHeightDependentFlexItems(flex_algorithm); -} - -bool LayoutFlexibleBox::HasAutoMarginsInCrossAxis( - const LayoutBox& child) const { - NOT_DESTROYED(); - if (IsHorizontalFlow()) { - return child.StyleRef().MarginTop().IsAuto() || - child.StyleRef().MarginBottom().IsAuto(); - } - return child.StyleRef().MarginLeft().IsAuto() || - child.StyleRef().MarginRight().IsAuto(); -} - -LayoutUnit LayoutFlexibleBox::ComputeChildMarginValue(const Length& margin) { - NOT_DESTROYED(); - // When resolving the margins, we use the content size for resolving percent - // and calc (for percents in calc expressions) margins. Fortunately, percent - // margins are always computed with respect to the block's width, even for - // margin-top and margin-bottom. - LayoutUnit available_size = ContentLogicalWidth(); - return MinimumValueForLength(margin, available_size); -} - -void LayoutFlexibleBox::PrepareOrderIteratorAndMargins() { - NOT_DESTROYED(); - OrderIteratorPopulator populator(order_iterator_); - - for (LayoutBox* child = FirstChildBox(); child; - child = child->NextSiblingBox()) { - populator.CollectChild(child); - - if (child->IsOutOfFlowPositioned()) - continue; - - // Before running the flex algorithm, 'auto' has a margin of 0. - const ComputedStyle& style = child->StyleRef(); - child->SetMarginTop(ComputeChildMarginValue(style.MarginTop())); - child->SetMarginRight(ComputeChildMarginValue(style.MarginRight())); - child->SetMarginBottom(ComputeChildMarginValue(style.MarginBottom())); - child->SetMarginLeft(ComputeChildMarginValue(style.MarginLeft())); - } -} - -DISABLE_CFI_PERF -MinMaxSizes LayoutFlexibleBox::ComputeMinAndMaxSizesForChild( - const FlexLayoutAlgorithm& algorithm, - const LayoutBox& child, - LayoutUnit border_and_padding, - LayoutUnit cross_axis_border_and_padding) const { - NOT_DESTROYED(); - MinMaxSizes sizes{LayoutUnit(), LayoutUnit::Max()}; - - const Length& max = IsHorizontalFlow() ? child.StyleRef().MaxWidth() - : child.StyleRef().MaxHeight(); - if (!max.IsNone()) { - sizes.max_size = - ComputeMainAxisExtentForChild(child, kMaxSize, max, border_and_padding); - if (sizes.max_size == -1) - sizes.max_size = LayoutUnit::Max(); - DCHECK_GE(sizes.max_size, LayoutUnit()); - } - - const Length& min = IsHorizontalFlow() ? child.StyleRef().MinWidth() - : child.StyleRef().MinHeight(); - if (!min.IsAuto()) { - sizes.min_size = - ComputeMainAxisExtentForChild(child, kMinSize, min, border_and_padding); - // computeMainAxisExtentForChild can return -1 when the child has a - // percentage min size, but we have an indefinite size in that axis. - sizes.min_size = std::max(LayoutUnit(), sizes.min_size); - } else if (algorithm.ShouldApplyMinSizeAutoForChild(child)) { - LayoutUnit content_size = ComputeMainAxisExtentForChild( - child, kMinSize, Length::MinContent(), border_and_padding); - DCHECK_GE(content_size, LayoutUnit()); - if (HasAspectRatio(child) && child.IntrinsicSize().Height() > 0) { - content_size = AdjustChildSizeForAspectRatioCrossAxisMinAndMax( - child, content_size, border_and_padding, - cross_axis_border_and_padding); - } - if (child.IsTable() && !IsColumnFlow()) { - // Avoid resolving minimum size to something narrower than the minimum - // preferred logical width of the table. - sizes.min_size = content_size; - } else { - if (sizes.max_size != -1 && content_size > sizes.max_size) - content_size = sizes.max_size; - - const Length& main_size = IsHorizontalFlow() ? child.StyleRef().Width() - : child.StyleRef().Height(); - if (MainAxisLengthIsDefinite(child, main_size)) { - LayoutUnit resolved_main_size = ComputeMainAxisExtentForChild( - child, kMainOrPreferredSize, main_size, border_and_padding); - DCHECK_GE(resolved_main_size, LayoutUnit()); - LayoutUnit specified_size = - sizes.max_size != -1 ? std::min(resolved_main_size, sizes.max_size) - : resolved_main_size; - - sizes.min_size = std::min(specified_size, content_size); - } else if (child.IsLayoutReplaced() && UseChildAspectRatio(child)) { - const Length& cross_size_length = IsHorizontalFlow() - ? child.StyleRef().Height() - : child.StyleRef().Width(); - LayoutUnit transferred_size = ComputeMainSizeFromAspectRatioUsing( - child, cross_size_length, border_and_padding, - cross_axis_border_and_padding); - transferred_size = AdjustChildSizeForAspectRatioCrossAxisMinAndMax( - child, transferred_size, border_and_padding, - cross_axis_border_and_padding); - sizes.min_size = std::min(transferred_size, content_size); - } else { - sizes.min_size = content_size; - } - } - } - DCHECK_GE(sizes.min_size, LayoutUnit()); - return sizes; -} - -bool LayoutFlexibleBox::CrossSizeIsDefiniteForPercentageResolution( - const LayoutBox& child) const { - NOT_DESTROYED(); - DCHECK(MainAxisIsInlineAxis(child)); - if (FlexLayoutAlgorithm::AlignmentForChild(StyleRef(), child.StyleRef()) != - ItemPosition::kStretch) - return false; - - // Here we implement https://drafts.csswg.org/css-flexbox/#algo-stretch - if (child.HasOverrideLogicalHeight()) - return true; - - // We don't currently implement the optimization from - // https://drafts.csswg.org/css-flexbox/#definite-sizes case 1. While that - // could speed up a specialized case, it requires determining if we have a - // definite size, which itself is not cheap. We can consider implementing it - // at a later time. (The correctness is ensured by redoing layout in - // applyStretchAlignmentToChild) - return false; -} - -bool LayoutFlexibleBox::MainSizeIsDefiniteForPercentageResolution( - const LayoutBox& child) const { - NOT_DESTROYED(); - DCHECK(!MainAxisIsInlineAxis(child)); - // This function implements section 9.8. Definite and Indefinite Sizes, case - // 2) of the flexbox spec. - // We need to check for the flexbox to have a definite main size. - // We make up a percentage to check whether we have a definite size. - if (!MainAxisLengthIsDefinite(child, Length::Percent(0), false)) - return false; - - return child.HasOverrideLogicalHeight(); -} - -bool LayoutFlexibleBox::UseOverrideLogicalHeightForPerentageResolution( - const LayoutBox& child) const { - NOT_DESTROYED(); - if (MainAxisIsInlineAxis(child)) - return CrossSizeIsDefiniteForPercentageResolution(child); - return MainSizeIsDefiniteForPercentageResolution(child); -} - -LayoutUnit LayoutFlexibleBox::AdjustChildSizeForAspectRatioCrossAxisMinAndMax( - const LayoutBox& child, - LayoutUnit child_size, - LayoutUnit main_axis_border_and_padding, - LayoutUnit cross_axis_border_and_padding) const { - NOT_DESTROYED(); - const Length& cross_min = IsHorizontalFlow() ? child.StyleRef().MinHeight() - : child.StyleRef().MinWidth(); - const Length& cross_max = IsHorizontalFlow() ? child.StyleRef().MaxHeight() - : child.StyleRef().MaxWidth(); - - if (CrossAxisLengthIsDefinite(child, cross_max)) { - LayoutUnit max_value = ComputeMainSizeFromAspectRatioUsing( - child, cross_max, main_axis_border_and_padding, - cross_axis_border_and_padding); - child_size = std::min(max_value, child_size); - } - - if (CrossAxisLengthIsDefinite(child, cross_min)) { - LayoutUnit min_value = ComputeMainSizeFromAspectRatioUsing( - child, cross_min, main_axis_border_and_padding, - cross_axis_border_and_padding); - child_size = std::max(min_value, child_size); - } - - return child_size; -} - -DISABLE_CFI_PERF -void LayoutFlexibleBox::ConstructAndAppendFlexItem( - FlexLayoutAlgorithm* algorithm, - LayoutBox& child, - ChildLayoutType layout_type) { - NOT_DESTROYED(); - if (layout_type != kNeverLayout && - ChildHasIntrinsicMainAxisSize(*algorithm, child)) { - // If this condition is true, then ComputeMainAxisExtentForChild will call - // child.IntrinsicContentLogicalHeight() and - // child.ScrollbarLogicalHeight(), so if the child has intrinsic - // min/max/preferred size, run layout on it now to make sure its logical - // height and scroll bars are up to date. - // For column flow flex containers, we even need to do this for children - // that don't need layout, if there's a chance that the logical width of - // the flex container has changed (because that may affect the intrinsic - // height of the child). - UpdateBlockChildDirtyBitsBeforeLayout(layout_type == kForceLayout, child); - if (child.NeedsLayout() || layout_type == kForceLayout || - !intrinsic_size_along_main_axis_.Contains(&child)) { - // Don't resolve percentages in children. This is especially important - // for the min-height calculation, where we want percentages to be - // treated as auto. For flex-basis itself, this is not a problem because - // by definition we have an indefinite flex basis here and thus - // percentages should not resolve. - if (IsHorizontalWritingMode() == child.IsHorizontalWritingMode()) - child.SetOverrideContainingBlockContentLogicalHeight(LayoutUnit(-1)); - else - child.SetOverrideContainingBlockContentLogicalWidth(LayoutUnit(-1)); - child.ClearOverrideSize(); - child.ForceLayout(); - CacheChildMainSize(child); - child.ClearOverrideContainingBlockContentSize(); - } - } - - LayoutUnit main_axis_border_padding = IsHorizontalFlow() - ? child.BorderAndPaddingWidth() - : child.BorderAndPaddingHeight(); - LayoutUnit cross_axis_border_padding = IsHorizontalFlow() - ? child.BorderAndPaddingHeight() - : child.BorderAndPaddingWidth(); - - LayoutUnit child_inner_flex_base_size = ComputeInnerFlexBaseSizeForChild( - child, main_axis_border_padding, cross_axis_border_padding, layout_type); - - MinMaxSizes sizes = ComputeMinAndMaxSizesForChild( - *algorithm, child, main_axis_border_padding, cross_axis_border_padding); - - NGPhysicalBoxStrut physical_margins(child.MarginTop(), child.MarginRight(), - child.MarginBottom(), child.MarginLeft()); - algorithm->emplace_back( - &child, child.StyleRef(), child_inner_flex_base_size, sizes, - /* min_max_cross_sizes */ absl::nullopt, main_axis_border_padding, - cross_axis_border_padding, physical_margins, /* unused */ NGBoxStrut(), - StyleRef().GetWritingMode()); -} - -void LayoutFlexibleBox::SetOverrideMainAxisContentSizeForChild(FlexItem& item) { - NOT_DESTROYED(); - if (MainAxisIsInlineAxis(*item.box_)) { - item.box_->SetOverrideLogicalWidth(item.FlexedBorderBoxSize()); - } else { - item.box_->SetOverrideLogicalHeight(item.FlexedBorderBoxSize()); - } -} - -namespace { - -LayoutUnit MainAxisStaticPositionCommon(const LayoutBox& child, - LayoutBox* parent, - LayoutUnit available_space) { - LayoutUnit offset = FlexLayoutAlgorithm::InitialContentPositionOffset( - parent->StyleRef(), available_space, - FlexLayoutAlgorithm::ResolvedJustifyContent(parent->StyleRef()), 1); - if (parent->StyleRef().ResolvedIsRowReverseFlexDirection() || - parent->StyleRef().ResolvedIsColumnReverseFlexDirection()) - offset = available_space - offset; - return offset; -} - -LayoutUnit StaticMainAxisPositionForNGPositionedChild(const LayoutBox& child, - LayoutBox* parent) { - const LayoutUnit available_space = - FlexLayoutAlgorithm::IsHorizontalFlow(parent->StyleRef()) - ? parent->ContentWidth() - child.Size().Width() - : parent->ContentHeight() - child.Size().Height(); - return MainAxisStaticPositionCommon(child, parent, available_space); -} - -LayoutUnit CrossAxisStaticPositionCommon(const LayoutBox& child, - LayoutBox* parent, - LayoutUnit available_space) { - return FlexItem::AlignmentOffset( - available_space, - FlexLayoutAlgorithm::AlignmentForChild(parent->StyleRef(), - child.StyleRef()), - LayoutUnit(), parent->StyleRef().FlexWrap() == EFlexWrap::kWrapReverse, - parent->StyleRef().IsDeprecatedWebkitBox()); -} - -LayoutUnit StaticCrossAxisPositionForNGPositionedChild(const LayoutBox& child, - LayoutBox* parent) { - const LayoutUnit available_space = - FlexLayoutAlgorithm::IsHorizontalFlow(parent->StyleRef()) - ? parent->ContentHeight() - child.Size().Height() - : parent->ContentWidth() - child.Size().Width(); - return CrossAxisStaticPositionCommon(child, parent, available_space); -} - -LayoutUnit StaticInlinePositionForNGPositionedChild(const LayoutBox& child, - LayoutBlock* parent) { - const LayoutUnit start_offset = parent->StartOffsetForContent(); - if (parent->StyleRef().IsDeprecatedWebkitBox()) - return start_offset; - return start_offset + - (parent->StyleRef().ResolvedIsColumnFlexDirection() - ? StaticCrossAxisPositionForNGPositionedChild(child, parent) - : StaticMainAxisPositionForNGPositionedChild(child, parent)); -} - -LayoutUnit StaticBlockPositionForNGPositionedChild(const LayoutBox& child, - LayoutBlock* parent) { - return parent->BorderAndPaddingBefore() + - (parent->StyleRef().ResolvedIsColumnFlexDirection() - ? StaticMainAxisPositionForNGPositionedChild(child, parent) - : StaticCrossAxisPositionForNGPositionedChild(child, parent)); -} - -} // namespace - -bool LayoutFlexibleBox::SetStaticPositionForChildInFlexNGContainer( - LayoutBox& child, - LayoutBlock* parent) { - const ComputedStyle& style = parent->StyleRef(); - bool position_changed = false; - PaintLayer* child_layer = child.Layer(); - if (child.StyleRef().HasStaticInlinePosition( - style.IsHorizontalWritingMode())) { - LayoutUnit inline_position = - StaticInlinePositionForNGPositionedChild(child, parent); - if (child_layer->StaticInlinePosition() != inline_position) { - child_layer->SetStaticInlinePosition(inline_position); - position_changed = true; - } - } - if (child.StyleRef().HasStaticBlockPosition( - style.IsHorizontalWritingMode())) { - LayoutUnit block_position = - StaticBlockPositionForNGPositionedChild(child, parent); - if (child_layer->StaticBlockPosition() != block_position) { - child_layer->SetStaticBlockPosition(block_position); - position_changed = true; - } - } - return position_changed; -} - -LayoutUnit LayoutFlexibleBox::StaticMainAxisPositionForPositionedChild( - const LayoutBox& child) { - NOT_DESTROYED(); - const LayoutUnit available_space = - MainAxisContentExtent(ContentLogicalHeight()) - - MainAxisExtentForChild(child); - - return MainAxisStaticPositionCommon(child, this, available_space); -} - -LayoutUnit LayoutFlexibleBox::StaticCrossAxisPositionForPositionedChild( - const LayoutBox& child) { - NOT_DESTROYED(); - LayoutUnit available_space = - CrossAxisContentExtent() - CrossAxisExtentForChild(child); - return CrossAxisStaticPositionCommon(child, this, available_space); -} - -LayoutUnit LayoutFlexibleBox::StaticInlinePositionForPositionedChild( - const LayoutBox& child) { - NOT_DESTROYED(); - const LayoutUnit start_offset = StartOffsetForContent(); - if (StyleRef().IsDeprecatedWebkitBox()) - return start_offset; - return start_offset + (IsColumnFlow() - ? StaticCrossAxisPositionForPositionedChild(child) - : StaticMainAxisPositionForPositionedChild(child)); -} - -LayoutUnit LayoutFlexibleBox::StaticBlockPositionForPositionedChild( - const LayoutBox& child) { - NOT_DESTROYED(); - return BorderAndPaddingBefore() + - (IsColumnFlow() ? StaticMainAxisPositionForPositionedChild(child) - : StaticCrossAxisPositionForPositionedChild(child)); -} - -bool LayoutFlexibleBox::SetStaticPositionForPositionedLayout(LayoutBox& child) { - NOT_DESTROYED(); - bool position_changed = false; - PaintLayer* child_layer = child.Layer(); - if (child.StyleRef().HasStaticInlinePosition( - StyleRef().IsHorizontalWritingMode())) { - LayoutUnit inline_position = StaticInlinePositionForPositionedChild(child); - if (child_layer->StaticInlinePosition() != inline_position) { - child_layer->SetStaticInlinePosition(inline_position); - position_changed = true; - } - } - if (child.StyleRef().HasStaticBlockPosition( - StyleRef().IsHorizontalWritingMode())) { - LayoutUnit block_position = StaticBlockPositionForPositionedChild(child); - if (child_layer->StaticBlockPosition() != block_position) { - child_layer->SetStaticBlockPosition(block_position); - position_changed = true; - } - } - return position_changed; -} - -void LayoutFlexibleBox::PrepareChildForPositionedLayout(LayoutBox& child) { - NOT_DESTROYED(); - DCHECK(child.IsOutOfFlowPositioned()); - child.ContainingBlock()->InsertPositionedObject(&child); - PaintLayer* child_layer = child.Layer(); - LayoutUnit static_inline_position = FlowAwareContentInsetStart(); - if (child_layer->StaticInlinePosition() != static_inline_position) { - child_layer->SetStaticInlinePosition(static_inline_position); - if (child.StyleRef().HasStaticInlinePosition( - StyleRef().IsHorizontalWritingMode())) - child.SetChildNeedsLayout(kMarkOnlyThis); - } - - LayoutUnit static_block_position = FlowAwareContentInsetBefore(); - if (child_layer->StaticBlockPosition() != static_block_position) { - child_layer->SetStaticBlockPosition(static_block_position); - if (child.StyleRef().HasStaticBlockPosition( - StyleRef().IsHorizontalWritingMode())) - child.SetChildNeedsLayout(kMarkOnlyThis); - } -} - -void LayoutFlexibleBox::ResetAutoMarginsAndLogicalTopInCrossAxis( - LayoutBox& child) { - NOT_DESTROYED(); - if (HasAutoMarginsInCrossAxis(child)) { - child.UpdateLogicalHeight(); - if (IsHorizontalFlow()) { - if (child.StyleRef().MarginTop().IsAuto()) - child.SetMarginTop(LayoutUnit()); - if (child.StyleRef().MarginBottom().IsAuto()) - child.SetMarginBottom(LayoutUnit()); - } else { - if (child.StyleRef().MarginLeft().IsAuto()) - child.SetMarginLeft(LayoutUnit()); - if (child.StyleRef().MarginRight().IsAuto()) - child.SetMarginRight(LayoutUnit()); - } - } -} - -bool LayoutFlexibleBox::NeedToStretchChildLogicalHeight( - const LayoutBox& child) const { - NOT_DESTROYED(); - // This function is a little bit magical. It relies on the fact that blocks - // intrinsically "stretch" themselves in their inline axis, i.e. a <div> has - // an implicit width: 100%. So the child will automatically stretch if our - // cross axis is the child's inline axis. That's the case if: - // - We are horizontal and the child is in vertical writing mode - // - We are vertical and the child is in horizontal writing mode - // Otherwise, we need to stretch if the cross axis size is auto. - if (FlexLayoutAlgorithm::AlignmentForChild(StyleRef(), child.StyleRef()) != - ItemPosition::kStretch) - return false; - - if (IsHorizontalFlow() != child.StyleRef().IsHorizontalWritingMode()) - return false; - - return child.StyleRef().LogicalHeight().IsAuto(); -} - -bool LayoutFlexibleBox::ChildHasIntrinsicMainAxisSize( - const FlexLayoutAlgorithm& algorithm, - const LayoutBox& child) const { - NOT_DESTROYED(); - bool result = false; - if (!MainAxisIsInlineAxis(child) && !child.ShouldApplySizeContainment()) { - Length child_flex_basis = FlexBasisForChild(child); - const Length& child_min_size = IsHorizontalFlow() - ? child.StyleRef().MinWidth() - : child.StyleRef().MinHeight(); - const Length& child_max_size = IsHorizontalFlow() - ? child.StyleRef().MaxWidth() - : child.StyleRef().MaxHeight(); - if (!MainAxisLengthIsDefinite(child, child_flex_basis) || - child_min_size.IsContentOrIntrinsic() || - child_max_size.IsContentOrIntrinsic()) { - result = true; - } else if (algorithm.ShouldApplyMinSizeAutoForChild(child)) { - result = true; - } - } - return result; -} - -EOverflow LayoutFlexibleBox::CrossAxisOverflowForChild( - const LayoutBox& child) const { - NOT_DESTROYED(); - if (IsHorizontalFlow()) - return child.StyleRef().OverflowY(); - return child.StyleRef().OverflowX(); -} - -DISABLE_CFI_PERF -void LayoutFlexibleBox::LayoutLineItems(FlexLine* current_line, - bool relayout_children, - SubtreeLayoutScope& layout_scope, - FlexOffset** current_item_offset) { - NOT_DESTROYED(); - for (wtf_size_t i = 0; i < current_line->line_items_.size(); ++i) { - FlexItem& flex_item = current_line->line_items_[i]; - LayoutBox* child = flex_item.box_; - - DCHECK(current_item_offset); - flex_item.offset_ = *current_item_offset; - (*current_item_offset)++; - - DCHECK(!flex_item.box_->IsOutOfFlowPositioned()); - - child->SetShouldCheckForPaintInvalidation(); - - SetOverrideMainAxisContentSizeForChild(flex_item); - // The flexed content size and the override size include the scrollbar - // width, so we need to compare to the size including the scrollbar. - if (flex_item.flexed_content_size_ != - MainAxisContentExtentForChildIncludingScrollbar(*child)) { - child->SetSelfNeedsLayoutForAvailableSpace(true); - } else { - // To avoid double applying margin changes in - // updateAutoMarginsInCrossAxis, we reset the margins here. - ResetAutoMarginsAndLogicalTopInCrossAxis(*child); - } - // We may have already forced relayout for orthogonal flowing children in - // computeInnerFlexBaseSizeForChild. - bool force_child_relayout = - relayout_children && !relaid_out_children_.Contains(child); - // TODO(dgrogan): Broaden the NG part of this check once NG types other - // than Mixin derivatives are cached. - auto* child_layout_block = DynamicTo<LayoutBlock>(child); - if (child_layout_block && - child_layout_block->HasPercentHeightDescendants() && - !CanAvoidLayoutForNGChild(*child)) { - // Have to force another relayout even though the child is sized - // correctly, because its descendants are not sized correctly yet. Our - // previous layout of the child was done without an override height set. - // So, redo it here. - force_child_relayout = true; - } - UpdateBlockChildDirtyBitsBeforeLayout(force_child_relayout, *child); - if (!child->NeedsLayout()) - MarkChildForPaginationRelayoutIfNeeded(*child, layout_scope); - if (child->NeedsLayout()) { - relaid_out_children_.insert(child); - // It is very important that we only clear the cross axis override size - // if we are in fact going to lay out the child. Otherwise, the cross - // axis size and the actual laid out size get out of sync, which will - // cause problems if we later lay out the child in simplified layout, - // which does not go through regular flex layout and therefore would - // not reset the cross axis size. - if (MainAxisIsInlineAxis(*child)) - child->ClearOverrideLogicalHeight(); - else - child->ClearOverrideLogicalWidth(); - } - child->LayoutIfNeeded(); - - // This shouldn't be necessary, because we set the override size to be - // the flexed_content_size and so the result should in fact be that size. - // But it turns out that tables ignore the override size, and so we have - // to re-check the size so that we place the flex item correctly. - flex_item.flexed_content_size_ = - MainAxisExtentForChild(*child) - flex_item.main_axis_border_padding_; - flex_item.cross_axis_size_ = CrossAxisUnstretchedExtentForChild(*child); - } -} - -void LayoutFlexibleBox::ApplyLineItemsPosition(FlexLine* current_line) { - NOT_DESTROYED(); - bool is_paginated = View()->GetLayoutState()->IsPaginated(); - for (wtf_size_t i = 0; i < current_line->line_items_.size(); ++i) { - const FlexItem& flex_item = current_line->line_items_[i]; - LayoutBox* child = flex_item.box_; - SetFlowAwareLocationForChild(*child, *flex_item.offset_); - child->SetMargin(flex_item.physical_margins_); - - if (is_paginated) - UpdateFragmentationInfoForChild(*child); - } - - if (IsColumnFlow()) { - SetLogicalHeight(std::max(LogicalHeight(), current_line->main_axis_extent_ + - FlowAwareContentInsetEnd())); - } else { - SetLogicalHeight( - std::max(LogicalHeight(), current_line->cross_axis_offset_ + - FlowAwareContentInsetAfter() + - current_line->cross_axis_extent_)); - } - - if (StyleRef().ResolvedIsColumnReverseFlexDirection()) { - // We have to do an extra pass for column-reverse to reposition the flex - // items since the start depends on the height of the flexbox, which we - // only know after we've positioned all the flex items. - UpdateLogicalHeight(); - LayoutColumnReverse(current_line->line_items_, - current_line->cross_axis_offset_, - current_line->remaining_free_space_); - } -} - -void LayoutFlexibleBox::LayoutColumnReverse(FlexItemVectorView& children, - LayoutUnit cross_axis_offset, - LayoutUnit available_free_space) { - NOT_DESTROYED(); - const StyleContentAlignmentData justify_content = - FlexLayoutAlgorithm::ResolvedJustifyContent(StyleRef()); - - // This is similar to the logic in FlexLine::ComputeLineItemsPosition, except - // we place the children starting from the end of the flexbox. - LayoutUnit main_axis_offset = LogicalHeight() - FlowAwareContentInsetEnd(); - main_axis_offset -= FlexLayoutAlgorithm::InitialContentPositionOffset( - StyleRef(), available_free_space, justify_content, children.size()); - - for (wtf_size_t i = 0; i < children.size(); ++i) { - FlexItem& flex_item = children[i]; - LayoutBox* child = flex_item.box_; - - DCHECK(!child->IsOutOfFlowPositioned()); - - main_axis_offset -= - MainAxisExtentForChild(*child) + flex_item.FlowAwareMarginEnd(); - - SetFlowAwareLocationForChild( - *child, - FlexOffset(main_axis_offset, - cross_axis_offset + flex_item.FlowAwareMarginBefore())); - - main_axis_offset -= flex_item.FlowAwareMarginStart(); - - main_axis_offset -= - FlexLayoutAlgorithm::ContentDistributionSpaceBetweenChildren( - available_free_space, justify_content, children.size()); - } -} - -void LayoutFlexibleBox::AlignFlexLines(FlexLayoutAlgorithm& algorithm) { - NOT_DESTROYED(); - Vector<FlexLine>& line_contexts = algorithm.FlexLines(); - const StyleContentAlignmentData align_content = - FlexLayoutAlgorithm::ResolvedAlignContent(StyleRef()); - if (align_content.GetPosition() == ContentPosition::kFlexStart && - algorithm.gap_between_lines_ == 0) { - return; - } - - if (IsMultiline() && !line_contexts.empty()) { - UseCounter::Count(GetDocument(), - WebFeature::kFlexboxSingleLineAlignContent); - } - - algorithm.AlignFlexLines(CrossAxisContentExtent()); - for (unsigned line_number = 0; line_number < line_contexts.size(); - ++line_number) { - FlexLine& line_context = line_contexts[line_number]; - for (FlexItem& flex_item : line_context.line_items_) { - ResetAlignmentForChild(*flex_item.box_, - flex_item.offset_->cross_axis_offset); - } - } -} - -void LayoutFlexibleBox::ResetAlignmentForChild( - LayoutBox& child, - LayoutUnit new_cross_axis_position) { - NOT_DESTROYED(); - SetFlowAwareLocationForChild( - child, {FlowAwareLocationForChild(child).main_axis_offset, - new_cross_axis_position}); -} - -void LayoutFlexibleBox::AlignChildren(FlexLayoutAlgorithm& algorithm) { - NOT_DESTROYED(); - Vector<FlexLine>& line_contexts = algorithm.FlexLines(); - - algorithm.AlignChildren(); - for (unsigned line_number = 0; line_number < line_contexts.size(); - ++line_number) { - FlexLine& line_context = line_contexts[line_number]; - for (FlexItem& flex_item : line_context.line_items_) { - if (flex_item.needs_relayout_for_stretch_) { - DCHECK(flex_item.Alignment() == ItemPosition::kStretch); - ApplyStretchAlignmentToChild(flex_item); - flex_item.needs_relayout_for_stretch_ = false; - } - ResetAlignmentForChild(*flex_item.box_, - flex_item.offset_->cross_axis_offset); - flex_item.box_->SetMargin(flex_item.physical_margins_); - } - } -} - -void LayoutFlexibleBox::ApplyStretchAlignmentToChild(FlexItem& flex_item) { - NOT_DESTROYED(); - LayoutBox& child = *flex_item.box_; - if (flex_item.MainAxisIsInlineAxis() && - child.StyleRef().LogicalHeight().IsAuto()) { - // FIXME: Can avoid laying out here in some cases. See - // https://webkit.org/b/87905. - bool child_needs_relayout = - flex_item.cross_axis_size_ != child.LogicalHeight(); - child.SetOverrideLogicalHeight(flex_item.cross_axis_size_); - - auto* child_block = DynamicTo<LayoutBlock>(child); - if (child_block && child_block->HasPercentHeightDescendants() && - !CanAvoidLayoutForNGChild(child)) { - // Have to force another relayout even though the child is sized - // correctly, because its descendants are not sized correctly yet. Our - // previous layout of the child was done without an override height set. - // So, redo it here. - child_needs_relayout |= relaid_out_children_.Contains(&child); - } - if (child_needs_relayout) - child.ForceLayout(); - } else if (!flex_item.MainAxisIsInlineAxis() && - child.StyleRef().LogicalWidth().IsAuto()) { - if (flex_item.cross_axis_size_ != child.LogicalWidth()) { - child.SetOverrideLogicalWidth(flex_item.cross_axis_size_); - child.ForceLayout(); - } - } -} - -void LayoutFlexibleBox::FlipForRightToLeftColumn( - const Vector<FlexLine>& line_contexts) { - NOT_DESTROYED(); - if (StyleRef().IsLeftToRightDirection() || !IsColumnFlow()) - return; - - LayoutUnit cross_extent = CrossAxisExtent(); - for (const FlexLine& line_context : line_contexts) { - for (const FlexItem& flex_item : line_context.line_items_) { - DCHECK(!flex_item.box_->IsOutOfFlowPositioned()); - - FlexOffset offset = FlowAwareLocationForChild(*flex_item.box_); - // For vertical flows, setFlowAwareLocationForChild will transpose x and - // y, so using the y axis for a column cross axis extent is correct. - offset.cross_axis_offset = - cross_extent - flex_item.cross_axis_size_ - offset.cross_axis_offset; - SetFlowAwareLocationForChild(*flex_item.box_, offset); - } - } -} - -} // namespace blink
diff --git a/third_party/blink/renderer/core/layout/layout_flexible_box.h b/third_party/blink/renderer/core/layout/layout_flexible_box.h deleted file mode 100644 index aab2fde..0000000 --- a/third_party/blink/renderer/core/layout/layout_flexible_box.h +++ /dev/null
@@ -1,270 +0,0 @@ -/* - * Copyright (C) 2011 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LAYOUT_FLEXIBLE_BOX_H_ -#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LAYOUT_FLEXIBLE_BOX_H_ - -#include "third_party/blink/renderer/core/core_export.h" -#include "third_party/blink/renderer/core/layout/geometry/flex_offset.h" -#include "third_party/blink/renderer/core/layout/layout_block.h" -#include "third_party/blink/renderer/core/layout/order_iterator.h" -#include "third_party/blink/renderer/platform/heap/collection_support/heap_hash_map.h" -#include "third_party/blink/renderer/platform/heap/collection_support/heap_hash_set.h" - -namespace blink { - -class FlexItem; -class FlexItemVectorView; -class FlexLayoutAlgorithm; -class FlexLine; -struct MinMaxSizes; - -class CORE_EXPORT LayoutFlexibleBox : public LayoutBlock { - public: - explicit LayoutFlexibleBox(Element*); - ~LayoutFlexibleBox() override; - void Trace(Visitor*) const override; - - const char* GetName() const override { - NOT_DESTROYED(); - return "LayoutFlexibleBox"; - } - - bool IsFlexibleBox() const final { - NOT_DESTROYED(); - return true; - } - bool IsFlexibleBoxIncludingNG() const final { - NOT_DESTROYED(); - return true; - } - void UpdateBlockLayout(bool relayout_children) final; - - bool IsChildAllowed(LayoutObject* object, - const ComputedStyle& style) const override; - LayoutUnit BaselinePosition( - FontBaseline, - bool first_line, - LineDirectionMode, - LinePositionMode = kPositionOnContainingLine) const override; - - static LayoutUnit SynthesizedBaselineFromBorderBox(const LayoutBox&, - LineDirectionMode); - - LayoutUnit FirstLineBoxBaseline() const override; - LayoutUnit InlineBlockBaseline(LineDirectionMode) const override; - bool HasTopOverflow() const override; - bool HasLeftOverflow() const override; - - void PaintChildren(const PaintInfo&, - const PhysicalOffset& paint_offset) const final; - - bool IsHorizontalFlow() const; - - const OrderIterator& GetOrderIterator() const { - NOT_DESTROYED(); - return order_iterator_; - } - - // These three functions are used when resolving percentages against a - // flex item's logical height. In flexbox, sometimes a logical height - // should be considered definite even though it normally shouldn't be, - // and these functions implement that logic. - bool CrossSizeIsDefiniteForPercentageResolution(const LayoutBox& child) const; - bool MainSizeIsDefiniteForPercentageResolution(const LayoutBox& child) const; - bool UseOverrideLogicalHeightForPerentageResolution( - const LayoutBox& child) const; - - void ClearCachedMainSizeForChild(const LayoutBox& child); - - LayoutUnit StaticMainAxisPositionForPositionedChild(const LayoutBox& child); - LayoutUnit StaticCrossAxisPositionForPositionedChild(const LayoutBox& child); - - LayoutUnit StaticInlinePositionForPositionedChild(const LayoutBox& child); - LayoutUnit StaticBlockPositionForPositionedChild(const LayoutBox& child); - - // Returns true if the position changed. In that case, the child will have to - // be laid out again. - bool SetStaticPositionForPositionedLayout(LayoutBox& child); - static bool SetStaticPositionForChildInFlexNGContainer(LayoutBox& child, - LayoutBlock* parent); - LayoutUnit CrossAxisContentExtent() const; - - protected: - MinMaxSizes ComputeIntrinsicLogicalWidths() const override; - - bool HitTestChildren(HitTestResult&, - const HitTestLocation&, - const PhysicalOffset& accumulated_offset, - HitTestPhase) override; - - void StyleDidChange(StyleDifference, const ComputedStyle* old_style) override; - void RemoveChild(LayoutObject*) override; - - private: - enum ChildLayoutType { kLayoutIfNeeded, kForceLayout, kNeverLayout }; - - enum class SizeDefiniteness { kDefinite, kIndefinite, kUnknown }; - - bool MainAxisIsInlineAxis(const LayoutBox& child) const; - bool IsColumnFlow() const; - bool IsLeftToRightFlow() const; - bool IsMultiline() const; - Length FlexBasisForChild(const LayoutBox& child) const; - LayoutUnit CrossAxisExtentForChild(const LayoutBox& child) const; - LayoutUnit CrossAxisUnstretchedExtentForChild(const LayoutBox& child) const; - LayoutUnit ChildUnstretchedLogicalHeight(const LayoutBox& child) const; - LayoutUnit ChildUnstretchedLogicalWidth(const LayoutBox& child) const; - LayoutUnit MainAxisExtentForChild(const LayoutBox& child) const; - LayoutUnit MainAxisContentExtentForChild(const LayoutBox& child) const; - LayoutUnit MainAxisContentExtentForChildIncludingScrollbar( - const LayoutBox& child) const; - LayoutUnit CrossAxisExtent() const; - LayoutUnit MainAxisContentExtent(LayoutUnit content_logical_height); - LayoutUnit ComputeMainAxisExtentForChild(const LayoutBox& child, - SizeType, - const Length& size, - LayoutUnit border_and_padding) const; - - LayoutUnit ContentInsetBottom() const; - LayoutUnit ContentInsetRight() const; - LayoutUnit FlowAwareContentInsetStart() const; - LayoutUnit FlowAwareContentInsetEnd() const; - LayoutUnit FlowAwareContentInsetBefore() const; - LayoutUnit FlowAwareContentInsetAfter() const; - - LayoutUnit CrossAxisScrollbarExtent() const; - LayoutUnit CrossAxisScrollbarExtentForChild(const LayoutBox& child) const; - FlexOffset FlowAwareLocationForChild(const LayoutBox& child) const; - bool UseChildAspectRatio(const LayoutBox& child) const; - LayoutUnit ComputeMainSizeFromAspectRatioUsing( - const LayoutBox& child, - const Length& cross_size_length, - LayoutUnit main_axis_border_and_padding, - LayoutUnit cross_axis_border_and_padding) const; - void SetFlowAwareLocationForChild(LayoutBox& child, const FlexOffset&); - LayoutUnit ComputeInnerFlexBaseSizeForChild( - LayoutBox& child, - LayoutUnit main_axis_border_and_padding, - LayoutUnit cross_axis_border_and_padding, - ChildLayoutType = kLayoutIfNeeded); - void ResetAlignmentForChild(LayoutBox& child, LayoutUnit); - bool MainAxisLengthIsDefinite(const LayoutBox& child, - const Length& flex_basis, - bool add_to_cb = true) const; - bool CrossAxisLengthIsDefinite(const LayoutBox& child, - const Length& flex_basis) const; - bool NeedToStretchChildLogicalHeight(const LayoutBox& child) const; - bool ChildHasIntrinsicMainAxisSize(const FlexLayoutAlgorithm&, - const LayoutBox& child) const; - EOverflow MainAxisOverflowForChild(const LayoutBox& child) const; - EOverflow CrossAxisOverflowForChild(const LayoutBox& child) const; - void CacheChildMainSize(const LayoutBox& child); - bool CanAvoidLayoutForNGChild(const LayoutBox& child) const; - - void LayoutFlexItems(bool relayout_children, SubtreeLayoutScope&); - bool HasAutoMarginsInCrossAxis(const LayoutBox& child) const; - void RepositionLogicalHeightDependentFlexItems( - FlexLayoutAlgorithm& algorithm); - LayoutUnit ClientLogicalBottomAfterRepositioning(); - - LayoutUnit ComputeChildMarginValue(const Length& margin); - void PrepareOrderIteratorAndMargins(); - MinMaxSizes ComputeMinAndMaxSizesForChild( - const FlexLayoutAlgorithm& algorithm, - const LayoutBox& child, - LayoutUnit border_and_padding, - LayoutUnit cross_axis_border_and_padding) const; - LayoutUnit AdjustChildSizeForAspectRatioCrossAxisMinAndMax( - const LayoutBox& child, - LayoutUnit child_size, - LayoutUnit main_axis_border_and_padding, - LayoutUnit cross_axis_border_and_padding) const; - void ConstructAndAppendFlexItem(FlexLayoutAlgorithm* algorithm, - LayoutBox& child, - ChildLayoutType); - - bool ResolveFlexibleLengths(FlexLine*, - LayoutUnit initial_free_space, - LayoutUnit& remaining_free_space); - - void ResetAutoMarginsAndLogicalTopInCrossAxis(LayoutBox& child); - void SetOverrideMainAxisContentSizeForChild(FlexItem&); - void PrepareChildForPositionedLayout(LayoutBox& child); - void LayoutLineItems(FlexLine*, - bool relayout_children, - SubtreeLayoutScope&, - FlexOffset** current_item_offset); - void ApplyLineItemsPosition(FlexLine*); - void LayoutColumnReverse(FlexItemVectorView&, - LayoutUnit cross_axis_offset, - LayoutUnit available_free_space); - void AlignFlexLines(FlexLayoutAlgorithm&); - void AlignChildren(FlexLayoutAlgorithm&); - void ApplyStretchAlignmentToChild(FlexItem& child); - void FlipForRightToLeftColumn(const Vector<FlexLine>& line_contexts); - - float CountIntrinsicSizeForAlgorithmChange( - LayoutUnit max_preferred_width, - LayoutBox* child, - float previous_max_content_flex_fraction) const; - - void MergeAnonymousFlexItems(LayoutObject* remove_child); - - // This is used to cache the preferred size for orthogonal flow children so we - // don't have to relayout to get it - HeapHashMap<Member<const LayoutObject>, LayoutUnit> - intrinsic_size_along_main_axis_; - - // This set is used to keep track of which children we laid out in this - // current layout iteration. We need it because the ones in this set may - // need an additional layout pass for correct stretch alignment handling, as - // the first layout likely did not use the correct value for percentage - // sizing of children. - HeapHashSet<Member<const LayoutObject>> relaid_out_children_; - - mutable OrderIterator order_iterator_; - int number_of_in_flow_children_on_first_line_; - - // This is SizeIsUnknown outside of layoutBlock() - mutable SizeDefiniteness has_definite_height_; - bool in_layout_; -}; - -template <> -struct DowncastTraits<LayoutFlexibleBox> { - static bool AllowFrom(const LayoutObject& object) { - return object.IsFlexibleBox(); - } -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LAYOUT_FLEXIBLE_BOX_H_
diff --git a/third_party/blink/renderer/core/layout/layout_flexible_box_test.cc b/third_party/blink/renderer/core/layout/layout_flexible_box_test.cc index f3877a8..46cdfcf 100644 --- a/third_party/blink/renderer/core/layout/layout_flexible_box_test.cc +++ b/third_party/blink/renderer/core/layout/layout_flexible_box_test.cc
@@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "third_party/blink/renderer/core/layout/layout_flexible_box.h" - #include "third_party/blink/renderer/core/paint/paint_layer.h" #include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h" #include "third_party/blink/renderer/core/testing/core_unit_test_helper.h"
diff --git a/third_party/blink/renderer/core/layout/layout_object.cc b/third_party/blink/renderer/core/layout/layout_object.cc index ded7e8e9..5311454 100644 --- a/third_party/blink/renderer/core/layout/layout_object.cc +++ b/third_party/blink/renderer/core/layout/layout_object.cc
@@ -76,7 +76,6 @@ #include "third_party/blink/renderer/core/layout/layout_custom_scrollbar_part.h" #include "third_party/blink/renderer/core/layout/layout_embedded_content.h" #include "third_party/blink/renderer/core/layout/layout_fieldset.h" -#include "third_party/blink/renderer/core/layout/layout_flexible_box.h" #include "third_party/blink/renderer/core/layout/layout_flow_thread.h" #include "third_party/blink/renderer/core/layout/layout_image.h" #include "third_party/blink/renderer/core/layout/layout_image_resource_style_image.h" @@ -92,6 +91,7 @@ #include "third_party/blink/renderer/core/layout/layout_text_fragment.h" #include "third_party/blink/renderer/core/layout/layout_theme.h" #include "third_party/blink/renderer/core/layout/layout_view.h" +#include "third_party/blink/renderer/core/layout/ng/flex/layout_ng_flexible_box.h" #include "third_party/blink/renderer/core/layout/ng/inline/layout_ng_text_combine.h" #include "third_party/blink/renderer/core/layout/ng/layout_ng_block_flow.h" #include "third_party/blink/renderer/core/layout/ng/list/layout_ng_list_item.h" @@ -393,11 +393,11 @@ } UseCounter::Count(element->GetDocument(), WebFeature::kWebkitBoxWithoutWebkitLineClamp); - return LayoutObjectFactory::CreateFlexibleBox(*element, style, legacy); + return MakeGarbageCollected<LayoutNGFlexibleBox>(element); case EDisplay::kFlex: case EDisplay::kInlineFlex: UseCounter::Count(element->GetDocument(), WebFeature::kCSSFlexibleBox); - return LayoutObjectFactory::CreateFlexibleBox(*element, style, legacy); + return MakeGarbageCollected<LayoutNGFlexibleBox>(element); case EDisplay::kGrid: case EDisplay::kInlineGrid: UseCounter::Count(element->GetDocument(), WebFeature::kCSSGridLayout);
diff --git a/third_party/blink/renderer/core/layout/layout_object.h b/third_party/blink/renderer/core/layout/layout_object.h index cb171b0da..6173eb1 100644 --- a/third_party/blink/renderer/core/layout/layout_object.h +++ b/third_party/blink/renderer/core/layout/layout_object.h
@@ -2963,13 +2963,7 @@ void Destroy(); - // Virtual function helper for the new FlexibleBox Layout (display: - // -webkit-flex). - virtual bool IsFlexibleBox() const { - NOT_DESTROYED(); - return false; - } - + // TODO(1229581): Rename this function. virtual bool IsFlexibleBoxIncludingNG() const { NOT_DESTROYED(); return false;
diff --git a/third_party/blink/renderer/core/layout/layout_object_factory.cc b/third_party/blink/renderer/core/layout/layout_object_factory.cc index 1a2f25a7..439d10fc 100644 --- a/third_party/blink/renderer/core/layout/layout_object_factory.cc +++ b/third_party/blink/renderer/core/layout/layout_object_factory.cc
@@ -12,7 +12,6 @@ #include "third_party/blink/renderer/core/layout/layout_block_flow.h" #include "third_party/blink/renderer/core/layout/layout_counter.h" #include "third_party/blink/renderer/core/layout/layout_fieldset.h" -#include "third_party/blink/renderer/core/layout/layout_flexible_box.h" #include "third_party/blink/renderer/core/layout/layout_frame_set.h" #include "third_party/blink/renderer/core/layout/layout_inside_list_marker.h" #include "third_party/blink/renderer/core/layout/layout_list_item.h" @@ -132,13 +131,6 @@ return MakeGarbageCollected<LayoutNGView>(&document); } -LayoutBlock* LayoutObjectFactory::CreateFlexibleBox(Node& node, - const ComputedStyle& style, - LegacyLayout legacy) { - return CreateObject<LayoutBlock, LayoutNGFlexibleBox, LayoutFlexibleBox>( - node, legacy); -} - LayoutBlock* LayoutObjectFactory::CreateMath(Node& node, const ComputedStyle& style, LegacyLayout legacy) {
diff --git a/third_party/blink/renderer/core/layout/layout_object_factory.h b/third_party/blink/renderer/core/layout/layout_object_factory.h index 7a1b2cd6..ab40696 100644 --- a/third_party/blink/renderer/core/layout/layout_object_factory.h +++ b/third_party/blink/renderer/core/layout/layout_object_factory.h
@@ -46,9 +46,6 @@ const ComputedStyle&, LegacyLayout); static LayoutView* CreateView(Document&, const ComputedStyle&); - static LayoutBlock* CreateFlexibleBox(Node&, - const ComputedStyle&, - LegacyLayout); static LayoutBlock* CreateMath(Node&, const ComputedStyle&, LegacyLayout); static LayoutBlock* CreateCustom(Node&, const ComputedStyle&, LegacyLayout); static LayoutObject* CreateListMarker(Node&,
diff --git a/third_party/blink/renderer/core/layout/layout_text_control.h b/third_party/blink/renderer/core/layout/layout_text_control.h index 8ee25bc..e3e3734 100644 --- a/third_party/blink/renderer/core/layout/layout_text_control.h +++ b/third_party/blink/renderer/core/layout/layout_text_control.h
@@ -25,7 +25,6 @@ #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/layout/layout_block_flow.h" -#include "third_party/blink/renderer/core/layout/layout_flexible_box.h" namespace blink {
diff --git a/third_party/blink/renderer/core/layout/ng/flex/ng_flex_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/flex/ng_flex_layout_algorithm.cc index 40f833a..455c54e 100644 --- a/third_party/blink/renderer/core/layout/ng/flex/ng_flex_layout_algorithm.cc +++ b/third_party/blink/renderer/core/layout/ng/flex/ng_flex_layout_algorithm.cc
@@ -10,7 +10,6 @@ #include "third_party/blink/renderer/core/layout/flexible_box_algorithm.h" #include "third_party/blink/renderer/core/layout/geometry/logical_size.h" #include "third_party/blink/renderer/core/layout/layout_box.h" -#include "third_party/blink/renderer/core/layout/layout_flexible_box.h" #include "third_party/blink/renderer/core/layout/ng/flex/layout_ng_flexible_box.h" #include "third_party/blink/renderer/core/layout/ng/flex/ng_flex_child_iterator.h" #include "third_party/blink/renderer/core/layout/ng/flex/ng_flex_data.h" @@ -993,7 +992,7 @@ /* is_parallel_context */ !is_column_, is_last_baseline, /* is_flipped */ is_wrap_reverse); algorithm_ - .emplace_back(nullptr, child.Style(), flex_base_content_size, + .emplace_back(child.Style(), flex_base_content_size, min_max_sizes_in_main_axis_direction, min_max_sizes_in_cross_axis_direction, main_axis_border_padding, cross_axis_border_padding,
diff --git a/third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm.cc index 2eacc798..a1c3d6e5 100644 --- a/third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm.cc +++ b/third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm.cc
@@ -1433,8 +1433,7 @@ return 0; } - const wtf_size_t tracks_per_repeat = - track_list.RepeaterCount() * track_list.AutoRepeatTrackCount(); + const wtf_size_t tracks_per_repeat = track_list.AutoRepeatTrackCount(); if (tracks_per_repeat > subgrid_span_size) { // No room left for auto repetitions because each repetition is too large. return 0;
diff --git a/third_party/blink/renderer/core/layout/ng/grid/ng_grid_line_resolver.cc b/third_party/blink/renderer/core/layout/ng/grid/ng_grid_line_resolver.cc index 91aa9f1..366714ea 100644 --- a/third_party/blink/renderer/core/layout/ng/grid/ng_grid_line_resolver.cc +++ b/third_party/blink/renderer/core/layout/ng/grid/ng_grid_line_resolver.cc
@@ -122,7 +122,7 @@ // merging. These are positive and relative to index 0, so we only need to // clamp values above `subgrid_span_size`. for (const auto& pair : subgrid_map) { - WTF::Vector<wtf_size_t> clamped_list; + Vector<wtf_size_t> clamped_list; for (const auto& position : pair.value) { if (position > subgrid_span_size) clamped_list.push_back(subgrid_span_size); @@ -136,7 +136,7 @@ // (`parent_map`). The map is a key-value store with keys as the implicit // line name and the value as an array of ascending indices. for (const auto& pair : parent_map) { - WTF::Vector<wtf_size_t> merged_list; + Vector<wtf_size_t> merged_list; for (const auto& position : pair.value) { auto IsGridAreaInSubgridRange = [&]() -> bool { // Returns true if a given position is within either the implicit @@ -224,8 +224,8 @@ [](NamedGridLinesMap& subgrid_map, const NamedGridLinesMap& parent_auto_repeat_map, const blink::ComputedGridTrackList& track_list, GridSpan subgrid_span, - wtf_size_t auto_repetitions, - bool is_opposite_direction_to_parent) -> void { + wtf_size_t auto_repetitions, bool is_opposite_direction_to_parent, + bool is_nested_subgrid) -> void { const wtf_size_t auto_repeat_track_count = track_list.TrackList().AutoRepeatTrackCount(); const wtf_size_t auto_repeat_total_tracks = @@ -238,24 +238,27 @@ // come after the auto repeater. This is because they were parsed without // knowledge of the number of repeats. Now that we know how many auto // repeats there are, we need to shift the existing entries by the total - // number of auto repeat tracks. + // number of auto repeat tracks. For now, skip this on nested subgrids, + // as it will double-shift non-auto repeat lines. + // TODO(kschmi): Properly shift line names after the insertion point for + // nested subgrids. This should happen in `MergeNamedGridLinesWithParent`. // TODO(kschmi): Do we also need to do this for implicit lines? const wtf_size_t insertion_point = track_list.auto_repeat_insertion_point; - const wtf_size_t last_auto_repeat_index = - insertion_point + auto_repeat_total_tracks; - for (const auto& pair : subgrid_map) { - WTF::Vector<wtf_size_t> shifted_list; - for (const auto& position : pair.value) { - if (position >= insertion_point) { - wtf_size_t expanded_position = position + last_auto_repeat_index; - // These have already been offset relative to index 0, so explicitly - // do not offset by `subgrid_span` like we do below. - if (subgrid_span.Contains(expanded_position)) { - shifted_list.push_back(expanded_position); + if (!is_nested_subgrid) { + for (const auto& pair : subgrid_map) { + Vector<wtf_size_t> shifted_list; + for (const auto& position : pair.value) { + if (position >= insertion_point) { + wtf_size_t expanded_position = position + auto_repeat_total_tracks; + // These have already been offset relative to index 0, so explicitly + // do not offset by `subgrid_span` like we do below. + if (subgrid_span.Contains(expanded_position)) { + shifted_list.push_back(expanded_position); + } } } + subgrid_map.Set(pair.key, shifted_list); } - subgrid_map.Set(pair.key, shifted_list); } // Now expand the auto repeaters into `subgrid_map`. @@ -308,12 +311,15 @@ } } }; - - // TODO(kschmi) - Account for orthogonal writing modes and swap rows/columns. const bool is_opposite_direction_to_parent = - (grid_style.Direction() != parent_line_resolver.style_->Direction()); + grid_style.Direction() != parent_line_resolver.style_->Direction(); + const bool is_parallel_to_parent = + IsParallelWritingMode(grid_style.GetWritingMode(), + parent_line_resolver.style_->GetWritingMode()); if (subgrid_area.columns.IsTranslatedDefinite()) { + const auto track_direction_in_parent = + is_parallel_to_parent ? kForColumns : kForRows; MergeNamedGridLinesWithParent( *subgridded_columns_merged_explicit_grid_line_names_, parent_line_resolver.ExplicitNamedLinesMap(kForColumns), @@ -323,29 +329,39 @@ parent_line_resolver.ImplicitNamedLinesMap(kForColumns), subgrid_area.columns); // Expand auto repeaters from the parent into the named line map. + // TODO(kschmi): Also expand the subgrid's repeaters. Otherwise, we could + // have issues with precedence. ExpandAutoRepeatTracksFromParent( *subgridded_columns_merged_explicit_grid_line_names_, - parent_line_resolver.AutoRepeatLineNamesMap(kForColumns), - parent_line_resolver.ComputedGridTrackList(kForColumns), - subgrid_area.columns, parent_line_resolver.AutoRepetitions(kForColumns), - is_opposite_direction_to_parent); + parent_line_resolver.AutoRepeatLineNamesMap(track_direction_in_parent), + parent_line_resolver.ComputedGridTrackList(track_direction_in_parent), + subgrid_area.columns, + parent_line_resolver.AutoRepetitions(track_direction_in_parent), + is_opposite_direction_to_parent, + parent_line_resolver.IsSubgridded(track_direction_in_parent)); } if (subgrid_area.rows.IsTranslatedDefinite()) { + const auto track_direction_in_parent = + is_parallel_to_parent ? kForRows : kForColumns; MergeNamedGridLinesWithParent( *subgridded_rows_merged_explicit_grid_line_names_, - parent_line_resolver.ExplicitNamedLinesMap(kForRows), subgrid_area.rows, - is_opposite_direction_to_parent); + parent_line_resolver.ExplicitNamedLinesMap(track_direction_in_parent), + subgrid_area.rows, is_opposite_direction_to_parent); MergeImplicitLinesWithParent( *subgridded_rows_merged_implicit_grid_line_names_, parent_line_resolver.ImplicitNamedLinesMap(kForRows), subgrid_area.rows); // Expand auto repeaters from the parent into the named line map. + // TODO(kschmi): Also expand the subgrid's repeaters. Otherwise, we could + // have issues with precedence. ExpandAutoRepeatTracksFromParent( *subgridded_rows_merged_explicit_grid_line_names_, - parent_line_resolver.AutoRepeatLineNamesMap(kForRows), - parent_line_resolver.ComputedGridTrackList(kForRows), subgrid_area.rows, - parent_line_resolver.AutoRepetitions(kForRows), - is_opposite_direction_to_parent); + parent_line_resolver.AutoRepeatLineNamesMap(track_direction_in_parent), + parent_line_resolver.ComputedGridTrackList(track_direction_in_parent), + subgrid_area.rows, + parent_line_resolver.AutoRepetitions(track_direction_in_parent), + is_opposite_direction_to_parent, + parent_line_resolver.IsSubgridded(track_direction_in_parent)); } }
diff --git a/third_party/blink/renderer/core/layout/ng/grid/ng_grid_named_line_collection.cc b/third_party/blink/renderer/core/layout/ng/grid/ng_grid_named_line_collection.cc index 4f61aaed..c884ac26 100644 --- a/third_party/blink/renderer/core/layout/ng/grid/ng_grid_named_line_collection.cc +++ b/third_party/blink/renderer/core/layout/ng/grid/ng_grid_named_line_collection.cc
@@ -8,7 +8,6 @@ #include "third_party/blink/renderer/core/style/computed_grid_track_list.h" #include "third_party/blink/renderer/core/style/computed_style.h" #include "third_party/blink/renderer/core/style/grid_area.h" -#include "third_party/blink/renderer/core/style/grid_positions_resolver.h" namespace blink {
diff --git a/third_party/blink/renderer/core/layout/ng/grid/ng_grid_track_collection.cc b/third_party/blink/renderer/core/layout/ng/grid/ng_grid_track_collection.cc index 0cc2302..416f22557 100644 --- a/third_party/blink/renderer/core/layout/ng/grid/ng_grid_track_collection.cc +++ b/third_party/blink/renderer/core/layout/ng/grid/ng_grid_track_collection.cc
@@ -226,8 +226,13 @@ DCHECK_GT(range.track_count, 0u); // Compute current repeater's index, size, and offset. + // TODO(ethavar): Simplify this logic. range.begin_set_index = current_set_index; - if (current_explicit_repeater_index != kNotFound) { + if (explicit_tracks_.IsSubgriddedAxis()) { + // Subgridded axis specified on standalone grid, use 'auto'. + range.repeater_index = kNotFound; + range.repeater_offset = 0u; + } else if (current_explicit_repeater_index != kNotFound) { current_repeater_size = explicit_tracks_.RepeatSize(current_explicit_repeater_index); @@ -913,10 +918,12 @@ }; if (range.repeater_index == kNotFound) { - // The only case where a range doesn't have a repeater index is when the - // range is in the implicit grid and there are no auto track definitions; - // fill the entire range with a single set of 'auto' tracks. - DCHECK(range.IsImplicit()); + // The only cases where a range doesn't have a repeater index are when the + // range is in the implicit grid and there are no auto track definitions, + // or when 'subgrid' is specified on a track definition but it's not a + // child of a grid (and thus not a subgrid); in both cases, fill the + // entire range with a single set of 'auto' tracks. + DCHECK(range.IsImplicit() || explicit_track_list.IsSubgriddedAxis()); CacheSetProperties(sets_.emplace_back(range.track_count)); } else { const auto& specified_track_list =
diff --git a/third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.cc b/third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.cc index 1b557dd4..8815bdd1 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.cc
@@ -291,24 +291,6 @@ /* relative_offset */ LogicalOffset())); } -void NGBoxFragmentBuilder::RemoveOldLegacyOOFFlexItem( - const LayoutObject& object) { - // While what this method does should "work" for any child fragment in - // general, it's only expected to be called under very specific legacy - // circumstances, and besides it's evil. - DCHECK(object.IsOutOfFlowPositioned()); - DCHECK(object.Parent()->IsFlexibleBox()); - DCHECK(object.Parent()->IsOutOfFlowPositioned()); - for (wtf_size_t idx = 0; idx < children_.size(); idx++) { - const NGLogicalLink& child = children_[idx]; - if (child.fragment->GetLayoutObject() == &object) { - children_.EraseAt(idx); - return; - } - } - NOTREACHED(); -} - NGPhysicalFragment::NGBoxType NGBoxFragmentBuilder::BoxType() const { if (box_type_ != NGPhysicalFragment::NGBoxType::kNormalBox) return box_type_;
diff --git a/third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.h b/third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.h index 0de8b3a2..a198113e 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.h +++ b/third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.h
@@ -236,14 +236,6 @@ const NGLogicalStaticPosition&, const LayoutInline* inline_container); - // Remove the fragment previously generated for an out-of-flow positioned flex - // item inside an out-of-flow legacy flex container. This is a work-around for - // OOFs being laid out out-of-document-order, which is an issue with the - // legacy engine (although it's not known to cause any other actual problems - // than this). We'll call this method to correct a document-out-of-order - // issue. - void RemoveOldLegacyOOFFlexItem(const LayoutObject&); - // Before layout we'll determine whether we can tell for sure that the node // (or what's left of it to lay out, in case we've already broken) will fit in // the current fragmentainer. If this is the case, we'll know that any
diff --git a/third_party/blink/renderer/core/layout/ng/ng_constraint_space.cc b/third_party/blink/renderer/core/layout/ng/ng_constraint_space.cc index 4472e206..27eb89e20 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_constraint_space.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_constraint_space.cc
@@ -8,7 +8,6 @@ #include <memory> #include "third_party/blink/renderer/core/layout/layout_block.h" -#include "third_party/blink/renderer/core/layout/layout_flexible_box.h" #include "third_party/blink/renderer/core/layout/layout_view.h" #include "third_party/blink/renderer/core/layout/ng/layout_box_utils.h" #include "third_party/blink/renderer/core/layout/ng/ng_constraint_space_builder.h" @@ -74,14 +73,6 @@ available_size.block_size = block.OverrideLogicalHeight(); is_fixed_block_size = true; } - if (block.IsFlexItem() && is_fixed_block_size) { - // The flexbox-specific behavior is in addition to regular definite-ness, so - // if the flex item would normally have a definite height it should keep it. - is_initial_block_size_definite = - To<LayoutFlexibleBox>(block.Parent()) - ->UseOverrideLogicalHeightForPerentageResolution(block) || - block.HasDefiniteLogicalHeight(); - } // We cannot enter NG layout at an object that isn't a formatting context // root. However, even though we're creating a constraint space for an object @@ -105,7 +96,7 @@ : NGBaselineAlgorithmType::kDefault); } - if (block.IsAtomicInlineLevel() || block.IsFlexItem() || block.IsFloating()) { + if (block.IsAtomicInlineLevel() || block.IsFloating()) { builder.SetIsPaintedAtomically(true); }
diff --git a/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.cc b/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.cc index 693a2e1b..a298562 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.cc
@@ -10,7 +10,6 @@ #include "third_party/blink/renderer/core/layout/geometry/writing_mode_converter.h" #include "third_party/blink/renderer/core/layout/layout_block.h" #include "third_party/blink/renderer/core/layout/layout_box.h" -#include "third_party/blink/renderer/core/layout/layout_flexible_box.h" #include "third_party/blink/renderer/core/layout/layout_inline.h" #include "third_party/blink/renderer/core/layout/layout_object.h" #include "third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm.h" @@ -298,37 +297,9 @@ if (placed_objects.Contains(legacy_object)) { if (!performing_extra_legacy_check_ || !legacy_object->NeedsLayout()) continue; - container_builder_->RemoveOldLegacyOOFFlexItem(*legacy_object); } - // Flex OOF children may have center alignment or similar, and in order - // to determine their static position correctly need to have a valid - // size first. - // We perform a pre-layout to correctly determine the static position. - // Copied from LayoutBlock::LayoutPositionedObject - // TODO(layout-dev): Remove this once LayoutFlexibleBox is removed. LayoutBox* layout_box = To<LayoutBox>(legacy_object); - if (layout_box->Parent()->IsFlexibleBox()) { - auto* parent = To<LayoutFlexibleBox>(layout_box->Parent()); - if (parent->SetStaticPositionForPositionedLayout(*layout_box)) { - NGLogicalOutOfFlowPositionedNode candidate((NGBlockNode(layout_box)), - NGLogicalStaticPosition()); - NodeInfo node_info = SetupNodeInfo(candidate); - NodeToLayout node_to_layout = { - node_info, CalculateOffset(node_info, /* only_layout */ nullptr)}; - LayoutOOFNode(node_to_layout, - /* only_layout */ nullptr); - parent->SetStaticPositionForPositionedLayout(*layout_box); - } - } - - // If we have a legacy OOF flex container, we'll allow some rocket science - // to take place, as an attempt to get things laid out in correct document - // order, or we might otherwise leave behind objects (OOF flex items) - // needing layout. - if (!has_legacy_flex_box_) - has_legacy_flex_box_ = layout_box->IsFlexibleBox(); - NGLogicalStaticPosition static_position = LayoutBoxUtils::ComputeStaticPositionFromLegacy( *layout_box,
diff --git a/third_party/blink/renderer/core/page/page.cc b/third_party/blink/renderer/core/page/page.cc index f133bae..969eaef9 100644 --- a/third_party/blink/renderer/core/page/page.cc +++ b/third_party/blink/renderer/core/page/page.cc
@@ -885,7 +885,6 @@ // TODO(loonybear): Most of this doesn't appear to take into account that // each SVGImage gets it's own Page instance. GetDeprecation().ClearSuppression(); - GetVisualViewport().SendUMAMetrics(); // Need to reset visual viewport position here since before commit load we // would update the previous history item, Page::didCommitLoad is called // after a new history item is created in FrameLoader.
diff --git a/third_party/blink/renderer/core/page/scrolling/main_thread_scrolling_reasons_test.cc b/third_party/blink/renderer/core/page/scrolling/main_thread_scrolling_reasons_test.cc index 1184d6c..aec01e37 100644 --- a/third_party/blink/renderer/core/page/scrolling/main_thread_scrolling_reasons_test.cc +++ b/third_party/blink/renderer/core/page/scrolling/main_thread_scrolling_reasons_test.cc
@@ -385,6 +385,12 @@ void TestNonCompositedReasons(const AtomicString& style_class, const uint32_t reason) { + if (RuntimeEnabledFeatures::CompositeScrollAfterPaintEnabled() && reason) { + // TODO(crbug.com/1414885): We need a new way to test non-composited + // main thread scrolling reasons. + return; + } + GetFrame()->GetSettings()->SetPreferCompositingToLCDTextForTesting(false); Document* document = GetFrame()->GetDocument(); Element* container = document->getElementById("scroller1");
diff --git a/third_party/blink/renderer/core/page/scrolling/scrolling_test.cc b/third_party/blink/renderer/core/page/scrolling/scrolling_test.cc index 4016401f..28ac21b6 100644 --- a/third_party/blink/renderer/core/page/scrolling/scrolling_test.cc +++ b/third_party/blink/renderer/core/page/scrolling/scrolling_test.cc
@@ -235,6 +235,23 @@ INSTANTIATE_PAINT_TEST_SUITE_P(ScrollingTest); +#define ASSERT_COMPOSITED(scroll_node) \ + do { \ + ASSERT_TRUE(scroll_node); \ + ASSERT_TRUE(scroll_node->is_composited); \ + EXPECT_EQ(cc::MainThreadScrollingReason::kNotScrollingOnMain, \ + scroll_node->main_thread_scrolling_reasons); \ + } while (false) + +#define ASSERT_NOT_COMPOSITED(scroll_node, \ + expected_main_thread_scrolling_reasons) \ + do { \ + ASSERT_TRUE(scroll_node); \ + ASSERT_FALSE(scroll_node->is_composited); \ + EXPECT_EQ(expected_main_thread_scrolling_reasons, \ + scroll_node->main_thread_scrolling_reasons); \ + } while (false) + TEST_P(ScrollingTest, fastScrollingByDefault) { GetWebView()->MainFrameViewWidget()->Resize(gfx::Size(800, 600)); LoadHTML("<div id='spacer' style='height: 1000px'></div>"); @@ -248,8 +265,7 @@ // Fast scrolling should be enabled by default. const auto* outer_scroll_node = ScrollNodeForScrollableArea(frame_view->LayoutViewport()); - ASSERT_TRUE(outer_scroll_node); - EXPECT_FALSE(outer_scroll_node->main_thread_scrolling_reasons); + ASSERT_COMPOSITED(outer_scroll_node); ASSERT_EQ(cc::EventListenerProperties::kNone, LayerTreeHost()->event_listener_properties( @@ -260,8 +276,7 @@ const auto* inner_scroll_node = ScrollNodeForScrollableArea(&page->GetVisualViewport()); - ASSERT_TRUE(inner_scroll_node); - EXPECT_FALSE(inner_scroll_node->main_thread_scrolling_reasons); + ASSERT_COMPOSITED(inner_scroll_node); } TEST_P(ScrollingTest, fastFractionalScrollingDiv) { @@ -312,8 +327,7 @@ // Sticky position should not fall back to main thread scrolling. const auto* scroll_node = ScrollNodeForScrollableArea(GetFrame()->View()->LayoutViewport()); - ASSERT_TRUE(scroll_node); - EXPECT_FALSE(scroll_node->main_thread_scrolling_reasons); + ASSERT_COMPOSITED(scroll_node); Document* document = GetFrame()->GetDocument(); { @@ -1100,6 +1114,11 @@ } TEST_P(ScrollingTest, WheelEventRegionUpdatedOnSubscrollerScrollChange) { + if (RuntimeEnabledFeatures::CompositeScrollAfterPaintEnabled()) { + // TODO(crbug.com/1414885): Fix wheel_event_region. + return; + } + SetPreferCompositingToLCDText(false); LoadHTML(R"HTML( <style> @@ -1357,6 +1376,11 @@ } TEST_P(ScrollingTest, NonFastScrollableRegionWithBorder) { + if (RuntimeEnabledFeatures::CompositeScrollAfterPaintEnabled()) { + // TODO(crbug.com/1414885): Fix non_fast_scrollable_region. + return; + } + SetPreferCompositingToLCDText(false); LoadHTML(R"HTML( <!DOCTYPE html> @@ -1381,6 +1405,11 @@ } TEST_P(ScrollingTest, ElementRegionCaptureData) { + if (RuntimeEnabledFeatures::CompositeScrollAfterPaintEnabled()) { + // TODO(crbug.com/1414885): Fix this test. + return; + } + LoadHTML(R"HTML( <head> <style type="text/css"> @@ -1576,6 +1605,11 @@ } TEST_P(ScrollingTest, NestedIFramesMainThreadScrollingRegion) { + if (RuntimeEnabledFeatures::CompositeScrollAfterPaintEnabled()) { + // TODO(crbug.com/1414885): Fix non_fast_scrollable_region. + return; + } + // This page has an absolute IFRAME. It contains a scrollable child DIV // that's nested within an intermediate IFRAME. SetPreferCompositingToLCDText(false); @@ -2111,9 +2145,10 @@ // noncomposited reasons set. It then removes the box-shadow property and // ensures the compositor node updates accordingly. TEST_P(UnifiedScrollingSimTest, ScrollNodeForNonCompositedScroller) { - // This test requires scroll unification. - if (!base::FeatureList::IsEnabled(::features::kScrollUnification)) + if (!base::FeatureList::IsEnabled(::features::kScrollUnification)) { + // This test requires scroll unification. return; + } SimRequest request("https://example.com/test.html", "text/html"); LoadURL("https://example.com/test.html"); @@ -2144,19 +2179,14 @@ MainFrame().GetFrame()->GetDocument()->getElementById("noncomposited"); auto* scrollable_area = noncomposited_element->GetLayoutBoxForScrolling()->GetScrollableArea(); - ASSERT_EQ( - cc::MainThreadScrollingReason::kCantPaintScrollingBackgroundAndLCDText, - scrollable_area->GetNonCompositedMainThreadScrollingReasons()); - const auto* scroll_node = ScrollNodeForScrollableArea(scrollable_area); - ASSERT_TRUE(scroll_node); - + ASSERT_NOT_COMPOSITED( + scroll_node, + RuntimeEnabledFeatures::CompositeScrollAfterPaintEnabled() + ? cc::MainThreadScrollingReason::kNotOpaqueForTextAndLCDText + : cc::MainThreadScrollingReason:: + kCantPaintScrollingBackgroundAndLCDText); EXPECT_EQ(scroll_node->element_id, scrollable_area->GetScrollElementId()); - EXPECT_FALSE(RootCcLayer() - ->layer_tree_host() - ->property_trees() - ->scroll_tree() - .IsComposited(*scroll_node)); // Now remove the box-shadow property and ensure the compositor scroll node // changes. @@ -2164,13 +2194,8 @@ "box-shadow: none"); Compositor().BeginFrame(); - EXPECT_EQ(0u, scrollable_area->GetNonCompositedMainThreadScrollingReasons()); + ASSERT_COMPOSITED(scroll_node); EXPECT_EQ(scroll_node->element_id, scrollable_area->GetScrollElementId()); - EXPECT_TRUE(RootCcLayer() - ->layer_tree_host() - ->property_trees() - ->scroll_tree() - .IsComposited(*scroll_node)); } // Tests that the compositor retains the scroll node for a composited scroller @@ -2178,9 +2203,10 @@ // IsComposited state updated accordingly. TEST_P(UnifiedScrollingSimTest, ScrollNodeForCompositedToNonCompositedScroller) { - // This test requires scroll unification. - if (!base::FeatureList::IsEnabled(::features::kScrollUnification)) + if (!base::FeatureList::IsEnabled(::features::kScrollUnification)) { + // This test requires scroll unification. return; + } SimRequest request("https://example.com/test.html", "text/html"); LoadURL("https://example.com/test.html"); @@ -2210,17 +2236,9 @@ MainFrame().GetFrame()->GetDocument()->getElementById("composited"); auto* scrollable_area = composited_element->GetLayoutBoxForScrolling()->GetScrollableArea(); - EXPECT_EQ(0u, scrollable_area->GetNonCompositedMainThreadScrollingReasons()); - const auto* scroll_node = ScrollNodeForScrollableArea(scrollable_area); - ASSERT_TRUE(scroll_node); - + ASSERT_COMPOSITED(scroll_node); EXPECT_EQ(scroll_node->element_id, scrollable_area->GetScrollElementId()); - EXPECT_TRUE(RootCcLayer() - ->layer_tree_host() - ->property_trees() - ->scroll_tree() - .IsComposited(*scroll_node)); // Now add an inset box-shadow property to make the node noncomposited and // ensure the compositor scroll node updates accordingly. @@ -2228,15 +2246,13 @@ "box-shadow: 10px 10px black inset"); Compositor().BeginFrame(); - ASSERT_EQ( - cc::MainThreadScrollingReason::kCantPaintScrollingBackgroundAndLCDText, - scrollable_area->GetNonCompositedMainThreadScrollingReasons()); + ASSERT_NOT_COMPOSITED( + scroll_node, + RuntimeEnabledFeatures::CompositeScrollAfterPaintEnabled() + ? cc::MainThreadScrollingReason::kNotOpaqueForTextAndLCDText + : cc::MainThreadScrollingReason:: + kCantPaintScrollingBackgroundAndLCDText); EXPECT_EQ(scroll_node->element_id, scrollable_area->GetScrollElementId()); - EXPECT_FALSE(RootCcLayer() - ->layer_tree_host() - ->property_trees() - ->scroll_tree() - .IsComposited(*scroll_node)); } // Tests that the compositor gets a scroll node for noncomposited scrollers @@ -2244,9 +2260,14 @@ // scroller with an inset box shadow, and ensuring that scroller generates a // compositor scroll node with the proper noncomposited reasons set. TEST_P(UnifiedScrollingSimTest, ScrollNodeForEmbeddedScrollers) { - // This test requires scroll unification. - if (!base::FeatureList::IsEnabled(::features::kScrollUnification)) + if (RuntimeEnabledFeatures::CompositeScrollAfterPaintEnabled()) { + // TODO(crbug.com/1414885): Fix this test. return; + } + if (!base::FeatureList::IsEnabled(::features::kScrollUnification)) { + // This test requires scroll unification. + return; + } SimRequest request("https://example.com/test.html", "text/html"); LoadURL("https://example.com/test.html"); @@ -2296,18 +2317,11 @@ iframe->contentDocument()->View()->LayoutViewport(); const auto* iframe_scroll_node = ScrollNodeForScrollableArea(iframe_scrollable_area); - ASSERT_TRUE(iframe_scroll_node); // The iframe itself is a composited scroller. - EXPECT_EQ( - 0u, iframe_scrollable_area->GetNonCompositedMainThreadScrollingReasons()); + ASSERT_COMPOSITED(iframe_scroll_node); EXPECT_EQ(iframe_scroll_node->element_id, iframe_scrollable_area->GetScrollElementId()); - EXPECT_TRUE(RootCcLayer() - ->layer_tree_host() - ->property_trees() - ->scroll_tree() - .IsComposited(*iframe_scroll_node)); // Ensure we have a compositor scroll node for the noncomposited subscroller. auto* child_scrollable_area = iframe->contentDocument() @@ -2316,19 +2330,14 @@ ->GetScrollableArea(); const auto* child_scroll_node = ScrollNodeForScrollableArea(child_scrollable_area); - ASSERT_TRUE(child_scroll_node); - - EXPECT_EQ( - cc::MainThreadScrollingReason::kCantPaintScrollingBackgroundAndLCDText, - child_scrollable_area->GetNonCompositedMainThreadScrollingReasons()); + ASSERT_NOT_COMPOSITED( + child_scroll_node, + RuntimeEnabledFeatures::CompositeScrollAfterPaintEnabled() + ? cc::MainThreadScrollingReason::kNotOpaqueForTextAndLCDText + : cc::MainThreadScrollingReason:: + kCantPaintScrollingBackgroundAndLCDText); EXPECT_EQ(child_scroll_node->element_id, child_scrollable_area->GetScrollElementId()); - - EXPECT_FALSE(RootCcLayer() - ->layer_tree_host() - ->property_trees() - ->scroll_tree() - .IsComposited(*child_scroll_node)); } // Similar to the above test, but for deeper nesting iframes to ensure we @@ -2406,19 +2415,14 @@ ->GetScrollableArea(); const auto* child_scroll_node = ScrollNodeForScrollableArea(child_scrollable_area); - ASSERT_TRUE(child_scroll_node); - - EXPECT_EQ( - cc::MainThreadScrollingReason::kCantPaintScrollingBackgroundAndLCDText, - child_scrollable_area->GetNonCompositedMainThreadScrollingReasons()); + ASSERT_NOT_COMPOSITED( + child_scroll_node, + RuntimeEnabledFeatures::CompositeScrollAfterPaintEnabled() + ? cc::MainThreadScrollingReason::kNotOpaqueForTextAndLCDText + : cc::MainThreadScrollingReason:: + kCantPaintScrollingBackgroundAndLCDText); EXPECT_EQ(child_scroll_node->element_id, child_scrollable_area->GetScrollElementId()); - - EXPECT_FALSE(RootCcLayer() - ->layer_tree_host() - ->property_trees() - ->scroll_tree() - .IsComposited(*child_scroll_node)); } // Tests that the compositor gets a scroll node for opacity 0 noncomposited @@ -2468,23 +2472,17 @@ // Ensure the opacity 0 noncomposited scrollable area generates a scroll node auto* invisible_scrollable_area = ScrollableAreaByDOMElementId("invisible"); - ASSERT_EQ( - cc::MainThreadScrollingReason::kCantPaintScrollingBackgroundAndLCDText, - invisible_scrollable_area->GetNonCompositedMainThreadScrollingReasons()); - const auto* invisible_scroll_node = ScrollNodeForScrollableArea(invisible_scrollable_area); - ASSERT_TRUE(invisible_scroll_node); - + ASSERT_NOT_COMPOSITED( + invisible_scroll_node, + RuntimeEnabledFeatures::CompositeScrollAfterPaintEnabled() + ? cc::MainThreadScrollingReason::kNotOpaqueForTextAndLCDText + : cc::MainThreadScrollingReason:: + kCantPaintScrollingBackgroundAndLCDText); EXPECT_EQ(invisible_scroll_node->element_id, invisible_scrollable_area->GetScrollElementId()); - EXPECT_FALSE(RootCcLayer() - ->layer_tree_host() - ->property_trees() - ->scroll_tree() - .IsComposited(*invisible_scroll_node)); - // Ensure there's no scrollable area (and therefore no scroll node) for a // display none scroller. EXPECT_EQ(nullptr, ScrollableAreaByDOMElementId("displaynone")); @@ -2511,11 +2509,10 @@ Compositor().BeginFrame(); auto* scrollable_area = ScrollableAreaByDOMElementId("textinput"); - ASSERT_EQ(cc::MainThreadScrollingReason::kNotOpaqueForTextAndLCDText, - scrollable_area->GetNonCompositedMainThreadScrollingReasons()); - const auto* scroll_node = ScrollNodeForScrollableArea(scrollable_area); ASSERT_TRUE(scroll_node); + ASSERT_EQ(cc::MainThreadScrollingReason::kNotOpaqueForTextAndLCDText, + scroll_node->main_thread_scrolling_reasons); EXPECT_EQ(scroll_node->element_id, scrollable_area->GetScrollElementId()); EXPECT_FALSE(RootCcLayer()
diff --git a/third_party/blink/renderer/core/paint/compositing/compositing_test.cc b/third_party/blink/renderer/core/paint/compositing/compositing_test.cc index 00f5a79..ca97f9d 100644 --- a/third_party/blink/renderer/core/paint/compositing/compositing_test.cc +++ b/third_party/blink/renderer/core/paint/compositing/compositing_test.cc
@@ -2710,7 +2710,14 @@ LayoutBox* scroller = To<LayoutBox>(bottom_frame.GetDocument() ->getElementById("scroller") ->GetLayoutObject()); - ASSERT_TRUE(scroller->GetScrollableArea()->NeedsCompositedScrolling()); + if (RuntimeEnabledFeatures::CompositeScrollAfterPaintEnabled()) { + // In CompositeScrollAfterPaint, NeedsComositedScrolling returns true + // only if the scroller is forced to be composited. + EXPECT_FALSE(scroller->GetScrollableArea()->NeedsCompositedScrolling()); + } else { + ASSERT_TRUE(scroller->GetScrollableArea()->NeedsCompositedScrolling()); + } + EXPECT_TRUE(CcLayerByDOMElementId("scroller")); // Hide the iframes. Scroller should be decomposited.
diff --git a/third_party/blink/renderer/core/paint/paint_and_raster_invalidation_test.cc b/third_party/blink/renderer/core/paint/paint_and_raster_invalidation_test.cc index 22480fbf..ab54bb1 100644 --- a/third_party/blink/renderer/core/paint/paint_and_raster_invalidation_test.cc +++ b/third_party/blink/renderer/core/paint/paint_and_raster_invalidation_test.cc
@@ -404,6 +404,10 @@ } TEST_P(PaintAndRasterInvalidationTest, NonCompositedLayoutViewResize) { + if (RuntimeEnabledFeatures::CompositeScrollAfterPaintEnabled()) { + // TODO(crbug.com/1414885): Fix this test. + return; + } ScopedPreferNonCompositedScrollingForTest non_composited_scrolling(true); SetBodyInnerHTML(R"HTML( @@ -480,6 +484,10 @@ } TEST_P(PaintAndRasterInvalidationTest, NonCompositedLayoutViewGradientResize) { + if (RuntimeEnabledFeatures::CompositeScrollAfterPaintEnabled()) { + // TODO(crbug.com/1414885): Fix this test. + return; + } ScopedPreferNonCompositedScrollingForTest non_composited_scrolling(true); SetBodyInnerHTML(R"HTML( @@ -644,6 +652,11 @@ TEST_P(PaintAndRasterInvalidationTest, NonCompositedBackgroundAttachmentLocalResize) { + if (RuntimeEnabledFeatures::CompositeScrollAfterPaintEnabled()) { + // TODO(crbug.com/1414885): Fix this test. + return; + } + SetUpHTML(*this); Element* target = GetDocument().getElementById("target"); auto* object = target->GetLayoutBox();
diff --git a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc index 0bb8e14..497882c 100644 --- a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc +++ b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc
@@ -81,7 +81,6 @@ #include "third_party/blink/renderer/core/layout/custom_scrollbar.h" #include "third_party/blink/renderer/core/layout/layout_custom_scrollbar_part.h" #include "third_party/blink/renderer/core/layout/layout_embedded_content.h" -#include "third_party/blink/renderer/core/layout/layout_flexible_box.h" #include "third_party/blink/renderer/core/layout/layout_theme.h" #include "third_party/blink/renderer/core/layout/layout_view.h" #include "third_party/blink/renderer/core/layout/ng/legacy_layout_tree_walking.h" @@ -1083,11 +1082,6 @@ in_overflow_relayout_ = false; scrollbar_manager_.DestroyDetachedScrollbars(); } - LayoutObject* parent = GetLayoutBox()->Parent(); - if (parent && parent->IsFlexibleBox()) { - To<LayoutFlexibleBox>(parent)->ClearCachedMainSizeForChild( - *GetLayoutBox()); - } } } } else if (!HasScrollbar() && resizer_will_change) { @@ -2481,8 +2475,10 @@ box->ComputeBackgroundPaintLocationIfComposited(); bool needs_composited_scrolling = ComputeNeedsCompositedScrollingInternal( new_background_paint_location, force_prefer_compositing_to_lcd_text); - if (!needs_composited_scrolling) + if (!RuntimeEnabledFeatures::CompositeScrollAfterPaintEnabled() && + !needs_composited_scrolling) { new_background_paint_location = kBackgroundPaintInBorderBoxSpace; + } box->GetMutableForPainting().SetBackgroundPaintLocation( new_background_paint_location); @@ -2500,21 +2496,24 @@ if (CompositingReasonFinder::RequiresCompositingForRootScroller(*layer_)) { return true; } - if (!ScrollsOverflow()) { return false; } - - if (!force_prefer_compositing_to_lcd_text && - RuntimeEnabledFeatures::PreferNonCompositedScrollingEnabled()) { + if (force_prefer_compositing_to_lcd_text) { + return true; + } + if (RuntimeEnabledFeatures::CompositeScrollAfterPaintEnabled()) { + // We'll decide composited scrolling in PaintArtifactCompositor later. + return false; + } + if (RuntimeEnabledFeatures::PreferNonCompositedScrollingEnabled()) { return false; } const auto* box = GetLayoutBox(); bool needs_composited_scrolling = true; - if (!force_prefer_compositing_to_lcd_text && - box->GetDocument().GetSettings()->GetLCDTextPreference() == - LCDTextPreference::kStronglyPreferred) { + if (box->GetDocument().GetSettings()->GetLCDTextPreference() == + LCDTextPreference::kStronglyPreferred) { if (!box->TextIsKnownToBeOnOpaqueBackground()) { non_composited_main_thread_scrolling_reasons_ |= cc::MainThreadScrollingReason::kNotOpaqueForTextAndLCDText; @@ -2895,11 +2894,17 @@ bool PaintLayerScrollableArea::ShouldDirectlyCompositeScrollbar( const Scrollbar& scrollbar) const { // Don't composite non-scrollable scrollbars. - if (!scrollbar.Maximum()) + if (!scrollbar.Maximum()) { return false; - if (scrollbar.IsCustomScrollbar()) + } + if (scrollbar.IsCustomScrollbar()) { return false; - + } + if (RuntimeEnabledFeatures::CompositeScrollAfterPaintEnabled()) { + // TODO(crbug.com/1414885): We may composite all scrollbars, or assume they + // are before PaintArtifactCompositor::Update(). + return true; + } return NeedsCompositedScrolling(); }
diff --git a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h index 5b5dd5b..50cf3590 100644 --- a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h +++ b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h
@@ -461,6 +461,10 @@ // properties which are updated based on the latter. bool UsesCompositedScrolling() const override; + // In CompositeScrollAfterPaint, NeedsCompositedScrolling() is false if + // composited scrolling will be determined after paint. + // TODO(crbug.com/1414885): We may need to redefine these functions for + // CompositeScrollAfterPaint. void UpdateNeedsCompositedScrolling( bool force_prefer_compositing_to_lcd_text); bool NeedsCompositedScrolling() const { return needs_composited_scrolling_; }
diff --git a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area_test.cc b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area_test.cc index 6cc11540..e26a78a 100644 --- a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area_test.cc +++ b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area_test.cc
@@ -60,31 +60,26 @@ return *chrome_client_; } - bool IsComposited(const LayoutObject* scroller) { + bool HasDirectCompositingReasons(const LayoutObject* scroller) { const auto* paint_properties = scroller->FirstFragment().PaintProperties(); return paint_properties && paint_properties->Transform() && paint_properties->Transform()->HasDirectCompositingReasons(); } - bool UsesCompositedScrolling(const LayoutObject* scroller) { - const auto* paint_properties = scroller->FirstFragment().PaintProperties(); - bool composited = - paint_properties && paint_properties->ScrollTranslation() && - paint_properties->ScrollTranslation()->HasDirectCompositingReasons(); - - auto* layer = To<LayoutBoxModelObject>(scroller)->Layer(); - if (!layer) { - DCHECK(!composited); - return false; + bool UsesCompositedScrolling(const LayoutBox* scroller) { + // TODO(crbug.com/1414885): In CompositeScrollAfterPaint, the tests no + // longer test PaintLayerScrollableArea. We should probably move them into + // scrolling_test.cc. + if (auto* scrollable_area = scroller->GetScrollableArea()) { + const auto* property_trees = + GetFrame().View()->RootCcLayer()->layer_tree_host()->property_trees(); + if (const auto* scroll_node = + property_trees->scroll_tree().FindNodeFromElementId( + scrollable_area->GetScrollElementId())) { + return scroll_node->is_composited; + } } - - auto* scrollable_area = layer->GetScrollableArea(); - if (!scrollable_area) { - DCHECK(!composited); - return false; - } - - return composited; + return false; } private: @@ -109,8 +104,7 @@ <div id="scroller"><div id="scrolled"></div></div> )HTML"); - auto* scroller = GetLayoutObjectByElementId("scroller"); - EXPECT_TRUE(UsesCompositedScrolling(scroller)); + EXPECT_TRUE(UsesCompositedScrolling(GetLayoutBoxByElementId("scroller"))); } TEST_P(MAYBE_PaintLayerScrollableAreaTest, NonStackingContextScrollerPromoted) { @@ -128,7 +122,7 @@ </div> )HTML"); - EXPECT_TRUE(UsesCompositedScrolling(GetLayoutObjectByElementId("scroller"))); + EXPECT_TRUE(UsesCompositedScrolling(GetLayoutBoxByElementId("scroller"))); } TEST_P(MAYBE_PaintLayerScrollableAreaTest, TransparentLayersNotPromoted) { @@ -142,7 +136,7 @@ <div id="scroller"><div id="scrolled"></div></div> )HTML"); - EXPECT_FALSE(UsesCompositedScrolling(GetLayoutObjectByElementId("scroller"))); + EXPECT_FALSE(UsesCompositedScrolling(GetLayoutBoxByElementId("scroller"))); } TEST_P(MAYBE_PaintLayerScrollableAreaTest, @@ -157,14 +151,14 @@ )HTML"); Element* scroller = GetDocument().getElementById("scroller"); - EXPECT_TRUE(UsesCompositedScrolling(scroller->GetLayoutObject())); + EXPECT_TRUE(UsesCompositedScrolling(scroller->GetLayoutBox())); // Change the background to transparent scroller->setAttribute( html_names::kStyleAttr, "background: rgba(255,255,255,0.5) local content-box;"); UpdateAllLifecyclePhasesForTest(); - EXPECT_FALSE(UsesCompositedScrolling(scroller->GetLayoutObject())); + EXPECT_FALSE(UsesCompositedScrolling(scroller->GetLayoutBox())); } TEST_P(MAYBE_PaintLayerScrollableAreaTest, OpaqueLayersPromotedOnStyleChange) { @@ -178,13 +172,13 @@ )HTML"); Element* scroller = GetDocument().getElementById("scroller"); - EXPECT_FALSE(UsesCompositedScrolling(scroller->GetLayoutObject())); + EXPECT_FALSE(UsesCompositedScrolling(scroller->GetLayoutBox())); // Change the background to opaque scroller->setAttribute(html_names::kStyleAttr, "background: white local content-box;"); UpdateAllLifecyclePhasesForTest(); - EXPECT_TRUE(UsesCompositedScrolling(scroller->GetLayoutObject())); + EXPECT_TRUE(UsesCompositedScrolling(scroller->GetLayoutBox())); } // Tests that a transform on the scroller or an ancestor doesn't prevent @@ -204,23 +198,23 @@ Element* parent = GetDocument().getElementById("parent"); Element* scroller = GetDocument().getElementById("scroller"); - EXPECT_TRUE(UsesCompositedScrolling(scroller->GetLayoutObject())); + EXPECT_TRUE(UsesCompositedScrolling(scroller->GetLayoutBox())); // Change the parent to have a transform. parent->setAttribute(html_names::kStyleAttr, "transform: translate(1px, 0);"); UpdateAllLifecyclePhasesForTest(); - EXPECT_TRUE(UsesCompositedScrolling(scroller->GetLayoutObject())); + EXPECT_TRUE(UsesCompositedScrolling(scroller->GetLayoutBox())); // Change the parent to have no transform again. parent->removeAttribute(html_names::kStyleAttr); UpdateAllLifecyclePhasesForTest(); - EXPECT_TRUE(UsesCompositedScrolling(scroller->GetLayoutObject())); + EXPECT_TRUE(UsesCompositedScrolling(scroller->GetLayoutBox())); // Apply a transform to the scroller directly. scroller->setAttribute(html_names::kStyleAttr, "transform: translate(1px, 0);"); UpdateAllLifecyclePhasesForTest(); - EXPECT_TRUE(UsesCompositedScrolling(scroller->GetLayoutObject())); + EXPECT_TRUE(UsesCompositedScrolling(scroller->GetLayoutBox())); } TEST_P(MAYBE_PaintLayerScrollableAreaTest, @@ -238,22 +232,22 @@ Element* parent = GetDocument().getElementById("parent"); Element* scroller = GetDocument().getElementById("scroller"); - EXPECT_TRUE(UsesCompositedScrolling(scroller->GetLayoutObject())); + EXPECT_TRUE(UsesCompositedScrolling(scroller->GetLayoutBox())); // Change the parent to be partially translucent. parent->setAttribute(html_names::kStyleAttr, "opacity: 0.5;"); UpdateAllLifecyclePhasesForTest(); - EXPECT_TRUE(UsesCompositedScrolling(scroller->GetLayoutObject())); + EXPECT_TRUE(UsesCompositedScrolling(scroller->GetLayoutBox())); // Change the parent to be opaque again. parent->setAttribute(html_names::kStyleAttr, "opacity: 1;"); UpdateAllLifecyclePhasesForTest(); - EXPECT_TRUE(UsesCompositedScrolling(scroller->GetLayoutObject())); + EXPECT_TRUE(UsesCompositedScrolling(scroller->GetLayoutBox())); // Make the scroller translucent. scroller->setAttribute(html_names::kStyleAttr, "opacity: 0.5"); UpdateAllLifecyclePhasesForTest(); - EXPECT_TRUE(UsesCompositedScrolling(scroller->GetLayoutObject())); + EXPECT_TRUE(UsesCompositedScrolling(scroller->GetLayoutBox())); } // Test that will-change: transform applied to the scroller will cause the @@ -269,15 +263,15 @@ )HTML"); Element* scroller = GetDocument().getElementById("scroller"); - EXPECT_FALSE(UsesCompositedScrolling(scroller->GetLayoutObject())); + EXPECT_FALSE(UsesCompositedScrolling(scroller->GetLayoutBox())); scroller->setAttribute(html_names::kStyleAttr, "will-change: transform"); UpdateAllLifecyclePhasesForTest(); - EXPECT_TRUE(UsesCompositedScrolling(scroller->GetLayoutObject())); + EXPECT_TRUE(UsesCompositedScrolling(scroller->GetLayoutBox())); scroller->setAttribute(html_names::kStyleAttr, ""); UpdateAllLifecyclePhasesForTest(); - EXPECT_FALSE(UsesCompositedScrolling(scroller->GetLayoutObject())); + EXPECT_FALSE(UsesCompositedScrolling(scroller->GetLayoutBox())); } // Test that will-change: transform applied to the scroller will cause the @@ -293,24 +287,24 @@ )HTML"); Element* scroller = GetDocument().getElementById("scroller"); - EXPECT_TRUE(UsesCompositedScrolling(scroller->GetLayoutObject())); + EXPECT_TRUE(UsesCompositedScrolling(scroller->GetLayoutBox())); // pointer-events: none does not affect whether composited scrolling is // present. scroller->setAttribute(html_names::kStyleAttr, "pointer-events: none"); UpdateAllLifecyclePhasesForTest(); - EXPECT_TRUE(UsesCompositedScrolling(scroller->GetLayoutObject())); + EXPECT_TRUE(UsesCompositedScrolling(scroller->GetLayoutBox())); // visibility: hidden causes the scroller to be invisible for hit testing, // so ScrollsOverflow becomes false on the PaintLayerScrollableArea, and hence // composited scrolling is not present. scroller->setAttribute(html_names::kStyleAttr, "visibility: hidden"); UpdateAllLifecyclePhasesForTest(); - EXPECT_FALSE(UsesCompositedScrolling(scroller->GetLayoutObject())); + EXPECT_FALSE(UsesCompositedScrolling(scroller->GetLayoutBox())); scroller->setAttribute(html_names::kStyleAttr, ""); UpdateAllLifecyclePhasesForTest(); - EXPECT_TRUE(UsesCompositedScrolling(scroller->GetLayoutObject())); + EXPECT_TRUE(UsesCompositedScrolling(scroller->GetLayoutBox())); } // Test that <input> elements don't use composited scrolling even with @@ -325,13 +319,13 @@ )HTML"); Element* element = GetDocument().getElementById("input"); - EXPECT_FALSE(IsComposited(element->GetLayoutObject())); - EXPECT_FALSE(UsesCompositedScrolling(element->GetLayoutObject())); + EXPECT_FALSE(HasDirectCompositingReasons(element->GetLayoutObject())); + EXPECT_FALSE(UsesCompositedScrolling(element->GetLayoutBox())); element->setAttribute("class", "composited"); UpdateAllLifecyclePhasesForTest(); - EXPECT_TRUE(IsComposited(element->GetLayoutObject())); - EXPECT_FALSE(UsesCompositedScrolling(element->GetLayoutObject())); + EXPECT_TRUE(HasDirectCompositingReasons(element->GetLayoutObject())); + EXPECT_FALSE(UsesCompositedScrolling(element->GetLayoutBox())); } // Test that <select> elements use composited scrolling with @@ -351,17 +345,29 @@ )HTML"); Element* element = GetDocument().getElementById("select"); - EXPECT_FALSE(IsComposited(element->GetLayoutObject())); - EXPECT_FALSE(UsesCompositedScrolling(element->GetLayoutObject())); + EXPECT_FALSE(HasDirectCompositingReasons(element->GetLayoutObject())); + if (RuntimeEnabledFeatures::CompositeScrollAfterPaintEnabled()) { + // PaintArtifactCompositor can detect the opaque background of <select> + // and use composited scrolling. +#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_IOS) + // <select> implementation is different and not scrollable on Android and + // iOS. + EXPECT_FALSE(UsesCompositedScrolling(element->GetLayoutBox())); +#else + EXPECT_TRUE(UsesCompositedScrolling(element->GetLayoutBox())); +#endif + } else { + EXPECT_FALSE(UsesCompositedScrolling(element->GetLayoutBox())); + } element->setAttribute("class", "composited"); UpdateAllLifecyclePhasesForTest(); - EXPECT_TRUE(IsComposited(element->GetLayoutObject())); + EXPECT_TRUE(HasDirectCompositingReasons(element->GetLayoutBox())); #if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_IOS) // <select> implementation is different and not scrollable on Android and iOS. - EXPECT_FALSE(UsesCompositedScrolling(element->GetLayoutObject())); + EXPECT_FALSE(UsesCompositedScrolling(element->GetLayoutBox())); #else - EXPECT_TRUE(UsesCompositedScrolling(element->GetLayoutObject())); + EXPECT_TRUE(UsesCompositedScrolling(element->GetLayoutBox())); #endif } @@ -492,8 +498,7 @@ Element* scroller = GetDocument().getElementById("scroller"); PaintLayerScrollableArea* scrollable_area = - To<LayoutBoxModelObject>(scroller->GetLayoutObject()) - ->GetScrollableArea(); + scroller->GetLayoutBox()->GetScrollableArea(); ASSERT_TRUE(scrollable_area); EXPECT_CALL(GetChromeClient(), MockUpdateTooltipUnderCursor( @@ -526,8 +531,7 @@ Element* scroller = GetDocument().getElementById("scroller"); ASSERT_TRUE(scroller); PaintLayerScrollableArea* scrollable_area = - To<LayoutBoxModelObject>(scroller->GetLayoutObject()) - ->GetScrollableArea(); + scroller->GetLayoutBox()->GetScrollableArea(); ASSERT_TRUE(scrollable_area); scrollable_area->SetScrollOffset(ScrollOffset(100, 0), mojom::blink::ScrollType::kClamping); @@ -558,11 +562,10 @@ Element* outer_div = GetDocument().getElementById("outerDiv"); ASSERT_TRUE(outer_div); - outer_div->GetLayoutObject()->SetNeedsLayout("test"); + outer_div->GetLayoutBox()->SetNeedsLayout("test"); UpdateAllLifecyclePhasesForTest(); PaintLayerScrollableArea* scrollable_area = - To<LayoutBoxModelObject>(outer_div->GetLayoutObject()) - ->GetScrollableArea(); + outer_div->GetLayoutBox()->GetScrollableArea(); ASSERT_TRUE(scrollable_area); EXPECT_TRUE(scrollable_area->HasVerticalScrollbar()); } @@ -590,8 +593,7 @@ Element* container = GetDocument().getElementById("container"); ASSERT_TRUE(container); PaintLayerScrollableArea* scrollable_area = - To<LayoutBoxModelObject>(container->GetLayoutObject()) - ->GetScrollableArea(); + container->GetLayoutBox()->GetScrollableArea(); ASSERT_TRUE(scrollable_area); EXPECT_FALSE(scrollable_area->HasHorizontalScrollbar()); } @@ -619,8 +621,7 @@ Element* container = GetDocument().getElementById("container"); ASSERT_TRUE(container); PaintLayerScrollableArea* scrollable_area = - To<LayoutBoxModelObject>(container->GetLayoutObject()) - ->GetScrollableArea(); + container->GetLayoutBox()->GetScrollableArea(); ASSERT_TRUE(scrollable_area); EXPECT_EQ(scrollable_area->ScrollOrigin().x(), 100); } @@ -640,7 +641,7 @@ </div> )HTML"); - auto* scroller = GetLayoutObjectByElementId("scroller"); + auto* scroller = GetLayoutBoxByElementId("scroller"); auto* scrollable_area = To<LayoutBoxModelObject>(scroller)->GetScrollableArea(); @@ -701,7 +702,7 @@ </div> )HTML"); - auto* scroller = GetLayoutObjectByElementId("scroller"); + auto* scroller = GetLayoutBoxByElementId("scroller"); auto* scrollable_area = To<LayoutBoxModelObject>(scroller)->GetScrollableArea(); @@ -795,6 +796,11 @@ TEST_P(MAYBE_PaintLayerScrollableAreaTest, ScrollWithLocalAttachmentBackgroundInScrollingContents) { + if (RuntimeEnabledFeatures::CompositeScrollAfterPaintEnabled()) { + // TODO(crbug.com/1414885): Fix this test. + return; + } + SetBodyInnerHTML(R"HTML( <style> #scroller { @@ -816,7 +822,11 @@ scroller->ComputeBackgroundPaintLocationIfComposited()); EXPECT_EQ(kBackgroundPaintInContentsSpace, scroller->GetBackgroundPaintLocation()); - EXPECT_TRUE(UsesCompositedScrolling(scroller)); + if (RuntimeEnabledFeatures::CompositeScrollAfterPaintEnabled()) { + EXPECT_FALSE(UsesCompositedScrolling(scroller)); + } else { + EXPECT_TRUE(UsesCompositedScrolling(scroller)); + } // Programmatically changing the scroll offset. scrollable_area->SetScrollOffset(ScrollOffset(0, 1), @@ -1071,7 +1081,7 @@ <div id='scroller'><div id='scrolled'></div></div> )HTML"); - auto* scroller = GetLayoutObjectByElementId("scroller"); + auto* scroller = GetLayoutBoxByElementId("scroller"); auto* scrollable_area = To<LayoutBoxModelObject>(scroller)->GetScrollableArea(); @@ -1119,7 +1129,7 @@ <div id='scroller'><div id='scrolled'></div></div> )HTML"); - auto* scroller = GetLayoutObjectByElementId("scroller"); + auto* scroller = GetLayoutBoxByElementId("scroller"); auto* scrollable_area = To<LayoutBoxModelObject>(scroller)->GetScrollableArea(); @@ -1147,10 +1157,9 @@ <div style="width: 10px; height: 700px; background: lightblue"></div> </div> )HTML"); - auto* scroller = - To<LayoutBoxModelObject>(GetLayoutObjectByElementId("scroller")); + auto* scroller = GetLayoutBoxByElementId("scroller"); auto* scrollable_area = scroller->GetScrollableArea(); - auto* sticky = To<LayoutBoxModelObject>(GetLayoutObjectByElementId("sticky")); + auto* sticky = GetLayoutBoxByElementId("sticky"); EXPECT_EQ(&sticky->FirstFragment().LocalBorderBoxProperties().Transform(), sticky->FirstFragment().PaintProperties()->StickyTranslation()); @@ -1381,7 +1390,7 @@ </div> )HTML"); - EXPECT_TRUE(UsesCompositedScrolling(GetLayoutObjectByElementId("scroller"))); + EXPECT_TRUE(UsesCompositedScrolling(GetLayoutBoxByElementId("scroller"))); } class PaintLayerScrollableAreaTestLowEndPlatform @@ -1413,7 +1422,7 @@ </div> )HTML"); - EXPECT_TRUE(UsesCompositedScrolling(GetLayoutObjectByElementId("scroller"))); + EXPECT_TRUE(UsesCompositedScrolling(GetLayoutBoxByElementId("scroller"))); } TEST_P(MAYBE_PaintLayerScrollableAreaTest, SetSnapContainerDataNeedsUpdate) { @@ -1433,11 +1442,11 @@ </div> )HTML"); - auto* first_scroller = GetLayoutObjectByElementId("first_scroller"); + auto* first_scroller = GetLayoutBoxByElementId("first_scroller"); auto* first_scrollable_area = To<LayoutBoxModelObject>(first_scroller)->GetScrollableArea(); - auto* second_scroller = GetLayoutObjectByElementId("second_scroller"); + auto* second_scroller = GetLayoutBoxByElementId("second_scroller"); auto* second_scrollable_area = To<LayoutBoxModelObject>(second_scroller)->GetScrollableArea();
diff --git a/third_party/blink/renderer/core/paint/paint_layer_test.cc b/third_party/blink/renderer/core/paint/paint_layer_test.cc index 980771c4..5b132e3 100644 --- a/third_party/blink/renderer/core/paint/paint_layer_test.cc +++ b/third_party/blink/renderer/core/paint/paint_layer_test.cc
@@ -121,7 +121,7 @@ PaintLayer* content_layer = GetPaintLayerByElementId("content"); const auto& fragment = content_layer->GetLayoutObject().FirstFragment(); EXPECT_EQ(PhysicalOffset(), content_layer->LocationWithoutPositionOffset()); - if (RuntimeEnabledFeatures::UnifiedScrollPaintingEnabled()) { + if (RuntimeEnabledFeatures::CompositeScrollAfterPaintEnabled()) { EXPECT_EQ(gfx::Rect(0, 0, 2000, 2000), fragment.GetContentsCullRect().Rect()); } else { @@ -138,7 +138,7 @@ content_layer->ContainingLayer()->PixelSnappedScrolledContentOffset()); EXPECT_FALSE(scroll_layer->SelfNeedsRepaint()); - if (RuntimeEnabledFeatures::UnifiedScrollPaintingEnabled()) { + if (RuntimeEnabledFeatures::CompositeScrollAfterPaintEnabled()) { EXPECT_EQ(gfx::Rect(0, 0, 2000, 2000), fragment.GetContentsCullRect().Rect()); EXPECT_FALSE(content_layer->SelfNeedsRepaint());
diff --git a/third_party/blink/renderer/core/paint/timing/image_paint_timing_detector_test.cc b/third_party/blink/renderer/core/paint/timing/image_paint_timing_detector_test.cc index c60da0d..23cd062 100644 --- a/third_party/blink/renderer/core/paint/timing/image_paint_timing_detector_test.cc +++ b/third_party/blink/renderer/core/paint/timing/image_paint_timing_detector_test.cc
@@ -1241,8 +1241,10 @@ TEST_P(ImagePaintTimingDetectorTest, LargestImagePaint_Detached_Frame) { #if BUILDFLAG(IS_ANDROID) - if (RuntimeEnabledFeatures::SolidColorLayersEnabled()) { - // TODO(crbug.com/1353921): This test is flaky on Android. Fix it. + if (RuntimeEnabledFeatures::SolidColorLayersEnabled() || + RuntimeEnabledFeatures::CompositeScrollAfterPaintEnabled()) { + // TODO(crbug.com/1353921, crbug.com/1414885): + // This test is flaky on Android. Fix it. // https://chrome-swarming.appspot.com/task?id=60c68038be22f011 // The first EXPECT_EQ(0u, events.size()) below failed. return;
diff --git a/third_party/blink/renderer/core/style/build.gni b/third_party/blink/renderer/core/style/build.gni index c174c385..a88e867 100644 --- a/third_party/blink/renderer/core/style/build.gni +++ b/third_party/blink/renderer/core/style/build.gni
@@ -39,8 +39,6 @@ "grid_enums.h", "grid_length.h", "grid_position.h", - "grid_positions_resolver.cc", - "grid_positions_resolver.h", "grid_track_list.cc", "grid_track_list.h", "grid_track_size.h",
diff --git a/third_party/blink/renderer/core/style/computed_style.h b/third_party/blink/renderer/core/style/computed_style.h index 0a98265f..31ee4653 100644 --- a/third_party/blink/renderer/core/style/computed_style.h +++ b/third_party/blink/renderer/core/style/computed_style.h
@@ -95,6 +95,7 @@ class FilterOperations; class Font; class Hyphenation; +class LayoutBox; class LayoutTheme; class Longhand; class NinePieceImage;
diff --git a/third_party/blink/renderer/core/style/grid_area.h b/third_party/blink/renderer/core/style/grid_area.h index 71b46a0..417a611 100644 --- a/third_party/blink/renderer/core/style/grid_area.h +++ b/third_party/blink/renderer/core/style/grid_area.h
@@ -33,7 +33,7 @@ #include "base/check_op.h" #include "base/dcheck_is_on.h" -#include "third_party/blink/renderer/core/style/grid_positions_resolver.h" +#include "third_party/blink/renderer/core/style/grid_enums.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h" #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" #include "third_party/blink/renderer/platform/wtf/hash_map.h"
diff --git a/third_party/blink/renderer/core/style/grid_positions_resolver.cc b/third_party/blink/renderer/core/style/grid_positions_resolver.cc deleted file mode 100644 index 09f941b..0000000 --- a/third_party/blink/renderer/core/style/grid_positions_resolver.cc +++ /dev/null
@@ -1,577 +0,0 @@ -// Copyright 2014 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "third_party/blink/renderer/core/style/grid_positions_resolver.h" - -#include <algorithm> -#include "third_party/blink/renderer/core/style/computed_style.h" -#include "third_party/blink/renderer/core/style/grid_area.h" - -namespace blink { - -static inline GridTrackSizingDirection DirectionFromSide( - GridPositionSide side) { - return side == kColumnStartSide || side == kColumnEndSide ? kForColumns - : kForRows; -} - -static inline String ImplicitNamedGridLineForSide(const String& line_name, - GridPositionSide side) { - return line_name + ((side == kColumnStartSide || side == kRowStartSide) - ? "-start" - : "-end"); -} - -NamedLineCollection::NamedLineCollection( - const ComputedStyle& grid_container_style, - const String& named_line, - GridTrackSizingDirection track_direction, - wtf_size_t last_line, - wtf_size_t auto_repeat_tracks_count, - bool is_subgridded_to_parent) - : last_line_(last_line), - auto_repeat_total_tracks_(auto_repeat_tracks_count) { - const bool is_for_columns = track_direction == kForColumns; - const ComputedGridTrackList& computed_grid_track_list = - is_for_columns ? grid_container_style.GridTemplateColumns() - : grid_container_style.GridTemplateRows(); - is_standalone_grid_ = - computed_grid_track_list.axis_type == GridAxisType::kStandaloneAxis; - - // Line names from the container style are valid when the grid axis type is a - // standalone grid or the axis is a subgrid and the parent is a grid. See: - // https://www.w3.org/TR/css-grid-2/#subgrid-listing - bool are_named_lines_valid = true; - if (RuntimeEnabledFeatures::LayoutNGSubgridEnabled()) { - are_named_lines_valid = is_subgridded_to_parent || is_standalone_grid_; - } - - const NamedGridLinesMap& grid_line_names = - computed_grid_track_list.named_grid_lines; - const NamedGridLinesMap& auto_repeat_grid_line_names = - computed_grid_track_list.auto_repeat_named_grid_lines; - const NamedGridLinesMap& implicit_grid_line_names = - is_for_columns ? grid_container_style.ImplicitNamedGridColumnLines() - : grid_container_style.ImplicitNamedGridRowLines(); - - if (!grid_line_names.empty() && are_named_lines_valid) { - auto it = grid_line_names.find(named_line); - named_lines_indexes_ = it == grid_line_names.end() ? nullptr : &it->value; - } - - if (!auto_repeat_grid_line_names.empty() && are_named_lines_valid) { - auto it = auto_repeat_grid_line_names.find(named_line); - auto_repeat_named_lines_indexes_ = - it == auto_repeat_grid_line_names.end() ? nullptr : &it->value; - } - - if (!implicit_grid_line_names.empty()) { - auto it = implicit_grid_line_names.find(named_line); - implicit_named_lines_indexes_ = - it == implicit_grid_line_names.end() ? nullptr : &it->value; - } - - insertion_point_ = computed_grid_track_list.auto_repeat_insertion_point; - auto_repeat_track_list_length_ = - computed_grid_track_list.auto_repeat_track_sizes.size(); -} - -bool NamedLineCollection::HasExplicitNamedLines() { - return named_lines_indexes_ || auto_repeat_named_lines_indexes_; -} - -bool NamedLineCollection::HasNamedLines() { - return HasExplicitNamedLines() || implicit_named_lines_indexes_; -} - -bool NamedLineCollection::Contains(wtf_size_t line) { - CHECK(HasNamedLines()); - - if (line > last_line_) { - return false; - } - - auto find = [](const Vector<wtf_size_t>* indexes, wtf_size_t line) { - return indexes && indexes->Find(line) != kNotFound; - }; - - if (find(implicit_named_lines_indexes_, line)) { - return true; - } - - if (auto_repeat_track_list_length_ == 0 || line < insertion_point_) { - return find(named_lines_indexes_, line); - } - - DCHECK(auto_repeat_total_tracks_); - - if (line > insertion_point_ + auto_repeat_total_tracks_) { - return find(named_lines_indexes_, line - (auto_repeat_total_tracks_ - 1)); - } - - if (line == insertion_point_) { - return find(named_lines_indexes_, line) || - find(auto_repeat_named_lines_indexes_, 0); - } - - if (line == insertion_point_ + auto_repeat_total_tracks_) { - return find(auto_repeat_named_lines_indexes_, - auto_repeat_track_list_length_) || - find(named_lines_indexes_, insertion_point_ + 1); - } - - wtf_size_t auto_repeat_index_in_first_repetition = - (line - insertion_point_) % auto_repeat_track_list_length_; - if (!auto_repeat_index_in_first_repetition && - find(auto_repeat_named_lines_indexes_, auto_repeat_track_list_length_)) { - return true; - } - return find(auto_repeat_named_lines_indexes_, - auto_repeat_index_in_first_repetition); -} - -wtf_size_t NamedLineCollection::FirstExplicitPosition() { - DCHECK(HasExplicitNamedLines()); - - wtf_size_t first_line = 0; - - // If it is an standalone grid and there is no auto repeat(), there must be - // some named line outside, return the 1st one. Also return it if it precedes - // the auto-repeat(). - if ((is_standalone_grid_ && auto_repeat_track_list_length_ == 0) || - (named_lines_indexes_ && - named_lines_indexes_->at(first_line) <= insertion_point_)) { - return named_lines_indexes_->at(first_line); - } - - // Return the 1st named line inside the auto repeat(), if any. - if (auto_repeat_named_lines_indexes_) { - return auto_repeat_named_lines_indexes_->at(first_line) + insertion_point_; - } - - // The 1st named line must be after the auto repeat(). - return named_lines_indexes_->at(first_line) + auto_repeat_total_tracks_ - 1; -} - -wtf_size_t NamedLineCollection::FirstPosition() { - CHECK(HasNamedLines()); - - if (!implicit_named_lines_indexes_) { - return FirstExplicitPosition(); - } - - wtf_size_t first_line = 0; - if (!HasExplicitNamedLines()) { - return implicit_named_lines_indexes_->at(first_line); - } - - return std::min(FirstExplicitPosition(), - implicit_named_lines_indexes_->at(first_line)); -} - -static void InitialAndFinalPositionsFromStyle( - const ComputedStyle& grid_item_style, - GridTrackSizingDirection track_direction, - GridPosition& initial_position, - GridPosition& final_position) { - const bool is_for_columns = track_direction == kForColumns; - initial_position = is_for_columns ? grid_item_style.GridColumnStart() - : grid_item_style.GridRowStart(); - final_position = is_for_columns ? grid_item_style.GridColumnEnd() - : grid_item_style.GridRowEnd(); - - // We must handle the placement error handling code here instead of in the - // StyleAdjuster because we don't want to overwrite the specified values. - if (initial_position.IsSpan() && final_position.IsSpan()) { - final_position.SetAutoPosition(); - } - - // If the grid item has an automatic position and a grid span for a named line - // in a given dimension, instead treat the grid span as one. - if (initial_position.IsAuto() && final_position.IsSpan() && - !final_position.NamedGridLine().IsNull()) { - final_position.SetSpanPosition(1, g_null_atom); - } - if (final_position.IsAuto() && initial_position.IsSpan() && - !initial_position.NamedGridLine().IsNull()) { - initial_position.SetSpanPosition(1, g_null_atom); - } -} - -static wtf_size_t LookAheadForNamedGridLine( - int start, - wtf_size_t number_of_lines, - wtf_size_t grid_last_line, - NamedLineCollection& lines_collection) { - DCHECK(number_of_lines); - - // Only implicit lines on the search direction are assumed to have the given - // name, so we can start to look from first line. - // See: https://drafts.csswg.org/css-grid/#grid-placement-span-int - wtf_size_t end = std::max(start, 0); - - if (!lines_collection.HasNamedLines()) { - end = std::max(end, grid_last_line + 1); - return end + number_of_lines - 1; - } - - for (; number_of_lines; ++end) { - if (end > grid_last_line || lines_collection.Contains(end)) { - number_of_lines--; - } - } - - DCHECK(end); - return end - 1; -} - -static int LookBackForNamedGridLine(int end, - wtf_size_t number_of_lines, - int grid_last_line, - NamedLineCollection& lines_collection) { - DCHECK(number_of_lines); - - // Only implicit lines on the search direction are assumed to have the given - // name, so we can start to look from last line. - // See: https://drafts.csswg.org/css-grid/#grid-placement-span-int - int start = std::min(end, grid_last_line); - - if (!lines_collection.HasNamedLines()) { - start = std::min(start, -1); - return start - number_of_lines + 1; - } - - for (; number_of_lines; --start) { - if (start < 0 || lines_collection.Contains(start)) { - number_of_lines--; - } - } - - return start + 1; -} - -static GridSpan DefiniteGridSpanWithNamedSpanAgainstOpposite( - int opposite_line, - const GridPosition& position, - GridPositionSide side, - int last_line, - NamedLineCollection& lines_collection) { - int start, end; - if (side == kRowStartSide || side == kColumnStartSide) { - start = LookBackForNamedGridLine(opposite_line - 1, position.SpanPosition(), - last_line, lines_collection); - end = opposite_line; - } else { - start = opposite_line; - end = LookAheadForNamedGridLine(opposite_line + 1, position.SpanPosition(), - last_line, lines_collection); - } - - return GridSpan::UntranslatedDefiniteGridSpan(start, end); -} - -wtf_size_t GridPositionsResolver::ExplicitGridColumnCount( - const ComputedStyle& grid_container_style, - wtf_size_t auto_repeat_tracks_count, - wtf_size_t subgrid_span_size) { - if (subgrid_span_size != kNotFound) { - return subgrid_span_size; - } - - const auto& track_list = - grid_container_style.GridTemplateColumns().track_sizes; - const wtf_size_t total_track_count = track_list.LegacyTrackList().size(); - - return std::min<wtf_size_t>( - std::max(total_track_count + auto_repeat_tracks_count, - grid_container_style.NamedGridAreaColumnCount()), - kGridMaxTracks); -} - -wtf_size_t GridPositionsResolver::ExplicitGridRowCount( - const ComputedStyle& grid_container_style, - wtf_size_t auto_repeat_tracks_count, - wtf_size_t subgrid_span_size) { - if (subgrid_span_size != kNotFound) { - return subgrid_span_size; - } - - const auto& track_list = grid_container_style.GridTemplateRows().track_sizes; - const wtf_size_t total_track_count = track_list.LegacyTrackList().size(); - - return std::min<wtf_size_t>( - std::max(total_track_count + auto_repeat_tracks_count, - grid_container_style.NamedGridAreaRowCount()), - kGridMaxTracks); -} - -static wtf_size_t ExplicitGridSizeForSide( - const ComputedStyle& grid_container_style, - GridPositionSide side, - wtf_size_t auto_repeat_tracks_count, - wtf_size_t subgrid_span_size) { - return (side == kColumnStartSide || side == kColumnEndSide) - ? GridPositionsResolver::ExplicitGridColumnCount( - grid_container_style, auto_repeat_tracks_count, - subgrid_span_size) - : GridPositionsResolver::ExplicitGridRowCount( - grid_container_style, auto_repeat_tracks_count, - subgrid_span_size); -} - -static GridSpan ResolveNamedGridLinePositionAgainstOppositePosition( - const ComputedStyle& grid_container_style, - int opposite_line, - const GridPosition& position, - wtf_size_t auto_repeat_tracks_count, - GridPositionSide side, - wtf_size_t subgrid_span_size) { - DCHECK(position.IsSpan()); - DCHECK(!position.NamedGridLine().IsNull()); - // Negative positions are not allowed per the specification and should have - // been handled during parsing. - DCHECK_GT(position.SpanPosition(), 0); - - wtf_size_t last_line = ExplicitGridSizeForSide( - grid_container_style, side, auto_repeat_tracks_count, subgrid_span_size); - NamedLineCollection lines_collection( - grid_container_style, position.NamedGridLine(), DirectionFromSide(side), - last_line, auto_repeat_tracks_count); - return DefiniteGridSpanWithNamedSpanAgainstOpposite( - opposite_line, position, side, last_line, lines_collection); -} - -static GridSpan DefiniteGridSpanWithSpanAgainstOpposite( - int opposite_line, - const GridPosition& position, - GridPositionSide side) { - wtf_size_t position_offset = position.SpanPosition(); - if (side == kColumnStartSide || side == kRowStartSide) { - return GridSpan::UntranslatedDefiniteGridSpan( - opposite_line - position_offset, opposite_line); - } - - return GridSpan::UntranslatedDefiniteGridSpan( - opposite_line, opposite_line + position_offset); -} - -static GridSpan ResolveGridPositionAgainstOppositePosition( - const ComputedStyle& grid_container_style, - int opposite_line, - const GridPosition& position, - GridPositionSide side, - wtf_size_t auto_repeat_tracks_count, - wtf_size_t subgrid_span_size) { - if (position.IsAuto()) { - if (side == kColumnStartSide || side == kRowStartSide) { - return GridSpan::UntranslatedDefiniteGridSpan(opposite_line - 1, - opposite_line); - } - return GridSpan::UntranslatedDefiniteGridSpan(opposite_line, - opposite_line + 1); - } - - DCHECK(position.IsSpan()); - DCHECK_GT(position.SpanPosition(), 0); - - if (!position.NamedGridLine().IsNull()) { - // span 2 'c' -> we need to find the appropriate grid line before / after - // our opposite position. - return ResolveNamedGridLinePositionAgainstOppositePosition( - grid_container_style, opposite_line, position, auto_repeat_tracks_count, - side, subgrid_span_size); - } - - return DefiniteGridSpanWithSpanAgainstOpposite(opposite_line, position, side); -} - -static wtf_size_t SpanSizeFromPositions(const GridPosition& initial_position, - const GridPosition& final_position) { - // This method will only be used when both positions need to be resolved - // against the opposite one. - DCHECK(initial_position.ShouldBeResolvedAgainstOppositePosition() && - final_position.ShouldBeResolvedAgainstOppositePosition()); - - if (initial_position.IsAuto() && final_position.IsAuto()) { - return 1; - } - - const GridPosition& span_position = - initial_position.IsSpan() ? initial_position : final_position; - DCHECK(span_position.IsSpan() && span_position.SpanPosition()); - return span_position.SpanPosition(); -} - -wtf_size_t GridPositionsResolver::SpanSizeForAutoPlacedItem( - const ComputedStyle& grid_item_style, - GridTrackSizingDirection track_direction) { - GridPosition initial_position, final_position; - InitialAndFinalPositionsFromStyle(grid_item_style, track_direction, - initial_position, final_position); - return SpanSizeFromPositions(initial_position, final_position); -} - -static int ResolveNamedGridLinePositionFromStyle( - const ComputedStyle& grid_container_style, - const GridPosition& position, - GridPositionSide side, - wtf_size_t auto_repeat_tracks_count, - wtf_size_t subgrid_span_size) { - DCHECK(!position.NamedGridLine().IsNull()); - - wtf_size_t last_line = ExplicitGridSizeForSide( - grid_container_style, side, auto_repeat_tracks_count, subgrid_span_size); - NamedLineCollection lines_collection( - grid_container_style, position.NamedGridLine(), DirectionFromSide(side), - last_line, auto_repeat_tracks_count); - - if (position.IsPositive()) { - return LookAheadForNamedGridLine(0, abs(position.IntegerPosition()), - last_line, lines_collection); - } - - return LookBackForNamedGridLine(last_line, abs(position.IntegerPosition()), - last_line, lines_collection); -} - -static int ResolveGridPositionFromStyle( - const ComputedStyle& grid_container_style, - const GridPosition& position, - GridPositionSide side, - wtf_size_t auto_repeat_tracks_count, - bool is_subgridded_to_parent, - wtf_size_t subgrid_span_size) { - switch (position.GetType()) { - case kExplicitPosition: { - DCHECK(position.IntegerPosition()); - - if (!position.NamedGridLine().IsNull()) { - return ResolveNamedGridLinePositionFromStyle( - grid_container_style, position, side, auto_repeat_tracks_count, - subgrid_span_size); - } - - // Handle <integer> explicit position. - if (position.IsPositive()) { - return position.IntegerPosition() - 1; - } - - wtf_size_t resolved_position = abs(position.IntegerPosition()) - 1; - wtf_size_t end_of_track = - ExplicitGridSizeForSide(grid_container_style, side, - auto_repeat_tracks_count, subgrid_span_size); - - return end_of_track - resolved_position; - } - case kNamedGridAreaPosition: { - // First attempt to match the grid area's edge to a named grid area: if - // there is a named line with the name ''<custom-ident>-start (for - // grid-*-start) / <custom-ident>-end'' (for grid-*-end), contributes the - // first such line to the grid item's placement. - String named_grid_line = position.NamedGridLine(); - DCHECK(!position.NamedGridLine().IsNull()); - - wtf_size_t last_line = - ExplicitGridSizeForSide(grid_container_style, side, - auto_repeat_tracks_count, subgrid_span_size); - NamedLineCollection implicit_lines( - grid_container_style, - ImplicitNamedGridLineForSide(named_grid_line, side), - DirectionFromSide(side), last_line, auto_repeat_tracks_count); - if (implicit_lines.HasNamedLines()) { - return implicit_lines.FirstPosition(); - } - - // Otherwise, if there is a named line with the specified name, - // contributes the first such line to the grid item's placement. - NamedLineCollection explicit_lines( - grid_container_style, named_grid_line, DirectionFromSide(side), - last_line, auto_repeat_tracks_count, is_subgridded_to_parent); - if (explicit_lines.HasNamedLines()) { - return explicit_lines.FirstPosition(); - } - - // If none of the above works specs mandate to assume that all the lines - // in the implicit grid have this name. - return last_line + 1; - } - case kAutoPosition: - case kSpanPosition: - // 'auto' and span depend on the opposite position for resolution (e.g. - // grid-row: auto / 1 or grid-column: span 3 / "myHeader"). - NOTREACHED(); - return 0; - } - NOTREACHED(); - return 0; -} - -GridSpan GridPositionsResolver::ResolveGridPositionsFromStyle( - const ComputedStyle& grid_container_style, - const ComputedStyle& grid_item_style, - GridTrackSizingDirection track_direction, - wtf_size_t auto_repeat_tracks_count, - bool is_subgridded_to_parent, - wtf_size_t subgrid_span_size) { - GridPosition initial_position, final_position; - InitialAndFinalPositionsFromStyle(grid_item_style, track_direction, - initial_position, final_position); - - const bool initial_should_be_resolved_against_opposite_position = - initial_position.ShouldBeResolvedAgainstOppositePosition(); - const bool final_should_be_resolved_against_opposite_position = - final_position.ShouldBeResolvedAgainstOppositePosition(); - - if (initial_should_be_resolved_against_opposite_position && - final_should_be_resolved_against_opposite_position) { - // We can't get our grid positions without running the auto placement - // algorithm. - return GridSpan::IndefiniteGridSpan( - SpanSizeFromPositions(initial_position, final_position)); - } - - const GridPositionSide initial_side = - (track_direction == kForColumns) ? kColumnStartSide : kRowStartSide; - const GridPositionSide final_side = - (track_direction == kForColumns) ? kColumnEndSide : kRowEndSide; - - if (initial_should_be_resolved_against_opposite_position) { - // Infer the position from the final_position position ('auto / 1' or 'span - // 2 / 3' case). - int end_line = ResolveGridPositionFromStyle( - grid_container_style, final_position, final_side, - auto_repeat_tracks_count, is_subgridded_to_parent, subgrid_span_size); - return ResolveGridPositionAgainstOppositePosition( - grid_container_style, end_line, initial_position, initial_side, - auto_repeat_tracks_count, subgrid_span_size); - } - - if (final_should_be_resolved_against_opposite_position) { - // Infer our position from the initial_position position ('1 / auto' or '3 / - // span 2' case). - int start_line = ResolveGridPositionFromStyle( - grid_container_style, initial_position, initial_side, - auto_repeat_tracks_count, is_subgridded_to_parent, subgrid_span_size); - return ResolveGridPositionAgainstOppositePosition( - grid_container_style, start_line, final_position, final_side, - auto_repeat_tracks_count, subgrid_span_size); - } - - int start_line = ResolveGridPositionFromStyle( - grid_container_style, initial_position, initial_side, - auto_repeat_tracks_count, is_subgridded_to_parent, subgrid_span_size); - int end_line = ResolveGridPositionFromStyle( - grid_container_style, final_position, final_side, - auto_repeat_tracks_count, is_subgridded_to_parent, subgrid_span_size); - - if (end_line < start_line) { - std::swap(end_line, start_line); - } else if (end_line == start_line) { - end_line = start_line + 1; - } - - return GridSpan::UntranslatedDefiniteGridSpan(start_line, end_line); -} - -} // namespace blink
diff --git a/third_party/blink/renderer/core/style/grid_positions_resolver.h b/third_party/blink/renderer/core/style/grid_positions_resolver.h deleted file mode 100644 index 3774d87..0000000 --- a/third_party/blink/renderer/core/style/grid_positions_resolver.h +++ /dev/null
@@ -1,79 +0,0 @@ -// Copyright 2014 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_GRID_POSITIONS_RESOLVER_H_ -#define THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_GRID_POSITIONS_RESOLVER_H_ - -#include "third_party/blink/renderer/core/style/grid_enums.h" -#include "third_party/blink/renderer/core/style/grid_position.h" -#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" - -namespace blink { - -struct GridSpan; -class LayoutBox; -class ComputedStyle; - -class NamedLineCollection { - public: - NamedLineCollection(const ComputedStyle&, - const String& named_line, - GridTrackSizingDirection, - wtf_size_t last_line, - wtf_size_t auto_repeat_tracks_count, - bool is_subgridded_to_parent = false); - - bool HasNamedLines(); - wtf_size_t FirstPosition(); - - bool Contains(wtf_size_t line); - - private: - bool HasExplicitNamedLines(); - wtf_size_t FirstExplicitPosition(); - const Vector<wtf_size_t>* named_lines_indexes_ = nullptr; - const Vector<wtf_size_t>* auto_repeat_named_lines_indexes_ = nullptr; - const Vector<wtf_size_t>* implicit_named_lines_indexes_ = nullptr; - - bool is_standalone_grid_; - wtf_size_t insertion_point_; - wtf_size_t last_line_; - wtf_size_t auto_repeat_total_tracks_; - wtf_size_t auto_repeat_track_list_length_; - - NamedLineCollection(const NamedLineCollection&) = delete; - NamedLineCollection& operator=(const NamedLineCollection&) = delete; -}; - -// This is a utility class with all the code related to grid items positions -// resolution. -class GridPositionsResolver { - DISALLOW_NEW(); - - public: - static wtf_size_t ExplicitGridColumnCount( - const ComputedStyle&, - wtf_size_t auto_repeat_columns_count, - wtf_size_t subgrid_span_size = kNotFound); - - static wtf_size_t ExplicitGridRowCount( - const ComputedStyle&, - wtf_size_t auto_repeat_rows_count, - wtf_size_t subgrid_span_size = kNotFound); - - static wtf_size_t SpanSizeForAutoPlacedItem(const ComputedStyle&, - GridTrackSizingDirection); - - static GridSpan ResolveGridPositionsFromStyle( - const ComputedStyle&, - const ComputedStyle&, - GridTrackSizingDirection, - wtf_size_t auto_repeat_tracks_count, - bool is_subgridded_to_parent = false, - wtf_size_t subgrid_span_size = kNotFound); -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_GRID_POSITIONS_RESOLVER_H_
diff --git a/third_party/blink/renderer/core/style/grid_track_list.cc b/third_party/blink/renderer/core/style/grid_track_list.cc index 38892bc6..047cce6f 100644 --- a/third_party/blink/renderer/core/style/grid_track_list.cc +++ b/third_party/blink/renderer/core/style/grid_track_list.cc
@@ -10,10 +10,12 @@ NGGridTrackRepeater::NGGridTrackRepeater(wtf_size_t repeat_index, wtf_size_t repeat_size, wtf_size_t repeat_count, + wtf_size_t line_name_indices_count, RepeatType repeat_type) : repeat_index(repeat_index), repeat_size(repeat_size), repeat_count(repeat_count), + line_name_indices_count(line_name_indices_count), repeat_type(repeat_type) {} String NGGridTrackRepeater::ToString() const { @@ -22,6 +24,8 @@ builder.AppendNumber<wtf_size_t>(repeat_index); builder.Append("], [RepeatSize: "); builder.AppendNumber<wtf_size_t>(repeat_size); + builder.Append("], [LineNameIndicesCount: "); + builder.AppendNumber<wtf_size_t>(line_name_indices_count); builder.Append("], [RepeatCount: "); switch (repeat_type) { case RepeatType::kNoRepeat: @@ -45,8 +49,8 @@ repeat_count == other.repeat_count && repeat_type == other.repeat_type; } -wtf_size_t NGGridTrackList::RepeatCount(const wtf_size_t index, - const wtf_size_t auto_value) const { +wtf_size_t NGGridTrackList::RepeatCount(wtf_size_t index, + wtf_size_t auto_value) const { DCHECK_LT(index, RepeaterCount()); if (index == auto_repeater_index_) { return auto_value; @@ -54,27 +58,31 @@ return repeaters_[index].repeat_count; } -wtf_size_t NGGridTrackList::RepeatIndex(const wtf_size_t index) const { +wtf_size_t NGGridTrackList::RepeatIndex(wtf_size_t index) const { // `repeat_index` is used for sizes, which subgrids don't have. DCHECK(!IsSubgriddedAxis()); DCHECK_LT(index, RepeaterCount()); return repeaters_[index].repeat_index; } -wtf_size_t NGGridTrackList::RepeatSize(const wtf_size_t index) const { +wtf_size_t NGGridTrackList::RepeatSize(wtf_size_t index) const { DCHECK_LT(index, RepeaterCount()); return repeaters_[index].repeat_size; } +wtf_size_t NGGridTrackList::LineNameIndicesCount(wtf_size_t index) const { + DCHECK_LT(index, RepeaterCount()); + return repeaters_[index].line_name_indices_count; +} + NGGridTrackRepeater::RepeatType NGGridTrackList::RepeatType( - const wtf_size_t index) const { + wtf_size_t index) const { DCHECK_LT(index, RepeaterCount()); return repeaters_[index].repeat_type; } -const GridTrackSize& NGGridTrackList::RepeatTrackSize( - const wtf_size_t index, - const wtf_size_t n) const { +const GridTrackSize& NGGridTrackList::RepeatTrackSize(wtf_size_t index, + wtf_size_t n) const { // Subgrids don't have track sizes associated with them. DCHECK(!IsSubgriddedAxis()); DCHECK_LT(index, RepeaterCount()); @@ -111,7 +119,8 @@ const Vector<GridTrackSize, 1>& repeater_track_sizes, NGGridTrackRepeater::RepeatType repeat_type, wtf_size_t repeat_count, - wtf_size_t repeat_number_of_lines) { + wtf_size_t repeat_number_of_lines, + wtf_size_t line_name_indices_count) { // Non-subgrid repeaters always have sizes associated with them, while // subgrids repeaters never do, as sizes will come from the parent grid. DCHECK(!IsSubgriddedAxis() || repeater_track_sizes.empty()); @@ -136,7 +145,13 @@ if (repeat_size > AvailableTrackCount() / repeat_count) { return false; } - track_count_without_auto_repeat_ += repeat_size * repeat_count; + // Don't increment `track_count_without_auto_repeat_` for subgridded + // axis. This is used to determine how many tracks are defined for + // placement, but this doesn't apply for subgrid, as it is based entirely + // on the subgrid span size, which should be used instead. + if (!IsSubgriddedAxis()) { + track_count_without_auto_repeat_ += repeat_size * repeat_count; + } break; case NGGridTrackRepeater::RepeatType::kAutoFill: case NGGridTrackRepeater::RepeatType::kAutoFit: // Intentional Fallthrough. @@ -149,7 +164,7 @@ } repeaters_.emplace_back(repeater_track_sizes_.size(), repeat_size, - repeat_count, repeat_type); + repeat_count, line_name_indices_count, repeat_type); if (!IsSubgriddedAxis()) { repeater_track_sizes_.AppendVector(repeater_track_sizes); }
diff --git a/third_party/blink/renderer/core/style/grid_track_list.h b/third_party/blink/renderer/core/style/grid_track_list.h index fdd3715..fb7417b 100644 --- a/third_party/blink/renderer/core/style/grid_track_list.h +++ b/third_party/blink/renderer/core/style/grid_track_list.h
@@ -27,11 +27,12 @@ NGGridTrackRepeater(wtf_size_t repeat_index, wtf_size_t repeat_size, wtf_size_t repeat_count, + wtf_size_t line_name_indices_count, RepeatType repeat_type); String ToString() const; bool operator==(const NGGridTrackRepeater& o) const; - // |NGGridTrackList| will store the sizes for each track in this repeater + // `NGGridTrackList` will store the sizes for each track in this repeater // consecutively in a single vector for all repeaters; this index specifies // the position of the first track size that belongs to this repeater. wtf_size_t repeat_index; @@ -39,6 +40,13 @@ wtf_size_t repeat_size; // Amount of times the group of tracks are repeated. wtf_size_t repeat_count; + // Count of line name indices defined in this repeater. This is different than + // the count of line names. for instance, a definition of + // `repeat(auto-fit, [a b], [c d])` would have a line name count of 4, but the + // line name indices count would be 2 (0 and 1). This is necessary for round + // tripping repeaters, as we need to know how many indices have line names. + // TODO(kschmi): Merge this with `repeat_size`. + wtf_size_t line_name_indices_count; // Type of repetition. RepeatType repeat_type; }; @@ -48,19 +56,19 @@ NGGridTrackList() = default; NGGridTrackList(const NGGridTrackList& other) = default; - // Returns the repeat count of the repeater at |index|, or |auto_value| + // Returns the repeat count of the repeater at `index`, or `auto_value` // if the repeater is auto. - wtf_size_t RepeatCount(const wtf_size_t index, - const wtf_size_t auto_value) const; - // Returns the position of the first track size in the repeater at |index|. - wtf_size_t RepeatIndex(const wtf_size_t index) const; - // Returns the number of tracks in the repeater at |index|. - wtf_size_t RepeatSize(const wtf_size_t index) const; - // Returns the repeat type of the repeater at |index|. - NGGridTrackRepeater::RepeatType RepeatType(const wtf_size_t index) const; - // Returns the size of the |n|-th specified track of the repeater at |index|. - const GridTrackSize& RepeatTrackSize(const wtf_size_t index, - const wtf_size_t n) const; + wtf_size_t RepeatCount(wtf_size_t index, wtf_size_t auto_value) const; + // Returns the position of the first track size in the repeater at `index`. + wtf_size_t RepeatIndex(wtf_size_t index) const; + // Returns the number of tracks in the repeater at `index`. + wtf_size_t RepeatSize(wtf_size_t index) const; + // Returns the number line name indices defined at a given repeater `index`. + wtf_size_t LineNameIndicesCount(wtf_size_t index) const; + // Returns the repeat type of the repeater at `index`. + NGGridTrackRepeater::RepeatType RepeatType(wtf_size_t index) const; + // Returns the size of the `n`-th specified track of the repeater at `index`. + const GridTrackSize& RepeatTrackSize(wtf_size_t index, wtf_size_t n) const; // Returns the count of repeaters. wtf_size_t RepeaterCount() const; @@ -79,7 +87,8 @@ NGGridTrackRepeater::RepeatType repeat_type = NGGridTrackRepeater::RepeatType::kNoRepeat, wtf_size_t repeat_count = 1u, - wtf_size_t repeat_number_of_lines = 1u); + wtf_size_t repeat_number_of_lines = 1u, + wtf_size_t line_name_indices_count = 0u); // Returns true if this list contains an auto repeater. bool HasAutoRepeater() const; // Returns true if this is a subgridded track list. @@ -106,7 +115,7 @@ // the same repeater group are stored consecutively. Vector<GridTrackSize, 1> repeater_track_sizes_; - // The index of the automatic repeater, if there is one; |kInvalidRangeIndex| + // The index of the automatic repeater, if there is one; `kInvalidRangeIndex` // otherwise. wtf_size_t auto_repeater_index_{kNotFound};
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc index f968f8c4..d851783 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc
@@ -4051,6 +4051,32 @@ } } +void AXObjectCacheImpl::GetImagesToAnnotate( + ui::AXTreeUpdate& update, + std::vector<ui::AXNodeData*>& nodes) { + for (auto& node : update.nodes) { + AXObject* src = ObjectFromAXID(node.id); + if (!src || src->IsDetached() || !src->AccessibilityIsIncludedInTree() || + (src->AccessibilityIsIgnored() && + !node.HasState(ax::mojom::blink::State::kFocusable))) { + continue; + } + + if (src->IsImage()) { + nodes.push_back(&node); + // This else clause matches links/documents because we would like to find + // an image that is in the near-descendant subtree of the link/document, + // since that image may be semantically representative of that + // link/document. See FindExactlyOneInnerImageInMaxDepthThree (not in + // this file), which is used by the caller of this method to find such + // an image. + } else if ((src->IsLink() || ui::IsPlatformDocument(node.role)) && + node.GetNameFrom() != ax::mojom::blink::NameFrom::kAttribute) { + nodes.push_back(&node); + } + } +} + bool AXObjectCacheImpl::AddPendingEvent(const ui::AXEvent& event, bool insert_at_beginning) { if (insert_at_beginning)
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h index 281d720..7363c55 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h +++ b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h
@@ -477,6 +477,9 @@ bool& had_load_complete_messages, bool& need_to_send_location_changes) override; + void GetImagesToAnnotate(ui::AXTreeUpdate& updates, + std::vector<ui::AXNodeData*>& nodes) override; + void ClearDirtyObjectsAndPendingEvents() override { dirty_objects_.clear(); pending_events_.clear();
diff --git a/third_party/blink/renderer/modules/exported/web_ax_context.cc b/third_party/blink/renderer/modules/exported/web_ax_context.cc index 2f71bef..008335c 100644 --- a/third_party/blink/renderer/modules/exported/web_ax_context.cc +++ b/third_party/blink/renderer/modules/exported/web_ax_context.cc
@@ -110,6 +110,11 @@ had_load_complete_messages, need_to_send_location_changes); } +void WebAXContext::GetImagesToAnnotate(ui::AXTreeUpdate& updates, + std::vector<ui::AXNodeData*>& nodes) { + private_->GetAXObjectCache().GetImagesToAnnotate(updates, nodes); +} + void WebAXContext::ClearDirtyObjectsAndPendingEvents() { if (!HasActiveDocument()) { return;
diff --git a/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.cc b/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.cc index ca0e5f9..4f6d0e4c 100644 --- a/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.cc +++ b/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.cc
@@ -161,6 +161,91 @@ .NearestScrollTranslationNode(); } +bool PaintArtifactCompositor::NeedsCompositedScrolling( + const TransformPaintPropertyNode& scroll_translation) const { + DCHECK(scroll_translation.ScrollNode()); + if (scroll_translation.HasDirectCompositingReasons()) { + return true; + } + if (RuntimeEnabledFeatures::CompositeScrollAfterPaintEnabled()) { + auto it = scroll_translation_nodes_.find(&scroll_translation); + if (it != scroll_translation_nodes_.end()) { + return it->value; + } + } + return false; +} + +bool PaintArtifactCompositor::ComputeNeedsCompositedScrolling( + const PaintArtifact& artifact, + Vector<PaintChunk>::const_iterator chunk_cursor) const { + // The chunk must be a ScrollHitTest chunk which contains no display items. + DCHECK(chunk_cursor->hit_test_data); + DCHECK(chunk_cursor->hit_test_data->scroll_translation); + DCHECK_EQ(chunk_cursor->size(), 0u); + const auto& scroll_translation = + *chunk_cursor->hit_test_data->scroll_translation; + DCHECK(scroll_translation.ScrollNode()); + // This function should be called before scroll_translation is inserted into + // scroll_translation_nodes_. + DCHECK(!scroll_translation_nodes_.Contains(&scroll_translation)); + + if (!RuntimeEnabledFeatures::CompositeScrollAfterPaintEnabled()) { + return scroll_translation.HasDirectCompositingReasons(); + } + + if (scroll_translation.HasDirectCompositingReasons()) { + return true; + } + if (RuntimeEnabledFeatures::PreferNonCompositedScrollingEnabled()) { + return false; + } + // Don't automatically composite non-user-scrollable scrollers. + if (!scroll_translation.ScrollNode()->UserScrollableHorizontal() && + !scroll_translation.ScrollNode()->UserScrollableVertical()) { + return false; + } + if (lcd_text_preference_ != LCDTextPreference::kStronglyPreferred || + chunk_cursor + 1 == artifact.PaintChunks().end()) { + return true; + } + // Normally the next chunk contains the scrolling background which normally + // defines the opaqueness of the scrolling contents. If it has an opaque rect + // covering the whole scrolling contents, we can use composited scrolling + // without losing LCD text. + const PaintChunk& next_chunk = *(chunk_cursor + 1); + return &next_chunk.properties.Transform().Unalias() == &scroll_translation && + &next_chunk.properties.Clip().Unalias() == + scroll_translation.ScrollNode()->OverflowClipNode() && + &next_chunk.properties.Effect().Unalias() == + &chunk_cursor->properties.Effect().Unalias() && + next_chunk.rect_known_to_be_opaque.Contains( + scroll_translation.ScrollNode()->ContentsRect()); +} + +PendingLayer::CompositingType PaintArtifactCompositor::ChunkCompositingType( + const PaintArtifact& artifact, + const PaintChunk& chunk) const { + if (chunk.hit_test_data && chunk.hit_test_data->scroll_translation && + NeedsCompositedScrolling(*chunk.hit_test_data->scroll_translation)) { + return PendingLayer::kScrollHitTestLayer; + } + if (chunk.size() == 1) { + const auto& item = artifact.GetDisplayItemList()[chunk.begin_index]; + if (item.IsForeignLayer()) { + return PendingLayer::kForeignLayer; + } + if (const auto* scrollbar = DynamicTo<ScrollbarDisplayItem>(item)) { + if (const auto* scroll_translation = scrollbar->ScrollTranslation()) { + if (NeedsCompositedScrolling(*scroll_translation)) { + return PendingLayer::kScrollbarLayer; + } + } + } + } + return PendingLayer::kOther; +} + namespace { cc::Layer* ForeignLayer(const PaintChunk& chunk, @@ -420,28 +505,34 @@ // O(p) due to copying the chunk list. Subtotal: O((qd + p)d) = O(qd^2 + pd) // Assuming p > d, the total complexity would be O(pqd + qd^2 + pd) = O(pqd) while (chunk_cursor != artifact->PaintChunks().end()) { - // Track painted ScrollTranslation nodes. with ScrollUnification enabled, - // PaintArtifactCompositor::Update uses this to know which - // ScrollTranslation nodes we need to create composited Transform nodes - // for. - if (chunk_cursor->hit_test_data && - chunk_cursor->hit_test_data->scroll_translation) { - scroll_translation_nodes_.insert( - chunk_cursor->hit_test_data->scroll_translation.get()); - } // Look at the effect node of the next chunk. There are 3 possible cases: // A. The next chunk belongs to the current group but no subgroup. // B. The next chunk does not belong to the current group. // C. The next chunk belongs to some subgroup of the current group. const auto& chunk_effect = chunk_cursor->properties.Effect().Unalias(); if (&chunk_effect == ¤t_group) { + // Track painted ScrollTranslation nodes and their composited scrolling + // status. With ScrollUnification enabled, Update() also uses this to + // know which ScrollTranslation nodes we need to create composited + // Transform nodes for. + if (chunk_cursor->hit_test_data && + chunk_cursor->hit_test_data->scroll_translation) { + scroll_translation_nodes_.insert( + chunk_cursor->hit_test_data->scroll_translation.get(), + ComputeNeedsCompositedScrolling(*artifact, chunk_cursor)); + } pending_layers_.emplace_back(artifact, *chunk_cursor); + pending_layers_.back().SetCompositingType( + ChunkCompositingType(*artifact, *chunk_cursor)); ++chunk_cursor; // force_draws_content doesn't apply to pending layers that require own // layer, specifically scrollbar layers, foreign layers, scroll hit // testing layers. - if (pending_layers_.back().ChunkRequiresOwnLayer()) + if (pending_layers_.back().ChunkRequiresOwnLayer()) { + // TODO(crbug.com/1414885): conditionally composite ScrollHitTest and + // scrollbar in CompositeScrollAfterPaint. continue; + } } else { const EffectPaintPropertyNode* subgroup = StrictUnaliasedChildOfAlongPath(current_group, chunk_effect);
diff --git a/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.h b/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.h index d75ddd1e..78d23a3 100644 --- a/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.h +++ b/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.h
@@ -307,6 +307,14 @@ CompositorElementId& mask_isolation_id, CompositorElementId& mask_effect_id) final; + bool NeedsCompositedScrolling( + const TransformPaintPropertyNode& scroll_translation) const final; + bool ComputeNeedsCompositedScrolling( + const PaintArtifact&, + Vector<PaintChunk>::const_iterator chunk_cursor) const; + PendingLayer::CompositingType ChunkCompositingType(const PaintArtifact&, + const PaintChunk&) const; + static void UpdateRenderSurfaceForEffects( cc::EffectTree&, const cc::LayerList&, @@ -341,9 +349,10 @@ class OldPendingLayerMatcher; PendingLayers pending_layers_; - // ScrollTranslationNodes of the PaintArtifact which are painted. + // ScrollTranslationNodes of the PaintArtifact that are painted. // This member variable is only used in PaintArtifactCompositor::Update. - HashSet<const TransformPaintPropertyNode*> scroll_translation_nodes_; + // The value indicates if the scroll should be composited. + HashMap<const TransformPaintPropertyNode*, bool> scroll_translation_nodes_; friend class StubChromeClientForCAP; friend class PaintArtifactCompositorTest;
diff --git a/third_party/blink/renderer/platform/graphics/compositing/pending_layer.cc b/third_party/blink/renderer/platform/graphics/compositing/pending_layer.cc index 25cd700..98435ac6 100644 --- a/third_party/blink/renderer/platform/graphics/compositing/pending_layer.cc +++ b/third_party/blink/renderer/platform/graphics/compositing/pending_layer.cc
@@ -23,23 +23,6 @@ namespace { -bool IsCompositedScrollHitTest(const PaintChunk& chunk) { - if (!chunk.hit_test_data) - return false; - const auto scroll_translation = chunk.hit_test_data->scroll_translation; - return scroll_translation && - scroll_translation->HasDirectCompositingReasons(); -} - -bool IsCompositedScrollbar(const DisplayItem& item) { - if (const auto* scrollbar = DynamicTo<ScrollbarDisplayItem>(item)) { - const auto* scroll_translation = scrollbar->ScrollTranslation(); - return scroll_translation && - scroll_translation->HasDirectCompositingReasons(); - } - return false; -} - // Snap |bounds| if within floating-point numeric limits of an integral rect. void PreserveNearIntegralBounds(gfx::RectF& bounds) { constexpr float kTolerance = 1e-5f; @@ -64,8 +47,7 @@ is_solid_color_(first_chunk.background_color.is_solid_color), chunks_(std::move(artifact), first_chunk), property_tree_state_( - first_chunk.properties.GetPropertyTreeState().Unalias()), - compositing_type_(kOther) { + first_chunk.properties.GetPropertyTreeState().Unalias()) { DCHECK(!ChunkRequiresOwnLayer() || first_chunk.size() <= 1u); // Though text_known_to_be_on_opaque_background is only meaningful when // has_text is true, we expect text_known_to_be_on_opaque_background to be @@ -79,17 +61,6 @@ } } rect_known_to_be_opaque_.Intersect(bounds_); - - if (IsCompositedScrollHitTest(first_chunk)) { - compositing_type_ = kScrollHitTestLayer; - } else if (first_chunk.size()) { - const auto& first_display_item = FirstDisplayItem(); - if (first_display_item.IsForeignLayer()) { - compositing_type_ = kForeignLayer; - } else if (IsCompositedScrollbar(first_display_item)) { - compositing_type_ = kScrollbarLayer; - } - } } gfx::Vector2dF PendingLayer::LayerOffset() const { @@ -138,14 +109,18 @@ std::unique_ptr<JSONObject> PendingLayer::ToJSON() const { std::unique_ptr<JSONObject> result = std::make_unique<JSONObject>(); + result->SetString("debug_name", DebugName()); result->SetArray("bounds", RectAsJSONArray(bounds_)); result->SetArray("rect_known_to_be_opaque", RectAsJSONArray(rect_known_to_be_opaque_)); - result->SetObject("property_tree_state", GetPropertyTreeState().ToJSON()); + result->SetBoolean("text_known_to_be_on_opaque_background", + text_known_to_be_on_opaque_background_); + result->SetString("property_tree_state", GetPropertyTreeState().ToString()); result->SetArray("offset_of_decomposited_transforms", VectorAsJSONArray(offset_of_decomposited_transforms_)); result->SetArray("paint_chunks", chunks_.ToJSON()); result->SetBoolean("draws_content", DrawsContent()); + result->SetBoolean("is_solid_color", is_solid_color_); return result; }
diff --git a/third_party/blink/renderer/platform/graphics/compositing/pending_layer.h b/third_party/blink/renderer/platform/graphics/compositing/pending_layer.h index 302daef..ba4a6c67 100644 --- a/third_party/blink/renderer/platform/graphics/compositing/pending_layer.h +++ b/third_party/blink/renderer/platform/graphics/compositing/pending_layer.h
@@ -198,7 +198,7 @@ gfx::Vector2dF offset_of_decomposited_transforms_; PaintPropertyChangeType change_of_decomposited_transforms_ = PaintPropertyChangeType::kUnchanged; - CompositingType compositing_type_; + CompositingType compositing_type_ = kOther; // This is set to non-null after layerization if ChunkRequiresOwnLayer() or // UsesSolidColorLayer() is true.
diff --git a/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.cc b/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.cc index 669b600..cd0dc61 100644 --- a/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.cc +++ b/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.cc
@@ -612,7 +612,18 @@ compositor_node.transform_id = scroll_translation_node.CcNodeId(new_sequence_number_); compositor_node.is_composited = - scroll_translation_node.HasDirectCompositingReasons(); + client_.NeedsCompositedScrolling(scroll_translation_node); + if (RuntimeEnabledFeatures::CompositeScrollAfterPaintEnabled() && + !RuntimeEnabledFeatures::PreferNonCompositedScrollingEnabled() && + !compositor_node.is_composited && + compositor_node.main_thread_scrolling_reasons == + cc::MainThreadScrollingReason::kNotScrollingOnMain) { + // TODO(crbug.com/1414885): We can't distinguish kNotOpaqueForTextAndLCDText + // and kCantPaintScrollingBackgroundAndLCDText here. We should probably + // merge the two reasons for CompositeScrollAfterPaint. + compositor_node.main_thread_scrolling_reasons = + cc::MainThreadScrollingReason::kNotOpaqueForTextAndLCDText; + } scroll_node.SetCcNodeId(new_sequence_number_, id);
diff --git a/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.h b/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.h index 596c398..137df80 100644 --- a/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.h +++ b/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.h
@@ -46,6 +46,8 @@ bool needs_layer, CompositorElementId& mask_isolation_id, CompositorElementId& mask_effect_id) = 0; + virtual bool NeedsCompositedScrolling( + const TransformPaintPropertyNode& scroll_translation) const = 0; }; // Mutates a cc property tree to reflect Blink paint property tree
diff --git a/third_party/blink/renderer/platform/graphics/paint/cull_rect.cc b/third_party/blink/renderer/platform/graphics/paint/cull_rect.cc index b5c4fcf..adeb5d4 100644 --- a/third_party/blink/renderer/platform/graphics/paint/cull_rect.cc +++ b/third_party/blink/renderer/platform/graphics/paint/cull_rect.cc
@@ -92,7 +92,7 @@ if (disable_expansion) { return false; } - if (!RuntimeEnabledFeatures::UnifiedScrollPaintingEnabled() && + if (!RuntimeEnabledFeatures::CompositeScrollAfterPaintEnabled() && // Don't expand for non-composited scrolling. !scroll_translation.HasDirectCompositingReasons()) { return false; @@ -363,7 +363,7 @@ const gfx::Vector2dF& delta, const TransformPaintPropertyNode& scroll_translation) { if (!scroll_translation.ScrollNode() || - (!RuntimeEnabledFeatures::UnifiedScrollPaintingEnabled() && + (!RuntimeEnabledFeatures::CompositeScrollAfterPaintEnabled() && !scroll_translation.HasDirectCompositingReasons())) { return !delta.IsZero(); }
diff --git a/third_party/blink/renderer/platform/graphics/paint/cull_rect_test.cc b/third_party/blink/renderer/platform/graphics/paint/cull_rect_test.cc index 3821822..61fb0a4c 100644 --- a/third_party/blink/renderer/platform/graphics/paint/cull_rect_test.cc +++ b/third_party/blink/renderer/platform/graphics/paint/cull_rect_test.cc
@@ -15,9 +15,9 @@ class CullRectTest : public testing::Test, public testing::WithParamInterface<bool>, - private ScopedUnifiedScrollPaintingForTest { + private ScopedCompositeScrollAfterPaintForTest { protected: - CullRectTest() : ScopedUnifiedScrollPaintingForTest(GetParam()) {} + CullRectTest() : ScopedCompositeScrollAfterPaintForTest(GetParam()) {} bool ApplyPaintProperties( CullRect& cull_rect, @@ -139,7 +139,7 @@ auto& scroll_translation = state.Transform(); CullRect cull_rect(gfx::Rect(0, 0, 50, 100)); - if (RuntimeEnabledFeatures::UnifiedScrollPaintingEnabled()) { + if (RuntimeEnabledFeatures::CompositeScrollAfterPaintEnabled()) { // Same as ApplyScrollTranslationPartialScrollingContents. EXPECT_TRUE(ApplyScrollTranslation(cull_rect, scroll_translation)); EXPECT_EQ(gfx::Rect(20, 1010, 7030, 7000), cull_rect.Rect()); @@ -234,7 +234,7 @@ auto& scroll_translation = state.Transform(); CullRect cull_rect(gfx::Rect(0, 0, 50, 100)); - if (RuntimeEnabledFeatures::UnifiedScrollPaintingEnabled()) { + if (RuntimeEnabledFeatures::CompositeScrollAfterPaintEnabled()) { // Same as ApplyScrollTranslationWholeScrollingContents. EXPECT_TRUE(ApplyScrollTranslation(cull_rect, scroll_translation)); EXPECT_EQ(gfx::Rect(20, 10, 2000, 2000), cull_rect.Rect());
diff --git a/third_party/blink/renderer/platform/graphics/paint/paint_property_node.h b/third_party/blink/renderer/platform/graphics/paint/paint_property_node.h index b954b21..136fe4f 100644 --- a/third_party/blink/renderer/platform/graphics/paint/paint_property_node.h +++ b/third_party/blink/renderer/platform/graphics/paint/paint_property_node.h
@@ -237,10 +237,13 @@ std::unique_ptr<JSONObject> ToJSONBase() const { auto json = std::make_unique<JSONObject>(); - if (Parent()) + json->SetString("this", String::Format("%p", this)); + if (Parent()) { json->SetString("parent", String::Format("%p", Parent())); - if (IsParentAlias()) + } + if (IsParentAlias()) { json->SetBoolean("is_alias", true); + } if (NodeChanged() != PaintPropertyChangeType::kUnchanged) { json->SetString("changed", PaintPropertyChangeTypeToString(NodeChanged()));
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5 index 9f0ae46..c42d017 100644 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -627,6 +627,9 @@ base_feature: "none", }, { + name: "CompositeScrollAfterPaint", + }, + { name: "ComputedAccessibilityInfo", status: "experimental", base_feature: "none", @@ -3397,9 +3400,6 @@ name: "UnexposedTaskIds", base_feature: "none", }, - { - name: "UnifiedScrollPainting", - }, // This is a reverse OT used for a phased deprecation, on desktop // https://crbug.com/1071424 {
diff --git a/third_party/blink/renderer/platform/testing/paint_test_configurations.h b/third_party/blink/renderer/platform/testing/paint_test_configurations.h index 8ebef51..bf066c7 100644 --- a/third_party/blink/renderer/platform/testing/paint_test_configurations.h +++ b/third_party/blink/renderer/platform/testing/paint_test_configurations.h
@@ -19,21 +19,21 @@ kUnderInvalidationChecking = 1 << 0, kScrollUnification = 1 << 1, kSolidColorLayers = 1 << 2, - kUnifiedScrollPainting = 1 << 3, + kCompositeScrollAfterPaint = 1 << 3, }; class PaintTestConfigurations : public testing::WithParamInterface<unsigned>, private ScopedPaintUnderInvalidationCheckingForTest, private ScopedSolidColorLayersForTest, - private ScopedUnifiedScrollPaintingForTest { + private ScopedCompositeScrollAfterPaintForTest { public: PaintTestConfigurations() : ScopedPaintUnderInvalidationCheckingForTest(GetParam() & kUnderInvalidationChecking), ScopedSolidColorLayersForTest(GetParam() & kSolidColorLayers), - ScopedUnifiedScrollPaintingForTest(GetParam() & - kUnifiedScrollPainting) { + ScopedCompositeScrollAfterPaintForTest(GetParam() & + kCompositeScrollAfterPaint) { if (GetParam() & kScrollUnification) { feature_list_.InitAndEnableFeature(::features::kScrollUnification); } else { @@ -55,13 +55,17 @@ base::test::ScopedFeatureList feature_list_; }; -// For now this has only one configuration, but can be extended in the future -// to include more configurations. +// Note: If a new test fails with kCompositeScrollAfterPaint, please add the +// following at the beginning of the test to skip it temporarily: +// if (RuntimeEnabledFeatures::CompositeScrollAfterPaintEnabled()) { +// // TODO(crbug.com/1414885): Fix this test. +// return; +// } #define INSTANTIATE_PAINT_TEST_SUITE_P(test_class) \ INSTANTIATE_TEST_SUITE_P( \ All, test_class, \ ::testing::Values(0, kScrollUnification, kSolidColorLayers, \ - kUnifiedScrollPainting)) + kScrollUnification | kCompositeScrollAfterPaint)) } // namespace blink
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index 9dd7feb..8c81caf 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -1715,7 +1715,6 @@ crbug.com/1232504 [ Win ] external/wpt/html/semantics/embedded-content/media-elements/ready-states/autoplay-hidden.optional.html [ Timeout ] crbug.com/1234199 [ Linux ] external/wpt/html/semantics/embedded-content/the-object-element/object-events.html [ Crash Failure Pass Timeout ] crbug.com/1234199 [ Mac ] external/wpt/html/semantics/embedded-content/the-object-element/object-events.html [ Crash Failure Pass Timeout ] -crbug.com/1394141 [ Win ] external/wpt/html/semantics/disabled-elements/event-propagate-disabled.tentative.html [ Failure Timeout ] crbug.com/1395815 external/wpt/html/semantics/forms/the-input-element/range-tick-marks-02.html [ Failure ] crbug.com/1004760 [ Mac ] external/wpt/html/semantics/embedded-content/media-elements/ready-states/autoplay-hidden.optional.html [ Timeout ] crbug.com/1191547 external/wpt/html/semantics/forms/the-label-element/proxy-modifier-click-to-associated-element.tentative.html [ Timeout ] @@ -3510,7 +3509,6 @@ crbug.com/618969 external/wpt/css/css-grid/subgrid/grid-gap-larger-002.html [ Failure ] crbug.com/618969 external/wpt/css/css-grid/subgrid/grid-gap-normal-001.html [ Failure ] crbug.com/618969 external/wpt/css/css-grid/subgrid/grid-gap-smaller-001.html [ Failure ] -crbug.com/618969 external/wpt/css/css-grid/subgrid/grid-template-computed-nogrid.html [ Failure ] crbug.com/618969 external/wpt/css/css-grid/subgrid/independent-formatting-context.html [ Failure ] crbug.com/618969 external/wpt/css/css-grid/subgrid/item-percentage-height-001.html [ Failure ] crbug.com/618969 external/wpt/css/css-grid/subgrid/line-names-007.html [ Failure ] @@ -5025,6 +5023,11 @@ # Sheriff 2021-06-14 crbug.com/1219499 [ Release Win ] external/wpt/websockets/Create-blocked-port.any.html?wpt_flags=h2 [ Failure Pass Timeout ] +# Waiting for resolution on disabled fieldsets in https://github.com/whatwg/html/issues/5886 +# We want to make fieldsets not disableable due to crbug.com/1422096 and crbug.com/1422547 +# which breaks this exhaustive test, but it will be updated after whatwg/html resolution. +crbug.com/588760 external/wpt/html/semantics/disabled-elements/event-propagate-disabled.tentative.html [ Failure ] + # Sheriff 2021-06-15 crbug.com/1220007 [ Linux ] fullscreen/full-screen-iframe-allowed-video.html [ Failure Pass Timeout ] @@ -5608,7 +5611,6 @@ # Sheriff 2022-04-05 crbug.com/1313282 inspector-protocol/input/dispatchMouseEvent.js [ Failure Pass Timeout ] crbug.com/1254163 [ Mac10.13 ] ietestcenter/css3/bordersbackgrounds/background-attachment-local-scrolling.htm [ Failure ] -crbug.com/1313396 [ Linux ] external/wpt/dom/events/Event-dispatch-on-disabled-elements.html [ Failure Pass ] crbug.com/1194945 external/wpt/dom/events/scrolling/overscroll-event-fired-to-scrolled-element.html [ Failure Pass ] crbug.com/1244896 fast/mediacapturefromelement/CanvasCaptureMediaStream-set-size-too-large.html [ Failure Pass Timeout ]
diff --git a/third_party/blink/web_tests/external/wpt/browsing-topics/browsing-topics-permissions-policy-default.tentative.https.sub.html b/third_party/blink/web_tests/external/wpt/browsing-topics/browsing-topics-permissions-policy-default.tentative.https.sub.html index a7c5a95..884ad92 100644 --- a/third_party/blink/web_tests/external/wpt/browsing-topics/browsing-topics-permissions-policy-default.tentative.https.sub.html +++ b/third_party/blink/web_tests/external/wpt/browsing-topics/browsing-topics-permissions-policy-default.tentative.https.sub.html
@@ -2,6 +2,7 @@ <body> <script src=/resources/testharness.js></script> <script src=/resources/testharnessreport.js></script> + <script src=/browsing-topics/resources/navigation-header-util.sub.js></script> <script src=/browsing-topics/resources/permissions-policy-util.sub.js></script> <script> 'use strict'; @@ -37,5 +38,18 @@ let topics_header = await response.text(); assert_equals(topics_header, ""); }, header + 'allows the \'Sec-Browsing-Topics\' header to be sent for the cross-origin topics fetch request.'); + + async_test(t => { + test_topics_iframe_navigation_header( + t, /*has_browsing_topics_attribute=*/true, /*is_same_origin=*/true, + expect_topics_header_available); + }, header + ' allows the \'Sec-Browsing-Topics\' header to be sent for the same-origin iframe navigation request.'); + + async_test(t => { + test_topics_iframe_navigation_header( + t, /*has_browsing_topics_attribute=*/true, /*is_same_origin=*/false, + expect_topics_header_available); + }, header + ' allows the \'Sec-Browsing-Topics\' header to be sent for the cross-origin iframe navigation request.'); + </script> </body>
diff --git a/third_party/blink/web_tests/external/wpt/browsing-topics/browsing-topics-permissions-policy-none.tentative.https.sub.html b/third_party/blink/web_tests/external/wpt/browsing-topics/browsing-topics-permissions-policy-none.tentative.https.sub.html index 7d33f3b..2f80daa2 100644 --- a/third_party/blink/web_tests/external/wpt/browsing-topics/browsing-topics-permissions-policy-none.tentative.https.sub.html +++ b/third_party/blink/web_tests/external/wpt/browsing-topics/browsing-topics-permissions-policy-none.tentative.https.sub.html
@@ -2,6 +2,7 @@ <body> <script src=/resources/testharness.js></script> <script src=/resources/testharnessreport.js></script> + <script src=/browsing-topics/resources/navigation-header-util.sub.js></script> <script src=/browsing-topics/resources/permissions-policy-util.sub.js></script> <script> 'use strict'; @@ -42,5 +43,17 @@ let topics_header = await response.text(); assert_equals(topics_header, "NO_TOPICS_HEADER"); }, header + 'disallows the \'Sec-Browsing-Topics\' header to be sent for the cross-origin topics fetch request.'); + + async_test(t => { + test_topics_iframe_navigation_header( + t, /*has_browsing_topics_attribute=*/true, /*is_same_origin=*/true, + expect_topics_header_unavailable); + }, header + ' disallows the \'Sec-Browsing-Topics\' header to be sent for the same-origin iframe navigation request.'); + + async_test(t => { + test_topics_iframe_navigation_header( + t, /*has_browsing_topics_attribute=*/true, /*is_same_origin=*/false, + expect_topics_header_unavailable); + }, header + ' disallows the \'Sec-Browsing-Topics\' header to be sent for the cross-origin iframe navigation request.'); </script> </body>
diff --git a/third_party/blink/web_tests/external/wpt/browsing-topics/browsing-topics-permissions-policy-self.tentative.https.sub.html b/third_party/blink/web_tests/external/wpt/browsing-topics/browsing-topics-permissions-policy-self.tentative.https.sub.html index 7647998..60126679 100644 --- a/third_party/blink/web_tests/external/wpt/browsing-topics/browsing-topics-permissions-policy-self.tentative.https.sub.html +++ b/third_party/blink/web_tests/external/wpt/browsing-topics/browsing-topics-permissions-policy-self.tentative.https.sub.html
@@ -2,6 +2,7 @@ <body> <script src=/resources/testharness.js></script> <script src=/resources/testharnessreport.js></script> + <script src=/browsing-topics/resources/navigation-header-util.sub.js></script> <script src=/browsing-topics/resources/permissions-policy-util.sub.js></script> <script> 'use strict'; @@ -49,5 +50,17 @@ let topics_header = await response.text(); assert_equals(topics_header, "NO_TOPICS_HEADER"); }, header + 'disallows the \'Sec-Browsing-Topics\' header to be sent for the redirect of a topics fetch request, where the redirect has a cross-origin URL.'); + + async_test(t => { + test_topics_iframe_navigation_header( + t, /*has_browsing_topics_attribute=*/true, /*is_same_origin=*/true, + expect_topics_header_available); + }, header + ' allows the \'Sec-Browsing-Topics\' header to be sent for the same-origin iframe navigation request.'); + + async_test(t => { + test_topics_iframe_navigation_header( + t, /*has_browsing_topics_attribute=*/true, /*is_same_origin=*/false, + expect_topics_header_unavailable); + }, header + ' disallows the \'Sec-Browsing-Topics\' header to be sent for the cross-origin iframe navigation request.'); </script> </body>
diff --git a/third_party/blink/web_tests/external/wpt/browsing-topics/iframe-topics-attribute-insecure-context.tentative.http.sub.html b/third_party/blink/web_tests/external/wpt/browsing-topics/iframe-topics-attribute-insecure-context.tentative.http.sub.html new file mode 100644 index 0000000..19c79e0 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/browsing-topics/iframe-topics-attribute-insecure-context.tentative.http.sub.html
@@ -0,0 +1,36 @@ +<!doctype html> +<body> + <script src=/resources/testharness.js></script> + <script src=/resources/testharnessreport.js></script> + <script src=/browsing-topics/resources/navigation-header-util.sub.js></script> + <script> + async_test(t => { + test_topics_iframe_navigation_header( + t, /*has_browsing_topics_attribute=*/true, /*is_same_origin=*/false, + expect_topics_header_unavailable); + }, 'test <iframe browsingtopics src=[url]></iframe> in an insecure context, where the browsingtopics attribute is set via IDL.'); + + async_test(t => { + const same_origin_src = '/browsing-topics/resources/check-topics-request-header-notify-parent.py'; + const cross_origin_src = 'https://{{domains[www]}}:{{ports[https][0]}}' + + same_origin_src; + + let frame = document.createElement('iframe'); + + window.addEventListener('message', t.step_func(function handler(evt) { + if (evt.source === frame.contentWindow) { + assert_equals(evt.data.topicsHeader, 'NO_TOPICS_HEADER'); + + document.body.removeChild(frame); + window.removeEventListener('message', handler); + t.done(); + } + })); + + document.body.appendChild(frame); + + frame.setAttribute("browsingtopics", "123"); + frame.src = cross_origin_src; + }, 'test <iframe browsingtopics src=[url]></iframe> in an insecure context, where the browsingtopics attribute is set via setAttribute().'); + </script> +</body>
diff --git a/third_party/blink/web_tests/external/wpt/browsing-topics/iframe-topics-attribute.tentative.https.html b/third_party/blink/web_tests/external/wpt/browsing-topics/iframe-topics-attribute.tentative.https.html new file mode 100644 index 0000000..b90f967 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/browsing-topics/iframe-topics-attribute.tentative.https.html
@@ -0,0 +1,19 @@ +<!doctype html> +<body> + <script src=/resources/testharness.js></script> + <script src=/resources/testharnessreport.js></script> + <script src=/browsing-topics/resources/navigation-header-util.sub.js></script> + <script> + async_test(t => { + test_topics_iframe_navigation_header( + t, /*has_browsing_topics_attribute=*/false, /*is_same_origin=*/false, + expect_topics_header_unavailable); + }, 'test <iframe src=[url]></iframe>'); + + async_test(t => { + test_topics_iframe_navigation_header( + t, /*has_browsing_topics_attribute=*/true, /*is_same_origin=*/false, + expect_topics_header_available); + }, 'test <iframe browsingtopics src=[url]></iframe>'); + </script> +</body>
diff --git a/third_party/blink/web_tests/external/wpt/browsing-topics/resources/check-topics-request-header-notify-parent.py b/third_party/blink/web_tests/external/wpt/browsing-topics/resources/check-topics-request-header-notify-parent.py new file mode 100644 index 0000000..98c77c2 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/browsing-topics/resources/check-topics-request-header-notify-parent.py
@@ -0,0 +1,18 @@ +def main(request, response): + """ + Returns an HTML response that notifies its parent frame the topics header + via postMessage + """ + + topics_header = request.headers.get(b"sec-browsing-topics", b"NO_TOPICS_HEADER") + + headers = [(b"Content-Type", b"text/html"), + (b"Access-Control-Allow-Origin", b"*")] + content = b''' +<script> + let parentOrOpener = window.opener || window.parent; + parentOrOpener.postMessage({ topicsHeader: '%s'}, "*"); +</script> +''' % (topics_header) + + return 200, headers, content
diff --git a/third_party/blink/web_tests/external/wpt/browsing-topics/resources/navigation-header-util.sub.js b/third_party/blink/web_tests/external/wpt/browsing-topics/resources/navigation-header-util.sub.js new file mode 100644 index 0000000..b3bec79 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/browsing-topics/resources/navigation-header-util.sub.js
@@ -0,0 +1,36 @@ +function test_topics_iframe_navigation_header( + test, has_browsing_topics_attribute, is_same_origin, expect_topics_header_available_func) { + const same_origin_src = '/browsing-topics/resources/check-topics-request-header-notify-parent.py'; + const cross_origin_src = 'https://{{domains[www]}}:{{ports[https][0]}}' + + same_origin_src; + + let frame = document.createElement('iframe'); + frame.src = is_same_origin ? same_origin_src : cross_origin_src; + + if (has_browsing_topics_attribute) { + frame.browsingTopics = true; + } + + window.addEventListener('message', test.step_func(function handler(evt) { + if (evt.source === frame.contentWindow) { + expect_topics_header_available_func(evt.data); + + document.body.removeChild(frame); + window.removeEventListener('message', handler); + test.done(); + } + })); + + document.body.appendChild(frame); +} + +function expect_topics_header_unavailable(data) { + assert_equals(data.topicsHeader, 'NO_TOPICS_HEADER'); +} + +function expect_topics_header_available(data) { + // An empty result indicates that the request was eligible for topics. + // Currently, the web-platform-tests framework does not support actually + // handling the topics request. + assert_equals(data.topicsHeader, ''); +} \ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/borders/discrete-no-interpolation.html b/third_party/blink/web_tests/external/wpt/css/CSS2/borders/discrete-no-interpolation.html new file mode 100644 index 0000000..0268b675 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/CSS2/borders/discrete-no-interpolation.html
@@ -0,0 +1,33 @@ +<!DOCTYPE html> +<link rel=author href="mailto:jarhar@chromium.org"> +<link rel=help href="https://github.com/w3c/csswg-drafts/issues/4441"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/interpolation-testcommon.js"></script> + +<body> +<script> +test_no_interpolation({ + property: 'border-left-style', + from: 'initial', + to: 'dotted' +}); + +test_no_interpolation({ + property: 'border-right-style', + from: 'initial', + to: 'dotted' +}); + +test_no_interpolation({ + property: 'border-top-style', + from: 'initial', + to: 'dotted' +}); + +test_no_interpolation({ + property: 'border-bottom-style', + from: 'initial', + to: 'dotted' +}); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-repeat/background-repeat-no-interpolation.html b/third_party/blink/web_tests/external/wpt/css/CSS2/floats-clear/clear-no-interpolation.html similarity index 88% copy from third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-repeat/background-repeat-no-interpolation.html copy to third_party/blink/web_tests/external/wpt/css/CSS2/floats-clear/clear-no-interpolation.html index a1a48d5..05db269e 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-repeat/background-repeat-no-interpolation.html +++ b/third_party/blink/web_tests/external/wpt/css/CSS2/floats-clear/clear-no-interpolation.html
@@ -8,8 +8,8 @@ <body> <script> test_no_interpolation({ - property: 'background-repeat', + property: 'clear', from: 'initial', - to: 'round' + to: 'both' }); </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-repeat/background-repeat-no-interpolation.html b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/border-collapse-no-interpolation.html similarity index 88% rename from third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-repeat/background-repeat-no-interpolation.html rename to third_party/blink/web_tests/external/wpt/css/CSS2/tables/border-collapse-no-interpolation.html index a1a48d5..800cc68 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-repeat/background-repeat-no-interpolation.html +++ b/third_party/blink/web_tests/external/wpt/css/CSS2/tables/border-collapse-no-interpolation.html
@@ -8,8 +8,8 @@ <body> <script> test_no_interpolation({ - property: 'background-repeat', + property: 'border-collapse', from: 'initial', - to: 'round' + to: 'collapse' }); </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/animations/discrete-no-interpolation.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/animations/discrete-no-interpolation.html new file mode 100644 index 0000000..d3d3421 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/animations/discrete-no-interpolation.html
@@ -0,0 +1,45 @@ +<!DOCTYPE html> +<link rel=author href="mailto:jarhar@chromium.org"> +<link rel=help href="https://github.com/w3c/csswg-drafts/issues/4441"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/interpolation-testcommon.js"></script> + +<body> +<script> +test_no_interpolation({ + property: 'background-attachment', + from: 'initial', + to: 'fixed' +}); + +test_no_interpolation({ + property: 'background-blend-mode', + from: 'initial', + to: 'overlay' +}); + +test_no_interpolation({ + property: 'background-clip', + from: 'initial', + to: 'content-box' +}); + +test_no_interpolation({ + property: 'background-origin', + from: 'initial', + to: 'border-box' +}); + +test_no_interpolation({ + property: 'background-repeat', + from: 'initial', + to: 'round' +}); + +test_no_interpolation({ + property: 'border-image-repeat', + from: 'initial', + to: 'round' +}); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-repeat/background-repeat-no-interpolation.html b/third_party/blink/web_tests/external/wpt/css/css-break/animation/break-no-interpolation.html similarity index 63% copy from third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-repeat/background-repeat-no-interpolation.html copy to third_party/blink/web_tests/external/wpt/css/css-break/animation/break-no-interpolation.html index a1a48d5..8a7bf7a 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-repeat/background-repeat-no-interpolation.html +++ b/third_party/blink/web_tests/external/wpt/css/css-break/animation/break-no-interpolation.html
@@ -8,8 +8,20 @@ <body> <script> test_no_interpolation({ - property: 'background-repeat', + property: 'break-after', from: 'initial', - to: 'round' + to: 'avoid' +}); + +test_no_interpolation({ + property: 'break-before', + from: 'initial', + to: 'avoid' +}); + +test_no_interpolation({ + property: 'break-inside', + from: 'initial', + to: 'avoid' }); </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/parsing/grid-template-columns-computed-nogrid.html b/third_party/blink/web_tests/external/wpt/css/css-grid/parsing/grid-template-columns-computed-nogrid.html index 11b0393..b1f80a7 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/parsing/grid-template-columns-computed-nogrid.html +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/parsing/grid-template-columns-computed-nogrid.html
@@ -26,6 +26,7 @@ test_computed_value("grid-template-columns", "1px repeat(auto-fill, 2px) 3px"); test_computed_value("grid-template-columns", "1px repeat(auto-fit, 2px) 3px"); test_computed_value("grid-template-columns", "1px [a] repeat(1, 2px 3px) [b] 4px"); +test_computed_value("grid-template-columns", "1px [a] repeat(2, 2px 3px) [b] 4px"); test_computed_value("grid-template-columns", "1px [a] repeat(auto-fill, 2px 3px) [b] 4px"); test_computed_value("grid-template-columns", "1px [a] repeat(auto-fit, 2px 3px) [b] 4px"); test_computed_value("grid-template-columns", "1px [a] repeat(1, [b] 2px [c]) [d] 3px"); @@ -33,6 +34,8 @@ test_computed_value("grid-template-columns", "1px [a] repeat(auto-fit, [b] 2px [c]) [d] 3px"); test_computed_value("grid-template-columns", "[a] 1px repeat(1, 2px [b] 3px) 4px [d]"); test_computed_value("grid-template-columns", "[a] 1px repeat(auto-fill, 2px [b] 3px) 4px [d]"); +test_computed_value("grid-template-columns", "[a] 1px 4px [d]"); +test_computed_value("grid-template-columns", "[a] 1px repeat(auto-fill, 2px [b] 3px) [d] 4px"); test_computed_value("grid-template-columns", "[a] 1px repeat(auto-fit, 2px [b] 3px) 4px [d]"); test_computed_value("grid-template-rows", "100% [a] repeat(1, [b] 200% [c]) [d] 300%"); test_computed_value("grid-template-rows", "100% [a] repeat(auto-fill, [b] 200% [c]) [d] 300%"); @@ -40,4 +43,9 @@ test_computed_value("grid-template-columns", "[a] 1em repeat(1, 2em [b] 3em) 4em [d]", "[a] 1px repeat(1, 2px [b] 3px) 4px [d]"); test_computed_value("grid-template-columns", "[a] 1em repeat(auto-fill, 2em [b] 3em) 4em [d]", "[a] 1px repeat(auto-fill, 2px [b] 3px) 4px [d]"); test_computed_value("grid-template-columns", "[a] 1em repeat(auto-fit, 2em [b] 3em) 4em [d]", "[a] 1px repeat(auto-fit, 2px [b] 3px) 4px [d]"); +test_computed_value("grid-template-columns", "repeat(1, 2px [a] 3px) [b] repeat(auto-fill, [c] 200% [d]) [e] 300%"); +test_computed_value("grid-template-columns", "[a] repeat(auto-fill, [b] 200% [c]) repeat(1, 2px [d] 3px) [e] 300%"); +test_computed_value("grid-template-columns", "repeat(1, [a] 2px [b] 3px) [b] repeat(auto-fill, [c] 200% [d]) [e] 300%"); +test_computed_value("grid-template-columns", "[a] repeat(auto-fill, [b] 200% [c]) repeat(1, 2px [d] 3px [e]) [f] 300%"); +test_computed_value("grid-template-columns", "[a] 1px [b c] repeat(auto-fill, [d] 200% [e f]) [g] 2px repeat(1, 3px [d e] 4px [e f]) [g] 300% [h]"); </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/subgrid/grid-template-computed-nogrid.html b/third_party/blink/web_tests/external/wpt/css/css-grid/subgrid/grid-template-computed-nogrid.html index ccfe67a5..1f37ce8 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/subgrid/grid-template-computed-nogrid.html +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/subgrid/grid-template-computed-nogrid.html
@@ -48,5 +48,22 @@ test_computed_value("grid-template-columns", "subgrid [a b] repeat(auto-fill, [c] [d e]) [g]"); test_computed_value("grid-template-columns", "subgrid [a] [b] repeat(auto-fill, [c] [d e]) [g h]"); test_computed_value("grid-template-columns", "subgrid [a] [b] repeat(auto-fill, [c] [d e])"); - +test_computed_value("grid-template-columns", "subgrid [a] repeat(2, [c] [d e])"); +test_computed_value("grid-template-columns", "subgrid repeat(1, [])"); +test_computed_value("grid-template-columns", "subgrid repeat(2, [])"); +test_computed_value("grid-template-columns", "subgrid repeat(2, [a])"); +test_computed_value("grid-template-columns", "subgrid repeat(2, [a] [])"); +test_computed_value("grid-template-columns", "subgrid repeat(2, [] [a] [])"); +test_computed_value("grid-template-columns", "subgrid repeat(2, [] [] []) repeat(auto-fill, [] [] [])"); +test_computed_value("grid-template-columns", "subgrid repeat(1, [a b])"); +test_computed_value("grid-template-columns", "subgrid repeat(2, [a b])"); +test_computed_value("grid-template-columns", "subgrid repeat(1, [a] [b])"); +test_computed_value("grid-template-columns", "subgrid repeat(2, [a] [b])"); +test_computed_value("grid-template-columns", "subgrid [a] repeat(2, [b])"); +test_computed_value("grid-template-columns", "subgrid repeat(2, [a]) [b]"); +test_computed_value("grid-template-columns", "subgrid [a] repeat(2, [b] [c d]) [e]"); +test_computed_value("grid-template-columns", "subgrid repeat(2, [a b]) repeat(auto-fill, [c] [d e])"); +test_computed_value("grid-template-columns", "subgrid repeat(auto-fill, [a] [b c]) repeat(2, [d e])"); +test_computed_value("grid-template-columns", "subgrid repeat(2, [a b]) repeat(auto-fill, [c] [d e]) repeat(2, [f g])"); +test_computed_value("grid-template-columns", "subgrid [a] [b c] repeat(2, [d e]) [f] [g h] repeat(auto-fill, [i] [j k]) [l] repeat(2, [m n]) [o]"); </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/subgrid/orthogonal-writing-mode-005-ref.html b/third_party/blink/web_tests/external/wpt/css/css-grid/subgrid/orthogonal-writing-mode-005-ref.html new file mode 100644 index 0000000..f8fa0ab8 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/subgrid/orthogonal-writing-mode-005-ref.html
@@ -0,0 +1,286 @@ +<!DOCTYPE HTML> +<html><head> + <meta charset="utf-8"> + <title>Reference: line names in orthogonal parent subgrid</title> + <link rel="author" title="Kurt Catti-Schmidt" href="mailto:kschmi@microsoft.com"> + <style> + body { + font:10px monospace; padding:0; margin:0; line-height:0; + } + + .grid { + display: inline-grid; + grid-auto-columns: 15px; + border: 1px solid; + vertical-align: bottom; + } + + .subgrid { + display: grid; + grid-template-columns: subgrid; + grid-column: 3 / span 4; + background: grey; + } + .grid > .subgrid > .subgrid { + writing-mode: vertical-lr; + grid-template-rows: subgrid; + grid-template-columns: initial; + grid-column: 1 / span 4; + grid-auto-columns: 8px; + grid-auto-flow: column; + } + + .fill-1a { grid-template-columns: subgrid repeat(auto-fill, [y]) [z] [z] [z] [z] } /* [y] [z] [z] [z] [z] */ + .fill-1b { grid-template-columns: subgrid [x] repeat(auto-fill, [y]) [z] [z] [z] } /* [x] [y] [z] [z] [z] */ + .fill-1c { grid-template-columns: subgrid [x] [x] repeat(auto-fill, [y]) [z] [z] } /* [x] [x] [y] [z] [z] */ + .fill-1d { grid-template-columns: subgrid [x] [x] [x] repeat(auto-fill, [y]) [z] } /* [x] [x] [x] [y] [z] */ + .fill-1e { grid-template-columns: subgrid [x] [x] [x] [x] repeat(auto-fill, [y]) } /* [x] [x] [x] [x] [y] */ + + .areas-1a { grid-template-areas: 'x x x x' } + .areas-1b { grid-template-areas: '. x x x' } + .areas-1c { grid-template-areas: 'x x x .' } + .areas-1d { grid-template-areas: '. . x x' } + .areas-1e { grid-template-areas: '. . x .' } + + .subgrid > .subgrid > :nth-child(2n) { background: black; } + .subgrid > .subgrid > :nth-child(2n+1) { background: pink; } + .subgrid > .subgrid > * { writing-mode: horizontal-tb; } + + </style> + </head> + <body> + + <!-- Line names before/after auto repeat --> + <div class="grid"><div class="subgrid fill-1a"><div class="subgrid"> + <div style="grid-row:4"></div> + <div style="grid-row:4"></div> + <div style="grid-row:4"></div> + <div style="grid-row:3"></div> + <div style="grid-row:2"></div> + <div style="grid-row:4"></div> + <div style="grid-row:4"></div> + <div style="grid-row:3"></div> + <div style="grid-row:2"></div> + <div style="grid-row:1"></div> + </div></div></div> + + <div class="grid"><div class="subgrid fill-1b"><div class="subgrid"> + <div style="grid-row:4"></div> + <div style="grid-row:4"></div> + <div style="grid-row:4"></div> + <div style="grid-row:4"></div> + <div style="grid-row:1"></div> + <div style="grid-row:1"></div> + <div style="grid-row:1"></div> + <div style="grid-row:1"></div> + <div style="grid-row:1"></div> + <div style="grid-row:1"></div> + </div></div></div> + + <div class="grid"><div class="subgrid fill-1c"><div class="subgrid"> + <div style="grid-row:4"></div> + <div style="grid-row:4"></div> + <div style="grid-row:4"></div> + <div style="grid-row:2"></div> + <div style="grid-row:1"></div> + <div style="grid-row:2"></div> + <div style="grid-row:1"></div> + <div style="grid-row:1"></div> + <div style="grid-row:1"></div> + <div style="grid-row:1"></div> + </div></div></div> + + <div class="grid"><div class="subgrid fill-1d"><div class="subgrid"> + <div style="grid-row:4"></div> + <div style="grid-row:4"></div> + <div style="grid-row:3"></div> + <div style="grid-row:2"></div> + <div style="grid-row:1"></div> + <div style="grid-row:3"></div> + <div style="grid-row:2"></div> + <div style="grid-row:1"></div> + <div style="grid-row:1"></div> + <div style="grid-row:1"></div> + </div></div></div> + + <div class="grid"><div class="subgrid fill-1e"><div class="subgrid"> + <div style="grid-row:4"></div> + <div style="grid-row:4"></div> + <div style="grid-row:3"></div> + <div style="grid-row:2"></div> + <div style="grid-row:1"></div> + <div style="grid-row:4"></div> + <div style="grid-row:3"></div> + <div style="grid-row:2"></div> + <div style="grid-row:1"></div> + <div style="grid-row:1"></div> + </div></div></div> + + <div class="grid"><div class="subgrid fill-1a"><div class="subgrid"> + <div style="grid-row:4"></div> + <div style="grid-row:4"></div> + <div style="grid-row:4"></div> + <div style="grid-row:4"></div> + <div style="grid-row:1"></div> + <div style="grid-row:1"></div> + <div style="grid-row:1"></div> + <div style="grid-row:1"></div> + <div style="grid-row:1"></div> + <div style="grid-row:1"></div> + </div></div></div> + + <!-- Auto repeat line names --> + <div class="grid"><div class="subgrid fill-1b"><div class="subgrid"> + <div style="grid-row:4"></div> + <div style="grid-row:4"></div> + <div style="grid-row:4"></div> + <div style="grid-row:4"></div> + <div style="grid-row:2"></div> + <div style="grid-row:2"></div> + <div style="grid-row:1"></div> + <div style="grid-row:1"></div> + <div style="grid-row:1"></div> + <div style="grid-row:1"></div> + </div></div></div> + + <div class="grid"><div class="subgrid fill-1c"><div class="subgrid"> + <div style="grid-row:4"></div> + <div style="grid-row:4"></div> + <div style="grid-row:4"></div> + <div style="grid-row:4"></div> + <div style="grid-row:3"></div> + <div style="grid-row:3"></div> + <div style="grid-row:1"></div> + <div style="grid-row:1"></div> + <div style="grid-row:1"></div> + <div style="grid-row:1"></div> + </div></div></div> + + <div class="grid"><div class="subgrid fill-1d"><div class="subgrid"> + <div style="grid-row:4"></div> + <div style="grid-row:4"></div> + <div style="grid-row:4"></div> + <div style="grid-row:4"></div> + <div style="grid-row:4"></div> + <div style="grid-row:4"></div> + <div style="grid-row:1"></div> + <div style="grid-row:1"></div> + <div style="grid-row:1"></div> + <div style="grid-row:1"></div> + </div></div></div> + + <div class="grid"><div class="subgrid fill-1e"><div class="subgrid"> + <div style="grid-row:4"></div> + <div style="grid-row:4"></div> + <div style="grid-row:4"></div> + <div style="grid-row:4"></div> + <div style="grid-row:4"></div> + <div style="grid-row:4"></div> + <div style="grid-row:1"></div> + <div style="grid-row:1"></div> + <div style="grid-row:1"></div> + <div style="grid-row:1"></div> + </div></div></div> + + <div class="grid"><div class="subgrid fill-1a"><div class="subgrid"> + <div style="grid-row:4"></div> + <div style="grid-row:4"></div> + <div style="grid-row:4"></div> + <div style="grid-row:3"></div> + <div style="grid-row:2"></div> + <div style="grid-row:4"></div> + <div style="grid-row:4"></div> + <div style="grid-row:3"></div> + <div style="grid-row:2"></div> + <div style="grid-row:1"></div> + </div></div></div> + + <div class="grid"><div class="subgrid fill-1b"><div class="subgrid"> + <div style="grid-row:4"></div> + <div style="grid-row:4"></div> + <div style="grid-row:4"></div> + <div style="grid-row:4"></div> + <div style="grid-row:3"></div> + <div style="grid-row:4"></div> + <div style="grid-row:4"></div> + <div style="grid-row:3"></div> + <div style="grid-row:1"></div> + <div style="grid-row:1"></div> + </div></div></div> + + <div class="grid"><div class="subgrid fill-1c"><div class="subgrid"> + <div style="grid-row:4"></div> + <div style="grid-row:4"></div> + <div style="grid-row:4"></div> + <div style="grid-row:4"></div> + <div style="grid-row:4"></div> + <div style="grid-row:4"></div> + <div style="grid-row:4"></div> + <div style="grid-row:1"></div> + <div style="grid-row:1"></div> + <div style="grid-row:1"></div> + </div></div></div> + + <div class="grid"><div class="subgrid fill-1d"><div class="subgrid"> + <div style="grid-row:4"></div> + <div style="grid-row:4"></div> + <div style="grid-row:4"></div> + <div style="grid-row:4"></div> + <div style="grid-row:4"></div> + <div style="grid-row:4"></div> + <div style="grid-row:1"></div> + <div style="grid-row:1"></div> + <div style="grid-row:1"></div> + <div style="grid-row:1"></div> + </div></div></div> + + <div class="grid"><div class="subgrid fill-1e"><div class="subgrid"> + <div style="grid-row:4"></div> + <div style="grid-row:4"></div> + <div style="grid-row:4"></div> + <div style="grid-row:4"></div> + <div style="grid-row:4"></div> + <div style="grid-row:1"></div> + <div style="grid-row:1"></div> + <div style="grid-row:1"></div> + <div style="grid-row:1"></div> + <div style="grid-row:1"></div> + </div></div></div> + + <!-- Named grid areas --> + <div class="grid"><div class="subgrid areas-1a"><div class="subgrid"> + <div style="grid-row:1"></div> + <div style="grid-row:1"></div> + <div style="grid-row:1"></div> + <div style="grid-row:2"></div> + </div></div></div> + + <div class="grid"><div class="subgrid areas-1b"><div class="subgrid"> + <div style="grid-row:1"></div> + <div style="grid-row:1"></div> + <div style="grid-row:1"></div> + <div style="grid-row:2"></div> + </div></div></div> + + <div class="grid"><div class="subgrid areas-1c"><div class="subgrid"> + <div style="grid-row:1"></div> + <div style="grid-row:1"></div> + <div style="grid-row:1"></div> + <div style="grid-row:2"></div> + </div></div></div> + + <div class="grid"><div class="subgrid areas-1d"><div class="subgrid"> + <div style="grid-row:1"></div> + <div style="grid-row:1"></div> + <div style="grid-row:1"></div> + <div style="grid-row:2"></div> + </div></div></div> + + <div class="grid"><div class="subgrid areas-1e"><div class="subgrid"> + <div style="grid-row:1"></div> + <div style="grid-row:1"></div> + <div style="grid-row:1"></div> + <div style="grid-row:2"></div> + </div></div></div> + </body> + </html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/subgrid/orthogonal-writing-mode-005.html b/third_party/blink/web_tests/external/wpt/css/css-grid/subgrid/orthogonal-writing-mode-005.html new file mode 100644 index 0000000..d5bd178 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/subgrid/orthogonal-writing-mode-005.html
@@ -0,0 +1,288 @@ +<!DOCTYPE HTML> +<html><head> + <meta charset="utf-8"> + <title>CSS Grid Test: line names in orthogonal parent subgrid</title> + <link rel="author" title="Kurt Catti-Schmidt" href="mailto:kschmi@microsoft.com"> + <link rel="help" href="https://drafts.csswg.org/css-grid-2/#subgrid-listing"> + <link rel="match" href="orthogonal-writing-mode-005-ref.html"> + <style> +body { + color:black; background-color:white; font:10px monospace; padding:0; margin:0; line-height:0; +} + +.grid { + display: inline-grid; + grid-auto-columns: 15px; + border: 1px solid; + vertical-align: bottom; +} + +.subgrid { + display: grid; + grid-template-columns: subgrid; + grid-column: 3 / span 4; + background: grey; +} +.grid > .subgrid > .subgrid { + writing-mode: vertical-lr; + grid-template-rows: subgrid; + grid-template-columns: initial; + grid-column: 1 / span 4; + grid-auto-columns: 8px; + grid-auto-flow: column; +} + +.fill-1a { grid-template-columns: subgrid repeat(auto-fill, [y]) [z] [z] [z] [z] } /* [y] [z] [z] [z] [z] */ +.fill-1b { grid-template-columns: subgrid [x] repeat(auto-fill, [y]) [z] [z] [z] } /* [x] [y] [z] [z] [z] */ +.fill-1c { grid-template-columns: subgrid [x] [x] repeat(auto-fill, [y]) [z] [z] } /* [x] [x] [y] [z] [z] */ +.fill-1d { grid-template-columns: subgrid [x] [x] [x] repeat(auto-fill, [y]) [z] } /* [x] [x] [x] [y] [z] */ +.fill-1e { grid-template-columns: subgrid [x] [x] [x] [x] repeat(auto-fill, [y]) } /* [x] [x] [x] [x] [y] */ + +.areas-1a { grid-template-areas: 'x x x x' } +.areas-1b { grid-template-areas: '. x x x' } +.areas-1c { grid-template-areas: 'x x x .' } +.areas-1d { grid-template-areas: '. . x x' } +.areas-1e { grid-template-areas: '. . x .' } + +.subgrid > .subgrid > :nth-child(2n) { background: black; } +.subgrid > .subgrid > :nth-child(2n+1) { background: pink; } +.subgrid > .subgrid > * { writing-mode: horizontal-tb; } + + </style> +</head> +<body> + +<!-- Line names before auto repeat --> +<div class="grid"><div class="subgrid fill-1a"><div class="subgrid"> + <div style="grid-row:z 5"></div> + <div style="grid-row:z 4"></div> + <div style="grid-row:z 3"></div> + <div style="grid-row:z 2"></div> + <div style="grid-row:z 1"></div> + <div style="grid-row:z -1"></div> + <div style="grid-row:z -2"></div> + <div style="grid-row:z -3"></div> + <div style="grid-row:z -4"></div> + <div style="grid-row:z -5"></div> +</div></div></div> + +<div class="grid"><div class="subgrid fill-1b"><div class="subgrid"> + <div style="grid-row:x 5"></div> + <div style="grid-row:x 4"></div> + <div style="grid-row:x 3"></div> + <div style="grid-row:x 2"></div> + <div style="grid-row:x 1"></div> + <div style="grid-row:x -1"></div> + <div style="grid-row:x -2"></div> + <div style="grid-row:x -3"></div> + <div style="grid-row:x -4"></div> + <div style="grid-row:x -5"></div> +</div></div></div> + +<div class="grid"><div class="subgrid fill-1c"><div class="subgrid"> + <div style="grid-row:x 5"></div> + <div style="grid-row:x 4"></div> + <div style="grid-row:x 3"></div> + <div style="grid-row:x 2"></div> + <div style="grid-row:x 1"></div> + <div style="grid-row:x -1"></div> + <div style="grid-row:x -2"></div> + <div style="grid-row:x -3"></div> + <div style="grid-row:x -4"></div> + <div style="grid-row:x -5"></div> +</div></div></div> + +<div class="grid"><div class="subgrid fill-1d"><div class="subgrid"> + <div style="grid-row:x 5"></div> + <div style="grid-row:x 4"></div> + <div style="grid-row:x 3"></div> + <div style="grid-row:x 2"></div> + <div style="grid-row:x 1"></div> + <div style="grid-row:x -1"></div> + <div style="grid-row:x -2"></div> + <div style="grid-row:x -3"></div> + <div style="grid-row:x -4"></div> + <div style="grid-row:x -5"></div> +</div></div></div> + +<div class="grid"><div class="subgrid fill-1e"><div class="subgrid"> + <div style="grid-row:x 5"></div> + <div style="grid-row:x 4"></div> + <div style="grid-row:x 3"></div> + <div style="grid-row:x 2"></div> + <div style="grid-row:x 1"></div> + <div style="grid-row:x -1"></div> + <div style="grid-row:x -2"></div> + <div style="grid-row:x -3"></div> + <div style="grid-row:x -4"></div> + <div style="grid-row:x -5"></div> +</div></div></div> + +<div class="grid"><div class="subgrid fill-1a"><div class="subgrid"> + <div style="grid-row:y 5"></div> + <div style="grid-row:y 4"></div> + <div style="grid-row:y 3"></div> + <div style="grid-row:y 2"></div> + <div style="grid-row:y 1"></div> + <div style="grid-row:y -1"></div> + <div style="grid-row:y -2"></div> + <div style="grid-row:y -3"></div> + <div style="grid-row:y -4"></div> + <div style="grid-row:y -5"></div> +</div></div></div> + +<!-- Auto repeat line names --> +<div class="grid"><div class="subgrid fill-1b"><div class="subgrid"> + <div style="grid-row:y 5"></div> + <div style="grid-row:y 4"></div> + <div style="grid-row:y 3"></div> + <div style="grid-row:y 2"></div> + <div style="grid-row:y 1"></div> + <div style="grid-row:y -1"></div> + <div style="grid-row:y -2"></div> + <div style="grid-row:y -3"></div> + <div style="grid-row:y -4"></div> + <div style="grid-row:y -5"></div> +</div></div></div> + +<div class="grid"><div class="subgrid fill-1c"><div class="subgrid"> + <div style="grid-row:y 5"></div> + <div style="grid-row:y 4"></div> + <div style="grid-row:y 3"></div> + <div style="grid-row:y 2"></div> + <div style="grid-row:y 1"></div> + <div style="grid-row:y -1"></div> + <div style="grid-row:y -2"></div> + <div style="grid-row:y -3"></div> + <div style="grid-row:y -4"></div> + <div style="grid-row:y -5"></div> +</div></div></div> + +<div class="grid"><div class="subgrid fill-1d"><div class="subgrid"> + <div style="grid-row:y 5"></div> + <div style="grid-row:y 4"></div> + <div style="grid-row:y 3"></div> + <div style="grid-row:y 2"></div> + <div style="grid-row:y 1"></div> + <div style="grid-row:y -1"></div> + <div style="grid-row:y -2"></div> + <div style="grid-row:y -3"></div> + <div style="grid-row:y -4"></div> + <div style="grid-row:y -5"></div> +</div></div></div> + +<div class="grid"><div class="subgrid fill-1e"><div class="subgrid"> + <div style="grid-row:y 5"></div> + <div style="grid-row:y 4"></div> + <div style="grid-row:y 3"></div> + <div style="grid-row:y 2"></div> + <div style="grid-row:y 1"></div> + <div style="grid-row:y -1"></div> + <div style="grid-row:y -2"></div> + <div style="grid-row:y -3"></div> + <div style="grid-row:y -4"></div> + <div style="grid-row:y -5"></div> +</div></div></div> + +<div class="grid"><div class="subgrid fill-1a"><div class="subgrid"> + <div style="grid-row:z 5"></div> + <div style="grid-row:z 4"></div> + <div style="grid-row:z 3"></div> + <div style="grid-row:z 2"></div> + <div style="grid-row:z 1"></div> + <div style="grid-row:z -1"></div> + <div style="grid-row:z -2"></div> + <div style="grid-row:z -3"></div> + <div style="grid-row:z -4"></div> + <div style="grid-row:z -5"></div> +</div></div></div> + +<div class="grid"><div class="subgrid fill-1b"><div class="subgrid"> + <div style="grid-row:z 5"></div> + <div style="grid-row:z 4"></div> + <div style="grid-row:z 3"></div> + <div style="grid-row:z 2"></div> + <div style="grid-row:z 1"></div> + <div style="grid-row:z -1"></div> + <div style="grid-row:z -2"></div> + <div style="grid-row:z -3"></div> + <div style="grid-row:z -4"></div> + <div style="grid-row:z -5"></div> +</div></div></div> + +<div class="grid"><div class="subgrid fill-1c"><div class="subgrid"> + <div style="grid-row:z 5"></div> + <div style="grid-row:z 4"></div> + <div style="grid-row:z 3"></div> + <div style="grid-row:z 2"></div> + <div style="grid-row:z 1"></div> + <div style="grid-row:z -1"></div> + <div style="grid-row:z -2"></div> + <div style="grid-row:z -3"></div> + <div style="grid-row:z -4"></div> + <div style="grid-row:z -5"></div> +</div></div></div> + +<div class="grid"><div class="subgrid fill-1d"><div class="subgrid"> + <div style="grid-row:z 5"></div> + <div style="grid-row:z 4"></div> + <div style="grid-row:z 3"></div> + <div style="grid-row:z 2"></div> + <div style="grid-row:z 1"></div> + <div style="grid-row:z -1"></div> + <div style="grid-row:z -2"></div> + <div style="grid-row:z -3"></div> + <div style="grid-row:z -4"></div> + <div style="grid-row:z -5"></div> +</div></div></div> + +<div class="grid"><div class="subgrid fill-1e"><div class="subgrid"> + <div style="grid-row:z 5"></div> + <div style="grid-row:z 4"></div> + <div style="grid-row:z 3"></div> + <div style="grid-row:z 2"></div> + <div style="grid-row:z 1"></div> + <div style="grid-row:z -1"></div> + <div style="grid-row:z -2"></div> + <div style="grid-row:z -3"></div> + <div style="grid-row:z -4"></div> + <div style="grid-row:z -5"></div> +</div></div></div> + +<!-- Named grid areas --> +<div class="grid"><div class="subgrid areas-1a"><div class="subgrid"> + <div style="grid-row:x-start"></div> + <div style="grid-row:x"></div> + <div style="grid-row:x-start / x-end"></div> + <div style="grid-row:x-end"></div> +</div></div></div> + +<div class="grid"><div class="subgrid areas-1b"><div class="subgrid"> + <div style="grid-row:x-start"></div> + <div style="grid-row:x"></div> + <div style="grid-row:x-start / x-end"></div> + <div style="grid-row:x-end"></div> +</div></div></div> + +<div class="grid"><div class="subgrid areas-1c"><div class="subgrid"> + <div style="grid-row:x-start"></div> + <div style="grid-row:x"></div> + <div style="grid-row:x-start / x-end"></div> + <div style="grid-row:x-end"></div> +</div></div></div> + +<div class="grid"><div class="subgrid areas-1d"><div class="subgrid"> + <div style="grid-row:x-start"></div> + <div style="grid-row:x"></div> + <div style="grid-row:x-start / x-end"></div> + <div style="grid-row:x-end"></div> +</div></div></div> + +<div class="grid"><div class="subgrid areas-1e"><div class="subgrid"> + <div style="grid-row:x-start"></div> + <div style="grid-row:x"></div> + <div style="grid-row:x-start / x-end"></div> + <div style="grid-row:x-end"></div> +</div></div></div> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/subgrid/repeat-auto-fill-003.html b/third_party/blink/web_tests/external/wpt/css/css-grid/subgrid/repeat-auto-fill-003.html index 3a1d270..df14ed8 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/subgrid/repeat-auto-fill-003.html +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/subgrid/repeat-auto-fill-003.html
@@ -11,13 +11,14 @@ <link rel="match" href="repeat-auto-fill-001-ref.html"> <style> html,body { - color:black; background-color:white; font:10px/1 monospace; padding:0; margin:0; + color:black; background-color:white; font:10px monospace; padding:0; margin:0; line-height:0; } .grid { display: inline-grid; grid-auto-columns: 15px; border: 1px solid; + vertical-align: top; } .subgrid {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-repeat/background-repeat-no-interpolation.html b/third_party/blink/web_tests/external/wpt/css/css-inline/alignment-baseline-no-interpolation.html similarity index 88% copy from third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-repeat/background-repeat-no-interpolation.html copy to third_party/blink/web_tests/external/wpt/css/css-inline/alignment-baseline-no-interpolation.html index a1a48d5..57deaf8 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-repeat/background-repeat-no-interpolation.html +++ b/third_party/blink/web_tests/external/wpt/css/css-inline/alignment-baseline-no-interpolation.html
@@ -8,8 +8,8 @@ <body> <script> test_no_interpolation({ - property: 'background-repeat', + property: 'alignment-baseline', from: 'initial', - to: 'round' + to: 'central' }); </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-repeat/background-repeat-no-interpolation.html b/third_party/blink/web_tests/external/wpt/css/css-inline/baseline-source/baseline-source-no-interpolation.html similarity index 88% copy from third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-repeat/background-repeat-no-interpolation.html copy to third_party/blink/web_tests/external/wpt/css/css-inline/baseline-source/baseline-source-no-interpolation.html index a1a48d5..86fede73 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-repeat/background-repeat-no-interpolation.html +++ b/third_party/blink/web_tests/external/wpt/css/css-inline/baseline-source/baseline-source-no-interpolation.html
@@ -8,8 +8,8 @@ <body> <script> test_no_interpolation({ - property: 'background-repeat', + property: 'baseline-source', from: 'initial', - to: 'round' + to: 'last' }); </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-repeat/background-repeat-no-interpolation.html b/third_party/blink/web_tests/external/wpt/css/css-logical/animations/caption-side-no-interpolation.html similarity index 88% copy from third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-repeat/background-repeat-no-interpolation.html copy to third_party/blink/web_tests/external/wpt/css/css-logical/animations/caption-side-no-interpolation.html index a1a48d5..2eef093 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-repeat/background-repeat-no-interpolation.html +++ b/third_party/blink/web_tests/external/wpt/css/css-logical/animations/caption-side-no-interpolation.html
@@ -8,8 +8,8 @@ <body> <script> test_no_interpolation({ - property: 'background-repeat', + property: 'caption-side', from: 'initial', - to: 'round' + to: 'bottom' }); </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-repeat/background-repeat-no-interpolation.html b/third_party/blink/web_tests/external/wpt/css/css-masking/clip-rule/clip-rule-no-interpolation.html similarity index 88% copy from third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-repeat/background-repeat-no-interpolation.html copy to third_party/blink/web_tests/external/wpt/css/css-masking/clip-rule/clip-rule-no-interpolation.html index a1a48d5..066636c5 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-repeat/background-repeat-no-interpolation.html +++ b/third_party/blink/web_tests/external/wpt/css/css-masking/clip-rule/clip-rule-no-interpolation.html
@@ -8,8 +8,8 @@ <body> <script> test_no_interpolation({ - property: 'background-repeat', + property: 'clip-rule', from: 'initial', - to: 'round' + to: 'evenodd' }); </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-repeat/background-repeat-no-interpolation.html b/third_party/blink/web_tests/external/wpt/css/css-sizing/animation/box-sizing-no-interpolation.html similarity index 88% copy from third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-repeat/background-repeat-no-interpolation.html copy to third_party/blink/web_tests/external/wpt/css/css-sizing/animation/box-sizing-no-interpolation.html index a1a48d5..d688445 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-repeat/background-repeat-no-interpolation.html +++ b/third_party/blink/web_tests/external/wpt/css/css-sizing/animation/box-sizing-no-interpolation.html
@@ -8,8 +8,8 @@ <body> <script> test_no_interpolation({ - property: 'background-repeat', + property: 'box-sizing', from: 'initial', - to: 'round' + to: 'border-box' }); </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-repeat/background-repeat-no-interpolation.html b/third_party/blink/web_tests/external/wpt/css/css-transforms/animation/backface-visibility-no-interpolation.html similarity index 88% copy from third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-repeat/background-repeat-no-interpolation.html copy to third_party/blink/web_tests/external/wpt/css/css-transforms/animation/backface-visibility-no-interpolation.html index a1a48d5..b7b9f2d5f 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-repeat/background-repeat-no-interpolation.html +++ b/third_party/blink/web_tests/external/wpt/css/css-transforms/animation/backface-visibility-no-interpolation.html
@@ -8,8 +8,8 @@ <body> <script> test_no_interpolation({ - property: 'background-repeat', + property: 'backface-visibility', from: 'initial', - to: 'round' + to: 'hidden' }); </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-repeat/background-repeat-no-interpolation.html b/third_party/blink/web_tests/external/wpt/css/css-ui/animation/appearance-no-interpolation.html similarity index 88% copy from third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-repeat/background-repeat-no-interpolation.html copy to third_party/blink/web_tests/external/wpt/css/css-ui/animation/appearance-no-interpolation.html index a1a48d5..5ddfcd4 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-repeat/background-repeat-no-interpolation.html +++ b/third_party/blink/web_tests/external/wpt/css/css-ui/animation/appearance-no-interpolation.html
@@ -8,8 +8,8 @@ <body> <script> test_no_interpolation({ - property: 'background-repeat', + property: 'appearance', from: 'initial', - to: 'round' + to: 'none' }); </script>
diff --git a/third_party/blink/web_tests/external/wpt/dom/events/Event-dispatch-on-disabled-elements.html b/third_party/blink/web_tests/external/wpt/dom/events/Event-dispatch-on-disabled-elements.html index 361006a..e7d6b455 100644 --- a/third_party/blink/web_tests/external/wpt/dom/events/Event-dispatch-on-disabled-elements.html +++ b/third_party/blink/web_tests/external/wpt/dom/events/Event-dispatch-on-disabled-elements.html
@@ -19,7 +19,7 @@ <body> <script> // HTML elements that can be disabled -const formElements = ["button", "fieldset", "input", "select", "textarea"]; +const formElements = ["button", "input", "select", "textarea"]; test(() => { for (const localName of formElements) {
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/disabled-elements/fieldset-event-propagation.tentative.html b/third_party/blink/web_tests/external/wpt/html/semantics/disabled-elements/fieldset-event-propagation.tentative.html new file mode 100644 index 0000000..11822e4 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/semantics/disabled-elements/fieldset-event-propagation.tentative.html
@@ -0,0 +1,48 @@ +<!DOCTYPE html> +<link rel=author href="mailto:jarhar@chromium.org"> +<link rel=help href="https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#concept-fe-disabled"> +<link rel=help href="https://github.com/whatwg/html/issues/5886#issuecomment-1460425364"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="/resources/testdriver-actions.js"></script> + +<div id=target1parent> + <fieldset disabled id=target1fieldset> + <div id=target1child>hello world</div> + </fieldset> +</div> + +<div id=target2parent> + <fieldset disabled id=target2fieldset>hello world</div> +</div> + +<script> +promise_test(async () => { + let target1parentClicked = false; + let target1childClicked = false; + let target1fieldsetClicked = false; + target1parent.onclick = () => target1parentClicked = true; + target1child.onclick = () => target1childClicked = true; + target1fieldset.onclick = () => target1fieldsetClicked = true; + + await test_driver.click(target1child); + + assert_true(target1parentClicked, 'The parent of the fieldset should receive a click event.'); + assert_true(target1childClicked, 'The child of the fieldset should receive a click event.'); + assert_true(target1fieldsetClicked, 'The fieldset element should receive a click event.'); +}, 'Disabled fieldset elements should not prevent click event propagation.'); + +promise_test(async () => { + let target2parentClicked = false; + let target2fieldsetClicked = false; + target2parent.onclick = () => target2parentClicked = true; + target2fieldset.onclick = () => target2fieldsetClicked = true; + + await test_driver.click(target2fieldset); + + assert_true(target2parentClicked, 'The parent of the fieldset should receive a click event.'); + assert_true(target2fieldsetClicked, 'The fieldset element should receive a click event.'); +}, 'Disabled fieldset elements should not block click events.'); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-selectmenu-element/selectmenu-pseudo-open-closed.tentative.html b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-selectmenu-element/selectmenu-pseudo-open-closed.tentative.html new file mode 100644 index 0000000..b1400e0 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-selectmenu-element/selectmenu-pseudo-open-closed.tentative.html
@@ -0,0 +1,61 @@ +<!DOCTYPE html> +<link rel=author href="mailto:jarhar@chromium.org"> +<link rel=help href="https://github.com/openui/open-ui/issues/547"> +<link rel=help href="https://drafts.csswg.org/selectors/#open-state"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<selectmenu id=myselectmenu> + <button id=custombutton slot=button behavior=button>button</button> + <option>one</option> + <option>two</option> +</selectmenu> + +<script> +test(() => { + assert_false(myselectmenu.matches(':open'), + 'Selectmenu should not match :open while it is closed.'); + assert_true(myselectmenu.matches(':closed'), + 'Selectmenu should match :closed while it is closed.'); + + custombutton.click(); + + assert_true(myselectmenu.matches(':open'), + 'Selectmenu should match :open while it is open.'); + assert_false(myselectmenu.matches(':closed'), + 'Selectmenu should not match :closed while it is open.'); +}, 'Selectmenu should support :open and :closed pseudo selectors.'); +</script> + +<selectmenu id=selectmenuinvalidation> + <button slot=button behavior=button>button</button> + <option>one</option> + <option>two</option> +</selectmenu> +<style> +selectmenu:closed { + background-color: red; +} +selectmenu:open { + background-color: green; +} +</style> + +<script> +test(() => { + const selectmenu = document.getElementById('selectmenuinvalidation'); + const button = selectmenu.querySelector('button'); + const option = selectmenu.querySelector('option'); + + assert_equals(getComputedStyle(selectmenu).backgroundColor, 'rgb(255, 0, 0)', + 'The style rules from :closed should apply when the selectmenu is closed.'); + + button.click(); + assert_equals(getComputedStyle(selectmenu).backgroundColor, 'rgb(0, 128, 0)', + 'The style rules from :open should apply when the selectmenu is open.'); + + option.click(); + assert_equals(getComputedStyle(selectmenu).backgroundColor, 'rgb(255, 0, 0)', + 'The style rules from :closed should apply when the selectmenu is opened and closed again.'); +}, 'Selectmenu :open and :closed should invalidate correctly.'); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/selectors/pseudo-classes/disabled.html b/third_party/blink/web_tests/external/wpt/html/semantics/selectors/pseudo-classes/disabled.html index 8808675..f960043 100644 --- a/third_party/blink/web_tests/external/wpt/html/semantics/selectors/pseudo-classes/disabled.html +++ b/third_party/blink/web_tests/external/wpt/html/semantics/selectors/pseudo-classes/disabled.html
@@ -26,7 +26,6 @@ </select> <textarea id=textarea1>textarea1</textarea> <textarea disabled id=textarea2>textarea2</textarea> -<fieldset id=fieldset1></fieldset> <fieldset disabled id=fieldset2> <legend><input type=checkbox id=club></legend> <p><label>Name on card: <input id=clubname required></label></p> @@ -40,21 +39,21 @@ <progress disabled></progress> <script> - testSelectorIdsMatch(":disabled", ["button2", "input2", "select2", "optgroup2", "option2", "textarea2", "fieldset2", "clubname", "clubnum"], "':disabled' should match only disabled elements"); + testSelectorIdsMatch(":disabled", ["button2", "input2", "select2", "optgroup2", "option2", "textarea2", "clubname", "clubnum"], "':disabled' should match only disabled elements"); document.getElementById("button2").removeAttribute("disabled"); - testSelectorIdsMatch(":disabled", ["input2", "select2", "optgroup2", "option2", "textarea2", "fieldset2", "clubname", "clubnum"], "':disabled' should not match elements whose disabled attribute has been removed"); + testSelectorIdsMatch(":disabled", ["input2", "select2", "optgroup2", "option2", "textarea2", "clubname", "clubnum"], "':disabled' should not match elements whose disabled attribute has been removed"); document.getElementById("button1").setAttribute("disabled", "disabled"); - testSelectorIdsMatch(":disabled", ["button1", "input2", "select2", "optgroup2", "option2", "textarea2", "fieldset2", "clubname", "clubnum"], "':disabled' should also match elements whose disabled attribute has been set"); + testSelectorIdsMatch(":disabled", ["button1", "input2", "select2", "optgroup2", "option2", "textarea2", "clubname", "clubnum"], "':disabled' should also match elements whose disabled attribute has been set"); document.getElementById("button1").setAttribute("disabled", "disabled"); - testSelectorIdsMatch(":disabled", ["button1", "input2", "select2", "optgroup2", "option2", "textarea2", "fieldset2", "clubname", "clubnum"], "':disabled' should also match elements whose disabled attribute has been set twice"); + testSelectorIdsMatch(":disabled", ["button1", "input2", "select2", "optgroup2", "option2", "textarea2", "clubname", "clubnum"], "':disabled' should also match elements whose disabled attribute has been set twice"); document.getElementById("input2").setAttribute("type", "submit"); // change input type to submit - testSelectorIdsMatch(":disabled", ["button1", "input2", "select2", "optgroup2", "option2", "textarea2", "fieldset2", "clubname", "clubnum"], "':disabled' should also match disabled elements whose type has changed"); + testSelectorIdsMatch(":disabled", ["button1", "input2", "select2", "optgroup2", "option2", "textarea2", "clubname", "clubnum"], "':disabled' should also match disabled elements whose type has changed"); var input = document.createElement("input"); input.setAttribute("disabled", "disabled"); - testSelectorIdsMatch(":disabled", ["button1", "input2", "select2", "optgroup2", "option2", "textarea2", "fieldset2", "clubname", "clubnum"], "':disabled' should not match elements not in the document"); + testSelectorIdsMatch(":disabled", ["button1", "input2", "select2", "optgroup2", "option2", "textarea2", "clubname", "clubnum"], "':disabled' should not match elements not in the document"); </script>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/selectors/pseudo-classes/enabled.html b/third_party/blink/web_tests/external/wpt/html/semantics/selectors/pseudo-classes/enabled.html index 0ad0e1b40..1948343 100644 --- a/third_party/blink/web_tests/external/wpt/html/semantics/selectors/pseudo-classes/enabled.html +++ b/third_party/blink/web_tests/external/wpt/html/semantics/selectors/pseudo-classes/enabled.html
@@ -36,7 +36,6 @@ </menu> </form> <fieldset id=fieldset1></fieldset> -<fieldset disabled id=fieldset2></fieldset> <script> testSelectorIdsMatch(":enabled", ["button1", "input1", "select1", "optgroup1", "option1", "textarea1", "submitbutton", "fieldset1"], "':enabled' elements that are not disabled");
diff --git a/third_party/blink/web_tests/fast/css/invalidation/fieldset-disabled-expected.txt b/third_party/blink/web_tests/fast/css/invalidation/fieldset-disabled-expected.txt deleted file mode 100644 index 4796425..0000000 --- a/third_party/blink/web_tests/fast/css/invalidation/fieldset-disabled-expected.txt +++ /dev/null
@@ -1,11 +0,0 @@ -Use descendant invalidation set for :disabled fieldset. - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - -PASS getComputedStyle(fieldset, '').backgroundColor is transparent -PASS internals.updateStyleAndReturnAffectedElementCount() is 2 -PASS getComputedStyle(fieldset, '').backgroundColor is green -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/blink/web_tests/fast/css/invalidation/fieldset-disabled.html b/third_party/blink/web_tests/fast/css/invalidation/fieldset-disabled.html index c96deb1..02316b4 100644 --- a/third_party/blink/web_tests/fast/css/invalidation/fieldset-disabled.html +++ b/third_party/blink/web_tests/fast/css/invalidation/fieldset-disabled.html
@@ -1,13 +1,15 @@ <!DOCTYPE html> -<script src="../../../resources/js-test.js"></script> +<script src="../../../resources/testharness.js"></script> +<script src="../../../resources/testharnessreport.js"></script> <style> -fieldset:disabled { background-color: green } +button:disabled { background-color: green } fieldset + div { color: pink } </style> <fieldset id="fieldset"> <legend></legend> <label for="field"></label> <input type="text" name="field" id="field"> + <button id=button></button> <div> <div></div> <div></div> @@ -22,21 +24,23 @@ <div></div> </div> <script> -description("Use descendant invalidation set for :disabled fieldset.") +test(() => { + const transparent = "rgba(0, 0, 0, 0)"; + const green = "rgb(0, 128, 0)"; -var transparent = "rgba(0, 0, 0, 0)"; -var green = "rgb(0, 128, 0)"; + assert_equals(getComputedStyle(fieldset, '').backgroundColor, transparent); -shouldBe("getComputedStyle(fieldset, '').backgroundColor", "transparent"); + fieldset.offsetTop; // Force recalc. + fieldset.disabled = true; -fieldset.offsetTop; // Force recalc. -fieldset.disabled = true; + if (window.internals) { + // There are still instances of SubtreeStyleChange left when updating + // disabled state. This count should become lower. + assert_equals(internals.updateStyleAndReturnAffectedElementCount(), 3); + } -if (window.internals) { - // There are still instances of SubtreeStyleChange left when updating - // disabled state. This count should become lower. - shouldBe("internals.updateStyleAndReturnAffectedElementCount()", "2"); -} - -shouldBe("getComputedStyle(fieldset, '').backgroundColor", "green"); + // Fieldsets can't be disabled or match :disabled, so we have to test a + // descendant element which becomes disabled by making the fieldset disabled. + assert_equals(getComputedStyle(button, '').backgroundColor, green); +}, "Use descendant invalidation set for :disabled fieldset."); </script>
diff --git a/third_party/blink/web_tests/fast/forms/fieldset/fieldset-disabled-expected.txt b/third_party/blink/web_tests/fast/forms/fieldset/fieldset-disabled-expected.txt deleted file mode 100644 index 0057f90..0000000 --- a/third_party/blink/web_tests/fast/forms/fieldset/fieldset-disabled-expected.txt +++ /dev/null
@@ -1,94 +0,0 @@ -Tests for HTMLFieldSetElement.disabled behavior. - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - - -Verifying parser generated fieldsets. -PASS parserGeneratedInput1.value is "L" -PASS parserGeneratedInput2.value is "M" -PASS parserGeneratedInput3.value is "NO" -PASS parserGeneratedInput4.value is "" -PASS parserGeneratedInput5.value is "PQRST" -PASS parserGeneratedInput6.value is "" -PASS parserGeneratedInput7.value is "" -PASS parserGeneratedInput8.value is "" -PASS parserGeneratedInput9.value is "" - -Testing a single fieldset element. -Verifying HTMLFormControl can be disabled regardless of enclosing fieldset. -PASS textInput.disabled is true -PASS textInput.value is "" -PASS fieldSet.disabled is false -Fieldset is enabled by default. A user can insertText into the text input field. -PASS textInput.value is "A" -Disable fieldset. -PASS fieldSet.disabled is true -Once the fieldset is disabled, text cannot be inserted. -PASS textInput.value is "A" -Check if the style of the text element changed. -PASS getComputedStyle(textInput).backgroundColor is 'rgb(255, 0, 0)' -Enable fieldset. -PASS fieldSet.disabled is false -PASS getComputedStyle(textInput).backgroundColor is 'rgb(255, 255, 100)' -PASS textInput.value is "AB" -Move the textinput element out of the fieldset. -Disable the fieldset. -PASS fieldSet.disabled is true -Text can be inserted, because the textinput element is outside of the disabled fieldset. -PASS textInput.value is "ABC" -Enable the fieldset. -PASS fieldSet.disabled is false -Insert a table into the fieldset. -Move the textinput field into the table. -PASS textInput.value is "ABCD" -Disable the fieldset. -PASS fieldSet.disabled is true -Inserting text should fail. -PASS textInput.value is "ABCD" -Enable the fieldset. -PASS fieldSet.disabled is false -PASS textInput.value is "ABCDE" - -Testing nested fieldset elements. -Verifying that subordinates of both fieldsets are enabled. -PASS outerTextInput.value is "F" -PASS innerTextInput.value is "F" -Disabling the inner fieldset only. -PASS innerFieldSet.disabled is true -PASS outerTextInput.value is "FGG" -PASS innerTextInput.value is "F" -Enabling the inner and disabling the outer fieldset. -PASS outerFieldSet.disabled is true -PASS innerFieldSet.disabled is false -PASS outerTextInput.value is "FGG" -PASS innerTextInput.value is "F" -Disabling both fieldset elements. -PASS outerFieldSet.disabled is true -PASS innerFieldSet.disabled is true -PASS outerTextInput.value is "FGG" -PASS innerTextInput.value is "F" -Enabling both fieldset elements. -PASS outerFieldSet.disabled is false -PASS innerFieldSet.disabled is false -PASS outerTextInput.value is "FGGH" -PASS innerTextInput.value is "FH" - -Test behavior of the first legend element in a fieldset elements. -Children of the first legend element in a fieldset should not get disabled with the fieldset. -PASS legendFieldSet.disabled is true -PASS firstLegendTextInput.value is "II" -PASS secondLegendTextInput.value is "" -Insert another legend element before the currently first one, and check again. -PASS insertedLegendTextInput.value is "JJJ" -PASS firstLegendTextInput.value is "II" -PASS secondLegendTextInput.value is "" -Enable the fieldset again and check for sanity. -PASS legendFieldSet.disabled is false -PASS insertedLegendTextInput.value is "JJJK" -PASS firstLegendTextInput.value is "IIK" -PASS secondLegendTextInput.value is "K" -PASS disabledFieldsetWithTabindex.focus(); document.activeElement is document.body -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/blink/web_tests/fast/forms/fieldset/fieldset-disabled.html b/third_party/blink/web_tests/fast/forms/fieldset/fieldset-disabled.html index d730dda..c5cd128 100644 --- a/third_party/blink/web_tests/fast/forms/fieldset/fieldset-disabled.html +++ b/third_party/blink/web_tests/fast/forms/fieldset/fieldset-disabled.html
@@ -1,7 +1,8 @@ <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> <html> <head> -<script src="../../../resources/js-test.js"></script> +<script src="../../../resources/testharness.js"></script> +<script src="../../../resources/testharnessreport.js"></script> <style type="text/css"> input { background:rgb(255,255,100); @@ -33,9 +34,9 @@ </form> <fieldset tabindex=0 disabled id="fieldset-tabindex"></fieldset> <script> -description('Tests for HTMLFieldSetElement.disabled behavior.'); +test(() => { -debug('\nVerifying parser generated fieldsets.'); +// Verifying parser generated fieldsets. var parserGeneratedInput1 = document.getElementById("parserGeneratedInput1"); var parserGeneratedInput2 = document.getElementById("parserGeneratedInput2"); var parserGeneratedInput3 = document.getElementById("parserGeneratedInput3"); @@ -65,77 +66,77 @@ parserGeneratedInput9.focus(); document.execCommand('insertText', false, 'T'); -shouldBe('parserGeneratedInput1.value', '"L"'); -shouldBe('parserGeneratedInput2.value', '"M"'); -shouldBe('parserGeneratedInput3.value', '"NO"'); -shouldBe('parserGeneratedInput4.value', '""'); -shouldBe('parserGeneratedInput5.value', '"PQRST"'); -shouldBe('parserGeneratedInput6.value', '""'); -shouldBe('parserGeneratedInput7.value', '""'); -shouldBe('parserGeneratedInput8.value', '""'); -shouldBe('parserGeneratedInput9.value', '""'); +assert_equals(parserGeneratedInput1.value, 'L'); +assert_equals(parserGeneratedInput2.value, 'M'); +assert_equals(parserGeneratedInput3.value, 'NO'); +assert_equals(parserGeneratedInput4.value, ''); +assert_equals(parserGeneratedInput5.value, 'PQRST'); +assert_equals(parserGeneratedInput6.value, ''); +assert_equals(parserGeneratedInput7.value, ''); +assert_equals(parserGeneratedInput8.value, ''); +assert_equals(parserGeneratedInput9.value, ''); -debug('\nTesting a single fieldset element.'); +// Testing a single fieldset element. var fieldSet = document.createElement('fieldset'); document.body.appendChild(fieldSet); var textInput = document.createElement('input'); textInput.type = "text"; fieldSet.appendChild(textInput); -debug('Verifying HTMLFormControl can be disabled regardless of enclosing fieldset.'); +// Verifying HTMLFormControl can be disabled regardless of enclosing fieldset. textInput.disabled = true; -shouldBeTrue('textInput.disabled'); +assert_true(textInput.disabled); textInput.focus(); document.execCommand('insertText', false, 'A'); -shouldBe('textInput.value', '""'); -shouldBeFalse('fieldSet.disabled'); +assert_equals(textInput.value, ''); +assert_false(fieldSet.disabled); textInput.disabled = false; -debug('Fieldset is enabled by default. A user can insertText into the text input field.'); +// Fieldset is enabled by default. A user can insertText into the text input field. textInput.focus(); document.execCommand('insertText', false, 'A'); -shouldBe('textInput.value', '"A"'); +assert_equals(textInput.value, 'A'); -debug('Disable fieldset.'); +// Disable fieldset. fieldSet.disabled = true; -shouldBeTrue('fieldSet.disabled'); +assert_true(fieldSet.disabled); -debug('Once the fieldset is disabled, text cannot be inserted.'); +// Once the fieldset is disabled, text cannot be inserted. textInput.focus(); document.execCommand('insertText', false, 'B'); -shouldBe('textInput.value', '"A"'); +assert_equals(textInput.value, 'A'); -debug("Check if the style of the text element changed."); -shouldBe("getComputedStyle(textInput).backgroundColor", "'rgb(255, 0, 0)'"); +// Check if the style of the text element changed. +assert_equals(getComputedStyle(textInput).backgroundColor, 'rgb(255, 0, 0)'); -debug('Enable fieldset.'); +// Enable fieldset. fieldSet.disabled = false; -shouldBeFalse('fieldSet.disabled'); -shouldBe("getComputedStyle(textInput).backgroundColor", "'rgb(255, 255, 100)'"); +assert_false(fieldSet.disabled); +assert_equals(getComputedStyle(textInput).backgroundColor, 'rgb(255, 255, 100)'); textInput.focus(); document.execCommand('insertText', false, 'B'); -shouldBe('textInput.value', '"AB"'); +assert_equals(textInput.value, 'AB'); -debug('Move the textinput element out of the fieldset.'); +// Move the textinput element out of the fieldset. fieldSet.removeChild(textInput); document.body.appendChild(textInput); -debug('Disable the fieldset.'); +// Disable the fieldset. fieldSet.disabled = true; -shouldBeTrue('fieldSet.disabled'); +assert_true(fieldSet.disabled); -debug('Text can be inserted, because the textinput element is outside of the disabled fieldset.'); +// Text can be inserted, because the textinput element is outside of the disabled fieldset. textInput.focus(); document.execCommand('insertText', false, 'C'); -shouldBe('textInput.value', '"ABC"'); +assert_equals(textInput.value, 'ABC'); -debug('Enable the fieldset.'); +// Enable the fieldset. fieldSet.disabled = false; -shouldBeFalse('fieldSet.disabled'); +assert_false(fieldSet.disabled); -debug('Insert a table into the fieldset.'); +// Insert a table into the fieldset. var table = document.createElement('table'); fieldSet.appendChild(table); var tr = document.createElement('tr'); @@ -143,33 +144,33 @@ var td = document.createElement('td'); tr.appendChild(td); -debug('Move the textinput field into the table.'); +// Move the textinput field into the table. document.body.removeChild(textInput); td.appendChild(textInput); textInput.focus(); document.execCommand('insertText', false, 'D'); -shouldBe('textInput.value', '"ABCD"'); +assert_equals(textInput.value, 'ABCD'); -debug('Disable the fieldset.'); +// Disable the fieldset. fieldSet.disabled = true; -shouldBeTrue('fieldSet.disabled'); +assert_true(fieldSet.disabled); -debug('Inserting text should fail.') +// Inserting text should fail. textInput.focus(); document.execCommand('insertText', false, 'E'); -shouldBe('textInput.value', '"ABCD"'); +assert_equals(textInput.value, 'ABCD'); -debug('Enable the fieldset.'); +// Enable the fieldset. fieldSet.disabled = false; -shouldBeFalse('fieldSet.disabled'); +assert_false(fieldSet.disabled); textInput.focus(); document.execCommand('insertText', false, 'E'); -shouldBe('textInput.value', '"ABCDE"'); +assert_equals(textInput.value, 'ABCDE'); -debug('\nTesting nested fieldset elements.'); +// Testing nested fieldset elements. var outerFieldSet = document.createElement('fieldset'); document.body.appendChild(outerFieldSet); var innerFieldSet = document.createElement('fieldset'); @@ -181,62 +182,62 @@ innerTextInput.type = "text"; innerFieldSet.appendChild(innerTextInput); -debug('Verifying that subordinates of both fieldsets are enabled.'); +// Verifying that subordinates of both fieldsets are enabled. outerTextInput.focus(); document.execCommand('insertText', false, 'F'); innerTextInput.focus(); document.execCommand('insertText', false, 'F'); -shouldBe('outerTextInput.value', '"F"'); -shouldBe('innerTextInput.value', '"F"'); +assert_equals(outerTextInput.value, 'F'); +assert_equals(innerTextInput.value, 'F'); -debug('Disabling the inner fieldset only.'); +// Disabling the inner fieldset only. innerFieldSet.disabled = true; -shouldBeTrue('innerFieldSet.disabled'); +assert_true(innerFieldSet.disabled); outerTextInput.focus(); document.execCommand('insertText', false, 'G'); innerTextInput.focus(); document.execCommand('insertText', false, 'G'); -shouldBe('outerTextInput.value', '"FGG"'); -shouldBe('innerTextInput.value', '"F"'); +assert_equals(outerTextInput.value, 'FGG'); +assert_equals(innerTextInput.value, 'F'); -debug('Enabling the inner and disabling the outer fieldset.'); +// Enabling the inner and disabling the outer fieldset. outerFieldSet.disabled = true; innerFieldSet.disabled = false; -shouldBeTrue('outerFieldSet.disabled'); -shouldBeFalse('innerFieldSet.disabled'); +assert_true(outerFieldSet.disabled); +assert_false(innerFieldSet.disabled); outerTextInput.focus(); document.execCommand('insertText', false, 'H'); innerTextInput.focus(); document.execCommand('insertText', false, 'H'); -shouldBe('outerTextInput.value', '"FGG"'); -shouldBe('innerTextInput.value', '"F"'); +assert_equals(outerTextInput.value, 'FGG'); +assert_equals(innerTextInput.value, 'F'); -debug('Disabling both fieldset elements.'); +// Disabling both fieldset elements. outerFieldSet.disabled = true; innerFieldSet.disabled = true; -shouldBeTrue('outerFieldSet.disabled'); -shouldBeTrue('innerFieldSet.disabled'); +assert_true(outerFieldSet.disabled); +assert_true(innerFieldSet.disabled); outerTextInput.focus(); document.execCommand('insertText', false, 'H'); innerTextInput.focus(); document.execCommand('insertText', false, 'H'); -shouldBe('outerTextInput.value', '"FGG"'); -shouldBe('innerTextInput.value', '"F"'); +assert_equals(outerTextInput.value, 'FGG'); +assert_equals(innerTextInput.value, 'F'); -debug('Enabling both fieldset elements.'); +// Enabling both fieldset elements. outerFieldSet.disabled = false; innerFieldSet.disabled = false; -shouldBeFalse('outerFieldSet.disabled'); -shouldBeFalse('innerFieldSet.disabled'); +assert_false(outerFieldSet.disabled); +assert_false(innerFieldSet.disabled); outerTextInput.focus(); document.execCommand('insertText', false, 'H'); innerTextInput.focus(); document.execCommand('insertText', false, 'H'); -shouldBe('outerTextInput.value', '"FGGH"'); -shouldBe('innerTextInput.value', '"FH"'); +assert_equals(outerTextInput.value, 'FGGH'); +assert_equals(innerTextInput.value, 'FH'); -debug('\nTest behavior of the first legend element in a fieldset elements.'); +// Test behavior of the first legend element in a fieldset elements. var legendFieldSet = document.createElement('fieldset'); document.body.appendChild(legendFieldSet); var firstLegend = document.createElement('legend'); @@ -252,17 +253,17 @@ secondLegendTextInput.type = "text"; secondLegend.appendChild(secondLegendTextInput); -debug('Children of the first legend element in a fieldset should not get disabled with the fieldset.'); +// Children of the first legend element in a fieldset should not get disabled with the fieldset. legendFieldSet.disabled = true; -shouldBeTrue('legendFieldSet.disabled'); +assert_true(legendFieldSet.disabled); firstLegendTextInput.focus(); document.execCommand('insertText', false, 'I'); secondLegendTextInput.focus() document.execCommand('insertText', false, 'I'); -shouldBe('firstLegendTextInput.value', '"II"'); -shouldBe('secondLegendTextInput.value', '""'); +assert_equals(firstLegendTextInput.value, 'II'); +assert_equals(secondLegendTextInput.value, ''); -debug('Insert another legend element before the currently first one, and check again.'); +// Insert another legend element before the currently first one, and check again. var insertedLegend = document.createElement('legend'); legendFieldSet.insertBefore(insertedLegend, firstLegend); var insertedLegendTextInput = document.createElement('input'); @@ -274,26 +275,27 @@ document.execCommand('insertText', false, 'J'); secondLegendTextInput.focus() document.execCommand('insertText', false, 'J'); -shouldBe('insertedLegendTextInput.value', '"JJJ"'); -shouldBe('firstLegendTextInput.value', '"II"'); -shouldBe('secondLegendTextInput.value', '""'); +assert_equals(insertedLegendTextInput.value, 'JJJ'); +assert_equals(firstLegendTextInput.value, 'II'); +assert_equals(secondLegendTextInput.value, ''); -debug('Enable the fieldset again and check for sanity.'); +// Enable the fieldset again and check for sanity. legendFieldSet.disabled = false; -shouldBeFalse('legendFieldSet.disabled'); +assert_false(legendFieldSet.disabled); insertedLegendTextInput.focus(); document.execCommand('insertText', false, 'K'); firstLegendTextInput.focus(); document.execCommand('insertText', false, 'K'); secondLegendTextInput.focus() document.execCommand('insertText', false, 'K'); -shouldBe('insertedLegendTextInput.value', '"JJJK"'); -shouldBe('firstLegendTextInput.value', '"IIK"'); -shouldBe('secondLegendTextInput.value', '"K"'); +assert_equals(insertedLegendTextInput.value, 'JJJK'); +assert_equals(firstLegendTextInput.value, 'IIK'); +assert_equals(secondLegendTextInput.value, 'K'); var disabledFieldsetWithTabindex = document.getElementById('fieldset-tabindex'); document.activeElement.blur(); -shouldBe('disabledFieldsetWithTabindex.focus(); document.activeElement', 'document.body'); +disabledFieldsetWithTabindex.focus(); +assert_equals(document.activeElement, disabledFieldsetWithTabindex); document.body.removeChild(document.getElementsByTagName('form')[0]); document.body.removeChild(fieldSet); @@ -301,6 +303,7 @@ document.body.removeChild(legendFieldSet); document.body.removeChild(disabledFieldsetWithTabindex); var successfullyParsed = true; +}, 'Tests for HTMLFieldSetElement.disabled behavior.'); </script> </body>
diff --git a/third_party/closure_compiler/externs/runtime.js b/third_party/closure_compiler/externs/runtime.js index e6e6935..bc5666d 100644 --- a/third_party/closure_compiler/externs/runtime.js +++ b/third_party/closure_compiler/externs/runtime.js
@@ -1,4 +1,4 @@ -// Copyright 2022 The Chromium Authors +// 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. @@ -160,6 +160,34 @@ }; /** + * @enum {string} + * @see https://developer.chrome.com/extensions/runtime#type-ContextType + */ +chrome.runtime.ContextType = { + TAB: 'TAB', + POPUP: 'POPUP', + BACKGROUND: 'BACKGROUND', + OFFSCREEN_DOCUMENT: 'OFFSCREEN_DOCUMENT', +}; + +/** + * A context hosting extension content. + * @typedef {{ + * contextType: !chrome.runtime.ContextType, + * contextId: string, + * tabId: number, + * windowId: number, + * documentId: (string|undefined), + * frameId: number, + * documentUrl: (string|undefined), + * documentOrigin: (string|undefined), + * incognito: boolean + * }} + * @see https://developer.chrome.com/extensions/runtime#type-ExtensionContext + */ +chrome.runtime.ExtensionContext; + +/** * This will be defined during an API method callback if there was an error * @typedef {{ * message: (string|undefined) @@ -250,10 +278,13 @@ * version is very far out of date and you'd like to prompt a user to update. * Most other uses of requestUpdateCheck, such as calling it unconditionally * based on a repeating timer, probably only serve to waste client, network, and - * server resources.</p> - * @param {function(!chrome.runtime.RequestUpdateCheckStatus, ({ - * version: string - * }|undefined)): void} callback + * server resources.</p><p>Note: When called with a callback, instead of + * returning an object this function will return the two properties as separate + * arguments passed to the callback.</p> + * @param {function({ + * status: !chrome.runtime.RequestUpdateCheckStatus, + * version: (string|undefined) + * }): void} callback * @see https://developer.chrome.com/extensions/runtime#method-requestUpdateCheck */ chrome.runtime.requestUpdateCheck = function(callback) {}; @@ -280,13 +311,12 @@ chrome.runtime.restartAfterDelay = function(seconds, callback) {}; /** - * Attempts to connect listeners within an extension/app (such as the - * background page), or other extensions/apps. This is useful for content - * scripts connecting to their extension processes, inter-app/extension - * communication, and <a href="manifest/externally_connectable.html">web - * messaging</a>. Note that this does not connect to any listeners in a content - * script. Extensions may connect to content scripts embedded in tabs via - * $(ref:tabs.connect). + * Attempts to connect listeners within an extension/app (such as the background + * page), or other extensions/apps. This is useful for content scripts + * connecting to their extension processes, inter-app/extension communication, + * and <a href="manifest/externally_connectable.html">web messaging</a>. Note + * that this does not connect to any listeners in a content script. Extensions + * may connect to content scripts embedded in tabs via $(ref:tabs.connect). * @param {string=} extensionId The ID of the extension or app to connect to. If * omitted, a connection will be attempted with your own extension. Required * if sending messages from a web page for <a @@ -362,6 +392,14 @@ chrome.runtime.getPackageDirectoryEntry = function(callback) {}; /** + * Fetches information about active contexts associated with this extension + * @param {function(!Array<!chrome.runtime.ExtensionContext>): void} callback + * Invoked with the matching contexts, if any. + * @see https://developer.chrome.com/extensions/runtime#method-getContexts + */ +chrome.runtime.getContexts = function(callback) {}; + +/** * Fired when a profile that has this extension installed first starts up. This * event is not fired when an incognito profile is started, even if this * extension is operating in 'split' incognito mode.
diff --git a/third_party/libxml/README.chromium b/third_party/libxml/README.chromium index 8d0700c..866d5419 100644 --- a/third_party/libxml/README.chromium +++ b/third_party/libxml/README.chromium
@@ -1,6 +1,6 @@ Name: libxml URL: http://xmlsoft.org -Version: 44ecefc8cc299a66ac21ffec141eb261e92638da +Version: 1061537efdf3874c91fd50d18f98c4b8a3518e52 CPEPrefix: cpe:/a:xmlsoft:libxml2:2.11.0 License: MIT License File: src/Copyright
diff --git a/third_party/libxml/src/HTMLparser.c b/third_party/libxml/src/HTMLparser.c index 81bd11f..abcdfe2 100644 --- a/third_party/libxml/src/HTMLparser.c +++ b/third_party/libxml/src/HTMLparser.c
@@ -411,7 +411,7 @@ return(ctxt->token); } - if ((ctxt->input->end - ctxt->input->cur < 4) && + if ((ctxt->input->end - ctxt->input->cur < INPUT_CHUNK) && (xmlParserGrow(ctxt) < 0)) return(0); @@ -3010,9 +3010,9 @@ htmlParseErr(ctxt, XML_ERR_LITERAL_NOT_FINISHED, "Unfinished SystemLiteral\n", NULL, NULL); } else { - NEXT; if (err == 0) ret = xmlStrndup((BASE_PTR+startPosition), len); + NEXT; } return(ret); @@ -3065,9 +3065,9 @@ htmlParseErr(ctxt, XML_ERR_LITERAL_NOT_FINISHED, "Unfinished PubidLiteral\n", NULL, NULL); } else { - NEXT; if (err == 0) ret = xmlStrndup((BASE_PTR + startPosition), len); + NEXT; } return(ret); @@ -3100,7 +3100,6 @@ int nbchar = 0; int cur,l; - SHRINK; cur = CUR_CHAR(l); while (cur != 0) { if ((cur == '<') && (NXT(1) == '/')) { @@ -3358,7 +3357,6 @@ * this is a Processing Instruction. */ SKIP(2); - SHRINK; /* * Parse the target name and check for special support like @@ -3481,7 +3479,6 @@ state = ctxt->instate; ctxt->instate = XML_PARSER_COMMENT; - SHRINK; SKIP(4); buf = (xmlChar *) xmlMallocAtomic(size); if (buf == NULL) { @@ -4477,8 +4474,8 @@ htmlParseCharData(ctxt); } - GROW; SHRINK; + GROW; } if (currentNode != NULL) xmlFree(currentNode); } @@ -4920,8 +4917,8 @@ htmlParseCharData(ctxt); } - GROW; SHRINK; + GROW; } if (currentNode != NULL) xmlFree(currentNode); }
diff --git a/third_party/libxml/src/encoding.c b/third_party/libxml/src/encoding.c index 101eba9..7eaaf3e 100644 --- a/third_party/libxml/src/encoding.c +++ b/third_party/libxml/src/encoding.c
@@ -197,7 +197,7 @@ } else { *outlen = out - outstart; *inlen = processed - base; - return(-1); + return(-2); } processed = (const unsigned char*) in; @@ -2037,7 +2037,7 @@ * as the return value is 0, else unpredictable. * The value of @outlen after return is the number of octets produced. */ -static int +int xmlEncInputChunk(xmlCharEncodingHandler *handler, unsigned char *out, int *outlen, const unsigned char *in, int *inlen, int flush) { int ret; @@ -2123,189 +2123,12 @@ * @out: an xmlBuffer for the output. * @in: an xmlBuffer for the input * - * Front-end for the encoding handler input function, but handle only - * the very first line, i.e. limit itself to 45 chars. - * - * Returns the number of byte written if success, or - * -1 general error - * -2 if the transcoding fails (for *in is not valid utf8 string or - * the result of transformation can't fit into the encoding we want), or + * DEPERECATED: Don't use. */ int xmlCharEncFirstLine(xmlCharEncodingHandler *handler, xmlBufferPtr out, xmlBufferPtr in) { - int ret; - int written; - int toconv; - - if (handler == NULL) return(-1); - if (out == NULL) return(-1); - if (in == NULL) return(-1); - - /* calculate space available */ - written = out->size - out->use - 1; /* count '\0' */ - toconv = in->use; - /* - * echo '<?xml version="1.0" encoding="UCS4"?>' | wc -c => 38 - * 45 chars should be sufficient to reach the end of the encoding - * declaration without going too far inside the document content. - * on UTF-16 this means 90bytes, on UCS4 this means 180 - * The actual value depending on guessed encoding is passed as @len - * if provided - */ - if (toconv > 180) - toconv = 180; - if (toconv * 2 >= written) { - xmlBufferGrow(out, toconv * 2); - written = out->size - out->use - 1; - } - - ret = xmlEncInputChunk(handler, &out->content[out->use], &written, - in->content, &toconv, 0); - xmlBufferShrink(in, toconv); - out->use += written; - out->content[out->use] = 0; - if (ret == -1) ret = -3; - -#ifdef DEBUG_ENCODING - switch (ret) { - case 0: - xmlGenericError(xmlGenericErrorContext, - "converted %d bytes to %d bytes of input\n", - toconv, written); - break; - case -1: - xmlGenericError(xmlGenericErrorContext,"converted %d bytes to %d bytes of input, %d left\n", - toconv, written, in->use); - break; - case -2: - xmlGenericError(xmlGenericErrorContext, - "input conversion failed due to input error\n"); - break; - case -3: - xmlGenericError(xmlGenericErrorContext,"converted %d bytes to %d bytes of input, %d left\n", - toconv, written, in->use); - break; - default: - xmlGenericError(xmlGenericErrorContext,"Unknown input conversion failed %d\n", ret); - } -#endif /* DEBUG_ENCODING */ - /* - * Ignore when input buffer is not on a boundary - */ - if (ret == -3) ret = 0; - if (ret == -1) ret = 0; - return(written ? written : ret); -} - -/** - * xmlCharEncFirstLineInput: - * @input: a parser input buffer - * @len: number of bytes to convert for the first line, or -1 - * - * Front-end for the encoding handler input function, but handle only - * the very first line. Point is that this is based on autodetection - * of the encoding and once that first line is converted we may find - * out that a different decoder is needed to process the input. - * - * Returns the number of byte written if success, or - * -1 general error - * -2 if the transcoding fails (for *in is not valid utf8 string or - * the result of transformation can't fit into the encoding we want), or - */ -int -xmlCharEncFirstLineInput(xmlParserInputBufferPtr input, int len) -{ - int ret; - size_t written; - size_t toconv; - int c_in; - int c_out; - xmlBufPtr in; - xmlBufPtr out; - - if ((input == NULL) || (input->encoder == NULL) || - (input->buffer == NULL) || (input->raw == NULL)) - return (-1); - out = input->buffer; - in = input->raw; - - toconv = xmlBufUse(in); - if (toconv == 0) - return (0); - written = xmlBufAvail(out); - /* - * echo '<?xml version="1.0" encoding="UCS4"?>' | wc -c => 38 - * 45 chars should be sufficient to reach the end of the encoding - * declaration without going too far inside the document content. - * on UTF-16 this means 90bytes, on UCS4 this means 180 - * The actual value depending on guessed encoding is passed as @len - * if provided - */ - if (len >= 0) { - if (toconv > (unsigned int) len) - toconv = len; - } else { - if (toconv > 180) - toconv = 180; - } - if (toconv * 2 >= written) { - xmlBufGrow(out, toconv * 2); - written = xmlBufAvail(out); - } - if (written > 360) - written = 360; - - c_in = toconv; - c_out = written; - ret = xmlEncInputChunk(input->encoder, xmlBufEnd(out), &c_out, - xmlBufContent(in), &c_in, 0); - xmlBufShrink(in, c_in); - xmlBufAddLen(out, c_out); - if (ret == -1) - ret = -3; - - switch (ret) { - case 0: -#ifdef DEBUG_ENCODING - xmlGenericError(xmlGenericErrorContext, - "converted %d bytes to %d bytes of input\n", - c_in, c_out); -#endif - break; - case -1: -#ifdef DEBUG_ENCODING - xmlGenericError(xmlGenericErrorContext, - "converted %d bytes to %d bytes of input, %d left\n", - c_in, c_out, (int)xmlBufUse(in)); -#endif - break; - case -3: -#ifdef DEBUG_ENCODING - xmlGenericError(xmlGenericErrorContext, - "converted %d bytes to %d bytes of input, %d left\n", - c_in, c_out, (int)xmlBufUse(in)); -#endif - break; - case -2: { - char buf[50]; - const xmlChar *content = xmlBufContent(in); - - snprintf(&buf[0], 49, "0x%02X 0x%02X 0x%02X 0x%02X", - content[0], content[1], - content[2], content[3]); - buf[49] = 0; - xmlEncodingErr(XML_I18N_CONV_FAILED, - "input conversion failed due to input error, bytes %s\n", - buf); - } - } - /* - * Ignore when input buffer is not on a boundary - */ - if (ret == -3) ret = 0; - if (ret == -1) ret = 0; - return(c_out ? c_out : ret); + return(xmlCharEncInFunc(handler, out, in)); } /**
diff --git a/third_party/libxml/src/include/libxml/encoding.h b/third_party/libxml/src/include/libxml/encoding.h index 231b0be1..67add3b 100644 --- a/third_party/libxml/src/include/libxml/encoding.h +++ b/third_party/libxml/src/include/libxml/encoding.h
@@ -203,6 +203,7 @@ xmlCharEncInFunc (xmlCharEncodingHandler *handler, xmlBufferPtr out, xmlBufferPtr in); +XML_DEPRECATED XMLPUBFUN int xmlCharEncFirstLine (xmlCharEncodingHandler *handler, xmlBufferPtr out,
diff --git a/third_party/libxml/src/include/private/enc.h b/third_party/libxml/src/include/private/enc.h index ddfc8aea..cbdc2b33 100644 --- a/third_party/libxml/src/include/private/enc.h +++ b/third_party/libxml/src/include/private/enc.h
@@ -8,7 +8,8 @@ xmlInitEncodingInternal(void); XML_HIDDEN int -xmlCharEncFirstLineInput(xmlParserInputBufferPtr input, int len); +xmlEncInputChunk(xmlCharEncodingHandler *handler, unsigned char *out, + int *outlen, const unsigned char *in, int *inlen, int flush); XML_HIDDEN int xmlCharEncInput(xmlParserInputBufferPtr input, int flush); XML_HIDDEN int
diff --git a/third_party/libxml/src/include/private/parser.h b/third_party/libxml/src/include/private/parser.h index 18036db..820bb587 100644 --- a/third_party/libxml/src/include/private/parser.h +++ b/third_party/libxml/src/include/private/parser.h
@@ -27,7 +27,7 @@ xmlHaltParser(xmlParserCtxtPtr ctxt); XML_HIDDEN int xmlParserGrow(xmlParserCtxtPtr ctxt); -XML_HIDDEN int +XML_HIDDEN void xmlParserShrink(xmlParserCtxtPtr ctxt); #endif /* XML_PARSER_H_PRIVATE__ */
diff --git a/third_party/libxml/src/parser.c b/third_party/libxml/src/parser.c index 8e548cd..3a6069c8 100644 --- a/third_party/libxml/src/parser.c +++ b/third_party/libxml/src/parser.c
@@ -4183,7 +4183,6 @@ xmlChar stop; int state = ctxt->instate; - SHRINK; if (RAW == '"') { NEXT; stop = '"'; @@ -4265,7 +4264,6 @@ xmlChar stop; xmlParserInputState oldstate = ctxt->instate; - SHRINK; if (RAW == '"') { NEXT; stop = '"'; @@ -4387,7 +4385,6 @@ int col = ctxt->input->col; int ccol; - SHRINK; GROW; /* * Accelerated common case where input don't need to be @@ -4533,7 +4530,6 @@ int nbchar = 0; int cur, l; - SHRINK; cur = CUR_CHAR(l); while ((cur != '<') && /* checked */ (cur != '&') && @@ -4629,8 +4625,6 @@ xmlParseExternalID(xmlParserCtxtPtr ctxt, xmlChar **publicID, int strict) { xmlChar *URI = NULL; - SHRINK; - *publicID = NULL; if (CMP6(CUR_PTR, 'S', 'Y', 'S', 'T', 'E', 'M')) { SKIP(6); @@ -4847,7 +4841,6 @@ ctxt->instate = XML_PARSER_COMMENT; inputid = ctxt->input->id; SKIP(2); - SHRINK; GROW; /* @@ -5133,7 +5126,6 @@ * this is a Processing Instruction. */ SKIP(2); - SHRINK; /* * Parse the target name and check for special support like @@ -5272,7 +5264,6 @@ if (CMP8(CUR_PTR, 'N', 'O', 'T', 'A', 'T', 'I', 'O', 'N')) { int inputid = ctxt->input->id; - SHRINK; SKIP(8); if (SKIP_BLANKS == 0) { xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED, @@ -5360,7 +5351,6 @@ /* GROW; done in the caller */ if (CMP6(CUR_PTR, 'E', 'N', 'T', 'I', 'T', 'Y')) { int inputid = ctxt->input->id; - SHRINK; SKIP(6); if (SKIP_BLANKS == 0) { xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED, @@ -5684,7 +5674,6 @@ xmlFatalErr(ctxt, XML_ERR_NOTATION_NOT_STARTED, NULL); return(NULL); } - SHRINK; do { NEXT; SKIP_BLANKS; @@ -5756,7 +5745,6 @@ xmlFatalErr(ctxt, XML_ERR_ATTLIST_NOT_STARTED, NULL); return(NULL); } - SHRINK; do { NEXT; SKIP_BLANKS; @@ -5885,7 +5873,6 @@ */ int xmlParseAttributeType(xmlParserCtxtPtr ctxt, xmlEnumerationPtr *tree) { - SHRINK; if (CMP5(CUR_PTR, 'C', 'D', 'A', 'T', 'A')) { SKIP(5); return(XML_ATTRIBUTE_CDATA); @@ -6070,7 +6057,6 @@ if (CMP7(CUR_PTR, '#', 'P', 'C', 'D', 'A', 'T', 'A')) { SKIP(7); SKIP_BLANKS; - SHRINK; if (RAW == ')') { if (ctxt->input->id != inputchk) { xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY, @@ -6242,7 +6228,6 @@ GROW; } SKIP_BLANKS; - SHRINK; while ((RAW != ')') && (ctxt->instate != XML_PARSER_EOF)) { /* * Each loop we parse one separator and one element. @@ -6787,6 +6772,7 @@ break; SKIP_BLANKS; + SHRINK; GROW; } @@ -7018,6 +7004,7 @@ return; } SKIP_BLANKS; + SHRINK; } if (RAW != 0) { @@ -8343,6 +8330,8 @@ return; } SKIP_BLANKS; + SHRINK; + GROW; } if (RAW == ']') { NEXT; @@ -9229,14 +9218,6 @@ if (RAW != '<') return(NULL); NEXT1; - /* - * NOTE: it is crucial with the SAX2 API to never call SHRINK beyond that - * point since the attribute values may be stored as pointers to - * the buffer and calling SHRINK would destroy them ! - * The Shrinking is only possible once the full set of attribute - * callbacks have been done. - */ - SHRINK; cur = ctxt->input->cur - ctxt->input->base; inputid = ctxt->input->id; nbatts = 0; @@ -9881,8 +9862,8 @@ xmlParseCharData(ctxt, 0); } - GROW; SHRINK; + GROW; } } @@ -10248,6 +10229,9 @@ xmlChar *buf = NULL; int len = 0; int size = 10; + int maxLength = (ctxt->options & XML_PARSE_HUGE) ? + XML_MAX_TEXT_LENGTH : + XML_MAX_NAME_LENGTH; xmlChar cur; cur = CUR; @@ -10280,13 +10264,13 @@ buf = tmp; } buf[len++] = cur; + if (len > maxLength) { + xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "EncName"); + xmlFree(buf); + return(NULL); + } NEXT; cur = CUR; - if (cur == 0) { - SHRINK; - GROW; - cur = CUR; - } } buf[len] = 0; } else { @@ -10383,6 +10367,7 @@ else if ((encoding != NULL) && ((!xmlStrcasecmp(encoding, BAD_CAST "UTF-8")) || (!xmlStrcasecmp(encoding, BAD_CAST "UTF8")))) { + /* TODO: Check for encoding mismatch. */ if (ctxt->encoding != NULL) xmlFree((xmlChar *) ctxt->encoding); ctxt->encoding = encoding; @@ -10708,15 +10693,7 @@ return(-1); } - /* - * Check for the XMLDecl in the Prolog. - * do not GROW here to avoid the detected encoder to decode more - * than just the first line, unless the amount of data is really - * too small to hold "<?xml version="1.0" encoding="foo" - */ - if ((ctxt->input->end - ctxt->input->cur) < 35) { - GROW; - } + GROW; if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) { /* @@ -11363,12 +11340,9 @@ /* * If we are operating on converted input, try to flush * remaining chars to avoid them stalling in the non-converted - * buffer. But do not do this in document start where - * encoding="..." may not have been read and we work on a - * guessed encoding. + * buffer. */ - if ((ctxt->instate != XML_PARSER_START) && - (ctxt->input->buf->raw != NULL) && + if ((ctxt->input->buf->raw != NULL) && (xmlBufIsEmpty(ctxt->input->buf->raw) == 0)) { size_t base = xmlBufGetInputBase(ctxt->input->buf->buffer, ctxt->input); @@ -11411,6 +11385,13 @@ start[2] = NXT(2); start[3] = NXT(3); enc = xmlDetectCharEncoding(start, 4); + /* + * We need more bytes to detect EBCDIC code pages. + * See xmlDetectEBCDIC. + */ + if ((enc == XML_CHAR_ENCODING_EBCDIC) && + (!terminate) && (avail < 200)) + goto done; xmlSwitchEncoding(ctxt, enc); break; } @@ -12202,15 +12183,8 @@ xmlParserCtxtPtr ctxt; xmlParserInputPtr inputStream; xmlParserInputBufferPtr buf; - xmlCharEncoding enc = XML_CHAR_ENCODING_NONE; - /* - * plug some encoding conversion routines - */ - if ((chunk != NULL) && (size >= 4)) - enc = xmlDetectCharEncoding((const xmlChar *) chunk, size); - - buf = xmlAllocParserInputBuffer(enc); + buf = xmlAllocParserInputBuffer(XML_CHAR_ENCODING_NONE); if (buf == NULL) return(NULL); ctxt = xmlNewSAXParserCtxt(sax, user_data); @@ -12269,10 +12243,6 @@ #endif } - if (enc != XML_CHAR_ENCODING_NONE) { - xmlSwitchEncoding(ctxt, enc); - } - return(ctxt); } #endif /* LIBXML_PUSH_ENABLED */
diff --git a/third_party/libxml/src/parserInternals.c b/third_party/libxml/src/parserInternals.c index dd16579..8dc6005 100644 --- a/third_party/libxml/src/parserInternals.c +++ b/third_party/libxml/src/parserInternals.c
@@ -409,17 +409,16 @@ * xmlParserShrink: * @ctxt: an XML parser context */ -int +void xmlParserShrink(xmlParserCtxtPtr ctxt) { xmlParserInputPtr in = ctxt->input; xmlParserInputBufferPtr buf = in->buf; size_t used; - int ret = 0; /* Don't shrink memory buffers. */ if ((buf == NULL) || ((buf->encoder == NULL) && (buf->readcallback == NULL))) - return(0); + return; used = in->cur - in->base; /* @@ -439,18 +438,7 @@ } } - if (xmlBufUse(buf->buffer) < INPUT_CHUNK) - ret = xmlParserInputBufferGrow(buf, INPUT_CHUNK); - xmlBufSetInputBaseCur(buf->buffer, in, 0, used); - - /* TODO: Get error code from xmlParserInputBufferGrow */ - if (ret < 0) { - xmlErrInternal(ctxt, "Growing input buffer", NULL); - xmlHaltParser(ctxt); - } - - return(ret); } /** @@ -539,7 +527,7 @@ return; } - if (ctxt->input->end - ctxt->input->cur < 4) { + if (ctxt->input->end - ctxt->input->cur < INPUT_CHUNK) { if (xmlParserGrow(ctxt) < 0) return; if (ctxt->input->cur >= ctxt->input->end) @@ -686,7 +674,7 @@ if (ctxt->instate == XML_PARSER_EOF) return(0); - if ((ctxt->input->end - ctxt->input->cur < 4) && + if ((ctxt->input->end - ctxt->input->cur < INPUT_CHUNK) && (xmlParserGrow(ctxt) < 0)) return(0); @@ -1002,9 +990,63 @@ * * ************************************************************************/ -static int -xmlSwitchInputEncodingInt(xmlParserCtxtPtr ctxt, xmlParserInputPtr input, - xmlCharEncodingHandlerPtr handler, int len); +static xmlCharEncodingHandlerPtr +xmlDetectEBCDIC(xmlParserInputPtr input) { + xmlChar out[200]; + xmlCharEncodingHandlerPtr handler; + int inlen, outlen, res, i; + + /* + * To detect the EBCDIC code page, we convert the first 200 bytes + * to EBCDIC-US and try to find the encoding declaration. + */ + handler = xmlGetCharEncodingHandler(XML_CHAR_ENCODING_EBCDIC); + if (handler == NULL) + return(NULL); + outlen = sizeof(out) - 1; + inlen = input->end - input->cur; + res = xmlEncInputChunk(handler, out, &outlen, input->cur, &inlen, 0); + if (res < 0) + return(handler); + out[outlen] = 0; + + for (i = 0; i < outlen; i++) { + if (out[i] == '>') + break; + if ((out[i] == 'e') && + (xmlStrncmp(out + i, BAD_CAST "encoding", 8) == 0)) { + int start, cur, quote; + + i += 8; + while (IS_BLANK_CH(out[i])) + i += 1; + if (out[i++] != '=') + break; + while (IS_BLANK_CH(out[i])) + i += 1; + quote = out[i++]; + if ((quote != '\'') && (quote != '"')) + break; + start = i; + cur = out[i]; + while (((cur >= 'a') && (cur <= 'z')) || + ((cur >= 'A') && (cur <= 'Z')) || + ((cur >= '0') && (cur <= '9')) || + (cur == '.') || (cur == '_') || + (cur == '-')) + cur = out[++i]; + if (cur != quote) + break; + out[i] = 0; + xmlCharEncCloseFunc(handler); + handler = xmlFindCharEncodingHandler((char *) out + start); + break; + } + } + + return(handler); +} + /** * xmlSwitchEncoding: * @ctxt: the parser context @@ -1019,7 +1061,6 @@ xmlSwitchEncoding(xmlParserCtxtPtr ctxt, xmlCharEncoding enc) { xmlCharEncodingHandlerPtr handler; - int len = -1; int ret; if (ctxt == NULL) return(-1); @@ -1048,51 +1089,13 @@ ctxt->input->cur += 3; } return(0); - case XML_CHAR_ENCODING_UTF16LE: - case XML_CHAR_ENCODING_UTF16BE: - /*The raw input characters are encoded - *in UTF-16. As we expect this function - *to be called after xmlCharEncInFunc, we expect - *ctxt->input->cur to contain UTF-8 encoded characters. - *So the raw UTF16 Byte Order Mark - *has also been converted into - *an UTF-8 BOM. Let's skip that BOM. - */ - if ((ctxt->input != NULL) && (ctxt->input->cur != NULL) && - (ctxt->input->cur[0] == 0xEF) && - (ctxt->input->cur[1] == 0xBB) && - (ctxt->input->cur[2] == 0xBF)) { - ctxt->input->cur += 3; - } - len = 90; - break; - case XML_CHAR_ENCODING_UCS2: - len = 90; - break; - case XML_CHAR_ENCODING_UCS4BE: - case XML_CHAR_ENCODING_UCS4LE: - case XML_CHAR_ENCODING_UCS4_2143: - case XML_CHAR_ENCODING_UCS4_3412: - len = 180; - break; - case XML_CHAR_ENCODING_EBCDIC: - case XML_CHAR_ENCODING_8859_1: - case XML_CHAR_ENCODING_8859_2: - case XML_CHAR_ENCODING_8859_3: - case XML_CHAR_ENCODING_8859_4: - case XML_CHAR_ENCODING_8859_5: - case XML_CHAR_ENCODING_8859_6: - case XML_CHAR_ENCODING_8859_7: - case XML_CHAR_ENCODING_8859_8: - case XML_CHAR_ENCODING_8859_9: - case XML_CHAR_ENCODING_ASCII: - case XML_CHAR_ENCODING_2022_JP: - case XML_CHAR_ENCODING_SHIFT_JIS: - case XML_CHAR_ENCODING_EUC_JP: - len = 45; - break; + case XML_CHAR_ENCODING_EBCDIC: + handler = xmlDetectEBCDIC(ctxt->input); + break; + default: + handler = xmlGetCharEncodingHandler(enc); + break; } - handler = xmlGetCharEncodingHandler(enc); if (handler == NULL) { /* * Default handlers. @@ -1124,7 +1127,7 @@ return(-1); } } - ret = xmlSwitchInputEncodingInt(ctxt, ctxt->input, handler, len); + ret = xmlSwitchInputEncoding(ctxt, ctxt->input, handler); if ((ret < 0) || (ctxt->errNo == XML_I18N_CONV_FAILED)) { /* * on encoding conversion errors, stop the parser @@ -1136,20 +1139,19 @@ } /** - * xmlSwitchInputEncodingInt: + * xmlSwitchInputEncoding: * @ctxt: the parser context * @input: the input stream * @handler: the encoding handler - * @len: the number of bytes to convert for the first line or -1 * * change the input functions when discovering the character encoding * of a given entity. * * Returns 0 in case of success, -1 otherwise */ -static int -xmlSwitchInputEncodingInt(xmlParserCtxtPtr ctxt, xmlParserInputPtr input, - xmlCharEncodingHandlerPtr handler, int len) +int +xmlSwitchInputEncoding(xmlParserCtxtPtr ctxt, xmlParserInputPtr input, + xmlCharEncodingHandlerPtr handler) { int nbchars; xmlParserInputBufferPtr in; @@ -1171,30 +1173,17 @@ return (-1); } - ctxt->charset = XML_CHAR_ENCODING_UTF8; - if (in->encoder != NULL) { /* - * Check in case the auto encoding detection triggered - * in already. + * TODO: Detect encoding mismatch. We should start by comparing + * in->encoder->name and handler->name, but there are a few + * compatible encodings like UTF-16 and UCS-2 or UTF-32 and UCS-4. */ - if (in->encoder == handler) - return (0); - - /* - * Note: this is a bit dangerous, but that's what it - * takes to use nearly compatible signature for different - * encodings. - * - * FIXME: Encoders might buffer partial byte sequences, so - * this probably can't work. We should return an error and - * make sure that callers never try to switch the encoding - * twice. - */ - xmlCharEncCloseFunc(in->encoder); - in->encoder = handler; + xmlCharEncCloseFunc(handler); return (0); } + + ctxt->charset = XML_CHAR_ENCODING_UTF8; in->encoder = handler; /* @@ -1242,20 +1231,7 @@ in->rawconsumed = processed; use = xmlBufUse(in->raw); - if (ctxt->html) { - /* - * convert as much as possible of the buffer - */ - nbchars = xmlCharEncInput(in, 1); - } else { - /* - * convert just enough to get - * '<?xml version="1.0" encoding="xxx"?>' - * parsed with the autodetected encoding - * into the parser reading buffer. - */ - nbchars = xmlCharEncFirstLineInput(in, len); - } + nbchars = xmlCharEncInput(in, 0); xmlBufResetInput(in->buffer, input); if (nbchars < 0) { xmlErrInternal(ctxt, @@ -1274,25 +1250,6 @@ } /** - * xmlSwitchInputEncoding: - * @ctxt: the parser context - * @input: the input stream - * @handler: the encoding handler - * - * DEPRECATED: Use xmlSwitchToEncoding - * - * change the input functions when discovering the character encoding - * of a given entity. - * - * Returns 0 in case of success, -1 otherwise - */ -int -xmlSwitchInputEncoding(xmlParserCtxtPtr ctxt, xmlParserInputPtr input, - xmlCharEncodingHandlerPtr handler) { - return(xmlSwitchInputEncodingInt(ctxt, input, handler, -1)); -} - -/** * xmlSwitchToEncoding: * @ctxt: the parser context * @handler: the encoding handler @@ -1307,7 +1264,7 @@ { if (ctxt == NULL) return(-1); - return(xmlSwitchInputEncodingInt(ctxt, ctxt->input, handler, -1)); + return(xmlSwitchInputEncoding(ctxt, ctxt->input, handler)); } /************************************************************************
diff --git a/third_party/libxslt/README.chromium b/third_party/libxslt/README.chromium index 1c7d2bcc..a225d68 100644 --- a/third_party/libxslt/README.chromium +++ b/third_party/libxslt/README.chromium
@@ -1,6 +1,6 @@ Name: libxslt URL: http://xmlsoft.org/XSLT -Version: 0203b5c5fa9c2d8197e0df7b6fd131be855ef173 +Version: f80ae929fa9e80d66d4c42108c6fb2456ce14b8b CPEPrefix: cpe:/a:xmlsoft:libxslt:1.1.37 Security Critical: yes License: MIT
diff --git a/third_party/libxslt/chromium/xslt-locale.patch b/third_party/libxslt/chromium/xslt-locale.patch index 88398ce..4e8ef110 100644 --- a/third_party/libxslt/chromium/xslt-locale.patch +++ b/third_party/libxslt/chromium/xslt-locale.patch
@@ -5,39 +5,41 @@ POSIX and Windows locale support, we preserve the behavior WebKit expects in XsltUnicodeSortFunction. -diff --git a/src/libxslt/xsltlocale.h b/src/libxslt/xsltlocale.h ---- src/libxslt/xsltlocale.h -+++ src/libxslt/xsltlocale.h -@@ -14,7 +14,12 @@ - #include <libxml/xmlstring.h> - #include "xsltexports.h" +In addition, it would seem that strxfrm_l is not supported on Fuchsia as using +it without this patch causes a compile error. + +diff --git a/libxslt/xsltlocale.c b/libxslt/xsltlocale.c +index 5a929188..9324f284 100644 +--- a/libxslt/xsltlocale.c ++++ b/libxslt/xsltlocale.c +@@ -19,29 +19,7 @@ + #include "xsltlocale.h" + #include "xsltutils.h" -#ifdef HAVE_STRXFRM_L -+#if defined(_WIN32) && !defined(__CYGWIN__) -+#include <windows.h> -+#include <winnls.h> -+#endif -+ -+#if 0 - - /* - * XSLT_LOCALE_POSIX: -@@ -32,7 +37,7 @@ - typedef locale_t xsltLocale; - typedef xmlChar xsltLocaleChar; - --#elif defined(_WIN32) -+#elif 0 - - /* - * XSLT_LOCALE_WINAPI: -@@ -40,9 +45,6 @@ - */ - #define XSLT_LOCALE_WINAPI - --#include <windows.h> --#include <winnls.h> - - typedef LCID xsltLocale; - typedef wchar_t xsltLocaleChar; +- #define XSLT_LOCALE_POSIX +- +- #ifdef HAVE_LOCALE_H +- #include <locale.h> +- #endif +- #ifdef HAVE_XLOCALE_H +- #include <xlocale.h> +- #endif +- +-#elif defined(_WIN32) +- +- #define XSLT_LOCALE_WINAPI +- +- #include <windows.h> +- #include <winnls.h> +- +-#else +- +- #define XSLT_LOCALE_NONE +- +-#endif ++#define XSLT_LOCALE_NONE + #define TOUPPER(c) (c & ~0x20) + #define TOLOWER(c) (c | 0x20)
diff --git a/third_party/libxslt/src/README b/third_party/libxslt/src/README deleted file mode 100644 index 94402947..0000000 --- a/third_party/libxslt/src/README +++ /dev/null
@@ -1,22 +0,0 @@ - - XSLT support for libxml2 (XML toolkit from the GNOME project) - -Full documentation is available on-line at - https://gitlab.gnome.org/GNOME/libxslt/-/wikis - -This code is released under the MIT Licence see the Copyright file. - -To report bugs, follow the instructions at: - https://gitlab.gnome.org/GNOME/libxslt/-/issues - -A mailing-list xslt@gnome.org is available, to subscribe: - http://mail.gnome.org/mailman/listinfo/xslt - -The list archive is at: - http://mail.gnome.org/archives/xslt/ - -All technical answers asked privately will be automatically answered on -the list and archived for public access unless pricacy is explicitely -required and justified. - -Daniel Veillard
diff --git a/third_party/libxslt/src/README.md b/third_party/libxslt/src/README.md new file mode 100644 index 0000000..ff0d56f --- /dev/null +++ b/third_party/libxslt/src/README.md
@@ -0,0 +1,19 @@ +# libxslt + +libxslt is an XSLT processor based on libxml2. + +Official releases can be downloaded from +<https://download.gnome.org/sources/libxslt/> + +The git repository is hosted on GNOME's GitLab server: +<https://gitlab.gnome.org/GNOME/libxslt> + +Bugs should be reported at +<https://gitlab.gnome.org/GNOME/libxslt/-/issues> + +Documentation is available at +<https://gitlab.gnome.org/GNOME/libxslt/-/wikis> + +The build system is similar to libxml2. Refer to libxml2's README for +build instructions. +
diff --git a/third_party/libxslt/src/configure.ac b/third_party/libxslt/src/configure.ac index 8064c7bc..540a2f2 100644 --- a/third_party/libxslt/src/configure.ac +++ b/third_party/libxslt/src/configure.ac
@@ -564,7 +564,5 @@ xslt-config libxslt.spec ]) -AC_CONFIG_LINKS([tests/fuzz/xpath.xml:tests/fuzz/xpath.xml]) -AC_CONFIG_LINKS([tests/fuzz/xslt.xml:tests/fuzz/xslt.xml]) AC_OUTPUT
diff --git a/third_party/libxslt/src/libexslt/date.c b/third_party/libxslt/src/libexslt/date.c index 60d353d..21214a1f 100644 --- a/third_party/libxslt/src/libexslt/date.c +++ b/third_party/libxslt/src/libexslt/date.c
@@ -227,37 +227,39 @@ } /** - * FORMAT_GYEAR: + * exsltFormatGYear: + * @cur: a pointer to a pointer to an allocated buffer + * @end: a pointer to the end of @cur buffer * @yr: the year to format - * @cur: a pointer to an allocated buffer * * Formats @yr in xsl:gYear format. Result is appended to @cur and * @cur is updated to point after the xsl:gYear. */ -#define FORMAT_GYEAR(yr, cur) \ - if (yr <= 0) { \ - *cur = '-'; \ - cur++; \ - } \ - { \ - long year = (yr <= 0) ? -yr + 1 : yr; \ - xmlChar tmp_buf[100], *tmp = tmp_buf; \ - /* result is in reverse-order */ \ - while (year > 0) { \ - *tmp = '0' + (xmlChar)(year % 10); \ - year /= 10; \ - tmp++; \ - } \ - /* virtually adds leading zeros */ \ - while ((tmp - tmp_buf) < 4) \ - *tmp++ = '0'; \ - /* restore the correct order */ \ - while (tmp > tmp_buf) { \ - tmp--; \ - *cur = *tmp; \ - cur++; \ - } \ - } +static void +exsltFormatGYear(xmlChar **cur, xmlChar *end, long yr) +{ + if (yr <= 0 && *cur < end) { + *(*cur)++ = '-'; + } + + long year = (yr <= 0) ? -yr + 1 : yr; + xmlChar tmp_buf[100], *tmp = tmp_buf, *tmp_end = tmp_buf + 99; + /* result is in reverse-order */ + while (year > 0 && tmp < tmp_end) { + *tmp++ = '0' + (xmlChar)(year % 10); + year /= 10; + } + + /* virtually adds leading zeros */ + while ((tmp - tmp_buf) < 4) + *tmp++ = '0'; + + /* restore the correct order */ + while (tmp > tmp_buf && *cur < end) { + tmp--; + *(*cur)++ = *tmp; + } +} /** * PARSE_2_DIGITS: @@ -286,18 +288,22 @@ cur += 2; /** - * FORMAT_2_DIGITS: - * @num: the integer to format - * @cur: a pointer to an allocated buffer + * exsltFormat2Digits: + * @cur: a pointer to a pointer to an allocated buffer + * @end: a pointer to the end of @cur buffer + * @num: the integer to format * * Formats a 2-digits integer. Result is appended to @cur and * @cur is updated to point after the integer. */ -#define FORMAT_2_DIGITS(num, cur) \ - *cur = '0' + ((num / 10) % 10); \ - cur++; \ - *cur = '0' + (num % 10); \ - cur++; +static void +exsltFormat2Digits(xmlChar **cur, xmlChar *end, unsigned int num) +{ + if (*cur < end) + *(*cur)++ = '0' + ((num / 10) % 10); + if (*cur < end) + *(*cur)++ = '0' + (num % 10); +} /** * PARSE_FLOAT: @@ -326,29 +332,6 @@ } /** - * FORMAT_FLOAT: - * @num: the double to format - * @cur: a pointer to an allocated buffer - * @pad: a flag for padding to 2 integer digits - * - * Formats a float. Result is appended to @cur and @cur is updated to - * point after the integer. If the @pad flag is non-zero, then the - * float representation has a minimum 2-digits integer part. The - * fractional part is formatted if @num has a fractional value. - */ -#define FORMAT_FLOAT(num, cur, pad) \ - { \ - xmlChar *sav, *str; \ - if ((pad) && (num < 10.0)) \ - *cur++ = '0'; \ - str = xmlXPathCastNumberToString(num); \ - sav = str; \ - while (*str != 0) \ - *cur++ = *str++; \ - xmlFree(sav); \ - } - -/** * _exsltDateParseGMonth: * @dt: pointer to a date structure * @str: pointer to the string to analyze @@ -380,17 +363,6 @@ } /** - * FORMAT_GMONTH: - * @mon: the month to format - * @cur: a pointer to an allocated buffer - * - * Formats @mon in xsl:gMonth format. Result is appended to @cur and - * @cur is updated to point after the xsl:gMonth. - */ -#define FORMAT_GMONTH(mon, cur) \ - FORMAT_2_DIGITS(mon, cur) - -/** * _exsltDateParseGDay: * @dt: pointer to a date structure * @str: pointer to the string to analyze @@ -422,32 +394,25 @@ } /** - * FORMAT_GDAY: + * exsltFormatYearMonthDay: + * @cur: a pointer to a pointer to an allocated buffer + * @end: a pointer to the end of @cur buffer * @dt: the #exsltDateVal to format - * @cur: a pointer to an allocated buffer - * - * Formats @dt in xsl:gDay format. Result is appended to @cur and - * @cur is updated to point after the xsl:gDay. - */ -#define FORMAT_GDAY(dt, cur) \ - FORMAT_2_DIGITS(dt->day, cur) - -/** - * FORMAT_DATE: - * @dt: the #exsltDateVal to format - * @cur: a pointer to an allocated buffer * * Formats @dt in xsl:date format. Result is appended to @cur and * @cur is updated to point after the xsl:date. */ -#define FORMAT_DATE(dt, cur) \ - FORMAT_GYEAR(dt->year, cur); \ - *cur = '-'; \ - cur++; \ - FORMAT_GMONTH(dt->mon, cur); \ - *cur = '-'; \ - cur++; \ - FORMAT_GDAY(dt, cur); +static void +exsltFormatYearMonthDay(xmlChar **cur, xmlChar *end, const exsltDateValPtr dt) +{ + exsltFormatGYear(cur, end, dt->year); + if (*cur < end) + *(*cur)++ = '-'; + exsltFormat2Digits(cur, end, dt->mon); + if (*cur < end) + *(*cur)++ = '-'; + exsltFormat2Digits(cur, end, dt->day); +} /** * _exsltDateParseTime: @@ -506,23 +471,6 @@ } /** - * FORMAT_TIME: - * @dt: the #exsltDateVal to format - * @cur: a pointer to an allocated buffer - * - * Formats @dt in xsl:time format. Result is appended to @cur and - * @cur is updated to point after the xsl:time. - */ -#define FORMAT_TIME(dt, cur) \ - FORMAT_2_DIGITS(dt->hour, cur); \ - *cur = ':'; \ - cur++; \ - FORMAT_2_DIGITS(dt->min, cur); \ - *cur = ':'; \ - cur++; \ - FORMAT_FLOAT(dt->sec, cur, 1); - -/** * _exsltDateParseTimeZone: * @dt: pointer to a date structure * @str: pointer to the string to analyze @@ -600,27 +548,31 @@ } /** - * FORMAT_TZ: - * @tzo: the timezone offset to format - * @cur: a pointer to an allocated buffer + * exsltFormatTimeZone: + * @cur: a pointer to a pointer to an allocated buffer + * @end: a pointer to the end of @cur buffer + * @tzo: the timezone offset to format * * Formats @tzo timezone. Result is appended to @cur and * @cur is updated to point after the timezone. */ -#define FORMAT_TZ(tzo, cur) \ - if (tzo == 0) { \ - *cur = 'Z'; \ - cur++; \ - } else { \ - int aTzo = (tzo < 0) ? - tzo : tzo; \ - int tzHh = aTzo / 60, tzMm = aTzo % 60; \ - *cur = (tzo < 0) ? '-' : '+' ; \ - cur++; \ - FORMAT_2_DIGITS(tzHh, cur); \ - *cur = ':'; \ - cur++; \ - FORMAT_2_DIGITS(tzMm, cur); \ - } +static void +exsltFormatTimeZone(xmlChar **cur, xmlChar *end, int tzo) +{ + if (tzo == 0) { + if (*cur < end) + *(*cur)++ = 'Z'; + } else { + unsigned int aTzo = (tzo < 0) ? -tzo : tzo; + unsigned int tzHh = aTzo / 60, tzMm = aTzo % 60; + if (*cur < end) + *(*cur)++ = (tzo < 0) ? '-' : '+'; + exsltFormat2Digits(cur, end, tzHh); + if (*cur < end) + *(*cur)++ = ':'; + exsltFormat2Digits(cur, end, tzMm); + } +} /**************************************************************** * * @@ -718,7 +670,7 @@ exsltDateCurrent (void) { struct tm localTm, gmTm; -#ifndef HAVE_GMTIME_R +#if !defined(HAVE_GMTIME_R) && !defined(_WIN32) struct tm *tb = NULL; #endif time_t secs; @@ -740,7 +692,11 @@ errno = 0; secs = (time_t) strtol (source_date_epoch, NULL, 10); if (errno == 0) { -#if HAVE_GMTIME_R +#ifdef _WIN32 + struct tm *gm = gmtime_s(&localTm, &secs) ? NULL : &localTm; + if (gm != NULL) + override = 1; +#elif HAVE_GMTIME_R if (gmtime_r(&secs, &localTm) != NULL) override = 1; #else @@ -757,7 +713,9 @@ /* get current time */ secs = time(NULL); -#if HAVE_LOCALTIME_R +#ifdef _WIN32 + localtime_s(&localTm, &secs); +#elif HAVE_LOCALTIME_R localtime_r(&secs, &localTm); #else localTm = *localtime(&secs); @@ -776,7 +734,9 @@ ret->sec = (double) localTm.tm_sec; /* determine the time zone offset from local to gm time */ -#if HAVE_GMTIME_R +#ifdef _WIN32 + gmtime_s(&gmTm, &secs); +#elif HAVE_GMTIME_R gmtime_r(&secs, &gmTm); #else tb = gmtime(&secs); @@ -1138,21 +1098,41 @@ return NULL; } -/** - * FORMAT_ITEM: - * @num: number to format - * @cur: current location to convert number - * @limit: max value - * @item: char designator - * - */ -#define FORMAT_ITEM(num, cur, limit, item) \ - if (num >= limit) { \ - double comp = floor(num / limit); \ - FORMAT_FLOAT(comp, cur, 0); \ - *cur++ = item; \ - num -= comp * limit; \ +static void +exsltFormatLong(xmlChar **cur, xmlChar *end, long num) { + xmlChar buf[20]; + int i = 0; + + while (i < 20) { + buf[i++] = '0' + num % 10; + num /= 10; + if (num == 0) + break; + } + + while (i > 0) { + if (*cur < end) + *(*cur)++ = buf[--i]; + } +} + +static void +exsltFormatNanoseconds(xmlChar **cur, xmlChar *end, long nsecs) { + long p10, digit; + + if (nsecs > 0) { + if (*cur < end) + *(*cur)++ = '.'; + p10 = 100000000; + while (nsecs > 0) { + digit = nsecs / p10; + if (*cur < end) + *(*cur)++ = '0' + digit; + nsecs -= digit * p10; + p10 /= 10; } + } +} /** * exsltDateFormatDuration: @@ -1165,9 +1145,9 @@ static xmlChar * exsltDateFormatDuration (const exsltDateDurValPtr dur) { - xmlChar buf[100], *cur = buf; - double secs, days; - double years, months; + xmlChar buf[100], *cur = buf, *end = buf + 99; + double secs, tmp; + long days, months, intSecs, nsecs; if (dur == NULL) return NULL; @@ -1177,9 +1157,8 @@ return xmlStrdup((xmlChar*)"P0D"); secs = dur->sec; - days = (double)dur->day; - years = (double)(dur->mon / 12); - months = (double)(dur->mon % 12); + days = dur->day; + months = dur->mon; *cur = '\0'; if (days < 0) { @@ -1190,10 +1169,6 @@ days = -days; *cur = '-'; } - if (years < 0) { - years = -years; - *cur = '-'; - } if (months < 0) { months = -months; *cur = '-'; @@ -1203,23 +1178,64 @@ *cur++ = 'P'; - if (years != 0.0) { - FORMAT_ITEM(years, cur, 1, 'Y'); + if (months >= 12) { + long years = months / 12; + + months -= years * 12; + exsltFormatLong(&cur, end, years); + if (cur < end) + *cur++ = 'Y'; } - if (months != 0.0) { - FORMAT_ITEM(months, cur, 1, 'M'); + if (months != 0) { + exsltFormatLong(&cur, end, months); + if (cur < end) + *cur++ = 'M'; } - FORMAT_ITEM(days, cur, 1, 'D'); - if (secs > 0.0) { - *cur++ = 'T'; + if (days != 0) { + exsltFormatLong(&cur, end, days); + if (cur < end) + *cur++ = 'D'; } - FORMAT_ITEM(secs, cur, SECS_PER_HOUR, 'H'); - FORMAT_ITEM(secs, cur, SECS_PER_MIN, 'M'); - if (secs > 0.0) { - FORMAT_FLOAT(secs, cur, 0); - *cur++ = 'S'; + + tmp = floor(secs); + intSecs = (long) tmp; + /* Round to nearest to avoid issues with floating point precision */ + nsecs = (long) floor((secs - tmp) * 1000000000 + 0.5); + if (nsecs >= 1000000000) { + nsecs -= 1000000000; + intSecs += 1; + } + + if ((intSecs > 0) || (nsecs > 0)) { + if (cur < end) + *cur++ = 'T'; + + if (intSecs >= SECS_PER_HOUR) { + long hours = intSecs / SECS_PER_HOUR; + + intSecs -= hours * SECS_PER_HOUR; + exsltFormatLong(&cur, end, hours); + if (cur < end) + *cur++ = 'H'; + } + + if (intSecs >= SECS_PER_MIN) { + long mins = intSecs / SECS_PER_MIN; + + intSecs -= mins * SECS_PER_MIN; + exsltFormatLong(&cur, end, mins); + if (cur < end) + *cur++ = 'M'; + } + + if ((intSecs > 0) || (nsecs > 0)) { + exsltFormatLong(&cur, end, intSecs); + exsltFormatNanoseconds(&cur, end, nsecs); + if (cur < end) + *cur++ = 'S'; + } } *cur = 0; @@ -1227,6 +1243,42 @@ return xmlStrdup(buf); } +static void +exsltFormatTwoDigits(xmlChar **cur, xmlChar *end, int num) { + if (num < 0 || num >= 100) + return; + if (*cur < end) + *(*cur)++ = '0' + num / 10; + if (*cur < end) + *(*cur)++ = '0' + num % 10; +} + +static void +exsltFormatTime(xmlChar **cur, xmlChar *end, exsltDateValPtr dt) { + double tmp; + long intSecs, nsecs; + + exsltFormatTwoDigits(cur, end, dt->hour); + if (*cur < end) + *(*cur)++ = ':'; + + exsltFormatTwoDigits(cur, end, dt->min); + if (*cur < end) + *(*cur)++ = ':'; + + tmp = floor(dt->sec); + intSecs = (long) tmp; + /* + * Round to nearest to avoid issues with floating point precision, + * but don't carry over so seconds stay below 60. + */ + nsecs = (long) floor((dt->sec - tmp) * 1000000000 + 0.5); + if (nsecs > 999999999) + nsecs = 999999999; + exsltFormatTwoDigits(cur, end, intSecs); + exsltFormatNanoseconds(cur, end, nsecs); +} + /** * exsltDateFormatDateTime: * @dt: an #exsltDateValPtr @@ -1238,16 +1290,16 @@ static xmlChar * exsltDateFormatDateTime (const exsltDateValPtr dt) { - xmlChar buf[100], *cur = buf; + xmlChar buf[100], *cur = buf, *end = buf + 99; if ((dt == NULL) || !VALID_DATETIME(dt)) return NULL; - FORMAT_DATE(dt, cur); - *cur = 'T'; - cur++; - FORMAT_TIME(dt, cur); - FORMAT_TZ(dt->tzo, cur); + exsltFormatYearMonthDay(&cur, end, dt); + if (cur < end) + *cur++ = 'T'; + exsltFormatTime(&cur, end, dt); + exsltFormatTimeZone(&cur, end, dt->tzo); *cur = 0; return xmlStrdup(buf); @@ -1264,14 +1316,14 @@ static xmlChar * exsltDateFormatDate (const exsltDateValPtr dt) { - xmlChar buf[100], *cur = buf; + xmlChar buf[100], *cur = buf, *end = buf + 99; if ((dt == NULL) || !VALID_DATETIME(dt)) return NULL; - FORMAT_DATE(dt, cur); + exsltFormatYearMonthDay(&cur, end, dt); if (dt->tz_flag || (dt->tzo != 0)) { - FORMAT_TZ(dt->tzo, cur); + exsltFormatTimeZone(&cur, end, dt->tzo); } *cur = 0; @@ -1289,14 +1341,14 @@ static xmlChar * exsltDateFormatTime (const exsltDateValPtr dt) { - xmlChar buf[100], *cur = buf; + xmlChar buf[100], *cur = buf, *end = buf + 99; if ((dt == NULL) || !VALID_TIME(dt)) return NULL; - FORMAT_TIME(dt, cur); + exsltFormatTime(&cur, end, dt); if (dt->tz_flag || (dt->tzo != 0)) { - FORMAT_TZ(dt->tzo, cur); + exsltFormatTimeZone(&cur, end, dt->tzo); } *cur = 0; @@ -1316,7 +1368,6 @@ static xmlChar * exsltDateFormat (const exsltDateValPtr dt) { - if (dt == NULL) return NULL; @@ -1332,17 +1383,17 @@ } if (dt->type & XS_GYEAR) { - xmlChar buf[100], *cur = buf; + xmlChar buf[100], *cur = buf, *end = buf + 99; - FORMAT_GYEAR(dt->year, cur); + exsltFormatGYear(&cur, end, dt->year); if (dt->type == XS_GYEARMONTH) { - *cur = '-'; - cur++; - FORMAT_GMONTH(dt->mon, cur); + if (cur < end) + *cur++ = '-'; + exsltFormat2Digits(&cur, end, dt->mon); } if (dt->tz_flag || (dt->tzo != 0)) { - FORMAT_TZ(dt->tzo, cur); + exsltFormatTimeZone(&cur, end, dt->tzo); } *cur = 0; return xmlStrdup(buf); @@ -1689,16 +1740,16 @@ exsltDateDurValPtr y) { /* months */ - if ((x->mon > 0 && y->mon > LONG_MAX - x->mon) || - (x->mon < 0 && y->mon < LONG_MIN - x->mon)) { + if ((x->mon > 0 && y->mon > LONG_MAX - x->mon) || + (x->mon < 0 && y->mon <= LONG_MIN - x->mon)) { /* Overflow */ return 0; } ret->mon = x->mon + y->mon; /* days */ - if ((x->day > 0 && y->day > LONG_MAX - x->day) || - (x->day < 0 && y->day < LONG_MIN - x->day)) { + if ((x->day > 0 && y->day > LONG_MAX - x->day) || + (x->day < 0 && y->day <= LONG_MIN - x->day)) { /* Overflow */ return 0; }
diff --git a/third_party/libxslt/src/libexslt/functions.c b/third_party/libxslt/src/libexslt/functions.c index 6babf0d..9497d7e 100644 --- a/third_party/libxslt/src/libexslt/functions.c +++ b/third_party/libxslt/src/libexslt/functions.c
@@ -114,6 +114,7 @@ xsltGenericError(xsltGenericErrorContext, "Failed to register function {%s}%s\n", URI, name); + xmlFree(func); } else { /* Do the registration */ xsltGenericDebug(xsltGenericDebugContext, "exsltFuncRegisterImportFunc: register {%s}%s\n", @@ -185,9 +186,11 @@ void *vdata) { exsltFuncData *data = (exsltFuncData *) vdata; - if (data->result != NULL) - xmlXPathFreeObject(data->result); - xmlFree(data); + if (data != NULL) { + if (data->result != NULL) + xmlXPathFreeObject(data->result); + xmlFree(data); + } } /** @@ -286,16 +289,12 @@ exsltFuncData *data; exsltFuncFunctionData *func; xmlNodePtr paramNode, oldInsert, oldXPNode, fake; - int oldBase; + int oldBase, newBase; void *oldCtxtVar; xsltStackElemPtr params = NULL, param; xsltTransformContextPtr tctxt = xsltXPathGetTransformContext(ctxt); - int i, notSet; - struct objChain { - struct objChain *next; - xmlXPathObjectPtr obj; - }; - struct objChain *savedObjChain = NULL, *savedObj; + int i; + xmlXPathObjectPtr *args = NULL; /* * retrieve func:function template @@ -357,6 +356,10 @@ /* Evaluating templates can change the XPath context node. */ oldXPNode = tctxt->xpathCtxt->node; + fake = xmlNewDocNode(tctxt->output, NULL, + (const xmlChar *)"fake", NULL); + if (fake == NULL) + goto error; /* * We have a problem with the evaluation of function parameters. * The original library code did not evaluate XPath expressions until @@ -379,16 +382,15 @@ * In order to give the function params and variables a new 'scope' * we change varsBase in the context. */ - oldBase = tctxt->varsBase; - tctxt->varsBase = tctxt->varsNr; + newBase = tctxt->varsNr; /* If there are any parameters */ if (paramNode != NULL) { + args = (xmlXPathObjectPtr *) xmlMalloc(sizeof(*args) * nargs); + if (args == NULL) + goto error; /* Fetch the stored argument values from the caller */ - for (i = 0; i < nargs; i++) { - savedObj = xmlMalloc(sizeof(struct objChain)); - savedObj->next = savedObjChain; - savedObj->obj = valuePop(ctxt); - savedObjChain = savedObj; + for (i = nargs - 1; i >= 0; i--) { + args[i] = valuePop(ctxt); } /* @@ -405,17 +407,20 @@ * as arguments from the caller * Calculate the number of un-set parameters */ - notSet = func->nargs - nargs; - for (; i > 0; i--) { + for (i = 0; i < func->nargs; i++) { param = xsltParseStylesheetCallerParam (tctxt, paramNode); - if (i > notSet) { /* if parameter value set */ + if (param == NULL) { + xsltLocalVariablePop(tctxt, newBase, -2); + xsltFreeStackElemList(params); + for (; i < nargs; i++) + xmlXPathFreeObject(args[i]); + goto error; + } + if (i < nargs) { /* if parameter value set */ param->computed = 1; if (param->value != NULL) xmlXPathFreeObject(param->value); - savedObj = savedObjChain; /* get next val from chain */ - param->value = savedObj->obj; - savedObjChain = savedObjChain->next; - xmlFree(savedObj); + param->value = args[i]; } xsltLocalVariablePush(tctxt, param, -1); param->next = params; @@ -427,11 +432,11 @@ * Actual processing. The context variable is cleared and restored * when func:result is evaluated. */ - fake = xmlNewDocNode(tctxt->output, NULL, - (const xmlChar *)"fake", NULL); + oldBase = tctxt->varsBase; oldInsert = tctxt->insert; oldCtxtVar = data->ctxtVar; data->ctxtVar = tctxt->contextVariable; + tctxt->varsBase = newBase; tctxt->insert = fake; tctxt->contextVariable = NULL; xsltApplyOneTemplate (tctxt, tctxt->node, @@ -470,14 +475,14 @@ "{%s}%s: cannot write to result tree while " "executing a function\n", ctxt->context->functionURI, ctxt->context->function); - xmlFreeNode(fake); xmlXPathFreeObject(ret); goto error; } - xmlFreeNode(fake); valuePush(ctxt, ret); error: + xmlFree(args); + xmlFreeNode(fake); tctxt->depth--; }
diff --git a/third_party/libxslt/src/libexslt/saxon.c b/third_party/libxslt/src/libexslt/saxon.c index 8512c6d..6166b15 100644 --- a/third_party/libxslt/src/libexslt/saxon.c +++ b/third_party/libxslt/src/libexslt/saxon.c
@@ -98,13 +98,18 @@ ret = xmlHashLookup(hash, arg); if (ret == NULL) { - ret = xmlXPathCtxtCompile(tctxt->xpathCtxt, arg); - if (ret == NULL) { - xmlFree(arg); - xmlXPathSetError(ctxt, XPATH_EXPR_ERROR); - return; - } - xmlHashAddEntry(hash, arg, (void *) ret); + ret = xmlXPathCtxtCompile(tctxt->xpathCtxt, arg); + if (ret == NULL) { + xmlFree(arg); + xmlXPathSetError(ctxt, XPATH_EXPR_ERROR); + return; + } + if (xmlHashAddEntry(hash, arg, (void *) ret) < 0) { + xmlXPathFreeCompExpr(ret); + xmlFree(arg); + xmlXPathSetError(ctxt, XPATH_MEMORY_ERROR); + return; + } } xmlFree(arg);
diff --git a/third_party/libxslt/src/libexslt/sets.c b/third_party/libxslt/src/libexslt/sets.c index a4b5546..357fe2c0 100644 --- a/third_party/libxslt/src/libexslt/sets.c +++ b/third_party/libxslt/src/libexslt/sets.c
@@ -112,13 +112,15 @@ /* !!! must be sorted !!! */ ret = xmlXPathDistinctSorted(ns); - if (ret != ns) - xmlXPathFreeNodeSet(ns); + if (ret != ns) + xmlXPathFreeNodeSet(ns); obj = xmlXPathWrapNodeSet(ret); - obj->user = user; - obj->boolval = boolval; - valuePush((ctxt), obj); + if (obj != NULL) { + obj->user = user; + obj->boolval = boolval; + } + valuePush(ctxt, obj); } /**
diff --git a/third_party/libxslt/src/libxslt/attributes.c b/third_party/libxslt/src/libxslt/attributes.c index 28a0841..4cc49d0d 100644 --- a/third_party/libxslt/src/libxslt/attributes.c +++ b/third_party/libxslt/src/libxslt/attributes.c
@@ -87,6 +87,7 @@ struct _xsltAttrSetContext { xsltStylesheetPtr topStyle; xsltStylesheetPtr style; + int error; }; static void @@ -421,9 +422,12 @@ set = xmlHashLookup2(style->attributeSets, ncname, nsUri); if (set == NULL) { set = xsltNewAttrSet(); - if (set == NULL) + if ((set == NULL) || + (xmlHashAddEntry2(style->attributeSets, ncname, nsUri, set) < 0)) { + xsltGenericError(xsltGenericErrorContext, "memory error\n"); + xsltFreeAttrSet(set); return; - xmlHashAddEntry2(style->attributeSets, ncname, nsUri, set); + } } /* @@ -663,6 +667,12 @@ xsltStylesheetPtr topStyle = asctx->topStyle; xsltStylesheetPtr style = asctx->style; + if (asctx->error) { + if (style != topStyle) + xsltFreeAttrSet(set); + return; + } + xsltResolveAttrSet(set, topStyle, style, name, ns, 1); /* Move attribute sets to top stylesheet. */ @@ -675,6 +685,8 @@ xsltGenericError(xsltGenericErrorContext, "xsl:attribute-set : internal error, can't move imported " " attribute set %s\n", name); + asctx->error = 1; + xsltFreeAttrSet(set); } } } @@ -695,6 +707,7 @@ "Resolving attribute sets references\n"); #endif asctx.topStyle = style; + asctx.error = 0; cur = style; while (cur != NULL) { if (cur->attributeSets != NULL) {
diff --git a/third_party/libxslt/src/libxslt/attrvt.c b/third_party/libxslt/src/libxslt/attrvt.c index a885526..6157fcd 100644 --- a/third_party/libxslt/src/libxslt/attrvt.c +++ b/third_party/libxslt/src/libxslt/attrvt.c
@@ -155,10 +155,8 @@ size_t size = sizeof(xsltAttrVT) + (avt->max_seg + MAX_AVT_SEG) * sizeof(void *); xsltAttrVTPtr tmp = (xsltAttrVTPtr) xmlRealloc(avt, size); - if (tmp == NULL) { - xsltFreeAttrVT(avt); + if (tmp == NULL) return NULL; - } avt = tmp; memset(&avt->segments[avt->nb_seg], 0, MAX_AVT_SEG*sizeof(void *)); avt->max_seg += MAX_AVT_SEG; @@ -182,6 +180,7 @@ const xmlChar *cur; xmlChar *ret = NULL; xmlChar *expr = NULL; + xmlXPathCompExprPtr comp = NULL; xsltAttrVTPtr avt; int i = 0, lastavt = 0; @@ -280,8 +279,6 @@ XSLT_TODO goto error; } else { - xmlXPathCompExprPtr comp; - comp = xsltXPathCompile(style, expr); if (comp == NULL) { xsltTransformError(NULL, style, attr->parent, @@ -293,14 +290,21 @@ if (avt->nb_seg == 0) avt->strstart = 0; if (lastavt == 1) { - if ((avt = xsltSetAttrVTsegment(avt, NULL)) == NULL) + if ((avt = xsltSetAttrVTsegment(avt, NULL)) == NULL) { + xsltTransformError(NULL, style, attr->parent, + "out of memory\n"); goto error; + } } - if ((avt = xsltSetAttrVTsegment(avt, (void *) comp)) == NULL) + if ((avt = xsltSetAttrVTsegment(avt, (void *) comp)) == NULL) { + xsltTransformError(NULL, style, attr->parent, + "out of memory\n"); goto error; + } lastavt = 1; xmlFree(expr); expr = NULL; + comp = NULL; } cur++; str = cur; @@ -350,6 +354,8 @@ xmlFree(ret); if (expr != NULL) xmlFree(expr); + if (comp != NULL) + xmlXPathFreeCompExpr(comp); }
diff --git a/third_party/libxslt/src/libxslt/documents.c b/third_party/libxslt/src/libxslt/documents.c index 4aad11bb..51865b85 100644 --- a/third_party/libxslt/src/libxslt/documents.c +++ b/third_party/libxslt/src/libxslt/documents.c
@@ -399,6 +399,8 @@ return(NULL); ret = xsltNewStyleDocument(style, doc); + if (ret == NULL) + xmlFreeDoc(doc); return(ret); }
diff --git a/third_party/libxslt/src/libxslt/extensions.c b/third_party/libxslt/src/libxslt/extensions.c index ea5e835..f9ca08e 100644 --- a/third_party/libxslt/src/libxslt/extensions.c +++ b/third_party/libxslt/src/libxslt/extensions.c
@@ -28,6 +28,7 @@ #include <libxml/xmlIO.h> #include "xslt.h" #include "xsltInternals.h" +#include "xsltlocale.h" #include "xsltutils.h" #include "imports.h" #include "extensions.h" @@ -738,8 +739,11 @@ * Store the user-data in the context of the given stylesheet. */ dataContainer = xsltNewExtData(module, userData); - if (dataContainer == NULL) + if (dataContainer == NULL) { + if (module->styleShutdownFunc) + module->styleShutdownFunc(style, URI, userData); return (NULL); + } if (xmlHashAddEntry(style->extInfos, URI, (void *) dataContainer) < 0) @@ -920,9 +924,8 @@ return (NULL); data = xsltNewExtData(module, extData); - if (data == NULL) - return (NULL); - if (xmlHashAddEntry(ctxt->extInfos, URI, (void *) data) < 0) { + if ((data == NULL) || + (xmlHashAddEntry(ctxt->extInfos, URI, (void *) data) < 0)) { xsltTransformError(ctxt, NULL, NULL, "Failed to register module data: %s\n", URI); @@ -994,6 +997,8 @@ } ctxtData = xsltNewExtData(module, extData); if (ctxtData == NULL) { + if (module->shutdownFunc) + module->shutdownFunc(ctxt->ctxt, URI, extData); ctxt->ret = -1; return; } @@ -1001,6 +1006,9 @@ if (ctxt->ctxt->extInfos == NULL) ctxt->ctxt->extInfos = xmlHashCreate(10); if (ctxt->ctxt->extInfos == NULL) { + if (module->shutdownFunc) + module->shutdownFunc(ctxt->ctxt, URI, extData); + xsltFreeExtData(ctxtData); ctxt->ret = -1; return; }
diff --git a/third_party/libxslt/src/libxslt/functions.c b/third_party/libxslt/src/libxslt/functions.c index 61ce190..061ef7b2 100644 --- a/third_party/libxslt/src/libxslt/functions.c +++ b/third_party/libxslt/src/libxslt/functions.c
@@ -241,14 +241,14 @@ obj2 = valuePop(ctxt); } - if (ctxt->value->type == XPATH_NODESET) { + if ((ctxt->value != NULL) && (ctxt->value->type == XPATH_NODESET)) { int i; xmlXPathObjectPtr newobj, ret; obj = valuePop(ctxt); ret = xmlXPathNewNodeSet(NULL); - if ((obj != NULL) && obj->nodesetval) { + if ((obj != NULL) && (obj->nodesetval != NULL) && (ret != NULL)) { for (i = 0; i < obj->nodesetval->nodeNr; i++) { valuePush(ctxt, xmlXPathNewNodeSet(obj->nodesetval->nodeTab[i])); @@ -260,11 +260,15 @@ xmlXPathNewNodeSet(obj->nodesetval-> nodeTab[i])); } + if (ctxt->error) + break; xsltDocumentFunction(ctxt, 2); newobj = valuePop(ctxt); - ret->nodesetval = xmlXPathNodeSetMerge(ret->nodesetval, - newobj->nodesetval); - xmlXPathFreeObject(newobj); + if (newobj != NULL) { + ret->nodesetval = xmlXPathNodeSetMerge(ret->nodesetval, + newobj->nodesetval); + xmlXPathFreeObject(newobj); + } } } @@ -279,7 +283,7 @@ * Make sure it's converted to a string */ xmlXPathStringFunction(ctxt, 1); - if (ctxt->value->type != XPATH_STRING) { + if ((ctxt->value == NULL) || (ctxt->value->type != XPATH_STRING)) { xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, "document() : invalid arg expecting a string\n"); ctxt->error = XPATH_INVALID_TYPE; @@ -378,6 +382,12 @@ xmlXPathObjectPtr newobj, ret; ret = xmlXPathNewNodeSet(NULL); + if (ret == NULL) { + ctxt->error = XPATH_MEMORY_ERROR; + xmlXPathFreeObject(obj1); + xmlXPathFreeObject(obj2); + return; + } if (obj2->nodesetval != NULL) { for (i = 0; i < obj2->nodesetval->nodeNr; i++) { @@ -387,8 +397,9 @@ xmlXPathStringFunction(ctxt, 1); xsltKeyFunction(ctxt, 2); newobj = valuePop(ctxt); - ret->nodesetval = xmlXPathNodeSetMerge(ret->nodesetval, - newobj->nodesetval); + if (newobj != NULL) + ret->nodesetval = xmlXPathNodeSetMerge(ret->nodesetval, + newobj->nodesetval); xmlXPathFreeObject(newobj); } } @@ -445,13 +456,13 @@ */ valuePush(ctxt, obj2); xmlXPathStringFunction(ctxt, 1); - if ((ctxt->value == NULL) || (ctxt->value->type != XPATH_STRING)) { + obj2 = valuePop(ctxt); + if ((obj2 == NULL) || (obj2->type != XPATH_STRING)) { xsltTransformError(tctxt, NULL, tctxt->inst, "key() : invalid arg expecting a string\n"); ctxt->error = XPATH_INVALID_TYPE; goto error; } - obj2 = valuePop(ctxt); value = obj2->stringval; /* @@ -554,6 +565,10 @@ obj = valuePop(ctxt); if (obj->type != XPATH_STRING) { obj = xmlXPathConvertString(obj); + if (obj == NULL) { + xmlXPathErr(ctxt, XPATH_MEMORY_ERROR); + return; + } } str = obj->stringval; @@ -646,7 +661,8 @@ return; } - if (formatValues != NULL) { + if ((ctxt->error == 0) && + (formatValues != NULL) && (formatObj != NULL) && (numberObj != NULL)) { if (xsltFormatNumberConversion(formatValues, formatObj->stringval, numberObj->floatval,
diff --git a/third_party/libxslt/src/libxslt/imports.c b/third_party/libxslt/src/libxslt/imports.c index 4f5de03..bf2196e 100644 --- a/third_party/libxslt/src/libxslt/imports.c +++ b/third_party/libxslt/src/libxslt/imports.c
@@ -53,6 +53,35 @@ } } +static int +xsltCheckCycle(xsltStylesheetPtr style, const xmlChar *URI) { + xsltStylesheetPtr ancestor; + xsltDocumentPtr docptr; + + /* + * in order to detect recursion, we check all previously included + * stylesheets. + */ + docptr = style->includes; + while (docptr != NULL) { + if (xmlStrEqual(docptr->doc->URL, URI)) + return(-1); + docptr = docptr->includes; + } + + /* + * Also check imported stylesheets. + */ + ancestor = style; + while (ancestor != NULL) { + if (xmlStrEqual(ancestor->doc->URL, URI)) + return(-1); + ancestor = ancestor->parent; + } + + return(0); +} + /** * xsltParseStylesheetImport: * @style: the XSLT stylesheet @@ -91,16 +120,10 @@ goto error; } - res = style; - while (res != NULL) { - if (res->doc == NULL) - break; - if (xmlStrEqual(res->doc->URL, URI)) { - xsltTransformError(NULL, style, cur, - "xsl:import : recursion detected on imported URL %s\n", URI); - goto error; - } - res = res->parent; + if (xsltCheckCycle(style, URI) < 0) { + xsltTransformError(NULL, style, cur, + "xsl:import : recursion detected on imported URL %s\n", URI); + goto error; } /* @@ -170,7 +193,6 @@ xmlChar *URI = NULL; xsltStylesheetPtr result; xsltDocumentPtr include; - xsltDocumentPtr docptr; int oldNopreproc; if ((cur == NULL) || (style == NULL)) @@ -191,18 +213,10 @@ goto error; } - /* - * in order to detect recursion, we check all previously included - * stylesheets. - */ - docptr = style->includes; - while (docptr != NULL) { - if (xmlStrEqual(docptr->doc->URL, URI)) { - xsltTransformError(NULL, style, cur, - "xsl:include : recursion detected on included URL %s\n", URI); - goto error; - } - docptr = docptr->includes; + if (xsltCheckCycle(style, URI) < 0) { + xsltTransformError(NULL, style, cur, + "xsl:include : recursion detected on included URL %s\n", URI); + goto error; } include = xsltLoadStyleDocument(style, URI);
diff --git a/third_party/libxslt/src/libxslt/keys.c b/third_party/libxslt/src/libxslt/keys.c index fb18cd5..f23cc4e9 100644 --- a/third_party/libxslt/src/libxslt/keys.c +++ b/third_party/libxslt/src/libxslt/keys.c
@@ -294,6 +294,8 @@ #endif key = xsltNewKeyDef(name, nameURI); + if (key == NULL) + return(-1); key->match = xmlStrdup(match); key->use = xmlStrdup(use); key->inst = inst; @@ -827,7 +829,10 @@ keylist = xmlXPathNodeSetCreate(cur); if (keylist == NULL) goto error; - xmlHashAddEntry(table->keys, str, keylist); + if (xmlHashAddEntry(table->keys, str, keylist) < 0) { + xmlXPathFreeNodeSet(keylist); + goto error; + } } else { /* * TODO: How do we know if this function failed?
diff --git a/third_party/libxslt/src/libxslt/numbers.c b/third_party/libxslt/src/libxslt/numbers.c index 9e496bb..e0ae625 100644 --- a/third_party/libxslt/src/libxslt/numbers.c +++ b/third_party/libxslt/src/libxslt/numbers.c
@@ -116,7 +116,7 @@ #define IS_DIGIT_ONE(x) xsltIsDigitZero((x)-1) static int -xsltIsDigitZero(unsigned int ch) +xsltIsDigitZero(int ch) { /* * Reference: ftp://ftp.unicode.org/Public/UNIDATA/UnicodeData.txt @@ -985,32 +985,12 @@ "Invalid format (0-length)\n"); } *result = NULL; - switch (xmlXPathIsInf(number)) { - case -1: - if (self->minusSign == NULL) - *result = xmlStrdup(BAD_CAST "-"); - else - *result = xmlStrdup(self->minusSign); - /* Intentional fall-through */ - case 1: - if ((self == NULL) || (self->infinity == NULL)) - *result = xmlStrcat(*result, BAD_CAST "Infinity"); - else - *result = xmlStrcat(*result, self->infinity); - return(status); - default: - if (xmlXPathIsNaN(number)) { - if ((self == NULL) || (self->noNumber == NULL)) - *result = xmlStrdup(BAD_CAST "NaN"); - else - *result = xmlStrdup(self->noNumber); - return(status); - } - } - - buffer = xmlBufferCreate(); - if (buffer == NULL) { - return XPATH_MEMORY_ERROR; + if (xmlXPathIsNaN(number)) { + if ((self == NULL) || (self->noNumber == NULL)) + *result = xmlStrdup(BAD_CAST "NaN"); + else + *result = xmlStrdup(self->noNumber); + return(status); } format_info.integer_hash = 0; @@ -1283,6 +1263,30 @@ format_info.add_decimal = TRUE; } + /* Apply multiplier */ + number *= (double)format_info.multiplier; + switch (xmlXPathIsInf(number)) { + case -1: + if (self->minusSign == NULL) + *result = xmlStrdup(BAD_CAST "-"); + else + *result = xmlStrdup(self->minusSign); + /* Intentional fall-through */ + case 1: + if ((self == NULL) || (self->infinity == NULL)) + *result = xmlStrcat(*result, BAD_CAST "Infinity"); + else + *result = xmlStrcat(*result, self->infinity); + return(status); + default: + break; + } + + buffer = xmlBufferCreate(); + if (buffer == NULL) { + return XPATH_MEMORY_ERROR; + } + /* Ready to output our number. First see if "default sign" is required */ if (default_sign != 0) xmlBufferAdd(buffer, self->minusSign, xmlUTF8Strsize(self->minusSign, 1)); @@ -1297,10 +1301,13 @@ j += len; } - /* Next do the integer part of the number */ - number = fabs(number) * (double)format_info.multiplier; + /* Round to n digits */ + number = fabs(number); scale = pow(10.0, (double)(format_info.frac_digits + format_info.frac_hash)); - number = floor((scale * number + 0.5)) / scale; + number += .5 / scale; + number -= fmod(number, 1 / scale); + + /* Next do the integer part of the number */ if ((self->grouping != NULL) && (self->grouping[0] != 0)) { int gchar;
diff --git a/third_party/libxslt/src/libxslt/pattern.c b/third_party/libxslt/src/libxslt/pattern.c index 0a6fd92..6e99b12 100644 --- a/third_party/libxslt/src/libxslt/pattern.c +++ b/third_party/libxslt/src/libxslt/pattern.c
@@ -311,10 +311,6 @@ "xsltCompMatchAdd: memory re-allocation failure.\n"); if (ctxt->style != NULL) ctxt->style->errors++; - if (value) - xmlFree(value); - if (value2) - xmlFree(value2); return (-1); } comp->maxStep *= 2; @@ -483,16 +479,12 @@ static int xsltPatPushState(xsltTransformContextPtr ctxt, xsltStepStates *states, int step, xmlNodePtr node) { - if ((states->states == NULL) || (states->maxstates <= 0)) { - states->maxstates = 4; - states->nbstates = 0; - states->states = xmlMalloc(4 * sizeof(xsltStepState)); - } - else if (states->maxstates <= states->nbstates) { + if (states->maxstates <= states->nbstates) { xsltStepState *tmp; + int newMax = states->maxstates == 0 ? 4 : 2 * states->maxstates; tmp = (xsltStepStatePtr) xmlRealloc(states->states, - 2 * states->maxstates * sizeof(xsltStepState)); + newMax * sizeof(xsltStepState)); if (tmp == NULL) { xsltGenericError(xsltGenericErrorContext, "xsltPatPushState: memory re-allocation failure.\n"); @@ -500,7 +492,7 @@ return(-1); } states->states = tmp; - states->maxstates *= 2; + states->maxstates = newMax; } states->states[states->nbstates].step = step; states->states[states->nbstates++].node = node; @@ -1512,6 +1504,7 @@ xmlChar *name = NULL; const xmlChar *URI = NULL; xmlChar *URL = NULL; + xmlChar *ret = NULL; int level; xsltAxis axis = 0; @@ -1588,7 +1581,6 @@ xsltTransformError(NULL, NULL, NULL, "xsltCompileStepPattern : Name expected\n"); ctxt->error = 1; - xmlFree(URL); goto error; } } else { @@ -1651,7 +1643,6 @@ level = 0; while (CUR == '[') { const xmlChar *q; - xmlChar *ret = NULL; level++; NEXT; @@ -1695,6 +1686,10 @@ xmlFree(token); if (name != NULL) xmlFree(name); + if (URL != NULL) + xmlFree(URL); + if (ret != NULL) + xmlFree(ret); } /** @@ -2087,6 +2082,8 @@ if (pat == NULL) return(-1); while (pat) { + int success = 0; + next = pat->next; pat->next = NULL; name = NULL; @@ -2158,17 +2155,15 @@ if (name != NULL) { if (style->templatesHash == NULL) { style->templatesHash = xmlHashCreate(1024); - if (style->templatesHash == NULL) { - xsltFreeCompMatch(pat); - return(-1); - } - xmlHashAddEntry3(style->templatesHash, name, mode, modeURI, pat); + success = (style->templatesHash != NULL) && + (xmlHashAddEntry3(style->templatesHash, name, mode, + modeURI, pat) >= 0); } else { list = (xsltCompMatchPtr) xmlHashLookup3(style->templatesHash, name, mode, modeURI); if (list == NULL) { - xmlHashAddEntry3(style->templatesHash, name, - mode, modeURI, pat); + success = (xmlHashAddEntry3(style->templatesHash, name, + mode, modeURI, pat) >= 0); } else { /* * Note '<=' since one must choose among the matching @@ -2188,6 +2183,7 @@ pat->next = list->next; list->next = pat; } + success = 1; } } } else if (top != NULL) { @@ -2207,10 +2203,13 @@ pat->next = list->next; list->next = pat; } - } else { + success = 1; + } + if (success == 0) { xsltTransformError(NULL, style, NULL, "xsltAddTemplate: invalid compiled pattern\n"); xsltFreeCompMatch(pat); + xsltFreeCompMatchList(next); return(-1); } #ifdef WITH_XSLT_DEBUG_PATTERN
diff --git a/third_party/libxslt/src/libxslt/preproc.c b/third_party/libxslt/src/libxslt/preproc.c index 7d2fa22..fae69a09 100644 --- a/third_party/libxslt/src/libxslt/preproc.c +++ b/third_party/libxslt/src/libxslt/preproc.c
@@ -392,8 +392,6 @@ break; case XSLT_FUNC_SORT: { xsltStyleItemSortPtr item = (xsltStyleItemSortPtr) comp; - if (item->locale != (xsltLocale)0) - xsltFreeLocale(item->locale); if (item->comp != NULL) xmlXPathFreeCompExpr(item->comp); } @@ -496,8 +494,6 @@ break; } #else - if (comp->locale != (xsltLocale)0) - xsltFreeLocale(comp->locale); if (comp->comp != NULL) xmlXPathFreeCompExpr(comp->comp); if (comp->numdata.countPat != NULL) @@ -743,12 +739,6 @@ comp->lang = xsltEvalStaticAttrValueTemplate(style, inst, (const xmlChar *)"lang", NULL, &comp->has_lang); - if (comp->lang != NULL) { - comp->locale = xsltNewLocale(comp->lang); - } - else { - comp->locale = (xsltLocale)0; - } comp->select = xsltGetCNsProp(style, inst,(const xmlChar *)"select", XSLT_NAMESPACE); if (comp->select == NULL) {
diff --git a/third_party/libxslt/src/libxslt/templates.c b/third_party/libxslt/src/libxslt/templates.c index 4108ed2..f08b9bda 100644 --- a/third_party/libxslt/src/libxslt/templates.c +++ b/third_party/libxslt/src/libxslt/templates.c
@@ -151,7 +151,7 @@ if (res != NULL) { if (res->type != XPATH_STRING) res = xmlXPathConvertString(res); - if (res->type == XPATH_STRING) { + if ((res != NULL) && (res->type == XPATH_STRING)) { ret = res->stringval; res->stringval = NULL; } else { @@ -229,7 +229,7 @@ insert = xmlNewDocNode(ctxt->output, NULL, (const xmlChar *)"fake", NULL); if (insert == NULL) { - xsltTransformError(ctxt, NULL, contextNode, + xsltTransformError(ctxt, NULL, inst, "Failed to create temporary node\n"); return(NULL); }
diff --git a/third_party/libxslt/src/libxslt/transform.c b/third_party/libxslt/src/libxslt/transform.c index 67d041a..0fc0400 100644 --- a/third_party/libxslt/src/libxslt/transform.c +++ b/third_party/libxslt/src/libxslt/transform.c
@@ -40,6 +40,7 @@ #include "xslt.h" #include "xsltInternals.h" #include "xsltutils.h" +#include "xsltlocale.h" #include "pattern.h" #include "transform.h" #include "variables.h" @@ -119,26 +120,18 @@ static int templPush(xsltTransformContextPtr ctxt, xsltTemplatePtr value) { - if (ctxt->templMax == 0) { - ctxt->templMax = 4; - ctxt->templTab = - (xsltTemplatePtr *) xmlMalloc(ctxt->templMax * - sizeof(ctxt->templTab[0])); - if (ctxt->templTab == NULL) { - xmlGenericError(xmlGenericErrorContext, "malloc failed !\n"); - return (0); - } - } - else if (ctxt->templNr >= ctxt->templMax) { - ctxt->templMax *= 2; - ctxt->templTab = - (xsltTemplatePtr *) xmlRealloc(ctxt->templTab, - ctxt->templMax * - sizeof(ctxt->templTab[0])); - if (ctxt->templTab == NULL) { + if (ctxt->templNr >= ctxt->templMax) { + xsltTemplatePtr *tmp; + int newMax = ctxt->templMax == 0 ? 4 : ctxt->templMax * 2; + + tmp = (xsltTemplatePtr *) xmlRealloc(ctxt->templTab, + newMax * sizeof(*tmp)); + if (tmp == NULL) { xmlGenericError(xmlGenericErrorContext, "realloc failed !\n"); return (0); } + ctxt->templTab = tmp; + ctxt->templMax = newMax; } ctxt->templTab[ctxt->templNr] = value; ctxt->templ = value; @@ -706,6 +699,10 @@ cur->xinclude = xsltGetXIncludeDefault(); cur->keyInitLevel = 0; + cur->newLocale = xsltNewLocale; + cur->freeLocale = xsltFreeLocale; + cur->genSortKey = xsltStrxfrm; + return(cur); internal_err: @@ -716,7 +713,7 @@ /** * xsltFreeTransformContext: - * @ctxt: an XSLT parser context + * @ctxt: an XSLT transform context * * Free up the memory allocated by @ctxt */ @@ -1090,8 +1087,10 @@ if (xmlDictOwns(ctxt->dict, cur->content)) copy->content = cur->content; else { - if ((copy->content = xmlStrdup(cur->content)) == NULL) + if ((copy->content = xmlStrdup(cur->content)) == NULL) { + xmlFreeNode(copy); return NULL; + } } ctxt->lasttext = NULL; @@ -2224,26 +2223,18 @@ xsltStackElemPtr variable, int level) { - if (ctxt->varsMax == 0) { - ctxt->varsMax = 10; - ctxt->varsTab = - (xsltStackElemPtr *) xmlMalloc(ctxt->varsMax * - sizeof(ctxt->varsTab[0])); - if (ctxt->varsTab == NULL) { - xmlGenericError(xmlGenericErrorContext, "malloc failed !\n"); - return (-1); - } - } if (ctxt->varsNr >= ctxt->varsMax) { - ctxt->varsMax *= 2; - ctxt->varsTab = - (xsltStackElemPtr *) xmlRealloc(ctxt->varsTab, - ctxt->varsMax * - sizeof(ctxt->varsTab[0])); - if (ctxt->varsTab == NULL) { + xsltStackElemPtr *tmp; + int newMax = ctxt->varsMax == 0 ? 10 : 2 * ctxt->varsMax; + + tmp = (xsltStackElemPtr *) xmlRealloc(ctxt->varsTab, + newMax * sizeof(*tmp)); + if (tmp == NULL) { xmlGenericError(xmlGenericErrorContext, "realloc failed !\n"); return (-1); } + ctxt->varsTab = tmp; + ctxt->varsMax = newMax; } ctxt->varsTab[ctxt->varsNr++] = variable; ctxt->vars = variable; @@ -5776,6 +5767,8 @@ if (cur->children != NULL && cur->type != XML_ENTITY_REF_NODE) { cur = cur->children; } else { + if (cur == (xmlNodePtr) doc) + return; while (cur->next == NULL) { cur = cur->parent; if (cur == (xmlNodePtr) doc)
diff --git a/third_party/libxslt/src/libxslt/variables.c b/third_party/libxslt/src/libxslt/variables.c index 8ce33d6..c0055c2 100644 --- a/third_party/libxslt/src/libxslt/variables.c +++ b/third_party/libxslt/src/libxslt/variables.c
@@ -757,26 +757,18 @@ return(-1); do { - if (ctxt->varsMax == 0) { - ctxt->varsMax = 10; - ctxt->varsTab = - (xsltStackElemPtr *) xmlMalloc(ctxt->varsMax * - sizeof(ctxt->varsTab[0])); - if (ctxt->varsTab == NULL) { - xmlGenericError(xmlGenericErrorContext, "malloc failed !\n"); - return (-1); - } - } if (ctxt->varsNr >= ctxt->varsMax) { - ctxt->varsMax *= 2; - ctxt->varsTab = - (xsltStackElemPtr *) xmlRealloc(ctxt->varsTab, - ctxt->varsMax * - sizeof(ctxt->varsTab[0])); - if (ctxt->varsTab == NULL) { - xmlGenericError(xmlGenericErrorContext, "realloc failed !\n"); - return (-1); - } + xsltStackElemPtr *tmp; + int newMax = ctxt->varsMax == 0 ? 10 : 2 * ctxt->varsMax; + + tmp = (xsltStackElemPtr *) xmlRealloc(ctxt->varsTab, + newMax * sizeof(*tmp)); + if (tmp == NULL) { + xmlGenericError(xmlGenericErrorContext, "realloc failed !\n"); + return (-1); + } + ctxt->varsTab = tmp; + ctxt->varsMax = newMax; } ctxt->varsTab[ctxt->varsNr++] = elem; ctxt->vars = elem; @@ -1318,8 +1310,13 @@ if (def == NULL) { def = xsltCopyStackElem(elem); - xmlHashAddEntry2(ctxt->globalVars, - elem->name, elem->nameURI, def); + if (xmlHashAddEntry2(ctxt->globalVars, + elem->name, elem->nameURI, def) < 0) { + xmlGenericError(xmlGenericErrorContext, + "hash update failed\n"); + xsltFreeStackElem(def); + return(-1); + } } else if ((elem->comp != NULL) && (elem->comp->type == XSLT_FUNC_VARIABLE)) { /* @@ -1877,7 +1874,10 @@ #endif /* else of XSLT_REFACTORED */ variable = xsltBuildVariable(ctxt, (xsltStylePreCompPtr) comp, tree); - xsltAddStackElem(ctxt, variable); + if (xsltAddStackElem(ctxt, variable) < 0) { + xsltFreeStackElem(variable); + return(-1); + } return(0); }
diff --git a/third_party/libxslt/src/libxslt/xslt.c b/third_party/libxslt/src/libxslt/xslt.c index e19f5296..c17faa6 100644 --- a/third_party/libxslt/src/libxslt/xslt.c +++ b/third_party/libxslt/src/libxslt/xslt.c
@@ -151,31 +151,23 @@ { int i; - if (style->exclPrefixMax == 0) { - style->exclPrefixMax = 4; - style->exclPrefixTab = - (xmlChar * *)xmlMalloc(style->exclPrefixMax * - sizeof(style->exclPrefixTab[0])); - if (style->exclPrefixTab == NULL) { - xmlGenericError(xmlGenericErrorContext, "malloc failed !\n"); - return (-1); - } - } /* do not push duplicates */ for (i = 0;i < style->exclPrefixNr;i++) { if (xmlStrEqual(style->exclPrefixTab[i], value)) return(-1); } if (style->exclPrefixNr >= style->exclPrefixMax) { - style->exclPrefixMax *= 2; - style->exclPrefixTab = - (xmlChar * *)xmlRealloc(style->exclPrefixTab, - style->exclPrefixMax * - sizeof(style->exclPrefixTab[0])); - if (style->exclPrefixTab == NULL) { + xmlChar **tmp; + size_t max = style->exclPrefixMax ? style->exclPrefixMax * 2 : 4; + + tmp = xmlRealloc(style->exclPrefixTab, + max * sizeof(style->exclPrefixTab[0])); + if (tmp == NULL) { xmlGenericError(xmlGenericErrorContext, "realloc failed !\n"); return (-1); } + style->exclPrefixTab = tmp; + style->exclPrefixMax = max; } style->exclPrefixTab[style->exclPrefixNr] = value; style->exclPrefix = value; @@ -1111,9 +1103,9 @@ xmlNodePtr node) { xmlNsPtr cur; - xmlNsPtr *ret = NULL; + xmlNsPtr *ret = NULL, *tmp; int nbns = 0; - int maxns = 10; + int maxns = 0; int i; if ((style == NULL) || (template == NULL) || (node == NULL) || @@ -1138,17 +1130,6 @@ if (xmlStrEqual(cur->href, style->exclPrefixTab[i])) goto skip_ns; } - if (ret == NULL) { - ret = - (xmlNsPtr *) xmlMalloc((maxns + 1) * - sizeof(xmlNsPtr)); - if (ret == NULL) { - xmlGenericError(xmlGenericErrorContext, - "xsltGetInheritedNsList : out of memory!\n"); - return(0); - } - ret[nbns] = NULL; - } /* * Skip shadowed namespace bindings. */ @@ -1159,16 +1140,16 @@ } if (i >= nbns) { if (nbns >= maxns) { - maxns *= 2; - ret = (xmlNsPtr *) xmlRealloc(ret, - (maxns + - 1) * - sizeof(xmlNsPtr)); - if (ret == NULL) { + maxns = (maxns == 0) ? 10 : 2 * maxns; + tmp = (xmlNsPtr *) xmlRealloc(ret, + (maxns + 1) * sizeof(xmlNsPtr)); + if (tmp == NULL) { xmlGenericError(xmlGenericErrorContext, "xsltGetInheritedNsList : realloc failed!\n"); + xmlFree(ret); return(0); } + ret = tmp; } ret[nbns++] = cur; ret[nbns] = NULL; @@ -1324,8 +1305,10 @@ if (elements != NULL) { if (style->cdataSection == NULL) style->cdataSection = xmlHashCreate(10); - if (style->cdataSection == NULL) + if (style->cdataSection == NULL) { + xmlFree(elements); return; + } element = elements; while (*element != 0) { @@ -1563,8 +1546,10 @@ if (style->stripSpaces == NULL) style->stripSpaces = xmlHashCreate(10); - if (style->stripSpaces == NULL) + if (style->stripSpaces == NULL) { + xmlFree(elements); return; + } element = elements; while (*element != 0) { @@ -1692,6 +1677,11 @@ if ((cur == NULL) || (style == NULL) || (cur->type != XML_ELEMENT_NODE)) return; + if (style->stripSpaces == NULL) + style->stripSpaces = xmlHashCreate(10); + if (style->stripSpaces == NULL) + return; + elements = xmlGetNsProp(cur, (const xmlChar *)"elements", NULL); if (elements == NULL) { xsltTransformError(NULL, style, cur, @@ -1700,11 +1690,6 @@ return; } - if (style->stripSpaces == NULL) - style->stripSpaces = xmlHashCreate(10); - if (style->stripSpaces == NULL) - return; - element = elements; while (*element != 0) { while (IS_BLANK(*element)) element++; @@ -6838,7 +6823,8 @@ if (val == NULL) return(NULL); if ((xmlStrcasecmp(val, BAD_CAST "text/xml")) && - (xmlStrcasecmp(val, BAD_CAST "text/xsl"))) { + (xmlStrcasecmp(val, BAD_CAST "text/xsl")) && + (xmlStrcasecmp(val, BAD_CAST "application/xslt+xml"))) { xmlFree(val); break; }
diff --git a/third_party/libxslt/src/libxslt/xsltInternals.h b/third_party/libxslt/src/libxslt/xsltInternals.h index 2fd1f68..7de638e 100644 --- a/third_party/libxslt/src/libxslt/xsltInternals.h +++ b/third_party/libxslt/src/libxslt/xsltInternals.h
@@ -21,7 +21,6 @@ #include <libxml/xmlstring.h> #include <libxslt/xslt.h> #include "xsltexports.h" -#include "xsltlocale.h" #include "numbersInternals.h" #ifdef __cplusplus @@ -1047,7 +1046,6 @@ int descending; /* sort */ const xmlChar *lang; /* sort */ int has_lang; /* sort */ - xsltLocale locale; /* sort */ const xmlChar *case_order; /* sort */ int lower_first; /* sort */ @@ -1377,7 +1375,6 @@ int descending; /* sort */ const xmlChar *lang; /* sort */ int has_lang; /* sort */ - xsltLocale locale; /* sort */ const xmlChar *case_order; /* sort */ int lower_first; /* sort */ @@ -1663,6 +1660,13 @@ XSLT_OUTPUT_TEXT } xsltOutputType; +typedef void * +(*xsltNewLocaleFunc)(const xmlChar *lang, int lowerFirst); +typedef void +(*xsltFreeLocaleFunc)(void *locale); +typedef xmlChar * +(*xsltGenSortKeyFunc)(void *locale, const xmlChar *lang); + typedef enum { XSLT_STATE_OK = 0, XSLT_STATE_ERROR, @@ -1788,6 +1792,10 @@ unsigned long opCount; int sourceDocDirty; unsigned long currentId; /* For generate-id() */ + + xsltNewLocaleFunc newLocale; + xsltFreeLocaleFunc freeLocale; + xsltGenSortKeyFunc genSortKey; }; /**
diff --git a/third_party/libxslt/src/libxslt/xsltlocale.c b/third_party/libxslt/src/libxslt/xsltlocale.c index 7674098..9324f284 100644 --- a/third_party/libxslt/src/libxslt/xsltlocale.c +++ b/third_party/libxslt/src/libxslt/xsltlocale.c
@@ -19,6 +19,8 @@ #include "xsltlocale.h" #include "xsltutils.h" +#define XSLT_LOCALE_NONE + #define TOUPPER(c) (c & ~0x20) #define TOLOWER(c) (c | 0x20) #define ISALPHA(c) ((unsigned)(TOUPPER(c) - 'A') < 26) @@ -37,8 +39,7 @@ struct xsltRFC1766Info_s { /*note typedef unsigned char xmlChar !*/ xmlChar tag[XSLTMAX_LANGTAGLEN+1]; - /*note typedef LCID xsltLocale !*/ - xsltLocale lcid; + LCID lcid; }; typedef struct xsltRFC1766Info_s xsltRFC1766Info; @@ -46,14 +47,15 @@ static xsltRFC1766Info *xsltLocaleList = NULL; -static xsltLocale +static void * xslt_locale_WINAPI(const xmlChar *languageTag) { int k; xsltRFC1766Info *p = xsltLocaleList; for (k=0; k<xsltLocaleListSize; k++, p++) - if (xmlStrcmp(p->tag, languageTag) == 0) return p->lcid; - return((xsltLocale)0); + if (xmlStrcmp(p->tag, languageTag) == 0) + return(&p->lcid); + return(NULL); } static void xsltEnumSupportedLocales(void); @@ -83,17 +85,17 @@ * * Returns the locale or NULL on error or if no matching locale was found */ -xsltLocale -xsltNewLocale(const xmlChar *languageTag) { +void * +xsltNewLocale(const xmlChar *languageTag, int lowerFirst ATTRIBUTE_UNUSED) { #ifdef XSLT_LOCALE_POSIX - xsltLocale locale; - char localeName[XSLTMAX_LANGTAGLEN+6]; /* 6 chars for ".utf8\0" */ + locale_t locale; + char localeName[XSLTMAX_LANGTAGLEN+7]; /* 7 chars for ".UTF-8\0" */ const xmlChar *p = languageTag; const char *region = NULL; char *q = localeName; int i, llen; - /* Convert something like "pt-br" to "pt_BR.utf8" */ + /* Convert something like "pt-br" to "pt_BR.UTF-8" */ if (languageTag == NULL) return(NULL); @@ -117,7 +119,7 @@ if (i == 0 || *p) return(NULL); - memcpy(q, ".utf8", 6); + memcpy(q, ".UTF-8", 7); locale = newlocale(LC_COLLATE_MASK, localeName, NULL); if (locale != NULL) return(locale); @@ -129,7 +131,7 @@ /* Try locale without territory, e.g. for Esperanto (eo) */ - memcpy(q, ".utf8", 6); + memcpy(q, ".UTF-8", 7); locale = newlocale(LC_COLLATE_MASK, localeName, NULL); if (locale != NULL) return(locale); @@ -147,7 +149,7 @@ *q++ = '_'; *q++ = region[0]; *q++ = region[1]; - memcpy(q, ".utf8", 6); + memcpy(q, ".UTF-8", 7); locale = newlocale(LC_COLLATE_MASK, localeName, NULL); return(locale); @@ -155,7 +157,7 @@ #ifdef XSLT_LOCALE_WINAPI { - xsltLocale locale = (xsltLocale)0; + void *locale = NULL; xmlChar localeName[XSLTMAX_LANGTAGLEN+1]; xmlChar *q = localeName; const xmlChar *p = languageTag; @@ -344,7 +346,7 @@ * Frees a locale created with xsltNewLocale */ void -xsltFreeLocale(xsltLocale locale) { +xsltFreeLocale(void *locale) { #ifdef XSLT_LOCALE_POSIX if (locale != NULL) freelocale(locale); @@ -358,58 +360,82 @@ * @locale: locale created with xsltNewLocale * @string: UTF-8 string to transform * - * Transforms a string according to locale. The transformed string must then be - * compared with xsltLocaleStrcmp and freed with xmlFree. + * Transforms a string according to locale. The transformed string must be + * freed with xmlFree. * * Returns the transformed string or NULL on error */ -xsltLocaleChar * -xsltStrxfrm(xsltLocale locale, const xmlChar *string) +xmlChar * +xsltStrxfrm(void *vlocale, const xmlChar *string) { #ifdef XSLT_LOCALE_NONE return(NULL); #else - size_t xstrlen, r; - xsltLocaleChar *xstr; + xmlChar *xstr; #ifdef XSLT_LOCALE_POSIX - xstrlen = strxfrm_l(NULL, (const char *)string, 0, locale) + 1; - xstr = (xsltLocaleChar *) xmlMalloc(xstrlen); + size_t xstrlen, r; + + xstrlen = strxfrm_l(NULL, (const char *)string, 0, vlocale) + 1; + xstr = (xmlChar *) xmlMalloc(xstrlen); if (xstr == NULL) { xsltTransformError(NULL, NULL, NULL, "xsltStrxfrm : out of memory error\n"); return(NULL); } - r = strxfrm_l((char *)xstr, (const char *)string, xstrlen, locale); -#endif - -#ifdef XSLT_LOCALE_WINAPI - (void) locale; - xstrlen = MultiByteToWideChar(CP_UTF8, 0, (char *) string, -1, NULL, 0); - if (xstrlen == 0) { - xsltTransformError(NULL, NULL, NULL, "xsltStrxfrm : MultiByteToWideChar check failed\n"); - return(NULL); - } - xstr = (xsltLocaleChar*) xmlMalloc(xstrlen * sizeof(xsltLocaleChar)); - if (xstr == NULL) { - xsltTransformError(NULL, NULL, NULL, "xsltStrxfrm : out of memory\n"); - return(NULL); - } - r = MultiByteToWideChar(CP_UTF8, 0, (char *) string, -1, xstr, xstrlen); - if (r == 0) { - xsltTransformError(NULL, NULL, NULL, "xsltStrxfrm : MultiByteToWideChar failed\n"); - xmlFree(xstr); - return(NULL); - } - return(xstr); -#endif /* XSLT_LOCALE_WINAPI */ + r = strxfrm_l((char *)xstr, (const char *)string, xstrlen, vlocale); if (r >= xstrlen) { xsltTransformError(NULL, NULL, NULL, "xsltStrxfrm : strxfrm failed\n"); xmlFree(xstr); return(NULL); } +#endif + +#ifdef XSLT_LOCALE_WINAPI + int wstrlen, xstrlen, r; + wchar_t *wstr; + LCID *lcid = vlocale; + + wstrlen = MultiByteToWideChar(CP_UTF8, 0, (char *) string, -1, NULL, 0); + if (wstrlen == 0) { + xsltTransformError(NULL, NULL, NULL, "xsltStrxfrm : MultiByteToWideChar check failed\n"); + return(NULL); + } + wstr = (wchar_t *) xmlMalloc(wstrlen * sizeof(wchar_t)); + if (wstr == NULL) { + xsltTransformError(NULL, NULL, NULL, "xsltStrxfrm : out of memory\n"); + return(NULL); + } + r = MultiByteToWideChar(CP_UTF8, 0, (char *) string, -1, wstr, wstrlen); + if (r == 0) { + xsltTransformError(NULL, NULL, NULL, "xsltStrxfrm : MultiByteToWideChar failed\n"); + xmlFree(wstr); + return(NULL); + } + /* This returns the size in bytes. */ + xstrlen = LCMapStringW(*lcid, LCMAP_SORTKEY, wstr, wstrlen, NULL, 0); + if (xstrlen == 0) { + xsltTransformError(NULL, NULL, NULL, "xsltStrxfrm : LCMapStringW failed\n"); + xmlFree(wstr); + return(NULL); + } + xstr = (xmlChar*) xmlMalloc(xstrlen); + if (xstr == NULL) { + xsltTransformError(NULL, NULL, NULL, "xsltStrxfrm : out of memory\n"); + xmlFree(wstr); + return(NULL); + } + r = LCMapStringW(*lcid, LCMAP_SORTKEY, wstr, wstrlen, (wchar_t *) xstr, + xstrlen); + xmlFree(wstr); + if (r == 0) { + xsltTransformError(NULL, NULL, NULL, "xsltStrxfrm : LCMapStringW failed\n"); + xmlFree(xstr); + return(NULL); + } +#endif /* XSLT_LOCALE_WINAPI */ return(xstr); #endif /* XSLT_LOCALE_NONE */ @@ -417,35 +443,22 @@ /** * xsltLocaleStrcmp: - * @locale: a locale identifier + * @locale: unused * @str1: a string transformed with xsltStrxfrm * @str2: a string transformed with xsltStrxfrm * - * Compares two strings transformed with xsltStrxfrm + * DEPRECATED: Same as xmlStrcmp. + * + * Compares two strings transformed with xsltStrxfrm. * * Returns a value < 0 if str1 sorts before str2, * a value > 0 if str1 sorts after str2, * 0 if str1 and str2 are equal wrt sorting */ int -xsltLocaleStrcmp(xsltLocale locale, const xsltLocaleChar *str1, const xsltLocaleChar *str2) { +xsltLocaleStrcmp(void *locale, const xmlChar *str1, const xmlChar *str2) { (void)locale; -#ifdef XSLT_LOCALE_WINAPI -{ - int ret; - if (str1 == str2) return(0); - if (str1 == NULL) return(-1); - if (str2 == NULL) return(1); - ret = CompareStringW(locale, 0, str1, -1, str2, -1); - if (ret == 0) { - xsltTransformError(NULL, NULL, NULL, "xsltLocaleStrcmp : CompareStringW fail\n"); - return(0); - } - return(ret - 2); -} -#else return(xmlStrcmp(str1, str2)); -#endif } #ifdef XSLT_LOCALE_WINAPI
diff --git a/third_party/libxslt/src/libxslt/xsltlocale.h b/third_party/libxslt/src/libxslt/xsltlocale.h index db881e2b..10a4402 100644 --- a/third_party/libxslt/src/libxslt/xsltlocale.h +++ b/third_party/libxslt/src/libxslt/xsltlocale.h
@@ -14,65 +14,23 @@ #include <libxml/xmlstring.h> #include "xsltexports.h" -#if defined(_WIN32) && !defined(__CYGWIN__) -#include <windows.h> -#include <winnls.h> -#endif - -#if 0 - -/* - * XSLT_LOCALE_POSIX: - * Macro indicating to use POSIX locale extensions - */ -#define XSLT_LOCALE_POSIX - -#ifdef HAVE_LOCALE_H -#include <locale.h> -#endif -#ifdef HAVE_XLOCALE_H -#include <xlocale.h> -#endif - -typedef locale_t xsltLocale; -typedef xmlChar xsltLocaleChar; - -#elif 0 - -/* - * XSLT_LOCALE_WINAPI: - * Macro indicating to use WinAPI for extended locale support - */ -#define XSLT_LOCALE_WINAPI - -typedef LCID xsltLocale; -typedef wchar_t xsltLocaleChar; - -#else - -/* - * XSLT_LOCALE_NONE: - * Macro indicating that there's no extended locale support - */ -#define XSLT_LOCALE_NONE - -typedef void *xsltLocale; -typedef xmlChar xsltLocaleChar; - -#endif - -XSLTPUBFUN xsltLocale XSLTCALL - xsltNewLocale (const xmlChar *langName); +XSLTPUBFUN void * XSLTCALL + xsltNewLocale (const xmlChar *langName, + int lowerFirst); XSLTPUBFUN void XSLTCALL - xsltFreeLocale (xsltLocale locale); -XSLTPUBFUN xsltLocaleChar * XSLTCALL - xsltStrxfrm (xsltLocale locale, + xsltFreeLocale (void *locale); +XSLTPUBFUN xmlChar * XSLTCALL + xsltStrxfrm (void *locale, const xmlChar *string); -XSLTPUBFUN int XSLTCALL - xsltLocaleStrcmp (xsltLocale locale, - const xsltLocaleChar *str1, - const xsltLocaleChar *str2); XSLTPUBFUN void XSLTCALL xsltFreeLocales (void); +/* Backward compatibility */ +typedef void *xsltLocale; +typedef xmlChar xsltLocaleChar; +XSLTPUBFUN int XSLTCALL + xsltLocaleStrcmp (void *locale, + const xmlChar *str1, + const xmlChar *str2); + #endif /* __XML_XSLTLOCALE_H__ */
diff --git a/third_party/libxslt/src/libxslt/xsltutils.c b/third_party/libxslt/src/libxslt/xsltutils.c index 390b958..59dd192d 100644 --- a/third_party/libxslt/src/libxslt/xsltutils.c +++ b/third_party/libxslt/src/libxslt/xsltutils.c
@@ -42,6 +42,7 @@ #include "transform.h" #if defined(_WIN32) +#include <windows.h> #define XSLT_WIN32_PERFORMANCE_COUNTER #endif @@ -960,7 +961,7 @@ */ static xmlXPathObjectPtr * xsltComputeSortResultInternal(xsltTransformContextPtr ctxt, xmlNodePtr sort, - int number, xsltLocale locale) { + int number, void *locale) { #ifdef XSLT_REFACTORED xsltStyleItemSortPtr comp; #else @@ -1034,6 +1035,8 @@ res = xmlXPathConvertString(res); if (number) res = xmlXPathConvertNumber(res); + } + if (res != NULL) { res->index = i; /* Save original pos for dupl resolv */ if (number) { if (res->type == XPATH_NUMBER) { @@ -1047,10 +1050,17 @@ } } else { if (res->type == XPATH_STRING) { - if (locale != (xsltLocale)0) { + if (locale != NULL) { xmlChar *str = res->stringval; - res->stringval = (xmlChar *) xsltStrxfrm(locale, str); - xmlFree(str); + xmlChar *sortKey = ctxt->genSortKey(locale, str); + + if (sortKey == NULL) { + xsltTransformError(ctxt, NULL, sort, + "xsltComputeSortResult: sort key is null\n"); + } else { + res->stringval = sortKey; + xmlFree(str); + } } results[i] = res; @@ -1094,7 +1104,8 @@ if (comp != NULL) number = comp->number; - return xsltComputeSortResultInternal(ctxt, sort, number, /* locale */ 0); + return xsltComputeSortResultInternal(ctxt, sort, number, + /* locale */ NULL); } /** @@ -1124,7 +1135,7 @@ xmlNodePtr node; xmlXPathObjectPtr tmp; int number[XSLT_MAX_SORT], desc[XSLT_MAX_SORT]; - xsltLocale locale[XSLT_MAX_SORT]; + void *locale[XSLT_MAX_SORT]; if ((ctxt == NULL) || (sorts == NULL) || (nbsorts <= 0) || (nbsorts >= XSLT_MAX_SORT)) @@ -1140,6 +1151,8 @@ return; /* nothing to do */ for (j = 0; j < nbsorts; j++) { + xmlChar *lang; + comp = sorts[j]->psvi; if ((comp->stype == NULL) && (comp->has_stype != 0)) { xmlChar *stype = @@ -1181,17 +1194,18 @@ desc[j] = comp->descending; } if ((comp->lang == NULL) && (comp->has_lang != 0)) { - xmlChar *lang = xsltEvalAttrValueTemplate(ctxt, sorts[j], + lang = xsltEvalAttrValueTemplate(ctxt, sorts[j], (xmlChar *) "lang", NULL); - if (lang != NULL) { - locale[j] = xsltNewLocale(lang); - xmlFree(lang); - } else { - locale[j] = 0; - } } else { - locale[j] = comp->locale; + lang = (xmlChar *) comp->lang; + } + if (lang != NULL) { + locale[j] = ctxt->newLocale(lang, comp->lower_first); + if (lang != comp->lang) + xmlFree(lang); + } else { + locale[j] = NULL; } } @@ -1236,11 +1250,6 @@ results[j + incr]->floatval) tst = 1; else tst = -1; - } else if(locale[0] != (xsltLocale)0) { - tst = xsltLocaleStrcmp( - locale[0], - (xsltLocaleChar *) results[j]->stringval, - (xsltLocaleChar *) results[j + incr]->stringval); } else { tst = xmlStrcmp(results[j]->stringval, results[j + incr]->stringval); @@ -1298,11 +1307,6 @@ res[j + incr]->floatval) tst = 1; else tst = -1; - } else if(locale[depth] != (xsltLocale)0) { - tst = xsltLocaleStrcmp( - locale[depth], - (xsltLocaleChar *) res[j]->stringval, - (xsltLocaleChar *) res[j + incr]->stringval); } else { tst = xmlStrcmp(res[j]->stringval, res[j + incr]->stringval); @@ -1351,11 +1355,8 @@ cleanup: for (j = 0; j < nbsorts; j++) { - comp = sorts[j]->psvi; - if ((comp->lang == NULL) && (comp->has_lang != 0)) { - if (locale[j] != (xsltLocale)0) { - xsltFreeLocale(locale[j]); - } + if (locale[j] != NULL) { + ctxt->freeLocale(locale[j]); } if (resultsTab[j] != NULL) { for (i = 0;i < len;i++) @@ -1396,6 +1397,8 @@ * xsltSetSortFunc: * @handler: the new handler function * + * DEPRECATED: Use xsltSetCtxtLocaleHandlers. + * * Function to reset the global handler for XSLT sorting. * If the handler is NULL, the default sort function will be used. */ @@ -1412,6 +1415,8 @@ * @ctxt: a XSLT process context * @handler: the new handler function * + * DEPRECATED: Use xsltSetCtxtLocaleHandlers. + * * Function to set the handler for XSLT sorting * for the specified context. * If the handler is NULL, then the global @@ -1422,6 +1427,28 @@ ctxt->sortfunc = handler; } +/** + * xsltSetCtxtLocaleHandlers: + * @ctxt: an XSLT transform context + * @newLocale: locale constructor + * @freeLocale: locale destructor + * @genSortKey sort key generator + * + * Set the locale handlers. + */ +void +xsltSetCtxtLocaleHandlers(xsltTransformContextPtr ctxt, + xsltNewLocaleFunc newLocale, + xsltFreeLocaleFunc freeLocale, + xsltGenSortKeyFunc genSortKey) { + if (ctxt == NULL) + return; + + ctxt->newLocale = newLocale; + ctxt->freeLocale = freeLocale; + ctxt->genSortKey = genSortKey; +} + /************************************************************************ * * * Parsing options * @@ -1801,6 +1828,8 @@ (const xmlChar *) "UTF-8"))) encoder = NULL; buf = xmlAllocOutputBuffer(encoder); + if (buf == NULL) + xmlCharEncCloseFunc(encoder); } else { buf = xmlAllocOutputBuffer(NULL); }
diff --git a/third_party/libxslt/src/libxslt/xsltutils.h b/third_party/libxslt/src/libxslt/xsltutils.h index 484032e..bca59dd 100644 --- a/third_party/libxslt/src/libxslt/xsltutils.h +++ b/third_party/libxslt/src/libxslt/xsltutils.h
@@ -179,6 +179,11 @@ xsltSetCtxtSortFunc (xsltTransformContextPtr ctxt, xsltSortFunc handler); XSLTPUBFUN void XSLTCALL + xsltSetCtxtLocaleHandlers (xsltTransformContextPtr ctxt, + xsltNewLocaleFunc newLocale, + xsltFreeLocaleFunc freeLocale, + xsltGenSortKeyFunc genSortKey); +XSLTPUBFUN void XSLTCALL xsltDefaultSortFunction (xsltTransformContextPtr ctxt, xmlNodePtr *sorts, int nbsorts);
diff --git a/tools/autotest.py b/tools/autotest.py index b5093cfe..9c3e8a5 100755 --- a/tools/autotest.py +++ b/tools/autotest.py
@@ -245,11 +245,14 @@ test_files = exact if len(exact) > 0 else close if len(test_files) > 1: - # Arbitrarily capping at 10 results so we don't print the name of every file - # in the repo if the target is poorly specified. - test_files = test_files[:10] - ExitWithMessage(f'Target "{target}" is ambiguous. Matching files: ' - f'{test_files}') + if len(test_files) < 10: + test_files = [HaveUserPickFile(test_files)] + else: + # Arbitrarily capping at 10 results so we don't print the name of every + # file in the repo if the target is poorly specified. + test_files = test_files[:10] + ExitWithMessage(f'Target "{target}" is ambiguous. Matching files: ' + f'{test_files}') if not test_files: ExitWithMessage(f'Target "{target}" did not match any files.') return test_files @@ -261,6 +264,19 @@ return target in _OTHER_TEST_TARGETS +def HaveUserPickFile(paths): + paths = sorted(paths, key=lambda p: (len(p), p)) + path_list = '\n'.join(f'{i}. {t}' for i, t in enumerate(paths)) + + while True: + user_input = input(f'Please choose the path you mean.\n{path_list}\n') + try: + value = int(user_input) + return paths[value] + except (ValueError, IndexError): + print('Try again') + + def HaveUserPickTarget(paths, targets): # Cap to 10 targets for convenience [0-9]. targets = targets[:10]
diff --git a/tools/gritsettings/resource_ids.spec b/tools/gritsettings/resource_ids.spec index 03c4a6a..65cb5b2 100644 --- a/tools/gritsettings/resource_ids.spec +++ b/tools/gritsettings/resource_ids.spec
@@ -740,10 +740,6 @@ "META": {"sizes": {"includes": [50],}}, "includes": [3405], }, - "<(SHARED_INTERMEDIATE_DIR)/ash/webui/projector_app/resources/annotator/trusted/ash_projector_annotator_trusted_resources.grd": { - "META": {"sizes": {"includes": [50],}}, - "includes": [3410], - }, "<(SHARED_INTERMEDIATE_DIR)/ash/webui/projector_app/resources/common/ash_projector_common_resources.grd": { "META": {"sizes": {"includes": [50],}}, "includes": [3415],
diff --git a/tools/memory/BUILD.gn b/tools/memory/BUILD.gn new file mode 100644 index 0000000..a7945854 --- /dev/null +++ b/tools/memory/BUILD.gn
@@ -0,0 +1,13 @@ +# 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("//testing/test.gni") + +group("all") { + testonly = true + deps = [ + "partition_allocator:all", + "simulator:all", + ] +}
diff --git a/tools/memory/simulator/BUILD.gn b/tools/memory/simulator/BUILD.gn new file mode 100644 index 0000000..ac1cf20 --- /dev/null +++ b/tools/memory/simulator/BUILD.gn
@@ -0,0 +1,47 @@ +# 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("//testing/test.gni") + +group("all") { + deps = [ ":memory_simulator" ] +} + +static_library("memory_simulator_lib") { + sources = [ + "contiguous_memory_holder.cc", + "contiguous_memory_holder.h", + "memory_holder.cc", + "memory_holder.h", + "memory_simulator.cc", + "memory_simulator.h", + "metrics_printer.cc", + "metrics_printer.h", + "metrics_provider.cc", + "metrics_provider.h", + "simulator_metrics_provider.cc", + "simulator_metrics_provider.h", + "utils.cc", + "utils.h", + ] + + if (is_mac) { + sources += [ + "process_metrics_provider_mac.cc", + "process_metrics_provider_mac.h", + "system_metrics_provider_mac.cc", + "system_metrics_provider_mac.h", + ] + } + + deps = [ "//base" ] +} + +executable("memory_simulator") { + sources = [ "memory_simulator_main.cc" ] + deps = [ + ":memory_simulator_lib", + "//base", + ] +}
diff --git a/tools/memory/simulator/OWNERS b/tools/memory/simulator/OWNERS new file mode 100644 index 0000000..1fb7e613 --- /dev/null +++ b/tools/memory/simulator/OWNERS
@@ -0,0 +1,2 @@ +fdoray@chromium.org +lizeb@chromium.org
diff --git a/tools/memory/simulator/contiguous_memory_holder.cc b/tools/memory/simulator/contiguous_memory_holder.cc new file mode 100644 index 0000000..846011a --- /dev/null +++ b/tools/memory/simulator/contiguous_memory_holder.cc
@@ -0,0 +1,94 @@ +// 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 "tools/memory/simulator/contiguous_memory_holder.h" + +#include <cstdint> + +#include "base/allocator/partition_allocator/page_allocator.h" +#include "base/check_op.h" +#include "base/debug/alias.h" +#include "base/memory/page_size.h" + +namespace memory_simulator { + +ContiguousMemoryHolder::ContiguousMemoryHolder(size_t max_pages) + : memory_length_(max_pages * base::GetPageSize()), + memory_(partition_alloc::AllocPages( + memory_length_, + base::GetPageSize(), + ::partition_alloc::PageAccessibilityConfiguration( + partition_alloc::PageAccessibilityConfiguration::kReadWrite), + partition_alloc::PageTag::kSimulation)), + alloc_position_(reinterpret_cast<uint64_t*>(memory_)), + read_position_(reinterpret_cast<uint64_t*>(memory_)), + write_position_(reinterpret_cast<uint64_t*>(memory_)) { + CHECK_NE(0u, memory_); +} + +ContiguousMemoryHolder::~ContiguousMemoryHolder() { + partition_alloc::FreePages(memory_, memory_length_); +} + +void ContiguousMemoryHolder::Allocate() { + DCHECK_EQ((reinterpret_cast<uintptr_t>(alloc_position_) - memory_) % + base::GetPageSize(), + 0u); + DCHECK_LT(reinterpret_cast<uintptr_t>(alloc_position_), + memory_ + memory_length_); + + // Writing zeros to the memory page forces it to be added to this process' + // private footprint. + for (size_t i = 0; i < base::GetPageSize() / sizeof(uint64_t); ++i) { + *alloc_position_ = 0; + ++alloc_position_; + } +} + +void ContiguousMemoryHolder::Read() { + if (read_position_ >= alloc_position_) { + read_position_ = reinterpret_cast<uint64_t*>(memory_); + if (read_position_ >= alloc_position_) { + // No-op if the initial allocation didn't happen. + return; + } + } + + DCHECK_LT(reinterpret_cast<uintptr_t>(read_position_), + memory_ + memory_length_); + DCHECK_EQ((reinterpret_cast<uintptr_t>(read_position_) - memory_) % + base::GetPageSize(), + 0u); + + uint64_t sum = 0; + for (size_t i = 0; i < base::GetPageSize() / sizeof(uint64_t); ++i) { + sum += *read_position_; + ++read_position_; + } + + base::debug::Alias(&sum); +} + +void ContiguousMemoryHolder::Write() { + if (write_position_ >= alloc_position_) { + write_position_ = reinterpret_cast<uint64_t*>(memory_); + if (write_position_ >= alloc_position_) { + // No-op if the initial allocation didn't happen. + return; + } + } + + DCHECK_LT(reinterpret_cast<uintptr_t>(write_position_), + memory_ + memory_length_); + DCHECK_EQ((reinterpret_cast<uintptr_t>(write_position_) - memory_) % + base::GetPageSize(), + 0u); + + for (size_t i = 0; i < base::GetPageSize() / sizeof(uint64_t); ++i) { + *write_position_ = Rand(); + ++write_position_; + } +} + +} // namespace memory_simulator
diff --git a/tools/memory/simulator/contiguous_memory_holder.h b/tools/memory/simulator/contiguous_memory_holder.h new file mode 100644 index 0000000..2aab4b8 --- /dev/null +++ b/tools/memory/simulator/contiguous_memory_holder.h
@@ -0,0 +1,39 @@ +// 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 TOOLS_MEMORY_SIMULATOR_CONTIGUOUS_MEMORY_HOLDER_H_ +#define TOOLS_MEMORY_SIMULATOR_CONTIGUOUS_MEMORY_HOLDER_H_ + +#include <cstddef> +#include <cstdint> + +#include "tools/memory/simulator/memory_holder.h" + +namespace memory_simulator { + +// A class that holds memory pages at contiguous virtual addresses. +class ContiguousMemoryHolder : public MemoryHolder { + public: + // `max_pages` is the maximum number of pages that can be allocated through + // this object (exceeding it will result in a crash). + explicit ContiguousMemoryHolder(size_t max_pages); + ~ContiguousMemoryHolder() override; + + // MemoryHolder: + void Allocate() override; + void Read() override; + void Write() override; + + private: + const size_t memory_length_; + const uintptr_t memory_; + + uint64_t* alloc_position_ = nullptr; + uint64_t* read_position_ = nullptr; + uint64_t* write_position_ = nullptr; +}; + +} // namespace memory_simulator + +#endif // TOOLS_MEMORY_SIMULATOR_CONTIGUOUS_MEMORY_HOLDER_H_
diff --git a/tools/memory/simulator/memory_holder.cc b/tools/memory/simulator/memory_holder.cc new file mode 100644 index 0000000..a76c2bdd --- /dev/null +++ b/tools/memory/simulator/memory_holder.cc
@@ -0,0 +1,16 @@ +// 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 "tools/memory/simulator/memory_holder.h" + +namespace memory_simulator { + +MemoryHolder::MemoryHolder() = default; +MemoryHolder::~MemoryHolder() = default; + +uint64_t MemoryHolder::Rand() { + return random_generator_.RandUint64(); +} + +} // namespace memory_simulator
diff --git a/tools/memory/simulator/memory_holder.h b/tools/memory/simulator/memory_holder.h new file mode 100644 index 0000000..0a42afb --- /dev/null +++ b/tools/memory/simulator/memory_holder.h
@@ -0,0 +1,44 @@ +// 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 TOOLS_MEMORY_SIMULATOR_MEMORY_HOLDER_H_ +#define TOOLS_MEMORY_SIMULATOR_MEMORY_HOLDER_H_ + +#include <stdint.h> + +#include "base/rand_util.h" + +namespace memory_simulator { + +// Interface for a class that supports these operations: +// - Allocate a new memory page +// - Read the next memory page +// - Write the next memory page +class MemoryHolder { + public: + MemoryHolder(); + virtual ~MemoryHolder(); + + // Add a page filled with zeros to the "private footprint" of this process. + virtual void Allocate() = 0; + + // Read the next memory page. When the end is reached, goes back to the first + // page. No-ops if no page was allocated yet. + virtual void Read() = 0; + + // Writes to the next memory page. When the end is reached, goes back to the + // first page. No-ops if no page was allocated yet. + virtual void Write() = 0; + + protected: + // Returns a random number for use by Write() implementations. + uint64_t Rand(); + + private: + base::InsecureRandomGenerator random_generator_; +}; + +} // namespace memory_simulator + +#endif // TOOLS_MEMORY_SIMULATOR_MEMORY_HOLDER_H_
diff --git a/tools/memory/simulator/memory_simulator.cc b/tools/memory/simulator/memory_simulator.cc new file mode 100644 index 0000000..9281099 --- /dev/null +++ b/tools/memory/simulator/memory_simulator.cc
@@ -0,0 +1,108 @@ +// 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 "tools/memory/simulator/memory_simulator.h" + +#include <cstdint> + +#include "base/check.h" +#include "base/debug/alias.h" +#include "base/logging.h" +#include "base/memory/page_size.h" +#include "base/time/time.h" +#include "tools/memory/simulator/contiguous_memory_holder.h" + +namespace memory_simulator { + +MemorySimulator::MemorySimulator() = default; +MemorySimulator::~MemorySimulator() = default; + +void MemorySimulator::Start(int64_t page_alloc_per_sec, + int64_t page_read_per_sec, + int64_t page_write_per_sec, + int64_t max_pages_allocated, + base::TimeTicks read_deadline, + base::TimeTicks write_deadline) { + memory_holder_ = + std::make_unique<ContiguousMemoryHolder>(max_pages_allocated); + max_pages_allocated_ = max_pages_allocated; + + if (page_alloc_per_sec != 0) { + alloc_timer_.Start(FROM_HERE, base::Hertz(page_alloc_per_sec), this, + &MemorySimulator::Allocate); + } + + if (page_read_per_sec != 0) { + read_timer_.Start(FROM_HERE, base::Hertz(page_read_per_sec), this, + &MemorySimulator::Read); + read_deadline_ = read_deadline; + } + + if (page_write_per_sec != 0) { + write_timer_.Start(FROM_HERE, base::Hertz(page_write_per_sec), this, + &MemorySimulator::Write); + write_deadline_ = write_deadline; + } +} + +void MemorySimulator::StopAndFree() { + memory_holder_.reset(); + alloc_timer_.Stop(); + read_timer_.Stop(); + write_timer_.Stop(); + pages_allocated_ = 0; +} + +int64_t MemorySimulator::GetPagesAllocated() const { + return pages_allocated_; +} + +int64_t MemorySimulator::GetPagesRead() const { + return pages_read_; +} + +int64_t MemorySimulator::GetPagesWritten() const { + return pages_written_; +} + +void MemorySimulator::Allocate() { + CHECK_LE(pages_allocated_, max_pages_allocated_); + if (pages_allocated_ == max_pages_allocated_) { + alloc_timer_.Stop(); + return; + } + + memory_holder_->Allocate(); + ++pages_allocated_; +} + +void MemorySimulator::Read() { + if (base::TimeTicks::Now() >= read_deadline_) { + read_timer_.Stop(); + return; + } + + if (pages_allocated_ == 0) { + return; + } + + memory_holder_->Read(); + ++pages_read_; +} + +void MemorySimulator::Write() { + if (base::TimeTicks::Now() >= write_deadline_) { + write_timer_.Stop(); + return; + } + + if (pages_allocated_ == 0) { + return; + } + + memory_holder_->Write(); + ++pages_written_; +} + +} // namespace memory_simulator
diff --git a/tools/memory/simulator/memory_simulator.h b/tools/memory/simulator/memory_simulator.h new file mode 100644 index 0000000..594a26f4 --- /dev/null +++ b/tools/memory/simulator/memory_simulator.h
@@ -0,0 +1,59 @@ +// 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 TOOLS_MEMORY_SIMULATOR_MEMORY_SIMULATOR_H_ +#define TOOLS_MEMORY_SIMULATOR_MEMORY_SIMULATOR_H_ + +#include <stdint.h> +#include <cstdint> +#include <memory> + +#include "base/rand_util.h" +#include "base/time/time.h" +#include "base/timer/timer.h" +#include "tools/memory/simulator/memory_holder.h" + +namespace memory_simulator { + +// Allocates, reads and writes memory pages at a configurable frequency. +class MemorySimulator { + public: + MemorySimulator(); + ~MemorySimulator(); + + void Start(int64_t page_alloc_per_second, + int64_t page_read_per_second, + int64_t page_write_per_second, + int64_t max_pages_allocated, + base::TimeTicks read_deadline, + base::TimeTicks write_deadline); + + void StopAndFree(); + + int64_t GetPagesAllocated() const; + int64_t GetPagesRead() const; + int64_t GetPagesWritten() const; + + private: + void Allocate(); + void Read(); + void Write(); + + std::unique_ptr<MemoryHolder> memory_holder_; + int64_t pages_allocated_ = 0; + int64_t max_pages_allocated_ = 0; + int64_t pages_read_ = 0; + int64_t pages_written_ = 0; + + base::MetronomeTimer alloc_timer_; + base::MetronomeTimer read_timer_; + base::MetronomeTimer write_timer_; + + base::TimeTicks read_deadline_; + base::TimeTicks write_deadline_; +}; + +} // namespace memory_simulator + +#endif // TOOLS_MEMORY_SIMULATOR_MEMORY_SIMULATOR_H_
diff --git a/tools/memory/simulator/memory_simulator_main.cc b/tools/memory/simulator/memory_simulator_main.cc new file mode 100644 index 0000000..63af6416 --- /dev/null +++ b/tools/memory/simulator/memory_simulator_main.cc
@@ -0,0 +1,249 @@ +// 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 <cstdint> +#include <iostream> +#include <limits> + +#include "base/command_line.h" +#include "base/functional/bind.h" +#include "base/functional/callback_forward.h" +#include "base/location.h" +#include "base/logging.h" +#include "base/run_loop.h" +#include "base/strings/string_number_conversions.h" +#include "base/strings/string_piece.h" +#include "base/strings/stringprintf.h" +#include "base/task/single_thread_task_executor.h" +#include "base/timer/timer.h" +#include "third_party/abseil-cpp/absl/types/optional.h" +#include "tools/memory/simulator/memory_simulator.h" +#include "tools/memory/simulator/metrics_printer.h" +#include "tools/memory/simulator/simulator_metrics_provider.h" +#include "tools/memory/simulator/utils.h" + +#if BUILDFLAG(IS_MAC) +#include "tools/memory/simulator/process_metrics_provider_mac.h" +#include "tools/memory/simulator/system_metrics_provider_mac.h" +#endif // BUILDFLAG(IS_MAC) + +namespace { + +void InitLogging() { + logging::LoggingSettings settings; + settings.logging_dest = + logging::LOG_TO_SYSTEM_DEBUG_LOG | logging::LOG_TO_STDERR; + settings.log_file_path = nullptr; + settings.lock_log = logging::DONT_LOCK_LOG_FILE; + settings.delete_old = logging::APPEND_TO_OLD_LOG_FILE; + bool logging_res = logging::InitLogging(settings); + CHECK(logging_res); +} + +constexpr char kSwitchHelp[] = "h"; +constexpr char kSwitchAllocPerSec[] = "mb_alloc_per_sec"; +constexpr char kSwitchReadPerSec[] = "mb_read_per_sec"; +constexpr char kSwitchWritePerSec[] = "mb_write_per_sec"; +constexpr char kSwitchAllocLimit[] = "alloc_limit"; +constexpr char kSwitchStartTimeout[] = "start_timeout"; +constexpr char kSwitchReadTimeout[] = "read_timeout"; +constexpr char kSwitchWriteTimeout[] = "write_timeout"; +constexpr char kSwitchFreeTimeout[] = "free_timeout"; +constexpr char kSwitchExitTimeout[] = "exit_timeout"; +constexpr char kUsageString[] = R"(Usage: memory_simulator [options] + +A tool to allocate, read and write memory pages at a configurable frequency. + +Options: + --mb_alloc_per_sec Megabytes allocated per second + --mb_read_per_sec Megabytes read per second + --mb_write_per_sec Megabytes written per second + --alloc_limit Stop allocating after this limit (megabytes) + --start_timeout Start alloc/read/write after this timeout (seconds) + --read_timeout Stop reading after this timeout (seconds) + --write_timeout Stop writing reaching this timeout (seconds) + --free_timeout Free all memory after this timeout (seconds) + --exit_timeout Exit after this timeout (seconds) + +All options can be set to inifinite with the value "inf". +)"; + +void PrintUsageError(const std::string error) { + std::cerr << "Error: " << error << std::endl << std::endl << kUsageString; +} + +// Status code, which can also be used as process exit code. Therefore +// success is explicitly 0. +enum StatusCode { + kStatusSuccess = 0, + kStatusUsage = 1, + kStatusInvalidParam = 2, + kStatusRuntimeError = 3, +}; + +absl::optional<int64_t> GetInt64Switch(const base::CommandLine& command_line, + const std::string& switch_name, + int64_t default_value) { + if (!command_line.HasSwitch(switch_name)) { + return default_value; + } + + const std::string switch_value = + command_line.GetSwitchValueASCII(switch_name); + if (switch_value == "inf") { + return std::numeric_limits<int64_t>::max(); + } + + int64_t switch_value_int64 = 0; + if (!base::StringToInt64(switch_value, &switch_value_int64) || + switch_value_int64 < 0) { + PrintUsageError(base::StringPrintf("Switch %s must be a positive integer", + switch_name.c_str())); + return absl::nullopt; + } + + return switch_value_int64; +} + +absl::optional<base::TimeDelta> GetSecondsSwitch( + const base::CommandLine& command_line, + const std::string& switch_name, + int64_t default_value) { + absl::optional<int64_t> seconds = + GetInt64Switch(command_line, switch_name, default_value); + if (!seconds.has_value()) { + return absl::nullopt; + } + + if (seconds.value() == std::numeric_limits<int64_t>::max()) { + return base::TimeDelta::Max(); + } + + return base::Seconds(seconds.value()); +} + +} // namespace + +int main(int argc, char** argv) { + base::CommandLine::Init(argc, argv); + const base::CommandLine& command_line = + *base::CommandLine::ForCurrentProcess(); + InitLogging(); + +#if DCHECK_IS_ON() + LOG(WARNING) << "!!!!!!"; + LOG(WARNING) << "memory_simulator was built with DCHECKs enabled. This " + "changes the behavior of alloc/free and may affect results."; + LOG(WARNING) << "!!!!!!"; +#endif + + if (command_line.HasSwitch(kSwitchHelp)) { + std::cerr << kUsageString; + return kStatusUsage; + } + + absl::optional<int64_t> mb_alloc_per_sec = + GetInt64Switch(command_line, kSwitchAllocPerSec, 512); + if (!mb_alloc_per_sec.has_value()) { + return kStatusInvalidParam; + } + + absl::optional<int64_t> mb_read_per_sec = + GetInt64Switch(command_line, kSwitchReadPerSec, 1024); + if (!mb_read_per_sec.has_value()) { + return kStatusInvalidParam; + } + + absl::optional<int64_t> mb_write_per_sec = + GetInt64Switch(command_line, kSwitchWritePerSec, 1024); + if (!mb_write_per_sec.has_value()) { + return kStatusInvalidParam; + } + + absl::optional<int64_t> mb_alloc_limit = + GetInt64Switch(command_line, kSwitchAllocLimit, 10 * 1024); + if (!mb_alloc_limit.has_value()) { + return kStatusInvalidParam; + } + + absl::optional<base::TimeDelta> start_timeout = + GetSecondsSwitch(command_line, kSwitchStartTimeout, 0); + if (!start_timeout.has_value()) { + return kStatusInvalidParam; + } + + absl::optional<base::TimeDelta> read_timeout = + GetSecondsSwitch(command_line, kSwitchReadTimeout, 5 * 60); + if (!read_timeout.has_value()) { + return kStatusInvalidParam; + } + + absl::optional<base::TimeDelta> write_timeout = + GetSecondsSwitch(command_line, kSwitchWriteTimeout, 5 * 60); + if (!write_timeout.has_value()) { + return kStatusInvalidParam; + } + + absl::optional<base::TimeDelta> free_timeout = + GetSecondsSwitch(command_line, kSwitchFreeTimeout, 10 * 60); + if (!free_timeout.has_value()) { + return kStatusInvalidParam; + } + + absl::optional<base::TimeDelta> exit_timeout = + GetSecondsSwitch(command_line, kSwitchExitTimeout, 5 * 60); + if (!exit_timeout.has_value()) { + return kStatusInvalidParam; + } + + base::SingleThreadTaskExecutor executor; + base::RunLoop run_loop; + + memory_simulator::MemorySimulator simulator; + + base::OneShotTimer free_timer; + free_timer.Start( + FROM_HERE, free_timeout.value(), + base::BindOnce(&memory_simulator::MemorySimulator::StopAndFree, + base::Unretained(&simulator))); + + base::OneShotTimer exit_timer; + exit_timer.Start(FROM_HERE, exit_timeout.value(), run_loop.QuitClosure()); + + memory_simulator::MetricsPrinter printer; + printer.AddProvider( + std::make_unique<memory_simulator::SimulatorMetricsProvider>(&simulator)); +#if BUILDFLAG(IS_MAC) + printer.AddProvider( + std::make_unique<memory_simulator::ProcessMetricsProviderMac>()); + printer.AddProvider( + std::make_unique<memory_simulator::SystemMetricsProviderMac>()); +#endif // BUILDFLAG(IS_MAC) + + base::RepeatingTimer stats_timer; + printer.PrintHeader(); + stats_timer.Start( + FROM_HERE, base::Seconds(5), + base::BindRepeating(&memory_simulator::MetricsPrinter::PrintStats, + base::Unretained(&printer))); + + base::TimeTicks now = base::TimeTicks::Now(); + base::TimeTicks read_deadline = now + read_timeout.value(); + base::TimeTicks write_deadline = now + write_timeout.value(); + + base::OneShotTimer start_timer; + start_timer.Start( + FROM_HERE, start_timeout.value(), + base::BindOnce(&memory_simulator::MemorySimulator::Start, + base::Unretained(&simulator), + memory_simulator::MBToPages(mb_alloc_per_sec.value()), + memory_simulator::MBToPages(mb_read_per_sec.value()), + memory_simulator::MBToPages(mb_write_per_sec.value()), + memory_simulator::MBToPages(mb_alloc_limit.value()), + read_deadline, write_deadline)); + + run_loop.Run(); + + return kStatusSuccess; +}
diff --git a/tools/memory/simulator/metrics_printer.cc b/tools/memory/simulator/metrics_printer.cc new file mode 100644 index 0000000..c4d676f --- /dev/null +++ b/tools/memory/simulator/metrics_printer.cc
@@ -0,0 +1,64 @@ +// 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 "tools/memory/simulator/metrics_printer.h" + +#include <iostream> + +#include "base/strings/stringprintf.h" + +namespace memory_simulator { + +MetricsPrinter::MetricsPrinter() = default; + +MetricsPrinter::~MetricsPrinter() = default; + +void MetricsPrinter::AddProvider(std::unique_ptr<MetricsProvider> provider) { + DCHECK(!did_print_header_); + providers_.push_back(std::move(provider)); +} + +void MetricsPrinter::PrintHeader() { + DCHECK(!did_print_header_); + did_print_header_ = true; + + std::string out = "elapsed_time(s)"; + + for (auto& provider : providers_) { + std::vector<std::string> metric_names = provider->GetMetricNames(); + for (const std::string& metric_name : metric_names) { + base::StringAppendF(&out, ",%s", metric_name.c_str()); + } + } + + std::cout << out << std::endl; +} + +void MetricsPrinter::PrintStats() { + DCHECK(did_print_header_); + + std::string out; + + base::TimeTicks now = base::TimeTicks::Now(); + double seconds_since_start = (now - start_time_).InSecondsF(); + base::StringAppendF(&out, "%.2f", seconds_since_start); + + for (auto& provider : providers_) { + std::vector<std::string> metric_names = provider->GetMetricNames(); + std::map<std::string, double> metric_values = + provider->GetMetricValues(now); + for (const std::string& metric_name : metric_names) { + auto it = metric_values.find(metric_name); + if (it == metric_values.end()) { + out += ","; + } else { + base::StringAppendF(&out, ",%.2f", it->second); + } + } + } + + std::cout << out << std::endl; +} + +} // namespace memory_simulator
diff --git a/tools/memory/simulator/metrics_printer.h b/tools/memory/simulator/metrics_printer.h new file mode 100644 index 0000000..ac8421c --- /dev/null +++ b/tools/memory/simulator/metrics_printer.h
@@ -0,0 +1,43 @@ +// 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 TOOLS_MEMORY_SIMULATOR_METRICS_PRINTER_H_ +#define TOOLS_MEMORY_SIMULATOR_METRICS_PRINTER_H_ + +#include <memory> +#include <vector> + +#include "base/time/time.h" +#include "tools/memory/simulator/metrics_provider.h" + +namespace memory_simulator { + +// Outputs memory stats in CSV format to stdout. +class MetricsPrinter { + public: + MetricsPrinter(); + ~MetricsPrinter(); + + // Adds a metrics provider. This can only be called before the first call to + // PrintHeader(). + void AddProvider(std::unique_ptr<MetricsProvider> provider); + + // Prints header row. + void PrintHeader(); + + // Prints stats row. This can only be called after PrintHeader() has been + // called. + void PrintStats(); + + private: + const base::TimeTicks start_time_ = base::TimeTicks::Now(); + + bool did_print_header_ = false; + + std::vector<std::unique_ptr<MetricsProvider>> providers_; +}; + +} // namespace memory_simulator + +#endif // TOOLS_MEMORY_SIMULATOR_METRICS_PRINTER_H_
diff --git a/tools/memory/simulator/metrics_provider.cc b/tools/memory/simulator/metrics_provider.cc new file mode 100644 index 0000000..d137254 --- /dev/null +++ b/tools/memory/simulator/metrics_provider.cc
@@ -0,0 +1,12 @@ +// 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 "tools/memory/simulator/metrics_provider.h" + +namespace memory_simulator { + +MetricsProvider::MetricsProvider() = default; +MetricsProvider::~MetricsProvider() = default; + +} // namespace memory_simulator
diff --git a/tools/memory/simulator/metrics_provider.h b/tools/memory/simulator/metrics_provider.h new file mode 100644 index 0000000..b66bef5 --- /dev/null +++ b/tools/memory/simulator/metrics_provider.h
@@ -0,0 +1,32 @@ +// 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 TOOLS_MEMORY_SIMULATOR_METRICS_PROVIDER_H_ +#define TOOLS_MEMORY_SIMULATOR_METRICS_PROVIDER_H_ + +#include <map> +#include <string> +#include <vector> + +#include "base/time/time.h" + +namespace memory_simulator { + +class MetricsProvider { + public: + MetricsProvider(); + virtual ~MetricsProvider(); + + // Returns the list of metrics that can be returned by this provider. This + // must always return the same metrics, in the same order. + virtual std::vector<std::string> GetMetricNames() = 0; + + // Returns metric values. All keys must be part of `GetMetricNames()`. + virtual std::map<std::string, double> GetMetricValues( + base::TimeTicks now) = 0; +}; + +} // namespace memory_simulator + +#endif // TOOLS_MEMORY_SIMULATOR_METRICS_PROVIDER_H_
diff --git a/tools/memory/simulator/process_metrics_provider_mac.cc b/tools/memory/simulator/process_metrics_provider_mac.cc new file mode 100644 index 0000000..c68f1d3 --- /dev/null +++ b/tools/memory/simulator/process_metrics_provider_mac.cc
@@ -0,0 +1,47 @@ +// 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 "tools/memory/simulator/process_metrics_provider_mac.h" + +#include <mach/mach.h> +#include <mach/mach_time.h> +#include <mach/mach_vm.h> + +#include "base/mac/mach_logging.h" +#include "base/mac/scoped_mach_port.h" +#include "base/time/time.h" +#include "tools/memory/simulator/utils.h" + +namespace memory_simulator { + +ProcessMetricsProviderMac::ProcessMetricsProviderMac() = default; +ProcessMetricsProviderMac::~ProcessMetricsProviderMac() = default; + +std::vector<std::string> ProcessMetricsProviderMac::GetMetricNames() { + return {"process_resident(gb)", "process_internal(gb)", + "process_external(gb)", "process_compressed(gb)", + "process_physical(gb)"}; +} + +std::map<std::string, double> ProcessMetricsProviderMac::GetMetricValues( + base::TimeTicks now) { + std::map<std::string, double> metrics; + + task_vm_info process_info; + mach_msg_type_number_t count = TASK_VM_INFO_REV2_COUNT; + kern_return_t result = + task_info(mach_task_self(), TASK_VM_INFO, + reinterpret_cast<task_info_t>(&process_info), &count); + CHECK_EQ(result, KERN_SUCCESS); + + metrics["process_resident(gb)"] = BytesToGB(process_info.resident_size); + metrics["process_internal(gb)"] = BytesToGB(process_info.internal); + metrics["process_external(gb)"] = BytesToGB(process_info.external); + metrics["process_compressed(gb)"] = BytesToGB(process_info.compressed); + metrics["process_physical(gb)"] = BytesToGB(process_info.phys_footprint); + + return metrics; +} + +} // namespace memory_simulator
diff --git a/tools/memory/simulator/process_metrics_provider_mac.h b/tools/memory/simulator/process_metrics_provider_mac.h new file mode 100644 index 0000000..2dabc13 --- /dev/null +++ b/tools/memory/simulator/process_metrics_provider_mac.h
@@ -0,0 +1,24 @@ +// 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 TOOLS_MEMORY_SIMULATOR_PROCESS_METRICS_PROVIDER_MAC_H_ +#define TOOLS_MEMORY_SIMULATOR_PROCESS_METRICS_PROVIDER_MAC_H_ + +#include "tools/memory/simulator/metrics_provider.h" + +namespace memory_simulator { + +class ProcessMetricsProviderMac : public MetricsProvider { + public: + ProcessMetricsProviderMac(); + ~ProcessMetricsProviderMac() override; + + // MetricsProvider: + std::vector<std::string> GetMetricNames() override; + std::map<std::string, double> GetMetricValues(base::TimeTicks now) override; +}; + +} // namespace memory_simulator + +#endif // TOOLS_MEMORY_SIMULATOR_PROCESS_METRICS_PROVIDER_MAC_H_
diff --git a/tools/memory/simulator/simulator_metrics_provider.cc b/tools/memory/simulator/simulator_metrics_provider.cc new file mode 100644 index 0000000..4ba4ac6b --- /dev/null +++ b/tools/memory/simulator/simulator_metrics_provider.cc
@@ -0,0 +1,50 @@ +// 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 "tools/memory/simulator/simulator_metrics_provider.h" + +#include "base/time/time.h" +#include "tools/memory/simulator/memory_simulator.h" +#include "tools/memory/simulator/utils.h" + +namespace memory_simulator { + +SimulatorMetricsProvider::SimulatorMetricsProvider(MemorySimulator* simulator) + : simulator_(simulator) {} + +SimulatorMetricsProvider::~SimulatorMetricsProvider() = default; + +std::vector<std::string> SimulatorMetricsProvider::GetMetricNames() { + return {"simulator_allocated(gb)", "simulator_allocation_rate(mb/s)", + "simulator_read_rate(mb/s)", "simulator_write_rate(mb/s)"}; +} + +std::map<std::string, double> SimulatorMetricsProvider::GetMetricValues( + base::TimeTicks now) { + int64_t pages_allocated = simulator_->GetPagesAllocated(); + int64_t pages_read = simulator_->GetPagesRead(); + int64_t pages_written = simulator_->GetPagesWritten(); + + std::map<std::string, double> metrics; + metrics["simulator_allocated(gb)"] = PagesToGB(pages_allocated); + + if (!prev_time_.is_null()) { + base::TimeDelta elapsed = now - prev_time_; + metrics["simulator_allocation_rate(mb/s)"] = + PagesToMBPerSec(prev_pages_allocated_, pages_allocated, elapsed); + metrics["simulator_read_rate(mb/s)"] = + PagesToMBPerSec(prev_pages_read_, pages_read, elapsed); + metrics["simulator_write_rate(mb/s)"] = + PagesToMBPerSec(prev_pages_written_, pages_written, elapsed); + } + + prev_time_ = now; + prev_pages_allocated_ = pages_allocated; + prev_pages_read_ = pages_read; + prev_pages_written_ = pages_written; + + return metrics; +} + +} // namespace memory_simulator
diff --git a/tools/memory/simulator/simulator_metrics_provider.h b/tools/memory/simulator/simulator_metrics_provider.h new file mode 100644 index 0000000..7a94b673 --- /dev/null +++ b/tools/memory/simulator/simulator_metrics_provider.h
@@ -0,0 +1,39 @@ +// 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 TOOLS_MEMORY_SIMULATOR_SIMULATOR_METRICS_PROVIDER_H_ +#define TOOLS_MEMORY_SIMULATOR_SIMULATOR_METRICS_PROVIDER_H_ + +#include <stdint.h> +#include <cstdint> + +#include "base/memory/raw_ptr.h" +#include "base/time/time.h" +#include "tools/memory/simulator/metrics_provider.h" + +namespace memory_simulator { + +class MemorySimulator; + +class SimulatorMetricsProvider : public MetricsProvider { + public: + explicit SimulatorMetricsProvider(MemorySimulator* simulator); + ~SimulatorMetricsProvider() override; + + // MetricsProvider: + std::vector<std::string> GetMetricNames() override; + std::map<std::string, double> GetMetricValues(base::TimeTicks now) override; + + private: + raw_ptr<MemorySimulator> simulator_; + + base::TimeTicks prev_time_; + int64_t prev_pages_allocated_ = 0; + int64_t prev_pages_read_ = 0; + int64_t prev_pages_written_ = 0; +}; + +} // namespace memory_simulator + +#endif // TOOLS_MEMORY_SIMULATOR_SIMULATOR_METRICS_PROVIDER_H_
diff --git a/tools/memory/simulator/system_metrics_provider_mac.cc b/tools/memory/simulator/system_metrics_provider_mac.cc new file mode 100644 index 0000000..e557cb8 --- /dev/null +++ b/tools/memory/simulator/system_metrics_provider_mac.cc
@@ -0,0 +1,117 @@ +// 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 "tools/memory/simulator/system_metrics_provider_mac.h" + +#include <mach/mach.h> +#include <mach/mach_time.h> + +#include "base/mac/mach_logging.h" +#include "base/mac/scoped_mach_port.h" +#include "base/time/time.h" +#include "tools/memory/simulator/utils.h" + +namespace memory_simulator { + +SystemMetricsProviderMac::SystemMetricsProviderMac() = default; +SystemMetricsProviderMac::~SystemMetricsProviderMac() = default; + +std::vector<std::string> SystemMetricsProviderMac::GetMetricNames() { + return {"total(gb)", + "free(gb)", + "active(gb)", + "inactive(gb)", + "wired(gb)", + "purgeable_count(gb)", + "speculative(gb)", + "compressor(gb)", + "throttled(gb)", + "file_backed(gb)", + "anonymous(gb)", + "uncompressed_in_compressor(gb)", + "reactivations(mb/s)", + "pageins(mb/s)", + "pageouts(mb/s)", + "faults(mb/s)", + "cow_faults(mb/s)", + "cache_lookups(mb/s)", + "cache_hits(mb/s)", + "purges(mb/s)", + "decompressions(mb/s)", + "compressions(mb/s)", + "swapins(mb/s)", + "swapouts(mb/s)"}; +} + +std::map<std::string, double> SystemMetricsProviderMac::GetMetricValues( + base::TimeTicks now) { + std::map<std::string, double> metrics; + + struct host_basic_info hostinfo; + mach_msg_type_number_t count = HOST_BASIC_INFO_COUNT; + base::mac::ScopedMachSendRight host(mach_host_self()); + int result = host_info(host.get(), HOST_BASIC_INFO, + reinterpret_cast<host_info_t>(&hostinfo), &count); + CHECK_EQ(result, KERN_SUCCESS); + + CHECK_EQ(HOST_BASIC_INFO_COUNT, count); + metrics["total(gb)"] = BytesToGB(hostinfo.max_mem); + + vm_statistics64_data_t vm_info; + count = HOST_VM_INFO64_COUNT; + CHECK_EQ(host_statistics64(host.get(), HOST_VM_INFO64, + reinterpret_cast<host_info64_t>(&vm_info), &count), + KERN_SUCCESS); + CHECK_EQ(HOST_VM_INFO64_COUNT, count); + + // Free memory includes speculative memory. + metrics["free(gb)"] = PagesToGB(vm_info.free_count); + metrics["active(gb)"] = PagesToGB(vm_info.active_count); + metrics["inactive(gb)"] = PagesToGB(vm_info.inactive_count); + metrics["wired(gb)"] = PagesToGB(vm_info.wire_count); + metrics["purgeable_count(gb)"] = PagesToGB(vm_info.purgeable_count); + metrics["speculative(gb)"] = PagesToGB(vm_info.speculative_count); + metrics["compressor(gb)"] = PagesToGB(vm_info.compressor_page_count); + metrics["throttled(gb)"] = PagesToGB(vm_info.throttled_count); + metrics["file_backed(gb)"] = PagesToGB(vm_info.external_page_count); + metrics["anonymous(gb)"] = PagesToGB(vm_info.internal_page_count); + metrics["uncompressed_in_compressor(gb)"] = + PagesToGB(vm_info.total_uncompressed_pages_in_compressor); + + if (!prev_time_.is_null()) { + const base::TimeDelta elapsed = now - prev_time_; + + metrics["reactivations(mb/s)"] = PagesToMBPerSec( + prev_vm_info_.reactivations, vm_info.reactivations, elapsed); + metrics["pageins(mb/s)"] = + PagesToMBPerSec(prev_vm_info_.pageins, vm_info.pageins, elapsed); + metrics["pageouts(mb/s)"] = + PagesToMBPerSec(prev_vm_info_.pageouts, vm_info.pageouts, elapsed); + metrics["faults(mb/s)"] = + PagesToMBPerSec(prev_vm_info_.faults, vm_info.faults, elapsed); + metrics["cow_faults(mb/s)"] = + PagesToMBPerSec(prev_vm_info_.cow_faults, vm_info.cow_faults, elapsed); + metrics["cache_lookups(mb/s)"] = + PagesToMBPerSec(prev_vm_info_.lookups, vm_info.lookups, elapsed); + metrics["cache_hits(mb/s)"] = + PagesToMBPerSec(prev_vm_info_.hits, vm_info.hits, elapsed); + metrics["purges(mb/s)"] = + PagesToMBPerSec(prev_vm_info_.purges, vm_info.purges, elapsed); + metrics["decompressions(mb/s)"] = PagesToMBPerSec( + prev_vm_info_.decompressions, vm_info.decompressions, elapsed); + metrics["compressions(mb/s)"] = PagesToMBPerSec( + prev_vm_info_.compressions, vm_info.compressions, elapsed); + metrics["swapins(mb/s)"] = + PagesToMBPerSec(prev_vm_info_.swapins, vm_info.swapins, elapsed); + metrics["swapouts(mb/s)"] = + PagesToMBPerSec(prev_vm_info_.swapouts, vm_info.swapouts, elapsed); + } + + prev_time_ = now; + prev_vm_info_ = vm_info; + + return metrics; +} + +} // namespace memory_simulator
diff --git a/tools/memory/simulator/system_metrics_provider_mac.h b/tools/memory/simulator/system_metrics_provider_mac.h new file mode 100644 index 0000000..4c6a41d --- /dev/null +++ b/tools/memory/simulator/system_metrics_provider_mac.h
@@ -0,0 +1,30 @@ +// 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 TOOLS_MEMORY_SIMULATOR_SYSTEM_METRICS_PROVIDER_MAC_H_ +#define TOOLS_MEMORY_SIMULATOR_SYSTEM_METRICS_PROVIDER_MAC_H_ + +#include <mach/mach_vm.h> + +#include "tools/memory/simulator/metrics_provider.h" + +namespace memory_simulator { + +class SystemMetricsProviderMac : public MetricsProvider { + public: + SystemMetricsProviderMac(); + ~SystemMetricsProviderMac() override; + + // MetricsProvider: + std::vector<std::string> GetMetricNames() override; + std::map<std::string, double> GetMetricValues(base::TimeTicks now) override; + + private: + base::TimeTicks prev_time_; + vm_statistics64_data_t prev_vm_info_; +}; + +} // namespace memory_simulator + +#endif // TOOLS_MEMORY_SIMULATOR_SYSTEM_METRICS_PROVIDER_MAC_H_
diff --git a/tools/memory/simulator/utils.cc b/tools/memory/simulator/utils.cc new file mode 100644 index 0000000..73f20555 --- /dev/null +++ b/tools/memory/simulator/utils.cc
@@ -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. + +#include "tools/memory/simulator/utils.h" + +#include "base/memory/page_size.h" + +namespace memory_simulator { + +double BytesToGB(uint64_t bytes) { + return static_cast<double>(bytes) / (1024 * 1024 * 1024); +} + +double BytesToMB(uint64_t bytes) { + return static_cast<double>(bytes) / (1024 * 1024); +} + +double PagesToGB(uint64_t pages) { + return BytesToGB(pages * base::GetPageSize()); +} + +double PagesToMB(uint64_t pages) { + return BytesToMB(pages * base::GetPageSize()); +} + +int64_t MBToPages(uint64_t mb) { + return mb * 1024 * 1024 / base::GetPageSize(); +} + +double PagesToMBPerSec(int64_t pages_begin, + int64_t pages_end, + base::TimeDelta duration) { + return PagesToMB(pages_end - pages_begin) / duration.InSecondsF(); +} + +} // namespace memory_simulator
diff --git a/tools/memory/simulator/utils.h b/tools/memory/simulator/utils.h new file mode 100644 index 0000000..7a1c297 --- /dev/null +++ b/tools/memory/simulator/utils.h
@@ -0,0 +1,29 @@ +// 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 TOOLS_MEMORY_SIMULATOR_UTILS_H_ +#define TOOLS_MEMORY_SIMULATOR_UTILS_H_ + +#include <stdint.h> + +#include "base/time/time.h" + +namespace memory_simulator { + +// Convert between bytes, GB, MB and pages. +double BytesToGB(uint64_t bytes); +double BytesToMB(uint64_t bytes); +double PagesToGB(uint64_t pages); +double PagesToMB(uint64_t pages); +int64_t MBToPages(uint64_t mb); + +// Computes the amount of Megabytes per Second from a number of page at the +// beginning and end of an interval and the duration of the interval. +double PagesToMBPerSec(int64_t pages_begin, + int64_t pages_end, + base::TimeDelta duration); + +} // namespace memory_simulator + +#endif // TOOLS_MEMORY_SIMULATOR_UTILS_H_
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index c099df1b..23f689a 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -13863,6 +13863,8 @@ <int value="1" label="get and observe via document api"/> <int value="2" label="get via fetch-like api"/> <int value="3" label="observe via fetch-like api"/> + <int value="4" label="get via iframe attribute api"/> + <int value="5" label="observe via iframe attribute api"/> </enum> <enum name="BrowsingTopicsCalculatorResultStatus"> @@ -35649,6 +35651,7 @@ <int value="1774" label="PASSWORDSPRIVATE_CONTINUEIMPORT"/> <int value="1775" label="PASSWORDSPRIVATE_RESETIMPORTER"/> <int value="1776" label="SMARTCARDPROVIDERPRIVATE_REPORTCANCELRESULT"/> + <int value="1777" label="RUNTIME_GETCONTEXTS"/> </enum> <enum name="ExtensionIconState"> @@ -58126,6 +58129,8 @@ <int value="-1940806558" label="enable-syncfs-directory-operation"/> <int value="-1940377152" label="MacRTL:enabled"/> <int value="-1940291343" label="SpeculativeResourcePrefetching:enabled"/> + <int value="-1940251540" + label="AutofillEnableEmailOtpForVcnYellowPath:enabled"/> <int value="-1939525844" label="AssistantTimersV2:enabled"/> <int value="-1939016096" label="OmniboxUIExperimentHideSuggestionUrlTrivialSubdomains:enabled"/> @@ -61188,6 +61193,7 @@ <int value="-271084069" label="ClickToCallUI:enabled"/> <int value="-270626757" label="log-net-log"/> <int value="-270261701" label="WebRtcEnableCaptureMultiChannelApm:disabled"/> + <int value="-270124279" label="GetTheMostOutOfChrome:enabled"/> <int value="-269966631" label="UnifiedPasswordManagerErrorMessages:enabled"/> <int value="-269440655" label="AutofillDownstreamCvcPromptUseGooglePayLogo:disabled"/> @@ -61321,6 +61327,8 @@ <int value="-185162926" label="IncreaseInputAudioBufferSize:enabled"/> <int value="-184091779" label="OmniboxUIExperimentWhiteBackgroundOnBlur:enabled"/> + <int value="-183541827" + label="AutofillEnableEmailOtpForVcnYellowPath:disabled"/> <int value="-183246373" label="enable-multilingual-spellchecker"/> <int value="-181590721" label="AutofillEnforceMinRequiredFieldsForHeuristics:enabled"/> @@ -64606,6 +64614,7 @@ <int value="1637615389" label="PrintServerScaling:enabled"/> <int value="1638123293" label="DeprecateAltClick:disabled"/> <int value="1638582559" label="UpdatedCellularActivationUi:disabled"/> + <int value="1638617234" label="GetTheMostOutOfChrome:disabled"/> <int value="1638927687" label="AutofillRichMetadataQueries:disabled"/> <int value="1639190590" label="UseMessagesGoogleComDomain:enabled"/> <int value="1639314588" label="LookalikeUrlNavigationSuggestions:disabled"/>
diff --git a/tools/metrics/histograms/metadata/ash/histograms.xml b/tools/metrics/histograms/metadata/ash/histograms.xml index 79d7e614..02c27e2 100644 --- a/tools/metrics/histograms/metadata/ash/histograms.xml +++ b/tools/metrics/histograms/metadata/ash/histograms.xml
@@ -3585,7 +3585,7 @@ <histogram name="Ash.NavigationWidget.AnimationSmoothness{HotseatTransitionType}" - units="%" expires_after="2023-04-20"> + units="%" expires_after="2024-03-27"> <owner>anasalazar@chromium.org</owner> <owner>newcomer@chromium.org</owner> <summary> @@ -3601,7 +3601,7 @@ <histogram name="Ash.NavigationWidget.{NavigationWidgetElement}AnimationSmoothness" - units="%" expires_after="2023-04-20"> + units="%" expires_after="2024-03-27"> <owner>anasalazar@chromium.org</owner> <owner>newcomer@chromium.org</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/chromeos/histograms.xml b/tools/metrics/histograms/metadata/chromeos/histograms.xml index 5e8ddfee..dbe7ce6 100644 --- a/tools/metrics/histograms/metadata/chromeos/histograms.xml +++ b/tools/metrics/histograms/metadata/chromeos/histograms.xml
@@ -66,7 +66,7 @@ <owner>chromeos-tango@google.com</owner> </variant> <variant name="FastPair" summary="Fast Pair"> - <owner>shanefitz@google.com</owner> + <owner>jackshira@google.com</owner> <owner>julietlevesque@google.com</owner> <owner>chromeos-cross-device-eng@google.com</owner> </variant> @@ -1139,7 +1139,7 @@ </histogram> <histogram name="ChromeOS.FeatureUsage.{FeatureName}" enum="FeatureUsageEvent" - expires_after="2023-05-11"> + expires_after="2024-04-01"> <owner>rsorokin@chromium.org</owner> <owner>cros-oac@google.com</owner> <summary> @@ -1151,7 +1151,7 @@ </histogram> <histogram name="ChromeOS.FeatureUsage.{FeatureName}.Usetime" units="ms" - expires_after="2023-05-11"> + expires_after="2024-04-01"> <owner>rsorokin@chromium.org</owner> <owner>cros-oac@google.com</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/cras/histograms.xml b/tools/metrics/histograms/metadata/cras/histograms.xml index 0d450a0..aeb15df 100644 --- a/tools/metrics/histograms/metadata/cras/histograms.xml +++ b/tools/metrics/histograms/metadata/cras/histograms.xml
@@ -390,6 +390,14 @@ <summary>Records the source of a change to the input gain.</summary> </histogram> +<histogram name="Cras.InputGainMutedSource" enum="AudioSettingsChangeSource" + expires_after="2024-02-14"> + <owner>gavinwill@chromium.org</owner> + <owner>yuhsuan@chromium.org</owner> + <owner>chromeos-audio@google.com</owner> + <summary>Records the source of muting/unmuting the input gain.</summary> +</histogram> + <histogram name="Cras.kHfpWidebandSpeechSelectedCodec" enum="CrasHfpCodec" expires_after="2022-12-01"> <owner>hychao@chromium.org</owner> @@ -503,6 +511,14 @@ <summary>Records the source of a change to the output volume.</summary> </histogram> +<histogram name="Cras.OutputVolumeMutedSource" enum="AudioSettingsChangeSource" + expires_after="2024-02-14"> + <owner>gavinwill@chromium.org</owner> + <owner>yuhsuan@chromium.org</owner> + <owner>chromeos-audio@google.com</owner> + <summary>Records the source of muting/unmuting the output volume.</summary> +</histogram> + <histogram name="Cras.RtcDevicePair" enum="CrasDevicePair" expires_after="2023-08-08"> <owner>yuhsuan@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/input/histograms.xml b/tools/metrics/histograms/metadata/input/histograms.xml index e22b7441..0a25f3fa 100644 --- a/tools/metrics/histograms/metadata/input/histograms.xml +++ b/tools/metrics/histograms/metadata/input/histograms.xml
@@ -1724,6 +1724,9 @@ <histogram name="Viewport.DidScalePage" enum="BooleanDidScalePage" expires_after="M108"> + <obsolete> + Removed in M108. + </obsolete> <owner>bokan@chromium.org</owner> <owner>input-dev@chromium.org</owner> <summary> @@ -1736,6 +1739,9 @@ <histogram name="Viewport.MaxPageScale" enum="PageScaleFactorRange" expires_after="M108"> + <obsolete> + Removed in M108. + </obsolete> <owner>bokan@chromium.org</owner> <owner>input-dev@chromium.org</owner> <summary> @@ -1749,7 +1755,7 @@ </histogram> <histogram name="Viewport.MetaTagType" enum="MetaTagTypeEnum" - expires_after="M108"> + expires_after="2024-03-23"> <owner>bokan@chromium.org</owner> <owner>input-dev@chromium.org</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/memory/histograms.xml b/tools/metrics/histograms/metadata/memory/histograms.xml index bb8b5a4c..aeb8adc 100644 --- a/tools/metrics/histograms/metadata/memory/histograms.xml +++ b/tools/metrics/histograms/metadata/memory/histograms.xml
@@ -524,6 +524,31 @@ </summary> </histogram> +<histogram name="Memory.Experimental.AvailableMemoryMB" units="MB" + expires_after="2023-09-22"> + <owner>anthonyvd@chromium.org</owner> + <owner>catan-team@chromium.org</owner> + <summary> + The amount of available physical memory on the system as reported by + base::SysInfo::AmountOfAvailablePhysicalMemory(). + + Recorded every 2 minutes. + </summary> +</histogram> + +<histogram name="Memory.Experimental.AvailableMemoryPercent" units="%" + expires_after="2023-09-22"> + <owner>anthonyvd@chromium.org</owner> + <owner>catan-team@chromium.org</owner> + <summary> + The percentage of physical memory on the system considered + "available" by base::SysInfo::AmountOfAvailablePhysicalMemory() + and base::SysInfo::AmountOfPhysicalMemory(). + + Recorded every 2 minutes. + </summary> +</histogram> + <histogram base="true" name="Memory.Experimental.Browser2" units="MB" expires_after="2024-01-10"> <!-- Name completed by histogram_suffixes name="ProcessMemoryAllocator2" -->
diff --git a/tools/metrics/histograms/metadata/new_tab_page/histograms.xml b/tools/metrics/histograms/metadata/new_tab_page/histograms.xml index 8c82c59..f919a07 100644 --- a/tools/metrics/histograms/metadata/new_tab_page/histograms.xml +++ b/tools/metrics/histograms/metadata/new_tab_page/histograms.xml
@@ -2205,29 +2205,6 @@ </summary> </histogram> -<histogram name="NewTabPage.UserClassifier.AverageHoursToOpenNTP" units="hours" - expires_after="2021-09-05"> - <owner>freedjm@chromium.org</owner> - <owner>feed@chromium.org</owner> - <summary> - Android: The estimated average number of hours between two successive times - when a new tab page is opened. Recorded after each opening of a NTP (and - after updating the model used for the estimate). - </summary> -</histogram> - -<histogram name="NewTabPage.UserClassifier.AverageHoursToShowSuggestions" - units="hours" expires_after="2021-09-05"> - <owner>freedjm@chromium.org</owner> - <owner>feed@chromium.org</owner> - <summary> - Android: The estimated average number of hours between two successive times - when the list of content suggestions on a new tab page is shown (i.e. when - the user scrolls below the fold). Recorded after each time the suggestions - are shown (and after updating the model used for the estimate). - </summary> -</histogram> - <histogram name="NewTabPage.UserClassifier.AverageHoursToUseSuggestions" units="hours" expires_after="2022-01-09"> <owner>freedjm@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/optimization/histograms.xml b/tools/metrics/histograms/metadata/optimization/histograms.xml index c0736a79..7bee9a25 100644 --- a/tools/metrics/histograms/metadata/optimization/histograms.xml +++ b/tools/metrics/histograms/metadata/optimization/histograms.xml
@@ -612,7 +612,7 @@ </histogram> <histogram name="OptimizationGuide.OptimizationHintsComponent.MajorVersion" - units="major version number" expires_after="2023-05-07"> + units="major version number" expires_after="M117"> <owner>sophiechang@chromium.org</owner> <owner>mcrouse@chromium.org</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/power/histograms.xml b/tools/metrics/histograms/metadata/power/histograms.xml index b36b514..6a0c172 100644 --- a/tools/metrics/histograms/metadata/power/histograms.xml +++ b/tools/metrics/histograms/metadata/power/histograms.xml
@@ -633,7 +633,7 @@ </histogram> <histogram name="Power.AdaptiveChargingMinutes.{ReportType}" units="minutes" - expires_after="2023-03-19"> + expires_after="2024-03-23"> <owner>dbasehore@chromium.org</owner> <owner>chromeos-platform-power@google.com</owner> <summary> @@ -2294,7 +2294,7 @@ </histogram> <histogram name="Power.ShutdownReason" enum="ShutdownReason" - expires_after="M85"> + expires_after="2024-03-23"> <owner>tbroch@chromium.org</owner> <summary> The reason for the Chrome OS power manager shutting down or rebooting the @@ -2369,7 +2369,7 @@ </histogram> <histogram name="Power.TimeInSuspendAtBoot" units="minutes" - expires_after="2021-03-15"> + expires_after="2024-03-23"> <owner>tbroch@chromium.org</owner> <summary> Chrome OS time in minutes spent in suspend-to-RAM mode sampled at boot @@ -2378,7 +2378,7 @@ </histogram> <histogram name="Power.TimeInSuspendAtResume" units="minutes" - expires_after="2021-04-04"> + expires_after="2024-03-23"> <owner>tbroch@chromium.org</owner> <summary> Chrome OS time in minutes spent in suspend-to-RAM mode sampled at resume. @@ -2386,7 +2386,7 @@ </histogram> <histogram name="Power.UserBrightnessAdjustmentsPerSessionOnAC" units="units" - expires_after="2022-05-01"> + expires_after="2024-03-23"> <owner>tbroch@chromium.org</owner> <owner>napper@chromium.org</owner> <summary> @@ -2397,7 +2397,7 @@ </histogram> <histogram name="Power.UserBrightnessAdjustmentsPerSessionOnBattery" - units="units" expires_after="2021-10-25"> + units="units" expires_after="2024-03-23"> <owner>tbroch@chromium.org</owner> <owner>napper@chromium.org</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/safe_browsing/histograms.xml b/tools/metrics/histograms/metadata/safe_browsing/histograms.xml index 44a7ab3..e9950d8 100644 --- a/tools/metrics/histograms/metadata/safe_browsing/histograms.xml +++ b/tools/metrics/histograms/metadata/safe_browsing/histograms.xml
@@ -60,31 +60,6 @@ <variant name="URT" summary="the URL real-time mechanism"/> </variants> -<variants name="MetricsCollectorBypassEventType"> - <variant name="CsdInterstitialBypass" - summary="client-side detection interstitial bypass"/> - <variant name="DangerousDownloadBypass" - summary="dangerous download warning bypass"/> - <variant name="DatabaseInterstitialBypass" - summary="Safe Browsing database interstitial bypass"/> - <variant name="ExtensionAllowlistInstallBypass" - summary="extension allowlist install bypass"/> - <variant name="NonAllowlistedExtensionReEnabled" - summary="non allowlisted extension re-enabled"/> - <variant name="PasswordReuseModalBypass" - summary="password reuse modal warning bypass"/> - <variant name="RealTimeInterstitialBypass" - summary="real time URL check warning bypass"/> -</variants> - -<variants name="MetricsCollectorSecuritySensitiveEventType"> - <variant name="Download" summary="download"/> - <variant name="PasswordProtection" summary="password protection"/> - <variant name="SafeBrowsingInterstitial" - summary="safe browsing interstitial"/> - <variant name="SSLInterstitial" summary="SSL interstitial"/> -</variants> - <variants name="MetricsCollectorTimesDisabledEnabledDuration"> <variant name="LongEnabled" summary="ESB enabled duration was greater than 24 hours"/> @@ -494,35 +469,29 @@ </histogram> <histogram - name="SafeBrowsing.Daily.BypassCountLast28Days.{UserState}.{EventType}" - units="events" expires_after="2024-01-04"> + name="SafeBrowsing.Daily.BypassCountLast28Days.{UserState}.AllEvents" + units="events" expires_after="2024-03-23"> <owner>xinghuilu@chromium.org</owner> <owner>chrome-counter-abuse-alerts@google.com</owner> <summary> - Logs the total number of {EventType} in the last 28 days. Recorded for all + Logs the total number of bypass events in the last 28 days. Recorded for all non-Incognito profiles that are under {UserState} every 24 hours and at startup if the last recording was more than 24 hours ago. </summary> <token key="UserState" variants="MetricsCollectorUserState"/> - <token key="EventType" variants="MetricsCollectorBypassEventType"> - <variant name="AllEvents" summary="any type of events"/> - </token> </histogram> <histogram - name="SafeBrowsing.Daily.SecuritySensitiveCountLast28Days.{UserState}.{EventType}" - units="events" expires_after="2023-03-08"> + name="SafeBrowsing.Daily.SecuritySensitiveCountLast28Days.{UserState}.AllEvents" + units="events" expires_after="2024-03-23"> <owner>xinghuilu@chromium.org</owner> <owner>chrome-counter-abuse-alerts@google.com</owner> <summary> - Logs the total number of security sensitive {EventType} in the last 28 days. + Logs the total number of security sensitive events in the last 28 days. Recorded for all non-Incognito profiles that are under {UserState} every 24 hours and at startup if the last recording was more than 24 hours ago. </summary> <token key="UserState" variants="MetricsCollectorUserState"/> - <token key="EventType" variants="MetricsCollectorSecuritySensitiveEventType"> - <variant name="AllEvents" summary="any type of events"/> - </token> </histogram> <histogram name="SafeBrowsing.DelayedWarnings.Event" @@ -568,35 +537,8 @@ </summary> </histogram> -<histogram name="SafeBrowsing.EsbDisabled.BypassCountLast28Days.{EventType}" - units="events" expires_after="2024-01-04"> - <owner>xinghuilu@chromium.org</owner> - <owner>chrome-counter-abuse-alerts@google.com</owner> - <summary> - Records the total number of {EventType} in the last 28 days. Logged each - time a user disables Enhanced Safe Browsing. Logged at most three times a - week. If ESB is disabled for more than three times a week, later records - will be dropped. - </summary> - <token key="EventType" variants="MetricsCollectorBypassEventType"/> -</histogram> - -<histogram name="SafeBrowsing.EsbDisabled.LastBypassEventInterval.{EventType}" - units="ms" expires_after="2024-01-04"> - <owner>xinghuilu@chromium.org</owner> - <owner>chrome-counter-abuse-alerts@google.com</owner> - <summary> - Records the time between the last bypass event and when the user disables - Enhanced Safe Browsing. Logged each time a user disables Enhanced Safe - Browsing and the {EventType} is the last bypass event type. Logged at most - three times a week. If ESB is disabled for more than three times a week, - later records will be dropped. - </summary> - <token key="EventType" variants="MetricsCollectorBypassEventType"/> -</histogram> - <histogram name="SafeBrowsing.EsbDisabled.LastBypassEventType" - enum="SBMetricsCollectorEventType" expires_after="2023-08-27"> + enum="SBMetricsCollectorEventType" expires_after="2024-03-23"> <owner>xinghuilu@chromium.org</owner> <owner>chrome-counter-abuse-alerts@google.com</owner> <summary> @@ -618,23 +560,8 @@ </summary> </histogram> -<histogram - name="SafeBrowsing.EsbDisabled.LastSecuritySensitiveEventInterval.{EventType}" - units="ms" expires_after="2023-03-08"> - <owner>xinghuilu@chromium.org</owner> - <owner>chrome-counter-abuse-alerts@google.com</owner> - <summary> - Records the time between the last security sensitive event and when the user - disables Enhanced Safe Browsing. Logged each time a user disables Enhanced - Safe Browsing and the {EventType} is the last security sensitive event type. - Logged at most three times a week. If ESB is disabled for more than three - times a week, later records will be dropped. - </summary> - <token key="EventType" variants="MetricsCollectorSecuritySensitiveEventType"/> -</histogram> - <histogram name="SafeBrowsing.EsbDisabled.LastSecuritySensitiveEventType" - enum="SBMetricsCollectorEventType" expires_after="2023-03-08"> + enum="SBMetricsCollectorEventType" expires_after="2024-03-23"> <owner>xinghuilu@chromium.org</owner> <owner>chrome-counter-abuse-alerts@google.com</owner> <summary> @@ -645,20 +572,6 @@ </histogram> <histogram - name="SafeBrowsing.EsbDisabled.SecuritySensitiveCountLast28Days.{EventType}" - units="events" expires_after="2023-03-08"> - <owner>xinghuilu@chromium.org</owner> - <owner>chrome-counter-abuse-alerts@google.com</owner> - <summary> - Records the total number of {EventType} in the last 28 days. Logged each - time a user disables Enhanced Safe Browsing. Logged at most three times a - week. If ESB is disabled for more than three times a week, later records - will be dropped. - </summary> - <token key="EventType" variants="MetricsCollectorSecuritySensitiveEventType"/> -</histogram> - -<histogram name="SafeBrowsing.EsbDisabled.TimesDisabledLast28Days.{EnabledDuration}" units="times" expires_after="2023-08-28"> <owner>thefrog@chromium.org</owner> @@ -1411,16 +1324,6 @@ </summary> </histogram> -<histogram name="SafeBrowsing.MetricsCollector.IsPrefValid" enum="BooleanValid" - expires_after="2023-08-20"> - <owner>xinghuilu@chromium.org</owner> - <owner>chrome-counter-abuse-alerts@google.com</owner> - <summary> - Records whether the pref for storing Safe Browsing events is valid. This is - logged each time old events are removed. It is logged daily. - </summary> -</histogram> - <histogram name="SafeBrowsing.NavigationObserver.MissingInitiatorRenderFrameHostPortal" enum="BooleanExists" expires_after="2023-04-23">
diff --git a/tools/rust/build_rust.py b/tools/rust/build_rust.py index da5f66b..28df06e 100755 --- a/tools/rust/build_rust.py +++ b/tools/rust/build_rust.py
@@ -63,18 +63,25 @@ VERSION_STAMP_PATH, GetPackageVersionForBuild) EXCLUDED_TESTS = [ - # Temporarily disabled due to https://github.com/rust-lang/rust/issues/94322 - os.path.join('tests', 'ui', 'numeric', 'numeric-cast.rs'), - # Temporarily disabled due to https://github.com/rust-lang/rust/issues/96497 + # https://github.com/rust-lang/rust/issues/45222 which appears to have + # regressed as of a recent LLVM update. This test is purely performance + # related, not correctness. + os.path.join('tests', 'codegen', 'issue-45222.rs'), + # https://github.com/rust-lang/rust/issues/96497 os.path.join('tests', 'codegen', 'issue-96497-slice-size-nowrap.rs'), # TODO(crbug.com/1347563): Re-enable when fixed. os.path.join('tests', 'codegen', 'sanitizer-cfi-emit-type-checks.rs'), os.path.join('tests', 'codegen', 'sanitizer-cfi-emit-type-metadata-itanium-cxx-abi.rs'), - # Temporarily disabled due to https://github.com/rust-lang/rust/issues/45222 - # which appears to have regressed as of a recent LLVM update. This test is - # purely performance related, not correctness. - os.path.join('tests', 'codegen', 'issue-45222.rs') + # https://github.com/rust-lang/rust/issues/109671 the test is being + # optimized in newer LLVM which breaks its expectations. + os.path.join('tests', 'ui', 'abi', 'stack-protector.rs'), + # https://github.com/rust-lang/rust/issues/109672 the second panic in a + # double-panic is being optimized out (reasonably correctly) by newer LLVM. + os.path.join('tests', 'ui', 'backtrace.rs'), + # https://github.com/rust-lang/rust/issues/94322 large output from + # compiletests is breaking json parsing of the results. + os.path.join('tests', 'ui', 'numeric', 'numeric-cast.rs'), ] EXCLUDED_TESTS_WINDOWS = [ # https://github.com/rust-lang/rust/issues/96464
diff --git a/tools/visual_debugger/connection.js b/tools/visual_debugger/connection.js index c374c50..26e90980 100644 --- a/tools/visual_debugger/connection.js +++ b/tools/visual_debugger/connection.js
@@ -8,52 +8,51 @@ const Connection = { - getUrl() { - var request_error = ""; - var server_error = ""; - var url = ""; - url = document.querySelector('#url').value; - if (!url) { - var http_requester = new XMLHttpRequest(); - // Sync request to avoid complexity but is poor form. - try { - http_requester.open("GET", location.origin + '/discover.html', false); - http_requester.send(); - } - catch (req_error) { - request_error = "Visual Debugger local server is inaccessible. \n" + - "Please launch the server with command:\n " + - " ./launchdebugger {app_port} {remote_port} \n" + - " remote_port defaults to 7777 \n" + - " corresponds to the chromium command line\n " + - " --remote-debugging-port=7777 \n" + - " app_port defaults to 8777. Currently app_port=" + location.port; - } - - if (http_requester.status != 200) { - server_error = "Server reports error=" + http_requester.responseText; - } - else { - var discover_json = JSON.parse(http_requester.responseText); - url = discover_json.webSocketDebuggerUrl; - } + async getUrl() { + let url = document.querySelector("#url").value; + if (url) { + return [url, ""]; } - const return_strings = [url, request_error, server_error]; - return return_strings; + + try { + let response = await fetch(location.origin + "/discover.json"); + if (!response.ok) { + return [ + "", + `Unexpected server error=${response.status} ${response.statusText}`, + ]; + } else { + let discover_json = await response.json(); + if (discover_json.error) { + // Error message from the python server + return ["", discover_json.error]; + } + + // Success + return [discover_json.webSocketDebuggerUrl, ""]; + } + } catch (e) { + request_error = + "Visual Debugger local server is inaccessible. \n" + + "Please launch the server with command:\n " + + " ./launchdebugger {app_port} {remote_port} \n" + + " remote_port defaults to 7777 \n" + + " corresponds to the chromium command line\n " + + " --remote-debugging-port=7777 \n" + + " app_port defaults to 8777. Currently app_port=" + + location.port; + return ["", request_error]; + } }, - startConnection() { + async startConnection() { const loop_interval = 3000; - const connect_info = this.getUrl(); + const connect_info = await this.getUrl(); if (connect_info[1] != "") { window.alert(connect_info[1]); return; } - if (connect_info[2] != "") { - window.alert(connect_info[2]); - return; - } url = connect_info[0]; // Create WebSocket connection. @@ -111,18 +110,28 @@ status.classList.add('disconnected'); // Checks if connection can be made every // loop_interval number of milliseconds. - var testing = function() { - var interval = setInterval(function() { - if (document.getElementById('autoconnect').checked) { - const test_connect = Connection.getUrl(); - if (test_connect[0] != "") { - clearInterval(interval); - Connection.startConnection(); - } + let retryAfterDelay = () => { + setTimeout(() => { + if (!document.getElementById("autoconnect").checked) { + // Keep this setTimeout loop alive in case the user re-checks the + // box. + retryAfterDelay(); + return; } + + console.log("Attempting autoconnect..."); + Connection.getUrl().then((test_connect) => { + if (test_connect[0] != "") { + Connection.startConnection(); + } else { + // Failure, queue a retry. + retryAfterDelay(); + } + }); }, loop_interval); - } - testing(); + }; + + retryAfterDelay(); }); disconnect.addEventListener('click', () => {
diff --git a/tools/visual_debugger/server.py b/tools/visual_debugger/server.py index 4f9206ae..f5e8a56 100755 --- a/tools/visual_debugger/server.py +++ b/tools/visual_debugger/server.py
@@ -3,6 +3,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +import json import sys if (sys.version_info < (3, )): @@ -23,29 +24,31 @@ class CORSRequestHandler(SimpleHTTPRequestHandler): def do_GET(self): - if (self.path == "/discover.html"): + if (self.path == "/discover.json"): + remote_discovery_url = "http://localhost:{remote_port}/json/version".format( + remote_port=remote_port) try: - contents = urllib.request.urlopen("http://localhost:" + - str(remote_port) + - "/json/version").read() - self.send_response(200) + contents = urllib.request.urlopen(remote_discovery_url).read() except Exception: - contents =\ - "\n Cannot connect to remote discovery page on localhost:"+\ - str(remote_port) +\ - "\n check for target command line parameter: \n" +\ - " --remote-debugging-port=" + str(remote_port) +\ - "\n and if the target is a remote DUT tunnel forwarding"+\ - " is required from local to remote : " + \ - "\n ssh root@$DUT_IP -L " + \ - str(remote_port)+":localhost:" + str(remote_port) + output = { + "error": + '''\ +Cannot connect to remote discovery page on: + {remote_discovery_url} +Check for target command line parameter: + --remote-debugging-port={remote_port} +If the target is a remote DUT tunnel forwarding is required +from local to remote: + ssh root@$DUT_IP -L {remote_port}:localhost:{remote_port} + '''.format(remote_port=remote_port, + remote_discovery_url=remote_discovery_url) + } + contents = json.dumps(output) contents = bytes(contents, 'UTF-8') - # Used error code 206 to prevent console logs every time - # connection is unsuccessful. - self.send_response(206) - self.send_header("Content-type", "text/html") + self.send_response(200) + self.send_header("Content-type", "application/json") self.send_header("Content-length", len(contents)) self.end_headers() self.wfile.write(contents)
diff --git a/tools/vscode/settings.json b/tools/vscode/settings.json index c0a3f54..98488b95 100644 --- a/tools/vscode/settings.json +++ b/tools/vscode/settings.json
@@ -11,6 +11,16 @@ "editor.detectIndentation": false, // Add a line at 80 characters. "editor.rulers": [80], + + "extensions": { + "recommendations": [ + // The GN language server from Microsoft. + // + // Provides support for .gn and .gni files. + "msedge-dev.gnls", + ], + }, + // Forces LF instead of "auto" which uses CRLF on Windows. "files.eol": "\n", // Trim tailing whitespace on save. @@ -22,12 +32,6 @@ "files.associations": { // Adds xml syntax highlighting for grd files. "*.grd" : "xml", - // Optional: .gn and .gni are not JavaScript, but at least it gives some - // approximate syntax highlighting. Ignore the linter warnings! - // There's an extension for these files, excluding the linter headaches. - // https://marketplace.visualstudio.com/items?itemName=npclaudiu.vscode-gn - "*.gni" : "javascript", - "*.gn" : "javascript" }, "files.exclude": {
diff --git a/ui/android/javatests/src/org/chromium/ui/test/util/DisableAnimationsTestRule.java b/ui/android/javatests/src/org/chromium/ui/test/util/DisableAnimationsTestRule.java index 6392e49..6819ca9 100644 --- a/ui/android/javatests/src/org/chromium/ui/test/util/DisableAnimationsTestRule.java +++ b/ui/android/javatests/src/org/chromium/ui/test/util/DisableAnimationsTestRule.java
@@ -7,6 +7,7 @@ import android.os.Build; import android.os.IBinder; import android.provider.Settings; +import android.support.test.InstrumentationRegistry; import org.junit.rules.TestRule; import org.junit.runner.Description; @@ -115,7 +116,8 @@ "settings put global transition_animation_scale " + scaleFactor, "settings put global window_animation_scale " + scaleFactor); for (String command : commandToRuns) { - Runtime.getRuntime().exec(command); + InstrumentationRegistry.getInstrumentation().getUiAutomation().executeShellCommand( + command); } } else { // Set animation scales through reflection in R-.
diff --git a/ui/base/ime/fuchsia/BUILD.gn b/ui/base/ime/fuchsia/BUILD.gn index 1fc9873f..db19f4e 100644 --- a/ui/base/ime/fuchsia/BUILD.gn +++ b/ui/base/ime/fuchsia/BUILD.gn
@@ -22,7 +22,7 @@ "//base", "//third_party/abseil-cpp:absl", "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.input.virtualkeyboard:fuchsia.input.virtualkeyboard_hlcpp", - "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.ui.input3:fuchsia.ui.input3_cpp", + "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.ui.input3:fuchsia.ui.input3_hlcpp", "//third_party/fuchsia-sdk/sdk/pkg/scenic_cpp", "//third_party/fuchsia-sdk/sdk/pkg/sys_cpp", "//ui/base/ime",
diff --git a/ui/base/ime/fuchsia/keyboard_client.cc b/ui/base/ime/fuchsia/keyboard_client.cc index fa04d03..4ee5911 100644 --- a/ui/base/ime/fuchsia/keyboard_client.cc +++ b/ui/base/ime/fuchsia/keyboard_client.cc
@@ -4,15 +4,13 @@ #include "ui/base/ime/fuchsia/keyboard_client.h" -#include <lib/async/default.h> - #include <limits> #include <tuple> #include <utility> -#include "base/fuchsia/fuchsia_logging.h" #include "base/logging.h" #include "base/notreached.h" +#include "third_party/abseil-cpp/absl/types/optional.h" #include "ui/events/event.h" #include "ui/events/fuchsia/input_event_sink.h" #include "ui/events/keycodes/dom/dom_code.h" @@ -26,10 +24,10 @@ // Adds `flag` to `event_flags` if `modifier` is present. Also removes handled // modifiers from `unhandled_modifiers`. -inline void MaybeAddFlag(fuchsia_ui_input3::Modifiers modifier, +inline void MaybeAddFlag(fuchsia::ui::input3::Modifiers modifier, EventFlags flag, EventFlags& event_flags, - fuchsia_ui_input3::Modifiers& unhandled_modifiers) { + fuchsia::ui::input3::Modifiers& unhandled_modifiers) { if (unhandled_modifiers & modifier) { event_flags |= flag; // Remove modifier from unhandled. @@ -39,72 +37,72 @@ // Converts the state of modifiers managed by Fuchsia (e.g. Caps and Num Lock) // into ui::Event flags. -int ModifiersToEventFlags(fuchsia_ui_input3::Modifiers modifiers) { +int ModifiersToEventFlags(fuchsia::ui::input3::Modifiers modifiers) { EventFlags event_flags = EF_NONE; - MaybeAddFlag(fuchsia_ui_input3::Modifiers::kCapsLock, EF_CAPS_LOCK_ON, + MaybeAddFlag(fuchsia::ui::input3::Modifiers::CAPS_LOCK, EF_CAPS_LOCK_ON, event_flags, modifiers); - MaybeAddFlag(fuchsia_ui_input3::Modifiers::kNumLock, EF_NUM_LOCK_ON, + MaybeAddFlag(fuchsia::ui::input3::Modifiers::NUM_LOCK, EF_NUM_LOCK_ON, event_flags, modifiers); - MaybeAddFlag(fuchsia_ui_input3::Modifiers::kScrollLock, EF_SCROLL_LOCK_ON, + MaybeAddFlag(fuchsia::ui::input3::Modifiers::SCROLL_LOCK, EF_SCROLL_LOCK_ON, event_flags, modifiers); // This mapping is present in case blink adds support in the future, but blink // doesn't currently output the Function modifier. See // https://crsrc.org/c/ui/events/blink/blink_event_util.cc;l=268?q=EventFlagsToWebEventModifiers - MaybeAddFlag(fuchsia_ui_input3::Modifiers::kFunction, EF_FUNCTION_DOWN, + MaybeAddFlag(fuchsia::ui::input3::Modifiers::FUNCTION, EF_FUNCTION_DOWN, event_flags, modifiers); - if (modifiers & fuchsia_ui_input3::Modifiers::kSymbol) { - // fuchsia_ui_input3::Modifiers::SYMBOL has no equivalent in + if (modifiers & fuchsia::ui::input3::Modifiers::SYMBOL) { + // fuchsia::ui::input3::Modifiers::SYMBOL has no equivalent in // //ui/events/event_constants.h. DLOG(WARNING) << "Ignoring unsupported Symbol modifier."; - modifiers &= ~fuchsia_ui_input3::Modifiers::kSymbol; + modifiers &= ~fuchsia::ui::input3::Modifiers::SYMBOL; } - MaybeAddFlag(fuchsia_ui_input3::Modifiers::kShift, EF_SHIFT_DOWN, event_flags, - modifiers); - if (modifiers & (fuchsia_ui_input3::Modifiers::kLeftShift | - fuchsia_ui_input3::Modifiers::kRightShift)) { + MaybeAddFlag(fuchsia::ui::input3::Modifiers::SHIFT, EF_SHIFT_DOWN, + event_flags, modifiers); + if (modifiers & (fuchsia::ui::input3::Modifiers::LEFT_SHIFT | + fuchsia::ui::input3::Modifiers::RIGHT_SHIFT)) { DCHECK(event_flags & EF_SHIFT_DOWN) << "Fuchsia is expected to provide an agnostic SHIFT modifier for both " "LEFT and RIGHT SHIFT"; - modifiers &= ~fuchsia_ui_input3::Modifiers::kLeftShift & - ~fuchsia_ui_input3::Modifiers::kRightShift; + modifiers &= ~fuchsia::ui::input3::Modifiers::LEFT_SHIFT & + ~fuchsia::ui::input3::Modifiers::RIGHT_SHIFT; } - MaybeAddFlag(fuchsia_ui_input3::Modifiers::kAlt, EF_ALT_DOWN, event_flags, + MaybeAddFlag(fuchsia::ui::input3::Modifiers::ALT, EF_ALT_DOWN, event_flags, modifiers); - if (modifiers & (fuchsia_ui_input3::Modifiers::kLeftAlt | - fuchsia_ui_input3::Modifiers::kRightAlt)) { + if (modifiers & (fuchsia::ui::input3::Modifiers::LEFT_ALT | + fuchsia::ui::input3::Modifiers::RIGHT_ALT)) { DCHECK(event_flags & EF_ALT_DOWN) << "Fuchsia is expected to provide an agnostic ALT modifier for both " "LEFT and RIGHT ALT"; - modifiers &= ~fuchsia_ui_input3::Modifiers::kLeftAlt & - ~fuchsia_ui_input3::Modifiers::kRightAlt; + modifiers &= ~fuchsia::ui::input3::Modifiers::LEFT_ALT & + ~fuchsia::ui::input3::Modifiers::RIGHT_ALT; } - MaybeAddFlag(fuchsia_ui_input3::Modifiers::kAltGraph, EF_ALTGR_DOWN, + MaybeAddFlag(fuchsia::ui::input3::Modifiers::ALT_GRAPH, EF_ALTGR_DOWN, event_flags, modifiers); - MaybeAddFlag(fuchsia_ui_input3::Modifiers::kMeta, EF_COMMAND_DOWN, + MaybeAddFlag(fuchsia::ui::input3::Modifiers::META, EF_COMMAND_DOWN, event_flags, modifiers); - if (modifiers & (fuchsia_ui_input3::Modifiers::kLeftMeta | - fuchsia_ui_input3::Modifiers::kRightMeta)) { + if (modifiers & (fuchsia::ui::input3::Modifiers::LEFT_META | + fuchsia::ui::input3::Modifiers::RIGHT_META)) { DCHECK(event_flags & EF_COMMAND_DOWN) << "Fuchsia is expected to provide an agnostic META modifier for both " "LEFT and RIGHT META"; - modifiers &= ~fuchsia_ui_input3::Modifiers::kLeftMeta & - ~fuchsia_ui_input3::Modifiers::kRightMeta; + modifiers &= ~fuchsia::ui::input3::Modifiers::LEFT_META & + ~fuchsia::ui::input3::Modifiers::RIGHT_META; } - MaybeAddFlag(fuchsia_ui_input3::Modifiers::kCtrl, EF_CONTROL_DOWN, + MaybeAddFlag(fuchsia::ui::input3::Modifiers::CTRL, EF_CONTROL_DOWN, event_flags, modifiers); - if (modifiers & (fuchsia_ui_input3::Modifiers::kLeftCtrl | - fuchsia_ui_input3::Modifiers::kRightCtrl)) { + if (modifiers & (fuchsia::ui::input3::Modifiers::LEFT_CTRL | + fuchsia::ui::input3::Modifiers::RIGHT_CTRL)) { DCHECK(event_flags & EF_CONTROL_DOWN) << "Fuchsia is expected to provide an agnostic CTRL modifier for both " "LEFT and RIGHT CTRL"; - modifiers &= ~fuchsia_ui_input3::Modifiers::kLeftCtrl & - ~fuchsia_ui_input3::Modifiers::kRightCtrl; + modifiers &= ~fuchsia::ui::input3::Modifiers::LEFT_CTRL & + ~fuchsia::ui::input3::Modifiers::RIGHT_CTRL; } DLOG_IF(WARNING, modifiers) @@ -113,14 +111,14 @@ } absl::optional<EventType> ConvertKeyEventType( - fuchsia_ui_input3::KeyEventType type) { + fuchsia::ui::input3::KeyEventType type) { switch (type) { - case fuchsia_ui_input3::KeyEventType::kPressed: + case fuchsia::ui::input3::KeyEventType::PRESSED: return ET_KEY_PRESSED; - case fuchsia_ui_input3::KeyEventType::kReleased: + case fuchsia::ui::input3::KeyEventType::RELEASED: return ET_KEY_RELEASED; - case fuchsia_ui_input3::KeyEventType::kSync: - case fuchsia_ui_input3::KeyEventType::kCancel: + case fuchsia::ui::input3::KeyEventType::SYNC: + case fuchsia::ui::input3::KeyEventType::CANCEL: // SYNC and CANCEL should not generate ui::Events. return absl::nullopt; default: @@ -132,84 +130,73 @@ } // namespace -KeyboardClient::KeyboardClient( - fidl::Client<fuchsia_ui_input3::Keyboard>& keyboard_fidl_client, - fuchsia_ui_views::ViewRef view_ref, - InputEventSink* event_sink) - : event_sink_(event_sink) { +KeyboardClient::KeyboardClient(fuchsia::ui::input3::Keyboard* keyboard_service, + fuchsia::ui::views::ViewRef view_ref, + InputEventSink* event_sink) + : binding_(this), event_sink_(event_sink) { DCHECK(event_sink_); - // Connect to the Keyboard service and register `keyboard_client_` as a + // Connect to the Keyboard service and register |keyboard_client_| as a // listener. - auto keyboard_listener_endpoints = - fidl::CreateEndpoints<fuchsia_ui_input3::KeyboardListener>(); - ZX_CHECK(keyboard_listener_endpoints.is_ok(), - keyboard_listener_endpoints.status_value()); - keyboard_fidl_client - ->AddListener( - {{.view_ref = std::move(view_ref), - .listener = std::move(keyboard_listener_endpoints->client)}}) - .ThenExactlyOnce([](auto result) {}); - binding_.emplace(async_get_default_dispatcher(), - std::move(keyboard_listener_endpoints->server), this, - fidl::kIgnoreBindingClosure); + fidl::InterfaceHandle<fuchsia::ui::input3::KeyboardListener> + keyboard_listener; + fidl::InterfaceRequest<fuchsia::ui::input3::KeyboardListener> + keyboard_listener_request = keyboard_listener.NewRequest(); + keyboard_service->AddListener(std::move(view_ref), + std::move(keyboard_listener), [] {}); + binding_.Bind(std::move(keyboard_listener_request)); } KeyboardClient::~KeyboardClient() = default; void KeyboardClient::OnKeyEvent( - KeyboardClient::OnKeyEventRequest& request, - KeyboardClient::OnKeyEventCompleter::Sync& completer) { - if (!IsValid(request.event())) { - binding_->Close(ZX_ERR_INVALID_ARGS); + fuchsia::ui::input3::KeyEvent key_event, + fuchsia::ui::input3::KeyboardListener::OnKeyEventCallback callback) { + if (!IsValid(key_event)) { + binding_.Close(ZX_ERR_INVALID_ARGS); return; } - if (ProcessKeyEvent(request.event())) { - completer.Reply(fuchsia_ui_input3::KeyEventStatus::kHandled); + if (ProcessKeyEvent(key_event)) { + callback(fuchsia::ui::input3::KeyEventStatus::HANDLED); } else { - completer.Reply(fuchsia_ui_input3::KeyEventStatus::kNotHandled); + callback(fuchsia::ui::input3::KeyEventStatus::NOT_HANDLED); } } -bool KeyboardClient::IsValid(const fuchsia_ui_input3::KeyEvent& key_event) { - if (!key_event.type() || !key_event.timestamp()) { +bool KeyboardClient::IsValid(const fuchsia::ui::input3::KeyEvent& key_event) { + if (!key_event.has_type() || !key_event.has_timestamp()) return false; - } - if (!key_event.key() && !key_event.key_meaning()) { + if (!key_event.has_key() && !key_event.has_key_meaning()) return false; - } return true; } bool KeyboardClient::ProcessKeyEvent( - const fuchsia_ui_input3::KeyEvent& key_event) { - absl::optional<EventType> event_type = - ConvertKeyEventType(key_event.type().value()); + const fuchsia::ui::input3::KeyEvent& key_event) { + absl::optional<EventType> event_type = ConvertKeyEventType(key_event.type()); if (!event_type) return false; - // Convert `key_event` to a ui::KeyEvent. + // Convert |key_event| to a ui::KeyEvent. int event_flags = EF_NONE; - if (key_event.modifiers()) { - event_flags |= ModifiersToEventFlags(key_event.modifiers().value()); - } - if (key_event.repeat_sequence()) { + if (key_event.has_modifiers()) + event_flags |= ModifiersToEventFlags(key_event.modifiers()); + if (key_event.has_repeat_sequence()) { event_flags |= EF_IS_REPEAT; } // Derive the DOM Key and Code directly from the event's fields. - // `key_event` has already been validated, so is guaranteed to have one - // or both of the `key` or `key_meaning` fields set. + // |key_event| has already been validated, so is guaranteed to have one + // or both of the |key| or |key_meaning| fields set. DomCode dom_code = DomCode::NONE; DomKey dom_key = DomKey::UNIDENTIFIED; KeyboardCode key_code = VKEY_UNKNOWN; - if (key_event.key()) { - dom_code = KeycodeConverter::UsbKeycodeToDomCode( - static_cast<uint32_t>(key_event.key().value())); + if (key_event.has_key()) { + dom_code = KeycodeConverter::UsbKeycodeToDomCode(key_event.key()); // Derive the legacy key_code. At present this only takes into account the // DOM Code, and event flags, so requires that key() be set. @@ -221,26 +208,26 @@ DomCodeToUsLayoutDomKey(dom_code, event_flags, &dom_key, &key_code); } - if (key_event.key_meaning()) { + if (key_event.has_key_meaning()) { // If the KeyMeaning is specified then use it to set the DOM Key. // Ignore events with codepoints outside the Basic Multilingual Plane, // since the Chromium keyboard pipeline cannot currently handle them. - if (key_event.key_meaning()->codepoint() && - (key_event.key_meaning()->codepoint().value() > + if (key_event.key_meaning().is_codepoint() && + (key_event.key_meaning().codepoint() > std::numeric_limits<char16_t>::max())) { return false; } DomKey dom_key_from_meaning = - DomKeyFromFuchsiaKeyMeaning(key_event.key_meaning().value()); + DomKeyFromFuchsiaKeyMeaning(key_event.key_meaning()); if (dom_key_from_meaning != DomKey::UNIDENTIFIED) dom_key = dom_key_from_meaning; } ui::KeyEvent converted_event( *event_type, key_code, dom_code, event_flags, dom_key, - base::TimeTicks::FromZxTime(key_event.timestamp().value())); + base::TimeTicks::FromZxTime(key_event.timestamp())); event_sink_->DispatchEvent(&converted_event); return converted_event.handled(); }
diff --git a/ui/base/ime/fuchsia/keyboard_client.h b/ui/base/ime/fuchsia/keyboard_client.h index ab07857..8e27ead8 100644 --- a/ui/base/ime/fuchsia/keyboard_client.h +++ b/ui/base/ime/fuchsia/keyboard_client.h
@@ -5,11 +5,10 @@ #ifndef UI_BASE_IME_FUCHSIA_KEYBOARD_CLIENT_H_ #define UI_BASE_IME_FUCHSIA_KEYBOARD_CLIENT_H_ -#include <fidl/fuchsia.ui.input3/cpp/fidl.h> +#include <fuchsia/ui/input3/cpp/fidl.h> #include <lib/fidl/cpp/binding.h> #include "base/component_export.h" -#include "third_party/abseil-cpp/absl/types/optional.h" namespace ui { @@ -17,41 +16,40 @@ // Handles keyboard events from the Fuchsia keyboard service. class COMPONENT_EXPORT(UI_BASE_IME_FUCHSIA) KeyboardClient - : public fidl::Server<fuchsia_ui_input3::KeyboardListener> { + : public fuchsia::ui::input3::KeyboardListener { public: - // `keyboard_service` and `event_sink` must outlive `this`. - KeyboardClient( - fidl::Client<fuchsia_ui_input3::Keyboard>& keyboard_fidl_client, - fuchsia_ui_views::ViewRef view_ref, - InputEventSink* event_sink); + // |keyboard_service| and |event_sink| must outlive |this|. + KeyboardClient(fuchsia::ui::input3::Keyboard* keyboard_service, + fuchsia::ui::views::ViewRef view_ref, + InputEventSink* event_sink); ~KeyboardClient() override; KeyboardClient(const KeyboardClient&) = delete; KeyboardClient& operator=(const KeyboardClient&) = delete; - // fuchsia_ui_input3::KeyboardListener implementation. - void OnKeyEvent(OnKeyEventRequest& request, - OnKeyEventCompleter::Sync& completer) final; + // fuchsia::ui::input3::KeyboardListener implementation. + void OnKeyEvent( + fuchsia::ui::input3::KeyEvent key_event, + fuchsia::ui::input3::KeyboardListener::OnKeyEventCallback callback) final; private: - bool IsValid(const fuchsia_ui_input3::KeyEvent& key_event); + bool IsValid(const fuchsia::ui::input3::KeyEvent& key_event); - // Handles converting and propagating `key_event`. Returns false if critical - // information about `key_event` is missing, or if the key's event type is not + // Handles converting and propagating |key_event|. Returns false if critical + // information about |key_event| is missing, or if the key's event type is not // supported. // TODO(http://fxbug.dev/69620): Add support for SYNC and CANCEL key event // types. - bool ProcessKeyEvent(const fuchsia_ui_input3::KeyEvent& key_event); + bool ProcessKeyEvent(const fuchsia::ui::input3::KeyEvent& key_event); // Update the value of modifiers such as shift. - void UpdateCachedModifiers(const fuchsia_ui_input3::KeyEvent& key_event); + void UpdateCachedModifiers(const fuchsia::ui::input3::KeyEvent& key_event); // Translate state of locally tracked modifier keys (e.g. shift, alt) into // ui::Event flags. int EventFlagsForCachedModifiers(); - absl::optional<fidl::ServerBinding<fuchsia_ui_input3::KeyboardListener>> - binding_; + fidl::Binding<fuchsia::ui::input3::KeyboardListener> binding_; // Dispatches events into Chromium once they have been converted to // ui::KeyEvents.
diff --git a/ui/events/BUILD.gn b/ui/events/BUILD.gn index 7a99006..af2d65ca 100644 --- a/ui/events/BUILD.gn +++ b/ui/events/BUILD.gn
@@ -166,7 +166,7 @@ "keycodes/keyboard_code_conversion_fuchsia.h", ] - deps += [ "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.ui.input3:fuchsia.ui.input3_cpp" ] + deps += [ "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.ui.input3:fuchsia.ui.input3_hlcpp" ] } if (ozone_platform_x11) { @@ -734,7 +734,7 @@ deps += [ "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.ui.input:fuchsia.ui.input_hlcpp", - "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.ui.input3:fuchsia.ui.input3_cpp", + "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.ui.input3:fuchsia.ui.input3_hlcpp", "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.ui.pointer:fuchsia.ui.pointer_cpp", "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.ui.pointer:fuchsia.ui.pointer_cpp_hlcpp_conversion", "//third_party/fuchsia-sdk/sdk/pkg/scenic_cpp_testing",
diff --git a/ui/events/keycodes/keyboard_code_conversion_fuchsia.cc b/ui/events/keycodes/keyboard_code_conversion_fuchsia.cc index 8cc7626..db086acf 100644 --- a/ui/events/keycodes/keyboard_code_conversion_fuchsia.cc +++ b/ui/events/keycodes/keyboard_code_conversion_fuchsia.cc
@@ -4,7 +4,7 @@ #include "ui/events/keycodes/keyboard_code_conversion_fuchsia.h" -#include <fidl/fuchsia.ui.input3/cpp/fidl.h> +#include <fuchsia/ui/input3/cpp/fidl.h> #include "base/containers/flat_map.h" @@ -12,16 +12,13 @@ namespace { DomKey DomKeyFromFuchsiaNonPrintableKey( - const fuchsia_ui_input3::NonPrintableKey& key) { - if (key == fuchsia_ui_input3::NonPrintableKey::kEnter) { + const fuchsia::ui::input3::NonPrintableKey& key) { + if (key == fuchsia::ui::input3::NonPrintableKey::ENTER) return DomKey::ENTER; - } - if (key == fuchsia_ui_input3::NonPrintableKey::kTab) { + if (key == fuchsia::ui::input3::NonPrintableKey::TAB) return DomKey::TAB; - } - if (key == fuchsia_ui_input3::NonPrintableKey::kBackspace) { + if (key == fuchsia::ui::input3::NonPrintableKey::BACKSPACE) return DomKey::BACKSPACE; - } return DomKey::UNIDENTIFIED; } @@ -29,21 +26,18 @@ } // namespace DomKey DomKeyFromFuchsiaKeyMeaning( - const fuchsia_ui_input3::KeyMeaning& key_meaning) { - if (key_meaning.codepoint()) { + const fuchsia::ui::input3::KeyMeaning& key_meaning) { + if (key_meaning.is_codepoint()) { // TODO(fxbug.dev/106600): Remove this check for codepoint zero, once the // platform provides non-printable key meanings consistently. - if (key_meaning.codepoint().value() == 0) { + if (key_meaning.codepoint() == 0) return DomKey::UNIDENTIFIED; - } - return DomKey::FromCharacter(key_meaning.codepoint().value()); + return DomKey::FromCharacter(key_meaning.codepoint()); } - if (key_meaning.non_printable_key()) { - return DomKeyFromFuchsiaNonPrintableKey( - key_meaning.non_printable_key().value()); - } + if (key_meaning.is_non_printable_key()) + return DomKeyFromFuchsiaNonPrintableKey(key_meaning.non_printable_key()); return DomKey::UNIDENTIFIED; }
diff --git a/ui/events/keycodes/keyboard_code_conversion_fuchsia.h b/ui/events/keycodes/keyboard_code_conversion_fuchsia.h index 39891089..0e9d30c 100644 --- a/ui/events/keycodes/keyboard_code_conversion_fuchsia.h +++ b/ui/events/keycodes/keyboard_code_conversion_fuchsia.h
@@ -8,15 +8,19 @@ #include "ui/events/events_base_export.h" #include "ui/events/keycodes/dom/dom_key.h" -namespace fuchsia_ui_input3 { +namespace fuchsia { +namespace ui { +namespace input3 { class KeyMeaning; -} // namespace fuchsia_ui_input3 +} // namespace input3 +} // namespace ui +} // namespace fuchsia namespace ui { // Converts a Fuchsia KeyMeaning to a DomKey. EVENTS_BASE_EXPORT DomKey -DomKeyFromFuchsiaKeyMeaning(const fuchsia_ui_input3::KeyMeaning& key_meaning); +DomKeyFromFuchsiaKeyMeaning(const fuchsia::ui::input3::KeyMeaning& key_meaning); } // namespace ui
diff --git a/ui/events/keycodes/keyboard_code_conversion_fuchsia_unittest.cc b/ui/events/keycodes/keyboard_code_conversion_fuchsia_unittest.cc index 22821a9..f4e1db4 100644 --- a/ui/events/keycodes/keyboard_code_conversion_fuchsia_unittest.cc +++ b/ui/events/keycodes/keyboard_code_conversion_fuchsia_unittest.cc
@@ -4,7 +4,8 @@ #include "ui/events/keycodes/keyboard_code_conversion_fuchsia.h" -#include <fidl/fuchsia.ui.input3/cpp/fidl.h> +#include <fuchsia/input/cpp/fidl.h> +#include <fuchsia/ui/input3/cpp/fidl.h> #include <cstdint> #include "base/logging.h" @@ -14,9 +15,9 @@ namespace { -using fuchsia_input::Key; -using fuchsia_ui_input3::KeyMeaning; -using fuchsia_ui_input3::NonPrintableKey; +using fuchsia::input::Key; +using fuchsia::ui::input3::KeyMeaning; +using fuchsia::ui::input3::NonPrintableKey; #define EXPECT_CODEPOINT_MAPS(codepoint) \ EXPECT_EQ( \ @@ -59,8 +60,8 @@ // Check that NonPrintableKeys are converted correctly. EXPECT_EQ(ui::DomKey::ENTER, - ui::DomKeyFromFuchsiaKeyMeaning( - KeyMeaning::WithNonPrintableKey(NonPrintableKey::kEnter))); + ui::DomKeyFromFuchsiaKeyMeaning(KeyMeaning::WithNonPrintableKey( + NonPrintableKey(NonPrintableKey::ENTER)))); } } // namespace
diff --git a/ui/gl/generate_bindings.py b/ui/gl/generate_bindings.py index 289827c0..9cf579f 100755 --- a/ui/gl/generate_bindings.py +++ b/ui/gl/generate_bindings.py
@@ -720,6 +720,14 @@ 'extensions': ['GL_ANGLE_shader_pixel_local_storage']}], 'arguments': 'GLint plane, const GLuint* value', }, { 'return_type': 'void', + 'versions': [{'name': 'glFramebufferPixelLocalStorageInterruptANGLE', + 'extensions': ['GL_ANGLE_shader_pixel_local_storage']}], + 'arguments': '', }, +{ 'return_type': 'void', + 'versions': [{'name': 'glFramebufferPixelLocalStorageRestoreANGLE', + 'extensions': ['GL_ANGLE_shader_pixel_local_storage']}], + 'arguments': '', }, +{ 'return_type': 'void', 'names': ['glFramebufferRenderbufferEXT', 'glFramebufferRenderbuffer'], 'arguments': 'GLenum target, GLenum attachment, GLenum renderbuffertarget, '
diff --git a/ui/gl/gl_bindings_api_autogen_gl.h b/ui/gl/gl_bindings_api_autogen_gl.h index 4a239d2..5047a12 100644 --- a/ui/gl/gl_bindings_api_autogen_gl.h +++ b/ui/gl/gl_bindings_api_autogen_gl.h
@@ -432,6 +432,8 @@ const GLint* value) override; void glFramebufferPixelLocalClearValueuivANGLEFn(GLint plane, const GLuint* value) override; +void glFramebufferPixelLocalStorageInterruptANGLEFn() override; +void glFramebufferPixelLocalStorageRestoreANGLEFn() override; void glFramebufferRenderbufferEXTFn(GLenum target, GLenum attachment, GLenum renderbuffertarget,
diff --git a/ui/gl/gl_bindings_autogen_gl.cc b/ui/gl/gl_bindings_autogen_gl.cc index ce675c8b..50bee0d 100644 --- a/ui/gl/gl_bindings_autogen_gl.cc +++ b/ui/gl/gl_bindings_autogen_gl.cc
@@ -1223,6 +1223,18 @@ GetGLProcAddress("glFramebufferPixelLocalClearValueuivANGLE")); } + if (ext.b_GL_ANGLE_shader_pixel_local_storage) { + fn.glFramebufferPixelLocalStorageInterruptANGLEFn = + reinterpret_cast<glFramebufferPixelLocalStorageInterruptANGLEProc>( + GetGLProcAddress("glFramebufferPixelLocalStorageInterruptANGLE")); + } + + if (ext.b_GL_ANGLE_shader_pixel_local_storage) { + fn.glFramebufferPixelLocalStorageRestoreANGLEFn = + reinterpret_cast<glFramebufferPixelLocalStorageRestoreANGLEProc>( + GetGLProcAddress("glFramebufferPixelLocalStorageRestoreANGLE")); + } + if (ver->IsAtLeastGL(3u, 0u) || ver->is_es) { fn.glFramebufferRenderbufferEXTFn = reinterpret_cast<glFramebufferRenderbufferEXTProc>( @@ -4024,6 +4036,14 @@ driver_->fn.glFramebufferPixelLocalClearValueuivANGLEFn(plane, value); } +void GLApiBase::glFramebufferPixelLocalStorageInterruptANGLEFn() { + driver_->fn.glFramebufferPixelLocalStorageInterruptANGLEFn(); +} + +void GLApiBase::glFramebufferPixelLocalStorageRestoreANGLEFn() { + driver_->fn.glFramebufferPixelLocalStorageRestoreANGLEFn(); +} + void GLApiBase::glFramebufferRenderbufferEXTFn(GLenum target, GLenum attachment, GLenum renderbuffertarget, @@ -7650,6 +7670,18 @@ gl_api_->glFramebufferPixelLocalClearValueuivANGLEFn(plane, value); } +void TraceGLApi::glFramebufferPixelLocalStorageInterruptANGLEFn() { + TRACE_EVENT_BINARY_EFFICIENT0( + "gpu", "TraceGLAPI::glFramebufferPixelLocalStorageInterruptANGLE"); + gl_api_->glFramebufferPixelLocalStorageInterruptANGLEFn(); +} + +void TraceGLApi::glFramebufferPixelLocalStorageRestoreANGLEFn() { + TRACE_EVENT_BINARY_EFFICIENT0( + "gpu", "TraceGLAPI::glFramebufferPixelLocalStorageRestoreANGLE"); + gl_api_->glFramebufferPixelLocalStorageRestoreANGLEFn(); +} + void TraceGLApi::glFramebufferRenderbufferEXTFn(GLenum target, GLenum attachment, GLenum renderbuffertarget, @@ -12046,6 +12078,20 @@ gl_api_->glFramebufferPixelLocalClearValueuivANGLEFn(plane, value); } +void LogGLApi::glFramebufferPixelLocalStorageInterruptANGLEFn() { + GL_SERVICE_LOG("glFramebufferPixelLocalStorageInterruptANGLE" + << "(" + << ")"); + gl_api_->glFramebufferPixelLocalStorageInterruptANGLEFn(); +} + +void LogGLApi::glFramebufferPixelLocalStorageRestoreANGLEFn() { + GL_SERVICE_LOG("glFramebufferPixelLocalStorageRestoreANGLE" + << "(" + << ")"); + gl_api_->glFramebufferPixelLocalStorageRestoreANGLEFn(); +} + void LogGLApi::glFramebufferRenderbufferEXTFn(GLenum target, GLenum attachment, GLenum renderbuffertarget, @@ -16880,6 +16926,14 @@ NoContextHelper("glFramebufferPixelLocalClearValueuivANGLE"); } +void NoContextGLApi::glFramebufferPixelLocalStorageInterruptANGLEFn() { + NoContextHelper("glFramebufferPixelLocalStorageInterruptANGLE"); +} + +void NoContextGLApi::glFramebufferPixelLocalStorageRestoreANGLEFn() { + NoContextHelper("glFramebufferPixelLocalStorageRestoreANGLE"); +} + void NoContextGLApi::glFramebufferRenderbufferEXTFn(GLenum target, GLenum attachment, GLenum renderbuffertarget,
diff --git a/ui/gl/gl_bindings_autogen_gl.h b/ui/gl/gl_bindings_autogen_gl.h index 7f6fac81..b692284 100644 --- a/ui/gl/gl_bindings_autogen_gl.h +++ b/ui/gl/gl_bindings_autogen_gl.h
@@ -507,6 +507,9 @@ typedef void(GL_BINDING_CALL* glFramebufferPixelLocalClearValueuivANGLEProc)( GLint plane, const GLuint* value); +typedef void( + GL_BINDING_CALL* glFramebufferPixelLocalStorageInterruptANGLEProc)(); +typedef void(GL_BINDING_CALL* glFramebufferPixelLocalStorageRestoreANGLEProc)(); typedef void(GL_BINDING_CALL* glFramebufferRenderbufferEXTProc)( GLenum target, GLenum attachment, @@ -2268,6 +2271,10 @@ glFramebufferPixelLocalClearValueivANGLEFn; glFramebufferPixelLocalClearValueuivANGLEProc glFramebufferPixelLocalClearValueuivANGLEFn; + glFramebufferPixelLocalStorageInterruptANGLEProc + glFramebufferPixelLocalStorageInterruptANGLEFn; + glFramebufferPixelLocalStorageRestoreANGLEProc + glFramebufferPixelLocalStorageRestoreANGLEFn; glFramebufferRenderbufferEXTProc glFramebufferRenderbufferEXTFn; glFramebufferTexture2DEXTProc glFramebufferTexture2DEXTFn; glFramebufferTexture2DMultisampleEXTProc @@ -3104,6 +3111,8 @@ virtual void glFramebufferPixelLocalClearValueuivANGLEFn( GLint plane, const GLuint* value) = 0; + virtual void glFramebufferPixelLocalStorageInterruptANGLEFn() = 0; + virtual void glFramebufferPixelLocalStorageRestoreANGLEFn() = 0; virtual void glFramebufferRenderbufferEXTFn(GLenum target, GLenum attachment, GLenum renderbuffertarget, @@ -4654,6 +4663,10 @@ ::gl::g_current_gl_context->glFramebufferPixelLocalClearValueivANGLEFn #define glFramebufferPixelLocalClearValueuivANGLE \ ::gl::g_current_gl_context->glFramebufferPixelLocalClearValueuivANGLEFn +#define glFramebufferPixelLocalStorageInterruptANGLE \ + ::gl::g_current_gl_context->glFramebufferPixelLocalStorageInterruptANGLEFn +#define glFramebufferPixelLocalStorageRestoreANGLE \ + ::gl::g_current_gl_context->glFramebufferPixelLocalStorageRestoreANGLEFn #define glFramebufferRenderbufferEXT \ ::gl::g_current_gl_context->glFramebufferRenderbufferEXTFn #define glFramebufferTexture2DEXT \
diff --git a/ui/gl/gl_bindings_autogen_mock.cc b/ui/gl/gl_bindings_autogen_mock.cc index b1d52585..0fcfa80 100644 --- a/ui/gl/gl_bindings_autogen_mock.cc +++ b/ui/gl/gl_bindings_autogen_mock.cc
@@ -1631,6 +1631,18 @@ } void GL_BINDING_CALL +MockGLInterface::Mock_glFramebufferPixelLocalStorageInterruptANGLE() { + MakeGlMockFunctionUnique("glFramebufferPixelLocalStorageInterruptANGLE"); + interface_->FramebufferPixelLocalStorageInterruptANGLE(); +} + +void GL_BINDING_CALL +MockGLInterface::Mock_glFramebufferPixelLocalStorageRestoreANGLE() { + MakeGlMockFunctionUnique("glFramebufferPixelLocalStorageRestoreANGLE"); + interface_->FramebufferPixelLocalStorageRestoreANGLE(); +} + +void GL_BINDING_CALL MockGLInterface::Mock_glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, @@ -5974,6 +5986,12 @@ if (strcmp(name, "glFramebufferPixelLocalClearValueuivANGLE") == 0) return reinterpret_cast<GLFunctionPointerType>( Mock_glFramebufferPixelLocalClearValueuivANGLE); + if (strcmp(name, "glFramebufferPixelLocalStorageInterruptANGLE") == 0) + return reinterpret_cast<GLFunctionPointerType>( + Mock_glFramebufferPixelLocalStorageInterruptANGLE); + if (strcmp(name, "glFramebufferPixelLocalStorageRestoreANGLE") == 0) + return reinterpret_cast<GLFunctionPointerType>( + Mock_glFramebufferPixelLocalStorageRestoreANGLE); if (strcmp(name, "glFramebufferRenderbuffer") == 0) return reinterpret_cast<GLFunctionPointerType>( Mock_glFramebufferRenderbuffer);
diff --git a/ui/gl/gl_bindings_autogen_mock.h b/ui/gl/gl_bindings_autogen_mock.h index 6fd6e1c2..bdc33cd 100644 --- a/ui/gl/gl_bindings_autogen_mock.h +++ b/ui/gl/gl_bindings_autogen_mock.h
@@ -685,6 +685,8 @@ static void GL_BINDING_CALL Mock_glFramebufferPixelLocalClearValueuivANGLE(GLint plane, const GLuint* value); +static void GL_BINDING_CALL Mock_glFramebufferPixelLocalStorageInterruptANGLE(); +static void GL_BINDING_CALL Mock_glFramebufferPixelLocalStorageRestoreANGLE(); static void GL_BINDING_CALL Mock_glFramebufferRenderbuffer(GLenum target, GLenum attachment,
diff --git a/ui/gl/gl_mock_autogen_gl.h b/ui/gl/gl_mock_autogen_gl.h index a5ebd53..9997b61 100644 --- a/ui/gl/gl_mock_autogen_gl.h +++ b/ui/gl/gl_mock_autogen_gl.h
@@ -391,6 +391,8 @@ void(GLint plane, const GLint* value)); MOCK_METHOD2(FramebufferPixelLocalClearValueuivANGLE, void(GLint plane, const GLuint* value)); +MOCK_METHOD0(FramebufferPixelLocalStorageInterruptANGLE, void()); +MOCK_METHOD0(FramebufferPixelLocalStorageRestoreANGLE, void()); MOCK_METHOD4(FramebufferRenderbufferEXT, void(GLenum target, GLenum attachment,
diff --git a/ui/gl/gl_stub_autogen_gl.h b/ui/gl/gl_stub_autogen_gl.h index 6a581f5..4b63267 100644 --- a/ui/gl/gl_stub_autogen_gl.h +++ b/ui/gl/gl_stub_autogen_gl.h
@@ -436,6 +436,8 @@ void glFramebufferPixelLocalClearValueuivANGLEFn(GLint plane, const GLuint* value) override { } +void glFramebufferPixelLocalStorageInterruptANGLEFn() override {} +void glFramebufferPixelLocalStorageRestoreANGLEFn() override {} void glFramebufferRenderbufferEXTFn(GLenum target, GLenum attachment, GLenum renderbuffertarget,
diff --git a/ui/ozone/platform/flatland/BUILD.gn b/ui/ozone/platform/flatland/BUILD.gn index 8750b5a..ff5da9b 100644 --- a/ui/ozone/platform/flatland/BUILD.gn +++ b/ui/ozone/platform/flatland/BUILD.gn
@@ -60,8 +60,6 @@ "//third_party/angle/src/common/fuchsia_egl", "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.mem:fuchsia.mem_hlcpp", "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.sysmem:fuchsia.sysmem_hlcpp", - "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.ui.views:fuchsia.ui.views_cpp_hlcpp_conversion", - "//third_party/fuchsia-sdk/sdk/pkg/component_incoming_cpp", "//third_party/fuchsia-sdk/sdk/pkg/sys_cpp", "//ui/base", "//ui/base/cursor", @@ -77,7 +75,7 @@ public_deps = [ "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.ui.composition:fuchsia.ui.composition_hlcpp", "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.ui.gfx:fuchsia.ui.gfx_hlcpp", - "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.ui.input3:fuchsia.ui.input3_cpp", + "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.ui.input3:fuchsia.ui.input3_hlcpp", "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.ui.pointer:fuchsia.ui.pointer_cpp", "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.ui.pointer:fuchsia.ui.pointer_cpp_hlcpp_conversion", "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.ui.views:fuchsia.ui.views_hlcpp",
diff --git a/ui/ozone/platform/flatland/flatland_window.cc b/ui/ozone/platform/flatland/flatland_window.cc index c6fbab7..c2ee8fc 100644 --- a/ui/ozone/platform/flatland/flatland_window.cc +++ b/ui/ozone/platform/flatland/flatland_window.cc
@@ -5,9 +5,7 @@ #include "ui/ozone/platform/flatland/flatland_window.h" #include <fidl/fuchsia.ui.pointer/cpp/hlcpp_conversion.h> -#include <fidl/fuchsia.ui.views/cpp/hlcpp_conversion.h> #include <fuchsia/sys/cpp/fidl.h> -#include <lib/async/default.h> #include <lib/sys/cpp/component_context.h> #include <lib/ui/scenic/cpp/view_identity.h> @@ -19,8 +17,8 @@ #include <vector> #include "base/check_op.h" -#include "base/fuchsia/fuchsia_component_connect.h" #include "base/fuchsia/fuchsia_logging.h" +#include "base/fuchsia/process_context.h" #include "base/functional/bind.h" #include "base/memory/scoped_refptr.h" #include "ui/base/cursor/platform_cursor.h" @@ -123,15 +121,14 @@ if (properties.enable_keyboard) { is_virtual_keyboard_enabled_ = properties.enable_virtual_keyboard; - auto keyboard_client_end = - base::fuchsia_component::Connect<fuchsia_ui_input3::Keyboard>(); - CHECK(keyboard_client_end.is_ok()) - << base::FidlConnectionErrorMessage(keyboard_client_end); - keyboard_fidl_client_.Bind(std::move(keyboard_client_end.value()), - async_get_default_dispatcher(), - &fidl_error_event_logger_); - keyboard_client_ = std::make_unique<KeyboardClient>( - keyboard_fidl_client_, fidl::HLCPPToNatural(CloneViewRef()), this); + keyboard_service_ = base::ComponentContextForProcess() + ->svc() + ->Connect<fuchsia::ui::input3::Keyboard>(); + keyboard_service_.set_error_handler([](zx_status_t status) { + ZX_LOG(ERROR, status) << "input3.Keyboard service disconnected."; + }); + keyboard_client_ = std::make_unique<KeyboardClient>(keyboard_service_.get(), + CloneViewRef(), this); } else { DCHECK(!properties.enable_virtual_keyboard); }
diff --git a/ui/ozone/platform/flatland/flatland_window.h b/ui/ozone/platform/flatland/flatland_window.h index 8c5382dc..acb7cc1 100644 --- a/ui/ozone/platform/flatland/flatland_window.h +++ b/ui/ozone/platform/flatland/flatland_window.h
@@ -5,8 +5,8 @@ #ifndef UI_OZONE_PLATFORM_FLATLAND_FLATLAND_WINDOW_H_ #define UI_OZONE_PLATFORM_FLATLAND_FLATLAND_WINDOW_H_ -#include <fidl/fuchsia.ui.input3/cpp/fidl.h> #include <fuchsia/ui/composition/cpp/fidl.h> +#include <fuchsia/ui/input3/cpp/fidl.h> #include <fuchsia/ui/views/cpp/fidl.h> #include <lib/ui/scenic/cpp/view_ref_pair.h> @@ -15,7 +15,6 @@ #include <vector> #include "base/component_export.h" -#include "base/fuchsia/fidl_event_handler.h" #include "base/functional/callback.h" #include "third_party/abseil-cpp/absl/types/optional.h" #include "ui/base/ime/fuchsia/keyboard_client.h" @@ -122,9 +121,7 @@ ScenicWindowDelegate* const scenic_window_delegate_; gfx::AcceleratedWidget const window_id_; - fidl::Client<fuchsia_ui_input3::Keyboard> keyboard_fidl_client_; - base::FidlErrorEventLogger<fuchsia_ui_input3::Keyboard> - fidl_error_event_logger_; + fuchsia::ui::input3::KeyboardPtr keyboard_service_; std::unique_ptr<KeyboardClient> keyboard_client_; std::unique_ptr<PointerEventsHandler> pointer_handler_;
diff --git a/ui/ozone/platform/scenic/BUILD.gn b/ui/ozone/platform/scenic/BUILD.gn index 29e29e87..112607d 100644 --- a/ui/ozone/platform/scenic/BUILD.gn +++ b/ui/ozone/platform/scenic/BUILD.gn
@@ -67,8 +67,6 @@ "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.mem:fuchsia.mem_hlcpp", "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.sysmem:fuchsia.sysmem_hlcpp", "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.ui.pointer:fuchsia.ui.pointer_cpp_hlcpp_conversion", - "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.ui.views:fuchsia.ui.views_cpp_hlcpp_conversion", - "//third_party/fuchsia-sdk/sdk/pkg/component_incoming_cpp", "//third_party/fuchsia-sdk/sdk/pkg/scenic_cpp", "//third_party/fuchsia-sdk/sdk/pkg/sys_cpp", "//ui/base",
diff --git a/ui/ozone/platform/scenic/scenic_window.cc b/ui/ozone/platform/scenic/scenic_window.cc index 1bfa940..c2e282e 100644 --- a/ui/ozone/platform/scenic/scenic_window.cc +++ b/ui/ozone/platform/scenic/scenic_window.cc
@@ -5,9 +5,7 @@ #include "ui/ozone/platform/scenic/scenic_window.h" #include <fidl/fuchsia.ui.pointer/cpp/hlcpp_conversion.h> -#include <fidl/fuchsia.ui.views/cpp/hlcpp_conversion.h> #include <fuchsia/sys/cpp/fidl.h> -#include <lib/async/default.h> #include <lib/sys/cpp/component_context.h> #include <algorithm> @@ -17,8 +15,8 @@ #include <utility> #include <vector> -#include "base/fuchsia/fuchsia_component_connect.h" #include "base/fuchsia/fuchsia_logging.h" +#include "base/fuchsia/process_context.h" #include "base/memory/scoped_refptr.h" #include "ui/base/cursor/platform_cursor.h" #include "ui/display/types/display_constants.h" @@ -138,15 +136,14 @@ if (properties.enable_keyboard) { is_virtual_keyboard_enabled_ = properties.enable_virtual_keyboard; - auto keyboard_client_end = - base::fuchsia_component::Connect<fuchsia_ui_input3::Keyboard>(); - CHECK(keyboard_client_end.is_ok()) - << base::FidlConnectionErrorMessage(keyboard_client_end); - keyboard_fidl_client_.Bind(std::move(keyboard_client_end.value()), - async_get_default_dispatcher(), - &fidl_error_event_logger_); - keyboard_client_ = std::make_unique<KeyboardClient>( - keyboard_fidl_client_, fidl::HLCPPToNatural(CloneViewRef()), this); + keyboard_service_ = base::ComponentContextForProcess() + ->svc() + ->Connect<fuchsia::ui::input3::Keyboard>(); + keyboard_service_.set_error_handler([](zx_status_t status) { + ZX_LOG(ERROR, status) << "input3.Keyboard service disconnected."; + }); + keyboard_client_ = std::make_unique<KeyboardClient>(keyboard_service_.get(), + CloneViewRef(), this); } else { DCHECK(!properties.enable_virtual_keyboard); }
diff --git a/ui/ozone/platform/scenic/scenic_window.h b/ui/ozone/platform/scenic/scenic_window.h index bac1e0a..9ad7099 100644 --- a/ui/ozone/platform/scenic/scenic_window.h +++ b/ui/ozone/platform/scenic/scenic_window.h
@@ -5,10 +5,9 @@ #ifndef UI_OZONE_PLATFORM_SCENIC_SCENIC_WINDOW_H_ #define UI_OZONE_PLATFORM_SCENIC_SCENIC_WINDOW_H_ -#include <fidl/fuchsia.ui.input3/cpp/fidl.h> #include <fuchsia/ui/gfx/cpp/fidl.h> #include <fuchsia/ui/input/cpp/fidl.h> -#include <fuchsia/ui/views/cpp/fidl.h> +#include <fuchsia/ui/input3/cpp/fidl.h> #include <lib/ui/scenic/cpp/resources.h> #include <lib/ui/scenic/cpp/session.h> #include <lib/ui/scenic/cpp/view_ref_pair.h> @@ -17,7 +16,6 @@ #include <vector> #include "base/component_export.h" -#include "base/fuchsia/fidl_event_handler.h" #include "ui/base/ime/fuchsia/keyboard_client.h" #include "ui/events/fuchsia/input_event_sink.h" #include "ui/events/fuchsia/pointer_events_handler.h" @@ -147,9 +145,7 @@ // Used to coordinate window closure requests with the shell. fuchsia::element::ViewControllerPtr view_controller_; - fidl::Client<fuchsia_ui_input3::Keyboard> keyboard_fidl_client_; - base::FidlErrorEventLogger<fuchsia_ui_input3::Keyboard> - fidl_error_event_logger_; + fuchsia::ui::input3::KeyboardPtr keyboard_service_; std::unique_ptr<KeyboardClient> keyboard_client_; // React to view-focus coming and going.
diff --git a/ui/views/accessibility/view_ax_platform_node_delegate_unittest.cc b/ui/views/accessibility/view_ax_platform_node_delegate_unittest.cc index 53f0907..ddb5816 100644 --- a/ui/views/accessibility/view_ax_platform_node_delegate_unittest.cc +++ b/ui/views/accessibility/view_ax_platform_node_delegate_unittest.cc
@@ -408,11 +408,8 @@ TEST_F(ViewAXPlatformNodeDelegateTest, OverrideNameAndDescription) { // Initially the button has no name and no description. - // TODO(accessibility): If nothing has set the name, should the NameFrom - // be kNone or kUninitialized instead of kAttribute? EXPECT_EQ(button_accessibility()->GetName(), ""); - EXPECT_EQ(button_accessibility()->GetNameFrom(), - ax::mojom::NameFrom::kAttribute); + EXPECT_EQ(button_accessibility()->GetNameFrom(), ax::mojom::NameFrom::kNone); EXPECT_EQ(button_accessibility()->GetDescription(), ""); EXPECT_EQ(button_accessibility()->GetDescriptionFrom(), ax::mojom::DescriptionFrom::kNone);
diff --git a/ui/views/accessible_pane_view.cc b/ui/views/accessible_pane_view.cc index 696fade1..4bb6355 100644 --- a/ui/views/accessible_pane_view.cc +++ b/ui/views/accessible_pane_view.cc
@@ -50,6 +50,7 @@ AccessiblePaneView::AccessiblePaneView() : last_focused_view_tracker_(std::make_unique<ViewTracker>()) { focus_search_ = std::make_unique<AccessiblePaneViewFocusSearch>(this); + SetAccessibilityProperties(ax::mojom::Role::kPane); } AccessiblePaneView::~AccessiblePaneView() { @@ -217,10 +218,6 @@ View::SetVisible(flag); } -void AccessiblePaneView::GetAccessibleNodeData(ui::AXNodeData* node_data) { - node_data->role = ax::mojom::Role::kPane; -} - void AccessiblePaneView::RequestFocus() { SetPaneFocusAndFocusDefault(); }
diff --git a/ui/views/accessible_pane_view.h b/ui/views/accessible_pane_view.h index 8d03aa8..1bbb452 100644 --- a/ui/views/accessible_pane_view.h +++ b/ui/views/accessible_pane_view.h
@@ -53,7 +53,6 @@ FocusTraversable* GetPaneFocusTraversable() override; bool AcceleratorPressed(const ui::Accelerator& accelerator) override; void SetVisible(bool flag) override; - void GetAccessibleNodeData(ui::AXNodeData* node_data) override; void RequestFocus() override; // Overridden from FocusChangeListener:
diff --git a/ui/views/accessible_pane_view_unittest.cc b/ui/views/accessible_pane_view_unittest.cc index 24f348477..3d5d3cbf 100644 --- a/ui/views/accessible_pane_view_unittest.cc +++ b/ui/views/accessible_pane_view_unittest.cc
@@ -269,4 +269,30 @@ EXPECT_TRUE(test_view2->AcceleratorPressed(test_view2->escape_key())); } +TEST_F(AccessiblePaneViewTest, AccessibleProperties) { + TestBarView* test_view = new TestBarView(); + test_view->SetAccessibleName(u"Name"); + test_view->SetAccessibleDescription(u"Description"); + EXPECT_EQ(test_view->GetAccessibleName(), u"Name"); + EXPECT_EQ(test_view->GetAccessibleDescription(), u"Description"); + EXPECT_EQ(test_view->GetAccessibleRole(), ax::mojom::Role::kPane); + + ui::AXNodeData data; + test_view->GetAccessibleNodeData(&data); + EXPECT_EQ(data.GetString16Attribute(ax::mojom::StringAttribute::kName), + u"Name"); + EXPECT_EQ(data.GetString16Attribute(ax::mojom::StringAttribute::kDescription), + u"Description"); + EXPECT_EQ(data.role, ax::mojom::Role::kPane); + + data = ui::AXNodeData(); + test_view->SetAccessibleRole(ax::mojom::Role::kToolbar); + test_view->GetAccessibleNodeData(&data); + EXPECT_EQ(data.GetString16Attribute(ax::mojom::StringAttribute::kName), + u"Name"); + EXPECT_EQ(data.GetString16Attribute(ax::mojom::StringAttribute::kDescription), + u"Description"); + EXPECT_EQ(data.role, ax::mojom::Role::kToolbar); +} + } // namespace views
diff --git a/ui/views/controls/button/button.cc b/ui/views/controls/button/button.cc index d50193d..61c61384 100644 --- a/ui/views/controls/button/button.cc +++ b/ui/views/controls/button/button.cc
@@ -519,8 +519,7 @@ } void Button::GetAccessibleNodeData(ui::AXNodeData* node_data) { - node_data->role = ax::mojom::Role::kButton; - node_data->SetName(GetAccessibleName()); + View::GetAccessibleNodeData(node_data); if (!GetEnabled()) node_data->SetRestriction(ax::mojom::Restriction::kDisabled); @@ -606,6 +605,8 @@ // TODO(pbos): Investigate not setting a default color so that we can DCHECK // if one hasn't been set. InkDrop::Get(this)->SetBaseColor(gfx::kPlaceholderColor); + + SetAccessibilityProperties(ax::mojom::Role::kButton); } void Button::RequestFocusFromEvent() {
diff --git a/ui/views/controls/button/button_unittest.cc b/ui/views/controls/button/button_unittest.cc index 2656d77..248bca8 100644 --- a/ui/views/controls/button/button_unittest.cc +++ b/ui/views/controls/button/button_unittest.cc
@@ -927,4 +927,18 @@ EXPECT_EQ(test_tooltip_text, base::ASCIIToUTF16(name)); } +TEST_F(ButtonTest, AccessibleRole) { + ui::AXNodeData data; + button()->GetAccessibleNodeData(&data); + EXPECT_EQ(data.role, ax::mojom::Role::kButton); + EXPECT_EQ(button()->GetAccessibleRole(), ax::mojom::Role::kButton); + + button()->SetAccessibleRole(ax::mojom::Role::kCheckBox); + + data = ui::AXNodeData(); + button()->GetAccessibleNodeData(&data); + EXPECT_EQ(data.role, ax::mojom::Role::kCheckBox); + EXPECT_EQ(button()->GetAccessibleRole(), ax::mojom::Role::kCheckBox); +} + } // namespace views
diff --git a/ui/views/controls/button/label_button.cc b/ui/views/controls/button/label_button.cc index ca06154..31682201 100644 --- a/ui/views/controls/button/label_button.cc +++ b/ui/views/controls/button/label_button.cc
@@ -420,9 +420,10 @@ } void LabelButton::GetAccessibleNodeData(ui::AXNodeData* node_data) { - if (GetIsDefault()) - node_data->AddState(ax::mojom::State::kDefault); Button::GetAccessibleNodeData(node_data); + if (GetIsDefault()) { + node_data->AddState(ax::mojom::State::kDefault); + } } ui::NativeTheme::Part LabelButton::GetThemePart() const {
diff --git a/ui/views/controls/label.cc b/ui/views/controls/label.cc index 37c22391..c619e78c 100644 --- a/ui/views/controls/label.cc +++ b/ui/views/controls/label.cc
@@ -18,7 +18,6 @@ #include "build/build_config.h" #include "build/chromeos_buildflags.h" #include "ui/accessibility/ax_enums.mojom.h" -#include "ui/accessibility/ax_node_data.h" #include "ui/base/clipboard/clipboard.h" #include "ui/base/clipboard/scoped_clipboard_writer.h" #include "ui/base/cursor/cursor.h" @@ -139,6 +138,11 @@ ClearDisplayText(); if (GetWidget()) UpdateColorsFromTheme(); + + SetAccessibleRole(text_context_ == style::CONTEXT_DIALOG_TITLE + ? ax::mojom::Role::kTitleBar + : ax::mojom::Role::kStaticText); + OnPropertyChanged(&text_context_, kPropertyEffectsPreferredSizeChanged); } @@ -467,6 +471,7 @@ if (tooltip_text_ == tooltip_text) return; tooltip_text_ = tooltip_text; + TooltipTextChanged(); OnPropertyChanged(&tooltip_text_, kPropertyEffectsNone); } @@ -715,15 +720,6 @@ return this; } -void Label::GetAccessibleNodeData(ui::AXNodeData* node_data) { - if (text_context_ == style::CONTEXT_DIALOG_TITLE) - node_data->role = ax::mojom::Role::kTitleBar; - else - node_data->role = ax::mojom::Role::kStaticText; - - node_data->SetName(GetAccessibleName()); -} - std::u16string Label::GetTooltipText(const gfx::Point& p) const { if (handles_tooltips_) { if (!tooltip_text_.empty()) @@ -1145,6 +1141,11 @@ UpdateFullTextElideBehavior(); full_text_->SetDirectionalityMode(directionality_mode); + SetAccessibilityProperties(text_context_ == style::CONTEXT_DIALOG_TITLE + ? ax::mojom::Role::kTitleBar + : ax::mojom::Role::kStaticText, + text); + SetText(text); // Only selectable labels will get requests to show the context menu, due to
diff --git a/ui/views/controls/label.h b/ui/views/controls/label.h index 03c33a8..cdaa989 100644 --- a/ui/views/controls/label.h +++ b/ui/views/controls/label.h
@@ -322,7 +322,6 @@ View* GetTooltipHandlerForPoint(const gfx::Point& point) override; bool GetCanProcessEventsWithinSubtree() const override; WordLookupClient* GetWordLookupClient() override; - void GetAccessibleNodeData(ui::AXNodeData* node_data) override; std::u16string GetTooltipText(const gfx::Point& p) const override; protected:
diff --git a/ui/views/controls/label_unittest.cc b/ui/views/controls/label_unittest.cc index 55dc466..36a5ce0 100644 --- a/ui/views/controls/label_unittest.cc +++ b/ui/views/controls/label_unittest.cc
@@ -758,6 +758,39 @@ EXPECT_EQ(u"Altered", label()->display_text_->GetDisplayText()); } +TEST_F(LabelTest, AccessibleNameAndRole) { + label()->SetText(u"Text"); + EXPECT_EQ(label()->GetAccessibleName(), u"Text"); + EXPECT_EQ(label()->GetAccessibleRole(), ax::mojom::Role::kStaticText); + + ui::AXNodeData data; + label()->GetAccessibleNodeData(&data); + EXPECT_EQ(data.GetString16Attribute(ax::mojom::StringAttribute::kName), + u"Text"); + EXPECT_EQ(data.role, ax::mojom::Role::kStaticText); + + label()->SetTextContext(style::CONTEXT_DIALOG_TITLE); + EXPECT_EQ(label()->GetAccessibleName(), u"Text"); + EXPECT_EQ(label()->GetAccessibleRole(), ax::mojom::Role::kTitleBar); + + data = ui::AXNodeData(); + label()->GetAccessibleNodeData(&data); + EXPECT_EQ(data.GetString16Attribute(ax::mojom::StringAttribute::kName), + u"Text"); + EXPECT_EQ(data.role, ax::mojom::Role::kTitleBar); + + label()->SetText(u"New Text"); + label()->SetAccessibleRole(ax::mojom::Role::kLink); + EXPECT_EQ(label()->GetAccessibleName(), u"New Text"); + EXPECT_EQ(label()->GetAccessibleRole(), ax::mojom::Role::kLink); + + data = ui::AXNodeData(); + label()->GetAccessibleNodeData(&data); + EXPECT_EQ(data.GetString16Attribute(ax::mojom::StringAttribute::kName), + u"New Text"); + EXPECT_EQ(data.role, ax::mojom::Role::kLink); +} + TEST_F(LabelTest, EmptyLabelSizing) { const gfx::Size expected_size(0, label()->font_list().GetHeight()); EXPECT_EQ(expected_size, label()->GetPreferredSize());
diff --git a/ui/views/controls/slider.cc b/ui/views/controls/slider.cc index f8437b1e..b0b563e9 100644 --- a/ui/views/controls/slider.cc +++ b/ui/views/controls/slider.cc
@@ -73,6 +73,7 @@ Slider::Slider(SliderListener* listener) : listener_(listener) { highlight_animation_.SetSlideDuration(base::Milliseconds(150)); SetFlipCanvasOnPaintForRTLUI(true); + SetAccessibilityProperties(ax::mojom::Role::kSlider); #if BUILDFLAG(IS_MAC) SetFocusBehavior(FocusBehavior::ACCESSIBLE_ONLY); @@ -321,7 +322,7 @@ } void Slider::GetAccessibleNodeData(ui::AXNodeData* node_data) { - node_data->role = ax::mojom::Role::kSlider; + View::GetAccessibleNodeData(node_data); node_data->SetValue(base::UTF8ToUTF16( base::StringPrintf("%d%%", static_cast<int>(value_ * 100 + 0.5)))); node_data->AddAction(ax::mojom::Action::kIncrement);
diff --git a/ui/views/controls/slider_unittest.cc b/ui/views/controls/slider_unittest.cc index 8375a29e..4a7e59b 100644 --- a/ui/views/controls/slider_unittest.cc +++ b/ui/views/controls/slider_unittest.cc
@@ -21,6 +21,7 @@ #include "ui/events/gesture_event_details.h" #include "ui/events/keycodes/keyboard_codes.h" #include "ui/events/test/event_generator.h" +#include "ui/views/accessibility/view_accessibility.h" #include "ui/views/test/ax_event_counter.h" #include "ui/views/test/slider_test_api.h" #include "ui/views/test/views_test_base.h" @@ -289,6 +290,20 @@ slider()->GetValue()); } +TEST_P(SliderTest, AccessibleRole) { + ui::AXNodeData data; + slider()->GetViewAccessibility().GetAccessibleNodeData(&data); + EXPECT_EQ(data.role, ax::mojom::Role::kSlider); + EXPECT_EQ(slider()->GetAccessibleRole(), ax::mojom::Role::kSlider); + + slider()->SetAccessibleRole(ax::mojom::Role::kMeter); + + data = ui::AXNodeData(); + slider()->GetViewAccessibility().GetAccessibleNodeData(&data); + EXPECT_EQ(data.role, ax::mojom::Role::kMeter); + EXPECT_EQ(slider()->GetAccessibleRole(), ax::mojom::Role::kMeter); +} + // No touch on desktop Mac. Tracked in http://crbug.com/445520. #if !BUILDFLAG(IS_MAC) || defined(USE_AURA)
diff --git a/ui/views/controls/styled_label.cc b/ui/views/controls/styled_label.cc index de27c7f..5fc2b10 100644 --- a/ui/views/controls/styled_label.cc +++ b/ui/views/controls/styled_label.cc
@@ -16,7 +16,6 @@ #include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/abseil-cpp/absl/types/variant.h" #include "ui/accessibility/ax_enums.mojom.h" -#include "ui/accessibility/ax_node_data.h" #include "ui/base/metadata/metadata_impl_macros.h" #include "ui/color/color_id.h" #include "ui/color/color_provider.h" @@ -79,7 +78,11 @@ std::vector<std::unique_ptr<View>> owned_views; }; -StyledLabel::StyledLabel() = default; +StyledLabel::StyledLabel() { + SetAccessibilityProperties(text_context_ == style::CONTEXT_DIALOG_TITLE + ? ax::mojom::Role::kTitleBar + : ax::mojom::Role::kStaticText); +} StyledLabel::~StyledLabel() = default; @@ -96,6 +99,7 @@ return; text_ = text; + SetAccessibleName(text_); style_ranges_.clear(); RemoveOrDeleteAllChildViews(); OnPropertyChanged(&text_, kPropertyEffectsPreferredSizeChanged); @@ -135,6 +139,9 @@ return; text_context_ = text_context; + SetAccessibleRole(text_context_ == style::CONTEXT_DIALOG_TITLE + ? ax::mojom::Role::kTitleBar + : ax::mojom::Role::kStaticText); OnPropertyChanged(&text_context_, kPropertyEffectsPreferredSizeChanged); } @@ -219,13 +226,6 @@ SetSize(size); } -void StyledLabel::GetAccessibleNodeData(ui::AXNodeData* node_data) { - node_data->role = (text_context_ == style::CONTEXT_DIALOG_TITLE) - ? ax::mojom::Role::kTitleBar - : ax::mojom::Role::kStaticText; - node_data->SetName(GetText()); -} - gfx::Size StyledLabel::CalculatePreferredSize() const { // Respect any existing size. If there is none, default to a single line. CalculateLayout((width() == 0) ? std::numeric_limits<int>::max() : width());
diff --git a/ui/views/controls/styled_label.h b/ui/views/controls/styled_label.h index 646f67a..8884e55 100644 --- a/ui/views/controls/styled_label.h +++ b/ui/views/controls/styled_label.h
@@ -171,7 +171,6 @@ void SizeToFit(int fixed_width); // View: - void GetAccessibleNodeData(ui::AXNodeData* node_data) override; gfx::Size CalculatePreferredSize() const override; int GetHeightForWidth(int w) const override; void Layout() override;
diff --git a/ui/views/controls/styled_label_unittest.cc b/ui/views/controls/styled_label_unittest.cc index fb3831df..dae57fc 100644 --- a/ui/views/controls/styled_label_unittest.cc +++ b/ui/views/controls/styled_label_unittest.cc
@@ -875,4 +875,36 @@ EXPECT_EQ(size, styled()->GetPreferredSize()); } +TEST_F(StyledLabelTest, AccessibleNameAndRole) { + const std::string text("Text"); + InitStyledLabel(text); + EXPECT_EQ(styled()->GetAccessibleName(), base::UTF8ToUTF16(text)); + EXPECT_EQ(styled()->GetAccessibleRole(), ax::mojom::Role::kStaticText); + + ui::AXNodeData data; + styled()->GetAccessibleNodeData(&data); + EXPECT_EQ(data.GetStringAttribute(ax::mojom::StringAttribute::kName), text); + EXPECT_EQ(data.role, ax::mojom::Role::kStaticText); + + styled()->SetTextContext(style::CONTEXT_DIALOG_TITLE); + EXPECT_EQ(styled()->GetAccessibleName(), base::UTF8ToUTF16(text)); + EXPECT_EQ(styled()->GetAccessibleRole(), ax::mojom::Role::kTitleBar); + + data = ui::AXNodeData(); + styled()->GetAccessibleNodeData(&data); + EXPECT_EQ(data.GetStringAttribute(ax::mojom::StringAttribute::kName), text); + EXPECT_EQ(data.role, ax::mojom::Role::kTitleBar); + + styled()->SetText(u"New Text"); + styled()->SetAccessibleRole(ax::mojom::Role::kLink); + EXPECT_EQ(styled()->GetAccessibleName(), u"New Text"); + EXPECT_EQ(styled()->GetAccessibleRole(), ax::mojom::Role::kLink); + + data = ui::AXNodeData(); + styled()->GetAccessibleNodeData(&data); + EXPECT_EQ(data.GetString16Attribute(ax::mojom::StringAttribute::kName), + u"New Text"); + EXPECT_EQ(data.role, ax::mojom::Role::kLink); +} + } // namespace views
diff --git a/ui/views/controls/textfield/textfield.cc b/ui/views/controls/textfield/textfield.cc index de07dc7f..dc6efb3 100644 --- a/ui/views/controls/textfield/textfield.cc +++ b/ui/views/controls/textfield/textfield.cc
@@ -257,6 +257,8 @@ AddAccelerator(ui::Accelerator(ui::VKEY_V, ui::EF_CONTROL_DOWN)); #endif + SetAccessibilityProperties(ax::mojom::Role::kTextField); + // Sometimes there are additional ignored views, such as the View representing // the cursor, inside the text field. These should always be ignored by // accessibility since a plain text field should always be a leaf node in the @@ -1013,10 +1015,7 @@ } void Textfield::GetAccessibleNodeData(ui::AXNodeData* node_data) { - node_data->role = ax::mojom::Role::kTextField; - - node_data->SetName(GetAccessibleName()); - node_data->SetNameFrom(ax::mojom::NameFrom::kAttribute); + View::GetAccessibleNodeData(node_data); // Editable state indicates support of editable interface, and is always set // for a textfield, even if disabled or readonly.
diff --git a/ui/views/controls/textfield/textfield_unittest.cc b/ui/views/controls/textfield/textfield_unittest.cc index 8400210..741df4f 100644 --- a/ui/views/controls/textfield/textfield_unittest.cc +++ b/ui/views/controls/textfield/textfield_unittest.cc
@@ -4567,6 +4567,22 @@ EXPECT_TRUE(node_data_protected.HasState(ax::mojom::State::kProtected)); } +TEST_F(TextfieldTest, AccessibleRole) { + InitTextfield(); + + ui::AXNodeData data; + textfield_->GetAccessibleNodeData(&data); + EXPECT_EQ(data.role, ax::mojom::Role::kTextField); + EXPECT_EQ(textfield_->GetAccessibleRole(), ax::mojom::Role::kTextField); + + textfield_->SetAccessibleRole(ax::mojom::Role::kSearchBox); + + data = ui::AXNodeData(); + textfield_->GetAccessibleNodeData(&data); + EXPECT_EQ(data.role, ax::mojom::Role::kSearchBox); + EXPECT_EQ(textfield_->GetAccessibleRole(), ax::mojom::Role::kSearchBox); +} + // Verify that cursor visibility is controlled by SetCursorEnabled. TEST_F(TextfieldTest, CursorVisibility) { InitTextfield();
diff --git a/ui/webui/resources/cr_components/history_clusters/page_favicon.html b/ui/webui/resources/cr_components/history_clusters/page_favicon.html index b9cadcd7..b66015e 100644 --- a/ui/webui/resources/cr_components/history_clusters/page_favicon.html +++ b/ui/webui/resources/cr_components/history_clusters/page_favicon.html
@@ -22,6 +22,12 @@ max-height: 100%; max-width: 100%; } + + :host([is-image-cover_]) #page-image { + height: 100%; + object-fit: cover; + width: 100%; + } </style> <template is="dom-if" if="[[imageUrl_]]">
diff --git a/ui/webui/resources/cr_components/history_clusters/page_favicon.ts b/ui/webui/resources/cr_components/history_clusters/page_favicon.ts index df08b0bb..a10db368d 100644 --- a/ui/webui/resources/cr_components/history_clusters/page_favicon.ts +++ b/ui/webui/resources/cr_components/history_clusters/page_favicon.ts
@@ -77,6 +77,12 @@ type: Object, value: null, }, + + isImageCover_: { + type: Boolean, + value: () => loadTimeData.getBoolean('isHistoryClustersImageCover'), + reflectToAttribute: true, + }, }; }