diff --git a/BUILD.gn b/BUILD.gn index 645819d..239c4d6 100644 --- a/BUILD.gn +++ b/BUILD.gn
@@ -1451,6 +1451,9 @@ args = _common_web_test_args + # Use --wpt-only to skip tests under web_tests/virtual/ + args += [ "--wpt-only" ] + data_deps = [ ":blink_web_tests_support_data" ] data = [ "//third_party/blink/perf_tests/", @@ -1474,6 +1477,7 @@ # === List Test Cases folders here === "//third_party/blink/web_tests/external/", "//third_party/blink/web_tests/wpt_internal/", + "//third_party/blink/web_tests/virtual/", # === Test Case Folders Ends === ]
diff --git a/DEPS b/DEPS index 3ccd7e0..c423a416 100644 --- a/DEPS +++ b/DEPS
@@ -300,15 +300,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': '9540beb7057b6672ebb761c1d11e3cecb34daa33', + 'skia_revision': '848fe76219b0a1f65815b90f1c6a648658328fc3', # 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': 'a15821edd7c6f3b89725f3c029b3b73ee5521217', + 'v8_revision': 'f99c9d0827a1df7cc4524a6a67f1834341e701b2', # 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': 'f7274de21ea52644ea5fd1a8abab6e99ffd7d2f2', + 'angle_revision': 'efa9a4d914fce3be312b3ca5afe86ab4b7031b57', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. @@ -316,7 +316,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. - 'pdfium_revision': '5337c83fbb82c66079a412d83df775443f25ed79', + 'pdfium_revision': 'e0ea309bac37762ef6772cbc460423a03f658ce6', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling BoringSSL # and whatever else without interference from each other. @@ -327,7 +327,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:9.20220824.2.1', + 'fuchsia_version': 'version:9.20220825.0.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. @@ -347,7 +347,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling NaCl # and whatever else without interference from each other. - 'nacl_revision': 'fc84d07f7489f43b99db71ae2d417afba2e8c81f', + 'nacl_revision': '3418b267ecc8ead003eb328fc52d479bc5b00193', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling freetype # and whatever else without interference from each other. @@ -371,7 +371,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': '5571576cd66841e89180820e062e6b93c4d11c63', + 'catapult_revision': '3fdc858272d1b7d39f6788d11eb955a649ff1891', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -379,7 +379,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': '693b0f160ac929a8416114755e20f6e9a0b47bf0', + 'devtools_frontend_revision': '3379193dc5e947b26ce3e66d87f4ce40c28c583f', # 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. @@ -415,7 +415,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'dawn_revision': '202362f47db4f81df9dcee8d97a4fef295cf4579', + 'dawn_revision': '4b0147002041fc0b63fdd26a1aef6ea869105f26', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -776,7 +776,7 @@ Var('chromium_git') + '/external/github.com/toji/webvr.info.git' + '@' + 'c58ae99b9ff9e2aa4c524633519570bf33536248', 'src/docs/website': { - 'url': Var('chromium_git') + '/website.git' + '@' + '8cc6301c5a6e0bc9a72c606712997db36d6387c6', + 'url': Var('chromium_git') + '/website.git' + '@' + '837988b0fa77937bd361568b9599356fb634e100', }, 'src/ios/third_party/earl_grey2/src': { @@ -1177,7 +1177,7 @@ # For Linux and Chromium OS. 'src/third_party/cros_system_api': { - 'url': Var('chromium_git') + '/chromiumos/platform2/system_api.git' + '@' + 'dc5729d39a84b6630466d6a522ebff95580bbb32', + 'url': Var('chromium_git') + '/chromiumos/platform2/system_api.git' + '@' + '51398d6bbd48ea4b8ab1bbed6eb9b4594dd77fb7', 'condition': 'checkout_linux', }, @@ -1559,7 +1559,7 @@ Var('chromium_git') + '/external/github.com/cisco/openh264' + '@' + 'fac04ceb3e966f613ed17e98178e9d690280bba6', 'src/third_party/openscreen/src': - Var('chromium_git') + '/openscreen' + '@' + '5528ecf4e6e10cdd5cfc3551dc443c9d403debe8', + Var('chromium_git') + '/openscreen' + '@' + '25e5b65e8885a8c95945f7c93ded525a95a9c8a1', 'src/third_party/openxr/src': { 'url': Var('chromium_git') + '/external/github.com/KhronosGroup/OpenXR-SDK' + '@' + 'bf21ccb1007bb531b45d9978919a56ea5059c245', @@ -1707,7 +1707,7 @@ 'dep_type': 'cipd', }, - 'src/third_party/vulkan-deps': '{chromium_git}/vulkan-deps@bc2e8177d3ca2a079932d11ab82cab79ac931730', + 'src/third_party/vulkan-deps': '{chromium_git}/vulkan-deps@e623f608cbf37ee753b3abb9d55b9540506edde6', 'src/third_party/vulkan_memory_allocator': Var('chromium_git') + '/external/github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator.git' + '@' + 'ebe84bec02c041d28f902da0214bf442743fc907', @@ -1819,7 +1819,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@0d33bf0ae30943312ec8003244d972352589c892', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@ec56c50fcb9eedaade23b8791366bfbdfd72acde', 'condition': 'checkout_src_internal', }, @@ -1860,7 +1860,7 @@ 'packages': [ { 'package': 'chromeos_internal/apps/media_app/app', - 'version': 'f03cQfrkjG1toP0-ztpp2OrVQKZgI-VOkgzsfZPuPxEC', + 'version': 'Mwlpj1_xwRsnvGsIbvpnay7DbJ_m4OCWZccG60MFlLAC', }, ], 'condition': 'checkout_chromeos and checkout_src_internal',
diff --git a/PRESUBMIT.py b/PRESUBMIT.py index a9320fa..d034f826 100644 --- a/PRESUBMIT.py +++ b/PRESUBMIT.py
@@ -680,7 +680,7 @@ '^gin/array_buffer\.(cc|h)', '^chrome/services/sharing/nearby/', # gRPC provides some C++ libraries that use std::shared_ptr<>. - '^chromeos/services/libassistant/grpc/', + '^chromeos/ash/services/libassistant/grpc/', '^chromecast/cast_core/grpc', '^chromecast/cast_core/runtime/browser', # Fuchsia provides C++ libraries that use std::shared_ptr<>.
diff --git a/WATCHLISTS b/WATCHLISTS index f80d4d4..59d1583 100644 --- a/WATCHLISTS +++ b/WATCHLISTS
@@ -116,6 +116,10 @@ 'android_webview_network_service': { 'filepath': 'android_webview/browser/network_service/', }, + 'app_management': { + 'filepath': 'chrome/browser/resources/settings/chromeos/os_apps_page'\ + '|chrome/browser/ui/webui/app_management', + }, 'app_service': { 'filepath': 'chrome/browser/apps/app_service/'\ '|chrome/browser/ui/app_list/app_service/'\ @@ -1713,7 +1717,11 @@ '|chrome/common/profiler/'\ '|chrome/renderer/v8_unwinder'\ '|components/metrics/.*call_stack'\ - '|components/metrics/public/mojom/call_stack', + '|components/metrics/public/mojom/call_stack'\ + '|build/android/gyp/create_unwind_table*'\ + '|build/android/gyp/extract_unwind_tables*'\ + '|chrome/android/features/stack_unwinder/'\ + '|chrome/android/modules/stack_unwinder/', }, 'scanning': { 'filepath': 'ash/webui/scanning/'\ @@ -2209,6 +2217,7 @@ 'webapks-watchlist@chromium.org'], 'android_webview': ['android-webview-reviews@chromium.org'], 'android_webview_network_service': [], + 'app_management': ['jshikaram+watch-app_management@chromium.org'], 'app_service': ['dominickn+watch-app_service@chromium.org', 'nancylingwang@chromium.org'], 'app_shortcuts': ['dominickn+watch-app_shortcuts@chromium.org', @@ -2795,7 +2804,7 @@ 'yusukes+watch@chromium.org'], 'permissions': ['dominickn+watch-permissions@chromium.org', 'permissions-reviews@chromium.org'], - 'phonehub': ['hansberry+watch-phonehub@chromium.org', + 'phonehub': ['hansberry+watch-phonehub@chromium.org', 'jonmann+watch-phonehub@chromium.org'], 'picture_in_picture': ['beaufort.francois+pip@gmail.com'], 'plugin_metadata': ['wfh+watch@chromium.org'],
diff --git a/android_webview/browser/gfx/task_forwarding_sequence.cc b/android_webview/browser/gfx/task_forwarding_sequence.cc index 61494cd..d31754b9 100644 --- a/android_webview/browser/gfx/task_forwarding_sequence.cc +++ b/android_webview/browser/gfx/task_forwarding_sequence.cc
@@ -78,7 +78,7 @@ scoped_refptr<gpu::SyncPointOrderData> sync_point_order_data) { // Block thread when waiting for sync token. This avoids blocking when we // encounter the wait command later. - for (const auto& sync_token : sync_token_fences) { + for (const auto& sync_token : gpu::ReduceSyncTokens(sync_token_fences)) { base::WaitableEvent completion; if (sync_point_manager->Wait( sync_token, sync_point_order_data->sequence_id(), order_num,
diff --git a/ash/clipboard/clipboard_history_item.cc b/ash/clipboard/clipboard_history_item.cc index ca9adb02..464630ff 100644 --- a/ash/clipboard/clipboard_history_item.cc +++ b/ash/clipboard/clipboard_history_item.cc
@@ -21,6 +21,7 @@ ui::ClipboardData ClipboardHistoryItem::ReplaceEquivalentData( ui::ClipboardData&& new_data) { DCHECK(data_ == new_data); + time_copied_ = base::Time::Now(); // If work has already been done to encode an image belonging to both data // instances, make sure it is not lost. if (data_.maybe_png() && !new_data.maybe_png())
diff --git a/ash/clipboard/clipboard_history_item.h b/ash/clipboard/clipboard_history_item.h index d52c3a6..8be0fca 100644 --- a/ash/clipboard/clipboard_history_item.h +++ b/ash/clipboard/clipboard_history_item.h
@@ -6,8 +6,6 @@ #define ASH_CLIPBOARD_CLIPBOARD_HISTORY_ITEM_H_ #include "ash/ash_export.h" -#include "base/i18n/time_formatting.h" -#include "base/strings/utf_string_conversions.h" #include "base/time/time.h" #include "base/unguessable_token.h" #include "ui/base/clipboard/clipboard_data.h" @@ -43,8 +41,7 @@ // Underlying data for an item in the clipboard history menu. ui::ClipboardData data_; - // Recorded when data is committed to the clipboard history list for the first - // time. + // Time when the item's current data was set. base::Time time_copied_; };
diff --git a/ash/clipboard/clipboard_history_unittest.cc b/ash/clipboard/clipboard_history_unittest.cc index 49b2ef9c..f04ffa0 100644 --- a/ash/clipboard/clipboard_history_unittest.cc +++ b/ash/clipboard/clipboard_history_unittest.cc
@@ -457,6 +457,7 @@ const auto& data_to_duplicate = items.back().data(); const auto original_sequence_number_token = data_to_duplicate.sequence_number_token(); + const auto original_timestamp = items.back().time_copied(); EXPECT_FALSE(data_to_duplicate.maybe_png()); auto png = ui::ClipboardData::EncodeBitmapData(test_bitmap_1); data_to_duplicate.SetPngDataAfterEncoding(png); @@ -472,6 +473,7 @@ // Verify that the encoded image data was preserved while deduplicating data // and reordering items in clipboard history. ASSERT_EQ(items.size(), 2u); + EXPECT_GT(items.front().time_copied(), original_timestamp); const auto& duplicated_data = items.front().data(); EXPECT_EQ(duplicated_data, data_to_duplicate); EXPECT_NE(duplicated_data.sequence_number_token(),
diff --git a/ash/constants/ash_features.cc b/ash/constants/ash_features.cc index 5dd013d..c2475f2 100644 --- a/ash/constants/ash_features.cc +++ b/ash/constants/ash_features.cc
@@ -254,6 +254,9 @@ const base::Feature kBluetoothWbsDogfood{"BluetoothWbsDogfood", base::FEATURE_DISABLED_BY_DEFAULT}; +const base::Feature kRobustAudioDeviceSelectLogic{ + "RobustAudioDeviceSelectLogic", base::FEATURE_DISABLED_BY_DEFAULT}; + // Enable Big GL when using Borealis. const base::Feature kBorealisBigGl{"BorealisBigGl", base::FEATURE_ENABLED_BY_DEFAULT}; @@ -267,12 +270,17 @@ const base::Feature kBorealisPermitted{"BorealisPermitted", base::FEATURE_DISABLED_BY_DEFAULT}; -// Force the client to be on its beta version. If not set, the client will be on -// its stable version. +// Force the steam client to be on its beta version. If not set, the client will +// be on its stable version. const base::Feature kBorealisForceBetaClient{"BorealisForceBetaClient", base::FEATURE_DISABLED_BY_DEFAULT}; -// Prevent Borealis' client from exercising ChromeOS integrations, in this mode +// Force the steam client to render in 2x size (using GDK_SCALE as discussed in +// b/171935238#comment4). +const base::Feature kBorealisForceDoubleScale{ + "BorealisForceDoubleScale", base::FEATURE_DISABLED_BY_DEFAULT}; + +// Prevent the steam client from exercising ChromeOS integrations, in this mode // it functions more like the linux client. const base::Feature kBorealisLinuxMode{"BorealisLinuxMode", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/ash/constants/ash_features.h b/ash/constants/ash_features.h index 097ea730..889e2e4 100644 --- a/ash/constants/ash_features.h +++ b/ash/constants/ash_features.h
@@ -113,12 +113,16 @@ COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kBluetoothRevamp; COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kBluetoothWbsDogfood; COMPONENT_EXPORT(ASH_CONSTANTS) +extern const base::Feature kRobustAudioDeviceSelectLogic; +COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kBorealisBigGl; COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kBorealisDiskManagement; COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kBorealisForceBetaClient; COMPONENT_EXPORT(ASH_CONSTANTS) +extern const base::Feature kBorealisForceDoubleScale; +COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kBorealisLinuxMode; COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kBorealisPermitted;
diff --git a/ash/projector/projector_controller_unittest.cc b/ash/projector/projector_controller_unittest.cc index 13dbb7a7..88f8b9a 100644 --- a/ash/projector/projector_controller_unittest.cc +++ b/ash/projector/projector_controller_unittest.cc
@@ -197,12 +197,13 @@ const AudioNodeInfo kInternalMic[] = { {true, 55555, "Fake Mic", "INTERNAL_MIC", "Internal Mic"}}; - const AudioNode audio_node = AudioNode( - kInternalMic->is_input, kInternalMic->id, - /*has_v2_stable_device_id=*/false, kInternalMic->id, - /*stable_device_id_v2=*/0, kInternalMic->device_name, kInternalMic->type, - kInternalMic->name, /*active=*/false, - /*plugged_time=*/0, /*max_supported_channels=*/1, /*audio_effect=*/1); + const AudioNode audio_node = + AudioNode(kInternalMic->is_input, kInternalMic->id, + /*has_v2_stable_device_id=*/false, kInternalMic->id, + /*stable_device_id_v2=*/0, kInternalMic->device_name, + kInternalMic->type, kInternalMic->name, /*active=*/false, + /*plugged_time=*/0, /*max_supported_channels=*/1, + /*audio_effect=*/1, /*number_of_volume_steps=*/25); FakeCrasAudioClient::Get()->SetAudioNodesForTesting({audio_node}); CrasAudioHandler::Get()->SetActiveInputNodes({kInternalMic->id});
diff --git a/ash/resources/vector_icons/BUILD.gn b/ash/resources/vector_icons/BUILD.gn index 24b5307b..43f610a 100644 --- a/ash/resources/vector_icons/BUILD.gn +++ b/ash/resources/vector_icons/BUILD.gn
@@ -197,6 +197,7 @@ "notification_charging_usb_c.icon", "notification_chromevox.icon", "notification_keyboard.icon", + "notification_linux.icon", "notification_low_power_charger.icon", "notification_monitor_warning.icon", "notification_multi_device_setup.icon",
diff --git a/chrome/app/vector_icons/notification_linux.icon b/ash/resources/vector_icons/notification_linux.icon similarity index 100% rename from chrome/app/vector_icons/notification_linux.icon rename to ash/resources/vector_icons/notification_linux.icon
diff --git a/ash/style/ash_color_provider.cc b/ash/style/ash_color_provider.cc index 8991944..3081b942 100644 --- a/ash/style/ash_color_provider.cc +++ b/ash/style/ash_color_provider.cc
@@ -167,7 +167,6 @@ } SkColor AshColorProvider::GetContentLayerColor(ContentLayerType type) const { - bool use_dark_color = IsDarkModeEnabled(); auto* color_provider = GetColorProvider(); switch (type) { case ContentLayerType::kSeparatorColor: @@ -240,15 +239,9 @@ case ContentLayerType::kTextColorSuggestion: return color_provider->GetColor(kColorAshTextColorSuggestion); case ContentLayerType::kTextColorPrimary: - // TODO(crbug.com/1346394): Change to `color_provider` when relevant - // callers are fixed. - return cros_styles::ResolveColor(ColorName::kTextColorPrimary, - use_dark_color); + return color_provider->GetColor(kColorAshTextColorPrimary); case ContentLayerType::kTextColorSecondary: - // TODO(crbug.com/1346394): Change to `color_provider` when relevant - // callers are fixed. - return cros_styles::ResolveColor(ColorName::kTextColorSecondary, - use_dark_color); + return color_provider->GetColor(kColorAshTextColorSecondary); case ContentLayerType::kTextColorAlert: return color_provider->GetColor(kColorAshTextColorAlert); case ContentLayerType::kTextColorWarning:
diff --git a/ash/system/audio/unified_audio_detailed_view_controller_unittest.cc b/ash/system/audio/unified_audio_detailed_view_controller_unittest.cc index dca7ab78..50ec9bb 100644 --- a/ash/system/audio/unified_audio_detailed_view_controller_unittest.cc +++ b/ash/system/audio/unified_audio_detailed_view_controller_unittest.cc
@@ -69,6 +69,9 @@ const uint32_t kInputMaxSupportedChannels = 1; const uint32_t kOutputMaxSupportedChannels = 2; +const int32_t kInputNumberOfVolumeSteps = 0; +const int32_t kOutputNumberOfVolumeSteps = 25; + const AudioNodeInfo kMicJack[] = { {true, kMicJackId, "Fake Mic Jack", "MIC", "Mic Jack", 0}}; @@ -91,7 +94,9 @@ false /* is_active*/, 0 /* pluged_time */, node_info->is_input ? kInputMaxSupportedChannels : kOutputMaxSupportedChannels, - node_info->audio_effect); + node_info->audio_effect, + node_info->is_input ? kInputNumberOfVolumeSteps + : kOutputNumberOfVolumeSteps); } AudioNodeList GenerateAudioNodeList(
diff --git a/ash/system/channel_indicator/channel_indicator.cc b/ash/system/channel_indicator/channel_indicator.cc index 422459ca3..8755e372 100644 --- a/ash/system/channel_indicator/channel_indicator.cc +++ b/ash/system/channel_indicator/channel_indicator.cc
@@ -10,6 +10,7 @@ #include "ash/shell.h" #include "ash/system/channel_indicator/channel_indicator_utils.h" #include "ash/system/tray/tray_constants.h" +#include "base/check.h" #include "base/memory/weak_ptr.h" #include "base/strings/strcat.h" #include "base/strings/string_util.h" @@ -17,6 +18,7 @@ #include "components/version_info/channel.h" #include "ui/accessibility/ax_node_data.h" #include "ui/base/l10n/l10n_util.h" +#include "ui/gfx/canvas.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/size.h" #include "ui/gfx/paint_vector_icon.h" @@ -24,6 +26,7 @@ #include "ui/views/border.h" #include "ui/views/controls/image_view.h" #include "ui/views/layout/box_layout.h" +#include "ui/views/painter.h" #include "ui/views/view.h" namespace ash { @@ -33,14 +36,56 @@ // Background rounded rectangle corner radius. constexpr int kIndicatorBgCornerRadius = 50; -// Size of padding area around the icon or text. -constexpr int kIndicatorInset = 8; +// Size of padding area between the border and icon or text. +constexpr int kBorderInset = 6; + +// Size of the vector icon. +constexpr int kVectorIconSize = 16; + +// Insets in the layout manager. +constexpr int kLayoutManagerInset = 2; + +// Icon background minimum size, see the declaration of (pure-virtual) +// `GetMinimumSize` in ui/views/painter.h for details. +constexpr int kIconBackgroundMinimumDimension = 20; + +// CirclePainter - for rendering a perfectly circular background for the channel +// indicator icon. +class CirclePainter : public views::Painter { + public: + CirclePainter(SkColor color, size_t diameter) + : color_(color), diameter_(diameter) {} + CirclePainter(const CirclePainter&) = delete; + CirclePainter& operator=(const CirclePainter&) = delete; + ~CirclePainter() override = default; + + private: + // views::Painter: + gfx::Size GetMinimumSize() const override { + return gfx::Size(kIconBackgroundMinimumDimension, + kIconBackgroundMinimumDimension); + } + + void Paint(gfx::Canvas* canvas, const gfx::Size& size) override { + gfx::RectF bounds{gfx::SizeF(size)}; + cc::PaintFlags flags; + flags.setAntiAlias(true); + flags.setColor(color_); + canvas->DrawCircle(bounds.CenterPoint(), diameter_ / 2.f, flags); + } + + const SkColor color_; + const size_t diameter_; +}; } // namespace ChannelIndicatorView::ChannelIndicatorView(Shelf* shelf, version_info::Channel channel) - : TrayItemView(shelf), channel_(channel), session_observer_(this) { + : TrayItemView(shelf), + channel_(channel), + box_layout_(SetLayoutManager(std::make_unique<views::BoxLayout>())), + session_observer_(this) { shell_observer_.Observe(Shell::Get()); SetVisible(false); Update(); @@ -72,12 +117,13 @@ session_manager::SessionState::ACTIVE) { // User is logged in, set image view colors. if (image_view()) { - image_view()->SetBackground(views::CreateRoundedRectBackground( - channel_indicator_utils::GetBgColor(channel_), - kIndicatorBgCornerRadius)); + SetBackground( + views::CreateBackgroundFromPainter(std::make_unique<CirclePainter>( + channel_indicator_utils::GetBgColor(channel_), + IsHorizontalAlignment() ? GetLocalBounds().width() + : GetLocalBounds().height()))); image_view()->SetImage(gfx::CreateVectorIcon( - channel_indicator_utils::GetVectorIcon(channel_), - kUnifiedTrayChannelIndicatorDimension, + channel_indicator_utils::GetVectorIcon(channel_), kVectorIconSize, channel_indicator_utils::GetFgColor(channel_))); } return; @@ -118,18 +164,23 @@ DestroyLabel(); CreateImageView(); - // Border insets depend on shelf horizontal alignment. - SetBorder(views::CreateEmptyBorder( - IsHorizontalAlignment() ? gfx::Insets::VH(kIndicatorInset, 0) - : gfx::Insets::VH(0, kIndicatorInset))); + // Parent's border insets depend on shelf horizontal alignment. Note that + // this modifies the circular background (created below), and can cause + // clipping if incorrectly positioned/sized. + SetBorder(views::CreateEmptyBorder(IsHorizontalAlignment() + ? gfx::Insets::VH(kBorderInset, 0) + : gfx::Insets::VH(0, kBorderInset))); - image_view()->SetBackground(views::CreateRoundedRectBackground( - channel_indicator_utils::GetBgColor(channel_), - kIndicatorBgCornerRadius)); - image_view()->SetImage( - gfx::CreateVectorIcon(channel_indicator_utils::GetVectorIcon(channel_), - kUnifiedTrayChannelIndicatorDimension, - channel_indicator_utils::GetFgColor(channel_))); + box_layout_->set_inside_border_insets( + gfx::Insets::VH(kLayoutManagerInset, kLayoutManagerInset)); + SetBackground( + views::CreateBackgroundFromPainter(std::make_unique<CirclePainter>( + channel_indicator_utils::GetBgColor(channel_), + IsHorizontalAlignment() ? GetLocalBounds().width() + : GetLocalBounds().height()))); + image_view()->SetImage(gfx::CreateVectorIcon( + channel_indicator_utils::GetVectorIcon(channel_), kVectorIconSize, + channel_indicator_utils::GetFgColor(channel_))); PreferredSizeChanged(); return; } @@ -145,8 +196,11 @@ // where side-shelf isn't possible (for now at least!), so nothing here is // adjusted for shelf alignment. DCHECK(IsHorizontalAlignment()); - SetBorder(views::CreateEmptyBorder(gfx::Insets::VH(kIndicatorInset, 0))); - label()->SetBorder(views::CreateEmptyBorder(gfx::Insets::VH(0, 6))); + SetBackground(nullptr); + box_layout_->set_inside_border_insets(gfx::Insets()); + SetBorder(views::CreateEmptyBorder(gfx::Insets::VH(kBorderInset, 0))); + label()->SetBorder( + views::CreateEmptyBorder(gfx::Insets::VH(0, kBorderInset))); label()->SetBackground(views::CreateRoundedRectBackground( channel_indicator_utils::GetBgColor(channel_), kIndicatorBgCornerRadius)); label()->SetEnabledColor(channel_indicator_utils::GetFgColor(channel_)); @@ -191,10 +245,12 @@ aura::Window* root_window, ShelfAlignment old_alignment) { if (image_view()) { - // Border insets depend on shelf horizontal alignment. - SetBorder(views::CreateEmptyBorder( - IsHorizontalAlignment() ? gfx::Insets::VH(kIndicatorInset, 0) - : gfx::Insets::VH(0, kIndicatorInset))); + // Parent's border insets depend on shelf horizontal alignment. Note that + // this modifies the circular background, and can cause clipping if + // incorrectly positioned/sized. + SetBorder(views::CreateEmptyBorder(IsHorizontalAlignment() + ? gfx::Insets::VH(kBorderInset, 0) + : gfx::Insets::VH(0, kBorderInset))); } }
diff --git a/ash/system/channel_indicator/channel_indicator.h b/ash/system/channel_indicator/channel_indicator.h index 2bbdae5..c0eeb30 100644 --- a/ash/system/channel_indicator/channel_indicator.h +++ b/ash/system/channel_indicator/channel_indicator.h
@@ -15,6 +15,10 @@ #include "components/session_manager/session_manager_types.h" #include "components/version_info/channel.h" +namespace views { +class BoxLayout; +} + namespace ash { // A view that resides in the system tray, to make it obvious to the user when a @@ -68,6 +72,12 @@ // The release track on which this devices resides. const version_info::Channel channel_; + // The `BoxLayout` with which the `TrayItemView`-provided `FillLayout` is + // replaced, owned by `views::View`. `FillLayout` wants to size child views to + // fit the parent's bounds, but children of `ChannelIndicatorView` need to + // have specific sizes and insets regardless of the parent's bounds. + views::BoxLayout* box_layout_; + ScopedSessionObserver session_observer_; base::ScopedObservation<Shell,
diff --git a/ash/system/channel_indicator/channel_indicator_unittest.cc b/ash/system/channel_indicator/channel_indicator_unittest.cc index 7f24b52..4cdd2ee 100644 --- a/ash/system/channel_indicator/channel_indicator_unittest.cc +++ b/ash/system/channel_indicator/channel_indicator_unittest.cc
@@ -24,6 +24,15 @@ namespace ash { +namespace { + +// Constants for determining whether a view is "squished" i.e. one of its +// dimensions is very small and one dimension is much larger than the other. +constexpr int kSquishedMinDimension = 2; +constexpr int kSquishedMaxDifferenceBetweenDimensions = 2; + +} // namespace + class ChannelIndicatorViewTest : public AshTestBase, public testing::WithParamInterface<version_info::Channel> { @@ -52,6 +61,24 @@ Shell::Get()->session_controller()->SetSessionInfo(info); } + bool IsViewSquished(const views::View* view) { + DCHECK(view); + + // A view is considered "squished" if: + // (1) Either dimension of its bounds is very small and + // (2) One dimension is much larger than the other + gfx::Rect bounds = view->GetLocalBounds(); + bool is_squished = (bounds.width() <= kSquishedMinDimension || + bounds.height() <= kSquishedMinDimension) && + std::abs(bounds.width() - bounds.height()) >= + kSquishedMaxDifferenceBetweenDimensions; + if (is_squished) { + LOG(ERROR) << __FUNCTION__ << " view (w: " << bounds.width() + << " h: " << bounds.height() << ") is squished "; + } + return is_squished; + } + private: base::test::ScopedFeatureList feature_list_; }; @@ -112,13 +139,8 @@ channel_indicator_view->GetWidget()->LayoutRootViewIfNecessary(); // Now test the bounds of the image view. - gfx::Rect image_view_bounds = GetPrimaryUnifiedSystemTray() - ->channel_indicator_view() - ->image_view() - ->GetLocalBounds(); - EXPECT_GE(image_view_bounds.width(), kUnifiedTrayChannelIndicatorDimension); - EXPECT_GE(image_view_bounds.height(), - kUnifiedTrayChannelIndicatorDimension); + EXPECT_FALSE(IsViewSquished( + GetPrimaryUnifiedSystemTray()->channel_indicator_view()->image_view())); } // User locks the session, view should display text, no image. @@ -141,13 +163,8 @@ channel_indicator_view->GetWidget()->LayoutRootViewIfNecessary(); // Now test the bounds of the image view. - gfx::Rect image_view_bounds = GetPrimaryUnifiedSystemTray() - ->channel_indicator_view() - ->image_view() - ->GetLocalBounds(); - EXPECT_GE(image_view_bounds.width(), kUnifiedTrayChannelIndicatorDimension); - EXPECT_GE(image_view_bounds.height(), - kUnifiedTrayChannelIndicatorDimension); + EXPECT_FALSE(IsViewSquished( + GetPrimaryUnifiedSystemTray()->channel_indicator_view()->image_view())); } }
diff --git a/ash/system/tray/tray_constants.h b/ash/system/tray/tray_constants.h index b8a6b58..d65ef4d5 100644 --- a/ash/system/tray/tray_constants.h +++ b/ash/system/tray/tray_constants.h
@@ -134,7 +134,6 @@ constexpr int kUnifiedTraySpacingBetweenIcons = 6; constexpr int kUnifiedTrayBatteryWidth = 12; constexpr int kUnifiedTrayBatteryBottomPadding = 1; -constexpr int kUnifiedTrayChannelIndicatorDimension = 16; constexpr int kUnifiedTrayContentPadding = 12; constexpr int kUnifiedTopShortcutSpacing = 16; constexpr int kUnifiedNotificationHiddenLineHeight = 20;
diff --git a/ash/system/tray/tray_detailed_view.cc b/ash/system/tray/tray_detailed_view.cc index 390bd87..934ffff 100644 --- a/ash/system/tray/tray_detailed_view.cc +++ b/ash/system/tray/tray_detailed_view.cc
@@ -280,7 +280,9 @@ delegate_->GetBackgroundColor().value_or(SK_ColorTRANSPARENT))); } -TrayDetailedView::~TrayDetailedView() = default; +TrayDetailedView::~TrayDetailedView() { + is_destroying_ = true; +} void TrayDetailedView::OnViewClicked(views::View* sender) { HandleViewClicked(sender); @@ -487,6 +489,10 @@ void TrayDetailedView::OnThemeChanged() { views::View::OnThemeChanged(); + + if (is_destroying_) + return; + delegate_->UpdateColors(); auto* color_provider = AshColorProvider::Get();
diff --git a/ash/system/tray/tray_detailed_view.h b/ash/system/tray/tray_detailed_view.h index d7fc47b..3a4cedcc 100644 --- a/ash/system/tray/tray_detailed_view.h +++ b/ash/system/tray/tray_detailed_view.h
@@ -168,6 +168,11 @@ // separator. bool has_separator_ = true; + // True once the destructor is called. Used to prevent `OnThemeChanged` from + // being called at the same time when this view is being removed. See + // https://crbug.com/1353195 for more details. + bool is_destroying_ = false; + // The accessible name for the `progress_bar_`. absl::optional<std::u16string> progress_bar_accessible_name_; };
diff --git a/ash/webui/face_ml_app_ui/BUILD.gn b/ash/webui/face_ml_app_ui/BUILD.gn index e8b047d..550f5c5 100644 --- a/ash/webui/face_ml_app_ui/BUILD.gn +++ b/ash/webui/face_ml_app_ui/BUILD.gn
@@ -11,12 +11,16 @@ sources = [ "face_ml_app_ui.cc", "face_ml_app_ui.h", + "face_ml_app_untrusted_ui.cc", + "face_ml_app_untrusted_ui.h", "url_constants.cc", "url_constants.h", ] deps = [ + "//ash/webui/resources:face_ml_app_bundle_resources", "//ash/webui/resources:face_ml_app_resources", + "//ash/webui/resources:face_ml_app_untrusted_resources", "//ash/webui/system_apps/public:system_web_app_config", "//content/public/browser", "//ui/webui",
diff --git a/ash/webui/face_ml_app_ui/README.md b/ash/webui/face_ml_app_ui/README.md new file mode 100644 index 0000000..b00cddc --- /dev/null +++ b/ash/webui/face_ml_app_ui/README.md
@@ -0,0 +1,5 @@ +Provides the chrome://face-ml WebUI and supporting interfaces that allow the +Face ML App to integrate with ChromeOS. + +The bulk of the UI will be provided by an internal CIPD package via DEPS, which +is then served via the resource bundle.
diff --git a/ash/webui/face_ml_app_ui/face_ml_app_ui.cc b/ash/webui/face_ml_app_ui/face_ml_app_ui.cc index f1c703a..e8249e33 100644 --- a/ash/webui/face_ml_app_ui/face_ml_app_ui.cc +++ b/ash/webui/face_ml_app_ui/face_ml_app_ui.cc
@@ -33,17 +33,25 @@ trusted_source->SetDefaultResource(IDR_ASH_FACE_ML_APP_INDEX_HTML); #endif // !DCHECK_IS_ON() - // Register common permissions for chrome://face_ml pages. + // We need a CSP override to use the chrome-untrusted:// scheme in the host. + trusted_source->OverrideContentSecurityPolicy( + network::mojom::CSPDirectiveName::FrameSrc, + std::string("frame-src ") + kChromeUIFaceMLAppUntrustedURL + ";"); + + // Add ability to request "chrome-untrusted" URLs. + web_ui->AddRequestableScheme(content::kChromeUIUntrustedScheme); + + // Register common permissions for chrome-untrusted://face-ml pages. auto* webui_allowlist = WebUIAllowlist::GetOrCreate(browser_context); - const url::Origin app_origin = - url::Origin::Create(GURL(kChromeUIFaceMLAppURL)); + const url::Origin untrusted_origin = + url::Origin::Create(GURL(kChromeUIFaceMLAppUntrustedURL)); webui_allowlist->RegisterAutoGrantedPermissions( - app_origin, { - ContentSettingsType::COOKIES, - ContentSettingsType::JAVASCRIPT, - ContentSettingsType::IMAGES, - ContentSettingsType::SOUND, - }); + untrusted_origin, { + ContentSettingsType::COOKIES, + ContentSettingsType::JAVASCRIPT, + ContentSettingsType::IMAGES, + ContentSettingsType::SOUND, + }); } FaceMLAppUI::~FaceMLAppUI() = default;
diff --git a/ash/webui/face_ml_app_ui/face_ml_app_ui.gni b/ash/webui/face_ml_app_ui/face_ml_app_ui.gni new file mode 100644 index 0000000..33496bc1 --- /dev/null +++ b/ash/webui/face_ml_app_ui/face_ml_app_ui.gni
@@ -0,0 +1,5 @@ +declare_args() { + # Whether to enable the product Face ML app. When false, a mock app + # is bundled for testing integration points. + enable_cros_face_ml = false +}
diff --git a/ash/webui/face_ml_app_ui/face_ml_app_untrusted_ui.cc b/ash/webui/face_ml_app_ui/face_ml_app_untrusted_ui.cc new file mode 100644 index 0000000..3e1c6551 --- /dev/null +++ b/ash/webui/face_ml_app_ui/face_ml_app_untrusted_ui.cc
@@ -0,0 +1,54 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ash/webui/face_ml_app_ui/face_ml_app_untrusted_ui.h" + +#include "ash/webui/grit/ash_face_ml_app_bundle_resources.h" +#include "ash/webui/grit/ash_face_ml_app_bundle_resources_map.h" +#include "ash/webui/grit/ash_face_ml_app_untrusted_resources.h" +#include "ash/webui/grit/ash_face_ml_app_untrusted_resources_map.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 "services/network/public/mojom/content_security_policy.mojom.h" + +namespace ash { + +namespace { + +content::WebUIDataSource* CreateFaceMLAppUntrustedDataSource() { + content::WebUIDataSource* source = + content::WebUIDataSource::Create(kChromeUIFaceMLAppUntrustedURL); + source->SetDefaultResource(IDR_ASH_FACE_ML_APP_UNTRUSTED_APP_HTML); + source->AddResourcePaths(base::make_span( + kAshFaceMlAppUntrustedResources, kAshFaceMlAppUntrustedResourcesSize)); + + // Add all resources from ash_face_ml_app_bundle.pak. + source->AddResourcePaths(base::make_span(kAshFaceMlAppBundleResources, + kAshFaceMlAppBundleResourcesSize)); + + source->AddFrameAncestor(GURL(kChromeUIFaceMLAppURL)); + + // TODO(b/239374316) Allow to handle blob: and data: URLs. + // E.g. allow <img>, <audio>, <video> to load blob: and data: URLs. + // and allow framing blob: URLs for browsable content. + + return source; +} + +} // namespace + +FaceMLAppUntrustedUI::FaceMLAppUntrustedUI(content::WebUI* web_ui) + : ui::UntrustedWebUIController(web_ui) { + content::WebUIDataSource* untrusted_source = + CreateFaceMLAppUntrustedDataSource(); + + auto* browser_context = web_ui->GetWebContents()->GetBrowserContext(); + content::WebUIDataSource::Add(browser_context, untrusted_source); +} + +FaceMLAppUntrustedUI::~FaceMLAppUntrustedUI() = default; + +} // namespace ash
diff --git a/ash/webui/face_ml_app_ui/face_ml_app_untrusted_ui.h b/ash/webui/face_ml_app_ui/face_ml_app_untrusted_ui.h new file mode 100644 index 0000000..4cf4182 --- /dev/null +++ b/ash/webui/face_ml_app_ui/face_ml_app_untrusted_ui.h
@@ -0,0 +1,34 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ASH_WEBUI_FACE_ML_APP_UI_FACE_ML_APP_UNTRUSTED_UI_H_ +#define ASH_WEBUI_FACE_ML_APP_UI_FACE_ML_APP_UNTRUSTED_UI_H_ + +#include "ash/webui/face_ml_app_ui/url_constants.h" +#include "ash/webui/system_apps/public/system_web_app_ui_config.h" +#include "content/public/browser/webui_config.h" +#include "ui/webui/untrusted_web_ui_controller.h" + +namespace ash { + +// The Web UI for chrome-untrusted://face-ml. +class FaceMLAppUntrustedUI : public ui::UntrustedWebUIController { + public: + explicit FaceMLAppUntrustedUI(content::WebUI* web_ui); + FaceMLAppUntrustedUI(const FaceMLAppUntrustedUI&) = delete; + FaceMLAppUntrustedUI& operator=(const FaceMLAppUntrustedUI&) = delete; + ~FaceMLAppUntrustedUI() override; +}; + +class FaceMLAppUntrustedUIConfig + : public SystemWebAppUntrustedUIConfig<FaceMLAppUntrustedUI> { + public: + FaceMLAppUntrustedUIConfig() + : SystemWebAppUntrustedUIConfig(kChromeUIFaceMLAppHost, + SystemWebAppType::FACE_ML) {} +}; + +} // namespace ash + +#endif // ASH_WEBUI_FACE_ML_APP_UI_FACE_ML_APP_UNTRUSTED_UI_H_
diff --git a/ash/webui/face_ml_app_ui/resources/mock/app_bin.js b/ash/webui/face_ml_app_ui/resources/mock/app_bin.js new file mode 100644 index 0000000..e978368 --- /dev/null +++ b/ash/webui/face_ml_app_ui/resources/mock/app_bin.js
@@ -0,0 +1,7 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +const div = document.createElement('div'); +div.append(`This is a Face ML mock app.`); +document.body.appendChild(div);
diff --git a/ash/webui/face_ml_app_ui/resources/mock/face_ml_app_bundle_mock_resources.grd b/ash/webui/face_ml_app_ui/resources/mock/face_ml_app_bundle_mock_resources.grd new file mode 100644 index 0000000..b7fc2ac --- /dev/null +++ b/ash/webui/face_ml_app_ui/resources/mock/face_ml_app_bundle_mock_resources.grd
@@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="utf-8"?> +<grit current_release="1" latest_public_release="0" output_all_resource_defines="false"> + <outputs> + <output filename="grit/ash_face_ml_app_bundle_resources.h" type="rc_header"> + <emit emit_type="prepend"/> + </output> + <output filename="grit/ash_face_ml_app_bundle_resources_map.cc" type="resource_file_map_source"/> + <output filename="grit/ash_face_ml_app_bundle_resources_map.h" type="resource_map_header"/> + <output filename="ash_face_ml_app_bundle_resources.pak" type="data_package"/> + </outputs> + <release seq="1"> + <includes> + <include name="IDR_FACE_ML_APP_APP_BIN_JS" file="app_bin.js" type="BINDATA" compress="brotli" /> + </includes> + </release> +</grit>
diff --git a/ash/webui/face_ml_app_ui/resources/trusted/index.html b/ash/webui/face_ml_app_ui/resources/trusted/index.html index 16fb7e3..54904091 100644 --- a/ash/webui/face_ml_app_ui/resources/trusted/index.html +++ b/ash/webui/face_ml_app_ui/resources/trusted/index.html
@@ -11,5 +11,6 @@ <body> <div id="content"></div> <script src="main.js" type="module"></script> + <iframe src="chrome-untrusted://face-ml/app.html"></iframe> </body> </html>
diff --git a/ash/webui/face_ml_app_ui/resources/untrusted/BUILD.gn b/ash/webui/face_ml_app_ui/resources/untrusted/BUILD.gn new file mode 100644 index 0000000..3adb6b0 --- /dev/null +++ b/ash/webui/face_ml_app_ui/resources/untrusted/BUILD.gn
@@ -0,0 +1,16 @@ +# Copyright 2022 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import("//build/config/chromeos/ui_mode.gni") +import("//ui/webui/resources/tools/generate_grd.gni") + +assert(is_chromeos_ash, "Face ML App is ash-chrome only") + +generate_grd("untrusted_grd") { + grd_prefix = "ash_face_ml_app_untrusted" + out_grd = "$target_gen_dir/${grd_prefix}_resources.grd" + + input_files = [ "app.html" ] + input_files_base_dir = rebase_path(".", "//") +}
diff --git a/ash/webui/face_ml_app_ui/resources/untrusted/app.html b/ash/webui/face_ml_app_ui/resources/untrusted/app.html new file mode 100644 index 0000000..4fc97b8 --- /dev/null +++ b/ash/webui/face_ml_app_ui/resources/untrusted/app.html
@@ -0,0 +1,7 @@ +<!-- Copyright 2022 The Chromium Authors. All rights reserved. + Use of this source code is governed by a BSD-style license that can be + found in the LICENSE file. --> +<!DOCTYPE html> +<meta charset="utf-8"> +<div>Face ML Guest Content.</div> +<script src="/app_bin.js" defer></script>
diff --git a/ash/webui/face_ml_app_ui/url_constants.cc b/ash/webui/face_ml_app_ui/url_constants.cc index 250a779..a6414b8 100644 --- a/ash/webui/face_ml_app_ui/url_constants.cc +++ b/ash/webui/face_ml_app_ui/url_constants.cc
@@ -8,5 +8,6 @@ const char kChromeUIFaceMLAppHost[] = "face-ml"; const char kChromeUIFaceMLAppURL[] = "chrome://face-ml"; +const char kChromeUIFaceMLAppUntrustedURL[] = "chrome-untrusted://face-ml/"; } // namespace ash
diff --git a/ash/webui/face_ml_app_ui/url_constants.h b/ash/webui/face_ml_app_ui/url_constants.h index 6b1de4d8..b2335f4 100644 --- a/ash/webui/face_ml_app_ui/url_constants.h +++ b/ash/webui/face_ml_app_ui/url_constants.h
@@ -9,6 +9,7 @@ extern const char kChromeUIFaceMLAppHost[]; extern const char kChromeUIFaceMLAppURL[]; +extern const char kChromeUIFaceMLAppUntrustedURL[]; } // namespace ash
diff --git a/ash/webui/os_feedback_ui/backend/feedback_service_provider.cc b/ash/webui/os_feedback_ui/backend/feedback_service_provider.cc index 1c9bd8a..85cc007 100644 --- a/ash/webui/os_feedback_ui/backend/feedback_service_provider.cc +++ b/ash/webui/os_feedback_ui/backend/feedback_service_provider.cc
@@ -10,6 +10,7 @@ #include "ash/webui/os_feedback_ui/backend/os_feedback_delegate.h" #include "ash/webui/os_feedback_ui/mojom/os_feedback_ui.mojom.h" #include "base/bind.h" +#include "google_apis/gaia/gaia_auth_util.h" #include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/receiver.h" #include "url/gurl.h" @@ -67,6 +68,10 @@ feedback_context->page_url = feedback_delegate_->GetLastActivePageUrl(); feedback_context->email = feedback_delegate_->GetSignedInUserEmail(); + feedback_context->is_internal_account = + feedback_context->email.has_value() && + gaia::IsGoogleInternalAccountEmail(feedback_context->email.value()); + std::move(callback).Run(std::move(feedback_context)); }
diff --git a/ash/webui/os_feedback_ui/backend/feedback_service_provider_unittest.cc b/ash/webui/os_feedback_ui/backend/feedback_service_provider_unittest.cc index 5b7427f..a6322a02 100644 --- a/ash/webui/os_feedback_ui/backend/feedback_service_provider_unittest.cc +++ b/ash/webui/os_feedback_ui/backend/feedback_service_provider_unittest.cc
@@ -25,8 +25,14 @@ constexpr char kPageUrl[] = "https://www.google.com/"; constexpr char kSignedInUserEmail[] = "test_user_email@test.com"; +constexpr char kSignedInInternalUserEmail[] = "test_user_email@google.com"; constexpr char kFeedbackAppPostSubmitAction[] = "Feedback.ChromeOSApp.PostSubmitAction"; +// Set this flag true to use kSignedInInternalUserEmail as signed in email, +// set false to use kSignedInUserEmail as signed in email. +bool kUseInternalUserEmail = false; +constexpr bool kIsInternalEmail = true; +constexpr bool kIsNotInternalEmail = false; const std::vector<uint8_t> kFakePngData = {42, 22, 26, 13, 7, 16, 8, 2}; using FeedbackAppPostSubmitAction = @@ -53,7 +59,8 @@ } absl::optional<std::string> GetSignedInUserEmail() const override { - return kSignedInUserEmail; + return kUseInternalUserEmail ? kSignedInInternalUserEmail + : kSignedInUserEmail; } void GetScreenshotPng(GetScreenshotPngCallback callback) override { @@ -124,10 +131,20 @@ // Test that GetFeedbackContext returns a response with correct feedback // context. TEST_F(FeedbackServiceProviderTest, GetFeedbackContext) { + kUseInternalUserEmail = true; + auto internal_feedback_context = GetFeedbackContextAndWait(); + + EXPECT_EQ(kSignedInInternalUserEmail, + internal_feedback_context->email.value()); + EXPECT_EQ(kPageUrl, internal_feedback_context->page_url.value().spec()); + EXPECT_EQ(kIsInternalEmail, internal_feedback_context->is_internal_account); + + kUseInternalUserEmail = false; auto feedback_context = GetFeedbackContextAndWait(); EXPECT_EQ(kSignedInUserEmail, feedback_context->email.value()); EXPECT_EQ(kPageUrl, feedback_context->page_url.value().spec()); + EXPECT_EQ(kIsNotInternalEmail, feedback_context->is_internal_account); } // Test that GetScreenshotPng returns a response with correct status.
diff --git a/ash/webui/os_feedback_ui/mojom/os_feedback_ui.mojom b/ash/webui/os_feedback_ui/mojom/os_feedback_ui.mojom index f5f62d6..d53fdce9 100644 --- a/ash/webui/os_feedback_ui/mojom/os_feedback_ui.mojom +++ b/ash/webui/os_feedback_ui/mojom/os_feedback_ui.mojom
@@ -72,6 +72,8 @@ struct FeedbackContext { // The e-mail of the user that initiated this feedback. string? email; + // Whether or not the signed in email is an internal google account. + bool is_internal_account; // The URL of the page that this issue was being experienced on. url.mojom.Url? page_url; // Extra diagnostics information provided by source CrOS application by
diff --git a/ash/webui/os_feedback_ui/resources/fake_data.js b/ash/webui/os_feedback_ui/resources/fake_data.js index 6989b92..7b1b00be 100644 --- a/ash/webui/os_feedback_ui/resources/fake_data.js +++ b/ash/webui/os_feedback_ui/resources/fake_data.js
@@ -71,12 +71,21 @@ export const fakeFeedbackContext = { email: 'test.user2@test.com', pageUrl: {url: 'chrome://tab/'}, + isInternalAccount: false, }; /** @type {!FeedbackContext} */ export const fakeEmptyFeedbackContext = { email: '', pageUrl: {url: ''}, + isInternalAccount: false, +}; + +/** @type {!FeedbackContext} */ +export const fakeInternalUserFeedbackContext = { + email: 'test.user@google.com', + pageUrl: {url: 'chrome://tab/'}, + isInternalAccount: true, }; /** @type {!Array<number>} */
diff --git a/ash/webui/os_feedback_ui/resources/share_data_page.html b/ash/webui/os_feedback_ui/resources/share_data_page.html index 7094f6e..22fc9a9 100644 --- a/ash/webui/os_feedback_ui/resources/share_data_page.html +++ b/ash/webui/os_feedback_ui/resources/share_data_page.html
@@ -223,8 +223,9 @@ <label id="sysInfoCheckboxLabel" inner-h-t-m-l="[[sysInfoCheckboxLabel_]]"></label> </div> <!-- Bluetooth Logs (Googler Internal Only) --> - <div id="bluetoothCheckboxContainer" class="checkbox-field-container"> - <cr-checkbox id="bluetoothLogsCheckbox" aria-labelledby="sysInfoCheckboxLabel" checked> + <div id="bluetoothCheckboxContainer" class="checkbox-field-container" + hidden$="[[!shouldShowBluetoothCheckbox_(feedbackContext)]]"> + <cr-checkbox id="bluetoothLogsCheckbox" aria-labelledby="bluetoothInfoLabel" checked> </cr-checkbox> <label id="bluetoothInfoLabel" inner-h-t-m-l="[[bluetoothLogsCheckboxLabel_]]"></label> </div>
diff --git a/ash/webui/os_feedback_ui/resources/share_data_page.js b/ash/webui/os_feedback_ui/resources/share_data_page.js index fc1cfb5..51ba9dde 100644 --- a/ash/webui/os_feedback_ui/resources/share_data_page.js +++ b/ash/webui/os_feedback_ui/resources/share_data_page.js
@@ -116,6 +116,18 @@ * @return {boolean} * @protected */ + shouldShowBluetoothCheckbox_() { + // TODO: add an additional logic to hide bluetooth checkbox if user input + // is not relevant to bluetooth. + return ( + this.feedbackContext !== null && + this.feedbackContext.isInternalAccount); + } + + /** + * @return {boolean} + * @protected + */ hasScreenshot_() { return !!this.screenshotUrl; } @@ -248,7 +260,6 @@ !!this.getElement_('#screenshotImage').src, contactUserConsentGranted: this.getElement_('#userConsentCheckbox').checked, - sendBluetoothLogs: this.getElement_('#bluetoothLogsCheckbox').checked, }); report.attachedFile = @@ -276,8 +287,12 @@ this.feedbackContext.extraDiagnostics; } - if (this.getElement_('#bluetoothLogsCheckbox').checked) { + if (!this.getElement_('#bluetoothCheckboxContainer').hidden && + this.getElement_('#bluetoothLogsCheckbox').checked) { report.feedbackContext.categoryTag = 'BluetoothReportWithLogs'; + report.sendBluetoothLogs = true; + } else { + report.sendBluetoothLogs = false; } return report;
diff --git a/ash/webui/personalization_app/resources/js/ambient/album_list_element.html b/ash/webui/personalization_app/resources/js/ambient/album_list_element.html index 933ccb6..2b5d428fc 100644 --- a/ash/webui/personalization_app/resources/js/ambient/album_list_element.html +++ b/ash/webui/personalization_app/resources/js/ambient/album_list_element.html
@@ -16,7 +16,7 @@ aria-label$="[[album.title]]" aria-posinset$="[[getAriaIndex_(index)]]" class$="[[getAlbumItemClass_(album, albums)]]" - image-src="[[album.url.url]]" + src="[[album.url]]" on-click="onAlbumSelected_" on-keypress="onAlbumSelected_" primary-text="[[album.title]]"
diff --git a/ash/webui/personalization_app/resources/js/wallpaper/google_photos_albums_element.html b/ash/webui/personalization_app/resources/js/wallpaper/google_photos_albums_element.html index a099801..fbfe7e9 100644 --- a/ash/webui/personalization_app/resources/js/wallpaper/google_photos_albums_element.html +++ b/ash/webui/personalization_app/resources/js/wallpaper/google_photos_albums_element.html
@@ -23,7 +23,7 @@ aria-label$="[[getAlbumAriaLabel_(album)]]" aria-posinset$="[[getAlbumAriaIndex_(index)]]" class="album" - image-src="[[album.preview.url]]" + src="[[album.preview]]" index="[[index]]" on-click="onAlbumSelected_" on-keypress="onAlbumSelected_"
diff --git a/ash/webui/personalization_app/resources/js/wallpaper/google_photos_photos_by_album_id_element.html b/ash/webui/personalization_app/resources/js/wallpaper/google_photos_photos_by_album_id_element.html index 9d8dc5e4..eb6f0050 100644 --- a/ash/webui/personalization_app/resources/js/wallpaper/google_photos_photos_by_album_id_element.html +++ b/ash/webui/personalization_app/resources/js/wallpaper/google_photos_photos_by_album_id_element.html
@@ -20,7 +20,7 @@ aria-label$="[[getPhotoAriaLabel_(photo)]]" aria-posinset$="[[getPhotoAriaIndex_(index)]]" class="photo" - image-src="[[photo.url.url]]" + src="[[photo.url]]" index="[[index]]" on-click="onPhotoSelected_" on-keypress="onPhotoSelected_"
diff --git a/ash/webui/personalization_app/resources/js/wallpaper/google_photos_photos_element.html b/ash/webui/personalization_app/resources/js/wallpaper/google_photos_photos_element.html index 17ddca2..b3182dc 100644 --- a/ash/webui/personalization_app/resources/js/wallpaper/google_photos_photos_element.html +++ b/ash/webui/personalization_app/resources/js/wallpaper/google_photos_photos_element.html
@@ -74,7 +74,7 @@ aria-posinset$="[[getPhotoAriaIndex_(photo.index)]]" class="photo" colindex$="[[index]]" - image-src="[[photo.url.url]]" + src="[[photo.url]]" index="[[photo.index]]" on-click="onPhotoSelected_" on-keypress="onPhotoSelected_"
diff --git a/ash/webui/personalization_app/resources/js/wallpaper/wallpaper_error_element.html b/ash/webui/personalization_app/resources/js/wallpaper/wallpaper_error_element.html index d9bdc2e2..d9158d9 100644 --- a/ash/webui/personalization_app/resources/js/wallpaper/wallpaper_error_element.html +++ b/ash/webui/personalization_app/resources/js/wallpaper/wallpaper_error_element.html
@@ -16,9 +16,8 @@ <svg width="380" height="140" viewBox="0 0 380 140" fill="none" xmlns="http://www.w3.org/2000/svg"> <g clip-path="url(#clip0)"> - <rect width="380" height="140" fill="white" /> - <rect width="380" height="188" transform="translate(0 -24)" - fill="white" /> + <rect width="380" height="140"></rect> + <rect width="380" height="188" transform="translate(0 -24)"></rect> <path d="M133.881 108.03L131.437 100.874C130.991 99.5695 129.576 98.8745 128.276 99.3212L121.14 101.773C119.839 102.22 119.146 103.639 119.592 104.943L122.036 112.099C122.482 113.403 123.897 114.098 125.198 113.652L132.333 111.2C133.634 110.753 134.327 109.334 133.881 108.03Z" fill="#FBBC05" /> @@ -65,7 +64,7 @@ </g> <defs> <clipPath id="clip0"> - <rect width="380" height="140" fill="white" /> + <rect width="380" height="140"></rect> </clipPath> </defs> </svg>
diff --git a/ash/webui/personalization_app/resources/js/wallpaper/wallpaper_grid_item_element.html b/ash/webui/personalization_app/resources/js/wallpaper/wallpaper_grid_item_element.html index f1b93296..18e40844 100644 --- a/ash/webui/personalization_app/resources/js/wallpaper/wallpaper_grid_item_element.html +++ b/ash/webui/personalization_app/resources/js/wallpaper/wallpaper_grid_item_element.html
@@ -141,7 +141,7 @@ <img clear-src hidden is-google-photos - auto-src="[[imageSrc]]" + auto-src="[[src.url]]" aria-hidden="true" id="image" is="cr-auto-img">
diff --git a/ash/webui/personalization_app/resources/js/wallpaper/wallpaper_grid_item_element.ts b/ash/webui/personalization_app/resources/js/wallpaper/wallpaper_grid_item_element.ts index d661082..0ffdf88 100644 --- a/ash/webui/personalization_app/resources/js/wallpaper/wallpaper_grid_item_element.ts +++ b/ash/webui/personalization_app/resources/js/wallpaper/wallpaper_grid_item_element.ts
@@ -9,6 +9,7 @@ import 'chrome://resources/cr_elements/cr_auto_img/cr_auto_img.js'; import '../../css/common.css.js'; +import {Url} from 'chrome://resources/mojo/url/mojom/url.mojom-webui.js'; import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {getLoadingPlaceholderAnimationDelay} from './utils.js'; @@ -29,8 +30,8 @@ static get properties() { return { - imageSrc: { - type: String, + src: { + type: Url, observer: 'onImageSrcChanged_', }, @@ -52,7 +53,7 @@ } /** The source for the image to render for the grid item. */ - imageSrc: string|undefined; + src: Url|undefined; /** The index of the grid item within its parent grid. */ index: number; @@ -76,11 +77,11 @@ placeholder: boolean; // Invoked on changes to |imageSrc|. - private onImageSrcChanged_(imageSrc: WallpaperGridItem['imageSrc']) { + private onImageSrcChanged_(src: WallpaperGridItem['src']) { // Hide the |image| element until it has successfully loaded. Note that it // is intentional that the |image| element remain hidden on failure. this.$.image.setAttribute('hidden', ''); - this.$.image.onload = (imageSrc && imageSrc.length) ? + this.$.image.onload = (src && src.url.length) ? () => this.$.image.removeAttribute('hidden') : null; }
diff --git a/ash/webui/resources/BUILD.gn b/ash/webui/resources/BUILD.gn index 28d00ce..11ee40f 100644 --- a/ash/webui/resources/BUILD.gn +++ b/ash/webui/resources/BUILD.gn
@@ -3,6 +3,7 @@ # found in the LICENSE file. import("//ash/webui/eche_app_ui/eche_app_ui.gni") +import("//ash/webui/face_ml_app_ui/face_ml_app_ui.gni") import("//ash/webui/help_app_ui/help_app_ui.gni") import("//ash/webui/media_app_ui/media_app_ui.gni") import("//ash/webui/projector_app/projector_app.gni") @@ -325,6 +326,33 @@ deps = [ "//ash/webui/face_ml_app_ui/resources/trusted:trusted_grd" ] } +# Resources used by chrome-untrusted://face-ml +ash_generated_grit("face_ml_app_untrusted_resources") { + source = "$root_gen_dir/ash/webui/face_ml_app_ui/resources/untrusted/ash_face_ml_app_untrusted_resources.grd" + deps = [ "//ash/webui/face_ml_app_ui/resources/untrusted:untrusted_grd" ] +} + +# Resources automatically served by the chrome-untrusted://face-ml bundle, obtained via DEPS. +grit("face_ml_app_bundle_resources") { + if (enable_cros_face_ml) { + # Obtained via an internal CIPD package in src/DEPS. + source = "//ash/webui/face_ml_app_ui/resources/prod/face_ml_app_bundle_resources.grd" + } else { + source = "//ash/webui/face_ml_app_ui/resources/mock/face_ml_app_bundle_mock_resources.grd" + } + + use_brotli = true + + outputs = [ + "grit/ash_face_ml_app_bundle_resources.h", + "grit/ash_face_ml_app_bundle_resources_map.cc", + "grit/ash_face_ml_app_bundle_resources_map.h", + "ash_face_ml_app_bundle_resources.pak", + ] + + output_dir = "$ash_webui_grit_output_dir" +} + # Resources used by chrome://eche-app ash_generated_grit("eche_app_resources") { source = "$root_gen_dir/ash/webui/eche_app_ui/ash_eche_app_resources.grd"
diff --git a/base/BUILD.gn b/base/BUILD.gn index a70160c..471bfc82 100644 --- a/base/BUILD.gn +++ b/base/BUILD.gn
@@ -953,6 +953,7 @@ "types/expected.h", "types/expected_internal.h", "types/id_type.h", + "types/optional_util.h", "types/pass_key.h", "types/strong_alias.h", "types/token_type.h", @@ -2073,15 +2074,6 @@ # partition_alloc code if use_partition_alloc = false because no code uses # partition_alloc. public_deps += [ "allocator/partition_allocator:partition_alloc" ] - - # PartitionAlloc is not yet built as a standalone component, and - # "external" usage of some exported functions causes Win32 component - # builds to break (LNK4217). This statement properly belongs _only_ - # in PA's BUILD.gn, but we need it here to ensure the rest of - # `//base` is also considered "inside" the PA implementation. - # - # TODO(crbug.com/1151236): Remove this when possible. - defines += [ "IS_PARTITION_ALLOC_IMPL" ] } # Windows. @@ -3406,6 +3398,7 @@ "tuple_unittest.cc", "types/expected_unittest.cc", "types/id_type_unittest.cc", + "types/optional_util_unittest.cc", "types/pass_key_unittest.cc", "types/strong_alias_unittest.cc", "types/token_type_unittest.cc",
diff --git a/base/allocator/partition_allocator/BUILD.gn b/base/allocator/partition_allocator/BUILD.gn index cc14ccc3..f1a56bb 100644 --- a/base/allocator/partition_allocator/BUILD.gn +++ b/base/allocator/partition_allocator/BUILD.gn
@@ -41,17 +41,7 @@ } } -if (make_partition_alloc_standalone) { - partition_alloc_target_type = "component" -} else { - if (is_component_build) { - partition_alloc_target_type = "source_set" - } else { - partition_alloc_target_type = "static_library" - } -} - -target(partition_alloc_target_type, "partition_alloc") { +component("partition_alloc") { sources = [ "address_pool_manager.cc", "address_pool_manager.h", @@ -315,6 +305,10 @@ frameworks += [ "Security.framework" ] } + if (is_component_build && is_apple) { + frameworks += [ "CoreFoundation.framework" ] + } + configs += [ "//build/config/compiler:wexit_time_destructors" ] # Partition alloc is relatively hot (>1% of cycles for users of CrOS). Use speed-focused
diff --git a/base/allocator/partition_allocator/partition_alloc.gni b/base/allocator/partition_allocator/partition_alloc.gni index f57e547..23ce4a11 100644 --- a/base/allocator/partition_allocator/partition_alloc.gni +++ b/base/allocator/partition_allocator/partition_alloc.gni
@@ -3,7 +3,6 @@ # found in the LICENSE file. declare_args() { - make_partition_alloc_standalone = false use_freeslot_bitmap = false }
diff --git a/base/allocator/partition_allocator/starscan/metadata_allocator.cc b/base/allocator/partition_allocator/starscan/metadata_allocator.cc index f6ffca1..5ae3172c 100644 --- a/base/allocator/partition_allocator/starscan/metadata_allocator.cc +++ b/base/allocator/partition_allocator/starscan/metadata_allocator.cc
@@ -6,6 +6,7 @@ #include <cstring> +#include "base/allocator/partition_allocator/partition_alloc_base/component_export.h" #include "base/allocator/partition_allocator/partition_alloc_base/no_destructor.h" namespace partition_alloc::internal { @@ -22,6 +23,7 @@ }; } // namespace +PA_COMPONENT_EXPORT(PARTITION_ALLOC) ThreadSafePartitionRoot& PCScanMetadataAllocator() { static internal::base::NoDestructor<ThreadSafePartitionRoot> allocator( kConfig);
diff --git a/base/allocator/partition_allocator/starscan/metadata_allocator.h b/base/allocator/partition_allocator/starscan/metadata_allocator.h index fd951763..05ac6098 100644 --- a/base/allocator/partition_allocator/starscan/metadata_allocator.h +++ b/base/allocator/partition_allocator/starscan/metadata_allocator.h
@@ -7,11 +7,13 @@ #include <utility> +#include "base/allocator/partition_allocator/partition_alloc_base/component_export.h" #include "base/allocator/partition_allocator/partition_alloc_constants.h" #include "base/allocator/partition_allocator/partition_root.h" namespace partition_alloc::internal { +PA_COMPONENT_EXPORT(PARTITION_ALLOC) ThreadSafePartitionRoot& PCScanMetadataAllocator(); void ReinitPCScanMetadataAllocatorForTesting();
diff --git a/base/stl_util.h b/base/stl_util.h index 72bd0f155..3ef7d089d 100644 --- a/base/stl_util.h +++ b/base/stl_util.h
@@ -14,7 +14,9 @@ #include "base/check.h" #include "base/ranges/algorithm.h" -#include "third_party/abseil-cpp/absl/types/optional.h" +// TODO(https://crbug.com/1356184): Remove this. Temporarily forward to ease the +// migration to the new location. +#include "base/types/optional_util.h" namespace base { @@ -175,25 +177,6 @@ const typename Collection::const_iterator end_; }; -// Helper for returning the optional value's address, or nullptr. -template <class T> -T* OptionalOrNullptr(absl::optional<T>& optional) { - return optional.has_value() ? &optional.value() : nullptr; -} - -template <class T> -const T* OptionalOrNullptr(const absl::optional<T>& optional) { - return optional.has_value() ? &optional.value() : nullptr; -} - -// Helper for creating an optional<T> from a potentially nullptr T*. -template <class T> -absl::optional<T> OptionalFromPtr(const T* value) { - if (value) - return absl::optional<T>(*value); - return absl::nullopt; -} - } // namespace base #endif // BASE_STL_UTIL_H_
diff --git a/base/stl_util_unittest.cc b/base/stl_util_unittest.cc index 60012f0d..edfeaf4 100644 --- a/base/stl_util_unittest.cc +++ b/base/stl_util_unittest.cc
@@ -302,14 +302,5 @@ EXPECT_EQ(expected, lhs); } -TEST(STLUtilTest, OptionalOrNullptr) { - absl::optional<float> optional; - EXPECT_EQ(nullptr, base::OptionalOrNullptr(optional)); - - optional = 0.1f; - EXPECT_EQ(&optional.value(), base::OptionalOrNullptr(optional)); - EXPECT_NE(nullptr, base::OptionalOrNullptr(optional)); -} - } // namespace } // namespace base
diff --git a/base/types/optional_util.h b/base/types/optional_util.h new file mode 100644 index 0000000..6e0a5c07 --- /dev/null +++ b/base/types/optional_util.h
@@ -0,0 +1,69 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef BASE_TYPES_OPTIONAL_UTIL_H_ +#define BASE_TYPES_OPTIONAL_UTIL_H_ + +#include "third_party/abseil-cpp/absl/types/optional.h" + +namespace base { + +// Helper for converting an `absl::optional<T>` to a pointer suitable for +// passing as a function argument: +// +// void MaybeProcessData(const std::string* optional_data); +// +// class Example { +// public: +// void DoSomething() { +// MaybeProcessData(base::OptionalToPtr(data_)); +// } +// +// private: +// absl::optional<std::string> data_; +// }; +// +// Rationale: per the C++ style guide, if `T` would normally be passed by +// reference, the optional version should be passed as `T*`, and *not* as +// `const absl::optional<T>&`. Passing as `const absl::optional<T>&` leads to +// implicit constructions and copies, e.g.: +// +// // BAD: a caller passing a `std::string` implicitly copies the entire string +// // to construct a temporary `absl::optional<std::string>` to use for the +// // function argument. +// void BadMaybeProcessData(const absl::optional<std::string>& optional_data); +// +// For more background, see https://abseil.io/tips/163. +template <class T> +const T* OptionalToPtr(const absl::optional<T>& optional) { + return optional.has_value() ? &optional.value() : nullptr; +} + +template <class T> +T* OptionalToPtr(absl::optional<T>& optional) { + return optional.has_value() ? &optional.value() : nullptr; +} + +// Deprecated synonyms for `OptionalToPtr()`. These were the original names, +// but the naming does not match `OptionalFromPtr`. +// TODO(https://crbug.com/1356184): Remove the deprecated synonyms. +template <class T> +T* OptionalOrNullptr(absl::optional<T>& optional) { + return optional.has_value() ? &optional.value() : nullptr; +} + +template <class T> +const T* OptionalOrNullptr(const absl::optional<T>& optional) { + return optional.has_value() ? &optional.value() : nullptr; +} + +// Helper for creating an `absl::optional<T>` from a `T*` which may be null. +template <class T> +absl::optional<T> OptionalFromPtr(const T* value) { + return value ? absl::optional<T>(*value) : absl::nullopt; +} + +} // namespace base + +#endif // BASE_TYPES_OPTIONAL_UTIL_H_
diff --git a/base/types/optional_util_unittest.cc b/base/types/optional_util_unittest.cc new file mode 100644 index 0000000..699f1ed --- /dev/null +++ b/base/types/optional_util_unittest.cc
@@ -0,0 +1,31 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/types/optional_util.h" + +#include "testing/gtest/include/gtest/gtest.h" + +namespace base { +namespace { + +TEST(OptionalUtilTest, OptionalToPtr) { + absl::optional<float> optional; + EXPECT_EQ(nullptr, OptionalToPtr(optional)); + + optional = 0.1f; + EXPECT_EQ(&optional.value(), OptionalToPtr(optional)); + EXPECT_NE(nullptr, OptionalToPtr(optional)); +} + +TEST(OptionalUtilTest, OptionalFromPtr) { + float* f_ptr = nullptr; + EXPECT_EQ(absl::nullopt, OptionalFromPtr(f_ptr)); + + float f = 0.1f; + absl::optional<float> optional_f(f); + EXPECT_EQ(optional_f, OptionalFromPtr(&f)); +} + +} // namespace +} // namespace base
diff --git a/base/values.cc b/base/values.cc index 4803510..c174f447 100644 --- a/base/values.cc +++ b/base/values.cc
@@ -1502,6 +1502,136 @@ } #endif // BUILDFLAG(ENABLE_BASE_TRACING) +///////////////////// DictAdapterForMigration //////////////////// + +DictAdapterForMigration::DictAdapterForMigration( + const Value::Dict& dict) noexcept + : dict_(dict) {} + +DictAdapterForMigration::DictAdapterForMigration( + const DictionaryValue& dict) noexcept + : dict_(dict.GetDict()) {} + +bool DictAdapterForMigration::empty() const { + return dict_.empty(); +} + +size_t DictAdapterForMigration::size() const { + return dict_.size(); +} + +DictAdapterForMigration::const_iterator DictAdapterForMigration::begin() const { + return dict_.begin(); +} + +DictAdapterForMigration::const_iterator DictAdapterForMigration::cbegin() + const { + return dict_.cbegin(); +} + +DictAdapterForMigration::const_iterator DictAdapterForMigration::end() const { + return dict_.end(); +} + +DictAdapterForMigration::const_iterator DictAdapterForMigration::cend() const { + return dict_.cend(); +} + +bool DictAdapterForMigration::contains(base::StringPiece key) const { + return dict_.contains(key); +} + +Value::Dict DictAdapterForMigration::Clone() const { + return dict_.Clone(); +} + +const Value* DictAdapterForMigration::Find(StringPiece key) const { + return dict_.Find(key); +} + +absl::optional<bool> DictAdapterForMigration::FindBool(StringPiece key) const { + return dict_.FindBool(key); +} + +absl::optional<int> DictAdapterForMigration::FindInt(StringPiece key) const { + return dict_.FindInt(key); +} + +absl::optional<double> DictAdapterForMigration::FindDouble( + StringPiece key) const { + return dict_.FindDouble(key); +} +const std::string* DictAdapterForMigration::FindString(StringPiece key) const { + return dict_.FindString(key); +} + +const Value::BlobStorage* DictAdapterForMigration::FindBlob( + StringPiece key) const { + return dict_.FindBlob(key); +} + +const Value::Dict* DictAdapterForMigration::FindDict(StringPiece key) const { + return dict_.FindDict(key); +} + +const Value::List* DictAdapterForMigration::FindList(StringPiece key) const { + return dict_.FindList(key); +} + +const Value* DictAdapterForMigration::FindByDottedPath(StringPiece path) const { + return dict_.FindByDottedPath(path); +} + +absl::optional<bool> DictAdapterForMigration::FindBoolByDottedPath( + StringPiece path) const { + return dict_.FindBoolByDottedPath(path); +} + +absl::optional<int> DictAdapterForMigration::FindIntByDottedPath( + StringPiece path) const { + return dict_.FindIntByDottedPath(path); +} + +absl::optional<double> DictAdapterForMigration::FindDoubleByDottedPath( + StringPiece path) const { + return dict_.FindDoubleByDottedPath(path); +} + +const std::string* DictAdapterForMigration::FindStringByDottedPath( + StringPiece path) const { + return dict_.FindStringByDottedPath(path); +} + +const Value::BlobStorage* DictAdapterForMigration::FindBlobByDottedPath( + StringPiece path) const { + return dict_.FindBlobByDottedPath(path); +} + +const Value::Dict* DictAdapterForMigration::FindDictByDottedPath( + StringPiece path) const { + return dict_.FindDictByDottedPath(path); +} + +const Value::List* DictAdapterForMigration::FindListByDottedPath( + StringPiece path) const { + return dict_.FindListByDottedPath(path); +} + +std::string DictAdapterForMigration::DebugString() const { + return dict_.DebugString(); +} + +#if BUILDFLAG(ENABLE_BASE_TRACING) +void DictAdapterForMigration::WriteIntoTrace( + perfetto::TracedValue context) const { + return dict_.WriteIntoTrace(std::move(context)); +} +#endif // BUILDFLAG(ENABLE_BASE_TRACING) + +const Value::Dict& DictAdapterForMigration::dict_for_test() const { + return dict_; +} + ///////////////////// DictionaryValue //////////////////// // static
diff --git a/base/values.h b/base/values.h index cb54ede..657d0d1 100644 --- a/base/values.h +++ b/base/values.h
@@ -33,6 +33,7 @@ namespace base { +class DictAdapterForMigration; class DictionaryValue; class ListValue; @@ -1250,6 +1251,75 @@ data_; }; +// DictAdapterForMigration is an adapter class to help the migration of +// base::DictionaryValue to base::Value::Dict. +// +// DictAdapterForMigration mirrors the API of base::Value::Dict, +// and is implicitly constructable from both base::DictionaryValue +// and base::Value::Dict. Currently this is read-only, similar to StringPiece. +// +// To migrate a function that takes a base::DictionaryValue, change the +// signature to take DictAdapterForMigration instead, and update the +// function body to use the Dict::Value API. +// The call sites can be left unchanged and migrated later. +// +// Note that DictAdapterForMigration is intended as a shim to help migrations, +// and will go away with base::DictionaryValue. +class BASE_EXPORT GSL_POINTER DictAdapterForMigration { + public: + using iterator = detail::dict_iterator; + using const_iterator = detail::const_dict_iterator; + + DictAdapterForMigration() = delete; + + // NOLINTNEXTLINE(google-explicit-constructor) + DictAdapterForMigration(const Value::Dict&) noexcept; + // NOLINTNEXTLINE(google-explicit-constructor) + DictAdapterForMigration(const DictionaryValue&) noexcept; + + bool empty() const; + size_t size() const; + + const_iterator begin() const; + const_iterator cbegin() const; + const_iterator end() const; + const_iterator cend() const; + + bool contains(base::StringPiece key) const; + + Value::Dict Clone() const; + + const Value* Find(StringPiece key) const; + absl::optional<bool> FindBool(StringPiece key) const; + absl::optional<int> FindInt(StringPiece key) const; + absl::optional<double> FindDouble(StringPiece key) const; + const std::string* FindString(StringPiece key) const; + const Value::BlobStorage* FindBlob(StringPiece key) const; + const Value::Dict* FindDict(StringPiece key) const; + const Value::List* FindList(StringPiece key) const; + + const Value* FindByDottedPath(StringPiece path) const; + + absl::optional<bool> FindBoolByDottedPath(StringPiece path) const; + absl::optional<int> FindIntByDottedPath(StringPiece path) const; + absl::optional<double> FindDoubleByDottedPath(StringPiece path) const; + const std::string* FindStringByDottedPath(StringPiece path) const; + const Value::BlobStorage* FindBlobByDottedPath(StringPiece path) const; + const Value::Dict* FindDictByDottedPath(StringPiece path) const; + const Value::List* FindListByDottedPath(StringPiece path) const; + + std::string DebugString() const; + +#if BUILDFLAG(ENABLE_BASE_TRACING) + void WriteIntoTrace(perfetto::TracedValue) const; +#endif // BUILDFLAG(ENABLE_BASE_TRACING) + + const Value::Dict& dict_for_test() const; + + private: + const Value::Dict& dict_; +}; + // DictionaryValue provides a key-value dictionary with (optional) "path" // parsing for recursive access; see the comment at the top of the file. Keys // are std::string's and should be UTF-8 encoded.
diff --git a/base/values_unittest.cc b/base/values_unittest.cc index 6056899..de93a76 100644 --- a/base/values_unittest.cc +++ b/base/values_unittest.cc
@@ -2400,6 +2400,78 @@ } #endif // BUILDFLAG(ENABLE_BASE_TRACING) +TEST(DictAdapterForMigrationTest, ImplicitConstruction) { + { + Value::Dict dict; + dict.Set("hello", "world"); + DictAdapterForMigration a = dict; + EXPECT_EQ(&dict, &a.dict_for_test()); + } + { + DictionaryValue dict; + dict.SetString("hello", "world"); + DictAdapterForMigration v = dict; + EXPECT_EQ(&dict.GetDict(), &v.dict_for_test()); + } +} + +TEST(DictAdapterForMigrationTest, BasicFunctions) { + Value::Dict dict; + DictAdapterForMigration a = dict; + + EXPECT_TRUE(a.empty()); + EXPECT_EQ(a.size(), 0u); + + dict.Set("hello", "world"); + EXPECT_FALSE(a.empty()); + EXPECT_EQ(a.size(), 1u); + + EXPECT_EQ(dict.cbegin(), a.begin()); + EXPECT_EQ(dict.cend(), a.end()); + EXPECT_EQ(dict.cbegin(), a.cbegin()); + EXPECT_EQ(dict.cend(), a.cend()); + + EXPECT_TRUE(a.contains("hello")); + EXPECT_FALSE(a.contains("world")); + + EXPECT_EQ(a.Clone(), dict); + + EXPECT_EQ(a.DebugString(), dict.DebugString()); +} + +TEST(DictAdapterForMigrationTest, Find) { + Value::Dict dict; + dict.Set("null", Value()); + dict.Set("bool", true); + dict.Set("int", 2); + dict.Set("double", 3.0); + dict.Set("string", std::string("4")); + dict.Set("blob", Value(Value::BlobStorage())); + dict.Set("list", Value::List()); + dict.Set("dict", Value::Dict()); + DictAdapterForMigration a = dict; + + EXPECT_EQ(a.Find("n/a"), nullptr); + EXPECT_EQ(*a.Find("null"), Value()); + EXPECT_EQ(a.FindBool("bool"), true); + EXPECT_EQ(a.FindInt("int"), 2); + EXPECT_EQ(a.FindDouble("double"), 3.0); + EXPECT_EQ(*a.FindString("string"), "4"); + EXPECT_EQ(*a.FindBlob("blob"), Value::BlobStorage()); + EXPECT_EQ(*a.FindList("list"), Value::List()); + EXPECT_EQ(*a.FindDict("dict"), Value::Dict()); + + EXPECT_EQ(a.FindByDottedPath("n/a"), nullptr); + EXPECT_EQ(*a.FindByDottedPath("null"), Value()); + EXPECT_EQ(a.FindBoolByDottedPath("bool"), true); + EXPECT_EQ(a.FindIntByDottedPath("int"), 2); + EXPECT_EQ(a.FindDoubleByDottedPath("double"), 3.0); + EXPECT_EQ(*a.FindStringByDottedPath("string"), "4"); + EXPECT_EQ(*a.FindBlobByDottedPath("blob"), Value::BlobStorage()); + EXPECT_EQ(*a.FindListByDottedPath("list"), Value::List()); + EXPECT_EQ(*a.FindDictByDottedPath("dict"), Value::Dict()); +} + TEST(ValueViewTest, BasicConstruction) { { ValueView v = true;
diff --git a/chrome/VERSION b/chrome/VERSION index 40561fb..a974ea03 100644 --- a/chrome/VERSION +++ b/chrome/VERSION
@@ -1,4 +1,4 @@ MAJOR=107 MINOR=0 -BUILD=5260 +BUILD=5261 PATCH=0
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index e9bdc60d..3065270 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn
@@ -821,6 +821,7 @@ "//chrome/browser/password_entry_edit/android/internal:java", "//chrome/browser/tabmodel/internal:java", "//chrome/browser/touch_to_fill/android/internal:java", + "//chrome/browser/touch_to_fill/payments/android/internal:java", "//chrome/browser/ui/android/appmenu/internal:java", "//chrome/browser/ui/android/autofill/internal:java", "//chrome/browser/ui/android/fast_checkout/internal:java", @@ -873,6 +874,7 @@ "//chrome/browser/segmentation_platform:jni_headers", "//chrome/browser/tab:jni_headers", "//chrome/browser/touch_to_fill/android:jni_headers", + "//chrome/browser/touch_to_fill/payments/android:jni_headers", "//chrome/browser/ui/android/fast_checkout:jni_headers", "//chrome/browser/ui/android/favicon:jni_headers", "//chrome/browser/ui/android/logo:jni_headers",
diff --git a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantFormActionTest.java b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantFormActionTest.java index 429f11a..1c34a734f 100644 --- a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantFormActionTest.java +++ b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantFormActionTest.java
@@ -76,9 +76,11 @@ import org.chromium.chrome.browser.autofill_assistant.proto.SupportedScriptProto; import org.chromium.chrome.browser.autofill_assistant.proto.SupportedScriptProto.PresentationProto; import org.chromium.chrome.browser.customtabs.CustomTabActivityTestRule; +import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.flags.ChromeSwitches; import org.chromium.chrome.browser.util.ChromeAccessibilityUtil; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; +import org.chromium.chrome.test.util.browser.Features.EnableFeatures; import org.chromium.components.autofill_assistant.R; import org.chromium.content_public.browser.test.util.TestThreadUtils; @@ -578,7 +580,13 @@ @Test @MediumTest @DisableIf.Build(sdk_is_less_than = 21) + // When both START_SURFACE_ANDROID and TAB_GROUPS_CONTINUATION_ANDROID are enabled, changing + // accessibility status won't recreate ChromeTabbedActivity. + @EnableFeatures({ChromeFeatureList.START_SURFACE_ANDROID, + ChromeFeatureList.TAB_GROUPS_CONTINUATION_ANDROID}) + // clang-format off public void testCounterExpandDisabledWithAccessibility() { + // clang-format on startTestCounterExpansion(true); waitUntilViewMatchesCondition(withText("Continue"), isCompletelyDisplayed());
diff --git a/chrome/android/java/res/layout/custom_tabs_handle_view.xml b/chrome/android/java/res/layout/custom_tabs_handle_view.xml index 72ae3c1..133fb1c 100644 --- a/chrome/android/java/res/layout/custom_tabs_handle_view.xml +++ b/chrome/android/java/res/layout/custom_tabs_handle_view.xml
@@ -16,6 +16,7 @@ android:layout_height="@dimen/custom_tabs_handle_height" android:background="@drawable/custom_tabs_handle_view_shape"> <ImageView + android:id="@+id/drag_handlebar" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="bottom|center_horizontal"
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabRootUiCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabRootUiCoordinator.java index 87dd644..3d7f91b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabRootUiCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabRootUiCoordinator.java
@@ -252,6 +252,7 @@ intentDataProvider.getInitialActivityHeight(), intentDataProvider.getColorProvider().getNavigationBarColor(), intentDataProvider.getColorProvider().getNavigationBarDividerColor(), + intentDataProvider.isPartialCustomTabFixedHeight(), CustomTabsConnection.getInstance(), intentDataProvider.getSession(), mActivityLifecycleDispatcher); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabHeightStrategy.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabHeightStrategy.java index aec279e..bca31ad 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabHeightStrategy.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabHeightStrategy.java
@@ -20,14 +20,15 @@ public class CustomTabHeightStrategy { public static CustomTabHeightStrategy createStrategy(Activity activity, @Px int initialHeight, Integer navigationBarColor, Integer navigationBarDividerColor, - CustomTabsConnection connection, @Nullable CustomTabsSessionToken session, + boolean isPartialCustomTabFixedHeight, CustomTabsConnection connection, + @Nullable CustomTabsSessionToken session, ActivityLifecycleDispatcher lifecycleDispatcher) { if (initialHeight <= 0) { return new CustomTabHeightStrategy(); } return new PartialCustomTabHeightStrategy(activity, initialHeight, navigationBarColor, - navigationBarDividerColor, + navigationBarDividerColor, isPartialCustomTabFixedHeight, size -> connection.onResized(session, size), lifecycleDispatcher); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java index c84ba2d1..08c91e9 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java
@@ -183,6 +183,12 @@ public static final String EXTRA_CLOSE_BUTTON_POSITION = "androidx.browser.customtabs.extra.CLOSE_BUTTON_POSITION"; + /** + * Extra that, if set, disallows the resizing of the Partial Custom Tab. + */ + public static final String EXTRA_PARTIAL_CUSTOM_TAB_FIXED_HEIGHT = + "androidx.browser.customtabs.extra.PARTIAL_CUSTOM_TAB_FIXED_HEIGHT"; + private static final String DEFAULT_POLICY_PARAM_NAME = "default_policy"; private static final String DEFAULT_POLICY_USE_DENYLIST = "use-denylist"; private static final String DEFAULT_POLICY_USE_ALLOWLIST = "use-allowlist"; @@ -250,6 +256,8 @@ private final @Px int mInitialActivityHeight; private final @Px int mPartialTabToolbarCornerRadius; + private final boolean mIsPartialCustomTabFixedHeight; + /** * Add extras to customize menu items for opening Reader Mode UI custom tab from Chrome. */ @@ -401,6 +409,9 @@ } else { mPartialTabToolbarCornerRadius = defaultToolbarCornerRadius; } + + mIsPartialCustomTabFixedHeight = IntentUtils.safeGetBooleanExtra( + intent, EXTRA_PARTIAL_CUSTOM_TAB_FIXED_HEIGHT, false); } private void updateExtraMenuItems(List<Bundle> menuItems) { @@ -914,4 +925,9 @@ public int getPartialTabToolbarCornerRadius() { return mPartialTabToolbarCornerRadius; } + + @Override + public boolean isPartialCustomTabFixedHeight() { + return mIsPartialCustomTabFixedHeight; + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/PartialCustomTabHeightStrategy.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/PartialCustomTabHeightStrategy.java index 8dc5ebc..74875b84 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/PartialCustomTabHeightStrategy.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/PartialCustomTabHeightStrategy.java
@@ -106,6 +106,7 @@ private final AnimatorListener mSpinnerFadeoutAnimatorListener; private final int mCachedHandleHeight; private boolean mWindowAboveNavbar; + private final boolean mIsFixedHeight; private @Px int mInitialHeight; private ValueAnimator mAnimator; private int mShadowOffset; @@ -289,7 +290,7 @@ mTargetStatus = HeightStatus.INITIAL_HEIGHT; } } else { // Move down - // Prevents skipping intial state when swiping from the top. + // Prevents skipping initial state when swiping from the top. if (mStatus == HeightStatus.TOP) finalY = Math.min(initialY, finalY); if (Math.abs(initialY - finalY) < Math.abs(finalY - bottomY)) { @@ -310,7 +311,7 @@ } public PartialCustomTabHeightStrategy(Activity activity, @Px int initialHeight, - Integer navigationBarColor, Integer navigationBarDividerColor, + Integer navigationBarColor, Integer navigationBarDividerColor, boolean isFixedHeight, OnResizedCallback onResizedCallback, ActivityLifecycleDispatcher lifecycleDispatcher) { mWindowAboveNavbar = ChromeFeatureList.sCctResizableWindowAboveNavbar.isEnabled(); mActivity = activity; @@ -318,6 +319,7 @@ mInitialHeight = MathUtils.clamp( initialHeight, mMaxHeight, (int) (mMaxHeight * MINIMAL_HEIGHT_RATIO)); mDisplayHeight = getDisplayHeight(); + mIsFixedHeight = isFixedHeight; mOnResizedCallback = onResizedCallback; // When the flag is enabled, we make the max snap point 10% shorter, so it will only occupy // 90% of the height. @@ -610,6 +612,11 @@ private void updateDragBarVisibility() { View dragBar = mActivity.findViewById(R.id.drag_bar); if (dragBar != null) dragBar.setVisibility(isFullHeight() ? View.GONE : View.VISIBLE); + + View dragHandlebar = mActivity.findViewById(R.id.drag_handlebar); + if (dragHandlebar != null) { + dragHandlebar.setVisibility(isFixedHeight() ? View.GONE : View.VISIBLE); + } } private void updateShadowOffset() { @@ -641,6 +648,10 @@ return mOrientation == Configuration.ORIENTATION_LANDSCAPE || mIsInMultiWindowMode; } + private boolean isFixedHeight() { + return mIsFixedHeight; + } + private void updateWindowPos(@Px int y) { // Do not allow the Window to go above the minimum threshold capped by the status // bar and (optionally) the 90%-height adjustment. @@ -650,6 +661,10 @@ WindowManager.LayoutParams attrs = window.getAttributes(); if (attrs.y == y) return; + // If the tab is not resizable then dragging it higher than the initial height will not be + // allowed. The tab can still be dragged down in order to be closed. + if (isFixedHeight() && y < initialY()) return; + attrs.y = y; window.setAttributes(attrs);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/findinpage/FindToolbar.java b/chrome/android/java/src/org/chromium/chrome/browser/findinpage/FindToolbar.java index 7360c3b..eeb3d73 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/findinpage/FindToolbar.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/findinpage/FindToolbar.java
@@ -142,6 +142,7 @@ } else if (event.getAction() == KeyEvent.ACTION_UP) { getKeyDispatcherState().handleUpEvent(event); if (event.isTracking() && !event.isCanceled()) { + BackPressManager.record(Type.FIND_TOOLBAR); mFindToolbar.deactivate(); return true; }
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 1471b00..51c99d4 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
@@ -371,6 +371,13 @@ } } + public void destroy() { + if (mCurrentConstraintDelegate != null) { + mCurrentConstraintDelegate.removeObserver(this); + mCurrentConstraintDelegate = null; + } + } + @Override public void onResult(Integer result) { set(result); @@ -1620,6 +1627,8 @@ mActivity.unregisterComponentCallbacks(mComponentCallbacks); mComponentCallbacks = null; ChromeAccessibilityUtil.get().removeObserver(this); + + mConstraintsProxy.destroy(); } /**
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/page_info/PageInfoViewTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/page_info/PageInfoViewTest.java index 7e405ef3..089ce04 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/page_info/PageInfoViewTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/page_info/PageInfoViewTest.java
@@ -73,6 +73,7 @@ import org.chromium.chrome.test.ChromeTabbedActivityTestRule; import org.chromium.chrome.test.batch.BlankCTATabInitialStateRule; import org.chromium.chrome.test.util.browser.Features; +import org.chromium.chrome.test.util.browser.Features.EnableFeatures; import org.chromium.components.browser_ui.site_settings.ContentSettingException; import org.chromium.components.browser_ui.site_settings.WebsitePreferenceBridge; import org.chromium.components.browser_ui.site_settings.WebsitePreferenceBridgeJni; @@ -763,7 +764,13 @@ */ @Test @MediumTest + // When both START_SURFACE_ANDROID and TAB_GROUPS_CONTINUATION_ANDROID are enabled, changing + // accessibility status won't recreate ChromeTabbedActivity. + @EnableFeatures({ChromeFeatureList.START_SURFACE_ANDROID, + ChromeFeatureList.TAB_GROUPS_CONTINUATION_ANDROID}) + // clang-format off public void testCloseButton() { + // clang-format on TestThreadUtils.runOnUiThreadBlocking( () -> { ChromeAccessibilityUtil.get().setAccessibilityEnabledForTesting(true); }); loadUrlAndOpenPageInfo(mTestServerRule.getServer().getURL(sSimpleHtml));
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/undo_tab_close_snackbar/UndoBarControllerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/undo_tab_close_snackbar/UndoBarControllerTest.java index 7443fc4..1e89976 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/undo_tab_close_snackbar/UndoBarControllerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/undo_tab_close_snackbar/UndoBarControllerTest.java
@@ -28,6 +28,7 @@ import org.chromium.chrome.test.ChromeTabbedActivityTestRule; import org.chromium.chrome.test.util.ChromeTabUtils; import org.chromium.chrome.test.util.browser.Features; +import org.chromium.chrome.test.util.browser.Features.EnableFeatures; import org.chromium.content_public.browser.test.util.TestThreadUtils; import org.chromium.ui.test.util.UiDisableIf; @@ -141,7 +142,13 @@ @Test @SmallTest + // When both START_SURFACE_ANDROID and TAB_GROUPS_CONTINUATION_ANDROID are enabled, changing + // accessibility status won't recreate ChromeTabbedActivity. + @EnableFeatures({ChromeFeatureList.START_SURFACE_ANDROID, + ChromeFeatureList.TAB_GROUPS_CONTINUATION_ANDROID}) + // clang-format off public void testUndoSnackbarDisabled_AccessibilityEnabled() throws Exception { + // clang-format on TestThreadUtils.runOnUiThreadBlocking( () -> ChromeAccessibilityUtil.get().setAccessibilityEnabledForTesting(true)); ChromeTabUtils.newTabFromMenu(
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProviderTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProviderTest.java index 7e70c61..dacedf2 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProviderTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProviderTest.java
@@ -292,6 +292,25 @@ } @Test + public void partialCustomTabFixedHeight_isSetToTrue() { + Intent intent = new Intent().putExtra( + CustomTabIntentDataProvider.EXTRA_PARTIAL_CUSTOM_TAB_FIXED_HEIGHT, true); + + CustomTabIntentDataProvider dataProvider = + new CustomTabIntentDataProvider(intent, mContext, COLOR_SCHEME_LIGHT); + + assertTrue(dataProvider.isPartialCustomTabFixedHeight()); + } + + @Test + public void partialCustomTabFixedHeight_defaultFalse() { + CustomTabIntentDataProvider dataProvider = + new CustomTabIntentDataProvider(new Intent(), mContext, COLOR_SCHEME_LIGHT); + + assertFalse(dataProvider.isPartialCustomTabFixedHeight()); + } + + @Test public void testGetReferrerPackageName() { assertEquals("extra.activity.referrer", CustomTabIntentDataProvider.getReferrerPackageName(
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/PartialCustomTabHeightStrategyTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/PartialCustomTabHeightStrategyTest.java index 1cbe486..a979cfd4 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/PartialCustomTabHeightStrategyTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/PartialCustomTabHeightStrategyTest.java
@@ -148,6 +148,8 @@ @Mock private View mDragBar; @Mock + private View mDragHandlebar; + @Mock private CommandLine mCommandLine; private Context mContext; @@ -167,6 +169,7 @@ when(mActivity.findViewById(R.id.custom_tabs_handle_view_stub)).thenReturn(mHandleViewStub); when(mActivity.findViewById(R.id.custom_tabs_handle_view)).thenReturn(mHandleView); when(mActivity.findViewById(R.id.drag_bar)).thenReturn(mDragBar); + when(mActivity.findViewById(R.id.drag_handlebar)).thenReturn(mDragHandlebar); when(mActivity.findViewById(R.id.coordinator)).thenReturn(mCoordinatorLayout); when(mActivity.findViewById(android.R.id.content)).thenReturn(mContentFrame); when(mHandleView.getLayoutParams()).thenReturn(mLayoutParams); @@ -224,8 +227,13 @@ } private PartialCustomTabHeightStrategy createPcctAtHeight(int heightPx) { - PartialCustomTabHeightStrategy pcct = new PartialCustomTabHeightStrategy( - mActivity, heightPx, null, null, mOnResizedCallback, mActivityLifecycleDispatcher); + return createPcctAtHeight(heightPx, false); + } + + private PartialCustomTabHeightStrategy createPcctAtHeight(int heightPx, boolean isFixedHeight) { + PartialCustomTabHeightStrategy pcct = + new PartialCustomTabHeightStrategy(mActivity, heightPx, null, null, isFixedHeight, + mOnResizedCallback, mActivityLifecycleDispatcher); pcct.setWindowAboveNavbarForTesting(mWindowAboveNavbar); pcct.setMockViewForTesting( mNavbar, mSpinnerView, mSpinner, mToolbarView, mToolbarCoordinator); @@ -659,6 +667,68 @@ assertTabIsFullHeight(mAttributeResults.get(length - 1)); } + @Test + public void moveUpFixedHeight() { + PartialCustomTabHeightStrategy strategy = createPcctAtHeight(500, true); + verifyWindowFlagsSet(); + + assertEquals(1, mAttributeResults.size()); + assertTabIsAtInitialPos(mAttributeResults.get(0)); + + PartialCustomTabHandleStrategy handleStrategy = + strategy.new PartialCustomTabHandleStrategy(null); + + long timestamp = SystemClock.uptimeMillis(); + + // Try to drag up and verify that the location does not change. + actionDown(handleStrategy, timestamp, INITIAL_HEIGHT - 100); + actionMove(handleStrategy, timestamp, INITIAL_HEIGHT - 250); + assertTabIsAtInitialPos(mAttributeResults.get(0)); + } + + @Test + public void moveDownFixedHeight() { + PartialCustomTabHeightStrategy strategy = createPcctAtHeight(500, true); + verifyWindowFlagsSet(); + + assertEquals(1, mAttributeResults.size()); + assertTabIsAtInitialPos(mAttributeResults.get(0)); + + PartialCustomTabHandleStrategy handleStrategy = + strategy.new PartialCustomTabHandleStrategy(null); + + // Try to drag down and check that it returns to the initial height. + assertTabIsAtInitialPos(dragTab(handleStrategy, 1500, 1550, 1600)); + } + + @Test + public void moveDownToDismissFixedHeight() { + PartialCustomTabHeightStrategy strategy = createPcctAtHeight(500, true); + verifyWindowFlagsSet(); + + assertEquals(1, mAttributeResults.size()); + assertTabIsAtInitialPos(mAttributeResults.get(0)); + + PartialCustomTabHandleStrategy handleStrategy = + strategy.new PartialCustomTabHandleStrategy(null); + final boolean[] closed = {false}; + handleStrategy.setCloseClickHandler(() -> closed[0] = true); + + dragTab(handleStrategy, INITIAL_HEIGHT, DEVICE_HEIGHT - 400); + assertTrue("Close click handler should be called.", closed[0]); + } + + @Test + public void dragHandlebarInvisibleFixedHeight() { + PartialCustomTabHeightStrategy strategy = createPcctAtHeight(500, true); + verifyWindowFlagsSet(); + + assertEquals(1, mAttributeResults.size()); + assertTabIsAtInitialPos(mAttributeResults.get(0)); + + verify(mDragHandlebar).setVisibility(View.GONE); + } + private void verifyWindowFlagsSet() { verify(mWindow).addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL); verify(mWindow).clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
diff --git a/chrome/app/os_settings_strings.grdp b/chrome/app/os_settings_strings.grdp index 4ef7df3c..c58ef35 100644 --- a/chrome/app/os_settings_strings.grdp +++ b/chrome/app/os_settings_strings.grdp
@@ -1667,6 +1667,15 @@ <message name="IDS_SETTINGS_GUEST_OS_SHARED_USB_DEVICES_REASSIGN" desc="Confirmation explaining to users that reassigning a USB device from being attached from one VM to another could cause errors."> "<ph name="USB_DEVICE_NAME">$1<ex>Nexus 5</ex></ph>" is in use. Reassigning the device while it's in use could cause errors. Are you sure you want to continue? </message> + <message name="IDS_SETTINGS_GUEST_OS_SHARED_USB_DEVICES_TABLE_TITLE" desc="Title of the table containing shared USB devices."> + USB devices + </message> + <message name="IDS_SETTINGS_GUEST_OS_SHARED_USB_DEVICES_ADD_TITLE" desc="Dialog title for adding shared USB devices."> + Add USB device + </message> + <message name="IDS_SETTINGS_GUEST_OS_SHARED_USB_DEVICES_NONE_ATTACHED" desc="Indicates there are no USB devices currently shared."> + No USB devices are attached. + </message> <!-- Crostini --> <message name="IDS_SETTINGS_CROSTINI_TITLE" desc="The title of Crostini section. It is meant to be used by software developers."> @@ -3364,7 +3373,7 @@ Hide sensitive content </message> <message name="IDS_SETTINGS_PEOPLE_ENABLE_SCREENLOCK" desc="The text on the checkbox to enable screenlocker for current user. Lock will happen in the device goes into sleep mode from being idle, or when laptop lid or detachable cover is closed"> - Lock when sleeping or when lid is closed + Lock when sleeping or lid is closed </message> <message name="IDS_SETTINGS_PEOPLE_SCREEN_LOCK_ENABLE_TITLE" desc="The title on the toggle to enable screen lock for current user."> Screen lock
diff --git a/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_GUEST_OS_SHARED_USB_DEVICES_ADD_TITLE.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_GUEST_OS_SHARED_USB_DEVICES_ADD_TITLE.png.sha1 new file mode 100644 index 0000000..69ef7c26 --- /dev/null +++ b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_GUEST_OS_SHARED_USB_DEVICES_ADD_TITLE.png.sha1
@@ -0,0 +1 @@ +801a89586e03501d2fddc0721acea09f3d292e39 \ No newline at end of file
diff --git a/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_GUEST_OS_SHARED_USB_DEVICES_NONE_ATTACHED.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_GUEST_OS_SHARED_USB_DEVICES_NONE_ATTACHED.png.sha1 new file mode 100644 index 0000000..17648f7d --- /dev/null +++ b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_GUEST_OS_SHARED_USB_DEVICES_NONE_ATTACHED.png.sha1
@@ -0,0 +1 @@ +6a543a1dceffc16787b3038e1fe5f008aaafb481 \ No newline at end of file
diff --git a/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_GUEST_OS_SHARED_USB_DEVICES_TABLE_TITLE.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_GUEST_OS_SHARED_USB_DEVICES_TABLE_TITLE.png.sha1 new file mode 100644 index 0000000..69ef7c26 --- /dev/null +++ b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_GUEST_OS_SHARED_USB_DEVICES_TABLE_TITLE.png.sha1
@@ -0,0 +1 @@ +801a89586e03501d2fddc0721acea09f3d292e39 \ No newline at end of file
diff --git a/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_PEOPLE_ENABLE_SCREENLOCK.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_PEOPLE_ENABLE_SCREENLOCK.png.sha1 index 4b7518f..78790db7 100644 --- a/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_PEOPLE_ENABLE_SCREENLOCK.png.sha1 +++ b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_PEOPLE_ENABLE_SCREENLOCK.png.sha1
@@ -1 +1 @@ -b130223a56f110c61b974d5e7cf7a99b8b30d3c0 \ No newline at end of file +a809f74d9a465518cb776b1ddd53d83a1868a066 \ No newline at end of file
diff --git a/chrome/app/vector_icons/BUILD.gn b/chrome/app/vector_icons/BUILD.gn index 8bf4bd3..483c557 100644 --- a/chrome/app/vector_icons/BUILD.gn +++ b/chrome/app/vector_icons/BUILD.gn
@@ -224,7 +224,6 @@ "notification_google.icon", "notification_image.icon", "notification_installed.icon", - "notification_linux.icon", "notification_messages.icon", "notification_mobile_data.icon", "notification_mobile_data_off.icon",
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index a3bc81d..fb18fec6 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -3259,11 +3259,8 @@ "sync/trusted_vault_client_android.h", "tab/web_contents_state.cc", "tab/web_contents_state.h", - "touch_to_fill/payments/android/touch_to_fill_credit_card_view_impl.cc", - "touch_to_fill/payments/android/touch_to_fill_credit_card_view_impl.h", - "touch_to_fill/payments/touch_to_fill_credit_card_controller.cc", - "touch_to_fill/payments/touch_to_fill_credit_card_controller.h", - "touch_to_fill/payments/touch_to_fill_credit_card_view.h", + "touch_to_fill/payments/android/touch_to_fill_credit_card_controller.cc", + "touch_to_fill/payments/android/touch_to_fill_credit_card_controller.h", "touch_to_fill/touch_to_fill_controller.cc", "touch_to_fill/touch_to_fill_controller.h", "touch_to_fill/touch_to_fill_webauthn_credential.cc", @@ -3343,6 +3340,7 @@ "//chrome/browser/signin/services/android:jni_headers", "//chrome/browser/sync/android:jni_headers", "//chrome/browser/tab:jni_headers", + "//chrome/browser/touch_to_fill/payments/android:public", "//chrome/browser/ui/android/layouts:android", "//chrome/browser/ui/webui/explore_sites_internals:mojo_bindings", "//chrome/browser/ui/webui/feed_internals:mojo_bindings",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 5d5cb6b..d9fcdbf 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -2784,6 +2784,8 @@ "borealis-disk-management"; constexpr char kBorealisForceBetaClientInternalName[] = "borealis-force-beta-client"; +constexpr char kBorealisForceDoubleScaleInternalName[] = + "borealis-force-double-scale"; constexpr char kBorealisLinuxModeInternalName[] = "borealis-linux-mode"; // This differs slightly from its symbol's name since "enabled" is used // internally to refer to whether borealis is installed or not. @@ -3639,6 +3641,10 @@ {"bluetooth-coredump", flag_descriptions::kBluetoothCoredumpName, flag_descriptions::kBluetoothCoredumpDescription, kOsCrOS, FEATURE_VALUE_TYPE(chromeos::bluetooth::features::kBluetoothCoredump)}, + {"robust-audio-device-select-logic", + flag_descriptions::kRobustAudioDeviceSelectLogicName, + flag_descriptions::kRobustAudioDeviceSelectLogicDescription, kOsCrOS, + FEATURE_VALUE_TYPE(chromeos::features::kRobustAudioDeviceSelectLogic)}, {"bluetooth-use-floss", flag_descriptions::kBluetoothUseFlossName, flag_descriptions::kBluetoothUseFlossDescription, kOsCrOS, FEATURE_VALUE_TYPE(floss::features::kFlossEnabled)}, @@ -8283,6 +8289,10 @@ flag_descriptions::kBorealisForceBetaClientName, flag_descriptions::kBorealisForceBetaClientDescription, kOsCrOS, FEATURE_VALUE_TYPE(ash::features::kBorealisForceBetaClient)}, + {kBorealisForceDoubleScaleInternalName, + flag_descriptions::kBorealisForceDoubleScaleName, + flag_descriptions::kBorealisForceDoubleScaleDescription, kOsCrOS, + FEATURE_VALUE_TYPE(ash::features::kBorealisForceDoubleScale)}, {kBorealisLinuxModeInternalName, flag_descriptions::kBorealisLinuxModeName, flag_descriptions::kBorealisLinuxModeDescription, kOsCrOS, FEATURE_VALUE_TYPE(ash::features::kBorealisLinuxMode)}, @@ -9286,6 +9296,10 @@ return !base::FeatureList::IsEnabled(features::kBorealis); } + if (!strcmp(kBorealisForceDoubleScaleInternalName, entry.internal_name)) { + return !base::FeatureList::IsEnabled(features::kBorealis); + } + if (!strcmp(kBorealisLinuxModeInternalName, entry.internal_name)) { return !base::FeatureList::IsEnabled(features::kBorealis); }
diff --git a/chrome/browser/android/browserservices/intents/java/src/org/chromium/chrome/browser/browserservices/intents/BrowserServicesIntentDataProvider.java b/chrome/browser/android/browserservices/intents/java/src/org/chromium/chrome/browser/browserservices/intents/BrowserServicesIntentDataProvider.java index 9e4f0b7c..cac1e9321 100644 --- a/chrome/browser/android/browserservices/intents/java/src/org/chromium/chrome/browser/browserservices/intents/BrowserServicesIntentDataProvider.java +++ b/chrome/browser/android/browserservices/intents/java/src/org/chromium/chrome/browser/browserservices/intents/BrowserServicesIntentDataProvider.java
@@ -495,4 +495,11 @@ public @Px int getPartialTabToolbarCornerRadius() { return 0; } + + /** + * Returns false as by default PCCT is resizable. + */ + public boolean isPartialCustomTabFixedHeight() { + return false; + } }
diff --git a/chrome/browser/android/examples/custom_tabs_client/BUILD.gn b/chrome/browser/android/examples/custom_tabs_client/BUILD.gn index 9d4a7664..1bf94bc 100644 --- a/chrome/browser/android/examples/custom_tabs_client/BUILD.gn +++ b/chrome/browser/android/examples/custom_tabs_client/BUILD.gn
@@ -72,6 +72,7 @@ deps = [ ":chrome_tabs_client_example_apk_resources", + "//third_party/android_deps:com_android_support_support_annotations_java", "//third_party/android_deps:material_design_java", "//third_party/androidx:androidx_annotation_annotation_java", "//third_party/androidx:androidx_appcompat_appcompat_java",
diff --git a/chrome/browser/android/examples/custom_tabs_client/src/java/org/chromium/customtabsclient/MainActivity.java b/chrome/browser/android/examples/custom_tabs_client/src/java/org/chromium/customtabsclient/MainActivity.java index c0b30f2..e3224ed5 100644 --- a/chrome/browser/android/examples/custom_tabs_client/src/java/org/chromium/customtabsclient/MainActivity.java +++ b/chrome/browser/android/examples/custom_tabs_client/src/java/org/chromium/customtabsclient/MainActivity.java
@@ -13,12 +13,16 @@ import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Color; +import android.graphics.Rect; import android.media.MediaPlayer; import android.net.Uri; +import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.Looper; +import android.support.annotation.Px; import android.text.TextUtils; +import android.util.DisplayMetrics; import android.util.Log; import android.util.Pair; import android.view.LayoutInflater; @@ -28,6 +32,7 @@ import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.Button; +import android.widget.CheckBox; import android.widget.EditText; import android.widget.SeekBar; import android.widget.SeekBar.OnSeekBarChangeListener; @@ -59,6 +64,10 @@ extends AppCompatActivity implements OnClickListener, ServiceConnectionCallback { private static final String TAG = "CustomTabsClientExample"; private static final String TOOLBAR_COLOR = "#ef6c00"; + /** + * Minimal height the bottom sheet CCT should show is half of the display height. + */ + private static final float MINIMAL_HEIGHT_RATIO = 0.5f; private EditText mEditText; private CustomTabsSession mCustomTabsSession; @@ -75,6 +84,11 @@ private MaterialButtonToggleGroup mCloseButtonPositionToggle; private TextView mToolbarCornerRadiusLabel; private SeekBar mToolbarCornerRadiusSlider; + private CheckBox mPcctResizableCheckbox; + private TextView mPcctInitialHeightLabel; + private SeekBar mPcctInitialHeightSlider; + private @Px int mMaxHeight; + private @Px int mInitialHeight; /** * Once per second, asks the framework for the process importance, and logs any change. @@ -169,6 +183,26 @@ @Override public void onStopTrackingTouch(SeekBar seekBar) {} }); + mPcctResizableCheckbox = findViewById(R.id.pcct_resizable_checkbox); + mMaxHeight = getMaximumPossibleHeight(); + mInitialHeight = (int) (mMaxHeight * MINIMAL_HEIGHT_RATIO); + mPcctInitialHeightSlider = findViewById(R.id.pcct_initial_height_slider); + mPcctInitialHeightLabel = findViewById(R.id.pcct_initial_height_slider_label); + mPcctInitialHeightSlider.setMax(mMaxHeight); + mPcctInitialHeightSlider.setProgress(mInitialHeight); + mPcctInitialHeightLabel.setText(getString(R.string.px_template, mInitialHeight)); + mPcctInitialHeightSlider.setOnSeekBarChangeListener(new OnSeekBarChangeListener() { + @Override + public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { + mPcctInitialHeightLabel.setText(getString(R.string.px_template, progress)); + } + + @Override + public void onStartTrackingTouch(SeekBar seekBar) {} + + @Override + public void onStopTrackingTouch(SeekBar seekBar) {} + }); Intent activityIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.example.com")); PackageManager pm = getPackageManager(); @@ -315,8 +349,6 @@ CustomTabsIntent customTabsIntent = builder.build(); configSessionConnection(session, customTabsIntent); customTabsIntent.intent.putExtra( - "androidx.browser.customtabs.extra.INITIAL_ACTIVITY_HEIGHT_IN_PIXEL", 500); - customTabsIntent.intent.putExtra( "androidx.browser.customtabs.extra.CLOSE_BUTTON_POSITION", closeButtonPosition); int toolbarCornerRadiusDp = mToolbarCornerRadiusSlider.getProgress(); int toolbarCornerRadiusPx = @@ -324,6 +356,20 @@ customTabsIntent.intent.putExtra( "androidx.browser.customtabs.extra.TOOLBAR_CORNER_RADIUS_IN_PIXEL", toolbarCornerRadiusPx); + + int pcctInitialHeightPx = mPcctInitialHeightSlider.getProgress(); + + if (pcctInitialHeightPx != 0) { + customTabsIntent.intent.putExtra( + "androidx.browser.customtabs.extra.INITIAL_ACTIVITY_HEIGHT_IN_PIXEL", + pcctInitialHeightPx); + } + + if (!mPcctResizableCheckbox.isChecked()) { + customTabsIntent.intent.putExtra( + "androidx.browser.customtabs.extra.PARTIAL_CUSTOM_TAB_FIXED_HEIGHT", true); + } + customTabsIntent.launchUrl(this, Uri.parse(url)); } } @@ -386,4 +432,18 @@ mLaunchIncognitoButton.setEnabled(false); mClient = null; } + + private @Px int getMaximumPossibleHeight() { + @Px + int res = 0; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + Rect rect = this.getWindowManager().getMaximumWindowMetrics().getBounds(); + res = Math.max(rect.width(), rect.height()); + } else { + DisplayMetrics displayMetrics = new DisplayMetrics(); + this.getWindowManager().getDefaultDisplay().getRealMetrics(displayMetrics); + res = Math.max(displayMetrics.widthPixels, displayMetrics.heightPixels); + } + return res; + } }
diff --git a/chrome/browser/android/examples/custom_tabs_client/src/res/layout/main.xml b/chrome/browser/android/examples/custom_tabs_client/src/res/layout/main.xml index c9c57d0..1c36255 100644 --- a/chrome/browser/android/examples/custom_tabs_client/src/res/layout/main.xml +++ b/chrome/browser/android/examples/custom_tabs_client/src/res/layout/main.xml
@@ -134,6 +134,44 @@ android:max="72"/> </LinearLayout> + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal" + android:gravity="center_vertical" + android:layout_marginStart="3dp" + android:layout_marginBottom="16dp"> + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/pcct_initial_height_text" + android:layout_marginEnd="8dp" + android:maxWidth="160sp" + style="?attr/textAppearanceLabelLarge" /> + <TextView + android:id="@+id/pcct_initial_height_slider_label" + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:gravity="center_vertical|end" + android:minWidth="40sp" + android:labelFor="@+id/pcct_initial_height_slider" + android:contentDescription="@string/pcct_initial_height_slider_label_desc" + style="?attr/textAppearanceLabelLarge" /> + <SeekBar + android:id="@+id/pcct_initial_height_slider" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_gravity="center_vertical" + android:layout_weight="1"/> + </LinearLayout> + + <CheckBox + android:id="@+id/pcct_resizable_checkbox" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:checked = "true" + android:text="@string/pcct_resizable_text" /> + <Space android:layout_width="match_parent" android:layout_height="5dp" />
diff --git a/chrome/browser/android/examples/custom_tabs_client/src/res/values/strings.xml b/chrome/browser/android/examples/custom_tabs_client/src/res/values/strings.xml index 16d1db00..45de664 100644 --- a/chrome/browser/android/examples/custom_tabs_client/src/res/values/strings.xml +++ b/chrome/browser/android/examples/custom_tabs_client/src/res/values/strings.xml
@@ -35,4 +35,8 @@ <string name="package_label">Package:</string> <string name="amazing_grace">Amazing Grace 2011</string> <string name="artist">Kevin MacLeod</string> + <string name="pcct_resizable_text">PCCT Resizable</string> + <string name="pcct_initial_height_text">PCCT Initial Height</string> + <string name="pcct_initial_height_slider_label_desc">PCCT initial height slider</string> + <string name="px_template">%dpx</string> </resources>
diff --git a/chrome/browser/apps/app_service/publishers/crostini_apps.cc b/chrome/browser/apps/app_service/publishers/crostini_apps.cc index e017fd4a..6715031 100644 --- a/chrome/browser/apps/app_service/publishers/crostini_apps.cc +++ b/chrome/browser/apps/app_service/publishers/crostini_apps.cc
@@ -48,6 +48,10 @@ namespace { +const char kTextPlainMimeType[] = "text/plain"; +const char kTextTypeMimeType[] = "text/"; +const char kTextWildcardMimeType[] = "text/*"; + bool ShouldShowDisplayDensityMenuItem(const std::string& app_id, apps::mojom::MenuType menu_type, int64_t display_id) { @@ -73,8 +77,6 @@ if (mime_types_set.empty()) { return {}; } - std::vector<std::string> mime_types(mime_types_set.begin(), - mime_types_set.end()); // When a file has a mime type that Files App can't recognise but Crostini can // (e.g. a proprietary file type), we should look at the file extensions that @@ -85,6 +87,24 @@ extension_types = mime_types_service->GetExtensionTypesFromMimeTypes( mime_types_set, registration.VmName(), registration.ContainerName()); } + std::vector<std::string> mime_types(mime_types_set.begin(), + mime_types_set.end()); + + // If we see that the app supports the text/plain mime-type, then the app + // supports all files with type text/*, as per xdg spec. + // https://specifications.freedesktop.org/shared-mime-info-spec/shared-mime-info-spec-latest.html. + // In this case, remove all mime types that begin with "text/" and replace + // them with a single "text/*" mime type. + if (base::Contains(mime_types, kTextPlainMimeType)) { + mime_types.erase(std::remove_if(mime_types.begin(), mime_types.end(), + [](const std::string& mime) { + return mime.find(kTextTypeMimeType) != + std::string::npos; + }), + mime_types.end()); + mime_types.push_back(kTextWildcardMimeType); + } + apps::IntentFilters intent_filters; intent_filters.push_back(apps_util::CreateFileFilter( {apps_util::kIntentActionView}, mime_types, extension_types,
diff --git a/chrome/browser/apps/app_service/publishers/crostini_apps_unittest.cc b/chrome/browser/apps/app_service/publishers/crostini_apps_unittest.cc index ee6bf036..099b287 100644 --- a/chrome/browser/apps/app_service/publishers/crostini_apps_unittest.cc +++ b/chrome/browser/apps/app_service/publishers/crostini_apps_unittest.cc
@@ -29,7 +29,6 @@ namespace apps { -// ENABLE ash::features::ShouldArcAndGuestOsFileTasksUseAppService class CrostiniAppsTest : public testing::Test { public: CrostiniAppsTest() @@ -63,6 +62,39 @@ ash::CiceroneClient::Shutdown(); } + // Set up the test Crostini app for our desired mime types. + std::string AddCrostiniAppWithMimeTypes(std::string app_id, + std::string app_name, + std::vector<std::string> mime_types) { + vm_tools::apps::App app; + for (std::string mime_type : mime_types) { + app.add_mime_types(mime_type); + } + app.set_desktop_file_id(app_id); + vm_tools::apps::App::LocaleString::Entry* entry = + app.mutable_name()->add_values(); + entry->set_locale(std::string()); + entry->set_value(app_name); + test_helper()->AddApp(app); + + return crostini::CrostiniTestHelper::GenerateAppId( + app.desktop_file_id(), crostini::kCrostiniDefaultVmName, + crostini::kCrostiniDefaultContainerName); + } + + // Get the registered intent filter for the app in App Service. + std::vector<std::unique_ptr<IntentFilter>> GetIntentFiltersForApp( + std::string app_id) { + std::vector<std::unique_ptr<IntentFilter>> intent_filters; + app_service_proxy()->AppRegistryCache().ForOneApp( + app_id, [&intent_filters](const AppUpdate& update) { + for (auto& intent_filter : update.IntentFilters()) { + intent_filters.push_back(std::move(intent_filter)); + } + }); + return intent_filters; + } + private: content::BrowserTaskEnvironment task_environment_; std::unique_ptr<TestingProfile> profile_; @@ -72,41 +104,19 @@ }; TEST_F(CrostiniAppsTest, AppServiceHasCrostiniIntentFilters) { - std::vector<std::string> mime_types = {"text/csv", "text/plain"}; + std::vector<std::string> mime_types = {"text/csv", "text/html"}; - // Set up the test Crostini app for our desired mime types. - vm_tools::apps::App app; - for (std::string mime_type : mime_types) { - app.add_mime_types(mime_type); - } - app.set_desktop_file_id("app_id"); - vm_tools::apps::App::LocaleString::Entry* entry = - app.mutable_name()->add_values(); - entry->set_locale(std::string()); - entry->set_value("app_name"); - test_helper()->AddApp(app); - - // Get the app ID so that we can find the Crostini app in App Service later. - std::string app_service_id = crostini::CrostiniTestHelper::GenerateAppId( - app.desktop_file_id(), crostini::kCrostiniDefaultVmName, - crostini::kCrostiniDefaultContainerName); - - // Retrieve the registered intent filter for the app in App Service. - std::vector<std::unique_ptr<IntentFilter>> intent_filters; - app_service_proxy()->AppRegistryCache().ForOneApp( - app_service_id, [&intent_filters](const AppUpdate& update) { - for (auto& intent_filter : update.IntentFilters()) { - intent_filters.push_back(std::move(intent_filter)); - } - }); + std::string app_id = + AddCrostiniAppWithMimeTypes("app_id", "app_name", mime_types); + std::vector<std::unique_ptr<IntentFilter>> intent_filters = + GetIntentFiltersForApp(app_id); EXPECT_EQ(intent_filters.size(), 1U); - std::unique_ptr<IntentFilter> intent_filter = std::move(intent_filters[0]); - EXPECT_EQ(intent_filter->conditions.size(), 2U); + EXPECT_EQ(intent_filters[0]->conditions.size(), 2U); // Check that the filter has the correct action type. { - const Condition* condition = intent_filter->conditions[0].get(); + const Condition* condition = intent_filters[0]->conditions[0].get(); ASSERT_EQ(condition->condition_type, ConditionType::kAction); EXPECT_EQ(condition->condition_values.size(), 1U); ASSERT_EQ(condition->condition_values[0]->match_type, @@ -119,7 +129,7 @@ // would also have the extension equivalents of the mime types too if there // were mime/ extension mappings in prefs. { - const Condition* condition = intent_filter->conditions[1].get(); + const Condition* condition = intent_filters[0]->conditions[1].get(); ASSERT_EQ(condition->condition_type, ConditionType::kFile); EXPECT_EQ(condition->condition_values.size(), 2U); ASSERT_EQ(condition->condition_values[0]->value, mime_types[0]); @@ -129,23 +139,12 @@ TEST_F(CrostiniAppsTest, AppReadinessUpdatesWhenCrostiniDisabled) { // Install a Crostini app. - vm_tools::apps::App app; - app.set_desktop_file_id("app_id"); - vm_tools::apps::App::LocaleString::Entry* entry = - app.mutable_name()->add_values(); - entry->set_locale(std::string()); - entry->set_value("app_name"); - test_helper()->AddApp(app); - - // Get the app ID so that we can find the Crostini app in App Service later. - std::string app_service_id = crostini::CrostiniTestHelper::GenerateAppId( - app.desktop_file_id(), crostini::kCrostiniDefaultVmName, - crostini::kCrostiniDefaultContainerName); + std::string app_id = AddCrostiniAppWithMimeTypes("app_id", "app_name", {}); // Check that the app is ready. apps::Readiness readiness_before; app_service_proxy()->AppRegistryCache().ForOneApp( - app_service_id, [&readiness_before](const AppUpdate& update) { + app_id, [&readiness_before](const AppUpdate& update) { readiness_before = update.Readiness(); }); ASSERT_EQ(readiness_before, Readiness::kReady); @@ -158,7 +157,7 @@ // Check that the app is now disabled. apps::Readiness readiness_after; app_service_proxy()->AppRegistryCache().ForOneApp( - app_service_id, [&readiness_after](const AppUpdate& update) { + app_id, [&readiness_after](const AppUpdate& update) { readiness_after = update.Readiness(); }); ASSERT_EQ(readiness_after, Readiness::kUninstalledByUser); @@ -178,29 +177,11 @@ (*mime_types_list.mutable_mime_type_mappings())[extension] = mime_type; mime_types_service()->UpdateMimeTypes(mime_types_list); - // Create Crostini app. - vm_tools::apps::App app; - app.add_mime_types(mime_type); - app.set_desktop_file_id("app_id"); - vm_tools::apps::App::LocaleString::Entry* entry = - app.mutable_name()->add_values(); - entry->set_locale(std::string()); - entry->set_value("app_name"); - - // Get the app ID so that we can find the Crostini app in App Service later. - test_helper()->AddApp(app); - std::string app_service_id = crostini::CrostiniTestHelper::GenerateAppId( - app.desktop_file_id(), crostini::kCrostiniDefaultVmName, - crostini::kCrostiniDefaultContainerName); - - // Retrieve the registered intent filter for the app in App Service. - std::vector<std::unique_ptr<IntentFilter>> intent_filters; - app_service_proxy()->AppRegistryCache().ForOneApp( - app_service_id, [&intent_filters](const AppUpdate& update) { - for (auto& intent_filter : update.IntentFilters()) { - intent_filters.push_back(std::move(intent_filter)); - } - }); + // Create Crostini app and get its registered intent filters. + std::string app_id = + AddCrostiniAppWithMimeTypes("app_id", "app_name", {mime_type}); + std::vector<std::unique_ptr<IntentFilter>> intent_filters = + GetIntentFiltersForApp(app_id); EXPECT_EQ(intent_filters.size(), 1U); std::unique_ptr<IntentFilter> intent_filter = std::move(intent_filters[0]); @@ -232,4 +213,40 @@ } } +TEST_F(CrostiniAppsTest, IntentFilterWithTextPlainAddsTextWildcardMimeType) { + std::string normal_app_id = AddCrostiniAppWithMimeTypes( + "normal_app_id", "normal_app_name", {"text/csv"}); + std::vector<std::unique_ptr<IntentFilter>> intent_filters = + GetIntentFiltersForApp(normal_app_id); + + EXPECT_EQ(intent_filters.size(), 1U); + EXPECT_EQ(intent_filters[0]->conditions.size(), 2U); + + // Check that the filter is unchanged because there isn't a "text/plain" + // mime type condition. + { + const Condition* condition = intent_filters[0]->conditions[1].get(); + ASSERT_EQ(condition->condition_type, ConditionType::kFile); + EXPECT_EQ(condition->condition_values.size(), 1U); + ASSERT_EQ(condition->condition_values[0]->value, "text/csv"); + } + + std::string many_mimes_app_id = AddCrostiniAppWithMimeTypes( + "many_mimes_app_id", "many_mimes_app_name", + {"text/plain", "text/csv", "text/javascript", "video/mp4"}); + intent_filters = GetIntentFiltersForApp(many_mimes_app_id); + + EXPECT_EQ(intent_filters.size(), 1U); + EXPECT_EQ(intent_filters[0]->conditions.size(), 2U); + + // Check that the filter has "text/*" to replace all the text mime types. + { + const Condition* condition = intent_filters[0]->conditions[1].get(); + ASSERT_EQ(condition->condition_type, ConditionType::kFile); + EXPECT_EQ(condition->condition_values.size(), 2U); + ASSERT_EQ(condition->condition_values[0]->value, "video/mp4"); + ASSERT_EQ(condition->condition_values[1]->value, "text/*"); + } +} + } // namespace apps
diff --git a/chrome/browser/ash/arc/app_shortcuts/arc_app_shortcuts_menu_builder.cc b/chrome/browser/ash/arc/app_shortcuts/arc_app_shortcuts_menu_builder.cc index 37f15a7..52af1f9 100644 --- a/chrome/browser/ash/arc/app_shortcuts/arc_app_shortcuts_menu_builder.cc +++ b/chrome/browser/ash/arc/app_shortcuts/arc_app_shortcuts_menu_builder.cc
@@ -15,8 +15,8 @@ #include "chrome/browser/ui/app_list/app_list_client_impl.h" #include "chrome/browser/ui/app_list/arc/arc_app_utils.h" #include "chrome/browser/ui/app_list/search/ranking/launch_data.h" +#include "chrome/browser/ui/app_list/search/ranking/ranking_item_util.h" #include "chrome/browser/ui/app_list/search/search_controller.h" -#include "chrome/browser/ui/app_list/search/search_result_ranker/ranking_item_util.h" #include "ui/base/models/image_model.h" #include "ui/base/models/simple_menu_model.h"
diff --git a/chrome/browser/ash/arc/bluetooth/arc_bluetooth_bridge.cc b/chrome/browser/ash/arc/bluetooth/arc_bluetooth_bridge.cc index 1d8068ce..c47bac1 100644 --- a/chrome/browser/ash/arc/bluetooth/arc_bluetooth_bridge.cc +++ b/chrome/browser/ash/arc/bluetooth/arc_bluetooth_bridge.cc
@@ -1156,6 +1156,7 @@ uint32_t discovery_timeout = property->get_discovery_timeout(); if (discovery_timeout > 0) { discoverable_off_timeout_ = discovery_timeout; + OnSetAdapterProperty(mojom::BluetoothStatus::SUCCESS, std::move(property)); } else { OnSetAdapterProperty(mojom::BluetoothStatus::PARM_INVALID, std::move(property));
diff --git a/chrome/browser/ash/borealis/borealis_task.cc b/chrome/browser/ash/borealis/borealis_task.cc index d6efd47..90dc921 100644 --- a/chrome/browser/ash/borealis/borealis_task.cc +++ b/chrome/browser/ash/borealis/borealis_task.cc
@@ -329,6 +329,7 @@ "update_chrome_flags"}; PushFlag(chromeos::features::kBorealisLinuxMode, command); PushFlag(chromeos::features::kBorealisForceBetaClient, command); + PushFlag(chromeos::features::kBorealisForceDoubleScale, command); std::string output; if (!base::GetAppOutput(command, &output)) {
diff --git a/chrome/browser/ash/crosapi/local_printer_ash_unittest.cc b/chrome/browser/ash/crosapi/local_printer_ash_unittest.cc index f4437d0..97de1da0 100644 --- a/chrome/browser/ash/crosapi/local_printer_ash_unittest.cc +++ b/chrome/browser/ash/crosapi/local_printer_ash_unittest.cc
@@ -436,10 +436,10 @@ printers_manager().SetPrinterStatus(printer1); crosapi::mojom::PrinterStatusPtr printer_status; local_printer_ash()->GetStatus( - "printer1", base::BindOnce(base::BindLambdaForTesting( - [&](crosapi::mojom::PrinterStatusPtr status) { - printer_status = std::move(status); - }))); + "printer1", + base::BindLambdaForTesting([&](crosapi::mojom::PrinterStatusPtr status) { + printer_status = std::move(status); + })); auto expected_status = crosapi::mojom::PrinterStatus::New(); expected_status->printer_id = "printer1"; expected_status->timestamp = printer1.GetTimestamp(); @@ -738,8 +738,8 @@ TEST_F(LocalPrinterAshTest, GetPolicies_Unset) { crosapi::mojom::PoliciesPtr policies; - local_printer_ash()->GetPolicies(base::BindOnce(base::BindLambdaForTesting( - [&](crosapi::mojom::PoliciesPtr data) { policies = std::move(data); }))); + local_printer_ash()->GetPolicies(base::BindLambdaForTesting( + [&](crosapi::mojom::PoliciesPtr data) { policies = std::move(data); })); EXPECT_EQ(crosapi::mojom::Policies::New(), policies); } @@ -750,8 +750,8 @@ prefs->Set("printing.paper_size_default", std::move(paper_size)); crosapi::mojom::PoliciesPtr policies; - local_printer_ash()->GetPolicies(base::BindOnce(base::BindLambdaForTesting( - [&](crosapi::mojom::PoliciesPtr data) { policies = std::move(data); }))); + local_printer_ash()->GetPolicies(base::BindLambdaForTesting( + [&](crosapi::mojom::PoliciesPtr data) { policies = std::move(data); })); ASSERT_TRUE(policies); EXPECT_EQ(gfx::Size(210000, 297000), policies->paper_size_default); @@ -765,8 +765,8 @@ prefs->SetInteger(prefs::kPrintingBackgroundGraphicsDefault, 1); crosapi::mojom::PoliciesPtr policies; - local_printer_ash()->GetPolicies(base::BindOnce(base::BindLambdaForTesting( - [&](crosapi::mojom::PoliciesPtr data) { policies = std::move(data); }))); + local_printer_ash()->GetPolicies(base::BindLambdaForTesting( + [&](crosapi::mojom::PoliciesPtr data) { policies = std::move(data); })); ASSERT_TRUE(policies); EXPECT_EQ( @@ -782,8 +782,8 @@ prefs->SetInteger(prefs::kPrintingMaxSheetsAllowed, 5); crosapi::mojom::PoliciesPtr policies; - local_printer_ash()->GetPolicies(base::BindOnce(base::BindLambdaForTesting( - [&](crosapi::mojom::PoliciesPtr data) { policies = std::move(data); }))); + local_printer_ash()->GetPolicies(base::BindLambdaForTesting( + [&](crosapi::mojom::PoliciesPtr data) { policies = std::move(data); })); EXPECT_TRUE(policies->max_sheets_allowed_has_value); EXPECT_EQ(5u, policies->max_sheets_allowed); @@ -795,8 +795,8 @@ prefs->SetInteger(prefs::kPrintingMaxSheetsAllowed, 0); crosapi::mojom::PoliciesPtr policies; - local_printer_ash()->GetPolicies(base::BindOnce(base::BindLambdaForTesting( - [&](crosapi::mojom::PoliciesPtr data) { policies = std::move(data); }))); + local_printer_ash()->GetPolicies(base::BindLambdaForTesting( + [&](crosapi::mojom::PoliciesPtr data) { policies = std::move(data); })); ASSERT_TRUE(policies); EXPECT_TRUE(policies->max_sheets_allowed_has_value); @@ -809,8 +809,8 @@ prefs->SetInteger(prefs::kPrintingMaxSheetsAllowed, -1); crosapi::mojom::PoliciesPtr policies; - local_printer_ash()->GetPolicies(base::BindOnce(base::BindLambdaForTesting( - [&](crosapi::mojom::PoliciesPtr data) { policies = std::move(data); }))); + local_printer_ash()->GetPolicies(base::BindLambdaForTesting( + [&](crosapi::mojom::PoliciesPtr data) { policies = std::move(data); })); ASSERT_TRUE(policies); EXPECT_FALSE(policies->max_sheets_allowed_has_value); @@ -820,8 +820,8 @@ auto* prefs = GetPrefs(); prefs->SetBoolean(prefs::kPrintHeaderFooter, false); crosapi::mojom::PoliciesPtr policies; - local_printer_ash()->GetPolicies(base::BindOnce(base::BindLambdaForTesting( - [&](crosapi::mojom::PoliciesPtr data) { policies = std::move(data); }))); + local_printer_ash()->GetPolicies(base::BindLambdaForTesting( + [&](crosapi::mojom::PoliciesPtr data) { policies = std::move(data); })); ASSERT_TRUE(policies); EXPECT_EQ(crosapi::mojom::Policies::OptionalBool::kUnset, policies->print_header_footer_allowed); @@ -833,8 +833,8 @@ auto* prefs = GetPrefs(); prefs->SetBoolean(prefs::kPrintHeaderFooter, true); crosapi::mojom::PoliciesPtr policies; - local_printer_ash()->GetPolicies(base::BindOnce(base::BindLambdaForTesting( - [&](crosapi::mojom::PoliciesPtr data) { policies = std::move(data); }))); + local_printer_ash()->GetPolicies(base::BindLambdaForTesting( + [&](crosapi::mojom::PoliciesPtr data) { policies = std::move(data); })); ASSERT_TRUE(policies); EXPECT_EQ(crosapi::mojom::Policies::OptionalBool::kUnset, policies->print_header_footer_allowed); @@ -847,8 +847,8 @@ prefs->SetManagedPref(prefs::kPrintHeaderFooter, std::make_unique<base::Value>(false)); crosapi::mojom::PoliciesPtr policies; - local_printer_ash()->GetPolicies(base::BindOnce(base::BindLambdaForTesting( - [&](crosapi::mojom::PoliciesPtr data) { policies = std::move(data); }))); + local_printer_ash()->GetPolicies(base::BindLambdaForTesting( + [&](crosapi::mojom::PoliciesPtr data) { policies = std::move(data); })); ASSERT_TRUE(policies); EXPECT_EQ(crosapi::mojom::Policies::OptionalBool::kFalse, policies->print_header_footer_allowed); @@ -861,8 +861,8 @@ prefs->SetManagedPref(prefs::kPrintHeaderFooter, std::make_unique<base::Value>(true)); crosapi::mojom::PoliciesPtr policies; - local_printer_ash()->GetPolicies(base::BindOnce(base::BindLambdaForTesting( - [&](crosapi::mojom::PoliciesPtr data) { policies = std::move(data); }))); + local_printer_ash()->GetPolicies(base::BindLambdaForTesting( + [&](crosapi::mojom::PoliciesPtr data) { policies = std::move(data); })); ASSERT_TRUE(policies); EXPECT_EQ(crosapi::mojom::Policies::OptionalBool::kTrue, policies->print_header_footer_allowed); @@ -879,8 +879,8 @@ prefs->SetInteger(prefs::kPrintingColorDefault, 2); crosapi::mojom::PoliciesPtr policies; - local_printer_ash()->GetPolicies(base::BindOnce(base::BindLambdaForTesting( - [&](crosapi::mojom::PoliciesPtr data) { policies = std::move(data); }))); + local_printer_ash()->GetPolicies(base::BindLambdaForTesting( + [&](crosapi::mojom::PoliciesPtr data) { policies = std::move(data); })); EXPECT_EQ(expected_allowed_color_modes, policies->allowed_color_modes); EXPECT_EQ(printing::mojom::ColorModeRestriction::kColor, @@ -896,8 +896,8 @@ prefs->SetInteger(prefs::kPrintingDuplexDefault, 1); crosapi::mojom::PoliciesPtr policies; - local_printer_ash()->GetPolicies(base::BindOnce(base::BindLambdaForTesting( - [&](crosapi::mojom::PoliciesPtr data) { policies = std::move(data); }))); + local_printer_ash()->GetPolicies(base::BindLambdaForTesting( + [&](crosapi::mojom::PoliciesPtr data) { policies = std::move(data); })); EXPECT_EQ(expected_allowed_duplex_modes, policies->allowed_duplex_modes); EXPECT_EQ(printing::mojom::DuplexModeRestriction::kSimplex, @@ -910,8 +910,8 @@ prefs->SetInteger(prefs::kPrintingPinDefault, 2); crosapi::mojom::PoliciesPtr policies; - local_printer_ash()->GetPolicies(base::BindOnce(base::BindLambdaForTesting( - [&](crosapi::mojom::PoliciesPtr data) { policies = std::move(data); }))); + local_printer_ash()->GetPolicies(base::BindLambdaForTesting( + [&](crosapi::mojom::PoliciesPtr data) { policies = std::move(data); })); EXPECT_EQ(printing::mojom::PinModeRestriction::kPin, policies->allowed_pin_modes);
diff --git a/chrome/browser/ash/crosapi/test_mojo_connection_manager_unittest.cc b/chrome/browser/ash/crosapi/test_mojo_connection_manager_unittest.cc index 3a12660b..0da5ef70 100644 --- a/chrome/browser/ash/crosapi/test_mojo_connection_manager_unittest.cc +++ b/chrome/browser/ash/crosapi/test_mojo_connection_manager_unittest.cc
@@ -139,15 +139,14 @@ ssize_t size; base::RunLoop run_loop; base::ThreadPool::PostTaskAndReply( - FROM_HERE, {base::MayBlock()}, - base::BindOnce(base::BindLambdaForTesting([&]() { + FROM_HERE, {base::MayBlock()}, base::BindLambdaForTesting([&]() { // Mark the channel as blocking. int flags = fcntl(socket_fd.get(), F_GETFL); PCHECK(flags != -1); fcntl(socket_fd.get(), F_SETFL, flags & ~O_NONBLOCK); size = mojo::SocketRecvmsg(socket_fd.get(), buf, sizeof(buf), &descriptors, true /*block*/); - })), + }), run_loop.QuitClosure()); run_loop.Run(); EXPECT_EQ(1, size); @@ -203,9 +202,8 @@ // Set up UserManager to fake the login state. user_manager::FakeUserManager user_manager; user_manager.Initialize(); - base::ScopedClosureRunner user_manager_teardown( - base::BindOnce(base::BindLambdaForTesting( - [&user_manager]() { user_manager.Destroy(); }))); + base::ScopedClosureRunner user_manager_teardown(base::BindLambdaForTesting( + [&user_manager]() { user_manager.Destroy(); })); const AccountId account = AccountId::FromUserEmail("test@test"); const user_manager::User* user = user_manager.AddUser(account); user_manager.UserLoggedIn(account, user->username_hash(), false, false);
diff --git a/chrome/browser/ash/crostini/crostini_export_import_notification_controller.cc b/chrome/browser/ash/crostini/crostini_export_import_notification_controller.cc index 4b8dd83..d650b61 100644 --- a/chrome/browser/ash/crostini/crostini_export_import_notification_controller.cc +++ b/chrome/browser/ash/crostini/crostini_export_import_notification_controller.cc
@@ -7,7 +7,7 @@ #include "ash/constants/notifier_catalogs.h" #include "ash/constants/url_constants.h" #include "ash/public/cpp/notification_utils.h" -#include "chrome/app/vector_icons/vector_icons.h" +#include "ash/resources/vector_icons/vector_icons.h" #include "chrome/browser/ash/crostini/crostini_export_import.h" #include "chrome/browser/notifications/notification_display_service.h" #include "chrome/browser/platform_util.h" @@ -59,7 +59,7 @@ weak_ptr_factory_.GetWeakPtr())); message_center::RichNotificationData rich_notification_data; - rich_notification_data.vector_small_image = &kNotificationLinuxIcon; + rich_notification_data.vector_small_image = &ash::kNotificationLinuxIcon; rich_notification_data.accent_color = ash::kSystemNotificationColorNormal; notification_ = std::make_unique<message_center::Notification>(
diff --git a/chrome/browser/ash/crostini/crostini_package_notification.cc b/chrome/browser/ash/crostini/crostini_package_notification.cc index fe1a2e93..96e89c5 100644 --- a/chrome/browser/ash/crostini/crostini_package_notification.cc +++ b/chrome/browser/ash/crostini/crostini_package_notification.cc
@@ -6,7 +6,7 @@ #include "ash/constants/notifier_catalogs.h" #include "ash/public/cpp/notification_utils.h" -#include "chrome/app/vector_icons/vector_icons.h" +#include "ash/resources/vector_icons/vector_icons.h" #include "chrome/browser/ash/crostini/crostini_package_service.h" #include "chrome/browser/ash/crostini/crostini_util.h" #include "chrome/browser/ash/guest_os/guest_os_registry_service_factory.h" @@ -66,7 +66,7 @@ ->AddObserver(this); } message_center::RichNotificationData rich_notification_data; - rich_notification_data.vector_small_image = &kNotificationLinuxIcon; + rich_notification_data.vector_small_image = &ash::kNotificationLinuxIcon; rich_notification_data.never_timeout = true; rich_notification_data.accent_color = ash::kSystemNotificationColorNormal;
diff --git a/chrome/browser/ash/file_manager/file_manager_browsertest.cc b/chrome/browser/ash/file_manager/file_manager_browsertest.cc index f61ab087..757b2cff 100644 --- a/chrome/browser/ash/file_manager/file_manager_browsertest.cc +++ b/chrome/browser/ash/file_manager/file_manager_browsertest.cc
@@ -1938,16 +1938,14 @@ .EnableFiltersInRecents() .EnableFiltersInRecentsV2() .FilesSwa(), - // TODO(crbug.com/1355515) - // TestCase("recentsRespondToTimezoneChangeForGridView") - // .EnableFiltersInRecents() - // .EnableFiltersInRecentsV2() - // .FilesSwa(), - // TODO(crbug.com/1355515) - // TestCase("recentsRespondToTimezoneChangeForListView") - // .EnableFiltersInRecents() - // .EnableFiltersInRecentsV2() - // .FilesSwa(), + TestCase("recentsRespondToTimezoneChangeForGridView") + .EnableFiltersInRecents() + .EnableFiltersInRecentsV2() + .FilesSwa(), + TestCase("recentsRespondToTimezoneChangeForListView") + .EnableFiltersInRecents() + .EnableFiltersInRecentsV2() + .FilesSwa(), TestCase("recentsTimePeriodHeadings") .EnableFiltersInRecents() .EnableFiltersInRecentsV2(),
diff --git a/chrome/browser/ash/policy/reporting/metrics_reporting/network/network_events_observer_browsertest.cc b/chrome/browser/ash/policy/reporting/metrics_reporting/network/network_events_observer_browsertest.cc new file mode 100644 index 0000000..e0c6101 --- /dev/null +++ b/chrome/browser/ash/policy/reporting/metrics_reporting/network/network_events_observer_browsertest.cc
@@ -0,0 +1,159 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <memory> +#include <string> + +#include "ash/components/settings/cros_settings_names.h" +#include "chrome/browser/ash/login/test/cryptohome_mixin.h" +#include "chrome/browser/ash/policy/affiliation/affiliation_mixin.h" +#include "chrome/browser/ash/policy/affiliation/affiliation_test_helper.h" +#include "chrome/browser/ash/policy/core/device_policy_cros_browser_test.h" +#include "chrome/browser/ash/settings/scoped_testing_cros_settings.h" +#include "chrome/browser/ash/settings/stub_cros_settings_provider.h" +#include "chromeos/ash/components/network/network_handler_test_helper.h" +#include "chromeos/ash/services/cros_healthd/public/cpp/fake_cros_healthd.h" +#include "chromeos/dbus/missive/missive_client_test_observer.h" +#include "components/reporting/proto/synced/metric_data.pb.h" +#include "components/reporting/proto/synced/record.pb.h" +#include "components/reporting/proto/synced/record_constants.pb.h" +#include "components/signin/public/identity_manager/identity_test_utils.h" +#include "content/public/test/browser_test.h" +#include "content/public/test/test_launcher.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/cros_system_api/dbus/shill/dbus-constants.h" + +using ::testing::Eq; + +namespace reporting { +namespace { + +constexpr int kSignalStrength = 50; +constexpr char kWifiGuid[] = "wifi-guid"; +constexpr char kWifiServicePath[] = "/service/wlan"; +const auto network_connection_state = + chromeos::network_health::mojom::NetworkState::kOnline; + +Record GetNextRecord(::chromeos::MissiveClientTestObserver* observer) { + const std::tuple<Priority, Record>& enqueued_record = + observer->GetNextEnqueuedRecord(); + Priority priority = std::get<0>(enqueued_record); + Record record = std::get<1>(enqueued_record); + EXPECT_THAT(priority, Eq(Priority::SLOW_BATCH)); + return record; +} + +class NetworkEventsBrowserTest : public ::policy::DevicePolicyCrosBrowserTest { + protected: + NetworkEventsBrowserTest() { + crypto_home_mixin_.MarkUserAsExisting(affiliation_mixin_.account_id()); + } + + void SetUpCommandLine(base::CommandLine* command_line) override { + ::policy::AffiliationTestHelper::AppendCommandLineSwitchesForLoginManager( + command_line); + ::policy::DevicePolicyCrosBrowserTest::SetUpCommandLine(command_line); + } + + void SetUpOnMainThread() override { + ::policy::DevicePolicyCrosBrowserTest::SetUpOnMainThread(); + if (content::IsPreTest()) { + // Preliminary setup - set up affiliated user + ::policy::AffiliationTestHelper::PreLoginUser( + affiliation_mixin_.account_id()); + + return; + } + ::policy::AffiliationTestHelper::LoginUser(affiliation_mixin_.account_id()); + } + + void EnablePolicy() { + scoped_testing_cros_settings_.device_settings()->SetBoolean( + ash::kReportDeviceNetworkStatus, true); + } + + void DisablePolicy() { + scoped_testing_cros_settings_.device_settings()->SetBoolean( + ash::kReportDeviceNetworkStatus, false); + } + + // Create user. + ::policy::DevicePolicyCrosTestHelper test_helper_; + ::policy::AffiliationMixin affiliation_mixin_{&mixin_host_, &test_helper_}; + ash::CryptohomeMixin crypto_home_mixin_{&mixin_host_}; + ash::ScopedTestingCrosSettings scoped_testing_cros_settings_; +}; + +IN_PROC_BROWSER_TEST_F(NetworkEventsBrowserTest, + PRE_ConnectionStateAffiliatedUserAndPolicyEnabled) { + // dummy case to register user. +} + +IN_PROC_BROWSER_TEST_F(NetworkEventsBrowserTest, + ConnectionStateAffiliatedUserAndPolicyEnabled) { + chromeos::MissiveClientTestObserver missive_observer_( + ::reporting::Destination::EVENT_METRIC); + + ::ash::NetworkHandlerTestHelper network_handler_test_helper_; + network_handler_test_helper_.AddDefaultProfiles(); + network_handler_test_helper_.ResetDevicesAndServices(); + auto* const service_client = network_handler_test_helper_.service_test(); + + service_client->AddService(kWifiServicePath, kWifiGuid, "wifi-name", + shill::kTypeWifi, shill::kStateReady, true); + + EnablePolicy(); + + chromeos::cros_healthd::FakeCrosHealthd::Get() + ->EmitConnectionStateChangedEventForTesting(kWifiGuid, + network_connection_state); + + const Record& record = GetNextRecord(&missive_observer_); + MetricData record_data; + + ASSERT_TRUE(record_data.ParseFromString(record.data())); + + // Testing event found successfully. + EXPECT_THAT( + record_data.event_data().type(), + Eq(::reporting::MetricEventType::NETWORK_CONNECTION_STATE_CHANGE)); +} + +IN_PROC_BROWSER_TEST_F(NetworkEventsBrowserTest, + PRE_SignalStrengthAffiliatedUserAndPolicyEnabled) { + // dummy case to register user. +} + +IN_PROC_BROWSER_TEST_F(NetworkEventsBrowserTest, + SignalStrengthAffiliatedUserAndPolicyEnabled) { + chromeos::MissiveClientTestObserver missive_observer_( + ::reporting::Destination::EVENT_METRIC); + + ::ash::NetworkHandlerTestHelper network_handler_test_helper_; + network_handler_test_helper_.AddDefaultProfiles(); + network_handler_test_helper_.ResetDevicesAndServices(); + auto* const service_client = network_handler_test_helper_.service_test(); + + service_client->AddService(kWifiServicePath, kWifiGuid, "wifi-name", + shill::kTypeWifi, shill::kStateReady, true); + + EnablePolicy(); + chromeos::cros_healthd::FakeCrosHealthd::Get() + ->EmitSignalStrengthChangedEventForTesting( + kWifiGuid, + chromeos::network_health::mojom::UInt32Value::New(kSignalStrength)); + + const Record& record = GetNextRecord(&missive_observer_); + MetricData record_data; + + ASSERT_TRUE(record_data.ParseFromString(record.data())); + + // Testing event found successfully. + EXPECT_THAT(record_data.event_data().type(), + Eq(::reporting::MetricEventType::NETWORK_SIGNAL_STRENGTH_CHANGE)); +} + +} // namespace +} // namespace reporting \ No newline at end of file
diff --git a/chrome/browser/ash/usb/cros_usb_detector.cc b/chrome/browser/ash/usb/cros_usb_detector.cc index 460d79c8..f4bce99 100644 --- a/chrome/browser/ash/usb/cros_usb_detector.cc +++ b/chrome/browser/ash/usb/cros_usb_detector.cc
@@ -167,7 +167,20 @@ const absl::optional<std::u16string>& reply) override { disposition_ = CrosUsbNotificationClosed::kUnknown; if (button_index && *button_index < static_cast<int>(vm_names_.size())) { - HandleConnectToVm(vm_names_[*button_index]); + if (vm_names_[*button_index] == crostini::kCrostiniDefaultVmName) { + // When multi-container is enabled, show the settings page instead of + // directly attaching the device to the VM. Otherwise, the device is + // attached to the default container in the VM. + if (crostini::CrostiniFeatures::Get()->IsMultiContainerAllowed( + profile())) { + HandleShowSettings( + chromeos::settings::mojom::kCrostiniUsbPreferencesSubpagePath); + } else { + HandleConnectToGuest(crostini::DefaultContainerId()); + } + } else { + HandleConnectToGuest(vm_names_[*button_index]); + } } else { HandleShowSettings(settings_sub_page_); } @@ -180,17 +193,20 @@ private: ~CrosUsbNotificationDelegate() override = default; - void HandleConnectToVm(const std::string& vm_name) { + void HandleConnectToGuest(const guest_os::GuestId& guest_id) { disposition_ = CrosUsbNotificationClosed::kConnectToLinux; CrosUsbDetector* detector = CrosUsbDetector::Get(); if (detector) { - detector->AttachUsbDeviceToGuest(guest_os::GuestId(vm_name, ""), guid_, - base::DoNothing()); + detector->AttachUsbDeviceToGuest(guest_id, guid_, base::DoNothing()); return; } Close(false); } + void HandleConnectToGuest(const std::string& vm_name) { + HandleConnectToGuest(guest_os::GuestId(vm_name, "")); + } + void HandleShowSettings(const std::string& sub_page) { chrome::SettingsWindowManager::GetInstance()->ShowOSSettings(profile(), sub_page); @@ -387,10 +403,14 @@ std::string guid, std::u16string label, absl::optional<guest_os::GuestId> shared_guest_id, + uint16_t vendor_id, + uint16_t product_id, bool prompt_before_sharing) : guid(guid), label(label), shared_guest_id(shared_guest_id), + vendor_id(vendor_id), + product_id(product_id), prompt_before_sharing(prompt_before_sharing) {} CrosUsbDeviceInfo::CrosUsbDeviceInfo(const CrosUsbDeviceInfo&) = default; CrosUsbDeviceInfo::~CrosUsbDeviceInfo() = default; @@ -494,6 +514,7 @@ continue; result.emplace_back( device.info->guid, device.label, device.shared_guest_id, + device.info->vendor_id, device.info->product_id, /*prompt_before_sharing=*/ device.shared_guest_id.has_value() || !device.mount_points.empty()); }
diff --git a/chrome/browser/ash/usb/cros_usb_detector.h b/chrome/browser/ash/usb/cros_usb_detector.h index 6cddf87a..0b00aff 100644 --- a/chrome/browser/ash/usb/cros_usb_detector.h +++ b/chrome/browser/ash/usb/cros_usb_detector.h
@@ -50,6 +50,8 @@ CrosUsbDeviceInfo(std::string guid, std::u16string label, absl::optional<guest_os::GuestId> shared_guest_id, + uint16_t vendor_id, + uint16_t product_id, bool prompt_before_sharing); CrosUsbDeviceInfo(const CrosUsbDeviceInfo&); ~CrosUsbDeviceInfo(); @@ -59,6 +61,8 @@ // Name of VM shared with. Unset if not shared. The device may be shared but // not yet attached. absl::optional<guest_os::GuestId> shared_guest_id; + uint16_t vendor_id; + uint16_t product_id; // Devices shared with other devices or otherwise in use by the system // should have a confirmation prompt shown prior to sharing. bool prompt_before_sharing;
diff --git a/chrome/browser/ash/web_applications/face_ml_system_web_app_info.cc b/chrome/browser/ash/web_applications/face_ml_system_web_app_info.cc index 09d3369..fc0d6ac 100644 --- a/chrome/browser/ash/web_applications/face_ml_system_web_app_info.cc +++ b/chrome/browser/ash/web_applications/face_ml_system_web_app_info.cc
@@ -58,13 +58,10 @@ } FaceMLSystemAppDelegate::FaceMLSystemAppDelegate(Profile* profile) - : ash::SystemWebAppDelegate( - ash::SystemWebAppType::FACE_ML, - "FaceML", - GURL(ash::kChromeUIFaceMLAppURL), - profile, - ash::OriginTrialsMap({{ash::GetOrigin(ash::kChromeUIFaceMLAppURL), - {"FileHandling"}}})) {} + : ash::SystemWebAppDelegate(ash::SystemWebAppType::FACE_ML, + "FaceML", + GURL(ash::kChromeUIFaceMLAppURL), + profile) {} std::unique_ptr<WebAppInstallInfo> FaceMLSystemAppDelegate::GetWebAppInfo() const {
diff --git a/chrome/browser/ash/web_applications/projector_system_web_app_info.cc b/chrome/browser/ash/web_applications/projector_system_web_app_info.cc index 6334481..4dd21ac 100644 --- a/chrome/browser/ash/web_applications/projector_system_web_app_info.cc +++ b/chrome/browser/ash/web_applications/projector_system_web_app_info.cc
@@ -7,17 +7,11 @@ #include "ash/constants/ash_features.h" #include "ash/webui/grit/ash_projector_app_trusted_resources.h" #include "ash/webui/projector_app/public/cpp/projector_app_constants.h" -#include "chrome/browser/apps/app_service/app_launch_params.h" -#include "chrome/browser/ash/system_web_apps/types/system_web_app_type.h" #include "chrome/browser/ash/web_applications/system_web_app_install_utils.h" #include "chrome/browser/ui/ash/projector/projector_utils.h" -#include "chrome/browser/ui/ash/system_web_apps/system_web_app_ui_utils.h" -#include "chrome/browser/ui/browser.h" -#include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/web_applications/user_display_mode.h" #include "chrome/browser/web_applications/web_app_install_info.h" #include "chrome/grit/generated_resources.h" -#include "content/public/browser/web_contents.h" #include "third_party/skia/include/core/SkColor.h" #include "ui/base/l10n/l10n_util.h" #include "ui/chromeos/styles/cros_styles.h" @@ -92,30 +86,3 @@ bool ProjectorSystemWebAppDelegate::IsAppEnabled() const { return IsProjectorAppEnabled(profile_); } - -Browser* ProjectorSystemWebAppDelegate::LaunchAndNavigateSystemWebApp( - Profile* profile, - web_app::WebAppProvider* provider, - const GURL& url, - const apps::AppLaunchParams& params) const { - Browser* browser = - ash::FindSystemWebAppBrowser(profile, ash::SystemWebAppType::PROJECTOR); - // If the Projector app is not already open or we're not launching with files - // then proceed as usual. - if (!browser || params.launch_files.empty()) { - return SystemWebAppDelegate::LaunchAndNavigateSystemWebApp( - profile, provider, url, params); - } - // Otherwise, the app is already open and we're launching files. Suppose the - // user clicks on a share link for a transcoding screencast. The app's URL - // would be set to chrome://projector/app/screencastId. However, calling - // LaunchSystemWebAppAsync() always launches the app at the default start url - // of chrome://projector/app/. The launch event would reload the app back to - // the gallery view! To prevent this bug, we must match the app's current url - // to avoid a visible app reload. In general, launch events should be - // invisible to the user. - content::WebContents* web_contents = - browser->tab_strip_model()->GetActiveWebContents(); - return SystemWebAppDelegate::LaunchAndNavigateSystemWebApp( - profile, provider, web_contents->GetURL(), params); -}
diff --git a/chrome/browser/ash/web_applications/projector_system_web_app_info.h b/chrome/browser/ash/web_applications/projector_system_web_app_info.h index 73b0340..efb6f8c 100644 --- a/chrome/browser/ash/web_applications/projector_system_web_app_info.h +++ b/chrome/browser/ash/web_applications/projector_system_web_app_info.h
@@ -22,11 +22,6 @@ bool ShouldCaptureNavigations() const override; gfx::Size GetMinimumWindowSize() const override; bool IsAppEnabled() const override; - Browser* LaunchAndNavigateSystemWebApp( - Profile* profile, - web_app::WebAppProvider* provider, - const GURL& url, - const apps::AppLaunchParams& params) const override; }; #endif // CHROME_BROWSER_ASH_WEB_APPLICATIONS_PROJECTOR_SYSTEM_WEB_APP_INFO_H_
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn index dcc583a..5f92462 100644 --- a/chrome/browser/chromeos/BUILD.gn +++ b/chrome/browser/chromeos/BUILD.gn
@@ -165,7 +165,9 @@ "//ash/webui/resources:connectivity_diagnostics_resources_grit", "//ash/webui/resources:diagnostics_app_resources_grit", "//ash/webui/resources:eche_bundle_resources_grit", + "//ash/webui/resources:face_ml_app_bundle_resources_grit", "//ash/webui/resources:face_ml_app_resources_grit", + "//ash/webui/resources:face_ml_app_untrusted_resources_grit", "//ash/webui/resources:firmware_update_app_resources_grit", "//ash/webui/resources:help_app_resources_grit", "//ash/webui/resources:media_app_bundle_resources_grit",
diff --git a/chrome/browser/devtools/chrome_devtools_manager_delegate.cc b/chrome/browser/devtools/chrome_devtools_manager_delegate.cc index a6296e3..22dc5f9a 100644 --- a/chrome/browser/devtools/chrome_devtools_manager_delegate.cc +++ b/chrome/browser/devtools/chrome_devtools_manager_delegate.cc
@@ -97,7 +97,7 @@ DCHECK(!g_instance); g_instance = this; -#if !BUILDFLAG(IS_CHROMEOS_ASH) +#if !BUILDFLAG(IS_CHROMEOS) // Only create and hold keep alive for automation test for non ChromeOS. // ChromeOS automation test (aka tast) manages chrome instance via session // manager daemon. The extra keep alive is not needed and makes ChromeOS
diff --git a/chrome/browser/extensions/offscreen_document_browsertest.cc b/chrome/browser/extensions/offscreen_document_browsertest.cc index 78ba1e9b8..897214b 100644 --- a/chrome/browser/extensions/offscreen_document_browsertest.cc +++ b/chrome/browser/extensions/offscreen_document_browsertest.cc
@@ -609,7 +609,7 @@ run_loop.Quit(); }; offscreen_document->SetCloseHandler( - base::BindOnce(base::BindLambdaForTesting(close_handler))); + base::BindLambdaForTesting(close_handler)); content::ExecuteScriptAsync(offscreen_document->host_contents(), "window.close();"); run_loop.Run(); @@ -632,7 +632,7 @@ ++close_count; }; offscreen_document->SetCloseHandler( - base::BindOnce(base::BindLambdaForTesting(close_handler))); + base::BindLambdaForTesting(close_handler)); content::WebContents* contents = offscreen_document->host_contents(); // WebContentsDelegate::CloseContents() isn't guaranteed to be called by the
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index 5beb593d..f5bd971 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -754,6 +754,11 @@ "expiry_milestone": 110 }, { + "name": "borealis-force-double-scale", + "owners": [ "hollingum" ], + "expiry_milestone": 110 + }, + { "name": "borealis-linux-mode", "owners": [ "hollingum" ], "expiry_milestone": 110 @@ -4026,7 +4031,7 @@ { "name": "isolated-app-origins", "owners": [ "peletskyi@google.com", "desktop-pwas-team@google.com" ], - "expiry_milestone": 106 + "expiry_milestone": 109 }, { "name": "isolation-by-default", @@ -5619,6 +5624,11 @@ "expiry_milestone": 110 }, { + "name": "robust-audio-device-select-logic", + "owners": [ "mingxuanshi@google.com", "chromeos-audio-sw@google.com" ], + "expiry_milestone": 114 + }, + { "name": "rounded-display", "owners": [ "zoraiznaeem",
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index 8d3f946..f23d7fca 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -649,6 +649,10 @@ const char kBorealisForceBetaClientDescription[] = "Force the client to run its beta version."; +const char kBorealisForceDoubleScaleName[] = "Borealis Force Double Scale"; +const char kBorealisForceDoubleScaleDescription[] = + "Force the client to run in 2x visual zoom."; + const char kBorealisLinuxModeName[] = "Borealis Linux Mode"; const char kBorealisLinuxModeDescription[] = "Do not run ChromeOS-specific code in the client."; @@ -4695,6 +4699,12 @@ "coredumps are only collected when hardware exceptions occur and are " "used for debugging such exceptions."; +const char kRobustAudioDeviceSelectLogicName[] = + "Robust Audio Device Select Logic"; +const char kRobustAudioDeviceSelectLogicDescription[] = + "A more robust logic for automatic audio device selection which is more " + "capable of remembering the user's preferences of audio devices."; + const char kBluetoothUseFlossName[] = "Use Floss instead of BlueZ"; const char kBluetoothUseFlossDescription[] = "Enables using Floss (also known as Fluoride, Android's Bluetooth stack) "
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index d4089fe..39dc1964 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -350,6 +350,9 @@ extern const char kBorealisForceBetaClientName[]; extern const char kBorealisForceBetaClientDescription[]; +extern const char kBorealisForceDoubleScaleName[]; +extern const char kBorealisForceDoubleScaleDescription[]; + extern const char kBorealisLinuxModeName[]; extern const char kBorealisLinuxModeDescription[]; @@ -2685,6 +2688,9 @@ extern const char kBluetoothCoredumpName[]; extern const char kBluetoothCoredumpDescription[]; +extern const char kRobustAudioDeviceSelectLogicName[]; +extern const char kRobustAudioDeviceSelectLogicDescription[]; + extern const char kBluetoothUseFlossName[]; extern const char kBluetoothUseFlossDescription[];
diff --git a/chrome/browser/lookalikes/lookalike_url_navigation_throttle.cc b/chrome/browser/lookalikes/lookalike_url_navigation_throttle.cc index 57f0fb3d..6ba33ab 100644 --- a/chrome/browser/lookalikes/lookalike_url_navigation_throttle.cc +++ b/chrome/browser/lookalikes/lookalike_url_navigation_throttle.cc
@@ -114,10 +114,7 @@ content::NavigationHandle* handle = navigation_handle(); // Ignore errors and same document navigations. - // TODO(crbug.com/1199724): The throttle would have to cancel the prerender - // if we should show an interstitial after activation. - if (handle->GetNetErrorCode() != net::OK || !handle->IsInMainFrame() || - handle->IsSameDocument()) { + if (handle->GetNetErrorCode() != net::OK || handle->IsSameDocument()) { return content::NavigationThrottle::PROCEED; } @@ -233,12 +230,16 @@ } ThrottleCheckResult -LookalikeUrlNavigationThrottle::CheckManifestsAndMaybeShowInterstitial( +LookalikeUrlNavigationThrottle::CheckAndMaybeShowInterstitial( const GURL& safe_domain, const GURL& lookalike_domain, ukm::SourceId source_id, LookalikeUrlMatchType match_type, bool triggered_by_initial_url) { + // Cancel the prerender to show an interstitial after activation. + if (navigation_handle()->IsInPrerenderedMainFrame()) + return content::NavigationThrottle::CANCEL; + RecordUMAFromMatchType(match_type); // Punycode interstitial doesn't have a target site, so safe_domain isn't @@ -400,15 +401,15 @@ if (first_is_lookalike && ShouldBlockLookalikeUrlNavigation(first_match_type)) { - return CheckManifestsAndMaybeShowInterstitial( - first_suggested_url, first_url, source_id, first_match_type, - first_is_lookalike); + return CheckAndMaybeShowInterstitial(first_suggested_url, first_url, + source_id, first_match_type, + first_is_lookalike); } if (last_is_lookalike && ShouldBlockLookalikeUrlNavigation(last_match_type)) { - return CheckManifestsAndMaybeShowInterstitial(last_suggested_url, last_url, - source_id, last_match_type, - first_is_lookalike); + return CheckAndMaybeShowInterstitial(last_suggested_url, last_url, + source_id, last_match_type, + first_is_lookalike); } LookalikeUrlMatchType match_type =
diff --git a/chrome/browser/lookalikes/lookalike_url_navigation_throttle.h b/chrome/browser/lookalikes/lookalike_url_navigation_throttle.h index a4eb503..a4013708 100644 --- a/chrome/browser/lookalikes/lookalike_url_navigation_throttle.h +++ b/chrome/browser/lookalikes/lookalike_url_navigation_throttle.h
@@ -100,9 +100,10 @@ LookalikeUrlMatchType match_type, bool triggered_by_initial_url); - // Checks digital asset links of |lookalike_domain| and |safe_domain| and - // shows a full page interstitial if either manifest validation fails. - ThrottleCheckResult CheckManifestsAndMaybeShowInterstitial( + // Checks if a full page intersitial can be shown. This function checks if + // manifest validation fails for digital asset links of |lookalike_domain|, + // |safe_domain| or if the navigation isn't in prerendering navigation. + ThrottleCheckResult CheckAndMaybeShowInterstitial( const GURL& safe_domain, const GURL& lookalike_domain, ukm::SourceId source_id,
diff --git a/chrome/browser/lookalikes/lookalike_url_navigation_throttle_browsertest.cc b/chrome/browser/lookalikes/lookalike_url_navigation_throttle_browsertest.cc index 73ff7eb06..80eac07 100644 --- a/chrome/browser/lookalikes/lookalike_url_navigation_throttle_browsertest.cc +++ b/chrome/browser/lookalikes/lookalike_url_navigation_throttle_browsertest.cc
@@ -45,6 +45,7 @@ #include "content/public/common/content_paths.h" #include "content/public/test/browser_test.h" #include "content/public/test/content_mock_cert_verifier.h" +#include "content/public/test/prerender_test_util.h" #include "content/public/test/signed_exchange_browser_test_helper.h" #include "content/public/test/test_navigation_observer.h" #include "content/public/test/url_loader_interceptor.h" @@ -2226,3 +2227,69 @@ DigitalAssetLinkCrossValidator::kEventHistogramName, DigitalAssetLinkCrossValidator::Event::kLookalikeManifestFailed, 1); } + +class LookalikeUrlNavigationThrottlePrerenderBrowserTest + : public LookalikeUrlNavigationThrottleBrowserTest { + public: + LookalikeUrlNavigationThrottlePrerenderBrowserTest() = default; + ~LookalikeUrlNavigationThrottlePrerenderBrowserTest() override = default; + + // |prerender_helper_| has a ScopedFeatureList so we needed to delay its + // creation until now because the base class also uses ScopedFeatureList and + // initialization order matters. + void SetUpCommandLine(base::CommandLine* command_line) override { + LookalikeUrlNavigationThrottleBrowserTest::SetUpCommandLine(command_line); + prerender_helper_ = std::make_unique<content::test::PrerenderTestHelper>( + base::BindRepeating( + &LookalikeUrlNavigationThrottlePrerenderBrowserTest::web_contents, + base::Unretained(this))); + } + + void SetUpOnMainThread() override { + prerender_helper_->SetUp(embedded_test_server()); + LookalikeUrlNavigationThrottleBrowserTest::SetUpOnMainThread(); + } + + content::WebContents* web_contents() { + return browser()->tab_strip_model()->GetActiveWebContents(); + } + + protected: + std::unique_ptr<content::test::PrerenderTestHelper> prerender_helper_; +}; + +IN_PROC_BROWSER_TEST_P(LookalikeUrlNavigationThrottlePrerenderBrowserTest, + ShowInterstitialAfterActivation) { + // TODO(crbug.com/1176054): Cross-origin prerender isn't yet supported, so we + // trigger prerendering a page that needs to show an interstitial like this. + // Once cross-origin prerender is supported, this should be updated to more + // realistic use-case. i.e. navigate to an primary page with a normal URL and + // prerender/activate with a lookalike URL. + const GURL kNavigateUrl = GetURL("googlé.com"); + LoadAndCheckInterstitialAt(browser(), kNavigateUrl); + SendInterstitialCommandSync(browser(), + SecurityInterstitialCommand::CMD_PROCEED); + ReputationService::Get(browser()->profile()) + ->ResetWarningDismissedETLDPlusOnesForTesting(); + + // Start a prerender. + const GURL kPrerenderUrl = + embedded_test_server()->GetURL("googlé.com", "/title1.html?prerender"); + content::test::PrerenderHostObserver host_observer(*web_contents(), + kPrerenderUrl); + prerender_helper_->AddPrerenderAsync(kPrerenderUrl); + + // Wait until the prerender destroyed. + host_observer.WaitForDestroyed(); + EXPECT_EQ(nullptr, GetCurrentInterstitial(web_contents())); + + // Activate the prerendered page. + prerender_helper_->NavigatePrimaryPage(kPrerenderUrl); + EXPECT_EQ(LookalikeUrlBlockingPage::kTypeForTesting, + GetInterstitialType(web_contents())); + EXPECT_FALSE(IsUrlShowing(browser())); +} + +INSTANTIATE_TEST_SUITE_P(All, + LookalikeUrlNavigationThrottlePrerenderBrowserTest, + testing::Bool() /* digital_asset_links_enabled */);
diff --git a/chrome/browser/media/cdm_document_service_impl.cc b/chrome/browser/media/cdm_document_service_impl.cc index 10252f7..aafb6b9 100644 --- a/chrome/browser/media/cdm_document_service_impl.cc +++ b/chrome/browser/media/cdm_document_service_impl.cc
@@ -361,7 +361,8 @@ CdmPrefServiceHelper::SetCdmClientToken(user_prefs, cdm_origin, client_token); } -void CdmDocumentServiceImpl::OnCdmEvent(media::CdmEvent event) { +void CdmDocumentServiceImpl::OnCdmEvent(media::CdmEvent event, + uint32_t hresult) { DVLOG(1) << __func__ << ": event=" << static_cast<int>(event); // CdmDocumentServiceImpl is shared by all CDMs in the same RenderFrame. @@ -389,7 +390,8 @@ case media::CdmEvent::kCdmError: if (!has_reported_cdm_error_) { has_reported_cdm_error_ = true; - MediaFoundationServiceMonitor::GetInstance()->OnPlaybackOrCdmError(); + MediaFoundationServiceMonitor::GetInstance()->OnPlaybackOrCdmError( + static_cast<HRESULT>(hresult)); } break; }
diff --git a/chrome/browser/media/cdm_document_service_impl.h b/chrome/browser/media/cdm_document_service_impl.h index faa1cd94..36fb930 100644 --- a/chrome/browser/media/cdm_document_service_impl.h +++ b/chrome/browser/media/cdm_document_service_impl.h
@@ -52,7 +52,7 @@ void GetMediaFoundationCdmData( GetMediaFoundationCdmDataCallback callback) final; void SetCdmClientToken(const std::vector<uint8_t>& client_token) final; - void OnCdmEvent(media::CdmEvent event) final; + void OnCdmEvent(media::CdmEvent event, uint32_t hresult) final; static void ClearCdmData( Profile* profile,
diff --git a/chrome/browser/media/media_foundation_service_monitor.cc b/chrome/browser/media/media_foundation_service_monitor.cc index 3677ad2..cc4d26fd 100644 --- a/chrome/browser/media/media_foundation_service_monitor.cc +++ b/chrome/browser/media/media_foundation_service_monitor.cc
@@ -10,6 +10,7 @@ #include "base/feature_list.h" #include "base/json/values_util.h" #include "base/logging.h" +#include "base/metrics/histogram_functions.h" #include "base/power_monitor/power_monitor.h" #include "base/values.h" #include "chrome/browser/browser_process.h" @@ -141,6 +142,11 @@ if (!info.IsService<media::mojom::MediaFoundationServiceBroker>()) return; + bool is_after_power_or_display_change = + (base::Time::Now() - last_power_or_display_change_time_) < kGracePeriod; + base::UmaHistogramBoolean("Media.EME.MediaFoundationService.Crash", + is_after_power_or_display_change); + // Not checking `last_power_or_display_change_time_`; crashes are always bad. DVLOG(1) << __func__ << ": MediaFoundationService process crashed!"; AddSample(kCrash); @@ -174,16 +180,20 @@ AddSample(kSignificantPlayback); } -void MediaFoundationServiceMonitor::OnPlaybackOrCdmError() { +void MediaFoundationServiceMonitor::OnPlaybackOrCdmError(HRESULT hr) { DVLOG(1) << __func__; DCHECK_CURRENTLY_ON(content::BrowserThread::UI); if (base::Time::Now() - last_power_or_display_change_time_ < kGracePeriod) { DVLOG(1) << "Playback or CDM error ignored since it happened right after " "a power or display change."; + base::UmaHistogramSparse( + "Media.EME.MediaFoundationService.ErrorAfterPowerOrDisplayChange", hr); return; } + base::UmaHistogramSparse( + "Media.EME.MediaFoundationService.ErrorNotAfterPowerOrDisplayChange", hr); AddSample(kPlaybackOrCdmError); }
diff --git a/chrome/browser/media/media_foundation_service_monitor.h b/chrome/browser/media/media_foundation_service_monitor.h index 6e0a5b3..63655ac0 100644 --- a/chrome/browser/media/media_foundation_service_monitor.h +++ b/chrome/browser/media/media_foundation_service_monitor.h
@@ -48,7 +48,7 @@ // Called when a significant playback or error happened when using // MediaFoundationCdm. void OnSignificantPlayback(); - void OnPlaybackOrCdmError(); + void OnPlaybackOrCdmError(HRESULT hr); private: // Make constructor/destructor private since this is a singleton.
diff --git a/chrome/browser/media/router/BUILD.gn b/chrome/browser/media/router/BUILD.gn index 47dd940..8988eb1 100644 --- a/chrome/browser/media/router/BUILD.gn +++ b/chrome/browser/media/router/BUILD.gn
@@ -23,6 +23,19 @@ ] } +source_set("logger_list") { + sources = [ + "logger_list.cc", + "logger_list.h", + ] + + deps = [ + "//base", + "//components/media_router/browser", + "//content/public/browser", + ] +} + static_library("media_router_feature") { sources = [ "media_router_feature.cc", @@ -99,6 +112,8 @@ public_deps += [ "//components/media_router/common/mojom:logger" ] sources += [ + "logger_list.cc", + "logger_list.h", "mojo/media_router_desktop.cc", "mojo/media_router_desktop.h", "mojo/media_router_mojo_impl.cc", @@ -278,6 +293,7 @@ "discovery/mdns/cast_media_sink_service_unittest.cc", "discovery/mdns/dns_sd_registry_unittest.cc", "discovery/media_sink_discovery_metrics_unittest.cc", + "logger_list_unittest.cc", "media_router_feature_unittest.cc", "mojo/media_router_mojo_impl_unittest.cc", "mojo/media_sink_service_status_unittest.cc",
diff --git a/chrome/browser/media/router/discovery/BUILD.gn b/chrome/browser/media/router/discovery/BUILD.gn index 809c4f0..f62ad83 100644 --- a/chrome/browser/media/router/discovery/BUILD.gn +++ b/chrome/browser/media/router/discovery/BUILD.gn
@@ -15,6 +15,7 @@ "//chrome/app:generated_resources", "//chrome/browser:browser_process", "//chrome/browser/media/router:data_decoder_util", + "//chrome/browser/media/router:logger_list", "//chrome/browser/media/router:media_router_feature", "//chrome/common:constants", "//components/cast_channel",
diff --git a/chrome/browser/media/router/discovery/dial/dial_app_discovery_service.cc b/chrome/browser/media/router/discovery/dial/dial_app_discovery_service.cc index cb4dfe2..57a85c5f 100644 --- a/chrome/browser/media/router/discovery/dial/dial_app_discovery_service.cc +++ b/chrome/browser/media/router/discovery/dial/dial_app_discovery_service.cc
@@ -69,15 +69,6 @@ pending_requests_.back()->Start(); } -void DialAppDiscoveryService::BindLogger( - mojo::PendingRemote<mojom::Logger> pending_remote) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (logger_.is_bound()) - return; - logger_.Bind(std::move(pending_remote)); - logger_.reset_on_disconnect(); -} - void DialAppDiscoveryService::SetParserForTest( std::unique_ptr<SafeDialAppInfoParser> parser) { parser_ = std::move(parser); @@ -158,13 +149,12 @@ .Run(sink_id_, app_name_, DialAppInfoResult(nullptr, DialAppInfoResultCode::kParsingError)); } else { - if (service_->logger_.is_bound()) { - service_->logger_->LogInfo( - mojom::LogCategory::kDiscovery, kLoggerComponent, - base::StringPrintf("DIAL sink supports disconnect: %s", - parsed_app_info->allow_stop ? "true" : "false"), - sink_id_, "", ""); - } + LoggerList::GetInstance()->Log( + LoggerImpl::Severity::kInfo, mojom::LogCategory::kDiscovery, + kLoggerComponent, + base::StringPrintf("DIAL sink supports disconnect: %s", + parsed_app_info->allow_stop ? "true" : "false"), + sink_id_, "", ""); RecordDialFetchAppInfo(DialAppInfoResultCode::kOk); std::move(app_info_cb_)
diff --git a/chrome/browser/media/router/discovery/dial/dial_app_discovery_service.h b/chrome/browser/media/router/discovery/dial/dial_app_discovery_service.h index 8bdb1608..1ca62a0e 100644 --- a/chrome/browser/media/router/discovery/dial/dial_app_discovery_service.h +++ b/chrome/browser/media/router/discovery/dial/dial_app_discovery_service.h
@@ -17,8 +17,8 @@ #include "chrome/browser/media/router/discovery/dial/dial_url_fetcher.h" #include "chrome/browser/media/router/discovery/dial/parsed_dial_app_info.h" #include "chrome/browser/media/router/discovery/dial/safe_dial_app_info_parser.h" +#include "chrome/browser/media/router/logger_list.h" #include "components/media_router/common/discovery/media_sink_internal.h" -#include "components/media_router/common/mojom/logger.mojom.h" #include "third_party/abseil-cpp/absl/types/optional.h" #include "url/gurl.h" @@ -87,8 +87,6 @@ const std::string& app_name, DialAppInfoCallback app_info_cb); - void BindLogger(mojo::PendingRemote<mojom::Logger> pending_remote); - private: friend class DialAppDiscoveryServiceTest; @@ -153,8 +151,6 @@ // Safe DIAL parser. Does the parsing in a utility process. std::unique_ptr<SafeDialAppInfoParser> parser_; - mojo::Remote<mojom::Logger> logger_; - SEQUENCE_CHECKER(sequence_checker_); };
diff --git a/chrome/browser/media/router/discovery/dial/dial_app_discovery_service_unittest.cc b/chrome/browser/media/router/discovery/dial/dial_app_discovery_service_unittest.cc index 65a6577..ad2e5544 100644 --- a/chrome/browser/media/router/discovery/dial/dial_app_discovery_service_unittest.cc +++ b/chrome/browser/media/router/discovery/dial/dial_app_discovery_service_unittest.cc
@@ -11,6 +11,7 @@ #include "chrome/browser/media/router/discovery/dial/parsed_dial_device_description.h" #include "chrome/browser/media/router/discovery/dial/safe_dial_app_info_parser.h" #include "chrome/browser/media/router/test/provider_test_helpers.h" +#include "content/public/test/browser_task_environment.h" #include "net/http/http_status_code.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -113,6 +114,10 @@ protected: raw_ptr<TestSafeDialAppInfoParser> test_parser_; DialAppDiscoveryService dial_app_discovery_service_; + + // Must be on Chrome_UIThread, as `OnDialAppInfoFetchComplete` uses a + // LoggerList instance which requires UI thread. + content::BrowserTaskEnvironment task_environment_; }; TEST_F(DialAppDiscoveryServiceTest, TestFetchDialAppInfoFetchURL) {
diff --git a/chrome/browser/media/router/discovery/dial/dial_media_sink_service.cc b/chrome/browser/media/router/discovery/dial/dial_media_sink_service.cc index 483bd3e..cad138a85 100644 --- a/chrome/browser/media/router/discovery/dial/dial_media_sink_service.cc +++ b/chrome/browser/media/router/discovery/dial/dial_media_sink_service.cc
@@ -64,14 +64,4 @@ sinks_discovered_cb.Run(std::move(sinks)); } -void DialMediaSinkService::BindLogger( - mojo::PendingRemote<mojom::Logger> pending_remote) { - // TODO(crbug.com/1293535): Simplify how logger instances are made available - // to their clients. - impl_->task_runner()->PostTask( - FROM_HERE, - base::BindOnce(&DialMediaSinkServiceImpl::BindLogger, - base::Unretained(impl_.get()), std::move(pending_remote))); -} - } // namespace media_router
diff --git a/chrome/browser/media/router/discovery/dial/dial_media_sink_service.h b/chrome/browser/media/router/discovery/dial/dial_media_sink_service.h index 572f806..fe17896 100644 --- a/chrome/browser/media/router/discovery/dial/dial_media_sink_service.h +++ b/chrome/browser/media/router/discovery/dial/dial_media_sink_service.h
@@ -14,7 +14,6 @@ #include "base/task/sequenced_task_runner.h" #include "components/media_router/common/discovery/media_sink_internal.h" #include "components/media_router/common/discovery/media_sink_service_util.h" -#include "components/media_router/common/mojom/logger.mojom.h" #include "url/origin.h" namespace media_router { @@ -54,10 +53,6 @@ return impl_.get(); } - // Binds |pending_remote| to the Mojo Remote owned by |impl_|. - // Marked virtual for tests. - virtual void BindLogger(mojo::PendingRemote<mojom::Logger> pending_remote); - private: // Marked virtual for tests. virtual std::unique_ptr<DialMediaSinkServiceImpl, base::OnTaskRunnerDeleter>
diff --git a/chrome/browser/media/router/discovery/dial/dial_media_sink_service_impl.cc b/chrome/browser/media/router/discovery/dial/dial_media_sink_service_impl.cc index d2ddbaa..3f345827 100644 --- a/chrome/browser/media/router/discovery/dial/dial_media_sink_service_impl.cc +++ b/chrome/browser/media/router/discovery/dial/dial_media_sink_service_impl.cc
@@ -99,6 +99,10 @@ dial_registry_ = std::make_unique<DialRegistry>(*this, task_runner_); dial_registry_->Start(); + + LoggerList::GetInstance()->Log( + LoggerImpl::Severity::kInfo, mojom::LogCategory::kDiscovery, + kLoggerComponent, "DialMediaSinkService has started.", "", "", ""); } void DialMediaSinkServiceImpl::OnUserGesture() { @@ -187,11 +191,10 @@ void DialMediaSinkServiceImpl::OnDialError(DialRegistry::DialErrorCode type) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (logger_.is_bound()) { - logger_->LogError(mojom::LogCategory::kDiscovery, kLoggerComponent, - base::StrCat({"Dial Error: ", EnumToString(type)}), "", - "", ""); - } + LoggerList::GetInstance()->Log( + LoggerImpl::Severity::kError, mojom::LogCategory::kDiscovery, + kLoggerComponent, base::StrCat({"Dial Error: ", EnumToString(type)}), "", + "", ""); } void DialMediaSinkServiceImpl::OnDeviceDescriptionAvailable( @@ -228,13 +231,12 @@ const DialDeviceData& device, const std::string& error_message) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (logger_.is_bound()) { - logger_->LogError( - mojom::LogCategory::kDiscovery, kLoggerComponent, - base::StrCat({"Device description error. Device id: ", - device.device_id(), ", error message: ", error_message}), - "", "", ""); - } + LoggerList::GetInstance()->Log( + LoggerImpl::Severity::kError, mojom::LogCategory::kDiscovery, + kLoggerComponent, + base::StrCat({"Device description error. Device id: ", device.device_id(), + ", error message: ", error_message}), + "", "", ""); } void DialMediaSinkServiceImpl::OnAppInfoParseCompleted( @@ -254,9 +256,10 @@ if (old_status == app_status) return; - if (logger_.is_bound() && !result.app_info) { - logger_->LogError( - mojom::LogCategory::kDiscovery, kLoggerComponent, + if (!result.app_info) { + LoggerList::GetInstance()->Log( + LoggerImpl::Severity::kError, mojom::LogCategory::kDiscovery, + kLoggerComponent, base::StringPrintf( "App info parsing error. DialAppInfoResultCode: %d. app name: %s", static_cast<int>(result.result_code), app_name.c_str()), @@ -348,22 +351,4 @@ return sinks; } -void DialMediaSinkServiceImpl::BindLogger( - mojo::PendingRemote<mojom::Logger> pending_remote) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - // Reset |logger_| if it is bound to a disconnected remote. - if (logger_.is_bound()) - return; - logger_.Bind(std::move(pending_remote)); - logger_.reset_on_disconnect(); - - logger_->LogInfo(mojom::LogCategory::kDiscovery, kLoggerComponent, - "DialMediaSinkService has started.", "", "", ""); - - mojo::PendingRemote<mojom::Logger> discovery_service_remote; - logger_->BindReceiver( - discovery_service_remote.InitWithNewPipeAndPassReceiver()); - app_discovery_service_->BindLogger(std::move(discovery_service_remote)); -} - } // namespace media_router
diff --git a/chrome/browser/media/router/discovery/dial/dial_media_sink_service_impl.h b/chrome/browser/media/router/discovery/dial/dial_media_sink_service_impl.h index d54cab3..8c6c552 100644 --- a/chrome/browser/media/router/discovery/dial/dial_media_sink_service_impl.h +++ b/chrome/browser/media/router/discovery/dial/dial_media_sink_service_impl.h
@@ -84,8 +84,6 @@ virtual std::vector<MediaSinkInternal> GetAvailableSinks( const std::string& app_name) const; - void BindLogger(mojo::PendingRemote<mojom::Logger> pending_remote); - protected: void SetDescriptionServiceForTest( std::unique_ptr<DeviceDescriptionService> description_service); @@ -188,11 +186,6 @@ base::flat_map<std::string, std::unique_ptr<SinkQueryByAppCallbackList>> sink_queries_; - // Mojo Remote to the logger owned by the Media Router. The Remote is not - // bound until |BindLogger()| is called. Always check if |logger_.is_bound()| - // is true before using. - mojo::Remote<mojom::Logger> logger_; - scoped_refptr<base::SequencedTaskRunner> task_runner_; DialDeviceCountMetrics metrics_;
diff --git a/chrome/browser/media/router/discovery/dial/dial_media_sink_service_impl_unittest.cc b/chrome/browser/media/router/discovery/dial/dial_media_sink_service_impl_unittest.cc index 37e92ce..035f0c22 100644 --- a/chrome/browser/media/router/discovery/dial/dial_media_sink_service_impl_unittest.cc +++ b/chrome/browser/media/router/discovery/dial/dial_media_sink_service_impl_unittest.cc
@@ -11,7 +11,6 @@ #include "base/timer/mock_timer.h" #include "chrome/browser/media/router/discovery/dial/dial_device_data.h" #include "chrome/browser/media/router/test/provider_test_helpers.h" -#include "components/media_router/browser/logger_impl.h" #include "content/public/test/browser_task_environment.h" #include "services/data_decoder/public/cpp/test_support/in_process_data_decoder.h" #include "testing/gmock/include/gmock/gmock.h" @@ -369,25 +368,4 @@ StartMonitoringAvailableSinksForApp("YouTube"); } -TEST_F(DialMediaSinkServiceImplTest, BindLogger) { - std::unique_ptr<LoggerImpl> logger_1 = std::make_unique<LoggerImpl>(); - mojo::PendingRemote<mojom::Logger> pending_remote_1; - logger_1->BindReceiver(pending_remote_1.InitWithNewPipeAndPassReceiver()); - media_sink_service_->BindLogger(std::move(pending_remote_1)); - - // Trying to bind another pending remote no-ops instead of causing - // a DCHECK failure from binding to a remote that's already bound. - std::unique_ptr<LoggerImpl> logger_2 = std::make_unique<LoggerImpl>(); - mojo::PendingRemote<mojom::Logger> pending_remote_2; - logger_2->BindReceiver(pending_remote_2.InitWithNewPipeAndPassReceiver()); - media_sink_service_->BindLogger(std::move(pending_remote_2)); - - // Trying to bind a disconnected receiver should work. - logger_1.reset(); - std::unique_ptr<LoggerImpl> logger_3 = std::make_unique<LoggerImpl>(); - mojo::PendingRemote<mojom::Logger> pending_remote_3; - logger_3->BindReceiver(pending_remote_3.InitWithNewPipeAndPassReceiver()); - media_sink_service_->BindLogger(std::move(pending_remote_3)); -} - } // namespace media_router
diff --git a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service.cc b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service.cc index c075e5a0f..78c45c8d 100644 --- a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service.cc +++ b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service.cc
@@ -100,10 +100,9 @@ dns_sd_registry_ = DnsSdRegistry::GetInstance(); dns_sd_registry_->AddObserver(this); dns_sd_registry_->RegisterDnsSdListener(kCastServiceType); - if (logger_impl_) { - logger_impl_->LogInfo(mojom::LogCategory::kDiscovery, kLoggerComponent, - "mDNS discovery started.", "", "", ""); - } + LoggerList::GetInstance()->Log( + LoggerImpl::Severity::kInfo, mojom::LogCategory::kDiscovery, + kLoggerComponent, "mDNS discovery started.", "", "", ""); } } @@ -157,27 +156,4 @@ sinks_discovered_cb.Run(std::move(sinks)); } -void CastMediaSinkService::BindLogger(LoggerImpl* logger_impl) { - // TODO(crbug.com/1293535): Simplify how logger instances are made available - // to their clients. - - DCHECK(logger_impl); - logger_impl_ = logger_impl; - if (dns_sd_registry_) { - logger_impl->LogInfo(mojom::LogCategory::kDiscovery, kLoggerComponent, - "mDNS service has started.", "", "", ""); - } - - mojo::PendingRemote<mojom::Logger> pending_remote; - logger_impl_->BindReceiver(pending_remote.InitWithNewPipeAndPassReceiver()); - impl_->task_runner()->PostTask( - FROM_HERE, - base::BindOnce(&CastMediaSinkServiceImpl::BindLogger, - base::Unretained(impl_.get()), std::move(pending_remote))); -} - -void CastMediaSinkService::RemoveLogger() { - logger_impl_ = nullptr; -} - } // namespace media_router
diff --git a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service.h b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service.h index 69e45fb..e685828 100644 --- a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service.h +++ b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service.h
@@ -18,7 +18,6 @@ #include "chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl.h" #include "chrome/browser/media/router/discovery/mdns/dns_sd_delegate.h" #include "chrome/browser/media/router/discovery/mdns/dns_sd_registry.h" -#include "components/media_router/browser/logger_impl.h" #include "components/media_router/common/discovery/media_sink_internal.h" #include "components/media_router/common/discovery/media_sink_service_util.h" #include "components/prefs/pref_change_registrar.h" @@ -76,12 +75,6 @@ void SetDnsSdRegistryForTest(DnsSdRegistry* registry); - // Binds |pending_remote| to the Mojo Remote owned by |impl_|. - // Marked virtual for tests. - virtual void BindLogger(LoggerImpl* logger_impl); - - virtual void RemoveLogger(); - private: friend class CastMediaSinkServiceTest; @@ -114,10 +107,6 @@ // List of cast sinks found in current round of mDNS discovery. std::vector<MediaSinkInternal> cast_sinks_; - // Pointer to the LoggerImpl object owned by MediaRouterDesktop. It should - // only be used after BindLogger() is called. - raw_ptr<LoggerImpl> logger_impl_ = nullptr; - SEQUENCE_CHECKER(sequence_checker_); base::WeakPtrFactory<CastMediaSinkService> weak_ptr_factory_{this}; };
diff --git a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl.cc b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl.cc index 842fee1e..6794ae0 100644 --- a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl.cc +++ b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl.cc
@@ -18,7 +18,6 @@ #include "chrome/browser/net/system_network_context_manager.h" // nogncheck #include "components/cast_channel/cast_channel_enum.h" #include "components/cast_channel/cast_socket_service.h" -#include "components/cast_channel/logger.h" #include "components/media_router/common/discovery/media_sink_internal.h" #include "components/media_router/common/media_sink.h" #include "components/media_router/common/mojom/media_router.mojom.h" @@ -360,15 +359,17 @@ std::find_if(sinks.begin(), sinks.end(), [&socket_id](const auto& entry) { return entry.second.cast_data().cast_channel_id == socket_id; }); - if (logger_.is_bound()) { - auto sink_id = sink_it == sinks.end() ? "" : sink_it->first; - logger_->LogError( - mojom::LogCategory::kDiscovery, kLoggerComponent, - base::StrCat({"Media Router Channel Error: ", EnumToString(error_code), - ". channel_id: ", base::NumberToString(socket_id), - ". IP endpoint: ", ip_endpoint.ToString()}), - sink_id, "", ""); - } + + auto sink_id = sink_it == sinks.end() ? "" : sink_it->first; + + LoggerList::GetInstance()->Log( + LoggerImpl::Severity::kError, mojom::LogCategory::kDiscovery, + kLoggerComponent, + base::StrCat({"Media Router Channel Error: ", EnumToString(error_code), + ". channel_id: ", base::NumberToString(socket_id), + ". IP endpoint: ", ip_endpoint.ToString()}), + sink_id, "", ""); + if (sink_it == sinks.end()) { return; } @@ -416,13 +417,12 @@ sink_cache_[last_network_id] = std::move(current_sinks); } - if (logger_.is_bound()) { - logger_->LogError(mojom::LogCategory::kDiscovery, kLoggerComponent, - base::StringPrintf( - "Network ID chagned from \"%s\" to \"%s\".", - last_network_id.c_str(), current_network_id_.c_str()), - "", "", ""); - } + LoggerList::GetInstance()->Log( + LoggerImpl::Severity::kError, mojom::LogCategory::kDiscovery, + kLoggerComponent, + base::StringPrintf("Network ID chagned from \"%s\" to \"%s\".", + last_network_id.c_str(), current_network_id_.c_str()), + "", "", ""); // TODO(imcheng): Maybe this should clear |sinks_| and call |StartTimer()| // so it is more responsive? @@ -667,14 +667,13 @@ !(ip_endpoint == existing_sink->cast_data().ip_endpoint)) return; - if (logger_.is_bound()) { - logger_->LogError( - mojom::LogCategory::kDiscovery, kLoggerComponent, - base::StrCat({"Failed to open the channel. IP endpoint: ", - ip_endpoint.ToString(), ". channel_id: ", - base::NumberToString(existing_sink->cast_channel_id())}), - sink.sink().id(), "", ""); - } + LoggerList::GetInstance()->Log( + LoggerImpl::Severity::kError, mojom::LogCategory::kDiscovery, + kLoggerComponent, + base::StrCat({"Failed to open the channel. IP endpoint: ", + ip_endpoint.ToString(), ". channel_id: ", + base::NumberToString(existing_sink->cast_channel_id())}), + sink.sink().id(), "", ""); RemoveSink(sink); } @@ -737,19 +736,6 @@ allow_all_ips_ = allow_all_ips; } -void CastMediaSinkServiceImpl::BindLogger( - mojo::PendingRemote<mojom::Logger> pending_remote) { - // TODO(crbug.com/1293535): Simplify how logger instances are made available - // to their clients. - - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - // Reset |logger_| if it is bound to a disconnected remote. - if (logger_.is_bound()) - return; - logger_.Bind(std::move(pending_remote)); - logger_.reset_on_disconnect(); -} - bool CastMediaSinkServiceImpl::HasSink(const MediaSink::Id& sink_id) { return base::Contains(GetSinks(), sink_id); }
diff --git a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl.h b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl.h index 4cc4cab..ff61150f 100644 --- a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl.h +++ b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl.h
@@ -99,8 +99,6 @@ // Called by CastMediaSinkService to set |allow_all_ips_|. void SetCastAllowAllIPs(bool allow_all_ips); - void BindLogger(mojo::PendingRemote<mojom::Logger> pending_remote); - // Opens cast channel. This method will not open a channel if there is already // a pending request for |ip_endpoint|, or if a channel for |ip_endpoint| // already exists. @@ -379,11 +377,6 @@ // discovery. May be nullptr if the DIAL Media Route Provider is disabled. const raw_ptr<MediaSinkServiceBase> dial_media_sink_service_; - // Mojo Remote to the logger owned by the Media Router. The Remote is not - // bound until |BindLogger()| is called. Always check if |logger_.is_bound()| - // is true before using. - mojo::Remote<mojom::Logger> logger_; - // The SequencedTaskRunner on which methods are run. This shares the // same SequencedTaskRunner as the one used by |cast_socket_service_|. scoped_refptr<base::SequencedTaskRunner> task_runner_;
diff --git a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl_unittest.cc b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl_unittest.cc index d44488c..18ddced 100644 --- a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl_unittest.cc +++ b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl_unittest.cc
@@ -23,7 +23,6 @@ #include "components/cast_channel/cast_socket.h" #include "components/cast_channel/cast_socket_service.h" #include "components/cast_channel/cast_test_util.h" -#include "components/media_router/browser/logger_impl.h" #include "components/media_router/common/test/test_helper.h" #include "content/public/test/browser_task_environment.h" #include "content/public/test/test_utils.h" @@ -1422,27 +1421,6 @@ open_params.liveness_timeout.InSeconds()); } -TEST_P(CastMediaSinkServiceImplTest, BindLogger) { - std::unique_ptr<LoggerImpl> logger_1 = std::make_unique<LoggerImpl>(); - mojo::PendingRemote<mojom::Logger> pending_remote_1; - logger_1->BindReceiver(pending_remote_1.InitWithNewPipeAndPassReceiver()); - media_sink_service_impl_.BindLogger(std::move(pending_remote_1)); - - // Trying to bind another pending remote no-ops instead of causing - // a DCHECK failure from binding to a remote that's already bound. - mojo::PendingRemote<mojom::Logger> pending_remote_2; - std::unique_ptr<LoggerImpl> logger_2 = std::make_unique<LoggerImpl>(); - logger_2->BindReceiver(pending_remote_2.InitWithNewPipeAndPassReceiver()); - media_sink_service_impl_.BindLogger(std::move(pending_remote_2)); - - // Trying to bind a disconnected receiver should work. - logger_1.reset(); - std::unique_ptr<LoggerImpl> logger_3 = std::make_unique<LoggerImpl>(); - mojo::PendingRemote<mojom::Logger> pending_remote_3; - logger_3->BindReceiver(pending_remote_3.InitWithNewPipeAndPassReceiver()); - media_sink_service_impl_.BindLogger(std::move(pending_remote_3)); -} - TEST_P(CastMediaSinkServiceImplTest, TestHasSink) { MediaSinkInternal cast_sink1 = CreateCastSink(1); MediaSinkInternal cast_sink2 = CreateCastSink(2);
diff --git a/chrome/browser/media/router/logger_list.cc b/chrome/browser/media/router/logger_list.cc new file mode 100644 index 0000000..c9a680a --- /dev/null +++ b/chrome/browser/media/router/logger_list.cc
@@ -0,0 +1,72 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/media/router/logger_list.h" + +#include "base/task/sequenced_task_runner.h" +#include "content/public/browser/browser_task_traits.h" + +namespace media_router { + +// static +LoggerList* LoggerList::GetInstance() { + static LoggerList* instance = new LoggerList(); + return instance; +} + +void LoggerList::AddLogger(LoggerImpl* logger_impl) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + DCHECK(logger_impl); + loggers_.insert(logger_impl); +} + +void LoggerList::RemoveLogger(LoggerImpl* logger_impl) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + DCHECK(logger_impl); + loggers_.erase(logger_impl); +} + +void LoggerList::Log(LoggerImpl::Severity severity, + mojom::LogCategory category, + const std::string& component, + const std::string& message, + const std::string& sink_id, + const std::string& media_source, + const std::string& session_id) { + if (content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)) { + LogOnUiThread(severity, category, base::Time::Now(), component, message, + sink_id, media_source, session_id); + } else { + content::GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, + base::BindOnce(&LoggerList::LogOnUiThread, base::Unretained(this), + severity, category, base::Time::Now(), component, + message, sink_id, media_source, session_id)); + } +} + +int LoggerList::GetLoggerCount() const { + return loggers_.size(); +} + +LoggerList::LoggerList() = default; + +LoggerList::~LoggerList() = default; + +void LoggerList::LogOnUiThread(LoggerImpl::Severity severity, + mojom::LogCategory category, + base::Time time, + const std::string& component, + const std::string& message, + const std::string& sink_id, + const std::string& media_source, + const std::string& session_id) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + for (LoggerImpl* logger : loggers_) { + logger->Log(severity, category, time, component, message, sink_id, + media_source, session_id); + } +} + +} // namespace media_router
diff --git a/chrome/browser/media/router/logger_list.h b/chrome/browser/media/router/logger_list.h new file mode 100644 index 0000000..689e7d3 --- /dev/null +++ b/chrome/browser/media/router/logger_list.h
@@ -0,0 +1,65 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_MEDIA_ROUTER_LOGGER_LIST_H_ +#define CHROME_BROWSER_MEDIA_ROUTER_LOGGER_LIST_H_ + +#include <set> + +#include "components/media_router/browser/logger_impl.h" +#include "content/public/browser/browser_thread.h" + +namespace media_router { + +// This class uses a list of LoggerImpl instances to handle logging from within +// MediaSinkService component. It allows a client to log to multiple LoggerImpl +// instances at once, where each instance is typically associated with a +// Profile. It is used as a singleton that is never freed. All methods must be +// called on the UI thread except for GetInstance() and Log() as it also handles +// logging for MediaSinkService classes that are on IO thread. +class LoggerList { + public: + // Can be called on any thread. + // Returns the lazily-created singleton instance. + static LoggerList* GetInstance(); + + LoggerList(const LoggerList&) = delete; + LoggerList& operator=(const LoggerList&) = delete; + + // Only on the UI thread. + void AddLogger(LoggerImpl* logger_impl); + void RemoveLogger(LoggerImpl* logger_impl); + + // Can be called on any thread. + void Log(LoggerImpl::Severity severity, + mojom::LogCategory category, + const std::string& component, + const std::string& message, + const std::string& sink_id, + const std::string& media_source, + const std::string& session_id); + + // Used by tests. + int GetLoggerCount() const; + + private: + LoggerList(); + ~LoggerList(); + + // Only on the UI thread. + void LogOnUiThread(LoggerImpl::Severity severity, + mojom::LogCategory category, + base::Time time, + const std::string& component, + const std::string& message, + const std::string& sink_id, + const std::string& media_source, + const std::string& session_id); + + std::set<raw_ptr<LoggerImpl>> loggers_; +}; + +} // namespace media_router + +#endif // CHROME_BROWSER_MEDIA_ROUTER_LOGGER_LIST_H_
diff --git a/chrome/browser/media/router/logger_list_unittest.cc b/chrome/browser/media/router/logger_list_unittest.cc new file mode 100644 index 0000000..820f705b --- /dev/null +++ b/chrome/browser/media/router/logger_list_unittest.cc
@@ -0,0 +1,86 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/media/router/logger_list.h" + +#include "base/json/json_reader.h" +#include "content/public/test/browser_task_environment.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace media_router { + +class LoggerListTest : public testing::Test { + protected: + std::string GetAttributeOfFirstEntry(const std::string& logs_json, + const std::string& attribute) { + base::Value logs = base::JSONReader::Read(logs_json).value(); + return *logs.GetList()[0].FindStringKey(attribute); + } + + // Must be on Chrome_UIThread, as adding/removing loggers to/from LoggerList + // can only be done on UI thread. + content::BrowserTaskEnvironment task_environment_; +}; + +TEST_F(LoggerListTest, AddingAndRemovingLoggers) { + LoggerImpl logger1, logger2, logger3; + LoggerList* logger_list = LoggerList::GetInstance(); + EXPECT_EQ(logger_list->GetLoggerCount(), 0); + logger_list->AddLogger(&logger1); + EXPECT_EQ(logger_list->GetLoggerCount(), 1); + logger_list->AddLogger(&logger2); + EXPECT_EQ(logger_list->GetLoggerCount(), 2); + logger_list->AddLogger(&logger1); + EXPECT_EQ(logger_list->GetLoggerCount(), 2); + logger_list->RemoveLogger(&logger1); + EXPECT_EQ(logger_list->GetLoggerCount(), 1); + logger_list->RemoveLogger(&logger1); + EXPECT_EQ(logger_list->GetLoggerCount(), 1); + logger_list->AddLogger(&logger3); + EXPECT_EQ(logger_list->GetLoggerCount(), 2); + logger_list->RemoveLogger(&logger3); + EXPECT_EQ(logger_list->GetLoggerCount(), 1); + logger_list->RemoveLogger(&logger2); + EXPECT_EQ(logger_list->GetLoggerCount(), 0); +} + +TEST_F(LoggerListTest, Log) { + LoggerImpl logger1, logger2; + LoggerList* logger_list = LoggerList::GetInstance(); + logger_list->AddLogger(&logger1); + logger_list->AddLogger(&logger2); + + logger_list->Log(LoggerImpl::Severity::kInfo, mojom::LogCategory::kDiscovery, + "MyComponent", "My message", "sink-12345", "cast:ABCDEFGH", + "session-67890"); + + const std::string logs1 = logger1.GetLogsAsJson(); + const std::string logs2 = logger2.GetLogsAsJson(); + + std::string time_field = GetAttributeOfFirstEntry(logs1, "time"); + const std::string expected_logs = + R"([ + { + "severity": "Info", + "category": "Discovery", + "component": "MyComponent", + "time": ")" + + time_field + R"(", + "message": "My message", + "sinkId": "2345", + "mediaSource": "cast:ABCDEFGH", + "sessionId": "7890" + } + ])"; + + EXPECT_EQ(base::JSONReader::Read(logs1), + base::JSONReader::Read(expected_logs)); + EXPECT_EQ(base::JSONReader::Read(logs2), + base::JSONReader::Read(expected_logs)); + + logger_list->RemoveLogger(&logger1); + logger_list->RemoveLogger(&logger2); +} + +} // namespace media_router
diff --git a/chrome/browser/media/router/mojo/media_router_desktop.cc b/chrome/browser/media/router/mojo/media_router_desktop.cc index 2041878..a74011f 100644 --- a/chrome/browser/media/router/mojo/media_router_desktop.cc +++ b/chrome/browser/media/router/mojo/media_router_desktop.cc
@@ -37,7 +37,7 @@ MediaRouterDesktop::~MediaRouterDesktop() { if (media_sink_service_) - media_sink_service_->RemoveLogger(); + media_sink_service_->RemoveLogger(GetLogger()); } void MediaRouterDesktop::OnUserGesture() { @@ -137,7 +137,7 @@ void MediaRouterDesktop::Initialize() { MediaRouterMojoImpl::Initialize(); if (media_sink_service_) { - media_sink_service_->BindLogger(GetLogger()); + media_sink_service_->AddLogger(GetLogger()); InitializeMediaRouteProviders(); #if BUILDFLAG(IS_WIN) CanFirewallUseLocalPorts(
diff --git a/chrome/browser/media/router/providers/cast/cast_app_discovery_service.cc b/chrome/browser/media/router/providers/cast/cast_app_discovery_service.cc index 7362ca9..a236b2a 100644 --- a/chrome/browser/media/router/providers/cast/cast_app_discovery_service.cc +++ b/chrome/browser/media/router/providers/cast/cast_app_discovery_service.cc
@@ -82,15 +82,14 @@ cast_channel::CastSocket* socket = socket_service_->GetSocket(channel_id); if (!socket) { - if (logger_.is_bound()) { - logger_->LogError( - mojom::LogCategory::kDiscovery, kLoggerComponent, - base::StringPrintf( - "Socket not found for channel id: %d when starting " - "discovery for source.", - channel_id), - sink.first, source.source_id(), ""); - } + LoggerList::GetInstance()->Log( + LoggerImpl::Severity::kError, mojom::LogCategory::kDiscovery, + kLoggerComponent, + base::StringPrintf( + "Socket not found for channel id: %d when starting " + "discovery for source.", + channel_id), + sink.first, source.source_id(), ""); continue; } RequestAppAvailability(socket, app_id, sink.second); @@ -111,15 +110,14 @@ int channel_id = sink.second.cast_data().cast_channel_id; cast_channel::CastSocket* socket = socket_service_->GetSocket(channel_id); if (!socket) { - if (logger_.is_bound()) { - logger_->LogError( - mojom::LogCategory::kDiscovery, kLoggerComponent, - base::StringPrintf( - "Socket not found for channel id: %d when refreshing " - "the discovery state.", - channel_id), - sink.first, "", ""); - } + LoggerList::GetInstance()->Log( + LoggerImpl::Severity::kError, mojom::LogCategory::kDiscovery, + kLoggerComponent, + base::StringPrintf( + "Socket not found for channel id: %d when refreshing " + "the discovery state.", + channel_id), + sink.first, "", ""); continue; } RequestAppAvailability(socket, app_id, sink.second); @@ -127,19 +125,6 @@ } } -void CastAppDiscoveryServiceImpl::BindLogger( - mojo::PendingRemote<mojom::Logger> pending_remote) { - // TODO(crbug.com/1293535): Simplify how logger instances are made available - // to their clients. - - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - // Reset |logger_| if it is bound to a disconnected remote. - if (logger_.is_bound()) - return; - logger_.Bind(std::move(pending_remote)); - logger_.reset_on_disconnect(); -} - scoped_refptr<base::SequencedTaskRunner> CastAppDiscoveryServiceImpl::task_runner() { return socket_service_->task_runner(); @@ -169,14 +154,13 @@ cast_channel::CastSocket* socket = socket_service_->GetSocket(sink.cast_channel_id()); if (!socket) { - if (logger_.is_bound()) { - logger_->LogError( - mojom::LogCategory::kDiscovery, kLoggerComponent, - base::StringPrintf("Socket not found for channel id: " - "%d when the sink is added or updated.", - sink.cast_channel_id()), - sink.id(), "", ""); - } + LoggerList::GetInstance()->Log( + LoggerImpl::Severity::kError, mojom::LogCategory::kDiscovery, + kLoggerComponent, + base::StringPrintf("Socket not found for channel id: " + "%d when the sink is added or updated.", + sink.cast_channel_id()), + sink.id(), "", ""); return; } @@ -215,10 +199,10 @@ cast_channel::GetAppAvailabilityResult availability) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); RecordAppAvailabilityResult(availability, clock_->NowTicks() - start_time); - if (availability != cast_channel::GetAppAvailabilityResult::kAvailable && - logger_.is_bound()) { - logger_->LogInfo( - mojom::LogCategory::kDiscovery, kLoggerComponent, + if (availability != cast_channel::GetAppAvailabilityResult::kAvailable) { + LoggerList::GetInstance()->Log( + LoggerImpl::Severity::kInfo, mojom::LogCategory::kDiscovery, + kLoggerComponent, base::StrCat({"App ", app_id, " on sink is ", ToString(availability)}), sink.id(), "", ""); }
diff --git a/chrome/browser/media/router/providers/cast/cast_app_discovery_service.h b/chrome/browser/media/router/providers/cast/cast_app_discovery_service.h index 7e044f74..e203447e 100644 --- a/chrome/browser/media/router/providers/cast/cast_app_discovery_service.h +++ b/chrome/browser/media/router/providers/cast/cast_app_discovery_service.h
@@ -16,14 +16,13 @@ #include "base/memory/weak_ptr.h" #include "base/task/sequenced_task_runner.h" #include "base/time/time.h" +#include "chrome/browser/media/router/logger_list.h" #include "chrome/browser/media/router/providers/cast/cast_app_availability_tracker.h" #include "components/cast_channel/cast_message_util.h" #include "components/media_router/common/discovery/media_sink_service_base.h" #include "components/media_router/common/media_sink.h" #include "components/media_router/common/media_source.h" -#include "components/media_router/common/mojom/logger.mojom.h" #include "components/media_router/common/providers/cast/cast_media_source.h" -#include "mojo/public/cpp/bindings/remote.h" namespace base { class TickClock; @@ -60,10 +59,6 @@ // Media Router dialog). virtual void Refresh() = 0; - // Binds |pending_remote| to the Mojo Remote owned by |impl_|. - virtual void BindLogger( - mojo::PendingRemote<mojom::Logger> pending_remote) = 0; - // Returns the SequencedTaskRunner that should be used to invoke methods on // this instance. Can be invoked on any thread. virtual scoped_refptr<base::SequencedTaskRunner> task_runner() = 0; @@ -96,8 +91,6 @@ // pairs whose status is kUnavailable or kUnknown. void Refresh() override; - void BindLogger(mojo::PendingRemote<mojom::Logger> pending_remote) override; - scoped_refptr<base::SequencedTaskRunner> task_runner() override; private: @@ -154,10 +147,6 @@ CastAppAvailabilityTracker availability_tracker_; const raw_ptr<const base::TickClock> clock_; - // Mojo Remote to the logger owned by the Media Router. The Remote is not - // bound until |BindLogger()| is called. Always check if |logger_.is_bound()| - // is true before using. - mojo::Remote<mojom::Logger> logger_; SEQUENCE_CHECKER(sequence_checker_); base::WeakPtrFactory<CastAppDiscoveryServiceImpl> weak_ptr_factory_{this};
diff --git a/chrome/browser/media/router/providers/cast/cast_app_discovery_service_unittest.cc b/chrome/browser/media/router/providers/cast/cast_app_discovery_service_unittest.cc index ca506dd..6c3f7f34 100644 --- a/chrome/browser/media/router/providers/cast/cast_app_discovery_service_unittest.cc +++ b/chrome/browser/media/router/providers/cast/cast_app_discovery_service_unittest.cc
@@ -10,7 +10,6 @@ #include "base/test/test_simple_task_runner.h" #include "chrome/browser/media/router/test/provider_test_helpers.h" #include "components/cast_channel/cast_test_util.h" -#include "components/media_router/browser/logger_impl.h" #include "components/media_router/common/discovery/media_sink_service_base.h" #include "components/media_router/common/providers/cast/cast_media_source.h" #include "components/media_router/common/test/test_helper.h" @@ -328,24 +327,4 @@ AddOrUpdateSink(sink1); } -TEST_F(CastAppDiscoveryServiceTest, BindLogger) { - std::unique_ptr<LoggerImpl> logger_1 = std::make_unique<LoggerImpl>(); - mojo::PendingRemote<mojom::Logger> pending_remote_1; - logger_1->BindReceiver(pending_remote_1.InitWithNewPipeAndPassReceiver()); - app_discovery_service_->BindLogger(std::move(pending_remote_1)); - - // Trying to bind another pending remote no-ops instead of causing - // a DCHECK failure from binding to a remote that's already bound. - std::unique_ptr<LoggerImpl> logger_2 = std::make_unique<LoggerImpl>(); - mojo::PendingRemote<mojom::Logger> pending_remote_2; - logger_2->BindReceiver(pending_remote_2.InitWithNewPipeAndPassReceiver()); - app_discovery_service_->BindLogger(std::move(pending_remote_2)); - - // Trying to bind a disconnected receiver should work. - logger_1.reset(); - std::unique_ptr<LoggerImpl> logger_3 = std::make_unique<LoggerImpl>(); - mojo::PendingRemote<mojom::Logger> pending_remote_3; - logger_3->BindReceiver(pending_remote_3.InitWithNewPipeAndPassReceiver()); - app_discovery_service_->BindLogger(std::move(pending_remote_3)); -} } // namespace media_router
diff --git a/chrome/browser/media/router/providers/cast/dual_media_sink_service.cc b/chrome/browser/media/router/providers/cast/dual_media_sink_service.cc index dee7862..ec38895c 100644 --- a/chrome/browser/media/router/providers/cast/dual_media_sink_service.cc +++ b/chrome/browser/media/router/providers/cast/dual_media_sink_service.cc
@@ -115,37 +115,12 @@ sinks_discovered_callbacks_.Notify(provider_name, sinks_for_provider); } -void DualMediaSinkService::BindLogger(LoggerImpl* logger_impl) { - // TODO(crbug.com/1293535): Simplify how logger instances are made available - // to their clients. - - if (logger_is_bound_) - return; - logger_is_bound_ = true; - cast_media_sink_service_->BindLogger(logger_impl); - - if (dial_media_sink_service_) { - mojo::PendingRemote<mojom::Logger> dial_pending_remote; - logger_impl->BindReceiver( - dial_pending_remote.InitWithNewPipeAndPassReceiver()); - dial_media_sink_service_->BindLogger(std::move(dial_pending_remote)); - } - - mojo::PendingRemote<mojom::Logger> cast_discovery_pending_remote; - logger_impl->BindReceiver( - cast_discovery_pending_remote.InitWithNewPipeAndPassReceiver()); - cast_app_discovery_service_->task_runner()->PostTask( - FROM_HERE, - base::BindOnce(&CastAppDiscoveryService::BindLogger, - base::Unretained(cast_app_discovery_service_.get()), - std::move(cast_discovery_pending_remote))); +void DualMediaSinkService::AddLogger(LoggerImpl* logger_impl) { + LoggerList::GetInstance()->AddLogger(logger_impl); } -void DualMediaSinkService::RemoveLogger() { - if (!logger_is_bound_) - return; - logger_is_bound_ = false; - cast_media_sink_service_->RemoveLogger(); +void DualMediaSinkService::RemoveLogger(LoggerImpl* logger_impl) { + LoggerList::GetInstance()->RemoveLogger(logger_impl); } } // namespace media_router
diff --git a/chrome/browser/media/router/providers/cast/dual_media_sink_service.h b/chrome/browser/media/router/providers/cast/dual_media_sink_service.h index 10056ce..4133001 100644 --- a/chrome/browser/media/router/providers/cast/dual_media_sink_service.h +++ b/chrome/browser/media/router/providers/cast/dual_media_sink_service.h
@@ -71,15 +71,9 @@ base::CallbackListSubscription AddSinksDiscoveredCallback( const OnSinksDiscoveredProviderCallback& callback); - // Instantiate two PendingRemote objects. The objects will be bound with - // |logger_impl| and passed to |cast_media_sink_service_| and - // |dial_media_sink_service_|. - // The binding should be done once and the method is a no-op after the first - // call. - // Marked virtual for testing. - virtual void BindLogger(LoggerImpl* logger_impl); + void AddLogger(LoggerImpl* logger_impl); - virtual void RemoveLogger(); + void RemoveLogger(LoggerImpl* logger_impl); virtual void OnUserGesture(); @@ -120,8 +114,6 @@ std::unique_ptr<CastMediaSinkService> cast_media_sink_service_; std::unique_ptr<CastAppDiscoveryService> cast_app_discovery_service_; - bool logger_is_bound_ = false; - OnSinksDiscoveredProviderCallbackList sinks_discovered_callbacks_; base::flat_map<std::string, std::vector<MediaSinkInternal>> current_sinks_;
diff --git a/chrome/browser/media/router/providers/cast/dual_media_sink_service_unittest.cc b/chrome/browser/media/router/providers/cast/dual_media_sink_service_unittest.cc index 66ab988a..6aed657 100644 --- a/chrome/browser/media/router/providers/cast/dual_media_sink_service_unittest.cc +++ b/chrome/browser/media/router/providers/cast/dual_media_sink_service_unittest.cc
@@ -8,7 +8,6 @@ #include "base/memory/raw_ptr.h" #include "base/run_loop.h" #include "chrome/browser/media/router/test/provider_test_helpers.h" -#include "components/media_router/browser/logger_impl.h" #include "content/public/test/browser_task_environment.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -116,29 +115,4 @@ base::Unretained(this))); } -TEST_F(DualMediaSinkServiceTest, BindAndRemoveLogger) { - std::unique_ptr<LoggerImpl> logger = std::make_unique<LoggerImpl>(); - EXPECT_CALL(*cast_media_sink_service_, BindLogger(logger.get())); - EXPECT_CALL(*dial_media_sink_service_, BindLogger(_)); - EXPECT_CALL(*cast_app_discovery_service_, BindLogger(_)); - dual_media_sink_service_->BindLogger(logger.get()); - base::RunLoop().RunUntilIdle(); - - // |dual_media_sink_service_| cannot bind a new logger if the old one is not - // removed. - EXPECT_CALL(*cast_media_sink_service_, BindLogger(_)).Times(0); - EXPECT_CALL(*dial_media_sink_service_, BindLogger(_)).Times(0); - EXPECT_CALL(*cast_app_discovery_service_, BindLogger(_)).Times(0); - dual_media_sink_service_->BindLogger(logger.get()); - - EXPECT_CALL(*cast_media_sink_service_, RemoveLogger()); - dual_media_sink_service_->RemoveLogger(); - - EXPECT_CALL(*cast_media_sink_service_, BindLogger(logger.get())); - EXPECT_CALL(*dial_media_sink_service_, BindLogger(_)); - EXPECT_CALL(*cast_app_discovery_service_, BindLogger(_)); - dual_media_sink_service_->BindLogger(logger.get()); - base::RunLoop().RunUntilIdle(); -} - } // namespace media_router
diff --git a/chrome/browser/media/router/test/noop_dual_media_sink_service.h b/chrome/browser/media/router/test/noop_dual_media_sink_service.h index 4c82dc4..645ba9cc 100644 --- a/chrome/browser/media/router/test/noop_dual_media_sink_service.h +++ b/chrome/browser/media/router/test/noop_dual_media_sink_service.h
@@ -10,8 +10,6 @@ namespace media_router { -class LoggerImpl; - class NoopDualMediaSinkService : public DualMediaSinkService { public: NoopDualMediaSinkService(); @@ -26,8 +24,6 @@ #if BUILDFLAG(IS_WIN) void StartMdnsDiscovery() override {} #endif - void BindLogger(LoggerImpl* logger_impl) override {} - void RemoveLogger() override {} }; } // namespace media_router
diff --git a/chrome/browser/media/router/test/provider_test_helpers.h b/chrome/browser/media/router/test/provider_test_helpers.h index bc213851..494f9f39 100644 --- a/chrome/browser/media/router/test/provider_test_helpers.h +++ b/chrome/browser/media/router/test/provider_test_helpers.h
@@ -25,7 +25,6 @@ #include "components/media_router/browser/media_sinks_observer.h" #include "components/media_router/browser/test/test_helper.h" #include "components/media_router/common/discovery/media_sink_internal.h" -#include "components/media_router/common/mojom/logger.mojom.h" #include "net/base/ip_endpoint.h" #include "services/network/test/test_url_loader_factory.h" #include "testing/gmock/include/gmock/gmock.h" @@ -40,7 +39,6 @@ MOCK_METHOD1(Start, void(const OnSinksDiscoveredCallback&)); MOCK_METHOD0(OnUserGesture, void()); - MOCK_METHOD1(BindLogger, void(mojo::PendingRemote<mojom::Logger>)); }; class MockCastMediaSinkService : public CastMediaSinkService { @@ -51,8 +49,6 @@ MOCK_METHOD2(Start, void(const OnSinksDiscoveredCallback&, MediaSinkServiceBase*)); MOCK_METHOD0(OnUserGesture, void()); - MOCK_METHOD1(BindLogger, void(LoggerImpl*)); - MOCK_METHOD0(RemoveLogger, void()); MOCK_METHOD0(StartMdnsDiscovery, void()); }; @@ -67,7 +63,6 @@ scoped_refptr<base::SequencedTaskRunner> task_runner() override; MOCK_METHOD1(DoStartObservingMediaSinks, void(const CastMediaSource&)); MOCK_METHOD0(Refresh, void()); - MOCK_METHOD1(BindLogger, void(mojo::PendingRemote<mojom::Logger>)); SinkQueryCallbackList& callbacks() { return callbacks_; }
diff --git a/chrome/browser/page_load_metrics/observers/formfill_page_load_metrics_observer.cc b/chrome/browser/page_load_metrics/observers/formfill_page_load_metrics_observer.cc index 8307b8f..cac4d8ed 100644 --- a/chrome/browser/page_load_metrics/observers/formfill_page_load_metrics_observer.cc +++ b/chrome/browser/page_load_metrics/observers/formfill_page_load_metrics_observer.cc
@@ -22,12 +22,17 @@ FormfillPageLoadMetricsObserver::~FormfillPageLoadMetricsObserver() = default; -// TODO(https://crbug.com/1317494): Audit and use appropriate policy. +const char* FormfillPageLoadMetricsObserver::GetObserverName() const { + static const char kName[] = "FormfillPageLoadMetricsObserver"; + return kName; +} + page_load_metrics::PageLoadMetricsObserver::ObservePolicy FormfillPageLoadMetricsObserver::OnFencedFramesStart( content::NavigationHandle* navigation_handle, const GURL& currently_committed_url) { - return STOP_OBSERVING; + // OnFeaturesUsageObserved needs observer level forwarding. + return FORWARD_OBSERVING; } page_load_metrics::PageLoadMetricsObserver::ObservePolicy @@ -53,8 +58,7 @@ blink::mojom::WebFeature::kUserDataFieldFilledPreviously); } - return page_load_metrics::PageLoadMetricsObserver::ObservePolicy:: - CONTINUE_OBSERVING; + return CONTINUE_OBSERVING; } void FormfillPageLoadMetricsObserver::OnFeaturesUsageObserved(
diff --git a/chrome/browser/page_load_metrics/observers/formfill_page_load_metrics_observer.h b/chrome/browser/page_load_metrics/observers/formfill_page_load_metrics_observer.h index 717cf09..b49db23 100644 --- a/chrome/browser/page_load_metrics/observers/formfill_page_load_metrics_observer.h +++ b/chrome/browser/page_load_metrics/observers/formfill_page_load_metrics_observer.h
@@ -24,6 +24,7 @@ const FormfillPageLoadMetricsObserver&) = delete; // page_load_metrics::PageLoadMetricsObserver + const char* GetObserverName() const override; ObservePolicy OnFencedFramesStart( content::NavigationHandle* navigation_handle, const GURL& currently_committed_url) override;
diff --git a/chrome/browser/renderer_context_menu/render_view_context_menu_unittest.cc b/chrome/browser/renderer_context_menu/render_view_context_menu_unittest.cc index a51f5be..49db2cae 100644 --- a/chrome/browser/renderer_context_menu/render_view_context_menu_unittest.cc +++ b/chrome/browser/renderer_context_menu/render_view_context_menu_unittest.cc
@@ -1068,7 +1068,13 @@ EXPECT_FALSE(menu.IsItemPresent(IDC_CONTENT_CONTEXT_LENS_REGION_SEARCH)); } -TEST_F(RenderViewContextMenuPrefsTest, LensRegionSearchPdfEnabled) { +#if BUILDFLAG(IS_CHROMEOS) +#define MAYBE_LensRegionSearchPdfEnabled DISABLED_LensRegionSearchPdfEnabled +#else +#define MAYBE_LensRegionSearchPdfEnabled LensRegionSearchPdfEnabled +#endif +// TODO(https://crbug.com/1354637): Re-enable on ChromeOS. +TEST_F(RenderViewContextMenuPrefsTest, MAYBE_LensRegionSearchPdfEnabled) { base::test::ScopedFeatureList features; features.InitWithFeatures({lens::features::kLensStandalone, lens::features::kEnableRegionSearchOnPdfViewer},
diff --git a/chrome/browser/reputation/reputation_service.cc b/chrome/browser/reputation/reputation_service.cc index 2dc6238..24391a6 100644 --- a/chrome/browser/reputation/reputation_service.cc +++ b/chrome/browser/reputation/reputation_service.cc
@@ -160,6 +160,10 @@ num_sensitive_keywords_ = top500_domains::kNumTopKeywords; } +void ReputationService::ResetWarningDismissedETLDPlusOnesForTesting() { + warning_dismissed_etld1s_.clear(); +} + void ReputationService::GetReputationStatusWithEngagedSites( const GURL& url, bool has_delayed_warning,
diff --git a/chrome/browser/reputation/reputation_service.h b/chrome/browser/reputation/reputation_service.h index 3a239ee3..b21a490 100644 --- a/chrome/browser/reputation/reputation_service.h +++ b/chrome/browser/reputation/reputation_service.h
@@ -96,6 +96,10 @@ size_t num_new_keywords); void ResetSensitiveKeywordsForTesting(); + // Reset set of eTLD+1s to forget the user action that ignores warning. Only + // for testing. + void ResetWarningDismissedETLDPlusOnesForTesting(); + private: // Callback once we have up-to-date |engaged_sites|. Performs checks on the // navigated |url|. |has_delayed_warning| is true if the relevant WebContents
diff --git a/chrome/browser/resources/settings/autofill_page/password_edit_dialog.ts b/chrome/browser/resources/settings/autofill_page/password_edit_dialog.ts index bc4d111..b4a48c9e 100644 --- a/chrome/browser/resources/settings/autofill_page/password_edit_dialog.ts +++ b/chrome/browser/resources/settings/autofill_page/password_edit_dialog.ts
@@ -257,7 +257,7 @@ }, }, - /* If true, change event will be dispatched. */ + /* Enables dispatching change events and extending auth. */ isPasswordViewPageEnabled_: { type: Boolean, value() { @@ -267,6 +267,12 @@ }; } + static get observers() { + return [ + 'extendAuthValidityOnUserInteraction_(username_, password_, note_)', + ]; + } + existingEntry: chrome.passwordsPrivate.PasswordUiEntry|null; isAccountStoreUser: boolean; accountEmail: string|null; @@ -780,6 +786,13 @@ return usernamesByOrigin; }, new Map()); } + + private extendAuthValidityOnUserInteraction_() { + if (!this.isPasswordViewPageEnabled_) { + return; + } + PasswordManagerImpl.getInstance().extendAuthValidity(); + } } declare global {
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 9a069c4..4a80da0 100644 --- a/chrome/browser/resources/settings/autofill_page/password_manager_proxy.ts +++ b/chrome/browser/resources/settings/autofill_page/password_manager_proxy.ts
@@ -266,6 +266,11 @@ isManualFlow: boolean): void; /** + * Requests extension of authentication validity. + */ + extendAuthValidity(): void; + + /** * Add an observer to the compromised passwords change. */ addCompromisedCredentialsListener(listener: CredentialsChangedListener): void; @@ -595,6 +600,10 @@ insecureCredential, isManualFlow); } + extendAuthValidity() { + chrome.passwordsPrivate.extendAuthValidity(); + } + addCompromisedCredentialsListener(listener: CredentialsChangedListener) { chrome.passwordsPrivate.onCompromisedCredentialsChanged.addListener( listener);
diff --git a/chrome/browser/resources/settings/chromeos/BUILD.gn b/chrome/browser/resources/settings/chromeos/BUILD.gn index 8316eaf..6df253bf 100644 --- a/chrome/browser/resources/settings/chromeos/BUILD.gn +++ b/chrome/browser/resources/settings/chromeos/BUILD.gn
@@ -6,6 +6,7 @@ import("//third_party/closure_compiler/compile_js.gni") import("//tools/grit/grit_rule.gni") import("//tools/grit/preprocess_if_expr.gni") +import("//tools/polymer/css_to_wrapper.gni") import("//tools/polymer/html_to_js.gni") import("//tools/polymer/html_to_wrapper.gni") import("//tools/typescript/ts_library.gni") @@ -130,6 +131,7 @@ preprocess_if_expr("preprocess_gen_ts_files") { defines = chrome_grit_defines deps = [ + ":generate_web_component_css_wrapper_files", ":generate_web_component_html_wrapper_files", ":generate_web_components", ] @@ -144,6 +146,12 @@ out_folder = get_path_info("../", "gen_dir") } +css_to_wrapper("generate_web_component_css_wrapper_files") { + in_folder = "../" + in_files = css_files + out_folder = get_path_info("../", "gen_dir") +} + # Generate all WebUI mojom files and copy them to preprocessed_ts_folder to be # input to ts_library(). These files are bundled in optimized builds. group("generate_mojom_webui") { @@ -425,10 +433,6 @@ "os_apps_page/app_notifications_page:web_components", "os_bluetooth_page:web_components", "os_files_page:web_components", - - # TODO(crbug.com/1322682): Migrate os_languages_page's CSS files to - # css_to_wrapper(). - "os_languages_page:css_wrapper_files", "os_people_page:web_components", "os_printing_page:web_components", "os_privacy_page:web_components",
diff --git a/chrome/browser/resources/settings/chromeos/crostini_page/BUILD.gn b/chrome/browser/resources/settings/chromeos/crostini_page/BUILD.gn index 2eb153e..10ec1cb 100644 --- a/chrome/browser/resources/settings/chromeos/crostini_page/BUILD.gn +++ b/chrome/browser/resources/settings/chromeos/crostini_page/BUILD.gn
@@ -24,6 +24,7 @@ ":crostini_page", ":crostini_port_forwarding", ":crostini_port_forwarding_add_port_dialog", + ":crostini_shared_usb_devices", ":crostini_subpage", ] } @@ -131,6 +132,7 @@ ":crostini_export_import", ":crostini_extra_containers", ":crostini_port_forwarding", + ":crostini_shared_usb_devices", ":crostini_subpage", "..:deep_linking_behavior", "..:os_route", @@ -237,6 +239,14 @@ externs_list = [ "../settings_controls_types.js" ] } +js_library("crostini_shared_usb_devices") { + deps = [ + ":crostini_browser_proxy", + "../guest_os:guest_os_shared_usb_devices", + "//ui/webui/resources/js:load_time_data.m", + ] +} + js_library("bruschetta_subpage") { deps = [ "..:deep_linking_behavior",
diff --git a/chrome/browser/resources/settings/chromeos/crostini_page/crostini_browser_proxy.js b/chrome/browser/resources/settings/chromeos/crostini_page/crostini_browser_proxy.js index 5a00ff35..65e1861 100644 --- a/chrome/browser/resources/settings/chromeos/crostini_page/crostini_browser_proxy.js +++ b/chrome/browser/resources/settings/chromeos/crostini_page/crostini_browser_proxy.js
@@ -13,7 +13,7 @@ /** @type {string} */ export const DEFAULT_CROSTINI_VM = 'termina'; /** @type {string} */ export const DEFAULT_CROSTINI_CONTAINER = 'penguin'; -/** @type {!GuestId} */ export const DEFAULT_CONTAINER_ID = { +/** @type {!GuestId} */ export const DEFAULT_CROSTINI_GUEST_ID = { vm_name: DEFAULT_CROSTINI_VM, container_name: DEFAULT_CROSTINI_CONTAINER, }; @@ -74,7 +74,7 @@ * to install and uninstall Crostini. */ - /** @interface */ +/** @interface */ export class CrostiniBrowserProxy { /* Show crostini installer. */ requestCrostiniInstallerView() {}
diff --git a/chrome/browser/resources/settings/chromeos/crostini_page/crostini_export_import.js b/chrome/browser/resources/settings/chromeos/crostini_page/crostini_export_import.js index aeb5c72..710a3482 100644 --- a/chrome/browser/resources/settings/chromeos/crostini_page/crostini_export_import.js +++ b/chrome/browser/resources/settings/chromeos/crostini_page/crostini_export_import.js
@@ -23,7 +23,7 @@ import {routes} from '../os_route.js'; import {RouteObserverBehavior, RouteObserverBehaviorInterface} from '../route_observer_behavior.js'; -import {CrostiniBrowserProxy, CrostiniBrowserProxyImpl, DEFAULT_CONTAINER_ID, DEFAULT_CROSTINI_VM} from './crostini_browser_proxy.js'; +import {CrostiniBrowserProxy, CrostiniBrowserProxyImpl, DEFAULT_CROSTINI_GUEST_ID, DEFAULT_CROSTINI_VM} from './crostini_browser_proxy.js'; /** * @constructor @@ -106,7 +106,7 @@ exportContainerId_: { type: Object, value() { - return DEFAULT_CONTAINER_ID; + return DEFAULT_CROSTINI_GUEST_ID; }, }, @@ -118,7 +118,7 @@ importContainerId_: { type: Object, value() { - return DEFAULT_CONTAINER_ID; + return DEFAULT_CROSTINI_GUEST_ID; }, }, @@ -188,8 +188,8 @@ onContainerInfo_(containerInfos) { this.allContainers_ = containerInfos; if (!this.isMultiContainer_(containerInfos)) { - this.exportContainerId_ = DEFAULT_CONTAINER_ID; - this.importContainerId_ = DEFAULT_CONTAINER_ID; + this.exportContainerId_ = DEFAULT_CROSTINI_GUEST_ID; + this.importContainerId_ = DEFAULT_CROSTINI_GUEST_ID; } } @@ -226,7 +226,7 @@ isMultiContainer_(allContainers) { return !( allContainers.length === 1 && - equalContainerId(allContainers[0].id, DEFAULT_CONTAINER_ID)); + equalContainerId(allContainers[0].id, DEFAULT_CROSTINI_GUEST_ID)); } getSettingsBoxClass_(allContainers) {
diff --git a/chrome/browser/resources/settings/chromeos/crostini_page/crostini_page.html b/chrome/browser/resources/settings/chromeos/crostini_page/crostini_page.html index 0dfeb32d..d5ceb3af 100644 --- a/chrome/browser/resources/settings/chromeos/crostini_page/crostini_page.html +++ b/chrome/browser/resources/settings/chromeos/crostini_page/crostini_page.html
@@ -100,8 +100,8 @@ <template is="dom-if" route-path="/crostini/sharedUsbDevices"> <settings-subpage page-title="$i18n{guestOsSharedUsbDevicesLabel}"> - <settings-guest-os-shared-usb-devices guest-os-type="crostini"> - </settings-guest-os-shared-usb-devices> + <settings-crostini-shared-usb-devices> + </settings-crostini-shared-usb-devices> </settings-subpage> </template>
diff --git a/chrome/browser/resources/settings/chromeos/crostini_page/crostini_page.js b/chrome/browser/resources/settings/chromeos/crostini_page/crostini_page.js index fbcd2cfa..505b039 100644 --- a/chrome/browser/resources/settings/chromeos/crostini_page/crostini_page.js +++ b/chrome/browser/resources/settings/chromeos/crostini_page/crostini_page.js
@@ -22,6 +22,7 @@ import './crostini_export_import.js'; import './crostini_extra_containers.js'; import './crostini_port_forwarding.js'; +import './crostini_shared_usb_devices.js'; import './crostini_subpage.js'; import './bruschetta_subpage.js';
diff --git a/chrome/browser/resources/settings/chromeos/crostini_page/crostini_port_forwarding.js b/chrome/browser/resources/settings/chromeos/crostini_page/crostini_port_forwarding.js index 6bf4bb05..8151cbe 100644 --- a/chrome/browser/resources/settings/chromeos/crostini_page/crostini_port_forwarding.js +++ b/chrome/browser/resources/settings/chromeos/crostini_page/crostini_port_forwarding.js
@@ -28,7 +28,7 @@ import {recordSettingChange} from '../metrics_recorder.js'; import {PrefsBehavior, PrefsBehaviorInterface} from '../prefs_behavior.js'; -import {CrostiniBrowserProxy, CrostiniBrowserProxyImpl, CrostiniPortActiveSetting, CrostiniPortProtocol, CrostiniPortSetting, DEFAULT_CONTAINER_ID, DEFAULT_CROSTINI_CONTAINER, DEFAULT_CROSTINI_VM} from './crostini_browser_proxy.js'; +import {CrostiniBrowserProxy, CrostiniBrowserProxyImpl, CrostiniPortActiveSetting, CrostiniPortProtocol, CrostiniPortSetting, DEFAULT_CROSTINI_CONTAINER, DEFAULT_CROSTINI_GUEST_ID, DEFAULT_CROSTINI_VM} from './crostini_browser_proxy.js'; /** * @constructor @@ -282,7 +282,8 @@ showContainerId_(allPorts, id) { return allPorts.some(port => equalContainerId(port.container_id, id)) && allPorts.some( - port => !equalContainerId(port.container_id, DEFAULT_CONTAINER_ID)); + port => !equalContainerId( + port.container_id, DEFAULT_CROSTINI_GUEST_ID)); } /**
diff --git a/chrome/browser/resources/settings/chromeos/crostini_page/crostini_port_forwarding_add_port_dialog.js b/chrome/browser/resources/settings/chromeos/crostini_page/crostini_port_forwarding_add_port_dialog.js index 0170bcd..f478c2a 100644 --- a/chrome/browser/resources/settings/chromeos/crostini_page/crostini_port_forwarding_add_port_dialog.js +++ b/chrome/browser/resources/settings/chromeos/crostini_page/crostini_port_forwarding_add_port_dialog.js
@@ -19,7 +19,7 @@ import {ContainerInfo, GuestId} from '../guest_os/guest_os_browser_proxy.js'; -import {CrostiniBrowserProxy, CrostiniBrowserProxyImpl, CrostiniPortProtocol, CrostiniPortSetting, DEFAULT_CONTAINER_ID, DEFAULT_CROSTINI_VM, MAX_VALID_PORT_NUMBER, MIN_VALID_PORT_NUMBER, PortState} from './crostini_browser_proxy.js'; +import {CrostiniBrowserProxy, CrostiniBrowserProxyImpl, CrostiniPortProtocol, CrostiniPortSetting, DEFAULT_CROSTINI_GUEST_ID, DEFAULT_CROSTINI_VM, MAX_VALID_PORT_NUMBER, MIN_VALID_PORT_NUMBER, PortState} from './crostini_browser_proxy.js'; /** @polymer */ class CrostiniPortForwardingAddPortDialog extends PolymerElement { @@ -71,7 +71,7 @@ containerId_: { type: Object, value() { - return DEFAULT_CONTAINER_ID; + return DEFAULT_CROSTINI_GUEST_ID; }, },
diff --git a/chrome/browser/resources/settings/chromeos/crostini_page/crostini_shared_usb_devices.js b/chrome/browser/resources/settings/chromeos/crostini_page/crostini_shared_usb_devices.js new file mode 100644 index 0000000..044f6bc --- /dev/null +++ b/chrome/browser/resources/settings/chromeos/crostini_page/crostini_shared_usb_devices.js
@@ -0,0 +1,68 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/** + * @fileoverview 'settings-crostini-shared-usb-devices' is a variant of the + * shared usb devices subpage for Crostini. + */ + +import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js'; + +import {GuestId} from '../guest_os/guest_os_browser_proxy.js'; +import {SettingsGuestOsSharedUsbDevicesElement} from '../guest_os/guest_os_shared_usb_devices.js'; + +import {CrostiniBrowserProxy, CrostiniBrowserProxyImpl, DEFAULT_CROSTINI_GUEST_ID} from './crostini_browser_proxy.js'; + +/** @polymer */ +class CrostiniSharedUsbDevicesElement extends + SettingsGuestOsSharedUsbDevicesElement { + static get is() { + return 'settings-crostini-shared-usb-devices'; + } + + static get properties() { + return { + guestOsType: { + type: String, + value: 'crostini', + }, + + /** + * @type {!GuestId} + */ + defaultGuestId: { + type: Object, + value() { + return DEFAULT_CROSTINI_GUEST_ID; + }, + }, + + /** + * Whether the guest OS hosts multiple containers. + */ + hasContainers: { + type: Boolean, + value() { + return loadTimeData.getBoolean('showCrostiniExtraContainers'); + }, + }, + }; + } + + constructor() { + super(); + } + + /** @override */ + ready() { + super.ready(); + + this.addWebUIListener( + 'crostini-container-info', (infos) => this.onContainerInfo_(infos)); + CrostiniBrowserProxyImpl.getInstance().requestContainerInfo(); + } +} + +customElements.define( + CrostiniSharedUsbDevicesElement.is, CrostiniSharedUsbDevicesElement);
diff --git a/chrome/browser/resources/settings/chromeos/guest_os/BUILD.gn b/chrome/browser/resources/settings/chromeos/guest_os/BUILD.gn index c05382c..2d7d2a6 100644 --- a/chrome/browser/resources/settings/chromeos/guest_os/BUILD.gn +++ b/chrome/browser/resources/settings/chromeos/guest_os/BUILD.gn
@@ -14,6 +14,7 @@ ":guest_os_container_select", ":guest_os_shared_paths", ":guest_os_shared_usb_devices", + ":guest_os_shared_usb_devices_add_dialog", ] } @@ -36,6 +37,7 @@ deps = [ ":guest_os_browser_proxy", ":guest_os_container_select", + ":guest_os_shared_usb_devices_add_dialog", "..:metrics_recorder", "//ui/webui/resources/js:i18n_behavior.m", "//ui/webui/resources/js:web_ui_listener_behavior.m", @@ -44,6 +46,19 @@ [ "//ui/webui/resources/cr_elements/cr_toggle/cr_toggle_externs.js" ] } +js_library("guest_os_shared_usb_devices_add_dialog") { + deps = [ + ":guest_os_browser_proxy", + ":guest_os_container_select", + "..:metrics_recorder", + "//ui/webui/resources/cr_elements/cr_button:cr_button", + "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog", + "//ui/webui/resources/js:cr.m", + "//ui/webui/resources/js:i18n_behavior.m", + "//ui/webui/resources/js:load_time_data.m", + ] +} + js_library("guest_os_shared_paths") { deps = [ ":guest_os_browser_proxy", @@ -58,6 +73,7 @@ js_files = [ "guest_os_container_select.js", "guest_os_shared_usb_devices.js", + "guest_os_shared_usb_devices_add_dialog.js", "guest_os_shared_paths.js", ] }
diff --git a/chrome/browser/resources/settings/chromeos/guest_os/guest_os_browser_proxy.js b/chrome/browser/resources/settings/chromeos/guest_os/guest_os_browser_proxy.js index e4c83a33e..e97d649d 100644 --- a/chrome/browser/resources/settings/chromeos/guest_os/guest_os_browser_proxy.js +++ b/chrome/browser/resources/settings/chromeos/guest_os/guest_os_browser_proxy.js
@@ -7,7 +7,9 @@ /** * @typedef {{guid: string, * label: string, - * sharedWith: ?string, + * guestId: ?GuestId, + * vendorId: string, + * productId: string, * promptBeforeSharing: boolean}} */ export let GuestOsSharedUsbDevice; @@ -17,13 +19,13 @@ /** * Non-js key names are kept to match c++ style keys in prefs. - * @typedef {{vm_name: ?string, - * container_name: ?string}} + * @typedef {{vm_name: string, + * container_name: string}} */ export let GuestId; /** - * |ipv4| below is null if the container is not currently running. + * |ipv4| below is null if the guest is not currently running. * @typedef {{id: !GuestId, * ipv4: ?string}} */ @@ -53,10 +55,11 @@ /** * @param {string} vmName VM to share device with. + * @param {string} containerName container to share device with. * @param {string} guid Unique device identifier. * @param {boolean} shared Whether device is currently shared with Crostini. */ - setGuestOsUsbDeviceShared(vmName, guid, shared) {} + setGuestOsUsbDeviceShared(vmName, containerName, guid, shared) {} } /** @type {?GuestOsBrowserProxy} */ @@ -92,7 +95,8 @@ } /** @override */ - setGuestOsUsbDeviceShared(vmName, guid, shared) { - return chrome.send('setGuestOsUsbDeviceShared', [vmName, guid, shared]); + setGuestOsUsbDeviceShared(vmName, containerName, guid, shared) { + return chrome.send( + 'setGuestOsUsbDeviceShared', [vmName, containerName, guid, shared]); } }
diff --git a/chrome/browser/resources/settings/chromeos/guest_os/guest_os_shared_usb_devices.html b/chrome/browser/resources/settings/chromeos/guest_os/guest_os_shared_usb_devices.html index 8331c79f..37fc069 100644 --- a/chrome/browser/resources/settings/chromeos/guest_os/guest_os_shared_usb_devices.html +++ b/chrome/browser/resources/settings/chromeos/guest_os/guest_os_shared_usb_devices.html
@@ -1,10 +1,14 @@ -<style include="settings-shared"> +<style include="settings-shared md-select"> .toggle-container { display: flex; flex-direction: row; flex-wrap: nowrap; justify-content: space-between; } + + #selectDevice { + width: 100%; + } </style> <div class="settings-box first"> <div class="settings-box-text"> @@ -14,22 +18,83 @@ </div> </div> </div> -<div class="settings-box secondary continuation" - hidden="[[sharedUsbDevices_.length]]"> - $i18n{guestOsSharedUsbDevicesListEmptyMessage} -</div> -<template is="dom-if" if="[[sharedUsbDevices_.length]]" restamp> - <div class="list-frame vertical-list"> - <template is="dom-repeat" items="[[sharedUsbDevices_]]"> - <div class="list-item toggle-container"> - <div class="label">[[item.device.label]]</div> - <cr-toggle class="toggle" checked="[[item.shared]]" - on-change="onDeviceSharedChange_" - aria-label$="[[item.device.label]]"> - </cr-toggle> - </div> - </template> +<template is="dom-if" if="[[!hasContainers]]" restamp> + <div class="settings-box secondary continuation" + hidden="[[sharedUsbDevices_.length]]"> + $i18n{guestOsSharedUsbDevicesListEmptyMessage} </div> + <template is="dom-if" if="[[sharedUsbDevices_.length]]" restamp> + <div class="list-frame vertical-list"> + <template is="dom-repeat" items="[[sharedUsbDevices_]]"> + <div class="list-item toggle-container"> + <div class="label">[[item.device.label]]</div> + <cr-toggle class="toggle" checked="[[item.shared]]" + on-change="onDeviceSharedChange_" + aria-label$="[[item.device.label]]"> + </cr-toggle> + </div> + </template> + </div> + </template> +</template> + +<template is="dom-if" if="[[hasContainers]]" restamp> + <div id="addUsb" class="settings-box first"> + <div id="usbTableTitle" class="start" + aria-hidden="true"> + $i18n{guestOsSharedUsbDevicesTableTitle} + </div> + <cr-button id="addUsbBtn" on-click="onAddUsbClick_" + aria-label="$i18n{guestOsSharedUsbDevicesAddTitle}" + aria-describedby="addUsb"> + $i18n{add} + </cr-button> + </div> + <template is="dom-if" if="[[sharedUsbDevices_.length]]" restamp> + <template is="dom-repeat" items="[[allContainers_]]" + as="containerInfo" index-as="cidx" mutable-data> + <template is="dom-if" + if="[[showGuestId_(sharedUsbDevices_, containerInfo.id)]]" restamp> + <h2 id="usbListContainerId[[cidx]]" + hidden="[[!showGuestId_(sharedUsbDevices_, containerInfo.id)]]" + class="settings-box usb-list-guest-id"> + [[guestLabel_(containerInfo.id)]] + </h2> + <div class="list-frame vertical-list usb-list-card" + id="usbListCard[[cidx]]"> + <template is="dom-repeat" items="[[sharedUsbDevices_]]" + filter="[[byGuestId_(containerInfo.id)]]" mutable-data> + <div class="list-item"> + <div id="usbLabel[[cidx]]-[[index]]" + class="start usb-list-card-label" aria-hidden="true"> + [[item.device.label]] + </div> + <cr-icon-button id="removeUsb[[cidx]]-[[index]]" + class="icon-clear usb-list-card-remove" title="$i18n{remove}" + on-click="onRemoveUsbClick_" data-guid$="[[item.device.guid]]" + aria-label="$i18n{remove}" + aria-describedby$="usbLabel[[cidx]]-[[index]]"> + </cr-icon-button> + </div> + </template> + </div> + </template> + </template> + </template> + <template is="dom-if" + if="[[!hasSharedDevices_(sharedUsbDevices_, allContainers_)]]" restamp> + <div class="settings-box secondary"> + $i18n{guestOsSharedUsbDevicesNoneAttached} + </div> + </template> +</template> +<template is="dom-if" if="[[showAddUsbDialog_]]" restamp> + <settings-guest-os-shared-usb-devices-add-dialog + on-close="onAddUsbDialogClose_" + shared-usb-devices="[[sharedUsbDevices_]]" + all-containers="[[allContainers_]]" + default-guest-id="[[defaultGuestId]]"> + </settings-guest-os-shared-usb-devices-add-dialog> </template> <template is="dom-if" if="[[reassignDevice_]]" restamp> <cr-dialog id="reassignDialog" close-text="$i18n{close}"
diff --git a/chrome/browser/resources/settings/chromeos/guest_os/guest_os_shared_usb_devices.js b/chrome/browser/resources/settings/chromeos/guest_os/guest_os_shared_usb_devices.js index 374fce0..59b92745 100644 --- a/chrome/browser/resources/settings/chromeos/guest_os/guest_os_shared_usb_devices.js +++ b/chrome/browser/resources/settings/chromeos/guest_os/guest_os_shared_usb_devices.js
@@ -9,7 +9,7 @@ */ import 'chrome://resources/cr_elements/cr_toggle/cr_toggle.js'; -import '../../settings_shared.css.js'; +import './guest_os_shared_usb_devices_add_dialog.js'; import {I18nBehavior, I18nBehaviorInterface} from 'chrome://resources/js/i18n_behavior.m.js'; import {WebUIListenerBehavior, WebUIListenerBehaviorInterface} from 'chrome://resources/js/web_ui_listener_behavior.m.js'; @@ -17,7 +17,8 @@ import {recordSettingChange} from '../metrics_recorder.js'; -import {GuestOsBrowserProxy, GuestOsBrowserProxyImpl, GuestOsSharedUsbDevice} from './guest_os_browser_proxy.js'; +import {ContainerInfo, GuestId, GuestOsBrowserProxy, GuestOsBrowserProxyImpl, GuestOsSharedUsbDevice} from './guest_os_browser_proxy.js'; +import {containerLabel, equalContainerId} from './guest_os_container_select.js'; /** * @constructor @@ -29,7 +30,7 @@ mixinBehaviors([I18nBehavior, WebUIListenerBehavior], PolymerElement); /** @polymer */ -class SettingsGuestOsSharedUsbDevicesElement extends +export class SettingsGuestOsSharedUsbDevicesElement extends SettingsGuestOsSharedUsbDevicesElementBase { static get is() { return 'settings-guest-os-shared-usb-devices'; @@ -48,9 +49,27 @@ /** * The USB Devices available for connection to a VM. - * @private {Array<{shared: boolean, device: !GuestOsSharedUsbDevice}>} + * @private {!Array<{shared: boolean, device: !GuestOsSharedUsbDevice}>} */ - sharedUsbDevices_: Array, + sharedUsbDevices_: { + type: Array, + value() { + return []; + }, + }, + + /** + * @type {!GuestId} + */ + defaultGuestId: { + type: Object, + value() { + return { + 'vm_name': '', + 'container_name': '', + }; + }, + }, /** * The USB device which was toggled to be shared, but is already shared @@ -61,6 +80,32 @@ type: Object, value: null, }, + + /** + * Whether the guest OS hosts multiple containers. + */ + hasContainers: { + type: Boolean, + value: false, + }, + + /** @private */ + showAddUsbDialog_: { + type: Boolean, + value: false, + }, + + /** + * The known ContainerIds for display in the UI. + * @private {!Array<!ContainerInfo>} + */ + allContainers_: { + type: Array, + notify: true, + value() { + return []; + }, + }, }; } @@ -82,12 +127,48 @@ } /** + * @param {!Array<!ContainerInfo>} containerInfos + * @protected + */ + onContainerInfo_(containerInfos) { + this.set('allContainers_', containerInfos); + } + + /** + * @param {!Array<{shared: boolean, device: !GuestOsSharedUsbDevice}>} + * sharedUsbDevices + * @param {!GuestId} id + * @return boolean + * @private + */ + showGuestId_(sharedUsbDevices, id) { + return sharedUsbDevices.some(this.byGuestId_(id)); + } + + /** + * @param {!Array<{shared: boolean, device: !GuestOsSharedUsbDevice}>} + * sharedUsbDevices + * @param {!Array<!ContainerInfo>} containerInfos + * @return boolean + * @private + */ + hasSharedDevices_(sharedUsbDevices, containerInfos) { + return sharedUsbDevices.some( + dev => containerInfos.some( + info => dev.device.guestId && + equalContainerId(dev.device.guestId, info.id))); + } + + /** * @param {!Array<GuestOsSharedUsbDevice>} devices * @private */ onGuestOsSharedUsbDevicesChanged_(devices) { this.sharedUsbDevices_ = devices.map((device) => { - return {shared: device.sharedWith === this.vmName_(), device: device}; + return { + shared: device.guestId && device.guestId.vm_name === this.vmName_(), + device: device, + }; }); } @@ -104,7 +185,8 @@ return; } this.browserProxy_.setGuestOsUsbDeviceShared( - this.vmName_(), device.guid, event.target.checked); + this.vmName_(), this.defaultGuestId.container_name, device.guid, + event.target.checked); recordSettingChange(); } @@ -116,7 +198,8 @@ /** @private */ onReassignContinueClick_() { this.browserProxy_.setGuestOsUsbDeviceShared( - this.vmName_(), this.reassignDevice_.guid, true); + this.vmName_(), this.defaultGuestId.container_name, + this.reassignDevice_.guid, true); this.reassignDevice_ = null; recordSettingChange(); } @@ -150,6 +233,54 @@ getReassignDialogText_(device) { return this.i18n('guestOsSharedUsbDevicesReassign', device.label); } + + /** + * @param {!GuestId} id + * @return function({shared: boolean, device: !GuestOsSharedUsbDevice}): + * boolean + * @private + */ + byGuestId_(id) { + return dev => + dev.device.guestId && equalContainerId(dev.device.guestId, id); + } + + /** + * @param {!Event} event + * @private + */ + onAddUsbClick_(event) { + this.showAddUsbDialog_ = true; + } + + /** + * @param {!Event} event + * @private + */ + onAddUsbDialogClose_(event) { + this.showAddUsbDialog_ = false; + } + + /** + * @param {!GuestId} id + * @return string + * @private + */ + guestLabel_(id) { + return containerLabel(id, this.vmName_()); + } + + /** + * @param {!Event} event + * @private + */ + onRemoveUsbClick_(event) { + const device = event.model.item.device; + if (device.guestId != null) { + this.browserProxy_.setGuestOsUsbDeviceShared( + device.guestId.vm_name, '', device.guid, false); + } + } } customElements.define(
diff --git a/chrome/browser/resources/settings/chromeos/guest_os/guest_os_shared_usb_devices_add_dialog.html b/chrome/browser/resources/settings/chromeos/guest_os/guest_os_shared_usb_devices_add_dialog.html new file mode 100644 index 0000000..ba6869a --- /dev/null +++ b/chrome/browser/resources/settings/chromeos/guest_os/guest_os_shared_usb_devices_add_dialog.html
@@ -0,0 +1,75 @@ +<style include="settings-shared md-select"> + #selectDevice { + width: 100%; + } + + .custom-body { + padding-bottom: 20px; + } + + .custom-button-container { + float: right; + } + + .input-container { + padding-bottom: 10px; + } +</style> +<cr-dialog id="dialog" close-text="$i18n{close}"> + <div slot="title">$i18n{guestOsSharedUsbDevicesAddTitle}</div> + <div slot="body"> + <div class="input-container"> + <label class="cr-form-field-label">Device</label> + <select id="selectDevice" class="md-select" + disabled="[[!sharedUsbDevices.length]]"> + <template is="dom-if" if="[[!sharedUsbDevices.length]]" restamp> + <option>$i18n{guestOsSharedUsbDevicesListEmptyMessage}</option> + </template> + <template is="dom-repeat" items="[[sharedUsbDevices]]"> + <option value="[[item.device.guid]]"> + [[item.device.label]] + [[[item.device.vendorId]]:[[item.device.productId]]] + </option> + </template> + </select> + </div> + <template is="dom-if" if="[[showContainerSelect_(allContainers)]]" restamp> + <settings-guest-os-container-select + containers="[[allContainers]]" + selected-container-id="{{guestId_}}" + default-vm-name="[[defaultGuestId.vm_name]]"> + </settings-guest-os-container-select> + </template> + </div> + <div slot="body" class="custom-body"> + <div slot="button-container" class="custom-button-container"> + <cr-button id="cancel" class="cancel-button" on-click="onCancelTap_"> + $i18n{cancel} + </cr-button> + <cr-button id="continue" class="action-button" + disabled="[[!sharedUsbDevices.length]]" on-click="onAddTap_"> + $i18n{add} + </cr-button> + </div> + </div> +</cr-dialog> +<template is="dom-if" if="[[reassignDevice_]]" restamp> + <cr-dialog id="reassignDialog" close-text="$i18n{close}" + on-cancel="onReassignCancel_" show-on-attach> + <div slot="title"> + $i18n{guestOsSharedUsbDevicesInUse} + </div> + <div slot="body"> + [[getReassignDialogText_(reassignDevice_)]] + </div> + <div slot="button-container"> + <cr-button id="cancel" class="cancel-button" on-click="onReassignCancel_"> + $i18n{cancel} + </cr-button> + <cr-button id="continue" class="action-button" + on-click="onReassignContinueClick_"> + $i18n{continue} + </cr-button> + </div> + </cr-dialog> +</template>
diff --git a/chrome/browser/resources/settings/chromeos/guest_os/guest_os_shared_usb_devices_add_dialog.js b/chrome/browser/resources/settings/chromeos/guest_os/guest_os_shared_usb_devices_add_dialog.js new file mode 100644 index 0000000..e7b7f52 --- /dev/null +++ b/chrome/browser/resources/settings/chromeos/guest_os/guest_os_shared_usb_devices_add_dialog.js
@@ -0,0 +1,160 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/** + * @fileoverview 'settings-guest-os-shared-usb-devices-add-dialog' is a + * component enabling a user to add a USB device by filling in the appropriate + * fields and clicking add. + */ + +import 'chrome://resources/cr_elements/cr_button/cr_button.js'; +import 'chrome://resources/cr_elements/cr_dialog/cr_dialog.js'; +import 'chrome://resources/cr_elements/md_select_css.m.js'; +import './guest_os_container_select.js'; + +import {assert} from 'chrome://resources/js/assert_ts.js'; +import {I18nBehavior, I18nBehaviorInterface} from 'chrome://resources/js/i18n_behavior.m.js'; +import {html, microTask, mixinBehaviors, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + +import {recordSettingChange} from '../metrics_recorder.js'; + +import {ContainerInfo, GuestId, GuestOsBrowserProxy, GuestOsBrowserProxyImpl, GuestOsSharedUsbDevice} from './guest_os_browser_proxy.js'; +import {containerLabel} from './guest_os_container_select.js'; + +/** + * @constructor + * @extends {PolymerElement} + * @implements {I18nBehaviorInterface} + */ +const GuestOsSharedUsbDevicesAddDialogElementBase = + mixinBehaviors([I18nBehavior], PolymerElement); + +/** @polymer */ +class GuestOsSharedUsbDevicesAddDialog extends + GuestOsSharedUsbDevicesAddDialogElementBase { + static get is() { + return 'settings-guest-os-shared-usb-devices-add-dialog'; + } + + static get template() { + return html`{__html_template__}`; + } + + static get properties() { + return { + /** + * The USB Devices available for connection to a VM. + * @private {!Array<{shared: boolean, device: !GuestOsSharedUsbDevice}>} + */ + sharedUsbDevices: Array, + + /** + * @type {!GuestId} + */ + defaultGuestId: { + type: Object, + value() { + return { + 'vm_name': '', + 'container_name': '', + }; + }, + }, + + /** + * @type {GuestId} + */ + guestId_: Object, + + /** + * List of containers that are already stored in the settings. + * @type {!Array<!ContainerInfo>} + */ + allContainers: { + type: Array, + value: [], + }, + + /** + * The USB device which was toggled to be shared, but is already shared + * with another VM. When non-null the reassign dialog is shown. + * @private {?GuestOsSharedUsbDevice} + */ + reassignDevice_: { + type: Object, + value: null, + }, + }; + } + + /** @override */ + connectedCallback() { + super.connectedCallback(); + this.$.dialog.showModal(); + microTask.run(() => { + this.$.selectDevice.focus(); + }); + } + + /** @private */ + onCancelTap_() { + this.$.dialog.close(); + } + + /** @private */ + onAddTap_() { + const sharedUsbDevice = this.sharedUsbDevices.find( + ({device}) => device.guid === this.$.selectDevice.value); + assert(sharedUsbDevice); + + const {device} = sharedUsbDevice; + if (device.promptBeforeSharing) { + this.reassignDevice_ = device; + return; + } + + const guestId = this.guestId_ || this.defaultGuestId; + GuestOsBrowserProxyImpl.getInstance().setGuestOsUsbDeviceShared( + guestId.vm_name, guestId.container_name, device.guid, true); + this.$.dialog.close(); + recordSettingChange(); + } + + /** @private */ + onReassignCancel_() { + this.reassignDevice_ = null; + } + + /** @private */ + onReassignContinueClick_() { + const guestId = this.guestId_ || this.defaultGuestId; + GuestOsBrowserProxyImpl.getInstance().setGuestOsUsbDeviceShared( + guestId.vm_name, guestId.container_name, this.reassignDevice_.guid, + true); + this.reassignDevice_ = null; + this.$.dialog.close(); + recordSettingChange(); + } + + /** + * @param {!GuestOsSharedUsbDevice} device USB device. + * @private + * @return {string} Confirmation prompt text. + */ + getReassignDialogText_(device) { + return this.i18n('guestOsSharedUsbDevicesReassign', device.label); + } + + /** + * @param {!Array<!ContainerInfo>} allContainers + * @return boolean + * @private + */ + showContainerSelect_(allContainers) { + return allContainers.length > 1; + } +} + +customElements.define( + GuestOsSharedUsbDevicesAddDialog.is, GuestOsSharedUsbDevicesAddDialog);
diff --git a/chrome/browser/resources/settings/chromeos/lazy_load.js b/chrome/browser/resources/settings/chromeos/lazy_load.js index e1c4d8b..6cd742d 100644 --- a/chrome/browser/resources/settings/chromeos/lazy_load.js +++ b/chrome/browser/resources/settings/chromeos/lazy_load.js
@@ -16,11 +16,13 @@ import './crostini_page/crostini_page.js'; import './crostini_page/crostini_port_forwarding.js'; import './crostini_page/crostini_port_forwarding_add_port_dialog.js'; +import './crostini_page/crostini_shared_usb_devices.js'; import './crostini_page/crostini_subpage.js'; import './date_time_page/date_time_page.js'; import './date_time_page/timezone_selector.js'; import './guest_os/guest_os_container_select.js'; import './guest_os/guest_os_shared_usb_devices.js'; +import './guest_os/guest_os_shared_usb_devices_add_dialog.js'; import './guest_os/guest_os_shared_paths.js'; import './os_a11y_page/os_a11y_page.js'; import './os_a11y_page/manage_a11y_page.js';
diff --git a/chrome/browser/resources/settings/chromeos/os_languages_page/BUILD.gn b/chrome/browser/resources/settings/chromeos/os_languages_page/BUILD.gn index 41d05b4..a2c92d0 100644 --- a/chrome/browser/resources/settings/chromeos/os_languages_page/BUILD.gn +++ b/chrome/browser/resources/settings/chromeos/os_languages_page/BUILD.gn
@@ -6,7 +6,6 @@ # TODO(crbug.com/1226913): Add the missing deps. import("//third_party/closure_compiler/compile_js.gni") -import("//tools/polymer/html_to_js.gni") import("../os_settings.gni") js_type_check("closure_compile_module") { @@ -237,11 +236,3 @@ "//ui/webui/resources/js:load_time_data.m", ] } - -# TODO(crbug.com/1322682): Migrate this to css_to_wrapper(). -html_to_js("css_wrapper_files") { - js_files = [ - "shared_style.js", - "shared_vars.js", - ] -}
diff --git a/chrome/browser/resources/settings/chromeos/os_languages_page/add_items_dialog.js b/chrome/browser/resources/settings/chromeos/os_languages_page/add_items_dialog.js index e999e5b3..a9e0dd32 100644 --- a/chrome/browser/resources/settings/chromeos/os_languages_page/add_items_dialog.js +++ b/chrome/browser/resources/settings/chromeos/os_languages_page/add_items_dialog.js
@@ -13,7 +13,7 @@ import 'chrome://resources/polymer/v3_0/iron-flex-layout/iron-flex-layout-classes.js'; import 'chrome://resources/polymer/v3_0/iron-list/iron-list.js'; import './cr_checkbox_with_policy.js'; -import './shared_style.js'; +import './shared_style.css.js'; import '../../settings_shared.css.js'; import {CrScrollableBehavior, CrScrollableBehaviorInterface} from 'chrome://resources/cr_elements/cr_scrollable_behavior.m.js';
diff --git a/chrome/browser/resources/settings/chromeos/os_languages_page/change_device_language_dialog.js b/chrome/browser/resources/settings/chromeos/os_languages_page/change_device_language_dialog.js index a1825de..f1a9404 100644 --- a/chrome/browser/resources/settings/chromeos/os_languages_page/change_device_language_dialog.js +++ b/chrome/browser/resources/settings/chromeos/os_languages_page/change_device_language_dialog.js
@@ -12,7 +12,7 @@ import 'chrome://resources/polymer/v3_0/iron-flex-layout/iron-flex-layout-classes.js'; import 'chrome://resources/polymer/v3_0/iron-list/iron-list.js'; import 'chrome://resources/polymer/v3_0/paper-ripple/paper-ripple.js'; -import './shared_style.js'; +import './shared_style.css.js'; import 'chrome://resources/cr_components/localized_link/localized_link.js'; import './languages.js'; import '../../settings_shared.css.js';
diff --git a/chrome/browser/resources/settings/chromeos/os_languages_page/input_method_util.js b/chrome/browser/resources/settings/chromeos/os_languages_page/input_method_util.js index 42971f7..76654bae 100644 --- a/chrome/browser/resources/settings/chromeos/os_languages_page/input_method_util.js +++ b/chrome/browser/resources/settings/chromeos/os_languages_page/input_method_util.js
@@ -151,9 +151,9 @@ * @enum {string} */ export const UiType = { - TOGGLE_BUTTON: 'toggleButton', DROPDOWN: 'dropdown', LINK: 'link', + TOGGLE_BUTTON: 'toggleButton', }; /** @@ -162,11 +162,11 @@ * @enum {string} */ const SettingsHeaders = { - BASIC: 'basic', ADVANCED: 'advanced', + BASIC: 'basic', PHYSICAL_KEYBOARD: 'physicalKeyboard', - VIRTUAL_KEYBOARD: 'virtualKeyboard', SUGGESTIONS: 'suggestions', + VIRTUAL_KEYBOARD: 'virtualKeyboard', }; /**
diff --git a/chrome/browser/resources/settings/chromeos/os_languages_page/shared_style.css b/chrome/browser/resources/settings/chromeos/os_languages_page/shared_style.css new file mode 100644 index 0000000..d1f633d --- /dev/null +++ b/chrome/browser/resources/settings/chromeos/os_languages_page/shared_style.css
@@ -0,0 +1,57 @@ +/* Copyright 2022 The Chromium Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. */ + +/* #css_wrapper_metadata_start + * #type=style + * #import=./shared_vars.css.js + * #css_wrapper_metadata_end */ + +cr-search-field { + --cr-search-field-clear-icon-fill: var(--cros-icon-color-primary); + --cr-search-field-clear-icon-margin-end: 8px; + --cr-search-field-clear-icon-size: 18px; + --cr-search-field-input-border-bottom: none; + --cr-search-field-input-min-height: 32px; + --cr-search-field-input-padding-bottom: 0; + --cr-search-field-input-padding-start: 8px; + --cr-search-field-input-padding-top: 0; + --cr-search-field-input-underline-border-radius: 4px; + --cr-search-field-input-underline-height: 4px; + --cr-search-field-input-width: 100%; + --cr-search-field-search-icon-display: none; + --cr-search-field-search-icon-fill: var(--cros-icon-color-primary); + --cr-search-field-search-icon-inline-display: block; + --cr-search-field-search-icon-inline-margin-start: 6px; + background-color: var(--cros-textfield-background-color); + border-radius: 4px; +} + +cr-dialog [slot=title] { + padding-inline-end: var(--dialog-horizontal-padding); + padding-inline-start: var(--dialog-horizontal-padding); + padding-top: var(--dialog-horizontal-padding); +} + +cr-dialog [slot=body] { + padding-inline-end: var(--dialog-horizontal-padding); + padding-inline-start: var(--dialog-horizontal-padding); +} + +cr-dialog [slot=button-container] { + padding-bottom: 20px; + padding-inline-end: var(--dialog-horizontal-padding); + padding-inline-start: var(--dialog-horizontal-padding); + padding-top: 20px; +} + +.centered-message { + align-items: center; + color: var(--md-loading-message-color); + display: flex; + flex: 1; + font-size: 108%; + font-weight: 500; + height: 100%; + justify-content: center; +}
diff --git a/chrome/browser/resources/settings/chromeos/os_languages_page/shared_style.html b/chrome/browser/resources/settings/chromeos/os_languages_page/shared_style.html deleted file mode 100644 index 40a677f..0000000 --- a/chrome/browser/resources/settings/chromeos/os_languages_page/shared_style.html +++ /dev/null
@@ -1,52 +0,0 @@ -<template> - <style> - cr-search-field { - --cr-search-field-clear-icon-fill: var(--cros-icon-color-primary); - --cr-search-field-clear-icon-margin-end: 8px; - --cr-search-field-clear-icon-size: 18px; - --cr-search-field-input-border-bottom: none; - --cr-search-field-input-min-height: 32px; - --cr-search-field-input-padding-bottom: 0; - --cr-search-field-input-padding-start: 8px; - --cr-search-field-input-padding-top: 0; - --cr-search-field-input-underline-border-radius: 4px; - --cr-search-field-input-underline-height: 4px; - --cr-search-field-input-width: 100%; - --cr-search-field-search-icon-display: none; - --cr-search-field-search-icon-fill: var(--cros-icon-color-primary); - --cr-search-field-search-icon-inline-display: block; - --cr-search-field-search-icon-inline-margin-start: 6px; - background-color: var(--cros-textfield-background-color); - border-radius: 4px; - } - - cr-dialog [slot=title] { - padding-inline-end: var(--dialog-horizontal-padding); - padding-inline-start: var(--dialog-horizontal-padding); - padding-top: var(--dialog-horizontal-padding); - } - - cr-dialog [slot=body] { - padding-inline-end: var(--dialog-horizontal-padding); - padding-inline-start: var(--dialog-horizontal-padding); - } - - cr-dialog [slot=button-container] { - padding-bottom: 20px; - padding-inline-end: var(--dialog-horizontal-padding); - padding-inline-start: var(--dialog-horizontal-padding); - padding-top: 20px; - } - - .centered-message { - align-items: center; - color: var(--md-loading-message-color); - display: flex; - flex: 1; - font-size: 108%; - font-weight: 500; - height: 100%; - justify-content: center; - } - </style> -</template>
diff --git a/chrome/browser/resources/settings/chromeos/os_languages_page/shared_style.js b/chrome/browser/resources/settings/chromeos/os_languages_page/shared_style.js deleted file mode 100644 index 7b7e1a4..0000000 --- a/chrome/browser/resources/settings/chromeos/os_languages_page/shared_style.js +++ /dev/null
@@ -1,10 +0,0 @@ -// Copyright 2021 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import './shared_vars.js'; -const template = document.createElement('template'); -template.innerHTML = ` -<dom-module id="shared-style" assetpath="chrome://resources/">{__html_template__}</dom-module> -`; -document.body.appendChild(template.content.cloneNode(true));
diff --git a/chrome/browser/resources/settings/chromeos/os_languages_page/shared_vars.css b/chrome/browser/resources/settings/chromeos/os_languages_page/shared_vars.css new file mode 100644 index 0000000..b29710d2 --- /dev/null +++ b/chrome/browser/resources/settings/chromeos/os_languages_page/shared_vars.css
@@ -0,0 +1,12 @@ +/* Copyright 2022 The Chromium Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. */ + +/* #css_wrapper_metadata_start + * #type=vars + * #import=chrome://resources/cr_elements/shared_vars_css.m.js + * #css_wrapper_metadata_end */ + +html { + --dialog-horizontal-padding: 24px; +}
diff --git a/chrome/browser/resources/settings/chromeos/os_languages_page/shared_vars.html b/chrome/browser/resources/settings/chromeos/os_languages_page/shared_vars.html deleted file mode 100644 index 9a75264..0000000 --- a/chrome/browser/resources/settings/chromeos/os_languages_page/shared_vars.html +++ /dev/null
@@ -1,7 +0,0 @@ -<custom-style> -<style> - html { - --dialog-horizontal-padding: 24px; - } -</style> -</custom-style>
diff --git a/chrome/browser/resources/settings/chromeos/os_languages_page/shared_vars.js b/chrome/browser/resources/settings/chromeos/os_languages_page/shared_vars.js deleted file mode 100644 index 870e4b4..0000000 --- a/chrome/browser/resources/settings/chromeos/os_languages_page/shared_vars.js +++ /dev/null
@@ -1,10 +0,0 @@ -// Copyright 2021 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; -import 'chrome://resources/cr_elements/shared_vars_css.m.js'; - -const template = document.createElement('template'); -template.innerHTML = `{__html_template__}`; -document.head.appendChild(template.content);
diff --git a/chrome/browser/resources/settings/chromeos/os_settings.gni b/chrome/browser/resources/settings/chromeos/os_settings.gni index 1018a53e..3d88353 100644 --- a/chrome/browser/resources/settings/chromeos/os_settings.gni +++ b/chrome/browser/resources/settings/chromeos/os_settings.gni
@@ -54,10 +54,23 @@ web_component_html_wrapper_files += [ filename + ".ts" ] } +# Files that are passed as input to css_to_wrapper(). +css_files = [ + "chromeos/os_languages_page/shared_style.css", + "chromeos/os_languages_page/shared_vars.css", +] + +# Files that are generated by css_to_wrapper(). +css_wrapper_files = [] +foreach(f, css_files) { + css_wrapper_files += [ f + ".ts" ] +} + non_web_component_files = [ "chromeos/bluetooth_page/bluetooth_page_browser_proxy.js", "chromeos/combined_search_handler.js", "chromeos/crostini_page/crostini_browser_proxy.js", + "chromeos/crostini_page/crostini_shared_usb_devices.js", "chromeos/date_time_page/date_time_types.js", "chromeos/date_time_page/timezone_browser_proxy.js", "chromeos/deep_linking_behavior.js", @@ -188,6 +201,7 @@ "chromeos/guest_os/guest_os_container_select.js", "chromeos/guest_os/guest_os_shared_paths.js", "chromeos/guest_os/guest_os_shared_usb_devices.js", + "chromeos/guest_os/guest_os_shared_usb_devices_add_dialog.js", "chromeos/internet_page/cellular_networks_list.js", "chromeos/internet_page/cellular_roaming_toggle_button.js", "chromeos/internet_page/cellular_setup_dialog.js", @@ -287,8 +301,6 @@ "chromeos/os_files_page/os_files_page.js", "chromeos/os_files_page/smb_shares_page.js", "chromeos/os_icons.js", - "chromeos/os_languages_page/shared_style.js", - "chromeos/os_languages_page/shared_vars.js", "chromeos/os_people_page/account_manager.js", "chromeos/os_people_page/fingerprint_list.js", "chromeos/os_people_page/lock_screen.js", @@ -345,9 +357,11 @@ # TODO(crbug/1315757) JS files here are available for TS conversion src_ts_files = non_web_component_files + web_component_files -# Files sourced from gen_dir and generated by html_to_js() or html_to_wrapper() +# Files sourced from gen_dir and generated by html_to_js(), html_to_wrapper() or +# css_to_wrapper() # TODO(crbug/1315757) JS files here are available for TS conversion -gen_ts_files = gen_web_component_files + web_component_html_wrapper_files +gen_ts_files = gen_web_component_files + web_component_html_wrapper_files + + css_wrapper_files # TODO(crbug.com/1121865): browser_resolver_prefix_replacements allows path # from ../../shared/* to resolve to ../../../nearby_share/shared/* for closure
diff --git a/chrome/browser/touch_to_fill/payments/DIR_METADATA b/chrome/browser/touch_to_fill/payments/DIR_METADATA new file mode 100644 index 0000000..110957a --- /dev/null +++ b/chrome/browser/touch_to_fill/payments/DIR_METADATA
@@ -0,0 +1,3 @@ +monorail: { + component: "UI>Browser>Autofill>UI" +}
diff --git a/chrome/browser/touch_to_fill/payments/android/BUILD.gn b/chrome/browser/touch_to_fill/payments/android/BUILD.gn new file mode 100644 index 0000000..e99528f --- /dev/null +++ b/chrome/browser/touch_to_fill/payments/android/BUILD.gn
@@ -0,0 +1,50 @@ +# Copyright 2022 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import("//build/config/android/rules.gni") + +source_set("public") { + deps = [ "//base" ] + + sources = [ + "touch_to_fill_credit_card_view.h", + "touch_to_fill_credit_card_view_controller.h", + ] +} + +source_set("android") { + sources = [ + "touch_to_fill_credit_card_view_impl.cc", + "touch_to_fill_credit_card_view_impl.h", + ] + + public_deps = [ "//base" ] + + deps = [ + ":jni_headers", + ":public", + "//components/autofill/core/common:features", + "//content/public/browser:browser", + "//ui/android", + ] +} + +generate_jni("jni_headers") { + sources = [ + "internal/java/src/org/chromium/chrome/browser/touch_to_fill/payments/TouchToFillCreditCardControllerBridge.java", + "internal/java/src/org/chromium/chrome/browser/touch_to_fill/payments/TouchToFillCreditCardViewBridge.java", + ] +} + +android_library("public_java") { + deps = [ + "//base:jni_java", + "//chrome/android:chrome_java", + "//components/browser_ui/bottomsheet/android:java", + "//third_party/androidx:androidx_annotation_annotation_java", + "//ui/android:ui_java", + ] + + sources = [ "java/src/org/chromium/chrome/browser/touch_to_fill/payments/TouchToFillCreditCardComponent.java" ] +}
diff --git a/chrome/browser/touch_to_fill/payments/android/internal/BUILD.gn b/chrome/browser/touch_to_fill/payments/android/internal/BUILD.gn new file mode 100644 index 0000000..8aa78471 --- /dev/null +++ b/chrome/browser/touch_to_fill/payments/android/internal/BUILD.gn
@@ -0,0 +1,30 @@ +# Copyright 2022 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import("//build/config/android/rules.gni") + +android_library("java") { + deps = [ + "//base:base_java", + "//base:jni_java", + "//build/android:build_java", + "//chrome/android:chrome_java", + "//chrome/browser/touch_to_fill/payments/android:public_java", + "//components/browser_ui/bottomsheet/android:java", + "//third_party/androidx:androidx_annotation_annotation_java", + "//ui/android:ui_java", + ] + + sources = [ + "java/src/org/chromium/chrome/browser/touch_to_fill/payments/TouchToFillCreditCardControllerBridge.java", + "java/src/org/chromium/chrome/browser/touch_to_fill/payments/TouchToFillCreditCardCoordinator.java", + "java/src/org/chromium/chrome/browser/touch_to_fill/payments/TouchToFillCreditCardMediator.java", + "java/src/org/chromium/chrome/browser/touch_to_fill/payments/TouchToFillCreditCardProperties.java", + "java/src/org/chromium/chrome/browser/touch_to_fill/payments/TouchToFillCreditCardView.java", + "java/src/org/chromium/chrome/browser/touch_to_fill/payments/TouchToFillCreditCardViewBinder.java", + "java/src/org/chromium/chrome/browser/touch_to_fill/payments/TouchToFillCreditCardViewBridge.java", + ] + + annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ] +}
diff --git a/chrome/browser/touch_to_fill/payments/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/payments/TouchToFillCreditCardControllerBridge.java b/chrome/browser/touch_to_fill/payments/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/payments/TouchToFillCreditCardControllerBridge.java new file mode 100644 index 0000000..de90190 --- /dev/null +++ b/chrome/browser/touch_to_fill/payments/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/payments/TouchToFillCreditCardControllerBridge.java
@@ -0,0 +1,45 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.touch_to_fill.payments; + +import org.chromium.base.annotations.CalledByNative; +import org.chromium.base.annotations.JNINamespace; +import org.chromium.base.annotations.NativeMethods; + +/** + * JNI wrapper for C++ TouchToFillCreditCardViewController. Delegates calls from Java to native. + */ +@JNINamespace("autofill") +class TouchToFillCreditCardControllerBridge implements TouchToFillCreditCardComponent.Delegate { + private long mNativeTouchToFillCreditCardViewController; + + private TouchToFillCreditCardControllerBridge(long nativeTouchToFillCreditCardViewController) { + mNativeTouchToFillCreditCardViewController = nativeTouchToFillCreditCardViewController; + } + + @CalledByNative + private static TouchToFillCreditCardControllerBridge create( + long nativeTouchToFillCreditCardViewController) { + return new TouchToFillCreditCardControllerBridge(nativeTouchToFillCreditCardViewController); + } + + @CalledByNative + private void onNativeDestroyed() { + mNativeTouchToFillCreditCardViewController = 0; + } + + @Override + public void onDismissed() { + if (mNativeTouchToFillCreditCardViewController != 0) { + TouchToFillCreditCardControllerBridgeJni.get().onDismissed( + mNativeTouchToFillCreditCardViewController); + } + } + + @NativeMethods + interface Natives { + void onDismissed(long nativeTouchToFillCreditCardViewController); + } +}
diff --git a/chrome/browser/touch_to_fill/payments/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/payments/TouchToFillCreditCardCoordinator.java b/chrome/browser/touch_to_fill/payments/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/payments/TouchToFillCreditCardCoordinator.java new file mode 100644 index 0000000..fbc8f4d58 --- /dev/null +++ b/chrome/browser/touch_to_fill/payments/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/payments/TouchToFillCreditCardCoordinator.java
@@ -0,0 +1,55 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.touch_to_fill.payments; + +import android.content.Context; + +import androidx.annotation.VisibleForTesting; + +import org.chromium.components.browser_ui.bottomsheet.BottomSheetController; +import org.chromium.ui.modelutil.PropertyModel; +import org.chromium.ui.modelutil.PropertyModelChangeProcessor; + +/** + * Implements the TouchToFillCreditCardComponent. It uses a bottom sheet to let the user select a + * credit card to be filled into the focused form. + */ +public class TouchToFillCreditCardCoordinator implements TouchToFillCreditCardComponent { + private final TouchToFillCreditCardMediator mMediator = new TouchToFillCreditCardMediator(); + + @Override + public void initialize(Context context, BottomSheetController sheetController, + TouchToFillCreditCardComponent.Delegate delegate) { + PropertyModel model = new PropertyModel.Builder(TouchToFillCreditCardProperties.ALL_KEYS) + .with(TouchToFillCreditCardProperties.VISIBLE, false) + .with(TouchToFillCreditCardProperties.DISMISS_HANDLER, + mMediator::onDismissed) + .build(); + + mMediator.initialize(delegate, model); + setUpModelChangeProcessors(model, new TouchToFillCreditCardView(context, sheetController)); + } + + @Override + public void showSheet() { + mMediator.showSheet(); + } + + @Override + public void hideSheet() { + mMediator.hideSheet(); + } + + /** + * Connects the given model with the given view using Model Change Processors. + * @param model A {@link PropertyModel} built with {@link TouchToFillCreditCardProperties}. + * @param view A {@link TouchToFillCreditCardView}. + */ + @VisibleForTesting + static void setUpModelChangeProcessors(PropertyModel model, TouchToFillCreditCardView view) { + PropertyModelChangeProcessor.create( + model, view, TouchToFillCreditCardViewBinder::bindTouchToFillCreditCardView); + } +}
diff --git a/chrome/browser/touch_to_fill/payments/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/payments/TouchToFillCreditCardMediator.java b/chrome/browser/touch_to_fill/payments/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/payments/TouchToFillCreditCardMediator.java new file mode 100644 index 0000000..77b1288 --- /dev/null +++ b/chrome/browser/touch_to_fill/payments/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/payments/TouchToFillCreditCardMediator.java
@@ -0,0 +1,40 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.touch_to_fill.payments; + +import static org.chromium.chrome.browser.touch_to_fill.payments.TouchToFillCreditCardProperties.VISIBLE; + +import org.chromium.components.browser_ui.bottomsheet.BottomSheetController; +import org.chromium.components.browser_ui.bottomsheet.BottomSheetController.StateChangeReason; +import org.chromium.ui.modelutil.PropertyModel; + +/** + * Contains the logic for the TouchToFillCreditCard component. It sets the state of the model + * and reacts to events like clicks. + */ +class TouchToFillCreditCardMediator { + private TouchToFillCreditCardComponent.Delegate mDelegate; + private PropertyModel mModel; + + void initialize(TouchToFillCreditCardComponent.Delegate delegate, PropertyModel model) { + assert delegate != null; + mDelegate = delegate; + mModel = model; + } + + void showSheet() { + mModel.set(VISIBLE, true); + } + + void hideSheet() { + onDismissed(BottomSheetController.StateChangeReason.NONE); + } + + public void onDismissed(@StateChangeReason int reason) { + if (!mModel.get(VISIBLE)) return; // Dismiss only if not dismissed yet. + mModel.set(VISIBLE, false); + mDelegate.onDismissed(); + } +}
diff --git a/chrome/browser/touch_to_fill/payments/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/payments/TouchToFillCreditCardProperties.java b/chrome/browser/touch_to_fill/payments/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/payments/TouchToFillCreditCardProperties.java new file mode 100644 index 0000000..8b32eda --- /dev/null +++ b/chrome/browser/touch_to_fill/payments/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/payments/TouchToFillCreditCardProperties.java
@@ -0,0 +1,21 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.touch_to_fill.payments; + +import org.chromium.base.Callback; +import org.chromium.ui.modelutil.PropertyKey; +import org.chromium.ui.modelutil.PropertyModel; + +/** + * Properties defined here reflect the visible state of the TouchToFillCreditCard component. + */ +class TouchToFillCreditCardProperties { + static final PropertyModel.WritableBooleanPropertyKey VISIBLE = + new PropertyModel.WritableBooleanPropertyKey("visible"); + static final PropertyModel.ReadableObjectPropertyKey<Callback<Integer>> DISMISS_HANDLER = + new PropertyModel.ReadableObjectPropertyKey<>("dismiss_handler"); + + static final PropertyKey[] ALL_KEYS = {VISIBLE, DISMISS_HANDLER}; +}
diff --git a/chrome/browser/touch_to_fill/payments/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/payments/TouchToFillCreditCardView.java b/chrome/browser/touch_to_fill/payments/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/payments/TouchToFillCreditCardView.java new file mode 100644 index 0000000..9b5478c --- /dev/null +++ b/chrome/browser/touch_to_fill/payments/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/payments/TouchToFillCreditCardView.java
@@ -0,0 +1,175 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.touch_to_fill.payments; + +import android.content.Context; +import android.view.View; +import android.widget.RelativeLayout; + +import androidx.annotation.Nullable; + +import org.chromium.base.Callback; +import org.chromium.components.browser_ui.bottomsheet.BottomSheetContent; +import org.chromium.components.browser_ui.bottomsheet.BottomSheetController; +import org.chromium.components.browser_ui.bottomsheet.BottomSheetObserver; +import org.chromium.components.browser_ui.bottomsheet.EmptyBottomSheetObserver; + +/** + * This class is responsible for rendering the bottom sheet which displays the + * TouchToFillCreditCard. It is a View in this Model-View-Controller component and doesn't inherit + * but holds Android Views. + */ +class TouchToFillCreditCardView implements BottomSheetContent { + private final BottomSheetController mBottomSheetController; + private final RelativeLayout mContentView; + private Callback<Integer> mDismissHandler; + + // TODO(crbug.com/1247698): Reuse this logic between different sheets. + private final BottomSheetObserver mBottomSheetObserver = new EmptyBottomSheetObserver() { + @Override + public void onSheetClosed(@BottomSheetController.StateChangeReason int reason) { + super.onSheetClosed(reason); + assert mDismissHandler != null; + mDismissHandler.onResult(reason); + mBottomSheetController.removeObserver(mBottomSheetObserver); + } + + @Override + public void onSheetStateChanged(int newState, int reason) { + super.onSheetStateChanged(newState, reason); + if (newState != BottomSheetController.SheetState.HIDDEN) return; + // This is a fail-safe for cases where onSheetClosed isn't triggered. + mDismissHandler.onResult(BottomSheetController.StateChangeReason.NONE); + mBottomSheetController.removeObserver(mBottomSheetObserver); + } + }; + + /** + * Constructs a TouchToFillCreditCardView which creates, modifies, and shows the bottom sheet. + * + * @param context A {@link Context} used to load resources and inflate the sheet. + * @param bottomSheetController The {@link BottomSheetController} used to show/hide the sheet. + */ + TouchToFillCreditCardView(Context context, BottomSheetController bottomSheetController) { + mBottomSheetController = bottomSheetController; + mContentView = new RelativeLayout(context); + } + + /** + * Sets a new listener that reacts to a dismisal event. + * + * @param dismissHandler A {@link Callback<Integer>}. + */ + void setDismissHandler(Callback<Integer> dismissHandler) { + mDismissHandler = dismissHandler; + } + + /** + * If set to true, requests to show the bottom sheet. Otherwise, requests to hide the sheet. + * + * @param isVisible A boolean describing whether to show or hide the sheet. + * @return True if the request was successful, false otherwise. + */ + boolean setVisible(boolean isVisible) { + if (!isVisible) { + mBottomSheetController.hideContent(this, true); + return true; + } + + mBottomSheetController.addObserver(mBottomSheetObserver); + if (!mBottomSheetController.requestShowContent(this, true)) { + mBottomSheetController.removeObserver(mBottomSheetObserver); + return false; + } + return true; + } + + @Override + public void destroy() { + mBottomSheetController.removeObserver(mBottomSheetObserver); + } + + @Override + public View getContentView() { + return mContentView; + } + + @Nullable + @Override + public View getToolbarView() { + return null; + } + + @Override + public int getVerticalScrollOffset() { + return 0; + } + + @Override + public int getPriority() { + return BottomSheetContent.ContentPriority.HIGH; + } + + @Override + public boolean hasCustomScrimLifecycle() { + return false; + } + + @Override + public boolean swipeToDismissEnabled() { + return false; + } + + @Override + public boolean skipHalfStateOnScrollingDown() { + return false; + } + + @Override + public int getPeekHeight() { + return BottomSheetContent.HeightMode.DISABLED; + } + + @Override + public float getFullHeightRatio() { + // TODO(crbug.com/1247698): Calculate proper ratio. + return 1.0f; + } + + @Override + public float getHalfHeightRatio() { + // TODO(crbug.com/1247698): Calculate proper ratio. + return 0.5f; + } + + @Override + public boolean hideOnScroll() { + return false; + } + + @Override + public int getSheetContentDescriptionStringId() { + // TODO(crbug.com/1247698): Introduce and use proper payments string. + return android.R.string.ok; + } + + @Override + public int getSheetHalfHeightAccessibilityStringId() { + // TODO(crbug.com/1247698): Introduce and use proper payments string. + return android.R.string.ok; + } + + @Override + public int getSheetFullHeightAccessibilityStringId() { + // TODO(crbug.com/1247698): Introduce and use proper payments string. + return android.R.string.ok; + } + + @Override + public int getSheetClosedAccessibilityStringId() { + // TODO(crbug.com/1247698): Introduce and use proper payments string. + return android.R.string.ok; + } +}
diff --git a/chrome/browser/touch_to_fill/payments/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/payments/TouchToFillCreditCardViewBinder.java b/chrome/browser/touch_to_fill/payments/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/payments/TouchToFillCreditCardViewBinder.java new file mode 100644 index 0000000..a5100db --- /dev/null +++ b/chrome/browser/touch_to_fill/payments/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/payments/TouchToFillCreditCardViewBinder.java
@@ -0,0 +1,41 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.touch_to_fill.payments; + +import static org.chromium.chrome.browser.touch_to_fill.payments.TouchToFillCreditCardProperties.DISMISS_HANDLER; +import static org.chromium.chrome.browser.touch_to_fill.payments.TouchToFillCreditCardProperties.VISIBLE; + +import org.chromium.components.browser_ui.bottomsheet.BottomSheetController; +import org.chromium.ui.modelutil.PropertyKey; +import org.chromium.ui.modelutil.PropertyModel; + +/** + * Provides functions that map {@link TouchToFillCreditCardProperties} changes in a {@link + * PropertyModel} to the suitable method in {@link TouchToFillCreditCardView}. + */ +class TouchToFillCreditCardViewBinder { + /** + * Called whenever a property in the given model changes. It updates the given view accordingly. + * @param model The observed {@link PropertyModel}. Its data need to be reflected in the view. + * @param view The {@link TouchToFillCreditCardView} to update. + * @param propertyKey The {@link PropertyKey} which changed. + */ + static void bindTouchToFillCreditCardView( + PropertyModel model, TouchToFillCreditCardView view, PropertyKey propertyKey) { + if (propertyKey == DISMISS_HANDLER) { + view.setDismissHandler(model.get(DISMISS_HANDLER)); + } else if (propertyKey == VISIBLE) { + boolean visibilityChangeSuccessful = view.setVisible(model.get(VISIBLE)); + if (!visibilityChangeSuccessful && model.get(VISIBLE)) { + assert (model.get(DISMISS_HANDLER) != null); + model.get(DISMISS_HANDLER).onResult(BottomSheetController.StateChangeReason.NONE); + } + } else { + assert false : "Unhandled update to property:" + propertyKey; + } + } + + private TouchToFillCreditCardViewBinder() {} +}
diff --git a/chrome/browser/touch_to_fill/payments/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/payments/TouchToFillCreditCardViewBridge.java b/chrome/browser/touch_to_fill/payments/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/payments/TouchToFillCreditCardViewBridge.java new file mode 100644 index 0000000..59987c3 --- /dev/null +++ b/chrome/browser/touch_to_fill/payments/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/payments/TouchToFillCreditCardViewBridge.java
@@ -0,0 +1,53 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.touch_to_fill.payments; + +import android.content.Context; + +import androidx.annotation.Nullable; + +import org.chromium.base.annotations.CalledByNative; +import org.chromium.base.annotations.JNIAdditionalImport; +import org.chromium.base.annotations.JNINamespace; +import org.chromium.components.browser_ui.bottomsheet.BottomSheetController; +import org.chromium.components.browser_ui.bottomsheet.BottomSheetControllerProvider; +import org.chromium.ui.base.WindowAndroid; + +/** + * JNI wrapper for C++ TouchToFillCreditCardViewImpl. Delegates calls from native to Java. + */ +@JNINamespace("autofill") +@JNIAdditionalImport(TouchToFillCreditCardComponent.class) +class TouchToFillCreditCardViewBridge { + private final TouchToFillCreditCardComponent mComponent; + + private TouchToFillCreditCardViewBridge(TouchToFillCreditCardComponent.Delegate delegate, + Context context, BottomSheetController bottomSheetController) { + mComponent = new TouchToFillCreditCardCoordinator(); + mComponent.initialize(context, bottomSheetController, delegate); + } + + @CalledByNative + private static @Nullable TouchToFillCreditCardViewBridge create( + TouchToFillCreditCardComponent.Delegate delegate, WindowAndroid windowAndroid) { + if (windowAndroid == null) return null; + Context context = windowAndroid.getContext().get(); + if (context == null) return null; + BottomSheetController bottomSheetController = + BottomSheetControllerProvider.from(windowAndroid); + if (bottomSheetController == null) return null; + return new TouchToFillCreditCardViewBridge(delegate, context, bottomSheetController); + } + + @CalledByNative + private void showSheet() { + mComponent.showSheet(); + } + + @CalledByNative + private void hideSheet() { + mComponent.hideSheet(); + } +}
diff --git a/chrome/browser/touch_to_fill/payments/android/java/src/org/chromium/chrome/browser/touch_to_fill/payments/TouchToFillCreditCardComponent.java b/chrome/browser/touch_to_fill/payments/android/java/src/org/chromium/chrome/browser/touch_to_fill/payments/TouchToFillCreditCardComponent.java new file mode 100644 index 0000000..d7b5d75 --- /dev/null +++ b/chrome/browser/touch_to_fill/payments/android/java/src/org/chromium/chrome/browser/touch_to_fill/payments/TouchToFillCreditCardComponent.java
@@ -0,0 +1,43 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.touch_to_fill.payments; + +import android.content.Context; + +import org.chromium.components.browser_ui.bottomsheet.BottomSheetController; + +/** + * This component allows to select a credit card to be filled into a form. It acts as a 1-tap + * surface (bottom sheet) and is meant to be shown while the keyboard is suppressed. + */ +public interface TouchToFillCreditCardComponent { + /** + * This delegate is called when the TouchToFillCreditCard component is interacted with. + */ + interface Delegate { + /** + * Called whenever the sheet is dismissed (by user or native). + */ + void onDismissed(); + } + + /** + * Initializes the component. + * @param context A {@link Context} to create views and retrieve resources. + * @param sheetController A {@link BottomSheetController} used to show/hide the sheet. + * @param delegate A {@link Delegate} that handles interaction events. + */ + void initialize(Context context, BottomSheetController sheetController, Delegate delegate); + + /** + * Displays a new bottom sheet. + */ + void showSheet(); + + /** + * Hides the bottom sheet if shown. + */ + void hideSheet(); +}
diff --git a/chrome/browser/touch_to_fill/payments/android/touch_to_fill_credit_card_controller.cc b/chrome/browser/touch_to_fill/payments/android/touch_to_fill_credit_card_controller.cc new file mode 100644 index 0000000..5d9fc6b9 --- /dev/null +++ b/chrome/browser/touch_to_fill/payments/android/touch_to_fill_credit_card_controller.cc
@@ -0,0 +1,58 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/touch_to_fill/payments/android/touch_to_fill_credit_card_controller.h" + +#include "chrome/browser/touch_to_fill/payments/android/jni_headers/TouchToFillCreditCardControllerBridge_jni.h" +#include "chrome/browser/touch_to_fill/payments/android/touch_to_fill_credit_card_view.h" +#include "components/autofill/core/browser/ui/touch_to_fill_delegate.h" + +namespace autofill { + +TouchToFillCreditCardController::TouchToFillCreditCardController() = default; +TouchToFillCreditCardController::~TouchToFillCreditCardController() { + if (java_object_) { + Java_TouchToFillCreditCardControllerBridge_onNativeDestroyed( + base::android::AttachCurrentThread(), java_object_); + } +} + +bool TouchToFillCreditCardController::Show( + std::unique_ptr<TouchToFillCreditCardView> view, + base::WeakPtr<TouchToFillDelegate> delegate) { + // Abort if TTF surface is already shown. + if (view_) + return false; + + if (!view->Show(this)) { + java_object_.Reset(); + return false; + } + + view_ = std::move(view); + delegate_ = std::move(delegate); + return true; +} + +void TouchToFillCreditCardController::Hide() { + if (view_) + view_->Hide(); +} + +void TouchToFillCreditCardController::OnDismissed(JNIEnv* env) { + view_.reset(); + delegate_.reset(); + java_object_.Reset(); +} + +base::android::ScopedJavaLocalRef<jobject> +TouchToFillCreditCardController::GetJavaObject() { + if (!java_object_) { + java_object_ = Java_TouchToFillCreditCardControllerBridge_create( + base::android::AttachCurrentThread(), reinterpret_cast<intptr_t>(this)); + } + return base::android::ScopedJavaLocalRef<jobject>(java_object_); +} + +} // namespace autofill
diff --git a/chrome/browser/touch_to_fill/payments/android/touch_to_fill_credit_card_controller.h b/chrome/browser/touch_to_fill/payments/android/touch_to_fill_credit_card_controller.h new file mode 100644 index 0000000..fcf884e2 --- /dev/null +++ b/chrome/browser/touch_to_fill/payments/android/touch_to_fill_credit_card_controller.h
@@ -0,0 +1,60 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_TOUCH_TO_FILL_PAYMENTS_ANDROID_TOUCH_TO_FILL_CREDIT_CARD_CONTROLLER_H_ +#define CHROME_BROWSER_TOUCH_TO_FILL_PAYMENTS_ANDROID_TOUCH_TO_FILL_CREDIT_CARD_CONTROLLER_H_ + +#include <memory> + +#include "base/android/jni_android.h" +#include "base/android/scoped_java_ref.h" +#include "base/memory/weak_ptr.h" +#include "chrome/browser/touch_to_fill/payments/android/touch_to_fill_credit_card_view_controller.h" + +namespace autofill { + +class TouchToFillCreditCardView; +class TouchToFillDelegate; + +// Controller of the bottom sheet surface for filling credit card data on +// Android. It is responsible for showing the view and handling user +// interactions. While the surface is shown, stores its Java counterpart in +// `java_object_`. +class TouchToFillCreditCardController + : public TouchToFillCreditCardViewController { + public: + TouchToFillCreditCardController(); + TouchToFillCreditCardController(const TouchToFillCreditCardController&) = + delete; + TouchToFillCreditCardController& operator=( + const TouchToFillCreditCardController&) = delete; + ~TouchToFillCreditCardController() override; + + // Shows the Touch To Fill `view`. `delegate` will provide the fillable credit + // cards and be notified of the user's decision. Returns whether the surface + // was successfully shown. + bool Show(std::unique_ptr<TouchToFillCreditCardView> view, + base::WeakPtr<TouchToFillDelegate> delegate); + + // Hides the surface if it is currently shown. + void Hide(); + + private: + // TouchToFillCreditCardViewController: + // Called whenever the surface gets hidden (regardless of the cause). + void OnDismissed(JNIEnv* env) override; + // Gets or creates the Java counterpart. + base::android::ScopedJavaLocalRef<jobject> GetJavaObject() override; + + // Delegate for the surface being shown. + base::WeakPtr<TouchToFillDelegate> delegate_; + // View that displays the surface, owned by `this`. + std::unique_ptr<TouchToFillCreditCardView> view_; + // The corresponding Java TouchToFillCreditCardControllerBridge. + base::android::ScopedJavaGlobalRef<jobject> java_object_; +}; + +} // namespace autofill + +#endif // CHROME_BROWSER_TOUCH_TO_FILL_PAYMENTS_ANDROID_TOUCH_TO_FILL_CREDIT_CARD_CONTROLLER_H_
diff --git a/chrome/browser/touch_to_fill/payments/android/touch_to_fill_credit_card_view.h b/chrome/browser/touch_to_fill/payments/android/touch_to_fill_credit_card_view.h new file mode 100644 index 0000000..a807ac8 --- /dev/null +++ b/chrome/browser/touch_to_fill/payments/android/touch_to_fill_credit_card_view.h
@@ -0,0 +1,24 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_TOUCH_TO_FILL_PAYMENTS_ANDROID_TOUCH_TO_FILL_CREDIT_CARD_VIEW_H_ +#define CHROME_BROWSER_TOUCH_TO_FILL_PAYMENTS_ANDROID_TOUCH_TO_FILL_CREDIT_CARD_VIEW_H_ + +namespace autofill { + +class TouchToFillCreditCardViewController; + +// The UI interface which prompts the user to select a credit card to fill +// using Touch To Fill surface. +class TouchToFillCreditCardView { + public: + virtual ~TouchToFillCreditCardView() = default; + + virtual bool Show(TouchToFillCreditCardViewController* controller) = 0; + virtual void Hide() = 0; +}; + +} // namespace autofill + +#endif // CHROME_BROWSER_TOUCH_TO_FILL_PAYMENTS_ANDROID_TOUCH_TO_FILL_CREDIT_CARD_VIEW_H_
diff --git a/chrome/browser/touch_to_fill/payments/android/touch_to_fill_credit_card_view_controller.h b/chrome/browser/touch_to_fill/payments/android/touch_to_fill_credit_card_view_controller.h new file mode 100644 index 0000000..9c1d284 --- /dev/null +++ b/chrome/browser/touch_to_fill/payments/android/touch_to_fill_credit_card_view_controller.h
@@ -0,0 +1,23 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_TOUCH_TO_FILL_PAYMENTS_ANDROID_TOUCH_TO_FILL_CREDIT_CARD_VIEW_CONTROLLER_H_ +#define CHROME_BROWSER_TOUCH_TO_FILL_PAYMENTS_ANDROID_TOUCH_TO_FILL_CREDIT_CARD_VIEW_CONTROLLER_H_ + +namespace autofill { + +// An interface for interaction between the view and the corresponding UI +// controller on Android. Acts as the native counterpart for the Java +// TouchToFillCreditCardComponent.Delegate. +class TouchToFillCreditCardViewController { + public: + virtual ~TouchToFillCreditCardViewController() = default; + + virtual void OnDismissed(JNIEnv* env) = 0; + virtual base::android::ScopedJavaLocalRef<jobject> GetJavaObject() = 0; +}; + +} // namespace autofill + +#endif // CHROME_BROWSER_TOUCH_TO_FILL_PAYMENTS_ANDROID_TOUCH_TO_FILL_CREDIT_CARD_VIEW_CONTROLLER_H_
diff --git a/chrome/browser/touch_to_fill/payments/android/touch_to_fill_credit_card_view_impl.cc b/chrome/browser/touch_to_fill/payments/android/touch_to_fill_credit_card_view_impl.cc index 404bf4b9..1299596c 100644 --- a/chrome/browser/touch_to_fill/payments/android/touch_to_fill_credit_card_view_impl.cc +++ b/chrome/browser/touch_to_fill/payments/android/touch_to_fill_credit_card_view_impl.cc
@@ -4,22 +4,59 @@ #include "chrome/browser/touch_to_fill/payments/android/touch_to_fill_credit_card_view_impl.h" -#include "base/notreached.h" +#include "chrome/browser/touch_to_fill/payments/android/jni_headers/TouchToFillCreditCardViewBridge_jni.h" +#include "chrome/browser/touch_to_fill/payments/android/touch_to_fill_credit_card_view_controller.h" +#include "components/autofill/core/common/autofill_features.h" +#include "content/public/browser/web_contents.h" +#include "ui/android/view_android.h" +#include "ui/android/window_android.h" namespace autofill { -TouchToFillCreditCardViewImpl::TouchToFillCreditCardViewImpl() = default; -TouchToFillCreditCardViewImpl::~TouchToFillCreditCardViewImpl() = default; +TouchToFillCreditCardViewImpl::TouchToFillCreditCardViewImpl( + content::WebContents* web_contents) + : web_contents_(web_contents) { + DCHECK(web_contents); + DCHECK(base::FeatureList::IsEnabled( + features::kAutofillTouchToFillForCreditCardsAndroid)); +} -bool TouchToFillCreditCardViewImpl::Show() { - // TODO(crbug.com/1247698): Show Android view. - NOTIMPLEMENTED(); - return false; +TouchToFillCreditCardViewImpl::~TouchToFillCreditCardViewImpl() { + Hide(); +} + +bool TouchToFillCreditCardViewImpl::Show( + TouchToFillCreditCardViewController* controller) { + if (java_object_) + return false; // Already shown. + + if (!web_contents_->GetNativeView() || + !web_contents_->GetNativeView()->GetWindowAndroid()) { + return false; // No window attached (yet or anymore). + } + + DCHECK(controller); + base::android::ScopedJavaLocalRef<jobject> java_controller = + controller->GetJavaObject(); + if (!java_controller) + return false; + + JNIEnv* env = base::android::AttachCurrentThread(); + java_object_.Reset(Java_TouchToFillCreditCardViewBridge_create( + env, java_controller, + web_contents_->GetTopLevelNativeWindow()->GetJavaObject())); + if (!java_object_) + return false; + + Java_TouchToFillCreditCardViewBridge_showSheet(env, java_object_); + return true; } void TouchToFillCreditCardViewImpl::Hide() { - // TODO(crbug.com/1247698): Hide Android view. - NOTIMPLEMENTED(); + if (java_object_) { + Java_TouchToFillCreditCardViewBridge_hideSheet( + base::android::AttachCurrentThread(), java_object_); + } } } // namespace autofill
diff --git a/chrome/browser/touch_to_fill/payments/android/touch_to_fill_credit_card_view_impl.h b/chrome/browser/touch_to_fill/payments/android/touch_to_fill_credit_card_view_impl.h index 80c6872..7e3ed1e 100644 --- a/chrome/browser/touch_to_fill/payments/android/touch_to_fill_credit_card_view_impl.h +++ b/chrome/browser/touch_to_fill/payments/android/touch_to_fill_credit_card_view_impl.h
@@ -5,21 +5,37 @@ #ifndef CHROME_BROWSER_TOUCH_TO_FILL_PAYMENTS_ANDROID_TOUCH_TO_FILL_CREDIT_CARD_VIEW_IMPL_H_ #define CHROME_BROWSER_TOUCH_TO_FILL_PAYMENTS_ANDROID_TOUCH_TO_FILL_CREDIT_CARD_VIEW_IMPL_H_ -#include "chrome/browser/touch_to_fill/payments/touch_to_fill_credit_card_view.h" +#include "chrome/browser/touch_to_fill/payments/android/touch_to_fill_credit_card_view.h" + +#include "base/android/scoped_java_ref.h" +#include "base/memory/raw_ptr.h" + +namespace content { +class WebContents; +} namespace autofill { +class TouchToFillCreditCardViewController; + +// Android implementation of the surface to select a credit card to fill. +// Uses Java TouchToFillCreditCardComponent to present a bottom sheet. class TouchToFillCreditCardViewImpl : public TouchToFillCreditCardView { public: - TouchToFillCreditCardViewImpl(); + explicit TouchToFillCreditCardViewImpl(content::WebContents* web_contents); TouchToFillCreditCardViewImpl(const TouchToFillCreditCardViewImpl&) = delete; TouchToFillCreditCardViewImpl& operator=( const TouchToFillCreditCardViewImpl&) = delete; ~TouchToFillCreditCardViewImpl() override; + private: // TouchToFillCreditCardView: - bool Show() override; + bool Show(TouchToFillCreditCardViewController* controller) override; void Hide() override; + + // The corresponding Java TouchToFillCreditCardViewBridge. + base::android::ScopedJavaGlobalRef<jobject> java_object_; + raw_ptr<content::WebContents> web_contents_; }; } // namespace autofill
diff --git a/chrome/browser/touch_to_fill/payments/touch_to_fill_credit_card_controller.cc b/chrome/browser/touch_to_fill/payments/touch_to_fill_credit_card_controller.cc deleted file mode 100644 index 3b13f0e..0000000 --- a/chrome/browser/touch_to_fill/payments/touch_to_fill_credit_card_controller.cc +++ /dev/null
@@ -1,38 +0,0 @@ -// Copyright 2022 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/touch_to_fill/payments/touch_to_fill_credit_card_controller.h" - -#include "chrome/browser/touch_to_fill/payments/touch_to_fill_credit_card_view.h" -#include "components/autofill/core/browser/ui/touch_to_fill_delegate.h" - -namespace autofill { - -TouchToFillCreditCardController::TouchToFillCreditCardController() = default; -TouchToFillCreditCardController::~TouchToFillCreditCardController() = default; - -bool TouchToFillCreditCardController::Show( - std::unique_ptr<TouchToFillCreditCardView> view, - base::WeakPtr<TouchToFillDelegate> delegate) { - // Abort if TTF surface is already shown. - if (view_) - return false; - - if (!view->Show()) - return false; - - view_ = std::move(view); - delegate_ = std::move(delegate); - return true; -} - -void TouchToFillCreditCardController::Hide() { - if (view_) { - view_->Hide(); - view_.reset(); - delegate_.reset(); - } -} - -} // namespace autofill
diff --git a/chrome/browser/touch_to_fill/payments/touch_to_fill_credit_card_controller.h b/chrome/browser/touch_to_fill/payments/touch_to_fill_credit_card_controller.h deleted file mode 100644 index 76aaaee..0000000 --- a/chrome/browser/touch_to_fill/payments/touch_to_fill_credit_card_controller.h +++ /dev/null
@@ -1,46 +0,0 @@ -// Copyright 2022 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_TOUCH_TO_FILL_PAYMENTS_TOUCH_TO_FILL_CREDIT_CARD_CONTROLLER_H_ -#define CHROME_BROWSER_TOUCH_TO_FILL_PAYMENTS_TOUCH_TO_FILL_CREDIT_CARD_CONTROLLER_H_ - -#include <memory> - -#include "base/memory/weak_ptr.h" - -namespace autofill { - -class TouchToFillCreditCardView; -class TouchToFillDelegate; - -// Controller of the bottom sheet surface for filling credit card data. It is -// responsible for showing the view and handling user interactions. -class TouchToFillCreditCardController { - public: - TouchToFillCreditCardController(); - TouchToFillCreditCardController(const TouchToFillCreditCardController&) = - delete; - TouchToFillCreditCardController& operator=( - const TouchToFillCreditCardController&) = delete; - ~TouchToFillCreditCardController(); - - // Shows the Touch To Fill |view|. |delegate| will provide the fillable credit - // cards and be notified of the user's decision. Returns whether the surface - // was successfully shown. - bool Show(std::unique_ptr<TouchToFillCreditCardView> view, - base::WeakPtr<TouchToFillDelegate> delegate); - - // Hides the surface if it is currently shown. - void Hide(); - - private: - // Delegate for the surface being shown. - base::WeakPtr<TouchToFillDelegate> delegate_; - // View that displays the surface, owned by |this|. - std::unique_ptr<TouchToFillCreditCardView> view_; -}; - -} // namespace autofill - -#endif // CHROME_BROWSER_TOUCH_TO_FILL_PAYMENTS_TOUCH_TO_FILL_CREDIT_CARD_CONTROLLER_H_
diff --git a/chrome/browser/touch_to_fill/payments/touch_to_fill_credit_card_view.h b/chrome/browser/touch_to_fill/payments/touch_to_fill_credit_card_view.h deleted file mode 100644 index bdce337..0000000 --- a/chrome/browser/touch_to_fill/payments/touch_to_fill_credit_card_view.h +++ /dev/null
@@ -1,22 +0,0 @@ -// Copyright 2022 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_TOUCH_TO_FILL_PAYMENTS_TOUCH_TO_FILL_CREDIT_CARD_VIEW_H_ -#define CHROME_BROWSER_TOUCH_TO_FILL_PAYMENTS_TOUCH_TO_FILL_CREDIT_CARD_VIEW_H_ - -namespace autofill { - -// The UI interface which prompts the user to select a credit card to fill -// using Touch To Fill surface. -class TouchToFillCreditCardView { - public: - virtual ~TouchToFillCreditCardView() = default; - - virtual bool Show() = 0; - virtual void Hide() = 0; -}; - -} // namespace autofill - -#endif // CHROME_BROWSER_TOUCH_TO_FILL_PAYMENTS_TOUCH_TO_FILL_CREDIT_CARD_VIEW_H_
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index ceb13a0..330151f 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -906,6 +906,7 @@ "//chrome/browser/image_decoder", "//chrome/browser/notifications/scheduler/public", "//chrome/browser/resources/webapks:resources", + "//chrome/browser/touch_to_fill/payments/android", "//chrome/browser/ui/android/autofill/internal:jni_headers", "//chrome/browser/ui/webui/explore_sites_internals:mojo_bindings", "//chrome/browser/ui/webui/feed_internals:mojo_bindings", @@ -2131,6 +2132,8 @@ "app_list/search/ranking/ranker.h", "app_list/search/ranking/ranker_delegate.cc", "app_list/search/ranking/ranker_delegate.h", + "app_list/search/ranking/ranking_item_util.cc", + "app_list/search/ranking/ranking_item_util.h", "app_list/search/ranking/removed_results_ranker.cc", "app_list/search/ranking/removed_results_ranker.h", "app_list/search/ranking/score_normalizing_ranker.cc", @@ -2168,8 +2171,6 @@ "app_list/search/search_result_ranker/frecency_store.h", "app_list/search/search_result_ranker/histogram_util.cc", "app_list/search/search_result_ranker/histogram_util.h", - "app_list/search/search_result_ranker/ranking_item_util.cc", - "app_list/search/search_result_ranker/ranking_item_util.h", "app_list/search/search_result_ranker/recurrence_predictor.cc", "app_list/search/search_result_ranker/recurrence_predictor.h", "app_list/search/search_result_ranker/recurrence_ranker.cc",
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/UrlBar.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/UrlBar.java index 037232a..f3eba65c 100644 --- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/UrlBar.java +++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/UrlBar.java
@@ -42,6 +42,7 @@ import org.chromium.base.ThreadUtils; import org.chromium.base.compat.ApiHelperForO; import org.chromium.base.metrics.RecordUserAction; +import org.chromium.chrome.browser.back_press.BackPressManager; import org.chromium.components.browser_ui.share.ShareHelper; import org.chromium.ui.KeyboardVisibilityDelegate; import org.chromium.ui.base.WindowDelegate; @@ -248,10 +249,9 @@ } }, ThreadUtils.getUiThreadHandler()); mGestureDetector.setOnDoubleTapListener(null); - mKeyboardHideHelper = new KeyboardHideHelper(this, new Runnable() { - @Override - public void run() { - if (mUrlBarDelegate != null) mUrlBarDelegate.backKeyPressed(); + mKeyboardHideHelper = new KeyboardHideHelper(this, () -> { + if (mUrlBarDelegate != null && !BackPressManager.isEnabled()) { + mUrlBarDelegate.backKeyPressed(); } });
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 cf8cdd9..ae1602ba 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
@@ -1478,7 +1478,9 @@ } else if (mOptionalButtonAnimationRunning) { return CaptureReadinessResult.notReady( TopToolbarBlockCaptureReason.OPTIONAL_BUTTON_ANIMATION_IN_PROGRESS); - } else if (mLocationBar.getStatusCoordinator().isStatusIconAnimating()) { + } else if (mLocationBar.getStatusCoordinator() != null + && mLocationBar.getStatusCoordinator().isStatusIconAnimating()) { + // TODO(https://crbug.com/1356153): It may be possible to remove the above null check. return CaptureReadinessResult.notReady( TopToolbarBlockCaptureReason.STATUS_ICON_ANIMATION_IN_PROGRESS); } else {
diff --git a/chrome/browser/ui/app_list/app_list_client_impl.cc b/chrome/browser/ui/app_list/app_list_client_impl.cc index f32dfbf..c581c43a 100644 --- a/chrome/browser/ui/app_list/app_list_client_impl.cc +++ b/chrome/browser/ui/app_list/app_list_client_impl.cc
@@ -36,9 +36,9 @@ #include "chrome/browser/ui/app_list/search/chrome_search_result.h" #include "chrome/browser/ui/app_list/search/cros_action_history/cros_action_recorder.h" #include "chrome/browser/ui/app_list/search/ranking/launch_data.h" +#include "chrome/browser/ui/app_list/search/ranking/ranking_item_util.h" #include "chrome/browser/ui/app_list/search/search_controller.h" #include "chrome/browser/ui/app_list/search/search_controller_factory.h" -#include "chrome/browser/ui/app_list/search/search_result_ranker/ranking_item_util.h" #include "chrome/browser/ui/ash/shelf/app_shortcut_shelf_item_controller.h" #include "chrome/browser/ui/ash/shelf/chrome_shelf_controller.h" #include "chrome/browser/ui/ash/shelf/chrome_shelf_controller_util.h"
diff --git a/chrome/browser/ui/app_list/arc/arc_app_utils.cc b/chrome/browser/ui/app_list/arc/arc_app_utils.cc index 1433880..cff2e9f 100644 --- a/chrome/browser/ui/app_list/arc/arc_app_utils.cc +++ b/chrome/browser/ui/app_list/arc/arc_app_utils.cc
@@ -46,8 +46,8 @@ #include "chrome/browser/ui/app_list/app_list_client_impl.h" #include "chrome/browser/ui/app_list/arc/intent.h" #include "chrome/browser/ui/app_list/search/ranking/launch_data.h" +#include "chrome/browser/ui/app_list/search/ranking/ranking_item_util.h" #include "chrome/browser/ui/app_list/search/search_controller.h" -#include "chrome/browser/ui/app_list/search/search_result_ranker/ranking_item_util.h" #include "chrome/browser/ui/ash/shelf/arc_app_shelf_id.h" #include "chrome/browser/ui/ash/shelf/arc_shelf_spinner_item_controller.h" #include "chrome/browser/ui/ash/shelf/chrome_shelf_controller.h"
diff --git a/chrome/browser/ui/app_list/search/app_search_provider.cc b/chrome/browser/ui/app_list/search/app_search_provider.cc index 3a640ba4..12df973 100644 --- a/chrome/browser/ui/app_list/search/app_search_provider.cc +++ b/chrome/browser/ui/app_list/search/app_search_provider.cc
@@ -38,8 +38,8 @@ #include "chrome/browser/ui/app_list/chrome_app_list_item.h" #include "chrome/browser/ui/app_list/internal_app/internal_app_metadata.h" #include "chrome/browser/ui/app_list/search/app_service_app_result.h" +#include "chrome/browser/ui/app_list/search/ranking/ranking_item_util.h" #include "chrome/browser/ui/app_list/search/search_result_ranker/app_search_result_ranker.h" -#include "chrome/browser/ui/app_list/search/search_result_ranker/ranking_item_util.h" #include "chrome/browser/ui/app_list/search/search_tags_util.h" #include "chrome/browser/web_applications/web_app_id_constants.h" #include "chrome/grit/generated_resources.h"
diff --git a/chrome/browser/ui/app_list/search/app_search_provider_unittest.cc b/chrome/browser/ui/app_list/search/app_search_provider_unittest.cc index af00588..5f76e08 100644 --- a/chrome/browser/ui/app_list/search/app_search_provider_unittest.cc +++ b/chrome/browser/ui/app_list/search/app_search_provider_unittest.cc
@@ -32,8 +32,8 @@ #include "chrome/browser/ui/app_list/arc/arc_app_test.h" #include "chrome/browser/ui/app_list/arc/arc_default_app_list.h" #include "chrome/browser/ui/app_list/search/chrome_search_result.h" +#include "chrome/browser/ui/app_list/search/ranking/ranking_item_util.h" #include "chrome/browser/ui/app_list/search/search_result_ranker/app_search_result_ranker.h" -#include "chrome/browser/ui/app_list/search/search_result_ranker/ranking_item_util.h" #include "chrome/browser/ui/app_list/search/test/test_search_controller.h" #include "chrome/browser/ui/app_list/test/fake_app_list_model_updater.h" #include "chrome/browser/ui/app_list/test/test_app_list_controller_delegate.h"
diff --git a/chrome/browser/ui/app_list/search/files/zero_state_file_provider.cc b/chrome/browser/ui/app_list/search/files/zero_state_file_provider.cc index 0e01ce4..4a9e48a4 100644 --- a/chrome/browser/ui/app_list/search/files/zero_state_file_provider.cc +++ b/chrome/browser/ui/app_list/search/files/zero_state_file_provider.cc
@@ -22,6 +22,7 @@ #include "base/task/thread_pool.h" #include "base/threading/scoped_blocking_call.h" #include "base/time/time.h" +#include "chrome/browser/ash/file_manager/path_util.h" #include "chrome/browser/ash/profiles/profile_helper.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/app_list/search/files/file_result.h" @@ -41,13 +42,23 @@ constexpr size_t kMaxLocalFiles = 10u; constexpr base::TimeDelta kSaveDelay = base::Seconds(3); -// Given the output of MrfuCache::GetAll, partition files into: -// - valid files that exist on-disk and have been modified in the last -// |max_last_modified_time| days -// - invalid files, otherwise. +// Screenshots are identified as files that match ScreenshotXXX.png in the +// Downloads folder. +bool IsScreenshot(const base::FilePath& path, + const base::FilePath& downloads_path) { + return path.DirName() == downloads_path && path.Extension() == ".png" && + path.BaseName().value().rfind("Screenshot", 0) == 0; +} + +// Given the output of MrfuCache::GetAll, partition files into valid and invalid +// files. Valid files are files that: +// - Exist on-disk +// - Have been modified in the last |max_last_modified_time| days +// - Are not screenshots. ZeroStateFileProvider::ValidAndInvalidResults ValidateFiles( const std::vector<std::pair<std::string, float>>& ranker_results, - const base::TimeDelta& max_last_modified_time) { + const base::TimeDelta& max_last_modified_time, + const base::FilePath& downloads_path) { base::ScopedBlockingCall scoped_blocking_call(FROM_HERE, base::BlockingType::MAY_BLOCK); @@ -57,13 +68,13 @@ for (const auto& path_score : ranker_results) { // We use FilePath::FromUTF8Unsafe to decode the filepath string. As per its // documentation, this is a safe use of the function because - // ZeroStateFileProvider is only used on ChromeOS, for which - // filepaths are UTF8. + // ZeroStateFileProvider is only used on ChromeOS, for which filepaths are + // UTF8. const auto& path = base::FilePath::FromUTF8Unsafe(path_score.first); - base::File::Info info; if (base::PathExists(path) && base::GetFileInfo(path, &info) && - (now - info.last_modified <= max_last_modified_time)) { + (now - info.last_modified <= max_last_modified_time) && + !IsScreenshot(path, downloads_path)) { valid_results.emplace_back(path, path_score.second, info.last_accessed, info.last_modified); } else { @@ -104,7 +115,9 @@ max_last_modified_time_(base::Days(base::GetFieldTrialParamByFeatureAsInt( ash::features::kProductivityLauncher, "max_last_modified_time", - 8))) { + 8))), + downloads_path_( + file_manager::util::GetDownloadsFolderForProfile(profile)) { DCHECK(profile_); task_runner_ = base::ThreadPool::CreateSequencedTaskRunner( {base::TaskPriority::USER_BLOCKING, base::MayBlock(), @@ -134,7 +147,7 @@ base::PostTaskAndReplyWithResult( task_runner_.get(), FROM_HERE, base::BindOnce(&ValidateFiles, files_ranker_->GetAll(), - max_last_modified_time_), + max_last_modified_time_, downloads_path_), base::BindOnce(&ZeroStateFileProvider::SetSearchResults, weak_factory_.GetWeakPtr())); } @@ -166,7 +179,7 @@ base::PostTaskAndReplyWithResult( task_runner_.get(), FROM_HERE, base::BindOnce(&ValidateFiles, files_ranker_->GetAll(), - max_last_modified_time_), + max_last_modified_time_, downloads_path_), base::BindOnce(&ZeroStateFileProvider::SetSearchResults, weak_factory_.GetWeakPtr())); }
diff --git a/chrome/browser/ui/app_list/search/files/zero_state_file_provider.h b/chrome/browser/ui/app_list/search/files/zero_state_file_provider.h index 0ebb7fa..5c6eb6f 100644 --- a/chrome/browser/ui/app_list/search/files/zero_state_file_provider.h +++ b/chrome/browser/ui/app_list/search/files/zero_state_file_provider.h
@@ -91,6 +91,9 @@ // valid. const base::TimeDelta max_last_modified_time_; + // Path to the downloads folder for this profile. + const base::FilePath downloads_path_; + base::ScopedObservation<file_manager::file_tasks::FileTasksNotifier, file_manager::file_tasks::FileTasksObserver> file_tasks_observer_{this};
diff --git a/chrome/browser/ui/app_list/search/files/zero_state_file_provider_unittest.cc b/chrome/browser/ui/app_list/search/files/zero_state_file_provider_unittest.cc index 71ae5f3..6512183 100644 --- a/chrome/browser/ui/app_list/search/files/zero_state_file_provider_unittest.cc +++ b/chrome/browser/ui/app_list/search/files/zero_state_file_provider_unittest.cc
@@ -10,7 +10,9 @@ #include "base/files/file_path.h" #include "base/files/file_util.h" #include "base/files/scoped_temp_dir.h" +#include "base/test/scoped_running_on_chromeos.h" #include "base/test/task_environment.h" +#include "chrome/browser/ash/file_manager/path_util.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/app_list/search/chrome_search_result.h" #include "chrome/browser/ui/app_list/search/test/test_search_controller.h" @@ -40,12 +42,22 @@ app_list_color_provider_ = std::make_unique<ash::TestAppListColorProvider>(); - profile_ = std::make_unique<TestingProfile>(); + ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); + profile_ = std::make_unique<TestingProfile>(temp_dir_.GetPath()); + + // The downloads directory depends on whether it is inside or outside + // chromeos. So this needs to be in scope before |provider_| and + // |downloads_folder_|. + base::test::ScopedRunningOnChromeOS running_on_chromeos; auto provider = std::make_unique<ZeroStateFileProvider>(profile_.get()); provider_ = provider.get(); search_controller_.AddProvider(0, std::move(provider)); + downloads_folder_ = + file_manager::util::GetDownloadsFolderForProfile(profile_.get()); + ASSERT_TRUE(base::CreateDirectory(downloads_folder_)); + Wait(); } @@ -55,15 +67,19 @@ return profile_->GetPath().AppendASCII(filename); } - void WriteFile(const std::string& filename) { - CHECK(base::WriteFile(Path(filename), "abcd")); - CHECK(base::PathExists(Path(filename))); + base::FilePath DownloadsPath(const std::string& filename) { + return downloads_folder_.AppendASCII(filename); + } + + void WriteFile(const base::FilePath& path) { + CHECK(base::WriteFile(path, "abcd")); + CHECK(base::PathExists(path)); Wait(); } - FileTasksObserver::FileOpenEvent OpenEvent(const std::string& filename) { + FileTasksObserver::FileOpenEvent OpenEvent(const base::FilePath& path) { FileTasksObserver::FileOpenEvent e; - e.path = Path(filename); + e.path = path; e.open_type = FileTasksObserver::OpenType::kOpen; return e; } @@ -85,6 +101,9 @@ content::BrowserTaskEnvironment task_environment_; std::unique_ptr<Profile> profile_; + base::ScopedTempDir temp_dir_; + base::FilePath downloads_folder_; + TestSearchController search_controller_; ZeroStateFileProvider* provider_ = nullptr; std::unique_ptr<ash::TestAppListColorProvider> app_list_color_provider_; @@ -97,14 +116,14 @@ } TEST_F(ZeroStateFileProviderTest, ResultsProvided) { - WriteFile("exists_1.txt"); - WriteFile("exists_2.png"); - WriteFile("exists_3.pdf"); + WriteFile(Path("exists_1.txt")); + WriteFile(Path("exists_2.png")); + WriteFile(Path("exists_3.pdf")); // Results are only added if they have been opened at least once. - provider_->OnFilesOpened( - {OpenEvent("exists_1.txt"), OpenEvent("exists_2.png")}); - provider_->OnFilesOpened({OpenEvent("nonexistant.txt")}); + provider_->OnFilesOpened({OpenEvent(Path("exists_1.txt")), + OpenEvent(Path("exists_2.png")), + OpenEvent(Path("nonexistent.txt"))}); StartZeroStateSearch(); Wait(); @@ -114,12 +133,13 @@ } TEST_F(ZeroStateFileProviderTest, OldFilesNotReturned) { - WriteFile("new.txt"); - WriteFile("old.png"); + WriteFile(Path("new.txt")); + WriteFile(Path("old.png")); auto now = base::Time::Now(); base::TouchFile(Path("old.png"), now, now - base::Days(8)); - provider_->OnFilesOpened({OpenEvent("new.txt"), OpenEvent("old.png")}); + provider_->OnFilesOpened( + {OpenEvent(Path("new.txt")), OpenEvent(Path("old.png"))}); StartZeroStateSearch(); Wait(); @@ -127,4 +147,26 @@ EXPECT_THAT(LastResults(), UnorderedElementsAre(Title(u"new.txt"))); } +TEST_F(ZeroStateFileProviderTest, FilterScreenshots) { + WriteFile(Path("ScreenshotNonDownload.png")); + WriteFile(DownloadsPath("ScreenshotNonPng.jpg")); + WriteFile(DownloadsPath("NotScreenshot.png")); + WriteFile(DownloadsPath("Screenshot123.png")); + + provider_->OnFilesOpened({OpenEvent(Path("ScreenshotNonDownload.png")), + OpenEvent(DownloadsPath("ScreenshotNonPng.jpg")), + OpenEvent(DownloadsPath("NotScreenshot.png")), + OpenEvent(DownloadsPath("Screenshot123.png"))}); + + StartZeroStateSearch(); + Wait(); + + // Screenshot123 matches the criteria for a screenshot and should be filtered + // out. + EXPECT_THAT(LastResults(), + UnorderedElementsAre(Title(u"ScreenshotNonDownload.png"), + Title(u"ScreenshotNonPng.jpg"), + Title(u"NotScreenshot.png"))); +} + } // namespace app_list
diff --git a/chrome/browser/ui/app_list/search/mixer.cc b/chrome/browser/ui/app_list/search/mixer.cc index 6d281205..6f1eb74 100644 --- a/chrome/browser/ui/app_list/search/mixer.cc +++ b/chrome/browser/ui/app_list/search/mixer.cc
@@ -18,10 +18,10 @@ #include "base/strings/string_util.h" #include "chrome/browser/ui/app_list/app_list_model_updater.h" #include "chrome/browser/ui/app_list/search/chrome_search_result.h" +#include "chrome/browser/ui/app_list/search/ranking/ranking_item_util.h" #include "chrome/browser/ui/app_list/search/search_controller_impl.h" #include "chrome/browser/ui/app_list/search/search_provider.h" #include "chrome/browser/ui/app_list/search/search_result_ranker/chip_ranker.h" -#include "chrome/browser/ui/app_list/search/search_result_ranker/ranking_item_util.h" #include "chrome/browser/ui/app_list/search/search_result_ranker/search_result_ranker.h" namespace app_list {
diff --git a/chrome/browser/ui/app_list/search/omnibox_lacros_provider_unittest.cc b/chrome/browser/ui/app_list/search/omnibox_lacros_provider_unittest.cc index fb1a5e7..757c9e98 100644 --- a/chrome/browser/ui/app_list/search/omnibox_lacros_provider_unittest.cc +++ b/chrome/browser/ui/app_list/search/omnibox_lacros_provider_unittest.cc
@@ -73,7 +73,6 @@ result->contents_type = cam::SearchResult::TextType::kUnset; result->description = u"description"; result->description_type = cam::SearchResult::TextType::kUnset; - result->is_omnibox_search = cam::SearchResult::OptionalBool::kTrue; result->is_omnibox_search = cam::SearchResult::OptionalBool::kFalse; result->answer_type = answer_type;
diff --git a/chrome/browser/ui/app_list/search/omnibox_provider.h b/chrome/browser/ui/app_list/search/omnibox_provider.h index f7407dd..06aef50 100644 --- a/chrome/browser/ui/app_list/search/omnibox_provider.h +++ b/chrome/browser/ui/app_list/search/omnibox_provider.h
@@ -38,10 +38,17 @@ void StartZeroState() override; ash::AppListSearchResultType ResultType() const override; - private: // Populates result list from AutocompleteResult. void PopulateFromACResult(const AutocompleteResult& result); + // Change the query_finished_ flag for testing purpose. + // TODO(crbug.com/1356409): Replace this function with formal testing + // procedures. + void set_query_finished_for_test(bool query_finished) { + query_finished_ = query_finished; + }; + + private: // AutocompleteController::Observer overrides: void OnResultChanged(AutocompleteController* controller, bool default_match_changed) override;
diff --git a/chrome/browser/ui/app_list/search/omnibox_provider_unittest.cc b/chrome/browser/ui/app_list/search/omnibox_provider_unittest.cc new file mode 100644 index 0000000..0cf2a1e8 --- /dev/null +++ b/chrome/browser/ui/app_list/search/omnibox_provider_unittest.cc
@@ -0,0 +1,310 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/app_list/search/omnibox_provider.h" + +#include <cstddef> +#include <string> +#include <vector> + +#include "ash/constants/ash_features.h" +#include "base/run_loop.h" +#include "base/test/scoped_feature_list.h" +#include "chrome/browser/search_engines/template_url_service_factory.h" +#include "chrome/browser/ui/app_list/search/omnibox_util.h" +#include "chrome/browser/ui/app_list/search/search_controller.h" +#include "chrome/browser/ui/app_list/search/test/test_search_controller.h" +#include "chrome/browser/ui/app_list/test/test_app_list_controller_delegate.h" +#include "chrome/common/chrome_constants.h" +#include "chrome/test/base/testing_browser_process.h" +#include "chrome/test/base/testing_profile_manager.h" +#include "components/omnibox/browser/suggestion_answer.h" +#include "components/variations/scoped_variations_ids_provider.h" +#include "components/variations/variations_ids_provider.h" +#include "content/public/test/browser_task_environment.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace app_list::test { + +// Note that there is necessarily a lot of overlap with unittest in the lacros +// omnibox provider unittest, since this is testing the same behavior. +namespace { + +// Helper functions to populate search results. +// Currently only the ones that may affect test results are filled. +AutocompleteMatch NewOmniboxResult(const std::string& url) { + AutocompleteMatch result; + + result.relevance = 1.0; + result.destination_url = GURL(url); + result.stripped_destination_url = GURL(url); + result.contents = u"contents"; + result.description = u"description"; + result.type = AutocompleteMatchType::BOOKMARK_TITLE; + + return result; +} + +AutocompleteMatch NewAnswerResult(const std::string& url, + SuggestionAnswer::AnswerType answer_type) { + AutocompleteMatch result; + + result.relevance = 1.0; + result.destination_url = GURL(url); + result.stripped_destination_url = GURL(url); + result.contents = u"contents"; + result.description = u"description"; + SuggestionAnswer answer; + answer.set_type(answer_type); + result.answer = answer; + + return result; +} + +AutocompleteMatch NewOpenTabResult(const std::string& url) { + AutocompleteMatch result; + + result.relevance = 1.0; + result.destination_url = GURL(url); + result.stripped_destination_url = GURL(url); + result.contents = u"contents"; + result.description = u"description"; + result.type = AutocompleteMatchType::OPEN_TAB; + + return result; +} + +} // namespace + +class OmniboxProviderTest : public testing::Test { + public: + OmniboxProviderTest() { + scoped_feature_list_.InitAndEnableFeature( + ash::features::kProductivityLauncher); + } + OmniboxProviderTest(const OmniboxProviderTest&) = delete; + OmniboxProviderTest& operator=(const OmniboxProviderTest&) = delete; + ~OmniboxProviderTest() override = default; + + void SetUp() override { + // Create the profile manager and an active profile. + profile_manager_ = std::make_unique<TestingProfileManager>( + TestingBrowserProcess::GetGlobal()); + ASSERT_TRUE(profile_manager_->SetUp()); + // The profile needs a template URL service for history Omnibox results. + profile_ = profile_manager_->CreateTestingProfile( + chrome::kInitialProfile, + {{TemplateURLServiceFactory::GetInstance(), + base::BindRepeating(&TemplateURLServiceFactory::BuildInstanceFor)}}); + + // Create client of our provider. + search_controller_ = std::make_unique<TestSearchController>(); + + // Create the object to actually test. + list_controller_ = + std::make_unique<::test::TestAppListControllerDelegate>(); + provider_ = + std::make_unique<OmniboxProvider>(profile_, list_controller_.get()); + provider_->set_controller(search_controller_.get()); + + base::RunLoop().RunUntilIdle(); + } + + void TearDown() override { + provider_.reset(); + search_controller_.reset(); + list_controller_.reset(); + scoped_feature_list_.Reset(); + profile_ = nullptr; + profile_manager_->DeleteTestingProfile(chrome::kInitialProfile); + } + + void ProduceResults(const AutocompleteResult& results) { + provider_->set_query_finished_for_test(false); + provider_->PopulateFromACResult(std::move(results)); + base::RunLoop().RunUntilIdle(); + } + + // Starts a search and waits for the query to be sent + void StartSearch(const std::u16string& query) { + provider_->Start(query); + base::RunLoop().RunUntilIdle(); + } + + protected: + std::unique_ptr<TestSearchController> search_controller_; + + private: + base::test::ScopedFeatureList scoped_feature_list_; + content::BrowserTaskEnvironment task_environment_; + variations::ScopedVariationsIdsProvider scoped_variations_ids_provider_{ + variations::VariationsIdsProvider::Mode::kUseSignedInState}; + std::unique_ptr<AppListControllerDelegate> list_controller_; + + std::unique_ptr<TestingProfileManager> profile_manager_; + TestingProfile* profile_; + + std::unique_ptr<OmniboxProvider> provider_; +}; + +// Test that results each instantiate a Chrome search result. +TEST_F(OmniboxProviderTest, Basic) { + StartSearch(u"query"); + + std::vector<AutocompleteMatch> to_produce; + AutocompleteResult result; + + to_produce.emplace_back(NewOmniboxResult("https://example.com/result")); + to_produce.emplace_back( + NewAnswerResult("https://example.com/answer", + SuggestionAnswer::AnswerType::ANSWER_TYPE_WEATHER)); + to_produce.emplace_back(NewOpenTabResult("https://example.com/open_tab")); + result.AppendMatches(to_produce); + ProduceResults(std::move(result)); + + // Results always appear after answer and open tab entries. + ASSERT_EQ(3u, search_controller_->last_results().size()); + EXPECT_EQ("omnibox_answer://https://example.com/answer", + search_controller_->last_results()[0]->id()); + EXPECT_EQ("opentab://https://example.com/open_tab", + search_controller_->last_results()[1]->id()); + EXPECT_EQ("https://example.com/result", + search_controller_->last_results()[2]->id()); +} + +// Test that newly-produced results supersede previous results. +TEST_F(OmniboxProviderTest, NewResults) { + StartSearch(u"query"); + + // Produce one result. + std::vector<AutocompleteMatch> to_produce; + AutocompleteResult result; + + to_produce.emplace_back(NewOpenTabResult("https://example.com/open_tab_1")); + result.AppendMatches(to_produce); + ProduceResults(std::move(result)); + + // Then produce another. + to_produce.clear(); + AutocompleteResult new_result; + to_produce.emplace_back(NewOpenTabResult("https://example.com/open_tab_2")); + new_result.AppendMatches(to_produce); + ProduceResults(std::move(new_result)); + + // Only newest result should be stored. + ASSERT_EQ(1u, search_controller_->last_results().size()); + EXPECT_EQ("opentab://https://example.com/open_tab_2", + search_controller_->last_results()[0]->id()); +} + +// Test that invalid URLs aren't accepted. +TEST_F(OmniboxProviderTest, BadUrls) { + StartSearch(u"query"); + + // All results have bad URLs. + std::vector<AutocompleteMatch> to_produce; + AutocompleteResult result; + + to_produce.emplace_back(NewOmniboxResult("")); + to_produce.emplace_back(NewAnswerResult( + "badscheme", SuggestionAnswer::AnswerType::ANSWER_TYPE_WEATHER)); + to_produce.emplace_back(NewOpenTabResult("http://?k=v")); + result.AppendMatches(to_produce); + ProduceResults(std::move(result)); + + // None of the results should be accepted. + EXPECT_TRUE(search_controller_->last_results().empty()); +} + +// Test that results with the same URL are deduplicated in the correct order. +TEST_F(OmniboxProviderTest, Deduplicate) { + StartSearch(u"query"); + + // A result that has the same URL as another result, but is a history (i.e. + // higher-priority) type. + auto history_result = NewOmniboxResult("https://example.com/result_1"); + history_result.contents = u"history"; + history_result.description = u"history description"; + history_result.type = AutocompleteMatchType::SEARCH_HISTORY; + + std::vector<AutocompleteMatch> to_produce; + AutocompleteResult result; + + to_produce.emplace_back(NewOmniboxResult("https://example.com/result_2")); + to_produce.emplace_back(NewOmniboxResult("https://example.com/result_1")); + to_produce.emplace_back(std::move(history_result)); + + result.AppendMatches(to_produce); + ProduceResults(std::move(result)); + + // Only the higher-priority (i.e. history) result for URL 1 should be kept. + ASSERT_EQ(2u, search_controller_->last_results().size()); + EXPECT_EQ("https://example.com/result_1", + search_controller_->last_results()[0]->id()); + EXPECT_EQ(u"history", search_controller_->last_results()[0]->title()); + EXPECT_EQ("https://example.com/result_2", + search_controller_->last_results()[1]->id()); +} + +// Test that results aren't created for URLs for which there are other +// specialist producers. +TEST_F(OmniboxProviderTest, UnhandledUrls) { + StartSearch(u"query"); + + // Drive URLs aren't handled (_unless_ they are open tabs pointing to the + // Drive website), and file URLs aren't handled. + std::vector<AutocompleteMatch> to_produce; + AutocompleteResult result; + + to_produce.emplace_back(NewOmniboxResult("https://drive.google.com/doc1")); + to_produce.emplace_back( + NewAnswerResult("https://docs.google.com/doc2", + SuggestionAnswer::AnswerType::ANSWER_TYPE_FINANCE)); + to_produce.emplace_back(NewOpenTabResult("https://drive.google.com/doc1")); + to_produce.emplace_back(NewOpenTabResult("https://docs.google.com/doc2")); + to_produce.emplace_back(NewOpenTabResult("file:///docs/doc3")); + result.AppendMatches(to_produce); + ProduceResults(std::move(result)); + + ASSERT_EQ(2u, search_controller_->last_results().size()); + EXPECT_EQ("opentab://https://drive.google.com/doc1", + search_controller_->last_results()[0]->id()); + EXPECT_EQ("opentab://https://docs.google.com/doc2", + search_controller_->last_results()[1]->id()); +} + +// Test that answers of certain kinds (that tend to over-trigger) aren't shown +// on very short queries. +TEST_F(OmniboxProviderTest, ShortQuery) { + // Start with a query that is one character too short. + StartSearch(std::u16string(kMinQueryLengthForCommonAnswers - 1, 'a')); + + // All results except dictionary and translate answers are allowed. + std::vector<AutocompleteMatch> to_produce; + AutocompleteResult result; + + to_produce.emplace_back(NewOmniboxResult("https://nonanswer.com/")); + to_produce.emplace_back( + NewAnswerResult("https://finance.com/", + SuggestionAnswer::AnswerType::ANSWER_TYPE_FINANCE)); + to_produce.emplace_back(NewOpenTabResult("https://opentab.com/")); + to_produce.emplace_back( + NewAnswerResult("https://translation.com/", + SuggestionAnswer::AnswerType::ANSWER_TYPE_TRANSLATION)); + to_produce.emplace_back( + NewAnswerResult("https://dictionary.com/", + SuggestionAnswer::AnswerType::ANSWER_TYPE_DICTIONARY)); + result.AppendMatches(to_produce); + ProduceResults(std::move(result)); + + ASSERT_EQ(3u, search_controller_->last_results().size()); + EXPECT_EQ("omnibox_answer://https://finance.com/", + search_controller_->last_results()[0]->id()); + EXPECT_EQ("opentab://https://opentab.com/", + search_controller_->last_results()[1]->id()); + EXPECT_EQ("https://nonanswer.com/", + search_controller_->last_results()[2]->id()); +} + +} // namespace app_list::test
diff --git a/chrome/browser/ui/app_list/search/ranking/launch_data.h b/chrome/browser/ui/app_list/search/ranking/launch_data.h index 5d299639..4a8df061 100644 --- a/chrome/browser/ui/app_list/search/ranking/launch_data.h +++ b/chrome/browser/ui/app_list/search/ranking/launch_data.h
@@ -8,7 +8,7 @@ #include <string> #include "ash/public/cpp/app_list/app_list_types.h" -#include "chrome/browser/ui/app_list/search/search_result_ranker/ranking_item_util.h" +#include "chrome/browser/ui/app_list/search/ranking/ranking_item_util.h" namespace app_list {
diff --git a/chrome/browser/ui/app_list/search/search_result_ranker/ranking_item_util.cc b/chrome/browser/ui/app_list/search/ranking/ranking_item_util.cc similarity index 97% rename from chrome/browser/ui/app_list/search/search_result_ranker/ranking_item_util.cc rename to chrome/browser/ui/app_list/search/ranking/ranking_item_util.cc index 958abe5..a2b8ba6 100644 --- a/chrome/browser/ui/app_list/search/search_result_ranker/ranking_item_util.cc +++ b/chrome/browser/ui/app_list/search/ranking/ranking_item_util.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/ui/app_list/search/search_result_ranker/ranking_item_util.h" +#include "chrome/browser/ui/app_list/search/ranking/ranking_item_util.h" #include "ash/public/cpp/app_list/app_list_features.h" #include "ash/public/cpp/app_list/app_list_types.h"
diff --git a/chrome/browser/ui/app_list/search/search_result_ranker/ranking_item_util.h b/chrome/browser/ui/app_list/search/ranking/ranking_item_util.h similarity index 88% rename from chrome/browser/ui/app_list/search/search_result_ranker/ranking_item_util.h rename to chrome/browser/ui/app_list/search/ranking/ranking_item_util.h index 0b6c437..8e74b483 100644 --- a/chrome/browser/ui/app_list/search/search_result_ranker/ranking_item_util.h +++ b/chrome/browser/ui/app_list/search/ranking/ranking_item_util.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_UI_APP_LIST_SEARCH_SEARCH_RESULT_RANKER_RANKING_ITEM_UTIL_H_ -#define CHROME_BROWSER_UI_APP_LIST_SEARCH_SEARCH_RESULT_RANKER_RANKING_ITEM_UTIL_H_ +#ifndef CHROME_BROWSER_UI_APP_LIST_SEARCH_RANKING_RANKING_ITEM_UTIL_H_ +#define CHROME_BROWSER_UI_APP_LIST_SEARCH_RANKING_RANKING_ITEM_UTIL_H_ #include <string> @@ -58,4 +58,4 @@ } // namespace app_list -#endif // CHROME_BROWSER_UI_APP_LIST_SEARCH_SEARCH_RESULT_RANKER_RANKING_ITEM_UTIL_H_ +#endif // CHROME_BROWSER_UI_APP_LIST_SEARCH_RANKING_RANKING_ITEM_UTIL_H_
diff --git a/chrome/browser/ui/app_list/search/search_result_ranker/ranking_item_util_unittest.cc b/chrome/browser/ui/app_list/search/ranking/ranking_item_util_unittest.cc similarity index 96% rename from chrome/browser/ui/app_list/search/search_result_ranker/ranking_item_util_unittest.cc rename to chrome/browser/ui/app_list/search/ranking/ranking_item_util_unittest.cc index 8c04767..490813c 100644 --- a/chrome/browser/ui/app_list/search/search_result_ranker/ranking_item_util_unittest.cc +++ b/chrome/browser/ui/app_list/search/ranking/ranking_item_util_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/ui/app_list/search/search_result_ranker/ranking_item_util.h" +#include "chrome/browser/ui/app_list/search/ranking/ranking_item_util.h" #include <memory> #include <string>
diff --git a/chrome/browser/ui/app_list/search/search_controller_impl.cc b/chrome/browser/ui/app_list/search/search_controller_impl.cc index de21720e..98482a3 100644 --- a/chrome/browser/ui/app_list/search/search_controller_impl.cc +++ b/chrome/browser/ui/app_list/search/search_controller_impl.cc
@@ -25,11 +25,11 @@ #include "chrome/browser/ui/app_list/search/chrome_search_result.h" #include "chrome/browser/ui/app_list/search/common/string_util.h" #include "chrome/browser/ui/app_list/search/cros_action_history/cros_action_recorder.h" +#include "chrome/browser/ui/app_list/search/ranking/ranking_item_util.h" #include "chrome/browser/ui/app_list/search/search_metrics_observer.h" #include "chrome/browser/ui/app_list/search/search_provider.h" #include "chrome/browser/ui/app_list/search/search_result_ranker/chip_ranker.h" #include "chrome/browser/ui/app_list/search/search_result_ranker/histogram_util.h" -#include "chrome/browser/ui/app_list/search/search_result_ranker/ranking_item_util.h" #include "chrome/browser/ui/app_list/search/search_result_ranker/search_result_ranker.h" #include "components/metrics/structured/structured_events.h" #include "components/prefs/pref_service.h"
diff --git a/chrome/browser/ui/app_list/search/search_result_ranker/chip_ranker.cc b/chrome/browser/ui/app_list/search/search_result_ranker/chip_ranker.cc index 8bc685d..70ded489 100644 --- a/chrome/browser/ui/app_list/search/search_result_ranker/chip_ranker.cc +++ b/chrome/browser/ui/app_list/search/search_result_ranker/chip_ranker.cc
@@ -15,9 +15,9 @@ #include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/ui/app_list/internal_app/internal_app_metadata.h" #include "chrome/browser/ui/app_list/search/chrome_search_result.h" +#include "chrome/browser/ui/app_list/search/ranking/ranking_item_util.h" #include "chrome/browser/ui/app_list/search/search_result_ranker/app_search_result_ranker.h" #include "chrome/browser/ui/app_list/search/search_result_ranker/histogram_util.h" -#include "chrome/browser/ui/app_list/search/search_result_ranker/ranking_item_util.h" #include "chrome/browser/ui/app_list/search/search_result_ranker/recurrence_ranker.h" namespace app_list {
diff --git a/chrome/browser/ui/app_list/search/search_result_ranker/histogram_util.cc b/chrome/browser/ui/app_list/search/search_result_ranker/histogram_util.cc index b88e729..b3e863f 100644 --- a/chrome/browser/ui/app_list/search/search_result_ranker/histogram_util.cc +++ b/chrome/browser/ui/app_list/search/search_result_ranker/histogram_util.cc
@@ -10,7 +10,7 @@ #include "base/containers/flat_set.h" #include "base/metrics/histogram_functions.h" #include "base/metrics/histogram_macros.h" -#include "chrome/browser/ui/app_list/search/search_result_ranker/ranking_item_util.h" +#include "chrome/browser/ui/app_list/search/ranking/ranking_item_util.h" namespace app_list { namespace {
diff --git a/chrome/browser/ui/app_list/search/search_result_ranker/histogram_util.h b/chrome/browser/ui/app_list/search/search_result_ranker/histogram_util.h index a1097425b..d37308e2 100644 --- a/chrome/browser/ui/app_list/search/search_result_ranker/histogram_util.h +++ b/chrome/browser/ui/app_list/search/search_result_ranker/histogram_util.h
@@ -8,7 +8,7 @@ #include <string> #include <vector> -#include "chrome/browser/ui/app_list/search/search_result_ranker/ranking_item_util.h" +#include "chrome/browser/ui/app_list/search/ranking/ranking_item_util.h" namespace app_list {
diff --git a/chrome/browser/ui/app_list/search/search_result_ranker/search_result_ranker.cc b/chrome/browser/ui/app_list/search/search_result_ranker/search_result_ranker.cc index 2abe6a3e..46bb0d71 100644 --- a/chrome/browser/ui/app_list/search/search_result_ranker/search_result_ranker.cc +++ b/chrome/browser/ui/app_list/search/search_result_ranker/search_result_ranker.cc
@@ -26,9 +26,9 @@ #include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/ui/app_list/search/chrome_search_result.h" #include "chrome/browser/ui/app_list/search/cros_action_history/cros_action_recorder.h" +#include "chrome/browser/ui/app_list/search/ranking/ranking_item_util.h" #include "chrome/browser/ui/app_list/search/search_result_ranker/app_search_result_ranker.h" #include "chrome/browser/ui/app_list/search/search_result_ranker/histogram_util.h" -#include "chrome/browser/ui/app_list/search/search_result_ranker/ranking_item_util.h" #include "chrome/browser/ui/app_list/search/search_result_ranker/recurrence_ranker.h" #include "url/gurl.h"
diff --git a/chrome/browser/ui/app_list/search/search_result_ranker/search_result_ranker_unittest.cc b/chrome/browser/ui/app_list/search/search_result_ranker/search_result_ranker_unittest.cc index b108f1f..07e4dbea 100644 --- a/chrome/browser/ui/app_list/search/search_result_ranker/search_result_ranker_unittest.cc +++ b/chrome/browser/ui/app_list/search/search_result_ranker/search_result_ranker_unittest.cc
@@ -24,10 +24,10 @@ #include "chrome/browser/ui/app_list/search/chrome_search_result.h" #include "chrome/browser/ui/app_list/search/mixer.h" #include "chrome/browser/ui/app_list/search/ranking/launch_data.h" +#include "chrome/browser/ui/app_list/search/ranking/ranking_item_util.h" #include "chrome/browser/ui/app_list/search/search_controller.h" #include "chrome/browser/ui/app_list/search/search_controller_impl.h" #include "chrome/browser/ui/app_list/search/search_result_ranker/histogram_util.h" -#include "chrome/browser/ui/app_list/search/search_result_ranker/ranking_item_util.h" #include "chrome/browser/ui/app_list/search/search_result_ranker/recurrence_predictor.h" #include "chrome/browser/ui/app_list/search/search_result_ranker/recurrence_ranker.h" #include "chrome/browser/ui/app_list/search/test/ranking_test_util.h"
diff --git a/chrome/browser/ui/ash/projector/projector_client_impl.cc b/chrome/browser/ui/ash/projector/projector_client_impl.cc index 8a18560b..c803843 100644 --- a/chrome/browser/ui/ash/projector/projector_client_impl.cc +++ b/chrome/browser/ui/ash/projector/projector_client_impl.cc
@@ -127,7 +127,8 @@ } void ProjectorClientImpl::OpenProjectorApp() const { - LaunchProjectorAppWithFiles(/*files=*/{}); + auto* profile = ProfileManager::GetActiveUserProfile(); + ash::LaunchSystemWebAppAsync(profile, ash::SystemWebAppType::PROJECTOR); } void ProjectorClientImpl::MinimizeProjectorApp() const {
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 3ff4956c..9d2a8f6 100644 --- a/chrome/browser/ui/ash/projector/projector_client_impl_browsertest.cc +++ b/chrome/browser/ui/ash/projector/projector_client_impl_browsertest.cc
@@ -201,31 +201,10 @@ content::PAGE_TYPE_NORMAL); } -// This test covers launching the Projector app with files for the first time. -IN_PROC_BROWSER_TEST_F(ProjectorClientTest, LaunchProjectorAppWithFiles) { - auto* profile = browser()->profile(); - SystemWebAppManager::GetForTest(profile)->InstallSystemAppsForTesting(); - - base::FilePath file1("test1"), file2("test2"); - LaunchProjectorAppWithFiles({file1, file2}); - FlushSystemWebAppLaunchesForTesting(profile); - - // Verify that Projector App is opened. - Browser* app_browser = - FindSystemWebAppBrowser(profile, SystemWebAppType::PROJECTOR); - ASSERT_TRUE(app_browser); - content::WebContents* tab = - app_browser->tab_strip_model()->GetActiveWebContents(); - ASSERT_TRUE(tab); - EXPECT_EQ(tab->GetController().GetVisibleEntry()->GetPageType(), - content::PAGE_TYPE_NORMAL); -} - // This test covers launching the Projector app with files when the app is // already open. The launch event should recycle the existing window and should // not open a new window. -IN_PROC_BROWSER_TEST_F(ProjectorClientTest, - LaunchProjectorAppWithFilesWhenAppAlreadyOpen) { +IN_PROC_BROWSER_TEST_F(ProjectorClientTest, SendFilesToProjectorApp) { const size_t starting_browser_count = chrome::GetTotalBrowserCount(); auto* profile = browser()->profile(); @@ -244,7 +223,7 @@ base::FilePath file1("test1"), file2("test2"); // Launch the app again with files. This operation should recycle the same // window. - LaunchProjectorAppWithFiles({file1, file2}); + SendFilesToProjectorApp({file1, file2}); FlushSystemWebAppLaunchesForTesting(profile); // Verify that the Projector App is still open.
diff --git a/chrome/browser/ui/ash/projector/projector_utils.cc b/chrome/browser/ui/ash/projector/projector_utils.cc index 44b4156..08f20fee 100644 --- a/chrome/browser/ui/ash/projector/projector_utils.cc +++ b/chrome/browser/ui/ash/projector/projector_utils.cc
@@ -6,6 +6,8 @@ #include "ash/constants/ash_features.h" #include "ash/constants/ash_pref_names.h" +#include "ash/webui/projector_app/public/cpp/projector_app_constants.h" +#include "ash/webui/projector_app/trusted_projector_ui.h" #include "base/files/file_path.h" #include "chrome/browser/ash/profiles/profile_helper.h" #include "chrome/browser/ash/system_web_apps/types/system_web_app_type.h" @@ -13,7 +15,15 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/ui/ash/system_web_apps/system_web_app_ui_utils.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/tabs/tab_strip_model.h" +#include "chrome/browser/web_applications/web_app_launch_params.h" +#include "chrome/browser/web_applications/web_app_launch_queue.h" +#include "chrome/browser/web_applications/web_app_tab_helper.h" #include "components/prefs/pref_service.h" +#include "content/public/browser/navigation_controller.h" +#include "content/public/browser/web_contents.h" +#include "content/public/browser/web_ui.h" namespace { @@ -60,10 +70,38 @@ profile->GetPrefs()->GetBoolean(ash::prefs::kProjectorAllowByPolicy)); } -void LaunchProjectorAppWithFiles(std::vector<base::FilePath> files) { - auto* profile = ProfileManager::GetActiveUserProfile(); - ash::SystemAppLaunchParams params; - params.launch_paths = std::move(files); - ash::LaunchSystemWebAppAsync(profile, ash::SystemWebAppType::PROJECTOR, - params); +void SendFilesToProjectorApp(std::vector<base::FilePath> files) { + Profile* profile = ProfileManager::GetActiveUserProfile(); + Browser* browser = + ash::FindSystemWebAppBrowser(profile, ash::SystemWebAppType::PROJECTOR); + if (!browser) { + // Do not call SendFilesToProjectorApp() unless the Projector app is already + // open. + return; + } + content::WebContents* web_contents = + browser->tab_strip_model()->GetActiveWebContents(); + auto* web_ui = web_contents->GetWebUI(); + if (!web_ui) + return; + if (!web_ui->GetController()->GetAs<ash::TrustedProjectorUI>()) { + // We only want to send files to the Projector SWA. Don't send files to the + // wrong trusted context if it navigates away. + // TODO(b/237089852): Consider using a navigation throttle to prevent the + // trusted contents from navigating away, but this check is still useful as + // an extra precaution. + return; + } + + web_app::WebAppLaunchParams launch_params; + launch_params.started_new_navigation = false; + launch_params.app_id = ash::kChromeUITrustedProjectorSwaAppId; + // Sending files should not navigate the app. This argument is used for + // storage isolation, and won't impact navigation. It should be in scope of + // the current WebContent's origin. + launch_params.target_url = web_contents->GetVisibleURL(); + launch_params.paths = std::move(files); + web_app::WebAppTabHelper::FromWebContents(web_contents) + ->EnsureLaunchQueue() + .Enqueue(std::move(launch_params)); }
diff --git a/chrome/browser/ui/ash/projector/projector_utils.h b/chrome/browser/ui/ash/projector/projector_utils.h index 28b4d1a..58371ee 100644 --- a/chrome/browser/ui/ash/projector/projector_utils.h +++ b/chrome/browser/ui/ash/projector/projector_utils.h
@@ -19,8 +19,11 @@ // Returns whether the Projector app is enabled. bool IsProjectorAppEnabled(const Profile* profile); -// Launches the Projector SWA with the specified files. If the app is already -// open, then reuse the existing window. -void LaunchProjectorAppWithFiles(std::vector<base::FilePath> files); +// Sends the specified `files` to the Projector SWA. The app must be already +// open as a prerequisite before calling this function. +// Note: this function passes by value to avoid a copy in the implementation. +// Transfer ownership using std::move() if you want to avoid a copy when calling +// this function. +void SendFilesToProjectorApp(std::vector<base::FilePath> files); #endif // CHROME_BROWSER_UI_ASH_PROJECTOR_PROJECTOR_UTILS_H_
diff --git a/chrome/browser/ui/ash/projector/screencast_manager.cc b/chrome/browser/ui/ash/projector/screencast_manager.cc index 2875ffe3..1d27759 100644 --- a/chrome/browser/ui/ash/projector/screencast_manager.cc +++ b/chrome/browser/ui/ash/projector/screencast_manager.cc
@@ -65,7 +65,7 @@ video->duration_millis = base::NumberToString(metadata->duration * kOneSecondInMillisecond); // Launches app on UI thread when duration is valid. - LaunchProjectorAppWithFiles({video_path}); + SendFilesToProjectorApp({video_path}); std::move(callback).Run(std::move(video), /*error_message=*/std::string()); }
diff --git a/chrome/browser/ui/ash/projector/screencast_manager_browsertest.cc b/chrome/browser/ui/ash/projector/screencast_manager_browsertest.cc index d0df3800..2f5431148 100644 --- a/chrome/browser/ui/ash/projector/screencast_manager_browsertest.cc +++ b/chrome/browser/ui/ash/projector/screencast_manager_browsertest.cc
@@ -21,6 +21,7 @@ #include "chrome/browser/ash/system_web_apps/test_support/system_web_app_integration_test.h" #include "chrome/browser/ash/system_web_apps/types/system_web_app_type.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/ash/projector/projector_utils.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/web_applications/test/profile_test_helper.h" @@ -242,7 +243,7 @@ // Tests that the ScreencastManager rejects malformed video files. IN_PROC_BROWSER_TEST_P(ScreencastManagerTestWithDriveFs, - GetMalFormedVideoFail) { + GetMalformedVideoFail) { // Uses a binary file for this test and renames it to `kVideoFileName`. AddTestMediaFileToDefaultFolder("bear-audio-mp4a.69.ts", kVideoFileName, kProjectorMediaMimeType, true); @@ -296,14 +297,9 @@ ASSERT_TRUE(first_browser); EXPECT_EQ(first_browser->tab_strip_model()->GetActiveWebContents(), app); - // Use LaunchAppWithFileWithoutWaiting() instead of LaunchAppWithFile() - // because the second one waits for the app to finish loading, but we don't - // reload the app when we send files. Thus, LaunchAppWithFile() would time out - // and we should use LaunchAppWithFileWithoutWaiting() instead. base::FilePath absolute_path = GetTestFile(kVideoFileName, /*relative=*/false); - app = LaunchAppWithFileWithoutWaiting(SystemWebAppType::PROJECTOR, - absolute_path); + SendFilesToProjectorApp({absolute_path}); Browser* second_browser = chrome::FindBrowserWithActiveWindow(); // Launching the app with files should not open a new window. EXPECT_EQ(first_browser, second_browser); @@ -370,8 +366,7 @@ EXPECT_TRUE(WaitForLoadStop(app)); base::FilePath absolute_path = GetTestFile("NotFoundError.file", /*relative=*/false); - app = LaunchAppWithFileWithoutWaiting(SystemWebAppType::PROJECTOR, - absolute_path); + SendFilesToProjectorApp({absolute_path}); const std::string& script = base::StringPrintf(kGetVideoScript, kVideoFileId); content::EvalJsResult result = @@ -393,8 +388,7 @@ EXPECT_TRUE(WaitForLoadStop(app)); base::FilePath absolute_path = GetTestFile("MyTestScreencast.txt", /*relative=*/false); - app = LaunchAppWithFileWithoutWaiting(SystemWebAppType::PROJECTOR, - absolute_path); + SendFilesToProjectorApp({absolute_path}); AddTestMediaFileToDefaultFolder(kTestVideoFile, kVideoFileName, "text/plain", /*shared_with_me=*/true);
diff --git a/chrome/browser/ui/autofill/chrome_autofill_client.cc b/chrome/browser/ui/autofill/chrome_autofill_client.cc index 30b82dc..4f0902028 100644 --- a/chrome/browser/ui/autofill/chrome_autofill_client.cc +++ b/chrome/browser/ui/autofill/chrome_autofill_client.cc
@@ -695,7 +695,8 @@ return false; return touch_to_fill_credit_card_controller_.Show( - std::make_unique<TouchToFillCreditCardViewImpl>(), delegate); + std::make_unique<TouchToFillCreditCardViewImpl>(web_contents()), + delegate); #else // Touch To Fill is not supported on Desktop. NOTREACHED();
diff --git a/chrome/browser/ui/autofill/chrome_autofill_client.h b/chrome/browser/ui/autofill/chrome_autofill_client.h index e3144f3..88822a8 100644 --- a/chrome/browser/ui/autofill/chrome_autofill_client.h +++ b/chrome/browser/ui/autofill/chrome_autofill_client.h
@@ -29,7 +29,7 @@ #if BUILDFLAG(IS_ANDROID) #include "chrome/browser/autofill/android/save_update_address_profile_flow_manager.h" -#include "chrome/browser/touch_to_fill/payments/touch_to_fill_credit_card_controller.h" +#include "chrome/browser/touch_to_fill/payments/android/touch_to_fill_credit_card_controller.h" #include "chrome/browser/ui/android/autofill/save_card_message_controller_android.h" #include "components/autofill/core/browser/ui/payments/card_expiration_date_fix_flow_controller_impl.h" #include "components/autofill/core/browser/ui/payments/card_name_fix_flow_controller_impl.h"
diff --git a/chrome/browser/ui/views/side_search/side_search_browser_controller_interactive_uitest.cc b/chrome/browser/ui/views/side_search/side_search_browser_controller_interactive_uitest.cc index 46b282f..330b672c3 100644 --- a/chrome/browser/ui/views/side_search/side_search_browser_controller_interactive_uitest.cc +++ b/chrome/browser/ui/views/side_search/side_search_browser_controller_interactive_uitest.cc
@@ -249,8 +249,16 @@ EXPECT_TRUE(GetSidePanelFor(browser())->GetVisible()); } +#if BUILDFLAG(IS_MAC) +// TODO(crbug.com/1348296): Test is flaky on Mac. +#define MAYBE_SidePanelTogglesCorrectlyMultipleTabs \ + DISABLED_SidePanelTogglesCorrectlyMultipleTabs +#else +#define MAYBE_SidePanelTogglesCorrectlyMultipleTabs \ + SidePanelTogglesCorrectlyMultipleTabs +#endif IN_PROC_BROWSER_TEST_P(SideSearchBrowserControllerTest, - SidePanelTogglesCorrectlyMultipleTabs) { + MAYBE_SidePanelTogglesCorrectlyMultipleTabs) { // Navigate to a matching search URL followed by a non-matching URL in two // independent browser tabs such that both have the side panel ready. The // side panel should respect the state-per-tab flag.
diff --git a/chrome/browser/ui/views/side_search/unified_side_search_controller_interactive_uitest.cc b/chrome/browser/ui/views/side_search/unified_side_search_controller_interactive_uitest.cc index 4799e80..435e8a3f 100644 --- a/chrome/browser/ui/views/side_search/unified_side_search_controller_interactive_uitest.cc +++ b/chrome/browser/ui/views/side_search/unified_side_search_controller_interactive_uitest.cc
@@ -177,8 +177,16 @@ EXPECT_TRUE(GetSidePanelFor(browser())->GetVisible()); } +#if BUILDFLAG(IS_MAC) +// TODO(crbug.com/1348296): Test is flaky on Mac. +#define MAYBE_SidePanelTogglesCorrectlyMultipleTabs \ + DISABLED_SidePanelTogglesCorrectlyMultipleTabs +#else +#define MAYBE_SidePanelTogglesCorrectlyMultipleTabs \ + SidePanelTogglesCorrectlyMultipleTabs +#endif IN_PROC_BROWSER_TEST_F(SideSearchV2Test, - SidePanelTogglesCorrectlyMultipleTabs) { + MAYBE_SidePanelTogglesCorrectlyMultipleTabs) { // Navigate to a matching search URL followed by a non-matching URL in two // independent browser tabs such that both have the side panel ready. The // side panel should respect the state-per-tab flag.
diff --git a/chrome/browser/ui/web_applications/BUILD.gn b/chrome/browser/ui/web_applications/BUILD.gn index 5d2724f..446d443 100644 --- a/chrome/browser/ui/web_applications/BUILD.gn +++ b/chrome/browser/ui/web_applications/BUILD.gn
@@ -42,14 +42,10 @@ "web_app_engagement_browsertest.cc", "web_app_file_handling_browsertest.cc", "web_app_launch_handler_browsertest.cc", - "web_app_link_capturing_browsertest.cc", "web_app_metrics_browsertest.cc", "web_app_navigate_browsertest.cc", - "web_app_protocol_handling_browsertest.cc", "web_app_ui_manager_impl_browsertest.cc", "web_app_uninstall_browsertest.cc", - "web_app_url_handling_browsertest.cc", - "web_app_window_controls_overlay_browsertest.cc", ] if (!is_chromeos_lacros) { @@ -97,7 +93,13 @@ source_set("app_service_browser_tests") { testonly = true - sources = [ "launch_web_app_browsertest.cc" ] + sources = [ + "launch_web_app_browsertest.cc", + "web_app_link_capturing_browsertest.cc", + "web_app_protocol_handling_browsertest.cc", + "web_app_url_handling_browsertest.cc", + "web_app_window_controls_overlay_browsertest.cc", + ] if (is_chromeos) { sources += [ @@ -118,7 +120,10 @@ "//chrome/browser/web_applications:web_applications_test_support", "//chrome/test:test_support", "//chrome/test:test_support_ui", + "//components/embedder_support", + "//components/page_load_metrics/browser:test_support", "//components/services/app_service/public/cpp:intents", + "//components/services/app_service/public/cpp:protocol_handling", ] if (is_chromeos_lacros) {
diff --git a/chrome/browser/ui/web_applications/test/web_app_navigation_browsertest.cc b/chrome/browser/ui/web_applications/test/web_app_navigation_browsertest.cc index a0b20d77..ec3e5c0 100644 --- a/chrome/browser/ui/web_applications/test/web_app_navigation_browsertest.cc +++ b/chrome/browser/ui/web_applications/test/web_app_navigation_browsertest.cc
@@ -6,14 +6,17 @@ #include "base/bind.h" #include "base/callback.h" +#include "base/logging.h" #include "base/strings/escape.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" +#include "build/chromeos_buildflags.h" #include "chrome/browser/profiles/profile_io_data.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/ui/web_applications/test/web_app_browsertest_util.h" +#include "chrome/browser/web_applications/test/app_registration_waiter.h" #include "chrome/browser/web_applications/test/web_app_install_test_utils.h" #include "chrome/browser/web_applications/user_display_mode.h" #include "chrome/browser/web_applications/web_app_install_info.h" @@ -29,6 +32,11 @@ #include "third_party/blink/public/common/features.h" #include "third_party/blink/public/common/switches.h" +#if BUILDFLAG(IS_CHROMEOS_LACROS) +#include "chromeos/crosapi/mojom/web_app_service.mojom.h" +#include "chromeos/lacros/lacros_service.h" +#endif + namespace { const char kLaunchingPageHost[] = "launching-page.com"; @@ -109,6 +117,18 @@ return observer; } +bool WebAppNavigationBrowserTest::IsServiceAvailable() const { +#if BUILDFLAG(IS_CHROMEOS_LACROS) + chromeos::LacrosService* lacros_service = chromeos::LacrosService::Get(); + if (!lacros_service || + !lacros_service->IsAvailable<crosapi::mojom::WebAppService>()) { + LOG(WARNING) << "Unsupported ash version."; + return false; + } +#endif + return true; +} + // static void WebAppNavigationBrowserTest::ClickLinkWithModifiersAndWaitForURL( content::WebContents* web_contents, @@ -243,7 +263,10 @@ web_app_info->description = u"Test description"; web_app_info->user_display_mode = web_app::UserDisplayMode::kStandalone; - return test::InstallWebApp(profile(), std::move(web_app_info)); + AppId app_id = test::InstallWebApp(profile(), std::move(web_app_info)); + DCHECK(!app_id.empty()); + AppRegistrationWaiter(profile(), app_id).Await(); + return app_id; } Browser* WebAppNavigationBrowserTest::OpenTestWebApp() {
diff --git a/chrome/browser/ui/web_applications/test/web_app_navigation_browsertest.h b/chrome/browser/ui/web_applications/test/web_app_navigation_browsertest.h index 00b9656..c440bc6 100644 --- a/chrome/browser/ui/web_applications/test/web_app_navigation_browsertest.h +++ b/chrome/browser/ui/web_applications/test/web_app_navigation_browsertest.h
@@ -50,6 +50,9 @@ GetTestNavigationObserver(const GURL& target_url); protected: + // On Lacros, we require a sufficiently recent Ash version. + bool IsServiceAvailable() const; + // Creates an <a> element, sets its href and target to |link_url| and |target| // respectively, adds it to the DOM, and clicks on it with |modifiers|. // Returns once |target_url| has loaded. |modifiers| should be based on
diff --git a/chrome/browser/ui/web_applications/web_app_link_capturing_browsertest.cc b/chrome/browser/ui/web_applications/web_app_link_capturing_browsertest.cc index b746da5..e63fd2e7 100644 --- a/chrome/browser/ui/web_applications/web_app_link_capturing_browsertest.cc +++ b/chrome/browser/ui/web_applications/web_app_link_capturing_browsertest.cc
@@ -188,6 +188,9 @@ // app windows. IN_PROC_BROWSER_TEST_F(WebAppLinkCapturingBrowserTest, NavigateExistingClientFromBrowser) { + if (!IsServiceAvailable()) + GTEST_SKIP(); + InstallTestApp( "/web_apps/get_manifest.html?" "launch_handler_client_mode_navigate_existing.json"); @@ -220,6 +223,9 @@ // Link captures from about:blank cleans up the about:blank page. IN_PROC_BROWSER_TEST_F(WebAppLinkCapturingBrowserTest, AboutBlankNavigationCleanUp) { + if (!IsServiceAvailable()) + GTEST_SKIP(); + InstallTestApp("/web_apps/basic.html"); TurnOnLinkCapturing(); @@ -241,6 +247,9 @@ // page. IN_PROC_BROWSER_TEST_F(WebAppLinkCapturingBrowserTest, JavascriptAboutBlankNavigationCleanUp) { + if (!IsServiceAvailable()) + GTEST_SKIP(); + InstallTestApp("/web_apps/basic.html"); TurnOnLinkCapturing(); @@ -285,6 +294,9 @@ // the app window. IN_PROC_BROWSER_TEST_F(WebAppTabStripLinkCapturingBrowserTest, InScopeNavigationsCaptured) { + if (!IsServiceAvailable()) + GTEST_SKIP(); + InstallTestTabbedApp(); TurnOnLinkCapturing();
diff --git a/chrome/browser/ui/web_applications/web_app_protocol_handling_browsertest.cc b/chrome/browser/ui/web_applications/web_app_protocol_handling_browsertest.cc index f8b95d4..18eda5f 100644 --- a/chrome/browser/ui/web_applications/web_app_protocol_handling_browsertest.cc +++ b/chrome/browser/ui/web_applications/web_app_protocol_handling_browsertest.cc
@@ -75,6 +75,9 @@ IN_PROC_BROWSER_TEST_F(WebAppProtocolHandlingBrowserTest, BasicProtocolHandlers) { + if (!IsServiceAvailable()) + GTEST_SKIP(); + AppId app_id = InstallTestApp( "/banners/" "manifest_test_page.html?manifest=manifest_protocol_handlers.json", @@ -102,6 +105,9 @@ } IN_PROC_BROWSER_TEST_F(WebAppProtocolHandlingBrowserTest, NoProtocolHandlers) { + if (!IsServiceAvailable()) + GTEST_SKIP(); + AppId app_id = InstallTestApp("/banners/manifest_test_page.html?manifest=manifest.json", /*await_metric=*/false);
diff --git a/chrome/browser/ui/web_applications/web_app_url_handling_browsertest.cc b/chrome/browser/ui/web_applications/web_app_url_handling_browsertest.cc index b34a529..6ccb030 100644 --- a/chrome/browser/ui/web_applications/web_app_url_handling_browsertest.cc +++ b/chrome/browser/ui/web_applications/web_app_url_handling_browsertest.cc
@@ -68,6 +68,9 @@ }; IN_PROC_BROWSER_TEST_F(WebAppUrlHandlingBrowserTest, BasicUrlHandlers) { + if (!IsServiceAvailable()) + GTEST_SKIP(); + AppId app_id = InstallTestApp( "/banners/" "manifest_test_page.html?manifest=manifest_url_handlers.json", @@ -95,6 +98,9 @@ } IN_PROC_BROWSER_TEST_F(WebAppUrlHandlingBrowserTest, NoUrlHandlers) { + if (!IsServiceAvailable()) + GTEST_SKIP(); + AppId app_id = InstallTestApp("/banners/manifest_test_page.html?manifest=manifest.json", /*await_metric=*/false);
diff --git a/chrome/browser/ui/web_applications/web_app_window_controls_overlay_browsertest.cc b/chrome/browser/ui/web_applications/web_app_window_controls_overlay_browsertest.cc index b9e8a56..1fdf17f5e 100644 --- a/chrome/browser/ui/web_applications/web_app_window_controls_overlay_browsertest.cc +++ b/chrome/browser/ui/web_applications/web_app_window_controls_overlay_browsertest.cc
@@ -69,6 +69,9 @@ IN_PROC_BROWSER_TEST_F(WebAppWindowControlsOverlayBrowserTest, BasicDisplayOverride) { + if (!IsServiceAvailable()) + GTEST_SKIP(); + AppId app_id = InstallTestApp( "/banners/" "manifest_test_page.html?manifest=manifest_window_controls_overlay.json", @@ -85,6 +88,9 @@ IN_PROC_BROWSER_TEST_F(WebAppWindowControlsOverlayBrowserTest, NoDisplayOverride) { + if (!IsServiceAvailable()) + GTEST_SKIP(); + AppId app_id = InstallTestApp("/banners/manifest_test_page.html?manifest=manifest.json", /*await_metric=*/false);
diff --git a/chrome/browser/ui/webui/chrome_untrusted_web_ui_configs_chromeos.cc b/chrome/browser/ui/webui/chrome_untrusted_web_ui_configs_chromeos.cc index 19cfa87..a1e528ab 100644 --- a/chrome/browser/ui/webui/chrome_untrusted_web_ui_configs_chromeos.cc +++ b/chrome/browser/ui/webui/chrome_untrusted_web_ui_configs_chromeos.cc
@@ -10,6 +10,7 @@ #if BUILDFLAG(IS_CHROMEOS_ASH) #include "ash/constants/ash_features.h" #include "ash/webui/eche_app_ui/untrusted_eche_app_ui.h" +#include "ash/webui/face_ml_app_ui/face_ml_app_untrusted_ui.h" #include "ash/webui/file_manager/file_manager_untrusted_ui.h" #include "ash/webui/help_app_ui/help_app_kids_magazine_untrusted_ui.h" #include "ash/webui/os_feedback_ui/os_feedback_untrusted_ui.h" @@ -57,6 +58,10 @@ map.AddUntrustedWebUIConfig( std::make_unique<ash::feedback::OsFeedbackUntrustedUIConfig>()); } + if (base::FeatureList::IsEnabled(ash::features::kFaceMLApp)) { + map.AddUntrustedWebUIConfig( + std::make_unique<ash::FaceMLAppUntrustedUIConfig>()); + } #if !defined(OFFICIAL_BUILD) map.AddUntrustedWebUIConfig( std::make_unique<ash::SampleSystemWebAppUntrustedUIConfig>());
diff --git a/chrome/browser/ui/webui/history_clusters/history_clusters_handler.cc b/chrome/browser/ui/webui/history_clusters/history_clusters_handler.cc index a208df0..0446ae98 100644 --- a/chrome/browser/ui/webui/history_clusters/history_clusters_handler.cc +++ b/chrome/browser/ui/webui/history_clusters/history_clusters_handler.cc
@@ -209,6 +209,24 @@ return search_query_mojom; } +void ShowSurveyAndLogMetrics(HatsService* service, + content::WebContents* contents, + const std::string& trigger, + base::TimeDelta delay) { + DCHECK(service); + DCHECK(contents); + + base::UmaHistogramBoolean("History.Clusters.Survey.CanShowAnySurvey", + service->CanShowAnySurvey(/*user_prompted=*/false)); + base::UmaHistogramBoolean("History.Clusters.Survey.CanShowSurvey", + service->CanShowSurvey(trigger)); + + bool success = service->LaunchDelayedSurveyForWebContents( + kHatsSurveyTriggerJourneysHistoryEntrypoint, contents, + delay.InMilliseconds()); + base::UmaHistogramBoolean("History.Clusters.Survey.Success", success); +} + } // namespace // Creates a `mojom::QueryResultPtr` using the original `query`, if the query @@ -506,21 +524,33 @@ return; } + constexpr char kHistoryClustersSurveyRequestedUmaName[] = + "History.Clusters.Survey.Requested"; + // These values must match enums.xml, and should not be modified. + enum HistoryClustersSurvey { + kHistoryEntrypoint = 0, + kOmniboxEntrypoint = 1, + kMaxValue = kOmniboxEntrypoint, + }; if (*initial_state == history_clusters::HistoryClustersInitialState::kSameDocument && base::FeatureList::IsEnabled(kJourneysSurveyForHistoryEntrypoint)) { // Same document navigation basically means clicking over from History. - hats_service->LaunchDelayedSurveyForWebContents( - kHatsSurveyTriggerJourneysHistoryEntrypoint, web_contents_, - kJourneysSurveyForHistoryEntrypointDelay.Get().InMilliseconds()); + ShowSurveyAndLogMetrics(hats_service, web_contents_, + kHatsSurveyTriggerJourneysHistoryEntrypoint, + kJourneysSurveyForHistoryEntrypointDelay.Get()); + base::UmaHistogramEnumeration(kHistoryClustersSurveyRequestedUmaName, + kHistoryEntrypoint); } else if (*initial_state == history_clusters::HistoryClustersInitialState:: kIndirectNavigation && base::FeatureList::IsEnabled( kJourneysSurveyForOmniboxEntrypoint)) { // Indirect navigation basically means from the omnibox. - hats_service->LaunchDelayedSurveyForWebContents( - kHatsSurveyTriggerJourneysOmniboxEntrypoint, web_contents_, - kJourneysSurveyForOmniboxEntrypointDelay.Get().InMilliseconds()); + ShowSurveyAndLogMetrics(hats_service, web_contents_, + kHatsSurveyTriggerJourneysOmniboxEntrypoint, + kJourneysSurveyForOmniboxEntrypointDelay.Get()); + base::UmaHistogramEnumeration(kHistoryClustersSurveyRequestedUmaName, + kOmniboxEntrypoint); } }
diff --git a/chrome/browser/ui/webui/print_preview/local_printer_handler_chromeos_unittest.cc b/chrome/browser/ui/webui/print_preview/local_printer_handler_chromeos_unittest.cc index e9619b6..afdd2ae 100644 --- a/chrome/browser/ui/webui/print_preview/local_printer_handler_chromeos_unittest.cc +++ b/chrome/browser/ui/webui/print_preview/local_printer_handler_chromeos_unittest.cc
@@ -82,10 +82,10 @@ PrinterStatusRequestNoAsh_ProvidesDefaultValue) { absl::optional<base::Value::Dict> printer_status = base::Value::Dict(); local_printer_handler()->StartPrinterStatusRequest( - "printer1", base::BindOnce(base::BindLambdaForTesting( - [&](absl::optional<base::Value::Dict> status) { - printer_status = std::move(status); - }))); + "printer1", + base::BindLambdaForTesting([&](absl::optional<base::Value::Dict> status) { + printer_status = std::move(status); + })); EXPECT_EQ(absl::nullopt, printer_status); } @@ -108,9 +108,8 @@ TEST_F(LocalPrinterHandlerChromeosTest, GetDefaultPrinterNoAsh_ProvidesDefaultValue) { std::string default_printer = "unset"; - local_printer_handler()->GetDefaultPrinter( - base::BindOnce(base::BindLambdaForTesting( - [&](const std::string& printer) { default_printer = printer; }))); + local_printer_handler()->GetDefaultPrinter(base::BindLambdaForTesting( + [&](const std::string& printer) { default_printer = printer; })); EXPECT_EQ("", default_printer); }
diff --git a/chrome/browser/ui/webui/settings/chromeos/apps_section.cc b/chrome/browser/ui/webui/settings/chromeos/apps_section.cc index 7eeea95..d0e0de9e 100644 --- a/chrome/browser/ui/webui/settings/chromeos/apps_section.cc +++ b/chrome/browser/ui/webui/settings/chromeos/apps_section.cc
@@ -292,6 +292,12 @@ IDS_SETTINGS_GUEST_OS_SHARED_USB_DEVICES_IN_USE}, {"guestOsSharedUsbDevicesReassign", IDS_SETTINGS_GUEST_OS_SHARED_USB_DEVICES_REASSIGN}, + {"guestOsSharedUsbDevicesTableTitle", + IDS_SETTINGS_GUEST_OS_SHARED_USB_DEVICES_TABLE_TITLE}, + {"guestOsSharedUsbDevicesAddTitle", + IDS_SETTINGS_GUEST_OS_SHARED_USB_DEVICES_ADD_TITLE}, + {"guestOsSharedUsbDevicesNoneAttached", + IDS_SETTINGS_GUEST_OS_SHARED_USB_DEVICES_NONE_ATTACHED}, }; html_source->AddLocalizedStrings(kLocalizedStrings); }
diff --git a/chrome/browser/ui/webui/settings/chromeos/guest_os_handler.cc b/chrome/browser/ui/webui/settings/chromeos/guest_os_handler.cc index 966b43d..9be64f27 100644 --- a/chrome/browser/ui/webui/settings/chromeos/guest_os_handler.cc +++ b/chrome/browser/ui/webui/settings/chromeos/guest_os_handler.cc
@@ -10,6 +10,7 @@ #include "base/bind.h" #include "base/callback_helpers.h" +#include "base/strings/stringprintf.h" #include "chrome/browser/ash/file_manager/path_util.h" #include "chrome/browser/ash/guest_os/guest_os_share_path.h" #include "chrome/browser/profiles/profile.h" @@ -25,8 +26,14 @@ base::Value::Dict device_info; device_info.Set("guid", device.guid); device_info.Set("label", device.label); - if (device.shared_guest_id.has_value()) - device_info.Set("sharedWith", device.shared_guest_id->vm_name); + if (device.shared_guest_id.has_value()) { + base::Value::Dict guest_id; + guest_id.Set("vm_name", device.shared_guest_id->vm_name); + guest_id.Set("container_name", device.shared_guest_id->container_name); + device_info.Set("guestId", std::move(guest_id)); + } + device_info.Set("vendorId", base::StringPrintf("%04x", device.vendor_id)); + device_info.Set("productId", base::StringPrintf("%04x", device.product_id)); device_info.Set("promptBeforeSharing", device.prompt_before_sharing); usb_devices_list.Append(std::move(device_info)); } @@ -119,16 +126,16 @@ void GuestOsHandler::HandleSetGuestOsUsbDeviceShared( const base::Value::List& args) { - CHECK_EQ(3U, args.size()); - const std::string& guid = args[1].GetString(); - bool shared = args[2].GetBool(); - - const auto guest_id = guest_os::GuestId(args[0].GetString(), ""); - + CHECK_EQ(4U, args.size()); chromeos::CrosUsbDetector* detector = chromeos::CrosUsbDetector::Get(); if (!detector) return; + const auto guest_id = + guest_os::GuestId(args[0].GetString(), args[1].GetString()); + const std::string& guid = args[2].GetString(); + bool shared = args[3].GetBool(); + if (shared) { detector->AttachUsbDeviceToGuest(guest_id, guid, base::DoNothing()); return;
diff --git a/chrome/browser/web_applications/test/fake_web_app_database_factory.cc b/chrome/browser/web_applications/test/fake_web_app_database_factory.cc index 05f5a07..28bfa505 100644 --- a/chrome/browser/web_applications/test/fake_web_app_database_factory.cc +++ b/chrome/browser/web_applications/test/fake_web_app_database_factory.cc
@@ -78,11 +78,11 @@ store_->CommitWriteBatch( std::move(write_batch), - base::BindOnce(base::BindLambdaForTesting( + base::BindLambdaForTesting( [&](const absl::optional<syncer::ModelError>& error) { DCHECK(!error); run_loop.Quit(); - }))); + })); run_loop.Run(); }
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt index 5bb6bb38..a3a3d43 100644 --- a/chrome/build/linux.pgo.txt +++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@ -chrome-linux-main-1661363899-7be88a19f15311eae255111f78cd73ad49a33e82.profdata +chrome-linux-main-1661384205-142099a268b36c6d5c4493880c31475b5b649143.profdata
diff --git a/chrome/build/mac-arm.pgo.txt b/chrome/build/mac-arm.pgo.txt index 7cd44fe..269aa45 100644 --- a/chrome/build/mac-arm.pgo.txt +++ b/chrome/build/mac-arm.pgo.txt
@@ -1 +1 @@ -chrome-mac-arm-main-1661342370-ea994796c189ec55dcb31bdf43b565d83f179210.profdata +chrome-mac-arm-main-1661384205-ea5cc04a4683d879d179c1c40d9deb92556c7135.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt index dfa4281..e513c62 100644 --- a/chrome/build/mac.pgo.txt +++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@ -chrome-mac-main-1661342370-105146dc736e5aeaaea6ea52eaf6167cd2683600.profdata +chrome-mac-main-1661384205-24ab0d1fad67efe658b33303579c02ffcfbd4023.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt index 15d091b..ed97069 100644 --- a/chrome/build/win32.pgo.txt +++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@ -chrome-win32-main-1661353049-6c6fd8092fd57e40789b60be1617a939f0d530af.profdata +chrome-win32-main-1661384205-8deb92ce7f68f70b30dfc970fe22ad5e4ba40459.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt index 8267a42..01bbb82 100644 --- a/chrome/build/win64.pgo.txt +++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@ -chrome-win64-main-1661353049-0c3c892c1a41cc98d97248b00417193b1a32b27f.profdata +chrome-win64-main-1661396378-853a8456258e1a4f7a21b3fe47ba032cc41c0919.profdata
diff --git a/chrome/chrome_paks.gni b/chrome/chrome_paks.gni index 1e0bae8..2e90c09 100644 --- a/chrome/chrome_paks.gni +++ b/chrome/chrome_paks.gni
@@ -223,7 +223,9 @@ "$root_gen_dir/ash/webui/ash_diagnostics_app_resources.pak", "$root_gen_dir/ash/webui/ash_eche_app_resources.pak", "$root_gen_dir/ash/webui/ash_eche_bundle_resources.pak", + "$root_gen_dir/ash/webui/ash_face_ml_app_bundle_resources.pak", "$root_gen_dir/ash/webui/ash_face_ml_app_resources.pak", + "$root_gen_dir/ash/webui/ash_face_ml_app_untrusted_resources.pak", "$root_gen_dir/ash/webui/ash_firmware_update_app_resources.pak", "$root_gen_dir/ash/webui/ash_guest_os_installer_resources.pak", "$root_gen_dir/ash/webui/ash_help_app_resources.pak", @@ -284,7 +286,10 @@ "//ash/webui/resources:diagnostics_app_resources", "//ash/webui/resources:eche_app_resources", "//ash/webui/resources:eche_bundle_resources", + "//ash/webui/resources:face_ml_app_bundle_resources", "//ash/webui/resources:face_ml_app_resources", + "//ash/webui/resources:face_ml_app_resources", + "//ash/webui/resources:face_ml_app_untrusted_resources", "//ash/webui/resources:firmware_update_app_resources", "//ash/webui/resources:guest_os_installer_resources", "//ash/webui/resources:help_app_bundle_resources",
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 3d327ee..c216606a 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -3854,6 +3854,7 @@ "../browser/ash/policy/reporting/metrics_reporting/metric_browsertest_utils.cc", "../browser/ash/policy/reporting/metrics_reporting/metric_browsertest_utils.h", "../browser/ash/policy/reporting/metrics_reporting/network/network_info_sampler_browsertest.cc", + "../browser/ash/policy/reporting/metrics_reporting/network/network_events_observer_browsertest.cc", "../browser/ash/policy/reporting/metrics_reporting/usb/usb_events_browsertest.cc", "../browser/ash/policy/reporting/user_added_removed/user_added_removed_reporter_browsertest.cc", "../browser/ash/policy/status_collector/child_status_collector_browsertest.cc", @@ -4791,6 +4792,7 @@ } data = [ + "data/banners/", "data/extensions/", "data/media/", "data/policy/test_certs/", @@ -7232,6 +7234,7 @@ "../browser/ui/app_list/search/mixer_unittest.cc", "../browser/ui/app_list/search/omnibox_answer_result_unittest.cc", "../browser/ui/app_list/search/omnibox_lacros_provider_unittest.cc", + "../browser/ui/app_list/search/omnibox_provider_unittest.cc", "../browser/ui/app_list/search/omnibox_result_unittest.cc", "../browser/ui/app_list/search/open_tab_result_unittest.cc", "../browser/ui/app_list/search/ranking/answer_ranker_unittest.cc", @@ -7240,6 +7243,7 @@ "../browser/ui/app_list/search/ranking/ftrl_ranker_unittest.cc", "../browser/ui/app_list/search/ranking/mrfu_ranker_unittest.cc", "../browser/ui/app_list/search/ranking/query_highlighter_unittest.cc", + "../browser/ui/app_list/search/ranking/ranking_item_util_unittest.cc", "../browser/ui/app_list/search/ranking/removed_results_ranker_unittest.cc", "../browser/ui/app_list/search/ranking/score_normalizing_ranker_unittest.cc", "../browser/ui/app_list/search/search_controller_impl_new_unittest.cc", @@ -7250,7 +7254,6 @@ "../browser/ui/app_list/search/search_result_ranker/app_search_result_ranker_unittest.cc", "../browser/ui/app_list/search/search_result_ranker/chip_ranker_unittest.cc", "../browser/ui/app_list/search/search_result_ranker/frecency_store_unittest.cc", - "../browser/ui/app_list/search/search_result_ranker/ranking_item_util_unittest.cc", "../browser/ui/app_list/search/search_result_ranker/recurrence_predictor_unittest.cc", "../browser/ui/app_list/search/search_result_ranker/recurrence_ranker_unittest.cc", "../browser/ui/app_list/search/search_result_ranker/recurrence_ranker_util_unittest.cc", @@ -9071,6 +9074,7 @@ if (is_chromeos_lacros) { deps += [ + "//chromeos/lacros", "//components/account_manager_core", "//components/account_manager_core:test_support", ]
diff --git a/chrome/test/data/webui/chromeos/os_feedback_ui/share_data_page_test.js b/chrome/test/data/webui/chromeos/os_feedback_ui/share_data_page_test.js index 5c6f3d3..0806376 100644 --- a/chrome/test/data/webui/chromeos/os_feedback_ui/share_data_page_test.js +++ b/chrome/test/data/webui/chromeos/os_feedback_ui/share_data_page_test.js
@@ -5,7 +5,7 @@ import 'chrome://resources/mojo/mojo/public/mojom/base/big_buffer.mojom-lite.js'; import 'chrome://resources/mojo/mojo/public/mojom/base/string16.mojom-lite.js'; -import {fakeEmptyFeedbackContext, fakeFeedbackContext} from 'chrome://os-feedback/fake_data.js'; +import {fakeEmptyFeedbackContext, fakeFeedbackContext, fakeInternalUserFeedbackContext} from 'chrome://os-feedback/fake_data.js'; import {FakeFeedbackServiceProvider} from 'chrome://os-feedback/fake_feedback_service_provider.js'; import {FeedbackFlowState} from 'chrome://os-feedback/feedback_flow.js'; import {FeedbackAppPreSubmitAction, FeedbackContext} from 'chrome://os-feedback/feedback_types.js'; @@ -646,12 +646,44 @@ }); /** + * Test that when not logged as internal google account, the bluetooth + * checkbox container is hidden, and sendBluetoothLogs flag is set false. + */ + test('bluetoothCheckboxHiddenWithoutInternalAccount', async () => { + await initializePage(); + page.feedbackContext = fakeFeedbackContext; + + await flushTasks(); + // Verify the bluetooth checkbox is hidden. + assertFalse(isVisible(getElement('#bluetoothCheckboxContainer'))); + + // Check the bluetooth checkbox. + const bluetoothCheckbox = getElement('#bluetoothLogsCheckbox'); + assertTrue(!!bluetoothCheckbox); + bluetoothCheckbox.checked = true; + + // Send report with the checkbox checked somehow, but without an internal + // account. The report should not have sendBluetoothLogs flag. + const request = (await clickSendAndWait(page)).report; + + assertFalse(request.sendBluetoothLogs); + assertFalse(!!request.feedbackContext.categoryTag); + }); + + /** * Test that sendBluetoothLogs flag is true and categoryTag is marked as * 'BluetoothReportWithLogs' when bluetooth logs checkbox is checked. */ test('sendReportWithBluetoothLogsFlagChecked', async () => { await initializePage(); - page.feedbackContext = fakeFeedbackContext; + page.feedbackContext = fakeInternalUserFeedbackContext; + await flushTasks(); + + // Fake internal google account is used for login. The bluetooth logs + // checkbox container should be visible. + assertEquals( + getElement('#userEmailDropDown').value, 'test.user@google.com'); + assertTrue(isVisible(getElement('#bluetoothCheckboxContainer'))); const bluetoothLogsCheckbox = getElement('#bluetoothLogsCheckbox'); @@ -659,7 +691,7 @@ assertTrue(!!bluetoothLogsCheckbox); assertTrue(bluetoothLogsCheckbox.checked); - // Report should have sendBluetoothLogs flag true,and category marked as + // Report should have sendBluetoothLogs flag true, and category marked as // "BluetoothReportWithLogs". const requestWithBluetoothFlag = (await clickSendAndWait(page)).report; @@ -676,11 +708,17 @@ */ test('sendReportWithoutBluetoothLogsFlagChecked', async () => { await initializePage(); - page.feedbackContext = fakeFeedbackContext; + page.feedbackContext = fakeInternalUserFeedbackContext; + await flushTasks(); - const bluetoothLogsCheckbox = getElement('#bluetoothLogsCheckbox'); + // Fake internal google account is used for login. The bluetooth logs + // checkbox container should be visible. + assertEquals( + getElement('#userEmailDropDown').value, 'test.user@google.com'); + assertTrue(isVisible(getElement('#bluetoothCheckboxContainer'))); // BluetoothLogs checkbox is default to be checked. + const bluetoothLogsCheckbox = getElement('#bluetoothLogsCheckbox'); assertTrue(!!bluetoothLogsCheckbox); assertTrue(bluetoothLogsCheckbox.checked); @@ -690,7 +728,7 @@ await flushTasks(); // Report should not have sendBluetoothLogs flag, - // and category marked as "BluetoothReportWithLogs". + // and category should not be marked as "BluetoothReportWithLogs". const requestWithoutBluetoothFlag = (await clickSendAndWait(page)).report; assertFalse(requestWithoutBluetoothFlag.sendBluetoothLogs);
diff --git a/chrome/test/data/webui/chromeos/personalization_app/google_photos_albums_element_test.ts b/chrome/test/data/webui/chromeos/personalization_app/google_photos_albums_element_test.ts index 6d46b5db..c887958 100644 --- a/chrome/test/data/webui/chromeos/personalization_app/google_photos_albums_element_test.ts +++ b/chrome/test/data/webui/chromeos/personalization_app/google_photos_albums_element_test.ts
@@ -6,7 +6,7 @@ import 'chrome://webui-test/mojo_webui_test_support.js'; import {fetchGooglePhotosAlbums, getCountText, GooglePhotosAlbum, GooglePhotosAlbums, initializeGooglePhotosData, PersonalizationActionName, PersonalizationRouter, SetErrorAction, WallpaperGridItem} from 'chrome://personalization/js/personalization_app.js'; -import {assertEquals, assertNotEquals} from 'chrome://webui-test/chai_assert.js'; +import {assertDeepEquals, assertEquals, assertNotEquals} from 'chrome://webui-test/chai_assert.js'; import {TestBrowserProxy} from 'chrome://webui-test/test_browser_proxy.js'; import {waitAfterNextRender} from 'chrome://webui-test/test_util.js'; @@ -95,7 +95,7 @@ const albumEls = querySelectorAll(albumSelector) as WallpaperGridItem[]; assertEquals(albumEls.length, albums.length); albumEls.forEach((albumEl, i) => { - assertEquals(albumEl.imageSrc, albums[i]!.preview.url); + assertDeepEquals(albumEl.src, albums[i]!.preview); assertEquals(albumEl.primaryText, albums[i]!.title); assertEquals(albumEl.secondaryText, getCountText(albums[i]!.photoCount)); });
diff --git a/chrome/test/data/webui/chromeos/personalization_app/google_photos_photos_by_album_id_element_test.ts b/chrome/test/data/webui/chromeos/personalization_app/google_photos_photos_by_album_id_element_test.ts index 563e29b..33ad0d0 100644 --- a/chrome/test/data/webui/chromeos/personalization_app/google_photos_photos_by_album_id_element_test.ts +++ b/chrome/test/data/webui/chromeos/personalization_app/google_photos_photos_by_album_id_element_test.ts
@@ -232,7 +232,7 @@ const photosEls = querySelectorAll(photoSelector) as WallpaperGridItem[]; assertEquals(photosEls.length, photosByAlbumId[album.id]?.length); photosEls.forEach((photoEl, i) => { - assertEquals(photoEl.imageSrc, photosByAlbumId[album.id]![i]!.url.url); + assertEquals(photoEl.src, photosByAlbumId[album.id]![i]!.url); }); // Select the other album id for which data is already loaded. Photos should @@ -690,7 +690,7 @@ const photoSelector = 'wallpaper-grid-item:not([hidden]).photo'; const photoEls = querySelectorAll(photoSelector) as WallpaperGridItem[]; assertEquals(photoEls.length, 1); - assertEquals(photoEls[0]!.imageSrc, photo.url.url); + assertEquals(photoEls[0]!.src, photo.url); assertEquals(photoEls[0]!.primaryText, undefined); assertEquals(photoEls[0]!.secondaryText, undefined);
diff --git a/chrome/test/data/webui/chromeos/personalization_app/google_photos_photos_element_test.ts b/chrome/test/data/webui/chromeos/personalization_app/google_photos_photos_element_test.ts index 1c5ee51f..daaaad0 100644 --- a/chrome/test/data/webui/chromeos/personalization_app/google_photos_photos_element_test.ts +++ b/chrome/test/data/webui/chromeos/personalization_app/google_photos_photos_element_test.ts
@@ -408,7 +408,7 @@ WallpaperGridItem | null; assertNotEquals(photoEl, null); - assertEquals(photoEl!.imageSrc, photo.url.url); + assertDeepEquals(photoEl!.src, photo.url); assertEquals(photoEl!.primaryText, undefined); assertEquals(photoEl!.secondaryText, undefined); }); @@ -814,7 +814,7 @@ const photoSelector = 'wallpaper-grid-item:not([hidden]).photo'; const photoEls = querySelectorAll(photoSelector) as WallpaperGridItem[]; assertEquals(photoEls.length, 1); - assertEquals(photoEls[0]!.imageSrc, photo.url.url); + assertDeepEquals(photoEls[0]!.src, photo.url); assertEquals(photoEls[0]!.primaryText, undefined); assertEquals(photoEls[0]!.secondaryText, undefined);
diff --git a/chrome/test/data/webui/chromeos/personalization_app/wallpaper_grid_item_element_test.ts b/chrome/test/data/webui/chromeos/personalization_app/wallpaper_grid_item_element_test.ts index f267241..49d06fc6 100644 --- a/chrome/test/data/webui/chromeos/personalization_app/wallpaper_grid_item_element_test.ts +++ b/chrome/test/data/webui/chromeos/personalization_app/wallpaper_grid_item_element_test.ts
@@ -6,6 +6,7 @@ import 'chrome://webui-test/mojo_webui_test_support.js'; import {WallpaperGridItem} from 'chrome://personalization/js/personalization_app.js'; +import {Url} from 'chrome://resources/mojo/url/mojom/url.mojom-webui.js'; import {assertEquals, assertNotEquals} from 'chrome://webui-test/chai_assert.js'; import {waitAfterNextRender} from 'chrome://webui-test/test_util.js'; @@ -45,27 +46,29 @@ }); test('displays image', async () => { - let imageSrc = 'data:image/svg+xml;utf8,' + - '<svg xmlns="http://www.w3.org/2000/svg" height="100px" width="100px">' + - '<rect fill="red" height="100px" width="100px"></rect>' + - '</svg>'; + const src: Url = { + url: 'data:image/svg+xml;utf8,' + + '<svg xmlns="http://www.w3.org/2000/svg" height="100px" width="100px">' + + '<rect fill="red" height="100px" width="100px"></rect>' + + '</svg>', + }; // Initialize |wallpaperGridItemElement|. - wallpaperGridItemElement = initElement(WallpaperGridItem, {imageSrc}); + wallpaperGridItemElement = initElement(WallpaperGridItem, {src}); await waitAfterNextRender(wallpaperGridItemElement); // Verify state. Note that |img| is shown as |imageSrc| has already loaded. const img = querySelector('img'); - assertEquals(img?.getAttribute('auto-src'), imageSrc); + assertEquals(img?.getAttribute('auto-src'), src.url); assertEquals(img?.getAttribute('aria-hidden'), 'true'); assertEquals(img?.hasAttribute('clear-src'), true); assertEquals(img?.hasAttribute('hidden'), false); assertEquals(img?.hasAttribute('is-google-photos'), true); // Update state. Note that |img| is hidden as |imageSrc| hasn't yet loaded. - imageSrc = imageSrc.replace('red', 'blue'); - wallpaperGridItemElement.imageSrc = imageSrc; - assertEquals(img?.getAttribute('auto-src'), imageSrc); + const newSrc: Url = {url: src.url.replace('red', 'blue')}; + wallpaperGridItemElement.src = newSrc; + assertEquals(img?.getAttribute('auto-src'), newSrc.url); assertEquals(img?.hasAttribute('hidden'), true); // Verify that once |imageSrc| has loaded, |img| will be shown.
diff --git a/chrome/test/data/webui/settings/chromeos/crostini_page_test.js b/chrome/test/data/webui/settings/chromeos/crostini_page_test.js index 30efe6d..8d45f12 100644 --- a/chrome/test/data/webui/settings/chromeos/crostini_page_test.js +++ b/chrome/test/data/webui/settings/chromeos/crostini_page_test.js
@@ -1332,17 +1332,30 @@ setup(async function() { setCrostiniPrefs(true); + loadTimeData.overrideValues({ + showCrostiniExtraContainers: false, + }); guestOsBrowserProxy.sharedUsbDevices = [ { guid: '0001', name: 'usb_dev1', - sharedWith: 'termina', + guestId: { + vm_name: 'termina', + container_name: '', + }, + vendorId: '0000', + productId: '0000', promptBeforeSharing: false, }, { guid: '0002', name: 'usb_dev2', - sharedWith: null, + guestId: { + vm_name: '', + container_name: '', + }, + vendorId: '0000', + productId: '0000', promptBeforeSharing: false, }, ]; @@ -1353,7 +1366,7 @@ await flushTasks(); subpage = crostiniPage.shadowRoot.querySelector( - 'settings-guest-os-shared-usb-devices'); + 'settings-crostini-shared-usb-devices'); assertTrue(!!subpage); }); @@ -1365,6 +1378,76 @@ }); }); + // Functionality is already tested in OSSettingsGuestOsSharedUsbDevicesTest, + // so just check that we correctly set up the page. + suite('SubPageSharedUsbDevicesMultiContainer', function() { + let subpage; + + setup(async function() { + setCrostiniPrefs(true); + loadTimeData.overrideValues({ + showCrostiniExtraContainers: true, + }); + crostiniBrowserProxy.containerInfo = multipleContainers; + guestOsBrowserProxy.sharedUsbDevices = [ + { + guid: '0001', + label: 'usb_dev1', + guestId: { + vm_name: '', + container_name: '', + }, + vendorId: '0000', + productId: '0000', + promptBeforeSharing: false, + }, + { + guid: '0002', + label: 'usb_dev2', + guestId: { + vm_name: 'termina', + container_name: 'penguin', + }, + vendorId: '0000', + productId: '0000', + promptBeforeSharing: true, + }, + { + guid: '0003', + label: 'usb_dev3', + guestId: { + vm_name: 'not-termina', + container_name: 'not-penguin', + }, + vendorId: '0000', + productId: '0000', + promptBeforeSharing: true, + }, + ]; + + await flushTasks(); + Router.getInstance().navigateTo(routes.CROSTINI_SHARED_USB_DEVICES); + + await flushTasks(); + subpage = crostiniPage.shadowRoot.querySelector( + 'settings-crostini-shared-usb-devices'); + assertTrue(!!subpage); + }); + + test('USB devices are shown', async function() { + const guests = subpage.shadowRoot.querySelectorAll('.usb-list-guest-id'); + assertEquals(2, guests.length); + assertEquals('penguin', guests[0].innerText); + assertEquals('not-termina:not-penguin', guests[1].innerText); + + const devices = + subpage.shadowRoot.querySelectorAll('.usb-list-card-label'); + assertEquals(2, devices.length); + assertEquals('usb_dev2', devices[0].innerText); + assertEquals('usb_dev3', devices[1].innerText); + }); + }); + suite('SubPageArcAdb', function() { let subpage;
diff --git a/chrome/test/data/webui/settings/chromeos/guest_os_shared_usb_devices_test.js b/chrome/test/data/webui/settings/chromeos/guest_os_shared_usb_devices_test.js index 83b3d3f..f2bc61b 100644 --- a/chrome/test/data/webui/settings/chromeos/guest_os_shared_usb_devices_test.js +++ b/chrome/test/data/webui/settings/chromeos/guest_os_shared_usb_devices_test.js
@@ -10,30 +10,8 @@ import {flushTasks} from 'chrome://test/test_util.js'; import {assertEquals, assertFalse, assertTrue} from '../../chai_assert.js'; -import {TestBrowserProxy} from '../../test_browser_proxy.js'; -/** @implements {GuestOsBrowserProxy} */ -class TestGuestOsBrowserProxy extends TestBrowserProxy { - constructor() { - super([ - 'notifyGuestOsSharedUsbDevicesPageReady', - 'setGuestOsUsbDeviceShared', - ]); - this.sharedUsbDevices = []; - } - - /** @override */ - notifyGuestOsSharedUsbDevicesPageReady() { - this.methodCalled('notifyGuestOsSharedUsbDevicesPageReady'); - webUIListenerCallback( - 'guest-os-shared-usb-devices-changed', this.sharedUsbDevices); - } - - /** override */ - setGuestOsUsbDeviceShared(vmName, guid, shared) { - this.methodCalled('setGuestOsUsbDeviceShared', [vmName, guid, shared]); - } -} +import {TestGuestOsBrowserProxy} from './test_guest_os_browser_proxy.js'; suite('SharedUsbDevices', function() { /** @type {?SettingsGuestOsSharedUsbDevicesElement} */ @@ -48,19 +26,34 @@ { guid: '0001', label: 'usb_dev1', - sharedWith: null, + guestId: { + vm_name: '', + container_name: '', + }, + vendorId: '0000', + productId: '0000', promptBeforeSharing: false, }, { guid: '0002', label: 'usb_dev2', - sharedWith: 'PvmDefault', + guestId: { + vm_name: 'PvmDefault', + container_name: '', + }, + vendorId: '0000', + productId: '0000', promptBeforeSharing: true, }, { guid: '0003', label: 'usb_dev3', - sharedWith: 'otherVm', + guestId: { + vm_name: 'otherVm', + container_name: '', + }, + vendorId: '0000', + productId: '0000', promptBeforeSharing: true, }, ]; @@ -90,14 +83,20 @@ const args = await guestOsBrowserProxy.whenCalled('setGuestOsUsbDeviceShared'); assertEquals('PvmDefault', args[0]); - assertEquals('0001', args[1]); - assertEquals(true, args[2]); + assertEquals('', args[1]); + assertEquals('0001', args[2]); + assertEquals(true, args[3]); // Simulate a change in the underlying model. webUIListenerCallback('guest-os-shared-usb-devices-changed', [ { guid: '0001', label: 'usb_dev1', - sharedWith: 'PvmDefault', + guestId: { + vm_name: 'PvmDefault', + container_name: '', + }, + vendorId: '0000', + productId: '0000', promptBeforeSharing: true, }, ]); @@ -143,7 +142,231 @@ const args = await guestOsBrowserProxy.whenCalled('setGuestOsUsbDeviceShared'); assertEquals('PvmDefault', args[0]); - assertEquals('0003', args[1]); - assertEquals(true, args[2]); + assertEquals('', args[1]); + assertEquals('0003', args[2]); + assertEquals(true, args[3]); + }); +}); + +suite('SharedUsbDevicesMultiContainer', function() { + /** @type {?SettingsGuestOsSharedUsbDevicesElement} */ + let page = null; + + /** @type {?TestGuestOsBrowserProxy} */ + let guestOsBrowserProxy = null; + + setup(async function() { + guestOsBrowserProxy = new TestGuestOsBrowserProxy(); + guestOsBrowserProxy.sharedUsbDevices = [ + { + guid: '0001', + label: 'usb_dev1', + guestId: { + vm_name: '', + container_name: '', + }, + vendorId: '0000', + productId: '0000', + promptBeforeSharing: false, + }, + { + guid: '0002', + label: 'usb_dev2', + guestId: { + vm_name: 'termina', + container_name: 'penguin', + }, + vendorId: '0000', + productId: '0000', + promptBeforeSharing: true, + }, + { + guid: '0003', + label: 'usb_dev3', + guestId: { + vm_name: 'not-termina', + container_name: 'not-penguin', + }, + vendorId: '0000', + productId: '0000', + promptBeforeSharing: true, + }, + ]; + GuestOsBrowserProxyImpl.setInstanceForTesting(guestOsBrowserProxy); + PolymerTest.clearBody(); + page = document.createElement('settings-guest-os-shared-usb-devices'); + page.guestOsType = 'crostini'; + page.hasContainers = true; + page.defaultGuestId = { + 'vm_name': 'termina', + 'container_name': 'penguin', + }; + page.onContainerInfo_([ + { + id: { + vm_name: 'termina', + container_name: 'penguin', + }, + ipv4: '1.2.3.4', + }, + { + id: { + vm_name: 'not-termina', + container_name: 'not-penguin', + }, + ipv4: '1.2.3.5', + }, + ]); + document.body.appendChild(page); + await flushTasks(); + }); + + teardown(function() { + page.remove(); + }); + + test('USB devices are shown', async function() { + const guests = page.shadowRoot.querySelectorAll('.usb-list-guest-id'); + assertEquals(2, guests.length); + // Default VM name is omitted. + assertEquals('penguin', guests[0].innerText); + assertEquals('not-termina:not-penguin', guests[1].innerText); + + const devices = page.shadowRoot.querySelectorAll('.usb-list-card-label'); + assertEquals(2, devices.length); + assertEquals('usb_dev2', devices[0].innerText); + assertEquals('usb_dev3', devices[1].innerText); + + page.shadowRoot.querySelector('#addUsbBtn').click(); + flush(); + + const dialog = page.shadowRoot.querySelector( + 'settings-guest-os-shared-usb-devices-add-dialog'); + + // USB devices shown in dropdown. + const selectDevice = dialog.shadowRoot.querySelector('#selectDevice'); + assertEquals(3, selectDevice.options.length); + // Guests VMs/containers shown in dropdown. + const selectContainer = + dialog.shadowRoot.querySelector('settings-guest-os-container-select') + .shadowRoot.querySelector('#selectContainer'); + assertEquals(2, selectContainer.options.length); + + dialog.shadowRoot.querySelector('#cancel').click(); + flush(); + await flushTasks(); + + // Dialog should close. + assertEquals( + null, + page.shadowRoot.querySelector( + 'settings-guest-os-shared-usb-devices-add-dialog')); + }); + + test('USB shared state is updated by adding device', async function() { + page.shadowRoot.querySelector('#addUsbBtn').click(); + flush(); + + const dialog = page.shadowRoot.querySelector( + 'settings-guest-os-shared-usb-devices-add-dialog'); + + // Add the first device to the first guest (termina:penguin). + dialog.shadowRoot.querySelector('#continue').click(); + flush(); + await flushTasks(); + + // Dialog should close. + assertEquals( + null, + page.shadowRoot.querySelector( + 'settings-guest-os-shared-usb-devices-add-dialog')); + + const args = + await guestOsBrowserProxy.whenCalled('setGuestOsUsbDeviceShared'); + assertEquals('termina', args[0]); + assertEquals('penguin', args[1]); + assertEquals('0001', args[2]); + assertEquals(true, args[3]); + // Simulate a change in the underlying model. + const updatedDevices = + structuredClone(guestOsBrowserProxy.sharedUsbDevices); + updatedDevices[0].guestId.vm_name = 'termina'; + updatedDevices[0].guestId.container_name = 'penguin'; + updatedDevices[0].promptBeforeSharing = true; + webUIListenerCallback( + 'guest-os-shared-usb-devices-changed', updatedDevices); + flush(); + assertEquals( + 2, page.shadowRoot.querySelectorAll('.usb-list-guest-id').length); + assertEquals( + 3, page.shadowRoot.querySelectorAll('.usb-list-card-label').length); + }); + + test('Show dialog for reassign', async function() { + page.shadowRoot.querySelector('#addUsbBtn').click(); + flush(); + + const dialog = page.shadowRoot.querySelector( + 'settings-guest-os-shared-usb-devices-add-dialog'); + + const selectDevice = dialog.shadowRoot.querySelector('#selectDevice'); + selectDevice.selectedIndex = 1; + const selectContainer = + dialog.shadowRoot.querySelector('settings-guest-os-container-select') + .shadowRoot.querySelector('#selectContainer'); + selectContainer.selectedIndex = 1; + selectContainer.dispatchEvent(new Event('change')); + + // Adding the second device to the second guest (not-termina:not-penguin) + // will show the dialog. + dialog.shadowRoot.querySelector('#continue').click(); + flush(); + + let reassignDialog = dialog.shadowRoot.querySelector('#reassignDialog'); + assertTrue(!!reassignDialog && reassignDialog.open); + + // Clicking cancel will close the inner dialog. + reassignDialog.querySelector('#cancel').click(); + flush(); + + assertEquals(null, dialog.shadowRoot.querySelector('#reassignDialog')); + + // Re-enter the inner dialog. + dialog.shadowRoot.querySelector('#continue').click(); + flush(); + + reassignDialog = dialog.shadowRoot.querySelector('#reassignDialog'); + assertTrue(!!reassignDialog && reassignDialog.open); + + // Clicking continue will reassign the device. + reassignDialog.querySelector('#continue').click(); + flush(); + await flushTasks(); + + // All dialogs should close. + assertEquals(null, dialog.shadowRoot.querySelector('#reassignDialog')); + assertEquals( + null, + page.shadowRoot.querySelector( + 'settings-guest-os-shared-usb-devices-add-dialog')); + + const args = + await guestOsBrowserProxy.whenCalled('setGuestOsUsbDeviceShared'); + assertEquals('not-termina', args[0]); + assertEquals('not-penguin', args[1]); + assertEquals('0002', args[2]); + assertEquals(true, args[3]); + // Simulate a change in the underlying model. + const updatedDevices = + structuredClone(guestOsBrowserProxy.sharedUsbDevices); + updatedDevices[1].guestId.vm_name = 'not-termina'; + updatedDevices[1].guestId.container_name = 'not-penguin'; + webUIListenerCallback( + 'guest-os-shared-usb-devices-changed', updatedDevices); + flush(); + assertEquals( + 1, page.shadowRoot.querySelectorAll('.usb-list-guest-id').length); + assertEquals( + 2, page.shadowRoot.querySelectorAll('.usb-list-card-label').length); }); });
diff --git a/chrome/test/data/webui/settings/chromeos/test_guest_os_browser_proxy.js b/chrome/test/data/webui/settings/chromeos/test_guest_os_browser_proxy.js index b142a25..769be28 100644 --- a/chrome/test/data/webui/settings/chromeos/test_guest_os_browser_proxy.js +++ b/chrome/test/data/webui/settings/chromeos/test_guest_os_browser_proxy.js
@@ -36,8 +36,9 @@ } /** @override */ - setGuestOsUsbDeviceShared(vmName, guid, shared) { - this.methodCalled('setGuestOsUsbDeviceShared', [vmName, guid, shared]); + setGuestOsUsbDeviceShared(vmName, containerName, guid, shared) { + this.methodCalled( + 'setGuestOsUsbDeviceShared', [vmName, containerName, guid, shared]); } /** override */
diff --git a/chrome/test/data/webui/settings/password_edit_dialog_test.ts b/chrome/test/data/webui/settings/password_edit_dialog_test.ts index 510ccf6..25b3aa5 100644 --- a/chrome/test/data/webui/settings/password_edit_dialog_test.ts +++ b/chrome/test/data/webui/settings/password_edit_dialog_test.ts
@@ -816,6 +816,44 @@ assertEquals('', noteElement!.value); }); + test('editingInputsDoesntCallExtendAuthValidity', async function() { + loadTimeData.overrideValues({enablePasswordViewPage: false}); + const commonEntry = createPasswordEntry({ + url: 'goo.gl', + username: 'derine', + id: 42, + }); + const passwordDialog = elementFactory.createPasswordEditDialog(commonEntry); + + passwordDialog.$.usernameInput.value += 'l'; + + assertEquals(0, passwordManager.getCallCount('extendAuthValidity')); + + passwordDialog.$.passwordInput.value = 'super5tr0ngpa55'; + + assertEquals(0, passwordManager.getCallCount('extendAuthValidity')); + }); + + test('editingInputsCallsExtendAuthValidityOnViewPage', async function() { + loadTimeData.overrideValues({enablePasswordViewPage: true}); + const commonEntry = createPasswordEntry({ + url: 'goo.gl', + username: 'derine', + id: 42, + }); + const passwordDialog = elementFactory.createPasswordEditDialog(commonEntry); + passwordManager.resetResolver('extendAuthValidity'); + + passwordDialog.$.usernameInput.value += 'l'; + + assertEquals(1, passwordManager.getCallCount('extendAuthValidity')); + + passwordDialog.shadowRoot!.querySelector<SettingsTextareaElement>( + '#note')!.value = 'personal account'; + + assertEquals(2, passwordManager.getCallCount('extendAuthValidity')); + }); + // <if expr="not is_chromeos"> // On ChromeOS/Lacros the behavior is different (on failure we request token // and retry).
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 6d4efcf..5c8ca49 100644 --- a/chrome/test/data/webui/settings/test_password_manager_proxy.ts +++ b/chrome/test/data/webui/settings/test_password_manager_proxy.ts
@@ -101,6 +101,7 @@ 'cancelExportPasswords', 'changeSavedPassword', 'exportPasswords', + 'extendAuthValidity', 'getCompromisedCredentials', 'getPasswordCheckStatus', 'getUrlCollection', @@ -409,6 +410,10 @@ 'recordChangePasswordFlowStarted', insecureCredential, isManualFlow); } + extendAuthValidity() { + this.methodCalled('extendAuthValidity'); + } + importPasswords(toStore: chrome.passwordsPrivate.PasswordStoreSet) { this.methodCalled('importPasswords', toStore); return Promise.resolve(this.importResults_);
diff --git a/chrome/updater/test/integration_tests.cc b/chrome/updater/test/integration_tests.cc index f7dd358..dadbd86 100644 --- a/chrome/updater/test/integration_tests.cc +++ b/chrome/updater/test/integration_tests.cc
@@ -713,7 +713,14 @@ #if BUILDFLAG(CHROMIUM_BRANDING) || BUILDFLAG(GOOGLE_CHROME_BRANDING) #if !defined(COMPONENT_BUILD) -TEST_F(IntegrationTest, SelfUpdateFromOldReal) { +// Disabled on Windows due to undiagnosed typelib errors even after +// instrumenting the build; see https://crbug.com/1341471. +#if BUILDFLAG(IS_WIN) +#define MAYBE_SelfUpdateFromOldReal DISABLED_SelfUpdateFromOldReal +#else +#define MAYBE_SelfUpdateFromOldReal SelfUpdateFromOldReal +#endif +TEST_F(IntegrationTest, MAYBE_SelfUpdateFromOldReal) { ScopedServer test_server(test_commands_); SetupRealUpdaterLowerVersion(); @@ -736,6 +743,29 @@ ExpectVersionActive(kUpdaterVersion); Uninstall(); } + +// Tests that installing and uninstalling an old version of the updater from +// CIPD is possible. +// TODO(crbug.com/1341471) - this may be slightly flaky as the typelib errors +// showing up on Windows (which resulted in disabling SelfUpdateFromOldReal) are +// being investigated. This test is simpler than SelfUpdateFromOldReal. +TEST_F(IntegrationTest, InstallUninstallLowerVersion) { + SetupRealUpdaterLowerVersion(); + ExpectVersionNotActive(kUpdaterVersion); + Uninstall(); + +#if BUILDFLAG(IS_WIN) + // This deletes a tree of empty subdirectories corresponding to the crash + // handler of the lower version updater installed above. `Uninstall` runs + // `updater --uninstall` from the out directory of the build, which attempts + // to launch the `uninstall.cmd` script corresponding to this version of the + // updater from the install directory. However, there is no such script + // because this version was never installed, and the script is not found + // there. + DeleteUpdaterDirectory(); +#endif // IS_WIN +} + #endif #endif
diff --git a/chrome/updater/test/integration_tests_impl.cc b/chrome/updater/test/integration_tests_impl.cc index cdb69ba1..1806204 100644 --- a/chrome/updater/test/integration_tests_impl.cc +++ b/chrome/updater/test/integration_tests_impl.cc
@@ -187,11 +187,11 @@ registration.version = base::Version("0.1"); base::RunLoop loop; update_service->RegisterApp( - registration, base::BindOnce(base::BindLambdaForTesting( - [&loop](const RegistrationResponse& response) { - EXPECT_EQ(response.status_code, 0); - loop.Quit(); - }))); + registration, + base::BindLambdaForTesting([&loop](const RegistrationResponse& response) { + EXPECT_EQ(response.status_code, 0); + loop.Quit(); + })); loop.Run(); } @@ -285,11 +285,11 @@ { scoped_refptr<UpdateService> service = CreateUpdateServiceProxy(scope); base::RunLoop loop; - service->GetVersion(base::BindOnce(base::BindLambdaForTesting( + service->GetVersion(base::BindLambdaForTesting( [&loop, &active_version](const base::Version& version) { active_version = version; loop.Quit(); - }))); + })); loop.Run(); } ASSERT_TRUE(active_version.IsValid()); @@ -312,8 +312,8 @@ update_service->Update( app_id, install_data_index, UpdateService::Priority::kForeground, UpdateService::PolicySameVersionUpdate::kNotAllowed, base::DoNothing(), - base::BindOnce(base::BindLambdaForTesting( - [&loop](UpdateService::Result result_unused) { loop.Quit(); }))); + base::BindLambdaForTesting( + [&loop](UpdateService::Result result_unused) { loop.Quit(); })); loop.Run(); } @@ -322,8 +322,8 @@ base::RunLoop loop; update_service->UpdateAll( base::DoNothing(), - base::BindOnce(base::BindLambdaForTesting( - [&loop](UpdateService::Result result_unused) { loop.Quit(); }))); + base::BindLambdaForTesting( + [&loop](UpdateService::Result result_unused) { loop.Quit(); })); loop.Run(); }
diff --git a/chromeos/ash/components/audio/audio_devices_pref_handler_impl_unittest.cc b/chromeos/ash/components/audio/audio_devices_pref_handler_impl_unittest.cc index 88fc613f..5ca13b5 100644 --- a/chromeos/ash/components/audio/audio_devices_pref_handler_impl_unittest.cc +++ b/chromeos/ash/components/audio/audio_devices_pref_handler_impl_unittest.cc
@@ -79,6 +79,9 @@ const uint32_t kInputAudioEffect = 1; const uint32_t kOutputAudioEffect = 0; +// Does not support getting input step now. +const int32_t kInputNumberOfVolumeSteps = 0; +const int32_t kOutputNumberOfVolumeSteps = 25; AudioDevice CreateAudioDevice(const AudioNodeInfo& info, int version) { return AudioDevice(AudioNode( @@ -86,7 +89,8 @@ version == 1 ? 0 : info.id ^ 0xFF /* stable_device_id_v2 */, info.device_name, info.type, info.name, false, 0, info.is_input ? kInputMaxSupportedChannels : kOutputMaxSupportedChannels, - info.is_input ? kInputAudioEffect : kOutputAudioEffect)); + info.is_input ? kInputAudioEffect : kOutputAudioEffect, + info.is_input ? kInputNumberOfVolumeSteps : kOutputNumberOfVolumeSteps)); } // Test param determines whether the test should test input or output devices
diff --git a/chromeos/ash/components/audio/cras_audio_handler_unittest.cc b/chromeos/ash/components/audio/cras_audio_handler_unittest.cc index fb177e9..96366b49 100644 --- a/chromeos/ash/components/audio/cras_audio_handler_unittest.cc +++ b/chromeos/ash/components/audio/cras_audio_handler_unittest.cc
@@ -89,6 +89,7 @@ const char* const device_name; const char* const type; const char* const name; + const int32_t number_of_volume_steps; }; const uint32_t kInputMaxSupportedChannels = 1; @@ -97,68 +98,69 @@ const uint32_t kInputAudioEffect = 1; const uint32_t kOutputAudioEffect = 0; -const AudioNodeInfo kInternalSpeaker[] = { - {false, kInternalSpeakerId, "Fake Speaker", "INTERNAL_SPEAKER", "Speaker"}}; +const AudioNodeInfo kInternalSpeaker[] = {{false, kInternalSpeakerId, + "Fake Speaker", "INTERNAL_SPEAKER", + "Speaker", 25}}; const AudioNodeInfo kHeadphone[] = { - {false, kHeadphoneId, "Fake Headphone", "HEADPHONE", "Headphone"}}; + {false, kHeadphoneId, "Fake Headphone", "HEADPHONE", "Headphone", 25}}; const AudioNodeInfo kInternalMic[] = { - {true, kInternalMicId, "Fake Mic", "INTERNAL_MIC", "Internal Mic"}}; + {true, kInternalMicId, "Fake Mic", "INTERNAL_MIC", "Internal Mic", 0}}; const AudioNodeInfo kMicJack[] = { - {true, kMicJackId, "Fake Mic Jack", "MIC", "Mic Jack"}}; + {true, kMicJackId, "Fake Mic Jack", "MIC", "Mic Jack", 0}}; const AudioNodeInfo kUSBMic1[] = { - {true, kUSBMicId1, "Fake USB Mic 1", "USB", "USB Microphone 1"}}; + {true, kUSBMicId1, "Fake USB Mic 1", "USB", "USB Microphone 1", 0}}; const AudioNodeInfo kUSBMic2[] = { - {true, kUSBMicId2, "Fake USB Mic 2", "USB", "USB Microphone 2"}}; + {true, kUSBMicId2, "Fake USB Mic 2", "USB", "USB Microphone 2", 0}}; const AudioNodeInfo kKeyboardMic[] = {{true, kKeyboardMicId, "Fake Keyboard Mic", "KEYBOARD_MIC", - "Keyboard Mic"}}; + "Keyboard Mic", 0}}; const AudioNodeInfo kFrontMic[] = { - {true, kFrontMicId, "Fake Front Mic", "FRONT_MIC", "Front Mic"}}; + {true, kFrontMicId, "Fake Front Mic", "FRONT_MIC", "Front Mic", 0}}; const AudioNodeInfo kRearMic[] = { - {true, kRearMicId, "Fake Rear Mic", "REAR_MIC", "Rear Mic"}}; + {true, kRearMicId, "Fake Rear Mic", "REAR_MIC", "Rear Mic", 0}}; const AudioNodeInfo kOther[] = { - {false, kOtherId, "Non Simple Output Device", "OTHER", "Other"}}; + {false, kOtherId, "Non Simple Output Device", "OTHER", "Other", 25}}; const AudioNodeInfo kBluetoothHeadset[] = {{false, kBluetoothHeadsetId, "Bluetooth Headset", "BLUETOOTH", - "Bluetooth Headset 1"}}; + "Bluetooth Headset 1", 25}}; const AudioNodeInfo kHDMIOutput[] = { - {false, kHDMIOutputId, "HDMI output", "HDMI", "HDMI output"}}; + {false, kHDMIOutputId, "HDMI output", "HDMI", "HDMI output", 25}}; const AudioNodeInfo kUSBHeadphone1[] = { - {false, kUSBHeadphoneId1, "USB Headphone", "USB", "USB Headphone 1"}}; + {false, kUSBHeadphoneId1, "USB Headphone", "USB", "USB Headphone 1", 25}}; const AudioNodeInfo kUSBHeadphone2[] = { - {false, kUSBHeadphoneId2, "USB Headphone", "USB", "USB Headphone 1"}}; + {false, kUSBHeadphoneId2, "USB Headphone", "USB", "USB Headphone 1", 16}}; const AudioNodeInfo kUSBJabraSpeakerOutput1[] = { {false, kUSBJabraSpeakerOutputId1, "Jabra Speaker 1", "USB", - "Jabra Speaker 1"}}; + "Jabra Speaker 1", 16}}; const AudioNodeInfo kUSBJabraSpeakerOutput2[] = { {false, kUSBJabraSpeakerOutputId2, "Jabra Speaker 2", "USB", - "Jabra Speaker 2"}}; + "Jabra Speaker 2", 25}}; const AudioNodeInfo kUSBJabraSpeakerInput1[] = {{true, kUSBJabraSpeakerInputId1, "Jabra Speaker 1", "USB", - "Jabra Speaker"}}; + "Jabra Speaker", 0}}; const AudioNodeInfo kUSBJabraSpeakerInput2[] = {{true, kUSBJabraSpeakerInputId2, "Jabra Speaker 2", "USB", - "Jabra Speaker 2"}}; + "Jabra Speaker 2", 0}}; const AudioNodeInfo kUSBCameraInput[] = { - {true, kUSBCameraInputId, "USB Camera", "USB", "USB Camera"}}; + {true, kUSBCameraInputId, "USB Camera", "USB", "USB Camera", 0}}; class TestObserver : public CrasAudioHandler::AudioObserver { public: @@ -338,7 +340,8 @@ 0 /* pluged_time */, node_info->is_input ? kInputMaxSupportedChannels : kOutputMaxSupportedChannels, - node_info->is_input ? kInputAudioEffect : kOutputAudioEffect); + node_info->is_input ? kInputAudioEffect : kOutputAudioEffect, + node_info->number_of_volume_steps); } AudioNodeList GenerateAudioNodeList(
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 4cf3badb..f5ddd8d 100644 --- a/chromeos/ash/components/audio/cros_audio_config_impl_unittest.cc +++ b/chromeos/ash/components/audio/cros_audio_config_impl_unittest.cc
@@ -43,6 +43,9 @@ const uint32_t kInputMaxSupportedChannels = 1; const uint32_t kOutputMaxSupportedChannels = 2; +const int32_t kInputNumberOfVolumeSteps = 0; +const int32_t kOutputNumberOfVolumeSteps = 25; + const AudioNodeInfo kInternalSpeaker[] = { {false, kInternalSpeakerId, "Fake Speaker", "INTERNAL_SPEAKER", "Speaker"}}; @@ -150,7 +153,10 @@ /* plugged_time=*/0, node_info->is_input ? kInputMaxSupportedChannels : kOutputMaxSupportedChannels, - node_info->audio_effect); + node_info->audio_effect, + /* number_of_volume_steps=*/ + node_info->is_input ? kInputNumberOfVolumeSteps + : kOutputNumberOfVolumeSteps); } AudioNodeList GenerateAudioNodeList(
diff --git a/chromeos/ash/components/dbus/audio/audio_node.cc b/chromeos/ash/components/dbus/audio/audio_node.cc index 6a7fdc1..2b89ef5 100644 --- a/chromeos/ash/components/dbus/audio/audio_node.cc +++ b/chromeos/ash/components/dbus/audio/audio_node.cc
@@ -14,6 +14,8 @@ namespace ash { +constexpr int32_t NUMBER_OF_VOLUME_STEPS_DEFAULT = 25; + AudioNode::AudioNode() = default; AudioNode::AudioNode(bool is_input, @@ -27,7 +29,8 @@ bool active, uint64_t plugged_time, uint32_t max_supported_channels, - uint32_t audio_effect) + uint32_t audio_effect, + int32_t number_of_volume_steps) : is_input(is_input), id(id), has_v2_stable_device_id(has_v2_stable_device_id), @@ -39,8 +42,12 @@ active(active), plugged_time(plugged_time), max_supported_channels(max_supported_channels), - audio_effect(audio_effect) { + audio_effect(audio_effect), + number_of_volume_steps(number_of_volume_steps) { DCHECK(!(audio_effect & ~cras::EFFECT_TYPE_NOISE_CANCELLATION)); + if (!is_input && number_of_volume_steps <= 0) { + this->number_of_volume_steps = NUMBER_OF_VOLUME_STEPS_DEFAULT; + } } AudioNode::AudioNode(const AudioNode& other) = default; @@ -66,7 +73,8 @@ base::StringAppendF(&result, "max_supported_channels= %s ", base::NumberToString(max_supported_channels).c_str()); base::StringAppendF(&result, "audio_effect = 0x%" PRIx32 " ", audio_effect); - + base::StringAppendF(&result, "number_of_volume_steps= %s", + base::NumberToString(number_of_volume_steps).c_str()); return result; }
diff --git a/chromeos/ash/components/dbus/audio/audio_node.h b/chromeos/ash/components/dbus/audio/audio_node.h index f1cf8a8..868e407 100644 --- a/chromeos/ash/components/dbus/audio/audio_node.h +++ b/chromeos/ash/components/dbus/audio/audio_node.h
@@ -31,7 +31,14 @@ uint32_t max_supported_channels = 0; // Bit-wise audio effect support information. uint32_t audio_effect = 0; - + // The number of volume steps that can be adjusted for the node. + // Mainly used to calculate the percentage of playback volume change. + // e.g. number_of_volume_steps=25 volume will change 4% (100%/25=4%) for one + // volume change event. If this value is set to 0, indicates that the value + // for this node is invalid. Currently all input nodes this value is invalid + // (0), all output nodes should get a valid number (>0) if output nodes + // somehow get a number_of_volume_steps <=0, use 25 as default value. + int32_t number_of_volume_steps = 0; AudioNode(); AudioNode(bool is_input, uint64_t id, @@ -44,7 +51,8 @@ bool active, uint64_t plugged_time, uint32_t max_supported_channels, - uint32_t audio_effect); + uint32_t audio_effect, + int32_t number_of_volume_steps); AudioNode(const AudioNode& other); ~AudioNode();
diff --git a/chromeos/ash/components/dbus/audio/cras_audio_client.cc b/chromeos/ash/components/dbus/audio/cras_audio_client.cc index c856b61..7975a79 100644 --- a/chromeos/ash/components/dbus/audio/cras_audio_client.cc +++ b/chromeos/ash/components/dbus/audio/cras_audio_client.cc
@@ -1078,6 +1078,9 @@ } else if (key == cras::kAudioEffectProperty) { if (!value_reader.PopUint32(&node->audio_effect)) return false; + } else if (key == cras::kNumberOfVolumeStepsProperty) { + if (!value_reader.PopInt32(&node->number_of_volume_steps)) + return false; } }
diff --git a/chromeos/ash/components/dbus/audio/cras_audio_client_unittest.cc b/chromeos/ash/components/dbus/audio/cras_audio_client_unittest.cc index 21e82b0..5469e6fa 100644 --- a/chromeos/ash/components/dbus/audio/cras_audio_client_unittest.cc +++ b/chromeos/ash/components/dbus/audio/cras_audio_client_unittest.cc
@@ -38,6 +38,9 @@ const uint32_t kInputAudioEffect = cras::EFFECT_TYPE_NOISE_CANCELLATION; const uint32_t kOutputAudioEffect = 0; +const int32_t kInputNumberOfVolumeSteps = 0; +const int32_t kOutputNumberOfVolumeSteps = 25; + const AudioNode kInternalSpeaker(false, kInternalSpeakerId, false /* has_v2_stable_device_id */, @@ -49,7 +52,8 @@ false, 0, kOutputMaxSupportedChannels, - kOutputAudioEffect); + kOutputAudioEffect, + kOutputNumberOfVolumeSteps); const AudioNode kInternalMic(true, kInternalMicId, @@ -62,7 +66,8 @@ false, 0, kInputMaxSupportedChannels, - kInputAudioEffect); + kInputAudioEffect, + kInputNumberOfVolumeSteps); const AudioNode kInternalSpeakerV2( false, @@ -78,7 +83,8 @@ false, 0, kOutputMaxSupportedChannels, - kOutputAudioEffect); + kOutputAudioEffect, + kOutputNumberOfVolumeSteps); const AudioNode kInternalMicV2(true, kInternalMicId, @@ -93,7 +99,8 @@ false, 0, kInputMaxSupportedChannels, - kInputAudioEffect); + kInputAudioEffect, + kInputNumberOfVolumeSteps); // A mock CrasAudioClient Observer. class MockObserver : public CrasAudioClient::Observer { @@ -304,6 +311,11 @@ entry_writer.AppendVariantOfUint32(node_list[i].audio_effect); sub_writer.CloseContainer(&entry_writer); + sub_writer.OpenDictEntry(&entry_writer); + entry_writer.AppendString(cras::kNumberOfVolumeStepsProperty); + entry_writer.AppendVariantOfInt32(node_list[i].number_of_volume_steps); + sub_writer.CloseContainer(&entry_writer); + writer->CloseContainer(&sub_writer); } } @@ -331,6 +343,8 @@ EXPECT_EQ(expected_node_list[i].StableDeviceIdVersion(), node_list[i].StableDeviceIdVersion()); EXPECT_EQ(expected_node_list[i].audio_effect, node_list[i].audio_effect); + EXPECT_EQ(expected_node_list[i].number_of_volume_steps, + node_list[i].number_of_volume_steps); } }
diff --git a/chromeos/ash/services/BUILD.gn b/chromeos/ash/services/BUILD.gn index e148539..e4ceec8 100644 --- a/chromeos/ash/services/BUILD.gn +++ b/chromeos/ash/services/BUILD.gn
@@ -22,6 +22,9 @@ ] if (enable_cros_libassistant) { - deps += [ "//chromeos/ash/services/libassistant:unit_tests" ] + deps += [ + "//chromeos/ash/services/libassistant:unit_tests", + "//chromeos/ash/services/libassistant/grpc:unit_tests", + ] } }
diff --git a/chromeos/ash/services/libassistant/BUILD.gn b/chromeos/ash/services/libassistant/BUILD.gn index 0d165220..7344b200 100644 --- a/chromeos/ash/services/libassistant/BUILD.gn +++ b/chromeos/ash/services/libassistant/BUILD.gn
@@ -154,16 +154,16 @@ "//chromeos/ash/resources", "//chromeos/ash/services/assistant/public/cpp", "//chromeos/ash/services/assistant/public/proto", + "//chromeos/ash/services/libassistant/grpc:assistant_client", + "//chromeos/ash/services/libassistant/grpc:grpc_service", + "//chromeos/ash/services/libassistant/grpc/external_services:grpc_services_initializer", + "//chromeos/ash/services/libassistant/grpc/external_services:grpc_services_observer", "//chromeos/assistant/internal", "//chromeos/assistant/internal:libassistant", "//chromeos/assistant/internal:libassistant_shared_headers", "//chromeos/assistant/internal:support", "//chromeos/assistant/internal/proto:assistant", "//chromeos/dbus/power", - "//chromeos/services/libassistant/grpc:assistant_client", - "//chromeos/services/libassistant/grpc:grpc_service", - "//chromeos/services/libassistant/grpc/external_services:grpc_services_initializer", - "//chromeos/services/libassistant/grpc/external_services:grpc_services_observer", "//chromeos/services/libassistant/public/mojom", "//chromeos/services/network_config/public/cpp", "//chromeos/strings:strings_grit", @@ -204,8 +204,8 @@ "//ash/public/mojom", "//base", "//chromeos/ash/services/assistant/public/cpp", + "//chromeos/ash/services/libassistant/grpc:assistant_client", "//chromeos/assistant/internal:libassistant_shared_headers", - "//chromeos/services/libassistant/grpc:assistant_client", "//chromeos/services/libassistant/public/mojom", "//media", "//media/mojo/mojom", @@ -247,9 +247,9 @@ ":internal", ":libassistant", "//base/test:test_support", + "//chromeos/ash/services/libassistant/grpc:assistant_client", "//chromeos/assistant/internal:test_support", "//chromeos/assistant/internal/proto:assistant", - "//chromeos/services/libassistant/grpc:assistant_client", "//chromeos/services/libassistant/public/mojom", "//services/network:test_support", ] @@ -288,13 +288,13 @@ "//base/test:test_support", "//chromeos/ash/components/assistant/test_support:test_support", "//chromeos/ash/services/assistant/public/cpp", + "//chromeos/ash/services/libassistant/grpc:assistant_client", "//chromeos/assistant/internal", "//chromeos/assistant/internal:libassistant_shared_headers", "//chromeos/assistant/internal:support", "//chromeos/assistant/internal:test_support", "//chromeos/dbus/dlcservice", "//chromeos/dbus/power", - "//chromeos/services/libassistant/grpc:assistant_client", "//chromeos/services/libassistant/public/mojom", "//services/audio/public/cpp:test_support", "//services/device/public/cpp:test_support",
diff --git a/chromeos/ash/services/libassistant/conversation_controller.cc b/chromeos/ash/services/libassistant/conversation_controller.cc index e076a20..7f7b3b8 100644 --- a/chromeos/ash/services/libassistant/conversation_controller.cc +++ b/chromeos/ash/services/libassistant/conversation_controller.cc
@@ -11,12 +11,12 @@ #include "base/thread_annotations.h" #include "base/threading/sequenced_task_runner_handle.h" #include "chromeos/ash/services/assistant/public/cpp/features.h" +#include "chromeos/ash/services/libassistant/grpc/assistant_client.h" #include "chromeos/ash/services/libassistant/util.h" #include "chromeos/assistant/internal/internal_util.h" #include "chromeos/assistant/internal/libassistant/shared_headers.h" #include "chromeos/assistant/internal/proto/shared/proto/v2/delegate/event_handler_interface.pb.h" #include "chromeos/assistant/internal/proto/shared/proto/v2/internal_options.pb.h" -#include "chromeos/services/libassistant/grpc/assistant_client.h" #include "chromeos/services/libassistant/public/mojom/conversation_controller.mojom.h" #include "chromeos/strings/grit/chromeos_strings.h" #include "mojo/public/cpp/bindings/pending_receiver.h"
diff --git a/chromeos/ash/services/libassistant/conversation_controller.h b/chromeos/ash/services/libassistant/conversation_controller.h index 21c9b9c5..574beaf 100644 --- a/chromeos/ash/services/libassistant/conversation_controller.h +++ b/chromeos/ash/services/libassistant/conversation_controller.h
@@ -11,8 +11,8 @@ #include "base/component_export.h" #include "base/sequence_checker.h" #include "chromeos/ash/services/assistant/public/cpp/conversation_observer.h" +#include "chromeos/ash/services/libassistant/grpc/assistant_client_observer.h" #include "chromeos/assistant/internal/action/assistant_action_observer.h" -#include "chromeos/services/libassistant/grpc/assistant_client_observer.h" #include "chromeos/services/libassistant/public/cpp/assistant_notification.h" #include "chromeos/services/libassistant/public/mojom/authentication_state_observer.mojom.h" #include "chromeos/services/libassistant/public/mojom/conversation_controller.mojom.h"
diff --git a/chromeos/ash/services/libassistant/conversation_state_listener_impl.cc b/chromeos/ash/services/libassistant/conversation_state_listener_impl.cc index f2887f7..33364c6 100644 --- a/chromeos/ash/services/libassistant/conversation_state_listener_impl.cc +++ b/chromeos/ash/services/libassistant/conversation_state_listener_impl.cc
@@ -6,8 +6,8 @@ #include "chromeos/ash/services/assistant/public/cpp/assistant_enums.h" #include "chromeos/ash/services/libassistant/audio_input_controller.h" +#include "chromeos/ash/services/libassistant/grpc/assistant_client.h" #include "chromeos/assistant/internal/libassistant/shared_headers.h" -#include "chromeos/services/libassistant/grpc/assistant_client.h" #include "chromeos/services/libassistant/public/mojom/conversation_observer.mojom.h" #include "chromeos/services/libassistant/public/mojom/speech_recognition_observer.mojom.h"
diff --git a/chromeos/ash/services/libassistant/conversation_state_listener_impl.h b/chromeos/ash/services/libassistant/conversation_state_listener_impl.h index 88ad8ce..4cb42b7 100644 --- a/chromeos/ash/services/libassistant/conversation_state_listener_impl.h +++ b/chromeos/ash/services/libassistant/conversation_state_listener_impl.h
@@ -6,8 +6,8 @@ #define CHROMEOS_ASH_SERVICES_LIBASSISTANT_CONVERSATION_STATE_LISTENER_IMPL_H_ #include "base/sequence_checker.h" +#include "chromeos/ash/services/libassistant/grpc/assistant_client_observer.h" #include "chromeos/assistant/internal/libassistant/shared_headers.h" -#include "chromeos/services/libassistant/grpc/assistant_client_observer.h" #include "chromeos/services/libassistant/public/mojom/display_controller.mojom.h" #include "mojo/public/cpp/bindings/receiver.h" #include "mojo/public/cpp/bindings/remote_set.h"
diff --git a/chromeos/ash/services/libassistant/device_settings_controller.cc b/chromeos/ash/services/libassistant/device_settings_controller.cc index c9da7b3..417fddb 100644 --- a/chromeos/ash/services/libassistant/device_settings_controller.cc +++ b/chromeos/ash/services/libassistant/device_settings_controller.cc
@@ -10,12 +10,12 @@ #include "base/logging.h" #include "base/memory/weak_ptr.h" +#include "chromeos/ash/services/libassistant/grpc/assistant_client.h" #include "chromeos/ash/services/libassistant/util.h" #include "chromeos/assistant/internal/internal_util.h" #include "chromeos/assistant/internal/libassistant/shared_headers.h" #include "chromeos/assistant/internal/proto/shared/proto/device_args.pb.h" #include "chromeos/assistant/internal/proto/shared/proto/v2/internal_options.pb.h" -#include "chromeos/services/libassistant/grpc/assistant_client.h" #include "chromeos/services/libassistant/public/mojom/device_settings_delegate.mojom.h" namespace client_op = ::assistant::api::client_op;
diff --git a/chromeos/ash/services/libassistant/device_settings_controller.h b/chromeos/ash/services/libassistant/device_settings_controller.h index cc83553..8a47a88 100644 --- a/chromeos/ash/services/libassistant/device_settings_controller.h +++ b/chromeos/ash/services/libassistant/device_settings_controller.h
@@ -12,8 +12,8 @@ #include "base/component_export.h" #include "base/memory/weak_ptr.h" #include "base/task/sequenced_task_runner.h" +#include "chromeos/ash/services/libassistant/grpc/assistant_client_observer.h" #include "chromeos/assistant/internal/action/assistant_action_observer.h" -#include "chromeos/services/libassistant/grpc/assistant_client_observer.h" #include "chromeos/services/libassistant/public/mojom/device_settings_delegate.mojom.h" #include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/remote.h"
diff --git a/chromeos/ash/services/libassistant/display_connection.cc b/chromeos/ash/services/libassistant/display_connection.cc index 8f1886b..5e02831 100644 --- a/chromeos/ash/services/libassistant/display_connection.cc +++ b/chromeos/ash/services/libassistant/display_connection.cc
@@ -9,8 +9,8 @@ #include "base/check.h" #include "base/logging.h" #include "base/threading/sequenced_task_runner_handle.h" +#include "chromeos/ash/services/libassistant/grpc/assistant_client.h" #include "chromeos/assistant/internal/proto/shared/proto/v2/display_interface.pb.h" -#include "chromeos/services/libassistant/grpc/assistant_client.h" namespace chromeos { namespace libassistant {
diff --git a/chromeos/ash/services/libassistant/display_connection.h b/chromeos/ash/services/libassistant/display_connection.h index 26addbb..74a590f 100644 --- a/chromeos/ash/services/libassistant/display_connection.h +++ b/chromeos/ash/services/libassistant/display_connection.h
@@ -8,10 +8,10 @@ #include <string> #include "base/task/sequenced_task_runner.h" +#include "chromeos/ash/services/libassistant/grpc/external_services/grpc_services_observer.h" #include "chromeos/assistant/internal/libassistant/shared_headers.h" #include "chromeos/assistant/internal/proto/assistant/display_connection.pb.h" #include "chromeos/assistant/internal/proto/shared/proto/v2/delegate/event_handler_interface.pb.h" -#include "chromeos/services/libassistant/grpc/external_services/grpc_services_observer.h" #include "chromeos/services/libassistant/public/cpp/android_app_info.h" namespace chromeos {
diff --git a/chromeos/ash/services/libassistant/display_controller.cc b/chromeos/ash/services/libassistant/display_controller.cc index 966610a..4800cf43 100644 --- a/chromeos/ash/services/libassistant/display_controller.cc +++ b/chromeos/ash/services/libassistant/display_controller.cc
@@ -9,11 +9,11 @@ #include "base/threading/sequenced_task_runner_handle.h" #include "chromeos/ash/services/assistant/public/cpp/features.h" #include "chromeos/ash/services/libassistant/display_connection.h" +#include "chromeos/ash/services/libassistant/grpc/assistant_client.h" #include "chromeos/ash/services/libassistant/util.h" #include "chromeos/assistant/internal/internal_util.h" #include "chromeos/assistant/internal/libassistant/shared_headers.h" #include "chromeos/assistant/internal/proto/shared/proto/v2/internal_options.pb.h" -#include "chromeos/services/libassistant/grpc/assistant_client.h" #include "chromeos/services/libassistant/public/mojom/speech_recognition_observer.mojom.h" namespace chromeos {
diff --git a/chromeos/ash/services/libassistant/display_controller.h b/chromeos/ash/services/libassistant/display_controller.h index 9786c4ff..e4b2cd1 100644 --- a/chromeos/ash/services/libassistant/display_controller.h +++ b/chromeos/ash/services/libassistant/display_controller.h
@@ -7,9 +7,9 @@ #include "base/sequence_checker.h" #include "base/task/sequenced_task_runner.h" +#include "chromeos/ash/services/libassistant/grpc/assistant_client_observer.h" #include "chromeos/assistant/internal/action/assistant_action_observer.h" #include "chromeos/assistant/internal/libassistant/shared_headers.h" -#include "chromeos/services/libassistant/grpc/assistant_client_observer.h" #include "chromeos/services/libassistant/public/mojom/display_controller.mojom.h" #include "mojo/public/cpp/bindings/receiver.h" #include "mojo/public/cpp/bindings/remote_set.h"
diff --git a/chromeos/ash/services/libassistant/display_controller_unittest.cc b/chromeos/ash/services/libassistant/display_controller_unittest.cc index e419b4e..275720d 100644 --- a/chromeos/ash/services/libassistant/display_controller_unittest.cc +++ b/chromeos/ash/services/libassistant/display_controller_unittest.cc
@@ -6,8 +6,8 @@ #include "base/run_loop.h" #include "base/test/task_environment.h" #include "chromeos/ash/components/assistant/test_support/expect_utils.h" +#include "chromeos/ash/services/libassistant/grpc/assistant_client.h" #include "chromeos/ash/services/libassistant/test_support/fake_assistant_client.h" -#include "chromeos/services/libassistant/grpc/assistant_client.h" #include "chromeos/services/libassistant/public/mojom/speech_recognition_observer.mojom.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h"
diff --git a/chromeos/services/libassistant/grpc/BUILD.gn b/chromeos/ash/services/libassistant/grpc/BUILD.gn similarity index 96% rename from chromeos/services/libassistant/grpc/BUILD.gn rename to chromeos/ash/services/libassistant/grpc/BUILD.gn index 2e0dc0b..121e9d8 100644 --- a/chromeos/services/libassistant/grpc/BUILD.gn +++ b/chromeos/ash/services/libassistant/grpc/BUILD.gn
@@ -2,6 +2,10 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +import("//build/config/chromeos/ui_mode.gni") + +assert(is_chromeos_ash, "Non ChromeOS builds must not depend on //chromeos/ash") + source_set("assistant_client") { sources = [ "./utils/media_status_utils.cc",
diff --git a/chromeos/services/libassistant/grpc/DEPS b/chromeos/ash/services/libassistant/grpc/DEPS similarity index 100% rename from chromeos/services/libassistant/grpc/DEPS rename to chromeos/ash/services/libassistant/grpc/DEPS
diff --git a/chromeos/services/libassistant/grpc/assistant_client.cc b/chromeos/ash/services/libassistant/grpc/assistant_client.cc similarity index 91% rename from chromeos/services/libassistant/grpc/assistant_client.cc rename to chromeos/ash/services/libassistant/grpc/assistant_client.cc index bec0bfa..15cb72c 100644 --- a/chromeos/services/libassistant/grpc/assistant_client.cc +++ b/chromeos/ash/services/libassistant/grpc/assistant_client.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 "chromeos/services/libassistant/grpc/assistant_client.h" +#include "chromeos/ash/services/libassistant/grpc/assistant_client.h" #include <memory>
diff --git a/chromeos/services/libassistant/grpc/assistant_client.h b/chromeos/ash/services/libassistant/grpc/assistant_client.h similarity index 95% rename from chromeos/services/libassistant/grpc/assistant_client.h rename to chromeos/ash/services/libassistant/grpc/assistant_client.h index 9f4355bb6..8a4d358 100644 --- a/chromeos/services/libassistant/grpc/assistant_client.h +++ b/chromeos/ash/services/libassistant/grpc/assistant_client.h
@@ -2,15 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROMEOS_SERVICES_LIBASSISTANT_GRPC_ASSISTANT_CLIENT_H_ -#define CHROMEOS_SERVICES_LIBASSISTANT_GRPC_ASSISTANT_CLIENT_H_ +#ifndef CHROMEOS_ASH_SERVICES_LIBASSISTANT_GRPC_ASSISTANT_CLIENT_H_ +#define CHROMEOS_ASH_SERVICES_LIBASSISTANT_GRPC_ASSISTANT_CLIENT_H_ #include <memory> #include "base/callback_forward.h" +#include "chromeos/ash/services/libassistant/grpc/external_services/grpc_services_observer.h" +#include "chromeos/ash/services/libassistant/grpc/services_status_observer.h" #include "chromeos/assistant/internal/proto/shared/proto/v2/device_state_event.pb.h" -#include "chromeos/services/libassistant/grpc/external_services/grpc_services_observer.h" -#include "chromeos/services/libassistant/grpc/services_status_observer.h" #include "chromeos/services/libassistant/public/cpp/assistant_timer.h" namespace assistant { @@ -120,7 +120,6 @@ virtual void AddExperimentIds(const std::vector<std::string>& exp_ids) = 0; - // Speaker Id Enrollment methods. virtual void AddSpeakerIdEnrollmentEventObserver( GrpcServicesObserver<OnSpeakerIdEnrollmentEventRequest>* observer) = 0; @@ -242,4 +241,4 @@ } // namespace libassistant } // namespace chromeos -#endif // CHROMEOS_SERVICES_LIBASSISTANT_GRPC_ASSISTANT_CLIENT_H_ +#endif // CHROMEOS_ASH_SERVICES_LIBASSISTANT_GRPC_ASSISTANT_CLIENT_H_
diff --git a/chromeos/services/libassistant/grpc/assistant_client_impl.cc b/chromeos/ash/services/libassistant/grpc/assistant_client_impl.cc similarity index 97% rename from chromeos/services/libassistant/grpc/assistant_client_impl.cc rename to chromeos/ash/services/libassistant/grpc/assistant_client_impl.cc index 9c6e9928..92e23f8 100644 --- a/chromeos/services/libassistant/grpc/assistant_client_impl.cc +++ b/chromeos/ash/services/libassistant/grpc/assistant_client_impl.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 "chromeos/services/libassistant/grpc/assistant_client_impl.h" +#include "chromeos/ash/services/libassistant/grpc/assistant_client_impl.h" #include <memory> @@ -15,6 +15,11 @@ #include "base/threading/sequenced_task_runner_handle.h" #include "chromeos/ash/services/assistant/public/cpp/features.h" #include "chromeos/ash/services/libassistant/callback_utils.h" +#include "chromeos/ash/services/libassistant/grpc/assistant_client_v1.h" +#include "chromeos/ash/services/libassistant/grpc/external_services/action_service.h" +#include "chromeos/ash/services/libassistant/grpc/grpc_libassistant_client.h" +#include "chromeos/ash/services/libassistant/grpc/services_status_observer.h" +#include "chromeos/ash/services/libassistant/grpc/utils/timer_utils.h" #include "chromeos/assistant/internal/grpc_transport/request_utils.h" #include "chromeos/assistant/internal/internal_constants.h" #include "chromeos/assistant/internal/internal_util.h" @@ -27,11 +32,6 @@ #include "chromeos/assistant/internal/proto/shared/proto/v2/experiment_interface.pb.h" #include "chromeos/assistant/internal/proto/shared/proto/v2/query_interface.pb.h" #include "chromeos/assistant/internal/proto/shared/proto/v2/speaker_id_enrollment_interface.pb.h" -#include "chromeos/services/libassistant/grpc/assistant_client_v1.h" -#include "chromeos/services/libassistant/grpc/external_services/action_service.h" -#include "chromeos/services/libassistant/grpc/grpc_libassistant_client.h" -#include "chromeos/services/libassistant/grpc/services_status_observer.h" -#include "chromeos/services/libassistant/grpc/utils/timer_utils.h" namespace chromeos { namespace libassistant {
diff --git a/chromeos/services/libassistant/grpc/assistant_client_impl.h b/chromeos/ash/services/libassistant/grpc/assistant_client_impl.h similarity index 90% rename from chromeos/services/libassistant/grpc/assistant_client_impl.h rename to chromeos/ash/services/libassistant/grpc/assistant_client_impl.h index 0d7eb33..8ed7c7d7 100644 --- a/chromeos/services/libassistant/grpc/assistant_client_impl.h +++ b/chromeos/ash/services/libassistant/grpc/assistant_client_impl.h
@@ -2,17 +2,17 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROMEOS_SERVICES_LIBASSISTANT_GRPC_ASSISTANT_CLIENT_IMPL_H_ -#define CHROMEOS_SERVICES_LIBASSISTANT_GRPC_ASSISTANT_CLIENT_IMPL_H_ +#ifndef CHROMEOS_ASH_SERVICES_LIBASSISTANT_GRPC_ASSISTANT_CLIENT_IMPL_H_ +#define CHROMEOS_ASH_SERVICES_LIBASSISTANT_GRPC_ASSISTANT_CLIENT_IMPL_H_ #include <memory> #include <string> #include "base/callback_forward.h" #include "base/scoped_observation.h" -#include "chromeos/services/libassistant/grpc/assistant_client_v1.h" -#include "chromeos/services/libassistant/grpc/external_services/grpc_services_initializer.h" -#include "chromeos/services/libassistant/grpc/services_status_provider.h" +#include "chromeos/ash/services/libassistant/grpc/assistant_client_v1.h" +#include "chromeos/ash/services/libassistant/grpc/external_services/grpc_services_initializer.h" +#include "chromeos/ash/services/libassistant/grpc/services_status_provider.h" namespace chromeos { namespace libassistant { @@ -121,4 +121,4 @@ } // namespace libassistant } // namespace chromeos -#endif // CHROMEOS_SERVICES_LIBASSISTANT_GRPC_ASSISTANT_CLIENT_IMPL_H_ +#endif // CHROMEOS_ASH_SERVICES_LIBASSISTANT_GRPC_ASSISTANT_CLIENT_IMPL_H_
diff --git a/chromeos/services/libassistant/grpc/assistant_client_observer.h b/chromeos/ash/services/libassistant/grpc/assistant_client_observer.h similarity index 89% rename from chromeos/services/libassistant/grpc/assistant_client_observer.h rename to chromeos/ash/services/libassistant/grpc/assistant_client_observer.h index 1a6c82f4..6dab024 100644 --- a/chromeos/services/libassistant/grpc/assistant_client_observer.h +++ b/chromeos/ash/services/libassistant/grpc/assistant_client_observer.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROMEOS_SERVICES_LIBASSISTANT_GRPC_ASSISTANT_CLIENT_OBSERVER_H_ -#define CHROMEOS_SERVICES_LIBASSISTANT_GRPC_ASSISTANT_CLIENT_OBSERVER_H_ +#ifndef CHROMEOS_ASH_SERVICES_LIBASSISTANT_GRPC_ASSISTANT_CLIENT_OBSERVER_H_ +#define CHROMEOS_ASH_SERVICES_LIBASSISTANT_GRPC_ASSISTANT_CLIENT_OBSERVER_H_ #include "base/component_export.h" #include "base/observer_list_types.h" @@ -51,4 +51,4 @@ } // namespace libassistant } // namespace chromeos -#endif // CHROMEOS_SERVICES_LIBASSISTANT_GRPC_ASSISTANT_CLIENT_OBSERVER_H_ +#endif // CHROMEOS_ASH_SERVICES_LIBASSISTANT_GRPC_ASSISTANT_CLIENT_OBSERVER_H_
diff --git a/chromeos/services/libassistant/grpc/assistant_client_v1.cc b/chromeos/ash/services/libassistant/grpc/assistant_client_v1.cc similarity index 98% rename from chromeos/services/libassistant/grpc/assistant_client_v1.cc rename to chromeos/ash/services/libassistant/grpc/assistant_client_v1.cc index e58fa44..5b1fb71 100644 --- a/chromeos/services/libassistant/grpc/assistant_client_v1.cc +++ b/chromeos/ash/services/libassistant/grpc/assistant_client_v1.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 "chromeos/services/libassistant/grpc/assistant_client_v1.h" +#include "chromeos/ash/services/libassistant/grpc/assistant_client_v1.h" #include <string> @@ -15,6 +15,10 @@ #include "base/time/time.h" #include "chromeos/ash/services/assistant/public/cpp/features.h" #include "chromeos/ash/services/libassistant/callback_utils.h" +#include "chromeos/ash/services/libassistant/grpc/assistant_client.h" +#include "chromeos/ash/services/libassistant/grpc/utils/media_status_utils.h" +#include "chromeos/ash/services/libassistant/grpc/utils/settings_utils.h" +#include "chromeos/ash/services/libassistant/grpc/utils/timer_utils.h" #include "chromeos/assistant/internal/grpc_transport/request_utils.h" #include "chromeos/assistant/internal/internal_util.h" #include "chromeos/assistant/internal/libassistant/shared_headers.h" @@ -27,10 +31,6 @@ #include "chromeos/assistant/internal/proto/shared/proto/v2/display_interface.pb.h" #include "chromeos/assistant/internal/proto/shared/proto/v2/speaker_id_enrollment_event.pb.h" #include "chromeos/assistant/internal/proto/shared/proto/v2/speaker_id_enrollment_interface.pb.h" -#include "chromeos/services/libassistant/grpc/assistant_client.h" -#include "chromeos/services/libassistant/grpc/utils/media_status_utils.h" -#include "chromeos/services/libassistant/grpc/utils/settings_utils.h" -#include "chromeos/services/libassistant/grpc/utils/timer_utils.h" #include "chromeos/services/libassistant/public/cpp/assistant_timer.h" namespace chromeos {
diff --git a/chromeos/services/libassistant/grpc/assistant_client_v1.h b/chromeos/ash/services/libassistant/grpc/assistant_client_v1.h similarity index 95% rename from chromeos/services/libassistant/grpc/assistant_client_v1.h rename to chromeos/ash/services/libassistant/grpc/assistant_client_v1.h index 002ad3a..1080a04 100644 --- a/chromeos/services/libassistant/grpc/assistant_client_v1.h +++ b/chromeos/ash/services/libassistant/grpc/assistant_client_v1.h
@@ -2,15 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROMEOS_SERVICES_LIBASSISTANT_GRPC_ASSISTANT_CLIENT_V1_H_ -#define CHROMEOS_SERVICES_LIBASSISTANT_GRPC_ASSISTANT_CLIENT_V1_H_ +#ifndef CHROMEOS_ASH_SERVICES_LIBASSISTANT_GRPC_ASSISTANT_CLIENT_V1_H_ +#define CHROMEOS_ASH_SERVICES_LIBASSISTANT_GRPC_ASSISTANT_CLIENT_V1_H_ #include "base/callback.h" #include "base/callback_forward.h" #include "base/memory/weak_ptr.h" #include "base/observer_list.h" +#include "chromeos/ash/services/libassistant/grpc/assistant_client.h" #include "chromeos/assistant/internal/libassistant/shared_headers.h" -#include "chromeos/services/libassistant/grpc/assistant_client.h" #include "third_party/abseil-cpp/absl/types/optional.h" namespace assistant_client { @@ -163,4 +163,4 @@ } // namespace libassistant } // namespace chromeos -#endif // CHROMEOS_SERVICES_LIBASSISTANT_GRPC_ASSISTANT_CLIENT_V1_H_ +#endif // CHROMEOS_ASH_SERVICES_LIBASSISTANT_GRPC_ASSISTANT_CLIENT_V1_H_
diff --git a/chromeos/services/libassistant/grpc/assistant_client_v1_unittests.cc b/chromeos/ash/services/libassistant/grpc/assistant_client_v1_unittests.cc similarity index 96% rename from chromeos/services/libassistant/grpc/assistant_client_v1_unittests.cc rename to chromeos/ash/services/libassistant/grpc/assistant_client_v1_unittests.cc index 032c85b..70c59c1 100644 --- a/chromeos/services/libassistant/grpc/assistant_client_v1_unittests.cc +++ b/chromeos/ash/services/libassistant/grpc/assistant_client_v1_unittests.cc
@@ -6,10 +6,10 @@ #include "base/callback_helpers.h" #include "base/test/task_environment.h" +#include "chromeos/ash/services/libassistant/grpc/assistant_client_v1.h" +#include "chromeos/ash/services/libassistant/grpc/services_status_observer.h" #include "chromeos/assistant/internal/test_support/fake_assistant_manager.h" #include "chromeos/assistant/internal/test_support/fake_assistant_manager_internal.h" -#include "chromeos/services/libassistant/grpc/assistant_client_v1.h" -#include "chromeos/services/libassistant/grpc/services_status_observer.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h"
diff --git a/chromeos/services/libassistant/grpc/async_service_driver.h b/chromeos/ash/services/libassistant/grpc/async_service_driver.h similarity index 81% rename from chromeos/services/libassistant/grpc/async_service_driver.h rename to chromeos/ash/services/libassistant/grpc/async_service_driver.h index 8f9b4ca5..c5556d3 100644 --- a/chromeos/services/libassistant/grpc/async_service_driver.h +++ b/chromeos/ash/services/libassistant/grpc/async_service_driver.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROMEOS_SERVICES_LIBASSISTANT_GRPC_ASYNC_SERVICE_DRIVER_H_ -#define CHROMEOS_SERVICES_LIBASSISTANT_GRPC_ASYNC_SERVICE_DRIVER_H_ +#ifndef CHROMEOS_ASH_SERVICES_LIBASSISTANT_GRPC_ASYNC_SERVICE_DRIVER_H_ +#define CHROMEOS_ASH_SERVICES_LIBASSISTANT_GRPC_ASYNC_SERVICE_DRIVER_H_ #include "base/check.h" #include "base/logging.h" @@ -34,4 +34,4 @@ } // namespace libassistant } // namespace chromeos -#endif // CHROMEOS_SERVICES_LIBASSISTANT_GRPC_ASYNC_SERVICE_DRIVER_H_ +#endif // CHROMEOS_ASH_SERVICES_LIBASSISTANT_GRPC_ASYNC_SERVICE_DRIVER_H_
diff --git a/chromeos/services/libassistant/grpc/external_services/BUILD.gn b/chromeos/ash/services/libassistant/grpc/external_services/BUILD.gn similarity index 70% rename from chromeos/services/libassistant/grpc/external_services/BUILD.gn rename to chromeos/ash/services/libassistant/grpc/external_services/BUILD.gn index 9f6920ba..b18b63c7 100644 --- a/chromeos/services/libassistant/grpc/external_services/BUILD.gn +++ b/chromeos/ash/services/libassistant/grpc/external_services/BUILD.gn
@@ -2,6 +2,10 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +import("//build/config/chromeos/ui_mode.gni") + +assert(is_chromeos_ash, "Non ChromeOS builds must not depend on //chromeos/ash") + source_set("grpc_services_initializer") { sources = [ "action_args.cc", @@ -20,13 +24,13 @@ ":heartbeat_event_handler_driver", "//base", "//chromeos/ash/services/libassistant:callback_utils", + "//chromeos/ash/services/libassistant/grpc:grpc_client", + "//chromeos/ash/services/libassistant/grpc:grpc_service", + "//chromeos/ash/services/libassistant/grpc:grpc_util", + "//chromeos/ash/services/libassistant/grpc:http_connection_client", + "//chromeos/ash/services/libassistant/grpc:libassistant_client", "//chromeos/assistant/internal", "//chromeos/assistant/internal:libassistant_shared_headers", - "//chromeos/services/libassistant/grpc:grpc_client", - "//chromeos/services/libassistant/grpc:grpc_service", - "//chromeos/services/libassistant/grpc:grpc_util", - "//chromeos/services/libassistant/grpc:http_connection_client", - "//chromeos/services/libassistant/grpc:libassistant_client", "//third_party/grpc:grpc++", ] } @@ -45,10 +49,10 @@ deps = [ "//base", + "//chromeos/ash/services/libassistant/grpc:grpc_client", + "//chromeos/ash/services/libassistant/grpc:libassistant_client", "//chromeos/assistant/internal/proto:assistant", "//chromeos/assistant/internal/proto:assistant_grpc", - "//chromeos/services/libassistant/grpc:grpc_client", - "//chromeos/services/libassistant/grpc:libassistant_client", ] } @@ -66,7 +70,7 @@ deps = [ ":grpc_services_observer", "//base", - "//chromeos/services/libassistant/grpc:grpc_service", + "//chromeos/ash/services/libassistant/grpc:grpc_service", "//third_party/grpc:grpc++", ] }
diff --git a/chromeos/services/libassistant/grpc/external_services/action_args.cc b/chromeos/ash/services/libassistant/grpc/external_services/action_args.cc similarity index 96% rename from chromeos/services/libassistant/grpc/external_services/action_args.cc rename to chromeos/ash/services/libassistant/grpc/external_services/action_args.cc index 02512e5..c2d45a4b 100644 --- a/chromeos/services/libassistant/grpc/external_services/action_args.cc +++ b/chromeos/ash/services/libassistant/grpc/external_services/action_args.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 "chromeos/services/libassistant/grpc/external_services/action_args.h" +#include "chromeos/ash/services/libassistant/grpc/external_services/action_args.h" #include "chromeos/assistant/internal/proto/shared/proto/v2/delegate/action_interface.pb.h"
diff --git a/chromeos/services/libassistant/grpc/external_services/action_args.h b/chromeos/ash/services/libassistant/grpc/external_services/action_args.h similarity index 86% rename from chromeos/services/libassistant/grpc/external_services/action_args.h rename to chromeos/ash/services/libassistant/grpc/external_services/action_args.h index c25436ce..9b40a10a 100644 --- a/chromeos/services/libassistant/grpc/external_services/action_args.h +++ b/chromeos/ash/services/libassistant/grpc/external_services/action_args.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROMEOS_SERVICES_LIBASSISTANT_GRPC_EXTERNAL_SERVICES_ACTION_ARGS_H_ -#define CHROMEOS_SERVICES_LIBASSISTANT_GRPC_EXTERNAL_SERVICES_ACTION_ARGS_H_ +#ifndef CHROMEOS_ASH_SERVICES_LIBASSISTANT_GRPC_EXTERNAL_SERVICES_ACTION_ARGS_H_ +#define CHROMEOS_ASH_SERVICES_LIBASSISTANT_GRPC_EXTERNAL_SERVICES_ACTION_ARGS_H_ #include "chromeos/assistant/internal/libassistant/shared_headers.h" #include "chromeos/assistant/internal/proto/shared/proto/client_op.pb.h" @@ -48,4 +48,4 @@ } // namespace libassistant } // namespace chromeos -#endif // CHROMEOS_SERVICES_LIBASSISTANT_GRPC_EXTERNAL_SERVICES_ACTION_ARGS_H_ +#endif // CHROMEOS_ASH_SERVICES_LIBASSISTANT_GRPC_EXTERNAL_SERVICES_ACTION_ARGS_H_
diff --git a/chromeos/services/libassistant/grpc/external_services/action_service.cc b/chromeos/ash/services/libassistant/grpc/external_services/action_service.cc similarity index 97% rename from chromeos/services/libassistant/grpc/external_services/action_service.cc rename to chromeos/ash/services/libassistant/grpc/external_services/action_service.cc index b27cf5f7..ae5981c7d 100644 --- a/chromeos/services/libassistant/grpc/external_services/action_service.cc +++ b/chromeos/ash/services/libassistant/grpc/external_services/action_service.cc
@@ -2,15 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chromeos/services/libassistant/grpc/external_services/action_service.h" +#include "chromeos/ash/services/libassistant/grpc/external_services/action_service.h" #include "base/memory/ptr_util.h" #include "base/strings/string_number_conversions.h" #include "chromeos/ash/services/libassistant/callback_utils.h" +#include "chromeos/ash/services/libassistant/grpc/external_services/action_args.h" +#include "chromeos/ash/services/libassistant/grpc/grpc_libassistant_client.h" #include "chromeos/assistant/internal/grpc_transport/request_utils.h" #include "chromeos/assistant/internal/internal_constants.h" -#include "chromeos/services/libassistant/grpc/external_services/action_args.h" -#include "chromeos/services/libassistant/grpc/grpc_libassistant_client.h" namespace chromeos { namespace libassistant {
diff --git a/chromeos/services/libassistant/grpc/external_services/action_service.h b/chromeos/ash/services/libassistant/grpc/external_services/action_service.h similarity index 92% rename from chromeos/services/libassistant/grpc/external_services/action_service.h rename to chromeos/ash/services/libassistant/grpc/external_services/action_service.h index 04967df..a4cf611 100644 --- a/chromeos/services/libassistant/grpc/external_services/action_service.h +++ b/chromeos/ash/services/libassistant/grpc/external_services/action_service.h
@@ -2,19 +2,19 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROMEOS_SERVICES_LIBASSISTANT_GRPC_EXTERNAL_SERVICES_ACTION_SERVICE_H_ -#define CHROMEOS_SERVICES_LIBASSISTANT_GRPC_EXTERNAL_SERVICES_ACTION_SERVICE_H_ +#ifndef CHROMEOS_ASH_SERVICES_LIBASSISTANT_GRPC_EXTERNAL_SERVICES_ACTION_SERVICE_H_ +#define CHROMEOS_ASH_SERVICES_LIBASSISTANT_GRPC_EXTERNAL_SERVICES_ACTION_SERVICE_H_ #include "base/containers/flat_map.h" #include "base/memory/weak_ptr.h" #include "base/sequence_checker.h" #include "base/task/sequenced_task_runner.h" +#include "chromeos/ash/services/libassistant/grpc/async_service_driver.h" +#include "chromeos/ash/services/libassistant/grpc/rpc_method_driver.h" #include "chromeos/assistant/internal/libassistant/shared_headers.h" #include "chromeos/assistant/internal/proto/shared/proto/v2/delegate/action_interface.pb.h" #include "chromeos/assistant/internal/proto/shared/proto/v2/delegate/action_service.grpc.pb.h" #include "chromeos/assistant/internal/proto/shared/proto/v2/query_interface.pb.h" -#include "chromeos/services/libassistant/grpc/async_service_driver.h" -#include "chromeos/services/libassistant/grpc/rpc_method_driver.h" namespace assistant { namespace api { @@ -129,4 +129,4 @@ } // namespace libassistant } // namespace chromeos -#endif // CHROMEOS_SERVICES_LIBASSISTANT_GRPC_EXTERNAL_SERVICES_ACTION_SERVICE_H_ +#endif // CHROMEOS_ASH_SERVICES_LIBASSISTANT_GRPC_EXTERNAL_SERVICES_ACTION_SERVICE_H_
diff --git a/chromeos/services/libassistant/grpc/external_services/customer_registration_client.cc b/chromeos/ash/services/libassistant/grpc/external_services/customer_registration_client.cc similarity index 95% rename from chromeos/services/libassistant/grpc/external_services/customer_registration_client.cc rename to chromeos/ash/services/libassistant/grpc/external_services/customer_registration_client.cc index 9837306..6667c4e7 100644 --- a/chromeos/services/libassistant/grpc/external_services/customer_registration_client.cc +++ b/chromeos/ash/services/libassistant/grpc/external_services/customer_registration_client.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 "chromeos/services/libassistant/grpc/external_services/customer_registration_client.h" +#include "chromeos/ash/services/libassistant/grpc/external_services/customer_registration_client.h" #include "base/bind.h" #include "base/check_op.h" @@ -11,10 +11,10 @@ #include "base/task/bind_post_task.h" #include "base/threading/thread_task_runner_handle.h" #include "base/time/time.h" +#include "chromeos/ash/services/libassistant/grpc/grpc_libassistant_client.h" +#include "chromeos/ash/services/libassistant/grpc/grpc_state.h" #include "chromeos/assistant/internal/proto/shared/proto/v2/customer_registration_service.grpc.pb.h" #include "chromeos/assistant/internal/proto/shared/proto/v2/delegate/event_handler_service.grpc.pb.h" -#include "chromeos/services/libassistant/grpc/grpc_libassistant_client.h" -#include "chromeos/services/libassistant/grpc/grpc_state.h" namespace chromeos { namespace libassistant {
diff --git a/chromeos/services/libassistant/grpc/external_services/customer_registration_client.h b/chromeos/ash/services/libassistant/grpc/external_services/customer_registration_client.h similarity index 92% rename from chromeos/services/libassistant/grpc/external_services/customer_registration_client.h rename to chromeos/ash/services/libassistant/grpc/external_services/customer_registration_client.h index 7de64f0..ff765d0d 100644 --- a/chromeos/services/libassistant/grpc/external_services/customer_registration_client.h +++ b/chromeos/ash/services/libassistant/grpc/external_services/customer_registration_client.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROMEOS_SERVICES_LIBASSISTANT_GRPC_EXTERNAL_SERVICES_CUSTOMER_REGISTRATION_CLIENT_H_ -#define CHROMEOS_SERVICES_LIBASSISTANT_GRPC_EXTERNAL_SERVICES_CUSTOMER_REGISTRATION_CLIENT_H_ +#ifndef CHROMEOS_ASH_SERVICES_LIBASSISTANT_GRPC_EXTERNAL_SERVICES_CUSTOMER_REGISTRATION_CLIENT_H_ +#define CHROMEOS_ASH_SERVICES_LIBASSISTANT_GRPC_EXTERNAL_SERVICES_CUSTOMER_REGISTRATION_CLIENT_H_ #include <memory> #include <string> @@ -99,4 +99,4 @@ } // namespace libassistant } // namespace chromeos -#endif // CHROMEOS_SERVICES_LIBASSISTANT_GRPC_EXTERNAL_SERVICES_CUSTOMER_REGISTRATION_CLIENT_H_ +#endif // CHROMEOS_ASH_SERVICES_LIBASSISTANT_GRPC_EXTERNAL_SERVICES_CUSTOMER_REGISTRATION_CLIENT_H_
diff --git a/chromeos/services/libassistant/grpc/external_services/event_handler_driver.cc b/chromeos/ash/services/libassistant/grpc/external_services/event_handler_driver.cc similarity index 97% rename from chromeos/services/libassistant/grpc/external_services/event_handler_driver.cc rename to chromeos/ash/services/libassistant/grpc/external_services/event_handler_driver.cc index a19df26..c4f2b2d 100644 --- a/chromeos/services/libassistant/grpc/external_services/event_handler_driver.cc +++ b/chromeos/ash/services/libassistant/grpc/external_services/event_handler_driver.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 "chromeos/services/libassistant/grpc/external_services/event_handler_driver.h" +#include "chromeos/ash/services/libassistant/grpc/external_services/event_handler_driver.h" #include "chromeos/assistant/internal/libassistant_util.h" #include "chromeos/assistant/internal/proto/shared/proto/v2/event_notification_interface.pb.h"
diff --git a/chromeos/services/libassistant/grpc/external_services/event_handler_driver.h b/chromeos/ash/services/libassistant/grpc/external_services/event_handler_driver.h similarity index 85% rename from chromeos/services/libassistant/grpc/external_services/event_handler_driver.h rename to chromeos/ash/services/libassistant/grpc/external_services/event_handler_driver.h index 23cc0cf..27b97d2 100644 --- a/chromeos/services/libassistant/grpc/external_services/event_handler_driver.h +++ b/chromeos/ash/services/libassistant/grpc/external_services/event_handler_driver.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROMEOS_SERVICES_LIBASSISTANT_GRPC_EXTERNAL_SERVICES_EVENT_HANDLER_DRIVER_H_ -#define CHROMEOS_SERVICES_LIBASSISTANT_GRPC_EXTERNAL_SERVICES_EVENT_HANDLER_DRIVER_H_ +#ifndef CHROMEOS_ASH_SERVICES_LIBASSISTANT_GRPC_EXTERNAL_SERVICES_EVENT_HANDLER_DRIVER_H_ +#define CHROMEOS_ASH_SERVICES_LIBASSISTANT_GRPC_EXTERNAL_SERVICES_EVENT_HANDLER_DRIVER_H_ #include <memory> #include <string> @@ -11,12 +11,12 @@ #include "base/memory/weak_ptr.h" #include "base/observer_list.h" #include "base/sequence_checker.h" +#include "chromeos/ash/services/libassistant/grpc/async_service_driver.h" +#include "chromeos/ash/services/libassistant/grpc/external_services/grpc_services_observer.h" +#include "chromeos/ash/services/libassistant/grpc/grpc_libassistant_client.h" +#include "chromeos/ash/services/libassistant/grpc/rpc_method_driver.h" #include "chromeos/assistant/internal/proto/shared/proto/v2/delegate/event_handler_service.grpc.pb.h" #include "chromeos/assistant/internal/proto/shared/proto/v2/event_notification_interface.pb.h" -#include "chromeos/services/libassistant/grpc/async_service_driver.h" -#include "chromeos/services/libassistant/grpc/external_services/grpc_services_observer.h" -#include "chromeos/services/libassistant/grpc/grpc_libassistant_client.h" -#include "chromeos/services/libassistant/grpc/rpc_method_driver.h" #include "third_party/grpc/src/include/grpcpp/grpcpp.h" namespace chromeos { @@ -48,11 +48,11 @@ friend class EventHandlerDriver; }; - typedef typename UnwrapTypeFromInterface<decltype( - &THandlerInterface::AsyncService::OnEventFromLibas)>::ResponseType - ResponseType; - typedef typename UnwrapTypeFromInterface<decltype( - &THandlerInterface::AsyncService::OnEventFromLibas)>::RequestType + typedef typename UnwrapTypeFromInterface< + decltype(&THandlerInterface::AsyncService::OnEventFromLibas)>:: + ResponseType ResponseType; + typedef typename UnwrapTypeFromInterface< + decltype(&THandlerInterface::AsyncService::OnEventFromLibas)>::RequestType RequestType; using EventObserverType = GrpcServicesObserver<RequestType>; @@ -154,4 +154,4 @@ } // namespace libassistant } // namespace chromeos -#endif // CHROMEOS_SERVICES_LIBASSISTANT_GRPC_EXTERNAL_SERVICES_EVENT_HANDLER_DRIVER_H_i +#endif // CHROMEOS_ASH_SERVICES_LIBASSISTANT_GRPC_EXTERNAL_SERVICES_EVENT_HANDLER_DRIVER_H_i
diff --git a/chromeos/services/libassistant/grpc/external_services/grpc_services_initializer.cc b/chromeos/ash/services/libassistant/grpc/external_services/grpc_services_initializer.cc similarity index 93% rename from chromeos/services/libassistant/grpc/external_services/grpc_services_initializer.cc rename to chromeos/ash/services/libassistant/grpc/external_services/grpc_services_initializer.cc index 52076c6..2bbb8298 100644 --- a/chromeos/services/libassistant/grpc/external_services/grpc_services_initializer.cc +++ b/chromeos/ash/services/libassistant/grpc/external_services/grpc_services_initializer.cc
@@ -2,21 +2,21 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chromeos/services/libassistant/grpc/external_services/grpc_services_initializer.h" +#include "chromeos/ash/services/libassistant/grpc/external_services/grpc_services_initializer.h" #include <memory> #include "base/time/time.h" +#include "chromeos/ash/services/libassistant/grpc/external_services/action_service.h" +#include "chromeos/ash/services/libassistant/grpc/external_services/customer_registration_client.h" +#include "chromeos/ash/services/libassistant/grpc/external_services/heartbeat_event_handler_driver.h" +#include "chromeos/ash/services/libassistant/grpc/grpc_http_connection_client.h" +#include "chromeos/ash/services/libassistant/grpc/grpc_libassistant_client.h" +#include "chromeos/ash/services/libassistant/grpc/grpc_util.h" #include "chromeos/assistant/internal/internal_constants.h" #include "chromeos/assistant/internal/libassistant/shared_headers.h" #include "chromeos/assistant/internal/proto/shared/proto/v2/delegate/event_handler_interface.pb.h" #include "chromeos/assistant/internal/proto/shared/proto/v2/delegate/event_handler_service.grpc.pb.h" -#include "chromeos/services/libassistant/grpc/external_services/action_service.h" -#include "chromeos/services/libassistant/grpc/external_services/customer_registration_client.h" -#include "chromeos/services/libassistant/grpc/external_services/heartbeat_event_handler_driver.h" -#include "chromeos/services/libassistant/grpc/grpc_http_connection_client.h" -#include "chromeos/services/libassistant/grpc/grpc_libassistant_client.h" -#include "chromeos/services/libassistant/grpc/grpc_util.h" #include "third_party/grpc/src/include/grpc/grpc_security_constants.h" #include "third_party/grpc/src/include/grpc/impl/codegen/grpc_types.h" #include "third_party/grpc/src/include/grpcpp/create_channel.h"
diff --git a/chromeos/services/libassistant/grpc/external_services/grpc_services_initializer.h b/chromeos/ash/services/libassistant/grpc/external_services/grpc_services_initializer.h similarity index 86% rename from chromeos/services/libassistant/grpc/external_services/grpc_services_initializer.h rename to chromeos/ash/services/libassistant/grpc/external_services/grpc_services_initializer.h index 905e961..1d9c875 100644 --- a/chromeos/services/libassistant/grpc/external_services/grpc_services_initializer.h +++ b/chromeos/ash/services/libassistant/grpc/external_services/grpc_services_initializer.h
@@ -2,20 +2,20 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROMEOS_SERVICES_LIBASSISTANT_GRPC_EXTERNAL_SERVICES_GRPC_SERVICES_INITIALIZER_H_ -#define CHROMEOS_SERVICES_LIBASSISTANT_GRPC_EXTERNAL_SERVICES_GRPC_SERVICES_INITIALIZER_H_ +#ifndef CHROMEOS_ASH_SERVICES_LIBASSISTANT_GRPC_EXTERNAL_SERVICES_GRPC_SERVICES_INITIALIZER_H_ +#define CHROMEOS_ASH_SERVICES_LIBASSISTANT_GRPC_EXTERNAL_SERVICES_GRPC_SERVICES_INITIALIZER_H_ #include <memory> #include <string> #include "base/scoped_observation.h" -#include "chromeos/services/libassistant/grpc/external_services/customer_registration_client.h" -#include "chromeos/services/libassistant/grpc/external_services/event_handler_driver.h" -#include "chromeos/services/libassistant/grpc/external_services/grpc_services_observer.h" -#include "chromeos/services/libassistant/grpc/external_services/heartbeat_event_handler_driver.h" -#include "chromeos/services/libassistant/grpc/grpc_client_thread.h" -#include "chromeos/services/libassistant/grpc/services_initializer_base.h" -#include "chromeos/services/libassistant/grpc/services_status_provider.h" +#include "chromeos/ash/services/libassistant/grpc/external_services/customer_registration_client.h" +#include "chromeos/ash/services/libassistant/grpc/external_services/event_handler_driver.h" +#include "chromeos/ash/services/libassistant/grpc/external_services/grpc_services_observer.h" +#include "chromeos/ash/services/libassistant/grpc/external_services/heartbeat_event_handler_driver.h" +#include "chromeos/ash/services/libassistant/grpc/grpc_client_thread.h" +#include "chromeos/ash/services/libassistant/grpc/services_initializer_base.h" +#include "chromeos/ash/services/libassistant/grpc/services_status_provider.h" #include "third_party/grpc/src/include/grpcpp/server_builder.h" namespace assistant { @@ -168,4 +168,4 @@ } // namespace libassistant } // namespace chromeos -#endif // CHROMEOS_SERVICES_LIBASSISTANT_GRPC_EXTERNAL_SERVICES_GRPC_SERVICES_INITIALIZER_H_ +#endif // CHROMEOS_ASH_SERVICES_LIBASSISTANT_GRPC_EXTERNAL_SERVICES_GRPC_SERVICES_INITIALIZER_H_
diff --git a/chromeos/services/libassistant/grpc/external_services/grpc_services_observer.h b/chromeos/ash/services/libassistant/grpc/external_services/grpc_services_observer.h similarity index 69% rename from chromeos/services/libassistant/grpc/external_services/grpc_services_observer.h rename to chromeos/ash/services/libassistant/grpc/external_services/grpc_services_observer.h index bd2103c..0c80b81 100644 --- a/chromeos/services/libassistant/grpc/external_services/grpc_services_observer.h +++ b/chromeos/ash/services/libassistant/grpc/external_services/grpc_services_observer.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROMEOS_SERVICES_LIBASSISTANT_GRPC_EXTERNAL_SERVICES_GRPC_SERVICES_OBSERVER_H_ -#define CHROMEOS_SERVICES_LIBASSISTANT_GRPC_EXTERNAL_SERVICES_GRPC_SERVICES_OBSERVER_H_ +#ifndef CHROMEOS_ASH_SERVICES_LIBASSISTANT_GRPC_EXTERNAL_SERVICES_GRPC_SERVICES_OBSERVER_H_ +#define CHROMEOS_ASH_SERVICES_LIBASSISTANT_GRPC_EXTERNAL_SERVICES_GRPC_SERVICES_OBSERVER_H_ #include "base/observer_list_types.h" @@ -24,4 +24,4 @@ } // namespace libassistant } // namespace chromeos -#endif // CHROMEOS_SERVICES_LIBASSISTANT_GRPC_EXTERNAL_SERVICES_GRPC_SERVICES_OBSERVER_H_ +#endif // CHROMEOS_ASH_SERVICES_LIBASSISTANT_GRPC_EXTERNAL_SERVICES_GRPC_SERVICES_OBSERVER_H_
diff --git a/chromeos/services/libassistant/grpc/external_services/heartbeat_event_handler_driver.cc b/chromeos/ash/services/libassistant/grpc/external_services/heartbeat_event_handler_driver.cc similarity index 96% rename from chromeos/services/libassistant/grpc/external_services/heartbeat_event_handler_driver.cc rename to chromeos/ash/services/libassistant/grpc/external_services/heartbeat_event_handler_driver.cc index ba37f8b7..698c43f 100644 --- a/chromeos/services/libassistant/grpc/external_services/heartbeat_event_handler_driver.cc +++ b/chromeos/ash/services/libassistant/grpc/external_services/heartbeat_event_handler_driver.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 "chromeos/services/libassistant/grpc/external_services/heartbeat_event_handler_driver.h" +#include "chromeos/ash/services/libassistant/grpc/external_services/heartbeat_event_handler_driver.h" #include <utility>
diff --git a/chromeos/services/libassistant/grpc/external_services/heartbeat_event_handler_driver.h b/chromeos/ash/services/libassistant/grpc/external_services/heartbeat_event_handler_driver.h similarity index 83% rename from chromeos/services/libassistant/grpc/external_services/heartbeat_event_handler_driver.h rename to chromeos/ash/services/libassistant/grpc/external_services/heartbeat_event_handler_driver.h index c8c208c..bb99c706 100644 --- a/chromeos/services/libassistant/grpc/external_services/heartbeat_event_handler_driver.h +++ b/chromeos/ash/services/libassistant/grpc/external_services/heartbeat_event_handler_driver.h
@@ -2,18 +2,18 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROMEOS_SERVICES_LIBASSISTANT_GRPC_EXTERNAL_SERVICES_HEARTBEAT_EVENT_HANDLER_DRIVER_H_ -#define CHROMEOS_SERVICES_LIBASSISTANT_GRPC_EXTERNAL_SERVICES_HEARTBEAT_EVENT_HANDLER_DRIVER_H_ +#ifndef CHROMEOS_ASH_SERVICES_LIBASSISTANT_GRPC_EXTERNAL_SERVICES_HEARTBEAT_EVENT_HANDLER_DRIVER_H_ +#define CHROMEOS_ASH_SERVICES_LIBASSISTANT_GRPC_EXTERNAL_SERVICES_HEARTBEAT_EVENT_HANDLER_DRIVER_H_ #include <memory> #include "base/memory/scoped_refptr.h" #include "base/memory/weak_ptr.h" #include "base/observer_list.h" +#include "chromeos/ash/services/libassistant/grpc/async_service_driver.h" +#include "chromeos/ash/services/libassistant/grpc/external_services/grpc_services_observer.h" +#include "chromeos/ash/services/libassistant/grpc/rpc_method_driver.h" #include "chromeos/assistant/internal/proto/shared/proto/v2/delegate/event_handler_service.grpc.pb.h" -#include "chromeos/services/libassistant/grpc/async_service_driver.h" -#include "chromeos/services/libassistant/grpc/external_services/grpc_services_observer.h" -#include "chromeos/services/libassistant/grpc/rpc_method_driver.h" namespace assistant { namespace api { @@ -81,4 +81,4 @@ } // namespace libassistant } // namespace chromeos -#endif // CHROMEOS_SERVICES_LIBASSISTANT_GRPC_EXTERNAL_SERVICES_HEARTBEAT_EVENT_HANDLER_DRIVER_H_ +#endif // CHROMEOS_ASH_SERVICES_LIBASSISTANT_GRPC_EXTERNAL_SERVICES_HEARTBEAT_EVENT_HANDLER_DRIVER_H_
diff --git a/chromeos/services/libassistant/grpc/grpc_client_thread.cc b/chromeos/ash/services/libassistant/grpc/grpc_client_thread.cc similarity index 97% rename from chromeos/services/libassistant/grpc/grpc_client_thread.cc rename to chromeos/ash/services/libassistant/grpc/grpc_client_thread.cc index cd5a40e9..bf36da0 100644 --- a/chromeos/services/libassistant/grpc/grpc_client_thread.cc +++ b/chromeos/ash/services/libassistant/grpc/grpc_client_thread.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 "chromeos/services/libassistant/grpc/grpc_client_thread.h" +#include "chromeos/ash/services/libassistant/grpc/grpc_client_thread.h" #include <memory>
diff --git a/chromeos/services/libassistant/grpc/grpc_client_thread.h b/chromeos/ash/services/libassistant/grpc/grpc_client_thread.h similarity index 88% rename from chromeos/services/libassistant/grpc/grpc_client_thread.h rename to chromeos/ash/services/libassistant/grpc/grpc_client_thread.h index 5b4be162..50a8af3 100644 --- a/chromeos/services/libassistant/grpc/grpc_client_thread.h +++ b/chromeos/ash/services/libassistant/grpc/grpc_client_thread.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROMEOS_SERVICES_LIBASSISTANT_GRPC_GRPC_CLIENT_THREAD_H_ -#define CHROMEOS_SERVICES_LIBASSISTANT_GRPC_GRPC_CLIENT_THREAD_H_ +#ifndef CHROMEOS_ASH_SERVICES_LIBASSISTANT_GRPC_GRPC_CLIENT_THREAD_H_ +#define CHROMEOS_ASH_SERVICES_LIBASSISTANT_GRPC_GRPC_CLIENT_THREAD_H_ #include <memory> #include <string> @@ -52,4 +52,4 @@ } // namespace libassistant } // namespace chromeos -#endif // CHROMEOS_SERVICES_LIBASSISTANT_GRPC_GRPC_CLIENT_THREAD_H_ +#endif // CHROMEOS_ASH_SERVICES_LIBASSISTANT_GRPC_GRPC_CLIENT_THREAD_H_
diff --git a/chromeos/services/libassistant/grpc/grpc_http_connection_client.cc b/chromeos/ash/services/libassistant/grpc/grpc_http_connection_client.cc similarity index 97% rename from chromeos/services/libassistant/grpc/grpc_http_connection_client.cc rename to chromeos/ash/services/libassistant/grpc/grpc_http_connection_client.cc index aca4dc9..b1c31af8 100644 --- a/chromeos/services/libassistant/grpc/grpc_http_connection_client.cc +++ b/chromeos/ash/services/libassistant/grpc/grpc_http_connection_client.cc
@@ -2,14 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chromeos/services/libassistant/grpc/grpc_http_connection_client.h" +#include "chromeos/ash/services/libassistant/grpc/grpc_http_connection_client.h" #include "base/bind.h" #include "base/notreached.h" +#include "chromeos/ash/services/libassistant/grpc/grpc_client_thread.h" +#include "chromeos/ash/services/libassistant/grpc/grpc_http_connection_delegate.h" #include "chromeos/assistant/internal/grpc_transport/streaming/bidi_streaming_rpc_call.h" #include "chromeos/assistant/internal/grpc_transport/streaming/streaming_write_queue.h" -#include "chromeos/services/libassistant/grpc/grpc_client_thread.h" -#include "chromeos/services/libassistant/grpc/grpc_http_connection_delegate.h" #include "third_party/grpc/src/include/grpc/grpc_security_constants.h" #include "third_party/grpc/src/include/grpc/grpc_security_constants.h"
diff --git a/chromeos/services/libassistant/grpc/grpc_http_connection_client.h b/chromeos/ash/services/libassistant/grpc/grpc_http_connection_client.h similarity index 89% rename from chromeos/services/libassistant/grpc/grpc_http_connection_client.h rename to chromeos/ash/services/libassistant/grpc/grpc_http_connection_client.h index b9c3cce..f8e1400 100644 --- a/chromeos/services/libassistant/grpc/grpc_http_connection_client.h +++ b/chromeos/ash/services/libassistant/grpc/grpc_http_connection_client.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROMEOS_SERVICES_LIBASSISTANT_GRPC_GRPC_HTTP_CONNECTION_CLIENT_H_ -#define CHROMEOS_SERVICES_LIBASSISTANT_GRPC_GRPC_HTTP_CONNECTION_CLIENT_H_ +#ifndef CHROMEOS_ASH_SERVICES_LIBASSISTANT_GRPC_GRPC_HTTP_CONNECTION_CLIENT_H_ +#define CHROMEOS_ASH_SERVICES_LIBASSISTANT_GRPC_GRPC_HTTP_CONNECTION_CLIENT_H_ #include <memory> #include <string> @@ -12,13 +12,13 @@ #include "base/memory/raw_ptr.h" #include "base/synchronization/lock.h" #include "base/threading/sequenced_task_runner_handle.h" +#include "chromeos/ash/services/libassistant/grpc/grpc_client_thread.h" +#include "chromeos/ash/services/libassistant/grpc/grpc_state.h" +#include "chromeos/ash/services/libassistant/grpc/grpc_util.h" #include "chromeos/assistant/internal/grpc_transport/streaming/bidi_streaming_rpc_call.h" #include "chromeos/assistant/internal/grpc_transport/streaming/streaming_write_queue.h" #include "chromeos/assistant/internal/libassistant/shared_headers.h" #include "chromeos/assistant/internal/proto/shared/proto/v2/http_connection_service.grpc.pb.h" -#include "chromeos/services/libassistant/grpc/grpc_client_thread.h" -#include "chromeos/services/libassistant/grpc/grpc_state.h" -#include "chromeos/services/libassistant/grpc/grpc_util.h" #include "third_party/grpc/src/include/grpcpp/channel.h" namespace chromeos { @@ -102,4 +102,4 @@ } // namespace libassistant } // namespace chromeos -#endif // CHROMEOS_SERVICES_LIBASSISTANT_GRPC_GRPC_HTTP_CONNECTION_CLIENT_H_ +#endif // CHROMEOS_ASH_SERVICES_LIBASSISTANT_GRPC_GRPC_HTTP_CONNECTION_CLIENT_H_
diff --git a/chromeos/services/libassistant/grpc/grpc_http_connection_client_unittests.cc b/chromeos/ash/services/libassistant/grpc/grpc_http_connection_client_unittests.cc similarity index 99% rename from chromeos/services/libassistant/grpc/grpc_http_connection_client_unittests.cc rename to chromeos/ash/services/libassistant/grpc/grpc_http_connection_client_unittests.cc index a6b856a..50926e64 100644 --- a/chromeos/services/libassistant/grpc/grpc_http_connection_client_unittests.cc +++ b/chromeos/ash/services/libassistant/grpc/grpc_http_connection_client_unittests.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 "chromeos/services/libassistant/grpc/grpc_http_connection_client.h" +#include "chromeos/ash/services/libassistant/grpc/grpc_http_connection_client.h" #include "base/memory/raw_ptr.h" #include "base/run_loop.h"
diff --git a/chromeos/services/libassistant/grpc/grpc_http_connection_delegate.cc b/chromeos/ash/services/libassistant/grpc/grpc_http_connection_delegate.cc similarity index 96% rename from chromeos/services/libassistant/grpc/grpc_http_connection_delegate.cc rename to chromeos/ash/services/libassistant/grpc/grpc_http_connection_delegate.cc index 4972945..23d72bc3 100644 --- a/chromeos/services/libassistant/grpc/grpc_http_connection_delegate.cc +++ b/chromeos/ash/services/libassistant/grpc/grpc_http_connection_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 "chromeos/services/libassistant/grpc/grpc_http_connection_delegate.h" +#include "chromeos/ash/services/libassistant/grpc/grpc_http_connection_delegate.h" namespace chromeos { namespace libassistant {
diff --git a/chromeos/services/libassistant/grpc/grpc_http_connection_delegate.h b/chromeos/ash/services/libassistant/grpc/grpc_http_connection_delegate.h similarity index 82% rename from chromeos/services/libassistant/grpc/grpc_http_connection_delegate.h rename to chromeos/ash/services/libassistant/grpc/grpc_http_connection_delegate.h index 19202e72..c018c8d 100644 --- a/chromeos/services/libassistant/grpc/grpc_http_connection_delegate.h +++ b/chromeos/ash/services/libassistant/grpc/grpc_http_connection_delegate.h
@@ -2,13 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROMEOS_SERVICES_LIBASSISTANT_GRPC_GRPC_HTTP_CONNECTION_DELEGATE_H_ -#define CHROMEOS_SERVICES_LIBASSISTANT_GRPC_GRPC_HTTP_CONNECTION_DELEGATE_H_ +#ifndef CHROMEOS_ASH_SERVICES_LIBASSISTANT_GRPC_GRPC_HTTP_CONNECTION_DELEGATE_H_ +#define CHROMEOS_ASH_SERVICES_LIBASSISTANT_GRPC_GRPC_HTTP_CONNECTION_DELEGATE_H_ #include "base/task/sequenced_task_runner.h" #include "base/threading/sequenced_task_runner_handle.h" +#include "chromeos/ash/services/libassistant/grpc/grpc_http_connection_client.h" #include "chromeos/assistant/internal/libassistant/shared_headers.h" -#include "chromeos/services/libassistant/grpc/grpc_http_connection_client.h" namespace chromeos { namespace libassistant { @@ -42,4 +42,4 @@ } // namespace libassistant } // namespace chromeos -#endif // CHROMEOS_SERVICES_LIBASSISTANT_GRPC_GRPC_HTTP_CONNECTION_DELEGATE_H_ +#endif // CHROMEOS_ASH_SERVICES_LIBASSISTANT_GRPC_GRPC_HTTP_CONNECTION_DELEGATE_H_
diff --git a/chromeos/services/libassistant/grpc/grpc_libassistant_client.cc b/chromeos/ash/services/libassistant/grpc/grpc_libassistant_client.cc similarity index 98% rename from chromeos/services/libassistant/grpc/grpc_libassistant_client.cc rename to chromeos/ash/services/libassistant/grpc/grpc_libassistant_client.cc index fcc27e7..d8a65d2 100644 --- a/chromeos/services/libassistant/grpc/grpc_libassistant_client.cc +++ b/chromeos/ash/services/libassistant/grpc/grpc_libassistant_client.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 "chromeos/services/libassistant/grpc/grpc_libassistant_client.h" +#include "chromeos/ash/services/libassistant/grpc/grpc_libassistant_client.h" #include <memory>
diff --git a/chromeos/services/libassistant/grpc/grpc_libassistant_client.h b/chromeos/ash/services/libassistant/grpc/grpc_libassistant_client.h similarity index 82% rename from chromeos/services/libassistant/grpc/grpc_libassistant_client.h rename to chromeos/ash/services/libassistant/grpc/grpc_libassistant_client.h index 3f3e1e4..ca0dbd7 100644 --- a/chromeos/services/libassistant/grpc/grpc_libassistant_client.h +++ b/chromeos/ash/services/libassistant/grpc/grpc_libassistant_client.h
@@ -2,16 +2,16 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROMEOS_SERVICES_LIBASSISTANT_GRPC_GRPC_LIBASSISTANT_CLIENT_H_ -#define CHROMEOS_SERVICES_LIBASSISTANT_GRPC_GRPC_LIBASSISTANT_CLIENT_H_ +#ifndef CHROMEOS_ASH_SERVICES_LIBASSISTANT_GRPC_GRPC_LIBASSISTANT_CLIENT_H_ +#define CHROMEOS_ASH_SERVICES_LIBASSISTANT_GRPC_GRPC_LIBASSISTANT_CLIENT_H_ #include <memory> #include <string> #include "base/threading/sequenced_task_runner_handle.h" -#include "chromeos/services/libassistant/grpc/grpc_client_thread.h" -#include "chromeos/services/libassistant/grpc/grpc_state.h" -#include "chromeos/services/libassistant/grpc/grpc_util.h" +#include "chromeos/ash/services/libassistant/grpc/grpc_client_thread.h" +#include "chromeos/ash/services/libassistant/grpc/grpc_state.h" +#include "chromeos/ash/services/libassistant/grpc/grpc_util.h" #include "third_party/grpc/src/include/grpcpp/channel.h" namespace chromeos { @@ -59,4 +59,4 @@ } // namespace libassistant } // namespace chromeos -#endif // CHROMEOS_SERVICES_LIBASSISTANT_GRPC_GRPC_LIBASSISTANT_CLIENT_H_ +#endif // CHROMEOS_ASH_SERVICES_LIBASSISTANT_GRPC_GRPC_LIBASSISTANT_CLIENT_H_
diff --git a/chromeos/services/libassistant/grpc/grpc_state.h b/chromeos/ash/services/libassistant/grpc/grpc_state.h similarity index 96% rename from chromeos/services/libassistant/grpc/grpc_state.h rename to chromeos/ash/services/libassistant/grpc/grpc_state.h index 0f7fb238..f868452 100644 --- a/chromeos/services/libassistant/grpc/grpc_state.h +++ b/chromeos/ash/services/libassistant/grpc/grpc_state.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROMEOS_SERVICES_LIBASSISTANT_GRPC_GRPC_STATE_H_ -#define CHROMEOS_SERVICES_LIBASSISTANT_GRPC_GRPC_STATE_H_ +#ifndef CHROMEOS_ASH_SERVICES_LIBASSISTANT_GRPC_GRPC_STATE_H_ +#define CHROMEOS_ASH_SERVICES_LIBASSISTANT_GRPC_GRPC_STATE_H_ #include <memory> #include <string> @@ -13,8 +13,8 @@ #include "base/location.h" #include "base/logging.h" #include "base/task/sequenced_task_runner.h" +#include "chromeos/ash/services/libassistant/grpc/grpc_util.h" #include "chromeos/assistant/internal/grpc_transport/grpc_client_cq_tag.h" -#include "chromeos/services/libassistant/grpc/grpc_util.h" #include "third_party/grpc/src/include/grpcpp/client_context.h" #include "third_party/grpc/src/include/grpcpp/generic/generic_stub.h" #include "third_party/grpc/src/include/grpcpp/grpcpp.h" @@ -218,4 +218,4 @@ } // namespace libassistant } // namespace chromeos -#endif // CHROMEOS_SERVICES_LIBASSISTANT_GRPC_GRPC_STATE_H_ +#endif // CHROMEOS_ASH_SERVICES_LIBASSISTANT_GRPC_GRPC_STATE_H_
diff --git a/chromeos/services/libassistant/grpc/grpc_util.cc b/chromeos/ash/services/libassistant/grpc/grpc_util.cc similarity index 95% rename from chromeos/services/libassistant/grpc/grpc_util.cc rename to chromeos/ash/services/libassistant/grpc/grpc_util.cc index 4c61327..7c8a515 100644 --- a/chromeos/services/libassistant/grpc/grpc_util.cc +++ b/chromeos/ash/services/libassistant/grpc/grpc_util.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 "chromeos/services/libassistant/grpc/grpc_util.h" +#include "chromeos/ash/services/libassistant/grpc/grpc_util.h" #include "base/check_op.h" #include "third_party/grpc/src/include/grpcpp/impl/codegen/proto_utils.h"
diff --git a/chromeos/services/libassistant/grpc/grpc_util.h b/chromeos/ash/services/libassistant/grpc/grpc_util.h similarity index 86% rename from chromeos/services/libassistant/grpc/grpc_util.h rename to chromeos/ash/services/libassistant/grpc/grpc_util.h index 7c8d9222..465b6e95 100644 --- a/chromeos/services/libassistant/grpc/grpc_util.h +++ b/chromeos/ash/services/libassistant/grpc/grpc_util.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROMEOS_SERVICES_LIBASSISTANT_GRPC_GRPC_UTIL_H_ -#define CHROMEOS_SERVICES_LIBASSISTANT_GRPC_GRPC_UTIL_H_ +#ifndef CHROMEOS_ASH_SERVICES_LIBASSISTANT_GRPC_GRPC_UTIL_H_ +#define CHROMEOS_ASH_SERVICES_LIBASSISTANT_GRPC_GRPC_UTIL_H_ #include <string> @@ -34,4 +34,4 @@ } // namespace libassistant } // namespace chromeos -#endif // CHROMEOS_SERVICES_LIBASSISTANT_GRPC_GRPC_UTIL_H_ +#endif // CHROMEOS_ASH_SERVICES_LIBASSISTANT_GRPC_GRPC_UTIL_H_
diff --git a/chromeos/services/libassistant/grpc/rpc_method_driver.h b/chromeos/ash/services/libassistant/grpc/rpc_method_driver.h similarity index 96% rename from chromeos/services/libassistant/grpc/rpc_method_driver.h rename to chromeos/ash/services/libassistant/grpc/rpc_method_driver.h index 1a528c6..c495fc0f 100644 --- a/chromeos/services/libassistant/grpc/rpc_method_driver.h +++ b/chromeos/ash/services/libassistant/grpc/rpc_method_driver.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROMEOS_SERVICES_LIBASSISTANT_GRPC_RPC_METHOD_DRIVER_H_ -#define CHROMEOS_SERVICES_LIBASSISTANT_GRPC_RPC_METHOD_DRIVER_H_ +#ifndef CHROMEOS_ASH_SERVICES_LIBASSISTANT_GRPC_RPC_METHOD_DRIVER_H_ +#define CHROMEOS_ASH_SERVICES_LIBASSISTANT_GRPC_RPC_METHOD_DRIVER_H_ #include <memory> @@ -183,4 +183,4 @@ } // namespace libassistant } // namespace chromeos -#endif // CHROMEOS_SERVICES_LIBASSISTANT_GRPC_RPC_METHOD_DRIVER_H_ +#endif // CHROMEOS_ASH_SERVICES_LIBASSISTANT_GRPC_RPC_METHOD_DRIVER_H_
diff --git a/chromeos/services/libassistant/grpc/services_initializer_base.cc b/chromeos/ash/services/libassistant/grpc/services_initializer_base.cc similarity index 96% rename from chromeos/services/libassistant/grpc/services_initializer_base.cc rename to chromeos/ash/services/libassistant/grpc/services_initializer_base.cc index 0f14159..baab682 100644 --- a/chromeos/services/libassistant/grpc/services_initializer_base.cc +++ b/chromeos/ash/services/libassistant/grpc/services_initializer_base.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 "chromeos/services/libassistant/grpc/services_initializer_base.h" +#include "chromeos/ash/services/libassistant/grpc/services_initializer_base.h" #include <string>
diff --git a/chromeos/services/libassistant/grpc/services_initializer_base.h b/chromeos/ash/services/libassistant/grpc/services_initializer_base.h similarity index 86% rename from chromeos/services/libassistant/grpc/services_initializer_base.h rename to chromeos/ash/services/libassistant/grpc/services_initializer_base.h index 3b47e96..df7cba2 100644 --- a/chromeos/services/libassistant/grpc/services_initializer_base.h +++ b/chromeos/ash/services/libassistant/grpc/services_initializer_base.h
@@ -2,15 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROMEOS_SERVICES_LIBASSISTANT_GRPC_SERVICES_INITIALIZER_BASE_H_ -#define CHROMEOS_SERVICES_LIBASSISTANT_GRPC_SERVICES_INITIALIZER_BASE_H_ +#ifndef CHROMEOS_ASH_SERVICES_LIBASSISTANT_GRPC_SERVICES_INITIALIZER_BASE_H_ +#define CHROMEOS_ASH_SERVICES_LIBASSISTANT_GRPC_SERVICES_INITIALIZER_BASE_H_ #include <memory> #include <string> #include <vector> #include "base/threading/thread.h" -#include "chromeos/services/libassistant/grpc/async_service_driver.h" +#include "chromeos/ash/services/libassistant/grpc/async_service_driver.h" #include "third_party/grpc/src/include/grpcpp/completion_queue.h" #include "third_party/grpc/src/include/grpcpp/server_builder.h" @@ -62,4 +62,4 @@ } // namespace libassistant } // namespace chromeos -#endif // CHROMEOS_SERVICES_LIBASSISTANT_GRPC_SERVICES_INITIALIZER_BASE_H_ +#endif // CHROMEOS_ASH_SERVICES_LIBASSISTANT_GRPC_SERVICES_INITIALIZER_BASE_H_
diff --git a/chromeos/services/libassistant/grpc/services_status_observer.h b/chromeos/ash/services/libassistant/grpc/services_status_observer.h similarity index 80% rename from chromeos/services/libassistant/grpc/services_status_observer.h rename to chromeos/ash/services/libassistant/grpc/services_status_observer.h index 3c4c070..19565e6 100644 --- a/chromeos/services/libassistant/grpc/services_status_observer.h +++ b/chromeos/ash/services/libassistant/grpc/services_status_observer.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROMEOS_SERVICES_LIBASSISTANT_GRPC_SERVICES_STATUS_OBSERVER_H_ -#define CHROMEOS_SERVICES_LIBASSISTANT_GRPC_SERVICES_STATUS_OBSERVER_H_ +#ifndef CHROMEOS_ASH_SERVICES_LIBASSISTANT_GRPC_SERVICES_STATUS_OBSERVER_H_ +#define CHROMEOS_ASH_SERVICES_LIBASSISTANT_GRPC_SERVICES_STATUS_OBSERVER_H_ #include "base/observer_list_types.h" @@ -33,4 +33,4 @@ } // namespace libassistant } // namespace chromeos -#endif // CHROMEOS_SERVICES_LIBASSISTANT_GRPC_SERVICES_STATUS_OBSERVER_H_ +#endif // CHROMEOS_ASH_SERVICES_LIBASSISTANT_GRPC_SERVICES_STATUS_OBSERVER_H_
diff --git a/chromeos/services/libassistant/grpc/services_status_provider.cc b/chromeos/ash/services/libassistant/grpc/services_status_provider.cc similarity index 93% rename from chromeos/services/libassistant/grpc/services_status_provider.cc rename to chromeos/ash/services/libassistant/grpc/services_status_provider.cc index 8200029..50bb5762 100644 --- a/chromeos/services/libassistant/grpc/services_status_provider.cc +++ b/chromeos/ash/services/libassistant/grpc/services_status_provider.cc
@@ -2,10 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chromeos/services/libassistant/grpc/services_status_provider.h" +#include "chromeos/ash/services/libassistant/grpc/services_status_provider.h" #include "base/logging.h" -#include "chromeos/services/libassistant/grpc/services_status_observer.h" +#include "chromeos/ash/services/libassistant/grpc/services_status_observer.h" namespace chromeos { namespace libassistant {
diff --git a/chromeos/services/libassistant/grpc/services_status_provider.h b/chromeos/ash/services/libassistant/grpc/services_status_provider.h similarity index 76% rename from chromeos/services/libassistant/grpc/services_status_provider.h rename to chromeos/ash/services/libassistant/grpc/services_status_provider.h index c9c6f7a..8fa5ec49 100644 --- a/chromeos/services/libassistant/grpc/services_status_provider.h +++ b/chromeos/ash/services/libassistant/grpc/services_status_provider.h
@@ -2,14 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROMEOS_SERVICES_LIBASSISTANT_GRPC_SERVICES_STATUS_PROVIDER_H_ -#define CHROMEOS_SERVICES_LIBASSISTANT_GRPC_SERVICES_STATUS_PROVIDER_H_ +#ifndef CHROMEOS_ASH_SERVICES_LIBASSISTANT_GRPC_SERVICES_STATUS_PROVIDER_H_ +#define CHROMEOS_ASH_SERVICES_LIBASSISTANT_GRPC_SERVICES_STATUS_PROVIDER_H_ #include "base/observer_list.h" #include "base/observer_list_types.h" +#include "chromeos/ash/services/libassistant/grpc/external_services/grpc_services_observer.h" +#include "chromeos/ash/services/libassistant/grpc/services_status_observer.h" #include "chromeos/assistant/internal/proto/shared/proto/v2/delegate/event_handler_interface.pb.h" -#include "chromeos/services/libassistant/grpc/external_services/grpc_services_observer.h" -#include "chromeos/services/libassistant/grpc/services_status_observer.h" namespace chromeos { namespace libassistant { @@ -40,4 +40,4 @@ } // namespace libassistant } // namespace chromeos -#endif // CHROMEOS_SERVICES_LIBASSISTANT_GRPC_SERVICES_STATUS_PROVIDER_H_ +#endif // CHROMEOS_ASH_SERVICES_LIBASSISTANT_GRPC_SERVICES_STATUS_PROVIDER_H_
diff --git a/chromeos/services/libassistant/grpc/utils/media_status_utils.cc b/chromeos/ash/services/libassistant/grpc/utils/media_status_utils.cc similarity index 98% rename from chromeos/services/libassistant/grpc/utils/media_status_utils.cc rename to chromeos/ash/services/libassistant/grpc/utils/media_status_utils.cc index a74ca2f..2ea42f7 100644 --- a/chromeos/services/libassistant/grpc/utils/media_status_utils.cc +++ b/chromeos/ash/services/libassistant/grpc/utils/media_status_utils.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 "chromeos/services/libassistant/grpc/utils/media_status_utils.h" +#include "chromeos/ash/services/libassistant/grpc/utils/media_status_utils.h" #include "chromeos/assistant/internal/libassistant/shared_headers.h" #include "chromeos/services/libassistant/public/mojom/media_controller.mojom.h"
diff --git a/chromeos/services/libassistant/grpc/utils/media_status_utils.h b/chromeos/ash/services/libassistant/grpc/utils/media_status_utils.h similarity index 82% rename from chromeos/services/libassistant/grpc/utils/media_status_utils.h rename to chromeos/ash/services/libassistant/grpc/utils/media_status_utils.h index cf972f9..1dbb7d1b 100644 --- a/chromeos/services/libassistant/grpc/utils/media_status_utils.h +++ b/chromeos/ash/services/libassistant/grpc/utils/media_status_utils.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROMEOS_SERVICES_LIBASSISTANT_GRPC_UTILS_MEDIA_STATUS_UTILS_H_ -#define CHROMEOS_SERVICES_LIBASSISTANT_GRPC_UTILS_MEDIA_STATUS_UTILS_H_ +#ifndef CHROMEOS_ASH_SERVICES_LIBASSISTANT_GRPC_UTILS_MEDIA_STATUS_UTILS_H_ +#define CHROMEOS_ASH_SERVICES_LIBASSISTANT_GRPC_UTILS_MEDIA_STATUS_UTILS_H_ #include "chromeos/assistant/internal/proto/shared/proto/v2/device_state_event.pb.h" #include "chromeos/services/libassistant/public/mojom/media_controller.mojom-forward.h" @@ -33,4 +33,4 @@ } // namespace libassistant } // namespace chromeos -#endif // CHROMEOS_SERVICES_LIBASSISTANT_GRPC_UTILS_MEDIA_STATUS_UTILS_H_ +#endif // CHROMEOS_ASH_SERVICES_LIBASSISTANT_GRPC_UTILS_MEDIA_STATUS_UTILS_H_
diff --git a/chromeos/services/libassistant/grpc/utils/settings_utils.cc b/chromeos/ash/services/libassistant/grpc/utils/settings_utils.cc similarity index 98% rename from chromeos/services/libassistant/grpc/utils/settings_utils.cc rename to chromeos/ash/services/libassistant/grpc/utils/settings_utils.cc index 2c8a424..e88a2eb8 100644 --- a/chromeos/services/libassistant/grpc/utils/settings_utils.cc +++ b/chromeos/ash/services/libassistant/grpc/utils/settings_utils.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 "chromeos/services/libassistant/grpc/utils/settings_utils.h" +#include "chromeos/ash/services/libassistant/grpc/utils/settings_utils.h" #include "base/check.h" #include "base/logging.h"
diff --git a/chromeos/services/libassistant/grpc/utils/settings_utils.h b/chromeos/ash/services/libassistant/grpc/utils/settings_utils.h similarity index 87% rename from chromeos/services/libassistant/grpc/utils/settings_utils.h rename to chromeos/ash/services/libassistant/grpc/utils/settings_utils.h index a23b4c4a..5527b046 100644 --- a/chromeos/services/libassistant/grpc/utils/settings_utils.h +++ b/chromeos/ash/services/libassistant/grpc/utils/settings_utils.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROMEOS_SERVICES_LIBASSISTANT_GRPC_UTILS_SETTINGS_UTILS_H_ -#define CHROMEOS_SERVICES_LIBASSISTANT_GRPC_UTILS_SETTINGS_UTILS_H_ +#ifndef CHROMEOS_ASH_SERVICES_LIBASSISTANT_GRPC_UTILS_SETTINGS_UTILS_H_ +#define CHROMEOS_ASH_SERVICES_LIBASSISTANT_GRPC_UTILS_SETTINGS_UTILS_H_ #include "chromeos/assistant/internal/proto/shared/proto/v2/config_settings_interface.pb.h" @@ -39,4 +39,4 @@ } // namespace libassistant } // namespace chromeos -#endif // CHROMEOS_SERVICES_LIBASSISTANT_GRPC_UTILS_SETTINGS_UTILS_H_ +#endif // CHROMEOS_ASH_SERVICES_LIBASSISTANT_GRPC_UTILS_SETTINGS_UTILS_H_
diff --git a/chromeos/services/libassistant/grpc/utils/timer_utils.cc b/chromeos/ash/services/libassistant/grpc/utils/timer_utils.cc similarity index 98% rename from chromeos/services/libassistant/grpc/utils/timer_utils.cc rename to chromeos/ash/services/libassistant/grpc/utils/timer_utils.cc index 55def85..8d06edb 100644 --- a/chromeos/services/libassistant/grpc/utils/timer_utils.cc +++ b/chromeos/ash/services/libassistant/grpc/utils/timer_utils.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 "chromeos/services/libassistant/grpc/utils/timer_utils.h" +#include "chromeos/ash/services/libassistant/grpc/utils/timer_utils.h" #include "base/time/time.h" #include "chromeos/assistant/internal/proto/shared/proto/timer_params.pb.h"
diff --git a/chromeos/services/libassistant/grpc/utils/timer_utils.h b/chromeos/ash/services/libassistant/grpc/utils/timer_utils.h similarity index 87% rename from chromeos/services/libassistant/grpc/utils/timer_utils.h rename to chromeos/ash/services/libassistant/grpc/utils/timer_utils.h index 1afc7f84f..4bc84b39 100644 --- a/chromeos/services/libassistant/grpc/utils/timer_utils.h +++ b/chromeos/ash/services/libassistant/grpc/utils/timer_utils.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROMEOS_SERVICES_LIBASSISTANT_GRPC_UTILS_TIMER_UTILS_H_ -#define CHROMEOS_SERVICES_LIBASSISTANT_GRPC_UTILS_TIMER_UTILS_H_ +#ifndef CHROMEOS_ASH_SERVICES_LIBASSISTANT_GRPC_UTILS_TIMER_UTILS_H_ +#define CHROMEOS_ASH_SERVICES_LIBASSISTANT_GRPC_UTILS_TIMER_UTILS_H_ #include "chromeos/assistant/internal/libassistant/shared_headers.h" #include "chromeos/services/libassistant/public/cpp/assistant_timer.h" @@ -46,4 +46,4 @@ } // namespace libassistant } // namespace chromeos -#endif // CHROMEOS_SERVICES_LIBASSISTANT_GRPC_UTILS_TIMER_UTILS_H_ +#endif // CHROMEOS_ASH_SERVICES_LIBASSISTANT_GRPC_UTILS_TIMER_UTILS_H_
diff --git a/chromeos/ash/services/libassistant/media_controller.cc b/chromeos/ash/services/libassistant/media_controller.cc index 8dcaa585..d75f3db3 100644 --- a/chromeos/ash/services/libassistant/media_controller.cc +++ b/chromeos/ash/services/libassistant/media_controller.cc
@@ -6,14 +6,14 @@ #include "base/strings/string_util.h" #include "base/threading/sequenced_task_runner_handle.h" +#include "chromeos/ash/services/libassistant/grpc/assistant_client.h" +#include "chromeos/ash/services/libassistant/grpc/external_services/grpc_services_observer.h" +#include "chromeos/ash/services/libassistant/grpc/utils/media_status_utils.h" #include "chromeos/assistant/internal/libassistant/shared_headers.h" #include "chromeos/assistant/internal/proto/shared/proto/v2/delegate/event_handler_interface.pb.h" #include "chromeos/assistant/internal/proto/shared/proto/v2/device_state_event.pb.h" #include "chromeos/assistant/internal/util_headers.h" #include "chromeos/services/assistant/public/shared/utils.h" -#include "chromeos/services/libassistant/grpc/assistant_client.h" -#include "chromeos/services/libassistant/grpc/external_services/grpc_services_observer.h" -#include "chromeos/services/libassistant/grpc/utils/media_status_utils.h" namespace chromeos { namespace libassistant {
diff --git a/chromeos/ash/services/libassistant/media_controller.h b/chromeos/ash/services/libassistant/media_controller.h index 00b9ad80..17b4ffa 100644 --- a/chromeos/ash/services/libassistant/media_controller.h +++ b/chromeos/ash/services/libassistant/media_controller.h
@@ -5,8 +5,8 @@ #ifndef CHROMEOS_ASH_SERVICES_LIBASSISTANT_MEDIA_CONTROLLER_H_ #define CHROMEOS_ASH_SERVICES_LIBASSISTANT_MEDIA_CONTROLLER_H_ +#include "chromeos/ash/services/libassistant/grpc/assistant_client_observer.h" #include "chromeos/assistant/internal/proto/shared/proto/v2/device_state_event.pb.h" -#include "chromeos/services/libassistant/grpc/assistant_client_observer.h" #include "chromeos/services/libassistant/public/mojom/media_controller.mojom.h" #include "mojo/public/cpp/bindings/receiver.h" #include "mojo/public/cpp/bindings/remote.h"
diff --git a/chromeos/ash/services/libassistant/platform_api.h b/chromeos/ash/services/libassistant/platform_api.h index 71a10ff..0fbde11 100644 --- a/chromeos/ash/services/libassistant/platform_api.h +++ b/chromeos/ash/services/libassistant/platform_api.h
@@ -7,9 +7,9 @@ #include <memory> +#include "chromeos/ash/services/libassistant/grpc/assistant_client_observer.h" #include "chromeos/ash/services/libassistant/network_provider_impl.h" #include "chromeos/assistant/internal/libassistant/shared_headers.h" -#include "chromeos/services/libassistant/grpc/assistant_client_observer.h" #include "chromeos/services/libassistant/public/mojom/audio_output_delegate.mojom.h" #include "chromeos/services/libassistant/public/mojom/platform_delegate.mojom.h" #include "mojo/public/cpp/bindings/pending_remote.h"
diff --git a/chromeos/ash/services/libassistant/service_controller.cc b/chromeos/ash/services/libassistant/service_controller.cc index 2ef0fb1..f7b0fb87 100644 --- a/chromeos/ash/services/libassistant/service_controller.cc +++ b/chromeos/ash/services/libassistant/service_controller.cc
@@ -10,12 +10,12 @@ #include "base/check.h" #include "chromeos/ash/services/assistant/public/cpp/features.h" #include "chromeos/ash/services/libassistant/chromium_api_delegate.h" +#include "chromeos/ash/services/libassistant/grpc/assistant_client.h" #include "chromeos/ash/services/libassistant/libassistant_factory.h" #include "chromeos/ash/services/libassistant/settings_controller.h" #include "chromeos/ash/services/libassistant/util.h" #include "chromeos/assistant/internal/internal_util.h" #include "chromeos/assistant/internal/libassistant/shared_headers.h" -#include "chromeos/services/libassistant/grpc/assistant_client.h" #include "services/network/public/cpp/cross_thread_pending_shared_url_loader_factory.h" #include "services/network/public/cpp/wrapper_shared_url_loader_factory.h"
diff --git a/chromeos/ash/services/libassistant/service_controller.h b/chromeos/ash/services/libassistant/service_controller.h index 0acdf2d5..8a86069 100644 --- a/chromeos/ash/services/libassistant/service_controller.h +++ b/chromeos/ash/services/libassistant/service_controller.h
@@ -9,10 +9,10 @@ #include "base/memory/weak_ptr.h" #include "base/observer_list.h" #include "base/scoped_observation.h" +#include "chromeos/ash/services/libassistant/grpc/assistant_client.h" +#include "chromeos/ash/services/libassistant/grpc/assistant_client_observer.h" +#include "chromeos/ash/services/libassistant/grpc/services_status_observer.h" #include "chromeos/assistant/internal/libassistant/shared_headers.h" -#include "chromeos/services/libassistant/grpc/assistant_client.h" -#include "chromeos/services/libassistant/grpc/assistant_client_observer.h" -#include "chromeos/services/libassistant/grpc/services_status_observer.h" #include "chromeos/services/libassistant/public/mojom/service.mojom.h" #include "chromeos/services/libassistant/public/mojom/service_controller.mojom.h" #include "chromeos/services/libassistant/public/mojom/settings_controller.mojom-forward.h"
diff --git a/chromeos/ash/services/libassistant/service_controller_unittest.cc b/chromeos/ash/services/libassistant/service_controller_unittest.cc index 288b7e9..0424d010 100644 --- a/chromeos/ash/services/libassistant/service_controller_unittest.cc +++ b/chromeos/ash/services/libassistant/service_controller_unittest.cc
@@ -12,12 +12,12 @@ #include "base/test/gtest_util.h" #include "base/test/scoped_path_override.h" #include "base/test/task_environment.h" +#include "chromeos/ash/services/libassistant/grpc/assistant_client_observer.h" #include "chromeos/ash/services/libassistant/settings_controller.h" #include "chromeos/ash/services/libassistant/test_support/fake_libassistant_factory.h" #include "chromeos/assistant/internal/libassistant/shared_headers.h" #include "chromeos/assistant/internal/test_support/fake_assistant_manager.h" #include "chromeos/assistant/internal/test_support/fake_assistant_manager_internal.h" -#include "chromeos/services/libassistant/grpc/assistant_client_observer.h" #include "chromeos/services/libassistant/public/mojom/service_controller.mojom.h" #include "chromeos/services/libassistant/public/mojom/settings_controller.mojom.h" #include "mojo/public/cpp/bindings/receiver.h"
diff --git a/chromeos/ash/services/libassistant/settings_controller.cc b/chromeos/ash/services/libassistant/settings_controller.cc index 75aa287..8e6c433 100644 --- a/chromeos/ash/services/libassistant/settings_controller.cc +++ b/chromeos/ash/services/libassistant/settings_controller.cc
@@ -13,13 +13,13 @@ #include "chromeos/ash/services/assistant/public/proto/assistant_device_settings_ui.pb.h" #include "chromeos/ash/services/assistant/public/proto/settings_ui.pb.h" #include "chromeos/ash/services/libassistant/callback_utils.h" +#include "chromeos/ash/services/libassistant/grpc/assistant_client.h" +#include "chromeos/ash/services/libassistant/grpc/utils/settings_utils.h" #include "chromeos/assistant/internal/internal_util.h" #include "chromeos/assistant/internal/proto/assistant/display_connection.pb.h" #include "chromeos/assistant/internal/proto/shared/proto/settings_ui.pb.h" #include "chromeos/assistant/internal/proto/shared/proto/v2/config_settings_interface.pb.h" #include "chromeos/assistant/internal/proto/shared/proto/v2/display_interface.pb.h" -#include "chromeos/services/libassistant/grpc/assistant_client.h" -#include "chromeos/services/libassistant/grpc/utils/settings_utils.h" #include "third_party/icu/source/common/unicode/locid.h" namespace chromeos {
diff --git a/chromeos/ash/services/libassistant/settings_controller.h b/chromeos/ash/services/libassistant/settings_controller.h index 592635d..0fbb115 100644 --- a/chromeos/ash/services/libassistant/settings_controller.h +++ b/chromeos/ash/services/libassistant/settings_controller.h
@@ -10,7 +10,7 @@ #include "third_party/abseil-cpp/absl/types/optional.h" #include "chromeos/ash/services/libassistant/abortable_task_list.h" -#include "chromeos/services/libassistant/grpc/assistant_client_observer.h" +#include "chromeos/ash/services/libassistant/grpc/assistant_client_observer.h" #include "chromeos/services/libassistant/public/mojom/settings_controller.mojom.h" #include "mojo/public/cpp/bindings/receiver.h"
diff --git a/chromeos/ash/services/libassistant/speaker_id_enrollment_controller.cc b/chromeos/ash/services/libassistant/speaker_id_enrollment_controller.cc index 03b2321..5a56a80 100644 --- a/chromeos/ash/services/libassistant/speaker_id_enrollment_controller.cc +++ b/chromeos/ash/services/libassistant/speaker_id_enrollment_controller.cc
@@ -5,12 +5,12 @@ #include "chromeos/ash/services/libassistant/speaker_id_enrollment_controller.h" #include "base/scoped_observation.h" +#include "chromeos/ash/services/libassistant/grpc/assistant_client.h" +#include "chromeos/ash/services/libassistant/grpc/external_services/grpc_services_observer.h" #include "chromeos/assistant/internal/libassistant/shared_headers.h" #include "chromeos/assistant/internal/proto/shared/proto/v2/delegate/event_handler_interface.pb.h" #include "chromeos/assistant/internal/proto/shared/proto/v2/speaker_id_enrollment_event.pb.h" #include "chromeos/assistant/internal/proto/shared/proto/v2/speaker_id_enrollment_interface.pb.h" -#include "chromeos/services/libassistant/grpc/assistant_client.h" -#include "chromeos/services/libassistant/grpc/external_services/grpc_services_observer.h" #include "chromeos/services/libassistant/public/mojom/audio_input_controller.mojom.h" #include "mojo/public/cpp/bindings/remote.h"
diff --git a/chromeos/ash/services/libassistant/speaker_id_enrollment_controller.h b/chromeos/ash/services/libassistant/speaker_id_enrollment_controller.h index faf51e9..4921182 100644 --- a/chromeos/ash/services/libassistant/speaker_id_enrollment_controller.h +++ b/chromeos/ash/services/libassistant/speaker_id_enrollment_controller.h
@@ -6,7 +6,7 @@ #define CHROMEOS_ASH_SERVICES_LIBASSISTANT_SPEAKER_ID_ENROLLMENT_CONTROLLER_H_ #include "chromeos/ash/services/libassistant/abortable_task_list.h" -#include "chromeos/services/libassistant/grpc/assistant_client_observer.h" +#include "chromeos/ash/services/libassistant/grpc/assistant_client_observer.h" #include "chromeos/services/libassistant/public/mojom/audio_input_controller.mojom-forward.h" #include "chromeos/services/libassistant/public/mojom/speaker_id_enrollment_controller.mojom.h" #include "mojo/public/cpp/bindings/receiver.h"
diff --git a/chromeos/ash/services/libassistant/test_support/fake_assistant_client.cc b/chromeos/ash/services/libassistant/test_support/fake_assistant_client.cc index 861a1ec..6a4343e 100644 --- a/chromeos/ash/services/libassistant/test_support/fake_assistant_client.cc +++ b/chromeos/ash/services/libassistant/test_support/fake_assistant_client.cc
@@ -6,9 +6,9 @@ #include "base/callback.h" #include "base/test/bind.h" +#include "chromeos/ash/services/libassistant/grpc/utils/timer_utils.h" #include "chromeos/assistant/internal/proto/shared/proto/v2/delegate/event_handler_interface.pb.h" #include "chromeos/assistant/internal/test_support/fake_alarm_timer_manager.h" -#include "chromeos/services/libassistant/grpc/utils/timer_utils.h" #include "chromeos/services/libassistant/public/cpp/assistant_timer.h" namespace chromeos {
diff --git a/chromeos/ash/services/libassistant/test_support/fake_assistant_client.h b/chromeos/ash/services/libassistant/test_support/fake_assistant_client.h index 96484e6..65b8931 100644 --- a/chromeos/ash/services/libassistant/test_support/fake_assistant_client.h +++ b/chromeos/ash/services/libassistant/test_support/fake_assistant_client.h
@@ -5,9 +5,9 @@ #ifndef CHROMEOS_ASH_SERVICES_LIBASSISTANT_TEST_SUPPORT_FAKE_ASSISTANT_CLIENT_H_ #define CHROMEOS_ASH_SERVICES_LIBASSISTANT_TEST_SUPPORT_FAKE_ASSISTANT_CLIENT_H_ +#include "chromeos/ash/services/libassistant/grpc/assistant_client.h" #include "chromeos/assistant/internal/test_support/fake_assistant_manager.h" #include "chromeos/assistant/internal/test_support/fake_assistant_manager_internal.h" -#include "chromeos/services/libassistant/grpc/assistant_client.h" namespace chromeos { namespace libassistant {
diff --git a/chromeos/ash/services/libassistant/timer_controller.cc b/chromeos/ash/services/libassistant/timer_controller.cc index 667a29e..fd3b4e6410 100644 --- a/chromeos/ash/services/libassistant/timer_controller.cc +++ b/chromeos/ash/services/libassistant/timer_controller.cc
@@ -7,10 +7,10 @@ #include "base/thread_annotations.h" #include "build/buildflag.h" #include "chromeos/ash/services/assistant/public/cpp/features.h" +#include "chromeos/ash/services/libassistant/grpc/assistant_client.h" +#include "chromeos/ash/services/libassistant/grpc/external_services/grpc_services_observer.h" +#include "chromeos/ash/services/libassistant/grpc/utils/timer_utils.h" #include "chromeos/assistant/internal/proto/shared/proto/v2/delegate/event_handler_interface.pb.h" -#include "chromeos/services/libassistant/grpc/assistant_client.h" -#include "chromeos/services/libassistant/grpc/external_services/grpc_services_observer.h" -#include "chromeos/services/libassistant/grpc/utils/timer_utils.h" #include "chromeos/services/libassistant/public/cpp/assistant_timer.h" namespace chromeos {
diff --git a/chromeos/ash/services/libassistant/timer_controller.h b/chromeos/ash/services/libassistant/timer_controller.h index 31421e7..864d622 100644 --- a/chromeos/ash/services/libassistant/timer_controller.h +++ b/chromeos/ash/services/libassistant/timer_controller.h
@@ -8,7 +8,7 @@ #include <string> #include "base/time/time.h" -#include "chromeos/services/libassistant/grpc/assistant_client_observer.h" +#include "chromeos/ash/services/libassistant/grpc/assistant_client_observer.h" #include "chromeos/services/libassistant/public/mojom/timer_controller.mojom.h" #include "mojo/public/cpp/bindings/receiver.h" #include "mojo/public/cpp/bindings/remote.h"
diff --git a/chromeos/services/BUILD.gn b/chromeos/services/BUILD.gn index 3248e2e8..6ec2e61e 100644 --- a/chromeos/services/BUILD.gn +++ b/chromeos/services/BUILD.gn
@@ -3,7 +3,6 @@ # found in the LICENSE file. import("//build/config/ui.gni") -import("//chromeos/ash/components/assistant/assistant.gni") import("//testing/test.gni") assert(is_chromeos, "Non-ChromeOS builds cannot depend on //chromeos") @@ -25,8 +24,4 @@ "//chromeos/services/network_config:unit_tests", "//chromeos/services/tts:services_unittests", ] - - if (enable_cros_libassistant) { - deps += [ "//chromeos/services/libassistant/grpc:unit_tests" ] - } }
diff --git a/chromeos/tast_control.gni b/chromeos/tast_control.gni index 9eef0f2..c3d1e777 100644 --- a/chromeos/tast_control.gni +++ b/chromeos/tast_control.gni
@@ -190,31 +190,9 @@ "health.DiagnosticsRun.dns_resolution", "health.DiagnosticsRun.dns_resolver_present", - # http://b234699971 - "crostini.AppGeditUnshareFolder", - # b/235279574 "wmp.DragAndDropWindow", - # http://b/236312054 - "crostini.AppGeditFilesharing", - "crostini.AppGeditFilesharing.stable", - "crostini.AppGeditFilesharing.clamshell_stable", - - # http://b/236710501 - "crostini.AppAndroidStudio.stable", - "crostini.AppGeditUnshareFolder.stable", - "crostini.AppGeditUnshareFolder.clamshell_stable", - - # http://crbug.com/1339132 - "crostini.AppEclipse", - "crostini.AppEmacs", - "crostini.AppVscode", - "crostini.BasicLxdNext.stable", - "crostini.RestartApp", - "crostini.RestartApp.stable", - "crostini.RestartApp.clamshell_stable", - # http://b/238600197 "crostini.FilesAppWatch.buster_stable", @@ -280,9 +258,6 @@ "crostini.SSHFSMount.bullseye_stable", "crostini.SSHFSMount.buster_stable", - # https://crbug.com/1353760 - "crostini.RestartIcon.bullseye_stable", - # https://crbug.com/1354215 "lacros.Basic", ]
diff --git a/components/autofill/core/browser/form_processing/name_processing_util.cc b/components/autofill/core/browser/form_processing/name_processing_util.cc index ce3786b..d7b5c1a 100644 --- a/components/autofill/core/browser/form_processing/name_processing_util.cc +++ b/components/autofill/core/browser/form_processing/name_processing_util.cc
@@ -4,10 +4,9 @@ #include "components/autofill/core/browser/form_processing/name_processing_util.h" -#include "base/feature_list.h" -#include "base/strings/utf_string_conversions.h" -#include "components/autofill/core/browser/form_structure.h" -#include "components/autofill/core/common/autofill_features.h" +#include <utility> + +#include "base/ranges/algorithm.h" #include "components/autofill/core/common/autofill_regexes.h" namespace autofill { @@ -20,218 +19,63 @@ constexpr int kCommonNamePrefixRemovalFieldThreshold = 3; // Minimum required length for prefixes common to a subset of the field names. constexpr int kMinCommonNamePrefixLength = 16; -// Minimum required number of available fields for trying to remove affixes. -constexpr int kCommonNameAffixRemovalFieldNumberThreshold = 3; -// Minimum required length for affixes common to all field names. -constexpr int kMinCommonNameAffixLength = 3; -// Minimum required length for prefixes common to a subset of the field names. -constexpr int kMinCommonNameLongPrefixLength = 16; -// Regular expression for checking if |parseable_name| is valid after stripping -// affixes. -constexpr char16_t kParseableNameValidationRe[] = u"\\D"; using NamePieces = std::vector<base::StringPiece16>; -using OptionalNamePieces = absl::optional<NamePieces>; -// Returns the length of the longest common prefix. -// If |findCommonSuffix| is set, the length of the longest common suffix is -// returned. -size_t FindLongestCommonAffixLength(const NamePieces& strings, - bool findCommonSuffix) { +// Returns the length of the longest common prefix of the `strings`. The runtime +// is O(strings.size() * length-of-longest-common-prefix). +size_t FindLongestCommonPrefixLength(const NamePieces& strings) { if (strings.empty()) return 0; - // Go through each character of the first string until there is a mismatch at - // the same position in any other string. Adapted from http://goo.gl/YGukMM. - for (size_t affix_len = 0; affix_len < strings[0].size(); affix_len++) { - size_t base_string_index = - findCommonSuffix ? strings[0].size() - affix_len - 1 : affix_len; - for (size_t i = 1; i < strings.size(); i++) { - size_t compared_string_index = - findCommonSuffix ? strings[i].size() - affix_len - 1 : affix_len; - if (affix_len >= strings[i].size() || - strings[i][compared_string_index] != strings[0][base_string_index]) { - // Mismatch found. - return affix_len; - } - } - } - return strings[0].size(); + size_t prefix_len = 0; + auto AgreeOnNextChar = [&](base::StringPiece16 other) { + return prefix_len < other.size() && + strings[0][prefix_len] == other[prefix_len]; + }; + while (base::ranges::all_of(strings, AgreeOnNextChar)) + ++prefix_len; + return prefix_len; } -// Find the longest prefix in |strings| when only considering entries with a -// |minimal_length|. -size_t FindLongestCommonPrefixLengthInStringsWithMinimalLength( - const NamePieces& strings, - size_t minimal_length) { - if (strings.empty()) - return 0; - - NamePieces filtered_strings; - - // Any strings less than |minimal_length| are not considered when processing - // for a common prefix. - std::copy_if( - strings.begin(), strings.end(), std::back_inserter(filtered_strings), - [&](base::StringPiece16 s) { return s.length() >= minimal_length; }); - - if (filtered_strings.empty()) - return 0; - - return FindLongestCommonAffixLength(filtered_strings, false); +// Returns true if `parseable_name` is a valid parseable_name. To be considered +// valid, the string cannot be empty or consist of digits only. +// This condition prevents the logic from simplifying strings like +// "address-line-1", "address-line-2" to "1", "2". +bool IsValidParseableName(base::StringPiece16 parseable_name) { + static constexpr char16_t kRegex[] = u"\\D"; + return MatchesRegex<kRegex>(parseable_name); } -// Returns true if |parseable_name| is a valid parseable_name. Current criterion -// is the |kParseableNameValidationRe| regex. -bool IsValidParseableName(const base::StringPiece16 parseable_name) { - return MatchesRegex<kParseableNameValidationRe>(parseable_name); -} - -// Tries to strip |offset_left| and |offset_right| from entriees in -// |field_names| and checks if the resulting names are still valid parseable -// names. If not possible, return |absl::nullopt|. -OptionalNamePieces GetStrippedParseableNamesIfValid( - const NamePieces& field_names, - size_t offset_left, - size_t offset_right, - size_t minimal_string_length_to_strip) { - NamePieces stripped_names; - stripped_names.reserve(field_names.size()); - - for (auto& parseable_name : field_names) { - // This check allows to only strip affixes from long enough strings. - stripped_names.push_back( - parseable_name.size() > offset_right + offset_left && - parseable_name.size() >= minimal_string_length_to_strip - ? parseable_name.substr(offset_left, parseable_name.size() - - offset_right - offset_left) - : parseable_name); - - if (!IsValidParseableName(stripped_names.back())) - return absl::nullopt; - } - - return absl::make_optional(stripped_names); -} - -// Tries to remove common affixes from |field_names| and returns the result. If -// neither a common affix exists, or if one or more of the resulting strings is -// not a valid parseable name, |absl::nullopt| is returned. -// The number of names in |field_names| must exceed -// |kCommonNameAffixRemovalFieldNumberThreshold| in order to make the affix -// removal possible. Also, the length of an affix must exceed -// |kMinCommonNameAffixLength| to be removed. -OptionalNamePieces RemoveCommonAffixesIfPossible( - const NamePieces& field_names) { - // Updates the field name parsed by heuristics if several criteria are met. - // Several fields must be present in the form. - if (field_names.size() < kCommonNameAffixRemovalFieldNumberThreshold) - return absl::nullopt; - - size_t longest_prefix_length = - FindLongestCommonAffixLength(field_names, false); - size_t longest_suffix_length = - FindLongestCommonAffixLength(field_names, true); - - // Don't remove the common affix if it's not long enough. - if (longest_prefix_length < kMinCommonNameAffixLength) - longest_prefix_length = 0; - - if (longest_suffix_length < kMinCommonNameAffixLength) - longest_suffix_length = 0; - - // If neither a common prefix of suffix was found return false. - if (longest_prefix_length == 0 && longest_suffix_length == 0) { - return absl::nullopt; - } - - // Otherwise try to reduce the names. - return GetStrippedParseableNamesIfValid(field_names, longest_prefix_length, - longest_suffix_length, - /*minimal_string_length_to_strip=*/0); -} - -// Tries to remove common prefixes from |field_names| and returns the result. If +// Tries to remove common prefixes from `field_names` and returns the result. If // neither a common prefix exists, or if one or more of the resulting strings is -// not a valid parseable name, |absl::nullopt| is returned. -// The number of names in |field_names| must exceed -// |kCommonNamePrefixRemovalFieldThreshold| in order to make the prefix +// not a valid parseable name, `absl::nullopt` is returned. +// The number of names in `field_names` must exceed +// `kCommonNamePrefixRemovalFieldThreshold` in order to make the prefix // removal possible. Also, the length of a prefix must exceed -// |kMinCommonNamePrefixLength| to be removed. -OptionalNamePieces RemoveCommonPrefixIfPossible(const NamePieces& field_names) { - // Updates the field name parsed by heuristics if several criteria are met. - // Several fields must be present in the form. +// `kMinCommonNamePrefixLength` to be removed. +absl::optional<NamePieces> RemoveCommonPrefixIfPossible( + const NamePieces& field_names) { if (field_names.size() < kCommonNamePrefixRemovalFieldThreshold) return absl::nullopt; - size_t longest_prefix_length = - FindLongestCommonAffixLength(field_names, false); - - // Don't remove the common affix if it's not long enough. + size_t longest_prefix_length = FindLongestCommonPrefixLength(field_names); if (longest_prefix_length < kMinCommonNamePrefixLength) return absl::nullopt; - // Otherwise try to reduce the names. - return GetStrippedParseableNamesIfValid( - field_names, longest_prefix_length, /*offset_right=*/0, - /*minimal_string_length_to_strip=*/kMinCommonNamePrefixLength); + NamePieces stripped_names; + stripped_names.reserve(field_names.size()); + for (auto& parseable_name : field_names) { + stripped_names.push_back(parseable_name.substr(longest_prefix_length)); + if (!IsValidParseableName(stripped_names.back())) + return absl::nullopt; + } + return stripped_names; } -// If possible, returns field names with a removed common prefix that is common -// to the subset of names in |field_names| with a minimal length of -// |kMinCommonNameLongPrefixLength|. -// The number of names in |field_names| must exceed -// |kCommonNamePrefixRemovalFieldThreshold| in order to make the prefix -// removal possible. Also, the length of a prefix must exceed -// |kMinCommonNameLongPrefixLength| to be removed. -OptionalNamePieces RemoveCommonPrefixForNamesWithMinimalLengthIfPossible( - const NamePieces& field_names) { - // Update the field name parsed by heuristics if several criteria are met. - // Several fields must be present in the form. - if (field_names.size() < kCommonNamePrefixRemovalFieldThreshold) - return absl::nullopt; - - const size_t longest_prefix = - FindLongestCommonPrefixLengthInStringsWithMinimalLength( - field_names, kMinCommonNameLongPrefixLength); - if (longest_prefix < kMinCommonNameLongPrefixLength) { - return absl::nullopt; - } - - return GetStrippedParseableNamesIfValid(field_names, longest_prefix, 0, - kMinCommonNameLongPrefixLength); -} - -std::vector<std::u16string> GetParseableNames(const NamePieces& field_names) { - OptionalNamePieces parseable_names = absl::nullopt; - - std::vector<std::u16string> result; - result.reserve(field_names.size()); - - // If the feature is enabled, try to remove a common affix. If this is not - // possible try to remove lengthy prefixes that may be missing in short names. - if (base::FeatureList::IsEnabled(features::kAutofillLabelAffixRemoval)) { - // Try to remove both common suffixes and prefixes that are common to all - // fields. - parseable_names = RemoveCommonAffixesIfPossible(field_names); - if (!parseable_names.has_value()) { - // Remove prefix common to string that have a minimum length given by - // |kMinCommonNamePrefixLength|. - parseable_names = - RemoveCommonPrefixForNamesWithMinimalLengthIfPossible(field_names); - } - - } else { - parseable_names = RemoveCommonPrefixIfPossible(field_names); - } - - // If there are no parseable names after affix removal, return the original - // field names. - base::ranges::transform( - parseable_names.has_value() ? parseable_names.value() : field_names, - std::back_inserter(result), [](auto& s) { return std::u16string(s); }); - - return result; +NamePieces GetParseableNamesAsStringPiece(const NamePieces* field_names) { + // TODO(crbug.com/1355264): Revise the `AutofillLabelAffixRemoval` feature. + return RemoveCommonPrefixIfPossible(*field_names).value_or(*field_names); } } // namespace autofill
diff --git a/components/autofill/core/browser/form_processing/name_processing_util.h b/components/autofill/core/browser/form_processing/name_processing_util.h index 2bbb77e..6605c15 100644 --- a/components/autofill/core/browser/form_processing/name_processing_util.h +++ b/components/autofill/core/browser/form_processing/name_processing_util.h
@@ -8,55 +8,29 @@ #include <vector> #include "base/strings/string_piece.h" -#include "base/strings/utf_string_conversions.h" -#include "components/autofill/core/browser/form_structure.h" #include "third_party/abseil-cpp/absl/types/optional.h" namespace autofill { #ifdef UNIT_TEST -size_t FindLongestCommonAffixLength( - const std::vector<base::StringPiece16>& strings, - bool findCommonSuffix); +size_t FindLongestCommonPrefixLength( + const std::vector<base::StringPiece16>& strings); -bool IsValidParseableName(const base::StringPiece16 parseable_name); - -absl::optional<std::vector<base::StringPiece16>> RemoveCommonAffixesIfPossible( - const std::vector<base::StringPiece16>& field_names); - -size_t FindLongestCommonPrefixLengthInStringsWithMinimalLength( - const std::vector<base::StringPiece16>& strings, - size_t minimal_length); - -absl::optional<std::vector<base::StringPiece16>> -GetStrippedParseableNamesIfValid( - const std::vector<base::StringPiece16>& field_names, - size_t offset_left, - size_t offset_right, - size_t minimal_string_length_to_strip); +bool IsValidParseableName(base::StringPiece16 parseable_name); absl::optional<std::vector<base::StringPiece16>> RemoveCommonPrefixIfPossible( const std::vector<base::StringPiece16>& field_names); - -absl::optional<std::vector<base::StringPiece16>> -RemoveCommonPrefixForNamesWithMinimalLengthIfPossible( - const std::vector<base::StringPiece16>& field_names); #endif -// Determines and returns the parseable names for |field_names|. -// With the |kAutofillLabelAffixRemoval| feature enabled, first it is tried to -// remove a common affix from all names in |field_names|. If this is not -// possible, it is attempted to remove long prefixes from a subset of names in -// |field_names| which exceed a given length. If the -// |kAutofillLabelAffixRemoval| is disabled, a prefix removal is attempted. In -// any case, if a affix/prefix removal is not possible, the original names in -// |field_names| are returned. -// -// Beware, this function works on string pieces and therefore, it should not be -// called with temporary objects. Also, the underlying strings should not be -// modified before the last usage of the result. -std::vector<std::u16string> GetParseableNames( - const std::vector<base::StringPiece16>& field_names); +// Determines and returns the parseable names of `field_names`, by removing +// long common prefixes. If the common prefix is too short or empty, the +// original names in `field_names` are returned. +// While this function works on a general set of strings, it is solely used for +// the purpose of "rationalizing" the names of `FormFieldData::name`. The result +// is then referred to as the "parseable name" of the field. Hence the +// terminology here. +std::vector<base::StringPiece16> GetParseableNamesAsStringPiece( + const std::vector<base::StringPiece16>* field_names); } // namespace autofill
diff --git a/components/autofill/core/browser/form_processing/name_processing_util_unittest.cc b/components/autofill/core/browser/form_processing/name_processing_util_unittest.cc index cd09fb3..a8d3a296 100644 --- a/components/autofill/core/browser/form_processing/name_processing_util_unittest.cc +++ b/components/autofill/core/browser/form_processing/name_processing_util_unittest.cc
@@ -4,338 +4,67 @@ #include "components/autofill/core/browser/form_processing/name_processing_util.h" -#include "base/feature_list.h" -#include "base/strings/utf_string_conversions.h" -#include "base/test/scoped_feature_list.h" -#include "components/autofill/core/common/autofill_features.h" +#include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -namespace { - -size_t strlen16(const char16_t* str) { - return std::char_traits<char16_t>::length(str); -} - -std::vector<base::StringPiece16> StringsToStringPieces( - const std::vector<std::u16string>& strings) { - std::vector<base::StringPiece16> string_pieces; - for (const auto& s : strings) { - string_pieces.emplace_back(base::StringPiece16(s)); - } - return string_pieces; -} -} // namespace - namespace autofill { +using testing::ElementsAre; + // Tests that the validity of parseable names is determined correctly. TEST(NameProcessingUtil, IsValidParseableName) { // Parseable name should not be empty. EXPECT_FALSE(IsValidParseableName(u"")); // Parseable name should not be solely numerical. EXPECT_FALSE(IsValidParseableName(u"1265125")); - // Valid parseable name cases. EXPECT_TRUE(IsValidParseableName(u"a23")); EXPECT_TRUE(IsValidParseableName(u"*)&%@")); } -// Tests that the correct length of prefixes and suffixes are returned. -TEST(NameProcessingUtil, FindLongestCommonAffixLength) { - auto String16ToStringPiece16 = [](std::vector<std::u16string>& vin, - std::vector<base::StringPiece16>& vout) { - vout.clear(); - for (auto& str : vin) - vout.push_back(str); - }; - - // Normal prefix case. - std::vector<std::u16string> strings; - std::vector<base::StringPiece16> stringPieces; - strings.push_back(u"123456XXX123456789"); - strings.push_back(u"12345678XXX012345678_foo"); - strings.push_back(u"1234567890123456"); - strings.push_back(u"1234567XXX901234567890"); - String16ToStringPiece16(strings, stringPieces); - size_t affixLength = FindLongestCommonAffixLength(stringPieces, false); - EXPECT_EQ(strlen16(u"123456"), affixLength); - - // Normal suffix case. - strings.clear(); - strings.push_back(u"black and gold dress"); - strings.push_back(u"work_address"); - strings.push_back(u"123456XXX1234_home_address"); - strings.push_back(u"1234567890123456_city_address"); - String16ToStringPiece16(strings, stringPieces); - affixLength = FindLongestCommonAffixLength(stringPieces, true); - EXPECT_EQ(strlen16(u"dress"), affixLength); - - // Handles no common prefix. - strings.clear(); - strings.push_back(u"1234567890123456"); - strings.push_back(u"4567890123456789"); - strings.push_back(u"7890123456789012"); - String16ToStringPiece16(strings, stringPieces); - affixLength = FindLongestCommonAffixLength(stringPieces, false); - EXPECT_EQ(strlen16(u""), affixLength); - - // Handles no common suffix. - strings.clear(); - strings.push_back(u"1234567890123456"); - strings.push_back(u"4567890123456789"); - strings.push_back(u"7890123456789012"); - String16ToStringPiece16(strings, stringPieces); - affixLength = FindLongestCommonAffixLength(stringPieces, true); - EXPECT_EQ(strlen16(u""), affixLength); - - // Only one string, prefix case. - strings.clear(); - strings.push_back(u"1234567890"); - String16ToStringPiece16(strings, stringPieces); - affixLength = FindLongestCommonAffixLength(stringPieces, false); - EXPECT_EQ(strlen16(u"1234567890"), affixLength); - - // Only one string, suffix case. - strings.clear(); - strings.push_back(u"1234567890"); - String16ToStringPiece16(strings, stringPieces); - affixLength = FindLongestCommonAffixLength(stringPieces, true); - EXPECT_EQ(strlen16(u"1234567890"), affixLength); - - // Empty vector, prefix case. - strings.clear(); - String16ToStringPiece16(strings, stringPieces); - affixLength = FindLongestCommonAffixLength(stringPieces, false); - EXPECT_EQ(strlen16(u""), affixLength); - - // Empty vector, suffix case. - strings.clear(); - String16ToStringPiece16(strings, stringPieces); - affixLength = FindLongestCommonAffixLength(stringPieces, true); - EXPECT_EQ(strlen16(u""), affixLength); +// Tests that the length of the longest common prefix is computed correctly. +TEST(NameProcessingUtil, FindLongestCommonPrefixLength) { + EXPECT_EQ(base::StringPiece("123456").size(), + FindLongestCommonPrefixLength( + {u"123456XXX123456789", u"12345678XXX012345678_foo", + u"1234567890123456", u"1234567XXX901234567890"})); + EXPECT_EQ(base::StringPiece("1234567890").size(), + FindLongestCommonPrefixLength({u"1234567890"})); + EXPECT_EQ( + 0u, FindLongestCommonPrefixLength( + {u"1234567890123456", u"4567890123456789", u"7890123456789012"})); + EXPECT_EQ(0u, FindLongestCommonPrefixLength({})); } -// Tests the determination of the length of the longest common prefix for -// strings with a minimal length. -TEST(NameProcessingUtil, - FindLongestCommonPrefixLengthForStringsWithMinimalLength) { - std::vector<std::u16string> strings; - strings.push_back(u"aabbccddeeff"); - strings.push_back(u"aabbccddeeffgg"); - strings.push_back(u"zzz"); - strings.push_back(u"aabbc___"); - EXPECT_EQ(FindLongestCommonPrefixLengthInStringsWithMinimalLength( - StringsToStringPieces(strings), 4), - 5U); - EXPECT_EQ(FindLongestCommonPrefixLengthInStringsWithMinimalLength( - StringsToStringPieces(strings), 3), - 0U); -} - -// Tests that a |absl::nullopt| is returned if no common affix was removed. -TEST(NameProcessingUtil, RemoveCommonAffixesIfPossible_NotPossible) { - std::vector<std::u16string> strings; - strings.push_back(u"abc"); - strings.push_back(u"def"); - strings.push_back(u"abcd"); - strings.push_back(u"abcdef"); - - EXPECT_EQ(RemoveCommonAffixesIfPossible(StringsToStringPieces(strings)), - absl::nullopt); -} - -// Tests that both the prefix and the suffix are removed. -TEST(NameProcessingUtil, RemoveCommonAffixesIfPossible) { - std::vector<std::u16string> strings; - strings.push_back(u"abcaazzz"); - strings.push_back(u"abcbbzzz"); - strings.push_back(u"abccczzz"); - - std::vector<std::u16string> expectation; - expectation.push_back(u"aa"); - expectation.push_back(u"bb"); - expectation.push_back(u"cc"); - - EXPECT_EQ(RemoveCommonAffixesIfPossible(StringsToStringPieces(strings)), - StringsToStringPieces(expectation)); -} - -// Tests that a |absl::nullopt| is returned if no common prefix was removed. -TEST(NameProcessingUtil, RemoveCommonPrefixIfPossible_NotPossible) { - std::vector<std::u16string> strings; - strings.push_back(u"abc"); - strings.push_back(u"def"); - strings.push_back(u"abcd"); - strings.push_back(u"abcdef"); - - EXPECT_EQ(RemoveCommonPrefixIfPossible(StringsToStringPieces(strings)), - absl::nullopt); -} - -// Tests that prefix is removed correctly. TEST(NameProcessingUtil, RemoveCommonPrefixIfPossible) { - std::vector<std::u16string> strings; - // The strings contain a long common prefix that can be removed. - strings.push_back(u"ccccccccccccccccaazzz"); - strings.push_back(u"ccccccccccccccccbbzzz"); - strings.push_back(u"cccccccccccccccccczzz"); - - std::vector<std::u16string> expectation; - expectation.push_back(u"aazzz"); - expectation.push_back(u"bbzzz"); - expectation.push_back(u"cczzz"); - - EXPECT_EQ(RemoveCommonPrefixIfPossible(StringsToStringPieces(strings)), - StringsToStringPieces(expectation)); -} - -// Tests that prefix is removed correctly for fields with a minimal length. -TEST(NameProcessingUtil, - RemoveCommonPrefixForFieldsWithMinimalLengthIfPossible) { - std::vector<std::u16string> strings; - strings.push_back(u"ccccccccccccccccaazzz"); - // This name is too short to be considered and is skipped both in the - // detection of prefixes as well as in the removal. - strings.push_back(u"abc"); - strings.push_back(u"cccccccccccccccccczzz"); - - std::vector<std::u16string> expectation; - expectation.push_back(u"aazzz"); - expectation.push_back(u"abc"); - expectation.push_back(u"cczzz"); - - EXPECT_EQ(RemoveCommonPrefixForNamesWithMinimalLengthIfPossible( - StringsToStringPieces(strings)), - StringsToStringPieces(expectation)); -} - -// Tests that prefix is not removed because it is too short. -TEST(NameProcessingUtil, RemoveCommonPrefixIfPossible_TooShort) { - std::vector<std::u16string> strings; - strings.push_back(u"abcaazzz"); - strings.push_back(u"abcbbzzz"); - strings.push_back(u"abccczzz"); - - EXPECT_EQ(RemoveCommonPrefixIfPossible(StringsToStringPieces(strings)), - absl::nullopt); -} - -// Tests that the strings are correctly stripped. -TEST(NameProcessingUtil, GetStrippedParseableNamesIfValid) { - std::vector<std::u16string> strings; - strings.push_back(u"abcaazzz"); - strings.push_back(u"abcbbzzz"); - strings.push_back(u"abccczzz"); - - std::vector<std::u16string> expectation; - expectation.push_back(u"aaz"); - expectation.push_back(u"bbz"); - expectation.push_back(u"ccz"); - - EXPECT_EQ( - GetStrippedParseableNamesIfValid(StringsToStringPieces(strings), 3, 2, 1), - StringsToStringPieces(expectation)); -} - -// Tests that a |absl::nullopt| is returned if one of stripped names is not -// valid. -TEST(NameProcessingUtil, GetStrippedParseableNamesIfValid_NotValid) { - std::vector<std::u16string> strings; - strings.push_back(u"abcaazzz"); - // This string is not valid because only the "1" is left after stripping. - strings.push_back(u"abc1zz"); - strings.push_back(u"abccczzz"); - - std::vector<std::u16string> expectation; - expectation.push_back(u"aaz"); - expectation.push_back(u"bbz"); - expectation.push_back(u"ccz"); - - EXPECT_EQ( - GetStrippedParseableNamesIfValid(StringsToStringPieces(strings), 3, 2, 1), - absl::nullopt); + // No common prefix. + EXPECT_FALSE( + RemoveCommonPrefixIfPossible({u"abc", u"def", u"abcd", u"abcdef"})); + // The common prefix is too short. + EXPECT_FALSE( + RemoveCommonPrefixIfPossible({u"abcaazzz", u"abcbbzzz", u"abccczzz"})); + // Not enough strings. + EXPECT_FALSE(RemoveCommonPrefixIfPossible( + {u"ccccccccccccccccaazzz", u"ccccccccccccccccbbzzz"})); + // A long common prefix of enough strings is removed. + EXPECT_THAT(RemoveCommonPrefixIfPossible({u"ccccccccccccccccaazzz", + u"ccccccccccccccccbbzzz", + u"cccccccccccccccccczzz"}), + testing::Optional(ElementsAre(u"aazzz", u"bbzzz", u"cczzz"))); } // Tests that the parseable names are returned correctly. -TEST(NameProcessingUtil, GetParseableNames_OnlyPrefix) { - std::vector<std::u16string> strings; - strings.push_back(u"abcaazzz1"); - strings.push_back(u"abcbbzzz2"); - strings.push_back(u"abccczzz3"); - - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitAndEnableFeature( - features::kAutofillLabelAffixRemoval); - - // With the feature turned on, the prefix is removed. - std::vector<std::u16string> expectation; - expectation.push_back(u"aazzz1"); - expectation.push_back(u"bbzzz2"); - expectation.push_back(u"cczzz3"); - - EXPECT_EQ(GetParseableNames(StringsToStringPieces(strings)), expectation); -} - -// Tests that the parseable names are returned correctly. -TEST(NameProcessingUtil, GetParseableNames_OnlySuffix) { - std::vector<std::u16string> strings; - strings.push_back(u"1aazzz"); - strings.push_back(u"2bbzzz"); - strings.push_back(u"3cczzz"); - - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitAndEnableFeature( - features::kAutofillLabelAffixRemoval); - - // With the feature turned on, the suffix is removed. - std::vector<std::u16string> expectation; - expectation.push_back(u"1aa"); - expectation.push_back(u"2bb"); - expectation.push_back(u"3cc"); - - EXPECT_EQ(GetParseableNames(StringsToStringPieces(strings)), expectation); -} - -// Tests that the parseable names are returned correctly. -TEST(NameProcessingUtil, GetParseableNames_Affix) { - std::vector<std::u16string> strings; - strings.push_back(u"abcaazzz"); - strings.push_back(u"abcbbzzz"); - strings.push_back(u"abccczzz"); - - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitAndEnableFeature( - features::kAutofillLabelAffixRemoval); - - // With the feature turned on, the prefix and affix is removed. - std::vector<std::u16string> expectation; - expectation.push_back(u"aa"); - expectation.push_back(u"bb"); - expectation.push_back(u"cc"); - - EXPECT_EQ(GetParseableNames(StringsToStringPieces(strings)), expectation); - - scoped_feature_list.Reset(); - scoped_feature_list.InitAndDisableFeature( - features::kAutofillLabelAffixRemoval); - - // With the feature turned off, the names are too short for a prefix removal. - expectation.clear(); - expectation.push_back(u"abcaazzz"); - expectation.push_back(u"abcbbzzz"); - expectation.push_back(u"abccczzz"); - EXPECT_EQ(GetParseableNames(StringsToStringPieces(strings)), expectation); - - // But very long prefixes are still removed. - strings.clear(); - strings.push_back(u"1234567890ABCDEFGabcaazzz"); - strings.push_back(u"1234567890ABCDEFGabcbbzzz"); - strings.push_back(u"1234567890ABCDEFGabccczzz"); - - expectation.clear(); - expectation.push_back(u"aazzz"); - expectation.push_back(u"bbzzz"); - expectation.push_back(u"cczzz"); - EXPECT_EQ(GetParseableNames(StringsToStringPieces(strings)), expectation); +TEST(NameProcessingUtil, GetParseableNames) { + // The prefix is too short, so the original strings are returned. + std::vector<base::StringPiece16> short_prefix{u"abcaazzz", u"abcbbzzz", + u"abccczzz"}; + EXPECT_THAT(GetParseableNamesAsStringPiece(&short_prefix), + testing::ElementsAreArray(short_prefix)); + // Long prefixes are removed. + std::vector<base::StringPiece16> long_prefix{u"1234567890ABCDEFGabcaazzz", + u"1234567890ABCDEFGabcbbzzz", + u"1234567890ABCDEFGabccczzz"}; + EXPECT_THAT(GetParseableNamesAsStringPiece(&long_prefix), + ElementsAre(u"aazzz", u"bbzzz", u"cczzz")); } } // namespace autofill
diff --git a/components/autofill/core/browser/form_structure.cc b/components/autofill/core/browser/form_structure.cc index 5491f1b..38ae316 100644 --- a/components/autofill/core/browser/form_structure.cc +++ b/components/autofill/core/browser/form_structure.cc
@@ -2376,11 +2376,12 @@ } // Determine the parseable names and write them into the corresponding field. - std::vector<std::u16string> parseable_names = GetParseableNames(names); + std::vector<base::StringPiece16> parseable_names = + GetParseableNamesAsStringPiece(&names); DCHECK_EQ(parseable_names.size(), field_count()); size_t idx = 0; for (auto& field : *this) { - field->set_parseable_name(parseable_names.at(idx++)); + field->set_parseable_name(std::u16string(parseable_names[idx++])); } }
diff --git a/components/autofill/core/browser/form_structure_unittest.cc b/components/autofill/core/browser/form_structure_unittest.cc index c3e7dae..66a6306 100644 --- a/components/autofill/core/browser/form_structure_unittest.cc +++ b/components/autofill/core/browser/form_structure_unittest.cc
@@ -662,262 +662,6 @@ } // All fields share a common prefix which could confuse the heuristics. Test -// that the common prefixes are stripped out before running heuristics. -// This test ensures that |parseable_name| is used for heuristics. -TEST_F(FormStructureTestImpl, StripCommonNameAffix) { - base::test::ScopedFeatureList feature_list; - feature_list.InitAndEnableFeature(kAutofillLabelAffixRemoval); - - FormData form; - form.url = GURL("http://www.foo.com/"); - - FormFieldData field; - field.form_control_type = "text"; - - field.label = u"First Name"; - field.name = u"ctl01$ctl00$ShippingAddressCreditPhone$firstname"; - field.unique_renderer_id = test::MakeFieldRendererId(); - form.fields.push_back(field); - - field.label = u"Last Name"; - field.name = u"ctl01$ctl00$ShippingAddressCreditPhone$lastname"; - field.unique_renderer_id = test::MakeFieldRendererId(); - form.fields.push_back(field); - - field.label = u"Email"; - field.name = u"ctl01$ctl00$ShippingAddressCreditPhone$email"; - field.unique_renderer_id = test::MakeFieldRendererId(); - form.fields.push_back(field); - - field.label = u"Phone"; - field.name = u"ctl01$ctl00$ShippingAddressCreditPhone$phone"; - field.unique_renderer_id = test::MakeFieldRendererId(); - form.fields.push_back(field); - - field.label = std::u16string(); - field.name = u"ctl01$ctl00$ShippingAddressCreditPhone$submit"; - field.form_control_type = "submit"; - field.unique_renderer_id = test::MakeFieldRendererId(); - form.fields.push_back(field); - - std::unique_ptr<FormStructure> form_structure(new FormStructure(form)); - form_structure->DetermineHeuristicTypes(nullptr, nullptr); - EXPECT_TRUE(form_structure->IsAutofillable()); - - // Expect the correct number of fields. - ASSERT_EQ(5U, form_structure->field_count()); - ASSERT_EQ(4U, form_structure->autofill_count()); - - // First name. - EXPECT_EQ(u"firstname", form_structure->field(0)->parseable_name()); - EXPECT_EQ(NAME_FIRST, form_structure->field(0)->heuristic_type()); - // Last name. - EXPECT_EQ(u"lastname", form_structure->field(1)->parseable_name()); - EXPECT_EQ(NAME_LAST, form_structure->field(1)->heuristic_type()); - // Email. - EXPECT_EQ(u"email", form_structure->field(2)->parseable_name()); - EXPECT_EQ(EMAIL_ADDRESS, form_structure->field(2)->heuristic_type()); - // Phone. - EXPECT_EQ(u"phone", form_structure->field(3)->parseable_name()); - EXPECT_EQ(PHONE_HOME_WHOLE_NUMBER, - form_structure->field(3)->heuristic_type()); - // Submit. - EXPECT_EQ(u"submit", form_structure->field(4)->parseable_name()); - EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(4)->heuristic_type()); -} - -// All fields share a common prefix, but it's not stripped due to -// the |IsValidParseableName()| rule. -TEST_F(FormStructureTestImpl, StripCommonNameAffix_SmallPrefix) { - base::test::ScopedFeatureList feature_list; - feature_list.InitAndEnableFeature(kAutofillLabelAffixRemoval); - - FormData form; - form.url = GURL("http://www.foo.com/"); - - FormFieldData field; - field.form_control_type = "text"; - - field.label = u"Address 1"; - field.name = u"address1"; - form.fields.push_back(field); - - field.label = u"Address 2"; - field.name = u"address2"; - form.fields.push_back(field); - - field.label = u"Address 3"; - field.name = u"address3"; - form.fields.push_back(field); - - std::unique_ptr<FormStructure> form_structure(new FormStructure(form)); - - // Expect the correct number of fields. - ASSERT_EQ(3U, form_structure->field_count()); - - // Address 1. - EXPECT_EQ(u"address1", form_structure->field(0)->parseable_name()); - // Address 2. - EXPECT_EQ(u"address2", form_structure->field(1)->parseable_name()); - // Address 3 - EXPECT_EQ(u"address3", form_structure->field(2)->parseable_name()); -} - -// All fields share both a common prefix and suffix which could confuse the -// heuristics. Test that the common affixes are stripped out from -// |parseable_name| during |FormStructure| initialization. -TEST_F(FormStructureTestImpl, StripCommonNameAffix_PrefixAndSuffix) { - base::test::ScopedFeatureList feature_list; - feature_list.InitAndEnableFeature(kAutofillLabelAffixRemoval); - - FormData form; - form.url = GURL("http://www.foo.com/"); - - FormFieldData field; - field.form_control_type = "text"; - - field.label = u"First Name"; - field.name = u"ctl01$ctl00$ShippingAddressCreditPhone$firstname_data"; - form.fields.push_back(field); - - field.label = u"Last Name"; - field.name = u"ctl01$ctl00$ShippingAddressCreditPhone$lastname_data"; - form.fields.push_back(field); - - field.label = u"Email"; - field.name = u"ctl01$ctl00$ShippingAddressCreditPhone$email_data"; - form.fields.push_back(field); - - field.label = u"Phone"; - field.name = u"ctl01$ctl00$ShippingAddressCreditPhone$phone_data"; - form.fields.push_back(field); - - field.label = std::u16string(); - field.name = u"ctl01$ctl00$ShippingAddressCreditPhone$submit_data"; - field.form_control_type = "submit"; - form.fields.push_back(field); - - std::unique_ptr<FormStructure> form_structure(new FormStructure(form)); - - // Expect the correct number of fields. - ASSERT_EQ(5U, form_structure->field_count()); - - // First name. - EXPECT_EQ(u"firstname", form_structure->field(0)->parseable_name()); - // Last name. - EXPECT_EQ(u"lastname", form_structure->field(1)->parseable_name()); - // Email. - EXPECT_EQ(u"email", form_structure->field(2)->parseable_name()); - // Phone. - EXPECT_EQ(u"phone", form_structure->field(3)->parseable_name()); - // Submit. - EXPECT_EQ(u"submit", form_structure->field(4)->parseable_name()); -} - -// Only some fields share a long common long prefix, no fields share a suffix. -// Test that only the common prefixes are stripped out in |parseable_name| -// during |FormStructure| initialization. -TEST_F(FormStructureTestImpl, StripCommonNameAffix_SelectiveLongPrefix) { - base::test::ScopedFeatureList feature_list; - feature_list.InitAndEnableFeature(kAutofillLabelAffixRemoval); - - FormData form; - form.url = GURL("http://www.foo.com/"); - - FormFieldData field; - field.form_control_type = "text"; - - field.label = u"First Name"; - field.name = u"ctl01$ctl00$ShippingAddressCreditPhone$firstname"; - form.fields.push_back(field); - - field.label = u"Last Name"; - field.name = u"ctl01$ctl00$ShippingAddressCreditPhone$lastname"; - form.fields.push_back(field); - - field.label = u"Email"; - field.name = u"email"; - form.fields.push_back(field); - - field.label = u"Phone"; - field.name = u"phone"; - form.fields.push_back(field); - - field.label = std::u16string(); - field.name = u"ctl01$ctl00$ShippingAddressCreditPhone$submit"; - field.form_control_type = "submit"; - form.fields.push_back(field); - - std::unique_ptr<FormStructure> form_structure(new FormStructure(form)); - - // Expect the correct number of fields. - ASSERT_EQ(5U, form_structure->field_count()); - - // First name. - EXPECT_EQ(u"firstname", form_structure->field(0)->parseable_name()); - // Last name. - EXPECT_EQ(u"lastname", form_structure->field(1)->parseable_name()); - // Email. - EXPECT_EQ(u"email", form_structure->field(2)->parseable_name()); - // Phone. - EXPECT_EQ(u"phone", form_structure->field(3)->parseable_name()); - // Submit. - EXPECT_EQ(u"submit", form_structure->field(4)->parseable_name()); -} - -// Only some fields share a long common short prefix, no fields share a suffix. -// Test that short uncommon prefixes are not stripped (even if there are -// enough). -TEST_F(FormStructureTestImpl, - StripCommonNameAffix_SelectiveLongPrefixIgnoreLength) { - base::test::ScopedFeatureList feature_list; - feature_list.InitAndEnableFeature(kAutofillLabelAffixRemoval); - - FormData form; - form.url = GURL("http://www.foo.com/"); - - FormFieldData field; - field.form_control_type = "text"; - - field.label = u"First Name"; - field.name = u"firstname"; - form.fields.push_back(field); - - field.label = u"Last Name"; - field.name = u"lastname"; - form.fields.push_back(field); - - field.label = u"Street Name"; - field.name = u"address_streetname"; - form.fields.push_back(field); - - field.label = u"Phone"; - field.name = u"address_housenumber"; - form.fields.push_back(field); - - field.label = std::u16string(); - field.name = u"address_apartmentnumber"; - form.fields.push_back(field); - - std::unique_ptr<FormStructure> form_structure(new FormStructure(form)); - - // Expect the correct number of fields. - ASSERT_EQ(5U, form_structure->field_count()); - - // First name. - EXPECT_EQ(u"firstname", form_structure->field(0)->parseable_name()); - // Last name. - EXPECT_EQ(u"lastname", form_structure->field(1)->parseable_name()); - // Email. - EXPECT_EQ(u"address_streetname", form_structure->field(2)->parseable_name()); - // Phone. - EXPECT_EQ(u"address_housenumber", form_structure->field(3)->parseable_name()); - // Submit. - EXPECT_EQ(u"address_apartmentnumber", - form_structure->field(4)->parseable_name()); -} - -// All fields share a common prefix which could confuse the heuristics. Test // that the common prefix is stripped out before running heuristics. TEST_F(FormStructureTestImpl, StripCommonNamePrefix) { CheckFormStructureTestData(
diff --git a/components/autofill_assistant/browser/actions/configure_bottom_sheet_action_unittest.cc b/components/autofill_assistant/browser/actions/configure_bottom_sheet_action_unittest.cc index 5203db0..3622afb 100644 --- a/components/autofill_assistant/browser/actions/configure_bottom_sheet_action_unittest.cc +++ b/components/autofill_assistant/browser/actions/configure_bottom_sheet_action_unittest.cc
@@ -57,10 +57,10 @@ *action_proto.mutable_configure_bottom_sheet() = proto_; action_ = std::make_unique<ConfigureBottomSheetAction>( &mock_action_delegate_, action_proto); - action_->ProcessAction(base::BindOnce(base::BindLambdaForTesting( + action_->ProcessAction(base::BindLambdaForTesting( [&](std::unique_ptr<ProcessedActionProto> result) { processed_action_ = *result; - }))); + })); } // Runs an action that waits for a resize.
diff --git a/components/autofill_assistant/browser/actions/wait_for_document_action_unittest.cc b/components/autofill_assistant/browser/actions/wait_for_document_action_unittest.cc index 94c92a9..c8ea7ac 100644 --- a/components/autofill_assistant/browser/actions/wait_for_document_action_unittest.cc +++ b/components/autofill_assistant/browser/actions/wait_for_document_action_unittest.cc
@@ -50,11 +50,11 @@ *action_proto.mutable_wait_for_document() = proto_; action_ = std::make_unique<WaitForDocumentAction>(&mock_action_delegate_, action_proto); - action_->ProcessAction(base::BindOnce(base::BindLambdaForTesting( + action_->ProcessAction(base::BindLambdaForTesting( [&](std::unique_ptr<ProcessedActionProto> result) { LOG(ERROR) << "Got Processed action Result"; processed_action_ = *result; - }))); + })); } protected:
diff --git a/components/media_router/browser/logger_impl.cc b/components/media_router/browser/logger_impl.cc index 3454f42..c2e8f7e1 100644 --- a/components/media_router/browser/logger_impl.cc +++ b/components/media_router/browser/logger_impl.cc
@@ -64,7 +64,10 @@ } // namespace LoggerImpl::LoggerImpl() : capacity_(kEntriesCapacity) {} -LoggerImpl::~LoggerImpl() = default; + +LoggerImpl::~LoggerImpl() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); +} void LoggerImpl::LogInfo(mojom::LogCategory category, const std::string& component, @@ -72,6 +75,7 @@ const std::string& sink_id, const std::string& media_source, const std::string& session_id) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); Log(Severity::kInfo, category, base::Time::Now(), component, message, sink_id, media_source, session_id); } @@ -82,6 +86,7 @@ const std::string& sink_id, const std::string& media_source, const std::string& session_id) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); Log(Severity::kWarning, category, base::Time::Now(), component, message, sink_id, media_source, session_id); } @@ -92,14 +97,34 @@ const std::string& sink_id, const std::string& media_source, const std::string& session_id) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); Log(Severity::kError, category, base::Time::Now(), component, message, sink_id, media_source, session_id); } void LoggerImpl::BindReceiver(mojo::PendingReceiver<mojom::Logger> receiver) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); receivers_.Add(this, std::move(receiver)); } +void LoggerImpl::Log(Severity severity, + mojom::LogCategory category, + base::Time time, + const std::string& component, + const std::string& message, + const std::string& sink_id, + const std::string& media_source, + const std::string& session_id) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + entries_.emplace_back( + severity, category, time, TruncateComponent(component), + TruncateMessage(message), TruncateId(sink_id), + MediaSource(media_source).TruncateForLogging(kSourceMaxLength), + TruncateId(session_id)); + if (entries_.size() > capacity_) + entries_.pop_front(); +} + std::string LoggerImpl::GetLogsAsJson() const { std::string json; JSONStringValueSerializer serializer(&json); @@ -147,23 +172,6 @@ LoggerImpl::Entry::~Entry() = default; -void LoggerImpl::Log(Severity severity, - mojom::LogCategory category, - base::Time time, - const std::string& component, - const std::string& message, - const std::string& sink_id, - const std::string& media_source, - const std::string& session_id) { - entries_.emplace_back( - severity, category, time, TruncateComponent(component), - TruncateMessage(message), TruncateId(sink_id), - MediaSource(media_source).TruncateForLogging(kSourceMaxLength), - TruncateId(session_id)); - if (entries_.size() > capacity_) - entries_.pop_front(); -} - // static base::Value LoggerImpl::AsValue(const LoggerImpl::Entry& entry) { base::Value entry_val(base::Value::Type::DICTIONARY);
diff --git a/components/media_router/browser/logger_impl.h b/components/media_router/browser/logger_impl.h index 74eb6ec..72d3daa 100644 --- a/components/media_router/browser/logger_impl.h +++ b/components/media_router/browser/logger_impl.h
@@ -50,6 +50,16 @@ const std::string& session_id) override; void BindReceiver(mojo::PendingReceiver<mojom::Logger> receiver) override; + // Called by tests or in-regular use that want to specify `time`. + void Log(Severity severity, + mojom::LogCategory category, + base::Time time, + const std::string& component, + const std::string& message, + const std::string& sink_id, + const std::string& media_source, + const std::string& session_id); + std::string GetLogsAsJson() const; base::Value GetLogsAsValue() const; @@ -84,21 +94,13 @@ std::string session_id; }; - // Called by tests that want to specify |time|. - void Log(Severity severity, - mojom::LogCategory category, - base::Time time, - const std::string& component, - const std::string& message, - const std::string& sink_id, - const std::string& media_source, - const std::string& session_id); - static base::Value AsValue(const Entry& entry); mojo::ReceiverSet<mojom::Logger> receivers_; base::circular_deque<Entry> entries_; size_t const capacity_; + + SEQUENCE_CHECKER(sequence_checker_); }; } // namespace media_router
diff --git a/components/media_router/browser/logger_impl_unittest.cc b/components/media_router/browser/logger_impl_unittest.cc index 59e5914e..799ed199 100644 --- a/components/media_router/browser/logger_impl_unittest.cc +++ b/components/media_router/browser/logger_impl_unittest.cc
@@ -53,7 +53,7 @@ std::string GetAttributeOfFirstEntry(const std::string& logs_json, const std::string& attribute) { base::Value logs = base::JSONReader::Read(logs_json).value(); - return *logs.GetListDeprecated()[0].FindStringKey(attribute); + return *logs.GetList()[0].FindStringKey(attribute); } };
diff --git a/components/net_log/net_log_proxy_source_unittest.cc b/components/net_log/net_log_proxy_source_unittest.cc index a548c8a..3ea1cd6e 100644 --- a/components/net_log/net_log_proxy_source_unittest.cc +++ b/components/net_log/net_log_proxy_source_unittest.cc
@@ -187,9 +187,9 @@ // templatized which seems to confuse BindOnce. Capturing is safe here as // the test will WaitForExpectedEntries() before completing. base::ThreadPool::PostTask( - FROM_HERE, base::BindOnce(base::BindLambdaForTesting([&]() { + FROM_HERE, base::BindLambdaForTesting([&]() { source1.EndEvent(net::NetLogEventType::SOCKET_ALIVE); - }))); + })); // Wait for all the expected events to be proxied over the mojo pipe and // recorded.
diff --git a/components/offline_pages/core/offline_page_metadata_store_test_util.cc b/components/offline_pages/core/offline_page_metadata_store_test_util.cc index 49ce272..14621b4fd 100644 --- a/components/offline_pages/core/offline_page_metadata_store_test_util.cc +++ b/components/offline_pages/core/offline_page_metadata_store_test_util.cc
@@ -103,12 +103,12 @@ OfflinePageItem* page = nullptr; auto task = std::make_unique<GetPagesTask>( store(), criteria, - base::BindOnce(base::BindLambdaForTesting( + base::BindLambdaForTesting( [&](const std::vector<OfflinePageItem>& cb_pages) { if (!cb_pages.empty()) page = new OfflinePageItem(cb_pages[0]); run_loop.Quit(); - }))); + })); task->Execute(base::DoNothing()); run_loop.Run(); return base::WrapUnique<OfflinePageItem>(page);
diff --git a/components/page_load_metrics/browser/metrics_web_contents_observer_unittest.cc b/components/page_load_metrics/browser/metrics_web_contents_observer_unittest.cc index 82d4966a..e411771 100644 --- a/components/page_load_metrics/browser/metrics_web_contents_observer_unittest.cc +++ b/components/page_load_metrics/browser/metrics_web_contents_observer_unittest.cc
@@ -1569,10 +1569,23 @@ MetricsWebContentsObserverNonPrimaryPageTest* owner) : owner_(owner) {} - // TODO(https://crbug.com/1317494): Audit and use appropriate policy. + const char* GetObserverName() const override { + static const char kName[] = + "MetricsWebContentsObserverNonPrimaryPageTest::MetricsObserver"; + return kName; + } + ObservePolicy OnFencedFramesStart( content::NavigationHandle* navigation_handle, const GURL& currently_committed_url) override { + // Takes the default option to test general cases. + return FORWARD_OBSERVING; + } + + ObservePolicy OnPrerenderStart( + content::NavigationHandle* navigation_handle, + const GURL& currently_committed_url) override { + // This class's users don't need to support Prerendering yet. return STOP_OBSERVING; }
diff --git a/components/page_load_metrics/browser/observers/assert_page_load_metrics_observer.cc b/components/page_load_metrics/browser/observers/assert_page_load_metrics_observer.cc index 4e3b783d..ba3f2e0e 100644 --- a/components/page_load_metrics/browser/observers/assert_page_load_metrics_observer.cc +++ b/components/page_load_metrics/browser/observers/assert_page_load_metrics_observer.cc
@@ -75,6 +75,10 @@ DCHECK(!activated_); committed_ = true; + DCHECK(navigation_handle->IsInPrimaryMainFrame() || + navigation_handle->IsInPrerenderedMainFrame()); + DCHECK(!navigation_handle->IsPrerenderedPageActivation()); + return CONTINUE_OBSERVING; }
diff --git a/components/printing/browser/print_to_pdf/pdf_print_job.cc b/components/printing/browser/print_to_pdf/pdf_print_job.cc index d935d99..438a843 100644 --- a/components/printing/browser/print_to_pdf/pdf_print_job.cc +++ b/components/printing/browser/print_to_pdf/pdf_print_job.cc
@@ -69,6 +69,9 @@ case printing::mojom::PrintFailureReason::kInvalidPageRange: FailJob(PdfPrintResult::kPageCountExceeded); return; + case printing::mojom::PrintFailureReason::kPrintingInProgress: + FailJob(PdfPrintResult::kPrintingInProgress); + return; } }
diff --git a/components/printing/browser/print_to_pdf/pdf_print_result.cc b/components/printing/browser/print_to_pdf/pdf_print_result.cc index d51c6df..e958ea3d0 100644 --- a/components/printing/browser/print_to_pdf/pdf_print_result.cc +++ b/components/printing/browser/print_to_pdf/pdf_print_result.cc
@@ -12,8 +12,6 @@ return std::string(); // no error message case PdfPrintResult::kPrintFailure: return "Printing failed"; - case PdfPrintResult::kInvalidPrinterSettings: - return "Show invalid printer settings error"; case PdfPrintResult::kInvalidSharedMemoryRegion: return "Invalid shared memory region"; case PdfPrintResult::kInvalidSharedMemoryMapping: @@ -24,6 +22,8 @@ return "Page range is invalid (start > end)"; case PdfPrintResult::kPageCountExceeded: return "Page range exceeds page count"; + case PdfPrintResult::kPrintingInProgress: + return "Page is already being printed"; } }
diff --git a/components/printing/browser/print_to_pdf/pdf_print_result.h b/components/printing/browser/print_to_pdf/pdf_print_result.h index e650918..49f4919 100644 --- a/components/printing/browser/print_to_pdf/pdf_print_result.h +++ b/components/printing/browser/print_to_pdf/pdf_print_result.h
@@ -12,12 +12,12 @@ enum class PdfPrintResult { kPrintSuccess, kPrintFailure, - kInvalidPrinterSettings, kInvalidSharedMemoryRegion, kInvalidSharedMemoryMapping, kPageRangeSyntaxError, kPageRangeInvalidRange, kPageCountExceeded, + kPrintingInProgress, }; std::string PdfPrintResultToString(PdfPrintResult result);
diff --git a/components/printing/common/print.mojom b/components/printing/common/print.mojom index 95d9f190..255a687 100644 --- a/components/printing/common/print.mojom +++ b/components/printing/common/print.mojom
@@ -273,6 +273,7 @@ enum PrintFailureReason { kGeneralFailure, kInvalidPageRange, + kPrintingInProgress, }; union PrintWithParamsResult {
diff --git a/components/printing/renderer/print_render_frame_helper.cc b/components/printing/renderer/print_render_frame_helper.cc index 2331b4d..1908f32 100644 --- a/components/printing/renderer/print_render_frame_helper.cc +++ b/components/printing/renderer/print_render_frame_helper.cc
@@ -1350,6 +1350,12 @@ return; } + if (print_with_params_callback_) { + std::move(callback).Run(mojom::PrintWithParamsResult::NewFailureReason( + mojom::PrintFailureReason::kPrintingInProgress)); + return; + } + blink::WebLocalFrame* frame = render_frame()->GetWebFrame(); frame->DispatchBeforePrintEvent(/*print_client=*/nullptr); // Don't print if the RenderFrame is gone. @@ -1359,6 +1365,8 @@ return; } + print_with_params_callback_ = std::move(callback); + // If we are printing a frame with an internal PDF plugin element, find the // plugin node and print that instead. auto plugin_node = delegate_->GetPdfElement(frame); @@ -1373,9 +1381,6 @@ prep_frame_view_ = std::make_unique<PrepareFrameAndViewForPrint>( *settings->params, frame, plugin_node, /* ignore_css_margins=*/false); - CHECK(!print_with_params_callback_); - print_with_params_callback_ = std::move(callback); - PrintPages(); FinishFramePrinting();
diff --git a/components/signin/ios/browser/account_consistency_service_unittest.mm b/components/signin/ios/browser/account_consistency_service_unittest.mm index 4621cd6..d985c9d 100644 --- a/components/signin/ios/browser/account_consistency_service_unittest.mm +++ b/components/signin/ios/browser/account_consistency_service_unittest.mm
@@ -358,12 +358,12 @@ base::RunLoop run_loop; network::mojom::CookieManager* cookie_manager = browser_state_.GetCookieManager(); - cookie_manager->GetAllCookies(base::BindOnce(base::BindLambdaForTesting( + cookie_manager->GetAllCookies(base::BindLambdaForTesting( [&run_loop, &cookies_out](const std::vector<net::CanonicalCookie>& cookies) { cookies_out = cookies; run_loop.Quit(); - }))); + })); run_loop.Run(); return cookies_out;
diff --git a/content/browser/attribution_reporting/attribution_test_utils.cc b/content/browser/attribution_reporting/attribution_test_utils.cc index c8746c97..597d89bd 100644 --- a/content/browser/attribution_reporting/attribution_test_utils.cc +++ b/content/browser/attribution_reporting/attribution_test_utils.cc
@@ -1381,11 +1381,10 @@ AttributionReport::ReportType::kEventLevel, AttributionReport::ReportType::kAggregatableAttribution}, /*limit=*/-1, - base::BindOnce(base::BindLambdaForTesting( - [&](std::vector<AttributionReport> reports) { - attribution_reports = std::move(reports); - run_loop.Quit(); - }))); + base::BindLambdaForTesting([&](std::vector<AttributionReport> reports) { + attribution_reports = std::move(reports); + run_loop.Quit(); + })); run_loop.Run(); return attribution_reports; }
diff --git a/content/browser/compositor/viz_process_transport_factory.cc b/content/browser/compositor/viz_process_transport_factory.cc index 4a9cf8ff..46471262 100644 --- a/content/browser/compositor/viz_process_transport_factory.cc +++ b/content/browser/compositor/viz_process_transport_factory.cc
@@ -450,9 +450,16 @@ scoped_refptr<gpu::GpuChannelHost> gpu_channel_host) { DCHECK(!is_gpu_compositing_disabled_); - // Fallback to software compositing if there is no IPC channel. - if (!gpu_channel_host) + if (!gpu_channel_host) { +#if BUILDFLAG(IS_CHROMEOS_ASH) + // Chrome OS can't fallback to software compositing so treat this as a + // transient failure and retry initializing GPU channel. + return gpu::ContextResult::kTransientFailure; +#else + // Fallback to software compositing if there is no IPC channel. return gpu::ContextResult::kFatalFailure; +#endif + } const auto& gpu_feature_info = gpu_channel_host->gpu_feature_info(); // Fallback to software compositing if GPU compositing is blacklisted.
diff --git a/content/browser/fenced_frame/fenced_frame.h b/content/browser/fenced_frame/fenced_frame.h index 9d5b3a5..3cabc5b 100644 --- a/content/browser/fenced_frame/fenced_frame.h +++ b/content/browser/fenced_frame/fenced_frame.h
@@ -62,7 +62,6 @@ void DidStartLoading(FrameTreeNode* frame_tree_node, bool should_show_loading_ui) override {} void DidStopLoading() override {} - void DidChangeLoadProgress() override {} bool IsHidden() override; void NotifyPageChanged(PageImpl& page) override {} int GetOuterDelegateFrameTreeNodeId() override;
diff --git a/content/browser/indexed_db/indexed_db_browsertest.cc b/content/browser/indexed_db/indexed_db_browsertest.cc index cbc3ebc..6f152777 100644 --- a/content/browser/indexed_db/indexed_db_browsertest.cc +++ b/content/browser/indexed_db/indexed_db_browsertest.cc
@@ -219,12 +219,12 @@ base::RunLoop loop; int64_t size = 0; auto& control = GetControl(browser); - control.GetUsage(base::BindOnce(base::BindLambdaForTesting( + control.GetUsage(base::BindLambdaForTesting( [&](std::vector<storage::mojom::StorageUsageInfoPtr> usages) { for (auto& usage : usages) size += usage->total_size_bytes; loop.Quit(); - }))); + })); loop.Run(); return size; } @@ -234,11 +234,10 @@ int64_t count = 0; auto control_test = GetControlTest(); control_test->GetBlobCountForTesting( - bucket_locator, - base::BindOnce(base::BindLambdaForTesting([&](int64_t returned_count) { + bucket_locator, base::BindLambdaForTesting([&](int64_t returned_count) { count = returned_count; loop.Quit(); - }))); + })); loop.Run(); return count; } @@ -248,11 +247,10 @@ bool downgraded; auto control_test = GetControlTest(); control_test->ForceSchemaDowngradeForTesting( - bucket_locator, - base::BindOnce(base::BindLambdaForTesting([&](bool was_downgraded) { + bucket_locator, base::BindLambdaForTesting([&](bool was_downgraded) { downgraded = was_downgraded; loop.Quit(); - }))); + })); loop.Run(); return downgraded; } @@ -1056,12 +1054,12 @@ ->UpdateOrCreateBucket( storage::BucketInitParams::ForDefaultBucket(storage_key), base::SequencedTaskRunnerHandle::Get(), - base::BindOnce(base::BindLambdaForTesting( + base::BindLambdaForTesting( [&](storage::QuotaErrorOr<storage::BucketInfo> result) { ASSERT_TRUE(result.ok()); bucket_locator = result->ToBucketLocator(); loop.Quit(); - }))); + })); loop.Run(); embedded_test_server()->RegisterRequestHandler(base::BindRepeating( &CorruptDBRequestHandler, base::SequencedTaskRunnerHandle::Get(),
diff --git a/content/browser/manifest/manifest_browsertest.cc b/content/browser/manifest/manifest_browsertest.cc index aa64074..062172f 100644 --- a/content/browser/manifest/manifest_browsertest.cc +++ b/content/browser/manifest/manifest_browsertest.cc
@@ -770,14 +770,13 @@ ASSERT_TRUE(NavigateToURL(shell(), test_url)); { base::RunLoop run_loop; - web_contents()->GetPrimaryPage().GetManifest( - base::BindOnce(base::BindLambdaForTesting( - [&](const GURL& manifest_url, blink::mojom::ManifestPtr manifest) { - // Get the manifest on a primary page. - EXPECT_FALSE(manifest_url.is_empty()); - EXPECT_FALSE(blink::IsEmptyManifest(*manifest)); - run_loop.Quit(); - }))); + web_contents()->GetPrimaryPage().GetManifest(base::BindLambdaForTesting( + [&](const GURL& manifest_url, blink::mojom::ManifestPtr manifest) { + // Get the manifest on a primary page. + EXPECT_FALSE(manifest_url.is_empty()); + EXPECT_FALSE(blink::IsEmptyManifest(*manifest)); + run_loop.Quit(); + })); run_loop.Run(); } @@ -789,29 +788,27 @@ prerender_helper().GetPrerenderedMainFrameHost(host_id); { base::RunLoop run_loop; - prerender_rfh->GetPage().GetManifest( - base::BindOnce(base::BindLambdaForTesting( - [&](const GURL& manifest_url, blink::mojom::ManifestPtr manifest) { - // Ensure that the manifest is empty in prerendering. - EXPECT_TRUE(manifest_url.is_empty()); - EXPECT_TRUE(blink::IsEmptyManifest(*manifest)); - run_loop.Quit(); - }))); + prerender_rfh->GetPage().GetManifest(base::BindLambdaForTesting( + [&](const GURL& manifest_url, blink::mojom::ManifestPtr manifest) { + // Ensure that the manifest is empty in prerendering. + EXPECT_TRUE(manifest_url.is_empty()); + EXPECT_TRUE(blink::IsEmptyManifest(*manifest)); + run_loop.Quit(); + })); run_loop.Run(); } prerender_helper().NavigatePrimaryPage(prerender_url); { base::RunLoop run_loop; - prerender_rfh->GetPage().GetManifest( - base::BindOnce(base::BindLambdaForTesting( - [&](const GURL& manifest_url, blink::mojom::ManifestPtr manifest) { - // Ensure that getting the manifest works after prerendering - // activation. - EXPECT_FALSE(manifest_url.is_empty()); - EXPECT_FALSE(blink::IsEmptyManifest(*manifest)); - run_loop.Quit(); - }))); + prerender_rfh->GetPage().GetManifest(base::BindLambdaForTesting( + [&](const GURL& manifest_url, blink::mojom::ManifestPtr manifest) { + // Ensure that getting the manifest works after prerendering + // activation. + EXPECT_FALSE(manifest_url.is_empty()); + EXPECT_FALSE(blink::IsEmptyManifest(*manifest)); + run_loop.Quit(); + })); run_loop.Run(); } } @@ -853,16 +850,15 @@ document.head.appendChild(link);)")); base::RunLoop run_loop; - fenced_frame_rfh->GetPage().GetManifest( - base::BindOnce(base::BindLambdaForTesting( - [&](const GURL& manifest_url, blink::mojom::ManifestPtr manifest) { - // Even though `fenced_frame_rfh` has a manifest updated above, - // this should get an empty manifest since it's not a primary main - // frame. - EXPECT_TRUE(manifest_url.is_empty()); - EXPECT_TRUE(blink::IsEmptyManifest(*manifest)); - run_loop.Quit(); - }))); + fenced_frame_rfh->GetPage().GetManifest(base::BindLambdaForTesting( + [&](const GURL& manifest_url, blink::mojom::ManifestPtr manifest) { + // Even though `fenced_frame_rfh` has a manifest updated above, + // this should get an empty manifest since it's not a primary main + // frame. + EXPECT_TRUE(manifest_url.is_empty()); + EXPECT_TRUE(blink::IsEmptyManifest(*manifest)); + run_loop.Quit(); + })); run_loop.Run(); }
diff --git a/content/browser/navigation_browsertest.cc b/content/browser/navigation_browsertest.cc index 8a46943..d6989f0 100644 --- a/content/browser/navigation_browsertest.cc +++ b/content/browser/navigation_browsertest.cc
@@ -181,7 +181,8 @@ site_instance, std::move(render_view_host), delegate, frame_tree, frame_tree_node, routing_id, std::move(frame_remote), frame_token, renderer_initiated_creation, lifecycle_state, - std::move(browsing_context_state))); + std::move(browsing_context_state), + frame_tree_node->frame_owner_element_type())); } };
diff --git a/content/browser/portal/portal_browsertest.cc b/content/browser/portal/portal_browsertest.cc index 9a3bce3..b2a75a99 100644 --- a/content/browser/portal/portal_browsertest.cc +++ b/content/browser/portal/portal_browsertest.cc
@@ -1621,7 +1621,8 @@ site_instance, std::move(render_view_host), delegate, frame_tree, frame_tree_node, routing_id, std::move(frame_remote), frame_token, renderer_initiated_creation, lifecycle_state, - std::move(browsing_context_state))); + std::move(browsing_context_state), + frame_tree_node->frame_owner_element_type())); } };
diff --git a/content/browser/preloading/prerender/prerender_browsertest.cc b/content/browser/preloading/prerender/prerender_browsertest.cc index 362d9c9..ec3f6fb 100644 --- a/content/browser/preloading/prerender/prerender_browsertest.cc +++ b/content/browser/preloading/prerender/prerender_browsertest.cc
@@ -283,6 +283,14 @@ return ssl_server_.GetURL("b.test", path); } + GURL GetUrlForSameSiteCrossOriginTest(const std::string& path) { + return ssl_server().GetURL("a.a.test", path); + } + + GURL GetSameSiteCrossOriginUrl(const std::string& path) { + return ssl_server().GetURL("b.a.test", path); + } + void ResetSSLConfig( net::test_server::EmbeddedTestServer::ServerCertificate cert, const net::SSLServerConfig& ssl_config) { @@ -4927,6 +4935,28 @@ base::test::ScopedFeatureList feature_list_; }; +class PrerenderSameSiteCrossOriginBrowserTest : public PrerenderBrowserTest { + public: + PrerenderSameSiteCrossOriginBrowserTest() { + feature_list_.InitWithFeaturesAndParameters( + {{blink::features::kPrerender2, {{}}}, + {blink::features::kSameSiteCrossOriginForSpeculationRulesPrerender, + {{}}}}, + {/* disabled_features */}); + } + + GURL GetUrl(const std::string& path) { + return ssl_server().GetURL("a.a.test", path); + } + + GURL GetCrossOriginUrl(const std::string& path) { + return ssl_server().GetURL("a.b.test", path); + } + + private: + base::test::ScopedFeatureList feature_list_; +}; + // Make sure that we can deal with the speculative RFH that is created during // the activation navigation. // TODO(https://crbug.com/1190197): We should try to avoid creating the @@ -5562,6 +5592,151 @@ } } +// Tests that same-site cross-origin navigation by speculation rules is not +// allowed with the feature disabled. +IN_PROC_BROWSER_TEST_F( + PrerenderBrowserTest, + SameSiteCrossOriginNavigationSpeculationRulesWithoutFeatureEnabled) { + ASSERT_FALSE(blink::features:: + IsSameSiteCrossOriginForSpeculationRulesPrerender2Enabled()); + const GURL kInitialUrl = GetUrlForSameSiteCrossOriginTest("/empty.html"); + const GURL kPrerenderingUrl = + GetSameSiteCrossOriginUrl("/empty.html?samesitecrossorigin"); + + ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl)); + + // Add a same-site cross-origin prerender rule. + test::PrerenderHostRegistryObserver registry_observer(*web_contents_impl()); + AddPrerenderAsync(kPrerenderingUrl); + // Wait for PrerenderHostRegistry to receive the cross-origin prerender + // request, and it should be ignored. + registry_observer.WaitForTrigger(kPrerenderingUrl); + EXPECT_FALSE(HasHostForUrl(kPrerenderingUrl)); + + ExpectFinalStatusForSpeculationRule( + PrerenderHost::FinalStatus::kCrossOriginNavigation); +} + +// Tests that same-site cross-origin redirection by speculation rules is not +// allowed with the feature disabled. +IN_PROC_BROWSER_TEST_F( + PrerenderBrowserTest, + SameSiteCrossOriginRedirectionSpeculationRulesWithoutFeatureEnabled) { + ASSERT_FALSE(blink::features:: + IsSameSiteCrossOriginForSpeculationRulesPrerender2Enabled()); + // Navigate to an initial page. + const GURL kInitialUrl = GetUrlForSameSiteCrossOriginTest("/empty.html"); + ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl)); + + // Start prerendering a URL that causes cross-origin redirection. The + // cross-origin redirection should fail prerendering. + const GURL kRedirectedUrl = + GetSameSiteCrossOriginUrl("/empty.html?samesitecrossorigin"); + const GURL kPrerenderingUrl = GetUrlForSameSiteCrossOriginTest( + "/server-redirect?" + kRedirectedUrl.spec()); + test::PrerenderHostRegistryObserver registry_observer(*web_contents_impl()); + test::PrerenderHostObserver host_observer(*web_contents_impl(), + kPrerenderingUrl); + AddPrerenderAsync(kPrerenderingUrl); + host_observer.WaitForDestroyed(); + EXPECT_EQ(GetRequestCount(kPrerenderingUrl), 1); + EXPECT_EQ(GetRequestCount(kRedirectedUrl), 0); + EXPECT_FALSE(HasHostForUrl(kPrerenderingUrl)); + EXPECT_FALSE(HasHostForUrl(kRedirectedUrl)); + ExpectFinalStatusForSpeculationRule( + PrerenderHost::FinalStatus::kCrossOriginRedirect); +} + +// Tests that same-site cross-origin navigation by speculation rules can be +// prerendered with the feature enabled. +IN_PROC_BROWSER_TEST_F(PrerenderSameSiteCrossOriginBrowserTest, + CheckSameSiteCrossOriginSpeculationRulesPrerender) { + ASSERT_TRUE(blink::features:: + IsSameSiteCrossOriginForSpeculationRulesPrerender2Enabled()); + const GURL kInitialUrl = GetUrl("/empty.html"); + const GURL kPrerenderingUrl = + GetSameSiteCrossOriginUrl("/empty.html?samesitecrossorigin"); + + ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl)); + + // Add a same-site cross-origin prerender rule. + ASSERT_EQ(GetRequestCount(kPrerenderingUrl), 0); + AddPrerender(kPrerenderingUrl); + EXPECT_EQ(GetRequestCount(kPrerenderingUrl), 1); + + NavigatePrimaryPage(kPrerenderingUrl); + ASSERT_EQ(web_contents()->GetLastCommittedURL(), kPrerenderingUrl); + // Activating the prerendered page should not issue a request. + EXPECT_EQ(GetRequestCount(kPrerenderingUrl), 1); + ExpectFinalStatusForSpeculationRule(PrerenderHost::FinalStatus::kActivated); +} + +// Tests that same-site cross-origin redirection by speculation rules is +// allowed. +IN_PROC_BROWSER_TEST_F(PrerenderSameSiteCrossOriginBrowserTest, + SameSiteCrossOriginSpeculationRulesRedirection) { + ASSERT_TRUE(blink::features:: + IsSameSiteCrossOriginForSpeculationRulesPrerender2Enabled()); + // Navigate to an initial page. + const GURL kInitialUrl = GetUrl("/empty.html"); + ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl)); + + // Start prerendering a URL that causes same-origin redirection. + const GURL kRedirectedUrl = + GetSameSiteCrossOriginUrl("/empty.html?prerender"); + const GURL kPrerenderingUrl = + GetSameSiteCrossOriginUrl("/server-redirect?" + kRedirectedUrl.spec()); + RedirectChainObserver redirect_chain_observer(*shell()->web_contents(), + kRedirectedUrl); + ASSERT_EQ(GetRequestCount(kPrerenderingUrl), 0); + ASSERT_EQ(GetRequestCount(kRedirectedUrl), 0); + AddPrerender(kPrerenderingUrl); + EXPECT_EQ(GetRequestCount(kPrerenderingUrl), 1); + EXPECT_EQ(GetRequestCount(kRedirectedUrl), 1); + + ASSERT_EQ(2u, redirect_chain_observer.redirect_chain().size()); + EXPECT_EQ(kPrerenderingUrl, redirect_chain_observer.redirect_chain()[0]); + EXPECT_EQ(kRedirectedUrl, redirect_chain_observer.redirect_chain()[1]); + + // The prerender host should be registered for the initial request URL, not + // the redirected URL. + EXPECT_TRUE(HasHostForUrl(kPrerenderingUrl)); + EXPECT_FALSE(HasHostForUrl(kRedirectedUrl)); + + RedirectChainObserver activation_redirect_chain_observer( + *shell()->web_contents(), kRedirectedUrl); + NavigatePrimaryPage(kPrerenderingUrl); + ASSERT_EQ(1u, activation_redirect_chain_observer.redirect_chain().size()); + EXPECT_EQ(kRedirectedUrl, + activation_redirect_chain_observer.redirect_chain()[0]); + + ASSERT_EQ(web_contents()->GetLastCommittedURL(), kRedirectedUrl); + ExpectFinalStatusForSpeculationRule(PrerenderHost::FinalStatus::kActivated); + // Activating the prerendered page should not issue a request. + EXPECT_EQ(GetRequestCount(kPrerenderingUrl), 1); + EXPECT_EQ(GetRequestCount(kRedirectedUrl), 1); + + { + // Cross-check that in case redirection when the prerender navigates and + // user ends up navigating to the redirected URL. accurate_triggering is + // true. + ukm::SourceId ukm_source_id = PrimaryPageSourceId(); + auto attempt_ukm_entries = test_ukm_recorder()->GetEntries( + Preloading_Attempt::kEntryName, test::kPreloadingAttemptUkmMetrics); + + UkmEntry attempt_expected_entry = attempt_ukm_entry_builder().BuildEntry( + ukm_source_id, PreloadingType::kPrerender, + PreloadingEligibility::kEligible, PreloadingHoldbackStatus::kAllowed, + PreloadingTriggeringOutcome::kSuccess, + PreloadingFailureReason::kUnspecified, + /*accurate=*/true); + + EXPECT_EQ(attempt_ukm_entries[0], attempt_expected_entry) + << test::ActualVsExpectedUkmEntryToString(attempt_ukm_entries[0], + attempt_expected_entry); + } +} + IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, EmbedderTrigger_SameOriginRedirection) { const GURL kInitialUrl = GetUrl("/empty.html");
diff --git a/content/browser/preloading/prerender/prerender_host_registry.cc b/content/browser/preloading/prerender/prerender_host_registry.cc index 1dabb34..8460d57b 100644 --- a/content/browser/preloading/prerender/prerender_host_registry.cc +++ b/content/browser/preloading/prerender/prerender_host_registry.cc
@@ -17,6 +17,7 @@ #include "build/build_config.h" #include "content/browser/preloading/preloading_attempt_impl.h" #include "content/browser/preloading/prerender/prerender_metrics.h" +#include "content/browser/preloading/prerender/prerender_navigation_utils.h" #include "content/browser/renderer_host/frame_tree_node.h" #include "content/browser/renderer_host/navigation_request.h" #include "content/browser/renderer_host/render_frame_host_impl.h" @@ -137,19 +138,34 @@ return RenderFrameHost::kNoFrameTreeNodeId; } - // TODO(crbug.com/1176054): Support cross-origin prerendering. + // TODO(crbug.com/1176054): Support cross-site prerendering. // The initiator origin is nullopt when prerendering is initiated by the // browser (not by a renderer using Speculation Rules API). In that case, - // skip the same-origin check. - if (!attributes.IsBrowserInitiated() && - !attributes.initiator_origin.value().IsSameOriginWith( - attributes.prerendering_url)) { - RecordPrerenderHostFinalStatus( - PrerenderHost::FinalStatus::kCrossOriginNavigation, attributes, - ukm::kInvalidSourceId); - if (attempt) - attempt->SetEligibility(PreloadingEligibility::kCrossOrigin); - return RenderFrameHost::kNoFrameTreeNodeId; + // skip the same-site and same-origin check. + if (!attributes.IsBrowserInitiated()) { + if (blink::features:: + IsSameSiteCrossOriginForSpeculationRulesPrerender2Enabled()) { + if (!prerender_navigation_utils::IsSameSite( + attributes.prerendering_url, + attributes.initiator_origin.value())) { + RecordPrerenderHostFinalStatus( + PrerenderHost::FinalStatus::kCrossOriginNavigation, attributes, + ukm::kInvalidSourceId); + if (attempt) + attempt->SetEligibility(PreloadingEligibility::kCrossOrigin); + return RenderFrameHost::kNoFrameTreeNodeId; + } + } else { + if (!attributes.initiator_origin.value().IsSameOriginWith( + attributes.prerendering_url)) { + RecordPrerenderHostFinalStatus( + PrerenderHost::FinalStatus::kCrossOriginNavigation, attributes, + ukm::kInvalidSourceId); + if (attempt) + attempt->SetEligibility(PreloadingEligibility::kCrossOrigin); + return RenderFrameHost::kNoFrameTreeNodeId; + } + } } // Once all eligibility checks are completed, set the status to kEligible.
diff --git a/content/browser/preloading/prerender/prerender_navigation_throttle.cc b/content/browser/preloading/prerender/prerender_navigation_throttle.cc index 4b3f011e..39e9343 100644 --- a/content/browser/preloading/prerender/prerender_navigation_throttle.cc +++ b/content/browser/preloading/prerender/prerender_navigation_throttle.cc
@@ -140,14 +140,32 @@ // origin is nullopt for browser-initiated prerendering. DCHECK(!prerender_host->initiator_origin().has_value()); } else if (prerendering_origin != prerender_host->initiator_origin()) { - // Cancel prerendering if this is cross-origin prerendering, cross-origin - // redirection during prerendering, or cross-origin navigation from a - // prerendered page. - prerender_host_registry->CancelHost( - frame_tree_node->frame_tree_node_id(), - is_redirection ? PrerenderHost::FinalStatus::kCrossOriginRedirect - : PrerenderHost::FinalStatus::kCrossOriginNavigation); - return CANCEL; + if (blink::features:: + IsSameSiteCrossOriginForSpeculationRulesPrerender2Enabled()) { + // Cancel prerendering if this is cross-site prerendering, cross-site + // redirection during prerendering, or cross-site navigation from a + // prerendered page. + if (!prerender_navigation_utils::IsSameSite( + prerendering_url, prerender_host->initiator_origin().value())) { + // TODO(crbug.com/1176054): Add status for cross site navigations and + // redirections. + prerender_host_registry->CancelHost( + frame_tree_node->frame_tree_node_id(), + is_redirection + ? PrerenderHost::FinalStatus::kCrossOriginRedirect + : PrerenderHost::FinalStatus::kCrossOriginNavigation); + return CANCEL; + } + } else { + // Cancel prerendering if this is cross-origin prerendering, cross-origin + // redirection during prerendering, or cross-origin navigation from a + // prerendered page. + prerender_host_registry->CancelHost( + frame_tree_node->frame_tree_node_id(), + is_redirection ? PrerenderHost::FinalStatus::kCrossOriginRedirect + : PrerenderHost::FinalStatus::kCrossOriginNavigation); + return CANCEL; + } } return PROCEED;
diff --git a/content/browser/preloading/prerender/prerender_navigation_utils.cc b/content/browser/preloading/prerender/prerender_navigation_utils.cc index 31e122c..3339b600 100644 --- a/content/browser/preloading/prerender/prerender_navigation_utils.cc +++ b/content/browser/preloading/prerender/prerender_navigation_utils.cc
@@ -3,6 +3,7 @@ // found in the LICENSE file. #include "content/browser/preloading/prerender/prerender_navigation_utils.h" +#include "net/base/registry_controlled_domains/registry_controlled_domain.h" namespace content::prerender_navigation_utils { @@ -17,4 +18,11 @@ return response_code < 100 || response_code > 399; } +bool IsSameSite(const GURL& target_url, const url::Origin& origin) { + return target_url.scheme() == origin.scheme() && + net::registry_controlled_domains::SameDomainOrHost( + target_url, origin, + net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES); +} + } // namespace content::prerender_navigation_utils
diff --git a/content/browser/preloading/prerender/prerender_navigation_utils.h b/content/browser/preloading/prerender/prerender_navigation_utils.h index 68dbf13..dc343bbc 100644 --- a/content/browser/preloading/prerender/prerender_navigation_utils.h +++ b/content/browser/preloading/prerender/prerender_navigation_utils.h
@@ -5,6 +5,9 @@ #ifndef CONTENT_BROWSER_PRELOADING_PRERENDER_PRERENDER_NAVIGATION_UTILS_H_ #define CONTENT_BROWSER_PRELOADING_PRERENDER_PRERENDER_NAVIGATION_UTILS_H_ +#include "url/gurl.h" +#include "url/origin.h" + namespace content::prerender_navigation_utils { // Returns true if the response code is disallowed for pre-rendering (e.g 404, @@ -12,6 +15,9 @@ // main frame in a prerendered page. bool IsDisallowedHttpResponseCode(int response_code); +// Returns true if target_url is in the same site as origin. +bool IsSameSite(const GURL& target_url, const url::Origin& origin); + } // namespace content::prerender_navigation_utils #endif // CONTENT_BROWSER_PRELOADING_PRERENDER_PRERENDER_NAVIGATION_UTILS_H_
diff --git a/content/browser/preloading/prerender/prerender_page_holder.h b/content/browser/preloading/prerender/prerender_page_holder.h index 14a6076..7fb9c8e 100644 --- a/content/browser/preloading/prerender/prerender_page_holder.h +++ b/content/browser/preloading/prerender/prerender_page_holder.h
@@ -31,7 +31,6 @@ void DidStartLoading(FrameTreeNode* frame_tree_node, bool should_show_loading_ui) override {} void DidStopLoading() override; - void DidChangeLoadProgress() override {} bool IsHidden() override; FrameTree* LoadingTree() override; void NotifyPageChanged(PageImpl& page) override {}
diff --git a/content/browser/preloading/speculation_rules/speculation_host_impl.cc b/content/browser/preloading/speculation_rules/speculation_host_impl.cc index 691f7a8..a3a81b1a 100644 --- a/content/browser/preloading/speculation_rules/speculation_host_impl.cc +++ b/content/browser/preloading/speculation_rules/speculation_host_impl.cc
@@ -15,6 +15,7 @@ #include "content/browser/preloading/preloading_data_impl.h" #include "content/browser/preloading/prerender/prerender_attributes.h" #include "content/browser/preloading/prerender/prerender_host_registry.h" +#include "content/browser/preloading/prerender/prerender_navigation_utils.h" #include "content/browser/renderer_host/render_frame_host_delegate.h" #include "content/browser/renderer_host/render_frame_host_impl.h" #include "content/public/browser/browser_thread.h" @@ -263,17 +264,34 @@ GetContentClient()->browser()->LogWebFeatureForCurrentPage( &rfhi, blink::mojom::WebFeature::kSpeculationRulesPrerender); - // TODO(crbug.com/1176054): Remove it after supporting cross-origin + // TODO(crbug.com/1176054): Remove it after supporting cross-site // prerender. - if (!rfhi.GetLastCommittedOrigin().IsSameOriginWith(it->url)) { - rfhi.AddMessageToConsole( - blink::mojom::ConsoleMessageLevel::kWarning, - base::StringPrintf( - "The SpeculationRules API does not support cross-origin " - "prerender yet. (initiator origin: %s, prerender origin: %s). " - "https://crbug.com/1176054 tracks cross-origin support.", - rfhi.GetLastCommittedOrigin().Serialize().c_str(), - url::Origin::Create(it->url).Serialize().c_str())); + if (blink::features:: + IsSameSiteCrossOriginForSpeculationRulesPrerender2Enabled()) { + if (!prerender_navigation_utils::IsSameSite( + it->url, rfhi.GetLastCommittedOrigin())) { + rfhi.AddMessageToConsole( + blink::mojom::ConsoleMessageLevel::kWarning, + base::StringPrintf( + "The SpeculationRules API does not support cross-site " + "prerender yet " + "(kSameSiteCrossOriginForSpeculationRulesPrerender2 is " + "enabled). (initiator origin: %s, prerender origin: %s). " + "https://crbug.com/1176054 tracks cross-site support.", + rfhi.GetLastCommittedOrigin().Serialize().c_str(), + url::Origin::Create(it->url).Serialize().c_str())); + } + } else { + if (!rfhi.GetLastCommittedOrigin().IsSameOriginWith(it->url)) { + rfhi.AddMessageToConsole( + blink::mojom::ConsoleMessageLevel::kWarning, + base::StringPrintf( + "The SpeculationRules API does not support cross-origin " + "prerender yet. (initiator origin: %s, prerender origin: %s). " + "https://crbug.com/1176054 tracks cross-origin support.", + rfhi.GetLastCommittedOrigin().Serialize().c_str(), + url::Origin::Create(it->url).Serialize().c_str())); + } } Referrer referrer(*(it->referrer));
diff --git a/content/browser/renderer_host/frame_tree.h b/content/browser/renderer_host/frame_tree.h index 6708738..0eadcf0 100644 --- a/content/browser/renderer_host/frame_tree.h +++ b/content/browser/renderer_host/frame_tree.h
@@ -144,9 +144,6 @@ // indicator for loading. virtual void DidStopLoading() = 0; - // The load progress was changed. - virtual void DidChangeLoadProgress() = 0; - // Returns the delegate's top loading tree, which should be used to infer // the values of loading-related states. The state of // IsLoadingIncludingInnerFrameTrees() is a WebContents level concept and
diff --git a/content/browser/renderer_host/pending_beacon_browsertest.cc b/content/browser/renderer_host/pending_beacon_browsertest.cc new file mode 100644 index 0000000..2293cae --- /dev/null +++ b/content/browser/renderer_host/pending_beacon_browsertest.cc
@@ -0,0 +1,596 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <type_traits> + +#include "base/feature_list.h" +#include "base/location.h" +#include "base/strings/strcat.h" +#include "base/test/bind.h" +#include "base/test/metrics/histogram_tester.h" +#include "base/test/scoped_feature_list.h" +#include "components/ukm/test_ukm_recorder.h" +#include "content/browser/back_forward_cache_test_util.h" +#include "content/browser/renderer_host/render_frame_host_impl.h" +#include "content/public/browser/render_frame_host.h" +#include "content/public/test/browser_test.h" +#include "content/public/test/browser_test_utils.h" +#include "content/public/test/content_browser_test.h" +#include "content/public/test/content_browser_test_utils.h" +#include "content/shell/browser/shell.h" +#include "net/dns/mock_host_resolver.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "third_party/blink/public/common/features.h" + +namespace content { + +class PendingBeaconTimeoutBrowserTestBase : public ContentBrowserTest { + protected: + void SetUpOnMainThread() override { + host_resolver()->AddRule("*", "127.0.0.1"); + // Using base::Unretained() as `embedded_test_server()` is owned by + // `content::BrowserTestBase` and should not be able to outlive. + embedded_test_server()->RegisterDefaultHandler(base::BindRepeating( + &PendingBeaconTimeoutBrowserTestBase::HandleBeaconRequest, + base::Unretained(this))); + ContentBrowserTest::SetUpOnMainThread(); + } + + // Runs JS `script` in page A, and then navigates to page B. + void RunScriptInANavigateToB(const std::string& script) { + RunScriptInA(script); + + // Navigate to B. + ASSERT_TRUE( + NavigateToURL(embedded_test_server()->GetURL("b.com", "/title1.html"))); + } + + // Runs JS `script` in page A. + void RunScriptInA(const std::string& script) { + // Navigate to A. + ASSERT_TRUE( + NavigateToURL(embedded_test_server()->GetURL("a.com", "/title1.html"))); + RenderFrameHostWrapper rfh_a(current_frame_host()); + // Execute `script` in A. + ASSERT_TRUE(ExecJs(web_contents(), script)); + } + + // Registers a request monitor to wait for `total_beacon` beacons received, + // and then starts the test server. + void RegisterBeaconRequestMonitor(const size_t total_beacon) { + // Using base::Unretained() as `embedded_test_server()` is owned by + // `content::BrowserTestBase` and should not be able to outlive. + embedded_test_server()->RegisterRequestMonitor(base::BindRepeating( + &PendingBeaconTimeoutBrowserTestBase::MonitorBeaconRequest, + base::Unretained(this), total_beacon)); + ASSERT_TRUE(embedded_test_server()->Start()); + } + + // Waits for `kBeaconEndpoint` to be requested `total_beacon` times. + // If `sent_beacon_count_` does not yet reach `total_beacon`, a RunLoop will + // be created and runs until it is stopped by `MonitorBeaconRequest`. + void WaitForAllBeaconsSent(size_t total_beacon) { + { + base::AutoLock auto_lock(count_lock_); + if (sent_beacon_count_ >= total_beacon) + return; + } + { + base::AutoLock auto_lock(count_lock_); + waiting_run_loop_ = std::make_unique<base::RunLoop>( + base::RunLoop::Type::kNestableTasksAllowed); + } + waiting_run_loop_->Run(); + { + base::AutoLock auto_lock(count_lock_); + waiting_run_loop_.reset(); + } + } + + WebContents* web_contents() const { return shell()->web_contents(); } + + RenderFrameHostWrapper& current_document() { + current_document_ = + std::make_unique<RenderFrameHostWrapper>(current_frame_host()); + return *current_document_; + } + RenderFrameHostWrapper& previous_document() { return *previous_document_; } + + bool NavigateToURL(const GURL& url) { + previous_document_ = + std::make_unique<RenderFrameHostWrapper>(current_frame_host()); + return content::NavigateToURL(web_contents(), url); + } + + size_t sent_beacon_count() { + base::AutoLock auto_lock(count_lock_); + return sent_beacon_count_; + } + + static constexpr char kBeaconEndpoint[] = "/pending_beacon/timeout"; + + private: + // Waits until `total_beacon` beacons received and stops `waiting_run_loop_`. + // Invoked on `embedded_test_server()`'s IO Thread, so it's required to use + // a lock to protect shared data `sent_beacon_count_` access. + void MonitorBeaconRequest(const size_t total_beacon, + const net::test_server::HttpRequest& request) { + if (request.relative_url == kBeaconEndpoint) { + { + base::AutoLock auto_lock(count_lock_); + sent_beacon_count_++; + if (sent_beacon_count_ < total_beacon) { + return; + } + } + + base::AutoLock auto_lock(count_lock_); + if (waiting_run_loop_) { + waiting_run_loop_->Quit(); + } + } + } + + // Invoked on `embedded_test_server()`'s IO Thread. + // PendingBeacon doesn't really look into its response, so this method just + // returns OK status. + std::unique_ptr<net::test_server::HttpResponse> HandleBeaconRequest( + const net::test_server::HttpRequest& request) { + if (request.relative_url != kBeaconEndpoint) { + return nullptr; + } + auto response = std::make_unique<net::test_server::BasicHttpResponse>(); + response->set_code(net::HTTP_OK); + return response; + } + + RenderFrameHost* current_frame_host() { + return web_contents()->GetPrimaryMainFrame(); + } + + base::Lock count_lock_; + size_t sent_beacon_count_ GUARDED_BY(count_lock_) = 0; + std::unique_ptr<base::RunLoop> waiting_run_loop_; + + std::unique_ptr<RenderFrameHostWrapper> current_document_ = nullptr; + std::unique_ptr<RenderFrameHostWrapper> previous_document_ = nullptr; +}; + +MATCHER(IsFrameVisible, + base::StrCat({"Frame is", negation ? " not" : "", " visible"})) { + return arg->GetVisibilityState() == PageVisibilityState::kVisible; +} + +MATCHER(IsFrameHidden, + base::StrCat({"Frame is", negation ? " not" : "", " hidden"})) { + return arg->GetVisibilityState() == PageVisibilityState::kHidden; +} + +struct TestTimeoutType { + std::string test_case_name; + int32_t timeout; +}; + +// Tests to cover PendingBeacon's backgroundTimeout & timeout behaviors when +// BackForwardCache is off. +// Disables BackForwardCache by setting its cache size to 0 such that a page is +// discarded right away on user navigating to another page. And on page +// discard, pending beacons should be sent out no matter what value its +// backgroundTimeout/timeout is. +class PendingBeaconTimeoutNoBackForwardCacheBrowserTest + : public PendingBeaconTimeoutBrowserTestBase, + public testing::WithParamInterface<TestTimeoutType> { + protected: + void SetUpCommandLine(base::CommandLine* command_line) override { + feature_list_.InitWithFeaturesAndParameters( + {{blink::features::kPendingBeaconAPI, {}}, + {features::kBackForwardCache, {{"cache_size", "0"}}}}, + {}); + PendingBeaconTimeoutBrowserTestBase::SetUpCommandLine(command_line); + } + + private: + base::test::ScopedFeatureList feature_list_; +}; + +INSTANTIATE_TEST_SUITE_P( + All, + PendingBeaconTimeoutNoBackForwardCacheBrowserTest, + testing::ValuesIn<std::vector<TestTimeoutType>>({ + {"LongTimeout", 600000}, + {"OneSecondTimeout", 1000}, + {"ShortTimeout", 1}, + {"NoTimeout", 0}, + {"DefaultTimeout", -1}, // default. + {"NegativeTimeout", -600000}, // behaves the same as default. + }), + [](const testing::TestParamInfo<TestTimeoutType>& info) { + return info.param.test_case_name; + }); + +IN_PROC_BROWSER_TEST_P(PendingBeaconTimeoutNoBackForwardCacheBrowserTest, + SendOnPageDiscardNotUsingBackgroundTimeout) { + const size_t total_beacon = 1; + RegisterBeaconRequestMonitor(total_beacon); + + // Creates a pending beacon with various backgroundTimeout, which should all + // be sent on page A discard. + RunScriptInANavigateToB(JsReplace(R"( + let p = new PendingGetBeacon($1, {backgroundTimeout: $2}); + )", + kBeaconEndpoint, GetParam().timeout)); + ASSERT_TRUE(previous_document().WaitUntilRenderFrameDeleted()); + + WaitForAllBeaconsSent(total_beacon); + EXPECT_EQ(sent_beacon_count(), total_beacon); +} + +IN_PROC_BROWSER_TEST_P(PendingBeaconTimeoutNoBackForwardCacheBrowserTest, + SendOnPageDiscardNotUsingTimeout) { + const size_t total_beacon = 1; + RegisterBeaconRequestMonitor(total_beacon); + + // Creates a pending beacon with various timeout, which should all be sent on + // page A discard. + RunScriptInANavigateToB(JsReplace(R"( + let p = new PendingGetBeacon($1, {timeout: $2}); + )", + kBeaconEndpoint, GetParam().timeout)); + ASSERT_TRUE(previous_document().WaitUntilRenderFrameDeleted()); + + WaitForAllBeaconsSent(total_beacon); + EXPECT_EQ(sent_beacon_count(), total_beacon); +} + +// Tests to cover PendingBeacon's backgroundTimeout behaviors. +// Sets `PendingBeaconMaxBackgroundTimeoutInMs` (10s) > BFCache timeout (5s) to +// also cover beacon sending on page eviction. +class PendingBeaconBackgroundTimeoutBrowserTest + : public PendingBeaconTimeoutBrowserTestBase { + protected: + void SetUpCommandLine(base::CommandLine* command_line) override { + feature_list_.InitWithFeaturesAndParameters( + {{blink::features::kPendingBeaconAPI, + {{"PendingBeaconMaxBackgroundTimeoutInMs", "10000"}}}, + {features::kBackForwardCache, + {{"TimeToLiveInBackForwardCacheInSeconds", "5"}}}}, + {}); + PendingBeaconTimeoutBrowserTestBase::SetUpCommandLine(command_line); + } + + private: + base::test::ScopedFeatureList feature_list_; +}; + +IN_PROC_BROWSER_TEST_F(PendingBeaconBackgroundTimeoutBrowserTest, + SendOnHidden) { + const size_t total_beacon = 1; + RegisterBeaconRequestMonitor(total_beacon); + + // Creates a pending beacon with 0s backgroundTimeout. + // It should be sent out right on entering `hidden` state. + RunScriptInANavigateToB(JsReplace(R"( + let p = new PendingGetBeacon($1, {backgroundTimeout: 0}); + )", + kBeaconEndpoint)); + ASSERT_THAT(previous_document(), IsFrameHidden()); + + WaitForAllBeaconsSent(total_beacon); + ASSERT_THAT(previous_document(), IsFrameHidden()); + EXPECT_EQ(sent_beacon_count(), total_beacon); +} + +IN_PROC_BROWSER_TEST_F(PendingBeaconBackgroundTimeoutBrowserTest, + SendOnBackgroundTimeout) { + const size_t total_beacon = 1; + RegisterBeaconRequestMonitor(total_beacon); + + // Creates a pending beacon with backgroundTimeout (1s) < BFCache TTL (5s). + // The beacon should be sent out on entering `hidden` state but before + // page deletion. + RunScriptInANavigateToB(JsReplace(R"( + let p = new PendingGetBeacon($1, {backgroundTimeout: 1000}); + )", + kBeaconEndpoint)); + ASSERT_THAT(previous_document(), IsFrameHidden()); + + WaitForAllBeaconsSent(total_beacon); + ASSERT_THAT(previous_document(), IsFrameHidden()); + EXPECT_EQ(sent_beacon_count(), total_beacon); +} + +// When backgroundTimeout is set, its timer resets every time when the page +// becomes visible if it has not yet expired. +IN_PROC_BROWSER_TEST_F( + PendingBeaconBackgroundTimeoutBrowserTest, + NotSendWhenPageIsRestoredBeforeBackgroundTimeoutExpires) { + const size_t total_beacon = 0; + RegisterBeaconRequestMonitor(total_beacon); + + // Creates a pending beacon with backgroundTimeout (3s) < BFCache TTL (5s). + RunScriptInANavigateToB(JsReplace(R"( + let p = new PendingGetBeacon($1, {backgroundTimeout: 3000}); + )", + kBeaconEndpoint)); + ASSERT_THAT(previous_document(), IsFrameHidden()); + + // Navigate back to A. + ASSERT_TRUE(HistoryGoBack(web_contents())); + // The page A becomes visible again, so backgroundTimeout timer should stop. + ASSERT_THAT(current_document(), IsFrameVisible()); + + // Verify that beacon is not sent. + EXPECT_EQ(sent_beacon_count(), total_beacon); +} + +IN_PROC_BROWSER_TEST_F(PendingBeaconBackgroundTimeoutBrowserTest, + SendOnBackForwardCacheEviction) { + const size_t total_beacon = 1; + RegisterBeaconRequestMonitor(total_beacon); + + // Creates a pending beacon with backgroundTimeout (8s) > BFCache TTL (5s) + // The beacon should be sent out on page deletion. + RunScriptInANavigateToB(JsReplace(R"( + let p = new PendingGetBeacon($1, {backgroundTimeout: 8000}); + )", + kBeaconEndpoint)); + ASSERT_TRUE(previous_document().WaitUntilRenderFrameDeleted()); + + WaitForAllBeaconsSent(total_beacon); + EXPECT_EQ(sent_beacon_count(), total_beacon); +} + +IN_PROC_BROWSER_TEST_F(PendingBeaconBackgroundTimeoutBrowserTest, + SendMultipleOnBackgroundTimeout) { + const size_t total_beacon = 5; + RegisterBeaconRequestMonitor(total_beacon); + + RunScriptInANavigateToB(JsReplace(R"( + let p1 = new PendingGetBeacon($1, {backgroundTimeout: 200}); + let p2 = new PendingGetBeacon($1, {backgroundTimeout: 100}); + let p3 = new PendingGetBeacon($1, {backgroundTimeout: 500}); + let p4 = new PendingGetBeacon($1, {backgroundTimeout: 700}); + let p5 = new PendingGetBeacon($1, {backgroundTimeout: 300}); + )", + kBeaconEndpoint)); + ASSERT_THAT(previous_document(), IsFrameHidden()); + + WaitForAllBeaconsSent(total_beacon); + EXPECT_EQ(sent_beacon_count(), total_beacon); +} + +// Tests to cover PendingBeacon's timeout behaviors. +// Sets `BeaconTimeToLiveInMs` (10s) > BFCache timeout (5s) to also cover beacon +// sending on page eviction. +using PendingBeaconTimeoutBrowserTest = + PendingBeaconBackgroundTimeoutBrowserTest; + +IN_PROC_BROWSER_TEST_F(PendingBeaconTimeoutBrowserTest, SendOnZeroTimeout) { + const size_t total_beacon = 1; + RegisterBeaconRequestMonitor(total_beacon); + + // Creates a pending beacon with 0s timeout. It should be sent out right away + // (without the page entering 'hidden' state). + RunScriptInA(JsReplace(R"( + let p = new PendingGetBeacon($1, {timeout: 0}); + )", + kBeaconEndpoint)); + ASSERT_THAT(current_document(), IsFrameVisible()); + + WaitForAllBeaconsSent(total_beacon); + EXPECT_EQ(sent_beacon_count(), total_beacon); +} + +// When timeout is set, it's not relevant whether the page is hidden or not. +IN_PROC_BROWSER_TEST_F(PendingBeaconTimeoutBrowserTest, + SendOnTimeoutWhenPageIsHidden) { + const size_t total_beacon = 1; + RegisterBeaconRequestMonitor(total_beacon); + + // Creates a pending beacon with a timeout which should expire when the page A + // is still hidden. + RunScriptInANavigateToB(JsReplace(R"( + let p = new PendingGetBeacon($1, {timeout: 1000}); + )", + kBeaconEndpoint)); + ASSERT_THAT(previous_document(), IsFrameHidden()); + + WaitForAllBeaconsSent(total_beacon); + // Verify that beacon is sent. + EXPECT_EQ(sent_beacon_count(), total_beacon); +} + +// When timeout is set, it's not relevant whether the page is visible or not. +IN_PROC_BROWSER_TEST_F(PendingBeaconTimeoutBrowserTest, + SendOnTimeoutWhenPageIsVisible) { + const size_t total_beacon = 1; + RegisterBeaconRequestMonitor(total_beacon); + + // Creates a pending beacon with a timeout longer enough such that page can + // experience visible -> hidden -> visible. + RunScriptInANavigateToB(JsReplace(R"( + let p = new PendingGetBeacon($1, {timeout: 4000}); + )", + kBeaconEndpoint)); + ASSERT_THAT(previous_document(), IsFrameHidden()); + // beacon is not yet sent. + ASSERT_EQ(sent_beacon_count(), 0u); + + // Navigate back to A. + ASSERT_TRUE(HistoryGoBack(web_contents())); + // The page A becomes visible again, but timeout timer never stops. + ASSERT_THAT(current_document(), IsFrameVisible()); + + WaitForAllBeaconsSent(total_beacon); + // Verify that beacon is sent. + EXPECT_EQ(sent_beacon_count(), total_beacon); +} + +IN_PROC_BROWSER_TEST_F(PendingBeaconTimeoutBrowserTest, SendOnShorterTimeout) { + const size_t total_beacon = 1; + RegisterBeaconRequestMonitor(total_beacon); + + // Creates a pending beacon with long (5s) timeout. And then quickly updates + // to a very short (0.01s) timeout. The beacon should be sent out right away. + RunScriptInA(JsReplace(R"( + let p = new PendingGetBeacon($1, {timeout: 5000}); + p.timeout = 10; + )", + kBeaconEndpoint)); + ASSERT_THAT(current_document(), IsFrameVisible()); + + WaitForAllBeaconsSent(total_beacon); + EXPECT_EQ(sent_beacon_count(), total_beacon); +} + +IN_PROC_BROWSER_TEST_F(PendingBeaconTimeoutBrowserTest, SendOnlyOnce) { + const size_t total_beacon = 1; + RegisterBeaconRequestMonitor(total_beacon); + + // Creates a pending beacon which should be sent out right way. + // But it won't be sent out twice. + RunScriptInA(JsReplace(R"( + let p = new PendingGetBeacon($1, {timeout: 0}); + p.timeout = 1; + )", + kBeaconEndpoint)); + ASSERT_THAT(current_document(), IsFrameVisible()); + + WaitForAllBeaconsSent(total_beacon); + EXPECT_EQ(sent_beacon_count(), total_beacon); +} + +IN_PROC_BROWSER_TEST_F(PendingBeaconTimeoutBrowserTest, SendMultipleOnTimeout) { + const size_t total_beacon = 5; + RegisterBeaconRequestMonitor(total_beacon); + + RunScriptInA(JsReplace(R"( + let p1 = new PendingGetBeacon($1, {timeout: 200}); + let p2 = new PendingGetBeacon($1, {timeout: 100}); + let p3 = new PendingGetBeacon($1, {timeout: 500}); + let p4 = new PendingGetBeacon($1, {timeout: 700}); + let p5 = new PendingGetBeacon($1, {timeout: 300}); + )", + kBeaconEndpoint)); + ASSERT_THAT(current_document(), IsFrameVisible()); + + WaitForAllBeaconsSent(total_beacon); + EXPECT_EQ(sent_beacon_count(), total_beacon); +} + +// Tests to cover PendingBeacon's backgroundTimeout & timeout mutual behaviors. +// Sets a long BFCache timeout (1min) so that beacon won't be sent out due to +// page eviction. +class PendingBeaconMutualTimeoutWithLongBackForwardCacheTTLBrowserTest + : public PendingBeaconTimeoutBrowserTestBase, + public BackForwardCacheMetricsTestMatcher { + protected: + void SetUpCommandLine(base::CommandLine* command_line) override { + feature_list_.InitWithFeaturesAndParameters( + {{blink::features::kPendingBeaconAPI, {}}, + {features::kBackForwardCache, + {{"TimeToLiveInBackForwardCacheInSeconds", "60"}}}}, + {}); + PendingBeaconTimeoutBrowserTestBase::SetUpCommandLine(command_line); + } + + void SetUpOnMainThread() override { + // TestAutoSetUkmRecorder's constructor requires a sequenced context. + ukm_recorder_ = std::make_unique<ukm::TestAutoSetUkmRecorder>(); + histogram_tester_ = std::make_unique<base::HistogramTester>(); + PendingBeaconTimeoutBrowserTestBase::SetUpOnMainThread(); + } + + void TearDownOnMainThread() override { + ukm_recorder_.reset(); + histogram_tester_.reset(); + PendingBeaconTimeoutBrowserTestBase::TearDownOnMainThread(); + } + + // `BackForwardCacheMetricsTestMatcher` implementation. + const ukm::TestAutoSetUkmRecorder& ukm_recorder() override { + return *ukm_recorder_; + } + // `BackForwardCacheMetricsTestMatcher` implementation. + const base::HistogramTester& histogram_tester() override { + return *histogram_tester_; + } + + private: + base::test::ScopedFeatureList feature_list_; + + std::unique_ptr<ukm::TestAutoSetUkmRecorder> ukm_recorder_; + std::unique_ptr<base::HistogramTester> histogram_tester_; +}; + +IN_PROC_BROWSER_TEST_F( + PendingBeaconMutualTimeoutWithLongBackForwardCacheTTLBrowserTest, + NotSendWhenPageIsRestoredBeforeBeingEvictedFromBackForwardCache) { + const size_t total_beacon = 0; + RegisterBeaconRequestMonitor(total_beacon); + + // Creates a pending beacon with default backgroundTimeout & timeout. + // It should not be sent out as long as the page is alive (not evicted from + // BackForwardCache). + RunScriptInANavigateToB(JsReplace(R"( + let p = new PendingGetBeacon($1); + )", + kBeaconEndpoint)); + ASSERT_THAT(previous_document(), IsFrameHidden()); + // Navigate back to A. + ASSERT_TRUE(HistoryGoBack(web_contents())); + // The same page A is still alive. + ExpectRestored(FROM_HERE); + + // Verify that beacon is not sent. + EXPECT_EQ(sent_beacon_count(), total_beacon); +} + +// When both backgroundTimeout & timeout is set, whichever expires earlier will +// trigger beacon sending (part 1). +IN_PROC_BROWSER_TEST_F( + PendingBeaconMutualTimeoutWithLongBackForwardCacheTTLBrowserTest, + SendOnEarlierTimeout) { + const size_t total_beacon = 1; + RegisterBeaconRequestMonitor(total_beacon); + + // Creates a pending beacon with long backgroundTimeout (60s) & short + // timeout (1s). + // The shorter one, i.e. timeout, should be reachable such that the beacon + // can be sent before this test case times out. + RunScriptInANavigateToB(JsReplace(R"( + let p = new PendingGetBeacon($1, {backgroundTimeout: 60000, timeout: 1000}); + )", + kBeaconEndpoint)); + ASSERT_THAT(previous_document(), IsFrameHidden()); + + WaitForAllBeaconsSent(total_beacon); + // Verify that beacon is sent. + EXPECT_EQ(sent_beacon_count(), total_beacon); +} + +// When both backgroundTimeout & timeout is set, whichever expires earlier will +// trigger beacon sending (part 2). +IN_PROC_BROWSER_TEST_F( + PendingBeaconMutualTimeoutWithLongBackForwardCacheTTLBrowserTest, + SendOnEarlierBackgroundTimeout) { + const size_t total_beacon = 1; + RegisterBeaconRequestMonitor(total_beacon); + + // Creates a pending beacon with short backgroundTimeout (1s) & long + // timeout (60s). + // The shorter one, i.e. backgroundTimeout, should be reachable such that the + // beacon can be sent before this test case times out. + RunScriptInANavigateToB(JsReplace(R"( + let p = new PendingGetBeacon($1, {backgroundTimeout: 1000, timeout: 60000}); + )", + kBeaconEndpoint)); + ASSERT_THAT(previous_document(), IsFrameHidden()); + + WaitForAllBeaconsSent(total_beacon); + // Verify that beacon is sent. + EXPECT_EQ(sent_beacon_count(), total_beacon); +} + +} // namespace content
diff --git a/content/browser/renderer_host/render_frame_host_delegate.h b/content/browser/renderer_host/render_frame_host_delegate.h index 009580f7..3d863d3 100644 --- a/content/browser/renderer_host/render_frame_host_delegate.h +++ b/content/browser/renderer_host/render_frame_host_delegate.h
@@ -661,6 +661,9 @@ bool is_hung) {} #endif + // The load progress for the primary main frame was changed. + virtual void DidChangeLoadProgressForPrimaryMainFrame() {} + protected: virtual ~RenderFrameHostDelegate() = default; };
diff --git a/content/browser/renderer_host/render_frame_host_factory.cc b/content/browser/renderer_host/render_frame_host_factory.cc index ccaaff0..4c5c585 100644 --- a/content/browser/renderer_host/render_frame_host_factory.cc +++ b/content/browser/renderer_host/render_frame_host_factory.cc
@@ -38,7 +38,8 @@ site_instance, std::move(render_view_host), delegate, frame_tree, frame_tree_node, routing_id, std::move(frame_remote), frame_token, renderer_initiated_creation, lifecycle_state, - std::move(browsing_context_state))); + std::move(browsing_context_state), + frame_tree_node->frame_owner_element_type())); } // static
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc index cc2f15ec..1a26e92 100644 --- a/content/browser/renderer_host/render_frame_host_impl.cc +++ b/content/browser/renderer_host/render_frame_host_impl.cc
@@ -1598,7 +1598,8 @@ const blink::LocalFrameToken& frame_token, bool renderer_initiated_creation_of_main_frame, LifecycleStateImpl lifecycle_state, - scoped_refptr<BrowsingContextState> browsing_context_state) + scoped_refptr<BrowsingContextState> browsing_context_state, + blink::FrameOwnerElementType frame_owner_element_type) : render_view_host_(std::move(render_view_host)), delegate_(delegate), site_instance_(static_cast<SiteInstanceImpl*>(site_instance)), @@ -1607,6 +1608,7 @@ frame_tree_(frame_tree), frame_tree_node_(frame_tree_node), browsing_context_state_(std::move(browsing_context_state)), + frame_owner_element_type_(frame_owner_element_type), parent_(frame_tree_node_->parent()), depth_(parent_ ? parent_->GetFrameDepth() + 1 : 0), last_committed_site_info_(site_instance_->GetBrowserContext()), @@ -5778,7 +5780,7 @@ } blink::FrameOwnerElementType RenderFrameHostImpl::GetFrameOwnerElementType() { - return frame_tree_node_->frame_owner_element_type(); + return frame_owner_element_type_; } bool RenderFrameHostImpl::HasTransientUserActivation() { @@ -6086,10 +6088,7 @@ } void RenderFrameHostImpl::DidChangeLoadProgress(double load_progress) { - // We should not be invoking DidChangeLoadProgress for subframes or fenced - // frames as we only update the observers for primary/ prerender main frame - // load progress change. - if (!is_main_frame() || IsFencedFrameRoot()) + if (!is_main_frame()) return; if (load_progress < GetPage().load_progress()) @@ -6097,7 +6096,9 @@ GetPage().set_load_progress(load_progress); - frame_tree_node_->frame_tree()->delegate()->DidChangeLoadProgress(); + // Only dispatch LoadProgressChanged for the primary main frame. + if (IsInPrimaryMainFrame()) + delegate_->DidChangeLoadProgressForPrimaryMainFrame(); } void RenderFrameHostImpl::DidFinishLoad(const GURL& validated_url) {
diff --git a/content/browser/renderer_host/render_frame_host_impl.h b/content/browser/renderer_host/render_frame_host_impl.h index 80101615..b68afb3 100644 --- a/content/browser/renderer_host/render_frame_host_impl.h +++ b/content/browser/renderer_host/render_frame_host_impl.h
@@ -2583,7 +2583,8 @@ const blink::LocalFrameToken& frame_token, bool renderer_initiated_creation_of_main_frame, LifecycleStateImpl lifecycle_state, - scoped_refptr<BrowsingContextState> browsing_context_state); + scoped_refptr<BrowsingContextState> browsing_context_state, + blink::FrameOwnerElementType frame_owner_element_type); // The SendCommit* functions below are wrappers for commit calls // made to mojom::NavigationClient. @@ -3494,6 +3495,9 @@ // TODO(crbug.com/1270671): make this field const when legacy mode is removed. scoped_refptr<BrowsingContextState> browsing_context_state_; + // Enum for the type of the frame owner element for a frame. + blink::FrameOwnerElementType frame_owner_element_type_; + // The immediate children of this specific frame. std::vector<std::unique_ptr<FrameTreeNode>> children_;
diff --git a/content/browser/renderer_host/render_frame_host_impl_browsertest.cc b/content/browser/renderer_host/render_frame_host_impl_browsertest.cc index 02539b6..7f6f7c7 100644 --- a/content/browser/renderer_host/render_frame_host_impl_browsertest.cc +++ b/content/browser/renderer_host/render_frame_host_impl_browsertest.cc
@@ -622,7 +622,8 @@ site_instance, std::move(render_view_host), delegate, frame_tree, frame_tree_node, routing_id, std::move(frame_remote), frame_token, renderer_initiated_creation, lifecycle_state, - std::move(browsing_context_state))); + std::move(browsing_context_state), + frame_tree_node->frame_owner_element_type())); } };
diff --git a/content/browser/renderer_host/render_frame_host_manager_browsertest.cc b/content/browser/renderer_host/render_frame_host_manager_browsertest.cc index f5288fca..f2eecb8 100644 --- a/content/browser/renderer_host/render_frame_host_manager_browsertest.cc +++ b/content/browser/renderer_host/render_frame_host_manager_browsertest.cc
@@ -7899,11 +7899,30 @@ return blink::mojom::SuddenTerminationDisablerType::kUnloadHandler; } + // Returns the list of event targets that the given `event_name` should be + // registered on. + // Since the `visibilitychange` event is fired at the document and it + // may bubble up to the window, we should test the cases where the event + // listener is registered on both the document and the window. + std::vector<const std::string> EventTargetsForEvent( + const std::string& event_name) { + if (event_name == "unload" || event_name == "beforeunload" || + event_name == "pagehide") { + return {"window"}; + } + if (event_name == "visibilitychange") { + return {"window", "document"}; + } + NOTREACHED(); + return {}; + } + // Adds an unload event handler (can be for the unload, pagehide, or // visibilitychange event) to |rfh| and verifies that the unload state // bookkeeping on |rfh| is updated properly. void AddUnloadEventHandler(RenderFrameHostImpl* rfh, const std::string& event_name, + const std::string& event_target, const std::string& script) { EXPECT_THAT(event_name, testing::AnyOf(testing::Eq("unload"), testing::Eq("pagehide"), @@ -7911,8 +7930,6 @@ EXPECT_FALSE(rfh->GetSuddenTerminationDisablerState( DisablerTypeForEvent(event_name))); EXPECT_FALSE(rfh->has_unload_handlers()); - std::string event_target = - event_name == "visibilitychange" ? "document" : "window"; EXPECT_TRUE(ExecuteScript( rfh, base::StringPrintf("%s.addEventListener('%s', (e) => { %s });", event_target.c_str(), event_name.c_str(), @@ -7985,25 +8002,28 @@ GURL c_url(embedded_test_server()->GetURL("c.com", "/title1.html")); for (const std::string& unload_event_name : unload_event_names) { - EXPECT_TRUE(NavigateToURL(shell(), main_url)); - FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) - ->GetPrimaryFrameTree() - .root(); - RenderFrameHostImpl* child_rfh = root->child_at(0)->current_frame_host(); + for (const std::string& unload_event_target : + EventTargetsForEvent(unload_event_name)) { + EXPECT_TRUE(NavigateToURL(shell(), main_url)); + FrameTreeNode* root = + static_cast<WebContentsImpl*>(shell()->web_contents()) + ->GetPrimaryFrameTree() + .root(); + RenderFrameHostImpl* child_rfh = root->child_at(0)->current_frame_host(); + // Add a subframe unload handler to do a termination ping via sendBeacon. + AddUnloadEventHandler( + child_rfh, unload_event_name, unload_event_target, + base::StringPrintf("navigator.sendBeacon('%s', 'ping');", + ping_url.spec().c_str())); + ExtendSubframeUnloadTimeoutForTerminationPing(child_rfh); - // Add a subframe unload handler to do a termination ping via sendBeacon. - AddUnloadEventHandler( - child_rfh, unload_event_name, - base::StringPrintf("navigator.sendBeacon('%s', 'ping');", - ping_url.spec().c_str())); - ExtendSubframeUnloadTimeoutForTerminationPing(child_rfh); - - // Navigate the main frame to c.com and wait for the ping. - StartMonitoringRequestsFor(ping_url); - EXPECT_TRUE(NavigateToURL(shell(), c_url)); - // Test succeeds if this doesn't time out while waiting for |ping_url|. - WaitForMonitoredRequest(); - EXPECT_EQ("ping", GetRequestContent()); + // Navigate the main frame to c.com and wait for the ping. + StartMonitoringRequestsFor(ping_url); + EXPECT_TRUE(NavigateToURL(shell(), c_url)); + // Test succeeds if this doesn't time out while waiting for |ping_url|. + WaitForMonitoredRequest(); + EXPECT_EQ("ping", GetRequestContent()); + } } } @@ -8028,7 +8048,7 @@ // image. GURL ping_url(embedded_test_server()->GetURL("b.com", "/blank.jpg")); AddUnloadEventHandler( - child_rfh, "unload", + child_rfh, "unload", "window", base::StringPrintf("var img = document.createElement('img');" "img.src = '%s';" "document.body.appendChild(img);", @@ -8071,7 +8091,7 @@ // sendBeacon. GURL ping_url(embedded_test_server()->GetURL("c.com", "/empty.html")); AddUnloadEventHandler( - child_rfh, "unload", + child_rfh, "unload", "window", base::StringPrintf("navigator.sendBeacon('%s', 'ping');", ping_url.spec().c_str())); ExtendSubframeUnloadTimeoutForTerminationPing(child_rfh); @@ -8101,7 +8121,7 @@ RenderFrameHostImpl* child_rfh = root->child_at(0)->current_frame_host(); // Add an unload handler which never finishes to b.com subframe. - AddUnloadEventHandler(child_rfh, "unload", "while(1);"); + AddUnloadEventHandler(child_rfh, "unload", "window", "while(1);"); // Navigate the main frame to c.com and wait for the subframe process to // shut down. This should happen when the subframe unload timeout happens, @@ -8147,7 +8167,7 @@ // Add an unload handler in the child frame to send a postMessage to the // parent frame. - AddUnloadEventHandler(child->current_frame_host(), "unload", + AddUnloadEventHandler(child->current_frame_host(), "unload", "window", "parent.postMessage('foo', '*')"); // Navigate the subframe cross-site to c.com and wait for the message. @@ -8162,7 +8182,7 @@ // Now repeat the test with a remote-to-local navigation that brings the // subframe back to a.com. - AddUnloadEventHandler(child->current_frame_host(), "unload", + AddUnloadEventHandler(child->current_frame_host(), "unload", "window", "parent.postMessage('bar', '*')"); GURL a_url(embedded_test_server()->GetURL("a.com", "/title2.html")); EXPECT_TRUE(ExecuteScriptAndExtractString( @@ -8252,14 +8272,7 @@ for (const std::string& event_name : sudden_termination_disabler_event_names) { - std::vector<const std::string> event_targets = {"window"}; - // Since the `visibilitychange` event is fired at the document and it - // may bubble up to the window, we should test the cases where the event - // listener is registered on both the document and window. - if (event_name == "visibilitychange") - event_targets.push_back("document"); - - for (const std::string& event_target : event_targets) { + for (const std::string& event_target : EventTargetsForEvent(event_name)) { // The sudden termination disabler state is initially set to false. EXPECT_FALSE(rfh->GetSuddenTerminationDisablerState( DisablerTypeForEvent(event_name)));
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc index 718d135..77196ac 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc
@@ -7496,7 +7496,7 @@ LoadingStateChanged(true /* should_show_loading_ui */, details.get()); } -void WebContentsImpl::DidChangeLoadProgress() { +void WebContentsImpl::DidChangeLoadProgressForPrimaryMainFrame() { OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::DidChangeLoadProgress"); if (IsBeingDestroyed()) return;
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h index 91dd718d..805e7e0 100644 --- a/content/browser/web_contents/web_contents_impl.h +++ b/content/browser/web_contents/web_contents_impl.h
@@ -818,6 +818,7 @@ const base::FilePath& path, bool is_hung) override; #endif // BUILDFLAG(ENABLE_PPAPI) + void DidChangeLoadProgressForPrimaryMainFrame() override; // RenderViewHostDelegate ---------------------------------------------------- RenderViewHostDelegateView* GetDelegateView() override; @@ -1031,7 +1032,6 @@ void DidStartLoading(FrameTreeNode* frame_tree_node, bool should_show_loading_ui) override; void DidStopLoading() override; - void DidChangeLoadProgress() override; bool IsHidden() override; void NotifyPageChanged(PageImpl& page) override; int GetOuterDelegateFrameTreeNodeId() override;
diff --git a/content/renderer/render_view_browsertest.cc b/content/renderer/render_view_browsertest.cc index d750ee8c..b7bf427 100644 --- a/content/renderer/render_view_browsertest.cc +++ b/content/renderer/render_view_browsertest.cc
@@ -2978,7 +2978,7 @@ base::RunLoop run_loop; bool was_callback_run = false; message_mock_frame_host()->SetDidAddMessageToConsoleCallback( - base::BindOnce(base::BindLambdaForTesting([&](const std::u16string& msg) { + base::BindLambdaForTesting([&](const std::u16string& msg) { // Makes sure this happens during the beforeunload handler. EXPECT_EQ(u"OnBeforeUnload called", msg); @@ -2990,7 +2990,7 @@ was_callback_run = true; run_loop.Quit(); - }))); + })); // Simulate a BeforeUnload IPC received from the browser. frame()->SimulateBeforeUnload(false);
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index 597d4fa2..8a711ca 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -1395,6 +1395,7 @@ "../browser/renderer_host/page_impl_browsertest.cc", "../browser/renderer_host/page_lifecycle_state_manager_browsertest.cc", "../browser/renderer_host/panel_rotation_browsertest.cc", + "../browser/renderer_host/pending_beacon_browsertest.cc", "../browser/renderer_host/policy_container_host_browsertest.cc", "../browser/renderer_host/private_network_access_browsertest.cc", "../browser/renderer_host/render_document_host_browsertest.cc",
diff --git a/content/test/test_render_frame_host.cc b/content/test/test_render_frame_host.cc index 48cb0c1d7..5a4a3a4fc4 100644 --- a/content/test/test_render_frame_host.cc +++ b/content/test/test_render_frame_host.cc
@@ -83,7 +83,8 @@ frame_token, /*renderer_initiated_creation_of_main_frame=*/false, lifecycle_state, - browsing_context_state), + browsing_context_state, + frame_tree_node->frame_owner_element_type()), child_creation_observer_( WebContents::FromRenderViewHost(render_view_host.get())), simulate_history_list_was_cleared_(false),
diff --git a/docs/infra/watchlists.md b/docs/infra/watchlists.md index f88f0a21..0ac1457 100644 --- a/docs/infra/watchlists.md +++ b/docs/infra/watchlists.md
@@ -62,7 +62,7 @@ Example (from src): ``` -python ../depot_tools/watchlists.py PATH/TO/FILE1 PATH/TO/FILE2 .... +python third_party/depot_tools/watchlists.py PATH/TO/FILE1 PATH/TO/FILE2 .... ```
diff --git a/extensions/browser/api/audio/audio_apitest_chromeos.cc b/extensions/browser/api/audio/audio_apitest_chromeos.cc index 707e262..d46558d 100644 --- a/extensions/browser/api/audio/audio_apitest_chromeos.cc +++ b/extensions/browser/api/audio/audio_apitest_chromeos.cc
@@ -57,6 +57,9 @@ const uint32_t kInputAudioEffect = 1; const uint32_t kOutputAudioEffect = 0; +const int32_t kInputNumberOfVolumeSteps = 0; +const int32_t kOutputNumberOfVolumeSteps = 25; + const AudioNodeInfo kJabraSpeaker1 = { false, kJabraSpeaker1Id, kJabraSpeaker1StableDeviceId, "Jabra Speaker", "USB", "Jabra Speaker 1"}; @@ -90,7 +93,8 @@ version == 2 ? info.stable_id ^ 0xFFFF : 0, info.device_name, info.type, info.name, false, 0, info.is_input ? kInputMaxSupportedChannels : kOutputMaxSupportedChannels, - info.is_input ? kInputAudioEffect : kOutputAudioEffect); + info.is_input ? kInputAudioEffect : kOutputAudioEffect, + info.is_input ? kInputNumberOfVolumeSteps : kOutputNumberOfVolumeSteps); } class AudioApiTest : public ShellApiTest {
diff --git a/extensions/browser/api/declarative/rules_registry.cc b/extensions/browser/api/declarative/rules_registry.cc index ce61fb7..3476151e 100644 --- a/extensions/browser/api/declarative/rules_registry.cc +++ b/extensions/browser/api/declarative/rules_registry.cc
@@ -54,11 +54,11 @@ return rules; rules.reserve(value->GetList().size()); - for (const base::Value& value : value->GetList()) { - if (!value.is_dict()) + for (const base::Value& dict_value : value->GetList()) { + if (!dict_value.is_dict()) continue; api::events::Rule rule; - if (api::events::Rule::Populate(value, &rule)) + if (api::events::Rule::Populate(dict_value, &rule)) rules.push_back(std::move(rule)); }
diff --git a/extensions/browser/api/socket/socket_api.cc b/extensions/browser/api/socket/socket_api.cc index 7ebf328..36f58b6 100644 --- a/extensions/browser/api/socket/socket_api.cc +++ b/extensions/browser/api/socket/socket_api.cc
@@ -13,7 +13,6 @@ #include "base/containers/span.h" #include "base/values.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/network_service_instance.h" @@ -42,6 +41,10 @@ namespace extensions { +#if BUILDFLAG(IS_CHROMEOS_ASH) +const char kCrOSTerminal[] = "chrome-untrusted://terminal"; +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + namespace { const char kAddressKey[] = "address"; @@ -66,7 +69,6 @@ #if BUILDFLAG(IS_CHROMEOS_ASH) const char kFirewallFailure[] = "Failed to open firewall port"; -const char kCrOSTerminal[] = "chrome-untrusted://terminal"; #endif // BUILDFLAG(IS_CHROMEOS_ASH) bool IsPortValid(int port) {
diff --git a/extensions/browser/api/socket/socket_api.h b/extensions/browser/api/socket/socket_api.h index ba622a6..f55015c 100644 --- a/extensions/browser/api/socket/socket_api.h +++ b/extensions/browser/api/socket/socket_api.h
@@ -56,6 +56,11 @@ } // namespace network namespace extensions { + +#if BUILDFLAG(IS_CHROMEOS_ASH) +extern const char kCrOSTerminal[]; +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + class Socket; // A simple interface to ApiResourceManager<Socket> or derived class. The goal
diff --git a/extensions/browser/api/sockets_tcp/tcp_socket_event_dispatcher.cc b/extensions/browser/api/sockets_tcp/tcp_socket_event_dispatcher.cc index 2a18ba5..ace17035 100644 --- a/extensions/browser/api/sockets_tcp/tcp_socket_event_dispatcher.cc +++ b/extensions/browser/api/sockets_tcp/tcp_socket_event_dispatcher.cc
@@ -196,10 +196,18 @@ reinterpret_cast<content::BrowserContext*>(browser_context_id); if (!extensions::ExtensionsBrowserClient::Get()->IsValidContext(context)) return; - - EventRouter* event_router = EventRouter::Get(context); - if (event_router) - event_router->DispatchEventToExtension(extension_id, std::move(event)); + EventRouter* router = EventRouter::Get(context); + if (router) { +#if BUILDFLAG(IS_CHROMEOS_ASH) + // Terminal app is the only non-extension to use sockets + // (crbug.com/1350479). + if (extension_id == kCrOSTerminal) { + router->DispatchEventToURL(GURL(extension_id), std::move(event)); + return; + } +#endif + router->DispatchEventToExtension(extension_id, std::move(event)); + } } } // namespace api
diff --git a/extensions/browser/api/sockets_tcp_server/sockets_tcp_server_api.cc b/extensions/browser/api/sockets_tcp_server/sockets_tcp_server_api.cc index 8537449..286f324 100644 --- a/extensions/browser/api/sockets_tcp_server/sockets_tcp_server_api.cc +++ b/extensions/browser/api/sockets_tcp_server/sockets_tcp_server_api.cc
@@ -88,8 +88,7 @@ sockets_tcp_server::Create::Params::Create(args()); EXTENSION_FUNCTION_VALIDATE(params.get()); - auto* socket = - new ResumableTCPServerSocket(browser_context(), extension_->id()); + auto* socket = new ResumableTCPServerSocket(browser_context(), GetOriginId()); sockets_tcp_server::SocketProperties* properties = params->properties.get(); if (properties) { @@ -146,7 +145,7 @@ if (socket->paused() != params->paused) { socket->set_paused(params->paused); if (socket->IsConnected() && !params->paused) { - socket_event_dispatcher->OnServerSocketResume(extension_->id(), + socket_event_dispatcher->OnServerSocketResume(GetOriginId(), params->socket_id); } } @@ -199,7 +198,7 @@ return; } if (net_result == net::OK) { - socket_event_dispatcher_->OnServerSocketListen(extension_->id(), + socket_event_dispatcher_->OnServerSocketListen(GetOriginId(), params_->socket_id); } else { Respond(ErrorWithCode(net_result, net::ErrorToString(net_result)));
diff --git a/extensions/browser/api/sockets_tcp_server/tcp_server_socket_event_dispatcher.cc b/extensions/browser/api/sockets_tcp_server/tcp_server_socket_event_dispatcher.cc index cdf1e2c..f5aa83d 100644 --- a/extensions/browser/api/sockets_tcp_server/tcp_server_socket_event_dispatcher.cc +++ b/extensions/browser/api/sockets_tcp_server/tcp_server_socket_event_dispatcher.cc
@@ -200,8 +200,17 @@ if (!extensions::ExtensionsBrowserClient::Get()->IsValidContext(context)) return; EventRouter* router = EventRouter::Get(context); - if (router) + if (router) { +#if BUILDFLAG(IS_CHROMEOS_ASH) + // Terminal app is the only non-extension to use sockets + // (crbug.com/1350479). + if (extension_id == kCrOSTerminal) { + router->DispatchEventToURL(GURL(extension_id), std::move(event)); + return; + } +#endif router->DispatchEventToExtension(extension_id, std::move(event)); + } } } // namespace api
diff --git a/extensions/browser/api/sockets_udp/sockets_udp_api.cc b/extensions/browser/api/sockets_udp/sockets_udp_api.cc index 0cb0d26..f70f35f 100644 --- a/extensions/browser/api/sockets_udp/sockets_udp_api.cc +++ b/extensions/browser/api/sockets_udp/sockets_udp_api.cc
@@ -113,7 +113,7 @@ ResumableUDPSocket* socket = new ResumableUDPSocket( std::move(udp_socket), std::move(socket_listener_receiver), - extension_->id()); + GetOriginId()); sockets_udp::SocketProperties* properties = params->properties.get(); if (properties) { @@ -169,8 +169,7 @@ if (socket->paused() != params->paused) { socket->set_paused(params->paused); if (socket->IsConnected() && !params->paused) { - socket_event_dispatcher->OnSocketResume(extension_->id(), - params->socket_id); + socket_event_dispatcher->OnSocketResume(GetOriginId(), params->socket_id); } } @@ -214,8 +213,7 @@ return; } if (net_result == net::OK) { - socket_event_dispatcher_->OnSocketBind(extension_->id(), - params_->socket_id); + socket_event_dispatcher_->OnSocketBind(GetOriginId(), params_->socket_id); } else { Respond(ErrorWithCode(net_result, net::ErrorToString(net_result))); return;
diff --git a/extensions/browser/api/sockets_udp/udp_socket_event_dispatcher.cc b/extensions/browser/api/sockets_udp/udp_socket_event_dispatcher.cc index 57fc408..7f330d2 100644 --- a/extensions/browser/api/sockets_udp/udp_socket_event_dispatcher.cc +++ b/extensions/browser/api/sockets_udp/udp_socket_event_dispatcher.cc
@@ -185,8 +185,17 @@ if (!extensions::ExtensionsBrowserClient::Get()->IsValidContext(context)) return; EventRouter* router = EventRouter::Get(context); - if (router) + if (router) { +#if BUILDFLAG(IS_CHROMEOS_ASH) + // Terminal app is the only non-extension to use sockets + // (crbug.com/1350479). + if (extension_id == kCrOSTerminal) { + router->DispatchEventToURL(GURL(extension_id), std::move(event)); + return; + } +#endif router->DispatchEventToExtension(extension_id, std::move(event)); + } } } // namespace api
diff --git a/extensions/browser/event_router.cc b/extensions/browser/event_router.cc index 2b2c1cc8..17e3734 100644 --- a/extensions/browser/event_router.cc +++ b/extensions/browser/event_router.cc
@@ -794,13 +794,19 @@ } void EventRouter::BroadcastEvent(std::unique_ptr<Event> event) { - DispatchEventImpl(std::string(), std::move(event)); + DispatchEventImpl(std::string(), GURL(), std::move(event)); } void EventRouter::DispatchEventToExtension(const std::string& extension_id, std::unique_ptr<Event> event) { DCHECK(!extension_id.empty()); - DispatchEventImpl(extension_id, std::move(event)); + DispatchEventImpl(extension_id, GURL(), std::move(event)); +} + +void EventRouter::DispatchEventToURL(const GURL& url, + std::unique_ptr<Event> event) { + DCHECK(!url.is_empty()); + DispatchEventImpl(std::string(), url, std::move(event)); } void EventRouter::DispatchEventWithLazyListener(const std::string& extension_id, @@ -840,6 +846,7 @@ } void EventRouter::DispatchEventImpl(const std::string& restrict_to_extension_id, + const GURL& restrict_to_url, std::unique_ptr<Event> event) { DCHECK(event); // We don't expect to get events from a completely different browser context. @@ -872,6 +879,10 @@ restrict_to_extension_id != listener->extension_id()) { continue; } + if (!restrict_to_url.is_empty() && + !url::IsSameOriginWith(restrict_to_url, listener->listener_url())) { + continue; + } if (!listener->IsLazy()) continue; @@ -885,6 +896,10 @@ restrict_to_extension_id != listener->extension_id()) { continue; } + if (!restrict_to_url.is_empty() && + !url::IsSameOriginWith(restrict_to_url, listener->listener_url())) { + continue; + } if (listener->IsLazy()) continue; if (lazy_event_dispatcher.HasAlreadyDispatched(
diff --git a/extensions/browser/event_router.h b/extensions/browser/event_router.h index 2dcb2d63..8aae1c36b 100644 --- a/extensions/browser/event_router.h +++ b/extensions/browser/event_router.h
@@ -290,6 +290,10 @@ virtual void DispatchEventToExtension(const std::string& extension_id, std::unique_ptr<Event> event); + // Dispatches an event to the given url. + virtual void DispatchEventToURL(const GURL& owner_url, + std::unique_ptr<Event> event); + // Dispatches |event| to the given extension as if the extension has a lazy // listener for it. NOTE: This should be used rarely, for dispatching events // to extensions that haven't had a chance to add their own listeners yet, eg: @@ -337,6 +341,7 @@ friend class DownloadExtensionTest; friend class SystemInfoAPITest; FRIEND_TEST_ALL_PREFIXES(EventRouterTest, MultipleEventRouterObserver); + FRIEND_TEST_ALL_PREFIXES(EventRouterDispatchTest, TestDispatch); FRIEND_TEST_ALL_PREFIXES( DeveloperPrivateApiUnitTest, UpdateHostAccess_UnrequestedHostsDispatchUpdateEvents); @@ -404,10 +409,11 @@ void RemoveLazyEventListenerImpl(std::unique_ptr<EventListener> listener, RegisteredEventType type); - // Shared by all event dispatch methods. If |restrict_to_extension_id| is - // empty, the event is broadcast. An event that just came off the pending - // list may not be delayed again. + // Shared by all event dispatch methods. If |restrict_to_extension_id| and + // |restrict_to_url| is empty, the event is broadcast. An event that just + // came off the pending list may not be delayed again. void DispatchEventImpl(const std::string& restrict_to_extension_id, + const GURL& restrict_to_url, std::unique_ptr<Event> event); // Dispatches the event to the specified extension or URL running in
diff --git a/extensions/browser/event_router_unittest.cc b/extensions/browser/event_router_unittest.cc index ae37063d..0be81a0 100644 --- a/extensions/browser/event_router_unittest.cc +++ b/extensions/browser/event_router_unittest.cc
@@ -16,8 +16,12 @@ #include "content/public/test/mock_render_process_host.h" #include "extensions/browser/event_listener_map.h" #include "extensions/browser/extensions_test.h" +#include "extensions/browser/test_event_router_observer.h" +#include "extensions/common/extension_api.h" #include "extensions/common/extension_builder.h" #include "extensions/common/extension_messages.h" +#include "extensions/common/features/feature_provider.h" +#include "extensions/common/features/simple_feature.h" #include "testing/gtest/include/gtest/gtest.h" using base::DictionaryValue; @@ -196,7 +200,7 @@ class EventRouterFilterTest : public ExtensionsTest, public testing::WithParamInterface<bool> { public: - EventRouterFilterTest() {} + EventRouterFilterTest() = default; EventRouterFilterTest(const EventRouterFilterTest&) = delete; EventRouterFilterTest& operator=(const EventRouterFilterTest&) = delete; @@ -515,4 +519,91 @@ EventRouterFilterTest, testing::Values(true)); +class EventRouterDispatchTest : public ExtensionsTest { + public: + EventRouterDispatchTest() = default; + EventRouterDispatchTest(const EventRouterDispatchTest&) = delete; + EventRouterDispatchTest& operator=(const EventRouterDispatchTest&) = delete; + + void SetUp() override { + ExtensionsTest::SetUp(); + render_process_host_ = + std::make_unique<content::MockRenderProcessHost>(browser_context()); + ASSERT_TRUE(event_router()); // constructs EventRouter + } + + void TearDown() override { + render_process_host_.reset(); + ExtensionsTest::TearDown(); + } + + content::RenderProcessHost* process() const { + return render_process_host_.get(); + } + EventRouter* event_router() { return EventRouter::Get(browser_context()); } + + private: + std::unique_ptr<content::RenderProcessHost> render_process_host_; +}; + +TEST_F(EventRouterDispatchTest, TestDispatch) { + std::string ext1 = "ext1"; + std::string ext2 = "ext2"; + GURL webui1("chrome-untrusted://one"); + GURL webui2("chrome-untrusted://two"); + std::string event_name = "testapi.onEvent"; + FeatureProvider provider; + auto feature = std::make_unique<SimpleFeature>(); + feature->set_name("test feature"); + feature->set_matches({webui1.spec().c_str(), webui2.spec().c_str()}); + provider.AddFeature(event_name, std::move(feature)); + ExtensionAPI::GetSharedInstance()->RegisterDependencyProvider("api", + &provider); + TestEventRouterObserver observer(event_router()); + auto add_extension = [&](const std::string& id) { + scoped_refptr<const Extension> extension = + ExtensionBuilder() + .SetID(id) + .SetManifest(DictionaryBuilder() + .Set("name", "Test app") + .Set("version", "1.0") + .Set("manifest_version", 2) + .Build()) + .Build(); + ExtensionRegistry::Get(browser_context())->AddEnabled(extension); + }; + add_extension(ext1); + add_extension(ext2); + auto event = [](std::string name) { + return std::make_unique<extensions::Event>(extensions::events::FOR_TEST, + name, base::Value::List()); + }; + + // Register both extensions and both URLs for event. + event_router()->AddEventListener(event_name, process(), ext1); + event_router()->AddEventListener(event_name, process(), ext2); + event_router()->AddEventListenerForURL(event_name, process(), webui1); + event_router()->AddEventListenerForURL(event_name, process(), webui2); + + // Should only dispatch to the single specified extension or url. + event_router()->DispatchEventToExtension(ext1, event(event_name)); + EXPECT_EQ(1u, observer.dispatched_events().size()); + observer.ClearEvents(); + event_router()->DispatchEventToExtension(ext2, event(event_name)); + EXPECT_EQ(1u, observer.dispatched_events().size()); + observer.ClearEvents(); + event_router()->DispatchEventToURL(webui1, event(event_name)); + EXPECT_EQ(1u, observer.dispatched_events().size()); + observer.ClearEvents(); + event_router()->DispatchEventToURL(webui2, event(event_name)); + EXPECT_EQ(1u, observer.dispatched_events().size()); + observer.ClearEvents(); + + // No listeners registered for 'api.other' event. + event_router()->DispatchEventToExtension(ext1, event("api.other")); + EXPECT_EQ(0u, observer.dispatched_events().size()); + event_router()->DispatchEventToURL(webui1, event("api.other")); + EXPECT_EQ(0u, observer.dispatched_events().size()); +} + } // namespace extensions
diff --git a/gpu/command_buffer/common/sync_token.cc b/gpu/command_buffer/common/sync_token.cc index 69dfc8f..3f730ca 100644 --- a/gpu/command_buffer/common/sync_token.cc +++ b/gpu/command_buffer/common/sync_token.cc
@@ -4,6 +4,7 @@ #include "gpu/command_buffer/common/sync_token.h" +#include <algorithm> #include <sstream> namespace gpu { @@ -39,4 +40,23 @@ return stream.str(); } +std::vector<SyncToken> ReduceSyncTokens(base::span<const SyncToken> tokens) { + std::vector<SyncToken> reduced; + for (const SyncToken& next_token : tokens) { + auto itr = std::find_if( + reduced.begin(), reduced.end(), [&next_token](const SyncToken& token) { + return next_token.namespace_id() == token.namespace_id() && + next_token.command_buffer_id() == token.command_buffer_id(); + }); + if (itr == reduced.end()) { + reduced.push_back(next_token); + } else { + if (itr->release_count() < next_token.release_count()) { + *itr = next_token; + } + } + } + return reduced; +} + } // namespace gpu
diff --git a/gpu/command_buffer/common/sync_token.h b/gpu/command_buffer/common/sync_token.h index eae3faf2..9d1d42e0 100644 --- a/gpu/command_buffer/common/sync_token.h +++ b/gpu/command_buffer/common/sync_token.h
@@ -9,7 +9,9 @@ #include <string.h> #include <tuple> +#include <vector> +#include "base/containers/span.h" #include "gpu/command_buffer/common/command_buffer_id.h" #include "gpu/command_buffer/common/constants.h" #include "gpu/gpu_export.h" @@ -96,6 +98,11 @@ static_assert(sizeof(SyncToken) <= GL_SYNC_TOKEN_SIZE_CHROMIUM, "SyncToken size must not exceed GL_SYNC_TOKEN_SIZE_CHROMIUM"); +// Remove redundant tokens such that it should be equivalent to wait on all +// tokens in the output instead of waiting on all input `tokens`. +GPU_EXPORT std::vector<SyncToken> ReduceSyncTokens( + base::span<const SyncToken> tokens); + } // namespace gpu #endif // GPU_COMMAND_BUFFER_COMMON_SYNC_TOKEN_H_
diff --git a/gpu/command_buffer/service/scheduler.cc b/gpu/command_buffer/service/scheduler.cc index 39fa45e..2acd932 100644 --- a/gpu/command_buffer/service/scheduler.cc +++ b/gpu/command_buffer/service/scheduler.cc
@@ -489,7 +489,7 @@ uint32_t order_num = sequence->ScheduleTask(std::move(task.closure), std::move(task.report_callback)); - for (const SyncToken& sync_token : task.sync_token_fences) { + for (const SyncToken& sync_token : ReduceSyncTokens(task.sync_token_fences)) { SequenceId release_sequence_id = sync_point_manager_->GetSyncTokenReleaseSequenceId(sync_token); // base::Unretained is safe here since all sequences and corresponding sync
diff --git a/infra/config/dev.star b/infra/config/dev.star index 6ccb444..feb21c2d 100755 --- a/infra/config/dev.star +++ b/infra/config/dev.star
@@ -22,6 +22,7 @@ tracked_files = [ "luci/chops-weetbix-dev.cfg", "luci/cr-buildbucket-dev.cfg", + "luci/luci-analysis-dev.cfg", "luci/luci-logdog-dev.cfg", "luci/luci-milo-dev.cfg", "luci/luci-scheduler-dev.cfg", @@ -30,10 +31,16 @@ fail_on_warnings = True, ) -# Just copy chops-weetbix-dev.cfg to generated outputs. +# Just copy LUCI Analysis config to generated outputs. +lucicfg.emit( + dest = "luci/luci-analysis-dev.cfg", + data = io.read_file("luci-analysis-dev.cfg"), +) + +# TODO(b/243488110): Delete when instance decommissioned. lucicfg.emit( dest = "luci/chops-weetbix-dev.cfg", - data = io.read_file("chops-weetbix-dev.cfg"), + data = io.read_file("luci-analysis-dev.cfg"), ) branches.exec("//dev/dev.star")
diff --git a/infra/config/chops-weetbix-dev.cfg b/infra/config/generated/luci/luci-analysis-dev.cfg similarity index 100% copy from infra/config/chops-weetbix-dev.cfg copy to infra/config/generated/luci/luci-analysis-dev.cfg
diff --git a/infra/config/chops-weetbix.cfg b/infra/config/generated/luci/luci-analysis.cfg similarity index 100% copy from infra/config/chops-weetbix.cfg copy to infra/config/generated/luci/luci-analysis.cfg
diff --git a/infra/config/chops-weetbix-dev.cfg b/infra/config/luci-analysis-dev.cfg similarity index 100% rename from infra/config/chops-weetbix-dev.cfg rename to infra/config/luci-analysis-dev.cfg
diff --git a/infra/config/chops-weetbix.cfg b/infra/config/luci-analysis.cfg similarity index 100% rename from infra/config/chops-weetbix.cfg rename to infra/config/luci-analysis.cfg
diff --git a/infra/config/main.star b/infra/config/main.star index f4564757..f1c7b19 100755 --- a/infra/config/main.star +++ b/infra/config/main.star
@@ -28,6 +28,7 @@ "luci/commit-queue.cfg", "luci/chops-weetbix.cfg", "luci/cr-buildbucket.cfg", + "luci/luci-analysis.cfg", "luci/luci-logdog.cfg", "luci/luci-milo.cfg", "luci/luci-notify.cfg", @@ -58,11 +59,16 @@ data = io.read_file("tricium-prod.cfg"), ) -# Weetbix configuration is also copied verbatim to generated -# outputs. +# Just copy LUCI Analysis config to generated outputs. +lucicfg.emit( + dest = "luci/luci-analysis.cfg", + data = io.read_file("luci-analysis.cfg"), +) + +# TODO(b/243488110): Delete when instance decommissioned. lucicfg.emit( dest = "luci/chops-weetbix.cfg", - data = io.read_file("chops-weetbix.cfg"), + data = io.read_file("luci-analysis.cfg"), ) luci.project(
diff --git a/ios/chrome/browser/history/BUILD.gn b/ios/chrome/browser/history/BUILD.gn index d26e56e89..88364af 100644 --- a/ios/chrome/browser/history/BUILD.gn +++ b/ios/chrome/browser/history/BUILD.gn
@@ -58,6 +58,8 @@ "//components/strings", "//ios/chrome/browser", "//ios/chrome/browser/browser_state", + "//ios/chrome/browser/complex_tasks", + "//ios/chrome/browser/sessions", "//ios/web", "//ui/base", "//url",
diff --git a/ios/chrome/browser/history/history_tab_helper.h b/ios/chrome/browser/history/history_tab_helper.h index 5977f827..bc99ee7 100644 --- a/ios/chrome/browser/history/history_tab_helper.h +++ b/ios/chrome/browser/history/history_tab_helper.h
@@ -19,6 +19,7 @@ namespace web { class NavigationItem; +class NavigationContext; } // namespace web // HistoryTabHelper updates the history database based on navigation events from @@ -32,13 +33,15 @@ ~HistoryTabHelper() override; - // Updates history with the specified navigation. - void UpdateHistoryForNavigation( - const history::HistoryAddPageArgs& add_page_args); - - // Sends the page title to the history service. + // Sends the page title to the history service. Public for testing. void UpdateHistoryPageTitle(const web::NavigationItem& item); + // Returns the history::HistoryAddPageArgs to use for adding a page to + // history. Public for testing. + history::HistoryAddPageArgs CreateHistoryAddPageArgs( + web::NavigationItem* last_committed_item, + web::NavigationContext* navigation_context); + // Sets whether the navigation should be send to the HistoryService or saved // for later (this will generally be set to true while the WebState is used // for pre-rendering).
diff --git a/ios/chrome/browser/history/history_tab_helper.mm b/ios/chrome/browser/history/history_tab_helper.mm index 9a53fde..6a1b970 100644 --- a/ios/chrome/browser/history/history_tab_helper.mm +++ b/ios/chrome/browser/history/history_tab_helper.mm
@@ -12,7 +12,10 @@ #include "components/strings/grit/components_strings.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h" #include "ios/chrome/browser/chrome_url_constants.h" +#import "ios/chrome/browser/complex_tasks/ios_content_record_task_id.h" +#import "ios/chrome/browser/complex_tasks/ios_task_tab_helper.h" #include "ios/chrome/browser/history/history_service_factory.h" +#import "ios/chrome/browser/sessions/ios_chrome_session_tab_helper.h" #import "ios/web/public/navigation/navigation_context.h" #import "ios/web/public/navigation/navigation_item.h" #import "ios/web/public/navigation/navigation_manager.h" @@ -57,6 +60,91 @@ } } +history::HistoryAddPageArgs HistoryTabHelper::CreateHistoryAddPageArgs( + web::NavigationItem* last_committed_item, + web::NavigationContext* navigation_context) { + const GURL& url = last_committed_item->GetURL(); + + const ui::PageTransition transition = + last_committed_item->GetTransitionType(); + + history::RedirectList redirects; + const GURL& original_url = last_committed_item->GetOriginalRequestURL(); + const GURL& referrer_url = last_committed_item->GetReferrer().url; + if (original_url != url) { + // Simulate a valid redirect chain in case of URLs that have been modified + // by CRWWebController -finishHistoryNavigationFromEntry:. + if (transition & ui::PAGE_TRANSITION_CLIENT_REDIRECT || + url.EqualsIgnoringRef(original_url)) { + redirects.push_back(referrer_url); + } + // TODO(crbug.com/703872): the redirect chain is not constructed the same + // way as desktop so this part needs to be revised. + redirects.push_back(original_url); + redirects.push_back(url); + } + + // Navigations originating from New Tab Page or Reading List should not + // contribute to Most Visited. + const bool content_suggestions_navigation = + referrer_url == ntp_snippets::GetContentSuggestionsReferrerURL() && + ui::PageTransitionCoreTypeIs(transition, + ui::PAGE_TRANSITION_AUTO_BOOKMARK); + const bool consider_for_ntp_most_visited = + !content_suggestions_navigation && + referrer_url != kReadingListReferrerURL; + + const int http_response_code = + navigation_context->GetResponseHeaders() + ? navigation_context->GetResponseHeaders()->response_code() + : 0; + + // Hide navigations that result in an error in order to prevent the omnibox + // from suggesting URLs that have never been navigated to successfully. + // (If a navigation to the URL succeeds at some point, the URL will be + // unhidden and thus eligible to be suggested by the omnibox.) + const bool hidden = (http_response_code >= 400); + + history::VisitContextAnnotations::OnVisitFields context_annotations; + + context_annotations.browser_type = + history::VisitContextAnnotations::BrowserType::kTabbed; + + IOSChromeSessionTabHelper* session_tab_helper = + IOSChromeSessionTabHelper::FromWebState(web_state_); + if (session_tab_helper) { + context_annotations.window_id = session_tab_helper->window_id(); + context_annotations.tab_id = session_tab_helper->session_id(); + } + + IOSTaskTabHelper* task_tab_helper = + IOSTaskTabHelper::FromWebState(web_state_); + if (task_tab_helper) { + const IOSContentRecordTaskId* content_record_task_id = + task_tab_helper->GetContextRecordTaskId( + last_committed_item->GetUniqueID()); + if (content_record_task_id) { + context_annotations.task_id = content_record_task_id->task_id(); + context_annotations.root_task_id = content_record_task_id->root_task_id(); + context_annotations.parent_task_id = + content_record_task_id->parent_task_id(); + } + } + + context_annotations.response_code = http_response_code; + + return history::HistoryAddPageArgs( + url, last_committed_item->GetTimestamp(), this, + last_committed_item->GetUniqueID(), referrer_url, redirects, transition, + hidden, history::SOURCE_BROWSED, + /*did_replace_entry=*/false, consider_for_ntp_most_visited, + navigation_context->IsSameDocument() ? GetPageTitle(*last_committed_item) + : absl::nullopt, + /*opener=*/absl::nullopt, + /*bookmark_id=*/absl::nullopt, + /*context_annotations=*/std::move(context_annotations)); +} + void HistoryTabHelper::SetDelayHistoryServiceNotification( bool delay_notification) { delay_notification_ = delay_notification; @@ -130,8 +218,8 @@ // desktop, but prevents dumping huge view-source urls into the history // database. Keep it NDEBUG only because view-source:// URLs are enabled // on NDEBUG builds only. - const GURL& url = last_committed_item->GetURL(); #ifndef NDEBUG + const GURL& url = last_committed_item->GetURL(); if (url.SchemeIs(url::kDataScheme)) { return; } @@ -139,46 +227,8 @@ num_title_changes_ = 0; - history::RedirectList redirects; - const GURL& original_url = last_committed_item->GetOriginalRequestURL(); - const GURL& referrer_url = last_committed_item->GetReferrer().url; - if (original_url != url) { - // Simulate a valid redirect chain in case of URLs that have been modified - // by CRWWebController -finishHistoryNavigationFromEntry:. - if (transition & ui::PAGE_TRANSITION_CLIENT_REDIRECT || - url.EqualsIgnoringRef(original_url)) { - redirects.push_back(referrer_url); - } - // TODO(crbug.com/703872): the redirect chain is not constructed the same - // way as desktop so this part needs to be revised. - redirects.push_back(original_url); - redirects.push_back(url); - } - - // Navigations originating from New Tab Page or Reading List should not - // contribute to Most Visited. - const bool content_suggestions_navigation = - referrer_url == ntp_snippets::GetContentSuggestionsReferrerURL() && - ui::PageTransitionCoreTypeIs(transition, - ui::PAGE_TRANSITION_AUTO_BOOKMARK); - const bool consider_for_ntp_most_visited = - !content_suggestions_navigation && - referrer_url != kReadingListReferrerURL; - - // Hide navigations that result in an error in order to prevent the omnibox - // from suggesting URLs that have never been navigated to successfully. - // (If a navigation to the URL succeeds at some point, the URL will be - // unhidden and thus eligible to be suggested by the omnibox.) - const bool hidden = - (navigation_context->GetResponseHeaders() && - navigation_context->GetResponseHeaders()->response_code() >= 400); - history::HistoryAddPageArgs add_page_args( - url, last_committed_item->GetTimestamp(), this, - last_committed_item->GetUniqueID(), referrer_url, redirects, transition, - hidden, history::SOURCE_BROWSED, - /*did_replace_entry=*/false, consider_for_ntp_most_visited, - navigation_context->IsSameDocument() ? GetPageTitle(*last_committed_item) - : absl::nullopt); + history::HistoryAddPageArgs add_page_args = + CreateHistoryAddPageArgs(last_committed_item, navigation_context); if (delay_notification_) { recorded_navigations_.push_back(std::move(add_page_args));
diff --git a/ios/chrome/browser/history/history_tab_helper_unittest.mm b/ios/chrome/browser/history/history_tab_helper_unittest.mm index 25641e6..5629d9a 100644 --- a/ios/chrome/browser/history/history_tab_helper_unittest.mm +++ b/ios/chrome/browser/history/history_tab_helper_unittest.mm
@@ -16,6 +16,7 @@ #include "ios/chrome/browser/chrome_url_constants.h" #include "ios/chrome/browser/history/history_service_factory.h" #include "ios/web/public/navigation/navigation_item.h" +#import "ios/web/public/test/fakes/fake_navigation_context.h" #include "ios/web/public/test/fakes/fake_web_state.h" #include "testing/gtest/include/gtest/gtest.h" #include "testing/platform_test.h" @@ -224,3 +225,32 @@ QueryURL(file_url); EXPECT_NE(file_url, latest_row_result_.url()); } + +TEST_F(HistoryTabHelperTest, + CreateAddPageArgsPopulatesOnVisitContextAnnotations) { + std::unique_ptr<web::NavigationItem> item = web::NavigationItem::Create(); + GURL test_url("https://www.google.com/"); + item->SetVirtualURL(test_url); + + web::FakeNavigationContext context; + context.SetUrl(test_url); + context.SetHasCommitted(true); + + std::string raw_response_headers = "HTTP/1.1 234 OK\r\n\r\n"; + scoped_refptr<net::HttpResponseHeaders> response_headers = + net::HttpResponseHeaders::TryToCreate(raw_response_headers); + DCHECK(response_headers); + context.SetResponseHeaders(response_headers); + + HistoryTabHelper* helper = HistoryTabHelper::FromWebState(&web_state_); + history::HistoryAddPageArgs args = + helper->CreateHistoryAddPageArgs(item.get(), &context); + + // Make sure the `context_annotations` are populated. + ASSERT_TRUE(args.context_annotations.has_value()); + // Most of the actual fields can't be verified here, because the corresponding + // data sources don't exist in this unit test (e.g. there's no Browser, no + // other TabHelpers, etc). At least check the response code that was set up + // above. + EXPECT_EQ(args.context_annotations->response_code, 234); +}
diff --git a/ios/chrome/browser/signin/gaia_auth_fetcher_ios_ns_url_session_bridge_unittests.mm b/ios/chrome/browser/signin/gaia_auth_fetcher_ios_ns_url_session_bridge_unittests.mm index c515a7f2..59d1481 100644 --- a/ios/chrome/browser/signin/gaia_auth_fetcher_ios_ns_url_session_bridge_unittests.mm +++ b/ios/chrome/browser/signin/gaia_auth_fetcher_ios_ns_url_session_bridge_unittests.mm
@@ -255,12 +255,12 @@ base::RunLoop run_loop; network::mojom::CookieManager* cookie_manager = browser_state_->GetCookieManager(); - cookie_manager->GetAllCookies(base::BindOnce(base::BindLambdaForTesting( + cookie_manager->GetAllCookies(base::BindLambdaForTesting( [&run_loop, &cookies_out](const std::vector<net::CanonicalCookie>& cookies) { cookies_out = cookies; run_loop.Quit(); - }))); + })); run_loop.Run(); return cookies_out;
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1 index 8c41db2..ea88f05 100644 --- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -bb7d940a9f16cb33fda60914080377fb11085242 \ No newline at end of file +3d6357aa82f865a1b81c8c49abd70da252a93fee \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1 index ba1ff02..57a211c 100644 --- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -c641eaf5c32f2e7fc58c60d6da4c7af979ee4bca \ No newline at end of file +a45adacf5ac4ff077ed7ceaf0aafa23099113196 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1 index 10d8f94..c1915db 100644 --- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -0adbef9954b5b97341835c405f78ee3805e99d02 \ No newline at end of file +0d4e34db6094af8ac9187fa25bf57235bc29e476 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1 index de05205..10eddc47 100644 --- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -4d7d8c74f11597ee3a594d24a57fcb3c35015cf1 \ No newline at end of file +76af18ff462523339f57f9d813ba6c7b083d2ca5 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.ios.zip.sha1 index a8e830d..9794124 100644 --- a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -af4787dedcf75002a9c6464a5aebcc46caa612d7 \ No newline at end of file +4161db04f3473b73907b3a38a73d2b1f894bd42a \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.iossimulator.zip.sha1 index 8e882c78..65dd22d6 100644 --- a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -59d7caa8fd003d0785faee7462af5c1c8cc5c539 \ No newline at end of file +155d384d459c905e3c163ac9c4ab24e24a9f606b \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1 index f8b9b1d..ca8a0969 100644 --- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -b3aa412a5a355f2ba81397cd695bfac7dea170c7 \ No newline at end of file +ce1ee4aeb2efca61a14c425f11b73e61600ddd1c \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1 index 7b678e9..c56de4f 100644 --- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -996915948f5561931829716507cc7b887a3e617e \ No newline at end of file +94dd6014750bfcf60a2416b3e3f563b222f46591 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1 index 5356040..4326a760 100644 --- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -3f309a3c81b0849ad40fdde61f6c65a31df49aee \ No newline at end of file +855d0b4e69f2b4ebe4018127b2a328db33718e73 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1 index b709986..d92e063 100644 --- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -970691d5c442ce56b45947fc0b2c4da97e285270 \ No newline at end of file +e358c4caeba91fc48a291d07ada62a2a6ad6795f \ No newline at end of file
diff --git a/media/audio/audio_manager_unittest.cc b/media/audio/audio_manager_unittest.cc index 161ab95f..b9c7fb2 100644 --- a/media/audio/audio_manager_unittest.cc +++ b/media/audio/audio_manager_unittest.cc
@@ -129,18 +129,20 @@ const uint64_t kWebcamMicId = 40003; const uint64_t kWebcamMicStableDeviceId = 90003; -const AudioNode kInternalSpeaker(false, - kInternalSpeakerId, - true, - kInternalSpeakerStableDeviceId, - kInternalSpeakerStableDeviceId ^ 0xFF, - "Internal Speaker", - "INTERNAL_SPEAKER", - "Speaker", - false, - 0, - 2, - 0); +const AudioNode kInternalSpeaker( + false, + kInternalSpeakerId, + true, + kInternalSpeakerStableDeviceId, + kInternalSpeakerStableDeviceId ^ 0xFF, + "Internal Speaker", + "INTERNAL_SPEAKER", + "Speaker", + false, + 0, + 2, + 0, + 25); // output nodes should get a valid number (>0) const AudioNode kInternalMic(true, kInternalMicId, @@ -153,33 +155,38 @@ false, 0, 1, - 1); // EFFECT_TYPE_NOISE_CANCELLATION + 1, // EFFECT_TYPE_NOISE_CANCELLATION + 0); // input nodes this value is invalid (0) -const AudioNode kJabraSpeaker1(false, - kJabraSpeaker1Id, - true, - kJabraSpeaker1StableDeviceId, - kJabraSpeaker1StableDeviceId ^ 0xFF, - "Jabra Speaker", - "USB", - "Jabra Speaker 1", - false, - 0, - 2, // expects CHANNEL_LAYOUT_STEREO - 0); +const AudioNode kJabraSpeaker1( + false, + kJabraSpeaker1Id, + true, + kJabraSpeaker1StableDeviceId, + kJabraSpeaker1StableDeviceId ^ 0xFF, + "Jabra Speaker", + "USB", + "Jabra Speaker 1", + false, + 0, + 2, // expects CHANNEL_LAYOUT_STEREO + 0, + 25); // output nodes should get a valid number (>0) -const AudioNode kJabraSpeaker2(false, - kJabraSpeaker2Id, - true, - kJabraSpeaker2StableDeviceId, - kJabraSpeaker2StableDeviceId ^ 0xFF, - "Jabra Speaker", - "USB", - "Jabra Speaker 2", - false, - 0, - 6, // expects CHANNEL_LAYOUT_5_1 - 0); +const AudioNode kJabraSpeaker2( + false, + kJabraSpeaker2Id, + true, + kJabraSpeaker2StableDeviceId, + kJabraSpeaker2StableDeviceId ^ 0xFF, + "Jabra Speaker", + "USB", + "Jabra Speaker 2", + false, + 0, + 6, // expects CHANNEL_LAYOUT_5_1 + 0, + 25); // output nodes should get a valid number (>0) const AudioNode kHDMIOutput(false, kHDMIOutputId, @@ -192,7 +199,8 @@ false, 0, 8, // expects CHANNEL_LAYOUT_7_1 - 0); + 0, + 25); // output nodes should get a valid number (>0) const AudioNode kJabraMic1(true, kJabraMic1Id, @@ -205,7 +213,8 @@ false, 0, 1, - 0); + 0, + 0); // input nodes this value is invalid (0) const AudioNode kJabraMic2(true, kJabraMic2Id, @@ -218,7 +227,8 @@ false, 0, 1, - 0); + 0, + 0); // input nodes this value is invalid (0) const AudioNode kUSBCameraMic(true, kWebcamMicId, @@ -231,7 +241,8 @@ false, 0, 1, - 0); + 0, + 0); // input nodes this value is invalid (0) #endif // defined(USE_CRAS) const char kRealDefaultInputDeviceID[] = "input2";
diff --git a/media/base/key_systems.cc b/media/base/key_systems.cc index 0b27e769..d44316d 100644 --- a/media/base/key_systems.cc +++ b/media/base/key_systems.cc
@@ -320,8 +320,6 @@ private: friend class base::NoDestructor<KeySystemsImpl>; - using KeySystemPropertiesMap = - std::unordered_map<std::string, std::unique_ptr<KeySystemProperties>>; using MimeTypeToCodecsMap = std::unordered_map<std::string, SupportedCodecs>; using CodecMap = std::unordered_map<std::string, EmeCodec>; using InitDataTypesMap = std::unordered_map<std::string, EmeInitDataType>; @@ -357,8 +355,8 @@ // Pending callbacks for UpdateIfNeeded() calls. base::OnceClosureList update_callbacks_; - // Map from key system string to KeySystemProperties instance. - KeySystemPropertiesMap key_system_properties_map_; + // Vector of KeySystemProperties . + KeySystemPropertiesVector key_system_properties_vector_; // This member should only be modified by RegisterMimeType(). MimeTypeToCodecsMap mime_type_to_codecs_map_; @@ -488,8 +486,8 @@ KeySystemPropertiesVector key_systems) { DCHECK(thread_checker_.CalledOnValidThread()); - // Clear `key_system_properties_map_` before we repopulating it. - key_system_properties_map_.clear(); + // Clear `key_system_properties_vector_` before repopulating it. + key_system_properties_vector_.clear(); for (auto& properties : key_systems) { DCHECK(!properties->GetBaseKeySystemName().empty()); @@ -520,23 +518,20 @@ } const auto base_key_system_name = properties->GetBaseKeySystemName(); - DCHECK(!key_system_properties_map_.count(base_key_system_name)) - << "Key system '" << base_key_system_name << "' already registered"; DVLOG(1) << __func__ << ": Adding key system " << base_key_system_name; - key_system_properties_map_[base_key_system_name] = std::move(properties); + key_system_properties_vector_.push_back(std::move(properties)); } } const KeySystemProperties* KeySystemsImpl::GetKeySystemProperties( const std::string& key_system) const { DCHECK(!is_updating_); - for (const auto& entry : key_system_properties_map_) { - const auto& base_key_system = entry.first; - const auto* properties = entry.second.get(); + for (const auto& key_system_properties : key_system_properties_vector_) { + const auto& base_key_system = key_system_properties->GetBaseKeySystemName(); if ((key_system == base_key_system || IsSubKeySystemOf(key_system, base_key_system)) && - properties->IsSupportedKeySystem(key_system)) { - return properties; + key_system_properties->IsSupportedKeySystem(key_system)) { + return key_system_properties.get(); } }
diff --git a/media/base/win/hresults.h b/media/base/win/hresults.h index c355052..038ae8a 100644 --- a/media/base/win/hresults.h +++ b/media/base/win/hresults.h
@@ -21,6 +21,14 @@ MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0xFA02); constexpr HRESULT kErrorCdmProxyReceivedInInvalidState = MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0xFA03); +constexpr HRESULT kErrorResolveCoreWinRTStringDelayload = + MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0xFA04); +constexpr HRESULT kErrorZeroProtectionSystemId = + MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0xFA05); +constexpr HRESULT kErrorLoadLibrary = + MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0xFA06); +constexpr HRESULT kErrorGetFunctionPointer = + MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0xFA07); } // namespace media
diff --git a/media/base/win/media_foundation_cdm_proxy.h b/media/base/win/media_foundation_cdm_proxy.h index 36831e9..d56a1e7 100644 --- a/media/base/win/media_foundation_cdm_proxy.h +++ b/media/base/win/media_foundation_cdm_proxy.h
@@ -64,7 +64,7 @@ virtual void OnSignificantPlayback() = 0; // Notify the CDM that playback error happened. - virtual void OnPlaybackError() = 0; + virtual void OnPlaybackError(HRESULT hresult) = 0; protected: friend base::RefCountedThreadSafe<MediaFoundationCdmProxy>;
diff --git a/media/capture/video/chromeos/video_capture_features_chromeos.cc b/media/capture/video/chromeos/video_capture_features_chromeos.cc index 1d0ec3d..319016b 100644 --- a/media/capture/video/chromeos/video_capture_features_chromeos.cc +++ b/media/capture/video/chromeos/video_capture_features_chromeos.cc
@@ -32,7 +32,7 @@ // TODO(pihsun): Migrate the flag to use base::Feature. std::string value = command_line->GetSwitchValueASCII(media::switches::kAutoFramingOverride); - return value == media::switches::kAutoFramingForceEnabled; + return value != media::switches::kAutoFramingForceDisabled; } } // namespace media
diff --git a/media/cdm/cdm_auxiliary_helper.cc b/media/cdm/cdm_auxiliary_helper.cc index 2679b81..7bc3f403 100644 --- a/media/cdm/cdm_auxiliary_helper.cc +++ b/media/cdm/cdm_auxiliary_helper.cc
@@ -65,7 +65,7 @@ void CdmAuxiliaryHelper::SetCdmClientToken( const std::vector<uint8_t>& client_token) {} -void CdmAuxiliaryHelper::OnCdmEvent(CdmEvent event) {} +void CdmAuxiliaryHelper::OnCdmEvent(CdmEvent event, HRESULT hresult) {} #endif // BUILDFLAG(IS_WIN) } // namespace media
diff --git a/media/cdm/cdm_auxiliary_helper.h b/media/cdm/cdm_auxiliary_helper.h index ee35db8..ee903d3 100644 --- a/media/cdm/cdm_auxiliary_helper.h +++ b/media/cdm/cdm_auxiliary_helper.h
@@ -72,7 +72,7 @@ #if BUILDFLAG(IS_WIN) void GetMediaFoundationCdmData(GetMediaFoundationCdmDataCB callback) override; void SetCdmClientToken(const std::vector<uint8_t>& client_token) override; - void OnCdmEvent(CdmEvent event) override; + void OnCdmEvent(CdmEvent event, HRESULT hresult) override; #endif // BUILDFLAG(IS_WIN) };
diff --git a/media/cdm/cdm_document_service.h b/media/cdm/cdm_document_service.h index 43a290b..dbeb4c3 100644 --- a/media/cdm/cdm_document_service.h +++ b/media/cdm/cdm_document_service.h
@@ -84,8 +84,9 @@ virtual void SetCdmClientToken(const std::vector<uint8_t>& client_token) = 0; // Reports a CDM event. This can be used for metrics reporting or fallback - // logic, e.g. disable the CDM in the current robustness level. - virtual void OnCdmEvent(CdmEvent event) = 0; + // logic, e.g. disable the CDM in the current robustness level. For error + // events, the `hresult` provides more details about the error. + virtual void OnCdmEvent(CdmEvent event, HRESULT hresult) = 0; #endif // BUILDFLAG(IS_WIN) };
diff --git a/media/cdm/win/media_foundation_cdm.cc b/media/cdm/win/media_foundation_cdm.cc index b6d84c2..3b0a4b3 100644 --- a/media/cdm/win/media_foundation_cdm.cc +++ b/media/cdm/win/media_foundation_cdm.cc
@@ -18,6 +18,7 @@ #include "base/win/win_util.h" #include "base/win/windows_version.h" #include "media/base/cdm_promise.h" +#include "media/base/win/hresults.h" #include "media/base/win/media_foundation_cdm_proxy.h" #include "media/base/win/mf_helpers.h" #include "media/cdm/win/media_foundation_cdm_module.h" @@ -219,11 +220,11 @@ } void OnSignificantPlayback() override { - cdm_event_cb_.Run(CdmEvent::kSignificantPlayback); + cdm_event_cb_.Run(CdmEvent::kSignificantPlayback, S_OK); } - void OnPlaybackError() override { - cdm_event_cb_.Run(CdmEvent::kPlaybackError); + void OnPlaybackError(HRESULT hresult) override { + cdm_event_cb_.Run(CdmEvent::kPlaybackError, hresult); } private: @@ -237,7 +238,7 @@ RETURN_IF_FAILED( mf_cdm_->GetProtectionSystemIds(&protection_system_ids, &count)); if (count == 0) - return E_FAIL; + return kErrorZeroProtectionSystemId; *protection_system_id = *protection_system_ids; DVLOG(2) << __func__ << " protection_system_id=" @@ -314,7 +315,7 @@ // Only report CdmEvent::kCdmError here as this is where most failures // happen, and other errors can be easily triggered by sites, e.g. a bad // server certificate or a bad license. - OnCdmEvent(CdmEvent::kCdmError); + OnCdmEvent(CdmEvent::kCdmError, hresult); return hresult; } @@ -618,9 +619,9 @@ } } -void MediaFoundationCdm::OnCdmEvent(CdmEvent event) { +void MediaFoundationCdm::OnCdmEvent(CdmEvent event, HRESULT hresult) { DVLOG_FUNC(1); - cdm_event_cb_.Run(event); + cdm_event_cb_.Run(event, hresult); } void MediaFoundationCdm::OnIsTypeSupportedResult(
diff --git a/media/cdm/win/media_foundation_cdm.h b/media/cdm/win/media_foundation_cdm.h index f2e41c7..7f232239 100644 --- a/media/cdm/win/media_foundation_cdm.h +++ b/media/cdm/win/media_foundation_cdm.h
@@ -66,7 +66,9 @@ using StoreClientTokenCB = base::RepeatingCallback<void(const std::vector<uint8_t>&)>; - using CdmEventCB = base::RepeatingCallback<void(CdmEvent)>; + // Callback to notify the CDM of an event, with an optional HRESULT associated + // with that event (e.g. errors). + using CdmEventCB = base::RepeatingCallback<void(CdmEvent, HRESULT hresult)>; // Constructs `MediaFoundationCdm`. Note that `Initialize()` must be called // before calling any other methods. @@ -133,7 +135,7 @@ void OnHardwareContextReset(); // Called when CdmEvent happens. - void OnCdmEvent(CdmEvent event); + void OnCdmEvent(CdmEvent event, HRESULT hresult); // Called when IsTypeSupported() result is available. void OnIsTypeSupportedResult(std::unique_ptr<KeyStatusCdmPromise> promise,
diff --git a/media/cdm/win/media_foundation_cdm_factory.cc b/media/cdm/win/media_foundation_cdm_factory.cc index a9a53d7..f1a0374 100644 --- a/media/cdm/win/media_foundation_cdm_factory.cc +++ b/media/cdm/win/media_foundation_cdm_factory.cc
@@ -150,9 +150,7 @@ auto itr = create_cdm_factory_cbs_for_testing_.find(key_system); if (itr != create_cdm_factory_cbs_for_testing_.end()) { auto& create_cdm_factory_cb = itr->second; - if (!create_cdm_factory_cb) - return E_FAIL; - + DCHECK(create_cdm_factory_cb); RETURN_IF_FAILED(create_cdm_factory_cb.Run(cdm_factory)); return S_OK; } @@ -189,8 +187,8 @@ helper_->SetCdmClientToken(client_token); } -void MediaFoundationCdmFactory::OnCdmEvent(CdmEvent event) { - helper_->OnCdmEvent(event); +void MediaFoundationCdmFactory::OnCdmEvent(CdmEvent event, HRESULT hresult) { + helper_->OnCdmEvent(event, hresult); } void MediaFoundationCdmFactory::CreateMfCdm(
diff --git a/media/cdm/win/media_foundation_cdm_factory.h b/media/cdm/win/media_foundation_cdm_factory.h index 0fdf38b..3bca73f 100644 --- a/media/cdm/win/media_foundation_cdm_factory.h +++ b/media/cdm/win/media_foundation_cdm_factory.h
@@ -70,7 +70,7 @@ IsTypeSupportedResultCB is_type_supported_result_cb); void StoreClientToken(const std::vector<uint8_t>& client_token); - void OnCdmEvent(CdmEvent event); + void OnCdmEvent(CdmEvent event, HRESULT hresult); // Creates `mf_cdm` based on the input parameters. Same as // CreateMediaFoundationCdm() but returns the HRESULT in out parameter so we
diff --git a/media/cdm/win/media_foundation_cdm_module.cc b/media/cdm/win/media_foundation_cdm_module.cc index b633095..10e0c6c 100644 --- a/media/cdm/win/media_foundation_cdm_module.cc +++ b/media/cdm/win/media_foundation_cdm_module.cc
@@ -8,6 +8,7 @@ #include "base/logging.h" #include "base/strings/utf_string_conversions.h" #include "base/win/scoped_hstring.h" +#include "media/base/win/hresults.h" #include "media/base/win/mf_helpers.h" namespace media { @@ -94,12 +95,12 @@ if (!library_.is_valid()) { LOG(ERROR) << "CDM failed to load previously"; - return E_FAIL; + return kErrorLoadLibrary; } // Initialization required to call base::win::ScopedHString::Create(); if (!base::win::ScopedHString::ResolveCoreWinRTStringDelayload()) - return E_FAIL; + return kErrorResolveCoreWinRTStringDelayload; // Get function pointer to the activation factory. using GetActivationFactoryFunc = @@ -110,7 +111,7 @@ library_.GetFunctionPointer(kDllGetActivationFactory)); if (!get_activation_factory_func) { LOG(ERROR) << "Cannot get function " << kDllGetActivationFactory; - return E_FAIL; + return kErrorGetFunctionPointer; } // Activate CdmFactory. Assuming the class ID is always in the format
diff --git a/media/cdm/win/media_foundation_cdm_unittest.cc b/media/cdm/win/media_foundation_cdm_unittest.cc index c5749fdf..90e99244 100644 --- a/media/cdm/win/media_foundation_cdm_unittest.cc +++ b/media/cdm/win/media_foundation_cdm_unittest.cc
@@ -94,7 +94,7 @@ void InitializeAndExpectFailure() { can_initialize_ = false; - EXPECT_CALL(cdm_event_cb_, Run(CdmEvent::kCdmError)); + EXPECT_CALL(cdm_event_cb_, Run(CdmEvent::kCdmError, E_FAIL)); ASSERT_FAILED(cdm_->Initialize()); } @@ -512,7 +512,7 @@ // Make the next `Initialize()` fail. can_initialize_ = false; - EXPECT_CALL(cdm_event_cb_, Run(CdmEvent::kCdmError)); + EXPECT_CALL(cdm_event_cb_, Run(CdmEvent::kCdmError, E_FAIL)); COM_EXPECT_CALL(mf_cdm_session_, Close()).WillOnce(Return(S_OK)); EXPECT_CALL(cdm_client_,
diff --git a/media/gpu/gpu_video_encode_accelerator_factory.cc b/media/gpu/gpu_video_encode_accelerator_factory.cc index 84fc572..381126f1 100644 --- a/media/gpu/gpu_video_encode_accelerator_factory.cc +++ b/media/gpu/gpu_video_encode_accelerator_factory.cc
@@ -137,8 +137,7 @@ VideoEncodeAccelerator::SupportedProfiles GetSupportedProfilesInternal( const gpu::GpuPreferences& gpu_preferences, const gpu::GpuDriverBugWorkarounds& gpu_workarounds, - const gpu::GPUInfo::GPUDevice& gpu_device, - bool populate_extended_info) { + const gpu::GPUInfo::GPUDevice& gpu_device) { if (gpu_preferences.disable_accelerated_video_encode) return VideoEncodeAccelerator::SupportedProfiles(); @@ -148,9 +147,7 @@ auto vea = std::move(create_vea).Run(); if (!vea) continue; - auto vea_profiles = populate_extended_info - ? vea->GetSupportedProfiles() - : vea->GetSupportedProfilesLight(); + auto vea_profiles = vea->GetSupportedProfiles(); GpuVideoAcceleratorUtil::InsertUniqueEncodeProfiles(vea_profiles, &profiles); } @@ -192,22 +189,12 @@ GpuVideoEncodeAcceleratorFactory::GetSupportedProfiles( const gpu::GpuPreferences& gpu_preferences, const gpu::GpuDriverBugWorkarounds& gpu_workarounds, - const gpu::GPUInfo::GPUDevice& gpu_device, - bool populate_extended_info) { + const gpu::GPUInfo::GPUDevice& gpu_device) { // Cache the supported profiles so that they will not be computed more than // once per GPU process. It is assumed that |gpu_preferences| do not change // between calls. - VideoEncodeAccelerator::SupportedProfiles* profiles_ptr = nullptr; - if (populate_extended_info) { - static auto profiles = GetSupportedProfilesInternal( - gpu_preferences, gpu_workarounds, gpu_device, true); - profiles_ptr = &profiles; - - } else { - static auto profiles = GetSupportedProfilesInternal( - gpu_preferences, gpu_workarounds, gpu_device, false); - profiles_ptr = &profiles; - } + static auto profiles = GetSupportedProfilesInternal( + gpu_preferences, gpu_workarounds, gpu_device); #if BUILDFLAG(USE_V4L2_CODEC) // V4L2-only: the encoder devices may not be visible at the time the GPU @@ -215,39 +202,38 @@ // devices again in the hope that they will have appeared in the meantime. // TODO(crbug.com/948147): trigger query when an device add/remove event // (e.g. via udev) has happened instead. - if (profiles_ptr->empty()) { + if (profiles.empty()) { VLOGF(1) << "Supported profiles empty, querying again..."; - *profiles_ptr = GetSupportedProfilesInternal( - gpu_preferences, gpu_workarounds, gpu_device, populate_extended_info); + profiles = GetSupportedProfilesInternal(gpu_preferences, gpu_workarounds, gpu_device); } #endif if (gpu_workarounds.disable_accelerated_vp8_encode) { - base::EraseIf(*profiles_ptr, [](const auto& vea_profile) { + base::EraseIf(profiles, [](const auto& vea_profile) { return vea_profile.profile == VP8PROFILE_ANY; }); } if (gpu_workarounds.disable_accelerated_vp9_encode) { - base::EraseIf(*profiles_ptr, [](const auto& vea_profile) { + base::EraseIf(profiles, [](const auto& vea_profile) { return vea_profile.profile >= VP9PROFILE_PROFILE0 && vea_profile.profile <= VP9PROFILE_PROFILE3; }); } if (gpu_workarounds.disable_accelerated_h264_encode) { - base::EraseIf(*profiles_ptr, [](const auto& vea_profile) { + base::EraseIf(profiles, [](const auto& vea_profile) { return vea_profile.profile >= H264PROFILE_MIN && vea_profile.profile <= H264PROFILE_MAX; }); } - base::EraseIf(*profiles_ptr, [](const auto& vea_profile) { + base::EraseIf(profiles, [](const auto& vea_profile) { return vea_profile.profile >= HEVCPROFILE_MIN && vea_profile.profile <= HEVCPROFILE_MAX; }); - return *profiles_ptr; + return profiles; } } // namespace media
diff --git a/media/gpu/gpu_video_encode_accelerator_factory.h b/media/gpu/gpu_video_encode_accelerator_factory.h index 87d487ce..bcf7ccf 100644 --- a/media/gpu/gpu_video_encode_accelerator_factory.h +++ b/media/gpu/gpu_video_encode_accelerator_factory.h
@@ -38,13 +38,10 @@ std::unique_ptr<MediaLog> media_log = nullptr); // Gets the supported codec profiles for video encoding on the platform. - // If |populate_extended_info| it false, this function will only populate: - // codec, framerate range and resolution range. It's faster. static VideoEncodeAccelerator::SupportedProfiles GetSupportedProfiles( const gpu::GpuPreferences& gpu_preferences, const gpu::GpuDriverBugWorkarounds& gpu_workarounds, - const gpu::GPUInfo::GPUDevice& gpu_device, - bool populate_extended_info = true); + const gpu::GPUInfo::GPUDevice& gpu_device); }; } // namespace media
diff --git a/media/gpu/mac/vt_video_encode_accelerator_mac.cc b/media/gpu/mac/vt_video_encode_accelerator_mac.cc index 965e398..2b6077b 100644 --- a/media/gpu/mac/vt_video_encode_accelerator_mac.cc +++ b/media/gpu/mac/vt_video_encode_accelerator_mac.cc
@@ -162,26 +162,6 @@ return profiles; } -VideoEncodeAccelerator::SupportedProfiles -VTVideoEncodeAccelerator::GetSupportedProfilesLight() { - DVLOG(3) << __func__; - DCHECK_CALLED_ON_VALID_SEQUENCE(client_sequence_checker_); - - SupportedProfiles profiles; - - SupportedProfile profile; - profile.max_framerate_numerator = kMaxFrameRateNumerator; - profile.max_framerate_denominator = kMaxFrameRateDenominator; - profile.rate_control_modes = VideoEncodeAccelerator::kConstantMode | - VideoEncodeAccelerator::kVariableMode; - profile.max_resolution = gfx::Size(kMaxResolutionWidth, kMaxResolutionHeight); - for (const auto& supported_profile : kSupportedProfiles) { - profile.profile = supported_profile; - profiles.push_back(profile); - } - return profiles; -} - bool VTVideoEncodeAccelerator::Initialize(const Config& config, Client* client, std::unique_ptr<MediaLog> media_log) {
diff --git a/media/gpu/mac/vt_video_encode_accelerator_mac.h b/media/gpu/mac/vt_video_encode_accelerator_mac.h index 7c69134..06dc276 100644 --- a/media/gpu/mac/vt_video_encode_accelerator_mac.h +++ b/media/gpu/mac/vt_video_encode_accelerator_mac.h
@@ -37,8 +37,6 @@ // VideoEncodeAccelerator implementation. VideoEncodeAccelerator::SupportedProfiles GetSupportedProfiles() override; - VideoEncodeAccelerator::SupportedProfiles GetSupportedProfilesLight() - override; bool Initialize(const Config& config, Client* client,
diff --git a/media/gpu/windows/media_foundation_video_encode_accelerator_win.cc b/media/gpu/windows/media_foundation_video_encode_accelerator_win.cc index 11f55d5..bcf878a 100644 --- a/media/gpu/windows/media_foundation_video_encode_accelerator_win.cc +++ b/media/gpu/windows/media_foundation_video_encode_accelerator_win.cc
@@ -315,26 +315,7 @@ SupportedProfiles profiles; for (auto codec : {VideoCodec::kH264, VideoCodec::kVP9, VideoCodec::kAV1}) { - auto codec_profiles = GetSupportedProfilesForCodec(codec, true); - profiles.insert(profiles.end(), codec_profiles.begin(), - codec_profiles.end()); - } - - ReleaseEncoderResources(); - return profiles; -} - -VideoEncodeAccelerator::SupportedProfiles -MediaFoundationVideoEncodeAccelerator::GetSupportedProfilesLight() { - TRACE_EVENT0( - "gpu,startup", - "MediaFoundationVideoEncodeAccelerator::GetSupportedProfilesLight"); - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - - SupportedProfiles profiles; - - for (auto codec : {VideoCodec::kH264, VideoCodec::kVP9, VideoCodec::kAV1}) { - auto codec_profiles = GetSupportedProfilesForCodec(codec, false); + auto codec_profiles = GetSupportedProfilesForCodec(codec); profiles.insert(profiles.end(), codec_profiles.begin(), codec_profiles.end()); } @@ -345,8 +326,7 @@ VideoEncodeAccelerator::SupportedProfiles MediaFoundationVideoEncodeAccelerator::GetSupportedProfilesForCodec( - VideoCodec codec, - bool populate_svc_info) { + VideoCodec codec) { SupportedProfiles profiles; if ((codec == VideoCodec::kVP9 && !base::FeatureList::IsEnabled(kMediaFoundationVP9Encoding)) || @@ -368,10 +348,8 @@ if (pp_activate) { for (UINT32 i = 0; i < encoder_count; i++) { if (pp_activate[i]) { - if (populate_svc_info && !svc_supported && - IsSvcSupported(pp_activate[i])) { + if (!svc_supported && IsSvcSupported(pp_activate[i])) svc_supported = true; - } // Release the enumerated instances if any. // According to Windows Dev Center,
diff --git a/media/gpu/windows/media_foundation_video_encode_accelerator_win.h b/media/gpu/windows/media_foundation_video_encode_accelerator_win.h index be7dd3a..c4bb0b6 100644 --- a/media/gpu/windows/media_foundation_video_encode_accelerator_win.h +++ b/media/gpu/windows/media_foundation_video_encode_accelerator_win.h
@@ -52,8 +52,6 @@ // VideoEncodeAccelerator implementation. VideoEncodeAccelerator::SupportedProfiles GetSupportedProfiles() override; - VideoEncodeAccelerator::SupportedProfiles GetSupportedProfilesLight() - override; bool Initialize(const Config& config, Client* client, std::unique_ptr<MediaLog> media_log) override; @@ -82,8 +80,7 @@ // Get supported profiles for specific codec. VideoEncodeAccelerator::SupportedProfiles GetSupportedProfilesForCodec( - VideoCodec codec, - bool populate_svc_info); + VideoCodec codec); // Activates the asynchronous encoder instance |encoder_| according to codec // merit.
diff --git a/media/mojo/clients/mojo_video_encode_accelerator.cc b/media/mojo/clients/mojo_video_encode_accelerator.cc index 5f03572..6a3fd9ba 100644 --- a/media/mojo/clients/mojo_video_encode_accelerator.cc +++ b/media/mojo/clients/mojo_video_encode_accelerator.cc
@@ -163,29 +163,45 @@ DCHECK_EQ(num_planes, frame->layout().num_planes()); DCHECK(vea_.is_bound()); - // GPU memory path: Pass-through. - if (frame->storage_type() == VideoFrame::STORAGE_GPU_MEMORY_BUFFER) { - vea_->Encode(frame, force_keyframe, - base::BindOnce([](scoped_refptr<VideoFrame>) {}, frame)); - return; - } - - // Mappable memory path: Copy buffer to shared memory. if (frame->format() != PIXEL_FORMAT_I420 && frame->format() != PIXEL_FORMAT_NV12) { DLOG(ERROR) << "Unexpected pixel format: " << VideoPixelFormatToString(frame->format()); return; } - if (frame->storage_type() != VideoFrame::STORAGE_SHMEM && - frame->storage_type() != VideoFrame::STORAGE_UNOWNED_MEMORY) { - DLOG(ERROR) << "Unexpected storage type: " - << VideoFrame::StorageTypeToString(frame->storage_type()); - return; + + scoped_refptr<VideoFrame> mojo_frame; + switch (frame->storage_type()) { + case VideoFrame::VideoFrame::STORAGE_GPU_MEMORY_BUFFER: + // GPU memory path: Pass-through. + mojo_frame = frame; + break; + case VideoFrame::STORAGE_SHMEM: { + size_t num_planes = VideoFrame::NumPlanes(frame->format()); + std::vector<uint32_t> offsets(num_planes); + std::vector<int32_t> strides(num_planes); + for (size_t i = 0; i < num_planes; ++i) { + strides[i] = frame->stride(i); + // This offset computation is safe because the planes are in the single + // buffer, a single SharedMemoryBuffer. The first plane data must lie + // in the beginning of the buffer. + offsets[i] = + base::saturated_cast<uint32_t>(frame->data(i) - frame->data(0)); + } + mojo_frame = MojoSharedBufferVideoFrame::Create( + frame->format(), frame->coded_size(), frame->visible_rect(), + frame->natural_size(), frame->shm_region()->Duplicate(), offsets, + strides, frame->timestamp()); + } break; + case VideoFrame::STORAGE_UNOWNED_MEMORY: + mojo_frame = MojoSharedBufferVideoFrame::CreateFromYUVFrame(*frame); + break; + default: + DLOG(ERROR) << "Unexpected storage type: " + << VideoFrame::StorageTypeToString(frame->storage_type()); + return; } - scoped_refptr<MojoSharedBufferVideoFrame> mojo_frame = - MojoSharedBufferVideoFrame::CreateFromYUVFrame(*frame); if (!mojo_frame) { DLOG(ERROR) << "Failed creating MojoSharedBufferVideoFrame from YUV"; return;
diff --git a/media/mojo/common/mojo_shared_buffer_video_frame.cc b/media/mojo/common/mojo_shared_buffer_video_frame.cc index a51bf68..ba26678 100644 --- a/media/mojo/common/mojo_shared_buffer_video_frame.cc +++ b/media/mojo/common/mojo_shared_buffer_video_frame.cc
@@ -82,6 +82,8 @@ scoped_refptr<MojoSharedBufferVideoFrame> MojoSharedBufferVideoFrame::CreateFromYUVFrame(VideoFrame& frame) { + // Use Create() for STORAGE_SHMEM VideoFrame. + DCHECK_NE(frame.storage_type(), VideoFrame::STORAGE_SHMEM); size_t num_planes = VideoFrame::NumPlanes(frame.format()); DCHECK_LE(num_planes, 3u); DCHECK_GE(num_planes, 2u); @@ -238,7 +240,7 @@ MojoSharedBufferVideoFrame::~MojoSharedBufferVideoFrame() = default; bool MojoSharedBufferVideoFrame::Init(base::span<const uint32_t> offsets) { - // TODO(hiroh): Don't map in a client side when sending + // TODO(b/241362231): Don't map in a client side when sending // MojoSharedBufferVideoFrame to a service process. DCHECK(!mapping_.IsValid()); mapping_ = region_.Map();
diff --git a/media/mojo/common/mojo_shared_buffer_video_frame_unittest.cc b/media/mojo/common/mojo_shared_buffer_video_frame_unittest.cc index 4f26314f..8755fe0 100644 --- a/media/mojo/common/mojo_shared_buffer_video_frame_unittest.cc +++ b/media/mojo/common/mojo_shared_buffer_video_frame_unittest.cc
@@ -319,17 +319,27 @@ data + 4, data + 8, base::TimeDelta()); frame->BackWithSharedMemory(&mapped_region.region); - auto mojo_frame = MojoSharedBufferVideoFrame::CreateFromYUVFrame(*frame); + size_t num_planes = VideoFrame::NumPlanes(frame->format()); + std::vector<uint32_t> offsets(num_planes); + std::vector<int32_t> strides(num_planes); + for (size_t i = 0; i < num_planes; ++i) { + strides[i] = frame->stride(i); + offsets[i] = + base::saturated_cast<uint32_t>(frame->data(i) - frame->data(0)); + } + + auto mojo_frame = MojoSharedBufferVideoFrame::Create( + frame->format(), frame->coded_size(), frame->visible_rect(), + frame->natural_size(), frame->shm_region()->Duplicate(), offsets, strides, + frame->timestamp()); EXPECT_TRUE(mojo_frame); - const size_t y_stride = frame->stride(VideoFrame::kYPlane); - const size_t u_stride = frame->stride(VideoFrame::kUPlane); - - // Verifies mapped size and offset. - EXPECT_EQ(mojo_frame->shmem_region().GetSize(), - static_cast<size_t>(3 * stride)); - EXPECT_EQ(mojo_frame->PlaneOffset(VideoFrame::kYPlane), 0u); - EXPECT_EQ(mojo_frame->PlaneOffset(VideoFrame::kUPlane), y_stride); - EXPECT_EQ(mojo_frame->PlaneOffset(VideoFrame::kVPlane), y_stride + u_stride); + EXPECT_EQ(mojo_frame->shmem_region().GetSize(), kAllocationSize); + EXPECT_EQ(mojo_frame->PlaneOffset(VideoFrame::kYPlane), + offsets[VideoFrame::kYPlane]); + EXPECT_EQ(mojo_frame->PlaneOffset(VideoFrame::kUPlane), + offsets[VideoFrame::kUPlane]); + EXPECT_EQ(mojo_frame->PlaneOffset(VideoFrame::kVPlane), + offsets[VideoFrame::kVPlane]); } } // namespace media
diff --git a/media/mojo/mojom/cdm_document_service.mojom b/media/mojo/mojom/cdm_document_service.mojom index f20e58de..4114f0d 100644 --- a/media/mojo/mojom/cdm_document_service.mojom +++ b/media/mojo/mojom/cdm_document_service.mojom
@@ -73,7 +73,8 @@ SetCdmClientToken(array<uint8> client_token); // Reports a CDM event, which can facilitate metrics reporting or fallback - // logic. + // logic. For error events, the `hresult` provides more details about the + // error. [EnableIf=is_win] - OnCdmEvent(CdmEvent event); + OnCdmEvent(CdmEvent event, uint32 hresult); };
diff --git a/media/mojo/services/mojo_cdm_helper.cc b/media/mojo/services/mojo_cdm_helper.cc index cec5821e..a1e1501 100644 --- a/media/mojo/services/mojo_cdm_helper.cc +++ b/media/mojo/services/mojo_cdm_helper.cc
@@ -64,9 +64,9 @@ cdm_document_service_->SetCdmClientToken(client_token); } -void MojoCdmHelper::OnCdmEvent(CdmEvent event) { +void MojoCdmHelper::OnCdmEvent(CdmEvent event, HRESULT hresult) { ConnectToCdmDocumentService(); - cdm_document_service_->OnCdmEvent(event); + cdm_document_service_->OnCdmEvent(event, hresult); } #endif // BUILDFLAG(IS_WIN)
diff --git a/media/mojo/services/mojo_cdm_helper.h b/media/mojo/services/mojo_cdm_helper.h index 97e3a0a..f9c9a3a 100644 --- a/media/mojo/services/mojo_cdm_helper.h +++ b/media/mojo/services/mojo_cdm_helper.h
@@ -51,7 +51,7 @@ #if BUILDFLAG(IS_WIN) void GetMediaFoundationCdmData(GetMediaFoundationCdmDataCB callback) final; void SetCdmClientToken(const std::vector<uint8_t>& client_token) final; - void OnCdmEvent(CdmEvent event) final; + void OnCdmEvent(CdmEvent event, HRESULT hresult) final; #endif // BUILDFLAG(IS_WIN) // MojoCdmFileIO::Delegate implementation.
diff --git a/media/renderers/win/media_foundation_protection_manager.cc b/media/renderers/win/media_foundation_protection_manager.cc index d9c7b08..c4c63e1 100644 --- a/media/renderers/win/media_foundation_protection_manager.cc +++ b/media/renderers/win/media_foundation_protection_manager.cc
@@ -14,6 +14,7 @@ #include "base/win/core_winrt_util.h" #include "base/win/scoped_hstring.h" #include "base/win/windows_types.h" +#include "media/base/win/hresults.h" #include "media/base/win/mf_helpers.h" namespace media { @@ -37,7 +38,7 @@ waiting_cb_ = std::move(waiting_cb); if (!base::win::ScopedHString::ResolveCoreWinRTStringDelayload()) - return E_FAIL; + return kErrorResolveCoreWinRTStringDelayload; // Init an empty |property_set_| as MFMediaEngine could access it via // |get_Properties| before we populate it within SetPMPServer.
diff --git a/media/renderers/win/media_foundation_renderer.cc b/media/renderers/win/media_foundation_renderer.cc index 991186e5..a02877b1 100644 --- a/media/renderers/win/media_foundation_renderer.cc +++ b/media/renderers/win/media_foundation_renderer.cc
@@ -954,7 +954,7 @@ if (cdm_proxy_) cdm_proxy_->OnHardwareContextReset(); } else if (cdm_proxy_) { - cdm_proxy_->OnPlaybackError(); + cdm_proxy_->OnPlaybackError(hresult); } // Attach hresult to `new_status` for logging and metrics reporting.
diff --git a/media/renderers/win/media_foundation_renderer_unittest.cc b/media/renderers/win/media_foundation_renderer_unittest.cc index 51a86a5..9193f55 100644 --- a/media/renderers/win/media_foundation_renderer_unittest.cc +++ b/media/renderers/win/media_foundation_renderer_unittest.cc
@@ -53,7 +53,7 @@ HRESULT(IUnknown* request, IMFAsyncResult* result)); MOCK_METHOD0(OnHardwareContextReset, void()); MOCK_METHOD0(OnSignificantPlayback, void()); - MOCK_METHOD0(OnPlaybackError, void()); + MOCK_METHOD1(OnPlaybackError, void(HRESULT)); protected: ~MockMediaFoundationCdmProxy() override;
diff --git a/media/video/video_encode_accelerator.cc b/media/video/video_encode_accelerator.cc index 9c04460..7796536 100644 --- a/media/video/video_encode_accelerator.cc +++ b/media/video/video_encode_accelerator.cc
@@ -166,11 +166,6 @@ VideoEncodeAccelerator::SupportedProfile::~SupportedProfile() = default; -VideoEncodeAccelerator::SupportedProfiles -VideoEncodeAccelerator::GetSupportedProfilesLight() { - return GetSupportedProfiles(); -} - void VideoEncodeAccelerator::Flush(FlushCallback flush_callback) { // TODO(owenlin): implements this https://crbug.com/755889. NOTIMPLEMENTED();
diff --git a/media/video/video_encode_accelerator.h b/media/video/video_encode_accelerator.h index 47119818..6014545 100644 --- a/media/video/video_encode_accelerator.h +++ b/media/video/video_encode_accelerator.h
@@ -355,14 +355,6 @@ // can be called before Initialize(). virtual SupportedProfiles GetSupportedProfiles() = 0; - // Returns a list of the supported codec profiles of the video encoder, - // similar to GetSupportedProfiles(), but this function only populates: - // codec, framerate range and resolution range. - // - // Populating things like SVC modes can take a lot of time and they are - // not always used. See https://crbug.com/1263196 - virtual SupportedProfiles GetSupportedProfilesLight(); - // Initializes the video encoder with specific configuration. Called once per // encoder construction. This call is synchronous and returns true iff // initialization is successful.
diff --git a/mojo/core/trap_unittest.cc b/mojo/core/trap_unittest.cc index 4dd2bd3..e7551e8e 100644 --- a/mojo/core/trap_unittest.cc +++ b/mojo/core/trap_unittest.cc
@@ -55,10 +55,10 @@ auto* context = new NotificationContext(base::BindLambdaForTesting(handler)); context->SetCancelCallback( - base::BindOnce(base::BindLambdaForTesting([cancel_handler, context] { + base::BindLambdaForTesting([cancel_handler, context] { cancel_handler(); delete context; - }))); + })); return reinterpret_cast<uintptr_t>(context); } @@ -1383,7 +1383,7 @@ wait_for_cancellation.Signal(); }); - ThreadedRunner runner(base::BindOnce(base::BindLambdaForTesting([&] { + ThreadedRunner runner(base::BindLambdaForTesting([&] { wait_for_notification.Wait(); // Cancel the watch while the notification is still running. @@ -1393,7 +1393,7 @@ wait_for_cancellation.Wait(); EXPECT_TRUE(callback_done); - }))); + })); runner.Start(); EXPECT_EQ(MOJO_RESULT_OK,
diff --git a/net/log/net_log_source.cc b/net/log/net_log_source.cc index d19b586..dcedad40 100644 --- a/net/log/net_log_source.cc +++ b/net/log/net_log_source.cc
@@ -7,26 +7,10 @@ #include <memory> #include <utility> -#include "base/bind.h" -#include "base/callback.h" -#include "base/check_op.h" #include "base/values.h" -#include "net/log/net_log_capture_mode.h" namespace net { -namespace { - -base::Value SourceEventParametersCallback(const NetLogSource source) { - if (!source.IsValid()) - return base::Value(); - base::Value::Dict event_params; - source.AddToEventParameters(event_params); - return base::Value(std::move(event_params)); -} - -} // namespace - // LoadTimingInfo requires this be 0. const uint32_t NetLogSource::kInvalidId = 0; @@ -57,7 +41,11 @@ } base::Value NetLogSource::ToEventParameters() const { - return SourceEventParametersCallback(*this); + if (!IsValid()) + return base::Value(); + base::Value::Dict event_params; + AddToEventParameters(event_params); + return base::Value(std::move(event_params)); } } // namespace net
diff --git a/remoting/host/BUILD.gn b/remoting/host/BUILD.gn index aa398af..ab3bbb8 100644 --- a/remoting/host/BUILD.gn +++ b/remoting/host/BUILD.gn
@@ -547,6 +547,8 @@ sources += [ "audio_capturer_chromeos.cc", "continue_window_chromeos.cc", + "curtain_mode_chromeos.cc", + "curtain_mode_chromeos.h", "desktop_display_info_loader_chromeos.cc", "disconnect_window_chromeos.cc", "input_injector_chromeos.cc", @@ -717,6 +719,7 @@ "it2me/it2me_confirmation_dialog_proxy_unittest.cc", "it2me/it2me_host_unittest.cc", "it2me/it2me_native_messaging_host_unittest.cc", + "it2me_desktop_environment_unittest.cc", "mouse_cursor_monitor_proxy_unittest.cc", "mouse_shape_pump_unittest.cc", "native_messaging/native_messaging_reader_unittest.cc",
diff --git a/remoting/host/curtain_mode.h b/remoting/host/curtain_mode.h index b76cfc2..8a79d489 100644 --- a/remoting/host/curtain_mode.h +++ b/remoting/host/curtain_mode.h
@@ -7,8 +7,7 @@ #include <memory> -#include "base/compiler_specific.h" -#include "base/memory/ref_counted.h" +#include "base/memory/scoped_refptr.h" #include "base/memory/weak_ptr.h" namespace base { @@ -24,7 +23,7 @@ CurtainMode(const CurtainMode&) = delete; CurtainMode& operator=(const CurtainMode&) = delete; - virtual ~CurtainMode() {} + virtual ~CurtainMode() = default; // Creates a platform-specific curtain mode implementation object that // "curtains" the current session making sure it is not accessible from @@ -40,7 +39,7 @@ virtual bool Activate() = 0; protected: - CurtainMode() {} + CurtainMode() = default; }; } // namespace remoting
diff --git a/remoting/host/curtain_mode_chromeos.cc b/remoting/host/curtain_mode_chromeos.cc new file mode 100644 index 0000000..db0a414b --- /dev/null +++ b/remoting/host/curtain_mode_chromeos.cc
@@ -0,0 +1,28 @@ +// 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 "remoting/host/curtain_mode_chromeos.h" + +#include <memory> + +#include "base/memory/scoped_refptr.h" +#include "base/memory/weak_ptr.h" +#include "base/task/single_thread_task_runner.h" + +namespace remoting { + +bool CurtainModeChromeOs::Activate() { + // TODO(b/236687774): Implement curtain mode on ChromeOS. + return true; +} + +// static +std::unique_ptr<CurtainMode> CurtainMode::Create( + scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner, + base::WeakPtr<ClientSessionControl> client_session_control) { + return std::make_unique<CurtainModeChromeOs>(); +} + +} // namespace remoting
diff --git a/remoting/host/curtain_mode_chromeos.h b/remoting/host/curtain_mode_chromeos.h new file mode 100644 index 0000000..cc03608 --- /dev/null +++ b/remoting/host/curtain_mode_chromeos.h
@@ -0,0 +1,30 @@ +// 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 REMOTING_HOST_CURTAIN_MODE_CHROMEOS_H_ +#define REMOTING_HOST_CURTAIN_MODE_CHROMEOS_H_ + +#include "remoting/host/curtain_mode.h" + +namespace remoting { + +// Helper class that handles everything related to curtained sessions on +// ChromeOS, which includes: +// - Creating a virtual display +// - Installing the curtain screen +// - Suppressing local input +class CurtainModeChromeOs : public CurtainMode { + public: + CurtainModeChromeOs() = default; + CurtainModeChromeOs(const CurtainModeChromeOs&) = delete; + CurtainModeChromeOs& operator=(const CurtainModeChromeOs&) = delete; + ~CurtainModeChromeOs() override = default; + + // CurtainMode implementation: + bool Activate() override; +}; + +} // namespace remoting + +#endif // REMOTING_HOST_CURTAIN_MODE_CHROMEOS_H_
diff --git a/remoting/host/it2me/BUILD.gn b/remoting/host/it2me/BUILD.gn index 36c72074..741f90b 100644 --- a/remoting/host/it2me/BUILD.gn +++ b/remoting/host/it2me/BUILD.gn
@@ -160,6 +160,7 @@ "//remoting/base:base", "//remoting/host:common", "//remoting/host/chromeos:enterprise_support", + "//remoting/host/chromeos:features", "//remoting/host/mojom:mojom", "//remoting/host/native_messaging", "//skia",
diff --git a/remoting/host/it2me/it2me_constants.cc b/remoting/host/it2me/it2me_constants.cc index 24cd46a..fdb0dd2 100644 --- a/remoting/host/it2me/it2me_constants.cc +++ b/remoting/host/it2me/it2me_constants.cc
@@ -17,6 +17,7 @@ const char kSuppressUserDialogs[] = "suppressUserDialogs"; const char kIsEnterpriseAdminUser[] = "isEnterpriseAdminUser"; const char kSuppressNotifications[] = "suppressNotifications"; +const char kCurtainLocalUserSession[] = "curtainLocalUserSession"; const char kTerminateUponInput[] = "terminateUponInput"; const char kUseElevatedHost[] = "useElevatedHost"; const char kUseSignalingProxy[] = "useSignalingProxy";
diff --git a/remoting/host/it2me/it2me_constants.h b/remoting/host/it2me/it2me_constants.h index b36474b5..796c4f4 100644 --- a/remoting/host/it2me/it2me_constants.h +++ b/remoting/host/it2me/it2me_constants.h
@@ -40,6 +40,7 @@ extern const char kIsEnterpriseAdminUser[]; extern const char kSuppressUserDialogs[]; extern const char kSuppressNotifications[]; +extern const char kCurtainLocalUserSession[]; extern const char kTerminateUponInput[]; extern const char kUseElevatedHost[]; extern const char kUseSignalingProxy[];
diff --git a/remoting/host/it2me/it2me_host.cc b/remoting/host/it2me/it2me_host.cc index a4f01cd..1faca7071 100644 --- a/remoting/host/it2me/it2me_host.cc +++ b/remoting/host/it2me/it2me_host.cc
@@ -12,18 +12,15 @@ #include "base/bind.h" #include "base/callback_helpers.h" #include "base/strings/string_util.h" -#include "base/threading/platform_thread.h" #include "base/threading/thread_task_runner_handle.h" #include "base/time/time.h" #include "build/chromeos_buildflags.h" #include "components/policy/policy_constants.h" #include "components/webrtc/thread_wrapper.h" -#include "net/url_request/url_request_context_getter.h" -#include "remoting/base/auto_thread.h" +#include "remoting/base/auto_thread_task_runner.h" #include "remoting/base/logging.h" #include "remoting/base/oauth_token_getter.h" #include "remoting/base/rsa_key_pair.h" -#include "remoting/base/service_urls.h" #include "remoting/host/chromoting_host.h" #include "remoting/host/chromoting_host_context.h" #include "remoting/host/ftl_signaling_connector.h" @@ -36,7 +33,6 @@ #include "remoting/host/it2me_desktop_environment.h" #include "remoting/protocol/auth_util.h" #include "remoting/protocol/chromium_port_allocator_factory.h" -#include "remoting/protocol/ice_transport.h" #include "remoting/protocol/it2me_host_authenticator_factory.h" #include "remoting/protocol/jingle_session_manager.h" #include "remoting/protocol/network_settings.h" @@ -104,6 +100,15 @@ #endif } +void It2MeHost::set_enable_curtaining(bool enable) { +#if BUILDFLAG(IS_CHROMEOS_ASH) || !defined(NDEBUG) + enable_curtaining_ = enable; +#else + NOTREACHED() << "It2MeHost::set_enable_curtaining is only supported " + "on ChromeOS"; +#endif +} + void It2MeHost::set_is_enterprise_session(bool is_enterprise_session) { #if BUILDFLAG(IS_CHROMEOS_ASH) || !defined(NDEBUG) is_enterprise_session_ = is_enterprise_session; @@ -265,6 +270,7 @@ options.set_enable_user_interface(enable_dialogs_); options.set_enable_notifications(enable_notifications_); options.set_terminate_upon_input(terminate_upon_input_); + options.set_enable_curtaining(enable_curtaining_); if (max_clipboard_size_.has_value()) { options.set_clipboard_size(max_clipboard_size_.value());
diff --git a/remoting/host/it2me/it2me_host.h b/remoting/host/it2me/it2me_host.h index 6ca4979..40eca3e9 100644 --- a/remoting/host/it2me/it2me_host.h +++ b/remoting/host/it2me/it2me_host.h
@@ -9,7 +9,6 @@ #include <string> #include <vector> -#include "base/gtest_prod_util.h" #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" #include "build/chromeos_buildflags.h" @@ -101,10 +100,17 @@ // Enable or disable whether or not the session should be terminated if local // input is detected. void set_terminate_upon_input(bool terminate_upon_input); + bool terminate_upon_input() const { return terminate_upon_input_; } + + // Enable, disable, or query whether or not the local user session is + // curtained when a remote user has connected. + void set_enable_curtaining(bool enable); + bool enable_curtaining() const { return enable_curtaining_; } // Indicates whether the session was initiated through the remote command // infrastructure for a managed device. void set_is_enterprise_session(bool is_enterprise_session); + bool is_enterprise_session() const { return is_enterprise_session_; } // Creates It2Me host structures and starts the host. virtual void Connect( @@ -240,6 +246,7 @@ bool enable_dialogs_ = true; bool enable_notifications_ = true; bool terminate_upon_input_ = false; + bool enable_curtaining_ = false; }; // Having a factory interface makes it possible for the test to provide a mock
diff --git a/remoting/host/it2me/it2me_host_unittest.cc b/remoting/host/it2me/it2me_host_unittest.cc index bb8133f..f4beaf50 100644 --- a/remoting/host/it2me/it2me_host_unittest.cc +++ b/remoting/host/it2me/it2me_host_unittest.cc
@@ -12,7 +12,7 @@ #include "base/callback.h" #include "base/location.h" #include "base/memory/raw_ptr.h" -#include "base/memory/ref_counted.h" +#include "base/memory/scoped_refptr.h" #include "base/memory/weak_ptr.h" #include "base/run_loop.h" #include "base/test/task_environment.h" @@ -214,6 +214,8 @@ absl::optional<bool> enable_dialogs_; absl::optional<bool> enable_notifications_; absl::optional<bool> is_enterprise_session_; + absl::optional<bool> terminate_upon_input_; + absl::optional<bool> enable_curtaining_; // Stores the last nat traversal policy value received. bool last_nat_traversal_enabled_value_ = false; @@ -352,6 +354,16 @@ // is_enterprise_session should only be run on ChromeOS. it2me_host_->set_is_enterprise_session(is_enterprise_session_.value()); } + if (terminate_upon_input_.has_value()) { + // Only ChromeOS supports this method, so tests setting + // terminate_upon_input_ should only be run on ChromeOS. + it2me_host_->set_terminate_upon_input(terminate_upon_input_.value()); + } + if (enable_curtaining_.has_value()) { + // Only ChromeOS supports this method, so tests setting + // curtain_local_user_session should only be run on ChromeOS. + it2me_host_->set_enable_curtaining(enable_curtaining_.value()); + } auto create_connection_context = base::BindOnce( [](std::unique_ptr<SignalStrategy> signal_strategy, ChromotingHostContext* host_context) { @@ -823,6 +835,28 @@ EXPECT_FALSE(GetHost()->desktop_environment_options().enable_notifications()); } +TEST_F(It2MeHostTest, ConnectRespectsTerminateUponInputParameter) { + terminate_upon_input_ = true; + StartHost(); + EXPECT_TRUE(GetHost()->desktop_environment_options().terminate_upon_input()); +} + +TEST_F(It2MeHostTest, TerminateUponInputDefaultsToFalse) { + StartHost(); + EXPECT_FALSE(GetHost()->desktop_environment_options().terminate_upon_input()); +} + +TEST_F(It2MeHostTest, ConnectRespectsEnableCurtainingParameter) { + enable_curtaining_ = true; + StartHost(); + EXPECT_TRUE(GetHost()->desktop_environment_options().enable_curtaining()); +} + +TEST_F(It2MeHostTest, EnableCurtainingDefaultsToFalse) { + StartHost(); + EXPECT_FALSE(GetHost()->desktop_environment_options().enable_curtaining()); +} + TEST_F(It2MeHostTest, EnterpriseSessionsSucceedWhenRemoteSupportConnectionsPolicyDisabled) { SetPolicies({{policy::key::kRemoteAccessHostAllowRemoteSupportConnections,
diff --git a/remoting/host/it2me/it2me_native_messaging_host.cc b/remoting/host/it2me/it2me_native_messaging_host.cc index 4ad888e..332f87e 100644 --- a/remoting/host/it2me/it2me_native_messaging_host.cc +++ b/remoting/host/it2me/it2me_native_messaging_host.cc
@@ -243,6 +243,8 @@ message.FindBool(kSuppressNotifications).value_or(false); bool terminate_upon_input = message.FindBool(kTerminateUponInput).value_or(false); + bool curtain_local_user_session = + message.FindBool(kCurtainLocalUserSession).value_or(false); #endif bool is_enterprise_admin_user = @@ -342,6 +344,7 @@ it2me_host_->set_enable_dialogs(!suppress_user_dialogs); it2me_host_->set_enable_notifications(!suppress_notifications); it2me_host_->set_terminate_upon_input(terminate_upon_input); + it2me_host_->set_enable_curtaining(curtain_local_user_session); it2me_host_->set_is_enterprise_session(is_enterprise_admin_user); #endif it2me_host_->Connect(
diff --git a/remoting/host/it2me/it2me_native_messaging_host_ash.cc b/remoting/host/it2me/it2me_native_messaging_host_ash.cc index 84fdbe6..f4bb25a 100644 --- a/remoting/host/it2me/it2me_native_messaging_host_ash.cc +++ b/remoting/host/it2me/it2me_native_messaging_host_ash.cc
@@ -2,19 +2,18 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include <utility> - #include "remoting/host/it2me/it2me_native_messaging_host_ash.h" +#include <utility> + #include "base/callback.h" -#include "base/json/json_reader.h" +#include "base/feature_list.h" #include "base/json/json_writer.h" -#include "base/lazy_instance.h" -#include "base/stl_util.h" #include "base/time/time.h" #include "base/values.h" #include "extensions/browser/api/messaging/native_message_host.h" #include "remoting/host/chromeos/chromeos_enterprise_params.h" +#include "remoting/host/chromeos/features.h" #include "remoting/host/chromoting_host_context.h" #include "remoting/host/it2me/it2me_native_messaging_host.h" #include "remoting/host/native_messaging/native_messaging_helpers.h" @@ -69,6 +68,24 @@ #endif } +bool ShouldCurtainLocalUserSession( + const mojom::SupportSessionParams& params, + const absl::optional<ChromeOsEnterpriseParams>& enterprise_params) { + if (!base::FeatureList::IsEnabled(features::kEnableCrdAdminRemoteAccess)) + return false; + + if (enterprise_params) + return enterprise_params.value().curtain_local_user_session; + + // On non-debug builds, do not allow setting this value through the Mojom + // API. +#if !defined(NDEBUG) + return params.curtain_local_user_session; +#else + return false; +#endif +} + } // namespace It2MeNativeMessageHostAsh::It2MeNativeMessageHostAsh() = default; @@ -122,6 +139,8 @@ ShouldSuppressNotifications(*params, enterprise_params)); message.Set(kTerminateUponInput, ShouldTerminateUponInput(*params, enterprise_params)); + message.Set(kCurtainLocalUserSession, + ShouldCurtainLocalUserSession(*params, enterprise_params)); message.Set(kIsEnterpriseAdminUser, enterprise_params.has_value()); std::string message_json;
diff --git a/remoting/host/it2me/it2me_native_messaging_host_unittest.cc b/remoting/host/it2me/it2me_native_messaging_host_unittest.cc index c672e74..1e014c77 100644 --- a/remoting/host/it2me/it2me_native_messaging_host_unittest.cc +++ b/remoting/host/it2me/it2me_native_messaging_host_unittest.cc
@@ -18,16 +18,11 @@ #include "base/memory/ptr_util.h" #include "base/memory/raw_ptr.h" #include "base/run_loop.h" -#include "base/strings/stringize_macros.h" #include "base/test/task_environment.h" -#include "base/threading/thread_task_runner_handle.h" #include "base/time/time.h" #include "base/values.h" -#include "build/chromeos_buildflags.h" #include "components/policy/core/common/fake_async_policy_loader.h" -#include "components/policy/core/common/mock_policy_service.h" #include "components/policy/policy_constants.h" -#include "net/base/file_stream.h" #include "remoting/base/auto_thread_task_runner.h" #include "remoting/host/chromoting_host_context.h" #include "remoting/host/it2me/it2me_constants.h" @@ -222,9 +217,7 @@ ~MockIt2MeHostFactory() override = default; - scoped_refptr<It2MeHost> CreateIt2MeHost() override { - return host; - } + scoped_refptr<It2MeHost> CreateIt2MeHost() override { return host; } scoped_refptr<MockIt2MeHost> host; }; @@ -692,6 +685,57 @@ VerifyDisconnectResponses(next_id); } +TEST_F(It2MeNativeMessagingHostTest, + ConnectRespectsTerminateUponInputParameterOnChromeOsOnly) { + int next_id = 1; + base::DictionaryValue connect_message = CreateConnectMessage(next_id); + connect_message.SetBoolKey(kTerminateUponInput, true); + WriteMessageToInputPipe(connect_message); + VerifyConnectResponses(next_id); +#if BUILDFLAG(IS_CHROMEOS_ASH) || !defined(NDEBUG) + EXPECT_TRUE(factory_raw_ptr_->host->terminate_upon_input()); +#else + EXPECT_FALSE(factory_raw_ptr_->host->terminate_upon_input()); +#endif + ++next_id; + WriteMessageToInputPipe(CreateDisconnectMessage(next_id)); + VerifyDisconnectResponses(next_id); +} + +TEST_F(It2MeNativeMessagingHostTest, + ConnectRespectsIsEnterpriseAdminUserParameterOnChromeOsOnly) { + int next_id = 1; + base::DictionaryValue connect_message = CreateConnectMessage(next_id); + connect_message.SetBoolKey(kIsEnterpriseAdminUser, true); + WriteMessageToInputPipe(connect_message); + VerifyConnectResponses(next_id); +#if BUILDFLAG(IS_CHROMEOS_ASH) || !defined(NDEBUG) + EXPECT_TRUE(factory_raw_ptr_->host->is_enterprise_session()); +#else + EXPECT_FALSE(factory_raw_ptr_->host->is_enterprise_session()); +#endif + ++next_id; + WriteMessageToInputPipe(CreateDisconnectMessage(next_id)); + VerifyDisconnectResponses(next_id); +} + +TEST_F(It2MeNativeMessagingHostTest, + ConnectRespectsCurtainLocalUserSessionParameterOnChromeOsOnly) { + int next_id = 1; + base::DictionaryValue connect_message = CreateConnectMessage(next_id); + connect_message.SetBoolKey(kCurtainLocalUserSession, true); + WriteMessageToInputPipe(connect_message); + VerifyConnectResponses(next_id); +#if BUILDFLAG(IS_CHROMEOS_ASH) || !defined(NDEBUG) + EXPECT_TRUE(factory_raw_ptr_->host->enable_curtaining()); +#else + EXPECT_FALSE(factory_raw_ptr_->host->enable_curtaining()); +#endif + ++next_id; + WriteMessageToInputPipe(CreateDisconnectMessage(next_id)); + VerifyDisconnectResponses(next_id); +} + // Verify non-Dictionary requests are rejected. TEST_F(It2MeNativeMessagingHostTest, WrongFormat) { base::ListValue message;
diff --git a/remoting/host/it2me_desktop_environment.cc b/remoting/host/it2me_desktop_environment.cc index f92dbba8..329ed52 100644 --- a/remoting/host/it2me_desktop_environment.cc +++ b/remoting/host/it2me_desktop_environment.cc
@@ -8,20 +8,24 @@ #include <utility> #include "base/check.h" -#include "base/memory/ptr_util.h" #include "base/task/single_thread_task_runner.h" #include "build/build_config.h" #include "remoting/host/client_session_control.h" #include "remoting/host/host_window.h" #include "remoting/host/host_window_proxy.h" #include "remoting/host/input_monitor/local_input_monitor.h" -#include "remoting/protocol/capability_names.h" #if BUILDFLAG(IS_POSIX) #include <sys/types.h> #include <unistd.h> #endif // BUILDFLAG(IS_POSIX) +#if BUILDFLAG(IS_CHROMEOS) +#include "base/feature_list.h" +#include "remoting/host/chromeos/features.h" +#include "remoting/host/curtain_mode_chromeos.h" +#endif // BUILDFLAG(IS_CHROMEOS) + namespace remoting { It2MeDesktopEnvironment::~It2MeDesktopEnvironment() { @@ -85,6 +89,23 @@ } } +bool It2MeDesktopEnvironment::InitializeCurtainMode() { +#if BUILDFLAG(IS_CHROMEOS) + if (base::FeatureList::IsEnabled(features::kEnableCrdAdminRemoteAccess)) { + if (desktop_environment_options().enable_curtaining()) { + curtain_mode_ = std::make_unique<CurtainModeChromeOs>(); + if (!curtain_mode_->Activate()) { + LOG(ERROR) << "Failed to activate the curtain mode."; + curtain_mode_ = nullptr; + return false; + } + return true; + } + } +#endif // BUILDFLAG(IS_CHROMEOS) + return true; +} + It2MeDesktopEnvironmentFactory::It2MeDesktopEnvironmentFactory( scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, scoped_refptr<base::SingleThreadTaskRunner> video_capture_task_runner, @@ -103,9 +124,14 @@ const DesktopEnvironmentOptions& options) { DCHECK(caller_task_runner()->BelongsToCurrentThread()); - return base::WrapUnique(new It2MeDesktopEnvironment( + std::unique_ptr<It2MeDesktopEnvironment> result(new It2MeDesktopEnvironment( caller_task_runner(), video_capture_task_runner(), input_task_runner(), ui_task_runner(), client_session_control, options)); + + if (!result->InitializeCurtainMode()) + return nullptr; + + return result; } } // namespace remoting
diff --git a/remoting/host/it2me_desktop_environment.h b/remoting/host/it2me_desktop_environment.h index a61f8f64..a773bc4 100644 --- a/remoting/host/it2me_desktop_environment.h +++ b/remoting/host/it2me_desktop_environment.h
@@ -10,6 +10,7 @@ #include "base/memory/weak_ptr.h" #include "base/task/single_thread_task_runner.h" #include "remoting/host/basic_desktop_environment.h" +#include "remoting/host/curtain_mode.h" namespace remoting { @@ -25,6 +26,12 @@ ~It2MeDesktopEnvironment() override; + // Initializes the curtain mode if needed. + // Returns `false` if the curtain mode failed to start for any reason. + bool InitializeCurtainMode(); + + bool is_curtained() const { return curtain_mode_ != nullptr; } + protected: friend class It2MeDesktopEnvironmentFactory; It2MeDesktopEnvironment( @@ -44,6 +51,8 @@ // Notifies the client session about the local mouse movements. std::unique_ptr<LocalInputMonitor> local_input_monitor_; + + std::unique_ptr<CurtainMode> curtain_mode_; }; // Used to create |It2MeDesktopEnvironment| instances.
diff --git a/remoting/host/it2me_desktop_environment_unittest.cc b/remoting/host/it2me_desktop_environment_unittest.cc new file mode 100644 index 0000000..2ae489fa --- /dev/null +++ b/remoting/host/it2me_desktop_environment_unittest.cc
@@ -0,0 +1,144 @@ +// 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 "remoting/host/it2me_desktop_environment.h" +#include <memory> + +#include "base/memory/scoped_refptr.h" +#include "base/memory/weak_ptr.h" +#include "base/test/scoped_feature_list.h" +#include "base/test/task_environment.h" +#include "remoting/host/base/desktop_environment_options.h" +#include "remoting/host/chromeos/features.h" +#include "remoting/host/client_session_control.h" +#include "remoting/host/client_session_events.h" +#include "remoting/proto/control.pb.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace remoting { +namespace { + +using ::testing::Eq; + +class FakeClientSessionControl : public ClientSessionControl { + public: + FakeClientSessionControl() = default; + FakeClientSessionControl(const FakeClientSessionControl&) = delete; + FakeClientSessionControl& operator=(const FakeClientSessionControl&) = delete; + ~FakeClientSessionControl() override = default; + + // ClientSessionControl implementation: + const std::string& client_jid() const override { return client_jid_; } + void DisconnectSession(protocol::ErrorCode error) override {} + void OnLocalPointerMoved(const webrtc::DesktopVector& position, + ui::EventType type) override {} + void OnLocalKeyPressed(uint32_t usb_keycode) override {} + void SetDisableInputs(bool disable_inputs) override {} + void OnDesktopDisplayChanged( + std::unique_ptr<protocol::VideoLayout> layout) override {} + + base::WeakPtr<FakeClientSessionControl> GetWeakPtr() { + return weak_ptr_factory_.GetWeakPtr(); + } + + private: + std::string client_jid_ = "<fake-client-jid>"; + base::WeakPtrFactory<FakeClientSessionControl> weak_ptr_factory_{this}; +}; + +class FakeClientSessionEvents : public ClientSessionEvents { + public: + FakeClientSessionEvents() = default; + FakeClientSessionEvents(const FakeClientSessionEvents&) = delete; + FakeClientSessionEvents& operator=(const FakeClientSessionEvents&) = delete; + ~FakeClientSessionEvents() override = default; + + // ClientSessionEvents implementation: + void OnDesktopAttached(uint32_t session_id) override {} + void OnDesktopDetached() override {} + + base::WeakPtr<FakeClientSessionEvents> GetWeakPtr() { + return weak_ptr_factory_.GetWeakPtr(); + } + + private: + base::WeakPtrFactory<FakeClientSessionEvents> weak_ptr_factory_{this}; +}; + +class It2MeDesktopEnvironmentTest : public ::testing::Test { + public: + It2MeDesktopEnvironmentTest() = default; + ~It2MeDesktopEnvironmentTest() override = default; + + DesktopEnvironmentOptions default_options() { + DesktopEnvironmentOptions options; + // These options must be false or we run into crashes in HostWindowProxy. + options.set_enable_user_interface(false); + options.set_enable_notifications(false); + return options; + } + + scoped_refptr<base::SingleThreadTaskRunner> task_runner() { + return environment_.GetMainThreadTaskRunner(); + } + + std::unique_ptr<It2MeDesktopEnvironment> Create( + DesktopEnvironmentOptions options) { + auto base_ptr = It2MeDesktopEnvironmentFactory(task_runner(), task_runner(), + task_runner(), task_runner()) + .Create(session_control_.GetWeakPtr(), + session_events_.GetWeakPtr(), options); + // Cast to It2MeDesktopEnvironment + return std::unique_ptr<It2MeDesktopEnvironment>( + static_cast<It2MeDesktopEnvironment*>(base_ptr.release())); + } + + private: + base::test::SingleThreadTaskEnvironment environment_; + + FakeClientSessionControl session_control_; + FakeClientSessionEvents session_events_; +}; + +#if BUILDFLAG(IS_CHROMEOS) +TEST_F(It2MeDesktopEnvironmentTest, + ShouldStartCurtainWhenEnableCurtainingIsTrue) { + base::test::ScopedFeatureList feature_list; + feature_list.InitAndEnableFeature(features::kEnableCrdAdminRemoteAccess); + DesktopEnvironmentOptions options(default_options()); + + options.set_enable_curtaining(true); + + auto desktop_environment = Create(options); + EXPECT_THAT(desktop_environment->is_curtained(), Eq(true)); +} + +TEST_F(It2MeDesktopEnvironmentTest, + ShouldNotStartCurtainWhenEnableCurtainingIsFalse) { + base::test::ScopedFeatureList feature_list; + feature_list.InitAndEnableFeature(features::kEnableCrdAdminRemoteAccess); + DesktopEnvironmentOptions options(default_options()); + + options.set_enable_curtaining(false); + + auto desktop_environment = Create(options); + EXPECT_THAT(desktop_environment->is_curtained(), Eq(false)); +} + +TEST_F(It2MeDesktopEnvironmentTest, + ShouldNotStartCurtainWhenCrdAdminRemoteAccessFeatureIsDisabled) { + base::test::ScopedFeatureList feature_list; + feature_list.InitAndDisableFeature(features::kEnableCrdAdminRemoteAccess); + DesktopEnvironmentOptions options(default_options()); + + options.set_enable_curtaining(true); + + auto desktop_environment = Create(options); + EXPECT_THAT(desktop_environment->is_curtained(), Eq(false)); +} +#endif // BUILDFLAG(IS_CHROMEOS) + +} // namespace +} // namespace remoting
diff --git a/remoting/host/me2me_desktop_environment.cc b/remoting/host/me2me_desktop_environment.cc index 5394efa..04cd35f 100644 --- a/remoting/host/me2me_desktop_environment.cc +++ b/remoting/host/me2me_desktop_environment.cc
@@ -215,7 +215,7 @@ return nullptr; } - return std::move(desktop_environment); + return desktop_environment; } } // namespace remoting
diff --git a/remoting/host/mojom/remote_support.mojom b/remoting/host/mojom/remote_support.mojom index c95ea7c..3277ad3d6e 100644 --- a/remoting/host/mojom/remote_support.mojom +++ b/remoting/host/mojom/remote_support.mojom
@@ -41,6 +41,8 @@ }; // The parameters required to start a remote support session. +// +// Next version: 2 [Stable] struct SupportSessionParams { // Gaia username of the user requesting the connection. @@ -63,6 +65,11 @@ // initiated connections using the RemoteCommand infrastructure. [EnableIf=is_chromeos] bool terminate_upon_input = false; + + // Curtain off the local displays during the remoting session. Used for Admin + // initiated connections using the RemoteCommand infrastructure. + [EnableIf=is_chromeos, MinVersion=1] + bool curtain_local_user_session = false; }; // Represents the state of the remote support host NAT device policies.
diff --git a/storage/browser/file_system/copy_or_move_operation_delegate.cc b/storage/browser/file_system/copy_or_move_operation_delegate.cc index eb8f73fa..6f4fc65 100644 --- a/storage/browser/file_system/copy_or_move_operation_delegate.cc +++ b/storage/browser/file_system/copy_or_move_operation_delegate.cc
@@ -975,16 +975,17 @@ copy_or_move_hook_delegate_->AsWeakPtr()); } else { // Cross filesystem case. - base::File::Error error = base::File::FILE_ERROR_FAILED; + base::File::Error get_validator_factory_error = + base::File::FILE_ERROR_FAILED; CopyOrMoveFileValidatorFactory* validator_factory = file_system_context()->GetCopyOrMoveFileValidatorFactory( - dest_root_.type(), &error); - if (error != base::File::FILE_OK) { + dest_root_.type(), &get_validator_factory_error); + if (get_validator_factory_error != base::File::FILE_OK) { PostTask(base::BindOnce(&CopyOrMoveHookDelegate::OnError, copy_or_move_hook_delegate_->AsWeakPtr(), src_url, - dest_url, error)); + dest_url, get_validator_factory_error)); - std::move(callback).Run(error); + std::move(callback).Run(get_validator_factory_error); return; }
diff --git a/testing/buildbot/chromium.chromiumos.json b/testing/buildbot/chromium.chromiumos.json index e3127f0..e7f2b08 100644 --- a/testing/buildbot/chromium.chromiumos.json +++ b/testing/buildbot/chromium.chromiumos.json
@@ -5742,21 +5742,21 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5239.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5249.7/test_ash_chrome" ], "isolate_profile_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "interactive_ui_tests Lacros version skew testing ash 106.0.5239.0", + "name": "interactive_ui_tests Lacros version skew testing ash 106.0.5249.7", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v106.0.5239.0", - "revision": "version:106.0.5239.0" + "location": "lacros_version_skew_tests_v106.0.5249.7", + "revision": "version:106.0.5249.7" } ], "dimension_sets": [ @@ -5769,26 +5769,26 @@ }, "test": "interactive_ui_tests", "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/", - "variant_id": "Lacros version skew testing ash 106.0.5239.0" + "variant_id": "Lacros version skew testing ash 106.0.5249.7" }, { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5259.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5260.0/test_ash_chrome" ], "isolate_profile_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "interactive_ui_tests Lacros version skew testing ash 107.0.5259.0", + "name": "interactive_ui_tests Lacros version skew testing ash 107.0.5260.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v107.0.5259.0", - "revision": "version:107.0.5259.0" + "location": "lacros_version_skew_tests_v107.0.5260.0", + "revision": "version:107.0.5260.0" } ], "dimension_sets": [ @@ -5801,7 +5801,7 @@ }, "test": "interactive_ui_tests", "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/", - "variant_id": "Lacros version skew testing ash 107.0.5259.0" + "variant_id": "Lacros version skew testing ash 107.0.5260.0" }, { "isolate_profile_data": true, @@ -5908,21 +5908,21 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5239.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5249.7/test_ash_chrome" ], "isolate_profile_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests Lacros version skew testing ash 106.0.5239.0", + "name": "lacros_chrome_browsertests Lacros version skew testing ash 106.0.5249.7", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v106.0.5239.0", - "revision": "version:106.0.5239.0" + "location": "lacros_version_skew_tests_v106.0.5249.7", + "revision": "version:106.0.5249.7" } ], "dimension_sets": [ @@ -5934,26 +5934,26 @@ }, "test": "lacros_chrome_browsertests", "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests/", - "variant_id": "Lacros version skew testing ash 106.0.5239.0" + "variant_id": "Lacros version skew testing ash 106.0.5249.7" }, { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5259.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5260.0/test_ash_chrome" ], "isolate_profile_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests Lacros version skew testing ash 107.0.5259.0", + "name": "lacros_chrome_browsertests Lacros version skew testing ash 107.0.5260.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v107.0.5259.0", - "revision": "version:107.0.5259.0" + "location": "lacros_version_skew_tests_v107.0.5260.0", + "revision": "version:107.0.5260.0" } ], "dimension_sets": [ @@ -5965,7 +5965,7 @@ }, "test": "lacros_chrome_browsertests", "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests/", - "variant_id": "Lacros version skew testing ash 107.0.5259.0" + "variant_id": "Lacros version skew testing ash 107.0.5260.0" }, { "args": [ @@ -6054,21 +6054,21 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5239.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5249.7/test_ash_chrome" ], "isolate_profile_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 106.0.5239.0", + "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 106.0.5249.7", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v106.0.5239.0", - "revision": "version:106.0.5239.0" + "location": "lacros_version_skew_tests_v106.0.5249.7", + "revision": "version:106.0.5249.7" } ], "dimension_sets": [ @@ -6080,26 +6080,26 @@ }, "test": "lacros_chrome_browsertests_run_in_series", "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests_run_in_series/", - "variant_id": "Lacros version skew testing ash 106.0.5239.0" + "variant_id": "Lacros version skew testing ash 106.0.5249.7" }, { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5259.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5260.0/test_ash_chrome" ], "isolate_profile_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 107.0.5259.0", + "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 107.0.5260.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v107.0.5259.0", - "revision": "version:107.0.5259.0" + "location": "lacros_version_skew_tests_v107.0.5260.0", + "revision": "version:107.0.5260.0" } ], "dimension_sets": [ @@ -6111,7 +6111,7 @@ }, "test": "lacros_chrome_browsertests_run_in_series", "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests_run_in_series/", - "variant_id": "Lacros version skew testing ash 107.0.5259.0" + "variant_id": "Lacros version skew testing ash 107.0.5260.0" }, { "isolate_profile_data": true,
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json index 869f3a7..87c3147 100644 --- a/testing/buildbot/chromium.fyi.json +++ b/testing/buildbot/chromium.fyi.json
@@ -99198,21 +99198,21 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5239.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5249.7/test_ash_chrome" ], "isolate_profile_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "interactive_ui_tests Lacros version skew testing ash 106.0.5239.0", + "name": "interactive_ui_tests Lacros version skew testing ash 106.0.5249.7", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v106.0.5239.0", - "revision": "version:106.0.5239.0" + "location": "lacros_version_skew_tests_v106.0.5249.7", + "revision": "version:106.0.5249.7" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", @@ -99220,26 +99220,26 @@ }, "test": "interactive_ui_tests", "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/", - "variant_id": "Lacros version skew testing ash 106.0.5239.0" + "variant_id": "Lacros version skew testing ash 106.0.5249.7" }, { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5259.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5260.0/test_ash_chrome" ], "isolate_profile_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "interactive_ui_tests Lacros version skew testing ash 107.0.5259.0", + "name": "interactive_ui_tests Lacros version skew testing ash 107.0.5260.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v107.0.5259.0", - "revision": "version:107.0.5259.0" + "location": "lacros_version_skew_tests_v107.0.5260.0", + "revision": "version:107.0.5260.0" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", @@ -99247,7 +99247,7 @@ }, "test": "interactive_ui_tests", "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/", - "variant_id": "Lacros version skew testing ash 107.0.5259.0" + "variant_id": "Lacros version skew testing ash 107.0.5260.0" }, { "isolate_profile_data": true, @@ -99334,54 +99334,54 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5239.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5249.7/test_ash_chrome" ], "isolate_profile_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests Lacros version skew testing ash 106.0.5239.0", + "name": "lacros_chrome_browsertests Lacros version skew testing ash 106.0.5249.7", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v106.0.5239.0", - "revision": "version:106.0.5239.0" + "location": "lacros_version_skew_tests_v106.0.5249.7", + "revision": "version:106.0.5249.7" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "lacros_chrome_browsertests", "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests/", - "variant_id": "Lacros version skew testing ash 106.0.5239.0" + "variant_id": "Lacros version skew testing ash 106.0.5249.7" }, { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5259.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5260.0/test_ash_chrome" ], "isolate_profile_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests Lacros version skew testing ash 107.0.5259.0", + "name": "lacros_chrome_browsertests Lacros version skew testing ash 107.0.5260.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v107.0.5259.0", - "revision": "version:107.0.5259.0" + "location": "lacros_version_skew_tests_v107.0.5260.0", + "revision": "version:107.0.5260.0" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "lacros_chrome_browsertests", "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests/", - "variant_id": "Lacros version skew testing ash 107.0.5259.0" + "variant_id": "Lacros version skew testing ash 107.0.5260.0" }, { "args": [ @@ -99455,54 +99455,54 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5239.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5249.7/test_ash_chrome" ], "isolate_profile_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 106.0.5239.0", + "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 106.0.5249.7", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v106.0.5239.0", - "revision": "version:106.0.5239.0" + "location": "lacros_version_skew_tests_v106.0.5249.7", + "revision": "version:106.0.5249.7" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "lacros_chrome_browsertests_run_in_series", "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests_run_in_series/", - "variant_id": "Lacros version skew testing ash 106.0.5239.0" + "variant_id": "Lacros version skew testing ash 106.0.5249.7" }, { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5259.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5260.0/test_ash_chrome" ], "isolate_profile_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 107.0.5259.0", + "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 107.0.5260.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v107.0.5259.0", - "revision": "version:107.0.5259.0" + "location": "lacros_version_skew_tests_v107.0.5260.0", + "revision": "version:107.0.5260.0" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "lacros_chrome_browsertests_run_in_series", "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests_run_in_series/", - "variant_id": "Lacros version skew testing ash 107.0.5259.0" + "variant_id": "Lacros version skew testing ash 107.0.5260.0" }, { "isolate_profile_data": true, @@ -100803,20 +100803,20 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5239.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5249.7/test_ash_chrome" ], "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "interactive_ui_tests Lacros version skew testing ash 106.0.5239.0", + "name": "interactive_ui_tests Lacros version skew testing ash 106.0.5249.7", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v106.0.5239.0", - "revision": "version:106.0.5239.0" + "location": "lacros_version_skew_tests_v106.0.5249.7", + "revision": "version:106.0.5249.7" } ], "dimension_sets": [ @@ -100830,25 +100830,25 @@ }, "test": "interactive_ui_tests", "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/", - "variant_id": "Lacros version skew testing ash 106.0.5239.0" + "variant_id": "Lacros version skew testing ash 106.0.5249.7" }, { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5259.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5260.0/test_ash_chrome" ], "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "interactive_ui_tests Lacros version skew testing ash 107.0.5259.0", + "name": "interactive_ui_tests Lacros version skew testing ash 107.0.5260.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v107.0.5259.0", - "revision": "version:107.0.5259.0" + "location": "lacros_version_skew_tests_v107.0.5260.0", + "revision": "version:107.0.5260.0" } ], "dimension_sets": [ @@ -100862,7 +100862,7 @@ }, "test": "interactive_ui_tests", "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/", - "variant_id": "Lacros version skew testing ash 107.0.5259.0" + "variant_id": "Lacros version skew testing ash 107.0.5260.0" }, { "merge": { @@ -100969,20 +100969,20 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5239.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5249.7/test_ash_chrome" ], "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests Lacros version skew testing ash 106.0.5239.0", + "name": "lacros_chrome_browsertests Lacros version skew testing ash 106.0.5249.7", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v106.0.5239.0", - "revision": "version:106.0.5239.0" + "location": "lacros_version_skew_tests_v106.0.5249.7", + "revision": "version:106.0.5249.7" } ], "dimension_sets": [ @@ -100995,25 +100995,25 @@ }, "test": "lacros_chrome_browsertests", "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests/", - "variant_id": "Lacros version skew testing ash 106.0.5239.0" + "variant_id": "Lacros version skew testing ash 106.0.5249.7" }, { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5259.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5260.0/test_ash_chrome" ], "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests Lacros version skew testing ash 107.0.5259.0", + "name": "lacros_chrome_browsertests Lacros version skew testing ash 107.0.5260.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v107.0.5259.0", - "revision": "version:107.0.5259.0" + "location": "lacros_version_skew_tests_v107.0.5260.0", + "revision": "version:107.0.5260.0" } ], "dimension_sets": [ @@ -101026,7 +101026,7 @@ }, "test": "lacros_chrome_browsertests", "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests/", - "variant_id": "Lacros version skew testing ash 107.0.5259.0" + "variant_id": "Lacros version skew testing ash 107.0.5260.0" }, { "args": [ @@ -101115,20 +101115,20 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5239.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5249.7/test_ash_chrome" ], "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 106.0.5239.0", + "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 106.0.5249.7", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v106.0.5239.0", - "revision": "version:106.0.5239.0" + "location": "lacros_version_skew_tests_v106.0.5249.7", + "revision": "version:106.0.5249.7" } ], "dimension_sets": [ @@ -101141,25 +101141,25 @@ }, "test": "lacros_chrome_browsertests_run_in_series", "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests_run_in_series/", - "variant_id": "Lacros version skew testing ash 106.0.5239.0" + "variant_id": "Lacros version skew testing ash 106.0.5249.7" }, { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5259.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5260.0/test_ash_chrome" ], "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 107.0.5259.0", + "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 107.0.5260.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v107.0.5259.0", - "revision": "version:107.0.5259.0" + "location": "lacros_version_skew_tests_v107.0.5260.0", + "revision": "version:107.0.5260.0" } ], "dimension_sets": [ @@ -101172,7 +101172,7 @@ }, "test": "lacros_chrome_browsertests_run_in_series", "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests_run_in_series/", - "variant_id": "Lacros version skew testing ash 107.0.5259.0" + "variant_id": "Lacros version skew testing ash 107.0.5260.0" }, { "merge": { @@ -102648,20 +102648,20 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5239.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5249.7/test_ash_chrome" ], "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "interactive_ui_tests Lacros version skew testing ash 106.0.5239.0", + "name": "interactive_ui_tests Lacros version skew testing ash 106.0.5249.7", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v106.0.5239.0", - "revision": "version:106.0.5239.0" + "location": "lacros_version_skew_tests_v106.0.5249.7", + "revision": "version:106.0.5249.7" } ], "dimension_sets": [ @@ -102675,25 +102675,25 @@ }, "test": "interactive_ui_tests", "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/", - "variant_id": "Lacros version skew testing ash 106.0.5239.0" + "variant_id": "Lacros version skew testing ash 106.0.5249.7" }, { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5259.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5260.0/test_ash_chrome" ], "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "interactive_ui_tests Lacros version skew testing ash 107.0.5259.0", + "name": "interactive_ui_tests Lacros version skew testing ash 107.0.5260.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v107.0.5259.0", - "revision": "version:107.0.5259.0" + "location": "lacros_version_skew_tests_v107.0.5260.0", + "revision": "version:107.0.5260.0" } ], "dimension_sets": [ @@ -102707,7 +102707,7 @@ }, "test": "interactive_ui_tests", "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/", - "variant_id": "Lacros version skew testing ash 107.0.5259.0" + "variant_id": "Lacros version skew testing ash 107.0.5260.0" }, { "merge": { @@ -102814,20 +102814,20 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5239.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5249.7/test_ash_chrome" ], "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests Lacros version skew testing ash 106.0.5239.0", + "name": "lacros_chrome_browsertests Lacros version skew testing ash 106.0.5249.7", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v106.0.5239.0", - "revision": "version:106.0.5239.0" + "location": "lacros_version_skew_tests_v106.0.5249.7", + "revision": "version:106.0.5249.7" } ], "dimension_sets": [ @@ -102840,25 +102840,25 @@ }, "test": "lacros_chrome_browsertests", "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests/", - "variant_id": "Lacros version skew testing ash 106.0.5239.0" + "variant_id": "Lacros version skew testing ash 106.0.5249.7" }, { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5259.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5260.0/test_ash_chrome" ], "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests Lacros version skew testing ash 107.0.5259.0", + "name": "lacros_chrome_browsertests Lacros version skew testing ash 107.0.5260.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v107.0.5259.0", - "revision": "version:107.0.5259.0" + "location": "lacros_version_skew_tests_v107.0.5260.0", + "revision": "version:107.0.5260.0" } ], "dimension_sets": [ @@ -102871,7 +102871,7 @@ }, "test": "lacros_chrome_browsertests", "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests/", - "variant_id": "Lacros version skew testing ash 107.0.5259.0" + "variant_id": "Lacros version skew testing ash 107.0.5260.0" }, { "args": [ @@ -102960,20 +102960,20 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5239.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5249.7/test_ash_chrome" ], "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 106.0.5239.0", + "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 106.0.5249.7", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v106.0.5239.0", - "revision": "version:106.0.5239.0" + "location": "lacros_version_skew_tests_v106.0.5249.7", + "revision": "version:106.0.5249.7" } ], "dimension_sets": [ @@ -102986,25 +102986,25 @@ }, "test": "lacros_chrome_browsertests_run_in_series", "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests_run_in_series/", - "variant_id": "Lacros version skew testing ash 106.0.5239.0" + "variant_id": "Lacros version skew testing ash 106.0.5249.7" }, { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5259.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5260.0/test_ash_chrome" ], "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 107.0.5259.0", + "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 107.0.5260.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v107.0.5259.0", - "revision": "version:107.0.5259.0" + "location": "lacros_version_skew_tests_v107.0.5260.0", + "revision": "version:107.0.5260.0" } ], "dimension_sets": [ @@ -103017,7 +103017,7 @@ }, "test": "lacros_chrome_browsertests_run_in_series", "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests_run_in_series/", - "variant_id": "Lacros version skew testing ash 107.0.5259.0" + "variant_id": "Lacros version skew testing ash 107.0.5260.0" }, { "merge": { @@ -103795,20 +103795,20 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5239.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5249.7/test_ash_chrome" ], "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "interactive_ui_tests Lacros version skew testing ash 106.0.5239.0", + "name": "interactive_ui_tests Lacros version skew testing ash 106.0.5249.7", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v106.0.5239.0", - "revision": "version:106.0.5239.0" + "location": "lacros_version_skew_tests_v106.0.5249.7", + "revision": "version:106.0.5249.7" } ], "dimension_sets": [ @@ -103821,25 +103821,25 @@ }, "test": "interactive_ui_tests", "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/", - "variant_id": "Lacros version skew testing ash 106.0.5239.0" + "variant_id": "Lacros version skew testing ash 106.0.5249.7" }, { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5259.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5260.0/test_ash_chrome" ], "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "interactive_ui_tests Lacros version skew testing ash 107.0.5259.0", + "name": "interactive_ui_tests Lacros version skew testing ash 107.0.5260.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v107.0.5259.0", - "revision": "version:107.0.5259.0" + "location": "lacros_version_skew_tests_v107.0.5260.0", + "revision": "version:107.0.5260.0" } ], "dimension_sets": [ @@ -103852,7 +103852,7 @@ }, "test": "interactive_ui_tests", "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/", - "variant_id": "Lacros version skew testing ash 107.0.5259.0" + "variant_id": "Lacros version skew testing ash 107.0.5260.0" } ] },
diff --git a/testing/buildbot/chromium.memory.json b/testing/buildbot/chromium.memory.json index 7d0824d..bff85fc 100644 --- a/testing/buildbot/chromium.memory.json +++ b/testing/buildbot/chromium.memory.json
@@ -20831,21 +20831,21 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5239.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5249.7/test_ash_chrome" ], "isolate_profile_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "interactive_ui_tests Lacros version skew testing ash 106.0.5239.0", + "name": "interactive_ui_tests Lacros version skew testing ash 106.0.5249.7", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v106.0.5239.0", - "revision": "version:106.0.5239.0" + "location": "lacros_version_skew_tests_v106.0.5249.7", + "revision": "version:106.0.5249.7" } ], "dimension_sets": [ @@ -20858,26 +20858,26 @@ }, "test": "interactive_ui_tests", "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/", - "variant_id": "Lacros version skew testing ash 106.0.5239.0" + "variant_id": "Lacros version skew testing ash 106.0.5249.7" }, { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5259.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5260.0/test_ash_chrome" ], "isolate_profile_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "interactive_ui_tests Lacros version skew testing ash 107.0.5259.0", + "name": "interactive_ui_tests Lacros version skew testing ash 107.0.5260.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v107.0.5259.0", - "revision": "version:107.0.5259.0" + "location": "lacros_version_skew_tests_v107.0.5260.0", + "revision": "version:107.0.5260.0" } ], "dimension_sets": [ @@ -20890,7 +20890,7 @@ }, "test": "interactive_ui_tests", "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/", - "variant_id": "Lacros version skew testing ash 107.0.5259.0" + "variant_id": "Lacros version skew testing ash 107.0.5260.0" }, { "isolate_profile_data": true, @@ -20997,21 +20997,21 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5239.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5249.7/test_ash_chrome" ], "isolate_profile_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests Lacros version skew testing ash 106.0.5239.0", + "name": "lacros_chrome_browsertests Lacros version skew testing ash 106.0.5249.7", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v106.0.5239.0", - "revision": "version:106.0.5239.0" + "location": "lacros_version_skew_tests_v106.0.5249.7", + "revision": "version:106.0.5249.7" } ], "dimension_sets": [ @@ -21023,26 +21023,26 @@ }, "test": "lacros_chrome_browsertests", "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests/", - "variant_id": "Lacros version skew testing ash 106.0.5239.0" + "variant_id": "Lacros version skew testing ash 106.0.5249.7" }, { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5259.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5260.0/test_ash_chrome" ], "isolate_profile_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests Lacros version skew testing ash 107.0.5259.0", + "name": "lacros_chrome_browsertests Lacros version skew testing ash 107.0.5260.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v107.0.5259.0", - "revision": "version:107.0.5259.0" + "location": "lacros_version_skew_tests_v107.0.5260.0", + "revision": "version:107.0.5260.0" } ], "dimension_sets": [ @@ -21054,7 +21054,7 @@ }, "test": "lacros_chrome_browsertests", "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests/", - "variant_id": "Lacros version skew testing ash 107.0.5259.0" + "variant_id": "Lacros version skew testing ash 107.0.5260.0" }, { "args": [ @@ -21143,21 +21143,21 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5239.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5249.7/test_ash_chrome" ], "isolate_profile_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 106.0.5239.0", + "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 106.0.5249.7", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v106.0.5239.0", - "revision": "version:106.0.5239.0" + "location": "lacros_version_skew_tests_v106.0.5249.7", + "revision": "version:106.0.5249.7" } ], "dimension_sets": [ @@ -21169,26 +21169,26 @@ }, "test": "lacros_chrome_browsertests_run_in_series", "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests_run_in_series/", - "variant_id": "Lacros version skew testing ash 106.0.5239.0" + "variant_id": "Lacros version skew testing ash 106.0.5249.7" }, { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5259.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5260.0/test_ash_chrome" ], "isolate_profile_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 107.0.5259.0", + "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 107.0.5260.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v107.0.5259.0", - "revision": "version:107.0.5259.0" + "location": "lacros_version_skew_tests_v107.0.5260.0", + "revision": "version:107.0.5260.0" } ], "dimension_sets": [ @@ -21200,7 +21200,7 @@ }, "test": "lacros_chrome_browsertests_run_in_series", "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests_run_in_series/", - "variant_id": "Lacros version skew testing ash 107.0.5259.0" + "variant_id": "Lacros version skew testing ash 107.0.5260.0" }, { "isolate_profile_data": true,
diff --git a/testing/buildbot/variants.pyl b/testing/buildbot/variants.pyl index b69115c0..7bd2415 100644 --- a/testing/buildbot/variants.pyl +++ b/testing/buildbot/variants.pyl
@@ -22,30 +22,30 @@ }, 'LACROS_VERSION_SKEW_CANARY': { 'args': [ - '--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5259.0/test_ash_chrome', + '--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5260.0/test_ash_chrome', ], - 'identifier': 'Lacros version skew testing ash 107.0.5259.0', + 'identifier': 'Lacros version skew testing ash 107.0.5260.0', 'swarming': { 'cipd_packages': [ { 'cipd_package': 'chromium/testing/linux-ash-chromium/x86_64/ash.zip', - 'location': 'lacros_version_skew_tests_v107.0.5259.0', - 'revision': 'version:107.0.5259.0', + 'location': 'lacros_version_skew_tests_v107.0.5260.0', + 'revision': 'version:107.0.5260.0', }, ], }, }, 'LACROS_VERSION_SKEW_DEV': { 'args': [ - '--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5239.0/test_ash_chrome', + '--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5249.7/test_ash_chrome', ], - 'identifier': 'Lacros version skew testing ash 106.0.5239.0', + 'identifier': 'Lacros version skew testing ash 106.0.5249.7', 'swarming': { 'cipd_packages': [ { 'cipd_package': 'chromium/testing/linux-ash-chromium/x86_64/ash.zip', - 'location': 'lacros_version_skew_tests_v106.0.5239.0', - 'revision': 'version:106.0.5239.0', + 'location': 'lacros_version_skew_tests_v106.0.5249.7', + 'revision': 'version:106.0.5249.7', }, ], },
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index 6a8dcae..2935166 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -5847,6 +5847,31 @@ ] } ], + "JourneysHaTSSurvey": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "EnabledOmniboxEntrypoint", + "params": { + "en_site_id": "5GjwX6M8T0ugnJ3q1cK0SahkU1Bm", + "probability": "1.0", + "survey": "journeys-omnibox-entrypoint", + "survey-delay-duration": "0s" + }, + "enable_features": [ + "JourneysSurveyForOmniboxEntrypoint" + ] + } + ] + } + ], "JourneysHideSingleDomainClusters": [ { "platforms": [ @@ -6844,6 +6869,30 @@ ] } ], + "OptimizationHintsShorterHostKeyedCacheDuration": [ + { + "platforms": [ + "android", + "chromeos", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled_20220729", + "params": { + "hints_fetch_refresh_duration_in_hours": "1", + "max_store_duration_for_featured_hints_in_days": "1" + }, + "enable_features": [ + "OptimizationHintsFetching" + ] + } + ] + } + ], "OptimizeGeolocationHeaderGeneration": [ { "platforms": [ @@ -9566,6 +9615,26 @@ ] } ], + "ThreadedHtmlTokenizer": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "ThreadedHtmlTokenizer", + "enable_features": [ + "ThreadedHtmlTokenizer" + ] + } + ] + } + ], "ThreadedPreloadScanner": [ { "platforms": [
diff --git a/third_party/android_build_tools/apkanalyzer/3pp/3pp.pb b/third_party/android_build_tools/apkanalyzer/3pp/3pp.pb new file mode 100644 index 0000000..5274a2b --- /dev/null +++ b/third_party/android_build_tools/apkanalyzer/3pp/3pp.pb
@@ -0,0 +1,23 @@ +# Copyright 2022 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +create { + source { + script { + name: "fetch.py" + use_fetch_checkout_workflow: true + } + } + + build { + install: "install.py" + tool: "chromium/third_party/maven" + dep: "chromium/third_party/jdk" + } +} + +upload { + pkg_prefix: "chromium/third_party/android_build_tools" + universal: true +}
diff --git a/third_party/android_build_tools/apkanalyzer/3pp/fetch.py b/third_party/android_build_tools/apkanalyzer/3pp/fetch.py new file mode 100755 index 0000000..2859f1a --- /dev/null +++ b/third_party/android_build_tools/apkanalyzer/3pp/fetch.py
@@ -0,0 +1,62 @@ +#!/usr/bin/env python3 +# Copyright 2022 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# This script is customized based on 3ppFetch.template. + +import argparse +import re +import urllib.request + +_REPO_URL = 'https://dl.google.com/android/maven2' +_GROUP_NAME = 'com/android/tools/apkparser' +_MODULE_NAME = 'apkanalyzer' +_OVERRIDE_LATEST = None +_PATCH_VERSION = 'cr0' + + +def do_latest(): + if _OVERRIDE_LATEST is not None: + print(_OVERRIDE_LATEST + f'.{_PATCH_VERSION}') + return + maven_metadata_url = '{}/{}/{}/maven-metadata.xml'.format( + _REPO_URL, _GROUP_NAME, _MODULE_NAME) + metadata = urllib.request.urlopen(maven_metadata_url).read().decode( + 'utf-8') + # Do not parse xml with the python included parser since it is susceptible + # to maliciously crafted xmls. Only use regular expression parsing to be + # safe. RE should be enough to handle what we need to extract. + match = re.search('<latest>([^<]+)</latest>', metadata) + if match: + latest = match.group(1) + else: + # if no latest info was found just hope the versions are sorted and the + # last one is the latest (as is commonly the case). + latest = re.findall('<version>([^<]+)</version>', metadata)[-1] + print(latest + f'.{_PATCH_VERSION}') + + +def do_checkout(): + # Everything is done in install.py. This method allows us to bypass having + # to download an unnecessary file. + pass + + +def main(): + argparser = argparse.ArgumentParser() + subparser = argparser.add_subparsers() + + latest = subparser.add_parser('latest') + latest.set_defaults(func=do_latest) + + checkout = subparser.add_parser('checkout') + checkout.add_argument('checkout_path') # Needed only to avoid parse error. + checkout.set_defaults(func=do_checkout) + + args = argparser.parse_args() + args.func() + + +if __name__ == '__main__': + main()
diff --git a/third_party/android_build_tools/apkanalyzer/3pp/install.py b/third_party/android_build_tools/apkanalyzer/3pp/install.py new file mode 100755 index 0000000..34c167a --- /dev/null +++ b/third_party/android_build_tools/apkanalyzer/3pp/install.py
@@ -0,0 +1,90 @@ +#!/usr/bin/env python3 +# Copyright 2022 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import os +import shutil +import subprocess +import sys + +_GROUP_ID = 'com.android.tools.apkparser' +_ARTIFACT_ID = 'apkanalyzer' +_FINAL_NAME = 'apkanalyzer.jar' + +_POM_TEMPLATE = """\ +<project> + <modelVersion>4.0.0</modelVersion> + <groupId>group</groupId> + <artifactId>artifact</artifactId> + <version>1</version> + <dependencies> + <dependency> + <groupId>{group_id}</groupId> + <artifactId>{artifact_id}</artifactId> + <version>{version}</version> + <scope>runtime</scope> + </dependency> + </dependencies> + <build> + <plugins> + <plugin> + <artifactId>maven-assembly-plugin</artifactId> + <version>3.3.0</version> + <configuration> + <descriptorRefs> + <descriptorRef>jar-with-dependencies</descriptorRef> + </descriptorRefs> + </configuration> + <executions> + <execution> + <phase>package</phase> + <goals> + <goal>single</goal> + </goals> + </execution> + </executions> + </plugin> + </plugins> + </build> + <repositories> + <repository> + <id>google</id> + <name>google</name> + <url>https://maven.google.com/</url> + </repository> + </repositories> +</project> +""" + + +def main(output_prefix: str, deps_prefix: str): + # Remove the patch version at the end: 30.4.0-alpha05.cr0 => 30.4.0-alpha05 + version = os.environ['_3PP_VERSION'].rsplit('.', 1)[0] + with open('pom.xml', 'w') as f: + f.write( + _POM_TEMPLATE.format(version=version, + group_id=_GROUP_ID, + artifact_id=_ARTIFACT_ID)) + + # Set up JAVA_HOME for the mvn command to find the JDK. + env = os.environ.copy() + env['JAVA_HOME'] = os.path.join(deps_prefix, 'current') + + # Ensure that mvn works and the environment is set up correctly. + subprocess.run(['mvn', '-v'], check=True, env=env) + + # Build the jar file, explicitly specify -f to reduce sources of error. + subprocess.run(['mvn', 'clean', 'assembly:single', '-f', 'pom.xml'], + check=True, + env=env) + + # Move and rename output to the upload directory. Moving only the jar avoids + # polluting the output directory with maven intermediate outputs. + os.makedirs(output_prefix, exist_ok=True) + shutil.move('target/artifact-1-jar-with-dependencies.jar', + os.path.join(output_prefix, _FINAL_NAME)) + + +if __name__ == '__main__': + main(sys.argv[1], sys.argv[2])
diff --git a/third_party/android_build_tools/apkanalyzer/LICENSE b/third_party/android_build_tools/apkanalyzer/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/third_party/android_build_tools/apkanalyzer/LICENSE
@@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License.
diff --git a/third_party/android_build_tools/apkanalyzer/OWNERS b/third_party/android_build_tools/apkanalyzer/OWNERS new file mode 100644 index 0000000..e8bce22 --- /dev/null +++ b/third_party/android_build_tools/apkanalyzer/OWNERS
@@ -0,0 +1,3 @@ +file://build/android/OWNERS + +agrieve@chromium.org
diff --git a/third_party/android_build_tools/apkanalyzer/README.chromium b/third_party/android_build_tools/apkanalyzer/README.chromium new file mode 100644 index 0000000..2c61b08 --- /dev/null +++ b/third_party/android_build_tools/apkanalyzer/README.chromium
@@ -0,0 +1,20 @@ +Name: APK Analyzer +Short Name: apkanalyzer +Version: unknown +License: Apache Version 2.0 +License File: NOT_SHIPPED +Security Critical: No +URL: https://developer.android.com/studio/command-line/apkanalyzer + +Description: +Tool for inspecting .apk files. + +Local Modifications: +None + +What version is this: + * New instances are uploaded by the packager bot: + https://ci.chromium.org/p/chromium/builders/ci/3pp-linux-amd64-packager + * The bot autoruns every 6 hours. Ping a trooper or a clank-build-core@ dev to + trigger it if you need it sooner: + https://luci-scheduler.appspot.com/jobs/chromium/3pp-linux-amd64-packager
diff --git a/third_party/blink/common/features.cc b/third_party/blink/common/features.cc index d4dcdff..8f7fb26 100644 --- a/third_party/blink/common/features.cc +++ b/third_party/blink/common/features.cc
@@ -345,6 +345,11 @@ base::FEATURE_DISABLED_BY_DEFAULT #endif }; + +const base::Feature kSameSiteCrossOriginForSpeculationRulesPrerender{ + "SameSiteCrossOriginForSpeculationRulesPrerender", + base::FEATURE_DISABLED_BY_DEFAULT}; + const char kPrerender2MaxNumOfRunningSpeculationRules[] = "max_num_of_running_speculation_rules"; @@ -358,6 +363,11 @@ return base::FeatureList::IsEnabled(blink::features::kPrerender2); } +bool IsSameSiteCrossOriginForSpeculationRulesPrerender2Enabled() { + return base::FeatureList::IsEnabled( + blink::features::kSameSiteCrossOriginForSpeculationRulesPrerender); +} + bool IsFencedFramesEnabled() { return base::FeatureList::IsEnabled(blink::features::kFencedFrames); }
diff --git a/third_party/blink/common/origin_trials/trial_token_validator_unittest.cc b/third_party/blink/common/origin_trials/trial_token_validator_unittest.cc index 252e89d..6ac9897 100644 --- a/third_party/blink/common/origin_trials/trial_token_validator_unittest.cc +++ b/third_party/blink/common/origin_trials/trial_token_validator_unittest.cc
@@ -465,8 +465,8 @@ base::span<const url::Origin> script_origins, base::Time timestamp) const override { std::vector<TrialTokenValidator::OriginInfo> info; - for (const url::Origin& origin : script_origins) { - info.emplace_back(origin); + for (const url::Origin& script_origin : script_origins) { + info.emplace_back(script_origin); } return validator_.ValidateTokenAndTrialWithOriginInfo( token, TrialTokenValidator::OriginInfo(origin), info, timestamp);
diff --git a/third_party/blink/common/storage_key/storage_key.cc b/third_party/blink/common/storage_key/storage_key.cc index 05e9d92..6139fd31 100644 --- a/third_party/blink/common/storage_key/storage_key.cc +++ b/third_party/blink/common/storage_key/storage_key.cc
@@ -87,12 +87,12 @@ return absl::nullopt; // Otherwise the key is partitioned, let's see what it's partitioned by. - absl::optional<EncodedAttribute> encoded_attribute = + absl::optional<EncodedAttribute> first_attribute = DeserializeAttributeSeparator(in.substr(pos_first_caret, 2)); - if (!encoded_attribute.has_value()) + if (!first_attribute.has_value()) return absl::nullopt; - switch (encoded_attribute.value()) { + switch (first_attribute.value()) { case EncodedAttribute::kTopLevelSite: { // A top-level site is serialized. @@ -113,10 +113,10 @@ !ValidSeparatorWithData(in, pos_last_caret)) return absl::nullopt; - absl::optional<EncodedAttribute> encoded_attribute = + absl::optional<EncodedAttribute> last_attribute = DeserializeAttributeSeparator(in.substr(pos_last_caret, 2)); - if (!encoded_attribute.has_value() || - encoded_attribute.value() != EncodedAttribute::kAncestorChainBit) + if (!last_attribute.has_value() || + last_attribute.value() != EncodedAttribute::kAncestorChainBit) return absl::nullopt; // The ancestor_chain_bit is the portion beyond the last separator. @@ -157,10 +157,10 @@ !ValidSeparatorWithData(in, pos_second_caret)) return absl::nullopt; - absl::optional<EncodedAttribute> encoded_attribute = + absl::optional<EncodedAttribute> second_attribute = DeserializeAttributeSeparator(in.substr(pos_second_caret, 2)); - if (!encoded_attribute.has_value() || - encoded_attribute.value() != EncodedAttribute::kNonceLow) + if (!second_attribute.has_value() || + second_attribute.value() != EncodedAttribute::kNonceLow) return absl::nullopt; // The origin is the portion up to, but not including, the first
diff --git a/third_party/blink/public/common/features.h b/third_party/blink/public/common/features.h index 525d1d3..41834ff 100644 --- a/third_party/blink/public/common/features.h +++ b/third_party/blink/public/common/features.h
@@ -168,8 +168,15 @@ // pages will not be prerendered even when kPrerender2 is enabled. BLINK_COMMON_EXPORT extern const char kPrerender2MemoryAcceptablePercentOfSystemMemoryParamName[]; +// Enables same-site cross origin Prerender2 +BLINK_COMMON_EXPORT extern const base::Feature + kSameSiteCrossOriginForSpeculationRulesPrerender; // Returns true when Prerender2 feature is enabled. BLINK_COMMON_EXPORT bool IsPrerender2Enabled(); +// Returns true when the same-site cross origin Prerender2 feature is +// enabled. +BLINK_COMMON_EXPORT bool +IsSameSiteCrossOriginForSpeculationRulesPrerender2Enabled(); // Fenced Frames: BLINK_COMMON_EXPORT bool IsFencedFramesEnabled();
diff --git a/third_party/blink/public/web/web_local_frame.h b/third_party/blink/public/web/web_local_frame.h index e9a2fa8..46df0f6e 100644 --- a/third_party/blink/public/web/web_local_frame.h +++ b/third_party/blink/public/web/web_local_frame.h
@@ -847,13 +847,19 @@ // page-orientation. virtual gfx::Size SpoolSizeInPixelsForTesting( const gfx::Size& page_size_in_pixels, + const WebVector<uint32_t>& pages) = 0; + virtual gfx::Size SpoolSizeInPixelsForTesting( + const gfx::Size& page_size_in_pixels, uint32_t page_count) = 0; - // Prints the frame into the canvas, with page boundaries drawn as one pixel - // wide blue lines. This method exists to support web tests. - virtual void PrintPagesForTesting(cc::PaintCanvas*, - const gfx::Size& page_size_in_pixels, - const gfx::Size& spool_size_in_pixels) = 0; + // Prints the given pages of the frame into the canvas, with page boundaries + // drawn as one pixel wide blue lines. By default, all pages are printed. This + // method exists to support web tests. + virtual void PrintPagesForTesting( + cc::PaintCanvas*, + const gfx::Size& page_size_in_pixels, + const gfx::Size& spool_size_in_pixels, + const WebVector<uint32_t>* pages = nullptr) = 0; // Returns the bounds rect for current selection. If selection is performed // on transformed text, the rect will still bound the selection but will
diff --git a/third_party/blink/renderer/bindings/core/v8/v8_metrics.cc b/third_party/blink/renderer/bindings/core/v8/v8_metrics.cc index 3a2463c..1adcb0d 100644 --- a/third_party/blink/renderer/bindings/core/v8/v8_metrics.cc +++ b/third_party/blink/renderer/bindings/core/v8/v8_metrics.cc
@@ -321,9 +321,9 @@ // Report efficacy metrics: DEFINE_THREAD_SAFE_STATIC_LOCAL( - CustomCountHistogram, efficacy_histogram, + CustomCountHistogram, efficacy_cpp_histogram, ("V8.GC.Cycle.Efficiency.Full.Cpp", kMinSize, kMaxSize, kNumBuckets)); - efficacy_histogram.Count( + efficacy_cpp_histogram.Count( CappedEfficacyInKBPerMs(event.efficiency_cpp_in_bytes_per_us)); DEFINE_THREAD_SAFE_STATIC_LOCAL( @@ -334,9 +334,9 @@ event.main_thread_efficiency_cpp_in_bytes_per_us)); DEFINE_THREAD_SAFE_STATIC_LOCAL( - CustomCountHistogram, collection_rate_histogram, + CustomCountHistogram, collection_rate_cpp_histogram, ("V8.GC.Cycle.CollectionRate.Full.Cpp", 1, 100, 20)); - collection_rate_histogram.Count( + collection_rate_cpp_histogram.Count( base::saturated_cast<base::Histogram::Sample>( 100 * event.collection_rate_cpp_in_percent)); }
diff --git a/third_party/blink/renderer/core/editing/commands/apply_block_element_command_test.cc b/third_party/blink/renderer/core/editing/commands/apply_block_element_command_test.cc index 1617bab..a005156 100644 --- a/third_party/blink/renderer/core/editing/commands/apply_block_element_command_test.cc +++ b/third_party/blink/renderer/core/editing/commands/apply_block_element_command_test.cc
@@ -230,7 +230,7 @@ "<blockquote style=\"margin: 0 0 0 40px; border: none; padding: 0px;\">" "<svg><foreignObject><table>| </table></foreignObject></svg>" "</blockquote>" - "<svg><foreignObject>x</foreignObject></svg>", + "<svg><foreignObject> x</foreignObject></svg>", GetSelectionTextFromBody()); }
diff --git a/third_party/blink/renderer/core/editing/commands/apply_style_command_test.cc b/third_party/blink/renderer/core/editing/commands/apply_style_command_test.cc index 9e8ebfa..c61b5873 100644 --- a/third_party/blink/renderer/core/editing/commands/apply_style_command_test.cc +++ b/third_party/blink/renderer/core/editing/commands/apply_style_command_test.cc
@@ -128,11 +128,10 @@ ->Apply(); EXPECT_EQ( "<svg>" - "<foreignObject>" - "<div style=\"text-align: right;\">|1</div>" + "<foreignObject>|1" "</foreignObject>" "<foreignObject>" - "<div style=\"text-align: right;\">2</div><b></b>" + " 2<b></b>" "</foreignObject>" "</svg>", GetSelectionTextFromBody());
diff --git a/third_party/blink/renderer/core/editing/visible_units.cc b/third_party/blink/renderer/core/editing/visible_units.cc index f8db64d..abaffb1 100644 --- a/third_party/blink/renderer/core/editing/visible_units.cc +++ b/third_party/blink/renderer/core/editing/visible_units.cc
@@ -625,6 +625,17 @@ position.AnchorNode(), Strategy::CaretMaxOffset(*position.AnchorNode())); } +static bool CanHaveCaretPosition(const Node& node) { + if (!node.IsSVGElement()) + return true; + if (IsA<SVGTextElement>(node)) + return true; // See http://crbug.com/891908 + if (IsA<SVGForeignObjectElement>(node)) + return true; // See http://crbug.com/1348816 + // There is no caret position in non-text svg elements. + return false; +} + // TODO(yosin): We should make |Most{Back,For}kwardCaretPosition()| to work for // positions other than |kOffsetInAnchor|. When we convert |position| to // |kOffsetInAnchor|, following tests are failed: @@ -678,8 +689,7 @@ last_node = current_node; } - // There is no caret position in non-text svg elements. - if (current_node->IsSVGElement() && !IsA<SVGTextElement>(current_node)) { + if (!CanHaveCaretPosition(*current_node)) { if (boundary_crossed && rule == kCannotCrossEditingBoundary) break; continue; @@ -853,8 +863,7 @@ if (IsA<HTMLBodyElement>(*current_node) && current_pos.AtEndOfNode()) break; - // There is no caret position in non-text svg elements. - if (current_node->IsSVGElement() && !IsA<SVGTextElement>(current_node)) { + if (!CanHaveCaretPosition(*current_node)) { if (boundary_crossed && rule == kCannotCrossEditingBoundary) break; continue;
diff --git a/third_party/blink/renderer/core/editing/visible_units_test.cc b/third_party/blink/renderer/core/editing/visible_units_test.cc index 12c6590..a600c6a5 100644 --- a/third_party/blink/renderer/core/editing/visible_units_test.cc +++ b/third_party/blink/renderer/core/editing/visible_units_test.cc
@@ -493,6 +493,30 @@ MostBackwardCaretPosition(PositionInFlatTree::AfterNode(*host))); } +// http://crbug.com/1348816 +TEST_F(VisibleUnitsTest, MostBackwardCaretPositionBeforeSvg) { + EXPECT_EQ( + "<div>A<svg><foreignObject height=\"10\" width=\"20\">| " + "Z</foreignObject></svg></div>", + TestSnapBackward("<div>A<svg><foreignObject height=10 width=20> " + "|Z</foreignObject></svg></div>")); +} + +// http://crbug.com/1348816 +TEST_F(VisibleUnitsTest, MostForwardCaretPositionBeforeSvg) { + EXPECT_EQ( + "<div>A|<svg><foreignObject height=\"10\" width=\"20\"> " + "Z</foreignObject></svg></div>", + TestSnapForward("<div>A|<svg><foreignObject height=10 width=20> " + "Z</foreignObject></svg></div>")); + + EXPECT_EQ( + "<div>A<svg><foreignObject height=\"10\" width=\"20\"> " + "|Z</foreignObject></svg></div>", + TestSnapForward("<div>A<svg><foreignObject height=10 width=20>| " + "Z</foreignObject></svg></div>")); +} + TEST_F(VisibleUnitsTest, mostForwardCaretPositionFirstLetter) { // Note: first-letter pseudo element contains letter and punctuations. const char* body_content =
diff --git a/third_party/blink/renderer/core/frame/attribution_response_parsing.cc b/third_party/blink/renderer/core/frame/attribution_response_parsing.cc index ab60832..b36418a 100644 --- a/third_party/blink/renderer/core/frame/attribution_response_parsing.cc +++ b/third_party/blink/renderer/core/frame/attribution_response_parsing.cc
@@ -292,18 +292,15 @@ mojom::blink::EventTriggerDataPtr event_trigger = mojom::blink::EventTriggerData::New(); - String trigger_data_string; - // A valid header must declare data for each sub-item. - if (!object_val->GetString("trigger_data", &trigger_data_string)) - return false; - bool trigger_data_is_valid = false; - uint64_t trigger_data_value = - trigger_data_string.ToUInt64Strict(&trigger_data_is_valid); + // Treat invalid trigger data, priority and deduplication key as if they + // were not set. - // Default invalid data values to 0 so a report will get sent. - event_trigger->data = trigger_data_is_valid ? trigger_data_value : 0; - - // Treat invalid priority and deduplication key as if they were not set. + if (String s; object_val->GetString("trigger_data", &s)) { + bool valid = false; + uint64_t trigger_data = s.ToUInt64Strict(&valid); + if (valid) + event_trigger->data = trigger_data; + } if (String s; object_val->GetString("priority", &s)) { bool valid = false;
diff --git a/third_party/blink/renderer/core/frame/attribution_response_parsing_test.cc b/third_party/blink/renderer/core/frame/attribution_response_parsing_test.cc index a71fa70..c06e32e3 100644 --- a/third_party/blink/renderer/core/frame/attribution_response_parsing_test.cc +++ b/third_party/blink/renderer/core/frame/attribution_response_parsing_test.cc
@@ -925,14 +925,28 @@ { "missing_trigger_data", ParseJSON(R"json([{}])json"), - false, - {}, + true, + VectorBuilder<mojom::blink::EventTriggerDataPtr>() + .Add(mojom::blink::EventTriggerData::New( + /*data=*/0, + /*priority=*/0, + /*dedup_key=*/nullptr, + /*filters=*/AttributionFilterDataBuilder().Build(), + /*not_filters=*/AttributionFilterDataBuilder().Build())) + .Build(), }, { "trigger_data_not_string", ParseJSON(R"json([{"trigger_data": 1}])json"), - false, - {}, + true, + VectorBuilder<mojom::blink::EventTriggerDataPtr>() + .Add(mojom::blink::EventTriggerData::New( + /*data=*/0, + /*priority=*/0, + /*dedup_key=*/nullptr, + /*filters=*/AttributionFilterDataBuilder().Build(), + /*not_filters=*/AttributionFilterDataBuilder().Build())) + .Build(), }, { "invalid_trigger_data",
diff --git a/third_party/blink/renderer/core/frame/build.gni b/third_party/blink/renderer/core/frame/build.gni index cfba452..62d5e74b 100644 --- a/third_party/blink/renderer/core/frame/build.gni +++ b/third_party/blink/renderer/core/frame/build.gni
@@ -284,6 +284,7 @@ "mhtml_archive_test.cc", "mhtml_loading_test.cc", "performance_monitor_test.cc", + "pending_beacon_dispatcher_test.cc", "policy_container_test.cc", "report_test.cc", "reporting_context_test.cc",
diff --git a/third_party/blink/renderer/core/frame/local_frame_view.cc b/third_party/blink/renderer/core/frame/local_frame_view.cc index 9235314..98b8f7c 100644 --- a/third_party/blink/renderer/core/frame/local_frame_view.cc +++ b/third_party/blink/renderer/core/frame/local_frame_view.cc
@@ -846,6 +846,8 @@ !document->GetDisplayLockDocumentState().HasForcedScopes()); DeferredShapingViewportScope viewport_scope(*this, *GetLayoutView()); GetLayoutView()->UpdateLayout(); + if (mobile_friendliness_checker_) + mobile_friendliness_checker_->NotifyInitialScaleUpdated(); } } @@ -1032,9 +1034,6 @@ void LocalFrameView::RunPostLifecycleSteps() { AllowThrottlingScope allow_throttling(*this); RunIntersectionObserverSteps(); - if (mobile_friendliness_checker_) - mobile_friendliness_checker_->MaybeRecompute(); - ForAllRemoteFrameViews([](RemoteFrameView& frame_view) { frame_view.UpdateCompositingScaleFactor(); }); @@ -2004,6 +2003,9 @@ } void LocalFrameView::WillBeRemovedFromFrame() { + if (mobile_friendliness_checker_) + mobile_friendliness_checker_->WillBeRemovedFromFrame(); + if (paint_artifact_compositor_) paint_artifact_compositor_->WillBeRemovedFromFrame();
diff --git a/third_party/blink/renderer/core/frame/pending_beacon.cc b/third_party/blink/renderer/core/frame/pending_beacon.cc index dcaf228..3f78409 100644 --- a/third_party/blink/renderer/core/frame/pending_beacon.cc +++ b/third_party/blink/renderer/core/frame/pending_beacon.cc
@@ -4,10 +4,10 @@ #include "third_party/blink/renderer/core/frame/pending_beacon.h" +#include "base/task/single_thread_task_runner.h" #include "base/time/time.h" #include "third_party/blink/public/common/features.h" #include "third_party/blink/public/mojom/frame/pending_beacon.mojom-blink.h" -#include "third_party/blink/public/platform/task_type.h" #include "third_party/blink/public/platform/web_url_request_util.h" #include "third_party/blink/renderer/core/execution_context/execution_context.h" #include "third_party/blink/renderer/core/frame/pending_beacon_dispatcher.h" @@ -19,6 +19,28 @@ #include "third_party/blink/renderer/platform/weborigin/kurl.h" namespace blink { +namespace { + +// Internally enforces a time limit to send out pending beacons when using +// background timeout. +// +// When the page is in hidden state, beacons will be sent out no later than +// min(Time evicted from back/forward cache, +// `kDefaultPendingBeaconMaxBackgroundTimeout`). +// Note that this is currently longer than back/forward cache entry's TTL. +// See https://github.com/WICG/unload-beacon/issues/3 +constexpr base::TimeDelta kDefaultPendingBeaconMaxBackgroundTimeout = + base::Minutes(30); // 30 minutes + +// Returns a max possible background timeout for every pending beacon. +base::TimeDelta GetMaxBackgroundTimeout() { + return base::Milliseconds(GetFieldTrialParamByFeatureAsInt( + features::kPendingBeaconAPI, "PendingBeaconMaxBackgroundTimeoutInMs", + base::checked_cast<int32_t>( + kDefaultPendingBeaconMaxBackgroundTimeout.InMilliseconds()))); +} + +} // namespace PendingBeacon::PendingBeacon(ExecutionContext* ec, const String& url, @@ -30,7 +52,7 @@ url_(url), method_(method), background_timeout_(base::Milliseconds(background_timeout)), - timeout_(base::Milliseconds(timeout)) { + timeout_timer_(GetTaskRunner(), this, &PendingBeacon::TimeoutTimerFired) { // Creates a corresponding instance of PendingBeacon in the browser process // and binds `remote_` to it. mojom::blink::BeaconMethod host_method; @@ -40,27 +62,33 @@ host_method = mojom::blink::BeaconMethod::kPost; } - auto task_runner = ec_->GetTaskRunner(PendingBeaconDispatcher::kTaskType); mojo::PendingReceiver<mojom::blink::PendingBeacon> beacon_receiver = - remote_.BindNewPipeAndPassReceiver(task_runner); + remote_.BindNewPipeAndPassReceiver(GetTaskRunner()); KURL host_url = ec_->CompleteURL(url); PendingBeaconDispatcher& dispatcher = PendingBeaconDispatcher::FromOrAttachTo(*ec_); - dispatcher.CreateHostBeacon(std::move(beacon_receiver), host_url, + dispatcher.CreateHostBeacon(this, std::move(beacon_receiver), host_url, host_method); + // May trigger beacon sending immediately. + setTimeout(timeout); } void PendingBeacon::Trace(Visitor* visitor) const { ScriptWrappable::Trace(visitor); visitor->Trace(ec_); visitor->Trace(remote_); + visitor->Trace(timeout_timer_); } void PendingBeacon::deactivate() { if (pending_) { remote_->Deactivate(); pending_ = false; + + auto* dispatcher = PendingBeaconDispatcher::From(*ec_); + DCHECK(dispatcher); + dispatcher->Unregister(this); } } @@ -68,6 +96,10 @@ if (pending_) { remote_->SendNow(); pending_ = false; + + auto* dispatcher = PendingBeaconDispatcher::From(*ec_); + DCHECK(dispatcher); + dispatcher->Unregister(this); } } @@ -77,6 +109,18 @@ void PendingBeacon::setTimeout(int32_t timeout) { timeout_ = base::Milliseconds(timeout); + if (timeout_.is_negative() || !pending_) { + return; + } + + // TODO(crbug.com/3774273): Use the nullity of data & url to decide whether + // beacon should be sent. + // https://github.com/WICG/unload-beacon/issues/17#issuecomment-1198871880 + + // If timeout >= 0, the timer starts immediately after its value is set or + // updated. + // https://github.com/WICG/unload-beacon/blob/main/README.md#properties + timeout_timer_.StartOneShot(timeout_, FROM_HERE); } void PendingBeacon::SetURLInternal(const String& url) { @@ -108,4 +152,24 @@ content_type.IsNull() ? "" : content_type); } +base::TimeDelta PendingBeacon::GetBackgroundTimeout() const { + const auto max_background_timeout = GetMaxBackgroundTimeout(); + return (background_timeout_.is_negative() || + background_timeout_ > max_background_timeout) + ? max_background_timeout + : background_timeout_; +} + +void PendingBeacon::Send() { + sendNow(); +} + +scoped_refptr<base::SingleThreadTaskRunner> PendingBeacon::GetTaskRunner() { + return ec_->GetTaskRunner(PendingBeaconDispatcher::kTaskType); +} + +void PendingBeacon::TimeoutTimerFired(TimerBase*) { + sendNow(); +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/frame/pending_beacon.h b/third_party/blink/renderer/core/frame/pending_beacon.h index d125ce9..eab1d0e 100644 --- a/third_party/blink/renderer/core/frame/pending_beacon.h +++ b/third_party/blink/renderer/core/frame/pending_beacon.h
@@ -7,8 +7,11 @@ #include "third_party/blink/public/mojom/frame/pending_beacon.mojom-blink.h" #include "third_party/blink/renderer/core/core_export.h" +#include "third_party/blink/renderer/core/execution_context/execution_context.h" +#include "third_party/blink/renderer/core/frame/pending_beacon_dispatcher.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" #include "third_party/blink/renderer/platform/mojo/heap_mojo_remote.h" +#include "third_party/blink/renderer/platform/timer.h" namespace blink { @@ -18,7 +21,15 @@ // Implementation of the PendingBeacon API. // https://github.com/WICG/unload-beacon/blob/main/README.md -class CORE_EXPORT PendingBeacon : public ScriptWrappable { +// Note that the lifetime of a PendingBeacon instance is not the same as the JS +// scope where the instance is created. Rather, it stays alive until +// - roughly when `sendNow()` or `deactivate()` is called (may still be alive +// for a while after this point). +// - when the document where it was created is destroyed. +// See `PendingBeaconDispatcher` for more details. +class CORE_EXPORT PendingBeacon + : public ScriptWrappable, + public PendingBeaconDispatcher::PendingBeacon { DEFINE_WRAPPERTYPEINFO(); public: @@ -44,6 +55,10 @@ void Trace(Visitor*) const override; + // `PendingBeaconDispatcher::PendingBeacon` implementation. + base::TimeDelta GetBackgroundTimeout() const override; + void Send() override; + protected: explicit PendingBeacon(ExecutionContext* context, const String& url, @@ -56,6 +71,11 @@ ExceptionState& exception_state); private: + // A convenient method to return a TaskRunner which is able to keep working + // even if the JS context is frozen. + scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner(); + void TimeoutTimerFired(TimerBase*); + Member<ExecutionContext> ec_; HeapMojoRemote<mojom::blink::PendingBeacon> remote_; String url_; @@ -63,6 +83,9 @@ base::TimeDelta background_timeout_; base::TimeDelta timeout_; bool pending_ = true; + + // A timer to handle `setTimeout()`. + HeapTaskRunnerTimer<PendingBeacon> timeout_timer_; }; } // namespace blink
diff --git a/third_party/blink/renderer/core/frame/pending_beacon_dispatcher.cc b/third_party/blink/renderer/core/frame/pending_beacon_dispatcher.cc index 1456478..777921b9b 100644 --- a/third_party/blink/renderer/core/frame/pending_beacon_dispatcher.cc +++ b/third_party/blink/renderer/core/frame/pending_beacon_dispatcher.cc
@@ -5,28 +5,42 @@ #include "third_party/blink/renderer/core/frame/pending_beacon_dispatcher.h" #include <algorithm> +#include <functional> +#include "base/numerics/safe_conversions.h" +#include "base/ranges/algorithm.h" #include "third_party/blink/public/platform/task_type.h" #include "third_party/blink/renderer/core/execution_context/execution_context.h" -#include "third_party/blink/renderer/platform/heap/collection_support/heap_hash_counted_set.h" +#include "third_party/blink/renderer/core/frame/local_dom_window.h" +#include "third_party/blink/renderer/core/page/page.h" namespace blink { +namespace { + +// Bundles beacons and sends them out to reduce the number of timer callback +// triggered. A bundle has beacons fall within the same 100x milliseconds. +// Spec says: The beacon is not guaranteed to be sent at exactly this many +// milliseconds after hidden; bundling/batching of beacons is possible. +// https://github.com/WICG/unload-beacon/blob/main/README.md#properties +constexpr base::TimeDelta kBeaconTimeoutInterval = base::Milliseconds(100); + +struct ReverseBeaconTimeoutSorter { + constexpr bool operator()( + const Member<PendingBeaconDispatcher::PendingBeacon>& lhs, + const Member<PendingBeaconDispatcher::PendingBeacon>& rhs) { + // Negative timeout is not accepted. + DCHECK(!lhs->GetBackgroundTimeout().is_negative()); + DCHECK(!rhs->GetBackgroundTimeout().is_negative()); + return lhs->GetBackgroundTimeout() > rhs->GetBackgroundTimeout(); + } +}; + +} // namespace // static const char PendingBeaconDispatcher::kSupplementName[] = "PendingBeaconDispatcher"; -PendingBeaconDispatcher::PendingBeaconDispatcher( - ExecutionContext& ec, - base::PassKey<PendingBeaconDispatcher> key) - : Supplement(ec), remote_(&ec) { - auto task_runner = ec.GetTaskRunner(kTaskType); - - mojo::PendingReceiver<mojom::blink::PendingBeaconHost> host_receiver = - remote_.BindNewPipeAndPassReceiver(task_runner); - ec.GetBrowserInterfaceBroker().GetInterface(std::move(host_receiver)); -} - // static PendingBeaconDispatcher& PendingBeaconDispatcher::FromOrAttachTo( ExecutionContext& ec) { @@ -45,16 +59,224 @@ return Supplement::From<PendingBeaconDispatcher>(ec); } +PendingBeaconDispatcher::PendingBeaconDispatcher( + ExecutionContext& ec, + base::PassKey<PendingBeaconDispatcher> key) + : Supplement(ec), + ExecutionContextLifecycleObserver(&ec), + PageVisibilityObserver(DomWindow() ? DomWindow()->GetFrame()->GetPage() + : nullptr), + remote_(&ec) { + auto task_runner = ec.GetTaskRunner(kTaskType); + + mojo::PendingReceiver<mojom::blink::PendingBeaconHost> host_receiver = + remote_.BindNewPipeAndPassReceiver(task_runner); + ec.GetBrowserInterfaceBroker().GetInterface(std::move(host_receiver)); +} + void PendingBeaconDispatcher::CreateHostBeacon( + PendingBeacon* pending_beacon, mojo::PendingReceiver<mojom::blink::PendingBeacon> receiver, const KURL& url, mojom::blink::BeaconMethod method) { + DCHECK(!pending_beacons_.Contains(pending_beacon)); + pending_beacons_.insert(pending_beacon); + remote_->CreateBeacon(std::move(receiver), url, method); } +void PendingBeaconDispatcher::Unregister(PendingBeacon* pending_beacon) { + pending_beacons_.erase(pending_beacon); +} + +void PendingBeaconDispatcher::ContextDestroyed() { + // Cancels all pending tasks when the Document is destroyed. + // The browser will take over the responsibility. + CancelDispatchBeacons(); + + pending_beacons_.clear(); +} + +void PendingBeaconDispatcher::PageVisibilityChanged() { + DCHECK(GetPage()); + + // Handles a PendingBeacon's `backgroundTimeout` properties. + // https://github.com/WICG/unload-beacon/blob/main/README.md#properties + if (GetPage()->IsPageVisible()) { + // The timer should be reset if the page enters `visible` visibility state + // before the `backgroundTimeout` expires. + CancelDispatchBeacons(); + } else { + // The timer should start after the page enters `hidden` visibility state. + ScheduleDispatchBeacons(); + } +} + +void PendingBeaconDispatcher::ScheduleDispatchBeacons() { + if (pending_beacons_.IsEmpty()) { + return; + } + + // Example: + // + // `pending_beacons_`'s content: + // ---------------------------------------------------- + // | [0] | [1] | [2] | [3] | [4] | [5] | [6] | + // |--------------------------------------------------- + // | 100ms | 201ms | 99ms | 0ms | 101ms | 1ms | 500ms | + // |--------------------------------------------------- + // + // `background_timeout_descending_beacons_` is empty on entering this method, + // but will be populated with: + // + // ---------------------------------------------------- + // | [0] | [1] | [2] | [3] | [4] | [5] | [6] | + // |--------------------------------------------------- + // | 500ms | 201ms | 101ms | 100ms | 99ms | 1ms | 0ms | + // |--------------------------------------------------- + // + CopyToVector(pending_beacons_, background_timeout_descending_beacons_); + std::sort(background_timeout_descending_beacons_.begin(), + background_timeout_descending_beacons_.end(), + ReverseBeaconTimeoutSorter()); + previous_delayed_ = base::Microseconds(0); + + ScheduleDispatchNextBundledBeacons(); +} + +void PendingBeaconDispatcher::ScheduleDispatchNextBundledBeacons() { + if (background_timeout_descending_beacons_.IsEmpty()) { + return; + } + + // Prepares a task to send out next bundle of beacons from the tail of + // `background_timeout_descending_beacons_`. + // The beacons with backgroundTimeout falls into the same interval, + // `kBeaconTimeoutInterval`, are indicated by [`start_index`, end). + // + // Using the same example from within `ScheduleDispatchBeacons()`: + // - Bundle 1: + // - `start_index` = [4], end = [7] + // - `delayed` = 99ms + // - `previous_delayed_` = 0ms => 99ms + // - Bundle 2: + // - `start_index` = [2], end = [4] + // - `delayed` = 2ms + // - `previous_delayed_` = 99ms => 101ms + // - Bundle 3: + // - `start_index` = [1], end = [2] + // - `delayed` = 100ms + // - `previous_delayed_` = 101ms => 201ms + // - Bundle 4: + // - `start_index` = [0], end = [1] + // - `delayed` = 299ms + // - `previous_delayed_` = 201ms => 500ms + auto task_runner = GetTaskRunner(); + const auto start_index = GetStartIndexForNextBundledBeacons(); + const auto delayed = background_timeout_descending_beacons_[start_index] + ->GetBackgroundTimeout() - + previous_delayed_; + DCHECK(!delayed.is_negative()); + previous_delayed_ += delayed; + // Uses `WrapWeakPersistent(this)` because if the associated Document is + // destroyed, the browser process should be responsible for sending out and + // destroy all queued beacons, which will unbound the receivers. In such case, + // this class and members should not outlive the Document (ExecutionContext). + task_handle_ = PostNonNestableDelayedCancellableTask( + *task_runner, FROM_HERE, + WTF::Bind(&PendingBeaconDispatcher::OnDispatchBeaconsAndRepeat, + WrapWeakPersistent(this), start_index), + delayed); +} + +void PendingBeaconDispatcher::OnDispatchBeaconsAndRepeat( + wtf_size_t start_index) { + DCHECK(start_index < background_timeout_descending_beacons_.size()); + + // Dispatches all beacons within the same bundle. + for (auto i = start_index; i < background_timeout_descending_beacons_.size(); + i++) { + auto beacon = background_timeout_descending_beacons_[i]; + beacon->Send(); + } + background_timeout_descending_beacons_.resize(start_index); + + // Schedules the next bundle of beacons to dispatch. + ScheduleDispatchNextBundledBeacons(); +} + +wtf_size_t PendingBeaconDispatcher::GetStartIndexForNextBundledBeacons() const { + DCHECK(background_timeout_descending_beacons_.size()); + if (background_timeout_descending_beacons_.size() == 1) { + return 0; + } + + // Locates an index `i` (or the returned value) such that the range + // [`i`, `background_timeout_descending_beacons_.size()`) contains the beacons + // with their background timeout values fall in the range + // [`floor_timeout`, `ceiling_timeout`), where (`ceiling_timeout` - 1ms) is + // the maximum background timeout which represents this bundle and will be + // used in scheduling. + // `floor_timeout` is the background timeout from the first beacon of this + // bundle. + // + // Using the same example from within `ScheduleDispatchBeacons()`: + // - Bundle 1: + // - `floor_timeout` = 0ms + // - `ceiling_timeout` = 100ms + // - returned index = [4] + // - Bundle 2: + // - `floor_timeout` = 100ms + // - `ceiling_timeout` = 200ms + // - returned index = [2] + // - Bundle 3: + // - `floor_timeout` = 201ms + // - `ceiling_timeout` = 300ms (not 301ms) + // - returned index = [1] + // - Bundle 4: + // - `floor_timeout` = 500ms + // - `ceiling_timeout` = 600ms + // - returned index = [0] + const auto floor_timeout = + background_timeout_descending_beacons_.back()->GetBackgroundTimeout(); + // Rounds the the nearest 100x ms. + const auto ceiling_timeout = + (floor_timeout + kBeaconTimeoutInterval).IntDiv(kBeaconTimeoutInterval) * + kBeaconTimeoutInterval; + // Locates the first element such that + // element.backgroundTimeout >= ceiling_timeout is false. + const auto* const it = base::ranges::lower_bound( + background_timeout_descending_beacons_, ceiling_timeout, + std::greater_equal(), + [](const Member<PendingBeaconDispatcher::PendingBeacon>& b) { + return b->GetBackgroundTimeout(); + }); + // The element with `floor_timeout`, i.e. last element, guarantees the + // existence of `it`. + return base::checked_cast<wtf_size_t>( + std::distance(background_timeout_descending_beacons_.begin(), it)); +} + +void PendingBeaconDispatcher::CancelDispatchBeacons() { + // Tasks must be canceled before clearing beacon references. + task_handle_.Cancel(); + previous_delayed_ = base::Milliseconds(0); + background_timeout_descending_beacons_.clear(); +} + +scoped_refptr<base::SingleThreadTaskRunner> +PendingBeaconDispatcher::GetTaskRunner() { + DCHECK(GetSupplementable()); + return GetSupplementable()->GetTaskRunner(kTaskType); +} + void PendingBeaconDispatcher::Trace(Visitor* visitor) const { Supplement::Trace(visitor); + ExecutionContextLifecycleObserver::Trace(visitor); + PageVisibilityObserver::Trace(visitor); visitor->Trace(remote_); + visitor->Trace(pending_beacons_); + visitor->Trace(background_timeout_descending_beacons_); } } // namespace blink
diff --git a/third_party/blink/renderer/core/frame/pending_beacon_dispatcher.h b/third_party/blink/renderer/core/frame/pending_beacon_dispatcher.h index a8b2f7b..f6e6959 100644 --- a/third_party/blink/renderer/core/frame/pending_beacon_dispatcher.h +++ b/third_party/blink/renderer/core/frame/pending_beacon_dispatcher.h
@@ -5,11 +5,17 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_PENDING_BEACON_DISPATCHER_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_PENDING_BEACON_DISPATCHER_H_ +#include "base/time/time.h" #include "base/types/pass_key.h" #include "third_party/blink/public/mojom/frame/pending_beacon.mojom-blink.h" #include "third_party/blink/renderer/core/core_export.h" +#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h" +#include "third_party/blink/renderer/core/page/page_visibility_observer.h" +#include "third_party/blink/renderer/platform/heap/collection_support/heap_hash_set.h" +#include "third_party/blink/renderer/platform/heap/collection_support/heap_vector.h" #include "third_party/blink/renderer/platform/heap/garbage_collected.h" #include "third_party/blink/renderer/platform/mojo/heap_mojo_remote.h" +#include "third_party/blink/renderer/platform/scheduler/public/post_cancellable_task.h" #include "third_party/blink/renderer/platform/supplementable.h" namespace blink { @@ -17,12 +23,26 @@ class ExecutionContext; class KURL; -// `PendingBeaconDispatcher` helps the caller connect to a `blink::Document`'s -// PendingBeaconHost by wrapping a shared HeapMojoRemote `remote_` that connects -// to a PendingBeaconHost instance running in the browser. +// `PendingBeaconDispatcher` connects a renderer `PendingBeacon` to its browser +// counterpart. // -// Every PendingBeacon from the same Document should use this class to make -// calls to the corresponding PendingBeaconHost. +// It supports the following requests: +// +// (1) Create browser-side PendingBeacon: +// On constructed, every `PendingBeacon` from the same Document should call +// `CreateHostBeacon()` to make calls to the corresponding +// PendingBeaconHost, and to register itself within this dispatcher. +// +// (2) Dispatch every registered `PendingBeacon` on its background timeout. +// Implicitly triggered when the page enters `hidden` state within +// `PageVisibilityChanged()`. In such case, it schedules a series of tasks +// to send out every beacons according to their individual background +// timeouts. If the page enters `visible` state, all the pending tasks will +// be canceled. +// See `ScheduleDispatchBeacons()` for the actual scheduling algorithm. +// +// Internally, it connects to a `blink::Document`'s corresponding +// PendingBeaconHost instance running in the browser via `remote_`. // // PendingBeaconDispatcher is only created and attached to an ExecutionContext // lazily by `PendingBeaconDispatcher::FromOrAttachTo()` if a PendingBeacon is @@ -31,30 +51,48 @@ // The lifetime of PendingBeaconDispatcher is the same as the ExecutionContext // it is attached to. // -// TODO(crbug.com/1293679): Implement dispatching beacons on timeout. -// TODO(crbug.com/1293679): Implement dispatching beacons on (page hidden + -// backgroundTimeout) msec. +// Example: +// // Accesses an instance of this class within a document. +// auto& dispatcher = PendingBeaconDispatcher::FromOrAttachTo(ec); +// +// // When creating a renderer-side PendingBeacon, also call the following +// // to create browser-side counterpart and to register itself for later +// // dispatching. +// dispatcher.CreateHostBeacon(pending_beacon, ...); +// +// // When a PendingBeacon becomes non-pending. +// dispatcher.Unregister(pending_beacon); class CORE_EXPORT PendingBeaconDispatcher : public GarbageCollected<PendingBeaconDispatcher>, - public Supplement<ExecutionContext> { + public Supplement<ExecutionContext>, + public ExecutionContextLifecycleObserver, + public PageVisibilityObserver { public: + // `PendingBeacon` is an interface to represent a reference to renderer-side + // pending beacon object. "pending" means this beacon is ok to send. + // PendingBeaconDispatcher uses this abstraction, instead of the entire + // blink::PendingBeacon, to schedule tasks to send out pending beacons. + class CORE_EXPORT PendingBeacon : public GarbageCollectedMixin { + public: + // Returns a background timeout to help schedule calls to `Send()` when the + // page where this beacon created enters hidden visibility state. + // Implementation should ensure the returned TimeDelta is not negative. + virtual base::TimeDelta GetBackgroundTimeout() const = 0; + // Triggers beacon sending action. + // Implementation should also transitions this beacon into non-pending + // state. and call `PendingBeaconDispatcher::Unregister()` to unregister + // itself from further scheduling. + virtual void Send() = 0; + }; + static const char kSupplementName[]; + // TODO(crbug.com/1293679): Update to proper TaskType once the spec finalized. - // Using the `TaskType::kMiscPlatformAPI` as pending beacons are not yet - // associated with any specific task runner in the spec. + // Using the `TaskType::kNetworkingUnfreezable` as pending beacons needs to + // work when Document is put into BackForwardCache (frozen). // See also // https://chromium.googlesource.com/chromium/src/+/main/third_party/blink/renderer/platform/scheduler/TaskSchedulingInBlink.md#task-types-and-task-sources - static constexpr TaskType kTaskType = TaskType::kMiscPlatformAPI; - - explicit PendingBeaconDispatcher(ExecutionContext& ec, - base::PassKey<PendingBeaconDispatcher> key); - - // Not copyable or movable - PendingBeaconDispatcher(const PendingBeaconDispatcher&) = delete; - PendingBeaconDispatcher& operator=(const PendingBeaconDispatcher&) = delete; - virtual ~PendingBeaconDispatcher() = default; - - void Trace(Visitor* visitor) const override; + static constexpr TaskType kTaskType = TaskType::kNetworkingUnfreezable; // Returns an instance of this class of `ec` if already stored in `ec`. // Otherwise, constructs a new one attached to `ec` and returns it. @@ -64,23 +102,113 @@ // Otherwise, returns nullptr. static PendingBeaconDispatcher* From(ExecutionContext& ec); + explicit PendingBeaconDispatcher(ExecutionContext& ec, + base::PassKey<PendingBeaconDispatcher> key); + + // Not copyable or movable + PendingBeaconDispatcher(const PendingBeaconDispatcher&) = delete; + PendingBeaconDispatcher& operator=(const PendingBeaconDispatcher&) = delete; + + void Trace(Visitor* visitor) const override; + // Asks the PendingBeaconHost in the browser process to create and store a new - // PendingBeacon that holds `receiver`. The caller `beacon` will be able to - // communicate with it by sending messages to `receiver`. + // PendingBeacon that holds `receiver`. The caller `pending_beacon` will be + // able to communicate with the browser-side PendingBeacon by sending messages + // to `receiver`. // - // This method also retains an extra reference to `beacon` for later use in - // `ScheduleDispatchingBeacons()`. + // Calling this method will also make this dispatcher retain at least one + // strong reference to `pending_beacon`, so that `pending_beacon` can be + // scheduled to dispatch even if its original reference is gone. void CreateHostBeacon( + PendingBeacon* pending_beacon, mojo::PendingReceiver<mojom::blink::PendingBeacon> receiver, const KURL& url, mojom::blink::BeaconMethod method); + // Unregisters `pending_beacon` from this dispatcher so that it won't be + // scheduled to send anymore. + // + // But it will still be able to send itself out when it is still alive. + // Note that some of references to `pending_beacon` in this dispatcher might + // not be cleared immediately. + void Unregister(PendingBeacon* pending_beacon); + + // `ExecutionContextLifecycleObserver` implementation. + void ContextDestroyed() override; + + // `PageVisibilityObserver` implementation. + void PageVisibilityChanged() override; + private: + // Schedules a series of tasks to dispatch pending beacons according to + // their `PendingBeacon::GetBackgroundTimeout()`. + // + // Internally, it doesn't send all of pending beacons out at once. Instead, it + // bundles pending beacons with similar background timeout, and sends them out + // in batch to reduce the number of task callbacks triggered. + void ScheduleDispatchBeacons(); + + // Cancels the scheduled task held by `task_handle_` if exists, and clears + // all pending beacons held in `background_timeout_descending_beacons_`. + void CancelDispatchBeacons(); + + // Internal method to schedule sending a bundle of beacons. see + // `GetStartIndexForNextBundledBeacons()` for more details. + void ScheduleDispatchNextBundledBeacons(); + + // Sends out beacons in the range [`start_index`, end) from + // `background_timeout_descending_beacons_`. + // It also schedules the next call to itself if feasible. + void OnDispatchBeaconsAndRepeat(wtf_size_t start_index); + + // Returns the starting index of a range of beacons that can be sent out + // together by looking into beacons in + // `background_timeout_descending_beacons_`. In other words, + // background_timeout_descending_beacons_[returned index, end) is the next + // bundle. + wtf_size_t GetStartIndexForNextBundledBeacons() const; + + // Returns a TaskRunner to schedule beacon sending tasks. + scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner(); + // Connects to a PendingBeaconHost running in browser process. HeapMojoRemote<mojom::blink::PendingBeaconHost> remote_; + + // Retains strong references to the pending beacons so that they can be + // scheduled to send even if the original references are gone. + // + // A new reference is inserted every time `CreateHostBeacon()` is called. + // A reference is removed if + // - it is manually un-registered by `Unregistered()`. + // - it is about to send in `OnDispatchBeaconsAndRepeat()`. + // + // This field should be the source of truth when deciding if a pending beacon + // is still *pending*, i.e. ok to send, or not. + HeapHashSet<Member<PendingBeacon>> pending_beacons_; + + // Retains additional references to the ones in `pending_beacons_` to process. + // + // These are sorted by their `PendingBeacon::GetBackgroundTimeout()` in + // non-ascending order: the earliest expired beacon is put last so that they + // can be easily removed. + // This field is empty until the sending process kicks off, i.e. + // `ScheduleDispatchBeacons()` is called. + // Must be cleared every time `CancelDispatchBeacons()` is called. + HeapVector<Member<PendingBeacon>> background_timeout_descending_beacons_; + + // The accumulated delay indicating how long it has passed since the initial + // call to `ScheduleDispatchBeacons()`. + // + // Must be reset to 0 every time `CancelDispatchBeacons()` is called. + base::TimeDelta previous_delayed_; + + // Points to the most recent bundled-beacons-sending task scheduled in + // `ScheduleDispatchNextBundledBeacons()`. + // + // It is canceled when `CancelDispatchBeacons()` is called. + TaskHandle task_handle_; }; } // namespace blink -#endif // #define - // THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_PENDING_BEACON_DISPATCHER_H_ +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_PENDING_BEACON_DISPATCHER_H_
diff --git a/third_party/blink/renderer/core/frame/pending_beacon_dispatcher_test.cc b/third_party/blink/renderer/core/frame/pending_beacon_dispatcher_test.cc new file mode 100644 index 0000000..a28bb09 --- /dev/null +++ b/third_party/blink/renderer/core/frame/pending_beacon_dispatcher_test.cc
@@ -0,0 +1,299 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +#include "third_party/blink/renderer/core/frame/pending_beacon_dispatcher.h" + +#include <utility> +#include <vector> + +#include "base/test/bind.h" +#include "base/time/time.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/mojom/frame/pending_beacon.mojom-blink-forward.h" +#include "third_party/blink/public/mojom/frame/pending_beacon.mojom-blink.h" +#include "third_party/blink/public/mojom/page/page_visibility_state.mojom.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h" +#include "third_party/blink/renderer/core/execution_context/execution_context.h" +#include "third_party/blink/renderer/core/page/page.h" +#include "third_party/blink/renderer/platform/heap/collection_support/heap_vector.h" +#include "third_party/blink/renderer/platform/mojo/heap_mojo_remote.h" +#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h" +#include "third_party/googletest/src/googlemock/include/gmock/gmock-matchers.h" +#include "third_party/googletest/src/googlemock/include/gmock/gmock-more-matchers.h" + +namespace blink { +namespace { + +using ::testing::ElementsAre; +using ::testing::IsEmpty; +using ::testing::UnorderedElementsAre; + +} // namespace + +class MockPendingBeacon : public GarbageCollected<MockPendingBeacon>, + public PendingBeaconDispatcher::PendingBeacon { + public: + MockPendingBeacon(ExecutionContext* ec, + int id, + base::TimeDelta background_timeout, + base::RepeatingCallback<void(int)> on_send) + : remote_(ec), + id_(id), + background_timeout_(background_timeout), + on_send_(on_send) { + auto task_runner = ec->GetTaskRunner(PendingBeaconDispatcher::kTaskType); + mojo::PendingReceiver<mojom::blink::PendingBeacon> unused_receiver = + remote_.BindNewPipeAndPassReceiver(task_runner); + + auto& dispatcher = PendingBeaconDispatcher::FromOrAttachTo(*ec); + dispatcher.CreateHostBeacon(this, std::move(unused_receiver), url_, + method_); + } + + MockPendingBeacon(ExecutionContext* ec, + int id, + base::RepeatingCallback<void(int)> on_send) + : MockPendingBeacon(ec, id, base::Milliseconds(-1), on_send) {} + + // Not copyable or movable + MockPendingBeacon(const MockPendingBeacon&) = delete; + MockPendingBeacon& operator=(const MockPendingBeacon&) = delete; + virtual ~MockPendingBeacon() = default; + + void Trace(Visitor* visitor) const override { visitor->Trace(remote_); } + + // PendingBeaconDispatcher::Beacon Implementation. + base::TimeDelta GetBackgroundTimeout() const override { + return background_timeout_; + } + void Send() override { on_send_.Run(id_); } + + private: + const KURL url_ = KURL("/"); + const mojom::blink::BeaconMethod method_ = mojom::blink::BeaconMethod::kGet; + HeapMojoRemote<mojom::blink::PendingBeacon> remote_; + const int id_; + const base::TimeDelta background_timeout_; + base::RepeatingCallback<void(int)> on_send_; +}; + +class PendingBeaconDispatcherTestBase : public ::testing::Test { + protected: + void TriggerDispatchOnBackgroundTimeout(V8TestingScope& scope) { + auto* ec = scope.GetExecutionContext(); + // Ensures that a dispatcher is attached to `ec`. + PendingBeaconDispatcher::FromOrAttachTo(*ec); + scope.GetPage().SetVisibilityState( + blink::mojom::PageVisibilityState::kHidden, /*is_initial_state=*/false); + } +}; + +struct BeaconIdToTimeoutsTestType { + std::string test_case_name; + std::vector<std::pair<int, base::TimeDelta>> id_to_timeouts; + std::vector<int> expected; +}; + +// Tests to cover the basic sending order of beacons on backgroundTimeout or +// on timeout. +// Note that the beacons in the same test falls into different bundles such that +// the resulting order is deterministic. +class PendingBeaconDispatcherBasicBeaconsTest + : public PendingBeaconDispatcherTestBase, + public ::testing::WithParamInterface<BeaconIdToTimeoutsTestType> {}; + +INSTANTIATE_TEST_SUITE_P( + All, + PendingBeaconDispatcherBasicBeaconsTest, + testing::ValuesIn<std::vector<BeaconIdToTimeoutsTestType>>({ + {"OneBeacon", {{1, base::Milliseconds(0)}}, {1}}, + {"OrderedBeacons", + { + {1, base::Milliseconds(0)}, + {2, base::Milliseconds(100)}, + {3, base::Milliseconds(200)}, + {4, base::Milliseconds(300)}, + {5, base::Milliseconds(400)}, + }, + {1, 2, 3, 4, 5}}, + {"ReversedBeacons", + { + {1, base::Milliseconds(400)}, + {2, base::Milliseconds(300)}, + {3, base::Milliseconds(200)}, + {4, base::Milliseconds(100)}, + {5, base::Milliseconds(0)}, + }, + {5, 4, 3, 2, 1}}, + {"RandomOrderedBeacons", + { + {1, base::Milliseconds(300)}, + {2, base::Milliseconds(100)}, + {3, base::Milliseconds(0)}, + {4, base::Milliseconds(500)}, + {5, base::Milliseconds(200)}, + }, + {3, 2, 5, 1, 4}}, + + }), + [](const testing::TestParamInfo<BeaconIdToTimeoutsTestType>& info) { + return info.param.test_case_name; + }); + +TEST_P(PendingBeaconDispatcherBasicBeaconsTest, + DispatchBeaconsOnBackgroundTimeout) { + const auto& id_to_timeouts = GetParam().id_to_timeouts; + std::vector<int> beacons_sent_order; + + V8TestingScope scope; + auto* ec = scope.GetExecutionContext(); + HeapVector<Member<MockPendingBeacon>> beacons; + for (const auto& id_to_timeout : id_to_timeouts) { + beacons.push_back(MakeGarbageCollected<MockPendingBeacon>( + ec, id_to_timeout.first, id_to_timeout.second, + base::BindLambdaForTesting([&beacons_sent_order](int id) { + beacons_sent_order.push_back(id); + }))); + } + + TriggerDispatchOnBackgroundTimeout(scope); + while (beacons_sent_order.size() < id_to_timeouts.size()) { + test::RunPendingTasks(); + } + + EXPECT_THAT(beacons_sent_order, testing::ContainerEq(GetParam().expected)); +} + +// Tests to cover the beacon bundling behavior on backgroundTimeout. +using PendingBeaconDispatcherBackgroundTimeoutBundledTest = + PendingBeaconDispatcherTestBase; + +TEST_F(PendingBeaconDispatcherBackgroundTimeoutBundledTest, + DispatchOrderedBeacons) { + const std::vector<std::pair<int, base::TimeDelta>> id_to_timeouts = { + {1, base::Milliseconds(0)}, {2, base::Milliseconds(1)}, + {3, base::Milliseconds(50)}, {4, base::Milliseconds(99)}, + {5, base::Milliseconds(100)}, {6, base::Milliseconds(101)}, + {7, base::Milliseconds(150)}, {8, base::Milliseconds(201)}, + {9, base::Milliseconds(202)}, {10, base::Milliseconds(250)}, + {11, base::Milliseconds(499)}, {12, base::Milliseconds(500)}, + }; + std::vector<int> beacons_sent_order; + + V8TestingScope scope; + auto* ec = scope.GetExecutionContext(); + HeapVector<Member<MockPendingBeacon>> beacons; + for (const auto& id_to_timeout : id_to_timeouts) { + beacons.push_back(MakeGarbageCollected<MockPendingBeacon>( + ec, id_to_timeout.first, id_to_timeout.second, + base::BindLambdaForTesting([&beacons_sent_order](int id) { + beacons_sent_order.push_back(id); + }))); + } + + TriggerDispatchOnBackgroundTimeout(scope); + while (beacons_sent_order.size() < id_to_timeouts.size()) { + test::RunPendingTasks(); + } + + // Bundle 1: {0, 1, 50, 99} + EXPECT_THAT(std::vector<int>(beacons_sent_order.begin(), + beacons_sent_order.begin() + 4), + UnorderedElementsAre(1, 2, 3, 4)); + // Bundle 2: {100, 101, 150} + EXPECT_THAT(std::vector<int>(beacons_sent_order.begin() + 4, + beacons_sent_order.begin() + 7), + UnorderedElementsAre(5, 6, 7)); + // Bundle 3: {201, 202, 250} + EXPECT_THAT(std::vector<int>(beacons_sent_order.begin() + 7, + beacons_sent_order.begin() + 10), + UnorderedElementsAre(8, 9, 10)); + // Bundle 4: {499, 500} + EXPECT_THAT(std::vector<int>(beacons_sent_order.begin() + 10, + beacons_sent_order.begin() + 12), + UnorderedElementsAre(11, 12)); +} + +TEST_F(PendingBeaconDispatcherBackgroundTimeoutBundledTest, + DispatchReversedBeacons) { + const std::vector<std::pair<int, base::TimeDelta>> id_to_timeouts = { + {1, base::Milliseconds(500)}, {2, base::Milliseconds(499)}, + {3, base::Milliseconds(250)}, {4, base::Milliseconds(202)}, + {5, base::Milliseconds(201)}, {6, base::Milliseconds(150)}, + {7, base::Milliseconds(101)}, {8, base::Milliseconds(100)}, + {9, base::Milliseconds(99)}, {10, base::Milliseconds(50)}, + {11, base::Milliseconds(1)}, {12, base::Milliseconds(0)}, + }; + std::vector<int> beacons_sent_order; + + V8TestingScope scope; + auto* ec = scope.GetExecutionContext(); + HeapVector<Member<MockPendingBeacon>> beacons; + for (const auto& id_to_timeout : id_to_timeouts) { + beacons.push_back(MakeGarbageCollected<MockPendingBeacon>( + ec, id_to_timeout.first, id_to_timeout.second, + base::BindLambdaForTesting([&beacons_sent_order](int id) { + beacons_sent_order.push_back(id); + }))); + } + + TriggerDispatchOnBackgroundTimeout(scope); + while (beacons_sent_order.size() < id_to_timeouts.size()) { + test::RunPendingTasks(); + } + + // Bundle 1: {0, 1, 50, 99} + EXPECT_THAT(std::vector<int>(beacons_sent_order.begin(), + beacons_sent_order.begin() + 4), + UnorderedElementsAre(9, 10, 11, 12)); + // Bundle 2: {100, 101, 150} + EXPECT_THAT(std::vector<int>(beacons_sent_order.begin() + 4, + beacons_sent_order.begin() + 7), + UnorderedElementsAre(6, 7, 8)); + // Bundle 3: {201, 202, 250} + EXPECT_THAT(std::vector<int>(beacons_sent_order.begin() + 7, + beacons_sent_order.begin() + 10), + UnorderedElementsAre(3, 4, 5)); + // Bundle 4: {499, 500} + EXPECT_THAT(std::vector<int>(beacons_sent_order.begin() + 10, + beacons_sent_order.begin() + 12), + UnorderedElementsAre(1, 2)); +} + +TEST_F(PendingBeaconDispatcherBackgroundTimeoutBundledTest, + DispatchDuplicatedBeacons) { + const std::vector<std::pair<int, base::TimeDelta>> id_to_timeouts = { + {1, base::Milliseconds(0)}, {2, base::Milliseconds(0)}, + {3, base::Milliseconds(100)}, {4, base::Milliseconds(100)}, + {5, base::Milliseconds(100)}, {6, base::Milliseconds(101)}, + {7, base::Milliseconds(101)}, + }; + std::vector<int> beacons_sent_order; + + V8TestingScope scope; + auto* ec = scope.GetExecutionContext(); + HeapVector<Member<MockPendingBeacon>> beacons; + for (const auto& id_to_timeout : id_to_timeouts) { + beacons.push_back(MakeGarbageCollected<MockPendingBeacon>( + ec, id_to_timeout.first, id_to_timeout.second, + base::BindLambdaForTesting([&beacons_sent_order](int id) { + beacons_sent_order.push_back(id); + }))); + } + + TriggerDispatchOnBackgroundTimeout(scope); + while (beacons_sent_order.size() < id_to_timeouts.size()) { + test::RunPendingTasks(); + } + + // Bundle 1: {0, 0} + EXPECT_THAT(std::vector<int>(beacons_sent_order.begin(), + beacons_sent_order.begin() + 2), + UnorderedElementsAre(1, 2)); + // Bundle 2: {100, 100, 100, 101, 101} + EXPECT_THAT(std::vector<int>(beacons_sent_order.begin() + 2, + beacons_sent_order.begin() + 7), + UnorderedElementsAre(3, 4, 5, 6, 7)); +} + +} // namespace blink
diff --git a/third_party/blink/renderer/core/frame/viewport_data.cc b/third_party/blink/renderer/core/frame/viewport_data.cc index 7aac63c..212541b 100644 --- a/third_party/blink/renderer/core/frame/viewport_data.cc +++ b/third_party/blink/renderer/core/frame/viewport_data.cc
@@ -108,6 +108,8 @@ document_->GetPage()->GetVisualViewport().IsActiveViewport()) { document_->GetPage()->GetChromeClient().DispatchViewportPropertiesDidChange( GetViewportDescription()); + if (auto* mf_checker = document_->View()->GetMobileFriendlinessChecker()) + mf_checker->NotifyViewportUpdated(GetViewportDescription()); } }
diff --git a/third_party/blink/renderer/core/frame/web_frame_test.cc b/third_party/blink/renderer/core/frame/web_frame_test.cc index dc031e6..1b6b5a0 100644 --- a/third_party/blink/renderer/core/frame/web_frame_test.cc +++ b/third_party/blink/renderer/core/frame/web_frame_test.cc
@@ -13371,8 +13371,56 @@ } } +std::vector<TextRunDOMNodeIdInfo> GetPrintedTextRunDOMNodeIds( + WebLocalFrame* frame, + const WebVector<uint32_t>* pages = nullptr) { + WebPrintParams print_params; + gfx::Size page_size(500, 500); + print_params.print_content_area.set_size(page_size); + + frame->PrintBegin(print_params, WebNode()); + cc::PaintRecorder recorder; + frame->PrintPagesForTesting(recorder.beginRecording(SkRect::MakeEmpty()), + page_size, page_size, pages); + frame->PrintEnd(); + + sk_sp<cc::PaintRecord> paint_record = recorder.finishRecordingAsPicture(); + std::vector<TextRunDOMNodeIdInfo> text_runs; + RecursiveCollectTextRunDOMNodeIds(paint_record, 0, &text_runs); + + return text_runs; +} + } // namespace +TEST_F(WebFrameTest, PrintSomePages) { + RegisterMockedHttpURLLoad("print-pages.html"); + frame_test_helpers::WebViewHelper web_view_helper; + web_view_helper.InitializeAndLoad(base_url_ + "print-pages.html"); + + WebVector<uint32_t> pages; + pages.push_back(1); + pages.push_back(4); + pages.push_back(8); + std::vector<TextRunDOMNodeIdInfo> text_runs = + GetPrintedTextRunDOMNodeIds(web_view_helper.LocalMainFrame(), &pages); + + ASSERT_EQ(3u, text_runs.size()); + EXPECT_EQ(2, text_runs[0].glyph_len); // Page 2 + EXPECT_EQ(5, text_runs[1].glyph_len); // Page 5 + EXPECT_EQ(9, text_runs[2].glyph_len); // Page 9 +} + +TEST_F(WebFrameTest, PrintAllPages) { + RegisterMockedHttpURLLoad("print-pages.html"); + frame_test_helpers::WebViewHelper web_view_helper; + web_view_helper.InitializeAndLoad(base_url_ + "print-pages.html"); + + std::vector<TextRunDOMNodeIdInfo> text_runs = + GetPrintedTextRunDOMNodeIds(web_view_helper.LocalMainFrame()); + EXPECT_EQ(10u, text_runs.size()); +} + TEST_F(WebFrameTest, FirstLetterHasDOMNodeIdWhenPrinting) { // When printing, every DrawText painting op needs to have an associated // DOM Node ID. This test ensures that when the first-letter style is used, @@ -13385,21 +13433,8 @@ frame_test_helpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "first-letter.html"); - // Print the page and capture the PaintRecord. - WebPrintParams print_params; - gfx::Size page_size(500, 500); - print_params.print_content_area.set_size(page_size); - WebLocalFrameImpl* frame = web_view_helper.LocalMainFrame(); - EXPECT_EQ(1u, frame->PrintBegin(print_params, WebNode())); - cc::PaintRecorder recorder; - frame->PrintPagesForTesting(recorder.beginRecording(SkRect::MakeEmpty()), - page_size, page_size); - frame->PrintEnd(); - sk_sp<PaintRecord> paint_record = recorder.finishRecordingAsPicture(); - - // Unpack the paint record and collect info about the text runs. - std::vector<TextRunDOMNodeIdInfo> text_runs; - RecursiveCollectTextRunDOMNodeIds(paint_record, 0, &text_runs); + std::vector<TextRunDOMNodeIdInfo> text_runs = + GetPrintedTextRunDOMNodeIds(web_view_helper.LocalMainFrame()); // The first text run should be "Hello". ASSERT_EQ(3U, text_runs.size());
diff --git a/third_party/blink/renderer/core/frame/web_local_frame_impl.cc b/third_party/blink/renderer/core/frame/web_local_frame_impl.cc index b0d96b9..b846a6b 100644 --- a/third_party/blink/renderer/core/frame/web_local_frame_impl.cc +++ b/third_party/blink/renderer/core/frame/web_local_frame_impl.cc
@@ -89,6 +89,7 @@ #include <algorithm> #include <memory> +#include <numeric> #include <utility> #include "base/notreached.h" @@ -328,10 +329,11 @@ return scale; } - void SpoolAllPagesWithBoundariesForTesting( + void SpoolPagesWithBoundariesForTesting( cc::PaintCanvas* canvas, const gfx::SizeF& page_size_in_pixels, - const gfx::SizeF& spool_size_in_pixels) { + const gfx::SizeF& spool_size_in_pixels, + const WebVector<uint32_t>* pages) { DispatchEventsForPrintingOnAllFrames(); if (!GetFrame()->GetDocument() || !GetFrame()->GetDocument()->GetLayoutView()) @@ -355,11 +357,22 @@ // Fill the whole background by white. context.FillRect(all_pages_rect, Color::kWhite, AutoDarkMode::Disabled()); - wtf_size_t num_pages = PageRects().size(); + WebVector<uint32_t> all_pages; + if (!pages) { + all_pages.reserve(page_rects_.size()); + all_pages.resize(page_rects_.size()); + std::iota(all_pages.begin(), all_pages.end(), 0); + pages = &all_pages; + } + int current_height = 0; - for (wtf_size_t page_index = 0; page_index < num_pages; page_index++) { + for (uint32_t page_index : *pages) { + if (page_index >= page_rects_.size()) { + break; + } + // Draw a line for a page boundary if this isn't the first page. - if (page_index > 0) { + if (page_index != pages->front()) { context.Save(); context.SetStrokeThickness(1); context.SetStrokeColor(Color(0, 0, 255)); @@ -391,7 +404,7 @@ #if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) // Account for the disabling of scaling in spoolPage. In the context of - // SpoolAllPagesWithBoundariesForTesting the scale HAS NOT been + // SpoolPagesWithBoundariesForTesting the scale HAS NOT been // pre-applied. float scale = GetPageShrink(page_index); transform.Scale(scale, scale); @@ -403,6 +416,7 @@ context.Restore(); } + canvas->drawPicture(context.EndRecording()); } @@ -1899,12 +1913,13 @@ gfx::Size WebLocalFrameImpl::SpoolSizeInPixelsForTesting( const gfx::Size& page_size_in_pixels, - uint32_t page_count) { + const WebVector<uint32_t>& pages) { int spool_width = page_size_in_pixels.width(); int spool_height = 0; - for (uint32_t page_index = 0; page_index < page_count; page_index++) { + + for (uint32_t page_index : pages) { // Make room for the 1px tall page separator. - if (page_index) + if (page_index != pages.front()) spool_height++; WebPrintPageDescription description; @@ -1919,15 +1934,24 @@ return gfx::Size(spool_width, spool_height); } +gfx::Size WebLocalFrameImpl::SpoolSizeInPixelsForTesting( + const gfx::Size& page_size_in_pixels, + uint32_t page_count) { + WebVector<uint32_t> pages(page_count); + std::iota(pages.begin(), pages.end(), 0); + return SpoolSizeInPixelsForTesting(page_size_in_pixels, pages); +} + void WebLocalFrameImpl::PrintPagesForTesting( cc::PaintCanvas* canvas, const gfx::Size& page_size_in_pixels, - const gfx::Size& spool_size_in_pixels) { + const gfx::Size& spool_size_in_pixels, + const WebVector<uint32_t>* pages) { DCHECK(print_context_); - print_context_->SpoolAllPagesWithBoundariesForTesting( - canvas, gfx::SizeF(page_size_in_pixels), - gfx::SizeF(spool_size_in_pixels)); + print_context_->SpoolPagesWithBoundariesForTesting( + canvas, gfx::SizeF(page_size_in_pixels), gfx::SizeF(spool_size_in_pixels), + pages); } gfx::Rect WebLocalFrameImpl::GetSelectionBoundsRectForTesting() const {
diff --git a/third_party/blink/renderer/core/frame/web_local_frame_impl.h b/third_party/blink/renderer/core/frame/web_local_frame_impl.h index 68811749f..26f4955 100644 --- a/third_party/blink/renderer/core/frame/web_local_frame_impl.h +++ b/third_party/blink/renderer/core/frame/web_local_frame_impl.h
@@ -318,11 +318,16 @@ void SetAdEvidence(const blink::FrameAdEvidence& ad_evidence) override; const absl::optional<blink::FrameAdEvidence>& AdEvidence() override; bool IsFrameCreatedByAdScript() override; + gfx::Size SpoolSizeInPixelsForTesting( + const gfx::Size& page_size_in_pixels, + const WebVector<uint32_t>& pages) override; gfx::Size SpoolSizeInPixelsForTesting(const gfx::Size& page_size_in_pixels, uint32_t page_count) override; - void PrintPagesForTesting(cc::PaintCanvas*, - const gfx::Size& page_size_in_pixels, - const gfx::Size& spool_size_in_pixels) override; + void PrintPagesForTesting( + cc::PaintCanvas*, + const gfx::Size& page_size_in_pixels, + const gfx::Size& spool_size_in_pixels, + const WebVector<uint32_t>* pages = nullptr) override; gfx::Rect GetSelectionBoundsRectForTesting() const override; gfx::Point GetPositionInViewportForTesting() const override; void WasHidden() override;
diff --git a/third_party/blink/renderer/core/html/html_frame_set_element.cc b/third_party/blink/renderer/core/html/html_frame_set_element.cc index 0209062..e21f41d1 100644 --- a/third_party/blink/renderer/core/html/html_frame_set_element.cc +++ b/third_party/blink/renderer/core/html/html_frame_set_element.cc
@@ -147,6 +147,10 @@ } else { border_set_ = false; } + if (auto* box = GetLayoutBox()) { + box->SetNeedsLayoutAndFullPaintInvalidation( + layout_invalidation_reason::kAttributeChanged); + } } else if (name == html_names::kBordercolorAttr) { border_color_set_ = !value.IsEmpty(); } else if (name == html_names::kOnafterprintAttr) {
diff --git a/third_party/blink/renderer/core/layout/ng/ng_anchor_query.cc b/third_party/blink/renderer/core/layout/ng/ng_anchor_query.cc index 707e175..7204c52 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_anchor_query.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_anchor_query.cc
@@ -17,6 +17,29 @@ fragment(logical_reference.fragment), is_invalid(logical_reference.is_invalid) {} +void NGLogicalAnchorReference::InsertInPreOrderInto( + Member<NGLogicalAnchorReference>* head_ptr) { + const LayoutObject* const object = fragment->GetLayoutObject(); + for (;;) { + NGLogicalAnchorReference* const head = *head_ptr; + DCHECK(!head || head->fragment->GetLayoutObject()); + if (!head || + object->IsBeforeInPreOrder(*head->fragment->GetLayoutObject())) { + next = head; + *head_ptr = this; + break; + } + + // Skip adding if there is a reference with the same validity status and is + // before in the tree order. Only the first one in the tree order is needed + // for each validity status. + if (is_invalid == head->is_invalid) + break; + + head_ptr = &head->next; + } +} + const NGPhysicalAnchorReference* NGPhysicalAnchorQuery::AnchorReference( const AtomicString& name) const { const auto& it = anchor_references_.find(name); @@ -46,9 +69,11 @@ const AtomicString& name) const { const auto& it = anchor_references_.find(name); if (it != anchor_references_.end()) { - const NGLogicalAnchorReference& result = *it->value; - if (!result.is_invalid) - return &result; + for (const NGLogicalAnchorReference* result = it->value; result; + result = result->next) { + if (!result->is_invalid) + return result; + } } return nullptr; } @@ -78,15 +103,27 @@ void NGLogicalAnchorQuery::Set(const AtomicString& name, NGLogicalAnchorReference* reference) { DCHECK(reference); + DCHECK(!reference->next); const auto result = anchor_references_.insert(name, reference); if (result.is_new_entry) return; + DCHECK(result.stored_value->value); NGLogicalAnchorReference& existing = *result.stored_value->value; - if (existing.fragment->GetLayoutObject() != - reference->fragment->GetLayoutObject()) { - // If this is the same name on a different |LayoutObject|, ignore it. - // This logic assumes that callers call this function in the correct order. + const LayoutObject* existing_object = existing.fragment->GetLayoutObject(); + DCHECK(existing_object); + const LayoutObject* new_object = reference->fragment->GetLayoutObject(); + DCHECK(new_object); + if (existing_object != new_object) { + if (!reference->is_invalid && !existing.is_invalid) { + // If both new and existing values are valid, ignore the new value. This + // logic assumes the callers call this function in the correct order. + DCHECK(existing_object->IsBeforeInPreOrder(*new_object)); + return; + } + // When out-of-flow objects are involved, callers can't guarantee the call + // order. Insert into the list in the tree order. + reference->InsertInPreOrderInto(&result.stored_value->value); return; } @@ -97,11 +134,17 @@ void NGPhysicalAnchorQuery::SetFromLogical( const NGLogicalAnchorQuery& logical_query, const WritingModeConverter& converter) { + // This function assumes |this| is empty on the entry. Merging multiple + // references is not supported. + DCHECK(IsEmpty()); for (const auto& it : logical_query.anchor_references_) { - DCHECK_EQ(AnchorReference(it.key), nullptr); - anchor_references_.Set( + // For each key, only the first one in the tree order, valid or invalid, is + // needed to be propagated, because the validity is re-computed for each + // containing block. Please see |SetFromPhysical|. + const auto result = anchor_references_.Set( it.key, MakeGarbageCollected<NGPhysicalAnchorReference>(*it.value, converter)); + DCHECK(result.is_new_entry); } } @@ -294,6 +337,7 @@ void NGLogicalAnchorReference::Trace(Visitor* visitor) const { visitor->Trace(fragment); + visitor->Trace(next); } void NGPhysicalAnchorReference::Trace(Visitor* visitor) const {
diff --git a/third_party/blink/renderer/core/layout/ng/ng_anchor_query.h b/third_party/blink/renderer/core/layout/ng/ng_anchor_query.h index 651c61e..4f62119f 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_anchor_query.h +++ b/third_party/blink/renderer/core/layout/ng/ng_anchor_query.h
@@ -75,10 +75,15 @@ bool is_invalid) : rect(rect), fragment(&fragment), is_invalid(is_invalid) {} + // Insert |this| into the given singly linked list in the pre-order. + void InsertInPreOrderInto(Member<NGLogicalAnchorReference>* head_ptr); + void Trace(Visitor* visitor) const; LogicalRect rect; Member<const NGPhysicalFragment> fragment; + // A singly linked list in the order of the pre-order DFS. + Member<NGLogicalAnchorReference> next; bool is_invalid = false; };
diff --git a/third_party/blink/renderer/core/layout/ng/ng_frame_set_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/ng_frame_set_layout_algorithm.cc index 3f3546c..cdd2b11 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_frame_set_layout_algorithm.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_frame_set_layout_algorithm.cc
@@ -75,7 +75,19 @@ MinMaxSizesResult NGFrameSetLayoutAlgorithm::ComputeMinMaxSizes( const MinMaxSizesFloatInput&) { - return MinMaxSizesResult(MinMaxSizes(), false); + MinMaxSizes sizes; + const auto& space = ConstraintSpace(); + // This function needs to return a value which is >= border+padding in order + // to pass a DCHECK in NGFlexLayoutAlgorithm::ConstructAndAppendFlexItems() + // though <frameset> ignores border and padding. + // + // We can't use BorderPadding() here because NGFragmentGeometry for <frameset> + // doesn't provide it. + // + // Test: external/wpt/css/css-flexbox/frameset-crash.html + sizes += (ComputeBorders(space, Node()) + ComputePadding(space, Style())) + .InlineSum(); + return MinMaxSizesResult(sizes, false); } // https://html.spec.whatwg.org/C/#convert-a-list-of-dimensions-to-a-list-of-pixel-values
diff --git a/third_party/blink/renderer/core/mobile_metrics/mobile_friendliness_checker.cc b/third_party/blink/renderer/core/mobile_metrics/mobile_friendliness_checker.cc index c2803452..f682b9a9 100644 --- a/third_party/blink/renderer/core/mobile_metrics/mobile_friendliness_checker.cc +++ b/third_party/blink/renderer/core/mobile_metrics/mobile_friendliness_checker.cc
@@ -54,18 +54,20 @@ // This phase will abort when it consumes more than 4ms. static constexpr base::TimeDelta kTimeBudgetForTapTargetExtraction = base::Milliseconds(4); +static constexpr base::TimeDelta kEvaluationDelay = base::Seconds(5); static constexpr base::TimeDelta kEvaluationInterval = base::Minutes(1); MobileFriendlinessChecker::MobileFriendlinessChecker(LocalFrameView& frame_view) : frame_view_(&frame_view), + timer_(frame_view_->GetFrame().GetTaskRunner(TaskType::kInternalDefault), + this, + &MobileFriendlinessChecker::Activate), viewport_scalar_( frame_view_->GetFrame().GetWidgetForLocalRoot() ? frame_view_->GetPage() ->GetChromeClient() .WindowToViewportScalar(&frame_view_->GetFrame(), 1) - : 1.0), - last_evaluated_(base::TimeTicks::Now() - kEvaluationInterval - - base::Seconds(5)) {} + : 1.0) {} MobileFriendlinessChecker::~MobileFriendlinessChecker() = default; @@ -87,36 +89,15 @@ previous_transform_ = viewport_transform_; current_x_offset_ = 0.0; - const ViewportDescription& viewport = frame_view_->GetFrame() - .GetDocument() - ->GetViewportData() - .GetViewportDescription(); - if (viewport.type == ViewportDescription::Type::kViewportMeta) { - const double zoom = viewport.zoom_is_explicit ? viewport.zoom : 1.0; - viewport_device_width_ = viewport.max_width.IsDeviceWidth(); - if (viewport.max_width.IsFixed()) { - viewport_hardcoded_width_ = viewport.max_width.GetFloatValue(); - // Convert value from Blink space to device-independent pixels. - viewport_hardcoded_width_ /= viewport_scalar_; - } - - if (viewport.zoom_is_explicit) - viewport_initial_scale_x10_ = std::round(viewport.zoom * 10); - - if (viewport.user_zoom_is_explicit) { - allow_user_zoom_ = viewport.user_zoom; - // If zooming is only allowed slightly. - if (viewport.max_zoom / zoom < kMaximumScalePreventsZoomingThreshold) - allow_user_zoom_ = false; - } - } - - initial_scale_ = frame_view_->GetPage() - ->GetPageScaleConstraintsSet() - .FinalConstraints() - .initial_scale; int frame_width = frame_view_->GetPage()->GetVisualViewport().Size().width(); viewport_width_ = frame_width * viewport_scalar_ / initial_scale_; + + if (timer_.IsActive() || + base::TimeTicks::Now() - last_evaluated_ < kEvaluationInterval) { + return; + } + + timer_.StartOneShot(kEvaluationDelay, FROM_HERE); } void MobileFriendlinessChecker::NotifyPaintEnd() { @@ -126,6 +107,10 @@ is_painting_ = false; } +void MobileFriendlinessChecker::WillBeRemovedFromFrame() { + timer_.Stop(); +} + namespace { bool IsTimeBudgetExpired(const base::TimeTicks& from) { @@ -531,17 +516,24 @@ return std::ceil(bad_tap_targets * 100.0 / all_tap_targets); } -void MobileFriendlinessChecker::MaybeRecompute() { +void MobileFriendlinessChecker::Activate(TimerBase*) { DCHECK(frame_view_->GetFrame().Client()->IsLocalFrameClientImpl()); DCHECK(frame_view_->GetFrame().IsOutermostMainFrame()); - base::TimeTicks now = base::TimeTicks::Now(); - if (now - last_evaluated_ < kEvaluationInterval) + + // If detached, there's no need to calculate any metrics. + if (!frame_view_->GetChromeClient()) return; - ComputeNow(); + frame_view_->RegisterForLifecycleNotifications(this); + frame_view_->ScheduleAnimation(); } -void MobileFriendlinessChecker::ComputeNow() { +void MobileFriendlinessChecker::DidFinishLifecycleUpdate( + const LocalFrameView&) { + DCHECK(frame_view_->GetFrame().Client()->IsLocalFrameClientImpl()); + DCHECK(frame_view_->GetFrame().IsOutermostMainFrame()); + + frame_view_->UnregisterFromLifecycleNotifications(this); frame_view_->DidChangeMobileFriendliness(MobileFriendliness{ .viewport_device_width = viewport_device_width_, .viewport_initial_scale_x10 = viewport_initial_scale_x10_, @@ -558,6 +550,40 @@ last_evaluated_ = base::TimeTicks::Now(); } +void MobileFriendlinessChecker::NotifyInitialScaleUpdated() { + initial_scale_ = frame_view_->GetPage() + ->GetPageScaleConstraintsSet() + .FinalConstraints() + .initial_scale; +} + +void MobileFriendlinessChecker::NotifyViewportUpdated( + const ViewportDescription& viewport) { + DCHECK(frame_view_->GetFrame().Client()->IsLocalFrameClientImpl()); + DCHECK(frame_view_->GetFrame().IsOutermostMainFrame()); + + if (viewport.type != ViewportDescription::Type::kViewportMeta) + return; + + const double zoom = viewport.zoom_is_explicit ? viewport.zoom : 1.0; + viewport_device_width_ = viewport.max_width.IsDeviceWidth(); + if (viewport.max_width.IsFixed()) { + viewport_hardcoded_width_ = viewport.max_width.GetFloatValue(); + // Convert value from Blink space to device-independent pixels. + viewport_hardcoded_width_ /= viewport_scalar_; + } + + if (viewport.zoom_is_explicit) + viewport_initial_scale_x10_ = std::round(viewport.zoom * 10); + + if (viewport.user_zoom_is_explicit) { + allow_user_zoom_ = viewport.user_zoom; + // If zooming is only allowed slightly. + if (viewport.max_zoom / zoom < kMaximumScalePreventsZoomingThreshold) + allow_user_zoom_ = false; + } +} + int MobileFriendlinessChecker::AreaSizes::SmallTextRatio() const { if (total_text_area == 0) return 0; @@ -631,6 +657,7 @@ void MobileFriendlinessChecker::Trace(Visitor* visitor) const { visitor->Trace(frame_view_); + visitor->Trace(timer_); } } // namespace blink
diff --git a/third_party/blink/renderer/core/mobile_metrics/mobile_friendliness_checker.h b/third_party/blink/renderer/core/mobile_metrics/mobile_friendliness_checker.h index 7213f007..03fac27 100644 --- a/third_party/blink/renderer/core/mobile_metrics/mobile_friendliness_checker.h +++ b/third_party/blink/renderer/core/mobile_metrics/mobile_friendliness_checker.h
@@ -12,29 +12,35 @@ #include "third_party/blink/renderer/platform/heap/garbage_collected.h" #include "third_party/blink/renderer/platform/heap/member.h" #include "third_party/blink/renderer/platform/heap/visitor.h" +#include "third_party/blink/renderer/platform/timer.h" namespace blink { class Document; class LocalFrameView; class TransformPaintPropertyNodeOrAlias; +struct ViewportDescription; // Calculates the mobile usability of current page, especially friendliness on // smart phone devices are checked. The calculated value will be sent as a part // of UKM. class CORE_EXPORT MobileFriendlinessChecker - : public GarbageCollected<MobileFriendlinessChecker> { + : public GarbageCollected<MobileFriendlinessChecker>, + public LocalFrameView::LifecycleNotificationObserver { public: explicit MobileFriendlinessChecker(LocalFrameView& frame_view); virtual ~MobileFriendlinessChecker(); static MobileFriendlinessChecker* Create(LocalFrameView& frame_view); static MobileFriendlinessChecker* From(const Document&); - void MaybeRecompute(); - void ComputeNowForTesting() { ComputeNow(); } + // LocalFrameView::LifecycleNotificationObserver implementation + void DidFinishLifecycleUpdate(const LocalFrameView&) override; + void NotifyInitialScaleUpdated(); void NotifyPaintBegin(); void NotifyPaintEnd(); + void WillBeRemovedFromFrame(); + void NotifyViewportUpdated(const ViewportDescription&); void NotifyPaintTextFragment( const PhysicalRect& paint_rect, int font_size, @@ -43,7 +49,7 @@ const PhysicalRect& paint_rect, const TransformPaintPropertyNodeOrAlias& current_transform); - void Trace(Visitor* visitor) const; + void Trace(Visitor* visitor) const override; struct AreaSizes { double small_font_area = 0; @@ -81,8 +87,7 @@ }; private: - // Evaluate mobile friendliness of the page. - void ComputeNow(); + void Activate(TimerBase*); // Returns percentage value [0-100] of bad tap targets in the area of the // first page. Returns kTimeBudgetExceeded if the time limit is exceeded. @@ -99,6 +104,7 @@ const TransformPaintPropertyNodeOrAlias* previous_transform_ = nullptr; float current_x_offset_ = 0.0; float viewport_width_ = 0.0; + HeapTaskRunnerTimer<MobileFriendlinessChecker> timer_; double viewport_scalar_; double initial_scale_ = 1.0; base::TimeTicks last_evaluated_;
diff --git a/third_party/blink/renderer/core/mobile_metrics/mobile_friendliness_checker_test.cc b/third_party/blink/renderer/core/mobile_metrics/mobile_friendliness_checker_test.cc index d04de747..4c52a6f 100644 --- a/third_party/blink/renderer/core/mobile_metrics/mobile_friendliness_checker_test.cc +++ b/third_party/blink/renderer/core/mobile_metrics/mobile_friendliness_checker_test.cc
@@ -76,8 +76,14 @@ static void EvalMobileFriendliness(LocalFrameView* view, bool fixed_clock) { DCHECK(view->GetFrame().IsLocalRoot()); ScopedTimeTicksOverride clock(fixed_clock); - view->UpdateAllLifecyclePhasesForTest(); - view->GetMobileFriendlinessChecker()->ComputeNowForTesting(); + for (const Frame* frame = &view->GetFrame(); frame; + frame = frame->Tree().TraverseNext()) { + if (const auto* local_frame = DynamicTo<LocalFrame>(frame)) { + local_frame->View()->UpdateAllLifecyclePhasesForTest(); + } + } + + view->GetMobileFriendlinessChecker()->DidFinishLifecycleUpdate(*view); } static void ConfigureAndroidSettings(WebSettings* settings) {
diff --git a/third_party/blink/renderer/core/testing/data/print-pages.html b/third_party/blink/renderer/core/testing/data/print-pages.html new file mode 100644 index 0000000..a857377 --- /dev/null +++ b/third_party/blink/renderer/core/testing/data/print-pages.html
@@ -0,0 +1,16 @@ +<!DOCTYPE html> +<style> + div { + break-before: page; + } +</style> +<div>0</div> +<div>01</div> +<div>012</div> +<div>0123</div> +<div>01234</div> +<div>012345</div> +<div>0123456</div> +<div>01234567</div> +<div>012345678</div> +<div>0123456789</div>
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object.cc b/third_party/blink/renderer/modules/accessibility/ax_object.cc index 33b9302..46d77af8 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_object.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_object.cc
@@ -1633,8 +1633,7 @@ void AXObject::SerializeScreenReaderAttributes(ui::AXNodeData* node_data) { String display_style; - Node* node = GetNode(); - if (node && !node->IsDocumentNode()) { + if (Node* node = GetNode(); node && !node->IsDocumentNode()) { if (const ComputedStyle* computed_style = node->GetComputedStyle()) { display_style = CSSProperty::Get(CSSPropertyID::kDisplay) .CSSValueFromComputedStyle(
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_filter_operation_resolver.cc b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_filter_operation_resolver.cc index a1bd8f5..5c21ff5 100644 --- a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_filter_operation_resolver.cc +++ b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_filter_operation_resolver.cc
@@ -337,15 +337,18 @@ num_canvas_filter_errors_to_console_allowed_--; if (num_canvas_filter_errors_to_console_allowed_ < 0) continue; - const String& message = - (!name.has_value()) - ? "CanvasFilters require key 'filter' to specify filter type." - : String::Format( - "\"%s\" is not among supported CanvasFilter types.", - name->Utf8().c_str()); - execution_context->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>( - mojom::blink::ConsoleMessageSource::kRendering, - mojom::blink::ConsoleMessageLevel::kWarning, message)); + { + const String& message = + (!name.has_value()) + ? "CanvasFilters require key 'filter' to specify filter type." + : String::Format( + "\"%s\" is not among supported CanvasFilter types.", + name->Utf8().c_str()); + execution_context->AddConsoleMessage( + MakeGarbageCollected<ConsoleMessage>( + mojom::blink::ConsoleMessageSource::kRendering, + mojom::blink::ConsoleMessageLevel::kWarning, message)); + } if (num_canvas_filter_errors_to_console_allowed_ == 0) { const String& message = "CanvasFilter: too many errors, no more errors will be reported to "
diff --git a/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder.cc b/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder.cc index e461d8d..5410ab9 100644 --- a/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder.cc +++ b/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder.cc
@@ -4,6 +4,8 @@ #include "third_party/blink/renderer/modules/ml/webnn/ml_graph_builder.h" +#include <algorithm> + #include "base/numerics/checked_math.h" #include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_ml_clamp_options.h" @@ -13,7 +15,6 @@ #include "third_party/blink/renderer/bindings/modules/v8/v8_ml_pool_2d_options.h" #include "third_party/blink/renderer/modules/ml/ml_context.h" #include "third_party/blink/renderer/modules/ml/webnn/ml_operand.h" -#include "third_party/blink/renderer/modules/ml/webnn/ml_operator.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" namespace blink { @@ -105,6 +106,57 @@ return true; } +absl::optional<Vector<int32_t>> BroadcastShapes(const Vector<int32_t>& dims_a, + const Vector<int32_t>& dims_b) { + // According WebNN spec: + // https://www.w3.org/TR/webnn/#api-mlgraphbuilder-binary, the element-wise + // binary operation will be broadcasted according to numpy-broadcasting-rule: + // https://numpy.org/doc/stable/user/basics.broadcasting.html#general-broadcasting-rules. + // The rank of the output tensor is the maximum rank of the input tensors. + auto rank_a = dims_a.size(), rank_b = dims_b.size(); + auto rank_output = std::max(rank_a, rank_b); + Vector<int32_t> dims_output(rank_output); + for (wtf_size_t i = 0; i < rank_output; ++i) { + auto dim_a = i < rank_a ? dims_a[rank_a - i - 1] : 1; + DCHECK_GT(dim_a, 0); + auto dim_b = i < rank_b ? dims_b[rank_b - i - 1] : 1; + DCHECK_GT(dim_b, 0); + // Two dimensions are compatible when they are equal, or one of them is 1. + if (dim_a != dim_b && dim_a != 1 && dim_b != 1) { + return absl::nullopt; + } + // For each dimension of the output tensor, its size is the maximum size + // along that dimension of the input tensors. + dims_output[rank_output - i - 1] = std::max(dim_a, dim_b); + } + return dims_output; +} + +MLOperand* BuildElementWiseBinary(MLGraphBuilder* builder, + MLOperator::OperatorKind kind, + const MLOperand* a, + const MLOperand* b, + ExceptionState& exception_state) { + if (a->Type() != b->Type()) { + exception_state.ThrowDOMException(DOMExceptionCode::kDataError, + "The input types don't match."); + return nullptr; + } + absl::optional<Vector<int32_t>> dims_output = + BroadcastShapes(a->Dimensions(), b->Dimensions()); + if (!dims_output) { + exception_state.ThrowDOMException( + DOMExceptionCode::kDataError, + "The input shapes are not broadcastable."); + return nullptr; + } + auto* binary = MakeGarbageCollected<MLOperator>(builder, kind); + auto* output = MLOperand::CreateOutput( + builder, a->Type(), std::move(dims_output.value()), binary); + binary->Connect({a, b}, {output}); + return output; +} + } // namespace // static @@ -207,15 +259,19 @@ return nullptr; } -MLOperand* MLGraphBuilder::add(const MLOperand* a, - const MLOperand* b, - ExceptionState& exception_state) { - // TODO(crbug.com/1273291): Implement this on operating systems to access - // hardware acceleration. - exception_state.ThrowDOMException(DOMExceptionCode::kNotSupportedError, - "Not implemented"); - return nullptr; -} +#define BUILD_ELEMENTWISE_BINARY_OP(op, op_kind) \ + MLOperand* MLGraphBuilder::op(const MLOperand* a, const MLOperand* b, \ + ExceptionState& exception_state) { \ + return BuildElementWiseBinary(this, MLOperator::OperatorKind::op_kind, a, \ + b, exception_state); \ + } + +BUILD_ELEMENTWISE_BINARY_OP(add, kAdd) +BUILD_ELEMENTWISE_BINARY_OP(sub, kSub) +BUILD_ELEMENTWISE_BINARY_OP(mul, kMul) +BUILD_ELEMENTWISE_BINARY_OP(div, kDiv) +BUILD_ELEMENTWISE_BINARY_OP(min, kMin) +BUILD_ELEMENTWISE_BINARY_OP(max, kMax) MLOperand* MLGraphBuilder::gemm(const MLOperand* a, const MLOperand* b,
diff --git a/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder.h b/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder.h index 2d4fc49..8a14ad3 100644 --- a/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder.h +++ b/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder.h
@@ -7,6 +7,7 @@ #include "third_party/blink/renderer/core/typed_arrays/array_buffer_view_helpers.h" #include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer_view.h" +#include "third_party/blink/renderer/modules/ml/webnn/ml_operator.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" #include "third_party/blink/renderer/platform/heap/collection_support/heap_vector.h" #include "third_party/blink/renderer/platform/heap/member.h" @@ -22,7 +23,6 @@ class MLPool2dOptions; class MLOperand; class MLOperandDescriptor; -class MLOperator; typedef HeapVector<std::pair<String, Member<MLOperand>>> MLNamedOperands; @@ -65,6 +65,21 @@ MLOperand* add(const MLOperand* a, const MLOperand* b, ExceptionState& exception_state); + MLOperand* sub(const MLOperand* a, + const MLOperand* b, + ExceptionState& exception_state); + MLOperand* mul(const MLOperand* a, + const MLOperand* b, + ExceptionState& exception_state); + MLOperand* div(const MLOperand* a, + const MLOperand* b, + ExceptionState& exception_state); + MLOperand* max(const MLOperand* a, + const MLOperand* b, + ExceptionState& exception_state); + MLOperand* min(const MLOperand* a, + const MLOperand* b, + ExceptionState& exception_state); MLOperand* gemm(const MLOperand* a, const MLOperand* b,
diff --git a/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder.idl b/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder.idl index a5d03b59..97932ad8 100644 --- a/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder.idl +++ b/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder.idl
@@ -70,6 +70,11 @@ // Element-wise binary operations [RaisesException] MLOperand add(MLOperand a, MLOperand b); + [RaisesException] MLOperand sub(MLOperand a, MLOperand b); + [RaisesException] MLOperand mul(MLOperand a, MLOperand b); + [RaisesException] MLOperand div(MLOperand a, MLOperand b); + [RaisesException] MLOperand max(MLOperand a, MLOperand b); + [RaisesException] MLOperand min(MLOperand a, MLOperand b); [RaisesException] MLOperand gemm(MLOperand a, MLOperand b, optional MLGemmOptions options = {});
diff --git a/third_party/blink/renderer/modules/ml/webnn/ml_operator.h b/third_party/blink/renderer/modules/ml/webnn/ml_operator.h index 50b8ea8..b7373be 100644 --- a/third_party/blink/renderer/modules/ml/webnn/ml_operator.h +++ b/third_party/blink/renderer/modules/ml/webnn/ml_operator.h
@@ -22,7 +22,14 @@ public: enum class OperatorKind { // Keep the order as the same as build methods of MLGraphBuilder. - kClamp + kClamp, + // Element-wise binary operations + kAdd, + kSub, + kMul, + kDiv, + kMax, + kMin }; MLOperator(MLGraphBuilder* builder, OperatorKind kind,
diff --git a/third_party/blink/renderer/modules/webaudio/script_processor_node_test.cc b/third_party/blink/renderer/modules/webaudio/script_processor_node_test.cc index 333df09..429eabd9 100644 --- a/third_party/blink/renderer/modules/webaudio/script_processor_node_test.cc +++ b/third_party/blink/renderer/modules/webaudio/script_processor_node_test.cc
@@ -28,7 +28,7 @@ EXPECT_EQ(2u, handler.shared_input_buffers_.size()); EXPECT_EQ(2u, handler.shared_input_buffers_.size()); } - BaseAudioContext::GraphAutoLocker locker(context); + BaseAudioContext::GraphAutoLocker graph_locker(context); handler.Dispose(); // Buffers should live after dispose() because an audio thread is using // them.
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_adapter.cc b/third_party/blink/renderer/modules/webgpu/gpu_adapter.cc index 3234b5b..d4f63c0c 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_adapter.cc +++ b/third_party/blink/renderer/modules/webgpu/gpu_adapter.cc
@@ -178,7 +178,10 @@ ScriptPromise GPUAdapter::requestDevice(ScriptState* script_state, GPUDeviceDescriptor* descriptor) { - auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); + auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>( + script_state, + ExceptionContext(ExceptionContext::Context::kOperationInvoke, + "GPUAdapter", "requestDevice")); ScriptPromise promise = resolver->Promise(); WGPUDeviceDescriptor dawn_desc = {}; @@ -200,6 +203,12 @@ // Insert features into a set to dedup them. HashSet<WGPUFeatureName> required_features_set; for (const V8GPUFeatureName& f : descriptor->requiredFeatures()) { + // If the feature is not a valid feature reject with a type error. + if (!features_->has(f.AsString())) { + resolver->RejectWithTypeError( + String::Format("Unsupported feature: %s", f.AsCStr())); + return promise; + } required_features_set.insert(AsDawnEnum(f)); }
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 266ec5a..9ebd2a53 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
@@ -940,13 +940,14 @@ CcEffectType type; }; Vector<PendingClip> pending_clips; - const ClipPaintPropertyNode* clip = &target_clip; - for (; clip && clip != current_.clip; clip = clip->UnaliasedParent()) { - if (auto type = SyntheticEffectType(*clip)) - pending_clips.emplace_back(PendingClip{clip, type}); + const ClipPaintPropertyNode* clip_node = &target_clip; + for (; clip_node && clip_node != current_.clip; + clip_node = clip_node->UnaliasedParent()) { + if (auto type = SyntheticEffectType(*clip_node)) + pending_clips.emplace_back(PendingClip{clip_node, type}); } - if (!clip) { + if (!clip_node) { // TODO(crbug.com/803649): We still have clip hierarchy issues with // fragment clips. See crbug.com/1238656 for the test case. Will change // the above condition to DCHECK after LayoutNGBlockFragmentation is fully
diff --git a/third_party/blink/renderer/platform/loader/fetch/client_hints_preferences.cc b/third_party/blink/renderer/platform/loader/fetch/client_hints_preferences.cc index 52f5f848..e6b3b7f 100644 --- a/third_party/blink/renderer/platform/loader/fetch/client_hints_preferences.cc +++ b/third_party/blink/renderer/platform/loader/fetch/client_hints_preferences.cc
@@ -92,9 +92,9 @@ if (context) { for (const auto& elem : network::GetClientHintToNameMap()) { - const auto& type = elem.first; - if (enabled_hints_.IsEnabled(type)) - context->CountClientHints(type); + const auto& hint_type = elem.first; + if (enabled_hints_.IsEnabled(hint_type)) + context->CountClientHints(hint_type); } } return true;
diff --git a/third_party/blink/renderer/platform/peerconnection/stats_collecting_decoder.cc b/third_party/blink/renderer/platform/peerconnection/stats_collecting_decoder.cc index c0232df..d206680 100644 --- a/third_party/blink/renderer/platform/peerconnection/stats_collecting_decoder.cc +++ b/third_party/blink/renderer/platform/peerconnection/stats_collecting_decoder.cc
@@ -156,9 +156,9 @@ int pixel_size = static_cast<int>(decodedImage.size()); bool is_hardware_accelerated = decoder_->GetDecoderInfo().is_hardware_accelerated; - float decode_time_ms = decodedImage.processing_time()->Elapsed().ms(); + float processing_time_ms = decodedImage.processing_time()->Elapsed().ms(); - AddProcessingTime(pixel_size, is_hardware_accelerated, decode_time_ms, + AddProcessingTime(pixel_size, is_hardware_accelerated, processing_time_ms, number_of_new_keyframes, now); } }
diff --git a/third_party/blink/renderer/platform/webrtc/webrtc_video_frame_adapter.cc b/third_party/blink/renderer/platform/webrtc/webrtc_video_frame_adapter.cc index 6a72913..cdc9622 100644 --- a/third_party/blink/renderer/platform/webrtc/webrtc_video_frame_adapter.cc +++ b/third_party/blink/renderer/platform/webrtc/webrtc_video_frame_adapter.cc
@@ -264,9 +264,9 @@ // copying only the necessary part. if (dst_frame->visible_rect() != source_frame->visible_rect() || dst_frame->natural_size() != source_frame->natural_size()) { - const auto format = dst_frame->format(); + const auto dst_format = dst_frame->format(); dst_frame = media::VideoFrame::WrapVideoFrame( - std::move(dst_frame), format, source_frame->visible_rect(), + std::move(dst_frame), dst_format, source_frame->visible_rect(), source_frame->natural_size()); DCHECK(dst_frame); }
diff --git a/third_party/blink/tools/blinkpy/web_tests/port/base.py b/third_party/blink/tools/blinkpy/web_tests/port/base.py index 6f6d320..d30e9ba 100644 --- a/third_party/blink/tools/blinkpy/web_tests/port/base.py +++ b/third_party/blink/tools/blinkpy/web_tests/port/base.py
@@ -271,6 +271,9 @@ self.default_configuration()) if not hasattr(options, 'target') or not options.target: self.set_option_default('target', self._options.configuration) + # set the default to make unit tests happy + if not hasattr(options, 'wpt_only'): + self.set_option_default('wpt_only', False) if not hasattr(options, 'no_virtual_tests'): self.set_option_default('no_virtual_tests', False) self._test_configuration = None @@ -1031,6 +1034,9 @@ def real_tests(self, paths): """Find all real tests in paths except WPT.""" + if self._options.wpt_only: + return [] + # When collecting test cases, skip these directories. skipped_directories = set([ 'platform', 'resources', 'support', 'script-tests', 'reference',
diff --git a/third_party/blink/tools/blinkpy/web_tests/run_web_tests.py b/third_party/blink/tools/blinkpy/web_tests/run_web_tests.py index fdb539f..d79a8579 100644 --- a/third_party/blink/tools/blinkpy/web_tests/run_web_tests.py +++ b/third_party/blink/tools/blinkpy/web_tests/run_web_tests.py
@@ -329,6 +329,10 @@ dest='build', action='store_false', help="Don't check to see if the build is up to date."), + optparse.make_option('--wpt-only', + action='store_true', + default=False, + help=('Run web platform tests only.')), optparse.make_option('--no-virtual-tests', action='store_true', default=False,
diff --git a/third_party/blink/web_tests/FlagExpectations/highdpi b/third_party/blink/web_tests/FlagExpectations/highdpi index 5c9c4458..5a6ed789 100644 --- a/third_party/blink/web_tests/FlagExpectations/highdpi +++ b/third_party/blink/web_tests/FlagExpectations/highdpi
@@ -1174,7 +1174,10 @@ paint/invalidation/outline/focus-layers.html [ Pass ] paint/invalidation/overflow/composited-overflow-with-borderbox-background.html [ Pass ] paint/invalidation/position/absolute-position-changed.html [ Pass ] -paint/invalidation/reflection/reflection-with-rotation.html [ Pass ] + +# TODO(michaelludwig): Suppressed for Skia roll, see crbug.com/1354678 +paint/invalidation/reflection/reflection-with-rotation.html [ Pass Failure ] + paint/invalidation/scroll/destroy-composited-scrollbar.html [ Pass ] paint/invalidation/selection/selection-within-composited-scroller.html [ Pass ] paint/invalidation/svg/animate-path-morphing.svg [ Pass ]
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index 7338e38..f455be0 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -1623,7 +1623,6 @@ crbug.com/660611 fast/multicol/flexbox/doubly-nested-with-zero-width-flexbox-and-forced-break-crash.html [ Skip ] ### Tests failing with LayoutNGFrameSet enabled: -crbug.com/1346221 external/wpt/css/css-flexbox/frameset-crash.html [ Crash Failure ] crbug.com/1346221 external/wpt/css/css-overflow/overflow-no-frameset-propagation.html [ Failure ] crbug.com/1346221 printing/frameset.html [ Failure ]
diff --git a/third_party/blink/web_tests/android/WebviewWPTExpectations b/third_party/blink/web_tests/android/WebviewWPTExpectations index 3dc9dd0..eb2d599 100644 --- a/third_party/blink/web_tests/android/WebviewWPTExpectations +++ b/third_party/blink/web_tests/android/WebviewWPTExpectations
@@ -1206,7 +1206,6 @@ crbug.com/1050754 external/wpt/css/css-scroll-snap/snap-after-relayout/changing-scroll-snap-type.html [ Failure ] crbug.com/1050754 external/wpt/css/css-scroll-snap/snap-after-relayout/move-current-target.html [ Failure ] crbug.com/1050754 external/wpt/css/css-scroll-snap/snap-after-relayout/remove-current-target.html [ Failure ] -crbug.com/1050754 external/wpt/css/css-scroll-snap/snap-after-relayout/snap-to-different-targets.html [ Failure ] crbug.com/1050754 external/wpt/css/css-scroll-snap/snap-area-capturing-add-scroll-container.html [ Failure ] crbug.com/1050754 external/wpt/css/css-scroll-snap/snap-area-capturing-remove-scroll-container.html [ Failure ] crbug.com/1050754 external/wpt/css/css-scroll-snap/snap-inline-block.html [ Failure Pass ]
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json index d2944e714..cfe1ce3 100644 --- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json +++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
@@ -389744,7 +389744,7 @@ ] }, "scroll-margin-visibility-check.html": [ - "faebf8f0d8f7a3155ec561eb655e3d3b9a27a52a", + "3ac77b2fb50556b588f308047a49eb9a09ecfa72", [ null, {} @@ -389908,14 +389908,14 @@ ] ], "resnap-to-focused.html": [ - "637c578a853b75e2f504961c768277e24dc96f46", + "8f71e16b277ff686767c2b8a38e12e7999122bab", [ null, {} ] ], "snap-to-different-targets.html": [ - "6ceab295e4ce89ff46d8ec3db56c566513098ffa", + "faf6a3c44009c95bd1526ccdb9f9d97b1f42504c", [ null, {} @@ -389974,7 +389974,7 @@ ] ], "snap-to-visible-areas-both.html": [ - "da10f982f1f2dc3a764291ede3c2f13560e36082", + "e6c37f14389d69a38f0963ec6a7ccf4b5f3ecba0", [ null, {}
diff --git a/third_party/blink/web_tests/external/wpt/css/css-scroll-snap/scroll-margin-visibility-check.html b/third_party/blink/web_tests/external/wpt/css/css-scroll-snap/scroll-margin-visibility-check.html index faebf8f0..3ac77b2 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-scroll-snap/scroll-margin-visibility-check.html +++ b/third_party/blink/web_tests/external/wpt/css/css-scroll-snap/scroll-margin-visibility-check.html
@@ -32,11 +32,12 @@ <script> let scroller = document.getElementById("scroller"); let target = document.getElementById("target"); -test(() => { +test(t => { scroller.scrollTo(0, 0); target.focus(); - - assert_true(scroller.scrollTop > 0, "Visibility check should not account for margin"); - assert_true(scroller.scrollLeft > 0, "Visibility check should not account for margin"); + window.requestAnimationFrame(t.step_func_done(() => { + assert_true(scroller.scrollTop > 0, "Visibility check should not account for margin"); + assert_true(scroller.scrollLeft > 0, "Visibility check should not account for margin"); + })); }); </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-scroll-snap/snap-after-relayout/resnap-to-focused.html b/third_party/blink/web_tests/external/wpt/css/css-scroll-snap/snap-after-relayout/resnap-to-focused.html index 637c578..8f71e16 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-scroll-snap/snap-after-relayout/resnap-to-focused.html +++ b/third_party/blink/web_tests/external/wpt/css/css-scroll-snap/snap-after-relayout/resnap-to-focused.html
@@ -71,11 +71,15 @@ unsnappable.focus(); container.style.width = "200px"; var startingRow = container.scrollTop/100 + 1; - assert_equals(startingRow, 2, "Initially snapped to row 2"); + window.requestAnimationFrame(t.step_func_done(() => { + assert_equals(startingRow, 2, "Initially snapped to row 2"); + })); child.focus(); container.style.width = "100px"; var endingRow = container.scrollTop/100 + 1; - assert_equals(endingRow, expectedRow, `After resize, should snap to row ${expectedRow}.`); + window.requestAnimationFrame(t.step_func_done(() => { + assert_equals(endingRow, expectedRow, `After resize, should snap to row ${expectedRow}.`); + })); }); }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-scroll-snap/snap-after-relayout/snap-to-different-targets.html b/third_party/blink/web_tests/external/wpt/css/css-scroll-snap/snap-after-relayout/snap-to-different-targets.html index 6ceab295..faf6a3c4 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-scroll-snap/snap-after-relayout/snap-to-different-targets.html +++ b/third_party/blink/web_tests/external/wpt/css/css-scroll-snap/snap-after-relayout/snap-to-different-targets.html
@@ -74,7 +74,7 @@ const y_target = document.getElementById("y-axis-target"); const scroller = document.getElementById("scroller"); -test(() => { +test(t => { // The scroller should be snapped to the two closest points on first layout. assert_equals(scroller.scrollTop, 200); assert_equals(scroller.scrollLeft, 200); @@ -84,9 +84,11 @@ // The style change makes it impossible for the scroller to snap to both // targets, but at least one of the targets should be preserved. The scroller // should then re-evaluate the snap point for the other axis. - const snapped_to_x = scroller.scrollLeft == 1000 && scroller.scrollTop == 300; - const snapped_to_y = scroller.scrollTop == 1000 && scroller.scrollLeft == 300; - assert_true(snapped_to_x || snapped_to_y); + window.requestAnimationFrame(t.step_func_done(() => { + const snapped_to_x = scroller.scrollLeft == 1000 && scroller.scrollTop == 300; + const snapped_to_y = scroller.scrollTop == 1000 && scroller.scrollLeft == 300; + assert_true(snapped_to_x || snapped_to_y); + })); }, "Scroller should snap to at least one of the targets if unable to snap to\ both after a layout change."); </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-scroll-snap/snap-to-visible-areas-both.html b/third_party/blink/web_tests/external/wpt/css/css-scroll-snap/snap-to-visible-areas-both.html index da10f98..e6c37f1 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-scroll-snap/snap-to-visible-areas-both.html +++ b/third_party/blink/web_tests/external/wpt/css/css-scroll-snap/snap-to-visible-areas-both.html
@@ -54,17 +54,23 @@ <div id="right-top" class="snap"></div> </div> <script> -test(() => { +test(t => { const scroller = document.getElementById("scroller"); scroller.scrollTo(0, 0); - assert_equals(scroller.scrollLeft, 0); - assert_equals(scroller.scrollTop, 0); + window.requestAnimationFrame(t.step_func_done(() => { + assert_equals(scroller.scrollLeft, 0); + assert_equals(scroller.scrollTop, 0); + })); scroller.scrollTo(500, 600); - assert_equals(scroller.scrollLeft, 0); - assert_equals(scroller.scrollTop, 800); + window.requestAnimationFrame(t.step_func_done(() => { + assert_equals(scroller.scrollLeft, 0); + assert_equals(scroller.scrollTop, 800); + })); scroller.scrollTo(600, 500); - assert_equals(scroller.scrollLeft, 800); - assert_equals(scroller.scrollTop, 0); + window.requestAnimationFrame(t.step_func_done(() => { + assert_equals(scroller.scrollLeft, 800); + assert_equals(scroller.scrollTop, 0); + })); }, 'Only snap to visible areas in the case where taking the closest snap point of \ each axis does not snap to a visible area'); </script>
diff --git a/third_party/blink/web_tests/wpt_internal/prerender/resources/background-fetch.https.html b/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/resources/background-fetch.https.html similarity index 100% rename from third_party/blink/web_tests/wpt_internal/prerender/resources/background-fetch.https.html rename to third_party/blink/web_tests/external/wpt/speculation-rules/prerender/resources/background-fetch.https.html
diff --git a/third_party/blink/web_tests/wpt_internal/prerender/resources/web-share.https.html b/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/resources/web-share.https.html similarity index 100% rename from third_party/blink/web_tests/wpt_internal/prerender/resources/web-share.https.html rename to third_party/blink/web_tests/external/wpt/speculation-rules/prerender/resources/web-share.https.html
diff --git a/third_party/blink/web_tests/wpt_internal/prerender/restriction-background-fetch.https.html b/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/restriction-background-fetch.https.html similarity index 89% rename from third_party/blink/web_tests/wpt_internal/prerender/restriction-background-fetch.https.html rename to third_party/blink/web_tests/external/wpt/speculation-rules/prerender/restriction-background-fetch.https.html index dd29d2b..cd1550b8 100644 --- a/third_party/blink/web_tests/wpt_internal/prerender/restriction-background-fetch.https.html +++ b/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/restriction-background-fetch.https.html
@@ -1,18 +1,18 @@ <!DOCTYPE html> -<!-- -This file cannot be upstreamed to WPT until: -* internals.setPermission() usage is replaced with a WebDriver API ---> <title>Access to the Background Fetch API is deferred</title> <meta name="timeout" content="long"> <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="/common/utils.js"></script> <script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script> <script src="/speculation-rules/prerender/resources/utils.js"></script> <body> <script> +setup(() => assertSpeculationRulesIsSupported()); + promise_test(async t => { const uid = token(); const bc = new PrerenderChannel('test-channel', uid); @@ -22,8 +22,7 @@ // backgroundFetch.fetch() waits until the permission is granted, which // is deferred during prerendering so the test would trivially pass without // the permission. - await internals.setPermission({name: 'background-fetch'}, 'granted', - location.origin, location.origin); + await test_driver.set_permission({ name: "background-fetch" }, "granted"); const gotMessage = new Promise(resolve => { bc.addEventListener('message', e => {
diff --git a/third_party/blink/web_tests/wpt_internal/prerender/restriction-web-share.https.html b/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/restriction-web-share.https.html similarity index 95% rename from third_party/blink/web_tests/wpt_internal/prerender/restriction-web-share.https.html rename to third_party/blink/web_tests/external/wpt/speculation-rules/prerender/restriction-web-share.https.html index a08aa7f..3bc071d 100644 --- a/third_party/blink/web_tests/wpt_internal/prerender/restriction-web-share.https.html +++ b/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/restriction-web-share.https.html
@@ -7,6 +7,7 @@ <script src="/speculation-rules/prerender/resources/utils.js"></script> <body> <script> +setup(() => assertSpeculationRulesIsSupported()); promise_test(async t => { const uid = token();
diff --git a/third_party/blink/web_tests/fast/frames/frameset-dynamic-border-expected.html b/third_party/blink/web_tests/fast/frames/frameset-dynamic-border-expected.html new file mode 100644 index 0000000..926a9ecc --- /dev/null +++ b/third_party/blink/web_tests/fast/frames/frameset-dynamic-border-expected.html
@@ -0,0 +1,9 @@ +<!DOCTYPE html> +<html> +<frameset border="20" rows="50%,*" cols="50%,*"> +<frame></frame> +<frame></frame> +<frame></frame> +<frame></frame> +</frameset> +</html>
diff --git a/third_party/blink/web_tests/fast/frames/frameset-dynamic-border.html b/third_party/blink/web_tests/fast/frames/frameset-dynamic-border.html new file mode 100644 index 0000000..68896f80 --- /dev/null +++ b/third_party/blink/web_tests/fast/frames/frameset-dynamic-border.html
@@ -0,0 +1,17 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<script> +window.onload = () => { + requestAnimationFrame(() => requestAnimationFrame(() => { + document.body.setAttribute('border', '20'); + document.documentElement.removeAttribute('class'); + })); +}; +</script> +<frameset border="6" rows="50%,*" cols="50%,*"> +<frame></frame> +<frame></frame> +<frame></frame> +<frame></frame> +</frameset> +</html>
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/external/wpt/css/css-scroll-snap/scroll-margin-visibility-check-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/external/wpt/css/css-scroll-snap/scroll-margin-visibility-check-expected.txt new file mode 100644 index 0000000..74b35f3 --- /dev/null +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/external/wpt/css/css-scroll-snap/scroll-margin-visibility-check-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +PASS scroll-margin-visibility-check +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/flag-specific/disable-site-isolation-trials/external/wpt/css/css-scroll-snap/scroll-margin-visibility-check-expected.txt b/third_party/blink/web_tests/flag-specific/disable-site-isolation-trials/external/wpt/css/css-scroll-snap/scroll-margin-visibility-check-expected.txt new file mode 100644 index 0000000..74b35f3 --- /dev/null +++ b/third_party/blink/web_tests/flag-specific/disable-site-isolation-trials/external/wpt/css/css-scroll-snap/scroll-margin-visibility-check-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +PASS scroll-margin-visibility-check +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/platform/generic/external/wpt/css/css-scroll-snap/scroll-margin-visibility-check-expected.txt b/third_party/blink/web_tests/platform/generic/external/wpt/css/css-scroll-snap/scroll-margin-visibility-check-expected.txt deleted file mode 100644 index 702fb7f9..0000000 --- a/third_party/blink/web_tests/platform/generic/external/wpt/css/css-scroll-snap/scroll-margin-visibility-check-expected.txt +++ /dev/null
@@ -1,4 +0,0 @@ -This is a testharness.js-based test. -FAIL scroll-margin-visibility-check assert_true: Visibility check should not account for margin expected true got false -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/platform/generic/external/wpt/webnn/idlharness.https.any-expected.txt b/third_party/blink/web_tests/platform/generic/external/wpt/webnn/idlharness.https.any-expected.txt index a24c09f..e500a0f 100644 --- a/third_party/blink/web_tests/platform/generic/external/wpt/webnn/idlharness.https.any-expected.txt +++ b/third_party/blink/web_tests/platform/generic/external/wpt/webnn/idlharness.https.any-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. -Found 386 tests; 146 PASS, 240 FAIL, 0 TIMEOUT, 0 NOTRUN. +Found 386 tests; 151 PASS, 235 FAIL, 0 TIMEOUT, 0 NOTRUN. FAIL idl_test setup promise_test: Unhandled rejection with value: object "TypeError: Failed to construct 'MLGraphBuilder': parameter 1 is not of type 'MLContext'." PASS idl_test validation PASS Partial interface MLContext: original interface defined @@ -168,11 +168,11 @@ PASS MLGraphBuilder interface: operation conv2d(MLOperand, MLOperand, optional MLConv2dOptions) FAIL MLGraphBuilder interface: operation convTranspose2d(MLOperand, MLOperand, optional MLConvTranspose2dOptions) assert_own_property: interface prototype object missing non-static operation expected property "convTranspose2d" missing PASS MLGraphBuilder interface: operation add(MLOperand, MLOperand) -FAIL MLGraphBuilder interface: operation sub(MLOperand, MLOperand) assert_own_property: interface prototype object missing non-static operation expected property "sub" missing -FAIL MLGraphBuilder interface: operation mul(MLOperand, MLOperand) assert_own_property: interface prototype object missing non-static operation expected property "mul" missing -FAIL MLGraphBuilder interface: operation div(MLOperand, MLOperand) assert_own_property: interface prototype object missing non-static operation expected property "div" missing -FAIL MLGraphBuilder interface: operation max(MLOperand, MLOperand) assert_own_property: interface prototype object missing non-static operation expected property "max" missing -FAIL MLGraphBuilder interface: operation min(MLOperand, MLOperand) assert_own_property: interface prototype object missing non-static operation expected property "min" missing +PASS MLGraphBuilder interface: operation sub(MLOperand, MLOperand) +PASS MLGraphBuilder interface: operation mul(MLOperand, MLOperand) +PASS MLGraphBuilder interface: operation div(MLOperand, MLOperand) +PASS MLGraphBuilder interface: operation max(MLOperand, MLOperand) +PASS MLGraphBuilder interface: operation min(MLOperand, MLOperand) FAIL MLGraphBuilder interface: operation pow(MLOperand, MLOperand) assert_own_property: interface prototype object missing non-static operation expected property "pow" missing FAIL MLGraphBuilder interface: operation abs(MLOperand) assert_own_property: interface prototype object missing non-static operation expected property "abs" missing FAIL MLGraphBuilder interface: operation ceil(MLOperand) assert_own_property: interface prototype object missing non-static operation expected property "ceil" missing
diff --git a/third_party/blink/web_tests/platform/generic/webexposed/global-interface-listing-expected.txt b/third_party/blink/web_tests/platform/generic/webexposed/global-interface-listing-expected.txt index 9d18b17a..de1d0855c 100644 --- a/third_party/blink/web_tests/platform/generic/webexposed/global-interface-listing-expected.txt +++ b/third_party/blink/web_tests/platform/generic/webexposed/global-interface-listing-expected.txt
@@ -5128,10 +5128,15 @@ method constant method constructor method conv2d + method div method gemm method input + method max + method min + method mul method reshape method softmax + method sub interface MLModelLoader attribute @@toStringTag method constructor
diff --git a/third_party/blink/web_tests/wpt_internal/attribution-reporting/debug-key.sub.https.html b/third_party/blink/web_tests/wpt_internal/attribution-reporting/debug-key.sub.https.html index c3113bf..7cc032a 100644 --- a/third_party/blink/web_tests/wpt_internal/attribution-reporting/debug-key.sub.https.html +++ b/third_party/blink/web_tests/wpt_internal/attribution-reporting/debug-key.sub.https.html
@@ -19,7 +19,7 @@ }); await registerAttributionSrc(t, {trigger: { - event_trigger_data: [{trigger_data: '0'}], + event_trigger_data: [{}], debug_key: forSource ? undefined : testCase.debugKey, }});
diff --git a/third_party/blink/web_tests/wpt_internal/attribution-reporting/event-level-debug-report.sub.https.html b/third_party/blink/web_tests/wpt_internal/attribution-reporting/event-level-debug-report.sub.https.html index 480c51c..f80d362 100644 --- a/third_party/blink/web_tests/wpt_internal/attribution-reporting/event-level-debug-report.sub.https.html +++ b/third_party/blink/web_tests/wpt_internal/attribution-reporting/event-level-debug-report.sub.https.html
@@ -18,7 +18,7 @@ }); await registerAttributionSrc(t, { trigger: { - event_trigger_data: [{trigger_data: '0'}], + event_trigger_data: [{}], debug_key: trigger_debug_key, }, cookie,
diff --git a/third_party/blink/web_tests/wpt_internal/attribution-reporting/source-priority.sub.https.html b/third_party/blink/web_tests/wpt_internal/attribution-reporting/source-priority.sub.https.html index c6c384f..2971a7b 100644 --- a/third_party/blink/web_tests/wpt_internal/attribution-reporting/source-priority.sub.https.html +++ b/third_party/blink/web_tests/wpt_internal/attribution-reporting/source-priority.sub.https.html
@@ -25,7 +25,7 @@ ]); await registerAttributionSrc(t, {trigger: { - event_trigger_data: [{trigger_data: '0'}], + event_trigger_data: [{}], }}); const payload = await pollEventLevelReports();
diff --git a/third_party/blink/web_tests/wpt_internal/attribution-reporting/source-registration.sub.https.html b/third_party/blink/web_tests/wpt_internal/attribution-reporting/source-registration.sub.https.html index d751c1c..86f187b 100644 --- a/third_party/blink/web_tests/wpt_internal/attribution-reporting/source-registration.sub.https.html +++ b/third_party/blink/web_tests/wpt_internal/attribution-reporting/source-registration.sub.https.html
@@ -27,7 +27,7 @@ }); await registerAttributionSrc(t, {trigger: { - event_trigger_data: [{trigger_data: '0'}], + event_trigger_data: [{}], }}); const payload = await pollEventLevelReports();
diff --git a/third_party/blink/web_tests/wpt_internal/attribution-reporting/trigger-registration.sub.https.html b/third_party/blink/web_tests/wpt_internal/attribution-reporting/trigger-registration.sub.https.html index b9e4b00..f908b7c 100644 --- a/third_party/blink/web_tests/wpt_internal/attribution-reporting/trigger-registration.sub.https.html +++ b/third_party/blink/web_tests/wpt_internal/attribution-reporting/trigger-registration.sub.https.html
@@ -23,7 +23,7 @@ await registerAttributionSrc(t, { trigger: { - event_trigger_data: [{trigger_data: '0'}], + event_trigger_data: [{}], }, method: 'variant', });
diff --git a/third_party/blink/web_tests/wpt_internal/css/css-anchor-position/anchor-name-003.html b/third_party/blink/web_tests/wpt_internal/css/css-anchor-position/anchor-name-003.html new file mode 100644 index 0000000..3c5b5af --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/css/css-anchor-position/anchor-name-003.html
@@ -0,0 +1,136 @@ +<!DOCTYPE html> +<link rel="help" href="https://tabatkins.github.io/specs/css-anchor-position/#determining"> +<link rel="help" href="https://tabatkins.github.io/specs/css-anchor-position/#propdef-anchor-name"> +<link rel="author" href="mailto:kojii@chromium.org"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/check-layout-th.js"></script> +<style> +.relpos { + position: relative; +} +.abspos { + position: absolute; +} +.anchor1 { + anchor-name: --a1; + width: 10px; + height: 10px; + background: orange; +} +.target { + position: absolute; + width: anchor-size(--a1 width); + height: 10px; + background: lime; +} +</style> +<body onload="checkLayout('.target')"> + <!-- In-flow and out-of-flow boxes in a containing block. --> + <div class="relpos"> + <div> + <div class="relpos"> + <div class="abspos"> + <div class="relpos"> + <div class="anchor1" style="position: absolute; width: 10px"></div> + <div class="anchor1" style="width: 20px"></div> + <div class="anchor1" style="position: absolute; width: 30px"></div> + <div class="anchor1" style="width: 40px"></div> + <div class="target" data-expected-width=20></div> + </div> + <div class="target" data-expected-width=10></div> + </div> + <div class="target" data-expected-width=0></div> + </div> + <div class="target" data-expected-width=10></div> + </div> + <div class="target" data-expected-width=10></div> + </div> + + <!-- In-flow boxes in ancestors, after the propagated ones. --> + <div class="relpos"> + <div> + <div class="relpos"> + <div class="abspos"> + <div class="relpos"> + <div class="anchor1" style="position: absolute; width: 10px"></div> + <div class="anchor1" style="width: 20px"></div> + <div class="target" data-expected-width=20></div> + </div> + <div class="anchor1" style="width: 50px"></div> + <div class="target" data-expected-width=10></div> + </div> + <div class="target" data-expected-width=0></div> + </div> + <div class="anchor1" style="width: 60px"></div> + <div class="target" data-expected-width=10></div> + </div> + <div class="anchor1" style="width: 70px"></div> + <div class="target" data-expected-width=10></div> + </div> + + <!-- Out-of-flow boxes in ancestors, after the propagated ones. --> + <div class="relpos"> + <div> + <div class="relpos"> + <div class="abspos"> + <div class="relpos"> + <div class="anchor1" style="position: absolute; width: 10px"></div> + <div class="anchor1" style="width: 20px"></div> + <div class="target" data-expected-width=20></div> + </div> + <div class="anchor1" style="position: absolute; width: 110px"></div> + <div class="target" data-expected-width=10></div> + </div> + <div class="target" data-expected-width=0></div> + </div> + <div class="target" data-expected-width=10></div> + </div> + <div class="anchor1" style="position: absolute; width: 100px"></div> + <div class="target" data-expected-width=10></div> + </div> + + <!-- In-flow boxes in ancestors, before the propagated ones. --> + <div class="relpos"> + <div class="anchor1" style="width: 100px"></div> + <div> + <div class="relpos"> + <div class="anchor1" style="width: 110px"></div> + <div class="abspos"> + <div class="anchor1" style="width: 120px"></div> + <div class="relpos"> + <div class="anchor1" style="position: absolute; width: 10px"></div> + <div class="anchor1" style="width: 20px"></div> + <div class="target" data-expected-width=20></div> + </div> + <div class="target" data-expected-width=120></div> + </div> + <div class="target" data-expected-width=110></div> + </div> + <div class="target" data-expected-width=100></div> + </div> + <div class="target" data-expected-width=100></div> + </div> + + <!-- Out-of-flow boxes in ancestors, before the propagated ones. --> + <div class="relpos"> + <div class="anchor1" style="position: absolute; width: 100px"></div> + <div> + <div class="relpos"> + <div class="anchor1" style="position: absolute; width: 110px"></div> + <div class="abspos"> + <div class="anchor1" style="position: absolute; width: 120px"></div> + <div class="relpos"> + <div class="anchor1" style="position: absolute; width: 10px"></div> + <div class="anchor1" style="width: 20px"></div> + <div class="target" data-expected-width=20></div> + </div> + <div class="target" data-expected-width=10></div> + </div> + <div class="target" data-expected-width=0></div> + </div> + <div class="target" data-expected-width=110></div> + </div> + <div class="target" data-expected-width=110></div> + </div> +</body>
diff --git a/tools/binary_size/libsupersize/main.py b/tools/binary_size/libsupersize/main.py index 361b422..f74ccfb 100755 --- a/tools/binary_size/libsupersize/main.py +++ b/tools/binary_size/libsupersize/main.py
@@ -50,7 +50,8 @@ for p in candidates: if p.exists(): return p - raise Exception('Paths do not exist: ' + ', '.join(candidates)) + raise Exception('Paths do not exist: ' + + ', '.join(str(t) for t in candidates)) class _DiffAction:
diff --git a/tools/gritsettings/resource_ids.spec b/tools/gritsettings/resource_ids.spec index ac3ffe5..80f8c8c4 100644 --- a/tools/gritsettings/resource_ids.spec +++ b/tools/gritsettings/resource_ids.spec
@@ -645,6 +645,20 @@ "META": {"join": 2, "sizes": {"includes": [50],}}, "includes": [3440], }, + # Both face_ml_app_bundle_resources.grd and face_ml_app_bundle_mock_resources.grd + # start with the same id because only one of them is built depending on if + # src_internal is available. + "ash/webui/face_ml_app_ui/resources/prod/face_ml_app_bundle_resources.grd": { + "META": {"sizes": {"includes": [120],}}, # Relies on src-internal. + "includes": [3460], + }, + "ash/webui/face_ml_app_ui/resources/mock/face_ml_app_bundle_mock_resources.grd": { + "includes": [3460], + }, + "<(SHARED_INTERMEDIATE_DIR)/ash/webui/face_ml_app_ui/resources/untrusted/ash_face_ml_app_untrusted_resources.grd": { + "META": {"join": 2, "sizes": {"includes": [50],}}, + "includes": [3480], + }, # END chromeos/ section. # START components/ section.
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 8e5ec98..9c14ce18 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -11748,6 +11748,11 @@ <int value="1" label="Affected"/> </enum> +<enum name="BooleanAfterPowerOrDisplayChange"> + <int value="0" label="Not After Power or Display Change"/> + <int value="1" label="After Power or Display Change"/> +</enum> + <enum name="BooleanAllowed"> <int value="0" label="Not Allowed"/> <int value="1" label="Allowed"/> @@ -48163,6 +48168,14 @@ </int> </enum> +<enum name="HistoryClustersSurvey"> + <summary> + Logs which HaTS survey was requested by the History Clusters UI code. + </summary> + <int value="0" label="HistoryEntrypointSurveyRequested"/> + <int value="1" label="OmniboxEntrypointSurveyRequested"/> +</enum> + <enum name="HistoryFaviconsRecoveryEnum"> <obsolete> History.FaviconsRecovery no longer tracked as of March 2017. @@ -48682,6 +48695,11 @@ <int value="-2147157503" label="media::kErrorInitializeMediaFoundation"/> <int value="-2147157502" label="media::kErrorInitializeVideoWindowClass"/> <int value="-2147157501" label="media::kErrorCdmProxyReceivedInInvalidState"/> + <int value="-2147157500" + label="media::kErrorResolveCoreWinRTStringDelayload"/> + <int value="-2147157499" label="media::kErrorZeroProtectionSystemId"/> + <int value="-2147157498" label="media::kErrorLoadLibrary"/> + <int value="-2147157497" label="media::kErrorGetFunctionPointer"/> <int value="-2147024894" label="ERROR_FILE_NOT_FOUND"/> <int value="-2147024893" label="ERROR_PATH_NOT_FOUND"/> <int value="-2147024891" label="E_ACCESSDENIED"/> @@ -56773,6 +56791,7 @@ <int value="-1611357520" label="MediaAppPdfInInk:enabled"/> <int value="-1611305202" label="KeepPrefetchedContentSuggestions:disabled"/> <int value="-1609065859" label="ClipboardCustomFormats:enabled"/> + <int value="-1608869911" label="RobustAudioDeviceSelectLogic:enabled"/> <int value="-1607953813" label="AndroidPartnerCustomizationPhenotype:enabled"/> <int value="-1607691647" label="MojoVideoEncodeAccelerator:disabled"/> @@ -58485,6 +58504,7 @@ <int value="-577982497" label="CupsPrintersUiOverhaul:enabled"/> <int value="-577503348" label="GridTabSwitcherForTablets:disabled"/> <int value="-576759065" label="HoldingSpaceInProgressAnimationV2:disabled"/> + <int value="-576475188" label="BorealisForceDoubleScale:disabled"/> <int value="-575081438" label="OmniboxMostVisitedTilesFadingOnTablet:disabled"/> <int value="-574965003" label="LauncherLacrosIntegration:disabled"/> @@ -60667,6 +60687,7 @@ <int value="793816915" label="MessagesForAndroidPopupBlocked:disabled"/> <int value="797344274" label="OmniboxTriggerForPrerender2:disabled"/> <int value="797924041" label="DeferredShaping:enabled"/> + <int value="798414711" label="BorealisForceDoubleScale:enabled"/> <int value="798696013" label="ImeInputLogicMozc:enabled"/> <int value="798803191" label="ShareToGoogleCollections:disabled"/> <int value="799680074" label="ContextualSearchTranslationModel:enabled"/> @@ -62067,6 +62088,7 @@ <int value="1692847616" label="ArcEnableWebAppShare:enabled"/> <int value="1693094211" label="FilesNG:disabled"/> <int value="1693658048" label="AppsShortcutDefaultOff:enabled"/> + <int value="1694663094" label="RobustAudioDeviceSelectLogic:disabled"/> <int value="1694766748" label="AutofillRestrictUnownedFieldsToFormlessCheckout:enabled"/> <int value="1694798717" label="NewNetErrorPageUI:enabled"/>
diff --git a/tools/metrics/histograms/metadata/METRIC_REVIEWER_OWNERS b/tools/metrics/histograms/metadata/METRIC_REVIEWER_OWNERS index a767e0e..4c54f0fc 100644 --- a/tools/metrics/histograms/metadata/METRIC_REVIEWER_OWNERS +++ b/tools/metrics/histograms/metadata/METRIC_REVIEWER_OWNERS
@@ -110,5 +110,6 @@ xuhong@chromium.org yigu@chromium.org yuhsuan@chromium.org +yyanagisawa@chromium.org zentaro@chromium.org zmin@chromium.org
diff --git a/tools/metrics/histograms/metadata/cryptohome/histograms.xml b/tools/metrics/histograms/metadata/cryptohome/histograms.xml index 60b30fb..b19376f 100644 --- a/tools/metrics/histograms/metadata/cryptohome/histograms.xml +++ b/tools/metrics/histograms/metadata/cryptohome/histograms.xml
@@ -474,6 +474,21 @@ </summary> </histogram> +<histogram name="Cryptohome.LECredential.LogReplayEntryCount" units="count" + expires_after="2023-08-19"> + <owner>hcyang@google.com</owner> + <owner>cros-hwsec+uma@chromium.org</owner> + <summary> + How many log entries are used to reconstruct a stale hash tree, for Low + Entropy (LE) credential management. This reflects whether the log entries + stored at LE credential server side are sufficient for recovering situations + where the LE credential client and server are not synced. This is logged + every time the client loses sync with the server (might happen during + authentication and credential management operations), and attempts to use + the LogReplay command to sync server state again. + </summary> +</histogram> + <histogram name="Cryptohome.LegacyCodePathUsage.{Location}" enum="BooleanCodePathUsage" expires_after="2022-01-09"> <owner>hardikgoyal@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/history/histograms.xml b/tools/metrics/histograms/metadata/history/histograms.xml index 8369ee8..ce73d2c 100644 --- a/tools/metrics/histograms/metadata/history/histograms.xml +++ b/tools/metrics/histograms/metadata/history/histograms.xml
@@ -1030,6 +1030,57 @@ </summary> </histogram> +<histogram name="History.Clusters.Survey.CanShowAnySurvey" enum="Boolean" + expires_after="2022-12-01"> + <owner>tommycli@chromium.org</owner> + <owner>chrome-journeys@google.com</owner> + <component>UI>Browser>Journeys</component> + <summary> + Recorded each time a History Clusters HaTS survey was requested. Records if + the HaTS service can show ANY survey BEFORE we make the actual request. + + Used for debugging missing HaTs survey impressions. + </summary> +</histogram> + +<histogram name="History.Clusters.Survey.CanShowSurvey" enum="Boolean" + expires_after="2022-12-01"> + <owner>tommycli@chromium.org</owner> + <owner>chrome-journeys@google.com</owner> + <component>UI>Browser>Journeys</component> + <summary> + Recorded each time a History Clusters HaTS survey was requested. Records if + the HaTS service can show this survey BEFORE we make the actual request. + + Used for debugging missing HaTs survey impressions. + </summary> +</histogram> + +<histogram name="History.Clusters.Survey.Requested" + enum="HistoryClustersSurvey" expires_after="2022-12-01"> + <owner>tommycli@chromium.org</owner> + <owner>chrome-journeys@google.com</owner> + <component>UI>Browser>Journeys</component> + <summary> + Recorded each time a History Clusters HaTS survey was requested. Records + which entrypoint survey was requested. + </summary> +</histogram> + +<histogram name="History.Clusters.Survey.Success" enum="Boolean" + expires_after="2022-12-01"> + <owner>tommycli@chromium.org</owner> + <owner>chrome-journeys@google.com</owner> + <component>UI>Browser>Journeys</component> + <summary> + Recorded each time a History Clusters HaTS survey was requested. Records if + the survey request succeeded. Note that a true count doesn't mean that the + survey was actually shown. It only measures if the HaTS service accepted the + request. The survey may still not be shown by HaTS for a different reason, + such as another survey being shown too recently. + </summary> +</histogram> + <histogram name="History.Clusters.UIActions.Cluster.{ClusterAction}" units="index" expires_after="2022-08-25"> <owner>mahmadi@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/media/histograms.xml b/tools/metrics/histograms/metadata/media/histograms.xml index ab65edd..dce2dec9 100644 --- a/tools/metrics/histograms/metadata/media/histograms.xml +++ b/tools/metrics/histograms/metadata/media/histograms.xml
@@ -2401,6 +2401,39 @@ <token key="EmeApi" variants="EmeApi"/> </histogram> +<histogram name="Media.EME.MediaFoundationService.Crash" + enum="BooleanAfterPowerOrDisplayChange" expires_after="2023-05-07"> + <owner>xhwang@chromium.org</owner> + <owner>media-dev@chromium.org</owner> + <summary> + Whether a MediaFoundationService process crash is within 2 seconds after + power or display change. Reported when the MediaFoundationService process + crashes. + </summary> +</histogram> + +<histogram + name="Media.EME.MediaFoundationService.ErrorAfterPowerOrDisplayChange" + enum="Hresult" expires_after="2023-05-07"> + <owner>xhwang@chromium.org</owner> + <owner>media-dev@chromium.org</owner> + <summary> + HRESULTs associated with errors happened in the MediaFoundationService + process within 2 seconds after power or display change. + </summary> +</histogram> + +<histogram + name="Media.EME.MediaFoundationService.ErrorNotAfterPowerOrDisplayChange" + enum="Hresult" expires_after="2023-05-07"> + <owner>xhwang@chromium.org</owner> + <owner>media-dev@chromium.org</owner> + <summary> + HRESULTs associated with errors happened in the MediaFoundationService + process NOT within 2 seconds after power or display change. + </summary> +</histogram> + <histogram name="Media.EME.MediaFoundationService.IsKeySystemSupported" units="ms" expires_after="2023-01-15"> <owner>xhwang@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/navigation/histograms.xml b/tools/metrics/histograms/metadata/navigation/histograms.xml index e0ea0b5..55222166 100644 --- a/tools/metrics/histograms/metadata/navigation/histograms.xml +++ b/tools/metrics/histograms/metadata/navigation/histograms.xml
@@ -1542,7 +1542,8 @@ </summary> </histogram> -<histogram name="Prerender.Experimental.ActivationNavigationParamsMatch" +<histogram + name="Prerender.Experimental.ActivationNavigationParamsMatch{PrerenderTriggerType}" enum="PrerenderActivationNavigationParamsMatch" expires_after="2022-12-05"> <owner>nhiroki@chromium.org</owner> <owner>chrome-prerendering@google.com</owner> @@ -1551,6 +1552,7 @@ parameters and the prerender activation navigation parameters. Recorded by PrerenderHost in the browser process when comparing these two parameters. </summary> + <token key="PrerenderTriggerType" variants="PrerenderTriggerType"/> </histogram> <histogram
diff --git a/tools/metrics/histograms/metadata/service/OWNERS b/tools/metrics/histograms/metadata/service/OWNERS index 695cb2f..7ea7e3e5 100644 --- a/tools/metrics/histograms/metadata/service/OWNERS +++ b/tools/metrics/histograms/metadata/service/OWNERS
@@ -8,3 +8,6 @@ # Secondary ayui@chromium.org + +# Apprentice +yyanagisawa@chromium.org
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json index 8ce797d..de553be 100644 --- a/tools/perf/core/perfetto_binary_roller/binary_deps.json +++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -13,8 +13,8 @@ "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux_arm/49b4b5dcbc312d8d2c3751cf29238b8efeb4e494/trace_processor_shell" }, "mac": { - "hash": "70c67bc92a5d8b81431b10ed8e485fc4063e3935", - "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/mac/95904362be483d694624c5c601a67f4325ce128a/trace_processor_shell" + "hash": "580b5cb2a39277bd4eba98f8d199a2940510ed92", + "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/mac/ee7e55c548972cb286c595a89e308768cff1f379/trace_processor_shell" }, "mac_arm64": { "hash": "e1ad4861384b06d911a65f035317914b8cc975c6",
diff --git a/ui/file_manager/integration_tests/file_manager/recents.js b/ui/file_manager/integration_tests/file_manager/recents.js index 2d86d4e..34e0241 100644 --- a/ui/file_manager/integration_tests/file_manager/recents.js +++ b/ui/file_manager/integration_tests/file_manager/recents.js
@@ -313,7 +313,7 @@ const actualSecondaryText = element.attributes['secondary-text']; if (expectedPrimaryText === actualPrimaryText && - actualSecondaryText === actualSecondaryText) { + expectedSecondaryText === actualSecondaryText) { return; } @@ -1115,6 +1115,7 @@ // Set timezone to Brisbane (GMT+10). await sendTestMessage({name: 'setTimezone', timezone: 'Australia/Brisbane'}); const testFile = prepareFileFor1AMToday('Australia/Brisbane'); + const isEarlierThan2AM = (new Date()).getHours() < 2; // Open Files app and go to Recent tab. const appId = @@ -1138,6 +1139,15 @@ // Set timezone to Perth (GMT+8). await sendTestMessage({name: 'setTimezone', timezone: 'Australia/Perth'}); + // If the OS time before timezone change is earlier than 2am, then after + // timezone change the current date will move to a day before, the OS and + // date and modification date changes at the same time, so it will be "today". + // For example: + // before timezone change: os time 1:30am file modification time: today 1am + // move by -2 hours: os time 11:30pm file modification time: today 11pm + const targetDate = isEarlierThan2AM ? 'Today' : 'Yesterday'; + const targetTime = '11:00 PM'; + // Check date modified column. const caller = getCaller(); await repeatUntil(async () => { @@ -1145,20 +1155,20 @@ await remoteCall.callRemoteTestUtil('getFileList', appId, []); // We need to assert the exact time here, so the timezones before/after // should not involve daylight savings. - if (filesAfter[0][3] === 'Yesterday 11:00 PM') { + if (filesAfter[0][3] === `${targetDate} ${targetTime}`) { return; } return pending( caller, - `Expected modified date to be Yesterday 11pm", got "${ + `Expected modified date to be "${targetDate} ${targetTime}", got "${ filesAfter[0][3]}"`); }); // Check group heading. const groupHeadingAfter = await remoteCall.waitForElement(appId, ['.group-heading']); - chrome.test.assertEq('Yesterday', groupHeadingAfter.text); + chrome.test.assertEq(targetDate, groupHeadingAfter.text); }; @@ -1167,9 +1177,10 @@ * timezone changes. */ testcase.recentsRespondToTimezoneChangeForGridView = async () => { - // Set timezone to Auckland (GMT+12/+13). - await sendTestMessage({name: 'setTimezone', timezone: 'Pacific/Auckland'}); - const testFile = prepareFileFor1AMToday('Pacific/Auckland'); + // Set timezone to Brisbane (GMT+10). + await sendTestMessage({name: 'setTimezone', timezone: 'Australia/Brisbane'}); + const testFile = prepareFileFor1AMToday('Australia/Brisbane'); + const isEarlierThan2AM = (new Date()).getHours() < 2; // Open Files app and go to Recent tab. const appId = @@ -1191,18 +1202,20 @@ // Set timezone to Perth (GMT+8). await sendTestMessage({name: 'setTimezone', timezone: 'Australia/Perth'}); + const targetDate = isEarlierThan2AM ? 'Today' : 'Yesterday'; + // Check group heading. const caller = getCaller(); await repeatUntil(async () => { const groupHeadingAfter = await remoteCall.waitForElement(appId, ['.grid-title']); - if (groupHeadingAfter.text === 'Yesterday') { + if (groupHeadingAfter.text === targetDate) { return; } return pending( caller, - `Expected group heading to be Yesterday", got "${ + `Expected group heading to be "${targetDate}", got "${ groupHeadingAfter.text}"`); }); };
diff --git a/ui/ozone/platform/wayland/host/gtk_primary_selection_device.cc b/ui/ozone/platform/wayland/host/gtk_primary_selection_device.cc index 92bb004a..e49f782d 100644 --- a/ui/ozone/platform/wayland/host/gtk_primary_selection_device.cc +++ b/ui/ozone/platform/wayland/host/gtk_primary_selection_device.cc
@@ -31,7 +31,7 @@ auto* data_source = source ? source->data_source() : nullptr; gtk_primary_selection_device_set_selection(data_device_.get(), data_source, serial); - connection()->ScheduleFlush(); + connection()->Flush(); } // static
diff --git a/ui/ozone/platform/wayland/host/gtk_primary_selection_device_manager.cc b/ui/ozone/platform/wayland/host/gtk_primary_selection_device_manager.cc index f718cbfe..6ab2bc5 100644 --- a/ui/ozone/platform/wayland/host/gtk_primary_selection_device_manager.cc +++ b/ui/ozone/platform/wayland/host/gtk_primary_selection_device_manager.cc
@@ -65,7 +65,7 @@ connection_, gtk_primary_selection_device_manager_get_device( device_manager_.get(), connection_->seat()->wl_object())); - connection_->ScheduleFlush(); + connection_->Flush(); } DCHECK(device_); return device_.get(); @@ -76,7 +76,7 @@ GtkPrimarySelectionSource::Delegate* delegate) { auto* data_source = gtk_primary_selection_device_manager_create_source(device_manager_.get()); - connection_->ScheduleFlush(); + connection_->Flush(); return std::make_unique<GtkPrimarySelectionSource>(data_source, connection_, delegate); }
diff --git a/ui/ozone/platform/wayland/host/proxy/wayland_proxy.h b/ui/ozone/platform/wayland/host/proxy/wayland_proxy.h index 260b562e..5f286c0 100644 --- a/ui/ozone/platform/wayland/host/proxy/wayland_proxy.h +++ b/ui/ozone/platform/wayland/host/proxy/wayland_proxy.h
@@ -81,9 +81,6 @@ // When this is called, |buffer| becomes invalid and mustn't be used any more. virtual void DestroyShmForWlBuffer(wl_buffer* buffer) = 0; - // Schedules display flush that dispatches pending requests. - virtual void ScheduleDisplayFlush() = 0; - // Immediately flushes pending requests for testing. virtual void FlushForTesting() = 0;
diff --git a/ui/ozone/platform/wayland/host/proxy/wayland_proxy_impl.cc b/ui/ozone/platform/wayland/host/proxy/wayland_proxy_impl.cc index 01c59484..71e12d0 100644 --- a/ui/ozone/platform/wayland/host/proxy/wayland_proxy_impl.cc +++ b/ui/ozone/platform/wayland/host/proxy/wayland_proxy_impl.cc
@@ -74,10 +74,6 @@ shm_buffers_.erase(it); } -void WaylandProxyImpl::ScheduleDisplayFlush() { - connection_->ScheduleFlush(); -} - void WaylandProxyImpl::FlushForTesting() { connection_->Flush(); }
diff --git a/ui/ozone/platform/wayland/host/proxy/wayland_proxy_impl.h b/ui/ozone/platform/wayland/host/proxy/wayland_proxy_impl.h index c1fb56d..8d03a0e 100644 --- a/ui/ozone/platform/wayland/host/proxy/wayland_proxy_impl.h +++ b/ui/ozone/platform/wayland/host/proxy/wayland_proxy_impl.h
@@ -35,7 +35,6 @@ gfx::AcceleratedWidget widget) override; wl_buffer* CreateShmBasedWlBuffer(const gfx::Size& buffer_size) override; void DestroyShmForWlBuffer(wl_buffer* buffer) override; - void ScheduleDisplayFlush() override; void FlushForTesting() override; ui::PlatformWindowType GetWindowType(gfx::AcceleratedWidget widget) override; bool WindowHasPointerFocus(gfx::AcceleratedWidget widget) override;
diff --git a/ui/ozone/platform/wayland/host/wayland_connection.cc b/ui/ozone/platform/wayland/host/wayland_connection.cc index 003c907f..bb2c4e5 100644 --- a/ui/ozone/platform/wayland/host/wayland_connection.cc +++ b/ui/ozone/platform/wayland/host/wayland_connection.cc
@@ -273,20 +273,6 @@ return true; } -void WaylandConnection::ScheduleFlush() { - // When we are in tests, the message loop is set later when the - // initialization of the OzonePlatform complete. Thus, just - // flush directly. This doesn't happen in normal run. - if (!base::CurrentUIThread::IsSet()) { - Flush(); - } else if (!scheduled_flush_) { - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, - base::BindOnce(&WaylandConnection::Flush, base::Unretained(this))); - scheduled_flush_ = true; - } -} - void WaylandConnection::RoundTripQueue() { if (roundtrip_closure_for_testing_) { roundtrip_closure_for_testing_.Run(); @@ -355,7 +341,6 @@ void WaylandConnection::Flush() { wl_display_flush(display_.get()); - scheduled_flush_ = false; } void WaylandConnection::UpdateInputDevices() { @@ -601,7 +586,7 @@ connection->available_globals_.emplace_back(interface, version); - connection->ScheduleFlush(); + connection->Flush(); } base::TimeTicks WaylandConnection::ConvertPresentationTime(uint32_t tv_sec_hi, @@ -666,14 +651,14 @@ uint32_t serial) { WaylandConnection* connection = static_cast<WaylandConnection*>(data); zxdg_shell_v6_pong(shell_v6, serial); - connection->ScheduleFlush(); + connection->Flush(); } // static void WaylandConnection::Ping(void* data, xdg_wm_base* shell, uint32_t serial) { WaylandConnection* connection = static_cast<WaylandConnection*>(data); xdg_wm_base_pong(shell, serial); - connection->ScheduleFlush(); + connection->Flush(); } // static
diff --git a/ui/ozone/platform/wayland/host/wayland_connection.h b/ui/ozone/platform/wayland/host/wayland_connection.h index b45280e..46be0823 100644 --- a/ui/ozone/platform/wayland/host/wayland_connection.h +++ b/ui/ozone/platform/wayland/host/wayland_connection.h
@@ -93,10 +93,7 @@ bool Initialize(); - // Schedules a flush of the Wayland connection. - void ScheduleFlush(); - - // Immediately flushes. Public for testing. + // Immediately flushes the Wayland display. void Flush(); // Calls wl_display_roundtrip_queue. Might be required during initialization @@ -453,8 +450,6 @@ display::TabletState tablet_layout_state_ = display::TabletState::kInClamshellMode; - bool scheduled_flush_ = false; - // Surfaces are submitted in pixel coordinates. Their buffer scales are always // advertised to server as 1, and the scale via vp_viewporter won't be // applied. The server will be responsible to scale the buffers to the right
diff --git a/ui/ozone/platform/wayland/host/wayland_cursor.cc b/ui/ozone/platform/wayland/host/wayland_cursor.cc index babf9c2d..7ec31b4 100644 --- a/ui/ozone/platform/wayland/host/wayland_cursor.cc +++ b/ui/ozone/platform/wayland/host/wayland_cursor.cc
@@ -109,7 +109,7 @@ wl_surface_attach(pointer_surface_.get(), nullptr, 0, 0); wl_surface_commit(pointer_surface_.get()); - connection_->ScheduleFlush(); + connection_->Flush(); if (listener_) listener_->OnCursorBufferAttached(nullptr); @@ -160,7 +160,7 @@ wl_surface_attach(pointer_surface_.get(), buffer, 0, 0); wl_surface_commit(pointer_surface_.get()); - connection_->ScheduleFlush(); + connection_->Flush(); } } // namespace ui
diff --git a/ui/ozone/platform/wayland/host/wayland_data_device.cc b/ui/ozone/platform/wayland/host/wayland_data_device.cc index 0153978..52dc1610 100644 --- a/ui/ozone/platform/wayland/host/wayland_data_device.cc +++ b/ui/ozone/platform/wayland/host/wayland_data_device.cc
@@ -46,7 +46,7 @@ origin_window.root_surface()->surface(), icon_surface, serial); drag_delegate_->DrawIcon(); - connection()->ScheduleFlush(); + connection()->Flush(); } void WaylandDataDevice::ResetDragDelegate() { @@ -78,7 +78,7 @@ uint32_t serial) { auto* data_source = source ? source->data_source() : nullptr; wl_data_device_set_selection(data_device_.get(), data_source, serial); - connection()->ScheduleFlush(); + connection()->Flush(); } void WaylandDataDevice::ReadDragDataFromFD(base::ScopedFD fd, @@ -140,7 +140,7 @@ gfx::PointF(wl_fixed_to_double(x), wl_fixed_to_double(y)), window); self->drag_delegate_->OnDragEnter(window, point, serial); - self->connection()->ScheduleFlush(); + self->connection()->Flush(); } void WaylandDataDevice::OnMotion(void* data, @@ -161,7 +161,7 @@ auto* self = static_cast<WaylandDataDevice*>(data); if (self->drag_delegate_) { self->drag_delegate_->OnDragDrop(); - self->connection()->ScheduleFlush(); + self->connection()->Flush(); } // There are buggy Exo versions, which send 'drop' event (even for @@ -178,7 +178,7 @@ auto* self = static_cast<WaylandDataDevice*>(data); if (self->drag_delegate_) { self->drag_delegate_->OnDragLeave(); - self->connection()->ScheduleFlush(); + self->connection()->Flush(); } self->ResetDragDelegateIfNeeded(); }
diff --git a/ui/ozone/platform/wayland/host/wayland_data_device_base.cc b/ui/ozone/platform/wayland/host/wayland_data_device_base.cc index 95965e5..1f1826c 100644 --- a/ui/ozone/platform/wayland/host/wayland_data_device_base.cc +++ b/ui/ozone/platform/wayland/host/wayland_data_device_base.cc
@@ -72,7 +72,7 @@ wl_callback_add_listener(deferred_read_callback_.get(), &kListener, this); - connection_->ScheduleFlush(); + connection_->Flush(); } void WaylandDataDeviceBase::RegisterDeferredReadClosure(
diff --git a/ui/ozone/platform/wayland/host/wayland_data_drag_controller.cc b/ui/ozone/platform/wayland/host/wayland_data_drag_controller.cc index 8733b4c..30085664 100644 --- a/ui/ozone/platform/wayland/host/wayland_data_drag_controller.cc +++ b/ui/ozone/platform/wayland/host/wayland_data_drag_controller.cc
@@ -210,7 +210,7 @@ DCHECK(self); self->DrawIconInternal(); self->icon_frame_callback_.reset(); - self->connection_->ScheduleFlush(); + self->connection_->Flush(); } void WaylandDataDragController::DrawIconInternal() {
diff --git a/ui/ozone/platform/wayland/host/wayland_data_source.cc b/ui/ozone/platform/wayland/host/wayland_data_source.cc index ad9dd8e..4bcc5ef 100644 --- a/ui/ozone/platform/wayland/host/wayland_data_source.cc +++ b/ui/ozone/platform/wayland/host/wayland_data_source.cc
@@ -119,7 +119,7 @@ const std::vector<std::string>& mime_types) { for (auto& mime_type : mime_types) wl_data_source_offer(data_source_.get(), mime_type.c_str()); - connection_->ScheduleFlush(); + connection_->Flush(); } template <typename T> @@ -154,7 +154,7 @@ const std::vector<std::string>& mime_types) { for (const auto& mime_type : mime_types) gtk_primary_selection_source_offer(data_source_.get(), mime_type.c_str()); - connection_->ScheduleFlush(); + connection_->Flush(); } template <> @@ -173,7 +173,7 @@ for (const auto& mime_type : mime_types) zwp_primary_selection_source_v1_offer(data_source_.get(), mime_type.c_str()); - connection_->ScheduleFlush(); + connection_->Flush(); } template class DataSource<gtk_primary_selection_source>;
diff --git a/ui/ozone/platform/wayland/host/wayland_drm.cc b/ui/ozone/platform/wayland/host/wayland_drm.cc index 12cd565..40d0e42 100644 --- a/ui/ozone/platform/wayland/host/wayland_drm.cc +++ b/ui/ozone/platform/wayland/host/wayland_drm.cc
@@ -56,7 +56,7 @@ &Capabilities, }; wl_drm_add_listener(wl_drm_.get(), &kDrmListener, this); - connection_->ScheduleFlush(); + connection_->Flush(); // A roundtrip after binding guarantees that the client has received all // supported formats and capabilities of the device. @@ -90,7 +90,7 @@ wl::Object<wl_buffer> buffer(wl_drm_create_prime_buffer( wl_drm_.get(), fd.get(), size.width(), size.height(), format, offset[0], stride[0], offset[1], stride[1], offset[2], stride[2])); - connection_->ScheduleFlush(); + connection_->Flush(); std::move(callback).Run(std::move(buffer)); } @@ -144,7 +144,7 @@ } wl_drm_authenticate(wl_drm_.get(), magic); - connection_->ScheduleFlush(); + connection_->Flush(); // Do the roundtrip to make sure the server processes this request and // authenticates us.
diff --git a/ui/ozone/platform/wayland/host/wayland_input_method_context_unittest.cc b/ui/ozone/platform/wayland/host/wayland_input_method_context_unittest.cc index 3907d1d8..fab3a8b 100644 --- a/ui/ozone/platform/wayland/host/wayland_input_method_context_unittest.cc +++ b/ui/ozone/platform/wayland/host/wayland_input_method_context_unittest.cc
@@ -171,7 +171,7 @@ input_method_context_.reset(static_cast<WaylandInputMethodContext*>( input_method_context.release())); input_method_context_->Init(true); - connection_->ScheduleFlush(); + connection_->Flush(); Sync(); // Unset Keyboard focus. @@ -206,7 +206,7 @@ EXPECT_CALL(*zwp_text_input_, ShowInputPanel()).Times(0); input_method_context_->UpdateFocus(true, ui::TEXT_INPUT_TYPE_NONE, ui::TEXT_INPUT_TYPE_TEXT); - connection_->ScheduleFlush(); + connection_->Flush(); Sync(); Mock::VerifyAndClearExpectations(zwp_text_input_); @@ -214,14 +214,14 @@ EXPECT_CALL(*zwp_text_input_, ShowInputPanel()); connection_->wayland_window_manager()->SetKeyboardFocusedWindow( window_.get()); - connection_->ScheduleFlush(); + connection_->Flush(); Sync(); Mock::VerifyAndClearExpectations(zwp_text_input_); EXPECT_CALL(*zwp_text_input_, HideInputPanel()); EXPECT_CALL(*zwp_text_input_, Deactivate()); connection_->wayland_window_manager()->SetKeyboardFocusedWindow(nullptr); - connection_->ScheduleFlush(); + connection_->Flush(); Sync(); Mock::VerifyAndClearExpectations(zwp_text_input_); @@ -229,7 +229,7 @@ EXPECT_CALL(*zwp_text_input_, Deactivate()).Times(0); input_method_context_->UpdateFocus(true, ui::TEXT_INPUT_TYPE_TEXT, ui::TEXT_INPUT_TYPE_NONE); - connection_->ScheduleFlush(); + connection_->Flush(); Sync(); Mock::VerifyAndClearExpectations(zwp_text_input_); @@ -239,7 +239,7 @@ EXPECT_CALL(*zwp_text_input_, ShowInputPanel()).Times(0); connection_->wayland_window_manager()->SetKeyboardFocusedWindow( window_.get()); - connection_->ScheduleFlush(); + connection_->Flush(); Sync(); Mock::VerifyAndClearExpectations(zwp_text_input_); @@ -247,7 +247,7 @@ EXPECT_CALL(*zwp_text_input_, ShowInputPanel()); input_method_context_->UpdateFocus(true, ui::TEXT_INPUT_TYPE_NONE, ui::TEXT_INPUT_TYPE_TEXT); - connection_->ScheduleFlush(); + connection_->Flush(); Sync(); Mock::VerifyAndClearExpectations(zwp_text_input_); @@ -255,14 +255,14 @@ EXPECT_CALL(*zwp_text_input_, Deactivate()); input_method_context_->UpdateFocus(true, ui::TEXT_INPUT_TYPE_TEXT, ui::TEXT_INPUT_TYPE_NONE); - connection_->ScheduleFlush(); + connection_->Flush(); Sync(); Mock::VerifyAndClearExpectations(zwp_text_input_); EXPECT_CALL(*zwp_text_input_, HideInputPanel()).Times(0); EXPECT_CALL(*zwp_text_input_, Deactivate()).Times(0); connection_->wayland_window_manager()->SetKeyboardFocusedWindow(nullptr); - connection_->ScheduleFlush(); + connection_->Flush(); Sync(); Mock::VerifyAndClearExpectations(zwp_text_input_); } @@ -270,14 +270,14 @@ TEST_P(WaylandInputMethodContextTest, Reset) { EXPECT_CALL(*zwp_text_input_, Reset()); input_method_context_->Reset(); - connection_->ScheduleFlush(); + connection_->Flush(); Sync(); } TEST_P(WaylandInputMethodContextTest, SetCursorLocation) { EXPECT_CALL(*zwp_text_input_, SetCursorRect(50, 0, 1, 1)); input_method_context_->SetCursorLocation(gfx::Rect(50, 0, 1, 1)); - connection_->ScheduleFlush(); + connection_->Flush(); Sync(); } @@ -290,7 +290,7 @@ EXPECT_CALL(*zwp_text_input_, SetSurroundingText(_, _)) .WillOnce(DoAll(SaveArg<0>(&sent_text), SaveArg<1>(&sent_range))); input_method_context_->SetSurroundingText(text, range); - connection_->ScheduleFlush(); + connection_->Flush(); Sync(); Mock::VerifyAndClearExpectations(zwp_text_input_); // The text and range sent as wayland protocol must be same to the original @@ -316,7 +316,7 @@ EXPECT_CALL(*zwp_text_input_, SetSurroundingText(_, _)) .WillOnce(DoAll(SaveArg<0>(&sent_text), SaveArg<1>(&sent_range))); input_method_context_->SetSurroundingText(text, range); - connection_->ScheduleFlush(); + connection_->Flush(); Sync(); Mock::VerifyAndClearExpectations(zwp_text_input_); // The text sent as wayland protocol must be at most 4000 byte and long @@ -344,7 +344,7 @@ EXPECT_CALL(*zwp_text_input_, SetSurroundingText(_, _)) .WillOnce(DoAll(SaveArg<0>(&sent_text), SaveArg<1>(&sent_range))); input_method_context_->SetSurroundingText(text, range); - connection_->ScheduleFlush(); + connection_->Flush(); Sync(); Mock::VerifyAndClearExpectations(zwp_text_input_); // The text sent as wayland protocol must be at most 4000 byte and large @@ -373,7 +373,7 @@ EXPECT_CALL(*zwp_text_input_, SetSurroundingText(_, _)) .WillOnce(DoAll(SaveArg<0>(&sent_text), SaveArg<1>(&sent_range))); input_method_context_->SetSurroundingText(text, range); - connection_->ScheduleFlush(); + connection_->Flush(); Sync(); Mock::VerifyAndClearExpectations(zwp_text_input_); // The text sent as wayland protocol must be at most 4000 byte and large @@ -400,7 +400,7 @@ // UTF8 form is longer than 4000 byte. EXPECT_CALL(*zwp_text_input_, SetSurroundingText(_, _)).Times(0); input_method_context_->SetSurroundingText(text, range); - connection_->ScheduleFlush(); + connection_->Flush(); Sync(); } @@ -413,7 +413,7 @@ EXPECT_CALL(*zwp_text_input_, SetSurroundingText(_, _)) .WillOnce(DoAll(SaveArg<0>(&sent_text), SaveArg<1>(&sent_range))); input_method_context_->SetSurroundingText(text, range); - connection_->ScheduleFlush(); + connection_->Flush(); Sync(); Mock::VerifyAndClearExpectations(zwp_text_input_); // The text and range sent as wayland protocol must be same to the original @@ -440,7 +440,7 @@ TEXT_INPUT_MODE_DEFAULT, TEXT_INPUT_FLAG_AUTOCOMPLETE_ON, /*should_do_learning=*/true); - connection_->ScheduleFlush(); + connection_->Flush(); Sync(); } @@ -454,7 +454,7 @@ TEXT_INPUT_MODE_DEFAULT, TEXT_INPUT_FLAG_AUTOCOMPLETE_ON, /*should_do_learning=*/false); - connection_->ScheduleFlush(); + connection_->Flush(); Sync(); } @@ -489,7 +489,7 @@ EXPECT_CALL(*zwp_text_input_, SetSurroundingText("abđcădef", gfx::Range(7, 10))); input_method_context_->SetSurroundingText(text, range); - connection_->ScheduleFlush(); + connection_->Flush(); Sync(); Mock::VerifyAndClearExpectations(zwp_text_input_); @@ -509,7 +509,7 @@ EXPECT_CALL(*zwp_text_input_, SetSurroundingText("abcădef", gfx::Range(3, 6))); input_method_context_->SetSurroundingText(text, range); - connection_->ScheduleFlush(); + connection_->Flush(); Sync(); Mock::VerifyAndClearExpectations(zwp_text_input_); @@ -547,7 +547,7 @@ // SetSurroundingText should be called in UTF-8. EXPECT_CALL(*zwp_text_input_, SetSurroundingText(u8_text, u8_range)); input_method_context_->SetSurroundingText(u16_text, u16_range); - connection_->ScheduleFlush(); + connection_->Flush(); Sync(); Mock::VerifyAndClearExpectations(zwp_text_input_); @@ -575,7 +575,7 @@ // SetSurroundingText should be called in UTF-8. EXPECT_CALL(*zwp_text_input_, SetSurroundingText(u8_text, u8_range)); input_method_context_->SetSurroundingText(u16_text, u16_range); - connection_->ScheduleFlush(); + connection_->Flush(); Sync(); Mock::VerifyAndClearExpectations(zwp_text_input_); @@ -620,14 +620,14 @@ TEST_P(WaylandInputMethodContextTest, DisplayVirtualKeyboard) { EXPECT_CALL(*zwp_text_input_, ShowInputPanel()); EXPECT_TRUE(input_method_context_->DisplayVirtualKeyboard()); - connection_->ScheduleFlush(); + connection_->Flush(); Sync(); } TEST_P(WaylandInputMethodContextTest, DismissVirtualKeyboard) { EXPECT_CALL(*zwp_text_input_, HideInputPanel()); input_method_context_->DismissVirtualKeyboard(); - connection_->ScheduleFlush(); + connection_->Flush(); Sync(); } @@ -635,13 +635,13 @@ EXPECT_FALSE(input_method_context_->IsKeyboardVisible()); zwp_text_input_v1_send_input_panel_state(zwp_text_input_->resource(), 1); - connection_->ScheduleFlush(); + connection_->Flush(); Sync(); EXPECT_TRUE(input_method_context_->IsKeyboardVisible()); zwp_text_input_v1_send_input_panel_state(zwp_text_input_->resource(), 0); - connection_->ScheduleFlush(); + connection_->Flush(); Sync(); EXPECT_FALSE(input_method_context_->IsKeyboardVisible()); @@ -668,7 +668,7 @@ EXPECT_CALL(*zwp_text_input_, ShowInputPanel()); input_method_context_->UpdateFocus(true, ui::TEXT_INPUT_TYPE_NONE, ui::TEXT_INPUT_TYPE_TEXT); - connection_->ScheduleFlush(); + connection_->Flush(); Sync(); Mock::VerifyAndClearExpectations(zwp_text_input_); @@ -676,7 +676,7 @@ EXPECT_CALL(*zwp_text_input_, Deactivate()); input_method_context_->UpdateFocus(false, ui::TEXT_INPUT_TYPE_TEXT, ui::TEXT_INPUT_TYPE_NONE); - connection_->ScheduleFlush(); + connection_->Flush(); Sync(); Mock::VerifyAndClearExpectations(zwp_text_input_); } @@ -690,7 +690,7 @@ EXPECT_CALL(*zwp_text_input_, ShowInputPanel()); input_method_context_->UpdateFocus(true, ui::TEXT_INPUT_TYPE_NONE, ui::TEXT_INPUT_TYPE_TEXT); - connection_->ScheduleFlush(); + connection_->Flush(); Sync(); Mock::VerifyAndClearExpectations(zwp_text_input_); @@ -701,7 +701,7 @@ EXPECT_CALL(*zwp_text_input_, ShowInputPanel()).Times(0); input_method_context_->UpdateFocus(false, ui::TEXT_INPUT_TYPE_TEXT, ui::TEXT_INPUT_TYPE_TEXT); - connection_->ScheduleFlush(); + connection_->Flush(); Sync(); Mock::VerifyAndClearExpectations(zwp_text_input_); }
diff --git a/ui/ozone/platform/wayland/host/wayland_keyboard.cc b/ui/ozone/platform/wayland/host/wayland_keyboard.cc index 5afac64f..33164b2 100644 --- a/ui/ozone/platform/wayland/host/wayland_keyboard.cc +++ b/ui/ozone/platform/wayland/host/wayland_keyboard.cc
@@ -246,7 +246,7 @@ // get spurious repeats. sync_callback_.reset(wl_display_sync(connection_->display_wrapper())); wl_callback_add_listener(sync_callback_.get(), &callback_listener_, this); - connection_->ScheduleFlush(); + connection_->Flush(); } void WaylandKeyboard::DispatchKey(unsigned int key,
diff --git a/ui/ozone/platform/wayland/host/wayland_keyboard_unittest.cc b/ui/ozone/platform/wayland/host/wayland_keyboard_unittest.cc index 817cb534..3cd265cf 100644 --- a/ui/ozone/platform/wayland/host/wayland_keyboard_unittest.cc +++ b/ui/ozone/platform/wayland/host/wayland_keyboard_unittest.cc
@@ -97,7 +97,7 @@ static_cast<base::RunLoop*>(data)->Quit(); }}; wl_callback_add_listener(sync_callback.get(), &listener, &run_loop); - connection_->ScheduleFlush(); + connection_->Flush(); Sync(); server_.Resume();
diff --git a/ui/ozone/platform/wayland/host/wayland_pointer_unittest.cc b/ui/ozone/platform/wayland/host/wayland_pointer_unittest.cc index 3b563cd..86742d5 100644 --- a/ui/ozone/platform/wayland/host/wayland_pointer_unittest.cc +++ b/ui/ozone/platform/wayland/host/wayland_pointer_unittest.cc
@@ -307,13 +307,13 @@ EXPECT_CALL(*pointer_, SetCursor(nullptr, 0, 0)); connection_->SetCursorBitmap({}, {}, 1.0); - connection_->ScheduleFlush(); + connection_->Flush(); Sync(); Mock::VerifyAndClearExpectations(pointer_); EXPECT_CALL(*pointer_, SetCursor(Ne(nullptr), 5, 8)); connection_->SetCursorBitmap({dummy_cursor}, gfx::Point(5, 8), 1.0); - connection_->ScheduleFlush(); + connection_->Flush(); Sync(); Mock::VerifyAndClearExpectations(pointer_); @@ -348,7 +348,7 @@ EXPECT_CALL(*pointer_, SetCursor(Ne(nullptr), 5, 8)) .WillOnce(SaveArg<0>(&surface_resource)); window_->SetCursor(cursor); - connection_->ScheduleFlush(); + connection_->Flush(); wl_pointer_send_leave(pointer_->resource(), ++serial, surface_->resource()); wl_pointer_send_frame(pointer_->resource()); @@ -367,7 +367,7 @@ wl_pointer_send_frame(pointer_->resource()); Sync(); - connection_->ScheduleFlush(); + connection_->Flush(); Sync(); Mock::VerifyAndClearExpectations(pointer_); @@ -376,7 +376,7 @@ wl_pointer_send_leave(pointer_->resource(), ++serial, surface_->resource()); wl_pointer_send_frame(pointer_->resource()); Sync(); - connection_->ScheduleFlush(); + connection_->Flush(); Sync(); Mock::VerifyAndClearExpectations(pointer_); }
diff --git a/ui/ozone/platform/wayland/host/wayland_popup.cc b/ui/ozone/platform/wayland/host/wayland_popup.cc index 7ba8780..8f9f77e7 100644 --- a/ui/ozone/platform/wayland/host/wayland_popup.cc +++ b/ui/ozone/platform/wayland/host/wayland_popup.cc
@@ -124,7 +124,7 @@ return; } - connection()->ScheduleFlush(); + connection()->Flush(); WaylandWindow::Show(inactive); } @@ -147,7 +147,7 @@ decorated_via_aura_popup_ = false; } - connection()->ScheduleFlush(); + connection()->Flush(); } bool WaylandPopup::IsVisible() const {
diff --git a/ui/ozone/platform/wayland/host/wayland_seat.cc b/ui/ozone/platform/wayland/host/wayland_seat.cc index 1d10dd3..25069a5 100644 --- a/ui/ozone/platform/wayland/host/wayland_seat.cc +++ b/ui/ozone/platform/wayland/host/wayland_seat.cc
@@ -132,7 +132,7 @@ } connection_->UpdateInputDevices(); - connection_->ScheduleFlush(); + connection_->Flush(); } } // namespace ui
diff --git a/ui/ozone/platform/wayland/host/wayland_shm.cc b/ui/ozone/platform/wayland/host/wayland_shm.cc index b6de107..6530c88 100644 --- a/ui/ozone/platform/wayland/host/wayland_shm.cc +++ b/ui/ozone/platform/wayland/host/wayland_shm.cc
@@ -61,7 +61,7 @@ with_alpha_channel ? WL_SHM_FORMAT_ARGB8888 : WL_SHM_FORMAT_XRGB8888; wl::Object<wl_buffer> shm_buffer(wl_shm_pool_create_buffer( pool.get(), 0, size.width(), size.height(), size.width() * 4, format)); - connection_->ScheduleFlush(); + connection_->Flush(); return shm_buffer; }
diff --git a/ui/ozone/platform/wayland/host/wayland_surface.cc b/ui/ozone/platform/wayland/host/wayland_surface.cc index 510dbd7..4791b81f 100644 --- a/ui/ozone/platform/wayland/host/wayland_surface.cc +++ b/ui/ozone/platform/wayland/host/wayland_surface.cc
@@ -205,7 +205,7 @@ void WaylandSurface::Commit(bool flush) { wl_surface_commit(surface_.get()); if (flush) - connection_->ScheduleFlush(); + connection_->Flush(); } void WaylandSurface::SetBufferTransform(gfx::OverlayTransform transform) {
diff --git a/ui/ozone/platform/wayland/host/wayland_toplevel_window.cc b/ui/ozone/platform/wayland/host/wayland_toplevel_window.cc index 6eb5502..890de19 100644 --- a/ui/ozone/platform/wayland/host/wayland_toplevel_window.cc +++ b/ui/ozone/platform/wayland/host/wayland_toplevel_window.cc
@@ -130,7 +130,7 @@ else shell_toplevel_->SurfaceResize(connection(), hittest); - connection()->ScheduleFlush(); + connection()->Flush(); } void WaylandToplevelWindow::Show(bool inactive) { @@ -165,7 +165,7 @@ aura_surface_.reset(); } shell_toplevel_.reset(); - connection()->ScheduleFlush(); + connection()->Flush(); } bool WaylandToplevelWindow::IsVisible() const { @@ -182,7 +182,7 @@ if (shell_toplevel_) { shell_toplevel_->SetTitle(title); - connection()->ScheduleFlush(); + connection()->Flush(); } } @@ -257,7 +257,7 @@ // but nothing more happens (until the user moves the mouse over a Lacros // window in which case events will start and the activation will come // through). - connection()->ScheduleFlush(); + connection()->Flush(); } void WaylandToplevelWindow::SizeConstraintsChanged() { @@ -844,7 +844,7 @@ delegate()->OnWindowStateChanged(previous_state_, state_); - connection()->ScheduleFlush(); + connection()->Flush(); } void WaylandToplevelWindow::SetWindowState(PlatformWindowState state) { @@ -875,7 +875,7 @@ if (max_size_dip.has_value()) shell_toplevel_->SetMaxSize(max_size_dip->width(), max_size_dip->height()); - connection()->ScheduleFlush(); + connection()->Flush(); } void WaylandToplevelWindow::SetOrResetRestoredBounds() {
diff --git a/ui/ozone/platform/wayland/host/wayland_window.cc b/ui/ozone/platform/wayland/host/wayland_window.cc index fe929cb9..d200659 100644 --- a/ui/ozone/platform/wayland/host/wayland_window.cc +++ b/ui/ozone/platform/wayland/host/wayland_window.cc
@@ -429,7 +429,7 @@ else frame_insets_px_ = absl::nullopt; UpdateDecorations(); - connection_->ScheduleFlush(); + connection_->Flush(); } void WaylandWindow::SetWindowIcons(const gfx::ImageSkia& window_icon, @@ -550,7 +550,7 @@ if (apply_pending_state_on_update_visual_size_for_testing_) { root_surface_->ApplyPendingState(); - connection_->ScheduleFlush(); + connection_->Flush(); } } @@ -660,7 +660,7 @@ std::vector<gfx::Rect> region{gfx::Rect{size_px_}}; root_surface_->SetOpaqueRegion(®ion); root_surface_->ApplyPendingState(); - connection_->ScheduleFlush(); + connection_->Flush(); return true; } @@ -950,7 +950,7 @@ // window has been applied. SetWindowGeometry(pending_bounds_dip_); AckConfigure(serial); - connection()->ScheduleFlush(); + connection()->Flush(); } else if (!pending_configures_.empty() && pending_bounds_dip_.size() == pending_configures_.back().bounds_dip.size()) { @@ -1045,7 +1045,7 @@ auto serial = result->serial; SetWindowGeometry(result->bounds_dip); AckConfigure(serial); - connection()->ScheduleFlush(); + connection()->Flush(); pending_configures_.erase(pending_configures_.begin(), ++result); return true; }
diff --git a/ui/ozone/platform/wayland/host/wayland_window_drag_controller.cc b/ui/ozone/platform/wayland/host/wayland_window_drag_controller.cc index 191d7e0..c011b05 100644 --- a/ui/ozone/platform/wayland/host/wayland_window_drag_controller.cc +++ b/ui/ozone/platform/wayland/host/wayland_window_drag_controller.cc
@@ -84,7 +84,7 @@ auto* surface = window ? window->root_surface()->surface() : nullptr; zcr_extended_drag_source_v1_drag(source_.get(), surface, offset.x(), offset.y()); - connection_.ScheduleFlush(); + connection_.Flush(); } private:
diff --git a/ui/ozone/platform/wayland/host/wayland_window_unittest.cc b/ui/ozone/platform/wayland/host/wayland_window_unittest.cc index f533ae6..e53eff4 100644 --- a/ui/ozone/platform/wayland/host/wayland_window_unittest.cc +++ b/ui/ozone/platform/wayland/host/wayland_window_unittest.cc
@@ -446,6 +446,10 @@ // window geometry. Emulate updating the visual size (sending the frame // update) for that. window_->UpdateVisualSize(kNormalBounds.size()); + // Setting geometry is double buffered and requires commit called on the + // surface. In production, this is handled during commit of a next frame + // (which also updates visual size). + window_->root_surface()->Commit(); Sync(); @@ -475,6 +479,10 @@ // window geometry. Emulate updating the visual size (sending the frame // update) for that. window_->UpdateVisualSize(kHiDpiSize); + // Setting geometry is double buffered and requires commit called on the + // surface. In production, this is handled during commit of a next frame + // (which also updates visual size). + window_->root_surface()->Commit(); Sync(); @@ -3257,6 +3265,7 @@ bool result = window->RequestSubsurface(); EXPECT_TRUE(result); + connection_->Flush(); WaylandSubsurface* wayland_subsurface = window->wayland_subsurfaces().begin()->get(); @@ -3271,7 +3280,7 @@ wayland_subsurface->ConfigureAndShowSurface( subsurface_bounds, gfx::RectF(0, 0, 640, 480) /*parent_bounds_px*/, 1.f /*buffer_scale*/, nullptr, nullptr); - connection_->ScheduleFlush(); + connection_->Flush(); Sync(); @@ -3351,7 +3360,7 @@ gfx::RectF(0.f, 0.f, 800.f, 600.f), 1.f, nullptr, nullptr); } - connection_->ScheduleFlush(); + connection_->Flush(); Sync(); @@ -3390,7 +3399,7 @@ subsurfaces[2]->ConfigureAndShowSurface(gfx::RectF(1.f, 2.f, 10.f, 20.f), gfx::RectF(0.f, 0.f, 800.f, 600.f), 1.f, nullptr, subsurfaces[0]); - connection_->ScheduleFlush(); + connection_->Flush(); Sync(); VerifyAndClearExpectations(); @@ -3426,7 +3435,7 @@ surface->SetViewportDestination({800, 600}); surface->ApplyPendingState(); surface->Commit(); - connection_->ScheduleFlush(); + connection_->Flush(); Sync(); VerifyAndClearExpectations(); @@ -3442,7 +3451,7 @@ surface->SetViewportDestination({800, 600}); surface->ApplyPendingState(); surface->Commit(); - connection_->ScheduleFlush(); + connection_->Flush(); Sync(); VerifyAndClearExpectations(); @@ -3458,7 +3467,7 @@ surface->SetViewportDestination({1024, 768}); surface->ApplyPendingState(); surface->Commit(); - connection_->ScheduleFlush(); + connection_->Flush(); Sync(); VerifyAndClearExpectations(); @@ -3474,7 +3483,7 @@ surface->SetViewportDestination({1024, 768}); surface->ApplyPendingState(); surface->Commit(); - connection_->ScheduleFlush(); + connection_->Flush(); Sync(); VerifyAndClearExpectations();
diff --git a/ui/ozone/platform/wayland/host/wayland_zwp_linux_dmabuf.cc b/ui/ozone/platform/wayland/host/wayland_zwp_linux_dmabuf.cc index 01ef1ae..3688909 100644 --- a/ui/ozone/platform/wayland/host/wayland_zwp_linux_dmabuf.cc +++ b/ui/ozone/platform/wayland/host/wayland_zwp_linux_dmabuf.cc
@@ -102,7 +102,7 @@ // created buffer and notify the client about it via the |callback|. pending_params_.emplace(std::move(params), std::move(callback)); } - connection_->ScheduleFlush(); + connection_->Flush(); } bool WaylandZwpLinuxDmabuf::CanCreateBufferImmed() const { @@ -148,7 +148,7 @@ pending_params_.erase(it); - connection_->ScheduleFlush(); + connection_->Flush(); } // static
diff --git a/ui/ozone/platform/wayland/host/xdg_foreign_wrapper.cc b/ui/ozone/platform/wayland/host/xdg_foreign_wrapper.cc index be5f284..a5306f0c 100644 --- a/ui/ozone/platform/wayland/host/xdg_foreign_wrapper.cc +++ b/ui/ozone/platform/wayland/host/xdg_foreign_wrapper.cc
@@ -165,7 +165,7 @@ zxdg_exported_v1_add_listener(exported_surface.exported.get(), &kExportedListener, this); exported_surfaces_.emplace_back(std::move(exported_surface)); - connection_->ScheduleFlush(); + connection_->Flush(); } template <> @@ -179,7 +179,7 @@ zxdg_exported_v2_add_listener(exported_surface.exported.get(), &kExportedListener, this); exported_surfaces_.emplace_back(std::move(exported_surface)); - connection_->ScheduleFlush(); + connection_->Flush(); } // static
diff --git a/ui/ozone/platform/wayland/host/xdg_popup_wrapper_impl.cc b/ui/ozone/platform/wayland/host/xdg_popup_wrapper_impl.cc index bcd64d2..1c1b7cb 100644 --- a/ui/ozone/platform/wayland/host/xdg_popup_wrapper_impl.cc +++ b/ui/ozone/platform/wayland/host/xdg_popup_wrapper_impl.cc
@@ -230,7 +230,7 @@ xdg_popup_reposition(xdg_popup_.get(), positioner.get(), ++next_reposition_token_); - connection_->ScheduleFlush(); + connection_->Flush(); return true; }
diff --git a/ui/ozone/platform/wayland/host/xdg_surface_wrapper_impl.cc b/ui/ozone/platform/wayland/host/xdg_surface_wrapper_impl.cc index 2d175c92..5e153eaf 100644 --- a/ui/ozone/platform/wayland/host/xdg_surface_wrapper_impl.cc +++ b/ui/ozone/platform/wayland/host/xdg_surface_wrapper_impl.cc
@@ -40,7 +40,7 @@ } xdg_surface_add_listener(xdg_surface_.get(), &xdg_surface_listener, this); - connection_->ScheduleFlush(); + connection_->Flush(); return true; }
diff --git a/ui/ozone/platform/wayland/host/zwp_primary_selection_device.cc b/ui/ozone/platform/wayland/host/zwp_primary_selection_device.cc index 28f3e8c3c..ce28c94 100644 --- a/ui/ozone/platform/wayland/host/zwp_primary_selection_device.cc +++ b/ui/ozone/platform/wayland/host/zwp_primary_selection_device.cc
@@ -31,7 +31,7 @@ auto* data_source = source ? source->data_source() : nullptr; zwp_primary_selection_device_v1_set_selection(data_device_.get(), data_source, serial); - connection()->ScheduleFlush(); + connection()->Flush(); } // static
diff --git a/ui/ozone/platform/wayland/host/zwp_primary_selection_device_manager.cc b/ui/ozone/platform/wayland/host/zwp_primary_selection_device_manager.cc index 9de4fe37..f1e1fb1e 100644 --- a/ui/ozone/platform/wayland/host/zwp_primary_selection_device_manager.cc +++ b/ui/ozone/platform/wayland/host/zwp_primary_selection_device_manager.cc
@@ -65,7 +65,7 @@ connection_, zwp_primary_selection_device_manager_v1_get_device( device_manager_.get(), connection_->seat()->wl_object())); - connection_->ScheduleFlush(); + connection_->Flush(); } DCHECK(device_); return device_.get(); @@ -76,7 +76,7 @@ ZwpPrimarySelectionSource::Delegate* delegate) { auto* data_source = zwp_primary_selection_device_manager_v1_create_source( device_manager_.get()); - connection_->ScheduleFlush(); + connection_->Flush(); return std::make_unique<ZwpPrimarySelectionSource>(data_source, connection_, delegate); }
diff --git a/ui/ozone/platform/wayland/host/zxdg_surface_v6_wrapper_impl.cc b/ui/ozone/platform/wayland/host/zxdg_surface_v6_wrapper_impl.cc index b02b46a9..b90165f 100644 --- a/ui/ozone/platform/wayland/host/zxdg_surface_v6_wrapper_impl.cc +++ b/ui/ozone/platform/wayland/host/zxdg_surface_v6_wrapper_impl.cc
@@ -43,7 +43,7 @@ zxdg_surface_v6_add_listener(zxdg_surface_v6_.get(), &zxdg_surface_v6_listener, this); - connection_->ScheduleFlush(); + connection_->Flush(); return true; }
diff --git a/ui/webui/resources/cr_components/history_clusters/cluster.html b/ui/webui/resources/cr_components/history_clusters/cluster.html index 697eb4da..a16337a0 100644 --- a/ui/webui/resources/cr_components/history_clusters/cluster.html +++ b/ui/webui/resources/cr_components/history_clusters/cluster.html
@@ -128,14 +128,14 @@ <div class="debug-info">[[cluster.debugInfo]]</div> <div class="timestamp">[[cluster.visits.0.relativeDate]]</div> </div> - <menu-container></menu-container> + <cluster-menu></cluster-menu> </div> <div class="label-row" hidden="[[inSidePanel]]"> <div id="label" class="label"></div> <div class="debug-info">[[cluster.debugInfo]]</div> <div class="timestamp-and-menu"> <div class="timestamp">[[cluster.visits.0.relativeDate]]</div> - <menu-container></menu-container> + <cluster-menu></cluster-menu> </div> </div> <template is="dom-repeat" items="[[visibleVisits_]]">
diff --git a/ui/webui/resources/cr_components/history_clusters/cluster.ts b/ui/webui/resources/cr_components/history_clusters/cluster.ts index 0b2f7693..b89b839 100644 --- a/ui/webui/resources/cr_components/history_clusters/cluster.ts +++ b/ui/webui/resources/cr_components/history_clusters/cluster.ts
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import './menu_container.js'; +import './cluster_menu.js'; import './search_query.js'; import './history_clusters_shared_style.css.js'; import './shared_vars.css.js';
diff --git a/ui/webui/resources/cr_components/history_clusters/menu_container.html b/ui/webui/resources/cr_components/history_clusters/cluster_menu.html similarity index 100% rename from ui/webui/resources/cr_components/history_clusters/menu_container.html rename to ui/webui/resources/cr_components/history_clusters/cluster_menu.html
diff --git a/ui/webui/resources/cr_components/history_clusters/menu_container.ts b/ui/webui/resources/cr_components/history_clusters/cluster_menu.ts similarity index 88% rename from ui/webui/resources/cr_components/history_clusters/menu_container.ts rename to ui/webui/resources/cr_components/history_clusters/cluster_menu.ts index 20d1e35..9d05f3f 100644 --- a/ui/webui/resources/cr_components/history_clusters/menu_container.ts +++ b/ui/webui/resources/cr_components/history_clusters/cluster_menu.ts
@@ -14,8 +14,8 @@ import {CrLazyRenderElement} from '../../cr_elements/cr_lazy_render/cr_lazy_render.js'; import {loadTimeData} from '../../js/load_time_data.m.js'; +import {getTemplate} from './cluster_menu.html.js'; import {URLVisit} from './history_clusters.mojom-webui.js'; -import {getTemplate} from './menu_container.html.js'; /** * @fileoverview This file provides a custom element displaying an action menu. @@ -25,22 +25,22 @@ declare global { interface HTMLElementTagNameMap { - 'menu-container': MenuContainerElement; + 'cluster-menu': ClusterMenuElement; } } -const MenuContainerElementBase = I18nMixin(PolymerElement); +const ClusterMenuElementBase = I18nMixin(PolymerElement); -interface MenuContainerElement { +interface ClusterMenuElement { $: { actionMenu: CrLazyRenderElement<CrActionMenuElement>, actionMenuButton: HTMLElement, }; } -class MenuContainerElement extends MenuContainerElementBase { +class ClusterMenuElement extends ClusterMenuElementBase { static get is() { - return 'menu-container'; + return 'cluster-menu'; } static get template() { @@ -104,4 +104,4 @@ } } -customElements.define(MenuContainerElement.is, MenuContainerElement); +customElements.define(ClusterMenuElement.is, ClusterMenuElement);
diff --git a/ui/webui/resources/cr_components/history_clusters/history_clusters.gni b/ui/webui/resources/cr_components/history_clusters/history_clusters.gni index e7b7653..61ac0eba 100644 --- a/ui/webui/resources/cr_components/history_clusters/history_clusters.gni +++ b/ui/webui/resources/cr_components/history_clusters/history_clusters.gni
@@ -6,7 +6,7 @@ _web_component_files = [ "cluster.ts", "clusters.ts", - "menu_container.ts", + "cluster_menu.ts", "page_favicon.ts", "search_query.ts", "url_visit.ts",
diff --git a/ui/webui/resources/cr_components/history_clusters/url_visit.ts b/ui/webui/resources/cr_components/history_clusters/url_visit.ts index 290a679..194c0ce 100644 --- a/ui/webui/resources/cr_components/history_clusters/url_visit.ts +++ b/ui/webui/resources/cr_components/history_clusters/url_visit.ts
@@ -40,7 +40,7 @@ } } -const MenuContainerElementBase = I18nMixin(PolymerElement); +const ClusterMenuElementBase = I18nMixin(PolymerElement); interface VisitRowElement { $: { @@ -51,7 +51,7 @@ }; } -class VisitRowElement extends MenuContainerElementBase { +class VisitRowElement extends ClusterMenuElementBase { static get is() { return 'url-visit'; }