diff --git a/DEPS b/DEPS index ce290a9..15f06b9 100644 --- a/DEPS +++ b/DEPS
@@ -275,19 +275,19 @@ # 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': 'd78d52a86fa3c646a96cc21a149a4e42467f2871', + 'skia_revision': 'b0831daddc8d12df16dd4d9b2a17686a4e92b15f', # 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': 'd942c5c6ba97760ea343ec8043217ee99c59dfcd', + 'v8_revision': 'd09bd16635919befeb7d86e768285e2ad2d9b5b5', # 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': '54e08a5af1f7ca50d5c154a09cc056166a9e49fa', + 'angle_revision': 'cd80b511ee47200db2c12224a773bc4eb179ab55', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. - 'swiftshader_revision': '39495e438601c5fb4325014ae893b5e8ddc03722', + 'swiftshader_revision': '5ca5b0ae5a7d0a2f05538d405426a5331ffd680b', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. @@ -390,7 +390,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': '09373989ecf3bb551565f2caf7016cb7ed0b7957', + 'dawn_revision': 'e6c03a3799922151e821c57a69c78b5e422ac2a5', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -747,7 +747,7 @@ Var('chromium_git') + '/external/github.com/toji/webvr.info.git' + '@' + 'c58ae99b9ff9e2aa4c524633519570bf33536248', 'src/docs/website': { - 'url': Var('chromium_git') + '/website.git' + '@' + 'c9e8aafa630691bee4a600eda757c133e7ecee5a', + 'url': Var('chromium_git') + '/website.git' + '@' + '1da38cece144a8f2bcbb6f0f1d17486be448f887', }, 'src/ios/third_party/earl_grey2/src': { @@ -756,7 +756,7 @@ }, 'src/ios/third_party/edo/src': { - 'url': Var('chromium_git') + '/external/github.com/google/eDistantObject.git' + '@' + 'c3ff324fbce0c09fe85efad31486c8d33df3cd64', + 'url': Var('chromium_git') + '/external/github.com/google/eDistantObject.git' + '@' + 'a431b7fa37c84b5c5b9ca2851ae046da5b936c29', 'condition': 'checkout_ios', }, @@ -920,7 +920,7 @@ 'packages': [ { 'package': 'chromium/third_party/androidx', - 'version': 'g6lx-mVoDndE0ghMUoFVgf37Jij287NPfrraBvGw2WgC', + 'version': 'D5bTTaUupCRV16Ip4D_XOLIU6YLCyvBCqFzYnvoKsogC', }, ], 'condition': 'checkout_android', @@ -1131,12 +1131,12 @@ # For Linux and Chromium OS. 'src/third_party/cros_system_api': { - 'url': Var('chromium_git') + '/chromiumos/platform2/system_api.git' + '@' + 'a3c1ad164e3eb5ca0330350c35f01f2965c91bbb', + 'url': Var('chromium_git') + '/chromiumos/platform2/system_api.git' + '@' + 'fcfe475ad52efaeda2f78c4a6aad4bda140f57ee', 'condition': 'checkout_linux', }, 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '31140af3cfe21203cd9b48135859654db4d39ca1', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '09c0c073ea80ea33335541e5179c809422fe6fb9', 'src/third_party/devtools-frontend/src': Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'), @@ -1290,7 +1290,7 @@ Var('chromium_git') + '/chromium/deps/hunspell_dictionaries.git' + '@' + '41cdffd71c9948f63c7ad36e1fb0ff519aa7a37e', 'src/third_party/icu': - Var('chromium_git') + '/chromium/deps/icu.git' + '@' + '4c1a868725d1226c13da64e3a5bfff2b8ae1a63b', + Var('chromium_git') + '/chromium/deps/icu.git' + '@' + '165825933050109d8331d0faa56cc9f52460fbbf', 'src/third_party/icu4j': { 'packages': [ @@ -1533,7 +1533,7 @@ }, 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + 'd7010bdf9a07b6182f233797e6cfbf20589bfc62', + Var('android_git') + '/platform/external/perfetto.git' + '@' + 'fecea55a5bc59c274e8200d06cd68260832d5591', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3', @@ -1669,7 +1669,7 @@ 'condition': 'checkout_android', }, - 'src/third_party/vulkan-deps': '{chromium_git}/vulkan-deps@c1e419261c412e7c86a4b57a9a096ee0bbd0eb3b', + 'src/third_party/vulkan-deps': '{chromium_git}/vulkan-deps@0899816630a9ae85789f2455fcbe9ac1b94b7438', 'src/third_party/vulkan_memory_allocator': Var('chromium_git') + '/external/github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator.git' + '@' + 'ebe84bec02c041d28f902da0214bf442743fc907', @@ -1708,7 +1708,7 @@ Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '5f05d6d5e625fe6f04903335473c5638ddf94514', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + '2d4207e85a1478cf5269ca1df4c43522a089c45a', + Var('webrtc_git') + '/src.git' + '@' + '488dd9ad158f80cffe297cd48e91f9b646b770a1', 'src/third_party/libgifcodec': Var('skia_git') + '/libgifcodec' + '@'+ Var('libgifcodec_revision'), @@ -1781,7 +1781,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@b05e115e6fbfd8999958713238909faa8e41d879', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@5a341e08cea8e876756d576036550e1271cd4ea0', 'condition': 'checkout_src_internal', },
diff --git a/WATCHLISTS b/WATCHLISTS index ffe79de9..3c6d47f0 100644 --- a/WATCHLISTS +++ b/WATCHLISTS
@@ -2470,7 +2470,8 @@ 'content_worker': ['blink-worker-reviews@chromium.org', 'kinuko+watch@chromium.org'], 'contextual_search': ['donnd+watch@chromium.org', - 'twellington+watch@chromium.org'], + 'twellington+watch@chromium.org', + 'gangwu+watch@chromium.org'], 'core_web_vitals_plm': ['core-web-vitals-plm-reviews@chromium.org'], 'core_web_vitals_wpt': ['chrome-speed-metrics-core+watchlist@google.com', 'lighthouse-eng-external+watch-speed-metrics@google.com'],
diff --git a/android_webview/BUILD.gn b/android_webview/BUILD.gn index d71a086..85e858d 100644 --- a/android_webview/BUILD.gn +++ b/android_webview/BUILD.gn
@@ -69,15 +69,18 @@ } } -# This version of the WebView APK doesn't include WebLayer java and resources. +# This version of the WebView APK doesn't include WebLayer. # It's used to define the allowlist of resources to be pulled out of language # splits. See |shared_resources_allowlist_target|. standalone_system_webview_apk_tmpl("system_webview_no_weblayer_apk") { exclude_weblayer_java = true apk_name = "SystemWebViewNoWebLayer" + # Don't include any code to speed up compilation. This is used only for the + # resources allowlist. include_32_bit_webview = false include_64_bit_webview = false + omit_dex = true # Adding deps on recycler view in the base WebView APK will end up keeping the # Java in the base APK instead of the WebLayer DFM, even though it is not
diff --git a/android_webview/system_webview_apk_tmpl.gni b/android_webview/system_webview_apk_tmpl.gni index 86f8504..8b3da5cb 100644 --- a/android_webview/system_webview_apk_tmpl.gni +++ b/android_webview/system_webview_apk_tmpl.gni
@@ -45,6 +45,8 @@ "include_64_bit_webview", ]) + _omit_dex = defined(omit_dex) && omit_dex + deps += [ "//android_webview:locale_pak_assets", "//android_webview:pak_file_assets", @@ -80,7 +82,9 @@ } } - product_config_java_packages = [ webview_product_config_java_package ] + if (!_omit_dex) { + product_config_java_packages = [ webview_product_config_java_package ] + } if (webview_includes_weblayer) { if (_is_bundle_module) { @@ -88,7 +92,9 @@ } else { deps += [ "//weblayer:locale_pak_assets" ] } - product_config_java_packages += [ weblayer_product_config_java_package ] + if (!_omit_dex) { + product_config_java_packages += [ weblayer_product_config_java_package ] + } } if (!defined(alternative_android_sdk_dep)) { @@ -106,14 +112,18 @@ "If trichrome library is used, static_library_provider must be set " + "so that a dep can be added on the library APK.") + _include_32_bit_webview = !defined(invoker.include_32_bit_webview) || + invoker.include_32_bit_webview + if (android_64bit_target_cpu) { + _include_64_bit_webview = !defined(invoker.include_64_bit_webview) || + invoker.include_64_bit_webview + } + # Pure 32-bit implies a 32-bit only Webview built on a 64-bit configuration. - _pure_32_bit = - android_64bit_target_cpu && defined(invoker.include_64_bit_webview) && - !invoker.include_64_bit_webview - _pure_64_bit = - android_64bit_target_cpu && defined(invoker.include_32_bit_webview) && - !invoker.include_32_bit_webview + _pure_32_bit = android_64bit_target_cpu && !_include_64_bit_webview + _pure_64_bit = android_64bit_target_cpu && !_include_32_bit_webview not_needed([ + "_include_32_bit_webview", "_pure_32_bit", "_pure_64_bit", ]) @@ -125,7 +135,8 @@ if (!_use_trichrome_library) { shared_resources = true - if (!android_64bit_target_cpu || !_pure_32_bit) { + if ((!android_64bit_target_cpu && _include_32_bit_webview) || + (android_64bit_target_cpu && !_pure_32_bit)) { shared_libraries = [ "//android_webview:libwebviewchromium" ] _include_primary_support = true } @@ -143,16 +154,26 @@ if (android_64bit_target_cpu) { if (invoker.is_64_bit_browser) { native_lib_placeholders = [ "libdummy.so" ] - if (invoker.include_32_bit_webview) { + if (_include_32_bit_webview) { secondary_abi_shared_libraries = [ "//android_webview:monochrome_64($android_secondary_abi_toolchain)" ] _include_secondary_support = true } } else { - if (invoker.include_64_bit_webview) { + if (_include_64_bit_webview) { shared_libraries = [ "//android_webview:monochrome" ] _include_primary_support = true } secondary_native_lib_placeholders = [ "libdummy.so" ] + static_library_provider_use_secondary_abi = true + } + + # http://crbug.com/1042107. + if (is_component_build) { + if (invoker.is_64_bit_browser) { + main_component_library = "libmonochrome_64.cr.so" + } else { + main_component_library = "libmonochrome.cr.so" + } } } else { native_lib_placeholders = [ "libdummy.so" ] @@ -246,7 +267,7 @@ command_line_flags_file = "webview-command-line" } - if (!is_java_debug) { + if (!is_java_debug && !_omit_dex) { proguard_enabled = true if (!defined(proguard_configs)) { proguard_configs = [] @@ -263,13 +284,13 @@ if (_use_trichrome_library) { if (android_64bit_target_cpu) { if (invoker.is_64_bit_browser) { - if (invoker.include_32_bit_webview) { + if (_include_32_bit_webview) { version_code = trichrome_64_32_version_code } else { version_code = trichrome_64_version_code } } else { - if (invoker.include_64_bit_webview) { + if (_include_64_bit_webview) { version_code = trichrome_32_64_version_code } else { version_code = trichrome_32_version_code
diff --git a/ash/DEPS b/ash/DEPS index 93740f0..460ff9f 100644 --- a/ash/DEPS +++ b/ash/DEPS
@@ -78,6 +78,8 @@ # derived from the canonical state in the browser. Using both sources could # create subtle inconsistencies based on when observers are called. "-chromeos/login/login_state", + "+chromeos/ash/components/network", + # TODO(https://crbug.com/1164001): remove when chromeos/network have migrated. "+chromeos/network", # //ash can use the public interfaces of various services. "+chromeos/services/assistant/public" ,
diff --git a/ash/app_list/views/app_list_bubble_apps_page.cc b/ash/app_list/views/app_list_bubble_apps_page.cc index 12c52abe..cd0c053 100644 --- a/ash/app_list/views/app_list_bubble_apps_page.cc +++ b/ash/app_list/views/app_list_bubble_apps_page.cc
@@ -290,11 +290,12 @@ // build a single animation with conditional parts. https://crbug.com/1266020 const int section_offset = is_side_shelf ? -20 : 20; int vertical_offset = 0; - if (continue_section_->GetTasksSuggestionsCount() > 0) { + if (continue_section_->GetVisible() && + continue_section_->GetTasksSuggestionsCount() > 0) { vertical_offset += section_offset; SlideViewIntoPosition(continue_section_, vertical_offset, slide_duration); } - if (recent_apps_->GetItemViewCount() > 0) { + if (recent_apps_->GetVisible() && recent_apps_->GetItemViewCount() > 0) { vertical_offset += section_offset; SlideViewIntoPosition(recent_apps_, vertical_offset, slide_duration); }
diff --git a/ash/app_list/views/app_list_bubble_apps_page_unittest.cc b/ash/app_list/views/app_list_bubble_apps_page_unittest.cc index fa06601..132c2ce6 100644 --- a/ash/app_list/views/app_list_bubble_apps_page_unittest.cc +++ b/ash/app_list/views/app_list_bubble_apps_page_unittest.cc
@@ -325,6 +325,37 @@ EXPECT_TRUE(apps_page->separator_for_test()->GetVisible()); } +// Regression test for https://crbug.com/1329227 +TEST_F(AppListBubbleAppsPageTest, HiddenContinueSectionDoesNotAnimateOnShow) { + base::test::ScopedFeatureList feature_list( + features::kLauncherHideContinueSection); + + // Simulate a user with the continue section hidden on startup. + Shell::Get()->app_list_controller()->SetHideContinueSection(true); + + // Enable animations. + ui::ScopedAnimationDurationScaleMode duration( + ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION); + + // Show the app list with enough items that the continue section and + // recent apps would normally be visible. + auto* helper = GetAppListTestHelper(); + helper->AddContinueSuggestionResults(4); + helper->AddRecentApps(5); + helper->AddAppItems(5); + helper->ShowAppList(); + + // Continue section view is not visible and does not have a layer animation. + auto* continue_section = helper->GetBubbleContinueSectionView(); + EXPECT_FALSE(continue_section->GetVisible()); + EXPECT_FALSE(continue_section->layer()); + + // Recent apps view is not visible and does not have a layer animation. + auto* recent_apps = helper->GetBubbleRecentAppsView(); + EXPECT_FALSE(recent_apps->GetVisible()); + EXPECT_FALSE(recent_apps->layer()); +} + TEST_F(AppListBubbleAppsPageTest, SortAppsMakesA11yAnnouncement) { auto* helper = GetAppListTestHelper(); helper->AddAppItems(5);
diff --git a/ash/ash_strings.grd b/ash/ash_strings.grd index 2b440b71..97e09b88 100644 --- a/ash/ash_strings.grd +++ b/ash/ash_strings.grd
@@ -4691,9 +4691,6 @@ <message name="IDS_APP_LIST_FOLDER_BUTTON_ACCESSIBILE_NAME" desc="The spoken feedback text for navigating to a folder button in top level app list"> Folder <ph name="folder_name">$1<ex>OEM Apps</ex></ph> </message> - <message name="IDS_APP_LIST_FOLDER_OPEN_FOLDER_ACCESSIBILE_NAME" desc="The spoken feedback text for opening an app launcher folder"> - Open folder - </message> <message name="IDS_APP_LIST_FOLDER_CLOSE_FOLDER_ACCESSIBILE_NAME" desc="The spoken feedback text for closing an app launcher folder"> Close folder </message>
diff --git a/ash/components/arc/arc_features.cc b/ash/components/arc/arc_features.cc index f0b7845..180f0ec3 100644 --- a/ash/components/arc/arc_features.cc +++ b/ash/components/arc/arc_features.cc
@@ -97,11 +97,6 @@ const base::Feature kKeyboardShortcutHelperIntegrationFeature{ "ArcKeyboardShortcutHelperIntegration", base::FEATURE_DISABLED_BY_DEFAULT}; -// Controls experimental 64-bit native bridge support for ARC on boards that -// have 64-bit native bridge support available but not yet enabled. -const base::Feature kNativeBridge64BitSupportExperimentFeature{ - "ArcNativeBridge64BitSupportExperiment", base::FEATURE_DISABLED_BY_DEFAULT}; - // Toggles between native bridge implementations for ARC. // Note, that we keep the original feature name to preserve // corresponding metrics.
diff --git a/ash/components/arc/arc_features.h b/ash/components/arc/arc_features.h index 1729048..d576a75 100644 --- a/ash/components/arc/arc_features.h +++ b/ash/components/arc/arc_features.h
@@ -32,7 +32,6 @@ extern const base::Feature kLogdConfig; extern const base::FeatureParam<int> kLogdConfigSize; extern const base::Feature kKeyboardShortcutHelperIntegrationFeature; -extern const base::Feature kNativeBridge64BitSupportExperimentFeature; extern const base::Feature kNativeBridgeToggleFeature; extern const base::Feature kOutOfProcessVideoDecoding; extern const base::Feature kPictureInPictureFeature;
diff --git a/ash/components/arc/arc_prefs.cc b/ash/components/arc/arc_prefs.cc index 9f23d33..9b649df 100644 --- a/ash/components/arc/arc_prefs.cc +++ b/ash/components/arc/arc_prefs.cc
@@ -126,13 +126,6 @@ // Keeps the duration of the current ANR rate period. const char kAnrPendingDuration[] = "arc.anr_pending_duration"; -// A boolean preference that indicates whether this device has run with the -// native bridge 64 bit support experiment enabled. Persisting value in local -// state, rather than in a user profile, is required as it needs to be read -// whenever ARC mini-container is started. -const char kNativeBridge64BitSupportExperimentEnabled[] = - "arc.native_bridge_64bit_support_experiment"; - // A dictionary preference that keeps track of stability metric values, which is // maintained by StabilityMetricsManager. Persisting values in local state is // required to include these metrics in the initial stability log in case of a @@ -154,8 +147,6 @@ registry->RegisterStringPref(kArcSerialNumberSalt, std::string()); registry->RegisterDictionaryPref(kArcSnapshotHours); registry->RegisterDictionaryPref(kArcSnapshotInfo); - registry->RegisterBooleanPref(kNativeBridge64BitSupportExperimentEnabled, - false); registry->RegisterDictionaryPref(kStabilityMetrics); registry->RegisterIntegerPref(kAnrPendingCount, 0);
diff --git a/ash/components/arc/arc_prefs.h b/ash/components/arc/arc_prefs.h index 289996e..d12acfc 100644 --- a/ash/components/arc/arc_prefs.h +++ b/ash/components/arc/arc_prefs.h
@@ -52,7 +52,6 @@ ARC_EXPORT extern const char kArcSerialNumberSalt[]; ARC_EXPORT extern const char kArcSnapshotHours[]; ARC_EXPORT extern const char kArcSnapshotInfo[]; -ARC_EXPORT extern const char kNativeBridge64BitSupportExperimentEnabled[]; ARC_EXPORT extern const char kStabilityMetrics[]; void RegisterLocalStatePrefs(PrefRegistrySimple* registry);
diff --git a/ash/components/arc/input_overlay/resources/com.dts.freefireth.json b/ash/components/arc/input_overlay/resources/com.dts.freefireth.json deleted file mode 100644 index a18bf65..0000000 --- a/ash/components/arc/input_overlay/resources/com.dts.freefireth.json +++ /dev/null
@@ -1,665 +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. - -{ - "mouse_lock": { - "key": "Escape" - }, - "move": [ - { - "id": 0, - "input_sources": [ - "mouse" - ], - "name": "camera move", - "hide_cursor": 1, - "mouse_action": "hover_move", - "location": [ - { - "type": "position", - "anchor_to_target": [ - 0.5, - 0.5 - ] - } - ], - "target_area": { - "top_left": { - "type": "position", - "anchor_to_target": [ - 0.5, - 0 - ] - }, - "bottom_right": { - "type": "position", - "anchor_to_target": [ - 0.9999, - 0.9999 - ] - } - } - }, - { - "id": 1, - "input_sources": [ - "keyboard" - ], - "name": "Virtual Joystick", - "keys": [ - "KeyW", - "KeyA", - "KeyS", - "KeyD" - ], - "location": [ - { - "type": "dependent_position", - "aspect_ratio": 1.78, - "anchor": [ - 0, - 1 - ], - "anchor_to_target": [ - 0.16875, - -0.2472222222 - ], - "x_on_y": 1.213483146, - "y_on_x": 0.8240740741 - } - ], - "radius": 0.1171296296 - } - ], - "tap": [ - { - "id": 2, - "input_sources": [ - "mouse" - ], - "name": "fight", - "mouse_action": "primary_click", - "location": [ - { - "type": "dependent_position", - "aspect_ratio": 1.78, - "anchor": [ - 1, - 1 - ], - "anchor_to_target": [ - -0.1796875, - -0.25 - ], - "x_on_y": 1.277777778, - "y_on_x": 0.7826086957 - } - ], - "radius": 0.0903 - }, - { - "id": 3, - "input_sources": [ - "mouse" - ], - "name": "aim", - "mouse_action": "secondary_click", - "location": [ - { - "type": "dependent_position", - "aspect_ratio": 1.78, - "anchor": [ - 1, - 1 - ], - "anchor_to_target": [ - -0.0375, - -0.4574074074 - ], - "x_on_y": 0.1457489879, - "y_on_x": 6.861111111 - } - ], - "radius": 0.05555555556 - }, - { - "id": 4, - "input_sources": [ - "keyboard" - ], - "name": "jump", - "key": "Space", - "location": [ - { - "type": "dependent_position", - "aspect_ratio": 1.78, - "anchor": [ - 1, - 1 - ], - "anchor_to_target": [ - -0.034375, - -0.3055555556 - ], - "x_on_y": 0.2, - "y_on_x": 5 - } - ], - "radius": 0.05555555556 - }, - { - "id": 5, - "input_sources": [ - "keyboard" - ], - "name": "crouch", - "key": "KeyC", - "location": [ - { - "type": "dependent_position", - "aspect_ratio": 1.78, - "anchor": [ - 1, - 1 - ], - "anchor_to_target": [ - -0.0625, - -0.1083333333 - ], - "x_on_y": 1.025641026, - "y_on_x": 0.975 - } - ], - "radius": 0.05555555556 - }, - { - "id": 6, - "input_sources": [ - "keyboard" - ], - "name": "lean", - "key": "KeyZ", - "location": [ - { - "type": "dependent_position", - "aspect_ratio": 1.78, - "anchor": [ - 1, - 1 - ], - "anchor_to_target": [ - -0.1786458333, - -0.075 - ], - "x_on_y": 4.234567901, - "y_on_x": 0.2361516035 - } - ], - "radius": 0.05555555556 - }, - { - "id": 7, - "input_sources": [ - "keyboard" - ], - "name": "hand", - "key": "KeyQ", - "location": [ - { - "type": "dependent_position", - "aspect_ratio": 1.78, - "anchor": [ - 1, - 1 - ], - "anchor_to_target": [ - -0.2864583333, - -0.5064814815 - ], - "x_on_y": 1.005484461, - "y_on_x": 0.9945454545 - } - ], - "radius": 0.04675925926 - }, - { - "id": 8, - "input_sources": [ - "keyboard" - ], - "name": "revive", - "key": "Digit5", - "location": [ - { - "type": "dependent_position", - "aspect_ratio": 1.78, - "anchor": [ - 1, - 1 - ], - "anchor_to_target": [ - -0.2864583333, - -0.3342592593 - ], - "x_on_y": 1.523545706, - "y_on_x": 0.6563636364 - } - ], - "radius": 0.04675925926 - }, - { - "id": 9, - "input_sources": [ - "keyboard" - ], - "name": "reload", - "key": "KeyR", - "location": [ - { - "type": "dependent_position", - "aspect_ratio": 1.78, - "anchor": [ - 1, - 0 - ], - "anchor_to_target": [ - -0.09479166667, - 0.085 - ], - "x_on_y": 2, - "y_on_x": 0.5 - } - ], - "radius": 0.05092592593 - }, - { - "id": 10, - "input_sources": [ - "keyboard" - ], - "name": "gun1", - "key": "Digit1", - "location": [ - { - "type": "dependent_position", - "aspect_ratio": 1.78, - "anchor": [ - 1, - 0 - ], - "anchor_to_target": [ - -0.1557291667, - 0.2009259259 - ], - "x_on_y": 1.377880184, - "y_on_x": 0.7257525084 - } - ], - "radius": 0.05555555556 - }, - { - "id": 11, - "input_sources": [ - "keyboard" - ], - "name": "gun2", - "key": "Digit2", - "location": [ - { - "type": "dependent_position", - "aspect_ratio": 1.78, - "anchor": [ - 1, - 0 - ], - "anchor_to_target": [ - -0.09322916667, - 0.2009259259 - ], - "x_on_y": 0.8248847926, - "y_on_x": 1.212290503 - } - ], - "radius": 0.05555555556 - }, - { - "id": 12, - "input_sources": [ - "keyboard" - ], - "name": "gun3", - "key": "Digit3", - "location": [ - { - "type": "dependent_position", - "aspect_ratio": 1.78, - "anchor": [ - 1, - 0 - ], - "anchor_to_target": [ - -0.0296875, - 0.2009259259 - ], - "x_on_y": 0.2626728111, - "y_on_x": 3.807017544 - } - ], - "radius": 0.05555555556 - }, - { - "id": 13, - "input_sources": [ - "keyboard" - ], - "name": "item1", - "key": "KeyF", - "location": [ - { - "type": "dependent_position", - "aspect_ratio": 1.78, - "anchor": [ - 1, - 0 - ], - "anchor_to_target": [ - -0.2380208333, - 0.3703703704 - ], - "x_on_y": 1.1425, - "y_on_x": 0.875273523 - } - ], - "radius": 0.05925925926 - }, - { - "id": 14, - "input_sources": [ - "keyboard" - ], - "name": "item2", - "key": "KeyG", - "location": [ - { - "type": "dependent_position", - "aspect_ratio": 1.78, - "anchor": [ - 1, - 0 - ], - "anchor_to_target": [ - -0.1682291667, - 0.3703703704 - ], - "x_on_y": 0.8075, - "y_on_x": 1.238390093 - } - ], - "radius": 0.05925925926 - }, - { - "id": 15, - "input_sources": [ - "keyboard" - ], - "name": "item3", - "key": "KeyH", - "location": [ - { - "type": "dependent_position", - "aspect_ratio": 1.78, - "anchor": [ - 1, - 0 - ], - "anchor_to_target": [ - -0.1005208333, - 0.3703703704 - ], - "x_on_y": 0.4825, - "y_on_x": 2.07253886 - } - ], - "radius": 0.05925925926 - }, - { - "id": 16, - "input_sources": [ - "keyboard" - ], - "name": "item4", - "key": "KeyJ", - "location": [ - { - "type": "dependent_position", - "aspect_ratio": 1.78, - "anchor": [ - 1, - 0 - ], - "anchor_to_target": [ - -0.03125, - 0.3703703704 - ], - "x_on_y": 0.15, - "y_on_x": 6.666666667 - } - ], - "radius": 0.05925925926 - }, - { - "id": 17, - "input_sources": [ - "keyboard" - ], - "name": "map", - "key": "KeyM", - "location": [ - { - "type": "dependent_position", - "aspect_ratio": 1.78, - "anchor": [ - 0, - 0 - ], - "anchor_to_target": [ - 0.078125, - 0.1333333333 - ], - "x_on_y": 1.041666667, - "y_on_x": 0.96 - } - ], - "radius": 0.1 - }, - { - "id": 18, - "input_sources": [ - "keyboard" - ], - "name": "mic", - "key": "KeyT", - "location": [ - { - "type": "dependent_position", - "aspect_ratio": 1.78, - "anchor": [ - 0, - 0 - ], - "anchor_to_target": [ - 0.184375, - 0.03055555556 - ], - "x_on_y": 10.72727273, - "y_on_x": 0.09322033898 - } - ], - "radius": 0.02824074074 - }, - { - "id": 19, - "input_sources": [ - "keyboard" - ], - "name": "volumn", - "key": "KeyY", - "location": [ - { - "type": "dependent_position", - "aspect_ratio": 1.78, - "anchor": [ - 0, - 0 - ], - "anchor_to_target": [ - 0.184375, - 0.1055555556 - ], - "x_on_y": 3.105263158, - "y_on_x": 0.3220338983 - } - ], - "radius": 0.02824074074 - }, - { - "id": 20, - "input_sources": [ - "keyboard" - ], - "name": "speed", - "key": "ShiftLeft", - "location": [ - { - "type": "position", - "anchor": [ - 0, - 0 - ], - "anchor_to_target": [ - 0.1666666667, - 0.4305555556 - ], - "max_x": 320 - } - ], - "radius": 0.05555555556 - }, - { - "id": 21, - "input_sources": [ - "keyboard" - ], - "name": "surf", - "key": "ControlLeft", - "location": [ - { - "type": "position", - "anchor": [ - 0, - 0 - ], - "anchor_to_target": [ - 0.3098958333, - 0.3194444444 - ], - "max_x": 595 - } - ], - "radius": 0.05555555556 - }, - { - "id": 22, - "input_sources": [ - "keyboard" - ], - "name": "fire", - "key": "KeyE", - "location": [ - { - "type": "position", - "anchor": [ - 0, - 0 - ], - "anchor_to_target": [ - 0.2401041667, - 0.4324074074 - ], - "max_x": 461 - } - ], - "radius": 0.05555555556 - }, - { - "id": 23, - "input_sources": [ - "keyboard" - ], - "name": "bag", - "key": "Tab", - "location": [ - { - "type": "position", - "anchor": [ - 0, - 0 - ], - "anchor_to_target": [ - 0.03072916667, - 0.5 - ], - "max_x": 60 - } - ], - "radius": 0.0462962963 - }, - { - "id": 24, - "input_sources": [ - "keyboard" - ], - "name": "heal", - "key": "Digit4", - "location": [ - { - "type": "position", - "anchor": [ - 0, - 0 - ], - "anchor_to_target": [ - 0.03072916667, - 0.6212962963 - ], - "max_x": 60 - } - ], - "radius": 0.0462962963 - }, - { - "id": 25, - "input_sources": [ - "keyboard" - ], - "name": "bomb", - "key": "KeyB", - "location": [ - { - "type": "position", - "anchor": [ - 0, - 0 - ], - "anchor_to_target": [ - 0.03072916667, - 0.7222222222 - ], - "max_x": 60 - } - ], - "radius": 0.0462962963 - } - ] -}
diff --git a/ash/components/arc/input_overlay/resources/input_overlay_resources.grd b/ash/components/arc/input_overlay/resources/input_overlay_resources.grd index 5ec08f8..bc56b14 100644 --- a/ash/components/arc/input_overlay/resources/input_overlay_resources.grd +++ b/ash/components/arc/input_overlay/resources/input_overlay_resources.grd
@@ -16,7 +16,6 @@ <include name="IDR_IO_ORG_CHROMIUM_ARC_TESTAPP_INPUTOVERLAY" file="org.chromium.arc.testapp.inputoverlay.json" type="BINDATA" /> <include name="IDR_IO_COM_BLACKPANTHER_NINJAARASHI2" file="com.blackpanther.ninjaarashi2.json" type="BINDATA" /> <include name="IDR_IO_COM_HABBY_ARCHERO" file="com.habby.archero.json" type="BINDATA" /> - <include name="IDR_IO_COM_DTS_FREEFIRETH" file="com.dts.freefireth.json" type="BINDATA" /> <include name="IDR_IO_COM_FINGERSOFT_HILLCLIMB" file="com.fingersoft.hillclimb.json" type="BINDATA" /> <include name="IDR_IO_COM_ANDROBABY_GAME2048" file="com.androbaby.game2048.json" type="BINDATA" /> <include name="IDR_IO_CO_IMBA_ARCHERO" file="co.imba.archero.json" type="BINDATA" />
diff --git a/ash/components/arc/mojom/tts.mojom b/ash/components/arc/mojom/tts.mojom index 01667b7c..2e36f2a 100644 --- a/ash/components/arc/mojom/tts.mojom +++ b/ash/components/arc/mojom/tts.mojom
@@ -1,7 +1,7 @@ // Copyright 2016 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. -// Next MinVersion: 4 +// Next MinVersion: 5 module arc.mojom; @@ -56,4 +56,7 @@ // Sends a stop request to Android text to speech. Stop@2(); + + // Request to call OnVoicesChanged if necessary. + [MinVersion=4] RefreshVoices@4(); };
diff --git a/ash/components/arc/net/arc_net_host_impl.cc b/ash/components/arc/net/arc_net_host_impl.cc index 1e56aff..6eb6c6a8 100644 --- a/ash/components/arc/net/arc_net_host_impl.cc +++ b/ash/components/arc/net/arc_net_host_impl.cc
@@ -22,6 +22,7 @@ #include "base/strings/stringprintf.h" #include "chromeos/ash/components/dbus/patchpanel/patchpanel_client.h" #include "chromeos/ash/components/dbus/patchpanel/patchpanel_service.pb.h" +#include "chromeos/ash/components/network/onc/network_onc_utils.h" #include "chromeos/dbus/shill/shill_manager_client.h" #include "chromeos/login/login_state/login_state.h" #include "chromeos/network/client_cert_util.h" @@ -34,7 +35,6 @@ #include "chromeos/network/network_state.h" #include "chromeos/network/network_state_handler.h" #include "chromeos/network/network_type_pattern.h" -#include "chromeos/network/onc/network_onc_utils.h" #include "components/device_event_log/device_event_log.h" #include "components/prefs/pref_service.h" #include "components/user_manager/user_manager.h"
diff --git a/ash/constants/ash_features.cc b/ash/constants/ash_features.cc index 5bb1fc1e..4085de3 100644 --- a/ash/constants/ash_features.cc +++ b/ash/constants/ash_features.cc
@@ -29,6 +29,12 @@ const base::Feature kAdaptiveCharging{"AdaptiveCharging", base::FEATURE_DISABLED_BY_DEFAULT}; +// Enable the logic to show the notifications for Adaptive Charging features. +// This is intended to be used by developers to test the UI aspect of the +// feature. +const base::Feature kAdaptiveChargingForTesting{ + "AdaptiveChargingForTesting", base::FEATURE_DISABLED_BY_DEFAULT}; + // Adjusts portrait mode split view to avoid the input field in the bottom // window being occluded by the virtual keyboard. const base::Feature kAdjustSplitViewForVK{"AdjustSplitViewForVK", @@ -459,13 +465,6 @@ const base::Feature kDisableIdleSocketsCloseOnMemoryPressure{ "disable_idle_sockets_close_on_memory_pressure", base::FEATURE_DISABLED_BY_DEFAULT}; - -// Disables "Office Editing for Docs, Sheets & Slides" component app so handlers -// won't be registered, making it possible to install another version for -// testing. -const base::Feature kDisableOfficeEditingComponentApp{ - "DisableOfficeEditingComponentApp", base::FEATURE_DISABLED_BY_DEFAULT}; - // Enables indicators to hint where displays are connected. const base::Feature kDisplayAlignAssist{"DisplayAlignAssist", base::FEATURE_DISABLED_BY_DEFAULT}; @@ -952,7 +951,7 @@ // and recent apps context menu that allow the user to hide the continue // section. const base::Feature kLauncherHideContinueSection{ - "LauncherHideContinueSection", base::FEATURE_DISABLED_BY_DEFAULT}; + "LauncherHideContinueSection", base::FEATURE_ENABLED_BY_DEFAULT}; // Uses short intervals for launcher nudge for testing if enabled. const base::Feature kLauncherNudgeShortInterval{ @@ -1452,7 +1451,7 @@ // Uses new AuthSession-based API in cryptohome to authenticate users during // sign-in. const base::Feature kUseAuthsessionAuthentication{ - "UseAuthsessionAuthentication", base::FEATURE_ENABLED_BY_DEFAULT}; + "UseAuthsessionAuthentication", base::FEATURE_DISABLED_BY_DEFAULT}; // Enables using the BluetoothSystem Mojo interface for Bluetooth operations. const base::Feature kUseBluetoothSystemInAsh{"UseBluetoothSystemInAsh", @@ -1611,6 +1610,10 @@ return base::FeatureList::IsEnabled(kAdaptiveCharging); } +bool IsAdaptiveChargingForTestingEnabled() { + return base::FeatureList::IsEnabled(kAdaptiveChargingForTesting); +} + bool IsAdjustSplitViewForVKEnabled() { return base::FeatureList::IsEnabled(kAdjustSplitViewForVK); }
diff --git a/ash/constants/ash_features.h b/ash/constants/ash_features.h index 799bc47..9b241f86 100644 --- a/ash/constants/ash_features.h +++ b/ash/constants/ash_features.h
@@ -20,6 +20,8 @@ COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kAdaptiveCharging; COMPONENT_EXPORT(ASH_CONSTANTS) +extern const base::Feature kAdaptiveChargingForTesting; +COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kAdjustSplitViewForVK; COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kAllowAmbientEQ; COMPONENT_EXPORT(ASH_CONSTANTS) @@ -190,8 +192,6 @@ extern const base::Feature kDisableCryptAuthV1DeviceSync; COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kDisableIdleSocketsCloseOnMemoryPressure; -COMPONENT_EXPORT(ASH_CONSTANTS) -extern const base::Feature kDisableOfficeEditingComponentApp; COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kDisplayAlignAssist; COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kDockedMagnifier; COMPONENT_EXPORT(ASH_CONSTANTS) @@ -618,6 +618,7 @@ COMPONENT_EXPORT(ASH_CONSTANTS) bool AreImprovedScreenCaptureSettingsEnabled(); COMPONENT_EXPORT(ASH_CONSTANTS) bool DoWindowsFollowCursor(); COMPONENT_EXPORT(ASH_CONSTANTS) bool IsAdaptiveChargingEnabled(); +COMPONENT_EXPORT(ASH_CONSTANTS) bool IsAdaptiveChargingForTestingEnabled(); COMPONENT_EXPORT(ASH_CONSTANTS) bool IsAdjustSplitViewForVKEnabled(); COMPONENT_EXPORT(ASH_CONSTANTS) bool IsAllowAmbientEQEnabled(); COMPONENT_EXPORT(ASH_CONSTANTS) bool IsAmbientModeAnimationEnabled();
diff --git a/ash/constants/ash_switches.cc b/ash/constants/ash_switches.cc index adaa940..9b777f31 100644 --- a/ash/constants/ash_switches.cc +++ b/ash/constants/ash_switches.cc
@@ -105,12 +105,6 @@ // See also |kArcVmUreadaheadMode|. const char kArcDisableUreadahead[] = "arc-disable-ureadahead"; -// Flag to enables an experiment to allow users to turn on 64-bit support in -// native bridge on systems that have such support available but not yet enabled -// by default. -const char kArcEnableNativeBridge64BitSupportExperiment[] = - "arc-enable-native-bridge-64bit-support-experiment"; - // Flag that forces the OptIn ui to be shown. Used in tests. const char kArcForceShowOptInUi[] = "arc-force-show-optin-ui";
diff --git a/ash/constants/ash_switches.h b/ash/constants/ash_switches.h index 9f2fd73..9bb10502 100644 --- a/ash/constants/ash_switches.h +++ b/ash/constants/ash_switches.h
@@ -41,8 +41,6 @@ extern const char kArcDisableMediaStoreMaintenance[]; COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kArcDisablePlayAutoInstall[]; COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kArcDisableUreadahead[]; -COMPONENT_EXPORT(ASH_CONSTANTS) -extern const char kArcEnableNativeBridge64BitSupportExperiment[]; COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kArcForceShowOptInUi[]; COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kArcGeneratePlayAutoInstall[]; COMPONENT_EXPORT(ASH_CONSTANTS)
diff --git a/ash/projector/projector_controller_impl.cc b/ash/projector/projector_controller_impl.cc index 336dbb19..d2702049 100644 --- a/ash/projector/projector_controller_impl.cc +++ b/ash/projector/projector_controller_impl.cc
@@ -282,11 +282,6 @@ return result; } -void ProjectorControllerImpl::OnToolSet(const AnnotatorTool& tool) { - // TODO(b/198184362): Reflect the annotator tool changes on the Projector - // toolbar. -} - void ProjectorControllerImpl::OnUndoRedoAvailabilityChanged( bool undo_available, bool redo_available) {
diff --git a/ash/projector/projector_controller_impl.h b/ash/projector/projector_controller_impl.h index 4c772fea7..00865d7 100644 --- a/ash/projector/projector_controller_impl.h +++ b/ash/projector/projector_controller_impl.h
@@ -75,7 +75,6 @@ void OnSpeechRecognitionStopped() override; bool IsEligible() const override; NewScreencastPrecondition GetNewScreencastPrecondition() const override; - void OnToolSet(const AnnotatorTool& tool) override; void OnUndoRedoAvailabilityChanged(bool undo_available, bool redo_available) override; void OnCanvasInitialized(bool success) override;
diff --git a/ash/public/cpp/projector/projector_controller.h b/ash/public/cpp/projector/projector_controller.h index a4bce550..e2972868d 100644 --- a/ash/public/cpp/projector/projector_controller.h +++ b/ash/public/cpp/projector/projector_controller.h
@@ -11,7 +11,6 @@ namespace ash { -struct AnnotatorTool; struct NewScreencastPrecondition; // File extension of Projector metadata file. It is used to identify Projector @@ -85,8 +84,6 @@ // The following functions are callbacks from the annotator back to the // ProjectorController. - // Callback indicating that the annotator tool has changed. - virtual void OnToolSet(const AnnotatorTool& tool) = 0; // Callback indicating availability of undo and redo functionalities. virtual void OnUndoRedoAvailabilityChanged(bool undo_available, bool redo_available) = 0;
diff --git a/ash/public/cpp/test/mock_projector_controller.h b/ash/public/cpp/test/mock_projector_controller.h index 3d9fd3a..266576b5 100644 --- a/ash/public/cpp/test/mock_projector_controller.h +++ b/ash/public/cpp/test/mock_projector_controller.h
@@ -30,7 +30,6 @@ MOCK_METHOD1(SetProjectorToolsVisible, void(bool is_visible)); MOCK_CONST_METHOD0(IsEligible, bool()); MOCK_CONST_METHOD0(GetNewScreencastPrecondition, NewScreencastPrecondition()); - MOCK_METHOD1(OnToolSet, void(const AnnotatorTool& tool)); MOCK_METHOD2(OnUndoRedoAvailabilityChanged, void(bool undo_available, bool redo_available)); MOCK_METHOD1(OnCanvasInitialized, void(bool success));
diff --git a/ash/system/phonehub/multidevice_feature_opt_in_view.cc b/ash/system/phonehub/multidevice_feature_opt_in_view.cc index 4557b4d..e33d8044 100644 --- a/ash/system/phonehub/multidevice_feature_opt_in_view.cc +++ b/ash/system/phonehub/multidevice_feature_opt_in_view.cc
@@ -172,11 +172,18 @@ void MultideviceFeatureOptInView::UpdateVisibility() { DCHECK(multidevice_feature_access_manager_); - // Refresh the permission status. - setup_mode_ = GetPermissionSetupMode(multidevice_feature_access_manager_); + // Refresh the permission status if changed + phonehub::util::PermissionsOnboardingSetUpMode current_mode = + GetPermissionSetupMode(multidevice_feature_access_manager_); + if (current_mode != setup_mode_) { + setup_mode_ = current_mode; + RefreshDescription( + GetDescriptionStringId(multidevice_feature_access_manager_)); + } SetVisible(setup_mode_ != PermissionsOnboardingSetUpMode::kNone && !multidevice_feature_access_manager_ ->HasMultideviceFeatureSetupUiBeenDismissed()); + PreferredSizeChanged(); } BEGIN_METADATA(MultideviceFeatureOptInView, views::View)
diff --git a/ash/system/phonehub/sub_feature_opt_in_view.cc b/ash/system/phonehub/sub_feature_opt_in_view.cc index bd92576..f22d394 100644 --- a/ash/system/phonehub/sub_feature_opt_in_view.cc +++ b/ash/system/phonehub/sub_feature_opt_in_view.cc
@@ -49,6 +49,12 @@ SubFeatureOptInView::~SubFeatureOptInView() = default; +void SubFeatureOptInView::RefreshDescription(int description_string_id) { + description_string_id_ = description_string_id; + text_label_->SetText(l10n_util::GetStringFUTF16(description_string_id_, + ui::GetChromeOSDeviceName())); +} + void SubFeatureOptInView::InitLayout() { SetPaintToLayer(); layer()->SetFillsBoundsOpaquely(false);
diff --git a/ash/system/phonehub/sub_feature_opt_in_view.h b/ash/system/phonehub/sub_feature_opt_in_view.h index 5468a25..342cc9c4 100644 --- a/ash/system/phonehub/sub_feature_opt_in_view.h +++ b/ash/system/phonehub/sub_feature_opt_in_view.h
@@ -31,6 +31,7 @@ SubFeatureOptInView(PhoneHubViewID view_id, int description_string_id, int set_up_button_string_id); + void RefreshDescription(int description_string_id); private: void InitLayout();
diff --git a/ash/system/power/adaptive_charging_controller.cc b/ash/system/power/adaptive_charging_controller.cc index 4aba183..ba58ec55 100644 --- a/ash/system/power/adaptive_charging_controller.cc +++ b/ash/system/power/adaptive_charging_controller.cc
@@ -4,12 +4,22 @@ #include "ash/system/power/adaptive_charging_controller.h" +#include "ash/constants/ash_features.h" #include "base/scoped_observation.h" #include "chromeos/dbus/power/power_manager_client.h" #include "chromeos/dbus/power_manager/power_supply_properties.pb.h" namespace ash { +namespace { + +#if DCHECK_IS_ON() +// Fake input for notification testing. +constexpr int kFakeNotificationInputForTesting = 8; +#endif // DCHECK_IS_ON() + +} // namespace + AdaptiveChargingController::AdaptiveChargingController() : nudge_controller_(std::make_unique<AdaptiveChargingNudgeController>()), notification_controller_( @@ -29,6 +39,23 @@ void AdaptiveChargingController::PowerChanged( const power_manager::PowerSupplyProperties& proto) { +#if DCHECK_IS_ON() + if (features::IsAdaptiveChargingForTestingEnabled()) { + bool is_on_charger_now = false; + if (proto.has_external_power()) { + is_on_charger_now = + proto.external_power() == power_manager::PowerSupplyProperties::AC; + } + if (!is_on_charger_ && is_on_charger_now) { + nudge_controller_->ShowNudgeForTesting(); // IN-TEST + notification_controller_->ShowAdaptiveChargingNotification( + kFakeNotificationInputForTesting); + } + is_on_charger_ = is_on_charger_now; + return; + } +#endif // DCHECK_IS_ON() + // Return if this change does not contain any adaptive_delaying_charge info. if (!proto.has_adaptive_delaying_charge()) return;
diff --git a/ash/system/power/adaptive_charging_controller.h b/ash/system/power/adaptive_charging_controller.h index 21b84cee..bc84b2f 100644 --- a/ash/system/power/adaptive_charging_controller.h +++ b/ash/system/power/adaptive_charging_controller.h
@@ -39,6 +39,9 @@ void PowerChanged(const power_manager::PowerSupplyProperties& proto) override; bool is_adaptive_delaying_charge_ = false; +#if DCHECK_IS_ON() + bool is_on_charger_ = false; +#endif // DCHECK_IS_ON() base::ScopedObservation<chromeos::PowerManagerClient, chromeos::PowerManagerClient::Observer>
diff --git a/ash/system/power/adaptive_charging_nudge_controller.cc b/ash/system/power/adaptive_charging_nudge_controller.cc index ae84379..e2c32dd 100644 --- a/ash/system/power/adaptive_charging_nudge_controller.cc +++ b/ash/system/power/adaptive_charging_nudge_controller.cc
@@ -52,6 +52,12 @@ weak_ptr_factory_.GetWeakPtr())); } +#if DCHECK_IS_ON() +void AdaptiveChargingNudgeController::ShowNudgeForTesting() { + SystemNudgeController::ShowNudge(); +} +#endif // DCHECK_IS_ON() + std::unique_ptr<SystemNudge> AdaptiveChargingNudgeController::CreateSystemNudge() { return std::make_unique<AdaptiveChargingNudge>();
diff --git a/ash/system/power/adaptive_charging_nudge_controller.h b/ash/system/power/adaptive_charging_nudge_controller.h index 01a306d..01bd107 100644 --- a/ash/system/power/adaptive_charging_nudge_controller.h +++ b/ash/system/power/adaptive_charging_nudge_controller.h
@@ -34,6 +34,12 @@ return nudge_delay_timer_.get(); } +#if DCHECK_IS_ON() + // This is intended to be used by developers to test the UI of the adaptive + // charging feature. + void ShowNudgeForTesting(); +#endif // DCHECK_IS_ON() + private: // SystemNudgeController: std::unique_ptr<SystemNudge> CreateSystemNudge() override;
diff --git a/ash/webui/diagnostics_ui/backend/network_health_provider_unittest.cc b/ash/webui/diagnostics_ui/backend/network_health_provider_unittest.cc index 44f7f06..8c46164 100644 --- a/ash/webui/diagnostics_ui/backend/network_health_provider_unittest.cc +++ b/ash/webui/diagnostics_ui/backend/network_health_provider_unittest.cc
@@ -12,6 +12,7 @@ #include "base/test/scoped_feature_list.h" #include "base/test/task_environment.h" #include "base/values.h" +#include "chromeos/ash/components/network/onc/network_onc_utils.h" #include "chromeos/dbus/shill/shill_ipconfig_client.h" #include "chromeos/login/login_state/login_state.h" #include "chromeos/network/managed_network_configuration_handler.h" @@ -21,7 +22,6 @@ #include "chromeos/network/network_handler_test_helper.h" #include "chromeos/network/network_state_handler.h" #include "chromeos/network/network_type_pattern.h" -#include "chromeos/network/onc/network_onc_utils.h" #include "chromeos/network/system_token_cert_db_storage.h" #include "chromeos/services/network_config/cros_network_config.h" #include "chromeos/services/network_config/in_process_instance.h"
diff --git a/ash/webui/diagnostics_ui/resources/diagnostics_card.html b/ash/webui/diagnostics_ui/resources/diagnostics_card.html index 3f31499..4a5f30a 100644 --- a/ash/webui/diagnostics_ui/resources/diagnostics_card.html +++ b/ash/webui/diagnostics_ui/resources/diagnostics_card.html
@@ -5,13 +5,21 @@ } ::slotted([slot=icon]) { - @apply --diagnostics-card-icon; + --iron-icon-fill-color: var(--cros-color-prominent); + --iron-icon-height: 20px; + --iron-icon-width: 20px; + background-color: var(--cros-highlight-color); + border-radius: 50%; margin: 0 20px; + padding: 8px; position: relative; } ::slotted([slot=title]) { - @apply --diagnostics-card-title-font; + color: var(--diagnostics-card-title-text-color); + font-family: var(--diagnostics-roboto-font-family); + font-size: var(--diagnostics-card-title-font-size); + font-weight: var(--diagnostics-medium-font-weight); } ::slotted([slot=left-panel]) {
diff --git a/ash/webui/diagnostics_ui/resources/diagnostics_card_frame.html b/ash/webui/diagnostics_ui/resources/diagnostics_card_frame.html index 5fadc4f6..2a6a924f 100644 --- a/ash/webui/diagnostics_ui/resources/diagnostics_card_frame.html +++ b/ash/webui/diagnostics_ui/resources/diagnostics_card_frame.html
@@ -5,7 +5,10 @@ } ::slotted([slot=title]) { - @apply --diagnostics-card-title-font; + color: var(--diagnostics-card-title-text-color); + font-family: var(--diagnostics-roboto-font-family); + font-size: var(--diagnostics-card-title-font-size); + font-weight: var(--diagnostics-medium-font-weight); } ::slotted([slot=left-panel]) {
diff --git a/ash/webui/diagnostics_ui/resources/diagnostics_fonts_css.html b/ash/webui/diagnostics_ui/resources/diagnostics_fonts_css.html index 26420e6..8431512 100644 --- a/ash/webui/diagnostics_ui/resources/diagnostics_fonts_css.html +++ b/ash/webui/diagnostics_ui/resources/diagnostics_fonts_css.html
@@ -38,29 +38,6 @@ --diagnostics-caution-banner-text-color: var(--cros-text-color-primary); --diagnostics-link-text-color: var(--cros-link-color); --diagnostics-settings-link-text-color: var(--cros-text-color-secondary); - - --diagnostics-card-title-font: { - color: var(--diagnostics-card-title-text-color); - font-family: var(--diagnostics-roboto-font-family); - font-size: var(--diagnostics-card-title-font-size); - font-weight: var(--diagnostics-medium-font-weight); - }; - --diagnostics-chart-label-font: { - font-family: var(--diagnostics-google-sans-font-family); - font-size: var(--diagnostics-chart-label-font-size); - font-weight: var(--diagnostics-regular-font-weight); - }; - --diagnostics-button-font: { - font-family: var(--diagnostics-roboto-font-family); - font-size: var(--diagnostics-button-font-size); - font-weight: var(--diagnostics-medium-font-weight); - }; - --diagnostics-caution-banner-font: { - color: var(--diagnostics-caution-banner-text-color); - font-family: var(--diagnostics-roboto-font-family); - font-size: var(--diagnostics-caution-banner-font-size); - font-weight: var(--diagnostics-regular-font-weight); - }; } </style> </template>
diff --git a/ash/webui/diagnostics_ui/resources/diagnostics_shared_css.html b/ash/webui/diagnostics_ui/resources/diagnostics_shared_css.html index 6bea12d..26b296f 100644 --- a/ash/webui/diagnostics_ui/resources/diagnostics_shared_css.html +++ b/ash/webui/diagnostics_ui/resources/diagnostics_shared_css.html
@@ -4,14 +4,6 @@ --diagnostics-box-shadow: var(--cros-elevation-1-shadow); --diagnostics-box-shadow-elevation-2: var(--cros-elevation-2-shadow); - --diagnostics-card-icon: { - --iron-icon-fill-color: var(--cros-color-prominent); - --iron-icon-height: 20px; - --iron-icon-width: 20px; - background-color: var(--cros-highlight-color); - border-radius: 50%; - padding: 8px; - }; --diagnostics-card-bg-color: var(--cros-bg-color); --diagnostics-chip-bg-color: var(--cros-bg-color-dropped-elevation-2); } @@ -150,6 +142,13 @@ padding-inline: 20px; } + .diagnostics-caution-banner-font { + color: var(--diagnostics-caution-banner-text-color); + font-family: var(--diagnostics-roboto-font-family); + font-size: var(--diagnostics-caution-banner-font-size); + font-weight: var(--diagnostics-regular-font-weight); + } + @media (min-width:600px) { :host { --container-padding: 24px;
diff --git a/ash/webui/diagnostics_ui/resources/diagnostics_sticky_banner.html b/ash/webui/diagnostics_ui/resources/diagnostics_sticky_banner.html index 85bac51..f3f7db61 100644 --- a/ash/webui/diagnostics_ui/resources/diagnostics_sticky_banner.html +++ b/ash/webui/diagnostics_ui/resources/diagnostics_sticky_banner.html
@@ -18,15 +18,11 @@ padding-inline-start: 40px; } - #bannerMsg { - @apply --diagnostics-caution-banner-font; - } - .elevation-2 { box-shadow: var(--diagnostics-box-shadow-elevation-2); } </style> <div id="banner" hidden$="[[!bannerMessage]]" class$="[[scrollingClass_]]"> <iron-icon icon="diagnostics:info" id="bannerIcon"></iron-icon> - <span id="bannerMsg">[[bannerMessage]]</span> + <span id="bannerMsg" class="diagnostics-caution-banner-font">[[bannerMessage]]</span> </div>
diff --git a/ash/webui/diagnostics_ui/resources/input_card.html b/ash/webui/diagnostics_ui/resources/input_card.html index d3629d91..6abe741 100644 --- a/ash/webui/diagnostics_ui/resources/input_card.html +++ b/ash/webui/diagnostics_ui/resources/input_card.html
@@ -6,8 +6,13 @@ } .device iron-icon { - @apply --diagnostics-card-icon; + --iron-icon-fill-color: var(--cros-color-prominent); + --iron-icon-height: 20px; + --iron-icon-width: 20px; + background-color: var(--cros-highlight-color); + border-radius: 50%; margin-inline-end: 28px; + padding: 8px; } .device-body {
diff --git a/ash/webui/diagnostics_ui/resources/percent_bar_chart.html b/ash/webui/diagnostics_ui/resources/percent_bar_chart.html index b3c31f1..8785bfe 100644 --- a/ash/webui/diagnostics_ui/resources/percent_bar_chart.html +++ b/ash/webui/diagnostics_ui/resources/percent_bar_chart.html
@@ -2,7 +2,7 @@ #chartName { color: var(--diagnostics-chart-title-color); display: inline-block; - font-family: Roboto; + font-family: var(--diagnostics-roboto-font-family); font-size: 13px; font-weight: var(--diagnostics-regular-font-weight); height: 20px;
diff --git a/ash/webui/diagnostics_ui/resources/routine_section.html b/ash/webui/diagnostics_ui/resources/routine_section.html index 2fcd662..807ca79 100644 --- a/ash/webui/diagnostics_ui/resources/routine_section.html +++ b/ash/webui/diagnostics_ui/resources/routine_section.html
@@ -7,18 +7,23 @@ } .button-container { - @apply --diagnostics-button-font; padding: 8px 0 4px; } .learn-more-button { - @apply --diagnostics-button-font; border-radius: 4px; height: 32px; margin-top: 12px; padding: 8px 16px; } + .button-container, + .learn-more-button { + font-family: var(--diagnostics-roboto-font-family); + font-size: var(--diagnostics-button-font-size); + font-weight: var(--diagnostics-medium-font-weight); + } + #messageIcon { --iron-icon-height: 20px; --iron-icon-width: 20px;
diff --git a/ash/webui/diagnostics_ui/resources/system_page.html b/ash/webui/diagnostics_ui/resources/system_page.html index 8fd7d5e..1d86371 100644 --- a/ash/webui/diagnostics_ui/resources/system_page.html +++ b/ash/webui/diagnostics_ui/resources/system_page.html
@@ -18,10 +18,6 @@ padding-inline-start: 40px; } - #bannerMsg { - @apply --diagnostics-caution-banner-font; - } - #diagnosticsContainer { align-items: center; box-sizing: border-box; @@ -73,7 +69,7 @@ </div> <div id="banner" hidden="[[!bannerMessage]]" class$="[[scrollingClass_]]"> <iron-icon icon="diagnostics:info" id="bannerIcon"></iron-icon> - <span id="bannerMsg">[[bannerMessage]]</span> + <span id="bannerMsg" class="diagnostics-caution-banner-font">[[bannerMessage]]</span> </div> <div class="overview-container"> <overview-card id="overviewCard"></overview-card>
diff --git a/ash/webui/os_feedback_ui/resources/BUILD.gn b/ash/webui/os_feedback_ui/resources/BUILD.gn index 01ab727..a6ac9685 100644 --- a/ash/webui/os_feedback_ui/resources/BUILD.gn +++ b/ash/webui/os_feedback_ui/resources/BUILD.gn
@@ -69,6 +69,7 @@ js_library("confirmation_page") { deps = [ + ":feedback_types", "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", ] }
diff --git a/ash/webui/os_feedback_ui/resources/confirmation_page.html b/ash/webui/os_feedback_ui/resources/confirmation_page.html index a8406c0..c4985ac85 100644 --- a/ash/webui/os_feedback_ui/resources/confirmation_page.html +++ b/ash/webui/os_feedback_ui/resources/confirmation_page.html
@@ -12,32 +12,29 @@ } </style> <!--TODO(xiangdongkong): use localized strings --> -<!--TODO(xiangdongkong): handle offline case --> <div id="container"> <div id="header"> - <h1 id="title">Thanks for your feedback</h1> + <h1 id="title">[[getTitle_(sendReportStatus)]]</h1> </div> - <div id="message"> - Your feedback helps improve ChromeOS and will be reviewed by our team. - Because of the large number of reports, we won’t be able to send a reply. - </div> - <div id="helpResources"> - <p id="helpResourcesLabel">Here are some other helpful resources:</p> - <cr-link-row id="explore" - start-icon="help-resources:explore" - label="Explore app" external - sub-label="Find help articles and answers to common Chromebook questions"> - </cr-link-row> - <cr-link-row id="diagnostics" - start-icon="help-resources:diagnostics" - label="Diagnostics app" external - sub-label="Run tests and troubleshooting for hardware issues"> - </cr-link-row> - <cr-link-row id="chromebookCommunity" - start-icon="help-resources2:chromebook-community" - label="Chromebook community" - sub-label="Ask the experts in the Chromebook help forum" external> - </cr-link-row> + <div id="content"> + <div id="message">[[getMessage_(sendReportStatus)]]</div> + <div id="helpResources"> + <p id="helpResourcesLabel">Here are some other helpful resources:</p> + <cr-link-row id="explore" start-icon="help-resources:explore" + label="Explore app" external + sub-label="Find help articles and answers to common Chromebook questions"> + </cr-link-row> + <cr-link-row id="diagnostics" start-icon="help-resources:diagnostics" + label="Diagnostics app" external + sub-label="Run tests and troubleshooting for hardware issues"> + </cr-link-row> + <cr-link-row id="chromebookCommunity" + start-icon="help-resources2:chromebook-community" + label="Chromebook community" + sub-label="Ask the experts in the Chromebook help forum" + hidden="[[isOffline_(sendReportStatus)]]" external> + </cr-link-row> + </div> </div> <div id="navButtons"> <cr-button id="buttonNewReport" class="action-button">
diff --git a/ash/webui/os_feedback_ui/resources/confirmation_page.js b/ash/webui/os_feedback_ui/resources/confirmation_page.js index abb05d1..638df94e 100644 --- a/ash/webui/os_feedback_ui/resources/confirmation_page.js +++ b/ash/webui/os_feedback_ui/resources/confirmation_page.js
@@ -7,10 +7,11 @@ import 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js'; import 'chrome://resources/cr_elements/cr_link_row/cr_link_row.js'; import 'chrome://resources/cr_elements/cr_button/cr_button.m.js'; -import './os_feedback_shared_css.js'; import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +import {SendReportStatus} from './feedback_types.js'; + /** * @fileoverview * 'confirmation-page' is the last step of the feedback tool. @@ -24,13 +25,57 @@ return html`{__html_template__}`; } - /** @override */ - ready() { - super.ready(); + static get properties() { + return { + sendReportStatus: {type: SendReportStatus, readOnly: false, notify: true}, + }; } - close_() { - window.close(); + constructor() { + super(); + + /** + * The status of sending the report. + * @type {?SendReportStatus} + */ + this.sendReportStatus; + } + + /** + * The page shows different information when the device is offline. + * @returns {boolean} + * @protected + */ + isOffline_() { + return this.sendReportStatus === SendReportStatus.kDelayed; + } + + /** + * @returns {string} + * @protected + */ + getTitle_() { + // TODO(xiangdongkong): Localize the strings. + if (this.isOffline_()) { + return 'You are offline now. Feedback will be sent later.'; + } + return 'Thanks for your feedback'; + } + + /** + * @returns {string} + * @protected + */ + getMessage_() { + // TODO(xiangdongkong): Localize the strings. + if (this.isOffline_()) { + return 'Thanks for the feedback. Your feedback helps improve Chrome OS ' + + 'and will be reviewed by the Chrome OS team. Because of the number ' + + ' of reports submitted, you won’t receive a direct reply. '; + } + return 'Your feedback helps improve ChromeOS and will be reviewed by ' + + 'our team. Because of the large number of reports, we won\’t be able ' + + ' to send a reply.'; } }
diff --git a/ash/webui/os_feedback_ui/resources/feedback_flow.html b/ash/webui/os_feedback_ui/resources/feedback_flow.html index 73adb516..8c1095c 100644 --- a/ash/webui/os_feedback_ui/resources/feedback_flow.html +++ b/ash/webui/os_feedback_ui/resources/feedback_flow.html
@@ -6,6 +6,8 @@ on-continue-click="handleContinueClick_" on-go-back-click="handleGoBackClick_"> </share-data-page> - <confirmation-page id="confirmationPage"></confirmation-page> + <confirmation-page id="confirmationPage" + send-report-status="[[sendReportStatus_]]"> + </confirmation-page> </iron-pages> </div>
diff --git a/ash/webui/os_feedback_ui/resources/feedback_flow.js b/ash/webui/os_feedback_ui/resources/feedback_flow.js index 705da101..8771ecc 100644 --- a/ash/webui/os_feedback_ui/resources/feedback_flow.js +++ b/ash/webui/os_feedback_ui/resources/feedback_flow.js
@@ -11,7 +11,7 @@ import {stringToMojoString16} from 'chrome://resources/ash/common/mojo_utils.js'; import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; -import {FeedbackContext, FeedbackServiceProviderInterface, Report} from './feedback_types.js'; +import {FeedbackContext, FeedbackServiceProviderInterface, Report, SendReportStatus} from './feedback_types.js'; import {getFeedbackServiceProvider} from './mojo_interface_provider.js'; /** @@ -70,6 +70,13 @@ * @private */ this.description_; + + /** + * The status of sending report. + * @type {?SendReportStatus} + * @private + */ + this.sendReportStatus_; } ready() { @@ -118,6 +125,7 @@ // take a while. this.feedbackServiceProvider_.sendReport(report).then((response) => { this.currentState_ = FeedbackFlowState.CONFIRMATION; + this.sendReportStatus_ = response.status; }); break; default: @@ -147,6 +155,13 @@ } /** + * @param {!SendReportStatus} status + */ + setSendReportStatusForTesting(status) { + this.sendReportStatus_ = status; + } + + /** * @param {string} text */ setDescriptionForTesting(text) {
diff --git a/ash/webui/os_feedback_ui/resources/feedback_types.js b/ash/webui/os_feedback_ui/resources/feedback_types.js index cd6138d..a7da5c2 100644 --- a/ash/webui/os_feedback_ui/resources/feedback_types.js +++ b/ash/webui/os_feedback_ui/resources/feedback_types.js
@@ -7,6 +7,8 @@ * Type aliases for the mojo API. */ +import '//resources/mojo/mojo/public/mojom/base/big_buffer.mojom-lite.js'; +import '//resources/mojo/mojo/public/mojom/base/string16.mojom-lite.js'; import '//resources/mojo/mojo/public/js/mojo_bindings_lite.js'; import '//resources/mojo/url/mojom/url.mojom-lite.js'; import './mojom/os_feedback_ui.mojom-lite.js';
diff --git a/ash/webui/personalization_app/personalization_app_ui.cc b/ash/webui/personalization_app/personalization_app_ui.cc index b41365d..3953851 100644 --- a/ash/webui/personalization_app/personalization_app_ui.cc +++ b/ash/webui/personalization_app/personalization_app_ui.cc
@@ -203,6 +203,8 @@ IDS_PERSONALIZATION_APP_KEYBOARD_BACKLIGHT_TITLE}, {"wallpaperColor", IDS_PERSONALIZATION_APP_KEYBOARD_BACKLIGHT_WALLPAPER_COLOR_LABEL}, + {"wallpaperColorTooltipText", + IDS_PERSONALIZATION_APP_KEYBOARD_BACKLIGHT_WALLPAPER_COLOR_TOOLTIP_TEXT}, {"whiteColor", IDS_PERSONALIZATION_APP_KEYBOARD_BACKLIGHT_WHITE_COLOR_LABEL}, {"redColor", IDS_PERSONALIZATION_APP_KEYBOARD_BACKLIGHT_RED_COLOR_LABEL},
diff --git a/ash/webui/personalization_app/resources/common/styles.html b/ash/webui/personalization_app/resources/common/styles.html index 366a9dc..8871d7a6 100644 --- a/ash/webui/personalization_app/resources/common/styles.html +++ b/ash/webui/personalization_app/resources/common/styles.html
@@ -303,5 +303,24 @@ .clickable { cursor: pointer; } + + paper-tooltip::part(tooltip) { + align-items: flex-end; + display: flex; + flex-direction: row; + height: 18px; + padding: 3px 8px; + } + + paper-tooltip { + --paper-tooltip-background: var(--cros-tooltip-background-color); + --paper-tooltip-text-color: var(--cros-tooltip-label-color); + } + + paper-tooltip span { + align-items: center; + display: flex; + font: var(--cros-body-2-font); + } </style> </template>
diff --git a/ash/webui/personalization_app/resources/trusted/ambient/ambient_preview_element.html b/ash/webui/personalization_app/resources/trusted/ambient/ambient_preview_element.html index ab5e77b..2fb3f4a0 100644 --- a/ash/webui/personalization_app/resources/trusted/ambient/ambient_preview_element.html +++ b/ash/webui/personalization_app/resources/trusted/ambient/ambient_preview_element.html
@@ -158,26 +158,6 @@ object-fit: cover; width: 100%; } - - #albumTitleTooltip::part(tooltip) { - align-items: flex-end; - display: flex; - flex-direction: row; - height: 18px; - padding: 3px 8px; - } - - #albumTitleTooltip { - --paper-tooltip-background: var(--cros-tooltip-background-color); - --paper-tooltip-opacity: 0.8; - --paper-tooltip-text-color: var(--cros-tooltip-label-color); - } - - #albumTitleTooltip span { - align-items: center; - display: flex; - font: 400 12px/18px var(--cros-font-family-roboto); - } </style> <div class$="[[getPreviewContainerClass_(ambientModeEnabled_, loading_)]]" id="container"> <slot></slot>
diff --git a/ash/webui/personalization_app/resources/trusted/keyboard_backlight/keyboard_backlight_element.html b/ash/webui/personalization_app/resources/trusted/keyboard_backlight/keyboard_backlight_element.html index 7a5ead34..e0bf677 100644 --- a/ash/webui/personalization_app/resources/trusted/keyboard_backlight/keyboard_backlight_element.html +++ b/ash/webui/personalization_app/resources/trusted/keyboard_backlight/keyboard_backlight_element.html
@@ -103,6 +103,10 @@ <iron-icon icon="personalization:auto"></iron-icon> </div> </div> + <paper-tooltip id="wallpaperColorTooltip" for$="[[wallpaperColorId_]]" + offset="0" aria-hidden="true"> + <span>$i18n{wallpaperColorTooltipText}</span> + </paper-tooltip> <div class="divider"></div> <template is="dom-repeat" items="[[presetColorIds_]]" as="presetColorId"> <div id$="[[presetColorId]]" class$="[[getPresetColorContainerClass_(presetColorId, presetColors_, backlightColor_)]]"
diff --git a/ash/webui/personalization_app/resources/trusted/keyboard_backlight/keyboard_backlight_element.ts b/ash/webui/personalization_app/resources/trusted/keyboard_backlight/keyboard_backlight_element.ts index adc1b65e8..9683ca0b 100644 --- a/ash/webui/personalization_app/resources/trusted/keyboard_backlight/keyboard_backlight_element.ts +++ b/ash/webui/personalization_app/resources/trusted/keyboard_backlight/keyboard_backlight_element.ts
@@ -5,6 +5,7 @@ import 'chrome://resources/polymer/v3_0/iron-a11y-keys/iron-a11y-keys.js'; import 'chrome://resources/polymer/v3_0/iron-selector/iron-selector.js'; import 'chrome://resources/polymer/v3_0/paper-ripple/paper-ripple.js'; +import 'chrome://resources/polymer/v3_0/paper-tooltip/paper-tooltip.js'; import '../../common/styles.js'; import '../cros_button_style.js';
diff --git a/ash/webui/personalization_app/resources/untrusted/images_grid.html b/ash/webui/personalization_app/resources/untrusted/images_grid.html index 83688e31..2a50117 100644 --- a/ash/webui/personalization_app/resources/untrusted/images_grid.html +++ b/ash/webui/personalization_app/resources/untrusted/images_grid.html
@@ -3,25 +3,35 @@ margin: 12px 0; } </style> -<iron-list grid items="[[tiles_]]" role="listbox" - aria-setsize$="[[tiles_.length]]"> - <template> - <div class="photo-container"> - <div class="photo-inner-container" tabindex$="[[tabIndex]]" role="option" - data-asset-id$="[[item.assetId]]" - data-unit-id$="[[item.unitId]]" on-click="onImageSelected_" - on-keypress="onImageSelected_" - aria-posinset$="[[getAriaIndex_(index)]]" - aria-selected$="[[getAriaSelected_(item, selectedAssetId_, pendingSelectedAssetId_)]]" - aria-label$="[[getAriaLabel_(item)]]"> - <div class="photo-images-container"> - <template is="dom-repeat" items="[[item.preview]]" as="preview"> - <img is="cr-auto-img" class$="[[getClassForImg_(index, item)]]" - auto-src="[[preview.url]]" aria-hidden="true" clear-src> - </template> - <iron-icon icon="personalization:checkmark"></iron-icon> - </div> +<template is="dom-if" if="[[tiles_]]"> + <iron-list grid items="[[tiles_]]" role="listbox" + aria-setsize$="[[tiles_.length]]"> + <template> + <div class="photo-container"> + <template is="dom-if" if="[[isLoadingTile_(item)]]"> + <div tabindex$="[[tabIndex]]" role="button" + class="photo-inner-container placeholder" + style$="[[getLoadingPlaceholderAnimationDelay_(index)]]" + aria-label="$i18n{ariaLabelLoading}" aria-disabled="true"></div> + </template> + <template is="dom-if" if="[[isImageTile_(item)]]"> + <div class="photo-inner-container" tabindex$="[[tabIndex]]" + role="option" data-asset-id$="[[item.assetId]]" + data-unit-id$="[[item.unitId]]" on-click="onImageSelected_" + on-keypress="onImageSelected_" + aria-posinset$="[[getAriaIndex_(index)]]" + aria-selected$="[[getAriaSelected_(item, selectedAssetId_, pendingSelectedAssetId_)]]" + aria-label$="[[getAriaLabel_(item)]]"> + <div class="photo-images-container"> + <template is="dom-repeat" items="[[item.preview]]" as="preview"> + <img is="cr-auto-img" class$="[[getClassForImg_(index, item)]]" + auto-src="[[preview.url]]" aria-hidden="true" clear-src> + </template> + <iron-icon icon="personalization:checkmark"></iron-icon> + </div> + </div> + </template> </div> - </div> - </template> -</iron-list> + </template> + </iron-list> +</template>
diff --git a/ash/webui/personalization_app/resources/untrusted/images_grid.ts b/ash/webui/personalization_app/resources/untrusted/images_grid.ts index 8904abd..17ac993 100644 --- a/ash/webui/personalization_app/resources/untrusted/images_grid.ts +++ b/ash/webui/personalization_app/resources/untrusted/images_grid.ts
@@ -11,7 +11,7 @@ import {afterNextRender, PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {Events, EventType, ImageTile} from '../common/constants.js'; -import {isSelectionEvent} from '../common/utils.js'; +import {getLoadingPlaceholderAnimationDelay, getLoadingPlaceholders, isSelectionEvent} from '../common/utils.js'; import {selectImage, validateReceivedData} from '../untrusted/iframe_api.js'; import {getTemplate} from './images_grid.html.js'; @@ -34,7 +34,11 @@ return { tiles_: { type: Array, - value: [], + value() { + // Fill the view with loading tiles. Will be adjusted to the correct + // number of tiles when collections are received. + return getLoadingPlaceholders(() => 0); + } }, selectedAssetId_: { @@ -49,7 +53,7 @@ }; } - private tiles_: ImageTile[]; + private tiles_: ImageTile[]|number[]; private selectedAssetId_: bigint|undefined; private pendingSelectedAssetId_: bigint|undefined; @@ -91,6 +95,19 @@ } } + private isLoadingTile_(tile: number|ImageTile): tile is number { + return typeof tile === 'number'; + } + + private isImageTile_(tile: number|ImageTile): tile is ImageTile { + return tile.hasOwnProperty('preview') && + Array.isArray((tile as any).preview); + } + + private getLoadingPlaceholderAnimationDelay_(index: number): string { + return getLoadingPlaceholderAnimationDelay(index); + } + private getAriaSelected_( tile: ImageTile, selectedAssetId: bigint|undefined, pendingSelectedAssetId: bigint|undefined): string {
diff --git a/ash/webui/projector_app/annotator_message_handler.cc b/ash/webui/projector_app/annotator_message_handler.cc index 5a80037a1..6ccc92a839 100644 --- a/ash/webui/projector_app/annotator_message_handler.cc +++ b/ash/webui/projector_app/annotator_message_handler.cc
@@ -20,10 +20,6 @@ void AnnotatorMessageHandler::RegisterMessages() { web_ui()->RegisterMessageCallback( - "onToolSet", base::BindRepeating(&AnnotatorMessageHandler::OnToolSet, - base::Unretained(this))); - - web_ui()->RegisterMessageCallback( "onUndoRedoAvailabilityChanged", base::BindRepeating( &AnnotatorMessageHandler::OnUndoRedoAvailabilityChanged, @@ -33,10 +29,6 @@ "onCanvasInitialized", base::BindRepeating(&AnnotatorMessageHandler::OnCanvasInitialized, base::Unretained(this))); - - web_ui()->RegisterMessageCallback( - "onError", base::BindRepeating(&AnnotatorMessageHandler::OnError, - base::Unretained(this))); } void AnnotatorMessageHandler::SetTool(const AnnotatorTool& tool) { @@ -59,11 +51,6 @@ FireWebUIListener("clear"); } -void AnnotatorMessageHandler::OnToolSet(const base::Value::List& args) { - DCHECK_EQ(args.size(), 1u); - ProjectorController::Get()->OnToolSet(AnnotatorTool::FromValue(args[0])); -} - void AnnotatorMessageHandler::OnUndoRedoAvailabilityChanged( const base::Value::List& args) { DCHECK_EQ(args.size(), 2u); @@ -80,10 +67,4 @@ ProjectorController::Get()->OnCanvasInitialized(args[0].GetBool()); } -void AnnotatorMessageHandler::OnError(const base::Value::List& args) { - // TODO(b/200846160): The annotator is in an error state. Show creation flow - // error notification and trigger a reload of the WebContent hosting the - // annotator to clear the error state. -} - } // namespace ash
diff --git a/ash/webui/projector_app/resources/annotator/annotator_embedder_impl.js b/ash/webui/projector_app/resources/annotator/annotator_embedder_impl.js index fbe526d..94fd9e5 100644 --- a/ash/webui/projector_app/resources/annotator/annotator_embedder_impl.js +++ b/ash/webui/projector_app/resources/annotator/annotator_embedder_impl.js
@@ -58,10 +58,7 @@ this.addWebUIListener('setTool', async (tool) => { try { - const success = await client.setTool(tool); - if (success) { - ProjectorBrowserProxyImpl.getInstance().onToolSet(tool); - } + client.setTool(tool); } catch (error) { ProjectorBrowserProxyImpl.getInstance().onError( [AnnotatorToolErrorType.SET_TOOL_ERROR]);
diff --git a/ash/webui/projector_app/resources/communication/projector_browser_proxy.js b/ash/webui/projector_app/resources/communication/projector_browser_proxy.js index 0ee2b80..7097bf0 100644 --- a/ash/webui/projector_app/resources/communication/projector_browser_proxy.js +++ b/ash/webui/projector_app/resources/communication/projector_browser_proxy.js
@@ -12,12 +12,6 @@ */ export class ProjectorBrowserProxy { /** - * Notifies the embedder content that tool has been set for annotator. - * @param {!projectorApp.AnnotatorToolParams} tool - */ - onToolSet(tool) {} - - /** * Notifies the embedder content that undo/redo availability changed for * annotator. * @param {boolean} undoAvailable @@ -135,11 +129,6 @@ */ export class ProjectorBrowserProxyImpl { /** @override */ - onToolSet(tool) { - return chrome.send('onToolSet', [tool]); - } - - /** @override */ onUndoRedoAvailabilityChanged(undoAvailable, redoAvailable) { return chrome.send( 'onUndoRedoAvailabilityChanged', [undoAvailable, redoAvailable]);
diff --git a/ash/webui/projector_app/test/annotator_message_handler_unittest.cc b/ash/webui/projector_app/test/annotator_message_handler_unittest.cc index cc0a9a5..4b82a32 100644 --- a/ash/webui/projector_app/test/annotator_message_handler_unittest.cc +++ b/ash/webui/projector_app/test/annotator_message_handler_unittest.cc
@@ -84,13 +84,6 @@ AnnotatorTool requested_tool = AnnotatorTool::FromValue(*call_data.arg2()); EXPECT_EQ(requested_tool, expected_tool); - - // Now let's check that when the tool has been set, we notify the callback. - EXPECT_CALL(controller(), OnToolSet(expected_tool)); - - base::ListValue list_args; - list_args.Append(expected_tool.ToValue()); - web_ui().HandleReceivedMessage("onToolSet", &list_args); } TEST_F(AnnotatorMessageHandlerTest, Undo) {
diff --git a/ash/webui/shimless_rma/backend/version_updater_unittest.cc b/ash/webui/shimless_rma/backend/version_updater_unittest.cc index 977a172..faae4321 100644 --- a/ash/webui/shimless_rma/backend/version_updater_unittest.cc +++ b/ash/webui/shimless_rma/backend/version_updater_unittest.cc
@@ -8,6 +8,7 @@ #include "base/bind.h" #include "base/test/task_environment.h" +#include "chromeos/ash/components/network/onc/network_onc_utils.h" #include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/dbus/update_engine/fake_update_engine_client.h" #include "chromeos/dbus/update_engine/update_engine.pb.h" @@ -20,7 +21,6 @@ #include "chromeos/network/network_handler.h" #include "chromeos/network/network_profile_handler.h" #include "chromeos/network/network_state_test_helper.h" -#include "chromeos/network/onc/network_onc_utils.h" #include "chromeos/network/proxy/ui_proxy_config_service.h" #include "chromeos/services/network_config/public/cpp/cros_network_config_test_helper.h" #include "chromeos/services/network_config/public/mojom/cros_network_config.mojom.h"
diff --git a/ash/webui/shimless_rma/resources/shimless_rma.html b/ash/webui/shimless_rma/resources/shimless_rma.html index 9d8a6d5..553ae9d2 100644 --- a/ash/webui/shimless_rma/resources/shimless_rma.html +++ b/ash/webui/shimless_rma/resources/shimless_rma.html
@@ -37,8 +37,9 @@ #back { border: 0; - height: 100%; - padding-inline-start: 0; + border-radius: 16px; + height: 32px; + padding-inline-start: 16px; } #next {
diff --git a/base/BUILD.gn b/base/BUILD.gn index 01eda7c..d1abe6d5 100644 --- a/base/BUILD.gn +++ b/base/BUILD.gn
@@ -1858,6 +1858,8 @@ # by public //base headers, which requires they be on the include path. # TODO(https://crbug.com/841171): Move these back to |deps|. public_deps += [ + "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.buildinfo", + "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.hwinfo", "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.intl", "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.io", "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.logger", @@ -3742,6 +3744,7 @@ "fuchsia/service_directory_test_base.h", "fuchsia/service_provider_impl_unittest.cc", "fuchsia/system_build_info_unittest.cc", + "fuchsia/system_product_info_unittest.cc", "fuchsia/test_component_context_for_process_unittest.cc", "fuchsia/time_zone_data_unittest.cc", "message_loop/fd_watch_controller_posix_unittest.cc", @@ -3754,6 +3757,7 @@ ":test_log_listener_safe", ":testfidl", "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.buildinfo", + "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.hwinfo", "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.intl", "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.logger", "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.mem",
diff --git a/base/fuchsia/system_info.cc b/base/fuchsia/system_info.cc index 1fe1812..4cf82970 100644 --- a/base/fuchsia/system_info.cc +++ b/base/fuchsia/system_info.cc
@@ -5,54 +5,69 @@ #include "base/fuchsia/system_info.h" #include <fuchsia/buildinfo/cpp/fidl.h> +#include <fuchsia/hwinfo/cpp/fidl.h> #include <lib/sys/cpp/component_context.h> #include "base/check.h" #include "base/fuchsia/fuchsia_logging.h" #include "base/fuchsia/process_context.h" +#include "base/location.h" #include "base/no_destructor.h" #include "base/threading/scoped_blocking_call.h" -#include "base/threading/thread_restrictions.h" namespace base { namespace { -fuchsia::buildinfo::BuildInfo FetchSystemBuildInfo() { - ScopedBlockingCall scoped_blocking_call(FROM_HERE, BlockingType::WILL_BLOCK); - - fuchsia::buildinfo::ProviderSyncPtr build_info_provider_sync; - ComponentContextForProcess()->svc()->Connect( - build_info_provider_sync.NewRequest()); - - fuchsia::buildinfo::BuildInfo build_info; - zx_status_t status = build_info_provider_sync->GetBuildInfo(&build_info); - ZX_DCHECK(status == ZX_OK, status); - DCHECK(!build_info.IsEmpty()) << "FIDL service returned empty BuildInfo"; - return build_info; +// Returns this process's ProductInfo object. +template <typename Data> +Data& CachedData() { + static NoDestructor<Data> data; + return *data; } -// Returns this process's BuildInfo object. -fuchsia::buildinfo::BuildInfo& CachedBuildInfo() { - static NoDestructor<fuchsia::buildinfo::BuildInfo> build_info; - return *build_info; +template <typename Data> +const Data& GetCachedData() { + DCHECK(!CachedData<Data>().IsEmpty()) + << "FetchAndCacheSystemInfo() has not been called in this process"; + return CachedData<Data>(); +} + +template <typename Interface, + typename Data, + zx_status_t (Interface::Sync_::*Getter)(Data*)> +void FetchAndCacheData() { + DCHECK(CachedData<Data>().IsEmpty()) << "Only call once per process"; + + fidl::SynchronousInterfacePtr<Interface> provider_sync; + ComponentContextForProcess()->svc()->Connect(provider_sync.NewRequest()); + + zx_status_t status = (provider_sync.get()->*Getter)(&CachedData<Data>()); + ZX_CHECK(status == ZX_OK, status) << Interface::Name_; + DCHECK(!CachedData<Data>().IsEmpty()) << "FIDL service returned empty data"; } } // namespace void FetchAndCacheSystemInfo() { - DCHECK(CachedBuildInfo().IsEmpty()) << "Only call once per process"; - CachedBuildInfo() = FetchSystemBuildInfo(); + ScopedBlockingCall scoped_blocking_call(FROM_HERE, BlockingType::WILL_BLOCK); + FetchAndCacheData<fuchsia::buildinfo::Provider, fuchsia::buildinfo::BuildInfo, + &fuchsia::buildinfo::Provider_Sync::GetBuildInfo>(); + FetchAndCacheData<fuchsia::hwinfo::Product, fuchsia::hwinfo::ProductInfo, + &fuchsia::hwinfo::Product_Sync::GetInfo>(); } const fuchsia::buildinfo::BuildInfo& GetCachedBuildInfo() { - DCHECK(!CachedBuildInfo().IsEmpty()) - << "FetchAndCacheSystemInfo() has not been called in this process"; - return CachedBuildInfo(); + return GetCachedData<fuchsia::buildinfo::BuildInfo>(); +} + +const fuchsia::hwinfo::ProductInfo& GetCachedProductInfo() { + return GetCachedData<fuchsia::hwinfo::ProductInfo>(); } void ClearCachedSystemInfoForTesting() { - CachedBuildInfo() = {}; + CachedData<fuchsia::buildinfo::BuildInfo>() = {}; + CachedData<fuchsia::hwinfo::ProductInfo>() = {}; } } // namespace base
diff --git a/base/fuchsia/system_info.h b/base/fuchsia/system_info.h index 481e2ff..ad48a992 100644 --- a/base/fuchsia/system_info.h +++ b/base/fuchsia/system_info.h
@@ -6,25 +6,29 @@ #define BASE_FUCHSIA_SYSTEM_INFO_H_ #include "base/base_export.h" -#include "base/strings/string_piece_forward.h" -namespace fuchsia { -namespace buildinfo { +namespace fuchsia::buildinfo { class BuildInfo; } -} // namespace fuchsia +namespace fuchsia::hwinfo { +class ProductInfo; +} namespace base { -// Fetches the build info from the system and caches it before returning. -// Must be called in each process before calling other non-test functions. +// Makes a blocking call to fetch the info from the system and caches it +// before returning. Must be called in each process during the initialization +// phase. BASE_EXPORT void FetchAndCacheSystemInfo(); // Returns the cached build info. BASE_EXPORT const fuchsia::buildinfo::BuildInfo& GetCachedBuildInfo(); -// Reset the cached BuildInfo to empty so that FetchAndCacheSystemInfo() -// can be called again in this process. +// Returns the cached product info. +BASE_EXPORT const fuchsia::hwinfo::ProductInfo& GetCachedProductInfo(); + +// Reset the cached system info to empty so that +// FetchAndCacheSystemInfo() can be called again in this process. BASE_EXPORT void ClearCachedSystemInfoForTesting(); } // namespace base
diff --git a/base/fuchsia/system_product_info_unittest.cc b/base/fuchsia/system_product_info_unittest.cc new file mode 100644 index 0000000..63171d1 --- /dev/null +++ b/base/fuchsia/system_product_info_unittest.cc
@@ -0,0 +1,130 @@ +// 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/fuchsia/system_info.h" + +#include <fuchsia/buildinfo/cpp/fidl.h> +#include <fuchsia/hwinfo/cpp/fidl.h> +#include <fuchsia/hwinfo/cpp/fidl_test_base.h> +#include <memory> + +#include "base/bind.h" +#include "base/fuchsia/scoped_service_binding.h" +#include "base/fuchsia/scoped_service_publisher.h" +#include "base/fuchsia/test_component_context_for_process.h" +#include "base/location.h" +#include "base/run_loop.h" +#include "base/strings/string_piece_forward.h" +#include "base/test/bind.h" +#include "base/test/gtest_util.h" +#include "base/test/task_environment.h" +#include "base/test/test_future.h" +#include "base/threading/sequence_bound.h" +#include "base/threading/thread.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace base { + +namespace { + +class FakeHardwareInfoProduct + : public fuchsia::hwinfo::testing::Product_TestBase { + public: + FakeHardwareInfoProduct(const base::StringPiece model, + const base::StringPiece manufacturer, + sys::OutgoingDirectory* outgoing_services) + : model_(model), + manufacturer_(manufacturer), + binding_(outgoing_services, this) {} + FakeHardwareInfoProduct(const FakeHardwareInfoProduct&) = delete; + FakeHardwareInfoProduct& operator=(const FakeHardwareInfoProduct&) = delete; + ~FakeHardwareInfoProduct() override = default; + + // fuchsia::hwinfo::testing::Provider_TestBase implementation + void GetInfo(GetInfoCallback callback) override { + fuchsia::hwinfo::ProductInfo product_info; + product_info.set_model(model_); + product_info.set_manufacturer(manufacturer_); + callback(std::move(product_info)); + } + void NotImplemented_(const std::string& name) final { + ADD_FAILURE() << "Unexpected call: " << name; + } + + private: + std::string model_; + std::string manufacturer_; + ScopedServiceBinding<fuchsia::hwinfo::Product> binding_; +}; + +} // namespace + +// Uses a fake "fuchsia.hwinfo.Product" implementation. +// clears the cached ProductInfo to ensure that each test starts with no cached +// ProductInfo and that subsequent tests runs do not use fake values. +class ProductInfoTest : public testing::Test { + protected: + ProductInfoTest() + : task_environment_( + base::test::SingleThreadTaskEnvironment::MainThreadType::IO), + thread_("ProductInfo Retrieval Thread") { + thread_.StartWithOptions( + base::Thread::Options(base::MessagePumpType::IO, 0)); + ClearCachedSystemInfoForTesting(); + component_context_.AddService(fuchsia::buildinfo::Provider::Name_); + } + ~ProductInfoTest() override { ClearCachedSystemInfoForTesting(); } + + // Fetch the product info in a separate thread, while servicing the + // FIDL fake implementation on the main thread. + void FetchProductInfoAndWaitUntilCached() { + base::RunLoop run_loop; + thread_.task_runner()->PostTaskAndReply( + FROM_HERE, BindOnce(&FetchAndCacheSystemInfo), run_loop.QuitClosure()); + run_loop.Run(); + } + + base::test::SingleThreadTaskEnvironment task_environment_; + TestComponentContextForProcess component_context_; + base::Thread thread_; +}; + +using ProductInfoDeathTest = ProductInfoTest; + +TEST_F(ProductInfoTest, GetCachedProductInfoReturnsFakedValues) { + FakeHardwareInfoProduct hwinfo_product_provider( + "test.model", "test.manufacturer", + component_context_.additional_services()); + FetchProductInfoAndWaitUntilCached(); + + const auto& product_info = GetCachedProductInfo(); + EXPECT_EQ(product_info.model(), "test.model"); + EXPECT_EQ(product_info.manufacturer(), "test.manufacturer"); +} + +TEST_F(ProductInfoDeathTest, DcheckOnGetWithoutFetch) { + EXPECT_DCHECK_DEATH_WITH( + GetCachedProductInfo(), + "FetchAndCacheSystemInfo\\(\\) has not been called in this " + "process"); +} + +TEST_F(ProductInfoTest, SystemServiceReturnsValidValues) { + component_context_.AddService(fuchsia::hwinfo::Product::Name_); + FetchProductInfoAndWaitUntilCached(); + + const auto& product_info = GetCachedProductInfo(); + EXPECT_TRUE(product_info.has_model()); + EXPECT_FALSE(product_info.model().empty()); + + EXPECT_TRUE(product_info.has_manufacturer()); + EXPECT_FALSE(product_info.manufacturer().empty()); +} + +TEST_F(ProductInfoDeathTest, DcheckOnServiceNotPresent) { + EXPECT_DCHECK_DEATH_WITH(FetchProductInfoAndWaitUntilCached(), + "ZX_ERR_PEER_CLOSED"); +} + +} // namespace base
diff --git a/base/process/process.h b/base/process/process.h index 19d2c2e..619374c 100644 --- a/base/process/process.h +++ b/base/process/process.h
@@ -20,10 +20,13 @@ #include <lib/zx/process.h> #endif -#if BUILDFLAG(IS_APPLE) +#if BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_CHROMEOS) #include "base/feature_list.h" +#endif // BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_CHROMEOS) + +#if BUILDFLAG(IS_APPLE) #include "base/process/port_provider_mac.h" -#endif +#endif // BUILDFLAG(IS_APPLE) namespace base { @@ -31,6 +34,14 @@ extern const Feature kMacAllowBackgroundingProcesses; #endif +#if BUILDFLAG(IS_CHROMEOS) +// OneGroupPerRenderer feature places each foreground renderer process into +// its own cgroup. This will cause the scheduler to use the aggregate runtime +// of all threads in the process when deciding on the next thread to schedule. +// It will help guarantee fairness between renderers. +BASE_EXPORT extern const Feature kOneGroupPerRenderer; +#endif + // Provides a move-only encapsulation of a process. // // This object is not tied to the lifetime of the underlying process: the @@ -113,6 +124,12 @@ // Returns true if this process is the current process. bool is_current() const; +#if BUILDFLAG(IS_CHROMEOS) + // A unique token generated for each process, this is used to create a unique + // cgroup for each renderer. + const std::string& unique_token() const { return unique_token_; } +#endif + // Close the process handle. This will not terminate the process. void Close(); @@ -171,8 +188,8 @@ #if BUILDFLAG(IS_MAC) // The Mac needs a Mach port in order to manipulate a process's priority, // and there's no good way to get that from base given the pid. These Mac - // variants of the IsProcessBackgrounded and SetProcessBackgrounded API take - // a port provider for this reason. See crbug.com/460102 + // variants of the IsProcessBackgrounded() and SetProcessBackgrounded() API + // take a port provider for this reason. See crbug.com/460102 // // A process is backgrounded when its task priority is // |TASK_BACKGROUND_APPLICATION|. @@ -211,7 +228,39 @@ ProcessId GetPidInNamespace() const; #endif +#if BUILDFLAG(IS_CHROMEOS) + // Returns true if the 'OneGroupPerRenderer' feature is enabled. The feature + // is enabled if the kOneGroupPerRenderer feature flag is enabled and the + // system supports the chrome cgroups. + static bool OneGroupPerRendererEnabled(); + + // If OneGroupPerRenderer is enabled, runs at process startup to clean up + // any stale cgroups that were left behind from any unclean exits of the + // browser process. + static void CleanUpStaleProcessStates(); + + // Initializes the process's priority. If OneGroupPerRenderer is enabled, it + // creates a unique cgroup for the process. This should be called before + // SetProcessBackgrounded(). This is a no-op if the Process is not valid + // or if it has already been called. + void InitializePriority(); +#endif // BUILDFLAG(IS_CHROMEOS) + private: +#if BUILDFLAG(IS_CHROMEOS) + // Cleans up process state. If OneGroupPerRenderer is enabled, it cleans up + // the cgroup created by InitializePriority(). If the process has not + // fully terminated yet, it will post a background task to try again. + void CleanUpProcess(int remaining_retries) const; + + // Calls CleanUpProcess() on a background thread. + void CleanUpProcessAsync() const; + + // Used to call CleanUpProcess() on a background thread because Process is not + // refcounted. + static void CleanUpProcessScheduled(Process process, int remaining_retries); +#endif // BUILDFLAG(IS_CHROMEOS) + #if BUILDFLAG(IS_WIN) win::ScopedHandle process_; #elif BUILDFLAG(IS_FUCHSIA) @@ -223,6 +272,14 @@ #if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_FUCHSIA) bool is_current_process_; #endif + +#if BUILDFLAG(IS_CHROMEOS) + // A unique token per process not per class instance (`base::Process`). This + // is similar to the PID of a process but should not be reused after the + // process's termination. The token will be copied during Duplicate() + // and move semantics as is the PID/ProcessHandle. + std::string unique_token_; +#endif }; #if BUILDFLAG(IS_CHROMEOS)
diff --git a/base/process/process_linux.cc b/base/process/process_linux.cc index a5cf7ba..3d916bd 100644 --- a/base/process/process_linux.cc +++ b/base/process/process_linux.cc
@@ -7,21 +7,49 @@ #include <errno.h> #include <sys/resource.h> +#include <cstring> + #include "base/check.h" #include "base/files/file_util.h" +#include "base/location.h" +#include "base/logging.h" #include "base/notreached.h" #include "base/posix/can_lower_nice_to.h" #include "base/process/internal_linux.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_split.h" #include "base/strings/stringprintf.h" -#include "base/synchronization/lock.h" #include "base/threading/thread_restrictions.h" #include "build/build_config.h" #include "build/chromeos_buildflags.h" +#if BUILDFLAG(IS_CHROMEOS) +#include "base/bind.h" +#include "base/feature_list.h" +#include "base/files/file_enumerator.h" +#include "base/files/file_path.h" +#include "base/process/process_handle.h" +#include "base/strings/strcat.h" +#include "base/strings/string_util.h" +#include "base/task/thread_pool.h" +#include "base/unguessable_token.h" +#endif // BUILDFLAG(IS_CHROMEOS) + namespace base { +#if BUILDFLAG(IS_CHROMEOS) +const Feature kOneGroupPerRenderer { + "OneGroupPerRenderer", + +#if BUILDFLAG(IS_CHROMEOS_LACROS) + FEATURE_ENABLED_BY_DEFAULT +}; +#else + FEATURE_DISABLED_BY_DEFAULT +}; +#endif // BUILDFLAG(IS_CHROMEOS_LACROS) +#endif // BUILDFLAG(IS_CHROMEOS) + namespace { const int kForegroundPriority = 0; @@ -36,9 +64,21 @@ // chrome / chromeos specific logic here. const int kBackgroundPriority = 19; const char kControlPath[] = "/sys/fs/cgroup/cpu%s/cgroup.procs"; +const char kFullRendererCgroupRoot[] = "/sys/fs/cgroup/cpu/chrome_renderers"; const char kForeground[] = "/chrome_renderers/foreground"; const char kBackground[] = "/chrome_renderers/background"; const char kProcPath[] = "/proc/%d/cgroup"; +const char kUclampMinFile[] = "cpu.uclamp.min"; +const char kUclampMaxFile[] = "cpu.uclamp.max"; + +constexpr int kCgroupDeleteRetries = 3; +constexpr TimeDelta kCgroupDeleteRetryTime(Seconds(1)); + +#if BUILDFLAG(IS_CHROMEOS_LACROS) +const char kCgroupPrefix[] = "l-"; +#elif BUILDFLAG(IS_CHROMEOS_ASH) +const char kCgroupPrefix[] = "a-"; +#endif struct CGroups { // Check for cgroups files. ChromeOS supports these by default. It creates @@ -47,21 +87,59 @@ // all background renderers. This allows us to limit the impact of background // renderers on foreground ones to a greater level than simple renicing. bool enabled; - base::FilePath foreground_file; - base::FilePath background_file; + FilePath foreground_file; + FilePath background_file; + + // A unique token for this instance of the browser. + std::string group_prefix_token; + + // UCLAMP settings for the foreground cgroups. + std::string uclamp_min; + std::string uclamp_max; CGroups() { - foreground_file = - base::FilePath(base::StringPrintf(kControlPath, kForeground)); - background_file = - base::FilePath(base::StringPrintf(kControlPath, kBackground)); - base::FileSystemType foreground_type; - base::FileSystemType background_type; - enabled = - base::GetFileSystemType(foreground_file, &foreground_type) && - base::GetFileSystemType(background_file, &background_type) && - foreground_type == FILE_SYSTEM_CGROUP && - background_type == FILE_SYSTEM_CGROUP; + foreground_file = FilePath(StringPrintf(kControlPath, kForeground)); + background_file = FilePath(StringPrintf(kControlPath, kBackground)); + FileSystemType foreground_type; + FileSystemType background_type; + enabled = GetFileSystemType(foreground_file, &foreground_type) && + GetFileSystemType(background_file, &background_type) && + foreground_type == FILE_SYSTEM_CGROUP && + background_type == FILE_SYSTEM_CGROUP; + + if (!enabled || !FeatureList::IsEnabled(kOneGroupPerRenderer)) { + return; + } + + // Generate a unique token for the full browser process + group_prefix_token = + StrCat({kCgroupPrefix, UnguessableToken::Create().ToString(), "-"}); + + // Reads the ULCAMP settings from the foreground cgroup that will be used + // for each renderer's cgroup. + FilePath foreground_path = foreground_file.DirName(); + ReadFileToString(foreground_path.Append(kUclampMinFile), &uclamp_min); + ReadFileToString(foreground_path.Append(kUclampMaxFile), &uclamp_max); + } + + // Returns the full path to a the cgroup dir of a process using + // the supplied token. + static FilePath GetForegroundCgroupDir(const std::string& token) { + // Get individualized cgroup if the feature is enabled + std::string cgroup_path_str; + StrAppend(&cgroup_path_str, {kFullRendererCgroupRoot, "/", token}); + return FilePath(cgroup_path_str); + } + + // Returns the path to the cgroup.procs file of the foreground cgroup. + static FilePath GetForegroundCgroupFile(const std::string& token) { + // Processes with an empty token use the default foreground cgroup. + if (token.empty()) { + return CGroups::Get().foreground_file; + } + + FilePath cgroup_path = GetForegroundCgroupDir(token); + return cgroup_path.Append("cgroup.procs"); } static CGroups& Get() { @@ -69,6 +147,7 @@ return groups; } }; + #else const int kBackgroundPriority = 5; #endif // BUILDFLAG(IS_CHROMEOS) @@ -110,10 +189,9 @@ #if BUILDFLAG(IS_CHROMEOS) if (CGroups::Get().enabled) { // Used to allow reading the process priority from proc on thread launch. - base::ThreadRestrictions::ScopedAllowIO allow_io; + ThreadRestrictions::ScopedAllowIO allow_io; std::string proc; - if (base::ReadFileToString( - base::FilePath(StringPrintf(kProcPath, process_)), &proc)) { + if (ReadFileToString(FilePath(StringPrintf(kProcPath, process_)), &proc)) { return IsProcessBackgroundedCGroup(proc); } return false; @@ -129,9 +207,10 @@ #if BUILDFLAG(IS_CHROMEOS) if (CGroups::Get().enabled) { std::string pid = NumberToString(process_); - const base::FilePath file = background ? CGroups::Get().background_file - : CGroups::Get().foreground_file; - return base::WriteFile(file, pid.c_str(), pid.size()) > 0; + const FilePath file = + background ? CGroups::Get().background_file + : CGroups::Get().GetForegroundCgroupFile(unique_token_); + return WriteFile(file, pid); } #endif // BUILDFLAG(IS_CHROMEOS) @@ -207,4 +286,132 @@ } #endif // BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) +// static +bool Process::OneGroupPerRendererEnabled() { + return CGroups::Get().enabled && FeatureList::IsEnabled(kOneGroupPerRenderer); +} + +// On Chrome OS, each renderer runs in its own cgroup when running in the +// foreground. After process creation the cgroup is created using a +// unique token. +void Process::InitializePriority() { + if (!OneGroupPerRendererEnabled() || !IsValid() || !unique_token_.empty()) { + return; + } + + // The token has the following format: + // {cgroup_prefix}{UnguessableToken} + // The cgroup prefix is to distinguish ash from lacros tokens for stale + // cgroup cleanup. + unique_token_ = StrCat({CGroups::Get().group_prefix_token, + UnguessableToken::Create().ToString()}); + + FilePath cgroup_path = CGroups::Get().GetForegroundCgroupDir(unique_token_); + // Note that CreateDirectoryAndGetError() does not fail if the directory + // already exits. + if (!CreateDirectoryAndGetError(cgroup_path, nullptr)) { + // If creating the directory fails, fall back to use the foreground group. + int saved_errno = errno; + LOG(ERROR) << "Failed to create cgroup, falling back to foreground" + << ", cgroup=" << cgroup_path + << ", errno=" << strerror(saved_errno); + + unique_token_.clear(); + return; + } + + if (!CGroups::Get().uclamp_min.empty() && + !WriteFile(cgroup_path.Append(kUclampMinFile), + CGroups::Get().uclamp_min)) { + LOG(ERROR) << "Failed to write uclamp min file, cgroup_path=" + << cgroup_path; + } + if (!CGroups::Get().uclamp_min.empty() && + !WriteFile(cgroup_path.Append(kUclampMaxFile), + CGroups::Get().uclamp_max)) { + LOG(ERROR) << "Failed to write uclamp max file, cgroup_path=" + << cgroup_path; + } +} + +// static +void Process::CleanUpProcessScheduled(Process process, int remaining_retries) { + process.CleanUpProcess(remaining_retries); +} + +void Process::CleanUpProcessAsync() const { + if (!OneGroupPerRendererEnabled() || unique_token_.empty()) { + return; + } + + ThreadPool::PostTask(FROM_HERE, {MayBlock(), TaskPriority::BEST_EFFORT}, + BindOnce(&Process::CleanUpProcessScheduled, Duplicate(), + kCgroupDeleteRetries)); +} + +void Process::CleanUpProcess(int remaining_retries) const { + if (!OneGroupPerRendererEnabled() || unique_token_.empty()) { + return; + } + + // Try to delete the cgroup + // TODO(1322562): We can use notify_on_release to automoatically delete the + // cgroup when the process has left the cgroup. + FilePath cgroup = CGroups::Get().GetForegroundCgroupDir(unique_token_); + if (!DeleteFile(cgroup)) { + auto saved_errno = errno; + LOG(ERROR) << "Failed to delete cgroup " << cgroup + << ", errno=" << strerror(saved_errno); + // If the delete failed, then the process is still potentially in the + // cgroup. Move the process to background and schedule a callback to try + // again. + if (remaining_retries > 0) { + std::string pidstr = NumberToString(process_); + if (!WriteFile(CGroups::Get().background_file, pidstr)) { + // Failed to move the process, LOG a warning but try again. + saved_errno = errno; + LOG(WARNING) << "Failed to move the process to background" + << ", pid=" << pidstr + << ", errno=" << strerror(saved_errno); + } + ThreadPool::PostDelayedTask(FROM_HERE, + {MayBlock(), TaskPriority::BEST_EFFORT}, + BindOnce(&Process::CleanUpProcessScheduled, + Duplicate(), remaining_retries - 1), + kCgroupDeleteRetryTime); + } + } +} + +// static +void Process::CleanUpStaleProcessStates() { + if (!OneGroupPerRendererEnabled()) { + return; + } + + FileEnumerator traversal(FilePath(kFullRendererCgroupRoot), false, + FileEnumerator::DIRECTORIES); + for (FilePath path = traversal.Next(); !path.empty(); + path = traversal.Next()) { + std::string dirname = path.BaseName().value(); + if (dirname == FilePath(kForeground).BaseName().value() || + dirname == FilePath(kBackground).BaseName().value()) { + continue; + } + + if (!StartsWith(dirname, kCgroupPrefix) || + StartsWith(dirname, CGroups::Get().group_prefix_token)) { + continue; + } + + if (!DeleteFile(path)) { + auto saved_errno = errno; + LOG(ERROR) << "Failed to delete " << path + << ", errno=" << strerror(saved_errno); + } + } +} +#endif // BUILDFLAG(IS_CHROMEOS) + } // namespace base
diff --git a/base/process/process_posix.cc b/base/process/process_posix.cc index bc49d4d..f9f633a9 100644 --- a/base/process/process_posix.cc +++ b/base/process/process_posix.cc
@@ -231,21 +231,27 @@ namespace base { -Process::Process(ProcessHandle handle) : process_(handle) { -} - -Process::~Process() = default; +Process::Process(ProcessHandle handle) : process_(handle) {} Process::Process(Process&& other) : process_(other.process_) { +#if BUILDFLAG(IS_CHROMEOS) + unique_token_ = std::move(other.unique_token_); +#endif + other.Close(); } Process& Process::operator=(Process&& other) { process_ = other.process_; +#if BUILDFLAG(IS_CHROMEOS) + unique_token_ = std::move(other.unique_token_); +#endif other.Close(); return *this; } +Process::~Process() = default; + // static Process Process::Current() { return Process(GetCurrentProcessHandle()); @@ -286,7 +292,13 @@ if (is_current()) return Current(); +#if BUILDFLAG(IS_CHROMEOS) + Process duplicate = Process(process_); + duplicate.unique_token_ = unique_token_; + return duplicate; +#else return Process(process_); +#endif } ProcessHandle Process::Release() { @@ -318,6 +330,11 @@ DPLOG(ERROR) << "Unable to terminate process " << process_; return false; } + +#if BUILDFLAG(IS_CHROMEOS) + CleanUpProcessAsync(); +#endif + if (!wait || WaitForExitWithTimeout(Seconds(60), nullptr)) { return true; } @@ -354,7 +371,11 @@ return exited; } -void Process::Exited(int exit_code) const {} +void Process::Exited(int exit_code) const { +#if BUILDFLAG(IS_CHROMEOS) + CleanUpProcessAsync(); +#endif +} int Process::GetPriority() const { DCHECK(IsValid());
diff --git a/base/process/process_unittest.cc b/base/process/process_unittest.cc index 3e64014..261cbee 100644 --- a/base/process/process_unittest.cc +++ b/base/process/process_unittest.cc
@@ -17,6 +17,22 @@ #include "testing/gtest/include/gtest/gtest.h" #include "testing/multiprocess_func_list.h" +#if BUILDFLAG(IS_CHROMEOS) +#include <unistd.h> + +#include <vector> + +#include "base/files/file_path.h" +#include "base/files/file_util.h" +#include "base/strings/string_number_conversions.h" +#include "base/strings/string_split.h" +#include "base/strings/string_util.h" +#include "base/strings/stringprintf.h" +#include "base/test/scoped_feature_list.h" +#include "base/test/task_environment.h" +#include "base/time/time.h" +#endif // BUILDFLAG(IS_CHROMEOS) + #if BUILDFLAG(IS_WIN) #include "base/win/base_win_buildflags.h" #include "base/win/windows_version.h" @@ -44,6 +60,44 @@ }; #endif +#if BUILDFLAG(IS_CHROMEOS) +const char kForeground[] = "/chrome_renderers/foreground"; +const char kCgroupRoot[] = "/sys/fs/cgroup/cpu"; +const char kFullRendererCgroupRoot[] = "/sys/fs/cgroup/cpu/chrome_renderers"; +const char kProcPath[] = "/proc/%d/cgroup"; + +std::string GetProcessCpuCgroup(const base::Process& process) { + std::string proc; + if (!base::ReadFileToString( + base::FilePath(base::StringPrintf(kProcPath, process.Pid())), + &proc)) { + return std::string(); + } + + std::vector<base::StringPiece> lines = SplitStringPiece( + proc, "\n", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY); + for (const auto& line : lines) { + std::vector<base::StringPiece> fields = SplitStringPiece( + line, ":", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); + if (fields.size() != 3U) { + continue; + } + + if (fields[1] == "cpu") { + return static_cast<std::string>(fields[2]); + } + } + + return std::string(); +} + +bool AddProcessToCpuCgroup(const base::Process& process, std::string& cgroup) { + base::FilePath path(cgroup); + path = path.Append("cgroup.procs"); + return base::WriteFile(path, base::NumberToString(process.Pid())); +} +#endif // BUILDFLAG(IS_CHROMEOS) + } // namespace namespace base { @@ -417,6 +471,188 @@ EXPECT_TRUE(IsProcessBackgroundedCGroup(kBackgrounded)); } +TEST_F(ProcessTest, InitializePriorityEmptyProcess) { + // TODO(b/172213843): base::Process is used by base::TestSuite::Initialize + // before we can use ScopedFeatureList here. Update the test to allow the + // use of ScopedFeatureList before base::TestSuite::Initialize runs. + if (!Process::OneGroupPerRendererEnabled()) + return; + + Process process; + process.InitializePriority(); + const std::string unique_token = process.unique_token(); + ASSERT_TRUE(unique_token.empty()); +} + +TEST_F(ProcessTest, SetProcessBackgroundedOneCgroupPerRender) { + if (!Process::OneGroupPerRendererEnabled()) + return; + + base::test::TaskEnvironment task_env; + + Process process(SpawnChild("SimpleChildProcess")); + process.InitializePriority(); + const std::string unique_token = process.unique_token(); + ASSERT_FALSE(unique_token.empty()); + + EXPECT_TRUE(process.SetProcessBackgrounded(false)); + EXPECT_FALSE(process.IsProcessBackgrounded()); + std::string cgroup = GetProcessCpuCgroup(process); + EXPECT_FALSE(cgroup.empty()); + EXPECT_NE(cgroup.find(unique_token), std::string::npos); + + EXPECT_TRUE(process.SetProcessBackgrounded(true)); + EXPECT_TRUE(process.IsProcessBackgrounded()); + + EXPECT_TRUE(process.Terminate(0, false)); + // Terminate should post a task, wait for it to run + task_env.RunUntilIdle(); + + cgroup = std::string(kCgroupRoot) + cgroup; + EXPECT_FALSE(base::DirectoryExists(FilePath(cgroup))); +} + +TEST_F(ProcessTest, CleanUpBusyProcess) { + if (!Process::OneGroupPerRendererEnabled()) + return; + + base::test::TaskEnvironment task_env; + + Process process(SpawnChild("SimpleChildProcess")); + process.InitializePriority(); + const std::string unique_token = process.unique_token(); + ASSERT_FALSE(unique_token.empty()); + + EXPECT_TRUE(process.SetProcessBackgrounded(false)); + EXPECT_FALSE(process.IsProcessBackgrounded()); + std::string cgroup = GetProcessCpuCgroup(process); + EXPECT_FALSE(cgroup.empty()); + EXPECT_NE(cgroup.find(unique_token), std::string::npos); + + // Add another process to the cgroup to ensure it stays busy. + cgroup = std::string(kCgroupRoot) + cgroup; + Process process2(SpawnChild("SimpleChildProcess")); + EXPECT_TRUE(AddProcessToCpuCgroup(process2, cgroup)); + + // Terminate the first process that should tirgger a cleanup of the cgroup + EXPECT_TRUE(process.Terminate(0, false)); + // Wait until the background task runs once. This should fail and requeue + // another task to retry. + task_env.RunUntilIdle(); + EXPECT_TRUE(base::DirectoryExists(FilePath(cgroup))); + + // Move the second process to free the cgroup + std::string foreground_path = + std::string(kCgroupRoot) + std::string(kForeground); + EXPECT_TRUE(AddProcessToCpuCgroup(process2, foreground_path)); + + // Wait for the retry. + PlatformThread::Sleep(base::Milliseconds(1100)); + task_env.RunUntilIdle(); + // The cgroup should be deleted now. + EXPECT_FALSE(base::DirectoryExists(FilePath(cgroup))); + + process2.Terminate(0, false); +} + +TEST_F(ProcessTest, SetProcessBackgroundedEmptyToken) { + if (!Process::OneGroupPerRendererEnabled()) + return; + + Process process(SpawnChild("SimpleChildProcess")); + const std::string unique_token = process.unique_token(); + ASSERT_TRUE(unique_token.empty()); + + // Moving to the foreground should use the default foregorund path + EXPECT_TRUE(process.SetProcessBackgrounded(false)); + EXPECT_FALSE(process.IsProcessBackgrounded()); + std::string cgroup = GetProcessCpuCgroup(process); + EXPECT_FALSE(cgroup.empty()); + EXPECT_EQ(cgroup, kForeground); +} + +TEST_F(ProcessTest, CleansUpStaleGroups) { + if (!Process::OneGroupPerRendererEnabled()) + return; + + base::test::TaskEnvironment task_env; + + // Create a process that will not be cleaned up + Process process(SpawnChild("SimpleChildProcess")); + process.InitializePriority(); + const std::string unique_token = process.unique_token(); + ASSERT_FALSE(unique_token.empty()); + + EXPECT_TRUE(process.SetProcessBackgrounded(true)); + EXPECT_TRUE(process.IsProcessBackgrounded()); + + // Create a stale cgroup + std::string root = kFullRendererCgroupRoot; + std::string cgroup = root + "/" + unique_token; + std::vector<std::string> tokens = base::SplitString( + cgroup, "-", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL); + tokens[1] = "fake"; + std::string fake_cgroup = base::JoinString(tokens, "-"); + EXPECT_TRUE(base::CreateDirectory(FilePath(fake_cgroup))); + + // Clean up stale groups + Process::CleanUpStaleProcessStates(); + + // validate the fake group is deleted + EXPECT_FALSE(base::DirectoryExists(FilePath(fake_cgroup))); + + // validate the active process cgroup is not deleted + EXPECT_TRUE(base::DirectoryExists(FilePath(cgroup))); + + // validate foreground and background are not deleted + EXPECT_TRUE(base::DirectoryExists(FilePath(root + "/foreground"))); + EXPECT_TRUE(base::DirectoryExists(FilePath(root + "/background"))); + + // clean up the process + EXPECT_TRUE(process.Terminate(0, false)); + // Terminate should post a task, wait for it to run + task_env.RunUntilIdle(); + EXPECT_FALSE(base::DirectoryExists(FilePath(cgroup))); +} + +TEST_F(ProcessTest, OneCgroupDoesNotCleanUpGroupsWithWrongPrefix) { + if (!Process::OneGroupPerRendererEnabled()) + return; + + base::test::TaskEnvironment task_env; + + // Create a process that will not be cleaned up + Process process(SpawnChild("SimpleChildProcess")); + process.InitializePriority(); + const std::string unique_token = process.unique_token(); + ASSERT_FALSE(unique_token.empty()); + + EXPECT_TRUE(process.SetProcessBackgrounded(false)); + EXPECT_FALSE(process.IsProcessBackgrounded()); + std::string cgroup = GetProcessCpuCgroup(process); + EXPECT_FALSE(cgroup.empty()); + EXPECT_NE(cgroup.find(unique_token), std::string::npos); + + // Create a stale cgroup + FilePath cgroup_path = FilePath(std::string(kCgroupRoot) + cgroup); + FilePath fake_cgroup = FilePath(kFullRendererCgroupRoot).AppendASCII("fake"); + EXPECT_TRUE(base::CreateDirectory(fake_cgroup)); + + // Clean up stale groups + Process::CleanUpStaleProcessStates(); + + // validate the fake group is deleted + EXPECT_TRUE(base::DirectoryExists(fake_cgroup)); + EXPECT_TRUE(base::DirectoryExists(cgroup_path)); + + // clean up the process + EXPECT_TRUE(process.SetProcessBackgrounded(true)); + EXPECT_TRUE(process.IsProcessBackgrounded()); + EXPECT_TRUE(process.Terminate(0, false)); + task_env.RunUntilIdle(); + EXPECT_FALSE(base::DirectoryExists(cgroup_path)); + base::DeleteFile(fake_cgroup); +} #endif // BUILDFLAG(IS_CHROMEOS) } // namespace base
diff --git a/base/system/sys_info.cc b/base/system/sys_info.cc index daedeb7..adb238f 100644 --- a/base/system/sys_info.cc +++ b/base/system/sys_info.cc
@@ -100,7 +100,8 @@ #endif void SysInfo::GetHardwareInfo(base::OnceCallback<void(HardwareInfo)> callback) { -#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE) +#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE) || \ + BUILDFLAG(IS_FUCHSIA) base::ThreadPool::PostTaskAndReplyWithResult( FROM_HERE, {}, base::BindOnce(&GetHardwareInfoSync), std::move(callback)); #elif BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
diff --git a/base/system/sys_info_fuchsia.cc b/base/system/sys_info_fuchsia.cc index fd77757..e857b41 100644 --- a/base/system/sys_info_fuchsia.cc +++ b/base/system/sys_info_fuchsia.cc
@@ -5,6 +5,7 @@ #include "base/system/sys_info.h" #include <fuchsia/buildinfo/cpp/fidl.h> +#include <fuchsia/hwinfo/cpp/fidl.h> #include <sys/statvfs.h> #include <zircon/syscalls.h> @@ -206,4 +207,14 @@ return getpagesize(); } +SysInfo::HardwareInfo SysInfo::GetHardwareInfoSync() { + const auto& product_info = GetCachedProductInfo(); + + return { + .manufacturer = + product_info.has_manufacturer() ? product_info.manufacturer() : "", + .model = product_info.has_model() ? product_info.model() : "", + }; +} + } // namespace base
diff --git a/base/system/sys_info_unittest.cc b/base/system/sys_info_unittest.cc index 1b0bcae..226ef8c2 100644 --- a/base/system/sys_info_unittest.cc +++ b/base/system/sys_info_unittest.cc
@@ -233,7 +233,7 @@ EXPECT_TRUE(IsStringUTF8(hardware_info->model)); bool empty_result_expected = #if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_WIN) || \ - BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) + BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_FUCHSIA) false; #else true;
diff --git a/build/android/gyp/proguard.py b/build/android/gyp/proguard.py index ad16a8a..6fd132f 100755 --- a/build/android/gyp/proguard.py +++ b/build/android/gyp/proguard.py
@@ -464,10 +464,6 @@ 'com.google.common.flogger.backend.google.GooglePlatform', 'com.google.common.flogger.backend.system.DefaultPlatform', - # trichrome_webview_google_bundle contains this missing reference. - # TODO(crbug.com/1142530): Fix this missing reference properly. - 'org.chromium.build.NativeLibraries', - # TODO(agrieve): Exclude these only when use_jacoco_coverage=true. 'java.lang.instrument.ClassFileTransformer', 'java.lang.instrument.IllegalClassFormatException',
diff --git a/build/config/android/rules.gni b/build/config/android/rules.gni index 1a9b3736..6c119948 100644 --- a/build/config/android/rules.gni +++ b/build/config/android/rules.gni
@@ -2133,6 +2133,7 @@ # uncompressed in the APK. Must be unset or true if load_library_from_apk # is set to true. # uncompress_dex: Store final .dex files uncompressed in the apk. + # omit_dex: If true, do not build or include classes.dex. # strip_resource_names: True if resource names should be stripped from the # resources.arsc file in the apk or module. # strip_unused_resources: True if unused resources should be stripped from @@ -2215,6 +2216,7 @@ defined(invoker.is_base_module) && invoker.is_base_module } + _omit_dex = defined(invoker.omit_dex) && invoker.omit_dex _enable_multidex = !defined(invoker.enable_multidex) || invoker.enable_multidex @@ -2358,12 +2360,13 @@ _rebased_build_config = rebase_path(_build_config, root_build_dir) assert(_rebased_build_config != "") # Mark as used. - _generate_buildconfig_java = !defined(invoker.apk_under_test) + _generate_buildconfig_java = !defined(invoker.apk_under_test) && !_omit_dex if (defined(invoker.generate_buildconfig_java)) { _generate_buildconfig_java = invoker.generate_buildconfig_java } - _generate_productconfig_java = defined(invoker.product_config_java_packages) + _generate_productconfig_java = + defined(invoker.product_config_java_packages) && !_omit_dex # JNI generation usually goes hand-in-hand with buildconfig generation. _generate_final_jni = _generate_buildconfig_java @@ -2427,7 +2430,7 @@ _incremental_apk_path = "${_final_apk_path_no_ext}_incremental.apk" } - if (!_incremental_apk) { + if (!_incremental_apk && !_omit_dex) { # Bundle modules don't build the dex here, but need to write this path # to their .build_config.json file. if (_proguard_enabled) { @@ -2684,8 +2687,9 @@ } else { _generate_native_libraries_java = (!_is_bundle_module || _is_base_module) && - (_native_libs_deps != [] || _secondary_abi_native_libs_deps != []) && - !_uses_static_library_synchronized_proguard + (_native_libs_deps != [] || _secondary_abi_native_libs_deps != [] || + defined(invoker.static_library_provider)) && + !_uses_static_library_synchronized_proguard && !_omit_dex } if (_generate_native_libraries_java) { write_native_libraries_java("${_template_name}__native_libraries") { @@ -2694,7 +2698,17 @@ # Do not add a dep on the generated_file target in order to avoid having # to build the native libraries before this target. The dependency is # instead captured via a depfile. - if (_native_libs_deps != []) { + if (_uses_static_library) { + _prefix = get_label_info(invoker.static_library_provider, + "target_gen_dir") + "/" + + get_label_info(invoker.static_library_provider, "name") + if (defined(invoker.static_library_provider_use_secondary_abi) && + invoker.static_library_provider_use_secondary_abi) { + native_libraries_list_file = "${_prefix}.secondary_abi_native_libs" + } else { + native_libraries_list_file = "${_prefix}.native_libs" + } + } else if (_native_libs_deps != []) { native_libraries_list_file = _shared_library_list_file } else { native_libraries_list_file = _secondary_abi_shared_library_list_file @@ -2790,14 +2804,15 @@ ]) } - _java_target = "${_template_name}__java" - if (_is_bundle_module) { _add_view_trace_events = defined(invoker.add_view_trace_events) && invoker.add_view_trace_events && enable_trace_event_bytecode_rewriting } + # We cannot skip this target when omit_dex = true because it writes the + # build_config.json. + _java_target = "${_template_name}__java" java_library_impl(_java_target) { forward_variables_from(invoker, [ @@ -2929,7 +2944,7 @@ if (_uses_static_library_synchronized_proguard) { _final_dex_target_dep = "${invoker.static_library_provider}__dexsplitter" - } else if (_is_bundle_module && _proguard_enabled) { + } else if ((_is_bundle_module && _proguard_enabled) || _omit_dex) { _final_deps += [ ":$_java_target" ] } else if (_incremental_apk) { if (defined(invoker.enable_proguard_checks)) { @@ -3205,7 +3220,7 @@ deps = _deps + [ ":$_build_config_target" ] if ((!_proguard_enabled || _incremental_apk) && - enable_jdk_library_desugaring) { + enable_jdk_library_desugaring && !_omit_dex) { _all_jdk_libs = "//build/android:all_jdk_libs" deps += [ _all_jdk_libs ] jdk_libs_dex = get_label_info(_all_jdk_libs, "target_out_dir") + @@ -3485,6 +3500,7 @@ "expected_libs_and_assets_base", "generate_buildconfig_java", "generate_final_jni", + "generate_native_libraries_java", "include_size_info", "input_jars_paths", "use_modern_linker", @@ -3509,6 +3525,7 @@ "native_lib_placeholders", "never_incremental", "no_xml_namespaces", + "omit_dex", "png_to_webp", "post_process_package_resources_script", "processor_args_javac", @@ -3533,6 +3550,7 @@ "srcjar_deps", "static_library_dependent_targets", "static_library_provider", + "static_library_provider_use_secondary_abi", "static_library_synchronized_proguard", "target_sdk_version", "testonly", @@ -3632,6 +3650,7 @@ "load_library_from_apk", "loadable_modules", "product_config_java_packages", + "main_component_library", "manifest_package", "max_sdk_version", "min_sdk_version", @@ -3660,6 +3679,7 @@ "short_resource_paths", "srcjar_deps", "static_library_provider", + "static_library_provider_use_secondary_abi", "static_library_synchronized_proguard", "strip_resource_names", "strip_unused_resources",
diff --git a/build/config/fuchsia/test/minimum.shard.test-cml b/build/config/fuchsia/test/minimum.shard.test-cml index 31ffcaf..432b77ac 100644 --- a/build/config/fuchsia/test/minimum.shard.test-cml +++ b/build/config/fuchsia/test/minimum.shard.test-cml
@@ -64,6 +64,7 @@ }, { protocol: [ + "fuchsia.hwinfo.Product", "fuchsia.media.ProfileProvider", "fuchsia.process.Launcher", "fuchsia.sys.Loader",
diff --git a/build/config/fuchsia/test/minimum_capabilities.test-cmx b/build/config/fuchsia/test/minimum_capabilities.test-cmx index 09c26346..ed903be 100644 --- a/build/config/fuchsia/test/minimum_capabilities.test-cmx +++ b/build/config/fuchsia/test/minimum_capabilities.test-cmx
@@ -3,6 +3,11 @@ "fuchsia.test": { "injected-services": { "fuchsia.buildinfo.Provider": "fuchsia-pkg://fuchsia.com/build-info-service#meta/build-info.cmx", + "fuchsia.factory.MiscFactoryStoreProvider": [ + "fuchsia-pkg://fuchsia.com/fake_factory_store_providers#meta/misc.cmx", + "--config=/config/data/fuchsia.factory.MiscFactoryStoreProvider.config" + ], + "fuchsia.hwinfo.Product": "fuchsia-pkg://fuchsia.com/hwinfo#meta/hwinfo.cmx", "fuchsia.intl.PropertyProvider": "fuchsia-pkg://fuchsia.com/intl_property_manager#meta/intl_property_manager_v1.cmx" }, "system-services": [ @@ -19,6 +24,8 @@ ], "services": [ "fuchsia.buildinfo.Provider", + "fuchsia.factory.MiscFactoryStoreProvider", + "fuchsia.hwinfo.Product", "fuchsia.intl.PropertyProvider", "fuchsia.logger.LogSink", "fuchsia.media.ProfileProvider",
diff --git a/build/fuchsia/linux_internal.sdk.sha1 b/build/fuchsia/linux_internal.sdk.sha1 index 21ca36d..074f8b8 100644 --- a/build/fuchsia/linux_internal.sdk.sha1 +++ b/build/fuchsia/linux_internal.sdk.sha1
@@ -1 +1 @@ -8.20220525.4.1 +8.20220526.4.1
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index a19272e6..693b89f 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn
@@ -2925,12 +2925,6 @@ } } -# TODO(agrieve): Remove this once we switch to using bundle targets to -# generate APK stubs. -android_resources("trichrome_dummy_resources") { - sources = [ "trichrome/res_dummy/values/strings.xml" ] -} - chrome_public_unit_test_apk_manifest = "$root_gen_dir/chrome_public_unit_test_apk_manifest/AndroidManifest.xml" chrome_public_test_apk_manifest =
diff --git a/chrome/android/chrome_public_apk_tmpl.gni b/chrome/android/chrome_public_apk_tmpl.gni index 6fb71709..87220dc 100644 --- a/chrome/android/chrome_public_apk_tmpl.gni +++ b/chrome/android/chrome_public_apk_tmpl.gni
@@ -235,6 +235,19 @@ use_chromium_linker = chromium_linker_supported } + if (_is_trichrome) { + static_library_provider_use_secondary_abi = _is_secondary_abi_primary + + # http://crbug.com/1042107. + if (is_component_build) { + if (android_64bit_target_cpu && _is_64_bit_browser) { + main_component_library = "libmonochrome_64.cr.so" + } else { + main_component_library = "libmonochrome.cr.so" + } + } + } + if (!_is_monochrome && !_is_trichrome) { deps += [ "//chrome/android:chrome_public_v8_assets",
diff --git a/chrome/android/expectations/trichrome_library_apk.AndroidManifest.expected b/chrome/android/expectations/trichrome_library_apk.AndroidManifest.expected index fd2f714..cb6d641c 100644 --- a/chrome/android/expectations/trichrome_library_apk.AndroidManifest.expected +++ b/chrome/android/expectations/trichrome_library_apk.AndroidManifest.expected
@@ -10,6 +10,7 @@ <uses-sdk android:minSdkVersion="29" android:targetSdkVersion="31"/> <application android:extractNativeLibs="false" + android:hasCode="false" android:icon="@drawable/icon_webview" android:label="Trichrome Library" android:multiArch="true"
diff --git a/chrome/android/java/AndroidManifest_trichrome_library.xml b/chrome/android/java/AndroidManifest_trichrome_library.xml index 97e9ddd..070efc3 100644 --- a/chrome/android/java/AndroidManifest_trichrome_library.xml +++ b/chrome/android/java/AndroidManifest_trichrome_library.xml
@@ -18,6 +18,7 @@ <!-- TODO(torne): we should specify an icon, roundIcon, and label from resources. --> <application + android:hasCode="false" android:label="{{ application_label|default('Trichrome Library') }}" android:icon="@drawable/icon_webview" android:multiArch="true"
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/appmenu/AppMenuPropertiesDelegateImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/app/appmenu/AppMenuPropertiesDelegateImpl.java index 0cb36ee..ec145ccf 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/app/appmenu/AppMenuPropertiesDelegateImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/app/appmenu/AppMenuPropertiesDelegateImpl.java
@@ -299,6 +299,7 @@ private boolean isInTabSwitcher() { return mLayoutStateProvider != null && mLayoutStateProvider.isLayoutVisible(LayoutType.TAB_SWITCHER) + && !mLayoutStateProvider.isLayoutStartingToHide(LayoutType.TAB_SWITCHER) && !isInStartSurfaceHomepage(); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerImpl.java index 2ce5c4a8..c4902b05 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerImpl.java
@@ -1186,6 +1186,11 @@ } @Override + public boolean isLayoutStartingToHide(int layoutType) { + return isLayoutVisible(layoutType) && getActiveLayout().isStartingToHide(); + } + + @Override public void addObserver(LayoutStateObserver listener) { mLayoutObservers.addObserver(listener); }
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 46fed5e..c6f7979 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
@@ -609,6 +609,11 @@ } @Override + public boolean isPartialHeightCustomTab() { + return getInitialActivityHeight() > 0; + } + + @Override public boolean shouldAnimateOnFinish() { return mAnimationBundle != null && getClientPackageName() != null; }
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 9af423e..4e1a40e1 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
@@ -87,7 +87,7 @@ private final Activity mActivity; private final @Px int mInitialHeight; private final @Px int mMaxHeight; - private final @Px int mNavbarHeight; + private final @Px int mFullyExpandedAdjustmentHeight; private final Integer mNavigationBarColor; private final Integer mNavigationBarDividerColor; @@ -100,6 +100,9 @@ private @HeightStatus int mStatus = HeightStatus.INITIAL_HEIGHT; private @HeightStatus int mTargetStatus; + // Bottom navigation bar height. Set to zero when the bar is positioned on the right side + // in landcape mode. + private @Px int mNavbarHeight; private int mOrientation; private boolean mIsInMultiWindowMode; @@ -250,13 +253,17 @@ mActivity = activity; mParentViewSupplier = parentViewSupplier; mMaxHeight = getMaximumPossibleHeight(); - mNavbarHeight = getNavbarHeight(); // Needs mMaxHeight. mInitialHeight = MathUtils.clamp( initialHeight, mMaxHeight, (int) (mMaxHeight * MINIMAL_HEIGHT_RATIO)); + + // Invoked twice - when populated/destroyed(null) parentViewSupplier.addObserver(parentView -> { - // Invoked twice: populated(on init) -> null(on destruction) + // When the navigation bar on the right side (not at the bottom), no need to call + // the methods below since the contents height is fixed and the system navigation + // bar works as expected. + if (mNavbarHeight == 0) return; setContentsHeight(); - showNavbar(parentView != null); + updateNavbarVisibility(parentView != null); }); mOnResizedCallback = onResizedCallback; @@ -302,7 +309,6 @@ @Override public void onAnimationCancel(Animator animator) {} }; - mActivity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS); initializeHeight(); } @@ -314,7 +320,7 @@ .getInsets(WindowInsets.Type.navigationBars()) .bottom; } - return mMaxHeight - getAppUsableScreenHeight(); + return getDisplayHeight() - getAppUsableScreenHeight(); } private int getAppUsableScreenHeight() { @@ -358,6 +364,8 @@ if (newConfig.orientation != mOrientation) { mOrientation = newConfig.orientation; initializeHeight(); + setContentsHeight(); + updateNavbarVisibility(true); } } @@ -396,21 +404,24 @@ mActivity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL); mActivity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND); + mNavbarHeight = getNavbarHeight(); int maxHeight = getDisplayHeight(); int maxExpandedY = getFullyExpandedYCoordinate(); final @Px int height; + if (mOrientation == Configuration.ORIENTATION_LANDSCAPE) { - height = maxHeight - maxExpandedY; // Resizing by user dragging is not supported in landscape mode; no need to set // the status here. + height = maxHeight - maxExpandedY; + mActivity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS); } else { height = mInitialHeight; mStatus = HeightStatus.INITIAL_HEIGHT; + mActivity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS); } WindowManager.LayoutParams attributes = mActivity.getWindow().getAttributes(); - // TODO(ctzsm): Consider to handle rotation and resizing when entering/exiting multi-window - // mode. + // TODO(jinsukkim): Handle multi-window mode. if (attributes.height == height) return; // We do not resize Window but just translate its vertical offset, and resize the parent @@ -435,16 +446,19 @@ private void onMoveStart() { showSpinnerView(); - showNavbar(false); + updateNavbarVisibility(false); } private void onMoveEnd() { setContentsHeight(); + + // TODO(crbug.com/1328555): Look into observing a view resize event to ensure the fade + // animation can always cover the transition artifact. mSpinnerView.animate() .alpha(0f) .setDuration(SPINNER_FADE_DURATION_MS) .setListener(mSpinnerFadeoutAnimatorListener); - showNavbar(true); + updateNavbarVisibility(true); } private void showSpinnerView() { @@ -500,15 +514,17 @@ int windowPos = mActivity.getWindow().getAttributes().y; lp.height = getDisplayHeight() - windowPos - mHandleHeight - mNavbarHeight; parentView.setLayoutParams(lp); - if (oldHeight >= 0 && lp.height != oldHeight) { - mOnResizedCallback.onResized(lp.height); - } + if (oldHeight >= 0 && lp.height != oldHeight) mOnResizedCallback.onResized(lp.height); } // Show or hide our own navigation bar. - // TODO: Handle landscape mode where the 3-button navigation bar is located on a side, - // not at the bottom. - private void showNavbar(boolean show) { + private void updateNavbarVisibility(boolean show) { + // No need draw its own navigation bar when it is located on the right side since + // the system navigation bar is visible and can handle API #setNavigationBarColor. + if (mNavbarHeight == 0) { + if (mNavbar != null) mNavbar.setVisibility(View.GONE); + return; + } if (show) { if (mNavbar == null) { mNavbar = (LinearLayout) mActivity.getLayoutInflater().inflate( @@ -646,4 +662,9 @@ mSpinner = spinner; mToolbarView = toolbar; } + + @VisibleForTesting + int getNavbarHeightForTesting() { + return mNavbarHeight; + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/features/CustomTabNavigationBarController.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/features/CustomTabNavigationBarController.java index e53b429..63cc68e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/features/CustomTabNavigationBarController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/features/CustomTabNavigationBarController.java
@@ -33,10 +33,14 @@ Integer navigationBarDividerColor = intentDataProvider.getColorProvider().getNavigationBarDividerColor(); + // PCCT is deemed incapable of system dark button support due to the way it implements + // partial height (window coordinate translation). We do the darkening ourselves. + boolean supportsDarkButtons = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O + && !intentDataProvider.isPartialHeightCustomTab(); boolean needsDarkButtons = navigationBarColor != null && !ColorUtils.shouldUseLightForegroundOnBackground(navigationBarColor); - updateBarColor(window, navigationBarColor, needsDarkButtons); + updateBarColor(window, navigationBarColor, supportsDarkButtons, needsDarkButtons); // navigationBarDividerColor can only be set in Android P+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) return; @@ -49,12 +53,10 @@ /** * Sets the navigation bar color according to intent extras. */ - private static void updateBarColor( - Window window, Integer navigationBarColor, boolean needsDarkButtons) { + private static void updateBarColor(Window window, Integer navigationBarColor, + boolean supportsDarkButtons, boolean needsDarkButtons) { if (navigationBarColor == null) return; - boolean supportsDarkButtons = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O; - if (supportsDarkButtons) { UiUtils.setNavigationBarIconColor(window.getDecorView().getRootView(), needsDarkButtons);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActivity.java index a96ea1e..7b2518e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActivity.java
@@ -92,6 +92,8 @@ @Override protected LaunchCauseMetrics createLaunchCauseMetrics() { - return new WebappLaunchCauseMetrics(this, mWebappActivityCoordinator.getWebappInfo()); + return new WebappLaunchCauseMetrics(this, + mWebappActivityCoordinator == null ? null + : mWebappActivityCoordinator.getWebappInfo()); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappLaunchCauseMetrics.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappLaunchCauseMetrics.java index f5587ad..a29e5c4 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappLaunchCauseMetrics.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappLaunchCauseMetrics.java
@@ -6,6 +6,8 @@ import android.app.Activity; +import androidx.annotation.Nullable; + import org.chromium.chrome.browser.app.metrics.LaunchCauseMetrics; import org.chromium.chrome.browser.browserservices.intents.WebappInfo; import org.chromium.components.webapps.ShortcutSource; @@ -15,15 +17,17 @@ * LaunchCauseMetrics for WebappActivity. */ public class WebappLaunchCauseMetrics extends LaunchCauseMetrics { + @Nullable private WebappInfo mWebappInfo; - public WebappLaunchCauseMetrics(Activity activity, WebappInfo info) { + public WebappLaunchCauseMetrics(Activity activity, @Nullable WebappInfo info) { super(activity); mWebappInfo = info; } @Override public @LaunchCause int computeIntentLaunchCause() { + if (mWebappInfo == null) return LaunchCause.OTHER; if (mWebappInfo.isLaunchedFromHomescreen()) { if (mWebappInfo.isForWebApk()) { if (mWebappInfo.distributor() == WebApkDistributor.BROWSER) {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/RecentlyClosedBridgeTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/RecentlyClosedBridgeTest.java index 2e22e24..38d0601 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/RecentlyClosedBridgeTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/RecentlyClosedBridgeTest.java
@@ -4,6 +4,7 @@ package org.chromium.chrome.browser.ntp; +import androidx.test.filters.LargeTest; import androidx.test.filters.MediumTest; import org.junit.After; @@ -16,6 +17,7 @@ import org.chromium.base.test.util.Batch; import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.base.test.util.CriteriaHelper; import org.chromium.base.test.util.Restriction; import org.chromium.chrome.browser.ChromeTabbedActivity; import org.chromium.chrome.browser.flags.ChromeFeatureList; @@ -587,6 +589,104 @@ } /** + * Tests opening a specific closed group and that it persists across restarts. + */ + @Test + @LargeTest + @EnableFeatures({ChromeFeatureList.BULK_TAB_RESTORE, ChromeFeatureList.TAB_GROUPS_ANDROID}) + @Restriction({Restriction.RESTRICTION_TYPE_NON_LOW_END_DEVICE}) + public void testOpenRecentlyClosedEntry_Group_FromGroupClosure_WithRestart() { + if (mTabGroupModelFilter == null) return; + + // Tab order is inverted in RecentlyClosedEntry as most recent comes first so log data in + // reverse. + final String urls[] = + new String[] {getUrl(TEST_PAGE_C), getUrl(TEST_PAGE_B), getUrl(TEST_PAGE_A)}; + final Tab tabA = sActivityTestRule.loadUrlInNewTab(urls[2], /*incognito=*/false); + final Tab tabB = sActivityTestRule.loadUrlInNewTab(urls[1], /*incognito=*/false); + final Tab tabC = sActivityTestRule.loadUrlInNewTab(urls[0], /*incognito=*/false); + + final String[] titles = new String[3]; + TestThreadUtils.runOnUiThreadBlocking(() -> { + mTabGroupModelFilter.mergeTabsToGroup(tabB.getId(), tabA.getId()); + mTabGroupModelFilter.mergeTabsToGroup(tabC.getId(), tabA.getId()); + TabGroupTitleUtils.storeTabGroupTitle(tabA.getId(), "Bar"); + titles[2] = tabA.getTitle(); + titles[1] = tabB.getTitle(); + titles[0] = tabC.getTitle(); + mTabModel.closeMultipleTabs(Arrays.asList(new Tab[] {tabA, tabB, tabC}), false); + }); + + final List<RecentlyClosedEntry> recentEntries = new ArrayList<>(); + final int tabCount = getRecentEntriesAndReturnActiveTabCount(recentEntries); + Assert.assertEquals(1, tabCount); + Assert.assertEquals(1, recentEntries.size()); + assertEntryIs(recentEntries.get(0), RecentlyClosedGroup.class, new String[] {"Bar"}, titles, + urls); + + final RecentlyClosedGroup group = (RecentlyClosedGroup) recentEntries.get(0); + TestThreadUtils.runOnUiThreadBlocking( + () -> { mRecentlyClosedBridge.openRecentlyClosedEntry(mTabModel, group); }); + + // 1. Blank tab + // 2. tabA restored in new tab. + // 3. tabB restored in new tab. + // 4. tabC restored in new tab. + final List<Tab> tabs = getAllTabs(); + Assert.assertEquals(4, tabs.size()); + Assert.assertEquals(titles[2], ChromeTabUtils.getTitleOnUiThread(tabs.get(1))); + Assert.assertEquals(urls[2], ChromeTabUtils.getUrlOnUiThread(tabs.get(1)).getSpec()); + Assert.assertEquals(titles[1], ChromeTabUtils.getTitleOnUiThread(tabs.get(2))); + Assert.assertEquals(urls[1], ChromeTabUtils.getUrlOnUiThread(tabs.get(2)).getSpec()); + Assert.assertEquals(titles[0], ChromeTabUtils.getTitleOnUiThread(tabs.get(3))); + Assert.assertEquals(urls[0], ChromeTabUtils.getUrlOnUiThread(tabs.get(3)).getSpec()); + final int tabIds[] = + new int[] {tabs.get(1).getId(), tabs.get(2).getId(), tabs.get(3).getId()}; + TestThreadUtils.runOnUiThreadBlocking(() -> { + Assert.assertEquals("Bar", TabGroupTitleUtils.getTabGroupTitle(tabs.get(1).getId())); + Assert.assertTrue(mTabGroupModelFilter.hasOtherRelatedTabs(tabs.get(1))); + Assert.assertTrue(mTabGroupModelFilter.hasOtherRelatedTabs(tabs.get(2))); + Assert.assertTrue(mTabGroupModelFilter.hasOtherRelatedTabs(tabs.get(3))); + Assert.assertEquals(Arrays.asList(new Tab[] {tabs.get(1), tabs.get(2), tabs.get(3)}), + mTabGroupModelFilter.getRelatedTabList(tabs.get(1).getId())); + }); + + // Restart activity. + TestThreadUtils.runOnUiThreadBlocking(() -> { mActivity.saveState(); }); + sActivityTestRule.recreateActivity(); + mActivity = sActivityTestRule.getActivity(); + mTabModelSelector = mActivity.getTabModelSelectorSupplier().get(); + CriteriaHelper.pollUiThread(mTabModelSelector::isTabStateInitialized); + mTabModel = mTabModelSelector.getModel(false); + TabModelFilter filter = + mTabModelSelector.getTabModelFilterProvider().getTabModelFilter(false); + assert filter instanceof TabGroupModelFilter; + mTabGroupModelFilter = (TabGroupModelFilter) filter; + + // Confirm the same tabs are present with the same group structure. + tabs.clear(); + tabs.addAll(getAllTabs()); + Assert.assertEquals(4, tabs.size()); + Assert.assertEquals(tabIds[0], tabs.get(1).getId()); + Assert.assertEquals(titles[2], ChromeTabUtils.getTitleOnUiThread(tabs.get(1))); + Assert.assertEquals(urls[2], ChromeTabUtils.getUrlOnUiThread(tabs.get(1)).getSpec()); + Assert.assertEquals(tabIds[1], tabs.get(2).getId()); + Assert.assertEquals(titles[1], ChromeTabUtils.getTitleOnUiThread(tabs.get(2))); + Assert.assertEquals(urls[1], ChromeTabUtils.getUrlOnUiThread(tabs.get(2)).getSpec()); + Assert.assertEquals(tabIds[2], tabs.get(3).getId()); + Assert.assertEquals(titles[0], ChromeTabUtils.getTitleOnUiThread(tabs.get(3))); + Assert.assertEquals(urls[0], ChromeTabUtils.getUrlOnUiThread(tabs.get(3)).getSpec()); + TestThreadUtils.runOnUiThreadBlocking(() -> { + Assert.assertEquals("Bar", TabGroupTitleUtils.getTabGroupTitle(tabs.get(1).getId())); + Assert.assertTrue(mTabGroupModelFilter.hasOtherRelatedTabs(tabs.get(1))); + Assert.assertTrue(mTabGroupModelFilter.hasOtherRelatedTabs(tabs.get(2))); + Assert.assertTrue(mTabGroupModelFilter.hasOtherRelatedTabs(tabs.get(3))); + Assert.assertEquals(Arrays.asList(new Tab[] {tabs.get(1), tabs.get(2), tabs.get(3)}), + mTabGroupModelFilter.getRelatedTabList(tabs.get(1).getId())); + }); + } + + /** * Tests opening a specific closed {@link Tab} that was closed as part of a bulk closure. */ @Test
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappLaunchCauseMetricsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappLaunchCauseMetricsTest.java index fb29f2d..e76e466 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappLaunchCauseMetricsTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappLaunchCauseMetricsTest.java
@@ -121,4 +121,18 @@ ++count; Assert.assertEquals(count, histogramCountForValue(LaunchCause.EXTERNAL_VIEW_INTENT)); } + + @Test + @SmallTest + @UiThreadTest + public void testNullWebAppInfo() throws Throwable { + int count = histogramCountForValue(LaunchCause.OTHER); + + WebappLaunchCauseMetrics metrics = new WebappLaunchCauseMetrics(mActivity, null); + + metrics.onReceivedIntent(); + metrics.recordLaunchCause(); + ++count; + Assert.assertEquals(count, histogramCountForValue(LaunchCause.OTHER)); + } }
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 120cfe68..96a8c28 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
@@ -12,6 +12,7 @@ import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.anyObject; import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import static org.robolectric.Shadows.shadowOf; @@ -119,6 +120,7 @@ private List<WindowManager.LayoutParams> mAttributeResults; private DisplayMetrics mRealMetrics; + private Point mDisplaySize; private ObservableSupplierImpl<FrameLayout> mParentViewSupplier = new ObservableSupplierImpl<>(); private Callback<Integer> mBottomInsetCallback = inset -> {}; @@ -175,10 +177,14 @@ }) .when(mDisplay) .getRealMetrics(any(DisplayMetrics.class)); + + mDisplaySize = new Point(); + mDisplaySize.x = DEVICE_WIDTH; + mDisplaySize.y = DEVICE_HEIGHT - NAVBAR_HEIGHT; doAnswer(invocation -> { Point point = invocation.getArgument(0); - point.x = DEVICE_WIDTH; - point.y = DEVICE_HEIGHT - NAVBAR_HEIGHT; + point.x = mDisplaySize.x; + point.y = mDisplaySize.y; return null; }) .when(mDisplay) @@ -226,6 +232,8 @@ mConfiguration.orientation = Configuration.ORIENTATION_LANDSCAPE; mRealMetrics.widthPixels = DEVICE_HEIGHT; mRealMetrics.heightPixels = DEVICE_WIDTH; + mDisplaySize.x = DEVICE_HEIGHT - NAVBAR_HEIGHT; + mDisplaySize.y = DEVICE_WIDTH; new PartialCustomTabHeightStrategy(mActivity, mParentViewSupplier, 800, mMultiWindowModeStateDispatcher, null, null, mOnResizedCallback, mActivityLifecycleDispatcher); @@ -319,6 +327,7 @@ PartialCustomTabHeightStrategy strategy = new PartialCustomTabHeightStrategy(mActivity, mParentViewSupplier, 800, mMultiWindowModeStateDispatcher, null, null, mOnResizedCallback, mActivityLifecycleDispatcher); + strategy.setMockViewForTesting(mNavbar, mSpinnerView, mSpinner, mToolbarView); // Pass null because we have a mock Activity and we don't depend on the GestureDetector // inside as we test MotionEvents directly. @@ -335,6 +344,25 @@ } @Test + public void rotateToLandescapeHideCustomNavbar() { + PartialCustomTabHeightStrategy strategy = new PartialCustomTabHeightStrategy(mActivity, + mParentViewSupplier, 800, mMultiWindowModeStateDispatcher, null, null, + mOnResizedCallback, mActivityLifecycleDispatcher); + strategy.setMockViewForTesting(mNavbar, mSpinnerView, mSpinner, mToolbarView); + + mConfiguration.orientation = Configuration.ORIENTATION_LANDSCAPE; + mRealMetrics.widthPixels = DEVICE_HEIGHT; + mRealMetrics.heightPixels = DEVICE_WIDTH; + mDisplaySize.x = DEVICE_HEIGHT - NAVBAR_HEIGHT; + mDisplaySize.y = DEVICE_WIDTH; + + strategy.onConfigurationChanged(mConfiguration); + + assertEquals(0, strategy.getNavbarHeightForTesting()); + verify(mNavbar, times(1)).setVisibility(View.GONE); + } + + @Test public void enterMultiwindowModeUnresizable() { PartialCustomTabHeightStrategy strategy = new PartialCustomTabHeightStrategy(mActivity, mParentViewSupplier, 800, mMultiWindowModeStateDispatcher, null, null,
diff --git a/chrome/android/proguard/trichrome.flags b/chrome/android/proguard/trichrome.flags deleted file mode 100644 index 68fb39a..0000000 --- a/chrome/android/proguard/trichrome.flags +++ /dev/null
@@ -1,8 +0,0 @@ -# Copyright 2018 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -# TODO(agrieve): Once this -keep is removed, add a @CheckDiscard to LibraryLoaderConfig.java. -# Currently the Trichrome library just contains NativeLibraries, which we keep. -# https://crbug.com/901465 --keep class org.chromium.build.NativeLibraries { *; }
diff --git a/chrome/android/trichrome.gni b/chrome/android/trichrome.gni index 01b7f0b..1e2eec7 100644 --- a/chrome/android/trichrome.gni +++ b/chrome/android/trichrome.gni
@@ -114,7 +114,7 @@ product_version_resources_dep = "//chrome/android:product_version_resources" } else { - generate_buildconfig_java = false + omit_dex = true } # TODO(torne): using icon_resources just to get a temporary icon @@ -194,37 +194,6 @@ } } } - - # http://crbug.com/1042107. - if (is_component_build) { - if (android_64bit_target_cpu && invoker.is_64_bit_browser) { - main_component_library = "libmonochrome_64.cr.so" - } else { - main_component_library = "libmonochrome.cr.so" - } - } - - if (!is_java_debug) { - proguard_enabled = true - proguard_configs = [ - "//base/android/proguard/chromium_apk.flags", - "//base/android/proguard/chromium_code.flags", - "//chrome/android/proguard/trichrome.flags", - ] - if (trichrome_synchronized_proguard) { - proguard_configs += [ - "//chrome/android/proguard/static_library_dex_reference_workarounds.flags", - "//base/android/proguard/enable_obfuscation.flags", - ] - } else { - # Disabling all obfuscation for the Trichrome library as a temporary - # workaround for crbug.com/1012842. There were naming conflicts between - # Library and Chrome, since each Proguard run doesn't know about the - # other, and thus handed out the first names (a, b, c) to both. - proguard_enable_obfuscation = false - } - } - deps += [ "//chrome/android:trichrome_dummy_resources" ] } }
diff --git a/chrome/android/trichrome/res_dummy/values/strings.xml b/chrome/android/trichrome/res_dummy/values/strings.xml deleted file mode 100644 index a0d71c24..0000000 --- a/chrome/android/trichrome/res_dummy/values/strings.xml +++ /dev/null
@@ -1,9 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright 2019 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. --> - -<!-- DO NOT ADD MORE RESOURCES HERE --> -<resources> - <string name="dummy"></string> -</resources> \ No newline at end of file
diff --git a/chrome/android/trichrome/static_library_shared_java_code.md b/chrome/android/trichrome/static_library_shared_java_code.md deleted file mode 100644 index a288902..0000000 --- a/chrome/android/trichrome/static_library_shared_java_code.md +++ /dev/null
@@ -1,100 +0,0 @@ -# Static Library Java code - -[TOC] - -## Overview - -This document describes how static library targets can be used to share common -Java code between multiple APKs. More detail can be found at -[go/proguarding-trichrome](goto.google.com/proguarding-trichrome). - -## TrichromeLibrary - -Currently (Jan 2020) trichrome library is the only target to make use of static -shared library APKs and is used to share common code used by both Chrome and -Webview. - -## Status - -Java code sharing is mostly implemented at this point but there is one remaining -blocker related to how -[native method resolution works in Webview](crbug.com/1025009). - -## How it works - -### Build variables - -For `android_apk_or_module` base templates: - -`static_library_provider`: Specifies that this target depends on a static shared -library APK. When synchronized proguard is turned on, the -`static_library_provider` becomes the target that provides the final dex file. - -`static_library_dependent_targets`: If set, generates final dex files for -itself and for all targets in the `static_library_dependent_targets` list. - -`static_library_synchronized_proguard`: Turns on synchronized proguard for -targets that also set `static_library_provider`. - -### .build_config - -`write_build_config.py` is responsible for figuring out where code and related -artifacts for the `static_library_provider` and -`static_library_dependent_targets` belongs. The main difference from regular -`.build_configs` is the mapping recording which input jars belong to each final -dex file. Ex: - -``` -"deps_info": { - ... - "static_library_dependent_classpath_configs": { - "gen/android_webview/trichrome_webview_apk.build_config.json": [ - "obj/android_webview/trichrome_webview_apk/trichrome_webview_apk.jar", - ... - ], - "gen/chrome/android/trichrome_chrome_bundle.build_config.json": [ - "lib.java/chrome/android/app_hooks_java.jar", - ... - "gen/chrome/android/trichrome_library_apk.build_config.json": [ - "lib.java/base/base_java.jar", - ... - ] - ... - } -} -``` - -### Synchronized ProGuard - -TrichromeChromeBundle (base module) and TrichromeWebview do not have a final -`dex` or `proguard` step. Instead the library APK creates a "fat" dex from the -`.build_config.json:deps_info:java_runtime_classpath`. - -Then, the mapping of `.build_config.json` -> owned input jars stored in the -`.build_config.json` is used by `dexsplitter` to generate final .dex files for -TrichromeLibrary, TrichromeChrome, and TrichromeWebview. - -### Resources - -For Java code to be shared between Chrome and Webview in [Trichrome][trichrome], -we ensure that Chrome and Webview use the same resource IDs. This requires a -few adjustments to how resources are created. - -1. Webview's resources are compiled first without any changes. -2. Chrome's resources are compiled second, but use the same resource IDs as - Webview when possible. -3. When synchronized proguarding is turned on, the `R.java` files generated in - the previous step are discarded. The shared static library APK target - (trichrome library) takes the output `R.txt` files from the previous steps - and includes those resources in its own `R.java` generation. - -[trichrome]: /chrome/android/trichrome/static_library_shared_java_code.md - -### Usage - -* Building trichrome_chrome_bundle or trichrome_webview_apk (and various arch - variants) will ensure the correct library target is also built. -* Using the generated wrapper script from the main APK is sufficient (no need - to explicitly install the library). - * `bin/trichrome_chrome_bundle run` will ensure TrichromeChromeBundle and - TrichromeLibrary are installed before launching Chrome.
diff --git a/chrome/app/chrome.cml b/chrome/app/chrome.cml index 7d2b289..dcf1ced8 100644 --- a/chrome/app/chrome.cml +++ b/chrome/app/chrome.cml
@@ -55,6 +55,7 @@ "fuchsia.device.NameProvider", "fuchsia.element.GraphicalPresenter", "fuchsia.fonts.Provider", + "fuchsia.hwinfo.Product", "fuchsia.input.virtualkeyboard.ControllerCreator", "fuchsia.intl.PropertyProvider", "fuchsia.media.Audio",
diff --git a/chrome/app/chrome_v1.cmx b/chrome/app/chrome_v1.cmx index a45fa78..cd376be 100644 --- a/chrome/app/chrome_v1.cmx +++ b/chrome/app/chrome_v1.cmx
@@ -18,6 +18,7 @@ "fuchsia.device.NameProvider", "fuchsia.element.GraphicalPresenter", "fuchsia.fonts.Provider", + "fuchsia.hwinfo.Product", "fuchsia.input.virtualkeyboard.ControllerCreator", "fuchsia.intl.PropertyProvider", "fuchsia.logger.LogSink",
diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp index a85481e..1bebb23d1 100644 --- a/chrome/app/chromeos_strings.grdp +++ b/chrome/app/chromeos_strings.grdp
@@ -5071,7 +5071,7 @@ <!-- Strings for EcheApp --> <message name="IDS_ECHE_APP_SCREEN_LOCK_SETTINGS_BUTTON" desc="Label for the button in the screen lock notification of EcheApp to open the settings app."> - Open Settings + Settings </message> <message name="IDS_ECHE_APP_SCREEN_LOCK_LEARN_MORE" desc="Learn more link text in screen lock notification of EcheApp."> Learn more @@ -5083,10 +5083,10 @@ Learn more </message> <message name="IDS_ECHE_APP_SCREEN_LOCK_NOTIFICATION_TITLE" desc="Title for notification shown when screen lock is not enabled while using app stream of EcheApp."> - Can't open app + Can't open <ph name="APP_NAME">$1<ex>the app</ex></ph> </message> <message name="IDS_ECHE_APP_SCREEN_LOCK_NOTIFICATION_MESSAGE" desc="Message for the notification shown when screen lock is not enabled while using app stream of EcheApp."> - To open <ph name="APP_NAME">$1<ex>the app</ex></ph>, enable "Show lock screen when waking from sleep" + Turn on "Show lock screen when waking from sleep" and try again </message> <message name="IDS_ECHE_APP_NOTIFICATION_OPEN_AGAIN_BUTTON" desc="Label for the inactivity notification button of EcheApp to open open."> Open again
diff --git a/chrome/app/chromeos_strings_grdp/IDS_ECHE_APP_SCREEN_LOCK_NOTIFICATION_MESSAGE.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_ECHE_APP_SCREEN_LOCK_NOTIFICATION_MESSAGE.png.sha1 index 33e553e..9f91339a 100644 --- a/chrome/app/chromeos_strings_grdp/IDS_ECHE_APP_SCREEN_LOCK_NOTIFICATION_MESSAGE.png.sha1 +++ b/chrome/app/chromeos_strings_grdp/IDS_ECHE_APP_SCREEN_LOCK_NOTIFICATION_MESSAGE.png.sha1
@@ -1 +1 @@ -680ae77ac0feb1ff37f4aa80877bea62a049a96b \ No newline at end of file +0b22106158ee9d776742fee4c189b3f24fa4a292 \ No newline at end of file
diff --git a/chrome/app/chromeos_strings_grdp/IDS_ECHE_APP_SCREEN_LOCK_NOTIFICATION_TITLE.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_ECHE_APP_SCREEN_LOCK_NOTIFICATION_TITLE.png.sha1 index 33e553e..9f91339a 100644 --- a/chrome/app/chromeos_strings_grdp/IDS_ECHE_APP_SCREEN_LOCK_NOTIFICATION_TITLE.png.sha1 +++ b/chrome/app/chromeos_strings_grdp/IDS_ECHE_APP_SCREEN_LOCK_NOTIFICATION_TITLE.png.sha1
@@ -1 +1 @@ -680ae77ac0feb1ff37f4aa80877bea62a049a96b \ No newline at end of file +0b22106158ee9d776742fee4c189b3f24fa4a292 \ No newline at end of file
diff --git a/chrome/app/chromeos_strings_grdp/IDS_ECHE_APP_SCREEN_LOCK_SETTINGS_BUTTON.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_ECHE_APP_SCREEN_LOCK_SETTINGS_BUTTON.png.sha1 index f7fc0077..9f91339a 100644 --- a/chrome/app/chromeos_strings_grdp/IDS_ECHE_APP_SCREEN_LOCK_SETTINGS_BUTTON.png.sha1 +++ b/chrome/app/chromeos_strings_grdp/IDS_ECHE_APP_SCREEN_LOCK_SETTINGS_BUTTON.png.sha1
@@ -1 +1 @@ -bf284f3dc923008482ba763eb9d056f1ab69f8e9 \ No newline at end of file +0b22106158ee9d776742fee4c189b3f24fa4a292 \ No newline at end of file
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index d4e71c2..4152141a7b 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -207,6 +207,7 @@ #endif #if BUILDFLAG(IS_CHROMEOS) +#include "base/process/process.h" #include "chrome/browser/apps/intent_helper/intent_picker_features.h" #include "chromeos/constants/chromeos_features.h" #endif @@ -3513,6 +3514,10 @@ {"adaptive-charging", flag_descriptions::kAdaptiveChargingName, flag_descriptions::kAdaptiveChargingDescription, kOsCrOS, FEATURE_VALUE_TYPE(ash::features::kAdaptiveCharging)}, + {"adaptive-charging-for-testing", + flag_descriptions::kAdaptiveChargingForTestingName, + flag_descriptions::kAdaptiveChargingForTestingDescription, kOsCrOS, + FEATURE_VALUE_TYPE(ash::features::kAdaptiveChargingForTesting)}, {"allow-poly-device-pairing", flag_descriptions::kAllowPolyDevicePairingName, flag_descriptions::kAllowPolyDevicePairingDescription, kOsCrOS, @@ -3590,10 +3595,6 @@ kOsCrOS, FEATURE_VALUE_TYPE( chromeos::features::kDisableIdleSocketsCloseOnMemoryPressure)}, - {"disable-office-editing-component-app", - flag_descriptions::kDisableOfficeEditingComponentAppName, - flag_descriptions::kDisableOfficeEditingComponentAppDescription, kOsCrOS, - FEATURE_VALUE_TYPE(chromeos::features::kDisableOfficeEditingComponentApp)}, {"oobe-hid-detection-revamp", flag_descriptions::kOobeHidDetectionRevampName, flag_descriptions::kOobeHidDetectionRevampDescription, kOsCrOS, @@ -3778,10 +3779,18 @@ flag_descriptions::kDeprecateLowUsageCodecsName, flag_descriptions::kDeprecateLowUsageCodecsDescription, kOsCrOS | kOsLacros, FEATURE_VALUE_TYPE(media::kDeprecateLowUsageCodecs)}, + {"disable-office-editing-component-app", + flag_descriptions::kDisableOfficeEditingComponentAppName, + flag_descriptions::kDisableOfficeEditingComponentAppDescription, + kOsCrOS | kOsLacros, + FEATURE_VALUE_TYPE(chromeos::features::kDisableOfficeEditingComponentApp)}, {"enable-tts-lacros-support", flag_descriptions::kEnableTtsLacrosSupportName, flag_descriptions::kEnableTtsLacrosSupportDescription, kOsCrOS | kOsLacros, FEATURE_VALUE_TYPE(chromeos::kLacrosTtsSupport)}, + {"one-group-per-renderer", flag_descriptions::kOneGroupPerRendererName, + flag_descriptions::kOneGroupPerRendererDescription, kOsCrOS | kOsLacros, + FEATURE_VALUE_TYPE(base::kOneGroupPerRenderer)}, #endif // BUILDFLAG(IS_CHROMEOS) #if BUILDFLAG(IS_LINUX) @@ -4868,11 +4877,6 @@ {"arc-native-bridge-toggle", flag_descriptions::kArcNativeBridgeToggleName, flag_descriptions::kArcNativeBridgeToggleDescription, kOsCrOS, FEATURE_VALUE_TYPE(arc::kNativeBridgeToggleFeature)}, - {"arc-native-bridge-64bit-support-experiment", - flag_descriptions::kArcNativeBridge64BitSupportExperimentName, - flag_descriptions::kArcNativeBridge64BitSupportExperimentDescription, - kOsCrOS, - FEATURE_VALUE_TYPE(arc::kNativeBridge64BitSupportExperimentFeature)}, {"arc-right-click-long-press", flag_descriptions::kArcRightClickLongPressName, flag_descriptions::kArcRightClickLongPressDescription, kOsCrOS,
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 2fdcc6b..9e4f0b7c 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
@@ -460,6 +460,13 @@ } /** + * @return Whether the intent is for partial-height custom tabs. + */ + public boolean isPartialHeightCustomTab() { + return false; + } + + /** * @return The value in pixels of the initial height of the Activity. It will return 0 if there * is no value set. */
diff --git a/chrome/browser/android/usb/web_usb_chooser_android.cc b/chrome/browser/android/usb/web_usb_chooser_android.cc index d8889670..21a5ccb 100644 --- a/chrome/browser/android/usb/web_usb_chooser_android.cc +++ b/chrome/browser/android/usb/web_usb_chooser_android.cc
@@ -10,16 +10,15 @@ #include "chrome/browser/ui/android/device_dialog/usb_chooser_dialog_android.h" #include "chrome/browser/usb/usb_chooser_controller.h" -WebUsbChooserAndroid::WebUsbChooserAndroid( - content::RenderFrameHost* render_frame_host) - : WebUsbChooser(render_frame_host) {} +WebUsbChooserAndroid::WebUsbChooserAndroid() = default; -WebUsbChooserAndroid::~WebUsbChooserAndroid() {} +WebUsbChooserAndroid::~WebUsbChooserAndroid() = default; void WebUsbChooserAndroid::ShowChooser( + content::RenderFrameHost* render_frame_host, std::unique_ptr<UsbChooserController> controller) { dialog_ = UsbChooserDialogAndroid::Create( - render_frame_host(), std::move(controller), + render_frame_host, std::move(controller), base::BindOnce(&WebUsbChooserAndroid::OnDialogClosed, base::Unretained(this))); } @@ -27,7 +26,3 @@ void WebUsbChooserAndroid::OnDialogClosed() { dialog_.reset(); } - -base::WeakPtr<WebUsbChooser> WebUsbChooserAndroid::GetWeakPtr() { - return weak_factory_.GetWeakPtr(); -}
diff --git a/chrome/browser/android/usb/web_usb_chooser_android.h b/chrome/browser/android/usb/web_usb_chooser_android.h index 55bd972..0e5b993 100644 --- a/chrome/browser/android/usb/web_usb_chooser_android.h +++ b/chrome/browser/android/usb/web_usb_chooser_android.h
@@ -6,7 +6,6 @@ #define CHROME_BROWSER_ANDROID_USB_WEB_USB_CHOOSER_ANDROID_H_ #include <memory> -#include <vector> #include "chrome/browser/usb/web_usb_chooser.h" @@ -18,7 +17,7 @@ // to access a certain device. class WebUsbChooserAndroid : public WebUsbChooser { public: - explicit WebUsbChooserAndroid(content::RenderFrameHost* render_frame_host); + WebUsbChooserAndroid(); WebUsbChooserAndroid(const WebUsbChooserAndroid&) = delete; WebUsbChooserAndroid& operator=(const WebUsbChooserAndroid&) = delete; @@ -26,16 +25,13 @@ ~WebUsbChooserAndroid() override; // WebUsbChooser implementation - void ShowChooser(std::unique_ptr<UsbChooserController> controller) override; - base::WeakPtr<WebUsbChooser> GetWeakPtr() override; + void ShowChooser(content::RenderFrameHost* render_frame_host, + std::unique_ptr<UsbChooserController> controller) override; private: void OnDialogClosed(); - // Only a single dialog can be shown at a time. std::unique_ptr<UsbChooserDialogAndroid> dialog_; - - base::WeakPtrFactory<WebUsbChooserAndroid> weak_factory_{this}; }; #endif // CHROME_BROWSER_ANDROID_USB_WEB_USB_CHOOSER_ANDROID_H_
diff --git a/chrome/browser/ash/BUILD.gn b/chrome/browser/ash/BUILD.gn index fc7b422..a98a0f5 100644 --- a/chrome/browser/ash/BUILD.gn +++ b/chrome/browser/ash/BUILD.gn
@@ -348,8 +348,6 @@ "arc/input_overlay/ui/action_edit_menu.h", "arc/input_overlay/ui/action_label.cc", "arc/input_overlay/ui/action_label.h", - "arc/input_overlay/ui/action_tag.cc", - "arc/input_overlay/ui/action_tag.h", "arc/input_overlay/ui/action_view.cc", "arc/input_overlay/ui/action_view.h", "arc/input_overlay/ui/edit_mode_exit_view.cc",
diff --git a/chrome/browser/ash/accessibility/dictation_browsertest.cc b/chrome/browser/ash/accessibility/dictation_browsertest.cc index fd6635c..1662fb5 100644 --- a/chrome/browser/ash/accessibility/dictation_browsertest.cc +++ b/chrome/browser/ash/accessibility/dictation_browsertest.cc
@@ -44,6 +44,7 @@ #include "content/public/test/browser_test.h" #include "content/public/test/browser_test_utils.h" #include "content/public/test/fake_speech_recognition_manager.h" +#include "extensions/browser/browsertest_util.h" #include "extensions/browser/extension_host_test_helper.h" #include "media/mojo/mojom/speech_recognition_service.mojom.h" #include "third_party/abseil-cpp/absl/types/optional.h" @@ -318,7 +319,13 @@ } // Routers to SpeechRecognitionTestHelper methods. - void WaitForRecognitionStarted() { test_helper_.WaitForRecognitionStarted(); } + void WaitForRecognitionStarted() { + test_helper_.WaitForRecognitionStarted(); + // Dictation intializes FocusHandler when speech recognition starts. + // Several tests require FocusHandler logic, so wait for it to initialize + // before proceeding. + WaitForFocusHandler(); + } void WaitForRecognitionStopped() { test_helper_.WaitForRecognitionStopped(); } @@ -390,6 +397,29 @@ .Wait(); } + void WaitForFocusHandler() { + std::string error_message = "Still waiting for FocusHandler"; + std::string script = R"( + if (accessibilityCommon.dictation_.focusHandler_.isReadyForTesting()) { + window.domAutomationController.send("ready"); + } else { + window.domAutomationController.send("not ready"); + } + )"; + SuccessWaiter( + base::BindLambdaForTesting([&]() { + std::string result = + extensions::browsertest_util::ExecuteScriptInBackgroundPage( + /*context=*/browser()->profile(), + /*extension_id=*/ + extension_misc::kAccessibilityCommonExtensionId, + /*script=*/script); + return result == "ready"; + }), + error_message) + .Wait(); + } + void ToggleDictationWithKeystroke() { ASSERT_NO_FATAL_FAILURE(ASSERT_TRUE(ui_test_utils::SendKeyPressToWindowSync( nullptr, ui::KeyboardCode::VKEY_D, false, false, false, true)));
diff --git a/chrome/browser/ash/accessibility/speech_monitor.cc b/chrome/browser/ash/accessibility/speech_monitor.cc index afb0130..8f679fd9 100644 --- a/chrome/browser/ash/accessibility/speech_monitor.cc +++ b/chrome/browser/ash/accessibility/speech_monitor.cc
@@ -103,6 +103,8 @@ void SpeechMonitor::FinalizeVoiceOrdering( std::vector<content::VoiceData>& voices) {} +void SpeechMonitor::RefreshVoices() {} + double SpeechMonitor::CalculateUtteranceDelayMS() { std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now(); std::chrono::duration<double> time_span =
diff --git a/chrome/browser/ash/accessibility/speech_monitor.h b/chrome/browser/ash/accessibility/speech_monitor.h index d3155a4..c7f916c 100644 --- a/chrome/browser/ash/accessibility/speech_monitor.h +++ b/chrome/browser/ash/accessibility/speech_monitor.h
@@ -102,6 +102,7 @@ void SetError(const std::string& error) override; void Shutdown() override; void FinalizeVoiceOrdering(std::vector<content::VoiceData>& voices) override; + void RefreshVoices() override; void MaybeContinueReplay(); void MaybePrintExpectations();
diff --git a/chrome/browser/ash/arc/input_overlay/actions/action.cc b/chrome/browser/ash/arc/input_overlay/actions/action.cc index 609b16b..4d5c609 100644 --- a/chrome/browser/ash/arc/input_overlay/actions/action.cc +++ b/chrome/browser/ash/arc/input_overlay/actions/action.cc
@@ -214,8 +214,7 @@ return (input_element.input_sources() & InputSource::IS_MOUSE) != 0; } -void Action::PrepareToBind(std::unique_ptr<InputElement> input_element, - DisplayMode mode) { +void Action::PrepareToBind(std::unique_ptr<InputElement> input_element) { if (pending_binding_) pending_binding_.reset(); pending_binding_ = std::move(input_element); @@ -224,7 +223,6 @@ if (!action_view_) return; action_view_->SetViewContent(BindingOption::kPending, bounds); - action_view_->SetDisplayMode(mode); } void Action::BindPending() { @@ -248,12 +246,17 @@ void Action::RestoreToDefault(const gfx::RectF& content_bounds) { DCHECK(action_view_); - if (!action_view_ || GetCurrentDisplayedBinding() == *original_binding_) + if (!action_view_) return; - pending_binding_.reset(); - pending_binding_ = std::make_unique<InputElement>(*original_binding_); - action_view_->SetViewContent(BindingOption::kPending, content_bounds); - action_view_->SetDisplayMode(DisplayMode::kEdited); + + if (GetCurrentDisplayedBinding() != *original_binding_) { + pending_binding_.reset(); + pending_binding_ = std::make_unique<InputElement>(*original_binding_); + action_view_->SetViewContent(BindingOption::kPending, content_bounds); + } + // Set to |DisplayMode::kRestore| to clear the focus even the current binding + // is same as original binding. + action_view_->SetDisplayMode(DisplayMode::kRestore); } const InputElement& Action::GetCurrentDisplayedBinding() { @@ -365,7 +368,12 @@ return; auto bounds = CalculateWindowContentBounds(target_window_); action_view_->SetViewContent(BindingOption::kPending, bounds); - action_view_->SetDisplayMode(DisplayMode::kEditedUnbound); + const int label_index = action_view_->unbind_label_index(); + action_view_->SetDisplayMode(DisplayMode::kEditedUnbound, + (label_index == kDefaultLabelIndex + ? nullptr + : action_view_->labels()[label_index])); + action_view_->set_unbind_label_index(kDefaultLabelIndex); } std::unique_ptr<ActionProto> Action::ConvertToProtoIfCustomized() {
diff --git a/chrome/browser/ash/arc/input_overlay/actions/action.h b/chrome/browser/ash/arc/input_overlay/actions/action.h index 2811face..efa6ed1e 100644 --- a/chrome/browser/ash/arc/input_overlay/actions/action.h +++ b/chrome/browser/ash/arc/input_overlay/actions/action.h
@@ -88,8 +88,7 @@ // This is called for editing the actions before change is saved. Or for // loading the customized data to override the default input mapping. - void PrepareToBind(std::unique_ptr<InputElement> input_element, - DisplayMode mode = DisplayMode::kEdit); + void PrepareToBind(std::unique_ptr<InputElement> input_element); // Save |pending_binding_| as |current_binding_|. void BindPending(); // Cancel |pending_binding_|.
diff --git a/chrome/browser/ash/arc/input_overlay/actions/action_move.cc b/chrome/browser/ash/arc/input_overlay/actions/action_move.cc index b5486ba5..b0238e9 100644 --- a/chrome/browser/ash/arc/input_overlay/actions/action_move.cc +++ b/chrome/browser/ash/arc/input_overlay/actions/action_move.cc
@@ -7,7 +7,7 @@ #include "base/strings/utf_string_conversions.h" #include "chrome/browser/ash/arc/input_overlay/actions/action.h" #include "chrome/browser/ash/arc/input_overlay/touch_id_manager.h" -#include "chrome/browser/ash/arc/input_overlay/ui/action_tag.h" +#include "chrome/browser/ash/arc/input_overlay/ui/action_label.h" #include "ui/events/keycodes/dom/dom_code.h" #include "ui/events/keycodes/dom/keycode_converter.h" #include "ui/gfx/geometry/point.h" @@ -31,7 +31,7 @@ {1, 0}}; // UI specs. // Offset by label center. -constexpr int kTagOffset = 49; +constexpr int kLabelOffset = 49; std::unique_ptr<Position> ParseApplyAreaPosition(const base::Value& value, base::StringPiece key) { @@ -66,22 +66,33 @@ // TODO(cuicuiruan): rewrite for post MVP once design is ready. void SetViewContent(BindingOption binding_option, const gfx::RectF& content_bounds) override { - auto tag = ActionTag::CreateTextActionTag(kMouseCursorLock); - auto tag_size = tag->GetPreferredSize(); - tag->SetSize(tag_size); - SetSize(tag_size); - center_.set_x(tag_size.width() / 2); - center_.set_y(tag_size.height() / 2); - tags_.emplace_back(AddChildView(std::move(tag))); + auto label = ActionLabel::CreateTextActionLabel(kMouseCursorLock); + labels_.emplace_back(AddChildView(std::move(label))); } // TODO(cuicuiruan): rewrite for post MVP once design is ready. - void OnKeyBindingChange(ActionTag* action_tag, ui::DomCode code) override { + void OnKeyBindingChange(ActionLabel* action_label, + ui::DomCode code) override { NOTIMPLEMENTED(); } void OnBindingToKeyboard() override { NOTIMPLEMENTED(); } void OnBindingToMouse(std::string mouse_action) override { NOTIMPLEMENTED(); } void OnMenuEntryPressed() override { NOTIMPLEMENTED(); } + + void ChildPreferredSizeChanged(View* child) override { + if (static_cast<ActionLabel*>(child) != labels_[0]) + return; + + auto label_size = labels_[0]->CalculatePreferredSize(); + labels_[0]->SetSize(label_size); + labels_[0]->SetPosition(gfx::Point()); + center_.set_x(label_size.width() / 2); + center_.set_y(label_size.height() / 2); + SetSize(label_size); + auto center_pos = action_->GetUICenterPosition( + CalculateWindowContentBounds(action_->target_window())); + SetPositionFromCenterPosition(center_pos); + } }; class ActionMove::ActionMoveKeyView : public ActionView { @@ -103,8 +114,7 @@ std::max(kActionMoveMinRadius, action_->GetUIRadius(content_bounds)); auto* action_move = static_cast<ActionMove*>(action_); action_move->set_move_distance(radius / 2); - SetSize(gfx::Size(radius * 2, radius * 2)); - if (!circle_) { + if (show_circle() && !circle_) { auto circle = std::make_unique<ActionCircle>(radius); circle_ = AddChildView(std::move(circle)); } @@ -130,51 +140,45 @@ return; auto keys = binding->keys(); - if (tags_.empty()) { + if (labels_.empty()) { for (int i = 0; i < keys.size(); i++) { - auto tag = ActionTag::CreateTextActionTag(GetDisplayText(keys[i])); - auto tag_size = tag->GetPreferredSize(); - tag->SetSize(tag_size); - int x = kDirection[i][0]; - int y = kDirection[i][1]; - auto pos = gfx::Point( - radius + x * (radius - kTagOffset) - tag_size.width() / 2, - radius + y * (radius - kTagOffset) - tag_size.height() / 2); - tag->SetPosition(pos); - tags_.emplace_back(AddChildView(std::move(tag))); + auto label = + ActionLabel::CreateTextActionLabel(GetDisplayText(keys[i])); + labels_.emplace_back(AddChildView(std::move(label))); } } else { - DCHECK(tags_.size() == keys.size()); + DCHECK(labels_.size() == keys.size()); for (int i = 0; i < keys.size(); i++) - tags_[i]->SetTextActionTag(std::move(GetDisplayText(keys[i]))); + labels_[i]->SetTextActionLabel(std::move(GetDisplayText(keys[i]))); } } - void OnKeyBindingChange(ActionTag* action_tag, ui::DomCode code) override { - DCHECK(tags_.size() == kActionMoveKeysSize); - if (tags_.size() != kActionMoveKeysSize) + void OnKeyBindingChange(ActionLabel* action_label, + ui::DomCode code) override { + DCHECK(labels_.size() == kActionMoveKeysSize); + if (labels_.size() != kActionMoveKeysSize) return; - auto it = std::find(tags_.begin(), tags_.end(), action_tag); - DCHECK(it != tags_.end()); - if (it == tags_.end()) + auto it = std::find(labels_.begin(), labels_.end(), action_label); + DCHECK(it != labels_.end()); + if (it == labels_.end()) return; - if (ShouldShowErrorMsg(code)) + if (ShouldShowErrorMsg(code, action_label)) return; auto& binding = action_->GetCurrentDisplayedBinding(); DCHECK(binding.keys().size() == kActionMoveKeysSize); - const int index = it - tags_.begin(); + const int index = it - labels_.begin(); std::vector<ui::DomCode> new_keys = binding.keys(); new_keys[index] = code; auto input_element = InputElement::CreateActionMoveKeyElement(new_keys); - display_overlay_controller_->OnBindingChange(action_, - std::move(input_element)); + ChangeBinding(action_, action_label, std::move(input_element)); } // TODO(cuicuiruan): Remove this for post MVP for editing |ActionMove|. - void SetDisplayMode(const DisplayMode mode) override { - ActionView::SetDisplayMode(mode); + void SetDisplayMode(const DisplayMode mode, + ActionLabel* editing_label = nullptr) override { + ActionView::SetDisplayMode(mode, editing_label); if (menu_entry_) menu_entry_->SetVisible(false); } @@ -183,6 +187,53 @@ void OnBindingToKeyboard() override { NOTIMPLEMENTED(); } void OnBindingToMouse(std::string mouse_action) override { NOTIMPLEMENTED(); } void OnMenuEntryPressed() override { NOTIMPLEMENTED(); } + + void ChildPreferredSizeChanged(View* child) override { + DCHECK(labels_.size() == kActionMoveKeysSize); + if (labels_.size() != kActionMoveKeysSize) + return; + + int label_index = -1; + auto* label = static_cast<ActionLabel*>(child); + for (int i = 0; i < kActionMoveKeysSize; i++) { + if (label == labels_[i]) { + label_index = i; + break; + } + } + if (label_index == -1) + return; + + auto content_bounds = + CalculateWindowContentBounds(action_->target_window()); + int radius = + std::max(kActionMoveMinRadius, action_->GetUIRadius(content_bounds)); + auto label_size = label->CalculatePreferredSize(); + label->SetSize(label_size); + int x = kDirection[label_index][0]; + int y = kDirection[label_index][1]; + auto pos = gfx::Point( + radius + x * (radius - kLabelOffset) - label_size.width() / 2, + radius + y * (radius - kLabelOffset) - label_size.height() / 2); + label->SetPosition(pos); + + // Calculate minimum size of the |ActionMoveKeyView|. + int left = INT_MAX, right = 0, top = INT_MAX, bottom = 0; + for (int i = 0; i < kActionMoveKeysSize; i++) { + left = std::min(left, labels_[i]->bounds().x()); + right = std::max(right, labels_[i]->bounds().right()); + top = std::min(top, labels_[i]->bounds().y()); + bottom = std::max(bottom, labels_[i]->bounds().bottom()); + } + DCHECK_LT(left, right); + DCHECK_LT(top, bottom); + + auto size = gfx::Size(radius * 2, radius * 2); + size.SetToMax(gfx::Size(right - left, bottom - top)); + SetSize(size); + auto center_pos = action_->GetUICenterPosition(content_bounds); + SetPositionFromCenterPosition(center_pos); + } }; ActionMove::ActionMove(aura::Window* window) : Action(window) {} @@ -342,8 +393,6 @@ } action_view_ = view.get(); view->set_editable(true); - auto center_pos = GetUICenterPosition(content_bounds); - view->SetPositionFromCenterPosition(center_pos); return view; } @@ -354,16 +403,18 @@ // It might be partially overlapped and only remove the keys overlapped. for (auto code : input_element.keys()) { for (int i = 0; i < pending_binding_->keys().size(); i++) { - if (code == pending_binding_->keys()[i]) + if (code == pending_binding_->keys()[i]) { pending_binding_->SetKey(i, ui::DomCode::NONE); + if (action_view_) + action_view_->set_unbind_label_index(i); + PostUnbindProcess(); + } } } } else { // TODO(cuicuiruan): Implement for unbinding mouse-bound action move. NOTIMPLEMENTED(); } - - PostUnbindProcess(); } bool ActionMove::RewriteKeyEvent(const ui::KeyEvent* key_event,
diff --git a/chrome/browser/ash/arc/input_overlay/actions/action_tap.cc b/chrome/browser/ash/arc/input_overlay/actions/action_tap.cc index 1ab0183..5e03e19 100644 --- a/chrome/browser/ash/arc/input_overlay/actions/action_tap.cc +++ b/chrome/browser/ash/arc/input_overlay/actions/action_tap.cc
@@ -8,7 +8,7 @@ #include "chrome/browser/ash/arc/input_overlay/actions/input_element.h" #include "chrome/browser/ash/arc/input_overlay/constants.h" #include "chrome/browser/ash/arc/input_overlay/touch_id_manager.h" -#include "chrome/browser/ash/arc/input_overlay/ui/action_tag.h" +#include "chrome/browser/ash/arc/input_overlay/ui/action_label.h" #include "ui/aura/window.h" #include "ui/events/base_event_utils.h" #include "ui/events/keycodes/dom/dom_code.h" @@ -20,26 +20,22 @@ namespace input_overlay { namespace { // UI specs. -constexpr int kTagPositionToSide = 36; -constexpr int kTagMargin = 2; +constexpr int kLabelPositionToSide = 36; +constexpr int kLabelMargin = 2; -// Create |ActionTag| for |ActionTap|. -std::unique_ptr<ActionTag> CreateActionTag(InputElement& input_element) { - std::unique_ptr<ActionTag> tag; +// Create |ActionLabel| for |ActionTap|. +std::unique_ptr<ActionLabel> CreateActionLabel(InputElement& input_element) { + std::unique_ptr<ActionLabel> label; if (IsKeyboardBound(input_element)) { DCHECK(input_element.keys().size() == 1); - tag = - ActionTag::CreateTextActionTag(GetDisplayText(input_element.keys()[0])); - tag->SetSize(tag->GetPreferredSize()); + label = ActionLabel::CreateTextActionLabel( + GetDisplayText(input_element.keys()[0])); + } else if (IsMouseBound(input_element)) { + label = ActionLabel::CreateImageActionLabel(input_element.mouse_action()); } else { - if (IsMouseBound(input_element)) { - tag = ActionTag::CreateImageActionTag(input_element.mouse_action()); - } else { - tag = ActionTag::CreateTextActionTag("?"); - } - tag->SetSize(tag->GetPreferredSize()); + label = ActionLabel::CreateTextActionLabel("?"); } - return tag; + return label; } } // namespace @@ -61,7 +57,7 @@ const gfx::RectF& content_bounds) override { // Add circle if it doesn't exist. int radius = action_->GetUIRadius(content_bounds); - if (!circle_) { + if (show_circle() && !circle_) { auto circle = std::make_unique<ActionCircle>(radius); circle_ = AddChildView(std::move(circle)); } @@ -83,53 +79,34 @@ if (!binding) return; - if (tags_.empty()) { - // Create new action tag when initializing. - auto tag = CreateActionTag(*binding); - tags_.emplace_back(AddChildView(std::move(tag))); + if (labels_.empty()) { + // Create new action label when initializing. + auto label = CreateActionLabel(*binding); + labels_.emplace_back(AddChildView(std::move(label))); } else if (!IsBound(*binding)) { - // Action tag exists but without any bindings. - tags_[0]->SetTextActionTag(std::move(GetDisplayText(ui::DomCode::NONE))); + // Action label exists but without any bindings. + labels_[0]->SetTextActionLabel( + std::move(GetDisplayText(ui::DomCode::NONE))); } else if (IsKeyboardBound(*binding)) { - // Action tag is bound to keyboard key. - tags_[0]->SetTextActionTag(std::move(GetDisplayText(binding->keys()[0]))); + // Action label is bound to keyboard key. + labels_[0]->SetTextActionLabel( + std::move(GetDisplayText(binding->keys()[0]))); } else { - // Action tag is bound to mouse. - tags_[0]->SetImageActionTag(binding->mouse_action()); - } - auto* tag = tags_[0]; - auto tag_size = tag->GetPreferredSize(); - int width = std::max(radius * 2, - radius * 2 - kTagPositionToSide + tag_size.width()); - SetSize(gfx::Size(width, radius * 2)); - - if (action_->on_left_or_middle_side()) { - circle_->SetPosition(gfx::Point()); - tag->SetPosition(gfx::Point(tag_size.width() > kTagPositionToSide - ? width - tag_size.width() - : width - kTagPositionToSide, - radius * 2 - tag_size.height() - kTagMargin)); - center_.set_x(radius); - center_.set_y(radius); - } else { - circle_->SetPosition(gfx::Point(width - radius * 2, 0)); - tag->SetPosition( - gfx::Point(0, radius * 2 - tag_size.height() - kTagMargin)); - center_.set_x(width - radius); - center_.set_y(radius); + // Action label is bound to mouse. + labels_[0]->SetImageActionLabel(binding->mouse_action()); } } - void OnKeyBindingChange(ActionTag* action_tag, ui::DomCode code) override { - if (ShouldShowErrorMsg(code)) + void OnKeyBindingChange(ActionLabel* action_label, + ui::DomCode code) override { + if (ShouldShowErrorMsg(code, action_label)) return; - DCHECK(tags_.size() == 1 && tags_[0] == action_tag); - if (tags_.size() != 1 || tags_[0] != action_tag) + DCHECK(labels_.size() == 1 && labels_[0] == action_label); + if (labels_.size() != 1 || labels_[0] != action_label) return; auto input_element = InputElement::CreateActionTapKeyElement(code); - display_overlay_controller_->OnBindingChange(action_, - std::move(input_element)); + ChangeBinding(action_, action_label, std::move(input_element)); } void OnBindingToKeyboard() override { @@ -141,7 +118,6 @@ action_->set_pending_binding(std::move(input_element)); auto bounds = CalculateWindowContentBounds(action_->target_window()); SetViewContent(BindingOption::kPending, bounds); - SetDisplayMode(DisplayMode::kEdited); } void OnBindingToMouse(std::string mouse_action) override { @@ -156,8 +132,7 @@ auto input_element = InputElement::CreateActionTapMouseElement(mouse_action); - display_overlay_controller_->OnBindingChange(action_, - std::move(input_element)); + ChangeBinding(action_, /*ActionLabel=*/nullptr, std::move(input_element)); } void OnMenuEntryPressed() override { @@ -167,6 +142,42 @@ return; menu_entry_->RequestFocus(); } + + void ChildPreferredSizeChanged(View* child) override { + DCHECK(labels_.size() == 1); + if (static_cast<ActionLabel*>(child) != labels_[0]) + return; + + auto content_bounds = + CalculateWindowContentBounds(action_->target_window()); + int radius = action_->GetUIRadius(content_bounds); + auto* label = labels_[0]; + auto label_size = label->CalculatePreferredSize(); + int width = std::max( + radius * 2, radius * 2 - kLabelPositionToSide + label_size.width()); + if (action_->on_left_or_middle_side()) { + if (show_circle()) + circle_->SetPosition(gfx::Point()); + label->SetPosition( + gfx::Point(label_size.width() > kLabelPositionToSide + ? width - label_size.width() + : width - kLabelPositionToSide, + radius * 2 - label_size.height() - kLabelMargin)); + center_.set_x(radius); + center_.set_y(radius); + } else { + if (show_circle()) + circle_->SetPosition(gfx::Point(width - radius * 2, 0)); + label->SetPosition( + gfx::Point(0, radius * 2 - label_size.height() - kLabelMargin)); + center_.set_x(width - radius); + center_.set_y(radius); + } + label->SetSize(label_size); + SetSize(gfx::Size(width, radius * 2)); + auto center_pos = action_->GetUICenterPosition(content_bounds); + SetPositionFromCenterPosition(center_pos); + } }; ActionTap::ActionTap(aura::Window* window) : Action(window) {} @@ -256,8 +267,6 @@ auto view = std::make_unique<ActionTapView>(this, display_overlay_controller, content_bounds); view->set_editable(true); - auto center_pos = GetUICenterPosition(content_bounds); - view->SetPositionFromCenterPosition(center_pos); action_view_ = view.get(); return view; } @@ -266,7 +275,8 @@ if (pending_binding_) pending_binding_.reset(); pending_binding_ = std::make_unique<InputElement>(); - + if (action_view_) + action_view_->set_unbind_label_index(0); PostUnbindProcess(); }
diff --git a/chrome/browser/ash/arc/input_overlay/actions/input_element.cc b/chrome/browser/ash/arc/input_overlay/actions/input_element.cc index 2c1a3da..7e4c341 100644 --- a/chrome/browser/ash/arc/input_overlay/actions/input_element.cc +++ b/chrome/browser/ash/arc/input_overlay/actions/input_element.cc
@@ -201,5 +201,9 @@ return equal; } +bool InputElement::operator!=(const InputElement& other) const { + return !(*this == other); +} + } // namespace input_overlay } // namespace arc
diff --git a/chrome/browser/ash/arc/input_overlay/actions/input_element.h b/chrome/browser/ash/arc/input_overlay/actions/input_element.h index 404f12f..2fcb623 100644 --- a/chrome/browser/ash/arc/input_overlay/actions/input_element.h +++ b/chrome/browser/ash/arc/input_overlay/actions/input_element.h
@@ -80,6 +80,7 @@ int mouse_flags() const { return mouse_flags_; } bool operator==(const InputElement& other) const; + bool operator!=(const InputElement& other) const; private: // Input source for this input element, could be keyboard or mouse or both.
diff --git a/chrome/browser/ash/arc/input_overlay/constants.h b/chrome/browser/ash/arc/input_overlay/constants.h index 8b3f52a6..87d10c3 100644 --- a/chrome/browser/ash/arc/input_overlay/constants.h +++ b/chrome/browser/ash/arc/input_overlay/constants.h
@@ -20,14 +20,19 @@ // Display overlay can receive events and action labels can be focused. It // shows input mapping in edit mode. kEdit, - // Display overlay can still receive events. It is a mode after an action - // label receives a valid key mapping. - kEdited, // Display overlay can receive events but action labels can't be focused. // It shows expanded menu and input mapping as in view mode. kMenu, - // It is a mode when an action is removed the input binding. + + // Below are related to edit for |ActionView|. + // Edit mode when action is assigned a pending input binding. + kEditedSuccess, + // Edit mode when an action is removed the input binding. kEditedUnbound, + // Edit mode when a wrong/unsupported input is trying to bind. + kEditedError, + // Restore mode when restoring the default input bindings. + kRestore, }; // Binding options for different ui display stages. @@ -49,6 +54,21 @@ kMove, }; +// Edit states related to the mouse input and focus for |ActionLabel|. +enum class EditState { + kNone, + // Default edit state when no mouse hovers or no focus. + kEditDefault, + // Edit state when the mouse hovers. This can be overridden by |kEditFocus|. + kEditHover, + // Edit state when the |ActionLabel| is focused. + kEditFocus, + // Edit state when a wrong/unsupported input tries to bind. + kEditError, + // Edit state when a input binding is removed. + kEditUnbind, +}; + } // namespace input_overlay } // namespace arc
diff --git a/chrome/browser/ash/arc/input_overlay/input_overlay_resources_util.cc b/chrome/browser/ash/arc/input_overlay/input_overlay_resources_util.cc index 3afe9e2..154ff9c 100644 --- a/chrome/browser/ash/arc/input_overlay/input_overlay_resources_util.cc +++ b/chrome/browser/ash/arc/input_overlay/input_overlay_resources_util.cc
@@ -16,7 +16,6 @@ IDR_IO_ORG_CHROMIUM_ARC_TESTAPP_INPUTOVERLAY}, {"com.blackpanther.ninjaarashi2", IDR_IO_COM_BLACKPANTHER_NINJAARASHI2}, {"com.habby.archero", IDR_IO_COM_HABBY_ARCHERO}, - {"com.dts.freefireth", IDR_IO_COM_DTS_FREEFIRETH}, {"com.fingersoft.hillclimb", IDR_IO_COM_FINGERSOFT_HILLCLIMB}, {"com.androbaby.game2048", IDR_IO_COM_ANDROBABY_GAME2048}, {"co.imba.archero", IDR_IO_CO_IMBA_ARCHERO},
diff --git a/chrome/browser/ash/arc/input_overlay/touch_injector.cc b/chrome/browser/ash/arc/input_overlay/touch_injector.cc index 6fa9dcc6..69213e0 100644 --- a/chrome/browser/ash/arc/input_overlay/touch_injector.cc +++ b/chrome/browser/ash/arc/input_overlay/touch_injector.cc
@@ -175,9 +175,9 @@ observation_.Reset(); } -void TouchInjector::OnBindingChange(Action* target_action, - std::unique_ptr<InputElement> input_element, - DisplayMode mode) { +void TouchInjector::OnBindingChange( + Action* target_action, + std::unique_ptr<InputElement> input_element) { if (display_overlay_controller_) display_overlay_controller_->RemoveEditErrorMsg(); Action* overlapped_action = nullptr; @@ -195,7 +195,7 @@ if (overlapped_action) overlapped_action->Unbind(*input_element); - target_action->PrepareToBind(std::move(input_element), mode); + target_action->PrepareToBind(std::move(input_element)); } void TouchInjector::OnApplyPendingBinding() { @@ -237,7 +237,7 @@ auto input_element = InputElement::ConvertFromProto(action_proto.input_element()); DCHECK(input_element); - OnBindingChange(action, std::move(input_element), DisplayMode::kView); + OnBindingChange(action, std::move(input_element)); } OnApplyPendingBinding(); }
diff --git a/chrome/browser/ash/arc/input_overlay/touch_injector.h b/chrome/browser/ash/arc/input_overlay/touch_injector.h index f385e4e..a4be1a2 100644 --- a/chrome/browser/ash/arc/input_overlay/touch_injector.h +++ b/chrome/browser/ash/arc/input_overlay/touch_injector.h
@@ -105,8 +105,7 @@ // (|mode| = DisplayMode::kEdit) or from customized protobuf data (|mode| = // DisplayMode::kView). void OnBindingChange(Action* target_action, - std::unique_ptr<InputElement> input_element, - DisplayMode mode = DisplayMode::kEdit); + std::unique_ptr<InputElement> input_element); // Apply pending binding as current binding, but don't save into the storage. void OnApplyPendingBinding(); // Save customized input binding/pending binding as current binding and go
diff --git a/chrome/browser/ash/arc/input_overlay/ui/action_circle.cc b/chrome/browser/ash/arc/input_overlay/ui/action_circle.cc index 761e9e9..8407920c 100644 --- a/chrome/browser/ash/arc/input_overlay/ui/action_circle.cc +++ b/chrome/browser/ash/arc/input_overlay/ui/action_circle.cc
@@ -64,7 +64,7 @@ SetBackground(std::make_unique<CircleBackground>(kEditDefaultColor, kEditDefaultStroke)); break; - case DisplayMode::kEdited: + case DisplayMode::kEditedSuccess: case DisplayMode::kEditedUnbound: SetBackground( std::make_unique<CircleBackground>(kEditedColor, kEditedStroke));
diff --git a/chrome/browser/ash/arc/input_overlay/ui/action_label.cc b/chrome/browser/ash/arc/input_overlay/ui/action_label.cc index 552ec07..450c9cb 100644 --- a/chrome/browser/ash/arc/input_overlay/ui/action_label.cc +++ b/chrome/browser/ash/arc/input_overlay/ui/action_label.cc
@@ -6,30 +6,45 @@ #include <set> -#include "chrome/browser/ash/arc/input_overlay/ui/action_tag.h" +#include "ash/style/style_util.h" +#include "chrome/app/vector_icons/vector_icons.h" +#include "chrome/browser/ash/arc/input_overlay/ui/action_label.h" +#include "chrome/browser/ash/arc/input_overlay/ui/action_view.h" #include "third_party/skia/include/core/SkColor.h" #include "ui/events/keycodes/dom/keycode_converter.h" #include "ui/gfx/color_palette.h" +#include "ui/gfx/paint_vector_icon.h" #include "ui/views/background.h" +#include "ui/views/controls/highlight_path_generator.h" namespace arc { namespace input_overlay { namespace { // UI specs. -constexpr int kWidthPadding = 10; -constexpr gfx::Size kMinimumViewLabelSize(32, 32); +constexpr int kSideInset = 6; +constexpr gfx::Size kMinimumSmallSize(32, 32); +constexpr gfx::Size kMinimumLargeSize(48, 48); constexpr int kCornerRadiusView = 6; +constexpr int kIconSize = 20; +constexpr char kFontSytle[] = "Google Sans"; +constexpr int kSmallFontSize = 16; +constexpr int kLargeFontSize = 20; +// About colors. constexpr SkColor kViewModeBgColor = SkColorSetA(SK_ColorGRAY, 0x99); constexpr SkColor kEditModeBgColor = SK_ColorWHITE; constexpr SkColor kEditedUnboundBgColor = gfx::kGoogleRed300; constexpr SkColor kViewTextColor = SK_ColorWHITE; constexpr SkColor kEditTextColor = gfx::kGoogleGrey900; +constexpr SkColor kFocusRingGreyColor = SkColorSetA(gfx::kGoogleGrey200, 0x60); +constexpr SkColor kFocusRingBlueColor = gfx::kGoogleBlue300; +constexpr SkColor kFocusRingRedColor = gfx::kGoogleRed300; -constexpr char kFontSytle[] = "Google Sans"; -constexpr int kViewFontSize = 16; -constexpr int kUnFocusFontSize = 16; -constexpr int kFocusFontSize = 20; +// About focus ring. +// Gap between focus ring outer edge to label. +constexpr float kHaloInset = -3; +// Thickness of focus ring. +constexpr float kHaloThickness = 2; // UI strings. // TODO(cuicuiruan): move the strings to chrome/app/generated_resources.grd @@ -80,81 +95,219 @@ } } -ActionLabel::ActionLabel() : views::Label() {} -ActionLabel::ActionLabel(const std::u16string& text) : views::Label(text) { - SetToViewMode(); +ActionLabel::ActionLabel() : views::LabelButton() { + SetRequestFocusOnPress(true); + SetHorizontalAlignment(gfx::ALIGN_CENTER); + SetBorder(views::CreateEmptyBorder(gfx::Insets::VH(0, kSideInset))); } ActionLabel::~ActionLabel() = default; +// static +std::unique_ptr<ActionLabel> ActionLabel::CreateTextActionLabel( + const std::string& text) { + auto label = std::make_unique<ActionLabel>(); + label->SetTextActionLabel(text); + return label; +} + +// static +std::unique_ptr<ActionLabel> ActionLabel::CreateImageActionLabel( + MouseAction mouse_action) { + DCHECK(mouse_action == MouseAction::PRIMARY_CLICK || + mouse_action == MouseAction::SECONDARY_CLICK); + if (mouse_action != MouseAction::PRIMARY_CLICK && + mouse_action != MouseAction::SECONDARY_CLICK) { + return nullptr; + } + auto label = std::make_unique<ActionLabel>(); + label->SetImageActionLabel(mouse_action); + return label; +} + +void ActionLabel::SetTextActionLabel(const std::string& text) { + label()->SetText(base::UTF8ToUTF16(text)); + SetAccessibleName(label()->GetText()); +} + +void ActionLabel::SetImageActionLabel(MouseAction mouse_action) { + SetAccessibleName(base::UTF8ToUTF16(GetClassName())); + set_mouse_action(mouse_action); +} + +void ActionLabel::SetDisplayMode(DisplayMode mode) { + DCHECK(mode != DisplayMode::kMenu); + if (mode == DisplayMode::kMenu) + return; + + switch (mode) { + case DisplayMode::kView: + SetToViewMode(); + break; + case DisplayMode::kEdit: + SetToEditMode(); + break; + case DisplayMode::kEditedSuccess: + SetToEditFocus(); + break; + case DisplayMode::kEditedUnbound: + SetToEditUnBind(); + break; + case DisplayMode::kEditedError: + SetToEditError(); + break; + case DisplayMode::kRestore: + if (!ClearFocus()) + SetToEditDefault(); + break; + default: + NOTREACHED(); + break; + } +} + gfx::Size ActionLabel::CalculatePreferredSize() const { - auto size = Label::CalculatePreferredSize(); - size.set_width(size.width() + kWidthPadding); - size.SetToMax(kMinimumViewLabelSize); + auto size = LabelButton::CalculatePreferredSize(); + switch (edit_state_) { + case EditState::kNone: + case EditState::kEditDefault: + case EditState::kEditUnbind: + size.SetToMax(kMinimumSmallSize); + break; + default: + size.SetToMax(kMinimumLargeSize); + break; + } return size; } -void ActionLabel::OnKeyEvent(ui::KeyEvent* event) { - if (event->type() == ui::ET_KEY_PRESSED) - return; - +bool ActionLabel::OnKeyPressed(const ui::KeyEvent& event) { DCHECK(parent()); - auto code = event->code(); - auto* parent_view = static_cast<ActionTag*>(parent()); - if (base::UTF8ToUTF16(GetDisplayText(code)) == GetText()) - parent_view->ShowErrorMsg(kEditErrorSameKey); + auto code = event.code(); + auto* parent_view = static_cast<ActionView*>(parent()); + if (base::UTF8ToUTF16(GetDisplayText(code)) == GetText()) { + parent_view->ShowErrorMsg(kEditErrorSameKey, this); + } else { + parent_view->OnKeyBindingChange(this, code); + } + return true; +} - parent_view->OnKeyBindingChange(code); +void ActionLabel::OnMouseEntered(const ui::MouseEvent& event) { + if (!HasFocus()) + SetToEditHover(); +} + +void ActionLabel::OnMouseExited(const ui::MouseEvent& event) { + if (!HasFocus()) + SetToEditDefault(); } void ActionLabel::OnFocus() { SetToEditFocus(); - SelectAll(); - Label::OnFocus(); + LabelButton::OnFocus(); } void ActionLabel::OnBlur() { - SetToEditMode(); - ClearSelection(); - Label::OnBlur(); + SetToEditDefault(); + LabelButton::OnBlur(); +} + +bool ActionLabel::ClearFocus() { + auto* focus_manager = GetFocusManager(); + bool has_focus = false; + if (focus_manager) { + has_focus = HasFocus(); + focus_manager->ClearFocus(); + } + return has_focus; } void ActionLabel::SetToViewMode() { - SetFontList(gfx::FontList({kFontSytle}, gfx::Font::NORMAL, kViewFontSize, - gfx::Font::Weight::BOLD)); - SetFocusBehavior(FocusBehavior::NEVER); + ClearFocus(); + SetInstallFocusRingOnFocus(false); + label()->SetFontList(gfx::FontList({kFontSytle}, gfx::Font::NORMAL, + kSmallFontSize, gfx::Font::Weight::BOLD)); + SetEnabledTextColors(kViewTextColor); + + if (mouse_action_ != MouseAction::NONE) { + if (mouse_action_ == MouseAction::PRIMARY_CLICK) { + auto left_click_icon = gfx::CreateVectorIcon( + gfx::IconDescription(kMouseLeftClickViewIcon, kIconSize)); + SetImage(views::Button::STATE_NORMAL, left_click_icon); + } else { + auto right_click_icon = gfx::CreateVectorIcon( + gfx::IconDescription(kMouseRightClickViewIcon, kIconSize)); + SetImage(views::Button::STATE_NORMAL, right_click_icon); + } + } + SetBackground( views::CreateRoundedRectBackground(kViewModeBgColor, kCornerRadiusView)); - SetAutoColorReadabilityEnabled(false); - SetEnabledColor(kViewTextColor); - SetSize(GetPreferredSize()); - SetSelectable(false); - SetEnabled(false); + SetPreferredSize(CalculatePreferredSize()); } void ActionLabel::SetToEditMode() { - SetFontList(gfx::FontList({kFontSytle}, gfx::Font::NORMAL, kUnFocusFontSize, - gfx::Font::Weight::BOLD)); - SetFocusBehavior(FocusBehavior::ALWAYS); - SetBackground( - views::CreateRoundedRectBackground(kEditModeBgColor, kCornerRadiusView)); - SetEnabledColor(kEditTextColor); - SetSize(GetPreferredSize()); - SetSelectable(true); - SetEnabled(true); + SetInstallFocusRingOnFocus(true); + auto* focus_ring = views::FocusRing::Get(this); + focus_ring->SetHaloInset(kHaloInset); + focus_ring->SetHaloThickness(kHaloThickness); + focus_ring->SetHasFocusPredicate([](views::View* view) { + return view->IsMouseHovered() || view->HasFocus(); + }); + + SetEnabledTextColors(kEditTextColor); + + if (mouse_action_ != MouseAction::NONE) { + if (mouse_action_ == MouseAction::PRIMARY_CLICK) { + auto left_click_icon = gfx::CreateVectorIcon( + gfx::IconDescription(kMouseLeftClickEditIcon, kIconSize)); + SetImage(views::Button::STATE_NORMAL, left_click_icon); + } else { + auto right_click_icon = gfx::CreateVectorIcon( + gfx::IconDescription(kMouseRightClickEditIcon, kIconSize)); + SetImage(views::Button::STATE_NORMAL, right_click_icon); + } + } + SetToEditDefault(); } -void ActionLabel::SetToEditedUnBind() { - SetBackground(views::CreateRoundedRectBackground(kEditedUnboundBgColor, - kCornerRadiusView)); - SetSize(GetPreferredSize()); - SetSelectable(true); - SetEnabled(true); +void ActionLabel::SetToEditDefault() { + edit_state_ = EditState::kEditDefault; + label()->SetFontList(gfx::FontList({kFontSytle}, gfx::Font::NORMAL, + kSmallFontSize, gfx::Font::Weight::BOLD)); + SetPreferredSize(CalculatePreferredSize()); + SetBackground( + views::CreateRoundedRectBackground(kEditModeBgColor, kCornerRadiusView)); +} + +void ActionLabel::SetToEditHover() { + edit_state_ = EditState::kEditHover; + auto* focus_ring = views::FocusRing::Get(this); + focus_ring->SetColor(kFocusRingGreyColor); + SetPreferredSize(CalculatePreferredSize()); } void ActionLabel::SetToEditFocus() { - SetFontList(gfx::FontList({kFontSytle}, gfx::Font::NORMAL, kFocusFontSize, - gfx::Font::Weight::BOLD)); + edit_state_ = EditState::kEditFocus; + views::FocusRing::Get(this)->SetColor(kFocusRingBlueColor); + label()->SetFontList(gfx::FontList({kFontSytle}, gfx::Font::NORMAL, + kLargeFontSize, gfx::Font::Weight::BOLD)); + SetPreferredSize(CalculatePreferredSize()); + SetBackground( + views::CreateRoundedRectBackground(kEditModeBgColor, kCornerRadiusView)); +} + +void ActionLabel::SetToEditError() { + edit_state_ = EditState::kEditError; + views::FocusRing::Get(this)->SetColor(kFocusRingRedColor); +} + +void ActionLabel::SetToEditUnBind() { + edit_state_ = EditState::kEditUnbind; + SetPreferredSize(CalculatePreferredSize()); + SetBackground(views::CreateRoundedRectBackground(kEditedUnboundBgColor, + kCornerRadiusView)); } } // namespace input_overlay
diff --git a/chrome/browser/ash/arc/input_overlay/ui/action_label.h b/chrome/browser/ash/arc/input_overlay/ui/action_label.h index 14a57871..fb5da151 100644 --- a/chrome/browser/ash/arc/input_overlay/ui/action_label.h +++ b/chrome/browser/ash/arc/input_overlay/ui/action_label.h
@@ -8,7 +8,8 @@ #include <string> #include "chrome/browser/ash/arc/input_overlay/constants.h" -#include "ui/views/controls/label.h" +#include "chrome/browser/ash/arc/input_overlay/db/proto/app_data.pb.h" +#include "ui/views/controls/button/label_button.h" namespace arc { namespace input_overlay { @@ -18,27 +19,55 @@ std::string GetDisplayText(const ui::DomCode code); // ActionLabel shows text mapping hint for each action. -class ActionLabel : public views::Label { +class ActionLabel : public views::LabelButton { public: ActionLabel(); - explicit ActionLabel(const std::u16string& text); - ActionLabel(const ActionLabel&) = delete; ActionLabel& operator=(const ActionLabel&) = delete; ~ActionLabel() override; - void SetToViewMode(); - void SetToEditMode(); - void SetToEditedUnBind(); + static std::unique_ptr<ActionLabel> CreateTextActionLabel( + const std::string& text); + static std::unique_ptr<ActionLabel> CreateImageActionLabel( + MouseAction mouse_action); + + void SetTextActionLabel(const std::string& text); + void SetImageActionLabel(MouseAction mouse_action); + void SetDisplayMode(DisplayMode mode); + void ShowErrorMsg(base::StringPiece error_msg); + void OnKeyBindingChange(ui::DomCode code); // views::View: gfx::Size CalculatePreferredSize() const override; - void OnKeyEvent(ui::KeyEvent* event) override; + bool OnKeyPressed(const ui::KeyEvent& event) override; + void OnMouseEntered(const ui::MouseEvent& event) override; + void OnMouseExited(const ui::MouseEvent& event) override; void OnFocus() override; void OnBlur() override; + void set_mouse_action(MouseAction mouse_action) { + mouse_action_ = mouse_action; + } + private: + // Return true if it has focus before clear focus. + bool ClearFocus(); + + void SetToViewMode(); + void SetToEditMode(); + // In edit mode without mouse hover or focus. + void SetToEditDefault(); + // In edit mode when mouse hovers. + void SetToEditHover(); + // In edit mode when this view is focused. void SetToEditFocus(); + // In edit mode when there is edit error. + void SetToEditError(); + // In edit mode when the input is unbound. + void SetToEditUnBind(); + + MouseAction mouse_action_ = MouseAction::NONE; + EditState edit_state_ = EditState::kNone; }; } // namespace input_overlay } // namespace arc
diff --git a/chrome/browser/ash/arc/input_overlay/ui/action_tag.cc b/chrome/browser/ash/arc/input_overlay/ui/action_tag.cc deleted file mode 100644 index ff9f4339..0000000 --- a/chrome/browser/ash/arc/input_overlay/ui/action_tag.cc +++ /dev/null
@@ -1,183 +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/ash/arc/input_overlay/ui/action_tag.h" - -#include "chrome/app/vector_icons/vector_icons.h" -#include "chrome/browser/ash/arc/input_overlay/actions/input_element.h" -#include "chrome/browser/ash/arc/input_overlay/ui/action_view.h" -#include "ui/gfx/paint_vector_icon.h" -#include "ui/views/background.h" -#include "ui/views/controls/button/image_button.h" - -namespace arc { -namespace input_overlay { -namespace { -constexpr int kIconSize = 20; -constexpr int kCornerRadius = 6; -constexpr SkColor kEditModeBgColor = SK_ColorWHITE; -constexpr SkColor kViewModeBgColor = SkColorSetA(SK_ColorGRAY, 0x99); -constexpr gfx::Size kImageButtonSize(32, 32); -} // namespace - -class ActionTag::ActionImage : public views::ImageButton { - public: - explicit ActionImage(MouseAction mouse_action) - : views::ImageButton(), mouse_action_(mouse_action) { - SetToViewMode(); - } - - ActionImage() : views::ImageButton() { SetToViewMode(); } - - ~ActionImage() override = default; - - void SetDisplayMode(DisplayMode mode) { - switch (mode) { - case DisplayMode::kMenu: - case DisplayMode::kView: - SetToViewMode(); - break; - case DisplayMode::kEdit: - SetToEditMode(); - break; - default: - NOTREACHED(); - break; - } - } - - void SetToViewMode() { - if (mouse_action_ == MouseAction::NONE) - return; - if (mouse_action_ == MouseAction::PRIMARY_CLICK) { - auto left_click_icon = gfx::CreateVectorIcon( - gfx::IconDescription(kMouseLeftClickViewIcon, kIconSize)); - SetImage(views::Button::STATE_NORMAL, left_click_icon); - } else { - auto right_click_icon = gfx::CreateVectorIcon( - gfx::IconDescription(kMouseRightClickViewIcon, kIconSize)); - SetImage(views::Button::STATE_NORMAL, right_click_icon); - } - SetBackground( - views::CreateRoundedRectBackground(kViewModeBgColor, kCornerRadius)); - } - - void SetToEditMode() { - if (mouse_action_ == MouseAction::PRIMARY_CLICK) { - auto left_click_icon = gfx::CreateVectorIcon( - gfx::IconDescription(kMouseLeftClickEditIcon, kIconSize)); - SetImage(views::Button::STATE_NORMAL, left_click_icon); - } else { - auto right_click_icon = gfx::CreateVectorIcon( - gfx::IconDescription(kMouseRightClickEditIcon, kIconSize)); - SetImage(views::Button::STATE_NORMAL, right_click_icon); - } - SetBackground( - views::CreateRoundedRectBackground(kEditModeBgColor, kCornerRadius)); - } - - private: - MouseAction mouse_action_; -}; - -ActionTag::ActionTag() : views::View() {} -ActionTag::~ActionTag() = default; - -void ActionTag::SetTextActionTag(const std::string& text) { - if (image_) { - RemoveChildViewT(image_); - image_ = nullptr; - } - - if (!label_) { - auto label = std::make_unique<ActionLabel>(base::UTF8ToUTF16(text)); - label->SetPosition(gfx::Point()); - label_ = AddChildView(std::move(label)); - } else { - label_->SetText(base::UTF8ToUTF16(text)); - } - label_->SetSize(label_->GetPreferredSize()); -} - -void ActionTag::SetImageActionTag(MouseAction mouse_action) { - RemoveAllChildViews(); - label_ = nullptr; - image_ = nullptr; - - auto image = std::make_unique<ActionImage>(mouse_action); - image->SetAccessibleName(base::UTF8ToUTF16(image->GetClassName())); - image->SetImageHorizontalAlignment(views::ImageButton::ALIGN_CENTER); - image->SetImageVerticalAlignment(views::ImageButton::ALIGN_MIDDLE); - image->SetToViewMode(); - image->SetPosition(gfx::Point()); - image->SetSize(kImageButtonSize); - image_ = AddChildView(std::move(image)); -} - -// static -std::unique_ptr<ActionTag> ActionTag::CreateTextActionTag(std::string text) { - auto tag = std::make_unique<ActionTag>(); - tag->SetTextActionTag(text); - return tag; -} - -// static -std::unique_ptr<ActionTag> ActionTag::CreateImageActionTag( - MouseAction mouse_action) { - DCHECK(mouse_action == MouseAction::PRIMARY_CLICK || - mouse_action == MouseAction::SECONDARY_CLICK); - if (mouse_action != MouseAction::PRIMARY_CLICK && - mouse_action != MouseAction::SECONDARY_CLICK) { - return nullptr; - } - auto tag = std::make_unique<ActionTag>(); - tag->SetImageActionTag(mouse_action); - - return tag; -} - -void ActionTag::SetDisplayMode(DisplayMode mode) { - switch (mode) { - case DisplayMode::kMenu: - case DisplayMode::kView: - if (label_) - label_->SetToViewMode(); - if (image_) - image_->SetToViewMode(); - break; - case DisplayMode::kEdit: - case DisplayMode::kEdited: - if (label_) - label_->SetToEditMode(); - if (image_) - image_->SetToEditMode(); - break; - case DisplayMode::kEditedUnbound: - if (label_) - label_->SetToEditedUnBind(); - break; - default: - NOTREACHED(); - break; - } -} - -void ActionTag::ShowErrorMsg(base::StringPiece error_msg) { - static_cast<ActionView*>(parent())->ShowErrorMsg(error_msg); -} - -void ActionTag::OnKeyBindingChange(ui::DomCode code) { - DCHECK(parent()); - static_cast<ActionView*>(parent())->OnKeyBindingChange(this, code); -} - -gfx::Size ActionTag::CalculatePreferredSize() const { - DCHECK((label_ && !image_) || (!label_ && image_)); - if (image_) - return image_->size(); - return label_ ? label_->GetPreferredSize() : gfx::Size(); -} - -} // namespace input_overlay -} // namespace arc
diff --git a/chrome/browser/ash/arc/input_overlay/ui/action_tag.h b/chrome/browser/ash/arc/input_overlay/ui/action_tag.h deleted file mode 100644 index 08718e2..0000000 --- a/chrome/browser/ash/arc/input_overlay/ui/action_tag.h +++ /dev/null
@@ -1,53 +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_ASH_ARC_INPUT_OVERLAY_UI_ACTION_TAG_H_ -#define CHROME_BROWSER_ASH_ARC_INPUT_OVERLAY_UI_ACTION_TAG_H_ - -#include "base/memory/raw_ptr.h" -#include "base/strings/string_piece_forward.h" -#include "chrome/browser/ash/arc/input_overlay/constants.h" -#include "chrome/browser/ash/arc/input_overlay/db/proto/app_data.pb.h" -#include "chrome/browser/ash/arc/input_overlay/ui/action_label.h" -#include "ui/views/view.h" - -namespace arc { -namespace input_overlay { - -// ActionTag is used to showing the mapping hint for each action. It can show -// text hint or image hint. -class ActionTag : public views::View { - public: - ActionTag(); - ActionTag(const ActionTag&) = delete; - ActionTag& operator=(const ActionTag&) = delete; - ~ActionTag() override; - - static std::unique_ptr<ActionTag> CreateTextActionTag(std::string text); - static std::unique_ptr<ActionTag> CreateImageActionTag( - MouseAction mouse_action); - - void SetTextActionTag(const std::string& text); - void SetImageActionTag(MouseAction mouse_action); - void SetDisplayMode(DisplayMode mode); - void ShowErrorMsg(base::StringPiece error_msg); - void OnKeyBindingChange(ui::DomCode code); - - // views::View: - gfx::Size CalculatePreferredSize() const override; - - private: - class ActionImage; - - void InitTextTag(); - void InitImageTag(); - - raw_ptr<ActionImage> image_ = nullptr; - raw_ptr<ActionLabel> label_ = nullptr; -}; - -} // namespace input_overlay -} // namespace arc - -#endif // CHROME_BROWSER_ASH_ARC_INPUT_OVERLAY_UI_ACTION_TAG_H_
diff --git a/chrome/browser/ash/arc/input_overlay/ui/action_view.cc b/chrome/browser/ash/arc/input_overlay/ui/action_view.cc index a41dbe2..c652991 100644 --- a/chrome/browser/ash/arc/input_overlay/ui/action_view.cc +++ b/chrome/browser/ash/arc/input_overlay/ui/action_view.cc
@@ -41,7 +41,7 @@ display_overlay_controller_(display_overlay_controller) {} ActionView::~ActionView() = default; -void ActionView::SetDisplayMode(DisplayMode mode) { +void ActionView::SetDisplayMode(DisplayMode mode, ActionLabel* editing_label) { DCHECK(mode != DisplayMode::kEducation); if ((!editable_ && mode == DisplayMode::kEdit) || mode == DisplayMode::kMenu) return; @@ -56,10 +56,14 @@ SetVisible(true); } - if (circle_) + if (show_circle() && circle_) circle_->SetDisplayMode(mode); - for (auto* tag : tags_) - tag->SetDisplayMode(mode); + if (!editing_label) { + for (auto* label : labels_) + label->SetDisplayMode(mode); + } else { + editing_label->SetDisplayMode(mode); + } } void ActionView::SetPositionFromCenterPosition(gfx::PointF& center_position) { @@ -86,9 +90,18 @@ display_overlay_controller_->RemoveActionEditMenu(); } -void ActionView::ShowErrorMsg(base::StringPiece error_msg) { +void ActionView::ShowErrorMsg(base::StringPiece error_msg, + ActionLabel* editing_label) { display_overlay_controller_->AddEditErrorMsg(this, error_msg); - SetDisplayMode(DisplayMode::kEdited); + SetDisplayMode(DisplayMode::kEditedError, editing_label); +} + +void ActionView::ChangeBinding(Action* action, + ActionLabel* action_label, + std::unique_ptr<InputElement> input_element) { + display_overlay_controller_->OnBindingChange(action, + std::move(input_element)); + SetDisplayMode(DisplayMode::kEditedSuccess, action_label); } void ActionView::OnResetBinding() { @@ -124,7 +137,8 @@ menu_entry_ = nullptr; } -bool ActionView::ShouldShowErrorMsg(ui::DomCode code) { +bool ActionView::ShouldShowErrorMsg(ui::DomCode code, + ActionLabel* editing_label) { // Check if |code| is duplicated with the keys in its action. For example, // there are four keys involved in the key-bound |ActionMove|. auto& binding = action_->GetCurrentDisplayedBinding(); @@ -132,8 +146,7 @@ for (const auto& key : binding.keys()) { if (key != code) continue; - display_overlay_controller_->AddEditErrorMsg(this, - kEditErrorDuplicatedKey); + ShowErrorMsg(kEditErrorDuplicatedKey, editing_label); return true; } } @@ -141,8 +154,7 @@ if ((!action_->support_modifier_key() && ModifierDomCodeToEventFlag(code) != ui::EF_NONE) || IsReservedDomCode(code)) { - display_overlay_controller_->AddEditErrorMsg(this, - kEditErrorUnsupportedKey); + ShowErrorMsg(kEditErrorUnsupportedKey, editing_label); return true; }
diff --git a/chrome/browser/ash/arc/input_overlay/ui/action_view.h b/chrome/browser/ash/arc/input_overlay/ui/action_view.h index 7d236c1..5f23958 100644 --- a/chrome/browser/ash/arc/input_overlay/ui/action_view.h +++ b/chrome/browser/ash/arc/input_overlay/ui/action_view.h
@@ -12,7 +12,7 @@ #include "chrome/browser/ash/arc/input_overlay/display_overlay_controller.h" #include "chrome/browser/ash/arc/input_overlay/ui/action_circle.h" #include "chrome/browser/ash/arc/input_overlay/ui/action_edit_button.h" -#include "chrome/browser/ash/arc/input_overlay/ui/action_tag.h" +#include "chrome/browser/ash/arc/input_overlay/ui/action_label.h" #include "ui/gfx/geometry/point.h" #include "ui/gfx/geometry/point_f.h" #include "ui/views/view.h" @@ -24,6 +24,9 @@ class DisplayOverlayController; class ActionEditButton; +// Represents the default label index. Default -1 means all the index. +constexpr int kDefaultLabelIndex = -1; + // ActionView is the view for each action. class ActionView : public views::View { public: @@ -37,7 +40,8 @@ virtual void SetViewContent(BindingOption binding_option, const gfx::RectF& content_bounds) = 0; // Each type of the actions acts differently on key binding change. - virtual void OnKeyBindingChange(ActionTag* action_tag, ui::DomCode code) = 0; + virtual void OnKeyBindingChange(ActionLabel* action_label, + ui::DomCode code) = 0; virtual void OnBindingToKeyboard() = 0; virtual void OnBindingToMouse(std::string mouse_action) = 0; // Each type of the actions shows different edit menu. @@ -45,7 +49,10 @@ // TODO(cuicuiruan): Remove virtual for post MVP once edit menu is ready for // |ActionMove|. - virtual void SetDisplayMode(const DisplayMode mode); + // If |editing_label| == nullptr, set display mode for all the |ActionLabel| + // child views, otherwise, only set the display mode for |editing_label|. + virtual void SetDisplayMode(const DisplayMode mode, + ActionLabel* editing_label = nullptr); // Set position from its center position. void SetPositionFromCenterPosition(gfx::PointF& center_position); @@ -53,18 +60,31 @@ gfx::Point GetEditMenuPosition(gfx::Size menu_size); void RemoveEditMenu(); // Show error message for action. - void ShowErrorMsg(base::StringPiece error_msg); + void ShowErrorMsg(base::StringPiece error_msg, ActionLabel* editing_label); + // Change binding for |action| binding to |input_element| and set + // |kEditedSuccess| on |action_label| if |action_label| is not nullptr. + // Otherwise, set |kEditedSuccess| to all |ActionLabel|. + void ChangeBinding(Action* action, + ActionLabel* action_label, + std::unique_ptr<InputElement> input_element); // Reset binding to its previous binding before entering to the edit mode. void OnResetBinding(); Action* action() { return action_; } + const std::vector<ActionLabel*>& labels() const { return labels_; } void set_editable(bool editable) { editable_ = editable; } DisplayOverlayController* display_overlay_controller() { return display_overlay_controller_; } + void set_unbind_label_index(int label_index) { + unbind_label_index_ = label_index; + } + int unbind_label_index() { return unbind_label_index_; } + bool show_circle() const { return show_circle_; } protected: - bool ShouldShowErrorMsg(ui::DomCode code); + bool ShouldShowErrorMsg(ui::DomCode code, + ActionLabel* editing_label = nullptr); // Reference to the action of this UI. raw_ptr<Action> action_ = nullptr; @@ -77,7 +97,7 @@ // The circle view shows up for editing the action. raw_ptr<ActionCircle> circle_ = nullptr; // Labels for mapping hints. - std::vector<ActionTag*> tags_; + std::vector<ActionLabel*> labels_; // Current display mode. DisplayMode current_display_mode_ = DisplayMode::kNone; // Center position of the circle view. @@ -88,6 +108,14 @@ private: void AddEditButton(); void RemoveEditButton(); + + // By default, all the labels are unbound. + int unbind_label_index_ = kDefaultLabelIndex; + + // TODO(cuicuiruan) As requested, we remove the action circle for edit mode + // for now. We will remove the circle permanently once the future design for + // MVP confirm that circle is not needed anymore. + bool show_circle_ = false; }; } // namespace input_overlay
diff --git a/chrome/browser/ash/arc/intent_helper/arc_settings_service.cc b/chrome/browser/ash/arc/intent_helper/arc_settings_service.cc index 7aa42c9..ba0b609 100644 --- a/chrome/browser/ash/arc/intent_helper/arc_settings_service.cc +++ b/chrome/browser/ash/arc/intent_helper/arc_settings_service.cc
@@ -35,11 +35,11 @@ #include "chrome/browser/ui/app_list/arc/arc_app_utils.h" #include "chrome/browser/ui/zoom/chrome_zoom_level_prefs.h" #include "chrome/common/pref_names.h" +#include "chromeos/ash/components/network/onc/network_onc_utils.h" #include "chromeos/network/network_handler.h" #include "chromeos/network/network_state.h" #include "chromeos/network/network_state_handler.h" #include "chromeos/network/network_state_handler_observer.h" -#include "chromeos/network/onc/network_onc_utils.h" #include "chromeos/network/proxy/proxy_config_service_impl.h" #include "components/arc/common/intent_helper/arc_intent_helper_package.h" #include "components/arc/intent_helper/arc_intent_helper_bridge.h"
diff --git a/chrome/browser/ash/arc/session/arc_session_manager.cc b/chrome/browser/ash/arc/session/arc_session_manager.cc index 6ef5aad..33731ec2 100644 --- a/chrome/browser/ash/arc/session/arc_session_manager.cc +++ b/chrome/browser/ash/arc/session/arc_session_manager.cc
@@ -1808,30 +1808,14 @@ // For ARCVM, generate <dest_path>/{combined.prop,fstab}. For ARC, generate // <dest_path>/{default,build,vendor_build}.prop. const bool is_arcvm = arc::IsArcVmEnabled(); - bool add_native_bridge_64bit_support = false; - if (base::CommandLine::ForCurrentProcess()->HasSwitch( - ash::switches::kArcEnableNativeBridge64BitSupportExperiment)) { - PrefService* local_pref_service = g_browser_process->local_state(); - if (base::FeatureList::IsEnabled( - arc::kNativeBridge64BitSupportExperimentFeature)) { - // Note that we treat this experiment as a one-way off->on switch, across - // all users of the device, as the lifetime of ARC mini-container and user - // sessions are different in different scenarios, and removing the - // experiment after it has been in effect for a user's ARC instance can - // lead to unexpected, and unsupported, results. - local_pref_service->SetBoolean( - prefs::kNativeBridge64BitSupportExperimentEnabled, true); - } - add_native_bridge_64bit_support = local_pref_service->GetBoolean( - prefs::kNativeBridge64BitSupportExperimentEnabled); - } std::deque<JobDesc> jobs = { JobDesc{kArcPrepareHostGeneratedDirJobName, UpstartOperation::JOB_START, {std::string("IS_ARCVM=") + (is_arcvm ? "1" : "0"), - std::string("ADD_NATIVE_BRIDGE_64BIT_SUPPORT=") + - (add_native_bridge_64bit_support ? "1" : "0")}}, + // TODO(b/233107740) Remove this once crrev.com/c/3656121 has + // landed. + std::string("ADD_NATIVE_BRIDGE_64BIT_SUPPORT=0")}}, }; ConfigureUpstartJobs(std::move(jobs), base::BindOnce(&ArcSessionManager::OnExpandPropertyFiles,
diff --git a/chrome/browser/ash/arc/tts/arc_tts_service_unittest.cc b/chrome/browser/ash/arc/tts/arc_tts_service_unittest.cc index 396f490..1d94eed 100644 --- a/chrome/browser/ash/arc/tts/arc_tts_service_unittest.cc +++ b/chrome/browser/ash/arc/tts/arc_tts_service_unittest.cc
@@ -64,6 +64,7 @@ content::TtsEngineDelegate* GetTtsEngineDelegate() override { return nullptr; } + void RefreshVoices() override {} void SetRemoteTtsEngineDelegate( content::RemoteTtsEngineDelegate* delegate) override {} void SetTtsPlatform(content::TtsPlatform* tts_platform) override {}
diff --git a/chrome/browser/ash/crosapi/network_settings_service_ash.cc b/chrome/browser/ash/crosapi/network_settings_service_ash.cc index 838283c..17a7df793 100644 --- a/chrome/browser/ash/crosapi/network_settings_service_ash.cc +++ b/chrome/browser/ash/crosapi/network_settings_service_ash.cc
@@ -12,10 +12,10 @@ #include "chrome/browser/ash/crosapi/network_settings_translation.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/profiles/profile_manager.h" +#include "chromeos/ash/components/network/onc/network_onc_utils.h" #include "chromeos/network/network_handler.h" #include "chromeos/network/network_state.h" #include "chromeos/network/network_state_handler.h" -#include "chromeos/network/onc/network_onc_utils.h" #include "chromeos/network/proxy/proxy_config_service_impl.h" #include "components/prefs/pref_change_registrar.h" #include "components/prefs/pref_registry_simple.h"
diff --git a/chrome/browser/ash/crostini/crostini_terminal.cc b/chrome/browser/ash/crostini/crostini_terminal.cc index 4c67ae57..7967c006 100644 --- a/chrome/browser/ash/crostini/crostini_terminal.cc +++ b/chrome/browser/ash/crostini/crostini_terminal.cc
@@ -523,11 +523,9 @@ } for (const auto& container : containers) { - // Use label 'penguin' if we have only the default container, else use - // <vm_name>:<container_name>. - std::string label = kCrostiniDefaultContainerName; - if (containers.size() > 1 || - container != crostini::ContainerId::GetDefault()) { + // Use <container_name> for termina, else <vm_name>:<container_name>. + std::string label = container.container_name; + if (container.vm_name != kCrostiniDefaultVmName) { label = base::StrCat({container.vm_name, ":", container.container_name}); } apps::AddShortcutCommandItem(next_command_id++,
diff --git a/chrome/browser/ash/eche_app/eche_app_notification_controller.cc b/chrome/browser/ash/eche_app/eche_app_notification_controller.cc index b99042f..8589f69 100644 --- a/chrome/browser/ash/eche_app/eche_app_notification_controller.cc +++ b/chrome/browser/ash/eche_app/eche_app_notification_controller.cc
@@ -138,14 +138,14 @@ const std::u16string& title) { message_center::RichNotificationData rich_notification_data; rich_notification_data.buttons.push_back(message_center::ButtonInfo( - l10n_util::GetStringUTF16(IDS_ECHE_APP_SCREEN_LOCK_SETTINGS_BUTTON))); - rich_notification_data.buttons.push_back(message_center::ButtonInfo( l10n_util::GetStringUTF16(IDS_ECHE_APP_SCREEN_LOCK_LEARN_MORE))); + rich_notification_data.buttons.push_back(message_center::ButtonInfo( + l10n_util::GetStringUTF16(IDS_ECHE_APP_SCREEN_LOCK_SETTINGS_BUTTON))); ShowNotification(CreateNotification( kEcheAppScreenLockNotifierId, NotificationCatalogName::kEcheAppScreenLock, - l10n_util::GetStringUTF16(IDS_ECHE_APP_SCREEN_LOCK_NOTIFICATION_TITLE), - l10n_util::GetStringFUTF16(IDS_ECHE_APP_SCREEN_LOCK_NOTIFICATION_MESSAGE, + l10n_util::GetStringFUTF16(IDS_ECHE_APP_SCREEN_LOCK_NOTIFICATION_TITLE, title), + l10n_util::GetStringUTF16(IDS_ECHE_APP_SCREEN_LOCK_NOTIFICATION_MESSAGE), ui::ImageModel(), rich_notification_data, new NotificationDelegate(kEcheAppScreenLockNotifierId, weak_ptr_factory_.GetWeakPtr()))); @@ -191,10 +191,10 @@ if (notification_id_ == kEcheAppScreenLockNotifierId) { if (*button_index == 0) { - notification_controller_->LaunchSettings(); + notification_controller_->LaunchLearnMore(); } else { DCHECK_EQ(1, *button_index); - notification_controller_->LaunchLearnMore(); + notification_controller_->LaunchSettings(); } } else if (notification_id_ == kEcheAppRetryConnectionNotifierId) { if (*button_index == 0) {
diff --git a/chrome/browser/ash/eche_app/eche_app_notification_controller_unittest.cc b/chrome/browser/ash/eche_app/eche_app_notification_controller_unittest.cc index bce1e55..ee97449 100644 --- a/chrome/browser/ash/eche_app/eche_app_notification_controller_unittest.cc +++ b/chrome/browser/ash/eche_app/eche_app_notification_controller_unittest.cc
@@ -172,14 +172,14 @@ ASSERT_EQ(2u, notification->buttons().size()); EXPECT_EQ(message_center::SYSTEM_PRIORITY, notification->priority()); - // Clicking the first notification button should launch settings. - EXPECT_CALL(*notification_controller_, LaunchSettings()); - notification->delegate()->Click(0, absl::nullopt); - - // Clicking the second notification button should launch learn more. + // Clicking the first notification button should launch learn more. EXPECT_CALL(*new_window_delegate_, OpenUrl(GURL(kEcheAppLearnMoreUrl), NewWindowDelegate::OpenUrlFrom::kUserInteraction)); + notification->delegate()->Click(0, absl::nullopt); + + // Clicking the second notification button should launch settings. + EXPECT_CALL(*notification_controller_, LaunchSettings()); notification->delegate()->Click(1, absl::nullopt); } @@ -196,14 +196,14 @@ ASSERT_EQ(2u, notification->buttons().size()); EXPECT_EQ(message_center::SYSTEM_PRIORITY, notification->priority()); - // Clicking the first notification button should launch settings. - EXPECT_CALL(*notification_controller_, LaunchSettings()); - notification->delegate()->Click(0, absl::nullopt); - // Clicking the second notification button should launch learn more. EXPECT_CALL(*new_window_delegate_, OpenUrl(GURL(kEcheAppLearnMoreUrl), NewWindowDelegate::OpenUrlFrom::kUserInteraction)); + notification->delegate()->Click(0, absl::nullopt); + + // Clicking the first notification button should launch settings. + EXPECT_CALL(*notification_controller_, LaunchSettings()); notification->delegate()->Click(1, absl::nullopt); }
diff --git a/chrome/browser/ash/file_manager/trash_io_task.cc b/chrome/browser/ash/file_manager/trash_io_task.cc index 9a10b15..61596f8d 100644 --- a/chrome/browser/ash/file_manager/trash_io_task.cc +++ b/chrome/browser/ash/file_manager/trash_io_task.cc
@@ -11,6 +11,7 @@ #include "base/task/bind_post_task.h" #include "base/task/thread_pool.h" #include "base/time/time_to_iso8601.h" +#include "chrome/browser/ash/drive/drive_integration_service.h" #include "chrome/browser/ash/file_manager/fileapi_util.h" #include "chrome/browser/ash/file_manager/io_task_util.h" #include "chrome/browser/ash/file_manager/path_util.h" @@ -22,6 +23,7 @@ namespace io_task { constexpr char kTrashFolderName[] = ".Trash"; +constexpr char kTrashUIDFolderName[] = ".Trash-1000"; constexpr char kInfoFolderName[] = "info"; constexpr char kFilesFolderName[] = "files"; @@ -145,6 +147,24 @@ progress_callback_ = std::move(progress_callback); complete_callback_ = std::move(complete_callback); + // Build the list of known paths that are enabled, for now Downloads is a bind + // mount at MyFiles/Downloads so treat them as separate volumes. + // TODO(b/233976434): Consider storing this data in the `DirectoryInfo` struct + // instead of separately. + enabled_trash_paths_.insert( + std::pair{util::GetMyFilesFolderForProfile(profile_), kTrashFolderName}); + enabled_trash_paths_.insert(std::pair{ + util::GetDownloadsFolderForProfile(profile_), kTrashFolderName}); + + auto* integration_service = + drive::DriveIntegrationServiceFactory::FindForProfile(profile_); + if (integration_service) { + enabled_trash_paths_.insert(std::pair{ + integration_service->GetMountPointPath(), kTrashUIDFolderName}); + } + + // TODO(b/231830443): Add in support for crostini. + progress_.state = State::kInProgress; UpdateTrashEntry(0); @@ -165,17 +185,14 @@ if (!base_path_.empty() && !source_path.IsAbsolute()) { source_path = base_path_.Append(source_path); } - const base::FilePath my_files_path = - util::GetMyFilesFolderForProfile(profile_); - const base::FilePath downloads_path = - util::GetDownloadsFolderForProfile(profile_); - base::FilePath trash_parent_path; - if (downloads_path.IsParent(source_path)) { - trash_parent_path = downloads_path; - } else if (my_files_path.IsParent(source_path)) { - trash_parent_path = my_files_path; - } else { + const auto& trash_parent_path_it = + std::find_if(enabled_trash_paths_.rbegin(), enabled_trash_paths_.rend(), + [&source_path](const auto& it) -> bool { + return it.first.IsParent(source_path); + }); + + if (trash_parent_path_it == enabled_trash_paths_.rend()) { // The `source_path` is not parented at a supported Trash location, bail // out completely. // TODO(b/231830211): This may be better handled more gracefully by @@ -186,8 +203,11 @@ return; } + const base::FilePath trash_parent_path = trash_parent_path_it->first; + const std::string folder_name = trash_parent_path_it->second; + TrashEntry& entry = trash_entries_[source_idx]; - entry.trash_path = trash_parent_path.Append(kTrashFolderName); + entry.trash_path = trash_parent_path.Append(folder_name); if (!UpdateTrashInfoContents(source_path, trash_parent_path, entry)) { // If we can't update the trash entry, update the source error and finish @@ -200,7 +220,7 @@ auto it = free_space_map_.find(trash_parent_path); if (it == free_space_map_.end()) { - GetFreeDiskSpace(source_idx, trash_parent_path); + GetFreeDiskSpace(source_idx, trash_parent_path, folder_name); return; } @@ -268,13 +288,14 @@ } void TrashIOTask::GetFreeDiskSpace(size_t source_idx, - const base::FilePath& trash_parent_path) { + const base::FilePath& trash_parent_path, + const std::string& folder_name) { base::ThreadPool::PostTaskAndReplyWithResult( FROM_HERE, {base::MayBlock()}, base::BindOnce(&base::SysInfo::AmountOfFreeDiskSpace, trash_parent_path), base::BindOnce(&TrashIOTask::GotFreeDiskSpace, weak_ptr_factory_.GetWeakPtr(), source_idx, - trash_parent_path)); + trash_parent_path, folder_name)); } base::FilePath TrashIOTask::MakeRelativeFromBasePath( @@ -293,9 +314,10 @@ void TrashIOTask::GotFreeDiskSpace(size_t source_idx, const base::FilePath& trash_parent_path, + const std::string& folder_name, int64_t free_space) { base::FilePath trash_path = - MakeRelativeFromBasePath(trash_parent_path.Append(kTrashFolderName)); + MakeRelativeFromBasePath(trash_parent_path.Append(folder_name)); const storage::FileSystemURL files_url = CreateFileSystemURL( progress_.sources[source_idx].url, trash_path.Append(kFilesFolderName)); const storage::FileSystemURL info_url = CreateFileSystemURL(
diff --git a/chrome/browser/ash/file_manager/trash_io_task.h b/chrome/browser/ash/file_manager/trash_io_task.h index 1ec8a1b..cee66ef 100644 --- a/chrome/browser/ash/file_manager/trash_io_task.h +++ b/chrome/browser/ash/file_manager/trash_io_task.h
@@ -74,6 +74,9 @@ // Constant representing the Trash folder name. extern const char kTrashFolderName[]; +// Constant representing the Trash folder name with the chronos UID suffix. +extern const char kTrashUIDFolderName[]; + // Constant representing the "info" folder name inside .Trash. extern const char kInfoFolderName[]; @@ -126,10 +129,16 @@ using FreeSpaceMap = std::map<base::FilePath, DirectoryInfo>; void ValidateAndDecrementFreeSpace(size_t source_idx, FreeSpaceMap::iterator& it); + // Get the free disk space for `trash_parent_path` to know whether the + // metadata can be written. The `folder_name` is used to differentiate between + // .Trash and .Trash-1000 folder names on various file systems (both are valid + // in the XDG spec). void GetFreeDiskSpace(size_t source_idx, - const base::FilePath& trash_parent_path); + const base::FilePath& trash_parent_path, + const std::string& folder_name); void GotFreeDiskSpace(size_t source_idx, const base::FilePath& trash_parent_path, + const std::string& folder_name, int64_t free_space); // Sets up the .Trash/files and .Trash/info subdirectories specified by the @@ -198,6 +207,9 @@ // finish the operation. Speedometer speedometer_; + // Any paths which are descendants from this list are enabled for trash. + std::map<const base::FilePath, const std::string> enabled_trash_paths_; + // Stores the id of the operations currently behind undertaken by Trash, // including directory creation. Enables cancelling an inflight operation. absl::optional<storage::FileSystemOperationRunner::OperationID> operation_id_;
diff --git a/chrome/browser/ash/file_manager/trash_io_task_unittest.cc b/chrome/browser/ash/file_manager/trash_io_task_unittest.cc index 7b7febb..d988302 100644 --- a/chrome/browser/ash/file_manager/trash_io_task_unittest.cc +++ b/chrome/browser/ash/file_manager/trash_io_task_unittest.cc
@@ -14,9 +14,16 @@ #include "base/test/mock_callback.h" #include "base/time/time_override.h" #include "base/time/time_to_iso8601.h" -#include "chrome/browser/ash/file_manager/fake_disk_mount_manager.h" +#include "chrome/browser/ash/drive/drive_integration_service.h" +#include "chrome/browser/ash/drive/drivefs_test_support.h" #include "chrome/browser/ash/file_manager/path_util.h" +#include "chrome/browser/ash/login/users/fake_chrome_user_manager.h" #include "chrome/test/base/testing_profile.h" +#include "chromeos/dbus/dbus_thread_manager.h" +#include "components/account_id/account_id.h" +#include "components/drive/drive_pref_names.h" +#include "components/prefs/pref_service.h" +#include "components/user_manager/scoped_user_manager.h" #include "content/public/test/browser_task_environment.h" #include "storage/browser/file_system/external_mount_points.h" #include "storage/browser/test/test_file_system_context.h" @@ -65,29 +72,57 @@ protected: void SetUp() override { ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); - file_system_context_ = storage::CreateFileSystemContextForTesting( - nullptr, temp_dir_.GetPath()); + + // Pass in a mock factory method that sets up a fake + // DriveIntegrationService. This ensures the enabled paths contain the drive + // path. + create_drive_integration_service_ = + base::BindRepeating(&TrashIOTaskTest::CreateDriveIntegrationService, + base::Unretained(this)); + service_factory_for_test_ = std::make_unique< + drive::DriveIntegrationServiceFactory::ScopedFactoryForTest>( + &create_drive_integration_service_); + + // Create the profile and add it to the user manager for DriveFS. profile_ = std::make_unique<TestingProfile>(base::FilePath(temp_dir_.GetPath())); + auto user_manager = std::make_unique<ash::FakeChromeUserManager>(); + AccountId account_id = + AccountId::FromUserEmailGaiaId(profile_->GetProfileUserName(), "12345"); + user_manager->AddUser(account_id); + user_manager->LoginUser(account_id); + scoped_user_manager_ = std::make_unique<user_manager::ScopedUserManager>( + std::move(user_manager)); - // Create Downloads and MyFiles inside the `temp_dir_`. + file_system_context_ = storage::CreateFileSystemContextForTesting( + nullptr, temp_dir_.GetPath()); my_files_dir_ = temp_dir_.GetPath().Append("MyFiles"); - downloads_dir_ = my_files_dir_.Append( - file_manager::util::GetDownloadsMountPointName(profile_.get())); - ASSERT_TRUE(base::CreateDirectory(downloads_dir_)); - ASSERT_TRUE(base::CreateDirectory(my_files_dir_)); - - // Register `my_files_dir_` as the parent directory for Downloads. storage::ExternalMountPoints::GetSystemInstance()->RegisterFileSystem( file_manager::util::GetDownloadsMountPointName(profile_.get()), storage::kFileSystemTypeLocal, storage::FileSystemMountOption(), my_files_dir_); + + // Create Downloads inside the `temp_dir_` which will implicitly create the + // `my_files_dir_. + downloads_dir_ = my_files_dir_.Append("Downloads"); + ASSERT_TRUE(base::CreateDirectory(downloads_dir_)); } void TearDown() override { // Ensure any previously registered mount points for Downloads are revoked. - storage::ExternalMountPoints::GetSystemInstance()->RevokeFileSystem( - file_manager::util::GetDownloadsMountPointName(profile_.get())); + storage::ExternalMountPoints::GetSystemInstance()->RevokeAllFileSystems(); + } + + drive::DriveIntegrationService* CreateDriveIntegrationService( + Profile* profile) { + base::ScopedAllowBlockingForTesting allow_blocking; + base::FilePath mount_point = temp_dir_.GetPath().Append("drivefs"); + fake_drivefs_helper_ = + std::make_unique<drive::FakeDriveFsHelper>(profile, mount_point); + integration_service_ = new drive::DriveIntegrationService( + profile, "", mount_point, + fake_drivefs_helper_->CreateFakeDriveFsListenerFactory()); + return integration_service_; } storage::FileSystemURL CreateFileSystemURL( @@ -138,9 +173,20 @@ const blink::StorageKey kTestStorageKey = blink::StorageKey::CreateFromStringForTesting("chrome-extension://abc"); + // DriveFS setup methods to ensure the tests have access to a mock + // DriveIntegrationService tied to the TestingProfile. + std::unique_ptr<user_manager::ScopedUserManager> scoped_user_manager_; + std::unique_ptr<drive::FakeDriveFsHelper> fake_drivefs_helper_; + drive::DriveIntegrationService* integration_service_ = nullptr; + drive::DriveIntegrationServiceFactory::FactoryCallback + create_drive_integration_service_; + std::unique_ptr<drive::DriveIntegrationServiceFactory::ScopedFactoryForTest> + service_factory_for_test_; + base::ScopedTempDir temp_dir_; base::FilePath downloads_dir_; base::FilePath my_files_dir_; + base::FilePath drive_dir_; scoped_refptr<storage::FileSystemContext> file_system_context_; }; @@ -221,6 +267,11 @@ } TEST_F(TrashIOTaskTest, SupportedDirectoryShouldSucceed) { + // Force the drive integration service to be created, this ensures the code + // path that adds the drive mount point is exercised. + ash::DBusThreadManager::Initialize(); + drive::DriveIntegrationServiceFactory::GetForProfile(profile_.get()); + std::string foo_contents = base::RandBytesAsString(kTestFileSize); const base::FilePath file_path = downloads_dir_.Append("foo.txt"); ASSERT_TRUE(base::WriteFile(file_path, foo_contents)); @@ -233,8 +284,8 @@ base::MockRepeatingCallback<void(const ProgressStatus&)> progress_callback; base::MockOnceCallback<void(ProgressStatus)> complete_callback; - // Progress callback should not be called as the verification of disk space - // should fail before any file operations occur. + // Progress callback is only invoked when there is multiple files being + // trashed. EXPECT_CALL(progress_callback, Run(_)).Times(0); EXPECT_CALL(complete_callback,
diff --git a/chrome/browser/ash/policy/core/browser_policy_connector_ash.cc b/chrome/browser/ash/policy/core/browser_policy_connector_ash.cc index 9099b2a..699f0eb 100644 --- a/chrome/browser/ash/policy/core/browser_policy_connector_ash.cc +++ b/chrome/browser/ash/policy/core/browser_policy_connector_ash.cc
@@ -73,11 +73,11 @@ #include "chrome/common/chrome_features.h" #include "chrome/common/pref_names.h" #include "chromeos/ash/components/dbus/upstart/upstart_client.h" +#include "chromeos/ash/components/network/onc/onc_certificate_importer_impl.h" #include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/dbus/session_manager/session_manager_client.h" #include "chromeos/network/network_cert_loader.h" #include "chromeos/network/network_handler.h" -#include "chromeos/network/onc/onc_certificate_importer_impl.h" #include "chromeos/system/statistics_provider.h" #include "components/policy/core/common/cloud/cloud_policy_client.h" #include "components/policy/core/common/cloud/cloud_policy_refresh_scheduler.h"
diff --git a/chrome/browser/ash/policy/networking/policy_certs_browsertest.cc b/chrome/browser/ash/policy/networking/policy_certs_browsertest.cc index 362d3cd..ef24187 100644 --- a/chrome/browser/ash/policy/networking/policy_certs_browsertest.cc +++ b/chrome/browser/ash/policy/networking/policy_certs_browsertest.cc
@@ -48,10 +48,10 @@ #include "chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h" #include "chrome/common/chrome_paths.h" #include "chrome/test/base/in_process_browser_test.h" +#include "chromeos/ash/components/network/onc/onc_certificate_importer.h" +#include "chromeos/ash/components/network/onc/onc_certificate_importer_impl.h" #include "chromeos/components/onc/onc_test_utils.h" #include "chromeos/network/network_cert_loader.h" -#include "chromeos/network/onc/onc_certificate_importer.h" -#include "chromeos/network/onc/onc_certificate_importer_impl.h" #include "chromeos/network/policy_certificate_provider.h" #include "chromeos/test/chromeos_test_utils.h" #include "components/onc/onc_constants.h"
diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd index e79aacf..1bf2c65 100644 --- a/chrome/browser/browser_resources.grd +++ b/chrome/browser/browser_resources.grd
@@ -232,10 +232,14 @@ </if> <if expr="chromeos_ash and _google_chrome"> <include name="IDR_HELP_MANIFEST" file="resources\help_app\manifest.json" type="BINDATA" /> - <include name="IDR_QUICKOFFICE_MANIFEST" file="resources\chromeos\quickoffice\manifest.json" type="BINDATA" /> <include name="IDR_PRODUCT_CHROMEOS_SYNC_CONSENT_SCREEN_ICONS" file="internal\resources\chromeos-sync-consent-icons.html" type="BINDATA" /> <include name="IDR_PRODUCT_CHROMEOS_SYNC_CONSENT_SCREEN_ICONS_M_JS" file="internal\resources\chromeos-sync-consent-icons.m.js" type="BINDATA" /> </if> + <if expr="chromeos_ash or chromeos_lacros"> + <if expr="_google_chrome"> + <include name="IDR_QUICKOFFICE_MANIFEST" file="resources\chromeos\quickoffice\manifest.json" type="BINDATA" /> + </if> + </if> <if expr="_google_chrome"> <include name="IDR_PREF_HASH_SEED_BIN" file="resources\settings_internal\pref_hash_seed.bin" type="BINDATA" /> <include name="IDR_ADDITIONAL_MODULE_IDS" file="${additional_modules_list_file}" use_base_dir="false" type="BINDATA" />
diff --git a/chrome/browser/chrome_browser_main.cc b/chrome/browser/chrome_browser_main.cc index 118f2bc..68042f64 100644 --- a/chrome/browser/chrome_browser_main.cc +++ b/chrome/browser/chrome_browser_main.cc
@@ -215,6 +215,11 @@ #include "chrome/browser/first_run/upgrade_util.h" #endif // !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) +#include "base/process/process.h" +#include "base/task/task_traits.h" +#endif // BUILDFLAG(IS_CHROMEOS) + #if !BUILDFLAG(IS_CHROMEOS_ASH) #include "components/enterprise/browser/controller/chrome_browser_cloud_management_controller.h" #endif // !BUILDFLAG(IS_CHROMEOS_ASH) @@ -1840,6 +1845,16 @@ sharing::ShareHistory::CreateForProfile( ProfileManager::GetPrimaryUserProfile()); #endif + +#if BUILDFLAG(IS_CHROMEOS) + // If OneGroupPerRenderer feature is enabled, post a task to clean any left + // over cgroups due to any unclean exits. + if (base::Process::OneGroupPerRendererEnabled()) { + base::ThreadPool::PostTask( + FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT}, + base::BindOnce(&base::Process::CleanUpStaleProcessStates)); + } +#endif // BUILDFLAG(IS_CHROMEOS) } void ChromeBrowserMainParts::PostMainMessageLoopRun() {
diff --git a/chrome/browser/extensions/BUILD.gn b/chrome/browser/extensions/BUILD.gn index 917a61f1..10b2f06 100644 --- a/chrome/browser/extensions/BUILD.gn +++ b/chrome/browser/extensions/BUILD.gn
@@ -1003,6 +1003,7 @@ deps += [ "//chrome/browser/chromeos/extensions:constants", "//chrome/browser/chromeos/extensions/login_screen", + "//chromeos/constants", "//chromeos/components/disks:prefs", "//chromeos/components/quick_answers/public/cpp:prefs", "//chromeos/crosapi/cpp",
diff --git a/chrome/browser/extensions/api/networking_private/networking_private_chromeos_apitest.cc b/chrome/browser/extensions/api/networking_private/networking_private_chromeos_apitest.cc index 6878f1d5..44907c96 100644 --- a/chrome/browser/extensions/api/networking_private/networking_private_chromeos_apitest.cc +++ b/chrome/browser/extensions/api/networking_private/networking_private_chromeos_apitest.cc
@@ -20,6 +20,7 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/extensions/api/networking_private/networking_private_ui_delegate_chromeos.h" #include "chrome/browser/extensions/extension_apitest.h" +#include "chromeos/ash/components/network/onc/network_onc_utils.h" #include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/dbus/shill/shill_device_client.h" #include "chromeos/dbus/shill/shill_ipconfig_client.h" @@ -36,7 +37,6 @@ #include "chromeos/network/network_state.h" #include "chromeos/network/network_state_handler.h" #include "chromeos/network/network_type_pattern.h" -#include "chromeos/network/onc/network_onc_utils.h" #include "components/onc/onc_constants.h" #include "components/onc/onc_pref_names.h" #include "components/policy/core/browser/browser_policy_connector.h"
diff --git a/chrome/browser/extensions/component_extensions_allowlist/allowlist.cc b/chrome/browser/extensions/component_extensions_allowlist/allowlist.cc index 7cbc426..60ab74d 100644 --- a/chrome/browser/extensions/component_extensions_allowlist/allowlist.cc +++ b/chrome/browser/extensions/component_extensions_allowlist/allowlist.cc
@@ -86,14 +86,16 @@ case IDR_WALLPAPERMANAGER_MANIFEST: #if BUILDFLAG(GOOGLE_CHROME_BRANDING) case IDR_HELP_MANIFEST: - case IDR_QUICKOFFICE_MANIFEST: #endif // BUILDFLAG(GOOGLE_CHROME_BRANDING) #endif // BUILDFLAG(IS_CHROMEOS_ASH) #if BUILDFLAG(IS_CHROMEOS) case IDR_CONTACT_CENTER_INSIGHTS_MANIFEST: case IDR_ECHO_MANIFEST: -#endif +#if BUILDFLAG(GOOGLE_CHROME_BRANDING) + case IDR_QUICKOFFICE_MANIFEST: +#endif // BUILDFLAG(GOOGLE_CHROME_BRANDING) +#endif // BUILDFLAG(IS_CHROMEOS) return true; }
diff --git a/chrome/browser/extensions/component_loader.cc b/chrome/browser/extensions/component_loader.cc index cdfc1d1e..a2b613f 100644 --- a/chrome/browser/extensions/component_loader.cc +++ b/chrome/browser/extensions/component_loader.cc
@@ -70,6 +70,10 @@ #include "ui/file_manager/grit/file_manager_resources.h" #endif +#if BUILDFLAG(IS_CHROMEOS) +#include "chromeos/constants/chromeos_features.h" +#endif + #if BUILDFLAG(ENABLE_PDF) #include "chrome/browser/pdf/pdf_extension_util.h" #endif @@ -507,7 +511,15 @@ #if BUILDFLAG(IS_CHROMEOS) Add(IDR_ECHO_MANIFEST, base::FilePath(FILE_PATH_LITERAL("/usr/share/chromeos-assets/echo"))); -#endif +#if BUILDFLAG(GOOGLE_CHROME_BRANDING) + if (!base::FeatureList::IsEnabled( + chromeos::features::kDisableOfficeEditingComponentApp)) { + Add(IDR_QUICKOFFICE_MANIFEST, + base::FilePath( + FILE_PATH_LITERAL("/usr/share/chromeos-assets/quickoffice"))); + } +#endif // BUILDFLAG(GOOGLE_CHROME_BRANDING) +#endif // BUILDFLAG(IS_CHROMEOS) #if BUILDFLAG(IS_CHROMEOS_ASH) if (command_line->HasSwitch(switches::kLoadGuestModeTestExtension)) { @@ -520,13 +532,6 @@ AddImageLoaderExtension(); #if BUILDFLAG(GOOGLE_CHROME_BRANDING) - if (!base::FeatureList::IsEnabled( - chromeos::features::kDisableOfficeEditingComponentApp)) { - Add(IDR_QUICKOFFICE_MANIFEST, - base::FilePath( - FILE_PATH_LITERAL("/usr/share/chromeos-assets/quickoffice"))); - } - // TODO(https://crbug.com/1005083): Force the off the record profile to be // created to allow the virtual keyboard to work in guest mode. if (!IsNormalSession())
diff --git a/chrome/browser/feature_guide/notifications/internal/feature_notification_guide_service_impl_unittest.cc b/chrome/browser/feature_guide/notifications/internal/feature_notification_guide_service_impl_unittest.cc index 1eae77a7..23102f9 100644 --- a/chrome/browser/feature_guide/notifications/internal/feature_notification_guide_service_impl_unittest.cc +++ b/chrome/browser/feature_guide/notifications/internal/feature_notification_guide_service_impl_unittest.cc
@@ -20,6 +20,7 @@ #include "components/optimization_guide/proto/models.pb.h" #include "components/segmentation_platform/public/segment_selection_result.h" #include "components/segmentation_platform/public/segmentation_platform_service.h" +#include "components/segmentation_platform/public/trigger_context.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -109,6 +110,17 @@ OPTIMIZATION_TARGET_SEGMENTATION_CHROME_LOW_USER_ENGAGEMENT; return result; } + int RegisterOnDemandSegmentSelectionCallback( + const std::string& segmentation_key, + const OnDemandSegmentSelectionCallback& callback) override { + return 0; + } + void UnregisterOnDemandSegmentSelectionCallback( + int callback_id, + const std::string& segmentation_key) override {} + void OnTrigger( + segmentation_platform::TriggerType trigger, + const segmentation_platform::TriggerContext& trigger_context) override {} void EnableMetrics(bool signal_collection_allowed) override {} segmentation_platform::ServiceProxy* GetServiceProxy() override { return nullptr;
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index 079aecbc..bc25d4e 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -64,6 +64,11 @@ "expiry_milestone": 115 }, { + "name": "adaptive-charging-for-testing", + "owners": [ "thanhdng" ], + "expiry_milestone": 115 + }, + { "name": "add-passwords-in-settings", "owners": [ "vidhanj", "mamir", "lizapopova" ], "expiry_milestone": 103 @@ -221,13 +226,6 @@ "expiry_milestone": 108 }, { - "name": "arc-native-bridge-64bit-support-experiment", - "owners": [ "jhorwich" ], - // Used on ChromeOS to experimentally enable 64-bit ARC native-bridge - // support before promoting it to enabled on a specific device class. - "expiry_milestone": 93 - }, - { "name": "arc-native-bridge-toggle", "owners": [ "levarum@google.com" ], // Used on ChromeOS to compare and debug different ARC native-bridge @@ -4650,6 +4648,11 @@ "expiry_milestone": 105 }, { + "name": "one-group-per-renderer", + "owners": ["youssefesmat", "baseos-perf@google.com"], + "expiry_milestone": 120 + }, + { "name": "oobe-hid-detection-revamp", "owners": [ "gordonseto", "cros-connectivity@google.com"], "expiry_milestone": 105 @@ -5757,7 +5760,7 @@ { "name": "tab-search-fuzzy-search", "owners": [ "yuhengh", "chrome-cros@google.com" ], - "expiry_milestone": 101 + "expiry_milestone": 110 }, { "name": "tab-search-media-tabs",
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index 3d174a9..e52c5bbd 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -4113,6 +4113,15 @@ "Enable hardware-accelerated mjpeg decode for captured frame where " "available."; +const char kAdaptiveChargingForTestingName[] = + "Show adaptive charging notifications for testing"; +const char kAdaptiveChargingForTestingDescription[] = + "Show adaptive charging notifications and nudges for testing. This is " + "meant to be used by developers to test the feature UI only. The " + "notifications will be shown after the device is plugged in to the " + "charger. Please DO NOT enable this if you're not a developer who wants to " + "test the UI of the adaptive charging feature."; + const char kAdaptiveChargingName[] = "Enable adaptive charging feature"; const char kAdaptiveChargingDescription[] = "Show settings to enable/disable adaptive charging feature."; @@ -4204,11 +4213,6 @@ const char kArcNativeBridgeToggleDescription[] = "Toggle between native bridge implementations for ARC."; -const char kArcNativeBridge64BitSupportExperimentName[] = - "Enable experimental 64-bit native bridge support for ARC"; -const char kArcNativeBridge64BitSupportExperimentDescription[] = - "Enable experimental 64-bit native bridge support for ARC where available."; - const char kArcRightClickLongPressName[] = "Enable ARC right click long press compatibility feature."; const char kArcRightClickLongPressDescription[] = @@ -4585,14 +4589,6 @@ const char kUseHDRTransferFunctionDescription[] = "Allows using the HDR transfer functions of any connected monitor that " "supports it"; - -const char kDisableOfficeEditingComponentAppName[] = - "Disable Office Editing for Docs, Sheets & Slides"; -const char kDisableOfficeEditingComponentAppDescription[] = - "Disables Office Editing for Docs, Sheets & Slides component app so " - "handlers won't be registered, making it possible to install another " - "version for testing."; - const char kDoubleTapToZoomInTabletModeName[] = "Double-tap to zoom in tablet mode"; const char kDoubleTapToZoomInTabletModeDescription[] = @@ -5683,6 +5679,13 @@ "Deprecates low usage codecs. Disable this feature to allow playback of " "AMR and GSM."; +const char kDisableOfficeEditingComponentAppName[] = + "Disable Office Editing for Docs, Sheets & Slides"; +const char kDisableOfficeEditingComponentAppDescription[] = + "Disables Office Editing for Docs, Sheets & Slides component app so " + "handlers won't be registered, making it possible to install another " + "version for testing."; + const char kVaapiAV1DecoderName[] = "VA-API decode acceleration for AV1"; const char kVaapiAV1DecoderDescription[] = "Enable or disable decode acceleration of AV1 videos using the VA-API."; @@ -5720,6 +5723,11 @@ const char kMessagesPreinstallDescription[] = "Enables preinstallation of the Messages for Web PWA for unmanaged users."; +const char kOneGroupPerRendererName[] = + "Use one cgroup for each foreground renderer"; +const char kOneGroupPerRendererDescription[] = + "Places each Chrome foreground renderer into its own cgroup"; + const char kSyncChromeOSExplicitPassphraseSharingName[] = "Sync passphrase sharing"; const char kSyncChromeOSExplicitPassphraseSharingDescription[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index 38238535..ba72d16 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -2356,6 +2356,9 @@ extern const char kAdaptiveChargingName[]; extern const char kAdaptiveChargingDescription[]; +extern const char kAdaptiveChargingForTestingName[]; +extern const char kAdaptiveChargingForTestingDescription[]; + extern const char kAllowDisableTouchpadHapticFeedbackName[]; extern const char kAllowDisableTouchpadHapticFeedbackDescription[]; @@ -2407,9 +2410,6 @@ extern const char kArcNativeBridgeToggleName[]; extern const char kArcNativeBridgeToggleDescription[]; -extern const char kArcNativeBridge64BitSupportExperimentName[]; -extern const char kArcNativeBridge64BitSupportExperimentDescription[]; - extern const char kArcRightClickLongPressName[]; extern const char kArcRightClickLongPressDescription[]; @@ -2616,10 +2616,6 @@ extern const char kUseHDRTransferFunctionName[]; extern const char kUseHDRTransferFunctionDescription[]; - -extern const char kDisableOfficeEditingComponentAppName[]; -extern const char kDisableOfficeEditingComponentAppDescription[]; - extern const char kDoubleTapToZoomInTabletModeName[]; extern const char kDoubleTapToZoomInTabletModeDescription[]; @@ -3253,12 +3249,13 @@ extern const char kDefaultCalculatorWebAppName[]; extern const char kDefaultCalculatorWebAppDescription[]; -#endif // BUILDFLAG(IS_CHROMEOS) -#if BUILDFLAG(IS_CHROMEOS) extern const char kDeprecateLowUsageCodecsName[]; extern const char kDeprecateLowUsageCodecsDescription[]; +extern const char kDisableOfficeEditingComponentAppName[]; +extern const char kDisableOfficeEditingComponentAppDescription[]; + extern const char kVaapiAV1DecoderName[]; extern const char kVaapiAV1DecoderDescription[]; @@ -3280,6 +3277,9 @@ extern const char kMessagesPreinstallName[]; extern const char kMessagesPreinstallDescription[]; +extern const char kOneGroupPerRendererName[]; +extern const char kOneGroupPerRendererDescription[]; + extern const char kSyncChromeOSExplicitPassphraseSharingName[]; extern const char kSyncChromeOSExplicitPassphraseSharingDescription[]; #endif // BUILDFLAG(IS_CHROMEOS)
diff --git a/chrome/browser/history_clusters/history_clusters_metrics_logger.cc b/chrome/browser/history_clusters/history_clusters_metrics_logger.cc index 253f5ca..4f298fb 100644 --- a/chrome/browser/history_clusters/history_clusters_metrics_logger.cc +++ b/chrome/browser/history_clusters/history_clusters_metrics_logger.cc
@@ -36,19 +36,23 @@ // window closing. final_state_ = HistoryClustersFinalState::kCloseTab; } + // TODO(crbug.com/1326954): Add UI-driven counts to UKM during final state + // clean up. builder.SetInitialState(static_cast<int>(*initial_state_)); builder.SetFinalState(static_cast<int>(*final_state_)); builder.SetNumQueries(num_queries_); builder.SetNumTogglesToBasicHistory(num_toggles_to_basic_history_); builder.Record(ukm::UkmRecorder::Get()); - // Record UMA metrics. - base::UmaHistogramExactLinear("History.Clusters.Actions.LinksOpened", - links_opened_count_, 100); base::UmaHistogramEnumeration("History.Clusters.Actions.InitialState", *initial_state_); + + // TODO(crbug.com/1326954): Clean up once the metrics are refactored + // to be driven by UI events rather than navigation state. Also + // add collected counts to both UMA and UKM. base::UmaHistogramEnumeration("History.Clusters.Actions.FinalState", *final_state_); + base::UmaHistogramBoolean("History.Clusters.Actions.DidMakeQuery", num_queries_ > 0); if (num_queries_ > 0) { @@ -59,6 +63,48 @@ } } +void HistoryClustersMetricsLogger::RecordVisitAction(VisitAction visit_action, + uint32_t visit_index, + VisitType visit_type) { + base::UmaHistogramCounts100( + "History.Clusters.UIActions.Visit." + VisitActionToString(visit_action), + visit_index); + + base::UmaHistogramCounts100("History.Clusters.UIActions." + + VisitTypeToString(visit_type) + "Visit." + + VisitActionToString(visit_action), + visit_index); + // TODO(crbug.com/1326954): Add final state of total counts for each visit + // action. +} + +void HistoryClustersMetricsLogger::RecordClusterAction( + ClusterAction cluster_action, + uint32_t cluster_index) { + base::UmaHistogramCounts100("History.Clusters.UIActions.Cluster." + + ClusterActionToString(cluster_action), + cluster_index); + // TODO(crbug.com/1326954): Add final state of total counts for each cluster + // action. +} + +void HistoryClustersMetricsLogger::RecordRelatedSearchAction( + RelatedSearchAction action, + uint32_t related_search_index) { + base::UmaHistogramCounts100("History.Clusters.UIActions.RelatedSearch." + + RelatedSearchActionToString(action), + related_search_index); + // TODO(crbug.com/1326954): Add final state of total counts for each related + // search action. +} + +void HistoryClustersMetricsLogger::RecordToggledVisibility(bool visible) { + base::UmaHistogramBoolean("History.Clusters.UIActions.ToggledVisiblity", + visible); + // TODO(crbug.com/1326954): Add final state of total counts for each + // visibility toggle. +} + PAGE_USER_DATA_KEY_IMPL(HistoryClustersMetricsLogger); } // namespace history_clusters
diff --git a/chrome/browser/history_clusters/history_clusters_metrics_logger.h b/chrome/browser/history_clusters/history_clusters_metrics_logger.h index 49e2f04..27d30bc 100644 --- a/chrome/browser/history_clusters/history_clusters_metrics_logger.h +++ b/chrome/browser/history_clusters/history_clusters_metrics_logger.h
@@ -5,6 +5,7 @@ #ifndef CHROME_BROWSER_HISTORY_CLUSTERS_HISTORY_CLUSTERS_METRICS_LOGGER_H_ #define CHROME_BROWSER_HISTORY_CLUSTERS_HISTORY_CLUSTERS_METRICS_LOGGER_H_ +#include "components/history_clusters/core/cluster_metrics_utils.h" #include "content/public/browser/page.h" #include "content/public/browser/page_user_data.h" #include "content/public/browser/web_contents_observer.h" @@ -32,6 +33,8 @@ }; // The final state, or outcome, of an interaction on the HistoryClusters UI. +// TODO(crbug.com/1326954): Clean up once the metrics are refactored +// to be driven by UI events rather than navigation state. // // Keep in sync with HistoryClustersFinalState in // tools/metrics/histograms/enums.xml. @@ -92,7 +95,23 @@ navigation_id_ = navigation_id; } - void IncrementLinksOpenedCount() { links_opened_count_++; } + // Records that an |visit_action| in the UI occurred at |visit_index| position + // on a specified |visit_type|. + void RecordVisitAction(VisitAction visit_action, + uint32_t visit_index, + VisitType visit_type); + + // Records that a related search link was clicked at |related_search_index|. + void RecordRelatedSearchAction(RelatedSearchAction action, + uint32_t related_search_index); + + // Records that the journeys UI visibility was toggled. + void RecordToggledVisibility(bool visible); + + // Records that an |cluster_action| in the UI occurred at |cluster_index| + // position + void RecordClusterAction(ClusterAction cluster_action, + uint32_t cluster_index); private: // The navigation ID of the navigation handle that this data is associated @@ -113,12 +132,6 @@ // The number of times in this interaction with HistoryClusters included the // user toggled to the basic History UI from the HistoryClusters UI. int num_toggles_to_basic_history_ = 0; - - // The number of links opened from the HistoryClusters UI. Includes both - // same-tab and new-tab/window navigations. Includes both visit and related - // search links. Does not include sidebar navigations (e.g. 'Clear browsing - // data'). - int links_opened_count_ = 0; }; } // namespace history_clusters
diff --git a/chrome/browser/history_clusters/history_clusters_tab_helper.cc b/chrome/browser/history_clusters/history_clusters_tab_helper.cc index 84e9145..896f904 100644 --- a/chrome/browser/history_clusters/history_clusters_tab_helper.cc +++ b/chrome/browser/history_clusters/history_clusters_tab_helper.cc
@@ -348,10 +348,10 @@ auto* logger = history_clusters::HistoryClustersMetricsLogger::GetOrCreateForPage( navigation_handle->GetWebContents()->GetPrimaryPage()); + // TODO(crbug.com/1326954): Clean up once the metrics are refactored + // to be driven by UI events rather than navigation state. logger->set_final_state( history_clusters::HistoryClustersFinalState::kLinkClick); - if (CanAddURLToHistory(navigation_handle->GetURL())) - logger->IncrementLinksOpenedCount(); } } @@ -408,28 +408,6 @@ logger->set_initial_state(initial_state); } -void HistoryClustersTabHelper::DidOpenRequestedURL( - content::WebContents* new_contents, - content::RenderFrameHost* source_render_frame_host, - const GURL& url, - const content::Referrer& referrer, - WindowOpenDisposition disposition, - ui::PageTransition transition, - bool started_from_context_menu, - bool renderer_initiated) { - // Will detect when a link was followed from the history clusters page in a - // new web contents (e.g. new tab or window). - // And will update this page's associated `HistoryClustersMetricsLogger`. - if (IsHistoryPage(web_contents()->GetLastCommittedURL(), - GURL(chrome::kChromeUIHistoryClustersURL)) && - CanAddURLToHistory(url)) { - auto* logger = - history_clusters::HistoryClustersMetricsLogger::GetOrCreateForPage( - web_contents()->GetPrimaryPage()); - logger->IncrementLinksOpenedCount(); - } -} - void HistoryClustersTabHelper::WebContentsDestroyed() { // Complete any incomplete visits associated with navigations made in this // tab.
diff --git a/chrome/browser/history_clusters/history_clusters_tab_helper.h b/chrome/browser/history_clusters/history_clusters_tab_helper.h index 7adb9c9..b5cf172 100644 --- a/chrome/browser/history_clusters/history_clusters_tab_helper.h +++ b/chrome/browser/history_clusters/history_clusters_tab_helper.h
@@ -63,14 +63,6 @@ content::NavigationHandle* navigation_handle) override; void DidFinishNavigation( content::NavigationHandle* navigation_handle) override; - void DidOpenRequestedURL(content::WebContents* new_contents, - content::RenderFrameHost* source_render_frame_host, - const GURL& url, - const content::Referrer& referrer, - WindowOpenDisposition disposition, - ui::PageTransition transition, - bool started_from_context_menu, - bool renderer_initiated) override; void WebContentsDestroyed() override; private:
diff --git a/chrome/browser/paint_preview/services/paint_preview_tab_service.cc b/chrome/browser/paint_preview/services/paint_preview_tab_service.cc index 808bf5a..1e789ad 100644 --- a/chrome/browser/paint_preview/services/paint_preview_tab_service.cc +++ b/chrome/browser/paint_preview/services/paint_preview_tab_service.cc
@@ -294,7 +294,7 @@ auto* rfh = content::RenderFrameHost::FromID(task->frame_routing_id()); if (!contents || !rfh || contents->IsBeingDestroyed() || contents->GetMainFrame() != rfh || !rfh->IsActive() || - !rfh->IsRenderFrameCreated() || !rfh->IsRenderFrameLive()) { + !rfh->IsRenderFrameLive()) { task->OnCaptured(Status::kWebContentsGone); return; }
diff --git a/chrome/browser/policy/networking/network_configuration_updater_ash_unittest.cc b/chrome/browser/policy/networking/network_configuration_updater_ash_unittest.cc index f2fcbc0..30a297e 100644 --- a/chrome/browser/policy/networking/network_configuration_updater_ash_unittest.cc +++ b/chrome/browser/policy/networking/network_configuration_updater_ash_unittest.cc
@@ -20,6 +20,7 @@ #include "chrome/browser/policy/networking/device_network_configuration_updater_ash.h" #include "chrome/browser/policy/networking/user_network_configuration_updater_ash.h" #include "chrome/test/base/testing_profile.h" +#include "chromeos/ash/components/network/onc/onc_certificate_importer.h" #include "chromeos/components/onc/certificate_scope.h" #include "chromeos/components/onc/onc_parsed_certificates.h" #include "chromeos/components/onc/onc_test_utils.h" @@ -27,7 +28,6 @@ #include "chromeos/dbus/session_manager/session_manager_client.h" #include "chromeos/network/fake_network_device_handler.h" #include "chromeos/network/mock_managed_network_configuration_handler.h" -#include "chromeos/network/onc/onc_certificate_importer.h" #include "chromeos/network/policy_certificate_provider.h" #include "chromeos/system/fake_statistics_provider.h" #include "chromeos/system/statistics_provider.h"
diff --git a/chrome/browser/policy/networking/user_network_configuration_updater_ash.cc b/chrome/browser/policy/networking/user_network_configuration_updater_ash.cc index 226aa8a..621979cd 100644 --- a/chrome/browser/policy/networking/user_network_configuration_updater_ash.cc +++ b/chrome/browser/policy/networking/user_network_configuration_updater_ash.cc
@@ -17,12 +17,12 @@ #include "chrome/browser/net/nss_service.h" #include "chrome/browser/net/nss_service_factory.h" #include "chrome/browser/profiles/profile.h" +#include "chromeos/ash/components/network/onc/network_onc_utils.h" +#include "chromeos/ash/components/network/onc/onc_certificate_importer_impl.h" #include "chromeos/components/onc/onc_parsed_certificates.h" #include "chromeos/components/onc/onc_utils.h" #include "chromeos/network/managed_network_configuration_handler.h" #include "chromeos/network/network_cert_loader.h" -#include "chromeos/network/onc/network_onc_utils.h" -#include "chromeos/network/onc/onc_certificate_importer_impl.h" #include "components/policy/policy_constants.h" #include "components/user_manager/user.h" #include "content/public/browser/browser_task_traits.h"
diff --git a/chrome/browser/policy/test/policy_certs_browsertest.cc b/chrome/browser/policy/test/policy_certs_browsertest.cc index 8a04699..f285894b2 100644 --- a/chrome/browser/policy/test/policy_certs_browsertest.cc +++ b/chrome/browser/policy/test/policy_certs_browsertest.cc
@@ -27,10 +27,10 @@ #include "chrome/browser/ui/browser_list.h" #include "chrome/common/chrome_paths.h" #include "chrome/test/base/in_process_browser_test.h" +#include "chromeos/ash/components/network/onc/onc_certificate_importer.h" +#include "chromeos/ash/components/network/onc/onc_certificate_importer_impl.h" #include "chromeos/components/onc/onc_test_utils.h" #include "chromeos/network/network_cert_loader.h" -#include "chromeos/network/onc/onc_certificate_importer.h" -#include "chromeos/network/onc/onc_certificate_importer_impl.h" #include "chromeos/test/chromeos_test_utils.h" #include "components/onc/onc_constants.h" #include "components/policy/core/browser/browser_policy_connector.h"
diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc index 10ed54b..8f3e3bc 100644 --- a/chrome/browser/prefs/browser_prefs.cc +++ b/chrome/browser/prefs/browser_prefs.cc
@@ -750,6 +750,12 @@ const char kColorModeThemed[] = "ash.dark_mode.color_mode_themed"; #endif // BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS_ASH) +// Deprecated 05/2022. +const char kNativeBridge64BitSupportExperimentEnabled[] = + "arc.native_bridge_64bit_support_experiment"; +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + // Register local state used only for migration (clearing or moving to a new // key). void RegisterLocalStatePrefsForMigration(PrefRegistrySimple* registry) { @@ -798,6 +804,11 @@ #if !BUILDFLAG(IS_ANDROID) registry->RegisterIntegerPref(kStabilityRendererLaunchCount, 0); #endif // !BUILDFLAG(IS_ANDROID) + +#if BUILDFLAG(IS_CHROMEOS_ASH) + registry->RegisterBooleanPref(kNativeBridge64BitSupportExperimentEnabled, + false); +#endif // BUILDFLAG(IS_CHROMEOS_ASH) } // Register prefs used only for migration (clearing or moving to a new key). @@ -1652,6 +1663,11 @@ local_state->ClearPref(prefs::kTabFreezingEnabled); #endif +#if BUILDFLAG(IS_CHROMEOS_ASH) + // Added 05/2022. + local_state->ClearPref(kNativeBridge64BitSupportExperimentEnabled); +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + // Please don't delete the following line. It is used by PRESUBMIT.py. // END_MIGRATE_OBSOLETE_LOCAL_STATE_PREFS
diff --git a/chrome/browser/resources/chromeos/accessibility/accessibility_common/BUILD.gn b/chrome/browser/resources/chromeos/accessibility/accessibility_common/BUILD.gn index 1b2f0c5..439f9d35 100644 --- a/chrome/browser/resources/chromeos/accessibility/accessibility_common/BUILD.gn +++ b/chrome/browser/resources/chromeos/accessibility/accessibility_common/BUILD.gn
@@ -42,6 +42,7 @@ "dictation/earcons/audio_end.wav", "dictation/earcons/audio_initiate.wav", "dictation/earcons/null_selection.wav", + "dictation/focus_handler.js", "dictation/input_controller.js", "dictation/macros/input_text_view_macro.js", "dictation/macros/list_commands_macro.js", @@ -124,6 +125,7 @@ "dictation/dictation_test.js", "dictation/dictation_test_base.js", "dictation/dictation_ui_test.js", + "dictation/focus_handler_test.js", "dictation/macros/dictation_macros_test.js", "dictation/parse/dictation_parse_test.js", "magnifier/magnifier_test.js", @@ -200,6 +202,7 @@ js_library("dictation") { sources = [ "dictation/dictation.js" ] deps = [ + ":dictation_focus_handler", ":dictation_input_controller", ":dictation_metrics", ":dictation_ui_controller", @@ -214,10 +217,6 @@ js_library("dictation_input_controller") { sources = [ "dictation/input_controller.js" ] - deps = [ - "../common:automation_predicate", - "../common:constants", - ] externs_list = [ "$externs_path/input_method_private.js", "$externs_path/language_settings_private.js", @@ -270,3 +269,12 @@ "$externs_path/speech_recognition_private.js", ] } + +js_library("dictation_focus_handler") { + sources = [ "dictation/focus_handler.js" ] + deps = [ + "../common:automation_predicate", + "../common:constants", + ] + externs_list = [ "$externs_path/automation.js" ] +}
diff --git a/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/dictation.js b/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/dictation.js index a7017c2cc..68a0981 100644 --- a/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/dictation.js +++ b/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/dictation.js
@@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import {FocusHandler} from '/accessibility_common/dictation/focus_handler.js'; import {InputController} from '/accessibility_common/dictation/input_controller.js'; import {Macro} from '/accessibility_common/dictation/macros/macro.js'; import {MacroName} from '/accessibility_common/dictation/macros/macro_names.js'; @@ -65,6 +66,9 @@ /** @private {boolean} */ this.isPumpkinEnabled_ = false; + /** @private {?FocusHandler} */ + this.focusHandler_ = null; + this.initialize_(); } @@ -73,8 +77,9 @@ * @private */ initialize_() { - this.inputController_ = - new InputController(() => this.stopDictation_(/*notify=*/ true)); + this.focusHandler_ = new FocusHandler(); + this.inputController_ = new InputController( + () => this.stopDictation_(/*notify=*/ true), this.focusHandler_); this.uiController_ = new UIController(); this.speechParser_ = new SpeechParser(this.inputController_); if (this.localePref_) { @@ -213,6 +218,7 @@ /** * Called when the Speech Recognition engine receives a recognition event. * @param {ResultEvent} event + * @return {!Promise} * @private */ async onSpeechRecognitionResult_(event) { @@ -233,6 +239,7 @@ * @param {string} transcript * @param {boolean} isFinal Whether this is a finalized transcript or an * interim result. + * @return {!Promise} * @private */ async processSpeechRecognitionResult_(transcript, isFinal) { @@ -295,6 +302,7 @@ this.uiController_.setState( UIState.STANDBY, {context: HintContext.STANDBY}); + this.focusHandler_.refresh(); } /**
diff --git a/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/dictation_test_base.js b/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/dictation_test_base.js index f660e19..a15e9314 100644 --- a/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/dictation_test_base.js +++ b/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/dictation_test_base.js
@@ -92,6 +92,8 @@ #include "base/command_line.h" #include "chrome/browser/ash/accessibility/accessibility_manager.h" #include "ui/accessibility/accessibility_features.h" +#include "components/prefs/pref_service.h" +#include "ash/constants/ash_pref_names.h" `); } @@ -99,6 +101,9 @@ testGenPreamble() { super.testGenPreamble(); GEN(` + browser()->profile()->GetPrefs()->SetBoolean( + ash::prefs::kDictationAcceleratorDialogHasBeenAccepted, true); + base::OnceClosure load_cb = base::BindOnce(&ash::AccessibilityManager::SetDictationEnabled, base::Unretained(ash::AccessibilityManager::Get()), @@ -196,6 +201,7 @@ /** * Checks that the latest IME commit text matches the expected value. * @param {string} expected + * @return {!Promise} */ async assertCommittedText(expected) { if (!this.mockInputIme.getLastCommittedParameters()) { @@ -217,6 +223,7 @@ /** * Async function to get a preference value from Settings. * @param {string} name + * @return {!Promise<*>} */ async getPref(name) { return new Promise(resolve => { @@ -229,6 +236,7 @@ /** * Async function to set a preference value in Settings. * @param {string} name + * @return {!Promise} */ async setPref(name, value) { return new Promise(resolve => { @@ -307,6 +315,7 @@ * Waits for the updateDictationBubble() API to be called with the given * properties. * @param {DictationBubbleProperties} targetProps + * @return {!Promise} */ async waitForUIProperties(targetProps) { // Poll until the updateDictationBubble() API gets called with @@ -321,7 +330,7 @@ clearInterval(intervalId); resolve(); } - }); + }, 100); }); }
diff --git a/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/focus_handler.js b/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/focus_handler.js new file mode 100644 index 0000000..3669fa2ec --- /dev/null +++ b/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/focus_handler.js
@@ -0,0 +1,109 @@ +// 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 AutomationNode = chrome.automation.AutomationNode; +const AutomationEvent = chrome.automation.AutomationEvent; +const EventType = chrome.automation.EventType; + +export class FocusHandler { + constructor() { + /** @private {boolean} */ + this.active_ = false; + + /** + * The currently focused editable node. + * @private {?AutomationNode} + */ + this.editableNode_ = null; + + /** @private {?number} */ + this.deactivateTimeoutId_ = null; + + /** @private {?EventHandler} */ + this.eventHandler_ = null; + } + + /** + * Starts listening to focus events and sets a timeout to deactivate after + * a certain amount of inactivity. + * @return {!Promise} + */ + async refresh() { + if (this.deactivateTimeoutId_ !== null) { + clearTimeout(this.deactivateTimeoutId_); + } + this.deactivateTimeoutId_ = setTimeout( + () => this.deactivate_(), FocusHandler.DEACTIVATE_TIMEOUT_MS_); + + await this.activate_(); + } + + /** + * Gets the current focus and starts listening for focus events. + * @private + * @return {!Promise} + */ + async activate_() { + if (this.active_) { + return; + } + + const desktop = + await new Promise(resolve => chrome.automation.getDesktop(resolve)); + + const focus = + await new Promise(resolve => chrome.automation.getFocus(resolve)); + if (focus && AutomationPredicate.editText(focus)) { + this.editableNode_ = focus; + } + + if (!this.eventHandler_) { + this.eventHandler_ = new EventHandler( + [], EventType.FOCUS, event => this.onFocusChanged_(event)); + } + this.eventHandler_.setNodes(desktop); + this.eventHandler_.start(); + + this.active_ = true; + } + + /** @private */ + deactivate_() { + this.eventHandler_.stop(); + this.eventHandler_ = null; + this.active_ = false; + this.editableNode_ = null; + } + + /** + * Saves the focused node if it's an editable. + * @param {!AutomationEvent} event + * @private + */ + onFocusChanged_(event) { + const node = event.target; + if (!node || !AutomationPredicate.editText(node)) { + this.editableNode_ = null; + return; + } + + this.editableNode_ = node; + } + + /** @return {?AutomationNode} */ + getEditableNode() { + return this.editableNode_; + } + + /** @return {boolean} */ + isReadyForTesting() { + return this.active_ && this.editableNode_ !== null; + } +} + +/** + * @const {number} + * @private + */ +FocusHandler.DEACTIVATE_TIMEOUT_MS_ = 45 * 1000;
diff --git a/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/focus_handler_test.js b/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/focus_handler_test.js new file mode 100644 index 0000000..378e11a --- /dev/null +++ b/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/focus_handler_test.js
@@ -0,0 +1,121 @@ +// 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. + +GEN_INCLUDE(['dictation_test_base.js']); + +DictationFocusHandlerTest = class extends DictationE2ETestBase { + /** @override */ + async setUpDeferred() { + await super.setUpDeferred(); + await importModule( + 'FocusHandler', '/accessibility_common/dictation/focus_handler.js'); + } + + /** @return {!FocusHandler} */ + getFocusHandler() { + return accessibilityCommon.dictation_.focusHandler_; + } + + /** @return {!Promise} */ + async activateFocusHandler() { + await this.getFocusHandler().refresh(); + assertTrue(this.getFocusHandler().active_); + assertNotNullNorUndefined(this.getFocusHandler().deactivateTimeoutId_); + } + + /** + * @param {boolean} active + * @return {!Promise} + */ + async waitForFocusHandlerActive(active) { + return new Promise(resolve => { + const intervalId = setInterval(() => { + if (this.getFocusHandler().active_ === active) { + clearInterval(intervalId); + resolve(); + } + }, 100); + }); + } + + /** + * @param {!AutomationNode} target + * @return {!Promise} + */ + async waitForFocus(target) { + return new Promise(resolve => { + const intervalId = setInterval(() => { + if (this.getFocusHandler().editableNode_ === target) { + clearInterval(intervalId); + resolve(); + } + }, 100); + }); + } + + /** @return {string} */ + simpleSite() { + return ` + <button autofocus>Start</button> + <input id="first" type="text"></input> + `; + } +}; + +// This test ensures that FocusHandler activates when Dictation is toggled on. +SYNC_TEST_F('DictationFocusHandlerTest', 'Activate', async function() { + const root = await this.runWithLoadedTree(this.simpleSite()); + const input = root.find({role: chrome.automation.RoleType.TEXT_FIELD}); + assertTrue(Boolean(input)); + + // FocusHandler should not be activated until Dictation is toggled on. + assertFalse(this.getFocusHandler().active_); + assertEquals(null, this.getFocusHandler().editableNode_); + input.focus(); + this.toggleDictationOn(); + await this.waitForFocusHandlerActive(true); +}); + +// This test ensures that FocusHandler deactivates automatically after a +// period of inactivity. +SYNC_TEST_F('DictationFocusHandlerTest', 'Deactivate', async function() { + // Shorten timeout for testing. + FocusHandler.DEACTIVATE_TIMEOUT_MS_ = 1000; + await this.activateFocusHandler(); + await this.waitForFocusHandlerActive(false); +}); + +// This test ensures that FocusHandler tracks focus once it's been activated. +SYNC_TEST_F('DictationFocusHandlerTest', 'OnFocusChanged', async function() { + await this.activateFocusHandler(); + const root = await this.runWithLoadedTree(this.simpleSite()); + const input = root.find({role: chrome.automation.RoleType.TEXT_FIELD}); + assertTrue(Boolean(input)); + + input.focus(); + await this.waitForFocus(input); +}); + +// This test ensures that the timeout to deactivate FocusHandler is reset +// whenever Dictation toggles on. +SYNC_TEST_F( + 'DictationFocusHandlerTest', 'ResetDeactivateTimeout', async function() { + this.mockSetTimeoutMethod(); + this.toggleDictationOn(); + await this.waitForFocusHandlerActive(true); + let callback = + this.getCallbackWithDelay(FocusHandler.DEACTIVATE_TIMEOUT_MS_); + assertNotNullNorUndefined(callback); + + this.clearSetTimeoutData(); + this.toggleDictationOff(); + this.toggleDictationOn(); + // Toggling Dictation on should set a new timeout to deactivate + // FocusHandler. + callback = this.getCallbackWithDelay(FocusHandler.DEACTIVATE_TIMEOUT_MS_); + assertNotNullNorUndefined(callback); + // Running `callback` should deactivate FocusHandler. + callback(); + await this.waitForFocusHandlerActive(false); + });
diff --git a/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/input_controller.js b/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/input_controller.js index 7c3d268..15c10a175 100644 --- a/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/input_controller.js +++ b/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/input_controller.js
@@ -2,19 +2,19 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -const AutomationNode = chrome.automation.AutomationNode; -const AutomationEvent = chrome.automation.AutomationEvent; -const EventType = chrome.automation.EventType; const IconType = chrome.accessibilityPrivate.DictationBubbleIconType; /** * InputController handles interaction with input fields for Dictation. */ export class InputController { - constructor(stopDictationCallback) { + constructor(stopDictationCallback, focusHandler) { /** @private {number} */ this.activeImeContextId_ = InputController.NO_ACTIVE_IME_CONTEXT_ID_; + /** @private {!FocusHandler} */ + this.focusHandler_ = focusHandler; + /** * The engine ID of the previously active IME input method. Used to * restore the previous IME after Dictation is deactivated. @@ -28,15 +28,6 @@ /** @private {?function():void} */ this.onConnectCallback_ = null; - /** - * The currently focused editable node. - * @private {?AutomationNode} - */ - this.editableNode_ = null; - - /** @private {?EventHandler} */ - this.focusHandler_ = null; - this.initialize_(); } @@ -50,16 +41,6 @@ (context) => this.onImeFocus_(context)); chrome.input.ime.onBlur.addListener( (contextId) => this.onImeBlur_(contextId)); - - // IME focus and blur listeners do not tell us which AutomationNode is - // currently focused. Register a focus event handler that will give us this - // information. - this.focusHandler_ = new EventHandler( - [], EventType.FOCUS, event => this.onFocusChanged_(event)); - chrome.automation.getDesktop((desktop) => { - this.focusHandler_.setNodes(desktop); - this.focusHandler_.start(); - }); } /** @@ -153,20 +134,6 @@ } /** - * @param {!AutomationEvent} event - * @private - */ - onFocusChanged_(event) { - const node = event.target; - if (!node || !AutomationPredicate.editText(node)) { - this.editableNode_ = null; - return; - } - - this.editableNode_ = node; - } - - /** * @param {string} text * @return {string} */ @@ -177,14 +144,15 @@ // space when committed to a text field. This is a temporary workaround // until the blocking SODA bug can be fixed. Note, a similar strategy // already exists in Dictation::OnSpeechResult(). - if (!this.editableNode_ || + const editableNode = this.focusHandler_.getEditableNode(); + if (!editableNode || InputController.BEGINS_WITH_WHITESPACE_REGEX_.test(text)) { return text; } - const value = this.editableNode_.value; - const selStart = this.editableNode_.textSelStart; - const selEnd = this.editableNode_.textSelEnd; + const value = editableNode.value; + const selStart = editableNode.textSelStart; + const selEnd = editableNode.textSelEnd; // Prepend a space to `text` if there is text directly left of the cursor. if (!selStart || selStart !== selEnd || !value || InputController.BEGINS_WITH_WHITESPACE_REGEX_.test(
diff --git a/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/parse/speech_parser.js b/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/parse/speech_parser.js index aef2ae4..a82d9c0c 100644 --- a/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/parse/speech_parser.js +++ b/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/parse/speech_parser.js
@@ -36,6 +36,7 @@ /** * @param {string} locale The Dictation recognition locale. Only some locales * are supported by Pumpkin. + * @return {!Promise} */ async initialize(locale) { this.isRTLLocale_ = SpeechParser.RTLLocales.has(locale);
diff --git a/chrome/browser/resources/history/history.ts b/chrome/browser/resources/history/history.ts index d14eb35..ddc12a6 100644 --- a/chrome/browser/resources/history/history.ts +++ b/chrome/browser/resources/history/history.ts
@@ -5,8 +5,8 @@ import './app.js'; export {BrowserProxyImpl} from 'chrome://resources/cr_components/history_clusters/browser_proxy.js'; -export {PageCallbackRouter, PageHandlerRemote} from 'chrome://resources/cr_components/history_clusters/history_clusters.mojom-webui.js'; -export {ClusterAction, MetricsProxy, MetricsProxyImpl, RelatedSearchAction, VisitAction, VisitType} from 'chrome://resources/cr_components/history_clusters/metrics_proxy.js'; +export {ClusterAction, PageCallbackRouter, PageHandlerRemote, RelatedSearchAction, VisitAction, VisitType} from 'chrome://resources/cr_components/history_clusters/history_clusters.mojom-webui.js'; +export {MetricsProxy, MetricsProxyImpl} from 'chrome://resources/cr_components/history_clusters/metrics_proxy.js'; export {CrActionMenuElement} from 'chrome://resources/cr_elements/cr_action_menu/cr_action_menu.js'; export {CrDialogElement} from 'chrome://resources/cr_elements/cr_dialog/cr_dialog.m.js'; export {ensureLazyLoaded, HistoryAppElement, listenForPrivilegedLinkClicks} from './app.js';
diff --git a/chrome/browser/resources/settings/chromeos/os_a11y_page/tts_subpage.js b/chrome/browser/resources/settings/chromeos/os_a11y_page/tts_subpage.js index 999cfb6..a75d8ef3 100644 --- a/chrome/browser/resources/settings/chromeos/os_a11y_page/tts_subpage.js +++ b/chrome/browser/resources/settings/chromeos/os_a11y_page/tts_subpage.js
@@ -145,6 +145,7 @@ 'tts-preview-state-changed', isSpeaking => this.onTtsPreviewStateChanged_(isSpeaking)); this.ttsBrowserProxy_.getTtsExtensions(); + this.ttsBrowserProxy_.refreshTtsVoices(); }, /**
diff --git a/chrome/browser/resources/settings/chromeos/os_a11y_page/tts_subpage_browser_proxy.js b/chrome/browser/resources/settings/chromeos/os_a11y_page/tts_subpage_browser_proxy.js index e26f04a..f7eaa44c 100644 --- a/chrome/browser/resources/settings/chromeos/os_a11y_page/tts_subpage_browser_proxy.js +++ b/chrome/browser/resources/settings/chromeos/os_a11y_page/tts_subpage_browser_proxy.js
@@ -32,6 +32,12 @@ * Awakens the tts engine. */ wakeTtsEngine() {} + + /** + * Triggers the TtsPlatform to update its list of voices and relay that update + * through VoicesChanged. + */ + refreshTtsVoices() {} } /** @@ -57,8 +63,13 @@ wakeTtsEngine() { chrome.send('wakeTtsEngine'); } + + /** @override */ + refreshTtsVoices() { + chrome.send('refreshTtsVoices'); + } } // The singleton instance_ is replaced with a test version of this wrapper // during testing. -addSingletonGetter(TtsSubpageBrowserProxyImpl); \ No newline at end of file +addSingletonGetter(TtsSubpageBrowserProxyImpl);
diff --git a/chrome/browser/segmentation_platform/segmentation_platform_profile_observer_unittest.cc b/chrome/browser/segmentation_platform/segmentation_platform_profile_observer_unittest.cc index 8ca0e89b..73fa5fe 100644 --- a/chrome/browser/segmentation_platform/segmentation_platform_profile_observer_unittest.cc +++ b/chrome/browser/segmentation_platform/segmentation_platform_profile_observer_unittest.cc
@@ -33,6 +33,13 @@ MOCK_METHOD(SegmentSelectionResult, GetCachedSegmentResult, (const std::string&)); + MOCK_METHOD(int, + RegisterOnDemandSegmentSelectionCallback, + (const std::string&, const OnDemandSegmentSelectionCallback&)); + MOCK_METHOD(void, + UnregisterOnDemandSegmentSelectionCallback, + (int, const std::string&)); + MOCK_METHOD(void, OnTrigger, (TriggerType, const TriggerContext&)); MOCK_METHOD(void, EnableMetrics, (bool)); MOCK_METHOD(void, GetServiceStatus, ()); MOCK_METHOD(bool, IsPlatformInitialized, ());
diff --git a/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/send_tab_to_self/SendTabToSelfBottomSheetRenderTest.java b/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/send_tab_to_self/SendTabToSelfBottomSheetRenderTest.java new file mode 100644 index 0000000..f6f3c534 --- /dev/null +++ b/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/send_tab_to_self/SendTabToSelfBottomSheetRenderTest.java
@@ -0,0 +1,122 @@ +// 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.share.send_tab_to_self; + +import static org.mockito.Mockito.when; + +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.drawable.Drawable; +import android.view.View; + +import androidx.appcompat.content.res.AppCompatResources; +import androidx.test.filters.MediumTest; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; + +import org.chromium.base.test.util.Feature; +import org.chromium.chrome.browser.profiles.Profile; +import org.chromium.chrome.browser.share.send_tab_to_self.TargetDeviceInfo.DeviceType; +import org.chromium.chrome.browser.signin.services.IdentityServicesProvider; +import org.chromium.chrome.test.ChromeJUnit4ClassRunner; +import org.chromium.components.browser_ui.bottomsheet.BottomSheetController; +import org.chromium.components.signin.base.AccountCapabilities; +import org.chromium.components.signin.base.AccountInfo; +import org.chromium.components.signin.base.CoreAccountId; +import org.chromium.components.signin.identitymanager.ConsentLevel; +import org.chromium.components.signin.identitymanager.IdentityManager; +import org.chromium.components.signin.test.util.R; +import org.chromium.content_public.browser.test.util.TestThreadUtils; +import org.chromium.ui.test.util.BlankUiTestActivityTestCase; +import org.chromium.ui.test.util.RenderTestRule; +import org.chromium.url.JUnitTestGURLs; + +import java.util.Arrays; +import java.util.Calendar; +import java.util.HashMap; +import java.util.List; +import java.util.concurrent.TimeUnit; + +/** Render tests for the send-tab-to-self bottom sheets. */ +@RunWith(ChromeJUnit4ClassRunner.class) +public class SendTabToSelfBottomSheetRenderTest extends BlankUiTestActivityTestCase { + @Rule + public final RenderTestRule mRenderTestRule = + RenderTestRule.Builder.withPublicCorpus() + .setBugComponent(RenderTestRule.Component.UI_BROWSER_SHARING) + .build(); + @Rule + public final MockitoRule mMockitoRule = MockitoJUnit.rule(); + + @Mock + private Profile mProfile; + @Mock + private IdentityServicesProvider mIdentityServicesProvider; + @Mock + private IdentityManager mIdentityManager; + @Mock + private BottomSheetController mBottomSheetController; + + @Test + @MediumTest + @Feature("RenderTest") + public void testDevicePickerBottomSheet() throws Throwable { + AccountInfo account = createFakeAccount(); + when(mIdentityManager.getPrimaryAccountInfo(ConsentLevel.SIGNIN)).thenReturn(account); + when(mIdentityManager.findExtendedAccountInfoByEmailAddress(account.getEmail())) + .thenReturn(account); + when(mIdentityServicesProvider.getIdentityManager(mProfile)).thenReturn(mIdentityManager); + IdentityServicesProvider.setInstanceForTests(mIdentityServicesProvider); + Profile.setLastUsedProfileForTesting(mProfile); + + long todayTimestamp = Calendar.getInstance().getTimeInMillis(); + List<TargetDeviceInfo> devices = Arrays.asList( + new TargetDeviceInfo("My Phone", "guid1", DeviceType.PHONE, todayTimestamp), + new TargetDeviceInfo("My Computer", "guid2", DeviceType.WIN, + todayTimestamp - TimeUnit.DAYS.toMillis(1))); + View view = TestThreadUtils.runOnUiThreadBlockingNoException(() -> { + DevicePickerBottomSheetContent sheetContent = + new DevicePickerBottomSheetContent(getActivity(), JUnitTestGURLs.HTTP_URL, + "Title", mBottomSheetController, devices); + getActivity().setContentView(sheetContent.getContentView()); + return sheetContent.getContentView(); + }); + mRenderTestRule.render(view, "device_picker"); + } + + @Test + @MediumTest + @Feature("RenderTest") + public void testNoTargetDeviceBottomSheet() throws Throwable { + View view = TestThreadUtils.runOnUiThreadBlockingNoException(() -> { + NoTargetDeviceBottomSheetContent sheetContent = + new NoTargetDeviceBottomSheetContent(getActivity()); + getActivity().setContentView(sheetContent.getContentView()); + return sheetContent.getContentView(); + }); + mRenderTestRule.render(view, "no_target_device"); + } + + // TODO(crbug.com/1219434): This duplicates the account in AccountManagerTestRule, so tests can + // later adopt the rule without failing the golden diffs. That's not done now because it + // requires changing the device picker to depend on ProfileDataCache instead of IdentityManager. + private AccountInfo createFakeAccount() { + Drawable drawable = + AppCompatResources.getDrawable(getActivity(), R.drawable.test_profile_picture); + Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), + drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888); + Canvas canvas = new Canvas(bitmap); + drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight()); + drawable.draw(canvas); + + return new AccountInfo(new CoreAccountId("id"), "test@gmail.com", "gaiaId", "John Doe", + "John", bitmap, new AccountCapabilities(new HashMap<>())); + } +} \ No newline at end of file
diff --git a/chrome/browser/share/android/test_java_sources.gni b/chrome/browser/share/android/test_java_sources.gni index d43abc7..b1a170d9 100644 --- a/chrome/browser/share/android/test_java_sources.gni +++ b/chrome/browser/share/android/test_java_sources.gni
@@ -11,6 +11,7 @@ "//chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/long_screenshots/bitmap_generation/LongScreenshotsTabServiceTest.java", "//chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/screenshot/ScreenshotShareSheetViewTest.java", "//chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/scroll_capture/ScrollCaptureCallbackRenderTest.java", + "//chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/send_tab_to_self/SendTabToSelfBottomSheetRenderTest.java", "//chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/send_tab_to_self/SendTabToSelfCoordinatorTest.java", "//chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/share_sheet/ChromeProvidedSharingOptionsProviderTest.java", "//chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/share_sheet/ShareSheetBottomSheetContentTest.java",
diff --git a/chrome/browser/speech/extension_api/tts_extension_apitest.cc b/chrome/browser/speech/extension_api/tts_extension_apitest.cc index 184b04f6..bd245f79 100644 --- a/chrome/browser/speech/extension_api/tts_extension_apitest.cc +++ b/chrome/browser/speech/extension_api/tts_extension_apitest.cc
@@ -139,6 +139,8 @@ [](const content::VoiceData& voice) { return !voice.native; }); } + void RefreshVoices() override {} + void GetVoicesForBrowserContext( content::BrowserContext* browser_context, const GURL& source_url,
diff --git a/chrome/browser/speech/tts_chromeos.cc b/chrome/browser/speech/tts_chromeos.cc index 028df481..18443aa 100644 --- a/chrome/browser/speech/tts_chromeos.cc +++ b/chrome/browser/speech/tts_chromeos.cc
@@ -163,6 +163,22 @@ [](const content::VoiceData& voice) { return !voice.native; }); } +void TtsPlatformImplChromeOs::RefreshVoices() { + // Android voices can be updated silently. + // If it happens, we can't return the latest voices here, but below + // eventually calls TtsController::VoicesChanged. + auto* const arc_service_manager = arc::ArcServiceManager::Get(); + if (!arc_service_manager) + return; + + arc::mojom::TtsInstance* tts = ARC_GET_INSTANCE_FOR_METHOD( + arc_service_manager->arc_bridge_service()->tts(), RefreshVoices); + if (!tts) + return; + + tts->RefreshVoices(); +} + // static TtsPlatformImplChromeOs* TtsPlatformImplChromeOs::GetInstance() {
diff --git a/chrome/browser/speech/tts_chromeos.h b/chrome/browser/speech/tts_chromeos.h index 54d43b0..ce29cfcb 100644 --- a/chrome/browser/speech/tts_chromeos.h +++ b/chrome/browser/speech/tts_chromeos.h
@@ -38,6 +38,7 @@ void SetError(const std::string& error) override; bool IsSpeaking() override; void FinalizeVoiceOrdering(std::vector<content::VoiceData>& voices) override; + void RefreshVoices() override; // Unimplemented. void Pause() override {}
diff --git a/chrome/browser/speech/tts_lacros.h b/chrome/browser/speech/tts_lacros.h index 5ed4644..4c72ef2c 100644 --- a/chrome/browser/speech/tts_lacros.h +++ b/chrome/browser/speech/tts_lacros.h
@@ -58,6 +58,7 @@ content::TtsUtterance* utterance, const content::VoiceData& voice_data) override {} void Shutdown() override {} + void RefreshVoices() override {} private: friend class base::NoDestructor<TtsPlatformImplLacros>;
diff --git a/chrome/browser/ui/android/layouts/java/src/org/chromium/chrome/browser/layouts/LayoutStateProvider.java b/chrome/browser/ui/android/layouts/java/src/org/chromium/chrome/browser/layouts/LayoutStateProvider.java index 20735887..42d429b 100644 --- a/chrome/browser/ui/android/layouts/java/src/org/chromium/chrome/browser/layouts/LayoutStateProvider.java +++ b/chrome/browser/ui/android/layouts/java/src/org/chromium/chrome/browser/layouts/LayoutStateProvider.java
@@ -60,6 +60,12 @@ boolean isLayoutVisible(@LayoutType int layoutType); /** + * @return Whether or not the {@link Layout} is starting to hide. + * @param layoutType whether the {@link Layout} give {@link LayoutType} is starting to hide. + */ + boolean isLayoutStartingToHide(@LayoutType int layoutType); + + /** * Get the type of the layout that is currently active. * @return The {@link LayoutType} of the active layout. */
diff --git a/chrome/browser/ui/app_list/app_service/app_service_app_item.cc b/chrome/browser/ui/app_list/app_service/app_service_app_item.cc index 400b775a..8fcd5ad 100644 --- a/chrome/browser/ui/app_list/app_service/app_service_app_item.cc +++ b/chrome/browser/ui/app_list/app_service/app_service_app_item.cc
@@ -106,7 +106,7 @@ SetPosition(CalculateDefaultPositionIfApplicable()); } - // Crostini apps and the Terminal System App start in the crostini folder. + // Crostini apps start in the crostini folder. if (app_type_ == apps::AppType::kCrostini) { DCHECK(folder_id().empty()); SetChromeFolderId(ash::kCrostiniFolderId);
diff --git a/chrome/browser/ui/app_list/search/files/file_result.cc b/chrome/browser/ui/app_list/search/files/file_result.cc index d6d8958f..363e5d4 100644 --- a/chrome/browser/ui/app_list/search/files/file_result.cc +++ b/chrome/browser/ui/app_list/search/files/file_result.cc
@@ -149,43 +149,16 @@ if (details) SetDetails(details.value()); - // Launcher search results UI is light by default, so use icons for light - // background if dark/light mode feature is not enabled. Productivity launcher - // has dark background by default, so use icons for dark background in that - // case. - const bool dark_background = - ash::features::IsDarkLightModeEnabled() - ? ash::ColorProvider::Get()->IsDarkModeEnabled() - : ash::features::IsProductivityLauncherEnabled(); - if (display_type == DisplayType::kChip) { - SetChipIcon(chromeos::GetChipIconForPath(filepath, dark_background)); - } else if (display_type == DisplayType::kContinue) { - // For Continue Section, if dark/light mode is disabled, we should use the - // icon and not the chip icon with a dark background as default. - const gfx::ImageSkia chip_icon = - ash::features::IsDarkLightModeEnabled() - ? chromeos::GetChipIconForPath(filepath, dark_background) - : chromeos::GetIconForPath(filepath, /*dark_background=*/true); - SetChipIcon(chip_icon); - } else { - switch (type) { - case Type::kFile: - SetIcon(IconInfo(chromeos::GetIconForPath(filepath, dark_background), - kSystemIconDimension)); - break; - case Type::kDirectory: - SetIcon(IconInfo(chromeos::GetIconFromType("folder", dark_background), - kSystemIconDimension)); - break; - case Type::kSharedDirectory: - SetIcon(IconInfo(chromeos::GetIconFromType("shared", dark_background), - kSystemIconDimension)); - break; - } - } + UpdateIcon(); + + if (ash::ColorProvider::Get()) + ash::ColorProvider::Get()->AddObserver(this); } -FileResult::~FileResult() = default; +FileResult::~FileResult() { + if (ash::ColorProvider::Get()) + ash::ColorProvider::Get()->RemoveObserver(this); +} void FileResult::Open(int event_flags) { switch (type_) { @@ -253,6 +226,10 @@ weak_factory_.GetWeakPtr())); } +void FileResult::OnColorModeChanged(bool dark_mode_enabled) { + UpdateIcon(); +} + void FileResult::OnThumbnailLoaded(const SkBitmap* bitmap, base::File::Error error) { if (!bitmap) { @@ -278,6 +255,46 @@ weak_factory_.GetWeakPtr())); } +void FileResult::UpdateIcon() { + // Launcher search results UI is light by default, so use icons for light + // background if dark/light mode feature is not enabled. Productivity launcher + // has dark background by default, so use icons for dark background in that + // case. + const bool is_dark_light_enabled = ash::features::IsDarkLightModeEnabled(); + // ColorProvider might be nullptr in tests. + auto* color_provider = ash::ColorProvider::Get(); + const bool dark_background = + is_dark_light_enabled + ? color_provider && color_provider->IsDarkModeEnabled() + : ash::features::IsProductivityLauncherEnabled(); + if (display_type() == DisplayType::kChip) { + SetChipIcon(chromeos::GetChipIconForPath(filepath_, dark_background)); + } else if (display_type() == DisplayType::kContinue) { + // For Continue Section, if dark/light mode is disabled, we should use the + // icon and not the chip icon with a dark background as default. + const gfx::ImageSkia chip_icon = + is_dark_light_enabled + ? chromeos::GetChipIconForPath(filepath_, dark_background) + : chromeos::GetIconForPath(filepath_, /*dark_background=*/true); + SetChipIcon(chip_icon); + } else { + switch (type_) { + case Type::kFile: + SetIcon(IconInfo(chromeos::GetIconForPath(filepath_, dark_background), + kSystemIconDimension)); + break; + case Type::kDirectory: + SetIcon(IconInfo(chromeos::GetIconFromType("folder", dark_background), + kSystemIconDimension)); + break; + case Type::kSharedDirectory: + SetIcon(IconInfo(chromeos::GetIconFromType("shared", dark_background), + kSystemIconDimension)); + break; + } + } +} + void FileResult::OnJustificationStringReturned( absl::optional<std::u16string> justification) { if (justification)
diff --git a/chrome/browser/ui/app_list/search/files/file_result.h b/chrome/browser/ui/app_list/search/files/file_result.h index cdb0bfe32..ddf4a09 100644 --- a/chrome/browser/ui/app_list/search/files/file_result.h +++ b/chrome/browser/ui/app_list/search/files/file_result.h
@@ -7,6 +7,7 @@ #include <iosfwd> +#include "ash/public/cpp/style/color_mode_observer.h" #include "base/files/file.h" #include "base/files/file_path.h" #include "chrome/browser/ui/app_list/search/chrome_search_result.h" @@ -24,7 +25,7 @@ // TODO(crbug.com/1258415): We should split this into four subclasses: // {drive,local} {zero-state,search}. -class FileResult : public ChromeSearchResult { +class FileResult : public ChromeSearchResult, public ash::ColorModeObserver { public: enum class Type { kFile, kDirectory, kSharedDirectory }; @@ -67,6 +68,9 @@ } private: + // ash::ColorModeObserver: + void OnColorModeChanged(bool dark_mode_enabled) override; + // Callback for the result of RequestThumbnail's call to the ThumbnailLoader. void OnThumbnailLoaded(const SkBitmap* bitmap, base::File::Error error); @@ -75,6 +79,8 @@ void OnJustificationStringReturned( absl::optional<std::u16string> justification); + void UpdateIcon(); + const base::FilePath filepath_; const Type type_; Profile* const profile_;
diff --git a/chrome/browser/ui/app_list/search/omnibox_answer_result.cc b/chrome/browser/ui/app_list/search/omnibox_answer_result.cc index 77c1baa..2ba346a1 100644 --- a/chrome/browser/ui/app_list/search/omnibox_answer_result.cc +++ b/chrome/browser/ui/app_list/search/omnibox_answer_result.cc
@@ -47,9 +47,12 @@ ChromeSearchResult::IconInfo CreateAnswerIconInfo( const gfx::VectorIcon& vector_icon) { const int dimension = GetAnswerCardIconDimension(); - const bool dark_mode = ash::features::IsProductivityLauncherEnabled() || - (ash::features::IsDarkLightModeEnabled() && - ash::ColorProvider::Get()->IsDarkModeEnabled()); + // ColorProvider might be nullptr in tests. + const bool dark_mode = + ash::features::IsProductivityLauncherEnabled() || + (ash::features::IsDarkLightModeEnabled() && ash::ColorProvider::Get() && + ash::ColorProvider::Get()->IsDarkModeEnabled()); + const auto icon = dark_mode ? gfx::ImageSkiaOperations::CreateImageWithCircleBackground( dimension / 2, gfx::kGoogleBlue300, @@ -195,15 +198,25 @@ } else { UpdateClassicTitleAndDetails(); } + if (ash::ColorProvider::Get()) + ash::ColorProvider::Get()->AddObserver(this); } -OmniboxAnswerResult::~OmniboxAnswerResult() = default; +OmniboxAnswerResult::~OmniboxAnswerResult() { + if (ash::ColorProvider::Get()) + ash::ColorProvider::Get()->RemoveObserver(this); +} void OmniboxAnswerResult::Open(int event_flags) { list_controller_->OpenURL(profile_, match_.destination_url, match_.transition, ui::DispositionFromEventFlags(event_flags)); } +void OmniboxAnswerResult::OnColorModeChanged(bool dark_mode_enabled) { + if (!IsWeatherResult()) + UpdateIcon(); +} + void OmniboxAnswerResult::UpdateIcon() { if (IsCalculatorResult()) { SetIcon(CreateAnswerIconInfo(omnibox::kCalculatorIcon));
diff --git a/chrome/browser/ui/app_list/search/omnibox_answer_result.h b/chrome/browser/ui/app_list/search/omnibox_answer_result.h index 623ce49b..73534a05 100644 --- a/chrome/browser/ui/app_list/search/omnibox_answer_result.h +++ b/chrome/browser/ui/app_list/search/omnibox_answer_result.h
@@ -5,6 +5,7 @@ #ifndef CHROME_BROWSER_UI_APP_LIST_SEARCH_OMNIBOX_ANSWER_RESULT_H_ #define CHROME_BROWSER_UI_APP_LIST_SEARCH_OMNIBOX_ANSWER_RESULT_H_ +#include "ash/public/cpp/style/color_mode_observer.h" #include "base/memory/weak_ptr.h" #include "chrome/browser/bitmap_fetcher/bitmap_fetcher_delegate.h" #include "chrome/browser/ui/app_list/search/chrome_search_result.h" @@ -21,7 +22,8 @@ // cards at the top of the categorical search launcher, so are separated in the // UI from other Omnibox results. class OmniboxAnswerResult : public ChromeSearchResult, - public BitmapFetcherDelegate { + public BitmapFetcherDelegate, + public ash::ColorModeObserver { public: OmniboxAnswerResult(Profile* profile, AppListControllerDelegate* list_controller, @@ -40,6 +42,9 @@ void OnFetchComplete(const GURL& url, const SkBitmap* bitmap) override; private: + // ash::ColorModeObserver: + void OnColorModeChanged(bool dark_mode_enabled) override; + void UpdateIcon(); // Updates title and details for the productivity launcher. void UpdateTitleAndDetails();
diff --git a/chrome/browser/ui/ash/system_tray_client_impl.cc b/chrome/browser/ui/ash/system_tray_client_impl.cc index 8bbc3c6..c7fb7a28 100644 --- a/chrome/browser/ui/ash/system_tray_client_impl.cc +++ b/chrome/browser/ui/ash/system_tray_client_impl.cc
@@ -56,13 +56,13 @@ #include "chrome/browser/upgrade_detector/upgrade_detector.h" #include "chrome/browser/web_applications/web_app_id_constants.h" #include "chrome/common/url_constants.h" +#include "chromeos/ash/components/network/onc/network_onc_utils.h" #include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/dbus/session_manager/session_manager_client.h" #include "chromeos/network/network_handler.h" #include "chromeos/network/network_state.h" #include "chromeos/network/network_state_handler.h" #include "chromeos/network/network_util.h" -#include "chromeos/network/onc/network_onc_utils.h" #include "chromeos/network/tether_constants.h" #include "components/session_manager/core/session_manager.h" #include "components/session_manager/core/session_manager_observer.h"
diff --git a/chrome/browser/ui/extensions/OWNERS b/chrome/browser/ui/extensions/OWNERS index 9e241ac..e4f2c270 100644 --- a/chrome/browser/ui/extensions/OWNERS +++ b/chrome/browser/ui/extensions/OWNERS
@@ -5,3 +5,4 @@ # Extension-y stuff finnur@chromium.org rdevlin.cronin@chromium.org +emiliapaz@chromium.org
diff --git a/chrome/browser/ui/singleton_tabs.cc b/chrome/browser/ui/singleton_tabs.cc index 98263487..9396744 100644 --- a/chrome/browser/ui/singleton_tabs.cc +++ b/chrome/browser/ui/singleton_tabs.cc
@@ -35,11 +35,6 @@ Navigate(¶ms); } -void ShowSingletonTabRespectRef(Browser* browser, const GURL& url) { - NavigateParams params(GetSingletonTabNavigateParams(browser, url)); - Navigate(¶ms); -} - void ShowSingletonTabOverwritingNTP(Browser* browser, NavigateParams* params) { DCHECK(browser); DCHECK_EQ(params->disposition, WindowOpenDisposition::SINGLETON_TAB);
diff --git a/chrome/browser/ui/singleton_tabs.h b/chrome/browser/ui/singleton_tabs.h index a69681d..3295a4f 100644 --- a/chrome/browser/ui/singleton_tabs.h +++ b/chrome/browser/ui/singleton_tabs.h
@@ -20,9 +20,6 @@ // is created. void ShowSingletonTab(Browser* browser, const GURL& url); -// Same as ShowSingletonTab, but does not ignore ref. -void ShowSingletonTabRespectRef(Browser* browser, const GURL& url); - // As ShowSingletonTab, but if the current tab is the new tab page or // about:blank, then overwrite it with the passed contents. void ShowSingletonTabOverwritingNTP(Browser* browser, NavigateParams* params);
diff --git a/chrome/browser/ui/views/tabs/tab_drag_controller.cc b/chrome/browser/ui/views/tabs/tab_drag_controller.cc index 3047ed88..fa43f05 100644 --- a/chrome/browser/ui/views/tabs/tab_drag_controller.cc +++ b/chrome/browser/ui/views/tabs/tab_drag_controller.cc
@@ -2516,10 +2516,23 @@ int left_most_selected_x_position = left_most_selected_tab->x() + tab_left_inset; - if ((left_most_selected_x_position <= left_edge - buffer) && - left_group.has_value() && + if (left_group.has_value() && !attached_model->IsGroupCollapsed(left_group.value())) { - return left_group; + // Take the dragged tabs out of left_group if they are at the rightmost edge + // of the tabstrip. This happens when the tabstrip is full and the dragged + // tabs are as far right as they can go without being pulled out into a new + // window. In this case, since the dragged tabs can't move further right in + // the tabstrip, it will never go "beyond" the left_group and therefore + // never leave it unless we add this check. See crbug.com/1134376. + // TODO(crbug/1329344): Update this to work better with Tab Scrolling once + // dragging near the end of the tabstrip is cleaner. + if (attached_context_->GetTabAt(selected.back())->bounds().right() >= + attached_context_->TabDragAreaEndX()) { + return absl::nullopt; + } + + if (left_most_selected_x_position <= left_edge - buffer) + return left_group; } if ((left_most_selected_x_position >= left_edge + buffer) && right_group.has_value() &&
diff --git a/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc b/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc index c1c015a..7dd3710b 100644 --- a/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc +++ b/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc
@@ -913,7 +913,7 @@ EXPECT_EQ(group_model->GetTabGroup(group1)->ListTabs(), gfx::Range(0, 4)); } -// Creates a browser with four tabs. The last tab is in Tab Group 1. The +// Creates a browser with five tabs. The fourth tab is in Tab Group 1. The // second tab is in Tab Group 2. Dragging the third tab over one to the right // will result in the tab joining Tab Group 1. Then dragging the second tab // over one to the right will result in the tab joining Tab Group 1. Then @@ -927,7 +927,7 @@ TabStripModel* model = browser()->tab_strip_model(); TabGroupModel* group_model = model->group_model(); - AddTabsAndResetBrowser(browser(), 3); + AddTabsAndResetBrowser(browser(), 4); tab_groups::TabGroupId group1 = model->AddToNewGroup({3}); model->AddToNewGroup({1}); StopAnimating(tab_strip); @@ -940,7 +940,7 @@ ASSERT_TRUE(ReleaseInput()); StopAnimating(tab_strip); - EXPECT_EQ("0 1 3 2", IDString(model)); + EXPECT_EQ("0 1 3 2 4", IDString(model)); EXPECT_EQ(group_model->GetTabGroup(group1)->ListTabs(), gfx::Range(2, 4)); // Dragging the tab in the first index to the tab in the second index switches @@ -950,7 +950,7 @@ ASSERT_TRUE(ReleaseInput()); StopAnimating(tab_strip); - EXPECT_EQ("0 3 1 2", IDString(model)); + EXPECT_EQ("0 3 1 2 4", IDString(model)); EXPECT_EQ(group_model->GetTabGroup(group1)->ListTabs(), gfx::Range(1, 4)); // Dragging the tab in the zero-th index to the tab in the first index @@ -960,10 +960,37 @@ ASSERT_TRUE(ReleaseInput()); StopAnimating(tab_strip); - EXPECT_EQ("3 0 1 2", IDString(model)); + EXPECT_EQ("3 0 1 2 4", IDString(model)); EXPECT_EQ(group_model->GetTabGroup(group1)->ListTabs(), gfx::Range(0, 4)); } +// Creates a browser with five tabs. The last two tabs are in a Tab Group. +// Dragging the first tab past the last slot should allow it to exit the group. +IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest, + DragSingleTabRightOfRightmostGroup) { + ASSERT_TRUE(browser()->tab_strip_model()->SupportsTabGroups()); + + TabStrip* tab_strip = GetTabStripForBrowser(browser()); + TabStripModel* model = browser()->tab_strip_model(); + TabGroupModel* group_model = model->group_model(); + + AddTabsAndResetBrowser(browser(), 4); + tab_groups::TabGroupId group = model->AddToNewGroup({3, 4}); + StopAnimating(tab_strip); + EnsureFocusToTabStrip(tab_strip); + + // Dragging the first tab past the last slot brings it to the end of the + // tabstrip, where it should not be in a group. + ASSERT_TRUE(PressInput(GetCenterInScreenCoordinates(tab_strip->tab_at(0)))); + ASSERT_TRUE(DragInputTo(GetCenterInScreenCoordinates(tab_strip->tab_at(4)) + + gfx::Vector2d(1, 0))); + ASSERT_TRUE(ReleaseInput()); + StopAnimating(tab_strip); + + EXPECT_EQ("1 2 3 4 0", IDString(model)); + EXPECT_EQ(group_model->GetTabGroup(group)->ListTabs(), gfx::Range(2, 4)); +} + // Creates a browser with four tabs each in its own group. Selecting and // dragging the first and third tabs right at the first tab will result in the // tabs joining the same group as the tab in the second position. Then dragging
diff --git a/chrome/browser/ui/webui/app_management/app_management_page_handler.cc b/chrome/browser/ui/webui/app_management/app_management_page_handler.cc index 2f36872..33bc72f 100644 --- a/chrome/browser/ui/webui/app_management/app_management_page_handler.cc +++ b/chrome/browser/ui/webui/app_management/app_management_page_handler.cc
@@ -68,10 +68,8 @@ app_constants::kLacrosAppId, }; -#if !BUILDFLAG(IS_CHROMEOS) const char kFileHandlingLearnMore[] = "https://support.google.com/chrome/?p=pwa_default_associations"; -#endif #if BUILDFLAG(IS_CHROMEOS_ASH) constexpr char const* kAppIdsWithHiddenStoragePermission[] = { @@ -443,15 +441,16 @@ std::move(run_on_os_login.value())); } -// Speculative fix for crbug.com/1315958 -#if !BUILDFLAG(IS_CHROMEOS) if (update.AppType() == apps::AppType::kWeb) { - auto* provider = - web_app::WebAppProvider::GetForLocalAppsUnchecked(profile_); - const bool fh_enabled = - !provider->registrar().IsAppFileHandlerPermissionBlocked(app->id); std::string file_handling_types; std::string file_handling_types_label; + bool fh_enabled = false; +// Speculative fix for crbug.com/1315958 +#if !BUILDFLAG(IS_CHROMEOS) + auto* provider = + web_app::WebAppProvider::GetForLocalAppsUnchecked(profile_); + fh_enabled = + !provider->registrar().IsAppFileHandlerPermissionBlocked(app->id); if (provider->os_integration_manager().IsFileHandlingAPIAvailable( app->id) && !provider->registrar().IsSystemApp(app->id) && @@ -478,6 +477,10 @@ static_cast<int>(truncated_extensions.size()), "LINK", "#")); } + + app->hide_window_mode = provider->registrar().IsIsolated(app->id); +#endif + absl::optional<GURL> learn_more_url; if (!CanShowDefaultAppAssociationsUi()) learn_more_url = GURL(kFileHandlingLearnMore); @@ -485,10 +488,7 @@ app->file_handling_state = app_management::mojom::FileHandlingState::New( fh_enabled, /*is_managed=*/false, file_handling_types, file_handling_types_label, learn_more_url); - - app->hide_window_mode = provider->registrar().IsIsolated(app->id); } -#endif app->publisher_id = update.PublisherId();
diff --git a/chrome/browser/ui/webui/chromeos/network_ui.cc b/chrome/browser/ui/webui/chromeos/network_ui.cc index f6eb7834..914ad73 100644 --- a/chrome/browser/ui/webui/chromeos/network_ui.cc +++ b/chrome/browser/ui/webui/chromeos/network_ui.cc
@@ -32,6 +32,7 @@ #include "chrome/grit/generated_resources.h" #include "chrome/grit/network_ui_resources.h" #include "chrome/grit/network_ui_resources_map.h" +#include "chromeos/ash/components/network/onc/network_onc_utils.h" #include "chromeos/network/cellular_esim_profile_handler.h" #include "chromeos/network/cellular_esim_profile_handler_impl.h" #include "chromeos/network/cellular_esim_uninstall_handler.h" @@ -42,7 +43,6 @@ #include "chromeos/network/network_device_handler.h" #include "chromeos/network/network_state.h" #include "chromeos/network/network_state_handler.h" -#include "chromeos/network/onc/network_onc_utils.h" #include "chromeos/services/network_config/public/mojom/cros_network_config.mojom.h" #include "chromeos/services/network_health/public/mojom/network_diagnostics.mojom.h" #include "chromeos/services/network_health/public/mojom/network_health.mojom.h"
diff --git a/chrome/browser/ui/webui/chromeos/onc_import_message_handler.cc b/chrome/browser/ui/webui/chromeos/onc_import_message_handler.cc index ddc6867..9c76401 100644 --- a/chrome/browser/ui/webui/chromeos/onc_import_message_handler.cc +++ b/chrome/browser/ui/webui/chromeos/onc_import_message_handler.cc
@@ -14,10 +14,10 @@ #include "chrome/browser/net/nss_service.h" #include "chrome/browser/net/nss_service_factory.h" #include "chrome/browser/profiles/profile.h" +#include "chromeos/ash/components/network/onc/network_onc_utils.h" +#include "chromeos/ash/components/network/onc/onc_certificate_importer_impl.h" #include "chromeos/components/onc/onc_parsed_certificates.h" #include "chromeos/components/onc/onc_utils.h" -#include "chromeos/network/onc/network_onc_utils.h" -#include "chromeos/network/onc/onc_certificate_importer_impl.h" #include "components/onc/onc_constants.h" #include "components/policy/core/browser/policy_conversions.h" #include "content/public/browser/browser_task_traits.h"
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 7938188..d612ba5 100644 --- a/chrome/browser/ui/webui/history_clusters/history_clusters_handler.cc +++ b/chrome/browser/ui/webui/history_clusters/history_clusters_handler.cc
@@ -23,6 +23,7 @@ #include "chrome/browser/ui/browser_finder.h" #include "chrome/common/pref_names.h" #include "components/history/core/browser/history_types.h" +#include "components/history_clusters/core/cluster_metrics_utils.h" #include "components/history_clusters/core/config.h" #include "components/history_clusters/core/features.h" #include "components/history_clusters/core/history_clusters_prefs.h" @@ -345,4 +346,37 @@ page_->OnVisitsRemoved(std::move(visits)); } +void HistoryClustersHandler::RecordVisitAction(mojom::VisitAction visit_action, + uint32_t visit_index, + mojom::VisitType visit_type) { + HistoryClustersMetricsLogger::GetOrCreateForPage( + web_contents_->GetPrimaryPage()) + ->RecordVisitAction(static_cast<VisitAction>(visit_action), visit_index, + static_cast<VisitType>(visit_type)); +} + +void HistoryClustersHandler::RecordClusterAction( + mojom::ClusterAction cluster_action, + uint32_t cluster_index) { + HistoryClustersMetricsLogger::GetOrCreateForPage( + web_contents_->GetPrimaryPage()) + ->RecordClusterAction(static_cast<ClusterAction>(cluster_action), + cluster_index); +} + +void HistoryClustersHandler::RecordRelatedSearchAction( + mojom::RelatedSearchAction action, + uint32_t related_search_index) { + HistoryClustersMetricsLogger::GetOrCreateForPage( + web_contents_->GetPrimaryPage()) + ->RecordRelatedSearchAction(static_cast<RelatedSearchAction>(action), + related_search_index); +} + +void HistoryClustersHandler::RecordToggledVisibility(bool visible) { + HistoryClustersMetricsLogger::GetOrCreateForPage( + web_contents_->GetPrimaryPage()) + ->RecordToggledVisibility(visible); +} + } // namespace history_clusters
diff --git a/chrome/browser/ui/webui/history_clusters/history_clusters_handler.h b/chrome/browser/ui/webui/history_clusters/history_clusters_handler.h index 23bacc5..e2e1559 100644 --- a/chrome/browser/ui/webui/history_clusters/history_clusters_handler.h +++ b/chrome/browser/ui/webui/history_clusters/history_clusters_handler.h
@@ -64,6 +64,14 @@ void RemoveVisits(std::vector<mojom::URLVisitPtr> visits, RemoveVisitsCallback callback) override; void OpenVisitUrlsInTabGroup(std::vector<mojom::URLVisitPtr> visits) override; + void RecordVisitAction(mojom::VisitAction visit_action, + uint32_t visit_index, + mojom::VisitType visit_type) override; + void RecordRelatedSearchAction(mojom::RelatedSearchAction action, + uint32_t related_search_index) override; + void RecordClusterAction(mojom::ClusterAction cluster_action, + uint32_t cluster_index) override; + void RecordToggledVisibility(bool visible) override; // HistoryClustersService::Observer: void OnDebugMessage(const std::string& message) override;
diff --git a/chrome/browser/ui/webui/history_clusters/history_clusters_handler_browsertest.cc b/chrome/browser/ui/webui/history_clusters/history_clusters_handler_browsertest.cc index a3e6652b..6e158b1 100644 --- a/chrome/browser/ui/webui/history_clusters/history_clusters_handler_browsertest.cc +++ b/chrome/browser/ui/webui/history_clusters/history_clusters_handler_browsertest.cc
@@ -5,6 +5,7 @@ #include "chrome/browser/ui/webui/history_clusters/history_clusters_handler.h" #include "base/memory/raw_ptr.h" +#include "base/test/metrics/histogram_tester.h" #include "base/test/scoped_feature_list.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" @@ -91,4 +92,68 @@ ASSERT_EQ(33, tab_strip_model->GetTabCount()); } +IN_PROC_BROWSER_TEST_F(HistoryClustersHandlerBrowserTest, + RecordUIVisitActions) { + auto* tab_strip_model = browser()->tab_strip_model(); + ASSERT_EQ(1, tab_strip_model->GetTabCount()); + + base::HistogramTester histogram_tester; + + handler_->RecordVisitAction(mojom::VisitAction::kClicked, 0, + mojom::VisitType::kNonSRP); + histogram_tester.ExpectBucketCount("History.Clusters.UIActions.Visit.Clicked", + 0, 1); + histogram_tester.ExpectBucketCount( + "History.Clusters.UIActions.nonSRPVisit.Clicked", 0, 1); + + handler_->RecordVisitAction(mojom::VisitAction::kDeleted, 0, + mojom::VisitType::kSRP); + histogram_tester.ExpectBucketCount("History.Clusters.UIActions.Visit.Deleted", + 0, 1); + histogram_tester.ExpectBucketCount( + "History.Clusters.UIActions.SRPVisit.Deleted", 0, 1); +} + +IN_PROC_BROWSER_TEST_F(HistoryClustersHandlerBrowserTest, + RecordUIClusterActions) { + auto* tab_strip_model = browser()->tab_strip_model(); + ASSERT_EQ(1, tab_strip_model->GetTabCount()); + + base::HistogramTester histogram_tester; + + handler_->RecordClusterAction(mojom::ClusterAction::kVisitClicked, 0); + histogram_tester.ExpectUniqueSample( + "History.Clusters.UIActions.Cluster.VisitClicked", 0, 1); + handler_->RecordClusterAction(mojom::ClusterAction::kDeleted, 0); + histogram_tester.ExpectUniqueSample( + "History.Clusters.UIActions.Cluster.Deleted", 0, 1); +} + +IN_PROC_BROWSER_TEST_F(HistoryClustersHandlerBrowserTest, + RecordUIRelatedSearchActions) { + auto* tab_strip_model = browser()->tab_strip_model(); + ASSERT_EQ(1, tab_strip_model->GetTabCount()); + + base::HistogramTester histogram_tester; + + handler_->RecordRelatedSearchAction(mojom::RelatedSearchAction::kClicked, 0); + histogram_tester.ExpectUniqueSample( + "History.Clusters.UIActions.RelatedSearch.Clicked", 0, 1); +} + +IN_PROC_BROWSER_TEST_F(HistoryClustersHandlerBrowserTest, + RecordUIToggledVisibility) { + auto* tab_strip_model = browser()->tab_strip_model(); + ASSERT_EQ(1, tab_strip_model->GetTabCount()); + + base::HistogramTester histogram_tester; + + handler_->RecordToggledVisibility(true); + histogram_tester.ExpectBucketCount( + "History.Clusters.UIActions.ToggledVisiblity", true, 1); + handler_->RecordToggledVisibility(false); + histogram_tester.ExpectBucketCount( + "History.Clusters.UIActions.ToggledVisiblity", false, 1); +} + } // namespace history_clusters
diff --git a/chrome/browser/ui/webui/settings/chromeos/tts_handler.cc b/chrome/browser/ui/webui/settings/chromeos/tts_handler.cc index 0105a30..8e61955f 100644 --- a/chrome/browser/ui/webui/settings/chromeos/tts_handler.cc +++ b/chrome/browser/ui/webui/settings/chromeos/tts_handler.cc
@@ -169,6 +169,9 @@ web_ui()->RegisterMessageCallback( "wakeTtsEngine", base::BindRepeating(&TtsHandler::WakeTtsEngine, base::Unretained(this))); + web_ui()->RegisterMessageCallback( + "refreshTtsVoices", base::BindRepeating(&TtsHandler::RefreshTtsVoices, + base::Unretained(this))); } void TtsHandler::OnJavascriptAllowed() { @@ -204,6 +207,10 @@ OnVoicesChanged(); } +void TtsHandler::RefreshTtsVoices(const base::Value::List& args) { + content::TtsController::GetInstance()->RefreshVoices(); +} + void TtsHandler::RemoveTtsControllerDelegates() { content::TtsController::GetInstance()->RemoveVoicesChangedDelegate(this); content::TtsController::GetInstance()->RemoveUtteranceEventDelegate(this);
diff --git a/chrome/browser/ui/webui/settings/chromeos/tts_handler.h b/chrome/browser/ui/webui/settings/chromeos/tts_handler.h index 411a3fa..2afab95 100644 --- a/chrome/browser/ui/webui/settings/chromeos/tts_handler.h +++ b/chrome/browser/ui/webui/settings/chromeos/tts_handler.h
@@ -45,6 +45,7 @@ private: void WakeTtsEngine(const base::Value::List& args); void OnTtsEngineAwake(bool success); + void RefreshTtsVoices(const base::Value::List& args); int GetVoiceLangMatchScore(const content::VoiceData* voice, const std::string& app_locale); void RemoveTtsControllerDelegates();
diff --git a/chrome/browser/usb/frame_usb_services.cc b/chrome/browser/usb/frame_usb_services.cc index 4dca5c38..57cfdac 100644 --- a/chrome/browser/usb/frame_usb_services.cc +++ b/chrome/browser/usb/frame_usb_services.cc
@@ -8,18 +8,11 @@ #include "build/build_config.h" #include "chrome/browser/usb/usb_tab_helper.h" +#include "content/public/browser/web_contents.h" #include "content/public/common/content_features.h" #include "mojo/public/cpp/bindings/message.h" #include "third_party/blink/public/mojom/permissions_policy/permissions_policy.mojom.h" -#if BUILDFLAG(IS_ANDROID) -#include "chrome/browser/android/usb/web_usb_chooser_android.h" -#else -#include "chrome/browser/ui/browser_finder.h" -#include "chrome/browser/ui/tabs/tab_strip_model.h" -#include "chrome/browser/usb/web_usb_chooser_desktop.h" -#endif // BUILDFLAG(IS_ANDROID) - using content::RenderFrameHost; using content::WebContents; @@ -41,16 +34,6 @@ FrameUsbServices::~FrameUsbServices() = default; -void FrameUsbServices::InitializeWebUsbChooser() { - if (!usb_chooser_) { -#if BUILDFLAG(IS_ANDROID) - usb_chooser_ = std::make_unique<WebUsbChooserAndroid>(&render_frame_host()); -#else - usb_chooser_ = std::make_unique<WebUsbChooserDesktop>(&render_frame_host()); -#endif // BUILDFLAG(IS_ANDROID) - } -} - void FrameUsbServices::InitializeWebUsbService( mojo::PendingReceiver<blink::mojom::WebUsbService> receiver) { if (!AllowedByPermissionsPolicy()) { @@ -58,10 +41,9 @@ return; } - InitializeWebUsbChooser(); if (!web_usb_service_) { - web_usb_service_ = std::make_unique<WebUsbServiceImpl>( - &render_frame_host(), usb_chooser_->GetWeakPtr()); + web_usb_service_ = + std::make_unique<WebUsbServiceImpl>(&render_frame_host()); } web_usb_service_->BindReceiver(std::move(receiver)); }
diff --git a/chrome/browser/usb/frame_usb_services.h b/chrome/browser/usb/frame_usb_services.h index f70d1da..4578a70d 100644 --- a/chrome/browser/usb/frame_usb_services.h +++ b/chrome/browser/usb/frame_usb_services.h
@@ -8,7 +8,6 @@ #include "chrome/browser/usb/web_usb_service_impl.h" #include "content/public/browser/document_user_data.h" #include "content/public/browser/render_frame_host.h" -#include "content/public/browser/web_contents.h" namespace blink { namespace mojom { @@ -16,8 +15,6 @@ } } // namespace blink -class WebUsbChooser; - // Collection of USB-related document-associated services (e.g. // WebUsbServiceImpl) with the lifetime bound to the lifetime of the document. class FrameUsbServices : public content::DocumentUserData<FrameUsbServices> { @@ -33,14 +30,11 @@ friend class content::DocumentUserData<FrameUsbServices>; - void InitializeWebUsbChooser(); - void InitializeWebUsbService( mojo::PendingReceiver<blink::mojom::WebUsbService> receiver); bool AllowedByPermissionsPolicy() const; - std::unique_ptr<WebUsbChooser> usb_chooser_; std::unique_ptr<WebUsbServiceImpl> web_usb_service_; DOCUMENT_USER_DATA_KEY_DECL();
diff --git a/chrome/browser/usb/usb_browsertest.cc b/chrome/browser/usb/usb_browsertest.cc index 057feca..ad9bad5 100644 --- a/chrome/browser/usb/usb_browsertest.cc +++ b/chrome/browser/usb/usb_browsertest.cc
@@ -6,6 +6,7 @@ #include <string> #include <utility> +#include "base/bind.h" #include "base/memory/raw_ptr.h" #include "base/memory/ref_counted.h" #include "base/task/thread_pool/thread_pool_instance.h" @@ -97,15 +98,15 @@ class FakeUsbChooser : public WebUsbChooser { public: - explicit FakeUsbChooser(RenderFrameHost* render_frame_host) - : WebUsbChooser(render_frame_host) {} + FakeUsbChooser() = default; FakeUsbChooser(const FakeUsbChooser&) = delete; FakeUsbChooser& operator=(const FakeUsbChooser&) = delete; - ~FakeUsbChooser() override {} + ~FakeUsbChooser() override = default; - void ShowChooser(std::unique_ptr<UsbChooserController> controller) override { + void ShowChooser(content::RenderFrameHost* render_frame_host, + std::unique_ptr<UsbChooserController> controller) override { // Device list initialization in UsbChooserController may completed before // having a valid view in which case OnOptionsInitialized() has no chance to // be triggered, so select the first option directly if options are ready. @@ -114,15 +115,19 @@ else new FakeChooserView(std::move(controller)); } - - base::WeakPtr<WebUsbChooser> GetWeakPtr() override { - return weak_factory_.GetWeakPtr(); - } - - private: - base::WeakPtrFactory<FakeUsbChooser> weak_factory_{this}; }; +std::unique_ptr<WebUsbChooser> RunChooser( + RenderFrameHost& frame, + std::vector<device::mojom::UsbDeviceFilterPtr> filters, + blink::mojom::WebUsbService::GetPermissionCallback callback) { + auto controller = std::make_unique<UsbChooserController>( + &frame, std::move(filters), std::move(callback)); + auto chooser = std::make_unique<FakeUsbChooser>(); + chooser->ShowChooser(&frame, std::move(controller)); + return chooser; +} + class TestContentBrowserClient : public ChromeContentBrowserClient { public: TestContentBrowserClient() {} @@ -140,9 +145,9 @@ ChromeContentBrowserClient::CreateWebUsbService(render_frame_host, std::move(receiver)); } else { - usb_chooser_ = std::make_unique<FakeUsbChooser>(render_frame_host); - web_usb_service_ = std::make_unique<WebUsbServiceImpl>( - render_frame_host, usb_chooser_->GetWeakPtr()); + web_usb_service_ = std::make_unique<WebUsbServiceImpl>(render_frame_host); + web_usb_service_->SetChooserFactoryForTesting( + base::BindRepeating(&RunChooser)); web_usb_service_->BindReceiver(std::move(receiver)); } } @@ -152,7 +157,6 @@ private: bool use_real_chooser_ = false; std::unique_ptr<WebUsbServiceImpl> web_usb_service_; - std::unique_ptr<WebUsbChooser> usb_chooser_; }; scoped_refptr<device::FakeUsbDeviceInfo> CreateSmartCardDevice() {
diff --git a/chrome/browser/usb/web_usb_chooser.cc b/chrome/browser/usb/web_usb_chooser.cc index efd0f7f8..1388d8d 100644 --- a/chrome/browser/usb/web_usb_chooser.cc +++ b/chrome/browser/usb/web_usb_chooser.cc
@@ -6,38 +6,29 @@ #include <utility> -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/usb/usb_chooser_context.h" -#include "chrome/browser/usb/usb_chooser_context_factory.h" +#include "build/build_config.h" #include "chrome/browser/usb/usb_chooser_controller.h" -#include "content/public/browser/browser_thread.h" -#include "content/public/browser/render_frame_host.h" -#include "content/public/browser/web_contents.h" -#include "services/device/public/mojom/usb_enumeration_options.mojom.h" -WebUsbChooser::WebUsbChooser(content::RenderFrameHost* render_frame_host) - : render_frame_host_(render_frame_host) { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - DCHECK(render_frame_host); +#if BUILDFLAG(IS_ANDROID) +#include "chrome/browser/android/usb/web_usb_chooser_android.h" +#else +#include "chrome/browser/usb/web_usb_chooser_desktop.h" +#endif // BUILDFLAG(IS_ANDROID) + +// static +std::unique_ptr<WebUsbChooser> WebUsbChooser::Create( + content::RenderFrameHost* render_frame_host, + std::unique_ptr<UsbChooserController> controller) { + std::unique_ptr<WebUsbChooser> chooser; +#if BUILDFLAG(IS_ANDROID) + chooser = std::make_unique<WebUsbChooserAndroid>(); +#else + chooser = std::make_unique<WebUsbChooserDesktop>(); +#endif // BUILDFLAG(IS_ANDROID) + chooser->ShowChooser(render_frame_host, std::move(controller)); + return chooser; } -WebUsbChooser::~WebUsbChooser() {} +WebUsbChooser::~WebUsbChooser() = default; -void WebUsbChooser::GetPermission( - std::vector<device::mojom::UsbDeviceFilterPtr> device_filters, - blink::mojom::WebUsbService::GetPermissionCallback callback) { - DCHECK(!render_frame_host_->IsNestedWithinFencedFrame()); - url::Origin origin = - render_frame_host_->GetMainFrame()->GetLastCommittedOrigin(); - auto* profile = - Profile::FromBrowserContext(render_frame_host_->GetBrowserContext()); - auto* context = UsbChooserContextFactory::GetForProfile(profile); - if (!context->CanRequestObjectPermission(origin)) { - std::move(callback).Run(nullptr); - return; - } - - auto controller = std::make_unique<UsbChooserController>( - render_frame_host_, std::move(device_filters), std::move(callback)); - ShowChooser(std::move(controller)); -} +WebUsbChooser::WebUsbChooser() = default;
diff --git a/chrome/browser/usb/web_usb_chooser.h b/chrome/browser/usb/web_usb_chooser.h index 434d1d4..9dfa5b4 100644 --- a/chrome/browser/usb/web_usb_chooser.h +++ b/chrome/browser/usb/web_usb_chooser.h
@@ -6,11 +6,6 @@ #define CHROME_BROWSER_USB_WEB_USB_CHOOSER_H_ #include <memory> -#include <vector> - -#include "base/memory/raw_ptr.h" -#include "base/memory/weak_ptr.h" -#include "third_party/blink/public/mojom/usb/web_usb_service.mojom.h" namespace content { class RenderFrameHost; @@ -22,26 +17,21 @@ // to access a certain device. class WebUsbChooser { public: - explicit WebUsbChooser(content::RenderFrameHost* render_frame_host); + static std::unique_ptr<WebUsbChooser> Create( + content::RenderFrameHost* frame, + std::unique_ptr<UsbChooserController> controller); WebUsbChooser(const WebUsbChooser&) = delete; WebUsbChooser& operator=(const WebUsbChooser&) = delete; virtual ~WebUsbChooser(); - void GetPermission( - std::vector<device::mojom::UsbDeviceFilterPtr> device_filters, - blink::mojom::WebUsbService::GetPermissionCallback callback); + protected: + WebUsbChooser(); virtual void ShowChooser( + content::RenderFrameHost* render_frame_host, std::unique_ptr<UsbChooserController> controller) = 0; - - virtual base::WeakPtr<WebUsbChooser> GetWeakPtr() = 0; - - content::RenderFrameHost* render_frame_host() { return render_frame_host_; } - - private: - const raw_ptr<content::RenderFrameHost> render_frame_host_; }; #endif // CHROME_BROWSER_USB_WEB_USB_CHOOSER_H_
diff --git a/chrome/browser/usb/web_usb_chooser_desktop.cc b/chrome/browser/usb/web_usb_chooser_desktop.cc index 9261616..b717c67 100644 --- a/chrome/browser/usb/web_usb_chooser_desktop.cc +++ b/chrome/browser/usb/web_usb_chooser_desktop.cc
@@ -7,23 +7,15 @@ #include <utility> #include "chrome/browser/ui/browser_dialogs.h" -#include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/usb/usb_chooser_controller.h" -#include "content/public/browser/web_contents.h" -WebUsbChooserDesktop::WebUsbChooserDesktop( - content::RenderFrameHost* render_frame_host) - : WebUsbChooser(render_frame_host) {} +WebUsbChooserDesktop::WebUsbChooserDesktop() = default; WebUsbChooserDesktop::~WebUsbChooserDesktop() = default; void WebUsbChooserDesktop::ShowChooser( + content::RenderFrameHost* render_frame_host, std::unique_ptr<UsbChooserController> controller) { - closure_runner_.RunAndReset(); closure_runner_.ReplaceClosure(chrome::ShowDeviceChooserDialog( - render_frame_host(), std::move(controller))); -} - -base::WeakPtr<WebUsbChooser> WebUsbChooserDesktop::GetWeakPtr() { - return weak_factory_.GetWeakPtr(); + render_frame_host, std::move(controller))); }
diff --git a/chrome/browser/usb/web_usb_chooser_desktop.h b/chrome/browser/usb/web_usb_chooser_desktop.h index 2d6578e1..838fb991 100644 --- a/chrome/browser/usb/web_usb_chooser_desktop.h +++ b/chrome/browser/usb/web_usb_chooser_desktop.h
@@ -14,7 +14,7 @@ // display the permission prompt. class WebUsbChooserDesktop : public WebUsbChooser { public: - explicit WebUsbChooserDesktop(content::RenderFrameHost* render_frame_host); + WebUsbChooserDesktop(); WebUsbChooserDesktop(const WebUsbChooserDesktop&) = delete; WebUsbChooserDesktop& operator=(const WebUsbChooserDesktop&) = delete; @@ -22,14 +22,11 @@ ~WebUsbChooserDesktop() override; // WebUsbChooser implementation - void ShowChooser(std::unique_ptr<UsbChooserController> controller) override; - - base::WeakPtr<WebUsbChooser> GetWeakPtr() override; + void ShowChooser(content::RenderFrameHost* render_frame_host, + std::unique_ptr<UsbChooserController> controller) override; private: - base::ScopedClosureRunner closure_runner_{base::DoNothing()}; - - base::WeakPtrFactory<WebUsbChooserDesktop> weak_factory_{this}; + base::ScopedClosureRunner closure_runner_; }; #endif // CHROME_BROWSER_USB_WEB_USB_CHOOSER_DESKTOP_H_
diff --git a/chrome/browser/usb/web_usb_service_impl.cc b/chrome/browser/usb/web_usb_service_impl.cc index fc252130..0e0a7e4 100644 --- a/chrome/browser/usb/web_usb_service_impl.cc +++ b/chrome/browser/usb/web_usb_service_impl.cc
@@ -15,6 +15,7 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/usb/usb_blocklist.h" #include "chrome/browser/usb/usb_chooser_context_factory.h" +#include "chrome/browser/usb/usb_chooser_controller.h" #include "chrome/browser/usb/usb_tab_helper.h" #include "content/public/browser/browser_thread.h" #include "extensions/buildflags/buildflags.h" @@ -73,6 +74,15 @@ return false; } +std::unique_ptr<WebUsbChooser> RunChooser( + content::RenderFrameHost& frame, + std::vector<device::mojom::UsbDeviceFilterPtr> filters, + WebUsbServiceImpl::GetPermissionCallback callback) { + auto controller = std::make_unique<UsbChooserController>( + &frame, std::move(filters), std::move(callback)); + return WebUsbChooser::Create(&frame, std::move(controller)); +} + } // namespace // A UsbDeviceClient represents a UsbDevice pipe that has been passed to the @@ -126,10 +136,8 @@ }; WebUsbServiceImpl::WebUsbServiceImpl( - content::RenderFrameHost* render_frame_host, - base::WeakPtr<WebUsbChooser> usb_chooser) - : render_frame_host_(render_frame_host), - usb_chooser_(std::move(usb_chooser)) { + content::RenderFrameHost* render_frame_host) + : render_frame_host_(render_frame_host) { DCHECK(render_frame_host_); content::WebContents* web_contents = content::WebContents::FromRenderFrameHost(render_frame_host_); @@ -143,6 +151,8 @@ receivers_.set_disconnect_handler(base::BindRepeating( &WebUsbServiceImpl::OnConnectionError, base::Unretained(this))); + + chooser_factory_ = base::BindRepeating(&RunChooser); } WebUsbServiceImpl::~WebUsbServiceImpl() = default; @@ -162,6 +172,11 @@ permission_observation_.Observe(chooser_context_.get()); } +void WebUsbServiceImpl::SetChooserFactoryForTesting( + ChooserFactoryCallback chooser_factory) { + chooser_factory_ = std::move(chooser_factory); +} + bool WebUsbServiceImpl::HasDevicePermission( const device::mojom::UsbDeviceInfo& device_info) const { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); @@ -316,12 +331,14 @@ void WebUsbServiceImpl::GetPermission( std::vector<device::mojom::UsbDeviceFilterPtr> device_filters, GetPermissionCallback callback) { - if (!usb_chooser_) { + if (!chooser_context_ || + !chooser_context_->CanRequestObjectPermission(origin_)) { std::move(callback).Run(nullptr); return; } - usb_chooser_->GetPermission(std::move(device_filters), std::move(callback)); + usb_chooser_ = chooser_factory_.Run( + *render_frame_host_, std::move(device_filters), std::move(callback)); } void WebUsbServiceImpl::ForgetDevice(const std::string& guid,
diff --git a/chrome/browser/usb/web_usb_service_impl.h b/chrome/browser/usb/web_usb_service_impl.h index 5c1f6be..0a0d708 100644 --- a/chrome/browser/usb/web_usb_service_impl.h +++ b/chrome/browser/usb/web_usb_service_impl.h
@@ -20,7 +20,8 @@ #include "mojo/public/cpp/bindings/receiver_set.h" #include "mojo/public/cpp/bindings/remote_set.h" #include "services/device/public/mojom/usb_device.mojom-forward.h" -#include "third_party/blink/public/mojom/usb/web_usb_service.mojom-forward.h" +#include "services/device/public/mojom/usb_enumeration_options.mojom.h" +#include "third_party/blink/public/mojom/usb/web_usb_service.mojom.h" #include "url/origin.h" namespace content { @@ -38,8 +39,13 @@ public permissions::ObjectPermissionContextBase::PermissionObserver, public UsbChooserContext::DeviceObserver { public: - WebUsbServiceImpl(content::RenderFrameHost* render_frame_host, - base::WeakPtr<WebUsbChooser> usb_chooser); + using ChooserFactoryCallback = + base::RepeatingCallback<std::unique_ptr<WebUsbChooser>( + content::RenderFrameHost&, + std::vector<device::mojom::UsbDeviceFilterPtr>, + WebUsbServiceImpl::GetPermissionCallback)>; + + explicit WebUsbServiceImpl(content::RenderFrameHost* render_frame_host); WebUsbServiceImpl(const WebUsbServiceImpl&) = delete; WebUsbServiceImpl& operator=(const WebUsbServiceImpl&) = delete; @@ -49,6 +55,9 @@ void BindReceiver( mojo::PendingReceiver<blink::mojom::WebUsbService> receiver); + // Allow tests to define and create the WebUsbChooser. + void SetChooserFactoryForTesting(ChooserFactoryCallback chooser_factory); + private: class UsbDeviceClient; @@ -90,7 +99,7 @@ void OnConnectionError(); const raw_ptr<content::RenderFrameHost> render_frame_host_; - base::WeakPtr<WebUsbChooser> usb_chooser_; + std::unique_ptr<WebUsbChooser> usb_chooser_; raw_ptr<UsbChooserContext> chooser_context_; url::Origin origin_; @@ -101,6 +110,8 @@ // A UsbDeviceClient tracks a UsbDevice pipe that has been passed to Blink. std::vector<std::unique_ptr<UsbDeviceClient>> device_clients_; + ChooserFactoryCallback chooser_factory_; + base::ScopedObservation<UsbChooserContext, UsbChooserContext::DeviceObserver> device_observation_{this}; base::ScopedObservation<
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt index 84065f8..589a64d 100644 --- a/chrome/build/linux.pgo.txt +++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@ -chrome-linux-main-1653566255-a5554d80a78a9325625283d634d620f34f55fc8e.profdata +chrome-linux-main-1653587488-d60b14ae1fa4042118b0bf3b4726c920abeb5fd9.profdata
diff --git a/chrome/build/mac-arm.pgo.txt b/chrome/build/mac-arm.pgo.txt index 15d830e1..03564b48 100644 --- a/chrome/build/mac-arm.pgo.txt +++ b/chrome/build/mac-arm.pgo.txt
@@ -1 +1 @@ -chrome-mac-arm-main-1653566255-300a8e5231c0420e085d40a875d1d0916634d103.profdata +chrome-mac-arm-main-1653609490-214c9b5cdb017b7b3bb5893c5de67034564867b6.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt index f7e7dba..19a0218 100644 --- a/chrome/build/mac.pgo.txt +++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@ -chrome-mac-main-1653566255-582816f27c2206b67a04fc3217422c2cab5d7580.profdata +chrome-mac-main-1653587488-c5a2a5c4dde425a5066dbec30cf55034be208a96.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt index 8979f533..6c75567 100644 --- a/chrome/build/win32.pgo.txt +++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@ -chrome-win32-main-1653577197-6910ce4f64c8f301cb957182ebd855b324e45c25.profdata +chrome-win32-main-1653598715-9f8e6c116a08624b1864ac15fa7e6e1f1b5f72d9.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt index 9947d25..cff9fab 100644 --- a/chrome/build/win64.pgo.txt +++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@ -chrome-win64-main-1653577197-f298df9bcb5350339d3d0ea2f94a9371fef97747.profdata +chrome-win64-main-1653598715-be0c36b77bcd6752e69788f777254325007803ab.profdata
diff --git a/chrome/installer/linux/common/rpm.include b/chrome/installer/linux/common/rpm.include index 3b959f99..ade56391 100644 --- a/chrome/installer/linux/common/rpm.include +++ b/chrome/installer/linux/common/rpm.include
@@ -24,6 +24,14 @@ NEED_KEYS=1 fi + # 2021 signing subkey + rpm -q ${KEY_PACKAGE} --qf '%{Pubkeys:armor}\n' | \ + gpg --with-colons - 2>/dev/null | \ + grep -q 4EB27DB2A3B88B8B + if [ "$?" -ne "0" ]; then + NEED_KEYS=1 + fi + if [ $NEED_KEYS -ne 1 ]; then return fi
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index ec9221b..643d6844 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -1141,7 +1141,10 @@ use_xvfb = use_xvfb_in_this_config configs += [ "//build/config:precompiled_headers" ] - configs += [ ":disable_thinlto_cache_flags" ] + configs += [ + ":disable_thinlto_cache_flags", + ":pdb_larger_than_4gb", + ] defines = [ "HAS_OUT_OF_PROC_TEST_RUNNER", "CHROME_VERSION_MAJOR=" + chrome_version_major, @@ -3924,7 +3927,6 @@ data_deps += [ "//ash/keyboard/ui:resources", "//chrome", - "//chrome/test/data/webui/cr_components/chromeos/cellular_setup:modulize_runtime_data", "//testing/buildbot/filters:chromeos_filters", "//ui/file_manager:unit_test_data", ] @@ -4957,6 +4959,15 @@ } } +config("pdb_larger_than_4gb") { + if (is_win && symbol_level == 2 && use_thin_lto) { + # These binaries create PDBs larger than 4 GiB. Increasing the PDB page + # size allows larger PDBs, but not all tools can handle such large PDBs + # yet. + ldflags = [ "/pdbpagesize:8192" ] + } +} + test("unit_tests") { use_xvfb = use_xvfb_in_this_config @@ -5435,7 +5446,10 @@ } configs += [ "//build/config:precompiled_headers" ] - configs += [ ":disable_thinlto_cache_flags" ] + configs += [ + ":disable_thinlto_cache_flags", + ":pdb_larger_than_4gb", + ] data_deps = [ "//chrome/test/data/media/engagement/preload:generate_preload_list",
diff --git a/chrome/test/data/webui/BUILD.gn b/chrome/test/data/webui/BUILD.gn index 70cb8df..70a78da 100644 --- a/chrome/test/data/webui/BUILD.gn +++ b/chrome/test/data/webui/BUILD.gn
@@ -221,23 +221,6 @@ if (is_chromeos_ash) { data += [ - "$root_gen_dir/chrome/test/data/webui/cr_components/chromeos/cellular_setup/activation_code_page_test.m.js", - "$root_gen_dir/chrome/test/data/webui/cr_components/chromeos/cellular_setup/base_page_test.m.js", - "$root_gen_dir/chrome/test/data/webui/cr_components/chromeos/cellular_setup/button_bar_test.m.js", - "$root_gen_dir/chrome/test/data/webui/cr_components/chromeos/cellular_setup/confirmation_code_page_test.m.js", - "$root_gen_dir/chrome/test/data/webui/cr_components/chromeos/cellular_setup/cellular_eid_dialog_test.m.js", - "$root_gen_dir/chrome/test/data/webui/cr_components/chromeos/cellular_setup/cellular_setup_test.m.js", - "$root_gen_dir/chrome/test/data/webui/cr_components/chromeos/cellular_setup/esim_flow_ui_test.m.js", - "$root_gen_dir/chrome/test/data/webui/cr_components/chromeos/cellular_setup/final_page_test.m.js", - "$root_gen_dir/chrome/test/data/webui/cr_components/chromeos/cellular_setup/provisioning_page_test.m.js", - "$root_gen_dir/chrome/test/data/webui/cr_components/chromeos/cellular_setup/psim_flow_ui_test.m.js", - "$root_gen_dir/chrome/test/data/webui/cr_components/chromeos/cellular_setup/fake_barcode_detector.m.js", - "$root_gen_dir/chrome/test/data/webui/cr_components/chromeos/cellular_setup/fake_canvas_context.m.js", - "$root_gen_dir/chrome/test/data/webui/cr_components/chromeos/cellular_setup/setup_loading_page_test.m.js", - "$root_gen_dir/chrome/test/data/webui/cr_components/chromeos/cellular_setup/fake_cellular_setup_remote.m.js", - "$root_gen_dir/chrome/test/data/webui/cr_components/chromeos/cellular_setup/fake_cellular_setup_delegate.m.js", - "$root_gen_dir/chrome/test/data/webui/cr_components/chromeos/cellular_setup/fake_esim_manager_remote.m.js", - "$root_gen_dir/chrome/test/data/webui/cr_components/chromeos/cellular_setup/fake_media_devices.m.js", "$root_gen_dir/chrome/test/data/webui/cr_components/chromeos/multidevice_setup/integration_test.m.js", "$root_gen_dir/chrome/test/data/webui/cr_components/chromeos/multidevice_setup/setup_succeeded_page_test.m.js", "$root_gen_dir/chrome/test/data/webui/cr_components/chromeos/multidevice_setup/start_setup_page_test.m.js",
diff --git a/chrome/test/data/webui/chromeos/os_feedback_ui/BUILD.gn b/chrome/test/data/webui/chromeos/os_feedback_ui/BUILD.gn index 35cd8cec..0a0e603 100644 --- a/chrome/test/data/webui/chromeos/os_feedback_ui/BUILD.gn +++ b/chrome/test/data/webui/chromeos/os_feedback_ui/BUILD.gn
@@ -28,6 +28,7 @@ deps = [ "../..:chai_assert", "//ash/webui/os_feedback_ui/resources:confirmation_page", + "//ash/webui/os_feedback_ui/resources:feedback_types", ] externs_list = [ "$externs_path/mocha-2.5.js" ] }
diff --git a/chrome/test/data/webui/chromeos/os_feedback_ui/confirmation_page_test.js b/chrome/test/data/webui/chromeos/os_feedback_ui/confirmation_page_test.js index 96158c2..eefeef09 100644 --- a/chrome/test/data/webui/chromeos/os_feedback_ui/confirmation_page_test.js +++ b/chrome/test/data/webui/chromeos/os_feedback_ui/confirmation_page_test.js
@@ -3,66 +3,162 @@ // found in the LICENSE file. import {ConfirmationPageElement} from 'chrome://os-feedback/confirmation_page.js'; +import {SendReportStatus} from 'chrome://os-feedback/feedback_types.js'; -import {assertEquals, assertTrue} from '../../chai_assert.js'; +import {assertEquals, assertFalse, assertTrue} from '../../chai_assert.js'; +import {flushTasks, isVisible} from '../../test_util.js'; + +/** @type {string} */ +const ONLINE_TITLE = 'Thanks for your feedback'; +/** @type {string} */ +const OFFLINE_TITLE = 'You are offline now. Feedback will be sent later.'; + +/** @type {string} */ +const ONLINE_MESSAGE = + 'Your feedback helps improve ChromeOS and will be reviewed by ' + + 'our team. Because of the large number of reports, we won\’t be able ' + + ' to send a reply.'; +/** @type {string} */ +const OFFLINE_MESSAGE = + 'Thanks for the feedback. Your feedback helps improve Chrome OS ' + + 'and will be reviewed by the Chrome OS team. Because of the number ' + + ' of reports submitted, you won’t receive a direct reply.'; export function confirmationPageTest() { /** @type {?ConfirmationPageElement} */ - let component = null; + let page = null; setup(() => { document.body.innerHTML = ''; - component = /** @type {!ConfirmationPageElement} */ ( - document.createElement('confirmation-page')); - document.body.appendChild(component); }); teardown(() => { - component.remove(); - component = null; + page.remove(); + page = null; }); - /**TODO(xiangdongkong): test user actions */ - test('confirmationPageLoaded', () => { - assertEquals( - 'Thanks for your feedback', - component.shadowRoot.querySelector('#title').textContent); - assertTrue(!!component.shadowRoot.querySelector('#message')); + function initializePage() { + assertFalse(!!page); + page = /** @type {!ConfirmationPageElement} */ ( + document.createElement('confirmation-page')); + assertTrue(!!page); + document.body.appendChild(page); + return flushTasks(); + } - // verify navigation buttons exist - const doneButton = component.shadowRoot.querySelector('#buttonDone'); - const startNewButton = - component.shadowRoot.querySelector('#buttonNewReport'); - assertTrue(!!doneButton); - assertTrue(!!startNewButton); + /** + * @param {?Element} host + * @param {string} selector + * @returns {!Element} + */ + function getElement(host, selector) { + const element = host.shadowRoot.querySelector(selector); + assertTrue(!!element); + return element; + } + + /** + * @param {?Element} host + * @param {string} selector + * @returns {string} + */ + function getElementContent(host, selector) { + const element = getElement(host, selector); + return element.textContent.trim(); + } + + /** + * @param {boolean} isOnline + * @private + */ + function verifyElementsByStatus(isOnline) { + if (isOnline) { + assertEquals(ONLINE_TITLE, getElementContent(page, '#title')); + assertEquals(ONLINE_MESSAGE, getElementContent(page, '#message')); + } else { + assertEquals(OFFLINE_TITLE, getElementContent(page, '#title')); + assertEquals(OFFLINE_MESSAGE, getElementContent(page, '#message')); + } // verify help resources exist - const helpResourcesSection = - component.shadowRoot.querySelector('#helpResources'); - assertTrue(!!helpResourcesSection); + const helpResourcesSection = getElement(page, '#helpResources'); assertEquals( 'Here are some other helpful resources:', - component.shadowRoot.querySelector('#helpResourcesLabel').textContent); + getElementContent(page, '#helpResourcesLabel')); const helpLinks = helpResourcesSection.querySelectorAll('cr-link-row'); assertTrue(!!helpLinks); - assertEquals(helpLinks.length, 3); + assertEquals(3, helpLinks.length); - assertTrue(!!helpLinks[0].shadowRoot.querySelector('#startIcon')); - assertTrue(!!helpLinks[0].shadowRoot.querySelector('#subLabel')); - const exploreLabel = helpLinks[0].shadowRoot.querySelector('#label'); - assertTrue(!!exploreLabel); - assertEquals(exploreLabel.textContent.trim(), 'Explore app'); + // Verify the explore app link. + const exploreLink = helpLinks[0]; + assertTrue(isVisible(exploreLink)); + assertEquals( + 'help-resources:explore', getElement(exploreLink, '#startIcon').icon); + assertEquals('Explore app', getElementContent(exploreLink, '#label')); + assertEquals( + 'Find help articles and answers to common Chromebook questions', + getElementContent(exploreLink, '#subLabel')); - assertTrue(!!helpLinks[1].shadowRoot.querySelector('#startIcon')); - assertTrue(!!helpLinks[1].shadowRoot.querySelector('#subLabel')); - const diagnosticsLabel = helpLinks[1].shadowRoot.querySelector('#label'); - assertTrue(!!diagnosticsLabel); - assertEquals(diagnosticsLabel.textContent.trim(), 'Diagnostics app'); + // Verify the diagnostics app link. + const diagnosticsLink = helpLinks[1]; + assertTrue(isVisible(diagnosticsLink)); + assertEquals( + 'help-resources:diagnostics', + getElement(diagnosticsLink, '#startIcon').icon); + assertEquals( + 'Diagnostics app', getElementContent(diagnosticsLink, '#label')); + assertEquals( + 'Run tests and troubleshooting for hardware issues', + getElementContent(diagnosticsLink, '#subLabel')); - assertTrue(!!helpLinks[2].shadowRoot.querySelector('#startIcon')); - assertTrue(!!helpLinks[2].shadowRoot.querySelector('#subLabel')); - const communityLabel = helpLinks[2].shadowRoot.querySelector('#label'); - assertTrue(!!communityLabel); - assertEquals(communityLabel.textContent.trim(), 'Chromebook community'); + // Verify the community link. + const communityLink = helpLinks[2]; + if (isOnline) { + assertTrue(isVisible(communityLink)); + } else { + assertFalse(isVisible(communityLink)); + } + assertEquals( + 'help-resources2:chromebook-community', + getElement(communityLink, '#startIcon').icon); + assertEquals( + 'Chromebook community', getElementContent(communityLink, '#label')); + assertEquals( + 'Ask the experts in the Chromebook help forum', + getElementContent(communityLink, '#subLabel')); + + // Verify buttons. + assertEquals( + 'Send new report', getElementContent(page, '#buttonNewReport')); + assertEquals('Done', getElementContent(page, '#buttonDone')); + } + + /**TODO(xiangdongkong): test user actions */ + + // Test when send report status is success, the corresponding title and + // message are being used. The community link should be visible, + test('onlineModeStatusSuccess', async () => { + await initializePage(); + + page.sendReportStatus = SendReportStatus.kSuccess; + verifyElementsByStatus(/**isOnline=*/ true); + }); + + // Test when send report status is unknown, the corresponding title and + // message are being used. The community link should be visible, + test('offlineModeStatusUnknown', async () => { + await initializePage(); + + page.sendReportStatus = SendReportStatus.kUnknown; + verifyElementsByStatus(/**isOnline=*/ true); + }); + + // Test when send report status is offline, the corresponding title and + // message are being used. The community link should be invisible, + test('offlineModeStatusDelayed', async () => { + await initializePage(); + + page.sendReportStatus = SendReportStatus.kDelayed; + verifyElementsByStatus(/**isOnline=*/ false); }); }
diff --git a/chrome/test/data/webui/chromeos/os_feedback_ui/feedback_flow_test.js b/chrome/test/data/webui/chromeos/os_feedback_ui/feedback_flow_test.js index 2791147..d6ca156 100644 --- a/chrome/test/data/webui/chromeos/os_feedback_ui/feedback_flow_test.js +++ b/chrome/test/data/webui/chromeos/os_feedback_ui/feedback_flow_test.js
@@ -6,6 +6,7 @@ import {FakeFeedbackServiceProvider} from 'chrome://os-feedback/fake_feedback_service_provider.js'; import {FakeHelpContentProvider} from 'chrome://os-feedback/fake_help_content_provider.js'; import {FeedbackFlowElement, FeedbackFlowState} from 'chrome://os-feedback/feedback_flow.js'; +import {SendReportStatus} from 'chrome://os-feedback/feedback_types.js'; import {setFeedbackServiceProviderForTesting, setHelpContentProviderForTesting} from 'chrome://os-feedback/mojo_interface_provider.js'; import {assertEquals, assertFalse, assertTrue} from '../../chai_assert.js'; @@ -104,6 +105,7 @@ test('ConfirmationPageIsShown', async () => { await initializePage(); page.setCurrentStateForTesting(FeedbackFlowState.CONFIRMATION); + page.setSendReportStatusForTesting(SendReportStatus.kSuccess); const activePage = page.shadowRoot.querySelector('.iron-selected'); assertTrue(!!activePage); @@ -226,6 +228,7 @@ activePage = page.shadowRoot.querySelector('.iron-selected'); assertTrue(!!activePage); assertEquals('confirmationPage', activePage.id); + assertEquals(SendReportStatus.kSuccess, activePage.sendReportStatus); }); // Test that the getUserEmail is called after initialization.
diff --git a/chrome/test/data/webui/chromeos/personalization_app/wallpaper_images_element_test.ts b/chrome/test/data/webui/chromeos/personalization_app/wallpaper_images_element_test.ts index 00a1967..cd6258eb 100644 --- a/chrome/test/data/webui/chromeos/personalization_app/wallpaper_images_element_test.ts +++ b/chrome/test/data/webui/chromeos/personalization_app/wallpaper_images_element_test.ts
@@ -96,6 +96,7 @@ }); test('displays images for current collection id', async () => { + loadTimeData.overrideValues({isDarkLightModeEnabled: false}); personalizationStore.data.wallpaper.backdrop.images = { 'id_0': wallpaperProvider.images, 'id_1': [
diff --git a/chrome/test/data/webui/cr_components/chromeos/BUILD.gn b/chrome/test/data/webui/cr_components/chromeos/BUILD.gn index 8354b800..819eb9e 100644 --- a/chrome/test/data/webui/cr_components/chromeos/BUILD.gn +++ b/chrome/test/data/webui/cr_components/chromeos/BUILD.gn
@@ -7,7 +7,6 @@ group("modulize") { deps = [ - "cellular_setup:modulize", "multidevice_setup:modulize", "network:modulize", ]
diff --git a/chrome/test/data/webui/cr_components/chromeos/cellular_setup/BUILD.gn b/chrome/test/data/webui/cr_components/chromeos/cellular_setup/BUILD.gn index 53e6543..ae1922e1 100644 --- a/chrome/test/data/webui/cr_components/chromeos/cellular_setup/BUILD.gn +++ b/chrome/test/data/webui/cr_components/chromeos/cellular_setup/BUILD.gn
@@ -1,41 +1,3 @@ # Copyright 2020 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("//ui/webui/resources/cr_components/chromeos/os_cr_components.gni") -import("//ui/webui/resources/tools/js_modulizer.gni") - -js_modulizer("modulize") { - input_files = [ - "activation_code_page_test.js", - "base_page_test.js", - "button_bar_test.js", - "confirmation_code_page_test.js", - "cellular_eid_dialog_test.js", - "cellular_setup_test.js", - "esim_flow_ui_test.js", - "final_page_test.js", - "provisioning_page_test.js", - "psim_flow_ui_test.js", - "setup_loading_page_test.js", - "fake_cellular_setup_delegate.js", - "fake_cellular_setup_remote.js", - "fake_esim_manager_remote.js", - "fake_media_devices.js", - "fake_canvas_context.js", - "fake_barcode_detector.js", - "mock_metrics_private.js", - ] - namespace_rewrites = cr_components_chromeos_namespace_rewrites + [ - "cellular_setup.FakeCellularSetupDelegate|FakeCellularSetupDelegate", - "cellular_setup.FakeCarrierPortalHandlerRemote|FakeCarrierPortalHandlerRemote", - "cellular_setup.FakeCellularSetupRemote|FakeCellularSetupRemote", - "cellular_setup.FakeESimManagerRemote|FakeESimManagerRemote", - "cellular_setup.FakeMediaDevices|FakeMediaDevices", - "cellular_setup.FakeCanvasContext|FakeCanvasContext", - "cellular_setup.MockMetricsPrivate|MockMetricsPrivate", - "test_util.eventToPromise|eventToPromise", - "test_util.flushTasks|flushTasks", - "test_util.waitAfterNextRender|waitAfterNextRender", - ] -}
diff --git a/chrome/test/data/webui/cr_components/chromeos/cellular_setup/activation_code_page_test.js b/chrome/test/data/webui/cr_components/chromeos/cellular_setup/activation_code_page_test.js index ad00aaa..95137a1a 100644 --- a/chrome/test/data/webui/cr_components/chromeos/cellular_setup/activation_code_page_test.js +++ b/chrome/test/data/webui/cr_components/chromeos/cellular_setup/activation_code_page_test.js
@@ -2,16 +2,16 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// clang-format off -// #import 'chrome://os-settings/strings.m.js'; -// #import 'chrome://resources/cr_components/chromeos/cellular_setup/activation_code_page.m.js'; +import 'chrome://os-settings/strings.m.js'; +import 'chrome://resources/cr_components/chromeos/cellular_setup/activation_code_page.m.js'; -// #import {flush, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; -// #import {assertTrue} from '../../../chai_assert.js'; -// #import {FakeMediaDevices} from './fake_media_devices.m.js'; -// #import {FakeBarcodeDetector, FakeImageCapture} from './fake_barcode_detector.m.js'; -// #import {eventToPromise, flushTasks, waitAfterNextRender} from 'chrome://test/test_util.js'; -// clang-format on +import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +import {eventToPromise, flushTasks, waitAfterNextRender} from 'chrome://test/test_util.js'; + +import {assertTrue} from '../../../chai_assert.js'; + +import {FakeBarcodeDetector, FakeImageCapture} from './fake_barcode_detector.js'; +import {FakeMediaDevices} from './fake_media_devices.js'; suite('CrComponentsActivationCodePageTest', function() { /** @type {string} */ @@ -29,7 +29,7 @@ let intervalFunction = null; function flushAsync() { - Polymer.dom.flush(); + flush(); // Use setTimeout to wait for the next macrotask. return new Promise(resolve => setTimeout(resolve)); } @@ -53,14 +53,14 @@ FakeBarcodeDetector, FakeImageCapture, setIntervalFunction, playVideoFunction, stopStreamFunction); document.body.appendChild(activationCodePage); - Polymer.dom.flush(); + flush(); - mediaDevices = new cellular_setup.FakeMediaDevices(); + mediaDevices = new FakeMediaDevices(); mediaDevices.addDevice(); activationCodePage.setMediaDevices(mediaDevices); mediaDevices.resolveEnumerateDevices(); await waitAfterNextRender(activationCodePage); - Polymer.dom.flush(); + flush(); }); teardown(function() { @@ -117,7 +117,7 @@ assertTrue(switchCameraButton.hidden); const focusNextButtonPromise = - test_util.eventToPromise('focus-default-button', activationCodePage); + eventToPromise('focus-default-button', activationCodePage); // Mock camera scanning a code. await intervalFunction(); @@ -126,7 +126,7 @@ // The scanFinishContainer and scanSuccessContainer should now be visible, // video, start scanning UI, scanFailureContainer hidden and nextbutton // is focused. - await Promise.all([focusNextButtonPromise, test_util.flushTasks()]); + await Promise.all([focusNextButtonPromise, flushTasks()]); assertFalse(scanFinishContainer.hidden); assertTrue(startScanningContainer.hidden); assertTrue(video.hidden); @@ -447,8 +447,8 @@ const setInputAndAssert = async (activationCode, isInputInvalid, shouldEventContainCode) => { - const activationCodeUpdatedPromise = test_util.eventToPromise( - 'activation-code-updated', activationCodePage); + const activationCodeUpdatedPromise = + eventToPromise('activation-code-updated', activationCodePage); input.value = activationCode; const activationCodeUpdatedEvent = await activationCodeUpdatedPromise; assertEquals( @@ -522,7 +522,7 @@ // Mock camera scanning an invalid code. let activationCodeUpdatedPromise = - test_util.eventToPromise('activation-code-updated', activationCodePage); + eventToPromise('activation-code-updated', activationCodePage); FakeBarcodeDetector.setDetectedBarcode(ACTIVATION_CODE_INVALID); await intervalFunction(); await flushAsync(); @@ -544,7 +544,7 @@ // Mock camera scanning a valid, incomplete code. activationCodeUpdatedPromise = - test_util.eventToPromise('activation-code-updated', activationCodePage); + eventToPromise('activation-code-updated', activationCodePage); FakeBarcodeDetector.setDetectedBarcode(/*barcode=*/ 'LPA:'); await intervalFunction(); await flushAsync(); @@ -566,7 +566,7 @@ // Mock camera scanning a valid code. activationCodeUpdatedPromise = - test_util.eventToPromise('activation-code-updated', activationCodePage); + eventToPromise('activation-code-updated', activationCodePage); FakeBarcodeDetector.setDetectedBarcode(ACTIVATION_CODE_VALID); await intervalFunction(); await flushAsync();
diff --git a/chrome/test/data/webui/cr_components/chromeos/cellular_setup/base_page_test.js b/chrome/test/data/webui/cr_components/chromeos/cellular_setup/base_page_test.js index dc9d171c..252a0e0 100644 --- a/chrome/test/data/webui/cr_components/chromeos/cellular_setup/base_page_test.js +++ b/chrome/test/data/webui/cr_components/chromeos/cellular_setup/base_page_test.js
@@ -2,23 +2,21 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// clang-format off -// #import 'chrome://resources/cr_components/chromeos/cellular_setup/base_page.m.js'; +import 'chrome://resources/cr_components/chromeos/cellular_setup/base_page.m.js'; -// #import {flush, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; -// clang-format on +import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; suite('CrComponentsBasePageTest', function() { let basePage; setup(function() { basePage = document.createElement('base-page'); document.body.appendChild(basePage); - Polymer.dom.flush(); + flush(); }); test('Title is shown', function() { basePage.title = 'Base page titile'; - Polymer.dom.flush(); + flush(); const title = basePage.$$('#title'); assertTrue(!!title); }); @@ -30,7 +28,7 @@ test('Message icon is shown', function() { basePage.messageIcon = 'warning'; - Polymer.dom.flush(); + flush(); const messageIcon = basePage.$$('iron-icon'); assertTrue(!!messageIcon); assertFalse(messageIcon.hidden);
diff --git a/chrome/test/data/webui/cr_components/chromeos/cellular_setup/button_bar_test.js b/chrome/test/data/webui/cr_components/chromeos/cellular_setup/button_bar_test.js index cc022a5..5cecdcec 100644 --- a/chrome/test/data/webui/cr_components/chromeos/cellular_setup/button_bar_test.js +++ b/chrome/test/data/webui/cr_components/chromeos/cellular_setup/button_bar_test.js
@@ -2,14 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// clang-format off -// #import 'chrome://os-settings/strings.m.js'; -// #import 'chrome://resources/cr_components/chromeos/cellular_setup/button_bar.m.js'; +import 'chrome://os-settings/strings.m.js'; +import 'chrome://resources/cr_components/chromeos/cellular_setup/button_bar.m.js'; -// #import {flush, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; -// #import {ButtonState, Button, ButtonBarState, CellularSetupPageName} from 'chrome://resources/cr_components/chromeos/cellular_setup/cellular_types.m.js'; -// #import {assertEquals, assertFalse, assertTrue} from '../../../chai_assert.js'; -// clang-format on +import {ButtonBarState, ButtonState} from 'chrome://resources/cr_components/chromeos/cellular_setup/cellular_types.m.js'; +import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + +import {assertEquals, assertTrue} from '../../../chai_assert.js'; suite('CellularSetupButtonBarTest', function() { /** @type {!ButtonBarElement} */ @@ -17,7 +16,7 @@ setup(function() { buttonBar = document.createElement('button-bar'); document.body.appendChild(buttonBar); - Polymer.dom.flush(); + flush(); }); teardown(function() { @@ -25,7 +24,7 @@ }); /** - * @param {!cellularSetup.ButtonBarState} state + * @param {!ButtonBarState} state */ function setStateForAllButtons(state) { buttonBar.buttonState = { @@ -33,7 +32,7 @@ cancel: state, forward: state, }; - Polymer.dom.flush(); + flush(); } /** @@ -61,44 +60,44 @@ } test('individual buttons appear if enabled', function() { - setStateForAllButtons(cellularSetup.ButtonState.ENABLED); + setStateForAllButtons(ButtonState.ENABLED); assertTrue(isButtonShownAndEnabled(buttonBar.$$('#backward'))); assertTrue(isButtonShownAndEnabled(buttonBar.$$('#cancel'))); assertTrue(isButtonShownAndEnabled(buttonBar.$$('#forward'))); }); test('individual buttons appear but are diabled', function() { - setStateForAllButtons(cellularSetup.ButtonState.DISABLED); + setStateForAllButtons(ButtonState.DISABLED); assertTrue(isButtonShownAndDisabled(buttonBar.$$('#backward'))); assertTrue(isButtonShownAndDisabled(buttonBar.$$('#cancel'))); assertTrue(isButtonShownAndDisabled(buttonBar.$$('#forward'))); }); test('individual buttons are hidden', function() { - setStateForAllButtons(cellularSetup.ButtonState.HIDDEN); + setStateForAllButtons(ButtonState.HIDDEN); assertTrue(isButtonHidden(buttonBar.$$('#backward'))); assertTrue(isButtonHidden(buttonBar.$$('#cancel'))); assertTrue(isButtonHidden(buttonBar.$$('#forward'))); }); test('default focus is on last button if all are enabled', function() { - setStateForAllButtons(cellularSetup.ButtonState.ENABLED); + setStateForAllButtons(ButtonState.ENABLED); buttonBar.focusDefaultButton(); - Polymer.dom.flush(); + flush(); assertEquals(buttonBar.shadowRoot.activeElement, buttonBar.$$('#forward')); }); test('default focus is on first button if rest are hidden', function() { buttonBar.buttonState = { - backward: cellularSetup.ButtonState.ENABLED, - cancel: cellularSetup.ButtonState.HIDDEN, - forward: cellularSetup.ButtonState.HIDDEN, + backward: ButtonState.ENABLED, + cancel: ButtonState.HIDDEN, + forward: ButtonState.HIDDEN, }; buttonBar.focusDefaultButton(); - Polymer.dom.flush(); + flush(); assertEquals(buttonBar.shadowRoot.activeElement, buttonBar.$$('#backward')); }); @@ -107,13 +106,13 @@ 'default focus is on first button if rest are visible but disabled', function() { buttonBar.buttonState = { - backward: cellularSetup.ButtonState.ENABLED, - cancel: cellularSetup.ButtonState.DISABLED, - forward: cellularSetup.ButtonState.DISABLED, + backward: ButtonState.ENABLED, + cancel: ButtonState.DISABLED, + forward: ButtonState.DISABLED, }; buttonBar.focusDefaultButton(); - Polymer.dom.flush(); + flush(); assertEquals( buttonBar.shadowRoot.activeElement, buttonBar.$$('#backward'));
diff --git a/chrome/test/data/webui/cr_components/chromeos/cellular_setup/cellular_eid_dialog_test.js b/chrome/test/data/webui/cr_components/chromeos/cellular_setup/cellular_eid_dialog_test.js index 8e833bc5..b09b933 100644 --- a/chrome/test/data/webui/cr_components/chromeos/cellular_setup/cellular_eid_dialog_test.js +++ b/chrome/test/data/webui/cr_components/chromeos/cellular_setup/cellular_eid_dialog_test.js
@@ -2,18 +2,16 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// clang-format off -// #import 'chrome://os-settings/strings.m.js'; -// #import 'chrome://resources/cr_components/chromeos/cellular_setup/cellular_eid_dialog.m.js'; +import 'chrome://os-settings/strings.m.js'; +import 'chrome://resources/cr_components/chromeos/cellular_setup/cellular_eid_dialog.m.js'; -// #import {afterNextRender, flush, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; -// #import {setESimManagerRemoteForTesting} from 'chrome://resources/cr_components/chromeos/cellular_setup/mojo_interface_provider.m.js'; -// #import {assertTrue, assertEquals, assertDeepEquals} from '../../../chai_assert.js'; -// #import {FakeESimManagerRemote} from './fake_esim_manager_remote.m.js'; -// #import {FakeCanvasContext} from "./fake_canvas_context.m.js"; -// #import {eventToPromise, flushTasks} from 'chrome://test/test_util.js'; -// #import {waitAfterNextRender} from 'chrome://test/test_util.js'; -// clang-format on +import {setESimManagerRemoteForTesting} from 'chrome://resources/cr_components/chromeos/cellular_setup/mojo_interface_provider.m.js'; +import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + +import {assertDeepEquals, assertEquals, assertTrue} from '../../../chai_assert.js'; + +import {FakeCanvasContext} from './fake_canvas_context.js'; +import {FakeESimManagerRemote} from './fake_esim_manager_remote.js'; suite('CrComponentsCellularEidDialogTest', function() { let eSimManagerRemote; @@ -22,8 +20,8 @@ let canvasContext; function init(eidQRCode) { - eSimManagerRemote = new cellular_setup.FakeESimManagerRemote(); - cellular_setup.setESimManagerRemoteForTesting(eSimManagerRemote); + eSimManagerRemote = new FakeESimManagerRemote(); + setESimManagerRemoteForTesting(eSimManagerRemote); testEuicc = eSimManagerRemote.addEuiccForTest(1); if (eidQRCode) { testEuicc.setEidQRCodeForTest(eidQRCode); @@ -31,12 +29,12 @@ eidDialog = document.createElement('cellular-eid-dialog'); eidDialog.euicc = testEuicc; - canvasContext = new cellular_setup.FakeCanvasContext(); + canvasContext = new FakeCanvasContext(); eidDialog.setCanvasContextForTest(canvasContext); document.body.appendChild(eidDialog); // Flush and wait for next macrotask. - Polymer.dom.flush(); + flush(); return new Promise(resolve => setTimeout(resolve)); } @@ -61,7 +59,7 @@ assertTrue(eidDialog.$.eidDialog.open); eidDialog.$.done.click(); - Polymer.dom.flush(); + flush(); assertFalse(eidDialog.$.eidDialog.open); });
diff --git a/chrome/test/data/webui/cr_components/chromeos/cellular_setup/cellular_setup_test.js b/chrome/test/data/webui/cr_components/chromeos/cellular_setup/cellular_setup_test.js index 9e22cc9..fe3b06f 100644 --- a/chrome/test/data/webui/cr_components/chromeos/cellular_setup/cellular_setup_test.js +++ b/chrome/test/data/webui/cr_components/chromeos/cellular_setup/cellular_setup_test.js
@@ -2,20 +2,20 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// clang-format off -// #import 'chrome://os-settings/strings.m.js'; -// #import 'chrome://resources/cr_components/chromeos/cellular_setup/cellular_setup.m.js'; -// #import 'chrome://resources/cr_components/chromeos/cellular_setup/psim_flow_ui.m.js'; +import 'chrome://os-settings/strings.m.js'; +import 'chrome://resources/cr_components/chromeos/cellular_setup/cellular_setup.m.js'; +import 'chrome://resources/cr_components/chromeos/cellular_setup/psim_flow_ui.m.js'; -// #import {CellularSetupPageName} from 'chrome://resources/cr_components/chromeos/cellular_setup/cellular_types.m.js'; -// #import {flush, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; -// #import {assertTrue, assertFalse} from '../../../chai_assert.js'; -// #import {FakeCellularSetupDelegate} from './fake_cellular_setup_delegate.m.js'; -// #import {FakeNetworkConfig} from 'chrome://test/chromeos/fake_network_config_mojom.js'; -// #import {FakeESimManagerRemote} from 'chrome://test/cr_components/chromeos/cellular_setup/fake_esim_manager_remote.m.js'; -// #import {setESimManagerRemoteForTesting} from 'chrome://resources/cr_components/chromeos/cellular_setup/mojo_interface_provider.m.js'; -// #import {MojoInterfaceProviderImpl} from 'chrome://resources/cr_components/chromeos/network/mojo_interface_provider.m.js'; -// clang-format on +import {CellularSetupPageName} from 'chrome://resources/cr_components/chromeos/cellular_setup/cellular_types.m.js'; +import {setESimManagerRemoteForTesting} from 'chrome://resources/cr_components/chromeos/cellular_setup/mojo_interface_provider.m.js'; +import {MojoInterfaceProviderImpl} from 'chrome://resources/cr_components/chromeos/network/mojo_interface_provider.m.js'; +import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +import {FakeNetworkConfig} from 'chrome://test/chromeos/fake_network_config_mojom.js'; +import {FakeESimManagerRemote} from 'chrome://test/cr_components/chromeos/cellular_setup/fake_esim_manager_remote.js'; + +import {assertFalse, assertTrue} from '../../../chai_assert.js'; + +import {FakeCellularSetupDelegate} from './fake_cellular_setup_delegate.js'; suite('CrComponentsCellularSetupTest', function() { let cellularSetupPage; @@ -23,15 +23,15 @@ let networkConfigRemote; setup(function() { - eSimManagerRemote = new cellular_setup.FakeESimManagerRemote(); - cellular_setup.setESimManagerRemoteForTesting(eSimManagerRemote); + eSimManagerRemote = new FakeESimManagerRemote(); + setESimManagerRemoteForTesting(eSimManagerRemote); networkConfigRemote = new FakeNetworkConfig(); - network_config.MojoInterfaceProviderImpl.getInstance().remote_ = networkConfigRemote; + MojoInterfaceProviderImpl.getInstance().remote_ = networkConfigRemote; }); async function flushAsync() { - Polymer.dom.flush(); + flush(); // Use setTimeout to wait for the next macrotask. return new Promise(resolve => setTimeout(resolve)); } @@ -44,12 +44,12 @@ simInfos: [{slot_id: 0, iccid: '1111111111111111'}], }); eSimManagerRemote.addEuiccForTest(2); - Polymer.dom.flush(); + flush(); cellularSetupPage = document.createElement('cellular-setup'); - cellularSetupPage.delegate = new cellular_setup.FakeCellularSetupDelegate(); + cellularSetupPage.delegate = new FakeCellularSetupDelegate(); document.body.appendChild(cellularSetupPage); - Polymer.dom.flush(); + flush(); } test('Show pSim flow ui', async function() { @@ -61,8 +61,7 @@ assertTrue(!!eSimFlow); assertFalse(!!pSimFlow); - cellularSetupPage.currentPageName = - cellularSetup.CellularSetupPageName.PSIM_FLOW_UI; + cellularSetupPage.currentPageName = CellularSetupPageName.PSIM_FLOW_UI; await flushAsync(); eSimFlow = cellularSetupPage.$$('esim-flow-ui'); pSimFlow = cellularSetupPage.$$('psim-flow-ui');
diff --git a/chrome/test/data/webui/cr_components/chromeos/cellular_setup/confirmation_code_page_test.js b/chrome/test/data/webui/cr_components/chromeos/cellular_setup/confirmation_code_page_test.js index 24866ab2..760cb029 100644 --- a/chrome/test/data/webui/cr_components/chromeos/cellular_setup/confirmation_code_page_test.js +++ b/chrome/test/data/webui/cr_components/chromeos/cellular_setup/confirmation_code_page_test.js
@@ -2,19 +2,18 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// clang-format off -// #import 'chrome://os-settings/strings.m.js'; -// #import 'chrome://resources/cr_components/chromeos/cellular_setup/confirmation_code_page.m.js'; +import 'chrome://os-settings/strings.m.js'; +import 'chrome://resources/cr_components/chromeos/cellular_setup/confirmation_code_page.m.js'; -// #import {flush, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; -// #import {assertTrue} from '../../../chai_assert.js'; -// clang-format on +import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + +import {assertTrue} from '../../../chai_assert.js'; suite('CrComponentsConfirmationCodePageTest', function() { let confirmationCodePage; function flushAsync() { - Polymer.dom.flush(); + flush(); // Use setTimeout to wait for the next macrotask. return new Promise(resolve => setTimeout(resolve)); } @@ -22,7 +21,7 @@ setup(function() { confirmationCodePage = document.createElement('confirmation-code-page'); document.body.appendChild(confirmationCodePage); - Polymer.dom.flush(); + flush(); }); test('Event is fired when enter is pressed on input', async function() {
diff --git a/chrome/test/data/webui/cr_components/chromeos/cellular_setup/esim_flow_ui_test.js b/chrome/test/data/webui/cr_components/chromeos/cellular_setup/esim_flow_ui_test.js index 32414a9..fe18823 100644 --- a/chrome/test/data/webui/cr_components/chromeos/cellular_setup/esim_flow_ui_test.js +++ b/chrome/test/data/webui/cr_components/chromeos/cellular_setup/esim_flow_ui_test.js
@@ -2,23 +2,23 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// clang-format off -// #import 'chrome://os-settings/strings.m.js'; -// #import 'chrome://resources/cr_components/chromeos/cellular_setup/esim_flow_ui.m.js'; +import 'chrome://os-settings/strings.m.js'; +import 'chrome://resources/cr_components/chromeos/cellular_setup/esim_flow_ui.m.js'; -// #import {flush, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; -// #import {setESimManagerRemoteForTesting} from 'chrome://resources/cr_components/chromeos/cellular_setup/mojo_interface_provider.m.js'; -// #import {ButtonState} from 'chrome://resources/cr_components/chromeos/cellular_setup/cellular_types.m.js'; -// #import {ESimPageName, ESimSetupFlowResult, ESIM_SETUP_RESULT_METRIC_NAME, SUCCESSFUL_ESIM_SETUP_DURATION_METRIC_NAME, FAILED_ESIM_SETUP_DURATION_METRIC_NAME} from 'chrome://resources/cr_components/chromeos/cellular_setup/esim_flow_ui.m.js'; -// #import {assertEquals, assertTrue} from '../../../chai_assert.js'; -// #import {FakeESimManagerRemote} from './fake_esim_manager_remote.m.js'; -// #import {FakeCellularSetupDelegate} from './fake_cellular_setup_delegate.m.js'; -// #import {FakeBarcodeDetector, FakeImageCapture} from './fake_barcode_detector.m.js'; -// #import {FakeNetworkConfig} from 'chrome://test/chromeos/fake_network_config_mojom.js'; -// #import {OncMojo} from 'chrome://resources/cr_components/chromeos/network/onc_mojo.m.js'; -// #import {MojoInterfaceProviderImpl} from 'chrome://resources/cr_components/chromeos/network/mojo_interface_provider.m.js'; -// #import {MockMetricsPrivate} from './mock_metrics_private.m.js'; -// clang-format on +import {ButtonState} from 'chrome://resources/cr_components/chromeos/cellular_setup/cellular_types.m.js'; +import {ESimPageName, ESimSetupFlowResult, FAILED_ESIM_SETUP_DURATION_METRIC_NAME, SUCCESSFUL_ESIM_SETUP_DURATION_METRIC_NAME} from 'chrome://resources/cr_components/chromeos/cellular_setup/esim_flow_ui.m.js'; +import {setESimManagerRemoteForTesting} from 'chrome://resources/cr_components/chromeos/cellular_setup/mojo_interface_provider.m.js'; +import {MojoInterfaceProviderImpl} from 'chrome://resources/cr_components/chromeos/network/mojo_interface_provider.m.js'; +import {OncMojo} from 'chrome://resources/cr_components/chromeos/network/onc_mojo.m.js'; +import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +import {FakeNetworkConfig} from 'chrome://test/chromeos/fake_network_config_mojom.js'; + +import {assertEquals, assertTrue} from '../../../chai_assert.js'; + +import {FakeBarcodeDetector, FakeImageCapture} from './fake_barcode_detector.js'; +import {FakeCellularSetupDelegate} from './fake_cellular_setup_delegate.js'; +import {FakeESimManagerRemote} from './fake_esim_manager_remote.js'; +import {MockMetricsPrivate} from './mock_metrics_private.js'; suite('CrComponentsEsimFlowUiTest', function() { /** @type {string} */ @@ -38,7 +38,7 @@ const wifiGuidPrefix = 'wifi'; async function flushAsync() { - Polymer.dom.flush(); + flush(); // Use setTimeout to wait for the next macrotask. return new Promise(resolve => setTimeout(resolve)); } @@ -46,7 +46,7 @@ /** @param {ESimSetupFlowResult} eSimSetupFlowResult */ function endFlowAndVerifyResult(eSimSetupFlowResult) { eSimPage.remove(); - Polymer.dom.flush(); + flush(); assertEquals( chrome.metricsPrivate.getHistogramEnumValueCount(eSimSetupFlowResult), 1); @@ -80,8 +80,7 @@ onlineNetwork.connectionState = chromeos.networkConfig.mojom.ConnectionStateType.kOnline; networkConfigRemote.addNetworksForTest([onlineNetwork]); - network_config.MojoInterfaceProviderImpl.getInstance().remote_ = - networkConfigRemote; + MojoInterfaceProviderImpl.getInstance().remote_ = networkConfigRemote; } /** Takes actively online network offline. */ @@ -110,17 +109,17 @@ addOnlineWifiNetwork(); chrome.metricsPrivate = new MockMetricsPrivate(); - eSimManagerRemote = new cellular_setup.FakeESimManagerRemote(); - cellular_setup.setESimManagerRemoteForTesting(eSimManagerRemote); + eSimManagerRemote = new FakeESimManagerRemote(); + setESimManagerRemoteForTesting(eSimManagerRemote); document.addEventListener('focus-default-button', () => { focusDefaultButtonEventFired = true; }); eSimPage = document.createElement('esim-flow-ui'); - eSimPage.delegate = new cellular_setup.FakeCellularSetupDelegate(); + eSimPage.delegate = new FakeCellularSetupDelegate(); document.body.appendChild(eSimPage); - Polymer.dom.flush(); + flush(); ironPages = eSimPage.$$('iron-pages'); profileLoadingPage = eSimPage.$$('#profileLoadingPage'); @@ -163,13 +162,12 @@ * navigating forward. Asserts that the button_bar and page state is disabled * and busy during the install. * @param {HTMLElement} page - * @param {cellularSetup.ButtonState} previousBackButtonState + * @param {ButtonState} previousBackButtonState */ async function navigateForwardForInstall(page, previousBackButtonState) { const checkShowBusyState = (page !== profileDiscoveryPage && page !== finalPage); - assertEquals( - eSimPage.buttonState.forward, cellularSetup.ButtonState.ENABLED); + assertEquals(eSimPage.buttonState.forward, ButtonState.ENABLED); assertEquals(eSimPage.buttonState.backward, previousBackButtonState); if (checkShowBusyState) { assertFalse(page.showBusy); @@ -178,16 +176,14 @@ // If back button is hidden before installation began, the new back button // state should also be hidden, if it was enabled new back button state // should be disabled while installation is taking place. - let newBackButtonState = cellularSetup.ButtonState.HIDDEN; - if (previousBackButtonState === cellularSetup.ButtonState.ENABLED) { - newBackButtonState = cellularSetup.ButtonState.DISABLED; + let newBackButtonState = ButtonState.HIDDEN; + if (previousBackButtonState === ButtonState.ENABLED) { + newBackButtonState = ButtonState.DISABLED; } eSimPage.navigateForward(); - assertEquals( - eSimPage.buttonState.forward, cellularSetup.ButtonState.DISABLED); - assertEquals( - eSimPage.buttonState.cancel, cellularSetup.ButtonState.DISABLED); + assertEquals(eSimPage.buttonState.forward, ButtonState.DISABLED); + assertEquals(eSimPage.buttonState.cancel, ButtonState.DISABLED); assertEquals(eSimPage.buttonState.backward, newBackButtonState); if (checkShowBusyState) { assertTrue(page.showBusy); @@ -212,13 +208,11 @@ } async function assertFinalPageAndPressDoneButton(shouldBeShowingError) { - assertSelectedPage(cellular_setup.ESimPageName.FINAL, finalPage); + assertSelectedPage(ESimPageName.FINAL, finalPage); assertEquals(!!finalPage.$$('.error'), shouldBeShowingError); - assertEquals( - cellularSetup.ButtonState.ENABLED, eSimPage.buttonState.forward); - assertEquals( - cellularSetup.ButtonState.HIDDEN, eSimPage.buttonState.backward); - assertEquals(cellularSetup.ButtonState.HIDDEN, eSimPage.buttonState.cancel); + assertEquals(ButtonState.ENABLED, eSimPage.buttonState.forward); + assertEquals(ButtonState.HIDDEN, eSimPage.buttonState.backward); + assertEquals(ButtonState.HIDDEN, eSimPage.buttonState.cancel); assertEquals(eSimPage.forwardButtonLabel, 'Done'); let exitCellularSetupEventFired = false; eSimPage.addEventListener('exit-cellular-setup', () => { @@ -232,16 +226,16 @@ /** * @param {boolean} forwardButtonShouldBeEnabled - * @param {cellularSetup.ButtonState} backButtonState + * @param {ButtonState} backButtonState */ function assertButtonState(forwardButtonShouldBeEnabled, backButtonState) { const buttonState = eSimPage.buttonState; assertEquals(buttonState.backward, backButtonState); - assertEquals(buttonState.cancel, cellularSetup.ButtonState.ENABLED); + assertEquals(buttonState.cancel, ButtonState.ENABLED); assertEquals( buttonState.forward, - forwardButtonShouldBeEnabled ? cellularSetup.ButtonState.ENABLED : - cellularSetup.ButtonState.DISABLED); + forwardButtonShouldBeEnabled ? ButtonState.ENABLED : + ButtonState.DISABLED); } function assertFocusDefaultButtonEventFired() { @@ -250,20 +244,18 @@ } async function assertProfileLoadingPageAndContinue() { - assertSelectedPage( - cellular_setup.ESimPageName.PROFILE_LOADING, profileLoadingPage); + assertSelectedPage(ESimPageName.PROFILE_LOADING, profileLoadingPage); assertButtonState( /*forwardButtonShouldBeEnabled=*/ false, - /*backButtonState=*/ cellularSetup.ButtonState.HIDDEN); + /*backButtonState=*/ ButtonState.HIDDEN); await flushAsync(); } function assertProfileDiscoveryPage() { - assertSelectedPage( - cellular_setup.ESimPageName.PROFILE_DISCOVERY, profileDiscoveryPage); + assertSelectedPage(ESimPageName.PROFILE_DISCOVERY, profileDiscoveryPage); assertButtonState( /*forwardButtonShouldBeEnabled*/ true, - /*backButtonState*/ cellularSetup.ButtonState.HIDDEN); + /*backButtonState*/ ButtonState.HIDDEN); } function assertActivationCodePage( @@ -272,8 +264,7 @@ // In the initial state, input should be cleared. assertEquals(activationCodePage.$$('#activationCode').value, ''); } - assertSelectedPage( - cellular_setup.ESimPageName.ACTIVATION_CODE, activationCodePage); + assertSelectedPage(ESimPageName.ACTIVATION_CODE, activationCodePage); assertButtonState(forwardButtonShouldBeEnabled, backButtonState); } @@ -283,8 +274,7 @@ // In the initial state, input should be cleared. assertEquals(confirmationCodePage.$$('#confirmationCode').value, ''); } - assertSelectedPage( - cellular_setup.ESimPageName.CONFIRMATION_CODE, confirmationCodePage); + assertSelectedPage(ESimPageName.CONFIRMATION_CODE, confirmationCodePage); assertButtonState(forwardButtonShouldBeEnabled, backButtonState); } @@ -304,14 +294,14 @@ // Should now be at the activation code page. assertActivationCodePage( /*forwardButtonShouldBeEnabled*/ false, - /*backButtonState*/ cellularSetup.ButtonState.HIDDEN); + /*backButtonState*/ ButtonState.HIDDEN); // Insert an activation code. activationCodePage.$$('#activationCode').value = ACTIVATION_CODE_VALID; // Forward button should now be enabled. assertActivationCodePage( /*forwardButtonShouldBeEnabled*/ true, - /*backButtonState*/ cellularSetup.ButtonState.HIDDEN); + /*backButtonState*/ ButtonState.HIDDEN); }); test('Invalid activation code', async function() { @@ -321,12 +311,12 @@ await navigateForwardForInstall( activationCodePage, - /*backButtonState*/ cellularSetup.ButtonState.HIDDEN); + /*backButtonState*/ ButtonState.HIDDEN); // Install should fail and still be at activation code page. assertActivationCodePage( /*forwardButtonShouldBeEnabled*/ true, - /*backButtonState*/ cellularSetup.ButtonState.HIDDEN); + /*backButtonState*/ ButtonState.HIDDEN); assertTrue(activationCodePage.showError); endFlowAndVerifyResult( @@ -336,7 +326,7 @@ test('Valid activation code', async function() { await navigateForwardForInstall( activationCodePage, - /*backButtonState*/ cellularSetup.ButtonState.HIDDEN); + /*backButtonState*/ ButtonState.HIDDEN); // Should go to final page. await assertFinalPageAndPressDoneButton(false); @@ -351,17 +341,17 @@ await navigateForwardForInstall( activationCodePage, - /*backButtonState*/ cellularSetup.ButtonState.HIDDEN); + /*backButtonState*/ ButtonState.HIDDEN); // Confirmation code page should be showing. assertConfirmationCodePage( /*forwardButtonShouldBeEnabled*/ false, - /*backButtonState*/ cellularSetup.ButtonState.ENABLED); + /*backButtonState*/ ButtonState.ENABLED); euicc.setProfileInstallResultForTest( ash.cellularSetup.mojom.ProfileInstallResult.kSuccess); await enterConfirmationCode( - /*backButtonState*/ cellularSetup.ButtonState.ENABLED); + /*backButtonState*/ ButtonState.ENABLED); // Should go to final page. await assertFinalPageAndPressDoneButton(false); @@ -376,22 +366,22 @@ await navigateForwardForInstall( activationCodePage, - /*backButtonState*/ cellularSetup.ButtonState.HIDDEN); + /*backButtonState*/ ButtonState.HIDDEN); // Confirmation code page should be showing. assertConfirmationCodePage( /*forwardButtonShouldBeEnabled*/ false, - /*backButtonState*/ cellularSetup.ButtonState.ENABLED); + /*backButtonState*/ ButtonState.ENABLED); euicc.setProfileInstallResultForTest( ash.cellularSetup.mojom.ProfileInstallResult.kFailure); const confirmationCodeInput = await enterConfirmationCode( - /*backButtonState*/ cellularSetup.ButtonState.ENABLED); + /*backButtonState*/ ButtonState.ENABLED); // Should still be at confirmation code page with input showing error. assertConfirmationCodePage( /*forwardButtonShouldBeEnabled*/ true, - /*backButtonState*/ cellularSetup.ButtonState.ENABLED); + /*backButtonState*/ ButtonState.ENABLED); assertTrue(confirmationCodeInput.invalid); endFlowAndVerifyResult(ESimSetupFlowResult.INSTALL_FAIL); @@ -404,12 +394,12 @@ await navigateForwardForInstall( activationCodePage, - /*backButtonState*/ cellularSetup.ButtonState.HIDDEN); + /*backButtonState*/ ButtonState.HIDDEN); // Confirmation code page should be showing. assertConfirmationCodePage( /*forwardButtonShouldBeEnabled*/ false, - /*backButtonState*/ cellularSetup.ButtonState.ENABLED); + /*backButtonState*/ ButtonState.ENABLED); confirmationCodePage.$$('#confirmationCode').value = 'CONFIRMATION_CODE'; eSimPage.navigateBackward(); @@ -418,7 +408,7 @@ // Should now be at the activation code page. assertActivationCodePage( /*forwardButtonShouldBeEnabled*/ true, - /*backButtonState*/ cellularSetup.ButtonState.HIDDEN); + /*backButtonState*/ ButtonState.HIDDEN); assertEquals( activationCodePage.$$('#activationCode').value, ACTIVATION_CODE_VALID); @@ -482,12 +472,12 @@ // Confirmation code page should be showing. assertConfirmationCodePage( /*forwardButtonShouldBeEnabled*/ false, - /*backButtonState*/ cellularSetup.ButtonState.HIDDEN); + /*backButtonState*/ ButtonState.HIDDEN); profile.setProfileInstallResultForTest( ash.cellularSetup.mojom.ProfileInstallResult.kSuccess); await enterConfirmationCode( - /*backButtonState*/ cellularSetup.ButtonState.HIDDEN); + /*backButtonState*/ ButtonState.HIDDEN); // Should go to final page. await assertFinalPageAndPressDoneButton(false); @@ -505,17 +495,17 @@ // Confirmation code page should be showing. assertConfirmationCodePage( /*forwardButtonShouldBeEnabled*/ false, - /*backButtonState*/ cellularSetup.ButtonState.HIDDEN); + /*backButtonState*/ ButtonState.HIDDEN); profile.setProfileInstallResultForTest( ash.cellularSetup.mojom.ProfileInstallResult.kFailure); const confirmationCodeInput = - await enterConfirmationCode(cellularSetup.ButtonState.HIDDEN); + await enterConfirmationCode(ButtonState.HIDDEN); // Should still be at confirmation code page with input showing error. assertConfirmationCodePage( /*forwardButtonShouldBeEnabled*/ true, - /*backButtonState*/ cellularSetup.ButtonState.HIDDEN); + /*backButtonState*/ ButtonState.HIDDEN); assertTrue(confirmationCodeInput.invalid); endFlowAndVerifyResult(ESimSetupFlowResult.INSTALL_FAIL); @@ -531,7 +521,7 @@ // Confirmation code page should be showing. assertConfirmationCodePage( /*forwardButtonShouldBeEnabled*/ false, - /*backButtonState*/ cellularSetup.ButtonState.HIDDEN); + /*backButtonState*/ ButtonState.HIDDEN); confirmationCodePage.$$('#confirmationCode').value = 'CONFIRMATION_CODE'; endFlowAndVerifyResult( @@ -577,15 +567,14 @@ function skipDiscovery() { // Simulate pressing 'Skip'. - assertTrue( - eSimPage.buttonState.forward === cellularSetup.ButtonState.ENABLED); + assertTrue(eSimPage.buttonState.forward === ButtonState.ENABLED); eSimPage.navigateForward(); - Polymer.dom.flush(); + flush(); // Should now be at the activation code page. assertActivationCodePage( /*forwardButtonShouldBeEnabled*/ false, - /*backButtonState*/ cellularSetup.ButtonState.ENABLED); + /*backButtonState*/ ButtonState.ENABLED); assertFocusDefaultButtonEventFired(); // Insert an activation code. @@ -594,7 +583,7 @@ assertActivationCodePage( /*forwardButtonShouldBeEnabled*/ true, - /*backButtonState*/ cellularSetup.ButtonState.ENABLED); + /*backButtonState*/ ButtonState.ENABLED); } test('Skip discovery flow', async function() { @@ -602,7 +591,7 @@ await navigateForwardForInstall( activationCodePage, - /*backButtonState*/ cellularSetup.ButtonState.ENABLED); + /*backButtonState*/ ButtonState.ENABLED); // Should now be at the final page. await assertFinalPageAndPressDoneButton(false); @@ -621,12 +610,12 @@ await navigateForwardForInstall( activationCodePage, - /*backButtonState*/ cellularSetup.ButtonState.ENABLED); + /*backButtonState*/ ButtonState.ENABLED); // Confirmation code page should be showing. assertConfirmationCodePage( /*forwardButtonShouldBeEnabled*/ false, - /*backButtonState*/ cellularSetup.ButtonState.ENABLED); + /*backButtonState*/ ButtonState.ENABLED); assertFocusDefaultButtonEventFired(); confirmationCodePage.$$('#confirmationCode').value = 'CONFIRMATION_CODE'; @@ -638,7 +627,7 @@ assertActivationCodePage( /*forwardButtonShouldBeEnabled*/ true, - /*backButtonState*/ cellularSetup.ButtonState.ENABLED); + /*backButtonState*/ ButtonState.ENABLED); assertFocusDefaultButtonEventFired(); assertEquals( activationCodePage.$$('#activationCode').value, @@ -660,16 +649,15 @@ // Select the first profile on the list. const profileList = profileDiscoveryPage.$$('#profileList'); profileList.selectItem(profileList.items[0]); - Polymer.dom.flush(); + flush(); // The 'Forward' button should now be enabled. - assertTrue( - eSimPage.buttonState.forward === cellularSetup.ButtonState.ENABLED); + assertTrue(eSimPage.buttonState.forward === ButtonState.ENABLED); // Simulate pressing 'Forward'. await navigateForwardForInstall( profileDiscoveryPage, - /*backButtonState*/ cellularSetup.ButtonState.HIDDEN); + /*backButtonState*/ ButtonState.HIDDEN); } test('Select profile flow', async function() { @@ -694,13 +682,13 @@ // Confirmation code page should be showing. assertConfirmationCodePage( /*forwardButtonShouldBeEnabled*/ false, - /*backButtonState*/ cellularSetup.ButtonState.ENABLED); + /*backButtonState*/ ButtonState.ENABLED); assertFocusDefaultButtonEventFired(); profileList.profiles[0].setProfileInstallResultForTest( ash.cellularSetup.mojom.ProfileInstallResult.kSuccess); await enterConfirmationCode( - /*backButtonState*/ cellularSetup.ButtonState.ENABLED); + /*backButtonState*/ ButtonState.ENABLED); // Should go to final page. await assertFinalPageAndPressDoneButton(false); @@ -724,7 +712,7 @@ // Confirmation code page should be showing. assertConfirmationCodePage( /*forwardButtonShouldBeEnabled*/ false, - /*backButtonState*/ cellularSetup.ButtonState.ENABLED); + /*backButtonState*/ ButtonState.ENABLED); confirmationCodePage.$$('#confirmationCode').value = 'CONFIRMATION_CODE'; @@ -764,8 +752,7 @@ pSimNetwork.connectionState = chromeos.networkConfig.mojom.ConnectionStateType.kConnected; networkConfigRemote.addNetworksForTest([pSimNetwork]); - network_config.MojoInterfaceProviderImpl.getInstance().remote_ = - networkConfigRemote; + MojoInterfaceProviderImpl.getInstance().remote_ = networkConfigRemote; await flushAsync(); assertEquals(
diff --git a/chrome/test/data/webui/cr_components/chromeos/cellular_setup/fake_barcode_detector.js b/chrome/test/data/webui/cr_components/chromeos/cellular_setup/fake_barcode_detector.js index df23a8b..f89a3b23 100644 --- a/chrome/test/data/webui/cr_components/chromeos/cellular_setup/fake_barcode_detector.js +++ b/chrome/test/data/webui/cr_components/chromeos/cellular_setup/fake_barcode_detector.js
@@ -18,7 +18,7 @@ /** * @implements {BarcodeDetector} */ -/* #export */ class FakeBarcodeDetector { +export class FakeBarcodeDetector { constructor() {} /** @override */ @@ -53,7 +53,7 @@ /** * @implements {ImageCapture} */ -/* #export */ class FakeImageCapture { +export class FakeImageCapture { constructor(mediaStream) { this.track = { readyState: 'live', @@ -66,4 +66,4 @@ grabFrame() { return null; } -} \ No newline at end of file +}
diff --git a/chrome/test/data/webui/cr_components/chromeos/cellular_setup/fake_canvas_context.js b/chrome/test/data/webui/cr_components/chromeos/cellular_setup/fake_canvas_context.js index 4ddb3b1..2314b85b 100644 --- a/chrome/test/data/webui/cr_components/chromeos/cellular_setup/fake_canvas_context.js +++ b/chrome/test/data/webui/cr_components/chromeos/cellular_setup/fake_canvas_context.js
@@ -2,41 +2,36 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -cr.define('cellular_setup', function() { - /** - * @implements {CanvasRenderingContext2D} - */ - /* #export */ class FakeCanvasContext { - constructor() { - this.clearRectCalls_ = []; - this.fillRectCalls_ = []; - } - - /** @override */ - clearRect(x, y, width, height) { - this.clearRectCalls_.push([x, y, width, height]); - } - - /** @override */ - fillRect(x, y, width, height) { - this.fillRectCalls_.push([x, y, width, height]); - } - - /** - * @return {Array<Array<int>} - */ - getClearRectCalls() { - return this.clearRectCalls_; - } - - /** - * @return {Array<Array<int>} - */ - getFillRectCalls() { - return this.fillRectCalls_; - } +/** + * @implements {CanvasRenderingContext2D} + */ +export class FakeCanvasContext { + constructor() { + this.clearRectCalls_ = []; + this.fillRectCalls_ = []; } - // #cr_define_end - return {FakeCanvasContext}; -}); \ No newline at end of file + /** @override */ + clearRect(x, y, width, height) { + this.clearRectCalls_.push([x, y, width, height]); + } + + /** @override */ + fillRect(x, y, width, height) { + this.fillRectCalls_.push([x, y, width, height]); + } + + /** + * @return {Array<Array<int>} + */ + getClearRectCalls() { + return this.clearRectCalls_; + } + + /** + * @return {Array<Array<int>} + */ + getFillRectCalls() { + return this.fillRectCalls_; + } +}
diff --git a/chrome/test/data/webui/cr_components/chromeos/cellular_setup/fake_cellular_setup_delegate.js b/chrome/test/data/webui/cr_components/chromeos/cellular_setup/fake_cellular_setup_delegate.js index 69ad6f9a..20e0d17 100644 --- a/chrome/test/data/webui/cr_components/chromeos/cellular_setup/fake_cellular_setup_delegate.js +++ b/chrome/test/data/webui/cr_components/chromeos/cellular_setup/fake_cellular_setup_delegate.js
@@ -2,26 +2,17 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// clang-format off -// #import {CellularSetupDelegate} from 'chrome://resources/cr_components/chromeos/cellular_setup/cellular_setup_delegate.m.js'; -// clang-format on +import {CellularSetupDelegate} from 'chrome://resources/cr_components/chromeos/cellular_setup/cellular_setup_delegate.m.js'; -cr.define('cellular_setup', function() { - /** @implements {cellular_setup.CellularSetupDelegate} */ - /* #export */ class FakeCellularSetupDelegate { - /** @override */ - shouldShowPageTitle() { - return false; - } - - /** @override */ - shouldShowCancelButton() { - return true; - } +/** @implements {CellularSetupDelegate} */ +export class FakeCellularSetupDelegate { + /** @override */ + shouldShowPageTitle() { + return false; } - // #cr_define_end - return { - FakeCellularSetupDelegate: FakeCellularSetupDelegate, - }; -}); \ No newline at end of file + /** @override */ + shouldShowCancelButton() { + return true; + } +}
diff --git a/chrome/test/data/webui/cr_components/chromeos/cellular_setup/fake_cellular_setup_remote.js b/chrome/test/data/webui/cr_components/chromeos/cellular_setup/fake_cellular_setup_remote.js index b2e47b1..28ebb80 100644 --- a/chrome/test/data/webui/cr_components/chromeos/cellular_setup/fake_cellular_setup_remote.js +++ b/chrome/test/data/webui/cr_components/chromeos/cellular_setup/fake_cellular_setup_remote.js
@@ -2,50 +2,41 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +/** + * @implements {ash.cellularSetup.mojom.CarrierPortalHandlerInterface} + */ +export class FakeCarrierPortalHandlerRemote { + constructor() {} -cr.define('cellular_setup', function() { + /** @override */ + onCarrierPortalStatusChange(status) { + this.status_ = status; + } +} + +/** @implements {ash.cellularSetup.mojom.CellularSetupInterface} */ +export class FakeCellularSetupRemote { /** - * @implements {ash.cellularSetup.mojom.CarrierPortalHandlerInterface} + * @param {!FakeCarrierPortalHandlerRemote} handler */ - /* #export */ class FakeCarrierPortalHandlerRemote { - constructor() {} - - /** @override */ - onCarrierPortalStatusChange(status) { - this.status_ = status; - } + constructor(handler) { + this.carrierHandler_ = handler; } - /** @implements {ash.cellularSetup.mojom.CellularSetupInterface} */ - /* #export */ class FakeCellularSetupRemote { - /** - * @param {!FakeCarrierPortalHandlerRemote} handler - */ - constructor(handler) { - this.carrierHandler_ = handler; - } - - /** @override */ - startActivation(delegate) { - this.delegate_ = delegate; - return new Promise((resolve, reject) => { - setTimeout(function() { - resolve({observer: this.carrierHandler_}); - }); + /** @override */ + startActivation(delegate) { + this.delegate_ = delegate; + return new Promise((resolve, reject) => { + setTimeout(function() { + resolve({observer: this.carrierHandler_}); }); - } - - /** - * @returns {!ash.cellularSetup.mojom.ActivationDelegateRemote} - */ - getLastActivationDelegate() { - return this.delegate_; - } + }); } - // #cr_define_end - return { - FakeCellularSetupRemote: FakeCellularSetupRemote, - FakeCarrierPortalHandlerRemote: FakeCarrierPortalHandlerRemote, - }; -}); + /** + * @returns {!ash.cellularSetup.mojom.ActivationDelegateRemote} + */ + getLastActivationDelegate() { + return this.delegate_; + } +}
diff --git a/chrome/test/data/webui/cr_components/chromeos/cellular_setup/fake_esim_manager_remote.js b/chrome/test/data/webui/cr_components/chromeos/cellular_setup/fake_esim_manager_remote.js index a4883190..b4d8754 100644 --- a/chrome/test/data/webui/cr_components/chromeos/cellular_setup/fake_esim_manager_remote.js +++ b/chrome/test/data/webui/cr_components/chromeos/cellular_setup/fake_esim_manager_remote.js
@@ -2,378 +2,370 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +/** @implements {ash.cellularSetup.mojom.ESimProfile} */ +class FakeProfile { + constructor(eid, iccid, fakeEuicc) { + this.properties = { + eid, + iccid, + activationCode: 'activation-code-' + iccid, + name: { + data: this.stringToCharCodeArray_('profile' + iccid), + }, + nickname: { + data: this.stringToCharCodeArray_('profile' + iccid), + }, + serviceProvider: { + data: this.stringToCharCodeArray_('provider' + iccid), + }, + state: ash.cellularSetup.mojom.ProfileState.kPending, + }; -cr.define('cellular_setup', function() { - /** @implements {ash.cellularSetup.mojom.ESimProfile} */ - class FakeProfile { - constructor(eid, iccid, fakeEuicc) { - this.properties = { - eid, - iccid, - activationCode: 'activation-code-' + iccid, - name: { - data: this.stringToCharCodeArray_('profile' + iccid), - }, - nickname: { - data: this.stringToCharCodeArray_('profile' + iccid), - }, - serviceProvider: { - data: this.stringToCharCodeArray_('provider' + iccid), - }, - state: ash.cellularSetup.mojom.ProfileState.kPending, - }; + this.deferGetProperties_ = false; + this.deferredGetPropertiesPromises_ = []; + this.fakeEuicc_ = fakeEuicc; + } - this.deferGetProperties_ = false; - this.deferredGetPropertiesPromises_ = []; - this.fakeEuicc_ = fakeEuicc; - } - - /** - * @override - * @return {!Promise<{properties: - * ash.cellularSetup.mojom.ESimProfileProperties},}>} - */ - getProperties() { - if (this.deferGetProperties_) { - const deferred = this.deferredPromise_(); - this.deferredGetPropertiesPromises_.push(deferred); - return deferred.promise; - } else { - return Promise.resolve({ - properties: this.properties, - }); - } - } - - /** - * @param {boolean} defer - */ - setDeferGetProperties(defer) { - this.deferGetProperties_ = defer; - } - - resolveLastGetPropertiesPromise() { - if (!this.deferredGetPropertiesPromises_.length) { - return; - } - const deferred = this.deferredGetPropertiesPromises_.pop(); - deferred.resolve({properties: this.properties}); - } - - /** - * @override - * @param {string} confirmationCode - * @return {!Promise<{result: - * ash.cellularSetup.mojom.ProfileInstallResult},}>} - */ - installProfile(confirmationCode) { - if (!this.profileInstallResult_ || - this.profileInstallResult_ === - ash.cellularSetup.mojom.ProfileInstallResult.kSuccess) { - this.properties.state = ash.cellularSetup.mojom.ProfileState.kActive; - } - this.fakeEuicc_.notifyProfileChangedForTest(this); - this.fakeEuicc_.notifyProfileListChangedForTest(); - // Simulate a delay in response. This is neccessary because a few tests - // require UI to be in installing state. - return new Promise( - resolve => setTimeout( - () => resolve({ - result: this.profileInstallResult_ ? - this.profileInstallResult_ : - ash.cellularSetup.mojom.ProfileInstallResult.kSuccess - }), - 0)); - } - - /** - * @param {ash.cellularSetup.mojom.ProfileInstallResult} result - */ - setProfileInstallResultForTest(result) { - this.profileInstallResult_ = result; - } - - /** - * @param {ash.cellularSetup.mojom.ESimOperationResult} result - */ - setEsimOperationResultForTest(result) { - this.esimOperationResult_ = result; - } - - /** - * @param {string} string - * @private - */ - stringToCharCodeArray_(string) { - const res = []; - for (let i = 0; i < string.length; i++) { - res.push(string.charCodeAt(i)); - } - return res; - } - - /** - * @return {Object} - * @private - */ - deferredPromise_() { - const deferred = {}; - const promise = new Promise(function(resolve, reject) { - deferred.resolve = resolve; - deferred.reject = reject; - }); - deferred.promise = promise; - return deferred; - } - - /** - * @override - * @param {?mojoBase.mojom.String16} nickname - * @return {!Promise<{result: - * ash.cellularSetup.mojom.ESimOperationResult},}>} - */ - setProfileNickname(nickname) { - if (!this.esimOperationResult_ || - this.esimOperationResult_ === - ash.cellularSetup.mojom.ESimOperationResult.kSuccess) { - this.properties.nickname = nickname; - } - - this.deferredSetProfileNicknamePromise_ = this.deferredPromise_(); - return this.deferredSetProfileNicknamePromise_.promise; - } - - /** @private */ - resolveSetProfileNicknamePromise_() { - this.deferredSetProfileNicknamePromise_.resolve({ - result: this.esimOperationResult_ ? - this.esimOperationResult_ : - ash.cellularSetup.mojom.ESimOperationResult.kSuccess - }); - } - - /** @override */ - uninstallProfile() { - this.fakeEuicc_.notifyProfileChangedForTest(this); - this.defferedUninstallProfilePromise_ = this.deferredPromise_(); - return this.defferedUninstallProfilePromise_.promise; - } - - /** @return {Promise<void>} */ - async resolveUninstallProfilePromise() { - if (!this.esimOperationResult_ || - this.esimOperationResult_ === - ash.cellularSetup.mojom.ESimOperationResult.kSuccess) { - const removeProfileResult = - await this.fakeEuicc_.removeProfileForTest(this.properties.iccid); - this.defferedUninstallProfilePromise_.resolve(removeProfileResult); - return; - } - - this.defferedUninstallProfilePromise_.resolve({ - result: this.esimOperationResult_ ? - this.esimOperationResult_ : - ash.cellularSetup.mojom.ESimOperationResult.kSuccess + /** + * @override + * @return {!Promise<{properties: + * ash.cellularSetup.mojom.ESimProfileProperties},}>} + */ + getProperties() { + if (this.deferGetProperties_) { + const deferred = this.deferredPromise_(); + this.deferredGetPropertiesPromises_.push(deferred); + return deferred.promise; + } else { + return Promise.resolve({ + properties: this.properties, }); } } - /** @implements {ash.cellularSetup.mojom.Euicc} */ - class FakeEuicc { - constructor(eid, numProfiles, fakeESimManager) { - this.fakeESimManager_ = fakeESimManager; - this.properties = {eid}; - this.profiles_ = []; - for (let i = 0; i < numProfiles; i++) { - this.addProfile(); + /** + * @param {boolean} defer + */ + setDeferGetProperties(defer) { + this.deferGetProperties_ = defer; + } + + resolveLastGetPropertiesPromise() { + if (!this.deferredGetPropertiesPromises_.length) { + return; + } + const deferred = this.deferredGetPropertiesPromises_.pop(); + deferred.resolve({properties: this.properties}); + } + + /** + * @override + * @param {string} confirmationCode + * @return {!Promise<{result: + * ash.cellularSetup.mojom.ProfileInstallResult},}>} + */ + installProfile(confirmationCode) { + if (!this.profileInstallResult_ || + this.profileInstallResult_ === + ash.cellularSetup.mojom.ProfileInstallResult.kSuccess) { + this.properties.state = ash.cellularSetup.mojom.ProfileState.kActive; + } + this.fakeEuicc_.notifyProfileChangedForTest(this); + this.fakeEuicc_.notifyProfileListChangedForTest(); + // Simulate a delay in response. This is neccessary because a few tests + // require UI to be in installing state. + return new Promise( + resolve => setTimeout( + () => resolve({ + result: this.profileInstallResult_ ? + this.profileInstallResult_ : + ash.cellularSetup.mojom.ProfileInstallResult.kSuccess + }), + 0)); + } + + /** + * @param {ash.cellularSetup.mojom.ProfileInstallResult} result + */ + setProfileInstallResultForTest(result) { + this.profileInstallResult_ = result; + } + + /** + * @param {ash.cellularSetup.mojom.ESimOperationResult} result + */ + setEsimOperationResultForTest(result) { + this.esimOperationResult_ = result; + } + + /** + * @param {string} string + * @private + */ + stringToCharCodeArray_(string) { + const res = []; + for (let i = 0; i < string.length; i++) { + res.push(string.charCodeAt(i)); + } + return res; + } + + /** + * @return {Object} + * @private + */ + deferredPromise_() { + const deferred = {}; + const promise = new Promise(function(resolve, reject) { + deferred.resolve = resolve; + deferred.reject = reject; + }); + deferred.promise = promise; + return deferred; + } + + /** + * @override + * @param {?mojoBase.mojom.String16} nickname + * @return {!Promise<{result: + * ash.cellularSetup.mojom.ESimOperationResult},}>} + */ + setProfileNickname(nickname) { + if (!this.esimOperationResult_ || + this.esimOperationResult_ === + ash.cellularSetup.mojom.ESimOperationResult.kSuccess) { + this.properties.nickname = nickname; + } + + this.deferredSetProfileNicknamePromise_ = this.deferredPromise_(); + return this.deferredSetProfileNicknamePromise_.promise; + } + + /** @private */ + resolveSetProfileNicknamePromise_() { + this.deferredSetProfileNicknamePromise_.resolve({ + result: this.esimOperationResult_ ? + this.esimOperationResult_ : + ash.cellularSetup.mojom.ESimOperationResult.kSuccess + }); + } + + /** @override */ + uninstallProfile() { + this.fakeEuicc_.notifyProfileChangedForTest(this); + this.defferedUninstallProfilePromise_ = this.deferredPromise_(); + return this.defferedUninstallProfilePromise_.promise; + } + + /** @return {Promise<void>} */ + async resolveUninstallProfilePromise() { + if (!this.esimOperationResult_ || + this.esimOperationResult_ === + ash.cellularSetup.mojom.ESimOperationResult.kSuccess) { + const removeProfileResult = + await this.fakeEuicc_.removeProfileForTest(this.properties.iccid); + this.defferedUninstallProfilePromise_.resolve(removeProfileResult); + return; + } + + this.defferedUninstallProfilePromise_.resolve({ + result: this.esimOperationResult_ ? + this.esimOperationResult_ : + ash.cellularSetup.mojom.ESimOperationResult.kSuccess + }); + } +} + +/** @implements {ash.cellularSetup.mojom.Euicc} */ +class FakeEuicc { + constructor(eid, numProfiles, fakeESimManager) { + this.fakeESimManager_ = fakeESimManager; + this.properties = {eid}; + this.profiles_ = []; + for (let i = 0; i < numProfiles; i++) { + this.addProfile(); + } + this.requestPendingProfilesResult_ = + ash.cellularSetup.mojom.ESimOperationResult.kSuccess; + } + + /** + * @override + * @return {!Promise<{properties: + * ash.cellularSetup.mojom.EuiccProperties},}>} + */ + getProperties() { + return Promise.resolve({properties: this.properties}); + } + + /** + * @override + * @return {!Promise<{result: + * ash.cellularSetup.mojom.ESimOperationResult},}>} + */ + requestPendingProfiles() { + return Promise.resolve({ + result: this.requestPendingProfilesResult_, + }); + } + + /** + * @override + * @return {!Promise<{profiles: Array<!ESimProfile>,}>} + */ + getProfileList() { + return Promise.resolve({ + profiles: this.profiles_, + }); + } + + /** + * @override + * @return {!Promise<{qrCode: ash.cellularSetup.mojom.QRCode} | null>} + */ + getEidQRCode() { + if (this.eidQRCode_) { + return Promise.resolve({qrCode: this.eidQRCode_}); + } else { + return Promise.resolve(null); + } + } + + /** + * @override + * @param {string} activationCode + * @param {string} confirmationCode + * @return {!Promise<{result: + * ash.cellularSetup.mojom.ProfileInstallResult},}>} + */ + installProfileFromActivationCode(activationCode, confirmationCode) { + this.notifyProfileListChangedForTest(); + return Promise.resolve({ + result: this.profileInstallResult_ ? + this.profileInstallResult_ : + ash.cellularSetup.mojom.ProfileInstallResult.kSuccess, + }); + } + + /** + * @param {ash.cellularSetup.mojom.ESimOperationResult} result + */ + setRequestPendingProfilesResult(result) { + this.requestPendingProfilesResult_ = result; + } + + /** + * @param {ash.cellularSetup.mojom.ProfileInstallResult} result + */ + setProfileInstallResultForTest(result) { + this.profileInstallResult_ = result; + } + + /** + * @param {ash.cellularSetup.mojom.QRCode} qrcode + */ + setEidQRCodeForTest(qrcode) { + this.eidQRCode_ = qrcode; + } + + /** + * @param {string} iccid + */ + async removeProfileForTest(iccid) { + const result = []; + let profileRemoved = false; + for (const profile of this.profiles_) { + const property = await profile.getProperties(); + if (property.properties.iccid === iccid) { + profileRemoved = true; + continue; } - this.requestPendingProfilesResult_ = - ash.cellularSetup.mojom.ESimOperationResult.kSuccess; + result.push(profile); } + this.profiles_ = result; - /** - * @override - * @return {!Promise<{properties: - * ash.cellularSetup.mojom.EuiccProperties},}>} - */ - getProperties() { - return Promise.resolve({properties: this.properties}); - } - - /** - * @override - * @return {!Promise<{result: - * ash.cellularSetup.mojom.ESimOperationResult},}>} - */ - requestPendingProfiles() { - return Promise.resolve({ - result: this.requestPendingProfilesResult_, - }); - } - - /** - * @override - * @return {!Promise<{profiles: Array<!ESimProfile>,}>} - */ - getProfileList() { - return Promise.resolve({ - profiles: this.profiles_, - }); - } - - /** - * @override - * @return {!Promise<{qrCode: ash.cellularSetup.mojom.QRCode} | null>} - */ - getEidQRCode() { - if (this.eidQRCode_) { - return Promise.resolve({qrCode: this.eidQRCode_}); - } else { - return Promise.resolve(null); - } - } - - /** - * @override - * @param {string} activationCode - * @param {string} confirmationCode - * @return {!Promise<{result: - * ash.cellularSetup.mojom.ProfileInstallResult},}>} - */ - installProfileFromActivationCode(activationCode, confirmationCode) { + if (profileRemoved) { this.notifyProfileListChangedForTest(); - return Promise.resolve({ - result: this.profileInstallResult_ ? - this.profileInstallResult_ : - ash.cellularSetup.mojom.ProfileInstallResult.kSuccess, - }); + return {result: ash.cellularSetup.mojom.ESimOperationResult.kSuccess}; } + return {result: ash.cellularSetup.mojom.ESimOperationResult.kFailure}; + } - /** - * @param {ash.cellularSetup.mojom.ESimOperationResult} result - */ - setRequestPendingProfilesResult(result) { - this.requestPendingProfilesResult_ = result; - } + /** + * @param {FakeProfile} profile + */ + notifyProfileChangedForTest(profile) { + this.fakeESimManager_.notifyProfileChangedForTest(profile); + } - /** - * @param {ash.cellularSetup.mojom.ProfileInstallResult} result - */ - setProfileInstallResultForTest(result) { - this.profileInstallResult_ = result; - } + notifyProfileListChangedForTest() { + this.fakeESimManager_.notifyProfileListChangedForTest(this); + } - /** - * @param {ash.cellularSetup.mojom.QRCode} qrcode - */ - setEidQRCodeForTest(qrcode) { - this.eidQRCode_ = qrcode; - } + /** @private */ + addProfile() { + const iccid = this.profiles_.length + 1 + ''; + this.profiles_.push(new FakeProfile(this.properties.eid, iccid, this)); + } +} - /** - * @param {string} iccid - */ - async removeProfileForTest(iccid) { - const result = []; - let profileRemoved = false; - for (const profile of this.profiles_) { - const property = await profile.getProperties(); - if (property.properties.iccid === iccid) { - profileRemoved = true; - continue; - } - result.push(profile); - } - this.profiles_ = result; +/** @implements {ash.cellularSetup.mojom.ESimManagerInterface} */ +export class FakeESimManagerRemote { + constructor() { + this.euiccs_ = []; + this.observers_ = []; + } - if (profileRemoved) { - this.notifyProfileListChangedForTest(); - return {result: ash.cellularSetup.mojom.ESimOperationResult.kSuccess}; - } - return {result: ash.cellularSetup.mojom.ESimOperationResult.kFailure}; - } + /** + * @override + * @return {!Promise<{euiccs: !Array<!Euicc>,}>} + */ + getAvailableEuiccs() { + return Promise.resolve({ + euiccs: this.euiccs_, + }); + } - /** - * @param {FakeProfile} profile - */ - notifyProfileChangedForTest(profile) { - this.fakeESimManager_.notifyProfileChangedForTest(profile); - } + /** + * @param {number} numProfiles The number of profiles the EUICC has. + * @return {FakeEuicc} The euicc that was added. + */ + addEuiccForTest(numProfiles) { + const eid = this.euiccs_.length + 1 + ''; + const euicc = new FakeEuicc(eid, numProfiles, this); + this.euiccs_.push(euicc); + this.notifyAvailableEuiccListChanged(); + return euicc; + } - notifyProfileListChangedForTest() { - this.fakeESimManager_.notifyProfileListChangedForTest(this); - } + /** + * @param {!ash.cellularSetup.mojom.ESimManagerObserverInterface} observer + */ + addObserver(observer) { + this.observers_.push(observer); + } - /** @private */ - addProfile() { - const iccid = this.profiles_.length + 1 + ''; - this.profiles_.push(new FakeProfile(this.properties.eid, iccid, this)); + notifyAvailableEuiccListChanged() { + for (const observer of this.observers_) { + observer.onAvailableEuiccListChanged(); } } - /** @implements {ash.cellularSetup.mojom.ESimManagerInterface} */ - /* #export */ class FakeESimManagerRemote { - constructor() { - this.euiccs_ = []; - this.observers_ = []; - } - - /** - * @override - * @return {!Promise<{euiccs: !Array<!Euicc>,}>} - */ - getAvailableEuiccs() { - return Promise.resolve({ - euiccs: this.euiccs_, - }); - } - - /** - * @param {number} numProfiles The number of profiles the EUICC has. - * @return {FakeEuicc} The euicc that was added. - */ - addEuiccForTest(numProfiles) { - const eid = this.euiccs_.length + 1 + ''; - const euicc = new FakeEuicc(eid, numProfiles, this); - this.euiccs_.push(euicc); - this.notifyAvailableEuiccListChanged(); - return euicc; - } - - /** - * @param {!ash.cellularSetup.mojom.ESimManagerObserverInterface} observer - */ - addObserver(observer) { - this.observers_.push(observer); - } - - notifyAvailableEuiccListChanged() { - for (const observer of this.observers_) { - observer.onAvailableEuiccListChanged(); - } - } - - /** - * @param {FakeEuicc} euicc - */ - notifyProfileListChangedForTest(euicc) { - for (const observer of this.observers_) { - observer.onProfileListChanged(euicc); - } - } - - /** - * @param {FakeProfile} profile - */ - notifyProfileChangedForTest(profile) { - for (const observer of this.observers_) { - observer.onProfileChanged(profile); - } + /** + * @param {FakeEuicc} euicc + */ + notifyProfileListChangedForTest(euicc) { + for (const observer of this.observers_) { + observer.onProfileListChanged(euicc); } } - // #cr_define_end - return { - FakeESimManagerRemote: FakeESimManagerRemote, - }; -}); + /** + * @param {FakeProfile} profile + */ + notifyProfileChangedForTest(profile) { + for (const observer of this.observers_) { + observer.onProfileChanged(profile); + } + } +}
diff --git a/chrome/test/data/webui/cr_components/chromeos/cellular_setup/fake_media_devices.js b/chrome/test/data/webui/cr_components/chromeos/cellular_setup/fake_media_devices.js index 623651b..e1333ab7 100644 --- a/chrome/test/data/webui/cr_components/chromeos/cellular_setup/fake_media_devices.js +++ b/chrome/test/data/webui/cr_components/chromeos/cellular_setup/fake_media_devices.js
@@ -2,110 +2,101 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -cr.define('cellular_setup', function() { +/** + * @implements {MediaDevices} + */ +export class FakeMediaDevices { + constructor() { + this.isStreamingUserFacingCamera = true; + this.devices_ = []; + + /** @private {?function()} */ + this.enumerateDevicesResolver_ = null; + + /** @private {?function()} */ + this.getMediaDevicesResolver_ = null; + } + + /** @override */ + addEventListener(type, listener) { + this.deviceChangeListener_ = listener; + } + + /** @override */ + enumerateDevices() { + return new Promise((res, rej) => { + this.enumerateDevicesResolver_ = res; + }); + } + /** - * @implements {MediaDevices} + * Resolves promise returned from enumerateDevices(). */ - /* #export */ class FakeMediaDevices { - constructor() { - this.isStreamingUserFacingCamera = true; - this.devices_ = []; + resolveEnumerateDevices() { + assertTrue( + !!this.enumerateDevicesResolver_, 'enumerateDevices was not called'); + this.enumerateDevicesResolver_(this.devices_); + } - /** @private {?function()} */ - this.enumerateDevicesResolver_ = null; + /** @override */ + getSupportedConstraints() { + return null; + } - /** @private {?function()} */ - this.getMediaDevicesResolver_ = null; - } + /** @override */ + getDisplayMedia() { + return new Promise((res, rej) => { + res(null); + }); + } - /** @override */ - addEventListener(type, listener) { - this.deviceChangeListener_ = listener; - } + /** @override */ + getUserMedia(constraints) { + this.isStreamingUserFacingCamera = constraints.video.facingMode === 'user'; + return new Promise((res, rej) => { + this.getMediaDevicesResolver_ = res; + }); + } - /** @override */ - enumerateDevices() { - return new Promise((res, rej) => { - this.enumerateDevicesResolver_ = res; - }); - } + /** + * Resolves promise returned from getUserMedia(). + */ + resolveGetUserMedia() { + assertTrue(!!this.getMediaDevicesResolver_, 'getUserMedia was not called'); + this.getMediaDevicesResolver_(new MediaStream()); + } - /** - * Resolves promise returned from enumerateDevices(). - */ - resolveEnumerateDevices() { - assertTrue( - !!this.enumerateDevicesResolver_, 'enumerateDevices was not called'); - this.enumerateDevicesResolver_(this.devices_); - } + /** @override */ + removeEventListener(event, fn) {} - /** @override */ - getSupportedConstraints() { - return null; - } - - /** @override */ - getDisplayMedia() { - return new Promise((res, rej) => { - res(null); - }); - } - - /** @override */ - getUserMedia(constraints) { - this.isStreamingUserFacingCamera = - constraints.video.facingMode === 'user'; - return new Promise((res, rej) => { - this.getMediaDevicesResolver_ = res; - }); - } - - /** - * Resolves promise returned from getUserMedia(). - */ - resolveGetUserMedia() { - assertTrue( - !!this.getMediaDevicesResolver_, 'getUserMedia was not called'); - this.getMediaDevicesResolver_(new MediaStream()); - } - - /** @override */ - removeEventListener(event, fn) {} - - /** - * Adds a video input device to the list of media devices. - */ - addDevice() { - const device = { - deviceId: '', - kind: 'videoinput', - label: '', - groupId: '', - }; - device.__proto__ = MediaDeviceInfo.prototype; - this.devices_.push(device); - if (this.deviceChangeListener_) { - this.deviceChangeListener_(); - } - } - - /** - * Removes the most recently added media device from the list of media - * devices. - */ - removeDevice() { - this.devices_.pop(); - if (this.devices_.length <= 1) { - this.isStreamingUserFacingCamera = true; - } - if (this.deviceChangeListener_) { - this.deviceChangeListener_(); - } + /** + * Adds a video input device to the list of media devices. + */ + addDevice() { + const device = { + deviceId: '', + kind: 'videoinput', + label: '', + groupId: '', + }; + device.__proto__ = MediaDeviceInfo.prototype; + this.devices_.push(device); + if (this.deviceChangeListener_) { + this.deviceChangeListener_(); } } - // #cr_define_end - return { - FakeMediaDevices: FakeMediaDevices, - }; -}); \ No newline at end of file + /** + * Removes the most recently added media device from the list of media + * devices. + */ + removeDevice() { + this.devices_.pop(); + if (this.devices_.length <= 1) { + this.isStreamingUserFacingCamera = true; + } + if (this.deviceChangeListener_) { + this.deviceChangeListener_(); + } + } +}
diff --git a/chrome/test/data/webui/cr_components/chromeos/cellular_setup/final_page_test.js b/chrome/test/data/webui/cr_components/chromeos/cellular_setup/final_page_test.js index 8ee98a4..3689218 100644 --- a/chrome/test/data/webui/cr_components/chromeos/cellular_setup/final_page_test.js +++ b/chrome/test/data/webui/cr_components/chromeos/cellular_setup/final_page_test.js
@@ -2,21 +2,21 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// clang-format off -// #import 'chrome://resources/cr_components/chromeos/cellular_setup/final_page.m.js'; +import 'chrome://resources/cr_components/chromeos/cellular_setup/final_page.m.js'; -// #import {flush, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; -// #import {assertFalse, assertTrue} from '../../../chai_assert.js'; -// #import {FakeCellularSetupDelegate} from './fake_cellular_setup_delegate.m.js'; -// clang-format on +import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + +import {assertTrue} from '../../../chai_assert.js'; + +import {FakeCellularSetupDelegate} from './fake_cellular_setup_delegate.js'; suite('CrComponentsFinalPageTest', function() { let finalPage; setup(function() { finalPage = document.createElement('final-page'); - finalPage.delegate = new cellular_setup.FakeCellularSetupDelegate(); + finalPage.delegate = new FakeCellularSetupDelegate(); document.body.appendChild(finalPage); - Polymer.dom.flush(); + flush(); }); test('Base test', function() {
diff --git a/chrome/test/data/webui/cr_components/chromeos/cellular_setup/mock_metrics_private.js b/chrome/test/data/webui/cr_components/chromeos/cellular_setup/mock_metrics_private.js index 1236598..45e99c30 100644 --- a/chrome/test/data/webui/cr_components/chromeos/cellular_setup/mock_metrics_private.js +++ b/chrome/test/data/webui/cr_components/chromeos/cellular_setup/mock_metrics_private.js
@@ -2,54 +2,47 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -cr.define('cellular_setup', function() { - /** - * A mock to intercept metric logging calls. - */ - /* #export */ class MockMetricsPrivate { - constructor() { - this.cellularSetupResultDict_ = {}; - this.histogramCounts_ = {}; - } - - recordEnumerationValue(histogramName, setupFlowResult, enumSize) { - if (setupFlowResult in this.cellularSetupResultDict_) { - this.cellularSetupResultDict_[setupFlowResult]++; - } else { - this.cellularSetupResultDict_[setupFlowResult] = 1; - } - this.incrementHistogramCount_(histogramName); - } - - recordLongTime(histogramName, value) { - this.incrementHistogramCount_(histogramName); - } - - getHistogramEnumValueCount(enumValue) { - if (enumValue in this.cellularSetupResultDict_) { - return this.cellularSetupResultDict_[enumValue]; - } - return 0; - } - - getHistogramCount(histogramName) { - if (histogramName in this.histogramCounts_) { - return this.histogramCounts_[histogramName]; - } - return 0; - } - - incrementHistogramCount_(histogramName) { - if (histogramName in this.histogramCounts_) { - this.histogramCounts_[histogramName]++; - } else { - this.histogramCounts_[histogramName] = 1; - } - } +/** + * A mock to intercept metric logging calls. + */ +export class MockMetricsPrivate { + constructor() { + this.cellularSetupResultDict_ = {}; + this.histogramCounts_ = {}; } - // #cr_define_end - return { - MockMetricsPrivate: MockMetricsPrivate, - }; -}); \ No newline at end of file + recordEnumerationValue(histogramName, setupFlowResult, enumSize) { + if (setupFlowResult in this.cellularSetupResultDict_) { + this.cellularSetupResultDict_[setupFlowResult]++; + } else { + this.cellularSetupResultDict_[setupFlowResult] = 1; + } + this.incrementHistogramCount_(histogramName); + } + + recordLongTime(histogramName, value) { + this.incrementHistogramCount_(histogramName); + } + + getHistogramEnumValueCount(enumValue) { + if (enumValue in this.cellularSetupResultDict_) { + return this.cellularSetupResultDict_[enumValue]; + } + return 0; + } + + getHistogramCount(histogramName) { + if (histogramName in this.histogramCounts_) { + return this.histogramCounts_[histogramName]; + } + return 0; + } + + incrementHistogramCount_(histogramName) { + if (histogramName in this.histogramCounts_) { + this.histogramCounts_[histogramName]++; + } else { + this.histogramCounts_[histogramName] = 1; + } + } +}
diff --git a/chrome/test/data/webui/cr_components/chromeos/cellular_setup/provisioning_page_test.js b/chrome/test/data/webui/cr_components/chromeos/cellular_setup/provisioning_page_test.js index 7b692f8..cb952e91 100644 --- a/chrome/test/data/webui/cr_components/chromeos/cellular_setup/provisioning_page_test.js +++ b/chrome/test/data/webui/cr_components/chromeos/cellular_setup/provisioning_page_test.js
@@ -2,22 +2,22 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// clang-format off -// #import 'chrome://os-settings/strings.m.js'; -// #import 'chrome://resources/cr_components/chromeos/cellular_setup/provisioning_page.m.js'; +import 'chrome://os-settings/strings.m.js'; +import 'chrome://resources/cr_components/chromeos/cellular_setup/provisioning_page.m.js'; -// #import {flush, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; -// #import {assertFalse, assertTrue} from '../../../chai_assert.js'; -// #import {FakeCellularSetupDelegate} from './fake_cellular_setup_delegate.m.js'; -// clang-format on +import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + +import {assertTrue} from '../../../chai_assert.js'; + +import {FakeCellularSetupDelegate} from './fake_cellular_setup_delegate.js'; suite('CrComponentsProvisioningPageTest', function() { let provisioningPage; setup(function() { provisioningPage = document.createElement('provisioning-page'); - provisioningPage.delegate = new cellular_setup.FakeCellularSetupDelegate(); + provisioningPage.delegate = new FakeCellularSetupDelegate(); document.body.appendChild(provisioningPage); - Polymer.dom.flush(); + flush(); }); test('Base test', function() {
diff --git a/chrome/test/data/webui/cr_components/chromeos/cellular_setup/psim_flow_ui_test.js b/chrome/test/data/webui/cr_components/chromeos/cellular_setup/psim_flow_ui_test.js index fd946bf..c243e4c1 100644 --- a/chrome/test/data/webui/cr_components/chromeos/cellular_setup/psim_flow_ui_test.js +++ b/chrome/test/data/webui/cr_components/chromeos/cellular_setup/psim_flow_ui_test.js
@@ -2,20 +2,20 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// clang-format off -// #import 'chrome://os-settings/strings.m.js'; -// #import 'chrome://resources/cr_components/chromeos/cellular_setup/psim_flow_ui.m.js'; +import 'chrome://os-settings/strings.m.js'; +import 'chrome://resources/cr_components/chromeos/cellular_setup/psim_flow_ui.m.js'; -// #import {PSimUIState, PSimPageName, PSimSetupFlowResult, PSIM_SETUP_RESULT_METRIC_NAME, SUCCESSFUL_PSIM_SETUP_DURATION_METRIC_NAME, FAILED_PSIM_SETUP_DURATION_METRIC_NAME} from 'chrome://resources/cr_components/chromeos/cellular_setup/psim_flow_ui.m.js'; -// #import {setCellularSetupRemoteForTesting} from 'chrome://resources/cr_components/chromeos/cellular_setup/mojo_interface_provider.m.js'; -// #import {flush, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; -// #import {assertTrue} from '../../../chai_assert.js'; -// #import {ButtonState} from 'chrome://resources/cr_components/chromeos/cellular_setup/cellular_types.m.js'; -// #import {FakeCellularSetupDelegate} from './fake_cellular_setup_delegate.m.js'; -// #import {FakeCarrierPortalHandlerRemote, FakeCellularSetupRemote} from './fake_cellular_setup_remote.m.js'; -// #import {MockMetricsPrivate} from './mock_metrics_private.m.js'; -// #import {eventToPromise, flushTasks} from 'chrome://test/test_util.js'; -// clang-format on +import {ButtonState} from 'chrome://resources/cr_components/chromeos/cellular_setup/cellular_types.m.js'; +import {setCellularSetupRemoteForTesting} from 'chrome://resources/cr_components/chromeos/cellular_setup/mojo_interface_provider.m.js'; +import {FAILED_PSIM_SETUP_DURATION_METRIC_NAME, PSimPageName, PSimSetupFlowResult, PSimUIState, SUCCESSFUL_PSIM_SETUP_DURATION_METRIC_NAME} from 'chrome://resources/cr_components/chromeos/cellular_setup/psim_flow_ui.m.js'; +import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +import {eventToPromise} from 'chrome://test/test_util.js'; + +import {assertTrue} from '../../../chai_assert.js'; + +import {FakeCellularSetupDelegate} from './fake_cellular_setup_delegate.js'; +import {FakeCarrierPortalHandlerRemote, FakeCellularSetupRemote} from './fake_cellular_setup_remote.js'; +import {MockMetricsPrivate} from './mock_metrics_private.js'; suite('CrComponentsPsimFlowUiTest', function() { let pSimPage; @@ -33,7 +33,7 @@ let timeoutFunction = null; async function flushAsync() { - Polymer.dom.flush(); + flush(); // Use setTimeout to wait for the next macrotask. return new Promise(resolve => setTimeout(resolve)); } @@ -41,7 +41,7 @@ /** @param {PSimSetupFlowResult} pSimSetupFlowResult */ function endFlowAndVerifyResult(pSimSetupFlowResult) { pSimPage.remove(); - Polymer.dom.flush(); + flush(); assertEquals( chrome.metricsPrivate.getHistogramEnumValueCount(pSimSetupFlowResult), 1); @@ -69,26 +69,24 @@ } setup(async function() { - cellularCarrierHandler = - new cellular_setup.FakeCarrierPortalHandlerRemote(); - cellularSetupRemote = - new cellular_setup.FakeCellularSetupRemote(cellularCarrierHandler); - cellular_setup.setCellularSetupRemoteForTesting(cellularSetupRemote); + cellularCarrierHandler = new FakeCarrierPortalHandlerRemote(); + cellularSetupRemote = new FakeCellularSetupRemote(cellularCarrierHandler); + setCellularSetupRemoteForTesting(cellularSetupRemote); chrome.metricsPrivate = new MockMetricsPrivate(); pSimPage = document.createElement('psim-flow-ui'); - pSimPage.delegate = new cellular_setup.FakeCellularSetupDelegate(); + pSimPage.delegate = new FakeCellularSetupDelegate(); pSimPage.setTimerFunctionForTest(function(fn, milliseconds) { timeoutFunction = fn; return 1; }); const focusNextButtonPromise = - test_util.eventToPromise('focus-default-button', pSimPage); + eventToPromise('focus-default-button', pSimPage); pSimPage.initSubflow(); await focusNextButtonPromise; document.body.appendChild(pSimPage); - Polymer.dom.flush(); + flush(); }); teardown(function() { @@ -102,8 +100,7 @@ const provisioningPage = pSimPage.$$('#provisioningPage'); assertTrue(!!provisioningPage); assertFalse( - pSimPage.selectedPSimPageName_ === - cellularSetup.PSimPageName.provisioningPage); + pSimPage.selectedPSimPageName_ === PSimPageName.provisioningPage); cellularActivationDelegate.onActivationFinished( ash.cellularSetup.mojom.ActivationResult @@ -111,16 +108,13 @@ await flushAsync(); - assertTrue( - pSimPage.selectedPSimPageName_ === - cellularSetup.PSimPageName.PROVISIONING); + assertTrue(pSimPage.selectedPSimPageName_ === PSimPageName.PROVISIONING); endFlowAndVerifyResult(PSimSetupFlowResult.SUCCESS); }); test('Sim detection failure with retries', async function() { - assertTrue( - pSimPage.state_ === cellularSetup.PSimUIState.STARTING_ACTIVATION); + assertTrue(pSimPage.state_ === PSimUIState.STARTING_ACTIVATION); assertTrue(!!pSimPage.currentTimeoutId_); await flushAsync(); @@ -128,15 +122,13 @@ // Simulate timeout. timeoutFunction(); - assertTrue( - pSimPage.state_ === cellularSetup.PSimUIState.TIMEOUT_START_ACTIVATION); + assertTrue(pSimPage.state_ === PSimUIState.TIMEOUT_START_ACTIVATION); assertTrue(pSimPage.forwardButtonLabel === 'Try again'); // Simulate clicking 'Try Again'. pSimPage.navigateForward(); - assertTrue( - pSimPage.state_ === cellularSetup.PSimUIState.STARTING_ACTIVATION); + assertTrue(pSimPage.state_ === PSimUIState.STARTING_ACTIVATION); assertTrue(!!pSimPage.currentTimeoutId_); await flushAsync(); @@ -144,15 +136,13 @@ // Timeout again. timeoutFunction(); - assertTrue( - pSimPage.state_ === cellularSetup.PSimUIState.TIMEOUT_START_ACTIVATION); + assertTrue(pSimPage.state_ === PSimUIState.TIMEOUT_START_ACTIVATION); assertTrue(pSimPage.forwardButtonLabel === 'Try again'); // Click 'Try Again' again. pSimPage.navigateForward(); - assertTrue( - pSimPage.state_ === cellularSetup.PSimUIState.STARTING_ACTIVATION); + assertTrue(pSimPage.state_ === PSimUIState.STARTING_ACTIVATION); assertTrue(!!pSimPage.currentTimeoutId_); await flushAsync(); @@ -161,9 +151,7 @@ timeoutFunction(); // Should now be at the failure state. - assertTrue( - pSimPage.state_ === - cellularSetup.PSimUIState.FINAL_TIMEOUT_START_ACTIVATION); + assertTrue(pSimPage.state_ === PSimUIState.FINAL_TIMEOUT_START_ACTIVATION); }); test('Carrier title on provisioning page', async () => { @@ -190,15 +178,13 @@ }); test('forward navigation and finish cellular setup test', async function() { - pSimPage.state_ = cellularSetup.PSimUIState.WAITING_FOR_PORTAL_TO_LOAD; - Polymer.dom.flush(); + pSimPage.state_ = PSimUIState.WAITING_FOR_PORTAL_TO_LOAD; + flush(); pSimPage.navigateForward(); assertTrue( - pSimPage.state_ === - cellularSetup.PSimUIState.WAITING_FOR_ACTIVATION_TO_FINISH); + pSimPage.state_ === PSimUIState.WAITING_FOR_ACTIVATION_TO_FINISH); - assertEquals( - cellularSetup.ButtonState.ENABLED, pSimPage.buttonState.forward); + assertEquals(ButtonState.ENABLED, pSimPage.buttonState.forward); assertEquals(pSimPage.forwardButtonLabel, 'Done'); let exitCellularSetupEventFired = false; pSimPage.addEventListener('exit-cellular-setup', () => { @@ -240,8 +226,7 @@ const provisioningPage = pSimPage.$$('#provisioningPage'); assertTrue(!!provisioningPage); assertFalse( - pSimPage.selectedPSimPageName_ === - cellularSetup.PSimPageName.provisioningPage); + pSimPage.selectedPSimPageName_ === PSimPageName.provisioningPage); cellularActivationDelegate.onActivationFinished( ash.cellularSetup.mojom.ActivationResult.kFailedToActivate);
diff --git a/chrome/test/data/webui/cr_components/chromeos/cellular_setup/setup_loading_page_test.js b/chrome/test/data/webui/cr_components/chromeos/cellular_setup/setup_loading_page_test.js index 06036b4..f7646f9 100644 --- a/chrome/test/data/webui/cr_components/chromeos/cellular_setup/setup_loading_page_test.js +++ b/chrome/test/data/webui/cr_components/chromeos/cellular_setup/setup_loading_page_test.js
@@ -2,13 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// clang-format off -// #import 'chrome://os-settings/strings.m.js'; -// #import 'chrome://resources/cr_components/chromeos/cellular_setup/setup_loading_page.m.js'; +import 'chrome://os-settings/strings.m.js'; +import 'chrome://resources/cr_components/chromeos/cellular_setup/setup_loading_page.m.js'; -// #import {flush, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; -// #import {assertFalse, assertTrue} from '../../../chai_assert.js'; -// clang-format on +import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + +import {assertFalse, assertTrue} from '../../../chai_assert.js'; suite('CrComponentsSetupLoadingPageTest', function() { let setupLoadingPage; @@ -17,7 +16,7 @@ setup(function() { setupLoadingPage = document.createElement('setup-loading-page'); document.body.appendChild(setupLoadingPage); - Polymer.dom.flush(); + flush(); basePage = setupLoadingPage.$$('base-page'); assertTrue(!!basePage); @@ -25,12 +24,12 @@ test('Loading animation and error graphic shown correctly', function() { setupLoadingPage.isSimDetectError = false; - Polymer.dom.flush(); + flush(); assertTrue(!!setupLoadingPage.$$('#animationContainer')); assertTrue(setupLoadingPage.$$('#simDetectError').hidden); setupLoadingPage.isSimDetectError = true; - Polymer.dom.flush(); + flush(); assertFalse(!!setupLoadingPage.$$('#animationContainer')); assertFalse(setupLoadingPage.$$('#simDetectError').hidden); });
diff --git a/chrome/test/data/webui/cr_components/chromeos/cr_components_chromeos_v3_browsertest.js b/chrome/test/data/webui/cr_components/chromeos/cr_components_chromeos_v3_browsertest.js index 5631c074..405aacc 100644 --- a/chrome/test/data/webui/cr_components/chromeos/cr_components_chromeos_v3_browsertest.js +++ b/chrome/test/data/webui/cr_components/chromeos/cr_components_chromeos_v3_browsertest.js
@@ -78,17 +78,17 @@ ].forEach(test => registerTest('MultiDeviceSetup', 'multidevice-setup', ...test)); [ - ['ActivationCodePage', 'cellular_setup/activation_code_page_test.m.js'], - ['BasePage', 'cellular_setup/base_page_test.m.js'], - ['ButtonBar', 'cellular_setup/button_bar_test.m.js'], - ['ConfirmationCodePage', 'cellular_setup/confirmation_code_page_test.m.js'], - ['CellularEidDialog', 'cellular_setup/cellular_eid_dialog_test.m.js'], - ['CellularSetup', 'cellular_setup/cellular_setup_test.m.js'], - ['EsimFlowUi', 'cellular_setup/esim_flow_ui_test.m.js'], - ['FinalPage', 'cellular_setup/final_page_test.m.js'], - ['ProvisioningPage', 'cellular_setup/provisioning_page_test.m.js'], - ['PsimFlowUi', 'cellular_setup/psim_flow_ui_test.m.js'], - ['SetupLoadingPage', 'cellular_setup/setup_loading_page_test.m.js'], + ['ActivationCodePage', 'cellular_setup/activation_code_page_test.js'], + ['BasePage', 'cellular_setup/base_page_test.js'], + ['ButtonBar', 'cellular_setup/button_bar_test.js'], + ['CellularEidDialog', 'cellular_setup/cellular_eid_dialog_test.js'], + ['CellularSetup', 'cellular_setup/cellular_setup_test.js'], + ['ConfirmationCodePage', 'cellular_setup/confirmation_code_page_test.js'], + ['EsimFlowUi', 'cellular_setup/esim_flow_ui_test.js'], + ['FinalPage', 'cellular_setup/final_page_test.js'], + ['ProvisioningPage', 'cellular_setup/provisioning_page_test.js'], + ['PsimFlowUi', 'cellular_setup/psim_flow_ui_test.js'], + ['SetupLoadingPage', 'cellular_setup/setup_loading_page_test.js'], ].forEach(test => registerTest('CellularSetup', 'os-settings', ...test)); // clang-format on
diff --git a/chrome/test/data/webui/cr_components/chromeos/network/network_list_item_test.js b/chrome/test/data/webui/cr_components/chromeos/network/network_list_item_test.js index 98160c33..2e0cff9 100644 --- a/chrome/test/data/webui/cr_components/chromeos/network/network_list_item_test.js +++ b/chrome/test/data/webui/cr_components/chromeos/network/network_list_item_test.js
@@ -16,7 +16,7 @@ // #import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; // #import {FakeNetworkConfig} from 'chrome://test/chromeos/fake_network_config_mojom.js'; // #import {setESimManagerRemoteForTesting} from 'chrome://resources/cr_components/chromeos/cellular_setup/mojo_interface_provider.m.js'; -// #import {FakeESimManagerRemote} from 'chrome://test/cr_components/chromeos/cellular_setup/fake_esim_manager_remote.m.js'; +// #import {FakeESimManagerRemote} from 'chrome://test/cr_components/chromeos/cellular_setup/fake_esim_manager_remote.js'; // #import {MojoInterfaceProviderImpl} from 'chrome://resources/cr_components/chromeos/network/mojo_interface_provider.m.js'; // #import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js'; // #import {NetworkList} from 'chrome://resources/cr_components/chromeos/network/network_list_types.m.js';
diff --git a/chrome/test/data/webui/settings/chromeos/cellular_networks_list_test.js b/chrome/test/data/webui/settings/chromeos/cellular_networks_list_test.js index 77bce66..1c3415e 100644 --- a/chrome/test/data/webui/settings/chromeos/cellular_networks_list_test.js +++ b/chrome/test/data/webui/settings/chromeos/cellular_networks_list_test.js
@@ -9,7 +9,7 @@ import {OncMojo} from 'chrome://resources/cr_components/chromeos/network/onc_mojo.m.js'; import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {FakeNetworkConfig} from 'chrome://test/chromeos/fake_network_config_mojom.js'; -import {FakeESimManagerRemote} from 'chrome://test/cr_components/chromeos/cellular_setup/fake_esim_manager_remote.m.js'; +import {FakeESimManagerRemote} from 'chrome://test/cr_components/chromeos/cellular_setup/fake_esim_manager_remote.js'; import {eventToPromise, flushTasks} from 'chrome://test/test_util.js'; import {assertEquals, assertFalse, assertTrue} from '../../chai_assert.js';
diff --git a/chrome/test/data/webui/settings/chromeos/esim_install_error_dialog_test.js b/chrome/test/data/webui/settings/chromeos/esim_install_error_dialog_test.js index f7b6130..9b2b43c 100644 --- a/chrome/test/data/webui/settings/chromeos/esim_install_error_dialog_test.js +++ b/chrome/test/data/webui/settings/chromeos/esim_install_error_dialog_test.js
@@ -6,7 +6,7 @@ import {setESimManagerRemoteForTesting} from 'chrome://resources/cr_components/chromeos/cellular_setup/mojo_interface_provider.m.js'; import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; -import {FakeESimManagerRemote} from 'chrome://test/cr_components/chromeos/cellular_setup/fake_esim_manager_remote.m.js'; +import {FakeESimManagerRemote} from 'chrome://test/cr_components/chromeos/cellular_setup/fake_esim_manager_remote.js'; import {assertEquals, assertTrue} from '../../chai_assert.js';
diff --git a/chrome/test/data/webui/settings/chromeos/esim_remove_profile_dialog_test.js b/chrome/test/data/webui/settings/chromeos/esim_remove_profile_dialog_test.js index 5824fa19..6fd9c0c 100644 --- a/chrome/test/data/webui/settings/chromeos/esim_remove_profile_dialog_test.js +++ b/chrome/test/data/webui/settings/chromeos/esim_remove_profile_dialog_test.js
@@ -8,7 +8,7 @@ import {OncMojo} from 'chrome://resources/cr_components/chromeos/network/onc_mojo.m.js'; import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {FakeNetworkConfig} from 'chrome://test/chromeos/fake_network_config_mojom.js'; -import {FakeESimManagerRemote} from 'chrome://test/cr_components/chromeos/cellular_setup/fake_esim_manager_remote.m.js'; +import {FakeESimManagerRemote} from 'chrome://test/cr_components/chromeos/cellular_setup/fake_esim_manager_remote.js'; import {eventToPromise} from 'chrome://test/test_util.js'; import {assertEquals, assertTrue} from '../../chai_assert.js';
diff --git a/chrome/test/data/webui/settings/chromeos/esim_rename_dialog_test.js b/chrome/test/data/webui/settings/chromeos/esim_rename_dialog_test.js index 530d00f..a25726a 100644 --- a/chrome/test/data/webui/settings/chromeos/esim_rename_dialog_test.js +++ b/chrome/test/data/webui/settings/chromeos/esim_rename_dialog_test.js
@@ -3,13 +3,14 @@ // found in the LICENSE file. import 'chrome://os-settings/chromeos/os_settings.js'; + import {setESimManagerRemoteForTesting} from 'chrome://resources/cr_components/chromeos/cellular_setup/mojo_interface_provider.m.js'; import {MojoInterfaceProviderImpl} from 'chrome://resources/cr_components/chromeos/network/mojo_interface_provider.m.js'; import {OncMojo} from 'chrome://resources/cr_components/chromeos/network/onc_mojo.m.js'; import {getDeepActiveElement} from 'chrome://resources/js/util.m.js'; import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {FakeNetworkConfig} from 'chrome://test/chromeos/fake_network_config_mojom.js'; -import {FakeESimManagerRemote} from 'chrome://test/cr_components/chromeos/cellular_setup/fake_esim_manager_remote.m.js'; +import {FakeESimManagerRemote} from 'chrome://test/cr_components/chromeos/cellular_setup/fake_esim_manager_remote.js'; import {eventToPromise} from 'chrome://test/test_util.js'; import {assertEquals, assertTrue} from '../../chai_assert.js';
diff --git a/chrome/test/data/webui/settings/chromeos/internet_detail_menu_test.js b/chrome/test/data/webui/settings/chromeos/internet_detail_menu_test.js index 6c2f7d9..06b2c6361 100644 --- a/chrome/test/data/webui/settings/chromeos/internet_detail_menu_test.js +++ b/chrome/test/data/webui/settings/chromeos/internet_detail_menu_test.js
@@ -9,7 +9,7 @@ import {getDeepActiveElement} from 'chrome://resources/js/util.m.js'; import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {FakeNetworkConfig} from 'chrome://test/chromeos/fake_network_config_mojom.js'; -import {FakeESimManagerRemote} from 'chrome://test/cr_components/chromeos/cellular_setup/fake_esim_manager_remote.m.js'; +import {FakeESimManagerRemote} from 'chrome://test/cr_components/chromeos/cellular_setup/fake_esim_manager_remote.js'; import {eventToPromise, flushTasks, waitAfterNextRender} from 'chrome://test/test_util.js'; import {assertEquals, assertTrue} from '../../chai_assert.js';
diff --git a/chrome/test/data/webui/settings/chromeos/internet_page_tests.js b/chrome/test/data/webui/settings/chromeos/internet_page_tests.js index 8da1843..91ef7ec 100644 --- a/chrome/test/data/webui/settings/chromeos/internet_page_tests.js +++ b/chrome/test/data/webui/settings/chromeos/internet_page_tests.js
@@ -10,7 +10,7 @@ import {getDeepActiveElement} from 'chrome://resources/js/util.m.js'; import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {FakeNetworkConfig} from 'chrome://test/chromeos/fake_network_config_mojom.js'; -import {FakeESimManagerRemote} from 'chrome://test/cr_components/chromeos/cellular_setup/fake_esim_manager_remote.m.js'; +import {FakeESimManagerRemote} from 'chrome://test/cr_components/chromeos/cellular_setup/fake_esim_manager_remote.js'; import {isVisible, waitAfterNextRender} from 'chrome://test/test_util.js'; suite('InternetPage', function() {
diff --git a/chrome/test/data/webui/settings/chromeos/internet_subpage_tests.js b/chrome/test/data/webui/settings/chromeos/internet_subpage_tests.js index 746dfe2..91e9ee8b 100644 --- a/chrome/test/data/webui/settings/chromeos/internet_subpage_tests.js +++ b/chrome/test/data/webui/settings/chromeos/internet_subpage_tests.js
@@ -10,7 +10,7 @@ import {getDeepActiveElement} from 'chrome://resources/js/util.m.js'; import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {FakeNetworkConfig} from 'chrome://test/chromeos/fake_network_config_mojom.js'; -import {FakeESimManagerRemote} from 'chrome://test/cr_components/chromeos/cellular_setup/fake_esim_manager_remote.m.js'; +import {FakeESimManagerRemote} from 'chrome://test/cr_components/chromeos/cellular_setup/fake_esim_manager_remote.js'; import {waitAfterNextRender} from 'chrome://test/test_util.js'; suite('InternetSubpage', function() {
diff --git a/chrome/test/data/webui/settings/chromeos/os_reset_page_test.js b/chrome/test/data/webui/settings/chromeos/os_reset_page_test.js index bed6f87..97eb76a 100644 --- a/chrome/test/data/webui/settings/chromeos/os_reset_page_test.js +++ b/chrome/test/data/webui/settings/chromeos/os_reset_page_test.js
@@ -7,7 +7,7 @@ import {setESimManagerRemoteForTesting} from 'chrome://resources/cr_components/chromeos/cellular_setup/mojo_interface_provider.m.js'; import {getDeepActiveElement} from 'chrome://resources/js/util.m.js'; import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; -import {FakeESimManagerRemote} from 'chrome://test/cr_components/chromeos/cellular_setup/fake_esim_manager_remote.m.js'; +import {FakeESimManagerRemote} from 'chrome://test/cr_components/chromeos/cellular_setup/fake_esim_manager_remote.js'; import {waitAfterNextRender} from 'chrome://test/test_util.js'; import {assertEquals, assertFalse, assertTrue} from '../../chai_assert.js';
diff --git a/chrome/test/data/webui/settings/chromeos/text_to_speech_subpage_tests.js b/chrome/test/data/webui/settings/chromeos/text_to_speech_subpage_tests.js index 46bdfca9..ccec2684 100644 --- a/chrome/test/data/webui/settings/chromeos/text_to_speech_subpage_tests.js +++ b/chrome/test/data/webui/settings/chromeos/text_to_speech_subpage_tests.js
@@ -21,6 +21,7 @@ 'getTtsExtensions', 'previewTtsVoice', 'wakeTtsEngine', + 'refreshTtsVoices', ]); } @@ -43,6 +44,11 @@ wakeTtsEngine() { this.methodCalled('wakeTtsEngine'); } + + /** @override */ + refreshTtsVoices() { + this.methodCalled('refreshTtsVoices'); + } } suite('TextToSpeechSubpageTests', function() {
diff --git a/chromecast/browser/accessibility/accessibility_service_impl.cc b/chromecast/browser/accessibility/accessibility_service_impl.cc index afb3e4b..767d263 100644 --- a/chromecast/browser/accessibility/accessibility_service_impl.cc +++ b/chromecast/browser/accessibility/accessibility_service_impl.cc
@@ -108,7 +108,7 @@ if (!render_frame_host) continue; - if (!render_frame_host->IsRenderFrameCreated()) + if (!render_frame_host->IsRenderFrameLive()) continue; service_manager::InterfaceProvider* interface_provider =
diff --git a/chromecast/browser/accessibility/flutter/ax_tree_source_flutter_unittest.cc b/chromecast/browser/accessibility/flutter/ax_tree_source_flutter_unittest.cc index 3d57773c..e2bdabd 100644 --- a/chromecast/browser/accessibility/flutter/ax_tree_source_flutter_unittest.cc +++ b/chromecast/browser/accessibility/flutter/ax_tree_source_flutter_unittest.cc
@@ -66,6 +66,7 @@ const GURL& source_url, std::vector<VoiceData>* out_voices) override { } + void RefreshVoices() override {} void LoadBuiltInTtsEngine(BrowserContext* browser_context) override {} void WillSpeakUtteranceWithVoice(TtsUtterance* utterance, const VoiceData& voice_data) override {}
diff --git a/chromecast/media/audio/mixer_service/output_stream_connection.cc b/chromecast/media/audio/mixer_service/output_stream_connection.cc index d21cbb1..79d0eb3 100644 --- a/chromecast/media/audio/mixer_service/output_stream_connection.cc +++ b/chromecast/media/audio/mixer_service/output_stream_connection.cc
@@ -241,7 +241,9 @@ (message.mixer_underrun().type() == MixerUnderrun::INPUT_UNDERRUN ? "Platform.Audio.Mixer.StreamUnderrun" : "Platform.Audio.Mixer.OutputUnderrun"); - RecordCastEvent(metric_name, CreateCastEvent(metric_name), + std::unique_ptr<CastEventBuilder> event = CreateCastEvent(metric_name); + delegate_->ProcessCastEvent(event.get()); + RecordCastEvent(metric_name, std::move(event), /* verbose_log_level = */ 0); delegate_->OnMixerUnderrun(static_cast<Delegate::MixerUnderrunType>( message.mixer_underrun().type()));
diff --git a/chromecast/media/audio/mixer_service/output_stream_connection.h b/chromecast/media/audio/mixer_service/output_stream_connection.h index 086de58..17bf489 100644 --- a/chromecast/media/audio/mixer_service/output_stream_connection.h +++ b/chromecast/media/audio/mixer_service/output_stream_connection.h
@@ -14,6 +14,7 @@ #include "net/base/io_buffer.h" namespace chromecast { +class CastEventBuilder; class IOBufferPool; namespace media { @@ -63,6 +64,10 @@ // Called when an underrun happens on mixer input/output. virtual void OnMixerUnderrun(MixerUnderrunType type) {} + // Called when OutputStreamConnection records a cast event. It allows + // the Delegate to provide some extra data to the event. + virtual void ProcessCastEvent(CastEventBuilder* event) {} + protected: virtual ~Delegate() = default; };
diff --git a/chromeos/components/cros_elements/BUILD.gn b/chromeos/ash/components/cros_elements/BUILD.gn similarity index 80% rename from chromeos/components/cros_elements/BUILD.gn rename to chromeos/ash/components/cros_elements/BUILD.gn index 2ea8474..54fccc2 100644 --- a/chromeos/components/cros_elements/BUILD.gn +++ b/chromeos/ash/components/cros_elements/BUILD.gn
@@ -2,8 +2,11 @@ # 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, "Non Chrome OS builds cannot depend on //chromeos/ash") + generate_grd("build_grdp") { grd_prefix = "cros_elements" out_grd = "$target_gen_dir/${grd_prefix}_resources.grdp"
diff --git a/chromeos/components/cros_elements/OWNERS b/chromeos/ash/components/cros_elements/OWNERS similarity index 100% rename from chromeos/components/cros_elements/OWNERS rename to chromeos/ash/components/cros_elements/OWNERS
diff --git a/chromeos/components/cros_elements/README.md b/chromeos/ash/components/cros_elements/README.md similarity index 100% rename from chromeos/components/cros_elements/README.md rename to chromeos/ash/components/cros_elements/README.md
diff --git a/chromeos/components/cros_elements/button/BUILD.gn b/chromeos/ash/components/cros_elements/button/BUILD.gn similarity index 87% rename from chromeos/components/cros_elements/button/BUILD.gn rename to chromeos/ash/components/cros_elements/button/BUILD.gn index 5b6702ac..1aa395ec 100644 --- a/chromeos/components/cros_elements/button/BUILD.gn +++ b/chromeos/ash/components/cros_elements/button/BUILD.gn
@@ -2,9 +2,12 @@ # 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("//third_party/material_web_components/rewrite_imports.gni") import("//tools/typescript/ts_library.gni") +assert(is_chromeos_ash, "Non Chrome OS builds cannot depend on //chromeos/ash") + ts_library("button_ts") { composite = true root_dir = "."
diff --git a/chromeos/components/cros_elements/button/button.ts b/chromeos/ash/components/cros_elements/button/button.ts similarity index 100% rename from chromeos/components/cros_elements/button/button.ts rename to chromeos/ash/components/cros_elements/button/button.ts
diff --git a/chromeos/components/cros_elements/tsconfig_base.json b/chromeos/ash/components/cros_elements/tsconfig_base.json similarity index 100% rename from chromeos/components/cros_elements/tsconfig_base.json rename to chromeos/ash/components/cros_elements/tsconfig_base.json
diff --git a/chromeos/ash/components/network/onc/BUILD.gn b/chromeos/ash/components/network/onc/BUILD.gn new file mode 100644 index 0000000..ac8ef45 --- /dev/null +++ b/chromeos/ash/components/network/onc/BUILD.gn
@@ -0,0 +1,79 @@ +# 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("//testing/libfuzzer/fuzzer_test.gni") + +assert(is_chromeos_ash, "Non-ChromeOS builds cannot depend on //chromeos/ash") + +source_set("onc") { + # Due to circular dependency, others should depend on via chromeos/network. + visibility = [ "//chromeos/network" ] + + configs += [ "//chromeos/network:network_config" ] + deps = [ + "//base", + "//chromeos/components/onc", + "//components/account_id", + "//components/certificate_matching", + "//components/device_event_log", + "//components/onc", + "//components/prefs", + "//components/proxy_config", + "//components/url_formatter", + "//components/user_manager", + "//net", + ] + sources = [ + "network_onc_utils.cc", + "network_onc_utils.h", + "onc_certificate_importer.h", + "onc_certificate_importer_impl.cc", + "onc_certificate_importer_impl.h", + "onc_certificate_pattern.cc", + "onc_certificate_pattern.h", + "onc_merger.cc", + "onc_merger.h", + "onc_normalizer.cc", + "onc_normalizer.h", + "onc_translation_tables.cc", + "onc_translation_tables.h", + "onc_translator.h", + "onc_translator_onc_to_shill.cc", + "onc_translator_shill_to_onc.cc", + ] +} + +source_set("unit_tests") { + testonly = true + deps = [ + "//base/test:test_support", + "//chromeos:test_utils", + "//chromeos/components/onc", + "//chromeos/components/onc:test_support", + "//chromeos/network", + "//components/onc", + "//crypto:test_support", + "//net:test_support", + "//testing/gmock", + "//testing/gtest", + ] + sources = [ + "network_onc_utils_unittest.cc", + "onc_certificate_importer_impl_unittest.cc", + "onc_certificate_pattern_unittest.cc", + "onc_merger_unittest.cc", + "onc_normalizer_unittest.cc", + "onc_translator_unittest.cc", + ] +} + +fuzzer_test("onc_normalizer_fuzzer") { + sources = [ "onc_normalizer_fuzzer.cc" ] + deps = [ + "//base", + "//chromeos/components/onc", + "//chromeos/network", + ] +}
diff --git a/chromeos/network/onc/DIR_METADATA b/chromeos/ash/components/network/onc/DIR_METADATA similarity index 100% rename from chromeos/network/onc/DIR_METADATA rename to chromeos/ash/components/network/onc/DIR_METADATA
diff --git a/chromeos/network/onc/network_onc_utils.cc b/chromeos/ash/components/network/onc/network_onc_utils.cc similarity index 98% rename from chromeos/network/onc/network_onc_utils.cc rename to chromeos/ash/components/network/onc/network_onc_utils.cc index 32f291c..800ca67 100644 --- a/chromeos/network/onc/network_onc_utils.cc +++ b/chromeos/ash/components/network/onc/network_onc_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/network/onc/network_onc_utils.h" +#include "chromeos/ash/components/network/onc/network_onc_utils.h" #include <stddef.h> #include <stdint.h> @@ -20,6 +20,9 @@ #include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" #include "base/values.h" +#include "chromeos/ash/components/network/onc/network_onc_utils.h" +#include "chromeos/ash/components/network/onc/onc_normalizer.h" +#include "chromeos/ash/components/network/onc/onc_translator.h" #include "chromeos/components/onc/onc_mapper.h" #include "chromeos/components/onc/onc_signature.h" #include "chromeos/components/onc/onc_utils.h" @@ -32,9 +35,6 @@ #include "chromeos/network/network_state.h" #include "chromeos/network/network_state_handler.h" #include "chromeos/network/network_ui_data.h" -#include "chromeos/network/onc/network_onc_utils.h" -#include "chromeos/network/onc/onc_normalizer.h" -#include "chromeos/network/onc/onc_translator.h" #include "chromeos/network/tether_constants.h" #include "components/account_id/account_id.h" #include "components/device_event_log/device_event_log.h"
diff --git a/chromeos/network/onc/network_onc_utils.h b/chromeos/ash/components/network/onc/network_onc_utils.h similarity index 94% rename from chromeos/network/onc/network_onc_utils.h rename to chromeos/ash/components/network/onc/network_onc_utils.h index e32af83..17c325f 100644 --- a/chromeos/network/onc/network_onc_utils.h +++ b/chromeos/ash/components/network/onc/network_onc_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_NETWORK_ONC_NETWORK_ONC_UTILS_H_ -#define CHROMEOS_NETWORK_ONC_NETWORK_ONC_UTILS_H_ +#ifndef CHROMEOS_ASH_COMPONENTS_NETWORK_ONC_NETWORK_ONC_UTILS_H_ +#define CHROMEOS_ASH_COMPONENTS_NETWORK_ONC_NETWORK_ONC_UTILS_H_ #include <map> #include <memory> @@ -99,4 +99,4 @@ } // namespace onc } // namespace chromeos -#endif // CHROMEOS_NETWORK_ONC_NETWORK_ONC_UTILS_H_ +#endif // CHROMEOS_ASH_COMPONENTS_NETWORK_ONC_NETWORK_ONC_UTILS_H_
diff --git a/chromeos/network/onc/network_onc_utils_unittest.cc b/chromeos/ash/components/network/onc/network_onc_utils_unittest.cc similarity index 98% rename from chromeos/network/onc/network_onc_utils_unittest.cc rename to chromeos/ash/components/network/onc/network_onc_utils_unittest.cc index 411e897..3187e244 100644 --- a/chromeos/network/onc/network_onc_utils_unittest.cc +++ b/chromeos/ash/components/network/onc/network_onc_utils_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 "chromeos/network/onc/network_onc_utils.h" +#include "chromeos/ash/components/network/onc/network_onc_utils.h" #include <string>
diff --git a/chromeos/network/onc/onc_certificate_importer.h b/chromeos/ash/components/network/onc/onc_certificate_importer.h similarity index 91% rename from chromeos/network/onc/onc_certificate_importer.h rename to chromeos/ash/components/network/onc/onc_certificate_importer.h index 97aa3dd..8cc1e195 100644 --- a/chromeos/network/onc/onc_certificate_importer.h +++ b/chromeos/ash/components/network/onc/onc_certificate_importer.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_NETWORK_ONC_ONC_CERTIFICATE_IMPORTER_H_ -#define CHROMEOS_NETWORK_ONC_ONC_CERTIFICATE_IMPORTER_H_ +#ifndef CHROMEOS_ASH_COMPONENTS_NETWORK_ONC_ONC_CERTIFICATE_IMPORTER_H_ +#define CHROMEOS_ASH_COMPONENTS_NETWORK_ONC_ONC_CERTIFICATE_IMPORTER_H_ #include "base/callback_forward.h" #include "base/component_export.h" @@ -57,4 +57,4 @@ } // namespace onc } // namespace chromeos -#endif // CHROMEOS_NETWORK_ONC_ONC_CERTIFICATE_IMPORTER_H_ +#endif // CHROMEOS_ASH_COMPONENTS_NETWORK_ONC_ONC_CERTIFICATE_IMPORTER_H_
diff --git a/chromeos/network/onc/onc_certificate_importer_impl.cc b/chromeos/ash/components/network/onc/onc_certificate_importer_impl.cc similarity index 98% rename from chromeos/network/onc/onc_certificate_importer_impl.cc rename to chromeos/ash/components/network/onc/onc_certificate_importer_impl.cc index a5c2b90..f3c41aa 100644 --- a/chromeos/network/onc/onc_certificate_importer_impl.cc +++ b/chromeos/ash/components/network/onc/onc_certificate_importer_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/network/onc/onc_certificate_importer_impl.h" +#include "chromeos/ash/components/network/onc/onc_certificate_importer_impl.h" #include <cert.h> #include <keyhi.h> @@ -21,9 +21,9 @@ #include "base/threading/sequenced_task_runner_handle.h" #include "base/threading/thread_task_runner_handle.h" #include "base/values.h" +#include "chromeos/ash/components/network/onc/network_onc_utils.h" #include "chromeos/components/onc/onc_parsed_certificates.h" #include "chromeos/network/network_event_log.h" -#include "chromeos/network/onc/network_onc_utils.h" #include "crypto/scoped_nss_types.h" #include "net/base/net_errors.h" #include "net/cert/nss_cert_database.h"
diff --git a/chromeos/network/onc/onc_certificate_importer_impl.h b/chromeos/ash/components/network/onc/onc_certificate_importer_impl.h similarity index 92% rename from chromeos/network/onc/onc_certificate_importer_impl.h rename to chromeos/ash/components/network/onc/onc_certificate_importer_impl.h index 2f433bc..9405809 100644 --- a/chromeos/network/onc/onc_certificate_importer_impl.h +++ b/chromeos/ash/components/network/onc/onc_certificate_importer_impl.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_NETWORK_ONC_ONC_CERTIFICATE_IMPORTER_IMPL_H_ -#define CHROMEOS_NETWORK_ONC_ONC_CERTIFICATE_IMPORTER_IMPL_H_ +#ifndef CHROMEOS_ASH_COMPONENTS_NETWORK_ONC_ONC_CERTIFICATE_IMPORTER_IMPL_H_ +#define CHROMEOS_ASH_COMPONENTS_NETWORK_ONC_ONC_CERTIFICATE_IMPORTER_IMPL_H_ #include <map> #include <memory> @@ -13,8 +13,8 @@ #include "base/component_export.h" #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" +#include "chromeos/ash/components/network/onc/onc_certificate_importer.h" #include "chromeos/components/onc/onc_parsed_certificates.h" -#include "chromeos/network/onc/onc_certificate_importer.h" #include "components/onc/onc_constants.h" namespace base { @@ -110,4 +110,4 @@ } // namespace onc } // namespace chromeos -#endif // CHROMEOS_NETWORK_ONC_ONC_CERTIFICATE_IMPORTER_IMPL_H_ +#endif // CHROMEOS_ASH_COMPONENTS_NETWORK_ONC_ONC_CERTIFICATE_IMPORTER_IMPL_H_
diff --git a/chromeos/network/onc/onc_certificate_importer_impl_unittest.cc b/chromeos/ash/components/network/onc/onc_certificate_importer_impl_unittest.cc similarity index 99% rename from chromeos/network/onc/onc_certificate_importer_impl_unittest.cc rename to chromeos/ash/components/network/onc/onc_certificate_importer_impl_unittest.cc index e883329..0ea3a9c 100644 --- a/chromeos/network/onc/onc_certificate_importer_impl_unittest.cc +++ b/chromeos/ash/components/network/onc/onc_certificate_importer_impl_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 "chromeos/network/onc/onc_certificate_importer_impl.h" +#include "chromeos/ash/components/network/onc/onc_certificate_importer_impl.h" #include <cert.h>
diff --git a/chromeos/network/onc/onc_certificate_pattern.cc b/chromeos/ash/components/network/onc/onc_certificate_pattern.cc similarity index 98% rename from chromeos/network/onc/onc_certificate_pattern.cc rename to chromeos/ash/components/network/onc/onc_certificate_pattern.cc index 856285f..11d58339 100644 --- a/chromeos/network/onc/onc_certificate_pattern.cc +++ b/chromeos/ash/components/network/onc/onc_certificate_pattern.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/network/onc/onc_certificate_pattern.h" +#include "chromeos/ash/components/network/onc/onc_certificate_pattern.h" #include <stddef.h>
diff --git a/chromeos/network/onc/onc_certificate_pattern.h b/chromeos/ash/components/network/onc/onc_certificate_pattern.h similarity index 91% rename from chromeos/network/onc/onc_certificate_pattern.h rename to chromeos/ash/components/network/onc/onc_certificate_pattern.h index e3a656cd..728195ea 100644 --- a/chromeos/network/onc/onc_certificate_pattern.h +++ b/chromeos/ash/components/network/onc/onc_certificate_pattern.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_NETWORK_ONC_ONC_CERTIFICATE_PATTERN_H_ -#define CHROMEOS_NETWORK_ONC_ONC_CERTIFICATE_PATTERN_H_ +#ifndef CHROMEOS_ASH_COMPONENTS_NETWORK_ONC_ONC_CERTIFICATE_PATTERN_H_ +#define CHROMEOS_ASH_COMPONENTS_NETWORK_ONC_ONC_CERTIFICATE_PATTERN_H_ #include <memory> #include <string> @@ -75,4 +75,4 @@ } // namespace chromeos -#endif // CHROMEOS_NETWORK_ONC_ONC_CERTIFICATE_PATTERN_H_ +#endif // CHROMEOS_ASH_COMPONENTS_NETWORK_ONC_ONC_CERTIFICATE_PATTERN_H_
diff --git a/chromeos/network/onc/onc_certificate_pattern_unittest.cc b/chromeos/ash/components/network/onc/onc_certificate_pattern_unittest.cc similarity index 98% rename from chromeos/network/onc/onc_certificate_pattern_unittest.cc rename to chromeos/ash/components/network/onc/onc_certificate_pattern_unittest.cc index b635477..eee39b7 100644 --- a/chromeos/network/onc/onc_certificate_pattern_unittest.cc +++ b/chromeos/ash/components/network/onc/onc_certificate_pattern_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 "chromeos/network/onc/onc_certificate_pattern.h" +#include "chromeos/ash/components/network/onc/onc_certificate_pattern.h" #include <string>
diff --git a/chromeos/network/onc/onc_merger.cc b/chromeos/ash/components/network/onc/onc_merger.cc similarity index 99% rename from chromeos/network/onc/onc_merger.cc rename to chromeos/ash/components/network/onc/onc_merger.cc index 7ff4568..e9c93e8 100644 --- a/chromeos/network/onc/onc_merger.cc +++ b/chromeos/ash/components/network/onc/onc_merger.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/network/onc/onc_merger.h" +#include "chromeos/ash/components/network/onc/onc_merger.h" #include <set> #include <string>
diff --git a/chromeos/network/onc/onc_merger.h b/chromeos/ash/components/network/onc/onc_merger.h similarity index 91% rename from chromeos/network/onc/onc_merger.h rename to chromeos/ash/components/network/onc/onc_merger.h index 7dfedadb..3f7887a 100644 --- a/chromeos/network/onc/onc_merger.h +++ b/chromeos/ash/components/network/onc/onc_merger.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_NETWORK_ONC_ONC_MERGER_H_ -#define CHROMEOS_NETWORK_ONC_ONC_MERGER_H_ +#ifndef CHROMEOS_ASH_COMPONENTS_NETWORK_ONC_ONC_MERGER_H_ +#define CHROMEOS_ASH_COMPONENTS_NETWORK_ONC_ONC_MERGER_H_ #include "base/component_export.h" @@ -51,4 +51,4 @@ } // namespace onc } // namespace chromeos -#endif // CHROMEOS_NETWORK_ONC_ONC_MERGER_H_ +#endif // CHROMEOS_ASH_COMPONENTS_NETWORK_ONC_ONC_MERGER_H_
diff --git a/chromeos/network/onc/onc_merger_unittest.cc b/chromeos/ash/components/network/onc/onc_merger_unittest.cc similarity index 98% rename from chromeos/network/onc/onc_merger_unittest.cc rename to chromeos/ash/components/network/onc/onc_merger_unittest.cc index 6c97d15..d8eaa2ff 100644 --- a/chromeos/network/onc/onc_merger_unittest.cc +++ b/chromeos/ash/components/network/onc/onc_merger_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 "chromeos/network/onc/onc_merger.h" +#include "chromeos/ash/components/network/onc/onc_merger.h" #include <string>
diff --git a/chromeos/network/onc/onc_normalizer.cc b/chromeos/ash/components/network/onc/onc_normalizer.cc similarity index 98% rename from chromeos/network/onc/onc_normalizer.cc rename to chromeos/ash/components/network/onc/onc_normalizer.cc index 0057a52..f0d411f 100644 --- a/chromeos/network/onc/onc_normalizer.cc +++ b/chromeos/ash/components/network/onc/onc_normalizer.cc
@@ -2,16 +2,16 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chromeos/network/onc/onc_normalizer.h" +#include "chromeos/ash/components/network/onc/onc_normalizer.h" #include <string> #include "base/logging.h" #include "base/values.h" +#include "chromeos/ash/components/network/onc/network_onc_utils.h" #include "chromeos/components/onc/onc_signature.h" #include "chromeos/components/onc/onc_utils.h" #include "chromeos/network/network_event_log.h" -#include "chromeos/network/onc/network_onc_utils.h" #include "components/onc/onc_constants.h" namespace chromeos {
diff --git a/chromeos/network/onc/onc_normalizer.h b/chromeos/ash/components/network/onc/onc_normalizer.h similarity index 91% rename from chromeos/network/onc/onc_normalizer.h rename to chromeos/ash/components/network/onc/onc_normalizer.h index ac6ef76..6ef887f5 100644 --- a/chromeos/network/onc/onc_normalizer.h +++ b/chromeos/ash/components/network/onc/onc_normalizer.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_NETWORK_ONC_ONC_NORMALIZER_H_ -#define CHROMEOS_NETWORK_ONC_ONC_NORMALIZER_H_ +#ifndef CHROMEOS_ASH_COMPONENTS_NETWORK_ONC_ONC_NORMALIZER_H_ +#define CHROMEOS_ASH_COMPONENTS_NETWORK_ONC_ONC_NORMALIZER_H_ #include "base/component_export.h" #include "base/values.h" @@ -58,4 +58,4 @@ } // namespace onc } // namespace chromeos -#endif // CHROMEOS_NETWORK_ONC_ONC_NORMALIZER_H_ +#endif // CHROMEOS_ASH_COMPONENTS_NETWORK_ONC_ONC_NORMALIZER_H_
diff --git a/chromeos/network/onc/onc_normalizer_fuzzer.cc b/chromeos/ash/components/network/onc/onc_normalizer_fuzzer.cc similarity index 93% rename from chromeos/network/onc/onc_normalizer_fuzzer.cc rename to chromeos/ash/components/network/onc/onc_normalizer_fuzzer.cc index 2d04d4e7..6961c24 100644 --- a/chromeos/network/onc/onc_normalizer_fuzzer.cc +++ b/chromeos/ash/components/network/onc/onc_normalizer_fuzzer.cc
@@ -8,8 +8,8 @@ #include "base/json/json_reader.h" #include "base/strings/string_piece.h" #include "base/values.h" +#include "chromeos/ash/components/network/onc/onc_normalizer.h" #include "chromeos/components/onc/onc_signature.h" -#include "chromeos/network/onc/onc_normalizer.h" #include "third_party/abseil-cpp/absl/types/optional.h" namespace chromeos {
diff --git a/chromeos/network/onc/onc_normalizer_unittest.cc b/chromeos/ash/components/network/onc/onc_normalizer_unittest.cc similarity index 98% rename from chromeos/network/onc/onc_normalizer_unittest.cc rename to chromeos/ash/components/network/onc/onc_normalizer_unittest.cc index a6da6ba..5571636 100644 --- a/chromeos/network/onc/onc_normalizer_unittest.cc +++ b/chromeos/ash/components/network/onc/onc_normalizer_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 "chromeos/network/onc/onc_normalizer.h" +#include "chromeos/ash/components/network/onc/onc_normalizer.h" #include "base/values.h" #include "chromeos/components/onc/onc_signature.h"
diff --git a/chromeos/network/onc/onc_translation_tables.cc b/chromeos/ash/components/network/onc/onc_translation_tables.cc similarity index 99% rename from chromeos/network/onc/onc_translation_tables.cc rename to chromeos/ash/components/network/onc/onc_translation_tables.cc index e5067fd..5d7f846 100644 --- a/chromeos/network/onc/onc_translation_tables.cc +++ b/chromeos/ash/components/network/onc/onc_translation_tables.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/network/onc/onc_translation_tables.h" +#include "chromeos/ash/components/network/onc/onc_translation_tables.h" #include <cstddef>
diff --git a/chromeos/network/onc/onc_translation_tables.h b/chromeos/ash/components/network/onc/onc_translation_tables.h similarity index 94% rename from chromeos/network/onc/onc_translation_tables.h rename to chromeos/ash/components/network/onc/onc_translation_tables.h index 5cbcd27..36c75ec 100644 --- a/chromeos/network/onc/onc_translation_tables.h +++ b/chromeos/ash/components/network/onc/onc_translation_tables.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_NETWORK_ONC_ONC_TRANSLATION_TABLES_H_ -#define CHROMEOS_NETWORK_ONC_ONC_TRANSLATION_TABLES_H_ +#ifndef CHROMEOS_ASH_COMPONENTS_NETWORK_ONC_ONC_TRANSLATION_TABLES_H_ +#define CHROMEOS_ASH_COMPONENTS_NETWORK_ONC_ONC_TRANSLATION_TABLES_H_ #include <string> #include <vector> @@ -98,4 +98,4 @@ } // namespace onc } // namespace chromeos -#endif // CHROMEOS_NETWORK_ONC_ONC_TRANSLATION_TABLES_H_ +#endif // CHROMEOS_ASH_COMPONENTS_NETWORK_ONC_ONC_TRANSLATION_TABLES_H_
diff --git a/chromeos/network/onc/onc_translator.h b/chromeos/ash/components/network/onc/onc_translator.h similarity index 91% rename from chromeos/network/onc/onc_translator.h rename to chromeos/ash/components/network/onc/onc_translator.h index 21ed517..62fb6d8 100644 --- a/chromeos/network/onc/onc_translator.h +++ b/chromeos/ash/components/network/onc/onc_translator.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_NETWORK_ONC_ONC_TRANSLATOR_H_ -#define CHROMEOS_NETWORK_ONC_ONC_TRANSLATOR_H_ +#ifndef CHROMEOS_ASH_COMPONENTS_NETWORK_ONC_ONC_TRANSLATOR_H_ +#define CHROMEOS_ASH_COMPONENTS_NETWORK_ONC_ONC_TRANSLATOR_H_ #include "base/component_export.h" #include "components/onc/onc_constants.h" @@ -53,4 +53,4 @@ } // namespace onc } // namespace chromeos -#endif // CHROMEOS_NETWORK_ONC_ONC_TRANSLATOR_H_ +#endif // CHROMEOS_ASH_COMPONENTS_NETWORK_ONC_ONC_TRANSLATOR_H_
diff --git a/chromeos/network/onc/onc_translator_onc_to_shill.cc b/chromeos/ash/components/network/onc/onc_translator_onc_to_shill.cc similarity index 98% rename from chromeos/network/onc/onc_translator_onc_to_shill.cc rename to chromeos/ash/components/network/onc/onc_translator_onc_to_shill.cc index d50075d..408b52b76 100644 --- a/chromeos/network/onc/onc_translator_onc_to_shill.cc +++ b/chromeos/ash/components/network/onc/onc_translator_onc_to_shill.cc
@@ -20,12 +20,12 @@ #include "base/notreached.h" #include "base/strings/string_util.h" #include "base/values.h" +#include "chromeos/ash/components/network/onc/network_onc_utils.h" +#include "chromeos/ash/components/network/onc/onc_translation_tables.h" +#include "chromeos/ash/components/network/onc/onc_translator.h" #include "chromeos/components/onc/onc_signature.h" #include "chromeos/network/client_cert_util.h" #include "chromeos/network/network_event_log.h" -#include "chromeos/network/onc/network_onc_utils.h" -#include "chromeos/network/onc/onc_translation_tables.h" -#include "chromeos/network/onc/onc_translator.h" #include "chromeos/network/shill_property_util.h" #include "components/onc/onc_constants.h" #include "net/base/ip_address.h"
diff --git a/chromeos/network/onc/onc_translator_shill_to_onc.cc b/chromeos/ash/components/network/onc/onc_translator_shill_to_onc.cc similarity index 99% rename from chromeos/network/onc/onc_translator_shill_to_onc.cc rename to chromeos/ash/components/network/onc/onc_translator_shill_to_onc.cc index 7d78339..6d943ed 100644 --- a/chromeos/network/onc/onc_translator_shill_to_onc.cc +++ b/chromeos/ash/components/network/onc/onc_translator_shill_to_onc.cc
@@ -12,14 +12,14 @@ #include "base/logging.h" #include "base/strings/string_util.h" #include "base/values.h" +#include "chromeos/ash/components/network/onc/network_onc_utils.h" +#include "chromeos/ash/components/network/onc/onc_translation_tables.h" +#include "chromeos/ash/components/network/onc/onc_translator.h" #include "chromeos/components/onc/onc_signature.h" #include "chromeos/components/onc/onc_utils.h" #include "chromeos/network/network_profile_handler.h" #include "chromeos/network/network_state.h" #include "chromeos/network/network_util.h" -#include "chromeos/network/onc/network_onc_utils.h" -#include "chromeos/network/onc/onc_translation_tables.h" -#include "chromeos/network/onc/onc_translator.h" #include "chromeos/network/shill_property_util.h" #include "components/device_event_log/device_event_log.h" #include "components/onc/onc_constants.h"
diff --git a/chromeos/network/onc/onc_translator_unittest.cc b/chromeos/ash/components/network/onc/onc_translator_unittest.cc similarity index 98% rename from chromeos/network/onc/onc_translator_unittest.cc rename to chromeos/ash/components/network/onc/onc_translator_unittest.cc index ad3c7ac..ae61b154 100644 --- a/chromeos/network/onc/onc_translator_unittest.cc +++ b/chromeos/ash/components/network/onc/onc_translator_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 "chromeos/network/onc/onc_translator.h" +#include "chromeos/ash/components/network/onc/onc_translator.h" #include <string> #include <utility>
diff --git a/chromeos/chromeos_strings.grd b/chromeos/chromeos_strings.grd index 375c48a..fbb6656 100644 --- a/chromeos/chromeos_strings.grd +++ b/chromeos/chromeos_strings.grd
@@ -2356,6 +2356,9 @@ <message name="IDS_PERSONALIZATION_APP_KEYBOARD_BACKLIGHT_WALLPAPER_COLOR_LABEL" desc="Label for the wallpaper extracted color in the keyboard backlight section of personalization hub."> Wallpaper color </message> + <message name="IDS_PERSONALIZATION_APP_KEYBOARD_BACKLIGHT_WALLPAPER_COLOR_TOOLTIP_TEXT" desc="The text label of the tooltip for the wallpaper extracted color in the keyboard backlight section of personalization hub."> + Keyboard color is based on wallpaper + </message> <message name="IDS_PERSONALIZATION_APP_KEYBOARD_BACKLIGHT_WHITE_COLOR_LABEL" desc="Label for the white color in the keyboard backlight section of personalization hub."> White </message>
diff --git a/chromeos/chromeos_strings_grd/IDS_PERSONALIZATION_APP_KEYBOARD_BACKLIGHT_WALLPAPER_COLOR_TOOLTIP_TEXT.png.sha1 b/chromeos/chromeos_strings_grd/IDS_PERSONALIZATION_APP_KEYBOARD_BACKLIGHT_WALLPAPER_COLOR_TOOLTIP_TEXT.png.sha1 new file mode 100644 index 0000000..83a72ea3 --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_PERSONALIZATION_APP_KEYBOARD_BACKLIGHT_WALLPAPER_COLOR_TOOLTIP_TEXT.png.sha1
@@ -0,0 +1 @@ +ef73aa1f0cd42d275901326ca9f37584c0192d7e \ No newline at end of file
diff --git a/chromeos/constants/chromeos_features.cc b/chromeos/constants/chromeos_features.cc index 2f478cc..390a6b9 100644 --- a/chromeos/constants/chromeos_features.cc +++ b/chromeos/constants/chromeos_features.cc
@@ -21,6 +21,12 @@ const base::Feature kDarkLightMode{"DarkLightMode", base::FEATURE_DISABLED_BY_DEFAULT}; +// Disables "Office Editing for Docs, Sheets & Slides" component app so handlers +// won't be registered, making it possible to install another version for +// testing. +const base::Feature kDisableOfficeEditingComponentApp{ + "DisableOfficeEditingComponentApp", base::FEATURE_DISABLED_BY_DEFAULT}; + // Disables translation services of the Quick Answers V2. const base::Feature kDisableQuickAnswersV2Translation{ "DisableQuickAnswersV2Translation", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/chromeos/constants/chromeos_features.h b/chromeos/constants/chromeos_features.h index f09b8a494..c20552ab 100644 --- a/chromeos/constants/chromeos_features.h +++ b/chromeos/constants/chromeos_features.h
@@ -26,6 +26,8 @@ extern const base::Feature kBluetoothPhoneFilter; COMPONENT_EXPORT(CHROMEOS_CONSTANTS) extern const base::Feature kDarkLightMode; COMPONENT_EXPORT(CHROMEOS_CONSTANTS) +extern const base::Feature kDisableOfficeEditingComponentApp; +COMPONENT_EXPORT(CHROMEOS_CONSTANTS) extern const base::Feature kDisableQuickAnswersV2Translation; COMPONENT_EXPORT(CHROMEOS_CONSTANTS) extern const base::Feature kQuickAnswersV2SettingsSubToggle;
diff --git a/chromeos/language/language_packs/language_packs_impl.cc b/chromeos/language/language_packs/language_packs_impl.cc index ce829da2..41adffa3 100644 --- a/chromeos/language/language_packs/language_packs_impl.cc +++ b/chromeos/language/language_packs/language_packs_impl.cc
@@ -33,27 +33,28 @@ } } +PackState GetPackStateFromStatusCode(const PackResult::StatusCode status_code) { + switch (status_code) { + case PackResult::NOT_INSTALLED: + return PackState::NOT_INSTALLED; + case PackResult::IN_PROGRESS: + return PackState::INSTALLING; + case PackResult::INSTALLED: + return PackState::INSTALLED; + // Catch all remaining cases as error. + default: + return PackState::ERROR; + } +} + // Called when GetPackState() or InstallPack() functions from Language Packs // are complete. void OnOperationComplete(LanguagePacksImpl::GetPackInfoCallback mojo_callback, const PackResult& pack_result) { auto info = LanguagePackInfo::New(); - switch (pack_result.pack_state) { - case PackResult::NOT_INSTALLED: - info->pack_state = PackState::NOT_INSTALLED; - break; - case PackResult::IN_PROGRESS: - info->pack_state = PackState::INSTALLING; - break; - case PackResult::INSTALLED: - info->pack_state = PackState::INSTALLED; - info->path = pack_result.path; - break; - - // Catch all remaining cases as error. - default: - info->pack_state = PackState::ERROR; - break; + info->pack_state = GetPackStateFromStatusCode(pack_result.pack_state); + if (pack_result.pack_state == PackResult::INSTALLED) { + info->path = pack_result.path; } base::UmaHistogramEnumeration("ChromeOS.LanguagePacks.Mojo.PackStateResponse",
diff --git a/chromeos/network/BUILD.gn b/chromeos/network/BUILD.gn index ca35ad8..8c7bdcc 100644 --- a/chromeos/network/BUILD.gn +++ b/chromeos/network/BUILD.gn
@@ -2,7 +2,6 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -import("//testing/libfuzzer/fuzzer_test.gni") import("//testing/test.gni") import("//third_party/protobuf/proto_library.gni") @@ -14,7 +13,10 @@ component("network") { configs += [ ":network_config" ] - public_deps = [ "//chromeos/ash/components/network/metrics" ] + public_deps = [ + "//chromeos/ash/components/network/metrics", + "//chromeos/ash/components/network/onc", + ] deps = [ "//ash/constants", "//base", @@ -28,7 +30,6 @@ "//chromeos/login/login_state", "//chromeos/services/network_config/public/mojom", "//components/account_id", - "//components/certificate_matching", "//components/crx_file", "//components/device_event_log", "//components/onc", @@ -47,7 +48,10 @@ # Allow circular dependency from sub-directories of # chromeos/ash/components/network. - allow_circular_includes_from = [ "//chromeos/ash/components/network/metrics" ] + allow_circular_includes_from = [ + "//chromeos/ash/components/network/metrics", + "//chromeos/ash/components/network/onc", + ] sources = [ "auto_connect_handler.cc", "auto_connect_handler.h", @@ -153,22 +157,6 @@ "network_ui_data.h", "network_util.cc", "network_util.h", - "onc/network_onc_utils.cc", - "onc/network_onc_utils.h", - "onc/onc_certificate_importer.h", - "onc/onc_certificate_importer_impl.cc", - "onc/onc_certificate_importer_impl.h", - "onc/onc_certificate_pattern.cc", - "onc/onc_certificate_pattern.h", - "onc/onc_merger.cc", - "onc/onc_merger.h", - "onc/onc_normalizer.cc", - "onc/onc_normalizer.h", - "onc/onc_translation_tables.cc", - "onc/onc_translation_tables.h", - "onc/onc_translator.h", - "onc/onc_translator_onc_to_shill.cc", - "onc/onc_translator_shill_to_onc.cc", "policy_applicator.cc", "policy_applicator.h", "policy_certificate_provider.h", @@ -267,6 +255,7 @@ "//base/test:test_support", "//chromeos:test_utils", "//chromeos/ash/components/network/metrics:unit_tests", + "//chromeos/ash/components/network/onc:unit_tests", "//chromeos/components/feature_usage", "//chromeos/components/onc", "//chromeos/components/onc:test_support", @@ -324,12 +313,6 @@ "network_type_pattern_unittest.cc", "network_ui_data_unittest.cc", "network_util_unittest.cc", - "onc/network_onc_utils_unittest.cc", - "onc/onc_certificate_importer_impl_unittest.cc", - "onc/onc_certificate_pattern_unittest.cc", - "onc/onc_merger_unittest.cc", - "onc/onc_normalizer_unittest.cc", - "onc/onc_translator_unittest.cc", "profile_policies_unittest.cc", "prohibited_technologies_handler_unittest.cc", "proxy/proxy_config_service_impl_unittest.cc", @@ -340,12 +323,3 @@ "system_token_cert_db_storage_unittest.cc", ] } - -fuzzer_test("onc_normalizer_fuzzer") { - sources = [ "onc/onc_normalizer_fuzzer.cc" ] - deps = [ - ":network", - "//base", - "//chromeos/components/onc:onc", - ] -}
diff --git a/chromeos/network/client_cert_resolver.cc b/chromeos/network/client_cert_resolver.cc index 60e3280..2e38af03 100644 --- a/chromeos/network/client_cert_resolver.cc +++ b/chromeos/network/client_cert_resolver.cc
@@ -21,13 +21,13 @@ #include "base/task/thread_pool.h" #include "base/time/clock.h" #include "base/values.h" +#include "chromeos/ash/components/network/onc/onc_certificate_pattern.h" #include "chromeos/components/onc/variable_expander.h" #include "chromeos/dbus/shill/shill_service_client.h" #include "chromeos/network/certificate_helper.h" #include "chromeos/network/managed_network_configuration_handler.h" #include "chromeos/network/network_event_log.h" #include "chromeos/network/network_state.h" -#include "chromeos/network/onc/onc_certificate_pattern.h" #include "components/onc/onc_constants.h" #include "crypto/scoped_nss_types.h" #include "dbus/object_path.h"
diff --git a/chromeos/network/client_cert_resolver_unittest.cc b/chromeos/network/client_cert_resolver_unittest.cc index 23ea2b54..ca0963b 100644 --- a/chromeos/network/client_cert_resolver_unittest.cc +++ b/chromeos/network/client_cert_resolver_unittest.cc
@@ -19,6 +19,7 @@ #include "base/test/simple_test_clock.h" #include "base/test/task_environment.h" #include "base/values.h" +#include "chromeos/ash/components/network/onc/onc_certificate_importer_impl.h" #include "chromeos/components/onc/onc_test_utils.h" #include "chromeos/dbus/shill/shill_clients.h" #include "chromeos/dbus/shill/shill_manager_client.h" @@ -29,7 +30,6 @@ #include "chromeos/network/network_configuration_handler.h" #include "chromeos/network/network_profile_handler.h" #include "chromeos/network/network_state_handler.h" -#include "chromeos/network/onc/onc_certificate_importer_impl.h" #include "chromeos/network/system_token_cert_db_storage.h" #include "components/onc/onc_constants.h" #include "crypto/scoped_nss_types.h"
diff --git a/chromeos/network/client_cert_util.h b/chromeos/network/client_cert_util.h index 8fc8226..b4f241e 100644 --- a/chromeos/network/client_cert_util.h +++ b/chromeos/network/client_cert_util.h
@@ -10,7 +10,7 @@ #include "base/component_export.h" #include "base/memory/ref_counted.h" -#include "chromeos/network/onc/onc_certificate_pattern.h" +#include "chromeos/ash/components/network/onc/onc_certificate_pattern.h" #include "components/onc/onc_constants.h" namespace base {
diff --git a/chromeos/network/managed_network_configuration_handler.cc b/chromeos/network/managed_network_configuration_handler.cc index 2f4faf1c..a1cb9b85 100644 --- a/chromeos/network/managed_network_configuration_handler.cc +++ b/chromeos/network/managed_network_configuration_handler.cc
@@ -6,9 +6,9 @@ #include "base/memory/ptr_util.h" #include "base/values.h" +#include "chromeos/ash/components/network/onc/network_onc_utils.h" #include "chromeos/network/managed_network_configuration_handler_impl.h" #include "chromeos/network/network_ui_data.h" -#include "chromeos/network/onc/network_onc_utils.h" #include "third_party/cros_system_api/dbus/service_constants.h" namespace chromeos {
diff --git a/chromeos/network/managed_network_configuration_handler_impl.cc b/chromeos/network/managed_network_configuration_handler_impl.cc index 4aec9e04..70f1cd9 100644 --- a/chromeos/network/managed_network_configuration_handler_impl.cc +++ b/chromeos/network/managed_network_configuration_handler_impl.cc
@@ -20,6 +20,8 @@ #include "base/threading/thread_task_runner_handle.h" #include "base/values.h" #include "chromeos/ash/components/network/metrics/esim_policy_login_metrics_logger.h" +#include "chromeos/ash/components/network/onc/onc_merger.h" +#include "chromeos/ash/components/network/onc/onc_translator.h" #include "chromeos/components/onc/onc_signature.h" #include "chromeos/components/onc/onc_utils.h" #include "chromeos/components/onc/onc_validator.h" @@ -37,8 +39,6 @@ #include "chromeos/network/network_state_handler.h" #include "chromeos/network/network_ui_data.h" #include "chromeos/network/network_util.h" -#include "chromeos/network/onc/onc_merger.h" -#include "chromeos/network/onc/onc_translator.h" #include "chromeos/network/policy_util.h" #include "chromeos/network/prohibited_technologies_handler.h" #include "chromeos/network/proxy/ui_proxy_config_service.h"
diff --git a/chromeos/network/network_connection_handler_impl_unittest.cc b/chromeos/network/network_connection_handler_impl_unittest.cc index d85ccb1a..9cade526 100644 --- a/chromeos/network/network_connection_handler_impl_unittest.cc +++ b/chromeos/network/network_connection_handler_impl_unittest.cc
@@ -14,6 +14,7 @@ #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" #include "base/test/task_environment.h" +#include "chromeos/ash/components/network/onc/network_onc_utils.h" #include "chromeos/network/cellular_connection_handler.h" #include "chromeos/network/cellular_inhibitor.h" #include "chromeos/network/cellular_utils.h" @@ -26,7 +27,6 @@ #include "chromeos/network/network_profile_handler.h" #include "chromeos/network/network_state_handler.h" #include "chromeos/network/network_state_test_helper.h" -#include "chromeos/network/onc/network_onc_utils.h" #include "chromeos/network/prohibited_technologies_handler.h" #include "chromeos/network/stub_cellular_networks_provider.h" #include "chromeos/network/system_token_cert_db_storage.h"
diff --git a/chromeos/network/network_util.cc b/chromeos/network/network_util.cc index ef6b2d54..760701ea 100644 --- a/chromeos/network/network_util.cc +++ b/chromeos/network/network_util.cc
@@ -13,6 +13,8 @@ #include "base/strings/string_tokenizer.h" #include "base/strings/string_util.h" #include "base/values.h" +#include "chromeos/ash/components/network/onc/onc_translation_tables.h" +#include "chromeos/ash/components/network/onc/onc_translator.h" #include "chromeos/components/onc/onc_signature.h" #include "chromeos/login/login_state/login_state.h" #include "chromeos/network/device_state.h" @@ -20,8 +22,6 @@ #include "chromeos/network/network_state.h" #include "chromeos/network/network_state_handler.h" #include "chromeos/network/network_ui_data.h" -#include "chromeos/network/onc/onc_translation_tables.h" -#include "chromeos/network/onc/onc_translator.h" #include "components/device_event_log/device_event_log.h" #include "third_party/cros_system_api/dbus/service_constants.h"
diff --git a/chromeos/network/policy_applicator.cc b/chromeos/network/policy_applicator.cc index c6bf902..9673bdc6a 100644 --- a/chromeos/network/policy_applicator.cc +++ b/chromeos/network/policy_applicator.cc
@@ -15,6 +15,7 @@ #include "base/location.h" #include "base/logging.h" #include "base/memory/ptr_util.h" +#include "chromeos/ash/components/network/onc/onc_translator.h" #include "chromeos/components/onc/onc_signature.h" #include "chromeos/dbus/shill/shill_profile_client.h" #include "chromeos/network/cellular_policy_handler.h" @@ -22,7 +23,6 @@ #include "chromeos/network/network_event_log.h" #include "chromeos/network/network_type_pattern.h" #include "chromeos/network/network_ui_data.h" -#include "chromeos/network/onc/onc_translator.h" #include "chromeos/network/policy_util.h" #include "chromeos/network/shill_property_util.h" #include "components/onc/onc_constants.h"
diff --git a/chromeos/network/policy_util.cc b/chromeos/network/policy_util.cc index 1b464c06..7a6cd05 100644 --- a/chromeos/network/policy_util.cc +++ b/chromeos/network/policy_util.cc
@@ -10,15 +10,15 @@ #include "base/logging.h" #include "base/notreached.h" #include "base/values.h" +#include "chromeos/ash/components/network/onc/network_onc_utils.h" +#include "chromeos/ash/components/network/onc/onc_merger.h" +#include "chromeos/ash/components/network/onc/onc_normalizer.h" +#include "chromeos/ash/components/network/onc/onc_translator.h" #include "chromeos/components/onc/onc_signature.h" #include "chromeos/components/onc/onc_utils.h" #include "chromeos/network/network_profile.h" #include "chromeos/network/network_type_pattern.h" #include "chromeos/network/network_ui_data.h" -#include "chromeos/network/onc/network_onc_utils.h" -#include "chromeos/network/onc/onc_merger.h" -#include "chromeos/network/onc/onc_normalizer.h" -#include "chromeos/network/onc/onc_translator.h" #include "chromeos/network/shill_property_util.h" #include "components/onc/onc_constants.h" #include "third_party/cros_system_api/dbus/service_constants.h"
diff --git a/chromeos/network/prohibited_technologies_handler_unittest.cc b/chromeos/network/prohibited_technologies_handler_unittest.cc index ca9724e..42287c7 100644 --- a/chromeos/network/prohibited_technologies_handler_unittest.cc +++ b/chromeos/network/prohibited_technologies_handler_unittest.cc
@@ -14,12 +14,12 @@ #include "base/memory/ptr_util.h" #include "base/run_loop.h" #include "base/test/task_environment.h" +#include "chromeos/ash/components/network/onc/network_onc_utils.h" #include "chromeos/network/managed_network_configuration_handler_impl.h" #include "chromeos/network/network_configuration_handler.h" #include "chromeos/network/network_profile_handler.h" #include "chromeos/network/network_state_handler.h" #include "chromeos/network/network_state_test_helper.h" -#include "chromeos/network/onc/network_onc_utils.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/cros_system_api/dbus/service_constants.h"
diff --git a/chromeos/network/proxy/proxy_config_handler.cc b/chromeos/network/proxy/proxy_config_handler.cc index ea32bf2..afb5e9d 100644 --- a/chromeos/network/proxy/proxy_config_handler.cc +++ b/chromeos/network/proxy/proxy_config_handler.cc
@@ -11,13 +11,13 @@ #include "base/json/json_writer.h" #include "base/logging.h" #include "base/values.h" +#include "chromeos/ash/components/network/onc/network_onc_utils.h" #include "chromeos/dbus/shill/shill_service_client.h" #include "chromeos/network/network_handler_callbacks.h" #include "chromeos/network/network_profile.h" #include "chromeos/network/network_profile_handler.h" #include "chromeos/network/network_state.h" #include "chromeos/network/network_state_handler.h" -#include "chromeos/network/onc/network_onc_utils.h" #include "components/onc/onc_pref_names.h" #include "components/pref_registry/pref_registry_syncable.h" #include "components/prefs/pref_registry_simple.h"
diff --git a/chromeos/network/proxy/proxy_config_service_impl.cc b/chromeos/network/proxy/proxy_config_service_impl.cc index b9a708390..c487edf 100644 --- a/chromeos/network/proxy/proxy_config_service_impl.cc +++ b/chromeos/network/proxy/proxy_config_service_impl.cc
@@ -12,11 +12,11 @@ #include "base/location.h" #include "base/logging.h" #include "base/values.h" +#include "chromeos/ash/components/network/onc/network_onc_utils.h" #include "chromeos/network/network_profile.h" #include "chromeos/network/network_profile_handler.h" #include "chromeos/network/network_state.h" #include "chromeos/network/network_state_handler.h" -#include "chromeos/network/onc/network_onc_utils.h" #include "chromeos/network/proxy/proxy_config_handler.h" #include "components/onc/onc_pref_names.h" #include "components/prefs/pref_service.h"
diff --git a/chromeos/services/network_config/cros_network_config.cc b/chromeos/services/network_config/cros_network_config.cc index d8f472f9..7ef4d84 100644 --- a/chromeos/services/network_config/cros_network_config.cc +++ b/chromeos/services/network_config/cros_network_config.cc
@@ -16,6 +16,7 @@ #include "base/strings/string_split.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" +#include "chromeos/ash/components/network/onc/onc_translation_tables.h" #include "chromeos/components/sync_wifi/network_eligibility_checker.h" #include "chromeos/dbus/hermes/hermes_euicc_client.h" #include "chromeos/dbus/hermes/hermes_manager_client.h" @@ -35,7 +36,6 @@ #include "chromeos/network/network_state_handler.h" #include "chromeos/network/network_type_pattern.h" #include "chromeos/network/network_util.h" -#include "chromeos/network/onc/onc_translation_tables.h" #include "chromeos/network/prohibited_technologies_handler.h" #include "chromeos/network/proxy/ui_proxy_config_service.h" #include "chromeos/services/network_config/public/cpp/cros_network_config_util.h"
diff --git a/chromeos/services/network_config/public/mojom/cros_network_config.mojom b/chromeos/services/network_config/public/mojom/cros_network_config.mojom index 5ab2e54..d3b1f2d 100644 --- a/chromeos/services/network_config/public/mojom/cros_network_config.mojom +++ b/chromeos/services/network_config/public/mojom/cros_network_config.mojom
@@ -740,9 +740,9 @@ // Properties for SetProperties and ConfigureNetwork. All of the top level // properties and many nested properties are optional so that sparse // configurations can be provided, e.g. just the |auto_connect| property can -// be changed. The ONC validation code (chromeos/network/onc/onc_validator.cc) -// ensures that configurations are valid before translating and passing them to -// Shill. +// be changed. The ONC validation code +// (chromeos/ash/components/network/onc/onc_validator.cc) ensures that +// configurations are valid before translating and passing them to Shill. // Wrapper to allow optional auto_connect configuration. struct AutoConnectConfig {
diff --git a/chromeos/tast_control.gni b/chromeos/tast_control.gni index f9f3e6c..17b33ee 100644 --- a/chromeos/tast_control.gni +++ b/chromeos/tast_control.gni
@@ -226,10 +226,6 @@ # https://crbug.com/1327361 "policy.FullscreenAllowed", - # https://crbug.com/1328925 - "inputs.InputMethodManagement", - "inputs.InputMethodManagement.guest", - # https://crbug.com/1328128 "policy.PopupsForURLCheck.blocklist", ]
diff --git a/components/autofill/content/browser/content_autofill_driver_factory.cc b/components/autofill/content/browser/content_autofill_driver_factory.cc index d46c26e..7992fb1 100644 --- a/components/autofill/content/browser/content_autofill_driver_factory.cc +++ b/components/autofill/content/browser/content_autofill_driver_factory.cc
@@ -137,7 +137,7 @@ // 3. `SomeOtherWebContentsObserver::RenderFrameDeleted(render_frame_host)` // calls `DriverForFrame(render_frame_host)`. // 5. `render_frame_host->~RenderFrameHostImpl()` finishes. - if (render_frame_host->IsRenderFrameCreated()) { + if (render_frame_host->IsRenderFrameLive()) { driver = CreateDriver(render_frame_host); DCHECK_EQ(driver_map_.find(render_frame_host)->second.get(), driver.get());
diff --git a/components/autofill/ios/browser/autofill_agent_unittests.mm b/components/autofill/ios/browser/autofill_agent_unittests.mm index 29aba95b..049f7f0 100644 --- a/components/autofill/ios/browser/autofill_agent_unittests.mm +++ b/components/autofill/ios/browser/autofill_agent_unittests.mm
@@ -179,7 +179,7 @@ fillFormData:form inFrame:fake_web_state_.GetWebFramesManager()->GetMainWebFrame()]; fake_web_state_.WasShown(); - EXPECT_EQ("__gCrWeb.autofill.fillForm({\"fields\":{\"2\":{\"section\":\"\"," + EXPECT_EQ(u"__gCrWeb.autofill.fillForm({\"fields\":{\"2\":{\"section\":\"\"," "\"value\":\"number_value\"}," "\"3\":{\"section\":\"\",\"value\":\"name_value\"}}," "\"formName\":\"CC form\",\"formRendererID\":1}, 0);",
diff --git a/components/autofill_assistant/browser/autofill_assistant_tts_controller_unittest.cc b/components/autofill_assistant/browser/autofill_assistant_tts_controller_unittest.cc index fe18483..0e4f322 100644 --- a/components/autofill_assistant/browser/autofill_assistant_tts_controller_unittest.cc +++ b/components/autofill_assistant/browser/autofill_assistant_tts_controller_unittest.cc
@@ -44,6 +44,7 @@ content::TtsEngineDelegate* GetTtsEngineDelegate() override { return nullptr; } + void RefreshVoices() override {} void SetTtsPlatform(content::TtsPlatform* tts_platform) override {} int QueueSize() override { return 0; } void StripSSML(
diff --git a/components/cast_streaming/browser/BUILD.gn b/components/cast_streaming/browser/BUILD.gn index 07f344c61..a69837fa 100644 --- a/components/cast_streaming/browser/BUILD.gn +++ b/components/cast_streaming/browser/BUILD.gn
@@ -72,6 +72,7 @@ source_set("streaming_session") { deps = [ ":core", + ":demuxer_stream_data_provider", ":receiver_session_public", ":renderer_controls", ":streaming_initialization_info", @@ -176,6 +177,7 @@ source_set("demuxer_stream_data_provider") { deps = [ + ":demuxer_stream_client", "//base", "//components/cast_streaming/public/mojom", "//media", @@ -199,7 +201,7 @@ source_set("streaming_initialization_info") { public_deps = [ - ":demuxer_stream_data_provider", + ":demuxer_stream_client", "//media", "//third_party/openscreen/src/cast/streaming:receiver", ] @@ -210,8 +212,15 @@ ] } +source_set("demuxer_stream_client") { + visibility = [ ":*" ] + sources = [ "demuxer_stream_client.h" ] + public_deps = [ "//base" ] +} + source_set("renderer_controls") { public_deps = [ + ":demuxer_stream_client", ":streaming_initialization_info", "//base", "//components/cast_streaming/public:remoting_utils", @@ -254,6 +263,7 @@ testonly = true deps = [ ":browser", + ":demuxer_stream_client", ":demuxer_stream_data_provider", ":renderer_controls", "//base",
diff --git a/components/cast_streaming/browser/demuxer_stream_client.h b/components/cast_streaming/browser/demuxer_stream_client.h new file mode 100644 index 0000000..c320bff --- /dev/null +++ b/components/cast_streaming/browser/demuxer_stream_client.h
@@ -0,0 +1,32 @@ +// 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 COMPONENTS_CAST_STREAMING_BROWSER_DEMUXER_STREAM_CLIENT_H_ +#define COMPONENTS_CAST_STREAMING_BROWSER_DEMUXER_STREAM_CLIENT_H_ + +#include "base/callback.h" + +namespace cast_streaming { + +// This class acts as a client to act upon state changes of the DemuxerStream +// and DemuxerStreamDataProvider with which it is associated. +class DemuxerStreamClient { + public: + virtual ~DemuxerStreamClient() = default; + + // Enables the bitstream converter for the data provider associated with this + // demuxer stream. + using BitstreamConverterEnabledCB = base::OnceCallback<void(bool)>; + virtual void EnableBitstreamConverter(BitstreamConverterEnabledCB cb) = 0; + + // Called when no buffers are available for reading. + virtual void OnNoBuffersAvailable() = 0; + + // Called when a fatal error occurs. Only called once. + virtual void OnError() = 0; +}; + +} // namespace cast_streaming + +#endif // COMPONENTS_CAST_STREAMING_BROWSER_DEMUXER_STREAM_CLIENT_H_
diff --git a/components/cast_streaming/browser/demuxer_stream_data_provider.h b/components/cast_streaming/browser/demuxer_stream_data_provider.h index 7d024cb..6cc294cd 100644 --- a/components/cast_streaming/browser/demuxer_stream_data_provider.h +++ b/components/cast_streaming/browser/demuxer_stream_data_provider.h
@@ -6,7 +6,9 @@ #define COMPONENTS_CAST_STREAMING_BROWSER_DEMUXER_STREAM_DATA_PROVIDER_H_ #include "base/callback_forward.h" +#include "base/memory/weak_ptr.h" #include "base/sequence_checker.h" +#include "components/cast_streaming/browser/demuxer_stream_client.h" #include "components/cast_streaming/public/mojom/demuxer_connector.mojom.h" #include "mojo/public/cpp/bindings/message.h" #include "mojo/public/cpp/bindings/pending_receiver.h" @@ -90,23 +92,21 @@ return config_; } - void SetOnNoBuffersAvailableCallback( - base::RepeatingClosure on_no_buffers_available) { + void SetClient(base::WeakPtr<DemuxerStreamClient> client) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - on_no_buffers_available_ = std::move(on_no_buffers_available); - } - - void SetOnErrorCallback(base::OnceClosure on_error) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - on_error_ = std::move(on_error); + client_ = std::move(client); } private: using GetBufferCallback = typename TMojoReceiverType::GetBufferCallback; + using EnableBitstreamConverterCallback = + typename TMojoReceiverType::EnableBitstreamConverterCallback; void OnFatalError() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - std::move(on_error_).Run(); + if (client_) { + client_->OnError(); + } std::move(on_mojo_disconnect_).Run(); } @@ -123,7 +123,19 @@ } current_callback_ = std::move(callback); - request_buffer_.Run(on_no_buffers_available_); + request_buffer_.Run( + base::BindOnce(&DemuxerStreamClient::OnNoBuffersAvailable, client_)); + } + + void EnableBitstreamConverter( + EnableBitstreamConverterCallback callback) override { + if (client_) { + client_->EnableBitstreamConverter(std::move(callback)); + } else { + std::move(callback).Run(false); + LOG(WARNING) + << "EnableBitstreamConverter() called when no client was available"; + } } // The most recently set config. @@ -139,12 +151,9 @@ // Callback to request a new buffer be read from the receiver. RequestBufferCB request_buffer_; - // Callback called when no buffers are available for reading. - base::RepeatingClosure on_no_buffers_available_; - - // Callback called on an unrecoverable error, prior to shutdown of the - // component. - base::OnceClosure on_error_; + // Client to use when the associated DemuxerStream requires an action be + // performed. + base::WeakPtr<DemuxerStreamClient> client_; // Callback called upon a mojo disconnection. base::OnceClosure on_mojo_disconnect_;
diff --git a/components/cast_streaming/browser/demuxer_stream_data_provider_unittest.cc b/components/cast_streaming/browser/demuxer_stream_data_provider_unittest.cc index 15fc978..992a1c7 100644 --- a/components/cast_streaming/browser/demuxer_stream_data_provider_unittest.cc +++ b/components/cast_streaming/browser/demuxer_stream_data_provider_unittest.cc
@@ -6,8 +6,10 @@ #include <utility> +#include "base/memory/weak_ptr.h" #include "base/test/bind.h" #include "base/test/task_environment.h" +#include "components/cast_streaming/browser/demuxer_stream_client.h" #include "media/base/audio_codecs.h" #include "media/base/audio_decoder_config.h" #include "media/base/channel_layout.h" @@ -47,12 +49,7 @@ base::Unretained(&callbacks_)), second_config_); - data_provider_->SetOnNoBuffersAvailableCallback(base::BindRepeating( - &DemuxerStreamDataProviderTest::Callbacks::OnNoBuffers, - base::Unretained(&callbacks_))); - data_provider_->SetOnErrorCallback( - base::BindRepeating(&DemuxerStreamDataProviderTest::Callbacks::OnError, - base::Unretained(&callbacks_))); + data_provider_->SetClient(client_.weak_factory_.GetWeakPtr()); std::vector<uint8_t> data = {1, 2, 3}; first_buffer_ = media::DecoderBuffer::CopyFrom(data.data(), 3); @@ -77,8 +74,6 @@ protected: class Callbacks { public: - MOCK_METHOD0(OnNoBuffers, void()); - MOCK_METHOD0(OnError, void()); MOCK_METHOD1(RequestBuffer, void(base::OnceClosure)); MOCK_METHOD0(OnMojoDisconnect, void()); @@ -101,6 +96,17 @@ } }; + class MockDemuxerStreamClient : public DemuxerStreamClient { + public: + ~MockDemuxerStreamClient() override = default; + + MOCK_METHOD1(EnableBitstreamConverter, void(BitstreamConverterEnabledCB)); + MOCK_METHOD0(OnNoBuffersAvailable, void()); + MOCK_METHOD0(OnError, void()); + + base::WeakPtrFactory<MockDemuxerStreamClient> weak_factory_{this}; + }; + using MojoPipePair = std::pair<mojo::ScopedDataPipeProducerHandle, mojo::ScopedDataPipeConsumerHandle>; MojoPipePair GetMojoPipePair() { @@ -112,6 +118,7 @@ } testing::StrictMock<Callbacks> callbacks_; + testing::StrictMock<MockDemuxerStreamClient> client_; base::test::SingleThreadTaskEnvironment task_environment_{ base::test::TaskEnvironment::TimeSource::MOCK_TIME}; @@ -178,26 +185,24 @@ task_environment_.RunUntilIdle(); } -TEST_F(DemuxerStreamDataProviderTest, NoBuffersCallsWithCallback) { +TEST_F(DemuxerStreamDataProviderTest, NoBuffersCallback) { EXPECT_CALL(callbacks_, RequestBuffer(testing::_)) .WillOnce([](base::OnceClosure no_buffers_cb) { std::move(no_buffers_cb).Run(); }); - EXPECT_CALL(callbacks_, OnNoBuffers()); + EXPECT_CALL(client_, OnNoBuffersAvailable()); remote_->GetBuffer(base::BindOnce( &DemuxerStreamDataProviderTest::Callbacks::OnGetBufferDone, base::Unretained(&callbacks_), first_config_, first_buffer_)); task_environment_.RunUntilIdle(); } -TEST_F(DemuxerStreamDataProviderTest, NoBuffersCallsNoCallback) { - data_provider_->SetOnNoBuffersAvailableCallback(base::RepeatingClosure()); - EXPECT_CALL(callbacks_, RequestBuffer(testing::_)) +TEST_F(DemuxerStreamDataProviderTest, EnableBitstreamConverter) { + EXPECT_CALL(client_, EnableBitstreamConverter(testing::_)) .WillOnce( - [](base::OnceClosure no_buffers_cb) { ASSERT_FALSE(no_buffers_cb); }); - remote_->GetBuffer(base::BindOnce( - &DemuxerStreamDataProviderTest::Callbacks::OnGetBufferDone, - base::Unretained(&callbacks_), first_config_, first_buffer_)); + [](base::OnceCallback<void(bool)> cb) { std::move(cb).Run(true); }); + ; + remote_->EnableBitstreamConverter(base::OnceCallback<void(bool)>()); task_environment_.RunUntilIdle(); }
diff --git a/components/cast_streaming/browser/playback_command_dispatcher.cc b/components/cast_streaming/browser/playback_command_dispatcher.cc index 0e11e163..1a53541 100644 --- a/components/cast_streaming/browser/playback_command_dispatcher.cc +++ b/components/cast_streaming/browser/playback_command_dispatcher.cc
@@ -90,39 +90,15 @@ absl::optional<StreamingInitializationInfo::AudioStreamInfo> audio_stream_info; if (receivers.audio_receiver) { - auto no_buffers_cb = base::BindPostTask( - task_runner_, - base::BindRepeating( - &remoting::RpcDemuxerStreamHandler::RequestMoreAudioBuffers, - demuxer_stream_handler_->GetWeakPtr()), - FROM_HERE); - auto error_cb = base::BindPostTask( - task_runner_, - base::BindRepeating(&remoting::RpcDemuxerStreamHandler::OnAudioError, - demuxer_stream_handler_->GetWeakPtr()), - FROM_HERE); audio_stream_info.emplace(media::AudioDecoderConfig(), - receivers.audio_receiver, - std::move(no_buffers_cb), std::move(error_cb)); + receivers.audio_receiver); } absl::optional<StreamingInitializationInfo::VideoStreamInfo> video_stream_info; if (receivers.video_receiver) { - auto no_buffers_cb = base::BindPostTask( - task_runner_, - base::BindRepeating( - &remoting::RpcDemuxerStreamHandler::RequestMoreVideoBuffers, - demuxer_stream_handler_->GetWeakPtr()), - FROM_HERE); - auto error_cb = base::BindPostTask( - task_runner_, - base::BindRepeating(&remoting::RpcDemuxerStreamHandler::OnVideoError, - demuxer_stream_handler_->GetWeakPtr()), - FROM_HERE); video_stream_info.emplace(media::VideoDecoderConfig(), - receivers.video_receiver, - std::move(no_buffers_cb), std::move(error_cb)); + receivers.video_receiver); } streaming_init_info_.emplace(receiver_session_, std::move(audio_stream_info), @@ -276,10 +252,18 @@ DCHECK(demuxer_stream_handler_); if (streaming_init_info_->audio_stream_info) { - demuxer_stream_handler_->RequestMoreAudioBuffers(); + auto client = demuxer_stream_handler_->GetAudioClient(); + DCHECK(client); + client->OnNoBuffersAvailable(); + streaming_init_info_->audio_stream_info->demuxer_stream_client = + std::move(client); } if (streaming_init_info_->video_stream_info) { - demuxer_stream_handler_->RequestMoreVideoBuffers(); + auto client = demuxer_stream_handler_->GetVideoClient(); + DCHECK(client); + client->OnNoBuffersAvailable(); + streaming_init_info_->video_stream_info->demuxer_stream_client = + std::move(client); } // |streaming_init_info_| is intentionally copied here.
diff --git a/components/cast_streaming/browser/receiver_session_impl.cc b/components/cast_streaming/browser/receiver_session_impl.cc index 05a40204..a09ddfc 100644 --- a/components/cast_streaming/browser/receiver_session_impl.cc +++ b/components/cast_streaming/browser/receiver_session_impl.cc
@@ -95,11 +95,8 @@ base::BindOnce(&ReceiverSessionImpl::OnMojoDisconnect, weak_factory_.GetWeakPtr()), std::move(initialization_info.audio_stream_info->config)); - audio_demuxer_stream_data_provider_->SetOnNoBuffersAvailableCallback( - std::move( - initialization_info.audio_stream_info->on_no_buffers_callback)); - audio_demuxer_stream_data_provider_->SetOnErrorCallback( - std::move(initialization_info.audio_stream_info->on_error_callback)); + audio_demuxer_stream_data_provider_->SetClient(std::move( + initialization_info.audio_stream_info->demuxer_stream_client)); audio_info = mojom::AudioStreamInitializationInfo::New( std::move(audio_receiver), mojom::AudioStreamInfo::New( @@ -117,11 +114,8 @@ base::BindOnce(&ReceiverSessionImpl::OnMojoDisconnect, weak_factory_.GetWeakPtr()), std::move(initialization_info.video_stream_info->config)); - video_demuxer_stream_data_provider_->SetOnNoBuffersAvailableCallback( - std::move( - initialization_info.video_stream_info->on_no_buffers_callback)); - video_demuxer_stream_data_provider_->SetOnErrorCallback( - std::move(initialization_info.video_stream_info->on_error_callback)); + video_demuxer_stream_data_provider_->SetClient(std::move( + initialization_info.video_stream_info->demuxer_stream_client)); video_info = mojom::VideoStreamInitializationInfo::New( std::move(video_receiver), mojom::VideoStreamInfo::New( @@ -163,11 +157,8 @@ if (audio_pipe_consumer) { if (!audio_demuxer_stream_data_provider_->config().Matches( initialization_info.audio_stream_info->config)) { - audio_demuxer_stream_data_provider_->SetOnNoBuffersAvailableCallback( - std::move( - initialization_info.audio_stream_info->on_no_buffers_callback)); - audio_demuxer_stream_data_provider_->SetOnErrorCallback( - std::move(initialization_info.audio_stream_info->on_error_callback)); + audio_demuxer_stream_data_provider_->SetClient(std::move( + initialization_info.audio_stream_info->demuxer_stream_client)); audio_demuxer_stream_data_provider_->OnNewStreamInfo( std::move(initialization_info.audio_stream_info->config), std::move(*audio_pipe_consumer)); @@ -180,11 +171,8 @@ if (video_pipe_consumer) { if (!video_demuxer_stream_data_provider_->config().Matches( initialization_info.video_stream_info->config)) { - video_demuxer_stream_data_provider_->SetOnNoBuffersAvailableCallback( - std::move( - initialization_info.video_stream_info->on_no_buffers_callback)); - video_demuxer_stream_data_provider_->SetOnErrorCallback( - std::move(initialization_info.video_stream_info->on_error_callback)); + video_demuxer_stream_data_provider_->SetClient(std::move( + initialization_info.video_stream_info->demuxer_stream_client)); video_demuxer_stream_data_provider_->OnNewStreamInfo( std::move(initialization_info.video_stream_info->config), std::move(*video_pipe_consumer));
diff --git a/components/cast_streaming/browser/rpc_demuxer_stream_handler.cc b/components/cast_streaming/browser/rpc_demuxer_stream_handler.cc index 70eb6ca..4aba944 100644 --- a/components/cast_streaming/browser/rpc_demuxer_stream_handler.cc +++ b/components/cast_streaming/browser/rpc_demuxer_stream_handler.cc
@@ -20,13 +20,12 @@ RpcDemuxerStreamHandler::RpcDemuxerStreamHandler( Client* client, HandleFactory handle_factory, - RpcProcessMessageCB message_processor) + RpcProcessMessageCB process_message_cb) : client_(client), handle_factory_(std::move(handle_factory)), - message_processor_(std::move(message_processor)), - weak_factory_(this) { + process_message_cb_(std::move(process_message_cb)) { DCHECK(handle_factory_); - DCHECK(message_processor_); + DCHECK(process_message_cb_); } RpcDemuxerStreamHandler::~RpcDemuxerStreamHandler() = default; @@ -38,83 +37,27 @@ // initialize the DemuxerStreams. if (audio_stream_handle != openscreen::cast::RpcMessenger::kInvalidHandle) { audio_message_processor_ = std::make_unique<MessageProcessor>( - client_, handle_factory_.Run(), audio_stream_handle, - MessageProcessor::Type::kAudio); + client_, process_message_cb_, handle_factory_.Run(), + audio_stream_handle, MessageProcessor::Type::kAudio); std::unique_ptr<openscreen::cast::RpcMessage> message = remoting::CreateMessageForDemuxerStreamInitialize( audio_message_processor_->local_handle()); - message_processor_.Run(audio_message_processor_->remote_handle(), - std::move(message)); + process_message_cb_.Run(audio_message_processor_->remote_handle(), + std::move(message)); } if (video_stream_handle != openscreen::cast::RpcMessenger::kInvalidHandle) { video_message_processor_ = std::make_unique<MessageProcessor>( - client_, handle_factory_.Run(), video_stream_handle, - MessageProcessor::Type::kVideo); + client_, process_message_cb_, handle_factory_.Run(), + video_stream_handle, MessageProcessor::Type::kVideo); std::unique_ptr<openscreen::cast::RpcMessage> message = remoting::CreateMessageForDemuxerStreamInitialize( video_message_processor_->local_handle()); - message_processor_.Run(video_message_processor_->remote_handle(), - std::move(message)); + process_message_cb_.Run(video_message_processor_->remote_handle(), + std::move(message)); } } -void RpcDemuxerStreamHandler::RequestMoreAudioBuffers() { - if (!audio_message_processor_) { - return; - } - - RequestMoreBuffers(audio_message_processor_.get()); -} - -void RpcDemuxerStreamHandler::RequestMoreVideoBuffers() { - if (!video_message_processor_) { - return; - } - - RequestMoreBuffers(video_message_processor_.get()); -} - -void RpcDemuxerStreamHandler::RequestMoreBuffers( - MessageProcessor* message_processor) { - if (message_processor->is_read_until_call_pending()) { - return; - } - - message_processor->set_read_until_call_pending(); - auto message = CreateMessageForDemuxerStreamReadUntil( - message_processor->local_handle(), - message_processor->total_frames_received() + kNumFramesInEachReadUntil); - message_processor_.Run(message_processor->remote_handle(), - std::move(message)); -} - -void RpcDemuxerStreamHandler::OnAudioError() { - if (!audio_message_processor_) { - return; - } - - OnError(audio_message_processor_.get()); -} - -void RpcDemuxerStreamHandler::OnVideoError() { - if (!video_message_processor_) { - return; - } - - OnError(video_message_processor_.get()); -} - -void RpcDemuxerStreamHandler::OnError(MessageProcessor* message_processor) { - auto message = CreateMessageForDemuxerStreamError(); - message_processor_.Run(message_processor->remote_handle(), - std::move(message)); -} - -base::WeakPtr<RpcDemuxerStreamHandler> RpcDemuxerStreamHandler::GetWeakPtr() { - return weak_factory_.GetWeakPtr(); -} - void RpcDemuxerStreamHandler::OnRpcInitializeCallback( openscreen::cast::RpcMessenger::Handle handle, absl::optional<media::AudioDecoderConfig> audio_config, @@ -152,22 +95,58 @@ } } +void RpcDemuxerStreamHandler::OnRpcBitstreamConverterEnabled( + openscreen::cast::RpcMessenger::Handle handle, + bool success) { + if (audio_message_processor_ && + handle == audio_message_processor_->local_handle()) { + audio_message_processor_->OnBitstreamConverterEnabled(success); + } else if (video_message_processor_ && + handle == video_message_processor_->local_handle()) { + video_message_processor_->OnBitstreamConverterEnabled(success); + } else { + LOG(WARNING) + << "OnRpcBitstreamConverterEnabled received for invalid handle"; + } +} + +base::WeakPtr<DemuxerStreamClient> RpcDemuxerStreamHandler::GetAudioClient() { + if (!audio_message_processor_) { + return nullptr; + } + + return audio_message_processor_->GetWeakPtr(); +} + +base::WeakPtr<DemuxerStreamClient> RpcDemuxerStreamHandler::GetVideoClient() { + if (!video_message_processor_) { + return nullptr; + } + + return video_message_processor_->GetWeakPtr(); +} + RpcDemuxerStreamHandler::Client::~Client() = default; RpcDemuxerStreamHandler::MessageProcessor::MessageProcessor( Client* client, + RpcProcessMessageCB process_message_cb, openscreen::cast::RpcMessenger::Handle local_handle, openscreen::cast::RpcMessenger::Handle remote_handle, Type type) : client_(client), + process_message_cb_(std::move(process_message_cb)), local_handle_(local_handle), remote_handle_(remote_handle), - type_(type) { + type_(type), + weak_factory_(this) { DCHECK(client_); DCHECK_NE(local_handle_, openscreen::cast::RpcMessenger::kInvalidHandle); DCHECK_NE(remote_handle_, openscreen::cast::RpcMessenger::kInvalidHandle); } +RpcDemuxerStreamHandler::MessageProcessor::~MessageProcessor() = default; + bool RpcDemuxerStreamHandler::MessageProcessor::OnRpcInitializeCallback( absl::optional<media::AudioDecoderConfig> audio_config, absl::optional<media::VideoDecoderConfig> video_config) { @@ -194,6 +173,7 @@ uint32_t total_frames_received) { if (!OnRpcInitializeCallback(std::move(audio_config), std::move(video_config))) { + LOG(WARNING) << "Failed to process OnRpcReadUntilCallback."; return false; } @@ -202,4 +182,43 @@ return true; } +void RpcDemuxerStreamHandler::MessageProcessor::OnBitstreamConverterEnabled( + bool success) { + if (!bitstream_converter_enabled_cb_) { + return; + } + + std::move(bitstream_converter_enabled_cb_).Run(success); +} + +base::WeakPtr<RpcDemuxerStreamHandler::MessageProcessor> +RpcDemuxerStreamHandler::MessageProcessor::GetWeakPtr() { + return weak_factory_.GetWeakPtr(); +} + +void RpcDemuxerStreamHandler::MessageProcessor::EnableBitstreamConverter( + BitstreamConverterEnabledCB cb) { + DCHECK(!bitstream_converter_enabled_cb_); + bitstream_converter_enabled_cb_ = std::move(cb); + + auto message = CreateMessageForDemuxerStreamEnableBitstreamConverter(); + process_message_cb_.Run(remote_handle(), std::move(message)); +} + +void RpcDemuxerStreamHandler::MessageProcessor::OnNoBuffersAvailable() { + if (is_read_until_call_pending()) { + return; + } + + set_read_until_call_pending(); + auto message = CreateMessageForDemuxerStreamReadUntil( + local_handle(), total_frames_received() + kNumFramesInEachReadUntil); + process_message_cb_.Run(remote_handle(), std::move(message)); +} + +void RpcDemuxerStreamHandler::MessageProcessor::OnError() { + auto message = CreateMessageForDemuxerStreamError(); + process_message_cb_.Run(remote_handle(), std::move(message)); +} + } // namespace cast_streaming::remoting
diff --git a/components/cast_streaming/browser/rpc_demuxer_stream_handler.h b/components/cast_streaming/browser/rpc_demuxer_stream_handler.h index 1a5b8a5..c1b2f1d 100644 --- a/components/cast_streaming/browser/rpc_demuxer_stream_handler.h +++ b/components/cast_streaming/browser/rpc_demuxer_stream_handler.h
@@ -9,6 +9,7 @@ #include "base/callback.h" #include "base/memory/weak_ptr.h" +#include "components/cast_streaming/browser/demuxer_stream_client.h" #include "components/cast_streaming/public/rpc_call_message_handler.h" #include "media/base/audio_decoder_config.h" #include "media/base/video_decoder_config.h" @@ -44,7 +45,7 @@ std::unique_ptr<openscreen::cast::RpcMessage>)>; RpcDemuxerStreamHandler(Client* client, HandleFactory handle_factory, - RpcProcessMessageCB message_processor); + RpcProcessMessageCB process_message_cb); ~RpcDemuxerStreamHandler() override; @@ -55,19 +56,17 @@ openscreen::cast::RpcMessenger::Handle audio_stream_handle, openscreen::cast::RpcMessenger::Handle video_stream_handle); - // To be called when no further buffers are available for reading to request - // more be sent. - void RequestMoreAudioBuffers(); - void RequestMoreVideoBuffers(); + // To be called when the RPC_DS_ENABLEBITSTREAMCONVERTER_CALLBACK message is + // received. + void OnRpcBitstreamConverterEnabled( + openscreen::cast::RpcMessenger::Handle handle, + bool success); - // Called when a DemuxerStream error occurs to inform the sender device. - void OnAudioError(); - void OnVideoError(); - - base::WeakPtr<RpcDemuxerStreamHandler> GetWeakPtr(); + base::WeakPtr<DemuxerStreamClient> GetAudioClient(); + base::WeakPtr<DemuxerStreamClient> GetVideoClient(); private: - class MessageProcessor { + class MessageProcessor : public DemuxerStreamClient { public: enum class Type { kUnknown = 0, kAudio, kVideo }; @@ -79,9 +78,11 @@ // OnRpcAcquiredDemuxer() call and used as the handle for sending messages // back to the sender. MessageProcessor(Client* client, + RpcProcessMessageCB process_message_cb, openscreen::cast::RpcMessenger::Handle local_handle, openscreen::cast::RpcMessenger::Handle remote_handle, Type type); + ~MessageProcessor() override; bool OnRpcInitializeCallback( absl::optional<media::AudioDecoderConfig> audio_config, @@ -90,6 +91,9 @@ absl::optional<media::AudioDecoderConfig> audio_config, absl::optional<media::VideoDecoderConfig> video_config, uint32_t total_frames_received); + void OnBitstreamConverterEnabled(bool success); + + base::WeakPtr<MessageProcessor> GetWeakPtr(); uint32_t total_frames_received() const { return total_frames_received_; } @@ -106,7 +110,12 @@ void set_read_until_call_pending() { is_read_until_call_pending_ = true; } private: + void EnableBitstreamConverter(BitstreamConverterEnabledCB cb) override; + void OnNoBuffersAvailable() override; + void OnError() override; + Client* client_; + RpcProcessMessageCB process_message_cb_; openscreen::cast::RpcMessenger::Handle local_handle_; openscreen::cast::RpcMessenger::Handle remote_handle_; Type type_ = Type::kUnknown; @@ -114,6 +123,11 @@ uint32_t total_frames_received_ = 0; bool is_read_until_call_pending_ = false; + + // Most recent callback for EnableBitstreamConverter(). + BitstreamConverterEnabledCB bitstream_converter_enabled_cb_; + + base::WeakPtrFactory<MessageProcessor> weak_factory_; }; // Helpers for the above methods of the same name. @@ -133,12 +147,10 @@ Client* const client_; HandleFactory handle_factory_; - RpcProcessMessageCB message_processor_; + RpcProcessMessageCB process_message_cb_; std::unique_ptr<MessageProcessor> audio_message_processor_; std::unique_ptr<MessageProcessor> video_message_processor_; - - base::WeakPtrFactory<RpcDemuxerStreamHandler> weak_factory_; }; } // namespace cast_streaming::remoting
diff --git a/components/cast_streaming/browser/rpc_demuxer_stream_handler_unittests.cc b/components/cast_streaming/browser/rpc_demuxer_stream_handler_unittests.cc index 8305553..3e0e57c 100644 --- a/components/cast_streaming/browser/rpc_demuxer_stream_handler_unittests.cc +++ b/components/cast_streaming/browser/rpc_demuxer_stream_handler_unittests.cc
@@ -62,6 +62,16 @@ EXPECT_EQ(handle, remote_handle); } +ACTION_P(CheckEnableBistreamConverterCall, remote_handle) { + const openscreen::cast::RpcMessenger::Handle handle = arg0; + const std::unique_ptr<openscreen::cast::RpcMessage>& rpc = arg1; + + ASSERT_TRUE(rpc); + EXPECT_EQ(rpc->proc(), + openscreen::cast::RpcMessage::RPC_DS_ENABLEBITSTREAMCONVERTER); + EXPECT_EQ(handle, remote_handle); +} + } // namespace class RpcDemuxerStreamHandlerTest : public testing::Test { @@ -119,6 +129,8 @@ MOCK_METHOD0(GetHandle, openscreen::cast::RpcMessenger::Handle()); + MOCK_METHOD1(OnBitstreamConverterEnabled, void(bool)); + void OnRpcInitializeCallback( openscreen::cast::RpcMessenger::Handle handle, absl::optional<media::AudioDecoderConfig> audio_config, @@ -139,6 +151,46 @@ total_frames_received); } + void RequestMoreAudioBuffers() { + auto client = stream_handler_.GetAudioClient(); + ASSERT_TRUE(!!client); + client->OnNoBuffersAvailable(); + } + + void RequestMoreVideoBuffers() { + auto client = stream_handler_.GetVideoClient(); + ASSERT_TRUE(!!client); + client->OnNoBuffersAvailable(); + } + + void OnAudioError() { + auto client = stream_handler_.GetAudioClient(); + ASSERT_TRUE(!!client); + client->OnError(); + } + + void OnVideoError() { + auto client = stream_handler_.GetVideoClient(); + ASSERT_TRUE(!!client); + client->OnError(); + } + + void EnableAudioBitstreamConverter() { + auto client = stream_handler_.GetAudioClient(); + ASSERT_TRUE(!!client); + client->EnableBitstreamConverter(base::BindOnce( + &RpcDemuxerStreamHandlerTest::OnBitstreamConverterEnabled, + base::Unretained(this))); + } + + void EnableVideoBitstreamConverter() { + auto client = stream_handler_.GetVideoClient(); + ASSERT_TRUE(!!client); + client->EnableBitstreamConverter(base::BindOnce( + &RpcDemuxerStreamHandlerTest::OnBitstreamConverterEnabled, + base::Unretained(this))); + } + openscreen::cast::RpcMessenger::Handle audio_remote_handle_ = 123; openscreen::cast::RpcMessenger::Handle video_remote_handle_ = 456; @@ -219,7 +271,7 @@ EXPECT_CALL(*this, SendMessage(_, _)) .WillOnce( CheckReadUntilCall(audio_remote_handle_, audio_local_handle_, 1)); - stream_handler_.RequestMoreAudioBuffers(); + RequestMoreAudioBuffers(); EXPECT_CALL(client_, OnNewAudioConfig(_)) .WillOnce([this](media::AudioDecoderConfig config) { @@ -230,7 +282,7 @@ EXPECT_CALL(*this, SendMessage(_, _)) .WillOnce( CheckReadUntilCall(audio_remote_handle_, audio_local_handle_, 17)); - stream_handler_.RequestMoreAudioBuffers(); + RequestMoreAudioBuffers(); } TEST_F(RpcDemuxerStreamHandlerTest, RequestMoreVideoBuffers) { @@ -243,7 +295,7 @@ EXPECT_CALL(*this, SendMessage(_, _)) .WillOnce( CheckReadUntilCall(video_remote_handle_, video_local_handle_, 12)); - stream_handler_.RequestMoreVideoBuffers(); + RequestMoreVideoBuffers(); EXPECT_CALL(client_, OnNewVideoConfig(_)) .WillOnce([this](media::VideoDecoderConfig config) { @@ -254,19 +306,37 @@ EXPECT_CALL(*this, SendMessage(_, _)) .WillOnce( CheckReadUntilCall(video_remote_handle_, video_local_handle_, 42)); - stream_handler_.RequestMoreVideoBuffers(); + RequestMoreVideoBuffers(); } TEST_F(RpcDemuxerStreamHandlerTest, OnAudioError) { EXPECT_CALL(*this, SendMessage(_, _)) .WillOnce(CheckOnErrorCall(audio_remote_handle_)); - stream_handler_.OnAudioError(); + OnAudioError(); } TEST_F(RpcDemuxerStreamHandlerTest, OnVideoError) { EXPECT_CALL(*this, SendMessage(_, _)) .WillOnce(CheckOnErrorCall(video_remote_handle_)); - stream_handler_.OnVideoError(); + OnVideoError(); +} + +TEST_F(RpcDemuxerStreamHandlerTest, OnEnableAudioBitstreamConverter) { + EXPECT_CALL(*this, SendMessage(_, _)) + .WillOnce(CheckEnableBistreamConverterCall(audio_remote_handle_)); + EnableAudioBitstreamConverter(); + + EXPECT_CALL(*this, OnBitstreamConverterEnabled(true)); + stream_handler_.OnRpcBitstreamConverterEnabled(audio_local_handle_, true); +} + +TEST_F(RpcDemuxerStreamHandlerTest, OnEnableVideoBitstreamConverter) { + EXPECT_CALL(*this, SendMessage(_, _)) + .WillOnce(CheckEnableBistreamConverterCall(video_remote_handle_)); + EnableVideoBitstreamConverter(); + + EXPECT_CALL(*this, OnBitstreamConverterEnabled(false)); + stream_handler_.OnRpcBitstreamConverterEnabled(video_local_handle_, false); } } // namespace cast_streaming::remoting
diff --git a/components/cast_streaming/browser/streaming_initialization_info.cc b/components/cast_streaming/browser/streaming_initialization_info.cc index f6e0ac0a..711473b 100644 --- a/components/cast_streaming/browser/streaming_initialization_info.cc +++ b/components/cast_streaming/browser/streaming_initialization_info.cc
@@ -28,32 +28,18 @@ StreamingInitializationInfo::AudioStreamInfo::AudioStreamInfo( media::AudioDecoderConfig audio_config, openscreen::cast::Receiver* cast_receiver) - : AudioStreamInfo(std::move(audio_config), - cast_receiver, - base::RepeatingClosure(), - base::OnceClosure()) {} + : AudioStreamInfo(std::move(audio_config), cast_receiver, nullptr) {} StreamingInitializationInfo::AudioStreamInfo::AudioStreamInfo( media::AudioDecoderConfig audio_config, openscreen::cast::Receiver* cast_receiver, - base::RepeatingClosure on_no_buffers_cb, - base::OnceClosure on_error_cb) + base::WeakPtr<DemuxerStreamClient> ds_client) : config(std::move(audio_config)), receiver(cast_receiver), - on_no_buffers_callback(std::move(on_no_buffers_cb)), - on_error_callback(std::move(on_error_cb)) {} + demuxer_stream_client(std::move(ds_client)) {} StreamingInitializationInfo::AudioStreamInfo::AudioStreamInfo( - const StreamingInitializationInfo::AudioStreamInfo& other) { - auto& old = const_cast<AudioStreamInfo&>(other); - auto cb_pair = base::SplitOnceCallback(std::move(old.on_error_callback)); - old.on_error_callback = std::move(cb_pair.first); - - config = other.config; - receiver = other.receiver; - on_no_buffers_callback = other.on_no_buffers_callback; - on_error_callback = std::move(cb_pair.second); -} + const StreamingInitializationInfo::AudioStreamInfo& other) = default; StreamingInitializationInfo::AudioStreamInfo::~AudioStreamInfo() = default; @@ -62,32 +48,18 @@ StreamingInitializationInfo::VideoStreamInfo::VideoStreamInfo( media::VideoDecoderConfig video_config, openscreen::cast::Receiver* cast_receiver) - : VideoStreamInfo(std::move(video_config), - cast_receiver, - base::RepeatingClosure(), - base::OnceClosure()) {} + : VideoStreamInfo(std::move(video_config), cast_receiver, nullptr) {} StreamingInitializationInfo::VideoStreamInfo::VideoStreamInfo( media::VideoDecoderConfig video_config, openscreen::cast::Receiver* cast_receiver, - base::RepeatingClosure on_no_buffers_cb, - base::OnceClosure on_error_cb) + base::WeakPtr<DemuxerStreamClient> ds_client) : config(std::move(video_config)), receiver(cast_receiver), - on_no_buffers_callback(std::move(on_no_buffers_cb)), - on_error_callback(std::move(on_error_cb)) {} + demuxer_stream_client(std::move(ds_client)) {} StreamingInitializationInfo::VideoStreamInfo::VideoStreamInfo( - const StreamingInitializationInfo::VideoStreamInfo& other) { - auto& old = const_cast<VideoStreamInfo&>(other); - auto cb_pair = base::SplitOnceCallback(std::move(old.on_error_callback)); - old.on_error_callback = std::move(cb_pair.first); - - config = other.config; - receiver = other.receiver; - on_no_buffers_callback = other.on_no_buffers_callback; - on_error_callback = std::move(cb_pair.second); -} + const StreamingInitializationInfo::VideoStreamInfo& other) = default; StreamingInitializationInfo::VideoStreamInfo::~VideoStreamInfo() = default;
diff --git a/components/cast_streaming/browser/streaming_initialization_info.h b/components/cast_streaming/browser/streaming_initialization_info.h index 188f2faf..2fd89a7e 100644 --- a/components/cast_streaming/browser/streaming_initialization_info.h +++ b/components/cast_streaming/browser/streaming_initialization_info.h
@@ -5,8 +5,8 @@ #ifndef COMPONENTS_CAST_STREAMING_BROWSER_STREAMING_INITIALIZATION_INFO_H_ #define COMPONENTS_CAST_STREAMING_BROWSER_STREAMING_INITIALIZATION_INFO_H_ -#include "base/callback.h" -#include "base/callback_forward.h" +#include "base/memory/weak_ptr.h" +#include "components/cast_streaming/browser/demuxer_stream_client.h" #include "media/base/audio_decoder_config.h" #include "media/base/video_decoder_config.h" #include "third_party/abseil-cpp/absl/types/optional.h" @@ -27,8 +27,7 @@ openscreen::cast::Receiver* cast_receiver); AudioStreamInfo(media::AudioDecoderConfig audio_config, openscreen::cast::Receiver* cast_receiver, - base::RepeatingClosure on_no_buffers_cb, - base::OnceClosure on_error_cb); + base::WeakPtr<DemuxerStreamClient> ds_client); AudioStreamInfo(); AudioStreamInfo(const AudioStreamInfo& other); ~AudioStreamInfo(); @@ -40,11 +39,9 @@ // duration of the streaming session. openscreen::cast::Receiver* receiver; - // Callback to be called when no buffers are available for reading. - base::RepeatingClosure on_no_buffers_callback; - - // Callback to be called when a non-recoverable error occurs. - base::OnceClosure on_error_callback; + // Client with methods to be called when the DemuxerStream requires an + // action be executed. + base::WeakPtr<DemuxerStreamClient> demuxer_stream_client; }; struct VideoStreamInfo { @@ -52,8 +49,7 @@ openscreen::cast::Receiver* cast_receiver); VideoStreamInfo(media::VideoDecoderConfig video_config, openscreen::cast::Receiver* cast_receiver, - base::RepeatingClosure on_no_buffers_cb, - base::OnceClosure on_error_cb); + base::WeakPtr<DemuxerStreamClient> ds_client); VideoStreamInfo(); VideoStreamInfo(const VideoStreamInfo& other); ~VideoStreamInfo(); @@ -65,11 +61,9 @@ // duration of the streaming session. openscreen::cast::Receiver* receiver; - // Callback to be called when no buffers are available for reading. - base::RepeatingClosure on_no_buffers_callback; - - // Callback to be called when a non-recoverable error occurs. - base::OnceClosure on_error_callback; + // Client with methods to be called when the DemuxerStream requires an + // action be executed. + base::WeakPtr<DemuxerStreamClient> demuxer_stream_client; }; StreamingInitializationInfo(
diff --git a/components/cast_streaming/public/mojom/demuxer_connector.mojom b/components/cast_streaming/public/mojom/demuxer_connector.mojom index d7c8ae0a..00ef810 100644 --- a/components/cast_streaming/public/mojom/demuxer_connector.mojom +++ b/components/cast_streaming/public/mojom/demuxer_connector.mojom
@@ -47,6 +47,10 @@ // returns. GetBuffer() => (AudioStreamInfo? stream_info, media.mojom.DecoderBuffer buffer); + + // Requests that the data source providing audio buffers enable its bitstream + // converter. Returns whether the operation was successful. + EnableBitstreamConverter() => (bool success); }; // Provides a "pull" mechanism to request DecoderBuffer frames of video data. @@ -56,6 +60,9 @@ // As AudioBufferRequester::GetBuffer() above. GetBuffer() => (VideoStreamInfo? stream_info, media.mojom.DecoderBuffer buffer); + + // As AudioBufferRequester::EnableBitstreamConverter() above. + EnableBitstreamConverter() => (bool success); }; // Initialization information for an audio DemuxerStream.
diff --git a/components/cast_streaming/public/remoting_message_factories.cc b/components/cast_streaming/public/remoting_message_factories.cc index da597e17..2dcb3a0 100644 --- a/components/cast_streaming/public/remoting_message_factories.cc +++ b/components/cast_streaming/public/remoting_message_factories.cc
@@ -150,6 +150,13 @@ } std::unique_ptr<openscreen::cast::RpcMessage> +CreateMessageForDemuxerStreamEnableBitstreamConverter() { + auto rpc = std::make_unique<openscreen::cast::RpcMessage>(); + rpc->set_proc(openscreen::cast::RpcMessage::RPC_DS_ENABLEBITSTREAMCONVERTER); + return rpc; +} + +std::unique_ptr<openscreen::cast::RpcMessage> CreateMessageForDemuxerStreamError() { auto rpc = std::make_unique<openscreen::cast::RpcMessage>(); rpc->set_proc(openscreen::cast::RpcMessage::RPC_DS_ONERROR);
diff --git a/components/cast_streaming/public/remoting_message_factories.h b/components/cast_streaming/public/remoting_message_factories.h index 980de9fa..9d00b066 100644 --- a/components/cast_streaming/public/remoting_message_factories.h +++ b/components/cast_streaming/public/remoting_message_factories.h
@@ -80,6 +80,9 @@ uint32_t buffers_requested); std::unique_ptr<openscreen::cast::RpcMessage> +CreateMessageForDemuxerStreamEnableBitstreamConverter(); + +std::unique_ptr<openscreen::cast::RpcMessage> CreateMessageForDemuxerStreamError(); } // namespace remoting
diff --git a/components/cast_streaming/public/remoting_message_factories_unittest.cc b/components/cast_streaming/public/remoting_message_factories_unittest.cc index 59b18a1..17c825a9 100644 --- a/components/cast_streaming/public/remoting_message_factories_unittest.cc +++ b/components/cast_streaming/public/remoting_message_factories_unittest.cc
@@ -208,6 +208,13 @@ EXPECT_EQ(message.callback_handle(), kTestHandle); } +TEST_F(RemotingMessageFactoriesTest, + CreateMessageForDemuxerStreamEnableBitstreamConverter) { + const auto rpc = CreateMessageForDemuxerStreamEnableBitstreamConverter(); + EXPECT_EQ(rpc->proc(), + openscreen::cast::RpcMessage::RPC_DS_ENABLEBITSTREAMCONVERTER); +} + TEST_F(RemotingMessageFactoriesTest, CreateMessageForDemuxerStreamError) { const auto rpc = CreateMessageForDemuxerStreamError(); EXPECT_EQ(rpc->proc(), openscreen::cast::RpcMessage::RPC_DS_ONERROR);
diff --git a/components/cast_streaming/renderer/cast_streaming_demuxer.cc b/components/cast_streaming/renderer/cast_streaming_demuxer.cc index 50e2610d..2016431 100644 --- a/components/cast_streaming/renderer/cast_streaming_demuxer.cc +++ b/components/cast_streaming/renderer/cast_streaming_demuxer.cc
@@ -182,6 +182,8 @@ } } + void OnBitstreamConverterEnabled(bool success) { NOTIMPLEMENTED_LOG_ONCE(); } + // DemuxerStream partial implementation. void Read(ReadCB read_cb) final { DVLOG(3) << __func__; @@ -212,6 +214,12 @@ buffer_reader_->ReadBufferAsync(); } + void EnableBitstreamConverter() final { + remote_->EnableBitstreamConverter( + base::BindOnce(&CastStreamingDemuxerStream::OnBitstreamConverterEnabled, + weak_factory_.GetWeakPtr())); + } + media::StreamLiveness liveness() const final { return media::StreamLiveness::kLive; }
diff --git a/components/history_clusters/core/BUILD.gn b/components/history_clusters/core/BUILD.gn index 45d448f..45d7b6a 100644 --- a/components/history_clusters/core/BUILD.gn +++ b/components/history_clusters/core/BUILD.gn
@@ -9,6 +9,7 @@ static_library("core") { sources = [ "cluster_finalizer.h", + "cluster_metrics_utils.cc", "cluster_metrics_utils.h", "cluster_processor.h", "clusterer.cc",
diff --git a/components/history_clusters/core/cluster_metrics_utils.cc b/components/history_clusters/core/cluster_metrics_utils.cc new file mode 100644 index 0000000..3ce089bf --- /dev/null +++ b/components/history_clusters/core/cluster_metrics_utils.cc
@@ -0,0 +1,59 @@ +// 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 "components/history_clusters/core/cluster_metrics_utils.h" + +#include "base/notreached.h" + +namespace history_clusters { + +std::string ClusterActionToString(ClusterAction action) { + switch (action) { + case ClusterAction::kDeleted: + return "Deleted"; + case ClusterAction::kOpenedInTabGroup: + return "OpenedInTabGroup"; + case ClusterAction::kRelatedSearchClicked: + return "RelatedSearchClicked"; + case ClusterAction::kRelatedVisitsVisibilityToggled: + return "RelatedVisitsVisibilityToggled"; + case ClusterAction::kVisitClicked: + return "VisitClicked"; + } + NOTREACHED(); + return std::string(); +} + +std::string VisitActionToString(VisitAction action) { + switch (action) { + case VisitAction::kDeleted: + return "Deleted"; + case VisitAction::kClicked: + return "Clicked"; + } + NOTREACHED(); + return std::string(); +} + +std::string VisitTypeToString(VisitType action) { + switch (action) { + case VisitType::kSRP: + return "SRP"; + case VisitType::kNonSRP: + return "nonSRP"; + } + NOTREACHED(); + return std::string(); +} + +std::string RelatedSearchActionToString(RelatedSearchAction action) { + switch (action) { + case RelatedSearchAction::kClicked: + return "Clicked"; + } + NOTREACHED(); + return std::string(); +} + +} // namespace history_clusters
diff --git a/components/history_clusters/core/cluster_metrics_utils.h b/components/history_clusters/core/cluster_metrics_utils.h index 9cb2e94..e9a5f1a 100644 --- a/components/history_clusters/core/cluster_metrics_utils.h +++ b/components/history_clusters/core/cluster_metrics_utils.h
@@ -35,6 +35,45 @@ const std::string filtered_reason_; }; +/** + * The following enums must be kept in sync with their respective variants in + * //tools/metrics/histograms/metadata/history/histograms.xml and + * //ui/webui/resources/cr_components/history_clusters/history_clusters.mojom + */ + +// Actions that can be performed on clusters. +enum class ClusterAction { + kDeleted = 0, + kOpenedInTabGroup = 1, + kRelatedSearchClicked = 2, + kRelatedVisitsVisibilityToggled = 3, + kVisitClicked = 4, +}; + +// Actions that can be performed on related search items. +enum class RelatedSearchAction { + kClicked = 0, +}; + +// Actions that can be performed on visits. +enum class VisitAction { + kClicked = 0, + kDeleted = 1, +}; + +// Types of visits that can be shown and acted on. +enum class VisitType { + kSRP = 0, + kNonSRP = 1, +}; + +// Returns the string representation of each enum class used for +// logging/histograms. +std::string ClusterActionToString(ClusterAction action); +std::string VisitActionToString(VisitAction action); +std::string VisitTypeToString(VisitType action); +std::string RelatedSearchActionToString(RelatedSearchAction action); + } // namespace history_clusters #endif // COMPONENTS_HISTORY_CLUSTERS_CORE_CLUSTER_METRICS_UTILS_H_
diff --git a/components/minidump_uploader/android/java/src/org/chromium/components/minidump_uploader/MinidumpUploadJobService.java b/components/minidump_uploader/android/java/src/org/chromium/components/minidump_uploader/MinidumpUploadJobService.java index de4bc33..34eb37d 100644 --- a/components/minidump_uploader/android/java/src/org/chromium/components/minidump_uploader/MinidumpUploadJobService.java +++ b/components/minidump_uploader/android/java/src/org/chromium/components/minidump_uploader/MinidumpUploadJobService.java
@@ -9,9 +9,12 @@ import android.app.job.JobService; import android.content.Context; import android.os.PersistableBundle; +import android.os.SystemClock; +import android.text.format.DateUtils; import org.chromium.base.ContextUtils; import org.chromium.base.Log; +import org.chromium.base.metrics.RecordHistogram; import org.chromium.build.BuildConfig; /** @@ -85,6 +88,8 @@ private MinidumpUploadJob.UploadsFinishedCallback createJobFinishedCallback( final JobParameters params) { return new MinidumpUploadJob.UploadsFinishedCallback() { + private final long mTaskStartTimeMs = SystemClock.uptimeMillis(); + @Override public void uploadsFinished(boolean reschedule) { if (reschedule) { @@ -96,6 +101,10 @@ } } MinidumpUploadJobService.this.jobFinished(params, reschedule); + long taskDurationMs = SystemClock.uptimeMillis() - mTaskStartTimeMs; + RecordHistogram.recordCustomTimesHistogram( + "Stability.Android.MinidumpUploadingTime", taskDurationMs, 1, + DateUtils.DAY_IN_MILLIS, 50); } }; }
diff --git a/components/omnibox/browser/builtin_provider.cc b/components/omnibox/browser/builtin_provider.cc index 9ffe1d29..4510287 100644 --- a/components/omnibox/browser/builtin_provider.cc +++ b/components/omnibox/browser/builtin_provider.cc
@@ -27,7 +27,6 @@ #include "url/url_constants.h" const int BuiltinProvider::kRelevance = 860; -const int BuiltinProvider::kStarterPackRelevance = 1200; BuiltinProvider::BuiltinProvider(AutocompleteProviderClient* client) : AutocompleteProvider(AutocompleteProvider::TYPE_BUILTIN), @@ -201,8 +200,9 @@ } void BuiltinProvider::AddStarterPackMatch(const TemplateURL& template_url) { - AutocompleteMatch match(this, kStarterPackRelevance, false, - AutocompleteMatchType::SEARCH_OTHER_ENGINE); + AutocompleteMatch match( + this, OmniboxFieldTrial::kSiteSearchStarterPackRelevanceScore.Get(), + false, AutocompleteMatchType::SEARCH_OTHER_ENGINE); match.fill_into_edit = template_url.keyword(); match.destination_url = GURL(template_url.url());
diff --git a/components/omnibox/browser/builtin_provider.h b/components/omnibox/browser/builtin_provider.h index ae4540b8..8d06e0f 100644 --- a/components/omnibox/browser/builtin_provider.h +++ b/components/omnibox/browser/builtin_provider.h
@@ -32,7 +32,6 @@ typedef std::vector<std::u16string> Builtins; static const int kRelevance; - static const int kStarterPackRelevance; // Populates `matches_` with matching starter pack keywords such as @history, // and @bookmarks
diff --git a/components/omnibox/browser/omnibox_field_trial.cc b/components/omnibox/browser/omnibox_field_trial.cc index 5eabc98..918d58f 100644 --- a/components/omnibox/browser/omnibox_field_trial.cc +++ b/components/omnibox/browser/omnibox_field_trial.cc
@@ -937,6 +937,11 @@ "PrefixSuggestIgnoreDuplicateVisits", false); +const base::FeatureParam<int> kSiteSearchStarterPackRelevanceScore( + &omnibox::kSiteSearchStarterPack, + "SiteSearchStarterPackRelevanceScore", + 1200); + } // namespace OmniboxFieldTrial std::string OmniboxFieldTrial::internal::GetValueForRuleInContext(
diff --git a/components/omnibox/browser/omnibox_field_trial.h b/components/omnibox/browser/omnibox_field_trial.h index a4633fd3..6f6d5c3 100644 --- a/components/omnibox/browser/omnibox_field_trial.h +++ b/components/omnibox/browser/omnibox_field_trial.h
@@ -561,6 +561,10 @@ // interval smaller than kAutocompleteDuplicateVisitIntervalThreshold. extern const base::FeatureParam<bool> kPrefixSuggestIgnoreDuplicateVisits; +// Specifies the relevance scores for the Site Search Starter Pack ACMatches +// (e.g. @bookmarks, @history) provided by the Builtin Provider. +extern const base::FeatureParam<int> kSiteSearchStarterPackRelevanceScore; + // New params should be inserted above this comment and formatted as: // - Short comment categorizing the relevant features & params. // - Optional: `bool Is[FeatureName]Enabled();` helpers that check if the
diff --git a/components/performance_manager/performance_manager.cc b/components/performance_manager/performance_manager.cc index a8f30d7..802410e 100644 --- a/components/performance_manager/performance_manager.cc +++ b/components/performance_manager/performance_manager.cc
@@ -95,8 +95,8 @@ auto* frame_node = helper->GetFrameNode(rfh); if (!frame_node) { // This should only happen if GetFrameNodeForRenderFrameHost is called - // before the RenderFrameCreate notification is dispatched. - DCHECK(!rfh->IsRenderFrameCreated()); + // before the RenderFrameCreated notification is dispatched. + DCHECK(!rfh->IsRenderFrameLive()); return nullptr; } return frame_node->GetWeakPtrOnUIThread();
diff --git a/components/performance_manager/performance_manager_browsertest.cc b/components/performance_manager/performance_manager_browsertest.cc index 39e742a..31feecd 100644 --- a/components/performance_manager/performance_manager_browsertest.cc +++ b/components/performance_manager/performance_manager_browsertest.cc
@@ -44,7 +44,7 @@ ASSERT_EQ(contents, old_contents); ASSERT_EQ(contents->GetLastCommittedURL().possibly_invalid_spec(), kUrl); content::RenderFrameHost* rfh = contents->GetMainFrame(); - ASSERT_TRUE(rfh->IsRenderFrameCreated()); + ASSERT_TRUE(rfh->IsRenderFrameLive()); base::WeakPtr<FrameNode> frame_node = PerformanceManager::GetFrameNodeForRenderFrameHost(rfh);
diff --git a/components/performance_manager/performance_manager_tab_helper.cc b/components/performance_manager/performance_manager_tab_helper.cc index bf5d7db..a8ab8dc 100644 --- a/components/performance_manager/performance_manager_tab_helper.cc +++ b/components/performance_manager/performance_manager_tab_helper.cc
@@ -86,7 +86,7 @@ // We have an early WebContents creation hook so should see it when there is // only a single frame, and it is not yet created. We sanity check that here. #if DCHECK_IS_ON() - DCHECK(!web_contents->GetMainFrame()->IsRenderFrameCreated()); + DCHECK(!web_contents->GetMainFrame()->IsRenderFrameLive()); size_t frame_count = 0; web_contents->ForEachRenderFrameHost(base::BindRepeating( [](size_t* frame_count, content::RenderFrameHost* render_frame_host) { @@ -268,7 +268,7 @@ if (it != frames_.end()) { new_frame = it->second.get(); } else { - DCHECK(!new_host->IsRenderFrameCreated()) + DCHECK(!new_host->IsRenderFrameLive()) << "There shouldn't be a case where RenderFrameHostChanged is " "dispatched before RenderFrameCreated with a live RenderFrame\n"; }
diff --git a/components/remote_cocoa/app_shim/native_widget_ns_window_bridge.h b/components/remote_cocoa/app_shim/native_widget_ns_window_bridge.h index d6bc556..b627ac5 100644 --- a/components/remote_cocoa/app_shim/native_widget_ns_window_bridge.h +++ b/components/remote_cocoa/app_shim/native_widget_ns_window_bridge.h
@@ -122,7 +122,6 @@ // Sets the cursor associated with the NSWindow. Retains |cursor|. void SetCursor(NSCursor* cursor); - void SetCursor(const ui::Cursor& cursor); // Called internally by the NSWindowDelegate when the window is closing. void OnWindowWillClose(); @@ -275,6 +274,7 @@ const mojom::WindowControlsOverlayNSViewType overlay_type) override; void RemoveWindowControlsOverlayNSView( const mojom::WindowControlsOverlayNSViewType overlay_type) override; + void SetCursor(const ui::Cursor& cursor) override; // Return true if [NSApp updateWindows] needs to be called after updating the // TextInputClient.
diff --git a/components/remote_cocoa/common/BUILD.gn b/components/remote_cocoa/common/BUILD.gn index 5005f8e..6a35864a 100644 --- a/components/remote_cocoa/common/BUILD.gn +++ b/components/remote_cocoa/common/BUILD.gn
@@ -21,6 +21,7 @@ "//mojo/public/mojom/base", "//services/network/public/mojom", "//ui/base/accelerators/mojom", + "//ui/base/cursor/mojom", "//ui/base/mojom", "//ui/display/mojom", "//ui/events/mojom",
diff --git a/components/remote_cocoa/common/native_widget_ns_window.mojom b/components/remote_cocoa/common/native_widget_ns_window.mojom index 9c103653..98292d6 100644 --- a/components/remote_cocoa/common/native_widget_ns_window.mojom +++ b/components/remote_cocoa/common/native_widget_ns_window.mojom
@@ -7,6 +7,7 @@ import "components/remote_cocoa/common/select_file_dialog.mojom"; import "mojo/public/mojom/base/string16.mojom"; import "services/network/public/mojom/network_param.mojom"; +import "ui/base/cursor/mojom/cursor.mojom"; import "ui/base/mojom/ui_base_types.mojom"; import "ui/events/mojom/event_constants.mojom"; import "ui/gfx/geometry/mojom/geometry.mojom"; @@ -250,4 +251,7 @@ // overlay display override for a |overlay_type|. RemoveWindowControlsOverlayNSView( WindowControlsOverlayNSViewType overlay_type); + + // Set the cursor type to display. + SetCursor(ui.mojom.Cursor cursor); };
diff --git a/components/safe_browsing/content/browser/threat_details.cc b/components/safe_browsing/content/browser/threat_details.cc index 7da4823..7b1bfd0e 100644 --- a/components/safe_browsing/content/browser/threat_details.cc +++ b/components/safe_browsing/content/browser/threat_details.cc
@@ -645,7 +645,7 @@ frame, back_forward_cache::DisabledReason( back_forward_cache::DisabledReasonId::kSafeBrowsingThreatDetails)); - if (!frame->IsRenderFrameCreated()) { + if (!frame->IsRenderFrameLive()) { // A child frame may have been created browser-side but has not completed // setting up the renderer for it yet. In particular, this occurs if the // child frame was blocked and that's why we're showing a safe browsing page
diff --git a/components/search_engines/default_search_policy_handler.cc b/components/search_engines/default_search_policy_handler.cc index 8c3dd4b..77afa2b4 100644 --- a/components/search_engines/default_search_policy_handler.cc +++ b/components/search_engines/default_search_policy_handler.cc
@@ -197,6 +197,7 @@ dict->SetString(DefaultSearchManager::kID, base::NumberToString(kInvalidTemplateURLID)); dict->SetInteger(DefaultSearchManager::kPrepopulateID, 0); + dict->SetInteger(DefaultSearchManager::kStarterPackId, 0); dict->SetString(DefaultSearchManager::kSyncGUID, std::string()); dict->SetString(DefaultSearchManager::kOriginatingURL, std::string()); dict->SetBoolean(DefaultSearchManager::kSafeForAutoReplace, true);
diff --git a/components/search_engines/template_url_data_util.cc b/components/search_engines/template_url_data_util.cc index 39cded9..f1c98f6 100644 --- a/components/search_engines/template_url_data_util.cc +++ b/components/search_engines/template_url_data_util.cc
@@ -54,6 +54,9 @@ result->SetShortName(base::UTF8ToUTF16(*short_name)); result->prepopulate_id = dict.FindIntKey(DefaultSearchManager::kPrepopulateID) .value_or(result->prepopulate_id); + result->starter_pack_id = + dict.FindIntKey(DefaultSearchManager::kStarterPackId) + .value_or(result->starter_pack_id); string_value = dict.FindStringKey(DefaultSearchManager::kSyncGUID); if (string_value) { result->sync_guid = *string_value; @@ -197,6 +200,8 @@ url_dict->SetStringKey(DefaultSearchManager::kKeyword, data.keyword()); url_dict->SetIntKey(DefaultSearchManager::kPrepopulateID, data.prepopulate_id); + url_dict->SetIntKey(DefaultSearchManager::kStarterPackId, + data.starter_pack_id); url_dict->SetStringKey(DefaultSearchManager::kSyncGUID, data.sync_guid); url_dict->SetStringKey(DefaultSearchManager::kURL, data.url());
diff --git a/components/segmentation_platform/content/BUILD.gn b/components/segmentation_platform/content/BUILD.gn new file mode 100644 index 0000000..40bbe13c --- /dev/null +++ b/components/segmentation_platform/content/BUILD.gn
@@ -0,0 +1,61 @@ +# 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. + +if (is_android) { + import("//build/config/android/config.gni") + import("//build/config/android/rules.gni") +} + +source_set("content") { + sources = [ + "page_load_trigger_context.cc", + "page_load_trigger_context.h", + ] + + deps = [ + "//base", + "//components/segmentation_platform/public", + "//content/public/browser", + ] + + if (is_android) { + deps += [ ":jni_headers" ] + } +} + +source_set("unit_tests") { + testonly = true + + # IMPORTANT NOTE: When adding new tests, also remember to update the list of + # tests in //components/segmentation_platform/components_unittests.filter + sources = [] + + deps = [ + ":content", + "//testing/gtest", + ] +} + +if (is_android) { + android_library("content_java") { + visibility = [ "*" ] + sources = [ "android/java/src/org/chromium/components/segmentation_platform/PageLoadTriggerContext.java" ] + + deps = [ + "//base:base_java", + "//base:jni_java", + "//build/android:build_java", + "//components/segmentation_platform/public:public_java", + "//content/public/android:content_java", + "//ui/android:ui_no_recycler_view_java", + ] + annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ] + } + + generate_jni("jni_headers") { + visibility = [ ":*" ] + + sources = [ "android/java/src/org/chromium/components/segmentation_platform/PageLoadTriggerContext.java" ] + } +}
diff --git a/components/segmentation_platform/content/DEPS b/components/segmentation_platform/content/DEPS new file mode 100644 index 0000000..4bea8d18 --- /dev/null +++ b/components/segmentation_platform/content/DEPS
@@ -0,0 +1,4 @@ +include_rules = [ + "+content/public/android/java/src/org/chromium/content_public/browser/WebContents.java", + "+content/public/browser", +]
diff --git a/components/segmentation_platform/content/android/java/src/org/chromium/components/segmentation_platform/PageLoadTriggerContext.java b/components/segmentation_platform/content/android/java/src/org/chromium/components/segmentation_platform/PageLoadTriggerContext.java new file mode 100644 index 0000000..a59e1d8 --- /dev/null +++ b/components/segmentation_platform/content/android/java/src/org/chromium/components/segmentation_platform/PageLoadTriggerContext.java
@@ -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. + +package org.chromium.components.segmentation_platform; + +import org.chromium.base.annotations.CalledByNative; +import org.chromium.content_public.browser.WebContents; + +/** + * Java representation of the native PageLoadTriggerContext. + */ +public class PageLoadTriggerContext extends TriggerContext { + public final WebContents webContents; + + @CalledByNative + private static PageLoadTriggerContext createPageLoadTriggerContext(WebContents webContents) { + return new PageLoadTriggerContext(webContents); + } + + public PageLoadTriggerContext(WebContents webContents) { + this.webContents = webContents; + } +}
diff --git a/components/segmentation_platform/content/page_load_trigger_context.cc b/components/segmentation_platform/content/page_load_trigger_context.cc new file mode 100644 index 0000000..bdfc874e --- /dev/null +++ b/components/segmentation_platform/content/page_load_trigger_context.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 "components/segmentation_platform/content/page_load_trigger_context.h" + +#include "content/public/browser/web_contents.h" + +#if BUILDFLAG(IS_ANDROID) +#include "base/android/jni_android.h" +#include "components/segmentation_platform/content/jni_headers/PageLoadTriggerContext_jni.h" +#endif // BUILDFLAG(IS_ANDROID) + +namespace segmentation_platform { + +PageLoadTriggerContext::PageLoadTriggerContext( + content::WebContents* web_contents) + : web_contents(web_contents) {} + +PageLoadTriggerContext::~PageLoadTriggerContext() = default; + +#if BUILDFLAG(IS_ANDROID) +base::android::ScopedJavaLocalRef<jobject> +PageLoadTriggerContext::CreateJavaObject() const { + JNIEnv* env = base::android::AttachCurrentThread(); + return Java_PageLoadTriggerContext_createPageLoadTriggerContext( + env, web_contents->GetJavaWebContents()); +} +#endif // BUILDFLAG(IS_ANDROID) + +} // namespace segmentation_platform
diff --git a/components/segmentation_platform/content/page_load_trigger_context.h b/components/segmentation_platform/content/page_load_trigger_context.h new file mode 100644 index 0000000..22d06193 --- /dev/null +++ b/components/segmentation_platform/content/page_load_trigger_context.h
@@ -0,0 +1,36 @@ +// 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 COMPONENTS_SEGMENTATION_PLATFORM_CONTENT_PAGE_LOAD_TRIGGER_CONTEXT_H_ +#define COMPONENTS_SEGMENTATION_PLATFORM_CONTENT_PAGE_LOAD_TRIGGER_CONTEXT_H_ + +#include "base/memory/raw_ptr.h" +#include "components/segmentation_platform/public/trigger_context.h" + +#if BUILDFLAG(IS_ANDROID) +#include "base/android/jni_android.h" +#endif // BUILDFLAG(IS_ANDROID) + +namespace content { +class WebContents; +} // namespace content + +namespace segmentation_platform { + +// Contains contextual information for a page load trigger event. +struct PageLoadTriggerContext : public TriggerContext { + public: + explicit PageLoadTriggerContext(content::WebContents* web_contents); + ~PageLoadTriggerContext() override; + +#if BUILDFLAG(IS_ANDROID) + base::android::ScopedJavaLocalRef<jobject> CreateJavaObject() const override; +#endif // BUILDFLAG(IS_ANDROID) + + raw_ptr<content::WebContents> web_contents; +}; + +} // namespace segmentation_platform + +#endif // COMPONENTS_SEGMENTATION_PLATFORM_CONTENT_PAGE_LOAD_TRIGGER_CONTEXT_H_
diff --git a/components/segmentation_platform/internal/BUILD.gn b/components/segmentation_platform/internal/BUILD.gn index 83d0f94..ad776c33 100644 --- a/components/segmentation_platform/internal/BUILD.gn +++ b/components/segmentation_platform/internal/BUILD.gn
@@ -99,6 +99,8 @@ "scheduler/model_execution_scheduler.h", "scheduler/model_execution_scheduler_impl.cc", "scheduler/model_execution_scheduler_impl.h", + "segment_id_convertor.cc", + "segment_id_convertor.h", "segmentation_platform_service_impl.cc", "segmentation_platform_service_impl.h", "segmentation_ukm_helper.cc", @@ -158,8 +160,13 @@ "//url:url", ] + public_deps = + [ "//components/optimization_guide/proto:optimization_guide_proto" ] + if (is_android) { sources += [ + "android/segmentation_platform_conversion_bridge.cc", + "android/segmentation_platform_conversion_bridge.h", "android/segmentation_platform_service_android.cc", "android/segmentation_platform_service_android.h", ] @@ -177,14 +184,11 @@ "execution/optimization_guide/optimization_guide_segmentation_model_provider.h", "execution/optimization_guide/segmentation_model_executor.cc", "execution/optimization_guide/segmentation_model_executor.h", - "segment_id_convertor.cc", - "segment_id_convertor.h", ] deps = [ ":internal", "//base", "//components/optimization_guide/core", - "//components/optimization_guide/proto:optimization_guide_proto", "//components/segmentation_platform/internal/proto", "//components/segmentation_platform/public", ] @@ -268,7 +272,6 @@ "//components/leveldb_proto:test_support", "//components/optimization_guide/core", "//components/optimization_guide/core:test_support", - "//components/optimization_guide/proto:optimization_guide_proto", "//components/prefs", "//components/prefs:test_support", "//components/segmentation_platform/internal/proto", @@ -322,7 +325,10 @@ if (is_android) { android_library("internal_java") { visibility = [ "//chrome/android:chrome_all_java" ] - sources = [ "android/java/src/org/chromium/components/segmentation_platform/SegmentationPlatformServiceImpl.java" ] + sources = [ + "android/java/src/org/chromium/components/segmentation_platform/SegmentationPlatformConversionBridge.java", + "android/java/src/org/chromium/components/segmentation_platform/SegmentationPlatformServiceImpl.java", + ] deps = [ "//base:base_java", @@ -340,6 +346,9 @@ "//chrome/browser", ] - sources = [ "android/java/src/org/chromium/components/segmentation_platform/SegmentationPlatformServiceImpl.java" ] + sources = [ + "android/java/src/org/chromium/components/segmentation_platform/SegmentationPlatformConversionBridge.java", + "android/java/src/org/chromium/components/segmentation_platform/SegmentationPlatformServiceImpl.java", + ] } }
diff --git a/components/segmentation_platform/internal/android/java/src/org/chromium/components/segmentation_platform/SegmentationPlatformConversionBridge.java b/components/segmentation_platform/internal/android/java/src/org/chromium/components/segmentation_platform/SegmentationPlatformConversionBridge.java new file mode 100644 index 0000000..32e304c --- /dev/null +++ b/components/segmentation_platform/internal/android/java/src/org/chromium/components/segmentation_platform/SegmentationPlatformConversionBridge.java
@@ -0,0 +1,29 @@ +// 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.components.segmentation_platform; + +import org.chromium.base.annotations.CalledByNative; +import org.chromium.base.annotations.JNINamespace; +import org.chromium.components.segmentation_platform.proto.SegmentationProto.SegmentId; + +/** + * Java side of the JNI bridge for various JNI conversions required by the segmentation platform. + */ +@JNINamespace("segmentation_platform") +public class SegmentationPlatformConversionBridge { + @CalledByNative + private static SegmentSelectionResult createSegmentSelectionResult( + boolean isReady, int selectedSegment) { + SegmentId segment = SegmentId.forNumber(selectedSegment); + if (segment == null) segment = SegmentId.OPTIMIZATION_TARGET_UNKNOWN; + return new SegmentSelectionResult(isReady, segment); + } + + @CalledByNative + private static OnDemandSegmentSelectionResult createOnDemandSegmentSelectionResult( + SegmentSelectionResult selectedSegment, TriggerContext triggerContext) { + return new OnDemandSegmentSelectionResult(selectedSegment, triggerContext); + } +}
diff --git a/components/segmentation_platform/internal/android/java/src/org/chromium/components/segmentation_platform/SegmentationPlatformServiceImpl.java b/components/segmentation_platform/internal/android/java/src/org/chromium/components/segmentation_platform/SegmentationPlatformServiceImpl.java index 2737e52a..2b74cfef 100644 --- a/components/segmentation_platform/internal/android/java/src/org/chromium/components/segmentation_platform/SegmentationPlatformServiceImpl.java +++ b/components/segmentation_platform/internal/android/java/src/org/chromium/components/segmentation_platform/SegmentationPlatformServiceImpl.java
@@ -8,7 +8,6 @@ import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; import org.chromium.base.annotations.NativeMethods; -import org.chromium.components.segmentation_platform.proto.SegmentationProto.SegmentId; /** * Java side of the JNI bridge between SegmentationPlatformServiceImpl in Java @@ -40,17 +39,22 @@ mNativePtr, this, segmentationKey); } - @CalledByNative - private void clearNativePtr() { - mNativePtr = 0; + @Override + public int registerOnDemandSegmentSelectionCallback( + String segmentationKey, Callback<OnDemandSegmentSelectionResult> callback) { + return SegmentationPlatformServiceImplJni.get().registerOnDemandSegmentSelectionCallback( + mNativePtr, this, segmentationKey, callback); + } + + @Override + public void unregisterOnDemandSegmentSelectionCallback(String segmentationKey, int callbackId) { + SegmentationPlatformServiceImplJni.get().unregisterOnDemandSegmentSelectionCallback( + mNativePtr, this, segmentationKey, callbackId); } @CalledByNative - private static SegmentSelectionResult createSegmentSelectionResult( - boolean isReady, int selectedSegment) { - SegmentId segment = SegmentId.forNumber(selectedSegment); - if (segment == null) segment = SegmentId.OPTIMIZATION_TARGET_UNKNOWN; - return new SegmentSelectionResult(isReady, segment); + private void clearNativePtr() { + mNativePtr = 0; } @NativeMethods @@ -60,5 +64,11 @@ Callback<SegmentSelectionResult> callback); SegmentSelectionResult getCachedSegmentResult(long nativeSegmentationPlatformServiceAndroid, SegmentationPlatformServiceImpl caller, String segmentationKey); + int registerOnDemandSegmentSelectionCallback(long nativeSegmentationPlatformServiceAndroid, + SegmentationPlatformServiceImpl caller, String segmentationKey, + Callback<OnDemandSegmentSelectionResult> callback); + void unregisterOnDemandSegmentSelectionCallback( + long nativeSegmentationPlatformServiceAndroid, + SegmentationPlatformServiceImpl caller, String segmentationKey, int callbackId); } }
diff --git a/components/segmentation_platform/internal/android/segmentation_platform_conversion_bridge.cc b/components/segmentation_platform/internal/android/segmentation_platform_conversion_bridge.cc new file mode 100644 index 0000000..029aaa5 --- /dev/null +++ b/components/segmentation_platform/internal/android/segmentation_platform_conversion_bridge.cc
@@ -0,0 +1,36 @@ +// 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 "components/segmentation_platform/internal/android/segmentation_platform_conversion_bridge.h" + +#include "components/segmentation_platform/internal/jni_headers/SegmentationPlatformConversionBridge_jni.h" +#include "components/segmentation_platform/public/segment_selection_result.h" +#include "components/segmentation_platform/public/trigger_context.h" + +namespace segmentation_platform { + +// static +ScopedJavaLocalRef<jobject> +SegmentationPlatformConversionBridge::CreateJavaSegmentSelectionResult( + JNIEnv* env, + const SegmentSelectionResult& result) { + int selected_segment = result.segment.has_value() + ? result.segment.value() + : proto::SegmentId::OPTIMIZATION_TARGET_UNKNOWN; + return Java_SegmentationPlatformConversionBridge_createSegmentSelectionResult( + env, result.is_ready, selected_segment); +} + +// static +ScopedJavaLocalRef<jobject> +SegmentationPlatformConversionBridge::CreateJavaOnDemandSegmentSelectionResult( + JNIEnv* env, + const SegmentSelectionResult& result, + const TriggerContext& trigger_context) { + return Java_SegmentationPlatformConversionBridge_createOnDemandSegmentSelectionResult( + env, CreateJavaSegmentSelectionResult(env, result), + trigger_context.CreateJavaObject()); +} + +} // namespace segmentation_platform
diff --git a/components/segmentation_platform/internal/android/segmentation_platform_conversion_bridge.h b/components/segmentation_platform/internal/android/segmentation_platform_conversion_bridge.h new file mode 100644 index 0000000..fcc653f --- /dev/null +++ b/components/segmentation_platform/internal/android/segmentation_platform_conversion_bridge.h
@@ -0,0 +1,32 @@ +// 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 COMPONENTS_SEGMENTATION_PLATFORM_INTERNAL_ANDROID_SEGMENTATION_PLATFORM_CONVERSION_BRIDGE_H_ +#define COMPONENTS_SEGMENTATION_PLATFORM_INTERNAL_ANDROID_SEGMENTATION_PLATFORM_CONVERSION_BRIDGE_H_ + +#include "base/android/jni_android.h" +#include "base/memory/raw_ptr.h" +#include "components/segmentation_platform/public/segment_selection_result.h" +#include "components/segmentation_platform/public/trigger_context.h" + +using base::android::ScopedJavaLocalRef; + +namespace segmentation_platform { + +// A helper class for creating Java objects required by the segmentation +// platform from their C++ counterparts. +class SegmentationPlatformConversionBridge { + public: + static ScopedJavaLocalRef<jobject> CreateJavaSegmentSelectionResult( + JNIEnv* env, + const SegmentSelectionResult& result); + static ScopedJavaLocalRef<jobject> CreateJavaOnDemandSegmentSelectionResult( + JNIEnv* env, + const SegmentSelectionResult& result, + const TriggerContext& trigger_context); +}; + +} // namespace segmentation_platform + +#endif // COMPONENTS_SEGMENTATION_PLATFORM_INTERNAL_ANDROID_SEGMENTATION_PLATFORM_CONVERSION_BRIDGE_H_
diff --git a/components/segmentation_platform/internal/android/segmentation_platform_service_android.cc b/components/segmentation_platform/internal/android/segmentation_platform_service_android.cc index bad5ce9..24d1cf4 100644 --- a/components/segmentation_platform/internal/android/segmentation_platform_service_android.cc +++ b/components/segmentation_platform/internal/android/segmentation_platform_service_android.cc
@@ -9,9 +9,11 @@ #include "base/android/callback_android.h" #include "base/android/jni_string.h" #include "base/bind.h" +#include "components/segmentation_platform/internal/android/segmentation_platform_conversion_bridge.h" #include "components/segmentation_platform/internal/jni_headers/SegmentationPlatformServiceImpl_jni.h" #include "components/segmentation_platform/public/segment_selection_result.h" #include "components/segmentation_platform/public/segmentation_platform_service.h" +#include "components/segmentation_platform/public/trigger_context.h" using base::android::AttachCurrentThread; @@ -21,21 +23,25 @@ const char kSegmentationPlatformServiceBridgeKey[] = "segmentation_platform_service_bridge"; -ScopedJavaLocalRef<jobject> CreateJavaSegmentSelectionResult( - JNIEnv* env, - const SegmentSelectionResult& result) { - int selected_segment = result.segment.has_value() - ? result.segment.value() - : proto::SegmentId::OPTIMIZATION_TARGET_UNKNOWN; - return Java_SegmentationPlatformServiceImpl_createSegmentSelectionResult( - env, result.is_ready, selected_segment); -} - void RunGetSelectedSegmentCallback(const JavaRef<jobject>& j_callback, const SegmentSelectionResult& result) { JNIEnv* env = AttachCurrentThread(); - RunObjectCallbackAndroid(j_callback, - CreateJavaSegmentSelectionResult(env, result)); + RunObjectCallbackAndroid( + j_callback, + SegmentationPlatformConversionBridge::CreateJavaSegmentSelectionResult( + env, result)); +} + +void RunOnDemandSegmentSelectionCallback( + const JavaRef<jobject>& j_callback, + const SegmentSelectionResult& result, + const TriggerContext& trigger_context) { + JNIEnv* env = AttachCurrentThread(); + ScopedJavaLocalRef<jobject> j_on_demand_result = + SegmentationPlatformConversionBridge:: + CreateJavaOnDemandSegmentSelectionResult(env, result, + trigger_context); + RunObjectCallbackAndroid(j_callback, j_on_demand_result); } } // namespace @@ -89,11 +95,34 @@ JNIEnv* env, const JavaParamRef<jobject>& jcaller, const JavaParamRef<jstring>& j_segmentation_key) { - return CreateJavaSegmentSelectionResult( + return SegmentationPlatformConversionBridge::CreateJavaSegmentSelectionResult( env, segmentation_platform_service_->GetCachedSegmentResult( ConvertJavaStringToUTF8(env, j_segmentation_key))); } +int SegmentationPlatformServiceAndroid:: + RegisterOnDemandSegmentSelectionCallback( + JNIEnv* env, + const JavaParamRef<jobject>& jcaller, + const JavaParamRef<jstring>& j_segmentation_key, + const JavaParamRef<jobject>& jcallback) { + return segmentation_platform_service_ + ->RegisterOnDemandSegmentSelectionCallback( + ConvertJavaStringToUTF8(env, j_segmentation_key), + base::BindRepeating(&RunOnDemandSegmentSelectionCallback, + ScopedJavaGlobalRef<jobject>(jcallback))); +} + +void SegmentationPlatformServiceAndroid:: + UnregisterOnDemandSegmentSelectionCallback( + JNIEnv* env, + const JavaParamRef<jobject>& jcaller, + const JavaParamRef<jstring>& j_segmentation_key, + jint j_callback_id) { + segmentation_platform_service_->UnregisterOnDemandSegmentSelectionCallback( + (int)j_callback_id, ConvertJavaStringToUTF8(env, j_segmentation_key)); +} + ScopedJavaLocalRef<jobject> SegmentationPlatformServiceAndroid::GetJavaObject() { return ScopedJavaLocalRef<jobject>(java_obj_);
diff --git a/components/segmentation_platform/internal/android/segmentation_platform_service_android.h b/components/segmentation_platform/internal/android/segmentation_platform_service_android.h index 86ad117a..7653f54 100644 --- a/components/segmentation_platform/internal/android/segmentation_platform_service_android.h +++ b/components/segmentation_platform/internal/android/segmentation_platform_service_android.h
@@ -35,6 +35,18 @@ const JavaParamRef<jobject>& jcaller, const JavaParamRef<jstring>& j_segmentation_key); + int RegisterOnDemandSegmentSelectionCallback( + JNIEnv* env, + const JavaParamRef<jobject>& jcaller, + const JavaParamRef<jstring>& j_segmentation_key, + const JavaParamRef<jobject>& jcallback); + + void UnregisterOnDemandSegmentSelectionCallback( + JNIEnv* env, + const JavaParamRef<jobject>& jcaller, + const JavaParamRef<jstring>& j_segmentation_key, + jint j_callback_id); + ScopedJavaLocalRef<jobject> GetJavaObject(); private:
diff --git a/components/segmentation_platform/internal/dummy_segmentation_platform_service.cc b/components/segmentation_platform/internal/dummy_segmentation_platform_service.cc index 51579d9..743b52c3 100644 --- a/components/segmentation_platform/internal/dummy_segmentation_platform_service.cc +++ b/components/segmentation_platform/internal/dummy_segmentation_platform_service.cc
@@ -9,6 +9,7 @@ #include "base/threading/sequenced_task_runner_handle.h" #include "components/segmentation_platform/internal/stats.h" #include "components/segmentation_platform/public/segment_selection_result.h" +#include "components/segmentation_platform/public/trigger_context.h" namespace segmentation_platform { @@ -31,6 +32,21 @@ return SegmentSelectionResult(); } +int DummySegmentationPlatformService::RegisterOnDemandSegmentSelectionCallback( + const std::string& segmentation_key, + const OnDemandSegmentSelectionCallback& callback) { + return 0; +} + +void DummySegmentationPlatformService:: + UnregisterOnDemandSegmentSelectionCallback( + int callback_id, + const std::string& segmentation_key) {} + +void DummySegmentationPlatformService::OnTrigger( + TriggerType trigger, + const TriggerContext& trigger_context) {} + void DummySegmentationPlatformService::EnableMetrics( bool signal_collection_allowed) {}
diff --git a/components/segmentation_platform/internal/dummy_segmentation_platform_service.h b/components/segmentation_platform/internal/dummy_segmentation_platform_service.h index b8c2ee65..ac81913 100644 --- a/components/segmentation_platform/internal/dummy_segmentation_platform_service.h +++ b/components/segmentation_platform/internal/dummy_segmentation_platform_service.h
@@ -29,6 +29,14 @@ SegmentSelectionCallback callback) override; SegmentSelectionResult GetCachedSegmentResult( const std::string& segmentation_key) override; + int RegisterOnDemandSegmentSelectionCallback( + const std::string& segmentation_key, + const OnDemandSegmentSelectionCallback& callback) override; + void UnregisterOnDemandSegmentSelectionCallback( + int callback_id, + const std::string& segmentation_key) override; + void OnTrigger(TriggerType trigger, + const TriggerContext& trigger_context) override; void EnableMetrics(bool signal_collection_allowed) override; bool IsPlatformInitialized() override; };
diff --git a/components/segmentation_platform/internal/segmentation_platform_service_impl.cc b/components/segmentation_platform/internal/segmentation_platform_service_impl.cc index 09022c0..bc503964 100644 --- a/components/segmentation_platform/internal/segmentation_platform_service_impl.cc +++ b/components/segmentation_platform/internal/segmentation_platform_service_impl.cc
@@ -29,6 +29,7 @@ #include "components/segmentation_platform/public/config.h" #include "components/segmentation_platform/public/field_trial_register.h" #include "components/segmentation_platform/public/model_provider.h" +#include "components/segmentation_platform/public/trigger_context.h" namespace segmentation_platform { namespace { @@ -135,6 +136,21 @@ return selector->GetCachedSegmentResult(); } +int SegmentationPlatformServiceImpl::RegisterOnDemandSegmentSelectionCallback( + const std::string& segmentation_key, + const OnDemandSegmentSelectionCallback& callback) { + return 0; +} + +void SegmentationPlatformServiceImpl:: + UnregisterOnDemandSegmentSelectionCallback( + int callback_id, + const std::string& segmentation_key) {} + +void SegmentationPlatformServiceImpl::OnTrigger( + TriggerType trigger, + const TriggerContext& trigger_context) {} + void SegmentationPlatformServiceImpl::EnableMetrics( bool signal_collection_allowed) { signal_handler_.EnableMetrics(signal_collection_allowed);
diff --git a/components/segmentation_platform/internal/segmentation_platform_service_impl.h b/components/segmentation_platform/internal/segmentation_platform_service_impl.h index b7aa877..626fce5 100644 --- a/components/segmentation_platform/internal/segmentation_platform_service_impl.h +++ b/components/segmentation_platform/internal/segmentation_platform_service_impl.h
@@ -92,6 +92,14 @@ SegmentSelectionCallback callback) override; SegmentSelectionResult GetCachedSegmentResult( const std::string& segmentation_key) override; + int RegisterOnDemandSegmentSelectionCallback( + const std::string& segmentation_key, + const OnDemandSegmentSelectionCallback& callback) override; + void UnregisterOnDemandSegmentSelectionCallback( + int callback_id, + const std::string& segmentation_key) override; + void OnTrigger(TriggerType trigger, + const TriggerContext& trigger_context) override; void EnableMetrics(bool signal_collection_allowed) override; ServiceProxy* GetServiceProxy() override; bool IsPlatformInitialized() override;
diff --git a/components/segmentation_platform/public/BUILD.gn b/components/segmentation_platform/public/BUILD.gn index d5aa36e..859a5d68 100644 --- a/components/segmentation_platform/public/BUILD.gn +++ b/components/segmentation_platform/public/BUILD.gn
@@ -23,6 +23,9 @@ "segmentation_platform_service.h", "service_proxy.cc", "service_proxy.h", + "trigger.h", + "trigger_context.cc", + "trigger_context.h", ] public_deps = [ "//components/segmentation_platform/public/proto" ] @@ -31,6 +34,10 @@ "//base", "//components/keyed_service/core", ] + + if (is_android) { + deps += [ ":jni_headers" ] + } } source_set("unit_tests") { @@ -49,12 +56,26 @@ if (is_android) { android_library("public_java") { sources = [ + "android/java/src/org/chromium/components/segmentation_platform/OnDemandSegmentSelectionResult.java", "android/java/src/org/chromium/components/segmentation_platform/SegmentSelectionResult.java", "android/java/src/org/chromium/components/segmentation_platform/SegmentationPlatformService.java", + "android/java/src/org/chromium/components/segmentation_platform/TriggerContext.java", ] - deps = [ "//base:base_java" ] + deps = [ + "//base:base_java", + "//base:jni_java", + "//build/android:build_java", + ] + + annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ] public_deps = [ "//components/segmentation_platform/public/proto:segmentation_platform_proto_java" ] } + + generate_jni("jni_headers") { + visibility = [ ":*" ] + + sources = [ "android/java/src/org/chromium/components/segmentation_platform/TriggerContext.java" ] + } }
diff --git a/components/segmentation_platform/public/android/java/src/org/chromium/components/segmentation_platform/OnDemandSegmentSelectionResult.java b/components/segmentation_platform/public/android/java/src/org/chromium/components/segmentation_platform/OnDemandSegmentSelectionResult.java new file mode 100644 index 0000000..3537bb0 --- /dev/null +++ b/components/segmentation_platform/public/android/java/src/org/chromium/components/segmentation_platform/OnDemandSegmentSelectionResult.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.components.segmentation_platform; + +/** + * Convenient wrapper containing results for on-demand segment selection along with the trigger + * context required by the UI layer. + */ +public class OnDemandSegmentSelectionResult { + public final SegmentSelectionResult segmentSelectionResult; + public final TriggerContext triggerContext; + + /** Constructor */ + public OnDemandSegmentSelectionResult( + SegmentSelectionResult segmentSelectionResult, TriggerContext triggerContext) { + this.segmentSelectionResult = segmentSelectionResult; + this.triggerContext = triggerContext; + } +}
diff --git a/components/segmentation_platform/public/android/java/src/org/chromium/components/segmentation_platform/SegmentationPlatformService.java b/components/segmentation_platform/public/android/java/src/org/chromium/components/segmentation_platform/SegmentationPlatformService.java index c300ec6..46f0dd5 100644 --- a/components/segmentation_platform/public/android/java/src/org/chromium/components/segmentation_platform/SegmentationPlatformService.java +++ b/components/segmentation_platform/public/android/java/src/org/chromium/components/segmentation_platform/SegmentationPlatformService.java
@@ -26,4 +26,21 @@ * @return The result of segment selection */ SegmentSelectionResult getCachedSegmentResult(String segmentationKey); -} \ No newline at end of file + + /** + * Called to register a callback to be invoked after a segment selection. Only used for + * on-demand segment selection. + * @param segmentationKey The key to be used to distinguish between different clients. + * @param callback The callback to be invoked after a segment selection is computed. + * @return A callback ID to be used when unregistering. + */ + int registerOnDemandSegmentSelectionCallback( + String segmentationKey, Callback<OnDemandSegmentSelectionResult> callback); + + /** + * Called to unregister a previously registered callback for segment selection result. + * @param segmentationKey The key to be used to distinguish between different clients. + * @param callbackId The associated callback ID obtained when registering. + */ + void unregisterOnDemandSegmentSelectionCallback(String segmentationKey, int callbackId); +}
diff --git a/components/segmentation_platform/public/android/java/src/org/chromium/components/segmentation_platform/TriggerContext.java b/components/segmentation_platform/public/android/java/src/org/chromium/components/segmentation_platform/TriggerContext.java new file mode 100644 index 0000000..1ad07e2 --- /dev/null +++ b/components/segmentation_platform/public/android/java/src/org/chromium/components/segmentation_platform/TriggerContext.java
@@ -0,0 +1,20 @@ +// 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.components.segmentation_platform; + +import org.chromium.base.annotations.CalledByNative; + +/** + * Java representation for the native TriggerContext. Contains contextual information for a trigger + * event. + */ +public class TriggerContext { + @CalledByNative + private static TriggerContext createTriggerContext() { + return new TriggerContext(); + } + + public TriggerContext() {} +}
diff --git a/components/segmentation_platform/public/segmentation_platform_service.h b/components/segmentation_platform/public/segmentation_platform_service.h index 36669f159..38ee2aa 100644 --- a/components/segmentation_platform/public/segmentation_platform_service.h +++ b/components/segmentation_platform/public/segmentation_platform_service.h
@@ -12,6 +12,7 @@ #include "base/supports_user_data.h" #include "build/build_config.h" #include "components/keyed_service/core/keyed_service.h" +#include "components/segmentation_platform/public/trigger.h" #if BUILDFLAG(IS_ANDROID) #include "base/android/jni_android.h" @@ -22,6 +23,7 @@ namespace segmentation_platform { class ServiceProxy; struct SegmentSelectionResult; +struct TriggerContext; // The core class of segmentation platform that integrates all the required // pieces on the client side. @@ -64,6 +66,24 @@ virtual SegmentSelectionResult GetCachedSegmentResult( const std::string& segmentation_key) = 0; + // Called to register a callback that will be invoked on segment selection + // on-demand. Returns a callback ID that can be used for unregister. + using OnDemandSegmentSelectionCallback = + base::RepeatingCallback<void(const SegmentSelectionResult&, + const TriggerContext&)>; + virtual int RegisterOnDemandSegmentSelectionCallback( + const std::string& segmentation_key, + const OnDemandSegmentSelectionCallback& callback) = 0; + + // Called to unregister the callback with the given callback_id. + virtual void UnregisterOnDemandSegmentSelectionCallback( + int callback_id, + const std::string& segmentation_key) = 0; + + // Called when a trigger event happens. + virtual void OnTrigger(TriggerType trigger, + const TriggerContext& trigger_context) = 0; + // Called to enable or disable metrics collection. Must be explicitly called // on startup. virtual void EnableMetrics(bool signal_collection_allowed) = 0;
diff --git a/components/segmentation_platform/public/trigger.h b/components/segmentation_platform/public/trigger.h new file mode 100644 index 0000000..2fdfebb --- /dev/null +++ b/components/segmentation_platform/public/trigger.h
@@ -0,0 +1,19 @@ +// 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 COMPONENTS_SEGMENTATION_PLATFORM_PUBLIC_TRIGGER_H_ +#define COMPONENTS_SEGMENTATION_PLATFORM_PUBLIC_TRIGGER_H_ + +namespace segmentation_platform { + +// Various trigger events that drive on-demand model execution. +enum class TriggerType { + kNone = 0, + kPageLoad = 1, + kMaxValue = kPageLoad, +}; + +} // namespace segmentation_platform + +#endif // COMPONENTS_SEGMENTATION_PLATFORM_PUBLIC_TRIGGER_H_
diff --git a/components/segmentation_platform/public/trigger_context.cc b/components/segmentation_platform/public/trigger_context.cc new file mode 100644 index 0000000..59c9735 --- /dev/null +++ b/components/segmentation_platform/public/trigger_context.cc
@@ -0,0 +1,28 @@ +// 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 "components/segmentation_platform/public/trigger_context.h" + +#include "build/build_config.h" + +#if BUILDFLAG(IS_ANDROID) +#include "base/android/jni_android.h" +#include "components/segmentation_platform/public/jni_headers/TriggerContext_jni.h" +#endif // BUILDFLAG(IS_ANDROID) + +namespace segmentation_platform { + +TriggerContext::TriggerContext() = default; + +TriggerContext::~TriggerContext() = default; + +#if BUILDFLAG(IS_ANDROID) +base::android::ScopedJavaLocalRef<jobject> TriggerContext::CreateJavaObject() + const { + JNIEnv* env = base::android::AttachCurrentThread(); + return Java_TriggerContext_createTriggerContext(env); +} +#endif // BUILDFLAG(IS_ANDROID) + +} // namespace segmentation_platform
diff --git a/components/segmentation_platform/public/trigger_context.h b/components/segmentation_platform/public/trigger_context.h new file mode 100644 index 0000000..c45343b --- /dev/null +++ b/components/segmentation_platform/public/trigger_context.h
@@ -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. + +#ifndef COMPONENTS_SEGMENTATION_PLATFORM_PUBLIC_TRIGGER_CONTEXT_H_ +#define COMPONENTS_SEGMENTATION_PLATFORM_PUBLIC_TRIGGER_CONTEXT_H_ + +#include "base/memory/raw_ptr.h" +#include "build/build_config.h" + +#if BUILDFLAG(IS_ANDROID) +#include "base/android/jni_android.h" +#endif // BUILDFLAG(IS_ANDROID) + +namespace segmentation_platform { + +// Contains contextual information for a trigger event. +struct TriggerContext { + public: + TriggerContext(); + virtual ~TriggerContext(); + +#if BUILDFLAG(IS_ANDROID) + // Returns a Java object representing the TriggerContext. + virtual base::android::ScopedJavaLocalRef<jobject> CreateJavaObject() const; +#endif // BUILDFLAG(IS_ANDROID) +}; + +} // namespace segmentation_platform + +#endif // COMPONENTS_SEGMENTATION_PLATFORM_PUBLIC_TRIGGER_CONTEXT_H_
diff --git a/components/url_rewrite/browser/url_request_rewrite_rules_manager.cc b/components/url_rewrite/browser/url_request_rewrite_rules_manager.cc index 2bd5b1d..fd24292a 100644 --- a/components/url_rewrite/browser/url_request_rewrite_rules_manager.cc +++ b/components/url_rewrite/browser/url_request_rewrite_rules_manager.cc
@@ -101,7 +101,7 @@ void UrlRequestRewriteRulesManager::Updater::MaybeRegisterExistingRenderFrame( content::RenderFrameHost* render_frame_host) { - if (render_frame_host->IsRenderFrameCreated()) { + if (render_frame_host->IsRenderFrameLive()) { // Call RenderFrameCreated() for frames that were created before this // observer started observing this WebContents. RenderFrameCreated(render_frame_host);
diff --git a/content/browser/accessibility/browser_accessibility_android.cc b/content/browser/accessibility/browser_accessibility_android.cc index 29a058e7..5fa2ddb 100644 --- a/content/browser/accessibility/browser_accessibility_android.cc +++ b/content/browser/accessibility/browser_accessibility_android.cc
@@ -481,7 +481,7 @@ // On Android, contenteditable needs to be handled the same as any // other text field. role = ax::mojom::Role::kTextField; - } else if (ui::IsAndroidTextViewCandidate(role) && HasOnlyTextChildren()) { + } else if (IsAndroidTextView()) { // On Android, we want to report some extra nodes as TextViews. For example, // a <div> that only contains text, or a <p> that only contains text. role = ax::mojom::Role::kStaticText; @@ -490,6 +490,10 @@ return ui::AXRoleToAndroidClassName(role, PlatformGetParent() != nullptr); } +bool BrowserAccessibilityAndroid::IsAndroidTextView() const { + return ui::IsAndroidTextViewCandidate(GetRole()) && HasOnlyTextChildren(); +} + bool BrowserAccessibilityAndroid::IsChildOfLeaf() const { BrowserAccessibility* ancestor = InternalGetParent(); @@ -1924,19 +1928,6 @@ auto* manager = static_cast<BrowserAccessibilityManagerAndroid*>(this->manager()); manager->ClearNodeInfoCacheForGivenId(unique_id()); - - // For any nodes that are the children of a leaf, we also want to invalidate - // the cache for the ancestry chain up until the first non-leaf node. - if (IsChildOfLeaf()) { - BrowserAccessibilityAndroid* parent = - static_cast<BrowserAccessibilityAndroid*>(PlatformGetParent()); - - while (parent != nullptr && (parent->IsChildOfLeaf() || parent->IsLeaf())) { - manager->ClearNodeInfoCacheForGivenId(parent->unique_id()); - parent = static_cast<BrowserAccessibilityAndroid*>( - parent->PlatformGetParent()); - } - } } int BrowserAccessibilityAndroid::CountChildrenWithRole(
diff --git a/content/browser/accessibility/browser_accessibility_android.h b/content/browser/accessibility/browser_accessibility_android.h index 3441934..372fc00 100644 --- a/content/browser/accessibility/browser_accessibility_android.h +++ b/content/browser/accessibility/browser_accessibility_android.h
@@ -37,6 +37,7 @@ std::u16string GetLocalizedStringForImageAnnotationStatus( ax::mojom::ImageAnnotationStatus status) const override; + bool IsAndroidTextView() const; bool IsCheckable() const; bool IsChecked() const; bool IsClickable() const override;
diff --git a/content/browser/accessibility/browser_accessibility_manager_android.cc b/content/browser/accessibility/browser_accessibility_manager_android.cc index 7db2cbd..357ee15 100644 --- a/content/browser/accessibility/browser_accessibility_manager_android.cc +++ b/content/browser/accessibility/browser_accessibility_manager_android.cc
@@ -263,6 +263,17 @@ wcax->AnnounceLiveRegionText(text); break; } + case ui::AXEventGenerator::Event::NAME_CHANGED: { + // Clear node from cache whenever the name changes to ensure fresh data. + wcax->ClearNodeInfoCacheForGivenId(android_node->unique_id()); + + // If this is a simple text element, also send an event to the framework. + if (ui::IsText(android_node->GetRole()) || + android_node->IsAndroidTextView()) { + wcax->HandleTextContentChanged(android_node->unique_id()); + } + break; + } case ui::AXEventGenerator::Event::RANGE_VALUE_CHANGED: DCHECK(android_node->GetData().IsRangeValueSupported()); if (android_node->IsSlider()) @@ -336,7 +347,6 @@ case ui::AXEventGenerator::Event::MENU_ITEM_SELECTED: case ui::AXEventGenerator::Event::MULTILINE_STATE_CHANGED: case ui::AXEventGenerator::Event::MULTISELECTABLE_STATE_CHANGED: - case ui::AXEventGenerator::Event::NAME_CHANGED: case ui::AXEventGenerator::Event::OBJECT_ATTRIBUTE_CHANGED: case ui::AXEventGenerator::Event::OTHER_ATTRIBUTE_CHANGED: case ui::AXEventGenerator::Event::PARENT_CHANGED:
diff --git a/content/browser/accessibility/web_contents_accessibility_android.cc b/content/browser/accessibility/web_contents_accessibility_android.cc index 23bc1fa..3cca1fc 100644 --- a/content/browser/accessibility/web_contents_accessibility_android.cc +++ b/content/browser/accessibility/web_contents_accessibility_android.cc
@@ -445,6 +445,16 @@ env, obj, base::android::ConvertUTF16ToJavaString(env, text)); } +void WebContentsAccessibilityAndroid::HandleTextContentChanged( + int32_t unique_id) { + JNIEnv* env = AttachCurrentThread(); + ScopedJavaLocalRef<jobject> obj = java_ref_.get(env); + if (obj.is_null()) + return; + Java_WebContentsAccessibilityImpl_handleTextContentChanged(env, obj, + unique_id); +} + void WebContentsAccessibilityAndroid::HandleTextSelectionChanged( int32_t unique_id) { JNIEnv* env = AttachCurrentThread();
diff --git a/content/browser/accessibility/web_contents_accessibility_android.h b/content/browser/accessibility/web_contents_accessibility_android.h index 905910cf7..47915ce8 100644 --- a/content/browser/accessibility/web_contents_accessibility_android.h +++ b/content/browser/accessibility/web_contents_accessibility_android.h
@@ -385,6 +385,7 @@ void HandleScrolledToAnchor(int32_t unique_id); void HandleDialogModalOpened(int32_t unique_id); void AnnounceLiveRegionText(const std::u16string& text); + void HandleTextContentChanged(int32_t unique_id); void HandleTextSelectionChanged(int32_t unique_id); void HandleEditableTextChanged(int32_t unique_id); void HandleSliderChanged(int32_t unique_id);
diff --git a/content/browser/child_process_launcher_helper_linux.cc b/content/browser/child_process_launcher_helper_linux.cc index b2b29e7..16d838b7 100644 --- a/content/browser/child_process_launcher_helper_linux.cc +++ b/content/browser/child_process_launcher_helper_linux.cc
@@ -73,7 +73,7 @@ bool* is_synchronous_launch, int* launch_result) { *is_synchronous_launch = true; - + Process process; ZygoteHandle zygote_handle = base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kNoZygote) ? nullptr @@ -98,16 +98,20 @@ } #endif - Process process; process.process = base::Process(handle); process.zygote = zygote_handle; - return process; + } else { + process.process = base::LaunchProcess(*command_line(), options); + *launch_result = process.process.IsValid() ? LAUNCH_RESULT_SUCCESS + : LAUNCH_RESULT_FAILURE; } - Process process; - process.process = base::LaunchProcess(*command_line(), options); - *launch_result = process.process.IsValid() ? LAUNCH_RESULT_SUCCESS - : LAUNCH_RESULT_FAILURE; +#if BUILDFLAG(IS_CHROMEOS) + if (GetProcessType() == switches::kRendererProcess) { + process.process.InitializePriority(); + } +#endif + return process; }
diff --git a/content/browser/data_decoder_browsertest.cc b/content/browser/data_decoder_browsertest.cc index c4767ecb..5ba0d868 100644 --- a/content/browser/data_decoder_browsertest.cc +++ b/content/browser/data_decoder_browsertest.cc
@@ -5,6 +5,7 @@ #include <limits> #include "base/base_paths.h" +#include "base/callback_helpers.h" #include "base/files/file_path.h" #include "base/files/file_util.h" #include "base/path_service.h" @@ -253,4 +254,80 @@ EXPECT_LE(overhead_estimate, end_to_end_duration_estimate); } +IN_PROC_BROWSER_TEST_F(DataDecoderBrowserTest, + NoCallbackAfterDestruction_Json) { + base::RunLoop run_loop; + + auto decoder = std::make_unique<data_decoder::DataDecoder>(); + auto* raw_decoder = decoder.get(); + + // Android's in-process parser can complete synchronously, so queue the + // delete task first unlike in the other tests. + base::SequencedTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, + std::move(decoder)); + + bool got_callback = false; + raw_decoder->ParseJson( + "[1, 2, 3]", + base::BindOnce( + [](bool* got_callback, base::ScopedClosureRunner quit_closure_runner, + data_decoder::DataDecoder::ValueOrError result) { + *got_callback = true; + }, + // Pass the quit closure as a ScopedClosureRunner, so that the loop + // is quit if the callback is destroyed un-run or after it runs. + &got_callback, base::ScopedClosureRunner(run_loop.QuitClosure()))); + + run_loop.Run(); + + EXPECT_FALSE(got_callback); +} + +IN_PROC_BROWSER_TEST_F(DataDecoderBrowserTest, NoCallbackAfterDestruction_Xml) { + base::RunLoop run_loop; + + auto decoder = std::make_unique<data_decoder::DataDecoder>(); + bool got_callback = false; + decoder->ParseXml( + "<marquee>hello world</marquee>", + data_decoder::mojom::XmlParser::WhitespaceBehavior::kIgnore, + base::BindOnce( + [](bool* got_callback, base::ScopedClosureRunner quit_closure_runner, + data_decoder::DataDecoder::ValueOrError result) { + *got_callback = true; + }, + // Pass the quit closure as a ScopedClosureRunner, so that the loop + // is quit if the callback is destroyed un-run or after it runs. + &got_callback, base::ScopedClosureRunner(run_loop.QuitClosure()))); + + base::SequencedTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, + std::move(decoder)); + run_loop.Run(); + + EXPECT_FALSE(got_callback); +} + +IN_PROC_BROWSER_TEST_F(DataDecoderBrowserTest, + NoCallbackAfterDestruction_Gzip) { + base::RunLoop run_loop; + + auto decoder = std::make_unique<data_decoder::DataDecoder>(); + bool got_callback = false; + decoder->GzipCompress( + {{0x1, 0x1, 0x1, 0x1, 0x1, 0x1}}, + base::BindOnce( + [](bool* got_callback, base::ScopedClosureRunner quit_closure_runner, + data_decoder::DataDecoder::ResultOrError<mojo_base::BigBuffer> + result) { *got_callback = true; }, + // Pass the quit closure as a ScopedClosureRunner, so that the loop + // is quit if the callback is destroyed un-run or after it runs. + &got_callback, base::ScopedClosureRunner(run_loop.QuitClosure()))); + + base::SequencedTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, + std::move(decoder)); + run_loop.Run(); + + EXPECT_FALSE(got_callback); +} + } // namespace content
diff --git a/content/browser/find_request_manager.cc b/content/browser/find_request_manager.cc index 1c788d9..e9d965a 100644 --- a/content/browser/find_request_manager.cc +++ b/content/browser/find_request_manager.cc
@@ -233,7 +233,7 @@ manager_->RemoveFrame(rfh); // Make sure RenderFrameDeleted will be called to clean up - DCHECK(rfh->IsRenderFrameCreated()); + DCHECK(rfh->IsRenderFrameLive()); if (IsFindInPageDisabled(rfh)) return;
diff --git a/content/browser/interest_group/ad_auction_service_impl.cc b/content/browser/interest_group/ad_auction_service_impl.cc index cc0e6dc8..a3ff007 100644 --- a/content/browser/interest_group/ad_auction_service_impl.cc +++ b/content/browser/interest_group/ad_auction_service_impl.cc
@@ -39,6 +39,7 @@ #include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/blink/public/common/features.h" #include "third_party/blink/public/common/fenced_frame/fenced_frame_utils.h" +#include "third_party/blink/public/common/interest_group/auction_config.h" #include "third_party/blink/public/common/interest_group/interest_group.h" #include "url/gurl.h" #include "url/origin.h" @@ -71,50 +72,6 @@ return true; } -bool IsAuctionValid(const blink::mojom::AuctionAdConfig& config, - bool is_top_level_auction) { - // The seller origin has to be HTTPS. - if (config.seller.scheme() != url::kHttpsScheme) - return false; - - // Opaque Origins have empty schemes. - DCHECK(!config.seller.opaque()); - - // `decision_logic_url` and, if present, `trusted_scoring_signals_url` must - // share the seller's origin. - if (url::SchemeHostPort(config.decision_logic_url) != - config.seller.GetTupleOrPrecursorTupleIfOpaque() || - (config.trusted_scoring_signals_url && - url::SchemeHostPort(*config.trusted_scoring_signals_url) != - config.seller.GetTupleOrPrecursorTupleIfOpaque())) { - return false; - } - - const auto& non_shared_params = config.auction_ad_config_non_shared_params; - // This isn't marked as optional in the Mojo struct, so Mojo should make sure - // it is non-null. - DCHECK(non_shared_params); - - // All interest group owners must be HTTPS. - if (non_shared_params->interest_group_buyers) { - for (const url::Origin& buyer : *non_shared_params->interest_group_buyers) { - if (buyer.scheme() != url::kHttpsScheme) - return false; - } - } - - for (const auto& component_auction : - config.auction_ad_config_non_shared_params->component_auctions) { - // Component auctions may not have their own nested component auctions. - if (!is_top_level_auction) - return false; - if (!IsAuctionValid(*component_auction, /*is_top_level_auction=*/false)) - return false; - } - - return true; -} - } // namespace // static @@ -240,7 +197,7 @@ origin(), GetClientSecurityState()); } -void AdAuctionServiceImpl::RunAdAuction(blink::mojom::AuctionAdConfigPtr config, +void AdAuctionServiceImpl::RunAdAuction(const blink::AuctionConfig& config, RunAdAuctionCallback callback) { // If the run ad auction API is not allowed for this context by Permissions // Policy, do nothing @@ -249,10 +206,6 @@ ReportBadMessageAndDeleteThis("Unexpected request"); return; } - if (!IsAuctionValid(*config, /*is_top_level_auction=*/true)) { - std::move(callback).Run(absl::nullopt); - return; - } auto* auction_result_metrics = AdAuctionResultMetrics::GetOrCreateForPage( render_frame_host()->GetPage()); @@ -356,13 +309,8 @@ } void AdAuctionServiceImpl::FinalizeAd(const std::string& ads_guid, - ::blink::mojom::AuctionAdConfigPtr config, + const blink::AuctionConfig& config, FinalizeAdCallback callback) { - if (!IsAuctionValid(*config, /*is_top_level_auction=*/true)) { - ReportBadMessageAndDeleteThis("Invalid auction"); - return; - } - if (ads_guid.empty()) { ReportBadMessageAndDeleteThis("GUID empty"); return;
diff --git a/content/browser/interest_group/ad_auction_service_impl.h b/content/browser/interest_group/ad_auction_service_impl.h index adfc465..4358a6a 100644 --- a/content/browser/interest_group/ad_auction_service_impl.h +++ b/content/browser/interest_group/ad_auction_service_impl.h
@@ -20,6 +20,7 @@ #include "services/network/public/cpp/wrapper_shared_url_loader_factory.h" #include "services/network/public/mojom/client_security_state.mojom.h" #include "services/network/public/mojom/url_loader_factory.mojom.h" +#include "third_party/blink/public/common/interest_group/auction_config.h" #include "third_party/blink/public/mojom/interest_group/ad_auction_service.mojom.h" #include "third_party/blink/public/mojom/interest_group/interest_group_types.mojom-forward.h" #include "third_party/blink/public/mojom/parakeet/ad_request.mojom.h" @@ -51,7 +52,7 @@ LeaveInterestGroupCallback callback) override; void LeaveInterestGroupForDocument() override; void UpdateAdInterestGroups() override; - void RunAdAuction(blink::mojom::AuctionAdConfigPtr config, + void RunAdAuction(const blink::AuctionConfig& config, RunAdAuctionCallback callback) override; void DeprecatedGetURLFromURN( const GURL& urn_url, @@ -63,7 +64,7 @@ void CreateAdRequest(blink::mojom::AdRequestConfigPtr config, CreateAdRequestCallback callback) override; void FinalizeAd(const std::string& ads_guid, - blink::mojom::AuctionAdConfigPtr config, + const blink::AuctionConfig& config, FinalizeAdCallback callback) override; scoped_refptr<network::WrapperSharedURLLoaderFactory>
diff --git a/content/browser/interest_group/ad_auction_service_impl_unittest.cc b/content/browser/interest_group/ad_auction_service_impl_unittest.cc index 3079fb3..f87601d 100644 --- a/content/browser/interest_group/ad_auction_service_impl_unittest.cc +++ b/content/browser/interest_group/ad_auction_service_impl_unittest.cc
@@ -644,7 +644,7 @@ // frame `rfh`. Returns the result of the auction, which is either a URL to // the winning ad, or absl::nullopt if no ad won the auction. absl::optional<GURL> RunAdAuctionAndFlushForFrame( - blink::mojom::AuctionAdConfigPtr auction_config, + const blink::AuctionConfig& auction_config, RenderFrameHost* rfh) { mojo::Remote<blink::mojom::AdAuctionService> interest_service; AdAuctionServiceImpl::CreateMojoService( @@ -653,7 +653,7 @@ base::RunLoop run_loop; absl::optional<GURL> maybe_url; interest_service->RunAdAuction( - std::move(auction_config), + auction_config, base::BindLambdaForTesting( [&run_loop, &maybe_url](const absl::optional<GURL>& result) { maybe_url = result; @@ -667,8 +667,8 @@ // Like RunAdAuctionAndFlushForFrame(), but uses the render frame host of the // main frame. absl::optional<GURL> RunAdAuctionAndFlush( - blink::mojom::AuctionAdConfigPtr auction_config) { - return RunAdAuctionAndFlushForFrame(std::move(auction_config), main_rfh()); + const blink::AuctionConfig& auction_config) { + return RunAdAuctionAndFlushForFrame(auction_config, main_rfh()); } // Like UpdateInterestGroupNoFlushForFrame, but uses the render frame host of @@ -700,7 +700,7 @@ // Finalizes an ad and expects the Mojo pipe to be closed without invoking the // callback, as should be done in the case of a bad Mojo message. void FinalizeAdAndExpectPipeClosed(const std::string& guid, - blink::mojom::AuctionAdConfigPtr config) { + const blink::AuctionConfig& config) { mojo::Remote<blink::mojom::AdAuctionService> interest_service; AdAuctionServiceImpl::CreateMojoService( main_rfh(), interest_service.BindNewPipeAndPassReceiver()); @@ -708,7 +708,7 @@ base::RunLoop run_loop; interest_service.set_disconnect_handler(run_loop.QuitClosure()); interest_service->FinalizeAd( - guid, std::move(config), + guid, config, base::BindLambdaForTesting( [&](const absl::optional<GURL>& creative_url) { ADD_FAILURE() << "Callback unexpectedly invoked."; @@ -3430,13 +3430,10 @@ JoinInterestGroupAndFlush(interest_group); EXPECT_EQ(1, GetJoinCount(kOriginA, kInterestGroupName)); - auto auction_config = blink::mojom::AuctionAdConfig::New(); - auction_config->seller = kOriginA; - auction_config->decision_logic_url = kUrlA.Resolve(kDecisionUrlPath); - auction_config->auction_ad_config_non_shared_params = - blink::mojom::AuctionAdConfigNonSharedParams::New(); - auction_config->auction_ad_config_non_shared_params->interest_group_buyers = { - kOriginA}; + blink::AuctionConfig auction_config; + auction_config.seller = kOriginA; + auction_config.decision_logic_url = kUrlA.Resolve(kDecisionUrlPath); + auction_config.non_shared_params.interest_group_buyers = {kOriginA}; absl::optional<GURL> auction_result = RunAdAuctionAndFlush(std::move(auction_config)); ASSERT_NE(auction_result, absl::nullopt); @@ -3485,13 +3482,10 @@ JoinInterestGroupAndFlush(interest_group_a); EXPECT_EQ(1, GetJoinCount(kOriginA, kInterestGroupName)); - auto auction_config = blink::mojom::AuctionAdConfig::New(); - auction_config->seller = kOriginA; - auction_config->decision_logic_url = kUrlA.Resolve(kDecisionUrlPath); - auction_config->auction_ad_config_non_shared_params = - blink::mojom::AuctionAdConfigNonSharedParams::New(); - auction_config->auction_ad_config_non_shared_params->interest_group_buyers = { - kOriginA}; + blink::AuctionConfig auction_config; + auction_config.seller = kOriginA; + auction_config.decision_logic_url = kUrlA.Resolve(kDecisionUrlPath); + auction_config.non_shared_params.interest_group_buyers = {kOriginA}; absl::optional<GURL> auction_result = RunAdAuctionAndFlush(std::move(auction_config)); ASSERT_NE(auction_result, absl::nullopt); @@ -3548,13 +3542,10 @@ JoinInterestGroupAndFlush(interest_group_a); EXPECT_EQ(1, GetJoinCount(kOriginA, kInterestGroupName)); - auto auction_config = blink::mojom::AuctionAdConfig::New(); - auction_config->seller = kOriginA; - auction_config->decision_logic_url = kUrlA.Resolve(kDecisionUrlPath); - auction_config->auction_ad_config_non_shared_params = - blink::mojom::AuctionAdConfigNonSharedParams::New(); - auction_config->auction_ad_config_non_shared_params->interest_group_buyers = { - kOriginA}; + blink::AuctionConfig auction_config; + auction_config.seller = kOriginA; + auction_config.decision_logic_url = kUrlA.Resolve(kDecisionUrlPath); + auction_config.non_shared_params.interest_group_buyers = {kOriginA}; absl::optional<GURL> auction_result = RunAdAuctionAndFlush(std::move(auction_config)); EXPECT_EQ(auction_result, absl::nullopt); @@ -3604,13 +3595,10 @@ JoinInterestGroupAndFlush(interest_group_a); EXPECT_EQ(1, GetJoinCount(kOriginA, kInterestGroupName)); - auto auction_config = blink::mojom::AuctionAdConfig::New(); - auction_config->seller = kOriginA; - auction_config->decision_logic_url = kUrlA.Resolve(kMissingScriptPath); - auction_config->auction_ad_config_non_shared_params = - blink::mojom::AuctionAdConfigNonSharedParams::New(); - auction_config->auction_ad_config_non_shared_params->interest_group_buyers = { - kOriginA}; + blink::AuctionConfig auction_config; + auction_config.seller = kOriginA; + auction_config.decision_logic_url = kUrlA.Resolve(kMissingScriptPath); + auction_config.non_shared_params.interest_group_buyers = {kOriginA}; absl::optional<GURL> auction_result = RunAdAuctionAndFlush(std::move(auction_config)); EXPECT_EQ(auction_result, absl::nullopt); @@ -3667,13 +3655,10 @@ JoinInterestGroupAndFlush(interest_group_no_update); EXPECT_EQ(1, GetJoinCount(kOriginNoUpdate, kInterestGroupName)); - auto auction_config = blink::mojom::AuctionAdConfig::New(); - auction_config->seller = kOriginNoUpdate; - auction_config->decision_logic_url = kUrlNoUpdate.Resolve(kDecisionUrlPath); - auction_config->auction_ad_config_non_shared_params = - blink::mojom::AuctionAdConfigNonSharedParams::New(); - auction_config->auction_ad_config_non_shared_params->interest_group_buyers = { - kOriginNoUpdate}; + blink::AuctionConfig auction_config; + auction_config.seller = kOriginNoUpdate; + auction_config.decision_logic_url = kUrlNoUpdate.Resolve(kDecisionUrlPath); + auction_config.non_shared_params.interest_group_buyers = {kOriginNoUpdate}; absl::optional<GURL> auction_result = RunAdAuctionAndFlush(std::move(auction_config)); ASSERT_NE(auction_result, absl::nullopt); @@ -3771,22 +3756,16 @@ EXPECT_EQ(1, GetJoinCount(kOriginC, kInterestGroupName)); NavigateAndCommit(kUrlA); - auto auction_config = blink::mojom::AuctionAdConfig::New(); - auction_config->seller = kOriginA; - auction_config->decision_logic_url = kUrlA.Resolve(kDecisionUrlPath); - auction_config->auction_ad_config_non_shared_params = - blink::mojom::AuctionAdConfigNonSharedParams::New(); - auction_config->auction_ad_config_non_shared_params->interest_group_buyers = { - kOriginA}; - auto component_auction = blink::mojom::AuctionAdConfig::New(); - component_auction->seller = kOriginA; - component_auction->decision_logic_url = kUrlA.Resolve(kDecisionUrlPath); - component_auction->auction_ad_config_non_shared_params = - blink::mojom::AuctionAdConfigNonSharedParams::New(); - component_auction->auction_ad_config_non_shared_params - ->interest_group_buyers = {kOriginC}; - auction_config->auction_ad_config_non_shared_params->component_auctions - .emplace_back(std::move(component_auction)); + blink::AuctionConfig auction_config; + auction_config.seller = kOriginA; + auction_config.decision_logic_url = kUrlA.Resolve(kDecisionUrlPath); + auction_config.non_shared_params.interest_group_buyers = {kOriginA}; + blink::AuctionConfig component_auction; + component_auction.seller = kOriginA; + component_auction.decision_logic_url = kUrlA.Resolve(kDecisionUrlPath); + component_auction.non_shared_params.interest_group_buyers = {kOriginC}; + auction_config.non_shared_params.component_auctions.emplace_back( + std::move(component_auction)); absl::optional<GURL> auction_result = RunAdAuctionAndFlush(std::move(auction_config)); ASSERT_NE(auction_result, absl::nullopt); @@ -3881,22 +3860,16 @@ EXPECT_EQ(1, GetJoinCount(kOriginC, kInterestGroupName)); NavigateAndCommit(kUrlA); - auto auction_config = blink::mojom::AuctionAdConfig::New(); - auction_config->seller = kOriginA; - auction_config->decision_logic_url = kUrlA.Resolve(kDecisionUrlPath); - auction_config->auction_ad_config_non_shared_params = - blink::mojom::AuctionAdConfigNonSharedParams::New(); - auction_config->auction_ad_config_non_shared_params->interest_group_buyers = { - kOriginA}; - auto component_auction = blink::mojom::AuctionAdConfig::New(); - component_auction->seller = kOriginA; - component_auction->decision_logic_url = kUrlA.Resolve(kDecisionUrlPath); - component_auction->auction_ad_config_non_shared_params = - blink::mojom::AuctionAdConfigNonSharedParams::New(); - component_auction->auction_ad_config_non_shared_params - ->interest_group_buyers = {kOriginC}; - auction_config->auction_ad_config_non_shared_params->component_auctions - .emplace_back(std::move(component_auction)); + blink::AuctionConfig auction_config; + auction_config.seller = kOriginA; + auction_config.decision_logic_url = kUrlA.Resolve(kDecisionUrlPath); + auction_config.non_shared_params.interest_group_buyers = {kOriginA}; + blink::AuctionConfig component_auction; + component_auction.seller = kOriginA; + component_auction.decision_logic_url = kUrlA.Resolve(kDecisionUrlPath); + component_auction.non_shared_params.interest_group_buyers = {kOriginC}; + auction_config.non_shared_params.component_auctions.emplace_back( + std::move(component_auction)); absl::optional<GURL> auction_result = RunAdAuctionAndFlush(std::move(auction_config)); ASSERT_NE(auction_result, absl::nullopt); @@ -3993,22 +3966,16 @@ EXPECT_EQ(1, GetJoinCount(kOriginC, kInterestGroupName)); NavigateAndCommit(kUrlA); - auto auction_config = blink::mojom::AuctionAdConfig::New(); - auction_config->seller = kOriginA; - auction_config->decision_logic_url = kUrlA.Resolve(kDecisionUrlPath); - auction_config->auction_ad_config_non_shared_params = - blink::mojom::AuctionAdConfigNonSharedParams::New(); - auction_config->auction_ad_config_non_shared_params->interest_group_buyers = { - kOriginA}; - auto component_auction = blink::mojom::AuctionAdConfig::New(); - component_auction->seller = kOriginA; - component_auction->decision_logic_url = kUrlA.Resolve(kDecisionUrlPath); - component_auction->auction_ad_config_non_shared_params = - blink::mojom::AuctionAdConfigNonSharedParams::New(); - component_auction->auction_ad_config_non_shared_params - ->interest_group_buyers = {kOriginC}; - auction_config->auction_ad_config_non_shared_params->component_auctions - .emplace_back(std::move(component_auction)); + blink::AuctionConfig auction_config; + auction_config.seller = kOriginA; + auction_config.decision_logic_url = kUrlA.Resolve(kDecisionUrlPath); + auction_config.non_shared_params.interest_group_buyers = {kOriginA}; + blink::AuctionConfig component_auction; + component_auction.seller = kOriginA; + component_auction.decision_logic_url = kUrlA.Resolve(kDecisionUrlPath); + component_auction.non_shared_params.interest_group_buyers = {kOriginC}; + auction_config.non_shared_params.component_auctions.emplace_back( + std::move(component_auction)); absl::optional<GURL> auction_result = RunAdAuctionAndFlush(std::move(auction_config)); EXPECT_EQ(auction_result, absl::nullopt); @@ -4085,13 +4052,10 @@ JoinInterestGroupAndFlush(interest_group); EXPECT_EQ(1, GetJoinCount(kOriginA, kInterestGroupName)); - auto auction_config = blink::mojom::AuctionAdConfig::New(); - auction_config->seller = kOriginA; - auction_config->decision_logic_url = kUrlA.Resolve(kDecisionUrlPath); - auction_config->auction_ad_config_non_shared_params = - blink::mojom::AuctionAdConfigNonSharedParams::New(); - auction_config->auction_ad_config_non_shared_params->interest_group_buyers = { - kOriginA}; + blink::AuctionConfig auction_config; + auction_config.seller = kOriginA; + auction_config.decision_logic_url = kUrlA.Resolve(kDecisionUrlPath); + auction_config.non_shared_params.interest_group_buyers = {kOriginA}; absl::optional<GURL> auction_result = RunAdAuctionAndFlush(std::move(auction_config)); EXPECT_NE(auction_result, absl::nullopt); @@ -4171,13 +4135,10 @@ JoinInterestGroupAndFlush(interest_group); EXPECT_EQ(1, GetJoinCount(kOriginA, kInterestGroupName)); - auto auction_config = blink::mojom::AuctionAdConfig::New(); - auction_config->seller = kOriginA; - auction_config->decision_logic_url = kUrlA.Resolve(kDecisionUrlPath); - auction_config->auction_ad_config_non_shared_params = - blink::mojom::AuctionAdConfigNonSharedParams::New(); - auction_config->auction_ad_config_non_shared_params->interest_group_buyers = { - kOriginA}; + blink::AuctionConfig auction_config; + auction_config.seller = kOriginA; + auction_config.decision_logic_url = kUrlA.Resolve(kDecisionUrlPath); + auction_config.non_shared_params.interest_group_buyers = {kOriginA}; absl::optional<GURL> auction_result = RunAdAuctionAndFlush(std::move(auction_config)); EXPECT_NE(auction_result, absl::nullopt); @@ -4259,14 +4220,11 @@ JoinInterestGroupAndFlush(interest_group); EXPECT_EQ(1, GetJoinCount(kOriginA, name)); - auto auction_config = blink::mojom::AuctionAdConfig::New(); - auction_config->seller = kOriginA; + blink::AuctionConfig auction_config; + auction_config.seller = kOriginA; - auction_config->decision_logic_url = kUrlA.Resolve(kDecisionUrlPath); - auction_config->auction_ad_config_non_shared_params = - blink::mojom::AuctionAdConfigNonSharedParams::New(); - auction_config->auction_ad_config_non_shared_params - ->interest_group_buyers = {kOriginA}; + auction_config.decision_logic_url = kUrlA.Resolve(kDecisionUrlPath); + auction_config.non_shared_params.interest_group_buyers = {kOriginA}; absl::optional<GURL> auction_result = RunAdAuctionAndFlush(std::move(auction_config)); EXPECT_NE(auction_result, absl::nullopt); @@ -4343,15 +4301,11 @@ JoinInterestGroupAndFlush(interest_group); EXPECT_EQ(1, GetJoinCount(kOriginA, kInterestGroupName)); - auto auction_config = blink::mojom::AuctionAdConfig::New(); - auction_config->seller = kOriginA; - auction_config->decision_logic_url = kUrlA.Resolve(kDecisionUrlPath); - auction_config->auction_ad_config_non_shared_params = - blink::mojom::AuctionAdConfigNonSharedParams::New(); - auction_config->auction_ad_config_non_shared_params->interest_group_buyers = { - kOriginA}; - absl::optional<GURL> auction_result = - RunAdAuctionAndFlush(std::move(auction_config)); + blink::AuctionConfig auction_config; + auction_config.seller = kOriginA; + auction_config.decision_logic_url = kUrlA.Resolve(kDecisionUrlPath); + auction_config.non_shared_params.interest_group_buyers = {kOriginA}; + absl::optional<GURL> auction_result = RunAdAuctionAndFlush(auction_config); EXPECT_NE(auction_result, absl::nullopt); task_environment()->FastForwardBy(base::Seconds(2)); @@ -4361,14 +4315,11 @@ EXPECT_EQ(manager_->report_queue_length_for_testing(), 1u); // Run a second auction while the first auction's reporting is in progress. - auto auction_config2 = blink::mojom::AuctionAdConfig::New(); - auction_config2->seller = kOriginA; - auction_config2->decision_logic_url = kUrlA.Resolve(kDecisionUrlPath); - auction_config2->auction_ad_config_non_shared_params = - blink::mojom::AuctionAdConfigNonSharedParams::New(); - auction_config2->auction_ad_config_non_shared_params - ->interest_group_buyers = {kOriginA}; - auction_result = RunAdAuctionAndFlush(std::move(auction_config2)); + blink::AuctionConfig auction_config2; + auction_config2.seller = kOriginA; + auction_config2.decision_logic_url = kUrlA.Resolve(kDecisionUrlPath); + auction_config2.non_shared_params.interest_group_buyers = {kOriginA}; + auction_result = RunAdAuctionAndFlush(auction_config2); EXPECT_NE(auction_result, absl::nullopt); // Two more reports are enqueued. EXPECT_EQ(manager_->report_queue_length_for_testing(), 3u); @@ -4382,14 +4333,11 @@ // Run a third auction after report queue is cleared, to make sure further // auction's reports can be normally enqueued and sent again. - auto auction_config3 = blink::mojom::AuctionAdConfig::New(); - auction_config3->seller = kOriginA; - auction_config3->decision_logic_url = kUrlA.Resolve(kDecisionUrlPath); - auction_config3->auction_ad_config_non_shared_params = - blink::mojom::AuctionAdConfigNonSharedParams::New(); - auction_config3->auction_ad_config_non_shared_params - ->interest_group_buyers = {kOriginA}; - auction_result = RunAdAuctionAndFlush(std::move(auction_config3)); + blink::AuctionConfig auction_config3; + auction_config3.seller = kOriginA; + auction_config3.decision_logic_url = kUrlA.Resolve(kDecisionUrlPath); + auction_config3.non_shared_params.interest_group_buyers = {kOriginA}; + auction_result = RunAdAuctionAndFlush(auction_config3); EXPECT_NE(auction_result, absl::nullopt); // Set `max_reporting_round_duration_` high enough so that the auction's two @@ -4460,71 +4408,61 @@ // bucket size is 1 hour, so specifying kMaxTime will select the max bucket. constexpr base::TimeDelta kMaxTime{base::Days(1)}; - auto succeed_auction_config = blink::mojom::AuctionAdConfig::New(); - succeed_auction_config->seller = kOriginA; - succeed_auction_config->decision_logic_url = kUrlA.Resolve(kDecisionUrlPath); - succeed_auction_config->auction_ad_config_non_shared_params = - blink::mojom::AuctionAdConfigNonSharedParams::New(); - succeed_auction_config->auction_ad_config_non_shared_params - ->interest_group_buyers = {kOriginA}; + blink::AuctionConfig succeed_auction_config; + succeed_auction_config.seller = kOriginA; + succeed_auction_config.decision_logic_url = kUrlA.Resolve(kDecisionUrlPath); + succeed_auction_config.non_shared_params.interest_group_buyers = {kOriginA}; - auto fail_auction_config = blink::mojom::AuctionAdConfig::New(); - fail_auction_config->seller = kOriginA; - fail_auction_config->decision_logic_url = + blink::AuctionConfig fail_auction_config; + fail_auction_config.seller = kOriginA; + fail_auction_config.decision_logic_url = kUrlA.Resolve(kDecisionFailAllUrlPath); - fail_auction_config->auction_ad_config_non_shared_params = - blink::mojom::AuctionAdConfigNonSharedParams::New(); - fail_auction_config->auction_ad_config_non_shared_params - ->interest_group_buyers = {kOriginA}; + fail_auction_config.non_shared_params.interest_group_buyers = {kOriginA}; // 1st auction - EXPECT_NE(RunAdAuctionAndFlush(succeed_auction_config->Clone()), - absl::nullopt); + EXPECT_NE(RunAdAuctionAndFlush(succeed_auction_config), absl::nullopt); // Time metrics are published every auction. histogram_tester.ExpectUniqueTimeSample( "Ads.InterestGroup.Auction.TimeSinceLastAuctionPerPage", kMaxTime, 1); // 2nd auction task_environment()->FastForwardBy(base::Seconds(1)); - EXPECT_EQ(RunAdAuctionAndFlush(fail_auction_config->Clone()), absl::nullopt); + EXPECT_EQ(RunAdAuctionAndFlush(fail_auction_config), absl::nullopt); histogram_tester.ExpectTimeBucketCount( "Ads.InterestGroup.Auction.TimeSinceLastAuctionPerPage", base::Seconds(1), 1); // 3rd auction task_environment()->FastForwardBy(base::Seconds(3)); - EXPECT_NE(RunAdAuctionAndFlush(succeed_auction_config->Clone()), - absl::nullopt); + EXPECT_NE(RunAdAuctionAndFlush(succeed_auction_config), absl::nullopt); histogram_tester.ExpectTimeBucketCount( "Ads.InterestGroup.Auction.TimeSinceLastAuctionPerPage", base::Seconds(3), 1); // 4th auction task_environment()->FastForwardBy(base::Minutes(1)); - EXPECT_NE(RunAdAuctionAndFlush(succeed_auction_config->Clone()), - absl::nullopt); + EXPECT_NE(RunAdAuctionAndFlush(succeed_auction_config), absl::nullopt); histogram_tester.ExpectTimeBucketCount( "Ads.InterestGroup.Auction.TimeSinceLastAuctionPerPage", base::Minutes(1), 1); // 5th auction task_environment()->FastForwardBy(base::Minutes(10)); - EXPECT_NE(RunAdAuctionAndFlush(succeed_auction_config->Clone()), - absl::nullopt); + EXPECT_NE(RunAdAuctionAndFlush(succeed_auction_config), absl::nullopt); histogram_tester.ExpectTimeBucketCount( "Ads.InterestGroup.Auction.TimeSinceLastAuctionPerPage", base::Minutes(10), 1); // 6th auction task_environment()->FastForwardBy(base::Minutes(30)); - EXPECT_EQ(RunAdAuctionAndFlush(fail_auction_config->Clone()), absl::nullopt); + EXPECT_EQ(RunAdAuctionAndFlush(fail_auction_config), absl::nullopt); histogram_tester.ExpectTimeBucketCount( "Ads.InterestGroup.Auction.TimeSinceLastAuctionPerPage", base::Minutes(30), 1); // 7th auction task_environment()->FastForwardBy(base::Hours(1)); - EXPECT_EQ(RunAdAuctionAndFlush(fail_auction_config->Clone()), absl::nullopt); + EXPECT_EQ(RunAdAuctionAndFlush(fail_auction_config), absl::nullopt); // Since the 1st auction has no prior auction -- it gets put in the same // bucket with the 7th auction -- there are 2 auctions now in this bucket. histogram_tester.ExpectTimeBucketCount( @@ -4625,33 +4563,26 @@ // bucket size is 1 hour, so specifying kMaxTime will select the max bucket. constexpr base::TimeDelta kMaxTime{base::Days(1)}; - auto succeed_auction_config = blink::mojom::AuctionAdConfig::New(); - succeed_auction_config->seller = kOriginA; - succeed_auction_config->decision_logic_url = kUrlA.Resolve(kDecisionUrlPath); - succeed_auction_config->auction_ad_config_non_shared_params = - blink::mojom::AuctionAdConfigNonSharedParams::New(); - succeed_auction_config->auction_ad_config_non_shared_params - ->interest_group_buyers = {kOriginA}; + blink::AuctionConfig succeed_auction_config; + succeed_auction_config.seller = kOriginA; + succeed_auction_config.decision_logic_url = kUrlA.Resolve(kDecisionUrlPath); + succeed_auction_config.non_shared_params.interest_group_buyers = {kOriginA}; - auto fail_auction_config = blink::mojom::AuctionAdConfig::New(); - fail_auction_config->seller = kOriginA; - fail_auction_config->decision_logic_url = + blink::AuctionConfig fail_auction_config; + fail_auction_config.seller = kOriginA; + fail_auction_config.decision_logic_url = kUrlA.Resolve(kDecisionFailAllUrlPath); - fail_auction_config->auction_ad_config_non_shared_params = - blink::mojom::AuctionAdConfigNonSharedParams::New(); - fail_auction_config->auction_ad_config_non_shared_params - ->interest_group_buyers = {kOriginA}; + fail_auction_config.non_shared_params.interest_group_buyers = {kOriginA}; // 1st auction - EXPECT_NE(RunAdAuctionAndFlush(succeed_auction_config->Clone()), - absl::nullopt); + EXPECT_NE(RunAdAuctionAndFlush(succeed_auction_config), absl::nullopt); // Time metrics are published every auction. histogram_tester.ExpectUniqueTimeSample( "Ads.InterestGroup.Auction.TimeSinceLastAuctionPerPage", kMaxTime, 1); // 2nd auction task_environment()->FastForwardBy(base::Seconds(1)); - EXPECT_EQ(RunAdAuctionAndFlush(fail_auction_config->Clone()), absl::nullopt); + EXPECT_EQ(RunAdAuctionAndFlush(fail_auction_config), absl::nullopt); histogram_tester.ExpectTimeBucketCount( "Ads.InterestGroup.Auction.TimeSinceLastAuctionPerPage", base::Seconds(1), 1); @@ -4785,17 +4716,13 @@ constexpr int kNumAuctions = 10; // Run kNumAuctions auctions, all should succeed since there's no limit: - auto succeed_auction_config = blink::mojom::AuctionAdConfig::New(); - succeed_auction_config->seller = kOriginA; - succeed_auction_config->decision_logic_url = kUrlA.Resolve(kDecisionUrlPath); - succeed_auction_config->auction_ad_config_non_shared_params = - blink::mojom::AuctionAdConfigNonSharedParams::New(); - succeed_auction_config->auction_ad_config_non_shared_params - ->interest_group_buyers = {kOriginA}; + blink::AuctionConfig succeed_auction_config; + succeed_auction_config.seller = kOriginA; + succeed_auction_config.decision_logic_url = kUrlA.Resolve(kDecisionUrlPath); + succeed_auction_config.non_shared_params.interest_group_buyers = {kOriginA}; for (int i = 0; i < kNumAuctions; i++) { - EXPECT_NE(RunAdAuctionAndFlush(succeed_auction_config->Clone()), - absl::nullopt); + EXPECT_NE(RunAdAuctionAndFlush(succeed_auction_config), absl::nullopt); } // Some metrics only get reported until after navigation. @@ -4917,36 +4844,29 @@ // An empty config should be treated as a bad message. TEST_F(AdAuctionServiceImplTest, FinalizeAdRejectsEmptyConfig) { - auto mojo_config = blink::mojom::AuctionAdConfig::New(); - mojo_config->auction_ad_config_non_shared_params = - blink::mojom::AuctionAdConfigNonSharedParams::New(); - + blink::AuctionConfig config; FinalizeAdAndExpectPipeClosed( - /*guid=*/std::string("1234"), std::move(mojo_config)); + /*guid=*/std::string("1234"), config); } // An HTTP decision logic URL should be treated as a bad message. TEST_F(AdAuctionServiceImplTest, FinalizeAdRejectsHTTPDecisionUrl) { - auto mojo_config = blink::mojom::AuctionAdConfig::New(); - mojo_config->auction_ad_config_non_shared_params = - blink::mojom::AuctionAdConfigNonSharedParams::New(); - mojo_config->seller = url::Origin::Create(GURL("https://site.test")); - mojo_config->decision_logic_url = GURL("http://site.test/"); + blink::AuctionConfig config; + config.seller = url::Origin::Create(GURL("https://site.test")); + config.decision_logic_url = GURL("http://site.test/"); FinalizeAdAndExpectPipeClosed( - /*guid=*/"1234", std::move(mojo_config)); + /*guid=*/"1234", config); } // An empty GUID should be treated as a bad message. TEST_F(AdAuctionServiceImplTest, FinalizeAdRejectsMissingGuid) { - auto mojo_config = blink::mojom::AuctionAdConfig::New(); - mojo_config->auction_ad_config_non_shared_params = - blink::mojom::AuctionAdConfigNonSharedParams::New(); - mojo_config->seller = url::Origin::Create(GURL("https://site.test")); - mojo_config->decision_logic_url = GURL("https://site.test/"); + blink::AuctionConfig config; + config.seller = url::Origin::Create(GURL("https://site.test")); + config.decision_logic_url = GURL("https://site.test/"); FinalizeAdAndExpectPipeClosed( - /*guid=*/std::string(), std::move(mojo_config)); + /*guid=*/std::string(), config); } class AdAuctionServiceImplNumAuctionLimitTest @@ -5021,33 +4941,26 @@ // bucket size is 1 hour, so specifying kMaxTime will select the max bucket. constexpr base::TimeDelta kMaxTime{base::Days(1)}; - auto succeed_auction_config = blink::mojom::AuctionAdConfig::New(); - succeed_auction_config->seller = kOriginA; - succeed_auction_config->decision_logic_url = kUrlA.Resolve(kDecisionUrlPath); - succeed_auction_config->auction_ad_config_non_shared_params = - blink::mojom::AuctionAdConfigNonSharedParams::New(); - succeed_auction_config->auction_ad_config_non_shared_params - ->interest_group_buyers = {kOriginA}; + blink::AuctionConfig succeed_auction_config; + succeed_auction_config.seller = kOriginA; + succeed_auction_config.decision_logic_url = kUrlA.Resolve(kDecisionUrlPath); + succeed_auction_config.non_shared_params.interest_group_buyers = {kOriginA}; - auto fail_auction_config = blink::mojom::AuctionAdConfig::New(); - fail_auction_config->seller = kOriginA; - fail_auction_config->decision_logic_url = + blink::AuctionConfig fail_auction_config; + fail_auction_config.seller = kOriginA; + fail_auction_config.decision_logic_url = kUrlA.Resolve(kDecisionFailAllUrlPath); - fail_auction_config->auction_ad_config_non_shared_params = - blink::mojom::AuctionAdConfigNonSharedParams::New(); - fail_auction_config->auction_ad_config_non_shared_params - ->interest_group_buyers = {kOriginA}; + fail_auction_config.non_shared_params.interest_group_buyers = {kOriginA}; // 1st auction - EXPECT_NE(RunAdAuctionAndFlush(succeed_auction_config->Clone()), - absl::nullopt); + EXPECT_NE(RunAdAuctionAndFlush(succeed_auction_config), absl::nullopt); // Time metrics are published every auction. histogram_tester.ExpectUniqueTimeSample( "Ads.InterestGroup.Auction.TimeSinceLastAuctionPerPage", kMaxTime, 1); // 2nd auction task_environment()->FastForwardBy(base::Seconds(1)); - EXPECT_EQ(RunAdAuctionAndFlush(fail_auction_config->Clone()), absl::nullopt); + EXPECT_EQ(RunAdAuctionAndFlush(fail_auction_config), absl::nullopt); histogram_tester.ExpectTimeBucketCount( "Ads.InterestGroup.Auction.TimeSinceLastAuctionPerPage", base::Seconds(1), 1); @@ -5055,8 +4968,7 @@ // 3rd auction -- fails even though decision_logic.js is used because the // auction limit is encountered. task_environment()->FastForwardBy(base::Seconds(3)); - EXPECT_EQ(RunAdAuctionAndFlush(succeed_auction_config->Clone()), - absl::nullopt); + EXPECT_EQ(RunAdAuctionAndFlush(succeed_auction_config), absl::nullopt); // The time metrics shouldn't get updated. histogram_tester.ExpectTimeBucketCount( "Ads.InterestGroup.Auction.TimeSinceLastAuctionPerPage", base::Seconds(3), @@ -5138,13 +5050,10 @@ JoinInterestGroupAndFlush(interest_group); EXPECT_EQ(1, GetJoinCount(kOriginA, kInterestGroupName)); - auto succeed_auction_config = blink::mojom::AuctionAdConfig::New(); - succeed_auction_config->seller = kOriginA; - succeed_auction_config->decision_logic_url = kUrlA.Resolve(kDecisionUrlPath); - succeed_auction_config->auction_ad_config_non_shared_params = - blink::mojom::AuctionAdConfigNonSharedParams::New(); - succeed_auction_config->auction_ad_config_non_shared_params - ->interest_group_buyers = {kOriginA}; + blink::AuctionConfig succeed_auction_config; + succeed_auction_config.seller = kOriginA; + succeed_auction_config.decision_logic_url = kUrlA.Resolve(kDecisionUrlPath); + succeed_auction_config.non_shared_params.interest_group_buyers = {kOriginA}; // Pick some large number, larger than the auction limit. constexpr int kNumAuctions = 10; @@ -5157,7 +5066,7 @@ for (int i = 0; i < kNumAuctions; i++) { interest_service->RunAdAuction( - succeed_auction_config->Clone(), + succeed_auction_config, base::BindLambdaForTesting( [&one_auction_complete]( const absl::optional<GURL>& ignored_result) { @@ -5400,16 +5309,12 @@ JoinInterestGroupAndFlush(interest_group); EXPECT_EQ(1, GetJoinCount(kOriginA, name)); - auto auction_config = blink::mojom::AuctionAdConfig::New(); - auction_config->seller = kOriginA; + blink::AuctionConfig auction_config; + auction_config.seller = kOriginA; - auction_config->decision_logic_url = kUrlA.Resolve(kDecisionUrlPath); - auction_config->auction_ad_config_non_shared_params = - blink::mojom::AuctionAdConfigNonSharedParams::New(); - auction_config->auction_ad_config_non_shared_params - ->interest_group_buyers = {kOriginA}; - absl::optional<GURL> auction_result = - RunAdAuctionAndFlush(std::move(auction_config)); + auction_config.decision_logic_url = kUrlA.Resolve(kDecisionUrlPath); + auction_config.non_shared_params.interest_group_buyers = {kOriginA}; + absl::optional<GURL> auction_result = RunAdAuctionAndFlush(auction_config); EXPECT_NE(auction_result, absl::nullopt); }
diff --git a/content/browser/interest_group/auction_runner.cc b/content/browser/interest_group/auction_runner.cc index 7aba832..d6c7304 100644 --- a/content/browser/interest_group/auction_runner.cc +++ b/content/browser/interest_group/auction_runner.cc
@@ -38,6 +38,7 @@ #include "services/network/public/mojom/url_loader_factory.mojom-forward.h" #include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/blink/public/common/interest_group/ad_auction_constants.h" +#include "third_party/blink/public/common/interest_group/auction_config.h" #include "third_party/blink/public/common/interest_group/interest_group.h" #include "third_party/blink/public/mojom/interest_group/interest_group_types.mojom.h" #include "url/gurl.h" @@ -171,7 +172,7 @@ AuctionRunner::ScoredBid::~ScoredBid() = default; AuctionRunner::Auction::Auction( - blink::mojom::AuctionAdConfig* config, + const blink::AuctionConfig* config, const Auction* parent, AuctionWorkletManager* auction_worklet_manager, InterestGroupManagerImpl* interest_group_manager, @@ -187,12 +188,12 @@ config_->decision_logic_url); for (const auto& component_auction_config : - config->auction_ad_config_non_shared_params->component_auctions) { + config->non_shared_params.component_auctions) { // Nested component auctions are not supported. DCHECK(!parent_); component_auctions_.emplace_back(std::make_unique<Auction>( - component_auction_config.get(), /*parent=*/this, - auction_worklet_manager, interest_group_manager, auction_start_time)); + &component_auction_config, /*parent=*/this, auction_worklet_manager, + interest_group_manager, auction_start_time)); } } @@ -269,9 +270,9 @@ ++num_pending_loads_; } - if (config_->auction_ad_config_non_shared_params->interest_group_buyers) { + if (config_->non_shared_params.interest_group_buyers) { for (const auto& buyer : - *config_->auction_ad_config_non_shared_params->interest_group_buyers) { + *config_->non_shared_params.interest_group_buyers) { if (!is_interest_group_api_allowed_callback.Run( ContentBrowserClient::InterestGroupApiOperation::kBuy, buyer)) { continue; @@ -362,9 +363,7 @@ DCHECK(top_seller_signals); if (!auction_worklet_manager_->RequestSellerWorklet( config_->decision_logic_url, config_->trusted_scoring_signals_url, - config_->has_seller_experiment_group_id - ? absl::make_optional(config_->seller_experiment_group_id) - : absl::nullopt, + config_->seller_experiment_group_id, base::BindOnce(&Auction::ReportSellerResult, base::Unretained(this), top_seller_signals), base::BindOnce(&Auction::OnWinningComponentSellerWorkletFatalError, @@ -604,14 +603,13 @@ std::vector<StorageInterestGroup> interest_groups) { ++num_owners_loaded_; if (!interest_groups.empty()) { - size_t size_limit = - config_->auction_ad_config_non_shared_params->all_buyers_group_limit; + size_t size_limit = config_->non_shared_params.all_buyers_group_limit; const url::Origin& owner = interest_groups[0].interest_group.owner; post_auction_update_owners_.push_back(owner); - const auto limit_iter = config_->auction_ad_config_non_shared_params - ->per_buyer_group_limits.find(owner); - if (limit_iter != config_->auction_ad_config_non_shared_params - ->per_buyer_group_limits.cend()) { + const auto limit_iter = + config_->non_shared_params.per_buyer_group_limits.find(owner); + if (limit_iter != + config_->non_shared_params.per_buyer_group_limits.cend()) { size_limit = static_cast<size_t>(limit_iter->second); } StorageInterestGroupDescByPriority cmp; @@ -751,9 +749,7 @@ trace_id_); if (auction_worklet_manager_->RequestSellerWorklet( config_->decision_logic_url, config_->trusted_scoring_signals_url, - config_->has_seller_experiment_group_id - ? absl::make_optional(config_->seller_experiment_group_id) - : absl::nullopt, + config_->seller_experiment_group_id, base::BindOnce(&Auction::OnSellerWorkletReceived, base::Unretained(this)), base::BindOnce(&Auction::OnSellerWorkletFatalError, @@ -834,8 +830,8 @@ interest_group.trusted_bidding_signals_keys, interest_group.user_bidding_signals, interest_group.ads, interest_group.ad_components), - config_->auction_ad_config_non_shared_params->auction_signals, - PerBuyerSignals(bid_state), PerBuyerTimeout(bid_state), config_->seller, + config_->non_shared_params.auction_signals, PerBuyerSignals(bid_state), + PerBuyerTimeout(bid_state), config_->seller, parent_ ? parent_->config_->seller : absl::optional<url::Origin>(), bid_state->bidder.bidding_browser_signals.Clone(), auction_start_time_, *bid_state->trace_id, @@ -1003,8 +999,7 @@ Bid* bid_raw = bid.get(); seller_worklet_handle_->GetSellerWorklet()->ScoreAd( - bid_raw->ad_metadata, bid_raw->bid, - config_->auction_ad_config_non_shared_params.Clone(), + bid_raw->ad_metadata, bid_raw->bid, config_->non_shared_params, GetOtherSellerParam(*bid_raw), bid_raw->interest_group->owner, bid_raw->render_url, bid_raw->ad_components, bid_raw->bid_duration.InMilliseconds(), SellerTimeout(), @@ -1182,8 +1177,7 @@ absl::optional<std::string> AuctionRunner::Auction::PerBuyerSignals( const BidState* state) { - const auto& per_buyer_signals = - config_->auction_ad_config_non_shared_params->per_buyer_signals; + const auto& per_buyer_signals = config_->non_shared_params.per_buyer_signals; if (per_buyer_signals.has_value()) { auto it = per_buyer_signals.value().find(state->bidder.interest_group.owner); @@ -1196,7 +1190,7 @@ absl::optional<base::TimeDelta> AuctionRunner::Auction::PerBuyerTimeout( const BidState* state) { const auto& per_buyer_timeouts = - config_->auction_ad_config_non_shared_params->per_buyer_timeouts; + config_->non_shared_params.per_buyer_timeouts; if (per_buyer_timeouts.has_value()) { auto it = per_buyer_timeouts.value().find(state->bidder.interest_group.owner); @@ -1204,18 +1198,16 @@ return std::min(it->second, kMaxTimeout); } const auto& all_buyers_timeout = - config_->auction_ad_config_non_shared_params->all_buyers_timeout; + config_->non_shared_params.all_buyers_timeout; if (all_buyers_timeout.has_value()) return std::min(all_buyers_timeout.value(), kMaxTimeout); return absl::nullopt; } absl::optional<base::TimeDelta> AuctionRunner::Auction::SellerTimeout() { - if (config_->auction_ad_config_non_shared_params->seller_timeout - .has_value()) { - return std::min( - config_->auction_ad_config_non_shared_params->seller_timeout.value(), - kMaxTimeout); + if (config_->non_shared_params.seller_timeout.has_value()) { + return std::min(config_->non_shared_params.seller_timeout.value(), + kMaxTimeout); } return absl::nullopt; } @@ -1326,10 +1318,9 @@ } seller_worklet_handle_->GetSellerWorklet()->ReportResult( - config_->auction_ad_config_non_shared_params.Clone(), - GetOtherSellerParam(*top_bid_->bid), top_bid_->bid->interest_group->owner, - top_bid_->bid->render_url, top_bid_->bid->bid, top_bid_->score, - highest_scoring_other_bid_, + config_->non_shared_params, GetOtherSellerParam(*top_bid_->bid), + top_bid_->bid->interest_group->owner, top_bid_->bid->render_url, + top_bid_->bid->bid, top_bid_->score, highest_scoring_other_bid_, std::move(browser_signals_component_auction_report_result_params), top_bid_->scoring_signals_data_version.value_or(0), top_bid_->scoring_signals_data_version.has_value(), trace_id_, @@ -1423,7 +1414,7 @@ top_bid_->bid->bid_state->worklet_handle->GetBidderWorklet()->ReportWin( top_bid_->bid->interest_group->name, - config_->auction_ad_config_non_shared_params->auction_signals, + config_->non_shared_params.auction_signals, PerBuyerSignals(top_bid_->bid->bid_state), signals_for_winner, top_bid_->bid->render_url, top_bid_->bid->bid, /*browser_signal_highest_scoring_other_bid=*/highest_scoring_other_bid_, @@ -1591,10 +1582,11 @@ absl::optional<uint16_t> experiment_group_id = absl::nullopt; auto it = config_->per_buyer_experiment_group_ids.find(interest_group.owner); - if (it != config_->per_buyer_experiment_group_ids.end()) + if (it != config_->per_buyer_experiment_group_ids.end()) { experiment_group_id = it->second; - else if (config_->has_all_buyer_experiment_group_id) + } else { experiment_group_id = config_->all_buyer_experiment_group_id; + } return auction_worklet_manager_->RequestBidderWorklet( interest_group.bidding_url.value_or(GURL()), @@ -1607,7 +1599,7 @@ std::unique_ptr<AuctionRunner> AuctionRunner::CreateAndStart( AuctionWorkletManager* auction_worklet_manager, InterestGroupManagerImpl* interest_group_manager, - blink::mojom::AuctionAdConfigPtr auction_config, + const blink::AuctionConfig& auction_config, network::mojom::ClientSecurityStatePtr client_security_state, IsInterestGroupApiAllowedCallback is_interest_group_api_allowed_callback, RunAuctionCallback callback) { @@ -1646,7 +1638,7 @@ AuctionRunner::AuctionRunner( AuctionWorkletManager* auction_worklet_manager, InterestGroupManagerImpl* interest_group_manager, - blink::mojom::AuctionAdConfigPtr auction_config, + const blink::AuctionConfig& auction_config, network::mojom::ClientSecurityStatePtr client_security_state, IsInterestGroupApiAllowedCallback is_interest_group_api_allowed_callback, RunAuctionCallback callback) @@ -1654,9 +1646,9 @@ client_security_state_(std::move(client_security_state)), is_interest_group_api_allowed_callback_( is_interest_group_api_allowed_callback), - owned_auction_config_(std::move(auction_config)), + owned_auction_config_(auction_config), callback_(std::move(callback)), - auction_(owned_auction_config_.get(), + auction_(&owned_auction_config_, /*parent=*/nullptr, auction_worklet_manager, interest_group_manager,
diff --git a/content/browser/interest_group/auction_runner.h b/content/browser/interest_group/auction_runner.h index a15cb11..df369a62 100644 --- a/content/browser/interest_group/auction_runner.h +++ b/content/browser/interest_group/auction_runner.h
@@ -31,6 +31,10 @@ #include "url/gurl.h" #include "url/origin.h" +namespace blink { +struct AuctionConfig; +} + namespace content { class InterestGroupManagerImpl; @@ -198,7 +202,7 @@ static std::unique_ptr<AuctionRunner> CreateAndStart( AuctionWorkletManager* auction_worklet_manager, InterestGroupManagerImpl* interest_group_manager, - blink::mojom::AuctionAdConfigPtr auction_config, + const blink::AuctionConfig& auction_config, network::mojom::ClientSecurityStatePtr client_security_state, IsInterestGroupApiAllowedCallback is_interest_group_api_allowed_callback, RunAuctionCallback callback); @@ -393,7 +397,7 @@ // destroyed. `config` is typically owned by the AuctionRunner's // `owned_auction_config_` field. `parent` should be the parent Auction if // this is a component auction, and null, otherwise. - Auction(blink::mojom::AuctionAdConfig* config, + Auction(const blink::AuctionConfig* config, const Auction* parent, AuctionWorkletManager* auction_worklet_manager, InterestGroupManagerImpl* interest_group_manager, @@ -732,7 +736,7 @@ const raw_ptr<InterestGroupManagerImpl> interest_group_manager_; // Configuration of this auction. - raw_ptr<const blink::mojom::AuctionAdConfig> config_; + raw_ptr<const blink::AuctionConfig> config_; // If this is a component auction, the parent Auction. Null, otherwise. const raw_ptr<const Auction> parent_; @@ -871,7 +875,7 @@ AuctionRunner( AuctionWorkletManager* auction_worklet_manager, InterestGroupManagerImpl* interest_group_manager, - blink::mojom::AuctionAdConfigPtr auction_config, + const blink::AuctionConfig& auction_config, network::mojom::ClientSecurityStatePtr client_security_state, IsInterestGroupApiAllowedCallback is_interest_group_api_allowed_callback, RunAuctionCallback callback); @@ -912,7 +916,7 @@ IsInterestGroupApiAllowedCallback is_interest_group_api_allowed_callback_; // Configuration. - blink::mojom::AuctionAdConfigPtr owned_auction_config_; + blink::AuctionConfig owned_auction_config_; RunAuctionCallback callback_; Auction auction_;
diff --git a/content/browser/interest_group/auction_runner_unittest.cc b/content/browser/interest_group/auction_runner_unittest.cc index a83340a..986600a 100644 --- a/content/browser/interest_group/auction_runner_unittest.cc +++ b/content/browser/interest_group/auction_runner_unittest.cc
@@ -993,7 +993,7 @@ void ScoreAd(const std::string& ad_metadata_json, double bid, - blink::mojom::AuctionAdConfigNonSharedParamsPtr + const blink::AuctionConfig::NonSharedParams& auction_ad_config_non_shared_params, auction_worklet::mojom::ComponentAuctionOtherSellerPtr browser_signals_other_seller, @@ -1032,7 +1032,7 @@ } void ReportResult( - blink::mojom::AuctionAdConfigNonSharedParamsPtr + const blink::AuctionConfig::NonSharedParams& auction_ad_config_non_shared_params, auction_worklet::mojom::ComponentAuctionOtherSellerPtr browser_signals_other_seller, @@ -1453,24 +1453,18 @@ std::string TakeBadMessage() { return std::move(bad_message_); } // Helper to create an auction config with the specified values. - blink::mojom::AuctionAdConfigPtr CreateAuctionConfig( + blink::AuctionConfig CreateAuctionConfig( const GURL& seller_decision_logic_url, absl::optional<std::vector<url::Origin>> buyers) { - blink::mojom::AuctionAdConfigPtr auction_config = - blink::mojom::AuctionAdConfig::New(); - auction_config->seller = url::Origin::Create(seller_decision_logic_url); - auction_config->decision_logic_url = seller_decision_logic_url; + blink::AuctionConfig auction_config; + auction_config.seller = url::Origin::Create(seller_decision_logic_url); + auction_config.decision_logic_url = seller_decision_logic_url; - auction_config->auction_ad_config_non_shared_params = - blink::mojom::AuctionAdConfigNonSharedParams::New(); - auction_config->auction_ad_config_non_shared_params->interest_group_buyers = - std::move(buyers); + auction_config.non_shared_params.interest_group_buyers = std::move(buyers); - auction_config->auction_ad_config_non_shared_params->seller_signals = - base::StringPrintf(R"({"url": "%s"})", - seller_decision_logic_url.spec().c_str()); - auction_config->auction_ad_config_non_shared_params->seller_timeout = - base::Milliseconds(1000); + auction_config.non_shared_params.seller_signals = base::StringPrintf( + R"({"url": "%s"})", seller_decision_logic_url.spec().c_str()); + auction_config.non_shared_params.seller_timeout = base::Milliseconds(1000); base::flat_map<url::Origin, std::string> per_buyer_signals; // Use a combination of bidder and seller values, so can make sure bidders @@ -1478,40 +1472,31 @@ // as a defense against pulling the right values from the wrong places. per_buyer_signals[kBidder1] = base::StringPrintf( R"({"%sSignals": "%sSignals"})", - auction_config->seller.Serialize().c_str(), kBidder1Name.c_str()); + auction_config.seller.Serialize().c_str(), kBidder1Name.c_str()); per_buyer_signals[kBidder2] = base::StringPrintf( R"({"%sSignals": "%sSignals"})", - auction_config->seller.Serialize().c_str(), kBidder2Name.c_str()); - auction_config->auction_ad_config_non_shared_params->per_buyer_signals = + auction_config.seller.Serialize().c_str(), kBidder2Name.c_str()); + auction_config.non_shared_params.per_buyer_signals = std::move(per_buyer_signals); base::flat_map<url::Origin, base::TimeDelta> per_buyer_timeouts; // Any per buyer timeout higher than 500 ms will be clamped to 500 ms by the // AuctionRunner. per_buyer_timeouts[kBidder1] = base::Milliseconds(1000); - auction_config->auction_ad_config_non_shared_params->per_buyer_timeouts = + auction_config.non_shared_params.per_buyer_timeouts = std::move(per_buyer_timeouts); - auction_config->auction_ad_config_non_shared_params->all_buyers_timeout = + auction_config.non_shared_params.all_buyers_timeout = base::Milliseconds(150); - auction_config->auction_ad_config_non_shared_params->auction_signals = - base::StringPrintf(R"("auctionSignalsFor %s")", - auction_config->seller.Serialize().c_str()); + auction_config.non_shared_params.auction_signals = base::StringPrintf( + R"("auctionSignalsFor %s")", auction_config.seller.Serialize().c_str()); - if (seller_experiment_group_id_.has_value()) { - auction_config->has_seller_experiment_group_id = true; - auction_config->seller_experiment_group_id = - seller_experiment_group_id_.value(); - } - - if (all_buyer_experiment_group_id_.has_value()) { - auction_config->has_all_buyer_experiment_group_id = true; - auction_config->all_buyer_experiment_group_id = - all_buyer_experiment_group_id_.value(); - } + auction_config.seller_experiment_group_id = seller_experiment_group_id_; + auction_config.all_buyer_experiment_group_id = + all_buyer_experiment_group_id_; for (const auto& kv : per_buyer_experiment_group_id_) { - auction_config->per_buyer_experiment_group_ids[kv.first] = kv.second; + auction_config.per_buyer_experiment_group_ids[kv.first] = kv.second; } return auction_config; @@ -1529,14 +1514,14 @@ std::vector<StorageInterestGroup> bidders) { auction_complete_ = false; - blink::mojom::AuctionAdConfigPtr auction_config = + auto auction_config = CreateAuctionConfig(seller_decision_logic_url, interest_group_buyers_); - auction_config->trusted_scoring_signals_url = trusted_scoring_signals_url_; + auction_config.trusted_scoring_signals_url = trusted_scoring_signals_url_; for (const auto& component_auction : component_auctions_) { - auction_config->auction_ad_config_non_shared_params->component_auctions - .emplace_back(component_auction.Clone()); + auction_config.non_shared_params.component_auctions.push_back( + component_auction); } interest_group_manager_ = std::make_unique<InterestGroupManagerImpl>( @@ -1982,7 +1967,7 @@ absl::optional<std::vector<url::Origin>> interest_group_buyers_ = { {kBidder1, kBidder2}}; - std::vector<blink::mojom::AuctionAdConfigPtr> component_auctions_; + std::vector<blink::AuctionConfig> component_auctions_; // Origins which are not allowed to take part in auctions, as the // corresponding participant types.
diff --git a/content/browser/interest_group/auction_worklet_manager_unittest.cc b/content/browser/interest_group/auction_worklet_manager_unittest.cc index 0213c51..b43766f 100644 --- a/content/browser/interest_group/auction_worklet_manager_unittest.cc +++ b/content/browser/interest_group/auction_worklet_manager_unittest.cc
@@ -266,7 +266,7 @@ void ScoreAd(const std::string& ad_metadata_json, double bid, - blink::mojom::AuctionAdConfigNonSharedParamsPtr + const blink::AuctionConfig::NonSharedParams& auction_ad_config_non_shared_params, auction_worklet::mojom::ComponentAuctionOtherSellerPtr browser_signals_other_seller, @@ -289,7 +289,7 @@ } void ReportResult( - blink::mojom::AuctionAdConfigNonSharedParamsPtr + const blink::AuctionConfig::NonSharedParams& auction_ad_config_non_shared_params, auction_worklet::mojom::ComponentAuctionOtherSellerPtr browser_signals_other_seller,
diff --git a/content/browser/interest_group/interest_group_browsertest.cc b/content/browser/interest_group/interest_group_browsertest.cc index 45f9e79..61a88fbb1 100644 --- a/content/browser/interest_group/interest_group_browsertest.cc +++ b/content/browser/interest_group/interest_group_browsertest.cc
@@ -6408,308 +6408,6 @@ "&experimentGroupId=1203")); } -// This test exercises the interest group and ad auction services directly, -// rather than via Blink, to ensure that those services running in the browser -// implement important security checks (Blink may also perform its own -// checking, but the render process is untrusted). -IN_PROC_BROWSER_TEST_F(InterestGroupBrowserTest, RunAdAuctionBasicBypassBlink) { - ASSERT_TRUE(NavigateToURL(shell(), https_server_->GetURL("a.test", "/echo"))); - - mojo::Remote<blink::mojom::AdAuctionService> auction_service; - AdAuctionServiceImpl::CreateMojoService( - web_contents()->GetMainFrame(), - auction_service.BindNewPipeAndPassReceiver()); - - base::RunLoop run_loop; - - auto auction_config = blink::mojom::AuctionAdConfig::New(); - auction_config->auction_ad_config_non_shared_params = - blink::mojom::AuctionAdConfigNonSharedParams::New(); - - auction_service->RunAdAuction( - std::move(auction_config), - base::BindLambdaForTesting([&run_loop](const absl::optional<GURL>& url) { - EXPECT_THAT(url, Eq(absl::nullopt)); - run_loop.Quit(); - })); - run_loop.Run(); -} - -// Fixture for Blink-bypassing auction tests that share the same interest group -// -- useful for checking auction service security validations. -class InterestGroupBrowserTestRunAdAuctionBypassBlink - : public InterestGroupBrowserTest { - protected: - void SetUpOnMainThread() override { - InterestGroupBrowserTest::SetUpOnMainThread(); - ad_url_ = https_server_->GetURL("c.test", "/echo?render_ad"); - - GURL test_url_a = https_server_->GetURL("a.test", "/echo"); - test_origin_a_ = url::Origin::Create(test_url_a); - ASSERT_TRUE(test_url_a.SchemeIs(url::kHttpsScheme)); - ASSERT_TRUE(NavigateToURL(shell(), test_url_a)); - - mojo::Remote<blink::mojom::AdAuctionService> interest_service; - AdAuctionServiceImpl::CreateMojoService( - web_contents()->GetMainFrame(), - interest_service.BindNewPipeAndPassReceiver()); - - // Set up ad_url_ as the only interest group ad in the auction. - blink::InterestGroup interest_group; - interest_group.expiry = base::Time::Now() + base::Seconds(300); - constexpr char kGroupName[] = "cars"; - interest_group.name = kGroupName; - interest_group.owner = test_origin_a_; - interest_group.bidding_url = - https_server_->GetURL("a.test", "/interest_group/bidding_logic.js"); - interest_group.trusted_bidding_signals_url = https_server_->GetURL( - "a.test", "/interest_group/trusted_bidding_signals.json"); - interest_group.trusted_bidding_signals_keys.emplace(); - interest_group.trusted_bidding_signals_keys->push_back("key1"); - interest_group.user_bidding_signals = - "{\"some\": \"json\", \"data\": {\"here\": [1, 2, 3]}}"; - interest_group.ads.emplace(); - interest_group.ads->push_back(blink::InterestGroup::Ad( - /* render_url = */ ad_url_, - /* metadata = */ "{\"ad\": \"metadata\", \"here\": [1, 2, 3]}")); - - base::RunLoop run_loop; - interest_service->JoinInterestGroup( - interest_group, - base::BindLambdaForTesting([&](bool failed_well_known_check) { - EXPECT_FALSE(failed_well_known_check); - run_loop.Quit(); - })); - run_loop.Run(); - - EXPECT_EQ(1, GetJoinCount(test_origin_a_, kGroupName)); - } - - absl::optional<GURL> RunAuctionBypassBlink( - blink::mojom::AuctionAdConfigPtr config) { - absl::optional<GURL> maybe_url; - base::RunLoop run_loop; - mojo::Remote<blink::mojom::AdAuctionService> auction_service; - AdAuctionServiceImpl::CreateMojoService( - web_contents()->GetMainFrame(), - auction_service.BindNewPipeAndPassReceiver()); - - auction_service->RunAdAuction( - std::move(config), - base::BindLambdaForTesting( - [&run_loop, &maybe_url](const absl::optional<GURL>& url) { - maybe_url = url; - run_loop.Quit(); - })); - run_loop.Run(); - if (maybe_url) { - TestFencedFrameURLMappingResultObserver observer; - ConvertFencedFrameURNToURL(*maybe_url, &observer); - EXPECT_TRUE(observer.mapped_url()); - absl::optional<GURL> decoded_URL = observer.mapped_url(); - EXPECT_EQ(decoded_URL, ConvertFencedFrameURNToURLInJS(*maybe_url)); - NavigateIframeAndCheckURL(web_contents(), *maybe_url, - decoded_URL.value_or(GURL())); - return *observer.mapped_url(); - } - return absl::nullopt; - } - - // Creates a valid AuctionAdConfigPtr which will run an auction with the - // InterestGroup added in SetUpOnMainThread() participating and winning. - blink::mojom::AuctionAdConfigPtr CreateValidAuctionConfig() { - auto config = blink::mojom::AuctionAdConfig::New(); - config->seller = test_origin_a_; - config->decision_logic_url = - https_server_->GetURL("a.test", "/interest_group/decision_logic.js"); - config->auction_ad_config_non_shared_params = - blink::mojom::AuctionAdConfigNonSharedParams::New(); - config->auction_ad_config_non_shared_params->interest_group_buyers = { - test_origin_a_}; - return config; - } - - url::Origin test_origin_a_; - GURL ad_url_; -}; - -IN_PROC_BROWSER_TEST_F(InterestGroupBrowserTestRunAdAuctionBypassBlink, - BasicSuccess) { - GURL test_url_b = https_server_->GetURL("b.test", "/page_with_iframe.html"); - ASSERT_TRUE(test_url_b.SchemeIs(url::kHttpsScheme)); - url::Origin test_origin_b = url::Origin::Create(test_url_b); - ASSERT_TRUE(NavigateToURL(shell(), test_url_b)); - - auto config = blink::mojom::AuctionAdConfig::New(); - config->seller = test_origin_b; - config->decision_logic_url = - https_server_->GetURL("b.test", "/interest_group/decision_logic.js"); - config->auction_ad_config_non_shared_params = - blink::mojom::AuctionAdConfigNonSharedParams::New(); - config->auction_ad_config_non_shared_params->interest_group_buyers = { - test_origin_a_}; - - EXPECT_THAT(RunAuctionBypassBlink(std::move(config)), Optional(Eq(ad_url_))); -} - -IN_PROC_BROWSER_TEST_F(InterestGroupBrowserTestRunAdAuctionBypassBlink, - SellerNotHttps) { - GURL test_url_b = https_server_->GetURL("a.test", "/echo"); - url::Origin test_origin_b = url::Origin::Create(test_url_b); - ASSERT_TRUE(NavigateToURL(shell(), test_url_b)); - - auto config = blink::mojom::AuctionAdConfig::New(); - config->seller = test_origin_b; - config->decision_logic_url = embedded_test_server()->GetURL( - "b.test", "/interest_group/decision_logic.js"); - ASSERT_TRUE(config->decision_logic_url.SchemeIs(url::kHttpScheme)); - config->auction_ad_config_non_shared_params = - blink::mojom::AuctionAdConfigNonSharedParams::New(); - config->auction_ad_config_non_shared_params->interest_group_buyers = { - test_origin_a_}; - - EXPECT_THAT(RunAuctionBypassBlink(std::move(config)), Eq(absl::nullopt)); -} - -IN_PROC_BROWSER_TEST_F(InterestGroupBrowserTestRunAdAuctionBypassBlink, - WrongDecisionUrlOrigin) { - // The `decision_logic_url` origin doesn't match `seller`s, which is invalid. - auto config = blink::mojom::AuctionAdConfig::New(); - config->seller = test_origin_a_; - config->decision_logic_url = - https_server_->GetURL("b.test", "/interest_group/decision_logic.js"); - config->auction_ad_config_non_shared_params = - blink::mojom::AuctionAdConfigNonSharedParams::New(); - config->auction_ad_config_non_shared_params->interest_group_buyers = { - test_origin_a_}; - - EXPECT_THAT(RunAuctionBypassBlink(std::move(config)), Eq(absl::nullopt)); -} - -IN_PROC_BROWSER_TEST_F(InterestGroupBrowserTestRunAdAuctionBypassBlink, - InterestGroupBuyerOriginNotHttps) { - GURL test_url_b = https_server_->GetURL("b.test", "/page_with_iframe.html"); - ASSERT_TRUE(test_url_b.SchemeIs(url::kHttpsScheme)); - url::Origin test_origin_b = url::Origin::Create(test_url_b); - ASSERT_TRUE(NavigateToURL(shell(), test_url_b)); - - // Same hostname as `test_url_a_`, different scheme. This buyer is not valid - // because it is not https, so the auction fails. - GURL test_url_a_http = embedded_test_server()->GetURL("a.test", "/echo"); - ASSERT_TRUE(test_url_a_http.SchemeIs(url::kHttpScheme)); - url::Origin test_origin_a_http = url::Origin::Create(test_url_a_http); - - auto config = blink::mojom::AuctionAdConfig::New(); - config->seller = test_origin_b; - config->decision_logic_url = - https_server_->GetURL("b.test", "/interest_group/decision_logic.js"); - config->auction_ad_config_non_shared_params = - blink::mojom::AuctionAdConfigNonSharedParams::New(); - config->auction_ad_config_non_shared_params->interest_group_buyers = { - test_origin_a_http}; - - EXPECT_THAT(RunAuctionBypassBlink(std::move(config)), Eq(absl::nullopt)); -} - -IN_PROC_BROWSER_TEST_F(InterestGroupBrowserTestRunAdAuctionBypassBlink, - InterestGroupBuyerOriginNotHttpsMultipleBuyers) { - GURL test_url_b = https_server_->GetURL("b.test", "/page_with_iframe.html"); - ASSERT_TRUE(test_url_b.SchemeIs(url::kHttpsScheme)); - url::Origin test_origin_b = url::Origin::Create(test_url_b); - ASSERT_TRUE(NavigateToURL(shell(), test_url_b)); - - // Same hostname as `test_url_a_`, different scheme. This buyer is not valid - // because it is not https, so the auction fails, even though the other buyer - // is valid. - GURL test_url_a_http = embedded_test_server()->GetURL("a.test", "/echo"); - ASSERT_TRUE(test_url_a_http.SchemeIs(url::kHttpScheme)); - url::Origin test_origin_a_http = url::Origin::Create(test_url_a_http); - - auto config = blink::mojom::AuctionAdConfig::New(); - config->seller = test_origin_b; - config->decision_logic_url = - https_server_->GetURL("b.test", "/interest_group/decision_logic.js"); - config->auction_ad_config_non_shared_params = - blink::mojom::AuctionAdConfigNonSharedParams::New(); - config->auction_ad_config_non_shared_params->interest_group_buyers = { - test_origin_a_, test_origin_a_http}; - - EXPECT_THAT(RunAuctionBypassBlink(std::move(config)), Eq(absl::nullopt)); -} - -IN_PROC_BROWSER_TEST_F(InterestGroupBrowserTestRunAdAuctionBypassBlink, - BuyerWithNoRegisteredInterestGroupsIgnored) { - GURL test_url_b = https_server_->GetURL("b.test", "/page_with_iframe.html"); - ASSERT_TRUE(test_url_b.SchemeIs(url::kHttpsScheme)); - url::Origin test_origin_b = url::Origin::Create(test_url_b); - ASSERT_TRUE(NavigateToURL(shell(), test_url_b)); - - // New valid origin, not associated with any registered interest group. Its - // presence in the auctions `interest_group_buyers` shouldn't affect the - // auction outcome. - GURL test_url_c = https_server_->GetURL("c.test", "/echo"); - ASSERT_TRUE(test_url_c.SchemeIs(url::kHttpsScheme)); - url::Origin test_origin_c = url::Origin::Create(test_url_c); - - auto config = blink::mojom::AuctionAdConfig::New(); - config->seller = test_origin_b; - config->decision_logic_url = - https_server_->GetURL("b.test", "/interest_group/decision_logic.js"); - config->auction_ad_config_non_shared_params = - blink::mojom::AuctionAdConfigNonSharedParams::New(); - config->auction_ad_config_non_shared_params->interest_group_buyers = { - test_origin_a_, test_origin_c}; - - EXPECT_THAT(RunAuctionBypassBlink(std::move(config)), Optional(Eq(ad_url_))); -} - -IN_PROC_BROWSER_TEST_F(InterestGroupBrowserTestRunAdAuctionBypassBlink, - TrustedScoringSignalsUrlWrongOrigin) { - GURL test_url_b = https_server_->GetURL("b.test", "/page_with_iframe.html"); - ASSERT_TRUE(test_url_b.SchemeIs(url::kHttpsScheme)); - url::Origin test_origin_b = url::Origin::Create(test_url_b); - ASSERT_TRUE(NavigateToURL(shell(), test_url_b)); - - auto config = blink::mojom::AuctionAdConfig::New(); - config->seller = test_origin_b; - config->decision_logic_url = - https_server_->GetURL("b.test", "/interest_group/decision_logic.js"); - config->trusted_scoring_signals_url = https_server_->GetURL( - "not-b.test", "/interest_group/trusted_scoring_signals.json"); - config->auction_ad_config_non_shared_params = - blink::mojom::AuctionAdConfigNonSharedParams::New(); - config->auction_ad_config_non_shared_params->interest_group_buyers = { - test_origin_a_}; - - EXPECT_THAT(RunAuctionBypassBlink(std::move(config)), Eq(absl::nullopt)); -} - -IN_PROC_BROWSER_TEST_F(InterestGroupBrowserTestRunAdAuctionBypassBlink, - InvalidComponentAuctionUrl) { - auto config = CreateValidAuctionConfig(); - auto component_auction_config = CreateValidAuctionConfig(); - // This is invalid because it's cross-origin to the seller. - component_auction_config->decision_logic_url = - https_server_->GetURL("d.test", "/interest_group/decision_logic.js"); - config->auction_ad_config_non_shared_params->component_auctions.emplace_back( - std::move(component_auction_config)); - - EXPECT_THAT(RunAuctionBypassBlink(std::move(config)), Eq(absl::nullopt)); -} - -// Test that component auctions with their own component auctions are rejected. -IN_PROC_BROWSER_TEST_F(InterestGroupBrowserTestRunAdAuctionBypassBlink, - InvalidComponentAuctionDepth) { - auto config = CreateValidAuctionConfig(); - auto component_auction_config = CreateValidAuctionConfig(); - component_auction_config->auction_ad_config_non_shared_params - ->component_auctions.emplace_back(CreateValidAuctionConfig()); - config->auction_ad_config_non_shared_params->component_auctions.emplace_back( - std::move(component_auction_config)); - - EXPECT_THAT(RunAuctionBypassBlink(std::move(config)), Eq(absl::nullopt)); -} - // Validate that createAdRequest is available and be successfully called as part // of PARAKEET. IN_PROC_BROWSER_TEST_F(InterestGroupBrowserTest, CreateAdRequestWorks) {
diff --git a/content/browser/media/capture/content_capture_device_browsertest_base.cc b/content/browser/media/capture/content_capture_device_browsertest_base.cc index 1cb1439..a7ebae1 100644 --- a/content/browser/media/capture/content_capture_device_browsertest_base.cc +++ b/content/browser/media/capture/content_capture_device_browsertest_base.cc
@@ -21,6 +21,7 @@ #include "content/public/test/test_utils.h" #include "content/shell/browser/shell.h" #include "content/shell/common/shell_switches.h" +#include "media/base/video_types.h" #include "net/dns/mock_host_resolver.h" #include "net/test/embedded_test_server/embedded_test_server.h" #include "net/test/embedded_test_server/http_request.h" @@ -94,7 +95,7 @@ media::VideoCaptureParams params; params.requested_format = media::VideoCaptureFormat( - capture_size, kMaxFramesPerSecond, media::PIXEL_FORMAT_I420); + capture_size, kMaxFramesPerSecond, GetVideoPixelFormat()); params.resolution_change_policy = IsFixedAspectRatioTest() ? media::ResolutionChangePolicy::FIXED_ASPECT_RATIO @@ -102,6 +103,11 @@ return params; } +media::VideoPixelFormat +ContentCaptureDeviceBrowserTestBase::GetVideoPixelFormat() const { + return media::VideoPixelFormat::PIXEL_FORMAT_I420; +} + base::TimeDelta ContentCaptureDeviceBrowserTestBase::GetMinCapturePeriod() { return base::Microseconds( base::Time::kMicrosecondsPerSecond /
diff --git a/content/browser/media/capture/content_capture_device_browsertest_base.h b/content/browser/media/capture/content_capture_device_browsertest_base.h index 28a0fab..cc9947d 100644 --- a/content/browser/media/capture/content_capture_device_browsertest_base.h +++ b/content/browser/media/capture/content_capture_device_browsertest_base.h
@@ -11,6 +11,7 @@ #include "build/build_config.h" #include "content/browser/media/capture/fake_video_capture_stack.h" #include "content/public/test/content_browser_test.h" +#include "media/base/video_types.h" #include "media/capture/video_capture_types.h" #include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/skia/include/core/SkColor.h" @@ -54,6 +55,8 @@ gfx::Size GetExpectedSourceSize(); // Returns capture parameters based on the captured source size. + // Capture format can be customized by the subclasses, see + // |GetVideoPixelFormat()|. media::VideoCaptureParams SnapshotCaptureParams(); // Returns the actual minimum capture period the device is using. This should @@ -99,6 +102,9 @@ virtual bool IsFixedAspectRatioTest() const; virtual bool IsCrossSiteCaptureTest() const; + // Used to customize the video pixel format that will be used for capture. + virtual media::VideoPixelFormat GetVideoPixelFormat() const; + // Returns the size of the original content (i.e., not including any // stretching/scaling being done to fit it within a video frame). virtual gfx::Size GetCapturedSourceSize() const = 0;
diff --git a/content/browser/media/capture/fake_video_capture_stack.cc b/content/browser/media/capture/fake_video_capture_stack.cc index 2af1cad..5515600f 100644 --- a/content/browser/media/capture/fake_video_capture_stack.cc +++ b/content/browser/media/capture/fake_video_capture_stack.cc
@@ -6,17 +6,25 @@ #include <stdint.h> +#include <memory> #include <utility> #include "base/bind.h" +#include "base/callback_helpers.h" #include "base/memory/raw_ptr.h" +#include "base/memory/scoped_refptr.h" #include "content/browser/media/capture/frame_test_util.h" +#include "gpu/command_buffer/common/mailbox_holder.h" +#include "gpu/ipc/common/gpu_memory_buffer_support.h" #include "media/base/video_frame.h" +#include "media/base/video_types.h" +#include "media/base/video_util.h" #include "media/capture/video/video_frame_receiver.h" #include "media/capture/video_capture_types.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/skia/include/core/SkColorSpace.h" #include "ui/gfx/geometry/rect.h" +#include "ui/gfx/gpu_memory_buffer.h" namespace content { @@ -47,15 +55,9 @@ buffers_[buffer_id] = std::move(buffer_handle); } - void OnFrameReadyInBuffer( + scoped_refptr<media::VideoFrame> GetVideoFrameFromSharedMemory( media::ReadyFrameInBuffer frame, - std::vector<media::ReadyFrameInBuffer> scaled_frames) override { - const auto it = buffers_.find(frame.buffer_id); - CHECK(it != buffers_.end()); - - CHECK(it->second->is_read_only_shmem_region()); - base::ReadOnlySharedMemoryMapping mapping = - it->second->get_read_only_shmem_region().Map(); + base::ReadOnlySharedMemoryMapping mapping) { CHECK(mapping.IsValid()); const auto& frame_format = media::VideoCaptureFormat( @@ -70,9 +72,12 @@ const_cast<uint8_t*>(static_cast<const uint8_t*>(mapping.memory())), mapping.size(), frame.frame_info->timestamp); CHECK(video_frame); + video_frame->set_metadata(frame.frame_info->metadata); - if (frame.frame_info->color_space.has_value()) + if (frame.frame_info->color_space.has_value()) { video_frame->set_color_space(frame.frame_info->color_space.value()); + } + // This destruction observer will unmap the shared memory when the // VideoFrame goes out-of-scope. video_frame->AddDestructionObserver(base::BindOnce( @@ -83,6 +88,68 @@ [](std::unique_ptr<Buffer::ScopedAccessPermission> access) {}, std::move(frame.buffer_read_permission))); + return video_frame; + } + + scoped_refptr<media::VideoFrame> GetVideoFrameFromGpuMemoryBuffer( + media::ReadyFrameInBuffer frame, + const gfx::GpuMemoryBufferHandle& gmb_handle) { + CHECK(!gmb_handle.is_null()); + CHECK_EQ(frame.frame_info->pixel_format, + media::VideoPixelFormat::PIXEL_FORMAT_NV12); + + gpu::GpuMemoryBufferSupport gmb_support; + std::unique_ptr<gfx::GpuMemoryBuffer> gmb = + gmb_support.CreateGpuMemoryBufferImplFromHandle( + gmb_handle.Clone(), frame.frame_info->coded_size, + gfx::BufferFormat::YUV_420_BIPLANAR, + gfx::BufferUsage::SCANOUT_VEA_CPU_READ, base::DoNothing()); + CHECK(gmb); + + gfx::Size size = gmb->GetSize(); + gpu::MailboxHolder mailbox_holders[media::VideoFrame::kMaxPlanes]; + auto video_frame = media::VideoFrame::WrapExternalGpuMemoryBuffer( + frame.frame_info->visible_rect, size, std::move(gmb), mailbox_holders, + base::BindOnce([](const gpu::SyncToken& token, + std::unique_ptr<gfx::GpuMemoryBuffer> gmb) {}), + frame.frame_info->timestamp); + CHECK(video_frame); + + video_frame->set_metadata(frame.frame_info->metadata); + if (frame.frame_info->color_space.has_value()) { + video_frame->set_color_space(frame.frame_info->color_space.value()); + } + + auto mapped_frame = media::ConvertToMemoryMappedFrame(video_frame); + CHECK(mapped_frame); + + // This destruction observer will notify the video capture device once all + // downstream code is done using the VideoFrame. + mapped_frame->AddDestructionObserver(base::BindOnce( + [](std::unique_ptr<Buffer::ScopedAccessPermission> access) {}, + std::move(frame.buffer_read_permission))); + + return mapped_frame; + } + + void OnFrameReadyInBuffer( + media::ReadyFrameInBuffer frame, + std::vector<media::ReadyFrameInBuffer> scaled_frames) override { + const auto it = buffers_.find(frame.buffer_id); + CHECK(it != buffers_.end()); + + CHECK(it->second->is_read_only_shmem_region() || + it->second->is_gpu_memory_buffer_handle()); + + scoped_refptr<media::VideoFrame> video_frame = nullptr; + if (it->second->is_read_only_shmem_region()) { + video_frame = GetVideoFrameFromSharedMemory( + std::move(frame), it->second->get_read_only_shmem_region().Map()); + } else { + video_frame = GetVideoFrameFromGpuMemoryBuffer( + std::move(frame), it->second->get_gpu_memory_buffer_handle()); + } + // This implementation does not forward scaled frames. capture_stack_->OnReceivedFrame(std::move(video_frame)); } @@ -155,6 +222,10 @@ EXPECT_TRUE(frame->ColorSpace().IsValid()); + if (on_frame_received_) { + on_frame_received_.Run(frame.get()); + } + frames_.emplace_back(std::move(frame)); }
diff --git a/content/browser/media/capture/fake_video_capture_stack.h b/content/browser/media/capture/fake_video_capture_stack.h index 975e0c77..f1be3ea9 100644 --- a/content/browser/media/capture/fake_video_capture_stack.h +++ b/content/browser/media/capture/fake_video_capture_stack.h
@@ -8,6 +8,7 @@ #include <memory> #include <string> +#include "base/callback_forward.h" #include "base/containers/circular_deque.h" #include "base/memory/scoped_refptr.h" #include "base/time/time.h" @@ -58,6 +59,15 @@ // capture stack. void ExpectNoLogMessages(); + using FrameReceivedCallback = + base::RepeatingCallback<void(media::VideoFrame*)>; + + // Sets a callback that will be invoked with a pointer to VideoFrame every + // time new frame gets added to the queue. + void SetFrameReceivedCallback(FrameReceivedCallback callback) { + on_frame_received_ = std::move(callback); + } + private: // A minimal implementation of VideoFrameReceiver that wraps buffers into // VideoFrame instances and forwards all relevant callbacks and data to the @@ -73,6 +83,7 @@ base::circular_deque<std::string> log_messages_; base::circular_deque<scoped_refptr<media::VideoFrame>> frames_; base::TimeDelta last_frame_timestamp_ = base::TimeDelta::Min(); + FrameReceivedCallback on_frame_received_; }; } // namespace content
diff --git a/content/browser/media/capture/frame_test_util.cc b/content/browser/media/capture/frame_test_util.cc index 1ebfdf5..593cf06 100644 --- a/content/browser/media/capture/frame_test_util.cc +++ b/content/browser/media/capture/frame_test_util.cc
@@ -10,7 +10,9 @@ #include "base/numerics/safe_conversions.h" #include "media/base/video_frame.h" +#include "media/base/video_types.h" #include "third_party/skia/include/core/SkColorSpace.h" +#include "third_party/skia/include/core/SkTypes.h" #include "ui/gfx/color_space.h" #include "ui/gfx/color_transform.h" #include "ui/gfx/geometry/rect.h" @@ -38,6 +40,34 @@ } } +void LoadStimsFromYUV(const uint8_t y_src[], + const uint16_t uv_src[], + int width, + TriStim stims[]) { +// https://docs.microsoft.com/en-us/windows/win32/medfound/recommended-8-bit-yuv-formats-for-video-rendering#nv12 +// "All of the Y samples appear first in memory as an array of unsigned char +// values with an even number of lines. The Y plane is followed immediately by +// an array of unsigned char values that contains packed U (Cb) and V (Cr) +// samples. When the combined U-V array is addressed as an array of +// little-endian WORD values, the LSBs contain the U values, and the MSBs +// contain the V values." +#if defined(SK_CPU_BENDIAN) + for (int i = 0; i < width; ++i) { + stims[i].SetPoint( + y_src[i] / 255.0f, + (uv_src[i / 2] >> 8) / 255.0f, // MSB contains U values on LE + (uv_src[i / 2] & 0xFF) / 255.0f); + } +#else + for (int i = 0; i < width; ++i) { + stims[i].SetPoint( + y_src[i] / 255.0f, + (uv_src[i / 2] & 0xFF) / 255.0f, // LSB contains U values on LE + (uv_src[i / 2] >> 8) / 255.0f); + } +#endif +} + // Maps [0.0,1.0]⇒[0,255], rounding to the nearest integer. uint8_t QuantizeAndClamp(float value) { return base::saturated_cast<uint8_t>( @@ -82,13 +112,24 @@ // Convert one row at a time. std::vector<gfx::ColorTransform::TriStim> stims(bitmap.width()); for (int row = 0; row < bitmap.height(); ++row) { - LoadStimsFromYUV(frame.visible_data(media::VideoFrame::kYPlane) + - row * frame.stride(media::VideoFrame::kYPlane), - frame.visible_data(media::VideoFrame::kUPlane) + - (row / 2) * frame.stride(media::VideoFrame::kUPlane), - frame.visible_data(media::VideoFrame::kVPlane) + - (row / 2) * frame.stride(media::VideoFrame::kVPlane), - bitmap.width(), stims.data()); + if (frame.format() == media::VideoPixelFormat::PIXEL_FORMAT_I420) { + LoadStimsFromYUV(frame.visible_data(media::VideoFrame::kYPlane) + + row * frame.stride(media::VideoFrame::kYPlane), + frame.visible_data(media::VideoFrame::kUPlane) + + (row / 2) * frame.stride(media::VideoFrame::kUPlane), + frame.visible_data(media::VideoFrame::kVPlane) + + (row / 2) * frame.stride(media::VideoFrame::kVPlane), + bitmap.width(), stims.data()); + } else { + CHECK_EQ(frame.format(), media::VideoPixelFormat::PIXEL_FORMAT_NV12); + LoadStimsFromYUV( + frame.visible_data(media::VideoFrame::kYPlane) + + row * frame.stride(media::VideoFrame::kYPlane), + reinterpret_cast<const uint16_t*>( + frame.visible_data(media::VideoFrame::kUVPlane) + + (row / 2) * frame.stride(media::VideoFrame::kUVPlane)), + bitmap.width(), stims.data()); + } transform->Transform(stims.data(), stims.size()); StimsToN32Row(stims.data(), bitmap.width(), reinterpret_cast<uint8_t*>(bitmap.getAddr32(0, row)));
diff --git a/content/browser/media/capture/web_contents_video_capture_device_browsertest.cc b/content/browser/media/capture/web_contents_video_capture_device_browsertest.cc index e6028a5..dce8233 100644 --- a/content/browser/media/capture/web_contents_video_capture_device_browsertest.cc +++ b/content/browser/media/capture/web_contents_video_capture_device_browsertest.cc
@@ -6,7 +6,9 @@ #include <tuple> +#include "base/bind.h" #include "base/run_loop.h" +#include "base/test/scoped_feature_list.h" #include "build/build_config.h" #include "build/chromeos_buildflags.h" #include "cc/test/pixel_test_utils.h" @@ -23,15 +25,17 @@ #include "content/public/browser/web_contents.h" #include "content/public/test/browser_test.h" #include "content/shell/browser/shell.h" +#include "media/base/video_frame.h" +#include "media/base/video_types.h" #include "media/base/video_util.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/skia/include/core/SkBitmap.h" +#include "third_party/skia/include/core/SkColor.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/rect_conversions.h" #include "ui/gfx/geometry/rect_f.h" #if BUILDFLAG(IS_WIN) -#include "base/test/scoped_feature_list.h" #include "ui/aura/test/aura_test_utils.h" #include "ui/aura/window.h" #include "ui/aura/window_tree_host.h" @@ -126,7 +130,7 @@ } if (testing::Test::HasFailure()) { - ADD_FAILURE() << "Test failure occurred at this frame; PNG dump: " + ADD_FAILURE() << "Test failure occurred at this frame; PNG dump:\n" << cc::GetPNGDataUrl(rgb_frame); return; } @@ -147,7 +151,7 @@ VLOG(1) << "Observed desired frame."; return; } else { - VLOG(3) << "PNG dump of undesired frame: " + VLOG(3) << "PNG dump of undesired frame:\n" << cc::GetPNGDataUrl(rgb_frame); } } @@ -411,7 +415,8 @@ class WebContentsVideoCaptureDeviceBrowserTestP : public WebContentsVideoCaptureDeviceBrowserTest, - public testing::WithParamInterface<std::tuple<bool, bool, bool>> { + public testing::WithParamInterface< + std::tuple<bool, bool, bool, media::VideoPixelFormat>> { public: bool IsSoftwareCompositingTest() const override { return std::get<0>(GetParam()); @@ -422,6 +427,9 @@ bool IsCrossSiteCaptureTest() const override { return std::get<2>(GetParam()); } + media::VideoPixelFormat GetVideoPixelFormat() const override { + return std::get<3>(GetParam()); + } }; #if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_ANDROID) @@ -434,7 +442,24 @@ testing::Values(false /* variable aspect ratio */, true /* fixed aspect ratio */), testing::Values(false /* page has only a main frame */, - true /* page contains a cross-site iframe */))); + true /* page contains a cross-site iframe */), + testing::Values(media::VideoPixelFormat::PIXEL_FORMAT_I420))); +#elif BUILDFLAG(IS_MAC) +// On MacOS, there is a newly added support for NV12-in-GMB. It relies on GPU +// acceleration, but has a feature detection built-in if the format is +// specified as media::VideoPixelFormat::PIXEL_FORMAT_UNKNOWN. +INSTANTIATE_TEST_SUITE_P( + All, + WebContentsVideoCaptureDeviceBrowserTestP, + testing::Combine( + testing::Values(false /* GPU-accelerated compositing */, + true /* software compositing */), + testing::Values(false /* variable aspect ratio */, + true /* fixed aspect ratio */), + testing::Values(false /* page has only a main frame */, + true /* page contains a cross-site iframe */), + testing::Values(media::VideoPixelFormat::PIXEL_FORMAT_I420, + media::VideoPixelFormat::PIXEL_FORMAT_UNKNOWN))); #else INSTANTIATE_TEST_SUITE_P( All, @@ -445,8 +470,9 @@ testing::Values(false /* variable aspect ratio */, true /* fixed aspect ratio */), testing::Values(false /* page has only a main frame */, - true /* page contains a cross-site iframe */))); -#endif // BUILDFLAG(IS_CHROMEOS_ASH) + true /* page contains a cross-site iframe */), + testing::Values(media::VideoPixelFormat::PIXEL_FORMAT_I420))); +#endif // Tests that the device successfully captures a series of content changes, // whether the browser is running with software compositing or GPU-accelerated @@ -462,6 +488,22 @@ << (IsFixedAspectRatioTest() ? "Fixed Video Aspect Ratio" : "Variable Video Aspect Ratio")); + media::VideoPixelFormat specified_format = GetVideoPixelFormat(); + media::VideoPixelFormat expected_format = specified_format; + if (specified_format == media::VideoPixelFormat::PIXEL_FORMAT_UNKNOWN) { + if (IsSoftwareCompositingTest()) { + expected_format = media::VideoPixelFormat::PIXEL_FORMAT_I420; + } else { + expected_format = media::VideoPixelFormat::PIXEL_FORMAT_NV12; + } + } + + capture_stack()->SetFrameReceivedCallback(base::BindRepeating( + [](media::VideoPixelFormat expected_format, media::VideoFrame* frame) { + EXPECT_EQ(frame->format(), expected_format); + }, + expected_format)); + NavigateToInitialDocument(); AllocateAndStartAndWaitForFirstFrame(); EXPECT_TRUE(shell()->web_contents()->IsBeingCaptured());
diff --git a/content/browser/renderer_host/media/media_stream_dispatcher_host.cc b/content/browser/renderer_host/media/media_stream_dispatcher_host.cc index 2d5acf78..21277cd 100644 --- a/content/browser/renderer_host/media/media_stream_dispatcher_host.cc +++ b/content/browser/renderer_host/media/media_stream_dispatcher_host.cc
@@ -45,7 +45,7 @@ RenderFrameHost* render_frame_host = RenderFrameHost::FromID(render_process_id, render_frame_id); - if (render_frame_host && render_frame_host->IsRenderFrameCreated()) + if (render_frame_host && render_frame_host->IsRenderFrameLive()) render_frame_host->GetRemoteInterfaces()->GetInterface(std::move(receiver)); }
diff --git a/content/browser/renderer_host/navigation_controller_impl.cc b/content/browser/renderer_host/navigation_controller_impl.cc index 679cd1f9..1114de5 100644 --- a/content/browser/renderer_host/navigation_controller_impl.cc +++ b/content/browser/renderer_host/navigation_controller_impl.cc
@@ -4400,7 +4400,7 @@ frame_state.navigation_api_id.value_or(std::u16string()), url, frame_state.item_sequence_number, frame_state.document_sequence_number, - frame_state.navigation_api_state.value_or(std::u16string())); + frame_state.navigation_api_state); DCHECK(entry->url.empty() || pending_origin.CanBeDerivedFrom(GURL(entry->url)));
diff --git a/content/browser/renderer_host/page_impl.cc b/content/browser/renderer_host/page_impl.cc index dc292f9..87ec940 100644 --- a/content/browser/renderer_host/page_impl.cc +++ b/content/browser/renderer_host/page_impl.cc
@@ -253,7 +253,7 @@ bool animate) { // TODO(https://crbug.com/1154852): Asking for the LocalMainFrame interface // before the RenderFrame is created is racy. - if (!GetMainDocument().IsRenderFrameCreated()) + if (!GetMainDocument().IsRenderFrameLive()) return; GetMainDocument().GetAssociatedLocalMainFrame()->UpdateBrowserControlsState(
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc index 792d8e29..d0300c6 100644 --- a/content/browser/renderer_host/render_frame_host_impl.cc +++ b/content/browser/renderer_host/render_frame_host_impl.cc
@@ -2230,7 +2230,7 @@ void RenderFrameHostImpl::GetCanonicalUrl( base::OnceCallback<void(const absl::optional<GURL>&)> callback) { - if (IsRenderFrameCreated()) { + if (IsRenderFrameLive()) { // Validate that the URL returned by the renderer is HTTP(S) only. It is // allowed to be cross-origin. auto validate_and_forward = @@ -2251,7 +2251,7 @@ void RenderFrameHostImpl::GetOpenGraphMetadata( base::OnceCallback<void(blink::mojom::OpenGraphMetadataPtr)> callback) { - if (IsRenderFrameCreated()) { + if (IsRenderFrameLive()) { GetAssociatedLocalFrame()->GetOpenGraphMetadata( base::BindOnce(&ForwardOpenGraphMetadataIfValid, std::move(callback))); } else { @@ -2282,7 +2282,7 @@ const base::flat_map<blink::FrameToken, base::FilePath>& frame_token_map, bool save_with_empty_url, mojo::PendingRemote<mojom::FrameHTMLSerializerHandler> serializer_handler) { - if (!IsRenderFrameCreated()) + if (!IsRenderFrameLive()) return; GetMojomFrameInRenderer()->GetSerializedHtmlWithLocalLinks( url_map, frame_token_map, save_with_empty_url, @@ -2565,7 +2565,7 @@ } service_manager::InterfaceProvider* RenderFrameHostImpl::GetRemoteInterfaces() { - DCHECK(IsRenderFrameCreated()); + DCHECK(IsRenderFrameLive()); return remote_interfaces_.get(); } @@ -3172,7 +3172,7 @@ if (IsPendingDeletion()) return; - if (IsRenderFrameCreated()) { + if (IsRenderFrameLive()) { GetMojomFrameInRenderer()->Delete(intent); // We change the lifecycle state to kRunningUnloadHandlers at the end of @@ -3339,7 +3339,7 @@ // Inner frame trees shouldn't be possible here. DCHECK_EQ(render_frame_host->frame_tree(), main_rfh->frame_tree()); - if (render_frame_host->IsRenderFrameCreated()) + if (render_frame_host->IsRenderFrameLive()) render_frame_host->frame_->ResumeBlockedRequests(); }, base::Unretained(this))); @@ -4524,7 +4524,7 @@ if (proxy) { SetLifecycleState(LifecycleStateImpl::kRunningUnloadHandlers); - if (IsRenderFrameCreated()) { + if (IsRenderFrameLive()) { GetMojomFrameInRenderer()->Unload( proxy->GetRoutingID(), is_loading, proxy->frame_tree_node()->current_replication_state().Clone(), @@ -5478,7 +5478,7 @@ DCHECK(network_service_disconnect_handler_holder_); network_service_disconnect_handler_holder_.FlushForTesting(); // IN-TEST - DCHECK(IsRenderFrameCreated()); + DCHECK(IsRenderFrameLive()); DCHECK(frame_); frame_.FlushForTesting(); // IN-TEST } @@ -7891,7 +7891,7 @@ TRACE_EVENT1("navigation", "RenderFrameHostImpl::Stop", "render_frame_host", this); // Don't call GetAssociatedLocalFrame before the RenderFrame is created. - if (!IsRenderFrameCreated()) + if (!IsRenderFrameLive()) return; GetAssociatedLocalFrame()->StopLoading(); } @@ -9207,7 +9207,7 @@ void RenderFrameHostImpl::UpdateAccessibilityMode() { // Don't update accessibility mode for a frame that hasn't been created yet. - if (!IsRenderFrameCreated()) + if (!IsRenderFrameLive()) return; ui::AXMode ax_mode = delegate_->GetAccessibilityMode(); @@ -9256,7 +9256,7 @@ AXTreeSnapshotCallback callback, mojom::SnapshotAccessibilityTreeParamsPtr params) { // TODO(https://crbug.com/859110): Remove once frame_ can no longer be null. - if (!IsRenderFrameCreated()) + if (!IsRenderFrameLive()) return; GetMojomFrameInRenderer()->SnapshotAccessibilityTree( @@ -9268,7 +9268,7 @@ void RenderFrameHostImpl::RequestDistilledAXTree( AXTreeDistillerCallback callback) { // TODO(https://crbug.com/859110): Remove once frame_ can no longer be null. - if (!IsRenderFrameCreated()) + if (!IsRenderFrameLive()) return; GetMojomFrameInRenderer()->SnapshotAndDistillAXTree( @@ -9349,10 +9349,6 @@ return ip_end_point.address().IsPubliclyRoutable(); } -bool RenderFrameHostImpl::IsRenderFrameCreated() { - return is_render_frame_created(); -} - bool RenderFrameHostImpl::IsRenderFrameLive() { bool is_live = GetProcess()->IsInitializedAndNotDead() && is_render_frame_created();
diff --git a/content/browser/renderer_host/render_frame_host_impl.h b/content/browser/renderer_host/render_frame_host_impl.h index 960fc98..edd55b94d 100644 --- a/content/browser/renderer_host/render_frame_host_impl.h +++ b/content/browser/renderer_host/render_frame_host_impl.h
@@ -401,7 +401,6 @@ blink::AssociatedInterfaceProvider* GetRemoteAssociatedInterfaces() override; content::PageVisibilityState GetVisibilityState() override; bool IsLastCommitIPAddressPubliclyRoutable() const override; - bool IsRenderFrameCreated() override; bool IsRenderFrameLive() override; LifecycleState GetLifecycleState() override; bool IsInLifecycleState(LifecycleState lifecycle_state) override;
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 d4d89d9..dda7275 100644 --- a/content/browser/renderer_host/render_frame_host_impl_browsertest.cc +++ b/content/browser/renderer_host/render_frame_host_impl_browsertest.cc
@@ -333,7 +333,7 @@ MessagesBeforeAndAfterRenderFrameCreated) { // Start with a WebContents that hasn't created its main RenderFrame. WebContents* web_contents = shell()->web_contents(); - ASSERT_FALSE(web_contents->GetMainFrame()->IsRenderFrameCreated()); + ASSERT_FALSE(web_contents->GetMainFrame()->IsRenderFrameLive()); // An attempt to run script via GetAssociatedLocalFrame will do nothing before // the RenderFrame is created, since the message sent to the renderer will get @@ -345,7 +345,7 @@ // Navigating will create the RenderFrame. GURL url(embedded_test_server()->GetURL("/title1.html")); EXPECT_TRUE(NavigateToURL(shell(), url)); - ASSERT_TRUE(web_contents->GetMainFrame()->IsRenderFrameCreated()); + ASSERT_TRUE(web_contents->GetMainFrame()->IsRenderFrameLive()); // Future attempts to run script via GetAssociatedLocalFrame should succeed. // This timed out before the fix, since the message was dropped and no value
diff --git a/content/browser/renderer_host/render_frame_host_manager.cc b/content/browser/renderer_host/render_frame_host_manager.cc index c8f2abaf..dd1e91e 100644 --- a/content/browser/renderer_host/render_frame_host_manager.cc +++ b/content/browser/renderer_host/render_frame_host_manager.cc
@@ -3406,7 +3406,7 @@ // 2) a current RenderFrameHost which has just received a commit IPC from the // renderer, so it must have a live connection to its renderer frame in // order to receive the IPC. - DCHECK(pending_rfh->IsRenderFrameCreated()); + DCHECK(pending_rfh->IsRenderFrameLive()); // We should not have a pending bfcache entry unless bfcache or prerendering // is enabled. Note that in prerendering, the prerendering page information is
diff --git a/content/browser/site_per_process_browsertest.cc b/content/browser/site_per_process_browsertest.cc index 3262ca4..bcc761a 100644 --- a/content/browser/site_per_process_browsertest.cc +++ b/content/browser/site_per_process_browsertest.cc
@@ -1866,7 +1866,6 @@ EXPECT_FALSE( child->current_frame_host()->render_view_host()->IsRenderViewLive()); EXPECT_FALSE(child->current_frame_host()->IsRenderFrameLive()); - EXPECT_FALSE(child->current_frame_host()->IsRenderFrameCreated()); // Now crash the top-level page to clear the child frame. {
diff --git a/content/browser/speech/tts_controller_impl.cc b/content/browser/speech/tts_controller_impl.cc index 70c3bee..644dcef 100644 --- a/content/browser/speech/tts_controller_impl.cc +++ b/content/browser/speech/tts_controller_impl.cc
@@ -452,6 +452,10 @@ return engine_delegate_; } +void TtsControllerImpl::RefreshVoices() { + GetTtsPlatform()->RefreshVoices(); +} + void TtsControllerImpl::Shutdown() { if (tts_platform_) tts_platform_->Shutdown();
diff --git a/content/browser/speech/tts_controller_impl.h b/content/browser/speech/tts_controller_impl.h index f5a718b..2a4bb7db 100644 --- a/content/browser/speech/tts_controller_impl.h +++ b/content/browser/speech/tts_controller_impl.h
@@ -74,6 +74,7 @@ void RemoveUtteranceEventDelegate(UtteranceEventDelegate* delegate) override; void SetTtsEngineDelegate(TtsEngineDelegate* delegate) override; TtsEngineDelegate* GetTtsEngineDelegate() override; + void RefreshVoices() override; void Shutdown();
diff --git a/content/browser/speech/tts_controller_unittest.cc b/content/browser/speech/tts_controller_unittest.cc index 23c75cf3..dc280208 100644 --- a/content/browser/speech/tts_controller_unittest.cc +++ b/content/browser/speech/tts_controller_unittest.cc
@@ -77,6 +77,7 @@ content::BrowserContext* browser_context, const GURL& source_url, std::vector<content::VoiceData>* out_voices) override {} + void RefreshVoices() override {} void SetPlatformImplSupported(bool state) { platform_supported_ = state; } void SetPlatformImplInitialized(bool state) { platform_initialized_ = state; }
diff --git a/content/browser/speech/tts_platform_impl.h b/content/browser/speech/tts_platform_impl.h index adb1b7d..9137346 100644 --- a/content/browser/speech/tts_platform_impl.h +++ b/content/browser/speech/tts_platform_impl.h
@@ -33,6 +33,7 @@ content::BrowserContext* browser_context, const GURL& source_url, std::vector<content::VoiceData>* out_voices) override {} + void RefreshVoices() override {} protected: TtsPlatformImpl() {}
diff --git a/content/public/android/java/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityImpl.java b/content/public/android/java/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityImpl.java index fb07ff2..247205d 100644 --- a/content/public/android/java/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityImpl.java +++ b/content/public/android/java/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityImpl.java
@@ -1660,6 +1660,16 @@ } @CalledByNative + private void handleTextContentChanged(int id) { + AccessibilityEvent event = + buildAccessibilityEvent(id, AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED); + if (event != null) { + event.setContentChangeTypes(AccessibilityEvent.CONTENT_CHANGE_TYPE_TEXT); + requestSendAccessibilityEvent(event); + } + } + + @CalledByNative private void handleEditableTextChanged(int id) { sendAccessibilityEvent(id, AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED); }
diff --git a/content/public/browser/render_frame_host.h b/content/public/browser/render_frame_host.h index a7a7565..0ce03629 100644 --- a/content/public/browser/render_frame_host.h +++ b/content/public/browser/render_frame_host.h
@@ -242,7 +242,7 @@ // can be checked with IsRenderFrameLive(). // NOTE: Due to historical relationships between RenderViewHost and // RenderWidgetHost, the main frame RenderWidgetHostView may initially exist - // before IsRenderFrameCreated() is true, but they would afterward change + // before IsRenderFrameLive() is true, but they would afterward change // values together. It is better to not rely on this behaviour as it is // intended to change. See https://crbug.com/419087. virtual RenderWidgetHostView* GetView() = 0; @@ -638,13 +638,9 @@ // Returns whether the IP address of the last commit was publicly routable. virtual bool IsLastCommitIPAddressPubliclyRoutable() const = 0; - // Returns true if WebContentsObserver::RenderFrameCreated notification has - // been dispatched for this frame, and so a RenderFrameDeleted notification - // will later be dispatched for this frame. - virtual bool IsRenderFrameCreated() = 0; - // Returns whether the RenderFrame in the renderer process has been created // and still has a connection. This is valid for all frames. + // RenderFrameDeleted notification will later be dispatched for this frame. virtual bool IsRenderFrameLive() = 0; // Defines different states the RenderFrameHost can be in during its lifetime,
diff --git a/content/public/browser/tts_controller.h b/content/public/browser/tts_controller.h index f56d337..11a6c87 100644 --- a/content/public/browser/tts_controller.h +++ b/content/public/browser/tts_controller.h
@@ -181,6 +181,10 @@ // embedder. virtual TtsEngineDelegate* GetTtsEngineDelegate() = 0; + // Triggers the TtsPlatform to update its list of voices and relay that update + // through VoicesChanged. + virtual void RefreshVoices() = 0; + // Visible for testing. virtual void SetTtsPlatform(TtsPlatform* tts_platform) = 0; virtual int QueueSize() = 0;
diff --git a/content/public/browser/tts_platform.h b/content/public/browser/tts_platform.h index 1c56d83..85d4f6c 100644 --- a/content/public/browser/tts_platform.h +++ b/content/public/browser/tts_platform.h
@@ -97,6 +97,10 @@ // Given engine delegate and platform voices, returns the finalized voice // ordering used by the controller when exposing voices to clients. virtual void FinalizeVoiceOrdering(std::vector<VoiceData>& voices) = 0; + + // Triggers the TtsPlatform to update its list of voices and relay that update + // through VoicesChanged. + virtual void RefreshVoices() = 0; }; } // namespace content
diff --git a/content/public/test/browser_test_base.cc b/content/public/test/browser_test_base.cc index b58ef821..451fb8c1 100644 --- a/content/public/test/browser_test_base.cc +++ b/content/public/test/browser_test_base.cc
@@ -407,7 +407,7 @@ ui::fuchsia::IgnorePresentCallsForTest(); - // Clear the per-process cached BuildInfo, which was initialized by + // Clear the per-process cached system info, which was initialized by // TestSuite::Initialize(), to prevent a DCHECK for multiple calls during // in-process browser tests. There is not a single TestSuite for all browser // tests and some use the cached values, so skipping the earlier
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index 1138a407..6c0e195ba 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc
@@ -978,8 +978,10 @@ item.SetURLString(WebString::FromUTF16(entry.url)); item.SetItemSequenceNumber(entry.item_sequence_number); item.SetDocumentSequenceNumber(entry.document_sequence_number); - item.SetNavigationApiState( - WebSerializedScriptValue::FromString(WebString::FromUTF16(entry.state))); + if (entry.state) { + item.SetNavigationApiState(WebSerializedScriptValue::FromString( + WebString::FromUTF16(entry.state))); + } return item; } @@ -4140,6 +4142,10 @@ observer.DidSetPageLifecycleState(); } +void RenderFrameImpl::NotifyCurrentHistoryItemChanged() { + SendUpdateState(); +} + void RenderFrameImpl::DidUpdateCurrentHistoryItem() { StartDelayedSyncTimer(); }
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h index 3557a63..8e3d2fe 100644 --- a/content/renderer/render_frame_impl.h +++ b/content/renderer/render_frame_impl.h
@@ -574,6 +574,7 @@ void WillFreezePage() override; void DidOpenDocumentInputStream(const blink::WebURL& url) override; void DidSetPageLifecycleState() override; + void NotifyCurrentHistoryItemChanged() override; void DidUpdateCurrentHistoryItem() override; base::UnguessableToken GetDevToolsFrameToken() override; void AbortClientNavigation() override;
diff --git a/content/services/auction_worklet/seller_worklet.cc b/content/services/auction_worklet/seller_worklet.cc index 003b48e..5af35d31d 100644 --- a/content/services/auction_worklet/seller_worklet.cc +++ b/content/services/auction_worklet/seller_worklet.cc
@@ -33,6 +33,7 @@ #include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/remote.h" #include "services/network/public/mojom/url_loader_factory.mojom.h" +#include "third_party/blink/public/common/interest_group/auction_config.h" #include "third_party/blink/public/mojom/interest_group/interest_group_types.mojom.h" #include "url/gurl.h" #include "url/origin.h" @@ -70,7 +71,7 @@ const GURL& decision_logic_url, const absl::optional<GURL>& trusted_coding_signals_url, const absl::optional<uint16_t> experiment_group_id, - blink::mojom::AuctionAdConfigNonSharedParams& + const blink::AuctionConfig::NonSharedParams& auction_ad_config_non_shared_params, std::vector<v8::Local<v8::Value>>* args) { v8::Isolate* isolate = v8_helper->isolate(); @@ -169,10 +170,9 @@ std::vector<v8::Local<v8::Value>> component_auction_vector; for (const auto& component_auction : component_auctions) { if (!AppendAuctionConfig( - v8_helper, context, component_auction->decision_logic_url, - component_auction->trusted_scoring_signals_url, - experiment_group_id, - *component_auction->auction_ad_config_non_shared_params, + v8_helper, context, component_auction.decision_logic_url, + component_auction.trusted_scoring_signals_url, + experiment_group_id, component_auction.non_shared_params, &component_auction_vector)) { return false; } @@ -267,7 +267,7 @@ void SellerWorklet::ScoreAd( const std::string& ad_metadata_json, double bid, - blink::mojom::AuctionAdConfigNonSharedParamsPtr + const blink::AuctionConfig::NonSharedParams& auction_ad_config_non_shared_params, mojom::ComponentAuctionOtherSellerPtr browser_signals_other_seller, const url::Origin& browser_signal_interest_group_owner, @@ -284,7 +284,7 @@ score_ad_task->ad_metadata_json = ad_metadata_json; score_ad_task->bid = bid; score_ad_task->auction_ad_config_non_shared_params = - std::move(auction_ad_config_non_shared_params); + auction_ad_config_non_shared_params; score_ad_task->browser_signals_other_seller = std::move(browser_signals_other_seller); score_ad_task->browser_signal_interest_group_owner = @@ -324,7 +324,7 @@ } void SellerWorklet::ReportResult( - blink::mojom::AuctionAdConfigNonSharedParamsPtr + const blink::AuctionConfig::NonSharedParams& auction_ad_config_non_shared_params, mojom::ComponentAuctionOtherSellerPtr browser_signals_other_seller, const url::Origin& browser_signal_interest_group_owner, @@ -351,7 +351,7 @@ auto report_result_task = report_result_tasks_.begin(); report_result_task->auction_ad_config_non_shared_params = - std::move(auction_ad_config_non_shared_params); + auction_ad_config_non_shared_params; report_result_task->browser_signals_other_seller = std::move(browser_signals_other_seller); report_result_task->browser_signal_interest_group_owner = @@ -426,7 +426,7 @@ void SellerWorklet::V8State::ScoreAd( const std::string& ad_metadata_json, double bid, - blink::mojom::AuctionAdConfigNonSharedParamsPtr + const blink::AuctionConfig::NonSharedParams& auction_ad_config_non_shared_params, scoped_refptr<TrustedSignals::Result> trusted_scoring_signals, mojom::ComponentAuctionOtherSellerPtr browser_signals_other_seller, @@ -469,7 +469,7 @@ if (!AppendAuctionConfig(v8_helper_.get(), context, decision_logic_url_, trusted_scoring_signals_url_, experiment_group_id_, - *auction_ad_config_non_shared_params, &args)) { + auction_ad_config_non_shared_params, &args)) { PostScoreAdCallbackToUserThread( std::move(callback), /*score=*/0, /*component_auction_modified_bid_params=*/nullptr, @@ -689,7 +689,7 @@ } void SellerWorklet::V8State::ReportResult( - blink::mojom::AuctionAdConfigNonSharedParamsPtr + const blink::AuctionConfig::NonSharedParams& auction_ad_config_non_shared_params, mojom::ComponentAuctionOtherSellerPtr browser_signals_other_seller, const url::Origin& browser_signal_interest_group_owner, @@ -722,7 +722,7 @@ std::vector<v8::Local<v8::Value>> args; if (!AppendAuctionConfig(v8_helper_.get(), context, decision_logic_url_, trusted_scoring_signals_url_, experiment_group_id_, - *auction_ad_config_non_shared_params, &args)) { + auction_ad_config_non_shared_params, &args)) { PostReportResultCallbackToUserThread(std::move(callback), /*signals_for_winner=*/absl::nullopt, /*report_url=*/absl::nullopt,
diff --git a/content/services/auction_worklet/seller_worklet.h b/content/services/auction_worklet/seller_worklet.h index 52c3a0f8..6194cfc 100644 --- a/content/services/auction_worklet/seller_worklet.h +++ b/content/services/auction_worklet/seller_worklet.h
@@ -29,6 +29,7 @@ #include "mojo/public/cpp/bindings/remote.h" #include "services/network/public/mojom/url_loader_factory.mojom.h" #include "third_party/abseil-cpp/absl/types/optional.h" +#include "third_party/blink/public/common/interest_group/auction_config.h" #include "third_party/blink/public/mojom/interest_group/interest_group_types.mojom-forward.h" #include "url/gurl.h" #include "url/origin.h" @@ -80,7 +81,7 @@ void ScoreAd( const std::string& ad_metadata_json, double bid, - blink::mojom::AuctionAdConfigNonSharedParamsPtr + const blink::AuctionConfig::NonSharedParams& auction_ad_config_non_shared_params, mojom::ComponentAuctionOtherSellerPtr browser_signals_other_seller, const url::Origin& browser_signal_interest_group_owner, @@ -92,7 +93,7 @@ ScoreAdCallback callback) override; void SendPendingSignalsRequests() override; void ReportResult( - blink::mojom::AuctionAdConfigNonSharedParamsPtr + const blink::AuctionConfig::NonSharedParams& auction_ad_config_non_shared_params, mojom::ComponentAuctionOtherSellerPtr browser_signals_other_seller, const url::Origin& browser_signal_interest_group_owner, @@ -122,8 +123,7 @@ // safe to access after that happens. std::string ad_metadata_json; double bid; - blink::mojom::AuctionAdConfigNonSharedParamsPtr - auction_ad_config_non_shared_params; + blink::AuctionConfig::NonSharedParams auction_ad_config_non_shared_params; mojom::ComponentAuctionOtherSellerPtr browser_signals_other_seller; url::Origin browser_signal_interest_group_owner; GURL browser_signal_render_url; @@ -157,8 +157,7 @@ // These fields all correspond to the arguments of ReportResult(). They're // std::move()ed when calling out to V8State to run Javascript, so are not // safe to access after that happens. - blink::mojom::AuctionAdConfigNonSharedParamsPtr - auction_ad_config_non_shared_params; + blink::AuctionConfig::NonSharedParams auction_ad_config_non_shared_params; mojom::ComponentAuctionOtherSellerPtr browser_signals_other_seller; url::Origin browser_signal_interest_group_owner; GURL browser_signal_render_url; @@ -210,7 +209,7 @@ void ScoreAd( const std::string& ad_metadata_json, double bid, - blink::mojom::AuctionAdConfigNonSharedParamsPtr + const blink::AuctionConfig::NonSharedParams& auction_ad_config_non_shared_params, scoped_refptr<TrustedSignals::Result> trusted_scoring_signals, mojom::ComponentAuctionOtherSellerPtr browser_signals_other_seller, @@ -223,7 +222,7 @@ ScoreAdCallbackInternal callback); void ReportResult( - blink::mojom::AuctionAdConfigNonSharedParamsPtr + const blink::AuctionConfig::NonSharedParams& auction_ad_config_non_shared_params, mojom::ComponentAuctionOtherSellerPtr browser_signals_other_seller, const url::Origin& browser_signal_interest_group_owner,
diff --git a/content/services/auction_worklet/seller_worklet_unittest.cc b/content/services/auction_worklet/seller_worklet_unittest.cc index 9023c08..e99e5e5 100644 --- a/content/services/auction_worklet/seller_worklet_unittest.cc +++ b/content/services/auction_worklet/seller_worklet_unittest.cc
@@ -30,6 +30,7 @@ #include "testing/gtest/include/gtest/gtest.h" #include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/blink/public/common/features.h" +#include "third_party/blink/public/common/interest_group/auction_config.h" #include "third_party/blink/public/mojom/interest_group/interest_group_types.mojom.h" #include "url/gurl.h" @@ -137,7 +138,7 @@ decision_logic_url_ = GURL("https://url.test/"); trusted_scoring_signals_url_.reset(); auction_ad_config_non_shared_params_ = - blink::mojom::AuctionAdConfigNonSharedParams::New(); + blink::AuctionConfig::NonSharedParams(); top_window_origin_ = url::Origin::Create(GURL("https://window.test/")); experiment_group_id_ = absl::nullopt; @@ -247,7 +248,7 @@ const absl::optional<GURL>& expected_debug_win_report_url, base::OnceClosure done_closure) { seller_worklet->ScoreAd( - ad_metadata_, bid_, auction_ad_config_non_shared_params_.Clone(), + ad_metadata_, bid_, auction_ad_config_non_shared_params_, browser_signals_other_seller_.Clone(), browser_signal_interest_group_owner_, browser_signal_render_url_, browser_signal_ad_components_, browser_signal_bidding_duration_msecs_, @@ -303,7 +304,7 @@ void RunScoreAdOnWorkletExpectingCallbackNeverInvoked( mojom::SellerWorklet* seller_worklet) { seller_worklet->ScoreAd( - ad_metadata_, bid_, auction_ad_config_non_shared_params_.Clone(), + ad_metadata_, bid_, auction_ad_config_non_shared_params_, browser_signals_other_seller_.Clone(), browser_signal_interest_group_owner_, browser_signal_render_url_, browser_signal_ad_components_, browser_signal_bidding_duration_msecs_, @@ -414,7 +415,7 @@ const std::vector<std::string>& expected_errors, base::OnceClosure done_closure) { seller_worklet->ReportResult( - auction_ad_config_non_shared_params_.Clone(), + auction_ad_config_non_shared_params_, browser_signals_other_seller_.Clone(), browser_signal_interest_group_owner_, browser_signal_render_url_, bid_, browser_signal_desireability_, @@ -446,7 +447,7 @@ void RunReportResultExpectingCallbackNeverInvoked( mojom::SellerWorklet* seller_worklet) { seller_worklet->ReportResult( - auction_ad_config_non_shared_params_.Clone(), + auction_ad_config_non_shared_params_, browser_signals_other_seller_.Clone(), browser_signal_interest_group_owner_, browser_signal_render_url_, bid_, browser_signal_desireability_, @@ -554,8 +555,7 @@ double bid_; GURL decision_logic_url_; absl::optional<GURL> trusted_scoring_signals_url_; - blink::mojom::AuctionAdConfigNonSharedParamsPtr - auction_ad_config_non_shared_params_; + blink::AuctionConfig::NonSharedParams auction_ad_config_non_shared_params_; url::Origin top_window_origin_; absl::optional<uint16_t> experiment_group_id_; mojom::ComponentAuctionOtherSellerPtr browser_signals_other_seller_; @@ -2068,29 +2068,28 @@ decision_logic_url_ = GURL("https://example.com/auction.js"); trusted_scoring_signals_url_ = GURL("https://example.com/scoring_signals.json"); - auction_ad_config_non_shared_params_->interest_group_buyers = { + auction_ad_config_non_shared_params_.interest_group_buyers = { url::Origin::Create(GURL("https://buyer1.com")), url::Origin::Create(GURL("https://another-buyer.com"))}; - auction_ad_config_non_shared_params_->auction_signals = + auction_ad_config_non_shared_params_.auction_signals = R"({"is_auction_signals": true})"; - auction_ad_config_non_shared_params_->seller_signals = + auction_ad_config_non_shared_params_.seller_signals = R"({"is_seller_signals": true})"; - auction_ad_config_non_shared_params_->seller_timeout = - base::Milliseconds(200); + auction_ad_config_non_shared_params_.seller_timeout = base::Milliseconds(200); base::flat_map<url::Origin, std::string> per_buyer_signals; per_buyer_signals[url::Origin::Create(GURL("https://a.com"))] = R"({"signals_a": "A"})"; per_buyer_signals[url::Origin::Create(GURL("https://b.com"))] = R"({"signals_b": "B"})"; - auction_ad_config_non_shared_params_->per_buyer_signals = + auction_ad_config_non_shared_params_.per_buyer_signals = std::move(per_buyer_signals); base::flat_map<url::Origin, base::TimeDelta> per_buyer_timeouts; per_buyer_timeouts[url::Origin::Create(GURL("https://a.com"))] = base::Milliseconds(100); - auction_ad_config_non_shared_params_->per_buyer_timeouts = + auction_ad_config_non_shared_params_.per_buyer_timeouts = std::move(per_buyer_timeouts); - auction_ad_config_non_shared_params_->all_buyers_timeout = + auction_ad_config_non_shared_params_.all_buyers_timeout = base::Milliseconds(150); // Add and populate two component auctions, each with one the mandatory @@ -2099,27 +2098,23 @@ // non-shared params. auto& component_auctions = - auction_ad_config_non_shared_params_->component_auctions; + auction_ad_config_non_shared_params_.component_auctions; - component_auctions.emplace_back(blink::mojom::AuctionAdConfig::New()); - component_auctions[0]->auction_ad_config_non_shared_params = - blink::mojom::AuctionAdConfigNonSharedParams::New(); - component_auctions[0]->seller = - url::Origin::Create(GURL("http://component1.com")); - component_auctions[0]->decision_logic_url = - GURL("http://component1.com/script.js"); - component_auctions[0]->auction_ad_config_non_shared_params->seller_timeout = + component_auctions.emplace_back(blink::AuctionConfig()); + component_auctions[0].seller = + url::Origin::Create(GURL("https://component1.com")); + component_auctions[0].decision_logic_url = + GURL("https://component1.com/script.js"); + component_auctions[0].non_shared_params.seller_timeout = base::Milliseconds(111); - component_auctions.emplace_back(blink::mojom::AuctionAdConfig::New()); - component_auctions[1]->auction_ad_config_non_shared_params = - blink::mojom::AuctionAdConfigNonSharedParams::New(); - component_auctions[1]->seller = - url::Origin::Create(GURL("http://component2.com")); - component_auctions[1]->decision_logic_url = - GURL("http://component2.com/script.js"); - component_auctions[1]->trusted_scoring_signals_url = - GURL("http://component2.com/signals.json"); + component_auctions.emplace_back(blink::AuctionConfig()); + component_auctions[1].seller = + url::Origin::Create(GURL("https://component2.com")); + component_auctions[1].decision_logic_url = + GURL("https://component2.com/script.js"); + component_auctions[1].trusted_scoring_signals_url = + GURL("https://component2.com/signals.json"); const char kExpectedJson[] = R"({"seller":"https://example.com",)" @@ -2132,12 +2127,12 @@ R"("perBuyerSignals":{"https://a.com":{"signals_a":"A"},)" R"("https://b.com":{"signals_b":"B"}},)" R"("perBuyerTimeouts":{"https://a.com":100,"*":150},)" - R"("componentAuctions":[{"seller":"http://component1.com",)" - R"("decisionLogicUrl":"http://component1.com/script.js",)" + R"("componentAuctions":[{"seller":"https://component1.com",)" + R"("decisionLogicUrl":"https://component1.com/script.js",)" R"("sellerTimeout":111},)" - R"({"seller":"http://component2.com",)" - R"("decisionLogicUrl":"http://component2.com/script.js",)" - R"("trustedScoringSignalsUrl":"http://component2.com/signals.json"}]})"; + R"({"seller":"https://component2.com",)" + R"("decisionLogicUrl":"https://component2.com/script.js",)" + R"("trustedScoringSignalsUrl":"https://component2.com/signals.json"}]})"; RunReportResultCreatedScriptExpectingResult( "auctionConfig", /*extra_code=*/std::string(), kExpectedJson, /*expected_report_url=*/absl::nullopt); @@ -2154,7 +2149,7 @@ /*expected_report_url=*/absl::nullopt); base::flat_map<url::Origin, base::TimeDelta> per_buyer_timeouts; - auction_ad_config_non_shared_params_->per_buyer_timeouts = + auction_ad_config_non_shared_params_.per_buyer_timeouts = std::move(per_buyer_timeouts); RunReportResultCreatedScriptExpectingResult( @@ -2164,7 +2159,7 @@ R"("perBuyerTimeouts":{}})", /*expected_report_url=*/absl::nullopt); - auction_ad_config_non_shared_params_->all_buyers_timeout = + auction_ad_config_non_shared_params_.all_buyers_timeout = base::Milliseconds(150); RunReportResultCreatedScriptExpectingResult( "auctionConfig", /*extra_code=*/std::string(), @@ -2228,7 +2223,7 @@ for (int j = 0; j < 2; ++j) { base::RunLoop run_loop; seller_worklet->ScoreAd( - ad_metadata_, bid_, auction_ad_config_non_shared_params_.Clone(), + ad_metadata_, bid_, auction_ad_config_non_shared_params_, browser_signals_other_seller_.Clone(), browser_signal_interest_group_owner_, browser_signal_render_url_, browser_signal_ad_components_, browser_signal_bidding_duration_msecs_, @@ -2254,7 +2249,7 @@ for (int j = 0; j < 2; ++j) { base::RunLoop run_loop; seller_worklet->ReportResult( - auction_ad_config_non_shared_params_.Clone(), + auction_ad_config_non_shared_params_, browser_signals_other_seller_.Clone(), browser_signal_interest_group_owner_, browser_signal_render_url_, bid_, browser_signal_desireability_, @@ -2286,7 +2281,7 @@ base::WaitableEvent* event_handle = WedgeV8Thread(v8_helper_.get()); seller_worklet->ScoreAd( - ad_metadata_, bid_, auction_ad_config_non_shared_params_.Clone(), + ad_metadata_, bid_, auction_ad_config_non_shared_params_, browser_signals_other_seller_.Clone(), browser_signal_interest_group_owner_, browser_signal_render_url_, browser_signal_ad_components_, browser_signal_bidding_duration_msecs_, @@ -2318,7 +2313,7 @@ base::WaitableEvent* event_handle = WedgeV8Thread(v8_helper_.get()); seller_worklet->ReportResult( - auction_ad_config_non_shared_params_.Clone(), + auction_ad_config_non_shared_params_, browser_signals_other_seller_.Clone(), browser_signal_interest_group_owner_, browser_signal_render_url_, bid_, browser_signal_desireability_, browser_signal_highest_scoring_other_bid_, @@ -2994,7 +2989,7 @@ TEST_F(SellerWorkletBiddingAndScoringDebugReportingAPIEnabledTest, ForDebuggingOnlyReportsInvalidScoreAdParameter) { // Auction config param is invalid. - auction_ad_config_non_shared_params_->auction_signals = "{invalid json"; + auction_ad_config_non_shared_params_.auction_signals = "{invalid json"; RunScoreAdWithJavascriptExpectingResult( CreateScoreAdScript( "1", @@ -3002,7 +2997,7 @@ forDebuggingOnly.reportAdAuctionWin("https://win.url"))"), 0); // Setting it back to default value to avoid affecting following tests. - auction_ad_config_non_shared_params_->auction_signals = + auction_ad_config_non_shared_params_.auction_signals = R"({"is_auction_signals": true})"; // `ad_metadata_` is an invalid json. @@ -3165,7 +3160,7 @@ for (int i = 0; i < 2; ++i) { base::RunLoop run_loop; seller_worklet->ScoreAd( - ad_metadata_, i + 1, auction_ad_config_non_shared_params_.Clone(), + ad_metadata_, i + 1, auction_ad_config_non_shared_params_, browser_signals_other_seller_.Clone(), browser_signal_interest_group_owner_, browser_signal_render_url_, browser_signal_ad_components_, browser_signal_bidding_duration_msecs_,
diff --git a/content/shell/browser/shell.cc b/content/shell/browser/shell.cc index 7a6e31a..625474b 100644 --- a/content/shell/browser/shell.cc +++ b/content/shell/browser/shell.cc
@@ -125,7 +125,7 @@ // for windows opened from the renderer) then the Shell won't hear about the // main frame being created as a WebContentsObservers. This gives the delegate // a chance to act on the main frame accordingly. - if (raw_web_contents->GetMainFrame()->IsRenderFrameCreated()) + if (raw_web_contents->GetMainFrame()->IsRenderFrameLive()) g_platform->MainFrameCreated(shell); return shell;
diff --git a/content/shell/fuchsia/content_shell.cmx b/content/shell/fuchsia/content_shell.cmx index b1d2a6fd..6fdf012 100644 --- a/content/shell/fuchsia/content_shell.cmx +++ b/content/shell/fuchsia/content_shell.cmx
@@ -15,6 +15,7 @@ "fuchsia.buildinfo.Provider", "fuchsia.device.NameProvider", "fuchsia.fonts.Provider", + "fuchsia.hwinfo.Product", "fuchsia.input.virtualkeyboard.ControllerCreator", "fuchsia.intl.PropertyProvider", "fuchsia.logger.LogSink",
diff --git a/content/test/attribution_simulator_input_parser.cc b/content/test/attribution_simulator_input_parser.cc index 29424be..c09345c 100644 --- a/content/test/attribution_simulator_input_parser.cc +++ b/content/test/attribution_simulator_input_parser.cc
@@ -43,11 +43,6 @@ constexpr char kTimestampKey[] = "timestamp"; -constexpr char kAggregatableTriggerDataKey[] = - "Attribution-Reporting-Register-Aggregatable-Trigger-Data"; -constexpr char kAggregatableValuesKey[] = - "Attribution-Reporting-Register-Aggregatable-Values"; - class AttributionSimulatorInputParser { public: AttributionSimulatorInputParser(base::Time offset_time, @@ -248,8 +243,8 @@ base::TimeDelta expiry; AttributionFilterData filter_data; - if (!ParseAttributionSource( - source_dict, + if (!ParseAttributionEvent( + source_dict, "Attribution-Reporting-Register-Source", base::BindLambdaForTesting([&](const base::Value::Dict& dict) { source_event_id = ParseRequiredUint64(dict, "source_event_id"); destination_origin = ParseOrigin(dict, "destination"); @@ -284,22 +279,34 @@ if (!EnsureDictionary(trigger)) return; - const base::Value::Dict& dict = trigger.GetDict(); + const base::Value::Dict& trigger_dict = trigger.GetDict(); - base::Time trigger_time = ParseTime(dict, kTimestampKey); - url::Origin reporting_origin = ParseOrigin(dict, "reporting_origin"); - url::Origin destination_origin = ParseOrigin(dict, "destination_origin"); + base::Time trigger_time = ParseTime(trigger_dict, kTimestampKey); + url::Origin reporting_origin = + ParseOrigin(trigger_dict, "reporting_origin"); + url::Origin destination_origin = + ParseOrigin(trigger_dict, "destination_origin"); - absl::optional<uint64_t> debug_key = - ParseOptionalUint64(dict, "Attribution-Reporting-Trigger-Debug-Key"); - AttributionFilterData filters = - ParseFilterData(dict, "Attribution-Reporting-Filters", - &AttributionFilterData::FromTriggerFilterValues); - std::vector<AttributionTrigger::EventTriggerData> event_triggers = - ParseEventTriggers(dict); + absl::optional<uint64_t> debug_key; + AttributionFilterData filters; + std::vector<AttributionTrigger::EventTriggerData> event_triggers; + AttributionAggregatableTrigger aggregatable_trigger; - AttributionAggregatableTrigger aggregatable_trigger = - ParseAggregatableTrigger(dict); + if (!ParseAttributionEvent( + trigger_dict, + "Attribution-Reporting-Register-Trigger", + base::BindLambdaForTesting( + [&](const base::Value::Dict& dict) { + debug_key = ParseOptionalUint64(dict, "debug_key"); + filters = ParseFilterData( + dict, "filters", + &AttributionFilterData::FromTriggerFilterValues); + event_triggers = ParseEventTriggers(dict); + + aggregatable_trigger = ParseAggregatableTrigger(dict); + }))) { + return; + } if (has_error()) return; @@ -319,8 +326,7 @@ const base::Value::Dict& cfg) { std::vector<AttributionTrigger::EventTriggerData> event_triggers; - static constexpr char kKey[] = - "Attribution-Reporting-Register-Event-Trigger"; + static constexpr char kKey[] = "event_trigger_data"; const base::Value* values = cfg.Find(kKey); if (!values) @@ -466,14 +472,13 @@ return source_type; } - bool ParseAttributionSource( + bool ParseAttributionEvent( const base::Value::Dict& value, + base::StringPiece key, base::OnceCallback<void(const base::Value::Dict&)> callback) { - static constexpr char kKey[] = "Attribution-Reporting-Register-Source"; + auto context = PushContext(key); - auto context = PushContext(kKey); - - const base::Value* dict = value.Find(kKey); + const base::Value* dict = value.Find(key); if (!dict) { *Error() << "must be present"; return false; @@ -646,17 +651,16 @@ std::vector<blink::mojom::AttributionAggregatableTriggerDataPtr> ParseAggregatableTriggerData(const base::Value::Dict& dict) { + static constexpr char kKey[] = "aggregatable_trigger_data"; + std::vector<blink::mojom::AttributionAggregatableTriggerDataPtr> aggregatable_triggers; - auto context = PushContext(kAggregatableTriggerDataKey); - - const base::Value* values = dict.Find(kAggregatableTriggerDataKey); - if (!values) { - *Error() << "must be present"; + const base::Value* values = dict.Find(kKey); + if (!values) return aggregatable_triggers; - } + auto context = PushContext(kKey); ParseList( *values, base::BindLambdaForTesting( @@ -697,15 +701,15 @@ AttributionAggregatableTrigger::Values ParseAggregatableValues( const base::Value::Dict& dict) { + static constexpr char kKey[] = "aggregatable_values"; + AttributionAggregatableTrigger::Values aggregatable_values; - auto context = PushContext(kAggregatableValuesKey); - - const base::Value* value = dict.Find(kAggregatableValuesKey); - if (!value) { - *Error() << "must be present"; + const base::Value* value = dict.Find(kKey); + if (!value) return aggregatable_values; - } + + auto context = PushContext(kKey); if (!EnsureDictionary(*value)) return aggregatable_values; @@ -726,11 +730,6 @@ AttributionAggregatableTrigger ParseAggregatableTrigger( const base::Value::Dict& dict) { - if (!dict.Find(kAggregatableTriggerDataKey) && - !dict.Find(kAggregatableValuesKey)) { - return AttributionAggregatableTrigger(); - } - auto mojo = blink::mojom::AttributionAggregatableTrigger::New( ParseAggregatableTriggerData(dict), ParseAggregatableValues(dict));
diff --git a/content/test/attribution_simulator_input_parser_unittest.cc b/content/test/attribution_simulator_input_parser_unittest.cc index 38bb1229..b7700d3c 100644 --- a/content/test/attribution_simulator_input_parser_unittest.cc +++ b/content/test/attribution_simulator_input_parser_unittest.cc
@@ -261,11 +261,13 @@ "timestamp": "1643235576123", "reporting_origin": "https://a.r.test", "destination_origin": " https://a.d1.test", - "trigger_data": "10", - "event_source_trigger_data": "3", - "priority": "-5", - "deduplication_key": "123", - "debug_key": "14" + "Attribution-Reporting-Register-Trigger": { + "trigger_data": "10", + "event_source_trigger_data": "3", + "priority": "-5", + "deduplication_key": "123", + "debug_key": "14" + } } ]})json"; @@ -286,40 +288,45 @@ "timestamp": "1643235576123", "reporting_origin": "https://a.r.test", "destination_origin": " https://a.d1.test", - "Attribution-Reporting-Register-Event-Trigger": [ - { - "trigger_data": "10", - "priority": "-5", - "deduplication_key": "123", - "filters": { - "x": ["y"] + "Attribution-Reporting-Register-Trigger": { + "event_trigger_data": [ + { + "trigger_data": "10", + "priority": "-5", + "deduplication_key": "123", + "filters": { + "x": ["y"] + }, + "not_filters": { + "z": [] + } }, - "not_filters": { - "z": [] - } - }, - {} - ], - "Attribution-Reporting-Trigger-Debug-Key": "14", - "Attribution-Reporting-Filters": { - "a": ["b", "c"], - "d": [] + {} + ], + "debug_key": "14", + "filters": { + "a": ["b", "c"], + "d": [] + } } }, { "timestamp": "1643235575123", "reporting_origin": "https://b.r.test", - "destination_origin": " https://a.d2.test" + "destination_origin": " https://a.d2.test", + "Attribution-Reporting-Register-Trigger": {} }, { "timestamp": "1643235574123", "reporting_origin": "https://b.r.test", "destination_origin": " https://a.d2.test", - "Attribution-Reporting-Register-Aggregatable-Trigger-Data": [{ - "source_keys": ["a"], - "key_piece": "0x1" - }], - "Attribution-Reporting-Register-Aggregatable-Values": {"a": 1} + "Attribution-Reporting-Register-Trigger": { + "aggregatable_trigger_data": [{ + "source_keys": ["a"], + "key_piece": "0x1" + }], + "aggregatable_values": {"a": 1} + } } ]})json"; @@ -424,7 +431,8 @@ "triggers": [{ "timestamp": "1643235575123", "reporting_origin": "https://b.r.test", - "destination_origin": " https://a.d2.test" + "destination_origin": " https://a.d2.test", + "Attribution-Reporting-Register-Trigger": {} }] })json"; @@ -798,21 +806,24 @@ R"(["triggers"][0]["timestamp"]: must be an integer number of)", R"json({"triggers": [{ "reporting_origin": "https://a.r.test", - "destination_origin": " https://a.d1.test" + "destination_origin": " https://a.d1.test", + "Attribution-Reporting-Register-Trigger": {} }]})json", }, { R"(["triggers"][0]["destination_origin"]: must be a valid, secure origin)", R"json({"triggers": [{ "timestamp": "1643235576000", - "reporting_origin": "https://a.r.test" + "reporting_origin": "https://a.r.test", + "Attribution-Reporting-Register-Trigger": {} }]})json", }, { R"(["triggers"][0]["reporting_origin"]: must be a valid, secure origin)", R"json({"triggers": [{ "timestamp": "1643235576000", - "destination_origin": " https://a.d1.test" + "destination_origin": " https://a.d1.test", + "Attribution-Reporting-Register-Trigger": {} }]})json", }, { @@ -820,120 +831,132 @@ R"json({"triggers": ""})json", }, { - R"(["triggers"][0]["Attribution-Reporting-Register-Event-Trigger"]: must be a list)", + R"(["triggers"][0]["Attribution-Reporting-Register-Trigger"]: must be present)", + R"json({"triggers": [{}]})json", + }, + { + R"(["triggers"][0]["Attribution-Reporting-Register-Trigger"]: must be a dictionary)", R"json({"triggers": [{ - "timestamp": "1643235576000", - "reporting_origin": "https://a.r.test", - "destination_origin": " https://a.d1.test", - "Attribution-Reporting-Register-Event-Trigger": 1 + "Attribution-Reporting-Register-Trigger": "" }]})json", }, { - R"(["triggers"][0]["Attribution-Reporting-Register-Aggregatable-Trigger-Data"]: must be a list)", + R"(["triggers"][0]["Attribution-Reporting-Register-Trigger"]["event_trigger_data"]: must be a list)", R"json({"triggers": [{ - "timestamp": "1643235576000", - "reporting_origin": "https://a.r.test", - "destination_origin": " https://a.d1.test", - "Attribution-Reporting-Register-Aggregatable-Trigger-Data": 5 - }]})json", - }, - { - R"(["triggers"][0]["Attribution-Reporting-Register-Aggregatable-Trigger-Data"][0]: must be a dictionary)", - R"json({"triggers": [{ - "timestamp": "1643235576000", - "reporting_origin": "https://a.r.test", - "destination_origin": " https://a.d1.test", - "Attribution-Reporting-Register-Aggregatable-Trigger-Data": [ 5 ] - }]})json", - }, - { - R"(["triggers"][0]["Attribution-Reporting-Register-Aggregatable-Trigger-Data"][0]["source_keys"]: must be present)", - R"json({"triggers": [{ - "timestamp": "1643235576000", - "reporting_origin": "https://a.r.test", - "destination_origin": " https://a.d1.test", - "Attribution-Reporting-Register-Aggregatable-Trigger-Data": [{}] - }]})json", - }, - { - R"(["triggers"][0]["Attribution-Reporting-Register-Aggregatable-Trigger-Data"][0]["source_keys"]: must be a list)", - R"json({"triggers": [{ - "timestamp": "1643235576000", - "reporting_origin": "https://a.r.test", - "destination_origin": " https://a.d1.test", - "Attribution-Reporting-Register-Aggregatable-Trigger-Data": [{ - "source_keys": "a" - }] - }]})json", - }, - { - R"(["triggers"][0]["Attribution-Reporting-Register-Aggregatable-Trigger-Data"][0]["source_keys"][0]: must be a string)", - R"json({"triggers": [{ - "timestamp": "1643235576000", - "reporting_origin": "https://a.r.test", - "destination_origin": " https://a.d1.test", - "Attribution-Reporting-Register-Aggregatable-Trigger-Data": [{ - "source_keys": [ 5 ] - }] - }]})json", - }, - { - R"(["triggers"][0]["Attribution-Reporting-Register-Aggregatable-Trigger-Data"][0]["key_piece"]: must be a uint128 formatted as a base-16 string)", - R"json({"triggers": [{ - "timestamp": "1643235576000", - "reporting_origin": "https://a.r.test", - "destination_origin": " https://a.d1.test", - "Attribution-Reporting-Register-Aggregatable-Trigger-Data": [{ - "source_keys": [ "a" ], - "key_piece": "0xG" - }] - }]})json", - }, - { - R"(["triggers"][0]["Attribution-Reporting-Register-Aggregatable-Values"]: must be a dictionary)", - R"json({"triggers": [{ - "timestamp": "1643235576000", - "reporting_origin": "https://a.r.test", - "destination_origin": " https://a.d1.test", - "Attribution-Reporting-Register-Aggregatable-Values": 5 - }]})json", - }, - { - R"(["triggers"][0]["Attribution-Reporting-Register-Aggregatable-Values"]["a"]: must be a positive integer)", - R"json({"triggers": [{ - "timestamp": "1643235576000", - "reporting_origin": "https://a.r.test", - "destination_origin": " https://a.d1.test", - "Attribution-Reporting-Register-Aggregatable-Values": { - "a": -5 + "Attribution-Reporting-Register-Trigger": { + "timestamp": "1643235576000", + "reporting_origin": "https://a.r.test", + "destination_origin": " https://a.d1.test", + "event_trigger_data": 1 } }]})json", }, { - R"(["triggers"][0]["Attribution-Reporting-Register-Event-Trigger"][0]: must be a dictionary)", + R"(["triggers"][0]["Attribution-Reporting-Register-Trigger"]["aggregatable_trigger_data"]: must be a list)", + R"json({"triggers": [{ + "Attribution-Reporting-Register-Trigger": { + "timestamp": "1643235576000", + "reporting_origin": "https://a.r.test", + "destination_origin": " https://a.d1.test", + "aggregatable_trigger_data": 5 + } + }]})json", + }, + { + R"(["triggers"][0]["Attribution-Reporting-Register-Trigger"]["aggregatable_trigger_data"][0]: must be a dictionary)", + R"json({"triggers": [{ + "Attribution-Reporting-Register-Trigger": { + "timestamp": "1643235576000", + "reporting_origin": "https://a.r.test", + "destination_origin": " https://a.d1.test", + "aggregatable_trigger_data": [ 5 ] + } + }]})json", + }, + { + R"(["triggers"][0]["Attribution-Reporting-Register-Trigger"]["aggregatable_trigger_data"][0]["source_keys"]: must be present)", + R"json({"triggers": [{ + "Attribution-Reporting-Register-Trigger": { + "timestamp": "1643235576000", + "reporting_origin": "https://a.r.test", + "destination_origin": " https://a.d1.test", + "aggregatable_trigger_data": [{}] + } + }]})json", + }, + { + R"(["triggers"][0]["Attribution-Reporting-Register-Trigger"]["aggregatable_trigger_data"][0]["source_keys"]: must be a list)", + R"json({"triggers": [{ + "Attribution-Reporting-Register-Trigger": { + "timestamp": "1643235576000", + "reporting_origin": "https://a.r.test", + "destination_origin": " https://a.d1.test", + "aggregatable_trigger_data": [{ + "source_keys": "a" + }] + } + }]})json", + }, + { + R"(["triggers"][0]["Attribution-Reporting-Register-Trigger"]["aggregatable_trigger_data"][0]["source_keys"][0]: must be a string)", + R"json({"triggers": [{ + "Attribution-Reporting-Register-Trigger": { + "timestamp": "1643235576000", + "reporting_origin": "https://a.r.test", + "destination_origin": " https://a.d1.test", + "aggregatable_trigger_data": [{ + "source_keys": [ 5 ] + }] + } + }]})json", + }, + { + R"(["triggers"][0]["Attribution-Reporting-Register-Trigger"]["aggregatable_trigger_data"][0]["key_piece"]: must be a uint128 formatted as a base-16 string)", + R"json({"triggers": [{ + "Attribution-Reporting-Register-Trigger": { + "timestamp": "1643235576000", + "reporting_origin": "https://a.r.test", + "destination_origin": " https://a.d1.test", + "aggregatable_trigger_data": [{ + "source_keys": [ "a" ], + "key_piece": "0xG" + }] + } + }]})json", + }, + { + R"(["triggers"][0]["Attribution-Reporting-Register-Trigger"]["aggregatable_values"]: must be a dictionary)", + R"json({"triggers": [{ + "Attribution-Reporting-Register-Trigger": { + "timestamp": "1643235576000", + "reporting_origin": "https://a.r.test", + "destination_origin": " https://a.d1.test", + "aggregatable_values": 5 + } + }]})json", + }, + { + R"(["triggers"][0]["Attribution-Reporting-Register-Trigger"]["aggregatable_values"]["a"]: must be a positive integer)", + R"json({"triggers": [{ + "Attribution-Reporting-Register-Trigger": { + "timestamp": "1643235576000", + "reporting_origin": "https://a.r.test", + "destination_origin": " https://a.d1.test", + "aggregatable_values": { + "a": -5 + } + } + }]})json", + }, + { + R"(["triggers"][0]["Attribution-Reporting-Register-Trigger"]["event_trigger_data"][0]: must be a dictionary)", R"json({"triggers":[{ - "timestamp": "1643235576000", - "reporting_origin": "https://a.r.test", - "destination_origin": " https://a.d1.test", - "Attribution-Reporting-Register-Event-Trigger":[true] - }]})json", - }, - { - R"(["triggers"][0]["Attribution-Reporting-Register-Aggregatable-Trigger-Data"]: must be present)", - R"json({"triggers": [{ - "timestamp": "1643235576000", - "reporting_origin": "https://a.r.test", - "destination_origin": " https://a.d1.test", - "Attribution-Reporting-Register-Aggregatable-Values": {} - }]})json", - }, - { - R"(["triggers"][0]["Attribution-Reporting-Register-Aggregatable-Values"]: must be present)", - R"json({"triggers": [{ - "timestamp": "1643235576000", - "reporting_origin": "https://a.r.test", - "destination_origin": " https://a.d1.test", - "Attribution-Reporting-Register-Aggregatable-Trigger-Data": [] + "Attribution-Reporting-Register-Trigger": { + "timestamp": "1643235576000", + "reporting_origin": "https://a.r.test", + "destination_origin": " https://a.d1.test", + "event_trigger_data":[true] + } }]})json", }, {
diff --git a/content/test/data/accessibility/html/popup-api-expected-blink.txt b/content/test/data/accessibility/html/popup-api-expected-blink.txt index 4a84b4fa..1bf4841 100644 --- a/content/test/data/accessibility/html/popup-api-expected-blink.txt +++ b/content/test/data/accessibility/html/popup-api-expected-blink.txt
@@ -13,24 +13,44 @@ ++++++button collapsed name='Button pointing to hidden popup' ++++++++staticText name='Button pointing to hidden popup' ++++++++++inlineTextBox name='Button pointing to hidden popup' +++++++textField +++++++++genericContainer +++++++staticText name='Text input pointing to hidden popup ' +++++++++inlineTextBox name='Text input pointing to hidden popup ' ++++++genericContainer ignored invisible ++++++++staticText ignored name='Popup' ++++++button description='Hint' name='Show button pointing to hidden hint' descriptionFrom=popupElement ++++++++staticText name='Show button pointing to hidden hint' ++++++++++inlineTextBox name='Show button pointing to hidden hint' +++++++searchBox description='Hint' descriptionFrom=popupElement +++++++++genericContainer +++++++staticText name='Search input pointing to hidden hint ' +++++++++inlineTextBox name='Search input pointing to hidden hint ' ++++++genericContainer ignored invisible ++++++++staticText ignored name='Hint' ++++++button name='Hide button pointing to hidden async' ++++++++staticText name='Hide button pointing to hidden async' ++++++++++inlineTextBox name='Hide button pointing to hidden async' +++++++textField +++++++++genericContainer +++++++staticText name='Email input pointing to hidden async ' +++++++++inlineTextBox name='Email input pointing to hidden async ' ++++++genericContainer ignored invisible ++++++++staticText ignored name='Async' ++++++button name='Button pointing to showing popup' ++++++++staticText name='Button pointing to showing popup' ++++++++++inlineTextBox name='Button pointing to showing popup' +++++++textField +++++++++genericContainer +++++++staticText name='Tel input pointing to showing popup ' +++++++++inlineTextBox name='Tel input pointing to showing popup ' ++++++button description='Hint (nested)' name='Show button pointing to showing hint' descriptionFrom=popupElement ++++++++staticText name='Show button pointing to showing hint' ++++++++++inlineTextBox name='Show button pointing to showing hint' +++++++textField description='Hint (nested)' descriptionFrom=popupElement +++++++++genericContainer +++++++staticText name='Url input pointing to showing hint ' +++++++++inlineTextBox name='Url input pointing to showing hint ' ++++++genericContainer ++++++++staticText name='Popup' ++++++++++inlineTextBox name='Popup' @@ -40,18 +60,30 @@ ++++++button name='Hide button pointing to showing async' ++++++++staticText name='Hide button pointing to showing async' ++++++++++inlineTextBox name='Hide button pointing to showing async' +++++++textField +++++++++genericContainer +++++++staticText name='Text input pointing to showing async ' +++++++++inlineTextBox name='Text input pointing to showing async ' ++++++genericContainer ++++++++staticText name='Async' ++++++++++inlineTextBox name='Async' ++++++button name='Button pointing to non-popup' ++++++++staticText name='Button pointing to non-popup' ++++++++++inlineTextBox name='Button pointing to non-popup' +++++++textField +++++++++genericContainer +++++++staticText name='Text input pointing to non-popup' +++++++++inlineTextBox name='Text input pointing to non-popup' ++++++genericContainer ++++++++staticText name='No popup attribute' ++++++++++inlineTextBox name='No popup attribute' ++++++button name='Button pointing to invalid popup value' ++++++++staticText name='Button pointing to invalid popup value' ++++++++++inlineTextBox name='Button pointing to invalid popup value' +++++++textField +++++++++genericContainer +++++++staticText name='Text input pointing to invalid popup value' +++++++++inlineTextBox name='Text input pointing to invalid popup value' ++++++genericContainer ++++++++staticText name='Invalid popup attribute value' ++++++++++inlineTextBox name='Invalid popup attribute value'
diff --git a/content/test/data/accessibility/html/popup-api.html b/content/test/data/accessibility/html/popup-api.html index 7cc493c2..f5331c2 100644 --- a/content/test/data/accessibility/html/popup-api.html +++ b/content/test/data/accessibility/html/popup-api.html
@@ -1,23 +1,27 @@ -<html> -<body> <div popup=popup>Div popup</div> <ul popup=popup role=listbox><li>Listbox role on ul</li></ul> <ul popup=popup role=listbox><li>Listbox role on ul</li></ul> <details popup=popup><summary>summary/details popup</summary></details> <button togglepopup=popup1>Button pointing to hidden popup</button> +<input type=text togglepopup=popup1>Text input pointing to hidden popup</button> <div popup=popup id=popup1>Popup</div> <button showpopup=hint1>Show button pointing to hidden hint</button> +<input type=search showpopup=hint1>Search input pointing to hidden hint</button> <div popup=hint id=hint1>Hint</div> <button hidepopup=async1>Hide button pointing to hidden async</button> +<input type=email hidepopup=async1>Email input pointing to hidden async</button> <div popup=async id=async1>Async</div> <button togglepopup=popup2>Button pointing to showing popup</button> +<input type=tel togglepopup=popup2>Tel input pointing to showing popup</button> <button showpopup=hint2>Show button pointing to showing hint</button> +<input type=url showpopup=hint2>Url input pointing to showing hint</button> <div popup=popup id=popup2>Popup <div popup=hint id=hint2>Hint (nested)</div> </div> <button hidepopup=async2>Hide button pointing to showing async</button> +<input type=text hidepopup=async2>Text input pointing to showing async</button> <div popup=async id=async2>Async</div> <script> popup2.showPopup(); @@ -26,8 +30,8 @@ </script> <button togglepopup=noattr>Button pointing to non-popup</button> +<input type=text togglepopup=noattr>Text input pointing to non-popup</button> <div id=noattr>No popup attribute</div> <button togglepopup=badattr>Button pointing to invalid popup value</button> +<input type=text togglepopup=badattr>Text input pointing to invalid popup value</button> <div id=badattr popup=invalid_value>Invalid popup attribute value</div> -</body> -</html>
diff --git a/content/test/data/attribution_reporting/interop/README.md b/content/test/data/attribution_reporting/interop/README.md index 69929ad0..7f0685b3f 100644 --- a/content/test/data/attribution_reporting/interop/README.md +++ b/content/test/data/attribution_reporting/interop/README.md
@@ -121,77 +121,79 @@ "url": "https://reporting.example", "response": { - // Optional list of zero or more event trigger data. - "Attribution-Reporting-Register-Event-Trigger": [ - { - // Optional uint64 formatted as a base-10 string. - // Defaults to 0. - "trigger_data": "3", + "Attribution-Reporting-Register-Trigger": { + // Optional list of zero or more event trigger data. + "event_trigger_data": [ + { + // Optional uint64 formatted as a base-10 string. + // Defaults to 0. + "trigger_data": "3", - // Optional int64 formatted as a base-10 string. - // Defaults to 0. - "priority": "-456", + // Optional int64 formatted as a base-10 string. + // Defaults to 0. + "priority": "-456", - // Optional uint64 formatted as a base-10 string. Defaults to - // null. - "deduplication_key": "654", + // Optional uint64 formatted as a base-10 string. Defaults to + // null. + "deduplication_key": "654", - // Optional dictionary of filters and corresponding values. - // Defaults to empty. - "filters": { - "a": ["b", "c"], - "d": [] - }, + // Optional dictionary of filters and corresponding values. + // Defaults to empty. + "filters": { + "a": ["b", "c"], + "d": [] + }, - // Optional dictionary of negated filters and corresponding - // values. Defaults to empty. - "not_filters": { - "x": ["y"], - "z": [] + // Optional dictionary of negated filters and corresponding + // values. Defaults to empty. + "not_filters": { + "x": ["y"], + "z": [] + } } - } - ], + ], - // Optional list of zero or more aggregatable trigger data. - "Attribution-Reporting-Register-Aggregatable-Trigger-Data": [ - { - // Required uint128 formatted as a base-16 string. - "key_piece": "0x10", + // Optional list of zero or more aggregatable trigger data. + "aggregatable_trigger_data": [ + { + // Required uint128 formatted as a base-16 string. + "key_piece": "0x10", - // Required list of key identifiers. - "source_keys": ["a"], + // Required list of key identifiers. + "source_keys": ["a"], - // Optional dictionary of filters and corresponding values. - // Defaults to empty. - "filters": { - "a": ["b", "c"], - "d": [] - }, + // Optional dictionary of filters and corresponding values. + // Defaults to empty. + "filters": { + "a": ["b", "c"], + "d": [] + }, - // Optional dictionary of negated filters and corresponding - // values. Defaults to empty. - "not_filters": { - "x": ["y"], - "z": [] + // Optional dictionary of negated filters and corresponding + // values. Defaults to empty. + "not_filters": { + "x": ["y"], + "z": [] + } } + ], + + // Optional dictionary of key identifiers and corresponding + // values. + "aggregatable_values": { + "a": 123 + }, + + // Optional uint64 formatted as a base-10 string. Defaults to + // null. + "debug_key": "789", + + // Optional dictionary of filters and corresponding values. + // Defaults to empty. + "filters": { + "a": ["b", "c"], + "d": [] } - ], - - // Optional dictionary of key identifiers and corresponding - // values. - "Attribution-Reporting-Register-Aggregatable-Values": { - "a": 123 - }, - - // Optional uint64 formatted as a base-10 string. Defaults to - // null. - "Attribution-Reporting-Trigger-Debug-Key": "789", - - // Optional dictionary of filters and corresponding values. - // Defaults to empty. - "Attribution-Reporting-Filters": { - "a": ["b", "c"], - "d": [] } } }
diff --git a/content/test/data/attribution_reporting/interop/basic.json b/content/test/data/attribution_reporting/interop/basic.json index 0a8b47a..9d258375 100644 --- a/content/test/data/attribution_reporting/interop/basic.json +++ b/content/test/data/attribution_reporting/interop/basic.json
@@ -30,11 +30,13 @@ "responses": [{ "url": "https://reporter.test/register-trigger", "response": { - "Attribution-Reporting-Register-Event-Trigger": [ - { - "trigger_data": "7" - } - ] + "Attribution-Reporting-Register-Trigger": { + "event_trigger_data": [ + { + "trigger_data": "7" + } + ] + } } }] }
diff --git a/content/test/data/attribution_reporting/interop/basic_aggregatable.json b/content/test/data/attribution_reporting/interop/basic_aggregatable.json index 3a5aa76c..2382659 100644 --- a/content/test/data/attribution_reporting/interop/basic_aggregatable.json +++ b/content/test/data/attribution_reporting/interop/basic_aggregatable.json
@@ -36,19 +36,21 @@ "responses": [{ "url": "https://reporter.test/register-trigger", "response": { - "Attribution-Reporting-Register-Event-Trigger": [ - { - "trigger_data": "7" + "Attribution-Reporting-Register-Trigger": { + "event_trigger_data": [ + { + "trigger_data": "7" + } + ], + "aggregatable_trigger_data": [ + { + "source_keys": ["a"], + "key_piece": "0x400" + } + ], + "aggregatable_values": { + "a": 123 } - ], - "Attribution-Reporting-Register-Aggregatable-Trigger-Data": [ - { - "source_keys": ["a"], - "key_piece": "0x400" - } - ], - "Attribution-Reporting-Register-Aggregatable-Values": { - "a": 123 } } }]
diff --git a/content/test/data/attribution_reporting/interop/deactivated_source.json b/content/test/data/attribution_reporting/interop/deactivated_source.json index 065296b..453a155 100644 --- a/content/test/data/attribution_reporting/interop/deactivated_source.json +++ b/content/test/data/attribution_reporting/interop/deactivated_source.json
@@ -49,11 +49,13 @@ "responses": [{ "url": "https://reporter.test/register-trigger", "response": { - "Attribution-Reporting-Register-Event-Trigger": [ - { - "trigger_data": "1" - } - ] + "Attribution-Reporting-Register-Trigger": { + "event_trigger_data": [ + { + "trigger_data": "1" + } + ] + } } }] }, @@ -66,11 +68,13 @@ "responses": [{ "url": "https://reporter.test/register-trigger", "response": { - "Attribution-Reporting-Register-Event-Trigger": [ - { - "trigger_data": "2" - } - ] + "Attribution-Reporting-Register-Trigger": { + "event_trigger_data": [ + { + "trigger_data": "2" + } + ] + } } }] }
diff --git a/content/test/data/attribution_reporting/interop/dedup_key.json b/content/test/data/attribution_reporting/interop/dedup_key.json index 1be0e61..9dca2d3 100644 --- a/content/test/data/attribution_reporting/interop/dedup_key.json +++ b/content/test/data/attribution_reporting/interop/dedup_key.json
@@ -30,12 +30,14 @@ "responses": [{ "url": "https://reporter.test/register-trigger", "response": { - "Attribution-Reporting-Register-Event-Trigger": [ - { - "trigger_data": "1", - "deduplication_key": "1" - } - ] + "Attribution-Reporting-Register-Trigger": { + "event_trigger_data": [ + { + "trigger_data": "1", + "deduplication_key": "1" + } + ] + } } }] }, @@ -48,12 +50,14 @@ "responses": [{ "url": "https://reporter.test/register-trigger", "response": { - "Attribution-Reporting-Register-Event-Trigger": [ - { - "trigger_data": "2", - "deduplication_key": "1" - } - ] + "Attribution-Reporting-Register-Trigger": { + "event_trigger_data": [ + { + "trigger_data": "2", + "deduplication_key": "1" + } + ] + } } }] }, @@ -66,12 +70,14 @@ "responses": [{ "url": "https://reporter.test/register-trigger", "response": { - "Attribution-Reporting-Register-Event-Trigger": [ - { - "trigger_data": "3", - "deduplication_key": "2" - } - ] + "Attribution-Reporting-Register-Trigger": { + "event_trigger_data": [ + { + "trigger_data": "3", + "deduplication_key": "2" + } + ] + } } }] }
diff --git a/content/test/data/attribution_reporting/interop/event_source.json b/content/test/data/attribution_reporting/interop/event_source.json index 88f5e17..2abd77f 100644 --- a/content/test/data/attribution_reporting/interop/event_source.json +++ b/content/test/data/attribution_reporting/interop/event_source.json
@@ -30,11 +30,13 @@ "responses": [{ "url": "https://reporter.test/register-trigger", "response": { - "Attribution-Reporting-Register-Event-Trigger": [ - { - "trigger_data": "1" - } - ] + "Attribution-Reporting-Register-Trigger": { + "event_trigger_data": [ + { + "trigger_data": "1" + } + ] + } } }] }
diff --git a/content/test/data/attribution_reporting/interop/expired_source.json b/content/test/data/attribution_reporting/interop/expired_source.json index 40df37d..716b30e 100644 --- a/content/test/data/attribution_reporting/interop/expired_source.json +++ b/content/test/data/attribution_reporting/interop/expired_source.json
@@ -31,11 +31,13 @@ "responses": [{ "url": "https://reporter.test/register-trigger", "response": { - "Attribution-Reporting-Register-Event-Trigger": [ - { - "trigger_data": "7" - } - ] + "Attribution-Reporting-Register-Trigger": { + "event_trigger_data": [ + { + "trigger_data": "7" + } + ] + } } }] }
diff --git a/content/test/data/attribution_reporting/interop/most_recent_source.json b/content/test/data/attribution_reporting/interop/most_recent_source.json index d43d3ed..37d3c00 100644 --- a/content/test/data/attribution_reporting/interop/most_recent_source.json +++ b/content/test/data/attribution_reporting/interop/most_recent_source.json
@@ -47,11 +47,13 @@ "responses": [{ "url": "https://reporter.test/register-trigger", "response": { - "Attribution-Reporting-Register-Event-Trigger": [ - { - "trigger_data": "7" - } - ] + "Attribution-Reporting-Register-Trigger": { + "event_trigger_data": [ + { + "trigger_data": "7" + } + ] + } } }] }
diff --git a/content/test/data/attribution_reporting/interop/same_destination_site.json b/content/test/data/attribution_reporting/interop/same_destination_site.json index cb83e613..48ce0e5 100644 --- a/content/test/data/attribution_reporting/interop/same_destination_site.json +++ b/content/test/data/attribution_reporting/interop/same_destination_site.json
@@ -30,11 +30,13 @@ "responses": [{ "url": "https://reporter.test/register-trigger", "response": { - "Attribution-Reporting-Register-Event-Trigger": [ - { - "trigger_data": "7" - } - ] + "Attribution-Reporting-Register-Trigger": { + "event_trigger_data": [ + { + "trigger_data": "7" + } + ] + } } }] }, @@ -47,11 +49,13 @@ "responses": [{ "url": "https://reporter.test/register-trigger", "response": { - "Attribution-Reporting-Register-Event-Trigger": [ - { - "trigger_data": "6" - } - ] + "Attribution-Reporting-Register-Trigger": { + "event_trigger_data": [ + { + "trigger_data": "6" + } + ] + } } }] }
diff --git a/content/test/data/attribution_reporting/interop/source_priority.json b/content/test/data/attribution_reporting/interop/source_priority.json index 9021e45..514ebfa 100644 --- a/content/test/data/attribution_reporting/interop/source_priority.json +++ b/content/test/data/attribution_reporting/interop/source_priority.json
@@ -67,11 +67,13 @@ "responses": [{ "url": "https://reporter.test/register-trigger", "response": { - "Attribution-Reporting-Register-Event-Trigger": [ - { - "trigger_data": "7" - } - ] + "Attribution-Reporting-Register-Trigger": { + "event_trigger_data": [ + { + "trigger_data": "7" + } + ] + } } }] }
diff --git a/content/test/data/attribution_reporting/simulator/README.md b/content/test/data/attribution_reporting/simulator/README.md index 7173467..3d634529 100644 --- a/content/test/data/attribution_reporting/simulator/README.md +++ b/content/test/data/attribution_reporting/simulator/README.md
@@ -73,74 +73,76 @@ // Required origin on which the trigger is being registered. "destination_origin": "https://destination.example", - // Optional list of zero or more event trigger data. - "Attribution-Reporting-Register-Event-Trigger": [ - { - // Optional uint64 formatted as a base-10 string. - // Defaults to 0. - "trigger_data": "3", + "Attribution-Reporting-Register-Trigger": { + // Optional list of zero or more event trigger data. + "event_trigger_data": [ + { + // Optional uint64 formatted as a base-10 string. + // Defaults to 0. + "trigger_data": "3", - // Optional int64 formatted as a base-10 string. - // Defaults to 0. - "priority": "-456", + // Optional int64 formatted as a base-10 string. + // Defaults to 0. + "priority": "-456", - // Optional uint64 formatted as a base-10 string. Defaults to null. - "deduplication_key": "654", + // Optional uint64 formatted as a base-10 string. Defaults to null. + "deduplication_key": "654", - // Optional dictionary of filters and corresponding values. Defaults - // to empty. - "filters": { - "a": ["b", "c"], - "d": [] - }, + // Optional dictionary of filters and corresponding values. Defaults + // to empty. + "filters": { + "a": ["b", "c"], + "d": [] + }, - // Optional dictionary of negated filters and corresponding values. - // Defaults to empty. - "not_filters": { - "x": ["y"], - "z": [] + // Optional dictionary of negated filters and corresponding values. + // Defaults to empty. + "not_filters": { + "x": ["y"], + "z": [] + } } - } - ], + ], - // Optional list of zero or more aggregatable trigger data. - "Attribution-Reporting-Register-Aggregatable-Trigger-Data": [ - { - // Required uint128 formatted as a base-16 string. - "key_piece": "0x10", + // Optional list of zero or more aggregatable trigger data. + "aggregatable_trigger_data": [ + { + // Required uint128 formatted as a base-16 string. + "key_piece": "0x10", - // Required list of key identifiers. - "source_keys": ["a"], + // Required list of key identifiers. + "source_keys": ["a"], - // Optional dictionary of filters and corresponding values. Defaults - // to empty. - "filters": { - "a": ["b", "c"], - "d": [] - }, + // Optional dictionary of filters and corresponding values. Defaults + // to empty. + "filters": { + "a": ["b", "c"], + "d": [] + }, - // Optional dictionary of negated filters and corresponding values. - // Defaults to empty. - "not_filters": { - "x": ["y"], - "z": [] + // Optional dictionary of negated filters and corresponding values. + // Defaults to empty. + "not_filters": { + "x": ["y"], + "z": [] + } } + ], + + // Optional dictionary of key identifiers and corresponding values. + "aggregatable_values": { + "a": 123 + }, + + // Optional uint64 formatted as a base-10 string. Defaults to null. + "debug_key": "789", + + // Optional dictionary of filters and corresponding values. Defaults to + // empty. + "filters": { + "a": ["b", "c"], + "d": [] } - ], - - // Optional dictionary of key identifiers and corresponding values. - "Attribution-Reporting-Register-Aggregatable-Values": { - "a": 123 - }, - - // Optional uint64 formatted as a base-10 string. Defaults to null. - "Attribution-Reporting-Trigger-Debug-Key": "789", - - // Optional dictionary of filters and corresponding values. Defaults to - // empty. - "Attribution-Reporting-Filters": { - "a": ["b", "c"], - "d": [] } } ],
diff --git a/content/test/data/attribution_reporting/simulator/basic.input.json b/content/test/data/attribution_reporting/simulator/basic.input.json index a0de459ed..163aa30 100644 --- a/content/test/data/attribution_reporting/simulator/basic.input.json +++ b/content/test/data/attribution_reporting/simulator/basic.input.json
@@ -16,11 +16,13 @@ "timestamp": "1643235574123", "reporting_origin": "https://r.test", "destination_origin": "https://d.test", - "Attribution-Reporting-Register-Event-Trigger": [ - { - "trigger_data": "7" - } - ] + "Attribution-Reporting-Register-Trigger": { + "event_trigger_data": [ + { + "trigger_data": "7" + } + ] + } } ] }
diff --git a/content/test/data/attribution_reporting/simulator/basic_aggregatable.input.json b/content/test/data/attribution_reporting/simulator/basic_aggregatable.input.json index ed631c8..8cfe8ce 100644 --- a/content/test/data/attribution_reporting/simulator/basic_aggregatable.input.json +++ b/content/test/data/attribution_reporting/simulator/basic_aggregatable.input.json
@@ -22,19 +22,21 @@ "timestamp": "1643235574123", "reporting_origin": "https://r.test", "destination_origin": "https://d.test", - "Attribution-Reporting-Register-Event-Trigger": [ - { - "trigger_data": "7" + "Attribution-Reporting-Register-Trigger": { + "event_trigger_data": [ + { + "trigger_data": "7" + } + ], + "aggregatable_trigger_data": [ + { + "source_keys": ["a"], + "key_piece": "0x400" + } + ], + "aggregatable_values": { + "a": 123 } - ], - "Attribution-Reporting-Register-Aggregatable-Trigger-Data": [ - { - "source_keys": ["a"], - "key_piece": "0x400" - } - ], - "Attribution-Reporting-Register-Aggregatable-Values": { - "a": 123 } } ]
diff --git a/content/test/data/attribution_reporting/simulator/basic_iso8601.input.json b/content/test/data/attribution_reporting/simulator/basic_iso8601.input.json index a0de459ed..163aa30 100644 --- a/content/test/data/attribution_reporting/simulator/basic_iso8601.input.json +++ b/content/test/data/attribution_reporting/simulator/basic_iso8601.input.json
@@ -16,11 +16,13 @@ "timestamp": "1643235574123", "reporting_origin": "https://r.test", "destination_origin": "https://d.test", - "Attribution-Reporting-Register-Event-Trigger": [ - { - "trigger_data": "7" - } - ] + "Attribution-Reporting-Register-Trigger": { + "event_trigger_data": [ + { + "trigger_data": "7" + } + ] + } } ] }
diff --git a/content/test/data/attribution_reporting/simulator/clear_data.input.json b/content/test/data/attribution_reporting/simulator/clear_data.input.json index 5327fd7f..3ac46fa9 100644 --- a/content/test/data/attribution_reporting/simulator/clear_data.input.json +++ b/content/test/data/attribution_reporting/simulator/clear_data.input.json
@@ -26,21 +26,25 @@ "timestamp": "1643235575000", "reporting_origin": "https://r.test", "destination_origin": "https://d1.test", - "Attribution-Reporting-Register-Event-Trigger": [ - { - "trigger_data": "6" - } - ] + "Attribution-Reporting-Register-Trigger": { + "event_trigger_data": [ + { + "trigger_data": "6" + } + ] + } }, { "timestamp": "1643235575000", "reporting_origin": "https://r.test", "destination_origin": "https://d2.test", - "Attribution-Reporting-Register-Event-Trigger": [ - { - "trigger_data": "7" - } - ] + "Attribution-Reporting-Register-Trigger": { + "event_trigger_data": [ + { + "trigger_data": "7" + } + ] + } } ], "data_clears": [
diff --git a/content/test/data/attribution_reporting/simulator/clear_data.output.json b/content/test/data/attribution_reporting/simulator/clear_data.output.json index 58b8a55f..d22e1bdc 100644 --- a/content/test/data/attribution_reporting/simulator/clear_data.output.json +++ b/content/test/data/attribution_reporting/simulator/clear_data.output.json
@@ -22,11 +22,13 @@ "timestamp": "1643235575000", "reporting_origin": "https://r.test", "destination_origin": "https://d1.test", - "Attribution-Reporting-Register-Event-Trigger": [ - { - "trigger_data": "6" - } - ] + "Attribution-Reporting-Register-Trigger": { + "event_trigger_data": [ + { + "trigger_data": "6" + } + ] + } } } ]
diff --git a/content/test/data/attribution_reporting/simulator/debug.input.json b/content/test/data/attribution_reporting/simulator/debug.input.json index 06c75305f..e9fc4ae 100644 --- a/content/test/data/attribution_reporting/simulator/debug.input.json +++ b/content/test/data/attribution_reporting/simulator/debug.input.json
@@ -17,23 +17,27 @@ "timestamp": "1643235574000", "reporting_origin": "https://r.test", "destination_origin": "https://d.test", - "Attribution-Reporting-Register-Event-Trigger": [ - { - "trigger_data": "7" - } - ], - "Attribution-Reporting-Trigger-Debug-Key": "333" + "Attribution-Reporting-Register-Trigger": { + "event_trigger_data": [ + { + "trigger_data": "7" + } + ], + "debug_key": "333" + } }, { "timestamp": "1643235575000", "reporting_origin": "https://r.test", "destination_origin": "https://d.test", - "Attribution-Reporting-Register-Event-Trigger": [ - { - "trigger_data": "6" - } - ], - "Attribution-Reporting-Trigger-Debug-Key": "444" + "Attribution-Reporting-Register-Trigger": { + "event_trigger_data": [ + { + "trigger_data": "6" + } + ], + "debug_key": "444" + } } ], "cookies": [
diff --git a/content/test/data/attribution_reporting/simulator/debug_skip_check.input.json b/content/test/data/attribution_reporting/simulator/debug_skip_check.input.json index 5189c7b3..f639e4c1 100644 --- a/content/test/data/attribution_reporting/simulator/debug_skip_check.input.json +++ b/content/test/data/attribution_reporting/simulator/debug_skip_check.input.json
@@ -17,12 +17,14 @@ "timestamp": "1643235574000", "reporting_origin": "https://r.test", "destination_origin": "https://d.test", - "Attribution-Reporting-Register-Event-Trigger": [ - { - "trigger_data": "7" - } - ], - "Attribution-Reporting-Trigger-Debug-Key": "333" + "Attribution-Reporting-Register-Trigger": { + "event_trigger_data": [ + { + "trigger_data": "7" + } + ], + "debug_key": "333" + } } ] }
diff --git a/content/test/data/attribution_reporting/simulator/no_delay.input.json b/content/test/data/attribution_reporting/simulator/no_delay.input.json index 5d90189b..97e6171 100644 --- a/content/test/data/attribution_reporting/simulator/no_delay.input.json +++ b/content/test/data/attribution_reporting/simulator/no_delay.input.json
@@ -16,11 +16,13 @@ "timestamp": "1643235574000", "reporting_origin": "https://r.test", "destination_origin": "https://d.test", - "Attribution-Reporting-Register-Event-Trigger": [ - { - "trigger_data": "7" - } - ] + "Attribution-Reporting-Register-Trigger": { + "event_trigger_data": [ + { + "trigger_data": "7" + } + ] + } } ] }
diff --git a/content/test/data/attribution_reporting/simulator/rejected_triggers.input.json b/content/test/data/attribution_reporting/simulator/rejected_triggers.input.json index c3a8be1..42275a9 100644 --- a/content/test/data/attribution_reporting/simulator/rejected_triggers.input.json +++ b/content/test/data/attribution_reporting/simulator/rejected_triggers.input.json
@@ -22,73 +22,85 @@ "timestamp": "1643235572000", "reporting_origin": "https://r.test", "destination_origin": "https://d.test", - "Attribution-Reporting-Register-Event-Trigger": [ - { - "trigger_data": "1" - } - ] + "Attribution-Reporting-Register-Trigger": { + "event_trigger_data": [ + { + "trigger_data": "1" + } + ] + } }, { "timestamp": "1643235574000", "reporting_origin": "https://r.test", "destination_origin": "https://d.test", - "Attribution-Reporting-Register-Event-Trigger": [ - { - "trigger_data": "2", - "deduplication_key": "22" - } - ] + "Attribution-Reporting-Register-Trigger": { + "event_trigger_data": [ + { + "trigger_data": "2", + "deduplication_key": "22" + } + ] + } }, { "timestamp": "1643235575000", "reporting_origin": "https://r.test", "destination_origin": "https://d.test", - "Attribution-Reporting-Register-Event-Trigger": [ - { - "trigger_data": "3", - "deduplication_key": "22" - } - ] + "Attribution-Reporting-Register-Trigger": { + "event_trigger_data": [ + { + "trigger_data": "3", + "deduplication_key": "22" + } + ] + } }, { "timestamp": "1643235576000", "reporting_origin": "https://r.test", "destination_origin": "https://d.test", - "Attribution-Reporting-Register-Event-Trigger": [ - { - "trigger_data": "4", - "priority": "100" - } - ] + "Attribution-Reporting-Register-Trigger": { + "event_trigger_data": [ + { + "trigger_data": "4", + "priority": "100" + } + ] + } }, { "timestamp": "1643235577000", "reporting_origin": "https://r.test", "destination_origin": "https://d.test", - "Attribution-Reporting-Register-Event-Trigger": [ - { - "trigger_data": "5", - "priority": "100" - } - ] + "Attribution-Reporting-Register-Trigger": { + "event_trigger_data": [ + { + "trigger_data": "5", + "priority": "100" + } + ] + } }, { "timestamp": "1643235578000", "reporting_origin": "https://r.test", "destination_origin": "https://d.test", - "Attribution-Reporting-Register-Event-Trigger": [ - { - "trigger_data": "6" + "Attribution-Reporting-Register-Trigger": { + "event_trigger_data": [ + { + "trigger_data": "6" + } + ], + "aggregatable_trigger_data": [ + { + "source_keys": ["a"], + "key_piece": "0x400" + } + ], + "aggregatable_values": { + "b": 123 } - ], - "Attribution-Reporting-Register-Aggregatable-Trigger-Data": [ - { - "source_keys": ["a"], - "key_piece": "0x400" - } - ], - "Attribution-Reporting-Register-Aggregatable-Values": { - "b": 123 } } ]
diff --git a/content/test/data/attribution_reporting/simulator/rejected_triggers.output.json b/content/test/data/attribution_reporting/simulator/rejected_triggers.output.json index 93a416abf..db2b9a8 100644 --- a/content/test/data/attribution_reporting/simulator/rejected_triggers.output.json +++ b/content/test/data/attribution_reporting/simulator/rejected_triggers.output.json
@@ -6,11 +6,13 @@ "timestamp": "1643235572000", "reporting_origin": "https://r.test", "destination_origin": "https://d.test", - "Attribution-Reporting-Register-Event-Trigger": [ - { - "trigger_data": "1" - } - ] + "Attribution-Reporting-Register-Trigger": { + "event_trigger_data": [ + { + "trigger_data": "1" + } + ] + } } }, { @@ -19,12 +21,14 @@ "timestamp": "1643235575000", "reporting_origin": "https://r.test", "destination_origin": "https://d.test", - "Attribution-Reporting-Register-Event-Trigger": [ - { - "trigger_data": "3", - "deduplication_key": "22" - } - ] + "Attribution-Reporting-Register-Trigger": { + "event_trigger_data": [ + { + "trigger_data": "3", + "deduplication_key": "22" + } + ] + } } }, { @@ -34,19 +38,21 @@ "timestamp": "1643235578000", "reporting_origin": "https://r.test", "destination_origin": "https://d.test", - "Attribution-Reporting-Register-Event-Trigger": [ - { - "trigger_data": "6" + "Attribution-Reporting-Register-Trigger": { + "event_trigger_data": [ + { + "trigger_data": "6" + } + ], + "aggregatable_trigger_data": [ + { + "source_keys": ["a"], + "key_piece": "0x400" + } + ], + "aggregatable_values": { + "b": 123 } - ], - "Attribution-Reporting-Register-Aggregatable-Trigger-Data": [ - { - "source_keys": ["a"], - "key_piece": "0x400" - } - ], - "Attribution-Reporting-Register-Aggregatable-Values": { - "b": 123 } } }
diff --git a/content/test/data/attribution_reporting/simulator/replaced_reports.input.json b/content/test/data/attribution_reporting/simulator/replaced_reports.input.json index e46b3b25..81844650 100644 --- a/content/test/data/attribution_reporting/simulator/replaced_reports.input.json +++ b/content/test/data/attribution_reporting/simulator/replaced_reports.input.json
@@ -16,22 +16,26 @@ "timestamp": "1643235574000", "reporting_origin": "https://r.test", "destination_origin": "https://d.test", - "Attribution-Reporting-Register-Event-Trigger": [ - { - "trigger_data": "0" - } - ] + "Attribution-Reporting-Register-Trigger": { + "event_trigger_data": [ + { + "trigger_data": "0" + } + ] + } }, { "timestamp": "1643235575000", "reporting_origin": "https://r.test", "destination_origin": "https://d.test", - "Attribution-Reporting-Register-Event-Trigger": [ - { - "trigger_data": "1", - "priority": "5" - } - ] + "Attribution-Reporting-Register-Trigger": { + "event_trigger_data": [ + { + "trigger_data": "1", + "priority": "5" + } + ] + } } ] }
diff --git a/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt index f8f6df28..7feae46 100644 --- a/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt +++ b/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt
@@ -397,15 +397,17 @@ crbug.com/1321305 [ mac release apple-apple-m1 ] Pixel_WebGPUImportVideoFrame [ Failure ] crbug.com/1321305 [ mac release apple-apple-m1 ] Pixel_WebGPUImportVideoFrameOffscreenCanvas [ Failure ] -# WebGPU pixel tests fail because current expectations are incorrect. Disabled to allow work to progress. -crbug.com/1325002 [ mac ] Pixel_WebGPUImportVideoFrame* [ Failure ] -crbug.com/1325002 [ win ] Pixel_WebGPUImportVideoFrame* [ Failure ] -crbug.com/1325002 [ linux ] Pixel_VulkanSwiftShader_WebGPUImportVideoFrame* [ Failure ] - -# Vulkan Swiftshader WebGPU interop flipped destination image +# Vulkan Swiftshader WebGPU interop - flipped destination image crbug.com/1307787 [ linux skia-renderer-vulkan ] Pixel_VulkanSwiftShader_WebGPUCopyExternalImage* [ Failure ] -# Vulkan Swiftshader WebGPU unaccelerated OffscreenCanvas missing source image +# Vulkan Swiftshader WebGPU interop - missing destination image +crbug.com/1307787 [ linux skia-renderer-vulkan ] Pixel_VulkanSwiftShader_WebGPUImportVideoFrame [ Failure ] + +# Vulkan Swiftshader WebGPU interop - missing source and destination images +crbug.com/1307787 [ linux skia-renderer-vulkan ] Pixel_VulkanSwiftShader_WebGPUImportVideoFrameOffscreenCanvas [ Failure ] +crbug.com/1307787 [ linux skia-renderer-vulkan ] Pixel_VulkanSwiftShader_WebGPUImportVideoFrameUnaccelerated [ Failure ] + +# Vulkan Swiftshader WebGPU interop - missing source image crbug.com/1307787 [ linux skia-renderer-vulkan ] Pixel_VulkanSwiftShader_WebGPUImportVideoFrameUnacceleratedOffscreenCanvas [ Failure ] crbug.com/1203317 [ android android-shield-android-tv no-passthrough ] Pixel_OffscreenCanvasWebGLPaintAfterResize [ RetryOnFailure ]
diff --git a/content/test/web_contents_observer_consistency_checker.cc b/content/test/web_contents_observer_consistency_checker.cc index 8bc2b59..75cf451 100644 --- a/content/test/web_contents_observer_consistency_checker.cc +++ b/content/test/web_contents_observer_consistency_checker.cc
@@ -66,9 +66,6 @@ << Format(render_frame_host); } - CHECK(render_frame_host->IsRenderFrameCreated()) - << "RenderFrameCreated was called for a RenderFrameHost that has not been" - "marked created."; CHECK(render_frame_host->GetProcess()->IsInitializedAndNotDead()) << "RenderFrameCreated was called for a RenderFrameHost whose render " "process is not currently live, so there's no way for the RenderFrame " @@ -95,9 +92,6 @@ void WebContentsObserverConsistencyChecker::RenderFrameDeleted( RenderFrameHost* render_frame_host) { CHECK(!web_contents_destroyed_); - CHECK(!render_frame_host->IsRenderFrameCreated()) - << "RenderFrameDeleted was called for a RenderFrameHost that is" - "(still) marked as created."; CHECK(!render_frame_host->IsRenderFrameLive()) << "RenderFrameDeleted was called for a RenderFrameHost that is" "still live.";
diff --git a/content/web_test/browser/web_test_tts_platform.cc b/content/web_test/browser/web_test_tts_platform.cc index 9ab1a544..769fd19 100644 --- a/content/web_test/browser/web_test_tts_platform.cc +++ b/content/web_test/browser/web_test_tts_platform.cc
@@ -76,6 +76,8 @@ const GURL& source_url, std::vector<content::VoiceData>* out_voices) {} +void WebTestTtsPlatform::RefreshVoices() {} + WebTestTtsPlatform::WebTestTtsPlatform() = default; WebTestTtsPlatform::~WebTestTtsPlatform() = default;
diff --git a/content/web_test/browser/web_test_tts_platform.h b/content/web_test/browser/web_test_tts_platform.h index 1dd35c37..536b500 100644 --- a/content/web_test/browser/web_test_tts_platform.h +++ b/content/web_test/browser/web_test_tts_platform.h
@@ -45,6 +45,7 @@ content::BrowserContext* browser_context, const GURL& source_url, std::vector<content::VoiceData>* out_voices) override; + void RefreshVoices() override; private: WebTestTtsPlatform();
diff --git a/extensions/browser/api/networking_private/networking_private_chromeos.cc b/extensions/browser/api/networking_private/networking_private_chromeos.cc index 45328e3f..554c7ce 100644 --- a/extensions/browser/api/networking_private/networking_private_chromeos.cc +++ b/extensions/browser/api/networking_private/networking_private_chromeos.cc
@@ -12,6 +12,8 @@ #include "base/containers/contains.h" #include "base/logging.h" #include "base/values.h" +#include "chromeos/ash/components/network/onc/network_onc_utils.h" +#include "chromeos/ash/components/network/onc/onc_translator.h" #include "chromeos/components/onc/onc_signature.h" #include "chromeos/login/login_state/login_state.h" #include "chromeos/network/device_state.h" @@ -24,8 +26,6 @@ #include "chromeos/network/network_state.h" #include "chromeos/network/network_state_handler.h" #include "chromeos/network/network_util.h" -#include "chromeos/network/onc/network_onc_utils.h" -#include "chromeos/network/onc/onc_translator.h" #include "chromeos/network/portal_detector/network_portal_detector.h" #include "components/onc/onc_constants.h" #include "components/proxy_config/proxy_prefs.h"
diff --git a/extensions/browser/api/networking_private/networking_private_event_router_chromeos.cc b/extensions/browser/api/networking_private/networking_private_event_router_chromeos.cc index a725efc0..9c2604a 100644 --- a/extensions/browser/api/networking_private/networking_private_event_router_chromeos.cc +++ b/extensions/browser/api/networking_private/networking_private_event_router_chromeos.cc
@@ -5,6 +5,7 @@ #include "extensions/browser/api/networking_private/networking_private_event_router.h" #include "base/json/json_writer.h" +#include "chromeos/ash/components/network/onc/onc_translator.h" #include "chromeos/components/onc/onc_signature.h" #include "chromeos/network/device_state.h" #include "chromeos/network/network_certificate_handler.h" @@ -12,7 +13,6 @@ #include "chromeos/network/network_state.h" #include "chromeos/network/network_state_handler.h" #include "chromeos/network/network_state_handler_observer.h" -#include "chromeos/network/onc/onc_translator.h" #include "components/keyed_service/content/browser_context_dependency_manager.h" #include "components/onc/onc_constants.h" #include "content/public/browser/browser_context.h"
diff --git a/fuchsia/engine/BUILD.gn b/fuchsia/engine/BUILD.gn index f44bcbaa..d639c3e 100644 --- a/fuchsia/engine/BUILD.gn +++ b/fuchsia/engine/BUILD.gn
@@ -638,6 +638,7 @@ ] ] use_cfv2 = false additional_manifest_fragments = [ + "//build/config/fuchsia/test/audio_capabilities.test-cmx", "//build/config/fuchsia/test/network_capabilities.test-cmx", "//build/config/fuchsia/test/read_debug_data.test-cmx", "//build/config/fuchsia/test/vulkan_capabilities.test-cmx",
diff --git a/fuchsia/engine/browser/frame_impl.cc b/fuchsia/engine/browser/frame_impl.cc index d815a97..09ddc4b 100644 --- a/fuchsia/engine/browser/frame_impl.cc +++ b/fuchsia/engine/browser/frame_impl.cc
@@ -996,8 +996,9 @@ // to the view-tree to be displayed. See https://crbug.com/1109270 } -void FrameImpl::SetMediaSessionId(uint64_t session_id) { - media_session_id_ = session_id; +void FrameImpl::SetMediaSettings( + fuchsia::web::FrameMediaSettings media_settings) { + media_settings_ = std::move(media_settings); } void FrameImpl::MediaStartedPlaying(const MediaPlayerInfo& video_type,
diff --git a/fuchsia/engine/browser/frame_impl.h b/fuchsia/engine/browser/frame_impl.h index 50631a4..ea127a2 100644 --- a/fuchsia/engine/browser/frame_impl.h +++ b/fuchsia/engine/browser/frame_impl.h
@@ -86,8 +86,8 @@ FrameImpl(const FrameImpl&) = delete; FrameImpl& operator=(const FrameImpl&) = delete; - absl::optional<uint64_t> media_session_id() const { - return media_session_id_; + const fuchsia::web::FrameMediaSettings& media_settings() const { + return media_settings_; } FramePermissionController* permission_controller() { @@ -273,7 +273,8 @@ SetUrlRequestRewriteRulesCallback callback) override; void EnableHeadlessRendering() override; void DisableHeadlessRendering() override; - void SetMediaSessionId(uint64_t session_id) override; + void SetMediaSettings( + fuchsia::web::FrameMediaSettings media_settings) override; void ForceContentDimensions( std::unique_ptr<fuchsia::ui::gfx::vec2> web_dips) override; void SetPermissionState(fuchsia::web::PermissionDescriptor permission, @@ -387,9 +388,7 @@ FramePermissionController permission_controller_; std::unique_ptr<NavigationPolicyHandler> navigation_policy_handler_; - // Session ID to use for fuchsia.media.AudioConsumer. Set with - // SetMediaSessionId(). - absl::optional<uint64_t> media_session_id_; + fuchsia::web::FrameMediaSettings media_settings_; // Stored settings for web contents in the current Frame. fuchsia::web::ContentAreaSettings content_area_settings_;
diff --git a/fuchsia/engine/browser/web_engine_media_resource_provider_impl.cc b/fuchsia/engine/browser/web_engine_media_resource_provider_impl.cc index 1e0fc518..a997d9b 100644 --- a/fuchsia/engine/browser/web_engine_media_resource_provider_impl.cc +++ b/fuchsia/engine/browser/web_engine_media_resource_provider_impl.cc
@@ -36,7 +36,8 @@ ShouldUseAudioConsumerCallback callback) { auto* frame_impl = FrameImpl::FromRenderFrameHost(render_frame_host()); DCHECK(frame_impl); - std::move(callback).Run(frame_impl->media_session_id().has_value()); + std::move(callback).Run( + frame_impl->media_settings().has_audio_consumer_session_id()); } void WebEngineMediaResourceProviderImpl::CreateAudioConsumer( @@ -55,12 +56,13 @@ auto* frame_impl = FrameImpl::FromRenderFrameHost(render_frame_host()); DCHECK(frame_impl); - if (!frame_impl->media_session_id().has_value()) { + if (!frame_impl->media_settings().has_audio_consumer_session_id()) { LOG(WARNING) << "Renderer tried creating AudioConsumer for a Frame without " "media_session_id()."; return; } - factory->CreateAudioConsumer(frame_impl->media_session_id().value(), - std::move(request)); + factory->CreateAudioConsumer( + frame_impl->media_settings().audio_consumer_session_id(), + std::move(request)); }
diff --git a/fuchsia/engine/test/web_engine_shell.cmx b/fuchsia/engine/test/web_engine_shell.cmx index 7b303c6..a14d635 100644 --- a/fuchsia/engine/test/web_engine_shell.cmx +++ b/fuchsia/engine/test/web_engine_shell.cmx
@@ -16,6 +16,7 @@ "fuchsia.feedback.ComponentDataRegister", "fuchsia.feedback.CrashReportingProductRegister", "fuchsia.fonts.Provider", + "fuchsia.hwinfo.Product", "fuchsia.input.virtualkeyboard.ControllerCreator", "fuchsia.intl.PropertyProvider", "fuchsia.logger.LogSink",
diff --git a/fuchsia/engine/web_engine_integration_test.cc b/fuchsia/engine/web_engine_integration_test.cc index 298ab77..0009cf59 100644 --- a/fuchsia/engine/web_engine_integration_test.cc +++ b/fuchsia/engine/web_engine_integration_test.cc
@@ -12,6 +12,7 @@ #include "base/fuchsia/fuchsia_logging.h" #include "base/fuchsia/mem_buffer_util.h" +#include "base/fuchsia/process_context.h" #include "base/strings/stringprintf.h" #include "base/test/test_future.h" #include "build/build_config.h" @@ -59,32 +60,6 @@ void RunPermissionTest(bool grant); }; -// Configures the default filtered service directory with a fake AudioConsumer -// service for testing. -class WebEngineIntegrationMediaTest : public WebEngineIntegrationTest { - protected: - WebEngineIntegrationMediaTest() - : fake_audio_consumer_service_(filtered_service_directory() - .outgoing_directory() - ->GetOrCreateDirectory("svc")), - fake_audio_device_enumerator_(filtered_service_directory() - .outgoing_directory() - ->GetOrCreateDirectory("svc")) {} - - // Returns a CreateContextParams that has AUDIO feature, and the "testdata" - // content directory provider configured. - fuchsia::web::CreateContextParams ContextParamsWithAudioAndTestData() { - fuchsia::web::CreateContextParams create_params = - TestContextParamsWithTestData(); - *create_params.mutable_features() |= - fuchsia::web::ContextFeatureFlags::AUDIO; - return create_params; - } - - media::FakeAudioConsumerService fake_audio_consumer_service_; - media::FakeAudioDeviceEnumerator fake_audio_device_enumerator_; -}; - class WebEngineIntegrationUserAgentTest : public WebEngineIntegrationTest { protected: GURL GetEchoUserAgentUrl() { @@ -344,11 +319,54 @@ navigation_listener()->RunUntilUrlAndTitleEquals(kUrl, kTitle); } -TEST_F(WebEngineIntegrationMediaTest, PlayAudio) { - CreateContextAndFrame(ContextParamsWithAudioAndTestData()); +// Configures the default filtered service directory with a fake AudioConsumer +// service for testing. +class WebEngineIntegrationMediaTest : public WebEngineIntegrationTest { + protected: + WebEngineIntegrationMediaTest() + : fake_audio_consumer_service_(filtered_service_directory() + .outgoing_directory() + ->GetOrCreateDirectory("svc")) { + auto* outgoing_directory = + filtered_service_directory().outgoing_directory(); - static const uint16_t kTestMediaSessionId = 43; - frame_->SetMediaSessionId(kTestMediaSessionId); + // Publish fake AudioDeviceEnumerator. + outgoing_directory + ->RemovePublicService<fuchsia::media::AudioDeviceEnumerator>(); + fake_audio_device_enumerator_.emplace( + outgoing_directory->GetOrCreateDirectory("svc")); + + // Intercept `fuchsia::media::Audio` connections in order to count them. + outgoing_directory->RemovePublicService<fuchsia::media::Audio>(); + zx_status_t status = outgoing_directory->AddPublicService( + fidl::InterfaceRequestHandler<fuchsia::media::Audio>( + [this](auto request) { + ++num_audio_connections_; + base::ComponentContextForProcess()->svc()->Connect( + std::move(request)); + })); + ZX_CHECK(status == ZX_OK, status) << "AddPublicService"; + } + + // Returns a CreateContextParams that has AUDIO feature, and the "testdata" + // content directory provider configured. + fuchsia::web::CreateContextParams ContextParamsWithAudioAndTestData() { + fuchsia::web::CreateContextParams create_params = + TestContextParamsWithTestData(); + *create_params.mutable_features() |= + fuchsia::web::ContextFeatureFlags::AUDIO; + return create_params; + } + + media::FakeAudioConsumerService fake_audio_consumer_service_; + absl::optional<media::FakeAudioDeviceEnumerator> + fake_audio_device_enumerator_; + + size_t num_audio_connections_ = 0; +}; + +TEST_F(WebEngineIntegrationMediaTest, PlayAudioToAudioRenderer) { + CreateContextAndFrame(ContextParamsWithAudioAndTestData()); ASSERT_NO_FATAL_FAILURE(LoadUrlAndExpectResponse( "fuchsia-dir://testdata/play_audio.html", @@ -356,6 +374,27 @@ navigation_listener()->RunUntilTitleEquals("ended"); + EXPECT_EQ(num_audio_connections_, 1U); + EXPECT_EQ(fake_audio_consumer_service_.num_instances(), 0U); +} + +TEST_F(WebEngineIntegrationMediaTest, PlayAudioToAudioConsumer) { + CreateContextAndFrame(ContextParamsWithAudioAndTestData()); + + // Send `FrameMediaSettings` with `audio_consumer_session_id`. This enables + // `AudioConsumer`. + static const uint16_t kTestMediaSessionId = 43; + fuchsia::web::FrameMediaSettings media_settings; + media_settings.set_audio_consumer_session_id(kTestMediaSessionId); + frame_->SetMediaSettings(std::move(media_settings)); + + ASSERT_NO_FATAL_FAILURE(LoadUrlAndExpectResponse( + "fuchsia-dir://testdata/play_audio.html", + cr_fuchsia::CreateLoadUrlParamsWithUserActivation())); + + navigation_listener()->RunUntilTitleEquals("ended"); + + EXPECT_EQ(num_audio_connections_, 0U); ASSERT_EQ(fake_audio_consumer_service_.num_instances(), 1U); auto pos = fake_audio_consumer_service_.instance(0)->GetMediaPosition(); @@ -376,40 +415,29 @@ TestContextParamsWithTestData(); CreateContextAndFrame(std::move(create_params)); - bool is_requested = false; - zx_status_t status = - filtered_service_directory() - .outgoing_directory() - ->RemovePublicService<fuchsia::media::SessionAudioConsumerFactory>(); - ZX_CHECK(status == ZX_OK, status) << "RemovePublicService"; - status = filtered_service_directory().outgoing_directory()->AddPublicService( - fidl::InterfaceRequestHandler< - fuchsia::media::SessionAudioConsumerFactory>( - [&is_requested](auto request) { is_requested = true; })); - ZX_CHECK(status == ZX_OK, status) << "AddPublicService"; - - static const uint16_t kTestMediaSessionId = 1; - frame_->SetMediaSessionId(kTestMediaSessionId); - ASSERT_NO_FATAL_FAILURE(LoadUrlAndExpectResponse( "fuchsia-dir://testdata/play_audio.html", cr_fuchsia::CreateLoadUrlParamsWithUserActivation())); - navigation_listener()->RunUntilTitleEquals("media element error"); - EXPECT_FALSE(is_requested); + // The file is still expected to play to the end. + navigation_listener()->RunUntilTitleEquals("ended"); + + EXPECT_EQ(fake_audio_consumer_service_.num_instances(), 0U); + EXPECT_EQ(num_audio_connections_, 0U); } TEST_F(WebEngineIntegrationMediaTest, PlayVideo) { CreateContextAndFrame(ContextParamsWithAudioAndTestData()); - static const uint16_t kTestMediaSessionId = 1; - frame_->SetMediaSessionId(kTestMediaSessionId); - ASSERT_NO_FATAL_FAILURE(LoadUrlAndExpectResponse( kAutoplayVp9OpusToEndUrl, cr_fuchsia::CreateLoadUrlParamsWithUserActivation())); navigation_listener()->RunUntilTitleEquals("ended"); + + // Audio should be sent to AudioRenderer (created though `fuchsia.web.Audio`). + EXPECT_EQ(num_audio_connections_, 1U); + EXPECT_EQ(fake_audio_consumer_service_.num_instances(), 0U); } void WebEngineIntegrationTest::RunPermissionTest(bool grant) { @@ -601,12 +629,13 @@ HardwareVideoDecoderFlag_Provided) { // Check that the CodecFactory service is requested. base::RunLoop codec_connected_run_loop; - zx_status_t status = - filtered_service_directory().outgoing_directory()->AddPublicService( - fidl::InterfaceRequestHandler<fuchsia::mediacodec::CodecFactory>( - [&codec_connected_run_loop](auto request) { - codec_connected_run_loop.Quit(); - })); + auto* outgoing_directory = filtered_service_directory().outgoing_directory(); + outgoing_directory->RemovePublicService<fuchsia::mediacodec::CodecFactory>(); + zx_status_t status = outgoing_directory->AddPublicService( + fidl::InterfaceRequestHandler<fuchsia::mediacodec::CodecFactory>( + [&codec_connected_run_loop](auto request) { + codec_connected_run_loop.Quit(); + })); ZX_CHECK(status == ZX_OK, status) << "AddPublicService"; // The VULKAN flag is required for hardware video decoders to be available. @@ -617,9 +646,6 @@ fuchsia::web::ContextFeatureFlags::HARDWARE_VIDEO_DECODER; CreateContextAndFrame(std::move(create_params)); - static const uint16_t kTestMediaSessionId = 1; - frame_->SetMediaSessionId(kTestMediaSessionId); - ASSERT_NO_FATAL_FAILURE(LoadUrlAndExpectResponse( kAutoplayVp9OpusToEndUrl, cr_fuchsia::CreateLoadUrlParamsWithUserActivation())); @@ -631,19 +657,17 @@ // The video should use software decoders and still play. TEST_F(WebEngineIntegrationMediaTest, HardwareVideoDecoderFlag_NotProvided) { bool is_requested = false; - zx_status_t status = - filtered_service_directory().outgoing_directory()->AddPublicService( - fidl::InterfaceRequestHandler<fuchsia::mediacodec::CodecFactory>( - [&is_requested](auto request) { is_requested = true; })); + auto* outgoing_directory = filtered_service_directory().outgoing_directory(); + outgoing_directory->RemovePublicService<fuchsia::mediacodec::CodecFactory>(); + zx_status_t status = outgoing_directory->AddPublicService( + fidl::InterfaceRequestHandler<fuchsia::mediacodec::CodecFactory>( + [&is_requested](auto request) { is_requested = true; })); ZX_CHECK(status == ZX_OK, status) << "AddPublicService"; fuchsia::web::CreateContextParams create_params = ContextParamsWithAudioAndTestData(); CreateContextAndFrame(std::move(create_params)); - static const uint16_t kTestMediaSessionId = 1; - frame_->SetMediaSessionId(kTestMediaSessionId); - ASSERT_NO_FATAL_FAILURE(LoadUrlAndExpectResponse( kAutoplayVp9OpusToEndUrl, cr_fuchsia::CreateLoadUrlParamsWithUserActivation()));
diff --git a/fuchsia/engine/web_instance.cmx b/fuchsia/engine/web_instance.cmx index d6a05145..4163a99 100644 --- a/fuchsia/engine/web_instance.cmx +++ b/fuchsia/engine/web_instance.cmx
@@ -15,6 +15,7 @@ "fuchsia.camera3.DeviceWatcher", "fuchsia.device.NameProvider", "fuchsia.fonts.Provider", + "fuchsia.hwinfo.Product", "fuchsia.input.virtualkeyboard.ControllerCreator", "fuchsia.intl.PropertyProvider", "fuchsia.legacymetrics.MetricsRecorder",
diff --git a/fuchsia/engine/web_instance_host/web_instance_host.cc b/fuchsia/engine/web_instance_host/web_instance_host.cc index 7dbf2514..96417238 100644 --- a/fuchsia/engine/web_instance_host/web_instance_host.cc +++ b/fuchsia/engine/web_instance_host/web_instance_host.cc
@@ -428,12 +428,12 @@ // at: // https://fuchsia.dev/reference/fidl/fuchsia.web#CreateContextParams.service_directory std::vector<std::string> services{ - "fuchsia.buildinfo.Provider", "fuchsia.device.NameProvider", - "fuchsia.fonts.Provider", "fuchsia.intl.PropertyProvider", - "fuchsia.logger.LogSink", "fuchsia.memorypressure.Provider", - "fuchsia.process.Launcher", + "fuchsia.buildinfo.Provider", "fuchsia.device.NameProvider", + "fuchsia.fonts.Provider", "fuchsia.hwinfo.Product", + "fuchsia.intl.PropertyProvider", "fuchsia.logger.LogSink", + "fuchsia.memorypressure.Provider", "fuchsia.process.Launcher", "fuchsia.settings.Display", // Used if preferred theme is DEFAULT. - "fuchsia.sysmem.Allocator", "fuchsia.ui.scenic.Scenic"}; + "fuchsia.sysmem.Allocator", "fuchsia.ui.scenic.Scenic"}; // TODO(crbug.com/1209031): Provide these conditionally, once corresponding // ContextFeatureFlags have been defined.
diff --git a/fuchsia/runners/cast/cast_component.cc b/fuchsia/runners/cast/cast_component.cc index 1d6ecad2..d79c10c 100644 --- a/fuchsia/runners/cast/cast_component.cc +++ b/fuchsia/runners/cast/cast_component.cc
@@ -64,7 +64,7 @@ return false; if (!initial_url_rewrite_rules) return false; - if (!media_session_id) + if (!media_settings) return false; return true; } @@ -85,7 +85,7 @@ std::move(params.initial_url_rewrite_rules.value())), api_bindings_client_(std::move(params.api_bindings_client)), application_context_(params.application_context.Bind()), - media_session_id_(params.media_session_id.value()), + media_settings_(std::move(params.media_settings.value())), headless_disconnect_watch_(FROM_HERE) { base::AutoReset<bool> constructor_active_reset(&constructor_active_, true); } @@ -146,7 +146,7 @@ }); OnRewriteRulesReceived(std::move(initial_url_rewrite_rules_)); - frame()->SetMediaSessionId(media_session_id_); + frame()->SetMediaSettings(std::move(media_settings_)); frame()->ConfigureInputTypes(fuchsia::web::InputTypes::ALL, fuchsia::web::AllowInputState::DENY); if (application_config_.has_initial_min_console_log_severity()) {
diff --git a/fuchsia/runners/cast/cast_component.h b/fuchsia/runners/cast/cast_component.h index d1ed3b0e..53056c1 100644 --- a/fuchsia/runners/cast/cast_component.h +++ b/fuchsia/runners/cast/cast_component.h
@@ -63,7 +63,7 @@ application_context; absl::optional<std::vector<fuchsia::web::UrlRequestRewriteRule>> initial_url_rewrite_rules; - absl::optional<uint64_t> media_session_id; + absl::optional<fuchsia::web::FrameMediaSettings> media_settings; }; // See WebComponent documentation for details of |debug_name| and |runner|. @@ -138,7 +138,7 @@ std::unique_ptr<ApiBindingsClient> api_bindings_client_; std::unique_ptr<ApplicationControllerImpl> application_controller_; chromium::cast::ApplicationContextPtr application_context_; - uint64_t media_session_id_ = 0; + fuchsia::web::FrameMediaSettings media_settings_; zx::eventpair headless_view_token_; base::MessagePumpForIO::ZxHandleWatchController headless_disconnect_watch_; };
diff --git a/fuchsia/runners/cast/cast_runner.cc b/fuchsia/runners/cast/cast_runner.cc index de07f0d..fffc18b 100644 --- a/fuchsia/runners/cast/cast_runner.cc +++ b/fuchsia/runners/cast/cast_runner.cc
@@ -50,6 +50,7 @@ // "fuchsia.camera3.DeviceWatcher" is redirected to the agent. "fuchsia.device.NameProvider", "fuchsia.fonts.Provider", + "fuchsia.hwinfo.Product", "fuchsia.input.virtualkeyboard.ControllerCreator", "fuchsia.intl.PropertyProvider", // "fuchsia.legacymetrics.MetricsRecorder" is redirected to the agent.
diff --git a/fuchsia/runners/cast/cast_runner.cmx b/fuchsia/runners/cast/cast_runner.cmx index 9757e704..137974ab 100644 --- a/fuchsia/runners/cast/cast_runner.cmx +++ b/fuchsia/runners/cast/cast_runner.cmx
@@ -15,6 +15,7 @@ "fuchsia.feedback.ComponentDataRegister", "fuchsia.feedback.CrashReportingProductRegister", "fuchsia.fonts.Provider", + "fuchsia.hwinfo.Product", "fuchsia.input.virtualkeyboard.ControllerCreator", "fuchsia.intl.PropertyProvider", "fuchsia.logger.LogSink",
diff --git a/fuchsia/runners/cast/cast_runner_integration_test.cc b/fuchsia/runners/cast/cast_runner_integration_test.cc index f7ff292..962b247 100644 --- a/fuchsia/runners/cast/cast_runner_integration_test.cc +++ b/fuchsia/runners/cast/cast_runner_integration_test.cc
@@ -142,7 +142,7 @@ private: // chromium::cast::ApplicationContext implementation. void GetMediaSessionId(GetMediaSessionIdCallback callback) override { - callback(0); + callback(1); } void SetApplicationController( fidl::InterfaceHandle<chromium::cast::ApplicationController> controller)
diff --git a/fuchsia/runners/cast/fidl/application_config.fidl b/fuchsia/runners/cast/fidl/application_config.fidl index 4406206..8667be21 100644 --- a/fuchsia/runners/cast/fidl/application_config.fidl +++ b/fuchsia/runners/cast/fidl/application_config.fidl
@@ -6,6 +6,7 @@ library chromium.cast; using fuchsia.diagnostics; +using fuchsia.media; using fuchsia.ui.gfx; using fuchsia.web; @@ -44,7 +45,12 @@ /// [`fuchsia.logger/LogSink`] configured for this application. If not set, no /// messages will be logged. // TODO(crbug.com/1088094): Deprecate once there is another mechanism. - 10: initial_min_console_log_severity fuchsia.diagnostics.Severity; + 10: initial_min_console_log_severity fuchsia.diagnostics.Severity; + + /// The usage for [`fuchsia.media/AudioRenderer`] created by the app. If not + /// specified, then audio will be played through + /// [`fuchsia.media/AudioConsumer`]. + 11: audio_renderer_usage fuchsia.media.AudioRenderUsage; }; /// Service interface for working with application configurations.
diff --git a/fuchsia/runners/cast/fidl/application_context.fidl b/fuchsia/runners/cast/fidl/application_context.fidl index e6bc30fb..c5de66fe 100644 --- a/fuchsia/runners/cast/fidl/application_context.fidl +++ b/fuchsia/runners/cast/fidl/application_context.fidl
@@ -7,7 +7,9 @@ @discoverable protocol ApplicationContext { - /// Returns session_id to use in the AudioConsumer API. + /// Returns `session_id` to use in the AudioConsumer API. May return 0 + /// if there is no media session associated with the app. In this case + /// audio will be rendered through AudioRenderer. GetMediaSessionId() -> (struct { media_session_id uint64; });
diff --git a/fuchsia/runners/cast/pending_cast_component.cc b/fuchsia/runners/cast/pending_cast_component.cc index f67ec439..bf5e60f8 100644 --- a/fuchsia/runners/cast/pending_cast_component.cc +++ b/fuchsia/runners/cast/pending_cast_component.cc
@@ -110,10 +110,24 @@ ZX_LOG(ERROR, status) << "ApplicationContext disconnected."; delegate_->CancelPendingComponent(this); }); - application_context_->GetMediaSessionId([this](uint64_t session_id) { - params_.media_session_id = session_id; - MaybeLaunchComponent(); - }); + + if (params_.application_config.has_audio_renderer_usage()) { + DCHECK(!params_.media_settings); + params_.media_settings = fuchsia::web::FrameMediaSettings{}; + params_.media_settings->set_renderer_usage( + params_.application_config.audio_renderer_usage()); + } else { + // If `audio_renderer_usage` is not specified then `AudioConsumer` is used + // for that app. We need to fetch `session_id` in that case. + application_context_->GetMediaSessionId([this](uint64_t session_id) { + DCHECK(!params_.media_settings); + params_.media_settings = fuchsia::web::FrameMediaSettings{}; + if (session_id > 0) + params_.media_settings->set_audio_consumer_session_id(session_id); + + MaybeLaunchComponent(); + }); + } } void PendingCastComponent::OnApiBindingsInitialized() {
diff --git a/fuchsia/runners/web/web_runner.cmx b/fuchsia/runners/web/web_runner.cmx index cf99c070..c98e487 100644 --- a/fuchsia/runners/web/web_runner.cmx +++ b/fuchsia/runners/web/web_runner.cmx
@@ -14,6 +14,7 @@ "fuchsia.feedback.ComponentDataRegister", "fuchsia.feedback.CrashReportingProductRegister", "fuchsia.fonts.Provider", + "fuchsia.hwinfo.Product", "fuchsia.input.virtualkeyboard.ControllerCreator", "fuchsia.intl.PropertyProvider", "fuchsia.logger.LogSink",
diff --git a/infra/config/generated/builders/ci/Win x64 Builder/properties.json b/infra/config/generated/builders/ci/Win x64 Builder/properties.json index 44d3421e..4d0b417 100644 --- a/infra/config/generated/builders/ci/Win x64 Builder/properties.json +++ b/infra/config/generated/builders/ci/Win x64 Builder/properties.json
@@ -98,8 +98,8 @@ "project": "chromium" }, "builder_spec": { - "build_gs_bucket": "chromium-fyi-archive", - "builder_group": "chromium.fyi", + "build_gs_bucket": "chromium-win-archive", + "builder_group": "chromium.win", "execution_mode": "TEST", "legacy_chromium_config": { "apply_configs": [
diff --git a/infra/config/generated/builders/ci/Win11 Tests x64/properties.json b/infra/config/generated/builders/ci/Win11 Tests x64/properties.json index 86694361..13fd9d19 100644 --- a/infra/config/generated/builders/ci/Win11 Tests x64/properties.json +++ b/infra/config/generated/builders/ci/Win11 Tests x64/properties.json
@@ -37,8 +37,8 @@ "project": "chromium" }, "builder_spec": { - "build_gs_bucket": "chromium-fyi-archive", - "builder_group": "chromium.fyi", + "build_gs_bucket": "chromium-win-archive", + "builder_group": "chromium.win", "execution_mode": "TEST", "legacy_chromium_config": { "apply_configs": [ @@ -86,6 +86,9 @@ "v.test_suite" ] }, - "builder_group": "chromium.fyi", - "recipe": "chromium" + "builder_group": "chromium.win", + "recipe": "chromium", + "sheriff_rotations": [ + "chromium" + ] } \ No newline at end of file
diff --git a/infra/config/generated/builders/reclient/Linux Builder reclient test/properties.json b/infra/config/generated/builders/reclient/Linux Builder reclient test/properties.json index fa5b27b..669bb9e 100644 --- a/infra/config/generated/builders/reclient/Linux Builder reclient test/properties.json +++ b/infra/config/generated/builders/reclient/Linux Builder reclient test/properties.json
@@ -43,7 +43,7 @@ } }, "$build/reclient": { - "instance": "goma-foundry-experiments", + "instance": "rbe-chromium-trusted-test", "metrics_project": "chromium-reclient-metrics" }, "$recipe_engine/resultdb/test_presentation": {
diff --git a/infra/config/generated/builders/reclient/Simple Chrome Builder reclient test/properties.json b/infra/config/generated/builders/reclient/Simple Chrome Builder reclient test/properties.json index 69f2d9c..441ce26f1 100644 --- a/infra/config/generated/builders/reclient/Simple Chrome Builder reclient test/properties.json +++ b/infra/config/generated/builders/reclient/Simple Chrome Builder reclient test/properties.json
@@ -47,7 +47,7 @@ } }, "$build/reclient": { - "instance": "goma-foundry-experiments", + "instance": "rbe-chromium-trusted-test", "metrics_project": "chromium-reclient-metrics" }, "$recipe_engine/resultdb/test_presentation": {
diff --git a/infra/config/generated/builders/reclient/Win x64 Builder reclient test/properties.json b/infra/config/generated/builders/reclient/Win x64 Builder reclient test/properties.json index c978c0db..2e0af97c 100644 --- a/infra/config/generated/builders/reclient/Win x64 Builder reclient test/properties.json +++ b/infra/config/generated/builders/reclient/Win x64 Builder reclient test/properties.json
@@ -44,7 +44,7 @@ } }, "$build/reclient": { - "instance": "goma-foundry-experiments", + "instance": "rbe-chromium-trusted-test", "metrics_project": "chromium-reclient-metrics" }, "$recipe_engine/resultdb/test_presentation": {
diff --git a/infra/config/generated/builders/try/win11-x64-fyi-rel/properties.json b/infra/config/generated/builders/try/win11-x64-fyi-rel/properties.json index 741ef58e..db8d3402 100644 --- a/infra/config/generated/builders/try/win11-x64-fyi-rel/properties.json +++ b/infra/config/generated/builders/try/win11-x64-fyi-rel/properties.json
@@ -37,8 +37,8 @@ "project": "chromium" }, "builder_spec": { - "build_gs_bucket": "chromium-fyi-archive", - "builder_group": "chromium.fyi", + "build_gs_bucket": "chromium-win-archive", + "builder_group": "chromium.win", "execution_mode": "TEST", "legacy_chromium_config": { "apply_configs": [
diff --git a/infra/config/generated/luci/cr-buildbucket.cfg b/infra/config/generated/luci/cr-buildbucket.cfg index 35844765..65f0064 100644 --- a/infra/config/generated/luci/cr-buildbucket.cfg +++ b/infra/config/generated/luci/cr-buildbucket.cfg
@@ -21068,7 +21068,7 @@ dimensions: "builderless:1" dimensions: "cores:8" dimensions: "cpu:x86-64" - dimensions: "os:Windows-10" + dimensions: "os:Ubuntu-18.04" dimensions: "pool:luci.chromium.ci" dimensions: "ssd:0" exe { @@ -21097,11 +21097,14 @@ ' }' ' }' ' },' - ' "builder_group": "chromium.fyi",' + ' "builder_group": "chromium.win",' ' "led_builder_is_bootstrapped": true,' - ' "recipe": "chromium"' + ' "recipe": "chromium",' + ' "sheriff_rotations": [' + ' "chromium"' + ' ]' '}' - execution_timeout_secs: 36000 + execution_timeout_secs: 10800 build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments {
diff --git a/infra/config/generated/luci/luci-milo.cfg b/infra/config/generated/luci/luci-milo.cfg index 43383ac..238366a 100644 --- a/infra/config/generated/luci/luci-milo.cfg +++ b/infra/config/generated/luci/luci-milo.cfg
@@ -141,6 +141,11 @@ short_name: "w10" } builders { + name: "buildbucket/luci.chromium.ci/Win11 Tests x64" + category: "chromium.win|release|tester" + short_name: "w11" + } + builders { name: "buildbucket/luci.chromium.ci/Win x64 Builder (dbg)" category: "chromium.win|debug|builder" short_name: "64" @@ -7851,10 +7856,6 @@ category: "win10" } builders { - name: "buildbucket/luci.chromium.ci/Win11 Tests x64" - category: "win11" - } - builders { name: "buildbucket/luci.chromium.ci/win32-arm64-rel" category: "win32|arm64" } @@ -14098,6 +14099,11 @@ short_name: "w10" } builders { + name: "buildbucket/luci.chromium.ci/Win11 Tests x64" + category: "release|tester" + short_name: "w11" + } + builders { name: "buildbucket/luci.chromium.ci/Win x64 Builder (dbg)" category: "debug|builder" short_name: "64"
diff --git a/infra/config/generated/sheriff-rotations/chromium.txt b/infra/config/generated/sheriff-rotations/chromium.txt index b7117b0..bcffceae 100644 --- a/infra/config/generated/sheriff-rotations/chromium.txt +++ b/infra/config/generated/sheriff-rotations/chromium.txt
@@ -45,6 +45,7 @@ ci/Win x64 Builder ci/Win x64 Builder (dbg) ci/Win10 Tests x64 +ci/Win11 Tests x64 ci/Win7 (32) Tests ci/Win7 Tests (1) ci/Windows deterministic
diff --git a/infra/config/subprojects/chromium/ci/chromium.fyi.star b/infra/config/subprojects/chromium/ci/chromium.fyi.star index ed62f69..dc1af2ff 100644 --- a/infra/config/subprojects/chromium/ci/chromium.fyi.star +++ b/infra/config/subprojects/chromium/ci/chromium.fyi.star
@@ -1605,39 +1605,6 @@ ) ci.builder( - name = "Win11 Tests x64", - builder_spec = builder_config.builder_spec( - execution_mode = builder_config.execution_mode.TEST, - gclient_config = builder_config.gclient_config( - config = "chromium", - apply_configs = [ - "use_clang_coverage", - ], - ), - chromium_config = builder_config.chromium_config( - config = "chromium", - apply_configs = [ - "mb", - ], - build_config = builder_config.build_config.RELEASE, - target_bits = 64, - target_platform = builder_config.target_platform.WIN, - ), - build_gs_bucket = "chromium-fyi-archive", - ), - builderless = True, - console_view_entry = consoles.console_view_entry( - category = "win11", - ), - goma_backend = None, - main_console_view = None, - # TODO(gbeaty) Investigate if this needs to run on windows, if not switch to - # ci.thin_tester - os = os.WINDOWS_10, - triggered_by = ["ci/Win x64 Builder"], -) - -ci.builder( name = "win32-arm64-rel", console_view_entry = consoles.console_view_entry( category = "win32|arm64",
diff --git a/infra/config/subprojects/chromium/ci/chromium.win.star b/infra/config/subprojects/chromium/ci/chromium.win.star index 8d2027c..21e64356 100644 --- a/infra/config/subprojects/chromium/ci/chromium.win.star +++ b/infra/config/subprojects/chromium/ci/chromium.win.star
@@ -320,6 +320,35 @@ triggered_by = ["ci/Win x64 Builder"], ) +ci.thin_tester( + name = "Win11 Tests x64", + builder_spec = builder_config.builder_spec( + execution_mode = builder_config.execution_mode.TEST, + gclient_config = builder_config.gclient_config( + config = "chromium", + apply_configs = [ + "use_clang_coverage", + ], + ), + chromium_config = builder_config.chromium_config( + config = "chromium", + apply_configs = [ + "mb", + ], + build_config = builder_config.build_config.RELEASE, + target_bits = 64, + target_platform = builder_config.target_platform.WIN, + ), + build_gs_bucket = "chromium-win-archive", + ), + console_view_entry = consoles.console_view_entry( + category = "release|tester", + short_name = "w11", + ), + triggered_by = ["ci/Win x64 Builder"], + tree_closing = False, +) + ci.builder( name = "Windows deterministic", console_view_entry = consoles.console_view_entry(
diff --git a/infra/config/subprojects/reclient/reclient.star b/infra/config/subprojects/reclient/reclient.star index ad898d6..6d678b5 100644 --- a/infra/config/subprojects/reclient/reclient.star +++ b/infra/config/subprojects/reclient/reclient.star
@@ -74,7 +74,7 @@ return fyi_reclient_staging_builder( name = name, console_view_category = console_view_category, - reclient_instance = "goma-foundry-experiments", + reclient_instance = "rbe-chromium-trusted-test", **kwargs )
diff --git a/ios/chrome/browser/ui/follow/first_follow_view_controller.mm b/ios/chrome/browser/ui/follow/first_follow_view_controller.mm index 1b914a42..c0aa8d8 100644 --- a/ios/chrome/browser/ui/follow/first_follow_view_controller.mm +++ b/ios/chrome/browser/ui/follow/first_follow_view_controller.mm
@@ -23,7 +23,7 @@ namespace { constexpr CGFloat customSpacingBeforeImageIfNoToolbar = 24; -constexpr CGFloat customSpacingAfterImage = 1; +constexpr CGFloat customSpacingAfterImage = 24; } // namespace @@ -72,4 +72,18 @@ [super viewDidLoad]; } +#pragma mark - ConfirmationAlertViewController + +- (void)updateStylingForSecondaryTitleLabel:(UILabel*)secondaryTitleLabel { + secondaryTitleLabel.font = + [UIFont preferredFontForTextStyle:UIFontTextStyleBody]; + secondaryTitleLabel.textColor = [UIColor colorNamed:kTextSecondaryColor]; +} + +- (void)updateStylingForSubtitleLabel:(UILabel*)subtitleLabel { + subtitleLabel.font = + [UIFont preferredFontForTextStyle:UIFontTextStyleFootnote]; + subtitleLabel.textColor = [UIColor colorNamed:kTextTertiaryColor]; +} + @end
diff --git a/ios/chrome/browser/web/https_only_mode_egtest.mm b/ios/chrome/browser/web/https_only_mode_egtest.mm index 795b2c6..d2773280 100644 --- a/ios/chrome/browser/web/https_only_mode_egtest.mm +++ b/ios/chrome/browser/web/https_only_mode_egtest.mm
@@ -497,11 +497,9 @@ // elements. Not currently supported by MetricsAppInterface. } -// Navigate to an HTTP URL and allowlist the URL. Then clear browsing data via -// UI settings. This should clear the HTTP allowlist. -// Disable the test due to try bot failure. -// TODO (crbug.com/1328537): please re-enable it after fix. -- (void)DISABLED_testUpgrade_RemoveBrowsingData_ShouldClearAllowlist { +// Navigate to an HTTP URL and allowlist the URL. Then clear browsing data. +// This should clear the HTTP allowlist. +- (void)testUpgrade_RemoveBrowsingData_ShouldClearAllowlist { [HttpsOnlyModeAppInterface setHTTPPortForTesting:self.testServer->port()]; [HttpsOnlyModeAppInterface setHTTPSPortForTesting:self.badHTTPSServer->port()]; @@ -524,15 +522,16 @@ [ChromeEarlGrey waitForWebStateContainingText:"HTTP_RESPONSE"]; [self assertFailedUpgrade:1]; - // Clear the allowlist by clearing the browsing data. - [ChromeEarlGreyUI clearAllBrowsingData]; + // Clear the allowlist by clearing the browsing data. This clears the history + // programmatically, so it won't automatically reload the tabs. + [ChromeEarlGrey clearBrowsingHistory]; - // Clearing the browsing data automatically reloads tabs. Check that the - // interstitial is showing. + // Reloading the should show the interstitial again. + [ChromeEarlGrey reload]; [ChromeEarlGrey waitForWebStateContainingText:kInterstitialText]; [self assertFailedUpgrade:2]; - // Reloading the should show the interstitial again. + // Reload once more. [ChromeEarlGrey reload]; [ChromeEarlGrey waitForWebStateContainingText:kInterstitialText]; [self assertFailedUpgrade:3];
diff --git a/ios/chrome/common/ui/confirmation_alert/confirmation_alert_view_controller.h b/ios/chrome/common/ui/confirmation_alert/confirmation_alert_view_controller.h index 14fd3e4c..9d5545d 100644 --- a/ios/chrome/common/ui/confirmation_alert/confirmation_alert_view_controller.h +++ b/ios/chrome/common/ui/confirmation_alert/confirmation_alert_view_controller.h
@@ -92,6 +92,14 @@ // The action handler for interactions in this View Controller. @property(nonatomic, weak) id<ConfirmationAlertActionHandler> actionHandler; +// Updates the style of the secondary title label. The default implementation +// does nothing, but subclasses can override to customize the styling if needed. +- (void)updateStylingForSecondaryTitleLabel:(UILabel*)secondaryTitleLabel; + +// Updates the style of the subtitle label. The default implementation does +// nothing, but subclasses can override to customize the styling if needed. +- (void)updateStylingForSubtitleLabel:(UILabel*)subtitleLabel; + @end #endif // IOS_CHROME_COMMON_UI_CONFIRMATION_ALERT_CONFIRMATION_ALERT_VIEW_CONTROLLER_H_
diff --git a/ios/chrome/common/ui/confirmation_alert/confirmation_alert_view_controller.mm b/ios/chrome/common/ui/confirmation_alert/confirmation_alert_view_controller.mm index 285772b7..8176a70 100644 --- a/ios/chrome/common/ui/confirmation_alert/confirmation_alert_view_controller.mm +++ b/ios/chrome/common/ui/confirmation_alert/confirmation_alert_view_controller.mm
@@ -355,6 +355,16 @@ [super updateViewConstraints]; } +- (void)updateStylingForSecondaryTitleLabel:(UILabel*)secondaryTitleLabel { + // The subclass needs to overwrite this method if it wants a different style + // than the default. +} + +- (void)updateStylingForSubtitleLabel:(UILabel*)subtitleLabel { + // The subclass need to overwrite this method if it wants a different style + // than the default. +} + #pragma mark - UIToolbarDelegate - (UIBarPosition)positionForBar:(id<UIBarPositioning>)bar { @@ -576,6 +586,7 @@ secondaryTitle.textColor = [UIColor colorNamed:kTextPrimaryColor]; secondaryTitle.accessibilityIdentifier = kConfirmationAlertSecondaryTitleAccessibilityIdentifier; + [self updateStylingForSecondaryTitleLabel:secondaryTitle]; return secondaryTitle; } @@ -587,6 +598,7 @@ subtitle.textColor = [UIColor colorNamed:kTextSecondaryColor]; subtitle.accessibilityIdentifier = kConfirmationAlertSubtitleAccessibilityIdentifier; + [self updateStylingForSubtitleLabel:subtitle]; return subtitle; } @@ -616,7 +628,7 @@ UIStackView* stackView = [[UIStackView alloc] initWithArrangedSubviews:subviews]; [stackView setCustomSpacing:self.customSpacingAfterImage - afterView:self.imageView]; + afterView:self.imageContainerView]; if (self.imageHasFixedSize) { stackView.alignment = UIStackViewAlignmentCenter;
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 37301303..0d8322f7 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 @@ -49dea002efe50d5b2afa7801722f528fae4690cd \ No newline at end of file +3ffa9f20af779101683df99836b761fd89f43c55 \ 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 6bcf3fa9..dd83092 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 @@ -c464b40893e172acc8f4b1bdabe3b6fb97837b10 \ No newline at end of file +52e880781f1879e60a722e5997b9635d08101e49 \ 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 68e388c..d8debfb 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 @@ -9c3d82a1f8a9777182f787071c8b27532608b656 \ No newline at end of file +a9a93893e61e91c2e90107b868a2c04943c809ea \ 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 8f4b2696..6104c66 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 @@ -5c2addb7d3571a84098ee850138227b6868242c2 \ No newline at end of file +8f69268988df5bef7f9eb4df06f7a3cdfa45a448 \ 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 ac11efc1..4cd11bfa 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 @@ -bd8c0cf3119062a12e0beef8b9dedff1d379cf1a \ No newline at end of file +7c60bf5755b7e85edf6da605865a8490d46217e4 \ 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 cfa68ef..247778b2 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 @@ -d05f25eb80a9d6d458b3ef2170b23eb66ad46355 \ No newline at end of file +e6f2bc03dbdaad5c65ee945205af004deebd29d6 \ 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 7661a887..6ffd005 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 @@ -e245fa17945ff53c9d1bfdf7043c2e67de976cae \ No newline at end of file +ae0af028a3e73e4b57db305881e440a118c8bf07 \ 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 c318f95..170ff3e 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 @@ -ea905e765ee27aec5170b53c7dc86df4b85d00b9 \ No newline at end of file +70c9175177555752adc2fcc38431c03d8bf01321 \ 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 b84828d..0be0221 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 @@ -b3bb22c0370139194dc85c8e5a6a42792dbfe868 \ No newline at end of file +717878862ded05ee8cc0bbd164b1d80a4a48a087 \ 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 c6812589..12ebad2 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 @@ -fa67459c82ae15f891186788655fefca6936243f \ No newline at end of file +0d8869de893986a8dc56028232fc25bc834fa320 \ No newline at end of file
diff --git a/ios/web/find_in_page/find_in_page_manger_impl_unittest.mm b/ios/web/find_in_page/find_in_page_manger_impl_unittest.mm index f393d1e6..dc75afc1 100644 --- a/ios/web/find_in_page/find_in_page_manger_impl_unittest.mm +++ b/ios/web/find_in_page/find_in_page_manger_impl_unittest.mm
@@ -113,11 +113,11 @@ return fake_delegate_.state(); })); ASSERT_EQ(2ul, frame_with_one_match_ptr->GetJavaScriptCallHistory().size()); - EXPECT_EQ("__gCrWeb.findInPage.selectAndScrollToVisibleMatch(0);", + EXPECT_EQ(u"__gCrWeb.findInPage.selectAndScrollToVisibleMatch(0);", frame_with_one_match_ptr->GetJavaScriptCallHistory()[1]); - EXPECT_EQ("__gCrWeb.findInPage.findString(\"foo\", 100.0);", + EXPECT_EQ(u"__gCrWeb.findInPage.findString(\"foo\", 100.0);", frame_with_one_match_ptr->GetJavaScriptCallHistory()[0]); - EXPECT_EQ("__gCrWeb.findInPage.findString(\"foo\", 100.0);", + EXPECT_EQ(u"__gCrWeb.findInPage.findString(\"foo\", 100.0);", frame_with_two_matches_ptr->GetLastJavaScriptCall()); EXPECT_EQ(3, fake_delegate_.state()->match_count); } @@ -142,12 +142,12 @@ base::RunLoop().RunUntilIdle(); return fake_delegate_.state(); })); - EXPECT_EQ("__gCrWeb.findInPage.findString(\"foo\", 100.0);", + EXPECT_EQ(u"__gCrWeb.findInPage.findString(\"foo\", 100.0);", frame_with_null_result_ptr->GetLastJavaScriptCall()); ASSERT_EQ(2ul, frame_with_one_match_ptr->GetJavaScriptCallHistory().size()); - EXPECT_EQ("__gCrWeb.findInPage.selectAndScrollToVisibleMatch(0);", + EXPECT_EQ(u"__gCrWeb.findInPage.selectAndScrollToVisibleMatch(0);", frame_with_one_match_ptr->GetJavaScriptCallHistory()[1]); - EXPECT_EQ("__gCrWeb.findInPage.findString(\"foo\", 100.0);", + EXPECT_EQ(u"__gCrWeb.findInPage.findString(\"foo\", 100.0);", frame_with_one_match_ptr->GetJavaScriptCallHistory()[0]); EXPECT_EQ(1, fake_delegate_.state()->match_count); } @@ -179,11 +179,11 @@ return fake_delegate_.state(); })); ASSERT_EQ(3ul, frame_with_two_matches_ptr->GetJavaScriptCallHistory().size()); - EXPECT_EQ("__gCrWeb.findInPage.selectAndScrollToVisibleMatch(0);", + EXPECT_EQ(u"__gCrWeb.findInPage.selectAndScrollToVisibleMatch(0);", frame_with_two_matches_ptr->GetJavaScriptCallHistory()[2]); - EXPECT_EQ("__gCrWeb.findInPage.findString(\"foo\", 100.0);", + EXPECT_EQ(u"__gCrWeb.findInPage.findString(\"foo\", 100.0);", frame_with_two_matches_ptr->GetJavaScriptCallHistory()[1]); - EXPECT_EQ("__gCrWeb.findInPage.findString(\"foo\", 100.0);", + EXPECT_EQ(u"__gCrWeb.findInPage.findString(\"foo\", 100.0);", frame_with_two_matches_ptr->GetJavaScriptCallHistory()[0]); EXPECT_EQ(2, fake_delegate_.state()->match_count); } @@ -228,9 +228,9 @@ })); ASSERT_EQ(2ul, frame_with_one_match_ptr->GetJavaScriptCallHistory().size()); - EXPECT_EQ("__gCrWeb.findInPage.selectAndScrollToVisibleMatch(0);", + EXPECT_EQ(u"__gCrWeb.findInPage.selectAndScrollToVisibleMatch(0);", frame_with_one_match_ptr->GetJavaScriptCallHistory()[1]); - EXPECT_EQ("__gCrWeb.findInPage.findString(\"foo\", 100.0);", + EXPECT_EQ(u"__gCrWeb.findInPage.findString(\"foo\", 100.0);", frame_with_one_match_ptr->GetJavaScriptCallHistory()[0]); EXPECT_EQ(1, fake_delegate_.state()->match_count); } @@ -259,13 +259,13 @@ return fake_delegate_.state(); })); ASSERT_EQ(3ul, frame_with_two_matches_ptr->GetJavaScriptCallHistory().size()); - EXPECT_EQ("__gCrWeb.findInPage.selectAndScrollToVisibleMatch(0);", + EXPECT_EQ(u"__gCrWeb.findInPage.selectAndScrollToVisibleMatch(0);", frame_with_two_matches_ptr->GetJavaScriptCallHistory()[2]); - EXPECT_EQ("__gCrWeb.findInPage.pumpSearch(100.0);", + EXPECT_EQ(u"__gCrWeb.findInPage.pumpSearch(100.0);", frame_with_two_matches_ptr->GetJavaScriptCallHistory()[1]); - EXPECT_EQ("__gCrWeb.findInPage.findString(\"foo\", 100.0);", + EXPECT_EQ(u"__gCrWeb.findInPage.findString(\"foo\", 100.0);", frame_with_two_matches_ptr->GetJavaScriptCallHistory()[0]); - EXPECT_EQ("__gCrWeb.findInPage.findString(\"foo\", 100.0);", + EXPECT_EQ(u"__gCrWeb.findInPage.findString(\"foo\", 100.0);", frame_with_one_match_ptr->GetLastJavaScriptCall()); EXPECT_EQ(3, fake_delegate_.state()->match_count); } @@ -280,7 +280,7 @@ GetFindInPageManager()->Find(@"foo", FindInPageOptions::FindInPageSearch); - EXPECT_EQ("__gCrWeb.findInPage.findString(\"foo\", 100.0);", + EXPECT_EQ(u"__gCrWeb.findInPage.findString(\"foo\", 100.0);", frame_with_one_match_ptr->GetLastJavaScriptCall()); base::RunLoop().RunUntilIdle(); } @@ -332,7 +332,7 @@ })); ASSERT_EQ(1ul, frame_with_zero_matches_ptr->GetJavaScriptCallHistory().size()); - EXPECT_EQ("__gCrWeb.findInPage.findString(\"foo\", 100.0);", + EXPECT_EQ(u"__gCrWeb.findInPage.findString(\"foo\", 100.0);", frame_with_zero_matches_ptr->GetJavaScriptCallHistory()[0]); EXPECT_EQ(0, fake_delegate_.state()->match_count); EXPECT_EQ(-1, fake_delegate_.state()->index); @@ -354,9 +354,9 @@ return fake_delegate_.state(); })); ASSERT_EQ(2ul, frame_with_two_matches_ptr->GetJavaScriptCallHistory().size()); - EXPECT_EQ("__gCrWeb.findInPage.selectAndScrollToVisibleMatch(0);", + EXPECT_EQ(u"__gCrWeb.findInPage.selectAndScrollToVisibleMatch(0);", frame_with_two_matches_ptr->GetJavaScriptCallHistory()[1]); - EXPECT_EQ("__gCrWeb.findInPage.findString(\"foo\", 100.0);", + EXPECT_EQ(u"__gCrWeb.findInPage.findString(\"foo\", 100.0);", frame_with_two_matches_ptr->GetJavaScriptCallHistory()[0]); EXPECT_EQ(0, fake_delegate_.state()->index); } @@ -377,9 +377,9 @@ return fake_delegate_.state(); })); ASSERT_EQ(2ul, frame_with_two_matches_ptr->GetJavaScriptCallHistory().size()); - EXPECT_EQ("__gCrWeb.findInPage.selectAndScrollToVisibleMatch(0);", + EXPECT_EQ(u"__gCrWeb.findInPage.selectAndScrollToVisibleMatch(0);", frame_with_two_matches_ptr->GetJavaScriptCallHistory()[1]); - EXPECT_EQ("__gCrWeb.findInPage.findString(\"foo\", 100.0);", + EXPECT_EQ(u"__gCrWeb.findInPage.findString(\"foo\", 100.0);", frame_with_two_matches_ptr->GetJavaScriptCallHistory()[0]); GetFindInPageManager()->Find(@"foo", FindInPageOptions::FindInPageNext); @@ -388,7 +388,7 @@ base::RunLoop().RunUntilIdle(); return fake_delegate_.state()->index > -1; })); - EXPECT_EQ("__gCrWeb.findInPage.selectAndScrollToVisibleMatch(1);", + EXPECT_EQ(u"__gCrWeb.findInPage.selectAndScrollToVisibleMatch(1);", frame_with_two_matches_ptr->GetLastJavaScriptCall()); EXPECT_EQ(1, fake_delegate_.state()->index); } @@ -414,7 +414,7 @@ return fake_delegate_.state(); })); EXPECT_EQ(0, fake_delegate_.state()->index); - EXPECT_EQ("__gCrWeb.findInPage.selectAndScrollToVisibleMatch(0);", + EXPECT_EQ(u"__gCrWeb.findInPage.selectAndScrollToVisibleMatch(0);", frame_with_one_match_ptr->GetLastJavaScriptCall()); GetFindInPageManager()->Find(@"foo", FindInPageOptions::FindInPageNext); @@ -423,7 +423,7 @@ return fake_delegate_.state(); })); EXPECT_EQ(1, fake_delegate_.state()->index); - EXPECT_EQ("__gCrWeb.findInPage.selectAndScrollToVisibleMatch(0);", + EXPECT_EQ(u"__gCrWeb.findInPage.selectAndScrollToVisibleMatch(0);", frame_with_two_matches_ptr->GetLastJavaScriptCall()); GetFindInPageManager()->Find(@"foo", FindInPageOptions::FindInPageNext); @@ -432,7 +432,7 @@ return fake_delegate_.state(); })); EXPECT_EQ(2, fake_delegate_.state()->index); - EXPECT_EQ("__gCrWeb.findInPage.selectAndScrollToVisibleMatch(1);", + EXPECT_EQ(u"__gCrWeb.findInPage.selectAndScrollToVisibleMatch(1);", frame_with_two_matches_ptr->GetLastJavaScriptCall()); GetFindInPageManager()->Find(@"foo", FindInPageOptions::FindInPageNext); @@ -441,7 +441,7 @@ return fake_delegate_.state(); })); EXPECT_EQ(0, fake_delegate_.state()->index); - EXPECT_EQ("__gCrWeb.findInPage.selectAndScrollToVisibleMatch(0);", + EXPECT_EQ(u"__gCrWeb.findInPage.selectAndScrollToVisibleMatch(0);", frame_with_one_match_ptr->GetLastJavaScriptCall()); } @@ -467,7 +467,7 @@ return fake_delegate_.state(); })); EXPECT_EQ(0, fake_delegate_.state()->index); - EXPECT_EQ("__gCrWeb.findInPage.selectAndScrollToVisibleMatch(0);", + EXPECT_EQ(u"__gCrWeb.findInPage.selectAndScrollToVisibleMatch(0);", frame_with_one_match_ptr->GetLastJavaScriptCall()); GetFindInPageManager()->Find(@"foo", FindInPageOptions::FindInPagePrevious); @@ -477,7 +477,7 @@ return fake_delegate_.state(); })); EXPECT_EQ(2, fake_delegate_.state()->index); - EXPECT_EQ("__gCrWeb.findInPage.selectAndScrollToVisibleMatch(1);", + EXPECT_EQ(u"__gCrWeb.findInPage.selectAndScrollToVisibleMatch(1);", frame_with_two_matches_ptr->GetLastJavaScriptCall()); GetFindInPageManager()->Find(@"foo", FindInPageOptions::FindInPagePrevious); @@ -487,7 +487,7 @@ return fake_delegate_.state(); })); EXPECT_EQ(1, fake_delegate_.state()->index); - EXPECT_EQ("__gCrWeb.findInPage.selectAndScrollToVisibleMatch(0);", + EXPECT_EQ(u"__gCrWeb.findInPage.selectAndScrollToVisibleMatch(0);", frame_with_two_matches_ptr->GetLastJavaScriptCall()); GetFindInPageManager()->Find(@"foo", FindInPageOptions::FindInPagePrevious); @@ -497,7 +497,7 @@ return fake_delegate_.state(); })); EXPECT_EQ(0, fake_delegate_.state()->index); - EXPECT_EQ("__gCrWeb.findInPage.selectAndScrollToVisibleMatch(0);", + EXPECT_EQ(u"__gCrWeb.findInPage.selectAndScrollToVisibleMatch(0);", frame_with_one_match_ptr->GetLastJavaScriptCall()); } @@ -521,12 +521,12 @@ base::RunLoop().RunUntilIdle(); return fake_delegate_.state(); })); - EXPECT_EQ("__gCrWeb.findInPage.findString(\"foo\", 100.0);", + EXPECT_EQ(u"__gCrWeb.findInPage.findString(\"foo\", 100.0);", frame_with_two_matches_ptr->GetLastJavaScriptCall()); ASSERT_EQ(2ul, frame_with_one_match_ptr->GetJavaScriptCallHistory().size()); - EXPECT_EQ("__gCrWeb.findInPage.selectAndScrollToVisibleMatch(0);", + EXPECT_EQ(u"__gCrWeb.findInPage.selectAndScrollToVisibleMatch(0);", frame_with_one_match_ptr->GetJavaScriptCallHistory()[1]); - EXPECT_EQ("__gCrWeb.findInPage.findString(\"foo\", 100.0);", + EXPECT_EQ(u"__gCrWeb.findInPage.findString(\"foo\", 100.0);", frame_with_one_match_ptr->GetJavaScriptCallHistory()[0]); GetFindInPageManager()->Find(@"foo", FindInPageOptions::FindInPagePrevious); @@ -535,7 +535,7 @@ base::RunLoop().RunUntilIdle(); return fake_delegate_.state()->index == 2; })); - EXPECT_EQ("__gCrWeb.findInPage.selectAndScrollToVisibleMatch(1);", + EXPECT_EQ(u"__gCrWeb.findInPage.selectAndScrollToVisibleMatch(1);", frame_with_two_matches_ptr->GetLastJavaScriptCall()); } @@ -580,7 +580,7 @@ return fake_delegate_.state(); })); ASSERT_EQ(2ul, frame_with_one_match_ptr->GetJavaScriptCallHistory().size()); - EXPECT_EQ("__gCrWeb.findInPage.selectAndScrollToVisibleMatch(0);", + EXPECT_EQ(u"__gCrWeb.findInPage.selectAndScrollToVisibleMatch(0);", frame_with_one_match_ptr->GetJavaScriptCallHistory()[1]); RemoveWebFrame(kMainFakeFrameId); @@ -590,7 +590,7 @@ base::RunLoop().RunUntilIdle(); return fake_delegate_.state()->index == 0; })); - EXPECT_EQ("__gCrWeb.findInPage.selectAndScrollToVisibleMatch(0);", + EXPECT_EQ(u"__gCrWeb.findInPage.selectAndScrollToVisibleMatch(0);", frame_with_two_matches_ptr->GetLastJavaScriptCall()); }
diff --git a/ios/web/public/test/fakes/fake_web_frame.h b/ios/web/public/test/fakes/fake_web_frame.h index dcc2ace..afd7f82 100644 --- a/ios/web/public/test/fakes/fake_web_frame.h +++ b/ios/web/public/test/fakes/fake_web_frame.h
@@ -38,11 +38,14 @@ static std::unique_ptr<FakeWebFrame> CreateChildWebFrame( GURL security_origin); - // Returns the most recent JavaScript handler call made to this frame. - virtual std::string GetLastJavaScriptCall() const = 0; + // Returns the most recent JavaScript call made to this frame. + virtual std::u16string GetLastJavaScriptCall() const = 0; // Returns |javascript_calls|. Use LastJavaScriptCall() if possible. - virtual const std::vector<std::string>& GetJavaScriptCallHistory() = 0; + virtual const std::vector<std::u16string>& GetJavaScriptCallHistory() = 0; + + // Clears the history of javascript calls sent to this frame. + virtual void ClearJavaScriptCallHistory() = 0; // Sets the browser state associated with this frame. virtual void set_browser_state(BrowserState* browser_state) = 0;
diff --git a/ios/web/test/fakes/fake_web_frame_impl.cc b/ios/web/test/fakes/fake_web_frame_impl.cc index c0787cdf..566c01ca 100644 --- a/ios/web/test/fakes/fake_web_frame_impl.cc +++ b/ios/web/test/fakes/fake_web_frame_impl.cc
@@ -10,6 +10,7 @@ #include "base/bind.h" #include "base/callback.h" #include "base/json/json_writer.h" +#include "base/strings/utf_string_conversions.h" #include "base/values.h" #include "ios/web/public/thread/web_task_traits.h" #include "ios/web/public/thread/web_thread.h" @@ -90,18 +91,19 @@ call_java_script_function_callback_.Run(); } - std::string javascript_call = std::string("__gCrWeb." + name + "("); + std::u16string javascript_call = + std::u16string(u"__gCrWeb." + base::UTF8ToUTF16(name) + u"("); bool first = true; for (auto& param : parameters) { if (!first) { - javascript_call += ", "; + javascript_call += u", "; } first = false; std::string paramString; base::JSONWriter::Write(param, ¶mString); - javascript_call += paramString; + javascript_call += base::UTF8ToUTF16(paramString); } - javascript_call += ");"; + javascript_call += u");"; java_script_calls_.push_back(javascript_call); return can_call_function_; } @@ -145,18 +147,21 @@ } bool FakeWebFrameImpl::ExecuteJavaScript(const std::u16string& script) { + java_script_calls_.push_back(script); return false; } bool FakeWebFrameImpl::ExecuteJavaScript( const std::u16string& script, base::OnceCallback<void(const base::Value*)> callback) { + java_script_calls_.push_back(script); return false; } bool FakeWebFrameImpl::ExecuteJavaScript( const std::u16string& script, base::OnceCallback<void(const base::Value*, bool)> callback) { + java_script_calls_.push_back(script); return false; } @@ -170,14 +175,19 @@ return last_received_content_world_; } -std::string FakeWebFrameImpl::GetLastJavaScriptCall() const { - return java_script_calls_.size() == 0 ? "" : java_script_calls_.back(); +std::u16string FakeWebFrameImpl::GetLastJavaScriptCall() const { + return java_script_calls_.size() == 0 ? u"" : java_script_calls_.back(); } -const std::vector<std::string>& FakeWebFrameImpl::GetJavaScriptCallHistory() { +const std::vector<std::u16string>& +FakeWebFrameImpl::GetJavaScriptCallHistory() { return java_script_calls_; } +void FakeWebFrameImpl::ClearJavaScriptCallHistory() { + java_script_calls_.clear(); +} + void FakeWebFrameImpl::set_browser_state(BrowserState* browser_state) { browser_state_ = browser_state; }
diff --git a/ios/web/test/fakes/fake_web_frame_impl.h b/ios/web/test/fakes/fake_web_frame_impl.h index f21d3de3..556a98b 100644 --- a/ios/web/test/fakes/fake_web_frame_impl.h +++ b/ios/web/test/fakes/fake_web_frame_impl.h
@@ -50,8 +50,9 @@ base::OnceCallback<void(const base::Value*, bool)> callback) override; // FakeWebFrame: - std::string GetLastJavaScriptCall() const override; - const std::vector<std::string>& GetJavaScriptCallHistory() override; + std::u16string GetLastJavaScriptCall() const override; + const std::vector<std::u16string>& GetJavaScriptCallHistory() override; + void ClearJavaScriptCallHistory() override; void set_browser_state(BrowserState* browser_state) override; void AddJsResultForFunctionCall(base::Value* js_result, const std::string& function_name) override; @@ -98,7 +99,7 @@ GURL security_origin_; // Vector holding history of all javascript handler calls made in this frame. // The calls are sorted with the most recent appended at the end. - std::vector<std::string> java_script_calls_; + std::vector<std::u16string> java_script_calls_; // The return value of CanCallJavaScriptFunction(). bool can_call_function_ = true; // When set to true, will force calls to CallJavaScriptFunction to fail with
diff --git a/media/audio/fuchsia/audio_output_stream_fuchsia.cc b/media/audio/fuchsia/audio_output_stream_fuchsia.cc index d2f112e6..3ec94836 100644 --- a/media/audio/fuchsia/audio_output_stream_fuchsia.cc +++ b/media/audio/fuchsia/audio_output_stream_fuchsia.cc
@@ -24,6 +24,8 @@ fuchsia::media::AudioRenderUsage GetStreamUsage( const AudioParameters& parameters) { + // TODO(crbug.com/1253010) In WebEngine: use `audio_renderer_usage` from the + // `FrameMediaSettings` for the current web frame. if (parameters.latency_tag() == AudioLatency::LATENCY_RTC) return fuchsia::media::AudioRenderUsage::COMMUNICATION; return fuchsia::media::AudioRenderUsage::MEDIA;
diff --git a/media/base/decoder_status.cc b/media/base/decoder_status.cc index 777aed6..caba2464 100644 --- a/media/base/decoder_status.cc +++ b/media/base/decoder_status.cc
@@ -30,7 +30,6 @@ STRINGIFY(DecoderStatus::Codes::kMalformedBitstream); STRINGIFY(DecoderStatus::Codes::kFailedToGetDecoderBuffer); STRINGIFY(DecoderStatus::Codes::kDecoderStreamInErrorState); - STRINGIFY(DecoderStatus::Codes::kDecoderStreamReinitFailed); STRINGIFY(DecoderStatus::Codes::kDecoderStreamDemuxerError); STRINGIFY(DecoderStatus::Codes::kUnsupportedProfile); STRINGIFY(DecoderStatus::Codes::kUnsupportedCodec);
diff --git a/media/base/decoder_status.h b/media/base/decoder_status.h index bb7ec80..1142cb6 100644 --- a/media/base/decoder_status.h +++ b/media/base/decoder_status.h
@@ -28,7 +28,6 @@ kMalformedBitstream = 104, kFailedToGetDecoderBuffer = 107, kDecoderStreamInErrorState = 108, - kDecoderStreamReinitFailed = 109, kDecoderStreamDemuxerError = 110, kKeyFrameRequired = 111, kMissingTimestamp = 112,
diff --git a/media/base/status.h b/media/base/status.h index 78ac9c5..345a31a7 100644 --- a/media/base/status.h +++ b/media/base/status.h
@@ -538,7 +538,12 @@ // Return constref of the value, if we have one. // Callers should ensure that this |has_value()|. - const OtherType& operator->() { + const OtherType& operator->() const { + CHECK(value_); + return std::get<0>(*value_); + } + + const OtherType& operator*() const { CHECK(value_); return std::get<0>(*value_); }
diff --git a/media/filters/decoder_selector.cc b/media/filters/decoder_selector.cc index d13c5264..23a28d21 100644 --- a/media/filters/decoder_selector.cc +++ b/media/filters/decoder_selector.cc
@@ -152,7 +152,7 @@ DVLOG(2) << __func__; DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (select_decoder_cb_) - ReturnNullDecoder(); + ReturnSelectionError(DecoderStatus::Codes::kFailed); } template <DemuxerStream::Type StreamType> @@ -174,9 +174,10 @@ } template <DemuxerStream::Type StreamType> -void DecoderSelector<StreamType>::SelectDecoder( +void DecoderSelector<StreamType>::SelectDecoderInternal( SelectDecoderCB select_decoder_cb, - typename Decoder::OutputCB output_cb) { + typename Decoder::OutputCB output_cb, + bool needs_new_decoders) { DVLOG(2) << __func__; DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(select_decoder_cb); @@ -191,19 +192,37 @@ if (!config_.IsValidConfig()) { DLOG(ERROR) << "Invalid stream config"; - ReturnNullDecoder(); + ReturnSelectionError(DecoderStatus::Codes::kUnsupportedConfig); return; } - // If this is the first selection (ever or since FinalizeDecoderSelection()), - // start selection with the full list of potential decoders. - if (!is_selecting_decoders_) { - is_selecting_decoders_ = true; + if (needs_new_decoders) { decoder_selection_start_ = base::TimeTicks::Now(); + decode_failure_reinit_cause_ = absl::nullopt; CreateDecoders(); } - InitializeDecoder(); + GetAndInitializeNextDecoder(); +} + +template <DemuxerStream::Type StreamType> +void DecoderSelector<StreamType>::BeginDecoderSelection( + SelectDecoderCB select_decoder_cb, + typename Decoder::OutputCB output_cb) { + SelectDecoderInternal(std::move(select_decoder_cb), std::move(output_cb), + /*needs_new_decoders = */ true); +} + +template <DemuxerStream::Type StreamType> +void DecoderSelector<StreamType>::ResumeDecoderSelection( + SelectDecoderCB select_decoder_cb, + typename Decoder::OutputCB output_cb, + DecoderStatus&& reinit_cause) { + DVLOG(2) << __func__; + if (!decode_failure_reinit_cause_.has_value()) + decode_failure_reinit_cause_ = std::move(reinit_cause); + SelectDecoderInternal(std::move(select_decoder_cb), std::move(output_cb), + /*needs_new_decoders = */ false); } template <DemuxerStream::Type StreamType> @@ -211,7 +230,6 @@ DVLOG(2) << __func__; DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(!select_decoder_cb_); - is_selecting_decoders_ = false; const std::string decoder_type = is_platform_decoder_ ? "HW" : "SW"; const std::string stream_type = @@ -263,9 +281,7 @@ // Decoders inserted directly should be given priority over those returned by // |create_decoders_cb_|. decoders_.insert(decoders_.begin(), std::move(decoder)); - - if (is_selecting_decoders_) - FilterAndSortAvailableDecoders(); + FilterAndSortAvailableDecoders(); } template <DemuxerStream::Type StreamType> @@ -287,7 +303,7 @@ } template <DemuxerStream::Type StreamType> -void DecoderSelector<StreamType>::InitializeDecoder() { +void DecoderSelector<StreamType>::GetAndInitializeNextDecoder() { DVLOG(2) << __func__; DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(!decoder_); @@ -300,7 +316,11 @@ return; } - ReturnNullDecoder(); + if (decode_failure_reinit_cause_.has_value()) { + ReturnSelectionError(std::move(*decode_failure_reinit_cause_)); + } else { + ReturnSelectionError(DecoderStatus::Codes::kUnsupportedConfig); + } return; } @@ -323,35 +343,35 @@ template <DemuxerStream::Type StreamType> void DecoderSelector<StreamType>::OnDecoderInitializeDone( DecoderStatus status) { + DCHECK(decoder_); DVLOG(2) << __func__ << ": " << decoder_->GetDecoderType() << " success=" << static_cast<int>(status.code()); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (!status.is_ok()) { - // TODO(tmathmeyer) this was too noisy in media log. Batch all the logs - // together and then send them as an informational notice instead of - // using NotifyError. + // Note: Don't track this decode status, as it is the result of + // initialization failure. MEDIA_LOG(INFO, media_log_) << "Failed to initialize " << decoder_->GetDecoderType(); // Try the next decoder on the list. - decoder_.reset(); - InitializeDecoder(); + decoder_ = nullptr; + GetAndInitializeNextDecoder(); return; } - RunSelectDecoderCB(); + RunSelectDecoderCB(std::move(decoder_)); } template <DemuxerStream::Type StreamType> -void DecoderSelector<StreamType>::ReturnNullDecoder() { +void DecoderSelector<StreamType>::ReturnSelectionError(DecoderStatus error) { DVLOG(1) << __func__ << ": No decoder selected"; DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(!error.is_ok()); decrypting_demuxer_stream_.reset(); - decoder_.reset(); decoders_.clear(); - RunSelectDecoderCB(); + RunSelectDecoderCB(std::move(error)); } template <DemuxerStream::Type StreamType> @@ -380,7 +400,8 @@ if (status != PIPELINE_OK) { // Since we already tried every potential decoder without DDS, give up. - ReturnNullDecoder(); + ReturnSelectionError( + {DecoderStatus::Codes::kUnsupportedEncryptionMode, std::move(status)}); return; } @@ -395,24 +416,26 @@ // Try decoder selection again now that DDS is being used. CreateDecoders(); - InitializeDecoder(); + GetAndInitializeNextDecoder(); } template <DemuxerStream::Type StreamType> -void DecoderSelector<StreamType>::RunSelectDecoderCB() { +void DecoderSelector<StreamType>::RunSelectDecoderCB( + DecoderOrError decoder_or_error) { DCHECK(select_decoder_cb_); TRACE_EVENT_ASYNC_END2( "media", kSelectDecoderTrace, this, "type", DemuxerStream::GetTypeName(StreamType), "decoder", base::StringPrintf( "%s (%s)", - decoder_ ? GetDecoderName(decoder_->GetDecoderType()).c_str() - : "null", + decoder_or_error.has_value() + ? GetDecoderName(decoder_or_error->GetDecoderType()).c_str() + : "null", decrypting_demuxer_stream_ ? "encrypted" : "unencrypted")); task_runner_->PostTask( FROM_HERE, - base::BindOnce(std::move(select_decoder_cb_), std::move(decoder_), + base::BindOnce(std::move(select_decoder_cb_), std::move(decoder_or_error), std::move(decrypting_demuxer_stream_))); }
diff --git a/media/filters/decoder_selector.h b/media/filters/decoder_selector.h index 152785b..de60499 100644 --- a/media/filters/decoder_selector.h +++ b/media/filters/decoder_selector.h
@@ -54,6 +54,7 @@ typedef DecoderStreamTraits<StreamType> StreamTraits; typedef typename StreamTraits::DecoderType Decoder; typedef typename StreamTraits::DecoderConfigType DecoderConfig; + using DecoderOrError = DecoderStatus::Or<std::unique_ptr<Decoder>>; // Callback to create a list of decoders to select from. // TODO(xhwang): Use a DecoderFactory to create decoders one by one as needed, @@ -76,7 +77,7 @@ // The caller should call DecryptingDemuxerStream::Reset() before // calling Decoder::Reset() to release any pending decryption or read. using SelectDecoderCB = - base::OnceCallback<void(std::unique_ptr<Decoder>, + base::OnceCallback<void(DecoderOrError, std::unique_ptr<DecryptingDemuxerStream>)>; DecoderSelector() = delete; @@ -98,17 +99,27 @@ WaitingCB waiting_cb); // Selects and initializes a decoder, which will be returned via - // |select_decoder_cb| posted to |task_runner|. Subsequent calls to - // SelectDecoder() will return different decoder instances, until all - // potential decoders have been exhausted. + // |select_decoder_cb| posted to |task_runner|. In the event that a selected + // decoder fails to decode, |ResumeDecoderSelection| may be used to get + // another one. // // When the caller determines that decoder selection has succeeded (eg. // because the decoder decoded a frame successfully), it should call // FinalizeDecoderSelection(). // + // |SelectDecoderCB| may be called with an error if no decoders are available. + // // Must not be called while another selection is pending. - void SelectDecoder(SelectDecoderCB select_decoder_cb, - typename Decoder::OutputCB output_cb); + void BeginDecoderSelection(SelectDecoderCB select_decoder_cb, + typename Decoder::OutputCB output_cb); + + // When a client was provided with a decoder that fails to decode after + // being successfully initialized, it should request a new decoder via + // this method rather than |SelectDecoder|. This allows the pipeline to + // report the root cause of decoder failure. + void ResumeDecoderSelection(SelectDecoderCB select_decoder_cb, + typename Decoder::OutputCB output_cb, + DecoderStatus&& reinit_cause); // Signals that decoder selection has been completed (successfully). Future // calls to SelectDecoder() will select from the full list of decoders. @@ -131,13 +142,16 @@ private: void CreateDecoders(); - void InitializeDecoder(); + void GetAndInitializeNextDecoder(); void OnDecoderInitializeDone(DecoderStatus status); - void ReturnNullDecoder(); + void ReturnSelectionError(DecoderStatus error); void InitializeDecryptingDemuxerStream(); void OnDecryptingDemuxerStreamInitializeDone(PipelineStatus status); - void RunSelectDecoderCB(); + void RunSelectDecoderCB(DecoderOrError decoder_or_error); void FilterAndSortAvailableDecoders(); + void SelectDecoderInternal(SelectDecoderCB select_decoder_cb, + typename Decoder::OutputCB output_cb, + bool needs_new_decoders); scoped_refptr<base::SequencedTaskRunner> task_runner_; SEQUENCE_CHECKER(sequence_checker_); @@ -153,10 +167,9 @@ // Overall decoder selection state. DecoderConfig config_; - bool is_selecting_decoders_ = false; std::vector<std::unique_ptr<Decoder>> decoders_; - // State for a single SelectDecoder() invocation. + // State for a single GetAndInitializeNextDecoder() invocation. SelectDecoderCB select_decoder_cb_; typename Decoder::OutputCB output_cb_; std::unique_ptr<Decoder> decoder_; @@ -169,6 +182,11 @@ base::TimeTicks decoder_selection_start_; base::TimeTicks codec_change_start_; + // Used to keep track of the original failure-to-decode reason so that if + // playback fails entirely, we have a root cause to point to, rather than + // failing due to running out of more acceptable decoders. + absl::optional<DecoderStatus> decode_failure_reinit_cause_ = absl::nullopt; + base::WeakPtrFactory<DecoderSelector> weak_this_factory_{this}; };
diff --git a/media/filters/decoder_selector_unittest.cc b/media/filters/decoder_selector_unittest.cc index 4951e02a..4310170f 100644 --- a/media/filters/decoder_selector_unittest.cc +++ b/media/filters/decoder_selector_unittest.cc
@@ -305,14 +305,16 @@ void(std::unique_ptr<DecryptingDemuxerStream>)); void OnDecoderSelectedThunk( - std::unique_ptr<Decoder> decoder, + typename Selector::DecoderOrError decoder, std::unique_ptr<DecryptingDemuxerStream> decrypting_demuxer_stream) { // Report only the type or id of the decoder, since that's what the tests // care about. The decoder will be destructed immediately. - if (decoder && decoder->GetDecoderType() == DecoderType::kTesting) { + if (decoder.has_value() && + decoder->GetDecoderType() == DecoderType::kTesting) { OnDecoderSelected( - static_cast<MockDecoder*>(decoder.get())->GetDecoderId()); - } else if (decoder) { + static_cast<MockDecoder*>(std::move(decoder).value().get()) + ->GetDecoderId()); + } else if (decoder.has_value()) { OnDecoderSelected(decoder->GetDecoderType()); } else { NoDecoderSelected(); @@ -429,13 +431,26 @@ TypeParam::UseHighQualityEncryptedDecoderConfig(demuxer_stream_); } - void SelectDecoder() { - decoder_selector_->SelectDecoder( - base::BindOnce(&Self::OnDecoderSelectedThunk, base::Unretained(this)), - base::BindRepeating(&Self::OnOutput, base::Unretained(this))); + void SelectNextDecoder() { + if (is_selecting_) { + decoder_selector_->ResumeDecoderSelection( + base::BindOnce(&Self::OnDecoderSelectedThunk, base::Unretained(this)), + base::BindRepeating(&Self::OnOutput, base::Unretained(this)), + DecoderStatus::Codes::kFailed); + } else { + decoder_selector_->BeginDecoderSelection( + base::BindOnce(&Self::OnDecoderSelectedThunk, base::Unretained(this)), + base::BindRepeating(&Self::OnOutput, base::Unretained(this))); + } + is_selecting_ = true; RunUntilIdle(); } + void FinalizeDecoderSelection() { + decoder_selector_->FinalizeDecoderSelection(); + is_selecting_ = false; + } + void RunUntilIdle() { task_environment_.RunUntilIdle(); } base::test::TaskEnvironment task_environment_; @@ -449,6 +464,7 @@ std::unique_ptr<Selector> decoder_selector_; bool use_decrypting_decoder_ = false; + bool is_selecting_ = false; std::vector<MockDecoderArgs> mock_decoders_to_create_; }; @@ -468,7 +484,7 @@ this->CreateDecoderSelector(); EXPECT_CALL(*this, NoDecoderSelected()); - this->SelectDecoder(); + this->SelectNextDecoder(); } TYPED_TEST(DecoderSelectorTest, ClearStream_NoClearDecoder) { @@ -477,7 +493,7 @@ this->CreateDecoderSelector(); EXPECT_CALL(*this, NoDecoderSelected()); - this->SelectDecoder(); + this->SelectNextDecoder(); } TYPED_TEST(DecoderSelectorTest, ClearStream_OneClearDecoder) { @@ -486,7 +502,7 @@ this->CreateDecoderSelector(); EXPECT_CALL(*this, OnDecoderSelected(kDecoder1)); - this->SelectDecoder(); + this->SelectNextDecoder(); } TYPED_TEST(DecoderSelectorTest, ClearStream_InternalFallback) { @@ -496,7 +512,7 @@ this->CreateDecoderSelector(); EXPECT_CALL(*this, OnDecoderSelected(kDecoder2)); - this->SelectDecoder(); + this->SelectNextDecoder(); } TYPED_TEST(DecoderSelectorTest, ClearStream_ExternalFallback) { @@ -506,13 +522,13 @@ this->CreateDecoderSelector(); EXPECT_CALL(*this, OnDecoderSelected(kDecoder1)); - this->SelectDecoder(); + this->SelectNextDecoder(); EXPECT_CALL(*this, OnDecoderSelected(kDecoder2)); - this->SelectDecoder(); + this->SelectNextDecoder(); EXPECT_CALL(*this, NoDecoderSelected()); - this->SelectDecoder(); + this->SelectNextDecoder(); } TYPED_TEST(DecoderSelectorTest, ClearStream_FinalizeDecoderSelection) { @@ -522,12 +538,12 @@ this->CreateDecoderSelector(); EXPECT_CALL(*this, OnDecoderSelected(kDecoder1)); - this->SelectDecoder(); + this->SelectNextDecoder(); - this->decoder_selector_->FinalizeDecoderSelection(); + this->FinalizeDecoderSelection(); EXPECT_CALL(*this, OnDecoderSelected(kDecoder1)); - this->SelectDecoder(); + this->SelectNextDecoder(); } // Tests that platform decoders are prioritized for @@ -544,16 +560,16 @@ base::BindRepeating(TypeParam::MockDecoderPriorityCB)); EXPECT_CALL(*this, OnDecoderSelected(kDecoder1)); - this->SelectDecoder(); + this->SelectNextDecoder(); EXPECT_CALL(*this, OnDecoderSelected(kDecoder3)); - this->SelectDecoder(); + this->SelectNextDecoder(); EXPECT_CALL(*this, OnDecoderSelected(kDecoder2)); - this->SelectDecoder(); + this->SelectNextDecoder(); EXPECT_CALL(*this, OnDecoderSelected(kDecoder4)); - this->SelectDecoder(); + this->SelectNextDecoder(); EXPECT_CALL(*this, NoDecoderSelected()); - this->SelectDecoder(); + this->SelectNextDecoder(); } // Tests that non-platform decoders are prioritized for @@ -570,16 +586,16 @@ base::BindRepeating(TypeParam::MockDecoderPriorityCB)); EXPECT_CALL(*this, OnDecoderSelected(kDecoder2)); - this->SelectDecoder(); + this->SelectNextDecoder(); EXPECT_CALL(*this, OnDecoderSelected(kDecoder4)); - this->SelectDecoder(); + this->SelectNextDecoder(); EXPECT_CALL(*this, OnDecoderSelected(kDecoder1)); - this->SelectDecoder(); + this->SelectNextDecoder(); EXPECT_CALL(*this, OnDecoderSelected(kDecoder3)); - this->SelectDecoder(); + this->SelectNextDecoder(); EXPECT_CALL(*this, NoDecoderSelected()); - this->SelectDecoder(); + this->SelectNextDecoder(); } // Tests that platform and non-platform decoders remain in the order they are @@ -597,16 +613,16 @@ base::BindRepeating(TypeParam::NormalDecoderPriorityCB)); EXPECT_CALL(*this, OnDecoderSelected(kDecoder1)); - this->SelectDecoder(); + this->SelectNextDecoder(); EXPECT_CALL(*this, OnDecoderSelected(kDecoder2)); - this->SelectDecoder(); + this->SelectNextDecoder(); EXPECT_CALL(*this, OnDecoderSelected(kDecoder3)); - this->SelectDecoder(); + this->SelectNextDecoder(); EXPECT_CALL(*this, OnDecoderSelected(kDecoder4)); - this->SelectDecoder(); + this->SelectNextDecoder(); EXPECT_CALL(*this, NoDecoderSelected()); - this->SelectDecoder(); + this->SelectNextDecoder(); } TYPED_TEST(DecoderSelectorTest, ClearStream_SkipAllDecoders) { @@ -621,7 +637,7 @@ base::BindRepeating(TypeParam::SkipDecoderPriorityCB)); EXPECT_CALL(*this, NoDecoderSelected()); - this->SelectDecoder(); + this->SelectNextDecoder(); } TYPED_TEST(DecoderSelectorTest, ClearStream_ForceHardwareDecoders) { @@ -637,11 +653,11 @@ this->CreateDecoderSelector(); EXPECT_CALL(*this, OnDecoderSelected(kDecoder1)); - this->SelectDecoder(); + this->SelectNextDecoder(); EXPECT_CALL(*this, OnDecoderSelected(kDecoder3)); - this->SelectDecoder(); + this->SelectNextDecoder(); EXPECT_CALL(*this, NoDecoderSelected()); - this->SelectDecoder(); + this->SelectNextDecoder(); } // Tests the production predicate for `DecoderSelector<DemuxerStream::VIDEO>` @@ -661,15 +677,15 @@ this->CreateDecoderSelector(); EXPECT_CALL(*this, OnDecoderSelected(kDecoder2)); - this->SelectDecoder(); + this->SelectNextDecoder(); EXPECT_CALL(*this, OnDecoderSelected(kDecoder4)); - this->SelectDecoder(); + this->SelectNextDecoder(); EXPECT_CALL(*this, OnDecoderSelected(kDecoder1)); - this->SelectDecoder(); + this->SelectNextDecoder(); EXPECT_CALL(*this, OnDecoderSelected(kDecoder3)); - this->SelectDecoder(); + this->SelectNextDecoder(); EXPECT_CALL(*this, NoDecoderSelected()); - this->SelectDecoder(); + this->SelectNextDecoder(); } // Tests the production predicate for `DecoderSelector<DemuxerStream::VIDEO>` @@ -689,15 +705,15 @@ this->CreateDecoderSelector(); EXPECT_CALL(*this, OnDecoderSelected(kDecoder1)); - this->SelectDecoder(); + this->SelectNextDecoder(); EXPECT_CALL(*this, OnDecoderSelected(kDecoder3)); - this->SelectDecoder(); + this->SelectNextDecoder(); EXPECT_CALL(*this, OnDecoderSelected(kDecoder2)); - this->SelectDecoder(); + this->SelectNextDecoder(); EXPECT_CALL(*this, OnDecoderSelected(kDecoder4)); - this->SelectDecoder(); + this->SelectNextDecoder(); EXPECT_CALL(*this, NoDecoderSelected()); - this->SelectDecoder(); + this->SelectNextDecoder(); } // Tests for encrypted streams. @@ -721,7 +737,7 @@ this->CreateDecoderSelector(); EXPECT_CALL(*this, NoDecoderSelected()); - this->SelectDecoder(); + this->SelectNextDecoder(); } // Tests that for an encrypted stream, platform decoders are prioritized for @@ -738,16 +754,16 @@ base::BindRepeating(TypeParam::MockDecoderPriorityCB)); EXPECT_CALL(*this, OnDecoderSelected(kDecoder1)); - this->SelectDecoder(); + this->SelectNextDecoder(); EXPECT_CALL(*this, OnDecoderSelected(kDecoder3)); - this->SelectDecoder(); + this->SelectNextDecoder(); EXPECT_CALL(*this, OnDecoderSelected(kDecoder2)); - this->SelectDecoder(); + this->SelectNextDecoder(); EXPECT_CALL(*this, OnDecoderSelected(kDecoder4)); - this->SelectDecoder(); + this->SelectNextDecoder(); EXPECT_CALL(*this, NoDecoderSelected()); - this->SelectDecoder(); + this->SelectNextDecoder(); } // Tests that for an encrypted stream, non-platform decoders are prioritized for @@ -764,16 +780,16 @@ base::BindRepeating(TypeParam::MockDecoderPriorityCB)); EXPECT_CALL(*this, OnDecoderSelected(kDecoder2)); - this->SelectDecoder(); + this->SelectNextDecoder(); EXPECT_CALL(*this, OnDecoderSelected(kDecoder4)); - this->SelectDecoder(); + this->SelectNextDecoder(); EXPECT_CALL(*this, OnDecoderSelected(kDecoder1)); - this->SelectDecoder(); + this->SelectNextDecoder(); EXPECT_CALL(*this, OnDecoderSelected(kDecoder3)); - this->SelectDecoder(); + this->SelectNextDecoder(); EXPECT_CALL(*this, NoDecoderSelected()); - this->SelectDecoder(); + this->SelectNextDecoder(); } // Tests that platform and non-platform decoders remain in the order they are @@ -791,16 +807,16 @@ base::BindRepeating(TypeParam::NormalDecoderPriorityCB)); EXPECT_CALL(*this, OnDecoderSelected(kDecoder1)); - this->SelectDecoder(); + this->SelectNextDecoder(); EXPECT_CALL(*this, OnDecoderSelected(kDecoder2)); - this->SelectDecoder(); + this->SelectNextDecoder(); EXPECT_CALL(*this, OnDecoderSelected(kDecoder3)); - this->SelectDecoder(); + this->SelectNextDecoder(); EXPECT_CALL(*this, OnDecoderSelected(kDecoder4)); - this->SelectDecoder(); + this->SelectNextDecoder(); EXPECT_CALL(*this, NoDecoderSelected()); - this->SelectDecoder(); + this->SelectNextDecoder(); } TYPED_TEST(DecoderSelectorTest, EncryptedStream_SkipAllDecoders) { @@ -815,7 +831,7 @@ base::BindRepeating(TypeParam::SkipDecoderPriorityCB)); EXPECT_CALL(*this, NoDecoderSelected()); - this->SelectDecoder(); + this->SelectNextDecoder(); } TYPED_TEST(DecoderSelectorTest, EncryptedStream_ForceHardwareDecoders) { @@ -831,9 +847,9 @@ this->CreateDecoderSelector(); EXPECT_CALL(*this, OnDecoderSelected(kDecoder3)); - this->SelectDecoder(); + this->SelectNextDecoder(); EXPECT_CALL(*this, NoDecoderSelected()); - this->SelectDecoder(); + this->SelectNextDecoder(); } TYPED_TEST(DecoderSelectorTest, EncryptedStream_NoDecryptor_OneClearDecoder) { @@ -843,7 +859,7 @@ this->CreateDecoderSelector(); EXPECT_CALL(*this, NoDecoderSelected()); - this->SelectDecoder(); + this->SelectNextDecoder(); } TYPED_TEST(DecoderSelectorTest, EncryptedStream_NoDecryptor_InternalFallback) { @@ -854,7 +870,7 @@ this->CreateDecoderSelector(); EXPECT_CALL(*this, OnDecoderSelected(kDecoder2)); - this->SelectDecoder(); + this->SelectNextDecoder(); } TYPED_TEST(DecoderSelectorTest, EncryptedStream_NoDecryptor_ExternalFallback) { @@ -865,10 +881,10 @@ this->CreateDecoderSelector(); EXPECT_CALL(*this, OnDecoderSelected(kDecoder1)); - this->SelectDecoder(); + this->SelectNextDecoder(); EXPECT_CALL(*this, OnDecoderSelected(kDecoder2)); - this->SelectDecoder(); + this->SelectNextDecoder(); } TYPED_TEST(DecoderSelectorTest, @@ -880,12 +896,12 @@ this->CreateDecoderSelector(); EXPECT_CALL(*this, OnDecoderSelected(kDecoder1)); - this->SelectDecoder(); + this->SelectNextDecoder(); - this->decoder_selector_->FinalizeDecoderSelection(); + this->FinalizeDecoderSelection(); EXPECT_CALL(*this, OnDecoderSelected(kDecoder1)); - this->SelectDecoder(); + this->SelectNextDecoder(); } TYPED_TEST(DecoderSelectorTest, EncryptedStream_DecryptOnly_NoDecoder) { @@ -894,7 +910,7 @@ this->CreateDecoderSelector(); EXPECT_CALL(*this, NoDecoderSelected()); - this->SelectDecoder(); + this->SelectNextDecoder(); } TYPED_TEST(DecoderSelectorTest, EncryptedStream_DecryptOnly_OneClearDecoder) { @@ -905,7 +921,7 @@ EXPECT_CALL(*this, OnDecoderSelected(kDecoder1)); EXPECT_CALL(*this, OnDemuxerStreamSelected(NotNull())); - this->SelectDecoder(); + this->SelectNextDecoder(); } TYPED_TEST(DecoderSelectorTest, EncryptedStream_DecryptOnly_InternalFallback) { @@ -918,7 +934,7 @@ EXPECT_CALL(*this, OnDecoderSelected(kDecoder2)); EXPECT_CALL(*this, OnDemuxerStreamSelected(NotNull())); - this->SelectDecoder(); + this->SelectNextDecoder(); } TYPED_TEST(DecoderSelectorTest, @@ -936,13 +952,13 @@ saved_dds = std::move(dds); }); - this->SelectDecoder(); + this->SelectNextDecoder(); - this->decoder_selector_->FinalizeDecoderSelection(); + this->FinalizeDecoderSelection(); // DDS is reused. EXPECT_CALL(*this, OnDecoderSelected(kDecoder1)); - this->SelectDecoder(); + this->SelectNextDecoder(); } TYPED_TEST(DecoderSelectorTest, EncryptedStream_DecryptAndDecode) { @@ -964,7 +980,7 @@ EXPECT_CALL(*this, OnDemuxerStreamSelected(NotNull())); #endif // !BUILDFLAG(IS_ANDROID) - this->SelectDecoder(); + this->SelectNextDecoder(); } TYPED_TEST(DecoderSelectorTest, @@ -979,7 +995,7 @@ #if !BUILDFLAG(IS_ANDROID) // DecryptingDecoder is selected immediately. EXPECT_CALL(*this, OnDecoderSelected(TestFixture::DecoderType::kDecrypting)); - this->SelectDecoder(); + this->SelectNextDecoder(); #endif // !BUILDFLAG(IS_ANDROID) // On fallback, a DecryptingDemuxerStream will be created. @@ -989,11 +1005,11 @@ .WillOnce([&](std::unique_ptr<DecryptingDemuxerStream> dds) { saved_dds = std::move(dds); }); - this->SelectDecoder(); + this->SelectNextDecoder(); // The DecryptingDemuxerStream should be reused. EXPECT_CALL(*this, OnDecoderSelected(kDecoder2)); - this->SelectDecoder(); + this->SelectNextDecoder(); } TYPED_TEST(DecoderSelectorTest, ClearToEncryptedStream_DecryptOnly) { @@ -1003,14 +1019,14 @@ this->CreateDecoderSelector(); EXPECT_CALL(*this, OnDecoderSelected(kDecoder1)); - this->SelectDecoder(); + this->SelectNextDecoder(); - this->decoder_selector_->FinalizeDecoderSelection(); + this->FinalizeDecoderSelection(); this->UseEncryptedDecoderConfig(); EXPECT_CALL(*this, OnDecoderSelected(kDecoder1)); EXPECT_CALL(*this, OnDemuxerStreamSelected(NotNull())); - this->SelectDecoder(); + this->SelectNextDecoder(); } // Tests the production predicate for `DecoderSelector<DemuxerStream::VIDEO>` @@ -1030,11 +1046,11 @@ this->CreateDecoderSelector(); EXPECT_CALL(*this, OnDecoderSelected(kDecoder4)); - this->SelectDecoder(); + this->SelectNextDecoder(); EXPECT_CALL(*this, OnDecoderSelected(kDecoder3)); - this->SelectDecoder(); + this->SelectNextDecoder(); EXPECT_CALL(*this, NoDecoderSelected()); - this->SelectDecoder(); + this->SelectNextDecoder(); } // Tests the production predicate for `DecoderSelector<DemuxerStream::VIDEO>` @@ -1054,11 +1070,11 @@ this->CreateDecoderSelector(); EXPECT_CALL(*this, OnDecoderSelected(kDecoder3)); - this->SelectDecoder(); + this->SelectNextDecoder(); EXPECT_CALL(*this, OnDecoderSelected(kDecoder4)); - this->SelectDecoder(); + this->SelectNextDecoder(); EXPECT_CALL(*this, NoDecoderSelected()); - this->SelectDecoder(); + this->SelectNextDecoder(); } // Tests we always use resolution-based rules for RTC. @@ -1077,7 +1093,7 @@ this->CreateDecoderSelector(); EXPECT_CALL(*this, OnDecoderSelected(kDecoder2)); - this->SelectDecoder(); + this->SelectNextDecoder(); } // Non-platform decoders should be used for RTC unless enabled by a switch. @@ -1094,7 +1110,7 @@ this->CreateDecoderSelector(); EXPECT_CALL(*this, OnDecoderSelected(kDecoder1)).Times(0); - this->SelectDecoder(); + this->SelectNextDecoder(); } // Platform decoders should be allowed for RTC without the sw switch. @@ -1111,7 +1127,7 @@ this->CreateDecoderSelector(); EXPECT_CALL(*this, OnDecoderSelected(kDecoder1)); - this->SelectDecoder(); + this->SelectNextDecoder(); } // Non-platform decoders should be allowed for RTC if enabled by a switch. @@ -1128,7 +1144,7 @@ this->CreateDecoderSelector(); EXPECT_CALL(*this, OnDecoderSelected(kDecoder1)); - this->SelectDecoder(); + this->SelectNextDecoder(); } } // namespace media
diff --git a/media/filters/decoder_stream.cc b/media/filters/decoder_stream.cc index 92bf8ff..84dc02c 100644 --- a/media/filters/decoder_stream.cc +++ b/media/filters/decoder_stream.cc
@@ -169,7 +169,7 @@ std::move(waiting_cb)); state_ = STATE_INITIALIZING; - SelectDecoder(); + BeginDecoderSelection(); } template <DemuxerStream::Type StreamType> @@ -186,8 +186,8 @@ TRACE_EVENT_ASYNC_BEGIN0("media", GetReadTraceString<StreamType>(), this); if (state_ == STATE_ERROR) { read_cb_ = BindToCurrentLoop(std::move(read_cb)); - // TODO(crbug.com/1129662): Consider attaching a caused-by of the original - // error as well. + // OnDecodeDone, OnBufferReady, and CompleteDecoderReinitialization all set + // STATE_ERROR and call SatisfyRead, passing the error back to a ReadCB. SatisfyRead(DecoderStatus::Codes::kDecoderStreamInErrorState); return; } @@ -337,8 +337,8 @@ } template <DemuxerStream::Type StreamType> -void DecoderStream<StreamType>::SelectDecoder() { - decoder_selector_.SelectDecoder( +void DecoderStream<StreamType>::BeginDecoderSelection() { + decoder_selector_.BeginDecoderSelection( base::BindOnce(&DecoderStream<StreamType>::OnDecoderSelected, weak_factory_.GetWeakPtr()), base::BindRepeating(&DecoderStream<StreamType>::OnDecodeOutputReady, @@ -346,12 +346,23 @@ } template <DemuxerStream::Type StreamType> +void DecoderStream<StreamType>::ResumeDecoderSelection( + DecoderStatus&& reinit_cause) { + decoder_selector_.ResumeDecoderSelection( + base::BindOnce(&DecoderStream<StreamType>::OnDecoderSelected, + weak_factory_.GetWeakPtr()), + base::BindRepeating(&DecoderStream<StreamType>::OnDecodeOutputReady, + fallback_weak_factory_.GetWeakPtr()), + std::move(reinit_cause)); +} + +template <DemuxerStream::Type StreamType> void DecoderStream<StreamType>::OnDecoderSelected( - std::unique_ptr<Decoder> selected_decoder, + DecoderStatus::Or<std::unique_ptr<Decoder>> decoder_or_error, std::unique_ptr<DecryptingDemuxerStream> decrypting_demuxer_stream) { FUNCTION_DVLOG(1) << ": " - << (selected_decoder - ? GetDecoderName(selected_decoder->GetDecoderType()) + << (decoder_or_error.has_value() + ? GetDecoderName(decoder_or_error->GetDecoderType()) : "No decoder selected."); DCHECK(task_runner_->RunsTasksInCurrentSequence()); DCHECK(state_ == STATE_INITIALIZING || state_ == STATE_REINITIALIZING_DECODER) @@ -377,13 +388,14 @@ cdm_context_ = nullptr; } - decoder_ = std::move(selected_decoder); - if (decoder_change_observer_cb_) - decoder_change_observer_cb_.Run(decoder_.get()); + if (decoder_change_observer_cb_) { + decoder_change_observer_cb_.Run( + decoder_or_error.has_value() ? (*decoder_or_error).get() : nullptr); + } // TODO(tguilbert): crbug.com/603713 support config changes on decoder reinit. if (received_config_change_during_reinit_) { - CompleteDecoderReinitialization(false); + CompleteDecoderReinitialization(DecoderStatus::Codes::kInterrupted); return; } @@ -391,18 +403,24 @@ // never successfully outputed a frame). fallback_buffers_ = pending_buffers_; - if (!decoder_) { + if (decoder_or_error.has_error()) { if (state_ == STATE_INITIALIZING) { state_ = STATE_UNINITIALIZED; MEDIA_LOG(ERROR, media_log_) << GetStreamTypeString() << " decoder initialization failed"; std::move(init_cb_).Run(false); + // Node that |decoder_or_error| is not actually lost in this case, as + // DecoderSelector is keeping track of it to use in case there are no + // successfully initialized decoders. } else { - CompleteDecoderReinitialization(false); + CompleteDecoderReinitialization(std::move(decoder_or_error).error()); } return; } + DCHECK(decoder_or_error.has_value()); + decoder_ = std::move(decoder_or_error).value(); + // Send logs and statistics updates including the decoder name. traits_->SetIsPlatformDecoder(decoder_->IsPlatformDecoder()); traits_->SetIsDecryptingDemuxerStream(!!decrypting_demuxer_stream_); @@ -428,7 +446,7 @@ << traits_->GetDecoderConfig(stream_).AsHumanReadableString(); if (state_ == STATE_REINITIALIZING_DECODER) { - CompleteDecoderReinitialization(true); + CompleteDecoderReinitialization(OkStatus()); return; } @@ -609,7 +627,7 @@ pending_decode_requests_ = 0; decoding_eos_ = false; state_ = STATE_REINITIALIZING_DECODER; - SelectDecoder(); + ResumeDecoderSelection(std::move(status)); } else { media_log_->NotifyError(status); MEDIA_LOG(ERROR, media_log_) @@ -760,6 +778,8 @@ << GetStreamTypeString() << " demuxer stream read error!"; pending_buffers_.clear(); ClearOutputs(); + // TODO(crbug.com/c/1326324): Convert |status| into a typed status so that + // it can be set as a cause here. if (read_cb_) SatisfyRead(DecoderStatus::Codes::kDecoderStreamDemuxerError); } @@ -867,16 +887,17 @@ state_ = STATE_REINITIALIZING_DECODER; decoder_selector_.PrependDecoder(std::move(decoder_)); - SelectDecoder(); + BeginDecoderSelection(); } template <DemuxerStream::Type StreamType> -void DecoderStream<StreamType>::CompleteDecoderReinitialization(bool success) { +void DecoderStream<StreamType>::CompleteDecoderReinitialization( + DecoderStatus status) { FUNCTION_DVLOG(2); DCHECK(task_runner_->RunsTasksInCurrentSequence()); DCHECK_EQ(state_, STATE_REINITIALIZING_DECODER); - state_ = success ? STATE_NORMAL : STATE_ERROR; + state_ = status.is_ok() ? STATE_NORMAL : STATE_ERROR; if (reset_cb_) { std::move(reset_cb_).Run(); @@ -889,7 +910,7 @@ if (state_ == STATE_ERROR) { MEDIA_LOG(ERROR, media_log_) << GetStreamTypeString() << " decoder reinitialization failed"; - SatisfyRead(DecoderStatus::Codes::kDecoderStreamReinitFailed); + SatisfyRead(std::move(status)); return; }
diff --git a/media/filters/decoder_stream.h b/media/filters/decoder_stream.h index 894949c..a66a9f4 100644 --- a/media/filters/decoder_stream.h +++ b/media/filters/decoder_stream.h
@@ -173,13 +173,14 @@ // Returns true if one more decode request can be submitted to the decoder. bool CanDecodeMore() const; - void SelectDecoder(); + void BeginDecoderSelection(); + void ResumeDecoderSelection(DecoderStatus&& reinit_cause); // Called when |decoder_selector| selected the |selected_decoder|. // |decrypting_demuxer_stream| was also populated if a DecryptingDemuxerStream // is created to help decrypt the encrypted stream. void OnDecoderSelected( - std::unique_ptr<Decoder> selected_decoder, + DecoderStatus::Or<std::unique_ptr<Decoder>> decoder_or_error, std::unique_ptr<DecryptingDemuxerStream> decrypting_demuxer_stream); // Satisfy pending |read_cb_| with |result|. @@ -214,7 +215,7 @@ void ReinitializeDecoder(); - void CompleteDecoderReinitialization(bool success); + void CompleteDecoderReinitialization(DecoderStatus status); void ResetDecoder(); void OnDecoderReset();
diff --git a/media/gpu/v4l2/test/av1_decoder.cc b/media/gpu/v4l2/test/av1_decoder.cc index 399e1cf2..a0f65621 100644 --- a/media/gpu/v4l2/test/av1_decoder.cc +++ b/media/gpu/v4l2/test/av1_decoder.cc
@@ -4,6 +4,8 @@ #include "media/gpu/v4l2/test/av1_decoder.h" +#include <linux/media/av1-ctrls.h> + #include "base/logging.h" #include "base/memory/ptr_util.h" #include "media/filters/ivf_parser.h" @@ -18,6 +20,61 @@ "Too many CAPTURE buffers are used. The number of CAPTURE " "buffers is currently assumed to be no larger than 16."); +// TODO(stevecho): Remove this provision when av1-ctrls.h includes linux/bits.h. +#ifndef BIT +#define BIT(nr) (1U << (nr)) +#endif + +inline void conditionally_set_flags(__u8* flags, + const bool condition, + const bool mask) { + *flags |= (condition ? mask : 0); +} + +// Section 5.9.11. Loop filter params syntax in AV1 spec. +// https://aomediacodec.github.io/av1-spec/av1-spec.pdf +// Note that |update_ref_delta| and |update_mode_delta| flags in the spec +// are not needed for V4L2 AV1 API. +// TODO(stevecho): sanity check data structures in libgav1 against the AV1 spec. +void FillLoopFilterParams(struct v4l2_av1_loop_filter* v4l2_lf, + const libgav1::LoopFilter& lf) { + conditionally_set_flags(&v4l2_lf->flags, lf.delta_enabled, + V4L2_AV1_LOOP_FILTER_FLAG_DELTA_ENABLED); + conditionally_set_flags(&v4l2_lf->flags, lf.delta_update, + V4L2_AV1_LOOP_FILTER_FLAG_DELTA_UPDATE); + + static_assert(std::size(decltype(v4l2_lf->level){}) == libgav1::kFrameLfCount, + "Invalid size of loop filter level (strength) array"); + for (size_t i = 0; i < libgav1::kFrameLfCount; i++) + v4l2_lf->level[i] = base::checked_cast<__u8>(lf.level[i]); + + v4l2_lf->sharpness = lf.sharpness; + + static_assert(std::size(decltype(v4l2_lf->ref_deltas){}) == + libgav1::kNumReferenceFrameTypes, + "Invalid size of ref deltas array"); + for (size_t i = 0; i < libgav1::kNumReferenceFrameTypes; i++) + v4l2_lf->ref_deltas[i] = lf.ref_deltas[i]; + + static_assert(std::size(decltype(v4l2_lf->mode_deltas){}) == + libgav1::kLoopFilterMaxModeDeltas, + "Invalid size of mode deltas array"); + for (size_t i = 0; i < libgav1::kLoopFilterMaxModeDeltas; i++) + v4l2_lf->mode_deltas[i] = lf.mode_deltas[i]; +} + +// Section 5.9.18. Loop filter delta parameters syntax. +// Note that |delta_lf_res| in |v4l2_av1_loop_filter| corresponds to +// |delta_lf.scale| in the frame header defined in libgav1. +void FillLoopFilterDeltaParams(struct v4l2_av1_loop_filter* v4l2_lf, + const libgav1::Delta& delta_lf) { + conditionally_set_flags(&v4l2_lf->flags, delta_lf.present, + V4L2_AV1_LOOP_FILTER_FLAG_DELTA_LF_PRESENT); + + v4l2_lf->delta_lf_res = delta_lf.scale; + v4l2_lf->delta_lf_multi = delta_lf.multi; +} + Av1Decoder::Av1Decoder(std::unique_ptr<IvfParser> ivf_parser, std::unique_ptr<V4L2IoctlShim> v4l2_ioctl, std::unique_ptr<V4L2Queue> OUTPUT_queue, @@ -257,7 +314,14 @@ } // TODO(b/228534730): add changes to prepare parameters for V4L2 AV1 stateless - // decoding + // decoding and make VIDIOC_S_EXT_CTRLS v4l2 ioctl call + struct v4l2_ctrl_av1_frame_header v4l2_frame_params = {}; + + FillLoopFilterParams(&v4l2_frame_params.loop_filter, + current_frame_header.loop_filter); + + FillLoopFilterDeltaParams(&v4l2_frame_params.loop_filter, + current_frame_header.delta_lf); if (!v4l2_ioctl_->MediaRequestIocQueue(OUTPUT_queue_)) LOG(FATAL) << "MEDIA_REQUEST_IOC_QUEUE failed.";
diff --git a/media/gpu/v4l2/test/av1_decoder.h b/media/gpu/v4l2/test/av1_decoder.h index cad35a0..5f8de6333 100644 --- a/media/gpu/v4l2/test/av1_decoder.h +++ b/media/gpu/v4l2/test/av1_decoder.h
@@ -8,6 +8,10 @@ #include "media/gpu/v4l2/test/v4l2_ioctl_shim.h" #include "media/gpu/v4l2/test/video_decoder.h" +// TODO(b/234019411): Move this include to v4l2_stateless_decoder.cc +// once the bug is fixed. +#include <linux/media/av1-ctrls.h> + #include <set> #include "media/filters/ivf_parser.h" @@ -23,16 +27,11 @@ #define ANALYZER_ALLOW_UNUSED(var) static_cast<void>(var); // TODO(stevecho): This is temporary until the change to define -// V4L2_PIX_FMT_AV1_FRAME lands in videodev2.h. +// V4L2_PIX_FMT_AV1 lands in videodev2.h. // https://patchwork.linuxtv.org/project/linux-media/patch/20210810220552.298140-2-daniel.almeida@collabora.com/ #ifndef V4L2_PIX_FMT_AV1 #define V4L2_PIX_FMT_AV1 v4l2_fourcc('A', 'V', '0', '1') /* AV1 */ #endif -#ifndef V4L2_PIX_FMT_AV1_FRAME -#define V4L2_PIX_FMT_AV1_FRAME \ - v4l2_fourcc('A', 'V', '1', 'F') /* AV1 parsed frame \ - */ -#endif namespace media {
diff --git a/media/mojo/services/stable_video_decoder_service.cc b/media/mojo/services/stable_video_decoder_service.cc index 36b0eab..2cbdedf 100644 --- a/media/mojo/services/stable_video_decoder_service.cc +++ b/media/mojo/services/stable_video_decoder_service.cc
@@ -8,7 +8,10 @@ StableVideoDecoderService::StableVideoDecoderService( std::unique_ptr<mojom::VideoDecoder> dst_video_decoder) - : dst_video_decoder_(std::move(dst_video_decoder)) { + : video_decoder_client_receiver_(this), + media_log_receiver_(this), + stable_video_frame_handle_releaser_receiver_(this), + dst_video_decoder_(std::move(dst_video_decoder)) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); CHECK(!!dst_video_decoder_); } @@ -32,7 +35,31 @@ mojo::ScopedDataPipeConsumerHandle decoder_buffer_pipe, const gfx::ColorSpace& target_color_space) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - NOTIMPLEMENTED(); + if (video_decoder_client_receiver_.is_bound()) { + mojo::ReportBadMessage("Construct() already called"); + return; + } + + DCHECK(!video_decoder_client_receiver_.is_bound()); + DCHECK(!stable_video_decoder_client_remote_.is_bound()); + stable_video_decoder_client_remote_.Bind( + std::move(stable_video_decoder_client_remote)); + + DCHECK(!media_log_receiver_.is_bound()); + DCHECK(!stable_media_log_remote_.is_bound()); + stable_media_log_remote_.Bind(std::move(stable_media_log_remote)); + + DCHECK(!video_frame_handle_releaser_remote_); + DCHECK(!stable_video_frame_handle_releaser_receiver_.is_bound()); + stable_video_frame_handle_releaser_receiver_.Bind( + std::move(stable_video_frame_handle_releaser_receiver)); + + dst_video_decoder_->Construct( + video_decoder_client_receiver_.BindNewEndpointAndPassRemote(), + media_log_receiver_.BindNewPipeAndPassRemote(), + video_frame_handle_releaser_remote_.BindNewPipeAndPassReceiver(), + std::move(decoder_buffer_pipe), mojom::CommandBufferId::New(), + target_color_space); } void StableVideoDecoderService::Initialize( @@ -56,4 +83,34 @@ NOTIMPLEMENTED(); } +void StableVideoDecoderService::ReleaseVideoFrame( + const base::UnguessableToken& release_token) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + NOTIMPLEMENTED(); +} + +void StableVideoDecoderService::OnVideoFrameDecoded( + const scoped_refptr<VideoFrame>& frame, + bool can_read_without_stalling, + const absl::optional<base::UnguessableToken>& release_token) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + NOTIMPLEMENTED(); +} + +void StableVideoDecoderService::OnWaiting(WaitingReason reason) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + NOTIMPLEMENTED(); +} + +void StableVideoDecoderService::RequestOverlayInfo( + bool restart_for_transitions) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + NOTREACHED(); +} + +void StableVideoDecoderService::AddLogRecord(const MediaLogRecord& event) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + NOTIMPLEMENTED(); +} + } // namespace media
diff --git a/media/mojo/services/stable_video_decoder_service.h b/media/mojo/services/stable_video_decoder_service.h index 5282507..4593d04 100644 --- a/media/mojo/services/stable_video_decoder_service.h +++ b/media/mojo/services/stable_video_decoder_service.h
@@ -7,9 +7,14 @@ #include "base/sequence_checker.h" #include "base/thread_annotations.h" +#include "media/mojo/mojom/media_log.mojom.h" #include "media/mojo/mojom/stable/stable_video_decoder.mojom.h" #include "media/mojo/mojom/video_decoder.mojom.h" #include "media/mojo/services/media_mojo_export.h" +#include "mojo/public/cpp/bindings/associated_receiver.h" +#include "mojo/public/cpp/bindings/associated_remote.h" +#include "mojo/public/cpp/bindings/receiver.h" +#include "mojo/public/cpp/bindings/remote.h" namespace media { @@ -34,7 +39,10 @@ // StableVideoDecoderService should also check incoming data due to similar // concerns. class MEDIA_MOJO_EXPORT StableVideoDecoderService - : public stable::mojom::StableVideoDecoder { + : public stable::mojom::StableVideoDecoder, + public stable::mojom::VideoFrameHandleReleaser, + public mojom::VideoDecoderClient, + public mojom::MediaLog { public: explicit StableVideoDecoderService( std::unique_ptr<mojom::VideoDecoder> dst_video_decoder); @@ -62,7 +70,45 @@ DecodeCallback callback) final; void Reset(ResetCallback callback) final; + // mojom::stable::VideoFrameHandleReleaser implementation. + void ReleaseVideoFrame(const base::UnguessableToken& release_token) final; + + // mojom::VideoDecoderClient implementation. + void OnVideoFrameDecoded( + const scoped_refptr<VideoFrame>& frame, + bool can_read_without_stalling, + const absl::optional<base::UnguessableToken>& release_token) final; + void OnWaiting(WaitingReason reason) final; + void RequestOverlayInfo(bool restart_for_transitions) final; + + // mojom::MediaLog implementation. + void AddLogRecord(const MediaLogRecord& event) final; + private: + // Incoming calls from the |dst_video_decoder_| to + // |video_decoder_client_receiver_| are forwarded to + // |stable_video_decoder_client_remote_|. + mojo::AssociatedReceiver<mojom::VideoDecoderClient> + video_decoder_client_receiver_ GUARDED_BY_CONTEXT(sequence_checker_); + mojo::AssociatedRemote<stable::mojom::VideoDecoderClient> + stable_video_decoder_client_remote_ GUARDED_BY_CONTEXT(sequence_checker_); + + // Incoming calls from the |dst_video_decoder_| to |media_log_receiver_| are + // forwarded to |stable_media_log_remote_|. + mojo::Receiver<mojom::MediaLog> media_log_receiver_ + GUARDED_BY_CONTEXT(sequence_checker_); + mojo::Remote<stable::mojom::MediaLog> stable_media_log_remote_ + GUARDED_BY_CONTEXT(sequence_checker_); + + // Incoming requests from the client to + // |stable_video_frame_handle_releaser_receiver_| are forwarded to + // |video_frame_handle_releaser_remote_|. + mojo::Receiver<stable::mojom::VideoFrameHandleReleaser> + stable_video_frame_handle_releaser_receiver_ + GUARDED_BY_CONTEXT(sequence_checker_); + mojo::Remote<mojom::VideoFrameHandleReleaser> + video_frame_handle_releaser_remote_ GUARDED_BY_CONTEXT(sequence_checker_); + // The incoming stable::mojom::StableVideoDecoder requests are forwarded to // |dst_video_decoder_|. std::unique_ptr<mojom::VideoDecoder> dst_video_decoder_
diff --git a/media/mojo/services/stable_video_decoder_service_unittest.cc b/media/mojo/services/stable_video_decoder_service_unittest.cc index c8ac1170..3f24b23 100644 --- a/media/mojo/services/stable_video_decoder_service_unittest.cc +++ b/media/mojo/services/stable_video_decoder_service_unittest.cc
@@ -5,9 +5,13 @@ #include "media/mojo/services/stable_video_decoder_service.h" #include "base/test/mock_callback.h" #include "base/test/task_environment.h" +#include "media/mojo/common/mojo_decoder_buffer_converter.h" +#include "media/mojo/mojom/media_log.mojom.h" #include "media/mojo/mojom/video_decoder.mojom.h" #include "media/mojo/services/stable_video_decoder_factory_service.h" +#include "mojo/public/cpp/bindings/associated_receiver.h" #include "mojo/public/cpp/bindings/remote.h" +#include "mojo/public/cpp/system/data_pipe.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -21,6 +25,29 @@ namespace { +class MockVideoFrameHandleReleaser : public mojom::VideoFrameHandleReleaser { + public: + explicit MockVideoFrameHandleReleaser( + mojo::PendingReceiver<mojom::VideoFrameHandleReleaser> + video_frame_handle_releaser) + : video_frame_handle_releaser_receiver_( + this, + std::move(video_frame_handle_releaser)) {} + MockVideoFrameHandleReleaser(const MockVideoFrameHandleReleaser&) = delete; + MockVideoFrameHandleReleaser& operator=(const MockVideoFrameHandleReleaser&) = + delete; + ~MockVideoFrameHandleReleaser() override = default; + + // mojom::VideoFrameHandleReleaser implementation. + MOCK_METHOD2(ReleaseVideoFrame, + void(const base::UnguessableToken& release_token, + const gpu::SyncToken& release_sync_token)); + + private: + mojo::Receiver<mojom::VideoFrameHandleReleaser> + video_frame_handle_releaser_receiver_; +}; + class MockVideoDecoder : public mojom::VideoDecoder { public: MockVideoDecoder() = default; @@ -28,17 +55,40 @@ MockVideoDecoder& operator=(const MockVideoDecoder&) = delete; ~MockVideoDecoder() override = default; + mojo::AssociatedRemote<mojom::VideoDecoderClient> TakeClientRemote() { + return std::move(client_remote_); + } + mojo::Remote<mojom::MediaLog> TakeMediaLogRemote() { + return std::move(media_log_remote_); + } + std::unique_ptr<StrictMock<MockVideoFrameHandleReleaser>> + TakeVideoFrameHandleReleaser() { + return std::move(video_frame_handle_releaser_); + } + std::unique_ptr<MojoDecoderBufferReader> TakeMojoDecoderBufferReader() { + return std::move(mojo_decoder_buffer_reader_); + }; + // mojom::VideoDecoder implementation. MOCK_METHOD1(GetSupportedConfigs, void(GetSupportedConfigsCallback callback)); - MOCK_METHOD6( - Construct, - void(mojo::PendingAssociatedRemote<mojom::VideoDecoderClient> client, - mojo::PendingRemote<mojom::MediaLog> media_log, - mojo::PendingReceiver<mojom::VideoFrameHandleReleaser> - video_frame_handle_receiver, - mojo::ScopedDataPipeConsumerHandle decoder_buffer_pipe, - mojom::CommandBufferIdPtr command_buffer_id, - const gfx::ColorSpace& target_color_space)); + void Construct( + mojo::PendingAssociatedRemote<mojom::VideoDecoderClient> client, + mojo::PendingRemote<mojom::MediaLog> media_log, + mojo::PendingReceiver<mojom::VideoFrameHandleReleaser> + video_frame_handle_releaser, + mojo::ScopedDataPipeConsumerHandle decoder_buffer_pipe, + mojom::CommandBufferIdPtr command_buffer_id, + const gfx::ColorSpace& target_color_space) final { + client_remote_.Bind(std::move(client)); + media_log_remote_.Bind(std::move(media_log)); + video_frame_handle_releaser_ = + std::make_unique<StrictMock<MockVideoFrameHandleReleaser>>( + std::move(video_frame_handle_releaser)); + DoConstruct(std::move(command_buffer_id), target_color_space); + } + MOCK_METHOD2(DoConstruct, + void(mojom::CommandBufferIdPtr command_buffer_id, + const gfx::ColorSpace& target_color_space)); MOCK_METHOD4(Initialize, void(const VideoDecoderConfig& config, bool low_delay, @@ -48,8 +98,168 @@ void(mojom::DecoderBufferPtr buffer, DecodeCallback callback)); MOCK_METHOD1(Reset, void(ResetCallback callback)); MOCK_METHOD1(OnOverlayInfoChanged, void(const OverlayInfo& overlay_info)); + + private: + mojo::AssociatedRemote<mojom::VideoDecoderClient> client_remote_; + mojo::Remote<mojom::MediaLog> media_log_remote_; + std::unique_ptr<StrictMock<MockVideoFrameHandleReleaser>> + video_frame_handle_releaser_; + std::unique_ptr<MojoDecoderBufferReader> mojo_decoder_buffer_reader_; }; +class MockStableVideoDecoderClient : public stable::mojom::VideoDecoderClient { + public: + explicit MockStableVideoDecoderClient( + mojo::PendingAssociatedReceiver<stable::mojom::VideoDecoderClient> + pending_receiver) + : receiver_(this, std::move(pending_receiver)) {} + MockStableVideoDecoderClient(const MockStableVideoDecoderClient&) = delete; + MockStableVideoDecoderClient& operator=(const MockStableVideoDecoderClient&) = + delete; + ~MockStableVideoDecoderClient() override = default; + + // stable::mojom::VideoDecoderClient implementation. + MOCK_METHOD3(OnVideoFrameDecoded, + void(const scoped_refptr<VideoFrame>& frame, + bool can_read_without_stalling, + const base::UnguessableToken& release_token)); + MOCK_METHOD1(OnWaiting, void(WaitingReason reason)); + + private: + mojo::AssociatedReceiver<stable::mojom::VideoDecoderClient> receiver_; +}; + +class MockStableMediaLog : public stable::mojom::MediaLog { + public: + explicit MockStableMediaLog( + mojo::PendingReceiver<stable::mojom::MediaLog> pending_receiver) + : receiver_(this, std::move(pending_receiver)) {} + MockStableMediaLog(const MockStableMediaLog&) = delete; + MockStableMediaLog& operator=(const MockStableMediaLog&) = delete; + ~MockStableMediaLog() override = default; + + // stable::mojom::MediaLog implementation. + MOCK_METHOD1(AddLogRecord, void(const MediaLogRecord& event)); + + private: + mojo::Receiver<stable::mojom::MediaLog> receiver_; +}; + +// AuxiliaryEndpoints groups the endpoints that support the operation of a +// StableVideoDecoderService and that come from the Construct() call. That way, +// tests can easily poke at one endpoint and set expectations on the other. For +// example, a test might want to simulate the scenario in which a frame has been +// decoded by the underlying mojom::VideoDecoder. In this case, the test can +// call |video_decoder_client_remote|->OnVideoFrameDecoded() and then set an +// expectation on |mock_stable_video_decoder_client|->OnVideoFrameDecoded(). +struct AuxiliaryEndpoints { + // |video_decoder_client_remote| is the client that the underlying + // mojom::VideoDecoder receives through the Construct() call. Tests can make + // calls on it and those calls should ultimately be received by the + // |mock_stable_video_decoder_client|. + mojo::AssociatedRemote<mojom::VideoDecoderClient> video_decoder_client_remote; + std::unique_ptr<StrictMock<MockStableVideoDecoderClient>> + mock_stable_video_decoder_client; + + // |media_log_remote| is the MediaLog that the underlying mojom::VideoDecoder + // receives through the Construct() call. Tests can make calls on it and those + // calls should ultimately be received by the |mock_stable_media_log|. + mojo::Remote<mojom::MediaLog> media_log_remote; + std::unique_ptr<StrictMock<MockStableMediaLog>> mock_stable_media_log; + + // Tests can use |stable_video_frame_handle_releaser_remote| to simulate + // releasing a VideoFrame. + // |mock_video_frame_handle_releaser| is the VideoFrameHandleReleaser that's + // setup when the underlying mojom::VideoDecoder receives a Construct() call. + // Tests can make calls on |stable_video_frame_handle_releaser_remote| and + // they should be ultimately received by the + // |mock_video_frame_handle_releaser|. + mojo::Remote<stable::mojom::VideoFrameHandleReleaser> + stable_video_frame_handle_releaser_remote; + std::unique_ptr<StrictMock<MockVideoFrameHandleReleaser>> + mock_video_frame_handle_releaser; + + // |mojo_decoder_buffer_reader| wraps the reading end of the data pipe that + // the underlying mojom::VideoDecoder receives through the Construct() call. + // Tests can write data using the |mojo_decoder_buffer_writer| and that data + // should be ultimately received by the |mojo_decoder_buffer_reader|. + std::unique_ptr<MojoDecoderBufferWriter> mojo_decoder_buffer_writer; + std::unique_ptr<MojoDecoderBufferReader> mojo_decoder_buffer_reader; +}; + +// Calls Construct() on |stable_video_decoder_remote| and, if +// |expect_construct_call| is true, expects a corresponding Construct() call on +// |mock_video_decoder| which is assumed to be the backing decoder of +// |stable_video_decoder_remote|. Returns nullptr if the expectations on +// |mock_video_decoder| are violated. Otherwise, returns an AuxiliaryEndpoints +// instance that contains the supporting endpoints that tests can use to +// interact with the auxiliary interfaces used by the +// |stable_video_decoder_remote|. +std::unique_ptr<AuxiliaryEndpoints> ConstructStableVideoDecoder( + mojo::Remote<stable::mojom::StableVideoDecoder>& + stable_video_decoder_remote, + StrictMock<MockVideoDecoder>& mock_video_decoder, + bool expect_construct_call) { + constexpr gfx::ColorSpace kTargetColorSpace = gfx::ColorSpace::CreateSRGB(); + if (expect_construct_call) { + EXPECT_CALL(mock_video_decoder, + DoConstruct(/*command_buffer_id=*/_, + /*target_color_space=*/kTargetColorSpace)); + } + mojo::PendingAssociatedRemote<stable::mojom::VideoDecoderClient> + stable_video_decoder_client_remote; + auto mock_stable_video_decoder_client = + std::make_unique<StrictMock<MockStableVideoDecoderClient>>( + stable_video_decoder_client_remote + .InitWithNewEndpointAndPassReceiver()); + + mojo::PendingRemote<stable::mojom::MediaLog> stable_media_log_remote; + auto mock_stable_media_log = std::make_unique<StrictMock<MockStableMediaLog>>( + stable_media_log_remote.InitWithNewPipeAndPassReceiver()); + + mojo::Remote<stable::mojom::VideoFrameHandleReleaser> + video_frame_handle_releaser_remote; + + mojo::ScopedDataPipeConsumerHandle remote_consumer_handle; + std::unique_ptr<MojoDecoderBufferWriter> mojo_decoder_buffer_writer = + MojoDecoderBufferWriter::Create( + GetDefaultDecoderBufferConverterCapacity(DemuxerStream::VIDEO), + &remote_consumer_handle); + + stable_video_decoder_remote->Construct( + std::move(stable_video_decoder_client_remote), + std::move(stable_media_log_remote), + video_frame_handle_releaser_remote.BindNewPipeAndPassReceiver(), + std::move(remote_consumer_handle), kTargetColorSpace); + stable_video_decoder_remote.FlushForTesting(); + + if (!Mock::VerifyAndClearExpectations(&mock_video_decoder)) + return nullptr; + + auto auxiliary_endpoints = std::make_unique<AuxiliaryEndpoints>(); + + auxiliary_endpoints->video_decoder_client_remote = + mock_video_decoder.TakeClientRemote(); + auxiliary_endpoints->mock_stable_video_decoder_client = + std::move(mock_stable_video_decoder_client); + + auxiliary_endpoints->media_log_remote = + mock_video_decoder.TakeMediaLogRemote(); + auxiliary_endpoints->mock_stable_media_log = std::move(mock_stable_media_log); + + auxiliary_endpoints->stable_video_frame_handle_releaser_remote = + std::move(video_frame_handle_releaser_remote); + auxiliary_endpoints->mock_video_frame_handle_releaser = + mock_video_decoder.TakeVideoFrameHandleReleaser(); + + auxiliary_endpoints->mojo_decoder_buffer_writer = + std::move(mojo_decoder_buffer_writer); + auxiliary_endpoints->mojo_decoder_buffer_reader = + mock_video_decoder.TakeMojoDecoderBufferReader(); + + return auxiliary_endpoints; +} + class StableVideoDecoderServiceTest : public testing::Test { public: StableVideoDecoderServiceTest() { @@ -125,6 +335,38 @@ } } +// Tests that a call to stable::mojom::VideoDecoder::Construct() call gets +// routed correctly to the underlying mojom::VideoDecoder. +TEST_F(StableVideoDecoderServiceTest, StableVideoDecoderCanBeConstructed) { + auto mock_video_decoder = std::make_unique<StrictMock<MockVideoDecoder>>(); + auto* mock_video_decoder_raw = mock_video_decoder.get(); + auto stable_video_decoder_remote = + CreateStableVideoDecoder(std::move(mock_video_decoder)); + ASSERT_TRUE(stable_video_decoder_remote.is_bound()); + ASSERT_TRUE(stable_video_decoder_remote.is_connected()); + ASSERT_TRUE(ConstructStableVideoDecoder(stable_video_decoder_remote, + *mock_video_decoder_raw, + /*expect_construct_call=*/true)); +} + +// Tests that if two calls to stable::mojom::VideoDecoder::Construct() are made, +// only one is routed to the underlying mojom::VideoDecoder. +TEST_F(StableVideoDecoderServiceTest, + StableVideoDecoderCannotBeConstructedTwice) { + auto mock_video_decoder = std::make_unique<StrictMock<MockVideoDecoder>>(); + auto* mock_video_decoder_raw = mock_video_decoder.get(); + auto stable_video_decoder_remote = + CreateStableVideoDecoder(std::move(mock_video_decoder)); + ASSERT_TRUE(stable_video_decoder_remote.is_bound()); + ASSERT_TRUE(stable_video_decoder_remote.is_connected()); + EXPECT_TRUE(ConstructStableVideoDecoder(stable_video_decoder_remote, + *mock_video_decoder_raw, + /*expect_construct_call=*/true)); + EXPECT_TRUE(ConstructStableVideoDecoder(stable_video_decoder_remote, + *mock_video_decoder_raw, + /*expect_construct_call=*/false)); +} + } // namespace } // namespace media
diff --git a/media/renderers/video_renderer_impl.cc b/media/renderers/video_renderer_impl.cc index 9b0e9cb..2623b95 100644 --- a/media/renderers/video_renderer_impl.cc +++ b/media/renderers/video_renderer_impl.cc
@@ -575,12 +575,16 @@ default: // Anything other than `kOk` or `kAborted` is treated as an error. DCHECK(result.has_error()); - auto status = result.code() == DecoderStatus::Codes::kDisconnected - ? PIPELINE_ERROR_DISCONNECTED - : PIPELINE_ERROR_DECODE; + + PipelineStatus::Codes code = + result.code() == DecoderStatus::Codes::kDisconnected + ? PIPELINE_ERROR_DISCONNECTED + : PIPELINE_ERROR_DECODE; + PipelineStatus status = {code, std::move(result).error()}; task_runner_->PostTask( - FROM_HERE, base::BindOnce(&VideoRendererImpl::OnPlaybackError, - weak_factory_.GetWeakPtr(), status)); + FROM_HERE, + base::BindOnce(&VideoRendererImpl::OnPlaybackError, + weak_factory_.GetWeakPtr(), std::move(status))); return; }
diff --git a/net/third_party/quiche/BUILD.gn b/net/third_party/quiche/BUILD.gn index 446faac..75a6a64 100644 --- a/net/third_party/quiche/BUILD.gn +++ b/net/third_party/quiche/BUILD.gn
@@ -33,7 +33,10 @@ config("quiche_internal_config") { cflags = [] if (is_clang) { - cflags += [ "-Wno-unused-private-field" ] + cflags += [ + "-Wno-unused-private-field", + "-Wno-sign-compare", + ] } }
diff --git a/printing/test_printing_context.cc b/printing/test_printing_context.cc index f4b694ec..cce3e1a 100644 --- a/printing/test_printing_context.cc +++ b/printing/test_printing_context.cc
@@ -17,6 +17,7 @@ #include "printing/mojom/print.mojom.h" #include "printing/print_settings.h" #include "printing/printing_context.h" +#include "printing/units.h" #include "ui/gfx/geometry/size.h" #if BUILDFLAG(IS_WIN) @@ -103,8 +104,11 @@ } gfx::Size TestPrintingContext::GetPdfPaperSizeDeviceUnits() { - NOTIMPLEMENTED(); - return gfx::Size(); + // Default to A4 paper size, which is an alternative to Letter size that is + // often used as the fallback size for some platform-specific + // implementations. + return gfx::Size(kA4WidthInch * settings_->device_units_per_inch(), + kA4HeightInch * settings_->device_units_per_inch()); } mojom::ResultCode TestPrintingContext::UpdatePrinterSettings(
diff --git a/remoting/protocol/webrtc_video_encoder_factory.cc b/remoting/protocol/webrtc_video_encoder_factory.cc index 6234bcd..8f08b6a4 100644 --- a/remoting/protocol/webrtc_video_encoder_factory.cc +++ b/remoting/protocol/webrtc_video_encoder_factory.cc
@@ -9,6 +9,7 @@ #include "remoting/protocol/video_channel_state_observer.h" #include "remoting/protocol/webrtc_video_encoder_wrapper.h" #include "third_party/webrtc/api/video_codecs/sdp_video_format.h" +#include "third_party/webrtc/api/video_codecs/video_codec.h" #include "third_party/webrtc/api/video_codecs/vp9_profile.h" #if defined(USE_H264_ENCODER) @@ -19,19 +20,20 @@ WebrtcVideoEncoderFactory::WebrtcVideoEncoderFactory() : main_task_runner_(base::ThreadTaskRunnerHandle::Get()) { - formats_.push_back(webrtc::SdpVideoFormat("VP8")); - formats_.push_back(webrtc::SdpVideoFormat("VP9")); - formats_.push_back( - webrtc::SdpVideoFormat("VP9", {{webrtc::kVP9FmtpProfileId, "1"}})); + formats_.emplace_back(webrtc::SdpVideoFormat("VP8")); + formats_.emplace_back(webrtc::SdpVideoFormat("VP9")); + formats_.emplace_back(webrtc::SdpVideoFormat( + "VP9", {{webrtc::kVP9FmtpProfileId, + webrtc::VP9ProfileToString(webrtc::VP9Profile::kProfile1)}})); #if defined(USE_H264_ENCODER) // This call will query the underlying media classes to determine whether // hardware encoding is supported or not. We use a default resolution and // framerate so the call doesn't fail due to invalid params. if (WebrtcVideoEncoderGpu::IsSupportedByH264({{1920, 1080}, 30})) { - formats_.push_back(webrtc::SdpVideoFormat("H264")); + formats_.emplace_back(webrtc::SdpVideoFormat("H264")); } #endif - formats_.push_back(webrtc::SdpVideoFormat("AV1")); + formats_.emplace_back(webrtc::SdpVideoFormat("AV1")); } WebrtcVideoEncoderFactory::~WebrtcVideoEncoderFactory() = default;
diff --git a/remoting/protocol/webrtc_video_encoder_wrapper.cc b/remoting/protocol/webrtc_video_encoder_wrapper.cc index 74313d24..49840f86 100644 --- a/remoting/protocol/webrtc_video_encoder_wrapper.cc +++ b/remoting/protocol/webrtc_video_encoder_wrapper.cc
@@ -22,6 +22,7 @@ #include "remoting/codec/webrtc_video_encoder_vpx.h" #include "remoting/protocol/video_channel_state_observer.h" #include "remoting/protocol/webrtc_video_frame_adapter.h" +#include "third_party/webrtc/api/video_codecs/sdp_video_format.h" #include "third_party/webrtc/api/video_codecs/vp9_profile.h" #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h" #include "third_party/webrtc/modules/video_coding/include/video_codec_interface.h" @@ -101,9 +102,10 @@ encoder_ = WebrtcVideoEncoderVpx::CreateForVP8(); break; case webrtc::kVideoCodecVP9: { - const auto iter = format.parameters.find(webrtc::kVP9FmtpProfileId); - bool lossless_color = - iter != format.parameters.end() && iter->second == "1"; + absl::optional<webrtc::VP9Profile> profile = + webrtc::ParseSdpForVP9Profile(format.parameters); + bool lossless_color = profile.has_value() && + profile.value() == webrtc::VP9Profile::kProfile1; VLOG(0) << "Creating VP9 encoder, lossless_color=" << (lossless_color ? "true" : "false"); encoder_ = WebrtcVideoEncoderVpx::CreateForVP9(); @@ -399,11 +401,8 @@ NOTREACHED(); #endif } else if (frame.codec == webrtc::kVideoCodecAV1) { -#if defined(USE_AV1_ENCODER) // TODO(joedow): Set codec specific params for AV1 here. -#else - NOTREACHED(); -#endif + NOTIMPLEMENTED(); } else { NOTREACHED(); }
diff --git a/sandbox/policy/BUILD.gn b/sandbox/policy/BUILD.gn index 9a9c8714..6b3f411 100644 --- a/sandbox/policy/BUILD.gn +++ b/sandbox/policy/BUILD.gn
@@ -155,6 +155,7 @@ "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.buildinfo", "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.camera3", "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.fonts", + "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.hwinfo", "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.intl", "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.logger",
diff --git a/sandbox/policy/fuchsia/sandbox_policy_fuchsia.cc b/sandbox/policy/fuchsia/sandbox_policy_fuchsia.cc index 36169b3..3f5cbb9 100644 --- a/sandbox/policy/fuchsia/sandbox_policy_fuchsia.cc +++ b/sandbox/policy/fuchsia/sandbox_policy_fuchsia.cc
@@ -12,6 +12,7 @@ #include <fuchsia/buildinfo/cpp/fidl.h> #include <fuchsia/camera3/cpp/fidl.h> #include <fuchsia/fonts/cpp/fidl.h> +#include <fuchsia/hwinfo/cpp/fidl.h> #include <fuchsia/intl/cpp/fidl.h> #include <fuchsia/logger/cpp/fidl.h> #include <fuchsia/media/cpp/fidl.h> @@ -74,8 +75,11 @@ // clang-format off constexpr auto kMinimalServices = base::make_span((const char* const[]){ // TODO(crbug.com/1286960): Remove this and/or intl below if an alternative - // solution does not require access to the service in all processes. + // solution does not require access to the service in all processes. For now + // these services are made available everywhere because they are required by + // base::SysInfo. fuchsia::buildinfo::Provider::Name_, + fuchsia::hwinfo::Product::Name_, // DebugData service is needed only for profiling. #if BUILDFLAG(CLANG_PROFILING)
diff --git a/services/data_decoder/public/cpp/data_decoder.cc b/services/data_decoder/public/cpp/data_decoder.cc index 762b3e3..cdb14344 100644 --- a/services/data_decoder/public/cpp/data_decoder.cc +++ b/services/data_decoder/public/cpp/data_decoder.cc
@@ -43,8 +43,9 @@ template <typename T, typename V> class ValueParseRequest : public base::RefCounted<ValueParseRequest<T, V>> { public: - explicit ValueParseRequest(DataDecoder::ResultCallback<V> callback) - : callback_(std::move(callback)) {} + ValueParseRequest(DataDecoder::ResultCallback<V> callback, + scoped_refptr<DataDecoder::CancellationFlag> is_cancelled) + : callback_(std::move(callback)), is_cancelled_(is_cancelled) {} ValueParseRequest(const ValueParseRequest&) = delete; ValueParseRequest& operator=(const ValueParseRequest&) = delete; @@ -68,7 +69,7 @@ // Handles a successful parse from the service. void OnServiceValueOrError(absl::optional<V> value, const absl::optional<std::string>& error) { - if (!callback()) + if (!callback() || is_cancelled_->data) return; DataDecoder::ResultOrError<V> result; @@ -96,6 +97,9 @@ ~ValueParseRequest() = default; void OnRemoteDisconnected() { + if (is_cancelled_->data) + return; + if (callback()) { std::move(callback()) .Run(DataDecoder::ResultOrError<V>::Error( @@ -105,6 +109,7 @@ mojo::Remote<T> remote_; DataDecoder::ResultCallback<V> callback_; + scoped_refptr<DataDecoder::CancellationFlag> is_cancelled_; }; #if BUILDFLAG(IS_IOS) @@ -126,8 +131,12 @@ #if BUILDFLAG(IS_ANDROID) || BUILDFLAG(BUILD_RUST_JSON_PARSER) -void ParsingComplete(DataDecoder::ValueParseCallback callback, +void ParsingComplete(scoped_refptr<DataDecoder::CancellationFlag> is_cancelled, + DataDecoder::ValueParseCallback callback, base::JSONReader::ValueWithError value_with_error) { + if (is_cancelled->data) + return; + if (!value_with_error.value) { std::move(callback).Run( DataDecoder::ValueOrError::Error(value_with_error.error_message)); @@ -141,12 +150,15 @@ } // namespace -DataDecoder::DataDecoder() : idle_timeout_(kServiceProcessIdleTimeoutDefault) {} +DataDecoder::DataDecoder() : DataDecoder(kServiceProcessIdleTimeoutDefault) {} DataDecoder::DataDecoder(base::TimeDelta idle_timeout) - : idle_timeout_(idle_timeout) {} + : idle_timeout_(idle_timeout), + cancel_requests_(new CancellationFlag(false)) {} -DataDecoder::~DataDecoder() = default; +DataDecoder::~DataDecoder() { + cancel_requests_->data = true; +} mojom::DataDecoderService* DataDecoder::GetService() { // Lazily start an instance of the service if possible and necessary. @@ -184,13 +196,18 @@ json, base::JSON_PARSE_RFC); }, json), - base::BindOnce(&ParsingComplete, std::move(callback))); + base::BindOnce(&ParsingComplete, cancel_requests_, std::move(callback))); #elif BUILDFLAG(IS_ANDROID) // For Android, if the full Rust parser is not available, we use the // in-process sanitizer and then parse in-process. JsonSanitizer::Sanitize( json, base::BindOnce( - [](ValueParseCallback callback, JsonSanitizer::Result result) { + [](ValueParseCallback callback, + scoped_refptr<CancellationFlag> is_cancelled, + JsonSanitizer::Result result) { + if (is_cancelled->data) + return; + if (!result.value) { std::move(callback).Run(ValueOrError::Error(*result.error)); return; @@ -199,15 +216,15 @@ base::JSONReader::ValueWithError value_with_error = base::JSONReader::ReadAndReturnValueWithError( *result.value, base::JSON_PARSE_RFC); - ParsingComplete(std::move(callback), + ParsingComplete(is_cancelled, std::move(callback), std::move(value_with_error)); }, - std::move(callback))); + std::move(callback), cancel_requests_)); #else // Parse JSON out-of-process. auto request = base::MakeRefCounted<ValueParseRequest<mojom::JsonParser, base::Value>>( - std::move(callback)); + std::move(callback), cancel_requests_); GetService()->BindJsonParser(request->BindRemote()); request->remote()->Parse( json, base::JSON_PARSE_RFC, @@ -240,7 +257,7 @@ ValueParseCallback callback) { auto request = base::MakeRefCounted<ValueParseRequest<mojom::XmlParser, base::Value>>( - std::move(callback)); + std::move(callback), cancel_requests_); GetService()->BindXmlParser(request->BindRemote()); request->remote()->Parse( xml, whitespace_behavior, @@ -273,7 +290,7 @@ GzipperCallback callback) { auto request = base::MakeRefCounted< ValueParseRequest<mojom::Gzipper, mojo_base::BigBuffer>>( - std::move(callback)); + std::move(callback), cancel_requests_); GetService()->BindGzipper(request->BindRemote()); request->remote()->Deflate( data, @@ -287,7 +304,7 @@ GzipperCallback callback) { auto request = base::MakeRefCounted< ValueParseRequest<mojom::Gzipper, mojo_base::BigBuffer>>( - std::move(callback)); + std::move(callback), cancel_requests_); GetService()->BindGzipper(request->BindRemote()); request->remote()->Inflate( data, max_uncompressed_size, @@ -300,7 +317,7 @@ GzipperCallback callback) { auto request = base::MakeRefCounted< ValueParseRequest<mojom::Gzipper, mojo_base::BigBuffer>>( - std::move(callback)); + std::move(callback), cancel_requests_); GetService()->BindGzipper(request->BindRemote()); request->remote()->Compress( data, @@ -313,7 +330,7 @@ GzipperCallback callback) { auto request = base::MakeRefCounted< ValueParseRequest<mojom::Gzipper, mojo_base::BigBuffer>>( - std::move(callback)); + std::move(callback), cancel_requests_); GetService()->BindGzipper(request->BindRemote()); request->remote()->Uncompress( data,
diff --git a/services/data_decoder/public/cpp/data_decoder.h b/services/data_decoder/public/cpp/data_decoder.h index 0b25df9..cea5b7f8 100644 --- a/services/data_decoder/public/cpp/data_decoder.h +++ b/services/data_decoder/public/cpp/data_decoder.h
@@ -8,6 +8,7 @@ #include <string> #include "base/callback_forward.h" +#include "base/memory/ref_counted.h" #include "base/time/time.h" #include "base/values.h" #include "mojo/public/cpp/bindings/pending_receiver.h" @@ -89,6 +90,8 @@ using GzipperCallback = base::OnceCallback<void(ResultOrError<mojo_base::BigBuffer>)>; + using CancellationFlag = base::RefCountedData<bool>; + // Returns a raw interface to the service instance. This launches an instance // of the service process if possible on the current platform, or returns a // connection to the in-process instance of in a test environment using @@ -171,6 +174,13 @@ // This instance's connection to the service. This connection is lazily // established and may be reset after long periods of idle time. mojo::Remote<mojom::DataDecoderService> service_; + + // Cancellation flag for any outstanding requests. When a request is + // started, it takes a reference to this flag. Upon the destruction of this + // instance, the flag is set to `true`. Any outstanding requests should check + // this flag, and if it is `true`, they should not run the callback, per + // the API guarantees above. + scoped_refptr<CancellationFlag> cancel_requests_; }; } // namespace data_decoder
diff --git a/storage/browser/quota/OWNERS b/storage/browser/quota/OWNERS index 2d495dc6..22981a3 100644 --- a/storage/browser/quota/OWNERS +++ b/storage/browser/quota/OWNERS
@@ -3,6 +3,7 @@ # Secondary asully@chromium.org +estade@chromium.org jarrydg@chromium.org jsbell@chromium.org
diff --git a/testing/buildbot/chrome.json b/testing/buildbot/chrome.json index 6064b795..2f5520fe 100644 --- a/testing/buildbot/chrome.json +++ b/testing/buildbot/chrome.json
@@ -1943,7 +1943,7 @@ { "args": [], "cros_board": "atlas", - "cros_img": "atlas-release/R102-14695.68.0", + "cros_img": "atlas-release/R103-14816.25.0", "name": "lacros_all_tast_tests ATLAS_RELEASE_BETA", "resultdb": { "enable": true, @@ -1991,7 +1991,7 @@ { "args": [], "cros_board": "eve", - "cros_img": "eve-release/R102-14695.55.0", + "cros_img": "eve-release/R103-14816.25.0", "name": "lacros_all_tast_tests EVE_RELEASE_BETA", "resultdb": { "enable": true, @@ -2084,7 +2084,7 @@ { "args": [], "cros_board": "hana", - "cros_img": "hana-release/R102-14695.68.0", + "cros_img": "hana-release/R103-14816.25.0", "name": "lacros_all_tast_tests HANA_RELEASE_BETA", "resultdb": { "enable": true, @@ -2132,7 +2132,7 @@ { "args": [], "cros_board": "jacuzzi", - "cros_img": "jacuzzi-release/R102-14695.68.0", + "cros_img": "jacuzzi-release/R103-14816.25.0", "name": "lacros_all_tast_tests JACUZZI_RELEASE_BETA", "resultdb": { "enable": true, @@ -2184,7 +2184,7 @@ "--test-launcher-filter-file=../../testing/buildbot/filters/lacros-arm.ozone_unittests.filter" ], "cros_board": "hana", - "cros_img": "hana-release/R102-14695.68.0", + "cros_img": "hana-release/R103-14816.25.0", "name": "ozone_unittests HANA_RELEASE_BETA", "resultdb": { "enable": true, @@ -2235,7 +2235,7 @@ "--test-launcher-filter-file=../../testing/buildbot/filters/lacros-arm.ozone_unittests.filter" ], "cros_board": "jacuzzi", - "cros_img": "jacuzzi-release/R102-14695.68.0", + "cros_img": "jacuzzi-release/R103-14816.25.0", "name": "ozone_unittests JACUZZI_RELEASE_BETA", "resultdb": { "enable": true, @@ -2286,7 +2286,7 @@ "--test-launcher-filter-file=../../testing/buildbot/filters/lacros-arm.viz_unittests.filter" ], "cros_board": "hana", - "cros_img": "hana-release/R102-14695.68.0", + "cros_img": "hana-release/R103-14816.25.0", "name": "viz_unittests HANA_RELEASE_BETA", "resultdb": { "enable": true, @@ -2337,7 +2337,7 @@ "--test-launcher-filter-file=../../testing/buildbot/filters/lacros-arm.viz_unittests.filter" ], "cros_board": "jacuzzi", - "cros_img": "jacuzzi-release/R102-14695.68.0", + "cros_img": "jacuzzi-release/R103-14816.25.0", "name": "viz_unittests JACUZZI_RELEASE_BETA", "resultdb": { "enable": true,
diff --git a/testing/buildbot/chromium.android.fyi.json b/testing/buildbot/chromium.android.fyi.json index fbc26c5..85009ce7 100644 --- a/testing/buildbot/chromium.android.fyi.json +++ b/testing/buildbot/chromium.android.fyi.json
@@ -8240,15 +8240,15 @@ { "args": [ "--additional-apk=apks/WebLayerShellSystemWebView.apk", + "--webview-apk-path=apks/SystemWebView.apk", "--test-runner-outdir", ".", + "--client-outdir", + "../../weblayer_instrumentation_test_M102/out/Release", "--implementation-outdir", ".", "--test-expectations", "../../weblayer/browser/android/javatests/skew/expectations.txt", - "--webview-apk-path=apks/SystemWebView.apk", - "--client-outdir", - "../../weblayer_instrumentation_test_M102/out/Release", "--client-version=102", "--gs-results-bucket=chromium-result-details", "--recover-devices", @@ -8274,7 +8274,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M102", - "revision": "version:102.0.5005.75" + "revision": "version:102.0.5005.76" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -8750,15 +8750,15 @@ { "args": [ "--additional-apk=apks/WebLayerShellSystemWebView.apk", + "--webview-apk-path=apks/AOSP_SystemWebView.apk", "--test-runner-outdir", ".", "--client-outdir", ".", - "--test-expectations", - "../../weblayer/browser/android/javatests/skew/expectations.txt", - "--webview-apk-path=apks/AOSP_SystemWebView.apk", "--implementation-outdir", "../../weblayer_instrumentation_test_M102/out/Release", + "--test-expectations", + "../../weblayer/browser/android/javatests/skew/expectations.txt", "--impl-version=102", "--gs-results-bucket=chromium-result-details", "--recover-devices", @@ -8784,7 +8784,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M102", - "revision": "version:102.0.5005.75" + "revision": "version:102.0.5005.76" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
diff --git a/testing/buildbot/chromium.android.json b/testing/buildbot/chromium.android.json index 1876a04..fc4bf367 100644 --- a/testing/buildbot/chromium.android.json +++ b/testing/buildbot/chromium.android.json
@@ -46214,15 +46214,15 @@ { "args": [ "--additional-apk=apks/WebLayerShellSystemWebView.apk", + "--webview-apk-path=apks/SystemWebView.apk", "--test-runner-outdir", ".", + "--client-outdir", + "../../weblayer_instrumentation_test_M102/out/Release", "--implementation-outdir", ".", "--test-expectations", "../../weblayer/browser/android/javatests/skew/expectations.txt", - "--webview-apk-path=apks/SystemWebView.apk", - "--client-outdir", - "../../weblayer_instrumentation_test_M102/out/Release", "--client-version=102", "--gs-results-bucket=chromium-result-details", "--recover-devices", @@ -46248,7 +46248,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M102", - "revision": "version:102.0.5005.75" + "revision": "version:102.0.5005.76" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -46724,15 +46724,15 @@ { "args": [ "--additional-apk=apks/WebLayerShellSystemWebView.apk", + "--webview-apk-path=apks/AOSP_SystemWebView.apk", "--test-runner-outdir", ".", "--client-outdir", ".", - "--test-expectations", - "../../weblayer/browser/android/javatests/skew/expectations.txt", - "--webview-apk-path=apks/AOSP_SystemWebView.apk", "--implementation-outdir", "../../weblayer_instrumentation_test_M102/out/Release", + "--test-expectations", + "../../weblayer/browser/android/javatests/skew/expectations.txt", "--impl-version=102", "--gs-results-bucket=chromium-result-details", "--recover-devices", @@ -46758,7 +46758,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M102", - "revision": "version:102.0.5005.75" + "revision": "version:102.0.5005.76" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -47238,15 +47238,15 @@ { "args": [ "--additional-apk=apks/ChromePublic.apk", + "--webview-apk-path=apks/SystemWebView.apk", "--test-runner-outdir", ".", + "--client-outdir", + "../../weblayer_instrumentation_test_M102/out/Release", "--implementation-outdir", ".", "--test-expectations", "../../weblayer/browser/android/javatests/skew/expectations.txt", - "--webview-apk-path=apks/SystemWebView.apk", - "--client-outdir", - "../../weblayer_instrumentation_test_M102/out/Release", "--client-version=102", "--gs-results-bucket=chromium-result-details", "--recover-devices", @@ -47272,7 +47272,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M102", - "revision": "version:102.0.5005.75" + "revision": "version:102.0.5005.76" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -47748,15 +47748,15 @@ { "args": [ "--additional-apk=apks/ChromePublic.apk", + "--webview-apk-path=apks/AOSP_SystemWebView.apk", "--test-runner-outdir", ".", "--client-outdir", ".", - "--test-expectations", - "../../weblayer/browser/android/javatests/skew/expectations.txt", - "--webview-apk-path=apks/AOSP_SystemWebView.apk", "--implementation-outdir", "../../weblayer_instrumentation_test_M102/out/Release", + "--test-expectations", + "../../weblayer/browser/android/javatests/skew/expectations.txt", "--impl-version=102", "--gs-results-bucket=chromium-result-details", "--recover-devices", @@ -47782,7 +47782,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M102", - "revision": "version:102.0.5005.75" + "revision": "version:102.0.5005.76" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -48330,15 +48330,15 @@ { "args": [ "--additional-apk=apks/WebLayerShellSystemWebView.apk", + "--webview-apk-path=apks/SystemWebView.apk", "--test-runner-outdir", ".", + "--client-outdir", + "../../weblayer_instrumentation_test_M102/out/Release", "--implementation-outdir", ".", "--test-expectations", "../../weblayer/browser/android/javatests/skew/expectations.txt", - "--webview-apk-path=apks/SystemWebView.apk", - "--client-outdir", - "../../weblayer_instrumentation_test_M102/out/Release", "--client-version=102", "--gs-results-bucket=chromium-result-details", "--recover-devices", @@ -48364,7 +48364,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M102", - "revision": "version:102.0.5005.75" + "revision": "version:102.0.5005.76" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -48840,15 +48840,15 @@ { "args": [ "--additional-apk=apks/WebLayerShellSystemWebView.apk", + "--webview-apk-path=apks/SystemWebView.apk", "--test-runner-outdir", ".", "--client-outdir", ".", - "--test-expectations", - "../../weblayer/browser/android/javatests/skew/expectations.txt", - "--webview-apk-path=apks/SystemWebView.apk", "--implementation-outdir", "../../weblayer_instrumentation_test_M102/out/Release", + "--test-expectations", + "../../weblayer/browser/android/javatests/skew/expectations.txt", "--impl-version=102", "--gs-results-bucket=chromium-result-details", "--recover-devices", @@ -48874,7 +48874,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M102", - "revision": "version:102.0.5005.75" + "revision": "version:102.0.5005.76" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -49422,15 +49422,15 @@ { "args": [ "--additional-apk=apks/WebLayerShellSystemWebView.apk", + "--webview-apk-path=apks/SystemWebView.apk", "--test-runner-outdir", ".", + "--client-outdir", + "../../weblayer_instrumentation_test_M102/out/Release", "--implementation-outdir", ".", "--test-expectations", "../../weblayer/browser/android/javatests/skew/expectations.txt", - "--webview-apk-path=apks/SystemWebView.apk", - "--client-outdir", - "../../weblayer_instrumentation_test_M102/out/Release", "--client-version=102", "--gs-results-bucket=chromium-result-details", "--recover-devices", @@ -49456,7 +49456,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M102", - "revision": "version:102.0.5005.75" + "revision": "version:102.0.5005.76" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -49932,15 +49932,15 @@ { "args": [ "--additional-apk=apks/WebLayerShellSystemWebView.apk", + "--webview-apk-path=apks/SystemWebView.apk", "--test-runner-outdir", ".", "--client-outdir", ".", - "--test-expectations", - "../../weblayer/browser/android/javatests/skew/expectations.txt", - "--webview-apk-path=apks/SystemWebView.apk", "--implementation-outdir", "../../weblayer_instrumentation_test_M102/out/Release", + "--test-expectations", + "../../weblayer/browser/android/javatests/skew/expectations.txt", "--impl-version=102", "--gs-results-bucket=chromium-result-details", "--recover-devices", @@ -49966,7 +49966,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M102", - "revision": "version:102.0.5005.75" + "revision": "version:102.0.5005.76" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
diff --git a/testing/buildbot/chromium.chromiumos.json b/testing/buildbot/chromium.chromiumos.json index bf7f9c2..8b37cc2 100644 --- a/testing/buildbot/chromium.chromiumos.json +++ b/testing/buildbot/chromium.chromiumos.json
@@ -5801,38 +5801,6 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v102.0.5005.56/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 102.0.5005.56", - "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_v102.0.5005.56", - "revision": "version:102.0.5005.56" - } - ], - "dimension_sets": [ - { - "os": "Ubuntu-18.04" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 - }, - "test": "interactive_ui_tests", - "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/", - "variant_id": "Lacros version skew testing ash 102.0.5005.56" - }, - { - "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter", "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5060.15/test_ash_chrome" ], "isolate_profile_data": true, @@ -5865,6 +5833,38 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5060.22/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 103.0.5060.22", + "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_v103.0.5060.22", + "revision": "version:103.0.5060.22" + } + ], + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 3 + }, + "test": "interactive_ui_tests", + "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/", + "variant_id": "Lacros version skew testing ash 103.0.5060.22" + }, + { + "args": [ + "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter", "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5085.0/test_ash_chrome" ], "isolate_profile_data": true, @@ -5968,37 +5968,6 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v102.0.5005.56/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 102.0.5005.56", - "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_v102.0.5005.56", - "revision": "version:102.0.5005.56" - } - ], - "dimension_sets": [ - { - "os": "Ubuntu-18.04" - } - ], - "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 102.0.5005.56" - }, - { - "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5060.15/test_ash_chrome" ], "isolate_profile_data": true, @@ -6030,6 +5999,37 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5060.22/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 103.0.5060.22", + "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_v103.0.5060.22", + "revision": "version:103.0.5060.22" + } + ], + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "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 103.0.5060.22" + }, + { + "args": [ + "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5085.0/test_ash_chrome" ], "isolate_profile_data": true, @@ -6114,37 +6114,6 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v102.0.5005.56/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 102.0.5005.56", - "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_v102.0.5005.56", - "revision": "version:102.0.5005.56" - } - ], - "dimension_sets": [ - { - "os": "Ubuntu-18.04" - } - ], - "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 102.0.5005.56" - }, - { - "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5060.15/test_ash_chrome" ], "isolate_profile_data": true, @@ -6176,6 +6145,37 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5060.22/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 103.0.5060.22", + "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_v103.0.5060.22", + "revision": "version:103.0.5060.22" + } + ], + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "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 103.0.5060.22" + }, + { + "args": [ + "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5085.0/test_ash_chrome" ], "isolate_profile_data": true,
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json index 488f28d..9b98eb7 100644 --- a/testing/buildbot/chromium.fyi.json +++ b/testing/buildbot/chromium.fyi.json
@@ -87983,33 +87983,6 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v102.0.5005.56/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 102.0.5005.56", - "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_v102.0.5005.56", - "revision": "version:102.0.5005.56" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 - }, - "test": "interactive_ui_tests", - "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/", - "variant_id": "Lacros version skew testing ash 102.0.5005.56" - }, - { - "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter", "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5060.15/test_ash_chrome" ], "isolate_profile_data": true, @@ -88037,6 +88010,33 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5060.22/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 103.0.5060.22", + "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_v103.0.5060.22", + "revision": "version:103.0.5060.22" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 3 + }, + "test": "interactive_ui_tests", + "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/", + "variant_id": "Lacros version skew testing ash 103.0.5060.22" + }, + { + "args": [ + "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter", "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5085.0/test_ash_chrome" ], "isolate_profile_data": true, @@ -88120,32 +88120,6 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v102.0.5005.56/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 102.0.5005.56", - "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_v102.0.5005.56", - "revision": "version:102.0.5005.56" - } - ], - "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 102.0.5005.56" - }, - { - "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5060.15/test_ash_chrome" ], "isolate_profile_data": true, @@ -88172,6 +88146,32 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5060.22/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 103.0.5060.22", + "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_v103.0.5060.22", + "revision": "version:103.0.5060.22" + } + ], + "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 103.0.5060.22" + }, + { + "args": [ + "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5085.0/test_ash_chrome" ], "isolate_profile_data": true, @@ -88241,32 +88241,6 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v102.0.5005.56/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 102.0.5005.56", - "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_v102.0.5005.56", - "revision": "version:102.0.5005.56" - } - ], - "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 102.0.5005.56" - }, - { - "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5060.15/test_ash_chrome" ], "isolate_profile_data": true, @@ -88293,6 +88267,32 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5060.22/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 103.0.5060.22", + "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_v103.0.5060.22", + "revision": "version:103.0.5060.22" + } + ], + "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 103.0.5060.22" + }, + { + "args": [ + "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5085.0/test_ash_chrome" ], "isolate_profile_data": true, @@ -89588,38 +89588,6 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v102.0.5005.56/test_ash_chrome" - ], - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "name": "interactive_ui_tests Lacros version skew testing ash 102.0.5005.56", - "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_v102.0.5005.56", - "revision": "version:102.0.5005.56" - } - ], - "dimension_sets": [ - { - "os": "Ubuntu-18.04", - "ssd": "0" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 - }, - "test": "interactive_ui_tests", - "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/", - "variant_id": "Lacros version skew testing ash 102.0.5005.56" - }, - { - "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter", "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5060.15/test_ash_chrome" ], "merge": { @@ -89652,6 +89620,38 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5060.22/test_ash_chrome" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "name": "interactive_ui_tests Lacros version skew testing ash 103.0.5060.22", + "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_v103.0.5060.22", + "revision": "version:103.0.5060.22" + } + ], + "dimension_sets": [ + { + "os": "Ubuntu-18.04", + "ssd": "0" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 3 + }, + "test": "interactive_ui_tests", + "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/", + "variant_id": "Lacros version skew testing ash 103.0.5060.22" + }, + { + "args": [ + "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter", "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5085.0/test_ash_chrome" ], "merge": { @@ -89755,37 +89755,6 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v102.0.5005.56/test_ash_chrome" - ], - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "name": "lacros_chrome_browsertests Lacros version skew testing ash 102.0.5005.56", - "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_v102.0.5005.56", - "revision": "version:102.0.5005.56" - } - ], - "dimension_sets": [ - { - "os": "Ubuntu-18.04", - "ssd": "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 102.0.5005.56" - }, - { - "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5060.15/test_ash_chrome" ], "merge": { @@ -89817,6 +89786,37 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5060.22/test_ash_chrome" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "name": "lacros_chrome_browsertests Lacros version skew testing ash 103.0.5060.22", + "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_v103.0.5060.22", + "revision": "version:103.0.5060.22" + } + ], + "dimension_sets": [ + { + "os": "Ubuntu-18.04", + "ssd": "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 103.0.5060.22" + }, + { + "args": [ + "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5085.0/test_ash_chrome" ], "merge": { @@ -89901,37 +89901,6 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v102.0.5005.56/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 102.0.5005.56", - "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_v102.0.5005.56", - "revision": "version:102.0.5005.56" - } - ], - "dimension_sets": [ - { - "os": "Ubuntu-18.04", - "ssd": "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 102.0.5005.56" - }, - { - "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5060.15/test_ash_chrome" ], "merge": { @@ -89963,6 +89932,37 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5060.22/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 103.0.5060.22", + "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_v103.0.5060.22", + "revision": "version:103.0.5060.22" + } + ], + "dimension_sets": [ + { + "os": "Ubuntu-18.04", + "ssd": "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 103.0.5060.22" + }, + { + "args": [ + "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5085.0/test_ash_chrome" ], "merge": { @@ -91421,38 +91421,6 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v102.0.5005.56/test_ash_chrome" - ], - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "name": "interactive_ui_tests Lacros version skew testing ash 102.0.5005.56", - "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_v102.0.5005.56", - "revision": "version:102.0.5005.56" - } - ], - "dimension_sets": [ - { - "os": "Ubuntu-18.04", - "ssd": "0" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 - }, - "test": "interactive_ui_tests", - "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/", - "variant_id": "Lacros version skew testing ash 102.0.5005.56" - }, - { - "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter", "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5060.15/test_ash_chrome" ], "merge": { @@ -91485,6 +91453,38 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5060.22/test_ash_chrome" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "name": "interactive_ui_tests Lacros version skew testing ash 103.0.5060.22", + "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_v103.0.5060.22", + "revision": "version:103.0.5060.22" + } + ], + "dimension_sets": [ + { + "os": "Ubuntu-18.04", + "ssd": "0" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 3 + }, + "test": "interactive_ui_tests", + "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/", + "variant_id": "Lacros version skew testing ash 103.0.5060.22" + }, + { + "args": [ + "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter", "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5085.0/test_ash_chrome" ], "merge": { @@ -91588,37 +91588,6 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v102.0.5005.56/test_ash_chrome" - ], - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "name": "lacros_chrome_browsertests Lacros version skew testing ash 102.0.5005.56", - "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_v102.0.5005.56", - "revision": "version:102.0.5005.56" - } - ], - "dimension_sets": [ - { - "os": "Ubuntu-18.04", - "ssd": "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 102.0.5005.56" - }, - { - "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5060.15/test_ash_chrome" ], "merge": { @@ -91650,6 +91619,37 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5060.22/test_ash_chrome" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "name": "lacros_chrome_browsertests Lacros version skew testing ash 103.0.5060.22", + "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_v103.0.5060.22", + "revision": "version:103.0.5060.22" + } + ], + "dimension_sets": [ + { + "os": "Ubuntu-18.04", + "ssd": "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 103.0.5060.22" + }, + { + "args": [ + "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5085.0/test_ash_chrome" ], "merge": { @@ -91734,37 +91734,6 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v102.0.5005.56/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 102.0.5005.56", - "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_v102.0.5005.56", - "revision": "version:102.0.5005.56" - } - ], - "dimension_sets": [ - { - "os": "Ubuntu-18.04", - "ssd": "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 102.0.5005.56" - }, - { - "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5060.15/test_ash_chrome" ], "merge": { @@ -91796,6 +91765,37 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5060.22/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 103.0.5060.22", + "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_v103.0.5060.22", + "revision": "version:103.0.5060.22" + } + ], + "dimension_sets": [ + { + "os": "Ubuntu-18.04", + "ssd": "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 103.0.5060.22" + }, + { + "args": [ + "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5085.0/test_ash_chrome" ], "merge": { @@ -92495,37 +92495,6 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v102.0.5005.56/test_ash_chrome" - ], - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "name": "interactive_ui_tests Lacros version skew testing ash 102.0.5005.56", - "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_v102.0.5005.56", - "revision": "version:102.0.5005.56" - } - ], - "dimension_sets": [ - { - "os": "Ubuntu-18.04" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 - }, - "test": "interactive_ui_tests", - "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/", - "variant_id": "Lacros version skew testing ash 102.0.5005.56" - }, - { - "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter", "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5060.15/test_ash_chrome" ], "merge": { @@ -92557,6 +92526,37 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5060.22/test_ash_chrome" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "name": "interactive_ui_tests Lacros version skew testing ash 103.0.5060.22", + "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_v103.0.5060.22", + "revision": "version:103.0.5060.22" + } + ], + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 3 + }, + "test": "interactive_ui_tests", + "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/", + "variant_id": "Lacros version skew testing ash 103.0.5060.22" + }, + { + "args": [ + "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter", "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5085.0/test_ash_chrome" ], "merge": {
diff --git a/testing/buildbot/internal.chromeos.fyi.json b/testing/buildbot/internal.chromeos.fyi.json index aa54377..7e886592 100644 --- a/testing/buildbot/internal.chromeos.fyi.json +++ b/testing/buildbot/internal.chromeos.fyi.json
@@ -1150,7 +1150,7 @@ { "args": [], "cros_board": "octopus", - "cros_img": "octopus-release/R102-14695.68.0", + "cros_img": "octopus-release/R103-14816.25.0", "name": "lacros_fyi_tast_tests OCTOPUS_RELEASE_BETA", "swarming": {}, "tast_expr": "(\"group:mainline\" && \"dep:lacros\" && !informational)", @@ -1196,7 +1196,7 @@ { "args": [], "cros_board": "octopus", - "cros_img": "octopus-release/R102-14695.68.0", + "cros_img": "octopus-release/R103-14816.25.0", "name": "ozone_unittests OCTOPUS_RELEASE_BETA", "swarming": {}, "test": "ozone_unittests", @@ -1250,7 +1250,7 @@ { "args": [], "cros_board": "strongbad", - "cros_img": "strongbad-release/R102-14695.68.0", + "cros_img": "strongbad-release/R103-14816.25.0", "name": "lacros_all_tast_tests STRONGBAD_RELEASE_BETA", "swarming": {}, "tast_expr": "(\"group:mainline\" && \"dep:lacros\" && !informational)", @@ -1296,7 +1296,7 @@ { "args": [], "cros_board": "strongbad", - "cros_img": "strongbad-release/R102-14695.68.0", + "cros_img": "strongbad-release/R103-14816.25.0", "name": "ozone_unittests STRONGBAD_RELEASE_BETA", "swarming": {}, "test": "ozone_unittests", @@ -1340,7 +1340,7 @@ { "args": [], "cros_board": "strongbad", - "cros_img": "strongbad-release/R102-14695.68.0", + "cros_img": "strongbad-release/R103-14816.25.0", "name": "viz_unittests STRONGBAD_RELEASE_BETA", "swarming": {}, "test": "viz_unittests",
diff --git a/testing/buildbot/variants.pyl b/testing/buildbot/variants.pyl index ce2bd9c..da3aa55 100644 --- a/testing/buildbot/variants.pyl +++ b/testing/buildbot/variants.pyl
@@ -52,15 +52,15 @@ }, 'LACROS_VERSION_SKEW_BETA': { 'args': [ - '--ash-chrome-path-override=../../lacros_version_skew_tests_v102.0.5005.56/test_ash_chrome', + '--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5060.22/test_ash_chrome', ], - 'identifier': 'Lacros version skew testing ash 102.0.5005.56', + 'identifier': 'Lacros version skew testing ash 103.0.5060.22', 'swarming': { 'cipd_packages': [ { 'cipd_package': 'chromium/testing/linux-ash-chromium/x86_64/ash.zip', - 'location': 'lacros_version_skew_tests_v102.0.5005.56', - 'revision': 'version:102.0.5005.56', + 'location': 'lacros_version_skew_tests_v103.0.5060.22', + 'revision': 'version:103.0.5060.22', }, ], }, @@ -486,16 +486,16 @@ }, 'WEBLAYER_10_AND_M_IMPL_SKEW_TESTS_NTH_MINUS_ONE_MILESTONE': { 'args': [ + '--webview-apk-path=apks/AOSP_SystemWebView.apk', '--test-runner-outdir', '.', '--client-outdir', '.', - '--test-expectations', - '../../weblayer/browser/android/javatests/skew/expectations.txt', - '--webview-apk-path=apks/AOSP_SystemWebView.apk', '--implementation-outdir', '../../weblayer_instrumentation_test_M102/out/Release', - '--impl-version=102' + '--test-expectations', + '../../weblayer/browser/android/javatests/skew/expectations.txt', + '--impl-version=102', ], 'identifier': 'with_impl_from_102', 'swarming': { @@ -503,10 +503,10 @@ { 'cipd_package': 'chromium/testing/weblayer-x86', 'location': 'weblayer_instrumentation_test_M102', - 'revision': 'version:102.0.5005.75' + 'revision': 'version:102.0.5005.76', } - ] - } + ], + }, }, 'WEBLAYER_10_AND_M_IMPL_SKEW_TESTS_NTH_MINUS_TWO_MILESTONE': { 'args': [ @@ -630,16 +630,16 @@ }, 'WEBLAYER_IMPL_SKEW_TESTS_NTH_MINUS_ONE_MILESTONE': { 'args': [ + '--webview-apk-path=apks/SystemWebView.apk', '--test-runner-outdir', '.', '--client-outdir', '.', - '--test-expectations', - '../../weblayer/browser/android/javatests/skew/expectations.txt', - '--webview-apk-path=apks/SystemWebView.apk', '--implementation-outdir', '../../weblayer_instrumentation_test_M102/out/Release', - '--impl-version=102' + '--test-expectations', + '../../weblayer/browser/android/javatests/skew/expectations.txt', + '--impl-version=102', ], 'identifier': 'with_impl_from_102', 'swarming': { @@ -647,10 +647,10 @@ { 'cipd_package': 'chromium/testing/weblayer-x86', 'location': 'weblayer_instrumentation_test_M102', - 'revision': 'version:102.0.5005.75' + 'revision': 'version:102.0.5005.76', } - ] - } + ], + }, }, 'WEBLAYER_IMPL_SKEW_TESTS_NTH_MINUS_TWO_MILESTONE': { 'args': [ @@ -774,16 +774,16 @@ }, 'WEBLAYER_CLIENT_SKEW_TESTS_NTH_MINUS_ONE_MILESTONE': { 'args': [ + '--webview-apk-path=apks/SystemWebView.apk', '--test-runner-outdir', '.', + '--client-outdir', + '../../weblayer_instrumentation_test_M102/out/Release', '--implementation-outdir', '.', '--test-expectations', '../../weblayer/browser/android/javatests/skew/expectations.txt', - '--webview-apk-path=apks/SystemWebView.apk', - '--client-outdir', - '../../weblayer_instrumentation_test_M102/out/Release', - '--client-version=102' + '--client-version=102', ], 'identifier': 'with_client_from_102', 'swarming': { @@ -791,10 +791,10 @@ { 'cipd_package': 'chromium/testing/weblayer-x86', 'location': 'weblayer_instrumentation_test_M102', - 'revision': 'version:102.0.5005.75' + 'revision': 'version:102.0.5005.76', } - ] - } + ], + }, }, 'WEBLAYER_CLIENT_SKEW_TESTS_NTH_MINUS_TWO_MILESTONE': { 'args': [ @@ -913,8 +913,8 @@ 'CROS_ATLAS_RELEASE_BETA': { 'skylab': { 'cros_board': 'atlas', - 'cros_chrome_version': '102.0.5005.56', - 'cros_img': 'atlas-release/R102-14695.68.0', + 'cros_chrome_version': '103.0.5060.22', + 'cros_img': 'atlas-release/R103-14816.25.0', }, 'enabled': True, 'identifier': 'ATLAS_RELEASE_BETA', @@ -940,8 +940,8 @@ 'CROS_EVE_RELEASE_BETA': { 'skylab': { 'cros_board': 'eve', - 'cros_chrome_version': '102.0.5005.48', - 'cros_img': 'eve-release/R102-14695.55.0', + 'cros_chrome_version': '103.0.5060.22', + 'cros_img': 'eve-release/R103-14816.25.0', }, 'enabled': True, 'identifier': 'EVE_RELEASE_BETA', @@ -976,8 +976,8 @@ 'CROS_HANA_RELEASE_BETA': { 'skylab': { 'cros_board': 'hana', - 'cros_chrome_version': '102.0.5005.56', - 'cros_img': 'hana-release/R102-14695.68.0', + 'cros_chrome_version': '103.0.5060.22', + 'cros_img': 'hana-release/R103-14816.25.0', }, 'enabled': True, 'identifier': 'HANA_RELEASE_BETA', @@ -1003,8 +1003,8 @@ 'CROS_JACUZZI_RELEASE_BETA': { 'skylab': { 'cros_board': 'jacuzzi', - 'cros_chrome_version': '102.0.5005.56', - 'cros_img': 'jacuzzi-release/R102-14695.68.0', + 'cros_chrome_version': '103.0.5060.22', + 'cros_img': 'jacuzzi-release/R103-14816.25.0', }, 'enabled': True, 'identifier': 'JACUZZI_RELEASE_BETA', @@ -1039,8 +1039,8 @@ 'CROS_OCTOPUS_RELEASE_BETA': { 'skylab': { 'cros_board': 'octopus', - 'cros_chrome_version': '102.0.5005.56', - 'cros_img': 'octopus-release/R102-14695.68.0', + 'cros_chrome_version': '103.0.5060.22', + 'cros_img': 'octopus-release/R103-14816.25.0', }, 'enabled': True, 'identifier': 'OCTOPUS_RELEASE_BETA', @@ -1075,8 +1075,8 @@ 'CROS_STRONGBAD_RELEASE_BETA': { 'skylab': { 'cros_board': 'strongbad', - 'cros_chrome_version': '102.0.5005.56', - 'cros_img': 'strongbad-release/R102-14695.68.0', + 'cros_chrome_version': '103.0.5060.22', + 'cros_img': 'strongbad-release/R103-14816.25.0', }, 'enabled': True, 'identifier': 'STRONGBAD_RELEASE_BETA',
diff --git a/third_party/blink/common/BUILD.gn b/third_party/blink/common/BUILD.gn index 732c092..ccb0729b 100644 --- a/third_party/blink/common/BUILD.gn +++ b/third_party/blink/common/BUILD.gn
@@ -136,6 +136,8 @@ "input/web_mouse_wheel_event.cc", "input/web_pointer_event.cc", "input/web_touch_event.cc", + "interest_group/auction_config.cc", + "interest_group/auction_config_mojom_traits.cc", "interest_group/interest_group.cc", "interest_group/interest_group_mojom_traits.cc", "link_to_text/link_to_text_mojom_traits.cc", @@ -331,6 +333,7 @@ "indexeddb/indexeddb_key_unittest.cc", "input/synthetic_web_input_event_builders_unittest.cc", "input/web_input_event_unittest.cc", + "interest_group/auction_config_mojom_traits_test.cc", "interest_group/interest_group_mojom_traits_test.cc", "loader/inter_process_time_ticks_converter_unittest.cc", "loader/mime_sniffing_throttle_unittest.cc",
diff --git a/third_party/blink/common/interest_group/auction_config.cc b/third_party/blink/common/interest_group/auction_config.cc new file mode 100644 index 0000000..6823f4c --- /dev/null +++ b/third_party/blink/common/interest_group/auction_config.cc
@@ -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. + +#include "third_party/blink/public/common/interest_group/auction_config.h" + +namespace blink { + +AuctionConfig::NonSharedParams::NonSharedParams() = default; +AuctionConfig::NonSharedParams::NonSharedParams(const NonSharedParams&) = + default; +AuctionConfig::NonSharedParams::NonSharedParams(NonSharedParams&&) = default; +AuctionConfig::NonSharedParams::~NonSharedParams() = default; + +AuctionConfig::NonSharedParams& AuctionConfig::NonSharedParams::operator=( + const NonSharedParams&) = default; +AuctionConfig::NonSharedParams& AuctionConfig::NonSharedParams::operator=( + NonSharedParams&&) = default; + +bool AuctionConfig::NonSharedParams::operator==( + const NonSharedParams& other) const { + return std::tie(interest_group_buyers, auction_signals, seller_signals, + seller_timeout, per_buyer_signals, per_buyer_timeouts, + all_buyers_timeout, per_buyer_group_limits, + all_buyers_group_limit, component_auctions) != + std::tie(other.interest_group_buyers, other.auction_signals, + other.seller_signals, other.seller_timeout, + other.per_buyer_signals, other.per_buyer_timeouts, + other.all_buyers_timeout, other.per_buyer_group_limits, + other.all_buyers_group_limit, other.component_auctions); +} + +AuctionConfig::AuctionConfig() = default; +AuctionConfig::AuctionConfig(const AuctionConfig&) = default; +AuctionConfig::AuctionConfig(AuctionConfig&&) = default; +AuctionConfig::~AuctionConfig() = default; + +AuctionConfig& AuctionConfig::operator=(const AuctionConfig&) = default; +AuctionConfig& AuctionConfig::operator=(AuctionConfig&&) = default; + +bool AuctionConfig::operator==(const AuctionConfig& other) const { + return std::tie(seller, decision_logic_url, trusted_scoring_signals_url, + non_shared_params, seller_experiment_group_id, + all_buyer_experiment_group_id, + per_buyer_experiment_group_ids) != + std::tie(other.seller, other.decision_logic_url, + other.trusted_scoring_signals_url, other.non_shared_params, + other.seller_experiment_group_id, + other.all_buyer_experiment_group_id, + other.per_buyer_experiment_group_ids); +} + +} // namespace blink
diff --git a/third_party/blink/common/interest_group/auction_config_mojom_traits.cc b/third_party/blink/common/interest_group/auction_config_mojom_traits.cc new file mode 100644 index 0000000..be33650 --- /dev/null +++ b/third_party/blink/common/interest_group/auction_config_mojom_traits.cc
@@ -0,0 +1,102 @@ +// 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/public/common/interest_group/auction_config_mojom_traits.h" + +#include "base/time/time.h" +#include "third_party/abseil-cpp/absl/types/optional.h" +#include "third_party/blink/public/common/interest_group/auction_config.h" +#include "third_party/blink/public/mojom/interest_group/interest_group_types.mojom.h" +#include "url/gurl.h" +#include "url/origin.h" +#include "url/url_constants.h" + +namespace mojo { + +namespace { + +// Helper to check if `url` is HTTPS and has the specified origin. Used to +// validate seller URLs can be used with the seller's origin. +bool IsHttpsAndMatchesOrigin(const GURL& seller_url, + const url::Origin& seller_origin) { + return seller_url.scheme() == url::kHttpsScheme && + url::Origin::Create(seller_url) == seller_origin; +} + +} // namespace + +bool StructTraits<blink::mojom::AuctionAdConfigNonSharedParamsDataView, + blink::AuctionConfig::NonSharedParams>:: + Read(blink::mojom::AuctionAdConfigNonSharedParamsDataView data, + blink::AuctionConfig::NonSharedParams* out) { + if (!data.ReadInterestGroupBuyers(&out->interest_group_buyers) || + !data.ReadAuctionSignals(&out->auction_signals) || + !data.ReadSellerSignals(&out->seller_signals) || + !data.ReadSellerTimeout(&out->seller_timeout) || + !data.ReadPerBuyerSignals(&out->per_buyer_signals) || + !data.ReadPerBuyerTimeouts(&out->per_buyer_timeouts) || + !data.ReadAllBuyersTimeout(&out->all_buyers_timeout) || + !data.ReadPerBuyerGroupLimits(&out->per_buyer_group_limits) || + !data.ReadComponentAuctions(&out->component_auctions)) { + return false; + } + + out->all_buyers_group_limit = data.all_buyers_group_limit(); + + if (out->interest_group_buyers) { + for (const auto& buyer : *out->interest_group_buyers) { + // Buyers must be HTTPS. + if (buyer.scheme() != url::kHttpsScheme) + return false; + } + } + + for (const auto& component_auction : out->component_auctions) { + // Component auctions may not have their own nested component auctions. + if (!component_auction.non_shared_params.component_auctions.empty()) { + return false; + } + } + + return true; +} + +bool StructTraits<blink::mojom::AuctionAdConfigDataView, blink::AuctionConfig>:: + Read(blink::mojom::AuctionAdConfigDataView data, + blink::AuctionConfig* out) { + if (!data.ReadSeller(&out->seller) || + !data.ReadDecisionLogicUrl(&out->decision_logic_url) || + !data.ReadTrustedScoringSignalsUrl(&out->trusted_scoring_signals_url) || + !data.ReadAuctionAdConfigNonSharedParams(&out->non_shared_params) || + !data.ReadPerBuyerExperimentGroupIds( + &out->per_buyer_experiment_group_ids)) { + return false; + } + + if (data.has_seller_experiment_group_id()) + out->seller_experiment_group_id = data.seller_experiment_group_id(); + + if (data.has_all_buyer_experiment_group_id()) + out->all_buyer_experiment_group_id = data.all_buyer_experiment_group_id(); + + // Seller must be HTTPS. This also excludes opaque origins, for which scheme() + // returns an empty string. + if (out->seller.scheme() != url::kHttpsScheme) + return false; + + // `decision_logic_url` and, if present, `trusted_scoring_signals_url` must + // share the seller's origin, and must be HTTPS. Need to explicitly check the + // scheme because some non-HTTPS URLs may have HTTPS origins (e.g., blob + // URLs). + if (!IsHttpsAndMatchesOrigin(out->decision_logic_url, out->seller) || + (out->trusted_scoring_signals_url && + !IsHttpsAndMatchesOrigin(*out->trusted_scoring_signals_url, + out->seller))) { + return false; + } + + return true; +} + +} // namespace mojo
diff --git a/third_party/blink/common/interest_group/auction_config_mojom_traits_test.cc b/third_party/blink/common/interest_group/auction_config_mojom_traits_test.cc new file mode 100644 index 0000000..0b38dbc8 --- /dev/null +++ b/third_party/blink/common/interest_group/auction_config_mojom_traits_test.cc
@@ -0,0 +1,182 @@ +// 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/public/common/interest_group/auction_config_mojom_traits.h" + +#include <string> +#include <vector> + +#include "base/containers/flat_map.h" +#include "base/time/time.h" +#include "mojo/public/cpp/test_support/test_utils.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/abseil-cpp/absl/types/optional.h" +#include "third_party/blink/public/common/interest_group/auction_config.h" +#include "third_party/blink/public/mojom/interest_group/interest_group_types.mojom.h" +#include "url/gurl.h" +#include "url/origin.h" + +namespace blink { + +namespace { + +// Creates a minimal valid AuctionConfig, with a seller and the passed in +// decision logic URL. Seller is derived from `decision_logic_url`. +AuctionConfig CreateBasicConfig( + const GURL& decision_logic_url = GURL("https://seller.test/foo")) { + AuctionConfig auction_config; + auction_config.seller = url::Origin::Create(decision_logic_url); + auction_config.decision_logic_url = decision_logic_url; + return auction_config; +} + +// Creates an AuctionConfig with all fields except `component_auctions` +// populated. +AuctionConfig CreateFullConfig() { + AuctionConfig auction_config = CreateBasicConfig(); + + auction_config.trusted_scoring_signals_url = GURL("https://seller.test/bar"); + auction_config.seller_experiment_group_id = 1; + auction_config.all_buyer_experiment_group_id = 2; + + url::Origin buyer = url::Origin::Create(GURL("https://buyer.test")); + auction_config.per_buyer_experiment_group_ids[buyer] = 3; + + AuctionConfig::NonSharedParams& non_shared_params = + auction_config.non_shared_params; + non_shared_params.interest_group_buyers.emplace(); + non_shared_params.interest_group_buyers->push_back(buyer); + non_shared_params.auction_signals = "[4]"; + non_shared_params.seller_signals = "[5]"; + non_shared_params.seller_timeout = base::Seconds(6); + non_shared_params.per_buyer_signals.emplace(); + (*non_shared_params.per_buyer_signals)[buyer] = "[7]"; + non_shared_params.per_buyer_timeouts.emplace(); + (*non_shared_params.per_buyer_timeouts)[buyer] = base::Seconds(8); + non_shared_params.all_buyers_timeout = base::Seconds(9); + non_shared_params.per_buyer_group_limits[buyer] = 10; + non_shared_params.all_buyers_group_limit = 11; + + return auction_config; +} + +// Attempts to serialize and then deserialize `auction_config`, returning true +// if deserialization succeeded. On success, also checks that the resulting +// config matches the original config. +bool SerializeAndDeserialize(const AuctionConfig& auction_config) { + AuctionConfig auction_config_clone; + bool success = + mojo::test::SerializeAndDeserialize<blink::mojom::AuctionAdConfig>( + auction_config, auction_config_clone); + + if (success) + EXPECT_EQ(auction_config, auction_config_clone); + return success; +} + +TEST(AuctionConfigMojomTraitsTest, Empty) { + AuctionConfig auction_config; + EXPECT_FALSE(SerializeAndDeserialize(auction_config)); +} + +TEST(AuctionConfigMojomTraitsTest, Basic) { + AuctionConfig auction_config = CreateBasicConfig(); + EXPECT_TRUE(SerializeAndDeserialize(auction_config)); +} + +TEST(AuctionConfigMojomTraitsTest, SellerNotHttps) { + AuctionConfig auction_config = CreateBasicConfig(GURL("http://seller.test")); + EXPECT_FALSE(SerializeAndDeserialize(auction_config)); +} + +TEST(AuctionConfigMojomTraitsTest, SellerDecisionUrlMismatch) { + AuctionConfig auction_config = CreateBasicConfig(GURL("http://seller.test")); + // Different origin than seller, but same scheme. + auction_config.decision_logic_url = GURL("https://not.seller.test/foo"); + EXPECT_FALSE(SerializeAndDeserialize(auction_config)); + + auction_config = CreateBasicConfig(GURL("https://seller.test")); + // This blob URL should be considered same-origin to the seller, but the + // scheme is wrong. + auction_config.decision_logic_url = GURL("blob:https://seller.test/foo"); + ASSERT_EQ(auction_config.seller, + url::Origin::Create(auction_config.decision_logic_url)); + EXPECT_FALSE(SerializeAndDeserialize(auction_config)); +} + +TEST(AuctionConfigMojomTraitsTest, SellerScoringSignalsUrlMismatch) { + AuctionConfig auction_config = CreateBasicConfig(GURL("http://seller.test")); + // Different origin than seller, but same scheme. + auction_config.trusted_scoring_signals_url = + GURL("https://not.seller.test/foo"); + EXPECT_FALSE(SerializeAndDeserialize(auction_config)); + + auction_config = CreateBasicConfig(GURL("https://seller.test")); + // This blob URL should be considered same-origin to the seller, but the + // scheme is wrong. + auction_config.trusted_scoring_signals_url = + GURL("blob:https://seller.test/foo"); + ASSERT_EQ(auction_config.seller, + url::Origin::Create(*auction_config.trusted_scoring_signals_url)); + EXPECT_FALSE(SerializeAndDeserialize(auction_config)); +} + +TEST(AuctionConfigMojomTraitsTest, FullConfig) { + AuctionConfig auction_config = CreateFullConfig(); + EXPECT_TRUE(SerializeAndDeserialize(auction_config)); +} + +TEST(AuctionConfigMojomTraitsTest, BuyerNotHttps) { + AuctionConfig auction_config = CreateBasicConfig(); + auction_config.non_shared_params.interest_group_buyers.emplace(); + auction_config.non_shared_params.interest_group_buyers->push_back( + url::Origin::Create(GURL("http://buyer.test"))); + EXPECT_FALSE(SerializeAndDeserialize(auction_config)); +} + +TEST(AuctionConfigMojomTraitsTest, BuyerNotHttpsMultipleBuyers) { + AuctionConfig auction_config = CreateBasicConfig(); + auction_config.non_shared_params.interest_group_buyers.emplace(); + auction_config.non_shared_params.interest_group_buyers->push_back( + url::Origin::Create(GURL("https://buyer1.test"))); + auction_config.non_shared_params.interest_group_buyers->push_back( + url::Origin::Create(GURL("http://buyer2.test"))); + EXPECT_FALSE(SerializeAndDeserialize(auction_config)); +} + +TEST(AuctionConfigMojomTraitsTest, ComponentAuctionUrlHttps) { + AuctionConfig auction_config = CreateBasicConfig(); + auction_config.non_shared_params.component_auctions.emplace_back( + CreateBasicConfig(GURL("http://seller.test"))); + EXPECT_FALSE(SerializeAndDeserialize(auction_config)); +} + +TEST(AuctionConfigMojomTraitsTest, ComponentAuctionTooDeep) { + AuctionConfig auction_config = CreateBasicConfig(); + auction_config.non_shared_params.component_auctions.emplace_back( + CreateBasicConfig()); + auction_config.non_shared_params.component_auctions[0] + .non_shared_params.component_auctions.emplace_back(CreateBasicConfig()); + EXPECT_FALSE(SerializeAndDeserialize(auction_config)); +} + +TEST(AuctionConfigMojomTraitsTest, ComponentAuctionSuccessSingleBasic) { + AuctionConfig auction_config = CreateBasicConfig(); + auction_config.non_shared_params.component_auctions.emplace_back( + CreateBasicConfig()); + EXPECT_TRUE(SerializeAndDeserialize(auction_config)); +} + +TEST(AuctionConfigMojomTraitsTest, ComponentAuctionSuccessMutipleFull) { + AuctionConfig auction_config = CreateFullConfig(); + auction_config.non_shared_params.component_auctions.emplace_back( + CreateFullConfig()); + auction_config.non_shared_params.component_auctions.emplace_back( + CreateFullConfig()); + EXPECT_TRUE(SerializeAndDeserialize(auction_config)); +} + +} // namespace + +} // namespace blink
diff --git a/third_party/blink/public/common/BUILD.gn b/third_party/blink/public/common/BUILD.gn index 611c6cf..d10f539 100644 --- a/third_party/blink/public/common/BUILD.gn +++ b/third_party/blink/public/common/BUILD.gn
@@ -171,6 +171,8 @@ "input/web_touch_event.h", "input/web_touch_point.h", "interest_group/ad_auction_constants.h", + "interest_group/auction_config.h", + "interest_group/auction_config_mojom_traits.h", "interest_group/interest_group.h", "interest_group/interest_group_mojom_traits.h", "link_to_text/link_to_text_mojom_traits.h",
diff --git a/third_party/blink/public/common/interest_group/auction_config.h b/third_party/blink/public/common/interest_group/auction_config.h new file mode 100644 index 0000000..573d1af --- /dev/null +++ b/third_party/blink/public/common/interest_group/auction_config.h
@@ -0,0 +1,116 @@ +// 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 THIRD_PARTY_BLINK_PUBLIC_COMMON_INTEREST_GROUP_AUCTION_CONFIG_H_ +#define THIRD_PARTY_BLINK_PUBLIC_COMMON_INTEREST_GROUP_AUCTION_CONFIG_H_ + +#include <stdint.h> + +#include <limits> +#include <string> +#include <vector> + +#include "base/containers/flat_map.h" +#include "base/time/time.h" +#include "third_party/abseil-cpp/absl/types/optional.h" +#include "third_party/blink/public/common/common_export.h" +#include "url/gurl.h" +#include "url/origin.h" + +namespace blink { + +// AuctionConfig class used by FLEDGE auctions. Typemapped to +// blink::mojom::AuctionAdConfig, primarily so the typemap can include validity +// checks on the origins of the provided URLs. Not called blink::AuctionConfig +// because a class of that name is already created from auction_ad_config.idl. +// +// All URLs and origins must be HTTPS. +struct BLINK_COMMON_EXPORT AuctionConfig { + // Subset of AuctionConfig that is not shared by all auctions that are + // using the same SellerWorklet object (so it's "not shared" between + // AuctionConfigs that share the same SellerWorklet). Other AuctionConfig + // parameters all must be the same for two auctions to share a Sellerworklet. + // + // Typemapped to blink::mojom::AuctionAdConfigNonSharedParams. + struct BLINK_COMMON_EXPORT NonSharedParams { + NonSharedParams(); + NonSharedParams(const NonSharedParams&); + NonSharedParams(NonSharedParams&&); + ~NonSharedParams(); + + NonSharedParams& operator=(const NonSharedParams&); + NonSharedParams& operator=(NonSharedParams&&); + + // Provided for testing. + bool operator==(const NonSharedParams& other) const; + + // Owners of interest groups allowed to participate in the auction. + absl::optional<std::vector<url::Origin>> interest_group_buyers; + + // Opaque JSON data, passed as object to all worklets. + absl::optional<std::string> auction_signals; + + // Opaque JSON data, passed as object to the seller worklet. + absl::optional<std::string> seller_signals; + + // The value restricts the runtime of the seller's scoreAd() script. + absl::optional<base::TimeDelta> seller_timeout; + + // Value is opaque JSON data, passed as object to particular buyers. + absl::optional<base::flat_map<url::Origin, std::string>> per_buyer_signals; + + // Values restrict the runtime of particular buyer's generateBid() scripts. + absl::optional<base::flat_map<url::Origin, base::TimeDelta>> + per_buyer_timeouts; + + // The value restricts generateBid() script's runtime of all buyers with + // unspecified timeouts, if present. + absl::optional<base::TimeDelta> all_buyers_timeout; + + // Values restrict the number of bidding interest groups for a particular + // buyer that can participate in an auction. Values must be greater than 0. + base::flat_map<url::Origin, std::uint16_t> per_buyer_group_limits; + + // Limit on the number of bidding interest groups for any buyer. Must be + // greater than 0. Defaults to the largest uint16 value, which is fine + // in our case since the backend storage applies a lower limit. + std::uint16_t all_buyers_group_limit = + std::numeric_limits<std::uint16_t>::max(); + + // Nested auctions whose results will also be fed to `seller`. Only the top + // level auction config can have component auctions. + std::vector<AuctionConfig> component_auctions; + }; + + AuctionConfig(); + AuctionConfig(const AuctionConfig&); + AuctionConfig(AuctionConfig&&); + ~AuctionConfig(); + + AuctionConfig& operator=(const AuctionConfig&); + AuctionConfig& operator=(AuctionConfig&&); + + // Provided for testing. + bool operator==(const AuctionConfig& other) const; + + // Seller running the auction. + url::Origin seller; + + // Both URLS, if present, must be same-origin to `seller`. + GURL decision_logic_url; + absl::optional<GURL> trusted_scoring_signals_url; + + // Other parameters are grouped in a struct that is passed to SellerWorklets. + NonSharedParams non_shared_params; + + // Identifier for an experiment group, used when getting trusted + // signals (and as part of AuctionConfig given to worklets). + absl::optional<uint16_t> seller_experiment_group_id; + absl::optional<uint16_t> all_buyer_experiment_group_id; + base::flat_map<url::Origin, uint16_t> per_buyer_experiment_group_ids; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_PUBLIC_COMMON_INTEREST_GROUP_AUCTION_CONFIG_H_
diff --git a/third_party/blink/public/common/interest_group/auction_config_mojom_traits.h b/third_party/blink/public/common/interest_group/auction_config_mojom_traits.h new file mode 100644 index 0000000..1d986cd --- /dev/null +++ b/third_party/blink/public/common/interest_group/auction_config_mojom_traits.h
@@ -0,0 +1,131 @@ +// 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 THIRD_PARTY_BLINK_PUBLIC_COMMON_INTEREST_GROUP_AUCTION_CONFIG_MOJOM_TRAITS_H_ +#define THIRD_PARTY_BLINK_PUBLIC_COMMON_INTEREST_GROUP_AUCTION_CONFIG_MOJOM_TRAITS_H_ + +#include <string> +#include <vector> + +#include "base/time/time.h" +#include "third_party/abseil-cpp/absl/types/optional.h" +#include "third_party/blink/public/common/common_export.h" +#include "third_party/blink/public/common/interest_group/auction_config.h" +#include "third_party/blink/public/mojom/interest_group/interest_group_types.mojom-forward.h" +#include "url/gurl.h" +#include "url/origin.h" + +namespace mojo { + +template <> +struct BLINK_COMMON_EXPORT + StructTraits<blink::mojom::AuctionAdConfigNonSharedParamsDataView, + blink::AuctionConfig::NonSharedParams> { + static const absl::optional<std::vector<url::Origin>>& interest_group_buyers( + const blink::AuctionConfig::NonSharedParams& params) { + return params.interest_group_buyers; + } + + static const absl::optional<std::string>& auction_signals( + const blink::AuctionConfig::NonSharedParams& params) { + return params.auction_signals; + } + + static const absl::optional<std::string>& seller_signals( + const blink::AuctionConfig::NonSharedParams& params) { + return params.seller_signals; + } + + static absl::optional<base::TimeDelta> seller_timeout( + const blink::AuctionConfig::NonSharedParams& params) { + return params.seller_timeout; + } + + static const absl::optional<base::flat_map<url::Origin, std::string>>& + per_buyer_signals(const blink::AuctionConfig::NonSharedParams& params) { + return params.per_buyer_signals; + } + + static const absl::optional<base::flat_map<url::Origin, base::TimeDelta>>& + per_buyer_timeouts(const blink::AuctionConfig::NonSharedParams& params) { + return params.per_buyer_timeouts; + } + + static const absl::optional<base::TimeDelta>& all_buyers_timeout( + const blink::AuctionConfig::NonSharedParams& params) { + return params.all_buyers_timeout; + } + + static const base::flat_map<url::Origin, std::uint16_t>& + per_buyer_group_limits(const blink::AuctionConfig::NonSharedParams& params) { + return params.per_buyer_group_limits; + } + + static std::uint16_t all_buyers_group_limit( + const blink::AuctionConfig::NonSharedParams& params) { + return params.all_buyers_group_limit; + } + + static const std::vector<blink::AuctionConfig>& component_auctions( + const blink::AuctionConfig::NonSharedParams& params) { + return params.component_auctions; + } + + static bool Read(blink::mojom::AuctionAdConfigNonSharedParamsDataView data, + blink::AuctionConfig::NonSharedParams* out); +}; + +template <> +struct BLINK_COMMON_EXPORT + StructTraits<blink::mojom::AuctionAdConfigDataView, blink::AuctionConfig> { + static const url::Origin& seller(const blink::AuctionConfig& config) { + return config.seller; + } + + static const GURL& decision_logic_url(const blink::AuctionConfig& config) { + return config.decision_logic_url; + } + + static const absl::optional<GURL>& trusted_scoring_signals_url( + const blink::AuctionConfig& config) { + return config.trusted_scoring_signals_url; + } + + static const blink::AuctionConfig::NonSharedParams& + auction_ad_config_non_shared_params(const blink::AuctionConfig& config) { + return config.non_shared_params; + } + + static bool has_seller_experiment_group_id( + const blink::AuctionConfig& config) { + return config.seller_experiment_group_id.has_value(); + } + + static std::int16_t seller_experiment_group_id( + const blink::AuctionConfig& config) { + return config.seller_experiment_group_id.value_or(0); + } + + static bool has_all_buyer_experiment_group_id( + const blink::AuctionConfig& config) { + return config.all_buyer_experiment_group_id.has_value(); + } + + static std::int16_t all_buyer_experiment_group_id( + const blink::AuctionConfig& config) { + return config.all_buyer_experiment_group_id.value_or(0); + } + + static const base::flat_map<url::Origin, uint16_t>& + per_buyer_experiment_group_ids(const blink::AuctionConfig& config) { + return config.per_buyer_experiment_group_ids; + } + + static bool Read(blink::mojom::AuctionAdConfigDataView data, + blink::AuctionConfig* out); +}; + +} // namespace mojo + +#endif // THIRD_PARTY_BLINK_PUBLIC_COMMON_INTEREST_GROUP_AUCTION_CONFIG_MOJOM_TRAITS_H_
diff --git a/third_party/blink/public/mojom/BUILD.gn b/third_party/blink/public/mojom/BUILD.gn index 6008ee0..dce260b2 100644 --- a/third_party/blink/public/mojom/BUILD.gn +++ b/third_party/blink/public/mojom/BUILD.gn
@@ -515,6 +515,26 @@ { types = [ { + mojom = "blink.mojom.AuctionAdConfigNonSharedParams" + cpp = "::blink::AuctionConfig::NonSharedParams" + }, + ] + traits_headers = [ "//third_party/blink/public/common/interest_group/auction_config_mojom_traits.h" ] + traits_public_deps = [ "//url/mojom:mojom_traits" ] + }, + { + types = [ + { + mojom = "blink.mojom.AuctionAdConfig" + cpp = "::blink::AuctionConfig" + }, + ] + traits_headers = [ "//third_party/blink/public/common/interest_group/auction_config_mojom_traits.h" ] + traits_public_deps = [ "//url/mojom:mojom_traits" ] + }, + { + types = [ + { mojom = "blink.mojom.ClipboardBuffer" cpp = "::ui::ClipboardBuffer" },
diff --git a/third_party/blink/public/mojom/interest_group/interest_group_types.mojom b/third_party/blink/public/mojom/interest_group/interest_group_types.mojom index 8eee162a..caddd77 100644 --- a/third_party/blink/public/mojom/interest_group/interest_group_types.mojom +++ b/third_party/blink/public/mojom/interest_group/interest_group_types.mojom
@@ -55,12 +55,13 @@ // parameters all must be the same for two auctions to share a Sellerworklet. struct AuctionAdConfigNonSharedParams { // Owners of interest groups allowed to participate in the auction. + // Must all be HTTPS. array<url.mojom.Origin>? interest_group_buyers; - // Opaque JSON data, passed as object to auction worklet. + // Opaque JSON data, passed as object to all worklets. string? auction_signals; - // Opaque JSON data, passed as object to auction worklet. + // Opaque JSON data, passed as object to the seller worklet. string? seller_signals; // The value restricts the runtime of the seller's scoreAd() script. @@ -100,7 +101,7 @@ // https://github.com/WICG/turtledove/blob/main/FLEDGE.md#21-initiating-an-on-device-auction struct AuctionAdConfig { // The entity running the ad auction. Unlike for interest groups, `seller` - // *doesn't* need to match the the current frame URL's origin since the + // *doesn't* need to match the current frame URL's origin since the // `decision_logic_url` determines the behavior of the auction. This allows // the publisher page embedding the ad to call runAdAuction() directly if it // desires, rather than requiring the runAdAuction() call to be made inside a @@ -109,7 +110,7 @@ // seller and publisher could be different entities, or the same entity. url.mojom.Origin seller; - // `decision_logic_url`'s origin must match the the seller's origin. + // `decision_logic_url`'s origin must match the seller's origin. url.mojom.Url decision_logic_url; // Base URL for per-bid data passed to the seller worklet. Must be same
diff --git a/third_party/blink/public/mojom/navigation/navigation_api_history_entry_arrays.mojom b/third_party/blink/public/mojom/navigation/navigation_api_history_entry_arrays.mojom index 1dbc48a..b0f376a 100644 --- a/third_party/blink/public/mojom/navigation/navigation_api_history_entry_arrays.mojom +++ b/third_party/blink/public/mojom/navigation/navigation_api_history_entry_arrays.mojom
@@ -18,7 +18,7 @@ mojo_base.mojom.String16 url; int64 item_sequence_number; int64 document_sequence_number; - mojo_base.mojom.String16 state; + mojo_base.mojom.String16? state; }; // A same-origin subset of the back/forward list exposed by the
diff --git a/third_party/blink/public/web/web_local_frame_client.h b/third_party/blink/public/web/web_local_frame_client.h index 5954411..97c7d87 100644 --- a/third_party/blink/public/web/web_local_frame_client.h +++ b/third_party/blink/public/web/web_local_frame_client.h
@@ -452,6 +452,10 @@ // Called when a frame's page lifecycle state gets updated. virtual void DidSetPageLifecycleState() {} + // Immediately notifies the browser of a change in the current HistoryItem. + // Prefer DidUpdateCurrentHistoryItem(). + virtual void NotifyCurrentHistoryItemChanged() {} + // Called upon update to scroll position, document state, and other // non-navigational events related to the data held by WebHistoryItem. // WARNING: This method may be called very frequently.
diff --git a/third_party/blink/renderer/bindings/core/v8/v8_script_runner.cc b/third_party/blink/renderer/bindings/core/v8/v8_script_runner.cc index 8762e2c..2ccfd313 100644 --- a/third_party/blink/renderer/bindings/core/v8/v8_script_runner.cc +++ b/third_party/blink/renderer/bindings/core/v8/v8_script_runner.cc
@@ -650,46 +650,6 @@ return ScriptEvaluationResult::FromClassicExceptionRethrown(); } -v8::MaybeLocal<v8::Value> V8ScriptRunner::CompileAndRunInternalScript( - v8::Isolate* isolate, - ScriptState* script_state, - const ClassicScript& classic_script) { - DCHECK_EQ(isolate, script_state->GetIsolate()); - - const ReferrerScriptInfo referrer_info(classic_script.BaseUrl(), - classic_script.FetchOptions()); - v8::Local<v8::Data> host_defined_options = - referrer_info.ToV8HostDefinedOptions(isolate, classic_script.SourceUrl()); - - v8::ScriptCompiler::CompileOptions compile_options; - V8CodeCache::ProduceCacheOptions produce_cache_options; - v8::ScriptCompiler::NoCacheReason no_cache_reason; - std::tie(compile_options, produce_cache_options, no_cache_reason) = - V8CodeCache::GetCompileOptions(mojom::blink::V8CacheOptions::kDefault, - classic_script); - // Currently internal scripts don't have cache handlers. So we should not - // produce cache for them. - DCHECK_EQ(produce_cache_options, - V8CodeCache::ProduceCacheOptions::kNoProduceCache); - v8::Local<v8::Script> script; - if (!V8ScriptRunner::CompileScript(script_state, classic_script, - compile_options, no_cache_reason, - host_defined_options) - .ToLocal(&script)) - return v8::MaybeLocal<v8::Value>(); - - TRACE_EVENT0("v8", "v8.run"); - RuntimeCallStatsScopedTracer rcs_scoped_tracer(isolate); - RUNTIME_CALL_TIMER_SCOPE(isolate, RuntimeCallStats::CounterId::kV8); - v8::Isolate::SafeForTerminationScope safe_for_termination(isolate); - v8::MicrotasksScope microtasks_scope( - isolate, ToMicrotaskQueue(script_state), - v8::MicrotasksScope::kDoNotRunMicrotasks); - v8::MaybeLocal<v8::Value> result = script->Run(isolate->GetCurrentContext()); - CHECK(!isolate->IsDead()); - return result; -} - v8::MaybeLocal<v8::Value> V8ScriptRunner::CallAsConstructor( v8::Isolate* isolate, v8::Local<v8::Object> constructor,
diff --git a/third_party/blink/renderer/bindings/core/v8/v8_script_runner.h b/third_party/blink/renderer/bindings/core/v8/v8_script_runner.h index fe4ab37..3d96451 100644 --- a/third_party/blink/renderer/bindings/core/v8/v8_script_runner.h +++ b/third_party/blink/renderer/bindings/core/v8/v8_script_runner.h
@@ -125,8 +125,6 @@ ClassicScript*, ExecuteScriptPolicy, RethrowErrorsOption); - static v8::MaybeLocal<v8::Value> - CompileAndRunInternalScript(v8::Isolate*, ScriptState*, const ClassicScript&); static v8::MaybeLocal<v8::Value> CallAsConstructor( v8::Isolate*, v8::Local<v8::Object>,
diff --git a/third_party/blink/renderer/core/frame/local_frame_client.h b/third_party/blink/renderer/core/frame/local_frame_client.h index 6fb2409..c5b2d86 100644 --- a/third_party/blink/renderer/core/frame/local_frame_client.h +++ b/third_party/blink/renderer/core/frame/local_frame_client.h
@@ -303,6 +303,12 @@ virtual bool AllowScriptExtensions() = 0; virtual void DidChangeScrollOffset() {} + + // Immediately notifies the browser of a change in the current HistoryItem. + // Prefer DidUpdateCurrentHistoryItem(). + virtual void NotifyCurrentHistoryItemChanged() {} + // Notifies the browser of a change in the current HistoryItem on a timer, + // allowing batching of updates. virtual void DidUpdateCurrentHistoryItem() {} // Called when a content-initiated, main frame navigation to a data URL is
diff --git a/third_party/blink/renderer/core/frame/local_frame_client_impl.cc b/third_party/blink/renderer/core/frame/local_frame_client_impl.cc index 40042e1..da7bd0f 100644 --- a/third_party/blink/renderer/core/frame/local_frame_client_impl.cc +++ b/third_party/blink/renderer/core/frame/local_frame_client_impl.cc
@@ -290,9 +290,13 @@ web_frame_->Client()->DidChangeScrollOffset(); } -void LocalFrameClientImpl::DidUpdateCurrentHistoryItem() { +void LocalFrameClientImpl::NotifyCurrentHistoryItemChanged() { if (web_frame_->Client()) - web_frame_->Client()->DidUpdateCurrentHistoryItem(); + web_frame_->Client()->NotifyCurrentHistoryItemChanged(); +} + +void LocalFrameClientImpl::DidUpdateCurrentHistoryItem() { + web_frame_->Client()->DidUpdateCurrentHistoryItem(); } bool LocalFrameClientImpl::AllowContentInitiatedDataUrlNavigations(
diff --git a/third_party/blink/renderer/core/frame/local_frame_client_impl.h b/third_party/blink/renderer/core/frame/local_frame_client_impl.h index 1f929d9..f2e228ab 100644 --- a/third_party/blink/renderer/core/frame/local_frame_client_impl.h +++ b/third_party/blink/renderer/core/frame/local_frame_client_impl.h
@@ -193,6 +193,7 @@ WebRemotePlaybackClient* CreateWebRemotePlaybackClient( HTMLMediaElement&) override; void DidChangeScrollOffset() override; + void NotifyCurrentHistoryItemChanged() override; void DidUpdateCurrentHistoryItem() override; bool AllowContentInitiatedDataUrlNavigations(const KURL&) override;
diff --git a/third_party/blink/renderer/core/html/media/autoplay_policy.cc b/third_party/blink/renderer/core/html/media/autoplay_policy.cc index 862314da..871d825 100644 --- a/third_party/blink/renderer/core/html/media/autoplay_policy.cc +++ b/third_party/blink/renderer/core/html/media/autoplay_policy.cc
@@ -347,7 +347,8 @@ return; if (self->element_->can_autoplay_ && self->element_->Autoplay()) { - self->element_->PauseInternal(); + self->element_->PauseInternal( + HTMLMediaElement::PlayPromiseError::kPaused_AutoplayAutoPause); self->element_->can_autoplay_ = true; } };
diff --git a/third_party/blink/renderer/core/html/media/html_media_element.cc b/third_party/blink/renderer/core/html/media/html_media_element.cc index 05b0138..b4fbf82 100644 --- a/third_party/blink/renderer/core/html/media/html_media_element.cc +++ b/third_party/blink/renderer/core/html/media/html_media_element.cc
@@ -1735,7 +1735,7 @@ ScheduleEvent(event_type_names::kError); // 6 - Reject pending play promises with NotSupportedError. - ScheduleRejectPlayPromises(DOMExceptionCode::kNotSupportedError); + ScheduleRejectPlayPromises(PlayPromiseError::kNotSupported); CloseMediaSource(); @@ -2745,10 +2745,10 @@ DVLOG(2) << "pause(" << *this << ")"; autoplay_policy_->StopAutoplayMutedWhenVisible(); - PauseInternal(); + PauseInternal(PlayPromiseError::kPaused_PauseCalled); } -void HTMLMediaElement::PauseInternal() { +void HTMLMediaElement::PauseInternal(PlayPromiseError code) { DVLOG(3) << "pauseInternal(" << *this << ")"; if (network_state_ == kNetworkEmpty) @@ -2767,7 +2767,7 @@ // time to accurately reflect movie time at the moment we paused. SetOfficialPlaybackPosition(CurrentPlaybackPosition()); - ScheduleRejectPlayPromises(DOMExceptionCode::kAbortError); + ScheduleRejectPlayPromises(code); } UpdatePlayState(); @@ -3004,7 +3004,7 @@ WebFeature::kHTMLMediaElementPauseAtFragmentEnd); // changes paused to true and fires a simple event named pause at the // media element. - PauseInternal(); + PauseInternal(PlayPromiseError::kPaused_EndOfPlayback); } } @@ -3590,7 +3590,7 @@ // media element. paused_ = true; ScheduleEvent(event_type_names::kPause); - ScheduleRejectPlayPromises(DOMExceptionCode::kAbortError); + ScheduleRejectPlayPromises(PlayPromiseError::kPaused_EndOfPlayback); } // Queue a task to fire a simple event named ended at the media element. ScheduleEvent(event_type_names::kEnded); @@ -4378,7 +4378,7 @@ WrapWeakPersistent(this))); } -void HTMLMediaElement::ScheduleRejectPlayPromises(DOMExceptionCode code) { +void HTMLMediaElement::ScheduleRejectPlayPromises(PlayPromiseError code) { // TODO(mlamouri): per spec, we should create a new task but we can't create // a new cancellable task without cancelling the previous one. There are two // approaches then: cancel the previous task and create a new one with the @@ -4418,20 +4418,38 @@ } void HTMLMediaElement::RejectScheduledPlayPromises() { - // TODO(mlamouri): the message is generated based on the code because - // arguments can't be passed to a cancellable task. In order to save space - // used by the object, the string isn't saved. - DCHECK(play_promise_error_code_ == DOMExceptionCode::kAbortError || - play_promise_error_code_ == DOMExceptionCode::kNotSupportedError); - if (play_promise_error_code_ == DOMExceptionCode::kAbortError) { - RejectPlayPromisesInternal(DOMExceptionCode::kAbortError, - "The play() request was interrupted by a call " - "to pause(). https://goo.gl/LdLk22"); - } else { - RejectPlayPromisesInternal( - DOMExceptionCode::kNotSupportedError, - "Failed to load because no supported source was found."); + switch (play_promise_error_code_) { + case PlayPromiseError::kNotSupported: + return RejectPlayPromisesInternal( + DOMExceptionCode::kNotSupportedError, + "Failed to load because no supported source was found."); + case PlayPromiseError::kPaused_Unknown: + return RejectPlayPromisesInternal( + DOMExceptionCode::kAbortError, + "The play() request was interrupted because the media paused. " + "https://goo.gl/LdLk22"); + case PlayPromiseError::kPaused_PauseCalled: + return RejectPlayPromisesInternal( + DOMExceptionCode::kAbortError, + "The play() request was interrupted by a call to pause(). " + "https://goo.gl/LdLk22"); + case PlayPromiseError::kPaused_EndOfPlayback: + return RejectPlayPromisesInternal( + DOMExceptionCode::kAbortError, + "The play() request was interrupted by end of playback. " + "https://goo.gl/LdLk22"); + case PlayPromiseError::kPaused_RemovedFromDocument: + return RejectPlayPromisesInternal( + DOMExceptionCode::kAbortError, + "The play() request was interrupted because the media was removed " + "from the document. https://goo.gl/LdLk22"); + case PlayPromiseError::kPaused_AutoplayAutoPause: + return RejectPlayPromisesInternal( + DOMExceptionCode::kAbortError, + "The play() request was interrupted because autoplaying media was " + "auto-paused. https://goo.gl/LdLk22"); } + NOTREACHED(); } void HTMLMediaElement::RejectPlayPromises(DOMExceptionCode code, @@ -4445,7 +4463,6 @@ const String& message) { DCHECK(code == DOMExceptionCode::kAbortError || code == DOMExceptionCode::kNotSupportedError); - for (auto& resolver : play_promise_reject_list_) resolver->Reject(MakeGarbageCollected<DOMException>(code, message)); @@ -4459,7 +4476,7 @@ // Video should not pause when playing in Picture-in-Picture and subsequently // removed from the Document. if (!PictureInPictureController::IsElementInPictureInPicture(this)) - PauseInternal(); + PauseInternal(PlayPromiseError::kPaused_RemovedFromDocument); } void HTMLMediaElement::AudioSourceProviderImpl::Wrap( @@ -4553,7 +4570,7 @@ } void HTMLMediaElement::PausePlayback() { - PauseInternal(); + PauseInternal(PlayPromiseError::kPaused_Unknown); } void HTMLMediaElement::DidPlayerStartPlaying() { @@ -4652,7 +4669,7 @@ frame, mojom::blink::UserActivationNotificationType::kInteraction); } } - PauseInternal(); + PauseInternal(PlayPromiseError::kPaused_Unknown); } void HTMLMediaElement::RequestSeekForward(base::TimeDelta seek_time) {
diff --git a/third_party/blink/renderer/core/html/media/html_media_element.h b/third_party/blink/renderer/core/html/media/html_media_element.h index 6a5f862..2da15b7 100644 --- a/third_party/blink/renderer/core/html/media/html_media_element.h +++ b/third_party/blink/renderer/core/html/media/html_media_element.h
@@ -113,6 +113,15 @@ static constexpr double kMinPlaybackRate = 0.0625; static constexpr double kMaxPlaybackRate = 16.0; + enum class PlayPromiseError { + kNotSupported, + kPaused_Unknown, + kPaused_PauseCalled, + kPaused_EndOfPlayback, + kPaused_RemovedFromDocument, + kPaused_AutoplayAutoPause, + }; + bool IsMediaElement() const override { return true; } static MIMETypeRegistry::SupportsType GetSupportsType(const ContentType&); @@ -599,7 +608,7 @@ void PlayInternal(); // This does not stop autoplay visibility observation. - void PauseInternal(); + void PauseInternal(PlayPromiseError code); void UpdatePlayState(); bool PotentiallyPlaying() const; @@ -646,7 +655,7 @@ void AudioTracksTimerFired(TimerBase*); void ScheduleResolvePlayPromises(); - void ScheduleRejectPlayPromises(DOMExceptionCode); + void ScheduleRejectPlayPromises(PlayPromiseError); void ScheduleNotifyPlaying(); void ResolveScheduledPlayPromises(); void RejectScheduledPlayPromises(); @@ -802,7 +811,7 @@ TaskHandle play_promise_reject_task_handle_; HeapVector<Member<ScriptPromiseResolver>> play_promise_resolve_list_; HeapVector<Member<ScriptPromiseResolver>> play_promise_reject_list_; - DOMExceptionCode play_promise_error_code_; + PlayPromiseError play_promise_error_code_; // HTMLMediaElement and its MediaElementAudioSourceNode in case it is provided // die together.
diff --git a/third_party/blink/renderer/core/input/event_handler.cc b/third_party/blink/renderer/core/input/event_handler.cc index 7231b5e..bc64875 100644 --- a/third_party/blink/renderer/core/input/event_handler.cc +++ b/third_party/blink/renderer/core/input/event_handler.cc
@@ -915,9 +915,9 @@ event_result == WebInputEventResult::kNotHandled) || mev.GetScrollbar()) { mouse_event_manager_->SetCapturesDragging(true); - // Main frames don't implicitly capture mouse input on MouseDown, just - // subframes do (regardless of whether local or remote). - if (!frame_->IsMainFrame()) + // Outermost main frames don't implicitly capture mouse input on MouseDown, + // all subframes do (regardless of whether local or remote or fenced). + if (frame_->IsAttached() && !frame_->IsOutermostMainFrame()) CaptureMouseEventsToWidget(true); } else { mouse_event_manager_->SetCapturesDragging(false);
diff --git a/third_party/blink/renderer/core/input/pointer_event_manager.cc b/third_party/blink/renderer/core/input/pointer_event_manager.cc index f992e8b..459f9e7 100644 --- a/third_party/blink/renderer/core/input/pointer_event_manager.cc +++ b/third_party/blink/renderer/core/input/pointer_event_manager.cc
@@ -667,11 +667,6 @@ mojom::blink::UserActivationNotificationType::kInteraction); } - if (event.GetType() == WebInputEvent::Type::kPointerDown) { - touch_event_manager_->UpdateTouchAttributeMapsForPointerDown( - event, pointer_event_target); - } - WebInputEventResult result = DispatchTouchPointerEvent( event, coalesced_events, predicted_events, pointer_event_target);
diff --git a/third_party/blink/renderer/core/input/touch_event_manager.cc b/third_party/blink/renderer/core/input/touch_event_manager.cc index f7af7beb..856961e3 100644 --- a/third_party/blink/renderer/core/input/touch_event_manager.cc +++ b/third_party/blink/renderer/core/input/touch_event_manager.cc
@@ -624,6 +624,12 @@ return; } + // In touch event model only touch starts can set the target and after that + // the touch event always goes to that target. + if (event.GetType() == WebInputEvent::Type::kPointerDown) { + UpdateTouchAttributeMapsForPointerDown(event, pointer_event_target); + } + // We might not receive the down action for a touch point. In that case we // would have never added them to |touch_attribute_map_| or hit-tested // them. For those just keep them in the map with a null target. Later they
diff --git a/third_party/blink/renderer/core/input/touch_event_manager.h b/third_party/blink/renderer/core/input/touch_event_manager.h index 8843365..6075f79 100644 --- a/third_party/blink/renderer/core/input/touch_event_manager.h +++ b/third_party/blink/renderer/core/input/touch_event_manager.h
@@ -48,14 +48,6 @@ // Returns whether there is any touch on the screen. bool IsAnyTouchActive() const; - // Keeps track of attributes of the touch point in the - // |touch_points_attributes_| map and computes the effective touch-action - // value, after possibly performing a hit-test if the original hit test result - // was not inside capturing frame |touch_sequence_document_| for touch events. - void UpdateTouchAttributeMapsForPointerDown( - const WebPointerEvent&, - const event_handling_util::PointerEventTarget&); - private: // Class represending one touch point event with its coalesced events and // related attributes. @@ -83,6 +75,14 @@ Touch* CreateDomTouch(const TouchPointAttributes*, bool* known_target); void AllTouchesReleasedCleanup(); + // Keeps track of attributes of the touch point in the + // |touch_points_attributes_| map and does the hit-testing if the original hit + // test result was not inside capturing frame |touch_sequence_document_| for + // touch events. + void UpdateTouchAttributeMapsForPointerDown( + const WebPointerEvent&, + const event_handling_util::PointerEventTarget&); + // This is triggered either by VSync signal to send one touch event per frame // accumulating all move events or by discrete events pointerdown/up/cancel. WebInputEventResult DispatchTouchEventFromAccumulatdTouchPoints(); @@ -135,9 +135,6 @@ // action which is sent to the browser after handling each dispatched // 'touchstart' is the intersection of all the previously calculated effective // touch action values during the sequence. - // - // TODO(https://crbug.com/844493): This seems incomplete code, should be - // removed. absl::optional<TouchAction> delayed_effective_touch_action_; };
diff --git a/third_party/blink/renderer/core/inspector/dev_tools_host.cc b/third_party/blink/renderer/core/inspector/dev_tools_host.cc index f120ca33..16f4fe2 100644 --- a/third_party/blink/renderer/core/inspector/dev_tools_host.cc +++ b/third_party/blink/renderer/core/inspector/dev_tools_host.cc
@@ -122,19 +122,9 @@ void DevToolsHost::EvaluateScript(const String& expression) { if (ScriptForbiddenScope::IsScriptForbidden()) return; - ScriptState* script_state = ToScriptStateForMainWorld(frontend_frame_); - if (!script_state) - return; - ScriptState::Scope scope(script_state); - v8::MicrotasksScope microtasks(script_state->GetIsolate(), - v8::MicrotasksScope::kRunMicrotasks); - // `kDoNotSanitize` is used for internal scripts for keeping the existing - // behavior. - V8ScriptRunner::CompileAndRunInternalScript( - script_state->GetIsolate(), script_state, - *ClassicScript::CreateUnspecifiedScript( - expression, ScriptSourceLocationType::kInternal, - SanitizeScriptErrors::kDoNotSanitize)); + ClassicScript::CreateUnspecifiedScript(expression, + ScriptSourceLocationType::kInternal) + ->RunScriptOnScriptState(ToScriptStateForMainWorld(frontend_frame_)); } void DevToolsHost::DisconnectClient() {
diff --git a/third_party/blink/renderer/core/inspector/thread_debugger.cc b/third_party/blink/renderer/core/inspector/thread_debugger.cc index 0ab58e2..2f2023f 100644 --- a/third_party/blink/renderer/core/inspector/thread_debugger.cc +++ b/third_party/blink/renderer/core/inspector/thread_debugger.cc
@@ -9,6 +9,7 @@ #include "base/check.h" #include "base/rand_util.h" #include "third_party/blink/public/mojom/frame/user_activation_notification_type.mojom-blink.h" +#include "third_party/blink/renderer/bindings/core/v8/script_evaluation_result.h" #include "third_party/blink/renderer/bindings/core/v8/source_location.h" #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h" #include "third_party/blink/renderer/bindings/core/v8/v8_blob.h" @@ -516,18 +517,22 @@ "function getAccessibleRole(node) { [Command Line API] }", v8::SideEffectType::kHasNoSideEffect); - v8::Local<v8::Value> function_value; - // `kDoNotSanitize` is used for internal scripts for keeping the existing - // behavior. - bool success = V8ScriptRunner::CompileAndRunInternalScript( - isolate_, ScriptState::From(context), - *ClassicScript::CreateUnspecifiedScript( - "(function(e) { console.log(e.type, e); })", - ScriptSourceLocationType::kInternal, - SanitizeScriptErrors::kDoNotSanitize)) - .ToLocal(&function_value) && - function_value->IsFunction(); - DCHECK(success); + ScriptEvaluationResult result = + ClassicScript::CreateUnspecifiedScript( + "(function(e) { console.log(e.type, e); })", + ScriptSourceLocationType::kInternal) + ->RunScriptOnScriptStateAndReturnValue(ScriptState::From(context)); + if (result.GetResultType() != ScriptEvaluationResult::ResultType::kSuccess) { + // On pages where scripting is disabled or CSP sandbox directive is used, + // this can be blocked and thus early exited here. + // This is probably OK because `monitorEvents()` console API is anyway not + // working on such pages. For more discussion see + // https://crrev.com/c/3258735/9/third_party/blink/renderer/core/inspector/thread_debugger.cc#529 + return; + } + + v8::Local<v8::Value> function_value = result.GetSuccessValue(); + DCHECK(function_value->IsFunction()); CreateFunctionPropertyWithData( context, object, "monitorEvents", ThreadDebugger::MonitorEventsCallback, function_value,
diff --git a/third_party/blink/renderer/core/layout/ng/ng_ink_overflow.cc b/third_party/blink/renderer/core/layout/ng/ng_ink_overflow.cc index c577509..298373a 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_ink_overflow.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_ink_overflow.cc
@@ -554,16 +554,7 @@ float resolved_thickness = decoration_info.ResolvedThickness(); if (has_underline) { - // Don't apply text-underline-offset to overline. - Length line_offset = - flip_underline_and_overline ? Length() : decoration.UnderlineOffset(); - - const int paint_underline_offset = - decoration_offset.ComputeUnderlineOffset( - underline_position, decoration_info.Style().ComputedFontSize(), - decoration_info.FontData(), line_offset, resolved_thickness); - decoration_info.SetLineData(TextDecorationLine::kUnderline, - paint_underline_offset); + decoration_info.SetUnderlineLineData(decoration, decoration_offset); accumulated_bound.Union(decoration_info.Bounds()); } if (has_overline) {
diff --git a/third_party/blink/renderer/core/loader/anchor_element_interaction_test.cc b/third_party/blink/renderer/core/loader/anchor_element_interaction_test.cc index 29526fd4..ba251cd 100644 --- a/third_party/blink/renderer/core/loader/anchor_element_interaction_test.cc +++ b/third_party/blink/renderer/core/loader/anchor_element_interaction_test.cc
@@ -11,6 +11,7 @@ #include "third_party/blink/public/common/input/web_mouse_event.h" #include "third_party/blink/public/mojom/loader/anchor_element_interaction_host.mojom-blink.h" #include "third_party/blink/renderer/core/dom/element.h" +#include "third_party/blink/renderer/core/execution_context/execution_context.h" #include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/core/html/html_anchor_element.h" #include "third_party/blink/renderer/core/input/event_handler.h" @@ -219,4 +220,34 @@ EXPECT_EQ(expected_url, url_received); } +TEST_F(AnchorElementInteractionTest, DestroyedContext) { + String source("https://example.com/p1"); + SimRequest main_resource(source, "text/html"); + LoadURL(source); + main_resource.Complete(R"HTML( + <a href='https://anchor1.com/'> + <div style='padding: 0px; width: 400px; height: 400px;'></div> + </a> + )HTML"); + + // Make sure getting pointer events after the execution context has been + // destroyed but before the document has been destroyed doesn't cause a crash. + GetDocument().GetExecutionContext()->NotifyContextDestroyed(); + WebPointerEvent event( + WebInputEvent::Type::kPointerDown, + WebPointerProperties(1, WebPointerProperties::PointerType::kTouch, + WebPointerProperties::Button::kLeft, + gfx::PointF(100, 100), gfx::PointF(100, 100)), + 1, 1); + GetDocument().GetFrame()->GetEventHandler().HandlePointerEvent( + event, Vector<WebPointerEvent>(), Vector<WebPointerEvent>()); + GetDocument().GetFrame()->GetEventHandler().DispatchBufferedTouchEvents(); + + base::RunLoop().RunUntilIdle(); + KURL expected_url = KURL("https://anchor1.com/"); + EXPECT_EQ(1u, hosts_.size()); + absl::optional<KURL> url_received = hosts_[0]->url_received_; + EXPECT_FALSE(url_received.has_value()); +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/loader/anchor_element_interaction_tracker.cc b/third_party/blink/renderer/core/loader/anchor_element_interaction_tracker.cc index d1ff5a2a..2c3c73c 100644 --- a/third_party/blink/renderer/core/loader/anchor_element_interaction_tracker.cc +++ b/third_party/blink/renderer/core/loader/anchor_element_interaction_tracker.cc
@@ -58,6 +58,13 @@ if (url.IsEmpty()) { return; } + + // interaction_host_ might become unbound: Android's low memory detector + // sometimes call NotifyContextDestroyed to save memory. This unbinds mojo + // pipes using that ExecutionContext even if those pages can still navigate. + if (!interaction_host_.is_bound()) { + return; + } interaction_host_->OnPointerDown(url); }
diff --git a/third_party/blink/renderer/core/navigation_api/navigation_api.cc b/third_party/blink/renderer/core/navigation_api/navigation_api.cc index 72ae9db..254977e 100644 --- a/third_party/blink/renderer/core/navigation_api/navigation_api.cc +++ b/third_party/blink/renderer/core/navigation_api/navigation_api.cc
@@ -340,7 +340,7 @@ return MakeGarbageCollected<NavigationHistoryEntry>( GetSupplementable(), entry->key, entry->id, KURL(entry->url), entry->document_sequence_number, - SerializedScriptValue::Create(entry->state)); + entry->state ? SerializedScriptValue::Create(entry->state) : nullptr); } // static
diff --git a/third_party/blink/renderer/core/navigation_api/navigation_history_entry.cc b/third_party/blink/renderer/core/navigation_api/navigation_history_entry.cc index 29341520..b1ce616 100644 --- a/third_party/blink/renderer/core/navigation_api/navigation_history_entry.cc +++ b/third_party/blink/renderer/core/navigation_api/navigation_history_entry.cc
@@ -8,6 +8,7 @@ #include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h" #include "third_party/blink/renderer/core/event_target_names.h" #include "third_party/blink/renderer/core/frame/local_dom_window.h" +#include "third_party/blink/renderer/core/frame/local_frame_client.h" #include "third_party/blink/renderer/core/loader/document_loader.h" #include "third_party/blink/renderer/core/navigation_api/navigation_api.h" @@ -70,6 +71,12 @@ state_ = state; DomWindow()->document()->Loader()->GetHistoryItem()->SetNavigationApiState( state); + // Force the new state object to be synced to the browser process immediately. + // The state object needs to be available as soon as possible in case a + // new navigation commits soon, so that browser has the best chance of having + // the up-to-date state object when constructing the arrays of non-current + // NavigationHistoryEntries. + DomWindow()->GetFrame()->Client()->NotifyCurrentHistoryItemChanged(); } const AtomicString& NavigationHistoryEntry::InterfaceName() const {
diff --git a/third_party/blink/renderer/core/paint/ng/ng_table_painters.cc b/third_party/blink/renderer/core/paint/ng/ng_table_painters.cc index dbe7c34..f67aaf3 100644 --- a/third_party/blink/renderer/core/paint/ng/ng_table_painters.cc +++ b/third_party/blink/renderer/core/paint/ng/ng_table_painters.cc
@@ -203,6 +203,9 @@ return NGTableCollapsedEdge(*this, borders_.EdgesPerRow()); } } + NGTableCollapsedEdge EmptyEdge() const { + return NGTableCollapsedEdge(borders_, UINT_MAX); + } NGTableCollapsedEdge& operator++() { DCHECK_NE(edge_index_, UINT_MAX); @@ -241,6 +244,8 @@ // Examined edge should shrink/expand its size to fill the joints. void ComputeEdgeJoints(const NGTableBorders& collapsed_borders, const NGTableCollapsedEdge& edge, + bool is_over_edge_fragmentation_boundary, + bool is_under_edge_fragmentation_boundary, LogicalSize& start_joint, LogicalSize& end_joint, bool& start_wins, @@ -261,13 +266,23 @@ // Find winner for the start of the inline edge. NGTableCollapsedEdge before_edge = edge.EdgeBeforeStartIntersection(); NGTableCollapsedEdge after_edge = edge.EdgeAfterStartIntersection(); - NGTableCollapsedEdge over_edge = edge.EdgeOverStartIntersection(); - NGTableCollapsedEdge under_edge = edge.EdgeUnderStartIntersection(); + NGTableCollapsedEdge over_edge = is_over_edge_fragmentation_boundary + ? edge.EmptyEdge() + : edge.EdgeOverStartIntersection(); + NGTableCollapsedEdge under_edge = + is_under_edge_fragmentation_boundary && edge.IsInlineAxis() + ? edge.EmptyEdge() + : edge.EdgeUnderStartIntersection(); int inline_compare = NGTableCollapsedEdge::CompareForPaint(before_edge, after_edge); start_joint.block_size = inline_compare == 1 ? before_edge.BorderWidth() : after_edge.BorderWidth(); + if (is_over_edge_fragmentation_boundary || + (is_under_edge_fragmentation_boundary && edge.IsInlineAxis())) { + start_joint.block_size = LayoutUnit(); + } + // Compare over and under edges. int block_compare = NGTableCollapsedEdge::CompareForPaint(over_edge, under_edge); @@ -287,13 +302,21 @@ // Find the winner for the end joint of the inline edge. before_edge = edge.EdgeBeforeEndIntersection(); after_edge = edge.EdgeAfterEndIntersection(); - over_edge = edge.EdgeOverEndIntersection(); - under_edge = edge.EdgeUnderEndIntersection(); + over_edge = is_over_edge_fragmentation_boundary && edge.IsInlineAxis() + ? edge.EmptyEdge() + : edge.EdgeOverEndIntersection(); + under_edge = is_under_edge_fragmentation_boundary + ? edge.EmptyEdge() + : edge.EdgeUnderEndIntersection(); inline_compare = NGTableCollapsedEdge::CompareForPaint(before_edge, after_edge); end_joint.block_size = inline_compare == 1 ? before_edge.BorderWidth() : after_edge.BorderWidth(); + if ((is_over_edge_fragmentation_boundary && edge.IsInlineAxis()) || + is_under_edge_fragmentation_boundary) { + end_joint.block_size = LayoutUnit(); + } block_compare = NGTableCollapsedEdge::CompareForPaint(over_edge, under_edge); end_joint.inline_size = @@ -437,7 +460,27 @@ namespace { -bool IsFirstRowFragmented(const NGPhysicalBoxFragment& section) { +const NGPhysicalFragment* StartSection(const NGPhysicalBoxFragment& table) { + for (const auto& child : table.Children()) { + if (!child->IsTableNGSection()) + continue; + return child.get(); + } + return nullptr; +} + +const NGPhysicalFragment* EndSection(const NGPhysicalBoxFragment& table) { + const auto children = table.Children(); + for (auto it = children.rbegin(); it != children.rend(); ++it) { + const auto& child = *it; + if (!child->IsTableNGSection()) + continue; + return child.get(); + } + return nullptr; +} + +bool IsStartRowFragmented(const NGPhysicalBoxFragment& section) { for (const auto& child : section.Children()) { if (!child->IsTableNGRow()) continue; @@ -446,7 +489,7 @@ return false; } -bool IsLastRowFragmented(const NGPhysicalBoxFragment& section) { +bool IsEndRowFragmented(const NGPhysicalBoxFragment& section) { const auto children = section.Children(); for (auto it = children.rbegin(); it != children.rend(); ++it) { const auto& child = *it; @@ -480,6 +523,13 @@ AutoDarkMode auto_dark_mode(PaintAutoDarkMode( fragment_.Style(), DarkModeFilter::ElementRole::kBackground)); + const wtf_size_t edges_per_row = collapsed_borders->EdgesPerRow(); + const wtf_size_t total_row_count = + collapsed_borders->EdgeCount() / edges_per_row; + + const auto* start_section = StartSection(fragment_); + const auto* end_section = EndSection(fragment_); + // We paint collapsed-borders section-by-section for fragmentation purposes. // This means that we need to track the final row we've painted in each // section to avoid double painting. @@ -495,16 +545,26 @@ if (!section_start_row_index) continue; - bool is_first_row_fragmented = IsFirstRowFragmented(section); - bool is_last_row_fragmented = IsLastRowFragmented(section); + const auto& section_row_offsets = *section.TableSectionRowOffsets(); + const wtf_size_t start_edge_index = + *section_start_row_index * edges_per_row; + + // Determine if we have (table) content in the next/previous fragmentainer. + // We'll use this information to paint "half" borders if required. + bool has_content_in_previous_fragmentainer = + (start_section == §ion) && (*section_start_row_index > 0u); + bool has_content_in_next_fragmentainer = + (end_section == §ion) && + (*section_start_row_index + section_row_offsets.size() < + total_row_count); + + // If our row was fragmented we skip painting the borders at that edge. + bool is_start_row_fragmented = IsStartRowFragmented(section); + bool is_end_row_fragmented = IsEndRowFragmented(section); WritingModeConverter converter(fragment_.Style().GetWritingDirection(), section.Size()); - const auto& section_row_offsets = *section.TableSectionRowOffsets(); - const wtf_size_t start_edge_index = - *section_start_row_index * collapsed_borders->EdgesPerRow(); - for (NGTableCollapsedEdge edge = NGTableCollapsedEdge(*collapsed_borders, start_edge_index); edge.Exists(); ++edge) { @@ -523,8 +583,10 @@ if (!edge.CanPaint()) continue; - bool is_row_start_fragmented = - is_first_row_fragmented && fragment_table_row == 0u; + bool is_start_row = fragment_table_row == 0u; + bool is_start_fragmented = is_start_row && is_start_row_fragmented; + bool is_start_at_fragmentation_boundary = + is_start_row && has_content_in_previous_fragmentainer; const LayoutUnit row_start_offset = section_row_offsets[fragment_table_row]; @@ -550,25 +612,34 @@ continue; } - bool is_row_end_fragmented = - is_last_row_fragmented && - fragment_table_row == section_row_offsets.size() - 1u; + bool is_end_row = fragment_table_row == section_row_offsets.size() - 1u; + bool is_end_fragmented = is_end_row && is_end_row_fragmented; + bool is_end_at_fragmentation_boundary = + is_end_row && has_content_in_next_fragmentainer; // If the current row has been fragmented, omit the inline border. - if (is_row_start_fragmented || is_row_end_fragmented) + if (is_start_fragmented || is_end_fragmented) continue; inline_start = column_start_offset; inline_size = collapsed_borders_geometry->columns[table_column + 1] - column_start_offset; - block_size = edge.BorderWidth(); - block_start = row_start_offset - edge.BorderWidth() / 2; + block_start = is_start_at_fragmentation_boundary + ? row_start_offset + : row_start_offset - edge.BorderWidth() / 2; + block_size = is_start_at_fragmentation_boundary || + is_end_at_fragmentation_boundary + ? edge.BorderWidth() / 2 + : edge.BorderWidth(); + LogicalSize start_joint; LogicalSize end_joint; bool start_wins; bool end_wins; - ComputeEdgeJoints(*collapsed_borders, edge, start_joint, end_joint, - start_wins, end_wins); + ComputeEdgeJoints(*collapsed_borders, edge, + is_start_at_fragmentation_boundary, + is_end_at_fragmentation_boundary, start_joint, + end_joint, start_wins, end_wins); if (start_wins) { inline_start -= start_joint.inline_size / 2; inline_size += start_joint.inline_size / 2; @@ -586,22 +657,27 @@ if (fragment_table_row + 1 >= section_row_offsets.size()) continue; - bool is_row_end_fragmented = - is_last_row_fragmented && + bool is_end_row = fragment_table_row + 1u == section_row_offsets.size() - 1u; + bool is_end_fragmented = is_end_row && is_end_row_fragmented; + bool is_end_at_fragmentation_boundary = + is_end_row && has_content_in_next_fragmentainer; block_start = row_start_offset; block_size = section_row_offsets[fragment_table_row + 1] - row_start_offset; inline_start = column_start_offset - edge.BorderWidth() / 2; inline_size = edge.BorderWidth(); + LogicalSize start_joint; LogicalSize end_joint; bool start_wins; bool end_wins; - ComputeEdgeJoints(*collapsed_borders, edge, start_joint, end_joint, - start_wins, end_wins); - if (is_row_start_fragmented) { + ComputeEdgeJoints(*collapsed_borders, edge, + is_start_at_fragmentation_boundary, + is_end_at_fragmentation_boundary, start_joint, + end_joint, start_wins, end_wins); + if (is_start_fragmented) { // We don't need to perform any adjustment if we've been start // fragmented as there isn't a joint here. } else if (start_wins) { @@ -611,7 +687,7 @@ block_start += start_joint.block_size / 2; block_size -= start_joint.block_size / 2; } - if (is_row_end_fragmented) { + if (is_end_fragmented) { // We don't need to perform any adjustment if we've been end // fragmented as there isn't a joint here. } else if (end_wins) {
diff --git a/third_party/blink/renderer/core/paint/text_decoration_info.cc b/third_party/blink/renderer/core/paint/text_decoration_info.cc index e488be68..a9322ea 100644 --- a/third_party/blink/renderer/core/paint/text_decoration_info.cc +++ b/third_party/blink/renderer/core/paint/text_decoration_info.cc
@@ -2,8 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "build/build_config.h" #include "third_party/blink/renderer/core/paint/text_decoration_info.h" + +#include "build/build_config.h" +#include "third_party/blink/renderer/core/layout/text_decoration_offset_base.h" #include "third_party/blink/renderer/core/paint/text_paint_style.h" #include "third_party/blink/renderer/core/style/computed_style.h" #include "third_party/blink/renderer/platform/geometry/length_functions.h" @@ -214,6 +216,23 @@ } } +void TextDecorationInfo::SetUnderlineLineData( + const AppliedTextDecoration& decoration, + const TextDecorationOffsetBase& decoration_offset) { + ResolvedUnderlinePosition underline_position = UnderlinePosition(); + Length line_offset; + if (UNLIKELY(underline_position == ResolvedUnderlinePosition::kOver)) { + // Don't apply text-underline-offset to overlines. |line_offset| is zero. + underline_position = ResolvedUnderlinePosition::kUnder; + } else { + line_offset = decoration.UnderlineOffset(); + } + const int paint_underline_offset = decoration_offset.ComputeUnderlineOffset( + underline_position, ComputedFontSize(), FontData(), line_offset, + ResolvedThickness()); + SetLineData(TextDecorationLine::kUnderline, paint_underline_offset); +} + ETextDecorationStyle TextDecorationInfo::DecorationStyle() const { if (IsSpellingOrGrammarError()) { #if BUILDFLAG(IS_MAC)
diff --git a/third_party/blink/renderer/core/paint/text_decoration_info.h b/third_party/blink/renderer/core/paint/text_decoration_info.h index add088c4..245a064 100644 --- a/third_party/blink/renderer/core/paint/text_decoration_info.h +++ b/third_party/blink/renderer/core/paint/text_decoration_info.h
@@ -24,6 +24,7 @@ class ComputedStyle; class Font; class SimpleFontData; +class TextDecorationOffsetBase; enum class ResolvedUnderlinePosition { kNearAlphabeticBaselineAuto, @@ -65,6 +66,8 @@ // through. Must be called before trying to paint or compute bounds // for a line. void SetLineData(TextDecorationLine line, float line_offset); + void SetUnderlineLineData(const AppliedTextDecoration& decoration, + const TextDecorationOffsetBase& decoration_offset); // These methods do not depend on SetDecorationIndex LayoutUnit Width() const { return width_; }
diff --git a/third_party/blink/renderer/core/paint/text_painter_base.cc b/third_party/blink/renderer/core/paint/text_painter_base.cc index e48bcd3..2f6ddb8b 100644 --- a/third_party/blink/renderer/core/paint/text_painter_base.cc +++ b/third_party/blink/renderer/core/paint/text_painter_base.cc
@@ -257,7 +257,7 @@ decoration_info.SetDecorationIndex(applied_decoration_index); - float resolved_thickness = decoration_info.ResolvedThickness(); + const float resolved_thickness = decoration_info.ResolvedThickness(); context.SetStrokeThickness(resolved_thickness); if (is_spelling_error || is_grammar_error) { @@ -280,16 +280,7 @@ } if (has_underline && decoration_info.FontData()) { - // Don't apply text-underline-offset to overline. - Length line_offset = - flip_underline_and_overline ? Length() : decoration.UnderlineOffset(); - - const int paint_underline_offset = - decoration_offset.ComputeUnderlineOffset( - underline_position, decoration_info.ComputedFontSize(), - decoration_info.FontData(), line_offset, resolved_thickness); - decoration_info.SetLineData(TextDecorationLine::kUnderline, - paint_underline_offset); + decoration_info.SetUnderlineLineData(decoration, decoration_offset); PaintDecorationUnderOrOverLine(context, decoration_info, TextDecorationLine::kUnderline, flags); }
diff --git a/third_party/blink/renderer/modules/accessibility/ax_node_object.cc b/third_party/blink/renderer/modules/accessibility/ax_node_object.cc index 33ea700..6f2ef23 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_node_object.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_node_object.cc
@@ -69,6 +69,7 @@ #include "third_party/blink/renderer/core/html/fenced_frame/html_fenced_frame_element.h" #include "third_party/blink/renderer/core/html/forms/html_button_element.h" #include "third_party/blink/renderer/core/html/forms/html_field_set_element.h" +#include "third_party/blink/renderer/core/html/forms/html_form_control_element.h" #include "third_party/blink/renderer/core/html/forms/html_input_element.h" #include "third_party/blink/renderer/core/html/forms/html_label_element.h" #include "third_party/blink/renderer/core/html/forms/html_legend_element.h" @@ -1837,12 +1838,11 @@ : kExpandedCollapsed; } - // For buttons that contain the |togglepopup|, |showpopup|, or |hidepopup| - // popup triggering attributes, and the pointed-to element is a valid popup - // with type kPopup, then set aria-expanded=false when the popup is hidden, - // and aria-expanded=true when it is showing. - if (auto* button = DynamicTo<HTMLButtonElement>(element)) { - if (auto popup = button->togglePopupElement().element; + // For form controls that act as triggering elements for popups of type + // kPopup, then set aria-expanded=false when the popup is hidden, and + // aria-expanded=true when it is showing. + if (auto* form_control = DynamicTo<HTMLFormControlElement>(element)) { + if (auto popup = form_control->togglePopupElement().element; popup && popup->PopupType() == PopupValueType::kPopup) { return popup->popupOpen() ? kExpandedExpanded : kExpandedCollapsed; } @@ -5600,11 +5600,10 @@ } } - // For buttons that contain the |togglepopup|, |showpopup|, or |hidepopup| - // popup triggering attributes, and the pointed-to element is a valid popup - // with type kHint, then set aria-describedby to the hint popup. - if (auto* button = DynamicTo<HTMLButtonElement>(element)) { - auto popup = button->togglePopupElement(); + // For form controls that act as triggering elements for popups of type kHint, + // then set aria-describedby to the hint popup. + if (auto* form_control = DynamicTo<HTMLFormControlElement>(element)) { + auto popup = form_control->togglePopupElement(); if (popup.element && popup.element->PopupType() == PopupValueType::kHint) { description_from = ax::mojom::blink::DescriptionFrom::kPopupElement; if (description_sources) {
diff --git a/third_party/blink/renderer/modules/webaudio/analyser_handler.cc b/third_party/blink/renderer/modules/webaudio/analyser_handler.cc index b6eff793..7af7ae2 100644 --- a/third_party/blink/renderer/modules/webaudio/analyser_handler.cc +++ b/third_party/blink/renderer/modules/webaudio/analyser_handler.cc
@@ -12,12 +12,19 @@ namespace blink { +namespace { + +constexpr unsigned kDefaultNumberOfInputChannels = 2; +constexpr unsigned kDefaultNumberOfOutputChannels = 1; + +} // namespace + AnalyserHandler::AnalyserHandler(AudioNode& node, float sample_rate) : AudioBasicInspectorHandler(kNodeTypeAnalyser, node, sample_rate), analyser_( node.context()->GetDeferredTaskHandler().RenderQuantumFrames()) { - channel_count_ = 2; - AddOutput(1); + channel_count_ = kDefaultNumberOfInputChannels; + AddOutput(kDefaultNumberOfOutputChannels); Initialize(); }
diff --git a/third_party/blink/renderer/modules/webaudio/audio_basic_processor_handler.cc b/third_party/blink/renderer/modules/webaudio/audio_basic_processor_handler.cc index 3d1ec0b..a4196e5 100644 --- a/third_party/blink/renderer/modules/webaudio/audio_basic_processor_handler.cc +++ b/third_party/blink/renderer/modules/webaudio/audio_basic_processor_handler.cc
@@ -32,6 +32,12 @@ namespace blink { +namespace { + +constexpr unsigned kDefaultNumberOfOutputChannels = 1; + +} // namespace + AudioBasicProcessorHandler::AudioBasicProcessorHandler( NodeType node_type, AudioNode& node, @@ -40,7 +46,7 @@ : AudioHandler(node_type, node, sample_rate), processor_(std::move(processor)) { AddInput(); - AddOutput(1); + AddOutput(kDefaultNumberOfOutputChannels); } AudioBasicProcessorHandler::~AudioBasicProcessorHandler() {
diff --git a/third_party/blink/renderer/modules/webaudio/audio_basic_processor_handler_test.cc b/third_party/blink/renderer/modules/webaudio/audio_basic_processor_handler_test.cc index 8fc7bf34d..f7bee8e0 100644 --- a/third_party/blink/renderer/modules/webaudio/audio_basic_processor_handler_test.cc +++ b/third_party/blink/renderer/modules/webaudio/audio_basic_processor_handler_test.cc
@@ -15,8 +15,12 @@ namespace blink { +namespace { + // Rendering size for these tests. This is the WebAudio default rendering size. -const unsigned kRenderQuantumFrames = 128; +constexpr unsigned kRenderQuantumFrames = 128; + +} // namespace class MockAudioProcessor final : public AudioProcessor { public:
diff --git a/third_party/blink/renderer/modules/webaudio/audio_buffer_source_handler.cc b/third_party/blink/renderer/modules/webaudio/audio_buffer_source_handler.cc index e7a6f94..18f1931 100644 --- a/third_party/blink/renderer/modules/webaudio/audio_buffer_source_handler.cc +++ b/third_party/blink/renderer/modules/webaudio/audio_buffer_source_handler.cc
@@ -21,12 +21,20 @@ namespace blink { -const double kDefaultGrainDuration = 0.020; // 20ms +namespace { + +constexpr double kDefaultGrainDuration = 0.020; // 20ms // Arbitrary upper limit on playback rate. // Higher than expected rates can be useful when playing back oversampled // buffers to minimize linear interpolation aliasing. -const double kMaxRate = 1024; +constexpr double kMaxRate = 1024.0; + +// Default to mono. A call to setBuffer() will set the number of output +// channels to that of the buffer. +constexpr unsigned kDefaultNumberOfOutputChannels = 1; + +} // namespace AudioBufferSourceHandler::AudioBufferSourceHandler( AudioNode& node, @@ -39,9 +47,7 @@ playback_rate_(&playback_rate), detune_(&detune), grain_duration_(kDefaultGrainDuration) { - // Default to mono. A call to setBuffer() will set the number of output - // channels to that of the buffer. - AddOutput(1); + AddOutput(kDefaultNumberOfOutputChannels); Initialize(); }
diff --git a/third_party/blink/renderer/modules/webaudio/audio_buffer_source_node.cc b/third_party/blink/renderer/modules/webaudio/audio_buffer_source_node.cc index 81e525c..566168c 100644 --- a/third_party/blink/renderer/modules/webaudio/audio_buffer_source_node.cc +++ b/third_party/blink/renderer/modules/webaudio/audio_buffer_source_node.cc
@@ -42,20 +42,27 @@ namespace blink { +namespace { + +constexpr double kDefaultPlaybackRateValue = 1.0; +constexpr double kDefaultDetuneValue = 0.0; + +} // namespace + AudioBufferSourceNode::AudioBufferSourceNode(BaseAudioContext& context) : AudioScheduledSourceNode(context), playback_rate_(AudioParam::Create( context, Uuid(), AudioParamHandler::kParamTypeAudioBufferSourcePlaybackRate, - 1.0, + kDefaultPlaybackRateValue, AudioParamHandler::AutomationRate::kControl, AudioParamHandler::AutomationRateMode::kFixed)), detune_(AudioParam::Create( context, Uuid(), AudioParamHandler::kParamTypeAudioBufferSourceDetune, - 0.0, + kDefaultDetuneValue, AudioParamHandler::AutomationRate::kControl, AudioParamHandler::AutomationRateMode::kFixed)) { SetHandler(AudioBufferSourceHandler::Create(*this, context.sampleRate(),
diff --git a/third_party/blink/renderer/modules/webaudio/audio_context.cc b/third_party/blink/renderer/modules/webaudio/audio_context.cc index 138289a..cfed8b2 100644 --- a/third_party/blink/renderer/modules/webaudio/audio_context.cc +++ b/third_party/blink/renderer/modules/webaudio/audio_context.cc
@@ -47,15 +47,15 @@ namespace blink { +namespace { + // Number of AudioContexts still alive. It's incremented when an // AudioContext is created and decremented when the context is closed. -static unsigned g_hardware_context_count = 0; +unsigned hardware_context_count = 0; // A context ID that is incremented for each context that is created. // This initializes the internal id for the context. -static unsigned g_context_id = 0; - -namespace { +unsigned context_id = 0; // When the client does not have enough permission, the outputLatency property // is quantized by 8ms to reduce the precision for privacy concerns. @@ -96,7 +96,7 @@ return builder.ToString(); } -static bool IsAudible(const AudioBus* rendered_data) { +bool IsAudible(const AudioBus* rendered_data) { // Compute the energy in each channel and sum up the energy in each channel // for the total energy. float energy = 0; @@ -174,7 +174,7 @@ SCOPED_UMA_HISTOGRAM_TIMER("WebAudio.AudioContext.CreateTime"); AudioContext* audio_context = MakeGarbageCollected<AudioContext>(document, latency_hint, sample_rate); - ++g_hardware_context_count; + ++hardware_context_count; audio_context->UpdateStateIfNeeded(); // This starts the audio thread. The destination node's @@ -192,7 +192,7 @@ } #if DEBUG_AUDIONODE_REFERENCES fprintf(stderr, "[%16p]: AudioContext::AudioContext(): %u #%u\n", - audio_context, audio_context->context_id_, g_hardware_context_count); + audio_context, audio_context->context_id_, hardware_context_count); #endif base::UmaHistogramSparse("WebAudio.AudioContext.MaxChannelsAvailable", @@ -207,7 +207,7 @@ const WebAudioLatencyHint& latency_hint, absl::optional<float> sample_rate) : BaseAudioContext(&document, kRealtimeContext), - context_id_(g_context_id++), + context_id_(context_id++), audio_context_manager_(document.GetExecutionContext()), permission_service_(document.GetExecutionContext()), permission_receiver_(this, document.GetExecutionContext()) { @@ -271,9 +271,9 @@ void AudioContext::Uninitialize() { DCHECK(IsMainThread()); - DCHECK_NE(g_hardware_context_count, 0u); + DCHECK_NE(hardware_context_count, 0u); SendLogMessage(String::Format("%s", __func__)); - --g_hardware_context_count; + --hardware_context_count; StopRendering(); DidClose(); RecordAutoplayMetrics();
diff --git a/third_party/blink/renderer/modules/webaudio/audio_context_autoplay_test.cc b/third_party/blink/renderer/modules/webaudio/audio_context_autoplay_test.cc index be2d93fd..61675c9 100644 --- a/third_party/blink/renderer/modules/webaudio/audio_context_autoplay_test.cc +++ b/third_party/blink/renderer/modules/webaudio/audio_context_autoplay_test.cc
@@ -67,7 +67,7 @@ size_t AudioHardwareBufferSize() override { return 128; } }; -} // anonymous namespace +} // namespace class AudioContextAutoplayTest : public testing::TestWithParam<AutoplayPolicy::Type> {
diff --git a/third_party/blink/renderer/modules/webaudio/audio_context_test.cc b/third_party/blink/renderer/modules/webaudio/audio_context_test.cc index ee486ca..3560c7c 100644 --- a/third_party/blink/renderer/modules/webaudio/audio_context_test.cc +++ b/third_party/blink/renderer/modules/webaudio/audio_context_test.cc
@@ -23,7 +23,8 @@ namespace blink { namespace { -static bool web_audio_device_paused_; + +bool web_audio_device_paused_; class MockWebAudioDeviceForAudioContext : public WebAudioDevice { public: @@ -85,7 +86,7 @@ size_t AudioHardwareBufferSize() override { return 128; } }; -} // anonymous namespace +} // namespace class AudioContextTest : public PageTestBase { protected:
diff --git a/third_party/blink/renderer/modules/webaudio/audio_listener.cc b/third_party/blink/renderer/modules/webaudio/audio_listener.cc index 7aefa197..dfefe90 100644 --- a/third_party/blink/renderer/modules/webaudio/audio_listener.cc +++ b/third_party/blink/renderer/modules/webaudio/audio_listener.cc
@@ -36,69 +36,83 @@ namespace blink { +namespace { + +constexpr double kDefaultPositionXValue = 0.0; +constexpr double kDefaultPositionYValue = 0.0; +constexpr double kDefaultPositionZValue = 0.0; +constexpr double kDefaultForwardXValue = 0.0; +constexpr double kDefaultForwardYValue = 0.0; +constexpr double kDefaultForwardZValue = -1.0; +constexpr double kDefaultUpXValue = 0.0; +constexpr double kDefaultUpYValue = 1.0; +constexpr double kDefaultUpZValue = 0.0; + +} // namespace + AudioListener::AudioListener(BaseAudioContext& context) : InspectorHelperMixin(context.GraphTracer(), context.Uuid()), position_x_(AudioParam::Create( context, Uuid(), AudioParamHandler::kParamTypeAudioListenerPositionX, - 0.0, + kDefaultPositionXValue, AudioParamHandler::AutomationRate::kAudio, AudioParamHandler::AutomationRateMode::kVariable)), position_y_(AudioParam::Create( context, Uuid(), AudioParamHandler::kParamTypeAudioListenerPositionY, - 0.0, + kDefaultPositionYValue, AudioParamHandler::AutomationRate::kAudio, AudioParamHandler::AutomationRateMode::kVariable)), position_z_(AudioParam::Create( context, Uuid(), AudioParamHandler::kParamTypeAudioListenerPositionZ, - 0.0, + kDefaultPositionZValue, AudioParamHandler::AutomationRate::kAudio, AudioParamHandler::AutomationRateMode::kVariable)), forward_x_( AudioParam::Create(context, Uuid(), AudioParamHandler::kParamTypeAudioListenerForwardX, - 0.0, + kDefaultForwardXValue, AudioParamHandler::AutomationRate::kAudio, AudioParamHandler::AutomationRateMode::kVariable)), forward_y_( AudioParam::Create(context, Uuid(), AudioParamHandler::kParamTypeAudioListenerForwardY, - 0.0, + kDefaultForwardYValue, AudioParamHandler::AutomationRate::kAudio, AudioParamHandler::AutomationRateMode::kVariable)), forward_z_( AudioParam::Create(context, Uuid(), AudioParamHandler::kParamTypeAudioListenerForwardZ, - -1.0, + kDefaultForwardZValue, AudioParamHandler::AutomationRate::kAudio, AudioParamHandler::AutomationRateMode::kVariable)), up_x_( AudioParam::Create(context, Uuid(), AudioParamHandler::kParamTypeAudioListenerUpX, - 0.0, + kDefaultUpXValue, AudioParamHandler::AutomationRate::kAudio, AudioParamHandler::AutomationRateMode::kVariable)), up_y_( AudioParam::Create(context, Uuid(), AudioParamHandler::kParamTypeAudioListenerUpY, - 1.0, + kDefaultUpYValue, AudioParamHandler::AutomationRate::kAudio, AudioParamHandler::AutomationRateMode::kVariable)), up_z_( AudioParam::Create(context, Uuid(), AudioParamHandler::kParamTypeAudioListenerUpZ, - 0.0, + kDefaultUpZValue, AudioParamHandler::AutomationRate::kAudio, AudioParamHandler::AutomationRateMode::kVariable)), position_x_values_(
diff --git a/third_party/blink/renderer/modules/webaudio/audio_param_handler.cc b/third_party/blink/renderer/modules/webaudio/audio_param_handler.cc index de057de..6c931b88 100644 --- a/third_party/blink/renderer/modules/webaudio/audio_param_handler.cc +++ b/third_party/blink/renderer/modules/webaudio/audio_param_handler.cc
@@ -24,13 +24,15 @@ namespace blink { -const double AudioParamHandler::kDefaultSmoothingConstant = 0.05; -const double AudioParamHandler::kSnapThreshold = 0.001; +namespace { + +constexpr double kDefaultSmoothingConstant = 0.05; +constexpr double kSnapThreshold = 0.001; // Replace NaN values in `values` with `default_value`. -static void HandleNaNValues(float* values, - unsigned number_of_values, - float default_value) { +void HandleNaNValues(float* values, + unsigned number_of_values, + float default_value) { unsigned k = 0; #if defined(ARCH_CPU_X86_FAMILY) if (number_of_values >= 4) { @@ -72,6 +74,8 @@ } } +} // namespace + AudioParamHandler::AudioParamHandler(BaseAudioContext& context, AudioParamType param_type, double default_value,
diff --git a/third_party/blink/renderer/modules/webaudio/audio_param_handler.h b/third_party/blink/renderer/modules/webaudio/audio_param_handler.h index a866fc6..e9c2bb0 100644 --- a/third_party/blink/renderer/modules/webaudio/audio_param_handler.h +++ b/third_party/blink/renderer/modules/webaudio/audio_param_handler.h
@@ -98,9 +98,6 @@ // Return a nice name for the AudioParam. String GetParamName() const; - static const double kDefaultSmoothingConstant; - static const double kSnapThreshold; - static scoped_refptr<AudioParamHandler> Create(BaseAudioContext& context, AudioParamType param_type, double default_value,
diff --git a/third_party/blink/renderer/modules/webaudio/audio_param_timeline.cc b/third_party/blink/renderer/modules/webaudio/audio_param_timeline.cc index 9e336c0..a873c2b1 100644 --- a/third_party/blink/renderer/modules/webaudio/audio_param_timeline.cc +++ b/third_party/blink/renderer/modules/webaudio/audio_param_timeline.cc
@@ -47,16 +47,18 @@ namespace blink { -// For a SetTarget event, we want the event to terminate eventually so that -// we can stop using the timeline to compute the values. See +namespace { + +// For a SetTarget event, we want the event to terminate eventually so that we +// can stop using the timeline to compute the values. See // `HasSetTargetConverged()` for the algorithm. `kSetTargetThreshold` is // exp(-`kTimeConstantsToConverge`). -const float kTimeConstantsToConverge = 10; -const float kSetTargetThreshold = 4.539992976248485e-05; +constexpr float kTimeConstantsToConverge = 10.0f; +constexpr float kSetTargetThreshold = 4.539992976248485e-05f; -static bool IsNonNegativeAudioParamTime(double time, - ExceptionState& exception_state, - String message = "Time") { +bool IsNonNegativeAudioParamTime(double time, + ExceptionState& exception_state, + String message = "Time") { if (time >= 0) { return true; } @@ -67,9 +69,9 @@ return false; } -static bool IsPositiveAudioParamTime(double time, - ExceptionState& exception_state, - String message) { +bool IsPositiveAudioParamTime(double time, + ExceptionState& exception_state, + String message) { if (time > 0) { return true; } @@ -82,11 +84,11 @@ // Test that for a SetTarget event, the current value is close enough // to the target value that we can consider the event to have // converged to the target. -static bool HasSetTargetConverged(float value, - float target, - double current_time, - double start_time, - double time_constant) { +bool HasSetTargetConverged(float value, + float target, + double current_time, + double start_time, + double time_constant) { // Converged if enough time constants (`kTimeConstantsToConverge`) have passed // since the start of the event. if (current_time > start_time + kTimeConstantsToConverge * time_constant) { @@ -109,6 +111,8 @@ return false; } +} // namespace + String AudioParamTimeline::EventToString(const ParamEvent& event) const { // The default arguments for most automation methods is the value and the // time.
diff --git a/third_party/blink/renderer/modules/webaudio/audio_scheduled_source_handler.cc b/third_party/blink/renderer/modules/webaudio/audio_scheduled_source_handler.cc index c7c6e2c..0971963 100644 --- a/third_party/blink/renderer/modules/webaudio/audio_scheduled_source_handler.cc +++ b/third_party/blink/renderer/modules/webaudio/audio_scheduled_source_handler.cc
@@ -20,8 +20,6 @@ namespace blink { -const double AudioScheduledSourceHandler::kUnknownTime = -1; - AudioScheduledSourceHandler::AudioScheduledSourceHandler(NodeType node_type, AudioNode& node, float sample_rate)
diff --git a/third_party/blink/renderer/modules/webaudio/audio_scheduled_source_handler.h b/third_party/blink/renderer/modules/webaudio/audio_scheduled_source_handler.h index 710b4e1..1f40b83 100644 --- a/third_party/blink/renderer/modules/webaudio/audio_scheduled_source_handler.h +++ b/third_party/blink/renderer/modules/webaudio/audio_scheduled_source_handler.h
@@ -131,15 +131,13 @@ double end_time_; // in seconds // Magic value indicating that the time (start or end) has not yet been set. - static const double kUnknownTime; + static constexpr double kUnknownTime = -1.0; // Number of extra frames to use when determining if a source node can be // stopped. This should be at least one rendering quantum, but we add one // more quantum for good measure. This doesn't need to be extra precise, just // more than one rendering quantum. See `HandleStoppableSourceNode()`. - // FIXME: Expose the rendering quantum somehow instead of hardwiring a value - // here. - static const int kExtraStopFrames = 256; + static constexpr int kExtraStopFrames = 256; private: // This is accessed by both the main thread and audio thread. Use the setter
diff --git a/third_party/blink/renderer/modules/webaudio/audio_worklet_global_scope.h b/third_party/blink/renderer/modules/webaudio/audio_worklet_global_scope.h index fc6f2d4..95048d58 100644 --- a/third_party/blink/renderer/modules/webaudio/audio_worklet_global_scope.h +++ b/third_party/blink/renderer/modules/webaudio/audio_worklet_global_scope.h
@@ -128,7 +128,7 @@ std::unique_ptr<ProcessorCreationParams> processor_creation_params_; size_t current_frame_ = 0; - float sample_rate_ = 0.0; + float sample_rate_ = 0.0f; // Default initialized to generate a distinct token for this worklet. const AudioWorkletToken token_;
diff --git a/third_party/blink/renderer/modules/webaudio/audio_worklet_global_scope_test.cc b/third_party/blink/renderer/modules/webaudio/audio_worklet_global_scope_test.cc index c1e038d..f52ec6a 100644 --- a/third_party/blink/renderer/modules/webaudio/audio_worklet_global_scope_test.cc +++ b/third_party/blink/renderer/modules/webaudio/audio_worklet_global_scope_test.cc
@@ -51,7 +51,7 @@ namespace { -static const size_t kRenderQuantumFrames = 128; +constexpr size_t kRenderQuantumFrames = 128; } // namespace
diff --git a/third_party/blink/renderer/modules/webaudio/audio_worklet_handler.cc b/third_party/blink/renderer/modules/webaudio/audio_worklet_handler.cc index d5a91263..950a897 100644 --- a/third_party/blink/renderer/modules/webaudio/audio_worklet_handler.cc +++ b/third_party/blink/renderer/modules/webaudio/audio_worklet_handler.cc
@@ -33,6 +33,12 @@ namespace blink { +namespace { + +constexpr unsigned kDefaultNumberOfOutputChannels = 1; + +} // namespace + AudioWorkletHandler::AudioWorkletHandler( AudioNode& node, float sample_rate, @@ -63,7 +69,7 @@ for (unsigned i = 0; i < options->numberOfOutputs(); ++i) { // If `options->outputChannelCount` unspecified, all outputs are mono. AddOutput(is_output_channel_count_given_ ? options->outputChannelCount()[i] - : 1); + : kDefaultNumberOfOutputChannels); } // Same for the outputs as well. outputs_.ReserveInitialCapacity(options->numberOfOutputs());
diff --git a/third_party/blink/renderer/modules/webaudio/base_audio_context.h b/third_party/blink/renderer/modules/webaudio/base_audio_context.h index 2c7df9c..f813c1c 100644 --- a/third_party/blink/renderer/modules/webaudio/base_audio_context.h +++ b/third_party/blink/renderer/modules/webaudio/base_audio_context.h
@@ -390,7 +390,7 @@ private: // This is considering 32 is large enough for multiple channels audio. // It is somewhat arbitrary and could be increased if necessary. - enum { kMaxNumberOfChannels = 32 }; + static constexpr uint32_t kMaxNumberOfChannels = 32; void Clear();
diff --git a/third_party/blink/renderer/modules/webaudio/biquad_dsp_kernel.cc b/third_party/blink/renderer/modules/webaudio/biquad_dsp_kernel.cc index b0995f47f..ffd599b 100644 --- a/third_party/blink/renderer/modules/webaudio/biquad_dsp_kernel.cc +++ b/third_party/blink/renderer/modules/webaudio/biquad_dsp_kernel.cc
@@ -31,7 +31,9 @@ namespace blink { -static bool hasConstantValues(float* values, int frames_to_process) { +namespace { + +bool HasConstantValues(float* values, int frames_to_process) { // TODO(rtoy): Use SIMD to optimize this. This would speed up // processing by a factor of 4 because we can process 4 floats at a // time. @@ -46,6 +48,8 @@ return true; } +} // namespace + void BiquadDSPKernel::UpdateCoefficientsIfNecessary(int frames_to_process) { if (GetBiquadProcessor()->FilterCoefficientsDirty()) { float cutoff_frequency[RenderQuantumFrames()]; @@ -72,10 +76,10 @@ // to compute filter coefficients for each frame since they would be the // same as the first. bool isConstant = - hasConstantValues(cutoff_frequency, frames_to_process) && - hasConstantValues(q, frames_to_process) && - hasConstantValues(gain, frames_to_process) && - hasConstantValues(detune, frames_to_process); + HasConstantValues(cutoff_frequency, frames_to_process) && + HasConstantValues(q, frames_to_process) && + HasConstantValues(gain, frames_to_process) && + HasConstantValues(detune, frames_to_process); UpdateCoefficients(isConstant ? 1 : frames_to_process, cutoff_frequency, q, gain, detune); @@ -154,7 +158,7 @@ // this, limit the maximum to this value so that we don't keep such // nodes alive "forever". // TODO: What is a reasonable upper limit? - const double kMaxTailTime = 30; + constexpr double kMaxTailTime = 30.0; double sample_rate = SampleRate(); double tail =
diff --git a/third_party/blink/renderer/modules/webaudio/biquad_filter_node.cc b/third_party/blink/renderer/modules/webaudio/biquad_filter_node.cc index f3937c2..79aff99 100644 --- a/third_party/blink/renderer/modules/webaudio/biquad_filter_node.cc +++ b/third_party/blink/renderer/modules/webaudio/biquad_filter_node.cc
@@ -36,40 +36,52 @@ namespace blink { +namespace { + +constexpr double kDefaultFrequencyValue = 350.0; +constexpr float kMinFrequencyValue = 0.0f; +constexpr double kDefaultQValue = 1.0; +constexpr double kDefaultGainValue = 0.0; +constexpr float kMinGainValue = std::numeric_limits<float>::lowest(); +constexpr double kDefaultDetuneValue = 0.0; + +} // namespace + BiquadFilterNode::BiquadFilterNode(BaseAudioContext& context) : AudioNode(context), frequency_( AudioParam::Create(context, Uuid(), AudioParamHandler::kParamTypeBiquadFilterFrequency, - 350.0, + kDefaultFrequencyValue, AudioParamHandler::AutomationRate::kAudio, AudioParamHandler::AutomationRateMode::kVariable, - 0, - context.sampleRate() / 2)), + kMinFrequencyValue, + /*max_value=*/context.sampleRate() / 2)), q_(AudioParam::Create(context, Uuid(), AudioParamHandler::kParamTypeBiquadFilterQ, - 1.0, + kDefaultQValue, AudioParamHandler::AutomationRate::kAudio, AudioParamHandler::AutomationRateMode::kVariable)), - gain_(AudioParam::Create(context, - Uuid(), - AudioParamHandler::kParamTypeBiquadFilterGain, - 0.0, - AudioParamHandler::AutomationRate::kAudio, - AudioParamHandler::AutomationRateMode::kVariable, - std::numeric_limits<float>::lowest(), - 40 * log10f(std::numeric_limits<float>::max()))), - detune_( - AudioParam::Create(context, - Uuid(), - AudioParamHandler::kParamTypeBiquadFilterDetune, - 0.0, - AudioParamHandler::AutomationRate::kAudio, - AudioParamHandler::AutomationRateMode::kVariable, - -1200 * log2f(std::numeric_limits<float>::max()), - 1200 * log2f(std::numeric_limits<float>::max()))) { + gain_(AudioParam::Create( + context, + Uuid(), + AudioParamHandler::kParamTypeBiquadFilterGain, + kDefaultGainValue, + AudioParamHandler::AutomationRate::kAudio, + AudioParamHandler::AutomationRateMode::kVariable, + kMinGainValue, + /*max_value=*/40 * log10f(std::numeric_limits<float>::max()))), + detune_(AudioParam::Create( + context, + Uuid(), + AudioParamHandler::kParamTypeBiquadFilterDetune, + kDefaultDetuneValue, + AudioParamHandler::AutomationRate::kAudio, + AudioParamHandler::AutomationRateMode::kVariable, + /*min_value=*/-1200 * log2f(std::numeric_limits<float>::max()), + /*max_value=*/1200 * log2f(std::numeric_limits<float>::max()))) { SetHandler(BiquadFilterHandler::Create(*this, context.sampleRate(), frequency_->Handler(), q_->Handler(), gain_->Handler(), detune_->Handler()));
diff --git a/third_party/blink/renderer/modules/webaudio/channel_merger_handler.cc b/third_party/blink/renderer/modules/webaudio/channel_merger_handler.cc index 4baad5ba..a23abd8 100644 --- a/third_party/blink/renderer/modules/webaudio/channel_merger_handler.cc +++ b/third_party/blink/renderer/modules/webaudio/channel_merger_handler.cc
@@ -11,12 +11,18 @@ namespace blink { +namespace { + +constexpr unsigned kNumberOfInputChannels = 1; + +} // namespace + ChannelMergerHandler::ChannelMergerHandler(AudioNode& node, float sample_rate, unsigned number_of_inputs) : AudioHandler(kNodeTypeChannelMerger, node, sample_rate) { // These properties are fixed for the node and cannot be changed by user. - channel_count_ = 1; + channel_count_ = kNumberOfInputChannels; SetInternalChannelCountMode(kExplicit); // Create the requested number of inputs.
diff --git a/third_party/blink/renderer/modules/webaudio/channel_merger_node.cc b/third_party/blink/renderer/modules/webaudio/channel_merger_node.cc index 740a789..885419d 100644 --- a/third_party/blink/renderer/modules/webaudio/channel_merger_node.cc +++ b/third_party/blink/renderer/modules/webaudio/channel_merger_node.cc
@@ -37,6 +37,13 @@ namespace blink { +namespace { + +// The default number of inputs for the merger node is 6. +constexpr unsigned kDefaultNumberOfInputs = 6; + +} // namespace + ChannelMergerNode::ChannelMergerNode(BaseAudioContext& context, unsigned number_of_inputs) : AudioNode(context) { @@ -48,8 +55,7 @@ ExceptionState& exception_state) { DCHECK(IsMainThread()); - // The default number of inputs for the merger node is 6. - return Create(context, 6, exception_state); + return Create(context, kDefaultNumberOfInputs, exception_state); } ChannelMergerNode* ChannelMergerNode::Create(BaseAudioContext& context,
diff --git a/third_party/blink/renderer/modules/webaudio/channel_splitter_handler.cc b/third_party/blink/renderer/modules/webaudio/channel_splitter_handler.cc index 8847ee2..76fd1206 100644 --- a/third_party/blink/renderer/modules/webaudio/channel_splitter_handler.cc +++ b/third_party/blink/renderer/modules/webaudio/channel_splitter_handler.cc
@@ -11,6 +11,12 @@ namespace blink { +namespace { + +constexpr unsigned kNumberOfOutputChannels = 1; + +} // namespace + ChannelSplitterHandler::ChannelSplitterHandler(AudioNode& node, float sample_rate, unsigned number_of_outputs) @@ -24,7 +30,7 @@ // Create a fixed number of outputs (able to handle the maximum number of // channels fed to an input). for (unsigned i = 0; i < number_of_outputs; ++i) { - AddOutput(1); + AddOutput(kNumberOfOutputChannels); } Initialize();
diff --git a/third_party/blink/renderer/modules/webaudio/channel_splitter_node.cc b/third_party/blink/renderer/modules/webaudio/channel_splitter_node.cc index 36c3f0f9..44dc7348 100644 --- a/third_party/blink/renderer/modules/webaudio/channel_splitter_node.cc +++ b/third_party/blink/renderer/modules/webaudio/channel_splitter_node.cc
@@ -34,6 +34,13 @@ namespace blink { +namespace { + +// Default number of outputs for the splitter node is 6. +constexpr unsigned kDefaultNumberOfOutputs = 6; + +} // namespace + ChannelSplitterNode::ChannelSplitterNode(BaseAudioContext& context, unsigned number_of_outputs) : AudioNode(context) { @@ -46,8 +53,7 @@ ExceptionState& exception_state) { DCHECK(IsMainThread()); - // Default number of outputs for the splitter node is 6. - return Create(context, 6, exception_state); + return Create(context, kDefaultNumberOfOutputs, exception_state); } ChannelSplitterNode* ChannelSplitterNode::Create(
diff --git a/third_party/blink/renderer/modules/webaudio/constant_source_handler.cc b/third_party/blink/renderer/modules/webaudio/constant_source_handler.cc index fbd27ce..8cddbaf 100644 --- a/third_party/blink/renderer/modules/webaudio/constant_source_handler.cc +++ b/third_party/blink/renderer/modules/webaudio/constant_source_handler.cc
@@ -13,7 +13,7 @@ namespace { // A ConstantSource is always mono. -constexpr unsigned kNumberOfOutputs = 1; +constexpr unsigned kNumberOfOutputChannels = 1; } // namespace @@ -23,7 +23,7 @@ : AudioScheduledSourceHandler(kNodeTypeConstantSource, node, sample_rate), offset_(&offset), sample_accurate_values_(GetDeferredTaskHandler().RenderQuantumFrames()) { - AddOutput(kNumberOfOutputs); + AddOutput(kNumberOfOutputChannels); Initialize(); }
diff --git a/third_party/blink/renderer/modules/webaudio/constant_source_node.cc b/third_party/blink/renderer/modules/webaudio/constant_source_node.cc index eca6b31..336790a 100644 --- a/third_party/blink/renderer/modules/webaudio/constant_source_node.cc +++ b/third_party/blink/renderer/modules/webaudio/constant_source_node.cc
@@ -11,13 +11,19 @@ namespace blink { +namespace { + +constexpr double kDefaultOffsetValue = 1.0; + +} // namespace + ConstantSourceNode::ConstantSourceNode(BaseAudioContext& context) : AudioScheduledSourceNode(context), offset_(AudioParam::Create( context, Uuid(), AudioParamHandler::kParamTypeConstantSourceOffset, - 1, + kDefaultOffsetValue, AudioParamHandler::AutomationRate::kAudio, AudioParamHandler::AutomationRateMode::kVariable)) { SetHandler(ConstantSourceHandler::Create(*this, context.sampleRate(),
diff --git a/third_party/blink/renderer/modules/webaudio/convolver_handler.cc b/third_party/blink/renderer/modules/webaudio/convolver_handler.cc index 8ea1bdc..b831d37 100644 --- a/third_party/blink/renderer/modules/webaudio/convolver_handler.cc +++ b/third_party/blink/renderer/modules/webaudio/convolver_handler.cc
@@ -16,6 +16,10 @@ #include "third_party/blink/renderer/platform/bindings/exception_messages.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" +namespace blink { + +namespace { + // Note about empirical tuning: // The maximum FFT size affects reverb performance and accuracy. // If the reverb is single-threaded and processes entirely in the real-time @@ -23,17 +27,20 @@ // a good value. But, the Reverb object is multi-threaded, so we want this as // high as possible without losing too much accuracy. Very large FFTs will have // worse phase errors. Given these constraints 32768 is a good compromise. -const unsigned MaxFFTSize = 32768; +constexpr unsigned kMaxFftSize = 32768; -namespace blink { +constexpr unsigned kDefaultNumberOfInputChannels = 2; +constexpr unsigned kDefaultNumberOfOutputChannels = 1; + +} // namespace ConvolverHandler::ConvolverHandler(AudioNode& node, float sample_rate) : AudioHandler(kNodeTypeConvolver, node, sample_rate) { AddInput(); - AddOutput(1); + AddOutput(kDefaultNumberOfOutputChannels); // Node-specific default mixing rules. - channel_count_ = 2; + channel_count_ = kDefaultNumberOfInputChannels; SetInternalChannelCountMode(kClampedMax); SetInternalChannelInterpretation(AudioBus::kSpeakers); @@ -165,7 +172,7 @@ // Create the reverb with the given impulse response. std::unique_ptr<Reverb> reverb = std::make_unique<Reverb>( buffer_bus.get(), GetDeferredTaskHandler().RenderQuantumFrames(), - MaxFFTSize, Context() && Context()->HasRealtimeConstraint(), normalize_); + kMaxFftSize, Context() && Context()->HasRealtimeConstraint(), normalize_); { // The context must be locked since changing the buffer can
diff --git a/third_party/blink/renderer/modules/webaudio/cpu/arm/oscillator_kernel_neon.cc b/third_party/blink/renderer/modules/webaudio/cpu/arm/oscillator_kernel_neon.cc index 6db3f21..674cfd6b4 100644 --- a/third_party/blink/renderer/modules/webaudio/cpu/arm/oscillator_kernel_neon.cc +++ b/third_party/blink/renderer/modules/webaudio/cpu/arm/oscillator_kernel_neon.cc
@@ -13,9 +13,11 @@ namespace blink { #if defined(CPU_ARM_NEON) -static float32x4_t WrapVirtualIndexVector(float32x4_t x, - float32x4_t wave_size, - float32x4_t inv_wave_size) { +namespace { + +float32x4_t WrapVirtualIndexVector(float32x4_t x, + float32x4_t wave_size, + float32x4_t inv_wave_size) { // r = x/wave_size, f = truncate(r), truncating towards 0 const float32x4_t r = vmulq_f32(x, inv_wave_size); int32x4_t f = vcvtq_s32_f32(r); @@ -27,13 +29,15 @@ return vsubq_f32(x, vmulq_f32(vcvtq_f32_s32(f), wave_size)); } -static ALWAYS_INLINE double WrapVirtualIndex(double virtual_index, - unsigned periodic_wave_size, - double inv_periodic_wave_size) { +ALWAYS_INLINE double WrapVirtualIndex(double virtual_index, + unsigned periodic_wave_size, + double inv_periodic_wave_size) { return virtual_index - floor(virtual_index * inv_periodic_wave_size) * periodic_wave_size; } +} // namespace + std::tuple<int, double> OscillatorHandler::ProcessKRateVector( int n, float* dest_p,
diff --git a/third_party/blink/renderer/modules/webaudio/cpu/x86/oscillator_kernel_sse2.cc b/third_party/blink/renderer/modules/webaudio/cpu/x86/oscillator_kernel_sse2.cc index 4ecd3e6..c6a3fdd 100644 --- a/third_party/blink/renderer/modules/webaudio/cpu/x86/oscillator_kernel_sse2.cc +++ b/third_party/blink/renderer/modules/webaudio/cpu/x86/oscillator_kernel_sse2.cc
@@ -10,9 +10,11 @@ namespace blink { -static __m128 WrapVirtualIndexVector(__m128 x, - __m128 wave_size, - __m128 inv_wave_size) { +namespace { + +__m128 WrapVirtualIndexVector(__m128 x, + __m128 wave_size, + __m128 inv_wave_size) { // Wrap the virtual index `x` to the range 0 to wave_size - 1. This is done // by computing `x` - floor(`x`/`wave_size`)*`wave_size`. // @@ -40,9 +42,9 @@ return _mm_sub_ps(x, _mm_mul_ps(_mm_cvtepi32_ps(f), wave_size)); } -static __m128d WrapVirtualIndexVectorPd(__m128d x, - __m128d wave_size, - __m128d inv_wave_size) { +__m128d WrapVirtualIndexVectorPd(__m128d x, + __m128d wave_size, + __m128d inv_wave_size) { // Wrap the virtual index `x` to the range 0 to wave_size - 1. This is done // by computing `x` - floor(`x`/`wave_size`)*`wave_size`. // @@ -74,6 +76,8 @@ return _mm_sub_pd(x, _mm_mul_pd(_mm_cvtepi32_pd(f), wave_size)); } +} // namespace + std::tuple<int, double> OscillatorHandler::ProcessKRateVector( int n, float* dest_p,
diff --git a/third_party/blink/renderer/modules/webaudio/delay_handler.cc b/third_party/blink/renderer/modules/webaudio/delay_handler.cc index 48396c8e..7431874 100644 --- a/third_party/blink/renderer/modules/webaudio/delay_handler.cc +++ b/third_party/blink/renderer/modules/webaudio/delay_handler.cc
@@ -12,6 +12,12 @@ namespace blink { +namespace { + +constexpr unsigned kNumberOfChannels = 1; + +} // namespace + DelayHandler::DelayHandler(AudioNode& node, float sample_rate, AudioParamHandler& delay_time, @@ -22,7 +28,7 @@ sample_rate, std::make_unique<DelayProcessor>( sample_rate, - 1, + kNumberOfChannels, node.context()->GetDeferredTaskHandler().RenderQuantumFrames(), delay_time, max_delay_time)) {
diff --git a/third_party/blink/renderer/modules/webaudio/delay_node.cc b/third_party/blink/renderer/modules/webaudio/delay_node.cc index 4884487e..896d33f 100644 --- a/third_party/blink/renderer/modules/webaudio/delay_node.cc +++ b/third_party/blink/renderer/modules/webaudio/delay_node.cc
@@ -35,7 +35,11 @@ namespace { -constexpr double kMaximumAllowedDelayTime = 180; +constexpr double kDefaultDelayTimeValue = 0.0; +constexpr float kMinDelayTimeValue = 0.0f; + +constexpr double kDefaultMaximumDelayTime = 1.0; // 1 second +constexpr double kMaximumAllowedDelayTime = 180.0; } // namespace @@ -45,10 +49,10 @@ AudioParam::Create(context, Uuid(), AudioParamHandler::kParamTypeDelayDelayTime, - 0.0, + kDefaultDelayTimeValue, AudioParamHandler::AutomationRate::kAudio, AudioParamHandler::AutomationRateMode::kVariable, - 0.0, + kMinDelayTimeValue, max_delay_time)) { SetHandler(DelayHandler::Create(*this, context.sampleRate(), delay_time_->Handler(), max_delay_time)); @@ -58,8 +62,7 @@ ExceptionState& exception_state) { DCHECK(IsMainThread()); - // The default maximum delay time for the delay node is 1 sec. - return Create(context, 1, exception_state); + return Create(context, kDefaultMaximumDelayTime, exception_state); } DelayNode* DelayNode::Create(BaseAudioContext& context,
diff --git a/third_party/blink/renderer/modules/webaudio/dynamics_compressor_handler.cc b/third_party/blink/renderer/modules/webaudio/dynamics_compressor_handler.cc index 521a846..f6ebd11a 100644 --- a/third_party/blink/renderer/modules/webaudio/dynamics_compressor_handler.cc +++ b/third_party/blink/renderer/modules/webaudio/dynamics_compressor_handler.cc
@@ -14,11 +14,15 @@ #include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h" -// Set output to stereo by default. -static const unsigned defaultNumberOfOutputChannels = 2; - namespace blink { +namespace { + +// Set output to stereo by default. +constexpr unsigned kDefaultNumberOfOutputChannels = 2; + +} // namespace + DynamicsCompressorHandler::DynamicsCompressorHandler( AudioNode& node, float sample_rate, @@ -35,7 +39,7 @@ attack_(&attack), release_(&release) { AddInput(); - AddOutput(defaultNumberOfOutputChannels); + AddOutput(kDefaultNumberOfOutputChannels); SetInternalChannelCountMode(kClampedMax); @@ -104,7 +108,7 @@ AudioHandler::Initialize(); dynamics_compressor_ = std::make_unique<DynamicsCompressor>( - Context()->sampleRate(), defaultNumberOfOutputChannels); + Context()->sampleRate(), kDefaultNumberOfOutputChannels); } bool DynamicsCompressorHandler::RequiresTailProcessing() const {
diff --git a/third_party/blink/renderer/modules/webaudio/dynamics_compressor_node.cc b/third_party/blink/renderer/modules/webaudio/dynamics_compressor_node.cc index bc3d15b..0ec0790 100644 --- a/third_party/blink/renderer/modules/webaudio/dynamics_compressor_node.cc +++ b/third_party/blink/renderer/modules/webaudio/dynamics_compressor_node.cc
@@ -37,53 +37,77 @@ namespace blink { +namespace { + +constexpr double kDefaultThresholdValue = -24.0; +constexpr float kMinThresholdValue = -100.0f; +constexpr float kMaxThresholdValue = 0.0f; + +constexpr double kDefaultKneeValue = 30.0; +constexpr float kMinKneeValue = 0.0f; +constexpr float kMaxKneeValue = 40.0f; + +constexpr double kDefaultRatioValue = 12.0; +constexpr float kMinRatioValue = 1.0f; +constexpr float kMaxRatioValue = 20.0f; + +constexpr double kDefaultAttackValue = 0.003; +constexpr float kMinAttackValue = 0.0f; +constexpr float kMaxAttackValue = 1.0f; + +constexpr double kDefaultReleaseValue = 0.250; +constexpr float kMinReleaseValue = 0.0f; +constexpr float kMaxReleaseValue = 1.0f; + +} // namespace + DynamicsCompressorNode::DynamicsCompressorNode(BaseAudioContext& context) : AudioNode(context), threshold_(AudioParam::Create( context, Uuid(), AudioParamHandler::kParamTypeDynamicsCompressorThreshold, - -24, + kDefaultThresholdValue, AudioParamHandler::AutomationRate::kControl, AudioParamHandler::AutomationRateMode::kFixed, - -100, - 0)), + kMinThresholdValue, + kMaxThresholdValue)), knee_(AudioParam::Create( context, Uuid(), AudioParamHandler::kParamTypeDynamicsCompressorKnee, - 30, + kDefaultKneeValue, AudioParamHandler::AutomationRate::kControl, AudioParamHandler::AutomationRateMode::kFixed, - 0, - 40)), + kMinKneeValue, + kMaxKneeValue)), ratio_(AudioParam::Create( context, Uuid(), AudioParamHandler::kParamTypeDynamicsCompressorRatio, - 12, + kDefaultRatioValue, AudioParamHandler::AutomationRate::kControl, AudioParamHandler::AutomationRateMode::kFixed, - 1, - 20)), + kMinRatioValue, + kMaxRatioValue)), attack_(AudioParam::Create( context, Uuid(), AudioParamHandler::kParamTypeDynamicsCompressorAttack, - 0.003, + kDefaultAttackValue, AudioParamHandler::AutomationRate::kControl, AudioParamHandler::AutomationRateMode::kFixed, - 0, - 1)), + kMinAttackValue, + kMaxAttackValue)), release_(AudioParam::Create( context, Uuid(), AudioParamHandler::kParamTypeDynamicsCompressorRelease, - 0.250, + kDefaultReleaseValue, AudioParamHandler::AutomationRate::kControl, AudioParamHandler::AutomationRateMode::kFixed, - 0, - 1)) { + kMinReleaseValue, + kMaxReleaseValue)) { SetHandler(DynamicsCompressorHandler::Create( *this, context.sampleRate(), threshold_->Handler(), knee_->Handler(), ratio_->Handler(), attack_->Handler(), release_->Handler()));
diff --git a/third_party/blink/renderer/modules/webaudio/gain_handler.cc b/third_party/blink/renderer/modules/webaudio/gain_handler.cc index 6f211431..affef5a 100644 --- a/third_party/blink/renderer/modules/webaudio/gain_handler.cc +++ b/third_party/blink/renderer/modules/webaudio/gain_handler.cc
@@ -11,6 +11,12 @@ namespace blink { +namespace { + +constexpr unsigned kNumberOfOutputChannels = 1; + +} // namespace + GainHandler::GainHandler(AudioNode& node, float sample_rate, AudioParamHandler& gain) @@ -19,7 +25,7 @@ sample_accurate_gain_values_( GetDeferredTaskHandler().RenderQuantumFrames()) { AddInput(); - AddOutput(1); + AddOutput(kNumberOfOutputChannels); Initialize(); }
diff --git a/third_party/blink/renderer/modules/webaudio/gain_node.cc b/third_party/blink/renderer/modules/webaudio/gain_node.cc index 45aa16c..5e697cc6 100644 --- a/third_party/blink/renderer/modules/webaudio/gain_node.cc +++ b/third_party/blink/renderer/modules/webaudio/gain_node.cc
@@ -31,13 +31,19 @@ namespace blink { +namespace { + +constexpr double kDefaultGainValue = 1.0; + +} // namespace + GainNode::GainNode(BaseAudioContext& context) : AudioNode(context), gain_(AudioParam::Create( context, Uuid(), AudioParamHandler::kParamTypeGainGain, - 1.0, + kDefaultGainValue, AudioParamHandler::AutomationRate::kAudio, AudioParamHandler::AutomationRateMode::kVariable)) { SetHandler(
diff --git a/third_party/blink/renderer/modules/webaudio/iir_filter_handler.cc b/third_party/blink/renderer/modules/webaudio/iir_filter_handler.cc index e3dfa04b..f34af46f 100644 --- a/third_party/blink/renderer/modules/webaudio/iir_filter_handler.cc +++ b/third_party/blink/renderer/modules/webaudio/iir_filter_handler.cc
@@ -16,6 +16,12 @@ namespace blink { +namespace { + +constexpr uint32_t kNumberOfChannels = 1; + +} // namespace + IIRFilterHandler::IIRFilterHandler(AudioNode& node, float sample_rate, const Vector<double>& feedforward_coef, @@ -27,7 +33,7 @@ sample_rate, std::make_unique<IIRProcessor>( sample_rate, - 1, + kNumberOfChannels, node.context()->GetDeferredTaskHandler().RenderQuantumFrames(), feedforward_coef, feedback_coef,
diff --git a/third_party/blink/renderer/modules/webaudio/iir_filter_node.cc b/third_party/blink/renderer/modules/webaudio/iir_filter_node.cc index 25857bf..57ea5c7 100644 --- a/third_party/blink/renderer/modules/webaudio/iir_filter_node.cc +++ b/third_party/blink/renderer/modules/webaudio/iir_filter_node.cc
@@ -18,6 +18,8 @@ namespace blink { +namespace { + // Determine if filter is stable based on the feedback coefficients. // We compute the reflection coefficients for the filter. If, at any // point, the magnitude of the reflection coefficient is greater than @@ -32,7 +34,7 @@ // // stopping at A[1](z). If at any point |k[n]| >= 1, the filter is // unstable. -static bool IsFilterStable(const Vector<double>& feedback_coef) { +bool IsFilterStable(const Vector<double>& feedback_coef) { // Make a copy of the feedback coefficients Vector<double> coef(feedback_coef); int order = coef.size() - 1; @@ -66,6 +68,8 @@ return true; } +} // namespace + IIRFilterNode::IIRFilterNode(BaseAudioContext& context, const Vector<double>& feedforward_coef, const Vector<double>& feedback_coef,
diff --git a/third_party/blink/renderer/modules/webaudio/media_element_audio_source_handler.cc b/third_party/blink/renderer/modules/webaudio/media_element_audio_source_handler.cc index da584573..71208b9 100644 --- a/third_party/blink/renderer/modules/webaudio/media_element_audio_source_handler.cc +++ b/third_party/blink/renderer/modules/webaudio/media_element_audio_source_handler.cc
@@ -22,6 +22,14 @@ namespace blink { +namespace { + +// Default to stereo. This could change depending on what the media element +// .src is set to. +constexpr unsigned kDefaultNumberOfOutputChannels = 2; + +} // namespace + class MediaElementAudioSourceHandlerLocker final { STACK_ALLOCATED(); @@ -51,9 +59,8 @@ node.context()->sampleRate()), media_element_(media_element) { DCHECK(IsMainThread()); - // Default to stereo. This could change depending on what the media element - // .src is set to. - AddOutput(2); + + AddOutput(kDefaultNumberOfOutputChannels); if (Context()->GetExecutionContext()) { task_runner_ = Context()->GetExecutionContext()->GetTaskRunner(
diff --git a/third_party/blink/renderer/modules/webaudio/media_stream_audio_destination_handler.cc b/third_party/blink/renderer/modules/webaudio/media_stream_audio_destination_handler.cc index b593c0a..5e87396 100644 --- a/third_party/blink/renderer/modules/webaudio/media_stream_audio_destination_handler.cc +++ b/third_party/blink/renderer/modules/webaudio/media_stream_audio_destination_handler.cc
@@ -14,10 +14,14 @@ namespace blink { +namespace { + // Channel counts greater than 8 are ignored by some audio tracks/sinks (see // WebAudioMediaStreamSource), so we set a limit here to avoid anything that // could cause a crash. -static const uint32_t kMaxChannelCount = 8; +constexpr uint32_t kMaxChannelCountSupported = 8; + +} // namespace MediaStreamAudioDestinationHandler::MediaStreamAudioDestinationHandler( AudioNode& node, @@ -108,7 +112,7 @@ } uint32_t MediaStreamAudioDestinationHandler::MaxChannelCount() const { - return kMaxChannelCount; + return kMaxChannelCountSupported; } void MediaStreamAudioDestinationHandler::PullInputs(
diff --git a/third_party/blink/renderer/modules/webaudio/media_stream_audio_destination_node.cc b/third_party/blink/renderer/modules/webaudio/media_stream_audio_destination_node.cc index ca6c4f4..a6fec307 100644 --- a/third_party/blink/renderer/modules/webaudio/media_stream_audio_destination_node.cc +++ b/third_party/blink/renderer/modules/webaudio/media_stream_audio_destination_node.cc
@@ -39,6 +39,9 @@ namespace { +// Default to stereo; `options` will update it appropriately if needed. +constexpr uint32_t kDefaultNumberOfChannels = 2; + void DidCreateMediaStreamAndTracks(MediaStreamDescriptor* stream) { for (uint32_t i = 0; i < stream->NumberOfAudioComponents(); ++i) { MediaStreamUtils::DidCreateMediaStreamTrack(stream->AudioComponent(i)); @@ -127,9 +130,9 @@ if (!context->CheckExecutionContextAndThrowIfNecessary(exception_state)) { return nullptr; } - // Default to stereo; `options` will update it appropriately if needed. MediaStreamAudioDestinationNode* node = - MakeGarbageCollected<MediaStreamAudioDestinationNode>(*context, 2); + MakeGarbageCollected<MediaStreamAudioDestinationNode>( + *context, kDefaultNumberOfChannels); // Need to handle channelCount here ourselves because the upper // limit is different from the normal AudioNode::setChannelCount
diff --git a/third_party/blink/renderer/modules/webaudio/media_stream_audio_source_handler.cc b/third_party/blink/renderer/modules/webaudio/media_stream_audio_source_handler.cc index 21e52fd..ee4ef38 100644 --- a/third_party/blink/renderer/modules/webaudio/media_stream_audio_source_handler.cc +++ b/third_party/blink/renderer/modules/webaudio/media_stream_audio_source_handler.cc
@@ -15,7 +15,7 @@ // Default to stereo. This could change depending on the format of the // MediaStream's audio track. -constexpr unsigned kNumberOfOutputChannels = 2; +constexpr unsigned kDefaultNumberOfOutputChannels = 2; } // namespace @@ -27,7 +27,7 @@ node.context()->sampleRate()), audio_source_provider_(std::move(audio_source_provider)) { SendLogMessage(String::Format("%s", __func__)); - AddOutput(kNumberOfOutputChannels); + AddOutput(kDefaultNumberOfOutputChannels); Initialize(); }
diff --git a/third_party/blink/renderer/modules/webaudio/offline_audio_worklet_thread.cc b/third_party/blink/renderer/modules/webaudio/offline_audio_worklet_thread.cc index 4340fdb..d167cec3 100644 --- a/third_party/blink/renderer/modules/webaudio/offline_audio_worklet_thread.cc +++ b/third_party/blink/renderer/modules/webaudio/offline_audio_worklet_thread.cc
@@ -14,9 +14,9 @@ // Use for ref-counting of all OfflineAudioWorkletThread instances in a // process. Incremented by the constructor and decremented by destructor. -static int ref_count = 0; +int ref_count = 0; -static void EnsureSharedBackingThread(const ThreadCreationParams& params) { +void EnsureSharedBackingThread(const ThreadCreationParams& params) { DCHECK(IsMainThread()); DCHECK_EQ(ref_count, 1); WorkletThreadHolder<OfflineAudioWorkletThread>::EnsureInstance(params);
diff --git a/third_party/blink/renderer/modules/webaudio/oscillator_handler.cc b/third_party/blink/renderer/modules/webaudio/oscillator_handler.cc index 964b05fd..8b6091f 100644 --- a/third_party/blink/renderer/modules/webaudio/oscillator_handler.cc +++ b/third_party/blink/renderer/modules/webaudio/oscillator_handler.cc
@@ -22,22 +22,20 @@ namespace blink { -// Breakpoints where we decide to do linear interpolation, 3-point -// interpolation or 5-point interpolation. See DoInterpolation(). -constexpr float kInterpolate2Point = 0.3; -constexpr float kInterpolate3Point = 0.16; +namespace { + +// An oscillator is always mono. +constexpr unsigned kNumberOfOutputChannels = 1; // Convert the detune value (in cents) to a frequency scale multiplier: // 2^(d/1200) -static float DetuneToFrequencyMultiplier(float detune_value) { +float DetuneToFrequencyMultiplier(float detune_value) { return std::exp2(detune_value / 1200); } // Clamp the frequency value to lie with Nyquist frequency. For NaN, arbitrarily // clamp to +Nyquist. -static void ClampFrequency(float* frequency, - int frames_to_process, - float nyquist) { +void ClampFrequency(float* frequency, int frames_to_process, float nyquist) { for (int k = 0; k < frames_to_process; ++k) { float f = frequency[k]; @@ -49,12 +47,12 @@ } } -static float DoInterpolation(double virtual_read_index, - float incr, - unsigned read_index_mask, - float table_interpolation_factor, - const float* lower_wave_data, - const float* higher_wave_data) { +float DoInterpolation(double virtual_read_index, + float incr, + unsigned read_index_mask, + float table_interpolation_factor, + const float* lower_wave_data, + const float* higher_wave_data) { DCHECK_GE(incr, 0); DCHECK(std::isfinite(virtual_read_index)); @@ -75,7 +73,7 @@ // We use Lagrange interpolation because it's relatively simple to // implement and fairly inexpensive, and the interpolator always // passes through known points. - if (incr >= kInterpolate2Point) { + if (incr >= OscillatorHandler::kInterpolate2Point) { // Increment is fairly large, so we're doing no more than about 3 // points between each wave table entry. Assume linear // interpolation between points is good enough. @@ -98,7 +96,7 @@ sample_lower = (1 - interpolation_factor) * sample1_lower + interpolation_factor * sample2_lower; - } else if (incr >= kInterpolate3Point) { + } else if (incr >= OscillatorHandler::kInterpolate3Point) { // We're doing about 6 interpolation values between each wave // table sample. Just use a 3-point Lagrange interpolator to get a // better estimate than just linear. @@ -154,6 +152,8 @@ return sample; } +} // namespace + OscillatorHandler::OscillatorHandler(AudioNode& node, float sample_rate, const String& oscillator_type, @@ -183,8 +183,7 @@ } } - // An oscillator is always mono. - AddOutput(1); + AddOutput(kNumberOfOutputChannels); Initialize(); }
diff --git a/third_party/blink/renderer/modules/webaudio/oscillator_handler.h b/third_party/blink/renderer/modules/webaudio/oscillator_handler.h index d82cd1a..0fde7fd 100644 --- a/third_party/blink/renderer/modules/webaudio/oscillator_handler.h +++ b/third_party/blink/renderer/modules/webaudio/oscillator_handler.h
@@ -34,8 +34,8 @@ // Breakpoints where we decide to do linear interpolation, 3-point // interpolation or 5-point interpolation. See DoInterpolation(). - static constexpr float kInterpolate2Point = 0.3; - static constexpr float kInterpolate3Point = 0.16; + static constexpr float kInterpolate2Point = 0.3f; + static constexpr float kInterpolate3Point = 0.16f; static scoped_refptr<OscillatorHandler> Create(AudioNode&, float sample_rate,
diff --git a/third_party/blink/renderer/modules/webaudio/oscillator_node.cc b/third_party/blink/renderer/modules/webaudio/oscillator_node.cc index d13b0498..11ed26b 100644 --- a/third_party/blink/renderer/modules/webaudio/oscillator_node.cc +++ b/third_party/blink/renderer/modules/webaudio/oscillator_node.cc
@@ -42,6 +42,13 @@ namespace blink { +namespace { + +constexpr double kDefaultFrequencyValue = 440.0; +constexpr double kDefaultDetuneValue = 0.0; + +} // namespace + OscillatorNode::OscillatorNode(BaseAudioContext& context, const String& oscillator_type, PeriodicWave* wave_table) @@ -51,21 +58,21 @@ AudioParam::Create(context, Uuid(), AudioParamHandler::kParamTypeOscillatorFrequency, - 440, + kDefaultFrequencyValue, AudioParamHandler::AutomationRate::kAudio, AudioParamHandler::AutomationRateMode::kVariable, - -context.sampleRate() / 2, - context.sampleRate() / 2)), + /*min_value=*/-context.sampleRate() / 2, + /*max_value=*/context.sampleRate() / 2)), // Default to no detuning. - detune_( - AudioParam::Create(context, - Uuid(), - AudioParamHandler::kParamTypeOscillatorDetune, - 0, - AudioParamHandler::AutomationRate::kAudio, - AudioParamHandler::AutomationRateMode::kVariable, - -1200 * log2f(std::numeric_limits<float>::max()), - 1200 * log2f(std::numeric_limits<float>::max()))) { + detune_(AudioParam::Create( + context, + Uuid(), + AudioParamHandler::kParamTypeOscillatorDetune, + kDefaultDetuneValue, + AudioParamHandler::AutomationRate::kAudio, + AudioParamHandler::AutomationRateMode::kVariable, + /*min_value=*/-1200 * log2f(std::numeric_limits<float>::max()), + /*max_value=*/1200 * log2f(std::numeric_limits<float>::max()))) { SetHandler( OscillatorHandler::Create(*this, context.sampleRate(), oscillator_type, wave_table ? wave_table->impl() : nullptr,
diff --git a/third_party/blink/renderer/modules/webaudio/panner_handler.cc b/third_party/blink/renderer/modules/webaudio/panner_handler.cc index 20224ff..e58dd58b 100644 --- a/third_party/blink/renderer/modules/webaudio/panner_handler.cc +++ b/third_party/blink/renderer/modules/webaudio/panner_handler.cc
@@ -20,6 +20,7 @@ namespace { +// A PannerNode only supports 1 or 2 channels constexpr unsigned kMinimumOutputChannels = 1; constexpr unsigned kMaximumOutputChannels = 2; @@ -675,7 +676,6 @@ DCHECK(IsMainThread()); BaseAudioContext::GraphAutoLocker locker(Context()); - // A PannerNode only supports 1 or 2 channels if (channel_count >= kMinimumOutputChannels && channel_count <= kMaximumOutputChannels) { if (channel_count_ != channel_count) {
diff --git a/third_party/blink/renderer/modules/webaudio/panner_node.cc b/third_party/blink/renderer/modules/webaudio/panner_node.cc index ca16e03..9090d279 100644 --- a/third_party/blink/renderer/modules/webaudio/panner_node.cc +++ b/third_party/blink/renderer/modules/webaudio/panner_node.cc
@@ -35,48 +35,59 @@ namespace blink { +namespace { + +constexpr double kDefaultPositionXValue = 0.0; +constexpr double kDefaultPositionYValue = 0.0; +constexpr double kDefaultPositionZValue = 0.0; +constexpr double kDefaultOrientationXValue = 1.0; +constexpr double kDefaultOrientationYValue = 0.0; +constexpr double kDefaultOrientationZValue = 0.0; + +} // namespace + PannerNode::PannerNode(BaseAudioContext& context) : AudioNode(context), position_x_( AudioParam::Create(context, Uuid(), AudioParamHandler::kParamTypePannerPositionX, - 0.0, + kDefaultPositionXValue, AudioParamHandler::AutomationRate::kAudio, AudioParamHandler::AutomationRateMode::kVariable)), position_y_( AudioParam::Create(context, Uuid(), AudioParamHandler::kParamTypePannerPositionY, - 0.0, + kDefaultPositionYValue, AudioParamHandler::AutomationRate::kAudio, AudioParamHandler::AutomationRateMode::kVariable)), position_z_( AudioParam::Create(context, Uuid(), AudioParamHandler::kParamTypePannerPositionZ, - 0.0, + kDefaultPositionZValue, AudioParamHandler::AutomationRate::kAudio, AudioParamHandler::AutomationRateMode::kVariable)), orientation_x_( AudioParam::Create(context, Uuid(), AudioParamHandler::kParamTypePannerOrientationX, - 1.0, + kDefaultOrientationXValue, AudioParamHandler::AutomationRate::kAudio, AudioParamHandler::AutomationRateMode::kVariable)), orientation_y_( AudioParam::Create(context, Uuid(), AudioParamHandler::kParamTypePannerOrientationY, - 0.0, + kDefaultOrientationYValue, AudioParamHandler::AutomationRate::kAudio, AudioParamHandler::AutomationRateMode::kVariable)), orientation_z_( AudioParam::Create(context, Uuid(), AudioParamHandler::kParamTypePannerOrientationZ, - 0.0, + kDefaultOrientationZValue, AudioParamHandler::AutomationRate::kAudio, AudioParamHandler::AutomationRateMode::kVariable)), listener_(context.listener()) {
diff --git a/third_party/blink/renderer/modules/webaudio/periodic_wave.cc b/third_party/blink/renderer/modules/webaudio/periodic_wave.cc index 84619e6..1a37038 100644 --- a/third_party/blink/renderer/modules/webaudio/periodic_wave.cc +++ b/third_party/blink/renderer/modules/webaudio/periodic_wave.cc
@@ -48,15 +48,19 @@ namespace blink { +namespace { + // The number of bands per octave. Each octave will have this many entries in // the wave tables. -const unsigned kNumberOfOctaveBands = 3; +constexpr unsigned kNumberOfOctaveBands = 3; // The max length of a periodic wave. This must be a power of two greater than // or equal to 2048 and must be supported by the FFT routines. -const unsigned kMaxPeriodicWaveSize = 16384; +constexpr unsigned kMaxPeriodicWaveSize = 16384; -const float kCentsPerRange = 1200 / kNumberOfOctaveBands; +constexpr float kCentsPerRange = 1200 / kNumberOfOctaveBands; + +} // namespace PeriodicWave* PeriodicWave::Create(BaseAudioContext& context, const Vector<float>& real,
diff --git a/third_party/blink/renderer/modules/webaudio/realtime_analyser.cc b/third_party/blink/renderer/modules/webaudio/realtime_analyser.cc index 0ae569b..e061fd2 100644 --- a/third_party/blink/renderer/modules/webaudio/realtime_analyser.cc +++ b/third_party/blink/renderer/modules/webaudio/realtime_analyser.cc
@@ -34,18 +34,6 @@ namespace blink { -const double RealtimeAnalyser::kDefaultSmoothingTimeConstant = 0.8; -const double RealtimeAnalyser::kDefaultMinDecibels = -100; -const double RealtimeAnalyser::kDefaultMaxDecibels = -30; - -const unsigned RealtimeAnalyser::kDefaultFFTSize = 2048; -// All FFT implementations are expected to handle power-of-two sizes -// MinFFTSize <= size <= MaxFFTSize. -const unsigned RealtimeAnalyser::kMinFFTSize = 32; -const unsigned RealtimeAnalyser::kMaxFFTSize = 32768; -const unsigned RealtimeAnalyser::kInputBufferSize = - RealtimeAnalyser::kMaxFFTSize * 2; - RealtimeAnalyser::RealtimeAnalyser(unsigned render_quantum_frames) : input_buffer_(kInputBufferSize), down_mix_bus_(AudioBus::Create(1, render_quantum_frames)),
diff --git a/third_party/blink/renderer/modules/webaudio/realtime_analyser.h b/third_party/blink/renderer/modules/webaudio/realtime_analyser.h index cd2e0ab..554a6e1 100644 --- a/third_party/blink/renderer/modules/webaudio/realtime_analyser.h +++ b/third_party/blink/renderer/modules/webaudio/realtime_analyser.h
@@ -41,14 +41,16 @@ DISALLOW_NEW(); public: - static const double kDefaultSmoothingTimeConstant; - static const double kDefaultMinDecibels; - static const double kDefaultMaxDecibels; + static constexpr double kDefaultSmoothingTimeConstant = 0.8; + static constexpr double kDefaultMinDecibels = -100.0; + static constexpr double kDefaultMaxDecibels = -30.0; - static const unsigned kDefaultFFTSize; - static const unsigned kMinFFTSize; - static const unsigned kMaxFFTSize; - static const unsigned kInputBufferSize; + static constexpr unsigned kDefaultFFTSize = 2048; + // All FFT implementations are expected to handle power-of-two sizes + // MinFFTSize <= size <= MaxFFTSize. + static constexpr unsigned kMinFFTSize = 32; + static constexpr unsigned kMaxFFTSize = 32768; + static constexpr unsigned kInputBufferSize = kMaxFFTSize * 2; explicit RealtimeAnalyser(unsigned render_quantum_frames);
diff --git a/third_party/blink/renderer/modules/webaudio/realtime_audio_destination_handler.cc b/third_party/blink/renderer/modules/webaudio/realtime_audio_destination_handler.cc index 25862bbd..c524ec84 100644 --- a/third_party/blink/renderer/modules/webaudio/realtime_audio_destination_handler.cc +++ b/third_party/blink/renderer/modules/webaudio/realtime_audio_destination_handler.cc
@@ -22,6 +22,12 @@ namespace blink { +namespace { + +constexpr unsigned kDefaultNumberOfInputChannels = 2; + +} // namespace + scoped_refptr<RealtimeAudioDestinationHandler> RealtimeAudioDestinationHandler::Create(AudioNode& node, const WebAudioLatencyHint& latency_hint, @@ -41,7 +47,7 @@ task_runner_(Context()->GetExecutionContext()->GetTaskRunner( TaskType::kInternalMediaRealTime)) { // Node-specific default channel count and mixing rules. - channel_count_ = 2; + channel_count_ = kDefaultNumberOfInputChannels; SetInternalChannelCountMode(kExplicit); SetInternalChannelInterpretation(AudioBus::kSpeakers); }
diff --git a/third_party/blink/renderer/modules/webaudio/realtime_audio_worklet_thread.cc b/third_party/blink/renderer/modules/webaudio/realtime_audio_worklet_thread.cc index 5e919929..f982dff 100644 --- a/third_party/blink/renderer/modules/webaudio/realtime_audio_worklet_thread.cc +++ b/third_party/blink/renderer/modules/webaudio/realtime_audio_worklet_thread.cc
@@ -16,9 +16,9 @@ // Use for ref-counting of all RealtimeAudioWorkletThread instances in a // process. Incremented by the constructor and decremented by destructor. -static int ref_count = 0; +int ref_count = 0; -static void EnsureSharedBackingThread(const ThreadCreationParams& params) { +void EnsureSharedBackingThread(const ThreadCreationParams& params) { DCHECK(IsMainThread()); DCHECK_EQ(ref_count, 1); WorkletThreadHolder<RealtimeAudioWorkletThread>::EnsureInstance(params);
diff --git a/third_party/blink/renderer/modules/webaudio/script_processor_node.cc b/third_party/blink/renderer/modules/webaudio/script_processor_node.cc index feecd58..8e3819f5 100644 --- a/third_party/blink/renderer/modules/webaudio/script_processor_node.cc +++ b/third_party/blink/renderer/modules/webaudio/script_processor_node.cc
@@ -67,8 +67,8 @@ (buffer_1->sampleRate() == buffer_2->sampleRate()); } -static uint32_t ChooseBufferSize(uint32_t callback_buffer_size) { - // Choose a buffer size based on the audio hardware buffer size. Arbitarily +uint32_t ChooseBufferSize(uint32_t callback_buffer_size) { + // Choose a buffer size based on the audio hardware buffer size. Arbitrarily // make it a power of two that is 4 times greater than the hardware buffer // size. // TODO(crbug.com/855758): What is the best way to choose this?
diff --git a/third_party/blink/renderer/modules/webaudio/semi_realtime_audio_worklet_thread.cc b/third_party/blink/renderer/modules/webaudio/semi_realtime_audio_worklet_thread.cc index 3210de3..15518a2b 100644 --- a/third_party/blink/renderer/modules/webaudio/semi_realtime_audio_worklet_thread.cc +++ b/third_party/blink/renderer/modules/webaudio/semi_realtime_audio_worklet_thread.cc
@@ -16,9 +16,9 @@ // Use for ref-counting of all SemiRealtimeAudioWorkletThread instances in a // process. Incremented by the constructor and decremented by destructor. -static int ref_count = 0; +int ref_count = 0; -static void EnsureSharedBackingThread(const ThreadCreationParams& params) { +void EnsureSharedBackingThread(const ThreadCreationParams& params) { DCHECK(IsMainThread()); DCHECK_EQ(ref_count, 1); WorkletThreadHolder<SemiRealtimeAudioWorkletThread>::EnsureInstance(params);
diff --git a/third_party/blink/renderer/modules/webaudio/stereo_panner_handler.cc b/third_party/blink/renderer/modules/webaudio/stereo_panner_handler.cc index f5b54b0..df6832f2 100644 --- a/third_party/blink/renderer/modules/webaudio/stereo_panner_handler.cc +++ b/third_party/blink/renderer/modules/webaudio/stereo_panner_handler.cc
@@ -17,6 +17,14 @@ namespace blink { +namespace { + +// A PannerNode only supports 1 or 2 channels +constexpr unsigned kMinimumOutputChannels = 1; +constexpr unsigned kMaximumOutputChannels = 2; + +} // namespace + StereoPannerHandler::StereoPannerHandler(AudioNode& node, float sample_rate, AudioParamHandler& pan) @@ -25,11 +33,11 @@ sample_accurate_pan_values_( GetDeferredTaskHandler().RenderQuantumFrames()) { AddInput(); - AddOutput(2); + AddOutput(kMaximumOutputChannels); // The node-specific default mixing rules declare that StereoPannerNode // can handle mono to stereo and stereo to stereo conversion. - channel_count_ = 2; + channel_count_ = kMaximumOutputChannels; SetInternalChannelCountMode(kClampedMax); SetInternalChannelInterpretation(AudioBus::kSpeakers); @@ -104,8 +112,8 @@ DCHECK(IsMainThread()); BaseAudioContext::GraphAutoLocker locker(Context()); - // A PannerNode only supports 1 or 2 channels - if (channel_count > 0 && channel_count <= 2) { + if (channel_count >= kMinimumOutputChannels && + channel_count <= kMaximumOutputChannels) { if (channel_count_ != channel_count) { channel_count_ = channel_count; if (InternalChannelCountMode() != kMax) { @@ -116,8 +124,8 @@ exception_state.ThrowDOMException( DOMExceptionCode::kNotSupportedError, ExceptionMessages::IndexOutsideRange<uint32_t>( - "channelCount", channel_count, 1, - ExceptionMessages::kInclusiveBound, 2, + "channelCount", channel_count, kMinimumOutputChannels, + ExceptionMessages::kInclusiveBound, kMaximumOutputChannels, ExceptionMessages::kInclusiveBound)); } }
diff --git a/third_party/blink/renderer/modules/webaudio/stereo_panner_node.cc b/third_party/blink/renderer/modules/webaudio/stereo_panner_node.cc index b9d3aa9b..f10467a3 100644 --- a/third_party/blink/renderer/modules/webaudio/stereo_panner_node.cc +++ b/third_party/blink/renderer/modules/webaudio/stereo_panner_node.cc
@@ -17,16 +17,24 @@ namespace blink { +namespace { + +constexpr double kDefaultPanValue = 0.0; +constexpr float kMinPanValue = -1.0f; +constexpr float kMaxPanValue = 1.0f; + +} // namespace + StereoPannerNode::StereoPannerNode(BaseAudioContext& context) : AudioNode(context), pan_(AudioParam::Create(context, Uuid(), AudioParamHandler::kParamTypeStereoPannerPan, - 0, + kDefaultPanValue, AudioParamHandler::AutomationRate::kAudio, AudioParamHandler::AutomationRateMode::kVariable, - -1, - 1)) { + kMinPanValue, + kMaxPanValue)) { SetHandler(StereoPannerHandler::Create(*this, context.sampleRate(), pan_->Handler())); }
diff --git a/third_party/blink/renderer/modules/webaudio/wave_shaper_handler.cc b/third_party/blink/renderer/modules/webaudio/wave_shaper_handler.cc index bc32aae..e203760 100644 --- a/third_party/blink/renderer/modules/webaudio/wave_shaper_handler.cc +++ b/third_party/blink/renderer/modules/webaudio/wave_shaper_handler.cc
@@ -12,6 +12,12 @@ namespace blink { +namespace { + +constexpr unsigned kNumberOfChannels = 1; + +} // namespace + WaveShaperHandler::WaveShaperHandler(AudioNode& node, float sample_rate) : AudioBasicProcessorHandler( kNodeTypeWaveShaper, @@ -19,7 +25,7 @@ sample_rate, std::make_unique<WaveShaperProcessor>( sample_rate, - 1, + kNumberOfChannels, node.context()->GetDeferredTaskHandler().RenderQuantumFrames())) { Initialize(); }
diff --git a/third_party/blink/renderer/modules/webcodecs/decoder_selector.cc b/third_party/blink/renderer/modules/webcodecs/decoder_selector.cc index c7fcef2..09726b98 100644 --- a/third_party/blink/renderer/modules/webcodecs/decoder_selector.cc +++ b/third_party/blink/renderer/modules/webcodecs/decoder_selector.cc
@@ -104,9 +104,9 @@ demuxer_stream_->Configure(config); demuxer_stream_->set_low_delay(low_delay); - // media::DecoderSelector will call back with a null decoder if selection is + // media::DecoderSelector will call back with a DecoderStatus if selection is // in progress when it is destructed. - impl_.SelectDecoder( + impl_.BeginDecoderSelection( WTF::Bind(&DecoderSelector<StreamType>::OnDecoderSelected, weak_factory_.GetWeakPtr(), std::move(select_decoder_cb)), output_cb_); @@ -130,7 +130,7 @@ template <media::DemuxerStream::Type StreamType> void DecoderSelector<StreamType>::OnDecoderSelected( SelectDecoderCB select_decoder_cb, - std::unique_ptr<Decoder> decoder, + DecoderOrError decoder_or_error, std::unique_ptr<media::DecryptingDemuxerStream> decrypting_demuxer_stream) { DCHECK(!decrypting_demuxer_stream); @@ -140,7 +140,11 @@ // (configure() no longer takes a promise). impl_.FinalizeDecoderSelection(); - std::move(select_decoder_cb).Run(std::move(decoder)); + if (decoder_or_error.has_error()) { + std::move(select_decoder_cb).Run(nullptr); + } else { + std::move(select_decoder_cb).Run(std::move(decoder_or_error).value()); + } } template class MODULES_EXPORT DecoderSelector<media::DemuxerStream::VIDEO>;
diff --git a/third_party/blink/renderer/modules/webcodecs/decoder_selector.h b/third_party/blink/renderer/modules/webcodecs/decoder_selector.h index 86aae0d6..d7e79a4 100644 --- a/third_party/blink/renderer/modules/webcodecs/decoder_selector.h +++ b/third_party/blink/renderer/modules/webcodecs/decoder_selector.h
@@ -25,6 +25,8 @@ typedef media::DecoderStreamTraits<StreamType> StreamTraits; typedef typename StreamTraits::DecoderType Decoder; typedef typename StreamTraits::DecoderConfigType DecoderConfig; + using DecoderOrError = + typename media::DecoderSelector<StreamType>::DecoderOrError; // Callback to create a list of decoders to select from. using CreateDecodersCB = @@ -63,7 +65,7 @@ // Proxy SelectDecoderCB from impl_ to our |select_decoder_cb|. void OnDecoderSelected(SelectDecoderCB select_decoder_cb, - std::unique_ptr<Decoder> decoder, + DecoderOrError decoder_or_error, std::unique_ptr<media::DecryptingDemuxerStream>); // Implements heavy lifting for decoder selection.
diff --git a/third_party/blink/renderer/platform/wtf/cross_thread_copier.h b/third_party/blink/renderer/platform/wtf/cross_thread_copier.h index 39630b4..35e8989d 100644 --- a/third_party/blink/renderer/platform/wtf/cross_thread_copier.h +++ b/third_party/blink/renderer/platform/wtf/cross_thread_copier.h
@@ -97,16 +97,10 @@ }; template <wtf_size_t inlineCapacity, typename Allocator> -struct CrossThreadCopier<Vector<String, inlineCapacity, Allocator>> { +struct CrossThreadCopier<Vector<String, inlineCapacity, Allocator>> + : public CrossThreadCopierPassThrough< + Vector<String, inlineCapacity, Allocator>> { STATIC_ONLY(CrossThreadCopier); - using Type = Vector<String, inlineCapacity, Allocator>; - static Type Copy(const Type& value) { - Type result; - result.ReserveInitialCapacity(value.size()); - for (const auto& element : value) - result.push_back(element.IsolatedCopy()); - return result; - } }; template <>
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index 6e6bdd8..c24387a 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -876,6 +876,11 @@ crbug.com/1299442 [ Mac11 ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/paint-arguments.https.html [ Failure ] crbug.com/1299442 [ Mac10.15 ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/registered-property-value-011.https.html [ Failure ] +# No explanation for this apart from different GPU back ends or the like. +# The tests could be moved to WPT and use fuzzy matching. +crbug.com/1329571 [ Mac11 ] paint/overflow/transformed-video-clipping.html [ Failure Pass ] +crbug.com/1329571 [ Linux ] paint/overflow/transformed-video-clipping.html [ Failure Pass ] + # ====== Paint team owned tests to here ====== # WPT speculative-parsing tests failing @@ -1574,6 +1579,7 @@ virtual/layout_ng_table_frag/external/wpt/css/css-break/table/break-before-table-cell-child.html [ Pass ] virtual/layout_ng_table_frag/external/wpt/css/css-break/table/table-cell-expansion-003.html [ Pass ] virtual/layout_ng_table_frag/external/wpt/css/css-break/table/table-col-paint-htb-ltr.html [ Pass ] +virtual/layout_ng_table_frag/external/wpt/css/css-break/table/table-collapsed-borders-paint-at-boundary.tentative.html [ Pass ] virtual/layout_ng_table_frag/external/wpt/css/css-break/table/table-collapsed-borders-paint-htb-ltr.html [ Pass ] virtual/layout_ng_table_frag/external/wpt/css/css-break/table/table-collapsed-borders-paint-vlr-rtl.html [ Pass ] virtual/layout_ng_table_frag/external/wpt/css/css-break/table/table-collapsed-borders-paint-vrl-ltr.html [ Pass ] @@ -3816,6 +3822,7 @@ crbug.com/1078927 external/wpt/css/css-break/table/break-before-table-cell-child.html [ Failure ] crbug.com/1078927 external/wpt/css/css-break/table/table-cell-expansion-003.html [ Failure ] crbug.com/1078927 external/wpt/css/css-break/table/table-col-paint-htb-ltr.html [ Failure ] +crbug.com/1078927 external/wpt/css/css-break/table/table-collapsed-borders-paint-at-boundary.tentative.html [ Failure ] crbug.com/1078927 external/wpt/css/css-break/table/table-collapsed-borders-paint-htb-ltr.html [ Failure ] crbug.com/1078927 external/wpt/css/css-break/table/table-collapsed-borders-paint-vlr-rtl.html [ Failure ] crbug.com/1078927 external/wpt/css/css-break/table/table-collapsed-borders-paint-vrl-ltr.html [ Failure ] @@ -5890,6 +5897,8 @@ crbug.com/1215949 external/wpt/pointerevents/pointerevent_iframe-touch-action-none_touch.html [ Pass Timeout ] crbug.com/1216139 http/tests/devtools/bfcache/bfcache-elements-update.js [ Failure Pass ] +crbug.com/1314739 external/wpt/pointerevents/pointerevent_touch-action-modified_touch.html [ Timeout ] + # Sheriff 2021-06-10 crbug.com/1177996 [ Mac10.15 ] storage/websql/database-lock-after-reload.html [ Failure Pass ] @@ -6917,3 +6926,4 @@ # Sheriff 2022-05-26 crbug.com/1322004 http/tests/inspector-protocol/conversion/insecure-subresource.js [ Pass Timeout ] +crbug.com/1329596 virtual/gpu-rasterization/images/jpeg-with-non-interleaved-dc-channels.html [ Failure Pass ]
diff --git a/third_party/blink/web_tests/external/wpt/css/css-break/table/table-collapsed-borders-paint-at-boundary-ref.html b/third_party/blink/web_tests/external/wpt/css/css-break/table/table-collapsed-borders-paint-at-boundary-ref.html new file mode 100644 index 0000000..04d6434 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-break/table/table-collapsed-borders-paint-at-boundary-ref.html
@@ -0,0 +1,22 @@ +<!DOCTYPE html> +<style> +.multicol { + width: 500px; + height: 100px; + columns: 5; + column-fill: auto; + gap: 10px; + padding: 10px; + border: solid 3px; +} +</style> +<div class="multicol"> + <div style="background: dodgerblue; height: 150px;"></div> + <div style="height: 35px; border: solid 10px lime; border-bottom-width: 5px; margin-left: 2.5px; margin-right: 2.5px;"></div> + <div style="height: 95px; border: solid black; border-width: 0 10px 5px 15px; margin-right: 2.5px;"> + <div style="border-top: solid lime 5px;"></div> + </div> + <div style="height: 5px; background: black; border-right: solid blue 15px; margin-left: 2.5px;"></div> + <div style="height: 40px; border: solid blue; border-width: 0 15px 10px 10px; margin-left: 2.5px;"></div> + <div style="height: 40px; border: solid blue; border-width: 0 10px 5px 10px; margin-left: 2.5px; margin-right: 2.5px;"></div> + <div style="height: 70px; border: solid blue; border-width: 5px 10px 10px 10px; margin-left: 2.5px; margin-right: 2.5px;"></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-break/table/table-collapsed-borders-paint-at-boundary.tentative.html b/third_party/blink/web_tests/external/wpt/css/css-break/table/table-collapsed-borders-paint-at-boundary.tentative.html new file mode 100644 index 0000000..0227b571 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-break/table/table-collapsed-borders-paint-at-boundary.tentative.html
@@ -0,0 +1,39 @@ +<!DOCTYPE html> +<link rel="match" href="table-collapsed-borders-paint-at-boundary-ref.html"> +<link rel="help" href="https://drafts.csswg.org/css-tables-3/#fragmentation"> +<link rel="help" href="https://drafts.csswg.org/css-tables-3/#rendering"> +<style> +.multicol { + width: 500px; + height: 100px; + columns: 5; + column-fill: auto; + gap: 10px; + padding: 10px; + border: solid 3px; +} +</style> +<div class="multicol"> + <table style="border-collapse: collapse; width: 100%;"> + <caption style="background: dodgerblue; height: 150px;"></caption> + <tbody> + <tr style="height: 45px;"> + <td style="border: solid 10px lime;"></td> + </tr> + <tr style="height: 100px;"> + <td style="border: solid 10px; border-left-width: 15px;"></td> + </tr> + </tbody> + <tbody> + <tr style="height: 50px;"> + <td style="border: solid blue 10px; border-right-width: 15px;"></td> + </tr> + <tr style="height: 50px;"> + <td style="border: solid blue 10px;"></td> + </tr> + <tr style="height: 80px;"> + <td style="border: solid blue 10px;"></td> + </tr> + </tbody> + </table> +</div>
diff --git a/third_party/blink/web_tests/external/wpt/navigation-api/state/cross-document-getState-undefined.html b/third_party/blink/web_tests/external/wpt/navigation-api/state/cross-document-getState-undefined.html new file mode 100644 index 0000000..cbd5cdd5 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/navigation-api/state/cross-document-getState-undefined.html
@@ -0,0 +1,17 @@ +<!doctype html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<iframe id="i" src="/common/blank.html"></iframe> +<script> +async_test(t => { + window.onload = t.step_func(() => { + assert_equals(i.contentWindow.navigation.entries().length, 1); + i.contentWindow.location.href = "?1"; + i.onload = t.step_func_done(() => { + assert_equals(i.contentWindow.navigation.entries().length, 2); + assert_equals(i.contentWindow.navigation.currentEntry.index, 1); + assert_equals(i.contentWindow.navigation.entries()[0].getState(), undefined); + }); + }); +}, "Default behavior for entry.getState() for a non-current cross-document entry"); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/navigation-api/state/cross-document-getState.html b/third_party/blink/web_tests/external/wpt/navigation-api/state/cross-document-getState.html new file mode 100644 index 0000000..aedbc471 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/navigation-api/state/cross-document-getState.html
@@ -0,0 +1,19 @@ +<!doctype html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<iframe id="i" src="/common/blank.html"></iframe> +<script> +async_test(t => { + window.onload = t.step_func(() => { + i.contentWindow.navigation.updateCurrentEntry({ state: { data: "value" } }); + assert_equals(i.contentWindow.navigation.entries().length, 1); + i.contentWindow.location.href = "?1"; + i.onload = t.step_func_done(() => { + assert_equals(i.contentWindow.navigation.entries().length, 2); + assert_equals(i.contentWindow.navigation.currentEntry.index, 1); + assert_not_equals(i.contentWindow.navigation.entries()[0].getState(), undefined); + assert_equals(i.contentWindow.navigation.entries()[0].getState().data, "value"); + }); + }); +}, "entry.getState() still works for a non-current cross-document entry"); +</script>
diff --git a/third_party/ipcz/include/ipcz/ipcz.h b/third_party/ipcz/include/ipcz/ipcz.h index d363d388..c8c3b53 100644 --- a/third_party/ipcz/include/ipcz/ipcz.h +++ b/third_party/ipcz/include/ipcz/ipcz.h
@@ -196,14 +196,13 @@ typedef uint32_t IpczTransportActivityFlags; // If set, the driver encountered an unrecoverable error using the transport and -// ipcz should discard it. This also implies that the driver will not invoke the -// activity handler again for the same transport. In such cases, ipcz does not -// invoke DeactivateTransport(), as the transport's deactivation is implied by -// the error notification. +// ipcz should discard it. Note that the driver is free to issue such +// notifications many times as long as it remans active, but ipcz will generally +// request deactivation ASAP once an error is signaled. #define IPCZ_TRANSPORT_ACTIVITY_ERROR IPCZ_FLAG_BIT(0) // When ipcz wants to deactivate a transport, it invokes the driver's -// DeactivateTransport function. Once the driver has finished any clean up and +// DeactivateTransport() function. Once the driver has finished any clean up and // can ensure that the transport's activity handler will no longer be invoked, // it must then invoke the activity handler one final time with this flag set. // This finalizes deactivation and allows ipcz to free any associated resources. @@ -224,12 +223,14 @@ // // If the driver encounters an unrecoverable error while performing I/O on the // transport, it should invoke this with the IPCZ_TRANSPORT_ACTIVITY_ERROR flag -// to instigate immediate destruction of the transport. This implies that the -// driver will not invoke this function ever again for `transport`, and that the -// transport is automatically deactivated without an explicit call to the -// driver's DeactivateTransport() function. +// to instigate deactivation of the transport by ipcz via a subsequent +// DeactivateTransport() call. // // `options` is currently unused and must be null. +// +// NOTE: It is the driver's responsibility to ensure that calls to this function +// for the same value of `transport` are mututally exclusive. Overlapping calls +// are unsafe and will result in undefined behavior. typedef IpczResult(IPCZ_API* IpczTransportActivityHandler)( IpczHandle transport, // in const void* data, // in @@ -395,10 +396,15 @@ uint32_t flags, // in const void* options); // in - // Called by ipcz to deactivate a transport. Once this returns successfully, - // the driver must make no further calls into this transport's activity - // handler. ipcz may continue to use the transport for outgoing transmissions - // until the driver's Close() is also called on `driver_transport`. + // Called by ipcz to deactivate a transport. The driver does not need to + // complete deactivation synchronously, but it must begin to deactivate the + // transport and must invoke the transport's activity handler one final time + // with IPCZ_TRANSPORT_ACTIVITY_DEACTIVATED once finished. Beyond that point, + // the activity handler must no longer be invoked for that transport. + // + // Note that even after deactivatoin, ipcz may continue to call into the + // transport until it's closed with an explicit call to the driver's Close() + // by ipcz. IpczResult(IPCZ_API* DeactivateTransport)( IpczDriverHandle driver_transport, // in uint32_t flags, // in
diff --git a/third_party/ipcz/src/reference_drivers/single_process_reference_driver.cc b/third_party/ipcz/src/reference_drivers/single_process_reference_driver.cc index 3eab5f0..888d4f5a 100644 --- a/third_party/ipcz/src/reference_drivers/single_process_reference_driver.cc +++ b/third_party/ipcz/src/reference_drivers/single_process_reference_driver.cc
@@ -35,30 +35,97 @@ IpczTransportActivityHandler activity_handler) : transport_(transport), activity_handler_(activity_handler) {} - IpczResult Notify(absl::Span<const uint8_t> data, - absl::Span<const IpczDriverHandle> handles) { - IpczResult result = - activity_handler_(transport_, data.data(), data.size(), handles.data(), - handles.size(), IPCZ_NO_FLAGS, nullptr); - if (result != IPCZ_RESULT_OK && result != IPCZ_RESULT_UNIMPLEMENTED) { - NotifyError(); - } - return result; + void Notify(absl::Span<const uint8_t> data, + absl::Span<const IpczDriverHandle> handles) { + DoNotify(IPCZ_NO_FLAGS, data, handles); } - IpczResult NotifyError() { - return activity_handler_(transport_, nullptr, 0, nullptr, 0, - IPCZ_TRANSPORT_ACTIVITY_ERROR, nullptr); - } + void NotifyError() { DoNotify(IPCZ_TRANSPORT_ACTIVITY_ERROR); } private: ~TransportWrapper() override { - activity_handler_(transport_, nullptr, 0, nullptr, 0, - IPCZ_TRANSPORT_ACTIVITY_DEACTIVATED, nullptr); + // Since this is destruction, we can safely assume the invocation will be + // exclusive. Otherwise someone is mismanaging a reference count or has + // a UAF bug. + DoNotifyExclusive(IPCZ_TRANSPORT_ACTIVITY_DEACTIVATED, {}, {}); + } + + // Helper to serialize the invocation of potentially overlapping or reentrant + // notifications from this transport. + void DoNotify(IpczTransportActivityFlags flags, + absl::Span<const uint8_t> data = {}, + absl::Span<const IpczDriverHandle> handles = {}) { + { + absl::MutexLock lock(&mutex_); + if (in_notification_) { + DeferredNotification notification = {.flags = flags}; + if (!data.empty()) { + notification.data = std::vector<uint8_t>(data.begin(), data.end()); + } + if (!handles.empty()) { + notification.handles = + std::vector<IpczDriverHandle>(handles.begin(), handles.end()); + } + deferred_notifications_.push_back(std::move(notification)); + return; + } + + in_notification_ = true; + } + + DoNotifyExclusive(flags, data, handles); + + // Now flush any notifications that queued while this one was in progress. + // This continues until we complete an iteration with no new notifications + // being queued. + for (;;) { + std::vector<DeferredNotification> notifications; + { + absl::MutexLock lock(&mutex_); + if (deferred_notifications_.empty()) { + in_notification_ = false; + return; + } + + notifications.swap(deferred_notifications_); + } + + for (const auto& n : notifications) { + DoNotifyExclusive(n.flags, n.data, n.handles); + } + } + } + + // Invokes the activity handler unguarded. The caller must ensure that this is + // mututally exclusive with any other invocation of the method. + void DoNotifyExclusive(IpczTransportActivityFlags flags, + absl::Span<const uint8_t> data, + absl::Span<const IpczDriverHandle> handles) { + const IpczResult result = activity_handler_( + transport_, data.empty() ? nullptr : data.data(), data.size(), + handles.empty() ? nullptr : handles.data(), handles.size(), flags, + nullptr); + if (result != IPCZ_RESULT_OK && result != IPCZ_RESULT_UNIMPLEMENTED) { + NotifyError(); + } } const IpczHandle transport_; const IpczTransportActivityHandler activity_handler_; + + // Queues copies of any pending notifications which were issued while another + // notification was already in progress, either concurrently or reentrantly. + // The queue is always flushed completely as the active notification stack + // unwinds. + struct DeferredNotification { + IpczTransportActivityFlags flags; + std::vector<uint8_t> data; + std::vector<IpczDriverHandle> handles; + }; + absl::Mutex mutex_; + bool in_notification_ ABSL_GUARDED_BY(mutex_) = false; + std::vector<DeferredNotification> deferred_notifications_ + ABSL_GUARDED_BY(mutex_); }; struct SavedMessage {
diff --git a/third_party/r8/3pp/fetch.py b/third_party/r8/3pp/fetch.py index 3d14dfa..e01ff54 100755 --- a/third_party/r8/3pp/fetch.py +++ b/third_party/r8/3pp/fetch.py
@@ -5,8 +5,10 @@ import argparse import datetime +import hashlib import json import os +import pathlib import urllib.request # I have arbitrarily chosen 100 as a number much more than the number of commits @@ -55,13 +57,29 @@ return None +def compute_patch_hash(): + this_dir = pathlib.Path(__file__).parent + md5 = hashlib.md5() + for p in sorted(this_dir.glob('patches/*.patch')): + md5.update(p.read_bytes()) + # Include install.py so that it triggers changes as well. + md5.update((this_dir / 'install.sh').read_bytes()) + # Shorten to avoid really long version strings. Given the low number of patch + # files, 10 digits is more than sufficient. + return md5.hexdigest()[:10] + + def do_latest(): commit_hash = get_commit_before_today() assert commit_hash is not None - print(commit_hash) + patch_hash = compute_patch_hash() + # Include hash of patch files so that 3pp bot will create a new version when + # they change. + print(f'{commit_hash}-{patch_hash}') -def get_download_url(sha): +def get_download_url(version): + sha = version.split('-')[0] partial_manifest = { 'url': [_ARCHIVE_URL.format(sha)], 'ext': '.tar.gz', @@ -71,7 +89,7 @@ def main(): ap = argparse.ArgumentParser() - sub = ap.add_subparsers() + sub = ap.add_subparsers(required=True) latest = sub.add_parser("latest") latest.set_defaults(func=do_latest)
diff --git a/tools/clang/scripts/update.py b/tools/clang/scripts/update.py index 43cf1e36..3f89c4b 100755 --- a/tools/clang/scripts/update.py +++ b/tools/clang/scripts/update.py
@@ -35,7 +35,7 @@ # https://chromium.googlesource.com/chromium/src/+/main/docs/updating_clang.md # Reverting problematic clang rolls is safe, though. # This is the output of `git describe` and is usable as a commit-ish. -CLANG_REVISION = 'llvmorg-15-init-10717-ge00cbbec' +CLANG_REVISION = 'llvmorg-15-init-11359-gca27f3e3' CLANG_SUB_REVISION = 1 PACKAGE_VERSION = '%s-%s' % (CLANG_REVISION, CLANG_SUB_REVISION)
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 14fb5533..3ad316d8 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -4152,7 +4152,7 @@ <int value="139" label="Terminated by SIGSEGV"> MINIJAIL_ERR_SIG_BASE + SIGSEGV from libminijail </int> - <int value="251" label="Cannot mount file in mount namespace"> + <int value="251" label="Cannot bind-mount file"> MINIJAIL_ERR_MOUNT from libminijail </int> <int value="253" label="Seccomp violation"> @@ -22474,6 +22474,45 @@ <int value="19" label="Failed to clean up ephemeral cryptohome"/> </enum> +<enum name="CryptohomeErrorHashed"> +<!-- + This enum is intended to be populated automatically by platform2/src/cryptohome/error/tool/location_db.py. It only populate values that indeed occurs in the wild, and the set of such values is gathered from the logs. + + The labels are of the format: <Error Location>/<Error Location Enum Value> ... + Whereby Error Location and enum values are defined in platform2/cryptohome/error/locations.h + --> + + <int value="706395249" + label="kLocUserDataAuthSessionNotFoundInExtendAuthSession/288"/> + <int value="4104955507" + label="kLocUserDataAuthSessionNotFoundInAuthAuthSession/286"/> +</enum> + +<enum name="CryptohomeErrorLocation"> +<!-- + This enum is intended to be populated automatically by platform2/src/cryptohome/error/tool/location_db.py. It populates all values found in the cryptohome code base. + + The labels are the Cryptohome Error Location enum defined in platform2/cryptohome/error/locations.h + --> + + <int value="286" label="kLocUserDataAuthSessionNotFoundInAuthAuthSession"/> + <int value="288" label="kLocUserDataAuthSessionNotFoundInExtendAuthSession"/> +</enum> + +<enum name="CryptohomeErrorLocationWithTPMError"> +<!-- + This enum is intended to be populated automatically by platform2/src/cryptohome/error/tool/location_db.py. It populates values that indeed occurs in the wild, and the set of such values is gathered through actual UMA data. + + The labels are of the format: <Error Location>-<TPM Error Code> + Whereby Error Location are defined in platform2/cryptohome/error/locations.h + --> + + <int value="12845195" + label="kLocTpmAuthBlockUtilsGetPubkeyFailedInPubkeyHash-TPM_RC_HANDLE"/> + <int value="12845218" + label="kLocTpmAuthBlockUtilsGetPubkeyFailedInPubkeyHash-TPM_RC_BAD_AUTH"/> +</enum> + <enum name="CryptohomeFetchUssExperimentConfigStatus"> <int value="0" label="Enabled"/> <int value="1" label="Disabled"/> @@ -42709,36 +42748,33 @@ <enum name="FuseArchiveError"> <int value="0" label="Success">EXIT_SUCCESS</int> - <int value="1" label="Generic Failure">EXIT_CODE_GENERIC_FAILURE</int> - <int value="11" label="Cannot Open Archive"> - EXIT_CODE_CANNOT_OPEN_ARCHIVE - </int> - <int value="20" label="Passphrase Required"> - EXIT_CODE_PASSPHRASE_REQUIRED - </int> - <int value="21" label="Passphrase Incorrect"> - EXIT_CODE_PASSPHRASE_INCORRECT - </int> - <int value="22" label="Passphrase Not Supported"> + <int value="1" label="Generic error">EXIT_CODE_GENERIC_FAILURE</int> + <int value="11" label="Cannot open">EXIT_CODE_CANNOT_OPEN_ARCHIVE</int> + <int value="20" label="Missing password">EXIT_CODE_PASSPHRASE_REQUIRED</int> + <int value="21" label="Bad password">EXIT_CODE_PASSPHRASE_INCORRECT</int> + <int value="22" label="Encryption method not supported"> EXIT_CODE_PASSPHRASE_NOT_SUPPORTED </int> - <int value="30" label="Invalid Archive">EXIT_CODE_INVALID_RAW_ARCHIVE</int> - <int value="31" label="Invalid Archive Header"> + <int value="30" label="Invalid archive">EXIT_CODE_INVALID_RAW_ARCHIVE</int> + <int value="31" label="Invalid archive header"> EXIT_CODE_INVALID_ARCHIVE_HEADER </int> - <int value="32" label="Invalid Archive Contents"> + <int value="32" label="Invalid archive contents"> EXIT_CODE_INVALID_ARCHIVE_CONTENTS </int> <int value="132" label="Terminated by SIGILL"> - MINIJAIL_ERR_SIG_BASE + SIGILL from libminijail + MINIJAIL_ERR_SIG_BASE (128) + SIGILL (4) from libminijail </int> <int value="134" label="Terminated by SIGABRT"> - MINIJAIL_ERR_SIG_BASE + SIGABRT from libminijail + MINIJAIL_ERR_SIG_BASE (128) + SIGABRT (6) from libminijail </int> <int value="139" label="Terminated by SIGSEGV"> - MINIJAIL_ERR_SIG_BASE + SIGSEGV from libminijail + MINIJAIL_ERR_SIG_BASE (128) + SIGSEGV (11) from libminijail </int> - <int value="251" label="Cannot mount file in mount namespace"> + <int value="143" label="Terminated by SIGTERM"> + MINIJAIL_ERR_SIG_BASE (128) + SIGTERM (15) from libminijail + </int> + <int value="251" label="Cannot bind-mount file"> MINIJAIL_ERR_MOUNT from libminijail </int> <int value="253" label="Seccomp violation"> @@ -42747,38 +42783,56 @@ </enum> <enum name="FuseZipError"> - <int value="0" label="Success">Hardcoded in fuse-zip</int> + <int value="0" label="Success">EXIT_SUCCESS</int> <int value="11" label="Multipart ZIP"> - ZIP_ER_BASE from fuse-zip + ZIP_ER_MULTIDISK from libzip + ZIP_ER_BASE (10) from fuse-zip + ZIP_ER_MULTIDISK (1) from libzip </int> <int value="15" label="Cannot read"> - ZIP_ER_BASE from fuse-zip + ZIP_ER_READ from libzip + ZIP_ER_BASE (10) from fuse-zip + ZIP_ER_READ (5) from libzip + </int> + <int value="19" label="No such file"> + ZIP_ER_BASE (10) from fuse-zip + ZIP_ER_NOENT (9) from libzip </int> <int value="21" label="Cannot open"> - ZIP_ER_BASE from fuse-zip + ZIP_ER_OPEN from libzip + ZIP_ER_BASE (10) from fuse-zip + ZIP_ER_OPEN (11) from libzip + </int> + <int value="23" label="Malloc failure"> + ZIP_ER_BASE (10) from fuse-zip + ZIP_ER_MEMORY (13) from libzip + </int> + <int value="26" label="Compression method not supported"> + ZIP_ER_BASE (10) from fuse-zip + ZIP_ER_COMPNOTSUPP (16) from libzip + </int> + <int value="27" label="Premature end of file"> + ZIP_ER_BASE (10) from fuse-zip + ZIP_ER_EOF (17) from libzip </int> <int value="29" label="Not a ZIP"> - ZIP_ER_BASE from fuse-zip + ZIP_ER_NOZIP from libzip + ZIP_ER_BASE (10) from fuse-zip + ZIP_ER_NOZIP (19) from libzip </int> <int value="31" label="Inconsistent ZIP"> - ZIP_ER_BASE from fuse-zip + ZIP_ER_INCONS from libzip + ZIP_ER_BASE (10) from fuse-zip + ZIP_ER_INCONS (21) from libzip + </int> + <int value="34" label="Encryption method not supported"> + ZIP_ER_BASE (10) from fuse-zip + ZIP_ER_ENCRNOTSUPP (24) from libzip </int> <int value="36" label="Missing password"> - ZIP_ER_BASE from fuse-zip + ZIP_ER_NOPASSWD from libzip + ZIP_ER_BASE (10) from fuse-zip + ZIP_ER_NOPASSWD (26) from libzip </int> <int value="37" label="Bad password"> - ZIP_ER_BASE from fuse-zip + ZIP_ER_WRONGPASSWD from libzip + ZIP_ER_BASE (10) from fuse-zip + ZIP_ER_WRONGPASSWD (27) from libzip </int> <int value="132" label="Terminated by SIGILL"> - MINIJAIL_ERR_SIG_BASE + SIGILL from libminijail + MINIJAIL_ERR_SIG_BASE (128) + SIGILL (4) from libminijail </int> <int value="134" label="Terminated by SIGABRT"> - MINIJAIL_ERR_SIG_BASE + SIGABRT from libminijail + MINIJAIL_ERR_SIG_BASE (128) + SIGABRT (6) from libminijail </int> <int value="139" label="Terminated by SIGSEGV"> - MINIJAIL_ERR_SIG_BASE + SIGSEGV from libminijail + MINIJAIL_ERR_SIG_BASE (128) + SIGSEGV (11) from libminijail </int> - <int value="251" label="Cannot mount file in mount namespace"> + <int value="143" label="Terminated by SIGTERM"> + MINIJAIL_ERR_SIG_BASE (128) + SIGTERM (15) from libminijail + </int> + <int value="251" label="Cannot bind-mount file"> MINIJAIL_ERR_MOUNT from libminijail </int> <int value="253" label="Seccomp violation"> @@ -55221,8 +55275,6 @@ <int value="-1668306615" label="CrostiniUseDlc:enabled"/> <int value="-1667822423" label="ContextMenuGoogleLensChip:disabled"/> <int value="-1666652919" label="MagnifierPanningImprovements:disabled"/> - <int value="-1665720309" - label="ArcNativeBridge64BitSupportExperiment:disabled"/> <int value="-1664795930" label="StorageAccessAPI:disabled"/> <int value="-1664290318" label="ComputePressure:enabled"/> <int value="-1663410466" label="top-document-isolation"/> @@ -56070,8 +56122,6 @@ <int value="-1151615978" label="BorealisBigGl:disabled"/> <int value="-1151476162" label="LacrosMergeIcuDataFile:disabled"/> <int value="-1151014496" label="NearbySharingDeviceContacts:disabled"/> - <int value="-1150881704" - label="ArcNativeBridge64BitSupportExperiment:enabled"/> <int value="-1146814438" label="TabbedAppOverflowMenuIcons:enabled"/> <int value="-1146310028" label="HardwareSecureDecryptionFallback:enabled"/> <int value="-1145905507" label="SendTabToSelfWhenSignedIn:disabled"/> @@ -57531,6 +57581,7 @@ <int value="-167744090" label="EnableHomeLauncher:enabled"/> <int value="-167420098" label="WebBluetoothNewPermissionsBackend:enabled"/> <int value="-165756594" label="enable-touch-feedback"/> + <int value="-165712979" label="AdaptiveChargingForTesting:enabled"/> <int value="-165006916" label="EnableNeuralPalmDetectionFilter:enabled"/> <int value="-164673139" label="ForceShowContinueSection:disabled"/> <int value="-164539906" @@ -58043,6 +58094,7 @@ <int value="178693406" label="LockScreenMediaControls:disabled"/> <int value="179083323" label="HelpAppBackgroundPage:disabled"/> <int value="179871410" label="ui-debug-tools:disabled"/> + <int value="180040169" label="OneGroupPerRenderer:disabled"/> <int value="180074362" label="memory-pressure-thresholds"/> <int value="181150000" label="CrosVmCupsProxy:enabled"/> <int value="182358203" label="AddToHomescreenIPH:enabled"/> @@ -58527,6 +58579,7 @@ <int value="494939785" label="InsecureFormSubmissionInterstitial:disabled"/> <int value="495435958" label="PageInfoAboutThisSiteMoreInfo:enabled"/> <int value="496667708" label="ArcInputOverlay:disabled"/> + <int value="497039057" label="AdaptiveChargingForTesting:disabled"/> <int value="497137719" label="OmniboxVoiceSearchAlwaysVisible:disabled"/> <int value="497150691" label="AssistEmojiEnhanced:disabled"/> <int value="500177932" label="ArcSmartTextSelection:disabled"/> @@ -59401,6 +59454,7 @@ <int value="1077758422" label="LeakDetectionUnauthenticated:disabled"/> <int value="1079032226" label="ParallelDownloading:enabled"/> <int value="1079302639" label="ArcEnableWebAppShare:disabled"/> + <int value="1080108820" label="OneGroupPerRenderer:enabled"/> <int value="1081546525" label="ash-enable-docked-windows"/> <int value="1082054180" label="PersistentWindowBounds:disabled"/> <int value="1082840061" label="LinkDoctorDeprecationAndroid:disabled"/> @@ -80047,15 +80101,18 @@ </int> <int value="24" label="Bad password">ERAR_BAD_PASSWORD from libunrar</int> <int value="132" label="Terminated by SIGILL"> - MINIJAIL_ERR_SIG_BASE + SIGILL from libminijail + MINIJAIL_ERR_SIG_BASE (128) + SIGILL (4) from libminijail </int> <int value="134" label="Terminated by SIGABRT"> - MINIJAIL_ERR_SIG_BASE + SIGABRT from libminijail + MINIJAIL_ERR_SIG_BASE (128) + SIGABRT (6) from libminijail </int> <int value="139" label="Terminated by SIGSEGV"> - MINIJAIL_ERR_SIG_BASE + SIGSEGV from libminijail + MINIJAIL_ERR_SIG_BASE (128) + SIGSEGV (11) from libminijail </int> - <int value="251" label="Cannot mount file in mount namespace"> + <int value="143" label="Terminated by SIGTERM"> + MINIJAIL_ERR_SIG_BASE (128) + SIGTERM (15) from libminijail + </int> + <int value="251" label="Cannot bind-mount file"> MINIJAIL_ERR_MOUNT from libminijail </int> <int value="253" label="Seccomp violation">
diff --git a/tools/metrics/histograms/metadata/METRIC_REVIEWER_OWNERS b/tools/metrics/histograms/metadata/METRIC_REVIEWER_OWNERS index 0c81ee7a..0b0d121 100644 --- a/tools/metrics/histograms/metadata/METRIC_REVIEWER_OWNERS +++ b/tools/metrics/histograms/metadata/METRIC_REVIEWER_OWNERS
@@ -59,6 +59,7 @@ manukh@chromium.org mcrouse@chromium.org mhasank@chromium.org +mjwilson@chromium.org mlippautz@chromium.org mthiesse@chromium.org mutexlox@chromium.org
diff --git a/tools/metrics/histograms/metadata/chromeos/histograms.xml b/tools/metrics/histograms/metadata/chromeos/histograms.xml index 2b9acaa..2d6b6a5 100644 --- a/tools/metrics/histograms/metadata/chromeos/histograms.xml +++ b/tools/metrics/histograms/metadata/chromeos/histograms.xml
@@ -1897,22 +1897,21 @@ </token> </histogram> -<histogram name="ChromeOS.Zram.{HugePageActivityMetric}" units="%" +<histogram name="ChromeOS.Zram.{HugePageActivityMetric}" units="pages" expires_after="2022-11-10"> <owner>ctshao@google.com</owner> <owner>raging@google.com</owner> <owner>bgeffon@chromium.org</owner> <owner>chromeos-memory@google.com</owner> <summary> - Records activity of {HugePageActivityMetric} (i.e., incompressible) in a - period of time. Recorded every 10s from boot to shutdown. Period is the time - between recordings (10s). + Records the {HugePageActivityMetric} in a period of time. Recorded every 10s + from boot to shutdown. Period is the time between recordings (10s). </summary> <token key="HugePageActivityMetric"> <variant name="HugePagesRemoved" - summary="Number of pages removed in a period"/> + summary="number of incompressible(huge) pages removed"/> <variant name="HugePagesStored" - summary="Number of pages added in a period"/> + summary="number of incompressible(huge) pages added"/> </token> </histogram>
diff --git a/tools/metrics/histograms/metadata/cryptohome/histograms.xml b/tools/metrics/histograms/metadata/cryptohome/histograms.xml index d7ab447..cf72dd3 100644 --- a/tools/metrics/histograms/metadata/cryptohome/histograms.xml +++ b/tools/metrics/histograms/metadata/cryptohome/histograms.xml
@@ -214,6 +214,147 @@ <summary>Records the result of triggering disk cleanup.</summary> </histogram> +<histogram name="Cryptohome.Error.AllLocations" enum="CryptohomeErrorLocation" + expires_after="2023-05-01"> + <owner>zuan@chromium.org</owner> + <owner>cros-hwsec+uma@chromium.org</owner> + <summary> + Background context on this histogram: A CryptohomeError in this context + refers to an error that occurred in response to a dbus request to selected + cryptohomed APIs. The set of APIs with this CryptohomeError is generally + those related to authentication, and contains CryptohomeErrorInfo field in + the dbus Reply protobuf. Currently that includes methods that are called + during login. A CryptohomeError consists of a linear stack of + ErrorLocations, each one of them is an actual line in the cryptohomed + codebase which the error passed through, and could have certain attributes, + known as ErrorAction attached to them. The ErrorLocation in the bottom of + the stack could optionally have a TPM Error Code associated, if the source + of error is TPM related. + + For this histogram, for every CryptohomeError that occurs, we individually + report each individual ErrorLocation's corresponding enum value when an + error ocurred. + + This is useful to cryptohome developers in the sense that they'll be able to + know which lines that handle error in cryptohomed has been triggered due to + an error. + </summary> +</histogram> + +<histogram name="Cryptohome.Error.DevUnexpectedState" + enum="CryptohomeErrorLocation" expires_after="2023-05-01"> + <owner>zuan@chromium.org</owner> + <owner>cros-hwsec+uma@chromium.org</owner> + <summary> + Background context on this histogram: A CryptohomeError in this context + refers to an error that occurred in response to a dbus request to selected + cryptohomed APIs. The set of APIs with this CryptohomeError is generally + those related to authentication, and contains CryptohomeErrorInfo field in + the dbus Reply protobuf. Currently that includes methods that are called + during login. A CryptohomeError consists of a linear stack of + ErrorLocations, each one of them is an actual line in the cryptohomed + codebase which the error passed through, and could have certain attributes, + known as ErrorAction attached to them. The ErrorLocation in the bottom of + the stack could optionally have a TPM Error Code associated, if the source + of error is TPM related. + + For this histogram, for every CryptohomeError, we individually report all + ErrorLocation that has the kDevCheckUnexpectedState ErrorAction associated + with it. The kDevCheckUnexpectedState ErrorAction is used by developers when + the developer believes that this error should never occur, so from a + notification standpoint, it functions similar to a DCHECK(), except it never + crashes cryptohome and handles the error in a graceful manner. + + This is useful to cryptohome developers because they'll be alerted when any + of the situations that the developers doesn't expect to occur occurs. + </summary> +</histogram> + +<histogram name="Cryptohome.Error.HashedStack" enum="CryptohomeErrorHashed" + expires_after="2023-05-01"> + <owner>zuan@chromium.org</owner> + <owner>cros-hwsec+uma@chromium.org</owner> + <summary> + Background context on this histogram: A CryptohomeError in this context + refers to an error that occurred in response to a dbus request to selected + cryptohomed APIs. The set of APIs with this CryptohomeError is generally + those related to authentication, and contains CryptohomeErrorInfo field in + the dbus Reply protobuf. Currently that includes methods that are called + during login. A CryptohomeError consists of a linear stack of + ErrorLocations, each one of them is an actual line in the cryptohomed + codebase which the error passed through, and could have certain attributes, + known as ErrorAction attached to them. The ErrorLocation in the bottom of + the stack could optionally have a TPM Error Code associated, if the source + of error is TPM related. + + For this histogram, we take the entire CryptohomeError's linear stack of + ErrorLocation, and hash the entire stack, then we report the hash. The + original stack of ErrorLocation is logged. + + This is useful to cryptohome developers because we're able to classify the + CryptohomeError by the content of the stack, and identify new ways the error + can occur if they do occur. + </summary> +</histogram> + +<histogram name="Cryptohome.Error.LeafErrorWithoutTPM" + enum="CryptohomeErrorLocation" expires_after="2023-05-01"> + <owner>zuan@chromium.org</owner> + <owner>cros-hwsec+uma@chromium.org</owner> + <summary> + Background context on this histogram: A CryptohomeError in this context + refers to an error that occurred in response to a dbus request to selected + cryptohomed APIs. The set of APIs with this CryptohomeError is generally + those related to authentication, and contains CryptohomeErrorInfo field in + the dbus Reply protobuf. Currently that includes methods that are called + during login. A CryptohomeError consists of a linear stack of + ErrorLocations, each one of them is an actual line in the cryptohomed + codebase which the error passed through, and could have certain attributes, + known as ErrorAction attached to them. The ErrorLocation in the bottom of + the stack could optionally have a TPM Error Code associated, if the source + of error is TPM related. + + For this histogram, for every CryptohomeError that occurred, we report the + last ErrorLocation in the stack of ErrorLocation in the CryptohomeError, if + the last ErrorLocation does not have a TPM Error Code associated with it. + + This is useful to cryptohome developers because frequently, the last + ErrorLocation in the stack would be able to uniquely identify the error, and + this histogram doesn't involve hashing, so it would be more convenient for + the developers. + </summary> +</histogram> + +<histogram name="Cryptohome.Error.LeafErrorWithTPM" + enum="CryptohomeErrorLocationWithTPMError" expires_after="2023-05-01"> + <owner>zuan@chromium.org</owner> + <owner>cros-hwsec+uma@chromium.org</owner> + <summary> + Background context on this histogram: A CryptohomeError in this context + refers to an error that occurred in response to a dbus request to selected + cryptohomed APIs. The set of APIs with this CryptohomeError is generally + those related to authentication, and contains CryptohomeErrorInfo field in + the dbus Reply protobuf. Currently that includes methods that are called + during login. A CryptohomeError consists of a linear stack of + ErrorLocations, each one of them is an actual line in the cryptohomed + codebase which the error passed through, and could have certain attributes, + known as ErrorAction attached to them. The ErrorLocation in the bottom of + the stack could optionally have a TPM Error Code associated, if the source + of error is TPM related. + + For this histogram, for every CryptohomeError that occurred, we report the + last ErrorLocation and the second last ErrorLocation in the CryptohomeError, + if the last ErrorLocation have a TPM Error Code associated with it. The + upper and lower 16-bit value of the reported value contains the second last + ErrorLocation and the TPM Error Code, correspondingly. + + This is useful to cryptohome developers because frequently, the last and + second last ErrorLocation in the stack would be able to uniquely identify + the error, and this histogram doesn't involve hashing, so it woul dbe more + convenient for the developers. + </summary> +</histogram> + <histogram name="Cryptohome.Errors" enum="CryptohomeError" expires_after="2022-09-25"> <owner>apronin@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/media/histograms.xml b/tools/metrics/histograms/metadata/media/histograms.xml index 15691e8..11d9b43 100644 --- a/tools/metrics/histograms/metadata/media/histograms.xml +++ b/tools/metrics/histograms/metadata/media/histograms.xml
@@ -665,7 +665,7 @@ </histogram> <histogram name="Media.Audio.Output.Win.{AudioOutputMethod}Error" - enum="Hresult" expires_after="M103"> + enum="Hresult" expires_after="M107"> <owner>dalecurtis@chromium.org</owner> <owner>media-dev@chromium.org</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/stability/histograms.xml b/tools/metrics/histograms/metadata/stability/histograms.xml index 711f3117..f5f54fe 100644 --- a/tools/metrics/histograms/metadata/stability/histograms.xml +++ b/tools/metrics/histograms/metadata/stability/histograms.xml
@@ -22,6 +22,16 @@ <histograms> +<histogram name="Stability.Android.MinidumpUploadingTime" units="ms" + expires_after="2022-11-30"> + <owner>shaktisahu@chromium.org</owner> + <owner>src/components/minidump_uploader/OWNERS</owner> + <summary> + Records the time (uptimeMillis) taken by a minidump uploading task to + complete. Recorded when the task finished callback is invoked. + </summary> +</histogram> + <histogram name="Stability.Android.OomKillReverseRank" units="rank" expires_after="2022-11-13"> <owner>boliu@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/web_audio/OWNERS b/tools/metrics/histograms/metadata/web_audio/OWNERS index dd691ad6..91c0afc 100644 --- a/tools/metrics/histograms/metadata/web_audio/OWNERS +++ b/tools/metrics/histograms/metadata/web_audio/OWNERS
@@ -2,4 +2,5 @@ # Prefer sending CLs to the owners listed below. # Use chromium-metrics-reviews@google.com as a backup. -hongchan@chromium.org \ No newline at end of file +hongchan@chromium.org +mjwilson@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 97a5b07..3b80a51 100644 --- a/tools/perf/core/perfetto_binary_roller/binary_deps.json +++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -5,24 +5,24 @@ "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux_arm64/49b4b5dcbc312d8d2c3751cf29238b8efeb4e494/trace_processor_shell" }, "win": { - "hash": "29b498fe190b44dbb5f5297e6f2723e6f04691af", - "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/1b28e4be5bc4b001da649e1432c196f5f4103d2a/trace_processor_shell.exe" + "hash": "bf1e019be579d5602acdd94a058aa88379866c1d", + "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/105e4c338e523b1974bfffb2422262736b91336e/trace_processor_shell.exe" }, "linux_arm": { "hash": "58893933be305d3bfe0a72ebebcacde2ac3ca893", "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux_arm/49b4b5dcbc312d8d2c3751cf29238b8efeb4e494/trace_processor_shell" }, "mac": { - "hash": "b32506de4326c12ad01743553237c74d0e3e6836", - "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/mac/1b28e4be5bc4b001da649e1432c196f5f4103d2a/trace_processor_shell" + "hash": "0033d86be5f8a2574ade41cf2ab22286b09e1699", + "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/mac/105e4c338e523b1974bfffb2422262736b91336e/trace_processor_shell" }, "mac_arm64": { "hash": "e1ad4861384b06d911a65f035317914b8cc975c6", "full_remote_path": "perfetto-luci-artifacts/v25.0/mac-arm64/trace_processor_shell" }, "linux": { - "hash": "5ee364b52fed5a2035c89230d0cbb4f1b7b21950", - "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/1b28e4be5bc4b001da649e1432c196f5f4103d2a/trace_processor_shell" + "hash": "a69c29ff4a09e03fde1c602209535753632a1965", + "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/fecea55a5bc59c274e8200d06cd68260832d5591/trace_processor_shell" } }, "power_profile.sql": {
diff --git a/tools/style_variable_generator/tests/style_variable_generator_test.py b/tools/style_variable_generator/tests/style_variable_generator_test.py index 29884000..c229ed1 100755 --- a/tools/style_variable_generator/tests/style_variable_generator_test.py +++ b/tools/style_variable_generator/tests/style_variable_generator_test.py
@@ -36,7 +36,7 @@ def AddJSONFilesToModel(self, files): relpaths_from_cwd = [ os.path.relpath(os.path.join(os.path.dirname(__file__), f), - os.getcwd()) for f in files + os.getcwd()).replace('\\', '/') for f in files ] self.generator.AddJSONFilesToModel(relpaths_from_cwd)
diff --git a/ui/file_manager/file_manager/background/js/volume_manager_impl.js b/ui/file_manager/file_manager/background/js/volume_manager_impl.js index 1b72789..a1e2b0e 100644 --- a/ui/file_manager/file_manager/background/js/volume_manager_impl.js +++ b/ui/file_manager/file_manager/background/js/volume_manager_impl.js
@@ -268,7 +268,7 @@ case VolumeManagerCommon.VolumeError.NEED_PASSWORD: case VolumeManagerCommon.VolumeError.CANCELLED: default: - console.error('Cannot mount (redacted):', status); + console.warn('Cannot mount (redacted):', status); console.debug(`Cannot mount '${sourcePath}':`, status); this.finishRequest_(requestKey, status); return; @@ -299,7 +299,7 @@ } default: - console.error('Cannot unmount (redacted):', status); + console.warn('Cannot unmount (redacted):', status); console.debug(`Cannot unmount '${volumeId}':`, status); this.finishRequest_(requestKey, status); return;
diff --git a/ui/file_manager/file_manager/background/js/volume_manager_unittest.m.js b/ui/file_manager/file_manager/background/js/volume_manager_unittest.m.js index 2853f3f8..7e95a63b 100644 --- a/ui/file_manager/file_manager/background/js/volume_manager_unittest.m.js +++ b/ui/file_manager/file_manager/background/js/volume_manager_unittest.m.js
@@ -302,6 +302,52 @@ reportPromise(test(), callback); } +export function testCancelMountingArchive(callback) { + const test = async () => { + // Set states of mock fileManagerPrivate APIs. + const mountSourcePath = '/usr/local/home/test/Downloads/foobar.zip'; + chrome.fileManagerPrivate.mountSourcePath_ = mountSourcePath; + chrome.fileManagerPrivate.fileSystemMap_['archive:foobar.zip'] = + new MockFileSystem('archive:foobar.zip'); + + const volumeManager = await volumeManagerFactory.getInstance(); + + // Drive + Downloads + Android. + const numberOfVolumes = 3; + await waitAllVolumes(volumeManager); + + setTimeout( + () => mockChrome.fileManagerPrivate.onMountCompleted.dispatchEvent({ + eventType: 'mount', + status: VolumeManagerCommon.VolumeError.CANCELLED, + volumeMetadata: { + volumeId: null, + volumeLabel: null, + volumeType: null, + isReadOnly: null, + sourcePath: mountSourcePath, + profile: null, + configurable: null, + watchable: null, + source: null, + }, + })); + + try { + await volumeManager.mountArchive( + 'filesystem:chrome-extension://extensionid/external/' + + 'Downloads-test/foobar.zip', + 'My Password'); + } catch (error) { + assertEquals(error, VolumeManagerCommon.VolumeError.CANCELLED); + } + + assertEquals(numberOfVolumes, volumeManager.volumeInfoList.length); + }; + + reportPromise(test(), callback); +} + export async function testGetCurrentProfileVolumeInfo(done) { const volumeManager = await volumeManagerFactory.getInstance(); await waitAllVolumes(volumeManager);
diff --git a/ui/file_manager/file_manager/foreground/js/file_manager_commands.js b/ui/file_manager/file_manager/foreground/js/file_manager_commands.js index e9e4e27..bf7f7c3 100644 --- a/ui/file_manager/file_manager/foreground/js/file_manager_commands.js +++ b/ui/file_manager/file_manager/foreground/js/file_manager_commands.js
@@ -689,7 +689,7 @@ try { await fileManager.volumeManager.unmount(volume); } catch (error) { - console.error(`Cannot unmount (redacted):`, error); + console.warn('Cannot unmount (redacted):', error); console.debug(`Cannot unmount '${volume.volumeId}':`, error); if (error != VolumeManagerCommon.VolumeError.PATH_NOT_MOUNTED) { errorCallback(volume.volumeType);
diff --git a/ui/file_manager/file_manager/foreground/js/file_tasks.js b/ui/file_manager/file_manager/foreground/js/file_tasks.js index a08fb0c..69b82e0 100644 --- a/ui/file_manager/file_manager/foreground/js/file_tasks.js +++ b/ui/file_manager/file_manager/foreground/js/file_tasks.js
@@ -494,7 +494,7 @@ verbButtonLabel = 'OPEN_WITH_VERB_BUTTON_LABEL'; break; default: - console.error('Invalid task verb: ' + task.verb + '.'); + console.error('Invalid task verb: ' + task.verb); } if (verbButtonLabel) { task.label = loadTimeData.getStringF(verbButtonLabel, task.title); @@ -1031,7 +1031,7 @@ item.state = ProgressItemState.ERROR; this.progressCenter_.updateItem(item); - console.error('Cannot mount (redacted):', error); + console.warn('Cannot mount (redacted):', error); console.debug(`Cannot mount '${url}':`, error); } }
diff --git a/ui/native_theme/BUILD.gn b/ui/native_theme/BUILD.gn index 33ca89b..051ecc99 100644 --- a/ui/native_theme/BUILD.gn +++ b/ui/native_theme/BUILD.gn
@@ -124,7 +124,7 @@ test("native_theme_unittests") { use_xvfb = use_xvfb_in_this_config - sources = [] + sources = [ "native_theme_features_unittest.cc" ] if (use_aura) { sources += [ "native_theme_aura_unittest.cc" ]
diff --git a/ui/native_theme/native_theme_features.cc b/ui/native_theme/native_theme_features.cc index 502de5b68..77a70108 100644 --- a/ui/native_theme/native_theme_features.cc +++ b/ui/native_theme/native_theme_features.cc
@@ -24,6 +24,14 @@ const base::Feature kOverlayScrollbar{"OverlayScrollbar", kOverlayScrollbarFeatureState}; +// Fluent scrollbars aim to modernize the Chromium scrollbars (both overlay +// and non-overlay) to fit the Windows 11 Fluent design language. For now, +// the feature will only support Windows platform and can be later available +// on Linux as well. The feature is currently in development and disabled +// by default. +const base::Feature kFluentScrollbar{"FluentScrollbar", + base::FEATURE_DISABLED_BY_DEFAULT}; + } // namespace features namespace ui { @@ -32,4 +40,14 @@ return base::FeatureList::IsEnabled(features::kOverlayScrollbar); } +bool IsFluentScrollbarEnabled() { +// Currently, the feature is only supported on Windows. +#if BUILDFLAG(IS_WIN) + return IsOverlayScrollbarEnabled() && + base::FeatureList::IsEnabled(features::kFluentScrollbar); +#else + return false; +#endif +} + } // namespace ui
diff --git a/ui/native_theme/native_theme_features.h b/ui/native_theme/native_theme_features.h index 85e8985..4a686b3 100644 --- a/ui/native_theme/native_theme_features.h +++ b/ui/native_theme/native_theme_features.h
@@ -13,12 +13,14 @@ namespace features { NATIVE_THEME_EXPORT extern const base::Feature kOverlayScrollbar; +NATIVE_THEME_EXPORT extern const base::Feature kFluentScrollbar; } // namespace features namespace ui { NATIVE_THEME_EXPORT bool IsOverlayScrollbarEnabled(); +NATIVE_THEME_EXPORT bool IsFluentScrollbarEnabled(); } // namespace ui
diff --git a/ui/native_theme/native_theme_features_unittest.cc b/ui/native_theme/native_theme_features_unittest.cc new file mode 100644 index 0000000..9aecc882 --- /dev/null +++ b/ui/native_theme/native_theme_features_unittest.cc
@@ -0,0 +1,46 @@ +// 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 "ui/native_theme/native_theme_features.h" + +#include "base/test/scoped_feature_list.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace ui { + +// The unit test verifies that the Fluent scrollbar feature is enabled +// on Windows when both overlay and fluent scrollbar base features are enabled. +TEST(FluentScrollbarFeatureStateTest, Enabled) { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitWithFeatures( + {features::kOverlayScrollbar, features::kFluentScrollbar}, {}); + + EXPECT_TRUE(IsOverlayScrollbarEnabled()); +#if BUILDFLAG(IS_WIN) + EXPECT_TRUE(IsFluentScrollbarEnabled()); +#else + EXPECT_FALSE(IsFluentScrollbarEnabled()); +#endif +} + +// The unit test verifies that the Fluent scrollbar feature is disabled when +// kOverlayScrollbar base feature is disabled no matter the state of +// kFluentScrollbar. +TEST(FluentScrollbarFeatureStateTest, Disabled) { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitWithFeatures({features::kFluentScrollbar}, + {features::kOverlayScrollbar}); + + EXPECT_FALSE(IsOverlayScrollbarEnabled()); + EXPECT_FALSE(IsFluentScrollbarEnabled()); +} + +// The unit test verifies that the Fluent scrollbar feature is disabled +// by default on all platforms. +TEST(FluentScrollbarFeatureStateTest, DisabledByDefault) { + EXPECT_FALSE(base::FeatureList::IsEnabled(features::kFluentScrollbar)); + EXPECT_FALSE(IsFluentScrollbarEnabled()); +} + +} // namespace ui
diff --git a/ui/qt/BUILD.gn b/ui/qt/BUILD.gn index 42c4ed81..a75de440 100644 --- a/ui/qt/BUILD.gn +++ b/ui/qt/BUILD.gn
@@ -88,6 +88,7 @@ deps = [ ":qt_interface", "//base", + "//skia", "//ui/gfx", "//ui/native_theme", "//ui/shell_dialogs",
diff --git a/ui/qt/DEPS b/ui/qt/DEPS index 9542741..bfa0817c 100644 --- a/ui/qt/DEPS +++ b/ui/qt/DEPS
@@ -1,4 +1,5 @@ include_rules = [ + "+third_party/skia", "+ui/gfx", "+ui/shell_dialogs", "+ui/views",
diff --git a/ui/qt/qt_interface.cc b/ui/qt/qt_interface.cc index 71de03b6..c75978a 100644 --- a/ui/qt/qt_interface.cc +++ b/ui/qt/qt_interface.cc
@@ -32,4 +32,38 @@ free(str_); } +Buffer::Buffer() = default; + +Buffer::Buffer(const uint8_t* data, size_t size) + : data_(static_cast<uint8_t*>(malloc(size))), size_(size) { + memcpy(data_, data, size); +} + +Buffer::Buffer(Buffer&& other) { + data_ = other.data_; + size_ = other.size_; + other.data_ = nullptr; + other.size_ = 0; +} + +Buffer& Buffer::operator=(Buffer&& other) { + free(data_); + data_ = other.data_; + size_ = other.size_; + other.data_ = nullptr; + other.size_ = 0; + return *this; +} + +Buffer::~Buffer() { + free(data_); +} + +uint8_t* Buffer::Take() { + uint8_t* data = data_; + data_ = nullptr; + size_ = 0; + return data; +} + } // namespace qt
diff --git a/ui/qt/qt_interface.h b/ui/qt/qt_interface.h index b0b4fb2..569af9e 100644 --- a/ui/qt/qt_interface.h +++ b/ui/qt/qt_interface.h
@@ -7,6 +7,9 @@ // This file shouldn't include any standard C++ headers (directly or indirectly) +#include <stdint.h> +#include <stdlib.h> + namespace qt { // std::string cannot be passed over the library boundary, so this class acts @@ -20,12 +23,33 @@ ~String(); // May be nullptr. - char* c_str() { return str_; } + const char* c_str() const { return str_; } private: char* str_ = nullptr; }; +// A generic bag of bytes. +class Buffer { + public: + Buffer(); + // Creates a copy of `data`. + Buffer(const uint8_t* data, size_t size); + Buffer(Buffer&& other); + Buffer& operator=(Buffer&& other); + ~Buffer(); + + // Take ownership of the data in this buffer (resetting `this`). + uint8_t* Take(); + + uint8_t* data() { return data_; } + size_t size() const { return size_; } + + private: + uint8_t* data_ = nullptr; + size_t size_ = 0; +}; + enum class FontHinting { kDefault, kNone, @@ -47,6 +71,14 @@ int weight; }; +struct Image { + int width = 0; + int height = 0; + float scale = 1.0f; + // The data is stored as ARGB32 (premultiplied). + Buffer data_argb; +}; + class QtInterface { public: class Delegate { @@ -64,6 +96,7 @@ virtual double GetScaleFactor() const = 0; virtual FontRenderParams GetFontRenderParams() const = 0; virtual FontDescription GetFontDescription() const = 0; + virtual Image GetIconForContentType(const String& content_type, int size) = 0; }; } // namespace qt
diff --git a/ui/qt/qt_shim.cc b/ui/qt/qt_shim.cc index 2bac272..89c77435 100644 --- a/ui/qt/qt_shim.cc +++ b/ui/qt/qt_shim.cc
@@ -8,6 +8,9 @@ #include <QApplication> #include <QFont> +#include <QIcon> +#include <QMimeDatabase> +#include <QMimeType> namespace qt { @@ -74,6 +77,26 @@ }; } +Image QtShim::GetIconForContentType(const String& content_type, int size) { + QMimeDatabase db; + for (const char* mime : {content_type.c_str(), "application/octet-stream"}) { + auto mt = db.mimeTypeForName(mime); + for (const auto& name : {mt.iconName(), mt.genericIconName()}) { + auto icon = QIcon::fromTheme(name); + auto pixmap = icon.pixmap(size); + auto image = pixmap.toImage(); + if (image.format() != QImage::Format_ARGB32_Premultiplied) + image = image.convertToFormat(QImage::Format_ARGB32_Premultiplied); + if (auto bytes = image.sizeInBytes()) { + return {image.width(), image.height(), + static_cast<float>(image.devicePixelRatio()), + Buffer(image.bits(), bytes)}; + } + } + } + return {}; +} + void QtShim::FontChanged(const QFont& font) { delegate_->FontChanged(); }
diff --git a/ui/qt/qt_shim.h b/ui/qt/qt_shim.h index 9fe764b..d565363 100644 --- a/ui/qt/qt_shim.h +++ b/ui/qt/qt_shim.h
@@ -26,6 +26,7 @@ double GetScaleFactor() const override; FontRenderParams GetFontRenderParams() const override; FontDescription GetFontDescription() const override; + Image GetIconForContentType(const String& content_type, int size) override; private slots: void FontChanged(const QFont& font);
diff --git a/ui/qt/qt_ui.cc b/ui/qt/qt_ui.cc index eea9484..cb72bb1 100644 --- a/ui/qt/qt_ui.cc +++ b/ui/qt/qt_ui.cc
@@ -11,11 +11,14 @@ #include "base/cxx17_backports.h" #include "base/notreached.h" #include "base/path_service.h" +#include "third_party/skia/include/core/SkBitmap.h" #include "ui/gfx/color_palette.h" #include "ui/gfx/font.h" #include "ui/gfx/font_render_params.h" #include "ui/gfx/font_render_params_linux.h" #include "ui/gfx/image/image.h" +#include "ui/gfx/image/image_skia_rep.h" +#include "ui/gfx/image/image_skia_source.h" #include "ui/qt/qt_interface.h" #include "ui/shell_dialogs/select_file_policy.h" #include "ui/views/controls/button/label_button_border.h" @@ -191,8 +194,21 @@ gfx::Image QtUi::GetIconForContentType(const std::string& content_type, int size, float scale) const { - NOTIMPLEMENTED_LOG_ONCE(); - return gfx::Image(); + Image image = + shim_->GetIconForContentType(String(content_type.c_str()), size * scale); + if (!image.data_argb.size()) + return {}; + + SkImageInfo image_info = SkImageInfo::Make( + image.width, image.height, kBGRA_8888_SkColorType, kPremul_SkAlphaType); + SkBitmap bitmap; + bitmap.installPixels( + image_info, image.data_argb.Take(), image_info.minRowBytes(), + [](void* data, void*) { free(data); }, nullptr); + gfx::ImageSkia image_skia = + gfx::ImageSkia::CreateFromBitmap(bitmap, image.scale); + image_skia.MakeThreadSafe(); + return gfx::Image(image_skia); } QtUi::WindowFrameAction QtUi::GetWindowFrameAction(
diff --git a/ui/views/controls/webview/webview.cc b/ui/views/controls/webview/webview.cc index a87b20d..e259cf28 100644 --- a/ui/views/controls/webview/webview.cc +++ b/ui/views/controls/webview/webview.cc
@@ -106,7 +106,7 @@ wc_owner_.reset(); AttachWebContentsNativeView(); - if (replacement && replacement->GetMainFrame()->IsRenderFrameCreated()) { + if (replacement && replacement->GetMainFrame()->IsRenderFrameLive()) { SetUpNewMainFrame(replacement->GetMainFrame()); } else { LostMainFrame(); @@ -138,7 +138,7 @@ DCHECK(!max_size.IsEmpty()); min_size_ = min_size; max_size_ = max_size; - if (web_contents() && web_contents()->GetMainFrame()->IsRenderFrameCreated()) + if (web_contents() && web_contents()->GetMainFrame()->IsRenderFrameLive()) MaybeEnableAutoResize(web_contents()->GetMainFrame()); } @@ -340,7 +340,7 @@ // yet. If the DCHECK fires, then we would need to handle the initial main // frame when it its renderer frame is created. if (!old_host) { - DCHECK(!new_host->IsRenderFrameCreated()); + DCHECK(!new_host->IsRenderFrameLive()); return; } @@ -472,7 +472,7 @@ } void WebView::MaybeEnableAutoResize(content::RenderFrameHost* frame_host) { - DCHECK(frame_host->IsRenderFrameCreated()); + DCHECK(frame_host->IsRenderFrameLive()); if (!max_size_.IsEmpty()) frame_host->GetView()->EnableAutoResize(min_size_, max_size_); }
diff --git a/ui/views/widget/native_widget_mac.mm b/ui/views/widget/native_widget_mac.mm index a56db90..42b1de8 100644 --- a/ui/views/widget/native_widget_mac.mm +++ b/ui/views/widget/native_widget_mac.mm
@@ -711,8 +711,8 @@ } void NativeWidgetMac::SetCursor(const ui::Cursor& cursor) { - if (GetInProcessNSWindowBridge()) - GetInProcessNSWindowBridge()->SetCursor(cursor); + if (GetNSWindowMojo()) + GetNSWindowMojo()->SetCursor(cursor); } void NativeWidgetMac::ShowEmojiPanel() {
diff --git a/ui/webui/resources/BUILD.gn b/ui/webui/resources/BUILD.gn index ce220f6..7468e5a 100644 --- a/ui/webui/resources/BUILD.gn +++ b/ui/webui/resources/BUILD.gn
@@ -93,12 +93,12 @@ deps += [ ":build_cros_styles_grdp", "//ash/webui/common/resources:build_grdp", - "//chromeos/components/cros_elements:build_grdp", + "//chromeos/ash/components/cros_elements:build_grdp", "//third_party/material_web_components:build_grdp", "//third_party/web-animations-js:build_grdp", ] grdp_files += [ - "$root_gen_dir/chromeos/components/cros_elements/cros_elements_resources.grdp", + "$root_gen_dir/chromeos/ash/components/cros_elements/cros_elements_resources.grdp", "$root_gen_dir/ui/webui/resources/cros_styles_resources.grdp", "$root_gen_dir/third_party/web-animations-js/web_animations_resources.grdp", "$root_gen_dir/third_party/material_web_components/material_web_components_resources.grdp",
diff --git a/ui/webui/resources/cr_components/history_clusters/cluster.html b/ui/webui/resources/cr_components/history_clusters/cluster.html index d8d22b9..58db643c 100644 --- a/ui/webui/resources/cr_components/history_clusters/cluster.html +++ b/ui/webui/resources/cr_components/history_clusters/cluster.html
@@ -103,7 +103,7 @@ <div id="label"></div> <div class="timestamp-and-menu"> <div class="timestamp">[[cluster.visits.0.relativeDate]]</div> - <menu-container is-top-menu is-cluster-menu></menu-container> + <menu-container></menu-container> </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 a29e37d..0d55010 100644 --- a/ui/webui/resources/cr_components/history_clusters/cluster.ts +++ b/ui/webui/resources/cr_components/history_clusters/cluster.ts
@@ -17,8 +17,8 @@ import {BrowserProxyImpl} from './browser_proxy.js'; import {getTemplate} from './cluster.html.js'; -import {Cluster, PageCallbackRouter, URLVisit} from './history_clusters.mojom-webui.js'; -import {ClusterAction, MetricsProxyImpl, VisitAction} from './metrics_proxy.js'; +import {Cluster, ClusterAction, PageCallbackRouter, URLVisit, VisitAction} from './history_clusters.mojom-webui.js'; +import {MetricsProxyImpl} from './metrics_proxy.js'; import {insertHighlightedTextWithMatchesIntoElement} from './utils.js'; /** @@ -151,16 +151,16 @@ private onRelatedSearchClicked_() { MetricsProxyImpl.getInstance().recordClusterAction( - ClusterAction.RELATED_SEARCH_CLICKED, this.index); + ClusterAction.kRelatedSearchClicked, this.index); } private onVisitClicked_(event: CustomEvent<URLVisit>) { MetricsProxyImpl.getInstance().recordClusterAction( - ClusterAction.VISIT_CLICKED, this.index); + ClusterAction.kVisitClicked, this.index); const visit = event.detail; MetricsProxyImpl.getInstance().recordVisitAction( - VisitAction.CLICKED, this.getVisitIndex_(visit), + VisitAction.kClicked, this.getVisitIndex_(visit), MetricsProxyImpl.getVisitType(visit)); } @@ -176,7 +176,7 @@ visitsToOpen); MetricsProxyImpl.getInstance().recordClusterAction( - ClusterAction.OPENED_IN_TAB_GROUP, this.index); + ClusterAction.kOpenedInTabGroup, this.index); } private onRemoveAllVisits_() { @@ -193,7 +193,7 @@ // place to record the metric. const visit = event.detail; MetricsProxyImpl.getInstance().recordVisitAction( - VisitAction.DELETED, this.getVisitIndex_(visit), + VisitAction.kDeleted, this.getVisitIndex_(visit), MetricsProxyImpl.getVisitType(visit)); this.dispatchEvent(new CustomEvent('remove-visits', { @@ -218,7 +218,7 @@ this.expanded_ = !this.expanded_; MetricsProxyImpl.getInstance().recordClusterAction( - ClusterAction.RELATED_VISITS_VISIBILITY_TOGGLED, this.index); + ClusterAction.kRelatedVisitsVisibilityToggled, this.index); // Dispatch an event to notify the parent elements of a resize. Note that // this simple solution only works because the child iron-collapse has @@ -266,7 +266,7 @@ })); MetricsProxyImpl.getInstance().recordClusterAction( - ClusterAction.DELETED, this.index); + ClusterAction.kDeleted, this.index); } else { this.set('cluster.visits', remainingVisits); }
diff --git a/ui/webui/resources/cr_components/history_clusters/history_clusters.mojom b/ui/webui/resources/cr_components/history_clusters/history_clusters.mojom index 1726e12..d448764 100644 --- a/ui/webui/resources/cr_components/history_clusters/history_clusters.mojom +++ b/ui/webui/resources/cr_components/history_clusters/history_clusters.mojom
@@ -35,6 +35,38 @@ kSearchResultsPage, }; +/** + * The following enums must be kept in sync with their respective variants in + * //tools/metrics/histograms/metadata/history/histograms.xml and + * //components/history_clusters/core/cluster_metrics_utils.h + */ + +// Actions that can be performed on clusters. +enum ClusterAction { + kDeleted, + kOpenedInTabGroup, + kRelatedSearchClicked, + kRelatedVisitsVisibilityToggled, + kVisitClicked, +}; + +// Actions that can be performed on related search items. +enum RelatedSearchAction { + kClicked, +}; + +// Actions that can be performed on visits. +enum VisitAction { + kClicked, + kDeleted, +}; + +// Types of visits that can be shown and acted on. +enum VisitType { + kSRP, + kNonSRP +}; + // Represents the most recent visit to a URL within a Cluster. Visits for which // there are more recent visits to the same (or a qualifying near-duplicate) URL // within the Cluster are omitted. @@ -151,6 +183,20 @@ // Requests to open the URLs in `visits` in a new tab group. OpenVisitUrlsInTabGroup(array<URLVisit> visits); + + // Records visit actions. + RecordVisitAction(VisitAction visit_action, + uint32 visit_index, + VisitType visit_type); + + // Records related search click action. + RecordRelatedSearchAction(RelatedSearchAction action, uint32 visit_index); + + // Records cluster actions. + RecordClusterAction(ClusterAction cluster_action, uint32 cluster_index); + + // Records that the journeys visibility was toggled. + RecordToggledVisibility(bool visible); }; // WebUI-side handler for requests from the browser.
diff --git a/ui/webui/resources/cr_components/history_clusters/menu_container.html b/ui/webui/resources/cr_components/history_clusters/menu_container.html index b387076..ddb8b2b 100644 --- a/ui/webui/resources/cr_components/history_clusters/menu_container.html +++ b/ui/webui/resources/cr_components/history_clusters/menu_container.html
@@ -1,19 +1,7 @@ <style include="history-clusters-shared-style"> - :host(:not([is-top-menu])) #openAllButton, - :host(:not([is-top-menu])) #removeAllButton { - display: none; - } - #actionMenuButton { - --cr-icon-button-margin-end: 8px; - } - - :host([is-top-menu]) #actionMenuButton { --cr-icon-button-icon-size: 24px; - } - - :host([is-cluster-menu]) #removeSelfButton { - display: none; + --cr-icon-button-margin-end: 8px; } </style> @@ -29,12 +17,9 @@ on-click="onOpenAllButtonClick_"> $i18n{openAllInTabGroup} </button> - <button id="removeSelfButton" class="dropdown-item" - on-click="onRemoveSelfButtonClick_"> - $i18n{removeFromHistory} - </button> <button id="removeAllButton" class="dropdown-item" - on-click="onRemoveAllButtonClick_"> + on-click="onRemoveAllButtonClick_" + hidden="[[!allowDeletingHistory_]]"> $i18n{removeAllFromHistory} </button> </cr-action-menu>
diff --git a/ui/webui/resources/cr_components/history_clusters/menu_container.ts b/ui/webui/resources/cr_components/history_clusters/menu_container.ts index 2dd9daa..94310c8 100644 --- a/ui/webui/resources/cr_components/history_clusters/menu_container.ts +++ b/ui/webui/resources/cr_components/history_clusters/menu_container.ts
@@ -4,12 +4,14 @@ import './history_clusters_shared_style.css.js'; import '../../cr_elements/cr_action_menu/cr_action_menu.js'; +import '../../cr_elements/cr_icon_button/cr_icon_button.m.js'; import '../../cr_elements/cr_lazy_render/cr_lazy_render.m.js'; import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {CrActionMenuElement} from '../../cr_elements/cr_action_menu/cr_action_menu.js'; import {CrLazyRenderElement} from '../../cr_elements/cr_lazy_render/cr_lazy_render.m.js'; +import {loadTimeData} from '../../js/load_time_data.m.js'; import {URLVisit} from './history_clusters.mojom-webui.js'; import {getTemplate} from './menu_container.html.js'; @@ -48,6 +50,15 @@ * The visit associated with this menu. */ visit: Object, + + /** + * Usually this is true, but this can be false if deleting history is + * prohibited by Enterprise policy. + */ + allowDeletingHistory_: { + type: Boolean, + value: () => loadTimeData.getBoolean('allowDeletingHistory'), + }, }; } @@ -56,17 +67,18 @@ //============================================================================ visit: URLVisit; + private allowDeletingHistory_: boolean; //============================================================================ // Event handlers //============================================================================ - private onActionMenuButtonClick_(event: MouseEvent) { + private onActionMenuButtonClick_(event: Event) { this.$.actionMenu.get().showAt(this.$.actionMenuButton); event.preventDefault(); // Prevent default browser action (navigation). } - private onOpenAllButtonClick_(event: MouseEvent) { + private onOpenAllButtonClick_(event: Event) { event.preventDefault(); // Prevent default browser action (navigation). this.dispatchEvent(new CustomEvent('open-all-visits', { @@ -77,7 +89,7 @@ this.$.actionMenu.get().close(); } - private onRemoveAllButtonClick_(event: MouseEvent) { + private onRemoveAllButtonClick_(event: Event) { event.preventDefault(); // Prevent default browser action (navigation). this.dispatchEvent(new CustomEvent('remove-all-visits', { @@ -87,18 +99,6 @@ this.$.actionMenu.get().close(); } - - private onRemoveSelfButtonClick_(event: MouseEvent) { - event.preventDefault(); // Prevent default browser action (navigation). - - this.dispatchEvent(new CustomEvent('remove-visit', { - bubbles: true, - composed: true, - detail: this.visit, - })); - - this.$.actionMenu.get().close(); - } } customElements.define(MenuContainerElement.is, MenuContainerElement);
diff --git a/ui/webui/resources/cr_components/history_clusters/metrics_proxy.ts b/ui/webui/resources/cr_components/history_clusters/metrics_proxy.ts index bdc38fb..d001f6e 100644 --- a/ui/webui/resources/cr_components/history_clusters/metrics_proxy.ts +++ b/ui/webui/resources/cr_components/history_clusters/metrics_proxy.ts
@@ -2,39 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import {Annotation, URLVisit} from './history_clusters.mojom-webui.js'; +import {BrowserProxyImpl} from './browser_proxy.js'; +import {Annotation, ClusterAction, RelatedSearchAction, URLVisit, VisitAction, VisitType} from './history_clusters.mojom-webui.js'; /** * @fileoverview This file provides an abstraction layer for logging metrics for * mocking in tests. */ -/** - * The following enums must be kept in sync with their respective variants in - * //tools/metrics/histograms/metadata/history/histograms.xml - */ -export enum ClusterAction { - DELETED = 'Deleted', - OPENED_IN_TAB_GROUP = 'OpenedInTabGroup', - RELATED_SEARCH_CLICKED = 'RelatedSearchClicked', - RELATED_VISITS_VISIBILITY_TOGGLED = 'RelatedVisitsVisibilityToggled', - VISIT_CLICKED = 'VisitClicked', -} - -export enum RelatedSearchAction { - CLICKED = 'Clicked', -} - -export enum VisitAction { - CLICKED = 'Clicked', - DELETED = 'Deleted', -} - -export enum VisitType { - NON_SRP = 'nonSRP', - SRP = 'SRP', -} - export interface MetricsProxy { recordClusterAction(action: ClusterAction, index: number): void; recordRelatedSearchAction(action: RelatedSearchAction, index: number): void; @@ -44,25 +19,21 @@ export class MetricsProxyImpl implements MetricsProxy { recordClusterAction(action: ClusterAction, index: number) { - chrome.metricsPrivate.recordMediumCount( - `History.Clusters.UIActions.Cluster.${action}`, index); + BrowserProxyImpl.getInstance().handler.recordClusterAction(action, index); } recordRelatedSearchAction(action: RelatedSearchAction, index: number) { - chrome.metricsPrivate.recordMediumCount( - `History.Clusters.UIActions.RelatedSearch.${action}`, index); + BrowserProxyImpl.getInstance().handler.recordRelatedSearchAction( + action, index); } recordToggledVisibility(visible: boolean) { - chrome.metricsPrivate.recordBoolean( - 'History.Clusters.UIActions.ToggledVisibility', visible); + BrowserProxyImpl.getInstance().handler.recordToggledVisibility(visible); } recordVisitAction(action: VisitAction, index: number, type: VisitType) { - chrome.metricsPrivate.recordMediumCount( - `History.Clusters.UIActions.Visit.${action}`, index); - chrome.metricsPrivate.recordMediumCount( - `History.Clusters.UIActions.${type}Visit.${action}`, index); + BrowserProxyImpl.getInstance().handler.recordVisitAction( + action, index, type); } static getInstance(): MetricsProxy { @@ -79,8 +50,8 @@ */ static getVisitType(visit: URLVisit): VisitType { return visit.annotations.includes(Annotation.kSearchResultsPage) ? - VisitType.SRP : - VisitType.NON_SRP; + VisitType.kSRP : + VisitType.kNonSRP; } }
diff --git a/ui/webui/resources/cr_components/history_clusters/search_query.ts b/ui/webui/resources/cr_components/history_clusters/search_query.ts index a92235a..ba00f45 100644 --- a/ui/webui/resources/cr_components/history_clusters/search_query.ts +++ b/ui/webui/resources/cr_components/history_clusters/search_query.ts
@@ -6,8 +6,8 @@ import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; -import {SearchQuery} from './history_clusters.mojom-webui.js'; -import {MetricsProxyImpl, RelatedSearchAction} from './metrics_proxy.js'; +import {RelatedSearchAction, SearchQuery} from './history_clusters.mojom-webui.js'; +import {MetricsProxyImpl} from './metrics_proxy.js'; import {OpenWindowProxyImpl} from './open_window_proxy.js'; import {getTemplate} from './search_query.html.js'; @@ -60,7 +60,7 @@ private onAuxClick_() { MetricsProxyImpl.getInstance().recordRelatedSearchAction( - RelatedSearchAction.CLICKED, this.index); + RelatedSearchAction.kClicked, this.index); // Notify the parent <history-cluster> element of this event. this.dispatchEvent(new CustomEvent('related-search-clicked', {
diff --git a/ui/webui/resources/cr_components/history_clusters/url_visit.html b/ui/webui/resources/cr_components/history_clusters/url_visit.html index 00b2c2a..79c6d1c2 100644 --- a/ui/webui/resources/cr_components/history_clusters/url_visit.html +++ b/ui/webui/resources/cr_components/history_clusters/url_visit.html
@@ -10,13 +10,14 @@ background-color: var(--cr-hover-background-color); } - .timestamp-and-menu { + #actionMenuButton { opacity: 0; /* Hides the element while keeping it in tab order. */ position: absolute; /* Surrender its layout space to other elements. */ + --cr-icon-button-margin-end: 8px; } - :host(:hover) .timestamp-and-menu, - .timestamp-and-menu:focus-within { + :host(:hover) #actionMenuButton, + #actionMenuButton:focus-within { opacity: 1; position: static; } @@ -107,8 +108,20 @@ </span> </div> </a> - <div class="timestamp-and-menu"> - <menu-container cluster-index="[[clusterIndex]]" visit="[[visit]]"> - </menu-container> - </div> + <cr-icon-button id="actionMenuButton" class="icon-more-vert" + title="$i18n{actionMenuDescription}" aria-haspopup="menu" + on-click="onActionMenuButtonClick_" + hidden="[[!allowDeletingHistory_]]"> + </cr-icon-button> </div> + +<cr-lazy-render id="actionMenu"> + <template> + <cr-action-menu role-description="$i18n{actionMenuDescription}"> + <button id="removeSelfButton" class="dropdown-item" + on-click="onRemoveSelfButtonClick_"> + $i18n{removeFromHistory} + </button> + </cr-action-menu> + </template> +</cr-lazy-render>
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 9464c90..9fd1aad 100644 --- a/ui/webui/resources/cr_components/history_clusters/url_visit.ts +++ b/ui/webui/resources/cr_components/history_clusters/url_visit.ts
@@ -2,14 +2,16 @@ // 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 './page_favicon.js'; import './history_clusters_shared_style.css.js'; import '../../cr_elements/cr_action_menu/cr_action_menu.js'; +import '../../cr_elements/cr_icon_button/cr_icon_button.m.js'; import '../../cr_elements/cr_lazy_render/cr_lazy_render.m.js'; import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +import {CrActionMenuElement} from '../../cr_elements/cr_action_menu/cr_action_menu.js'; +import {CrLazyRenderElement} from '../../cr_elements/cr_lazy_render/cr_lazy_render.m.js'; import {loadTimeData} from '../../js/load_time_data.m.js'; import {Annotation, URLVisit} from './history_clusters.mojom-webui.js'; @@ -39,6 +41,8 @@ interface VisitRowElement { $: { + actionMenu: CrLazyRenderElement<CrActionMenuElement>, + actionMenuButton: HTMLElement, title: HTMLElement, url: HTMLElement, }; @@ -74,6 +78,15 @@ }, /** + * Usually this is true, but this can be false if deleting history is + * prohibited by Enterprise policy. + */ + allowDeletingHistory_: { + type: Boolean, + value: () => loadTimeData.getBoolean('allowDeletingHistory'), + }, + + /** * Debug info for the visit. */ debugInfo_: { @@ -110,6 +123,7 @@ query: string; visit: URLVisit; private annotations_: Array<string>; + private allowDeletingHistory_: boolean; private debugInfo_: string; private unusedTitle_: string; private unusedVisibleUrl_: string; @@ -127,7 +141,7 @@ })); } - private onClick_(event: MouseEvent) { + private onClick_(event: Event) { // Ignore previously handled events. if (event.defaultPrevented) { return; @@ -153,6 +167,23 @@ OpenWindowProxyImpl.getInstance().open(this.visit.normalizedUrl.url); } + private onActionMenuButtonClick_(event: Event) { + this.$.actionMenu.get().showAt(this.$.actionMenuButton); + event.preventDefault(); // Prevent default browser action (navigation). + } + + private onRemoveSelfButtonClick_(event: Event) { + event.preventDefault(); // Prevent default browser action (navigation). + + this.dispatchEvent(new CustomEvent('remove-visit', { + bubbles: true, + composed: true, + detail: this.visit, + })); + + this.$.actionMenu.get().close(); + } + //============================================================================ // Helper methods //============================================================================