diff --git a/DEPS b/DEPS index 13a3814..4c6a8b2 100644 --- a/DEPS +++ b/DEPS
@@ -253,11 +253,11 @@ # 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': '72a425bab711d109a9b663966eaaa1197025b0a8', + 'skia_revision': 'ede5dae4db59840ef7d6e76496f92ec8d10728ef', # 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': '4e1875f07b4c8f59714d190c6e7999115c8af430', + 'v8_revision': '53958a11c7583d9e0e2eaaeb000ea418ae67efdd', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ANGLE # and whatever else without interference from each other. @@ -265,7 +265,7 @@ # 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': '89c498edff683c68df6be0dd224848f4b4af5ae7', + 'swiftshader_revision': '79d4c6cae485c50d2d49aa1b3defe601dc23f145', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. @@ -320,7 +320,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling catapult # and whatever else without interference from each other. - 'catapult_revision': '74c0bf3d684ebb866442b4c5cd7f4ba3230d67d0', + 'catapult_revision': '46b602cdaf2c2983e0b5cdbb2eca3c711d1417e8', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -364,7 +364,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': '1d882f55b7f47dd06fe57efdf286100bf2a3ad6b', + 'dawn_revision': '8e2a1f9ab93e38e1e22946a94d55b997c2d9600e', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -1106,7 +1106,7 @@ }, 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '7feb245cf57e743cb5d0acccc887bad15c73ff2d', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '87172073a6c87178dca378501fd56c52f6f76a4a', 'src/third_party/devtools-frontend/src': Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'), @@ -1713,10 +1713,10 @@ Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + 'cf04aebdf9b53bb2853f22a81465688daf879ec6', 'src/third_party/webgpu-cts/src': - Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + 'd54181c886109c3e1e34930fbeb03ece2c1e56e4', + Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '9007653926414cb1afb3fe7e882a31ac296163c8', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + 'b767350e486cb850a4e39f57b461f0cbaf25bb51', + Var('webrtc_git') + '/src.git' + '@' + '82caafd607f3f273d02476378a71b1ddafbeda0d', 'src/third_party/libgifcodec': Var('skia_git') + '/libgifcodec' + '@'+ Var('libgifcodec_revision'), @@ -1786,7 +1786,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@82e17f7a45a28363a30d0bbc9fe23ada6f44ee2e', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@df8bee5c5fa5f495230fc431738f9058a19e9170', 'condition': 'checkout_src_internal', },
diff --git a/android_webview/BUILD.gn b/android_webview/BUILD.gn index 827669ae..476d4bb 100644 --- a/android_webview/BUILD.gn +++ b/android_webview/BUILD.gn
@@ -14,7 +14,11 @@ import("//chrome/android/chrome_common_shared_library.gni") import("//chrome/android/chrome_public_apk_tmpl.gni") import("//chrome/android/trichrome.gni") +import("//components/safe_browsing/buildflags.gni") import("//components/spellcheck/spellcheck_build_features.gni") +import("//device/vr/buildflags/buildflags.gni") +import("//pdf/features.gni") +import("//printing/buildflags/buildflags.gni") import("//tools/grit/repack.gni") import("//tools/resources/generate_resource_allowlist.gni") import("//tools/v8_context_snapshot/v8_context_snapshot.gni") @@ -1113,6 +1117,11 @@ use_brotli = true + defines = [ + "enable_basic_printing=$enable_basic_printing", + "safe_browsing_mode=$safe_browsing_mode", + ] + # See :generate_webui_resources for an explanation of the allowlist _allowlist = rebase_path("$target_gen_dir/grit_resources_allowlist.txt", root_build_dir) @@ -1135,6 +1144,12 @@ "//components/resources:about_credits", "//components/resources/ssl/ssl_error_assistant:make_ssl_error_assistant_protobuf", ] + + if (safe_browsing_mode != 0) { + deps += [ + "//components/safe_browsing/content/resources:make_file_types_protobuf", + ] + } } grit("generate_components_scaled_resources") { @@ -1163,6 +1178,12 @@ grit("generate_components_strings") { source = "../components/components_strings.grd" + defines = [ + "enable_pdf=$enable_pdf", + "enable_print_preview=$enable_print_preview", + "enable_vr=$enable_vr", + ] + # components_strings contains strings from all components. WebView # will never display most of them, so we try to limit the included # strings. This allowlist trims about 50% more than the compile-based
diff --git a/android_webview/tools/system_webview_shell/BUILD.gn b/android_webview/tools/system_webview_shell/BUILD.gn index a7ad137..ea387c6 100644 --- a/android_webview/tools/system_webview_shell/BUILD.gn +++ b/android_webview/tools/system_webview_shell/BUILD.gn
@@ -62,10 +62,10 @@ deps = [ ":system_webview_shell_apk_resources", "//base:base_java", - "//third_party/android_deps:android_support_v7_appcompat_java", "//third_party/android_deps:guava_android_java", "//third_party/androidx:androidx_activity_activity_java", "//third_party/androidx:androidx_annotation_annotation_java", + "//third_party/androidx:androidx_appcompat_appcompat_java", "//third_party/androidx:androidx_savedstate_savedstate_java", "//third_party/androidx:androidx_webkit_webkit_java", ] @@ -109,7 +109,6 @@ "apk/res/values/styles.xml", "apk/res/xml/network_security_config.xml", ] - deps = [ "//third_party/android_deps:android_support_v7_appcompat_java" ] } instrumentation_test_apk("system_webview_shell_page_cycler_apk") {
diff --git a/ash/BUILD.gn b/ash/BUILD.gn index 9c3e0be7..26b381c 100644 --- a/ash/BUILD.gn +++ b/ash/BUILD.gn
@@ -1742,8 +1742,6 @@ "utility/rounded_window_targeter.h", "utility/transformer_util.cc", "utility/transformer_util.h", - "wallpaper/online_wallpaper_variant_info_fetcher.cc", - "wallpaper/online_wallpaper_variant_info_fetcher.h", "wallpaper/wallpaper_base_view.cc", "wallpaper/wallpaper_base_view.h", "wallpaper/wallpaper_constants.h", @@ -2829,7 +2827,6 @@ "utility/lottie_util_unittest.cc", "utility/occlusion_tracker_pauser_unittest.cc", "utility/rounded_window_targeter_unittest.cc", - "wallpaper/online_wallpaper_variant_info_fetcher_unittest.cc", "wallpaper/wallpaper_controller_unittest.cc", "wallpaper/wallpaper_utils/wallpaper_color_calculator_unittest.cc", "wallpaper/wallpaper_utils/wallpaper_resizer_unittest.cc",
diff --git a/ash/app_list/views/continue_task_container_view.cc b/ash/app_list/views/continue_task_container_view.cc index 5ae9ec1..9f33b40 100644 --- a/ash/app_list/views/continue_task_container_view.cc +++ b/ash/app_list/views/continue_task_container_view.cc
@@ -174,6 +174,15 @@ } else { animations_timer_.Start(FROM_HERE, base::Seconds(2), base::DoNothing()); } + + auto* notifier = view_delegate_->GetNotifier(); + if (notifier) { + // NOTE: Use `IsDrawn()` instead of `is_visible` to account for parent + // container visibility - `IsDrawn()` will return false if this view is + // visible but its parent is not. + notifier->NotifyContinueSectionVisibilityChanged( + SearchResultDisplayType::kContinue, IsDrawn()); + } } bool ContinueTaskContainerView::OnKeyPressed(const ui::KeyEvent &event) {
diff --git a/ash/app_list/views/recent_apps_view.cc b/ash/app_list/views/recent_apps_view.cc index 8bec8f08..83bfc572 100644 --- a/ash/app_list/views/recent_apps_view.cc +++ b/ash/app_list/views/recent_apps_view.cc
@@ -212,8 +212,12 @@ items.push_back(item); } - if (items.size() < kMinRecommendedApps) + if (items.size() < kMinRecommendedApps) { + if (auto* notifier = view_delegate_->GetNotifier()) { + notifier->NotifyResultsUpdated(SearchResultDisplayType::kRecentApps, {}); + } return; + } if (auto* notifier = view_delegate_->GetNotifier()) { std::vector<AppListNotifier::Result> notifier_results; @@ -253,7 +257,12 @@ void RecentAppsView::UpdateVisibility() { const bool has_enough_apps = item_views_.size() >= kMinRecommendedApps; const bool hidden_by_user = view_delegate_->ShouldHideContinueSection(); - SetVisible(has_enough_apps && !hidden_by_user); + const bool visible = has_enough_apps && !hidden_by_user; + SetVisible(visible); + if (auto* notifier = view_delegate_->GetNotifier()) { + notifier->NotifyContinueSectionVisibilityChanged( + SearchResultDisplayType::kRecentApps, visible); + } } int RecentAppsView::GetItemViewCount() const {
diff --git a/ash/capture_mode/capture_mode_camera_preview_view.cc b/ash/capture_mode/capture_mode_camera_preview_view.cc index 0a2e81e..47cacd9 100644 --- a/ash/capture_mode/capture_mode_camera_preview_view.cc +++ b/ash/capture_mode/capture_mode_camera_preview_view.cc
@@ -7,6 +7,7 @@ #include "ash/capture_mode/capture_mode_constants.h" #include "ash/capture_mode/capture_mode_util.h" #include "ash/resources/vector_icons/vector_icons.h" +#include "ash/shell.h" #include "ash/strings/grit/ash_strings.h" #include "ash/style/ash_color_provider.h" #include "base/bind.h" @@ -109,13 +110,8 @@ AshColorProvider::BaseLayerType::kTransparent80), resize_button_->GetPreferredSize().height() / 2.f)); - // Ensure that when `FadeInResizeButton` was called first time, it animates - // from 0 to 1. - resize_button_->layer()->SetOpacity(0); - - // The resize button should be hidden by default so that it doesn't handle - // events. - resize_button_->SetVisible(false); + accessibility_observation_.Observe(Shell::Get()->accessibility_controller()); + RefreshResizeButtonVisibility(); UpdateResizeButtonTooltip(); } @@ -283,6 +279,14 @@ gfx::Insets(views::FocusRing::kDefaultHaloThickness / 2)); } +void CameraPreviewView::OnAccessibilityStatusChanged() { + RefreshResizeButtonVisibility(); +} + +void CameraPreviewView::OnAccessibilityControllerShutdown() { + accessibility_observation_.Reset(); +} + void CameraPreviewView::OnResizeButtonPressed() { camera_controller_->ToggleCameraPreviewSize(); UpdateResizeButton(); @@ -357,7 +361,8 @@ if (!is_collapsible_ || camera_controller_->is_drag_in_progress()) return 0.f; - if (IsMouseHovered() || resize_button_->IsMouseHovered() || + if (Shell::Get()->accessibility_controller()->IsSwitchAccessRunning() || + IsMouseHovered() || resize_button_->IsMouseHovered() || resize_button_->has_focus() || has_been_tapped_) { return 1.f; }
diff --git a/ash/capture_mode/capture_mode_camera_preview_view.h b/ash/capture_mode/capture_mode_camera_preview_view.h index b8bda49..047d9b8 100644 --- a/ash/capture_mode/capture_mode_camera_preview_view.h +++ b/ash/capture_mode/capture_mode_camera_preview_view.h
@@ -5,11 +5,14 @@ #ifndef ASH_CAPTURE_MODE_CAPTURE_MODE_CAMERA_PREVIEW_VIEW_H_ #define ASH_CAPTURE_MODE_CAPTURE_MODE_CAMERA_PREVIEW_VIEW_H_ +#include "ash/accessibility/accessibility_controller_impl.h" +#include "ash/accessibility/accessibility_observer.h" #include "ash/capture_mode/camera_video_frame_renderer.h" #include "ash/capture_mode/capture_mode_button.h" #include "ash/capture_mode/capture_mode_camera_controller.h" #include "ash/capture_mode/capture_mode_session_focus_cycler.h" #include "base/memory/weak_ptr.h" +#include "base/scoped_observation.h" #include "mojo/public/cpp/bindings/remote.h" #include "ui/base/metadata/metadata_header_macros.h" #include "ui/gfx/geometry/size.h" @@ -56,7 +59,8 @@ // be responsible for painting the latest camera video frame inside its bounds. class CameraPreviewView : public views::View, - public CaptureModeSessionFocusCycler::HighlightableView { + public CaptureModeSessionFocusCycler::HighlightableView, + public AccessibilityObserver { public: METADATA_HEADER(CameraPreviewView); @@ -104,6 +108,10 @@ views::View* GetView() override; std::unique_ptr<views::HighlightPathGenerator> CreatePathGenerator() override; + // AccessibilityObserver: + void OnAccessibilityStatusChanged() override; + void OnAccessibilityControllerShutdown() override; + base::OneShotTimer* resize_button_hide_timer_for_test() { return &resize_button_hide_timer_; } @@ -169,6 +177,9 @@ // True only while handling a gesture tap event on this view. bool has_been_tapped_ = false; + base::ScopedObservation<AccessibilityControllerImpl, AccessibilityObserver> + accessibility_observation_{this}; + base::WeakPtrFactory<CameraPreviewView> weak_ptr_factory_{this}; };
diff --git a/ash/capture_mode/capture_mode_camera_unittests.cc b/ash/capture_mode/capture_mode_camera_unittests.cc index 2baac7c..321a367 100644 --- a/ash/capture_mode/capture_mode_camera_unittests.cc +++ b/ash/capture_mode/capture_mode_camera_unittests.cc
@@ -3398,6 +3398,114 @@ } } +// Tests that the resize button will stay visible after mouse exiting the +// preview and time exceeding the predefined duration on mouse event when switch +// access is enabled. And the resize button will behave in a default way if +// switch access is not enabled. +TEST_P(CaptureModeCameraPreviewTest, + ResizeButtonSwitchAccessVisibilityTestOnMouseEvent) { + UpdateDisplay("1366x768"); + + CaptureModeCameraController* camera_controller = GetCameraController(); + AddDefaultCamera(); + camera_controller->SetSelectedCamera(CameraId(kDefaultCameraModelId, 1)); + auto* event_generator = GetEventGenerator(); + + for (const bool switch_access_enabled : {false, true}) { + AccessibilityControllerImpl* a11y_controller = + Shell::Get()->accessibility_controller(); + a11y_controller->switch_access().SetEnabled(switch_access_enabled); + EXPECT_EQ(switch_access_enabled, a11y_controller->IsSwitchAccessRunning()); + + StartCaptureSessionWithParam(); + views::Widget* preview_widget = camera_controller->camera_preview_widget(); + DCHECK(preview_widget); + gfx::Rect preview_bounds = preview_widget->GetWindowBoundsInScreen(); + CaptureModeButton* resize_button = GetPreviewResizeButton(); + + // Tests the default visibility of the resize button based on whether switch + // access is enabled or not. + EXPECT_EQ(resize_button->GetVisible(), + switch_access_enabled ? true : false); + + event_generator->MoveMouseTo(preview_bounds.CenterPoint()); + EXPECT_TRUE(resize_button->GetVisible()); + + auto outside_point = preview_bounds.origin(); + outside_point.Offset(-1, -1); + event_generator->MoveMouseTo(outside_point); + base::OneShotTimer* timer = camera_controller->camera_preview_view() + ->resize_button_hide_timer_for_test(); + timer->FireNow(); + EXPECT_EQ(resize_button->GetVisible(), + switch_access_enabled ? true : false); + + // Tests that the resize button will be hidden when start dragging the + // camera preview regardless of whether the switch access is enabled or not. + event_generator->MoveMouseTo(preview_bounds.CenterPoint()); + EXPECT_TRUE(resize_button->GetVisible()); + event_generator->PressLeftButton(); + EXPECT_FALSE(resize_button->GetVisible()); + event_generator->MoveMouseBy(-100, -100); + EXPECT_FALSE(resize_button->GetVisible()); + + // Tests that the resize button will be visible if the switch access is + // enabled after releasing the drag and not visible otherwise. + event_generator->ReleaseLeftButton(); + EXPECT_EQ(resize_button->GetVisible(), + switch_access_enabled ? true : false); + + CaptureModeController::Get()->Stop(); + } +} + +// Tests that the resize button will stay visible after tapping on the preview +// and time exceeding the predefined duration on tap event when switch access is +// enabled. And the resize button will behave in a default way if switch +// access is not enabled. +TEST_P(CaptureModeCameraPreviewTest, + ResizeButtonSwitchAccessVisibilityTestOnTapEvent) { + UpdateDisplay("1366x768"); + + SwitchToTabletMode(); + EXPECT_TRUE(Shell::Get()->IsInTabletMode()); + + CaptureModeCameraController* camera_controller = GetCameraController(); + AddDefaultCamera(); + camera_controller->SetSelectedCamera(CameraId(kDefaultCameraModelId, 1)); + auto* event_generator = GetEventGenerator(); + + for (const bool switch_access_enabled : {false, true}) { + AccessibilityControllerImpl* a11y_controller = + Shell::Get()->accessibility_controller(); + a11y_controller->switch_access().SetEnabled(switch_access_enabled); + EXPECT_EQ(switch_access_enabled, a11y_controller->IsSwitchAccessRunning()); + + StartCaptureSessionWithParam(); + views::Widget* preview_widget = camera_controller->camera_preview_widget(); + DCHECK(preview_widget); + gfx::Rect preview_bounds = preview_widget->GetWindowBoundsInScreen(); + CaptureModeButton* resize_button = GetPreviewResizeButton(); + + // Tests the default visibility of the resize button based on whether switch + // access is enabled or not. + EXPECT_EQ(resize_button->GetVisible(), + switch_access_enabled ? true : false); + + event_generator->GestureTapAt(preview_bounds.CenterPoint()); + EXPECT_TRUE(resize_button->GetVisible()); + + base::OneShotTimer* timer = camera_controller->camera_preview_view() + ->resize_button_hide_timer_for_test(); + if (timer->IsRunning()) + timer->FireNow(); + + EXPECT_EQ(resize_button->GetVisible(), + switch_access_enabled ? true : false); + CaptureModeController::Get()->Stop(); + } +} + INSTANTIATE_TEST_SUITE_P(All, CaptureModeCameraPreviewTest, testing::Values(CaptureModeSource::kFullscreen,
diff --git a/ash/components/arc/mojom/net.mojom b/ash/components/arc/mojom/net.mojom index 2465a8b..463dca9 100644 --- a/ash/components/arc/mojom/net.mojom +++ b/ash/components/arc/mojom/net.mojom
@@ -430,6 +430,31 @@ // True if the network has been autodetected by the platform as a metered // network or if the user explicitly marked the network as metered in the UI. [MinVersion=14] bool is_metered; + + // Routes of destinations for the host network in CIDR format. If null/empty, + // all (both IPv4 and IPv6) destinations are assumed to go through the host + // network. As long as there is at least one destination in the list, + // regardless of IPv4 or IPv6 family, then no default destinations for any + // IPv* family are assumed anymore. + // + // For example: + // [ ] => Implies 0.0.0.0/0 and ::/0 + // [ 10.8.0.5/32 ] => 10.8.0.5/32 for IPv4, no IPv6 + // [ 2001:DB8::/32 ] => 2001:DB8::/32 for IPv6, no IPv4 + // [ 10.8.0.5/32, ::/0 ] => 10.8.0.5/32 for IPv4, all IPv6 + // [ 2001:DB88::/32, 0.0.0.0/0 ] => 2001::DB8::/32 for IPv6, all IPv4 + // + // If the same destination is present in include_routes and exclude_routes, + // then exclude_routes will take precedence and the destination will be + // excluded from the host network. + [MinVersion=15] array<string>? include_routes; + + // Routes of destinations to exclude for the host network in CIDR format. If + // null/empty, it is assumed no destinations are excluded. If the same + // destination is present in include_routes and exclude_routes, then + // exclude_routes will take precedence and the destination will be excluded + // from the host network. + [MinVersion=15] array<string>? exclude_routes; }; // Describes a Wifi network configuration that ARC has requested the host to
diff --git a/ash/components/arc/net/arc_net_host_impl.cc b/ash/components/arc/net/arc_net_host_impl.cc index 43b65f1..37a4201 100644 --- a/ash/components/arc/net/arc_net_host_impl.cc +++ b/ash/components/arc/net/arc_net_host_impl.cc
@@ -276,6 +276,28 @@ const int mtu = shill_ipconfig->FindIntPath(shill::kMtuProperty).value_or(0); if (mtu > 0) network->host_mtu = mtu; + + if (const auto* include_routes_list = + shill_ipconfig->FindListKey(shill::kIncludedRoutesProperty)) { + for (const auto& include_routes_value : + include_routes_list->GetListDeprecated()) { + const std::string& include_route = include_routes_value.GetString(); + if (!include_route.empty()) { + network->include_routes->push_back(include_route); + } + } + } + + if (const auto* exclude_routes_list = + shill_ipconfig->FindListKey(shill::kExcludedRoutesProperty)) { + for (const auto& exclude_routes_value : + exclude_routes_list->GetListDeprecated()) { + const std::string& exclude_route = exclude_routes_value.GetString(); + if (!exclude_route.empty()) { + network->exclude_routes->push_back(exclude_route); + } + } + } } arc::mojom::NetworkConfigurationPtr TranslateNetworkProperties( @@ -286,6 +308,8 @@ mojo->host_ipv6_global_addresses = std::vector<std::string>(); mojo->host_search_domains = std::vector<std::string>(); mojo->host_dns_addresses = std::vector<std::string>(); + mojo->include_routes = std::vector<std::string>(); + mojo->exclude_routes = std::vector<std::string>(); mojo->connection_state = TranslateConnectionState(network_state->connection_state()); mojo->guid = network_state->guid();
diff --git a/ash/public/cpp/app_list/app_list_notifier.h b/ash/public/cpp/app_list/app_list_notifier.h index 7cd9840..967eb24 100644 --- a/ash/public/cpp/app_list/app_list_notifier.h +++ b/ash/public/cpp/app_list/app_list_notifier.h
@@ -75,6 +75,11 @@ virtual void AddObserver(Observer* observer) = 0; virtual void RemoveObserver(Observer* observer) = 0; + // Called when visibility of a container within the launcher continue section + // (continue task suggestions, or recent apps) changes. + virtual void NotifyContinueSectionVisibilityChanged(Location location, + bool visible) = 0; + // Called to indicate a search |result| has been launched at the UI surface // |location|. virtual void NotifyLaunched(Location location, const Result& result) = 0;
diff --git a/ash/services/ime/BUILD.gn b/ash/services/ime/BUILD.gn index 3c16ddb..d2fe81d 100644 --- a/ash/services/ime/BUILD.gn +++ b/ash/services/ime/BUILD.gn
@@ -19,10 +19,10 @@ ] } -source_set("shared_lib") { +source_set("decoder") { sources = [ - "ime_shared_lib.cc", - "ime_shared_lib.h", + "ime_decoder.cc", + "ime_decoder.h", ] deps = [ @@ -49,7 +49,7 @@ deps = [ ":constants", - ":shared_lib", + ":decoder", "//ash/constants", "//ash/services/ime/public/cpp:rulebased", "//ash/services/ime/public/cpp/shared_lib:interfaces", @@ -66,7 +66,7 @@ deps = [ ":constants", - ":shared_lib", + ":decoder", "//base", "//sandbox/linux:sandbox_services", "//sandbox/policy", @@ -84,7 +84,7 @@ ":lib", ":test_support", "//ash/constants", - "//ash/services/ime:shared_lib", + "//ash/services/ime:decoder", "//ash/services/ime/public/mojom", "//base", "//base/test:test_support",
diff --git a/ash/services/ime/decoder/decoder_engine.cc b/ash/services/ime/decoder/decoder_engine.cc index 9385d5d..66a2ca53 100644 --- a/ash/services/ime/decoder/decoder_engine.cc +++ b/ash/services/ime/decoder/decoder_engine.cc
@@ -57,7 +57,7 @@ DecoderEngine::DecoderEngine( ImeCrosPlatform* platform, - absl::optional<ImeSharedLib::EntryPoints> entry_points) { + absl::optional<ImeDecoder::EntryPoints> entry_points) { if (!entry_points) { LOG(WARNING) << "DecoderEngine INIT INCOMPLETE."; return;
diff --git a/ash/services/ime/decoder/decoder_engine.h b/ash/services/ime/decoder/decoder_engine.h index ba23467f..0828e411 100644 --- a/ash/services/ime/decoder/decoder_engine.h +++ b/ash/services/ime/decoder/decoder_engine.h
@@ -5,7 +5,7 @@ #ifndef ASH_SERVICES_IME_DECODER_DECODER_ENGINE_H_ #define ASH_SERVICES_IME_DECODER_DECODER_ENGINE_H_ -#include "ash/services/ime/ime_shared_lib.h" +#include "ash/services/ime/ime_decoder.h" #include "ash/services/ime/public/cpp/shared_lib/interfaces.h" #include "ash/services/ime/public/mojom/input_engine.mojom.h" #include "ash/services/ime/public/mojom/input_method.mojom.h" @@ -29,9 +29,8 @@ // shared lib, to facilitate accessing an IME engine therein via ProtoMode. class DecoderEngine : public mojom::InputChannel { public: - explicit DecoderEngine( - ImeCrosPlatform* platform, - absl::optional<ImeSharedLib::EntryPoints> entry_points); + explicit DecoderEngine(ImeCrosPlatform* platform, + absl::optional<ImeDecoder::EntryPoints> entry_points); DecoderEngine(const DecoderEngine&) = delete; DecoderEngine& operator=(const DecoderEngine&) = delete; @@ -50,7 +49,7 @@ ProcessMessageCallback callback) override; private: - absl::optional<ImeSharedLib::EntryPoints> decoder_entry_points_; + absl::optional<ImeDecoder::EntryPoints> decoder_entry_points_; mojo::ReceiverSet<mojom::InputChannel> decoder_channel_receivers_; };
diff --git a/ash/services/ime/decoder/system_engine.cc b/ash/services/ime/decoder/system_engine.cc index 5aacddc..73fb6f0 100644 --- a/ash/services/ime/decoder/system_engine.cc +++ b/ash/services/ime/decoder/system_engine.cc
@@ -15,7 +15,7 @@ SystemEngine::SystemEngine( ImeCrosPlatform* platform, - absl::optional<ImeSharedLib::EntryPoints> entry_points) { + absl::optional<ImeDecoder::EntryPoints> entry_points) { if (!entry_points) { LOG(WARNING) << "SystemEngine INIT INCOMPLETE."; return;
diff --git a/ash/services/ime/decoder/system_engine.h b/ash/services/ime/decoder/system_engine.h index 40aa93eb..cdda1cc 100644 --- a/ash/services/ime/decoder/system_engine.h +++ b/ash/services/ime/decoder/system_engine.h
@@ -5,7 +5,7 @@ #ifndef ASH_SERVICES_IME_DECODER_SYSTEM_ENGINE_H_ #define ASH_SERVICES_IME_DECODER_SYSTEM_ENGINE_H_ -#include "ash/services/ime/ime_shared_lib.h" +#include "ash/services/ime/ime_decoder.h" #include "ash/services/ime/public/cpp/shared_lib/interfaces.h" #include "ash/services/ime/public/mojom/connection_factory.mojom.h" #include "ash/services/ime/public/mojom/input_engine.mojom.h" @@ -30,7 +30,7 @@ class SystemEngine { public: explicit SystemEngine(ImeCrosPlatform* platform, - absl::optional<ImeSharedLib::EntryPoints> entry_points); + absl::optional<ImeDecoder::EntryPoints> entry_points); SystemEngine(const SystemEngine&) = delete; SystemEngine& operator=(const SystemEngine&) = delete; @@ -49,7 +49,7 @@ bool IsConnected(); private: - absl::optional<ImeSharedLib::EntryPoints> decoder_entry_points_; + absl::optional<ImeDecoder::EntryPoints> decoder_entry_points_; }; } // namespace ime
diff --git a/ash/services/ime/decoder/system_engine_unittest.cc b/ash/services/ime/decoder/system_engine_unittest.cc index f1d3f9b..fecf2c38 100644 --- a/ash/services/ime/decoder/system_engine_unittest.cc +++ b/ash/services/ime/decoder/system_engine_unittest.cc
@@ -21,7 +21,7 @@ class TestDecoderState; // The fake decoder state has to be available globally because -// ImeSharedLib::EntryPoints is a list of stateless C functions, so the only way +// ImeDecoder::EntryPoints is a list of stateless C functions, so the only way // to have a stateful fake is to have a global reference to it. TestDecoderState* g_test_decoder_state = nullptr; @@ -78,10 +78,10 @@ mojo::Remote<mojom::InputMethodHost> input_method_host; }; -ImeSharedLib::EntryPoints CreateDecoderEntryPoints(TestDecoderState* state) { +ImeDecoder::EntryPoints CreateDecoderEntryPoints(TestDecoderState* state) { g_test_decoder_state = state; - ImeSharedLib::EntryPoints entry_points = { + ImeDecoder::EntryPoints entry_points = { .init_proto_mode = [](ImeCrosPlatform* platform) {}, .close_proto_mode = []() {}, .supports = [](const char* ime_spec) { return true; }, @@ -168,7 +168,7 @@ TEST_F(SystemEngineTest, BindRequestConnectsInputMethod) { TestDecoderState state; - ImeSharedLib::EntryPoints entry_points = CreateDecoderEntryPoints(&state); + ImeDecoder::EntryPoints entry_points = CreateDecoderEntryPoints(&state); SystemEngine engine(/*platform=*/nullptr, entry_points); mojo::Remote<mojom::InputMethod> input_method; @@ -184,7 +184,7 @@ TEST_F(SystemEngineTest, CanSendMessagesAfterBinding) { TestDecoderState state; - ImeSharedLib::EntryPoints entry_points = CreateDecoderEntryPoints(&state); + ImeDecoder::EntryPoints entry_points = CreateDecoderEntryPoints(&state); SystemEngine engine(/*platform=*/nullptr, entry_points); mojo::Remote<mojom::InputMethod> input_method; @@ -203,7 +203,7 @@ TEST_F(SystemEngineTest, CanReceiveMessagesAfterBinding) { TestDecoderState state; - ImeSharedLib::EntryPoints entry_points = CreateDecoderEntryPoints(&state); + ImeDecoder::EntryPoints entry_points = CreateDecoderEntryPoints(&state); SystemEngine engine(/*platform=*/nullptr, entry_points); mojo::Remote<mojom::InputMethod> input_method;
diff --git a/ash/services/ime/ime_shared_lib.cc b/ash/services/ime/ime_decoder.cc similarity index 78% rename from ash/services/ime/ime_shared_lib.cc rename to ash/services/ime/ime_decoder.cc index 7e5f353..73118873 100644 --- a/ash/services/ime/ime_shared_lib.cc +++ b/ash/services/ime/ime_decoder.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 "ash/services/ime/ime_shared_lib.h" +#include "ash/services/ime/ime_decoder.h" #include "ash/constants/ash_features.h" #include "ash/services/ime/constants.h" @@ -16,18 +16,18 @@ namespace { -const char kCrosImeSharedLib[] = "libimedecoder.so"; +const char kCrosImeDecoderLib[] = "libimedecoder.so"; // TODO(b/161491092): Add test image path based on value of // "CHROMEOS_RELEASE_TRACK" from `base::SysInfo::GetLsbReleaseValue`. -// Returns ImeSharedLib path based on the run time env. -base::FilePath GetImeSharedLibPath() { +// Returns ImeDecoderLib path based on the run time env. +base::FilePath GetImeDecoderLibPath() { #if defined(__x86_64__) || defined(__aarch64__) base::FilePath lib_path("/usr/lib64"); #else base::FilePath lib_path("/usr/lib"); #endif - lib_path = lib_path.Append(kCrosImeSharedLib); + lib_path = lib_path.Append(kCrosImeDecoderLib); return lib_path; } @@ -54,15 +54,15 @@ } // namespace -ImeSharedLibImpl::ImeSharedLibImpl() = default; +ImeDecoderImpl::ImeDecoderImpl() = default; -absl::optional<ImeSharedLib::EntryPoints> -ImeSharedLibImpl::MaybeLoadThenReturnEntryPoints() { +absl::optional<ImeDecoder::EntryPoints> +ImeDecoderImpl::MaybeLoadThenReturnEntryPoints() { if (entry_points_) { return entry_points_; } - base::FilePath path = GetImeSharedLibPath(); + base::FilePath path = GetImeDecoderLibPath(); // Add dlopen flags (RTLD_LAZY | RTLD_NODELETE) later. base::ScopedNativeLibrary library = base::ScopedNativeLibrary(path); @@ -77,12 +77,12 @@ library.GetFunctionPointer(kInitProtoModeFnName)), .close_proto_mode = reinterpret_cast<CloseProtoModeFn>( library.GetFunctionPointer(kCloseProtoModeFnName)), - .supports = reinterpret_cast<ImeSharedLibSupportsFn>( - library.GetFunctionPointer(kImeSharedLibSupportsFnName)), - .activate_ime = reinterpret_cast<ImeSharedLibActivateImeFn>( - library.GetFunctionPointer(kImeSharedLibActivateImeFnName)), - .process = reinterpret_cast<ImeSharedLibProcessFn>( - library.GetFunctionPointer(kImeSharedLibProcessFnName)), + .supports = reinterpret_cast<ImeDecoderSupportsFn>( + library.GetFunctionPointer(kImeDecoderSupportsFnName)), + .activate_ime = reinterpret_cast<ImeDecoderActivateImeFn>( + library.GetFunctionPointer(kImeDecoderActivateImeFnName)), + .process = reinterpret_cast<ImeDecoderProcessFn>( + library.GetFunctionPointer(kImeDecoderProcessFnName)), .init_mojo_mode = reinterpret_cast<InitMojoModeFn>( library.GetFunctionPointer(kInitMojoModeFnName)), .close_mojo_mode = reinterpret_cast<CloseMojoModeFn>( @@ -120,10 +120,10 @@ return entry_points_; } -ImeSharedLibImpl::~ImeSharedLibImpl() = default; +ImeDecoderImpl::~ImeDecoderImpl() = default; -ImeSharedLibImpl* ImeSharedLibImpl::GetInstance() { - static base::NoDestructor<ImeSharedLibImpl> instance; +ImeDecoderImpl* ImeDecoderImpl::GetInstance() { + static base::NoDestructor<ImeDecoderImpl> instance; return instance.get(); }
diff --git a/ash/services/ime/ime_shared_lib.h b/ash/services/ime/ime_decoder.h similarity index 68% rename from ash/services/ime/ime_shared_lib.h rename to ash/services/ime/ime_decoder.h index e7fb14ec..ead5ea9 100644 --- a/ash/services/ime/ime_shared_lib.h +++ b/ash/services/ime/ime_decoder.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 ASH_SERVICES_IME_IME_SHARED_LIB_H_ -#define ASH_SERVICES_IME_IME_SHARED_LIB_H_ +#ifndef ASH_SERVICES_IME_IME_DECODER_H_ +#define ASH_SERVICES_IME_IME_DECODER_H_ #include "ash/services/ime/public/cpp/shared_lib/interfaces.h" @@ -26,16 +26,15 @@ inline constexpr char kCloseProtoModeFnName[] = "CloseProtoMode"; typedef void (*CloseProtoModeFn)(); -inline constexpr char kImeSharedLibSupportsFnName[] = "ImeSharedLibSupports"; -typedef bool (*ImeSharedLibSupportsFn)(const char* ime_spec); +inline constexpr char kImeDecoderSupportsFnName[] = "ImeDecoderSupports"; +typedef bool (*ImeDecoderSupportsFn)(const char* ime_spec); -inline constexpr char kImeSharedLibActivateImeFnName[] = - "ImeSharedLibActivateIme"; -typedef bool (*ImeSharedLibActivateImeFn)(const char* ime_spec, - ImeClientDelegate* delegate); +inline constexpr char kImeDecoderActivateImeFnName[] = "ImeDecoderActivateIme"; +typedef bool (*ImeDecoderActivateImeFn)(const char* ime_spec, + ImeClientDelegate* delegate); -inline constexpr char kImeSharedLibProcessFnName[] = "ImeSharedLibProcess"; -typedef void (*ImeSharedLibProcessFn)(const uint8_t* data, size_t size); +inline constexpr char kImeDecoderProcessFnName[] = "ImeDecoderProcess"; +typedef void (*ImeDecoderProcessFn)(const uint8_t* data, size_t size); inline constexpr char kInitMojoModeFnName[] = "InitMojoMode"; typedef void (*InitMojoModeFn)(ImeCrosPlatform* platform); @@ -61,11 +60,12 @@ // END: Signatures of "C" API entry points of CrOS 1P IME shared lib. -// This class manages the dynamic loading of CrOS 1P IME shared lib.so -// and facilitates access to it's "C" API entry points. -class ImeSharedLib { +// TODO(b/214153032): Rename to ImeSharedLib to better reflect what this +// represents. This class manages the dynamic loading of CrOS 1P IME shared lib +// .so, and facilitates access to its "C" API entry points. +class ImeDecoder { public: - virtual ~ImeSharedLib() = default; + virtual ~ImeDecoder() = default; // Function pointers to "C" API entry points of the loaded IME shared library. // See ash/services/ime/public/cpp/shared_lib/interfaces.h for API specs. @@ -77,9 +77,9 @@ // indicate they only pertain to the IME shared lib's ProtoMode. While it's // "hard" to rename corresponding "C" API functions due to cross-repo // backward compat requirements, these are local and rename is feasible. - ImeSharedLibSupportsFn supports; - ImeSharedLibActivateImeFn activate_ime; - ImeSharedLibProcessFn process; + ImeDecoderSupportsFn supports; + ImeDecoderActivateImeFn activate_ime; + ImeDecoderProcessFn process; InitMojoModeFn init_mojo_mode; CloseMojoModeFn close_mojo_mode; @@ -99,23 +99,26 @@ virtual absl::optional<EntryPoints> MaybeLoadThenReturnEntryPoints() = 0; }; -// ImeSharedLib is implemented as a singleton and is initialized before 'ime' +// A proxy class for the IME decoder. +// ImeDecoder is implemented as a singleton and is initialized before 'ime' // sandbox is engaged. -class ImeSharedLibImpl : public ImeSharedLib { +// TODO(b/214153032): Rename to ImeSharedLibImpl, as soon as ImeDecoder is +// renamed to ImeSharedLib, to better reflect what this represents. +class ImeDecoderImpl : public ImeDecoder { public: - // Gets the singleton ImeSharedLibImpl. - static ImeSharedLibImpl* GetInstance(); + // Gets the singleton ImeDecoderImpl. + static ImeDecoderImpl* GetInstance(); - ImeSharedLibImpl(const ImeSharedLibImpl&) = delete; - ImeSharedLibImpl& operator=(const ImeSharedLibImpl&) = delete; + ImeDecoderImpl(const ImeDecoderImpl&) = delete; + ImeDecoderImpl& operator=(const ImeDecoderImpl&) = delete; absl::optional<EntryPoints> MaybeLoadThenReturnEntryPoints() override; private: - friend class base::NoDestructor<ImeSharedLibImpl>; + friend class base::NoDestructor<ImeDecoderImpl>; - explicit ImeSharedLibImpl(); - ~ImeSharedLibImpl() override; + explicit ImeDecoderImpl(); + ~ImeDecoderImpl() override; // Result of IME decoder DSO initialization. absl::optional<base::ScopedNativeLibrary> library_; @@ -126,4 +129,4 @@ } // namespace ime } // namespace ash -#endif // ASH_SERVICES_IME_IME_SHARED_LIB_H_ +#endif // ASH_SERVICES_IME_IME_DECODER_H_
diff --git a/ash/services/ime/ime_sandbox_hook.cc b/ash/services/ime/ime_sandbox_hook.cc index 23eb123..aa77e1c 100644 --- a/ash/services/ime/ime_sandbox_hook.cc +++ b/ash/services/ime/ime_sandbox_hook.cc
@@ -8,7 +8,7 @@ #include <vector> #include "ash/services/ime/constants.h" -#include "ash/services/ime/ime_shared_lib.h" +#include "ash/services/ime/ime_decoder.h" #include "base/files/file_path.h" #include "base/files/file_util.h" #include "base/logging.h" @@ -77,7 +77,7 @@ // TODO(crbug.com/1217513): This is not ideal, as it means rule-based // input methods will unnecessarily load the IME decoder shared library. // Either remove this line, or use a separate sandbox for rule-based. - ImeSharedLibImpl::GetInstance()->MaybeLoadThenReturnEntryPoints(); + ImeDecoderImpl::GetInstance()->MaybeLoadThenReturnEntryPoints(); instance->EngageNamespaceSandboxIfPossible(); return true; }
diff --git a/ash/services/ime/ime_service.cc b/ash/services/ime/ime_service.cc index 39534aa..711ea002 100644 --- a/ash/services/ime/ime_service.cc +++ b/ash/services/ime/ime_service.cc
@@ -58,11 +58,11 @@ ImeService::ImeService( mojo::PendingReceiver<mojom::ImeService> receiver, - ImeSharedLib* ime_shared_lib, + ImeDecoder* ime_decoder, std::unique_ptr<FieldTrialParamsRetriever> field_trial_params_retriever) : receiver_(this, std::move(receiver)), main_task_runner_(base::SequencedTaskRunnerHandle::Get()), - ime_shared_lib_(ime_shared_lib), + ime_decoder_(ime_decoder), field_trial_params_retriever_(std::move(field_trial_params_retriever)) {} ImeService::~ImeService() = default; @@ -107,7 +107,7 @@ ResetAllBackendConnections(); decoder_engine_ = std::make_unique<DecoderEngine>( - this, ime_shared_lib_->MaybeLoadThenReturnEntryPoints()); + this, ime_decoder_->MaybeLoadThenReturnEntryPoints()); bool bound = decoder_engine_->BindRequest( ime_spec, std::move(to_engine_request), std::move(from_engine), extra); std::move(callback).Run(bound); @@ -138,7 +138,7 @@ } case mojom::ConnectionTarget::kDecoder: { system_engine_ = std::make_unique<SystemEngine>( - this, ime_shared_lib_->MaybeLoadThenReturnEntryPoints()); + this, ime_decoder_->MaybeLoadThenReturnEntryPoints()); bool bound = system_engine_->BindConnectionFactory(std::move(connection_factory)); std::move(callback).Run(bound);
diff --git a/ash/services/ime/ime_service.h b/ash/services/ime/ime_service.h index b291b9d..c07f0c2 100644 --- a/ash/services/ime/ime_service.h +++ b/ash/services/ime/ime_service.h
@@ -55,7 +55,7 @@ public: explicit ImeService( mojo::PendingReceiver<mojom::ImeService> receiver, - ImeSharedLib* ime_shared_lib, + ImeDecoder* ime_decoder, std::unique_ptr<FieldTrialParamsRetriever> field_trial_params_retriever); ImeService(const ImeService&) = delete; @@ -133,7 +133,9 @@ mojo::Remote<mojom::PlatformAccessProvider> platform_access_; mojo::ReceiverSet<mojom::InputEngineManager> manager_receivers_; - ImeSharedLib* ime_shared_lib_ = nullptr; + // TODO(b/214153032): Rename to better reflect what this represents: + // ime_decoder_ --> ime_shared_lib_ + ImeDecoder* ime_decoder_ = nullptr; std::unique_ptr<FieldTrialParamsRetriever> field_trial_params_retriever_; };
diff --git a/ash/services/ime/ime_service_unittest.cc b/ash/services/ime/ime_service_unittest.cc index 360b651..3918ad1 100644 --- a/ash/services/ime/ime_service_unittest.cc +++ b/ash/services/ime/ime_service_unittest.cc
@@ -5,7 +5,7 @@ #include "ash/services/ime/ime_service.h" #include "ash/constants/ash_features.h" -#include "ash/services/ime/ime_shared_lib.h" +#include "ash/services/ime/ime_decoder.h" #include "ash/services/ime/mock_input_channel.h" #include "ash/services/ime/public/mojom/input_engine.mojom.h" #include "ash/services/ime/public/mojom/input_method.mojom.h" @@ -41,7 +41,7 @@ class TestDecoderState; // The fake decoder state has to be available globally because -// ImeSharedLib::EntryPoints is a list of stateless C functions, so the only way +// ImeDecoder::EntryPoints is a list of stateless C functions, so the only way // to have a stateful fake is to have a global reference to it. TestDecoderState* g_test_decoder_state = nullptr; @@ -77,14 +77,14 @@ mojo::Receiver<ime::mojom::ConnectionFactory> connection_factory_{this}; }; -class TestImeSharedLib : public ImeSharedLib { +class TestImeDecoder : public ImeDecoder { public: - static TestImeSharedLib* GetInstance() { - static base::NoDestructor<TestImeSharedLib> instance; + static TestImeDecoder* GetInstance() { + static base::NoDestructor<TestImeDecoder> instance; return instance.get(); } - absl::optional<ImeSharedLib::EntryPoints> MaybeLoadThenReturnEntryPoints() + absl::optional<ImeDecoder::EntryPoints> MaybeLoadThenReturnEntryPoints() override { return entry_points_; } @@ -120,13 +120,13 @@ } private: - friend class base::NoDestructor<TestImeSharedLib>; + friend class base::NoDestructor<TestImeDecoder>; - explicit TestImeSharedLib() { ResetState(); } + explicit TestImeDecoder() { ResetState(); } - ~TestImeSharedLib() override = default; + ~TestImeDecoder() override = default; - absl::optional<ImeSharedLib::EntryPoints> entry_points_; + absl::optional<ImeDecoder::EntryPoints> entry_points_; }; struct MockInputMethodHost : public mojom::InputMethodHost { @@ -212,7 +212,7 @@ void SetUp() override { service_ = std::make_unique<ImeService>( remote_service_.BindNewPipeAndPassReceiver(), - TestImeSharedLib::GetInstance(), + TestImeDecoder::GetInstance(), std::make_unique<TestFieldTrialParamsRetriever>()); remote_service_->BindInputEngineManager( remote_manager_.BindNewPipeAndPassReceiver()); @@ -220,7 +220,7 @@ void TearDown() override { service_.reset(); - TestImeSharedLib::GetInstance()->ResetState(); + TestImeDecoder::GetInstance()->ResetState(); } mojo::Remote<mojom::ImeService> remote_service_;
diff --git a/ash/shelf/shelf_app_button.cc b/ash/shelf/shelf_app_button.cc index 3ea3602ad..13c1534 100644 --- a/ash/shelf/shelf_app_button.cc +++ b/ash/shelf/shelf_app_button.cc
@@ -443,13 +443,18 @@ views::InkDrop::Get(this)->GetInkDrop()->GetTargetInkDropState()); views::InkDrop::Get(this)->GetInkDrop()->AnimateToState( views::InkDropState::DEACTIVATED); + context_menu_target_visibility_ = false; } void ShelfAppButton::ShowContextMenu(const gfx::Point& p, ui::MenuSourceType source_type) { - if (!context_menu_controller()) + // Return early if: + // 1. the context menu controller is not set; or + // 2. `context_menu_target_visibility_` is already true. + if (!context_menu_controller() || context_menu_target_visibility_) return; + context_menu_target_visibility_ = true; auto weak_this = weak_factory_.GetWeakPtr(); ShelfButton::ShowContextMenu(p, source_type); @@ -538,6 +543,12 @@ return icon_width == shelf_view_->GetButtonIconSize(); } +void ShelfAppButton::OnContextMenuModelRequestCanceled() { + // The request for the context menu model gets canceled so reset the context + // menu target visibility. + context_menu_target_visibility_ = false; +} + bool ShelfAppButton::FireDragTimerForTest() { if (!drag_timer_.IsRunning()) return false; @@ -764,15 +775,7 @@ // on a shelf app button, the button's inkdrop could be in the pending // state while the button's context menu is hidden. In this case, we // have to hide the inkdrop explicitly. - - // Note that the ET_GESTURE_END event may be received during the - // building of the context menu by triggering the synthesized gesture - // end event. Therefore we have to wait until the context menu is - // completely built. - base::SequencedTaskRunnerHandle::Get()->PostTask( - FROM_HERE, - base::BindOnce(&ShelfAppButton::MaybeHideInkDropWhenGestureEnds, - weak_factory_.GetWeakPtr())); + MaybeHideInkDropWhenGestureEnds(); } ClearDragStateOnGestureEnd(); @@ -956,11 +959,11 @@ } void ShelfAppButton::MaybeHideInkDropWhenGestureEnds() { - if (shelf_view_->IsShowingMenuForView(this) || + if (context_menu_target_visibility_ || views::InkDrop::Get(this)->GetInkDrop()->GetTargetInkDropState() == views::InkDropState::HIDDEN) { - // Return early if the shelf app button's context menu is showing or - // the button's inkdrop has been hidden. + // Return early if the shelf app button's context menu should show or + // the button's inkdrop has already been hidden. return; }
diff --git a/ash/shelf/shelf_app_button.h b/ash/shelf/shelf_app_button.h index 89405db..f7e0640 100644 --- a/ash/shelf/shelf_app_button.h +++ b/ash/shelf/shelf_app_button.h
@@ -19,7 +19,7 @@ namespace views { class DotIndicator; class ImageView; -} +} // namespace views namespace ash { struct ShelfItem; @@ -121,6 +121,9 @@ // Returns whether the icon size is up to date. bool IsIconSizeCurrent(); + // Called when the request for the context menu model is canceled. + void OnContextMenuModelRequestCanceled(); + bool FireDragTimerForTest(); void FireRippleActivationTimerForTest(); @@ -218,6 +221,11 @@ // A timer to activate the ink drop ripple during a long press. base::OneShotTimer ripple_activation_timer_; + // The target visibility of the shelf app's context menu. + // NOTE: when `context_menu_target_visibility_` is true, the context menu may + // not show yet due to the async request for the menu model. + bool context_menu_target_visibility_ = false; + std::unique_ptr<ShelfButtonDelegate::ScopedActiveInkDropCount> ink_drop_count_;
diff --git a/ash/shelf/shelf_view.cc b/ash/shelf/shelf_view.cc index 9d3825d..b18b5b3 100644 --- a/ash/shelf/shelf_view.cc +++ b/ash/shelf/shelf_view.cc
@@ -1499,6 +1499,8 @@ // a context menu just after drag starts. if (!context_menu_callback_.IsCancelled()) { context_menu_callback_.Cancel(); + GetShelfAppButton(item_awaiting_response_) + ->OnContextMenuModelRequestCanceled(); item_awaiting_response_ = ShelfID(); }
diff --git a/ash/shelf/shelf_view_unittest.cc b/ash/shelf/shelf_view_unittest.cc index 5576061..50a4277 100644 --- a/ash/shelf/shelf_view_unittest.cc +++ b/ash/shelf/shelf_view_unittest.cc
@@ -3432,6 +3432,57 @@ EXPECT_EQ(views::InkDropState::HIDDEN, GetInkDropStateOfAppIcon1()); } +TEST_F(ShelfViewGestureTapTest, + PressEscapeKeyBeforeReleaseLongPressOnAppButton) { + const ShelfID id = AddAppShortcut(); + auto item_delegate_owned = + std::make_unique<AsyncContextMenuShelfItemDelegate>(); + AsyncContextMenuShelfItemDelegate* item_delegate = item_delegate_owned.get(); + model_->ReplaceShelfItemDelegate(id, std::move(item_delegate_owned)); + + ShelfAppButton* app_button = GetButtonByID(id); + GetEventGenerator()->MoveTouch(app_button->GetBoundsInScreen().CenterPoint()); + GetEventGenerator()->PressTouch(); + + // Fast forward to generate the ET_GESTURE_SHOW_PRESS event. + task_environment()->FastForwardBy(base::Milliseconds(200)); + + // Fast forward to generate the ET_GESTURE_LONG_PRESS event to show the + // context menu. + task_environment()->FastForwardBy(base::Milliseconds(1000)); + EXPECT_TRUE(item_delegate->HasPendingContextMenuCallback()); + + // Build a dummy context menu and show it. + { + auto menu_model = std::make_unique<ui::SimpleMenuModel>(nullptr); + menu_model->AddItem(203, u"item"); + item_delegate->RunPendingContextMenuCallback(std::move(menu_model)); + EXPECT_TRUE(shelf_view_->IsShowingMenuForView(app_button)); + } + + // Press Escape. The context menu should be closed. + GetEventGenerator()->PressAndReleaseKey(ui::VKEY_ESCAPE); + EXPECT_FALSE(shelf_view_->IsShowingMenu()); + EXPECT_FALSE(item_delegate->HasPendingContextMenuCallback()); + + // Release the gesture press. The context menu should show again. + GetEventGenerator()->ReleaseTouch(); + task_environment()->FastForwardBy(base::Milliseconds(1000)); + EXPECT_TRUE(item_delegate->HasPendingContextMenuCallback()); + { + auto menu_model = std::make_unique<ui::SimpleMenuModel>(nullptr); + menu_model->AddItem(203, u"item"); + item_delegate->RunPendingContextMenuCallback(std::move(menu_model)); + EXPECT_TRUE(shelf_view_->IsShowingMenuForView(app_button)); + } + + // Verify that the ink drop of the app button for which the context menu shows + // for is activated. + EXPECT_EQ( + views::InkDropState::ACTIVATED, + views::InkDrop::Get(app_button)->GetInkDrop()->GetTargetInkDropState()); +} + // Verifies the shelf app button's inkdrop behavior when the mouse click // occurs before gesture long press. TEST_F(ShelfViewGestureTapTest, MouseClickInterruptionBeforeGestureLongPress) {
diff --git a/ash/system/machine_learning/user_settings_event_logger_unittest.cc b/ash/system/machine_learning/user_settings_event_logger_unittest.cc index 14dbf63f..26e0c5e 100644 --- a/ash/system/machine_learning/user_settings_event_logger_unittest.cc +++ b/ash/system/machine_learning/user_settings_event_logger_unittest.cc
@@ -50,8 +50,7 @@ wifi->signal_strength = signal_strength; wifi->security = security_type; network->type = NetworkType::kWiFi; - network->type_state = NetworkTypeStateProperties::New(); - network->type_state->set_wifi(std::move(wifi)); + network->type_state = NetworkTypeStateProperties::NewWifi(std::move(wifi)); return network; } @@ -62,8 +61,8 @@ CellularStatePropertiesPtr cellular = CellularStateProperties::New(); cellular->signal_strength = signal_strength; network->type = NetworkType::kCellular; - network->type_state = NetworkTypeStateProperties::New(); - network->type_state->set_cellular(std::move(cellular)); + network->type_state = + NetworkTypeStateProperties::NewCellular(std::move(cellular)); return network; }
diff --git a/ash/wallpaper/online_wallpaper_variant_info_fetcher.cc b/ash/wallpaper/online_wallpaper_variant_info_fetcher.cc deleted file mode 100644 index 2c25711b..0000000 --- a/ash/wallpaper/online_wallpaper_variant_info_fetcher.cc +++ /dev/null
@@ -1,280 +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 "ash/wallpaper/online_wallpaper_variant_info_fetcher.h" - -#include <algorithm> - -#include "ash/public/cpp/wallpaper/online_wallpaper_params.h" -#include "ash/public/cpp/wallpaper/online_wallpaper_variant.h" -#include "ash/public/cpp/wallpaper/wallpaper_controller_client.h" -#include "ash/public/cpp/wallpaper/wallpaper_info.h" -#include "ash/webui/personalization_app/proto/backdrop_wallpaper.pb.h" -#include "base/bind.h" -#include "base/callback.h" -#include "base/logging.h" -#include "base/strings/string_piece.h" -#include "base/task/post_task.h" -#include "base/threading/sequenced_task_runner_handle.h" - -namespace ash { -namespace { - -// Convenience alias for ColorMode enum. -using ColorMode = OnlineWallpaperVariantInfoFetcher::ColorMode; - -// Checks if the given |variant| is suitable for the current system's color -// mode. Image with type |Image_ImageType_IMAGE_TYPE_UNKNOWN| is not D/L aware -// and should be used regardless of color mode. -bool IsSuitableOnlineWallpaperVariant(const OnlineWallpaperVariant& variant, - ColorMode mode) { - switch (variant.type) { - case backdrop::Image_ImageType_IMAGE_TYPE_UNKNOWN: - return true; - case backdrop::Image_ImageType_IMAGE_TYPE_LIGHT_MODE: - return mode == ColorMode::kLightMode; - case backdrop::Image_ImageType_IMAGE_TYPE_DARK_MODE: - return mode == ColorMode::kDarkMode; - } -} - -// Returns a pointer to the first matching variant in |variants| if one -// exists. -const OnlineWallpaperVariant* FirstValidVariant( - const std::vector<OnlineWallpaperVariant>& variants, - ColorMode mode) { - const auto iter = std::find_if( - variants.begin(), variants.end(), [mode](const auto& variant) { - return IsSuitableOnlineWallpaperVariant(variant, mode); - }); - if (iter != variants.end()) - return &(*iter); - - return nullptr; -} - -// The filtered results from a set of backdrop::Images for a given |asset_id| -// and |mode| value. -class VariantMatches { - public: - VariantMatches(VariantMatches&&) = default; - - VariantMatches(const VariantMatches&) = delete; - VariantMatches& operator=(const VariantMatches&) = delete; - - ~VariantMatches() = default; - - // Filters |images| to only the entries that match |asset_id| and - // |mode|. - static absl::optional<VariantMatches> FromImages( - uint64_t asset_id, - ColorMode mode, - const std::vector<backdrop::Image>& images) { - // Find the exact image in the |images| collection. - auto image_iter = std::find_if(images.begin(), images.end(), - [asset_id](const backdrop::Image& image) { - return asset_id == image.asset_id(); - }); - - if (image_iter == images.end()) - return absl::nullopt; - - uint64_t unit_id = image_iter->unit_id(); - std::vector<OnlineWallpaperVariant> variants; - for (const auto& image : images) { - if (image.unit_id() == unit_id) { - variants.emplace_back(image.asset_id(), GURL(image.image_url()), - image.has_image_type() - ? image.image_type() - : backdrop::Image::IMAGE_TYPE_UNKNOWN); - } - } - - const OnlineWallpaperVariant* variant = FirstValidVariant(variants, mode); - if (!variant) { - // At least one usable variant must be found to use this set of images. - return absl::nullopt; - } - - return VariantMatches(unit_id, std::move(variants), *variant); - } - - // The unit id of the Variant that matched |asset_id| and |mode|. - const uint64_t unit_id; - - // The set of images that are appropriate for |asset_id| and - // |mode|. - const std::vector<OnlineWallpaperVariant> variants; - - // The first instance from |variants| that matches |asset_id| and - // |mode|. - const OnlineWallpaperVariant first_match; - - private: - VariantMatches(uint64_t unit_id_in, - std::vector<OnlineWallpaperVariant>&& variants_in, - const OnlineWallpaperVariant& first_match_in) - : unit_id(unit_id_in), - variants(variants_in), - first_match(first_match_in) { - DCHECK_EQ(std::count(variants.begin(), variants.end(), first_match), 1); - } -}; - -bool IsDaily(const WallpaperInfo& info) { - return info.type == WallpaperType::kDaily; -} - -} // namespace - -OnlineWallpaperVariantInfoFetcher::OnlineWallpaperRequest:: - OnlineWallpaperRequest(const AccountId& account_id_in, - const std::string& collection_id_in, - WallpaperLayout layout_in, - bool daily_refresh_enabled_in, - ColorMode mode_in) - : account_id(account_id_in), - collection_id(collection_id_in), - layout(layout_in), - daily_refresh_enabled(daily_refresh_enabled_in), - mode(mode_in) {} - -OnlineWallpaperVariantInfoFetcher::OnlineWallpaperRequest:: - ~OnlineWallpaperRequest() = default; - -OnlineWallpaperVariantInfoFetcher::OnlineWallpaperVariantInfoFetcher() = - default; -OnlineWallpaperVariantInfoFetcher::~OnlineWallpaperVariantInfoFetcher() = - default; - -void OnlineWallpaperVariantInfoFetcher::SetClient( - WallpaperControllerClient* client) { - wallpaper_controller_client_ = client; -} - -void OnlineWallpaperVariantInfoFetcher::FetchOnlineWallpaper( - const AccountId& account_id, - const WallpaperInfo& info, - ColorMode mode, - FetchParamsCallback callback) { - DCHECK(info.type == WallpaperType::kDaily || - info.type == WallpaperType::kOnline); - - DCHECK(wallpaper_controller_client_); - - if (info.unit_id.has_value() && !info.variants.empty()) { - // |info| already has all of the data we need. - const OnlineWallpaperVariant* variant = - FirstValidVariant(info.variants, mode); - if (!variant) { - NOTREACHED() << "No suitable wallpaper for " - << (mode == ColorMode::kDarkMode ? "dark" : "lite") - << " mode in collection"; - base::SequencedTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::BindOnce(std::move(callback), absl::nullopt)); - return; - } - - base::SequencedTaskRunnerHandle::Get()->PostTask( - FROM_HERE, - base::BindOnce( - std::move(callback), - OnlineWallpaperParams{account_id, variant->asset_id, - GURL(variant->raw_url), info.collection_id, - info.layout, /*preview_mode=*/false, - /*from_user=*/false, IsDaily(info), - info.unit_id, info.variants})); - return; - } - - // For requests from existing WallpaperInfo, asset_id is always populated. - DCHECK(info.asset_id.has_value()); - - bool daily = IsDaily(info); - auto request = std::make_unique<OnlineWallpaperRequest>( - account_id, info.collection_id, info.layout, daily, mode); - - wallpaper_controller_client_->FetchImagesForCollection( - request->collection_id, - base::BindOnce( - &OnlineWallpaperVariantInfoFetcher::FindAndSetOnlineWallpaperVariants, - weak_factory_.GetWeakPtr(), std::move(request), *info.asset_id, - std::move(callback))); -} - -bool OnlineWallpaperVariantInfoFetcher::FetchDailyWallpaper( - const AccountId& account_id, - const WallpaperInfo& info, - ColorMode mode, - FetchParamsCallback callback) { - DCHECK(IsDaily(info)); - - // We might not have a client yet. - if (!wallpaper_controller_client_) - return false; - - bool daily = true; // This is always a a daily wallpaper. - auto request = std::make_unique<OnlineWallpaperRequest>( - account_id, info.collection_id, info.layout, daily, mode); - wallpaper_controller_client_->FetchDailyRefreshWallpaper( - info.collection_id, - base::BindOnce(&OnlineWallpaperVariantInfoFetcher::OnSingleFetch, - weak_factory_.GetWeakPtr(), std::move(request), - std::move(callback))); - return true; -} - -void OnlineWallpaperVariantInfoFetcher::OnSingleFetch( - std::unique_ptr<OnlineWallpaperRequest> request, - FetchParamsCallback callback, - bool success, - const backdrop::Image& image) { - if (!success) { - std::move(callback).Run(absl::nullopt); - return; - } - - // If wallpaper_controller_client_ is null, we're shutting down. - if (!wallpaper_controller_client_) - return; - - wallpaper_controller_client_->FetchImagesForCollection( - request->collection_id, - base::BindOnce( - &OnlineWallpaperVariantInfoFetcher::FindAndSetOnlineWallpaperVariants, - weak_factory_.GetWeakPtr(), std::move(request), image.asset_id(), - std::move(callback))); -} - -void OnlineWallpaperVariantInfoFetcher::FindAndSetOnlineWallpaperVariants( - std::unique_ptr<OnlineWallpaperRequest> request, - uint64_t asset_id, - FetchParamsCallback callback, - bool success, - const std::vector<backdrop::Image>& images) { - if (!success) { - LOG(WARNING) << "Failed to fetch online wallpapers"; - std::move(callback).Run(absl::nullopt); - return; - } - - absl::optional<VariantMatches> matches = - VariantMatches::FromImages(asset_id, request->mode, images); - if (!matches) { - LOG(ERROR) << "No valid variants"; - std::move(callback).Run(absl::nullopt); - return; - } - - const OnlineWallpaperVariant& first_image = matches->first_match; - DCHECK(IsSuitableOnlineWallpaperVariant(first_image, request->mode)); - - std::move(callback).Run(ash::OnlineWallpaperParams{ - request->account_id, first_image.asset_id, first_image.raw_url, - request->collection_id, request->layout, /*preview_mode=*/false, - /*from_user=*/false, request->daily_refresh_enabled, matches->unit_id, - matches->variants}); -} - -} // namespace ash
diff --git a/ash/wallpaper/online_wallpaper_variant_info_fetcher.h b/ash/wallpaper/online_wallpaper_variant_info_fetcher.h deleted file mode 100644 index ca27f54..0000000 --- a/ash/wallpaper/online_wallpaper_variant_info_fetcher.h +++ /dev/null
@@ -1,115 +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 ASH_WALLPAPER_ONLINE_WALLPAPER_VARIANT_INFO_FETCHER_H_ -#define ASH_WALLPAPER_ONLINE_WALLPAPER_VARIANT_INFO_FETCHER_H_ - -#include <memory> -#include <string> -#include <vector> - -#include "ash/ash_export.h" -#include "ash/public/cpp/wallpaper/online_wallpaper_params.h" -#include "ash/public/cpp/wallpaper/online_wallpaper_variant.h" -#include "ash/public/cpp/wallpaper/wallpaper_info.h" -#include "base/callback_forward.h" -#include "base/memory/raw_ptr.h" -#include "base/memory/weak_ptr.h" -#include "components/account_id/account_id.h" - -namespace backdrop { -class Image; -} - -namespace ash { - -class WallpaperControllerClient; - -// Resolves wallpaper variants from WallpaperInfo for WallpaperController. -class ASH_EXPORT OnlineWallpaperVariantInfoFetcher { - public: - enum class ColorMode { - kDarkMode = 0, - kLightMode, - }; - - OnlineWallpaperVariantInfoFetcher(); - - OnlineWallpaperVariantInfoFetcher(const OnlineWallpaperVariantInfoFetcher&) = - delete; - OnlineWallpaperVariantInfoFetcher& operator=( - const OnlineWallpaperVariantInfoFetcher&) = delete; - - ~OnlineWallpaperVariantInfoFetcher(); - - void SetClient(WallpaperControllerClient* client); - - // Callback for Fetch* methods which populates the |unit_id| and |variants| - // fields in OnlineWallpaperParams. - using FetchParamsCallback = - base::OnceCallback<void(absl::optional<OnlineWallpaperParams>)>; - - // Fetches the wallpaper variants for |info| to produce a fully populated - // OnlineWallpaperParams in |callback|. The selected wallpaper will is - // designated by asset_id in |info|. - void FetchOnlineWallpaper(const AccountId& account_id, - const WallpaperInfo& info, - OnlineWallpaperVariantInfoFetcher::ColorMode mode, - FetchParamsCallback callback); - - // Always fetches a new daily refresh wallpaper and calls |callback| with a - // fully populated OnlineWallpaperParams. - bool FetchDailyWallpaper(const AccountId& account_id, - const WallpaperInfo& info, - OnlineWallpaperVariantInfoFetcher::ColorMode mode, - FetchParamsCallback callback); - - private: - // An internal representation of the partial information required to construct - // a complete OnlineWallpaperParams object as provided by the caller of - // Fetch*. - class OnlineWallpaperRequest { - public: - OnlineWallpaperRequest(const AccountId& account_id, - const std::string& collection_id, - WallpaperLayout layout, - bool daily_refresh_enabled, - OnlineWallpaperVariantInfoFetcher::ColorMode mode); - OnlineWallpaperRequest(const OnlineWallpaperRequest&) = delete; - OnlineWallpaperRequest& operator=(const OnlineWallpaperRequest&) = delete; - ~OnlineWallpaperRequest(); - - AccountId account_id; - std::string collection_id; - WallpaperLayout layout; - bool daily_refresh_enabled; - OnlineWallpaperVariantInfoFetcher::ColorMode mode; - }; - - // Handles the response for a single random image in a collection and proceeds - // to fetch the rest of the collection. - void OnSingleFetch(std::unique_ptr<OnlineWallpaperRequest> request, - FetchParamsCallback callback, - bool success, - const backdrop::Image& image); - - // Finishes variants fetch by populating the remaining fields for - // OnlineWallpaperParams in |callback|. Combines data from |request| with - // |images| and the matching variant in |images| for |asset_id|. - void FindAndSetOnlineWallpaperVariants( - std::unique_ptr<OnlineWallpaperRequest> request, - uint64_t asset_id, - FetchParamsCallback callback, - bool success, - const std::vector<backdrop::Image>& images); - - raw_ptr<WallpaperControllerClient> wallpaper_controller_client_ = - nullptr; // not owned - - base::WeakPtrFactory<OnlineWallpaperVariantInfoFetcher> weak_factory_{this}; -}; - -} // namespace ash - -#endif // ASH_WALLPAPER_ONLINE_WALLPAPER_VARIANT_INFO_FETCHER_H_
diff --git a/ash/wallpaper/online_wallpaper_variant_info_fetcher_unittest.cc b/ash/wallpaper/online_wallpaper_variant_info_fetcher_unittest.cc deleted file mode 100644 index 310abfb..0000000 --- a/ash/wallpaper/online_wallpaper_variant_info_fetcher_unittest.cc +++ /dev/null
@@ -1,251 +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 "ash/wallpaper/online_wallpaper_variant_info_fetcher.h" - -#include "ash/public/cpp/wallpaper/wallpaper_info.h" -#include "ash/wallpaper/test_wallpaper_controller_client.h" -#include "base/callback_forward.h" -#include "base/run_loop.h" -#include "base/strings/stringprintf.h" -#include "base/test/gtest_util.h" -#include "base/test/task_environment.h" -#include "base/test/test_future.h" -#include "components/account_id/account_id.h" -#include "testing/gmock/include/gmock/gmock-matchers.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace ash { -namespace { - -// Convenience aliases for light and dark mode names. -using ColorMode = OnlineWallpaperVariantInfoFetcher::ColorMode; - -constexpr char kUser1[] = "user1@test.com"; -const AccountId kAccount1 = AccountId::FromUserEmailGaiaId(kUser1, kUser1); -constexpr char kDummyCollectionId[] = "testCollectionId"; - -// Returns a set of images with the given |type|. -std::vector<backdrop::Image> ImageSet(backdrop::Image_ImageType type, - size_t size) { - std::vector<backdrop::Image> images; - for (size_t i = 0; i < size; i++) { - images.emplace_back(); - images.back().set_image_url( - base::StringPrintf("https://test_wallpaper/%zu", i)); - // A "unique" asset id. - images.back().set_asset_id(42 + i); - // Images should all have a different unit id except in a light/dark pair. - images.back().set_unit_id(13 + i); - images.back().set_image_type(type); - } - return images; -} - -class OnlineWallpaperVariantInfoFetcherTest : public testing::Test { - public: - OnlineWallpaperVariantInfoFetcherTest() - : task_environment_(base::test::TaskEnvironment::MainThreadType::UI) {} - - void SetUp() override { - wallpaper_fetcher_ = std::make_unique<OnlineWallpaperVariantInfoFetcher>(); - wallpaper_fetcher_->SetClient(&client_); - } - - void TearDown() override {} - - protected: - base::test::SingleThreadTaskEnvironment task_environment_; - - TestWallpaperControllerClient client_; - std::unique_ptr<OnlineWallpaperVariantInfoFetcher> wallpaper_fetcher_; -}; - -// Verify that variants in params is populated. -TEST_F(OnlineWallpaperVariantInfoFetcherTest, - FetchDailyWallpaper_VariantsPopulated) { - base::test::TestFuture<absl::optional<OnlineWallpaperParams>> test_future; - WallpaperInfo info("", WallpaperLayout::WALLPAPER_LAYOUT_CENTER, - WallpaperType::kDaily, base::Time::Now()); - info.collection_id = kDummyCollectionId; - - wallpaper_fetcher_->FetchDailyWallpaper( - kAccount1, info, ColorMode::kLightMode, test_future.GetCallback()); - - ASSERT_TRUE(test_future.Wait()) << "Fetch Daily never ran callback"; - auto result = test_future.Get(); - ASSERT_TRUE(result); - EXPECT_FALSE(result->variants.empty()); -} - -// Verify that repeated requests for daily wallpaper changes the url. -TEST_F(OnlineWallpaperVariantInfoFetcherTest, - FetchDailyWallpaper_EveryRequestDifferent) { - // Add some images for a new collection id. - const std::string kCollectionId = "FetchDaily"; - client_.AddCollection(kCollectionId, - ImageSet(backdrop::Image::IMAGE_TYPE_UNKNOWN, 6u)); - - // First fetch - base::test::TestFuture<absl::optional<OnlineWallpaperParams>> test_future; - WallpaperInfo info("", WallpaperLayout::WALLPAPER_LAYOUT_CENTER, - WallpaperType::kDaily, base::Time::Now()); - info.collection_id = kCollectionId; - - wallpaper_fetcher_->FetchDailyWallpaper( - kAccount1, info, ColorMode::kLightMode, test_future.GetCallback()); - auto first_result = test_future.Get(); - EXPECT_TRUE(first_result); - - // Calling FetchDaily with the same arguments should yield a different params - // object if there is more than one wallpaper in the collection. - base::test::TestFuture<absl::optional<OnlineWallpaperParams>> test_future2; - wallpaper_fetcher_->FetchDailyWallpaper( - kAccount1, info, ColorMode::kLightMode, test_future2.GetCallback()); - - auto second_result = test_future2.Get(); - EXPECT_TRUE(second_result); - - EXPECT_NE(first_result->url, second_result->url) - << "Urls for the two calls should be different"; -} - -// Verify that variants with matching unit id are selected and the asset of the -// appropriate type (dark/light). -TEST_F(OnlineWallpaperVariantInfoFetcherTest, - FetchOnlineWallpaper_DarkLightVariants) { - // Add some images for a new collection id. - const std::string kCollectionId = "FetchOnline"; - const uint64_t kLightAssetId = 99; - const std::string kLightUrl = "https://preferred_wallpaper/images/99"; - const uint64_t kDarkAssetId = 103; - const std::string kDarkUrl = "https://preferred_wallpaper/images/103"; - const uint64_t kUnitId = 432; - - // Initially populate the collection with images we won't use. - std::vector<backdrop::Image> images = - ImageSet(backdrop::Image::IMAGE_TYPE_UNKNOWN, 6u); - - // Push a dark and light asset that share a unit id. - backdrop::Image light_image; - light_image.set_asset_id(kLightAssetId); - light_image.set_unit_id(kUnitId); - light_image.set_image_type(backdrop::Image::IMAGE_TYPE_LIGHT_MODE); - light_image.set_image_url(kLightUrl); - images.push_back(light_image); - - backdrop::Image dark_image; - dark_image.set_asset_id(kDarkAssetId); - dark_image.set_unit_id(kUnitId); - dark_image.set_image_type(backdrop::Image::IMAGE_TYPE_DARK_MODE); - dark_image.set_image_url(kDarkUrl); - images.push_back(dark_image); - - client_.AddCollection(kCollectionId, images); - - base::test::TestFuture<absl::optional<OnlineWallpaperParams>> test_future; - WallpaperInfo info("", WallpaperLayout::WALLPAPER_LAYOUT_CENTER, - WallpaperType::kOnline, base::Time::Now()); - info.collection_id = kCollectionId; - info.asset_id = kLightAssetId; - { - // Checking light mode where asset id matches. - wallpaper_fetcher_->FetchOnlineWallpaper( - kAccount1, info, ColorMode::kLightMode, test_future.GetCallback()); - auto result = test_future.Get(); - EXPECT_TRUE(result); - EXPECT_EQ(2u, result->variants.size()); - EXPECT_EQ(kLightUrl, result->url.spec()); - } - { - base::test::TestFuture<absl::optional<OnlineWallpaperParams>> test_future; - - // Verify that we get a dark mode asset when in dark mode but our asset_id - // is for a light asset. - wallpaper_fetcher_->FetchOnlineWallpaper( - kAccount1, info, ColorMode::kDarkMode, test_future.GetCallback()); - auto result = test_future.Get(); - EXPECT_TRUE(result); - EXPECT_EQ(2u, result->variants.size()); - EXPECT_EQ(kDarkUrl, result->url.spec()); - } -} - -// Verify that the request fails if there are no matching variants for dark -// mode. -TEST_F(OnlineWallpaperVariantInfoFetcherTest, FetchOnlineWallpaper_NoDarkMode) { - const std::string kCollectionId = "OnlyLightModeWallpaper"; - std::vector<backdrop::Image> images = - ImageSet(backdrop::Image::IMAGE_TYPE_LIGHT_MODE, 4u); - client_.AddCollection(kCollectionId, images); - - base::test::TestFuture<absl::optional<OnlineWallpaperParams>> test_future; - WallpaperInfo info("", WallpaperLayout::WALLPAPER_LAYOUT_CENTER, - WallpaperType::kOnline, base::Time::Now()); - info.collection_id = kCollectionId; - // Pick an arbiratry asset in the set. - info.asset_id = images.front().asset_id(); - - // Initial request will pass because variants are not populated in |info|. - // Requesting dark mode when there are only light assets. - wallpaper_fetcher_->FetchOnlineWallpaper( - kAccount1, info, ColorMode::kDarkMode, test_future.GetCallback()); - - // Result should be missing if no suitable variants are found. - auto result = test_future.Get(); - EXPECT_FALSE(result); -} - -// When variants are already populated, params are returned. -TEST_F(OnlineWallpaperVariantInfoFetcherTest, FetchOnlineWallpaper_FromInfo) { - const uint64_t kAssetId = 14; - const GURL kUrl("https://populated_url/14"); - const std::string kCollectionId = "PrePopulatedCollection"; - const uint64_t kUnitId = 31; - const std::vector<OnlineWallpaperVariant> kVariants = {OnlineWallpaperVariant( - kAssetId, kUrl, backdrop::Image::IMAGE_TYPE_UNKNOWN)}; - OnlineWallpaperParams params( - kAccount1, kAssetId, kUrl, kCollectionId, - WallpaperLayout::WALLPAPER_LAYOUT_CENTER, /*preview_mode=*/false, - /*from_user=*/true, /*daily_refresh_enabled=*/false, kUnitId, kVariants); - WallpaperInfo info(params); - - base::test::TestFuture<absl::optional<OnlineWallpaperParams>> test_future; - wallpaper_fetcher_->FetchOnlineWallpaper( - kAccount1, info, ColorMode::kDarkMode, test_future.GetCallback()); - - // Callback is called - auto result = test_future.Get(); - EXPECT_TRUE(result); - - // WallpaperControllerClient is not used if OnlineWallpaperParams is fully - // populated. - EXPECT_EQ(0u, client_.fetch_images_for_collection_count()); -} - -// When variants are already populated but types don't match, returns false. -TEST_F(OnlineWallpaperVariantInfoFetcherTest, - FetchOnlineWallpaper_FromInfoLightDarkMismatch) { - const uint64_t kAssetId = 14; - const GURL kUrl("https://populated_url/14"); - const std::string kCollectionId = "PrePopulatedCollection"; - const uint64_t kUnitId = 31; - // Only one light mode wallpaper - const std::vector<OnlineWallpaperVariant> kVariants = {OnlineWallpaperVariant( - kAssetId, kUrl, backdrop::Image::IMAGE_TYPE_LIGHT_MODE)}; - - OnlineWallpaperParams params( - kAccount1, kAssetId, kUrl, kCollectionId, - WallpaperLayout::WALLPAPER_LAYOUT_CENTER, /*preview_mode=*/false, - /*from_user=*/true, /*daily_refresh_enabled=*/false, kUnitId, kVariants); - WallpaperInfo info(params); - - // In dark mode, fetch will fail if the variant is missing. - base::test::TestFuture<absl::optional<OnlineWallpaperParams>> test_future; - EXPECT_DCHECK_DEATH(wallpaper_fetcher_->FetchOnlineWallpaper( - kAccount1, info, ColorMode::kDarkMode, test_future.GetCallback())); -} - -} // namespace -} // namespace ash
diff --git a/ash/wallpaper/test_wallpaper_controller_client.cc b/ash/wallpaper/test_wallpaper_controller_client.cc index aebeb14..3be9167 100644 --- a/ash/wallpaper/test_wallpaper_controller_client.cc +++ b/ash/wallpaper/test_wallpaper_controller_client.cc
@@ -37,12 +37,6 @@ TestWallpaperControllerClient::~TestWallpaperControllerClient() = default; -void TestWallpaperControllerClient::AddCollection( - const std::string& collection_id, - const std::vector<backdrop::Image>& images) { - variations_[collection_id] = images; -} - void TestWallpaperControllerClient::ResetCounts() { open_count_ = 0; close_preview_count_ = 0; @@ -89,15 +83,13 @@ return; } - image_index_ = ++image_index_ % iter->second.size(); - backdrop::Image image(iter->second.at(image_index_)); + backdrop::Image image(iter->second.back()); std::move(callback).Run(/*success=*/true, std::move(image)); } void TestWallpaperControllerClient::FetchImagesForCollection( const std::string& collection_id, FetchImagesForCollectionCallback callback) { - fetch_images_for_collection_count_++; auto iter = variations_.find(collection_id); if (fetch_images_for_collection_fails_ || iter == variations_.end()) { std::move(callback).Run(/*success=*/false, std::vector<backdrop::Image>());
diff --git a/ash/wallpaper/test_wallpaper_controller_client.h b/ash/wallpaper/test_wallpaper_controller_client.h index 23e53bb5..ff7d38d 100644 --- a/ash/wallpaper/test_wallpaper_controller_client.h +++ b/ash/wallpaper/test_wallpaper_controller_client.h
@@ -29,11 +29,6 @@ const TestWallpaperControllerClient&) = delete; virtual ~TestWallpaperControllerClient(); - // Add a set of |images| for |collection_id| that will be returned for - // FetchDailyRefreshWallpaper and FetchImagesForCollection. - void AddCollection(const std::string& collection_id, - const std::vector<backdrop::Image>& images); - size_t open_count() const { return open_count_; } size_t close_preview_count() const { return close_preview_count_; } size_t set_default_wallpaper_count() const { @@ -42,9 +37,6 @@ size_t migrate_collection_id_from_chrome_app_count() const { return migrate_collection_id_from_chrome_app_count_; } - size_t fetch_images_for_collection_count() const { - return fetch_images_for_collection_count_; - } std::string get_fetch_daily_refresh_wallpaper_param() const { return fetch_daily_refresh_wallpaper_param_; } @@ -118,7 +110,6 @@ size_t close_preview_count_ = 0; size_t set_default_wallpaper_count_ = 0; size_t migrate_collection_id_from_chrome_app_count_ = 0; - size_t fetch_images_for_collection_count_ = 0; std::string fetch_daily_refresh_wallpaper_param_; bool fetch_daily_refresh_info_fails_ = false; AccountId get_wallpaper_path_from_drive_fs_account_id_; @@ -129,7 +120,6 @@ bool fetch_google_photos_photo_fails_ = false; bool google_photo_has_been_deleted_ = false; - int image_index_ = 0; base::flat_map<std::string, std::vector<backdrop::Image>> variations_; };
diff --git a/ash/wallpaper/wallpaper_controller_impl.cc b/ash/wallpaper/wallpaper_controller_impl.cc index c56284e..a315d721 100644 --- a/ash/wallpaper/wallpaper_controller_impl.cc +++ b/ash/wallpaper/wallpaper_controller_impl.cc
@@ -36,6 +36,7 @@ #include "ash/wallpaper/wallpaper_widget_controller.h" #include "ash/wallpaper/wallpaper_window_state_manager.h" #include "ash/webui/personalization_app/mojom/personalization_app.mojom.h" +#include "ash/webui/personalization_app/proto/backdrop_wallpaper.pb.h" #include "ash/wm/overview/overview_constants.h" #include "ash/wm/overview/overview_controller.h" #include "ash/wm/tablet_mode/tablet_mode_controller.h" @@ -487,6 +488,22 @@ return url_to_file_path_map; } +// Checks if the given |variant| is suitable for the current system's color +// mode. Image with type |Image_ImageType_IMAGE_TYPE_UNKNOWN| is not D/L aware +// and should be used regardless of color mode. +bool IsSuitableOnlineWallpaperVariant(const OnlineWallpaperVariant& variant) { + bool dark_mode_enabled = + Shell::Get()->ash_color_provider()->IsDarkModeEnabled(); + switch (variant.type) { + case backdrop::Image_ImageType_IMAGE_TYPE_UNKNOWN: + return true; + case backdrop::Image_ImageType_IMAGE_TYPE_LIGHT_MODE: + return !dark_mode_enabled; + case backdrop::Image_ImageType_IMAGE_TYPE_DARK_MODE: + return dark_mode_enabled; + } +} + // Saves the online wallpaper with both large and small sizes to local file // system. void SaveOnlineWallpaper(const std::string& url, @@ -768,13 +785,6 @@ kLargeWallpaperMaxHeight)); } -// Returns an appropriate ColorMode value based on the Light/Dark mode state. -OnlineWallpaperVariantInfoFetcher::ColorMode GetColorMode() { - return Shell::Get()->ash_color_provider()->IsDarkModeEnabled() - ? OnlineWallpaperVariantInfoFetcher::ColorMode::kDarkMode - : OnlineWallpaperVariantInfoFetcher::ColorMode::kLightMode; -} - } // namespace const char WallpaperControllerImpl::kSmallWallpaperSubDir[] = "small"; @@ -798,17 +808,11 @@ // static std::unique_ptr<WallpaperControllerImpl> WallpaperControllerImpl::Create( PrefService* local_state) { - auto online_wallpaper_variant_fetcher = - std::make_unique<OnlineWallpaperVariantInfoFetcher>(); - return std::make_unique<WallpaperControllerImpl>( - local_state, std::move(online_wallpaper_variant_fetcher)); + return std::make_unique<WallpaperControllerImpl>(local_state); } -WallpaperControllerImpl::WallpaperControllerImpl( - PrefService* local_state, - std::unique_ptr<OnlineWallpaperVariantInfoFetcher> online_fetcher) - : variant_info_fetcher_(std::move(online_fetcher)), - color_profiles_(GetProminentColorProfiles()), +WallpaperControllerImpl::WallpaperControllerImpl(PrefService* local_state) + : color_profiles_(GetProminentColorProfiles()), wallpaper_reload_delay_(kWallpaperReloadDelay), sequenced_task_runner_(base::ThreadPool::CreateSequencedTaskRunner( {base::MayBlock(), base::TaskPriority::USER_VISIBLE, @@ -1177,7 +1181,6 @@ void WallpaperControllerImpl::SetClient(WallpaperControllerClient* client) { wallpaper_controller_client_ = client; - variant_info_fetcher_->SetClient(client); } void WallpaperControllerImpl::Init( @@ -2233,29 +2236,6 @@ url_to_file_path_map.at(params.url.spec())); } -void WallpaperControllerImpl::OnWallpaperVariantsFetched( - WallpaperType type, - SetWallpaperCallback callback, - absl::optional<OnlineWallpaperParams> params) { - DCHECK(type == WallpaperType::kDaily || type == WallpaperType::kOnline); - if (params) { - SetOnlineWallpaper(*params, std::move(callback)); - - // The Daily Refresh timer depends on the value of the user WallpaperInfo. - // it after setting the wallpaper value. - if (type == WallpaperType::kDaily) - StartDailyRefreshTimer(); - return; - } - - // Report that setting the wallpaper failed. - std::move(callback).Run(false); - - // Daily wallpaper should schedule retry. - if (type == WallpaperType::kDaily) - OnFetchDailyWallpaperFailed(); -} - void WallpaperControllerImpl::OnOnlineWallpaperDecoded( const OnlineWallpaperParams& params, bool save_file, @@ -3015,7 +2995,7 @@ HandleDailyWallpaperInfoSyncedIn(account_id, info); break; case WallpaperType::kOnline: - HandleSettingOnlineWallpaperFromWallpaperInfo(account_id, info); + HandleOnlineWallpaperInfoSyncedIn(account_id, info); break; case WallpaperType::kGooglePhotos: case WallpaperType::kDailyGooglePhotos: @@ -3078,7 +3058,6 @@ size_t current_index, const gfx::ImageSkia& image) { if (image.isNull()) { - LOG(WARNING) << "Image download failed " << current_index; std::move(on_done).Run(); return; } @@ -3177,8 +3156,7 @@ } if (synced_info == local_info) return; - if (synced_info.date >= local_info.date) { - // If synced is newer or the same age, it wins. + if (synced_info.date > local_info.date) { HandleWallpaperInfoSyncedIn(account_id, synced_info); } else if (local_info.type == WallpaperType::kCustomized) { // Generally, we handle setting synced_info when local_info is updated. @@ -3229,19 +3207,13 @@ set_wallpaper_weak_factory_.GetWeakPtr(), account_id, info.collection_id, std::move(callback))); } else { - DCHECK_EQ(info.type, WallpaperType::kDaily); - OnlineWallpaperVariantInfoFetcher::FetchParamsCallback fetch_callback = - base::BindOnce(&WallpaperControllerImpl::OnWallpaperVariantsFetched, - set_wallpaper_weak_factory_.GetWeakPtr(), info.type, - std::move(callback)); - // Fetch can fail if wallpaper_controller_client has been cleared or - // |info| is malformed. - if (!variant_info_fetcher_->FetchDailyWallpaper( - account_id, info, GetColorMode(), std::move(fetch_callback))) { - // Could not start fetch of wallpaper variants. Likely because the - // chrome client isn't ready. Schedule for later. - NOTREACHED() << "Failed to initiate daily wallpaper fetch"; - } + wallpaper_controller_client_->FetchDailyRefreshWallpaper( + GetDailyRefreshCollectionId(account_id), + base::BindOnce(&WallpaperControllerImpl::SetDailyWallpaper, + set_wallpaper_weak_factory_.GetWeakPtr(), account_id, + GetDailyRefreshCollectionId(account_id), + ash::WallpaperLayout::WALLPAPER_LAYOUT_CENTER_CROPPED, + std::move(callback))); } } else { StartDailyRefreshTimer(); @@ -3249,6 +3221,44 @@ } } +void WallpaperControllerImpl::SetDailyWallpaper( + const AccountId& account_id, + const std::string& collection_id, + WallpaperLayout layout, + RefreshWallpaperCallback callback, + bool success, + const backdrop::Image& image) { + if (success) { + wallpaper_controller_client_->FetchImagesForCollection( + collection_id, + base::BindOnce( + &WallpaperControllerImpl::FindAndSetOnlineWallpaperVariants, + weak_factory_.GetWeakPtr(), + OnlineWallpaperParams( + account_id, image.asset_id(), GURL(image.image_url()), + collection_id, layout, /*preview_mode=*/false, + /*from_user=*/false, /*daily_refresh_enabled=*/true, + /*unit_id=*/absl::nullopt, + /*variants=*/std::vector<OnlineWallpaperVariant>()), + base::BindOnce(&WallpaperControllerImpl::OnSetDailyWallpaper, + weak_factory_.GetWeakPtr(), std::move(callback)))); + } else { + OnFetchDailyWallpaperFailed(); + std::move(callback).Run(false); + } +} + +void WallpaperControllerImpl::OnSetDailyWallpaper( + RefreshWallpaperCallback callback, + bool success) { + std::move(callback).Run(success); + if (success) { + StartDailyRefreshTimer(); + } else { + OnFetchDailyWallpaperFailed(); + } +} + void WallpaperControllerImpl::StartDailyRefreshTimer() { base::TimeDelta timer_delay = FuzzTimeDelta(GetTimeToNextDailyRefreshUpdate()); @@ -3265,7 +3275,6 @@ } void WallpaperControllerImpl::StartUpdateWallpaperTimer(base::TimeDelta delay) { - DCHECK(delay.is_positive()); base::Time desired_run_time = base::Time::Now() + delay; update_wallpaper_timer_.Start( FROM_HERE, desired_run_time, @@ -3278,9 +3287,8 @@ WallpaperInfo info; if (!GetUserWallpaperInfo(GetActiveAccountId(), &info)) return base::TimeDelta(); - base::TimeDelta delta = (info.date + base::Days(1)) - base::Time::Now(); - // Guarantee the delta is always 0 or positive. - return delta.is_positive() ? delta : base::TimeDelta(); + return info.date.ToDeltaSinceWindowsEpoch() - + base::Time::Now().ToDeltaSinceWindowsEpoch() + base::Days(1); } void WallpaperControllerImpl::OnUpdateWallpaperTimerExpired() { @@ -3417,17 +3425,21 @@ void WallpaperControllerImpl::HandleDailyWallpaperInfoSyncedIn( const AccountId& account_id, const WallpaperInfo& info) { - DCHECK(info.type == WallpaperType::kDaily); std::string old_collection_id = GetDailyRefreshCollectionId(account_id); if (info.collection_id == old_collection_id) return; - OnlineWallpaperVariantInfoFetcher::FetchParamsCallback callback = - base::BindOnce(&WallpaperControllerImpl::OnWallpaperVariantsFetched, - weak_factory_.GetWeakPtr(), info.type, base::DoNothing()); - if (!variant_info_fetcher_->FetchDailyWallpaper( - account_id, info, GetColorMode(), std::move(callback))) { - NOTREACHED() << "Fetch of daily wallpaper info failed."; - } + wallpaper_controller_client_->FetchDailyRefreshWallpaper( + info.collection_id, + base::BindOnce(&WallpaperControllerImpl::SetDailyWallpaper, + weak_factory_.GetWeakPtr(), account_id, info.collection_id, + ash::WallpaperLayout::WALLPAPER_LAYOUT_CENTER_CROPPED, + base::DoNothing())); +} + +void WallpaperControllerImpl::HandleOnlineWallpaperInfoSyncedIn( + const AccountId& account_id, + const WallpaperInfo& info) { + HandleSettingOnlineWallpaperFromWallpaperInfo(account_id, info); } void WallpaperControllerImpl::HandleGooglePhotosWallpaperInfoSyncedIn( @@ -3463,14 +3475,79 @@ void WallpaperControllerImpl::HandleSettingOnlineWallpaperFromWallpaperInfo( const AccountId& account_id, const WallpaperInfo& info) { - DCHECK(info.type == WallpaperType::kDaily || - info.type == WallpaperType::kOnline); - OnlineWallpaperVariantInfoFetcher::FetchParamsCallback callback = - base::BindOnce(&WallpaperControllerImpl::OnWallpaperVariantsFetched, - weak_factory_.GetWeakPtr(), info.type, base::DoNothing()); + bool daily_refresh_enabled = info.type == WallpaperType::kDaily; + if (info.unit_id.has_value() && !info.variants.empty()) { + const auto iter = std::find_if( + info.variants.begin(), info.variants.end(), [](const auto& variant) { + return IsSuitableOnlineWallpaperVariant(variant); + }); + if (iter != info.variants.end()) { + SetOnlineWallpaper( + ash::OnlineWallpaperParams{account_id, iter->asset_id, + GURL(iter->raw_url), info.collection_id, + info.layout, /*preview_mode=*/false, + /*from_user=*/false, daily_refresh_enabled, + info.unit_id, info.variants}, + base::DoNothing()); + } + } else { + wallpaper_controller_client_->FetchImagesForCollection( + info.collection_id, + base::BindOnce( + &WallpaperControllerImpl::FindAndSetOnlineWallpaperVariants, + weak_factory_.GetWeakPtr(), + OnlineWallpaperParams( + account_id, info.asset_id, GURL(info.location), + info.collection_id, info.layout, + /*preview_mode=*/false, + /*from_user=*/false, daily_refresh_enabled, + /*unit_id=*/absl::nullopt, + /*variants=*/std::vector<OnlineWallpaperVariant>()), + base::DoNothing())); + } +} - variant_info_fetcher_->FetchOnlineWallpaper(account_id, info, GetColorMode(), - std::move(callback)); +void WallpaperControllerImpl::FindAndSetOnlineWallpaperVariants( + const OnlineWallpaperParams& params, + base::OnceCallback<void(bool success)> callback, + bool success, + const std::vector<backdrop::Image>& images) { + if (!success) { + LOG(ERROR) << "Failed to fetch online wallpapers."; + std::move(callback).Run(success); + return; + } + + absl::optional<uint64_t> unit_id; + std::vector<ash::OnlineWallpaperVariant> variants; + for (const auto& image : images) { + if (image.asset_id() == params.asset_id) { + unit_id = image.unit_id(); + } + } + for (const auto& image : images) { + if (image.unit_id() == unit_id) { + variants.emplace_back(image.asset_id(), GURL(image.image_url()), + image.has_image_type() + ? image.image_type() + : backdrop::Image::IMAGE_TYPE_UNKNOWN); + } + } + + const auto iter = + std::find_if(variants.begin(), variants.end(), [](const auto& variant) { + return IsSuitableOnlineWallpaperVariant(variant); + }); + if (iter == variants.end()) { + std::move(callback).Run(/*success=*/false); + } else { + SetOnlineWallpaper( + ash::OnlineWallpaperParams{ + params.account_id, iter->asset_id, GURL(iter->raw_url), + params.collection_id, params.layout, params.preview_mode, + params.from_user, params.daily_refresh_enabled, unit_id, variants}, + std::move(callback)); + } } } // namespace ash
diff --git a/ash/wallpaper/wallpaper_controller_impl.h b/ash/wallpaper/wallpaper_controller_impl.h index c4676bc..ec41be0 100644 --- a/ash/wallpaper/wallpaper_controller_impl.h +++ b/ash/wallpaper/wallpaper_controller_impl.h
@@ -22,7 +22,6 @@ #include "ash/public/cpp/wallpaper/wallpaper_info.h" #include "ash/public/cpp/wallpaper/wallpaper_types.h" #include "ash/shell_observer.h" -#include "ash/wallpaper/online_wallpaper_variant_info_fetcher.h" #include "ash/wallpaper/wallpaper_utils/wallpaper_color_calculator_observer.h" #include "ash/wallpaper/wallpaper_utils/wallpaper_resizer_observer.h" #include "ash/webui/personalization_app/mojom/personalization_app.mojom-forward.h" @@ -117,9 +116,7 @@ // Prefer to use to obtain an new instance unless injecting non-production // members i.e. in tests. - explicit WallpaperControllerImpl( - PrefService* local_state, - std::unique_ptr<OnlineWallpaperVariantInfoFetcher> fetcher); + explicit WallpaperControllerImpl(PrefService* local_state); WallpaperControllerImpl(const WallpaperControllerImpl&) = delete; WallpaperControllerImpl& operator=(const WallpaperControllerImpl&) = delete; @@ -460,11 +457,6 @@ const OnlineWallpaperParams& params, const base::flat_map<std::string, base::FilePath>& url_to_file_path_map); - // Handler to receive Fetch*Wallpaper variants callbacks. - void OnWallpaperVariantsFetched(WallpaperType type, - SetWallpaperCallback callback, - absl::optional<OnlineWallpaperParams> params); - // Used as the callback of decoding wallpapers of type // `WallpaperType::kOnline`. Saves the image to local file if `save_file` is // true, and shows the wallpaper immediately if `params.account_id` is the @@ -699,6 +691,20 @@ // If the user has a Google Photos wallpaper set. bool IsGooglePhotosWallpaperSet() const; + // Callback from the client providing a url to a wallpaper from the user + // specified collection when daily refresh is enabled. If |success| is + // false, fetching the |image| failed, and should be tried again soon. + void SetDailyWallpaper(const AccountId& account_id, + const std::string& collection_id, + WallpaperLayout layout, + RefreshWallpaperCallback callback, + bool success, + const backdrop::Image& image); + + // Called after attempting to download and set a daily refresh wallpaper. + // On failure retry again in a while. + void OnSetDailyWallpaper(RefreshWallpaperCallback callback, bool success); + // Starts a wall clock timer, to update the wallpaper 24 hours since the last // wallpaper was set. void StartDailyRefreshTimer(); @@ -747,6 +753,9 @@ void HandleDailyWallpaperInfoSyncedIn(const AccountId& account_id, const WallpaperInfo& info); + void HandleOnlineWallpaperInfoSyncedIn(const AccountId& account_id, + const WallpaperInfo& info); + void HandleGooglePhotosWallpaperInfoSyncedIn(const AccountId& account_id, const WallpaperInfo& info); @@ -756,6 +765,15 @@ const AccountId& account_id, const WallpaperInfo& info); + // Find the variants for the online wallpaper with given |params.asset_id| and + // |params.collection_id| and determine the right variant to set based on the + // system's color mode. + void FindAndSetOnlineWallpaperVariants( + const OnlineWallpaperParams& params, + base::OnceCallback<void(bool)> callback, + bool success, + const std::vector<backdrop::Image>& images); + bool locked_ = false; WallpaperMode wallpaper_mode_ = WALLPAPER_NONE; @@ -774,9 +792,6 @@ // active. std::unique_ptr<WallpaperWindowStateManager> window_state_manager_; - // Delegate to resolve online wallpaper variants. - std::unique_ptr<OnlineWallpaperVariantInfoFetcher> variant_info_fetcher_; - // The prominent colors extracted from the current wallpaper. // kInvalidWallpaperColor is used by default or if extracting colors fails. std::vector<SkColor> prominent_colors_;
diff --git a/ash/wallpaper/wallpaper_controller_unittest.cc b/ash/wallpaper/wallpaper_controller_unittest.cc index 08aee7eb..44fb316 100644 --- a/ash/wallpaper/wallpaper_controller_unittest.cc +++ b/ash/wallpaper/wallpaper_controller_unittest.cc
@@ -46,7 +46,6 @@ #include "base/test/bind.h" #include "base/test/metrics/histogram_tester.h" #include "base/test/scoped_feature_list.h" -#include "base/test/task_environment.h" #include "base/test/test_future.h" #include "base/threading/thread_restrictions.h" #include "base/time/time_override.h" @@ -340,15 +339,8 @@ } WallpaperInfo InfoWithType(WallpaperType type) { - WallpaperInfo info(std::string(), WALLPAPER_LAYOUT_CENTER_CROPPED, type, - base::Time::Now()); - if (type == WallpaperType::kDaily || type == WallpaperType::kOnline) { - // Daily and Online types require asset id and collection id. - info.asset_id = 1234; - info.collection_id = "placeholder collection"; - info.location = "https://example.com/example.jpeg"; - } - return info; + return WallpaperInfo(std::string(), WALLPAPER_LAYOUT_CENTER_CROPPED, type, + base::Time::Now()); } base::Time DayBeforeYesterdayish() { @@ -398,8 +390,7 @@ class WallpaperControllerTestBase : public AshTestBase { public: - WallpaperControllerTestBase() - : AshTestBase(base::test::TaskEnvironment::TimeSource::MOCK_TIME) {} + WallpaperControllerTestBase() = default; WallpaperControllerTestBase(const WallpaperControllerTestBase&) = delete; WallpaperControllerTestBase& operator=(const WallpaperControllerTestBase&) = @@ -3103,7 +3094,24 @@ base::BindLambdaForTesting( [&is_second_callback_run]() { is_second_callback_run = true; }), test_window.get()); - RunAllTasksUntilIdle(); + { + // The animation is quite short (0.01 seconds) which is problematic in + // debug builds if RunAllTasksUntilIdle is a bit slow to execute. That leads + // to test flakes. We work around that by temporarily freezing time, which + // prevents the animation from unexpectedly completing too soon. + // Ideally this test should use MockTime instead, which will become easier + // after https://crrev.com/c/1352260 lands. + base::subtle::ScopedTimeClockOverrides time_override( + nullptr, + []() { + static base::TimeTicks time_ticks = + base::subtle::TimeTicksNowIgnoringOverride(); + return time_ticks; + }, + nullptr); + + RunAllTasksUntilIdle(); + } // Neither callback is run because the animation of the first wallpaper // hasn't finished yet. EXPECT_FALSE(is_first_callback_run); @@ -3111,7 +3119,6 @@ // Force the animation to complete. The two callbacks are both run. RunDesktopControllerAnimation(); - RunAllTasksUntilIdle(); EXPECT_TRUE(is_first_callback_run); EXPECT_TRUE(is_second_callback_run); @@ -3121,7 +3128,6 @@ base::BindLambdaForTesting( [&is_third_callback_run]() { is_third_callback_run = true; }), test_window.get()); - RunAllTasksUntilIdle(); EXPECT_TRUE(is_third_callback_run); } @@ -3776,9 +3782,9 @@ ClearLogin(); SimulateUserLogin(account_id_1); - // Info is set as over a day old so we expect one task to run in under an hour - // (due to fuzzing) then it will idle. - task_environment()->FastForwardBy(base::Hours(1)); + // |daily_refresh_timer_| adds a task to the sequence, as opposed to execute + // within the task that it is called in. + RunAllTasksUntilIdle(); EXPECT_EQ(TestWallpaperControllerClient::kDummyCollectionId, client_.get_fetch_daily_refresh_wallpaper_param());
diff --git a/ash/webui/personalization_app/personalization_app_ui.cc b/ash/webui/personalization_app/personalization_app_ui.cc index 0cb4a0e..82f2b125 100644 --- a/ash/webui/personalization_app/personalization_app_ui.cc +++ b/ash/webui/personalization_app/personalization_app_ui.cc
@@ -60,6 +60,7 @@ {"personalizationTitle", IDS_PERSONALIZATION_APP_PERSONALIZATION_HUB_TITLE}, {"wallpaperLabel", IDS_PERSONALIZATION_APP_WALLPAPER_LABEL}, + {"defaultWallpaper", IDS_PERSONALIZATION_APP_DEFAULT_WALLPAPER}, {"back", IDS_PERSONALIZATION_APP_BACK_BUTTON}, {"currentlySet", IDS_PERSONALIZATION_APP_CURRENTLY_SET}, {"myImagesLabel", IDS_PERSONALIZATION_APP_MY_IMAGES},
diff --git a/ash/webui/personalization_app/resources/trusted/user/avatar_list_element.ts b/ash/webui/personalization_app/resources/trusted/user/avatar_list_element.ts index 3f5ecba..c0af1829 100644 --- a/ash/webui/personalization_app/resources/trusted/user/avatar_list_element.ts +++ b/ash/webui/personalization_app/resources/trusted/user/avatar_list_element.ts
@@ -298,11 +298,16 @@ } } + private camelToKebab_(className: string): string { + return className.replace(/[A-Z]/g, m => '-' + m.toLowerCase()); + } + private getOptionInnerContainerClass_(option: Option, image: UserImage|null): string { + const defaultClass = option ? option.class : 'image-container'; return this.getAriaSelected_(option, image) === 'true' ? - `${option.class} selected-${option.id}` : - option.class; + `${defaultClass} selected-${this.camelToKebab_(option.id)}` : + defaultClass; } }
diff --git a/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_selected_element.ts b/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_selected_element.ts index 5a59cbec..f7aa050 100644 --- a/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_selected_element.ts +++ b/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_selected_element.ts
@@ -195,6 +195,9 @@ if (!image) { return this.i18n('unknownImageAttribution'); } + if (image.type === WallpaperType.kDefault) { + return this.i18n('defaultWallpaper'); + } if (isNonEmptyArray(image.attribution)) { const title = image.attribution[0]; return dailyRefreshCollectionId ? @@ -336,6 +339,9 @@ return this.i18n('currentlySet') + ' ' + this.i18n('unknownImageAttribution'); } + if (image.type === WallpaperType.kDefault) { + return `${this.i18n('currentlySet')} ${this.i18n('defaultWallpaper')}`; + } if (isNonEmptyArray(image.attribution)) { return dailyRefreshCollectionId ? [
diff --git a/ash/webui/shimless_rma/resources/onboarding_enter_rsu_wp_disable_code_page.html b/ash/webui/shimless_rma/resources/onboarding_enter_rsu_wp_disable_code_page.html index 3a91f16..0c46c2c 100644 --- a/ash/webui/shimless_rma/resources/onboarding_enter_rsu_wp_disable_code_page.html +++ b/ash/webui/shimless_rma/resources/onboarding_enter_rsu_wp_disable_code_page.html
@@ -62,6 +62,7 @@ <cr-input id="rsuCode" value="{{rsuCode_}}" + on-keydown="onKeyDown_" maxlength="[[rsuCodeExpectedLength_]]" invalid="[[rsuCodeInvalid_]]" disabled="[[allButtonsDisabled]]">
diff --git a/ash/webui/shimless_rma/resources/onboarding_enter_rsu_wp_disable_code_page.js b/ash/webui/shimless_rma/resources/onboarding_enter_rsu_wp_disable_code_page.js index cb0e3f4..fd5c20c 100644 --- a/ash/webui/shimless_rma/resources/onboarding_enter_rsu_wp_disable_code_page.js +++ b/ash/webui/shimless_rma/resources/onboarding_enter_rsu_wp_disable_code_page.js
@@ -13,7 +13,7 @@ import {getShimlessRmaService} from './mojo_interface_provider.js'; import {QrCode, ShimlessRmaServiceInterface, StateResult} from './shimless_rma_types.js'; -import {enableNextButton} from './shimless_rma_util.js'; +import {dispatchNextButtonClick, enableNextButton} from './shimless_rma_util.js'; // The size of each tile in pixels. const QR_CODE_TILE_SIZE = 5; @@ -191,6 +191,16 @@ } /** + * @param {!Event} event + * @protected + */ + onKeyDown_(event) { + if (event.key === 'Enter') { + dispatchNextButtonClick(this); + } + } + + /** * @return {!CanvasRenderingContext2D} * @private */
diff --git a/ash/webui/shimless_rma/resources/shimless_rma.html b/ash/webui/shimless_rma/resources/shimless_rma.html index e6ac1c4..aaf8c9c 100644 --- a/ash/webui/shimless_rma/resources/shimless_rma.html +++ b/ash/webui/shimless_rma/resources/shimless_rma.html
@@ -50,6 +50,11 @@ width: 20px; } + .button-icon { + height: var(--cr-icon-size); + width: var(--cr-icon-size); + } + #cancelButtonSpinner, #nextButtonCaret, #nextButtonSpinner { @@ -86,9 +91,9 @@ <paper-spinner-lite id="backButtonSpinner" class="busy-icon" hidden$="[[!backButtonClicked_]]" active> </paper-spinner-lite> - <span id="backButtonCaret" hidden$="[[backButtonClicked_]]"> - < - </span> + <iron-icon id="backButtonCaret" icon="cr:chevron-left" + class="button-icon" hidden$="[[backButtonClicked_]]"> + </iron-icon> <span id="backButtonLabel"> [[i18n('backButtonLabel')]] </span> @@ -117,9 +122,9 @@ <paper-spinner-lite id="nextButtonSpinner" class="busy-icon" hidden$="[[!nextButtonClicked_]]" active> </paper-spinner-lite> - <span id="nextButtonCaret" hidden$="[[nextButtonClicked_]]"> - > - </span> + <iron-icon id="nextButtonCaret" icon="cr:chevron-right" + class="button-icon" hidden$="[[nextButtonClicked_]]"> + </iron-icon> </cr-button> </div> </div>
diff --git a/ash/webui/shimless_rma/resources/shimless_rma.js b/ash/webui/shimless_rma/resources/shimless_rma.js index 9649931..feab56d 100644 --- a/ash/webui/shimless_rma/resources/shimless_rma.js +++ b/ash/webui/shimless_rma/resources/shimless_rma.js
@@ -388,6 +388,15 @@ }; /** + * The nextButtonCallback_ callback is used by the landing page to simulate + * the next button being clicked. + * @private {?Function} + */ + this.nextButtonCallback_ = (e) => { + this.onNextButtonClicked_(); + }; + + /** * The setNextButtonLabelCallback callback is used by page elements to set * the text label for the 'Next' button. * @private {?Function} @@ -411,6 +420,7 @@ window.addEventListener( 'enable-all-buttons', this.enableAllButtonsCallback_); window.addEventListener('click-cancel-button', this.cancelButtonCallback_); + window.addEventListener('click-next-button', this.nextButtonCallback_); } /** @override */ @@ -427,6 +437,7 @@ 'enable-all-buttons', this.enableAllButtonsCallback_); window.removeEventListener( 'click-cancel-button', this.cancelButtonCallback_); + window.removeEventListener('click-next-button', this.nextButtonCallback_); } /** @override */
diff --git a/ash/webui/shimless_rma/resources/shimless_rma_util.js b/ash/webui/shimless_rma/resources/shimless_rma_util.js index 31fbc9c0..62647bb 100644 --- a/ash/webui/shimless_rma/resources/shimless_rma_util.js +++ b/ash/webui/shimless_rma/resources/shimless_rma_util.js
@@ -64,3 +64,14 @@ {bubbles: true, composed: true, detail: fn}, )); } + +/** + * Dispatches an event to click the next button. + * @param {!HTMLElement} element + */ +export function dispatchNextButtonClick(element) { + element.dispatchEvent(new CustomEvent('click-next-button', { + bubbles: true, + composed: true, + })); +}
diff --git a/ash/wm/desks/templates/desks_templates_grid_view.cc b/ash/wm/desks/templates/desks_templates_grid_view.cc index a199a7c..a4d41dc9 100644 --- a/ash/wm/desks/templates/desks_templates_grid_view.cc +++ b/ash/wm/desks/templates/desks_templates_grid_view.cc
@@ -231,6 +231,7 @@ // be the new template, while the rest will be sorted alphabetically. for (size_t i = 0; i < grid_items_.size(); i++) ReorderChildView(grid_items_[i], i); + NotifyAccessibilityEvent(ax::mojom::Event::kTreeChanged, true); if (bounds_animator_.IsAnimating()) bounds_animator_.Cancel(); @@ -265,10 +266,8 @@ // and sort the remaining templates after it. SortTemplateGridItems(last_saved_template_uuid); - if (!initializing_grid_view) { + if (!initializing_grid_view) AnimateGridItems(new_grid_items); - NotifyAccessibilityEvent(ax::mojom::Event::kTreeChanged, true); - } } void DesksTemplatesGridView::DeleteTemplates(
diff --git a/ash/wm/desks/templates/desks_templates_icon_container.cc b/ash/wm/desks/templates/desks_templates_icon_container.cc index e231eebd..b137274 100644 --- a/ash/wm/desks/templates/desks_templates_icon_container.cc +++ b/ash/wm/desks/templates/desks_templates_icon_container.cc
@@ -71,6 +71,7 @@ // its values. void InsertIconIdentifierToIconInfo( const std::string& app_id, + const std::u16string& app_title, const std::string& identifier, int activation_index, std::map<std::string, DesksTemplatesIconContainer::IconInfo>* @@ -78,8 +79,9 @@ // A single app/site can have multiple windows so count their occurrences and // use the smallest activation index for sorting purposes. if (!base::Contains(*out_icon_identifier_to_icon_info, identifier)) { - (*out_icon_identifier_to_icon_info)[identifier] = {app_id, activation_index, - /*count=*/1}; + (*out_icon_identifier_to_icon_info)[identifier] = { + app_id, base::UTF16ToASCII(app_title), activation_index, + /*count=*/1}; } else { ++(*out_icon_identifier_to_icon_info)[identifier].count; (*out_icon_identifier_to_icon_info)[identifier].activation_index = std::min( @@ -113,13 +115,14 @@ const int activation_index = restore_data.second->activation_index.value(); const int active_tab_index = restore_data.second->active_tab_index.value_or(-1); + const std::u16string app_title = restore_data.second->title.value_or(u""); if (restore_data.second->urls.has_value() && is_browser) { const auto& urls = restore_data.second->urls.value(); for (int i = 0; i < static_cast<int>(urls.size()); ++i) { // Strip extra information from the url so urls with the same host but // different queries are treated the same. InsertIconIdentifierToIconInfo( - app_id, urls[i].GetWithEmptyPath().spec(), + app_id, app_title, urls[i].GetWithEmptyPath().spec(), active_tab_index == i ? activation_index : kInactiveTabOffset + activation_index, out_icon_identifier_to_icon_info); @@ -132,7 +135,8 @@ if (IsBrowserAppId(app_id) && app_name.has_value()) new_app_id = app_restore::GetAppIdFromAppName(app_name.value()); - InsertIconIdentifierToIconInfo(app_id, new_app_id, activation_index, + InsertIconIdentifierToIconInfo(app_id, app_title, new_app_id, + activation_index, out_icon_identifier_to_icon_info); } } @@ -196,8 +200,9 @@ // Since there were no modifications to `app_id`, app id and icon identifier // are both `app_id`. - InsertIconIdentifierToIconInfo(/*app_id=*/app_id, /*identifier=*/app_id, i, - &icon_identifier_to_icon_info); + InsertIconIdentifierToIconInfo( + /*app_id=*/app_id, /*app_title=*/window->GetTitle(), + /*identifier=*/app_id, i, &icon_identifier_to_icon_info); } CreateIconViewsFromIconIdentifiers( @@ -277,7 +282,8 @@ DesksTemplatesIconView::kIconSize / 2)) .Build()); icon_view->SetIconIdentifierAndCount(icon_identifier, icon_info.app_id, - icon_info.count, /*show_plus=*/true); + icon_info.app_title, icon_info.count, + /*show_plus=*/true); } else { num_hidden_icons += icon_info.count; } @@ -298,10 +304,11 @@ DesksTemplatesIconView::kIconSize / 2)) .Build()); - // Set both `icon_identifier` and `app_id` to be empty strings for overflow - // icon views, since only the count should matter. + // Set `icon_identifier`, `app_id` and `app_title` to be empty strings for + // overflow icon views, since only the count should matter. overflow_icon_view->SetIconIdentifierAndCount( /*icon_identifier=*/std::string(), /*app_id=*/std::string(), + /*app_title=*/std::string(), /*count=*/num_hidden_icons, show_plus); }
diff --git a/ash/wm/desks/templates/desks_templates_icon_container.h b/ash/wm/desks/templates/desks_templates_icon_container.h index 318ed73a..fa792fa 100644 --- a/ash/wm/desks/templates/desks_templates_icon_container.h +++ b/ash/wm/desks/templates/desks_templates_icon_container.h
@@ -44,6 +44,7 @@ // icons/favicons to display. struct IconInfo { std::string app_id; + std::string app_title; int activation_index; int count; };
diff --git a/ash/wm/desks/templates/desks_templates_icon_view.cc b/ash/wm/desks/templates/desks_templates_icon_view.cc index 47e9622..2f12db5 100644 --- a/ash/wm/desks/templates/desks_templates_icon_view.cc +++ b/ash/wm/desks/templates/desks_templates_icon_view.cc
@@ -65,6 +65,7 @@ void DesksTemplatesIconView::SetIconIdentifierAndCount( const std::string& icon_identifier, const std::string& app_id, + const std::string& app_title, int count, bool show_plus) { icon_identifier_ = icon_identifier; @@ -98,11 +99,14 @@ if (icon_identifier_.empty()) return; + // Add the icon to the front so that it gets read out before `count_label_` by + // spoken feedback. DCHECK(!icon_view_); icon_view_ = - AddChildView(views::Builder<RoundedImageView>() - .SetCornerRadius(DesksTemplatesIconView::kIconSize / 2) - .Build()); + AddChildViewAt(views::Builder<RoundedImageView>() + .SetCornerRadius(DesksTemplatesIconView::kIconSize / 2) + .Build(), + 0); // First check if the `icon_identifier_` is a special value, i.e. NTP url or // incognito window. If it is, use the corresponding icon for the special @@ -114,6 +118,7 @@ ->incognito_window_color_provider()); icon_view_->GetViewAccessibility().OverrideRole(ax::mojom::Role::kImage); + icon_view_->GetViewAccessibility().OverrideName(app_title); // PWAs (e.g. Messages) should use icon identifier as they share the same app // id as Chrome and would return short name for app id as "Chromium" (see @@ -122,12 +127,8 @@ // duplicate favicons (see https://crbug.com/1281391). if (chrome_icon.has_value()) { icon_view_->SetImage(CreateResizedImageToIconSize(chrome_icon.value())); - icon_view_->GetViewAccessibility().OverrideName( - delegate->GetAppShortName(app_id)); return; } - icon_view_->GetViewAccessibility().OverrideName( - delegate->GetAppShortName(icon_identifier_)); // It's not a special value so `icon_identifier_` is either a favicon or an // app id. If `icon_identifier_` is not a valid url then it's an app id. @@ -194,13 +195,15 @@ .AsImageSkia())); // Move `this` to the back of the visible icons, i.e. before any invisible - // siblings and before the overflow counter, + // siblings and before the overflow counter. Notify the a11y API so that the + // spoken feedback order matches the view order. auto siblings = parent()->children(); if (siblings.size() >= 2) { size_t i = 0; while (i < siblings.size() - 2 && siblings[i]->GetVisible()) ++i; parent()->ReorderChildView(this, i); + parent()->NotifyAccessibilityEvent(ax::mojom::Event::kTreeChanged, true); } }
diff --git a/ash/wm/desks/templates/desks_templates_icon_view.h b/ash/wm/desks/templates/desks_templates_icon_view.h index a4614f6..9a0d720 100644 --- a/ash/wm/desks/templates/desks_templates_icon_view.h +++ b/ash/wm/desks/templates/desks_templates_icon_view.h
@@ -50,6 +50,7 @@ // all unavailable icons. void SetIconIdentifierAndCount(const std::string& icon_identifier, const std::string& app_id, + const std::string& app_title, int count, bool show_plus);
diff --git a/base/BUILD.gn b/base/BUILD.gn index 4740e8e..f9f3ac6 100644 --- a/base/BUILD.gn +++ b/base/BUILD.gn
@@ -398,7 +398,6 @@ "memory/page_size.h", "memory/platform_shared_memory_handle.cc", "memory/platform_shared_memory_handle.h", - "memory/platform_shared_memory_mapper.cc", "memory/platform_shared_memory_mapper.h", "memory/platform_shared_memory_region.cc", "memory/platform_shared_memory_region.h", @@ -417,6 +416,8 @@ "memory/scoped_policy.h", "memory/scoped_refptr.h", "memory/shared_memory_hooks.h", + "memory/shared_memory_mapper.cc", + "memory/shared_memory_mapper.h", "memory/shared_memory_mapping.cc", "memory/shared_memory_mapping.h", "memory/shared_memory_security_policy.cc",
diff --git a/base/fuchsia/fuchsia_logging_unittest.cc b/base/fuchsia/fuchsia_logging_unittest.cc index f526b4f..51e2013 100644 --- a/base/fuchsia/fuchsia_logging_unittest.cc +++ b/base/fuchsia/fuchsia_logging_unittest.cc
@@ -34,6 +34,7 @@ std::make_unique<fuchsia::logger::LogFilterOptions>(); options->filter_by_pid = true; options->pid = Process::Current().Pid(); + options->min_severity = fuchsia::logger::LogLevelFilter::INFO; fuchsia::logger::LogPtr log = ComponentContextForProcess()->svc()->Connect<fuchsia::logger::Log>(); listener.ListenToLog(log.get(), std::move(options));
diff --git a/base/memory/platform_shared_memory_mapper.cc b/base/memory/platform_shared_memory_mapper.cc deleted file mode 100644 index 7e225703..0000000 --- a/base/memory/platform_shared_memory_mapper.cc +++ /dev/null
@@ -1,25 +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 "base/memory/platform_shared_memory_mapper.h" - -#include "base/check_op.h" - -namespace base { - -// static -absl::optional<span<uint8_t>> PlatformSharedMemoryMapper::Map( - subtle::PlatformSharedMemoryHandle handle, - bool write_allowed, - uint64_t offset, - size_t size) { - return MapInternal(std::move(handle), write_allowed, offset, size); -} - -// static -void PlatformSharedMemoryMapper::Unmap(span<uint8_t> mapping) { - return UnmapInternal(mapping); -} - -} // namespace base
diff --git a/base/memory/platform_shared_memory_mapper.h b/base/memory/platform_shared_memory_mapper.h index c8dd5a89..c4b6c4b 100644 --- a/base/memory/platform_shared_memory_mapper.h +++ b/base/memory/platform_shared_memory_mapper.h
@@ -6,36 +6,21 @@ #define BASE_MEMORY_PLATFORM_SHARED_MEMORY_MAPPER_H_ #include "base/base_export.h" -#include "base/containers/span.h" -#include "base/memory/platform_shared_memory_handle.h" -#include "third_party/abseil-cpp/absl/types/optional.h" - -#include <stdint.h> +#include "base/memory/shared_memory_mapper.h" namespace base { -// Static class responsible for the platform-specific logic to map a shared -// memory region into the virtual address space of the process. -class BASE_EXPORT PlatformSharedMemoryMapper { +// Default implementation of the SharedMemoryMapper interface. Implements the +// platform-specific logic for mapping shared memory regions into the virtual +// address space of the process. +class PlatformSharedMemoryMapper : public SharedMemoryMapper { public: - PlatformSharedMemoryMapper() = delete; + absl::optional<span<uint8_t>> Map(subtle::PlatformSharedMemoryHandle handle, + bool write_allowed, + uint64_t offset, + size_t size) override; - static absl::optional<span<uint8_t>> Map( - subtle::PlatformSharedMemoryHandle handle, - bool write_allowed, - uint64_t offset, - size_t size); - - static void Unmap(span<uint8_t> mapping); - - private: - static absl::optional<span<uint8_t>> MapInternal( - subtle::PlatformSharedMemoryHandle handle, - bool write_allowed, - uint64_t offset, - size_t size); - - static void UnmapInternal(span<uint8_t> mapping); + void Unmap(span<uint8_t> mapping) override; }; } // namespace base
diff --git a/base/memory/platform_shared_memory_mapper_android.cc b/base/memory/platform_shared_memory_mapper_android.cc index 544e5fa6..8921f17 100644 --- a/base/memory/platform_shared_memory_mapper_android.cc +++ b/base/memory/platform_shared_memory_mapper_android.cc
@@ -11,8 +11,7 @@ namespace base { -// static -absl::optional<span<uint8_t>> PlatformSharedMemoryMapper::MapInternal( +absl::optional<span<uint8_t>> PlatformSharedMemoryMapper::Map( subtle::PlatformSharedMemoryHandle handle, bool write_allowed, uint64_t offset, @@ -32,8 +31,7 @@ return make_span(reinterpret_cast<uint8_t*>(address), size); } -// static -void PlatformSharedMemoryMapper::UnmapInternal(span<uint8_t> mapping) { +void PlatformSharedMemoryMapper::Unmap(span<uint8_t> mapping) { if (munmap(mapping.data(), mapping.size()) < 0) DPLOG(ERROR) << "munmap"; }
diff --git a/base/memory/platform_shared_memory_mapper_fuchsia.cc b/base/memory/platform_shared_memory_mapper_fuchsia.cc index 5278cd6..791130ff 100644 --- a/base/memory/platform_shared_memory_mapper_fuchsia.cc +++ b/base/memory/platform_shared_memory_mapper_fuchsia.cc
@@ -11,8 +11,7 @@ namespace base { -// static -absl::optional<span<uint8_t>> PlatformSharedMemoryMapper::MapInternal( +absl::optional<span<uint8_t>> PlatformSharedMemoryMapper::Map( subtle::PlatformSharedMemoryHandle handle, bool write_allowed, uint64_t offset, @@ -31,8 +30,7 @@ return make_span(reinterpret_cast<uint8_t*>(addr), size); } -// static -void PlatformSharedMemoryMapper::UnmapInternal(span<uint8_t> mapping) { +void PlatformSharedMemoryMapper::Unmap(span<uint8_t> mapping) { uintptr_t addr = reinterpret_cast<uintptr_t>(mapping.data()); zx_status_t status = zx::vmar::root_self()->unmap(addr, mapping.size()); if (status != ZX_OK)
diff --git a/base/memory/platform_shared_memory_mapper_mac.cc b/base/memory/platform_shared_memory_mapper_mac.cc index 721d73f2..bc13008 100644 --- a/base/memory/platform_shared_memory_mapper_mac.cc +++ b/base/memory/platform_shared_memory_mapper_mac.cc
@@ -11,8 +11,7 @@ namespace base { -// static -absl::optional<span<uint8_t>> PlatformSharedMemoryMapper::MapInternal( +absl::optional<span<uint8_t>> PlatformSharedMemoryMapper::Map( subtle::PlatformSharedMemoryHandle handle, bool write_allowed, uint64_t offset, @@ -37,8 +36,7 @@ return make_span(reinterpret_cast<uint8_t*>(address), size); } -// static -void PlatformSharedMemoryMapper::UnmapInternal(span<uint8_t> mapping) { +void PlatformSharedMemoryMapper::Unmap(span<uint8_t> mapping) { kern_return_t kr = mach_vm_deallocate( mach_task_self(), reinterpret_cast<mach_vm_address_t>(mapping.data()), mapping.size());
diff --git a/base/memory/platform_shared_memory_mapper_posix.cc b/base/memory/platform_shared_memory_mapper_posix.cc index dcaab5d..10ee476 100644 --- a/base/memory/platform_shared_memory_mapper_posix.cc +++ b/base/memory/platform_shared_memory_mapper_posix.cc
@@ -11,8 +11,7 @@ namespace base { -// static -absl::optional<span<uint8_t>> PlatformSharedMemoryMapper::MapInternal( +absl::optional<span<uint8_t>> PlatformSharedMemoryMapper::Map( subtle::PlatformSharedMemoryHandle handle, bool write_allowed, uint64_t offset, @@ -29,8 +28,7 @@ return make_span(reinterpret_cast<uint8_t*>(address), size); } -// static -void PlatformSharedMemoryMapper::UnmapInternal(span<uint8_t> mapping) { +void PlatformSharedMemoryMapper::Unmap(span<uint8_t> mapping) { if (munmap(mapping.data(), mapping.size()) < 0) DPLOG(ERROR) << "munmap"; }
diff --git a/base/memory/platform_shared_memory_mapper_win.cc b/base/memory/platform_shared_memory_mapper_win.cc index fdede77..6f4a4b3 100644 --- a/base/memory/platform_shared_memory_mapper_win.cc +++ b/base/memory/platform_shared_memory_mapper_win.cc
@@ -23,8 +23,7 @@ } } // namespace -// static -absl::optional<span<uint8_t>> PlatformSharedMemoryMapper::MapInternal( +absl::optional<span<uint8_t>> PlatformSharedMemoryMapper::Map( subtle::PlatformSharedMemoryHandle handle, bool write_allowed, uint64_t offset, @@ -49,8 +48,7 @@ GetMemorySectionSize(address)); } -// static -void PlatformSharedMemoryMapper::UnmapInternal(span<uint8_t> mapping) { +void PlatformSharedMemoryMapper::Unmap(span<uint8_t> mapping) { if (!UnmapViewOfFile(mapping.data())) DPLOG(ERROR) << "UnmapViewOfFile"; }
diff --git a/base/memory/platform_shared_memory_region.cc b/base/memory/platform_shared_memory_region.cc index 1214379..9277273 100644 --- a/base/memory/platform_shared_memory_region.cc +++ b/base/memory/platform_shared_memory_region.cc
@@ -47,7 +47,8 @@ absl::optional<span<uint8_t>> PlatformSharedMemoryRegion::MapAt( uint64_t offset, - size_t size) const { + size_t size, + SharedMemoryMapper* mapper) const { if (!IsValid()) return absl::nullopt; @@ -66,9 +67,11 @@ RecordMappingWasBlockedHistogram(/*blocked=*/false); + if (!mapper) + mapper = SharedMemoryMapper::GetDefaultInstance(); + bool write_allowed = mode_ != Mode::kReadOnly; - auto result = PlatformSharedMemoryMapper::Map(GetPlatformHandle(), - write_allowed, offset, size); + auto result = mapper->Map(GetPlatformHandle(), write_allowed, offset, size); if (result.has_value()) { DCHECK(IsAligned(result.value().data(), kMapMinimumAlignment));
diff --git a/base/memory/platform_shared_memory_region.h b/base/memory/platform_shared_memory_region.h index ed9607e..74d1eff 100644 --- a/base/memory/platform_shared_memory_region.h +++ b/base/memory/platform_shared_memory_region.h
@@ -9,7 +9,7 @@ #include "base/containers/span.h" #include "base/gtest_prod_util.h" #include "base/memory/platform_shared_memory_handle.h" -#include "base/memory/platform_shared_memory_mapper.h" +#include "base/memory/shared_memory_mapper.h" #include "base/unguessable_token.h" #include "build/build_config.h" #include "third_party/abseil-cpp/absl/types/optional.h" @@ -188,14 +188,15 @@ bool ConvertToUnsafe(); // Maps |size| bytes of the shared memory region starting with the given - // |offset| into the caller's address space. |offset| must be aligned to value - // of |SysInfo::VMAllocationGranularity()|. Fails if requested bytes are out - // of the region limits. - // Returns true and sets |memory| and |mapped_size| on success, returns false - // and leaves output parameters in unspecified state otherwise. The mapped - // address is guaranteed to have an alignment of at least - // |kMapMinimumAlignment|. - absl::optional<span<uint8_t>> MapAt(uint64_t offset, size_t size) const; + // |offset| into the caller's address space using the provided + // |SharedMemoryMapper|. |offset| must be aligned to value of + // |SysInfo::VMAllocationGranularity()|. Fails if requested bytes are out of + // the region limits. Returns the mapping as span on success, or absl::nullopt + // on failure. The mapped address is guaranteed to have an alignment of at + // least |kMapMinimumAlignment|. + absl::optional<span<uint8_t>> MapAt(uint64_t offset, + size_t size, + SharedMemoryMapper* mapper) const; const UnguessableToken& GetGUID() const { return guid_; }
diff --git a/base/memory/read_only_shared_memory_region.cc b/base/memory/read_only_shared_memory_region.cc index 0950a57..70712b1 100644 --- a/base/memory/read_only_shared_memory_region.cc +++ b/base/memory/read_only_shared_memory_region.cc
@@ -14,20 +14,23 @@ ReadOnlySharedMemoryRegion::create_hook_ = nullptr; // static -MappedReadOnlyRegion ReadOnlySharedMemoryRegion::Create(size_t size) { +MappedReadOnlyRegion ReadOnlySharedMemoryRegion::Create( + size_t size, + SharedMemoryMapper* mapper) { if (create_hook_) - return create_hook_(size); + return create_hook_(size, mapper); subtle::PlatformSharedMemoryRegion handle = subtle::PlatformSharedMemoryRegion::CreateWritable(size); if (!handle.IsValid()) return {}; - auto result = handle.MapAt(0, handle.GetSize()); + auto result = handle.MapAt(0, handle.GetSize(), mapper); if (!result.has_value()) return {}; - WritableSharedMemoryMapping mapping(result.value(), size, handle.GetGUID()); + WritableSharedMemoryMapping mapping(result.value(), size, handle.GetGUID(), + mapper); #if BUILDFLAG(IS_MAC) handle.ConvertToReadOnly(mapping.memory()); #else @@ -65,21 +68,24 @@ return ReadOnlySharedMemoryRegion(handle_.Duplicate()); } -ReadOnlySharedMemoryMapping ReadOnlySharedMemoryRegion::Map() const { - return MapAt(0, handle_.GetSize()); +ReadOnlySharedMemoryMapping ReadOnlySharedMemoryRegion::Map( + SharedMemoryMapper* mapper) const { + return MapAt(0, handle_.GetSize(), mapper); } ReadOnlySharedMemoryMapping ReadOnlySharedMemoryRegion::MapAt( uint64_t offset, - size_t size) const { + size_t size, + SharedMemoryMapper* mapper) const { if (!IsValid()) return {}; - auto result = handle_.MapAt(offset, size); + auto result = handle_.MapAt(offset, size, mapper); if (!result.has_value()) return {}; - return ReadOnlySharedMemoryMapping(result.value(), size, handle_.GetGUID()); + return ReadOnlySharedMemoryMapping(result.value(), size, handle_.GetGUID(), + mapper); } bool ReadOnlySharedMemoryRegion::IsValid() const {
diff --git a/base/memory/read_only_shared_memory_region.h b/base/memory/read_only_shared_memory_region.h index c9ec0dd..cbabdcd1 100644 --- a/base/memory/read_only_shared_memory_region.h +++ b/base/memory/read_only_shared_memory_region.h
@@ -34,7 +34,8 @@ // This means that the caller's process is the only process that can modify // the region content. If you need to pass write access to another process, // consider using WritableSharedMemoryRegion or UnsafeSharedMemoryRegion. - static MappedReadOnlyRegion Create(size_t size); + static MappedReadOnlyRegion Create(size_t size, + SharedMemoryMapper* mapper = nullptr); using CreateFunction = decltype(Create); // Returns a ReadOnlySharedMemoryRegion built from a platform-specific handle @@ -78,14 +79,17 @@ // read-only access. The mapped address is guaranteed to have an alignment of // at least |subtle::PlatformSharedMemoryRegion::kMapMinimumAlignment|. // Returns a valid ReadOnlySharedMemoryMapping instance on success, invalid - // otherwise. - ReadOnlySharedMemoryMapping Map() const; + // otherwise. A custom |SharedMemoryMapper| for mapping (and later unmapping) + // the region can be provided using the optional |mapper| parameter. + ReadOnlySharedMemoryMapping Map(SharedMemoryMapper* mapper = nullptr) const; // Same as above, but maps only |size| bytes of the shared memory region // starting with the given |offset|. |offset| must be aligned to value of // |SysInfo::VMAllocationGranularity()|. Returns an invalid mapping if // requested bytes are out of the region limits. - ReadOnlySharedMemoryMapping MapAt(uint64_t offset, size_t size) const; + ReadOnlySharedMemoryMapping MapAt(uint64_t offset, + size_t size, + SharedMemoryMapper* mapper = nullptr) const; // Whether the underlying platform handle is valid. bool IsValid() const;
diff --git a/base/memory/ref_counted_unittest.nc b/base/memory/ref_counted_unittest.nc index 0830ce2b..d25970d 100644 --- a/base/memory/ref_counted_unittest.nc +++ b/base/memory/ref_counted_unittest.nc
@@ -22,4 +22,45 @@ #endif +#if defined(NCTEST_WRONG_REFCOUNT_BASE_CLASS) // [r"fatal error: static_assert failed due to requirement 'std::is_base_of_v<base::Foo, base::Bar>' \"T implements RefCounted<U>, but U is not a base of T\.\""] + +class Foo : public base::RefCounted<Foo> { + private: + friend class base::RefCounted<Foo>; + ~Foo() {} +}; + +class Bar : public base::RefCounted<Foo> { + private: + friend class base::RefCounted<Bar>; + ~Bar() {} +}; + +void WontCompile() { + scoped_refptr<Bar> ptr; +} + +#endif + +#if defined(NCTEST_WRONG_REFCOUNT_THREADSAFE_BASE_CLASS) // [r"fatal error: static_assert failed due to requirement 'std::is_base_of_v<base::Foo, base::Bar>' \"T implements RefCountedThreadSafe<U>, but U is not a base of T\.\""] + +class Foo : public base::RefCountedThreadSafe<Foo> { + private: + friend class base::RefCountedThreadSafe<Foo>; + ~Foo() {} +}; + +class Bar : public base::RefCountedThreadSafe<Foo> { + private: + friend class base::RefCountedThreadSafe<Bar>; + ~Bar() {} +}; + +void WontCompile() { + scoped_refptr<Bar> ptr; +} + +#endif + + } // namespace base
diff --git a/base/memory/scoped_refptr.h b/base/memory/scoped_refptr.h index ed70d55..45d32d45 100644 --- a/base/memory/scoped_refptr.h +++ b/base/memory/scoped_refptr.h
@@ -23,6 +23,8 @@ class RefCounted; template <class, typename> class RefCountedThreadSafe; +template <class> +class RefCountedDeleteOnSequence; class SequencedTaskRunner; class WrappedPromise; @@ -41,6 +43,10 @@ enum StartRefCountFromZeroTag { kStartRefCountFromZeroTag }; enum StartRefCountFromOneTag { kStartRefCountFromOneTag }; +// scoped_refptr<T> is typically used with one of several RefCounted<T> base +// classes or with custom AddRef and Release methods. These overloads dispatch +// on which was used. + template <typename T, typename U, typename V> constexpr bool IsRefCountPreferenceOverridden(const T*, const RefCounted<U, V>*) { @@ -56,10 +62,42 @@ std::decay_t<decltype(U::kRefCountPreference)>>::value; } +template <typename T, typename U> +constexpr bool IsRefCountPreferenceOverridden( + const T*, + const RefCountedDeleteOnSequence<U*>) { + return !std::is_same<std::decay_t<decltype(T::kRefCountPreference)>, + std::decay_t<decltype(U::kRefCountPreference)>>::value; +} + constexpr bool IsRefCountPreferenceOverridden(...) { return false; } +template <typename T, typename U, typename V> +constexpr void AssertRefCountBaseMatches(const T*, const RefCounted<U, V>*) { + static_assert(std::is_base_of_v<U, T>, + "T implements RefCounted<U>, but U is not a base of T."); +} + +template <typename T, typename U, typename V> +constexpr void AssertRefCountBaseMatches(const T*, + const RefCountedThreadSafe<U, V>*) { + static_assert( + std::is_base_of_v<U, T>, + "T implements RefCountedThreadSafe<U>, but U is not a base of T."); +} + +template <typename T, typename U> +constexpr void AssertRefCountBaseMatches(const T*, + const RefCountedDeleteOnSequence<U>*) { + static_assert( + std::is_base_of_v<U, T>, + "T implements RefCountedDeleteOnSequence<U>, but U is not a base of T."); +} + +constexpr void AssertRefCountBaseMatches(...) {} + } // namespace subtle // Creates a scoped_refptr from a raw pointer without incrementing the reference @@ -312,12 +350,14 @@ // static template <typename T> void scoped_refptr<T>::AddRef(T* ptr) { + base::subtle::AssertRefCountBaseMatches(ptr, ptr); ptr->AddRef(); } // static template <typename T> void scoped_refptr<T>::Release(T* ptr) { + base::subtle::AssertRefCountBaseMatches(ptr, ptr); ptr->Release(); }
diff --git a/base/memory/shared_memory_hooks_unittest.cc b/base/memory/shared_memory_hooks_unittest.cc index 8538acc..72e8f3cd 100644 --- a/base/memory/shared_memory_hooks_unittest.cc +++ b/base/memory/shared_memory_hooks_unittest.cc
@@ -26,7 +26,7 @@ absl::optional<size_t> requested_unsafe_shmem_size; absl::optional<size_t> requested_writable_shmem_size; -MappedReadOnlyRegion ReadOnlyShmemCreateHook(size_t size) { +MappedReadOnlyRegion ReadOnlyShmemCreateHook(size_t size, SharedMemoryMapper* mapper) { requested_read_only_shmem_size = size; return {}; }
diff --git a/base/memory/shared_memory_mapper.cc b/base/memory/shared_memory_mapper.cc new file mode 100644 index 0000000..0538aae --- /dev/null +++ b/base/memory/shared_memory_mapper.cc
@@ -0,0 +1,17 @@ +// 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/memory/shared_memory_mapper.h" + +#include "base/memory/platform_shared_memory_mapper.h" + +namespace base { + +// static +SharedMemoryMapper* SharedMemoryMapper::GetDefaultInstance() { + static PlatformSharedMemoryMapper instance; + return &instance; +} + +} // namespace base
diff --git a/base/memory/shared_memory_mapper.h b/base/memory/shared_memory_mapper.h new file mode 100644 index 0000000..3cdff54 --- /dev/null +++ b/base/memory/shared_memory_mapper.h
@@ -0,0 +1,44 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef BASE_MEMORY_SHARED_MEMORY_MAPPER_H_ +#define BASE_MEMORY_SHARED_MEMORY_MAPPER_H_ + +#include "base/base_export.h" +#include "base/containers/span.h" +#include "base/memory/platform_shared_memory_handle.h" +#include "third_party/abseil-cpp/absl/types/optional.h" + +#include <stdint.h> + +namespace base { + +// Interface to implement mapping and unmapping of shared memory regions into +// the virtual address space. The default implementation, +// |PlatformSharedMemoryMapper| uses the platform-specific APIs to map the +// region anywhere in the address space. Other implementations can be used for +// example to always map the regions into an existing address space reservation. +// Implementations of this interface should generally be statically allocated +// as SharedMemoryMappings keep a reference to their mapper. +class BASE_EXPORT SharedMemoryMapper { + public: + // Returns the default shared memory mapper. + static SharedMemoryMapper* GetDefaultInstance(); + + // Maps the shared memory region identified through the provided platform + // handle into the caller's address space. + virtual absl::optional<span<uint8_t>> Map( + subtle::PlatformSharedMemoryHandle handle, + bool write_allowed, + uint64_t offset, + size_t size) = 0; + + // Unmaps the specified region of shared memory from the caller's address + // space. + virtual void Unmap(span<uint8_t> mapping) = 0; +}; + +} // namespace base + +#endif // BASE_MEMORY_SHARED_MEMORY_MAPPER_H_
diff --git a/base/memory/shared_memory_mapping.cc b/base/memory/shared_memory_mapping.cc index 02b0d52..bfd9fe6 100644 --- a/base/memory/shared_memory_mapping.cc +++ b/base/memory/shared_memory_mapping.cc
@@ -7,7 +7,6 @@ #include <utility> #include "base/logging.h" -#include "base/memory/platform_shared_memory_mapper.h" #include "base/memory/shared_memory_security_policy.h" #include "base/memory/shared_memory_tracker.h" #include "base/unguessable_token.h" @@ -20,7 +19,8 @@ SharedMemoryMapping::SharedMemoryMapping(SharedMemoryMapping&& mapping) noexcept : mapped_span_(std::exchange(mapping.mapped_span_, span<uint8_t>())), size_(mapping.size_), - guid_(mapping.guid_) {} + guid_(mapping.guid_), + mapper_(mapping.mapper_) {} SharedMemoryMapping& SharedMemoryMapping::operator=( SharedMemoryMapping&& mapping) noexcept { @@ -28,6 +28,7 @@ mapped_span_ = std::exchange(mapping.mapped_span_, span<uint8_t>()); size_ = mapping.size_; guid_ = mapping.guid_; + mapper_ = mapping.mapper_; return *this; } @@ -37,8 +38,9 @@ SharedMemoryMapping::SharedMemoryMapping(span<uint8_t> mapped_span, size_t size, - const UnguessableToken& guid) - : mapped_span_(mapped_span), size_(size), guid_(guid) { + const UnguessableToken& guid, + SharedMemoryMapper* mapper) + : mapped_span_(mapped_span), size_(size), guid_(guid), mapper_(mapper) { SharedMemoryTracker::GetInstance()->IncrementMemoryUsage(*this); } @@ -46,10 +48,12 @@ if (!IsValid()) return; - SharedMemorySecurityPolicy::ReleaseReservationForMapping(size_); SharedMemoryTracker::GetInstance()->DecrementMemoryUsage(*this); - PlatformSharedMemoryMapper::Unmap(mapped_span_); + SharedMemoryMapper* mapper = mapper_; + if (!mapper) + mapper = SharedMemoryMapper::GetDefaultInstance(); + mapper->Unmap(mapped_span_); } ReadOnlySharedMemoryMapping::ReadOnlySharedMemoryMapping() = default; @@ -60,8 +64,9 @@ ReadOnlySharedMemoryMapping::ReadOnlySharedMemoryMapping( span<uint8_t> mapped_span, size_t size, - const UnguessableToken& guid) - : SharedMemoryMapping(mapped_span, size, guid) {} + const UnguessableToken& guid, + SharedMemoryMapper* mapper) + : SharedMemoryMapping(mapped_span, size, guid, mapper) {} WritableSharedMemoryMapping::WritableSharedMemoryMapping() = default; WritableSharedMemoryMapping::WritableSharedMemoryMapping( @@ -71,7 +76,8 @@ WritableSharedMemoryMapping::WritableSharedMemoryMapping( span<uint8_t> mapped_span, size_t size, - const UnguessableToken& guid) - : SharedMemoryMapping(mapped_span, size, guid) {} + const UnguessableToken& guid, + SharedMemoryMapper* mapper) + : SharedMemoryMapping(mapped_span, size, guid, mapper) {} } // namespace base
diff --git a/base/memory/shared_memory_mapping.h b/base/memory/shared_memory_mapping.h index 82bfdebc..ca25a01 100644 --- a/base/memory/shared_memory_mapping.h +++ b/base/memory/shared_memory_mapping.h
@@ -11,6 +11,7 @@ #include "base/base_export.h" #include "base/check.h" #include "base/containers/span.h" +#include "base/memory/shared_memory_mapper.h" #include "base/unguessable_token.h" namespace base { @@ -70,7 +71,8 @@ protected: SharedMemoryMapping(span<uint8_t> mapped_span, size_t size, - const UnguessableToken& guid); + const UnguessableToken& guid, + SharedMemoryMapper* mapper); void* raw_memory_ptr() const { return reinterpret_cast<void*>(mapped_span_.data()); } @@ -83,6 +85,7 @@ span<uint8_t> mapped_span_; size_t size_ = 0; UnguessableToken guid_; + SharedMemoryMapper* mapper_ = nullptr; }; // Class modeling a read-only mapping of a shared memory region into the @@ -156,7 +159,8 @@ friend class ReadOnlySharedMemoryRegion; ReadOnlySharedMemoryMapping(span<uint8_t> mapped_span, size_t size, - const UnguessableToken& guid); + const UnguessableToken& guid, + SharedMemoryMapper* mapper); }; // Class modeling a writable mapping of a shared memory region into the @@ -235,7 +239,8 @@ friend class UnsafeSharedMemoryRegion; WritableSharedMemoryMapping(span<uint8_t> mapped_span, size_t size, - const UnguessableToken& guid); + const UnguessableToken& guid, + SharedMemoryMapper* mapper); }; } // namespace base
diff --git a/base/memory/unsafe_shared_memory_region.cc b/base/memory/unsafe_shared_memory_region.cc index b1a3917..00d4f848 100644 --- a/base/memory/unsafe_shared_memory_region.cc +++ b/base/memory/unsafe_shared_memory_region.cc
@@ -48,20 +48,24 @@ return UnsafeSharedMemoryRegion(handle_.Duplicate()); } -WritableSharedMemoryMapping UnsafeSharedMemoryRegion::Map() const { - return MapAt(0, handle_.GetSize()); +WritableSharedMemoryMapping UnsafeSharedMemoryRegion::Map( + SharedMemoryMapper* mapper) const { + return MapAt(0, handle_.GetSize(), mapper); } -WritableSharedMemoryMapping UnsafeSharedMemoryRegion::MapAt(uint64_t offset, - size_t size) const { +WritableSharedMemoryMapping UnsafeSharedMemoryRegion::MapAt( + uint64_t offset, + size_t size, + SharedMemoryMapper* mapper) const { if (!IsValid()) return {}; - auto result = handle_.MapAt(offset, size); + auto result = handle_.MapAt(offset, size, mapper); if (!result.has_value()) return {}; - return WritableSharedMemoryMapping(result.value(), size, handle_.GetGUID()); + return WritableSharedMemoryMapping(result.value(), size, handle_.GetGUID(), + mapper); } bool UnsafeSharedMemoryRegion::IsValid() const {
diff --git a/base/memory/unsafe_shared_memory_region.h b/base/memory/unsafe_shared_memory_region.h index ebfe0bc..1f0458f4 100644 --- a/base/memory/unsafe_shared_memory_region.h +++ b/base/memory/unsafe_shared_memory_region.h
@@ -76,14 +76,17 @@ // access. The mapped address is guaranteed to have an alignment of // at least |subtle::PlatformSharedMemoryRegion::kMapMinimumAlignment|. // Returns a valid WritableSharedMemoryMapping instance on success, invalid - // otherwise. - WritableSharedMemoryMapping Map() const; + // otherwise. A custom |SharedMemoryMapper| for mapping (and later unmapping) + // the region can be provided using the optional |mapper| parameter. + WritableSharedMemoryMapping Map(SharedMemoryMapper* mapper = nullptr) const; // Same as above, but maps only |size| bytes of the shared memory region // starting with the given |offset|. |offset| must be aligned to value of // |SysInfo::VMAllocationGranularity()|. Returns an invalid mapping if // requested bytes are out of the region limits. - WritableSharedMemoryMapping MapAt(uint64_t offset, size_t size) const; + WritableSharedMemoryMapping MapAt(uint64_t offset, + size_t size, + SharedMemoryMapper* mapper = nullptr) const; // Whether the underlying platform handle is valid. bool IsValid() const;
diff --git a/base/memory/writable_shared_memory_region.cc b/base/memory/writable_shared_memory_region.cc index 20c18d9..03b45599 100644 --- a/base/memory/writable_shared_memory_region.cc +++ b/base/memory/writable_shared_memory_region.cc
@@ -63,21 +63,24 @@ WritableSharedMemoryRegion&& region) = default; WritableSharedMemoryRegion::~WritableSharedMemoryRegion() = default; -WritableSharedMemoryMapping WritableSharedMemoryRegion::Map() const { - return MapAt(0, handle_.GetSize()); +WritableSharedMemoryMapping WritableSharedMemoryRegion::Map( + SharedMemoryMapper* mapper) const { + return MapAt(0, handle_.GetSize(), mapper); } WritableSharedMemoryMapping WritableSharedMemoryRegion::MapAt( uint64_t offset, - size_t size) const { + size_t size, + SharedMemoryMapper* mapper) const { if (!IsValid()) return {}; - auto result = handle_.MapAt(offset, size); + auto result = handle_.MapAt(offset, size, mapper); if (!result.has_value()) return {}; - return WritableSharedMemoryMapping(result.value(), size, handle_.GetGUID()); + return WritableSharedMemoryMapping(result.value(), size, handle_.GetGUID(), + mapper); } bool WritableSharedMemoryRegion::IsValid() const {
diff --git a/base/memory/writable_shared_memory_region.h b/base/memory/writable_shared_memory_region.h index ed469a8..02f56e3e 100644 --- a/base/memory/writable_shared_memory_region.h +++ b/base/memory/writable_shared_memory_region.h
@@ -84,14 +84,17 @@ // access. The mapped address is guaranteed to have an alignment of // at least |subtle::PlatformSharedMemoryRegion::kMapMinimumAlignment|. // Returns a valid WritableSharedMemoryMapping instance on success, invalid - // otherwise. - WritableSharedMemoryMapping Map() const; + // otherwise. A custom |SharedMemoryMapper| for mapping (and later unmapping) + // the region can be provided using the optional |mapper| parameter. + WritableSharedMemoryMapping Map(SharedMemoryMapper* mapper = nullptr) const; // Same as above, but maps only |size| bytes of the shared memory block // starting with the given |offset|. |offset| must be aligned to value of // |SysInfo::VMAllocationGranularity()|. Returns an invalid mapping if // requested bytes are out of the region limits. - WritableSharedMemoryMapping MapAt(uint64_t offset, size_t size) const; + WritableSharedMemoryMapping MapAt(uint64_t offset, + size_t size, + SharedMemoryMapper* mapper = nullptr) const; // Whether underlying platform handles are valid. bool IsValid() const;
diff --git a/base/profiler/stack_sampler_impl_unittest.cc b/base/profiler/stack_sampler_impl_unittest.cc index ad8bae3..4c402bfc 100644 --- a/base/profiler/stack_sampler_impl_unittest.cc +++ b/base/profiler/stack_sampler_impl_unittest.cc
@@ -272,13 +272,7 @@ } // namespace -// TODO(crbug.com/1001923): Fails on Linux MSan. -#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) -#define MAYBE_CopyStack DISABLED_MAYBE_CopyStack -#else -#define MAYBE_CopyStack CopyStack -#endif -TEST(StackSamplerImplTest, MAYBE_CopyStack) { +TEST(StackSamplerImplTest, CopyStack) { ModuleCache module_cache; const std::vector<uintptr_t> stack = {0, 1, 2, 3, 4}; InjectModuleForContextInstructionPointer(stack, &module_cache);
diff --git a/base/strings/stringprintf.cc b/base/strings/stringprintf.cc index 1a404853..bcace27 100644 --- a/base/strings/stringprintf.cc +++ b/base/strings/stringprintf.cc
@@ -12,7 +12,6 @@ #include "base/logging.h" #include "base/scoped_clear_last_error.h" #include "base/strings/string_util.h" -#include "base/strings/utf_string_conversions.h" #include "build/build_config.h" namespace base {
diff --git a/base/test/test_shared_memory_util.cc b/base/test/test_shared_memory_util.cc index 9e65f327..8250aa4 100644 --- a/base/test/test_shared_memory_util.cc +++ b/base/test/test_shared_memory_util.cc
@@ -150,11 +150,13 @@ subtle::PlatformSharedMemoryRegion* region, uint64_t offset, size_t size) { - auto result = region->MapAt(offset, size); + SharedMemoryMapper* mapper = SharedMemoryMapper::GetDefaultInstance(); + auto result = region->MapAt(offset, size, mapper); if (!result.has_value()) return {}; - return WritableSharedMemoryMapping(result.value(), size, region->GetGUID()); + return WritableSharedMemoryMapping(result.value(), size, region->GetGUID(), + mapper); } template <>
diff --git a/build/fuchsia/linux_internal.sdk.sha1 b/build/fuchsia/linux_internal.sdk.sha1 index e0b6e68a..8ece2d5 100644 --- a/build/fuchsia/linux_internal.sdk.sha1 +++ b/build/fuchsia/linux_internal.sdk.sha1
@@ -1 +1 @@ -8.20220426.0.1 +8.20220426.2.1
diff --git a/cc/metrics/frame_sequence_metrics.cc b/cc/metrics/frame_sequence_metrics.cc index 1f4c2a5..6b4d3b0 100644 --- a/cc/metrics/frame_sequence_metrics.cc +++ b/cc/metrics/frame_sequence_metrics.cc
@@ -198,12 +198,13 @@ bool FrameSequenceMetrics::HasEnoughDataForReporting() const { return impl_throughput_.frames_expected >= kMinFramesForThroughputMetric || - main_throughput_.frames_expected >= kMinFramesForThroughputMetric; + main_throughput_.frames_expected >= kMinFramesForThroughputMetric || + v2_.frames_expected >= kMinFramesForThroughputMetric; } bool FrameSequenceMetrics::HasDataLeftForReporting() const { return impl_throughput_.frames_expected > 0 || - main_throughput_.frames_expected > 0; + main_throughput_.frames_expected > 0 || v2_.frames_expected > 0; } void FrameSequenceMetrics::AdoptTrace(FrameSequenceMetrics* adopt_from) {
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index 2c170b2..cbf4bf3 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn
@@ -265,7 +265,6 @@ "//components/translate/content/android:java_resources", "//components/webapps/browser/android:java_resources", "//content/public/android:content_java_resources", - "//third_party/android_deps:android_support_v7_appcompat_java", "//third_party/android_deps:material_design_java", "//third_party/androidx:androidx_gridlayout_gridlayout_java", "//third_party/androidx:androidx_preference_preference_java", @@ -608,7 +607,6 @@ "//services/shape_detection:shape_detection_java", "//services/shape_detection/public/mojom:mojom_java", "//skia/public/mojom:mojom_java", - "//third_party/android_deps:android_support_v7_appcompat_java", "//third_party/android_deps:chromium_play_services_availability_java", "//third_party/android_deps:com_google_android_play_core_java", "//third_party/android_deps:com_google_code_findbugs_jsr305_java", @@ -622,7 +620,6 @@ "//third_party/android_swipe_refresh:android_swipe_refresh_java", "//third_party/androidx:androidx_activity_activity_java", "//third_party/androidx:androidx_annotation_annotation_java", - "//third_party/androidx:androidx_appcompat_appcompat_resources_java", "//third_party/androidx:androidx_browser_browser_java", "//third_party/androidx:androidx_collection_collection_java", "//third_party/androidx:androidx_coordinatorlayout_coordinatorlayout_java", @@ -1032,6 +1029,7 @@ "//chrome/browser/ui/android/appmenu:java", "//chrome/browser/ui/android/appmenu/internal:junit", "//chrome/browser/ui/android/autofill/internal:junit", + "//chrome/browser/ui/android/autofill/test:test_support_java", "//chrome/browser/ui/android/default_browser_promo:java", "//chrome/browser/ui/android/default_browser_promo:junit", "//chrome/browser/ui/android/favicon:java", @@ -1139,7 +1137,6 @@ "//services/media_session/public/cpp/android:media_session_java", "//services/media_session/public/mojom:mojom_java", "//services/service_manager/public/java:service_manager_java", - "//third_party/android_deps:android_support_v7_appcompat_java", "//third_party/android_deps:chromium_play_services_availability_shadows_java", "//third_party/android_deps:com_google_guava_listenablefuture_java", "//third_party/android_deps:com_googlecode_java_diff_utils_diffutils_java", @@ -1594,7 +1591,6 @@ "//services/network/public/mojom:mojom_proxy_config_java", "//services/network/public/mojom:url_loader_base_java", "//services/service_manager/public/java:service_manager_java", - "//third_party/android_deps:android_support_v7_appcompat_java", "//third_party/android_deps:com_google_code_findbugs_jsr305_java", "//third_party/android_deps:com_google_flatbuffers_flatbuffers_java_java", "//third_party/android_deps:espresso_java", @@ -1607,7 +1603,6 @@ "//third_party/android_support_test_runner:rules_java", "//third_party/android_support_test_runner:runner_java", "//third_party/androidx:androidx_annotation_annotation_java", - "//third_party/androidx:androidx_appcompat_appcompat_resources_java", "//third_party/androidx:androidx_browser_browser_java", "//third_party/androidx:androidx_collection_collection_java", "//third_party/androidx:androidx_preference_preference_java", @@ -1726,13 +1721,10 @@ "//content/public/android:content_java", "//content/public/test/android:content_java_test_support", "//net/android:net_java_test_support", - "//third_party/android_deps:android_support_v7_appcompat_java", "//third_party/android_support_test_runner:rules_java", "//third_party/android_support_test_runner:runner_java", "//third_party/androidx:androidx_annotation_annotation_java", "//third_party/androidx:androidx_browser_browser_java", - "//third_party/androidx:androidx_lifecycle_lifecycle_common_java", - "//third_party/androidx:androidx_recyclerview_recyclerview_java", "//third_party/androidx:androidx_test_runner_java", "//third_party/junit", "//third_party/ub-uiautomator:ub_uiautomator_java",
diff --git a/chrome/android/chrome_java_resources.gni b/chrome/android/chrome_java_resources.gni index 10e3542..b45c38f 100644 --- a/chrome/android/chrome_java_resources.gni +++ b/chrome/android/chrome_java_resources.gni
@@ -160,6 +160,7 @@ "java/res/drawable-mdpi/tabswitcher_border_frame_inner_shadow.9.png", "java/res/drawable-mdpi/tabswitcher_border_frame_shadow.9.png", "java/res/drawable-mdpi/verify_checkmark.png", + "java/res/drawable-night/virtual_card_enrollment_illustration.xml", "java/res/drawable-nodpi/bookmark_widget_preview.png", "java/res/drawable-nodpi/widget_preview.png", "java/res/drawable-sw600dp/window_background.xml",
diff --git a/chrome/android/chrome_junit_test_java_sources.gni b/chrome/android/chrome_junit_test_java_sources.gni index 2bc4ee225..4718359 100644 --- a/chrome/android/chrome_junit_test_java_sources.gni +++ b/chrome/android/chrome_junit_test_java_sources.gni
@@ -22,7 +22,6 @@ "junit/src/org/chromium/chrome/browser/autofill/AutofillUiUtilsTest.java", "junit/src/org/chromium/chrome/browser/autofill/settings/AutofillVirtualCardEnrollmentDialogTest.java", "junit/src/org/chromium/chrome/browser/autofill/settings/AutofillVirtualCardUnenrollmentDialogTest.java", - "junit/src/org/chromium/chrome/browser/autofill/settings/FakeModalDialogManager.java", "junit/src/org/chromium/chrome/browser/background_sync/BackgroundSyncBackgroundTaskSchedulerTest.java", "junit/src/org/chromium/chrome/browser/background_sync/BackgroundSyncBackgroundTaskTest.java", "junit/src/org/chromium/chrome/browser/background_sync/BackgroundSyncGooglePlayServicesCheckerTest.java",
diff --git a/chrome/android/features/cablev2_authenticator/BUILD.gn b/chrome/android/features/cablev2_authenticator/BUILD.gn index c610598..8465a27 100644 --- a/chrome/android/features/cablev2_authenticator/BUILD.gn +++ b/chrome/android/features/cablev2_authenticator/BUILD.gn
@@ -23,8 +23,9 @@ "//components/webauthn/android:java", "//content/public/android:content_java", "//mojo/public/mojom/base:base_java", - "//third_party/android_deps:android_support_v7_appcompat_java", "//third_party/androidx:androidx_annotation_annotation_java", + "//third_party/androidx:androidx_fragment_fragment_java", + "//third_party/androidx:androidx_vectordrawable_vectordrawable_animated_java", "//third_party/blink/public/mojom:android_mojo_bindings_java", "//ui/android:ui_full_java", ]
diff --git a/chrome/android/features/keyboard_accessory/internal/BUILD.gn b/chrome/android/features/keyboard_accessory/internal/BUILD.gn index e0686b1..ba5dac7 100644 --- a/chrome/android/features/keyboard_accessory/internal/BUILD.gn +++ b/chrome/android/features/keyboard_accessory/internal/BUILD.gn
@@ -35,10 +35,11 @@ "//components/image_fetcher:java", "//components/url_formatter/android:url_formatter_java", "//content/public/android:content_java", - "//third_party/android_deps:android_support_v7_appcompat_java", "//third_party/android_deps:material_design_java", "//third_party/androidx:androidx_annotation_annotation_java", + "//third_party/androidx:androidx_appcompat_appcompat_java", "//third_party/androidx:androidx_appcompat_appcompat_resources_java", + "//third_party/androidx:androidx_core_core_java", "//third_party/androidx:androidx_recyclerview_recyclerview_java", "//third_party/androidx:androidx_viewpager_viewpager_java", "//ui/android:ui_java",
diff --git a/chrome/android/features/start_surface/internal/BUILD.gn b/chrome/android/features/start_surface/internal/BUILD.gn index b436f2f..98e7a972 100644 --- a/chrome/android/features/start_surface/internal/BUILD.gn +++ b/chrome/android/features/start_surface/internal/BUILD.gn
@@ -93,10 +93,12 @@ "//components/user_prefs/android:java", "//components/version_info/android:version_constants_java", "//content/public/android:content_java", - "//third_party/android_deps:android_support_v7_appcompat_java", "//third_party/android_deps:material_design_java", "//third_party/androidx:androidx_annotation_annotation_java", + "//third_party/androidx:androidx_appcompat_appcompat_java", "//third_party/androidx:androidx_browser_browser_java", + "//third_party/androidx:androidx_recyclerview_recyclerview_java", + "//third_party/androidx:androidx_vectordrawable_vectordrawable_animated_java", "//ui/android:ui_full_java", "//ui/android:ui_utils_java", "//ui/base/mojom:mojom_java",
diff --git a/chrome/android/features/tab_ui/BUILD.gn b/chrome/android/features/tab_ui/BUILD.gn index 614df94d..4cf2459 100644 --- a/chrome/android/features/tab_ui/BUILD.gn +++ b/chrome/android/features/tab_ui/BUILD.gn
@@ -235,16 +235,15 @@ "//content/public/android:content_java", "//content/public/android:content_java_resources", "//net/android:net_java", - "//third_party/android_deps:android_support_v7_appcompat_java", "//third_party/android_deps:material_design_java", "//third_party/androidx:androidx_annotation_annotation_java", + "//third_party/androidx:androidx_appcompat_appcompat_java", "//third_party/androidx:androidx_appcompat_appcompat_resources_java", "//third_party/androidx:androidx_coordinatorlayout_coordinatorlayout_java", "//third_party/androidx:androidx_core_core_java", - "//third_party/androidx:androidx_lifecycle_lifecycle_common_java", "//third_party/androidx:androidx_lifecycle_lifecycle_runtime_java", - "//third_party/androidx:androidx_lifecycle_lifecycle_viewmodel_java", "//third_party/androidx:androidx_recyclerview_recyclerview_java", + "//third_party/androidx:androidx_vectordrawable_vectordrawable_animated_java", "//ui/android:ui_java", "//ui/base/mojom:mojom_java", "//url:gurl_java",
diff --git a/chrome/android/features/vr/BUILD.gn b/chrome/android/features/vr/BUILD.gn index 8961852f..3523f9e 100644 --- a/chrome/android/features/vr/BUILD.gn +++ b/chrome/android/features/vr/BUILD.gn
@@ -94,11 +94,8 @@ "//components/policy/android:policy_java", "//content/public/android:content_java", "//device/vr:java", - "//third_party/android_deps:android_support_v7_appcompat_java", "//third_party/androidx:androidx_annotation_annotation_java", - "//third_party/androidx:androidx_lifecycle_lifecycle_common_java", "//third_party/androidx:androidx_lifecycle_lifecycle_runtime_java", - "//third_party/androidx:androidx_lifecycle_lifecycle_viewmodel_java", "//third_party/gvr-android-keyboard:kb_java", "//third_party/gvr-android-sdk:gvr_common_java", "//ui/android:ui_full_java",
diff --git a/chrome/android/feed/feed_java_sources.gni b/chrome/android/feed/feed_java_sources.gni index 290960c4..e0e665d 100644 --- a/chrome/android/feed/feed_java_sources.gni +++ b/chrome/android/feed/feed_java_sources.gni
@@ -7,16 +7,21 @@ feed_deps = [ "//base:base_java", "//chrome/android/feed:chrome_feed_java_resources", - "//third_party/android_deps:android_support_v7_appcompat_java", "//third_party/android_deps:com_google_code_findbugs_jsr305_java", "//third_party/android_deps:javax_inject_javax_inject_java", "//third_party/android_deps:protobuf_lite_runtime_java", "//third_party/androidx:androidx_annotation_annotation_java", + "//third_party/androidx:androidx_appcompat_appcompat_java", + "//third_party/androidx:androidx_appcompat_appcompat_resources_java", "//third_party/androidx:androidx_cardview_cardview_java", "//third_party/androidx:androidx_collection_collection_java", - "//third_party/androidx:androidx_interpolator_interpolator_java", + "//third_party/androidx:androidx_core_core_java", + "//third_party/androidx:androidx_fragment_fragment_java", + "//third_party/androidx:androidx_lifecycle_lifecycle_common_java", + "//third_party/androidx:androidx_media_media_java", "//third_party/androidx:androidx_recyclerview_recyclerview_java", "//third_party/androidx:androidx_swiperefreshlayout_swiperefreshlayout_java", + "//third_party/androidx:androidx_vectordrawable_vectordrawable_java", ] feed_java_sources = [
diff --git a/chrome/android/java/res/drawable-night/virtual_card_enrollment_illustration.xml b/chrome/android/java/res/drawable-night/virtual_card_enrollment_illustration.xml new file mode 100644 index 0000000..c509f34 --- /dev/null +++ b/chrome/android/java/res/drawable-night/virtual_card_enrollment_illustration.xml
@@ -0,0 +1,55 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- 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. --> + +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="125dp" + android:height="88dp" + android:viewportWidth="125" + android:viewportHeight="88"> + <path + android:strokeWidth="1" + android:pathData="M0.584,68.234C0.584,69.471 1.587,70.474 2.824,70.474H83.67C84.906,70.474 85.91,69.471 85.91,68.234V19.795C85.91,18.558 84.906,17.555 83.67,17.555H2.824C1.587,17.555 0.584,18.558 0.584,19.795V68.234Z" + android:fillColor="#9AA0A6" + android:strokeColor="#9AA0A6"/> + <path + android:pathData="M72.032,54.814H12.966C11.724,54.814 10.721,53.811 10.721,52.569V51.522C10.721,50.281 11.724,49.277 12.966,49.277H72.032C73.274,49.277 74.277,50.281 74.277,51.522V52.569C74.27,53.811 73.266,54.814 72.032,54.814Z" + android:fillColor="#BDC1C6"/> + <path + android:pathData="M16.734,41.986H8.866C7.66,41.986 6.686,41.011 6.686,39.806V34.825C6.686,33.619 7.66,32.645 8.866,32.645H16.734C17.94,32.645 18.915,33.619 18.915,34.825V39.806C18.915,41.011 17.94,41.986 16.734,41.986Z" + android:fillColor="#BDC1C6"/> + <path + android:pathData="M23.737,63.513H12.641C11.58,63.513 10.721,62.654 10.721,61.593V59.896C10.721,58.835 11.58,57.976 12.641,57.976H23.737C24.798,57.976 25.657,58.835 25.657,59.896V61.593C25.657,62.654 24.798,63.513 23.737,63.513Z" + android:fillColor="#BDC1C6"/> + <path + android:strokeWidth="1" + android:pathData="M10.217,32.645V41.986" + android:fillColor="#00000000" + android:strokeColor="#9AA0A6"/> + <path + android:strokeWidth="1" + android:pathData="M18.915,37.315H6.693" + android:fillColor="#00000000" + android:strokeColor="#9AA0A6"/> + <path + android:pathData="M75.771,88C100.072,88 119.771,68.3 119.771,44C119.771,19.699 100.072,0 75.771,0C51.471,0 31.771,19.699 31.771,44C31.771,68.3 51.471,88 75.771,88Z" + android:fillColor="#185ABC"/> + <path + android:pathData="M83.67,16.972H41.07C35.252,24.429 31.779,33.807 31.779,44C31.779,54.208 35.266,63.592 41.099,71.057H83.677C85.236,71.057 86.5,69.794 86.5,68.234V19.795C86.492,18.235 85.229,16.972 83.67,16.972Z" + android:fillColor="#4285F4"/> + <path + android:pathData="M92.059,41.849L101.941,51.732L123.981,29.685" + android:strokeLineJoin="round" + android:strokeWidth="2" + android:fillColor="#00000000" + android:strokeColor="#34A853" + android:strokeLineCap="round"/> + <path + android:pathData="M60.512,29.778L71.586,34.702V42.138C71.586,49.292 66.871,55.882 60.512,57.846C54.152,55.882 49.438,49.284 49.438,42.138V34.702L60.512,29.778Z" + android:strokeLineJoin="round" + android:strokeWidth="2" + android:fillColor="#00000000" + android:strokeColor="#ffffff" + android:strokeLineCap="round"/> +</vector>
diff --git a/chrome/android/java/res/menu/main_menu.xml b/chrome/android/java/res/menu/main_menu.xml index 1085a45..96f4adb1 100644 --- a/chrome/android/java/res/menu/main_menu.xml +++ b/chrome/android/java/res/menu/main_menu.xml
@@ -153,11 +153,9 @@ android:icon="@drawable/gm_filled_cardboard_24" /> <item android:id="@+id/managed_by_divider_line_id" android:title="@null" /> - <item android:id="@+id/managed_by_standard_menu_id" + <item android:id="@+id/managed_by_menu_id" android:title="@string/managed_browser" android:icon="@drawable/ic_business" /> - <item android:id="@+id/managed_by_menu_id" - android:title="@string/managed" /> </group> <!-- Items shown only in the tab switcher -->
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java index e07ff22..361157d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java
@@ -2652,9 +2652,7 @@ return true; } - if (id == R.id.managed_by_standard_menu_id) { - assert ChromeFeatureList.isEnabled(ChromeFeatureList.CHROME_MANAGEMENT_PAGE); - + if (id == R.id.managed_by_menu_id) { openChromeManagementPage(); return 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 46cd340..7b7231a3 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
@@ -1200,19 +1200,14 @@ } protected void updateManagedByMenuItem(Menu menu, @Nullable Tab currentTab) { - MenuItem managedByMenuItem = menu.findItem(R.id.managed_by_menu_id); MenuItem managedByDividerLine = menu.findItem(R.id.managed_by_divider_line_id); - MenuItem managedByStandardMenuItem = menu.findItem(R.id.managed_by_standard_menu_id); + MenuItem managedByMenuItem = menu.findItem(R.id.managed_by_menu_id); boolean managedByMenuItemVisible = currentTab != null && shouldShowManagedByMenuItem(currentTab); - boolean chromeManagementPageEnabled = - ChromeFeatureList.isEnabled(ChromeFeatureList.CHROME_MANAGEMENT_PAGE); - managedByMenuItem.setVisible(managedByMenuItemVisible && !chromeManagementPageEnabled); - managedByDividerLine.setVisible(managedByMenuItemVisible && chromeManagementPageEnabled); - managedByStandardMenuItem.setVisible( - managedByMenuItemVisible && chromeManagementPageEnabled); + managedByDividerLine.setVisible(managedByMenuItemVisible); + managedByMenuItem.setVisible(managedByMenuItemVisible); } @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/native_page/NativePageFactory.java b/chrome/android/java/src/org/chromium/chrome/browser/native_page/NativePageFactory.java index 153e517..77973a0 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/native_page/NativePageFactory.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/native_page/NativePageFactory.java
@@ -270,10 +270,6 @@ page = getBuilder().buildLaunchpadPage(tab); break; case NativePageType.MANAGEMENT: - if (!ChromeFeatureList.isEnabled(ChromeFeatureList.CHROME_MANAGEMENT_PAGE)) { - return null; - } - page = getBuilder().buildManagementPage(tab); break; default:
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabFromChromeExternalNavigationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabFromChromeExternalNavigationTest.java index 5a7d09f..1bb7ec3 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabFromChromeExternalNavigationTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabFromChromeExternalNavigationTest.java
@@ -7,41 +7,25 @@ import android.content.Intent; import android.net.Uri; import android.support.test.InstrumentationRegistry; -import android.util.Base64; -import androidx.test.filters.LargeTest; import androidx.test.filters.MediumTest; -import org.hamcrest.Matchers; import org.junit.Assert; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; -import org.chromium.base.ActivityState; -import org.chromium.base.ApiCompatibilityUtils; -import org.chromium.base.ApplicationStatus; import org.chromium.base.IntentUtils; import org.chromium.base.test.util.CommandLineFlags; -import org.chromium.base.test.util.Criteria; -import org.chromium.base.test.util.CriteriaHelper; -import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Feature; import org.chromium.chrome.browser.LaunchIntentDispatcher; import org.chromium.chrome.browser.customtabs.CustomTabDelegateFactory.CustomTabNavigationDelegate; import org.chromium.chrome.browser.flags.ChromeSwitches; -import org.chromium.chrome.browser.tab.InterceptNavigationDelegateTabHelper; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.TabDelegateFactory; import org.chromium.chrome.browser.tab.TabTestUtils; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; -import org.chromium.chrome.test.ChromeTabbedActivityTestRule; -import org.chromium.components.external_intents.ExternalNavigationHandler.OverrideUrlLoadingResultType; -import org.chromium.components.external_intents.InterceptNavigationDelegateImpl; import org.chromium.content_public.browser.test.util.TestThreadUtils; -import org.chromium.net.test.EmbeddedTestServerRule; - -import java.util.concurrent.atomic.AtomicReference; /** * Tests for external navigation handling of Custom Tabs generated by Chrome. @@ -52,12 +36,6 @@ @Rule public CustomTabActivityTestRule mActivityRule = new CustomTabActivityTestRule(); - @Rule - public ChromeTabbedActivityTestRule mChromeActivityTestRule = - new ChromeTabbedActivityTestRule(); - - public EmbeddedTestServerRule mServerRule = new EmbeddedTestServerRule(); - private Intent getCustomTabFromChromeIntent(final String url, final boolean markFromChrome) { return TestThreadUtils.runOnUiThreadBlockingNoException(() -> { Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); @@ -74,7 +52,6 @@ mActivityRule.startCustomTabActivityWithIntent(intent); } - @DisabledTest(message = "https://crbug.com/1197727") @Test @Feature("CustomTabFromChrome") @MediumTest @@ -89,53 +66,4 @@ Assert.assertFalse(customTabDelegateFactory.getExternalNavigationDelegate() instanceof CustomTabNavigationDelegate); } - - @Test - @Feature("CustomTabFromChrome") - @LargeTest - @DisabledTest(message = "https://crbug.com/1197727") - public void testIntentWithRedirectToApp() { - final String redirectUrl = "https://maps.google.com/maps?q=1600+amphitheatre+parkway"; - final String initialUrl = - mServerRule.getServer().getURL("/chrome/test/data/android/redirect/js_redirect.html" - + "?replace_text=" - + Base64.encodeToString( - ApiCompatibilityUtils.getBytesUtf8("PARAM_URL"), Base64.URL_SAFE) - + ":" - + Base64.encodeToString( - ApiCompatibilityUtils.getBytesUtf8(redirectUrl), Base64.URL_SAFE)); - - mActivityRule.launchActivity(getCustomTabFromChromeIntent(initialUrl, true)); - mActivityRule.waitForActivityNativeInitializationComplete(); - - final AtomicReference<InterceptNavigationDelegateImpl> navigationDelegate = - new AtomicReference<>(); - - CriteriaHelper.pollUiThread(() -> { - return mActivityRule.getActivity().getActivityTab() != null; - }, "Tab never initialized."); - - CriteriaHelper.pollUiThread(() -> { - Tab tab = mActivityRule.getActivity().getActivityTab(); - InterceptNavigationDelegateImpl delegate = - InterceptNavigationDelegateTabHelper.get(tab); - if (delegate == null) return false; - navigationDelegate.set(delegate); - return true; - }, "Navigation delegate never initialized."); - - CriteriaHelper.pollUiThread(() -> { - Criteria.checkThat(navigationDelegate.get().getLastOverrideUrlLoadingResultForTests(), - Matchers.notNullValue()); - Criteria.checkThat(navigationDelegate.get() - .getLastOverrideUrlLoadingResultForTests() - .getResultType(), - Matchers.is(OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT)); - }); - - CriteriaHelper.pollUiThread(() -> { - int state = ApplicationStatus.getStateForActivity(mActivityRule.getActivity()); - return state == ActivityState.STOPPED || state == ActivityState.DESTROYED; - }, "Activity never stopped or destroyed."); - } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/externalnav/UrlOverridingTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/externalnav/UrlOverridingTest.java index 839fa42..cb06445 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/externalnav/UrlOverridingTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/externalnav/UrlOverridingTest.java
@@ -21,6 +21,7 @@ import android.support.test.runner.lifecycle.Stage; import android.text.TextUtils; import android.util.Base64; +import android.util.Pair; import androidx.test.filters.LargeTest; import androidx.test.filters.SmallTest; @@ -39,17 +40,22 @@ import org.mockito.quality.Strictness; import org.chromium.base.ApiCompatibilityUtils; +import org.chromium.base.Callback; import org.chromium.base.ContextUtils; +import org.chromium.base.IntentUtils; import org.chromium.base.PackageManagerUtils; import org.chromium.base.test.util.ApplicationTestUtils; import org.chromium.base.test.util.CallbackHelper; import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.Criteria; import org.chromium.base.test.util.CriteriaHelper; +import org.chromium.base.test.util.Feature; import org.chromium.base.test.util.PackageManagerWrapper; import org.chromium.base.test.util.Restriction; import org.chromium.blink_public.common.BlinkFeatures; import org.chromium.chrome.browser.ChromeTabbedActivity; +import org.chromium.chrome.browser.LaunchIntentDispatcher; +import org.chromium.chrome.browser.customtabs.CustomTabActivityTestRule; import org.chromium.chrome.browser.document.ChromeLauncherActivity; import org.chromium.chrome.browser.flags.ChromeSwitches; import org.chromium.chrome.browser.init.AsyncInitializationActivity; @@ -64,6 +70,7 @@ import org.chromium.chrome.test.util.browser.Features; import org.chromium.components.embedder_support.util.UrlConstants; import org.chromium.components.external_intents.ExternalNavigationHandler; +import org.chromium.components.external_intents.ExternalNavigationHandler.OverrideUrlLoadingResult; import org.chromium.components.external_intents.ExternalNavigationHandler.OverrideUrlLoadingResultType; import org.chromium.components.external_intents.InterceptNavigationDelegateImpl; import org.chromium.components.external_intents.RedirectHandler; @@ -84,6 +91,7 @@ import java.util.List; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; +import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReference; /** @@ -98,6 +106,9 @@ @Rule public MockitoRule mMockitoRule = MockitoJUnit.rule().strictness(Strictness.STRICT_STUBS); + @Rule + public CustomTabActivityTestRule mCustomTabActivityRule = new CustomTabActivityTestRule(); + private static final String BASE_PATH = "/chrome/test/data/android/url_overriding/"; private static final String NAVIGATION_FROM_TIMEOUT_PAGE = BASE_PATH + "navigation_from_timer.html"; @@ -192,6 +203,8 @@ private static class TestContext extends ContextWrapper { private boolean mResolveToNonBrowserPackage; + private String mHostToMatch; + private IntentFilter mFilterForHostMatch; public TestContext(Context baseContext) { super(baseContext); @@ -210,6 +223,11 @@ return false; } + private void setIntentFilterForHost(String host, IntentFilter filter) { + mHostToMatch = host; + mFilterForHostMatch = filter; + } + @Override public PackageManager getPackageManager() { return new PackageManagerWrapper(super.getPackageManager()) { @@ -225,6 +243,13 @@ // images. if (targetsPlay(intent)) return null; + if (mHostToMatch != null && intent.getData() != null + && intent.getData().getHost().equals(mHostToMatch)) { + ResolveInfo info = newResolveInfo(NON_BROWSER_PACKAGE); + info.filter = mFilterForHostMatch; + return Arrays.asList(info); + } + return TestContext.super.getPackageManager().queryIntentActivities( intent, flags); } @@ -275,6 +300,17 @@ } } + private Intent getCustomTabFromChromeIntent(final String url, final boolean markFromChrome) { + return TestThreadUtils.runOnUiThreadBlockingNoException(() -> { + Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + intent = LaunchIntentDispatcher.createCustomTabActivityIntent( + InstrumentationRegistry.getTargetContext(), intent); + IntentUtils.addTrustedIntentExtras(intent); + return intent; + }); + } + private void loadUrlAndWaitForIntentUrl( final String url, boolean needClick, boolean shouldLaunchExternalIntent) { loadUrlAndWaitForIntentUrl(url, needClick, false, shouldLaunchExternalIntent, url, true); @@ -300,8 +336,19 @@ final Tab[] latestTabHolder = new Tab[1]; final InterceptNavigationDelegateImpl[] latestDelegateHolder = new InterceptNavigationDelegateImpl[1]; + + AtomicInteger lastResultValue = new AtomicInteger(); + latestTabHolder[0] = tab; latestDelegateHolder[0] = getInterceptNavigationDelegate(tab); + + Callback<Pair<GURL, OverrideUrlLoadingResult>> resultCallback = + (Pair<GURL, OverrideUrlLoadingResult> result) -> { + if (result.first.getSpec().equals(url)) return; + lastResultValue.set(result.second.getResultType()); + }; + + latestDelegateHolder[0].setResultCallbackForTesting(resultCallback); TestThreadUtils.runOnUiThreadBlocking(() -> { tab.addObserver(new TestTabObserver(finishCallback, failCallback, destroyedCallback)); @@ -313,19 +360,17 @@ newTab.addObserver( new TestTabObserver(finishCallback, failCallback, destroyedCallback)); latestTabHolder[0] = newTab; + latestDelegateHolder[0].setResultCallbackForTesting(null); latestDelegateHolder[0] = getInterceptNavigationDelegate(newTab); + latestDelegateHolder[0].setResultCallbackForTesting(resultCallback); } }; mActivityTestRule.getActivity().getTabModelSelector().addObserver(selectorObserver); }); mActivityTestRule.getActivity().onUserInteraction(); - InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() { - @Override - public void run() { - tab.loadUrl(new LoadUrlParams(url, PageTransition.LINK)); - } - }); + TestThreadUtils.runOnUiThreadBlocking( + () -> { tab.loadUrl(new LoadUrlParams(url, PageTransition.LINK)); }); if (finishCallback.getCallCount() == 0) { try { @@ -336,9 +381,6 @@ } } - TestThreadUtils.runOnUiThreadBlocking( - () -> { latestDelegateHolder[0].clearLastOverrideUrlLoadingResultForTests(); }); - if (needClick) { if (clickTargetId == null) { TouchCommon.singleClickView(tab.getView()); @@ -402,15 +444,11 @@ // fallback and normal navigation. See crbug.com/487364 for more. Tab latestTab = latestTabHolder[0]; InterceptNavigationDelegateImpl delegate = latestDelegateHolder[0]; - Criteria.checkThat( - delegate.getLastOverrideUrlLoadingResultForTests(), Matchers.notNullValue()); if (shouldLaunchExternalIntent) { - Criteria.checkThat( - delegate.getLastOverrideUrlLoadingResultForTests().getResultType(), + Criteria.checkThat(lastResultValue.get(), Matchers.is(OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT)); } else { - Criteria.checkThat( - delegate.getLastOverrideUrlLoadingResultForTests().getResultType(), + Criteria.checkThat(lastResultValue.get(), Matchers.not(OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT)); } if (expectedFinalUrl == null) return; @@ -805,7 +843,8 @@ } } }; - mActivityTestRule.startMainActivityWithURL(mTestServer.getURL(NAVIGATION_FROM_BFCACHE)); + String url = mTestServer.getURL(NAVIGATION_FROM_BFCACHE); + mActivityTestRule.startMainActivityWithURL(url); final Tab tab = mActivityTestRule.getActivity().getActivityTab(); @@ -824,6 +863,12 @@ finishCallback.waitForCallback(0); syncHelper.notifyCalled(); + AtomicInteger lastResultValue = new AtomicInteger(); + delegate.setResultCallbackForTesting((Pair<GURL, OverrideUrlLoadingResult> result) -> { + if (result.first.getSpec().equals(url)) return; + lastResultValue.set(result.second.getResultType()); + }); + // Press back to go back to first page with BFCache. TestThreadUtils.runOnUiThreadBlocking( () -> mActivityTestRule.getActivity().onBackPressed()); @@ -838,8 +883,7 @@ finishCallback.waitForCallback(2); // With RedirectHandler state cleared, this should be treated as a navigation without a // user gesture, and so should not allow external navigation. - Assert.assertEquals(OverrideUrlLoadingResultType.NO_OVERRIDE, - delegate.getLastOverrideUrlLoadingResultForTests().getResultType()); + Assert.assertEquals(OverrideUrlLoadingResultType.NO_OVERRIDE, lastResultValue.get()); Assert.assertTrue(mLastNavigationHandle.get().getUrl().getSpec().startsWith("intent://")); syncHelper.notifyCalled(); } @@ -949,4 +993,33 @@ () -> { Criteria.checkThat(mActivityMonitor.getHits(), Matchers.is(1)); }); } } + + @Test + @Feature("CustomTabFromChrome") + @LargeTest + public void testIntentWithRedirectToApp() { + final String redirectUrl = "https://example.com/path"; + final String initialUrl = + mTestServer.getURL("/chrome/test/data/android/redirect/js_redirect.html" + + "?replace_text=" + + Base64.encodeToString( + ApiCompatibilityUtils.getBytesUtf8("PARAM_URL"), Base64.URL_SAFE) + + ":" + + Base64.encodeToString( + ApiCompatibilityUtils.getBytesUtf8(redirectUrl), Base64.URL_SAFE)); + + IntentFilter filter = new IntentFilter(Intent.ACTION_VIEW); + filter.addCategory(Intent.CATEGORY_BROWSABLE); + filter.addDataAuthority("example.com", null); + filter.addDataScheme("https"); + ActivityMonitor monitor = InstrumentationRegistry.getInstrumentation().addMonitor( + filter, new Instrumentation.ActivityResult(Activity.RESULT_OK, null), true); + mTestContext.setIntentFilterForHost("example.com", filter); + + mCustomTabActivityRule.launchActivity(getCustomTabFromChromeIntent(initialUrl, true)); + + CriteriaHelper.pollUiThread(() -> { + Criteria.checkThat(monitor.getHits(), Matchers.is(1)); + }, 10000L, CriteriaHelper.DEFAULT_POLLING_INTERVAL); + } }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/app/appmenu/AppMenuPropertiesDelegateUnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/app/appmenu/AppMenuPropertiesDelegateUnitTest.java index a3691f1..751b85b 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/app/appmenu/AppMenuPropertiesDelegateUnitTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/app/appmenu/AppMenuPropertiesDelegateUnitTest.java
@@ -204,7 +204,6 @@ setBookmarkItemRowEnabled(false); setReadingListItemRowEnabled(false); setShoppingListItemRowEnabled(false); - mTestValues.addFeatureFlagOverride(ChromeFeatureList.CHROME_MANAGEMENT_PAGE, true); FeatureList.setTestValues(mTestValues); } @@ -235,11 +234,6 @@ mTestValues.addFeatureFlagOverride(ChromeFeatureList.SHOPPING_LIST, enabled); } - private void setChromeManagementPageEnabled(boolean enabled) { - mTestValues.addFeatureFlagOverride(ChromeFeatureList.CHROME_MANAGEMENT_PAGE, enabled); - FeatureList.setTestValues(mTestValues); - } - @After public void tearDown() { ThreadUtils.setThreadAssertsDisabledForTesting(false); @@ -415,7 +409,7 @@ R.id.divider_line_id, R.id.share_row_menu_id, R.id.find_in_page_id, R.id.translate_id, R.id.add_to_homescreen_id, R.id.request_desktop_site_row_menu_id, R.id.auto_dark_web_contents_row_menu_id, R.id.divider_line_id, R.id.preferences_id, - R.id.help_id, R.id.managed_by_divider_line_id, R.id.managed_by_standard_menu_id}; + R.id.help_id, R.id.managed_by_divider_line_id, R.id.managed_by_menu_id}; assertMenuItemsAreEqual(menu, expectedItems); } @@ -822,8 +816,7 @@ } @Test - public void managedByMenuItem_ChromeManagementPageDisabled() { - setChromeManagementPageEnabled(false); + public void managedByMenuItem_ChromeManagementPage() { setUpMocksForPageMenu(); setMenuOptions(new MenuOptions().withShowAddToHomeScreen()); doReturn(true).when(mAppMenuPropertiesDelegate).shouldShowManagedByMenuItem(any(Tab.class)); @@ -833,34 +826,9 @@ mAppMenuPropertiesDelegate.prepareMenu(menu, null); MenuItem managedByMenuItem = menu.findItem(R.id.managed_by_menu_id); - MenuItem managedByStandardMenuItem = menu.findItem(R.id.managed_by_standard_menu_id); Assert.assertNotNull(managedByMenuItem); Assert.assertTrue(managedByMenuItem.isVisible()); - - Assert.assertNotNull(managedByStandardMenuItem); - Assert.assertTrue(!managedByStandardMenuItem.isVisible()); - } - - @Test - public void managedByMenuItem_ChromeManagementPageEnabled() { - setChromeManagementPageEnabled(true); - setUpMocksForPageMenu(); - setMenuOptions(new MenuOptions().withShowAddToHomeScreen()); - doReturn(true).when(mAppMenuPropertiesDelegate).shouldShowManagedByMenuItem(any(Tab.class)); - - Assert.assertEquals(MenuGroup.PAGE_MENU, mAppMenuPropertiesDelegate.getMenuGroup()); - Menu menu = createTestMenu(); - mAppMenuPropertiesDelegate.prepareMenu(menu, null); - - MenuItem managedByMenuItem = menu.findItem(R.id.managed_by_menu_id); - MenuItem managedByStandardMenuItem = menu.findItem(R.id.managed_by_standard_menu_id); - - Assert.assertNotNull(managedByMenuItem); - Assert.assertTrue(!managedByMenuItem.isVisible()); - - Assert.assertNotNull(managedByStandardMenuItem); - Assert.assertTrue(managedByStandardMenuItem.isVisible()); } private void setUpMocksForPageMenu() {
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/autofill/settings/AutofillVirtualCardEnrollmentDialogTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/autofill/settings/AutofillVirtualCardEnrollmentDialogTest.java index 1d9ea9a..15ee21f9 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/autofill/settings/AutofillVirtualCardEnrollmentDialogTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/autofill/settings/AutofillVirtualCardEnrollmentDialogTest.java
@@ -37,6 +37,8 @@ import org.chromium.chrome.R; import org.chromium.chrome.browser.autofill.LegalMessageLine; import org.chromium.chrome.browser.customtabs.CustomTabActivity; +import org.chromium.chrome.browser.ui.autofill.FakeModalDialogManager; +import org.chromium.ui.modaldialog.ModalDialogManager.ModalDialogType; import org.chromium.ui.modaldialog.ModalDialogProperties; import org.chromium.ui.text.NoUnderlineClickableSpan; @@ -57,7 +59,7 @@ @Before public void setUp() { - mModalDialogManager = new FakeModalDialogManager(); + mModalDialogManager = new FakeModalDialogManager(ModalDialogType.APP); mVirtualCardEnrollmentFields = VirtualCardEnrollmentFields.create( "card label", Bitmap.createBitmap(100, 100, Bitmap.Config.ALPHA_8)); mVirtualCardEnrollmentFields.mGoogleLegalMessages.add(createLegalMessageLine("google"));
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/autofill/settings/AutofillVirtualCardUnenrollmentDialogTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/autofill/settings/AutofillVirtualCardUnenrollmentDialogTest.java index d196491..0eabd05 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/autofill/settings/AutofillVirtualCardUnenrollmentDialogTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/autofill/settings/AutofillVirtualCardUnenrollmentDialogTest.java
@@ -32,6 +32,8 @@ import org.chromium.base.Callback; import org.chromium.base.test.BaseRobolectricTestRunner; import org.chromium.chrome.browser.customtabs.CustomTabActivity; +import org.chromium.chrome.browser.ui.autofill.FakeModalDialogManager; +import org.chromium.ui.modaldialog.ModalDialogManager.ModalDialogType; import org.chromium.ui.modaldialog.ModalDialogProperties; import org.chromium.ui.text.NoUnderlineClickableSpan; @@ -50,7 +52,7 @@ @Before public void setUp() { - mModalDialogManager = new FakeModalDialogManager(); + mModalDialogManager = new FakeModalDialogManager(ModalDialogType.APP); mDialog = new AutofillVirtualCardUnenrollmentDialog( ApplicationProvider.getApplicationContext(), mModalDialogManager, mCallbackMock); mDialog.show();
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/tabbed_mode/TabbedAppMenuPropertiesDelegateUnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/tabbed_mode/TabbedAppMenuPropertiesDelegateUnitTest.java index 2b7db31..582973b 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/tabbed_mode/TabbedAppMenuPropertiesDelegateUnitTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/tabbed_mode/TabbedAppMenuPropertiesDelegateUnitTest.java
@@ -81,7 +81,7 @@ */ @RunWith(BaseRobolectricTestRunner.class) @Features.EnableFeatures({ChromeFeatureList.WEB_FEED, ChromeFeatureList.READ_LATER, - ChromeFeatureList.BOOKMARKS_REFRESH, ChromeFeatureList.CHROME_MANAGEMENT_PAGE}) + ChromeFeatureList.BOOKMARKS_REFRESH}) @Features.DisableFeatures({ChromeFeatureList.READ_LATER, ChromeFeatureList.SHOPPING_LIST}) public class TabbedAppMenuPropertiesDelegateUnitTest { // Costants defining flags that determines multi-window menu items visibility. @@ -230,7 +230,7 @@ R.id.find_in_page_id, R.id.add_to_homescreen_id, R.id.request_desktop_site_row_menu_id, R.id.auto_dark_web_contents_row_menu_id, R.id.divider_line_id, R.id.preferences_id, R.id.help_id, - R.id.managed_by_divider_line_id, R.id.managed_by_standard_menu_id}; + R.id.managed_by_divider_line_id, R.id.managed_by_menu_id}; assertMenuItemsAreEqual(menu, expectedItems); }
diff --git a/chrome/android/modules/cablev2_authenticator/public/BUILD.gn b/chrome/android/modules/cablev2_authenticator/public/BUILD.gn index 1350cdf3..25df020 100644 --- a/chrome/android/modules/cablev2_authenticator/public/BUILD.gn +++ b/chrome/android/modules/cablev2_authenticator/public/BUILD.gn
@@ -12,8 +12,8 @@ "//base:base_java", "//components/module_installer/android:module_installer_java", "//components/module_installer/android:module_interface_java", - "//third_party/android_deps:android_support_v7_appcompat_java", "//third_party/androidx:androidx_annotation_annotation_java", + "//third_party/androidx:androidx_fragment_fragment_java", ] annotation_processor_deps = [ "//components/module_installer/android:module_interface_processor" ]
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 0dc40a86..6f21dc7 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -4008,6 +4008,8 @@ "metrics/first_web_contents_profiler_base.cc", "metrics/first_web_contents_profiler_base.h", "metrics/incognito_observer_desktop.cc", + "metrics/power/power_metrics.cc", + "metrics/power/power_metrics.h", "metrics/power/power_metrics_reporter.cc", "metrics/power/power_metrics_reporter.h", "metrics/power/usage_scenario.cc",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 7001c5b..abbc711 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -217,7 +217,6 @@ #include "components/browser_ui/photo_picker/android/features.h" #include "components/content_creation/notes/core/note_features.h" #include "components/content_creation/reactions/core/reactions_features.h" -#include "components/external_intents/android/external_intents_features.h" #include "components/translate/content/android/translate_message.h" #include "components/webapps/browser/android/features.h" #else // BUILDFLAG(IS_ANDROID) @@ -4276,6 +4275,10 @@ {"theme-refactor-android", flag_descriptions::kThemeRefactorAndroidName, flag_descriptions::kThemeRefactorAndroidDescription, kOsAndroid, FEATURE_VALUE_TYPE(chrome::android::kThemeRefactorAndroid)}, + {"back-gesture-refactor-android", + flag_descriptions::kBackGestureRefactorAndroidName, + flag_descriptions::kBackGestureRefactorAndroidDescription, kOsAndroid, + FEATURE_VALUE_TYPE(chrome::android::kBackGestureRefactorAndroid)}, #endif // BUILDFLAG(IS_ANDROID) {"disallow-doc-written-script-loads", flag_descriptions::kDisallowDocWrittenScriptsUiName, @@ -6252,7 +6255,7 @@ FEATURE_VALUE_TYPE(autofill::features::kAutofillCreditCardUploadFeedback)}, {"font-access", flag_descriptions::kFontAccessAPIName, - flag_descriptions::kFontAccessAPIDescription, kOsAll, + flag_descriptions::kFontAccessAPIDescription, kOsDesktop, FEATURE_VALUE_TYPE(blink::features::kFontAccess)}, {"mouse-subframe-no-implicit-capture", @@ -6657,12 +6660,6 @@ #endif // BUILDFLAG(ENABLE_PAINT_PREVIEW) && BUILDFLAG(IS_ANDROID) #if BUILDFLAG(IS_ANDROID) - {"block-external-form-redirects-no-gesture", - flag_descriptions::kIntentBlockExternalFormRedirectsNoGestureName, - flag_descriptions::kIntentBlockExternalFormRedirectsNoGestureDescription, - kOsAndroid, - FEATURE_VALUE_TYPE( - external_intents::kIntentBlockExternalFormRedirectsNoGesture)}, {"recover-from-never-save-android", flag_descriptions::kRecoverFromNeverSaveAndroidName, flag_descriptions::kRecoverFromNeverSaveAndroidDescription, kOsAndroid, @@ -8002,11 +7999,6 @@ #endif // BUILDFLAG(IS_CHROMEOS_ASH) #if BUILDFLAG(IS_ANDROID) - {"enable-chrome-management-page-android", - flag_descriptions::kChromeManagementPageAndroidName, - flag_descriptions::kChromeManagementPageAndroidDescription, kOsAndroid, - FEATURE_VALUE_TYPE(policy::features::kChromeManagementPageAndroid)}, - {"context-menu-popup-style", flag_descriptions::kContextMenuPopupStyleName, flag_descriptions::kContextMenuPopupStyleDescription, kOsAndroid, FEATURE_VALUE_TYPE(chrome::android::kContextMenuPopupStyle)},
diff --git a/chrome/browser/android/examples/custom_tabs_client/BUILD.gn b/chrome/browser/android/examples/custom_tabs_client/BUILD.gn index 009a5a3..9d4a7664 100644 --- a/chrome/browser/android/examples/custom_tabs_client/BUILD.gn +++ b/chrome/browser/android/examples/custom_tabs_client/BUILD.gn
@@ -51,10 +51,7 @@ "src/res/values/strings.xml", ] android_manifest = "src/AndroidManifest.xml" - deps = [ - "//third_party/android_deps:android_support_v7_appcompat_java", - "//third_party/android_deps:material_design_java", - ] + deps = [ "//third_party/android_deps:material_design_java" ] } android_apk("custom_tabs_client_example_apk") { @@ -75,11 +72,9 @@ deps = [ ":chrome_tabs_client_example_apk_resources", - "//third_party/android_deps:android_support_v7_appcompat_java", "//third_party/android_deps:material_design_java", "//third_party/androidx:androidx_annotation_annotation_java", "//third_party/androidx:androidx_appcompat_appcompat_java", "//third_party/androidx:androidx_browser_browser_java", - "//third_party/androidx:androidx_lifecycle_lifecycle_common_java", ] }
diff --git a/chrome/browser/ash/crosapi/authentication_ash.cc b/chrome/browser/ash/crosapi/authentication_ash.cc index c38c45b..098ece16 100644 --- a/chrome/browser/ash/crosapi/authentication_ash.cc +++ b/chrome/browser/ash/crosapi/authentication_ash.cc
@@ -61,20 +61,21 @@ bool success, std::unique_ptr<TokenInfo> token_info, const std::string& error_message) { - mojom::CreateQuickUnlockPrivateTokenInfoResultPtr result_ptr = - mojom::CreateQuickUnlockPrivateTokenInfoResult::New(); + mojom::CreateQuickUnlockPrivateTokenInfoResultPtr result; if (success) { DCHECK(token_info); crosapi::mojom::QuickUnlockPrivateTokenInfoPtr out_token_info = crosapi::mojom::QuickUnlockPrivateTokenInfo::New(); out_token_info->token = token_info->token; out_token_info->lifetime_seconds = token_info->lifetime_seconds; - result_ptr->set_token_info(std::move(out_token_info)); + result = mojom::CreateQuickUnlockPrivateTokenInfoResult::NewTokenInfo( + std::move(out_token_info)); } else { DCHECK(!error_message.empty()); - result_ptr->set_error_message(error_message); + result = mojom::CreateQuickUnlockPrivateTokenInfoResult::NewErrorMessage( + error_message); } - std::move(callback).Run(std::move(result_ptr)); + std::move(callback).Run(std::move(result)); extended_authenticator->SetConsumer(nullptr); }
diff --git a/chrome/browser/ash/crosapi/keystore_service_ash.cc b/chrome/browser/ash/crosapi/keystore_service_ash.cc index 2cfb9bd..0d37650 100644 --- a/chrome/browser/ash/crosapi/keystore_service_ash.cc +++ b/chrome/browser/ash/crosapi/keystore_service_ash.cc
@@ -243,13 +243,15 @@ void* challenge_key_ptr, const ash::attestation::TpmChallengeKeyResult& result) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - crosapi::mojom::ChallengeAttestationOnlyKeystoreResultPtr result_ptr = - mojom::ChallengeAttestationOnlyKeystoreResult::New(); + crosapi::mojom::ChallengeAttestationOnlyKeystoreResultPtr result_ptr; if (result.IsSuccess()) { - result_ptr->set_challenge_response(std::vector<uint8_t>( - result.challenge_response.begin(), result.challenge_response.end())); + result_ptr = + mojom::ChallengeAttestationOnlyKeystoreResult::NewChallengeResponse( + std::vector<uint8_t>(result.challenge_response.begin(), + result.challenge_response.end())); } else { - result_ptr->set_error_message(result.GetErrorMessage()); + result_ptr = mojom::ChallengeAttestationOnlyKeystoreResult::NewErrorMessage( + result.GetErrorMessage()); } std::move(callback).Run(std::move(result_ptr)); @@ -317,12 +319,13 @@ void* challenge_key_ptr, const ash::attestation::TpmChallengeKeyResult& result) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - crosapi::mojom::DEPRECATED_KeystoreStringResultPtr result_ptr = - mojom::DEPRECATED_KeystoreStringResult::New(); + crosapi::mojom::DEPRECATED_KeystoreStringResultPtr result_ptr; if (result.IsSuccess()) { - result_ptr->set_challenge_response(result.challenge_response); + result_ptr = mojom::DEPRECATED_KeystoreStringResult::NewChallengeResponse( + result.challenge_response); } else { - result_ptr->set_error_message(result.GetErrorMessage()); + result_ptr = mojom::DEPRECATED_KeystoreStringResult::NewErrorMessage( + result.GetErrorMessage()); } std::move(callback).Run(std::move(result_ptr)); @@ -354,7 +357,7 @@ chromeos::platform_keys::Status status) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - mojom::GetKeyStoresResultPtr result_ptr = mojom::GetKeyStoresResult::New(); + mojom::GetKeyStoresResultPtr result_ptr; if (status == chromeos::platform_keys::Status::kSuccess) { std::vector<mojom::KeystoreType> key_stores; @@ -368,9 +371,9 @@ break; } } - result_ptr->set_key_stores(std::move(key_stores)); + result_ptr = mojom::GetKeyStoresResult::NewKeyStores(std::move(key_stores)); } else { - result_ptr->set_error( + result_ptr = mojom::GetKeyStoresResult::NewError( chromeos::platform_keys::StatusToKeystoreError(status)); } @@ -395,8 +398,7 @@ chromeos::platform_keys::Status status) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - mojom::DEPRECATED_GetKeyStoresResultPtr result_ptr = - mojom::DEPRECATED_GetKeyStoresResult::New(); + mojom::DEPRECATED_GetKeyStoresResultPtr result_ptr; if (status == chromeos::platform_keys::Status::kSuccess) { std::vector<mojom::KeystoreType> key_stores; @@ -410,9 +412,10 @@ break; } } - result_ptr->set_key_stores(std::move(key_stores)); + result_ptr = mojom::DEPRECATED_GetKeyStoresResult::NewKeyStores( + std::move(key_stores)); } else { - result_ptr->set_error_message( + result_ptr = mojom::DEPRECATED_GetKeyStoresResult::NewErrorMessage( chromeos::platform_keys::StatusToString(status)); } @@ -445,8 +448,7 @@ chromeos::platform_keys::Status status) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - mojom::KeystoreSelectClientCertificatesResultPtr result_ptr = - mojom::KeystoreSelectClientCertificatesResult::New(); + mojom::KeystoreSelectClientCertificatesResultPtr result_ptr; if (status == chromeos::platform_keys::Status::kSuccess) { std::vector<std::vector<uint8_t>> output; @@ -457,9 +459,10 @@ data, data + CRYPTO_BUFFER_len(der_buffer)); output.push_back(std::move(der_x509_certificate)); } - result_ptr->set_certificates(std::move(output)); + result_ptr = mojom::KeystoreSelectClientCertificatesResult::NewCertificates( + std::move(output)); } else { - result_ptr->set_error( + result_ptr = mojom::KeystoreSelectClientCertificatesResult::NewError( chromeos::platform_keys::StatusToKeystoreError(status)); } @@ -491,8 +494,7 @@ chromeos::platform_keys::Status status) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - mojom::GetCertificatesResultPtr result_ptr = - mojom::GetCertificatesResult::New(); + mojom::GetCertificatesResultPtr result_ptr; if (status == chromeos::platform_keys::Status::kSuccess) { std::vector<std::vector<uint8_t>> output; @@ -503,9 +505,10 @@ data, data + CRYPTO_BUFFER_len(der_buffer)); output.push_back(std::move(der_x509_certificate)); } - result_ptr->set_certificates(std::move(output)); + result_ptr = + mojom::GetCertificatesResult::NewCertificates(std::move(output)); } else { - result_ptr->set_error( + result_ptr = mojom::GetCertificatesResult::NewError( chromeos::platform_keys::StatusToKeystoreError(status)); } @@ -540,8 +543,7 @@ chromeos::platform_keys::Status status) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - mojom::DEPRECATED_GetCertificatesResultPtr result_ptr = - mojom::DEPRECATED_GetCertificatesResult::New(); + mojom::DEPRECATED_GetCertificatesResultPtr result_ptr; if (status == chromeos::platform_keys::Status::kSuccess) { std::vector<std::vector<uint8_t>> output; @@ -552,9 +554,10 @@ data, data + CRYPTO_BUFFER_len(der_buffer)); output.push_back(std::move(der_x509_certificate)); } - result_ptr->set_certificates(std::move(output)); + result_ptr = mojom::DEPRECATED_GetCertificatesResult::NewCertificates( + std::move(output)); } else { - result_ptr->set_error_message( + result_ptr = mojom::DEPRECATED_GetCertificatesResult::NewErrorMessage( chromeos::platform_keys::StatusToString(status)); } @@ -729,7 +732,7 @@ chromeos::platform_keys::GetPublicKeyAndAlgorithm(certificate, name.value()); - mojom::GetPublicKeyResultPtr result_ptr = mojom::GetPublicKeyResult::New(); + mojom::GetPublicKeyResultPtr result_ptr; if (output.status == chromeos::platform_keys::Status::kSuccess) { absl::optional<crosapi::mojom::KeystoreSigningAlgorithmPtr> signing_algorithm = @@ -741,9 +744,10 @@ success_result_ptr->public_key = std::move(output.public_key); success_result_ptr->algorithm_properties = std::move(signing_algorithm.value()); - result_ptr->set_success_result(std::move(success_result_ptr)); + result_ptr = mojom::GetPublicKeyResult::NewSuccessResult( + std::move(success_result_ptr)); } else { - result_ptr->set_error( + result_ptr = mojom::GetPublicKeyResult::NewError( crosapi::mojom::KeystoreError::kUnsupportedAlgorithmType); } } else { @@ -775,8 +779,7 @@ chromeos::platform_keys::GetPublicKeyAndAlgorithm(certificate, name.value()); - mojom::DEPRECATED_GetPublicKeyResultPtr result_ptr = - mojom::DEPRECATED_GetPublicKeyResult::New(); + mojom::DEPRECATED_GetPublicKeyResultPtr result_ptr; if (output.status == chromeos::platform_keys::Status::kSuccess) { absl::optional<crosapi::mojom::KeystoreSigningAlgorithmPtr> signing_algorithm = @@ -788,12 +791,14 @@ success_result_ptr->public_key = std::move(output.public_key); success_result_ptr->algorithm_properties = std::move(signing_algorithm.value()); - result_ptr->set_success_result(std::move(success_result_ptr)); + result_ptr = mojom::DEPRECATED_GetPublicKeyResult::NewSuccessResult( + std::move(success_result_ptr)); } else { - result_ptr->set_error_message(kUnsupportedAlgorithmType); + result_ptr = mojom::DEPRECATED_GetPublicKeyResult::NewErrorMessage( + kUnsupportedAlgorithmType); } } else { - result_ptr->set_error_message( + result_ptr = mojom::DEPRECATED_GetPublicKeyResult::NewErrorMessage( chromeos::platform_keys::StatusToString(output.status)); } std::move(callback).Run(std::move(result_ptr)); @@ -860,14 +865,14 @@ const std::string& public_key, absl::optional<crosapi::mojom::KeystoreError> error) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - crosapi::mojom::DEPRECATED_ExtensionKeystoreBinaryResultPtr result_ptr = - mojom::DEPRECATED_ExtensionKeystoreBinaryResult::New(); + crosapi::mojom::DEPRECATED_ExtensionKeystoreBinaryResultPtr result_ptr; if (!error) { - result_ptr->set_blob( + result_ptr = mojom::DEPRECATED_ExtensionKeystoreBinaryResult::NewBlob( std::vector<uint8_t>(public_key.begin(), public_key.end())); } else { - result_ptr->set_error_message( - chromeos::platform_keys::KeystoreErrorToString(error.value())); + result_ptr = + mojom::DEPRECATED_ExtensionKeystoreBinaryResult::NewErrorMessage( + chromeos::platform_keys::KeystoreErrorToString(error.value())); } std::move(callback).Run(std::move(result_ptr)); } @@ -1013,13 +1018,12 @@ const std::string& public_key, chromeos::platform_keys::Status status) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - crosapi::mojom::KeystoreBinaryResultPtr result_ptr = - mojom::KeystoreBinaryResult::New(); + crosapi::mojom::KeystoreBinaryResultPtr result_ptr; if (status == chromeos::platform_keys::Status::kSuccess) { - result_ptr->set_blob( + result_ptr = mojom::KeystoreBinaryResult::NewBlob( std::vector<uint8_t>(public_key.begin(), public_key.end())); } else { - result_ptr->set_error( + result_ptr = mojom::KeystoreBinaryResult::NewError( chromeos::platform_keys::StatusToKeystoreError(status)); } std::move(callback).Run(std::move(result_ptr)); @@ -1141,8 +1145,7 @@ DCHECK_CURRENTLY_ON(content::BrowserThread::UI); using KeyTag = crosapi::mojom::KeyTag; - crosapi::mojom::GetKeyTagsResultPtr result_ptr = - mojom::GetKeyTagsResult::New(); + crosapi::mojom::GetKeyTagsResultPtr result_ptr; if (status == chromeos::platform_keys::Status::kSuccess) { DCHECK(corporate.has_value()); @@ -1153,9 +1156,9 @@ if (corporate.value()) { tags |= static_cast<uint64_t>(KeyTag::kCorporate); } - result_ptr->set_tags(tags); + result_ptr = crosapi::mojom::GetKeyTagsResult::NewTags(tags); } else { - result_ptr->set_error( + result_ptr = crosapi::mojom::GetKeyTagsResult::NewError( chromeos::platform_keys::StatusToKeystoreError(status)); }
diff --git a/chrome/browser/ash/crosapi/login_screen_storage_ash.cc b/chrome/browser/ash/crosapi/login_screen_storage_ash.cc index 08c0c67..03e6db3 100644 --- a/chrome/browser/ash/crosapi/login_screen_storage_ash.cc +++ b/chrome/browser/ash/crosapi/login_screen_storage_ash.cc
@@ -82,14 +82,13 @@ void LoginScreenStorageAsh::OnRetrieved(RetrieveCallback callback, absl::optional<std::string> data, absl::optional<std::string> error) { - mojom::LoginScreenStorageRetrieveResultPtr result_ptr = - mojom::LoginScreenStorageRetrieveResult::New(); + mojom::LoginScreenStorageRetrieveResultPtr result; if (error) { - result_ptr->set_error_message(*error); + result = mojom::LoginScreenStorageRetrieveResult::NewErrorMessage(*error); } else if (data) { - result_ptr->set_data(*data); + result = mojom::LoginScreenStorageRetrieveResult::NewData(*data); } - std::move(callback).Run(std::move(result_ptr)); + std::move(callback).Run(std::move(result)); } } // namespace crosapi
diff --git a/chrome/browser/ash/crosapi/login_screen_storage_ash_unittest.cc b/chrome/browser/ash/crosapi/login_screen_storage_ash_unittest.cc index 7d6ba25b..ff51752 100644 --- a/chrome/browser/ash/crosapi/login_screen_storage_ash_unittest.cc +++ b/chrome/browser/ash/crosapi/login_screen_storage_ash_unittest.cc
@@ -222,8 +222,7 @@ .WillOnce(WithArgs<1>(Invoke(LoginScreenStorageRetrieveSuccess))); mojom::LoginScreenStorageRetrieveResultPtr expected_result_ptr = - mojom::LoginScreenStorageRetrieveResult::New(); - expected_result_ptr->set_data(kData); + mojom::LoginScreenStorageRetrieveResult::NewData(kData); base::RunLoop run_loop; login_screen_storage_remote_->Retrieve( @@ -237,8 +236,7 @@ .WillOnce(WithArgs<1>(Invoke(LoginScreenStorageRetrieveError))); mojom::LoginScreenStorageRetrieveResultPtr expected_result_ptr = - mojom::LoginScreenStorageRetrieveResult::New(); - expected_result_ptr->set_error_message(kError); + mojom::LoginScreenStorageRetrieveResult::NewErrorMessage(kError); base::RunLoop run_loop; login_screen_storage_remote_->Retrieve(
diff --git a/chrome/browser/ash/crosapi/login_state_ash_unittest.cc b/chrome/browser/ash/crosapi/login_state_ash_unittest.cc index c0873a7..837687f 100644 --- a/chrome/browser/ash/crosapi/login_state_ash_unittest.cc +++ b/chrome/browser/ash/crosapi/login_state_ash_unittest.cc
@@ -90,8 +90,7 @@ session_manager_->SetSessionState(test.session_state); mojom::GetSessionStateResultPtr expected_result_ptr = - mojom::GetSessionStateResult::New(); - expected_result_ptr->set_session_state(test.expected); + mojom::GetSessionStateResult::NewSessionState(test.expected); base::RunLoop run_loop; login_state_remote_->GetSessionState(
diff --git a/chrome/browser/ash/crosapi/network_settings_translation_unittest.cc b/chrome/browser/ash/crosapi/network_settings_translation_unittest.cc index 0776f47..55101de 100644 --- a/chrome/browser/ash/crosapi/network_settings_translation_unittest.cc +++ b/chrome/browser/ash/crosapi/network_settings_translation_unittest.cc
@@ -118,11 +118,8 @@ TEST(NetworkSettingsTranslationTest, CrosapiProxyToProxyConfigDirect) { crosapi::mojom::ProxyConfigPtr ptr = crosapi::mojom::ProxyConfig::New(); - crosapi::mojom::ProxySettingsPtr proxy = crosapi::mojom::ProxySettings::New(); - crosapi::mojom::ProxySettingsDirectPtr direct = - crosapi::mojom::ProxySettingsDirect::New(); - proxy->set_direct(std::move(direct)); - ptr->proxy_settings = std::move(proxy); + ptr->proxy_settings = crosapi::mojom::ProxySettings::NewDirect( + crosapi::mojom::ProxySettingsDirect::New()); EXPECT_EQ(CrosapiProxyToProxyConfig(std::move(ptr)).GetDictionary(), ProxyConfigDictionary::CreateDirect()); @@ -130,12 +127,10 @@ TEST(NetworkSettingsTranslationTest, CrosapiProxyToProxyConfigWpad) { crosapi::mojom::ProxyConfigPtr ptr = crosapi::mojom::ProxyConfig::New(); - crosapi::mojom::ProxySettingsPtr proxy = crosapi::mojom::ProxySettings::New(); crosapi::mojom::ProxySettingsWpadPtr wpad = crosapi::mojom::ProxySettingsWpad::New(); wpad->pac_url = GURL("pac.pac"); - proxy->set_wpad(std::move(wpad)); - ptr->proxy_settings = std::move(proxy); + ptr->proxy_settings = crosapi::mojom::ProxySettings::NewWpad(std::move(wpad)); EXPECT_EQ(CrosapiProxyToProxyConfig(std::move(ptr)).GetDictionary(), ProxyConfigDictionary::CreateAutoDetect()); @@ -143,26 +138,22 @@ TEST(NetworkSettingsTranslationTest, CrosapiProxyToProxyConfigPac) { crosapi::mojom::ProxyConfigPtr ptr = crosapi::mojom::ProxyConfig::New(); - crosapi::mojom::ProxySettingsPtr proxy = crosapi::mojom::ProxySettings::New(); crosapi::mojom::ProxySettingsPacPtr pac = crosapi::mojom::ProxySettingsPac::New(); pac->pac_url = GURL(kPacUrl); pac->pac_mandatory = true; - proxy->set_pac(pac.Clone()); - ptr->proxy_settings = proxy.Clone(); + ptr->proxy_settings = crosapi::mojom::ProxySettings::NewPac(pac.Clone()); EXPECT_EQ(CrosapiProxyToProxyConfig(ptr.Clone()).GetDictionary(), GetPacProxyConfig(kPacUrl, true)); pac->pac_mandatory = false; - proxy->set_pac(pac.Clone()); - ptr->proxy_settings = std::move(proxy); + ptr->proxy_settings = crosapi::mojom::ProxySettings::NewPac(pac.Clone()); EXPECT_EQ(CrosapiProxyToProxyConfig(std::move(ptr)).GetDictionary(), GetPacProxyConfig(kPacUrl, false)); } TEST(NetworkSettingsTranslationTest, CrosapiProxyToProxyConfigManual) { crosapi::mojom::ProxyConfigPtr ptr = crosapi::mojom::ProxyConfig::New(); - crosapi::mojom::ProxySettingsPtr proxy = crosapi::mojom::ProxySettings::New(); crosapi::mojom::ProxySettingsManualPtr manual = crosapi::mojom::ProxySettingsManual::New(); crosapi::mojom::ProxyLocationPtr location = @@ -180,8 +171,8 @@ location->port = 82; manual->socks_proxies.push_back(std::move(location)); manual->exclude_domains = {"localhost", "google.com"}; - proxy->set_manual(std::move(manual)); - ptr->proxy_settings = std::move(proxy); + ptr->proxy_settings = + crosapi::mojom::ProxySettings::NewManual(std::move(manual)); EXPECT_EQ(CrosapiProxyToProxyConfig(std::move(ptr)).GetDictionary(), GetManualProxyConfig("http=proxy1:80;http=proxy2:80;https=secure_" "proxy:81;socks=socks_proxy:82",
diff --git a/chrome/browser/ash/crosapi/networking_attributes_ash.cc b/chrome/browser/ash/crosapi/networking_attributes_ash.cc index b5c5389..9292b2a 100644 --- a/chrome/browser/ash/crosapi/networking_attributes_ash.cc +++ b/chrome/browser/ash/crosapi/networking_attributes_ash.cc
@@ -77,10 +77,8 @@ details->ipv6_address = ipv6_address; } - mojom::GetNetworkDetailsResultPtr result_ptr = - mojom::GetNetworkDetailsResult::New(); - result_ptr->set_network_details(std::move(details)); - std::move(callback).Run(std::move(result_ptr)); + std::move(callback).Run( + mojom::GetNetworkDetailsResult::NewNetworkDetails(std::move(details))); } } // namespace crosapi
diff --git a/chrome/browser/ash/crosapi/networking_attributes_ash_unittest.cc b/chrome/browser/ash/crosapi/networking_attributes_ash_unittest.cc index d9d69e6..0ea9467 100644 --- a/chrome/browser/ash/crosapi/networking_attributes_ash_unittest.cc +++ b/chrome/browser/ash/crosapi/networking_attributes_ash_unittest.cc
@@ -205,8 +205,7 @@ AddUser(/*is_affiliated=*/false); mojom::GetNetworkDetailsResultPtr expected_result_ptr = - mojom::GetNetworkDetailsResult::New(); - expected_result_ptr->set_error_message(kErrorUserNotAffiliated); + mojom::GetNetworkDetailsResult::NewErrorMessage(kErrorUserNotAffiliated); base::RunLoop run_loop; networking_attributes_remote_->GetNetworkDetails( @@ -219,8 +218,8 @@ AddUser(); mojom::GetNetworkDetailsResultPtr expected_result_ptr = - mojom::GetNetworkDetailsResult::New(); - expected_result_ptr->set_error_message(kErrorNetworkNotConnected); + mojom::GetNetworkDetailsResult::NewErrorMessage( + kErrorNetworkNotConnected); base::RunLoop run_loop; networking_attributes_remote_->GetNetworkDetails( @@ -244,8 +243,8 @@ expected_network_details->ipv4_address = ipv4_expected; expected_network_details->ipv6_address = ipv6_expected; mojom::GetNetworkDetailsResultPtr expected_result_ptr = - mojom::GetNetworkDetailsResult::New(); - expected_result_ptr->set_network_details(std::move(expected_network_details)); + mojom::GetNetworkDetailsResult::NewNetworkDetails( + std::move(expected_network_details)); base::RunLoop run_loop; networking_attributes_remote_->GetNetworkDetails(
diff --git a/chrome/browser/ash/crosapi/translate_proxy_config_to_crosapi.cc b/chrome/browser/ash/crosapi/translate_proxy_config_to_crosapi.cc index 67dc3def..dbed595 100644 --- a/chrome/browser/ash/crosapi/translate_proxy_config_to_crosapi.cc +++ b/chrome/browser/ash/crosapi/translate_proxy_config_to_crosapi.cc
@@ -95,19 +95,19 @@ GURL dhcp_wpad_url) { crosapi::mojom::ProxyConfigPtr proxy_config = crosapi::mojom::ProxyConfig::New(); - crosapi::mojom::ProxySettingsPtr proxy = crosapi::mojom::ProxySettings::New(); crosapi::mojom::ProxySettingsDirectPtr direct = crosapi::mojom::ProxySettingsDirect::New(); ProxyPrefs::ProxyMode mode; if (!proxy_dict || !proxy_dict->GetMode(&mode)) { - proxy->set_direct(std::move(direct)); - proxy_config->proxy_settings = std::move(proxy); + proxy_config->proxy_settings = + crosapi::mojom::ProxySettings::NewDirect(std::move(direct)); return proxy_config; } switch (mode) { case ProxyPrefs::MODE_DIRECT: - proxy->set_direct(std::move(direct)); + proxy_config->proxy_settings = + crosapi::mojom::ProxySettings::NewDirect(std::move(direct)); break; case ProxyPrefs::MODE_AUTO_DETECT: { crosapi::mojom::ProxySettingsWpadPtr wpad = @@ -119,13 +119,15 @@ // Fallback to WPAD via DNS. wpad->pac_url = GURL("http://wpad/wpad.dat"); } - proxy->set_wpad(std::move(wpad)); + proxy_config->proxy_settings = + crosapi::mojom::ProxySettings::NewWpad(std::move(wpad)); break; } case ProxyPrefs::MODE_PAC_SCRIPT: { std::string pac_url; if (!proxy_dict->GetPacUrl(&pac_url)) { - proxy->set_direct(std::move(direct)); + proxy_config->proxy_settings = + crosapi::mojom::ProxySettings::NewDirect(std::move(direct)); LOG(ERROR) << "No pac URL for pac_script proxy mode."; break; } @@ -136,13 +138,15 @@ crosapi::mojom::ProxySettingsPac::New(); pac->pac_url = GURL(pac_url); pac->pac_mandatory = pac_mandatory; - proxy->set_pac(std::move(pac)); + proxy_config->proxy_settings = + crosapi::mojom::ProxySettings::NewPac(std::move(pac)); break; } case ProxyPrefs::MODE_FIXED_SERVERS: { crosapi::mojom::ProxySettingsManualPtr manual = TranslateManualProxySettings(proxy_dict); - proxy->set_manual(std::move(manual)); + proxy_config->proxy_settings = + crosapi::mojom::ProxySettings::NewManual(std::move(manual)); break; } case ProxyPrefs::MODE_SYSTEM: @@ -153,10 +157,10 @@ break; default: LOG(ERROR) << "Incorrect proxy mode."; - proxy->set_direct(std::move(direct)); + proxy_config->proxy_settings = + crosapi::mojom::ProxySettings::NewDirect(std::move(direct)); } - proxy_config->proxy_settings = std::move(proxy); return proxy_config; }
diff --git a/chrome/browser/ash/crosapi/video_frame_handler_ash.cc b/chrome/browser/ash/crosapi/video_frame_handler_ash.cc index 5e2f64c..ebc53223 100644 --- a/chrome/browser/ash/crosapi/video_frame_handler_ash.cc +++ b/chrome/browser/ash/crosapi/video_frame_handler_ash.cc
@@ -77,23 +77,19 @@ crosapi_gpu_handle->stride = buffer_handle.stride; if (buffer_handle.type == gfx::GpuMemoryBufferType::SHARED_MEMORY_BUFFER) { - auto crosapi_platform_handle = - crosapi::mojom::GpuMemoryBufferPlatformHandle::New(); - crosapi_platform_handle->set_shared_memory_handle( - std::move(buffer_handle.region)); - crosapi_gpu_handle->platform_handle = std::move(crosapi_platform_handle); + crosapi_gpu_handle->platform_handle = + crosapi::mojom::GpuMemoryBufferPlatformHandle::NewSharedMemoryHandle( + std::move(buffer_handle.region)); } else if (buffer_handle.type == gfx::GpuMemoryBufferType::NATIVE_PIXMAP) { - auto crosapi_platform_handle = - crosapi::mojom::GpuMemoryBufferPlatformHandle::New(); auto crosapi_native_pixmap_handle = crosapi::mojom::NativePixmapHandle::New(); crosapi_native_pixmap_handle->planes = std::move(buffer_handle.native_pixmap_handle.planes); crosapi_native_pixmap_handle->modifier = buffer_handle.native_pixmap_handle.modifier; - crosapi_platform_handle->set_native_pixmap_handle( - std::move(crosapi_native_pixmap_handle)); - crosapi_gpu_handle->platform_handle = std::move(crosapi_platform_handle); + crosapi_gpu_handle->platform_handle = + crosapi::mojom::GpuMemoryBufferPlatformHandle::NewNativePixmapHandle( + std::move(crosapi_native_pixmap_handle)); } return crosapi_gpu_handle; }
diff --git a/chrome/browser/ash/crostini/crostini_browser_test_util.cc b/chrome/browser/ash/crostini/crostini_browser_test_util.cc index 7ef5397..0946f4a 100644 --- a/chrome/browser/ash/crostini/crostini_browser_test_util.cc +++ b/chrome/browser/ash/crostini/crostini_browser_test_util.cc
@@ -11,6 +11,8 @@ #include "chrome/browser/ash/crostini/crostini_pref_names.h" #include "chrome/browser/ash/crostini/crostini_util.h" #include "chrome/browser/ash/crostini/fake_crostini_features.h" +#include "chrome/browser/ash/guest_os/public/guest_os_service.h" +#include "chrome/browser/ash/guest_os/public/guest_os_wayland_server.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/chrome_browser_main.h" #include "chrome/browser/chrome_browser_main_extra_parts.h" @@ -132,6 +134,10 @@ void CrostiniBrowserTestBase::SetUpOnMainThread() { browser()->profile()->GetPrefs()->SetBoolean( crostini::prefs::kCrostiniEnabled, true); + + guest_os::GuestOsService::GetForProfile(browser()->profile()) + ->WaylandServer() + ->OverrideServerForTesting(vm_tools::launch::TERMINA, nullptr, {}); } void CrostiniBrowserTestBase::SetConnectionType(
diff --git a/chrome/browser/ash/crostini/crostini_capabilities.cc b/chrome/browser/ash/crostini/crostini_capabilities.cc new file mode 100644 index 0000000..27d8862 --- /dev/null +++ b/chrome/browser/ash/crostini/crostini_capabilities.cc
@@ -0,0 +1,34 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ash/crostini/crostini_capabilities.h" + +#include "base/logging.h" +#include "base/memory/ptr_util.h" +#include "chrome/browser/ash/crostini/crostini_features.h" +#include "third_party/cros_system_api/constants/vm_tools.h" + +namespace crostini { + +void CrostiniCapabilities::Build( + Profile* profile, + base::OnceCallback<void(std::unique_ptr<guest_os::GuestOsCapabilities>)> + callback) { + std::string reason; + if (!CrostiniFeatures::Get()->IsAllowedNow(profile, &reason)) { + LOG(WARNING) << "Crostini is not allowed: " << reason; + std::move(callback).Run(nullptr); + return; + } + // WrapUnique is used because the constructor is private. + std::move(callback).Run(base::WrapUnique(new CrostiniCapabilities())); +} + +CrostiniCapabilities::~CrostiniCapabilities() = default; + +std::string CrostiniCapabilities::GetSecurityContext() const { + return vm_tools::kConciergeSecurityContext; +} + +} // namespace crostini
diff --git a/chrome/browser/ash/crostini/crostini_capabilities.h b/chrome/browser/ash/crostini/crostini_capabilities.h new file mode 100644 index 0000000..f1c2d0a --- /dev/null +++ b/chrome/browser/ash/crostini/crostini_capabilities.h
@@ -0,0 +1,35 @@ +// 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_CROSTINI_CROSTINI_CAPABILITIES_H_ +#define CHROME_BROWSER_ASH_CROSTINI_CROSTINI_CAPABILITIES_H_ + +#include "base/callback_forward.h" +#include "chrome/browser/ash/guest_os/guest_os_capabilities.h" + +class Profile; + +namespace crostini { + +class CrostiniCapabilities : public guest_os::GuestOsCapabilities { + public: + // Builds an instance of the capabilities for the given |profile|. + static void Build( + Profile* profile, + base::OnceCallback<void(std::unique_ptr<guest_os::GuestOsCapabilities>)> + callback); + + ~CrostiniCapabilities() override; + + // exo::Capabilities overrides: + std::string GetSecurityContext() const override; + + private: + // Private constructor to force use of Build(). + CrostiniCapabilities() = default; +}; + +} // namespace crostini + +#endif // CHROME_BROWSER_ASH_CROSTINI_CROSTINI_CAPABILITIES_H_
diff --git a/chrome/browser/ash/crostini/crostini_manager.cc b/chrome/browser/ash/crostini/crostini_manager.cc index 4d41b57..4cd1440 100644 --- a/chrome/browser/ash/crostini/crostini_manager.cc +++ b/chrome/browser/ash/crostini/crostini_manager.cc
@@ -45,6 +45,9 @@ #include "chrome/browser/ash/file_manager/volume_manager.h" #include "chrome/browser/ash/guest_os/guest_os_share_path.h" #include "chrome/browser/ash/guest_os/guest_os_stability_monitor.h" +#include "chrome/browser/ash/guest_os/public/guest_os_service.h" +#include "chrome/browser/ash/guest_os/public/guest_os_service_factory.h" +#include "chrome/browser/ash/guest_os/public/guest_os_wayland_server.h" #include "chrome/browser/ash/policy/handlers/powerwash_requirements_checker.h" #include "chrome/browser/ash/scheduler_configuration_manager.h" #include "chrome/browser/ash/usb/cros_usb_detector.h" @@ -261,6 +264,7 @@ const base::FilePath& result_path); // chromeos::SchedulerConfigurationManagerBase::Observer: void OnConfigurationSet(bool success, size_t num_cores_disabled) override; + void OnWaylandServerCreated(guest_os::GuestOsWaylandServer::Result result); void StartTerminaVmFinished(bool success); void SharePathsFinished(bool success, const std::string& failure_reason); void StartLxdFinished(CrostiniResult result); @@ -314,6 +318,7 @@ CrostiniManager::RestartId restart_id_; bool is_running_ = false; bool did_successful_full_restart_ = false; + size_t num_cores_disabled_ = 0; mojom::InstallerState stage_ = mojom::InstallerState::kStart; CrostiniResult result_ = CrostiniResult::NEVER_FINISHED; @@ -666,9 +671,27 @@ g_browser_process->platform_part() ->scheduler_configuration_manager() ->RemoveObserver(this); + num_cores_disabled_ = num_cores_disabled; + + guest_os::GuestOsServiceFactory::GetForProfile(profile_) + ->WaylandServer() + ->Get(vm_tools::launch::TERMINA, + base::BindOnce(&CrostiniRestarter::OnWaylandServerCreated, + weak_ptr_factory_.GetWeakPtr())); +} + +void CrostiniManager::CrostiniRestarter::OnWaylandServerCreated( + guest_os::GuestOsWaylandServer::Result result) { + if (!result) { + LOG(ERROR) << "Wayland server creation failed: " + << static_cast<int>(result.Error()); + FinishRestart(CrostiniResult::WAYLAND_SERVER_CREATION_FAILED); + return; + } StartStage(mojom::InstallerState::kStartTerminaVm); crostini_manager_->StartTerminaVm( - container_id_.vm_name, disk_path_, num_cores_disabled, + container_id_.vm_name, disk_path_, result.Value()->server_path(), + num_cores_disabled_, base::BindOnce(&CrostiniRestarter::StartTerminaVmFinished, weak_ptr_factory_.GetWeakPtr())); } @@ -1242,6 +1265,7 @@ void CrostiniManager::StartTerminaVm(std::string name, const base::FilePath& disk_path, + const base::FilePath& wayland_path, size_t num_cores_disabled, BoolCallback callback) { if (name.empty()) { @@ -1286,6 +1310,7 @@ request.set_name(std::move(name)); request.set_start_termina(true); request.set_owner_id(owner_id_); + request.mutable_vm()->set_wayland_server(wayland_path.AsUTF8Unsafe()); if (base::FeatureList::IsEnabled(chromeos::features::kCrostiniGpuSupport)) request.set_enable_gpu(true); if (profile_->GetPrefs()->GetBoolean(prefs::kCrostiniMicAllowed) &&
diff --git a/chrome/browser/ash/crostini/crostini_manager.h b/chrome/browser/ash/crostini/crostini_manager.h index c06456f0..aefe8a3 100644 --- a/chrome/browser/ash/crostini/crostini_manager.h +++ b/chrome/browser/ash/crostini/crostini_manager.h
@@ -278,8 +278,11 @@ std::string name, // Path to the disk image on the host. const base::FilePath& disk_path, + // Path to the wayland server's socket, per go/secure-exo-ids. + const base::FilePath& wayland_path, // The number of logical CPU cores that are currently disabled. size_t num_cores_disabled, + // A callback to invoke with the result of the launch request. BoolCallback callback); // Checks the arguments for stopping a Termina VM. Stops the Termina VM via
diff --git a/chrome/browser/ash/crostini/crostini_manager_unittest.cc b/chrome/browser/ash/crostini/crostini_manager_unittest.cc index 7f469136..3ff80d1 100644 --- a/chrome/browser/ash/crostini/crostini_manager_unittest.cc +++ b/chrome/browser/ash/crostini/crostini_manager_unittest.cc
@@ -24,6 +24,8 @@ #include "chrome/browser/ash/crostini/crostini_types.mojom-shared.h" #include "chrome/browser/ash/crostini/crostini_util.h" #include "chrome/browser/ash/crostini/fake_crostini_features.h" +#include "chrome/browser/ash/guest_os/public/guest_os_service.h" +#include "chrome/browser/ash/guest_os/public/guest_os_wayland_server.h" #include "chrome/browser/ash/login/users/fake_chrome_user_manager.h" #include "chrome/browser/ash/policy/handlers/powerwash_requirements_checker.h" #include "chrome/browser/ash/settings/scoped_cros_settings_test_helper.h" @@ -245,6 +247,10 @@ g_browser_process->platform_part() ->InitializeSchedulerConfigurationManager(); + guest_os::GuestOsService::GetForProfile(profile()) + ->WaylandServer() + ->OverrideServerForTesting(vm_tools::launch::TERMINA, nullptr, {}); + chromeos::CryptohomeMiscClient::InitializeFake(); chromeos::FakeCryptohomeMiscClient::Get()->set_requires_powerwash(false); policy::PowerwashRequirementsChecker::InitializeSynchronouslyForTesting(); @@ -354,7 +360,7 @@ const base::FilePath& disk_path = base::FilePath("unused"); crostini_manager()->StartTerminaVm( - "", disk_path, 0, + "", disk_path, {}, 0, base::BindOnce(&ExpectFailure, run_loop()->QuitClosure())); run_loop()->Run(); EXPECT_EQ(fake_concierge_client_->start_termina_vm_call_count(), 0); @@ -367,7 +373,7 @@ false); crostini_manager()->StartTerminaVm( - kVmName, disk_path, 0, + kVmName, disk_path, {}, 0, base::BindOnce(&ExpectFailure, run_loop()->QuitClosure())); run_loop()->Run(); EXPECT_EQ(fake_concierge_client_->start_termina_vm_call_count(), 0); @@ -377,7 +383,7 @@ const base::FilePath& disk_path = base::FilePath(); crostini_manager()->StartTerminaVm( - kVmName, disk_path, 0, + kVmName, disk_path, {}, 0, base::BindOnce(&ExpectFailure, run_loop()->QuitClosure())); run_loop()->Run(); EXPECT_EQ(fake_concierge_client_->start_termina_vm_call_count(), 0); @@ -407,7 +413,7 @@ NotificationDisplayServiceTester notification_service(profile()); crostini_manager()->StartTerminaVm( - kVmName, disk_path, 0, + kVmName, disk_path, {}, 0, base::BindOnce(&ExpectFailure, run_loop()->QuitClosure())); run_loop()->Run(); EXPECT_EQ(fake_concierge_client_->start_termina_vm_call_count(), 0); @@ -444,7 +450,7 @@ NotificationDisplayServiceTester notification_service(profile()); crostini_manager()->StartTerminaVm( - kVmName, disk_path, 0, + kVmName, disk_path, {}, 0, base::BindOnce(&ExpectFailure, run_loop()->QuitClosure())); run_loop()->Run(); EXPECT_EQ(fake_concierge_client_->start_termina_vm_call_count(), 0); @@ -465,7 +471,7 @@ EnsureTerminaInstalled(); crostini_manager()->StartTerminaVm( - kVmName, disk_path, 0, + kVmName, disk_path, {}, 0, base::BindOnce(&ExpectFailure, run_loop()->QuitClosure())); run_loop()->Run(); EXPECT_GE(fake_concierge_client_->start_termina_vm_call_count(), 1); @@ -485,7 +491,7 @@ EnsureTerminaInstalled(); crostini_manager()->StartTerminaVm( - kVmName, disk_path, 0, + kVmName, disk_path, {}, 0, base::BindOnce(&ExpectSuccess, run_loop()->QuitClosure())); run_loop()->Run(); EXPECT_GE(fake_concierge_client_->start_termina_vm_call_count(), 1); @@ -499,7 +505,7 @@ EnsureTerminaInstalled(); crostini_manager()->StartTerminaVm( - kVmName, disk_path, 0, + kVmName, disk_path, {}, 0, base::BindOnce(&ExpectSuccess, run_loop()->QuitClosure())); run_loop()->Run(); EXPECT_GE(fake_concierge_client_->start_termina_vm_call_count(), 1); @@ -518,7 +524,7 @@ EnsureTerminaInstalled(); crostini_manager()->StartTerminaVm( - ContainerId::GetDefault().vm_name, disk_path, 0, + ContainerId::GetDefault().vm_name, disk_path, {}, 0, base::BindOnce(&ExpectSuccess, run_loop()->QuitClosure())); run_loop()->Run(); @@ -540,7 +546,7 @@ EnsureTerminaInstalled(); crostini_manager()->StartTerminaVm( - ContainerId::GetDefault().vm_name, disk_path, 0, + ContainerId::GetDefault().vm_name, disk_path, {}, 0, base::BindOnce(&ExpectSuccess, run_loop()->QuitClosure())); run_loop()->Run(); @@ -556,7 +562,7 @@ // Start the Vm. EnsureTerminaInstalled(); crostini_manager()->StartTerminaVm( - kVmName, disk_path, 0, + kVmName, disk_path, {}, 0, base::BindOnce(&ExpectSuccess, run_loop()->QuitClosure())); // Check that the Vm start is not recorded until tremplin starts. @@ -1376,7 +1382,7 @@ base::RunLoop run_loop2; crostini_manager()->StartTerminaVm( - kVmName, disk_path, 0, + kVmName, disk_path, {}, 0, base::BindOnce(&ExpectSuccess, run_loop2.QuitClosure())); run_loop2.Run(); EXPECT_GE(fake_concierge_client_->start_termina_vm_call_count(), 1);
diff --git a/chrome/browser/ash/crostini/crostini_simple_types.h b/chrome/browser/ash/crostini/crostini_simple_types.h index 8459575..778887d1 100644 --- a/chrome/browser/ash/crostini/crostini_simple_types.h +++ b/chrome/browser/ash/crostini/crostini_simple_types.h
@@ -98,7 +98,8 @@ VSH_CONNECT_FAILED = 65, CONTAINER_STOP_FAILED = 66, CONTAINER_STOP_CANCELLED = 67, - kMaxValue = CONTAINER_STOP_CANCELLED, + WAYLAND_SERVER_CREATION_FAILED = 68, + kMaxValue = WAYLAND_SERVER_CREATION_FAILED, // When adding a new value, check you've followed the steps in the comment at // the top of this enum. };
diff --git a/chrome/browser/ash/crostini/crostini_test_helper.cc b/chrome/browser/ash/crostini/crostini_test_helper.cc index af368b9..bfea145a 100644 --- a/chrome/browser/ash/crostini/crostini_test_helper.cc +++ b/chrome/browser/ash/crostini/crostini_test_helper.cc
@@ -11,12 +11,15 @@ #include "chrome/browser/ash/crostini/crostini_pref_names.h" #include "chrome/browser/ash/guest_os/guest_os_registry_service.h" #include "chrome/browser/ash/guest_os/guest_os_registry_service_factory.h" +#include "chrome/browser/ash/guest_os/public/guest_os_service.h" +#include "chrome/browser/ash/guest_os/public/guest_os_wayland_server.h" #include "chrome/browser/ash/login/users/fake_chrome_user_manager.h" #include "chrome/browser/ash/profiles/profile_helper.h" #include "chrome/browser/profiles/profile.h" #include "chrome/common/chrome_features.h" #include "chrome/test/base/testing_profile.h" #include "chromeos/dbus/dbus_thread_manager.h" +#include "chromeos/dbus/vm_launch/launch.pb.h" #include "components/crx_file/id_util.h" #include "components/prefs/pref_service.h" #include "components/user_manager/scoped_user_manager.h" @@ -46,6 +49,10 @@ current_apps_.set_vm_name(kCrostiniDefaultVmName); current_apps_.set_container_name(kCrostiniDefaultContainerName); + + guest_os::GuestOsService::GetForProfile(profile_) + ->WaylandServer() + ->OverrideServerForTesting(vm_tools::launch::TERMINA, nullptr, {}); } CrostiniTestHelper::~CrostiniTestHelper() {
diff --git a/chrome/browser/ash/guest_os/guest_os_share_path_unittest.cc b/chrome/browser/ash/guest_os/guest_os_share_path_unittest.cc index 619c53a..9bfbaf7 100644 --- a/chrome/browser/ash/guest_os/guest_os_share_path_unittest.cc +++ b/chrome/browser/ash/guest_os/guest_os_share_path_unittest.cc
@@ -24,6 +24,8 @@ #include "chrome/browser/ash/file_manager/volume_manager_factory.h" #include "chrome/browser/ash/file_system_provider/service_factory.h" #include "chrome/browser/ash/guest_os/guest_os_pref_names.h" +#include "chrome/browser/ash/guest_os/public/guest_os_service.h" +#include "chrome/browser/ash/guest_os/public/guest_os_wayland_server.h" #include "chrome/browser/ash/login/users/fake_chrome_user_manager.h" #include "chrome/browser/component_updater/fake_cros_component_manager.h" #include "chrome/common/chrome_features.h" @@ -292,6 +294,11 @@ drivefs_ = base::FilePath("/media/fuse/drivefs-84675c855b63e12f384d45f033826980"); + // Setup for a fake wayland server (needed when CrostiniManager makes a VM). + guest_os::GuestOsService::GetForProfile(profile()) + ->WaylandServer() + ->OverrideServerForTesting(vm_tools::launch::TERMINA, nullptr, {}); + // Create 'vm-running' VM instance which is running. crostini::CrostiniManager::GetForProfile(profile())->AddRunningVmForTesting( "vm-running");
diff --git a/chrome/browser/ash/guest_os/infra/cached_callback.h b/chrome/browser/ash/guest_os/infra/cached_callback.h index f30ec60..b47b108 100644 --- a/chrome/browser/ash/guest_os/infra/cached_callback.h +++ b/chrome/browser/ash/guest_os/infra/cached_callback.h
@@ -79,6 +79,10 @@ return std::move(real); } + void CacheForTesting(std::unique_ptr<T> real) { + OnRealResultFound(RealResult(std::move(real))); + } + protected: using RealResult = borealis::Expected<std::unique_ptr<T>, E>;
diff --git a/chrome/browser/ash/guest_os/public/guest_os_wayland_server.cc b/chrome/browser/ash/guest_os/public/guest_os_wayland_server.cc index 5eeb9a3e..dbf9555 100644 --- a/chrome/browser/ash/guest_os/public/guest_os_wayland_server.cc +++ b/chrome/browser/ash/guest_os/public/guest_os_wayland_server.cc
@@ -11,6 +11,7 @@ #include "base/callback.h" #include "chrome/browser/ash/borealis/borealis_capabilities.h" #include "chrome/browser/ash/borealis/borealis_service.h" +#include "chrome/browser/ash/crostini/crostini_capabilities.h" #include "chrome/browser/ash/guest_os/guest_os_capabilities.h" #include "chrome/browser/ash/guest_os/infra/cached_callback.h" #include "chrome/browser/ash/guest_os/public/guest_os_service.h" @@ -78,11 +79,13 @@ base::WeakPtr<GuestOsCapabilities> cap_ptr, bool success, const base::FilePath& path) { - if (success) { - std::move(callback).Run(Success(cap_ptr, path)); + if (!success) { + std::move(callback).Run(Failure(ServerFailure::kFailedToSpawn)); return; } - std::move(callback).Run(Failure(ServerFailure::kFailedToSpawn)); + DCHECK(cap_ptr); + DCHECK(!path.empty()); + std::move(callback).Run(Success(cap_ptr, path)); } static void OnCapabilitiesCreated(RealCallback callback, @@ -108,12 +111,12 @@ GuestOsWaylandServer::ServerDetails::ServerDetails( base::WeakPtr<GuestOsCapabilities> capabilities, base::FilePath path) - : capabilities_(capabilities), server_path_(std::move(path)) { - DCHECK(capabilities_); - DCHECK(!server_path_.empty()); -} + : capabilities_(capabilities), server_path_(std::move(path)) {} GuestOsWaylandServer::ServerDetails::~ServerDetails() { + // In tests, this is used to avoid dealing with the real server controller. + if (server_path_.empty()) + return; GuestOsCapabilities::MaybeRemoveServer(capabilities_, server_path_); } @@ -139,6 +142,9 @@ capability_holders_[vm_tools::launch::BOREALIS] = std::make_unique<CapabilityHolder>(base::BindRepeating( &borealis::BorealisCapabilities::Build, profile_)); + capability_holders_[vm_tools::launch::TERMINA] = + std::make_unique<CapabilityHolder>(base::BindRepeating( + &crostini::CrostiniCapabilities::Build, profile_)); } GuestOsWaylandServer::~GuestOsWaylandServer() = default; @@ -159,4 +165,12 @@ capability_holders_[vm_type] = std::make_unique<CapabilityHolder>(factory); } +void GuestOsWaylandServer::OverrideServerForTesting( + vm_tools::launch::VmType vm_type, + base::WeakPtr<GuestOsCapabilities> capabilities, + base::FilePath path) { + capability_holders_[vm_type]->CacheForTesting( // IN-TEST + std::make_unique<ServerDetails>(capabilities, std::move(path))); +} + } // namespace guest_os
diff --git a/chrome/browser/ash/guest_os/public/guest_os_wayland_server.h b/chrome/browser/ash/guest_os/public/guest_os_wayland_server.h index e2da39d..d17d43ab 100644 --- a/chrome/browser/ash/guest_os/public/guest_os_wayland_server.h +++ b/chrome/browser/ash/guest_os/public/guest_os_wayland_server.h
@@ -91,6 +91,11 @@ void(base::OnceCallback<void(std::unique_ptr<GuestOsCapabilities>)>)> factory); + // Used in tests to skip actually trying to allocate a server socket via exo. + void OverrideServerForTesting(vm_tools::launch::VmType vm_type, + base::WeakPtr<GuestOsCapabilities> capabilities, + base::FilePath path); + private: class CapabilityHolder;
diff --git a/chrome/browser/ash/login/easy_unlock/easy_unlock_notification_controller.cc b/chrome/browser/ash/login/easy_unlock/easy_unlock_notification_controller.cc index 9e3c7079..1a2fd87 100644 --- a/chrome/browser/ash/login/easy_unlock/easy_unlock_notification_controller.cc +++ b/chrome/browser/ash/login/easy_unlock/easy_unlock_notification_controller.cc
@@ -4,15 +4,20 @@ #include "chrome/browser/ash/login/easy_unlock/easy_unlock_notification_controller.h" +#include "ash/components/proximity_auth/proximity_auth_pref_names.h" #include "ash/components/proximity_auth/screenlock_bridge.h" +#include "ash/constants/ash_features.h" #include "base/guid.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/notifications/notification_display_service.h" +#include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/settings_window_manager_chromeos.h" #include "chrome/browser/ui/webui/settings/chromeos/constants/routes.mojom.h" +#include "chrome/common/pref_names.h" #include "chrome/common/webui_url_constants.h" #include "chrome/grit/generated_resources.h" #include "chrome/grit/theme_resources.h" +#include "components/prefs/pref_service.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/resource/resource_bundle.h" #include "ui/chromeos/devicetype_utils.h" @@ -30,6 +35,9 @@ const char kEasyUnlockPairingChangeAppliedNotifierId[] = "easyunlock_notification_ids.pairing_change_applied"; +const char kSmartLockSignInRemovedNotifierId[] = + "easyunlock_notification_ids.sign_in_removed"; + // Convenience function for creating a Notification. std::unique_ptr<message_center::Notification> CreateNotification( const std::string& id, @@ -55,6 +63,39 @@ EasyUnlockNotificationController::~EasyUnlockNotificationController() {} +// static +bool EasyUnlockNotificationController::ShouldShowSignInRemovedNotification( + Profile* profile) { + if (!profile->GetPrefs()->GetBoolean( + proximity_auth::prefs::kProximityAuthIsChromeOSLoginEnabled)) + return false; + + if (!base::FeatureList::IsEnabled(ash::features::kSmartLockSignInRemoved)) + return false; + + if (profile->GetPrefs()->GetBoolean( + prefs::kHasSeenSmartLockSignInRemovedNotification)) + return false; + + return true; +} + +void EasyUnlockNotificationController::ShowSignInRemovedNotification() { + PrefService* pref_service = profile_->GetPrefs(); + pref_service->SetBoolean(prefs::kHasSeenSmartLockSignInRemovedNotification, + true); + + ShowNotification(CreateNotification( + kSmartLockSignInRemovedNotifierId, + l10n_util::GetStringUTF16( + IDS_SMART_LOCK_SIGN_IN_REMOVED_NOTIFICATION_TITLE), + l10n_util::GetStringUTF16( + IDS_SMART_LOCK_SIGN_IN_REMOVED_NOTIFICATION_MESSAGE), + ui::ImageModel(), {}, + new NotificationDelegate(kSmartLockSignInRemovedNotifierId, + weak_ptr_factory_.GetWeakPtr()))); +} + void EasyUnlockNotificationController::ShowChromebookAddedNotification() { message_center::RichNotificationData rich_notification_data; rich_notification_data.buttons.push_back( @@ -139,6 +180,11 @@ profile_, chromeos::settings::mojom::kSmartLockSubpagePath); } +void EasyUnlockNotificationController::LaunchMultiDeviceSettings() { + chrome::SettingsWindowManager::GetInstance()->ShowOSSettings( + profile_, chromeos::settings::mojom::kMultiDeviceFeaturesSubpagePath); +} + void EasyUnlockNotificationController::LockScreen() { proximity_auth::ScreenlockBridge::Get()->Lock(); } @@ -171,7 +217,13 @@ DCHECK_EQ(1, *button_index); } - notification_controller_->LaunchEasyUnlockSettings(); + // The kSmartLockSignInRemoved flag removes the easy unlock settings page, so + // check flag to determine which route should be launched. + if (base::FeatureList::IsEnabled(ash::features::kSmartLockSignInRemoved)) { + notification_controller_->LaunchMultiDeviceSettings(); + } else { + notification_controller_->LaunchEasyUnlockSettings(); + } } } // namespace ash
diff --git a/chrome/browser/ash/login/easy_unlock/easy_unlock_notification_controller.h b/chrome/browser/ash/login/easy_unlock/easy_unlock_notification_controller.h index 5ff9c36..b8570d73 100644 --- a/chrome/browser/ash/login/easy_unlock/easy_unlock_notification_controller.h +++ b/chrome/browser/ash/login/easy_unlock/easy_unlock_notification_controller.h
@@ -28,6 +28,18 @@ virtual ~EasyUnlockNotificationController(); + // TODO(b/227674947): Eventually remove this method after Sign in with Smart + // Lock has been removed and enough time has elapsed for users to be notified. + // Returns whether the kSignInRemovedNotification should be shown for the + // provided profile. + static bool ShouldShowSignInRemovedNotification(Profile* profile); + + // TODO(b/227674947): Eventually remove this method after Sign in with Smart + // Lock has been removed and enough time has elapsed for users to be notified. + // Shows the notification explaining that Sign in with Smart Lock has been + // removed. + virtual void ShowSignInRemovedNotification(); + // Shows the notification when EasyUnlock is synced to a new Chromebook. virtual void ShowChromebookAddedNotification(); @@ -43,6 +55,7 @@ protected: // Exposed for testing. virtual void LaunchEasyUnlockSettings(); + virtual void LaunchMultiDeviceSettings(); virtual void LockScreen(); private:
diff --git a/chrome/browser/ash/login/easy_unlock/easy_unlock_notification_controller_unittest.cc b/chrome/browser/ash/login/easy_unlock/easy_unlock_notification_controller_unittest.cc index 86f7dc7c..109f5cc 100644 --- a/chrome/browser/ash/login/easy_unlock/easy_unlock_notification_controller_unittest.cc +++ b/chrome/browser/ash/login/easy_unlock/easy_unlock_notification_controller_unittest.cc
@@ -4,9 +4,14 @@ #include "chrome/browser/ash/login/easy_unlock/easy_unlock_notification_controller.h" +#include "ash/components/proximity_auth/proximity_auth_pref_names.h" +#include "ash/constants/ash_features.h" #include "base/strings/utf_string_conversions.h" +#include "base/test/scoped_feature_list.h" #include "chrome/browser/notifications/notification_display_service_tester.h" +#include "chrome/common/pref_names.h" #include "chrome/test/base/browser_with_test_window_test.h" +#include "components/sync_preferences/testing_pref_service_syncable.h" #include "testing/gmock/include/gmock/gmock.h" #include "ui/message_center/public/cpp/notification.h" #include "ui/message_center/public/cpp/notification_types.h" @@ -31,6 +36,7 @@ // EasyUnlockNotificationController: MOCK_METHOD0(LaunchEasyUnlockSettings, void()); + MOCK_METHOD0(LaunchMultiDeviceSettings, void()); MOCK_METHOD0(LockScreen, void()); }; @@ -61,6 +67,70 @@ }; TEST_F(EasyUnlockNotificationControllerTest, + TestShouldShowSignInRemovedNotification) { + TestingProfile* test_profile = profile(); + PrefService* pref_service = test_profile->GetPrefs(); + + ASSERT_FALSE( + EasyUnlockNotificationController::ShouldShowSignInRemovedNotification( + test_profile)); + + // Check returns false when kSmartLockSignInRemoved isn't enabled. + pref_service->SetBoolean( + proximity_auth::prefs::kProximityAuthIsChromeOSLoginEnabled, true); + pref_service->SetBoolean(prefs::kHasSeenSmartLockSignInRemovedNotification, + false); + ASSERT_FALSE( + EasyUnlockNotificationController::ShouldShowSignInRemovedNotification( + test_profile)); + + // Check returns false when kHasSeenSmartLockSignInRemovedNotification is + // true. + base::test::ScopedFeatureList feature_list( + ash::features::kSmartLockSignInRemoved); + pref_service->SetBoolean(prefs::kHasSeenSmartLockSignInRemovedNotification, + true); + ASSERT_FALSE( + EasyUnlockNotificationController::ShouldShowSignInRemovedNotification( + test_profile)); + + // Check returns false when kProximityAuthIsChromeOSLoginEnabled is false. + pref_service->SetBoolean( + proximity_auth::prefs::kProximityAuthIsChromeOSLoginEnabled, false); + pref_service->SetBoolean(prefs::kHasSeenSmartLockSignInRemovedNotification, + false); + ASSERT_FALSE( + EasyUnlockNotificationController::ShouldShowSignInRemovedNotification( + test_profile)); + + pref_service->SetBoolean( + proximity_auth::prefs::kProximityAuthIsChromeOSLoginEnabled, true); + ASSERT_TRUE( + EasyUnlockNotificationController::ShouldShowSignInRemovedNotification( + test_profile)); +} + +TEST_F(EasyUnlockNotificationControllerTest, + TestShowSignInRemovedNotification) { + base::test::ScopedFeatureList feature_list( + ash::features::kSmartLockSignInRemoved); + const char kNotificationId[] = "easyunlock_notification_ids.sign_in_removed"; + + notification_controller_->ShowSignInRemovedNotification(); + absl::optional<message_center::Notification> notification = + display_service_->GetNotification(kNotificationId); + ASSERT_TRUE(notification); + + // Clicking notification button should launch settings. + EXPECT_CALL(*notification_controller_, LaunchMultiDeviceSettings()); + notification->delegate()->Click(0, absl::nullopt); + + // Clicking the notification itself should also launch settings. + EXPECT_CALL(*notification_controller_, LaunchMultiDeviceSettings()); + notification->delegate()->Click(absl::nullopt, absl::nullopt); +} + +TEST_F(EasyUnlockNotificationControllerTest, TestShowChromebookAddedNotification) { const char kNotificationId[] = "easyunlock_notification_ids.chromebook_added";
diff --git a/chrome/browser/ash/login/session/user_session_manager.cc b/chrome/browser/ash/login/session/user_session_manager.cc index b7289dd..b927e00 100644 --- a/chrome/browser/ash/login/session/user_session_manager.cc +++ b/chrome/browser/ash/login/session/user_session_manager.cc
@@ -64,6 +64,7 @@ #include "chrome/browser/ash/login/chrome_restart_request.h" #include "chrome/browser/ash/login/demo_mode/demo_session.h" #include "chrome/browser/ash/login/easy_unlock/easy_unlock_key_manager.h" +#include "chrome/browser/ash/login/easy_unlock/easy_unlock_notification_controller.h" #include "chrome/browser/ash/login/easy_unlock/easy_unlock_service.h" #include "chrome/browser/ash/login/existing_user_controller.h" #include "chrome/browser/ash/login/helper.h" @@ -1934,6 +1935,13 @@ ->browser_policy_connector_ash() ->GetAdbSideloadingAllowanceModePolicyHandler() ->ShowAdbSideloadingPolicyChangeNotificationIfNeeded(); + + if (EasyUnlockNotificationController::ShouldShowSignInRemovedNotification( + profile)) { + easy_unlock_notification_controller_ = + std::make_unique<EasyUnlockNotificationController>(profile); + easy_unlock_notification_controller_->ShowSignInRemovedNotification(); + } } void UserSessionManager::MaybeLaunchSettings(Profile* profile) { @@ -2366,6 +2374,7 @@ token_observers_.clear(); always_on_vpn_manager_.reset(); u2f_notification_.reset(); + easy_unlock_notification_controller_.reset(); help_app_notification_controller_.reset(); password_service_voted_.reset(); password_was_saved_ = false;
diff --git a/chrome/browser/ash/login/session/user_session_manager.h b/chrome/browser/ash/login/session/user_session_manager.h index 8e79bfe..7ddfd25 100644 --- a/chrome/browser/ash/login/session/user_session_manager.h +++ b/chrome/browser/ash/login/session/user_session_manager.h
@@ -64,6 +64,7 @@ class OnboardingUserActivityCounter; class StubAuthenticatorBuilder; class TokenHandleFetcher; +class EasyUnlockNotificationController; namespace test { class UserSessionManagerTestApi; @@ -674,6 +675,11 @@ std::unique_ptr<HelpAppNotificationController> help_app_notification_controller_; + // TODO(b/227674947): Eventually delete this after Sign in with Smart Lock has + // been removed and enough time has elapsed for users to be notified. + std::unique_ptr<EasyUnlockNotificationController> + easy_unlock_notification_controller_; + bool token_handle_backfill_tried_for_testing_ = false; std::unique_ptr<OnboardingUserActivityCounter>
diff --git a/chrome/browser/ash/preferences.cc b/chrome/browser/ash/preferences.cc index a6d5cdb6..d52d4ab 100644 --- a/chrome/browser/ash/preferences.cc +++ b/chrome/browser/ash/preferences.cc
@@ -398,6 +398,11 @@ registry->RegisterBooleanPref(::prefs::kLanguageImeMenuActivated, false); + // TODO(b/227674947): Eventually delete this after Sign in with Smart Lock has + // been removed and enough time has elapsed for users to be notified. + registry->RegisterBooleanPref( + ::prefs::kHasSeenSmartLockSignInRemovedNotification, false); + registry->RegisterInt64Pref(::prefs::kHatsLastInteractionTimestamp, 0); registry->RegisterInt64Pref(::prefs::kHatsSurveyCycleEndTimestamp, 0);
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn index 79fab20..f78cafa 100644 --- a/chrome/browser/chromeos/BUILD.gn +++ b/chrome/browser/chromeos/BUILD.gn
@@ -1333,6 +1333,8 @@ "../ash/crostini/ansible/ansible_management_service.h", "../ash/crostini/ansible/ansible_management_service_factory.cc", "../ash/crostini/ansible/ansible_management_service_factory.h", + "../ash/crostini/crostini_capabilities.cc", + "../ash/crostini/crostini_capabilities.h", "../ash/crostini/crostini_disk.cc", "../ash/crostini/crostini_disk.h", "../ash/crostini/crostini_engagement_metrics_service.cc",
diff --git a/chrome/browser/content_creation/notes/internal/android/BUILD.gn b/chrome/browser/content_creation/notes/internal/android/BUILD.gn index 8477540..11ee6d995 100644 --- a/chrome/browser/content_creation/notes/internal/android/BUILD.gn +++ b/chrome/browser/content_creation/notes/internal/android/BUILD.gn
@@ -46,8 +46,11 @@ "//components/image_fetcher:java", "//components/url_formatter/android:url_formatter_java", "//content/public/android:content_java_resources", - "//third_party/android_deps:android_support_v7_appcompat_java", "//third_party/androidx:androidx_annotation_annotation_java", + "//third_party/androidx:androidx_appcompat_appcompat_java", + "//third_party/androidx:androidx_core_core_java", + "//third_party/androidx:androidx_fragment_fragment_java", + "//third_party/androidx:androidx_recyclerview_recyclerview_java", "//ui/android:ui_java", "//url:gurl_java", ]
diff --git a/chrome/browser/dev_ui_browser_resources.grd b/chrome/browser/dev_ui_browser_resources.grd index 9e2bc2a..988ef38 100644 --- a/chrome/browser/dev_ui_browser_resources.grd +++ b/chrome/browser/dev_ui_browser_resources.grd
@@ -49,7 +49,7 @@ <include name="IDR_PREDICTORS_RESOURCE_PREFETCH_PREDICTOR_JS" file="${root_gen_dir}\chrome\browser\resources\predictors\resource_prefetch_predictor.js" use_base_dir="false" type="BINDATA" /> <include name="IDR_MEDIA_SESSION_MOJOM_WEBUI_JS" file="${root_gen_dir}\mojom-webui\services\media_session\public\mojom\media_session.mojom-webui.js" use_base_dir="false" type="BINDATA" /> - <if expr="is_android or is_linux"> + <if expr="is_android or is_linux or chromeos_ash or chromeos_lacros"> <include name="IDR_SANDBOX_INTERNALS_HTML" file="resources\sandbox_internals\sandbox_internals.html" preprocess="true" type="BINDATA" /> <include name="IDR_SANDBOX_INTERNALS_JS" file="resources\sandbox_internals\sandbox_internals.js" preprocess="true" type="BINDATA" /> </if>
diff --git a/chrome/browser/devtools/devtools_window.cc b/chrome/browser/devtools/devtools_window.cc index 46e0b224..6b2b7f6 100644 --- a/chrome/browser/devtools/devtools_window.cc +++ b/chrome/browser/devtools/devtools_window.cc
@@ -442,10 +442,6 @@ if (throttle_) throttle_->ResumeThrottle(); - if (reattach_complete_callback_) { - std::move(reattach_complete_callback_).Run(); - } - life_stage_ = kClosing; UpdateBrowserWindow(); @@ -468,6 +464,13 @@ base::SequencedTaskRunnerHandle::Get()->DeleteSoon( FROM_HERE, std::move(owned_main_web_contents_)); } + + // This should be run after we remove |this| from + // |g_devtools_window_instances| as |reattach_complete_callback| may try to + // access it. + if (reattach_complete_callback_) { + std::move(reattach_complete_callback_).Run(); + } } // static
diff --git a/chrome/browser/extensions/api/activity_log_private/activity_log_private_api.cc b/chrome/browser/extensions/api/activity_log_private/activity_log_private_api.cc index bda9aa2..1815aa6 100644 --- a/chrome/browser/extensions/api/activity_log_private/activity_log_private_api.cc +++ b/chrome/browser/extensions/api/activity_log_private/activity_log_private_api.cc
@@ -88,13 +88,13 @@ } void ActivityLogAPI::OnExtensionActivity(scoped_refptr<Action> activity) { - std::unique_ptr<base::ListValue> value(new base::ListValue()); + base::Value::List value; ExtensionActivity activity_arg = activity->ConvertToExtensionActivity(); - value->Append(activity_arg.ToValue()); + value.Append(base::Value::FromUniquePtrValue(activity_arg.ToValue())); auto event = std::make_unique<Event>( events::ACTIVITY_LOG_PRIVATE_ON_EXTENSION_ACTIVITY, activity_log_private::OnExtensionActivity::kEventName, - std::move(*value).TakeListDeprecated(), browser_context_); + base::Value(std::move(value)).TakeListDeprecated(), browser_context_); EventRouter::Get(browser_context_)->BroadcastEvent(std::move(event)); }
diff --git a/chrome/browser/extensions/api/certificate_provider/certificate_provider_api.cc b/chrome/browser/extensions/api/certificate_provider/certificate_provider_api.cc index 74465113..0fde775 100644 --- a/chrome/browser/extensions/api/certificate_provider/certificate_provider_api.cc +++ b/chrome/browser/extensions/api/certificate_provider/certificate_provider_api.cc
@@ -510,7 +510,7 @@ LOG(WARNING) << "PIN request succeeded"; api::certificate_provider::PinResponseDetails details; details.user_input = std::make_unique<std::string>(value); - create_results->Append(details.ToValue()); + create_results->Append(base::Value::FromUniquePtrValue(details.ToValue())); } else { // TODO(crbug.com/1046860): Remove logging after stabilizing the feature. LOG(WARNING) << "PIN request canceled";
diff --git a/chrome/browser/extensions/api/commands/commands.cc b/chrome/browser/extensions/api/commands/commands.cc index ab97d64..87d7970 100644 --- a/chrome/browser/extensions/api/commands/commands.cc +++ b/chrome/browser/extensions/api/commands/commands.cc
@@ -13,22 +13,20 @@ namespace { -std::unique_ptr<base::DictionaryValue> CreateCommandValue( - const extensions::Command& command, - bool active) { - std::unique_ptr<base::DictionaryValue> result(new base::DictionaryValue()); - result->SetStringKey("name", command.command_name()); - result->SetStringKey("description", command.description()); - result->SetStringKey("shortcut", active - ? command.accelerator().GetShortcutText() - : std::u16string()); +base::Value::Dict CreateCommandValue(const extensions::Command& command, + bool active) { + base::Value::Dict result; + result.Set("name", command.command_name()); + result.Set("description", command.description()); + result.Set("shortcut", active ? command.accelerator().GetShortcutText() + : std::u16string()); return result; } } // namespace ExtensionFunction::ResponseAction GetAllCommandsFunction::Run() { - std::unique_ptr<base::ListValue> command_list(new base::ListValue()); + base::Value::List command_list; extensions::CommandService* command_service = extensions::CommandService::Get(browser_context()); @@ -41,14 +39,14 @@ if (command_service->GetExtensionActionCommand( extension_->id(), extensions::ActionInfo::TYPE_BROWSER, extensions::CommandService::ALL, &browser_action, &active)) { - command_list->Append(CreateCommandValue(browser_action, active)); + command_list.Append(CreateCommandValue(browser_action, active)); } extensions::Command page_action; if (command_service->GetExtensionActionCommand( extension_->id(), extensions::ActionInfo::TYPE_PAGE, extensions::CommandService::ALL, &page_action, &active)) { - command_list->Append(CreateCommandValue(page_action, active)); + command_list.Append(CreateCommandValue(page_action, active)); } extensions::CommandMap named_commands; @@ -64,9 +62,8 @@ ui::Accelerator shortcut_assigned = command.accelerator(); active = (shortcut_assigned.key_code() != ui::VKEY_UNKNOWN); - command_list->Append(CreateCommandValue(iter->second, active)); + command_list.Append(CreateCommandValue(iter->second, active)); } - return RespondNow( - OneArgument(base::Value::FromUniquePtrValue(std::move(command_list)))); + return RespondNow(OneArgument(base::Value(std::move(command_list)))); }
diff --git a/chrome/browser/extensions/api/extension_action/extension_action_api.cc b/chrome/browser/extensions/api/extension_action/extension_action_api.cc index 84929283..fe0ad38 100644 --- a/chrome/browser/extensions/api/extension_action/extension_action_api.cc +++ b/chrome/browser/extensions/api/extension_action/extension_action_api.cc
@@ -229,9 +229,10 @@ ExtensionTabUtil::ScrubTabBehavior scrub_tab_behavior = ExtensionTabUtil::GetScrubTabBehavior(extension, context_type, web_contents); - args->Append(ExtensionTabUtil::CreateTabObject( - web_contents, scrub_tab_behavior, extension) - ->ToValue()); + args->Append(base::Value::FromUniquePtrValue( + ExtensionTabUtil::CreateTabObject(web_contents, scrub_tab_behavior, + extension) + ->ToValue())); DispatchEventToExtension(web_contents->GetBrowserContext(), extension_action.extension_id(), histogram_value,
diff --git a/chrome/browser/extensions/api/font_settings/font_settings_api.cc b/chrome/browser/extensions/api/font_settings/font_settings_api.cc index 6eab088..fa759c2 100644 --- a/chrome/browser/extensions/api/font_settings/font_settings_api.cc +++ b/chrome/browser/extensions/api/font_settings/font_settings_api.cc
@@ -159,10 +159,10 @@ } std::string font_name = pref->GetValue()->GetString(); base::ListValue args; - std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); - dict->SetStringKey(kFontIdKey, font_name); - dict->SetStringKey(kGenericFamilyKey, generic_family); - dict->SetStringKey(kScriptKey, script); + base::Value::Dict dict; + dict.Set(kFontIdKey, font_name); + dict.Set(kGenericFamilyKey, generic_family); + dict.Set(kScriptKey, script); args.Append(std::move(dict)); extensions::preference_helpers::DispatchEventToExtensions( @@ -181,8 +181,8 @@ CHECK(pref); base::ListValue args; - std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); - dict->Set(key, base::Value::ToUniquePtrValue(pref->GetValue()->Clone())); + base::Value::Dict dict; + dict.Set(key, pref->GetValue()->Clone()); args.Append(std::move(dict)); extensions::preference_helpers::DispatchEventToExtensions( @@ -296,7 +296,7 @@ ExtensionFunction::ResponseValue FontSettingsGetFontListFunction::CopyFontsToResult(base::ListValue* fonts) { - std::unique_ptr<base::ListValue> result(new base::ListValue()); + base::Value::List result; for (const auto& entry : fonts->GetListDeprecated()) { if (!entry.is_list()) { NOTREACHED(); @@ -305,27 +305,21 @@ const base::Value::ConstListView font_list_value = entry.GetListDeprecated(); - if (font_list_value.size() < 2 || !font_list_value[0].is_string()) { + if (font_list_value.size() < 2 || !font_list_value[0].is_string() || + !font_list_value[1].is_string()) { NOTREACHED(); return Error(""); } const std::string& name = font_list_value[0].GetString(); - - if (!font_list_value[1].is_string()) { - NOTREACHED(); - return Error(""); - } const std::string& localized_name = font_list_value[1].GetString(); - std::unique_ptr<base::DictionaryValue> font_name( - new base::DictionaryValue()); - font_name->Set(kFontIdKey, std::make_unique<base::Value>(name)); - font_name->Set(kDisplayNameKey, - std::make_unique<base::Value>(localized_name)); - result->Append(std::move(font_name)); + base::Value::Dict font_name; + font_name.Set(kFontIdKey, name); + font_name.Set(kDisplayNameKey, localized_name); + result.Append(std::move(font_name)); } - return OneArgument(base::Value::FromUniquePtrValue(std::move(result))); + return OneArgument(base::Value(std::move(result))); } ExtensionFunction::ResponseAction ClearFontPrefExtensionFunction::Run() {
diff --git a/chrome/browser/extensions/api/language_settings_private/language_settings_private_api_unittest.cc b/chrome/browser/extensions/api/language_settings_private/language_settings_private_api_unittest.cc index b919d537..8554cf30 100644 --- a/chrome/browser/extensions/api/language_settings_private/language_settings_private_api_unittest.cc +++ b/chrome/browser/extensions/api/language_settings_private/language_settings_private_api_unittest.cc
@@ -184,14 +184,14 @@ profile()); EXPECT_TRUE(actual) << function->GetError(); - base::ListValue expected; - auto expected_status = std::make_unique<base::DictionaryValue>(); - expected_status->SetStringKey("languageCode", "fr"); - expected_status->SetBoolKey("isReady", false); - expected_status->SetBoolKey("isDownloading", true); - expected_status->SetBoolKey("downloadFailed", false); + base::Value::List expected; + base::Value::Dict expected_status; + expected_status.Set("languageCode", "fr"); + expected_status.Set("isReady", false); + expected_status.Set("isDownloading", true); + expected_status.Set("downloadFailed", false); expected.Append(std::move(expected_status)); - EXPECT_EQ(expected, *actual); + EXPECT_EQ(base::Value(std::move(expected)), *actual); } TEST_F(LanguageSettingsPrivateApiTest, SetLanguageAlwaysTranslateStateTest) {
diff --git a/chrome/browser/extensions/api/settings_private/settings_private_delegate.cc b/chrome/browser/extensions/api/settings_private/settings_private_delegate.cc index a2fa171..25c81021 100644 --- a/chrome/browser/extensions/api/settings_private/settings_private_delegate.cc +++ b/chrome/browser/extensions/api/settings_private/settings_private_delegate.cc
@@ -46,7 +46,7 @@ for (const auto& it : keys) { std::unique_ptr<base::Value> pref = GetPref(it.first); if (!pref->is_none()) - prefs->Append(std::move(pref)); + prefs->Append(base::Value::FromUniquePtrValue(std::move(pref))); } return std::move(prefs);
diff --git a/chrome/browser/extensions/api/storage/settings_sync_unittest.cc b/chrome/browser/extensions/api/storage/settings_sync_unittest.cc index 16989cb..eee6474 100644 --- a/chrome/browser/extensions/api/storage/settings_sync_unittest.cc +++ b/chrome/browser/extensions/api/storage/settings_sync_unittest.cc
@@ -1450,25 +1450,24 @@ static void UnlimitedSyncStorageTestCallback(ValueStore* sync_storage) { // Sync storage should still run out after ~100K; the unlimitedStorage // permission can't apply to sync. - std::unique_ptr<base::Value> kilobyte = settings_test_util::CreateKilobyte(); + base::Value kilobyte = settings_test_util::CreateKilobyte(); for (int i = 0; i < 100; ++i) { - sync_storage->Set(ValueStore::DEFAULTS, base::NumberToString(i), *kilobyte); + sync_storage->Set(ValueStore::DEFAULTS, base::NumberToString(i), kilobyte); } - EXPECT_FALSE(sync_storage->Set(ValueStore::DEFAULTS, "WillError", *kilobyte) + EXPECT_FALSE(sync_storage->Set(ValueStore::DEFAULTS, "WillError", kilobyte) .status() .ok()); } static void UnlimitedLocalStorageTestCallback(ValueStore* local_storage) { // Local storage should never run out. - std::unique_ptr<base::Value> megabyte = settings_test_util::CreateMegabyte(); + base::Value megabyte = settings_test_util::CreateMegabyte(); for (int i = 0; i < 7; ++i) { - local_storage->Set(ValueStore::DEFAULTS, base::NumberToString(i), - *megabyte); + local_storage->Set(ValueStore::DEFAULTS, base::NumberToString(i), megabyte); } - EXPECT_TRUE(local_storage->Set(ValueStore::DEFAULTS, "WontError", *megabyte) + EXPECT_TRUE(local_storage->Set(ValueStore::DEFAULTS, "WontError", megabyte) .status() .ok()); }
diff --git a/chrome/browser/extensions/api/terminal/terminal_private_browsertest.cc b/chrome/browser/extensions/api/terminal/terminal_private_browsertest.cc index 188dd05..979c64d 100644 --- a/chrome/browser/extensions/api/terminal/terminal_private_browsertest.cc +++ b/chrome/browser/extensions/api/terminal/terminal_private_browsertest.cc
@@ -4,6 +4,7 @@ #include <memory> +#include "chrome/browser/ash/crostini/crostini_browser_test_util.h" #include "chrome/browser/ash/crostini/fake_crostini_features.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/policy/system_features_disable_list_policy_handler.h" @@ -20,14 +21,15 @@ namespace extensions { -class TerminalPrivateBrowserTest : public InProcessBrowserTest { +class TerminalPrivateBrowserTest : public CrostiniBrowserTestBase { public: TerminalPrivateBrowserTest(const TerminalPrivateBrowserTest&) = delete; TerminalPrivateBrowserTest& operator=(const TerminalPrivateBrowserTest&) = delete; protected: - TerminalPrivateBrowserTest() = default; + TerminalPrivateBrowserTest() + : CrostiniBrowserTestBase(/*register_termina=*/false) {} void ExpectJsResult(const std::string& script, const std::string& expected) { content::WebContents* web_contents = @@ -50,12 +52,11 @@ })}))"; // 'vmshell not allowed' when crostini is not allowed. - crostini::FakeCrostiniFeatures crostini_features; - crostini_features.set_could_be_allowed(true); - crostini_features.set_is_allowed_now(false); + fake_crostini_features_.set_could_be_allowed(true); + fake_crostini_features_.set_is_allowed_now(false); ExpectJsResult(script, "vmshell not allowed"); - crostini_features.set_is_allowed_now(true); + fake_crostini_features_.set_is_allowed_now(true); ExpectJsResult(script, "success"); // openTerminalProcess not defined.
diff --git a/chrome/browser/extensions/api/top_sites/top_sites_api.cc b/chrome/browser/extensions/api/top_sites/top_sites_api.cc index 0f180bf..b38d307 100644 --- a/chrome/browser/extensions/api/top_sites/top_sites_api.cc +++ b/chrome/browser/extensions/api/top_sites/top_sites_api.cc
@@ -37,22 +37,21 @@ void TopSitesGetFunction::OnMostVisitedURLsAvailable( const history::MostVisitedURLList& data) { - std::unique_ptr<base::ListValue> pages_value(new base::ListValue); - for (size_t i = 0; i < data.size(); i++) { - const history::MostVisitedURL& url = data[i]; + base::Value::List pages_value; + for (const auto& url : data) { if (!url.url.is_empty()) { - std::unique_ptr<base::DictionaryValue> page_value( - new base::DictionaryValue()); - page_value->SetStringKey("url", url.url.spec()); - if (url.title.empty()) - page_value->SetStringKey("title", url.url.spec()); - else - page_value->SetStringKey("title", url.title); - pages_value->Append(std::move(page_value)); + base::Value::Dict page_value; + page_value.Set("url", url.url.spec()); + if (url.title.empty()) { + page_value.Set("title", url.url.spec()); + } else { + page_value.Set("title", url.title); + } + pages_value.Append(std::move(page_value)); } } - Respond(OneArgument(base::Value::FromUniquePtrValue(std::move(pages_value)))); + Respond(OneArgument(base::Value(std::move(pages_value)))); } } // namespace extensions
diff --git a/chrome/browser/extensions/api/virtual_keyboard_private/chrome_virtual_keyboard_delegate.cc b/chrome/browser/extensions/api/virtual_keyboard_private/chrome_virtual_keyboard_delegate.cc index 7af2e37f..f34056f 100644 --- a/chrome/browser/extensions/api/virtual_keyboard_private/chrome_virtual_keyboard_delegate.cc +++ b/chrome/browser/extensions/api/virtual_keyboard_private/chrome_virtual_keyboard_delegate.cc
@@ -608,7 +608,7 @@ return; auto event_args = std::make_unique<base::ListValue>(); - event_args->Append(std::move(settings)); + event_args->Append(base::Value::FromUniquePtrValue(std::move(settings))); auto event = std::make_unique<extensions::Event>( extensions::events::VIRTUAL_KEYBOARD_PRIVATE_ON_KEYBOARD_CONFIG_CHANGED,
diff --git a/chrome/browser/extensions/api/web_navigation/web_navigation_api_helpers.cc b/chrome/browser/extensions/api/web_navigation/web_navigation_api_helpers.cc index 3a456e0..86a4e3e 100644 --- a/chrome/browser/extensions/api/web_navigation/web_navigation_api_helpers.cc +++ b/chrome/browser/extensions/api/web_navigation/web_navigation_api_helpers.cc
@@ -112,33 +112,30 @@ navigation_handle->GetRenderFrameHost(); ui::PageTransition transition_type = navigation_handle->GetPageTransition(); - std::unique_ptr<base::ListValue> args(new base::ListValue()); - std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); - dict->SetIntKey(web_navigation_api_constants::kTabIdKey, - ExtensionTabUtil::GetTabId(web_contents)); - dict->SetStringKey(web_navigation_api_constants::kUrlKey, url.spec()); - dict->SetIntKey(web_navigation_api_constants::kProcessIdKey, - frame_host->GetProcess()->GetID()); - dict->SetIntKey(web_navigation_api_constants::kFrameIdKey, - ExtensionApiFrameIdMap::GetFrameId(frame_host)); - dict->SetIntKey(web_navigation_api_constants::kParentFrameIdKey, - ExtensionApiFrameIdMap::GetParentFrameId(frame_host)); - dict->SetStringKey( - web_navigation_api_constants::kDocumentIdKey, - ExtensionApiFrameIdMap::GetDocumentId(frame_host).ToString()); + base::Value::List args; + base::Value::Dict dict; + dict.Set(web_navigation_api_constants::kTabIdKey, + ExtensionTabUtil::GetTabId(web_contents)); + dict.Set(web_navigation_api_constants::kUrlKey, url.spec()); + dict.Set(web_navigation_api_constants::kProcessIdKey, + frame_host->GetProcess()->GetID()); + dict.Set(web_navigation_api_constants::kFrameIdKey, + ExtensionApiFrameIdMap::GetFrameId(frame_host)); + dict.Set(web_navigation_api_constants::kParentFrameIdKey, + ExtensionApiFrameIdMap::GetParentFrameId(frame_host)); + dict.Set(web_navigation_api_constants::kDocumentIdKey, + ExtensionApiFrameIdMap::GetDocumentId(frame_host).ToString()); // Only set the parentDocumentId value if we have a parent. if (content::RenderFrameHost* parent_frame_host = frame_host->GetParentOrOuterDocument()) { - dict->SetStringKey( + dict.Set( web_navigation_api_constants::kParentDocumentIdKey, ExtensionApiFrameIdMap::GetDocumentId(parent_frame_host).ToString()); } - dict->SetStringKey( - web_navigation_api_constants::kFrameTypeKey, - ToString(ExtensionApiFrameIdMap::GetFrameType(frame_host))); - dict->SetStringKey( - web_navigation_api_constants::kDocumentLifecycleKey, - ToString(ExtensionApiFrameIdMap::GetDocumentLifecycle(frame_host))); + dict.Set(web_navigation_api_constants::kFrameTypeKey, + ToString(ExtensionApiFrameIdMap::GetFrameType(frame_host))); + dict.Set(web_navigation_api_constants::kDocumentLifecycleKey, + ToString(ExtensionApiFrameIdMap::GetDocumentLifecycle(frame_host))); if (navigation_handle->WasServerRedirect()) { transition_type = ui::PageTransitionFromInt( @@ -152,8 +149,8 @@ if (ui::PageTransitionCoreTypeIs(transition_type, ui::PAGE_TRANSITION_AUTO_TOPLEVEL)) transition_type_string = "start_page"; - dict->SetStringKey(web_navigation_api_constants::kTransitionTypeKey, - transition_type_string); + dict.Set(web_navigation_api_constants::kTransitionTypeKey, + transition_type_string); base::Value qualifiers(base::Value::Type::LIST); if (transition_type & ui::PAGE_TRANSITION_CLIENT_REDIRECT) qualifiers.Append("client_redirect"); @@ -163,17 +160,17 @@ qualifiers.Append("forward_back"); if (transition_type & ui::PAGE_TRANSITION_FROM_ADDRESS_BAR) qualifiers.Append("from_address_bar"); - dict->SetKey(web_navigation_api_constants::kTransitionQualifiersKey, - std::move(qualifiers)); - dict->SetDoubleKey(web_navigation_api_constants::kTimeStampKey, - MilliSecondsFromTime(base::Time::Now())); - args->Append(std::move(dict)); + dict.Set(web_navigation_api_constants::kTransitionQualifiersKey, + std::move(qualifiers)); + dict.Set(web_navigation_api_constants::kTimeStampKey, + MilliSecondsFromTime(base::Time::Now())); + args.Append(std::move(dict)); content::BrowserContext* browser_context = navigation_handle->GetWebContents()->GetBrowserContext(); - auto event = std::make_unique<Event>(histogram_value, event_name, - std::move(*args).TakeListDeprecated(), - browser_context); + auto event = std::make_unique<Event>( + histogram_value, event_name, + base::Value(std::move(args)).TakeListDeprecated(), browser_context); DispatchEvent(browser_context, std::move(event), url); }
diff --git a/chrome/browser/extensions/api/webrtc_audio_private/webrtc_audio_private_browsertest.cc b/chrome/browser/extensions/api/webrtc_audio_private/webrtc_audio_private_browsertest.cc index 16286fe6..5fd8942 100644 --- a/chrome/browser/extensions/api/webrtc_audio_private/webrtc_audio_private_browsertest.cc +++ b/chrome/browser/extensions/api/webrtc_audio_private/webrtc_audio_private_browsertest.cc
@@ -117,10 +117,9 @@ protected: void AppendTabIdToRequestInfo(base::ListValue* params, int tab_id) { - std::unique_ptr<base::DictionaryValue> request_info( - new base::DictionaryValue()); - request_info->SetIntKey("tabId", tab_id); - params->Append(std::move(request_info)); + base::Value::Dict request_info; + request_info.Set("tabId", tab_id); + params->Append(base::Value(std::move(request_info))); } std::unique_ptr<base::Value> InvokeGetSinks() {
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index c2e850d..1d67de5 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -565,16 +565,16 @@ "expiry_milestone": 110 }, { + "name": "back-gesture-refactor-android", + "owners": ["lazzzis@google.com", "jinsukkim", "twellington"], + "expiry_milestone": 109 + }, + { "name": "biometric-reauth-password-filling", "owners": [ "ioanap" ], "expiry_milestone": 104 }, { - "name": "block-external-form-redirects-no-gesture", - "owners": [ "jochen", "tedchoc" ], - "expiry_milestone": 89 - }, - { "name": "block-insecure-private-network-requests", "owners": [ "titouan", "chrome-security-owp-team@google.com" ], "expiry_milestone": 107 @@ -3316,8 +3316,8 @@ }, { "name": "font-access", - "owners": [ "cmp", "pwnall" ], - "expiry_milestone": 102 + "owners": [ "dslee" ], + "expiry_milestone": 105 }, { "name": "force-color-profile",
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index b6446bd..96bdafc 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -2977,6 +2977,10 @@ "When enabled, app menu should show 'Mobile site' when showing desktop " "site, instead of showing 'Desktop Site' with checkbox"; +const char kBackGestureRefactorAndroidName[] = "Back Gesture Refactor"; +const char kBackGestureRefactorAndroidDescription[] = + "Enable Back Gesture Refactor."; + const char kCCTIncognitoName[] = "Chrome Custom Tabs Incognito mode"; const char kCCTIncognitoDescription[] = "Enables incognito mode for Chrome Custom Tabs, on Android."; @@ -3148,13 +3152,6 @@ const char kEnableAutofillRefreshStyleDescription[] = "Enable modernized style for Autofill on Android"; -const char kChromeManagementPageAndroidName[] = - "Enable chrome://management page on Android"; -const char kChromeManagementPageAndroidDescription[] = - "Enable chrome://management page on Android, which aims to inform the user " - "if their browser is managed by their employer along with other useful " - "information."; - const char kEnableCommandLineOnNonRootedName[] = "Enable command line on non-rooted devices"; const char kEnableCommandLineOnNoRootedDescription[] = @@ -3203,12 +3200,6 @@ const char kInstantStartDescription[] = "Show start surface before native library is loaded."; -const char kIntentBlockExternalFormRedirectsNoGestureName[] = - "Block intents from form submissions without user gesture"; -const char kIntentBlockExternalFormRedirectsNoGestureDescription[] = - "Require a user gesture that triggered a form submission in order to " - "allow for redirecting to an external intent."; - const char kInterestFeedV2Name[] = "Interest Feed v2"; const char kInterestFeedV2Description[] = "Show content suggestions on the New Tab Page and Start Surface using the "
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index 7426a92..dd3f32f8 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -1678,6 +1678,9 @@ extern const char kAppMenuMobileSiteOptionName[]; extern const char kAppMenuMobileSiteOptionDescription[]; +extern const char kBackGestureRefactorAndroidName[]; +extern const char kBackGestureRefactorAndroidDescription[]; + extern const char kCCTIncognitoName[]; extern const char kCCTIncognitoDescription[]; @@ -1768,9 +1771,6 @@ extern const char kEnableAutofillRefreshStyleName[]; extern const char kEnableAutofillRefreshStyleDescription[]; -extern const char kChromeManagementPageAndroidName[]; -extern const char kChromeManagementPageAndroidDescription[]; - extern const char kEnableCommandLineOnNonRootedName[]; extern const char kEnableCommandLineOnNoRootedDescription[]; @@ -1805,9 +1805,6 @@ extern const char kInstantStartName[]; extern const char kInstantStartDescription[]; -extern const char kIntentBlockExternalFormRedirectsNoGestureName[]; -extern const char kIntentBlockExternalFormRedirectsNoGestureDescription[]; - extern const char kInterestFeedV2Name[]; extern const char kInterestFeedV2Description[];
diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browser/flags/android/chrome_feature_list.cc index 64502580..275401f 100644 --- a/chrome/browser/flags/android/chrome_feature_list.cc +++ b/chrome/browser/flags/android/chrome_feature_list.cc
@@ -245,6 +245,7 @@ &kPageAnnotationsService, &kBookmarksImprovedSaveFlow, &kBookmarksRefresh, + &kBackGestureRefactorAndroid, &kProbabilisticCryptidRenderer, &kReachedCodeProfiler, &kImproveReaderModePrompt, @@ -352,7 +353,6 @@ &password_manager::features::kUnifiedPasswordManagerAndroid, &password_manager::features::kPasswordEditDialogWithDetails, &performance_hints::features::kContextMenuPerformanceInfo, - &policy::features::kChromeManagementPageAndroid, &privacy_sandbox::kPrivacySandboxSettings3, &query_tiles::features::kQueryTiles, &query_tiles::features::kQueryTilesInNTP, @@ -681,6 +681,9 @@ const base::Feature kBookmarksRefresh{"BookmarksRefresh", base::FEATURE_DISABLED_BY_DEFAULT}; +const base::Feature kBackGestureRefactorAndroid{ + "BackGestureRefactorAndroid", base::FEATURE_DISABLED_BY_DEFAULT}; + const base::Feature kProbabilisticCryptidRenderer{ "ProbabilisticCryptidRenderer", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/chrome/browser/flags/android/chrome_feature_list.h b/chrome/browser/flags/android/chrome_feature_list.h index db401d1d..69e86b0 100644 --- a/chrome/browser/flags/android/chrome_feature_list.h +++ b/chrome/browser/flags/android/chrome_feature_list.h
@@ -110,6 +110,7 @@ extern const base::Feature kPageAnnotationsService; extern const base::Feature kBookmarksImprovedSaveFlow; extern const base::Feature kBookmarksRefresh; +extern const base::Feature kBackGestureRefactorAndroid; extern const base::Feature kProbabilisticCryptidRenderer; extern const base::Feature kReachedCodeProfiler; extern const base::Feature kReengagementNotification;
diff --git a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java index 64d5cc5..0e3ce1f4 100644 --- a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java +++ b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java
@@ -233,6 +233,7 @@ public static final String APP_LAUNCHPAD = "AppLaunchpad"; public static final String APP_MENU_MOBILE_SITE_OPTION = "AppMenuMobileSiteOption"; public static final String BACKGROUND_THREAD_POOL = "BackgroundThreadPool"; + public static final String BACK_GESTURE_REFACTOR = "BackGestureRefactorAndroid"; public static final String BIOMETRIC_TOUCH_TO_FILL = "BiometricTouchToFill"; public static final String BULK_TAB_RESTORE = "BulkTabRestore"; public static final String CAPTIVE_PORTAL_CERTIFICATE_LIST = "CaptivePortalCertificateList"; @@ -256,7 +257,6 @@ "CCTReportParallelRequestStatus"; public static final String CLOSE_TAB_SUGGESTIONS = "CloseTabSuggestions"; public static final String DONT_AUTO_HIDE_BROWSER_CONTROLS = "DontAutoHideBrowserControls"; - public static final String CHROME_MANAGEMENT_PAGE = "ChromeManagementPageAndroid"; public static final String CHROME_NEW_DOWNLOAD_TAB = "ChromeNewDownloadTab"; public static final String CHROME_SHARE_LONG_SCREENSHOT = "ChromeShareLongScreenshot"; public static final String CHROME_SHARING_HUB = "ChromeSharingHub";
diff --git a/chrome/browser/image_editor/public/BUILD.gn b/chrome/browser/image_editor/public/BUILD.gn index 6fb3007..1b45913 100644 --- a/chrome/browser/image_editor/public/BUILD.gn +++ b/chrome/browser/image_editor/public/BUILD.gn
@@ -10,7 +10,6 @@ deps = [ "//base:base_java", "//chrome/browser/share:java", - "//third_party/android_deps:android_support_v7_appcompat_java", "//ui/android:ui_no_recycler_view_java", ] }
diff --git a/chrome/browser/media/webrtc/system_media_capture_permissions_mac.mm b/chrome/browser/media/webrtc/system_media_capture_permissions_mac.mm index 06c05f5..409d86b 100644 --- a/chrome/browser/media/webrtc/system_media_capture_permissions_mac.mm +++ b/chrome/browser/media/webrtc/system_media_capture_permissions_mac.mm
@@ -10,12 +10,12 @@ #include "base/callback_helpers.h" #include "base/command_line.h" #include "base/feature_list.h" +#include "base/logging.h" #include "base/mac/foundation_util.h" #include "base/mac/scoped_cftyperef.h" #include "base/no_destructor.h" -#include "base/notreached.h" +#include "base/task/post_task.h" #include "base/task/task_traits.h" -#include "base/task/thread_pool.h" #include "chrome/browser/media/webrtc/media_authorization_wrapper_mac.h" #include "chrome/common/chrome_features.h" #include "content/public/browser/browser_task_traits.h" @@ -60,14 +60,14 @@ const base::TaskTraits& traits) override { if (@available(macOS 10.14, *)) { __block base::OnceClosure block_callback = std::move(callback); - [AVCaptureDevice - requestAccessForMediaType:media_type - completionHandler:^(BOOL granted) { - base::ThreadPool::PostTask(FROM_HERE, traits, - std::move(block_callback)); - }]; + [AVCaptureDevice requestAccessForMediaType:media_type + completionHandler:^(BOOL granted) { + base::PostTask(FROM_HERE, traits, + std::move(block_callback)); + }]; } else { NOTREACHED(); + base::PostTask(FROM_HERE, traits, std::move(callback)); } } }; @@ -120,7 +120,7 @@ base::OnceClosure callback, const base::TaskTraits& traits) { if (UsingFakeMediaDevices()) { - base::ThreadPool::PostTask(FROM_HERE, traits, std::move(callback)); + base::PostTask(FROM_HERE, traits, std::move(callback)); return; } @@ -128,10 +128,11 @@ GetMediaAuthorizationWrapper().RequestAccessForMediaType( media_type, std::move(callback), traits); } else { + NOTREACHED(); // Should never happen since for pre-10.14 system permissions don't exist // and checking them in CheckSystemAudioCapturePermission() will always // return allowed, and this function should not be called. - NOTREACHED(); + base::PostTask(FROM_HERE, traits, std::move(callback)); } }
diff --git a/chrome/browser/metrics/power/power_metrics.cc b/chrome/browser/metrics/power/power_metrics.cc new file mode 100644 index 0000000..73e67ef --- /dev/null +++ b/chrome/browser/metrics/power/power_metrics.cc
@@ -0,0 +1,215 @@ +// 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/metrics/power/power_metrics.h" + +#include <string> + +#include "base/metrics/histogram_functions.h" +#include "base/strings/strcat.h" +#include "chrome/browser/performance_monitor/process_metrics_recorder_util.h" +#include "chrome/browser/performance_monitor/process_monitor.h" + +#if BUILDFLAG(IS_MAC) +#include "base/mac/mac_util.h" +#endif + +namespace { + +constexpr const char* kBatteryDischargeRateHistogramName = + "Power.BatteryDischargeRate2"; +constexpr const char* kBatteryDischargeModeHistogramName = + "Power.BatteryDischargeMode"; + +#if BUILDFLAG(IS_MAC) +// Reports `proportion` of a time used to a histogram in permyriad (1/100 %). +// `proportion` is 0.5 if half a CPU core or half total GPU time is used. It can +// be above 1.0 if more than 1 CPU core is used. CPU and GPU usage is often +// below 1% so it's useful to report with 1/10000 granularity (otherwise most +// samples end up in the same bucket). +void UsageTimeHistogram(const std::string& histogram_name, + double proportion, + int max_proportion) { + // Multiplicator to convert `proportion` to permyriad (1/100 %). + // For example, 1.0 * kScaleFactor = 10000 1/100 % = 100 %. + constexpr int kScaleFactor = 100 * 100; + + base::UmaHistogramCustomCounts( + histogram_name, std::lroundl(proportion * kScaleFactor), + /* min=*/1, /* exclusive_max=*/max_proportion * kScaleFactor, + /* buckets=*/50); +} + +// Max proportion for CPU time histograms. This used to be 64 but was reduced to +// 2 because data shows that less than 0.2% of samples are above that. +constexpr int kMaxCPUProportion = 2; + +// Max proportion for GPU time histograms. It's not possible to use more than +// 100% of total GPU time. +constexpr int kMaxGPUProportion = 1; +#endif // BUILDFLAG(IS_MAC) + +} // namespace + +void ReportAggregatedProcessMetricsHistograms( + const performance_monitor::ProcessMonitor::Metrics& + aggregated_process_metrics, + const std::vector<const char*>& suffixes) { + for (const char* suffix : suffixes) { + std::string complete_suffix = base::StrCat({"Total", suffix}); + performance_monitor::RecordProcessHistograms(complete_suffix.c_str(), + aggregated_process_metrics); + } +} + +void ReportBatteryHistograms(base::TimeDelta interval_duration, + BatteryDischarge battery_discharge, + const std::vector<const char*>& suffixes) { + // Ratio by which the time elapsed can deviate from + // |ProcessMonitor::kGatherInterval| without invalidating this sample. + constexpr double kTolerableTimeElapsedRatio = 0.10; + constexpr double kTolerablePositiveDrift = (1. + kTolerableTimeElapsedRatio); + constexpr double kTolerableNegativeDrift = (1. - kTolerableTimeElapsedRatio); + + if (battery_discharge.mode == BatteryDischargeMode::kDischarging && + interval_duration > performance_monitor::ProcessMonitor::kGatherInterval * + kTolerablePositiveDrift) { + // Too much time passed since the last record. Either the task took + // too long to get executed or system sleep took place. + battery_discharge.mode = BatteryDischargeMode::kInvalidInterval; + } + + if (battery_discharge.mode == BatteryDischargeMode::kDischarging && + interval_duration < performance_monitor::ProcessMonitor::kGatherInterval * + kTolerableNegativeDrift) { + // The recording task executed too early after the previous one, possibly + // because the previous task took too long to execute. + battery_discharge.mode = BatteryDischargeMode::kInvalidInterval; + } + + for (const char* suffix : suffixes) { + base::UmaHistogramEnumeration( + base::StrCat({kBatteryDischargeModeHistogramName, suffix}), + battery_discharge.mode); + + if (battery_discharge.mode == BatteryDischargeMode::kDischarging) { + DCHECK(battery_discharge.rate.has_value()); + base::UmaHistogramCounts1000( + base::StrCat({kBatteryDischargeRateHistogramName, suffix}), + *battery_discharge.rate); + } + } +} + +#if BUILDFLAG(IS_MAC) +void ReportShortIntervalHistograms( + const char* scenario_suffix, + absl::optional<power_metrics::CoalitionResourceUsageRate> + coalition_resource_usage_rate) { + if (!coalition_resource_usage_rate.has_value()) + return; + + for (const char* suffix : {"", scenario_suffix}) { + UsageTimeHistogram( + base::StrCat( + {"PerformanceMonitor.ResourceCoalition.CPUTime2_10sec", suffix}), + coalition_resource_usage_rate->cpu_time_per_second, kMaxCPUProportion); + } +} + +void ReportResourceCoalitionHistograms( + const power_metrics::CoalitionResourceUsageRate& rate, + const std::vector<const char*>& suffixes) { + // Calling this function with an empty suffix list is probably a mistake. + DCHECK(!suffixes.empty()); + + // TODO(crbug.com/1229884): Review the units and buckets once we have + // sufficient data from the field. + + for (const char* scenario_suffix : suffixes) { + // Suffixes are expected to be empty or starting by a period. + DCHECK(::strlen(scenario_suffix) == 0U || scenario_suffix[0] == '.'); + + UsageTimeHistogram( + base::StrCat( + {"PerformanceMonitor.ResourceCoalition.CPUTime2", scenario_suffix}), + rate.cpu_time_per_second, kMaxCPUProportion); + UsageTimeHistogram( + base::StrCat( + {"PerformanceMonitor.ResourceCoalition.GPUTime2", scenario_suffix}), + rate.gpu_time_per_second, kMaxGPUProportion); + + // Report the metrics based on a count (e.g. wakeups) with a millievent/sec + // granularity. In theory it doesn't make much sense to talk about a + // milliwakeups but the wakeup rate should ideally be lower than one per + // second in some scenarios and this will provide more granularity. + constexpr int kMilliFactor = 1000; + auto scale_sample = [](double sample) -> int { + // Round the sample to the nearest integer value. + return std::roundl(sample * kMilliFactor); + }; + base::UmaHistogramCounts1M( + base::StrCat( + {"PerformanceMonitor.ResourceCoalition.InterruptWakeupsPerSecond", + scenario_suffix}), + scale_sample(rate.interrupt_wakeups_per_second)); + base::UmaHistogramCounts1M( + base::StrCat({"PerformanceMonitor.ResourceCoalition." + "PlatformIdleWakeupsPerSecond", + scenario_suffix}), + scale_sample(rate.platform_idle_wakeups_per_second)); + base::UmaHistogramCounts10M( + base::StrCat( + {"PerformanceMonitor.ResourceCoalition.BytesReadPerSecond2", + scenario_suffix}), + rate.bytesread_per_second); + base::UmaHistogramCounts10M( + base::StrCat( + {"PerformanceMonitor.ResourceCoalition.BytesWrittenPerSecond2", + scenario_suffix}), + rate.byteswritten_per_second); + + // EnergyImpact is reported in centi-EI, so scaled up by a factor of 100 + // for the histogram recording. + if (rate.energy_impact_per_second.has_value()) { + constexpr double kEnergyImpactScalingFactor = 100.0; + base::UmaHistogramCounts100000( + base::StrCat({"PerformanceMonitor.ResourceCoalition.EnergyImpact", + scenario_suffix}), + std::roundl(rate.energy_impact_per_second.value() * + kEnergyImpactScalingFactor)); + } + + // As of Feb 2, 2022, the value of `rate->power_nw` is always zero on Intel. + // Don't report it to avoid polluting the data. + if (base::mac::GetCPUType() == base::mac::CPUType::kArm) { + constexpr int kMilliWattPerWatt = 1000; + constexpr int kNanoWattPerMilliWatt = 1000 * 1000; + // The maximum is 10 watts, which is larger than the 99.99th percentile + // as of Feb 2, 2022. + base::UmaHistogramCustomCounts( + base::StrCat( + {"PerformanceMonitor.ResourceCoalition.Power2", scenario_suffix}), + std::roundl(rate.power_nw / kNanoWattPerMilliWatt), + /* min=*/1, /* exclusive_max=*/10 * kMilliWattPerWatt, + /* buckets=*/50); + } + + auto record_qos_level = [&](size_t index, const char* qos_suffix) { + UsageTimeHistogram( + base::StrCat({"PerformanceMonitor.ResourceCoalition.QoSLevel.", + qos_suffix, scenario_suffix}), + rate.qos_time_per_second[index], kMaxCPUProportion); + }; + + record_qos_level(THREAD_QOS_DEFAULT, "Default"); + record_qos_level(THREAD_QOS_MAINTENANCE, "Maintenance"); + record_qos_level(THREAD_QOS_BACKGROUND, "Background"); + record_qos_level(THREAD_QOS_UTILITY, "Utility"); + record_qos_level(THREAD_QOS_LEGACY, "Legacy"); + record_qos_level(THREAD_QOS_USER_INITIATED, "UserInitiated"); + record_qos_level(THREAD_QOS_USER_INTERACTIVE, "UserInteractive"); + } +} +#endif // BUILDFLAG(IS_MAC)
diff --git a/chrome/browser/metrics/power/power_metrics.h b/chrome/browser/metrics/power/power_metrics.h new file mode 100644 index 0000000..7b5401c --- /dev/null +++ b/chrome/browser/metrics/power/power_metrics.h
@@ -0,0 +1,63 @@ +// 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_METRICS_POWER_POWER_METRICS_H_ +#define CHROME_BROWSER_METRICS_POWER_POWER_METRICS_H_ + +#include <vector> + +#include "base/time/time.h" +#include "build/build_config.h" +#include "chrome/browser/performance_monitor/process_monitor.h" +#include "third_party/abseil-cpp/absl/types/optional.h" + +#if BUILDFLAG(IS_MAC) +#include "chrome/browser/metrics/power/coalition_resource_usage_provider_mac.h" +#include "components/power_metrics/resource_coalition_mac.h" +#endif + +// Report aggregated process metrics to histograms with |suffixes|. +void ReportAggregatedProcessMetricsHistograms( + const performance_monitor::ProcessMonitor::Metrics& + aggregated_process_metrics, + const std::vector<const char*>& suffixes); + +// Any change to this enum should be reflected in the corresponding enums.xml +// and ukm.xml +enum class BatteryDischargeMode { + kDischarging = 0, + kPluggedIn = 1, + kStateChanged = 2, + kChargeLevelUnavailable = 3, + kNoBattery = 4, + kBatteryLevelIncreased = 5, + kInvalidInterval = 6, + kMacFullyCharged = 7, + kMaxValue = kMacFullyCharged +}; + +struct BatteryDischarge { + BatteryDischargeMode mode; + // Discharge rate in 1/10000 of full capacity per minute. + absl::optional<int64_t> rate; +}; + +// Report battery metrics to histograms with |suffixes|. +void ReportBatteryHistograms(base::TimeDelta interval_duration, + BatteryDischarge battery_discharge, + const std::vector<const char*>& suffixes); + +#if BUILDFLAG(IS_MAC) +void ReportShortIntervalHistograms( + const char* scenario_suffix, + absl::optional<power_metrics::CoalitionResourceUsageRate> + coalition_resource_usage_rate); + +// Report resource coalition metrics to histograms with |suffixes|. +void ReportResourceCoalitionHistograms( + const power_metrics::CoalitionResourceUsageRate& rate, + const std::vector<const char*>& suffixes); +#endif // BUILDFLAG(IS_MAC) + +#endif // CHROME_BROWSER_METRICS_POWER_POWER_METRICS_H_
diff --git a/chrome/browser/metrics/power/power_metrics_reporter.cc b/chrome/browser/metrics/power/power_metrics_reporter.cc index d5fc70c..65a9a39b 100644 --- a/chrome/browser/metrics/power/power_metrics_reporter.cc +++ b/chrome/browser/metrics/power/power_metrics_reporter.cc
@@ -22,47 +22,13 @@ #include "services/metrics/public/cpp/ukm_source_id.h" #if BUILDFLAG(IS_MAC) -#include "base/mac/mac_util.h" #include "components/power_metrics/resource_coalition_mac.h" #endif // BUILDFLAG(IS_MAC) namespace { - -constexpr const char* kBatteryDischargeRateHistogramName = - "Power.BatteryDischargeRate2"; -constexpr const char* kBatteryDischargeModeHistogramName = - "Power.BatteryDischargeMode"; constexpr const char* kBatterySamplingDelayHistogramName = "Power.BatterySamplingDelay"; -#if BUILDFLAG(IS_MAC) -// Reports `proportion` of a time used to a histogram in permyriad (1/100 %). -// `proportion` is 0.5 if half a CPU core or half total GPU time is used. It can -// be above 1.0 if more than 1 CPU core is used. CPU and GPU usage is often -// below 1% so it's useful to report with 1/10000 granularity (otherwise most -// samples end up in the same bucket). -void UsageTimeHistogram(const std::string& histogram_name, - double proportion, - int max_proportion) { - // Multiplicator to convert `proportion` to permyriad (1/100 %). - // For example, 1.0 * kScaleFactor = 10000 1/100 % = 100 %. - constexpr int kScaleFactor = 100 * 100; - - base::UmaHistogramCustomCounts( - histogram_name, std::lroundl(proportion * kScaleFactor), - /* min=*/1, /* exclusive_max=*/max_proportion * kScaleFactor, - /* buckets=*/50); -} - -// Max proportion for CPU time histograms. This used to be 64 but was reduced to -// 2 because data shows that less than 0.2% of samples are above that. -constexpr int kMaxCPUProportion = 2; - -// Max proportion for GPU time histograms. It's not possible to use more than -// 100% of total GPU time. -constexpr int kMaxGPUProportion = 1; -#endif // BUILDFLAG(IS_MAC) - // Calculates the UKM bucket |value| falls in and returns it. This uses an // exponential bucketing approach with an exponent base of 1.3, resulting in // 17 buckets for an interval of 120 seconds. @@ -195,21 +161,6 @@ } #if BUILDFLAG(IS_MAC) -// static -void PowerMetricsReporter::ReportShortIntervalHistograms( - const char* scenario_suffix, - absl::optional<CoalitionResourceUsageRate> coalition_resource_usage_rate) { - if (!coalition_resource_usage_rate.has_value()) - return; - - for (const char* suffix : {"", scenario_suffix}) { - UsageTimeHistogram( - base::StrCat( - {"PerformanceMonitor.ResourceCoalition.CPUTime2_10sec", suffix}), - coalition_resource_usage_rate->cpu_time_per_second, kMaxCPUProportion); - } -} - void PowerMetricsReporter::MaybeEmitHighCPUTraceEvent( const ScenarioParams& short_interval_scenario_params, absl::optional<CoalitionResourceUsageRate> coalition_resource_usage_rate) { @@ -231,47 +182,6 @@ } #endif // BUILDFLAG(IS_MAC) -// static -void PowerMetricsReporter::ReportBatteryHistograms( - base::TimeDelta interval_duration, - BatteryDischarge battery_discharge, - const std::vector<const char*>& suffixes) { - // Ratio by which the time elapsed can deviate from - // |ProcessMonitor::kGatherInterval| without invalidating this sample. - constexpr double kTolerableTimeElapsedRatio = 0.10; - constexpr double kTolerablePositiveDrift = (1. + kTolerableTimeElapsedRatio); - constexpr double kTolerableNegativeDrift = (1. - kTolerableTimeElapsedRatio); - - if (battery_discharge.mode == BatteryDischargeMode::kDischarging && - interval_duration > - ProcessMonitor::kGatherInterval * kTolerablePositiveDrift) { - // Too much time passed since the last record. Either the task took - // too long to get executed or system sleep took place. - battery_discharge.mode = BatteryDischargeMode::kInvalidInterval; - } - - if (battery_discharge.mode == BatteryDischargeMode::kDischarging && - interval_duration < - ProcessMonitor::kGatherInterval * kTolerableNegativeDrift) { - // The recording task executed too early after the previous one, possibly - // because the previous task took too long to execute. - battery_discharge.mode = BatteryDischargeMode::kInvalidInterval; - } - - for (const char* suffix : suffixes) { - base::UmaHistogramEnumeration( - base::StrCat({kBatteryDischargeModeHistogramName, suffix}), - battery_discharge.mode); - - if (battery_discharge.mode == BatteryDischargeMode::kDischarging) { - DCHECK(battery_discharge.rate.has_value()); - base::UmaHistogramCounts1000( - base::StrCat({kBatteryDischargeRateHistogramName, suffix}), - *battery_discharge.rate); - } - } -} - void PowerMetricsReporter::OnFirstBatteryStateSampled( const BatteryLevelProvider::BatteryState& battery_state) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); @@ -343,116 +253,6 @@ std::move(on_battery_sampled_for_testing_).Run(); } -// static -void PowerMetricsReporter::ReportAggregatedProcessMetricsHistograms( - const ProcessMonitor::Metrics& aggregated_process_metrics, - const std::vector<const char*>& suffixes) { - for (const char* suffix : suffixes) { - std::string complete_suffix = base::StrCat({"Total", suffix}); - performance_monitor::RecordProcessHistograms(complete_suffix.c_str(), - aggregated_process_metrics); - } -} - -#if BUILDFLAG(IS_MAC) -// static -void PowerMetricsReporter::ReportResourceCoalitionHistograms( - const power_metrics::CoalitionResourceUsageRate& rate, - const std::vector<const char*>& suffixes) { - // Calling this function with an empty suffix list is probably a mistake. - DCHECK(!suffixes.empty()); - - // TODO(crbug.com/1229884): Review the units and buckets once we have - // sufficient data from the field. - - for (const char* scenario_suffix : suffixes) { - // Suffixes are expected to be empty or starting by a period. - DCHECK(::strlen(scenario_suffix) == 0U || scenario_suffix[0] == '.'); - - UsageTimeHistogram( - base::StrCat( - {"PerformanceMonitor.ResourceCoalition.CPUTime2", scenario_suffix}), - rate.cpu_time_per_second, kMaxCPUProportion); - UsageTimeHistogram( - base::StrCat( - {"PerformanceMonitor.ResourceCoalition.GPUTime2", scenario_suffix}), - rate.gpu_time_per_second, kMaxGPUProportion); - - // Report the metrics based on a count (e.g. wakeups) with a millievent/sec - // granularity. In theory it doesn't make much sense to talk about a - // milliwakeups but the wakeup rate should ideally be lower than one per - // second in some scenarios and this will provide more granularity. - constexpr int kMilliFactor = 1000; - auto scale_sample = [](double sample) -> int { - // Round the sample to the nearest integer value. - return std::roundl(sample * kMilliFactor); - }; - base::UmaHistogramCounts1M( - base::StrCat( - {"PerformanceMonitor.ResourceCoalition.InterruptWakeupsPerSecond", - scenario_suffix}), - scale_sample(rate.interrupt_wakeups_per_second)); - base::UmaHistogramCounts1M( - base::StrCat({"PerformanceMonitor.ResourceCoalition." - "PlatformIdleWakeupsPerSecond", - scenario_suffix}), - scale_sample(rate.platform_idle_wakeups_per_second)); - base::UmaHistogramCounts10M( - base::StrCat( - {"PerformanceMonitor.ResourceCoalition.BytesReadPerSecond2", - scenario_suffix}), - rate.bytesread_per_second); - base::UmaHistogramCounts10M( - base::StrCat( - {"PerformanceMonitor.ResourceCoalition.BytesWrittenPerSecond2", - scenario_suffix}), - rate.byteswritten_per_second); - - // EnergyImpact is reported in centi-EI, so scaled up by a factor of 100 - // for the histogram recording. - if (rate.energy_impact_per_second.has_value()) { - constexpr double kEnergyImpactScalingFactor = 100.0; - base::UmaHistogramCounts100000( - base::StrCat({"PerformanceMonitor.ResourceCoalition.EnergyImpact", - scenario_suffix}), - std::roundl(rate.energy_impact_per_second.value() * - kEnergyImpactScalingFactor)); - } - - // As of Feb 2, 2022, the value of `rate->power_nw` is always zero on Intel. - // Don't report it to avoid polluting the data. - if (base::mac::GetCPUType() == base::mac::CPUType::kArm) { - constexpr int kMilliWattPerWatt = 1000; - constexpr int kNanoWattPerMilliWatt = 1000 * 1000; - // The maximum is 10 watts, which is larger than the 99.99th percentile - // as of Feb 2, 2022. - base::UmaHistogramCustomCounts( - base::StrCat( - {"PerformanceMonitor.ResourceCoalition.Power2", scenario_suffix}), - std::roundl(rate.power_nw / kNanoWattPerMilliWatt), - /* min=*/1, /* exclusive_max=*/10 * kMilliWattPerWatt, - /* buckets=*/50); - } - - auto record_qos_level = [&](size_t index, const char* qos_suffix) { - UsageTimeHistogram( - base::StrCat({"PerformanceMonitor.ResourceCoalition.QoSLevel.", - qos_suffix, scenario_suffix}), - rate.qos_time_per_second[index], kMaxCPUProportion); - }; - - record_qos_level(THREAD_QOS_DEFAULT, "Default"); - record_qos_level(THREAD_QOS_MAINTENANCE, "Maintenance"); - record_qos_level(THREAD_QOS_BACKGROUND, "Background"); - record_qos_level(THREAD_QOS_UTILITY, "Utility"); - record_qos_level(THREAD_QOS_LEGACY, "Legacy"); - record_qos_level(THREAD_QOS_USER_INITIATED, "UserInitiated"); - record_qos_level(THREAD_QOS_USER_INTERACTIVE, "UserInteractive"); - } -} -#endif // BUILDFLAG(IS_MAC) - -// static void PowerMetricsReporter::ReportUKMs( const UsageScenarioDataStore::IntervalData& interval_data, const ProcessMonitor::Metrics& metrics, @@ -526,8 +326,7 @@ builder.Record(ukm_recorder); } -PowerMetricsReporter::BatteryDischarge -PowerMetricsReporter::GetBatteryDischargeDuringInterval( +BatteryDischarge PowerMetricsReporter::GetBatteryDischargeDuringInterval( const BatteryLevelProvider::BatteryState& new_battery_state, base::TimeDelta interval_duration) { auto previous_battery_state =
diff --git a/chrome/browser/metrics/power/power_metrics_reporter.h b/chrome/browser/metrics/power/power_metrics_reporter.h index 5277a97d..897e479 100644 --- a/chrome/browser/metrics/power/power_metrics_reporter.h +++ b/chrome/browser/metrics/power/power_metrics_reporter.h
@@ -5,14 +5,13 @@ #ifndef CHROME_BROWSER_METRICS_POWER_POWER_METRICS_REPORTER_H_ #define CHROME_BROWSER_METRICS_POWER_POWER_METRICS_REPORTER_H_ -#include <stdint.h> #include <memory> #include <utility> -#include "base/gtest_prod_util.h" #include "base/time/time.h" #include "build/build_config.h" #include "chrome/browser/metrics/power/battery_level_provider.h" +#include "chrome/browser/metrics/power/power_metrics.h" #include "chrome/browser/metrics/power/usage_scenario.h" #include "chrome/browser/metrics/usage_scenario/usage_scenario_data_store.h" #include "chrome/browser/metrics/usage_scenario/usage_scenario_tracker.h" @@ -94,26 +93,6 @@ static int64_t GetBucketForSampleForTesting(base::TimeDelta value); protected: - // Any change to this enum should be reflected in the corresponding enums.xml - // and ukm.xml - enum class BatteryDischargeMode { - kDischarging = 0, - kPluggedIn = 1, - kStateChanged = 2, - kChargeLevelUnavailable = 3, - kNoBattery = 4, - kBatteryLevelIncreased = 5, - kInvalidInterval = 6, - kMacFullyCharged = 7, - kMaxValue = kMacFullyCharged - }; - - struct BatteryDischarge { - PowerMetricsReporter::BatteryDischargeMode mode; - // Discharge rate in 1/10000 of full capacity per minute. - absl::optional<int64_t> rate; - }; - static void ReportLongIntervalHistograms( const UsageScenarioDataStore::IntervalData& interval_data, const ProcessMonitor::Metrics& aggregated_process_metrics, @@ -127,33 +106,12 @@ ); #if BUILDFLAG(IS_MAC) - static void ReportShortIntervalHistograms( - const char* scenario_suffix, - absl::optional<CoalitionResourceUsageRate> coalition_resource_usage_rate); - // Emit trace event when CPU usage is high for 10 secondes or more. void MaybeEmitHighCPUTraceEvent( const ScenarioParams& short_interval_scenario_params, absl::optional<CoalitionResourceUsageRate> coalition_resource_usage_rate); #endif // BUILDFLAG(IS_MAC) - // Report battery metrics to histograms with |suffixes|. - static void ReportBatteryHistograms(base::TimeDelta interval_duration, - BatteryDischarge battery_discharge, - const std::vector<const char*>& suffixes); - - // Report aggregated process metrics to histograms with |suffixes|. - static void ReportAggregatedProcessMetricsHistograms( - const ProcessMonitor::Metrics& aggregated_process_metrics, - const std::vector<const char*>& suffixes); - -#if BUILDFLAG(IS_MAC) - // Report resource coalition metrics to histograms with |suffixes|. - static void ReportResourceCoalitionHistograms( - const power_metrics::CoalitionResourceUsageRate& rate, - const std::vector<const char*>& suffixes); -#endif // BUILDFLAG(IS_MAC) - private: // ProcessMonitor::Observer: void OnAggregatedMetricsSampled(
diff --git a/chrome/browser/metrics/power/power_metrics_reporter_unittest.cc b/chrome/browser/metrics/power/power_metrics_reporter_unittest.cc index 395e6a06..a356187 100644 --- a/chrome/browser/metrics/power/power_metrics_reporter_unittest.cc +++ b/chrome/browser/metrics/power/power_metrics_reporter_unittest.cc
@@ -22,7 +22,6 @@ #include "testing/gtest/include/gtest/gtest.h" #if BUILDFLAG(IS_MAC) -#include "base/mac/mac_util.h" #include "chrome/browser/metrics/power/coalition_resource_usage_provider_test_util_mac.h" #include "components/power_metrics/resource_coalition_mac.h" #endif @@ -36,9 +35,6 @@ constexpr base::TimeDelta kExpectedMetricsCollectionInterval = base::Seconds(120); -constexpr double kTolerableTimeElapsedRatio = 0.10; -constexpr double kTolerablePositiveDrift = 1 + kTolerableTimeElapsedRatio; -constexpr double kTolerableNegativeDrift = 1 - kTolerableTimeElapsedRatio; performance_monitor::ProcessMonitor::Metrics GetFakeProcessMetrics() { performance_monitor::ProcessMonitor::Metrics metrics; @@ -46,25 +42,6 @@ return metrics; } -#if BUILDFLAG(IS_MAC) -power_metrics::CoalitionResourceUsageRate GetFakeResourceUsageRate() { - power_metrics::CoalitionResourceUsageRate rate; - rate.cpu_time_per_second = 0.5; - rate.interrupt_wakeups_per_second = 10; - rate.platform_idle_wakeups_per_second = 11; - rate.bytesread_per_second = 12; - rate.byteswritten_per_second = 13; - rate.gpu_time_per_second = 0.6; - rate.energy_impact_per_second = 15; - rate.power_nw = 1000000; - - for (int i = 0; i < COALITION_NUM_THREAD_QOS_TYPES; ++i) - rate.qos_time_per_second[i] = 0.1 * i; - - return rate; -} -#endif // BUILDFLAG(IS_MAC) - struct HistogramSampleExpectation { std::string histogram_name_prefix; base::Histogram::Sample sample; @@ -90,25 +67,6 @@ using UkmEntry = ukm::builders::PowerUsageScenariosIntervalData; -class PowerMetricsReporterAccess : public PowerMetricsReporter { - public: - using PowerMetricsReporter::PowerMetricsReporter; - - // Expose members of PowerMetricsReporter publicly on - // PowerMetricsReporterAccess. - using PowerMetricsReporter::BatteryDischarge; - using PowerMetricsReporter::BatteryDischargeMode; - using PowerMetricsReporter::ReportBatteryHistograms; - using PowerMetricsReporter::ReportLongIntervalHistograms; -#if BUILDFLAG(IS_MAC) - using PowerMetricsReporter::ReportResourceCoalitionHistograms; - using PowerMetricsReporter::ReportShortIntervalHistograms; -#endif // BUILDFLAG(IS_MAC) -}; - -using BatteryDischargeMode = PowerMetricsReporterAccess::BatteryDischargeMode; -using BatteryDischarge = PowerMetricsReporterAccess::BatteryDischarge; - class FakeBatteryLevelProvider : public BatteryLevelProvider { public: explicit FakeBatteryLevelProvider( @@ -628,66 +586,6 @@ BatteryDischargeMode::kBatteryLevelIncreased, 1); } -TEST_F(PowerMetricsReporterUnitTest, BatteryDischargeCaptureIsTooEarly) { - UsageScenarioDataStore::IntervalData interval_data; - - PowerMetricsReporterAccess::ReportBatteryHistograms( - (kExpectedMetricsCollectionInterval * kTolerableNegativeDrift) - - base::Seconds(1), - BatteryDischarge{BatteryDischargeMode::kDischarging, 2500}, - GetLongIntervalSuffixes(interval_data)); - - histogram_tester_.ExpectTotalCount(kBatteryDischargeRateHistogramName, 0); - histogram_tester_.ExpectUniqueSample(kBatteryDischargeModeHistogramName, - BatteryDischargeMode::kInvalidInterval, - 1); -} - -TEST_F(PowerMetricsReporterUnitTest, BatteryDischargeCaptureIsEarly) { - UsageScenarioDataStore::IntervalData interval_data; - - PowerMetricsReporterAccess::ReportBatteryHistograms( - (kExpectedMetricsCollectionInterval * kTolerableNegativeDrift) + - base::Seconds(1), - BatteryDischarge{BatteryDischargeMode::kDischarging, 2500}, - GetLongIntervalSuffixes(interval_data)); - - histogram_tester_.ExpectUniqueSample(kBatteryDischargeRateHistogramName, 2500, - 1); - histogram_tester_.ExpectUniqueSample(kBatteryDischargeModeHistogramName, - BatteryDischargeMode::kDischarging, 1); -} - -TEST_F(PowerMetricsReporterUnitTest, BatteryDischargeCaptureIsTooLate) { - UsageScenarioDataStore::IntervalData interval_data; - - PowerMetricsReporterAccess::ReportBatteryHistograms( - (kExpectedMetricsCollectionInterval * kTolerablePositiveDrift) + - base::Seconds(1), - BatteryDischarge{BatteryDischargeMode::kDischarging, 2500}, - GetLongIntervalSuffixes(interval_data)); - - histogram_tester_.ExpectTotalCount(kBatteryDischargeRateHistogramName, 0); - histogram_tester_.ExpectUniqueSample(kBatteryDischargeModeHistogramName, - BatteryDischargeMode::kInvalidInterval, - 1); -} - -TEST_F(PowerMetricsReporterUnitTest, BatteryDischargeCaptureIsLate) { - UsageScenarioDataStore::IntervalData interval_data; - - PowerMetricsReporterAccess::ReportBatteryHistograms( - (kExpectedMetricsCollectionInterval * kTolerablePositiveDrift) - - base::Seconds(1), - BatteryDischarge{BatteryDischargeMode::kDischarging, 2500}, - GetLongIntervalSuffixes(interval_data)); - - histogram_tester_.ExpectUniqueSample(kBatteryDischargeRateHistogramName, 2500, - 1); - histogram_tester_.ExpectUniqueSample(kBatteryDischargeModeHistogramName, - BatteryDischargeMode::kDischarging, 1); -} - TEST_F(PowerMetricsReporterUnitTest, UKMsNoTab) { UsageScenarioDataStore::IntervalData fake_interval_data; @@ -789,82 +687,4 @@ histogram_tester_.ExpectUniqueSample( "PerformanceMonitor.ResourceCoalition.CPUTime2_10sec", 6000, 1); } - -TEST_F(PowerMetricsReporterUnitTest, ShortIntervalHistograms_Emitted) { - const char* kScenarioSuffix = ".AllTabsHidden_Audio"; - - PowerMetricsReporterAccess::ReportShortIntervalHistograms( - kScenarioSuffix, GetFakeResourceUsageRate()); - - const std::vector<const char*> suffixes({"", kScenarioSuffix}); - ExpectHistogramSamples( - &histogram_tester_, suffixes, - {{"PerformanceMonitor.ResourceCoalition.CPUTime2_10sec", 5000}}); -} - -TEST_F(PowerMetricsReporterUnitTest, ResourceCoalitionHistograms) { - base::HistogramTester histogram_tester; - - const std::vector<const char*> suffixes = {"", ".Foo", ".Bar"}; - PowerMetricsReporterAccess::ReportResourceCoalitionHistograms( - GetFakeResourceUsageRate(), suffixes); - - ExpectHistogramSamples( - &histogram_tester, suffixes, - {// These histograms reports the CPU/GPU times as a percentage of - // time with a permyriad granularity, 10% (0.1) will be represented - // as 1000. - {"PerformanceMonitor.ResourceCoalition.CPUTime2", 5000}, - {"PerformanceMonitor.ResourceCoalition.GPUTime2", 6000}, - // These histograms report counts with a millievent/second - // granularity. - {"PerformanceMonitor.ResourceCoalition.InterruptWakeupsPerSecond", - 10000}, - {"PerformanceMonitor.ResourceCoalition." - "PlatformIdleWakeupsPerSecond", - 11000}, - {"PerformanceMonitor.ResourceCoalition.BytesReadPerSecond2", 12}, - {"PerformanceMonitor.ResourceCoalition.BytesWrittenPerSecond2", 13}, - // EI is reported in centi-EI so the data needs to be multiplied by - // 100.0. - {"PerformanceMonitor.ResourceCoalition.EnergyImpact", 1500}, - // The QoS histograms also reports the CPU times as a percentage of - // time with a permyriad granularity. - {"PerformanceMonitor.ResourceCoalition.QoSLevel.Default", 0}, - {"PerformanceMonitor.ResourceCoalition.QoSLevel.Maintenance", 1000}, - {"PerformanceMonitor.ResourceCoalition.QoSLevel.Background", 2000}, - {"PerformanceMonitor.ResourceCoalition.QoSLevel.Utility", 3000}, - {"PerformanceMonitor.ResourceCoalition.QoSLevel.Legacy", 4000}, - {"PerformanceMonitor.ResourceCoalition.QoSLevel.UserInitiated", 5000}, - {"PerformanceMonitor.ResourceCoalition.QoSLevel.UserInteractive", - 6000}}); - - if (base::mac::GetCPUType() == base::mac::CPUType::kArm) { - ExpectHistogramSamples( - &histogram_tester, suffixes, - {// Power is reported in milliwatts (mj/s), the data - // is in nj/s so it has to be divided by 1000000. - {"PerformanceMonitor.ResourceCoalition.Power2", 1}}); - } else { - histogram_tester.ExpectTotalCount( - "PerformanceMonitor.ResourceCoalition.Power2", 0); - } -} - -// Verify that no energy impact histogram is reported when -// `CoalitionResourceUsageRate::energy_impact_per_second` is nullopt. -TEST_F(PowerMetricsReporterUnitTest, - ReportResourceCoalitionHistograms_NoEnergyImpact) { - base::HistogramTester histogram_tester; - power_metrics::CoalitionResourceUsageRate rate = GetFakeResourceUsageRate(); - rate.energy_impact_per_second.reset(); - - std::vector<const char*> suffixes = {"", ".Foo"}; - PowerMetricsReporterAccess::ReportResourceCoalitionHistograms(rate, suffixes); - - histogram_tester.ExpectTotalCount( - "PerformanceMonitor.ResourceCoalition.EnergyImpact", 0); - histogram_tester.ExpectTotalCount( - "PerformanceMonitor.ResourceCoalition.EnergyImpact.Foo", 0); -} #endif // BUILDFLAG(IS_MAC)
diff --git a/chrome/browser/metrics/power/power_metrics_unittest.cc b/chrome/browser/metrics/power/power_metrics_unittest.cc new file mode 100644 index 0000000..19ba754 --- /dev/null +++ b/chrome/browser/metrics/power/power_metrics_unittest.cc
@@ -0,0 +1,254 @@ +// 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/metrics/power/power_metrics.h" + +#include "base/strings/strcat.h" +#include "base/test/metrics/histogram_tester.h" +#include "testing/gtest/include/gtest/gtest.h" + +#if BUILDFLAG(IS_MAC) +#include "base/mac/mac_util.h" +#endif + +namespace { + +constexpr const char* kBatteryDischargeRateHistogramName = + "Power.BatteryDischargeRate2"; +constexpr const char* kBatteryDischargeModeHistogramName = + "Power.BatteryDischargeMode"; + +constexpr base::TimeDelta kExpectedMetricsCollectionInterval = + base::Seconds(120); +constexpr double kTolerableTimeElapsedRatio = 0.10; +constexpr double kTolerablePositiveDrift = 1 + kTolerableTimeElapsedRatio; +constexpr double kTolerableNegativeDrift = 1 - kTolerableTimeElapsedRatio; + +#if BUILDFLAG(IS_MAC) +power_metrics::CoalitionResourceUsageRate GetFakeResourceUsageRate() { + power_metrics::CoalitionResourceUsageRate rate; + rate.cpu_time_per_second = 0.5; + rate.interrupt_wakeups_per_second = 10; + rate.platform_idle_wakeups_per_second = 11; + rate.bytesread_per_second = 12; + rate.byteswritten_per_second = 13; + rate.gpu_time_per_second = 0.6; + rate.energy_impact_per_second = 15; + rate.power_nw = 1000000; + + for (int i = 0; i < COALITION_NUM_THREAD_QOS_TYPES; ++i) + rate.qos_time_per_second[i] = 0.1 * i; + + return rate; +} +#endif // BUILDFLAG(IS_MAC) + +struct HistogramSampleExpectation { + std::string histogram_name_prefix; + base::Histogram::Sample sample; +}; + +// For each histogram named after the combination of prefixes from +// `expectations` and suffixes from `suffixes`, verifies that there is a unique +// sample `expectation.sample`. +void ExpectHistogramSamples( + base::HistogramTester* histogram_tester, + const std::vector<const char*>& suffixes, + const std::vector<HistogramSampleExpectation>& expectations) { + for (const char* suffix : suffixes) { + for (const auto& expectation : expectations) { + std::string histogram_name = + base::StrCat({expectation.histogram_name_prefix, suffix}); + SCOPED_TRACE(histogram_name); + histogram_tester->ExpectUniqueSample(histogram_name, expectation.sample, + 1); + } + } +} + +} // namespace + +TEST(PowerMetricsTest, ReportAggregatedProcessMetricsHistograms) { + base::HistogramTester histogram_tester; + const std::vector<const char*> suffixes = {"", ".Foo", ".Bar"}; + + performance_monitor::ProcessMonitor::Metrics process_metrics; + process_metrics.cpu_usage = 0.20; +#if BUILDFLAG(IS_WIN) + process_metrics.precise_cpu_usage = 0.30; +#endif +#if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || \ + BUILDFLAG(IS_AIX) + // Returns the number of average idle cpu wakeups per second since the last + // time the metric was sampled. + process_metrics.idle_wakeups = 51; +#endif +#if BUILDFLAG(IS_MAC) + // The number of average "package idle exits" per second since the last + // time the metric was sampled. See base/process/process_metrics.h for a + // more detailed explanation. + process_metrics.package_idle_wakeups = 52; + + // "Energy Impact" is a synthetic power estimation metric displayed by macOS + // in Activity Monitor and the battery menu. + process_metrics.energy_impact = 10.00; +#endif + + ReportAggregatedProcessMetricsHistograms(process_metrics, suffixes); + + ExpectHistogramSamples(&histogram_tester, suffixes, { + {"PerformanceMonitor.AverageCPU2.Total", 20}, +#if BUILDFLAG(IS_WIN) + {"PerformanceMonitor.AverageCPU3.Total", 30}, +#endif + +#if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || \ + BUILDFLAG(IS_AIX) + {"PerformanceMonitor.IdleWakeups.Total", 51}, +#endif + +#if BUILDFLAG(IS_MAC) + {"PerformanceMonitor.PackageExitIdleWakeups.Total", 52}, + {"PerformanceMonitor.EnergyImpact.Total", 10}, +#endif + }); +} + +TEST(PowerMetricsTest, BatteryDischargeCaptureIsTooEarly) { + base::HistogramTester histogram_tester; + std::vector<const char*> suffixes = {""}; + + ReportBatteryHistograms( + (kExpectedMetricsCollectionInterval * kTolerableNegativeDrift) - + base::Seconds(1), + BatteryDischarge{BatteryDischargeMode::kDischarging, 2500}, suffixes); + + histogram_tester.ExpectTotalCount(kBatteryDischargeRateHistogramName, 0); + histogram_tester.ExpectUniqueSample(kBatteryDischargeModeHistogramName, + BatteryDischargeMode::kInvalidInterval, + 1); +} + +TEST(PowerMetricsTest, BatteryDischargeCaptureIsEarly) { + base::HistogramTester histogram_tester; + std::vector<const char*> suffixes = {""}; + + ReportBatteryHistograms( + (kExpectedMetricsCollectionInterval * kTolerableNegativeDrift) + + base::Seconds(1), + BatteryDischarge{BatteryDischargeMode::kDischarging, 2500}, suffixes); + + histogram_tester.ExpectUniqueSample(kBatteryDischargeRateHistogramName, 2500, + 1); + histogram_tester.ExpectUniqueSample(kBatteryDischargeModeHistogramName, + BatteryDischargeMode::kDischarging, 1); +} + +TEST(PowerMetricsTest, BatteryDischargeCaptureIsTooLate) { + base::HistogramTester histogram_tester; + std::vector<const char*> suffixes = {""}; + + ReportBatteryHistograms( + (kExpectedMetricsCollectionInterval * kTolerablePositiveDrift) + + base::Seconds(1), + BatteryDischarge{BatteryDischargeMode::kDischarging, 2500}, suffixes); + + histogram_tester.ExpectTotalCount(kBatteryDischargeRateHistogramName, 0); + histogram_tester.ExpectUniqueSample(kBatteryDischargeModeHistogramName, + BatteryDischargeMode::kInvalidInterval, + 1); +} + +TEST(PowerMetricsTest, BatteryDischargeCaptureIsLate) { + base::HistogramTester histogram_tester; + std::vector<const char*> suffixes = {""}; + + ReportBatteryHistograms( + (kExpectedMetricsCollectionInterval * kTolerablePositiveDrift) - + base::Seconds(1), + BatteryDischarge{BatteryDischargeMode::kDischarging, 2500}, suffixes); + + histogram_tester.ExpectUniqueSample(kBatteryDischargeRateHistogramName, 2500, + 1); + histogram_tester.ExpectUniqueSample(kBatteryDischargeModeHistogramName, + BatteryDischargeMode::kDischarging, 1); +} + +#if BUILDFLAG(IS_MAC) +TEST(PowerMetricsTest, ReportShortIntervalHistograms) { + base::HistogramTester histogram_tester; + const char* kScenarioSuffix = ".AllTabsHidden_Audio"; + + ReportShortIntervalHistograms(kScenarioSuffix, GetFakeResourceUsageRate()); + + const std::vector<const char*> suffixes({"", kScenarioSuffix}); + ExpectHistogramSamples( + &histogram_tester, suffixes, + {{"PerformanceMonitor.ResourceCoalition.CPUTime2_10sec", 5000}}); +} + +TEST(PowerMetricsTest, ReportResourceCoalitionHistograms) { + base::HistogramTester histogram_tester; + + const std::vector<const char*> suffixes = {"", ".Foo", ".Bar"}; + ReportResourceCoalitionHistograms(GetFakeResourceUsageRate(), suffixes); + + ExpectHistogramSamples( + &histogram_tester, suffixes, + {// These histograms reports the CPU/GPU times as a percentage of + // time with a permyriad granularity, 10% (0.1) will be represented + // as 1000. + {"PerformanceMonitor.ResourceCoalition.CPUTime2", 5000}, + {"PerformanceMonitor.ResourceCoalition.GPUTime2", 6000}, + // These histograms report counts with a millievent/second + // granularity. + {"PerformanceMonitor.ResourceCoalition.InterruptWakeupsPerSecond", + 10000}, + {"PerformanceMonitor.ResourceCoalition." + "PlatformIdleWakeupsPerSecond", + 11000}, + {"PerformanceMonitor.ResourceCoalition.BytesReadPerSecond2", 12}, + {"PerformanceMonitor.ResourceCoalition.BytesWrittenPerSecond2", 13}, + // EI is reported in centi-EI so the data needs to be multiplied by + // 100.0. + {"PerformanceMonitor.ResourceCoalition.EnergyImpact", 1500}, + // The QoS histograms also reports the CPU times as a percentage of + // time with a permyriad granularity. + {"PerformanceMonitor.ResourceCoalition.QoSLevel.Default", 0}, + {"PerformanceMonitor.ResourceCoalition.QoSLevel.Maintenance", 1000}, + {"PerformanceMonitor.ResourceCoalition.QoSLevel.Background", 2000}, + {"PerformanceMonitor.ResourceCoalition.QoSLevel.Utility", 3000}, + {"PerformanceMonitor.ResourceCoalition.QoSLevel.Legacy", 4000}, + {"PerformanceMonitor.ResourceCoalition.QoSLevel.UserInitiated", 5000}, + {"PerformanceMonitor.ResourceCoalition.QoSLevel.UserInteractive", + 6000}}); + + if (base::mac::GetCPUType() == base::mac::CPUType::kArm) { + ExpectHistogramSamples( + &histogram_tester, suffixes, + {// Power is reported in milliwatts (mj/s), the data + // is in nj/s so it has to be divided by 1000000. + {"PerformanceMonitor.ResourceCoalition.Power2", 1}}); + } else { + histogram_tester.ExpectTotalCount( + "PerformanceMonitor.ResourceCoalition.Power2", 0); + } +} + +// Verify that no energy impact histogram is reported when +// `CoalitionResourceUsageRate::energy_impact_per_second` is nullopt. +TEST(PowerMetricsTest, ReportResourceCoalitionHistograms_NoEnergyImpact) { + base::HistogramTester histogram_tester; + power_metrics::CoalitionResourceUsageRate rate = GetFakeResourceUsageRate(); + rate.energy_impact_per_second.reset(); + + std::vector<const char*> suffixes = {"", ".Foo"}; + ReportResourceCoalitionHistograms(rate, suffixes); + + histogram_tester.ExpectTotalCount( + "PerformanceMonitor.ResourceCoalition.EnergyImpact", 0); + histogram_tester.ExpectTotalCount( + "PerformanceMonitor.ResourceCoalition.EnergyImpact.Foo", 0); +} +#endif // BUILDFLAG(IS_MAC)
diff --git a/chrome/browser/notifications/BUILD.gn b/chrome/browser/notifications/BUILD.gn index ffbd09a..8adb53a3 100644 --- a/chrome/browser/notifications/BUILD.gn +++ b/chrome/browser/notifications/BUILD.gn
@@ -77,8 +77,8 @@ "//components/content_settings/android:content_settings_enums_java", "//components/url_formatter/android:url_formatter_java", "//content/public/android:content_full_java", - "//third_party/android_deps:android_support_v7_appcompat_java", "//third_party/androidx:androidx_annotation_annotation_java", + "//third_party/androidx:androidx_core_core_java", "//ui/android:ui_no_recycler_view_java", ]
diff --git a/chrome/browser/password_manager/password_manager_browsertest.cc b/chrome/browser/password_manager/password_manager_browsertest.cc index 67a339a..2ae27f1c 100644 --- a/chrome/browser/password_manager/password_manager_browsertest.cc +++ b/chrome/browser/password_manager/password_manager_browsertest.cc
@@ -557,7 +557,7 @@ // Need to pay attention for a message that XHR has finished since there // is no navigation to wait for. - content::DOMMessageQueue message_queue; + content::DOMMessageQueue message_queue(WebContents()); BubbleObserver prompt_observer(WebContents()); std::string fill_and_submit = "document.getElementById('username_action_mutation').value = 'temp';" @@ -698,7 +698,7 @@ // Need to pay attention for a message that XHR has finished since there // is no navigation to wait for. - content::DOMMessageQueue message_queue; + content::DOMMessageQueue message_queue(WebContents()); // Verify that if XHR without navigation occurs and the form has been filled // out we try and save the password. Note that in general the submission @@ -727,7 +727,7 @@ // Need to pay attention for a message that XHR has finished since there // is no navigation to wait for. - content::DOMMessageQueue message_queue; + content::DOMMessageQueue message_queue(WebContents()); // Verify that if XHR without navigation occurs and the form has been filled // out we try and save the password. Note that in general the submission @@ -757,7 +757,7 @@ // Need to pay attention for a message that XHR has finished since there // is no navigation to wait for. - content::DOMMessageQueue message_queue; + content::DOMMessageQueue message_queue(WebContents()); // Verify that if XHR without navigation occurs and the form has NOT been // filled out we don't prompt. @@ -783,7 +783,7 @@ // Need to pay attention for a message that XHR has finished since there // is no navigation to wait for. - content::DOMMessageQueue message_queue; + content::DOMMessageQueue message_queue(WebContents()); // Verify that if XHR without navigation occurs and the form has NOT been // filled out we don't prompt. @@ -826,7 +826,7 @@ // Need to pay attention for a message that XHR has finished since there // is no navigation to wait for. - content::DOMMessageQueue message_queue; + content::DOMMessageQueue message_queue(WebContents()); // Verify that if XHR without navigation occurs and the form has been filled // out we try and save the password. Note that in general the submission @@ -855,7 +855,7 @@ // Need to pay attention for a message that Fetch has finished since there // is no navigation to wait for. - content::DOMMessageQueue message_queue; + content::DOMMessageQueue message_queue(WebContents()); // Verify that if Fetch without navigation occurs and the form has been filled // out we try and save the password. Note that in general the submission @@ -886,7 +886,7 @@ // Need to pay attention for a message that Fetch has finished since there // is no navigation to wait for. - content::DOMMessageQueue message_queue; + content::DOMMessageQueue message_queue(WebContents()); // Verify that if Fetch without navigation occurs and the form has NOT been // filled out we don't prompt. @@ -912,7 +912,7 @@ // Need to pay attention for a message that Fetch has finished since there // is no navigation to wait for. - content::DOMMessageQueue message_queue; + content::DOMMessageQueue message_queue(WebContents()); // Verify that if Fetch without navigation occurs and the form has NOT been // filled out we don't prompt. @@ -2167,7 +2167,7 @@ // Need to pay attention for a message that XHR has finished since there // is no navigation to wait for. - content::DOMMessageQueue message_queue; + content::DOMMessageQueue message_queue(WebContents()); BubbleObserver prompt_observer(WebContents()); std::string fill_and_submit =
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/BUILD.gn b/chrome/browser/resources/chromeos/accessibility/chromevox/BUILD.gn index 76ab0414..13e0bf5 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/BUILD.gn +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/BUILD.gn
@@ -54,14 +54,11 @@ "common/abstract_earcons.js", "common/background_bridge.js", "common/braille_interface.js", - "common/bridge_helper.js", "common/extension_bridge.js", "common/key_sequence.js", "common/log_types.js", "common/msgs.js", - "common/panel_bridge.js", "common/panel_command.js", - "common/panel_node_menu_data.js", "common/phonetic_data.js", "common/spannable.js", "common/tree_dumper.js", @@ -116,9 +113,6 @@ "background/math_handler.js", "background/media_automation_handler.js", "background/page_load_sound_handler.js", - "background/panel/i_search.js", - "background/panel/panel_background.js", - "background/panel/panel_node_menu_background.js", "background/pointer_handler.js", "background/prefs.js", "background/range_automation_handler.js", @@ -138,7 +132,7 @@ "log_page/log.js", "options/bluetooth_braille_display_ui.js", "options/options.js", - "panel/i_search_ui.js", + "panel/i_search.js", "panel/panel.js", "panel/panel_interface.js", "panel/panel_menu.js", @@ -446,8 +440,6 @@ "background/logging/log_store_test.js", "background/output/locale_output_helper_test.js", "background/output/output_test.js", - "background/panel/i_search_test.js", - "background/panel/panel_node_menu_background_test.js", "background/portals_test.js", "background/settings_test.js", "background/smart_sticky_mode_test.js", @@ -456,6 +448,7 @@ "learn_mode/learn_mode_test.js", "options/bluetooth_braille_display_ui_test.js", "options/options_test.js", + "panel/i_search_test.js", "panel/panel_test.js", "panel/panel_test_base.js", "panel/tutorial_test.js", @@ -464,7 +457,6 @@ "../common/testing/accessibility_test_base.js", "../common/testing/assert_additions.js", "../common/testing/callback_helper.js", - "../common/testing/documents.js", "../common/testing/e2e_test_base.js", "testing/chromevox_e2e_test_base.js", "testing/chromevox_next_e2e_test_base.js",
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/background.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/background.js index 218ff480..eb48cf9d 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/background.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/background.js
@@ -19,7 +19,6 @@ import {MathHandler} from './math_handler.js'; import {MediaAutomationHandler} from './media_automation_handler.js'; import {PageLoadSoundHandler} from './page_load_sound_handler.js'; -import {PanelBackground} from './panel/panel_background.js'; import {RangeAutomationHandler} from './range_automation_handler.js'; /** @@ -114,7 +113,6 @@ FindHandler.init(); DownloadHandler.init(); - PanelBackground.init(); JaPhoneticData.init(JaPhoneticMap.MAP); chrome.accessibilityPrivate.onAnnounceForAccessibility.addListener(
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/braille/braille_background.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/braille/braille_background.js index 497a4c3..932f172 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/braille/braille_background.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/braille/braille_background.js
@@ -173,7 +173,7 @@ /** @type {?BrailleBackground} */ BrailleBackground.instance_ = null; -BridgeHelper.registerHandler( +BackgroundBridge.registerHandler( /*target=*/ 'BrailleBackground', 'backTranslate', (cells) => new Promise(resolve => { BrailleBackground.getInstance() @@ -182,7 +182,7 @@ .backTranslate(cells, resolve); })); -BridgeHelper.registerHandler( +BackgroundBridge.registerHandler( /*target=*/ 'BrailleBackground', 'refreshBrailleTable', (brailleTable) => BrailleBackground.getInstance().getTranslatorManager().refresh(
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/loader.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/loader.js index cc46aa9..6c74ec0 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/loader.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/loader.js
@@ -11,11 +11,11 @@ goog.require('AutomationTreeWalker'); goog.require('AutomationUtil'); goog.require('AutomationObjectConstructorInstaller'); +goog.require('BackgroundBridge'); goog.require('BrailleDisplayState'); goog.require('BrailleInterface'); goog.require('BrailleKeyCommand'); goog.require('BrailleKeyEvent'); -goog.require('BridgeHelper'); goog.require('ChromeVox'); goog.require('ChromeVoxState'); goog.require('ChromeVoxStateObserver'); @@ -35,10 +35,7 @@ goog.require('NavBraille'); goog.require('Output'); goog.require('OutputEventType'); -goog.require('PanelBridge'); goog.require('PanelCommand'); -goog.require('PanelNodeMenuData'); -goog.require('PanelNodeMenuItemData'); goog.require('PhoneticData'); goog.require('QueueMode'); goog.require('Spannable');
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/panel/i_search.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/panel/i_search.js deleted file mode 100644 index 71a057e..0000000 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/panel/i_search.js +++ /dev/null
@@ -1,113 +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. - -/** - * @fileoverview Class that incrementally searches the ChromeVox menus. - */ -export class ISearch { - /** - * @param {!cursors.Cursor} cursor - */ - constructor(cursor) { - if (!cursor.node) { - throw 'Incremental search started from invalid range.'; - } - - const leaf = - AutomationUtil.findNodePre( - cursor.node, constants.Dir.FORWARD, AutomationPredicate.leaf) || - cursor.node; - - /** @type {!cursors.Cursor} */ - this.cursor = cursors.Cursor.fromNode(leaf); - - /** @private {number} */ - this.callbackId_ = 0; - } - - /** - * Performs a search. - * @param {string} searchStr - * @param {constants.Dir} dir - * @param {boolean=} opt_nextObject - */ - search(searchStr, dir, opt_nextObject) { - this.clear(); - const step = () => { - searchStr = searchStr.toLocaleLowerCase(); - let result = this.cursor.node; - - if (opt_nextObject) { - // We want to start/continue the search at the next object. - result = AutomationUtil.findNextNode( - this.cursor.node, dir, AutomationPredicate.object); - } - - do { - // Ask native to search the underlying data for a performance boost. - result = - result.getNextTextMatch(searchStr, dir === constants.Dir.BACKWARD); - } while (result && !AutomationPredicate.object(result)); - - if (result) { - this.cursor = cursors.Cursor.fromNode(result); - const start = result.name.toLocaleLowerCase().indexOf(searchStr); - const end = start + searchStr.length; - this.onSearchResultChanged_(result, start, end); - } else { - this.onSearchReachedBoundary_(this.cursor.node); - } - }; - - this.callbackId_ = setTimeout(step, 0); - } - - clear() { - clearTimeout(this.callbackId_); - } - - /** - * @param {!chrome.automation.AutomationNode} boundaryNode - * @private - */ - onSearchReachedBoundary_(boundaryNode) { - this.output_(boundaryNode); - ChromeVox.earcons.playEarcon(Earcon.WRAP); - } - - /** - * @param {!chrome.automation.AutomationNode} node - * @param {number} start - * @param {number} end - * @private - */ - onSearchResultChanged_(node, start, end) { - this.output_(node, start, end); - } - - /** - * @param {!chrome.automation.AutomationNode} node - * @param {number=} opt_start - * @param {number=} opt_end - * @private - */ - output_(node, opt_start, opt_end) { - Output.forceModeForNextSpeechUtterance(QueueMode.FLUSH); - const o = new Output(); - if (opt_start && opt_end) { - o.withString([ - node.name.substr(0, opt_start), - node.name.substr(opt_start, opt_end - opt_start), - node.name.substr(opt_end) - ].join(', ')); - o.format('$role', node); - } else { - o.withRichSpeechAndBraille( - cursors.Range.fromNode(node), null, OutputEventType.NAVIGATE); - } - o.go(); - - ChromeVoxState.instance.setCurrentRange(cursors.Range.fromNode(node)); - } -}
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/panel/i_search_test.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/panel/i_search_test.js deleted file mode 100644 index de1678d2..0000000 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/panel/i_search_test.js +++ /dev/null
@@ -1,102 +0,0 @@ -// 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. - -// Include test fixture. -GEN_INCLUDE( - ['//chrome/browser/resources/chromeos/accessibility/chromevox/testing/' + - 'chromevox_next_e2e_test_base.js']); - -/** - * Test fixture for ISearch. - */ -ChromeVoxISearchTest = class extends ChromeVoxNextE2ETest { - constructor() { - super(); - this.expect_ = []; - } - - /** @override */ - async setUpDeferred() { - await super.setUpDeferred(); - await importModule('ISearch', '/chromevox/background/panel/i_search.js'); - } - - overrideOutputFunctions(iSearch) { - iSearch.onSearchReachedBoundary_ = (node) => { - const expectCallback = this.expect_.shift(); - expectCallback({node, isBoundary: true}); - }; - iSearch.onSearchResultChanged_ = (node, start, end) => { - const expectCallback = this.expect_.shift(); - expectCallback({node, start, end}); - }; - } - - expect(str) { - return new Promise(resolve => { - this.expect_.push(this.newCallback(args => { - const node = args.node; - let actual = node.name || node.role; - if (args.start && args.end) { - actual = - 'start=' + args.start + ' end=' + args.end + ' text=' + actual; - } - if (args.isBoundary) { - actual = 'boundary=' + actual; - } - assertEquals(str, actual); - resolve(); - })); - }); - } - - get linksAndHeadingsDoc() { - return ` - <p>start</p> - <a href='#a'>Home</a> - <a href='#b'>About US</a> - <p> - <h1>Latest Breaking News</h1> - <a href='foo'>See more...</a> - </p> - <a href='#bar'>Questions?</a> - <h2>Privacy Policy</h2> - <p>end<span>of test</span></p> - `; - } -}; - -TEST_F('ChromeVoxISearchTest', 'Simple', async function() { - const rootNode = await this.runWithLoadedTree(this.linksAndHeadingsDoc); - const search = new ISearch(new cursors.Cursor(rootNode, 0)); - this.overrideOutputFunctions(search); - - // Simple forward search. - search.search('US', 'forward'); - await this.expect('start=6 end=8 text=About US'); - - search.search('start', 'backward'); - await this.expect('start'); - - // Boundary (beginning). - search.search('foo', 'backward'); - await this.expect('boundary=start'); - - // Boundary (end). - search.search('foo', 'forward'); - // Search "focus" doesn't move. - await this.expect('boundary=start'); - - // Mixed case substring. - search.search('bReak', 'forward'); - await this.expect('start=7 end=12 text=Latest Breaking News'); - - search.search('bReaki', 'forward'); - // Incremental search stays on the current node. - await this.expect('start=7 end=13 text=Latest Breaking News'); - - search.search('bReakio', 'forward'); - // No results for the search. - await this.expect('boundary=Latest Breaking News'); -});
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/panel/panel_background.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/panel/panel_background.js deleted file mode 100644 index d09712a1..0000000 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/panel/panel_background.js +++ /dev/null
@@ -1,78 +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. - -/** - * @fileoverview Handles logic for the ChromeVox panel that requires state from - * the background context. - */ -import {ISearch} from './i_search.js'; - -// This class is imported for its side effects. -import {PanelNodeMenuBackground} from './panel_node_menu_background.js'; - -export class PanelBackground { - /** @private */ - constructor() { - /** @private {ISearch} */ - this.iSearch_; - } - - static init() { - if (PanelBackground.instance) { - throw 'Error: PanelBackground initiated more than once'; - } - PanelBackground.instance = new PanelBackground(); - } - - /** @private */ - createNewISearch_() { - if (this.iSearch_) { - this.iSearch_.clear(); - } - this.iSearch_ = new ISearch(ChromeVoxState.instance.currentRange.start); - } - - /** - * @param {string} searchStr - * @param {constants.Dir} dir - * @param {boolean=} opt_nextObject - * @private - */ - incrementalSearch_(searchStr, dir, opt_nextObject) { - if (!this.iSearch_) { - console.error( - 'Trying to incrementally search when no ISearch has been created.'); - return; - } - - this.iSearch_.search(searchStr, dir, opt_nextObject); - } - - /** @private */ - setRangeToISearchNode_() { - if (!this.iSearch_) { - console.error( - 'Setting range to ISearch node when no ISearch in progress'); - return; - } - - const node = this.iSearch_.cursor.node; - if (!node) { - return; - } - ChromeVoxState.instance.navigateToRange(cursors.Range.fromNode(node)); - } -} - -BridgeHelper.registerHandler( - /* target= */ 'PanelBackground', 'createNewISearch', - () => PanelBackground.instance.createNewISearch_()); -BridgeHelper.registerHandler( - /* target= */ 'PanelBackground', 'incrementalSearch', - ({searchStr, dir, opt_nextObject}) => - PanelBackground.instance.incrementalSearch_( - searchStr, dir, opt_nextObject)); -BridgeHelper.registerHandler( - /* target= */ 'PanelBackground', 'setRangeToISearchNode', - () => PanelBackground.instance.setRangeToISearchNode_());
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/panel/panel_node_menu_background.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/panel/panel_node_menu_background.js deleted file mode 100644 index b03913a4..0000000 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/panel/panel_node_menu_background.js +++ /dev/null
@@ -1,244 +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. - -/** - * @fileoverview Calculates the menu items for the node menus in the ChromeVox - * panel. - */ - -export class PanelNodeMenuBackground { - /** - * @param {!AutomationPredicate.Unary} predicate - * @param {boolean} isActiveMenu - * @private - */ - constructor(predicate, isActiveMenu) { - /** @private {chrome.automation.AutomationNode} */ - this.node_ = ChromeVoxState.instance.currentRange.start; - /** @private {AutomationTreeWalker|undefined} */ - this.walker_; - /** @private {number} */ - this.nodeCount_ = 0; - /** @private {!AutomationPredicate.Unary} */ - this.predicate_ = predicate; - /** @private {boolean} */ - this.isActiveMenu_ = isActiveMenu; - /** @private {boolean} */ - this.hasMenuItems_ = false; - - /** @private {!Array<!function()>} */ - this.menuActionCallbacks_ = []; - /** @private {number} */ - this.menuId_ = PanelNodeMenuBackground.instances_.length; - PanelNodeMenuBackground.instances_.push(this); - - if (this.isActiveMenu_) { - // Put this at the front of the queue so it is calculated first. - PanelNodeMenuBackground.populateQueue_.unshift(this); - } else { - PanelNodeMenuBackground.populateQueue_.push(this); - } - } - - /** - * @param {string=} opt_activateMenuTitle - * @return {!Array<!PanelNodeMenuData>} - */ - static createAllPanelNodeMenuData(opt_activateMenuTitle) { - const dataArray = []; - for (const mapping of PanelNodeMenuBackground.roleListMenuMapping) { - const isActiveMenu = mapping.menuTitle === opt_activateMenuTitle; - dataArray.push(PanelNodeMenuBackground.createData_( - mapping.menuTitle, mapping.predicate, isActiveMenu)); - } - - // Start populating node menus after we return. - setTimeout(PanelNodeMenuBackground.populateAll_, 0); - return dataArray; - } - - /** - * @param {number} menuId - * @param {number} callbackId - */ - static performMenuActionCallback(menuId, callbackId) { - if (menuId >= PanelNodeMenuBackground.instances_.length || menuId < 0) { - throw 'Error: Invalid menu ID provided to performMenuActionCallback'; - } - const instance = PanelNodeMenuBackground.instances_[menuId]; - - if (callbackId >= instance.menuActionCallbacks_.length || callbackId < 0) { - return; - } - - instance.menuActionCallbacks_[callbackId](); - } - - /** - * @param {string} menuTitle - * @param {!AutomationPredicate.Unary} predicate - * @param {boolean} isActiveMenu - * @return {!PanelNodeMenuData} - * @private - */ - static createData_(menuTitle, predicate, isActiveMenu) { - return (new PanelNodeMenuBackground(predicate, isActiveMenu)) - .getData_(menuTitle); - } - - static populateAll_() { - for (const instance of PanelNodeMenuBackground.populateQueue_) { - instance.populate_(); - } - } - - /** - * @param {string} menuTitle - * @private - */ - getData_(menuTitle) { - return new PanelNodeMenuData(menuTitle, this.menuId_); - } - - - /** - * Create the AutomationTreeWalker and kick off the search to find - * nodes that match the predicate for this menu. - * @private - */ - populate_() { - if (!this.node_) { - this.finish_(); - return; - } - - const root = AutomationUtil.getTopLevelRoot(this.node_); - if (!root) { - this.finish_(); - return; - } - - this.walker_ = new AutomationTreeWalker(root, constants.Dir.FORWARD, { - visit(node) { - return !AutomationPredicate.shouldIgnoreNode(node); - } - }); - this.findMoreNodes_(); - } - - /** - * Iterate over nodes from the tree walker. If a node matches the - * predicate, add an item to the menu data. - * - * Unless |this.isActiveMenu_| is true, after MAX_NODES_BEFORE_YIELDING nodes - * have been scanned, call setTimeout to defer searching. This frees - * up the main event loop to keep ChromeVox responsive, otherwise it basically - * freezes up until all of the nodes have been found. - * @private - */ - findMoreNodes_() { - let menuItems = []; - while (this.walker_.next().node) { - const node = this.walker_.node; - if (this.predicate_(node)) { - const isActive = this.isActiveMenu_ && node === this.node_; - - const output = new Output(); - const range = cursors.Range.fromNode(node); - output.withoutHints(); - output.withSpeech(range, range, OutputEventType.NAVIGATE); - const label = output.toString(); - - const indexInArray = this.menuActionCallbacks_.length; - this.menuActionCallbacks_.push( - () => ChromeVoxState.instance.navigateToRange( - cursors.Range.fromNode(node))); - - menuItems.push( - new PanelNodeMenuItemData(label, indexInArray, isActive)); - } - - if (menuItems.length >= PanelNodeMenuBackground.BATCH_SIZE) { - this.sendMenuItemData_(menuItems); - menuItems = []; - } - - this.nodeCount_++; - // If this is not the active menu, yield periodically to avoid blocking - // the user. - if (!this.isActiveMenu_ && - this.nodeCount_ >= - PanelNodeMenuBackground.MAX_NODES_BEFORE_YIELDING) { - this.nodeCount_ = 0; - - if (menuItems.length) { - this.sendMenuItemData_(menuItems); - menuItems = []; - } - - window.setTimeout(() => this.findMoreNodes_(), 0); - return; - } - } - - if (menuItems.length) { - this.sendMenuItemData_(menuItems); - } - this.finish_(); - } - - /** - * @param {!Array<!PanelNodeMenuItemData>} menuItems - * @private - */ - async sendMenuItemData_(menuItems) { - this.hasMenuItems_ = true; - await PanelBridge.addPanelNodeMenuItems(this.menuId_, menuItems); - } - - /** @private */ - finish_() { - if (!this.hasMenuItems_) { - this.sendMenuItemData_([new PanelNodeMenuItemData( - Msgs.getMsg('panel_menu_item_none'), -1, false)]); - } - } -} - -/** - * The number of matching nodes to find before sending the data to the panel UI. - * @const {number} - */ -PanelNodeMenuBackground.BATCH_SIZE = 5; - -/** - * The number of nodes to search before yielding to other tasks. - * @const {number} - */ -PanelNodeMenuBackground.MAX_NODES_BEFORE_YIELDING = 100; - -PanelNodeMenuBackground.roleListMenuMapping = [ - {menuTitle: 'role_heading', predicate: AutomationPredicate.heading}, - {menuTitle: 'role_landmark', predicate: AutomationPredicate.landmark}, - {menuTitle: 'role_link', predicate: AutomationPredicate.link}, { - menuTitle: 'panel_menu_form_controls', - predicate: AutomationPredicate.formField - }, - {menuTitle: 'role_table', predicate: AutomationPredicate.table} -]; - -/** @private {!Array<!PanelNodeMenuBackground>} */ -PanelNodeMenuBackground.instances_ = []; -/** @private {!Array<!PanelNodeMenuBackground>} */ -PanelNodeMenuBackground.populateQueue_ = []; - -BridgeHelper.registerHandler( - /* target= */ 'PanelNodeMenuBackground', 'createAllPanelNodeMenuData', - (opt_activateMenuTitle) => - PanelNodeMenuBackground.createAllPanelNodeMenuData( - opt_activateMenuTitle)); -BridgeHelper.registerHandler( - /* target= */ 'PanelNodeMenuBackground', 'performMenuActionCallback', - ({menuId, callbackId}) => - PanelNodeMenuBackground.performMenuActionCallback(menuId, callbackId));
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/panel/panel_node_menu_background_test.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/panel/panel_node_menu_background_test.js deleted file mode 100644 index 985eda6..0000000 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/panel/panel_node_menu_background_test.js +++ /dev/null
@@ -1,417 +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. - -GEN_INCLUDE([ - '../../../common/testing/documents.js', - '../../testing/chromevox_next_e2e_test_base.js', -]); - -// Fake Msgs object. -const Msgs = { - getMsg: () => 'None' -}; - -// Fake PanelBridge. -const PanelBridge = { - addPanelNodeMenuItems: (id, items) => PanelBridge.calls.append({id, items}), - calls: [], -}; - -/** Test fixture for PanelNodeMenuBackground. */ -ChromeVoxPanelNodeMenuBackgroundTest = class extends ChromeVoxNextE2ETest { - /** @override */ - async setUpDeferred() { - await super.setUpDeferred(); - await importModule( - 'PanelNodeMenuBackground', - '/chromevox/background/panel/panel_node_menu_background.js'); - this.expectedMenuCount = PanelNodeMenuBackground.roleListMenuMapping.length; - } - - // Yield so populateAll_ has a chance to run. - yieldForPopulation() { - return new Promise(resolve => setTimeout(resolve, 0)); - } - - get headingsDoc() { - return `<h1>Heading 1</h1> - <h2>Heading 2</h2> - <h3>Heading 3</h3>`; - } - - get landmarksDoc() { - return [ - Documents.application, - Documents.banner, - Documents.complementary, - Documents.form, - Documents.main, - Documents.navigation, - Documents.region, - Documents.search - ].join('\n'); - } - - get linksDoc() { - return `<a href="#a">Link 1</a> - <a href="#b">Link 2</a> - <a href="#c">Link 3</a> - <a href="#d">Link 4</a> - <p>Not a link</p>`; - } - - get formControlsDoc() { - return [ - Documents.button, - Documents.textInput, - Documents.textarea, - `<p>Static text</p>`, - Documents.checkbox, - Documents.color, - Documents.slider, - Documents.switch, - Documents.tab, - Documents.tree, - `<script> - document.getElementById('tree').focus(); - </script>` - ].join('\n'); - } - - get mixedDoc() { - return [ - Documents.button, - Documents.table, - Documents.region, - Documents.link, - Documents.header - ].join('\n'); - } - - get tablesDoc() { - return [ - Documents.grid, - Documents.table - ].join('\n'); - } -}; - -TEST_F( - 'ChromeVoxPanelNodeMenuBackgroundTest', 'EmptyDocument', async function() { - await this.runWithLoadedTree(''); - const menus = PanelNodeMenuBackground.createAllPanelNodeMenuData(); - assertEquals(this.expectedMenuCount, menus.length); - - // Verify that the menus are created in the expected order. - assertEquals('role_heading', menus[0].title); - assertEquals('role_landmark', menus[1].title); - assertEquals('role_link', menus[2].title); - assertEquals('panel_menu_form_controls', menus[3].title); - assertEquals('role_table', menus[4].title); - - // Verify that menu ids are unique. - for (const menu of menus) { - for (const otherMenu of menus) { - if (menu !== otherMenu) { - assertNotEquals(menu.menuId, otherMenu.menuId); - } - } - } - - await this.yieldForPopulation(); - - // With an empty document, we expect one call to addPanelNodeMenuItems per - // menu. - assertEquals(this.expectedMenuCount, PanelBridge.calls.length); - - // We expect the calls to add menu items indicating there are no relevant - // nodes. - for (const call of PanelBridge.calls) { - assertEquals(1, call.items.length); - assertEquals('None', call.items[0].title); - assertEquals(-1, call.items[0].callbackId); - assertFalse(call.items[0].isActive); - } - }); - -TEST_F('ChromeVoxPanelNodeMenuBackgroundTest', 'Headings', async function() { - await this.runWithLoadedTree(this.headingsDoc); - const menus = PanelNodeMenuBackground.createAllPanelNodeMenuData(); - - assertEquals(this.expectedMenuCount, menus.length); - assertEquals('role_heading', menus[0].title); - const headingMenuId = menus[0].menuId; - - await this.yieldForPopulation(); - - // The heading menu should have less than 5 items, which is the batch size, so - // we expect only one call for each menu (the others all being empty). - assertEquals(this.expectedMenuCount, PanelBridge.calls.length); - - let headingCall; - // All calls to add menu items other than the heading menu call should - // indicate there are no relevant nodes. - for (const call of PanelBridge.calls) { - if (call.id === headingMenuId) { - headingCall = call; - continue; - } - assertEquals(1, call.items.length); - assertEquals('None', call.items[0].title); - } - - // Check the contents of the heading call match what we expect based on the - // provided document. - const headingMenuItems = headingCall.items; - assertEquals(3, headingMenuItems.length); - assertEquals('Heading 1', headingMenuItems[0].title); - assertEquals('Heading 2', headingMenuItems[1].title); - assertEquals('Heading 3', headingMenuItems[2].title); - - for (const item of headingMenuItems) { - assertFalse(item.isActive); - // Verify the callback IDs are unique. - for (const otherItem of headingMenuItems) { - if (item !== otherItem) { - assertNotEquals(item.callbackId, otherItem.callbackId); - } - } - } -}); - -TEST_F('ChromeVoxPanelNodeMenuBackgroundTest', 'Landmarks', async function() { - await this.runWithLoadedTree(this.landmarksDoc); - const menus = PanelNodeMenuBackground.createAllPanelNodeMenuData(); - - assertEquals(this.expectedMenuCount, menus.length); - assertEquals('role_landmark', menus[1].title); - const landmarkMenuId = menus[1].menuId; - - await this.yieldForPopulation(); - - // The landmarks menu will have a total of 2 calls, as it has more than 5 - // items (the batch size). However, only one batch of landmarks occurs per - // call to yieldForPopulation, so expect one call per menu (the others all - // being empty). - assertEquals(this.expectedMenuCount, PanelBridge.calls.length); - - let landmarkCall; - // All calls to add menu items other than the landmark menu call should - // indicate there are no relevant nodes. - for (const call of PanelBridge.calls) { - if (call.id === landmarkMenuId) { - landmarkCall = call; - continue; - } - assertEquals(1, call.items.length); - assertEquals('None', call.items[0].title); - } - - // Check the contents of the landmark call match what we expect based on the - // provided document. - const landmarkMenuItems = landmarkCall.items; - assertEquals(5, landmarkMenuItems.length); - - // Wait for the rest of the menu items to populate. - PanelBridge.calls = []; - await this.yieldForPopulation(); - assertEquals(1, PanelBridge.calls.length); - - assertEquals(landmarkMenuId, PanelBridge.calls[0].id); - landmarkMenuItems.append(PanelBridge.calls[0].items); - assertEquals(8, landmarkMenuItems.length); - - assertEquals('application', landmarkMenuItems[0].title); - assertEquals('banner', landmarkMenuItems[1].title); - assertEquals('complementary', landmarkMenuItems[2].title); - assertEquals('form', landmarkMenuItems[3].title); - assertEquals('main', landmarkMenuItems[4].title); - assertEquals('navigation', landmarkMenuItems[5].title); - assertEquals('region', landmarkMenuItems[6].title); - assertEquals('search', landmarkMenuItems[7].title); - - for (const item of landmarkMenuItems) { - assertFalse(item.isActive); - // Verify the callback IDs are unique. - for (const otherItem of landmarkMenuItems) { - if (item !== otherItem) { - assertNotEquals(item.callbackId, otherItem.callbackId); - } - } - } -}); - -TEST_F('ChromeVoxPanelNodeMenuBackgroundTest', 'Links', async function() { - await this.runWithLoadedTree(this.linksDoc); - const menus = PanelNodeMenuBackground.createAllPanelNodeMenuData(); - - assertEquals(this.expectedMenuCount, menus.length); - assertEquals('role_link', menus[2].title); - const linkMenuId = menus[2].menuId; - - await this.yieldForPopulation(); - - // The link menu should have less than 5 items, which is the batch size, so - // we expect only one call for each menu (the others all being empty). - assertEquals(this.expectedMenuCount, PanelBridge.calls.length); - - let linkCall; - // All calls to add menu items other than the link menu call should - // indicate there are no relevant nodes. - for (const call of PanelBridge.calls) { - if (call.id === linkMenuId) { - linkCall = call; - continue; - } - assertEquals(1, call.items.length); - assertEquals('None', call.items.title); - } - - // Check the contents of the link call match what we expect based on the - // provided document. - const linkMenuItems = linkCall.items; - assertEquals(4, linkMenuItems.length); - assertEquals('Link 1', linkMenuItems[0].title); - assertEquals('Link 2', linkMenuItems[1].title); - assertEquals('Link 3', linkMenuItems[2].title); - assertEquals('Link 4', linkMenuItems[3].title); - - for (const item of linkMenuItems) { - assertFalse(item.isActive); - // Verify the callback IDs are unique. - for (const otherItem of linkMenuItems) { - if (item !== otherItem) { - assertNotEquals(item.callbackId, otherItem.callbackId); - } - } - } -}); - -TEST_F( - 'ChromeVoxPanelNodeMenuBackgroundTest', 'FormControls', async function() { - await this.runWithLoadedTree(this.formControlsDoc); - const menus = PanelNodeMenuBackground.createAllPanelNodeMenuData( - 'panel_menu_form_controls'); - - assertEquals(this.expectedMenuCount, menus.length); - assertEquals('panel_menu_form_controls', menus[3].title); - const formMenuId = menus[3].menuId; - - // The form controls menu will have a total of 2 calls, as it has more - // than 5 items (the batch size). And because it is specified as the - // activated menu, we expect both of those calls to happen before any - // others. - assertEquals(this.expectedMenuCount + 1, PanelBridge.calls.length); - const formCall1 = PanelBridge.calls.shift(); - assertEquals(formMenuId, formCall1.id); - const formCall2 = PanelBridge.calls.shift(); - assertEquals(formMenuId, formCall2.id); - - // All calls to add menu items other than the form control menu call - // should indicate there are no relevant nodes. - for (const call of PanelBridge.calls) { - assertNotEquals(formMenuId, call.id); - assertEquals(1, call.items.length); - assertEquals('None', call.items[0].title); - } - - // Check the contents of the form control call match what we expect based - // on the provided document. - const formMenuItems = formCall1.items; - formMenuItems.append(formCall2.items); - assertEquals(9, formMenuItems.length); - - assertEquals('button', formMenuItems[0].title); - assertEquals('textInput', formMenuItems[1].title); - assertEquals('textarea', formMenuItems[2].title); - assertEquals('checkbox', formMenuItems[3].title); - assertEquals('color', formMenuItems[4].title); - assertEquals('slider', formMenuItems[5].title); - assertEquals('switch', formMenuItems[6].title); - assertEquals('tab', formMenuItems[7].title); - assertEquals('tree', formMenuItems[8].title); - - // Because this menu is activated, and the focus is on the tree, we expect - // it to be active as well. - const treeItem = formMenuItems.pop(); - assertTrue(treeItem.isActive); - - for (const item of formMenuItems) { - assertFalse(item.isActive); - } - }); - -TEST_F('ChromeVoxPanelNodeMenuBackgroundTest', 'Tables', async function() { - await this.runWithLoadedTree(this.tablesDoc); - const menus = PanelNodeMenuBackground.createAllPanelNodeMenuData(); - - assertEquals(this.expectedMenuCount, menus.length); - assertEquals('role_table', menus[4].title); - const tableMenuId = menus[4].menuId; - - await this.yieldForPopulation(); - - // The table menu should have less than 5 items, which is the batch size, so - // we expect only one call for each menu (the others all being empty). - assertEquals(this.expectedMenuCount, PanelBridge.calls.length); - - let tableCall; - // All calls to add menu items other than the table menu call should - // indicate there are no relevant nodes. - for (const call of PanelBridge.calls) { - if (call.id === tableMenuId) { - tableCall = call; - continue; - } - assertEquals(1, call.items.length); - assertEquals('None', call.items.title); - } - - // Check the contents of the table call match what we expect based on the - // provided document. - const tableMenuItems = tableCall.items; - assertEquals(2, tableMenuItems.length); - assertEquals('grid', tableMenuItems[0].title); - assertEquals('table', tableMenuItems[1].title); - - assertFalse(tableMenuItems[0].isActive); - assertFalse(tableMenuItems[1].isActive); - assertNotEquals(tableMenuItems[0].callbackId, tableMenuItems[1].callbackId); -}); - -TEST_F('ChromeVoxPanelNodeMenuBackgroundTest', 'MixedData', async function() { - await this.runWithLoadedTree(this.mixedDoc); - const menus = PanelNodeMenuBackground.createAllPanelNodeMenuData(); - - assertEquals('role_heading', menus[0].title); - const headingId = menus[0].menuId; - assertEquals('role_landmark', menus[1].title); - const landmarkId = menus[1].menuId; - assertEquals('role_link', menus[2].title); - const linkId = menus[2].menuId; - assertEquals('panel_menu_form_controls', menus[3].title); - const formId = menus[3].menuId; - assertEquals('role_table', menus[4].title); - const tableId = menus[4].menuId; - - await this.yieldForPopulation(); - assertEquals(this.expectedMenuCount, PanelBridge.calls.length); - - const headingCall = PanelBridge.calls.find(call => call.id === headingId); - const landmarkCall = PanelBridge.calls.find(call => call.id === landmarkId); - const linkCall = PanelBridge.calls.find(call => call.id === linkId); - const formCall = PanelBridge.calls.find(call => call.id === formId); - const tableCall = PanelBridge.calls.find(call => call.id === tableId); - - assertEquals(1, headingCall.items.length); - assertEquals('header', headingCall.items[0].title); - assertEquals(1, landmarkCall.items.length); - assertEquals('region', landmarkCall.items[0].title); - assertEquals(1, linkCall.items.length); - assertEquals('link', linkCall.items[0].title); - assertEquals(1, formCall.items.length); - assertEquals('button', formCall.items[0].title); - assertEquals(1, tableCall.items.length); - assertEquals('table', tableCall.items[0].title); -});
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/prefs.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/prefs.js index aad17ddb..5d1a4d9 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/prefs.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/prefs.js
@@ -199,12 +199,12 @@ /** @type {!ChromeVoxPrefs} */ ChromeVoxPrefs.instance = new ChromeVoxPrefs(); -BridgeHelper.registerHandler( - /* target= */ 'ChromeVoxPrefs', 'getPrefs', - () => ChromeVoxPrefs.instance.getPrefs()); -BridgeHelper.registerHandler( - /* target= */ 'ChromeVoxPrefs', 'setLoggingPrefs', +const target = 'ChromeVoxPrefs'; +BackgroundBridge.registerHandler( + target, 'getPrefs', () => ChromeVoxPrefs.instance.getPrefs()); +BackgroundBridge.registerHandler( + target, 'setLoggingPrefs', ({key, value}) => ChromeVoxPrefs.instance.setLoggingPrefs(key, value)); -BridgeHelper.registerHandler( - /* target= */ 'ChromeVoxPrefs', 'setPref', +BackgroundBridge.registerHandler( + target, 'setPref', ({key, value}) => ChromeVoxPrefs.instance.setPref(key, value));
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/common/background_bridge.js b/chrome/browser/resources/chromeos/accessibility/chromevox/common/background_bridge.js index 403062b..773e279 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/common/background_bridge.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/common/background_bridge.js
@@ -3,15 +3,12 @@ // found in the LICENSE file. /** - * @fileoverview Provides an interface for non-background renderer contexts - * (options, panel, etc.) to communicate with the background. + * @fileoverview Provides an interface for non-background contexts (options, + * panel, etc.) to communicate with the background. */ goog.provide('BackgroundBridge'); -goog.require('BridgeHelper'); -goog.require('PanelNodeMenuData'); - BackgroundBridge.BrailleBackground = { /** * Translate braille cells into text. @@ -19,13 +16,13 @@ * @return {!Promise<?string>} */ async backTranslate(cells) { - return BridgeHelper.sendMessage( + return BackgroundBridge.sendMessage_( 'BrailleBackground', 'backTranslate', cells); }, /** @param {string} brailleTable The table for this translator to use. */ async refreshBrailleTable(brailleTable) { - return BridgeHelper.sendMessage( + return BackgroundBridge.sendMessage_( 'BrailleBackground', 'refreshBrailleTable', brailleTable); }, }; @@ -37,7 +34,7 @@ * localStorage. */ async getPrefs() { - return BridgeHelper.sendMessage('ChromeVoxPrefs', 'getPrefs'); + return BackgroundBridge.sendMessage_('ChromeVoxPrefs', 'getPrefs'); }, /** @@ -46,7 +43,7 @@ * @param {boolean} value The new value of the pref. */ async setLoggingPrefs(key, value) { - return BridgeHelper.sendMessage( + return BackgroundBridge.sendMessage_( 'ChromeVoxPrefs', 'setLoggingPrefs', {key, value}); }, @@ -56,50 +53,68 @@ * @param {Object|string|boolean} value The new value of the pref. */ async setPref(key, value) { - return BridgeHelper.sendMessage('ChromeVoxPrefs', 'setPref', {key, value}); + return BackgroundBridge.sendMessage_( + 'ChromeVoxPrefs', 'setPref', {key, value}); }, }; -BackgroundBridge.PanelBackground = { - async createNewISearch() { - return BridgeHelper.sendMessage('PanelBackground', 'createNewISearch'); - }, +// Helper functions: - /** - * Performs a search. - * @param {string} searchStr - * @param {constants.Dir} dir - * @param {boolean=} opt_nextObject - */ - async incrementalSearch(searchStr, dir, opt_nextObject) { - return BridgeHelper.sendMessage( - 'PanelBackground', 'incrementalSearch', - {searchStr, dir, opt_nextObject}); - }, +/** @private {!Object<string, Object<string, Function>>} */ +BackgroundBridge.handlers = {}; - async setRangeToISearchNode() { - return BridgeHelper.sendMessage('PanelBackground', 'setRangeToISearchNode'); - }, +/** + * @param {string} target The name of the class that is registering the handler. + * @param {string} action The name of the intended function or, if not a direct + * method of the class, a pseudo-function name. + * @param {Function} handler A function that performs the indicated action. It + * may optionally take a single parameter, and may have an optional return + * value that will be forwarded to the requestor. + * If the method takes multiple parameters, they are passed as named members + * of an object literal. + */ +BackgroundBridge.registerHandler = (target, action, handler) => { + if (!BackgroundBridge.handlers[target]) { + BackgroundBridge.handlers[target] = {}; + } + BackgroundBridge.handlers[target][action] = handler; }; -BackgroundBridge.PanelNodeMenuBackground = { - /** - * @param {string=} opt_activateMenuTitle - * @return {!Promise<!Array<!PanelNodeMenuData>>} - */ - async createAllPanelNodeMenuData(opt_activateMenuTitle) { - return BridgeHelper.sendMessage( - 'PanelNodeMenuBackground', 'createAllPanelNodeMenuData', - opt_activateMenuTitle); - }, - - /** - * @param {number} menuId - * @param {number} callbackId - */ - async performMenuActionCallback(menuId, callbackId) { - return BridgeHelper.sendMessage( - 'PanelNodeMenuBackground', 'performMenuActionCallback', - {menuId, callbackId}); - }, +BackgroundBridge.castTo = (type) => { + return (obj) => { + if (obj === null || obj === undefined) { + return obj; + } + Object.setPrototypeOf(obj, type.prototype); + return obj; + }; }; + + +/** + * @param {string} target The name of the class that will handle this request. + * @param {string} action The name of the intended function or, if not a direct + * method of the class, a pseudo-function name. + * @param {*=} value An optional single parameter to include with the message. + * If the method takes multiple parameters, they are passed as named members + * of an object literal. + * + * @return {!Promise} A promise, that resolves when the handler function has + * finished and contains any value returned by the handler. + * @private + */ +BackgroundBridge.sendMessage_ = (target, action, value) => { + return new Promise( + resolve => chrome.runtime.sendMessage({target, action, value}, resolve)); +}; + +chrome.runtime.onMessage.addListener((message, sender, respond) => { + const targetHandlers = BackgroundBridge.handlers[message.target]; + if (!targetHandlers || !targetHandlers[message.action]) { + return; + } + + const handler = targetHandlers[message.action]; + Promise.resolve(handler(message.value)).then(respond); + return true; /** Wait for asynchronous response. */ +});
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/common/bridge_helper.js b/chrome/browser/resources/chromeos/accessibility/chromevox/common/bridge_helper.js deleted file mode 100644 index 3c98d91..0000000 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/common/bridge_helper.js +++ /dev/null
@@ -1,75 +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. - -/** - * @fileoverview A collection of functions and behaviors helpful for message - * passing between renderers. - */ -goog.provide('BridgeHelper'); - -BridgeHelper.castTo = (type) => { - return (obj) => { - if (obj === null || obj === undefined) { - return obj; - } - Object.setPrototypeOf(obj, type.prototype); - return obj; - }; -}; - -/** @private {!Object<string, Object<string, Function>>} */ -BridgeHelper.handlers_ = {}; - -/** - * This function should only be used by Bridges (e.g. BackgroundBridge, - * PanelBridge) and not called directly by other classes. - * - * @param {string} target The name of the class that will handle this request. - * @param {string} action The name of the intended function or, if not a direct - * method of the class, a pseudo-function name. - * @param {*=} value An optional single parameter to include with the message. - * If the method takes multiple parameters, they are passed as named members - * of an object literal. - * - * @return {!Promise} A promise, that resolves when the handler function has - * finished and contains any value returned by the handler. - */ -BridgeHelper.sendMessage = (target, action, value) => { - return new Promise( - resolve => chrome.runtime.sendMessage({target, action, value}, resolve)); -}; - -/** - * @param {string} target The name of the class that is registering the handler. - * @param {string} action The name of the intended function or, if not a direct - * method of the class, a pseudo-function name. - * @param {Function} handler A function that performs the indicated action. It - * may optionally take a single parameter, and may have an optional return - * value that will be forwarded to the requestor. - * If the method takes multiple parameters, they are passed as named members - * of an object literal. - */ -BridgeHelper.registerHandler = (target, action, handler) => { - if (!BridgeHelper.handlers_[target]) { - BridgeHelper.handlers_[target] = {}; - } - - if (BridgeHelper.handlers_[target][action]) { - throw 'Error: Re-assigning handlers for a specific target/action ' + - 'is not permitted'; - } - - BridgeHelper.handlers_[target][action] = handler; -}; - -chrome.runtime.onMessage.addListener((message, sender, respond) => { - const targetHandlers = BridgeHelper.handlers_[message.target]; - if (!targetHandlers || !targetHandlers[message.action]) { - return; - } - - const handler = targetHandlers[message.action]; - Promise.resolve(handler(message.value)).then(respond); - return true; /** Wait for asynchronous response. */ -});
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/common/panel_bridge.js b/chrome/browser/resources/chromeos/accessibility/chromevox/common/panel_bridge.js deleted file mode 100644 index e0976e67..0000000 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/common/panel_bridge.js +++ /dev/null
@@ -1,21 +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. - -/** - * @fileoverview Provides an interface for other renderer contexts (e.g. the - * background context) to communicate with the ChromeVox panel. - */ - -goog.provide('PanelBridge'); - -PanelBridge = { - /** - * @param {number} menuId - * @param {!Array<!PanelNodeMenuItemData>} itemArray - */ - async addPanelNodeMenuItems(menuId, itemArray) { - return BridgeHelper.sendMessage( - 'Panel', 'addPanelNodeMenuItems', {menuId, itemArray}); - }, -};
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/common/panel_node_menu_data.js b/chrome/browser/resources/chromeos/accessibility/chromevox/common/panel_node_menu_data.js deleted file mode 100644 index 70eafc3..0000000 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/common/panel_node_menu_data.js +++ /dev/null
@@ -1,39 +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. - -/** - * @fileoverview Structures to hold the data for the panel's node menus. - */ -goog.provide('PanelNodeMenuData'); -goog.provide('PanelNodeMenuItemData'); - -PanelNodeMenuData = class { - /** - * @param {string} title - * @param {number} menuId - */ - constructor(title, menuId) { - /** @public {string} */ - this.title = title; - /** @public {number} */ - this.menuId = menuId; - } -}; - -PanelNodeMenuItemData = class { - /** - * @param {string} title - * @param {number} callbackId - * @param {boolean} isActive True when the menu was explicitly activated and - * the node is focused. - */ - constructor(title, callbackId, isActive) { - /** @public {string} */ - this.title = title; - /** @public {number} */ - this.callbackId = callbackId; - /** @public {boolean} */ - this.isActive = isActive; - } -};
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/panel/i_search.js b/chrome/browser/resources/chromeos/accessibility/chromevox/panel/i_search.js new file mode 100644 index 0000000..f32ec5d --- /dev/null +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/panel/i_search.js
@@ -0,0 +1,262 @@ +// 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. + +/** + * @fileoverview Objects related to incremental search. + */ + +import {PanelInterface} from './panel_interface.js'; + +const AutomationNode = chrome.automation.AutomationNode; +const Dir = constants.Dir; +const RoleType = chrome.automation.RoleType; + +/** + * An interface implemented by objects that wish to handle events related to + * incremental search. + * @interface + */ +class ISearchHandler { + constructor() {} + + /** + * Called when there are no remaining nodes in the document matching + * search. + * @param {!AutomationNode} boundaryNode The last node before reaching either + * the start or end of the document. + */ + onSearchReachedBoundary(boundaryNode) {} + + /** + * Called when search result node changes. + * @param {!AutomationNode} node The new search result. + * @param {number} start The index into the name where the search match + * starts. + * @param {number} end The index into the name where the search match ends. + */ + onSearchResultChanged(node, start, end) {} +} + + +/** + * Controls an incremental search. + */ +export class ISearch { + /** + * @param {!cursors.Cursor} cursor + */ + constructor(cursor) { + if (!cursor.node) { + throw 'Incremental search started from invalid range.'; + } + + /** @private {ISearchHandler} */ + this.handler_; + + const leaf = AutomationUtil.findNodePre( + cursor.node, Dir.FORWARD, AutomationPredicate.leaf) || + cursor.node; + + /** @type {!cursors.Cursor} */ + this.cursor = cursors.Cursor.fromNode(leaf); + + /** @private {number} */ + this.callbackId_ = 0; + + // Global exports. + /** Exported for this background script. */ + ChromeVox = chrome.extension.getBackgroundPage()['ChromeVox']; + } + + /** + * @param {!ISearchHandler} handler + */ + set handler(handler) { + this.handler_ = handler; + } + + /** + * Performs a search. + * @param {string} searchStr + * @param {constants.Dir} dir + * @param {boolean=} opt_nextObject + */ + search(searchStr, dir, opt_nextObject) { + clearTimeout(this.callbackId_); + const step = function() { + searchStr = searchStr.toLocaleLowerCase(); + const node = this.cursor.node; + let result = node; + + if (opt_nextObject) { + // We want to start/continue the search at the next object. + result = + AutomationUtil.findNextNode(node, dir, AutomationPredicate.object); + } + + do { + // Ask native to search the underlying data for a performance boost. + result = result.getNextTextMatch(searchStr, dir === Dir.BACKWARD); + } while (result && !AutomationPredicate.object(result)); + + if (result) { + this.cursor = cursors.Cursor.fromNode(result); + const start = result.name.toLocaleLowerCase().indexOf(searchStr); + const end = start + searchStr.length; + this.handler_.onSearchResultChanged(result, start, end); + } else { + this.handler_.onSearchReachedBoundary(this.cursor.node); + } + }; + + this.callbackId_ = setTimeout(step.bind(this), 0); + } + + clear() { + clearTimeout(this.callbackId_); + } +} + + +/** + * @implements {ISearchHandler} + */ +export class ISearchUI { + /** + * @param {Element} input + */ + constructor(input) { + /** @type {ChromeVoxState} @private */ + this.background_ = + chrome.extension.getBackgroundPage()['ChromeVoxState']['instance']; + this.iSearch_ = new ISearch(this.background_.currentRange.start); + this.input_ = input; + this.dir_ = Dir.FORWARD; + this.iSearch_.handler = this; + + this.onKeyDown = this.onKeyDown.bind(this); + this.onTextInput = this.onTextInput.bind(this); + + input.addEventListener('keydown', this.onKeyDown, true); + input.addEventListener('textInput', this.onTextInput, false); + } + + /** + * @param {Element} input + * @return {ISearchUI} + */ + static init(input) { + if (ISearchUI.instance_) { + ISearchUI.instance_.destroy(); + } + + if (!input) { + throw 'Expected search input'; + } + + ISearchUI.instance_ = new ISearchUI(input); + input.focus(); + input.select(); + return ISearchUI.instance_; + } + + /** + * Listens to key down events. + * @param {Event} evt + * @return {boolean} + */ + onKeyDown(evt) { + switch (evt.key) { + case 'ArrowUp': + this.dir_ = Dir.BACKWARD; + break; + case 'ArrowDown': + this.dir_ = Dir.FORWARD; + break; + case 'Escape': + PanelInterface.instance.closeMenusAndRestoreFocus(); + return false; + case 'Enter': + PanelInterface.instance.setPendingCallback(function() { + const node = this.iSearch_.cursor.node; + if (!node) { + return; + } + chrome.extension.getBackgroundPage() + .ChromeVoxState.instance['navigateToRange']( + cursors.Range.fromNode(node)); + }.bind(this)); + PanelInterface.instance.closeMenusAndRestoreFocus(); + return false; + default: + return false; + } + this.iSearch_.search(this.input_.value, this.dir_, true); + evt.preventDefault(); + evt.stopPropagation(); + return false; + } + + /** + * Listens to text input events. + * @param {Event} evt + * @return {boolean} + */ + onTextInput(evt) { + const searchStr = evt.target.value + evt.data; + this.iSearch_.clear(); + this.iSearch_.search(searchStr, this.dir_); + return true; + } + + /** + * @override + */ + onSearchReachedBoundary(boundaryNode) { + this.output_(boundaryNode); + ChromeVox.earcons.playEarcon(Earcon.WRAP); + } + + /** + * @override + */ + onSearchResultChanged(node, start, end) { + this.output_(node, start, end); + } + + /** + * @param {!AutomationNode} node + * @param {number=} opt_start + * @param {number=} opt_end + * @private + */ + output_(node, opt_start, opt_end) { + Output.forceModeForNextSpeechUtterance(QueueMode.FLUSH); + const o = new Output(); + if (opt_start && opt_end) { + o.withString([ + node.name.substr(0, opt_start), + node.name.substr(opt_start, opt_end - opt_start), + node.name.substr(opt_end) + ].join(', ')); + o.format('$role', node); + } else { + o.withRichSpeechAndBraille( + cursors.Range.fromNode(node), null, OutputEventType.NAVIGATE); + } + o.go(); + + this.background_.setCurrentRange(cursors.Range.fromNode(node)); + } + + /** Unregisters event handlers. */ + destroy() { + this.iSearch_.handler_ = null; + this.iSearch_ = null; + const input = this.input_; + this.input_ = null; + input.removeEventListener('keydown', this.onKeyDown, true); + input.removeEventListener('textInput', this.onTextInput, false); + } +}
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/panel/i_search_test.js b/chrome/browser/resources/chromeos/accessibility/chromevox/panel/i_search_test.js new file mode 100644 index 0000000..eaea1b8 --- /dev/null +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/panel/i_search_test.js
@@ -0,0 +1,117 @@ +// 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. + +// Include test fixture. +GEN_INCLUDE([ + '//chrome/browser/resources/chromeos/accessibility/chromevox/testing/chromevox_next_e2e_test_base.js' +]); + +/** + * Test fixture for ISearch. + */ +ChromeVoxISearchTest = class extends ChromeVoxNextE2ETest { + /** @override */ + get runtimeDeps() { + return ['ISearch', 'ISearchHandler']; + } + + /** @override */ + async setUpDeferred() { + await super.setUpDeferred(); + await importModule('ISearch', '/chromevox/panel/i_search.js'); + } + + get linksAndHeadingsDoc() { + return ` + <p>start</p> + <a href='#a'>Home</a> + <a href='#b'>About US</a> + <p> + <h1>Latest Breaking News</h1> + <a href='foo'>See more...</a> + </p> + <a href='#bar'>Questions?</a> + <h2>Privacy Policy</h2> + <p>end<span>of test</span></p> + `; + } +}; + + +/** + * @implements {ISearchHandler} + */ +class FakeISearchHandler { + constructor(testObj) { + this.test = testObj; + this.expect_ = []; + } + + /** @override */ + onSearchReachedBoundary(boundaryNode) { + this.expect_.shift()({node: boundaryNode, isBoundary: true}); + } + + /** @override */ + onSearchResultChanged(node, start, end) { + this.expect_.shift()({node, start, end}); + } + + expect(str, opt_callback) { + this.expect_.push(this.test.newCallback(function(args) { + const node = args.node; + let actual = node.name || node.role; + if (args.start && args.end) { + actual = 'start=' + args.start + ' end=' + args.end + ' text=' + actual; + } + if (args.isBoundary) { + actual = 'boundary=' + actual; + } + assertEquals(str, actual); + opt_callback && opt_callback(); + })); + } +} + + +TEST_F('ChromeVoxISearchTest', 'Simple', async function() { + const rootNode = await this.runWithLoadedTree(this.linksAndHeadingsDoc); + const handler = new FakeISearchHandler(this); + const search = new ISearch(new cursors.Cursor(rootNode, 0)); + search.handler = handler; + + // Simple forward search. + search.search('US', 'forward'); + handler.expect( + 'start=6 end=8 text=About US', + search.search.bind(search, 'start', 'backward')); + + handler.expect( + 'start', + // Boundary (beginning). + search.search.bind(search, 'foo', 'backward')); + + handler.expect( + 'boundary=start', + // Boundary (end). + search.search.bind(search, 'foo', 'forward')); + + // Search "focus" doesn't move. + handler.expect( + 'boundary=start', + // Mixed case substring. + search.search.bind(search, 'bReak', 'forward')); + + handler.expect( + 'start=7 end=12 text=Latest Breaking News', + search.search.bind(search, 'bReaki', 'forward')); + + // Incremental search stays on the current node. + handler.expect( + 'start=7 end=13 text=Latest Breaking News', + search.search.bind(search, 'bReakio', 'forward')); + + // No results for the search. + handler.expect('boundary=Latest Breaking News'); +});
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/panel/i_search_ui.js b/chrome/browser/resources/chromeos/accessibility/chromevox/panel/i_search_ui.js deleted file mode 100644 index 2cb4ca2..0000000 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/panel/i_search_ui.js +++ /dev/null
@@ -1,96 +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. - -/** - * @fileoverview The UI for searching the ChromeVox panel menus incrementally. - */ - -import {PanelInterface} from './panel_interface.js'; - -export class ISearchUI { - /** - * @param {Element} input - */ - constructor(input) { - /** @private {Element} */ - this.input_ = input; - /** @private {constants.Dir} */ - this.dir_ = constants.Dir.FORWARD; - - this.onKeyDown = (event) => this.onKeyDown_(event); - this.onTextInput = (event) => this.onTextInput_(event); - - input.addEventListener('keydown', this.onKeyDown, true); - input.addEventListener('textInput', this.onTextInput, false); - } - - /** @param {Element} input */ - static async init(input) { - if (ISearchUI.instance_) { - ISearchUI.instance_.destroy(); - } - - if (!input) { - throw 'Expected search input'; - } - - await BackgroundBridge.PanelBackground.createNewISearch(); - ISearchUI.instance_ = new ISearchUI(input); - input.focus(); - input.select(); - } - - /** - * Listens to key down events. - * @param {Event} evt - * @return {boolean} - * @private - */ - onKeyDown_(evt) { - switch (evt.key) { - case 'ArrowUp': - this.dir_ = constants.Dir.BACKWARD; - break; - case 'ArrowDown': - this.dir_ = constants.Dir.FORWARD; - break; - case 'Escape': - PanelInterface.instance.closeMenusAndRestoreFocus(); - return false; - case 'Enter': - PanelInterface.instance.setPendingCallback( - async () => - await BackgroundBridge.PanelBackground.setRangeToISearchNode()); - PanelInterface.instance.closeMenusAndRestoreFocus(); - return false; - default: - return false; - } - BackgroundBridge.PanelBackground.incrementalSearch( - this.input_.value, this.dir_, true); - evt.preventDefault(); - evt.stopPropagation(); - return false; - } - - /** - * Listens to text input events. - * @param {Event} evt - * @return {boolean} - * @private - */ - onTextInput_(evt) { - const searchStr = evt.target.value + evt.data; - BackgroundBridge.PanelBackground.incrementalSearch(searchStr, this.dir_); - return true; - } - - /** Unregisters event handlers. */ - destroy() { - const input = this.input_; - this.input_ = null; - input.removeEventListener('keydown', this.onKeyDown, true); - input.removeEventListener('textInput', this.onTextInput, false); - } -}
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/panel/panel.js b/chrome/browser/resources/chromeos/accessibility/chromevox/panel/panel.js index 9d189391..a2b33f6 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/panel/panel.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/panel/panel.js
@@ -279,7 +279,7 @@ /** * Open / show the ChromeVox Menus. * @param {Event=} opt_event An optional event that triggered this. - * @param {string=} opt_activateMenuTitle Title msg id of menu to open. + * @param {*=} opt_activateMenuTitle Title msg id of menu to open. */ static onOpenMenus(opt_event, opt_activateMenuTitle) { // If the menu was already open, close it now and exit early. @@ -503,11 +503,24 @@ Panel.onClose(); }); - const nodeMenuData = - await BackgroundBridge.PanelNodeMenuBackground - .createAllPanelNodeMenuData(opt_activateMenuTitle); - for (const data of nodeMenuData) { - Panel.nodeMenus_[data.menuId] = Panel.addNodeMenu(data); + const roleListMenuMapping = [ + {menuTitle: 'role_heading', predicate: AutomationPredicate.heading}, + {menuTitle: 'role_landmark', predicate: AutomationPredicate.landmark}, + {menuTitle: 'role_link', predicate: AutomationPredicate.link}, { + menuTitle: 'panel_menu_form_controls', + predicate: AutomationPredicate.formField + }, + {menuTitle: 'role_table', predicate: AutomationPredicate.table} + ]; + + for (let i = 0; i < roleListMenuMapping.length; ++i) { + const menuTitle = roleListMenuMapping[i].menuTitle; + const predicate = roleListMenuMapping[i].predicate; + // Create node menus asynchronously (because it may require + // searching a long document) unless that's the specific menu the + // user requested. + const async = (menuTitle !== opt_activateMenuTitle); + Panel.addNodeMenu(menuTitle, node, predicate, async); } if (node && node.standardActions) { @@ -559,12 +572,12 @@ } /** Open incremental search. */ - static async onSearch() { + static onSearch() { Panel.setMode(PanelMode.SEARCH); Panel.clearMenus(); Panel.pendingCallback_ = null; Panel.updateFromPrefs(); - await ISearchUI.init(Panel.searchInput_); + ISearchUI.init(Panel.searchInput_); } /** @@ -745,12 +758,15 @@ } /** - * Create a new node menu with the given data and add it to the menu bar. - * @param {!PanelNodeMenuData} data - * @return {!PanelNodeMenu} + * Create a new node menu with the given name and add it to the menu bar. + * @param {string} menuMsg The msg id of the new menu to add. + * @param {!chrome.automation.AutomationNode} node + * @param {AutomationPredicate.Unary} pred + * @param {boolean} defer If true, defers populating the menu. + * @return {PanelMenu} The menu just created. */ - static addNodeMenu(data) { - const menu = new PanelNodeMenu(data); + static addNodeMenu(menuMsg, node, pred, defer) { + const menu = new PanelNodeMenu(menuMsg, node, pred, defer); $('menu-bar').appendChild(menu.menuBarItemElement); menu.menuBarItemElement.addEventListener('mouseover', function() { Panel.activateMenu(menu, true /* activateFirstItem */); @@ -1296,8 +1312,6 @@ showContextMenu: 'show_context_menu' }; -/** @private {!Array<!PanelNodeMenu>} */ -Panel.nodeMenus_ = []; /** * @private {string} @@ -1343,7 +1357,3 @@ function $(id) { return document.getElementById(id); } - -BridgeHelper.registerHandler( - /* target= */ 'Panel', 'addPanelNodeMenuItems', - ({menuId, itemArray}) => Panel.nodeMenus_[menuId].addMenuItems(itemArray));
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/panel/panel_loader.js b/chrome/browser/resources/chromeos/accessibility/chromevox/panel/panel_loader.js index 2dd5c4a0..a1cfa02 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/panel/panel_loader.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/panel/panel_loader.js
@@ -8,7 +8,6 @@ goog.require('AutomationTreeWalker'); goog.require('AutomationUtil'); -goog.require('BridgeHelper'); goog.require('ChromeVoxState'); goog.require('EventSourceType'); goog.require('KeyCode'); @@ -18,8 +17,6 @@ goog.require('Output'); goog.require('Output'); goog.require('PanelCommand'); -goog.require('PanelNodeMenuData'); -goog.require('PanelNodeMenuItemData'); goog.require('QueueMode'); goog.require('constants'); goog.require('cursors.Cursor');
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/panel/panel_menu.js b/chrome/browser/resources/chromeos/accessibility/chromevox/panel/panel_menu.js index c7ab8b5..99abd0c 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/panel/panel_menu.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/panel/panel_menu.js
@@ -311,24 +311,27 @@ export class PanelNodeMenu extends PanelMenu { - /** @param {!PanelNodeMenuData} data */ - constructor(data) { - super(data.title); + /** + * @param {string} menuMsg The msg id of the menu. + * @param {chrome.automation.AutomationNode} node ChromeVox's current + * position. + * @param {AutomationPredicate.Unary} pred Filter to use on the document. + * @param {boolean} async If true, populates the menu asynchronously by + * posting a task after searching each chunk of nodes. + */ + constructor(menuMsg, node, pred, async) { + super(menuMsg); + /** @private {AutomationNode} */ + this.node_ = node; + /** @private {AutomationPredicate.Unary} */ + this.pred_ = pred; + /** @private {boolean} */ + this.async_ = async; + /** @private {AutomationTreeWalker|undefined} */ + this.walker_; /** @private {number} */ - this.id_ = data.menuId; - } - - /** @param {!Array<!PanelNodeMenuItemData>} dataArray */ - addMenuItems(dataArray) { - for (const data of dataArray) { - this.addMenuItem( - data.title, '', '', '', - () => BackgroundBridge.PanelNodeMenuBackground - .performMenuActionCallback(this.id_, data.callbackId)); - if (data.isActive) { - this.activeIndex_ = this.items_.length - 1; - } - } + this.nodeCount_ = 0; + this.populate_(); } /** @override */ @@ -341,9 +344,100 @@ this.activateItem(index); } } + + /** + * Create the AutomationTreeWalker and kick off the search to find + * nodes that match the predicate for this menu. + * @private + */ + populate_() { + if (!this.node_) { + this.finish_(); + return; + } + + const root = AutomationUtil.getTopLevelRoot(this.node_); + if (!root) { + this.finish_(); + return; + } + + this.walker_ = new AutomationTreeWalker(root, constants.Dir.FORWARD, { + visit(node) { + return !AutomationPredicate.shouldIgnoreNode(node); + } + }); + this.nodeCount_ = 0; + this.findMoreNodes_(); + } + + /** + * Iterate over nodes from the tree walker. If a node matches the + * predicate, add an item to the menu. + * + * If |this.async_| is true, then after MAX_NODES_BEFORE_ASYNC nodes + * have been scanned, call setTimeout to defer searching. This frees + * up the main event loop to keep the panel menu responsive, otherwise + * it basically freezes up until all of the nodes have been found. + * @private + */ + findMoreNodes_() { + while (this.walker_.next().node) { + const node = this.walker_.node; + if (this.pred_(node)) { + const output = new Output(); + const range = cursors.Range.fromNode(node); + output.withoutHints(); + output.withSpeech(range, range, OutputEventType.NAVIGATE); + const label = output.toString(); + this.addMenuItem(label, '', '', '', (function() { + const savedNode = node; + return function() { + chrome.extension.getBackgroundPage() + .ChromeVoxState.instance['navigateToRange']( + cursors.Range.fromNode(savedNode)); + }; + }())); + + if (node === this.node_ && !this.async_) { + this.activeIndex_ = this.items_.length - 1; + } + } + + if (this.async_) { + this.nodeCount_++; + if (this.nodeCount_ >= PanelNodeMenu.MAX_NODES_BEFORE_ASYNC) { + this.nodeCount_ = 0; + window.setTimeout(this.findMoreNodes_.bind(this), 0); + return; + } + } + } + this.finish_(); + } + + /** + * Called when we've finished searching for nodes. If no matches were + * found, adds an item to the menu indicating none were found. + * @private + */ + finish_() { + if (!this.items_.length) { + this.addMenuItem( + Msgs.getMsg('panel_menu_item_none'), '', '', '', function() {}); + } + } } /** + * The number of nodes to search before posting a task to finish + * searching. + * @const {number} + */ +PanelNodeMenu.MAX_NODES_BEFORE_ASYNC = 100; + + +/** * Implements a menu that allows users to dynamically search the contents of the * ChromeVox menus. */
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/panel/panel_test.js b/chrome/browser/resources/chromeos/accessibility/chromevox/panel/panel_test.js index 7f87abf..f06a41c0 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/panel/panel_test.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/panel/panel_test.js
@@ -123,9 +123,9 @@ }); TEST_F('ChromeVoxPanelTest', 'SearchMenu', async function() { + const mockFeedback = this.createMockFeedback(); await this.runWithLoadedTree(this.linksDoc); new PanelCommand(PanelCommandType.OPEN_MENUS).send(); - const mockFeedback = this.createMockFeedback(); await this.waitForMenu('panel_search_menu'); await mockFeedback .expectSpeech('Search the menus', /Type to search the menus/)
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/panel/panel_test_base.js b/chrome/browser/resources/chromeos/accessibility/chromevox/panel/panel_test_base.js index 325bef8d..1db3358 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/panel/panel_test_base.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/panel/panel_test_base.js
@@ -31,7 +31,6 @@ * chrome.extension.getViews for it. */ getPanel() { - assertNotNullNorUndefined(this.getPanelWindow().Panel); return this.getPanelWindow().Panel; } };
diff --git a/chrome/browser/resources/chromeos/accessibility/common/testing/documents.js b/chrome/browser/resources/chromeos/accessibility/common/testing/documents.js deleted file mode 100644 index ee0b8062..0000000 --- a/chrome/browser/resources/chromeos/accessibility/common/testing/documents.js +++ /dev/null
@@ -1,43 +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. - -/** - * @fileoverview A collection of document fragments to allow for easier test - * creation. - */ - -const Documents = { - application: `<div role="application" id="application">application</div>`, - banner: `<div role="banner" id="banner">banner</div>`, - button: `<button id="button">button</button>`, - checkbox: `<input type="checkbox" id="checkbox"></input> - <label for="checkbox">checkbox</label>`, - color: `<input type="color" id="color"></input> - <label for="color">color</label>`, - complementary: - `<div role="complementary" id="complementary">Complementary</div>`, - form: `<form aria-label="form" id="form"></form>`, - grid: `<div role="grid" id="grid">grid</div>`, - header: `<h1 id="header">header</header>`, - link: `<a href="#link" id="link">link</a>`, - main: `<div role="main" id="main">main</div>`, - navigation: `<nav id="navigation">navigation</nav>`, - region: `<div role="region" id="region">region</div>`, - search: `<input type="text" role="search" id="search"></input> - <label for="search">search</label>`, - slider: `<input type="range" id="slider"></input> - <label for="slider">slider</label>`, - switch: `<button role="switch" id="switch" aria-checked=true>switch</button> - <script> - const switchElement = document.getElementById("switch"); - switchElement.onclick = - () => switchElement.ariaChecked = !switchElement.ariaChecked; - </script>`, - tab: `<div role="tab" id="tab">tab</div>`, - table: `<table id="table" aria-label="table"></table>`, - textarea: `<textarea aria-label="textarea" id="textarea"></textarea>`, - textInput: - `<input type="text" aria-label="textInput" id="textInput"></input>`, - tree: `<div role="tree" id="tree">tree</div>`, -};
diff --git a/chrome/browser/resources/chromeos/login/oobe_polymer3.js b/chrome/browser/resources/chromeos/login/oobe_polymer3.js index 5d8415f..0cd080f 100644 --- a/chrome/browser/resources/chromeos/login/oobe_polymer3.js +++ b/chrome/browser/resources/chromeos/login/oobe_polymer3.js
@@ -13,6 +13,7 @@ import 'chrome://oobe/test_api/test_api.m.js'; import {i18nTemplate} from 'chrome://resources/js/i18n_template_no_process.m.js'; import {commonScreensList, loginScreensList, oobeScreensList} from 'chrome://oobe/screens.js'; +import {MultiTapDetector} from './multi_tap_detector.m.js'; // clang-format on /** @@ -48,17 +49,25 @@ } } -function initializeDebugger() { - if (document.readyState === 'loading') { - return; - } - document.removeEventListener('DOMContentLoaded', initializeDebugger); - OobeDebugger.DebuggerUI.getInstance().register(document.body); -} - // Create the global values attached to `window` that are used // for accessing OOBE controls from the browser side. function prepareGlobalValues(globalValue) { + // '$(id)' is an alias for 'document.getElementById(id)'. It is defined + // in chrome://resources/js/util.m.js. If this function is not exposed + // via the global object, it would not be available to tests that inject + // JavaScript directly into the renderer. + window.$ = $; + + window.MultiTapDetector = MultiTapDetector; + + // Install a global error handler so stack traces are included in logs. + window.onerror = function(message, file, line, column, error) { + if (error && error.stack) { + console.error(error.stack); + } + }; + + // TODO(crbug.com/1229130) - Remove the necessity for these global objects. if (globalValue.cr == undefined) { globalValue.cr = {}; } @@ -74,6 +83,35 @@ globalValue.Oobe = Oobe; } +function initializeOobe() { + if (document.readyState === 'loading') { + return; + } + document.removeEventListener('DOMContentLoaded', initializeOobe); + + // Initialize the on-screen debugger if present. + if (OobeDebugger.DebuggerUI) { + OobeDebugger.DebuggerUI.getInstance().register(document.body); + } + + try { + Oobe.initialize(); + } finally { + // TODO(crbug.com/712078): Do not set readyForTesting in case of that + // initialize() is failed. Currently, in some situation, initialize() + // raises an exception unexpectedly. It means testing APIs should not + // be called then. However, checking it here now causes bots failures + // unfortunately. So, as a short term workaround, here set + // readyForTesting even on failures, just to make test bots happy. + Oobe.readyForTesting = true; + } + + // Mark initialization complete and wake any callers that might be waiting + // for OOBE to load. + cr.ui.Oobe.initializationComplete = true; + cr.ui.Oobe.initCallbacks.forEach(resolvePromise => resolvePromise()); +} + (function (root) { i18nTemplate.process(document, loadTimeData); prepareGlobalValues(window); @@ -83,14 +121,9 @@ const isOobeFlow = loadTimeData.getBoolean('isOobeFlow'); addScreensToMainContainer(isOobeFlow ? oobeScreensList : loginScreensList); - Oobe.initialize(); - - // Initialize the debugger if it has been defined. - if (OobeDebugger.DebuggerUI) { - if (document.readyState === 'loading') { - document.addEventListener('DOMContentLoaded', initializeDebugger); - } else { - initializeDebugger(); - } + if (document.readyState === 'loading') { + document.addEventListener('DOMContentLoaded', initializeOobe); + } else { + initializeOobe(); } })(window);
diff --git a/chrome/browser/resources/new_tab_page/modules/modules.ts b/chrome/browser/resources/new_tab_page/modules/modules.ts index 068f3c35..a25ee4a2 100644 --- a/chrome/browser/resources/new_tab_page/modules/modules.ts +++ b/chrome/browser/resources/new_tab_page/modules/modules.ts
@@ -47,6 +47,11 @@ const SHORT_CLASS_NAME: string = 'short'; const TALL_CLASS_NAME: string = 'tall'; +// When a pair of short module containers are by each other, they are considered +// siblings and wrapped in another container. +const SHORT_MODULE_SIBLING_1: string = 'short-module-sibling-one'; +const SHORT_MODULE_SIBLING_2: string = 'short-module-sibling-two'; + /** Container for the NTP modules. */ export class ModulesElement extends PolymerElement { static get is() { @@ -197,6 +202,10 @@ this.modulesShownToUser = !moduleContainer.hidden; } if (loadTimeData.getBoolean('modulesRedesignedLayoutEnabled')) { + // Remove short module sibling container class name from short modules + // that were in a sibling container before. + moduleContainer.classList.toggle(SHORT_MODULE_SIBLING_1, false); + moduleContainer.classList.toggle(SHORT_MODULE_SIBLING_2, false); // Wrap pairs of sibling short modules in a container. All other // modules will be placed in a container of their own. if ((moduleContainer.classList.contains(SHORT_CLASS_NAME) || @@ -208,6 +217,7 @@ // hidden modules to the sibling container, so if a user reverts a // module from its hidden state, the module assumes its original // position. + moduleContainer.classList.toggle(SHORT_MODULE_SIBLING_2, true); moduleContainerParent = shortModuleSiblingsContainer; this.$.modules.appendChild(shortModuleSiblingsContainer); // If another visible short module is added, a visible tall module is @@ -229,6 +239,7 @@ // Add current short module to a new container since the next one is // short as well by setting its parent to be // 'shortModuleSiblingsContainer'. + moduleContainer.classList.toggle(SHORT_MODULE_SIBLING_1, true); shortModuleSiblingsContainer = this.ownerDocument.createElement('div'); shortModuleSiblingsContainer.classList.add( @@ -536,6 +547,7 @@ moduleContainers.indexOf((e.target as HTMLElement).parentElement!); const dragContainer = moduleContainers[dragIndex]; + const dropContainer = moduleContainers[dropIndex]; // To animate the modules as they are reordered we use the FLIP // (First, Last, Invert, Play) animation approach by @paullewis. @@ -546,9 +558,25 @@ const firstRects = undraggedModuleWrappers.map(moduleWrapper => { return moduleWrapper.getBoundingClientRect(); }); - - moduleContainers.splice(dragIndex, 1); - moduleContainers.splice(dropIndex, 0, dragContainer); + // If a tall module is dragged to a short module sibling container, the + // modules in the sibling container should move together. + // We add or subtract 1, from the drop index, to make sure the tall module + // moves behind or in front of the first module in the sibling container. + if (dragContainer.classList.contains(TALL_CLASS_NAME) && + dropContainer.classList.contains(SHORT_MODULE_SIBLING_1) && + dragIndex < dropIndex) { + moduleContainers.splice(dragIndex, 1); + moduleContainers.splice(dropIndex + 1, 0, dragContainer); + } else if ( + dragContainer.classList.contains(TALL_CLASS_NAME) && + dropContainer.classList.contains(SHORT_MODULE_SIBLING_2) && + dragIndex > dropIndex) { + moduleContainers.splice(dragIndex, 1); + moduleContainers.splice(dropIndex - 1, 0, dragContainer); + } else { + moduleContainers.splice(dragIndex, 1); + moduleContainers.splice(dropIndex, 0, dragContainer); + } this.appendModuleContainers_(moduleContainers); undraggedModuleWrappers.forEach((moduleWrapper, i) => {
diff --git a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_feature_behavior.js b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_feature_behavior.js index 1ab63ab..5c53104 100644 --- a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_feature_behavior.js +++ b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_feature_behavior.js
@@ -108,7 +108,8 @@ isPhoneHubCameraRollSetupRequired() { return this.isFeatureSupported(MultiDeviceFeature.PHONE_HUB_CAMERA_ROLL) && this.pageContentData.cameraRollAccessStatus === - PhoneHubFeatureAccessStatus.AVAILABLE_BUT_NOT_GRANTED; + PhoneHubFeatureAccessStatus.AVAILABLE_BUT_NOT_GRANTED && + this.isFeatureAllowedByPolicy(MultiDeviceFeature.PHONE_HUB_CAMERA_ROLL); }, /** @@ -118,7 +119,8 @@ isPhoneHubAppsSetupRequired() { return this.isFeatureSupported(MultiDeviceFeature.ECHE) && this.pageContentData.isPhoneHubPermissionsDialogSupported && - !this.pageContentData.isPhoneHubAppsAccessGranted; + !this.pageContentData.isPhoneHubAppsAccessGranted && + this.isFeatureAllowedByPolicy(MultiDeviceFeature.ECHE); }, /** @@ -127,7 +129,9 @@ */ isPhoneHubNotificationsSetupRequired() { return this.pageContentData.notificationAccessStatus === - PhoneHubFeatureAccessStatus.AVAILABLE_BUT_NOT_GRANTED; + PhoneHubFeatureAccessStatus.AVAILABLE_BUT_NOT_GRANTED && + this.isFeatureAllowedByPolicy( + MultiDeviceFeature.PHONE_HUB_NOTIFICATIONS); }, /**
diff --git a/chrome/browser/resources/vr/assets/PRESUBMIT.py b/chrome/browser/resources/vr/assets/PRESUBMIT.py index b5c0082..3a38c1c 100644 --- a/chrome/browser/resources/vr/assets/PRESUBMIT.py +++ b/chrome/browser/resources/vr/assets/PRESUBMIT.py
@@ -44,13 +44,16 @@ extension in {'sha1', 'png', 'wav'} and action in {'A', 'D'}): changed_asset_files[dirname].append((action, basename_without_extension)) if (extension == 'sha1' or basename == 'vr_assets_component_files.json'): - changed_assets = True + # See if there are actually changes or if it's just --files or --all: + if file.ChangedContents(): + changed_assets = True if basename == 'vr_assets_component_files.json': changed_component_list = True if basename == 'VERSION': - changed_version = True old_version = parse_version.ParseVersion(file.OldContents()) new_version = parse_version.ParseVersion(file.NewContents()) + if new_version != old_version: + changed_version = True local_version_filename = input_api.os_path.join( input_api.os_path.dirname(input_api.AffectedFiles()[0].LocalPath()),
diff --git a/chrome/browser/resources/webui_gallery/BUILD.gn b/chrome/browser/resources/webui_gallery/BUILD.gn index 199b563..7cc74663 100644 --- a/chrome/browser/resources/webui_gallery/BUILD.gn +++ b/chrome/browser/resources/webui_gallery/BUILD.gn
@@ -2,15 +2,15 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -import("//chrome/common/features.gni") import("//tools/grit/grit_rule.gni") +import("//tools/polymer/html_to_wrapper.gni") +import("//tools/typescript/ts_library.gni") import("//ui/webui/resources/tools/generate_grd.gni") +import("webui_gallery.gni") assert(!is_android) grit("resources") { - defines = chrome_grit_defines - # These arguments are needed since the grd is generated at build time. enable_input_discovery_for_gn_analyze = false source = "$target_gen_dir/resources.grd" @@ -28,6 +28,36 @@ generate_grd("build_grd") { grd_prefix = "webui_gallery" out_grd = "$target_gen_dir/resources.grd" - input_files = [ "webui_gallery.html" ] + input_files = [ + "demos/cr_button_demo.html", + "demos/cr_checkbox_demo.html", + "webui_gallery.html", + ] input_files_base_dir = rebase_path(".", "//") + deps = [ ":build_ts" ] + manifest_files = [ "$target_gen_dir/tsconfig.manifest" ] +} + +html_to_wrapper("html_wrapper_files") { + in_files = html_files +} + +copy("copy_ts_files") { + sources = ts_files + outputs = [ "$target_gen_dir/{{source_file_part}}" ] +} + +ts_library("build_ts") { + root_dir = target_gen_dir + out_dir = "$target_gen_dir/tsc" + tsconfig_base = "tsconfig_base.json" + in_files = ts_files + html_wrapper_files + deps = [ + "//third_party/polymer/v3_0:library", + "//ui/webui/resources:library", + ] + extra_deps = [ + ":copy_ts_files", + ":html_wrapper_files", + ] }
diff --git a/chrome/browser/resources/webui_gallery/app.html b/chrome/browser/resources/webui_gallery/app.html new file mode 100644 index 0000000..45f316e --- /dev/null +++ b/chrome/browser/resources/webui_gallery/app.html
@@ -0,0 +1,43 @@ +<style include="cr-nav-menu-item-style"> + :host { + display: flex; + height: 100%; + } + + #sidebar { + border-inline-end: 1px solid black; + box-sizing: border-box; + width: 256px; + } + + a { + text-decoration: none; + } + + iframe { + border: none; + height: 100%; + width: 100%; + } + + #main { + flex: 1; + } +</style> +<div id="sidebar"> + <cr-menu-selector> + <iron-selector selectable="a" + attr-for-selected="href" on-iron-activate="onSelectorActivate_" + on-click="onLinkClick_" selected-attribute="selected"> + <template is="dom-repeat" items="[[demos]]" + on-dom-change="onDomChange_" notify-dom-change> + <a role="menuitem" href="demos/[[item.url]]" + class="cr-nav-menu-item">[[item.name]]</a> + </template> + </iron-selector> + </cr-menu-selector> +</div> + +<div id="main"> + <iframe src="[[currentSrc_]]"></iframe> +</div>
diff --git a/chrome/browser/resources/webui_gallery/app.ts b/chrome/browser/resources/webui_gallery/app.ts new file mode 100644 index 0000000..8911714 --- /dev/null +++ b/chrome/browser/resources/webui_gallery/app.ts
@@ -0,0 +1,72 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import '//resources/cr_elements/cr_menu_selector/cr_menu_selector.js'; +import '//resources/cr_elements/cr_nav_menu_item_style.js'; +import '//resources/polymer/v3_0/iron-selector/iron-selector.js'; + +import {assert} from '//resources/js/assert_ts.js'; +import {PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + +import {getTemplate} from './app.html.js'; + +export class WebuiGalleryAppElement extends PolymerElement { + static get is() { + return 'webui-gallery-app'; + } + + static get template() { + return getTemplate(); + } + + static get properties() { + return { + demos: { + type: Array, + value: function() { + return [ + { + name: 'cr-button demo', + url: 'cr_button_demo.html', + }, + { + name: 'cr-checkbox demo', + url: 'cr_checkbox_demo.html', + } + ]; + }, + }, + + currentSrc_: String, + }; + } + + private currentSrc_: string; + + private onDomChange_() { + const first = this.shadowRoot!.querySelector('a'); + assert(first); + const selector = this.shadowRoot!.querySelector('iron-selector'); + assert(selector); + selector.selected = first.href; + this.currentSrc_ = first.href; + } + + private onLinkClick_(e: Event) { + e.preventDefault(); + } + + private onSelectorActivate_(e: CustomEvent<{selected: string}>) { + const demoUrl = e.detail.selected; + this.currentSrc_ = demoUrl; + } +} + +declare global { + interface HTMLElementTagNameMap { + 'webui-gallery-app': WebuiGalleryAppElement; + } +} + +customElements.define(WebuiGalleryAppElement.is, WebuiGalleryAppElement);
diff --git a/chrome/browser/resources/webui_gallery/demos/cr_button_demo.html b/chrome/browser/resources/webui_gallery/demos/cr_button_demo.html new file mode 100644 index 0000000..d2e07a4b --- /dev/null +++ b/chrome/browser/resources/webui_gallery/demos/cr_button_demo.html
@@ -0,0 +1,22 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>cr-button demo</title> + <style> + html, + body { + height: 100%; + overflow: hidden; + width: 100%; + } + + body { + margin: 0; + } + </style> + </head> + <body> + Demo content will be added here + </body> +</html>
diff --git a/chrome/browser/resources/webui_gallery/demos/cr_checkbox_demo.html b/chrome/browser/resources/webui_gallery/demos/cr_checkbox_demo.html new file mode 100644 index 0000000..55660ca --- /dev/null +++ b/chrome/browser/resources/webui_gallery/demos/cr_checkbox_demo.html
@@ -0,0 +1,22 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>cr-checkbox demo</title> + <style> + html, + body { + height: 100%; + overflow: hidden; + width: 100%; + } + + body { + margin: 0; + } + </style> + </head> + <body> + Demo content will be added here + </body> +</html>
diff --git a/chrome/browser/resources/webui_gallery/tsconfig_base.json b/chrome/browser/resources/webui_gallery/tsconfig_base.json new file mode 100644 index 0000000..de14880 --- /dev/null +++ b/chrome/browser/resources/webui_gallery/tsconfig_base.json
@@ -0,0 +1,7 @@ +{ + "extends": "../../../../tools/typescript/tsconfig_base.json", + "compilerOptions": { + "noUnusedLocals": false, + "strictPropertyInitialization": false + } +}
diff --git a/chrome/browser/resources/webui_gallery/webui_gallery.gni b/chrome/browser/resources/webui_gallery/webui_gallery.gni new file mode 100644 index 0000000..b11378e --- /dev/null +++ b/chrome/browser/resources/webui_gallery/webui_gallery.gni
@@ -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. + +# Files holding a Polymer element definition AND have an equivalent .html file. +web_component_files = [ "app.ts" ] + +# Files that are passed as input to html_to_wrapper(). +html_files = [] +foreach(f, web_component_files) { + html_files += [ string_replace(f, ".ts", ".html") ] +} + +# Files that are generated by html_to_wrapper(). +html_wrapper_files = [] +foreach(f, html_files) { + html_wrapper_files += [ f + ".ts" ] +} + +ts_files = web_component_files
diff --git a/chrome/browser/resources/webui_gallery/webui_gallery.html b/chrome/browser/resources/webui_gallery/webui_gallery.html index 95448d1..6f9f6ef 100644 --- a/chrome/browser/resources/webui_gallery/webui_gallery.html +++ b/chrome/browser/resources/webui_gallery/webui_gallery.html
@@ -1,12 +1,24 @@ -<!doctype html> +<!DOCTYPE html> <html dir="$i18n{textdirection}" lang="$i18n{language}"> <head> <meta charset="utf-8"> - <title>WebUI Gallery</title> + <title>WebUI gallery</title> <style> + html, + body { + height: 100%; + overflow: hidden; + width: 100%; + } + + body { + margin: 0; + } </style> </head> <body> - Coming soon + <link rel="stylesheet" href="chrome://resources/css/text_defaults_md.css"> + <script type="module" src="app.js"></script> + <webui-gallery-app></webui-gallery-app> </body> </html>
diff --git a/chrome/browser/safe_browsing/extension_telemetry/extension_telemetry_service.cc b/chrome/browser/safe_browsing/extension_telemetry/extension_telemetry_service.cc index 7e1fc1a..6082ccb 100644 --- a/chrome/browser/safe_browsing/extension_telemetry/extension_telemetry_service.cc +++ b/chrome/browser/safe_browsing/extension_telemetry/extension_telemetry_service.cc
@@ -23,7 +23,10 @@ #include "chrome/browser/safe_browsing/extension_telemetry/extension_telemetry_uploader.h" #include "chrome/browser/safe_browsing/extension_telemetry/remote_host_contacted_signal_processor.h" #include "chrome/browser/safe_browsing/extension_telemetry/tabs_execute_script_signal_processor.h" +#include "chrome/browser/signin/identity_manager_factory.h" #include "components/prefs/pref_service.h" +#include "components/safe_browsing/core/browser/sync/safe_browsing_primary_account_token_fetcher.h" +#include "components/safe_browsing/core/browser/sync/sync_utils.h" #include "components/safe_browsing/core/common/features.h" #include "components/safe_browsing/core/common/proto/csd.pb.h" #include "components/safe_browsing/core/common/safe_browsing_prefs.h" @@ -271,7 +274,8 @@ auto callback = base::BindOnce(&ExtensionTelemetryService::OnUploadComplete, weak_factory_.GetWeakPtr()); active_uploader_ = std::make_unique<ExtensionTelemetryUploader>( - std::move(callback), url_loader_factory_, std::move(upload_data)); + std::move(callback), url_loader_factory_, std::move(upload_data), + GetTokenFetcher()); active_uploader_->Start(); } @@ -312,7 +316,8 @@ auto callback = base::BindOnce(&ExtensionTelemetryService::OnUploadComplete, weak_factory_.GetWeakPtr()); active_uploader_ = std::make_unique<ExtensionTelemetryUploader>( - std::move(callback), url_loader_factory_, std::move(upload_data)); + std::move(callback), url_loader_factory_, std::move(upload_data), + GetTokenFetcher()); active_uploader_->Start(); } else { active_report_.reset(); @@ -388,6 +393,20 @@ return telemetry_report_pb; } +std::unique_ptr<SafeBrowsingTokenFetcher> +ExtensionTelemetryService::GetTokenFetcher() { + DCHECK(!profile_->IsOffTheRecord() && + IsEnhancedProtectionEnabled(*profile_->GetPrefs())); + signin::IdentityManager* identity_manager = + IdentityManagerFactory::GetForProfile(profile_); + if (identity_manager && + safe_browsing::SyncUtils::IsPrimaryAccountSignedIn(identity_manager)) { + return std::make_unique<SafeBrowsingPrimaryAccountTokenFetcher>( + identity_manager); + } + return nullptr; +} + void ExtensionTelemetryService::DumpReportForTest( const ExtensionTelemetryReportRequest& report) { base::Time creation_time =
diff --git a/chrome/browser/safe_browsing/extension_telemetry/extension_telemetry_service.h b/chrome/browser/safe_browsing/extension_telemetry/extension_telemetry_service.h index 064e764e..69c469f 100644 --- a/chrome/browser/safe_browsing/extension_telemetry/extension_telemetry_service.h +++ b/chrome/browser/safe_browsing/extension_telemetry/extension_telemetry_service.h
@@ -40,6 +40,7 @@ class ExtensionTelemetryReportRequest_ExtensionInfo; class ExtensionTelemetryUploader; class ExtensionTelemetryPersister; +class SafeBrowsingTokenFetcher; // This class process extension signals and reports telemetry for a given // profile (regular profile only). It is used exclusively on the UI thread. @@ -107,6 +108,10 @@ void UploadPersistedFile(std::string report, bool success); + // Creates access token fetcher based on profile log-in status. + // Returns nullptr when the user is not signed in. + std::unique_ptr<SafeBrowsingTokenFetcher> GetTokenFetcher(); + std::unique_ptr<safe_browsing::ExtensionTelemetryPersister> persister_; // The profile with which this instance of the service is associated.
diff --git a/chrome/browser/safe_browsing/extension_telemetry/extension_telemetry_service_factory.cc b/chrome/browser/safe_browsing/extension_telemetry/extension_telemetry_service_factory.cc index b306e56..a64808ed 100644 --- a/chrome/browser/safe_browsing/extension_telemetry/extension_telemetry_service_factory.cc +++ b/chrome/browser/safe_browsing/extension_telemetry/extension_telemetry_service_factory.cc
@@ -70,5 +70,4 @@ const { return true; } - } // namespace safe_browsing
diff --git a/chrome/browser/safe_browsing/extension_telemetry/extension_telemetry_service_unittest.cc b/chrome/browser/safe_browsing/extension_telemetry/extension_telemetry_service_unittest.cc index a3a7526..72c69c8 100644 --- a/chrome/browser/safe_browsing/extension_telemetry/extension_telemetry_service_unittest.cc +++ b/chrome/browser/safe_browsing/extension_telemetry/extension_telemetry_service_unittest.cc
@@ -179,7 +179,6 @@ EXPECT_FALSE(IsTelemetryServiceEnabled()); // Destruct and restart service and verify that it starts disabled. - telemetry_service_ = std::make_unique<ExtensionTelemetryService>( &profile_, test_url_loader_factory_.GetSafeWeakWrapper(), extension_registry_, extension_prefs_);
diff --git a/chrome/browser/safe_browsing/extension_telemetry/extension_telemetry_uploader.cc b/chrome/browser/safe_browsing/extension_telemetry/extension_telemetry_uploader.cc index c479ed4..8539549 100644 --- a/chrome/browser/safe_browsing/extension_telemetry/extension_telemetry_uploader.cc +++ b/chrome/browser/safe_browsing/extension_telemetry/extension_telemetry_uploader.cc
@@ -9,6 +9,9 @@ #include "base/bind.h" #include "base/metrics/histogram_functions.h" +#include "chrome/browser/signin/identity_manager_factory.h" +#include "components/safe_browsing/core/browser/sync/safe_browsing_primary_account_token_fetcher.h" +#include "components/safe_browsing/core/common/utils.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" #include "net/base/load_flags.h" @@ -44,7 +47,8 @@ destination: GOOGLE_OWNED_SERVICE } policy { - cookies_allowed: NO + cookies_allowed: YES + cookies_store: "Safe Browsing cookie store" setting: "Users can enable this feature by selecting 'Enhanced protection' " "under the Security->Safe Browsing setting. The feature is disabled by " @@ -107,17 +111,19 @@ ExtensionTelemetryUploader::ExtensionTelemetryUploader( OnUploadCallback callback, const scoped_refptr<network::SharedURLLoaderFactory>& url_loader_factory, - std::unique_ptr<std::string> upload_data) + std::unique_ptr<std::string> upload_data, + std::unique_ptr<SafeBrowsingTokenFetcher> token_fetcher) : callback_(std::move(callback)), url_loader_factory_(url_loader_factory), upload_data_(std::move(upload_data)), current_backoff_(base::Seconds(kInitialBackoffSeconds)), - num_upload_retries_(0) {} + num_upload_retries_(0), + token_fetcher_(std::move(token_fetcher)) {} void ExtensionTelemetryUploader::Start() { upload_start_time_ = base::TimeTicks::Now(); RecordUploadSize(upload_data_->size()); - SendRequest(); + MaybeSendRequestWithAccessToken(); } // static @@ -125,12 +131,27 @@ return kUploadUrl; } -void ExtensionTelemetryUploader::SendRequest() { +void ExtensionTelemetryUploader::MaybeSendRequestWithAccessToken() { + if (token_fetcher_) { + token_fetcher_->Start(base::BindOnce( + &ExtensionTelemetryUploader::SendRequest, weak_factory_.GetWeakPtr())); + } else { + SendRequest(std::string()); + } +} + +void ExtensionTelemetryUploader::SendRequest(const std::string& access_token) { auto resource_request = std::make_unique<network::ResourceRequest>(); resource_request->url = GURL(kUploadUrl); resource_request->method = "POST"; resource_request->load_flags = net::LOAD_DISABLE_CACHE; - resource_request->credentials_mode = network::mojom::CredentialsMode::kOmit; + if (!access_token.empty()) { + SetAccessTokenAndClearCookieInResourceRequest(resource_request.get(), + access_token); + } else { + resource_request->credentials_mode = + network::mojom::CredentialsMode::kInclude; + } url_loader_ = network::SimpleURLLoader::Create( std::move(resource_request), kSafeBrowsingExtensionTelemetryTrafficAnnotation); @@ -172,8 +193,9 @@ } else { content::GetUIThreadTaskRunner({})->PostDelayedTask( FROM_HERE, - base::BindOnce(&ExtensionTelemetryUploader::SendRequest, - weak_factory_.GetWeakPtr()), + base::BindOnce( + &ExtensionTelemetryUploader::MaybeSendRequestWithAccessToken, + weak_factory_.GetWeakPtr()), current_backoff_); current_backoff_ *= kBackoffFactor; num_upload_retries_++;
diff --git a/chrome/browser/safe_browsing/extension_telemetry/extension_telemetry_uploader.h b/chrome/browser/safe_browsing/extension_telemetry/extension_telemetry_uploader.h index 4280380..acea194 100644 --- a/chrome/browser/safe_browsing/extension_telemetry/extension_telemetry_uploader.h +++ b/chrome/browser/safe_browsing/extension_telemetry/extension_telemetry_uploader.h
@@ -11,6 +11,7 @@ #include "base/callback.h" #include "base/memory/weak_ptr.h" #include "base/time/time.h" +#include "chrome/browser/profiles/profile.h" namespace network { class SharedURLLoaderFactory; @@ -19,6 +20,8 @@ namespace safe_browsing { +class SafeBrowsingTokenFetcher; + // An uploader of extension telemetry reports. An upload is initiated by // creating an instance of this object and then calling its StartUpload method. // The upload can be cancelled by deleting the uploader instance. The instance @@ -37,7 +40,8 @@ ExtensionTelemetryUploader( OnUploadCallback callback, const scoped_refptr<network::SharedURLLoaderFactory>& url_loader_factory, - std::unique_ptr<std::string> upload_data); + std::unique_ptr<std::string> upload_data, + std::unique_ptr<SafeBrowsingTokenFetcher> token_fetcher); // Start the upload by sending a request. This method performs retries if // necessary and finally calls |callback_|. It must be called on the UI @@ -47,8 +51,11 @@ static std::string GetUploadURLForTest(); private: + // Determines whether to send a request with access token. + void MaybeSendRequestWithAccessToken(); + // Sends a single network request. - void SendRequest(); + void SendRequest(const std::string& access_token); // Callback when SimpleURLLoader gets the response. void OnURLLoaderComplete(std::unique_ptr<std::string> response_body); @@ -65,6 +72,10 @@ base::TimeDelta current_backoff_; int num_upload_retries_; base::TimeTicks upload_start_time_; + // The token fetcher used to attach OAuth access tokens to requests for + // appropriately consented users. It can be a nullptr when the user is + // not signed in. + std::unique_ptr<SafeBrowsingTokenFetcher> token_fetcher_; base::WeakPtrFactory<ExtensionTelemetryUploader> weak_factory_{this}; };
diff --git a/chrome/browser/safe_browsing/extension_telemetry/extension_telemetry_uploader_unittest.cc b/chrome/browser/safe_browsing/extension_telemetry/extension_telemetry_uploader_unittest.cc index 34a0996a..48d22b6 100644 --- a/chrome/browser/safe_browsing/extension_telemetry/extension_telemetry_uploader_unittest.cc +++ b/chrome/browser/safe_browsing/extension_telemetry/extension_telemetry_uploader_unittest.cc
@@ -5,19 +5,49 @@ #include <string> #include <utility> +#include "base/test/bind.h" #include "base/test/metrics/histogram_tester.h" +#include "chrome/browser/profiles/profile.h" #include "chrome/browser/safe_browsing/extension_telemetry/extension_telemetry_uploader.h" +#include "chrome/browser/signin/identity_test_environment_profile_adaptor.h" +#include "chrome/test/base/testing_profile.h" +#include "chrome/test/base/testing_profile_manager.h" +#include "components/safe_browsing/core/browser/safe_browsing_token_fetcher.h" #include "components/safe_browsing/core/common/proto/csd.pb.h" +#include "components/safe_browsing/core/common/safe_browsing_prefs.h" #include "content/public/test/browser_task_environment.h" #include "net/base/load_flags.h" #include "net/http/http_status_code.h" #include "services/network/public/cpp/shared_url_loader_factory.h" #include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h" #include "services/network/test/test_url_loader_factory.h" +#include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" namespace safe_browsing { +class TestSafeBrowsingTokenFetcher : public SafeBrowsingTokenFetcher { + public: + TestSafeBrowsingTokenFetcher() = default; + ~TestSafeBrowsingTokenFetcher() override { RunAccessTokenCallback(""); } + + void Start(Callback callback) override { + callback_ = std::move(callback); + was_start_called_ = true; + } + void RunAccessTokenCallback(std::string token) { + if (callback_) { + std::move(callback_).Run(token); + } + } + bool WasStartCalled() { return was_start_called_; } + MOCK_METHOD1(OnInvalidAccessToken, void(const std::string&)); + + private: + Callback callback_; + bool was_start_called_ = false; +}; + class ExtensionTelemetryUploaderTest : public testing::Test { public: void OnUploadTestCallback(bool success) { upload_success_ = success; } @@ -32,7 +62,7 @@ base::BindOnce(&ExtensionTelemetryUploaderTest::OnUploadTestCallback, base::Unretained(this)), test_url_loader_factory_.GetSafeWeakWrapper(), - std::make_unique<std::string>(upload_data_)); + std::make_unique<std::string>(upload_data_), nullptr); } std::string upload_data_; @@ -43,6 +73,64 @@ std::unique_ptr<ExtensionTelemetryUploader> uploader_; }; +TEST_F(ExtensionTelemetryUploaderTest, FetchAccessTokenForReport) { + auto token_fetcher = std::make_unique<TestSafeBrowsingTokenFetcher>(); + auto* raw_token_fetcher = token_fetcher.get(); + std::string access_token = "testing_access_token"; + network::TestURLLoaderFactory test_url_loader_factory; + test_url_loader_factory.SetInterceptor( + base::BindLambdaForTesting([&](const network::ResourceRequest& request) { + std::string header_value; + bool found_header = request.headers.GetHeader( + net::HttpRequestHeaders::kAuthorization, &header_value); + EXPECT_EQ(found_header, true); + EXPECT_EQ(header_value, "Bearer " + access_token); + })); + + test_url_loader_factory.AddResponse( + ExtensionTelemetryUploader::GetUploadURLForTest(), upload_data_, + net::HTTP_OK); + std::unique_ptr<ExtensionTelemetryUploader> sign_in_uploader = + std::make_unique<ExtensionTelemetryUploader>( + base::BindOnce(&ExtensionTelemetryUploaderTest::OnUploadTestCallback, + base::Unretained(this)), + test_url_loader_factory.GetSafeWeakWrapper(), + std::make_unique<std::string>(upload_data_), + std::move(token_fetcher)); + sign_in_uploader->Start(); + task_environment_.FastForwardUntilNoTasksRemain(); + // Expects token fetcher to be called. + EXPECT_EQ(raw_token_fetcher->WasStartCalled(), true); + raw_token_fetcher->RunAccessTokenCallback(access_token); +} + +TEST_F(ExtensionTelemetryUploaderTest, AttachZwiebackCookieForReport) { + network::TestURLLoaderFactory test_url_loader_factory; + test_url_loader_factory.SetInterceptor( + base::BindLambdaForTesting([&](const network::ResourceRequest& request) { + std::string header_value; + bool found_header = request.headers.GetHeader( + net::HttpRequestHeaders::kAuthorization, &header_value); + // When access token is not fetched, header does not include access + // token. + EXPECT_EQ(found_header, false); + // Set the credential mode to kInclude by default. + EXPECT_EQ(request.credentials_mode, + network::mojom::CredentialsMode::kInclude); + })); + test_url_loader_factory.AddResponse( + ExtensionTelemetryUploader::GetUploadURLForTest(), upload_data_, + net::HTTP_OK); + std::unique_ptr<ExtensionTelemetryUploader> sign_out_uploader = + std::make_unique<ExtensionTelemetryUploader>( + base::BindOnce(&ExtensionTelemetryUploaderTest::OnUploadTestCallback, + base::Unretained(this)), + test_url_loader_factory.GetSafeWeakWrapper(), + std::make_unique<std::string>(upload_data_), nullptr); + sign_out_uploader->Start(); + task_environment_.FastForwardUntilNoTasksRemain(); +} + TEST_F(ExtensionTelemetryUploaderTest, AbortsWithoutRetries) { // Aborts upload without retries if response code < 500 test_url_loader_factory_.AddResponse(
diff --git a/chrome/browser/safety_check/android/BUILD.gn b/chrome/browser/safety_check/android/BUILD.gn index 99539bd..68a227b 100644 --- a/chrome/browser/safety_check/android/BUILD.gn +++ b/chrome/browser/safety_check/android/BUILD.gn
@@ -53,10 +53,8 @@ "//components/password_manager/core/browser:password_manager_java_enums", "//components/signin/public/android:java", "//content/public/android:content_java", - "//third_party/android_deps:android_support_v7_appcompat_java", "//third_party/android_deps:guava_android_java", "//third_party/androidx:androidx_annotation_annotation_java", - "//third_party/androidx:androidx_fragment_fragment_java", "//third_party/androidx:androidx_lifecycle_lifecycle_common_java", "//third_party/androidx:androidx_lifecycle_lifecycle_common_java8_java", "//third_party/androidx:androidx_lifecycle_lifecycle_livedata_core_java",
diff --git a/chrome/browser/settings/BUILD.gn b/chrome/browser/settings/BUILD.gn index d2b04b8..baf3a8aa 100644 --- a/chrome/browser/settings/BUILD.gn +++ b/chrome/browser/settings/BUILD.gn
@@ -12,7 +12,6 @@ "//components/browser_ui/settings/android:java", "//components/prefs/android:java", "//components/user_prefs/android:java", - "//third_party/androidx:androidx_fragment_fragment_java", ] } @@ -34,7 +33,6 @@ "//chrome/test/android:chrome_java_test_support", "//components/browser_ui/settings/android:java", "//content/public/test/android:content_java_test_support", - "//third_party/android_deps:android_support_v7_appcompat_java", "//third_party/android_deps:espresso_java", "//third_party/android_deps:guava_android_java", "//third_party/android_support_test_runner:rules_java",
diff --git a/chrome/browser/site_isolation/site_per_process_interactive_browsertest.cc b/chrome/browser/site_isolation/site_per_process_interactive_browsertest.cc index d1a3c94..513e7fa8 100644 --- a/chrome/browser/site_isolation/site_per_process_interactive_browsertest.cc +++ b/chrome/browser/site_isolation/site_per_process_interactive_browsertest.cc
@@ -227,7 +227,7 @@ // Generate a few keyboard events and route them to currently focused frame. // We wait for replies to be sent back from the page, since keystrokes may // take time to propagate to the renderer's main thread. - content::DOMMessageQueue msg_queue; + content::DOMMessageQueue msg_queue(web_contents); std::string reply; SimulateKeyPress(web_contents, ui::DomKey::FromCharacter('F'), ui::DomCode::US_F, ui::VKEY_F, false, false, false, false); @@ -307,7 +307,7 @@ // Helper to simulate a tab press and wait for a focus message. auto press_tab_and_wait_for_message = [web_contents](bool reverse) { - content::DOMMessageQueue msg_queue; + content::DOMMessageQueue msg_queue(web_contents); std::string reply; SimulateKeyPress(web_contents, ui::DomKey::TAB, ui::DomCode::TAB, ui::VKEY_TAB, false, reverse /* shift */, false, false); @@ -401,7 +401,7 @@ // Helper to simulate a tab press and wait for a focus message. auto press_tab_and_wait_for_message = [web_contents](bool reverse) { - content::DOMMessageQueue msg_queue; + content::DOMMessageQueue msg_queue(web_contents); std::string reply; SimulateKeyPress(web_contents, ui::DomKey::TAB, ui::DomCode::TAB, ui::VKEY_TAB, false, reverse /* shift */, false, false); @@ -543,7 +543,7 @@ // Helper to simulate a tab press and wait for a focus message. auto press_tab_and_wait_for_message = [web_contents](bool reverse) { - content::DOMMessageQueue msg_queue; + content::DOMMessageQueue msg_queue(web_contents); std::string reply; SimulateKeyPress(web_contents, ui::DomKey::TAB, ui::DomCode::TAB, ui::VKEY_TAB, false, reverse /* shift */, false, false); @@ -554,7 +554,7 @@ auto click_element_and_wait_for_message = [web_contents](const gfx::Point& point) { - content::DOMMessageQueue msg_queue; + content::DOMMessageQueue msg_queue(web_contents); auto content_bounds = web_contents->GetContainerBounds(); ui_controls::SendMouseMove(point.x() + content_bounds.x(), @@ -777,7 +777,7 @@ std::set<std::string> expected_events = {"main_frame", "child"}; AddResizeListener(child, GetScreenSize()); { - content::DOMMessageQueue queue; + content::DOMMessageQueue queue(web_contents); FullscreenNotificationObserver observer(browser()); EXPECT_TRUE(ExecuteScript(child, "activateFullscreen()")); WaitForMultipleFullscreenEvents(expected_events, queue); @@ -812,7 +812,7 @@ // original size. AddResizeListener(child, original_child_size); { - content::DOMMessageQueue queue; + content::DOMMessageQueue queue(web_contents); FullscreenNotificationObserver observer(browser()); EXPECT_TRUE(ExecuteScript(child, "exitFullscreen()")); WaitForMultipleFullscreenEvents(expected_events, queue); @@ -876,7 +876,7 @@ // (3) the browser has finished the fullscreen transition. std::set<std::string> expected_events = {"main_frame", "child", "grandchild"}; { - content::DOMMessageQueue queue; + content::DOMMessageQueue queue(web_contents); FullscreenNotificationObserver fullscreen_observer(browser()); EXPECT_TRUE(ExecuteScript(grandchild, "activateFullscreen()")); WaitForMultipleFullscreenEvents(expected_events, queue); @@ -906,7 +906,7 @@ // Now exit fullscreen from the subframe. AddResizeListener(grandchild, original_grandchild_size); { - content::DOMMessageQueue queue; + content::DOMMessageQueue queue(web_contents); FullscreenNotificationObserver fullscreen_observer(browser()); switch (exit_method) { case FullscreenExitMethod::JS_CALL: @@ -1037,7 +1037,7 @@ // response, (2) |c_middle| is resized to fill the whole screen, and (3) the // browser finishes the fullscreen transition. { - content::DOMMessageQueue queue; + content::DOMMessageQueue queue(web_contents); FullscreenNotificationObserver fullscreen_observer(browser()); EXPECT_TRUE(ExecuteScript(c_middle, "activateFullscreen()")); WaitForMultipleFullscreenEvents(expected_events, queue); @@ -1077,7 +1077,7 @@ // resized back to its original size. AddResizeListener(c_middle, c_middle_original_size); { - content::DOMMessageQueue queue; + content::DOMMessageQueue queue(web_contents); FullscreenNotificationObserver fullscreen_observer(browser()); ASSERT_TRUE(ui_test_utils::SendKeyPressSync(browser(), ui::VKEY_ESCAPE, false, false, false, false));
diff --git a/chrome/browser/ssl/certificate_transparency_browsertest.cc b/chrome/browser/ssl/certificate_transparency_browsertest.cc new file mode 100644 index 0000000..091ac58 --- /dev/null +++ b/chrome/browser/ssl/certificate_transparency_browsertest.cc
@@ -0,0 +1,237 @@ +// 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/run_loop.h" +#include "base/task/current_thread.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/net/system_network_context_manager.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ssl/cert_verifier_browser_test.h" +#include "chrome/browser/ssl/ssl_browsertest_util.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/tabs/tab_strip_model.h" +#include "chrome/test/base/in_process_browser_test.h" +#include "chrome/test/base/ui_test_utils.h" +#include "components/certificate_transparency/pref_names.h" +#include "components/policy/core/browser/browser_policy_connector.h" +#include "components/policy/core/common/mock_configuration_policy_provider.h" +#include "components/policy/core/common/policy_map.h" +#include "components/policy/policy_constants.h" +#include "components/prefs/testing_pref_service.h" +#include "content/public/browser/network_service_instance.h" +#include "content/public/test/browser_test.h" +#include "crypto/sha2.h" +#include "net/base/hash_value.h" +#include "net/cert/asn1_util.h" +#include "net/cert/x509_util.h" +#include "net/dns/mock_host_resolver.h" +#include "net/test/cert_test_util.h" +#include "net/test/embedded_test_server/embedded_test_server.h" +#include "net/test/test_data_directory.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/abseil-cpp/absl/types/optional.h" + +namespace { + +// Returns the Sha256 hash of the SPKI of |cert|. +net::HashValue GetSPKIHash(const CRYPTO_BUFFER* cert) { + base::StringPiece spki_bytes; + EXPECT_TRUE(net::asn1::ExtractSPKIFromDERCert( + net::x509_util::CryptoBufferAsStringPiece(cert), &spki_bytes)); + net::HashValue sha256(net::HASH_VALUE_SHA256); + crypto::SHA256HashString(spki_bytes, sha256.data(), crypto::kSHA256Length); + return sha256; +} + +} // namespace + +// Class used to run browser tests that verify SSL UI triggered due to +// Certificate Transparency verification failures/successes. +class CertificateTransparencyBrowserTest : public CertVerifierBrowserTest { + public: + CertificateTransparencyBrowserTest() + : https_server_(net::EmbeddedTestServer::TYPE_HTTPS) { + SystemNetworkContextManager::SetEnableCertificateTransparencyForTesting( + true); + } + + CertificateTransparencyBrowserTest( + const CertificateTransparencyBrowserTest&) = delete; + CertificateTransparencyBrowserTest& operator=( + const CertificateTransparencyBrowserTest&) = delete; + + ~CertificateTransparencyBrowserTest() override { + SystemNetworkContextManager::SetEnableCertificateTransparencyForTesting( + absl::nullopt); + } + + void SetUpOnMainThread() override { + CertVerifierBrowserTest::SetUpOnMainThread(); + host_resolver()->AddRule("*", "127.0.0.1"); + https_server_.AddDefaultHandlers(GetChromeTestDataDir()); + } + + void SetUp() override { + policy_provider_.SetDefaultReturns( + /*is_initialization_complete_return=*/true, + /*is_first_policy_load_complete_return=*/true); + policy::BrowserPolicyConnector::SetPolicyProviderForTesting( + &policy_provider_); + + CertVerifierBrowserTest::SetUp(); + } + + // Sets the policy identified by |policy_name| to the value specified by + // |list_values|, ensuring that the corresponding list pref |pref_name| is + // updated to match. |policy_name| must specify a policy that is a list of + // string values. + void ConfigureStringListPolicy(PrefService* pref_service, + const char* policy_name, + const char* pref_name, + const std::vector<std::string>& list_values) { + base::Value policy_value(base::Value::Type::LIST); + for (const auto& value : list_values) { + policy_value.Append(value); + } + policy::PolicyMap policy_map; + policy_map.Set(policy_name, policy::POLICY_LEVEL_MANDATORY, + policy::POLICY_SCOPE_MACHINE, policy::POLICY_SOURCE_CLOUD, + std::move(policy_value), nullptr); + + EXPECT_NO_FATAL_FAILURE(UpdateChromePolicy(policy_map)); + + const base::Value* pref_value = pref_service->GetList(pref_name); + ASSERT_TRUE(pref_value); + std::vector<std::string> pref_values; + for (const auto& value : pref_value->GetListDeprecated()) { + ASSERT_TRUE(value.is_string()); + pref_values.push_back(value.GetString()); + } + EXPECT_THAT(pref_values, testing::UnorderedElementsAreArray(list_values)); + } + + net::EmbeddedTestServer* https_server() { return &https_server_; } + + private: + void UpdateChromePolicy(const policy::PolicyMap& policies) { + policy_provider_.UpdateChromePolicy(policies); + ASSERT_TRUE(base::CurrentThread::Get()); + + base::RunLoop().RunUntilIdle(); + + content::FlushNetworkServiceInstanceForTesting(); + } + + net::EmbeddedTestServer https_server_; + + testing::NiceMock<policy::MockConfigurationPolicyProvider> policy_provider_; +}; + +// Visit an HTTPS page that has a publicly trusted certificate issued after +// the Certificate Transparency requirement date of April 2018. The connection +// should be blocked, as the server will not be providing CT details, and the +// Chrome CT Policy should be being enforced. +IN_PROC_BROWSER_TEST_F(CertificateTransparencyBrowserTest, + EnforcedAfterApril2018) { + ASSERT_TRUE(https_server()->Start()); + + net::CertVerifyResult verify_result; + verify_result.verified_cert = + net::ImportCertFromFile(net::GetTestCertsDirectory(), "may_2018.pem"); + ASSERT_TRUE(verify_result.verified_cert); + verify_result.is_issued_by_known_root = true; + verify_result.public_key_hashes.push_back( + GetSPKIHash(verify_result.verified_cert->cert_buffer())); + + mock_cert_verifier()->AddResultForCert(https_server()->GetCertificate().get(), + verify_result, net::OK); + + ASSERT_TRUE(ui_test_utils::NavigateToURL( + browser(), https_server()->GetURL("/ssl/google.html"))); + + ssl_test_util::CheckSecurityState( + browser()->tab_strip_model()->GetActiveWebContents(), + net::CERT_STATUS_CERTIFICATE_TRANSPARENCY_REQUIRED, + security_state::DANGEROUS, + ssl_test_util::AuthState::SHOWING_INTERSTITIAL); +} + +// Visit an HTTPS page that has a publicly trusted certificate issued after +// the Certificate Transparency requirement date of April 2018. The connection +// would normally be blocked, as the server will not be providing CT details, +// and the Chrome CT Policy should be being enforced; however, because a policy +// configuration exists that disables CT enforcement for that cert, the +// connection should succeed. +IN_PROC_BROWSER_TEST_F(CertificateTransparencyBrowserTest, + EnforcedAfterApril2018UnlessPoliciesSet) { + ASSERT_TRUE(https_server()->Start()); + + net::CertVerifyResult verify_result; + verify_result.verified_cert = + net::ImportCertFromFile(net::GetTestCertsDirectory(), "may_2018.pem"); + ASSERT_TRUE(verify_result.verified_cert); + verify_result.is_issued_by_known_root = true; + verify_result.public_key_hashes.push_back( + GetSPKIHash(verify_result.verified_cert->cert_buffer())); + + mock_cert_verifier()->AddResultForCert(https_server()->GetCertificate().get(), + verify_result, net::OK); + + ASSERT_NO_FATAL_FAILURE(ConfigureStringListPolicy( + browser()->profile()->GetPrefs(), + policy::key::kCertificateTransparencyEnforcementDisabledForCas, + certificate_transparency::prefs::kCTExcludedSPKIs, + {verify_result.public_key_hashes.back().ToString()})); + + ASSERT_TRUE(ui_test_utils::NavigateToURL( + browser(), https_server()->GetURL("/ssl/google.html"))); + ssl_test_util::CheckSecurityState( + browser()->tab_strip_model()->GetActiveWebContents(), + ssl_test_util::CertError::NONE, security_state::SECURE, + ssl_test_util::AuthState::NONE); +} + +// Visit an HTTPS page that has a certificate issued by a certificate authority +// that is trusted in a root store that Chrome does not consider consistently +// secure. In the case where the certificate was issued after the Certificate +// Transparency requirement date of April 2018 the connection would normally be +// blocked, as the server will not be providing CT details, and the Chrome CT +// Policy should be being enforced; however, because a policy configuration +// exists that disables CT enforcement for that Legacy cert, the connection +// should succeed. For more detail, see /net/docs/certificate-transparency.md +IN_PROC_BROWSER_TEST_F(CertificateTransparencyBrowserTest, + LegacyEnforcedAfterApril2018UnlessPoliciesSet) { + ASSERT_TRUE(https_server()->Start()); + + net::CertVerifyResult verify_result; + verify_result.verified_cert = + net::ImportCertFromFile(net::GetTestCertsDirectory(), "may_2018.pem"); + ASSERT_TRUE(verify_result.verified_cert); + verify_result.is_issued_by_known_root = true; + + // We'll use a SPKI hash corresponding to the Federal Common Policy CA as + // captured at https://fpki.idmanagement.gov/announcements/mspkichanges/ + const net::SHA256HashValue legacy_spki_hash = { + 0x8e, 0x8b, 0x56, 0xf5, 0x91, 0x8a, 0x25, 0xbd, 0x85, 0xdc, 0xe7, + 0x66, 0x63, 0xfd, 0x94, 0xcc, 0x23, 0x69, 0x0f, 0x10, 0xea, 0x95, + 0x86, 0x61, 0x31, 0x71, 0xc6, 0xf8, 0x37, 0x88, 0x90, 0xd5}; + verify_result.public_key_hashes.push_back(net::HashValue(legacy_spki_hash)); + + mock_cert_verifier()->AddResultForCert(https_server()->GetCertificate().get(), + verify_result, net::OK); + + ASSERT_NO_FATAL_FAILURE(ConfigureStringListPolicy( + browser()->profile()->GetPrefs(), + policy::key::kCertificateTransparencyEnforcementDisabledForLegacyCas, + certificate_transparency::prefs::kCTExcludedLegacySPKIs, + {verify_result.public_key_hashes.back().ToString()})); + + ASSERT_TRUE(ui_test_utils::NavigateToURL( + browser(), https_server()->GetURL("/ssl/google.html"))); + ssl_test_util::CheckSecurityState( + browser()->tab_strip_model()->GetActiveWebContents(), + ssl_test_util::CertError::NONE, security_state::SECURE, + ssl_test_util::AuthState::NONE); +}
diff --git a/chrome/browser/ssl/ssl_browsertest.cc b/chrome/browser/ssl/ssl_browsertest.cc index 70030f9..5be642f5 100644 --- a/chrome/browser/ssl/ssl_browsertest.cc +++ b/chrome/browser/ssl/ssl_browsertest.cc
@@ -77,7 +77,6 @@ #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/test_launcher_utils.h" #include "chrome/test/base/ui_test_utils.h" -#include "components/certificate_transparency/pref_names.h" #include "components/content_settings/browser/page_specific_content_settings.h" #include "components/content_settings/common/content_settings_agent.mojom.h" #include "components/content_settings/core/browser/host_content_settings_map.h" @@ -1721,191 +1720,6 @@ ->initial_ssl_config->symantec_enforcement_disabled); } -class CertificateTransparencySSLUITest : public CertVerifierBrowserTest { - public: - CertificateTransparencySSLUITest() - : CertVerifierBrowserTest(), - https_server_(net::EmbeddedTestServer::TYPE_HTTPS) { - SystemNetworkContextManager::SetEnableCertificateTransparencyForTesting( - true); - } - - CertificateTransparencySSLUITest(const CertificateTransparencySSLUITest&) = - delete; - CertificateTransparencySSLUITest& operator=( - const CertificateTransparencySSLUITest&) = delete; - - ~CertificateTransparencySSLUITest() override { - SystemNetworkContextManager::SetEnableCertificateTransparencyForTesting( - absl::nullopt); - } - - void SetUpOnMainThread() override { - CertVerifierBrowserTest::SetUpOnMainThread(); - host_resolver()->AddRule("*", "127.0.0.1"); - https_server_.AddDefaultHandlers(GetChromeTestDataDir()); - } - - void SetUp() override { - policy_provider_.SetDefaultReturns( - /*is_initialization_complete_return=*/true, - /*is_first_policy_load_complete_return=*/true); - policy::BrowserPolicyConnector::SetPolicyProviderForTesting( - &policy_provider_); - - CertVerifierBrowserTest::SetUp(); - } - - // Sets the policy identified by |policy_name| to the value specified by - // |list_values|, ensuring that the corresponding list pref |pref_name| is - // updated to match. |policy_name| must specify a policy that is a list of - // string values. - void ConfigureStringListPolicy(PrefService* pref_service, - const char* policy_name, - const char* pref_name, - const std::vector<std::string>& list_values) { - base::Value policy_value(base::Value::Type::LIST); - for (const auto& value : list_values) { - policy_value.Append(value); - } - policy::PolicyMap policy_map; - policy_map.Set(policy_name, policy::POLICY_LEVEL_MANDATORY, - policy::POLICY_SCOPE_MACHINE, policy::POLICY_SOURCE_CLOUD, - std::move(policy_value), nullptr); - - EXPECT_NO_FATAL_FAILURE(UpdateChromePolicy(policy_map)); - - const base::Value* pref_value = pref_service->GetList(pref_name); - ASSERT_TRUE(pref_value); - std::vector<std::string> pref_values; - for (const auto& value : pref_value->GetListDeprecated()) { - ASSERT_TRUE(value.is_string()); - pref_values.push_back(value.GetString()); - } - EXPECT_THAT(pref_values, testing::UnorderedElementsAreArray(list_values)); - } - - net::EmbeddedTestServer* https_server() { return &https_server_; } - - private: - void UpdateChromePolicy(const policy::PolicyMap& policies) { - policy_provider_.UpdateChromePolicy(policies); - ASSERT_TRUE(base::CurrentThread::Get()); - - base::RunLoop().RunUntilIdle(); - - content::FlushNetworkServiceInstanceForTesting(); - } - - net::EmbeddedTestServer https_server_; - - testing::NiceMock<policy::MockConfigurationPolicyProvider> policy_provider_; -}; - -// Visit an HTTPS page that has a publicly trusted certificate issued after -// the Certificate Transparency requirement date of April 2018. The connection -// should be blocked, as the server will not be providing CT details, and the -// Chrome CT Policy should be being enforced. -IN_PROC_BROWSER_TEST_F(CertificateTransparencySSLUITest, - EnforcedAfterApril2018) { - ASSERT_TRUE(https_server()->Start()); - - net::CertVerifyResult verify_result; - verify_result.verified_cert = - net::ImportCertFromFile(net::GetTestCertsDirectory(), "may_2018.pem"); - ASSERT_TRUE(verify_result.verified_cert); - verify_result.is_issued_by_known_root = true; - verify_result.public_key_hashes.push_back( - GetSPKIHash(verify_result.verified_cert->cert_buffer())); - - mock_cert_verifier()->AddResultForCert(https_server()->GetCertificate().get(), - verify_result, net::OK); - - ASSERT_TRUE(ui_test_utils::NavigateToURL( - browser(), https_server()->GetURL("/ssl/google.html"))); - - ssl_test_util::CheckSecurityState( - browser()->tab_strip_model()->GetActiveWebContents(), - net::CERT_STATUS_CERTIFICATE_TRANSPARENCY_REQUIRED, - security_state::DANGEROUS, AuthState::SHOWING_INTERSTITIAL); -} - -// Visit an HTTPS page that has a publicly trusted certificate issued after -// the Certificate Transparency requirement date of April 2018. The connection -// would normally be blocked, as the server will not be providing CT details, -// and the Chrome CT Policy should be being enforced; however, because a policy -// configuration exists that disables CT enforcement for that cert, the -// connection should succeed. -IN_PROC_BROWSER_TEST_F(CertificateTransparencySSLUITest, - EnforcedAfterApril2018UnlessPoliciesSet) { - ASSERT_TRUE(https_server()->Start()); - - net::CertVerifyResult verify_result; - verify_result.verified_cert = - net::ImportCertFromFile(net::GetTestCertsDirectory(), "may_2018.pem"); - ASSERT_TRUE(verify_result.verified_cert); - verify_result.is_issued_by_known_root = true; - verify_result.public_key_hashes.push_back( - GetSPKIHash(verify_result.verified_cert->cert_buffer())); - - mock_cert_verifier()->AddResultForCert(https_server()->GetCertificate().get(), - verify_result, net::OK); - - ASSERT_NO_FATAL_FAILURE(ConfigureStringListPolicy( - browser()->profile()->GetPrefs(), - policy::key::kCertificateTransparencyEnforcementDisabledForCas, - certificate_transparency::prefs::kCTExcludedSPKIs, - {verify_result.public_key_hashes.back().ToString()})); - - ASSERT_TRUE(ui_test_utils::NavigateToURL( - browser(), https_server()->GetURL("/ssl/google.html"))); - ssl_test_util::CheckSecurityState( - browser()->tab_strip_model()->GetActiveWebContents(), CertError::NONE, - security_state::SECURE, AuthState::NONE); -} - -// Visit an HTTPS page that has a certificate issued by a certificate authority -// that is trusted in a root store that Chrome does not consider consistently -// secure. In the case where the certificate was issued after the Certificate -// Transparency requirement date of April 2018 the connection would normally be -// blocked, as the server will not be providing CT details, and the Chrome CT -// Policy should be being enforced; however, because a policy configuration -// exists that disables CT enforcement for that Legacy cert, the connection -// should succeed. For more detail, see /net/docs/certificate-transparency.md -IN_PROC_BROWSER_TEST_F(CertificateTransparencySSLUITest, - LegacyEnforcedAfterApril2018UnlessPoliciesSet) { - ASSERT_TRUE(https_server()->Start()); - - net::CertVerifyResult verify_result; - verify_result.verified_cert = - net::ImportCertFromFile(net::GetTestCertsDirectory(), "may_2018.pem"); - ASSERT_TRUE(verify_result.verified_cert); - verify_result.is_issued_by_known_root = true; - - // We'll use a SPKI hash corresponding to the Federal Common Policy CA as - // captured at https://fpki.idmanagement.gov/announcements/mspkichanges/ - const net::SHA256HashValue legacy_spki_hash = { - 0x8e, 0x8b, 0x56, 0xf5, 0x91, 0x8a, 0x25, 0xbd, 0x85, 0xdc, 0xe7, - 0x66, 0x63, 0xfd, 0x94, 0xcc, 0x23, 0x69, 0x0f, 0x10, 0xea, 0x95, - 0x86, 0x61, 0x31, 0x71, 0xc6, 0xf8, 0x37, 0x88, 0x90, 0xd5}; - verify_result.public_key_hashes.push_back(net::HashValue(legacy_spki_hash)); - - mock_cert_verifier()->AddResultForCert(https_server()->GetCertificate().get(), - verify_result, net::OK); - - ASSERT_NO_FATAL_FAILURE(ConfigureStringListPolicy( - browser()->profile()->GetPrefs(), - policy::key::kCertificateTransparencyEnforcementDisabledForLegacyCas, - certificate_transparency::prefs::kCTExcludedLegacySPKIs, - {verify_result.public_key_hashes.back().ToString()})); - - ASSERT_TRUE(ui_test_utils::NavigateToURL( - browser(), https_server()->GetURL("/ssl/google.html"))); - ssl_test_util::CheckSecurityState( - browser()->tab_strip_model()->GetActiveWebContents(), CertError::NONE, - security_state::SECURE, AuthState::NONE); -} - // Visit a HTTP page which request WSS connection to a server providing invalid // certificate. Close the page while WSS connection waits for SSLManager's // response from UI thread.
diff --git a/chrome/browser/subresource_filter/subresource_filter_browsertest.cc b/chrome/browser/subresource_filter/subresource_filter_browsertest.cc index 3f5b166..bda27ed 100644 --- a/chrome/browser/subresource_filter/subresource_filter_browsertest.cc +++ b/chrome/browser/subresource_filter/subresource_filter_browsertest.cc
@@ -1317,6 +1317,15 @@ // Add iframe that is not detected as an ad-frame nor an embed. AddIframe(render_frame_host, kNonAdNonEmbed); + EXPECT_TRUE(content::WaitForLoadStop(web_contents())); + + // LazyEmbeds and LazyAds must be disabled when the page is reloaded. + EXPECT_TRUE(render_frame_host->Reload()); + EXPECT_TRUE(content::WaitForLoadStop(web_contents())); + AddAdIframe(render_frame_host, kAdUrl); + AddIframe(render_frame_host, kEmbedUrl); + EXPECT_TRUE(content::WaitForLoadStop(web_contents())); + // Navigating away from the test page (kMainFrameUrl) causes the document to // be unloaded. That will cause any buffered metrics to be flushed. content::NavigateToURLBlockUntilNavigationsComplete(web_contents(),
diff --git a/chrome/browser/test_dummy/internal/BUILD.gn b/chrome/browser/test_dummy/internal/BUILD.gn index edffd86..a4d5bb2 100644 --- a/chrome/browser/test_dummy/internal/BUILD.gn +++ b/chrome/browser/test_dummy/internal/BUILD.gn
@@ -17,8 +17,8 @@ ":java_resources", "//base:base_java", "//chrome/browser/test_dummy:java", - "//third_party/android_deps:android_support_v7_appcompat_java", "//third_party/androidx:androidx_annotation_annotation_java", + "//third_party/androidx:androidx_appcompat_appcompat_java", ] sources = [ "android/java/src/org/chromium/chrome/browser/test_dummy/TestDummyImpl.java" ] @@ -49,8 +49,8 @@ "//chrome/android/modules/test_dummy/provider:java", "//chrome/android/modules/test_dummy/public:java", "//chrome/browser/test_dummy:java", - "//third_party/android_deps:android_support_v7_appcompat_java", "//third_party/androidx:androidx_annotation_annotation_java", + "//third_party/androidx:androidx_appcompat_appcompat_java", ] sources = [ "android/java/src/org/chromium/chrome/browser/test_dummy/TestDummyActivity.java" ] }
diff --git a/chrome/browser/touch_to_fill/android/internal/BUILD.gn b/chrome/browser/touch_to_fill/android/internal/BUILD.gn index a06ec37..05e0cd0a 100644 --- a/chrome/browser/touch_to_fill/android/internal/BUILD.gn +++ b/chrome/browser/touch_to_fill/android/internal/BUILD.gn
@@ -51,7 +51,6 @@ android_resources("java_resources") { deps = [ ":java_strings_grd", - "//third_party/android_deps:android_support_v7_appcompat_java", "//ui/android:ui_java_resources", ] sources = [
diff --git a/chrome/browser/ui/android/appmenu/internal/BUILD.gn b/chrome/browser/ui/android/appmenu/internal/BUILD.gn index 7f178a0..7a8f3bef 100644 --- a/chrome/browser/ui/android/appmenu/internal/BUILD.gn +++ b/chrome/browser/ui/android/appmenu/internal/BUILD.gn
@@ -30,9 +30,9 @@ "//chrome/browser/ui/android/appmenu:java", "//components/browser_ui/styles/android:java", "//components/browser_ui/widget/android:java", - "//third_party/android_deps:android_support_v7_appcompat_java", "//third_party/androidx:androidx_annotation_annotation_java", "//third_party/androidx:androidx_appcompat_appcompat_resources_java", + "//third_party/androidx:androidx_core_core_java", "//ui/android:ui_java", ] resources_package = "org.chromium.chrome.browser.ui.appmenu.internal" @@ -82,7 +82,6 @@ "//components/browser_ui/widget/android:java", "//components/browser_ui/widget/android:test_support_java", "//content/public/test/android:content_java_test_support", - "//third_party/android_deps:android_support_v7_appcompat_java", "//third_party/android_support_test_runner:rules_java", "//third_party/android_support_test_runner:runner_java", "//third_party/androidx:androidx_annotation_annotation_java",
diff --git a/chrome/browser/ui/android/autofill/internal/BUILD.gn b/chrome/browser/ui/android/autofill/internal/BUILD.gn index 2689356f..6a40742 100644 --- a/chrome/browser/ui/android/autofill/internal/BUILD.gn +++ b/chrome/browser/ui/android/autofill/internal/BUILD.gn
@@ -69,6 +69,7 @@ "//base:base_java_test_support", "//base:base_junit_test_support", "//base/test:test_support_java", + "//chrome/browser/ui/android/autofill/test:test_support_java", "//third_party/androidx:androidx_recyclerview_recyclerview_java", "//third_party/androidx:androidx_test_core_java", "//third_party/androidx:androidx_test_runner_java",
diff --git a/chrome/browser/ui/android/autofill/internal/java/src/org/chromium/chrome/browser/ui/autofill/AuthenticatorSelectionDialogBridgeTest.java b/chrome/browser/ui/android/autofill/internal/java/src/org/chromium/chrome/browser/ui/autofill/AuthenticatorSelectionDialogBridgeTest.java index 8f585285..fc1a5c0 100644 --- a/chrome/browser/ui/android/autofill/internal/java/src/org/chromium/chrome/browser/ui/autofill/AuthenticatorSelectionDialogBridgeTest.java +++ b/chrome/browser/ui/android/autofill/internal/java/src/org/chromium/chrome/browser/ui/autofill/AuthenticatorSelectionDialogBridgeTest.java
@@ -17,7 +17,6 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.Mockito; import org.mockito.MockitoAnnotations; import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; @@ -25,9 +24,7 @@ import org.chromium.base.test.BaseRobolectricTestRunner; import org.chromium.base.test.util.JniMocker; import org.chromium.chrome.browser.ui.autofill.data.AuthenticatorOption; -import org.chromium.ui.modaldialog.ModalDialogManager; -import org.chromium.ui.modaldialog.ModalDialogProperties; -import org.chromium.ui.modelutil.PropertyModel; +import org.chromium.ui.modaldialog.ModalDialogManager.ModalDialogType; import java.util.ArrayList; import java.util.List; @@ -66,38 +63,6 @@ public MockitoRule mMockitoRule = MockitoJUnit.rule(); @Rule public JniMocker mMocker = new JniMocker(); - private class FakeModalDialogManager extends ModalDialogManager { - private PropertyModel mShownDialogModel; - - public FakeModalDialogManager() { - super(Mockito.mock(Presenter.class), 0); - } - - @Override - public void showDialog(PropertyModel model, int dialogType) { - mShownDialogModel = model; - } - - @Override - public void dismissDialog(PropertyModel model, int dismissalCause) { - model.get(ModalDialogProperties.CONTROLLER).onDismiss(model, dismissalCause); - mShownDialogModel = null; - } - - public void clickPositiveButton() { - mShownDialogModel.get(ModalDialogProperties.CONTROLLER) - .onClick(mShownDialogModel, ModalDialogProperties.ButtonType.POSITIVE); - } - - public void clickNegativeButton() { - mShownDialogModel.get(ModalDialogProperties.CONTROLLER) - .onClick(mShownDialogModel, ModalDialogProperties.ButtonType.NEGATIVE); - } - - public PropertyModel getShownDialogModel() { - return mShownDialogModel; - } - } @Before public void setUp() { @@ -105,7 +70,7 @@ reset(mNativeMock); mOptions.add(OPTION_1); mOptions.add(OPTION_2); - mModalDialogManager = new FakeModalDialogManager(); + mModalDialogManager = new FakeModalDialogManager(ModalDialogType.TAB); mAuthenticatorSelectionDialogBridge = new AuthenticatorSelectionDialogBridge(NATIVE_AUTHENTICATOR_SELECTION_DIALOG_VIEW, ApplicationProvider.getApplicationContext(), mModalDialogManager);
diff --git a/chrome/browser/ui/android/autofill/internal/java/src/org/chromium/chrome/browser/ui/autofill/AuthenticatorSelectionDialogTest.java b/chrome/browser/ui/android/autofill/internal/java/src/org/chromium/chrome/browser/ui/autofill/AuthenticatorSelectionDialogTest.java index b0d622f..6b31539 100644 --- a/chrome/browser/ui/android/autofill/internal/java/src/org/chromium/chrome/browser/ui/autofill/AuthenticatorSelectionDialogTest.java +++ b/chrome/browser/ui/android/autofill/internal/java/src/org/chromium/chrome/browser/ui/autofill/AuthenticatorSelectionDialogTest.java
@@ -19,7 +19,6 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.Mockito; import org.mockito.MockitoAnnotations; import org.chromium.base.test.BaseRobolectricTestRunner; @@ -27,7 +26,7 @@ import org.chromium.chrome.browser.ui.autofill.data.AuthenticatorOption; import org.chromium.chrome.browser.ui.autofill.internal.R; import org.chromium.ui.modaldialog.DialogDismissalCause; -import org.chromium.ui.modaldialog.ModalDialogManager; +import org.chromium.ui.modaldialog.ModalDialogManager.ModalDialogType; import org.chromium.ui.modaldialog.ModalDialogProperties; import org.chromium.ui.modelutil.PropertyModel; @@ -59,38 +58,11 @@ private AuthenticatorSelectionDialog mAuthenticatorSelectionDialog; @Mock private AuthenticatorSelectionDialog.Listener mAuthenticatorSelectedListener; - private class FakeModalDialogManager extends ModalDialogManager { - private PropertyModel mShownDialogModel; - - public FakeModalDialogManager() { - super(Mockito.mock(Presenter.class), 0); - } - - @Override - public void showDialog(PropertyModel model, int dialogType) { - mShownDialogModel = model; - } - - @Override - public void dismissDialog(PropertyModel model, int dismissalCause) { - model.get(ModalDialogProperties.CONTROLLER).onDismiss(model, dismissalCause); - mShownDialogModel = null; - } - - public void clickPositiveButton() { - mShownDialogModel.get(ModalDialogProperties.CONTROLLER) - .onClick(mShownDialogModel, ModalDialogProperties.ButtonType.POSITIVE); - } - - public PropertyModel getShownDialogModel() { - return mShownDialogModel; - } - } @Before public void setUp() { MockitoAnnotations.initMocks(this); - mModalDialogManager = new FakeModalDialogManager(); + mModalDialogManager = new FakeModalDialogManager(ModalDialogType.TAB); mAuthenticatorSelectionDialog = new AuthenticatorSelectionDialog(ApplicationProvider.getApplicationContext(), mAuthenticatorSelectedListener, mModalDialogManager);
diff --git a/chrome/browser/ui/android/autofill/internal/java/src/org/chromium/chrome/browser/ui/autofill/AutofillErrorDialogBridgeTest.java b/chrome/browser/ui/android/autofill/internal/java/src/org/chromium/chrome/browser/ui/autofill/AutofillErrorDialogBridgeTest.java index a54e100..efc12be2 100644 --- a/chrome/browser/ui/android/autofill/internal/java/src/org/chromium/chrome/browser/ui/autofill/AutofillErrorDialogBridgeTest.java +++ b/chrome/browser/ui/android/autofill/internal/java/src/org/chromium/chrome/browser/ui/autofill/AutofillErrorDialogBridgeTest.java
@@ -17,15 +17,12 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.Mockito; import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; import org.chromium.base.test.BaseRobolectricTestRunner; import org.chromium.base.test.util.JniMocker; -import org.chromium.ui.modaldialog.ModalDialogManager; -import org.chromium.ui.modaldialog.ModalDialogProperties; -import org.chromium.ui.modelutil.PropertyModel; +import org.chromium.ui.modaldialog.ModalDialogManager.ModalDialogType; /** * Unit tests for {@link AutofillErrorDialogBridge} @@ -48,38 +45,10 @@ private AutofillErrorDialogBridge mAutofillErrorDialogBridge; private FakeModalDialogManager mModalDialogManager; - private class FakeModalDialogManager extends ModalDialogManager { - private PropertyModel mShownDialogModel; - - public FakeModalDialogManager() { - super(Mockito.mock(Presenter.class), 0); - } - - @Override - public void showDialog(PropertyModel model, int dialogType) { - mShownDialogModel = model; - } - - @Override - public void dismissDialog(PropertyModel model, int dismissalCause) { - model.get(ModalDialogProperties.CONTROLLER).onDismiss(model, dismissalCause); - mShownDialogModel = null; - } - - public void clickPositiveButton() { - mShownDialogModel.get(ModalDialogProperties.CONTROLLER) - .onClick(mShownDialogModel, ModalDialogProperties.ButtonType.POSITIVE); - } - - public PropertyModel getShownDialogModel() { - return mShownDialogModel; - } - } - @Before public void setUp() { reset(mNativeMock); - mModalDialogManager = new FakeModalDialogManager(); + mModalDialogManager = new FakeModalDialogManager(ModalDialogType.TAB); mAutofillErrorDialogBridge = new AutofillErrorDialogBridge(NATIVE_AUTOFILL_ERROR_DIALOG_VIEW, mModalDialogManager, ApplicationProvider.getApplicationContext());
diff --git a/chrome/browser/ui/android/autofill/internal/java/src/org/chromium/chrome/browser/ui/autofill/AutofillProgressDialogBridgeTest.java b/chrome/browser/ui/android/autofill/internal/java/src/org/chromium/chrome/browser/ui/autofill/AutofillProgressDialogBridgeTest.java index 3f41c173..1e99c03 100644 --- a/chrome/browser/ui/android/autofill/internal/java/src/org/chromium/chrome/browser/ui/autofill/AutofillProgressDialogBridgeTest.java +++ b/chrome/browser/ui/android/autofill/internal/java/src/org/chromium/chrome/browser/ui/autofill/AutofillProgressDialogBridgeTest.java
@@ -20,16 +20,14 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.Mockito; import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; import org.chromium.base.test.BaseRobolectricTestRunner; import org.chromium.base.test.util.JniMocker; import org.chromium.chrome.browser.ui.autofill.internal.R; -import org.chromium.ui.modaldialog.ModalDialogManager; +import org.chromium.ui.modaldialog.ModalDialogManager.ModalDialogType; import org.chromium.ui.modaldialog.ModalDialogProperties; -import org.chromium.ui.modelutil.PropertyModel; /** * Unit tests for {@link AutofillProgressDialogBridge} @@ -53,34 +51,6 @@ private AutofillProgressDialogBridge mAutofillProgressDialogBridge; private FakeModalDialogManager mModalDialogManager; - private class FakeModalDialogManager extends ModalDialogManager { - private PropertyModel mShownDialogModel; - - public FakeModalDialogManager() { - super(Mockito.mock(Presenter.class), 0); - } - - @Override - public void showDialog(PropertyModel model, int dialogType) { - mShownDialogModel = model; - } - - @Override - public void dismissDialog(PropertyModel model, int dismissalCause) { - model.get(ModalDialogProperties.CONTROLLER).onDismiss(model, dismissalCause); - mShownDialogModel = null; - } - - public void clickNegativeButton() { - mShownDialogModel.get(ModalDialogProperties.CONTROLLER) - .onClick(mShownDialogModel, ModalDialogProperties.ButtonType.NEGATIVE); - } - - public PropertyModel getShownDialogModel() { - return mShownDialogModel; - } - } - private void showProgressDialog() { mAutofillProgressDialogBridge.showDialog(PROGRESS_DIALOG_TITLE, PROGRESS_DIALOG_MESSAGE, PROGRESS_DIALOG_BUTTON_LABEL, /* iconId= */ 0); @@ -89,7 +59,7 @@ @Before public void setUp() { reset(mNativeMock); - mModalDialogManager = new FakeModalDialogManager(); + mModalDialogManager = new FakeModalDialogManager(ModalDialogType.TAB); mAutofillProgressDialogBridge = new AutofillProgressDialogBridge(NATIVE_AUTOFILL_PROGRESS_DIALOG_VIEW, mModalDialogManager, ApplicationProvider.getApplicationContext());
diff --git a/chrome/browser/ui/android/autofill/internal/java/src/org/chromium/chrome/browser/ui/autofill/OtpVerificationDialogTest.java b/chrome/browser/ui/android/autofill/internal/java/src/org/chromium/chrome/browser/ui/autofill/OtpVerificationDialogTest.java index 865a2520..7007b6ee 100644 --- a/chrome/browser/ui/android/autofill/internal/java/src/org/chromium/chrome/browser/ui/autofill/OtpVerificationDialogTest.java +++ b/chrome/browser/ui/android/autofill/internal/java/src/org/chromium/chrome/browser/ui/autofill/OtpVerificationDialogTest.java
@@ -21,13 +21,12 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.Mockito; import org.mockito.MockitoAnnotations; import org.chromium.base.test.BaseRobolectricTestRunner; import org.chromium.chrome.browser.ui.autofill.internal.R; import org.chromium.ui.modaldialog.DialogDismissalCause; -import org.chromium.ui.modaldialog.ModalDialogManager; +import org.chromium.ui.modaldialog.ModalDialogManager.ModalDialogType; import org.chromium.ui.modaldialog.ModalDialogProperties; import org.chromium.ui.modelutil.PropertyModel; @@ -48,38 +47,10 @@ @Mock private OtpVerificationDialogCoordinator.Delegate mDelegate; - private class FakeModalDialogManager extends ModalDialogManager { - private PropertyModel mShownDialogModel; - - public FakeModalDialogManager() { - super(Mockito.mock(Presenter.class), 0); - } - - @Override - public void showDialog(PropertyModel model, int dialogType) { - mShownDialogModel = model; - } - - @Override - public void dismissDialog(PropertyModel model, int dismissalCause) { - model.get(ModalDialogProperties.CONTROLLER).onDismiss(model, dismissalCause); - mShownDialogModel = null; - } - - public void clickPositiveButton() { - mShownDialogModel.get(ModalDialogProperties.CONTROLLER) - .onClick(mShownDialogModel, ModalDialogProperties.ButtonType.POSITIVE); - } - - public PropertyModel getShownDialogModel() { - return mShownDialogModel; - } - } - @Before public void setUp() { MockitoAnnotations.initMocks(this); - mModalDialogManager = new FakeModalDialogManager(); + mModalDialogManager = new FakeModalDialogManager(ModalDialogType.TAB); mOtpVerificationDialogView = (OtpVerificationDialogView) LayoutInflater .from(ApplicationProvider.getApplicationContext()) .inflate(R.layout.otp_verification_dialog, null);
diff --git a/chrome/browser/ui/android/autofill/test/BUILD.gn b/chrome/browser/ui/android/autofill/test/BUILD.gn new file mode 100644 index 0000000..b4e7452 --- /dev/null +++ b/chrome/browser/ui/android/autofill/test/BUILD.gn
@@ -0,0 +1,22 @@ +# Copyright 2022 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import("//build/config/android/config.gni") +import("//build/config/android/rules.gni") + +android_library("test_support_java") { + testonly = true + + visibility = [ + ":*", + "//chrome/android:chrome_junit_tests__java_binary", + "//chrome/browser/ui/android/autofill/internal:junit", + ] + sources = [ "java/src/org/chromium/chrome/browser/ui/autofill/FakeModalDialogManager.java" ] + deps = [ + "//base:base_java", + "//third_party/mockito:mockito_java", + "//ui/android:ui_no_recycler_view_java", + ] +}
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/autofill/settings/FakeModalDialogManager.java b/chrome/browser/ui/android/autofill/test/java/src/org/chromium/chrome/browser/ui/autofill/FakeModalDialogManager.java similarity index 83% rename from chrome/android/junit/src/org/chromium/chrome/browser/autofill/settings/FakeModalDialogManager.java rename to chrome/browser/ui/android/autofill/test/java/src/org/chromium/chrome/browser/ui/autofill/FakeModalDialogManager.java index 3330058..4f09d5d 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/autofill/settings/FakeModalDialogManager.java +++ b/chrome/browser/ui/android/autofill/test/java/src/org/chromium/chrome/browser/ui/autofill/FakeModalDialogManager.java
@@ -2,7 +2,7 @@ // 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.autofill.settings; +package org.chromium.chrome.browser.ui.autofill; import org.mockito.Mockito; @@ -10,17 +10,14 @@ import org.chromium.ui.modaldialog.ModalDialogProperties; import org.chromium.ui.modelutil.PropertyModel; -// TODO (crbug/1249597): Move this to a more suitable common directory, and deduplicate in other -// places. - /** * A fake ModalDialogManager for use in tests involving modals. */ public class FakeModalDialogManager extends ModalDialogManager { private PropertyModel mShownDialogModel; - public FakeModalDialogManager() { - super(Mockito.mock(Presenter.class), ModalDialogType.APP); + public FakeModalDialogManager(int modalDialogType) { + super(Mockito.mock(Presenter.class), modalDialogType); } @Override
diff --git a/chrome/browser/ui/android/night_mode/BUILD.gn b/chrome/browser/ui/android/night_mode/BUILD.gn index f19ee6a..a03083f 100644 --- a/chrome/browser/ui/android/night_mode/BUILD.gn +++ b/chrome/browser/ui/android/night_mode/BUILD.gn
@@ -43,8 +43,9 @@ "//components/ukm/android:java", "//components/user_prefs/android:java", "//content/public/android:content_full_java", - "//third_party/android_deps:android_support_v7_appcompat_java", "//third_party/androidx:androidx_annotation_annotation_java", + "//third_party/androidx:androidx_appcompat_appcompat_java", + "//third_party/androidx:androidx_appcompat_appcompat_resources_java", "//third_party/androidx:androidx_preference_preference_java", "//ui/android:ui_no_recycler_view_java", "//ui/android:ui_utils_java",
diff --git a/chrome/browser/ui/android/omnibox/BUILD.gn b/chrome/browser/ui/android/omnibox/BUILD.gn index 6e7ea29..d3cceb7a 100644 --- a/chrome/browser/ui/android/omnibox/BUILD.gn +++ b/chrome/browser/ui/android/omnibox/BUILD.gn
@@ -190,11 +190,14 @@ "//components/ukm/android:java", "//components/user_prefs/android:java", "//content/public/android:content_java", - "//third_party/android_deps:android_support_v7_appcompat_java", "//third_party/android_deps:guava_android_java", "//third_party/android_deps:material_design_java", "//third_party/androidx:androidx_annotation_annotation_java", + "//third_party/androidx:androidx_appcompat_appcompat_java", + "//third_party/androidx:androidx_appcompat_appcompat_resources_java", "//third_party/androidx:androidx_collection_collection_java", + "//third_party/androidx:androidx_core_core_java", + "//third_party/androidx:androidx_recyclerview_recyclerview_java", "//third_party/metrics_proto:metrics_proto_java", "//ui/android:ui_full_java", "//ui/android:ui_utils_java", @@ -410,11 +413,11 @@ "//content/public/android:content_java", "//content/public/test/android:content_java_test_support", "//testing/android/junit:junit_test_support", - "//third_party/android_deps:android_support_v7_appcompat_java", "//third_party/android_deps:material_design_java", "//third_party/android_deps:robolectric_all_java", "//third_party/android_support_test_runner:runner_java", "//third_party/androidx:androidx_annotation_annotation_java", + "//third_party/androidx:androidx_recyclerview_recyclerview_java", "//third_party/androidx:androidx_test_core_java", "//third_party/androidx:androidx_test_runner_java", "//third_party/hamcrest:hamcrest_library_java",
diff --git a/chrome/browser/ui/android/toolbar/BUILD.gn b/chrome/browser/ui/android/toolbar/BUILD.gn index 3dc6e0a..05a505b 100644 --- a/chrome/browser/ui/android/toolbar/BUILD.gn +++ b/chrome/browser/ui/android/toolbar/BUILD.gn
@@ -147,10 +147,14 @@ "//components/segmentation_platform/public:public_java", "//components/user_prefs/android:java", "//content/public/android:content_java", - "//third_party/android_deps:android_support_v7_appcompat_java", "//third_party/android_deps:material_design_java", "//third_party/androidx:androidx_annotation_annotation_java", + "//third_party/androidx:androidx_appcompat_appcompat_java", + "//third_party/androidx:androidx_appcompat_appcompat_resources_java", + "//third_party/androidx:androidx_core_core_java", + "//third_party/androidx:androidx_interpolator_interpolator_java", "//third_party/androidx:androidx_preference_preference_java", + "//third_party/androidx:androidx_vectordrawable_vectordrawable_java", "//third_party/metrics_proto:metrics_proto_java", "//ui/android:ui_full_java", "//ui/android:ui_utils_java",
diff --git a/chrome/browser/ui/android/webid/internal/BUILD.gn b/chrome/browser/ui/android/webid/internal/BUILD.gn index 5edab28..bffc42d 100644 --- a/chrome/browser/ui/android/webid/internal/BUILD.gn +++ b/chrome/browser/ui/android/webid/internal/BUILD.gn
@@ -51,7 +51,6 @@ deps = [ "//chrome/browser/ui/android/strings:ui_strings_grd", "//components/browser_ui/widget/android:java_resources", - "//third_party/android_deps:android_support_v7_appcompat_java", "//ui/android:ui_java_resources", ] sources = [
diff --git a/chrome/browser/ui/app_list/app_list_notifier_impl.cc b/chrome/browser/ui/app_list/app_list_notifier_impl.cc index 441ac9f..84642487 100644 --- a/chrome/browser/ui/app_list/app_list_notifier_impl.cc +++ b/chrome/browser/ui/app_list/app_list_notifier_impl.cc
@@ -65,6 +65,23 @@ } } +void AppListNotifierImpl::NotifyContinueSectionVisibilityChanged( + Location location, + bool visible) { + DCHECK(location == Location::kContinue || location == Location::kRecentApps); + + continue_section_visibility_[location] = visible; + DoStateTransition(location, shown_ && query_.empty() && visible + ? State::kShown + : State::kNone); +} + +bool AppListNotifierImpl::GetContinueSectionVisibility( + Location location) const { + const auto it = continue_section_visibility_.find(location); + return it != continue_section_visibility_.cend() && it->second; +} + void AppListNotifierImpl::NotifySearchQueryChanged( const std::u16string& query) { // In some cases the query can change after the launcher is closed, in @@ -73,8 +90,14 @@ if (shown_) { if (query.empty()) { DoStateTransition(Location::kList, State::kNone); - DoStateTransition(Location::kContinue, State::kShown); - DoStateTransition(Location::kRecentApps, State::kShown); + DoStateTransition(Location::kContinue, + GetContinueSectionVisibility(Location::kContinue) + ? State::kShown + : State::kNone); + DoStateTransition(Location::kRecentApps, + GetContinueSectionVisibility(Location::kRecentApps) + ? State::kShown + : State::kNone); } else { DoStateTransition(Location::kList, State::kShown); DoStateTransition(Location::kContinue, State::kNone); @@ -110,8 +133,10 @@ shown_ = shown; if (shown) { - DoStateTransition(Location::kContinue, State::kShown); - DoStateTransition(Location::kRecentApps, State::kShown); + if (GetContinueSectionVisibility(Location::kContinue)) + DoStateTransition(Location::kContinue, State::kShown); + if (GetContinueSectionVisibility(Location::kRecentApps)) + DoStateTransition(Location::kRecentApps, State::kShown); // kList is not shown until a search query is entered. } else { DoStateTransition(Location::kList, State::kNone);
diff --git a/chrome/browser/ui/app_list/app_list_notifier_impl.h b/chrome/browser/ui/app_list/app_list_notifier_impl.h index 7e8a710..a6f85de 100644 --- a/chrome/browser/ui/app_list/app_list_notifier_impl.h +++ b/chrome/browser/ui/app_list/app_list_notifier_impl.h
@@ -140,6 +140,8 @@ void NotifyLaunched(Location location, const Result& result) override; void NotifyResultsUpdated(Location location, const std::vector<Result>& results) override; + void NotifyContinueSectionVisibilityChanged(Location location, + bool visible) override; void NotifySearchQueryChanged(const std::u16string& query) override; bool FireImpressionTimerForTesting(Location location) override; @@ -171,12 +173,22 @@ // Returns the stored results for |location|. std::vector<Result> ResultsForLocation(Location location); + // Returns whether a continue section container (or recent apps container) are + // reported to be visible. + bool GetContinueSectionVisibility(Location location) const; + ash::AppListController* const app_list_controller_; base::ObserverList<Observer> observers_; // The current state of each state machine. base::flat_map<Location, State> states_; + + // The reported visibility state of app list continue section - used for + // `Location::kContinue` and `Location::kRecentApps`, which may remain hidden + // while app list is visible. + base::flat_map<Location, bool> continue_section_visibility_; + // An impression timer for each state machine. base::flat_map<Location, std::unique_ptr<base::OneShotTimer>> timers_;
diff --git a/chrome/browser/ui/app_list/app_list_notifier_impl_old.cc b/chrome/browser/ui/app_list/app_list_notifier_impl_old.cc index 7ffa48c..24c0d4a8 100644 --- a/chrome/browser/ui/app_list/app_list_notifier_impl_old.cc +++ b/chrome/browser/ui/app_list/app_list_notifier_impl_old.cc
@@ -39,6 +39,14 @@ observers_.RemoveObserver(observer); } +void AppListNotifierImplOld::NotifyContinueSectionVisibilityChanged( + Location location, + bool visible) { + // App list is not expected to have continue section when "old" app list + // notifier is active. + NOTREACHED(); +} + void AppListNotifierImplOld::NotifyLaunched(Location location, const Result& result) { launched_result_ = result;
diff --git a/chrome/browser/ui/app_list/app_list_notifier_impl_old.h b/chrome/browser/ui/app_list/app_list_notifier_impl_old.h index 313fc1c..eb4eb64 100644 --- a/chrome/browser/ui/app_list/app_list_notifier_impl_old.h +++ b/chrome/browser/ui/app_list/app_list_notifier_impl_old.h
@@ -139,6 +139,8 @@ // AppListNotifier: void AddObserver(Observer* observer) override; void RemoveObserver(Observer* observer) override; + void NotifyContinueSectionVisibilityChanged(Location location, + bool visible) override; void NotifyLaunched(Location location, const Result& result) override; void NotifyResultsUpdated(Location location, const std::vector<Result>& results) override;
diff --git a/chrome/browser/ui/browser_finder.h b/chrome/browser/ui/browser_finder.h index 672b2cc..33e2b49c 100644 --- a/chrome/browser/ui/browser_finder.h +++ b/chrome/browser/ui/browser_finder.h
@@ -92,6 +92,14 @@ size_t GetTotalBrowserCount(); // Returns the number of browsers with the Profile |profile|. +// Note that: +// 1. A profile may have non-browser windows. These are not counted. +// 2. A profile may have child profiles that have windows. Those are not +// counted. Thus, for example, a Guest profile (which is never displayed +// directly) will return 0. (For a Guest profile, only the child off-the- +// record profile is visible.) Likewise, a parent profile with off-the- +// record (Incognito) child profiles that have windows will not count those +// child windows. size_t GetBrowserCount(Profile* profile); // Returns the number of tabbed browsers with the Profile |profile|.
diff --git a/chrome/browser/ui/passwords/manage_passwords_ui_controller.cc b/chrome/browser/ui/passwords/manage_passwords_ui_controller.cc index b853c23..069d2ad 100644 --- a/chrome/browser/ui/passwords/manage_passwords_ui_controller.cc +++ b/chrome/browser/ui/passwords/manage_passwords_ui_controller.cc
@@ -754,18 +754,7 @@ return chrome::FindBrowserWithWebContents(web_contents()) != nullptr; } -void ManagePasswordsUIController::DidFinishNavigation( - content::NavigationHandle* navigation_handle) { - // TODO(https://crbug.com/1218946): With MPArch there may be multiple main - // frames. This caller was converted automatically to the primary main frame - // to preserve its semantics. Follow up to confirm correctness. - if (!navigation_handle->IsInPrimaryMainFrame() || - !navigation_handle->HasCommitted() || - // Don't react to same-document (fragment) navigations. - navigation_handle->IsSameDocument()) { - return; - } - +void ManagePasswordsUIController::PrimaryPageChanged(content::Page& page) { // Keep the state if the bubble is currently open or the fallback for saving // should be still available. if (IsShowingBubble() || save_fallback_timer_.IsRunning()) {
diff --git a/chrome/browser/ui/passwords/manage_passwords_ui_controller.h b/chrome/browser/ui/passwords/manage_passwords_ui_controller.h index 955b5e34..72f77dee 100644 --- a/chrome/browser/ui/passwords/manage_passwords_ui_controller.h +++ b/chrome/browser/ui/passwords/manage_passwords_ui_controller.h
@@ -221,8 +221,7 @@ bool IsShowingBubbleForTest() const { return IsShowingBubble(); } // content::WebContentsObserver: - void DidFinishNavigation( - content::NavigationHandle* navigation_handle) override; + void PrimaryPageChanged(content::Page& page) override; void OnVisibilityChanged(content::Visibility visibility) override; private:
diff --git a/chrome/browser/ui/startup/startup_browser_creator_impl.cc b/chrome/browser/ui/startup/startup_browser_creator_impl.cc index c8dd889..5e360948 100644 --- a/chrome/browser/ui/startup/startup_browser_creator_impl.cc +++ b/chrome/browser/ui/startup/startup_browser_creator_impl.cc
@@ -380,7 +380,7 @@ #endif // !BUILDFLAG(IS_CHROMEOS_ASH) const bool whats_new_enabled = - promotional_tabs_enabled && whats_new::ShouldShowForState(local_state); + whats_new::ShouldShowForState(local_state, promotional_tabs_enabled); auto* privacy_sandbox_serivce = PrivacySandboxServiceFactory::GetForProfile(profile_); @@ -478,6 +478,11 @@ LaunchResult launch_result = tabs.empty() ? LaunchResult::kNormally : LaunchResult::kWithGivenUrls; + if (whats_new_enabled && (launch_result == LaunchResult::kWithGivenUrls || + is_incognito_or_guest || is_post_crash_launch)) { + whats_new::LogStartupType(whats_new::StartupType::kIneligible); + } + // Only the New Tab Page or command line URLs may be shown in incognito mode. // A similar policy exists for crash recovery launches, to prevent getting the // user stuck in a crash loop. @@ -543,6 +548,8 @@ StartupTabs new_features_tabs; new_features_tabs = provider.GetNewFeaturesTabs(whats_new_enabled); AppendTabs(new_features_tabs, &tabs); + } else if (whats_new_enabled) { + whats_new::LogStartupType(whats_new::StartupType::kOverridden); } }
diff --git a/chrome/browser/ui/tabs/tab_strip_model.cc b/chrome/browser/ui/tabs/tab_strip_model.cc index 501eb55..8493d84c 100644 --- a/chrome/browser/ui/tabs/tab_strip_model.cc +++ b/chrome/browser/ui/tabs/tab_strip_model.cc
@@ -2269,6 +2269,14 @@ } MoveTabsAndSetGroupImpl(indices, destination_index, new_group); + + // Excluding the active tab, deselect all tabs being added to the group. + // See crbug/1301846 for more info. + const gfx::Range tab_indices = + group_model()->GetTabGroup(new_group)->ListTabs(); + for (auto index = tab_indices.start(); index < tab_indices.end(); ++index) + if (active_index() != static_cast<int>(index) && IsTabSelected(index)) + ToggleSelectionAt(index); } void TabStripModel::AddToExistingGroupImpl(
diff --git a/chrome/browser/ui/tabs/tab_strip_model_unittest.cc b/chrome/browser/ui/tabs/tab_strip_model_unittest.cc index a102b2a..fe26d2d1 100644 --- a/chrome/browser/ui/tabs/tab_strip_model_unittest.cc +++ b/chrome/browser/ui/tabs/tab_strip_model_unittest.cc
@@ -1466,6 +1466,11 @@ EXPECT_EQ(tabstrip.GetTabGroupForTab(0), tabstrip.GetTabGroupForTab(1)); EXPECT_NE(tabstrip.GetTabGroupForTab(0), original_group); + // Only the active tab will remain selected when adding multiple tabs to a + // group; all selected tabs continue to be selected when removing multiple + // tabs from a group. + tabstrip.ToggleSelectionAt(1); + // Execute CommandToggleGrouped again. Expect both tabs to be ungrouped, since // they were in the same group. tabstrip.ExecuteContextMenuCommand(0, TabStripModel::CommandToggleGrouped);
diff --git a/chrome/browser/ui/views/chrome_views_delegate.h b/chrome/browser/ui/views/chrome_views_delegate.h index a3508e6..acdcf2e9 100644 --- a/chrome/browser/ui/views/chrome_views_delegate.h +++ b/chrome/browser/ui/views/chrome_views_delegate.h
@@ -52,10 +52,13 @@ // TODO(crbug.com/1052397): Revisit the macro expression once build flag switch // of lacros-chrome is complete. #elif BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS) - gfx::ImageSkia* GetDefaultWindowIcon() const override; bool WindowManagerProvidesTitleBar(bool maximized) override; #endif +#if BUILDFLAG(IS_LINUX) + gfx::ImageSkia* GetDefaultWindowIcon() const override; +#endif + void AddRef() override; void ReleaseRef() override; bool IsShuttingDown() const override;
diff --git a/chrome/browser/ui/views/chrome_views_delegate_linux.cc b/chrome/browser/ui/views/chrome_views_delegate_linux.cc index 13723310c..5cd51ad 100644 --- a/chrome/browser/ui/views/chrome_views_delegate_linux.cc +++ b/chrome/browser/ui/views/chrome_views_delegate_linux.cc
@@ -23,6 +23,7 @@ return desktop_env == base::nix::DESKTOP_ENVIRONMENT_UNITY; } +#if BUILDFLAG(IS_LINUX) int GetWindowIconResourceId() { #if BUILDFLAG(GOOGLE_CHROME_BRANDING) switch (chrome::GetChannel()) { @@ -36,6 +37,7 @@ #endif return IDR_PRODUCT_LOGO_128; } +#endif // BUILDFLAG(IS_LINUX) } // namespace @@ -50,10 +52,12 @@ return ::CreateNativeWidget(native_widget_type, params, delegate); } +#if BUILDFLAG(IS_LINUX) gfx::ImageSkia* ChromeViewsDelegate::GetDefaultWindowIcon() const { ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); return rb.GetImageSkiaNamed(GetWindowIconResourceId()); } +#endif // BUILDFLAG(IS_LINUX) bool ChromeViewsDelegate::WindowManagerProvidesTitleBar(bool maximized) { // On Ubuntu Unity, the system always provides a title bar for
diff --git a/chrome/browser/ui/views/page_action/pwa_install_view.cc b/chrome/browser/ui/views/page_action/pwa_install_view.cc index 719fd1f..f3d6743 100644 --- a/chrome/browser/ui/views/page_action/pwa_install_view.cc +++ b/chrome/browser/ui/views/page_action/pwa_install_view.cc
@@ -8,7 +8,6 @@ #include "base/callback_helpers.h" #include "base/metrics/field_trial_params.h" -#include "base/metrics/histogram_functions.h" #include "base/metrics/user_metrics.h" #include "base/strings/utf_string_conversions.h" #include "base/time/time.h" @@ -139,8 +138,7 @@ PrefService* prefs = Profile::FromBrowserContext(web_contents->GetBrowserContext()) ->GetPrefs(); - base::UmaHistogramEnumeration("WebApp.InstallIphPromo.Result", - web_app::InstallIphResult::kIgnored); + web_app::RecordInstallIphIgnored( prefs, web_app::GenerateAppIdFromManifest(manager->manifest()), base::Time::Now());
diff --git a/chrome/browser/ui/views/passwords/password_bubble_view_test_base.cc b/chrome/browser/ui/views/passwords/password_bubble_view_test_base.cc index 360a37d5..1441e4f 100644 --- a/chrome/browser/ui/views/passwords/password_bubble_view_test_base.cc +++ b/chrome/browser/ui/views/passwords/password_bubble_view_test_base.cc
@@ -24,9 +24,6 @@ return model_delegate_; } - void DidFinishNavigation( - content::NavigationHandle* navigation_handle) override {} - private: base::WeakPtr<PasswordsModelDelegate> model_delegate_; }; @@ -64,8 +61,13 @@ // |test_web_contents_|, and will be retrieved correctly via // ManagePasswordsUIController::FromWebContents in // PasswordsModelDelegateFromWebContents(). - new TestManagePasswordsUIController( - test_web_contents_.get(), model_delegate_weak_ptr_factory_.GetWeakPtr()); + TestManagePasswordsUIController* controller = + new TestManagePasswordsUIController( + test_web_contents_.get(), + model_delegate_weak_ptr_factory_.GetWeakPtr()); + // Set a stub password manager client to avoid a DCHECK failure in + // |ManagePasswordsState|. + controller->set_client(&password_manager_client_); } PasswordBubbleViewTestBase::~PasswordBubbleViewTestBase() = default;
diff --git a/chrome/browser/ui/views/passwords/password_bubble_view_test_base.h b/chrome/browser/ui/views/passwords/password_bubble_view_test_base.h index 1ccfdca..a8e450f 100644 --- a/chrome/browser/ui/views/passwords/password_bubble_view_test_base.h +++ b/chrome/browser/ui/views/passwords/password_bubble_view_test_base.h
@@ -12,6 +12,7 @@ #include "chrome/test/base/testing_profile.h" #include "chrome/test/views/chrome_views_test_base.h" #include "components/password_manager/core/browser/mock_password_feature_manager.h" +#include "components/password_manager/core/browser/stub_password_manager_client.h" #include "components/signin/public/identity_manager/identity_test_environment.h" #include "content/public/test/test_renderer_host.h" #include "content/public/test/web_contents_tester.h" @@ -45,6 +46,7 @@ private: content::RenderViewHostTestEnabler test_render_host_factories_; + password_manager::StubPasswordManagerClient password_manager_client_; std::unique_ptr<TestingProfile> profile_; std::unique_ptr<IdentityTestEnvironmentProfileAdaptor> identity_test_env_profile_adaptor_;
diff --git a/chrome/browser/ui/views/policy/enterprise_startup_dialog_view.cc b/chrome/browser/ui/views/policy/enterprise_startup_dialog_view.cc index bc31aa90..6860694 100644 --- a/chrome/browser/ui/views/policy/enterprise_startup_dialog_view.cc +++ b/chrome/browser/ui/views/policy/enterprise_startup_dialog_view.cc
@@ -266,12 +266,13 @@ if (dialog_view_) dialog_view_->DisplayErrorMessage(error_message, accept_button); } + bool EnterpriseStartupDialogImpl::IsShowing() { return dialog_view_; } // views::WidgetObserver: -void EnterpriseStartupDialogImpl::OnWidgetClosing(views::Widget* widget) { +void EnterpriseStartupDialogImpl::OnWidgetDestroying(views::Widget* widget) { dialog_view_->RemoveWidgetObserver(this); dialog_view_ = nullptr; }
diff --git a/chrome/browser/ui/views/policy/enterprise_startup_dialog_view.h b/chrome/browser/ui/views/policy/enterprise_startup_dialog_view.h index 0a7c5b69..dc7b9c3 100644 --- a/chrome/browser/ui/views/policy/enterprise_startup_dialog_view.h +++ b/chrome/browser/ui/views/policy/enterprise_startup_dialog_view.h
@@ -82,7 +82,7 @@ bool IsShowing() override; // views::WidgetObserver: - void OnWidgetClosing(views::Widget* widget) override; + void OnWidgetDestroying(views::Widget* widget) override; private: // The dialog_view_ is owned by itself.
diff --git a/chrome/browser/ui/views/side_search/side_search_browser_controller.cc b/chrome/browser/ui/views/side_search/side_search_browser_controller.cc index db469878..47a4378 100644 --- a/chrome/browser/ui/views/side_search/side_search_browser_controller.cc +++ b/chrome/browser/ui/views/side_search/side_search_browser_controller.cc
@@ -159,9 +159,14 @@ METADATA_HEADER(HeaderView); HeaderView(base::RepeatingClosure callback, Browser* browser) : layout_(SetLayoutManager(std::make_unique<views::FlexLayout>())) { + constexpr int kHeaderHeight = 44; + SetPreferredSize(gfx::Size(0, kHeaderHeight)); + + constexpr int kHorizontalMargin = 8; layout_->SetOrientation(views::LayoutOrientation::kHorizontal) .SetMainAxisAlignment(views::LayoutAlignment::kStart) - .SetCrossAxisAlignment(views::LayoutAlignment::kCenter); + .SetCrossAxisAlignment(views::LayoutAlignment::kCenter) + .SetInteriorMargin(gfx::Insets::VH(0, kHorizontalMargin)); dse_image_view_ = AddChildView(std::make_unique<DseImageView>(browser)); dse_image_view_->SetProperty( @@ -245,9 +250,6 @@ if (feedback_button_) feedback_button_->UpdateIcon(); close_button_->UpdateIcon(); - - layout_->SetInteriorMargin( - GetLayoutInsets(LayoutInset::TOOLBAR_INTERIOR_MARGIN)); } raw_ptr<DseImageView> dse_image_view_ = nullptr;
diff --git a/chrome/browser/ui/views/tabs/fake_base_tab_strip_controller.cc b/chrome/browser/ui/views/tabs/fake_base_tab_strip_controller.cc index 3e6dc3c..82cbb63 100644 --- a/chrome/browser/ui/views/tabs/fake_base_tab_strip_controller.cc +++ b/chrome/browser/ui/views/tabs/fake_base_tab_strip_controller.cc
@@ -52,6 +52,7 @@ if (tab_strip_) tab_strip_->MoveTab(from_index, to_index, TabRendererData()); } + void FakeBaseTabStripController::MoveGroup(const tab_groups::TabGroupId& group, int to_index) {}
diff --git a/chrome/browser/ui/views/tabs/fake_tab_slot_controller.cc b/chrome/browser/ui/views/tabs/fake_tab_slot_controller.cc index 058b746..c596dd7 100644 --- a/chrome/browser/ui/views/tabs/fake_tab_slot_controller.cc +++ b/chrome/browser/ui/views/tabs/fake_tab_slot_controller.cc
@@ -4,16 +4,19 @@ #include "chrome/browser/ui/views/tabs/fake_tab_slot_controller.h" +#include "chrome/browser/ui/views/tabs/tab_container.h" +#include "chrome/browser/ui/views/tabs/tab_strip_controller.h" + +FakeTabSlotController::FakeTabSlotController( + TabStripController* tab_strip_controller) + : tab_strip_controller_(tab_strip_controller) {} + const ui::ListSelectionModel& FakeTabSlotController::GetSelectionModel() const { return selection_model_; } Tab* FakeTabSlotController::tab_at(int index) const { - return nullptr; -} - -int FakeTabSlotController::GetActiveIndex() const { - return 0; + return tab_container_->GetTabAtModelIndex(index); } bool FakeTabSlotController::ToggleTabGroupCollapsedState( @@ -123,27 +126,27 @@ std::u16string FakeTabSlotController::GetGroupTitle( const tab_groups::TabGroupId& group_id) const { - return std::u16string(); + return tab_strip_controller_->GetGroupTitle(group_id); } std::u16string FakeTabSlotController::GetGroupContentString( const tab_groups::TabGroupId& group) const { - return std::u16string(); + return tab_strip_controller_->GetGroupContentString(group); } tab_groups::TabGroupColorId FakeTabSlotController::GetGroupColorId( const tab_groups::TabGroupId& group_id) const { - return tab_groups::TabGroupColorId(); + return tab_strip_controller_->GetGroupColorId(group_id); } bool FakeTabSlotController::IsGroupCollapsed( const tab_groups::TabGroupId& group) const { - return false; + return tab_strip_controller_->IsGroupCollapsed(group); } absl::optional<int> FakeTabSlotController::GetLastTabInGroup( const tab_groups::TabGroupId& group) const { - return absl::nullopt; + return tab_strip_controller_->GetLastTabInGroup(group); } SkColor FakeTabSlotController::GetPaintedGroupColor(
diff --git a/chrome/browser/ui/views/tabs/fake_tab_slot_controller.h b/chrome/browser/ui/views/tabs/fake_tab_slot_controller.h index 68717f85..7343343a 100644 --- a/chrome/browser/ui/views/tabs/fake_tab_slot_controller.h +++ b/chrome/browser/ui/views/tabs/fake_tab_slot_controller.h
@@ -10,13 +10,20 @@ #include "ui/base/models/list_selection_model.h" #include "ui/gfx/color_palette.h" +class TabContainer; +class TabStripController; + class FakeTabSlotController : public TabSlotController { public: - FakeTabSlotController() = default; + explicit FakeTabSlotController( + TabStripController* tab_strip_controller_ = nullptr); FakeTabSlotController(const FakeTabSlotController&) = delete; FakeTabSlotController& operator=(const FakeTabSlotController&) = delete; ~FakeTabSlotController() override = default; + void set_tab_container(TabContainer* tab_container) { + tab_container_ = tab_container; + } void set_active_tab(Tab* tab) { active_tab_ = tab; } void set_paint_throbber_to_layer(bool value) { paint_throbber_to_layer_ = value; @@ -24,7 +31,6 @@ const ui::ListSelectionModel& GetSelectionModel() const override; Tab* tab_at(int index) const override; - int GetActiveIndex() const override; void SelectTab(Tab* tab, const ui::Event& event) override {} void ExtendSelectionTo(Tab* tab) override {} void ToggleSelected(Tab* tab) override {} @@ -104,6 +110,8 @@ } private: + raw_ptr<TabStripController> tab_strip_controller_; + raw_ptr<TabContainer> tab_container_; ui::ListSelectionModel selection_model_; raw_ptr<Tab> active_tab_ = nullptr; bool paint_throbber_to_layer_ = true;
diff --git a/chrome/browser/ui/views/tabs/tab_container.cc b/chrome/browser/ui/views/tabs/tab_container.cc index 01e9373..0cabdf4e 100644 --- a/chrome/browser/ui/views/tabs/tab_container.cc +++ b/chrome/browser/ui/views/tabs/tab_container.cc
@@ -354,11 +354,10 @@ Tab* TabContainer::AddTab(std::unique_ptr<Tab> tab, int model_index, TabPinned pinned) { - absl::optional<tab_groups::TabGroupId> group = tab->group(); - Tab* tab_ptr = AddChildViewAt( - std::move(tab), GetViewInsertionIndex(group, absl::nullopt, model_index)); + Tab* tab_ptr = AddChildView(std::move(tab)); tabs_view_model_.Add(tab_ptr, model_index); layout_helper_->InsertTabAt(model_index, tab_ptr, pinned); + OrderTabSlotView(tab_ptr); // Don't animate the first tab, it looks weird, and don't animate anything // if the containing window isn't visible yet. @@ -375,10 +374,9 @@ void TabContainer::MoveTab(int from_model_index, int to_model_index) { Tab* tab = GetTabAtModelIndex(from_model_index); - ReorderChildView(tab, GetViewInsertionIndex(tab->group(), from_model_index, - to_model_index)); tabs_view_model_.Move(from_model_index, to_model_index); layout_helper_->MoveTab(tab->group(), from_model_index, to_model_index); + OrderTabSlotView(tab); layout_helper()->SetTabPinned(to_model_index, tab->data().pinned ? TabPinned::kPinned @@ -490,19 +488,15 @@ layout_helper()->UpdateGroupHeaderIndex(group); - TabGroupHeader* group_header = group_views()[group]->header(); - const int first_tab_model_index = - controller_->GetFirstTabInGroup(group).value(); - - MoveGroupHeader(group_header, first_tab_model_index); + OrderTabSlotView(group_views()[group]->header()); } void TabContainer::OnGroupClosed(const tab_groups::TabGroupId& group) { bounds_animator().StopAnimatingView(group_views().at(group).get()->header()); layout_helper()->RemoveGroupHeader(group); + group_views().erase(group); StartBasicAnimation(); - group_views().erase(group); } void TabContainer::UpdateTabGroupVisuals(tab_groups::TabGroupId group_id) { @@ -1202,22 +1196,6 @@ } } -void TabContainer::MoveGroupHeader(TabGroupHeader* group_header, - int first_tab_model_index) { - const int header_index = GetIndexOf(group_header); - const int first_tab_view_index = - GetViewIndexForModelIndex(first_tab_model_index); - - // The header should be just before the first tab. If it isn't, reorder the - // header such that it is. Note that the index to reorder to is different - // depending on whether the header is before or after the tab, since the - // header itself occupies an index. - if (header_index < first_tab_view_index - 1) - ReorderChildView(group_header, first_tab_view_index - 1); - if (header_index > first_tab_view_index - 1) - ReorderChildView(group_header, first_tab_view_index); -} - void TabContainer::ResizeLayoutTabs() { // We've been called back after the TabStrip has been emptied out (probably // just prior to the window being destroyed). We need to do nothing here or @@ -1291,56 +1269,23 @@ mouse_watcher_ = nullptr; } -int TabContainer::GetViewInsertionIndex( - absl::optional<tab_groups::TabGroupId> group, - absl::optional<int> from_model_index, - int to_model_index) const { - // -1 is treated a sentinel value to indicate a tab is newly added to the - // beginning of the tab strip. - if (to_model_index < 0) - return 0; +void TabContainer::OrderTabSlotView(TabSlotView* slot_view) { + // |slot_view| is in the wrong place in children(). Fix it. + std::vector<TabSlotView*> slots = layout_helper_->GetTabSlotViews(); + size_t target_slot_index = + std::find(slots.begin(), slots.end(), slot_view) - slots.begin(); + // Find the index in children() that corresponds to |target_slot_index|. + size_t view_index = 0; + for (size_t slot_index = 0; slot_index < target_slot_index; slot_index++) { + // If we don't own this view, skip it *without* advancing in children(). + if (slots[slot_index]->parent() != this) + continue; + if (view_index == children().size()) + break; + view_index++; + } - // If to_model_index is beyond the end of the tab strip, then the tab is - // newly added to the end of the tab strip. In that case we can just return - // one beyond the view index of the last existing tab. - if (to_model_index >= GetTabCount()) - return (GetTabCount() ? GetViewIndexForModelIndex(GetTabCount() - 1) + 1 - : 0); - - // If there is no from_model_index, then the tab is newly added in the - // middle of the tab strip. In that case we treat it as coming from the end - // of the tab strip, since new views are ordered at the end by default. - if (!from_model_index.has_value()) - from_model_index = GetTabCount(); - - DCHECK_NE(to_model_index, from_model_index.value()); - - // Since we don't have an absolute mapping from model index to view index, - // we anchor on the last known view index at the given to_model_index. - Tab* other_tab = GetTabAtModelIndex(to_model_index); - int other_view_index = GetViewIndexForModelIndex(to_model_index); - - if (other_view_index <= 0) - return 0; - - // When moving to the right, just use the anchor index because the tab will - // replace that position in both the model and the view. This happens - // because the tab itself occupies a lower index that the other tabs will - // shift into. - if (to_model_index > from_model_index.value()) - return other_view_index; - - // When moving to the left, the tab may end up on either the left or right - // side of a group header, depending on if it's in that group. This affects - // its view index but not its model index, so we adjust the former only. - if (other_tab->group().has_value() && other_tab->group() != group) - return other_view_index - 1; - - return other_view_index; -} - -int TabContainer::GetViewIndexForModelIndex(int model_index) const { - return GetIndexOf(GetTabAtModelIndex(model_index)); + ReorderChildView(slot_view, view_index); } bool TabContainer::IsPointInTab(Tab* tab,
diff --git a/chrome/browser/ui/views/tabs/tab_container.h b/chrome/browser/ui/views/tabs/tab_container.h index add426b..81ffefc6 100644 --- a/chrome/browser/ui/views/tabs/tab_container.h +++ b/chrome/browser/ui/views/tabs/tab_container.h
@@ -25,7 +25,6 @@ #include "ui/views/view_targeter_delegate.h" class TabStrip; -class TabGroupHeader; class TabHoverCardController; class TabDragContext; @@ -238,8 +237,6 @@ // the removal of the tab at |model_index|. void UpdateClosingModeOnRemovedTab(int model_index, bool was_active); - void MoveGroupHeader(TabGroupHeader* group_header, int first_tab_model_index); - // Perform an animated resize-relayout of the TabContainer immediately. void ResizeLayoutTabs(); @@ -257,16 +254,9 @@ void AddMessageLoopObserver(); void RemoveMessageLoopObserver(); - // Returns the corresponding view index of a |tab| to be inserted at - // |to_model_index|. Used to reorder the child views of the tab container - // so that focus order stays consistent with the visual tab order. - // |from_model_index| is where the tab currently is, if it's being moved - // instead of added. - int GetViewInsertionIndex(absl::optional<tab_groups::TabGroupId> group, - absl::optional<int> from_model_index, - int to_model_index) const; - - int GetViewIndexForModelIndex(int tab_model_index) const; + // Moves |slot_view| within children() to match |layout_helper_|'s slot + // ordering. + void OrderTabSlotView(TabSlotView* slot_view); // Returns true if the specified point in TabStrip coords is within the // hit-test region of the specified Tab.
diff --git a/chrome/browser/ui/views/tabs/tab_container_unittest.cc b/chrome/browser/ui/views/tabs/tab_container_unittest.cc index 28ed2e5..72da5b7 100644 --- a/chrome/browser/ui/views/tabs/tab_container_unittest.cc +++ b/chrome/browser/ui/views/tabs/tab_container_unittest.cc
@@ -43,20 +43,23 @@ ChromeViewsTestBase::SetUp(); tab_strip_controller_ = std::make_unique<FakeBaseTabStripController>(); - tab_slot_controller_ = std::make_unique<FakeTabSlotController>(); + tab_slot_controller_ = + std::make_unique<FakeTabSlotController>(tab_strip_controller_.get()); std::unique_ptr<TabContainer> tab_container = std::make_unique<TabContainer>( tab_strip_controller_.get(), nullptr /*hover_card_controller*/, nullptr /*drag_context*/, tab_slot_controller_.get(), nullptr /*scroll_contents_view*/); - tab_container->SetAvailableWidthCallback( - base::BindRepeating([]() { return 500; })); - tab_container->SetBounds(0, 0, 500, GetLayoutConstant(TAB_HEIGHT)); - tab_container->Layout(); + tab_container->SetAvailableWidthCallback(base::BindRepeating( + [](TabContainerTest* test) { return test->tab_container_width_; }, + this)); widget_ = CreateTestWidget(); + SetTabContainerWidth(1000); tab_container_ = widget_->SetContentsView(std::move(tab_container)); + + tab_slot_controller_->set_tab_container(tab_container_); } void TearDown() override { @@ -143,6 +146,13 @@ AddTabToGroup(index, new_group.value()); } + std::vector<TabGroupViews*> ListGroupViews() const { + std::vector<TabGroupViews*> result; + for (auto const& group_view_pair : tab_container_->group_views()) + result.push_back(group_view_pair.second.get()); + return result; + } + // Returns all TabSlotViews in the order that they have as ViewChildren of // TabContainer. This should match the actual order that they appear in // visually. @@ -205,10 +215,18 @@ return tab->HitTestPoint(point_in_tab_coords); } + void SetTabContainerWidth(int width) { + tab_container_width_ = width; + widget_->SetSize( + gfx::Size(tab_container_width_, GetLayoutConstant(TAB_HEIGHT))); + } + std::unique_ptr<FakeBaseTabStripController> tab_strip_controller_; std::unique_ptr<FakeTabSlotController> tab_slot_controller_; raw_ptr<TabContainer> tab_container_; std::unique_ptr<views::Widget> widget_; + + int tab_container_width_ = 0; }; TEST_F(TabContainerTest, ExitsClosingModeAtStandardWidth) { @@ -372,8 +390,6 @@ } TEST_F(TabContainerTest, GetEventHandlerForOverlappingArea) { - tab_container_->SetSize(gfx::Size(1000, tab_container_->height())); - Tab* left_tab = AddTab(0); Tab* active_tab = AddTab(1, absl::nullopt, TabActive::kActive); Tab* right_tab = AddTab(2); @@ -429,8 +445,6 @@ } TEST_F(TabContainerTest, GetTooltipHandler) { - tab_container_->SetSize(gfx::Size(1000, tab_container_->height())); - Tab* left_tab = AddTab(0); Tab* active_tab = AddTab(1, absl::nullopt, TabActive::kActive); Tab* right_tab = AddTab(2); @@ -479,7 +493,7 @@ (right_tab->x() + most_right_tab->bounds().right() + 1) / 2, right_tab->bounds().bottom() - 1); - // Sanity check that the point is in both active and left tab. + // Sanity check that the point is in both tabs. ASSERT_TRUE(IsPointInTab(right_tab, unactive_overlap)); ASSERT_TRUE(IsPointInTab(most_right_tab, unactive_overlap)); @@ -491,3 +505,204 @@ // don't hit it. EXPECT_FALSE(tab_container_->GetTooltipHandlerForPoint(gfx::Point(-1, 2))); } + +TEST_F(TabContainerTest, GroupHeaderBasics) { + AddTab(0); + + Tab* tab = tab_container_->GetTabAtModelIndex(0); + const int first_slot_x = tab->x(); + + tab_groups::TabGroupId group = tab_groups::TabGroupId::GenerateNew(); + AddTabToGroup(0, group); + tab_container_->CompleteAnimationAndLayout(); + + std::vector<TabGroupViews*> views = ListGroupViews(); + EXPECT_EQ(1u, views.size()); + TabGroupHeader* header = views[0]->header(); + EXPECT_EQ(first_slot_x, header->x()); + EXPECT_GT(header->width(), 0); + EXPECT_EQ(header->bounds().right() - TabStyle::GetTabOverlap(), tab->x()); + EXPECT_EQ(tab->height(), header->height()); +} + +TEST_F(TabContainerTest, GroupHeaderBetweenTabs) { + AddTab(0); + AddTab(1); + tab_container_->CompleteAnimationAndLayout(); + + const int second_slot_x = tab_container_->GetTabAtModelIndex(1)->x(); + + tab_groups::TabGroupId group = tab_groups::TabGroupId::GenerateNew(); + AddTabToGroup(1, group); + tab_container_->CompleteAnimationAndLayout(); + + TabGroupHeader* header = ListGroupViews()[0]->header(); + EXPECT_EQ(header->x(), second_slot_x); +} + +TEST_F(TabContainerTest, GroupHeaderMovesRightWithTab) { + for (int i = 0; i < 4; i++) + AddTab(i); + tab_groups::TabGroupId group = tab_groups::TabGroupId::GenerateNew(); + AddTabToGroup(1, group); + tab_container_->CompleteAnimationAndLayout(); + + MoveTab(1, 2); + tab_container_->CompleteAnimationAndLayout(); + + TabGroupHeader* header = ListGroupViews()[0]->header(); + // Header is now left of tab 2. + EXPECT_LT(tab_container_->GetTabAtModelIndex(1)->x(), header->x()); + EXPECT_LT(header->x(), tab_container_->GetTabAtModelIndex(2)->x()); +} + +TEST_F(TabContainerTest, GroupHeaderMovesLeftWithTab) { + for (int i = 0; i < 4; i++) + AddTab(i); + tab_groups::TabGroupId group = tab_groups::TabGroupId::GenerateNew(); + AddTabToGroup(2, group); + tab_container_->CompleteAnimationAndLayout(); + + MoveTab(2, 1); + tab_container_->CompleteAnimationAndLayout(); + + TabGroupHeader* header = ListGroupViews()[0]->header(); + // Header is now left of tab 1. + EXPECT_LT(tab_container_->GetTabAtModelIndex(0)->x(), header->x()); + EXPECT_LT(header->x(), tab_container_->GetTabAtModelIndex(1)->x()); +} + +TEST_F(TabContainerTest, GroupHeaderDoesntMoveReorderingTabsInGroup) { + for (int i = 0; i < 4; i++) + AddTab(i); + tab_groups::TabGroupId group = tab_groups::TabGroupId::GenerateNew(); + AddTabToGroup(1, group); + AddTabToGroup(2, group); + tab_container_->CompleteAnimationAndLayout(); + + TabGroupHeader* header = ListGroupViews()[0]->header(); + const int initial_header_x = header->x(); + Tab* tab1 = tab_container_->GetTabAtModelIndex(1); + const int initial_tab_1_x = tab1->x(); + Tab* tab2 = tab_container_->GetTabAtModelIndex(2); + const int initial_tab_2_x = tab2->x(); + + MoveTab(1, 2); + tab_container_->CompleteAnimationAndLayout(); + + // Header has not moved. + EXPECT_EQ(initial_header_x, header->x()); + EXPECT_EQ(initial_tab_1_x, tab2->x()); + EXPECT_EQ(initial_tab_2_x, tab1->x()); +} + +TEST_F(TabContainerTest, GroupHeaderMovesOnRegrouping) { + for (int i = 0; i < 3; i++) + AddTab(i); + tab_groups::TabGroupId group0 = tab_groups::TabGroupId::GenerateNew(); + AddTabToGroup(0, group0); + tab_groups::TabGroupId group1 = tab_groups::TabGroupId::GenerateNew(); + AddTabToGroup(1, group1); + AddTabToGroup(2, group1); + tab_container_->CompleteAnimationAndLayout(); + + std::vector<TabGroupViews*> views = ListGroupViews(); + auto views_it = + std::find_if(views.begin(), views.end(), [&group1](TabGroupViews* view) { + return view->header()->group() == group1; + }); + ASSERT_TRUE(views_it != views.end()); + TabGroupViews* group1_views = *views_it; + + // Change groups in a way so that the header should swap with the tab, without + // an explicit MoveTab call. + MoveTabIntoGroup(1, group0); + tab_container_->CompleteAnimationAndLayout(); + + // Header is now right of tab 1. + EXPECT_LT(tab_container_->GetTabAtModelIndex(1)->x(), + group1_views->header()->x()); + EXPECT_LT(group1_views->header()->x(), + tab_container_->GetTabAtModelIndex(2)->x()); +} + +TEST_F(TabContainerTest, UngroupedTabMovesLeftOfHeader) { + for (int i = 0; i < 2; i++) + AddTab(i); + tab_groups::TabGroupId group = tab_groups::TabGroupId::GenerateNew(); + AddTabToGroup(0, group); + tab_container_->CompleteAnimationAndLayout(); + + MoveTab(1, 0); + tab_container_->CompleteAnimationAndLayout(); + + // Header is right of tab 0. + TabGroupHeader* header = ListGroupViews()[0]->header(); + EXPECT_LT(tab_container_->GetTabAtModelIndex(0)->x(), header->x()); + EXPECT_LT(header->x(), tab_container_->GetTabAtModelIndex(1)->x()); +} + +TEST_F(TabContainerTest, DeleteTabGroupViewsWhenEmpty) { + AddTab(0); + AddTab(1); + tab_groups::TabGroupId group = tab_groups::TabGroupId::GenerateNew(); + AddTabToGroup(0, group); + AddTabToGroup(1, group); + RemoveTabFromGroup(0); + + EXPECT_EQ(1u, ListGroupViews().size()); + RemoveTabFromGroup(1); + EXPECT_EQ(0u, ListGroupViews().size()); +} + +TEST_F(TabContainerTest, GroupUnderlineBasics) { + AddTab(0); + tab_groups::TabGroupId group = tab_groups::TabGroupId::GenerateNew(); + AddTabToGroup(0, group); + tab_container_->CompleteAnimationAndLayout(); + + std::vector<TabGroupViews*> views = ListGroupViews(); + EXPECT_EQ(1u, views.size()); + // Update underline manually in the absence of a real Paint cycle. + views[0]->UpdateBounds(); + + const TabGroupUnderline* underline = views[0]->underline(); + EXPECT_EQ(underline->x(), TabGroupUnderline::GetStrokeInset()); + EXPECT_GT(underline->width(), 0); + EXPECT_EQ(underline->bounds().right(), + tab_container_->GetTabAtModelIndex(0)->bounds().right() - + TabGroupUnderline::GetStrokeInset()); + EXPECT_EQ(underline->height(), TabGroupUnderline::kStrokeThickness); + + // Endpoints are different if the last grouped tab is active. + AddTab(1, absl::nullopt, TabActive::kActive); + MoveTabIntoGroup(1, group); + tab_container_->CompleteAnimationAndLayout(); + views[0]->UpdateBounds(); + + EXPECT_EQ(underline->x(), TabGroupUnderline::GetStrokeInset()); + EXPECT_EQ(underline->bounds().right(), + tab_container_->GetTabAtModelIndex(1)->bounds().right() + + TabGroupUnderline::kStrokeThickness); +} + +TEST_F(TabContainerTest, GroupHighlightBasics) { + AddTab(0); + + tab_groups::TabGroupId group = tab_groups::TabGroupId::GenerateNew(); + AddTabToGroup(0, group); + tab_container_->CompleteAnimationAndLayout(); + + std::vector<TabGroupViews*> views = ListGroupViews(); + EXPECT_EQ(1u, views.size()); + + // The highlight bounds match the group view bounds. Grab this manually + // here, since there isn't a real paint cycle to trigger OnPaint(). + gfx::Rect bounds = views[0]->GetBounds(); + EXPECT_EQ(bounds.x(), 0); + EXPECT_GT(bounds.width(), 0); + EXPECT_EQ(bounds.right(), + tab_container_->GetTabAtModelIndex(0)->bounds().right()); + EXPECT_EQ(bounds.height(), + tab_container_->GetTabAtModelIndex(0)->bounds().height()); +}
diff --git a/chrome/browser/ui/views/tabs/tab_group_views.cc b/chrome/browser/ui/views/tabs/tab_group_views.cc index d927b1c0..045fda4e 100644 --- a/chrome/browser/ui/views/tabs/tab_group_views.cc +++ b/chrome/browser/ui/views/tabs/tab_group_views.cc
@@ -60,9 +60,6 @@ header_->VisualsChanged(); underline_->SchedulePaint(); - const int active_index = tab_slot_controller_->GetActiveIndex(); - if (active_index != TabStripModel::kNoTab) - tab_slot_controller_->tab_at(active_index)->SchedulePaint(); } gfx::Rect TabGroupViews::GetBounds() const {
diff --git a/chrome/browser/ui/views/tabs/tab_slot_controller.h b/chrome/browser/ui/views/tabs/tab_slot_controller.h index dce6378..7f01f26 100644 --- a/chrome/browser/ui/views/tabs/tab_slot_controller.h +++ b/chrome/browser/ui/views/tabs/tab_slot_controller.h
@@ -54,9 +54,6 @@ // Returns the tab at |index|. virtual Tab* tab_at(int index) const = 0; - // Returns the index of the active tab. - virtual int GetActiveIndex() const = 0; - // Selects the tab. |event| is the event that causes |tab| to be selected. virtual void SelectTab(Tab* tab, const ui::Event& event) = 0;
diff --git a/chrome/browser/ui/views/tabs/tab_strip.cc b/chrome/browser/ui/views/tabs/tab_strip.cc index 73216b9b..5e00e54 100644 --- a/chrome/browser/ui/views/tabs/tab_strip.cc +++ b/chrome/browser/ui/views/tabs/tab_strip.cc
@@ -979,6 +979,11 @@ if (!is_collapsing) tab_container_->ExitTabClosingMode(); tab_container_->StartBasicAnimation(); + + // The active tab may need to repaint its group stroke if it's in |group|. + int active_index = GetActiveIndex(); + if (IsValidModelIndex(active_index)) + tab_at(active_index)->SchedulePaint(); } void TabStrip::ToggleTabGroup(const tab_groups::TabGroupId& group, @@ -1145,6 +1150,10 @@ tab_at(model_index)->SetTabNeedsAttention(attention); } +int TabStrip::GetActiveIndex() const { + return controller_->GetActiveIndex(); +} + int TabStrip::GetModelIndexOf(const TabSlotView* view) const { return tab_container_->GetModelIndexOf(view); } @@ -1206,10 +1215,6 @@ return tab_container_->GetTabAtModelIndex(index); } -int TabStrip::GetActiveIndex() const { - return controller_->GetActiveIndex(); -} - void TabStrip::SelectTab(Tab* tab, const ui::Event& event) { int model_index = GetModelIndexOf(tab);
diff --git a/chrome/browser/ui/views/tabs/tab_strip.h b/chrome/browser/ui/views/tabs/tab_strip.h index ddfb6b8..629bcbd 100644 --- a/chrome/browser/ui/views/tabs/tab_strip.h +++ b/chrome/browser/ui/views/tabs/tab_strip.h
@@ -185,6 +185,9 @@ return tab_container_->group_views().at(id).get()->header(); } + // Returns the active index, or kNoTab if no tab is active. + int GetActiveIndex() const; + // Returns the index of the specified view in the model coordinate system, or // -1 if view is closing or not a tab. int GetModelIndexOf(const TabSlotView* view) const; @@ -233,10 +236,9 @@ // on drop. bool WantsToReceiveAllDragEvents() const; - // TabController: + // TabSlotController: const ui::ListSelectionModel& GetSelectionModel() const override; Tab* tab_at(int index) const override; - int GetActiveIndex() const override; void SelectTab(Tab* tab, const ui::Event& event) override; void ExtendSelectionTo(Tab* tab) override; void ToggleSelected(Tab* tab) override;
diff --git a/chrome/browser/ui/views/tabs/tab_strip_unittest.cc b/chrome/browser/ui/views/tabs/tab_strip_unittest.cc index bce9c9c..af1e0cff 100644 --- a/chrome/browser/ui/views/tabs/tab_strip_unittest.cc +++ b/chrome/browser/ui/views/tabs/tab_strip_unittest.cc
@@ -582,223 +582,6 @@ EXPECT_TRUE(second_tab->closing()); } -TEST_P(TabStripTest, GroupHeaderBasics) { - SetMaxTabStripWidth(1000); - bounds_animator()->SetAnimationDuration(base::TimeDelta()); - controller_->AddTab(0, false); - - Tab* tab = tab_strip_->tab_at(0); - const int first_slot_x = tab->x(); - - absl::optional<tab_groups::TabGroupId> group = - tab_groups::TabGroupId::GenerateNew(); - controller_->MoveTabIntoGroup(0, group); - CompleteAnimationAndLayout(); - - std::vector<TabGroupViews*> views = ListGroupViews(); - EXPECT_EQ(1u, views.size()); - TabGroupHeader* header = views[0]->header(); - EXPECT_EQ(first_slot_x, header->x()); - EXPECT_GT(header->width(), 0); - EXPECT_EQ(header->bounds().right() - TabStyle::GetTabOverlap(), tab->x()); - EXPECT_EQ(tab->height(), header->height()); -} - -TEST_P(TabStripTest, GroupHeaderBetweenTabs) { - SetMaxTabStripWidth(1000); - bounds_animator()->SetAnimationDuration(base::TimeDelta()); - - controller_->AddTab(0, false); - controller_->AddTab(1, false); - - const int second_slot_x = tab_strip_->tab_at(1)->x(); - - absl::optional<tab_groups::TabGroupId> group = - tab_groups::TabGroupId::GenerateNew(); - controller_->MoveTabIntoGroup(1, group); - - TabGroupHeader* header = ListGroupViews()[0]->header(); - EXPECT_EQ(header->x(), second_slot_x); -} - -TEST_P(TabStripTest, GroupHeaderMovesRightWithTab) { - SetMaxTabStripWidth(2000); - for (int i = 0; i < 4; i++) - controller_->AddTab(i, false); - absl::optional<tab_groups::TabGroupId> group = - tab_groups::TabGroupId::GenerateNew(); - controller_->MoveTabIntoGroup(1, group); - CompleteAnimationAndLayout(); - - controller_->MoveTab(1, 2); - CompleteAnimationAndLayout(); - - TabGroupHeader* header = ListGroupViews()[0]->header(); - // Header is now left of tab 2. - EXPECT_LT(tab_strip_->tab_at(1)->x(), header->x()); - EXPECT_LT(header->x(), tab_strip_->tab_at(2)->x()); -} - -TEST_P(TabStripTest, GroupHeaderMovesLeftWithTab) { - SetMaxTabStripWidth(2000); - for (int i = 0; i < 4; i++) - controller_->AddTab(i, false); - absl::optional<tab_groups::TabGroupId> group = - tab_groups::TabGroupId::GenerateNew(); - controller_->MoveTabIntoGroup(2, group); - CompleteAnimationAndLayout(); - - controller_->MoveTab(2, 1); - CompleteAnimationAndLayout(); - - TabGroupHeader* header = ListGroupViews()[0]->header(); - // Header is now left of tab 1. - EXPECT_LT(tab_strip_->tab_at(0)->x(), header->x()); - EXPECT_LT(header->x(), tab_strip_->tab_at(1)->x()); -} - -TEST_P(TabStripTest, GroupHeaderDoesntMoveReorderingTabsInGroup) { - SetMaxTabStripWidth(2000); - for (int i = 0; i < 4; i++) - controller_->AddTab(i, false); - absl::optional<tab_groups::TabGroupId> group = - tab_groups::TabGroupId::GenerateNew(); - controller_->MoveTabIntoGroup(1, group); - controller_->MoveTabIntoGroup(2, group); - CompleteAnimationAndLayout(); - - TabGroupHeader* header = ListGroupViews()[0]->header(); - const int initial_header_x = header->x(); - Tab* tab1 = tab_strip_->tab_at(1); - const int initial_tab_1_x = tab1->x(); - Tab* tab2 = tab_strip_->tab_at(2); - const int initial_tab_2_x = tab2->x(); - - controller_->MoveTab(1, 2); - CompleteAnimationAndLayout(); - - // Header has not moved. - EXPECT_EQ(initial_header_x, header->x()); - EXPECT_EQ(initial_tab_1_x, tab2->x()); - EXPECT_EQ(initial_tab_2_x, tab1->x()); -} - -TEST_P(TabStripTest, GroupHeaderMovesOnRegrouping) { - SetMaxTabStripWidth(2000); - for (int i = 0; i < 3; i++) - controller_->AddTab(i, false); - tab_groups::TabGroupId group0 = tab_groups::TabGroupId::GenerateNew(); - controller_->MoveTabIntoGroup(0, group0); - tab_groups::TabGroupId group1 = tab_groups::TabGroupId::GenerateNew(); - controller_->MoveTabIntoGroup(1, group1); - controller_->MoveTabIntoGroup(2, group1); - CompleteAnimationAndLayout(); - - std::vector<TabGroupViews*> views = ListGroupViews(); - auto views_it = - std::find_if(views.begin(), views.end(), [&group1](TabGroupViews* view) { - return view->header()->group() == group1; - }); - ASSERT_TRUE(views_it != views.end()); - TabGroupViews* view = *views_it; - - // Change groups in a way so that the header should swap with the tab, without - // an explicit MoveTab call. - controller_->MoveTabIntoGroup(1, group0); - CompleteAnimationAndLayout(); - - // Header is now right of tab 1. - EXPECT_LT(tab_strip_->tab_at(1)->x(), view->header()->x()); - EXPECT_LT(view->header()->x(), tab_strip_->tab_at(2)->x()); -} - -TEST_P(TabStripTest, UngroupedTabMovesLeftOfHeader) { - SetMaxTabStripWidth(2000); - for (int i = 0; i < 2; i++) - controller_->AddTab(i, false); - tab_groups::TabGroupId group = tab_groups::TabGroupId::GenerateNew(); - controller_->MoveTabIntoGroup(0, group); - CompleteAnimationAndLayout(); - - controller_->MoveTab(1, 0); - CompleteAnimationAndLayout(); - - // Header is right of tab 0. - TabGroupHeader* header = ListGroupViews()[0]->header(); - EXPECT_LT(tab_strip_->tab_at(0)->x(), header->x()); - EXPECT_LT(header->x(), tab_strip_->tab_at(1)->x()); -} - -TEST_P(TabStripTest, DeleteTabGroupViewsWhenEmpty) { - controller_->AddTab(0, false); - controller_->AddTab(1, false); - absl::optional<tab_groups::TabGroupId> group = - tab_groups::TabGroupId::GenerateNew(); - controller_->MoveTabIntoGroup(0, group); - controller_->MoveTabIntoGroup(1, group); - controller_->MoveTabIntoGroup(0, absl::nullopt); - - EXPECT_EQ(1u, ListGroupViews().size()); - controller_->MoveTabIntoGroup(1, absl::nullopt); - EXPECT_EQ(0u, ListGroupViews().size()); -} - -TEST_P(TabStripTest, GroupUnderlineBasics) { - SetMaxTabStripWidth(1000); - bounds_animator()->SetAnimationDuration(base::TimeDelta()); - controller_->AddTab(0, false); - - absl::optional<tab_groups::TabGroupId> group = - tab_groups::TabGroupId::GenerateNew(); - controller_->MoveTabIntoGroup(0, group); - CompleteAnimationAndLayout(); - - std::vector<TabGroupViews*> views = ListGroupViews(); - EXPECT_EQ(1u, views.size()); - // Update underline manually in the absence of a real Paint cycle. - views[0]->UpdateBounds(); - - const TabGroupUnderline* underline = views[0]->underline(); - EXPECT_EQ(underline->x(), TabGroupUnderline::GetStrokeInset()); - EXPECT_GT(underline->width(), 0); - EXPECT_EQ(underline->bounds().right(), - tab_strip_->tab_at(0)->bounds().right() - - TabGroupUnderline::GetStrokeInset()); - EXPECT_EQ(underline->height(), TabGroupUnderline::kStrokeThickness); - - // Endpoints are different if the last grouped tab is active. - controller_->AddTab(1, true); - controller_->MoveTabIntoGroup(1, group); - views[0]->UpdateBounds(); - - EXPECT_EQ(underline->x(), TabGroupUnderline::GetStrokeInset()); - EXPECT_EQ(underline->bounds().right(), - tab_strip_->tab_at(1)->bounds().right() + - TabGroupUnderline::kStrokeThickness); -} - -TEST_P(TabStripTest, GroupHighlightBasics) { - SetMaxTabStripWidth(1000); - bounds_animator()->SetAnimationDuration(base::TimeDelta()); - controller_->AddTab(0, false); - - absl::optional<tab_groups::TabGroupId> group = - tab_groups::TabGroupId::GenerateNew(); - controller_->MoveTabIntoGroup(0, group); - CompleteAnimationAndLayout(); - - std::vector<TabGroupViews*> views = ListGroupViews(); - EXPECT_EQ(1u, views.size()); - - // The highlight bounds match the group view bounds. Grab this manually - // here, since there isn't a real paint cycle to trigger OnPaint(). - gfx::Rect bounds = views[0]->GetBounds(); - EXPECT_EQ(bounds.x(), 0); - EXPECT_GT(bounds.width(), 0); - EXPECT_EQ(bounds.right(), tab_strip_->tab_at(0)->bounds().right()); - EXPECT_EQ(bounds.height(), tab_strip_->tab_at(0)->bounds().height()); -} - TEST_P(TabStripTest, ChangingLayoutTypeResizesTabs) { SetMaxTabStripWidth(1000);
diff --git a/chrome/browser/ui/views/web_apps/pwa_confirmation_bubble_view.cc b/chrome/browser/ui/views/web_apps/pwa_confirmation_bubble_view.cc index d0bc25f..a3e3b80 100644 --- a/chrome/browser/ui/views/web_apps/pwa_confirmation_bubble_view.cc +++ b/chrome/browser/ui/views/web_apps/pwa_confirmation_bubble_view.cc
@@ -194,8 +194,6 @@ if (iph_state_ == chrome::PwaInProductHelpState::kShown && web_app_info_) { web_app::AppId app_id = web_app::GenerateAppId(web_app_info_->manifest_id, web_app_info_->start_url); - UMA_HISTOGRAM_ENUMERATION("WebApp.InstallIphPromo.Result", - web_app::InstallIphResult::kCanceled); web_app::RecordInstallIphIgnored(prefs_, app_id, base::Time::Now()); } if (callback_) { @@ -214,8 +212,6 @@ if (iph_state_ == chrome::PwaInProductHelpState::kShown) { web_app::AppId app_id = web_app::GenerateAppId(web_app_info_->manifest_id, web_app_info_->start_url); - UMA_HISTOGRAM_ENUMERATION("WebApp.InstallIphPromo.Result", - web_app::InstallIphResult::kInstalled); web_app::RecordInstallIphInstalled(prefs_, app_id); tracker_->NotifyEvent(feature_engagement::events::kDesktopPwaInstalled); }
diff --git a/chrome/browser/ui/views/web_apps/web_app_integration_browsertest.cc b/chrome/browser/ui/views/web_apps/web_app_integration_browsertest.cc index e6df18d..4373c49d 100644 --- a/chrome/browser/ui/views/web_apps/web_app_integration_browsertest.cc +++ b/chrome/browser/ui/views/web_apps/web_app_integration_browsertest.cc
@@ -2984,4 +2984,28 @@ helper_.CheckNoToolbar(); } +IN_PROC_BROWSER_TEST_F(WebAppIntegrationBrowserTest, + WebAppIntegration_29SiteB) { + // Test contents are generated by script. Please do not modify! + // See `chrome/test/webapps/README.md` for more info. + // Sheriffs: Disabling this test is supported. + helper_.InstallCreateShortcutTabbed(Site::kSiteB); +} + +IN_PROC_BROWSER_TEST_F(WebAppIntegrationBrowserTest, + WebAppIntegration_48SiteB) { + // Test contents are generated by script. Please do not modify! + // See `chrome/test/webapps/README.md` for more info. + // Sheriffs: Disabling this test is supported. + helper_.InstallPolicyAppTabbedShortcut(Site::kSiteB); +} + +IN_PROC_BROWSER_TEST_F(WebAppIntegrationBrowserTest, + WebAppIntegration_32SiteB) { + // Test contents are generated by script. Please do not modify! + // See `chrome/test/webapps/README.md` for more info. + // Sheriffs: Disabling this test is supported. + helper_.InstallPolicyAppTabbedNoShortcut(Site::kSiteB); +} + } // namespace web_app::integration_tests
diff --git a/chrome/browser/ui/webui/webui_gallery/webui_gallery_ui.cc b/chrome/browser/ui/webui/webui_gallery/webui_gallery_ui.cc index b90a6cc..c760e207 100644 --- a/chrome/browser/ui/webui/webui_gallery/webui_gallery_ui.cc +++ b/chrome/browser/ui/webui/webui_gallery/webui_gallery_ui.cc
@@ -10,6 +10,7 @@ #include "chrome/grit/webui_gallery_resources.h" #include "chrome/grit/webui_gallery_resources_map.h" #include "content/public/browser/web_ui_data_source.h" +#include "services/network/public/mojom/content_security_policy.mojom.h" #include "ui/base/webui/web_ui_util.h" namespace { @@ -22,6 +23,14 @@ source, base::make_span(kWebuiGalleryResources, kWebuiGalleryResourcesSize), IDR_WEBUI_GALLERY_WEBUI_GALLERY_HTML); + + source->DisableTrustedTypesCSP(); + source->OverrideContentSecurityPolicy( + network::mojom::CSPDirectiveName::FrameSrc, "frame-src 'self';"); + source->OverrideContentSecurityPolicy( + network::mojom::CSPDirectiveName::FrameAncestors, + "frame-ancestors 'self';"); + return source; }
diff --git a/chrome/browser/ui/webui/whats_new/whats_new_util.cc b/chrome/browser/ui/webui/whats_new/whats_new_util.cc index 4b01269..cea48abb 100644 --- a/chrome/browser/ui/webui/whats_new/whats_new_util.cc +++ b/chrome/browser/ui/webui/whats_new/whats_new_util.cc
@@ -50,33 +50,49 @@ g_is_remote_content_disabled = true; } +void LogStartupType(StartupType type) { + base::UmaHistogramEnumeration("WhatsNew.StartupType", type); +} + bool IsRemoteContentDisabled() { return g_is_remote_content_disabled; } -bool ShouldShowForState(PrefService* local_state) { - if (!local_state || !local_state->FindPreference(prefs::kLastWhatsNewVersion)) +bool ShouldShowForState(PrefService* local_state, + bool promotional_tabs_enabled) { + LogStartupType(StartupType::kCalledShouldShow); + + if (!promotional_tabs_enabled) { + whats_new::LogStartupType(whats_new::StartupType::kPromotionalTabsDisabled); return false; + } + + if (!local_state || + !local_state->FindPreference(prefs::kLastWhatsNewVersion)) { + LogStartupType(StartupType::kInvalidState); + return false; + } // Allow disabling the What's New experience in tests using the standard // kNoFirstRun switch. This behavior can be overridden using the // kForceWhatsNew switch for the What's New experience integration tests. const base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); - if (command_line->HasSwitch(switches::kNoFirstRun) && - !command_line->HasSwitch(switches::kForceWhatsNew)) { + if ((command_line->HasSwitch(switches::kNoFirstRun) && + !command_line->HasSwitch(switches::kForceWhatsNew)) || + !base::FeatureList::IsEnabled(features::kChromeWhatsNewUI)) { + LogStartupType(StartupType::kFeatureDisabled); return false; } - if (!base::FeatureList::IsEnabled(features::kChromeWhatsNewUI)) - return false; - int last_version = local_state->GetInteger(prefs::kLastWhatsNewVersion); // Don't show What's New if it's already been shown for the current major // milestone. - if (CHROME_VERSION_MAJOR <= last_version) + if (CHROME_VERSION_MAJOR <= last_version) { + LogStartupType(StartupType::kAlreadyShown); return false; + } // Set the last version here to indicate that What's New should not attempt // to display again for this milestone. This prevents the page from
diff --git a/chrome/browser/ui/webui/whats_new/whats_new_util.h b/chrome/browser/ui/webui/whats_new/whats_new_util.h index 05f8e7e..7706a30 100644 --- a/chrome/browser/ui/webui/whats_new/whats_new_util.h +++ b/chrome/browser/ui/webui/whats_new/whats_new_util.h
@@ -27,6 +27,26 @@ kMaxValue = kLoadFailAndDoNotShow, }; +// These values are persisted to logs. Entries should not be renumbered and +// numeric values should never be reused. +// The first value indicates that the logic for showing What's New is running. +// At most one of the remaining values will be logged for each run. If none of +// these values are logged, the page should try to load. +enum class StartupType { + kCalledShouldShow = 0, + kPromotionalTabsDisabled = 1, + kInvalidState = 2, + kFeatureDisabled = 3, + kAlreadyShown = 4, + kIneligible = 5, + kOverridden = 6, + kMaxValue = kOverridden, +}; + +// Logs the type of startup (e.g. whether a user is eligible for What's New, and +// whether we try to show the page). +void LogStartupType(StartupType type); + // Disables loading remote content for tests, because this can lead to a // redirect if it fails. Most tests don't expect redirects to occur. void DisableRemoteContentForTests(); @@ -47,7 +67,8 @@ // and possibly miss some users instead of repeatedly triggering a network // request at startup and/or showing the same What's New page many times for a // given user. -bool ShouldShowForState(PrefService* local_state); +bool ShouldShowForState(PrefService* local_state, + bool promotional_tabs_enabled); // Gets the server side URL for the What's New page for the current version of // Chrome. If |may_redirect| is true, return a server URL that will redirect to
diff --git a/chrome/browser/web_applications/extensions/externally_installed_web_app_prefs_unittest.cc b/chrome/browser/web_applications/extensions/externally_installed_web_app_prefs_unittest.cc index ab20be6..101a92d 100644 --- a/chrome/browser/web_applications/extensions/externally_installed_web_app_prefs_unittest.cc +++ b/chrome/browser/web_applications/extensions/externally_installed_web_app_prefs_unittest.cc
@@ -7,8 +7,12 @@ #include <algorithm> #include "base/command_line.h" +#include "base/json/json_reader.h" #include "chrome/browser/extensions/test_extension_system.h" +#include "chrome/browser/web_applications/test/fake_web_app_provider.h" +#include "chrome/browser/web_applications/test/web_app_test_utils.h" #include "chrome/browser/web_applications/web_app_constants.h" +#include "chrome/browser/web_applications/web_app_registry_update.h" #include "chrome/common/pref_names.h" #include "chrome/test/base/chrome_render_view_host_test_harness.h" #include "chrome/test/base/testing_profile.h" @@ -34,6 +38,9 @@ void SetUp() override { ChromeRenderViewHostTestHarness::SetUp(); + web_app_provider_ = web_app::FakeWebAppProvider::Get(profile()); + web_app_provider_->SkipAwaitingExtensionSystem(); + web_app_provider_->StartWithSubsystems(); // TODO(https://crbug.com/891172): Use an extension agnostic test registry. extensions::TestExtensionSystem* test_system = static_cast<extensions::TestExtensionSystem*>( @@ -73,6 +80,17 @@ return urls; } + void InitProvider() { + base::RunLoop run_loop; + web_app_provider_->on_registry_ready().Post(FROM_HERE, + run_loop.QuitClosure()); + run_loop.Run(); + } + + FakeWebAppProvider* provider() { return web_app_provider_; } + + private: + FakeWebAppProvider* web_app_provider_; }; TEST_F(ExternallyInstalledWebAppPrefsTest, BasicOps) { @@ -201,4 +219,122 @@ .IsPlaceholderApp("app_id_string")); } +// Case 1: Single App ID, no placeholder info (defaults to +// false). +TEST_F(ExternallyInstalledWebAppPrefsTest, NoPlaceholderInfoDefaultsToFalse) { + base::Value external_prefs = *base::JSONReader::Read(R"({ + "https://app1.com/": { + "extension_id": "test_app1", + "install_source": 2 + }, + "https://app2.com/": { + "extension_id": "test_app1", + "install_source": 3 + } + })"); + profile()->GetPrefs()->Set(prefs::kWebAppsExtensionIDs, + std::move(external_prefs)); + base::flat_map<AppId, ExternallyInstalledWebAppPrefs::ParsedPrefs> + web_app_data_map = + ExternallyInstalledWebAppPrefs::GetAppIdToWebAppParsedData( + profile()->GetPrefs()); + EXPECT_EQ(1u, web_app_data_map.size()); + EXPECT_FALSE(web_app_data_map["test_app1"] + .placeholder_map[WebAppManagement::Type::kPolicy]); + EXPECT_FALSE(web_app_data_map["test_app1"] + .placeholder_map[WebAppManagement::Type::kSystem]); +} + +// Case 2: Multiple entries with single app ID, with is_placeholder set to true. +TEST_F(ExternallyInstalledWebAppPrefsTest, + SinglePlaceholderInfoDefaultsToTrue) { + base::Value external_prefs = *base::JSONReader::Read(R"({ + "https://app1.com/": { + "extension_id": "test_app1", + "install_source": 0 + }, + "https://app2.com/": { + "extension_id": "test_app1", + "install_source": 0, + "is_placeholder": true + } + })"); + profile()->GetPrefs()->Set(prefs::kWebAppsExtensionIDs, + std::move(external_prefs)); + + base::flat_map<AppId, ExternallyInstalledWebAppPrefs::ParsedPrefs> + web_app_data_map = + ExternallyInstalledWebAppPrefs::GetAppIdToWebAppParsedData( + profile()->GetPrefs()); + EXPECT_EQ(1u, web_app_data_map.size()); + EXPECT_TRUE(web_app_data_map["test_app1"] + .placeholder_map[WebAppManagement::Type::kDefault]); +} + +TEST_F(ExternallyInstalledWebAppPrefsTest, MultiAppsMultiPlaceholderInfo) { + base::Value external_prefs = *base::JSONReader::Read(R"({ + "https://app1.com/": { + "extension_id": "test_app1", + "install_source": 1 + }, + "https://app2.com/": { + "extension_id": "test_app1", + "install_source": 1 + }, + "https://app3.com/": {}, + "https://app4.com/": { + "extension_id": "test_app4", + "install_source": 4, + "is_placeholder": true + }, + "https://app5.com/": { + "extension_id": "test_app4", + "is_placeholder": true + }, + "https://app6.com/": { + "install_source": 4 + } + })"); + profile()->GetPrefs()->Set(prefs::kWebAppsExtensionIDs, + std::move(external_prefs)); + base::flat_map<AppId, ExternallyInstalledWebAppPrefs::ParsedPrefs> + web_app_data_map = + ExternallyInstalledWebAppPrefs::GetAppIdToWebAppParsedData( + profile()->GetPrefs()); + EXPECT_EQ(2u, web_app_data_map.size()); + EXPECT_FALSE(web_app_data_map["test_app1"] + .placeholder_map[WebAppManagement::Type::kDefault]); + EXPECT_TRUE(web_app_data_map["test_app4"] + .placeholder_map[WebAppManagement::Type::kWebAppStore]); +} + +TEST_F(ExternallyInstalledWebAppPrefsTest, + PlaceholderMigrationTestForSingleSource) { + InitProvider(); + std::unique_ptr<WebApp> web_app = test::CreateWebApp( + GURL("https://app.com/"), WebAppManagement::Type::kDefault); + AppId app_id = web_app->app_id(); + { + ScopedRegistryUpdate update(&provider()->sync_bridge()); + update->CreateApp(std::move(web_app)); + } + const WebApp* installed_app = provider()->registrar().GetAppById(app_id); + EXPECT_FALSE(provider()->registrar().IsPlaceholderApp(app_id)); + EXPECT_EQ(0u, installed_app->management_to_external_config_map().size()); + + ExternallyInstalledWebAppPrefs external_prefs(profile()->GetPrefs()); + external_prefs.Insert(GURL("https://app.com/install"), app_id, + ExternalInstallSource::kExternalDefault); + external_prefs.SetIsPlaceholder(GURL("https://app.com/install"), true); + + ExternallyInstalledWebAppPrefs::MigrateExternalPrefData( + profile()->GetPrefs(), &provider()->sync_bridge()); + + EXPECT_TRUE(provider()->registrar().IsPlaceholderApp(app_id)); + EXPECT_EQ(1u, installed_app->management_to_external_config_map().size()); + EXPECT_TRUE(installed_app->management_to_external_config_map() + .at(WebAppManagement::Type::kDefault) + .is_placeholder); +} + } // namespace web_app
diff --git a/chrome/browser/web_applications/externally_installed_web_app_prefs.cc b/chrome/browser/web_applications/externally_installed_web_app_prefs.cc index 41080349..761281a 100644 --- a/chrome/browser/web_applications/externally_installed_web_app_prefs.cc +++ b/chrome/browser/web_applications/externally_installed_web_app_prefs.cc
@@ -8,8 +8,8 @@ #include <utility> #include <vector> -#include "base/values.h" -#include "chrome/browser/web_applications/web_app_registrar.h" +#include "chrome/browser/web_applications/web_app_install_utils.h" +#include "chrome/browser/web_applications/web_app_registry_update.h" #include "chrome/common/pref_names.h" #include "components/pref_registry/pref_registry_syncable.h" #include "components/prefs/pref_service.h" @@ -78,6 +78,13 @@ } // namespace +ExternallyInstalledWebAppPrefs::ParsedPrefs::ParsedPrefs() = default; + +ExternallyInstalledWebAppPrefs::ParsedPrefs::ParsedPrefs( + const ParsedPrefs& other) = default; + +ExternallyInstalledWebAppPrefs::ParsedPrefs::~ParsedPrefs() = default; + // static void ExternallyInstalledWebAppPrefs::RegisterProfilePrefs( user_prefs::PrefRegistrySyncable* registry) { @@ -239,4 +246,96 @@ return app_prefs->FindBoolKey(kIsPlaceholder).value_or(false); } +// static +base::flat_map<AppId, ExternallyInstalledWebAppPrefs::ParsedPrefs> +ExternallyInstalledWebAppPrefs::GetAppIdToWebAppParsedData( + PrefService* pref_service) { + const base::Value* urls_to_dicts = + pref_service->GetDictionary(prefs::kWebAppsExtensionIDs); + base::flat_map<AppId, ExternallyInstalledWebAppPrefs::ParsedPrefs> + ids_to_parsed_data; + if (!urls_to_dicts) + return ids_to_parsed_data; + + for (auto it : urls_to_dicts->DictItems()) { + ParsedPrefs parsed_prefs; + const base::Value* v = &it.second; + if (!v->is_dict()) { + continue; + } + + auto* app_id = v->FindKey(kExtensionId); + if (!app_id || !app_id->is_string()) { + continue; + } + + if (ids_to_parsed_data.contains(app_id->GetString())) { + parsed_prefs = ids_to_parsed_data[app_id->GetString()]; + } + + auto* source = v->FindKey(kInstallSource); + if (!source) { + ids_to_parsed_data[app_id->GetString()] = parsed_prefs; + continue; + } + + WebAppManagement::Type source_type = + ConvertExternalInstallSourceToWebAppManagement(source->GetInt()); + + parsed_prefs.placeholder_map[source_type] = + v->FindBoolKey(kIsPlaceholder).value_or(false); + ids_to_parsed_data.insert_or_assign(app_id->GetString(), + std::move(parsed_prefs)); + } + return ids_to_parsed_data; +} + +// static +WebAppManagement::Type +ExternallyInstalledWebAppPrefs::ConvertExternalInstallSourceToWebAppManagement( + int source) { + switch (source) { + case 0: + return ConvertExternalInstallSourceToSource( + ExternalInstallSource::kInternalDefault); + case 1: + return ConvertExternalInstallSourceToSource( + ExternalInstallSource::kExternalDefault); + case 2: + return ConvertExternalInstallSourceToSource( + ExternalInstallSource::kExternalPolicy); + case 3: + return ConvertExternalInstallSourceToSource( + ExternalInstallSource::kSystemInstalled); + case 4: + return ConvertExternalInstallSourceToSource(ExternalInstallSource::kArc); + default: + NOTREACHED(); + return WebAppManagement::Type::kSync; + } +} + +// static +void ExternallyInstalledWebAppPrefs::MigrateExternalPrefData( + PrefService* pref_service, + WebAppSyncBridge* sync_bridge) { + base::flat_map<AppId, ExternallyInstalledWebAppPrefs::ParsedPrefs> + pref_to_app_data = GetAppIdToWebAppParsedData(pref_service); + + ScopedRegistryUpdate update(sync_bridge); + for (auto it : pref_to_app_data) { + WebApp* web_app = update->UpdateApp(it.first); + if (web_app) { + // Sync placeholder info across external prefs and web_app DB by + // overwriting. + for (auto placeholder_info : it.second.placeholder_map) { + if (web_app->GetSources().test(placeholder_info.first)) { + web_app->AddPlaceholderInfoToManagementExternalConfigMap( + placeholder_info.first, placeholder_info.second); + } + } + } + } +} + } // namespace web_app
diff --git a/chrome/browser/web_applications/externally_installed_web_app_prefs.h b/chrome/browser/web_applications/externally_installed_web_app_prefs.h index 378d0e0..b8820055 100644 --- a/chrome/browser/web_applications/externally_installed_web_app_prefs.h +++ b/chrome/browser/web_applications/externally_installed_web_app_prefs.h
@@ -7,9 +7,11 @@ #include <map> +#include "base/containers/flat_map.h" #include "base/memory/raw_ptr.h" #include "chrome/browser/web_applications/web_app_constants.h" #include "chrome/browser/web_applications/web_app_id.h" +#include "chrome/browser/web_applications/web_app_sync_bridge.h" #include "third_party/abseil-cpp/absl/types/optional.h" class GURL; @@ -28,6 +30,15 @@ // and system apps. class ExternallyInstalledWebAppPrefs { public: + // Used in the migration to the web_app DB. + struct ParsedPrefs { + ParsedPrefs(); + ParsedPrefs(const ParsedPrefs& other); + ~ParsedPrefs(); + + base::flat_map<WebAppManagement::Type, bool> placeholder_map; + }; + static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry); static bool HasAppId(const PrefService* pref_service, const AppId& app_id); @@ -68,7 +79,21 @@ void SetIsPlaceholder(const GURL& url, bool is_placeholder); bool IsPlaceholderApp(const AppId& app_id) const; + // Converts the existing external_pref information to a map<AppId, + // ParsedPrefs> for simplified parsing and migrating to the web app DB. + static base::flat_map<AppId, ParsedPrefs> GetAppIdToWebAppParsedData( + PrefService* pref_service); + + // Used to migrate the external pref data to the installed web_app DB. + static void MigrateExternalPrefData(PrefService* pref_service, + WebAppSyncBridge* sync_bridge); + private: + // The install_source to web_app_management conversion refers to the + // ConvertExternalInstallSourceToSource() function in + // web_app_install_utils.cc. + static WebAppManagement::Type ConvertExternalInstallSourceToWebAppManagement( + int source); const raw_ptr<PrefService> pref_service_; };
diff --git a/chrome/browser/web_applications/externally_managed_app_install_task.cc b/chrome/browser/web_applications/externally_managed_app_install_task.cc index a8193524..528891f6 100644 --- a/chrome/browser/web_applications/externally_managed_app_install_task.cc +++ b/chrome/browser/web_applications/externally_managed_app_install_task.cc
@@ -312,6 +312,8 @@ options.add_to_desktop = install_options_.add_to_desktop; options.add_to_quick_launch_bar = install_options_.add_to_quick_launch_bar; + web_app_info.is_placeholder = true; + install_finalizer_->FinalizeInstall( web_app_info, options, base::BindOnce(
diff --git a/chrome/browser/web_applications/web_app.cc b/chrome/browser/web_applications/web_app.cc index 2bb6109f..89e4c126 100644 --- a/chrome/browser/web_applications/web_app.cc +++ b/chrome/browser/web_applications/web_app.cc
@@ -392,6 +392,13 @@ std::move(management_to_external_config_map); } +void WebApp::AddPlaceholderInfoToManagementExternalConfigMap( + WebAppManagement::Type type, + bool is_placeholder) { + DCHECK_NE(type, WebAppManagement::Type::kSync); + management_to_external_config_map_[type].is_placeholder = is_placeholder; +} + WebApp::ClientData::ClientData() = default; WebApp::ClientData::~ClientData() = default;
diff --git a/chrome/browser/web_applications/web_app.h b/chrome/browser/web_applications/web_app.h index 6c2f97a8..0635bbf 100644 --- a/chrome/browser/web_applications/web_app.h +++ b/chrome/browser/web_applications/web_app.h
@@ -375,6 +375,10 @@ base::flat_map<WebAppManagement::Type, ExternalManagementConfig> management_to_external_config_map); + void AddPlaceholderInfoToManagementExternalConfigMap( + WebAppManagement::Type source_type, + bool is_placeholder); + // For logging and debug purposes. bool operator==(const WebApp&) const; bool operator!=(const WebApp&) const;
diff --git a/chrome/browser/web_applications/web_app_constants.h b/chrome/browser/web_applications/web_app_constants.h index 8d28081..20b439e 100644 --- a/chrome/browser/web_applications/web_app_constants.h +++ b/chrome/browser/web_applications/web_app_constants.h
@@ -197,19 +197,6 @@ std::string RunOnOsLoginModeToString(RunOnOsLoginMode mode); -// These values are persisted to logs. Entries should not be renumbered and -// numeric values should never be reused. -// Records result of user reaction to install in-product help promo. -enum class InstallIphResult { - // Installed the web app after IPH was shown. - kInstalled = 0, - // Clicked the install icon but canceled install after IPH was shown. - kCanceled = 1, - // Ignored IPH, didn't click install. - kIgnored = 2, - kMaxValue = kIgnored, -}; - // Number of times IPH can be ignored for this app before it's muted. constexpr int kIphMuteAfterConsecutiveAppSpecificIgnores = 3; // Number of times IPH can be ignored for any app before it's muted.
diff --git a/chrome/browser/web_applications/web_app_install_finalizer.cc b/chrome/browser/web_applications/web_app_install_finalizer.cc index 4f5a43c..25efa1f 100644 --- a/chrome/browser/web_applications/web_app_install_finalizer.cc +++ b/chrome/browser/web_applications/web_app_install_finalizer.cc
@@ -169,6 +169,13 @@ web_app->SetParentAppId(options.parent_app_id); web_app->SetInstallSourceForMetrics(options.install_surface); + DCHECK(!(source == WebAppManagement::Type::kSync && + web_app_info.is_placeholder)); + if (source != WebAppManagement::Type::kSync) { + web_app->AddPlaceholderInfoToManagementExternalConfigMap( + source, web_app_info.is_placeholder); + } + if (!options.locally_installed) { DCHECK(!(options.add_to_applications_menu || options.add_to_desktop || options.add_to_quick_launch_bar))
diff --git a/chrome/browser/web_applications/web_app_install_info.h b/chrome/browser/web_applications/web_app_install_info.h index 234d299a..d5eb105 100644 --- a/chrome/browser/web_applications/web_app_install_info.h +++ b/chrome/browser/web_applications/web_app_install_info.h
@@ -12,7 +12,6 @@ #include <string> #include <vector> -#include "base/containers/flat_set.h" #include "base/values.h" #include "chrome/browser/web_applications/user_display_mode.h" #include "components/services/app_service/public/cpp/file_handler.h" @@ -320,6 +319,11 @@ // The declared permissions policy to apply as the baseline policy for all // documents belonging to the application. blink::ParsedPermissionsPolicy permissions_policy; + + // See ExternallyManagedAppManager for placeholder app documentation. + // Intended to be a temporary app while we wait for the install_url to + // successfully load. + bool is_placeholder = false; }; bool operator==(const IconSizes& icon_sizes1, const IconSizes& icon_sizes2);
diff --git a/chrome/browser/web_applications/web_app_provider.cc b/chrome/browser/web_applications/web_app_provider.cc index 9397e50c..7c2eecf 100644 --- a/chrome/browser/web_applications/web_app_provider.cc +++ b/chrome/browser/web_applications/web_app_provider.cc
@@ -357,6 +357,9 @@ void WebAppProvider::OnSyncBridgeReady() { DCHECK(!on_registry_ready_.is_signaled()); + ExternallyInstalledWebAppPrefs::MigrateExternalPrefData(profile_->GetPrefs(), + sync_bridge_.get()); + registrar_->Start(); install_finalizer_->Start(); icon_manager_->Start();
diff --git a/chrome/browser/webauthn/android/BUILD.gn b/chrome/browser/webauthn/android/BUILD.gn index 43df9d9..5924d6e 100644 --- a/chrome/browser/webauthn/android/BUILD.gn +++ b/chrome/browser/webauthn/android/BUILD.gn
@@ -18,8 +18,10 @@ "//chrome/browser/notifications:java", "//components/browser_ui/notifications/android:java", "//content/public/android:content_main_dex_java", - "//third_party/android_deps:android_support_v7_appcompat_java", "//third_party/androidx:androidx_annotation_annotation_java", + "//third_party/androidx:androidx_core_core_java", + "//third_party/androidx:androidx_fragment_fragment_java", + "//third_party/androidx:androidx_vectordrawable_vectordrawable_animated_java", "//ui/android:ui_no_recycler_view_java", ] annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ]
diff --git a/chrome/build/mac-arm.pgo.txt b/chrome/build/mac-arm.pgo.txt index c9d49d1..6918f3a 100644 --- a/chrome/build/mac-arm.pgo.txt +++ b/chrome/build/mac-arm.pgo.txt
@@ -1 +1 @@ -chrome-mac-arm-main-1650974392-e3c4b143bcb76e45751440f0e305c074613bcddf.profdata +chrome-mac-arm-main-1651017376-1a276e83e4fd9365ce83c3136dc9109129a5ecf8.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt index 8289608..58fbad5 100644 --- a/chrome/build/mac.pgo.txt +++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@ -chrome-mac-main-1650974392-05744d58a0384be9f8620fb5420a3ea2389f3b04.profdata +chrome-mac-main-1651017376-e88bf04884399054fcc1833c787590b30c143ddb.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt index 080537d..a627d573 100644 --- a/chrome/build/win32.pgo.txt +++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@ -chrome-win32-main-1650974392-57db2f99b0f4372454c69a1a11a65d71dd821985.profdata +chrome-win32-main-1651006646-398851e81db1e8c9f33d3737b1e7d1801d48afea.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt index 6e794c7..86b2f93 100644 --- a/chrome/build/win64.pgo.txt +++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@ -chrome-win64-main-1650985015-6310edfb8eafc2937ffb18731a4797fa5265b548.profdata +chrome-win64-main-1651006646-53e454dcbfd173abb05a9d0432955069c28a19e0.profdata
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc index 8ef3705..f440ee69 100644 --- a/chrome/common/pref_names.cc +++ b/chrome/common/pref_names.cc
@@ -1607,6 +1607,9 @@ // Preference storing Easy Unlock pairing data. const char kEasyUnlockPairing[] = "easy_unlock.pairing"; +const char kHasSeenSmartLockSignInRemovedNotification[] = + "easy_unlock.has_seen_smart_lock_sign_in_removed_notification"; + #if BUILDFLAG(ENABLE_EXTENSIONS) // Used to indicate whether or not the toolbar redesign bubble has been shown // and acknowledged, and the last time the bubble was shown.
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h index 607109e1..658dded6 100644 --- a/chrome/common/pref_names.h +++ b/chrome/common/pref_names.h
@@ -517,6 +517,7 @@ extern const char kEasyUnlockAllowed[]; extern const char kEasyUnlockPairing[]; +extern const char kHasSeenSmartLockSignInRemovedNotification[]; #if BUILDFLAG(ENABLE_EXTENSIONS) extern const char kToolbarIconSurfacingBubbleAcknowledged[];
diff --git a/chrome/installer/setup/install.cc b/chrome/installer/setup/install.cc index 1904d43..1356261 100644 --- a/chrome/installer/setup/install.cc +++ b/chrome/installer/setup/install.cc
@@ -21,6 +21,7 @@ #include "base/numerics/safe_conversions.h" #include "base/path_service.h" #include "base/process/launch.h" +#include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" @@ -442,6 +443,52 @@ } } +// Run a child process that will create/update a shortcut for an +// install. This is done in a child process to avoid crashing the main +// install process if we crash in Windows shell functions. For more info, +// see crbug.com/1276348. +void RunShortcutCreationInChildProc( + const InstallerState& installer_state, + const base::FilePath& setup_path, + const absl::optional<const base::FilePath>& prefs_path, + InstallShortcutLevel install_level, + InstallShortcutOperation install_operation) { + base::CommandLine command_line(setup_path); + InstallUtil::AppendModeAndChannelSwitches(&command_line); + if (installer_state.system_install()) + command_line.AppendSwitch(switches::kSystemLevel); + + command_line.AppendSwitch(switches::kVerboseLogging); + if (prefs_path.has_value()) + command_line.AppendSwitchPath(switches::kInstallerData, prefs_path.value()); + + command_line.AppendSwitchASCII(switches::kCreateShortcuts, + base::NumberToString(install_operation)); + command_line.AppendSwitchASCII(switches::kInstallLevel, + base::NumberToString(install_level)); + base::LaunchOptions launch_options; + launch_options.feedback_cursor_off = true; + + VLOG(1) << "Launching \"" << command_line.GetCommandLineString() + << "\" to create shortcuts"; + ::SetLastError(ERROR_SUCCESS); + base::Process process = base::LaunchProcess(command_line, launch_options); + if (!process.IsValid()) { + PLOG(ERROR) << "Failed to launch \"" << command_line.GetCommandLineString() + << "\""; + return; + } + int exit_code = OS_ERROR; + process.Process::WaitForExit(&exit_code); + + if (exit_code != CREATE_SHORTCUTS_SUCCESS) { + LOG(ERROR) << "Launch shortcut creation process failed with exit code " + << exit_code; + } else { + VLOG(1) << "Shortcut creation process succeeded."; + } +} + InstallStatus InstallOrUpdateProduct(const InstallParams& install_params, const base::FilePath& prefs_path, const InitialPreferences& prefs) { @@ -473,22 +520,12 @@ if (!InstallUtil::GetInstallReturnCode(result)) { installer_state.SetStage(COPYING_PREFERENCES_FILE); - if (result == FIRST_INSTALL_SUCCESS && !prefs_path.empty()) + const bool use_initial_prefs = + result == FIRST_INSTALL_SUCCESS && !prefs_path.empty(); + if (use_initial_prefs) CopyPreferenceFileForFirstRun(installer_state, prefs_path); installer_state.SetStage(CREATING_SHORTCUTS); - - // Creates shortcuts for Chrome. - const base::FilePath chrome_exe( - installer_state.target_path().Append(kChromeExe)); - - // Install per-user shortcuts on user-level installs and all-users shortcuts - // on system-level installs. Note that Active Setup will take care of - // installing missing per-user shortcuts on system-level install (i.e., - // quick launch, taskbar pin, and possibly deleted all-users shortcuts). - InstallShortcutLevel install_level = - installer_state.system_install() ? ALL_USERS : CURRENT_USER; - InstallShortcutOperation install_operation = INSTALL_SHORTCUT_REPLACE_EXISTING; if (result == FIRST_INSTALL_SUCCESS || result == INSTALL_REPAIRED || @@ -497,9 +534,13 @@ // when the Chrome product is being added to the current install. install_operation = INSTALL_SHORTCUT_CREATE_ALL; } - - CreateOrUpdateShortcuts(chrome_exe, prefs, install_level, - install_operation); + InstallShortcutLevel install_level = + installer_state.system_install() ? ALL_USERS : CURRENT_USER; + RunShortcutCreationInChildProc( + installer_state, setup_path, + use_initial_prefs ? absl::optional<base::FilePath>(prefs_path) + : absl::nullopt, + install_level, install_operation); // Register Chrome and, if requested, make Chrome the default browser. installer_state.SetStage(REGISTERING_CHROME); @@ -573,21 +614,19 @@ } void HandleOsUpgradeForBrowser(const InstallerState& installer_state, - const base::Version& installed_version) { + const base::Version& installed_version, + const base::FilePath& setup_path) { VLOG(1) << "Updating and registering shortcuts for --on-os-upgrade."; - // Read the initial preferences copied beside chrome.exe at install. - const InitialPreferences prefs( - installer_state.target_path().AppendASCII(kLegacyInitialPrefs)); - // Update shortcuts at this install level (per-user shortcuts on system-level // installs will be updated through Active Setup). const InstallShortcutLevel level = installer_state.system_install() ? ALL_USERS : CURRENT_USER; - const base::FilePath chrome_exe( - installer_state.target_path().Append(kChromeExe)); - CreateOrUpdateShortcuts(chrome_exe, prefs, level, - INSTALL_SHORTCUT_REPLACE_EXISTING); + + RunShortcutCreationInChildProc( + installer_state, setup_path, + installer_state.target_path().AppendASCII(kLegacyInitialPrefs), level, + INSTALL_SHORTCUT_REPLACE_EXISTING); // Adapt Chrome registrations to this new OS. RegisterChromeOnMachine(installer_state, false, installed_version); @@ -614,7 +653,8 @@ // can be done directly; whereas it requires triggering Active Setup for each // user's subsequent login on system-level installs. if (!installer_state.system_install()) { - UpdateDefaultBrowserBeaconForPath(chrome_exe); + UpdateDefaultBrowserBeaconForPath( + installer_state.target_path().Append(kChromeExe)); } else { UpdateActiveSetupVersionWorkItem active_setup_work_item( install_static::GetActiveSetupPath(), @@ -632,6 +672,7 @@ // install. It may also be invoked again when a system-level chrome install goes // through an OS upgrade. void HandleActiveSetupForBrowser(const InstallerState& installer_state, + const base::FilePath& setup_path, bool force) { std::unique_ptr<WorkItemList> cleanup_list(WorkItem::CreateWorkItemList()); cleanup_list->set_log_message("Cleanup deprecated per-user registrations"); @@ -652,27 +693,23 @@ ? INSTALL_SHORTCUT_REPLACE_EXISTING : INSTALL_SHORTCUT_CREATE_EACH_IF_NO_SYSTEM_LEVEL; - // Read the initial preferences copied beside chrome.exe at install for the + // Use the initial preferences copied beside chrome.exe at install for the // sake of creating/updating shortcuts. const base::FilePath installation_root = installer_state.target_path(); - InitialPreferences prefs(installation_root.AppendASCII(kLegacyInitialPrefs)); - base::FilePath chrome_exe(installation_root.Append(kChromeExe)); - CreateOrUpdateShortcuts(chrome_exe, prefs, CURRENT_USER, install_operation); + RunShortcutCreationInChildProc( + installer_state, setup_path, + installation_root.AppendASCII(kLegacyInitialPrefs), CURRENT_USER, + install_operation); - UpdateDefaultBrowserBeaconForPath(chrome_exe); + UpdateDefaultBrowserBeaconForPath(installation_root.Append(kChromeExe)); // This install may have been selected into a study for a retention // experiment following a successful update. In case the experiment was not // able to run immediately after the update (e.g., no user was logged on at // the time), try to run it now that the installer is running in the context // of a user. - if (ShouldRunUserExperiment(installer_state)) { - base::FilePath setup_exe; - if (!base::PathService::Get(base::FILE_EXE, &setup_exe)) - LOG(ERROR) << "Failed to get path to setup.exe."; - else - BeginUserExperiment(installer_state, setup_exe, true /* user_context */); - } + if (ShouldRunUserExperiment(installer_state)) + BeginUserExperiment(installer_state, setup_path, true /* user_context */); } } // namespace installer
diff --git a/chrome/installer/setup/install.h b/chrome/installer/setup/install.h index b3a5460..721cd32f 100644 --- a/chrome/installer/setup/install.h +++ b/chrome/installer/setup/install.h
@@ -24,6 +24,7 @@ // Create all shortcuts (potentially skipping those explicitly stated not to // be installed in the InstallShortcutPreferences). INSTALL_SHORTCUT_CREATE_ALL, + INSTALL_SHORTCUT_FIRST = INSTALL_SHORTCUT_CREATE_ALL, // Create each per-user shortcut (potentially skipping those explicitly stated // not to be installed in the InstallShortcutPreferences), but only if the // system-level equivalent of that shortcut is not present on the system. @@ -31,15 +32,19 @@ // Replace all shortcuts that still exist with the most recent version of // each individual shortcut. INSTALL_SHORTCUT_REPLACE_EXISTING, + INSTALL_SHORTCUT_LAST = INSTALL_SHORTCUT_REPLACE_EXISTING, }; enum InstallShortcutLevel { // Install shortcuts for the current user only. - CURRENT_USER, + INSTALL_SHORTCUT_LEVEL_FIRST = 0, + CURRENT_USER = INSTALL_SHORTCUT_LEVEL_FIRST, // Install global shortcuts visible to all users. Note: the Quick Launch // and taskbar pin shortcuts are still installed per-user (as they have no // all-users version). ALL_USERS, + // Update if a shortcut level is added. + INSTALL_SHORTCUT_LEVEL_LAST = ALL_USERS, }; // Creates chrome.VisualElementsManifest.xml in |src_path| if @@ -84,15 +89,18 @@ const InstallerState& installer_state); // Performs installation-related tasks following an OS upgrade. -// |chrome| The installed product (must be a browser). -// |installed_version| the current version of this install. +// `installer_state` The installer state. +// `installed_version` the current version of this install. +// `setup_path` path to setup.exe void HandleOsUpgradeForBrowser(const InstallerState& installer_state, - const base::Version& installed_version); + const base::Version& installed_version, + const base::FilePath& setup_path); // Performs per-user installation-related tasks on Active Setup (ran on first // login for each user post system-level Chrome install). Shortcut creation is -// skipped if the First Run beacon is present (unless |force| is set to true). +// skipped if the First Run beacon is present (unless `force` is set to true). void HandleActiveSetupForBrowser(const InstallerState& installer_state, + const base::FilePath& setup_path, bool force); } // namespace installer
diff --git a/chrome/installer/setup/setup_main.cc b/chrome/installer/setup/setup_main.cc index d233e04e1..ed41241 100644 --- a/chrome/installer/setup/setup_main.cc +++ b/chrome/installer/setup/setup_main.cc
@@ -896,12 +896,36 @@ return status; } +installer::InstallStatus CreateShortcutsInChildProc( + const InstallerState& installer_state, + const InitialPreferences& prefs, + installer::InstallShortcutLevel install_level, + installer::InstallShortcutOperation install_operation) { + // Create shortcut in a child process so that shell crashes don't make the + // install/update fail. Pass install operation on the command line since + // it can't be deduced by the child process; + + // Creates shortcuts for Chrome. + const base::FilePath chrome_exe( + installer_state.target_path().Append(installer::kChromeExe)); + + // Install per-user shortcuts on user-level installs and all-users shortcuts + // on system-level installs. Note that Active Setup will take care of + // installing missing per-user shortcuts on system-level install (i.e., + // quick launch, taskbar pin, and possibly deleted all-users shortcuts). + CreateOrUpdateShortcuts(chrome_exe, prefs, install_level, install_operation); + // TODO(): Plumb shortcut creation failure through and return a failure exit + // code. + return installer::CREATE_SHORTCUTS_SUCCESS; +} + // This method processes any command line options that make setup.exe do // various tasks other than installation (renaming chrome.exe, showing eula // among others). This function returns true if any such command line option // has been found and processed (so setup.exe should exit at that point). bool HandleNonInstallCmdLineOptions(installer::ModifyParams& modify_params, const base::CommandLine& cmd_line, + const InitialPreferences& prefs, int* exit_code) { installer::InstallerState* installer_state = &(modify_params.installer_state); installer::InstallationState* original_state = @@ -970,7 +994,8 @@ if (installer_state->system_install()) { bool force = cmd_line.HasSwitch(installer::switches::kForceConfigureUserSettings); - installer::HandleActiveSetupForBrowser(*installer_state, force); + installer::HandleActiveSetupForBrowser(*installer_state, setup_exe, + force); status = installer::INSTALL_REPAIRED; } else { LOG(DFATAL) @@ -1080,7 +1105,8 @@ const base::Version installed_version( base::UTF16ToUTF8(version_info->product_version())); if (installed_version.IsValid()) { - installer::HandleOsUpgradeForBrowser(*installer_state, installed_version); + installer::HandleOsUpgradeForBrowser(*installer_state, installed_version, + setup_exe); status = installer::INSTALL_REPAIRED; } else { LOG(DFATAL) << "Failed to extract product version from " @@ -1181,6 +1207,29 @@ ? installer::ROTATE_DTKEY_SUCCESS : installer::ROTATE_DTKEY_FAILED; #endif + } else if (cmd_line.HasSwitch(installer::switches::kCreateShortcuts)) { + std::string install_op_arg = + cmd_line.GetSwitchValueASCII(installer::switches::kCreateShortcuts); + std::string shortcut_level_arg = + cmd_line.GetSwitchValueASCII(installer::switches::kInstallLevel); + int install_op; + int install_level_op; + if (!base::StringToInt(install_op_arg, &install_op) || + install_op < installer::INSTALL_SHORTCUT_FIRST || + install_op > installer::INSTALL_SHORTCUT_LAST) { + LOG(ERROR) << "Invalid shortcut operation " << install_op_arg; + *exit_code = installer::UNSUPPORTED_OPTION; + } else if (!base::StringToInt(shortcut_level_arg, &install_level_op) || + install_level_op < installer::INSTALL_SHORTCUT_LEVEL_FIRST || + install_level_op > installer::INSTALL_SHORTCUT_LEVEL_LAST) { + LOG(ERROR) << "Invalid shortcut level " << shortcut_level_arg; + *exit_code = installer::UNSUPPORTED_OPTION; + } else { + *exit_code = CreateShortcutsInChildProc( + *installer_state, prefs, + static_cast<installer::InstallShortcutLevel>(install_level_op), + static_cast<installer::InstallShortcutOperation>(install_op)); + } } else { handled = false; } @@ -1577,7 +1626,8 @@ }; int exit_code = 0; - if (HandleNonInstallCmdLineOptions(modify_params, cmd_line, &exit_code)) { + if (HandleNonInstallCmdLineOptions(modify_params, cmd_line, prefs, + &exit_code)) { return exit_code; }
diff --git a/chrome/installer/util/util_constants.cc b/chrome/installer/util/util_constants.cc index 2dda2923..a05091fd 100644 --- a/chrome/installer/util/util_constants.cc +++ b/chrome/installer/util/util_constants.cc
@@ -26,6 +26,9 @@ // this option is not compatible with any other installer options. const char kConfigureUserSettings[] = "configure-user-settings"; +// Create shortcuts with the installer operation arg. +const char kCreateShortcuts[] = "create-shortcuts"; + // The version number of an update containing critical fixes, for which an // in-use Chrome should be restarted ASAP. const char kCriticalUpdateVersion[] = "critical-update-version"; @@ -82,6 +85,9 @@ // Specify the file path of Chrome initial preference file. const char kInstallerData[] = "installerdata"; +// What install level to create shortcuts for, if "create-shortcuts" is present. +const char kInstallLevel[] = "install-level"; + // If present, specify file path to write logging info. const char kLogFile[] = "log-file";
diff --git a/chrome/installer/util/util_constants.h b/chrome/installer/util/util_constants.h index d494504..ca8bbe4 100644 --- a/chrome/installer/util/util_constants.h +++ b/chrome/installer/util/util_constants.h
@@ -119,8 +119,9 @@ DOWNGRADE_CLEANUP_UNKNOWN_OPERATION = 70, ROTATE_DTKEY_FAILED = 71, // Failed to rotate device trust signing key. ROTATE_DTKEY_SUCCESS = 72, // Successfully rotated device trust signing key. - MAX_INSTALL_STATUS = 73, // When adding a new result, bump this and update - // the SetupInstallResult enum in histograms.xml. + CREATE_SHORTCUTS_SUCCESS = 73, // Successfully created Chrome shortcuts. + MAX_INSTALL_STATUS = 74, // When adding a new result, bump this and update + // the SetupInstallResult enum in enums.xml. }; // The type of an update archive. @@ -158,6 +159,7 @@ extern const char kAllowDowngrade[]; extern const char kChannel[]; extern const char kConfigureUserSettings[]; +extern const char kCreateShortcuts[]; extern const char kCriticalUpdateVersion[]; extern const char kDeleteOldVersions[]; extern const char kDeleteProfile[]; @@ -172,6 +174,7 @@ extern const char kInputFile[]; extern const char kInstallArchive[]; extern const char kInstallerData[]; +extern const char kInstallLevel[]; extern const char kLogFile[]; extern const char kMakeChromeDefault[]; extern const char kMsi[];
diff --git a/chrome/renderer/loadtimes_extension_bindings.cc b/chrome/renderer/loadtimes_extension_bindings.cc index a88aa98a..c4e18f7 100644 --- a/chrome/renderer/loadtimes_extension_bindings.cc +++ b/chrome/renderer/loadtimes_extension_bindings.cc
@@ -135,7 +135,7 @@ if (!document_loader) { return; } - const blink::WebURLResponse& response = document_loader->GetResponse(); + const blink::WebURLResponse& response = document_loader->GetWebResponse(); WebPerformance web_performance = frame->Performance(); // Though request time now tends to be used to describe the time that the // request for the main resource was issued, when chrome.loadTimes() was
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 183a943..5d06e5b 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -351,6 +351,7 @@ "//components/ukm:test_support", "//components/ukm:ukm_test_helper", "//components/web_modal", + "//ui/compositor:test_support", "//ui/snapshot", ] @@ -374,6 +375,8 @@ "../browser/ui/profile_ui_test_utils.h", "../browser/ui/tabs/pinned_tab_test_utils.cc", "../browser/ui/tabs/pinned_tab_test_utils.h", + "../browser/ui/test/test_browser_ui.cc", + "../browser/ui/test/test_browser_ui.h", "../test/base/browser_with_test_window_test.cc", "../test/base/browser_with_test_window_test.h", "base/dialog_test_browser_window.cc", @@ -1985,6 +1988,7 @@ "../browser/spellchecker/spellcheck_service_browsertest.cc", "../browser/ssl/certificate_reporting_test_utils.cc", "../browser/ssl/certificate_reporting_test_utils.h", + "../browser/ssl/certificate_transparency_browsertest.cc", "../browser/ssl/chrome_expect_ct_reporter_browsertest.cc", "../browser/ssl/connection_help_tab_helper_browsertest.cc", "../browser/ssl/crlset_browsertest.cc", @@ -2110,8 +2114,6 @@ "../browser/ui/test/browser_ui_browsertest.cc", "../browser/ui/test/test_browser_dialog.cc", "../browser/ui/test/test_browser_dialog.h", - "../browser/ui/test/test_browser_ui.cc", - "../browser/ui/test/test_browser_ui.h", "../browser/ui/test/test_infobar.cc", "../browser/ui/test/test_infobar.h", "../browser/ui/thumbnails/thumbnail_readiness_tracker_browsertest.cc", @@ -5488,6 +5490,7 @@ "../browser/download/download_shelf_context_menu_unittest.cc", "../browser/enterprise/signals/client_certificate_fetcher_unittest.cc", "../browser/metrics/power/power_metrics_reporter_unittest.cc", + "../browser/metrics/power/power_metrics_unittest.cc", "../browser/metrics/power/usage_scenario_unittest.cc", "../browser/metrics/usage_scenario/system_event_provider_unittest.cc", "../browser/metrics/usage_scenario/tab_usage_scenario_tracker_unittest.cc", @@ -7907,6 +7910,7 @@ "//components/safe_browsing/content/browser:safe_browsing_blocking_page", "//components/safe_browsing/content/common:file_type_policies", "//components/safe_browsing/content/common:file_type_policies_test_support", + "//components/safe_browsing/core/browser:token_fetcher", ] } @@ -8960,8 +8964,6 @@ "../browser/ui/startup/startup_browser_creator_interactive_uitest.cc", "../browser/ui/test/test_browser_dialog.cc", "../browser/ui/test/test_browser_dialog.h", - "../browser/ui/test/test_browser_ui.cc", - "../browser/ui/test/test_browser_ui.h", "../browser/ui/thumbnails/thumbnail_tab_helper_interactive_uitest.cc", "../browser/ui/translate/translate_bubble_test_utils.h", "../browser/ui/views/accessibility/caption_bubble_controller_views_browsertest.cc",
diff --git a/chrome/test/android/BUILD.gn b/chrome/test/android/BUILD.gn index 3da168a..3666013 100644 --- a/chrome/test/android/BUILD.gn +++ b/chrome/test/android/BUILD.gn
@@ -46,7 +46,6 @@ "//third_party/android_deps:guava_android_java", "//third_party/android_support_test_runner:runner_java", "//third_party/androidx:androidx_annotation_annotation_java", - "//third_party/androidx:androidx_drawerlayout_drawerlayout_java", "//third_party/androidx:androidx_test_uiautomator_uiautomator_java", "//third_party/junit", "//third_party/ub-uiautomator:ub_uiautomator_java", @@ -110,7 +109,6 @@ "//third_party/android_deps:espresso_java", "//third_party/android_deps:guava_android_java", "//third_party/android_support_test_runner:runner_java", - "//third_party/androidx:androidx_recyclerview_recyclerview_java", "//third_party/androidx:androidx_test_runner_java", "//third_party/hamcrest:hamcrest_java", "//third_party/junit", @@ -150,7 +148,6 @@ "//third_party/android_deps:guava_android_java", "//third_party/android_support_test_runner:runner_java", "//third_party/androidx:androidx_annotation_annotation_java", - "//third_party/androidx:androidx_recyclerview_recyclerview_java", "//third_party/androidx:androidx_test_runner_java", "//third_party/hamcrest:hamcrest_java", "//third_party/junit", @@ -363,7 +360,6 @@ "//net/android:net_java", "//net/android:net_java_test_support", "//services/device/public/mojom:mojom_java", - "//third_party/android_deps:android_support_v7_appcompat_java", "//third_party/android_deps:chromium_play_services_availability_java", "//third_party/android_deps:com_google_code_findbugs_jsr305_java", "//third_party/android_deps:espresso_java", @@ -373,9 +369,9 @@ "//third_party/android_support_test_runner:runner_java", "//third_party/androidx:androidx_annotation_annotation_java", "//third_party/androidx:androidx_appcompat_appcompat_java", + "//third_party/androidx:androidx_appcompat_appcompat_resources_java", "//third_party/androidx:androidx_core_core_java", "//third_party/androidx:androidx_fragment_fragment_java", - "//third_party/androidx:androidx_lifecycle_lifecycle_common_java", "//third_party/androidx:androidx_recyclerview_recyclerview_java", "//third_party/blink/public:blink_headers_java", "//third_party/blink/public/mojom:mojom_platform_java",
diff --git a/chrome/test/data/web_apps/site_b/basic.json b/chrome/test/data/web_apps/site_b/basic.json index e205f5dc..36a63d10 100644 --- a/chrome/test/data/web_apps/site_b/basic.json +++ b/chrome/test/data/web_apps/site_b/basic.json
@@ -14,5 +14,21 @@ ], "start_url": "/web_apps/site_b/basic.html", "scope": "/web_apps/site_b/", - "display": "minimal-ui" + "display": "minimal-ui", + "file_handlers": [ + { + "action": "/web_apps/site_b/text_handler.html", + "name": "Plain Text", + "accept": { + "text/plain": [".txt", ".md", ".csv", ".text"] + } + }, + { + "action": "/web_apps/site_b/image_handler.html", + "accept": { + "image/png": [".png"] + }, + "launch_type": "multiple-clients" + } + ] }
diff --git a/chrome/test/data/web_apps/site_b/image_handler.html b/chrome/test/data/web_apps/site_b/image_handler.html new file mode 100644 index 0000000..acdf8a9 --- /dev/null +++ b/chrome/test/data/web_apps/site_b/image_handler.html
@@ -0,0 +1,20 @@ +<!DOCTYPE html> +<html> +<head> + <title>Site B - Image Handler</title> + <script src="/web_apps/test_utils.js"></script> +</head> +<body> + <h1>Site B - Image Handler</h1> + <div> + <p> + TODO: Add code to verify the images loaded are correct. + </p> + <p> + This site is used for dPWA integration tests, and is subject to modification to support that framework. See + <a + href="https://chromium.googlesource.com/chromium/src/+/main/docs/webapps/integration-testing-framework.md">https://chromium.googlesource.com/chromium/src/+/main/docs/webapps/integration-testing-framework.md</a> + </p> + </div> +</body> +</html>
diff --git a/chrome/test/data/web_apps/site_b/text_handler.html b/chrome/test/data/web_apps/site_b/text_handler.html new file mode 100644 index 0000000..4fac732 --- /dev/null +++ b/chrome/test/data/web_apps/site_b/text_handler.html
@@ -0,0 +1,20 @@ +<!DOCTYPE html> +<html> +<head> + <title>Site B - Text Handler</title> + <script src="/web_apps/test_utils.js"></script> +</head> +<body> + <h1>Site B - Text Handler</h1> + <div> + <p> + TODO: Add code to verify the text files loaded are correct. + </p> + <p> + This site is used for dPWA integration tests, and is subject to modification to support that framework. See + <a + href="https://chromium.googlesource.com/chromium/src/+/main/docs/webapps/integration-testing-framework.md">https://chromium.googlesource.com/chromium/src/+/main/docs/webapps/integration-testing-framework.md</a> + </p> + </div> +</body> +</html>
diff --git a/chrome/test/data/webui/chromeos/personalization_app/personalization_theme_element_test.ts b/chrome/test/data/webui/chromeos/personalization_app/personalization_theme_element_test.ts index 6ba1f14..b84c2894 100644 --- a/chrome/test/data/webui/chromeos/personalization_app/personalization_theme_element_test.ts +++ b/chrome/test/data/webui/chromeos/personalization_app/personalization_theme_element_test.ts
@@ -97,7 +97,7 @@ personalizationStore.setReducersEnabled(true); personalizationStore.expectAction(ThemeActionName.SET_DARK_MODE_ENABLED); radioButton.click(); - let action = + const action = await personalizationStore.waitForAction( ThemeActionName.SET_DARK_MODE_ENABLED) as SetDarkModeEnabledAction; assertTrue(action.enabled); @@ -120,8 +120,8 @@ personalizationStore.expectAction( ThemeActionName.SET_COLOR_MODE_AUTO_SCHEDULE_ENABLED); radioButton.click(); - let action = await personalizationStore.waitForAction( - ThemeActionName.SET_COLOR_MODE_AUTO_SCHEDULE_ENABLED) as + const action = await personalizationStore.waitForAction( + ThemeActionName.SET_COLOR_MODE_AUTO_SCHEDULE_ENABLED) as SetDarkModeEnabledAction; assertTrue(action.enabled); assertTrue(personalizationStore.data.theme.colorModeAutoScheduleEnabled);
diff --git a/chrome/test/data/webui/chromeos/personalization_app/personalization_toast_element_test.ts b/chrome/test/data/webui/chromeos/personalization_app/personalization_toast_element_test.ts index 83e9a2553..53b74f5d 100644 --- a/chrome/test/data/webui/chromeos/personalization_app/personalization_toast_element_test.ts +++ b/chrome/test/data/webui/chromeos/personalization_app/personalization_toast_element_test.ts
@@ -86,8 +86,8 @@ test('automatically dismisses after ten seconds', async () => { // Spy on calls to |window.setTimeout|. - let setTimeout = window.setTimeout; - let setTimeoutCalls: {handler: Function|string, delay?: number}[] = []; + const setTimeout = window.setTimeout; + const setTimeoutCalls: {handler: Function|string, delay?: number}[] = []; window.setTimeout = (handler: Function|string, delay?: number, ...args: any[]): number => { setTimeoutCalls.push({handler, delay}); @@ -100,7 +100,7 @@ await waitAfterNextRender(personalizationToastElement); // Expect that a timeout will have been scheduled for 10 seconds. - let setTimeoutCall: {handler: Function|string, delay?: number}|undefined = + const setTimeoutCall: {handler: Function|string, delay?: number}|undefined = setTimeoutCalls.find((setTimeoutCall) => { return typeof setTimeoutCall.handler === 'function' && setTimeoutCall.delay === 10000;
diff --git a/chrome/test/data/webui/chromeos/personalization_app/wallpaper_collections_element_test.ts b/chrome/test/data/webui/chromeos/personalization_app/wallpaper_collections_element_test.ts index 83eb855..470806b9 100644 --- a/chrome/test/data/webui/chromeos/personalization_app/wallpaper_collections_element_test.ts +++ b/chrome/test/data/webui/chromeos/personalization_app/wallpaper_collections_element_test.ts
@@ -273,7 +273,7 @@ personalizationStore.notifyObservers(); // Wait for |sendCollections| to be called. - let [target, data] = await testProxy.whenCalled('sendCollections') as + const [target, data] = await testProxy.whenCalled('sendCollections') as Parameters<IFrameApi['sendCollections']>; await waitAfterNextRender(wallpaperCollectionsElement); @@ -286,7 +286,7 @@ assertEquals(null, data); // Wait for |sendLocalImages| to be called. - let [imageTarget, imageData] = + const [imageTarget, imageData] = await testProxy.whenCalled('sendLocalImages') as Parameters<IFrameApi['sendLocalImages']>; await waitAfterNextRender(wallpaperCollectionsElement);
diff --git a/chrome/test/data/webui/chromeos/personalization_app/wallpaper_selected_element_test.ts b/chrome/test/data/webui/chromeos/personalization_app/wallpaper_selected_element_test.ts index 70ffbce2..117f856 100644 --- a/chrome/test/data/webui/chromeos/personalization_app/wallpaper_selected_element_test.ts +++ b/chrome/test/data/webui/chromeos/personalization_app/wallpaper_selected_element_test.ts
@@ -7,7 +7,7 @@ import 'chrome://personalization/strings.m.js'; import 'chrome://webui-test/mojo_webui_test_support.js'; -import {Paths, WallpaperLayout, WallpaperSelected, WallpaperType} from 'chrome://personalization/trusted/personalization_app.js'; +import {CurrentWallpaper, Paths, WallpaperLayout, WallpaperSelected, WallpaperType} from 'chrome://personalization/trusted/personalization_app.js'; import {assertDeepEquals, assertEquals, assertFalse, assertNotEquals, assertTrue} from 'chrome://webui-test/chai_assert.js'; import {flushTasks, waitAfterNextRender} from 'chrome://webui-test/test_util.js'; @@ -294,4 +294,25 @@ await wallpaperProvider.whenCalled('setCurrentWallpaperLayout'), WallpaperLayout.kCenter); }); + + test('shows attribution for device default wallpaper', async () => { + const currentSelected: CurrentWallpaper = { + url: {url: 'url'}, + attribution: ['testing attribution'], + layout: WallpaperLayout.kStretch, + type: WallpaperType.kDefault, + key: 'key', + }; + personalizationStore.data.wallpaper.currentSelected = currentSelected; + + wallpaperSelectedElement = + initElement(WallpaperSelected, {path: Paths.CollectionImages}); + await waitAfterNextRender(wallpaperSelectedElement); + + assertEquals( + wallpaperSelectedElement.i18n('defaultWallpaper'), + wallpaperSelectedElement.shadowRoot!.getElementById( + 'imageTitle')!.innerText, + 'default wallpaper attribution is shown'); + }); });
diff --git a/chrome/test/data/webui/chromeos/shimless_rma/onboarding_enter_rsu_wp_disable_code_page_test.js b/chrome/test/data/webui/chromeos/shimless_rma/onboarding_enter_rsu_wp_disable_code_page_test.js index 9427a6e..f751e68 100644 --- a/chrome/test/data/webui/chromeos/shimless_rma/onboarding_enter_rsu_wp_disable_code_page_test.js +++ b/chrome/test/data/webui/chromeos/shimless_rma/onboarding_enter_rsu_wp_disable_code_page_test.js
@@ -64,6 +64,17 @@ return flushTasks(); } + /** + * @param {string} inputSelector + * @return {!Promise} + */ + function pressEnter(inputSelector) { + const rsuCodeInput = component.shadowRoot.querySelector(inputSelector); + rsuCodeInput.value = '12345678'; + rsuCodeInput.dispatchEvent(new KeyboardEvent('keydown', {key: 'Enter'})); + return flushTasks(); + } + test('EnterRsuWpDisableCodePageInitializes', async () => { await initializeEnterRsuWpDisableCodePage('rsu challenge', ''); const rsuCodeComponent = component.shadowRoot.querySelector('#rsuCode'); @@ -164,4 +175,17 @@ await flushTasks(); assertFalse(rsuCodeInput.invalid); }); + + test('EnterRsuWpDisableCodePagePressEnterkey', async () => { + await initializeEnterRsuWpDisableCodePage( + /*challenge=*/ '', /*hwid=*/ ''); + + let nextButtonEventFired = false; + component.addEventListener('click-next-button', (e) => { + nextButtonEventFired = true; + }); + await pressEnter('#rsuCode'); + + assertTrue(nextButtonEventFired); + }); }
diff --git a/chrome/test/data/webui/color_provider_css_colors_test.ts b/chrome/test/data/webui/color_provider_css_colors_test.ts index 8cbbda59..acc3f51 100644 --- a/chrome/test/data/webui/color_provider_css_colors_test.ts +++ b/chrome/test/data/webui/color_provider_css_colors_test.ts
@@ -12,7 +12,7 @@ link.rel = 'stylesheet'; link.href = 'chrome://theme/colors.css'; link.onload = function() { - let style = getComputedStyle(document.body); + const style = getComputedStyle(document.body); // Check that we are able to query for a ui/ side color. assertNotEquals('', style.getPropertyValue('--color-accent')); // Check that we are able to query for a chrome/ side color.
diff --git a/chrome/test/data/webui/extensions/activity_log_stream_test.ts b/chrome/test/data/webui/extensions/activity_log_stream_test.ts index 5066d10..d79fc31 100644 --- a/chrome/test/data/webui/extensions/activity_log_stream_test.ts +++ b/chrome/test/data/webui/extensions/activity_log_stream_test.ts
@@ -184,7 +184,7 @@ proxyDelegate.getOnExtensionActivity().callListeners(contentScriptActivity); flush(); - let streamItems = getStreamItems(); + const streamItems = getStreamItems(); assertEquals(2, streamItems.length); // We should see two items: one for every script called.
diff --git a/chrome/test/data/webui/extensions/code_section_test.ts b/chrome/test/data/webui/extensions/code_section_test.ts index 7d8195f..49dfc551 100644 --- a/chrome/test/data/webui/extensions/code_section_test.ts +++ b/chrome/test/data/webui/extensions/code_section_test.ts
@@ -56,7 +56,7 @@ assertTrue(testIsVisible('#main')); assertFalse(testIsVisible('#no-code')); - let codeSections = + const codeSections = codeSection.shadowRoot!.querySelectorAll('#source span span'); assertEquals(code.beforeHighlight, codeSections[0]!.textContent);
diff --git a/chrome/test/data/webui/extensions/detail_view_test.ts b/chrome/test/data/webui/extensions/detail_view_test.ts index fdb6ecb..f02a58b 100644 --- a/chrome/test/data/webui/extensions/detail_view_test.ts +++ b/chrome/test/data/webui/extensions/detail_view_test.ts
@@ -80,7 +80,7 @@ ]; const isChecked = (id: string) => item.shadowRoot!.querySelector<CrCheckboxElement>(id)!.checked; - for (let option of accessOptions) { + for (const option of accessOptions) { assertTrue(isChildVisible(item, option.id)); assertFalse(isChecked(option.id), option.id); item.set('data.' + option.key + '.isEnabled', false);
diff --git a/chrome/test/data/webui/extensions/error_console_test.ts b/chrome/test/data/webui/extensions/error_console_test.ts index 5128591..4425d68 100644 --- a/chrome/test/data/webui/extensions/error_console_test.ts +++ b/chrome/test/data/webui/extensions/error_console_test.ts
@@ -29,7 +29,7 @@ }); test('TestUpDownErrors', function() { - let initialFocus = findMatches(document, ACTIVE_ERROR_IN_STACK)[0]; + const initialFocus = findMatches(document, ACTIVE_ERROR_IN_STACK)[0]; assertTrue(!!initialFocus); assertEquals(1, findMatches(document, ACTIVE_ERROR_IN_STACK).length); assertEquals(4, findMatches(document, STACK_ERRORS).length);
diff --git a/chrome/test/data/webui/extensions/extension_options_dialog_test.ts b/chrome/test/data/webui/extensions/extension_options_dialog_test.ts index fc1720b..72db580 100644 --- a/chrome/test/data/webui/extensions/extension_options_dialog_test.ts +++ b/chrome/test/data/webui/extensions/extension_options_dialog_test.ts
@@ -35,7 +35,7 @@ const dialog = manager.shadowRoot!.querySelector('extensions-options-dialog'); assertTrue(!!dialog); - let waitForClose = eventToPromise('close', dialog); + const waitForClose = eventToPromise('close', dialog); dialog.$.dialog.cancel(); await waitForClose; const activeElement = getDeepActiveElement();
diff --git a/chrome/test/data/webui/extensions/item_test.ts b/chrome/test/data/webui/extensions/item_test.ts index a3359d5..4e1c83147 100644 --- a/chrome/test/data/webui/extensions/item_test.ts +++ b/chrome/test/data/webui/extensions/item_test.ts
@@ -397,7 +397,7 @@ }); test(assert(extension_item_tests.TestNames.HtmlInName), function() { - let name = '<HTML> in the name!'; + const name = '<HTML> in the name!'; item.set('data.name', name); flush(); assertEquals(name, item.$.name.textContent!.trim());
diff --git a/chrome/test/data/webui/extensions/manager_unit_test.ts b/chrome/test/data/webui/extensions/manager_unit_test.ts index 68dcb885..ca3e22ee 100644 --- a/chrome/test/data/webui/extensions/manager_unit_test.ts +++ b/chrome/test/data/webui/extensions/manager_unit_test.ts
@@ -101,7 +101,7 @@ assertEquals(alphaFromStore.id, getExtension(1).id); // Extensions from the same location are sorted by name. - let gammaUnpacked = createExtensionInfo({ + const gammaUnpacked = createExtensionInfo({ location: chrome.developerPrivate.Location.UNPACKED, name: 'Gamma', id: 'c'.repeat(32) @@ -181,7 +181,7 @@ manager.shadowRoot!.querySelector('extensions-detail-view'); assertTrue(!!detailsView); - let extensionCopy = Object.assign({}, extension); + const extensionCopy = Object.assign({}, extension); extensionCopy.description = newDescription; service.itemStateChangedTarget.callListeners({ event_type: chrome.developerPrivate.EventType.PREFS_CHANGED, @@ -189,7 +189,7 @@ }); // Updating a different extension shouldn't have any impact. - let secondExtensionCopy = Object.assign({}, secondExtension); + const secondExtensionCopy = Object.assign({}, secondExtension); secondExtensionCopy.description = 'something else'; service.itemStateChangedTarget.callListeners({ event_type: chrome.developerPrivate.EventType.PREFS_CHANGED,
diff --git a/chrome/test/data/webui/extensions/navigation_helper_test.ts b/chrome/test/data/webui/extensions/navigation_helper_test.ts index 9bf1d875..d2dd120 100644 --- a/chrome/test/data/webui/extensions/navigation_helper_test.ts +++ b/chrome/test/data/webui/extensions/navigation_helper_test.ts
@@ -117,16 +117,16 @@ }; // Test url -> state. - for (let key in stateUrlPairs) { - let entry = stateUrlPairs[key]; + for (const key in stateUrlPairs) { + const entry = stateUrlPairs[key]; assertTrue(!!entry); history.pushState({}, '', entry.url); assertDeepEquals(entry.state, navigationHelper.getCurrentPage(), key); } // Test state -> url. - for (let key in stateUrlPairs) { - let entry = stateUrlPairs[key]; + for (const key in stateUrlPairs) { + const entry = stateUrlPairs[key]; assertTrue(!!entry); navigationHelper.updateHistory(entry.state, false); assertEquals(entry.url, location.href, key);
diff --git a/chrome/test/data/webui/extensions/runtime_host_permissions_test.ts b/chrome/test/data/webui/extensions/runtime_host_permissions_test.ts index 569d195..682e264 100644 --- a/chrome/test/data/webui/extensions/runtime_host_permissions_test.ts +++ b/chrome/test/data/webui/extensions/runtime_host_permissions_test.ts
@@ -202,7 +202,7 @@ // Canceling the dialog should reset the selectHostAccess value to ON_CLICK, // since no host was added. assertTrue(dialog.isOpen()); - let whenClosed = eventToPromise('close', dialog); + const whenClosed = eventToPromise('close', dialog); dialog.shadowRoot!.querySelector<HTMLElement>('.cancel-button')!.click(); await whenClosed; @@ -265,7 +265,7 @@ // Closing the dialog (as opposed to canceling) should keep the // selectHostAccess value at ON_SPECIFIC_SITES. assertTrue(dialog.isOpen()); - let whenClosed = eventToPromise('close', dialog); + const whenClosed = eventToPromise('close', dialog); dialog.$.submit.click(); return whenClosed.then(() => { flush();
diff --git a/chrome/test/data/webui/extensions/runtime_hosts_dialog_test.ts b/chrome/test/data/webui/extensions/runtime_hosts_dialog_test.ts index 399f38e..e417b19b 100644 --- a/chrome/test/data/webui/extensions/runtime_hosts_dialog_test.ts +++ b/chrome/test/data/webui/extensions/runtime_hosts_dialog_test.ts
@@ -59,8 +59,8 @@ assertFalse(submit.disabled); submit.click(); return delegate.whenCalled('addRuntimeHostPermission').then((args) => { - let id = args[0]; - let input = args[1]; + const id = args[0]; + const input = args[1]; assertEquals(ITEM_ID, id); assertEquals('http://www.example.com/*', input); }); @@ -171,8 +171,8 @@ assertFalse(submit.disabled); submit.click(); return delegate.whenCalled('setItemHostAccess').then((args) => { - let id = args[0]; - let access = args[1]; + const id = args[0]; + const access = args[1]; assertEquals(ITEM_ID, id); assertEquals( chrome.developerPrivate.HostAccess.ON_SPECIFIC_SITES, access); @@ -249,11 +249,11 @@ assertFalse(submit.disabled); submit.click(); - let [id, host] = await delegate.whenCalled('addRuntimeHostPermission'); + const [id, host] = await delegate.whenCalled('addRuntimeHostPermission'); assertEquals(ITEM_ID, id); assertEquals('http://*.restricted.com/*', host); - let [siteSet, removedSites] = + const [siteSet, removedSites] = await delegate.whenCalled('removeUserSpecifiedSites'); assertEquals(chrome.developerPrivate.UserSiteSet.RESTRICTED, siteSet); assertDeepEquals(
diff --git a/chrome/test/data/webui/extensions/test_util.ts b/chrome/test/data/webui/extensions/test_util.ts index 7ed0fba..5d95683 100644 --- a/chrome/test/data/webui/extensions/test_util.ts +++ b/chrome/test/data/webui/extensions/test_util.ts
@@ -221,11 +221,11 @@ */ export function findMatches( root: HTMLElement|Document, query: string): HTMLElement[] { - let elements = new Set<HTMLElement>(); + const elements = new Set<HTMLElement>(); function doSearch(node: Node) { if (node.nodeType === Node.ELEMENT_NODE) { const matches = (node as Element).querySelectorAll<HTMLElement>(query); - for (let match of matches) { + for (const match of matches) { elements.add(match); } }
diff --git a/chrome/test/data/webui/metrics_reporter/metrics_reporter_test.ts b/chrome/test/data/webui/metrics_reporter/metrics_reporter_test.ts index 506dec27..9958fd23 100644 --- a/chrome/test/data/webui/metrics_reporter/metrics_reporter_test.ts +++ b/chrome/test/data/webui/metrics_reporter/metrics_reporter_test.ts
@@ -15,7 +15,7 @@ let now: bigint; let callbackRouter: PageMetricsCallbackRouter; - let apiProxy = TestBrowserProxy.fromClass(BrowserProxyImpl); + const apiProxy = TestBrowserProxy.fromClass(BrowserProxyImpl); let metricsReporter: MetricsReporter; function forwardTime() {
diff --git a/chrome/test/data/webui/new_tab_page/app_test.ts b/chrome/test/data/webui/new_tab_page/app_test.ts index 5d260ab..ffa269a2 100644 --- a/chrome/test/data/webui/new_tab_page/app_test.ts +++ b/chrome/test/data/webui/new_tab_page/app_test.ts
@@ -28,7 +28,7 @@ let backgroundManager: TestBrowserProxy; let moduleResolver: PromiseResolver<Module[]>; - let url: URL = new URL(location.href); + const url: URL = new URL(location.href); setup(async () => { document.body.innerHTML = '';
diff --git a/chrome/test/data/webui/new_tab_page/modules/cart_v2/module_test.ts b/chrome/test/data/webui/new_tab_page/modules/cart_v2/module_test.ts index dcbbdd8b..1a33609 100644 --- a/chrome/test/data/webui/new_tab_page/modules/cart_v2/module_test.ts +++ b/chrome/test/data/webui/new_tab_page/modules/cart_v2/module_test.ts
@@ -752,7 +752,7 @@ // Act. let waitForLeftScrollEnableChange = eventToPromise('left-scroll-hide', moduleElement); - let waitForRightScrollEnableChange = + const waitForRightScrollEnableChange = eventToPromise('right-scroll-show', moduleElement); await waitForLeftScrollEnableChange; await waitForRightScrollEnableChange;
diff --git a/chrome/test/data/webui/new_tab_page/modules/modules_test.ts b/chrome/test/data/webui/new_tab_page/modules/modules_test.ts index 489c27c..1174826 100644 --- a/chrome/test/data/webui/new_tab_page/modules/modules_test.ts +++ b/chrome/test/data/webui/new_tab_page/modules/modules_test.ts
@@ -245,7 +245,7 @@ // Arrange. const moduleArray = []; for (let i = 0; i < 4; ++i) { - let module = createElement(); + const module = createElement(); moduleArray.push(module); } const fooDescriptor = new ModuleDescriptorV2( @@ -314,7 +314,7 @@ let restoreCalled = false; const moduleArray = []; for (let i = 0; i < 3; ++i) { - let module = createElement(); + const module = createElement(); moduleArray.push(module); } const fooDescriptor = new ModuleDescriptorV2( @@ -662,7 +662,7 @@ // Arrange. const moduleArray = []; for (let i = 0; i < 3; ++i) { - let module = createElement(); + const module = createElement(); moduleArray.push(module); } const fooDescriptor = new ModuleDescriptorV2( @@ -825,5 +825,90 @@ assertEquals(secondPositionRect.x, firstModule.getBoundingClientRect().x); assertEquals(secondPositionRect.y, firstModule.getBoundingClientRect().y); }); + + test('drag tall module over short module sibling container', async () => { + // Arrange. + const moduleArray = []; + for (let i = 0; i < 3; ++i) { + const module = createElement(); + moduleArray.push(module); + } + const fooDescriptor = new ModuleDescriptorV2( + 'foo', 'Foo', ModuleHeight.TALL, async () => createElement()); + const barDescriptor = new ModuleDescriptorV2( + 'bar', 'Bar', ModuleHeight.SHORT, async () => createElement()); + const fooBarDescriptor = new ModuleDescriptorV2( + 'foo bar', 'Foo Baz', ModuleHeight.SHORT, + async () => createElement()); + + moduleRegistry.setResultFor( + 'getDescriptors', [fooDescriptor, barDescriptor, fooBarDescriptor]); + const modulesElement = await createModulesElement([ + { + descriptor: fooDescriptor, + element: moduleArray[0]!, + }, + { + descriptor: barDescriptor, + element: moduleArray[1]!, + }, + { + descriptor: fooBarDescriptor, + element: moduleArray[2]!, + }, + ]); + callbackRouterRemote.setDisabledModules(false, []); + await callbackRouterRemote.$.flushForTesting(); + + let moduleWrappers = Array.from( + modulesElement.shadowRoot!.querySelectorAll('ntp-module-wrapper')); + const tallModule = moduleWrappers[0]; + const shortModule1 = moduleWrappers[1]; + const shortModule2 = moduleWrappers[2]; + assertTrue(!!tallModule); + assertTrue(!!shortModule1); + assertTrue(!!shortModule2); + assertStyle(tallModule, 'cursor', 'grab'); + assertStyle(shortModule1, 'cursor', 'grab'); + assertStyle(shortModule2, 'cursor', 'grab'); + + // Act. + tallModule.dispatchEvent(new MouseEvent('mousedown')); + document.dispatchEvent(new MouseEvent('mousemove')); + + // Act. + shortModule1.dispatchEvent(new MouseEvent('mouseover')); + + // Assert. + moduleWrappers = Array.from( + modulesElement.shadowRoot!.querySelectorAll('ntp-module-wrapper')); + assertEquals(0, moduleWrappers.indexOf(shortModule1)); + assertEquals(1, moduleWrappers.indexOf(shortModule2)); + assertEquals(2, moduleWrappers.indexOf(tallModule)); + + // Act. + shortModule2.dispatchEvent(new MouseEvent('mouseover')); + + // Assert. + moduleWrappers = Array.from( + modulesElement.shadowRoot!.querySelectorAll('ntp-module-wrapper')); + assertEquals(0, moduleWrappers.indexOf(tallModule)); + assertEquals(1, moduleWrappers.indexOf(shortModule1)); + assertEquals(2, moduleWrappers.indexOf(shortModule2)); + + // Act. + shortModule1.dispatchEvent(new MouseEvent('mousedown')); + document.dispatchEvent(new MouseEvent('mousemove')); + + // Act. + tallModule.dispatchEvent(new MouseEvent('mouseover')); + + // Assert. + moduleWrappers = Array.from( + modulesElement.shadowRoot!.querySelectorAll('ntp-module-wrapper')); + assertEquals(0, moduleWrappers.indexOf(shortModule1)); + assertEquals(1, moduleWrappers.indexOf(tallModule)); + assertEquals(2, moduleWrappers.indexOf(shortModule2)); + }); }); });
diff --git a/chrome/test/data/webui/new_tab_page/realbox/realbox_test.ts b/chrome/test/data/webui/new_tab_page/realbox/realbox_test.ts index 2822da6..a0c6a540 100644 --- a/chrome/test/data/webui/new_tab_page/realbox/realbox_test.ts +++ b/chrome/test/data/webui/new_tab_page/realbox/realbox_test.ts
@@ -490,8 +490,8 @@ assertTrue(matchEls[0]!.classList.contains(Classes.SELECTED)); assertEquals(' hello world', realbox.$.input.value); - let start = realbox.$.input.selectionStart!; - let end = realbox.$.input.selectionEnd!; + const start = realbox.$.input.selectionStart!; + const end = realbox.$.input.selectionEnd!; assertEquals('', realbox.$.input.value.substring(start, end)); }); @@ -519,7 +519,7 @@ assertTrue(areMatchesShowing()); - let matchEls = + const matchEls = realbox.$.matches.shadowRoot!.querySelectorAll('ntp-realbox-match'); assertEquals(1, matchEls.length); verifyMatch(matches[0]!, matchEls[0]!); @@ -690,8 +690,8 @@ await testProxy.callbackRouterRemote.$.flushForTesting(); assertEquals('hello world', realbox.$.input.value); - let start = realbox.$.input.selectionStart!; - let end = realbox.$.input.selectionEnd!; + const start = realbox.$.input.selectionStart!; + const end = realbox.$.input.selectionEnd!; assertEquals('world', realbox.$.input.value.substring(start, end)); // Select the entire input. @@ -722,8 +722,8 @@ await testProxy.callbackRouterRemote.$.flushForTesting(); assertEquals('helloworld.com', realbox.$.input.value); - let start = realbox.$.input.selectionStart!; - let end = realbox.$.input.selectionEnd!; + const start = realbox.$.input.selectionStart!; + const end = realbox.$.input.selectionEnd!; assertEquals('world.com', realbox.$.input.value.substring(start, end)); const copyEvent = createClipboardEvent('copy'); @@ -1227,7 +1227,7 @@ assertEquals(2, matchEls.length); // Select the second match. - let arrowUpEvent = new KeyboardEvent('keydown', { + const arrowUpEvent = new KeyboardEvent('keydown', { bubbles: true, cancelable: true, composed: true, // So it propagates across shadow DOM boundary. @@ -1429,7 +1429,7 @@ // First match is not selected. assertFalse(matchEls[0]!.classList.contains(Classes.SELECTED)); - let arrowDownEvent = new KeyboardEvent('keydown', { + const arrowDownEvent = new KeyboardEvent('keydown', { bubbles: true, cancelable: true, composed: true, // So it propagates across shadow DOM boundary. @@ -1590,7 +1590,7 @@ await testProxy.callbackRouterRemote.$.flushForTesting(); assertTrue(areMatchesShowing()); - let matchEls = + const matchEls = realbox.$.matches.shadowRoot!.querySelectorAll('ntp-realbox-match'); assertEquals(2, matchEls.length); @@ -1692,13 +1692,13 @@ await testProxy.callbackRouterRemote.$.flushForTesting(); assertTrue(areMatchesShowing()); - let matchEls = + const matchEls = realbox.$.matches.shadowRoot!.querySelectorAll('ntp-realbox-match'); - let focusIndicator = matchEls[0]!.$['focus-indicator']; + const focusIndicator = matchEls[0]!.$['focus-indicator']; // Select the first match - let arrowDownEvent = new KeyboardEvent('keydown', { + const arrowDownEvent = new KeyboardEvent('keydown', { bubbles: true, cancelable: true, composed: true, // So it propagates across shadow DOM boundary. @@ -1778,8 +1778,8 @@ testProxy.handler.reset(); assertEquals('hello', realbox.$.input.value); - let start = realbox.$.input.selectionStart!; - let end = realbox.$.input.selectionEnd!; + const start = realbox.$.input.selectionStart!; + const end = realbox.$.input.selectionEnd!; assertEquals('ello', realbox.$.input.value.substring(start, end)); // Type the next character of the inline autocompletion. @@ -1842,7 +1842,7 @@ await testProxy.callbackRouterRemote.$.flushForTesting(); assertTrue(areMatchesShowing()); - let matchEls = + const matchEls = realbox.$.matches.shadowRoot!.querySelectorAll('ntp-realbox-match'); assertEquals(2, matchEls.length); assertIconMaskImageUrl(matchEls[0]!.$.icon, 'clock.svg'); @@ -1906,7 +1906,7 @@ assertBackgroundImageDataUrl(realbox.$.icon, faviconData); // Select the first match by pressing 'Escape'. - let escapeEvent = new KeyboardEvent('keydown', { + const escapeEvent = new KeyboardEvent('keydown', { bubbles: true, cancelable: true, composed: true, // So it propagates across shadow DOM boundary. @@ -1943,7 +1943,7 @@ // Select the entire input. realbox.$.input.setSelectionRange(0, realbox.$.input.value.length); - let cutEvent = createClipboardEvent('cut'); + const cutEvent = createClipboardEvent('cut'); realbox.$.input.dispatchEvent(cutEvent); assertTrue(cutEvent.defaultPrevented); @@ -1974,7 +1974,7 @@ await testProxy.callbackRouterRemote.$.flushForTesting(); assertTrue(areMatchesShowing()); - let matchEls = + const matchEls = realbox.$.matches.shadowRoot!.querySelectorAll('ntp-realbox-match'); assertEquals(2, matchEls.length); assertIconMaskImageUrl(matchEls[0]!.$.icon, 'page.svg'); @@ -2046,7 +2046,7 @@ assertTrue(window.getComputedStyle(realbox.$.icon).display !== 'none'); // Select the first match by pressing 'Escape'. - let escapeEvent = new KeyboardEvent('keydown', { + const escapeEvent = new KeyboardEvent('keydown', { bubbles: true, cancelable: true, composed: true, // So it propagates across shadow DOM boundary. @@ -2243,7 +2243,7 @@ await testProxy.callbackRouterRemote.$.flushForTesting(); assertTrue(areMatchesShowing()); - let matchEls = + const matchEls = realbox.$.matches.shadowRoot!.querySelectorAll('ntp-realbox-match'); assertEquals(1, matchEls.length); @@ -2255,7 +2255,7 @@ assertEquals( window.getComputedStyle(matchEls[0]!.$.separator).display, 'none'); - let arrowDownEvent = new KeyboardEvent('keydown', { + const arrowDownEvent = new KeyboardEvent('keydown', { bubbles: true, cancelable: true, composed: true, // So it propagates across shadow DOM boundary. @@ -2291,7 +2291,7 @@ }); await testProxy.callbackRouterRemote.$.flushForTesting(); assertTrue(areMatchesShowing()); - let matchEls = + const matchEls = realbox.$.matches.shadowRoot!.querySelectorAll('ntp-realbox-match'); verifyMatch(matches[0]!, matchEls[0]!); @@ -2299,7 +2299,7 @@ assertEquals( window.getComputedStyle(matchEls[0]!.$.separator).display, 'none'); - let arrowDownEvent = new KeyboardEvent('keydown', { + const arrowDownEvent = new KeyboardEvent('keydown', { bubbles: true, cancelable: true, composed: true, // So it propagates across shadow DOM boundary. @@ -2336,7 +2336,7 @@ await testProxy.callbackRouterRemote.$.flushForTesting(); assertTrue(areMatchesShowing()); - let matchEl = $$(realbox.$.matches, 'ntp-realbox-match')!; + const matchEl = $$(realbox.$.matches, 'ntp-realbox-match')!; verifyMatch(matches[0]!, matchEl); const pedalEl = $$($$(matchEl, 'ntp-realbox-action')!, '.contents')!; @@ -2346,7 +2346,7 @@ 'chrome://theme/current-channel-logo'); // Default Pedal // Icon - let leftClick = new MouseEvent('click', { + const leftClick = new MouseEvent('click', { bubbles: true, button: 1, cancelable: true, @@ -2388,7 +2388,7 @@ await testProxy.callbackRouterRemote.$.flushForTesting(); assertTrue(areMatchesShowing()); - let matchEls = + const matchEls = realbox.$.matches.shadowRoot!.querySelectorAll('ntp-realbox-match'); verifyMatch(matches[0]!, matchEls[0]!); verifyMatch(matches[1]!, matchEls[1]!); @@ -2400,7 +2400,7 @@ 'chrome://theme/current-channel-logo'); // Default Pedal // Icon - let leftClick = new MouseEvent('click', { + const leftClick = new MouseEvent('click', { bubbles: true, button: 0, cancelable: true,
diff --git a/chrome/test/data/webui/settings/chromeos/multidevice_subpage_tests.js b/chrome/test/data/webui/settings/chromeos/multidevice_subpage_tests.js index 04a936af..0b0fedf 100644 --- a/chrome/test/data/webui/settings/chromeos/multidevice_subpage_tests.js +++ b/chrome/test/data/webui/settings/chromeos/multidevice_subpage_tests.js
@@ -825,5 +825,129 @@ assertFalse(!!multideviceSubpage.$$('#phoneHubNotificationsItem')); assertFalse(!!multideviceSubpage.$$('#phoneHubAppsItem')); assertTrue(!!multideviceSubpage.$$('#phoneHubCombinedSetupItem')); + + // Notifications, CameraRoll and Apps features are not grant, but + // Notifications is prohibited. Should show Notifications and combined + // settings. + multideviceSubpage.pageContentData = + Object.assign({}, multideviceSubpage.pageContentData, { + phoneHubCameraRollState: MultiDeviceFeatureState.DISABLED_BY_USER, + cameraRollAccessStatus: + PhoneHubFeatureAccessStatus.AVAILABLE_BUT_NOT_GRANTED, + phoneHubNotificationsState: + MultiDeviceFeatureState.PROHIBITED_BY_POLICY, + notificationAccessStatus: + PhoneHubFeatureAccessStatus.AVAILABLE_BUT_NOT_GRANTED, + phoneHubAppsState: MultiDeviceFeatureState.DISABLED_BY_USER, + isPhoneHubAppsAccessGranted: false + }); + + flush(); + + assertTrue(!!multideviceSubpage.$$('#phoneHubItem')); + assertFalse(!!multideviceSubpage.$$('#phoneHubCameraRollItem')); + assertTrue(!!multideviceSubpage.$$('#phoneHubNotificationsItem')); + assertFalse(!!multideviceSubpage.$$('#phoneHubAppsItem')); + assertTrue(!!multideviceSubpage.$$('#phoneHubCombinedSetupItem')); + + // Notifications, CameraRoll and Apps features are not grant, but + // cameraRoll is prohibited. Should show cameraRoll and combined + // settings. + multideviceSubpage.pageContentData = + Object.assign({}, multideviceSubpage.pageContentData, { + phoneHubCameraRollState: + MultiDeviceFeatureState.PROHIBITED_BY_POLICY, + cameraRollAccessStatus: + PhoneHubFeatureAccessStatus.AVAILABLE_BUT_NOT_GRANTED, + phoneHubNotificationsState: + MultiDeviceFeatureState.DISABLED_BY_USER, + notificationAccessStatus: + PhoneHubFeatureAccessStatus.AVAILABLE_BUT_NOT_GRANTED, + phoneHubAppsState: MultiDeviceFeatureState.DISABLED_BY_USER, + isPhoneHubAppsAccessGranted: false + }); + + flush(); + + assertTrue(!!multideviceSubpage.$$('#phoneHubItem')); + assertTrue(!!multideviceSubpage.$$('#phoneHubCameraRollItem')); + assertFalse(!!multideviceSubpage.$$('#phoneHubNotificationsItem')); + assertFalse(!!multideviceSubpage.$$('#phoneHubAppsItem')); + assertTrue(!!multideviceSubpage.$$('#phoneHubCombinedSetupItem')); + + // Notifications, CameraRoll and Apps features are not grant, but Apps + // is prohibited. Should show Apps and combined settings. + multideviceSubpage.pageContentData = + Object.assign({}, multideviceSubpage.pageContentData, { + phoneHubCameraRollState: MultiDeviceFeatureState.DISABLED_BY_USER, + cameraRollAccessStatus: + PhoneHubFeatureAccessStatus.AVAILABLE_BUT_NOT_GRANTED, + phoneHubNotificationsState: + MultiDeviceFeatureState.DISABLED_BY_USER, + notificationAccessStatus: + PhoneHubFeatureAccessStatus.AVAILABLE_BUT_NOT_GRANTED, + phoneHubAppsState: MultiDeviceFeatureState.PROHIBITED_BY_POLICY, + isPhoneHubAppsAccessGranted: false + }); + + flush(); + + assertTrue(!!multideviceSubpage.$$('#phoneHubItem')); + assertFalse(!!multideviceSubpage.$$('#phoneHubCameraRollItem')); + assertFalse(!!multideviceSubpage.$$('#phoneHubNotificationsItem')); + assertTrue(!!multideviceSubpage.$$('#phoneHubAppsItem')); + assertTrue(!!multideviceSubpage.$$('#phoneHubCombinedSetupItem')); + + // Notifications, CameraRoll and Apps features are not grant, but + // Notifications and CameraRoll are prohibited. Should show + // Notifications, CameraRoll and Apps and hide combined settings. + multideviceSubpage.pageContentData = + Object.assign({}, multideviceSubpage.pageContentData, { + phoneHubCameraRollState: + MultiDeviceFeatureState.PROHIBITED_BY_POLICY, + cameraRollAccessStatus: + PhoneHubFeatureAccessStatus.AVAILABLE_BUT_NOT_GRANTED, + phoneHubNotificationsState: + MultiDeviceFeatureState.PROHIBITED_BY_POLICY, + notificationAccessStatus: + PhoneHubFeatureAccessStatus.AVAILABLE_BUT_NOT_GRANTED, + phoneHubAppsState: MultiDeviceFeatureState.DISABLED_BY_USER, + isPhoneHubAppsAccessGranted: false + }); + + flush(); + + assertTrue(!!multideviceSubpage.$$('#phoneHubItem')); + assertTrue(!!multideviceSubpage.$$('#phoneHubCameraRollItem')); + assertTrue(!!multideviceSubpage.$$('#phoneHubNotificationsItem')); + assertTrue(!!multideviceSubpage.$$('#phoneHubAppsItem')); + assertFalse(!!multideviceSubpage.$$('#phoneHubCombinedSetupItem')); + + + // Notifications, CameraRoll and Apps features are not grant, but Phone + // Hub (top feature) is prohibited. Should show Notifications, + // CameraRoll and Apps and hide combined settings. + multideviceSubpage.pageContentData = + Object.assign({}, multideviceSubpage.pageContentData, { + phoneHubState: MultiDeviceFeatureState.PROHIBITED_BY_POLICY, + phoneHubCameraRollState: + MultiDeviceFeatureState.PROHIBITED_BY_POLICY, + cameraRollAccessStatus: + PhoneHubFeatureAccessStatus.AVAILABLE_BUT_NOT_GRANTED, + phoneHubNotificationsState: + MultiDeviceFeatureState.PROHIBITED_BY_POLICY, + notificationAccessStatus: + PhoneHubFeatureAccessStatus.AVAILABLE_BUT_NOT_GRANTED, + phoneHubAppsState: MultiDeviceFeatureState.PROHIBITED_BY_POLICY, + isPhoneHubAppsAccessGranted: false + }); + + flush(); + + assertTrue(!!multideviceSubpage.$$('#phoneHubItem')); + assertTrue(!!multideviceSubpage.$$('#phoneHubCameraRollItem')); + assertTrue(!!multideviceSubpage.$$('#phoneHubNotificationsItem')); + assertTrue(!!multideviceSubpage.$$('#phoneHubAppsItem')); + assertFalse(!!multideviceSubpage.$$('#phoneHubCombinedSetupItem')); }); });
diff --git a/chrome/test/data/webui/side_panel/bookmarks/bookmarks_list_interactive_ui_test.ts b/chrome/test/data/webui/side_panel/bookmarks/bookmarks_list_interactive_ui_test.ts index 311b4af..df9e020 100644 --- a/chrome/test/data/webui/side_panel/bookmarks/bookmarks_list_interactive_ui_test.ts +++ b/chrome/test/data/webui/side_panel/bookmarks/bookmarks_list_interactive_ui_test.ts
@@ -144,7 +144,7 @@ assertEquals('3', copiedId); keyDownOn(bookmarkElement, 0, ['ctrl'], 'v'); - let [pastedId, pastedDestinationId] = + const [pastedId, pastedDestinationId] = await bookmarksApi.whenCalled('pasteToBookmark'); assertEquals('0', pastedId); assertEquals('3', pastedDestinationId);
diff --git a/chrome/test/data/webui/tab_search/tab_search_app_test.ts b/chrome/test/data/webui/tab_search/tab_search_app_test.ts index f785348..22bdfe5 100644 --- a/chrome/test/data/webui/tab_search/tab_search_app_test.ts +++ b/chrome/test/data/webui/tab_search/tab_search_app_test.ts
@@ -242,7 +242,7 @@ recentlyClosedSectionExpanded: true })); - let tabSearchItem = tabSearchApp.$.tabsList.querySelector<HTMLElement>( + const tabSearchItem = tabSearchApp.$.tabsList.querySelector<HTMLElement>( 'tab-search-item[id="100"]')!; tabSearchItem.click(); const [tabId, withSearch, isTab, index] = @@ -278,7 +278,7 @@ recentlyClosedSectionExpanded: true })); - let tabSearchItem = + const tabSearchItem = tabSearchApp.$.tabsList.querySelector('tab-search-group-item')!; tabSearchItem.click(); const [id, withSearch, isTab, index] = @@ -769,7 +769,7 @@ tabGroups: [tabGroup], })); - let tabSearchItem = tabSearchApp.$.tabsList.querySelector<TabSearchItem>( + const tabSearchItem = tabSearchApp.$.tabsList.querySelector<TabSearchItem>( 'tab-search-item[id="1"]')!; assertEquals('Google', tabSearchItem.data.tab.title); assertEquals('Search Engines', tabSearchItem.data.tabGroup!.title);
diff --git a/chrome/test/data/webui/tab_search/tab_search_test_helper.ts b/chrome/test/data/webui/tab_search/tab_search_test_helper.ts index ffd3448..8e6ff03 100644 --- a/chrome/test/data/webui/tab_search/tab_search_test_helper.ts +++ b/chrome/test/data/webui/tab_search/tab_search_test_helper.ts
@@ -14,7 +14,7 @@ klass.prototype[functionName] = function(options: any) { const args = []; if (typeof options === 'object' && options !== null) { - let noAnimationOptions = Object.assign({}, options); + const noAnimationOptions = Object.assign({}, options); delete noAnimationOptions.behavior; args.push(noAnimationOptions);
diff --git a/chrome/test/data/webui/tab_strip/drag_manager_test.ts b/chrome/test/data/webui/tab_strip/drag_manager_test.ts index c555718c..5afbf42 100644 --- a/chrome/test/data/webui/tab_strip/drag_manager_test.ts +++ b/chrome/test/data/webui/tab_strip/drag_manager_test.ts
@@ -181,7 +181,7 @@ const eventYWithinDragImageCenter = eventYPercentage * dragImageCenterRect.height; - let expectedOffsetX = + const expectedOffsetX = dragImageCenterLeftMargin + eventXWithinDragImageCenter; let expectedOffsetY = dragImageCenterTopMargin + eventYWithinDragImageCenter;
diff --git a/chrome/test/data/webui/tab_strip/tab_list_test.ts b/chrome/test/data/webui/tab_strip/tab_list_test.ts index d12917e..ca8e9107 100644 --- a/chrome/test/data/webui/tab_strip/tab_list_test.ts +++ b/chrome/test/data/webui/tab_strip/tab_list_test.ts
@@ -289,7 +289,7 @@ async function testPlaceTabElementAnimation( indexToMove: number, newIndex: number, direction: number) { await tabList.animationPromises; - let unpinnedTabs = getUnpinnedTabs(); + const unpinnedTabs = getUnpinnedTabs(); const movedTab = unpinnedTabs[indexToMove]!; tabList.placeTabElement(movedTab, newIndex, false, undefined); @@ -661,7 +661,7 @@ callbackRouter.tabUpdated(updatedTab); await flushTasks(); - let pinnedTabElements = getPinnedTabs(); + const pinnedTabElements = getPinnedTabs(); assertEquals(pinnedTabElements.length, 1); assertTrue(pinnedTabElements[0]!.tab.pinned); assertEquals(pinnedTabElements[0]!.tab.id, tabToPin.id); @@ -947,7 +947,7 @@ // The 2nd tab should be off-screen to the right, so activating it should // scroll so that the element's right edge is aligned with the screen's // right edge. - let activeTab = getUnpinnedTabs()[1]!; + const activeTab = getUnpinnedTabs()[1]!; assertEquals( tabList.scrollLeft + tabList.offsetWidth, activeTab.offsetLeft + activeTab.offsetWidth + scrollPadding);
diff --git a/chrome/test/data/webui/tab_strip/tab_swiper_test.ts b/chrome/test/data/webui/tab_strip/tab_swiper_test.ts index 49246b6..7f129d01a 100644 --- a/chrome/test/data/webui/tab_strip/tab_swiper_test.ts +++ b/chrome/test/data/webui/tab_strip/tab_swiper_test.ts
@@ -44,14 +44,14 @@ tabElement.dispatchEvent(new PointerEvent('pointermove', pointerState)); assertEquals(tabElStyle.maxWidth, `${tabWidth}px`); assertEquals(tabElStyle.opacity, '1'); - let startTop = tabElement.getBoundingClientRect().top; + const startTop = tabElement.getBoundingClientRect().top; assertEquals(startTop, 0); // Swipe was enough to start animating the position. pointerState.clientY = startY - (TRANSLATE_ANIMATION_THRESHOLD_PX + 1); tabElement.dispatchEvent(new PointerEvent('pointermove', pointerState)); assertEquals(tabElStyle.maxWidth, `${tabWidth}px`); - let top = tabElement.getBoundingClientRect().top; + const top = tabElement.getBoundingClientRect().top; assertTrue(top < startTop && top > -1 * SWIPE_FINISH_THRESHOLD_PX); // Swipe was enough to start animating max width and opacity.
diff --git a/chrome/test/interaction/interaction_sequence_browser_util.cc b/chrome/test/interaction/interaction_sequence_browser_util.cc index 0dd0def..1059d12c 100644 --- a/chrome/test/interaction/interaction_sequence_browser_util.cc +++ b/chrome/test/interaction/interaction_sequence_browser_util.cc
@@ -28,6 +28,9 @@ #include "chrome/browser/ui/browser_navigator_params.h" #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/tabs/tab_strip_model_observer.h" +#include "chrome/browser/ui/test/test_browser_ui.h" +#include "chrome/browser/ui/views/frame/browser_view.h" +#include "chrome/test/pixel/browser_skia_gold_pixel_diff.h" #include "content/public/browser/web_contents.h" #include "content/public/test/browser_test_utils.h" #include "third_party/abseil-cpp/absl/types/optional.h" @@ -47,6 +50,43 @@ namespace { +#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS) +#define SUPPORTS_PIXEL_TESTS 1 +#else +#define SUPPORTS_PIXEL_TESTS 0 +#endif + +#if SUPPORTS_PIXEL_TESTS +class PixelTestUi : public TestBrowserUi { + public: + PixelTestUi(views::View* view, + const std::string& screenshot_name, + const std::string& baseline) + : view_(view), screenshot_name_(screenshot_name), baseline_(baseline) {} + ~PixelTestUi() override = default; + + void ShowUi(const std::string& name) override { NOTREACHED(); } + void WaitForUserDismissal() override { NOTREACHED(); } + + bool VerifyUi() override { + auto* const test_info = + testing::UnitTest::GetInstance()->current_test_info(); + const std::string test_name = + base::StrCat({test_info->test_case_name(), "_", test_info->name()}); + const std::string screenshot_name = + screenshot_name_.empty() + ? baseline_ + : base::StrCat({screenshot_name_, "_", baseline_}); + return VerifyPixelUi(view_, test_name, screenshot_name); + } + + private: + base::raw_ptr<views::View> view_ = nullptr; + std::string screenshot_name_; + std::string baseline_; +}; +#endif // SUPPORTS_PIXEL_TESTS + content::WebContents* GetWebContents(Browser* browser, absl::optional<int> tab_index) { auto* const model = browser->tab_strip_model(); @@ -398,6 +438,38 @@ } // static +bool InteractionSequenceBrowserUtil::CompareScreenshot( + ui::TrackedElement* element, + const std::string& screenshot_name, + const std::string& baseline) { +#if SUPPORTS_PIXEL_TESTS + views::View* view = nullptr; + if (auto* const view_el = element->AsA<views::TrackedElementViews>()) { + view = view_el->view(); + } else if (auto* const page_el = element->AsA<TrackedElementWebPage>()) { + auto* const util = page_el->owner(); + if (util->web_view_data_) { + view = util->web_view_data_->web_view(); + } else { + Browser* const browser = GetBrowserFromContext(page_el->context()); + BrowserView* const browser_view = + BrowserView::GetBrowserViewForBrowser(browser); + CHECK(browser_view); + CHECK_EQ(util->web_contents(), browser_view->GetActiveWebContents()); + view = browser_view->contents_web_view(); + } + } + + CHECK(view); + + PixelTestUi pixel_test_ui(view, screenshot_name, baseline); + return pixel_test_ui.VerifyUi(); +#else // !SUPPORTS_PIXEL_TESTS + return true; +#endif +} + +// static std::unique_ptr<InteractionSequenceBrowserUtil> InteractionSequenceBrowserUtil::ForExistingTabInContext( ui::ElementContext context,
diff --git a/chrome/test/interaction/interaction_sequence_browser_util.h b/chrome/test/interaction/interaction_sequence_browser_util.h index d2fa2576..4c35746e 100644 --- a/chrome/test/interaction/interaction_sequence_browser_util.h +++ b/chrome/test/interaction/interaction_sequence_browser_util.h
@@ -168,6 +168,52 @@ // Returns whether the given value is "truthy" in the Javascript sense. static bool IsTruthy(const base::Value& value); + // Takes a screenshot based on the contents of `element` and compares with + // Skia Gold. Not all element types may be supported. On platforms where + // screenshots are unsupported or flaky, may trivially return true. + // + // If `element` is a TrackedElementWebPage that corresponds to a tab, the tab + // must be the active tab in the browser window. + // + // The name of the screenshot will be composed as follows: + // TestFixture_TestName[_screenshot_name]_baseline + // If you are taking more than one screenshot per test, then `screenshot_name` + // must be specified and unique within the test; otherwise you may leave it + // empty. + // + // IMPORTANT USAGE NOTES: + // + // In order to actually take screenshots: + // - Your test must be in browser_tests rather than interactive_ui_tests + // - Your test must be included in pixel_browser_tests.filter + // + // Note that test in browser_tests (when not running in the + // pixel_browser_tests CQ task) may run at the same time as other tests, which + // can result in flakiness for interaction tests (especially if mouse + // position, window activation, or occlusion could change the behavior of a + // test). So if you need to both test complex interaction and take screenshots + // you have several options: + // 1. Make a detailed test for interactive_ui_tests and one or more simple + // tests that just verify the UI visuals in browser_tests (downside: code + // duplication) + // 2. Put a test in browser_tests that only runs when the command line flag + // for pixel tests is set (downside: won't run on platforms that don't + // support pixel tests) + // 3. Put the full test in browser_tests and harden it against activation and + // focus changes, mouse position, etc. - e.g. by using things like + // BubbleDialogDelegate::PreventCloseOnDeactivate() (downside: more + // complicated test, still potential for flaking) + // + // In general, if (3) is possible and you can be sure your test won't flake, + // it's probably the best choice, followed by (1) if you can't guarantee + // stability in non-single-process tests. + // + // We are currently considering enabling pixel tests in interactive_ui_tests, + // which would solve the problem by providing a single safe place for both. + static bool CompareScreenshot(ui::TrackedElement* element, + const std::string& screenshot_name, + const std::string& baseline); + // Allow access to the associated WebContents. content::WebContents* web_contents() const { return WebContentsObserver::web_contents();
diff --git a/chrome/test/interaction/interaction_sequence_browser_util_browsertest.cc b/chrome/test/interaction/interaction_sequence_browser_util_browsertest.cc index de4422a..55400be6 100644 --- a/chrome/test/interaction/interaction_sequence_browser_util_browsertest.cc +++ b/chrome/test/interaction/interaction_sequence_browser_util_browsertest.cc
@@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "chrome/browser/ui/browser_element_identifiers.h" +#include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/test/interaction/interaction_sequence_browser_util.h" #include <sstream> @@ -1399,3 +1401,67 @@ EXPECT_CALL_IN_SCOPE(completed, Run, sequence->RunSynchronouslyForTesting()); } + +IN_PROC_BROWSER_TEST_F(InteractionSequenceBrowserUtilTest, + CompareScreenshot_View) { + UNCALLED_MOCK_CALLBACK(ui::InteractionSequence::CompletedCallback, completed); + UNCALLED_MOCK_CALLBACK(ui::InteractionSequence::AbortedCallback, aborted); + + auto sequence = + ui::InteractionSequence::Builder() + .SetCompletedCallback(completed.Get()) + .SetAbortedCallback(aborted.Get()) + .SetContext(browser()->window()->GetElementContext()) + .AddStep( + ui::InteractionSequence::StepBuilder() + .SetType(ui::InteractionSequence::StepType::kShown) + .SetElementID(kAppMenuButtonElementId) + .SetStartCallback(base::BindLambdaForTesting( + [&](ui::InteractionSequence* sequence, + ui::TrackedElement* element) { + EXPECT_TRUE( + InteractionSequenceBrowserUtil::CompareScreenshot( + element, "AppMenuButton", "3600270")); + })) + .Build()) + .Build(); + + EXPECT_CALL_IN_SCOPE(completed, Run, sequence->RunSynchronouslyForTesting()); +} + +IN_PROC_BROWSER_TEST_F(InteractionSequenceBrowserUtilTest, + CompareScreenshot_WebPage) { + UNCALLED_MOCK_CALLBACK(ui::InteractionSequence::CompletedCallback, completed); + UNCALLED_MOCK_CALLBACK(ui::InteractionSequence::AbortedCallback, aborted); + + // Set the browser view to a consistent size. + BrowserView* const browser_view = + BrowserView::GetBrowserViewForBrowser(browser()); + browser_view->GetWidget()->SetSize({400, 300}); + + auto util = InteractionSequenceBrowserUtil::ForExistingTabInBrowser( + browser(), kInteractionSequenceBrowserUtilTestId); + const GURL url = embedded_test_server()->GetURL("/title1.html"); + util->LoadPage(url); + + auto sequence = + ui::InteractionSequence::Builder() + .SetCompletedCallback(completed.Get()) + .SetAbortedCallback(aborted.Get()) + .SetContext(browser()->window()->GetElementContext()) + .AddStep( + ui::InteractionSequence::StepBuilder() + .SetType(ui::InteractionSequence::StepType::kShown) + .SetElementID(kInteractionSequenceBrowserUtilTestId) + .SetStartCallback(base::BindLambdaForTesting( + [&](ui::InteractionSequence* sequence, + ui::TrackedElement* element) { + EXPECT_TRUE( + InteractionSequenceBrowserUtil::CompareScreenshot( + element, std::string(), "3600270")); + })) + .Build()) + .Build(); + + EXPECT_CALL_IN_SCOPE(completed, Run, sequence->RunSynchronouslyForTesting()); +}
diff --git a/chrome/test/interaction/interaction_sequence_browser_util_interactive_uitest.cc b/chrome/test/interaction/interaction_sequence_browser_util_interactive_uitest.cc index d1bc32cb..5cc6652 100644 --- a/chrome/test/interaction/interaction_sequence_browser_util_interactive_uitest.cc +++ b/chrome/test/interaction/interaction_sequence_browser_util_interactive_uitest.cc
@@ -100,6 +100,7 @@ .AddStep(ui::InteractionSequence::StepBuilder() .SetType(ui::InteractionSequence::StepType::kShown) .SetElementID(AppMenuModel::kDownloadsMenuItem) + .SetMustRemainVisible(false) .SetStartCallback(base::BindLambdaForTesting( [&](ui::InteractionSequence*, ui::TrackedElement* element) {
diff --git a/chrome/test/webapps/coverage/coverage_cros.tsv b/chrome/test/webapps/coverage/coverage_cros.tsv index a5f8a4de..c051842 100644 --- a/chrome/test/webapps/coverage/coverage_cros.tsv +++ b/chrome/test/webapps/coverage/coverage_cros.tsv
@@ -1,5 +1,5 @@ # This is a generated file. -# Full coverage: 56%, with partial coverage: 76% +# Full coverage: 47%, with partial coverage: 65% install_create_shortcut_windowed_SiteA🌕 manifest_update_title_SiteA🌑 accept_app_id_update_dialog🌑 close_pwa🌑 launch_from_menu_option_SiteA🌑 check_app_title_site_a_is_SiteAUpdated🌑 install_create_shortcut_windowed_SiteA🌕 manifest_update_title_SiteA🌑 accept_app_id_update_dialog🌑 close_pwa🌑 launch_from_launch_icon_SiteA🌑 check_app_title_site_a_is_SiteAUpdated🌑 install_create_shortcut_windowed_SiteA🌕 manifest_update_title_SiteA🌑 accept_app_id_update_dialog🌑 close_pwa🌑 launch_from_chrome_apps_SiteA🌑 check_app_title_site_a_is_SiteAUpdated🌑 @@ -613,3 +613,131 @@ install_create_shortcut_tabbed_SiteA🌕 set_open_in_window_SiteA🌓 check_app_in_list_windowed_SiteA🌓 install_create_shortcut_tabbed_SiteA🌕 set_open_in_window_SiteA🌓 navigate_browser_SiteA🌕 check_install_icon_not_shown🌕 install_create_shortcut_tabbed_SiteA🌕 set_open_in_window_SiteA🌓 navigate_browser_SiteA🌕 check_launch_icon_shown🌕 +install_create_shortcut_windowed_SiteB🌕 check_site_handles_file_SiteB_Txt🌑 check_site_handles_file_SiteB_Png🌑 +install_omnibox_icon_SiteB🌕 check_site_handles_file_SiteB_Txt🌑 check_site_handles_file_SiteB_Png🌑 +install_policy_app_windowed_no_shortcut_SiteB🌓 check_site_handles_file_SiteB_Txt🌑 check_site_handles_file_SiteB_Png🌑 +install_policy_app_windowed_shortcut_SiteB🌓 check_site_handles_file_SiteB_Txt🌑 check_site_handles_file_SiteB_Png🌑 +install_menu_option_SiteB🌕 check_site_handles_file_SiteB_Txt🌑 check_site_handles_file_SiteB_Png🌑 +install_create_shortcut_tabbed_SiteB🌕 check_site_handles_file_SiteB_Txt🌑 check_site_handles_file_SiteB_Png🌑 +install_policy_app_tabbed_shortcut_SiteB🌓 check_site_handles_file_SiteB_Txt🌑 check_site_handles_file_SiteB_Png🌑 +install_policy_app_tabbed_no_shortcut_SiteB🌓 check_site_handles_file_SiteB_Txt🌑 check_site_handles_file_SiteB_Png🌑 +install_create_shortcut_windowed_SiteB🌕 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_omnibox_icon_SiteB🌕 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_windowed_no_shortcut_SiteB🌓 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_windowed_shortcut_SiteB🌓 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_menu_option_SiteB🌕 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_create_shortcut_tabbed_SiteB🌕 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_tabbed_shortcut_SiteB🌓 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_tabbed_no_shortcut_SiteB🌓 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_create_shortcut_windowed_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_OneTextFile🌑 +install_omnibox_icon_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_OneTextFile🌑 +install_policy_app_windowed_no_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_OneTextFile🌑 +install_policy_app_windowed_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_OneTextFile🌑 +install_menu_option_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_OneTextFile🌑 +install_create_shortcut_tabbed_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_OneTextFile🌑 +install_policy_app_tabbed_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_OneTextFile🌑 +install_policy_app_tabbed_no_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_OneTextFile🌑 +install_create_shortcut_windowed_SiteB🌕 launch_file_MultipleTextFiles🌑 check_file_handling_dialog_Shown🌑 +install_omnibox_icon_SiteB🌕 launch_file_MultipleTextFiles🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_windowed_no_shortcut_SiteB🌓 launch_file_MultipleTextFiles🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_windowed_shortcut_SiteB🌓 launch_file_MultipleTextFiles🌑 check_file_handling_dialog_Shown🌑 +install_menu_option_SiteB🌕 launch_file_MultipleTextFiles🌑 check_file_handling_dialog_Shown🌑 +install_create_shortcut_tabbed_SiteB🌕 launch_file_MultipleTextFiles🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_tabbed_shortcut_SiteB🌓 launch_file_MultipleTextFiles🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_tabbed_no_shortcut_SiteB🌓 launch_file_MultipleTextFiles🌑 check_file_handling_dialog_Shown🌑 +install_create_shortcut_windowed_SiteB🌕 launch_file_MultipleTextFiles🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_MultipleTextFiles🌑 +install_omnibox_icon_SiteB🌕 launch_file_MultipleTextFiles🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_MultipleTextFiles🌑 +install_policy_app_windowed_no_shortcut_SiteB🌓 launch_file_MultipleTextFiles🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_MultipleTextFiles🌑 +install_policy_app_windowed_shortcut_SiteB🌓 launch_file_MultipleTextFiles🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_MultipleTextFiles🌑 +install_menu_option_SiteB🌕 launch_file_MultipleTextFiles🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_MultipleTextFiles🌑 +install_create_shortcut_tabbed_SiteB🌕 launch_file_MultipleTextFiles🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_MultipleTextFiles🌑 +install_policy_app_tabbed_shortcut_SiteB🌓 launch_file_MultipleTextFiles🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_MultipleTextFiles🌑 +install_policy_app_tabbed_no_shortcut_SiteB🌓 launch_file_MultipleTextFiles🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_MultipleTextFiles🌑 +install_create_shortcut_windowed_SiteB🌕 launch_file_OnePngFile🌑 check_file_handling_dialog_Shown🌑 +install_omnibox_icon_SiteB🌕 launch_file_OnePngFile🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_windowed_no_shortcut_SiteB🌓 launch_file_OnePngFile🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_windowed_shortcut_SiteB🌓 launch_file_OnePngFile🌑 check_file_handling_dialog_Shown🌑 +install_menu_option_SiteB🌕 launch_file_OnePngFile🌑 check_file_handling_dialog_Shown🌑 +install_create_shortcut_tabbed_SiteB🌕 launch_file_OnePngFile🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_tabbed_shortcut_SiteB🌓 launch_file_OnePngFile🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_tabbed_no_shortcut_SiteB🌓 launch_file_OnePngFile🌑 check_file_handling_dialog_Shown🌑 +install_create_shortcut_windowed_SiteB🌕 launch_file_OnePngFile🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_OnePngFile🌑 +install_omnibox_icon_SiteB🌕 launch_file_OnePngFile🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_OnePngFile🌑 +install_policy_app_windowed_no_shortcut_SiteB🌓 launch_file_OnePngFile🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_OnePngFile🌑 +install_policy_app_windowed_shortcut_SiteB🌓 launch_file_OnePngFile🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_OnePngFile🌑 +install_menu_option_SiteB🌕 launch_file_OnePngFile🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_OnePngFile🌑 +install_create_shortcut_tabbed_SiteB🌕 launch_file_OnePngFile🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_OnePngFile🌑 +install_policy_app_tabbed_shortcut_SiteB🌓 launch_file_OnePngFile🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_OnePngFile🌑 +install_policy_app_tabbed_no_shortcut_SiteB🌓 launch_file_OnePngFile🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_OnePngFile🌑 +install_create_shortcut_windowed_SiteB🌕 launch_file_MultiplePngFiles🌑 check_file_handling_dialog_Shown🌑 +install_omnibox_icon_SiteB🌕 launch_file_MultiplePngFiles🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_windowed_no_shortcut_SiteB🌓 launch_file_MultiplePngFiles🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_windowed_shortcut_SiteB🌓 launch_file_MultiplePngFiles🌑 check_file_handling_dialog_Shown🌑 +install_menu_option_SiteB🌕 launch_file_MultiplePngFiles🌑 check_file_handling_dialog_Shown🌑 +install_create_shortcut_tabbed_SiteB🌕 launch_file_MultiplePngFiles🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_tabbed_shortcut_SiteB🌓 launch_file_MultiplePngFiles🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_tabbed_no_shortcut_SiteB🌓 launch_file_MultiplePngFiles🌑 check_file_handling_dialog_Shown🌑 +install_create_shortcut_windowed_SiteB🌕 launch_file_MultiplePngFiles🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_Two🌑 check_files_loaded_in_site_SiteB_MultiplePngFiles🌑 +install_omnibox_icon_SiteB🌕 launch_file_MultiplePngFiles🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_Two🌑 check_files_loaded_in_site_SiteB_MultiplePngFiles🌑 +install_policy_app_windowed_no_shortcut_SiteB🌓 launch_file_MultiplePngFiles🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_Two🌑 check_files_loaded_in_site_SiteB_MultiplePngFiles🌑 +install_policy_app_windowed_shortcut_SiteB🌓 launch_file_MultiplePngFiles🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_Two🌑 check_files_loaded_in_site_SiteB_MultiplePngFiles🌑 +install_menu_option_SiteB🌕 launch_file_MultiplePngFiles🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_Two🌑 check_files_loaded_in_site_SiteB_MultiplePngFiles🌑 +install_create_shortcut_tabbed_SiteB🌕 launch_file_MultiplePngFiles🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_Two🌑 check_files_loaded_in_site_SiteB_MultiplePngFiles🌑 +install_policy_app_tabbed_shortcut_SiteB🌓 launch_file_MultiplePngFiles🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_Two🌑 check_files_loaded_in_site_SiteB_MultiplePngFiles🌑 +install_policy_app_tabbed_no_shortcut_SiteB🌓 launch_file_MultiplePngFiles🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_Two🌑 check_files_loaded_in_site_SiteB_MultiplePngFiles🌑 +install_create_shortcut_windowed_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Allow_Remember🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_NotShown🌑 check_pwa_window_created_SiteB_One🌑 +install_omnibox_icon_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Allow_Remember🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_NotShown🌑 check_pwa_window_created_SiteB_One🌑 +install_policy_app_windowed_no_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Allow_Remember🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_NotShown🌑 check_pwa_window_created_SiteB_One🌑 +install_policy_app_windowed_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Allow_Remember🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_NotShown🌑 check_pwa_window_created_SiteB_One🌑 +install_menu_option_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Allow_Remember🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_NotShown🌑 check_pwa_window_created_SiteB_One🌑 +install_create_shortcut_tabbed_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Allow_Remember🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_NotShown🌑 check_pwa_window_created_SiteB_One🌑 +install_policy_app_tabbed_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Allow_Remember🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_NotShown🌑 check_pwa_window_created_SiteB_One🌑 +install_policy_app_tabbed_no_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Allow_Remember🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_NotShown🌑 check_pwa_window_created_SiteB_One🌑 +install_create_shortcut_windowed_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Allow_AskAgain🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_omnibox_icon_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Allow_AskAgain🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_windowed_no_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Allow_AskAgain🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_windowed_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Allow_AskAgain🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_menu_option_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Allow_AskAgain🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_create_shortcut_tabbed_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Allow_AskAgain🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_tabbed_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Allow_AskAgain🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_tabbed_no_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Allow_AskAgain🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_create_shortcut_windowed_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Deny_AskAgain🌑 check_window_not_created🌑 check_site_handles_file_SiteB_Txt🌑 check_site_handles_file_SiteB_Png🌑 +install_omnibox_icon_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Deny_AskAgain🌑 check_window_not_created🌑 check_site_handles_file_SiteB_Txt🌑 check_site_handles_file_SiteB_Png🌑 +install_policy_app_windowed_no_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Deny_AskAgain🌑 check_window_not_created🌑 check_site_handles_file_SiteB_Txt🌑 check_site_handles_file_SiteB_Png🌑 +install_policy_app_windowed_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Deny_AskAgain🌑 check_window_not_created🌑 check_site_handles_file_SiteB_Txt🌑 check_site_handles_file_SiteB_Png🌑 +install_menu_option_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Deny_AskAgain🌑 check_window_not_created🌑 check_site_handles_file_SiteB_Txt🌑 check_site_handles_file_SiteB_Png🌑 +install_create_shortcut_tabbed_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Deny_AskAgain🌑 check_window_not_created🌑 check_site_handles_file_SiteB_Txt🌑 check_site_handles_file_SiteB_Png🌑 +install_policy_app_tabbed_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Deny_AskAgain🌑 check_window_not_created🌑 check_site_handles_file_SiteB_Txt🌑 check_site_handles_file_SiteB_Png🌑 +install_policy_app_tabbed_no_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Deny_AskAgain🌑 check_window_not_created🌑 check_site_handles_file_SiteB_Txt🌑 check_site_handles_file_SiteB_Png🌑 +install_create_shortcut_windowed_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Deny_AskAgain🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_omnibox_icon_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Deny_AskAgain🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_windowed_no_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Deny_AskAgain🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_windowed_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Deny_AskAgain🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_menu_option_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Deny_AskAgain🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_create_shortcut_tabbed_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Deny_AskAgain🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_tabbed_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Deny_AskAgain🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_tabbed_no_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Deny_AskAgain🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_create_shortcut_windowed_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Deny_Remember🌑 check_window_not_created🌑 check_site_not_handles_file_SiteB_Txt🌑 check_site_not_handles_file_SiteB_Png🌑 +install_omnibox_icon_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Deny_Remember🌑 check_window_not_created🌑 check_site_not_handles_file_SiteB_Txt🌑 check_site_not_handles_file_SiteB_Png🌑 +install_policy_app_windowed_no_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Deny_Remember🌑 check_window_not_created🌑 check_site_not_handles_file_SiteB_Txt🌑 check_site_not_handles_file_SiteB_Png🌑 +install_policy_app_windowed_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Deny_Remember🌑 check_window_not_created🌑 check_site_not_handles_file_SiteB_Txt🌑 check_site_not_handles_file_SiteB_Png🌑 +install_menu_option_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Deny_Remember🌑 check_window_not_created🌑 check_site_not_handles_file_SiteB_Txt🌑 check_site_not_handles_file_SiteB_Png🌑 +install_create_shortcut_tabbed_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Deny_Remember🌑 check_window_not_created🌑 check_site_not_handles_file_SiteB_Txt🌑 check_site_not_handles_file_SiteB_Png🌑 +install_policy_app_tabbed_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Deny_Remember🌑 check_window_not_created🌑 check_site_not_handles_file_SiteB_Txt🌑 check_site_not_handles_file_SiteB_Png🌑 +install_policy_app_tabbed_no_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Deny_Remember🌑 check_window_not_created🌑 check_site_not_handles_file_SiteB_Txt🌑 check_site_not_handles_file_SiteB_Png🌑 +install_create_shortcut_windowed_SiteB🌕 add_file_handling_policy_approval_SiteB🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_NotShown🌑 check_pwa_window_created_SiteB_One🌑 +install_omnibox_icon_SiteB🌕 add_file_handling_policy_approval_SiteB🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_NotShown🌑 check_pwa_window_created_SiteB_One🌑 +install_policy_app_windowed_no_shortcut_SiteB🌓 add_file_handling_policy_approval_SiteB🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_NotShown🌑 check_pwa_window_created_SiteB_One🌑 +install_policy_app_windowed_shortcut_SiteB🌓 add_file_handling_policy_approval_SiteB🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_NotShown🌑 check_pwa_window_created_SiteB_One🌑 +install_menu_option_SiteB🌕 add_file_handling_policy_approval_SiteB🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_NotShown🌑 check_pwa_window_created_SiteB_One🌑 +install_create_shortcut_tabbed_SiteB🌕 add_file_handling_policy_approval_SiteB🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_NotShown🌑 check_pwa_window_created_SiteB_One🌑 +install_policy_app_tabbed_shortcut_SiteB🌓 add_file_handling_policy_approval_SiteB🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_NotShown🌑 check_pwa_window_created_SiteB_One🌑 +install_policy_app_tabbed_no_shortcut_SiteB🌓 add_file_handling_policy_approval_SiteB🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_NotShown🌑 check_pwa_window_created_SiteB_One🌑 +install_create_shortcut_windowed_SiteB🌕 add_file_handling_policy_approval_SiteB🌑 remove_file_handling_policy_approval_SiteB🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_omnibox_icon_SiteB🌕 add_file_handling_policy_approval_SiteB🌑 remove_file_handling_policy_approval_SiteB🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_windowed_no_shortcut_SiteB🌓 add_file_handling_policy_approval_SiteB🌑 remove_file_handling_policy_approval_SiteB🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_windowed_shortcut_SiteB🌓 add_file_handling_policy_approval_SiteB🌑 remove_file_handling_policy_approval_SiteB🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_menu_option_SiteB🌕 add_file_handling_policy_approval_SiteB🌑 remove_file_handling_policy_approval_SiteB🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_create_shortcut_tabbed_SiteB🌕 add_file_handling_policy_approval_SiteB🌑 remove_file_handling_policy_approval_SiteB🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_tabbed_shortcut_SiteB🌓 add_file_handling_policy_approval_SiteB🌑 remove_file_handling_policy_approval_SiteB🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_tabbed_no_shortcut_SiteB🌓 add_file_handling_policy_approval_SiteB🌑 remove_file_handling_policy_approval_SiteB🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑
diff --git a/chrome/test/webapps/coverage/coverage_linux.tsv b/chrome/test/webapps/coverage/coverage_linux.tsv index 0c14179a..a4aba43f 100644 --- a/chrome/test/webapps/coverage/coverage_linux.tsv +++ b/chrome/test/webapps/coverage/coverage_linux.tsv
@@ -1,5 +1,5 @@ # This is a generated file. -# Full coverage: 63%, with partial coverage: 85% +# Full coverage: 55%, with partial coverage: 75% install_create_shortcut_windowed_SiteA🌕 manifest_update_title_SiteA🌑 accept_app_id_update_dialog🌑 close_pwa🌑 launch_from_menu_option_SiteA🌑 check_app_title_site_a_is_SiteAUpdated🌑 install_create_shortcut_windowed_SiteA🌕 manifest_update_title_SiteA🌑 accept_app_id_update_dialog🌑 close_pwa🌑 launch_from_launch_icon_SiteA🌑 check_app_title_site_a_is_SiteAUpdated🌑 install_create_shortcut_windowed_SiteA🌕 manifest_update_title_SiteA🌑 accept_app_id_update_dialog🌑 close_pwa🌑 launch_from_chrome_apps_SiteA🌑 check_app_title_site_a_is_SiteAUpdated🌑 @@ -782,3 +782,131 @@ install_create_shortcut_tabbed_SiteA🌕 set_open_in_window_SiteA🌓 check_app_in_list_windowed_SiteA🌓 install_create_shortcut_tabbed_SiteA🌕 set_open_in_window_SiteA🌓 navigate_browser_SiteA🌕 check_install_icon_not_shown🌕 install_create_shortcut_tabbed_SiteA🌕 set_open_in_window_SiteA🌓 navigate_browser_SiteA🌕 check_launch_icon_shown🌕 +install_create_shortcut_windowed_SiteB🌕 check_site_handles_file_SiteB_Txt🌑 check_site_handles_file_SiteB_Png🌑 +install_omnibox_icon_SiteB🌕 check_site_handles_file_SiteB_Txt🌑 check_site_handles_file_SiteB_Png🌑 +install_policy_app_windowed_no_shortcut_SiteB🌓 check_site_handles_file_SiteB_Txt🌑 check_site_handles_file_SiteB_Png🌑 +install_policy_app_windowed_shortcut_SiteB🌓 check_site_handles_file_SiteB_Txt🌑 check_site_handles_file_SiteB_Png🌑 +install_menu_option_SiteB🌕 check_site_handles_file_SiteB_Txt🌑 check_site_handles_file_SiteB_Png🌑 +install_create_shortcut_tabbed_SiteB🌕 check_site_handles_file_SiteB_Txt🌑 check_site_handles_file_SiteB_Png🌑 +install_policy_app_tabbed_shortcut_SiteB🌓 check_site_handles_file_SiteB_Txt🌑 check_site_handles_file_SiteB_Png🌑 +install_policy_app_tabbed_no_shortcut_SiteB🌓 check_site_handles_file_SiteB_Txt🌑 check_site_handles_file_SiteB_Png🌑 +install_create_shortcut_windowed_SiteB🌕 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_omnibox_icon_SiteB🌕 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_windowed_no_shortcut_SiteB🌓 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_windowed_shortcut_SiteB🌓 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_menu_option_SiteB🌕 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_create_shortcut_tabbed_SiteB🌕 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_tabbed_shortcut_SiteB🌓 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_tabbed_no_shortcut_SiteB🌓 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_create_shortcut_windowed_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_OneTextFile🌑 +install_omnibox_icon_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_OneTextFile🌑 +install_policy_app_windowed_no_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_OneTextFile🌑 +install_policy_app_windowed_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_OneTextFile🌑 +install_menu_option_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_OneTextFile🌑 +install_create_shortcut_tabbed_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_OneTextFile🌑 +install_policy_app_tabbed_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_OneTextFile🌑 +install_policy_app_tabbed_no_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_OneTextFile🌑 +install_create_shortcut_windowed_SiteB🌕 launch_file_MultipleTextFiles🌑 check_file_handling_dialog_Shown🌑 +install_omnibox_icon_SiteB🌕 launch_file_MultipleTextFiles🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_windowed_no_shortcut_SiteB🌓 launch_file_MultipleTextFiles🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_windowed_shortcut_SiteB🌓 launch_file_MultipleTextFiles🌑 check_file_handling_dialog_Shown🌑 +install_menu_option_SiteB🌕 launch_file_MultipleTextFiles🌑 check_file_handling_dialog_Shown🌑 +install_create_shortcut_tabbed_SiteB🌕 launch_file_MultipleTextFiles🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_tabbed_shortcut_SiteB🌓 launch_file_MultipleTextFiles🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_tabbed_no_shortcut_SiteB🌓 launch_file_MultipleTextFiles🌑 check_file_handling_dialog_Shown🌑 +install_create_shortcut_windowed_SiteB🌕 launch_file_MultipleTextFiles🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_MultipleTextFiles🌑 +install_omnibox_icon_SiteB🌕 launch_file_MultipleTextFiles🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_MultipleTextFiles🌑 +install_policy_app_windowed_no_shortcut_SiteB🌓 launch_file_MultipleTextFiles🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_MultipleTextFiles🌑 +install_policy_app_windowed_shortcut_SiteB🌓 launch_file_MultipleTextFiles🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_MultipleTextFiles🌑 +install_menu_option_SiteB🌕 launch_file_MultipleTextFiles🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_MultipleTextFiles🌑 +install_create_shortcut_tabbed_SiteB🌕 launch_file_MultipleTextFiles🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_MultipleTextFiles🌑 +install_policy_app_tabbed_shortcut_SiteB🌓 launch_file_MultipleTextFiles🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_MultipleTextFiles🌑 +install_policy_app_tabbed_no_shortcut_SiteB🌓 launch_file_MultipleTextFiles🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_MultipleTextFiles🌑 +install_create_shortcut_windowed_SiteB🌕 launch_file_OnePngFile🌑 check_file_handling_dialog_Shown🌑 +install_omnibox_icon_SiteB🌕 launch_file_OnePngFile🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_windowed_no_shortcut_SiteB🌓 launch_file_OnePngFile🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_windowed_shortcut_SiteB🌓 launch_file_OnePngFile🌑 check_file_handling_dialog_Shown🌑 +install_menu_option_SiteB🌕 launch_file_OnePngFile🌑 check_file_handling_dialog_Shown🌑 +install_create_shortcut_tabbed_SiteB🌕 launch_file_OnePngFile🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_tabbed_shortcut_SiteB🌓 launch_file_OnePngFile🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_tabbed_no_shortcut_SiteB🌓 launch_file_OnePngFile🌑 check_file_handling_dialog_Shown🌑 +install_create_shortcut_windowed_SiteB🌕 launch_file_OnePngFile🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_OnePngFile🌑 +install_omnibox_icon_SiteB🌕 launch_file_OnePngFile🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_OnePngFile🌑 +install_policy_app_windowed_no_shortcut_SiteB🌓 launch_file_OnePngFile🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_OnePngFile🌑 +install_policy_app_windowed_shortcut_SiteB🌓 launch_file_OnePngFile🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_OnePngFile🌑 +install_menu_option_SiteB🌕 launch_file_OnePngFile🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_OnePngFile🌑 +install_create_shortcut_tabbed_SiteB🌕 launch_file_OnePngFile🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_OnePngFile🌑 +install_policy_app_tabbed_shortcut_SiteB🌓 launch_file_OnePngFile🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_OnePngFile🌑 +install_policy_app_tabbed_no_shortcut_SiteB🌓 launch_file_OnePngFile🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_OnePngFile🌑 +install_create_shortcut_windowed_SiteB🌕 launch_file_MultiplePngFiles🌑 check_file_handling_dialog_Shown🌑 +install_omnibox_icon_SiteB🌕 launch_file_MultiplePngFiles🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_windowed_no_shortcut_SiteB🌓 launch_file_MultiplePngFiles🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_windowed_shortcut_SiteB🌓 launch_file_MultiplePngFiles🌑 check_file_handling_dialog_Shown🌑 +install_menu_option_SiteB🌕 launch_file_MultiplePngFiles🌑 check_file_handling_dialog_Shown🌑 +install_create_shortcut_tabbed_SiteB🌕 launch_file_MultiplePngFiles🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_tabbed_shortcut_SiteB🌓 launch_file_MultiplePngFiles🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_tabbed_no_shortcut_SiteB🌓 launch_file_MultiplePngFiles🌑 check_file_handling_dialog_Shown🌑 +install_create_shortcut_windowed_SiteB🌕 launch_file_MultiplePngFiles🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_Two🌑 check_files_loaded_in_site_SiteB_MultiplePngFiles🌑 +install_omnibox_icon_SiteB🌕 launch_file_MultiplePngFiles🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_Two🌑 check_files_loaded_in_site_SiteB_MultiplePngFiles🌑 +install_policy_app_windowed_no_shortcut_SiteB🌓 launch_file_MultiplePngFiles🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_Two🌑 check_files_loaded_in_site_SiteB_MultiplePngFiles🌑 +install_policy_app_windowed_shortcut_SiteB🌓 launch_file_MultiplePngFiles🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_Two🌑 check_files_loaded_in_site_SiteB_MultiplePngFiles🌑 +install_menu_option_SiteB🌕 launch_file_MultiplePngFiles🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_Two🌑 check_files_loaded_in_site_SiteB_MultiplePngFiles🌑 +install_create_shortcut_tabbed_SiteB🌕 launch_file_MultiplePngFiles🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_Two🌑 check_files_loaded_in_site_SiteB_MultiplePngFiles🌑 +install_policy_app_tabbed_shortcut_SiteB🌓 launch_file_MultiplePngFiles🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_Two🌑 check_files_loaded_in_site_SiteB_MultiplePngFiles🌑 +install_policy_app_tabbed_no_shortcut_SiteB🌓 launch_file_MultiplePngFiles🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_Two🌑 check_files_loaded_in_site_SiteB_MultiplePngFiles🌑 +install_create_shortcut_windowed_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Allow_Remember🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_NotShown🌑 check_pwa_window_created_SiteB_One🌑 +install_omnibox_icon_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Allow_Remember🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_NotShown🌑 check_pwa_window_created_SiteB_One🌑 +install_policy_app_windowed_no_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Allow_Remember🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_NotShown🌑 check_pwa_window_created_SiteB_One🌑 +install_policy_app_windowed_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Allow_Remember🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_NotShown🌑 check_pwa_window_created_SiteB_One🌑 +install_menu_option_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Allow_Remember🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_NotShown🌑 check_pwa_window_created_SiteB_One🌑 +install_create_shortcut_tabbed_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Allow_Remember🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_NotShown🌑 check_pwa_window_created_SiteB_One🌑 +install_policy_app_tabbed_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Allow_Remember🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_NotShown🌑 check_pwa_window_created_SiteB_One🌑 +install_policy_app_tabbed_no_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Allow_Remember🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_NotShown🌑 check_pwa_window_created_SiteB_One🌑 +install_create_shortcut_windowed_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Allow_AskAgain🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_omnibox_icon_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Allow_AskAgain🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_windowed_no_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Allow_AskAgain🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_windowed_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Allow_AskAgain🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_menu_option_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Allow_AskAgain🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_create_shortcut_tabbed_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Allow_AskAgain🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_tabbed_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Allow_AskAgain🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_tabbed_no_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Allow_AskAgain🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_create_shortcut_windowed_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Deny_AskAgain🌑 check_window_not_created🌑 check_site_handles_file_SiteB_Txt🌑 check_site_handles_file_SiteB_Png🌑 +install_omnibox_icon_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Deny_AskAgain🌑 check_window_not_created🌑 check_site_handles_file_SiteB_Txt🌑 check_site_handles_file_SiteB_Png🌑 +install_policy_app_windowed_no_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Deny_AskAgain🌑 check_window_not_created🌑 check_site_handles_file_SiteB_Txt🌑 check_site_handles_file_SiteB_Png🌑 +install_policy_app_windowed_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Deny_AskAgain🌑 check_window_not_created🌑 check_site_handles_file_SiteB_Txt🌑 check_site_handles_file_SiteB_Png🌑 +install_menu_option_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Deny_AskAgain🌑 check_window_not_created🌑 check_site_handles_file_SiteB_Txt🌑 check_site_handles_file_SiteB_Png🌑 +install_create_shortcut_tabbed_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Deny_AskAgain🌑 check_window_not_created🌑 check_site_handles_file_SiteB_Txt🌑 check_site_handles_file_SiteB_Png🌑 +install_policy_app_tabbed_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Deny_AskAgain🌑 check_window_not_created🌑 check_site_handles_file_SiteB_Txt🌑 check_site_handles_file_SiteB_Png🌑 +install_policy_app_tabbed_no_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Deny_AskAgain🌑 check_window_not_created🌑 check_site_handles_file_SiteB_Txt🌑 check_site_handles_file_SiteB_Png🌑 +install_create_shortcut_windowed_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Deny_AskAgain🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_omnibox_icon_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Deny_AskAgain🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_windowed_no_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Deny_AskAgain🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_windowed_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Deny_AskAgain🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_menu_option_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Deny_AskAgain🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_create_shortcut_tabbed_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Deny_AskAgain🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_tabbed_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Deny_AskAgain🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_tabbed_no_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Deny_AskAgain🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_create_shortcut_windowed_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Deny_Remember🌑 check_window_not_created🌑 check_site_not_handles_file_SiteB_Txt🌑 check_site_not_handles_file_SiteB_Png🌑 +install_omnibox_icon_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Deny_Remember🌑 check_window_not_created🌑 check_site_not_handles_file_SiteB_Txt🌑 check_site_not_handles_file_SiteB_Png🌑 +install_policy_app_windowed_no_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Deny_Remember🌑 check_window_not_created🌑 check_site_not_handles_file_SiteB_Txt🌑 check_site_not_handles_file_SiteB_Png🌑 +install_policy_app_windowed_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Deny_Remember🌑 check_window_not_created🌑 check_site_not_handles_file_SiteB_Txt🌑 check_site_not_handles_file_SiteB_Png🌑 +install_menu_option_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Deny_Remember🌑 check_window_not_created🌑 check_site_not_handles_file_SiteB_Txt🌑 check_site_not_handles_file_SiteB_Png🌑 +install_create_shortcut_tabbed_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Deny_Remember🌑 check_window_not_created🌑 check_site_not_handles_file_SiteB_Txt🌑 check_site_not_handles_file_SiteB_Png🌑 +install_policy_app_tabbed_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Deny_Remember🌑 check_window_not_created🌑 check_site_not_handles_file_SiteB_Txt🌑 check_site_not_handles_file_SiteB_Png🌑 +install_policy_app_tabbed_no_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Deny_Remember🌑 check_window_not_created🌑 check_site_not_handles_file_SiteB_Txt🌑 check_site_not_handles_file_SiteB_Png🌑 +install_create_shortcut_windowed_SiteB🌕 add_file_handling_policy_approval_SiteB🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_NotShown🌑 check_pwa_window_created_SiteB_One🌑 +install_omnibox_icon_SiteB🌕 add_file_handling_policy_approval_SiteB🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_NotShown🌑 check_pwa_window_created_SiteB_One🌑 +install_policy_app_windowed_no_shortcut_SiteB🌓 add_file_handling_policy_approval_SiteB🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_NotShown🌑 check_pwa_window_created_SiteB_One🌑 +install_policy_app_windowed_shortcut_SiteB🌓 add_file_handling_policy_approval_SiteB🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_NotShown🌑 check_pwa_window_created_SiteB_One🌑 +install_menu_option_SiteB🌕 add_file_handling_policy_approval_SiteB🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_NotShown🌑 check_pwa_window_created_SiteB_One🌑 +install_create_shortcut_tabbed_SiteB🌕 add_file_handling_policy_approval_SiteB🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_NotShown🌑 check_pwa_window_created_SiteB_One🌑 +install_policy_app_tabbed_shortcut_SiteB🌓 add_file_handling_policy_approval_SiteB🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_NotShown🌑 check_pwa_window_created_SiteB_One🌑 +install_policy_app_tabbed_no_shortcut_SiteB🌓 add_file_handling_policy_approval_SiteB🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_NotShown🌑 check_pwa_window_created_SiteB_One🌑 +install_create_shortcut_windowed_SiteB🌕 add_file_handling_policy_approval_SiteB🌑 remove_file_handling_policy_approval_SiteB🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_omnibox_icon_SiteB🌕 add_file_handling_policy_approval_SiteB🌑 remove_file_handling_policy_approval_SiteB🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_windowed_no_shortcut_SiteB🌓 add_file_handling_policy_approval_SiteB🌑 remove_file_handling_policy_approval_SiteB🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_windowed_shortcut_SiteB🌓 add_file_handling_policy_approval_SiteB🌑 remove_file_handling_policy_approval_SiteB🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_menu_option_SiteB🌕 add_file_handling_policy_approval_SiteB🌑 remove_file_handling_policy_approval_SiteB🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_create_shortcut_tabbed_SiteB🌕 add_file_handling_policy_approval_SiteB🌑 remove_file_handling_policy_approval_SiteB🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_tabbed_shortcut_SiteB🌓 add_file_handling_policy_approval_SiteB🌑 remove_file_handling_policy_approval_SiteB🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_tabbed_no_shortcut_SiteB🌓 add_file_handling_policy_approval_SiteB🌑 remove_file_handling_policy_approval_SiteB🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑
diff --git a/chrome/test/webapps/coverage/coverage_mac.tsv b/chrome/test/webapps/coverage/coverage_mac.tsv index 5260ae1f..f49f5bb 100644 --- a/chrome/test/webapps/coverage/coverage_mac.tsv +++ b/chrome/test/webapps/coverage/coverage_mac.tsv
@@ -1,5 +1,5 @@ # This is a generated file. -# Full coverage: 59%, with partial coverage: 76% +# Full coverage: 51%, with partial coverage: 67% install_create_shortcut_windowed_SiteA🌕 manifest_update_title_SiteA🌑 accept_app_id_update_dialog🌑 close_pwa🌑 launch_from_menu_option_SiteA🌑 check_app_title_site_a_is_SiteAUpdated🌑 install_create_shortcut_windowed_SiteA🌕 manifest_update_title_SiteA🌑 accept_app_id_update_dialog🌑 close_pwa🌑 launch_from_launch_icon_SiteA🌑 check_app_title_site_a_is_SiteAUpdated🌑 install_create_shortcut_windowed_SiteA🌕 manifest_update_title_SiteA🌑 accept_app_id_update_dialog🌑 close_pwa🌑 launch_from_chrome_apps_SiteA🌑 check_app_title_site_a_is_SiteAUpdated🌑 @@ -782,3 +782,131 @@ install_create_shortcut_tabbed_SiteA🌕 set_open_in_window_SiteA🌓 check_app_in_list_windowed_SiteA🌓 install_create_shortcut_tabbed_SiteA🌕 set_open_in_window_SiteA🌓 navigate_browser_SiteA🌕 check_install_icon_not_shown🌕 install_create_shortcut_tabbed_SiteA🌕 set_open_in_window_SiteA🌓 navigate_browser_SiteA🌕 check_launch_icon_shown🌕 +install_create_shortcut_windowed_SiteB🌕 check_site_handles_file_SiteB_Txt🌑 check_site_handles_file_SiteB_Png🌑 +install_omnibox_icon_SiteB🌕 check_site_handles_file_SiteB_Txt🌑 check_site_handles_file_SiteB_Png🌑 +install_policy_app_windowed_no_shortcut_SiteB🌓 check_site_handles_file_SiteB_Txt🌑 check_site_handles_file_SiteB_Png🌑 +install_policy_app_windowed_shortcut_SiteB🌓 check_site_handles_file_SiteB_Txt🌑 check_site_handles_file_SiteB_Png🌑 +install_menu_option_SiteB🌕 check_site_handles_file_SiteB_Txt🌑 check_site_handles_file_SiteB_Png🌑 +install_create_shortcut_tabbed_SiteB🌕 check_site_handles_file_SiteB_Txt🌑 check_site_handles_file_SiteB_Png🌑 +install_policy_app_tabbed_shortcut_SiteB🌓 check_site_handles_file_SiteB_Txt🌑 check_site_handles_file_SiteB_Png🌑 +install_policy_app_tabbed_no_shortcut_SiteB🌓 check_site_handles_file_SiteB_Txt🌑 check_site_handles_file_SiteB_Png🌑 +install_create_shortcut_windowed_SiteB🌕 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_omnibox_icon_SiteB🌕 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_windowed_no_shortcut_SiteB🌓 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_windowed_shortcut_SiteB🌓 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_menu_option_SiteB🌕 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_create_shortcut_tabbed_SiteB🌕 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_tabbed_shortcut_SiteB🌓 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_tabbed_no_shortcut_SiteB🌓 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_create_shortcut_windowed_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_OneTextFile🌑 +install_omnibox_icon_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_OneTextFile🌑 +install_policy_app_windowed_no_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_OneTextFile🌑 +install_policy_app_windowed_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_OneTextFile🌑 +install_menu_option_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_OneTextFile🌑 +install_create_shortcut_tabbed_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_OneTextFile🌑 +install_policy_app_tabbed_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_OneTextFile🌑 +install_policy_app_tabbed_no_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_OneTextFile🌑 +install_create_shortcut_windowed_SiteB🌕 launch_file_MultipleTextFiles🌑 check_file_handling_dialog_Shown🌑 +install_omnibox_icon_SiteB🌕 launch_file_MultipleTextFiles🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_windowed_no_shortcut_SiteB🌓 launch_file_MultipleTextFiles🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_windowed_shortcut_SiteB🌓 launch_file_MultipleTextFiles🌑 check_file_handling_dialog_Shown🌑 +install_menu_option_SiteB🌕 launch_file_MultipleTextFiles🌑 check_file_handling_dialog_Shown🌑 +install_create_shortcut_tabbed_SiteB🌕 launch_file_MultipleTextFiles🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_tabbed_shortcut_SiteB🌓 launch_file_MultipleTextFiles🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_tabbed_no_shortcut_SiteB🌓 launch_file_MultipleTextFiles🌑 check_file_handling_dialog_Shown🌑 +install_create_shortcut_windowed_SiteB🌕 launch_file_MultipleTextFiles🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_MultipleTextFiles🌑 +install_omnibox_icon_SiteB🌕 launch_file_MultipleTextFiles🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_MultipleTextFiles🌑 +install_policy_app_windowed_no_shortcut_SiteB🌓 launch_file_MultipleTextFiles🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_MultipleTextFiles🌑 +install_policy_app_windowed_shortcut_SiteB🌓 launch_file_MultipleTextFiles🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_MultipleTextFiles🌑 +install_menu_option_SiteB🌕 launch_file_MultipleTextFiles🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_MultipleTextFiles🌑 +install_create_shortcut_tabbed_SiteB🌕 launch_file_MultipleTextFiles🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_MultipleTextFiles🌑 +install_policy_app_tabbed_shortcut_SiteB🌓 launch_file_MultipleTextFiles🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_MultipleTextFiles🌑 +install_policy_app_tabbed_no_shortcut_SiteB🌓 launch_file_MultipleTextFiles🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_MultipleTextFiles🌑 +install_create_shortcut_windowed_SiteB🌕 launch_file_OnePngFile🌑 check_file_handling_dialog_Shown🌑 +install_omnibox_icon_SiteB🌕 launch_file_OnePngFile🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_windowed_no_shortcut_SiteB🌓 launch_file_OnePngFile🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_windowed_shortcut_SiteB🌓 launch_file_OnePngFile🌑 check_file_handling_dialog_Shown🌑 +install_menu_option_SiteB🌕 launch_file_OnePngFile🌑 check_file_handling_dialog_Shown🌑 +install_create_shortcut_tabbed_SiteB🌕 launch_file_OnePngFile🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_tabbed_shortcut_SiteB🌓 launch_file_OnePngFile🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_tabbed_no_shortcut_SiteB🌓 launch_file_OnePngFile🌑 check_file_handling_dialog_Shown🌑 +install_create_shortcut_windowed_SiteB🌕 launch_file_OnePngFile🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_OnePngFile🌑 +install_omnibox_icon_SiteB🌕 launch_file_OnePngFile🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_OnePngFile🌑 +install_policy_app_windowed_no_shortcut_SiteB🌓 launch_file_OnePngFile🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_OnePngFile🌑 +install_policy_app_windowed_shortcut_SiteB🌓 launch_file_OnePngFile🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_OnePngFile🌑 +install_menu_option_SiteB🌕 launch_file_OnePngFile🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_OnePngFile🌑 +install_create_shortcut_tabbed_SiteB🌕 launch_file_OnePngFile🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_OnePngFile🌑 +install_policy_app_tabbed_shortcut_SiteB🌓 launch_file_OnePngFile🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_OnePngFile🌑 +install_policy_app_tabbed_no_shortcut_SiteB🌓 launch_file_OnePngFile🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_OnePngFile🌑 +install_create_shortcut_windowed_SiteB🌕 launch_file_MultiplePngFiles🌑 check_file_handling_dialog_Shown🌑 +install_omnibox_icon_SiteB🌕 launch_file_MultiplePngFiles🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_windowed_no_shortcut_SiteB🌓 launch_file_MultiplePngFiles🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_windowed_shortcut_SiteB🌓 launch_file_MultiplePngFiles🌑 check_file_handling_dialog_Shown🌑 +install_menu_option_SiteB🌕 launch_file_MultiplePngFiles🌑 check_file_handling_dialog_Shown🌑 +install_create_shortcut_tabbed_SiteB🌕 launch_file_MultiplePngFiles🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_tabbed_shortcut_SiteB🌓 launch_file_MultiplePngFiles🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_tabbed_no_shortcut_SiteB🌓 launch_file_MultiplePngFiles🌑 check_file_handling_dialog_Shown🌑 +install_create_shortcut_windowed_SiteB🌕 launch_file_MultiplePngFiles🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_Two🌑 check_files_loaded_in_site_SiteB_MultiplePngFiles🌑 +install_omnibox_icon_SiteB🌕 launch_file_MultiplePngFiles🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_Two🌑 check_files_loaded_in_site_SiteB_MultiplePngFiles🌑 +install_policy_app_windowed_no_shortcut_SiteB🌓 launch_file_MultiplePngFiles🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_Two🌑 check_files_loaded_in_site_SiteB_MultiplePngFiles🌑 +install_policy_app_windowed_shortcut_SiteB🌓 launch_file_MultiplePngFiles🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_Two🌑 check_files_loaded_in_site_SiteB_MultiplePngFiles🌑 +install_menu_option_SiteB🌕 launch_file_MultiplePngFiles🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_Two🌑 check_files_loaded_in_site_SiteB_MultiplePngFiles🌑 +install_create_shortcut_tabbed_SiteB🌕 launch_file_MultiplePngFiles🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_Two🌑 check_files_loaded_in_site_SiteB_MultiplePngFiles🌑 +install_policy_app_tabbed_shortcut_SiteB🌓 launch_file_MultiplePngFiles🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_Two🌑 check_files_loaded_in_site_SiteB_MultiplePngFiles🌑 +install_policy_app_tabbed_no_shortcut_SiteB🌓 launch_file_MultiplePngFiles🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_Two🌑 check_files_loaded_in_site_SiteB_MultiplePngFiles🌑 +install_create_shortcut_windowed_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Allow_Remember🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_NotShown🌑 check_pwa_window_created_SiteB_One🌑 +install_omnibox_icon_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Allow_Remember🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_NotShown🌑 check_pwa_window_created_SiteB_One🌑 +install_policy_app_windowed_no_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Allow_Remember🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_NotShown🌑 check_pwa_window_created_SiteB_One🌑 +install_policy_app_windowed_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Allow_Remember🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_NotShown🌑 check_pwa_window_created_SiteB_One🌑 +install_menu_option_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Allow_Remember🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_NotShown🌑 check_pwa_window_created_SiteB_One🌑 +install_create_shortcut_tabbed_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Allow_Remember🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_NotShown🌑 check_pwa_window_created_SiteB_One🌑 +install_policy_app_tabbed_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Allow_Remember🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_NotShown🌑 check_pwa_window_created_SiteB_One🌑 +install_policy_app_tabbed_no_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Allow_Remember🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_NotShown🌑 check_pwa_window_created_SiteB_One🌑 +install_create_shortcut_windowed_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Allow_AskAgain🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_omnibox_icon_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Allow_AskAgain🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_windowed_no_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Allow_AskAgain🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_windowed_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Allow_AskAgain🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_menu_option_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Allow_AskAgain🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_create_shortcut_tabbed_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Allow_AskAgain🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_tabbed_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Allow_AskAgain🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_tabbed_no_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Allow_AskAgain🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_create_shortcut_windowed_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Deny_AskAgain🌑 check_window_not_created🌑 check_site_handles_file_SiteB_Txt🌑 check_site_handles_file_SiteB_Png🌑 +install_omnibox_icon_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Deny_AskAgain🌑 check_window_not_created🌑 check_site_handles_file_SiteB_Txt🌑 check_site_handles_file_SiteB_Png🌑 +install_policy_app_windowed_no_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Deny_AskAgain🌑 check_window_not_created🌑 check_site_handles_file_SiteB_Txt🌑 check_site_handles_file_SiteB_Png🌑 +install_policy_app_windowed_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Deny_AskAgain🌑 check_window_not_created🌑 check_site_handles_file_SiteB_Txt🌑 check_site_handles_file_SiteB_Png🌑 +install_menu_option_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Deny_AskAgain🌑 check_window_not_created🌑 check_site_handles_file_SiteB_Txt🌑 check_site_handles_file_SiteB_Png🌑 +install_create_shortcut_tabbed_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Deny_AskAgain🌑 check_window_not_created🌑 check_site_handles_file_SiteB_Txt🌑 check_site_handles_file_SiteB_Png🌑 +install_policy_app_tabbed_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Deny_AskAgain🌑 check_window_not_created🌑 check_site_handles_file_SiteB_Txt🌑 check_site_handles_file_SiteB_Png🌑 +install_policy_app_tabbed_no_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Deny_AskAgain🌑 check_window_not_created🌑 check_site_handles_file_SiteB_Txt🌑 check_site_handles_file_SiteB_Png🌑 +install_create_shortcut_windowed_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Deny_AskAgain🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_omnibox_icon_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Deny_AskAgain🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_windowed_no_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Deny_AskAgain🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_windowed_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Deny_AskAgain🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_menu_option_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Deny_AskAgain🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_create_shortcut_tabbed_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Deny_AskAgain🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_tabbed_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Deny_AskAgain🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_tabbed_no_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Deny_AskAgain🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_create_shortcut_windowed_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Deny_Remember🌑 check_window_not_created🌑 check_site_not_handles_file_SiteB_Txt🌑 check_site_not_handles_file_SiteB_Png🌑 +install_omnibox_icon_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Deny_Remember🌑 check_window_not_created🌑 check_site_not_handles_file_SiteB_Txt🌑 check_site_not_handles_file_SiteB_Png🌑 +install_policy_app_windowed_no_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Deny_Remember🌑 check_window_not_created🌑 check_site_not_handles_file_SiteB_Txt🌑 check_site_not_handles_file_SiteB_Png🌑 +install_policy_app_windowed_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Deny_Remember🌑 check_window_not_created🌑 check_site_not_handles_file_SiteB_Txt🌑 check_site_not_handles_file_SiteB_Png🌑 +install_menu_option_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Deny_Remember🌑 check_window_not_created🌑 check_site_not_handles_file_SiteB_Txt🌑 check_site_not_handles_file_SiteB_Png🌑 +install_create_shortcut_tabbed_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Deny_Remember🌑 check_window_not_created🌑 check_site_not_handles_file_SiteB_Txt🌑 check_site_not_handles_file_SiteB_Png🌑 +install_policy_app_tabbed_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Deny_Remember🌑 check_window_not_created🌑 check_site_not_handles_file_SiteB_Txt🌑 check_site_not_handles_file_SiteB_Png🌑 +install_policy_app_tabbed_no_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Deny_Remember🌑 check_window_not_created🌑 check_site_not_handles_file_SiteB_Txt🌑 check_site_not_handles_file_SiteB_Png🌑 +install_create_shortcut_windowed_SiteB🌕 add_file_handling_policy_approval_SiteB🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_NotShown🌑 check_pwa_window_created_SiteB_One🌑 +install_omnibox_icon_SiteB🌕 add_file_handling_policy_approval_SiteB🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_NotShown🌑 check_pwa_window_created_SiteB_One🌑 +install_policy_app_windowed_no_shortcut_SiteB🌓 add_file_handling_policy_approval_SiteB🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_NotShown🌑 check_pwa_window_created_SiteB_One🌑 +install_policy_app_windowed_shortcut_SiteB🌓 add_file_handling_policy_approval_SiteB🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_NotShown🌑 check_pwa_window_created_SiteB_One🌑 +install_menu_option_SiteB🌕 add_file_handling_policy_approval_SiteB🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_NotShown🌑 check_pwa_window_created_SiteB_One🌑 +install_create_shortcut_tabbed_SiteB🌕 add_file_handling_policy_approval_SiteB🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_NotShown🌑 check_pwa_window_created_SiteB_One🌑 +install_policy_app_tabbed_shortcut_SiteB🌓 add_file_handling_policy_approval_SiteB🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_NotShown🌑 check_pwa_window_created_SiteB_One🌑 +install_policy_app_tabbed_no_shortcut_SiteB🌓 add_file_handling_policy_approval_SiteB🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_NotShown🌑 check_pwa_window_created_SiteB_One🌑 +install_create_shortcut_windowed_SiteB🌕 add_file_handling_policy_approval_SiteB🌑 remove_file_handling_policy_approval_SiteB🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_omnibox_icon_SiteB🌕 add_file_handling_policy_approval_SiteB🌑 remove_file_handling_policy_approval_SiteB🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_windowed_no_shortcut_SiteB🌓 add_file_handling_policy_approval_SiteB🌑 remove_file_handling_policy_approval_SiteB🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_windowed_shortcut_SiteB🌓 add_file_handling_policy_approval_SiteB🌑 remove_file_handling_policy_approval_SiteB🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_menu_option_SiteB🌕 add_file_handling_policy_approval_SiteB🌑 remove_file_handling_policy_approval_SiteB🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_create_shortcut_tabbed_SiteB🌕 add_file_handling_policy_approval_SiteB🌑 remove_file_handling_policy_approval_SiteB🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_tabbed_shortcut_SiteB🌓 add_file_handling_policy_approval_SiteB🌑 remove_file_handling_policy_approval_SiteB🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_tabbed_no_shortcut_SiteB🌓 add_file_handling_policy_approval_SiteB🌑 remove_file_handling_policy_approval_SiteB🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑
diff --git a/chrome/test/webapps/coverage/coverage_win.tsv b/chrome/test/webapps/coverage/coverage_win.tsv index 2d8a9f6..9c5bc8db 100644 --- a/chrome/test/webapps/coverage/coverage_win.tsv +++ b/chrome/test/webapps/coverage/coverage_win.tsv
@@ -1,5 +1,5 @@ # This is a generated file. -# Full coverage: 65%, with partial coverage: 87% +# Full coverage: 56%, with partial coverage: 76% install_create_shortcut_windowed_SiteA🌕 manifest_update_title_SiteA🌑 accept_app_id_update_dialog🌑 close_pwa🌑 launch_from_menu_option_SiteA🌑 check_app_title_site_a_is_SiteAUpdated🌑 install_create_shortcut_windowed_SiteA🌕 manifest_update_title_SiteA🌑 accept_app_id_update_dialog🌑 close_pwa🌑 launch_from_launch_icon_SiteA🌑 check_app_title_site_a_is_SiteAUpdated🌑 install_create_shortcut_windowed_SiteA🌕 manifest_update_title_SiteA🌑 accept_app_id_update_dialog🌑 close_pwa🌑 launch_from_chrome_apps_SiteA🌑 check_app_title_site_a_is_SiteAUpdated🌑 @@ -782,3 +782,131 @@ install_create_shortcut_tabbed_SiteA🌕 set_open_in_window_SiteA🌓 check_app_in_list_windowed_SiteA🌓 install_create_shortcut_tabbed_SiteA🌕 set_open_in_window_SiteA🌓 navigate_browser_SiteA🌕 check_install_icon_not_shown🌕 install_create_shortcut_tabbed_SiteA🌕 set_open_in_window_SiteA🌓 navigate_browser_SiteA🌕 check_launch_icon_shown🌕 +install_create_shortcut_windowed_SiteB🌕 check_site_handles_file_SiteB_Txt🌑 check_site_handles_file_SiteB_Png🌑 +install_omnibox_icon_SiteB🌕 check_site_handles_file_SiteB_Txt🌑 check_site_handles_file_SiteB_Png🌑 +install_policy_app_windowed_no_shortcut_SiteB🌓 check_site_handles_file_SiteB_Txt🌑 check_site_handles_file_SiteB_Png🌑 +install_policy_app_windowed_shortcut_SiteB🌓 check_site_handles_file_SiteB_Txt🌑 check_site_handles_file_SiteB_Png🌑 +install_menu_option_SiteB🌕 check_site_handles_file_SiteB_Txt🌑 check_site_handles_file_SiteB_Png🌑 +install_create_shortcut_tabbed_SiteB🌕 check_site_handles_file_SiteB_Txt🌑 check_site_handles_file_SiteB_Png🌑 +install_policy_app_tabbed_shortcut_SiteB🌓 check_site_handles_file_SiteB_Txt🌑 check_site_handles_file_SiteB_Png🌑 +install_policy_app_tabbed_no_shortcut_SiteB🌓 check_site_handles_file_SiteB_Txt🌑 check_site_handles_file_SiteB_Png🌑 +install_create_shortcut_windowed_SiteB🌕 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_omnibox_icon_SiteB🌕 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_windowed_no_shortcut_SiteB🌓 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_windowed_shortcut_SiteB🌓 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_menu_option_SiteB🌕 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_create_shortcut_tabbed_SiteB🌕 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_tabbed_shortcut_SiteB🌓 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_tabbed_no_shortcut_SiteB🌓 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_create_shortcut_windowed_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_OneTextFile🌑 +install_omnibox_icon_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_OneTextFile🌑 +install_policy_app_windowed_no_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_OneTextFile🌑 +install_policy_app_windowed_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_OneTextFile🌑 +install_menu_option_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_OneTextFile🌑 +install_create_shortcut_tabbed_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_OneTextFile🌑 +install_policy_app_tabbed_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_OneTextFile🌑 +install_policy_app_tabbed_no_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_OneTextFile🌑 +install_create_shortcut_windowed_SiteB🌕 launch_file_MultipleTextFiles🌑 check_file_handling_dialog_Shown🌑 +install_omnibox_icon_SiteB🌕 launch_file_MultipleTextFiles🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_windowed_no_shortcut_SiteB🌓 launch_file_MultipleTextFiles🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_windowed_shortcut_SiteB🌓 launch_file_MultipleTextFiles🌑 check_file_handling_dialog_Shown🌑 +install_menu_option_SiteB🌕 launch_file_MultipleTextFiles🌑 check_file_handling_dialog_Shown🌑 +install_create_shortcut_tabbed_SiteB🌕 launch_file_MultipleTextFiles🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_tabbed_shortcut_SiteB🌓 launch_file_MultipleTextFiles🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_tabbed_no_shortcut_SiteB🌓 launch_file_MultipleTextFiles🌑 check_file_handling_dialog_Shown🌑 +install_create_shortcut_windowed_SiteB🌕 launch_file_MultipleTextFiles🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_MultipleTextFiles🌑 +install_omnibox_icon_SiteB🌕 launch_file_MultipleTextFiles🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_MultipleTextFiles🌑 +install_policy_app_windowed_no_shortcut_SiteB🌓 launch_file_MultipleTextFiles🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_MultipleTextFiles🌑 +install_policy_app_windowed_shortcut_SiteB🌓 launch_file_MultipleTextFiles🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_MultipleTextFiles🌑 +install_menu_option_SiteB🌕 launch_file_MultipleTextFiles🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_MultipleTextFiles🌑 +install_create_shortcut_tabbed_SiteB🌕 launch_file_MultipleTextFiles🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_MultipleTextFiles🌑 +install_policy_app_tabbed_shortcut_SiteB🌓 launch_file_MultipleTextFiles🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_MultipleTextFiles🌑 +install_policy_app_tabbed_no_shortcut_SiteB🌓 launch_file_MultipleTextFiles🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_MultipleTextFiles🌑 +install_create_shortcut_windowed_SiteB🌕 launch_file_OnePngFile🌑 check_file_handling_dialog_Shown🌑 +install_omnibox_icon_SiteB🌕 launch_file_OnePngFile🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_windowed_no_shortcut_SiteB🌓 launch_file_OnePngFile🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_windowed_shortcut_SiteB🌓 launch_file_OnePngFile🌑 check_file_handling_dialog_Shown🌑 +install_menu_option_SiteB🌕 launch_file_OnePngFile🌑 check_file_handling_dialog_Shown🌑 +install_create_shortcut_tabbed_SiteB🌕 launch_file_OnePngFile🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_tabbed_shortcut_SiteB🌓 launch_file_OnePngFile🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_tabbed_no_shortcut_SiteB🌓 launch_file_OnePngFile🌑 check_file_handling_dialog_Shown🌑 +install_create_shortcut_windowed_SiteB🌕 launch_file_OnePngFile🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_OnePngFile🌑 +install_omnibox_icon_SiteB🌕 launch_file_OnePngFile🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_OnePngFile🌑 +install_policy_app_windowed_no_shortcut_SiteB🌓 launch_file_OnePngFile🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_OnePngFile🌑 +install_policy_app_windowed_shortcut_SiteB🌓 launch_file_OnePngFile🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_OnePngFile🌑 +install_menu_option_SiteB🌕 launch_file_OnePngFile🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_OnePngFile🌑 +install_create_shortcut_tabbed_SiteB🌕 launch_file_OnePngFile🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_OnePngFile🌑 +install_policy_app_tabbed_shortcut_SiteB🌓 launch_file_OnePngFile🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_OnePngFile🌑 +install_policy_app_tabbed_no_shortcut_SiteB🌓 launch_file_OnePngFile🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_One🌑 check_files_loaded_in_site_SiteB_OnePngFile🌑 +install_create_shortcut_windowed_SiteB🌕 launch_file_MultiplePngFiles🌑 check_file_handling_dialog_Shown🌑 +install_omnibox_icon_SiteB🌕 launch_file_MultiplePngFiles🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_windowed_no_shortcut_SiteB🌓 launch_file_MultiplePngFiles🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_windowed_shortcut_SiteB🌓 launch_file_MultiplePngFiles🌑 check_file_handling_dialog_Shown🌑 +install_menu_option_SiteB🌕 launch_file_MultiplePngFiles🌑 check_file_handling_dialog_Shown🌑 +install_create_shortcut_tabbed_SiteB🌕 launch_file_MultiplePngFiles🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_tabbed_shortcut_SiteB🌓 launch_file_MultiplePngFiles🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_tabbed_no_shortcut_SiteB🌓 launch_file_MultiplePngFiles🌑 check_file_handling_dialog_Shown🌑 +install_create_shortcut_windowed_SiteB🌕 launch_file_MultiplePngFiles🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_Two🌑 check_files_loaded_in_site_SiteB_MultiplePngFiles🌑 +install_omnibox_icon_SiteB🌕 launch_file_MultiplePngFiles🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_Two🌑 check_files_loaded_in_site_SiteB_MultiplePngFiles🌑 +install_policy_app_windowed_no_shortcut_SiteB🌓 launch_file_MultiplePngFiles🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_Two🌑 check_files_loaded_in_site_SiteB_MultiplePngFiles🌑 +install_policy_app_windowed_shortcut_SiteB🌓 launch_file_MultiplePngFiles🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_Two🌑 check_files_loaded_in_site_SiteB_MultiplePngFiles🌑 +install_menu_option_SiteB🌕 launch_file_MultiplePngFiles🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_Two🌑 check_files_loaded_in_site_SiteB_MultiplePngFiles🌑 +install_create_shortcut_tabbed_SiteB🌕 launch_file_MultiplePngFiles🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_Two🌑 check_files_loaded_in_site_SiteB_MultiplePngFiles🌑 +install_policy_app_tabbed_shortcut_SiteB🌓 launch_file_MultiplePngFiles🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_Two🌑 check_files_loaded_in_site_SiteB_MultiplePngFiles🌑 +install_policy_app_tabbed_no_shortcut_SiteB🌓 launch_file_MultiplePngFiles🌑 file_handling_dialog_Allow_AskAgain🌑 check_pwa_window_created_SiteB_Two🌑 check_files_loaded_in_site_SiteB_MultiplePngFiles🌑 +install_create_shortcut_windowed_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Allow_Remember🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_NotShown🌑 check_pwa_window_created_SiteB_One🌑 +install_omnibox_icon_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Allow_Remember🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_NotShown🌑 check_pwa_window_created_SiteB_One🌑 +install_policy_app_windowed_no_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Allow_Remember🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_NotShown🌑 check_pwa_window_created_SiteB_One🌑 +install_policy_app_windowed_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Allow_Remember🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_NotShown🌑 check_pwa_window_created_SiteB_One🌑 +install_menu_option_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Allow_Remember🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_NotShown🌑 check_pwa_window_created_SiteB_One🌑 +install_create_shortcut_tabbed_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Allow_Remember🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_NotShown🌑 check_pwa_window_created_SiteB_One🌑 +install_policy_app_tabbed_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Allow_Remember🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_NotShown🌑 check_pwa_window_created_SiteB_One🌑 +install_policy_app_tabbed_no_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Allow_Remember🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_NotShown🌑 check_pwa_window_created_SiteB_One🌑 +install_create_shortcut_windowed_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Allow_AskAgain🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_omnibox_icon_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Allow_AskAgain🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_windowed_no_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Allow_AskAgain🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_windowed_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Allow_AskAgain🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_menu_option_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Allow_AskAgain🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_create_shortcut_tabbed_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Allow_AskAgain🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_tabbed_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Allow_AskAgain🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_tabbed_no_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Allow_AskAgain🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_create_shortcut_windowed_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Deny_AskAgain🌑 check_window_not_created🌑 check_site_handles_file_SiteB_Txt🌑 check_site_handles_file_SiteB_Png🌑 +install_omnibox_icon_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Deny_AskAgain🌑 check_window_not_created🌑 check_site_handles_file_SiteB_Txt🌑 check_site_handles_file_SiteB_Png🌑 +install_policy_app_windowed_no_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Deny_AskAgain🌑 check_window_not_created🌑 check_site_handles_file_SiteB_Txt🌑 check_site_handles_file_SiteB_Png🌑 +install_policy_app_windowed_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Deny_AskAgain🌑 check_window_not_created🌑 check_site_handles_file_SiteB_Txt🌑 check_site_handles_file_SiteB_Png🌑 +install_menu_option_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Deny_AskAgain🌑 check_window_not_created🌑 check_site_handles_file_SiteB_Txt🌑 check_site_handles_file_SiteB_Png🌑 +install_create_shortcut_tabbed_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Deny_AskAgain🌑 check_window_not_created🌑 check_site_handles_file_SiteB_Txt🌑 check_site_handles_file_SiteB_Png🌑 +install_policy_app_tabbed_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Deny_AskAgain🌑 check_window_not_created🌑 check_site_handles_file_SiteB_Txt🌑 check_site_handles_file_SiteB_Png🌑 +install_policy_app_tabbed_no_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Deny_AskAgain🌑 check_window_not_created🌑 check_site_handles_file_SiteB_Txt🌑 check_site_handles_file_SiteB_Png🌑 +install_create_shortcut_windowed_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Deny_AskAgain🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_omnibox_icon_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Deny_AskAgain🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_windowed_no_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Deny_AskAgain🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_windowed_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Deny_AskAgain🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_menu_option_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Deny_AskAgain🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_create_shortcut_tabbed_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Deny_AskAgain🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_tabbed_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Deny_AskAgain🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_tabbed_no_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Deny_AskAgain🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_create_shortcut_windowed_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Deny_Remember🌑 check_window_not_created🌑 check_site_not_handles_file_SiteB_Txt🌑 check_site_not_handles_file_SiteB_Png🌑 +install_omnibox_icon_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Deny_Remember🌑 check_window_not_created🌑 check_site_not_handles_file_SiteB_Txt🌑 check_site_not_handles_file_SiteB_Png🌑 +install_policy_app_windowed_no_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Deny_Remember🌑 check_window_not_created🌑 check_site_not_handles_file_SiteB_Txt🌑 check_site_not_handles_file_SiteB_Png🌑 +install_policy_app_windowed_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Deny_Remember🌑 check_window_not_created🌑 check_site_not_handles_file_SiteB_Txt🌑 check_site_not_handles_file_SiteB_Png🌑 +install_menu_option_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Deny_Remember🌑 check_window_not_created🌑 check_site_not_handles_file_SiteB_Txt🌑 check_site_not_handles_file_SiteB_Png🌑 +install_create_shortcut_tabbed_SiteB🌕 launch_file_OneTextFile🌑 file_handling_dialog_Deny_Remember🌑 check_window_not_created🌑 check_site_not_handles_file_SiteB_Txt🌑 check_site_not_handles_file_SiteB_Png🌑 +install_policy_app_tabbed_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Deny_Remember🌑 check_window_not_created🌑 check_site_not_handles_file_SiteB_Txt🌑 check_site_not_handles_file_SiteB_Png🌑 +install_policy_app_tabbed_no_shortcut_SiteB🌓 launch_file_OneTextFile🌑 file_handling_dialog_Deny_Remember🌑 check_window_not_created🌑 check_site_not_handles_file_SiteB_Txt🌑 check_site_not_handles_file_SiteB_Png🌑 +install_create_shortcut_windowed_SiteB🌕 add_file_handling_policy_approval_SiteB🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_NotShown🌑 check_pwa_window_created_SiteB_One🌑 +install_omnibox_icon_SiteB🌕 add_file_handling_policy_approval_SiteB🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_NotShown🌑 check_pwa_window_created_SiteB_One🌑 +install_policy_app_windowed_no_shortcut_SiteB🌓 add_file_handling_policy_approval_SiteB🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_NotShown🌑 check_pwa_window_created_SiteB_One🌑 +install_policy_app_windowed_shortcut_SiteB🌓 add_file_handling_policy_approval_SiteB🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_NotShown🌑 check_pwa_window_created_SiteB_One🌑 +install_menu_option_SiteB🌕 add_file_handling_policy_approval_SiteB🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_NotShown🌑 check_pwa_window_created_SiteB_One🌑 +install_create_shortcut_tabbed_SiteB🌕 add_file_handling_policy_approval_SiteB🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_NotShown🌑 check_pwa_window_created_SiteB_One🌑 +install_policy_app_tabbed_shortcut_SiteB🌓 add_file_handling_policy_approval_SiteB🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_NotShown🌑 check_pwa_window_created_SiteB_One🌑 +install_policy_app_tabbed_no_shortcut_SiteB🌓 add_file_handling_policy_approval_SiteB🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_NotShown🌑 check_pwa_window_created_SiteB_One🌑 +install_create_shortcut_windowed_SiteB🌕 add_file_handling_policy_approval_SiteB🌑 remove_file_handling_policy_approval_SiteB🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_omnibox_icon_SiteB🌕 add_file_handling_policy_approval_SiteB🌑 remove_file_handling_policy_approval_SiteB🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_windowed_no_shortcut_SiteB🌓 add_file_handling_policy_approval_SiteB🌑 remove_file_handling_policy_approval_SiteB🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_windowed_shortcut_SiteB🌓 add_file_handling_policy_approval_SiteB🌑 remove_file_handling_policy_approval_SiteB🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_menu_option_SiteB🌕 add_file_handling_policy_approval_SiteB🌑 remove_file_handling_policy_approval_SiteB🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_create_shortcut_tabbed_SiteB🌕 add_file_handling_policy_approval_SiteB🌑 remove_file_handling_policy_approval_SiteB🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_tabbed_shortcut_SiteB🌓 add_file_handling_policy_approval_SiteB🌑 remove_file_handling_policy_approval_SiteB🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑 +install_policy_app_tabbed_no_shortcut_SiteB🌓 add_file_handling_policy_approval_SiteB🌑 remove_file_handling_policy_approval_SiteB🌑 launch_file_OneTextFile🌑 check_file_handling_dialog_Shown🌑
diff --git a/chrome/test/webapps/data/actions.md b/chrome/test/webapps/data/actions.md index f2bbedd..3a6e35d 100644 --- a/chrome/test/webapps/data/actions.md +++ b/chrome/test/webapps/data/actions.md
@@ -20,7 +20,7 @@ TODO(dmurph): Possibly this table up into markdown-header section. -| # Action base name | Argument Types | Output Actions | Unique Identifier (next: 123) | Status (WIP, Implemented, Not Implemented, Parameterized) | Description | Metadata, implementation bug, etc | +| # Action base name | Argument Types | Output Actions | Unique Identifier (next: 128) | Status (WIP, Implemented, Not Implemented, Parameterized) | Description | Metadata, implementation bug, etc | | --- | --- | --- | --- | --- | --- | --- | | # Badging | | check_app_badge_empty | Site | | 2 | Not Implemented | Check that the 'badge' on the app icon is empty | | @@ -107,6 +107,8 @@ | check_user_cannot_set_run_on_os_login | Site | | 111 | Implemented | Check user can't change the app's run_on_os_login state. | | | check_window_closed | | | 23 | Implemented | The window was closed | | | check_window_created | | | 24 | Implemented | A window was created. | | +| check_window_not_created | | | 127 | Not Implemented | A window was created. | P2 | +| check_pwa_window_created | Site, Number | | 123 | Implemented | A given number of windows were created for the given pwa. | | | check_window_display_minimal | | | 25 | Implemented | Check that the window is a PWA window, and has minimal browser controls. | | | check_window_display_standalone | | | 26 | Implemented | Check that the window is a PWA window, and has no browser controls. | | | close_custom_toolbar | | | 27 | Implemented | Press the 'x' button on the custom toolbar that is towards the top of the WebApp window. | | @@ -142,12 +144,15 @@ | sync_turn_off | | | 41 | Implemented | Turn chrome sync off for "Apps": chrome://settings/syncSetup/advanced | | | sync_turn_on | | | 42 | Implemented | Turn chrome sync on for "Apps": chrome://settings/syncSetup/advanced | | | switch_incognito_profile | | | 73 | Not Implemented | Switch to using incognito mode | P2 | -| check_site_handles_file | Site, FileExtension | | 118 | Not Implemented | | | | # File handling | +| check_site_handles_file | Site, FileExtension | | 118 | Not Implemented | | | +| check_site_not_handles_file | Site, FileExtension | | 122 | Not Implemented | | | | check_file_handling_dialog | IsShown | | 119 | Not Implemented | | | | launch_file | FilesOptions | | 120 | Not Implemented | | | -| accept_file_handling_dialog | | | 121 | Not Implemented | | | -| deny_file_handling_dialog | | | 122 | Not Implemented | | | +| file_handling_dialog | AllowDenyOptions, AskAgainOptions | | 121 | Not Implemented | | | +| check_files_loaded_in_site | Site, FilesOptions | | 126 | Not Implemented | Check that the appropriate file contents have loaded in in PWA windows. | | +| add_file_handling_policy_approval | Site | | 124 | Not Implemented | | | +| remove_file_handling_policy_approval | Site | | 125 | Not Implemented | | | | # Window Controls Overlay | check_window_controls_overlay_toggle | Site, IsShown | | 112 | WIP | | | | check_window_controls_overlay | Site, IsOn | | 113 | WIP | | |
diff --git a/chrome/test/webapps/data/critical_user_journeys.md b/chrome/test/webapps/data/critical_user_journeys.md index 7b29194..748220ed8 100644 --- a/chrome/test/webapps/data/critical_user_journeys.md +++ b/chrome/test/webapps/data/critical_user_journeys.md
@@ -6,6 +6,8 @@ TODO(dmurph): Move more documentation here. https://crbug.com/1314822 +[[TOC]] + ## How this file is parsed The tables are parsed in this file as critical user journeys. Lines are considered a CUJ if: @@ -259,3 +261,27 @@ | #WMLC | install_windowed(SiteB) | manifest_update_display(SiteB, WCO) | await_manifest_update(SiteB) | launch(SiteB) | enable_window_controls_overlay(SiteB) | check_window_controls_overlay_toggle(SiteB, Shown) | | #WMLC | install_windowed(SiteWCO) | manifest_update_display(SiteWCO, Standalone) | await_manifest_update(SiteWCO) | launch(SiteWCO) | check_window_controls_overlay_toggle(SiteWCO, NotShown) | | #WMLC | install_windowed(SiteWCO) | manifest_update_display(SiteWCO, Standalone) | await_manifest_update(SiteWCO) | launch(SiteWCO) | check_window_controls_overlay(SiteWCO, Off) | + +## File Handling + +| #Platforms | Test -> | | | | | | | | | | | | | | | | | +| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | +| WMLC | install(SiteB) | check_site_handles_file(SiteB, Txt) | check_site_handles_file(SiteB, Png) | +| # Single open & multiple open behavior | +| WMLC | install(SiteB) | launch_file(OneTextFile) | check_file_handling_dialog(Shown) | +| WMLC | install(SiteB) | launch_file(OneTextFile) | file_handling_dialog(Allow, AskAgain) | check_pwa_window_created(SiteB, One) | check_files_loaded_in_site(SiteB, OneTextFile) | +| WMLC | install(SiteB) | launch_file(MultipleTextFiles) | check_file_handling_dialog(Shown) +| WMLC | install(SiteB) | launch_file(MultipleTextFiles) | file_handling_dialog(Allow, AskAgain) | check_pwa_window_created(SiteB, One) | check_files_loaded_in_site(SiteB, MultipleTextFiles) | +| WMLC | install(SiteB) | launch_file(OnePngFile) | check_file_handling_dialog(Shown) | +| WMLC | install(SiteB) | launch_file(OnePngFile) | file_handling_dialog(Allow, AskAgain) | check_pwa_window_created(SiteB, One) | check_files_loaded_in_site(SiteB, OnePngFile) | +| WMLC | install(SiteB) | launch_file(MultiplePngFiles) | check_file_handling_dialog(Shown) | +| WMLC | install(SiteB) | launch_file(MultiplePngFiles) | file_handling_dialog(Allow, AskAgain) | check_pwa_window_created(SiteB, Two) | check_files_loaded_in_site(SiteB, MultiplePngFiles) | +| # Dialog options | +| WMLC | install(SiteB) | launch_file(OneTextFile) | file_handling_dialog(Allow, Remember) | launch_file(OneTextFile) | check_file_handling_dialog(NotShown) | check_pwa_window_created(SiteB, One) | +| WMLC | install(SiteB) | launch_file(OneTextFile) | file_handling_dialog(Allow, AskAgain) | launch_file(OneTextFile) | check_file_handling_dialog(Shown) | +| WMLC | install(SiteB) | launch_file(OneTextFile) | file_handling_dialog(Deny, AskAgain) | check_window_not_created | check_site_handles_file(SiteB, Txt) | check_site_handles_file(SiteB, Png) | +| WMLC | install(SiteB) | launch_file(OneTextFile) | file_handling_dialog(Deny, AskAgain) | launch_file(OneTextFile) | check_file_handling_dialog(Shown) | +| WMLC | install(SiteB) | launch_file(OneTextFile) | file_handling_dialog(Deny, Remember) | check_window_not_created | check_site_not_handles_file(SiteB, Txt) | check_site_not_handles_file(SiteB, Png) | +| # Policy approval | +| WMLC | install(SiteB) | add_file_handling_policy_approval(SiteB) | launch_file(OneTextFile) | check_file_handling_dialog(NotShown) | check_pwa_window_created(SiteB, One) | +| WMLC | install(SiteB) | add_file_handling_policy_approval(SiteB) | remove_file_handling_policy_approval(SiteB) | launch_file(OneTextFile) | check_file_handling_dialog(Shown) |
diff --git a/chrome/test/webapps/data/enums.md b/chrome/test/webapps/data/enums.md index a55361f7..fbb24ef 100644 --- a/chrome/test/webapps/data/enums.md +++ b/chrome/test/webapps/data/enums.md
@@ -20,7 +20,7 @@ | #Enum Name | Values (* = default) | | | | | | | | --- | --- | --- | --- | --- | --- | --- | --- | -| Site | SiteA* | SiteB | SiteC | SiteAFoo | SiteABar | SiteWco | kSiteIsolatedApp | | +| Site | SiteA* | SiteB | SiteC | SiteAFoo | SiteABar | SiteWco | SiteIsolatedApp | | | InstallableSite | SiteA* | SiteB | SiteAFoo | SiteABar | SiteWco | | | | Scope | SiteARoot | | | | | Title | SiteA | SiteAUpdated | | | | | | @@ -34,3 +34,5 @@ | Location | StartUrl | FileHandleUrlForTxt | FileHandleUrlForPng | | | | | | Number | One | Two | | | | | | | FilesOptions | OneTextFile | MultipleTextFiles | OnePngFile | MultiplePngFiles | AllTestAndPngFiles | | | +| AllowDenyOptions | Allow | Deny | +| AskAgainOptions | AskAgain | Remember |
diff --git a/chrome/utility/services.cc b/chrome/utility/services.cc index e27ddfac..97aaeac 100644 --- a/chrome/utility/services.cc +++ b/chrome/utility/services.cc
@@ -303,7 +303,7 @@ auto RunImeService( mojo::PendingReceiver<ash::ime::mojom::ImeService> receiver) { return std::make_unique<ash::ime::ImeService>( - std::move(receiver), ash::ime::ImeSharedLibImpl::GetInstance(), + std::move(receiver), ash::ime::ImeDecoderImpl::GetInstance(), std::make_unique<ash::ime::FieldTrialParamsRetrieverImpl>()); }
diff --git a/chromeos/chromeos_strings.grd b/chromeos/chromeos_strings.grd index 71de70a..54d7b5f 100644 --- a/chromeos/chromeos_strings.grd +++ b/chromeos/chromeos_strings.grd
@@ -2075,6 +2075,9 @@ <message name="IDS_PERSONALIZATION_APP_WALLPAPER_LABEL" desc="Label for wallpaper element in personalization hub"> Wallpaper </message> + <message name="IDS_PERSONALIZATION_APP_DEFAULT_WALLPAPER" desc="Label for the device default wallpaper"> + Default Wallpaper + </message> <message name="IDS_PERSONALIZATION_APP_BACK_BUTTON" desc="Aria label for the back button to return to a prior page"> Back to <ph name="PAGE_NAME">$1<ex>Wallpaper</ex></ph> </message>
diff --git a/chromeos/chromeos_strings_grd/IDS_PERSONALIZATION_APP_DEFAULT_WALLPAPER.png.sha1 b/chromeos/chromeos_strings_grd/IDS_PERSONALIZATION_APP_DEFAULT_WALLPAPER.png.sha1 new file mode 100644 index 0000000..e4169309 --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_PERSONALIZATION_APP_DEFAULT_WALLPAPER.png.sha1
@@ -0,0 +1 @@ +b5ec9f9fbe71ca0fccc083668bc7651ec7cc36ea \ No newline at end of file
diff --git a/chromeos/components/test/data/onc/policy/policy_allow_cellular_sim_lock.onc b/chromeos/components/test/data/onc/policy/policy_allow_cellular_sim_lock.onc index 4740612..05e08862 100644 --- a/chromeos/components/test/data/onc/policy/policy_allow_cellular_sim_lock.onc +++ b/chromeos/components/test/data/onc/policy/policy_allow_cellular_sim_lock.onc
@@ -1,8 +1,16 @@ { "NetworkConfigurations": [ + { + "GUID": "policy_cellular", + "Type": "Cellular", + "Name": "Managed cellular", + "Cellular": { + "SMDPAddress": "1$SMDP.GSMA.COM$00000-00000-00000-000-0001" + } + } ], "GlobalNetworkConfiguration": { "AllowCellularSimLock": false }, "Type": "UnencryptedConfiguration" -} \ No newline at end of file +}
diff --git a/chromeos/components/test/data/onc/policy/policy_allow_only_policy_cellular_networks.onc b/chromeos/components/test/data/onc/policy/policy_allow_only_policy_cellular_networks.onc index 2a95100..3ceb493 100644 --- a/chromeos/components/test/data/onc/policy/policy_allow_only_policy_cellular_networks.onc +++ b/chromeos/components/test/data/onc/policy/policy_allow_only_policy_cellular_networks.onc
@@ -1,8 +1,16 @@ { "NetworkConfigurations": [ + { + "GUID": "policy_cellular", + "Type": "Cellular", + "Name": "Managed cellular", + "Cellular": { + "SMDPAddress": "1$SMDP.GSMA.COM$00000-00000-00000-000-0001" + } + } ], "GlobalNetworkConfiguration": { "AllowOnlyPolicyCellularNetworks": true }, "Type": "UnencryptedConfiguration" -} \ No newline at end of file +}
diff --git a/chromeos/components/test/data/onc/policy/policy_empty_global_network_configuration.onc b/chromeos/components/test/data/onc/policy/policy_empty_global_network_configuration.onc new file mode 100644 index 0000000..35d96164 --- /dev/null +++ b/chromeos/components/test/data/onc/policy/policy_empty_global_network_configuration.onc
@@ -0,0 +1,6 @@ +{ + "NetworkConfigurations": [ ], + "GlobalNetworkConfiguration": { }, + "Type": "UnencryptedConfiguration" +} +
diff --git a/chromeos/components/test/data/onc/policy/policy_exhaustive_global_network_configuration.onc b/chromeos/components/test/data/onc/policy/policy_exhaustive_global_network_configuration.onc new file mode 100644 index 0000000..6ded3612 --- /dev/null +++ b/chromeos/components/test/data/onc/policy/policy_exhaustive_global_network_configuration.onc
@@ -0,0 +1,13 @@ +{ + "NetworkConfigurations": [ ], + "GlobalNetworkConfiguration": { + "AllowOnlyPolicyCellularNetworks": true, + "AllowOnlyPolicyNetworksToAutoconnect": true, + "AllowOnlyPolicyNetworksToConnect": true, + "AllowOnlyPolicyNetworksToConnectIfAvailable": true, + "BlockedHexSSIDs": [ "blocked_ssid" ], + "DisableNetworkTypes": [ "VPN" ] + }, + "Type": "UnencryptedConfiguration" +} +
diff --git a/chromeos/network/managed_network_configuration_handler_impl.cc b/chromeos/network/managed_network_configuration_handler_impl.cc index 5db8560..c39717fc 100644 --- a/chromeos/network/managed_network_configuration_handler_impl.cc +++ b/chromeos/network/managed_network_configuration_handler_impl.cc
@@ -535,7 +535,7 @@ policies_by_user_[userhash] = base::WrapUnique(policies); } - policies->global_network_config.MergeDictionary(&global_network_config); + policies->global_network_config = global_network_config.Clone(); // Update prohibited technologies. if (prohibited_technologies_handler_) {
diff --git a/chromeos/network/managed_network_configuration_handler_unittest.cc b/chromeos/network/managed_network_configuration_handler_unittest.cc index 8f492bd..ff2999e 100644 --- a/chromeos/network/managed_network_configuration_handler_unittest.cc +++ b/chromeos/network/managed_network_configuration_handler_unittest.cc
@@ -1065,12 +1065,9 @@ EXPECT_CALL(*network_state_handler_, UpdateBlockedCellularNetworks(true)) .Times(2); - // Set 'AllowOnlyPolicyCellularNetworks' policy and another arbitrary cellular - // policy. + // Set 'AllowOnlyPolicyCellularNetworks' policy. SetPolicy(::onc::ONC_SOURCE_DEVICE_POLICY, std::string(), "policy/policy_allow_only_policy_cellular_networks.onc"); - SetPolicy(::onc::ONC_SOURCE_DEVICE_POLICY, std::string(), - "policy/policy_cellular.onc"); FastForwardProfileRefreshDelay(); base::RunLoop().RunUntilIdle(); @@ -1087,12 +1084,9 @@ base::test::ScopedFeatureList feature_list; feature_list.InitAndEnableFeature(ash::features::kSimLockPolicy); - // Set 'AllowCellularSimLock' policy and another arbitrary cellular - // policy. + // Set 'AllowCellularSimLock' policy. SetPolicy(::onc::ONC_SOURCE_DEVICE_POLICY, std::string(), "policy/policy_allow_cellular_sim_lock.onc"); - SetPolicy(::onc::ONC_SOURCE_DEVICE_POLICY, std::string(), - "policy/policy_cellular.onc"); base::RunLoop().RunUntilIdle(); // Check ManagedNetworkConfigurationHandler policy accessors. @@ -1153,6 +1147,54 @@ EXPECT_EQ(blocked, managed_handler()->GetBlockedHexSSIDs()); } +TEST_F(ManagedNetworkConfigurationHandlerTest, WipeGlobalNetworkConfiguration) { + InitializeStandardProfiles(); + + // A user policy must be present to apply some global config, e.g. blocked + // SSIDs, even though they are actually given in device policy. It does not + // really matter which user policy is configured for this test. + SetPolicy(::onc::ONC_SOURCE_USER_POLICY, kUser1, "policy/policy_wifi1.onc"); + + // Step 1: Apply a device policy which sets all possible entries in + // GlobalNetworkConfiguration. + EXPECT_CALL( + *network_state_handler_, + UpdateBlockedWifiNetworks(/*only_managed=*/true, /*available_only=*/true, + std::vector<std::string>({"blocked_ssid"}))) + .Times(1); + + SetPolicy(::onc::ONC_SOURCE_DEVICE_POLICY, std::string(), + "policy/policy_exhaustive_global_network_configuration.onc"); + base::RunLoop().RunUntilIdle(); + + testing::Mock::VerifyAndClearExpectations(network_state_handler_.get()); + EXPECT_TRUE(managed_handler()->AllowOnlyPolicyCellularNetworks()); + EXPECT_TRUE(managed_handler()->AllowOnlyPolicyNetworksToAutoconnect()); + EXPECT_TRUE(managed_handler()->AllowOnlyPolicyWiFiToConnect()); + EXPECT_TRUE(managed_handler()->AllowOnlyPolicyWiFiToConnectIfAvailable()); + EXPECT_THAT(managed_handler()->GetBlockedHexSSIDs(), + testing::ElementsAre("blocked_ssid")); + // TODO(b/219568567): Also test that DisableNetworkTypes are propagated to + // ProhibitedTechnologiesHandler. + + // Step 2: Now apply a device policy with an empty GlobalNetworkConfiguration. + EXPECT_CALL(*network_state_handler_, + UpdateBlockedWifiNetworks( + /*only_managed=*/false, /*available_only=*/false, + std::vector<std::string>())) + .Times(1); + SetPolicy(::onc::ONC_SOURCE_DEVICE_POLICY, std::string(), + "policy/policy_empty_global_network_configuration.onc"); + base::RunLoop().RunUntilIdle(); + + testing::Mock::VerifyAndClearExpectations(network_state_handler_.get()); + EXPECT_FALSE(managed_handler()->AllowOnlyPolicyCellularNetworks()); + EXPECT_FALSE(managed_handler()->AllowOnlyPolicyNetworksToAutoconnect()); + EXPECT_FALSE(managed_handler()->AllowOnlyPolicyWiFiToConnect()); + EXPECT_FALSE(managed_handler()->AllowOnlyPolicyWiFiToConnectIfAvailable()); + EXPECT_THAT(managed_handler()->GetBlockedHexSSIDs(), testing::IsEmpty()); +} + // Proxy settings can come from different sources. Proxy enforced by user policy // (provided by kProxy prefence) should have precedence over configurations set // by ONC policy. This test verifies that the order of preference is respected.
diff --git a/chromeos/services/federated/public/cpp/federated_example_util.cc b/chromeos/services/federated/public/cpp/federated_example_util.cc index a46318bf..a4fa636 100644 --- a/chromeos/services/federated/public/cpp/federated_example_util.cc +++ b/chromeos/services/federated/public/cpp/federated_example_util.cc
@@ -8,24 +8,15 @@ namespace federated { mojom::ValueListPtr CreateInt64List(const std::vector<int64_t>& values) { - mojom::ValueListPtr value_list = mojom::ValueList::New(); - value_list->set_int64_list(mojom::Int64List::New()); - value_list->get_int64_list()->value = values; - return value_list; + return mojom::ValueList::NewInt64List(mojom::Int64List::New(values)); } mojom::ValueListPtr CreateFloatList(const std::vector<double>& values) { - mojom::ValueListPtr value_list = mojom::ValueList::New(); - value_list->set_float_list(mojom::FloatList::New()); - value_list->get_float_list()->value = values; - return value_list; + return mojom::ValueList::NewFloatList(mojom::FloatList::New(values)); } mojom::ValueListPtr CreateStringList(const std::vector<std::string>& values) { - mojom::ValueListPtr value_list = mojom::ValueList::New(); - value_list->set_string_list(mojom::StringList::New()); - value_list->get_string_list()->value = values; - return value_list; + return mojom::ValueList::NewStringList(mojom::StringList::New(values)); } } // namespace federated
diff --git a/components/autofill_assistant/android/BUILD.gn b/components/autofill_assistant/android/BUILD.gn index c9a0152..293abf2ed 100644 --- a/components/autofill_assistant/android/BUILD.gn +++ b/components/autofill_assistant/android/BUILD.gn
@@ -36,16 +36,15 @@ "//components/version_info/android:version_constants_java", "//content/public/android:content_java", "//mojo/public/java:bindings_java", - "//third_party/android_deps:android_support_v7_appcompat_java", "//third_party/android_deps:com_android_support_support_annotations_java", "//third_party/android_deps:material_design_java", "//third_party/androidx:androidx_annotation_annotation_java", + "//third_party/androidx:androidx_appcompat_appcompat_java", "//third_party/androidx:androidx_appcompat_appcompat_resources_java", "//third_party/androidx:androidx_collection_collection_java", "//third_party/androidx:androidx_coordinatorlayout_coordinatorlayout_java", "//third_party/androidx:androidx_core_core_java", "//third_party/androidx:androidx_gridlayout_gridlayout_java", - "//third_party/androidx:androidx_lifecycle_lifecycle_common_java", "//third_party/androidx:androidx_lifecycle_lifecycle_runtime_java", "//third_party/androidx:androidx_recyclerview_recyclerview_java", "//third_party/blink/public/mojom:android_mojo_bindings_java", @@ -335,7 +334,6 @@ deps = [ ":animated_poodle_resources", "//base:base_java", - "//third_party/android_deps:android_support_v7_appcompat_java", "//third_party/androidx:androidx_appcompat_appcompat_resources_java", "//ui/android:ui_java", ] @@ -359,7 +357,6 @@ deps = [ ":animated_poodle_resources", "//base:base_java", - "//third_party/android_deps:android_support_v7_appcompat_java", "//third_party/androidx:androidx_appcompat_appcompat_resources_java", "//ui/android:ui_java", ]
diff --git a/components/browser_ui/modaldialog/android/BUILD.gn b/components/browser_ui/modaldialog/android/BUILD.gn index 3d6dd2e..7ec923b 100644 --- a/components/browser_ui/modaldialog/android/BUILD.gn +++ b/components/browser_ui/modaldialog/android/BUILD.gn
@@ -18,8 +18,8 @@ "//components/browser_ui/styles/android:java", "//components/browser_ui/widget/android:java", "//content/public/android:content_java", - "//third_party/android_deps:android_support_v7_appcompat_java", "//third_party/androidx:androidx_annotation_annotation_java", + "//third_party/androidx:androidx_core_core_java", "//ui/android:ui_java", ] resources_package = "org.chromium.components.browser_ui.modaldialog" @@ -63,7 +63,6 @@ "//third_party/android_support_test_runner:rules_java", "//third_party/android_support_test_runner:runner_java", "//third_party/androidx:androidx_annotation_annotation_java", - "//third_party/androidx:androidx_core_core_java", "//third_party/androidx:androidx_test_runner_java", "//third_party/hamcrest:hamcrest_java", "//third_party/junit:junit",
diff --git a/components/browser_ui/settings/android/BUILD.gn b/components/browser_ui/settings/android/BUILD.gn index ccc442a..967a91bc 100644 --- a/components/browser_ui/settings/android/BUILD.gn +++ b/components/browser_ui/settings/android/BUILD.gn
@@ -29,9 +29,11 @@ ":java_resources", "//base:base_java", "//components/browser_ui/util/android:java", - "//third_party/android_deps:android_support_v7_appcompat_java", "//third_party/androidx:androidx_annotation_annotation_java", + "//third_party/androidx:androidx_appcompat_appcompat_java", "//third_party/androidx:androidx_appcompat_appcompat_resources_java", + "//third_party/androidx:androidx_core_core_java", + "//third_party/androidx:androidx_fragment_fragment_java", "//third_party/androidx:androidx_preference_preference_java", "//ui/android:ui_java", ]
diff --git a/components/browser_ui/site_settings/android/BUILD.gn b/components/browser_ui/site_settings/android/BUILD.gn index 7967d1d..c7fe615c 100644 --- a/components/browser_ui/site_settings/android/BUILD.gn +++ b/components/browser_ui/site_settings/android/BUILD.gn
@@ -87,9 +87,14 @@ "//components/user_prefs/android:java", "//content/public/android:content_java", "//services/device/public/java:device_feature_list_java", - "//third_party/android_deps:android_support_v7_appcompat_java", "//third_party/androidx:androidx_annotation_annotation_java", + "//third_party/androidx:androidx_appcompat_appcompat_java", + "//third_party/androidx:androidx_appcompat_appcompat_resources_java", + "//third_party/androidx:androidx_core_core_java", + "//third_party/androidx:androidx_fragment_fragment_java", "//third_party/androidx:androidx_preference_preference_java", + "//third_party/androidx:androidx_recyclerview_recyclerview_java", + "//third_party/androidx:androidx_vectordrawable_vectordrawable_java", "//ui/android:ui_full_java", "//ui/android:ui_utils_java", "//url:gurl_java", @@ -169,6 +174,5 @@ "//components/browser_ui/strings/android:browser_ui_strings_grd", "//components/browser_ui/styles/android:java_resources", "//components/permissions/android:java_resources", - "//third_party/android_deps:android_support_v7_appcompat_java", ] }
diff --git a/components/browser_ui/styles/android/BUILD.gn b/components/browser_ui/styles/android/BUILD.gn index 4793c03..960c2dbc 100644 --- a/components/browser_ui/styles/android/BUILD.gn +++ b/components/browser_ui/styles/android/BUILD.gn
@@ -13,9 +13,9 @@ deps = [ ":java_resources", "//base:base_java", - "//third_party/android_deps:android_support_v7_appcompat_java", "//third_party/android_deps:material_design_java", "//third_party/androidx:androidx_annotation_annotation_java", + "//third_party/androidx:androidx_appcompat_appcompat_java", "//third_party/androidx:androidx_appcompat_appcompat_resources_java", ] resources_package = "org.chromium.components.browser_ui.styles"
diff --git a/components/browser_ui/widget/android/BUILD.gn b/components/browser_ui/widget/android/BUILD.gn index 684c407b..a0e8693 100644 --- a/components/browser_ui/widget/android/BUILD.gn +++ b/components/browser_ui/widget/android/BUILD.gn
@@ -121,11 +121,16 @@ "//components/browser_ui/styles/android:java", "//components/browser_ui/util/android:java", "//components/embedder_support/android:util_java", - "//third_party/android_deps:android_support_v7_appcompat_java", "//third_party/android_deps:material_design_java", "//third_party/androidx:androidx_annotation_annotation_java", + "//third_party/androidx:androidx_appcompat_appcompat_java", "//third_party/androidx:androidx_appcompat_appcompat_resources_java", "//third_party/androidx:androidx_coordinatorlayout_coordinatorlayout_java", + "//third_party/androidx:androidx_core_core_java", + "//third_party/androidx:androidx_interpolator_interpolator_java", + "//third_party/androidx:androidx_recyclerview_recyclerview_java", + "//third_party/androidx:androidx_vectordrawable_vectordrawable_animated_java", + "//third_party/androidx:androidx_vectordrawable_vectordrawable_java", "//ui/android:ui_java", "//url:gurl_java", ] @@ -332,7 +337,6 @@ "//third_party/android_support_test_runner:rules_java", "//third_party/android_support_test_runner:runner_java", "//third_party/androidx:androidx_annotation_annotation_java", - "//third_party/androidx:androidx_appcompat_appcompat_java", "//third_party/androidx:androidx_appcompat_appcompat_resources_java", "//third_party/androidx:androidx_core_core_java", "//third_party/androidx:androidx_test_runner_java",
diff --git a/components/crash/core/app/crashpad.cc b/components/crash/core/app/crashpad.cc index 6da6be4..1ff1011 100644 --- a/components/crash/core/app/crashpad.cc +++ b/components/crash/core/app/crashpad.cc
@@ -209,7 +209,7 @@ g_database = crashpad::CrashReportDatabase::Initialize(database_path).release(); -#if !BUILDFLAG(IS_CHROMEOS_ASH) +#if !BUILDFLAG(IS_CHROMEOS_ASH) && !BUILDFLAG(IS_IOS) CrashReporterClient* crash_reporter_client = GetCrashReporterClient(); SetUploadConsent(crash_reporter_client->GetCollectStatsConsent()); #endif
diff --git a/components/cronet/android/BUILD.gn b/components/cronet/android/BUILD.gn index b0dbdbb6..5a0dfe94d 100644 --- a/components/cronet/android/BUILD.gn +++ b/components/cronet/android/BUILD.gn
@@ -434,7 +434,16 @@ "sample/res/values/strings.xml", ] android_manifest = "sample/AndroidManifest.xml" - deps = [ "//third_party/android_deps:android_support_v7_appcompat_java" ] + deps = [ + "//third_party/androidx:androidx_appcompat_appcompat_java", + "//third_party/androidx:androidx_appcompat_appcompat_resources_java", + "//third_party/androidx:androidx_drawerlayout_drawerlayout_java", + "//third_party/androidx:androidx_fragment_fragment_java", + "//third_party/androidx:androidx_interpolator_interpolator_java", + "//third_party/androidx:androidx_lifecycle_lifecycle_common_java", + "//third_party/androidx:androidx_vectordrawable_vectordrawable_animated_java", + "//third_party/androidx:androidx_vectordrawable_vectordrawable_java", + ] } android_library("cronet_sample_apk_java") { @@ -448,8 +457,9 @@ ":cronet_sample_apk_resources", ":package_api_java", ":package_impl_native_java", - "//third_party/android_deps:android_support_v7_appcompat_java", "//third_party/androidx:androidx_annotation_annotation_java", + "//third_party/androidx:androidx_appcompat_appcompat_java", + "//third_party/androidx:androidx_lifecycle_lifecycle_viewmodel_java", ] } @@ -786,7 +796,6 @@ "//third_party/junit", ] - enable_multidex = false if (!is_java_debug) { proguard_enabled = true proguard_configs = [ "sample/javatests/proguard.cfg" ]
diff --git a/components/exo/wayland/clients/client_base.cc b/components/exo/wayland/clients/client_base.cc index 637026b..7b97fe0 100644 --- a/components/exo/wayland/clients/client_base.cc +++ b/components/exo/wayland/clients/client_base.cc
@@ -28,6 +28,7 @@ #include "base/command_line.h" #include "base/logging.h" #include "base/memory/platform_shared_memory_region.h" +#include "base/memory/shared_memory_mapper.h" #include "base/memory/unsafe_shared_memory_region.h" #include "base/posix/eintr_wrapper.h" #include "base/strings/string_number_conversions.h" @@ -123,9 +124,11 @@ class MemfdMemoryMapping : public base::SharedMemoryMapping { public: MemfdMemoryMapping(base::span<uint8_t> mapped_span) - : base::SharedMemoryMapping(mapped_span, - mapped_span.size(), - base::UnguessableToken::Create()) {} + : base::SharedMemoryMapping( + mapped_span, + mapped_span.size(), + base::UnguessableToken::Create(), + base::SharedMemoryMapper::GetDefaultInstance()) {} }; void RegistryHandler(void* data,
diff --git a/components/external_intents/android/BUILD.gn b/components/external_intents/android/BUILD.gn index 44c5877..c5a8bd0 100644 --- a/components/external_intents/android/BUILD.gn +++ b/components/external_intents/android/BUILD.gn
@@ -7,7 +7,6 @@ android_library("java") { sources = [ "java/src/org/chromium/components/external_intents/AuthenticatorNavigationInterceptor.java", - "java/src/org/chromium/components/external_intents/ExternalIntentsFeatures.java", "java/src/org/chromium/components/external_intents/ExternalIntentsSwitches.java", "java/src/org/chromium/components/external_intents/ExternalNavigationDelegate.java", "java/src/org/chromium/components/external_intents/ExternalNavigationHandler.java", @@ -45,18 +44,11 @@ } generate_jni("jni_headers") { - sources = [ - "java/src/org/chromium/components/external_intents/ExternalIntentsFeatures.java", - "java/src/org/chromium/components/external_intents/InterceptNavigationDelegateImpl.java", - ] + sources = [ "java/src/org/chromium/components/external_intents/InterceptNavigationDelegateImpl.java" ] } static_library("android") { - sources = [ - "external_intents_features.cc", - "external_intents_features.h", - "intercept_navigation_delegate_impl.cc", - ] + sources = [ "intercept_navigation_delegate_impl.cc" ] deps = [ ":jni_headers",
diff --git a/components/external_intents/android/external_intents_features.cc b/components/external_intents/android/external_intents_features.cc deleted file mode 100644 index dca311e..0000000 --- a/components/external_intents/android/external_intents_features.cc +++ /dev/null
@@ -1,35 +0,0 @@ -// 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. - -#include "components/external_intents/android/external_intents_features.h" - -#include <jni.h> -#include <stddef.h> -#include <string> - -#include "base/android/jni_string.h" -#include "base/notreached.h" -#include "components/external_intents/android/jni_headers/ExternalIntentsFeatures_jni.h" - -namespace external_intents { - -namespace { - -// Array of features exposed through the Java ExternalIntentsFeatures API. -const base::Feature* kFeaturesExposedToJava[] = { - &kIntentBlockExternalFormRedirectsNoGesture, -}; - -} // namespace - -// Alphabetical: -const base::Feature kIntentBlockExternalFormRedirectsNoGesture{ - "IntentBlockExternalFormRedirectsNoGesture", - base::FEATURE_DISABLED_BY_DEFAULT}; - -static jlong JNI_ExternalIntentsFeatures_GetFeature(JNIEnv* env, jint ordinal) { - return reinterpret_cast<jlong>(kFeaturesExposedToJava[ordinal]); -} - -} // namespace external_intents
diff --git a/components/external_intents/android/external_intents_features.h b/components/external_intents/android/external_intents_features.h deleted file mode 100644 index e6c0d54..0000000 --- a/components/external_intents/android/external_intents_features.h +++ /dev/null
@@ -1,17 +0,0 @@ -// 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. - -#ifndef COMPONENTS_EXTERNAL_INTENTS_ANDROID_EXTERNAL_INTENTS_FEATURES_H_ -#define COMPONENTS_EXTERNAL_INTENTS_ANDROID_EXTERNAL_INTENTS_FEATURES_H_ - -#include "base/feature_list.h" - -namespace external_intents { - -// Alphabetical: -extern const base::Feature kIntentBlockExternalFormRedirectsNoGesture; - -} // namespace external_intents - -#endif // COMPONENTS_EXTERNAL_INTENTS_ANDROID_EXTERNAL_INTENTS_FEATURES_H_
diff --git a/components/external_intents/android/java/src/org/chromium/components/external_intents/ExternalIntentsFeatures.java b/components/external_intents/android/java/src/org/chromium/components/external_intents/ExternalIntentsFeatures.java deleted file mode 100644 index 2e1f1a3b..0000000 --- a/components/external_intents/android/java/src/org/chromium/components/external_intents/ExternalIntentsFeatures.java +++ /dev/null
@@ -1,42 +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. - -package org.chromium.components.external_intents; - -import org.chromium.base.Features; -import org.chromium.base.annotations.JNINamespace; -import org.chromium.base.annotations.NativeMethods; - -/** - * Java accessor for base/feature_list.h state. - * - * This class provides methods to access values of feature flags registered in - * |kFeaturesExposedToJava| in components/external_intents/android/external_intents_feature_list.cc. - * - */ -@JNINamespace("external_intents") -public class ExternalIntentsFeatures extends Features { - public static final String INTENT_BLOCK_EXTERNAL_FORM_REDIRECT_NO_GESTURE_NAME = - "IntentBlockExternalFormRedirectsNoGesture"; - - public static final ExternalIntentsFeatures INTENT_BLOCK_EXTERNAL_FORM_REDIRECT_NO_GESTURE = - new ExternalIntentsFeatures(0, INTENT_BLOCK_EXTERNAL_FORM_REDIRECT_NO_GESTURE_NAME); - - private final int mOrdinal; - - private ExternalIntentsFeatures(int ordinal, String name) { - super(name); - mOrdinal = ordinal; - } - - @Override - protected long getFeaturePointer() { - return ExternalIntentsFeaturesJni.get().getFeature(mOrdinal); - } - - @NativeMethods - interface Natives { - long getFeature(int ordinal); - } -}
diff --git a/components/external_intents/android/java/src/org/chromium/components/external_intents/ExternalNavigationHandler.java b/components/external_intents/android/java/src/org/chromium/components/external_intents/ExternalNavigationHandler.java index a962249..8b4ef37 100644 --- a/components/external_intents/android/java/src/org/chromium/components/external_intents/ExternalNavigationHandler.java +++ b/components/external_intents/android/java/src/org/chromium/components/external_intents/ExternalNavigationHandler.java
@@ -657,12 +657,6 @@ return false; } - /** Wrapper of check against the feature to support overriding for testing. */ - @VisibleForTesting - boolean blockExternalFormRedirectsWithoutGesture() { - return ExternalIntentsFeatures.INTENT_BLOCK_EXTERNAL_FORM_REDIRECT_NO_GESTURE.isEnabled(); - } - /** * http://crbug.com/149218: We want to show the intent picker for ordinary links, providing * the link is not an incoming intent from another application, unless it's a redirect. @@ -708,19 +702,6 @@ return false; } - // http://crbug.com/839751: Require user gestures for form submits to external - // protocols. - // TODO(tedchoc): Turn this on by default once we verify this change does - // not break the world. - if (isRedirectFromFormSubmit && !incomingIntentRedirect && !params.hasUserGesture() - && blockExternalFormRedirectsWithoutGesture()) { - if (DEBUG) { - Log.i(TAG, - "Incoming form intent attempting to redirect without " - + "user gesture"); - } - return false; - } // http://crbug/331571 : Do not override a navigation started from user typing. if (params.getRedirectHandler() != null && params.getRedirectHandler().isNavigationFromUserTyping()) {
diff --git a/components/external_intents/android/java/src/org/chromium/components/external_intents/InterceptNavigationDelegateImpl.java b/components/external_intents/android/java/src/org/chromium/components/external_intents/InterceptNavigationDelegateImpl.java index aaca6c0..391ac6f 100644 --- a/components/external_intents/android/java/src/org/chromium/components/external_intents/InterceptNavigationDelegateImpl.java +++ b/components/external_intents/android/java/src/org/chromium/components/external_intents/InterceptNavigationDelegateImpl.java
@@ -4,8 +4,11 @@ package org.chromium.components.external_intents; +import android.util.Pair; + import androidx.annotation.VisibleForTesting; +import org.chromium.base.Callback; import org.chromium.base.ContextUtils; import org.chromium.base.annotations.JNINamespace; import org.chromium.base.annotations.NativeMethods; @@ -35,7 +38,7 @@ public class InterceptNavigationDelegateImpl extends InterceptNavigationDelegate { private final AuthenticatorNavigationInterceptor mAuthenticatorHelper; private InterceptNavigationDelegateClient mClient; - private OverrideUrlLoadingResult mLastOverrideUrlLoadingResultForTesting; + private Callback<Pair<GURL, OverrideUrlLoadingResult>> mResultCallbackForTesting; private WebContents mWebContents; private ExternalNavigationHandler mExternalNavHandler; @@ -91,21 +94,13 @@ .setIsMainFrame(true) .build(); OverrideUrlLoadingResult result = mExternalNavHandler.shouldOverrideUrlLoading(params); - mLastOverrideUrlLoadingResultForTesting = result; + if (mResultCallbackForTesting != null) { + mResultCallbackForTesting.onResult(Pair.create(url, result)); + } return result.getResultType() != ExternalNavigationHandler.OverrideUrlLoadingResultType.NO_OVERRIDE; } - @VisibleForTesting - public void clearLastOverrideUrlLoadingResultForTests() { - mLastOverrideUrlLoadingResultForTesting = null; - } - - @VisibleForTesting - public OverrideUrlLoadingResult getLastOverrideUrlLoadingResultForTests() { - return mLastOverrideUrlLoadingResultForTesting; - } - @Override public boolean shouldIgnoreNavigation(NavigationHandle navigationHandle, GURL escapedUrl) { mClient.onNavigationStarted(navigationHandle); @@ -146,7 +141,9 @@ navigationHandle, redirectHandler, shouldCloseTab, escapedUrl) .build(); OverrideUrlLoadingResult result = mExternalNavHandler.shouldOverrideUrlLoading(params); - mLastOverrideUrlLoadingResultForTesting = result; + if (mResultCallbackForTesting != null) { + mResultCallbackForTesting.onResult(Pair.create(url, result)); + } mClient.onDecisionReachedForNavigation(navigationHandle, result); @@ -325,6 +322,12 @@ ContextUtils.getApplicationContext().getString(resId, url.getSpec())); } + @VisibleForTesting + public void setResultCallbackForTesting( + Callback<Pair<GURL, OverrideUrlLoadingResult>> callback) { + mResultCallbackForTesting = callback; + } + @NativeMethods interface Natives { void associateWithWebContents(
diff --git a/components/external_intents/android/javatests/src/org/chromium/components/external_intents/ExternalNavigationHandlerTest.java b/components/external_intents/android/javatests/src/org/chromium/components/external_intents/ExternalNavigationHandlerTest.java index 0fb8f96e..1eda2ba0 100644 --- a/components/external_intents/android/javatests/src/org/chromium/components/external_intents/ExternalNavigationHandlerTest.java +++ b/components/external_intents/android/javatests/src/org/chromium/components/external_intents/ExternalNavigationHandlerTest.java
@@ -329,12 +329,14 @@ .withPageTransition(PageTransition.FORM_SUBMIT) .withIsRedirect(true) .withHasUserGesture(false) - .expecting(OverrideUrlLoadingResultType.NO_OVERRIDE, IGNORE); + .expecting(OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT, + START_OTHER_ACTIVITY); checkUrl("http://youtube.com://") .withPageTransition(PageTransition.FORM_SUBMIT) .withIsRedirect(true) .withHasUserGesture(false) - .expecting(OverrideUrlLoadingResultType.NO_OVERRIDE, IGNORE); + .expecting(OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT, + START_OTHER_ACTIVITY); } @Test @@ -2590,11 +2592,6 @@ } @Override - public boolean blockExternalFormRedirectsWithoutGesture() { - return true; - } - - @Override protected boolean canLaunchIncognitoIntent(Intent intent, Context context) { mStartActivityInIncognitoIntent = intent; mStartIncognitoIntentCalled = true;
diff --git a/components/history_clusters/core/history_clusters_debug_jsons.cc b/components/history_clusters/core/history_clusters_debug_jsons.cc index c3e6ba6d..51848a5 100644 --- a/components/history_clusters/core/history_clusters_debug_jsons.cc +++ b/components/history_clusters/core/history_clusters_debug_jsons.cc
@@ -87,6 +87,11 @@ debug_entities.Append(std::move(debug_entity)); } debug_visit.SetKey("entities", std::move(debug_entities)); + if (!visit.annotated_visit.content_annotations.search_terms.empty()) { + debug_visit.SetStringKey( + "search_terms", + visit.annotated_visit.content_annotations.search_terms); + } debug_visit.SetDoubleKey("site_engagement_score", visit.engagement_score); base::ListValue debug_duplicate_visits;
diff --git a/components/media_router/browser/android/BUILD.gn b/components/media_router/browser/android/BUILD.gn index 3a028f66..31f7cda 100644 --- a/components/media_router/browser/android/BUILD.gn +++ b/components/media_router/browser/android/BUILD.gn
@@ -19,12 +19,11 @@ "//components/browser_ui/media/android:java", "//content/public/android:content_java", "//services/media_session/public/cpp/android:media_session_java", - "//third_party/android_deps:android_support_v7_appcompat_java", "//third_party/android_media:android_media_java", "//third_party/androidx:androidx_annotation_annotation_java", "//third_party/androidx:androidx_collection_collection_java", - "//third_party/androidx:androidx_core_core_java", "//third_party/androidx:androidx_fragment_fragment_java", + "//third_party/androidx:androidx_media_media_java", "//third_party/androidx:androidx_mediarouter_mediarouter_java", ] sources = [
diff --git a/components/media_router/test/android/cast_emulator/BUILD.gn b/components/media_router/test/android/cast_emulator/BUILD.gn index 14be15c..62f60b3e 100644 --- a/components/media_router/test/android/cast_emulator/BUILD.gn +++ b/components/media_router/test/android/cast_emulator/BUILD.gn
@@ -22,7 +22,6 @@ deps = [ "$google_play_services_package:google_play_services_cast_java", "//base:base_java", - "//third_party/android_deps:android_support_v7_appcompat_java", "//third_party/androidx:androidx_mediarouter_mediarouter_java", ] }
diff --git a/components/page_info/android/BUILD.gn b/components/page_info/android/BUILD.gn index c5e0d7f..31fe42d2c 100644 --- a/components/page_info/android/BUILD.gn +++ b/components/page_info/android/BUILD.gn
@@ -110,8 +110,11 @@ "//components/url_formatter/android:url_formatter_java", "//content/public/android:content_java", "//services/device/public/java:device_feature_list_java", - "//third_party/android_deps:android_support_v7_appcompat_java", "//third_party/androidx:androidx_annotation_annotation_java", + "//third_party/androidx:androidx_appcompat_appcompat_java", + "//third_party/androidx:androidx_appcompat_appcompat_resources_java", + "//third_party/androidx:androidx_core_core_java", + "//third_party/androidx:androidx_fragment_fragment_java", "//third_party/androidx:androidx_preference_preference_java", "//ui/android:ui_java", "//url:gurl_java",
diff --git a/components/policy/core/common/features.cc b/components/policy/core/common/features.cc index e1cfb4ed..02518d33 100644 --- a/components/policy/core/common/features.cc +++ b/components/policy/core/common/features.cc
@@ -22,9 +22,6 @@ const base::Feature kPasswordBreachEventReporting{ "PasswordBreachEventReporting", base::FEATURE_DISABLED_BY_DEFAULT}; -const base::Feature kChromeManagementPageAndroid{ - "ChromeManagementPageAndroid", base::FEATURE_ENABLED_BY_DEFAULT}; - const base::Feature kEnableUserCloudSigninRestrictionPolicyFetcher{ "UserCloudSigninRestrictionPolicyFetcher", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/components/policy/core/common/features.h b/components/policy/core/common/features.h index 6ce74123..accdfb8 100644 --- a/components/policy/core/common/features.h +++ b/components/policy/core/common/features.h
@@ -14,9 +14,6 @@ namespace policy { namespace features { -// Enable chrome://management page on Android. -POLICY_EXPORT extern const base::Feature kChromeManagementPageAndroid; - // Enable force installed Chrome apps policy migration. POLICY_EXPORT extern const base::Feature kDefaultChromeAppsMigration;
diff --git a/components/printing/test/print_render_frame_helper_browsertest.cc b/components/printing/test/print_render_frame_helper_browsertest.cc index 02049e1..d242fee 100644 --- a/components/printing/test/print_render_frame_helper_browsertest.cc +++ b/components/printing/test/print_render_frame_helper_browsertest.cc
@@ -508,18 +508,6 @@ mojo::AssociatedReceiver<mojom::PrintManagerHost> receiver_{this}; }; -class ScopedGenerateTaggedPDF { - public: - ScopedGenerateTaggedPDF() { - PrintTestContentRendererClient::SetGenerateTaggedPDFs(true); - } - ScopedGenerateTaggedPDF(const ScopedGenerateTaggedPDF&) = delete; - ScopedGenerateTaggedPDF& operator=(const ScopedGenerateTaggedPDF&) = delete; - ~ScopedGenerateTaggedPDF() { - PrintTestContentRendererClient::SetGenerateTaggedPDFs(false); - } -}; - } // namespace class PrintRenderFrameHelperTestBase : public content::RenderViewTest { @@ -534,7 +522,7 @@ protected: // content::RenderViewTest: content::ContentRendererClient* CreateContentRendererClient() override { - return new PrintTestContentRendererClient(); + return new PrintTestContentRendererClient(/*generate_tagged_pdfs=*/false); } void SetUp() override { @@ -1801,44 +1789,28 @@ ExpectOneBeforeOneAfterPrintEvent(); } -TEST_F(PrintRenderFrameHelperPreviewTest, - PrintPreviewRerenderWithNoTaggedPDFGeneration) { - LoadHTML(kHelloWorldHTML); +class PrintRenderFrameHelperTaggedPreviewTest + : public PrintRenderFrameHelperPreviewTest, + public testing::WithParamInterface<bool> { + public: + PrintRenderFrameHelperTaggedPreviewTest() = default; + PrintRenderFrameHelperTaggedPreviewTest( + const PrintRenderFrameHelperTaggedPreviewTest&) = delete; + PrintRenderFrameHelperTaggedPreviewTest& operator=( + const PrintRenderFrameHelperTaggedPreviewTest&) = delete; + ~PrintRenderFrameHelperTaggedPreviewTest() override = default; - OnPrintPreview(); + // content::RenderViewTest: + content::ContentRendererClient* CreateContentRendererClient() override { + return new PrintTestContentRendererClient(GenerateTaggedPDFs()); + } - EXPECT_EQ(0u, preview_ui()->print_preview_pages_remaining()); - VerifyDidPreviewPage(true, 0); - VerifyPreviewPageCount(1); - VerifyDefaultPageLayout(540, 720, 36, 36, 36, 36, false); - VerifyPrintPreviewCancelled(false); - VerifyPrintPreviewFailed(false); - VerifyPrintPreviewGenerated(true); - VerifyPagesPrinted(false); -#if BUILDFLAG(ENABLE_TAGGED_PDF) - EXPECT_EQ(0, print_manager()->accessibility_tree_set_count()); -#endif + bool GenerateTaggedPDFs() const { return GetParam(); } + bool ExpectsSetAccessibilityTreeCalls() const { return GenerateTaggedPDFs(); } +}; - print_settings().SetIntKey(kSettingScaleFactor, 200); - OnPrintPreviewRerender(); - - EXPECT_EQ(0u, preview_ui()->print_preview_pages_remaining()); - VerifyDidPreviewPage(true, 0); - VerifyPreviewPageCount(1); - VerifyDefaultPageLayout(540, 720, 36, 36, 36, 36, false); - VerifyPrintPreviewCancelled(false); - VerifyPrintPreviewFailed(false); - VerifyPrintPreviewGenerated(true); - VerifyPagesPrinted(false); -#if BUILDFLAG(ENABLE_TAGGED_PDF) - EXPECT_EQ(0, print_manager()->accessibility_tree_set_count()); -#endif -} - -TEST_F(PrintRenderFrameHelperPreviewTest, +TEST_P(PrintRenderFrameHelperTaggedPreviewTest, PrintPreviewRerenderGeneratesTaggedPDF) { - ScopedGenerateTaggedPDF generate_tagged_pdf; - LoadHTML(kHelloWorldHTML); OnPrintPreview(); @@ -1852,7 +1824,10 @@ VerifyPrintPreviewGenerated(true); VerifyPagesPrinted(false); #if BUILDFLAG(ENABLE_TAGGED_PDF) - EXPECT_EQ(1, print_manager()->accessibility_tree_set_count()); + int expected_accessibility_tree_set_count = + ExpectsSetAccessibilityTreeCalls() ? 1 : 0; + EXPECT_EQ(expected_accessibility_tree_set_count, + print_manager()->accessibility_tree_set_count()); #endif print_settings().SetIntKey(kSettingScaleFactor, 200); @@ -1867,10 +1842,17 @@ VerifyPrintPreviewGenerated(true); VerifyPagesPrinted(false); #if BUILDFLAG(ENABLE_TAGGED_PDF) - EXPECT_EQ(2, print_manager()->accessibility_tree_set_count()); + expected_accessibility_tree_set_count = + ExpectsSetAccessibilityTreeCalls() ? 2 : 0; + EXPECT_EQ(expected_accessibility_tree_set_count, + print_manager()->accessibility_tree_set_count()); #endif } +INSTANTIATE_TEST_SUITE_P(All, + PrintRenderFrameHelperTaggedPreviewTest, + testing::Bool()); + #endif // BUILDFLAG(ENABLE_PRINT_PREVIEW) #endif // !BUILDFLAG(IS_CHROMEOS_ASH)
diff --git a/components/printing/test/print_test_content_renderer_client.cc b/components/printing/test/print_test_content_renderer_client.cc index f6afe16..f53a11a 100644 --- a/components/printing/test/print_test_content_renderer_client.cc +++ b/components/printing/test/print_test_content_renderer_client.cc
@@ -14,10 +14,10 @@ namespace { -bool g_generate_tagged_pdfs = false; - class PrintRenderFrameHelperDelegate : public PrintRenderFrameHelper::Delegate { public: + explicit PrintRenderFrameHelperDelegate(bool generate_tagged_pdfs) + : generate_tagged_pdfs_(generate_tagged_pdfs) {} ~PrintRenderFrameHelperDelegate() override = default; blink::WebElement GetPdfElement(blink::WebLocalFrame* frame) override { @@ -30,25 +30,26 @@ return false; #endif } - bool ShouldGenerateTaggedPDF() override { return g_generate_tagged_pdfs; } + bool ShouldGenerateTaggedPDF() override { return generate_tagged_pdfs_; } bool OverridePrint(blink::WebLocalFrame* frame) override { return false; } + + private: + const bool generate_tagged_pdfs_; }; } // namespace -PrintTestContentRendererClient::PrintTestContentRendererClient() = default; +PrintTestContentRendererClient::PrintTestContentRendererClient( + bool generate_tagged_pdfs) + : generate_tagged_pdfs_(generate_tagged_pdfs) {} PrintTestContentRendererClient::~PrintTestContentRendererClient() = default; -// static -void PrintTestContentRendererClient::SetGenerateTaggedPDFs(bool generate) { - g_generate_tagged_pdfs = generate; -} - void PrintTestContentRendererClient::RenderFrameCreated( content::RenderFrame* render_frame) { new PrintRenderFrameHelper( - render_frame, std::make_unique<PrintRenderFrameHelperDelegate>()); + render_frame, + std::make_unique<PrintRenderFrameHelperDelegate>(generate_tagged_pdfs_)); } } // namespace printing
diff --git a/components/printing/test/print_test_content_renderer_client.h b/components/printing/test/print_test_content_renderer_client.h index e1ed43a..e040f3f3 100644 --- a/components/printing/test/print_test_content_renderer_client.h +++ b/components/printing/test/print_test_content_renderer_client.h
@@ -11,13 +11,14 @@ class PrintTestContentRendererClient : public content::ContentRendererClient { public: - PrintTestContentRendererClient(); + explicit PrintTestContentRendererClient(bool generate_tagged_pdfs); ~PrintTestContentRendererClient() override; - static void SetGenerateTaggedPDFs(bool generate); - // content::ContentRendererClient: void RenderFrameCreated(content::RenderFrame* render_frame) override; + + private: + const bool generate_tagged_pdfs_; }; } // namespace printing
diff --git a/components/search_engines/template_url.cc b/components/search_engines/template_url.cc index a81c8ac..0532d6c 100644 --- a/components/search_engines/template_url.cc +++ b/components/search_engines/template_url.cc
@@ -1446,6 +1446,8 @@ engine->created_from_play_api(), // Favor prepopulated engines over other auto-generated engines. engine->prepopulate_id() > 0, + // Favor starter pack engines over other auto-generated engines. + engine->starter_pack_id() > 0, // Favor engines derived from OpenSearch descriptions over // autogenerated engines heuristically generated from searchable forms. engine->originating_url().is_valid(),
diff --git a/components/search_engines/template_url_data.cc b/components/search_engines/template_url_data.cc index 96241fa..f3c8a57 100644 --- a/components/search_engines/template_url_data.cc +++ b/components/search_engines/template_url_data.cc
@@ -16,18 +16,24 @@ namespace { -// Returns a GUID used for sync, which is random except for prepopulated search +// Returns a GUID used for sync, which is random except for built-in search // engines. The latter benefit from using a deterministic GUID, to make sure // sync doesn't incur in duplicates for prepopulated engines. -std::string GenerateGUID(int prepopulate_id) { +std::string GenerateGUID(int prepopulate_id, int starter_pack_id) { + // We compute a GUID deterministically given |prepopulate_id| or + // |starter_pack_id|, using an arbitrary base GUID. + std::string guid; // IDs above 1000 are reserved for distribution custom engines. - if (prepopulate_id <= 0 || prepopulate_id > 1000) - return base::GenerateGUID(); + if (prepopulate_id > 0 && prepopulate_id <= 1000) { + guid = base::StringPrintf("485bf7d3-0215-45af-87dc-538868%06d", + prepopulate_id); + } else if (starter_pack_id > 0) { + guid = base::StringPrintf("ec205736-edd7-4022-a9a3-b431fc%06d", + starter_pack_id); + } else { + guid = base::GenerateGUID(); + } - // We compute a GUID deterministically given |prepopulate_id|, using an - // arbitrary base GUID. - std::string guid = - base::StringPrintf("485bf7d3-0215-45af-87dc-538868%06d", prepopulate_id); DCHECK(base::IsValidGUID(guid)); return guid; } @@ -91,7 +97,7 @@ created_from_play_api(false), usage_count(0), prepopulate_id(prepopulate_id), - sync_guid(GenerateGUID(prepopulate_id)), + sync_guid(GenerateGUID(prepopulate_id, 0)), preconnect_to_search_url(preconnect_to_search_url), prefetch_likely_navigations(prefetch_likely_navigations) { SetShortName(name); @@ -135,7 +141,7 @@ } void TemplateURLData::GenerateSyncGUID() { - sync_guid = GenerateGUID(prepopulate_id); + sync_guid = GenerateGUID(prepopulate_id, starter_pack_id); } size_t TemplateURLData::EstimateMemoryUsage() const {
diff --git a/components/search_engines/template_url_data.h b/components/search_engines/template_url_data.h index 5b76e09..069cfd8 100644 --- a/components/search_engines/template_url_data.h +++ b/components/search_engines/template_url_data.h
@@ -65,8 +65,9 @@ const std::string& url() const { return url_; } // Recomputes |sync_guid| using the same logic as in the constructor. This - // means a random GUID is generated, except for prepopulated search engines, - // which generate GUIDs deterministically based on |prepopulate_id|. + // means a random GUID is generated, except for built-in search engines, + // which generate GUIDs deterministically based on |prepopulate_id| or + // |starter_pack_id|. void GenerateSyncGUID(); // Estimates dynamic memory usage.
diff --git a/components/search_engines/template_url_data_util.cc b/components/search_engines/template_url_data_util.cc index 18c2316..39cded9 100644 --- a/components/search_engines/template_url_data_util.cc +++ b/components/search_engines/template_url_data_util.cc
@@ -409,6 +409,7 @@ turl->SetURL(engine.search_url); turl->favicon_url = GURL(ToStringPiece(engine.favicon_url)); turl->starter_pack_id = engine.id; + turl->GenerateSyncGUID(); turl->is_active = TemplateURLData::ActiveStatus::kTrue; return turl;
diff --git a/components/search_engines/template_url_service.cc b/components/search_engines/template_url_service.cc index 5970294e..1c5a390 100644 --- a/components/search_engines/template_url_service.cc +++ b/components/search_engines/template_url_service.cc
@@ -1400,6 +1400,7 @@ for (size_t i = 0; i < turl.alternate_urls().size(); ++i) se_specifics->add_alternate_urls(turl.alternate_urls()[i]); se_specifics->set_is_active(ActiveStatusToSync(turl.is_active())); + se_specifics->set_starter_pack_id(turl.starter_pack_id()); return syncer::SyncData::CreateLocalData(se_specifics->sync_guid(), se_specifics->keyword(), @@ -1472,6 +1473,7 @@ for (int i = 0; i < specifics.alternate_urls_size(); ++i) data.alternate_urls.push_back(specifics.alternate_urls(i)); data.is_active = ActiveStatusFromSync(specifics.is_active()); + data.starter_pack_id = specifics.starter_pack_id(); std::unique_ptr<TemplateURL> turl(new TemplateURL(data)); // If this TemplateURL matches a built-in prepopulated template URL, it's @@ -2092,16 +2094,19 @@ local_data->erase(guid); } - // Try to take over a local prepopulated entry, assuming we haven't already - // run into a keyword conflict. - if (local_duplicates.empty() && sync_turl->prepopulate_id() != 0) { + // Try to take over a local built-in (prepopulated or starter pack) entry, + // assuming we haven't already run into a keyword conflict. + if (local_duplicates.empty() && + (sync_turl->prepopulate_id() != 0 || sync_turl->starter_pack_id() != 0)) { // Check for a turl with a conflicting prepopulate_id. This detects the case // where the user changes a prepopulated engine's keyword on one client, // then begins syncing on another client. We want to reflect this keyword // change to that prepopulated URL on other clients instead of assuming that // the modified TemplateURL is a new entity. - TemplateURL* conflicting_prepopulated_turl = - FindPrepopulatedTemplateURL(sync_turl->prepopulate_id()); + TemplateURL* conflicting_built_in_turl = + (sync_turl->prepopulate_id() != 0) + ? FindPrepopulatedTemplateURL(sync_turl->prepopulate_id()) + : FindStarterPackTemplateURL(sync_turl->starter_pack_id()); // If we found a conflict, and the sync entity is better, apply the remote // changes locally. We consider |sync_turl| better if it's been modified @@ -2113,12 +2118,12 @@ // be applied to other clients. // If we can't safely replace the local entry with the synced one, or merge // the relevant changes in, we give up and leave both intact. - if (conflicting_prepopulated_turl && - !IsFromSync(conflicting_prepopulated_turl, sync_data) && + if (conflicting_built_in_turl && + !IsFromSync(conflicting_built_in_turl, sync_data) && sync_turl->IsBetterThanEngineWithConflictingKeyword( - conflicting_prepopulated_turl)) { - std::string guid = conflicting_prepopulated_turl->sync_guid(); - if (conflicting_prepopulated_turl == default_search_provider_) { + conflicting_built_in_turl)) { + std::string guid = conflicting_built_in_turl->sync_guid(); + if (conflicting_built_in_turl == default_search_provider_) { bool pref_matched = prefs_->GetString(prefs::kSyncedDefaultSearchProviderGUID) == default_search_provider_->sync_guid(); @@ -2136,7 +2141,7 @@ should_add_sync_turl = false; } else { - Remove(conflicting_prepopulated_turl); + Remove(conflicting_built_in_turl); } // Remove the local data so it isn't written to sync. local_data->erase(guid); @@ -2242,6 +2247,16 @@ return nullptr; } +TemplateURL* TemplateURLService::FindStarterPackTemplateURL( + int starter_pack_id) { + DCHECK(starter_pack_id); + for (const auto& turl : template_urls_) { + if (turl->starter_pack_id() == starter_pack_id) + return turl.get(); + } + return nullptr; +} + TemplateURL* TemplateURLService::FindTemplateURLForExtension( const std::string& extension_id, TemplateURL::Type type) {
diff --git a/components/search_engines/template_url_service.h b/components/search_engines/template_url_service.h index 56399fb..0e17278 100644 --- a/components/search_engines/template_url_service.h +++ b/components/search_engines/template_url_service.h
@@ -684,6 +684,9 @@ // Returns the TemplateURL corresponding to |prepopulated_id|, if any. TemplateURL* FindPrepopulatedTemplateURL(int prepopulated_id); + // Returns the TemplateURL corresponding to |starter_pack_id|, if any. + TemplateURL* FindStarterPackTemplateURL(int starter_pack_id); + // Returns the TemplateURL associated with |extension_id|, if any. TemplateURL* FindTemplateURLForExtension(const std::string& extension_id, TemplateURL::Type type);
diff --git a/components/services/storage/public/mojom/indexed_db_control_test.mojom b/components/services/storage/public/mojom/indexed_db_control_test.mojom index e3c413bc..6637a74 100644 --- a/components/services/storage/public/mojom/indexed_db_control_test.mojom +++ b/components/services/storage/public/mojom/indexed_db_control_test.mojom
@@ -4,7 +4,6 @@ module storage.mojom; -import "components/services/storage/public/mojom/buckets/bucket_locator.mojom"; import "mojo/public/mojom/base/file_path.mojom"; import "mojo/public/mojom/base/values.mojom"; import "mojo/public/mojom/base/time.mojom"; @@ -61,19 +60,19 @@ (V2SchemaCorruptionStatus status); // Does a direct write to a database with a given key/value pair. - WriteToIndexedDBForTesting(storage.mojom.BucketLocator bucket_locator, - string key, string value) => (); + WriteToIndexedDBForTesting(blink.mojom.StorageKey storage_key, string key, + string value) => (); // Returns the number of blobs for a given `storage_key`. GetBlobCountForTesting(blink.mojom.StorageKey storage_key) => (int64 num_blobs); // Returns the next blob id for a given `storage_key`. - GetNextBlobNumberForTesting(storage.mojom.BucketLocator bucket_locator, + GetNextBlobNumberForTesting(blink.mojom.StorageKey storage_key, int64 database_id) => (int64 next_blob_number); // Returns the path for a given key/database/blob. - GetPathForBlobForTesting(storage.mojom.BucketLocator bucket_locator, + GetPathForBlobForTesting(blink.mojom.StorageKey storage_key, int64 database_id, int64 blob_number) => (mojo_base.mojom.FilePath path);
diff --git a/components/sync/protocol/proto_visitors.h b/components/sync/protocol/proto_visitors.h index f1d21e7..75153808 100644 --- a/components/sync/protocol/proto_visitors.h +++ b/components/sync/protocol/proto_visitors.h
@@ -836,6 +836,7 @@ VISIT(image_url_post_params); VISIT(new_tab_url); VISIT_ENUM(is_active); + VISIT(starter_pack_id); } VISIT_PROTO_FIELDS(const sync_pb::SendTabToSelfSpecifics& proto) {
diff --git a/components/sync/protocol/search_engine_specifics.proto b/components/sync/protocol/search_engine_specifics.proto index 29f5448..7b07e74 100644 --- a/components/sync/protocol/search_engine_specifics.proto +++ b/components/sync/protocol/search_engine_specifics.proto
@@ -92,4 +92,7 @@ // Whether a search engine is 'active' and can be triggered via the omnibox by // typing in the relevant keyword. optional ActiveStatus is_active = 27; + // The ID associated with the starter pack engine. This is set to 0 if not a + // starter pack engine. + optional int32 starter_pack_id = 28; }
diff --git a/content/browser/accessibility/dump_accessibility_tree_browsertest.cc b/content/browser/accessibility/dump_accessibility_tree_browsertest.cc index ecc4a7960..88119df 100644 --- a/content/browser/accessibility/dump_accessibility_tree_browsertest.cc +++ b/content/browser/accessibility/dump_accessibility_tree_browsertest.cc
@@ -2029,6 +2029,11 @@ } IN_PROC_BROWSER_TEST_P(DumpAccessibilityTreeTest, + AccessibilityFencedFrameScrollable) { + RunHtmlTest(FILE_PATH_LITERAL("fencedframe-scrollable.html")); +} + +IN_PROC_BROWSER_TEST_P(DumpAccessibilityTreeTest, AccessibilityIframeScrollable) { RunHtmlTest(FILE_PATH_LITERAL("iframe-scrollable.html")); }
diff --git a/content/browser/attribution_reporting/attribution_data_host_manager_impl.cc b/content/browser/attribution_reporting/attribution_data_host_manager_impl.cc index c7788dd..5d38713 100644 --- a/content/browser/attribution_reporting/attribution_data_host_manager_impl.cc +++ b/content/browser/attribution_reporting/attribution_data_host_manager_impl.cc
@@ -90,6 +90,11 @@ constexpr size_t kMaxDelayedTriggers = 30; +void ReportBadMessageInsecureReportingOrigin() { + mojo::ReportBadMessage( + "AttributionDataHost: Reporting origin must be secure."); +} + } // namespace struct AttributionDataHostManagerImpl::FrozenContext { @@ -223,10 +228,16 @@ void AttributionDataHostManagerImpl::SourceDataAvailable( blink::mojom::AttributionSourceDataPtr data) { - // The API is only allowed in secure contexts. - if (!network::IsOriginPotentiallyTrustworthy(data->reporting_origin) || - !network::IsOriginPotentiallyTrustworthy(data->destination)) { + if (!network::IsOriginPotentiallyTrustworthy(data->reporting_origin)) { RecordSourceDataHandleStatus(DataHandleStatus::kUntrustworthyOrigin); + ReportBadMessageInsecureReportingOrigin(); + return; + } + + if (!network::IsOriginPotentiallyTrustworthy(data->destination)) { + RecordSourceDataHandleStatus(DataHandleStatus::kUntrustworthyOrigin); + mojo::ReportBadMessage( + "AttributionDataHost: Destination origin must be secure."); return; } @@ -237,8 +248,6 @@ case AttributionSourceType::kNavigation: DCHECK(context.destination.has_value()); - // For navigation sources verify the destination matches the final - // navigation origin. if (net::SchemefulSite(data->destination) != net::SchemefulSite(*context.destination)) { RecordSourceDataHandleStatus(DataHandleStatus::kContextError); @@ -246,11 +255,15 @@ } break; case AttributionSourceType::kEvent: - // For event sources verify that all sources are consistent. if (!context.destination.has_value()) { context.destination = data->destination; } else if (data->destination != *context.destination) { RecordSourceDataHandleStatus(DataHandleStatus::kContextError); + if (context.destination->opaque()) { + mojo::ReportBadMessage( + "AttributionDataHost: Cannot register sources after registering " + "a trigger."); + } return; } break; @@ -258,11 +271,16 @@ base::Time source_time = base::Time::Now(); + // When converting mojo values to the browser process equivalents, it should + // not be possible for there to be an error except in the case of a bad + // renderer. All of the validation here is also performed renderer-side. + absl::optional<AttributionFilterData> filter_data = AttributionFilterData::FromSourceFilterValues( std::move(data->filter_data->filter_values)); if (!filter_data.has_value()) { RecordSourceDataHandleStatus(DataHandleStatus::kInvalidData); + mojo::ReportBadMessage("AttributionDataHost: Invalid filter data."); return; } @@ -271,6 +289,7 @@ std::move(data->aggregatable_source->keys)); if (!aggregatable_source.has_value()) { RecordSourceDataHandleStatus(DataHandleStatus::kInvalidData); + mojo::ReportBadMessage("AttributionDataHost: Invalid aggregatable source."); return; } @@ -294,19 +313,20 @@ void AttributionDataHostManagerImpl::TriggerDataAvailable( blink::mojom::AttributionTriggerDataPtr data) { - // The API is only allowed in secure contexts. if (!network::IsOriginPotentiallyTrustworthy(data->reporting_origin)) { RecordTriggerDataHandleStatus(DataHandleStatus::kUntrustworthyOrigin); + ReportBadMessageInsecureReportingOrigin(); return; } FrozenContext& context = receivers_.current_context(); DCHECK(network::IsOriginPotentiallyTrustworthy(context.context_origin)); - // Only possible in the case of a bad renderer, navigation bound data hosts - // cannot register triggers. if (context.source_type == AttributionSourceType::kNavigation) { RecordTriggerDataHandleStatus(DataHandleStatus::kContextError); + mojo::ReportBadMessage( + "AttributionDataHost: Navigation-bound data hosts cannot register " + "triggers."); return; } @@ -315,6 +335,9 @@ OnSourceEligibleDataHostFinished(context.register_time); } else if (!context.destination->opaque()) { RecordTriggerDataHandleStatus(DataHandleStatus::kContextError); + mojo::ReportBadMessage( + "AttributionDataHost: Cannot register triggers after registering a " + "source."); return; } @@ -323,11 +346,13 @@ std::move(data->filters->filter_values)); if (!filters.has_value()) { RecordTriggerDataHandleStatus(DataHandleStatus::kInvalidData); + mojo::ReportBadMessage("AttributionDataHost: Invalid top-level filters."); return; } if (data->event_triggers.size() > blink::kMaxAttributionEventTriggerData) { RecordTriggerDataHandleStatus(DataHandleStatus::kInvalidData); + mojo::ReportBadMessage("AttributionDataHost: Too many event triggers."); return; } @@ -340,6 +365,8 @@ std::move(event_trigger->filters->filter_values)); if (!filters.has_value()) { RecordTriggerDataHandleStatus(DataHandleStatus::kInvalidData); + mojo::ReportBadMessage( + "AttributionDataHost: Invalid event-trigger filters."); return; } @@ -348,6 +375,8 @@ std::move(event_trigger->not_filters->filter_values)); if (!not_filters.has_value()) { RecordTriggerDataHandleStatus(DataHandleStatus::kInvalidData); + mojo::ReportBadMessage( + "AttributionDataHost: Invalid event-trigger not_filters."); return; } @@ -364,6 +393,8 @@ std::move(data->aggregatable_trigger)); if (!aggregatable_trigger.has_value()) { RecordTriggerDataHandleStatus(DataHandleStatus::kInvalidData); + mojo::ReportBadMessage( + "AttributionDataHost: Invalid aggregatable trigger."); return; }
diff --git a/content/browser/attribution_reporting/attribution_data_host_manager_impl_unittest.cc b/content/browser/attribution_reporting/attribution_data_host_manager_impl_unittest.cc index b2122db..8aeeca6 100644 --- a/content/browser/attribution_reporting/attribution_data_host_manager_impl_unittest.cc +++ b/content/browser/attribution_reporting/attribution_data_host_manager_impl_unittest.cc
@@ -28,6 +28,7 @@ #include "content/public/test/browser_task_environment.h" #include "content/public/test/test_utils.h" #include "mojo/public/cpp/bindings/remote.h" +#include "mojo/public/cpp/test_support/test_utils.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/abseil-cpp/absl/numeric/int128.h" @@ -97,8 +98,6 @@ } }; -} // namespace - class AttributionDataHostManagerImplTest : public testing::Test { public: AttributionDataHostManagerImplTest() @@ -169,6 +168,7 @@ const char* destination_origin; const char* reporting_origin; bool source_expected; + const char* bad_message = nullptr; } kTestCases[] = { {.source_origin = kLocalHost, .destination_origin = kLocalHost, @@ -181,11 +181,14 @@ {.source_origin = kLocalHost, .destination_origin = kLocalHost, .reporting_origin = "http://insecure.com", - .source_expected = false}, + .source_expected = false, + .bad_message = "AttributionDataHost: Reporting origin must be secure."}, {.source_origin = kLocalHost, .destination_origin = "http://insecure.com", .reporting_origin = kLocalHost, - .source_expected = false}, + .source_expected = false, + .bad_message = + "AttributionDataHost: Destination origin must be secure."}, {.source_origin = "http://insecure.com", .destination_origin = kLocalHost, .reporting_origin = kLocalHost, @@ -199,6 +202,8 @@ for (const auto& test_case : kTestCases) { EXPECT_CALL(mock_manager_, HandleSource).Times(test_case.source_expected); + mojo::test::BadMessageObserver bad_message_observer; + RemoteDataHost data_host_remote{.task_environment = task_environment_}; data_host_manager_.RegisterDataHost( data_host_remote.data_host.BindNewPipeAndPassReceiver(), @@ -216,6 +221,13 @@ data_host_remote.data_host.FlushForTesting(); Mock::VerifyAndClear(&mock_manager_); + + EXPECT_EQ(bad_message_observer.got_bad_message(), !!test_case.bad_message); + + if (test_case.bad_message) { + EXPECT_EQ(bad_message_observer.WaitForBadMessage(), + test_case.bad_message); + } } histograms.ExpectUniqueSample("Conversions.RegisteredSourcesPerDataHost", 1, @@ -239,6 +251,8 @@ data_host_remote.BindNewPipeAndPassReceiver(), url::Origin::Create(GURL("https://page.example"))); + mojo::test::BadMessageObserver bad_message_observer; + auto source_data = blink::mojom::AttributionSourceData::New(); source_data->destination = url::Origin::Create(GURL("https://trigger.example")); @@ -253,6 +267,13 @@ Mock::VerifyAndClear(&mock_manager_); + EXPECT_NE(bad_message_observer.got_bad_message(), test_case.valid); + + if (!test_case.valid) { + EXPECT_EQ(bad_message_observer.WaitForBadMessage(), + "AttributionDataHost: Invalid filter data."); + } + // kSuccess = 0, kInvalidData = 3. histograms.ExpectUniqueSample(kSourceDataHandleStatusMetric, test_case.valid ? 0 : 3, 1); @@ -289,6 +310,8 @@ data_host_remote.BindNewPipeAndPassReceiver(), url::Origin::Create(GURL("https://page.example"))); + mojo::test::BadMessageObserver bad_message_observer; + auto source_data = blink::mojom::AttributionSourceData::New(); source_data->destination = url::Origin::Create(GURL("https://trigger.example")); @@ -303,6 +326,13 @@ Mock::VerifyAndClear(&mock_manager_); + EXPECT_NE(bad_message_observer.got_bad_message(), test_case.valid); + + if (!test_case.valid) { + EXPECT_EQ(bad_message_observer.WaitForBadMessage(), + "AttributionDataHost: Invalid filter data."); + } + // kSuccess = 0, kInvalidData = 3. histograms.ExpectUniqueSample(kSourceDataHandleStatusMetric, test_case.valid ? 0 : 3, 1); @@ -409,6 +439,8 @@ test_case.description); // Since EXPECT_CALL doesn't support << EXPECT_CALL(mock_manager_, HandleSource).Times(test_case.valid); + mojo::test::BadMessageObserver bad_message_observer; + mojo::Remote<blink::mojom::AttributionDataHost> data_host_remote; data_host_manager_.RegisterDataHost( data_host_remote.BindNewPipeAndPassReceiver(), @@ -426,6 +458,13 @@ Mock::VerifyAndClear(&mock_manager_); + EXPECT_NE(bad_message_observer.got_bad_message(), test_case.valid); + + if (!test_case.valid) { + EXPECT_EQ(bad_message_observer.WaitForBadMessage(), + "AttributionDataHost: Invalid aggregatable source."); + } + // kSuccess = 0, kInvalidData = 3. histograms.ExpectUniqueSample(kSourceDataHandleStatusMetric, test_case.valid ? 0 : 3, 1); @@ -522,6 +561,7 @@ const char* destination_origin; const char* reporting_origin; bool trigger_expected; + const char* bad_message = nullptr; } kTestCases[] = { {.destination_origin = kLocalHost, .reporting_origin = kLocalHost, @@ -531,7 +571,8 @@ .trigger_expected = true}, {.destination_origin = kLocalHost, .reporting_origin = "http://insecure.com", - .trigger_expected = false}, + .trigger_expected = false, + .bad_message = "AttributionDataHost: Reporting origin must be secure."}, {.destination_origin = "http://insecure.com", .reporting_origin = kLocalHost, .trigger_expected = false}, @@ -543,6 +584,8 @@ for (const auto& test_case : kTestCases) { EXPECT_CALL(mock_manager_, HandleTrigger).Times(test_case.trigger_expected); + mojo::test::BadMessageObserver bad_message_observer; + RemoteDataHost data_host_remote{.task_environment = task_environment_}; data_host_manager_.RegisterDataHost( data_host_remote.data_host.BindNewPipeAndPassReceiver(), @@ -559,6 +602,13 @@ data_host_remote.data_host->TriggerDataAvailable(std::move(trigger_data)); data_host_remote.data_host.FlushForTesting(); + EXPECT_EQ(bad_message_observer.got_bad_message(), !!test_case.bad_message); + + if (test_case.bad_message) { + EXPECT_EQ(bad_message_observer.WaitForBadMessage(), + test_case.bad_message); + } + Mock::VerifyAndClear(&mock_manager_); } @@ -578,6 +628,8 @@ SCOPED_TRACE(test_case.description); // EXPECT_CALL doesn't support << EXPECT_CALL(mock_manager_, HandleTrigger).Times(test_case.valid); + mojo::test::BadMessageObserver bad_message_observer; + mojo::Remote<blink::mojom::AttributionDataHost> data_host_remote; data_host_manager_.RegisterDataHost( data_host_remote.BindNewPipeAndPassReceiver(), @@ -598,6 +650,13 @@ Mock::VerifyAndClear(&mock_manager_); + EXPECT_NE(bad_message_observer.got_bad_message(), test_case.valid); + + if (!test_case.valid) { + EXPECT_EQ(bad_message_observer.WaitForBadMessage(), + "AttributionDataHost: Invalid top-level filters."); + } + // kSuccess = 0, kInvalidData = 3. histograms.ExpectUniqueSample(kTriggerDataHandleStatusMetric, test_case.valid ? 0 : 3, 1); @@ -612,6 +671,8 @@ SCOPED_TRACE(test_case.description); // EXPECT_CALL doesn't support << EXPECT_CALL(mock_manager_, HandleTrigger).Times(test_case.valid); + mojo::test::BadMessageObserver bad_message_observer; + mojo::Remote<blink::mojom::AttributionDataHost> data_host_remote; data_host_manager_.RegisterDataHost( data_host_remote.BindNewPipeAndPassReceiver(), @@ -638,6 +699,13 @@ Mock::VerifyAndClear(&mock_manager_); + EXPECT_NE(bad_message_observer.got_bad_message(), test_case.valid); + + if (!test_case.valid) { + EXPECT_EQ(bad_message_observer.WaitForBadMessage(), + "AttributionDataHost: Invalid event-trigger filters."); + } + // kSuccess = 0, kInvalidData = 3. histograms.ExpectUniqueSample(kTriggerDataHandleStatusMetric, test_case.valid ? 0 : 3, 1); @@ -652,6 +720,8 @@ SCOPED_TRACE(test_case.description); // EXPECT_CALL doesn't support << EXPECT_CALL(mock_manager_, HandleTrigger).Times(test_case.valid); + mojo::test::BadMessageObserver bad_message_observer; + mojo::Remote<blink::mojom::AttributionDataHost> data_host_remote; data_host_manager_.RegisterDataHost( data_host_remote.BindNewPipeAndPassReceiver(), @@ -679,6 +749,13 @@ Mock::VerifyAndClear(&mock_manager_); + EXPECT_NE(bad_message_observer.got_bad_message(), test_case.valid); + + if (!test_case.valid) { + EXPECT_EQ(bad_message_observer.WaitForBadMessage(), + "AttributionDataHost: Invalid event-trigger not_filters."); + } + // kSuccess = 0, kInvalidData = 3. histograms.ExpectUniqueSample(kTriggerDataHandleStatusMetric, test_case.valid ? 0 : 3, 1); @@ -700,6 +777,8 @@ EXPECT_CALL(mock_manager_, HandleTrigger).Times(test_case.expected); + mojo::test::BadMessageObserver bad_message_observer; + mojo::Remote<blink::mojom::AttributionDataHost> data_host_remote; data_host_manager_.RegisterDataHost( data_host_remote.BindNewPipeAndPassReceiver(), @@ -728,6 +807,13 @@ Mock::VerifyAndClear(&mock_manager_); + EXPECT_NE(bad_message_observer.got_bad_message(), test_case.expected); + + if (!test_case.expected) { + EXPECT_EQ(bad_message_observer.WaitForBadMessage(), + "AttributionDataHost: Too many event triggers."); + } + // kSuccess = 0, kInvalidData = 3. histograms.ExpectUniqueSample(kTriggerDataHandleStatusMetric, test_case.expected ? 0 : 3, 1); @@ -754,6 +840,8 @@ data_host_remote.BindNewPipeAndPassReceiver(), url::Origin::Create(GURL("https://trigger.example"))); + mojo::test::BadMessageObserver bad_message_observer; + auto trigger_data = blink::mojom::AttributionTriggerData::New(); trigger_data->reporting_origin = url::Origin::Create(GURL("https://reporter.example")); @@ -772,6 +860,13 @@ Mock::VerifyAndClear(&mock_manager_); + EXPECT_NE(bad_message_observer.got_bad_message(), test_case.expected); + + if (!test_case.expected) { + EXPECT_EQ(bad_message_observer.WaitForBadMessage(), + "AttributionDataHost: Invalid aggregatable trigger."); + } + // kSuccess = 0, kInvalidData = 3. histograms.ExpectUniqueSample(kTriggerDataHandleStatusMetric, test_case.expected ? 0 : 3, 1); @@ -821,15 +916,23 @@ checkpoint.Call(2); - auto source_data = blink::mojom::AttributionSourceData::New(); - source_data->destination = destination_origin; - source_data->reporting_origin = reporting_origin; - source_data->filter_data = blink::mojom::AttributionFilterData::New(); - source_data->aggregatable_source = - blink::mojom::AttributionAggregatableSource::New(); + { + mojo::test::BadMessageObserver bad_message_observer; - data_host_remote.data_host->SourceDataAvailable(std::move(source_data)); - data_host_remote.data_host.FlushForTesting(); + auto source_data = blink::mojom::AttributionSourceData::New(); + source_data->destination = destination_origin; + source_data->reporting_origin = reporting_origin; + source_data->filter_data = blink::mojom::AttributionFilterData::New(); + source_data->aggregatable_source = + blink::mojom::AttributionAggregatableSource::New(); + + data_host_remote.data_host->SourceDataAvailable(std::move(source_data)); + data_host_remote.data_host.FlushForTesting(); + + EXPECT_EQ(bad_message_observer.WaitForBadMessage(), + "AttributionDataHost: Cannot register sources after " + "registering a trigger."); + } checkpoint.Call(3); @@ -890,14 +993,22 @@ checkpoint.Call(2); - auto trigger_data = blink::mojom::AttributionTriggerData::New(); - trigger_data->reporting_origin = reporting_origin; - trigger_data->filters = blink::mojom::AttributionFilterData::New(); - trigger_data->aggregatable_trigger = - blink::mojom::AttributionAggregatableTrigger::New(); + { + mojo::test::BadMessageObserver bad_message_observer; - data_host_remote.data_host->TriggerDataAvailable(std::move(trigger_data)); - data_host_remote.data_host.FlushForTesting(); + auto trigger_data = blink::mojom::AttributionTriggerData::New(); + trigger_data->reporting_origin = reporting_origin; + trigger_data->filters = blink::mojom::AttributionFilterData::New(); + trigger_data->aggregatable_trigger = + blink::mojom::AttributionAggregatableTrigger::New(); + + data_host_remote.data_host->TriggerDataAvailable(std::move(trigger_data)); + data_host_remote.data_host.FlushForTesting(); + + EXPECT_EQ(bad_message_observer.WaitForBadMessage(), + "AttributionDataHost: Cannot register triggers after " + "registering a source."); + } checkpoint.Call(3); @@ -1596,6 +1707,8 @@ attribution_src_token, url::Origin::Create(GURL("https://s.test")), url::Origin::Create(GURL("https://d.test"))); + mojo::test::BadMessageObserver bad_message_observer; + auto trigger_data = blink::mojom::AttributionTriggerData::New(); trigger_data->reporting_origin = url::Origin::Create(GURL("https://r.test")); trigger_data->filters = blink::mojom::AttributionFilterData::New(); @@ -1605,6 +1718,10 @@ data_host_remote->TriggerDataAvailable(std::move(trigger_data)); data_host_remote.FlushForTesting(); + EXPECT_EQ(bad_message_observer.WaitForBadMessage(), + "AttributionDataHost: Navigation-bound data hosts cannot register " + "triggers."); + // kContextError = 2. histograms.ExpectUniqueSample(kTriggerDataHandleStatusMetric, 2, 1); } @@ -1656,4 +1773,5 @@ data_host_remote2.FlushForTesting(); } +} // namespace } // namespace content
diff --git a/content/browser/indexed_db/indexed_db_backing_store.cc b/content/browser/indexed_db/indexed_db_backing_store.cc index e5422cb..61fe4625 100644 --- a/content/browser/indexed_db/indexed_db_backing_store.cc +++ b/content/browser/indexed_db/indexed_db_backing_store.cc
@@ -133,10 +133,8 @@ return path; } -std::string ComputeOriginIdentifier( - const storage::BucketLocator& bucket_locator) { - return storage::GetIdentifierFromOrigin(bucket_locator.storage_key.origin()) + - "@1"; +std::string ComputeOriginIdentifier(const blink::StorageKey& storage_key) { + return storage::GetIdentifierFromOrigin(storage_key.origin()) + "@1"; } // TODO(ericu): Error recovery. If we persistently can't read the @@ -628,7 +626,7 @@ IndexedDBBackingStore::IndexedDBBackingStore( Mode backing_store_mode, TransactionalLevelDBFactory* transactional_leveldb_factory, - const storage::BucketLocator& bucket_locator, + const blink::StorageKey& storage_key, const base::FilePath& blob_path, std::unique_ptr<TransactionalLevelDBDatabase> db, storage::mojom::BlobStorageContext* blob_storage_context, @@ -639,13 +637,13 @@ scoped_refptr<base::SequencedTaskRunner> idb_task_runner) : backing_store_mode_(backing_store_mode), transactional_leveldb_factory_(transactional_leveldb_factory), - bucket_locator_(bucket_locator), + storage_key_(storage_key), blob_path_(backing_store_mode == Mode::kInMemory ? base::FilePath() : blob_path), blob_storage_context_(blob_storage_context), file_system_access_context_(file_system_access_context), filesystem_proxy_(std::move(filesystem_proxy)), - origin_identifier_(ComputeOriginIdentifier(bucket_locator)), + origin_identifier_(ComputeOriginIdentifier(storage_key)), idb_task_runner_(std::move(idb_task_runner)), db_(std::move(db)), blob_files_cleaned_(std::move(blob_files_cleaned)) { @@ -711,9 +709,7 @@ INTERNAL_READ_ERROR(SET_UP_METADATA); return s; } - // TODO(crbug.com/1218100): Propagate BucketLocator to callee. - indexed_db::ReportSchemaVersion(db_schema_version, - bucket_locator_.storage_key); + indexed_db::ReportSchemaVersion(db_schema_version, storage_key_); if (!found) { // Initialize new backing store. db_schema_version = indexed_db::kLatestKnownSchemaVersion; @@ -793,10 +789,9 @@ s = db_->Write(write_batch.get()); write_batch.reset(); if (!s.ok()) { - // TODO(crbug.com/1218100): Propagate BucketLocator to callee. indexed_db::ReportOpenStatus( indexed_db::INDEXED_DB_BACKING_STORE_OPEN_FAILED_METADATA_SETUP, - bucket_locator_.storage_key); + storage_key_); INTERNAL_WRITE_ERROR(SET_UP_METADATA); return s; } @@ -804,11 +799,10 @@ if (clean_active_journal) { s = CleanUpBlobJournal(ActiveBlobJournalKey::Encode()); if (!s.ok()) { - // TODO(crbug.com/1218100): Propagate BucketLocator to callee. indexed_db::ReportOpenStatus( indexed_db:: INDEXED_DB_BACKING_STORE_OPEN_FAILED_CLEANUP_JOURNAL_ERROR, - bucket_locator_.storage_key); + storage_key_); } } #if DCHECK_IS_ON() @@ -3194,7 +3188,7 @@ const std::string schema_version_key = SchemaVersionKey::Encode(); Status s; - if (bucket_locator_.storage_key.origin().host() != "docs.google.com") { + if (storage_key_.origin().host() != "docs.google.com") { s = ValidateBlobFiles(db_.get()); if (!s.ok()) { INTERNAL_CONSISTENCY_ERROR(SET_UP_METADATA);
diff --git a/content/browser/indexed_db/indexed_db_backing_store.h b/content/browser/indexed_db/indexed_db_backing_store.h index 53563f18..bc73164d 100644 --- a/content/browser/indexed_db/indexed_db_backing_store.h +++ b/content/browser/indexed_db/indexed_db_backing_store.h
@@ -27,7 +27,6 @@ #include "base/time/time.h" #include "base/timer/timer.h" #include "components/services/storage/indexed_db/locks/leveled_lock.h" -#include "components/services/storage/public/cpp/buckets/bucket_locator.h" #include "components/services/storage/public/cpp/filesystem/filesystem_proxy.h" #include "components/services/storage/public/mojom/blob_storage_context.mojom-forward.h" #include "components/services/storage/public/mojom/file_system_access_context.mojom-forward.h" @@ -39,18 +38,18 @@ #include "storage/browser/blob/blob_data_handle.h" #include "storage/common/file_system/file_system_mount_option.h" #include "third_party/blink/public/common/indexeddb/indexeddb_key.h" +#include "third_party/blink/public/common/storage_key/storage_key.h" #include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom.h" #include "third_party/leveldatabase/src/include/leveldb/status.h" #include "url/gurl.h" namespace base { class SequencedTaskRunner; -} // namespace base +} namespace blink { class IndexedDBKeyRange; struct IndexedDBDatabaseMetadata; -class StorageKey; } // namespace blink namespace content { @@ -389,7 +388,7 @@ IndexedDBBackingStore( Mode backing_store_mode, TransactionalLevelDBFactory* transactional_leveldb_factory, - const storage::BucketLocator& bucket_locator, + const blink::StorageKey& storage_key, const base::FilePath& blob_path, std::unique_ptr<TransactionalLevelDBDatabase> db, storage::mojom::BlobStorageContext* blob_storage_context, @@ -408,9 +407,7 @@ // operations or method calls on this object. leveldb::Status Initialize(bool clean_active_blob_journal); - const storage::BucketLocator& bucket_locator() const { - return bucket_locator_; - } + const blink::StorageKey& storage_key() const { return storage_key_; } base::SequencedTaskRunner* idb_task_runner() const { return idb_task_runner_.get(); } @@ -666,7 +663,7 @@ const Mode backing_store_mode_; const raw_ptr<TransactionalLevelDBFactory> transactional_leveldb_factory_; - const storage::BucketLocator bucket_locator_; + const blink::StorageKey storage_key_; const base::FilePath blob_path_; // IndexedDB can store blobs and File System Access handles. These mojo
diff --git a/content/browser/indexed_db/indexed_db_backing_store_unittest.cc b/content/browser/indexed_db/indexed_db_backing_store_unittest.cc index aec1bcc5..fea887f 100644 --- a/content/browser/indexed_db/indexed_db_backing_store_unittest.cc +++ b/content/browser/indexed_db/indexed_db_backing_store_unittest.cc
@@ -35,7 +35,6 @@ #include "components/services/storage/indexed_db/scopes/varint_coding.h" #include "components/services/storage/indexed_db/transactional_leveldb/leveldb_write_batch.h" #include "components/services/storage/indexed_db/transactional_leveldb/transactional_leveldb_database.h" -#include "components/services/storage/public/cpp/buckets/bucket_locator.h" #include "components/services/storage/public/mojom/indexed_db_control.mojom-test-utils.h" #include "content/browser/indexed_db/indexed_db_bucket_state.h" #include "content/browser/indexed_db/indexed_db_class_factory.h" @@ -72,7 +71,7 @@ TestableIndexedDBBackingStore( IndexedDBBackingStore::Mode backing_store_mode, TransactionalLevelDBFactory* leveldb_factory, - const storage::BucketLocator& bucket_locator, + const blink::StorageKey& storage_key, const base::FilePath& blob_path, std::unique_ptr<TransactionalLevelDBDatabase> db, storage::mojom::BlobStorageContext* blob_storage_context, @@ -83,7 +82,7 @@ scoped_refptr<base::SequencedTaskRunner> idb_task_runner) : IndexedDBBackingStore(backing_store_mode, leveldb_factory, - bucket_locator, + storage_key, blob_path, std::move(db), blob_storage_context, @@ -141,7 +140,7 @@ std::unique_ptr<IndexedDBBackingStore> CreateBackingStore( IndexedDBBackingStore::Mode backing_store_mode, TransactionalLevelDBFactory* leveldb_factory, - const storage::BucketLocator& bucket_locator, + const blink::StorageKey& storage_key, const base::FilePath& blob_path, std::unique_ptr<TransactionalLevelDBDatabase> db, storage::mojom::BlobStorageContext*, @@ -155,7 +154,7 @@ // than the versions that were passed in to this method. This way tests can // use a different context from what is stored in the IndexedDBContext. return std::make_unique<TestableIndexedDBBackingStore>( - backing_store_mode, leveldb_factory, bucket_locator, blob_path, + backing_store_mode, leveldb_factory, storage_key, blob_path, std::move(db), blob_storage_context_, file_system_access_context_, std::move(filesystem_proxy), std::move(blob_files_cleaned), std::move(report_outstanding_blobs), std::move(idb_task_runner)); @@ -337,8 +336,6 @@ void CreateFactoryAndBackingStore() { const blink::StorageKey storage_key = blink::StorageKey::CreateFromStringForTesting("http://localhost:81"); - auto bucket_locator = storage::BucketLocator(); - bucket_locator.storage_key = storage_key; idb_factory_ = std::make_unique<TestIDBFactory>( idb_context_.get(), blob_context_.get(), file_system_access_context_.get()); @@ -346,7 +343,7 @@ leveldb::Status s; std::tie(bucket_state_handle_, s, std::ignore, data_loss_info_, std::ignore) = - idb_factory_->GetOrOpenBucketFactory(bucket_locator, + idb_factory_->GetOrOpenBucketFactory(storage_key, idb_context_->data_path(), /*create_if_missing=*/true); if (!bucket_state_handle_.IsHeld()) {
diff --git a/content/browser/indexed_db/indexed_db_browsertest.cc b/content/browser/indexed_db/indexed_db_browsertest.cc index b323b3d..67fce13 100644 --- a/content/browser/indexed_db/indexed_db_browsertest.cc +++ b/content/browser/indexed_db/indexed_db_browsertest.cc
@@ -28,8 +28,6 @@ #include "base/time/time.h" #include "build/build_config.h" #include "components/services/storage/indexed_db/transactional_leveldb/transactional_leveldb_database.h" -#include "components/services/storage/public/cpp/buckets/bucket_id.h" -#include "components/services/storage/public/cpp/buckets/bucket_locator.h" #include "components/services/storage/public/mojom/indexed_db_control.mojom-test-utils.h" #include "components/services/storage/public/mojom/indexed_db_control_test.mojom.h" #include "components/services/storage/public/mojom/storage_usage_info.mojom.h" @@ -275,13 +273,13 @@ } // Synchronously writes to the IndexedDB database at the given storage_key. - void WriteToIndexedDB(const storage::BucketLocator& bucket_locator, + void WriteToIndexedDB(const blink::StorageKey& storage_key, std::string key, std::string value) { auto control_test = GetControlTest(); base::RunLoop loop; control_test->WriteToIndexedDBForTesting( - bucket_locator, std::move(key), std::move(value), loop.QuitClosure()); + storage_key, std::move(key), std::move(value), loop.QuitClosure()); loop.Run(); } @@ -380,9 +378,6 @@ const GURL database_open_url = GetTestUrl("indexeddb", "database_test.html"); const blink::StorageKey kTestStorageKey = blink::StorageKey(url::Origin::Create(database_open_url)); - auto bucket_locator = storage::BucketLocator(); - bucket_locator.id = storage::BucketId::FromUnsafeValue(1); - bucket_locator.storage_key = kTestStorageKey; // Create the database. SimpleTest(database_open_url); // -10, little endian. @@ -399,7 +394,7 @@ })); loop.Run(); - WriteToIndexedDB(bucket_locator, key, value); + WriteToIndexedDB(kTestStorageKey, key, value); // Crash the tab to ensure no old navigations are picked up. CrashTab(shell()->web_contents()); SimpleTest(GetTestUrl("indexeddb", "open_bad_db.html")); @@ -409,9 +404,6 @@ const GURL database_open_url = GetTestUrl("indexeddb", "database_test.html"); const blink::StorageKey kTestStorageKey = blink::StorageKey(url::Origin::Create(database_open_url)); - auto bucket_locator = storage::BucketLocator(); - bucket_locator.id = storage::BucketId::FromUnsafeValue(1); - bucket_locator.storage_key = kTestStorageKey; // Create the database. SimpleTest(database_open_url); // -10, little endian. @@ -428,7 +420,7 @@ })); loop.Run(); - WriteToIndexedDB(bucket_locator, key, value); + WriteToIndexedDB(kTestStorageKey, key, value); // Crash the tab to ensure no old navigations are picked up. CrashTab(shell()->web_contents()); SimpleTest(GetTestUrl("indexeddb", "open_bad_db.html")); @@ -1200,14 +1192,14 @@ // This test is for https://crbug.com/1039446. class IndexedDBBrowserTestBlobKeyCorruption : public IndexedDBBrowserTest { public: - int64_t GetNextBlobNumber(const storage::BucketLocator& bucket_locator, + int64_t GetNextBlobNumber(const blink::StorageKey& storage_key, int64_t database_id) { int64_t number; base::RunLoop loop; auto control_test = GetControlTest(); control_test->GetNextBlobNumberForTesting( - bucket_locator, database_id, + storage_key, database_id, base::BindLambdaForTesting([&](int64_t next_blob_number) { number = next_blob_number; loop.Quit(); @@ -1216,14 +1208,14 @@ return number; } - base::FilePath PathForBlob(const storage::BucketLocator& bucket_locator, + base::FilePath PathForBlob(const blink::StorageKey& storage_key, int64_t database_id, int64_t blob_number) { base::FilePath path; base::RunLoop loop; auto control_test = GetControlTest(); control_test->GetPathForBlobForTesting( - bucket_locator, database_id, blob_number, + storage_key, database_id, blob_number, base::BindLambdaForTesting([&](const base::FilePath& blob_path) { path = blob_path; loop.Quit(); @@ -1242,9 +1234,6 @@ embedded_test_server()->InitializeAndListen()); const blink::StorageKey kTestStorageKey = blink::StorageKey( url::Origin::Create(embedded_test_server()->base_url())); - auto bucket_locator = storage::BucketLocator(); - bucket_locator.id = storage::BucketId::FromUnsafeValue(1); - bucket_locator.storage_key = kTestStorageKey; embedded_test_server()->RegisterRequestHandler(base::BindRepeating( &StaticFileRequestHandler, s_indexeddb_test_prefix, this)); embedded_test_server()->StartAcceptingConnections(); @@ -1253,12 +1242,12 @@ std::string test_file = std::string(s_indexeddb_test_prefix) + "write_and_read_blob.html"; SimpleTest(embedded_test_server()->GetURL(test_file)); - int64_t next_blob_number = GetNextBlobNumber(bucket_locator, 1); + int64_t next_blob_number = GetNextBlobNumber(kTestStorageKey, 1); base::FilePath first_blob = - PathForBlob(bucket_locator, 1, next_blob_number - 1); + PathForBlob(kTestStorageKey, 1, next_blob_number - 1); base::FilePath corrupt_blob = - PathForBlob(bucket_locator, 1, next_blob_number); + PathForBlob(kTestStorageKey, 1, next_blob_number); { base::ScopedAllowBlockingForTesting allow_blocking; EXPECT_TRUE(base::PathExists(first_blob));
diff --git a/content/browser/indexed_db/indexed_db_cleanup_on_io_error_unittest.cc b/content/browser/indexed_db/indexed_db_cleanup_on_io_error_unittest.cc index 6836257..66fcf57 100644 --- a/content/browser/indexed_db/indexed_db_cleanup_on_io_error_unittest.cc +++ b/content/browser/indexed_db/indexed_db_cleanup_on_io_error_unittest.cc
@@ -16,7 +16,6 @@ #include "components/services/storage/indexed_db/scopes/leveldb_scopes.h" #include "components/services/storage/indexed_db/transactional_leveldb/transactional_leveldb_database.h" #include "components/services/storage/indexed_db/transactional_leveldb/transactional_leveldb_factory.h" -#include "components/services/storage/public/cpp/buckets/bucket_locator.h" #include "content/browser/indexed_db/indexed_db_backing_store.h" #include "content/browser/indexed_db/indexed_db_class_factory.h" #include "content/browser/indexed_db/indexed_db_leveldb_env.h" @@ -37,8 +36,6 @@ base::test::TaskEnvironment task_env; const blink::StorageKey storage_key = blink::StorageKey::CreateFromStringForTesting("http://localhost:81"); - auto bucket_locator = storage::BucketLocator(); - bucket_locator.storage_key = storage_key; base::ScopedTempDir temp_directory; ASSERT_TRUE(temp_directory.CreateUniqueTempDir()); const base::FilePath path = temp_directory.GetPath(); @@ -48,7 +45,7 @@ std::unique_ptr<IndexedDBBackingStore> backing_store = std::make_unique< IndexedDBBackingStore>( IndexedDBBackingStore::Mode::kInMemory, &transactional_leveldb_factory, - bucket_locator, path, + storage_key, path, transactional_leveldb_factory.CreateLevelDBDatabase( FakeLevelDBFactory::GetBrokenLevelDB( leveldb::Status::IOError("It's broken!"), path), @@ -68,8 +65,6 @@ base::test::TaskEnvironment task_env; const blink::StorageKey storage_key = blink::StorageKey::CreateFromStringForTesting("http://localhost:81"); - auto bucket_locator = storage::BucketLocator(); - bucket_locator.storage_key = storage_key; base::ScopedTempDir temp_directory; ASSERT_TRUE(temp_directory.CreateUniqueTempDir()); const base::FilePath path = temp_directory.GetPath(); @@ -89,7 +84,7 @@ std::unique_ptr<IndexedDBBackingStore> backing_store = std::make_unique< IndexedDBBackingStore>( IndexedDBBackingStore::Mode::kInMemory, &transactional_leveldb_factory, - bucket_locator, path, + storage_key, path, transactional_leveldb_factory.CreateLevelDBDatabase( FakeLevelDBFactory::GetBrokenLevelDB(error_status, path), nullptr, task_runner.get(),
diff --git a/content/browser/indexed_db/indexed_db_context_impl.cc b/content/browser/indexed_db/indexed_db_context_impl.cc index 08ad665..f0378553 100644 --- a/content/browser/indexed_db/indexed_db_context_impl.cc +++ b/content/browser/indexed_db/indexed_db_context_impl.cc
@@ -30,7 +30,6 @@ #include "components/services/storage/indexed_db/scopes/varint_coding.h" #include "components/services/storage/indexed_db/transactional_leveldb/transactional_leveldb_database.h" #include "components/services/storage/public/cpp/buckets/bucket_info.h" -#include "components/services/storage/public/cpp/buckets/bucket_locator.h" #include "components/services/storage/public/cpp/buckets/constants.h" #include "components/services/storage/public/cpp/quota_client_callback_wrapper.h" #include "components/services/storage/public/cpp/quota_error_or.h" @@ -580,14 +579,14 @@ } void IndexedDBContextImpl::WriteToIndexedDBForTesting( - const storage::BucketLocator& bucket_locator, + const blink::StorageKey& storage_key, const std::string& key, const std::string& value, base::OnceClosure callback) { IndexedDBBucketStateHandle handle; leveldb::Status s; std::tie(handle, s, std::ignore, std::ignore, std::ignore) = - GetIDBFactory()->GetOrOpenBucketFactory(bucket_locator, data_path(), + GetIDBFactory()->GetOrOpenBucketFactory(storage_key, data_path(), /*create_if_missing=*/true); CHECK(s.ok()) << s.ToString(); CHECK(handle.IsHeld()); @@ -598,8 +597,7 @@ s = db->Put(key, &value_copy); CHECK(s.ok()) << s.ToString(); handle.Release(); - // TODO(crbug.com/1218100): Propagate BucketLocator to callee. - GetIDBFactory()->ForceClose(bucket_locator.storage_key, true); + GetIDBFactory()->ForceClose(storage_key, true); std::move(callback).Run(); } @@ -610,13 +608,13 @@ } void IndexedDBContextImpl::GetNextBlobNumberForTesting( - const storage::BucketLocator& bucket_locator, + const blink::StorageKey& storage_key, int64_t database_id, GetNextBlobNumberForTestingCallback callback) { IndexedDBBucketStateHandle handle; leveldb::Status s; std::tie(handle, s, std::ignore, std::ignore, std::ignore) = - GetIDBFactory()->GetOrOpenBucketFactory(bucket_locator, data_path(), + GetIDBFactory()->GetOrOpenBucketFactory(storage_key, data_path(), /*create_if_missing=*/true); CHECK(s.ok()) << s.ToString(); CHECK(handle.IsHeld()); @@ -640,14 +638,14 @@ } void IndexedDBContextImpl::GetPathForBlobForTesting( - const storage::BucketLocator& bucket_locator, + const blink::StorageKey& storage_key, int64_t database_id, int64_t blob_number, GetPathForBlobForTestingCallback callback) { IndexedDBBucketStateHandle handle; leveldb::Status s; std::tie(handle, s, std::ignore, std::ignore, std::ignore) = - GetIDBFactory()->GetOrOpenBucketFactory(bucket_locator, data_path(), + GetIDBFactory()->GetOrOpenBucketFactory(storage_key, data_path(), /*create_if_missing=*/true); CHECK(s.ok()) << s.ToString(); CHECK(handle.IsHeld());
diff --git a/content/browser/indexed_db/indexed_db_context_impl.h b/content/browser/indexed_db/indexed_db_context_impl.h index 663da87a..6aff990 100644 --- a/content/browser/indexed_db/indexed_db_context_impl.h +++ b/content/browser/indexed_db/indexed_db_context_impl.h
@@ -40,16 +40,15 @@ class FilePath; class SequencedTaskRunner; class Value; -} // namespace base +} namespace blink { class StorageKey; -} // namespace blink +} namespace storage { -struct BucketLocator; class QuotaClientCallbackWrapper; -} // namespace storage +} namespace content { class IndexedDBConnection; @@ -123,18 +122,18 @@ void HasV2SchemaCorruptionForTesting( const blink::StorageKey& storage_key, HasV2SchemaCorruptionForTestingCallback callback) override; - void WriteToIndexedDBForTesting(const storage::BucketLocator& bucket_locator, + void WriteToIndexedDBForTesting(const blink::StorageKey& storage_key, const std::string& key, const std::string& value, base::OnceClosure callback) override; void GetBlobCountForTesting(const blink::StorageKey& storage_key, GetBlobCountForTestingCallback callback) override; void GetNextBlobNumberForTesting( - const storage::BucketLocator& bucket_locator, + const blink::StorageKey& storage_key, int64_t database_id, GetNextBlobNumberForTestingCallback callback) override; void GetPathForBlobForTesting( - const storage::BucketLocator& bucket_locator, + const blink::StorageKey& storage_key, int64_t database_id, int64_t blob_number, GetPathForBlobForTestingCallback callback) override;
diff --git a/content/browser/indexed_db/indexed_db_context_unittest.cc b/content/browser/indexed_db/indexed_db_context_unittest.cc index d8bec47..eb606e18 100644 --- a/content/browser/indexed_db/indexed_db_context_unittest.cc +++ b/content/browser/indexed_db/indexed_db_context_unittest.cc
@@ -13,7 +13,6 @@ #include "base/threading/thread.h" #include "base/time/default_clock.h" #include "components/services/storage/public/cpp/buckets/bucket_info.h" -#include "components/services/storage/public/cpp/buckets/bucket_locator.h" #include "components/services/storage/public/cpp/buckets/constants.h" #include "components/services/storage/public/cpp/quota_error_or.h" #include "content/browser/indexed_db/indexed_db_context_impl.h" @@ -92,14 +91,10 @@ auto callbacks = base::MakeRefCounted<MockIndexedDBCallbacks>( /*expect_connection=*/false); callbacks->CallOnInfoSuccess(base::BarrierClosure(2, loop.QuitClosure())); - auto example_bucket_locator = storage::BucketLocator(); - example_bucket_locator.storage_key = example_storage_key_; indexed_db_context_->GetIDBFactory()->GetDatabaseInfo( - callbacks, example_bucket_locator, indexed_db_context_->data_path()); - auto google_bucket_locator = storage::BucketLocator(); - google_bucket_locator.storage_key = google_storage_key_; + callbacks, example_storage_key_, indexed_db_context_->data_path()); indexed_db_context_->GetIDBFactory()->GetDatabaseInfo( - callbacks, google_bucket_locator, indexed_db_context_->data_path()); + callbacks, google_storage_key_, indexed_db_context_->data_path()); loop.Run(); // Check default bucket exists for https://example.com.
diff --git a/content/browser/indexed_db/indexed_db_cursor.cc b/content/browser/indexed_db/indexed_db_cursor.cc index 7af4a72..aa395181 100644 --- a/content/browser/indexed_db/indexed_db_cursor.cc +++ b/content/browser/indexed_db/indexed_db_cursor.cc
@@ -12,7 +12,6 @@ #include "base/check_op.h" #include "base/notreached.h" #include "base/trace_event/base_tracing.h" -#include "components/services/storage/public/cpp/buckets/bucket_locator.h" #include "content/browser/indexed_db/indexed_db_callback_helpers.h" #include "content/browser/indexed_db/indexed_db_callbacks.h" #include "content/browser/indexed_db/indexed_db_context_impl.h" @@ -52,9 +51,9 @@ indexed_db::CursorType cursor_type, blink::mojom::IDBTaskType task_type, base::WeakPtr<IndexedDBTransaction> transaction) - : bucket_locator_(transaction->BackingStoreTransaction() - ->backing_store() - ->bucket_locator()), + : storage_key_(transaction->BackingStoreTransaction() + ->backing_store() + ->storage_key()), task_type_(task_type), cursor_type_(cursor_type), transaction_(std::move(transaction)), @@ -129,7 +128,7 @@ if (value) { mojo_value = IndexedDBValue::ConvertAndEraseValue(value); external_objects.swap(value->external_objects); - dispatcher_host->CreateAllExternalObjects(bucket_locator_, external_objects, + dispatcher_host->CreateAllExternalObjects(storage_key_, external_objects, &mojo_value->external_objects); } else { mojo_value = blink::mojom::IDBValue::New(); @@ -210,7 +209,7 @@ if (value) { mojo_value = IndexedDBValue::ConvertAndEraseValue(value); external_objects.swap(value->external_objects); - dispatcher_host->CreateAllExternalObjects(bucket_locator_, external_objects, + dispatcher_host->CreateAllExternalObjects(storage_key_, external_objects, &mojo_value->external_objects); } else { mojo_value = blink::mojom::IDBValue::New(); @@ -338,7 +337,7 @@ mojo_values.push_back( IndexedDBValue::ConvertAndEraseValue(&found_values[i])); dispatcher_host->CreateAllExternalObjects( - bucket_locator_, found_values[i].external_objects, + storage_key_, found_values[i].external_objects, &mojo_values[i]->external_objects); }
diff --git a/content/browser/indexed_db/indexed_db_cursor.h b/content/browser/indexed_db/indexed_db_cursor.h index 08d5f30..2ec5598 100644 --- a/content/browser/indexed_db/indexed_db_cursor.h +++ b/content/browser/indexed_db/indexed_db_cursor.h
@@ -15,12 +15,9 @@ #include "content/browser/indexed_db/indexed_db_database.h" #include "content/browser/indexed_db/indexed_db_transaction.h" #include "third_party/blink/public/common/indexeddb/web_idb_types.h" +#include "third_party/blink/public/common/storage_key/storage_key.h" #include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom-forward.h" -namespace storage { -struct BucketLocator; -} // namespace storage - namespace content { class IndexedDBCursor { @@ -81,7 +78,7 @@ IndexedDBTransaction* transaction); private: - const storage::BucketLocator bucket_locator_; + const blink::StorageKey storage_key_; blink::mojom::IDBTaskType task_type_; indexed_db::CursorType cursor_type_;
diff --git a/content/browser/indexed_db/indexed_db_database.cc b/content/browser/indexed_db/indexed_db_database.cc index 912be1d..58c59f3 100644 --- a/content/browser/indexed_db/indexed_db_database.cc +++ b/content/browser/indexed_db/indexed_db_database.cc
@@ -70,14 +70,14 @@ std::vector<blink::mojom::IDBReturnValuePtr> CreateMojoValues( std::vector<IndexedDBReturnValue>& found_values, IndexedDBDispatcherHost* dispatcher_host, - const storage::BucketLocator& bucket_locator) { + const blink::StorageKey& storage_key) { std::vector<blink::mojom::IDBReturnValuePtr> mojo_values; mojo_values.reserve(found_values.size()); for (size_t i = 0; i < found_values.size(); ++i) { mojo_values.push_back( IndexedDBReturnValue::ConvertReturnValue(&found_values[i])); dispatcher_host->CreateAllExternalObjects( - bucket_locator, found_values[i].external_objects, + storage_key, found_values[i].external_objects, &mojo_values[i]->value->external_objects); } return mojo_values; @@ -843,7 +843,7 @@ blink::mojom::IDBReturnValuePtr mojo_value = IndexedDBReturnValue::ConvertReturnValue(&value); dispatcher_host->CreateAllExternalObjects( - bucket_locator(), value.external_objects, + storage_key(), value.external_objects, &mojo_value->value->external_objects); std::move(callback).Run( blink::mojom::IDBDatabaseGetResult::NewValue(std::move(mojo_value))); @@ -901,7 +901,7 @@ blink::mojom::IDBReturnValuePtr mojo_value = IndexedDBReturnValue::ConvertReturnValue(&value); dispatcher_host->CreateAllExternalObjects( - bucket_locator(), value.external_objects, + storage_key(), value.external_objects, &mojo_value->value->external_objects); std::move(callback).Run( blink::mojom::IDBDatabaseGetResult::NewValue(std::move(mojo_value))); @@ -1063,7 +1063,7 @@ } else { if (found_values.size() >= max_values_before_sending) { result_sink->ReceiveValues(CreateMojoValues( - found_values, dispatcher_host.get(), bucket_locator())); + found_values, dispatcher_host.get(), storage_key())); found_values.clear(); } } @@ -1075,8 +1075,8 @@ } } else { if (!found_values.empty()) { - result_sink->ReceiveValues(CreateMojoValues( - found_values, dispatcher_host.get(), bucket_locator())); + result_sink->ReceiveValues( + CreateMojoValues(found_values, dispatcher_host.get(), storage_key())); } } return s; @@ -1209,9 +1209,8 @@ std::move(params->callback) .Run(blink::mojom::IDBTransactionPutResult::NewKey(*key)); } - // TODO(crbug.com/1218100): Propagate BucketLocator to callee. factory_->NotifyIndexedDBContentChanged( - bucket_locator().storage_key, metadata_.name, + storage_key(), metadata_.name, metadata_.object_stores[params->object_store_id].name); return s; } @@ -1402,7 +1401,7 @@ mojo_values.push_back( IndexedDBReturnValue::ConvertReturnValue(&found_values[j])); dispatcher_host->CreateAllExternalObjects( - bucket_locator(), found_values[j].external_objects, + storage_key(), found_values[j].external_objects, &mojo_values[j]->value->external_objects); } all_mojo_values.push_back(std::move(mojo_values)); @@ -1506,7 +1505,9 @@ } if (mojo_value) { - dispatcher_host->CreateAllExternalObjects(bucket_locator, external_objects, + // TODO(crbug.com/1218100): Propagate BucketLocator to callee. + dispatcher_host->CreateAllExternalObjects(bucket_locator.storage_key, + external_objects, &mojo_value->external_objects); } @@ -1581,9 +1582,8 @@ if (!s.ok()) return s; callbacks->OnSuccess(); - // TODO(crbug.com/1218100): Propagate BucketLocator to callee. factory_->NotifyIndexedDBContentChanged( - bucket_locator().storage_key, metadata_.name, + storage_key(), metadata_.name, metadata_.object_stores[object_store_id].name); return s; } @@ -1628,9 +1628,8 @@ return s; callbacks->OnSuccess(); - // TODO(crbug.com/1218100): Propagate BucketLocator to callee. factory_->NotifyIndexedDBContentChanged( - bucket_locator().storage_key, metadata_.name, + storage_key(), metadata_.name, metadata_.object_stores[object_store_id].name); return s; }
diff --git a/content/browser/indexed_db/indexed_db_database.h b/content/browser/indexed_db/indexed_db_database.h index 00e81bf0..56e5687 100644 --- a/content/browser/indexed_db/indexed_db_database.h +++ b/content/browser/indexed_db/indexed_db_database.h
@@ -34,6 +34,7 @@ #include "content/common/content_export.h" #include "third_party/blink/public/common/indexeddb/indexeddb_key.h" #include "third_party/blink/public/common/indexeddb/web_idb_types.h" +#include "third_party/blink/public/common/storage_key/storage_key.h" #include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom-forward.h" namespace blink { @@ -56,8 +57,8 @@ class CONTENT_EXPORT IndexedDBDatabase { public: - // Identifier is pair of (bucket_locator, database name). - using Identifier = std::pair<storage::BucketLocator, std::u16string>; + // Identifier is pair of (storage_key, database name). + using Identifier = std::pair<blink::StorageKey, std::u16string>; // Used to report irrecoverable backend errors. The second argument can be // null. using ErrorCallback = @@ -76,9 +77,7 @@ int64_t id() const { return metadata_.id; } const std::u16string& name() const { return metadata_.name; } - const storage::BucketLocator& bucket_locator() const { - return identifier_.first; - } + const blink::StorageKey& storage_key() const { return identifier_.first; } const blink::IndexedDBDatabaseMetadata& metadata() const { return metadata_; } LeveledLockManager* transaction_lock_manager() { return lock_manager_; }
diff --git a/content/browser/indexed_db/indexed_db_database_callbacks.cc b/content/browser/indexed_db/indexed_db_database_callbacks.cc index beaa2c8..79df6b3 100644 --- a/content/browser/indexed_db/indexed_db_database_callbacks.cc +++ b/content/browser/indexed_db/indexed_db_database_callbacks.cc
@@ -79,9 +79,8 @@ if (complete_) return; - // TODO(crbug.com/1218100): Propagate BucketLocator to callee. indexed_db_context_->TransactionComplete( - transaction.database()->bucket_locator().storage_key); + transaction.database()->storage_key()); if (callbacks_) callbacks_->Complete(transaction.id()); }
diff --git a/content/browser/indexed_db/indexed_db_dispatcher_host.cc b/content/browser/indexed_db/indexed_db_dispatcher_host.cc index f020c385..d84539b7 100644 --- a/content/browser/indexed_db/indexed_db_dispatcher_host.cc +++ b/content/browser/indexed_db/indexed_db_dispatcher_host.cc
@@ -291,8 +291,9 @@ IDBTaskRunner()); base::FilePath indexed_db_path = indexed_db_context_->data_path(); + // TODO(crbug.com/1218100): Propagate BucketLocator to callee. indexed_db_context_->GetIDBFactory()->GetDatabaseInfo( - std::move(callbacks), bucket_locator, indexed_db_path); + std::move(callbacks), bucket_locator.storage_key, indexed_db_path); } void IndexedDBDispatcherHost::Open( @@ -336,8 +337,9 @@ // TODO(dgrogan): Don't let a non-existing database be opened (and therefore // created) if this origin is already over quota. - indexed_db_context_->GetIDBFactory()->Open(name, std::move(connection), - bucket_locator, indexed_db_path); + // TODO(crbug.com/1218100): Propagate BucketLocator to callee. + indexed_db_context_->GetIDBFactory()->Open( + name, std::move(connection), bucket_locator.storage_key, indexed_db_path); } void IndexedDBDispatcherHost::DeleteDatabase( @@ -363,8 +365,10 @@ IDBTaskRunner()); base::FilePath indexed_db_path = indexed_db_context_->data_path(); + // TODO(crbug.com/1218100): Propagate BucketLocator to callee. indexed_db_context_->GetIDBFactory()->DeleteDatabase( - name, std::move(callbacks), bucket_locator, indexed_db_path, force_close); + name, std::move(callbacks), bucket_locator.storage_key, indexed_db_path, + force_close); } void IndexedDBDispatcherHost::AbortTransactionsAndCompactDatabase( @@ -444,7 +448,7 @@ } void IndexedDBDispatcherHost::CreateAllExternalObjects( - const storage::BucketLocator& bucket_locator, + const blink::StorageKey& storage_key, const std::vector<IndexedDBExternalObject>& objects, std::vector<blink::mojom::IDBExternalObjectPtr>* mojo_objects) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); @@ -509,7 +513,7 @@ } else { DCHECK(!blob_info.file_system_access_token().empty()); file_system_access_context()->DeserializeHandle( - bucket_locator.storage_key, blob_info.file_system_access_token(), + storage_key, blob_info.file_system_access_token(), mojo_token.InitWithNewPipeAndPassReceiver()); } mojo_object->get_file_system_access_token() = std::move(mojo_token);
diff --git a/content/browser/indexed_db/indexed_db_dispatcher_host.h b/content/browser/indexed_db/indexed_db_dispatcher_host.h index 5a85a8c..bec07d6 100644 --- a/content/browser/indexed_db/indexed_db_dispatcher_host.h +++ b/content/browser/indexed_db/indexed_db_dispatcher_host.h
@@ -28,7 +28,11 @@ namespace base { class SequencedTaskRunner; class TaskRunner; -} // namespace base +} + +namespace blink { +class StorageKey; +} namespace content { class IndexedDBContextImpl; @@ -93,7 +97,7 @@ // Create external objects from |objects| and store the results in // |mojo_objects|. |mojo_objects| must be the same length as |objects|. void CreateAllExternalObjects( - const storage::BucketLocator& bucket_locator, + const blink::StorageKey& storage_key, const std::vector<IndexedDBExternalObject>& objects, std::vector<blink::mojom::IDBExternalObjectPtr>* mojo_objects);
diff --git a/content/browser/indexed_db/indexed_db_factory.h b/content/browser/indexed_db/indexed_db_factory.h index a500bf5..c325be9 100644 --- a/content/browser/indexed_db/indexed_db_factory.h +++ b/content/browser/indexed_db/indexed_db_factory.h
@@ -24,10 +24,6 @@ #include "third_party/blink/public/common/storage_key/storage_key.h" #include "url/gurl.h" -namespace storage { -struct BucketLocator; -} // namespace storage - namespace content { class IndexedDBBackingStore; @@ -42,16 +38,16 @@ virtual ~IndexedDBFactory() = default; virtual void GetDatabaseInfo(scoped_refptr<IndexedDBCallbacks> callbacks, - const storage::BucketLocator& bucket_locator, + const blink::StorageKey& storage_key, const base::FilePath& data_directory) = 0; virtual void Open(const std::u16string& name, std::unique_ptr<IndexedDBPendingConnection> connection, - const storage::BucketLocator& bucket_locator, + const blink::StorageKey& storage_key, const base::FilePath& data_directory) = 0; virtual void DeleteDatabase(const std::u16string& name, scoped_refptr<IndexedDBCallbacks> callbacks, - const storage::BucketLocator& bucket_locator, + const blink::StorageKey& storage_key, const base::FilePath& data_directory, bool force_close) = 0;
diff --git a/content/browser/indexed_db/indexed_db_factory_impl.cc b/content/browser/indexed_db/indexed_db_factory_impl.cc index 231b6f93..fcd6f8f 100644 --- a/content/browser/indexed_db/indexed_db_factory_impl.cc +++ b/content/browser/indexed_db/indexed_db_factory_impl.cc
@@ -39,7 +39,6 @@ #include "components/services/storage/indexed_db/scopes/leveldb_scopes_factory.h" #include "components/services/storage/indexed_db/transactional_leveldb/transactional_leveldb_database.h" #include "components/services/storage/indexed_db/transactional_leveldb/transactional_leveldb_factory.h" -#include "components/services/storage/public/cpp/buckets/bucket_locator.h" #include "components/services/storage/public/cpp/filesystem/filesystem_proxy.h" #include "components/services/storage/public/mojom/blob_storage_context.mojom.h" #include "components/services/storage/public/mojom/indexed_db_control.mojom.h" @@ -189,7 +188,7 @@ void IndexedDBFactoryImpl::GetDatabaseInfo( scoped_refptr<IndexedDBCallbacks> callbacks, - const storage::BucketLocator& bucket_locator, + const blink::StorageKey& storage_key, const base::FilePath& data_directory) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); TRACE_EVENT0("IndexedDB", "IndexedDBFactoryImpl::GetDatabaseInfo"); @@ -200,7 +199,7 @@ // Note: Any data loss information here is not piped up to the renderer, and // will be lost. std::tie(bucket_state_handle, s, error, std::ignore, std::ignore) = - GetOrOpenBucketFactory(bucket_locator, data_directory, + GetOrOpenBucketFactory(storage_key, data_directory, /*create_if_missing=*/false); if (!bucket_state_handle.IsHeld() || !bucket_state_handle.bucket_state()) { if (s.IsNotFound()) { @@ -208,10 +207,8 @@ } else { callbacks->OnError(error); } - if (s.IsCorruption()) { - // TODO(crbug.com/1218100): Propagate BucketLocator to callee. - HandleBackingStoreCorruption(bucket_locator.storage_key, error); - } + if (s.IsCorruption()) + HandleBackingStoreCorruption(storage_key, error); return; } IndexedDBBucketState* factory = bucket_state_handle.bucket_state(); @@ -225,10 +222,8 @@ "Internal error opening backing store for " "indexedDB.databases()."); callbacks->OnError(error); - if (s.IsCorruption()) { - // TODO(crbug.com/1218100): Propagate BucketLocator to callee. - HandleBackingStoreCorruption(bucket_locator.storage_key, error); - } + if (s.IsCorruption()) + HandleBackingStoreCorruption(storage_key, error); return; } callbacks->OnSuccess(std::move(names_and_versions)); @@ -237,24 +232,22 @@ void IndexedDBFactoryImpl::Open( const std::u16string& name, std::unique_ptr<IndexedDBPendingConnection> connection, - const storage::BucketLocator& bucket_locator, + const blink::StorageKey& storage_key, const base::FilePath& data_directory) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); TRACE_EVENT0("IndexedDB", "IndexedDBFactoryImpl::Open"); - IndexedDBDatabase::Identifier unique_identifier(bucket_locator, name); + IndexedDBDatabase::Identifier unique_identifier(storage_key, name); IndexedDBBucketStateHandle bucket_state_handle; leveldb::Status s; IndexedDBDatabaseError error; std::tie(bucket_state_handle, s, error, connection->data_loss_info, connection->was_cold_open) = - GetOrOpenBucketFactory(bucket_locator, data_directory, + GetOrOpenBucketFactory(storage_key, data_directory, /*create_if_missing=*/true); if (!bucket_state_handle.IsHeld() || !bucket_state_handle.bucket_state()) { connection->callbacks->OnError(error); - if (s.IsCorruption()) { - // TODO(crbug.com/1218100): Propagate BucketLocator to callee. - HandleBackingStoreCorruption(bucket_locator.storage_key, error); - } + if (s.IsCorruption()) + HandleBackingStoreCorruption(storage_key, error); return; } IndexedDBBucketState* factory = bucket_state_handle.bucket_state(); @@ -265,12 +258,11 @@ return; } std::unique_ptr<IndexedDBDatabase> database; - // TODO(crbug.com/1218100): Propagate BucketLocator to callee. std::tie(database, s) = class_factory_->CreateIndexedDBDatabase( name, factory->backing_store(), this, base::BindRepeating(&IndexedDBFactoryImpl::MaybeRunTasksForBucket, bucket_state_destruction_weak_factory_.GetWeakPtr(), - bucket_locator.storage_key), + storage_key), std::make_unique<IndexedDBMetadataCoding>(), std::move(unique_identifier), factory->lock_manager()); if (!database.get()) { @@ -278,10 +270,8 @@ blink::mojom::IDBException::kUnknownError, u"Internal error creating database backend for indexedDB.open."); connection->callbacks->OnError(error); - if (s.IsCorruption()) { - // TODO(crbug.com/1218100): Propagate BucketLocator to callee. - HandleBackingStoreCorruption(bucket_locator.storage_key, error); - } + if (s.IsCorruption()) + HandleBackingStoreCorruption(storage_key, error); return; } @@ -296,26 +286,24 @@ void IndexedDBFactoryImpl::DeleteDatabase( const std::u16string& name, scoped_refptr<IndexedDBCallbacks> callbacks, - const storage::BucketLocator& bucket_locator, + const blink::StorageKey& storage_key, const base::FilePath& data_directory, bool force_close) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); TRACE_EVENT0("IndexedDB", "IndexedDBFactoryImpl::DeleteDatabase"); - IndexedDBDatabase::Identifier unique_identifier(bucket_locator, name); + IndexedDBDatabase::Identifier unique_identifier(storage_key, name); IndexedDBBucketStateHandle bucket_state_handle; leveldb::Status s; IndexedDBDatabaseError error; // Note: Any data loss information here is not piped up to the renderer, and // will be lost. std::tie(bucket_state_handle, s, error, std::ignore, std::ignore) = - GetOrOpenBucketFactory(bucket_locator, data_directory, + GetOrOpenBucketFactory(storage_key, data_directory, /*create_if_missing=*/true); if (!bucket_state_handle.IsHeld() || !bucket_state_handle.bucket_state()) { callbacks->OnError(error); - if (s.IsCorruption()) { - // TODO(crbug.com/1218100): Propagate BucketLocator to callee. - HandleBackingStoreCorruption(bucket_locator.storage_key, error); - } + if (s.IsCorruption()) + HandleBackingStoreCorruption(storage_key, error); return; } IndexedDBBucketState* factory = bucket_state_handle.bucket_state(); @@ -323,18 +311,14 @@ auto it = factory->databases().find(name); if (it != factory->databases().end()) { base::WeakPtr<IndexedDBDatabase> database = it->second->AsWeakPtr(); - // TODO(crbug.com/1218100): Propagate BucketLocator to callee. database->ScheduleDeleteDatabase( std::move(bucket_state_handle), callbacks, base::BindOnce(&IndexedDBFactoryImpl::OnDatabaseDeleted, - weak_factory_.GetWeakPtr(), bucket_locator.storage_key)); + weak_factory_.GetWeakPtr(), storage_key)); if (force_close) { leveldb::Status status = database->ForceCloseAndRunTasks(); - if (!status.ok()) { - // TODO(crbug.com/1218100): Propagate BucketLocator to callee. - OnDatabaseError(bucket_locator.storage_key, status, - "Error aborting transactions."); - } + if (!status.ok()) + OnDatabaseError(storage_key, status, "Error aborting transactions."); } return; } @@ -351,10 +335,8 @@ "Internal error opening backing store for " "indexedDB.deleteDatabase."); callbacks->OnError(error); - if (s.IsCorruption()) { - // TODO(crbug.com/1218100): Propagate BucketLocator to callee. - HandleBackingStoreCorruption(bucket_locator.storage_key, error); - } + if (s.IsCorruption()) + HandleBackingStoreCorruption(storage_key, error); return; } @@ -365,12 +347,11 @@ } std::unique_ptr<IndexedDBDatabase> database; - // TODO(crbug.com/1218100): Propagate BucketLocator to callee. std::tie(database, s) = class_factory_->CreateIndexedDBDatabase( name, factory->backing_store(), this, base::BindRepeating(&IndexedDBFactoryImpl::MaybeRunTasksForBucket, bucket_state_destruction_weak_factory_.GetWeakPtr(), - bucket_locator.storage_key), + storage_key), std::make_unique<IndexedDBMetadataCoding>(), unique_identifier, factory->lock_manager()); if (!database.get()) { @@ -378,27 +359,21 @@ u"Internal error creating database backend " u"for indexedDB.deleteDatabase."); callbacks->OnError(error); - if (s.IsCorruption()) { - // TODO(crbug.com/1218100): Propagate BucketLocator to callee. - HandleBackingStoreCorruption(bucket_locator.storage_key, error); - } + if (s.IsCorruption()) + HandleBackingStoreCorruption(storage_key, error); return; } base::WeakPtr<IndexedDBDatabase> database_ptr = factory->AddDatabase(name, std::move(database))->AsWeakPtr(); - // TODO(crbug.com/1218100): Propagate BucketLocator to callee. database_ptr->ScheduleDeleteDatabase( std::move(bucket_state_handle), std::move(callbacks), base::BindOnce(&IndexedDBFactoryImpl::OnDatabaseDeleted, - weak_factory_.GetWeakPtr(), bucket_locator.storage_key)); + weak_factory_.GetWeakPtr(), storage_key)); if (force_close) { leveldb::Status status = database_ptr->ForceCloseAndRunTasks(); - if (!status.ok()) { - // TODO(crbug.com/1218100): Propagate BucketLocator to callee. - OnDatabaseError(bucket_locator.storage_key, status, - "Error aborting transactions."); - } + if (!status.ok()) + OnDatabaseError(storage_key, status, "Error aborting transactions."); } } @@ -649,7 +624,7 @@ IndexedDBDataLossInfo, /*is_cold_open=*/bool> IndexedDBFactoryImpl::GetOrOpenBucketFactory( - const storage::BucketLocator& bucket_locator, + const blink::StorageKey& storage_key, const base::FilePath& data_directory, bool create_if_missing) { TRACE_EVENT0("IndexedDB", "indexed_db::GetOrOpenBucketFactory"); @@ -659,8 +634,7 @@ // where the flowchart should be seen as the 'master' logic template. Please // check the git history of both to make sure they are in sync. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - // TODO(crbug.com/1218100): Propagate BucketLocator to callee. - auto it = factories_per_bucket_.find(bucket_locator.storage_key); + auto it = factories_per_bucket_.find(storage_key); if (it != factories_per_bucket_.end()) { return {it->second->CreateHandle(), leveldb::Status::OK(), IndexedDBDatabaseError(), IndexedDBDataLossInfo(), @@ -677,9 +651,8 @@ if (!is_incognito_and_in_memory) { // The database will be on-disk and not in-memory. auto filesystem_proxy = storage::CreateFilesystemProxy(); - // TODO(crbug.com/1218100): Propagate BucketLocator to callee. std::tie(database_path, blob_path, s) = CreateDatabaseDirectories( - filesystem_proxy.get(), data_directory, bucket_locator.storage_key); + filesystem_proxy.get(), data_directory, storage_key); if (!s.ok()) return {IndexedDBBucketStateHandle(), s, CreateDefaultError(), IndexedDBDataLossInfo(), /*was_cold_open=*/true}; @@ -700,21 +673,20 @@ scopes_options.lock_manager = lock_manager.get(); scopes_options.metadata_key_prefix = ScopesPrefix::Encode(); scopes_options.failure_callback = base::BindRepeating( - [](const storage::BucketLocator& bucket_locator, + [](const blink::StorageKey& storage_key, base::WeakPtr<IndexedDBFactoryImpl> factory, leveldb::Status s) { if (!factory) return; - // TODO(crbug.com/1218100): Propagate BucketLocator to callee. - factory->OnDatabaseError(bucket_locator.storage_key, s, nullptr); + factory->OnDatabaseError(storage_key, s, nullptr); }, - bucket_locator, weak_factory_.GetWeakPtr()); + storage_key, weak_factory_.GetWeakPtr()); const bool is_first_attempt = i == 0; auto filesystem_proxy = !is_incognito_and_in_memory ? storage::CreateFilesystemProxy() : nullptr; std::tie(backing_store, s, data_loss_info, disk_full) = OpenAndVerifyIndexedDBBackingStore( - bucket_locator, data_directory, database_path, blob_path, + storage_key, data_directory, database_path, blob_path, std::move(scopes_options), &scopes_factory, std::move(filesystem_proxy), is_first_attempt, create_if_missing); if (LIKELY(is_first_attempt)) @@ -729,13 +701,10 @@ std::string sanitized_message = leveldb_env::GetCorruptionMessage(s); base::ReplaceSubstringsAfterOffset(&sanitized_message, 0u, data_directory.AsUTF8Unsafe(), "..."); - // TODO(crbug.com/1218100): Propagate BucketLocator to callee. - LOG(ERROR) << "Got corruption for " - << bucket_locator.storage_key.GetDebugString() << ", " - << sanitized_message; - // TODO(crbug.com/1218100): Propagate BucketLocator to callee. - IndexedDBBackingStore::RecordCorruptionInfo( - data_directory, bucket_locator.storage_key, sanitized_message); + LOG(ERROR) << "Got corruption for " << storage_key.GetDebugString() + << ", " << sanitized_message; + IndexedDBBackingStore::RecordCorruptionInfo(data_directory, storage_key, + sanitized_message); } } @@ -751,14 +720,11 @@ } if (UNLIKELY(!s.ok())) { - // TODO(crbug.com/1218100): Propagate BucketLocator to callee. ReportOpenStatus(indexed_db::INDEXED_DB_BACKING_STORE_OPEN_NO_RECOVERY, - bucket_locator.storage_key); + storage_key); if (disk_full) { - // TODO(crbug.com/1218100): Propagate BucketLocator to callee. - context_->quota_manager_proxy()->NotifyWriteFailed( - bucket_locator.storage_key); + context_->quota_manager_proxy()->NotifyWriteFailed(storage_key); return {IndexedDBBucketStateHandle(), s, IndexedDBDatabaseError(blink::mojom::IDBException::kQuotaError, u"Encountered full disk while opening " @@ -777,9 +743,8 @@ LevelDBScopes::TaskRunnerMode::kNewCleanupAndRevertSequences); if (UNLIKELY(!s.ok())) { - // TODO(crbug.com/1218100): Propagate BucketLocator to callee. ReportOpenStatus(indexed_db::INDEXED_DB_BACKING_STORE_OPEN_NO_RECOVERY, - bucket_locator.storage_key); + storage_key); return {IndexedDBBucketStateHandle(), s, CreateDefaultError(), data_loss_info, /*was_cold_open=*/true}; @@ -787,39 +752,32 @@ if (!is_incognito_and_in_memory) ReportOpenStatus(indexed_db::INDEXED_DB_BACKING_STORE_OPEN_SUCCESS, - bucket_locator.storage_key); + storage_key); - // TODO(crbug.com/1218100): Propagate BucketLocator to callee. - auto run_tasks_callback = - base::BindRepeating(&IndexedDBFactoryImpl::MaybeRunTasksForBucket, - bucket_state_destruction_weak_factory_.GetWeakPtr(), - bucket_locator.storage_key); + auto run_tasks_callback = base::BindRepeating( + &IndexedDBFactoryImpl::MaybeRunTasksForBucket, + bucket_state_destruction_weak_factory_.GetWeakPtr(), storage_key); auto tear_down_callback = base::BindRepeating( - [](const storage::BucketLocator& bucket_locator, + [](const blink::StorageKey& storage_key, base::WeakPtr<IndexedDBFactoryImpl> factory, leveldb::Status s) { if (!factory) return; - // TODO(crbug.com/1218100): Propagate BucketLocator to callee. - factory->OnDatabaseError(bucket_locator.storage_key, s, nullptr); + factory->OnDatabaseError(storage_key, s, nullptr); }, - bucket_locator, weak_factory_.GetWeakPtr()); + storage_key, weak_factory_.GetWeakPtr()); - // TODO(crbug.com/1218100): Propagate BucketLocator to callee. auto bucket_state = std::make_unique<IndexedDBBucketState>( - bucket_locator.storage_key, + storage_key, /*persist_for_incognito=*/is_incognito_and_in_memory, clock_, &class_factory_->transactional_leveldb_factory(), &earliest_sweep_, &earliest_compaction_, std::move(lock_manager), std::move(run_tasks_callback), std::move(tear_down_callback), std::move(backing_store)); - // TODO(crbug.com/1218100): Propagate BucketLocator to callee. - it = factories_per_bucket_ - .emplace(bucket_locator.storage_key, std::move(bucket_state)) - .first; - // TODO(crbug.com/1218100): Propagate BucketLocator to callee. - context_->FactoryOpened(bucket_locator.storage_key); + it = + factories_per_bucket_.emplace(storage_key, std::move(bucket_state)).first; + context_->FactoryOpened(storage_key); return {it->second->CreateHandle(), s, IndexedDBDatabaseError(), data_loss_info, /*was_cold_open=*/true}; } @@ -827,7 +785,7 @@ std::unique_ptr<IndexedDBBackingStore> IndexedDBFactoryImpl::CreateBackingStore( IndexedDBBackingStore::Mode backing_store_mode, TransactionalLevelDBFactory* transactional_leveldb_factory, - const storage::BucketLocator& bucket_locator, + const blink::StorageKey& storage_key, const base::FilePath& blob_path, std::unique_ptr<TransactionalLevelDBDatabase> db, storage::mojom::BlobStorageContext* blob_storage_context, @@ -838,18 +796,17 @@ report_outstanding_blobs, scoped_refptr<base::SequencedTaskRunner> idb_task_runner) { return std::make_unique<IndexedDBBackingStore>( - backing_store_mode, transactional_leveldb_factory, bucket_locator, - blob_path, std::move(db), blob_storage_context, - file_system_access_context, std::move(filesystem_proxy), - std::move(blob_files_cleaned), std::move(report_outstanding_blobs), - std::move(idb_task_runner)); + backing_store_mode, transactional_leveldb_factory, storage_key, blob_path, + std::move(db), blob_storage_context, file_system_access_context, + std::move(filesystem_proxy), std::move(blob_files_cleaned), + std::move(report_outstanding_blobs), std::move(idb_task_runner)); } std::tuple<std::unique_ptr<IndexedDBBackingStore>, leveldb::Status, IndexedDBDataLossInfo, bool /* is_disk_full */> IndexedDBFactoryImpl::OpenAndVerifyIndexedDBBackingStore( - const storage::BucketLocator& bucket_locator, + const blink::StorageKey& storage_key, base::FilePath data_directory, base::FilePath database_path, base::FilePath blob_path, @@ -874,17 +831,15 @@ if (!is_incognito_and_in_memory) { // Check for previous corruption, and if found then try to delete the // database. - // TODO(crbug.com/1218100): Propagate BucketLocator to callee. std::string corruption_message = indexed_db::ReadCorruptionInfo( - filesystem_proxy.get(), data_directory, bucket_locator.storage_key); + filesystem_proxy.get(), data_directory, storage_key); if (UNLIKELY(!corruption_message.empty())) { LOG(ERROR) << "IndexedDB recovering from a corrupted (and deleted) " "database."; if (is_first_attempt) { - // TODO(crbug.com/1218100): Propagate BucketLocator to callee. ReportOpenStatus( indexed_db::INDEXED_DB_BACKING_STORE_OPEN_FAILED_PRIOR_CORRUPTION, - bucket_locator.storage_key); + storage_key); } data_loss_info.status = blink::mojom::IDBDataLoss::Total; data_loss_info.message = base::StrCat( @@ -950,41 +905,35 @@ LOG(ERROR) << "IndexedDB had an error checking schema, treating it as " "failure to open: " << status.ToString(); - // TODO(crbug.com/1218100): Propagate BucketLocator to callee. ReportOpenStatus( indexed_db:: INDEXED_DB_BACKING_STORE_OPEN_FAILED_IO_ERROR_CHECKING_SCHEMA, - bucket_locator.storage_key); + storage_key); return {nullptr, status, std::move(data_loss_info), /*is_disk_full=*/false}; } else if (UNLIKELY(!are_schemas_known)) { LOG(ERROR) << "IndexedDB backing store had unknown schema, treating it as " "failure to open."; - // TODO(crbug.com/1218100): Propagate BucketLocator to callee. ReportOpenStatus( indexed_db::INDEXED_DB_BACKING_STORE_OPEN_FAILED_UNKNOWN_SCHEMA, - bucket_locator.storage_key); + storage_key); return {nullptr, leveldb::Status::Corruption("Unknown IndexedDB schema"), std::move(data_loss_info), /*is_disk_full=*/false}; } - // TODO(crbug.com/1218100): Propagate BucketLocator to callee. bool first_open_since_startup = - backends_opened_since_startup_.insert(bucket_locator.storage_key).second; + backends_opened_since_startup_.insert(storage_key).second; IndexedDBBackingStore::Mode backing_store_mode = is_incognito_and_in_memory ? IndexedDBBackingStore::Mode::kInMemory : IndexedDBBackingStore::Mode::kOnDisk; - // TODO(crbug.com/1218100): Propagate BucketLocator to callee. std::unique_ptr<IndexedDBBackingStore> backing_store = CreateBackingStore( backing_store_mode, &class_factory_->transactional_leveldb_factory(), - bucket_locator, blob_path, std::move(database), + storage_key, blob_path, std::move(database), context_->blob_storage_context(), context_->file_system_access_context(), std::move(filesystem_proxy), base::BindRepeating(&IndexedDBFactoryImpl::BlobFilesCleaned, - weak_factory_.GetWeakPtr(), - bucket_locator.storage_key), + weak_factory_.GetWeakPtr(), storage_key), base::BindRepeating(&IndexedDBFactoryImpl::ReportOutstandingBlobs, - weak_factory_.GetWeakPtr(), - bucket_locator.storage_key), + weak_factory_.GetWeakPtr(), storage_key), context_->IDBTaskRunner()); status = backing_store->Initialize( /*clean_active_blob_journal=*/(!is_incognito_and_in_memory &&
diff --git a/content/browser/indexed_db/indexed_db_factory_impl.h b/content/browser/indexed_db/indexed_db_factory_impl.h index 1c5857fe..72d6f91 100644 --- a/content/browser/indexed_db/indexed_db_factory_impl.h +++ b/content/browser/indexed_db/indexed_db_factory_impl.h
@@ -38,11 +38,7 @@ namespace base { class FilePath; class SequencedTaskRunner; -} // namespace base - -namespace storage { -struct BucketLocator; -} // namespace storage +} namespace content { class IndexedDBBucketState; @@ -68,16 +64,16 @@ // content::IndexedDBFactory overrides: void GetDatabaseInfo(scoped_refptr<IndexedDBCallbacks> callbacks, - const storage::BucketLocator& bucket_locator, + const blink::StorageKey& storage_key, const base::FilePath& data_directory) override; void Open(const std::u16string& name, std::unique_ptr<IndexedDBPendingConnection> connection, - const storage::BucketLocator& bucket_locator, + const blink::StorageKey& storage_key, const base::FilePath& data_directory) override; void DeleteDatabase(const std::u16string& name, scoped_refptr<IndexedDBCallbacks> callbacks, - const storage::BucketLocator& bucket_locator, + const blink::StorageKey& storage_key, const base::FilePath& data_directory, bool force_close) override; @@ -142,7 +138,7 @@ IndexedDBDatabaseError, IndexedDBDataLossInfo, /*was_cold_open=*/bool> - GetOrOpenBucketFactory(const storage::BucketLocator& bucket_locator, + GetOrOpenBucketFactory(const blink::StorageKey& storage_key, const base::FilePath& data_directory, bool create_if_missing); @@ -159,7 +155,7 @@ virtual std::unique_ptr<IndexedDBBackingStore> CreateBackingStore( IndexedDBBackingStore::Mode backing_store_mode, TransactionalLevelDBFactory* leveldb_factory, - const storage::BucketLocator& bucket_locator, + const blink::StorageKey& storage_key, const base::FilePath& blob_path, std::unique_ptr<TransactionalLevelDBDatabase> db, storage::mojom::BlobStorageContext* blob_storage_context, @@ -201,7 +197,7 @@ IndexedDBDataLossInfo, bool /* is_disk_full */> OpenAndVerifyIndexedDBBackingStore( - const storage::BucketLocator& bucket_locator, + const blink::StorageKey& storage_key, base::FilePath data_directory, base::FilePath database_path, base::FilePath blob_path,
diff --git a/content/browser/indexed_db/indexed_db_factory_unittest.cc b/content/browser/indexed_db/indexed_db_factory_unittest.cc index 2728d490..c992285 100644 --- a/content/browser/indexed_db/indexed_db_factory_unittest.cc +++ b/content/browser/indexed_db/indexed_db_factory_unittest.cc
@@ -144,7 +144,7 @@ // is no actual data in the database. std::tuple<std::unique_ptr<IndexedDBConnection>, scoped_refptr<MockIndexedDBDatabaseCallbacks>> - CreateConnectionForDatatabase(const storage::BucketLocator& bucket_locator, + CreateConnectionForDatatabase(const blink::StorageKey& storage_key, const std::u16string& name) { auto callbacks = base::MakeRefCounted<MockIndexedDBCallbacks>(); auto db_callbacks = base::MakeRefCounted<MockIndexedDBDatabaseCallbacks>(); @@ -161,7 +161,7 @@ base::RunLoop loop; callbacks->CallOnUpgradeNeeded( base::BindLambdaForTesting([&]() { loop.Quit(); })); - factory()->Open(name, std::move(connection), bucket_locator, + factory()->Open(name, std::move(connection), storage_key, context()->data_path()); loop.Run(); } @@ -236,27 +236,21 @@ const blink::StorageKey storage_key_1 = blink::StorageKey::CreateFromStringForTesting("http://localhost:81"); - auto bucket_locator_1 = storage::BucketLocator(); - bucket_locator_1.storage_key = storage_key_1; const blink::StorageKey storage_key_2 = blink::StorageKey::CreateFromStringForTesting("http://localhost:82"); - auto bucket_locator_2 = storage::BucketLocator(); - bucket_locator_2.storage_key = storage_key_2; IndexedDBBucketStateHandle bucket_state1_handle; IndexedDBBucketStateHandle bucket_state2_handle; leveldb::Status s; std::tie(bucket_state1_handle, s, std::ignore, std::ignore, std::ignore) = - factory()->GetOrOpenBucketFactory(bucket_locator_1, - context()->data_path(), + factory()->GetOrOpenBucketFactory(storage_key_1, context()->data_path(), /*create_if_missing=*/true); EXPECT_TRUE(bucket_state1_handle.IsHeld()) << s.ToString(); EXPECT_TRUE(s.ok()) << s.ToString(); std::tie(bucket_state2_handle, s, std::ignore, std::ignore, std::ignore) = - factory()->GetOrOpenBucketFactory(bucket_locator_2, - context()->data_path(), + factory()->GetOrOpenBucketFactory(storage_key_2, context()->data_path(), /*create_if_missing=*/true); EXPECT_TRUE(bucket_state2_handle.IsHeld()) << s.ToString(); EXPECT_TRUE(s.ok()) << s.ToString(); @@ -274,13 +268,12 @@ const blink::StorageKey storage_key = blink::StorageKey::CreateFromStringForTesting("http://localhost:81"); - auto bucket_locator = storage::BucketLocator(); - bucket_locator.storage_key = storage_key; + IndexedDBBucketStateHandle bucket_state_handle; leveldb::Status s; std::tie(bucket_state_handle, s, std::ignore, std::ignore, std::ignore) = - factory()->GetOrOpenBucketFactory(bucket_locator, context()->data_path(), + factory()->GetOrOpenBucketFactory(storage_key, context()->data_path(), /*create_if_missing=*/true); EXPECT_TRUE(bucket_state_handle.IsHeld()) << s.ToString(); bucket_state_handle.Release(); @@ -300,13 +293,12 @@ const blink::StorageKey storage_key = blink::StorageKey::CreateFromStringForTesting("http://localhost:81"); - auto bucket_locator = storage::BucketLocator(); - bucket_locator.storage_key = storage_key; + IndexedDBBucketStateHandle bucket_state_handle; leveldb::Status s; std::tie(bucket_state_handle, s, std::ignore, std::ignore, std::ignore) = - factory()->GetOrOpenBucketFactory(bucket_locator, context()->data_path(), + factory()->GetOrOpenBucketFactory(storage_key, context()->data_path(), /*create_if_missing=*/true); EXPECT_TRUE(bucket_state_handle.IsHeld()) << s.ToString(); bucket_state_handle.Release(); @@ -324,15 +316,14 @@ const blink::StorageKey storage_key = blink::StorageKey::CreateFromStringForTesting("http://localhost:81"); - auto bucket_locator = storage::BucketLocator(); - bucket_locator.storage_key = storage_key; + IndexedDBBucketStateHandle bucket_state_handle; leveldb::Status s; // Open a connection & immediately release it to cause the closing sequence to // start. std::tie(bucket_state_handle, s, std::ignore, std::ignore, std::ignore) = - factory()->GetOrOpenBucketFactory(bucket_locator, context()->data_path(), + factory()->GetOrOpenBucketFactory(storage_key, context()->data_path(), /*create_if_missing=*/true); EXPECT_TRUE(bucket_state_handle.IsHeld()) << s.ToString(); bucket_state_handle.Release(); @@ -356,7 +347,7 @@ // Open a connection & immediately release it to cause the closing sequence to // start again. std::tie(bucket_state_handle, s, std::ignore, std::ignore, std::ignore) = - factory()->GetOrOpenBucketFactory(bucket_locator, context()->data_path(), + factory()->GetOrOpenBucketFactory(storage_key, context()->data_path(), /*create_if_missing=*/true); EXPECT_TRUE(bucket_state_handle.IsHeld()) << s.ToString(); bucket_state_handle.Release(); @@ -377,7 +368,7 @@ // Stop sweep by opening a connection. std::tie(bucket_state_handle, s, std::ignore, std::ignore, std::ignore) = - factory()->GetOrOpenBucketFactory(bucket_locator, context()->data_path(), + factory()->GetOrOpenBucketFactory(storage_key, context()->data_path(), /*create_if_missing=*/true); EXPECT_TRUE(bucket_state_handle.IsHeld()) << s.ToString(); EXPECT_FALSE( @@ -403,7 +394,7 @@ // Finally, move the clock forward so the storage key should allow a sweep. clock.Advance(IndexedDBBucketState::kMaxEarliestBucketSweepFromNow); std::tie(bucket_state_handle, s, std::ignore, std::ignore, std::ignore) = - factory()->GetOrOpenBucketFactory(bucket_locator, context()->data_path(), + factory()->GetOrOpenBucketFactory(storage_key, context()->data_path(), /*create_if_missing=*/true); bucket_state_handle.Release(); factory()->GetBucketFactory(storage_key)->close_timer()->FireNow(); @@ -425,15 +416,14 @@ const blink::StorageKey storage_key = blink::StorageKey::CreateFromStringForTesting("http://localhost:81"); - auto bucket_locator = storage::BucketLocator(); - bucket_locator.storage_key = storage_key; + IndexedDBBucketStateHandle bucket_state_handle; leveldb::Status s; // Open a connection & immediately release it to cause the closing sequence to // start. std::tie(bucket_state_handle, s, std::ignore, std::ignore, std::ignore) = - factory()->GetOrOpenBucketFactory(bucket_locator, context()->data_path(), + factory()->GetOrOpenBucketFactory(storage_key, context()->data_path(), /*create_if_missing=*/true); EXPECT_TRUE(bucket_state_handle.IsHeld()) << s.ToString(); @@ -464,15 +454,14 @@ const blink::StorageKey storage_key = blink::StorageKey::CreateFromStringForTesting("http://localhost:81"); - auto bucket_locator = storage::BucketLocator(); - bucket_locator.storage_key = storage_key; + IndexedDBBucketStateHandle bucket_state_handle; leveldb::Status s; // Open a connection & immediately release it to cause the closing sequence to // start. std::tie(bucket_state_handle, s, std::ignore, std::ignore, std::ignore) = - factory()->GetOrOpenBucketFactory(bucket_locator, context()->data_path(), + factory()->GetOrOpenBucketFactory(storage_key, context()->data_path(), /*create_if_missing=*/true); EXPECT_TRUE(bucket_state_handle.IsHeld()) << s.ToString(); @@ -506,15 +495,13 @@ const blink::StorageKey storage_key = blink::StorageKey::CreateFromStringForTesting("http://localhost:81"); - auto bucket_locator = storage::BucketLocator(); - bucket_locator.storage_key = storage_key; IndexedDBBucketStateHandle bucket_state_handle; leveldb::Status s; // Open a connection & immediately release it to cause the closing sequence to // start. std::tie(bucket_state_handle, s, std::ignore, std::ignore, std::ignore) = - factory()->GetOrOpenBucketFactory(bucket_locator, context()->data_path(), + factory()->GetOrOpenBucketFactory(storage_key, context()->data_path(), /*create_if_missing=*/true); EXPECT_TRUE(bucket_state_handle.IsHeld()) << s.ToString(); @@ -527,13 +514,12 @@ const blink::StorageKey storage_key = blink::StorageKey::CreateFromStringForTesting("http://localhost:81"); - auto bucket_locator = storage::BucketLocator(); - bucket_locator.storage_key = storage_key; + IndexedDBBucketStateHandle bucket_state_handle; leveldb::Status s; std::tie(bucket_state_handle, s, std::ignore, std::ignore, std::ignore) = - factory()->GetOrOpenBucketFactory(bucket_locator, context()->data_path(), + factory()->GetOrOpenBucketFactory(storage_key, context()->data_path(), /*create_if_missing=*/true); EXPECT_TRUE(bucket_state_handle.IsHeld()) << s.ToString(); EXPECT_TRUE(StorageBucketFromHandle(bucket_state_handle) @@ -562,13 +548,12 @@ const blink::StorageKey too_long_storage_key = blink::StorageKey::CreateFromStringForTesting("http://" + origin + ":81/"); - auto too_long_bucket_locator = storage::BucketLocator(); - too_long_bucket_locator.storage_key = too_long_storage_key; + IndexedDBBucketStateHandle bucket_state_handle; leveldb::Status s; std::tie(bucket_state_handle, s, std::ignore, std::ignore, std::ignore) = - factory()->GetOrOpenBucketFactory(too_long_bucket_locator, + factory()->GetOrOpenBucketFactory(too_long_storage_key, context()->data_path(), /*create_if_missing=*/true); EXPECT_FALSE(bucket_state_handle.IsHeld()); @@ -579,8 +564,6 @@ SetupContext(); const blink::StorageKey storage_key = blink::StorageKey::CreateFromStringForTesting("http://localhost:81"); - auto bucket_locator = storage::BucketLocator(); - bucket_locator.storage_key = storage_key; auto callbacks = base::MakeRefCounted<MockIndexedDBCallbacks>(); auto db_callbacks = base::MakeRefCounted<MockIndexedDBDatabaseCallbacks>(); @@ -592,7 +575,7 @@ callbacks, db_callbacks, transaction_id, IndexedDBDatabaseMetadata::DEFAULT_VERSION, std::move(create_transaction_callback)); - factory()->Open(u"db", std::move(connection), bucket_locator, + factory()->Open(u"db", std::move(connection), storage_key, context()->data_path()); RunPostedTasks(); @@ -605,13 +588,12 @@ SetupContext(); const blink::StorageKey storage_key = blink::StorageKey::CreateFromStringForTesting("http://localhost:81"); - auto bucket_locator = storage::BucketLocator(); - bucket_locator.storage_key = storage_key; + IndexedDBBucketStateHandle bucket_state_handle; leveldb::Status s; std::tie(bucket_state_handle, s, std::ignore, std::ignore, std::ignore) = - factory()->GetOrOpenBucketFactory(bucket_locator, context()->data_path(), + factory()->GetOrOpenBucketFactory(storage_key, context()->data_path(), /*create_if_missing=*/true); EXPECT_TRUE(bucket_state_handle.IsHeld()) << s.ToString(); @@ -625,13 +607,12 @@ SetupContext(); const blink::StorageKey storage_key = blink::StorageKey::CreateFromStringForTesting("http://localhost:81"); - auto bucket_locator = storage::BucketLocator(); - bucket_locator.storage_key = storage_key; + IndexedDBBucketStateHandle bucket_state_handle; leveldb::Status s; std::tie(bucket_state_handle, s, std::ignore, std::ignore, std::ignore) = - factory()->GetOrOpenBucketFactory(bucket_locator, context()->data_path(), + factory()->GetOrOpenBucketFactory(storage_key, context()->data_path(), /*create_if_missing=*/true); EXPECT_TRUE(bucket_state_handle.IsHeld()) << s.ToString(); @@ -647,8 +628,6 @@ SetupContext(); const blink::StorageKey storage_key = blink::StorageKey::CreateFromStringForTesting("http://localhost:81"); - auto bucket_locator = storage::BucketLocator(); - bucket_locator.storage_key = storage_key; auto callbacks = base::MakeRefCounted<MockIndexedDBCallbacks>(); auto db_callbacks = base::MakeRefCounted<MockIndexedDBDatabaseCallbacks>(); @@ -660,7 +639,7 @@ callbacks, db_callbacks, transaction_id, IndexedDBDatabaseMetadata::DEFAULT_VERSION, std::move(create_transaction_callback)); - factory()->Open(u"db", std::move(connection), bucket_locator, + factory()->Open(u"db", std::move(connection), storage_key, context()->data_path()); EXPECT_FALSE(callbacks->connection()); RunPostedTasks(); @@ -681,8 +660,6 @@ SetupContext(); const blink::StorageKey storage_key = blink::StorageKey::CreateFromStringForTesting("http://localhost:81"); - auto bucket_locator = storage::BucketLocator(); - bucket_locator.storage_key = storage_key; auto callbacks = base::MakeRefCounted<MockIndexedDBCallbacks>(); auto db_callbacks = base::MakeRefCounted<MockIndexedDBDatabaseCallbacks>(); @@ -700,7 +677,7 @@ base::RunLoop loop; callbacks->CallOnUpgradeNeeded( base::BindLambdaForTesting([&]() { loop.Quit(); })); - factory()->Open(u"db", std::move(connection), bucket_locator, + factory()->Open(u"db", std::move(connection), storage_key, context()->data_path()); loop.Run(); } @@ -721,8 +698,6 @@ SetupContext(); const blink::StorageKey storage_key = blink::StorageKey::CreateFromStringForTesting("http://localhost:81"); - auto bucket_locator = storage::BucketLocator(); - bucket_locator.storage_key = storage_key; auto callbacks = base::MakeRefCounted<MockIndexedDBCallbacks>(); auto db_callbacks = base::MakeRefCounted<MockIndexedDBDatabaseCallbacks>(); @@ -740,7 +715,7 @@ base::RunLoop loop; callbacks->CallOnUpgradeNeeded( base::BindLambdaForTesting([&]() { loop.Quit(); })); - factory()->Open(u"db", std::move(connection), bucket_locator, + factory()->Open(u"db", std::move(connection), storage_key, context()->data_path()); loop.Run(); } @@ -761,13 +736,11 @@ SetupContext(); const blink::StorageKey storage_key = blink::StorageKey::CreateFromStringForTesting("http://localhost:81"); - auto bucket_locator = storage::BucketLocator(); - bucket_locator.storage_key = storage_key; std::unique_ptr<IndexedDBConnection> connection; scoped_refptr<MockIndexedDBDatabaseCallbacks> db_callbacks; std::tie(connection, db_callbacks) = - CreateConnectionForDatatabase(bucket_locator, u"db"); + CreateConnectionForDatatabase(storage_key, u"db"); // Force close the database. connection->database()->ForceCloseAndRunTasks(); @@ -786,10 +759,8 @@ const blink::StorageKey storage_key = blink::StorageKey::CreateFromStringForTesting("http://localhost:81"); - auto bucket_locator = storage::BucketLocator(); - bucket_locator.storage_key = storage_key; - factory()->DeleteDatabase(u"db", callbacks, bucket_locator, + factory()->DeleteDatabase(u"db", callbacks, storage_key, context()->data_path(), /*force_close=*/false); @@ -803,14 +774,12 @@ const blink::StorageKey storage_key = blink::StorageKey::CreateFromStringForTesting("http://localhost:81"); - auto bucket_locator = storage::BucketLocator(); - bucket_locator.storage_key = storage_key; const std::u16string name = u"db"; std::unique_ptr<IndexedDBConnection> connection; scoped_refptr<MockIndexedDBDatabaseCallbacks> db_callbacks; std::tie(connection, db_callbacks) = - CreateConnectionForDatatabase(bucket_locator, name); + CreateConnectionForDatatabase(storage_key, name); base::RunLoop run_loop; factory()->CallOnDatabaseDeletedForTesting(base::BindLambdaForTesting( @@ -822,7 +791,7 @@ auto callbacks = base::MakeRefCounted<MockIndexedDBCallbacks>( /*expect_connection=*/false); - factory()->DeleteDatabase(name, callbacks, bucket_locator, + factory()->DeleteDatabase(name, callbacks, storage_key, context()->data_path(), /*force_close=*/true); @@ -846,10 +815,8 @@ const blink::StorageKey storage_key = blink::StorageKey::CreateFromStringForTesting("http://localhost:81"); - auto bucket_locator = storage::BucketLocator(); - bucket_locator.storage_key = storage_key; - factory()->GetDatabaseInfo(callbacks, bucket_locator, context()->data_path()); + factory()->GetDatabaseInfo(callbacks, storage_key, context()->data_path()); EXPECT_TRUE(callbacks->info_called()); // Don't create a factory if one doesn't exist. @@ -864,17 +831,16 @@ const blink::StorageKey storage_key = blink::StorageKey::CreateFromStringForTesting("http://localhost:81"); - auto bucket_locator = storage::BucketLocator(); - bucket_locator.storage_key = storage_key; + IndexedDBBucketStateHandle bucket_state_handle; leveldb::Status s; std::tie(bucket_state_handle, s, std::ignore, std::ignore, std::ignore) = - factory()->GetOrOpenBucketFactory(bucket_locator, context()->data_path(), + factory()->GetOrOpenBucketFactory(storage_key, context()->data_path(), /*create_if_missing=*/true); EXPECT_TRUE(bucket_state_handle.IsHeld()) << s.ToString(); - factory()->GetDatabaseInfo(callbacks, bucket_locator, context()->data_path()); + factory()->GetDatabaseInfo(callbacks, storage_key, context()->data_path()); EXPECT_TRUE(callbacks->info_called()); EXPECT_TRUE(factory()->GetBucketFactory(storage_key)); @@ -920,8 +886,6 @@ nullptr, mojo::NullAssociatedRemote(), context()->IDBTaskRunner()); const blink::StorageKey storage_key = blink::StorageKey::CreateFromStringForTesting("http://localhost:81"); - auto bucket_locator = storage::BucketLocator(); - bucket_locator.storage_key = storage_key; const std::u16string name(u"name"); auto create_transaction_callback = base::BindOnce(&CreateAndBindTransactionPlaceholder); @@ -929,7 +893,7 @@ callbacks, dummy_database_callbacks, /*transaction_id=*/1, /*version=*/1, std::move(create_transaction_callback)); - factory()->Open(name, std::move(connection), bucket_locator, + factory()->Open(name, std::move(connection), storage_key, context()->data_path()); EXPECT_TRUE(callbacks->error_called()); base::RunLoop().RunUntilIdle(); @@ -979,8 +943,6 @@ SetupContext(); const blink::StorageKey storage_key = blink::StorageKey::CreateFromStringForTesting("http://localhost:81"); - auto bucket_locator = storage::BucketLocator(); - bucket_locator.storage_key = storage_key; const std::u16string db_name(u"db"); const int64_t transaction_id = 1; @@ -1002,7 +964,7 @@ base::RunLoop loop; callbacks->CallOnUpgradeNeeded( base::BindLambdaForTesting([&]() { loop.Quit(); })); - factory()->Open(db_name, std::move(connection), bucket_locator, + factory()->Open(db_name, std::move(connection), storage_key, context()->data_path()); loop.Run(); } @@ -1033,7 +995,7 @@ auto connection = std::make_unique<IndexedDBPendingConnection>( failed_open_callbacks, db_callbacks2, transaction_id, db_version, std::move(create_transaction_callback)); - factory()->Open(db_name, std::move(connection), bucket_locator, + factory()->Open(db_name, std::move(connection), storage_key, context()->data_path()); EXPECT_TRUE(factory()->IsDatabaseOpen(storage_key, db_name)); RunPostedTasks(); @@ -1067,7 +1029,7 @@ TEST_F(IndexedDBFactoryTest, DataFormatVersion) { SetupContext(); - auto try_open = [this](const storage::BucketLocator& bucket_locator, + auto try_open = [this](const blink::StorageKey& storage_key, const IndexedDBDataFormatVersion& version) { base::AutoReset<IndexedDBDataFormatVersion> override_version( &IndexedDBDataFormatVersion::GetMutableCurrentForTesting(), version); @@ -1095,7 +1057,7 @@ base::BindLambdaForTesting([&]() { loop.Quit(); })); this->factory()->Open(u"test_db", std::move(pending_connection), - bucket_locator, context()->data_path()); + storage_key, context()->data_path()); loop.Run(); // If an upgrade was requested, then commit the upgrade transaction. @@ -1116,7 +1078,7 @@ } } RunPostedTasks(); - factory()->ForceClose(bucket_locator.storage_key, false); + factory()->ForceClose(storage_key, false); RunPostedTasks(); return callbacks->data_loss(); }; @@ -1134,12 +1096,10 @@ SCOPED_TRACE(test.origin); const blink::StorageKey storage_key = blink::StorageKey::CreateFromStringForTesting(test.origin); - auto bucket_locator = storage::BucketLocator(); - bucket_locator.storage_key = storage_key; ASSERT_EQ(blink::mojom::IDBDataLoss::None, - try_open(bucket_locator, test.open_version_1)); + try_open(storage_key, test.open_version_1)); EXPECT_EQ(test.expected_data_loss, - try_open(bucket_locator, test.open_version_2)); + try_open(storage_key, test.open_version_2)); } }
diff --git a/content/browser/indexed_db/indexed_db_fake_backing_store.cc b/content/browser/indexed_db/indexed_db_fake_backing_store.cc index 18a72cfe..3a53cb1 100644 --- a/content/browser/indexed_db/indexed_db_fake_backing_store.cc +++ b/content/browser/indexed_db/indexed_db_fake_backing_store.cc
@@ -11,7 +11,6 @@ #include "base/threading/sequenced_task_runner_handle.h" #include "components/services/storage/indexed_db/transactional_leveldb/transactional_leveldb_database.h" #include "components/services/storage/indexed_db/transactional_leveldb/transactional_leveldb_factory.h" -#include "components/services/storage/public/cpp/buckets/bucket_locator.h" #include "content/browser/indexed_db/indexed_db_leveldb_env.h" #include "third_party/blink/public/common/storage_key/storage_key.h" @@ -26,49 +25,41 @@ return factory.get(); } -const storage::BucketLocator GetBucketLocator(blink::StorageKey storage_key) { - auto bucket_locator = storage::BucketLocator(); - bucket_locator.storage_key = storage_key; - return bucket_locator; -} - } // namespace IndexedDBFakeBackingStore::IndexedDBFakeBackingStore() - : IndexedDBBackingStore(IndexedDBBackingStore::Mode::kInMemory, - GetTransactionalLevelDBFactory(), - storage::BucketLocator(GetBucketLocator( - blink::StorageKey::CreateFromStringForTesting( - "http://localhost:81"))), - base::FilePath(), - std::unique_ptr<TransactionalLevelDBDatabase>(), - /*blob_storage_context=*/nullptr, - /*file_system_access_context=*/nullptr, - std::make_unique<storage::FilesystemProxy>( - storage::FilesystemProxy::UNRESTRICTED, - base::FilePath()), - BlobFilesCleanedCallback(), - ReportOutstandingBlobsCallback(), - base::SequencedTaskRunnerHandle::Get()) {} + : IndexedDBBackingStore( + IndexedDBBackingStore::Mode::kInMemory, + GetTransactionalLevelDBFactory(), + blink::StorageKey::CreateFromStringForTesting("http://localhost:81"), + base::FilePath(), + std::unique_ptr<TransactionalLevelDBDatabase>(), + /*blob_storage_context=*/nullptr, + /*file_system_access_context=*/nullptr, + std::make_unique<storage::FilesystemProxy>( + storage::FilesystemProxy::UNRESTRICTED, + base::FilePath()), + BlobFilesCleanedCallback(), + ReportOutstandingBlobsCallback(), + base::SequencedTaskRunnerHandle::Get()) {} IndexedDBFakeBackingStore::IndexedDBFakeBackingStore( BlobFilesCleanedCallback blob_files_cleaned, ReportOutstandingBlobsCallback report_outstanding_blobs, scoped_refptr<base::SequencedTaskRunner> task_runner) - : IndexedDBBackingStore(IndexedDBBackingStore::Mode::kOnDisk, - GetTransactionalLevelDBFactory(), - storage::BucketLocator(GetBucketLocator( - blink::StorageKey::CreateFromStringForTesting( - "http://localhost:81"))), - base::FilePath(), - std::unique_ptr<TransactionalLevelDBDatabase>(), - /*blob_storage_context=*/nullptr, - /*file_system_access_context=*/nullptr, - std::make_unique<storage::FilesystemProxy>( - storage::FilesystemProxy::UNRESTRICTED, - base::FilePath()), - std::move(blob_files_cleaned), - std::move(report_outstanding_blobs), - task_runner) {} + : IndexedDBBackingStore( + IndexedDBBackingStore::Mode::kOnDisk, + GetTransactionalLevelDBFactory(), + blink::StorageKey::CreateFromStringForTesting("http://localhost:81"), + base::FilePath(), + std::unique_ptr<TransactionalLevelDBDatabase>(), + /*blob_storage_context=*/nullptr, + /*file_system_access_context=*/nullptr, + std::make_unique<storage::FilesystemProxy>( + storage::FilesystemProxy::UNRESTRICTED, + base::FilePath()), + std::move(blob_files_cleaned), + std::move(report_outstanding_blobs), + task_runner) {} IndexedDBFakeBackingStore::~IndexedDBFakeBackingStore() = default; leveldb::Status IndexedDBFakeBackingStore::DeleteDatabase(
diff --git a/content/browser/indexed_db/indexed_db_unittest.cc b/content/browser/indexed_db/indexed_db_unittest.cc index ff0129e..b778a11 100644 --- a/content/browser/indexed_db/indexed_db_unittest.cc +++ b/content/browser/indexed_db/indexed_db_unittest.cc
@@ -266,7 +266,7 @@ std::make_unique<IndexedDBPendingConnection>( open_callbacks, open_db_callbacks, host_transaction_id, version, std::move(create_transaction_callback1)), - bucket_locator, context()->data_path()); + kTestStorageKey, context()->data_path()); EXPECT_TRUE(base::DirectoryExists(test_path)); auto create_transaction_callback2 = @@ -275,7 +275,7 @@ std::make_unique<IndexedDBPendingConnection>( closed_callbacks, closed_db_callbacks, host_transaction_id, version, std::move(create_transaction_callback2)), - bucket_locator, context()->data_path()); + kTestStorageKey, context()->data_path()); RunPostedTasks(); ASSERT_TRUE(closed_callbacks->connection()); closed_callbacks->connection()->AbortTransactionsAndClose( @@ -325,8 +325,6 @@ TEST_F(IndexedDBTest, ForceCloseOpenDatabasesOnCommitFailure) { const blink::StorageKey kTestStorageKey = blink::StorageKey::CreateFromStringForTesting("http://test/"); - auto bucket_locator = storage::BucketLocator(); - bucket_locator.storage_key = kTestStorageKey; auto* factory = static_cast<IndexedDBFactoryImpl*>(context()->GetIDBFactory()); @@ -341,7 +339,7 @@ callbacks, db_callbacks, transaction_id, IndexedDBDatabaseMetadata::DEFAULT_VERSION, std::move(create_transaction_callback1)); - factory->Open(u"db", std::move(connection), bucket_locator, + factory->Open(u"db", std::move(connection), kTestStorageKey, context()->data_path()); RunPostedTasks();
diff --git a/content/browser/indexed_db/mock_indexed_db_factory.h b/content/browser/indexed_db/mock_indexed_db_factory.h index f744c893..0f0b369 100644 --- a/content/browser/indexed_db/mock_indexed_db_factory.h +++ b/content/browser/indexed_db/mock_indexed_db_factory.h
@@ -29,7 +29,7 @@ const base::FilePath& data_directory)); MOCK_METHOD3(GetDatabaseInfo, void(scoped_refptr<IndexedDBCallbacks> callbacks, - const storage::BucketLocator& bucket_locator, + const blink::StorageKey& storage_key, const base::FilePath& data_directory)); MOCK_METHOD4(OpenProxy, void(const std::u16string& name, @@ -39,15 +39,14 @@ // Googlemock can't deal with move-only types, so *Proxy() is a workaround. void Open(const std::u16string& name, std::unique_ptr<IndexedDBPendingConnection> connection, - const storage::BucketLocator& bucket_locator, + const blink::StorageKey& storage_key, const base::FilePath& data_directory) override { - OpenProxy(name, connection.get(), bucket_locator.storage_key, - data_directory); + OpenProxy(name, connection.get(), storage_key, data_directory); } MOCK_METHOD5(DeleteDatabase, void(const std::u16string& name, scoped_refptr<IndexedDBCallbacks> callbacks, - const storage::BucketLocator& bucket_locator, + const blink::StorageKey& storage_key, const base::FilePath& data_directory, bool force_close)); MOCK_METHOD2(AbortTransactionsAndCompactDatabaseProxy,
diff --git a/content/browser/media/media_license_manager.cc b/content/browser/media/media_license_manager.cc index 380bb5a..3ee40f6 100644 --- a/content/browser/media/media_license_manager.cc +++ b/content/browser/media/media_license_manager.cc
@@ -13,6 +13,7 @@ #include "base/bind.h" #include "base/callback_forward.h" #include "base/containers/flat_map.h" +#include "base/feature_list.h" #include "base/files/file_path.h" #include "base/files/file_util.h" #include "base/memory/scoped_refptr.h" @@ -33,6 +34,7 @@ #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" #include "content/public/common/cdm_info.h" +#include "content/public/common/content_features.h" #include "media/cdm/cdm_type.h" #include "media/media_buildflags.h" #include "net/base/io_buffer.h" @@ -299,7 +301,13 @@ {blink::mojom::StorageType::kTemporary}); } - // TODO(crbug.com/1231162): Consider migrating media licenses here. + if (base::FeatureList::IsEnabled(features::kMediaLicenseBackend)) { + // Ensure the file system context is kept alive until we're done migrating + // media license data from the Plugin Private File System to this backend. + MigrateMediaLicenses( + base::BindOnce([](scoped_refptr<storage::FileSystemContext>) {}, + base::WrapRefCounted(context().get()))); + } } MediaLicenseManager::~MediaLicenseManager() = default; @@ -620,6 +628,13 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(host); + if (in_memory()) { + // Don't delete `host` for an in-memory profile, since the data is not safe + // to delete yet. For example, a site may be re-visited within the same + // incognito session. `host` will be destroyed when `this` is destroyed. + return; + } + DCHECK_GT(hosts_.count(host->storage_key()), 0ul); DCHECK_EQ(hosts_[host->storage_key()].get(), host);
diff --git a/content/browser/renderer_host/navigator.cc b/content/browser/renderer_host/navigator.cc index 5d1e0c0..7aba6be0 100644 --- a/content/browser/renderer_host/navigator.cc +++ b/content/browser/renderer_host/navigator.cc
@@ -844,6 +844,16 @@ frame_tree_node_id = render_frame_host->GetOutermostMainFrame() ->frame_tree_node() ->frame_tree_node_id(); + + // Fenced frames are enforced to have a history of length 1. Because the + // renderer thinks this navigation is to the fenced frame root, it sets + // `should_replace_current_entry` to true, but we do not want this + // restriction for navigations outside the fenced frame. + // TODO(crbug.com/1315802): Make sure that the browser doesn't rely on + // whether the renderer says we should replace the current entry, i.e. + // make sure there are no situations where we should actually replace the + // current entry but don't, due to this line. + should_replace_current_entry = false; } else { // Otherwise, proceed normally. frame_tree_node_id =
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 26870cf..94e3690 100644 --- a/content/browser/renderer_host/render_frame_host_impl_browsertest.cc +++ b/content/browser/renderer_host/render_frame_host_impl_browsertest.cc
@@ -2822,21 +2822,16 @@ EXPECT_EQ(0, process->get_media_stream_count_for_testing()); } -#if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX) -// ChromeOS and Linux failures are tracked in https://crbug.com/954217 -#define MAYBE_VisibilityScrolledOutOfView DISABLED_VisibilityScrolledOutOfView -#else -#define MAYBE_VisibilityScrolledOutOfView VisibilityScrolledOutOfView -#endif // Test that a frame is visible/hidden depending on its WebContents visibility // state. IN_PROC_BROWSER_TEST_F(RenderFrameHostImplBrowserTest, - MAYBE_VisibilityScrolledOutOfView) { + DISABLED_VisibilityScrolledOutOfView) { GURL main_frame(embedded_test_server()->GetURL("/iframe_out_of_view.html")); GURL child_url(embedded_test_server()->GetURL("/hello.html")); // This will set up the page frame tree as A(A1()). ASSERT_TRUE(NavigateToURL(shell(), main_frame)); + // TODO(crbug.com/954217): Re-enable this test FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root(); FrameTreeNode* nested_iframe_node = root->child_at(0); EXPECT_TRUE(NavigateToURLFromRenderer(nested_iframe_node, child_url));
diff --git a/content/browser/site_per_process_browsertest.cc b/content/browser/site_per_process_browsertest.cc index 158a585..add6707 100644 --- a/content/browser/site_per_process_browsertest.cc +++ b/content/browser/site_per_process_browsertest.cc
@@ -12132,7 +12132,7 @@ // //mojo/core/channel_fuchsia.cc #if BUILDFLAG(IS_FUCHSIA) #define MAYBE_RenderFrameProxyNotRecreatedDuringProcessShutdown \ - RenderFrameProxyNotRecreatedDuringProcessShutdown + DISABLED_RenderFrameProxyNotRecreatedDuringProcessShutdown #else #define MAYBE_RenderFrameProxyNotRecreatedDuringProcessShutdown \ RenderFrameProxyNotRecreatedDuringProcessShutdown
diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc index 6dbbdd8..935636ec 100644 --- a/content/public/common/content_features.cc +++ b/content/public/common/content_features.cc
@@ -539,7 +539,7 @@ // Use a custom backend to store media licenses in lieu of the // Plugin Private File System. const base::Feature kMediaLicenseBackend{"MediaLicenseBackend", - base::FEATURE_DISABLED_BY_DEFAULT}; + base::FEATURE_ENABLED_BY_DEFAULT}; // Allow cross-context transfer of MediaStreamTracks. const base::Feature kMediaStreamTrackTransfer{
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index f217de19..abcd95a 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc
@@ -415,7 +415,7 @@ // URL". This case should never reach this point as it's handled above, where // we return the original data: URL instead. if (document_loader->HasUnreachableURL()) { - *output = document_loader->UnreachableURL(); + *output = document_loader->UnreachableWebURL(); return true; } @@ -4667,7 +4667,7 @@ const blink::DocumentPolicyFeatureState& document_policy_header, const absl::optional<base::UnguessableToken>& embedding_token) { WebDocumentLoader* document_loader = frame_->GetDocumentLoader(); - const WebURLResponse& response = document_loader->GetResponse(); + const WebURLResponse& response = document_loader->GetWebResponse(); DocumentState* document_state = DocumentState::FromDocumentLoader(frame_->GetDocumentLoader()); @@ -4767,7 +4767,7 @@ // Update contents MIME type for main frame. params->contents_mime_type = - document_loader->GetResponse().MimeType().Utf8(); + document_loader->GetWebResponse().MimeType().Utf8(); params->transition = transition; // Check that if we are in a fenced frame tree then we must have
diff --git a/content/test/data/accessibility/html/fencedframe-scrollable-expected-blink.txt b/content/test/data/accessibility/html/fencedframe-scrollable-expected-blink.txt new file mode 100644 index 0000000..f651bc4 --- /dev/null +++ b/content/test/data/accessibility/html/fencedframe-scrollable-expected-blink.txt
@@ -0,0 +1,14 @@ +rootWebArea scrollable=true +++genericContainer ignored +++++genericContainer +++++++iframe name='Scrollable iframe' +++++++++rootWebArea scrollable=true +++++++++++genericContainer ignored +++++++++++++genericContainer ignored +++++++++++++++genericContainer +++++++++++++++++staticText name='visible text' +++++++++++++++++++inlineTextBox name='visible text' +++++++++++++++genericContainer ignored +++++++++++++++genericContainer +++++++++++++++++staticText name='hidden from viewport' +++++++++++++++++++inlineTextBox name='hidden from viewport'
diff --git a/content/test/data/accessibility/html/fencedframe-scrollable.html b/content/test/data/accessibility/html/fencedframe-scrollable.html new file mode 100644 index 0000000..885957a --- /dev/null +++ b/content/test/data/accessibility/html/fencedframe-scrollable.html
@@ -0,0 +1,10 @@ +<!-- +@BLINK-ALLOW:scrollable=* +--> +<!DOCTYPE html> +<html style="width:100px; height:100px;"> +<body> + <iframe style="width:200px; height: 200px;" aria-label="Scrollable iframe" src="frame/visible_text.html"> + </iframe> +</body> +</html>
diff --git a/content/test/gpu/gpu_tests/test_expectations/OWNERS b/content/test/gpu/gpu_tests/test_expectations/OWNERS new file mode 100644 index 0000000..56ad5561 --- /dev/null +++ b/content/test/gpu/gpu_tests/test_expectations/OWNERS
@@ -0,0 +1,2 @@ +# The entire Chrome Graphics team is allowed to administer these test expectations. +file://gpu/GRAPHICS_TEAM_OWNERS
diff --git a/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt index 4becb4a..bc2fc6c 100644 --- a/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt +++ b/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt
@@ -339,11 +339,11 @@ crbug.com/angleproject/6430 [ mac passthrough angle-metal ] WebglExtension_WEBGL_multi_draw_instanced_base_vertex_base_instance [ Failure ] crbug.com/angleproject/6430 [ mac passthrough angle-metal ] conformance/ogles/GL/build/build_009_to_016.html [ Failure ] crbug.com/angleproject/6430 [ mac passthrough angle-metal ] conformance2/rendering/fs-color-type-mismatch-color-buffer-type.html [ Failure ] -crbug.com/angleproject/6430 [ mac passthrough angle-metal ] deqp/functional/gles3/fboinvalidate/sub.html [ Failure ] -crbug.com/angleproject/6430 [ mac passthrough angle-metal ] deqp/functional/gles3/fboinvalidate/whole.html [ Failure ] -crbug.com/angleproject/6430 [ mac passthrough angle-metal ] deqp/functional/gles3/fbomultisample.2_samples.html [ Failure ] -crbug.com/angleproject/6430 [ mac passthrough angle-metal ] deqp/functional/gles3/fbomultisample.4_samples.html [ Failure ] -crbug.com/angleproject/6430 [ mac passthrough angle-metal ] deqp/functional/gles3/fbomultisample.8_samples.html [ Failure ] +crbug.com/angleproject/7079 [ mac passthrough angle-metal ] deqp/functional/gles3/fboinvalidate/sub.html [ Failure ] +crbug.com/angleproject/7079 [ mac passthrough angle-metal ] deqp/functional/gles3/fboinvalidate/whole.html [ Failure ] +crbug.com/angleproject/7079 [ mac passthrough angle-metal ] deqp/functional/gles3/fbomultisample.2_samples.html [ Failure ] +crbug.com/angleproject/7079 [ mac passthrough angle-metal ] deqp/functional/gles3/fbomultisample.4_samples.html [ Failure ] +crbug.com/angleproject/7079 [ mac passthrough angle-metal ] deqp/functional/gles3/fbomultisample.8_samples.html [ Failure ] crbug.com/angleproject/7234 [ mac passthrough angle-metal ] conformance2/textures/misc/integer-cubemap-texture-sampling.html [ Failure ] # Metal AMD
diff --git a/content/web_test/renderer/test_runner.cc b/content/web_test/renderer/test_runner.cc index 1193618..2fc1dc8 100644 --- a/content/web_test/renderer/test_runner.cc +++ b/content/web_test/renderer/test_runner.cc
@@ -3364,7 +3364,7 @@ spec = spec.substr(path_start); std::string mime_type = - web_frame->GetDocumentLoader()->GetResponse().MimeType().Utf8(); + web_frame->GetDocumentLoader()->GetWebResponse().MimeType().Utf8(); // In a text/plain document, and in a dumpAsText/ subdirectory, we generate // text results no matter what the test may previously have requested.
diff --git a/device/vr/openxr/openxr_anchor_manager.cc b/device/vr/openxr/openxr_anchor_manager.cc index 843308bd..6989b0d 100644 --- a/device/vr/openxr/openxr_anchor_manager.cc +++ b/device/vr/openxr/openxr_anchor_manager.cc
@@ -193,20 +193,20 @@ const gfx::Transform& native_origin_from_anchor, const std::vector<mojom::XRInputSourceStatePtr>& input_state) const { switch (native_origin_information.which()) { - case mojom::XRNativeOriginInformation::Tag::INPUT_SOURCE_SPACE_INFO: + case mojom::XRNativeOriginInformation::Tag::kInputSourceSpaceInfo: // Currently unimplemented as only anchors are supported and are never // created relative to input sources return absl::nullopt; - case mojom::XRNativeOriginInformation::Tag::REFERENCE_SPACE_TYPE: + case mojom::XRNativeOriginInformation::Tag::kReferenceSpaceType: return GetXrLocationFromReferenceSpace(openxr, current_stage_parameters, native_origin_information, native_origin_from_anchor); - case mojom::XRNativeOriginInformation::Tag::PLANE_ID: - case mojom::XRNativeOriginInformation::Tag::HAND_JOINT_SPACE_INFO: - case mojom::XRNativeOriginInformation::Tag::IMAGE_INDEX: + case mojom::XRNativeOriginInformation::Tag::kPlaneId: + case mojom::XRNativeOriginInformation::Tag::kHandJointSpaceInfo: + case mojom::XRNativeOriginInformation::Tag::kImageIndex: // Unsupported for now return absl::nullopt; - case mojom::XRNativeOriginInformation::Tag::ANCHOR_ID: + case mojom::XRNativeOriginInformation::Tag::kAnchorId: return XrLocation{ GfxTransformToXrPose(native_origin_from_anchor), GetAnchorSpace(AnchorId(native_origin_information.get_anchor_id()))};
diff --git a/device/vr/openxr/openxr_scene_understanding_manager.cc b/device/vr/openxr/openxr_scene_understanding_manager.cc index 1860309..39cedc6 100644 --- a/device/vr/openxr/openxr_scene_understanding_manager.cc +++ b/device/vr/openxr/openxr_scene_understanding_manager.cc
@@ -358,7 +358,7 @@ const gfx::Transform& mojo_from_viewer, const std::vector<mojom::XRInputSourceStatePtr>& input_state) { switch (native_origin_information.which()) { - case mojom::XRNativeOriginInformation::Tag::INPUT_SOURCE_SPACE_INFO: + case mojom::XRNativeOriginInformation::Tag::kInputSourceSpaceInfo: for (auto& input_source_state : input_state) { mojom::XRInputSourceSpaceInfo* input_source_space_info = native_origin_information.get_input_source_space_info().get(); @@ -368,17 +368,17 @@ } } return absl::nullopt; - case mojom::XRNativeOriginInformation::Tag::REFERENCE_SPACE_TYPE: + case mojom::XRNativeOriginInformation::Tag::kReferenceSpaceType: return GetMojoFromReferenceSpace( native_origin_information.get_reference_space_type(), mojo_from_viewer); - case mojom::XRNativeOriginInformation::Tag::PLANE_ID: + case mojom::XRNativeOriginInformation::Tag::kPlaneId: return absl::nullopt; - case mojom::XRNativeOriginInformation::Tag::ANCHOR_ID: + case mojom::XRNativeOriginInformation::Tag::kAnchorId: return absl::nullopt; - case mojom::XRNativeOriginInformation::Tag::HAND_JOINT_SPACE_INFO: + case mojom::XRNativeOriginInformation::Tag::kHandJointSpaceInfo: return absl::nullopt; - case mojom::XRNativeOriginInformation::Tag::IMAGE_INDEX: + case mojom::XRNativeOriginInformation::Tag::kImageIndex: return absl::nullopt; } } @@ -447,4 +447,4 @@ return mojo_from_input * input_from_pointer; } -} // namespace device \ No newline at end of file +} // namespace device
diff --git a/extensions/browser/api/storage/settings_test_util.cc b/extensions/browser/api/storage/settings_test_util.cc index 5d66d96..ab26359 100644 --- a/extensions/browser/api/storage/settings_test_util.cc +++ b/extensions/browser/api/storage/settings_test_util.cc
@@ -23,18 +23,18 @@ namespace settings_test_util { // Creates a kilobyte of data. -std::unique_ptr<base::Value> CreateKilobyte() { +base::Value CreateKilobyte() { std::string kilobyte_string(1024u, 'a'); - return std::make_unique<base::Value>(std::move(kilobyte_string)); + return base::Value(std::move(kilobyte_string)); } // Creates a megabyte of data. -std::unique_ptr<base::Value> CreateMegabyte() { - base::ListValue* megabyte = new base::ListValue(); +base::Value CreateMegabyte() { + base::Value::List megabyte; for (int i = 0; i < 1000; ++i) { - megabyte->Append(CreateKilobyte()); + megabyte.Append(CreateKilobyte()); } - return std::unique_ptr<base::Value>(megabyte); + return base::Value(std::move(megabyte)); } // Intended as a StorageCallback from GetStorage.
diff --git a/extensions/browser/api/storage/settings_test_util.h b/extensions/browser/api/storage/settings_test_util.h index 071a3f1..b7dcb0a 100644 --- a/extensions/browser/api/storage/settings_test_util.h +++ b/extensions/browser/api/storage/settings_test_util.h
@@ -17,6 +17,10 @@ #include "extensions/browser/mock_extension_system.h" #include "extensions/common/extension.h" +namespace base { +class Value; +} + namespace value_store { class ValueStore; } @@ -28,10 +32,10 @@ namespace settings_test_util { // Creates a kilobyte of data. -std::unique_ptr<base::Value> CreateKilobyte(); +base::Value CreateKilobyte(); // Creates a megabyte of data. -std::unique_ptr<base::Value> CreateMegabyte(); +base::Value CreateMegabyte(); // Synchronously gets the storage area for an extension from |frontend|. value_store::ValueStore* GetStorage(
diff --git a/extensions/browser/api/storage/storage_frontend_unittest.cc b/extensions/browser/api/storage/storage_frontend_unittest.cc index 35481ba..fed2841 100644 --- a/extensions/browser/api/storage/storage_frontend_unittest.cc +++ b/extensions/browser/api/storage/storage_frontend_unittest.cc
@@ -194,30 +194,30 @@ extension, settings::LOCAL, frontend_.get()); // Sync storage should run out after ~100K. - std::unique_ptr<base::Value> kilobyte = settings_test_util::CreateKilobyte(); + base::Value kilobyte = settings_test_util::CreateKilobyte(); for (int i = 0; i < 100; ++i) { - sync_storage->Set(DEFAULTS, base::NumberToString(i), *kilobyte); + sync_storage->Set(DEFAULTS, base::NumberToString(i), kilobyte); } EXPECT_FALSE( - sync_storage->Set(DEFAULTS, "WillError", *kilobyte).status().ok()); + sync_storage->Set(DEFAULTS, "WillError", kilobyte).status().ok()); // Local storage shouldn't run out after ~100K. for (int i = 0; i < 100; ++i) { - local_storage->Set(DEFAULTS, base::NumberToString(i), *kilobyte); + local_storage->Set(DEFAULTS, base::NumberToString(i), kilobyte); } EXPECT_TRUE( - local_storage->Set(DEFAULTS, "WontError", *kilobyte).status().ok()); + local_storage->Set(DEFAULTS, "WontError", kilobyte).status().ok()); // Local storage should run out after ~5MB. - std::unique_ptr<base::Value> megabyte = settings_test_util::CreateMegabyte(); + base::Value megabyte = settings_test_util::CreateMegabyte(); for (int i = 0; i < 5; ++i) { - local_storage->Set(DEFAULTS, base::NumberToString(i), *megabyte); + local_storage->Set(DEFAULTS, base::NumberToString(i), megabyte); } EXPECT_FALSE( - local_storage->Set(DEFAULTS, "WillError", *megabyte).status().ok()); + local_storage->Set(DEFAULTS, "WillError", megabyte).status().ok()); } } // namespace extensions
diff --git a/gin/array_buffer.cc b/gin/array_buffer.cc index 2e78aa6..917ab23 100644 --- a/gin/array_buffer.cc +++ b/gin/array_buffer.cc
@@ -8,9 +8,11 @@ #include <stdlib.h> #include "base/allocator/partition_allocator/page_allocator.h" +#include "base/bits.h" #include "base/check_op.h" #include "build/build_config.h" #include "gin/per_isolate_data.h" +#include "v8/include/v8-initialization.h" #if BUILDFLAG(IS_POSIX) #include <sys/mman.h> @@ -96,4 +98,91 @@ return true; } +// ArrayBufferSharedMemoryMapper --------------------------------------------- + +namespace { +#ifdef V8_SANDBOX +// When the V8 sandbox is enabled, shared memory backing ArrayBuffers must be +// mapped into the sandbox address space. This custom SharedMemoryMapper +// implements this. + +class ArrayBufferSharedMemoryMapper : public base::SharedMemoryMapper { + public: + absl::optional<base::span<uint8_t>> Map( + base::subtle::PlatformSharedMemoryHandle handle, + bool write_allowed, + uint64_t offset, + size_t size) override { + v8::VirtualAddressSpace* address_space = v8::V8::GetSandboxAddressSpace(); + size_t allocation_granularity = address_space->allocation_granularity(); + + v8::PlatformSharedMemoryHandle v8_handle; +#if BUILDFLAG(IS_MAC) + v8_handle = v8::SharedMemoryHandleFromMachMemoryEntry(handle); +#elif BUILDFLAG(IS_FUCHSIA) + v8_handle = v8::SharedMemoryHandleFromVMO(handle->get()); +#elif BUILDFLAG(IS_WIN) + v8_handle = v8::SharedMemoryHandleFromFileMapping(handle); +#elif BUILDFLAG(IS_ANDROID) + v8_handle = v8::SharedMemoryHandleFromFileDescriptor(handle); +#elif BUILDFLAG(IS_POSIX) + v8_handle = v8::SharedMemoryHandleFromFileDescriptor(handle.fd); +#else +#error "Unknown platform" +#endif + + // Size and offset must be a multiple of the page allocation granularity. + // The caller already ensures that the offset is a multiple of the + // allocation granularity though. + CHECK_EQ(0UL, offset % allocation_granularity); + size_t mapping_size = base::bits::AlignUp(size, allocation_granularity); + + v8::PagePermissions permissions = write_allowed + ? v8::PagePermissions::kReadWrite + : v8::PagePermissions::kRead; + uintptr_t mapping = v8::V8::GetSandboxAddressSpace()->AllocateSharedPages( + 0, mapping_size, permissions, v8_handle, offset); + if (!mapping) + return absl::nullopt; + + return base::make_span(reinterpret_cast<uint8_t*>(mapping), size); + } + + void Unmap(base::span<uint8_t> mapping) override { + v8::VirtualAddressSpace* address_space = v8::V8::GetSandboxAddressSpace(); + size_t allocation_granularity = address_space->allocation_granularity(); + + uintptr_t address = reinterpret_cast<uintptr_t>(mapping.data()); + CHECK_EQ(0UL, address % allocation_granularity); + size_t mapping_size = + base::bits::AlignUp(mapping.size(), allocation_granularity); + + address_space->FreeSharedPages(address, mapping_size); + } +}; +#endif // V8_SANDBOX + +base::SharedMemoryMapper* CreateSharedMemoryMapperForArrayBuffers() { +#if V8_SANDBOX + static ArrayBufferSharedMemoryMapper instance; + // Currently, it is still possible for the sandbox to be disabled at runtime + // (by not initializing it), in which case the default shared memory mapper + // must be used. In the future, this will no longer be allowed and this helper + // function can then be removed entirely. + // TODO(saelo) remove once sandbox initialization is mandatory. + if (v8::V8::GetSandboxSizeInBytes() > 0) + return &instance; + else +#endif + // Use nullptr here and let //base select the default mapper. + return nullptr; +} +} // namespace + +base::SharedMemoryMapper* GetSharedMemoryMapperForArrayBuffers() { + static base::SharedMemoryMapper* mapper = + CreateSharedMemoryMapperForArrayBuffers(); + return mapper; +} + } // namespace gin
diff --git a/gin/array_buffer.h b/gin/array_buffer.h index 8dfcf65b..cf8a650 100644 --- a/gin/array_buffer.h +++ b/gin/array_buffer.h
@@ -10,6 +10,7 @@ #include "base/compiler_specific.h" #include "base/memory/ref_counted.h" +#include "base/memory/shared_memory_mapper.h" #include "gin/converter.h" #include "gin/gin_export.h" #include "v8/include/v8-array-buffer.h" @@ -76,6 +77,8 @@ ArrayBufferView* out); }; +GIN_EXPORT base::SharedMemoryMapper* GetSharedMemoryMapperForArrayBuffers(); + } // namespace gin #endif // GIN_ARRAY_BUFFER_H_
diff --git a/gin/v8_initializer.cc b/gin/v8_initializer.cc index 9dddcdf8..0723877 100644 --- a/gin/v8_initializer.cc +++ b/gin/v8_initializer.cc
@@ -477,6 +477,13 @@ base::internal::PartitionAddressSpace::InitConfigurablePool(pool_base, pool_size); // TODO(saelo) maybe record the size of the Pool into UMA. + + // If this CHECK fails, it means that something used the array buffer + // shared memory mapper before the sandbox was initialized, which may then + // cause crashes later on as array buffers may have been mapped outside the + // sandbox. See GetSharedMemoryMapperForArrayBuffers(). TODO(saelo) remove + // once sandbox initialization is mandatory. + CHECK_NE(nullptr, GetSharedMemoryMapperForArrayBuffers()); } #endif // V8_SANDBOX }
diff --git a/gpu/GRAPHICS_TEAM_OWNERS b/gpu/GRAPHICS_TEAM_OWNERS new file mode 100644 index 0000000..4cfead6 --- /dev/null +++ b/gpu/GRAPHICS_TEAM_OWNERS
@@ -0,0 +1,101 @@ +## File enumerating all Chrome Graphics team members who should have +## ownership over common files. + +# Chrome GPU Overall team +vmiura@chromium.org +geofflang@chromium.org +fserb@chromium.org +sadrul@chromium.org +rockot@google.com +rjkroege@chromium.org +zmo@chromium.org + +# ANGLE team +capn@chromium.org +jmadill@chromium.org +jonahr@chromium.org +srisser@chromium.org +sugoi@chromium.org +syoussefi@chromium.org +ynovikov@chromium.org + +# Canvas team +aaronhk@chromium.org +jpgravel@google.com +juanmihd@chromium.org +junov@chromium.org +yiyix@chromium.org + +# Metrics team +behdadb@chromium.org +jonross@chromium.org +mjzhang@chromium.org +mohsen@chromium.org + +# Platforms Team +backer@chromium.org +boliu@chromium.org +ccameron@chromium.org +fangzhoug@chromium.org +hitawala@chromium.org +khaslett@chromium.org +kylechar@chromium.org +magchen@chromium.org +penghuang@chromium.org +petermcneeley@chromium.org +rivr@chromium.org +sunnyps@chromium.org +vasilyt@chromium.org +vikassoni@chromium.org + +# 3D Web team +alanbaker@google.com +amaiorano@google.com +bajones@chromium.org +bclayton@chromium.org +cwallez@chromium.org +dneto@google.com +dsinclair@chromium.org +enga@chromium.org +gman@chromium.org +jrprice@google.com +kainino@chromium.org +kbr@chromium.org +lokokung@google.com +rharrison@chromium.org +ricardocabello@google.com +shrekshao@google.com +senorblanco@chromium.org + +# Skia +brianosman@google.com +bsalomon@google.com +djsollen@google.com +egdaniel@google.com +fmalita@chromium.org +jcgregorio@chromium.org + +# Skia Core / eSkia +bungeman@chromium.org +jlavrova@google.com +scroggo@google.com +tdenniston@google.com +wrightgeorge@google.com + +# Skia GPU +jvanverth@chromium.org +michaelludwig@google.com +robertphillips@google.com + +# Skia Infra +borenet@google.com +erikrose@google.com +kjlubick@chromium.org +lovisolo@google.com +rmistry@chromium.org + +# SkSL +armansito@chromium.org +ethannicholas@chromium.org +herb@google.com +johnstiles@google.com
diff --git a/gpu/OWNERS b/gpu/OWNERS index b2e87eeb..83d4d26 100644 --- a/gpu/OWNERS +++ b/gpu/OWNERS
@@ -18,3 +18,6 @@ # D3D, dcomp, Windows platform integration, etc. rafael.cintron@microsoft.com + +# The extended Chrome Graphics team should be able to self-administer. +per-file GRAPHICS_TEAM_OWNERS=file://gpu/GRAPHICS_TEAM_OWNERS
diff --git a/gpu/command_buffer/client/raster_implementation.cc b/gpu/command_buffer/client/raster_implementation.cc index 2a43b28..d3a7613 100644 --- a/gpu/command_buffer/client/raster_implementation.cc +++ b/gpu/command_buffer/client/raster_implementation.cc
@@ -43,7 +43,6 @@ #include "gpu/command_buffer/client/shared_memory_limits.h" #include "gpu/command_buffer/client/transfer_buffer.h" #include "third_party/skia/include/core/SkColorSpace.h" -#include "ui/base/ui_base_features.h" #include "ui/gfx/color_space.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/rect_f.h" @@ -506,8 +505,7 @@ lost_(false), max_inlined_entry_size_(kMaxTransferCacheEntrySizeForTransferBuffer), transfer_cache_(this), - image_decode_accelerator_(image_decode_accelerator), - raw_draw_(features::IsUsingRawDraw()) { + image_decode_accelerator_(image_decode_accelerator) { DCHECK(helper); DCHECK(transfer_buffer); DCHECK(gpu_control); @@ -1410,7 +1408,7 @@ raster_properties_->color_space, &skottie_serialization_history_, raster_properties_->can_use_lcd_text, capabilities().context_supports_distance_field_text, - capabilities().max_texture_size, raw_draw_)); + capabilities().max_texture_size, /*raw_draw=*/true)); if (preserve_recording) { serializer.Serialize(&list->paint_op_buffer_, &temp_raster_offsets_, preamble);
diff --git a/gpu/command_buffer/client/raster_implementation.h b/gpu/command_buffer/client/raster_implementation.h index fdd547e..d936b83 100644 --- a/gpu/command_buffer/client/raster_implementation.h +++ b/gpu/command_buffer/client/raster_implementation.h
@@ -458,7 +458,6 @@ cc::SkottieSerializationHistory skottie_serialization_history_; raw_ptr<ImageDecodeAcceleratorInterface> image_decode_accelerator_; - const bool raw_draw_; // Tracing helpers. int raster_chromium_id_ = 0;
diff --git a/ios/build/bots/scripts/PRESUBMIT.py b/ios/build/bots/scripts/PRESUBMIT.py index 488b9c8..beda9baf04 100644 --- a/ios/build/bots/scripts/PRESUBMIT.py +++ b/ios/build/bots/scripts/PRESUBMIT.py
@@ -11,6 +11,9 @@ def _RunTestRunnerUnitTests(input_api, output_api): + # Don't run iOS tests on Windows. + if input_api.is_windows: + return [] """ Runs iOS test runner unit tests """ files = ['.*_test.py$']
diff --git a/media/gpu/v4l2/test/av1_decoder.cc b/media/gpu/v4l2/test/av1_decoder.cc index 3ced9cf..2844280 100644 --- a/media/gpu/v4l2/test/av1_decoder.cc +++ b/media/gpu/v4l2/test/av1_decoder.cc
@@ -104,6 +104,20 @@ return ParsingResult::kOk; } +void Av1Decoder::CopyFrameData(const libgav1::ObuFrameHeader& frame_hdr, + std::unique_ptr<V4L2Queue>& queue) { + CHECK_EQ(queue->num_buffers(), 1u) + << "Only 1 buffer is expected to be used for OUTPUT queue for now."; + + CHECK_EQ(queue->num_planes(), 1u) + << "Number of planes is expected to be 1 for OUTPUT queue."; + + scoped_refptr<MmapedBuffer> buffer = queue->GetBuffer(0); + + memcpy(static_cast<uint8_t*>(buffer->mmaped_planes()[0].start_addr), + ivf_frame_data_, ivf_frame_header_.frame_size); +} + VideoDecoder::Result Av1Decoder::DecodeNextFrame(std::vector<char>& y_plane, std::vector<char>& u_plane, std::vector<char>& v_plane, @@ -118,17 +132,46 @@ return VideoDecoder::kEOStream; } + libgav1::ObuFrameHeader current_frame_header = obu_parser_->frame_header(); + if (obu_parser_->sequence_header_changed()) current_sequence_header_.emplace(obu_parser_->sequence_header()); LOG_ASSERT(current_sequence_header_) << "Sequence header missing for decoding."; + CopyFrameData(current_frame_header, OUTPUT_queue_); + + LOG_ASSERT(OUTPUT_queue_->num_buffers() == 1) + << "Too many buffers in OUTPUT queue. It is currently designed to " + "support only 1 request at a time."; + + OUTPUT_queue_->GetBuffer(0)->set_frame_number(frame_number); + + if (!v4l2_ioctl_->QBuf(OUTPUT_queue_, 0)) + LOG(FATAL) << "VIDIOC_QBUF failed for OUTPUT queue."; + // TODO(b/228534725): add changes to support reference frames management // TODO(b/228534730): add changes to prepare parameters for V4L2 AV1 stateless // decoding + if (!v4l2_ioctl_->MediaRequestIocQueue(OUTPUT_queue_)) + LOG(FATAL) << "MEDIA_REQUEST_IOC_QUEUE failed."; + + uint32_t index; + + if (!v4l2_ioctl_->DQBuf(CAPTURE_queue_, &index)) + LOG(FATAL) << "VIDIOC_DQBUF failed for CAPTURE queue."; + + scoped_refptr<MmapedBuffer> buffer = CAPTURE_queue_->GetBuffer(index); + + if (!v4l2_ioctl_->DQBuf(OUTPUT_queue_, &index)) + LOG(FATAL) << "VIDIOC_DQBUF failed for OUTPUT queue."; + + if (!v4l2_ioctl_->MediaRequestIocReinit(OUTPUT_queue_)) + LOG(FATAL) << "MEDIA_REQUEST_IOC_REINIT failed."; + return VideoDecoder::kOk; }
diff --git a/media/gpu/v4l2/test/av1_decoder.h b/media/gpu/v4l2/test/av1_decoder.h index b7fc74e..074dab8 100644 --- a/media/gpu/v4l2/test/av1_decoder.h +++ b/media/gpu/v4l2/test/av1_decoder.h
@@ -76,6 +76,10 @@ // set upon completion. ParsingResult ReadNextFrame(libgav1::RefCountedBufferPtr& current_frame); + // Copies the frame data into the V4L2 buffer of OUTPUT |queue|. + void CopyFrameData(const libgav1::ObuFrameHeader& frame_hdr, + std::unique_ptr<V4L2Queue>& queue); + IvfFrameHeader ivf_frame_header_{}; const uint8_t* ivf_frame_data_ = nullptr;
diff --git a/media/gpu/v4l2/test/vp9_decoder.cc b/media/gpu/v4l2/test/vp9_decoder.cc index 2c7ae41..1dd48d8 100644 --- a/media/gpu/v4l2/test/vp9_decoder.cc +++ b/media/gpu/v4l2/test/vp9_decoder.cc
@@ -482,7 +482,7 @@ FillV4L2VP9SegmentationParams(segm_params, &v4l2_frame_params->seg); } -bool Vp9Decoder::CopyFrameData(const Vp9FrameHeader& frame_hdr, +void Vp9Decoder::CopyFrameData(const Vp9FrameHeader& frame_hdr, std::unique_ptr<V4L2Queue>& queue) { LOG_ASSERT(queue->num_buffers() == 1) << "Only 1 buffer is expected to be used for OUTPUT queue for now."; @@ -492,8 +492,8 @@ scoped_refptr<MmapedBuffer> buffer = queue->GetBuffer(0); - return memcpy(static_cast<uint8_t*>(buffer->mmaped_planes()[0].start_addr), - frame_hdr.data, frame_hdr.frame_size); + memcpy(static_cast<uint8_t*>(buffer->mmaped_planes()[0].start_addr), + frame_hdr.data, frame_hdr.frame_size); } VideoDecoder::Result Vp9Decoder::DecodeNextFrame(std::vector<char>& y_plane, @@ -520,8 +520,7 @@ VLOG_IF(2, !frame_hdr.show_frame) << "not displaying frame"; last_decoded_frame_visible_ = frame_hdr.show_frame; - if (!CopyFrameData(frame_hdr, OUTPUT_queue_)) - LOG(FATAL) << "Failed to copy the frame data into the V4L2 buffer."; + CopyFrameData(frame_hdr, OUTPUT_queue_); LOG_ASSERT(OUTPUT_queue_->num_buffers() == 1) << "Too many buffers in OUTPUT queue. It is currently designed to "
diff --git a/media/gpu/v4l2/test/vp9_decoder.h b/media/gpu/v4l2/test/vp9_decoder.h index 03fe5d3..d5144cb 100644 --- a/media/gpu/v4l2/test/vp9_decoder.h +++ b/media/gpu/v4l2/test/vp9_decoder.h
@@ -54,7 +54,7 @@ gfx::Size& size); // Copies the frame data into the V4L2 buffer of OUTPUT |queue|. - bool CopyFrameData(const Vp9FrameHeader& frame_hdr, + void CopyFrameData(const Vp9FrameHeader& frame_hdr, std::unique_ptr<V4L2Queue>& queue); // Sets up per frame parameters |v4l2_frame_params| needed for VP9 decoding
diff --git a/mojo/public/cpp/base/shared_memory_utils.cc b/mojo/public/cpp/base/shared_memory_utils.cc index 172f28c..e88d5f8 100644 --- a/mojo/public/cpp/base/shared_memory_utils.cc +++ b/mojo/public/cpp/base/shared_memory_utils.cc
@@ -25,12 +25,14 @@ return mojo::UnwrapWritableSharedMemoryRegion(std::move(handle)); } -base::MappedReadOnlyRegion CreateReadOnlySharedMemoryRegion(size_t size) { +base::MappedReadOnlyRegion CreateReadOnlySharedMemoryRegion( + size_t size, + base::SharedMemoryMapper* mapper) { auto writable_region = CreateWritableSharedMemoryRegion(size); if (!writable_region.IsValid()) return {}; - base::WritableSharedMemoryMapping mapping = writable_region.Map(); + base::WritableSharedMemoryMapping mapping = writable_region.Map(mapper); return {base::WritableSharedMemoryRegion::ConvertToReadOnly( std::move(writable_region)), std::move(mapping)};
diff --git a/ppapi/PRESUBMIT.py b/ppapi/PRESUBMIT.py index b3a11d6a..f518d31 100644 --- a/ppapi/PRESUBMIT.py +++ b/ppapi/PRESUBMIT.py
@@ -86,7 +86,7 @@ todo.append(filename) if todo: - return [output_api.PresubmitError( + return [output_api.PresubmitPromptWarning( 'TODOs found in stable public PPAPI files:', long_text='\n'.join(todo))] return []
diff --git a/remoting/android/BUILD.gn b/remoting/android/BUILD.gn index 939dd7a..d19b08c 100644 --- a/remoting/android/BUILD.gn +++ b/remoting/android/BUILD.gn
@@ -133,7 +133,6 @@ deps = [ ":credits_resources_raw", "//remoting/resources:strings_java", - "//third_party/android_deps:android_support_v7_appcompat_java", ] }
diff --git a/remoting/android/client_java_tmpl.gni b/remoting/android/client_java_tmpl.gni index 373788f..bffc012 100644 --- a/remoting/android/client_java_tmpl.gni +++ b/remoting/android/client_java_tmpl.gni
@@ -87,11 +87,11 @@ "//remoting/android:remoting_android_client_java_resources", "//remoting/android:remoting_apk_manifest", "//remoting/proto/remoting/v1:directory_proto_java", - "//third_party/android_deps:android_support_v7_appcompat_java", "//third_party/android_deps:protobuf_lite_runtime_java", "//third_party/androidx:androidx_annotation_annotation_java", + "//third_party/androidx:androidx_appcompat_appcompat_java", + "//third_party/androidx:androidx_core_core_java", "//third_party/androidx:androidx_drawerlayout_drawerlayout_java", - "//third_party/androidx:androidx_lifecycle_lifecycle_common_java", "//third_party/androidx:androidx_mediarouter_mediarouter_java", "//ui/android:ui_utils_java", ]
diff --git a/skia/config/SkUserConfig.h b/skia/config/SkUserConfig.h index 6086503..289671a1 100644 --- a/skia/config/SkUserConfig.h +++ b/skia/config/SkUserConfig.h
@@ -205,9 +205,6 @@ // Temporarily insulate Chrome pixel tests from Skia LOD bias change on GPU. #define SK_USE_LEGACY_MIPMAP_LOD_BIAS -// Temporarily insulate Chrome layout tests from change to HW stroking -#define SK_LEGACY_LINE_TESSELLATION - // Max. verb count for paths rendered by the edge-AA tessellating path renderer. #define GR_AA_TESSELLATOR_MAX_VERB_COUNT 100
diff --git a/skia/public/mojom/image_info_mojom_traits.cc b/skia/public/mojom/image_info_mojom_traits.cc index de7b7b6..fe5b162 100644 --- a/skia/public/mojom/image_info_mojom_traits.cc +++ b/skia/public/mojom/image_info_mojom_traits.cc
@@ -4,6 +4,7 @@ #include "skia/public/mojom/image_info_mojom_traits.h" +#include "base/numerics/checked_math.h" #include "base/numerics/safe_conversions.h" #include "mojo/public/cpp/bindings/array_data_view.h" #include "third_party/abseil-cpp/absl/types/optional.h" @@ -20,6 +21,8 @@ int height, mojo::ArrayDataView<float> color_transfer_function, mojo::ArrayDataView<float> color_to_xyz_matrix) { + CHECK_GE(width, 0); + CHECK_GE(height, 0); sk_sp<SkColorSpace> color_space; if (!color_transfer_function.is_null() && !color_to_xyz_matrix.is_null()) { const float* data = color_transfer_function.data(); @@ -208,9 +211,16 @@ mojo::ArrayDataView<float> color_to_xyz_matrix; data.GetColorToXyzMatrixDataView(&color_to_xyz_matrix); - *info = MakeSkImageInfo(color_type, alpha_type, data.width(), data.height(), - std::move(color_transfer_function), - std::move(color_to_xyz_matrix)); + // The ImageInfo wire types are uint32_t, but the Skia type uses int, and the + // values can't be negative. + auto width = base::MakeCheckedNum(data.width()).Cast<int>(); + auto height = base::MakeCheckedNum(data.height()).Cast<int>(); + if (!width.IsValid() || !height.IsValid()) + return false; + + *info = MakeSkImageInfo( + color_type, alpha_type, width.ValueOrDie(), height.ValueOrDie(), + std::move(color_transfer_function), std::move(color_to_xyz_matrix)); return true; } @@ -227,9 +237,16 @@ mojo::ArrayDataView<float> color_to_xyz_matrix; data.GetColorToXyzMatrixDataView(&color_to_xyz_matrix); - *info = MakeSkImageInfo(kN32_SkColorType, alpha_type, data.width(), - data.height(), std::move(color_transfer_function), - std::move(color_to_xyz_matrix)); + // The ImageInfo wire types are uint32_t, but the Skia type uses int, and the + // values can't be negative. + auto width = base::MakeCheckedNum(data.width()).Cast<int>(); + auto height = base::MakeCheckedNum(data.height()).Cast<int>(); + if (!width.IsValid() || !height.IsValid()) + return false; + + *info = MakeSkImageInfo( + kN32_SkColorType, alpha_type, width.ValueOrDie(), height.ValueOrDie(), + std::move(color_transfer_function), std::move(color_to_xyz_matrix)); return true; }
diff --git a/skia/public/mojom/test/mojom_traits_unittest.cc b/skia/public/mojom/test/mojom_traits_unittest.cc index 279f297f..4850da4 100644 --- a/skia/public/mojom/test/mojom_traits_unittest.cc +++ b/skia/public/mojom/test/mojom_traits_unittest.cc
@@ -2,9 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include <limits> #include "mojo/public/cpp/test_support/test_utils.h" #include "skia/public/mojom/bitmap.mojom.h" #include "skia/public/mojom/bitmap_skbitmap_mojom_traits.h" +#include "skia/public/mojom/image_info.mojom-shared.h" #include "skia/public/mojom/image_info.mojom.h" #include "skia/public/mojom/tile_mode.mojom.h" #include "skia/public/mojom/tile_mode_mojom_traits.h" @@ -69,6 +71,21 @@ return mojom_bitmap; } +// A helper to construct a skia.mojom.ImageInfo without using StructTraits +// to bypass checks on the sending/serialization side. +mojo::StructPtr<skia::mojom::ImageInfo> ConstructImageInfo( + SkColorType color_type, + SkAlphaType alpha_type, + uint32_t width, + uint32_t height) { + auto mojom_info = skia::mojom::ImageInfo::New(); + mojom_info->color_type = color_type; + mojom_info->alpha_type = alpha_type; + mojom_info->width = width; + mojom_info->height = height; + return mojom_info; +} + TEST(StructTraitsTest, ImageInfo) { SkImageInfo input = SkImageInfo::Make( 34, 56, SkColorType::kGray_8_SkColorType, @@ -88,6 +105,31 @@ EXPECT_EQ(another_input_with_null_color_space, output); } +// We catch negative integers on the sending side and crash, when struct traits +// are used. +TEST(StructTraitsDeathTest, ImageInfoOverflowSizeWithStructTrait) { + SkImageInfo input = SkImageInfo::Make( + std::numeric_limits<uint32_t>::max(), + std::numeric_limits<uint32_t>::max(), SkColorType::kGray_8_SkColorType, + SkAlphaType::kUnpremul_SkAlphaType, + SkColorSpace::MakeRGB(SkNamedTransferFn::kSRGB, SkNamedGamut::kAdobeRGB)); + SkImageInfo output; + EXPECT_DEATH(skia::mojom::ImageInfo::SerializeAsMessage(&input), ""); +} + +// We must reject sizes that would cause integer overflow on the receiving side. +// The wire format is `uint32_t`, but Skia needs us to convert that to an `int` +// for the SkImageInfo type. +TEST(StructTraitsTest, ImageInfoOverflowSizeWithoutStructTrait) { + SkImageInfo output; + mojo::StructPtr<skia::mojom::ImageInfo> input = ConstructImageInfo( + SkColorType::kGray_8_SkColorType, SkAlphaType::kUnpremul_SkAlphaType, + std::numeric_limits<uint32_t>::max(), + std::numeric_limits<uint32_t>::max()); + EXPECT_FALSE(mojo::test::SerializeAndDeserialize<skia::mojom::ImageInfo>( + input, output)); +} + TEST(StructTraitsTest, ImageInfoCustomColorSpace) { skcms_TransferFunction transfer{0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f}; skcms_Matrix3x3 gamut{
diff --git a/testing/PRESUBMIT.py b/testing/PRESUBMIT.py index 6a5524c..61b4fc1 100644 --- a/testing/PRESUBMIT.py +++ b/testing/PRESUBMIT.py
@@ -23,9 +23,7 @@ input_api, output_api, '.', - [r'^.+_unittest\.py$'], - run_on_python3=USE_PYTHON3, - skip_shebang_check=True)) + [r'^.+_unittest\.py$'])) output.extend(input_api.canned_checks.RunUnitTestsInDirectory( input_api, output_api, @@ -38,6 +36,21 @@ output.extend(input_api.canned_checks.RunPylint( input_api, output_api, + files_to_skip=[r'gmock.*', r'gtest.*', + r'buildbot.*', r'merge_scripts.*', r'trigger_scripts.*', + r'unexpected_passes_common.*', + r'clusterfuzz.*', + r'libfuzzer.*'])) + # Pylint2.7 is run on subdirs whose presubmit checks are migrated to Python3 + output.extend(input_api.canned_checks.RunPylint( + input_api, + output_api, + files_to_check=[r'buildbot.*\.py$', + r'merge_scripts.*\.py$', + r'trigger_scripts.*\.py$', + r'unexpected_passes_common.*\.py$', + r'clusterfuzz.*\.py$', + r'libfuzzer.*\.py$'], version='2.7')) return output
diff --git a/testing/__init__.py b/testing/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/testing/__init__.py +++ /dev/null
diff --git a/testing/buildbot/PRESUBMIT_test.py b/testing/buildbot/PRESUBMIT_test.py index 38e97fc..0ef25a4 100755 --- a/testing/buildbot/PRESUBMIT_test.py +++ b/testing/buildbot/PRESUBMIT_test.py
@@ -3,14 +3,10 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -import os -import sys import time import unittest -# Add src/testing/ into sys.path for importing PRESUBMIT without pylint errors. -sys.path.append(os.path.join(os.path.dirname(__file__), '..')) -from buildbot import PRESUBMIT +import PRESUBMIT class PresubmitError:
diff --git a/testing/buildbot/__init__.py b/testing/buildbot/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/testing/buildbot/__init__.py +++ /dev/null
diff --git a/testing/buildbot/chromium.android.fyi.json b/testing/buildbot/chromium.android.fyi.json index ab7c726..bd656cf1e 100644 --- a/testing/buildbot/chromium.android.fyi.json +++ b/testing/buildbot/chromium.android.fyi.json
@@ -8414,7 +8414,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M101", - "revision": "version:101.0.4951.49" + "revision": "version:101.0.4951.50" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -8498,7 +8498,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M102", - "revision": "version:102.0.5005.22" + "revision": "version:102.0.5005.23" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -8918,7 +8918,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M101", - "revision": "version:101.0.4951.49" + "revision": "version:101.0.4951.50" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -9002,7 +9002,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M102", - "revision": "version:102.0.5005.22" + "revision": "version:102.0.5005.23" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
diff --git a/testing/buildbot/chromium.android.json b/testing/buildbot/chromium.android.json index 6c930398..400e5948 100644 --- a/testing/buildbot/chromium.android.json +++ b/testing/buildbot/chromium.android.json
@@ -46015,7 +46015,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M101", - "revision": "version:101.0.4951.49" + "revision": "version:101.0.4951.50" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -46099,7 +46099,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M102", - "revision": "version:102.0.5005.22" + "revision": "version:102.0.5005.23" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -46519,7 +46519,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M101", - "revision": "version:101.0.4951.49" + "revision": "version:101.0.4951.50" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -46603,7 +46603,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M102", - "revision": "version:102.0.5005.22" + "revision": "version:102.0.5005.23" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -47027,7 +47027,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M101", - "revision": "version:101.0.4951.49" + "revision": "version:101.0.4951.50" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -47111,7 +47111,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M102", - "revision": "version:102.0.5005.22" + "revision": "version:102.0.5005.23" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -47531,7 +47531,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M101", - "revision": "version:101.0.4951.49" + "revision": "version:101.0.4951.50" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -47615,7 +47615,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M102", - "revision": "version:102.0.5005.22" + "revision": "version:102.0.5005.23" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -48106,7 +48106,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M101", - "revision": "version:101.0.4951.49" + "revision": "version:101.0.4951.50" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -48190,7 +48190,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M102", - "revision": "version:102.0.5005.22" + "revision": "version:102.0.5005.23" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -48610,7 +48610,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M101", - "revision": "version:101.0.4951.49" + "revision": "version:101.0.4951.50" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -48694,7 +48694,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M102", - "revision": "version:102.0.5005.22" + "revision": "version:102.0.5005.23" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -49185,7 +49185,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M101", - "revision": "version:101.0.4951.49" + "revision": "version:101.0.4951.50" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -49269,7 +49269,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M102", - "revision": "version:102.0.5005.22" + "revision": "version:102.0.5005.23" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -49689,7 +49689,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M101", - "revision": "version:101.0.4951.49" + "revision": "version:101.0.4951.50" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -49773,7 +49773,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M102", - "revision": "version:102.0.5005.22" + "revision": "version:102.0.5005.23" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json index c13fc3d..f5826d3 100644 --- a/testing/buildbot/chromium.fyi.json +++ b/testing/buildbot/chromium.fyi.json
@@ -9428,7 +9428,7 @@ "args": [ "--browser-ui-tests-verify-pixels", "--enable-pixel-output-in-tests", - "--test-launcher-filter-file=../../testing/buildbot/filters/pixel_browser_tests.filter", + "--test-launcher-filter-file=../../testing/buildbot/filters/pixel_tests.filter", "--git-revision=${got_revision}" ], "isolate_profile_data": true, @@ -10187,6 +10187,37 @@ "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/" }, { + "args": [ + "--browser-ui-tests-verify-pixels", + "--enable-pixel-output-in-tests", + "--test-launcher-filter-file=../../testing/buildbot/filters/pixel_tests.filter", + "--git-revision=${got_revision}" + ], + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "name": "pixel_interactive_ui_tests", + "precommit_args": [ + "--gerrit-issue=${patch_issue}", + "--gerrit-patchset=${patch_set}", + "--buildbucket-id=${buildbucket_build_id}" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Windows-11-22000" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "interactive_ui_tests", + "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/" + }, + { "isolate_profile_data": true, "merge": { "args": [], @@ -104417,7 +104448,7 @@ "args": [ "--browser-ui-tests-verify-pixels", "--enable-pixel-output-in-tests", - "--test-launcher-filter-file=../../testing/buildbot/filters/pixel_browser_tests.filter", + "--test-launcher-filter-file=../../testing/buildbot/filters/pixel_tests.filter", "--git-revision=${got_revision}" ], "merge": { @@ -104444,6 +104475,38 @@ }, "test": "browser_tests", "test_id_prefix": "ninja://chrome/test:browser_tests/" + }, + { + "args": [ + "--browser-ui-tests-verify-pixels", + "--enable-pixel-output-in-tests", + "--test-launcher-filter-file=../../testing/buildbot/filters/pixel_tests.filter", + "--git-revision=${got_revision}" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "name": "pixel_interactive_ui_tests", + "non_precommit_args": [ + "--test-launcher-retry-limit=0" + ], + "precommit_args": [ + "--gerrit-issue=${patch_issue}", + "--gerrit-patchset=${patch_set}", + "--buildbucket-id=${buildbucket_build_id}" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Windows-10-19042" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "interactive_ui_tests", + "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/" } ] },
diff --git a/testing/buildbot/chromium.win.json b/testing/buildbot/chromium.win.json index 5d892790..781e2fa 100644 --- a/testing/buildbot/chromium.win.json +++ b/testing/buildbot/chromium.win.json
@@ -2378,7 +2378,7 @@ "args": [ "--browser-ui-tests-verify-pixels", "--enable-pixel-output-in-tests", - "--test-launcher-filter-file=../../testing/buildbot/filters/pixel_browser_tests.filter", + "--test-launcher-filter-file=../../testing/buildbot/filters/pixel_tests.filter", "--git-revision=${got_revision}" ], "isolate_profile_data": true, @@ -3139,6 +3139,37 @@ "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/" }, { + "args": [ + "--browser-ui-tests-verify-pixels", + "--enable-pixel-output-in-tests", + "--test-launcher-filter-file=../../testing/buildbot/filters/pixel_tests.filter", + "--git-revision=${got_revision}" + ], + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "name": "pixel_interactive_ui_tests", + "precommit_args": [ + "--gerrit-issue=${patch_issue}", + "--gerrit-patchset=${patch_set}", + "--buildbucket-id=${buildbucket_build_id}" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Windows-10-19042" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "interactive_ui_tests", + "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/" + }, + { "isolate_profile_data": true, "merge": { "args": [],
diff --git a/testing/buildbot/filters/BUILD.gn b/testing/buildbot/filters/BUILD.gn index 25a91f5f..5020f65 100644 --- a/testing/buildbot/filters/BUILD.gn +++ b/testing/buildbot/filters/BUILD.gn
@@ -72,7 +72,7 @@ "//testing/buildbot/filters/mac.mac11-arm64-rel.browser_tests.filter", "//testing/buildbot/filters/mac.mac-rel.browser_tests.filter", "//testing/buildbot/filters/ozone-linux.wayland_browser_tests.filter", - "//testing/buildbot/filters/pixel_browser_tests.filter", + "//testing/buildbot/filters/pixel_tests.filter", "//testing/buildbot/filters/webrtc_functional.browser_tests.filter", "//testing/buildbot/filters/win_backuprefptr_fyi.browser_tests.filter", ] @@ -300,6 +300,7 @@ data = [ "//testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter", "//testing/buildbot/filters/ozone-linux.interactive_ui_tests_wayland.filter", + "//testing/buildbot/filters/pixel_tests.filter", ] }
diff --git a/testing/buildbot/filters/pixel_browser_tests.filter b/testing/buildbot/filters/pixel_tests.filter similarity index 77% rename from testing/buildbot/filters/pixel_browser_tests.filter rename to testing/buildbot/filters/pixel_tests.filter index bc3b0d9..9354c96 100644 --- a/testing/buildbot/filters/pixel_browser_tests.filter +++ b/testing/buildbot/filters/pixel_tests.filter
@@ -1,67 +1,80 @@ -# This is the filter for browser_tests that supports pixel tests. -AccuracyTipBubbleViewDialogBrowserTest.* -AppInfoDialogBrowserTest.* -AskGoogleForSuggestionsDialogTest.* -BookmarkBubbleViewBrowserTest.* -BookmarkEditorViewBrowserTest.* -ChromeLabsUiTest.* -ConfirmBubbleTest.* -ContentAnalysysDialogUiTest.* -ContentSettingBubbleDialogTest.* -CookieControlsBubbleViewTest.* -CryptoModulePasswordDialogTest.* -DeepScanningFailureModalDialogTest.* -*DiceWebSigninInterceptionBubblePixelTest.InvokeUi_* -*DiceWebSigninInterceptionBubbleSyncPromoPixelTest.InvokeUi_* -ExtensionInstallDialogViewInteractiveBrowserTest.* -ExtensionUninstallDialogViewInteractiveBrowserTest.* -*EyeDropperBrowserTest.* -FeaturePromoDialogTest.* -FileSystemAccessUsageBubbleViewTest.* -FirstRunDialogTest.* -GlobalErrorBubbleTest.* -HatsBubbleTest.* -HungRendererDialogViewBrowserTest.* -ImportLockDialogViewBrowserTest.* -InlineLoginHelperBrowserTest.InvokeUi_* -LocalCardMigrationBrowserUiTest.* -NewTabPageTest.* -OneTimePermissionPromptBubbleViewBrowserTest.* -OutdatedUpgradeBubbleTest.* -PageInfoBubbleViewAboutThisSiteDialogBrowserTest.* -PageInfoBubbleViewDialogBrowserTest.* -PageInfoBubbleViewPrivacySandboxDialogBrowserTest.* -PageInfoBubbleViewHistoryDialogBrowserTest.* -*PasswordBubbleBrowserTest.* -PasswordReuseModalWarningTest.* -PermissionRequestChipDialogBrowserTest.* -*PermissionPromptBubbleViewBrowserTest.* -PrivacySandboxDialogViewBrowserTest.* -PromptForScanningModalDialogTest.* -QRCodeGeneratorBubbleBrowserTest.* -RelaunchRecommendedBubbleViewDialogTest.* -RelaunchRequiredDialogViewDialogTest.* -ReopenTabPromoControllerDialogBrowserTest.* -SafetyTipPageInfoBubbleViewDialogTest.* -ScreenCaptureNotificationUiBrowserTest.* -SecurePaymentConfirmationDialogViewTest.InvokeUi_* -*SendTabToSelfBubbleTest.* -SessionCrashedBubbleViewTest.* -TabGroupEditorBubbleViewDialogBrowserTest.* -TabHoverCardBubbleViewBrowserTest.* -UpdateRecommendedDialogTest.* -WebAppConfirmViewBrowserTest.* -ZoomBubbleDialogTest.* - -# This test uses random network port and shows it on ui. --ContentSettingBubbleDialogTest.InvokeUi_popups --OutdatedUpgradeBubbleTest.InvokeUi_Critical -# TODO(crbug.com/1108988): Fix this flakiness test. --BookmarkBubbleViewBrowserTest.InvokeUi_bookmark_details_signed_in - -# TODO(crbug.com/2666206): Flaky --ContentSettingBubbleDialogTest.InvokeUi_mediastream_camera --ContentSettingBubbleDialogTest.InvokeUi_mediastream_mic_and_camera - -# TODO(crbug.com/1164574): Flaky --ContentSettingBubbleDialogTest.InvokeUi_mediastream_mic +# This is the filter for browser_tests and interactive_ui_tests that support +# pixel tests. In order for pixel tests to work, you *must* include your test +# here. +# +# Since these tests will all run in both browser_tests (or interactive_ui_tests) +# and pixel_browser_tests (or pixel_interactive_ui_tests), avoid including +# non-pixel tests here. +# +# Prefer browser_tests to interactive_ui_tests, as they are less expensive to +# run; only use interactive_ui_tests if running your test in browser_tests +# causes flakes (due to widget activation, occlusion, etc.) + +AccuracyTipBubbleViewDialogBrowserTest.* +AppInfoDialogBrowserTest.* +AskGoogleForSuggestionsDialogTest.* +BookmarkBubbleViewBrowserTest.* +BookmarkEditorViewBrowserTest.* +ChromeLabsUiTest.* +ConfirmBubbleTest.* +ContentAnalysysDialogUiTest.* +ContentSettingBubbleDialogTest.* +CookieControlsBubbleViewTest.* +CryptoModulePasswordDialogTest.* +DeepScanningFailureModalDialogTest.* +*DiceWebSigninInterceptionBubblePixelTest.InvokeUi_* +*DiceWebSigninInterceptionBubbleSyncPromoPixelTest.InvokeUi_* +ExtensionInstallDialogViewInteractiveBrowserTest.* +ExtensionUninstallDialogViewInteractiveBrowserTest.* +*EyeDropperBrowserTest.* +FeaturePromoDialogIntentChipTest.InvokeUi_* +FeaturePromoDialogTest.InvokeUi_* +FileSystemAccessUsageBubbleViewTest.* +FirstRunDialogTest.* +GlobalErrorBubbleTest.* +HatsBubbleTest.* +HungRendererDialogViewBrowserTest.* +ImportLockDialogViewBrowserTest.* +InlineLoginHelperBrowserTest.InvokeUi_* +InteractionSequenceBrowserUtilTest.CompareScreenshot_* +LocalCardMigrationBrowserUiTest.* +NewTabPageTest.* +OneTimePermissionPromptBubbleViewBrowserTest.* +OutdatedUpgradeBubbleTest.* +PageInfoBubbleViewAboutThisSiteDialogBrowserTest.* +PageInfoBubbleViewDialogBrowserTest.* +PageInfoBubbleViewPrivacySandboxDialogBrowserTest.* +PageInfoBubbleViewHistoryDialogBrowserTest.* +*PasswordBubbleBrowserTest.* +PasswordReuseModalWarningTest.* +PermissionRequestChipDialogBrowserTest.* +*PermissionPromptBubbleViewBrowserTest.* +PrivacySandboxDialogViewBrowserTest.* +PromptForScanningModalDialogTest.* +QRCodeGeneratorBubbleBrowserTest.* +RelaunchRecommendedBubbleViewDialogTest.* +RelaunchRequiredDialogViewDialogTest.* +ReopenTabPromoControllerDialogBrowserTest.* +SafetyTipPageInfoBubbleViewDialogTest.* +ScreenCaptureNotificationUiBrowserTest.* +SecurePaymentConfirmationDialogViewTest.InvokeUi_* +*SendTabToSelfBubbleTest.* +SessionCrashedBubbleViewTest.* +TabGroupEditorBubbleViewDialogBrowserTest.* +TabHoverCardBubbleViewBrowserTest.* +UpdateRecommendedDialogTest.* +WebAppConfirmViewBrowserTest.* +ZoomBubbleDialogTest.* + +# This test uses random network port and shows it on ui. +-ContentSettingBubbleDialogTest.InvokeUi_popups +-OutdatedUpgradeBubbleTest.InvokeUi_Critical +# TODO(crbug.com/1108988): Fix this flakiness test. +-BookmarkBubbleViewBrowserTest.InvokeUi_bookmark_details_signed_in + +# TODO(crbug.com/2666206): Flaky +-ContentSettingBubbleDialogTest.InvokeUi_mediastream_camera +-ContentSettingBubbleDialogTest.InvokeUi_mediastream_mic_and_camera + +# TODO(crbug.com/1164574): Flaky +-ContentSettingBubbleDialogTest.InvokeUi_mediastream_mic
diff --git a/testing/buildbot/test_suite_exceptions.pyl b/testing/buildbot/test_suite_exceptions.pyl index 2723558..45b5cddc 100644 --- a/testing/buildbot/test_suite_exceptions.pyl +++ b/testing/buildbot/test_suite_exceptions.pyl
@@ -2581,6 +2581,19 @@ }, }, }, + 'pixel_interactive_ui_tests': { + 'modifications': { + 'win-pixel-tester-rel': { + 'non_precommit_args': [ + # Do not allow retry or it will break the bulk approval process. + # When retry with fail-pass pattern, the passing test will overwrite the previously + # seen flaky version on the trace. We can triage the image using the printed link, + # but it will not show on the Skia Gold search page. + '--test-launcher-retry-limit=0', + ], + }, + }, + }, 'pixel_skia_gold_passthrough_test': { 'modifications': { 'Android FYI Release (Pixel 4)': {
diff --git a/testing/buildbot/test_suites.pyl b/testing/buildbot/test_suites.pyl index a0bd72c..ad08652 100644 --- a/testing/buildbot/test_suites.pyl +++ b/testing/buildbot/test_suites.pyl
@@ -4615,13 +4615,25 @@ 'args': [ '--browser-ui-tests-verify-pixels', '--enable-pixel-output-in-tests', - '--test-launcher-filter-file=../../testing/buildbot/filters/pixel_browser_tests.filter', + '--test-launcher-filter-file=../../testing/buildbot/filters/pixel_tests.filter', ], 'test': 'browser_tests', 'mixins': [ 'skia_gold_test', ], }, + 'pixel_interactive_ui_tests': { + 'name': 'pixel_interactive_ui_tests', + 'args': [ + '--browser-ui-tests-verify-pixels', + '--enable-pixel-output-in-tests', + '--test-launcher-filter-file=../../testing/buildbot/filters/pixel_tests.filter', + ], + 'test': 'interactive_ui_tests', + 'mixins': [ + 'skia_gold_test', + ], + }, }, # TODO(dpranke): These are run on the p/chromium waterfall; they should
diff --git a/testing/buildbot/variants.pyl b/testing/buildbot/variants.pyl index 4592b93..07fd18fc 100644 --- a/testing/buildbot/variants.pyl +++ b/testing/buildbot/variants.pyl
@@ -449,7 +449,7 @@ { 'cipd_package': 'chromium/testing/weblayer-x86', 'location': 'weblayer_instrumentation_test_M102', - 'revision': 'version:102.0.5005.22', + 'revision': 'version:102.0.5005.23', } ], }, @@ -473,7 +473,7 @@ { 'cipd_package': 'chromium/testing/weblayer-x86', 'location': 'weblayer_instrumentation_test_M101', - 'revision': 'version:101.0.4951.49', + 'revision': 'version:101.0.4951.50', } ], }, @@ -593,7 +593,7 @@ { 'cipd_package': 'chromium/testing/weblayer-x86', 'location': 'weblayer_instrumentation_test_M102', - 'revision': 'version:102.0.5005.22', + 'revision': 'version:102.0.5005.23', } ], }, @@ -617,7 +617,7 @@ { 'cipd_package': 'chromium/testing/weblayer-x86', 'location': 'weblayer_instrumentation_test_M101', - 'revision': 'version:101.0.4951.49', + 'revision': 'version:101.0.4951.50', } ], }, @@ -737,7 +737,7 @@ { 'cipd_package': 'chromium/testing/weblayer-x86', 'location': 'weblayer_instrumentation_test_M102', - 'revision': 'version:102.0.5005.22', + 'revision': 'version:102.0.5005.23', } ], }, @@ -761,7 +761,7 @@ { 'cipd_package': 'chromium/testing/weblayer-x86', 'location': 'weblayer_instrumentation_test_M101', - 'revision': 'version:101.0.4951.49', + 'revision': 'version:101.0.4951.50', } ], },
diff --git a/testing/chromoting/browser_tests_launcher.py b/testing/chromoting/browser_tests_launcher.py index c0dd849..6f0ba62 100644 --- a/testing/chromoting/browser_tests_launcher.py +++ b/testing/chromoting/browser_tests_launcher.py
@@ -85,7 +85,7 @@ retries += 1 time.sleep(30) continue - if jids_used: + elif jids_used: print('JID used by test matched me2me host JID: %s' % host_jid) else: # There wasn't a mismatch and no JIDs were returned. If no JIDs were
diff --git a/testing/merge_scripts/code_coverage/merge_lib.py b/testing/merge_scripts/code_coverage/merge_lib.py index 15a86e50..1699e958 100644 --- a/testing/merge_scripts/code_coverage/merge_lib.py +++ b/testing/merge_scripts/code_coverage/merge_lib.py
@@ -70,7 +70,8 @@ paths = [] for dir_path, _sub_dirs, file_names in os.walk(input_dir): paths.extend([ - os.path.join(dir_path, fn) + # Normalize to POSIX style paths for consistent results. + os.path.join(dir_path, fn).replace('\\', '/') for fn in file_names if fn.endswith(input_extension) and re.search(input_filename_pattern,fn) ])
diff --git a/testing/scripts/__init__.py b/testing/scripts/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/testing/scripts/__init__.py +++ /dev/null
diff --git a/testing/scripts/blink_lint_expectations.py b/testing/scripts/blink_lint_expectations.py index c1f2ad9..bb26b91 100755 --- a/testing/scripts/blink_lint_expectations.py +++ b/testing/scripts/blink_lint_expectations.py
@@ -7,10 +7,8 @@ import os import sys -# Add src/testing/ into sys.path for importing common without pylint errors. -sys.path.append( - os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir))) -from scripts import common + +import common def main_run(args):
diff --git a/testing/scripts/blink_python_tests.py b/testing/scripts/blink_python_tests.py index a9c854b..c7f14e68 100755 --- a/testing/scripts/blink_python_tests.py +++ b/testing/scripts/blink_python_tests.py
@@ -7,10 +7,8 @@ import os import sys -# Add src/testing/ into sys.path for importing common without pylint errors. -sys.path.append( - os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir))) -from scripts import common + +import common def main_run(args):
diff --git a/testing/scripts/check_gn_headers.py b/testing/scripts/check_gn_headers.py index ccf0ba21..6530ada7 100755 --- a/testing/scripts/check_gn_headers.py +++ b/testing/scripts/check_gn_headers.py
@@ -7,10 +7,8 @@ import os import sys -# Add src/testing/ into sys.path for importing common without pylint errors. -sys.path.append( - os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir))) -from scripts import common + +import common def main_run(args):
diff --git a/testing/scripts/check_network_annotations.py b/testing/scripts/check_network_annotations.py index 7d05b49a..6e2875d8 100755 --- a/testing/scripts/check_network_annotations.py +++ b/testing/scripts/check_network_annotations.py
@@ -12,10 +12,8 @@ import os import sys -# Add src/testing/ into sys.path for importing common without pylint errors. -sys.path.append( - os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir))) -from scripts import common + +import common def main_run(args):
diff --git a/testing/scripts/check_static_initializers.py b/testing/scripts/check_static_initializers.py index dc9b1d27..3afd112 100755 --- a/testing/scripts/check_static_initializers.py +++ b/testing/scripts/check_static_initializers.py
@@ -11,10 +11,7 @@ import subprocess import sys -# Add src/testing/ into sys.path for importing common without pylint errors. -sys.path.append( - os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir))) -from scripts import common +import common # A list of files that are allowed to have static initializers. # If something adds a static initializer, revert it. We don't accept regressions
diff --git a/testing/scripts/checkbins.py b/testing/scripts/checkbins.py index af8208dc..f66c8b1 100755 --- a/testing/scripts/checkbins.py +++ b/testing/scripts/checkbins.py
@@ -21,14 +21,11 @@ import os import sys -# Add src/testing/ into sys.path for importing common without pylint errors. -sys.path.append( - os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir))) -from scripts import common + +import common WIN_PY3_TARGETS = ['python3.exe', 'python3.bat'] - def with_python3(): if sys.version_info.major >= 3: return sys.executable
diff --git a/testing/scripts/checkdeps.py b/testing/scripts/checkdeps.py index 9c49d82..e772ae87 100755 --- a/testing/scripts/checkdeps.py +++ b/testing/scripts/checkdeps.py
@@ -8,10 +8,7 @@ import sys -# Add src/testing/ into sys.path for importing common without pylint errors. -sys.path.append( - os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir))) -from scripts import common +import common def main_run(args):
diff --git a/testing/scripts/checklicenses.py b/testing/scripts/checklicenses.py index 3a51fcf6..43342d0 100755 --- a/testing/scripts/checklicenses.py +++ b/testing/scripts/checklicenses.py
@@ -8,10 +8,7 @@ import sys -# Add src/testing/ into sys.path for importing common without pylint errors. -sys.path.append( - os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir))) -from scripts import common +import common def main_run(args):
diff --git a/testing/scripts/checkperms.py b/testing/scripts/checkperms.py index e635aa1..8adb025 100755 --- a/testing/scripts/checkperms.py +++ b/testing/scripts/checkperms.py
@@ -8,10 +8,7 @@ import sys -# Add src/testing/ into sys.path for importing common without pylint errors. -sys.path.append( - os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir))) -from scripts import common +import common def main_run(args):
diff --git a/testing/scripts/common.py b/testing/scripts/common.py index d57595c..1c31066d 100644 --- a/testing/scripts/common.py +++ b/testing/scripts/common.py
@@ -18,8 +18,7 @@ logging.basicConfig(level=logging.INFO) # Add src/testing/ into sys.path for importing xvfb and test_env. -sys.path.append( - os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir))) +sys.path.append(os.path.join(os.path.dirname(__file__), '..')) import test_env if sys.platform.startswith('linux'): import xvfb @@ -66,8 +65,6 @@ '\\ALL RESTRICTED APPLICATION PACKAGES:(I)(OI)(CI)(RX)' ] -# pylint: disable=useless-object-inheritance - def set_lpac_acls(acl_dir, is_test_script=False): """Sets LPAC ACLs on a directory. Windows 10 only.""" @@ -234,7 +231,7 @@ passing_statuses = ('PASS', 'SLOW', 'NEEDSREBASELINE') for test, result in convert_trie_to_flat_paths( - json_results['tests']).items(): + json_results['tests']).iteritems(): key = 'unexpected_' if result.get('is_unexpected') else '' data = result['actual'] actual_results = data.split()
diff --git a/testing/scripts/content_shell_crash_test.py b/testing/scripts/content_shell_crash_test.py index 60f76a75..fe3515a7 100755 --- a/testing/scripts/content_shell_crash_test.py +++ b/testing/scripts/content_shell_crash_test.py
@@ -9,11 +9,11 @@ import sys -# Add src/testing/ into sys.path for importing xvfb and common. -sys.path.append( - os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir))) +import common + +# Add src/testing/ into sys.path for importing xvfb. +sys.path.append(os.path.join(os.path.dirname(__file__), '..')) import xvfb -from scripts import common # Unfortunately we need to copy these variables from ../test_env.py.
diff --git a/testing/scripts/count_filtered_tests.py b/testing/scripts/count_filtered_tests.py index 588c87f..97bb8f54 100644 --- a/testing/scripts/count_filtered_tests.py +++ b/testing/scripts/count_filtered_tests.py
@@ -9,10 +9,7 @@ import sys -# Add src/testing/ into sys.path for importing common without pylint errors. -sys.path.append( - os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir))) -from scripts import common +import common def ParseTestList(test_list_contents):
diff --git a/testing/scripts/get_compile_targets.py b/testing/scripts/get_compile_targets.py index 75e15dc9d..3772d50a 100755 --- a/testing/scripts/get_compile_targets.py +++ b/testing/scripts/get_compile_targets.py
@@ -8,10 +8,7 @@ import os import sys -# Add src/testing/ into sys.path for importing common without pylint errors. -sys.path.append( - os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir))) -from scripts import common +import common def main(argv): @@ -54,11 +51,7 @@ return rc with open(tempfile_path) as f: - # json.load() throws a ValueError for empty files - try: - results[filename] = json.load(f) - except ValueError: - pass + results[filename] = json.load(f) with open(args.output, 'w') as f: json.dump(results, f)
diff --git a/testing/scripts/gpu_integration_test_adapter.py b/testing/scripts/gpu_integration_test_adapter.py index 6aae983e..8c12571 100644 --- a/testing/scripts/gpu_integration_test_adapter.py +++ b/testing/scripts/gpu_integration_test_adapter.py
@@ -2,14 +2,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -import os -import sys - -# Add src/testing/ into sys.path for importing common without pylint errors. -sys.path.append( - os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir))) -from scripts import common - +import common class GpuIntegrationTestAdapater(common.BaseIsolatedScriptArgsAdapter):
diff --git a/testing/scripts/grit_python_unittests.py b/testing/scripts/grit_python_unittests.py index 9a2218e..532e4b1 100755 --- a/testing/scripts/grit_python_unittests.py +++ b/testing/scripts/grit_python_unittests.py
@@ -11,10 +11,7 @@ import os import sys -# Add src/testing/ into sys.path for importing common without pylint errors. -sys.path.append( - os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir))) -from scripts import common +import common def main_run(args):
diff --git a/testing/scripts/headless_python_unittests.py b/testing/scripts/headless_python_unittests.py index 4e32907..881cff4a 100755 --- a/testing/scripts/headless_python_unittests.py +++ b/testing/scripts/headless_python_unittests.py
@@ -7,10 +7,8 @@ import os import sys -# Add src/testing/ into sys.path for importing common without pylint errors. -sys.path.append( - os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir))) -from scripts import common + +import common def main_run(args): @@ -18,7 +16,7 @@ os.path.dirname(__file__), os.path.pardir, os.path.pardir, 'third_party', 'catapult', 'third_party', 'typ')) _AddToPathIfNeeded(typ_path) - import typ #pylint: disable=import-outside-toplevel + import typ top_level_dir = os.path.join( common.SRC_DIR, 'headless', 'lib', 'browser', 'devtools_api')
diff --git a/testing/scripts/host_info.py b/testing/scripts/host_info.py index 86c8514..63e3b9ba 100755 --- a/testing/scripts/host_info.py +++ b/testing/scripts/host_info.py
@@ -9,10 +9,7 @@ import platform import sys -# Add src/testing/ into sys.path for importing common without pylint errors. -sys.path.append( - os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir))) -from scripts import common +import common def is_linux(): @@ -91,7 +88,7 @@ v['ro.build.fingerprint'] for v in device_info if not v['denylisted']] def unique_build_details(index): - return sorted(list({v.split(':')[index] for v in details})) + return sorted(list(set([v.split(':')[index] for v in details]))) parsed_details = { 'device_names': unique_build_details(0),
diff --git a/testing/scripts/metrics_python_tests.py b/testing/scripts/metrics_python_tests.py index 2746430..70770f41 100755 --- a/testing/scripts/metrics_python_tests.py +++ b/testing/scripts/metrics_python_tests.py
@@ -9,10 +9,8 @@ import os import sys -# Add src/testing/ into sys.path for importing common without pylint errors. -sys.path.append( - os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir))) -from scripts import common + +import common def main_run(args):
diff --git a/testing/scripts/run_android_wpt.py b/testing/scripts/run_android_wpt.py index 0417a5775..db183b2 100755 --- a/testing/scripts/run_android_wpt.py +++ b/testing/scripts/run_android_wpt.py
@@ -26,16 +26,12 @@ # run_wpt_tests.py script. import json -import os import sys +import common from run_wpt_tests import WPTAdapter -# Add src/testing/ into sys.path for importing common without pylint errors. -sys.path.append( - os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir))) -from scripts import common # This is not really a "script test" so does not need to manually add # any additional compile targets.
diff --git a/testing/scripts/run_android_wpt.pydeps b/testing/scripts/run_android_wpt.pydeps index cba4c8d8..ac6fdf5 100644 --- a/testing/scripts/run_android_wpt.pydeps +++ b/testing/scripts/run_android_wpt.pydeps
@@ -20,7 +20,6 @@ //build/util/lib/results/__init__.py //build/util/lib/results/result_sink.py //build/util/lib/results/result_types.py -//testing/scripts/__init__.py //testing/scripts/common.py //testing/scripts/run_android_wpt.py //testing/scripts/run_wpt_tests.py
diff --git a/testing/scripts/run_cast_core_tests.py b/testing/scripts/run_cast_core_tests.py index 7d5e9e9..f94e106 100755 --- a/testing/scripts/run_cast_core_tests.py +++ b/testing/scripts/run_cast_core_tests.py
@@ -19,13 +19,9 @@ """ import json -import os import sys -# Add src/testing/ into sys.path for importing common without pylint errors. -sys.path.append( - os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir))) -from scripts import common +import common class CastCoreIntegrationTestAdapter(common.BaseIsolatedScriptArgsAdapter): @@ -51,4 +47,4 @@ 'compile_targets': main_compile_targets, } sys.exit(common.run_script(sys.argv[1:], funcs)) - sys.exit(main()) + sys.exit(main()) \ No newline at end of file
diff --git a/testing/scripts/run_chromedriver_tests.py b/testing/scripts/run_chromedriver_tests.py index 203ae32..b1f67ce 100755 --- a/testing/scripts/run_chromedriver_tests.py +++ b/testing/scripts/run_chromedriver_tests.py
@@ -25,10 +25,7 @@ import tempfile import traceback -# Add src/testing/ into sys.path for importing common without pylint errors. -sys.path.append( - os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir))) -from scripts import common +import common class ChromeDriverAdapter(common.BaseIsolatedScriptArgsAdapter):
diff --git a/testing/scripts/run_devtools_check.py b/testing/scripts/run_devtools_check.py index 9f9be63..104f5f72 100755 --- a/testing/scripts/run_devtools_check.py +++ b/testing/scripts/run_devtools_check.py
@@ -21,11 +21,11 @@ import sys -# Add src/testing/ into sys.path for importing xvfb and common. -sys.path.append( - os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir))) +import common + +# Add src/testing/ into sys.path for importing xvfb. +sys.path.append(os.path.join(os.path.dirname(__file__), '..')) import xvfb -from scripts import common def main():
diff --git a/testing/scripts/run_finch_smoke_tests_android.py b/testing/scripts/run_finch_smoke_tests_android.py index cd12b7e..e3d91220 100755 --- a/testing/scripts/run_finch_smoke_tests_android.py +++ b/testing/scripts/run_finch_smoke_tests_android.py
@@ -19,7 +19,6 @@ SRC_DIR = os.path.abspath( os.path.join(os.path.dirname(__file__), os.pardir, os.pardir)) -PAR_DIR = os.path.join(SRC_DIR, 'testing') OUT_DIR = os.path.join(SRC_DIR, 'out', 'Release') BLINK_TOOLS = os.path.join( SRC_DIR, 'third_party', 'blink', 'tools') @@ -47,11 +46,10 @@ if WEBVIEW_VARIATIONS_PROTO not in sys.path: sys.path.append(WEBVIEW_VARIATIONS_PROTO) -sys.path.append(PAR_DIR) - if 'compile_targets' not in sys.argv: import aw_variations_seed_pb2 +import common import devil_chromium import wpt_common @@ -68,7 +66,6 @@ from devil.utils import logging_common from pylib.local.emulator import avd from py_utils.tempfile_ext import NamedTemporaryDirectory -from scripts import common from skia_gold_infra.finch_skia_gold_properties import FinchSkiaGoldProperties from skia_gold_infra import finch_skia_gold_session_manager from skia_gold_infra import finch_skia_gold_utils @@ -85,8 +82,6 @@ logger.setLevel(logging.INFO) TEST_CASES = {} -# pylint: disable=super-with-arguments - class FinchTestCase(wpt_common.BaseWptScriptAdapter): @@ -100,7 +95,6 @@ self.browser_activity_name = (self.options.browser_activity_name or self.default_browser_activity_name) self.log_mon = None - self.layout_test_results_subdir = None self.test_specific_browser_args = [] if self.options.webview_provider_apk: self.webview_provider_package_name = (
diff --git a/testing/scripts/run_flatbuffers_unittests.py b/testing/scripts/run_flatbuffers_unittests.py index daea0f5..c9b8fde9 100755 --- a/testing/scripts/run_flatbuffers_unittests.py +++ b/testing/scripts/run_flatbuffers_unittests.py
@@ -20,14 +20,11 @@ import os import sys -# Add src/testing/ into sys.path for importing xvfb and common. -sys.path.append( - os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir))) +import common + +# Add src/testing/ into sys.path for importing xvfb and test_env. +sys.path.append(os.path.join(os.path.dirname(__file__), '..')) import xvfb -from scripts import common - -# pylint: disable=super-with-arguments - def main(): parser = argparse.ArgumentParser()
diff --git a/testing/scripts/run_gpu_integration_test_as_googletest.py b/testing/scripts/run_gpu_integration_test_as_googletest.py index 3456a7e..dc5e128 100755 --- a/testing/scripts/run_gpu_integration_test_as_googletest.py +++ b/testing/scripts/run_gpu_integration_test_as_googletest.py
@@ -19,16 +19,11 @@ """ import json -import os import sys +import common import gpu_integration_test_adapter -# Add src/testing/ into sys.path for importing common without pylint errors. -sys.path.append( - os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir))) -from scripts import common - def main(): adapter = gpu_integration_test_adapter.GpuIntegrationTestAdapater()
diff --git a/testing/scripts/run_isolated_script_test.py b/testing/scripts/run_isolated_script_test.py index 0e963d6..fed58832 100755 --- a/testing/scripts/run_isolated_script_test.py +++ b/testing/scripts/run_isolated_script_test.py
@@ -26,11 +26,7 @@ import tempfile -# Add src/testing/ into sys.path for importing xvfb and common. -sys.path.append( - os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir))) -import xvfb -from scripts import common +import common # Some harnesses understand the --isolated-script-test arguments @@ -56,9 +52,10 @@ 'test_suite_all.py', # //tools/grit:grit_python_unittests } -# pylint: disable=super-with-arguments - class IsolatedScriptTestAdapter(common.BaseIsolatedScriptArgsAdapter): + def __init__(self): + super(IsolatedScriptTestAdapter, self).__init__() + def generate_sharding_args(self, total_shards, shard_index): # This script only uses environment variable for sharding. del total_shards, shard_index # unused @@ -121,6 +118,9 @@ return 'vpython3.bat' if sys.platform == 'win32' else 'vpython3' return super(TypUnittestAdapter, self).select_python_executable() + def run_test(self): + return super(TypUnittestAdapter, self).run_test() + def main(): if any(r in sys.argv[1] for r in KNOWN_ISOLATED_SCRIPT_TEST_RUNNERS):
diff --git a/testing/scripts/run_isolated_script_test.pydeps b/testing/scripts/run_isolated_script_test.pydeps index df35f82..bc8ff58 100644 --- a/testing/scripts/run_isolated_script_test.pydeps +++ b/testing/scripts/run_isolated_script_test.pydeps
@@ -4,7 +4,6 @@ //build/util/lib/results/__init__.py //build/util/lib/results/result_sink.py //build/util/lib/results/result_types.py -//testing/scripts/__init__.py //testing/scripts/common.py //testing/scripts/run_isolated_script_test.py //testing/test_env.py
diff --git a/testing/scripts/run_performance_tests.py b/testing/scripts/run_performance_tests.py index a46efbe5..b687be8 100755 --- a/testing/scripts/run_performance_tests.py +++ b/testing/scripts/run_performance_tests.py
@@ -48,11 +48,11 @@ import traceback import six +import common from collections import OrderedDict CHROMIUM_SRC_DIR = os.path.abspath( - os.path.join(os.path.dirname(__file__), - os.path.pardir, os.path.pardir)) + os.path.join(os.path.dirname(__file__), '..', '..')) PERF_DIR = os.path.join(CHROMIUM_SRC_DIR, 'tools', 'perf') sys.path.append(PERF_DIR) @@ -63,21 +63,19 @@ sys.path.append(PERF_CORE_DIR) import results_merger -# Add src/testing/ into sys.path for importing xvfb, test_env, and common. -sys.path.append( - os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir))) +# Add src/testing/ into sys.path for importing xvfb and test_env. +sys.path.append(os.path.join(os.path.dirname(__file__), '..')) import xvfb import test_env -from scripts import common # Unfortunately we need to copy these variables from ../test_env.py. # Importing it and using its get_sandbox_env breaks test runs on Linux # (it seems to unset DISPLAY). CHROME_SANDBOX_ENV = 'CHROME_DEVEL_SANDBOX' CHROME_SANDBOX_PATH = '/opt/chromium/chrome_sandbox' -SHARD_MAPS_DIRECTORY = os.path.abspath( - os.path.join(os.path.dirname(__file__), os.path.pardir, os.path.pardir, - 'tools', 'perf', 'core', 'shard_maps')) +SHARD_MAPS_DIRECTORY = os.path.join( + os.path.dirname(__file__), '..', '..', 'tools', 'perf', 'core', + 'shard_maps') # See https://crbug.com/923564. # We want to switch over to using histograms for everything, but converting from @@ -108,8 +106,6 @@ 'xr.vr.common_perftests', ] -# pylint: disable=useless-object-inheritance - class OutputFilePaths(object): """Provide paths to where results outputs should be written. @@ -192,7 +188,8 @@ executable = str(self.executable_name) if IsWindows(): return r'.\%s.exe' % executable - return './%s' % executable + else: + return './%s' % executable def _get_additional_flags(self): return self._additional_flags @@ -249,7 +246,7 @@ benchmark_name: { 'expected': 'PASS', 'actual': 'FAIL' if return_code else 'PASS', - 'is_unexpected': bool(return_code), + 'is_unexpected': True if return_code else False, }, }, 'interrupted': False, @@ -356,9 +353,9 @@ if os.path.exists(output_paths.perf_results): if command_generator.executable_name in GTEST_CONVERSION_WHITELIST: with path_util.SysPath(path_util.GetTracingDir()): - # pylint: disable=no-name-in-module,import-outside-toplevel + # pylint: disable=no-name-in-module from tracing.value import gtest_json_converter - # pylint: enable=no-name-in-module,import-outside-toplevel + # pylint: enable=no-name-in-module gtest_json_converter.ConvertGtestJsonFile(output_paths.perf_results) else: print('ERROR: gtest perf test %s did not generate perf output' %
diff --git a/testing/scripts/run_rendering_benchmark_with_gated_performance.py b/testing/scripts/run_rendering_benchmark_with_gated_performance.py index 39537a0..1011ac3 100755 --- a/testing/scripts/run_rendering_benchmark_with_gated_performance.py +++ b/testing/scripts/run_rendering_benchmark_with_gated_performance.py
@@ -26,13 +26,9 @@ import numpy as np +import common import run_performance_tests -# Add src/testing/ into sys.path for importing common without pylint errors. -sys.path.append( - os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir))) -from scripts import common - # AVG_ERROR_MARGIN determines how much more the value of frame times can be # compared to the recorded value (multiplier of upper limit). AVG_ERROR_MARGIN = 1.1 @@ -44,9 +40,6 @@ METRIC_NAME = 'frame_times' -# pylint: disable=useless-object-inheritance - - class ResultRecorder(object): def __init__(self): self.fails = 0 @@ -159,7 +152,7 @@ # least by 10 [AVG_ERROR_MARGIN] percent of upper limit, that would be # considered a failure. crbug.com/953895 with open( - os.path.join(os.path.dirname(os.path.abspath(__file__)), + os.path.join(os.path.dirname(__file__), 'representative_perf_test_data', 'representatives_frame_times_upper_limit.json') ) as bound_data:
diff --git a/testing/scripts/run_telemetry_as_googletest.py b/testing/scripts/run_telemetry_as_googletest.py index b67063bb..e05f733 100755 --- a/testing/scripts/run_telemetry_as_googletest.py +++ b/testing/scripts/run_telemetry_as_googletest.py
@@ -23,10 +23,7 @@ import os import sys -# Add src/testing/ into sys.path for importing common without pylint errors. -sys.path.append( - os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir))) -from scripts import common +import common class TelemetryUnittestAdapter(common.BaseIsolatedScriptArgsAdapter):
diff --git a/testing/scripts/run_variations_smoke_tests.py b/testing/scripts/run_variations_smoke_tests.py index 1bba02f..b681e54a 100755 --- a/testing/scripts/run_variations_smoke_tests.py +++ b/testing/scripts/run_variations_smoke_tests.py
@@ -21,12 +21,12 @@ from skia_gold_infra.finch_skia_gold_properties import FinchSkiaGoldProperties from skia_gold_infra import finch_skia_gold_utils +import common import variations_seed_access_helper as seed_helper _THIS_DIR = os.path.abspath(os.path.dirname(__file__)) _VARIATIONS_TEST_DATA = 'variations_smoke_test_data' -from . import common from selenium import webdriver from selenium.webdriver import ChromeOptions from selenium.common.exceptions import NoSuchElementException @@ -84,7 +84,7 @@ 'Windows (win32 or cygwin) are supported' % sys.platform) -def _find_chrome_binary(): #pylint: disable=inconsistent-return-statements +def _find_chrome_binary(): """Finds and returns the relative path to the Chrome binary. This function assumes that the CWD is the build directory. @@ -95,11 +95,11 @@ platform = _get_platform() if platform == 'linux': return os.path.join('.', 'chrome') - if platform == 'mac': + elif platform == 'mac': chrome_name = 'Google Chrome' return os.path.join('.', chrome_name + '.app', 'Contents', 'MacOS', chrome_name) - if platform == 'win': + elif platform == 'win': return os.path.join('.', 'chrome.exe')
diff --git a/testing/scripts/run_wpt_tests.py b/testing/scripts/run_wpt_tests.py index 2e7c0ff..82bc4b0cc 100755 --- a/testing/scripts/run_wpt_tests.py +++ b/testing/scripts/run_wpt_tests.py
@@ -12,13 +12,9 @@ import os import sys +import common import wpt_common -# Add src/testing/ into sys.path for importing common without pylint errors. -sys.path.append( - os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir))) -from scripts import common - logger = logging.getLogger(__name__) SRC_DIR = os.path.abspath( @@ -58,7 +54,6 @@ _ANDROID_ENABLED = False -# pylint: disable=super-with-arguments def _make_pass_through_action(dest, map_arg=lambda arg: arg): class PassThroughAction(argparse.Action): def __init__(self, option_strings, dest, nargs=None, **kwargs): @@ -179,7 +174,7 @@ def log_level(self): if self.options.verbose >= 2: return logging.DEBUG - if self.options.verbose >= 1: + elif self.options.verbose >= 1: return logging.INFO return logging.WARNING @@ -345,26 +340,26 @@ 'Options for configuring Android devices and tooling.') add_emulator_args(group) group.add_argument( - '--apk', + '--browser-apk', # Aliases for backwards compatibility. '--chrome-apk', - '--weblayer-support', - action='append', - default=[], - help='Path to an APK to install.') - group.add_argument( - '--shell-apk', - # Aliases for backwards compatibility. '--system-webview-shell', '--weblayer-shell', - help=('Path to a shell APK to install. ' - '(WebView and WebLayer only. ' + help=('Path to the browser APK to install and run. ' + '(For WebView and WebLayer, this value is the shell. ' 'Defaults to an on-device APK if not provided.)')) group.add_argument( '--webview-provider', help=('Path to a WebView provider APK to install. ' '(WebView only.)')) group.add_argument( + '--additional-apk', + # Aliases for backwards compatibility. + '--weblayer-support', + action='append', + default=[], + help='Paths to additional APKs to install.') + group.add_argument( '--release-channel', help='Install WebView from release channel. (WebView only.)') group.add_argument( @@ -436,7 +431,7 @@ def wpt_args(self): """list[str]: Arguments to add to a 'wpt run' command.""" args = [] - version = self.get_version() # pylint: disable=assignment-from-none + version = self.get_version() if version: args.append('--browser-version=%s' % version) webdriver = self.webdriver_binary @@ -617,7 +612,12 @@ See Also: https://github.com/web-platform-tests/wpt/blob/merge_pr_33203/tools/wpt/browser.py#L867-L924 """ - return self._options.package_name + if self._options.package_name: + return self._options.package_name + if self._options.browser_apk: + with contextlib.suppress(apk_helper.ApkHelperError): + return apk_helper.GetPackageName(self._options.browser_apk) + return None def get_version_provider_package_name(self): """Get the name of the package containing the product version. @@ -639,7 +639,10 @@ def provision_device(self, device): """Provision an Android device for a test.""" - for apk in self._options.apk: + if self._options.browser_apk: + self._tasks.enter_context( + _install_apk(device, self._options.browser_apk)) + for apk in self._options.additional_apk: self._tasks.enter_context(_install_apk(device, apk)) logger.info('Provisioned device (serial: %s)', device.serial) @@ -663,25 +666,7 @@ yield -class ChromeAndroidShellBase(ChromeAndroidBase): - def get_browser_package_name(self): - package_name = super(ChromeAndroidShellBase, - self).get_browser_package_name() - if package_name: - return package_name - if self._options.shell_apk: - with contextlib.suppress(apk_helper.ApkHelperError): - return apk_helper.GetPackageName(self._options.shell_apk) - return None - - def provision_device(self, device): - if self._options.shell_apk: - self._tasks.enter_context(_install_apk(device, - self._options.shell_apk)) - super(ChromeAndroidShellBase, self).provision_device(device) - - -class WebLayer(ChromeAndroidShellBase): +class WebLayer(ChromeAndroidBase): name = ANDROID_WEBLAYER aliases = ['weblayer'] @@ -696,14 +681,14 @@ or 'org.chromium.weblayer.shell') def get_version_provider_package_name(self): - # Read version from support APK. - if self._options.apk: + if self._options.additional_apk: + support_apk = self._options.additional_apk[0] with contextlib.suppress(apk_helper.ApkHelperError): - return apk_helper.GetPackageName(self._options.apk[0]) + return apk_helper.GetPackageName(support_apk) return super(WebLayer, self).get_version_provider_package_name() -class WebView(ChromeAndroidShellBase): +class WebView(ChromeAndroidBase): name = ANDROID_WEBVIEW aliases = ['webview'] @@ -713,11 +698,12 @@ return webview_app.UseWebViewProvider( device, self._options.webview_provider) - assert self._options.release_channel, 'no webview install method' - return _install_webview_from_release( - device, - self._options.release_channel, - self._python_executable) + else: + assert self._options.release_channel, 'no webview install method' + return _install_webview_from_release( + device, + self._options.release_channel, + self._python_executable) def _validate_options(self): super(WebView, self)._validate_options() @@ -751,20 +737,11 @@ def _validate_options(self): super(ChromeAndroid, self)._validate_options() - if not self._options.package_name and not self._options.apk: + if not self._options.package_name and not self._options.browser_apk: raise ValueError( - "Must provide either '--package-name' or '--apk' " + "Must provide either '--package-name' or '--browser-apk' " 'for %r.' % self.name) - def get_browser_package_name(self): - package_name = super(ChromeAndroid, self).get_browser_package_name() - if package_name: - return package_name - if self._options.apk: - with contextlib.suppress(apk_helper.ApkHelperError): - return apk_helper.GetPackageName(self._options.apk[0]) - return None - def add_emulator_args(parser): parser.add_argument(
diff --git a/testing/scripts/rust/rust_main_program.py b/testing/scripts/rust/rust_main_program.py index a1f95202..080dd2b 100644 --- a/testing/scripts/rust/rust_main_program.py +++ b/testing/scripts/rust/rust_main_program.py
@@ -11,7 +11,7 @@ import subprocess import sys -sys.path.append(os.path.dirname(os.path.abspath(__file__))) +sys.path.append(os.path.dirname(__file__)) import exe_util import main_program import test_results
diff --git a/testing/scripts/rust/test_filtering.py b/testing/scripts/rust/test_filtering.py index bc9c7eea..a386dd0 100644 --- a/testing/scripts/rust/test_filtering.py +++ b/testing/scripts/rust/test_filtering.py
@@ -56,7 +56,8 @@ """ if self._is_prefix_match: return test_name.startswith(self._filter_text) - return test_name == self._filter_text + else: + return test_name == self._filter_text def is_exclusion_filter(self): """Rreturns whether this filter excludes (rather than includes) matching
diff --git a/testing/scripts/skia_gold_infra/finch_skia_gold_utils.py b/testing/scripts/skia_gold_infra/finch_skia_gold_utils.py index 8d6d3d3..a6784bfb 100644 --- a/testing/scripts/skia_gold_infra/finch_skia_gold_utils.py +++ b/testing/scripts/skia_gold_infra/finch_skia_gold_utils.py
@@ -134,3 +134,4 @@ 'Given unhandled SkiaGoldSession StatusCode %s with error %s', status, error) return triage_link +
diff --git a/testing/scripts/test_buildbucket_api_gpu_use_cases.py b/testing/scripts/test_buildbucket_api_gpu_use_cases.py index b4652a6c..af2b7f8 100755 --- a/testing/scripts/test_buildbucket_api_gpu_use_cases.py +++ b/testing/scripts/test_buildbucket_api_gpu_use_cases.py
@@ -10,15 +10,11 @@ import os import sys -# Add src/testing/ into sys.path for importing common without pylint errors. -sys.path.append( - os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir))) -from scripts import common +import common # Add src/content/test/gpu into sys.path for importing common. -sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), - os.path.pardir, os.path.pardir, 'content', - 'test', 'gpu'))) +sys.path.append(os.path.join(os.path.dirname(__file__), + '..', '..', 'content', 'test', 'gpu')) import gather_power_measurement_results import gather_swarming_json_results
diff --git a/testing/scripts/test_traffic_annotation_auditor.py b/testing/scripts/test_traffic_annotation_auditor.py index bcd0fb1..01f6399 100755 --- a/testing/scripts/test_traffic_annotation_auditor.py +++ b/testing/scripts/test_traffic_annotation_auditor.py
@@ -15,10 +15,7 @@ import tempfile import traceback -# Add src/testing/ into sys.path for importing common without pylint errors. -sys.path.append( - os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir))) -from scripts import common +import common WINDOWS_SHEET_CONFIG = { "spreadsheet_id": "1TmBr9jnf1-hrjntiVBzT9EtkINGrtoBYFMWad2MBeaY",
diff --git a/testing/scripts/wpt_common.py b/testing/scripts/wpt_common.py index 33cb0c3..4a86345 100644 --- a/testing/scripts/wpt_common.py +++ b/testing/scripts/wpt_common.py
@@ -8,10 +8,7 @@ import os import sys -# Add src/testing/ into sys.path for importing common without pylint errors. -sys.path.append( - os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir))) -from scripts import common +import common BLINK_TOOLS_DIR = os.path.join(common.SRC_DIR, 'third_party', 'blink', 'tools') CATAPULT_DIR = os.path.join(common.SRC_DIR, 'third_party', 'catapult') @@ -33,7 +30,6 @@ logger = logging.getLogger(__name__) -# pylint: disable=super-with-arguments class BaseWptScriptAdapter(common.BaseIsolatedScriptArgsAdapter): """The base class for script adapters that use wptrunner to execute web platform tests. This contains any code shared between these scripts, such @@ -214,7 +210,6 @@ def generate_test_repeat_args(self, repeat_count): return ['--repeat=%d' % repeat_count] - # pylint: disable=unused-argument def generate_test_launcher_retry_limit_args(self, retry_limit): # TODO(crbug/1306222): wptrunner currently cannot rerun individual # failed tests, so this flag is accepted but not used.
diff --git a/testing/test_env.py b/testing/test_env.py index 43083fc..fa8df4c 100755 --- a/testing/test_env.py +++ b/testing/test_env.py
@@ -289,15 +289,13 @@ if p.poll() is not None: continue # SIGBREAK is defined only for win32. - # pylint: disable=no-member if sys.platform == 'win32' and sig == signal.SIGBREAK: p.send_signal(signal.CTRL_BREAK_EVENT) else: print("Forwarding signal(%d) to process %d" % (sig, p.pid)) p.send_signal(sig) - # pylint: enable=no-member if sys.platform == 'win32': - signal.signal(signal.SIGBREAK, _sig_handler) # pylint: disable=no-member + signal.signal(signal.SIGBREAK, _sig_handler) else: signal.signal(signal.SIGTERM, _sig_handler) signal.signal(signal.SIGINT, _sig_handler) @@ -351,13 +349,11 @@ if '--coverage-continuous-mode=1' in cmd: extra_env.update(get_coverage_continuous_mode_env(env)) - # pylint: disable=import-outside-toplevel if '--skip-set-lpac-acls=1' not in cmd and sys.platform == 'win32': sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), 'scripts')) - from scripts import common + import common common.set_lpac_acls(ROOT_DIR, is_test_script=True) - # pylint: enable=import-outside-toplevel cmd = trim_cmd(cmd) @@ -383,7 +379,7 @@ if stdoutfile: # Write to stdoutfile and poll to produce terminal output. return run_command_with_output(cmd, env=env, stdoutfile=stdoutfile) - if use_symbolization_script: + elif use_symbolization_script: # See above comment regarding offline symbolization. # Need to pipe to the symbolizer script. p1 = _popen(cmd, env=env, stdout=subprocess.PIPE, @@ -398,7 +394,8 @@ # Also feed the out-of-band JSON output to the symbolizer script. symbolize_snippets_in_json(cmd, env) return p1.returncode - return run_command(cmd, env=env, log=False) + else: + return run_command(cmd, env=env, log=False) except OSError: print('Failed to start %s' % cmd, file=sys.stderr) raise
diff --git a/testing/test_env_test_script.py b/testing/test_env_test_script.py index e318141..4957ee65 100755 --- a/testing/test_env_test_script.py +++ b/testing/test_env_test_script.py
@@ -19,5 +19,5 @@ signal.signal(signal.SIGTERM, print_signal) signal.signal(signal.SIGINT, print_signal) if sys.platform == 'win32': - signal.signal(signal.SIGBREAK, print_signal) # pylint: disable=no-member + signal.signal(signal.SIGBREAK, print_signal) time.sleep(2) # gives process time to receive signal.
diff --git a/testing/test_env_unittest.py b/testing/test_env_unittest.py index 8ec6194..707c65e 100755 --- a/testing/test_env_unittest.py +++ b/testing/test_env_unittest.py
@@ -20,8 +20,6 @@ HERE = os.path.dirname(os.path.abspath(__file__)) TEST_SCRIPT = os.path.join(HERE, 'test_env_user_script.py') -# pylint: disable=super-with-arguments - def launch_process_windows(args): # The `universal_newlines` option is equivalent to `text` in Python 3. @@ -44,13 +42,11 @@ universal_newlines=True) -# pylint: disable=inconsistent-return-statements def read_subprocess_message(proc, starts_with): """Finds the value after first line prefix condition.""" for line in proc.stdout: if line.startswith(starts_with): return line.rstrip().replace(starts_with, '') -# pylint: enable=inconsistent-return-statements def send_and_wait(proc, sig, sleep_time=0.3): @@ -69,9 +65,9 @@ def test_send_ctrl_break_event(self): proc = launch_process_windows([]) - send_and_wait(proc, signal.CTRL_BREAK_EVENT) # pylint: disable=no-member + send_and_wait(proc, signal.CTRL_BREAK_EVENT) sig = read_subprocess_message(proc, 'Signal :') - self.assertEqual(sig, str(int(signal.SIGBREAK))) # pylint: disable=no-member + self.assertEqual(sig, str(int(signal.SIGBREAK))) class SignalingNonWindowsTest(unittest.TestCase):
diff --git a/testing/unexpected_passes_common/unittest_utils.py b/testing/unexpected_passes_common/unittest_utils.py index bfc3b405..2df2f251 100644 --- a/testing/unexpected_passes_common/unittest_utils.py +++ b/testing/unexpected_passes_common/unittest_utils.py
@@ -141,15 +141,11 @@ class GenericBuilders(builders.Builders): - #pylint: disable=useless-super-delegation def __init__(self, include_internal_builders=False): super(GenericBuilders, self).__init__(include_internal_builders) - #pylint: enable=useless-super-delegation - #pylint: disable=unused-argument def _BuilderRunsTestOfInterest(self, test_map, suite): return True - #pylint: enable=unused-argument def GetIsolateNames(self): return {}
diff --git a/testing/variations/PRESUBMIT.py b/testing/variations/PRESUBMIT.py index fe53483..e854e162 100644 --- a/testing/variations/PRESUBMIT.py +++ b/testing/variations/PRESUBMIT.py
@@ -257,10 +257,10 @@ json_data, f.AbsoluteLocalPath(), output_api.PresubmitError) - if result: + if len(result): return result result = CheckPretty(contents, f.LocalPath(), output_api.PresubmitError) - if result: + if len(result): return result except ValueError: return [
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index f253e92..100274b 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -458,6 +458,45 @@ ] } ], + "ArcVmInitThrottle2": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "throttle_to_70_percent", + "enable_features": [ + "CrOSLateBootArcVmInitial70Throttle" + ], + "disable_features": [ + "CrOSLateBootArcVmInitial30Throttle", + "CrOSLateBootArcVmInitial50Throttle" + ] + }, + { + "name": "throttle_to_50_percent", + "enable_features": [ + "CrOSLateBootArcVmInitial50Throttle" + ], + "disable_features": [ + "CrOSLateBootArcVmInitial30Throttle", + "CrOSLateBootArcVmInitial70Throttle" + ] + }, + { + "name": "throttle_to_30_percent", + "enable_features": [ + "CrOSLateBootArcVmInitial30Throttle" + ], + "disable_features": [ + "CrOSLateBootArcVmInitial50Throttle", + "CrOSLateBootArcVmInitial70Throttle" + ] + } + ] + } + ], "ArcVmMemorySize": [ { "platforms": [
diff --git a/testing/xvfb.py b/testing/xvfb.py index a301e55a..c1f5f76 100755 --- a/testing/xvfb.py +++ b/testing/xvfb.py
@@ -23,15 +23,15 @@ import test_env -# pylint: disable=useless-object-inheritance - class _XvfbProcessError(Exception): """Exception raised when Xvfb cannot start.""" + pass class _WestonProcessError(Exception): """Exception raised when Weston cannot start.""" + pass def kill(proc, name, timeout_in_seconds=10): @@ -54,7 +54,7 @@ file=sys.stderr) -def launch_dbus(env): # pylint: disable=inconsistent-return-statements +def launch_dbus(env): """Starts a DBus session. Works around a bug in GLib where it performs operations which aren't @@ -136,9 +136,10 @@ if sys.platform.startswith('linux') and use_xvfb: return _run_with_xvfb(cmd, env, stdoutfile, use_openbox, use_xcompmgr) - if use_weston: + elif use_weston: return _run_with_weston(cmd, env, stdoutfile) - return test_env.run_executable(cmd, env, stdoutfile) + else: + return test_env.run_executable(cmd, env, stdoutfile) def _run_with_xvfb(cmd, env, stdoutfile, use_openbox, use_xcompmgr):
diff --git a/testing/xvfb_unittest.py b/testing/xvfb_unittest.py index 47b78f8..f28b6d2 100755 --- a/testing/xvfb_unittest.py +++ b/testing/xvfb_unittest.py
@@ -16,8 +16,6 @@ import time import unittest -# pylint: disable=super-with-arguments - TEST_FILE = __file__.replace('.pyc', '.py') XVFB = TEST_FILE.replace('_unittest', '') @@ -31,13 +29,11 @@ stderr=subprocess.STDOUT, env=os.environ.copy()) -# pylint: disable=inconsistent-return-statements def read_subprocess_message(proc, starts_with): """Finds the value after first line prefix condition.""" - for line in proc.stdout.read().decode('utf-8').splitlines(True): + for line in proc.stdout: if line.startswith(starts_with): return line.rstrip().replace(starts_with, '') -# pylint: enable=inconsistent-return-statements def send_signal(proc, sig, sleep_time=0.3): @@ -51,7 +47,7 @@ def setUp(self): super(XvfbLinuxTest, self).setUp() - if sys.platform != 'linux': + if sys.platform != 'linux2': self.skipTest('linux only test') def test_no_xvfb_display(self): @@ -96,13 +92,13 @@ proc = launch_process(['--sleep']) send_signal(proc, signal.SIGINT, 1) sig = read_subprocess_message(proc, 'Signal :') - self.assertEqual(int(sig), int(signal.SIGINT)) + self.assertEqual(sig, str(signal.SIGINT)) def test_send_sigterm(self): proc = launch_process(['--sleep']) send_signal(proc, signal.SIGTERM, 1) sig = read_subprocess_message(proc, 'Signal :') - self.assertEqual(int(sig), int(signal.SIGTERM)) + self.assertEqual(sig, str(signal.SIGTERM)) if __name__ == '__main__': unittest.main()
diff --git a/third_party/android_deps/BUILD.gn b/third_party/android_deps/BUILD.gn index b45bdcd..855fbb3a 100644 --- a/third_party/android_deps/BUILD.gn +++ b/third_party/android_deps/BUILD.gn
@@ -6,40 +6,6 @@ # Library groups if (!limit_android_deps) { - java_group("android_support_v4_java") { - deps = [ - "//third_party/androidx:androidx_core_core_java", - "//third_party/androidx:androidx_drawerlayout_drawerlayout_java", - "//third_party/androidx:androidx_fragment_fragment_java", - "//third_party/androidx:androidx_interpolator_interpolator_java", - "//third_party/androidx:androidx_lifecycle_lifecycle_common_java", - "//third_party/androidx:androidx_lifecycle_lifecycle_viewmodel_java", - "//third_party/androidx:androidx_media_media_java", - "//third_party/androidx:androidx_recyclerview_recyclerview_java", - ] - - # TODO(crbug.com/1315379): Remove this dep when inlined in chromecast - # internal code. - visibility = [ "//chromecast/*" ] - } - - java_group("android_support_v7_appcompat_java") { - deps = [ - "//third_party/androidx:androidx_appcompat_appcompat_java", - "//third_party/androidx:androidx_appcompat_appcompat_resources_java", - "//third_party/androidx:androidx_core_core_java", - "//third_party/androidx:androidx_drawerlayout_drawerlayout_java", - "//third_party/androidx:androidx_fragment_fragment_java", - "//third_party/androidx:androidx_interpolator_interpolator_java", - "//third_party/androidx:androidx_lifecycle_lifecycle_common_java", - "//third_party/androidx:androidx_lifecycle_lifecycle_viewmodel_java", - "//third_party/androidx:androidx_media_media_java", - "//third_party/androidx:androidx_recyclerview_recyclerview_java", - "//third_party/androidx:androidx_vectordrawable_vectordrawable_animated_java", - "//third_party/androidx:androidx_vectordrawable_vectordrawable_java", - ] - } - java_group("dagger_java") { deps = [ dagger_java_target ] }
diff --git a/third_party/android_media/BUILD.gn b/third_party/android_media/BUILD.gn index d8326b63..6ccaba9 100644 --- a/third_party/android_media/BUILD.gn +++ b/third_party/android_media/BUILD.gn
@@ -11,10 +11,7 @@ "java/res/layout/media_controller.xml", "java/res/values/colors.xml", ] - deps = [ - "//third_party/android_deps:android_support_v7_appcompat_java", - "//third_party/androidx:androidx_mediarouter_mediarouter_java", - ] + deps = [ "//third_party/androidx:androidx_mediarouter_mediarouter_java" ] } android_library("android_media_java") { @@ -23,7 +20,7 @@ [ "java/src/org/chromium/third_party/android/media/MediaController.java" ] deps = [ ":android_media_resources", - "//third_party/android_deps:android_support_v7_appcompat_java", + "//third_party/androidx:androidx_media_media_java", "//third_party/androidx:androidx_mediarouter_mediarouter_java", ] }
diff --git a/third_party/blink/public/mojom/web_feature/web_feature.mojom b/third_party/blink/public/mojom/web_feature/web_feature.mojom index 224cdcd..ac714ce 100644 --- a/third_party/blink/public/mojom/web_feature/web_feature.mojom +++ b/third_party/blink/public/mojom/web_feature/web_feature.mojom
@@ -2698,7 +2698,7 @@ kDOMWindowOpenPositioningFeaturesCrossScreen = 3392, kDOMWindowSetWindowRectCrossScreen = 3393, kFullscreenCrossScreen = 3394, - kBatterySavingsMeta = 3395, + kOBSOLETE_BatterySavingsMeta = 3395, kDigitalGoodsGetDigitalGoodsService = 3396, kDigitalGoodsGetDetails = 3397, kDigitalGoodsAcknowledge = 3398,
diff --git a/third_party/blink/public/web/web_document_loader.h b/third_party/blink/public/web/web_document_loader.h index 32a7dd0..73addd8 100644 --- a/third_party/blink/public/web/web_document_loader.h +++ b/third_party/blink/public/web/web_document_loader.h
@@ -77,12 +77,12 @@ virtual WebString Referrer() const = 0; // Returns the response associated with this datasource. - virtual const WebURLResponse& GetResponse() const = 0; + virtual const WebURLResponse& GetWebResponse() const = 0; // When this datasource was created as a result of WebFrame::loadData, // there may be an associated unreachableURL. virtual bool HasUnreachableURL() const = 0; - virtual WebURL UnreachableURL() const = 0; + virtual WebURL UnreachableWebURL() const = 0; // Returns whether the navigation associated with this datasource is a // client redirect.
diff --git a/third_party/blink/renderer/core/css/remote_font_face_source.cc b/third_party/blink/renderer/core/css/remote_font_face_source.cc index 1d2f960..c162b1f 100644 --- a/third_party/blink/renderer/core/css/remote_font_face_source.cc +++ b/third_party/blink/renderer/core/css/remote_font_face_source.cc
@@ -16,6 +16,7 @@ #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/inspector/console_message.h" +#include "third_party/blink/renderer/core/loader/subresource_integrity_helper.h" #include "third_party/blink/renderer/core/probe/core_probes.h" #include "third_party/blink/renderer/core/workers/worker_global_scope.h" #include "third_party/blink/renderer/platform/fonts/font_cache.h" @@ -184,7 +185,27 @@ auto* font = To<FontResource>(resource); histograms_.RecordRemoteFont(font); - custom_font_data_ = font->GetCustomFontData(); + // Refer to the comments in classic_pending_script.cc for the reason why + // SRI checks should be done here in ResourceClient instead of + // ResourceFetcher. SRI failure should behave as network error + // (ErrorOccurred()). PreloadCache even caches network errors. + // Font fetch itself doesn't support SRI but font preload does. + // So, if the resource was preloaded we need to check + // SRI failure and simulate network error if it happens. + + if (resource->IsLinkPreload()) { + SubresourceIntegrityHelper::DoReport(*execution_context, + resource->IntegrityReportInfo()); + } + + DCHECK(!custom_font_data_); + // font->GetCustomFontData() returns nullptr if network error happened + // (ErrorOccurred() is true). To simulate network error we don't update + // custom_font_data_ to keep the nullptr value in case of SRI failures. + if (!resource->IsLinkPreload() || resource->IntegrityDisposition() != + ResourceIntegrityDisposition::kFailed) { + custom_font_data_ = font->GetCustomFontData(); + } url_ = resource->Url().GetString(); // FIXME: Provide more useful message such as OTS rejection reason. @@ -221,12 +242,9 @@ if (face_->FontLoaded(this)) { font_selector_->FontFaceInvalidated( FontInvalidationReason::kFontFaceLoaded); - - const scoped_refptr<FontCustomPlatformData> customFontData = - font->GetCustomFontData(); - if (customFontData) { + if (custom_font_data_) { probe::FontsUpdated(execution_context, face_->GetFontFace(), - resource->Url().GetString(), customFontData.get()); + resource->Url().GetString(), custom_font_data_.get()); } } }
diff --git a/third_party/blink/renderer/core/css/style_element.cc b/third_party/blink/renderer/core/css/style_element.cc index 17eaf63..a367ffda 100644 --- a/third_party/blink/renderer/core/css/style_element.cc +++ b/third_party/blink/renderer/core/css/style_element.cc
@@ -120,7 +120,7 @@ if (sheet_->IsLoading()) { DCHECK(IsSameObject(owner_element)); if (pending_sheet_type_ != PendingSheetType::kNonBlocking) { - owner_element.GetDocument().GetStyleEngine().RemovePendingSheet( + owner_element.GetDocument().GetStyleEngine().RemovePendingBlockingSheet( owner_element, pending_sheet_type_); } pending_sheet_type_ = PendingSheetType::kNone; @@ -211,8 +211,8 @@ DCHECK(IsSameObject(*sheet_->ownerNode())); if (pending_sheet_type_ != PendingSheetType::kNonBlocking) { - document.GetStyleEngine().RemovePendingSheet(*sheet_->ownerNode(), - pending_sheet_type_); + document.GetStyleEngine().RemovePendingBlockingSheet(*sheet_->ownerNode(), + pending_sheet_type_); } pending_sheet_type_ = PendingSheetType::kNone; return true; @@ -222,7 +222,8 @@ DCHECK(IsSameObject(element)); DCHECK_LT(pending_sheet_type_, PendingSheetType::kBlocking); pending_sheet_type_ = PendingSheetType::kBlocking; - document.GetStyleEngine().AddPendingSheet(element, pending_sheet_type_); + document.GetStyleEngine().AddPendingBlockingSheet(element, + pending_sheet_type_); } void StyleElement::BlockingAttributeChanged(Element& element) { @@ -235,7 +236,7 @@ return; if (blocking() && blocking()->IsRenderBlocking()) return; - element.GetDocument().GetStyleEngine().RemovePendingSheet( + element.GetDocument().GetStyleEngine().RemovePendingBlockingSheet( element, pending_sheet_type_); pending_sheet_type_ = PendingSheetType::kNonBlocking; }
diff --git a/third_party/blink/renderer/core/css/style_engine.cc b/third_party/blink/renderer/core/css/style_engine.cc index fddb5554..8488715 100644 --- a/third_party/blink/renderer/core/css/style_engine.cc +++ b/third_party/blink/renderer/core/css/style_engine.cc
@@ -243,8 +243,8 @@ return *inspector_style_sheet_; } -void StyleEngine::AddPendingSheet(Node& style_sheet_candidate_node, - PendingSheetType type) { +void StyleEngine::AddPendingBlockingSheet(Node& style_sheet_candidate_node, + PendingSheetType type) { DCHECK(type == PendingSheetType::kBlocking || type == PendingSheetType::kDynamicRenderBlocking); @@ -268,8 +268,8 @@ } // This method is called whenever a top-level stylesheet has finished loading. -void StyleEngine::RemovePendingSheet(Node& style_sheet_candidate_node, - PendingSheetType type) { +void StyleEngine::RemovePendingBlockingSheet(Node& style_sheet_candidate_node, + PendingSheetType type) { DCHECK(type == PendingSheetType::kBlocking || type == PendingSheetType::kDynamicRenderBlocking); @@ -766,7 +766,7 @@ CSSStyleSheet* style_sheet = nullptr; if (type != PendingSheetType::kNonBlocking) - AddPendingSheet(element, type); + AddPendingBlockingSheet(element, type); AtomicString text_content(text);
diff --git a/third_party/blink/renderer/core/css/style_engine.h b/third_party/blink/renderer/core/css/style_engine.h index f2cc341..95705bd 100644 --- a/third_party/blink/renderer/core/css/style_engine.h +++ b/third_party/blink/renderer/core/css/style_engine.h
@@ -246,10 +246,10 @@ void SetPreferredStylesheetSetNameIfNotSet(const String&); void SetHttpDefaultStyle(const String&); - // TODO(xiaochengh): Rename them to Add/RemovePendingBlockingSheet. - void AddPendingSheet(Node& style_sheet_candidate_node, PendingSheetType type); - void RemovePendingSheet(Node& style_sheet_candidate_node, - PendingSheetType type); + void AddPendingBlockingSheet(Node& style_sheet_candidate_node, + PendingSheetType type); + void RemovePendingBlockingSheet(Node& style_sheet_candidate_node, + PendingSheetType type); bool HasPendingScriptBlockingSheets() const { return pending_script_blocking_stylesheets_ > 0;
diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc index 0313b01b..9ef772e 100644 --- a/third_party/blink/renderer/core/dom/document.cc +++ b/third_party/blink/renderer/core/dom/document.cc
@@ -195,7 +195,6 @@ #include "third_party/blink/renderer/core/frame/settings.h" #include "third_party/blink/renderer/core/frame/viewport_data.h" #include "third_party/blink/renderer/core/frame/visual_viewport.h" -#include "third_party/blink/renderer/core/html/battery_savings.h" #include "third_party/blink/renderer/core/html/canvas/canvas_font_cache.h" #include "third_party/blink/renderer/core/html/canvas/canvas_rendering_context.h" #include "third_party/blink/renderer/core/html/canvas/html_canvas_element.h" @@ -6881,34 +6880,6 @@ GetStyleEngine().SetPageColorSchemes(color_scheme); } -void Document::BatterySavingsMetaChanged() { - if (!RuntimeEnabledFeatures::BatterySavingsMetaEnabled(GetExecutionContext())) - return; - - if (!IsInOutermostMainFrame()) - return; - - UseCounter::Count(GetExecutionContext(), WebFeature::kBatterySavingsMeta); - auto* root_element = documentElement(); - if (!root_element) - return; - - BatterySavingsFlags savings = 0; - for (HTMLMetaElement& meta_element : - Traversal<HTMLMetaElement>::DescendantsOf(*root_element)) { - if (EqualIgnoringASCIICase(meta_element.GetName(), "battery-savings")) { - SpaceSplitString split_content( - AtomicString(meta_element.Content().GetString().LowerASCII())); - if (split_content.Contains("allow-reduced-framerate")) - savings |= kAllowReducedFrameRate; - if (split_content.Contains("allow-reduced-script-speed")) - savings |= kAllowReducedScriptSpeed; - break; - } - } - GetPage()->GetChromeClient().BatterySavingsChanged(*GetFrame(), savings); -} - void Document::SupportsReducedMotionMetaChanged() { if (!IsInOutermostMainFrame()) return;
diff --git a/third_party/blink/renderer/core/dom/document.h b/third_party/blink/renderer/core/dom/document.h index 16aae322..ad02450 100644 --- a/third_party/blink/renderer/core/dom/document.h +++ b/third_party/blink/renderer/core/dom/document.h
@@ -1718,10 +1718,6 @@ // Update the presentation level color-scheme property for the root element. void ColorSchemeMetaChanged(); - // A META element with name=battery-savings was added, removed, or modified. - // Re-collect the META values that apply and pass to LayerTreeHost. - void BatterySavingsMetaChanged(); - // A META element with name=supports-reduced-motion was added, removed, or // modified. Re-collect the META values. void SupportsReducedMotionMetaChanged();
diff --git a/third_party/blink/renderer/core/dom/document_test.cc b/third_party/blink/renderer/core/dom/document_test.cc index 1ce49f93..9533b2d7 100644 --- a/third_party/blink/renderer/core/dom/document_test.cc +++ b/third_party/blink/renderer/core/dom/document_test.cc
@@ -73,7 +73,6 @@ #include "third_party/blink/renderer/core/html/html_link_element.h" #include "third_party/blink/renderer/core/layout/layout_box.h" #include "third_party/blink/renderer/core/loader/document_loader.h" -#include "third_party/blink/renderer/core/loader/empty_clients.h" #include "third_party/blink/renderer/core/page/page.h" #include "third_party/blink/renderer/core/page/validation_message_client.h" #include "third_party/blink/renderer/core/testing/color_scheme_helper.h" @@ -1372,72 +1371,6 @@ ViewportTestCase("cover", mojom::ViewportFit::kCover), ViewportTestCase("invalid", mojom::ViewportFit::kAuto))); -class BatterySavingsChromeClient : public EmptyChromeClient { - public: - MOCK_METHOD2(BatterySavingsChanged, void(LocalFrame&, BatterySavingsFlags)); -}; - -class DocumentBatterySavingsTest : public PageTestBase, - private ScopedBatterySavingsMetaForTest { - protected: - DocumentBatterySavingsTest() : ScopedBatterySavingsMetaForTest(true) {} - - void SetUp() override { - chrome_client_ = MakeGarbageCollected<BatterySavingsChromeClient>(); - SetupPageWithClients(chrome_client_); - } - - Persistent<BatterySavingsChromeClient> chrome_client_; -}; - -TEST_F(DocumentBatterySavingsTest, ChromeClientCalls) { - testing::InSequence s; - // The client is called twice, once for each meta element, but is called with - // the same parameter both times because the first meta in DOM order takes - // precedence. - EXPECT_CALL(*chrome_client_, - BatterySavingsChanged(testing::_, kAllowReducedFrameRate)) - .Times(2); - - EXPECT_FALSE(GetDocument().Loader()->GetUseCounter().IsCounted( - WebFeature::kBatterySavingsMeta)); - - SetHtmlInnerHTML(R"HTML( - <meta id="first" name="battery-savings" content="allow-reduced-framerate"> - <meta id="second" name="battery-savings" content="allow-reduced-script-speed"> - )HTML"); - - EXPECT_TRUE(GetDocument().Loader()->GetUseCounter().IsCounted( - WebFeature::kBatterySavingsMeta)); - - // Remove the first meta causing the second to apply. - EXPECT_CALL(*chrome_client_, - BatterySavingsChanged(testing::_, kAllowReducedScriptSpeed)) - .Times(1); - - GetDocument().getElementById("first")->remove(); - - // Change the content attribute to an unsupported value. - EXPECT_CALL(*chrome_client_, BatterySavingsChanged(testing::_, 0)).Times(1); - - Element* second = GetDocument().getElementById("second"); - second->setAttribute(html_names::kContentAttr, "allow-blah"); - - // Change the content attribute to both supported values. - EXPECT_CALL(*chrome_client_, - BatterySavingsChanged(testing::_, kAllowReducedFrameRate | - kAllowReducedScriptSpeed)) - .Times(1); - - second->setAttribute(html_names::kContentAttr, - "allow-reduced-framerate allow-reduced-script-speed"); - - // Change the meta name to "viewport". - EXPECT_CALL(*chrome_client_, BatterySavingsChanged(testing::_, 0)).Times(1); - - second->setAttribute(html_names::kNameAttr, "viewport"); -} - namespace { class MockReportingContext final : public ReportingContext { public:
diff --git a/third_party/blink/renderer/core/dom/processing_instruction.cc b/third_party/blink/renderer/core/dom/processing_instruction.cc index 6a026f9..b595e29 100644 --- a/third_party/blink/renderer/core/dom/processing_instruction.cc +++ b/third_party/blink/renderer/core/dom/processing_instruction.cc
@@ -170,8 +170,8 @@ } else { params.SetCharset(charset.IsEmpty() ? GetDocument().Encoding() : WTF::TextEncoding(charset)); - GetDocument().GetStyleEngine().AddPendingSheet(*this, - PendingSheetType::kBlocking); + GetDocument().GetStyleEngine().AddPendingBlockingSheet( + *this, PendingSheetType::kBlocking); CSSStyleSheetResource::Fetch(params, GetDocument().Fetcher(), this); } } @@ -297,7 +297,7 @@ void ProcessingInstruction::RemovePendingSheet() { if (is_xsl_) return; - GetDocument().GetStyleEngine().RemovePendingSheet( + GetDocument().GetStyleEngine().RemovePendingBlockingSheet( *this, PendingSheetType::kBlocking); }
diff --git a/third_party/blink/renderer/core/exported/BUILD.gn b/third_party/blink/renderer/core/exported/BUILD.gn index eeb0726..fc55b0d 100644 --- a/third_party/blink/renderer/core/exported/BUILD.gn +++ b/third_party/blink/renderer/core/exported/BUILD.gn
@@ -29,8 +29,6 @@ "web_dev_tools_agent_impl.cc", "web_dev_tools_agent_impl.h", "web_document.cc", - "web_document_loader_impl.cc", - "web_document_loader_impl.h", "web_dom_activity_logger.cc", "web_dom_event.cc", "web_dom_message_event.cc",
diff --git a/third_party/blink/renderer/core/exported/web_document_loader_impl.cc b/third_party/blink/renderer/core/exported/web_document_loader_impl.cc deleted file mode 100644 index ee569d1..0000000 --- a/third_party/blink/renderer/core/exported/web_document_loader_impl.cc +++ /dev/null
@@ -1,199 +0,0 @@ -/* - * Copyright (C) 2009 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "third_party/blink/renderer/core/exported/web_document_loader_impl.h" - -#include <memory> -#include <utility> - -#include "base/memory/ptr_util.h" -#include "third_party/blink/public/common/features.h" -#include "third_party/blink/public/mojom/loader/mhtml_load_result.mojom-blink.h" -#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_network_provider.h" -#include "third_party/blink/public/platform/web_document_subresource_filter.h" -#include "third_party/blink/public/platform/web_url.h" -#include "third_party/blink/public/platform/web_url_error.h" -#include "third_party/blink/public/platform/web_vector.h" -#include "third_party/blink/renderer/core/frame/local_dom_window.h" -#include "third_party/blink/renderer/core/frame/local_frame.h" -#include "third_party/blink/renderer/core/loader/subresource_filter.h" -#include "third_party/blink/renderer/platform/heap/garbage_collected.h" -#include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h" -#include "third_party/blink/renderer/platform/mhtml/archive_resource.h" -#include "third_party/blink/renderer/platform/mhtml/mhtml_archive.h" - -namespace blink { - -// static -bool WebDocumentLoader::WillLoadUrlAsEmpty(const WebURL& url) { - return DocumentLoader::WillLoadUrlAsEmpty(url); -} - -WebString WebDocumentLoaderImpl::OriginalReferrer() const { - return DocumentLoader::OriginalReferrer(); -} - -WebURL WebDocumentLoaderImpl::GetUrl() const { - return DocumentLoader::Url(); -} - -WebString WebDocumentLoaderImpl::HttpMethod() const { - return DocumentLoader::HttpMethod(); -} - -WebString WebDocumentLoaderImpl::Referrer() const { - return DocumentLoader::GetReferrer(); -} - -const WebURLResponse& WebDocumentLoaderImpl::GetResponse() const { - return response_wrapper_; -} - -bool WebDocumentLoaderImpl::HasUnreachableURL() const { - return !DocumentLoader::UnreachableURL().IsEmpty(); -} - -WebURL WebDocumentLoaderImpl::UnreachableURL() const { - return DocumentLoader::UnreachableURL(); -} - -bool WebDocumentLoaderImpl::IsClientRedirect() const { - return DocumentLoader::IsClientRedirect(); -} - -bool WebDocumentLoaderImpl::ReplacesCurrentHistoryItem() const { - return DocumentLoader::ReplacesCurrentHistoryItem(); -} - -WebNavigationType WebDocumentLoaderImpl::GetNavigationType() const { - return DocumentLoader::GetNavigationType(); -} - -WebDocumentLoader::ExtraData* WebDocumentLoaderImpl::GetExtraData() const { - return extra_data_.get(); -} - -std::unique_ptr<WebDocumentLoader::ExtraData> -WebDocumentLoaderImpl::TakeExtraData() { - return std::move(extra_data_); -} - -void WebDocumentLoaderImpl::SetExtraData( - std::unique_ptr<ExtraData> extra_data) { - extra_data_ = std::move(extra_data); -} - -WebDocumentLoaderImpl::WebDocumentLoaderImpl( - LocalFrame* frame, - WebNavigationType navigation_type, - std::unique_ptr<WebNavigationParams> navigation_params, - std::unique_ptr<PolicyContainer> policy_container, - std::unique_ptr<ExtraData> extra_data) - : DocumentLoader(base::PassKey<WebDocumentLoaderImpl>(), - frame, - navigation_type, - std::move(navigation_params), - std::move(policy_container)), - response_wrapper_(DocumentLoader::GetResponse()), - extra_data_(std::move(extra_data)) {} - -WebDocumentLoaderImpl::~WebDocumentLoaderImpl() { - // Verify that detachFromFrame() has been called. - DCHECK(!extra_data_); -} - -void WebDocumentLoaderImpl::DetachFromFrame(bool flush_microtask_queue) { - DocumentLoader::DetachFromFrame(flush_microtask_queue); - extra_data_.reset(); -} - -void WebDocumentLoaderImpl::SetSubresourceFilter( - WebDocumentSubresourceFilter* subresource_filter) { - DocumentLoader::SetSubresourceFilter(MakeGarbageCollected<SubresourceFilter>( - GetFrame()->DomWindow(), base::WrapUnique(subresource_filter))); -} - -void WebDocumentLoaderImpl::SetServiceWorkerNetworkProvider( - std::unique_ptr<WebServiceWorkerNetworkProvider> provider) { - DocumentLoader::SetServiceWorkerNetworkProvider(std::move(provider)); -} - -WebServiceWorkerNetworkProvider* -WebDocumentLoaderImpl::GetServiceWorkerNetworkProvider() { - return DocumentLoader::GetServiceWorkerNetworkProvider(); -} - -void WebDocumentLoaderImpl::BlockParser() { - DocumentLoader::BlockParser(); -} - -void WebDocumentLoaderImpl::ResumeParser() { - DocumentLoader::ResumeParser(); -} - -bool WebDocumentLoaderImpl::HasBeenLoadedAsWebArchive() const { - return archive_; -} - -WebArchiveInfo WebDocumentLoaderImpl::GetArchiveInfo() const { - if (archive_ && - archive_->LoadResult() == mojom::blink::MHTMLLoadResult::kSuccess) { - return { - archive_->LoadResult(), - archive_->MainResource()->Url(), - archive_->Date(), - }; - } - - // TODO(arthursonzogni): Returning MHTMLLoadResult::kSuccess when there are no - // archive is very misleading. Consider adding a new enum value to - // discriminate success versus no archive. - return { - archive_ ? archive_->LoadResult() - : mojom::blink::MHTMLLoadResult::kSuccess, - WebURL(), - base::Time(), - }; -} - -bool WebDocumentLoaderImpl::LastNavigationHadTransientUserActivation() const { - return DocumentLoader::LastNavigationHadTransientUserActivation(); -} - -void WebDocumentLoaderImpl::SetCodeCacheHost( - mojo::PendingRemote<mojom::CodeCacheHost> code_cache_host) { - DocumentLoader::SetCodeCacheHost(std::move(code_cache_host)); -} - -void WebDocumentLoaderImpl::Trace(Visitor* visitor) const { - DocumentLoader::Trace(visitor); -} - -} // namespace blink
diff --git a/third_party/blink/renderer/core/exported/web_document_loader_impl.h b/third_party/blink/renderer/core/exported/web_document_loader_impl.h deleted file mode 100644 index 5328b03..0000000 --- a/third_party/blink/renderer/core/exported/web_document_loader_impl.h +++ /dev/null
@@ -1,105 +0,0 @@ -/* - * Copyright (C) 2009 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_EXPORTED_WEB_DOCUMENT_LOADER_IMPL_H_ -#define THIRD_PARTY_BLINK_RENDERER_CORE_EXPORTED_WEB_DOCUMENT_LOADER_IMPL_H_ - -#include <memory> -#include "third_party/blink/public/web/web_document_loader.h" -#include "third_party/blink/renderer/core/core_export.h" -#include "third_party/blink/renderer/core/frame/frame_types.h" -#include "third_party/blink/renderer/core/loader/document_loader.h" -#include "third_party/blink/renderer/platform/exported/wrapped_resource_request.h" -#include "third_party/blink/renderer/platform/exported/wrapped_resource_response.h" -#include "third_party/blink/renderer/platform/heap/garbage_collected.h" -#include "third_party/blink/renderer/platform/weborigin/kurl.h" -#include "third_party/blink/renderer/platform/wtf/vector.h" - -namespace blink { - -class PolicyContainer; - -// Extends blink::DocumentLoader to attach |extra_data_| to store data that can -// be set/get via the WebDocumentLoader interface. -class CORE_EXPORT WebDocumentLoaderImpl final : public DocumentLoader, - public WebDocumentLoader { - public: - WebDocumentLoaderImpl(LocalFrame*, - WebNavigationType navigation_type, - std::unique_ptr<WebNavigationParams> navigation_params, - std::unique_ptr<PolicyContainer> policy_container, - std::unique_ptr<ExtraData> extra_data); - ~WebDocumentLoaderImpl() override; - - static WebDocumentLoaderImpl* FromDocumentLoader(DocumentLoader* loader) { - return static_cast<WebDocumentLoaderImpl*>(loader); - } - - // WebDocumentLoader methods: - WebString OriginalReferrer() const override; - WebURL GetUrl() const override; - WebString HttpMethod() const override; - WebString Referrer() const override; - const WebURLResponse& GetResponse() const override; - bool HasUnreachableURL() const override; - WebURL UnreachableURL() const override; - bool IsClientRedirect() const override; - bool ReplacesCurrentHistoryItem() const override; - WebNavigationType GetNavigationType() const override; - ExtraData* GetExtraData() const override; - std::unique_ptr<ExtraData> TakeExtraData() override; - void SetExtraData(std::unique_ptr<ExtraData>) override; - void SetSubresourceFilter(WebDocumentSubresourceFilter*) override; - void SetServiceWorkerNetworkProvider( - std::unique_ptr<WebServiceWorkerNetworkProvider>) override; - WebServiceWorkerNetworkProvider* GetServiceWorkerNetworkProvider() override; - void BlockParser() override; - void ResumeParser() override; - bool HasBeenLoadedAsWebArchive() const override; - WebArchiveInfo GetArchiveInfo() const override; - bool LastNavigationHadTransientUserActivation() const override; - void SetCodeCacheHost( - mojo::PendingRemote<mojom::CodeCacheHost> code_cache_host) override; - - void Trace(Visitor*) const override; - - private: - void DetachFromFrame(bool flush_microtask_queue) override; - - // Mutable because the const getters will magically sync these to the - // latest version from WebKit. - mutable WrappedResourceResponse response_wrapper_; - - std::unique_ptr<ExtraData> extra_data_; -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_CORE_EXPORTED_WEB_DOCUMENT_LOADER_IMPL_H_
diff --git a/third_party/blink/renderer/core/exported/web_navigation_params.cc b/third_party/blink/renderer/core/exported/web_navigation_params.cc index c2839e3..4d2ef0f 100644 --- a/third_party/blink/renderer/core/exported/web_navigation_params.cc +++ b/third_party/blink/renderer/core/exported/web_navigation_params.cc
@@ -5,7 +5,6 @@ #include "third_party/blink/public/web/web_navigation_params.h" #include "third_party/blink/public/platform/modules/service_worker/web_service_worker_network_provider.h" -#include "third_party/blink/renderer/core/exported/web_document_loader_impl.h" #include "third_party/blink/renderer/platform/loader/static_data_navigation_body_loader.h" #include "third_party/blink/renderer/platform/network/encoded_form_data.h" #include "third_party/blink/renderer/platform/network/http_names.h"
diff --git a/third_party/blink/renderer/core/exported/web_plugin_container_impl.cc b/third_party/blink/renderer/core/exported/web_plugin_container_impl.cc index 27fbc0f8..ca58f631 100644 --- a/third_party/blink/renderer/core/exported/web_plugin_container_impl.cc +++ b/third_party/blink/renderer/core/exported/web_plugin_container_impl.cc
@@ -67,7 +67,6 @@ #include "third_party/blink/renderer/core/events/web_input_event_conversion.h" #include "third_party/blink/renderer/core/events/wheel_event.h" #include "third_party/blink/renderer/core/execution_context/execution_context.h" -#include "third_party/blink/renderer/core/exported/web_document_loader_impl.h" #include "third_party/blink/renderer/core/exported/web_view_impl.h" #include "third_party/blink/renderer/core/frame/csp/content_security_policy.h" #include "third_party/blink/renderer/core/frame/event_handler_registry.h"
diff --git a/third_party/blink/renderer/core/frame/attribution_src_loader.cc b/third_party/blink/renderer/core/frame/attribution_src_loader.cc index b8a6c6e..b12e5c0 100644 --- a/third_party/blink/renderer/core/frame/attribution_src_loader.cc +++ b/third_party/blink/renderer/core/frame/attribution_src_loader.cc
@@ -296,8 +296,8 @@ mojom::blink::PermissionsPolicyFeature::kAttributionReporting); if (!feature_policy_enabled) { - LogAuditIssue(AttributionReportingIssueType::kPermissionPolicyDisabled, "", - element, request_id); + LogAuditIssue(AttributionReportingIssueType::kPermissionPolicyDisabled, + /*string=*/absl::nullopt, element, request_id); return RegisterResult::kNotAllowed; } @@ -491,7 +491,7 @@ void AttributionSrcLoader::LogAuditIssue( AttributionReportingIssueType issue_type, - const String& string, + const absl::optional<String>& string, HTMLElement* element, const absl::optional<String>& request_id) { if (!local_frame_->IsAttached())
diff --git a/third_party/blink/renderer/core/frame/attribution_src_loader.h b/third_party/blink/renderer/core/frame/attribution_src_loader.h index 9ebfa448..36ee871 100644 --- a/third_party/blink/renderer/core/frame/attribution_src_loader.h +++ b/third_party/blink/renderer/core/frame/attribution_src_loader.h
@@ -102,7 +102,7 @@ RegisterResult& out_register_result); void LogAuditIssue(AttributionReportingIssueType issue_type, - const String& string, + const absl::optional<String>& string, HTMLElement* element, const absl::optional<String>& request_id);
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 f36d04f..8107267 100644 --- a/third_party/blink/renderer/core/frame/local_frame_client.h +++ b/third_party/blink/renderer/core/frame/local_frame_client.h
@@ -231,12 +231,7 @@ const Vector<String>& added_selectors, const Vector<String>& removed_selectors) = 0; - virtual DocumentLoader* CreateDocumentLoader( - LocalFrame*, - WebNavigationType, - std::unique_ptr<WebNavigationParams> navigation_params, - std::unique_ptr<PolicyContainer> policy_container, - std::unique_ptr<WebDocumentLoader::ExtraData> extra_data) = 0; + virtual void DidCreateDocumentLoader(DocumentLoader*) = 0; virtual String UserAgentOverride() = 0; virtual String UserAgent() = 0;
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 d10dce9f6..7727486 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
@@ -66,7 +66,6 @@ #include "third_party/blink/renderer/core/events/message_event.h" #include "third_party/blink/renderer/core/events/mouse_event.h" #include "third_party/blink/renderer/core/exported/web_dev_tools_agent_impl.h" -#include "third_party/blink/renderer/core/exported/web_document_loader_impl.h" #include "third_party/blink/renderer/core/exported/web_plugin_container_impl.h" #include "third_party/blink/renderer/core/exported/web_view_impl.h" #include "third_party/blink/renderer/core/fileapi/public_url_manager.h" @@ -188,8 +187,7 @@ void LocalFrameClientImpl::DidCommitDocumentReplacementNavigation( DocumentLoader* loader) { if (web_frame_->Client()) { - web_frame_->Client()->DidCommitDocumentReplacementNavigation( - WebDocumentLoaderImpl::FromDocumentLoader(loader)); + web_frame_->Client()->DidCommitDocumentReplacementNavigation(loader); } } @@ -770,20 +768,9 @@ } } -DocumentLoader* LocalFrameClientImpl::CreateDocumentLoader( - LocalFrame* frame, - WebNavigationType navigation_type, - std::unique_ptr<WebNavigationParams> navigation_params, - std::unique_ptr<PolicyContainer> policy_container, - std::unique_ptr<WebDocumentLoader::ExtraData> extra_data) { - DCHECK(frame); - WebDocumentLoaderImpl* document_loader = - MakeGarbageCollected<WebDocumentLoaderImpl>( - frame, navigation_type, std::move(navigation_params), - std::move(policy_container), std::move(extra_data)); - if (web_frame_->Client()) - web_frame_->Client()->DidCreateDocumentLoader(document_loader); - return document_loader; +void LocalFrameClientImpl::DidCreateDocumentLoader( + DocumentLoader* document_loader) { + web_frame_->Client()->DidCreateDocumentLoader(document_loader); } String LocalFrameClientImpl::UserAgentOverride() {
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 ac81fdc..200f0c5 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
@@ -158,16 +158,7 @@ void SelectorMatchChanged(const Vector<String>& added_selectors, const Vector<String>& removed_selectors) override; - // Creates a WebDocumentLoaderImpl that is a DocumentLoader but also has: - // - storage to store an extra data that can be used by the content layer - // - wrapper methods to expose DocumentLoader's variables to the content - // layer - DocumentLoader* CreateDocumentLoader( - LocalFrame*, - WebNavigationType, - std::unique_ptr<WebNavigationParams> navigation_params, - std::unique_ptr<PolicyContainer> policy_container, - std::unique_ptr<WebDocumentLoader::ExtraData> extra_data) override; + void DidCreateDocumentLoader(DocumentLoader*) override; String UserAgentOverride() override; WTF::String UserAgent() override;
diff --git a/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc b/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc index 9b586de..011b852 100644 --- a/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc +++ b/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc
@@ -86,7 +86,6 @@ #include "third_party/blink/renderer/core/frame/visual_viewport.h" #include "third_party/blink/renderer/core/frame/web_feature.h" #include "third_party/blink/renderer/core/frame/web_local_frame_impl.h" -#include "third_party/blink/renderer/core/html/battery_savings.h" #include "third_party/blink/renderer/core/html/fenced_frame/document_fenced_frames.h" #include "third_party/blink/renderer/core/html/fenced_frame/html_fenced_frame_element.h" #include "third_party/blink/renderer/core/html/html_frame_owner_element.h" @@ -3859,11 +3858,6 @@ } } -void WebFrameWidgetImpl::BatterySavingsChanged(BatterySavingsFlags savings) { - widget_base_->LayerTreeHost()->SetEnableFrameRateThrottling( - savings & kAllowReducedFrameRate); -} - const viz::LocalSurfaceId& WebFrameWidgetImpl::LocalSurfaceIdFromParent() { return widget_base_->local_surface_id_from_parent(); }
diff --git a/third_party/blink/renderer/core/frame/web_frame_widget_impl.h b/third_party/blink/renderer/core/frame/web_frame_widget_impl.h index 8e1d49e3..e06403f5 100644 --- a/third_party/blink/renderer/core/frame/web_frame_widget_impl.h +++ b/third_party/blink/renderer/core/frame/web_frame_widget_impl.h
@@ -56,7 +56,6 @@ #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/exported/web_page_popup_impl.h" #include "third_party/blink/renderer/core/frame/web_local_frame_impl.h" -#include "third_party/blink/renderer/core/html/battery_savings.h" #include "third_party/blink/renderer/core/page/event_with_hit_test_results.h" #include "third_party/blink/renderer/core/page/page_widget_delegate.h" #include "third_party/blink/renderer/core/page/viewport_description.h" @@ -569,10 +568,6 @@ void UpdateViewportDescription( const ViewportDescription& viewport_description); - // The value of the applied battery-savings META element in the document - // changed. - void BatterySavingsChanged(BatterySavingsFlags savings); - const viz::LocalSurfaceId& LocalSurfaceIdFromParent(); ScreenMetricsEmulator* DeviceEmulator();
diff --git a/third_party/blink/renderer/core/frame/web_local_frame_impl.cc b/third_party/blink/renderer/core/frame/web_local_frame_impl.cc index 7316260..a0c658da 100644 --- a/third_party/blink/renderer/core/frame/web_local_frame_impl.cc +++ b/third_party/blink/renderer/core/frame/web_local_frame_impl.cc
@@ -176,7 +176,6 @@ #include "third_party/blink/renderer/core/events/after_print_event.h" #include "third_party/blink/renderer/core/events/before_print_event.h" #include "third_party/blink/renderer/core/exported/web_dev_tools_agent_impl.h" -#include "third_party/blink/renderer/core/exported/web_document_loader_impl.h" #include "third_party/blink/renderer/core/exported/web_plugin_container_impl.h" #include "third_party/blink/renderer/core/exported/web_view_impl.h" #include "third_party/blink/renderer/core/frame/csp/content_security_policy.h" @@ -590,10 +589,6 @@ } }; -static WebDocumentLoader* DocumentLoaderForDocLoader(DocumentLoader* loader) { - return loader ? WebDocumentLoaderImpl::FromDocumentLoader(loader) : nullptr; -} - // WebFrame ------------------------------------------------------------------- static CreateWebFrameWidgetCallback* g_create_web_frame_widget = nullptr; @@ -1140,7 +1135,7 @@ WebDocumentLoader* WebLocalFrameImpl::GetDocumentLoader() const { DCHECK(GetFrame()); - return DocumentLoaderForDocLoader(GetFrame()->Loader().GetDocumentLoader()); + return GetFrame()->Loader().GetDocumentLoader(); } void WebLocalFrameImpl::EnableViewSourceMode(bool enable) {
diff --git a/third_party/blink/renderer/core/html/battery_savings.h b/third_party/blink/renderer/core/html/battery_savings.h deleted file mode 100644 index 5519b37..0000000 --- a/third_party/blink/renderer/core/html/battery_savings.h +++ /dev/null
@@ -1,24 +0,0 @@ -// 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. - -#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_HTML_BATTERY_SAVINGS_H_ -#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_BATTERY_SAVINGS_H_ - -namespace blink { - -// These are constants for the various keywords allowed for the battery-savings -// meta element. For instance: -// -// <meta name="battery-savings" content="allow-reduced-framerate"> -// These constants are bits which can be combined. -enum BatterySavings { - kAllowReducedFrameRate = 1 << 0, - kAllowReducedScriptSpeed = 1 << 1, -}; - -using BatterySavingsFlags = unsigned; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_BATTERY_SAVINGS_H_
diff --git a/third_party/blink/renderer/core/html/build.gni b/third_party/blink/renderer/core/html/build.gni index bf2f872..abd6f7f 100644 --- a/third_party/blink/renderer/core/html/build.gni +++ b/third_party/blink/renderer/core/html/build.gni
@@ -7,7 +7,6 @@ "anchor_element_metrics.h", "anchor_element_metrics_sender.cc", "anchor_element_metrics_sender.h", - "battery_savings.h", "blocking_attribute.cc", "blocking_attribute.h", "canvas/canvas_async_blob_creator.cc",
diff --git a/third_party/blink/renderer/core/html/html_dialog_element.cc b/third_party/blink/renderer/core/html/html_dialog_element.cc index 10e9dfa8..3b1ed08 100644 --- a/third_party/blink/renderer/core/html/html_dialog_element.cc +++ b/third_party/blink/renderer/core/html/html_dialog_element.cc
@@ -199,7 +199,8 @@ : dialog_(dialog) {} void Invoke(ExecutionContext*, Event* event) override { - DCHECK(dialog_); + if (!dialog_) + return; if (event->type() == event_type_names::kCancel) dialog_->CloseWatcherFiredCancel(); if (event->type() == event_type_names::kClose)
diff --git a/third_party/blink/renderer/core/html/html_frame_owner_element.cc b/third_party/blink/renderer/core/html/html_frame_owner_element.cc index 5a646f9..71bae267 100644 --- a/third_party/blink/renderer/core/html/html_frame_owner_element.cc +++ b/third_party/blink/renderer/core/html/html_frame_owner_element.cc
@@ -152,6 +152,29 @@ if (is_loading_attr_lazy) return true; + // When LazyAds and LazyEmbeds cause problems, the user might reload the page + // to fix the problem. Also, the user is likely to avoid reloading the page + // when they submit forms. So skips LazyEmbeds and LazyAds in the following + // conditions. + // - Reload a page. + // - Submit a form. + // - Resubmit a form. + // The reason why we use DocumentLoader::GetNavigationType() instead of + // DocumentLoader::LoadType() is that DocumentLoader::LoadType() is reset to + // WebFrameLoadType::kStandard on DidFinishNavigation(). When JavaScript adds + // iframes after navigation, DocumentLoader::LoadType() always returns + // WebFrameLoadType::kStandard. DocumentLoader::GetNavigationType() doesn't + // have this problem. + Document& top_document = document.TopDocument(); + WebNavigationType navigation_type = + top_document.Loader() ? top_document.Loader()->GetNavigationType() + : WebNavigationType::kWebNavigationTypeOther; + if (navigation_type == WebNavigationType::kWebNavigationTypeReload || + navigation_type == WebNavigationType::kWebNavigationTypeFormSubmitted || + navigation_type == WebNavigationType::kWebNavigationTypeFormResubmitted) { + return false; + } + if (record_uma) { base::UmaHistogramEnumeration( "Blink.AutomaticLazyLoadFrame",
diff --git a/third_party/blink/renderer/core/html/html_meta_element.cc b/third_party/blink/renderer/core/html/html_meta_element.cc index e6d5585..1aae2c0 100644 --- a/third_party/blink/renderer/core/html/html_meta_element.cc +++ b/third_party/blink/renderer/core/html/html_meta_element.cc
@@ -496,8 +496,6 @@ /*update_theme_color_cache=*/true); } else if (EqualIgnoringASCIICase(name_value, "color-scheme")) { GetDocument().ColorSchemeMetaChanged(); - } else if (EqualIgnoringASCIICase(name_value, "battery-savings")) { - GetDocument().BatterySavingsMetaChanged(); } else if (EqualIgnoringASCIICase(name_value, "supports-reduced-motion")) { GetDocument().SupportsReducedMotionMetaChanged(); } @@ -584,10 +582,6 @@ GetDocument().ColorSchemeMetaChanged(); return; } - if (EqualIgnoringASCIICase(name_value, "battery-savings")) { - GetDocument().BatterySavingsMetaChanged(); - return; - } if (EqualIgnoringASCIICase(name_value, "supports-reduced-motion")) { GetDocument().SupportsReducedMotionMetaChanged();
diff --git a/third_party/blink/renderer/core/html/link_style.cc b/third_party/blink/renderer/core/html/link_style.cc index 36908ccb..19898c4 100644 --- a/third_party/blink/renderer/core/html/link_style.cc +++ b/third_party/blink/renderer/core/html/link_style.cc
@@ -177,7 +177,8 @@ if (pending_sheet_type_ == PendingSheetType::kNonBlocking) return; - GetDocument().GetStyleEngine().AddPendingSheet(*owner_, pending_sheet_type_); + GetDocument().GetStyleEngine().AddPendingBlockingSheet(*owner_, + pending_sheet_type_); } void LinkStyle::RemovePendingSheet() { @@ -193,7 +194,7 @@ return; } - GetDocument().GetStyleEngine().RemovePendingSheet(*owner_, type); + GetDocument().GetStyleEngine().RemovePendingBlockingSheet(*owner_, type); } void LinkStyle::SetDisabledState(bool disabled) {
diff --git a/third_party/blink/renderer/core/html/parser/html_preload_scanner.cc b/third_party/blink/renderer/core/html/parser/html_preload_scanner.cc index f4de206..7a0b2ea 100644 --- a/third_party/blink/renderer/core/html/parser/html_preload_scanner.cc +++ b/third_party/blink/renderer/core/html/parser/html_preload_scanner.cc
@@ -337,7 +337,8 @@ // TODO(crbug.com/981419): Honor the integrity attribute value for all // supported preload destinations, not just the destinations that support // SRI in the first place. - if (type == ResourceType::kScript || type == ResourceType::kCSSStyleSheet) { + if (type == ResourceType::kScript || type == ResourceType::kCSSStyleSheet || + type == ResourceType::kFont) { request->SetIntegrityMetadata(integrity_metadata_); }
diff --git a/third_party/blink/renderer/core/loader/document_loader.cc b/third_party/blink/renderer/core/loader/document_loader.cc index 4e0ddfe6..25fa9b4f 100644 --- a/third_party/blink/renderer/core/loader/document_loader.cc +++ b/third_party/blink/renderer/core/loader/document_loader.cc
@@ -248,6 +248,7 @@ struct SameSizeAsDocumentLoader : public GarbageCollected<SameSizeAsDocumentLoader>, + public WebDocumentLoader, public UseCounter, public WebNavigationBodyLoader::Client { Member<MHTMLArchive> archive; @@ -272,6 +273,7 @@ Member<SubresourceFilter> subresource_filter; AtomicString original_referrer; ResourceResponse response; + mutable WrappedResourceResponse response_wrapper; WebFrameLoadType load_type; bool is_client_redirect; bool replaces_current_history_item; @@ -337,6 +339,7 @@ bool anonymous; bool waiting_for_document_loader; bool waiting_for_code_cache; + std::unique_ptr<ExtraData> extra_data; }; // Asserts size of DocumentLoader, so that whenever a new attribute is added to @@ -348,11 +351,11 @@ } // namespace DocumentLoader::DocumentLoader( - base::PassKey<WebDocumentLoaderImpl>, LocalFrame* frame, WebNavigationType navigation_type, std::unique_ptr<WebNavigationParams> navigation_params, - std::unique_ptr<PolicyContainer> policy_container) + std::unique_ptr<PolicyContainer> policy_container, + std::unique_ptr<ExtraData> extra_data) : params_(std::move(navigation_params)), policy_container_(std::move(policy_container)), url_(params_->url), @@ -378,6 +381,7 @@ : nullptr), original_referrer_(referrer_), response_(params_->response.ToResourceResponse()), + response_wrapper_(response_), load_type_(params_->frame_load_type), is_client_redirect_(params_->is_client_redirect), data_received_(false), @@ -434,7 +438,8 @@ params_->is_cross_site_cross_browsing_context_group), navigation_api_back_entries_(params_->navigation_api_back_entries), navigation_api_forward_entries_(params_->navigation_api_forward_entries), - anonymous_(params_->anonymous) { + anonymous_(params_->anonymous), + extra_data_(std::move(extra_data)) { DCHECK(frame_); // TODO(dgozman): we should get rid of this boolean field, and make client @@ -512,6 +517,8 @@ fenced_frame_reporting_->metadata.insert(destination, std::move(data)); } } + + frame_->Client()->DidCreateDocumentLoader(this); } std::unique_ptr<WebNavigationParams> @@ -645,20 +652,15 @@ return navigation_timing_info_.get(); } -const AtomicString& DocumentLoader::OriginalReferrer() const { +WebString DocumentLoader::OriginalReferrer() const { return original_referrer_; } -void DocumentLoader::SetSubresourceFilter( - SubresourceFilter* subresource_filter) { - subresource_filter_ = subresource_filter; -} - const KURL& DocumentLoader::Url() const { return url_; } -const AtomicString& DocumentLoader::HttpMethod() const { +WebString DocumentLoader::HttpMethod() const { return http_method_; } @@ -1583,6 +1585,7 @@ if (!frame_) return; + extra_data_.reset(); service_worker_network_provider_ = nullptr; WeakIdentifierMap<DocumentLoader>::NotifyObjectDestroyed(this); frame_ = nullptr; @@ -1609,6 +1612,10 @@ return SchemeRegistry::ShouldLoadURLSchemeAsEmptyDocument(url.Protocol()); } +bool WebDocumentLoader::WillLoadUrlAsEmpty(const WebURL& url) { + return DocumentLoader::WillLoadUrlAsEmpty(url); +} + void DocumentLoader::InitializeEmptyResponse() { response_ = ResourceResponse(url_); response_.SetMimeType("text/html"); @@ -2993,6 +3000,46 @@ } } +void DocumentLoader::SetSubresourceFilter( + WebDocumentSubresourceFilter* subresource_filter) { + DCHECK(subresource_filter); + subresource_filter_ = MakeGarbageCollected<SubresourceFilter>( + frame_->DomWindow(), base::WrapUnique(subresource_filter)); +} + +WebDocumentLoader::ExtraData* DocumentLoader::GetExtraData() const { + return extra_data_.get(); +} + +std::unique_ptr<WebDocumentLoader::ExtraData> DocumentLoader::TakeExtraData() { + return std::move(extra_data_); +} + +void DocumentLoader::SetExtraData(std::unique_ptr<ExtraData> extra_data) { + extra_data_ = std::move(extra_data); +} + +WebArchiveInfo DocumentLoader::GetArchiveInfo() const { + if (archive_ && + archive_->LoadResult() == mojom::blink::MHTMLLoadResult::kSuccess) { + return { + archive_->LoadResult(), + archive_->MainResource()->Url(), + archive_->Date(), + }; + } + + // TODO(arthursonzogni): Returning MHTMLLoadResult::kSuccess when there are no + // archive is very misleading. Consider adding a new enum value to + // discriminate success versus no archive. + return { + archive_ ? archive_->LoadResult() + : mojom::blink::MHTMLLoadResult::kSuccess, + WebURL(), + base::Time(), + }; +} + // static void DocumentLoader::DisableCodeCacheForTesting() { GetDisableCodeCacheForTesting() = true;
diff --git a/third_party/blink/renderer/core/loader/document_loader.h b/third_party/blink/renderer/core/loader/document_loader.h index 2dbe95f..eb8bda77 100644 --- a/third_party/blink/renderer/core/loader/document_loader.h +++ b/third_party/blink/renderer/core/loader/document_loader.h
@@ -71,6 +71,7 @@ #include "third_party/blink/renderer/core/loader/preload_helper.h" #include "third_party/blink/renderer/core/page/viewport_description.h" #include "third_party/blink/renderer/core/permissions_policy/policy_helper.h" +#include "third_party/blink/renderer/platform/exported/wrapped_resource_response.h" #include "third_party/blink/renderer/platform/instrumentation/use_counter.h" #include "third_party/blink/renderer/platform/loader/fetch/client_hints_preferences.h" #include "third_party/blink/renderer/platform/loader/fetch/code_cache_host.h" @@ -106,7 +107,6 @@ class ResourceTimingInfo; class SerializedScriptValue; class SubresourceFilter; -class WebDocumentLoaderImpl; class WebServiceWorkerNetworkProvider; namespace mojom { @@ -121,18 +121,15 @@ // provisional load, then commit but that is no longer necessary and this class // can be simplified. class CORE_EXPORT DocumentLoader : public GarbageCollected<DocumentLoader>, + public WebDocumentLoader, public UseCounter, public WebNavigationBodyLoader::Client { public: - // Do not create DocumentLoader directly. - // Use WebDocumentLoaderImpl's constructor to create it so that - // DocumentLoader can always be static_cast to WebDocumentLoaderImpl. - DocumentLoader(base::PassKey<WebDocumentLoaderImpl>, - LocalFrame*, + DocumentLoader(LocalFrame*, WebNavigationType navigation_type, std::unique_ptr<WebNavigationParams> navigation_params, - std::unique_ptr<PolicyContainer> policy_container); - + std::unique_ptr<PolicyContainer> policy_container, + std::unique_ptr<ExtraData> extra_data); ~DocumentLoader() override; // Returns WebNavigationParams that can be used to clone DocumentLoader. Used @@ -147,17 +144,58 @@ ResourceTimingInfo* GetNavigationTimingInfo() const; - virtual void DetachFromFrame(bool flush_microtask_queue); + void DetachFromFrame(bool flush_microtask_queue); uint64_t MainResourceIdentifier() const; const AtomicString& MimeType() const; - const AtomicString& OriginalReferrer() const; + // WebDocumentLoader overrides: + WebString OriginalReferrer() const override; + WebURL GetUrl() const override { return Url(); } + WebString HttpMethod() const override; + WebString Referrer() const override { return GetReferrer(); } + bool HasUnreachableURL() const override { + return !UnreachableURL().IsEmpty(); + } + WebURL UnreachableWebURL() const override { return UnreachableURL(); } + const WebURLResponse& GetWebResponse() const override { + return response_wrapper_; + } + bool IsClientRedirect() const override { return is_client_redirect_; } + bool ReplacesCurrentHistoryItem() const override { + return replaces_current_history_item_; + } + WebNavigationType GetNavigationType() const override { + return navigation_type_; + } + ExtraData* GetExtraData() const override; + std::unique_ptr<ExtraData> TakeExtraData() override; + void SetExtraData(std::unique_ptr<ExtraData>) override; + void SetSubresourceFilter(WebDocumentSubresourceFilter*) override; + void SetServiceWorkerNetworkProvider( + std::unique_ptr<WebServiceWorkerNetworkProvider>) override; + // May return null before the first HTML tag is inserted by the + // parser (before didCreateDataSource is called), after the document + // is detached from frame, or in tests. + WebServiceWorkerNetworkProvider* GetServiceWorkerNetworkProvider() override { + return service_worker_network_provider_.get(); + } + // Can be used to temporarily suspend feeding the parser with new data. The + // parser will be allowed to read new data when ResumeParser() is called the + // same number of time than BlockParser(). + void BlockParser() override; + void ResumeParser() override; + bool HasBeenLoadedAsWebArchive() const override { return archive_; } + WebArchiveInfo GetArchiveInfo() const override; + bool LastNavigationHadTransientUserActivation() const override { + return last_navigation_had_transient_user_activation_; + } + void SetCodeCacheHost( + mojo::PendingRemote<mojom::CodeCacheHost> code_cache_host) override; MHTMLArchive* Archive() const { return archive_.Get(); } - void SetSubresourceFilter(SubresourceFilter*); SubresourceFilter* GetSubresourceFilter() const { return subresource_filter_.Get(); } @@ -168,7 +206,6 @@ const KURL& Url() const; const KURL& UrlForHistory() const; - const AtomicString& HttpMethod() const; const AtomicString& GetReferrer() const; const SecurityOrigin* GetRequestorOrigin() const; const KURL& UnreachableURL() const; @@ -200,10 +237,6 @@ bool is_synchronously_committed); const ResourceResponse& GetResponse() const { return response_; } - bool IsClientRedirect() const { return is_client_redirect_; } - bool ReplacesCurrentHistoryItem() const { - return replaces_current_history_item_; - } bool IsCommittedButEmpty() const { return state_ >= kCommitted && !data_received_; @@ -215,7 +248,6 @@ WebFrameLoadType LoadType() const { return load_type_; } void SetLoadType(WebFrameLoadType load_type) { load_type_ = load_type; } - WebNavigationType GetNavigationType() const { return navigation_type_; } void SetNavigationType(WebNavigationType navigation_type) { navigation_type_ = navigation_type; } @@ -271,16 +303,6 @@ void DispatchLinkHeaderPreloads(const ViewportDescription*, PreloadHelper::MediaPreloadPolicy); - void SetServiceWorkerNetworkProvider( - std::unique_ptr<WebServiceWorkerNetworkProvider>); - - // May return null before the first HTML tag is inserted by the - // parser (before didCreateDataSource is called), after the document - // is detached from frame, or in tests. - WebServiceWorkerNetworkProvider* GetServiceWorkerNetworkProvider() { - return service_worker_network_provider_.get(); - } - void LoadFailed(const ResourceError&); void Trace(Visitor*) const override; @@ -299,12 +321,6 @@ return devtools_navigation_token_; } - // Can be used to temporarily suspend feeding the parser with new data. The - // parser will be allowed to read new data when ResumeParser() is called the - // same number of time than BlockParser(). - void BlockParser(); - void ResumeParser(); - UseCounterImpl& GetUseCounter() { return use_counter_; } Dactyloscoper& GetDactyloscoper() { return dactyloscoper_; } @@ -316,10 +332,6 @@ void SetCommitReason(CommitReason reason) { commit_reason_ = reason; } - bool LastNavigationHadTransientUserActivation() const { - return last_navigation_had_transient_user_activation_; - } - // Whether the navigation originated from the browser process. Note: history // navigation is always considered to be browser initiated, even if the // navigation was started using the history API in the renderer. @@ -367,8 +379,6 @@ const mojom::blink::PrerenderPageActivationParams& params); CodeCacheHost* GetCodeCacheHost(); - void SetCodeCacheHost( - mojo::PendingRemote<mojom::CodeCacheHost> code_cache_host); static void DisableCodeCacheForTesting(); mojo::PendingRemote<blink::mojom::CodeCacheHost> CreateWorkerCodeCacheHost(); @@ -552,6 +562,9 @@ const AtomicString original_referrer_; ResourceResponse response_; + // Mutable because the const getters will magically sync these to the + // latest version of |response_|. + mutable WrappedResourceResponse response_wrapper_; WebFrameLoadType load_type_; @@ -695,6 +708,8 @@ // features::kEarlyBodyLoad is enabled. bool waiting_for_document_loader_ = false; bool waiting_for_code_cache_ = false; + + std::unique_ptr<ExtraData> extra_data_; }; DECLARE_WEAK_IDENTIFIER_MAP(DocumentLoader);
diff --git a/third_party/blink/renderer/core/loader/empty_clients.cc b/third_party/blink/renderer/core/loader/empty_clients.cc index a7957a04..0dfbe43 100644 --- a/third_party/blink/renderer/core/loader/empty_clients.cc +++ b/third_party/blink/renderer/core/loader/empty_clients.cc
@@ -36,14 +36,11 @@ #include "third_party/blink/public/platform/modules/service_worker/web_service_worker_provider_client.h" #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/public/platform/web_media_player.h" -#include "third_party/blink/renderer/core/exported/web_document_loader_impl.h" -#include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/core/frame/visual_viewport.h" #include "third_party/blink/renderer/core/html/forms/color_chooser.h" #include "third_party/blink/renderer/core/html/forms/date_time_chooser.h" #include "third_party/blink/renderer/core/html/forms/file_chooser.h" #include "third_party/blink/renderer/core/html/forms/html_form_element.h" -#include "third_party/blink/renderer/core/loader/document_loader.h" namespace blink { @@ -120,20 +117,6 @@ void EmptyLocalFrameClient::DispatchWillSendSubmitEvent(HTMLFormElement*) {} -DocumentLoader* EmptyLocalFrameClient::CreateDocumentLoader( - LocalFrame* frame, - WebNavigationType navigation_type, - std::unique_ptr<WebNavigationParams> navigation_params, - std::unique_ptr<PolicyContainer> policy_container, - std::unique_ptr<WebDocumentLoader::ExtraData> extra_data) { - DCHECK(frame); - WebDocumentLoaderImpl* document_loader = - MakeGarbageCollected<WebDocumentLoaderImpl>( - frame, navigation_type, std::move(navigation_params), - std::move(policy_container), std::move(extra_data)); - return document_loader; -} - LocalFrame* EmptyLocalFrameClient::CreateFrame(const AtomicString&, HTMLFrameOwnerElement*) { return nullptr;
diff --git a/third_party/blink/renderer/core/loader/empty_clients.h b/third_party/blink/renderer/core/loader/empty_clients.h index aab6a77..acd3b33c 100644 --- a/third_party/blink/renderer/core/loader/empty_clients.h +++ b/third_party/blink/renderer/core/loader/empty_clients.h
@@ -234,8 +234,6 @@ void SetCursorForPlugin(const ui::Cursor&, LocalFrame*) override {} void InstallSupplements(LocalFrame&) override {} void MainFrameScrollOffsetChanged(LocalFrame& main_frame) const override {} - void BatterySavingsChanged(LocalFrame& main_frame, - BatterySavingsFlags savings) override {} private: const display::ScreenInfos empty_screen_infos_{display::ScreenInfo()}; @@ -302,12 +300,7 @@ void DidStartLoading() override {} void DidStopLoading() override {} - DocumentLoader* CreateDocumentLoader( - LocalFrame*, - WebNavigationType, - std::unique_ptr<WebNavigationParams> navigation_params, - std::unique_ptr<PolicyContainer> policy_container, - std::unique_ptr<WebDocumentLoader::ExtraData> extra_data) override; + void DidCreateDocumentLoader(DocumentLoader*) override {} String UserAgentOverride() override { return ""; } String UserAgent() override { return ""; }
diff --git a/third_party/blink/renderer/core/loader/frame_fetch_context_test.cc b/third_party/blink/renderer/core/loader/frame_fetch_context_test.cc index b007819..5a74c0ba 100644 --- a/third_party/blink/renderer/core/loader/frame_fetch_context_test.cc +++ b/third_party/blink/renderer/core/loader/frame_fetch_context_test.cc
@@ -176,23 +176,15 @@ filtered_load_callback_counter_ = 0; } - void TearDown() override { - document->Loader()->SetSubresourceFilter(nullptr); - FrameFetchContextTest::TearDown(); - } - int GetFilteredLoadCallCount() const { return filtered_load_callback_counter_; } void SetFilterPolicy(WebDocumentSubresourceFilter::LoadPolicy policy, bool is_associated_with_ad_subframe = false) { - document->Loader()->SetSubresourceFilter( - MakeGarbageCollected<SubresourceFilter>( - document->GetExecutionContext(), - std::make_unique<FixedPolicySubresourceFilter>( - policy, &filtered_load_callback_counter_, - is_associated_with_ad_subframe))); + document->Loader()->SetSubresourceFilter(new FixedPolicySubresourceFilter( + policy, &filtered_load_callback_counter_, + is_associated_with_ad_subframe)); } absl::optional<ResourceRequestBlockedReason> CanRequest() {
diff --git a/third_party/blink/renderer/core/loader/frame_loader.cc b/third_party/blink/renderer/core/loader/frame_loader.cc index e700b68..bb0593ba 100644 --- a/third_party/blink/renderer/core/loader/frame_loader.cc +++ b/third_party/blink/renderer/core/loader/frame_loader.cc
@@ -66,7 +66,6 @@ #include "third_party/blink/renderer/core/dom/element.h" #include "third_party/blink/renderer/core/dom/ignore_opens_during_unload_count_incrementer.h" #include "third_party/blink/renderer/core/events/page_transition_event.h" -#include "third_party/blink/renderer/core/exported/web_document_loader_impl.h" #include "third_party/blink/renderer/core/exported/web_plugin_container_impl.h" #include "third_party/blink/renderer/core/fragment_directive/text_fragment_anchor.h" #include "third_party/blink/renderer/core/frame/csp/content_security_policy.h" @@ -271,7 +270,7 @@ navigation_params->sandbox_flags |= csp->sandbox; } - DocumentLoader* new_document_loader = Client()->CreateDocumentLoader( + DocumentLoader* new_document_loader = MakeGarbageCollected<DocumentLoader>( frame_, kWebNavigationTypeOther, std::move(navigation_params), std::move(policy_container), nullptr /* extra_data */); @@ -1051,10 +1050,7 @@ if (commit_reason == CommitReason::kXSLT || commit_reason == CommitReason::kJavascriptUrl) { DCHECK(!extra_data); - if (auto* old_document_loader = - static_cast<WebDocumentLoaderImpl*>(document_loader_.Get())) { - extra_data = old_document_loader->TakeExtraData(); - } + extra_data = document_loader_->TakeExtraData(); } // Create the OldDocumentInfoForCommit for the old document (that might be in @@ -1150,7 +1146,7 @@ } // TODO(dgozman): get rid of provisional document loader and most of the code // below. We should probably call DocumentLoader::CommitNavigation directly. - DocumentLoader* new_document_loader = Client()->CreateDocumentLoader( + DocumentLoader* new_document_loader = MakeGarbageCollected<DocumentLoader>( frame_, navigation_type, std::move(navigation_params), std::move(policy_container), std::move(extra_data));
diff --git a/third_party/blink/renderer/core/loader/preload_helper.cc b/third_party/blink/renderer/core/loader/preload_helper.cc index 12f6aa4..d66cdd1 100644 --- a/third_party/blink/renderer/core/loader/preload_helper.cc +++ b/third_party/blink/renderer/core/loader/preload_helper.cc
@@ -350,7 +350,8 @@ // supported preload destinations, not just the destinations that support SRI // in the first place. if (resource_type == ResourceType::kScript || - resource_type == ResourceType::kCSSStyleSheet) { + resource_type == ResourceType::kCSSStyleSheet || + resource_type == ResourceType::kFont) { if (!integrity_attr.IsEmpty()) { IntegrityMetadataSet metadata_set; SubresourceIntegrity::ParseIntegrityAttribute(
diff --git a/third_party/blink/renderer/core/mojo/mojo_handle.cc b/third_party/blink/renderer/core/mojo/mojo_handle.cc index acb1b04e..97140df 100644 --- a/third_party/blink/renderer/core/mojo/mojo_handle.cc +++ b/third_party/blink/renderer/core/mojo/mojo_handle.cc
@@ -259,18 +259,31 @@ MojoMapBufferResult* MojoHandle::mapBuffer(unsigned offset, unsigned num_bytes) { MojoMapBufferResult* result_dict = MojoMapBufferResult::Create(); - void* data = nullptr; - MojoResult result = - MojoMapBuffer(handle_.get().value(), offset, num_bytes, nullptr, &data); - result_dict->setResult(result); - if (result == MOJO_RESULT_OK) { - ArrayBufferContents contents( - data, num_bytes, [](void* buffer, size_t length, void* alloc_data) { - MojoResult result = MojoUnmapBuffer(buffer); - DCHECK_EQ(result, MOJO_RESULT_OK); - }); + + // We need to extract the underlying shared memory region to map it as array + // buffer contents. However, as we don't know what kind of shared memory + // region is currently backing the buffer, we unwrap it to the underlying + // platform shared memory region. We also don't want to duplicate the region, + // and so need to perform a small dance here to first unwrap, and later + // re-wrap the MojoSharedBuffer to/from a //base shared memory region. + mojo::SharedBufferHandle buffer_handle(handle_.release().value()); + auto region = mojo::UnwrapPlatformSharedMemoryRegion( + mojo::ScopedSharedBufferHandle(buffer_handle)); + + if (region.IsValid()) { + ArrayBufferContents contents(region, offset, num_bytes); + result_dict->setResult(MOJO_RESULT_OK); result_dict->setBuffer(DOMArrayBuffer::Create(contents)); + } else { + result_dict->setResult(MOJO_RESULT_UNKNOWN); } + + // 2nd part of the dance: we now need to wrap the shared memory region into a + // mojo handle again. + mojo::ScopedSharedBufferHandle mojo_buffer = + mojo::WrapPlatformSharedMemoryRegion(std::move(region)); + handle_.reset(mojo::Handle(mojo_buffer.release().value())); + return result_dict; }
diff --git a/third_party/blink/renderer/core/page/chrome_client.h b/third_party/blink/renderer/core/page/chrome_client.h index 0325565..48a77bf 100644 --- a/third_party/blink/renderer/core/page/chrome_client.h +++ b/third_party/blink/renderer/core/page/chrome_client.h
@@ -41,7 +41,6 @@ #include "third_party/blink/public/mojom/devtools/console_message.mojom-blink-forward.h" #include "third_party/blink/public/mojom/input/focus_type.mojom-blink-forward.h" #include "third_party/blink/renderer/core/core_export.h" -#include "third_party/blink/renderer/core/html/battery_savings.h" #include "third_party/blink/renderer/core/html/forms/external_date_time_chooser.h" #include "third_party/blink/renderer/core/html/forms/popup_menu.h" #include "third_party/blink/renderer/core/layout/geometry/physical_offset.h" @@ -534,9 +533,6 @@ LocalFrame* frame, std::unique_ptr<gfx::DelegatedInkMetadata> metadata) {} - virtual void BatterySavingsChanged(LocalFrame& main_frame, - BatterySavingsFlags savings) = 0; - virtual void FormElementReset(HTMLFormElement& element) {} virtual void PasswordFieldReset(HTMLInputElement& element) {}
diff --git a/third_party/blink/renderer/core/page/chrome_client_impl.cc b/third_party/blink/renderer/core/page/chrome_client_impl.cc index 6286f81c..bb3e05b 100644 --- a/third_party/blink/renderer/core/page/chrome_client_impl.cc +++ b/third_party/blink/renderer/core/page/chrome_client_impl.cc
@@ -1276,14 +1276,6 @@ frame->GetWidgetForLocalRoot()->SetDelegatedInkMetadata(std::move(metadata)); } -void ChromeClientImpl::BatterySavingsChanged(LocalFrame& main_frame, - BatterySavingsFlags savings) { - DCHECK(main_frame.IsMainFrame()); - WebLocalFrameImpl::FromFrame(main_frame) - ->FrameWidgetImpl() - ->BatterySavingsChanged(savings); -} - void ChromeClientImpl::FormElementReset(HTMLFormElement& element) { Document& doc = element.GetDocument(); if (auto* fill_client = AutofillClientFromFrame(doc.GetFrame()))
diff --git a/third_party/blink/renderer/core/page/chrome_client_impl.h b/third_party/blink/renderer/core/page/chrome_client_impl.h index bac84fa..807567c 100644 --- a/third_party/blink/renderer/core/page/chrome_client_impl.h +++ b/third_party/blink/renderer/core/page/chrome_client_impl.h
@@ -290,9 +290,6 @@ double UserZoomFactor() const override; - void BatterySavingsChanged(LocalFrame& main_frame, - BatterySavingsFlags savings) override; - void FormElementReset(HTMLFormElement& element) override; void PasswordFieldReset(HTMLInputElement& element) override;
diff --git a/third_party/blink/renderer/core/speculation_rules/document_speculation_rules.cc b/third_party/blink/renderer/core/speculation_rules/document_speculation_rules.cc index f68b659..2697bbf 100644 --- a/third_party/blink/renderer/core/speculation_rules/document_speculation_rules.cc +++ b/third_party/blink/renderer/core/speculation_rules/document_speculation_rules.cc
@@ -74,12 +74,16 @@ return; has_pending_update_ = true; - auto task_runner = GetSupplementable()->GetExecutionContext()->GetTaskRunner( - TaskType::kIdleTask); - task_runner->PostTask( - base::Location::Current(), - WTF::Bind(&DocumentSpeculationRules::UpdateSpeculationCandidates, - WrapWeakPersistent(this))); + ExecutionContext* execution_context = + GetSupplementable()->GetExecutionContext(); + if (!execution_context) + return; + + execution_context->GetTaskRunner(TaskType::kIdleTask) + ->PostTask( + base::Location::Current(), + WTF::Bind(&DocumentSpeculationRules::UpdateSpeculationCandidates, + WrapWeakPersistent(this))); } void DocumentSpeculationRules::UpdateSpeculationCandidates() {
diff --git a/third_party/blink/renderer/core/typed_arrays/array_buffer/DEPS b/third_party/blink/renderer/core/typed_arrays/array_buffer/DEPS index 8ab5ed4..1927cf464 100644 --- a/third_party/blink/renderer/core/typed_arrays/array_buffer/DEPS +++ b/third_party/blink/renderer/core/typed_arrays/array_buffer/DEPS
@@ -1,4 +1,7 @@ include_rules = [ "+base/allocator/partition_allocator/oom.h", "+base/allocator/partition_allocator/page_allocator.h", + "+base/memory/page_size.h", + "+base/memory/platform_shared_memory_region.h", + "+gin/array_buffer.h" ]
diff --git a/third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_contents.cc b/third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_contents.cc index 60bfe8d..457e6298 100644 --- a/third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_contents.cc +++ b/third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_contents.cc
@@ -30,6 +30,8 @@ #include "base/allocator/partition_allocator/partition_alloc.h" #include "base/bits.h" +#include "base/system/sys_info.h" +#include "gin/array_buffer.h" #include "third_party/blink/renderer/platform/instrumentation/instance_counters.h" #include "third_party/blink/renderer/platform/wtf/allocator/partitions.h" @@ -45,6 +47,35 @@ } ArrayBufferContents::ArrayBufferContents( + const base::subtle::PlatformSharedMemoryRegion& region, + uint64_t offset, + size_t length) { + DCHECK(region.IsValid()); + + // The offset must be a multiples of |SysInfo::VMAllocationGranularity()|. + size_t offset_rounding = offset % base::SysInfo::VMAllocationGranularity(); + uint64_t real_offset = offset - offset_rounding; + size_t real_length = length + offset_rounding; + + absl::optional<base::span<uint8_t>> result = region.MapAt( + real_offset, real_length, gin::GetSharedMemoryMapperForArrayBuffers()); + if (!result.has_value()) { + return; + } + + auto deleter = [](void* buffer, size_t length, void* data) { + size_t offset = reinterpret_cast<uintptr_t>(buffer) % + base::SysInfo::VMAllocationGranularity(); + uint8_t* base = static_cast<uint8_t*>(buffer) - offset; + base::span<uint8_t> mapping = base::make_span(base, length + offset); + gin::GetSharedMemoryMapperForArrayBuffers()->Unmap(mapping); + }; + void* base = result.value().data() + offset_rounding; + backing_store_ = + v8::ArrayBuffer::NewBackingStore(base, length, deleter, nullptr); +} + +ArrayBufferContents::ArrayBufferContents( size_t num_elements, size_t element_byte_size, SharingType is_shared,
diff --git a/third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_contents.h b/third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_contents.h index 03fcc36..bea1fb3b9 100644 --- a/third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_contents.h +++ b/third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_contents.h
@@ -28,6 +28,7 @@ #define THIRD_PARTY_BLINK_RENDERER_CORE_TYPED_ARRAYS_ARRAY_BUFFER_ARRAY_BUFFER_CONTENTS_H_ #include "base/allocator/partition_allocator/page_allocator.h" +#include "base/memory/platform_shared_memory_region.h" #include "base/memory/scoped_refptr.h" #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" @@ -62,6 +63,10 @@ SharingType is_shared, InitializationPolicy); ArrayBufferContents(void* data, size_t length, DataDeleter deleter); + ArrayBufferContents( + const base::subtle::PlatformSharedMemoryRegion& shared_memory_region, + uint64_t offset, + size_t length); ArrayBufferContents(ArrayBufferContents&&) = default; ArrayBufferContents(const ArrayBufferContents&) = default; explicit ArrayBufferContents(std::shared_ptr<v8::BackingStore> backing_store)
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 12fb20a..59290ee 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_node_object.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_node_object.cc
@@ -1251,10 +1251,8 @@ return RoleFromLayoutObjectOrNode(); // Treat <iframe>, <frame> and <fencedframe> the same. - if (IsA<HTMLIFrameElement>(*GetNode()) || IsA<HTMLFrameElement>(*GetNode()) || - IsA<HTMLFencedFrameElement>(*GetNode())) { + if (IsFrame(GetNode())) return ax::mojom::blink::Role::kIframe; - } // There should only be one banner/contentInfo per page. If header/footer are // being used within an article or section then it should not be exposed as
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object.cc b/third_party/blink/renderer/modules/accessibility/ax_object.cc index a35a845..2b03f03c 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_object.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_object.cc
@@ -4243,7 +4243,7 @@ // It also states user agents should ignore the presentational role if // the element has global ARIA states and properties. if (ui::IsPresentational(role)) { - if (IsA<HTMLIFrameElement>(*GetNode()) || IsA<HTMLFrameElement>(*GetNode())) + if (IsFrame(GetNode())) return ax::mojom::blink::Role::kIframePresentational; if ((GetElement() && GetElement()->SupportsFocus()) || HasAriaAttribute(true /* does_undo_role_presentation */)) { @@ -5851,6 +5851,24 @@ } // static +bool AXObject::IsFrame(const Node* node) { + auto* frame_owner = DynamicTo<HTMLFrameOwnerElement>(node); + if (!frame_owner) + return false; + switch (frame_owner->OwnerType()) { + case FrameOwnerElementType::kIframe: + case FrameOwnerElementType::kFrame: + case FrameOwnerElementType::kFencedframe: + return true; + case FrameOwnerElementType::kObject: + case FrameOwnerElementType::kEmbed: + case FrameOwnerElementType::kPortal: + case FrameOwnerElementType::kNone: + return false; + } +} + +// static bool AXObject::HasARIAOwns(Element* element) { if (!element) return false;
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object.h b/third_party/blink/renderer/modules/accessibility/ax_object.h index d4f1009..c2bc2cd 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_object.h +++ b/third_party/blink/renderer/modules/accessibility/ax_object.h
@@ -1279,6 +1279,7 @@ // TODO(accessibility) Move these to a static helper util class. static bool IsARIAControl(ax::mojom::blink::Role); static bool IsARIAInput(ax::mojom::blink::Role); + static bool IsFrame(const Node*); static bool HasARIAOwns(Element* element); // Is this a widget that requires container widget. bool IsSubWidget() const;
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc index 13e8a6b..f581ff2 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc
@@ -59,7 +59,6 @@ #include "third_party/blink/renderer/core/html/forms/html_select_element.h" #include "third_party/blink/renderer/core/html/forms/listed_element.h" #include "third_party/blink/renderer/core/html/html_area_element.h" -#include "third_party/blink/renderer/core/html/html_frame_element_base.h" #include "third_party/blink/renderer/core/html/html_frame_owner_element.h" #include "third_party/blink/renderer/core/html/html_head_element.h" #include "third_party/blink/renderer/core/html/html_image_element.h" @@ -493,6 +492,12 @@ } if (node->IsTextNode()) { + // Children of an <iframe> tag will always be replaced by a new Document, + // either loaded from the iframe src or empty. In fact, we don't even parse + // them and they are treated like one text node. Consider irrelevant. + if (AXObject::IsFrame(node->parentElement())) + return false; + // Layout has more info available to determine if whitespace is relevant. // If display-locked, layout object may be missing or stale: // Assume that all display-locked text nodes are relevant. @@ -509,12 +514,6 @@ return false; } - // Children of an <iframe> tag will always be replaced by a new Document, - // either loaded from the iframe src or empty. In fact, we don't even parse - // them and they are treated like one text node. Consider irrelevant. - if (IsA<HTMLIFrameElement>(node->parentElement())) - return false; - // If unrendered and in <canvas>, consider even whitespace relevant. // TODO(aleventhal) Consider including all text, even unrendered whitespace, // whether or not in <canvas>. For now this matches previous behavior. @@ -604,7 +603,7 @@ // that is a child of the frame. In the case where descendants are allowed, // they will be in a different document, and therefore this loop will not // reach the frame/iframe. - if (IsA<HTMLFrameElementBase>(ancestor)) + if (AXObject::IsFrame(ancestor)) return false; // Objects inside an SVG <style> are irrelevant. // However, when can this condition be reached?
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5 index 4d25b5d..8397d73 100644 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -271,12 +271,6 @@ }, }, { - // https://github.com/chrishtr/battery-savings/blob/master/explainer.md - name: "BatterySavingsMeta", - origin_trial_feature_name: "BatterySavingsMeta", - status: "experimental", - }, - { // https://github.com/WICG/display-locking/blob/master/explainer-beforematch.md name: "BeforeMatchEvent", origin_trial_feature_name: "BeforeMatchEvent",
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index c9d2ace6..a5c443be 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -7725,3 +7725,7 @@ # Sheriff 2022-04-25 crbug.com/1319808 virtual/wbn-from-network/external/wpt/web-bundle/subresource-loading/script-reuse-web-bundle-resource.https.tentative.html [ Skip ] + +crbug.com/1267538 [ Linux ] http/tests/csspaint/border-color.html [ Failure Pass ] +crbug.com/1267538 [ Mac ] http/tests/csspaint/border-color.html [ Failure Pass ] +
diff --git a/third_party/blink/web_tests/external/Version b/third_party/blink/web_tests/external/Version index 29f0826..d966f6e 100644 --- a/third_party/blink/web_tests/external/Version +++ b/third_party/blink/web_tests/external/Version
@@ -1 +1 @@ -Version: e8199c0728bb283d72cfca4986751d72e4ecf80d +Version: b5410883dff5f0cc3608155543a1523c5f7895b5
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json index 7c87cda..045850b 100644 --- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json +++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
@@ -101,6 +101,13 @@ {} ] ], + "iframe-srcdoc.html": [ + "74460048e09e65097aa5f2139a5d2819bb0207e0", + [ + null, + {} + ] + ], "in-page-link-with-aria-hidden.html": [ "237707ba074c6943a3922c8a49fa81acb173a566", [ @@ -1561,6 +1568,13 @@ {} ] ], + "inline-with-spanner-in-overflowed-container-before-multicol-float.html": [ + "69abc9bcf99a16c1529965b7bd9133a58fd295af", + [ + null, + {} + ] + ], "multicol-block-in-inline-crash.html": [ "037b558ac0be08da6dfa6868b06e7a03e44031de", [ @@ -1736,6 +1750,20 @@ {} ] ], + "spanner-in-overflowed-container-before-float.html": [ + "c15d8aa0faf159d25f87dc76df745e18318ccc61", + [ + null, + {} + ] + ], + "spanner-in-overflowed-container-before-inline-content.html": [ + "8fba171e25dfb8128d59243f8a72f0149986416e", + [ + null, + {} + ] + ], "specified-height-with-just-spanner-and-oof.html": [ "3c4d51b0f433f4cbdb9e76f4301162924b6918f1", [ @@ -140444,6 +140472,58 @@ {} ] ], + "multicol-span-all-children-height-009.html": [ + "49b06b5ed4eed9b4773702f2add1198843ed8c98", + [ + null, + [ + [ + "/css/reference/ref-filled-green-100px-square.xht", + "==" + ] + ], + {} + ] + ], + "multicol-span-all-children-height-010.html": [ + "0bcbf4da3ce8e1abff5b1e4c87b1106cc67c3af0", + [ + null, + [ + [ + "/css/reference/ref-filled-green-100px-square.xht", + "==" + ] + ], + {} + ] + ], + "multicol-span-all-children-height-011.html": [ + "a85c7c59e6e16c6215ad93d019d0d869a97da7ce", + [ + null, + [ + [ + "/css/reference/ref-filled-green-100px-square.xht", + "==" + ] + ], + {} + ] + ], + "multicol-span-all-children-height-012.html": [ + "49437f027c13092d6d03d7cf26d6f79b05039cc6", + [ + null, + [ + [ + "/css/reference/ref-filled-green-100px-square.xht", + "==" + ] + ], + {} + ] + ], "multicol-span-all-dynamic-add-001.html": [ "d9bf40889f75db72835c279517341dbb786c8ba8", [ @@ -260056,6 +260136,10 @@ "f596b559b0e26b9c03d47b7dcab966a4d091308b", [] ], + "all-prop-revert-layer-expected.txt": [ + "8ae9b7998ecf1b075405a6dad10e7e642f390b45", + [] + ], "all-prop-revert-visited-ref.html": [ "0ef326c2722a4f65f6657d7740a990c079b08289", [] @@ -292901,7 +292985,7 @@ [] ], "idlharness-expected.txt": [ - "1977b31db37102d6ca51ce71ea610bf43575c652", + "44af348a500de338557b9ccf9e8f5ef0b4c91e8c", [] ], "insertRule-from-script-ref.html": [ @@ -328240,7 +328324,7 @@ [] ], "idlharness.js": [ - "53ca06ddf997c2559cf6a88cc994d6919bbf5c2e", + "b5eed06ce3e1380bc6bc1e8b75e2c545249fdc18", [] ], "idlharness.js.headers": [ @@ -328815,6 +328899,10 @@ "81374cc95b81514962979e4e076d615589fcd0d1", [] ], + "authentication-requires-user-activation.https-expected.txt": [ + "184762bba1fddbf63c30b492efc3590fde4ced6b", + [] + ], "enrollment-in-iframe.sub.https-expected.txt": [ "a0cabf07eeb4bcb0c88904cead5bb97060874526", [] @@ -328825,7 +328913,7 @@ ], "resources": { "iframe-authenticate.html": [ - "067cb588087124a422a2d3861334b410dd64ac60", + "e6a634ff5806d526fa7d586df31202413bb9a894", [] ], "iframe-enroll.html": [ @@ -335166,26 +335254,10 @@ [] ] }, - "idlharness.any-expected.txt": [ - "845370fc1055ff291bf102d65281592f1a3552c1", - [] - ], - "idlharness.any.worker-expected.txt": [ - "845370fc1055ff291bf102d65281592f1a3552c1", - [] - ], "instanceTestFactory.js": [ "ac468947ec22e29310d0714cb7dfa0972893477d", [] ], - "interface.any-expected.txt": [ - "bc607da32f42c6aff73a1593504970a2398502f1", - [] - ], - "interface.any.worker-expected.txt": [ - "bc607da32f42c6aff73a1593504970a2398502f1", - [] - ], "memory": { "assertions.js": [ "b539513adcab7d84e67d65fcf97453e9bc22de43", @@ -336506,7 +336578,7 @@ }, "the-audiocontext-interface": { "audiocontext-suspend-resume-expected.txt": [ - "4b3708bcb872ac53b8e82e6d780745dcb59cafab", + "962df08002c896cc0e28e714396643a0bb26f271", [] ], "constructor-allowed-to-start-expected.txt": [ @@ -377133,6 +377205,13 @@ {} ] ], + "all-prop-revert-layer.html": [ + "b031e76c1a6791402cf203fce6c171656c76f464", + [ + null, + {} + ] + ], "all-prop-revert-noop.html": [ "696f498421e54d469f8304d46f34d9c39f81a4ef", [ @@ -386773,6 +386852,13 @@ {} ] ], + "multicol-fill-balance-023.html": [ + "fbada1b6d800ca1b5e56459923d25cf5b35ae3eb", + [ + null, + {} + ] + ], "multicol-gap-animation-001.html": [ "6a3a8d33780fe048528e1e3cd6a26707f2df4b70", [ @@ -504102,6 +504188,13 @@ {} ] ], + "subresource-integrity-font.html": [ + "da705dcb135695e748f10cc3fd3b528259601f7c", + [ + null, + {} + ] + ], "subresource-integrity-partial-image.html": [ "108897c4d6531ad53921f67c294b9754e987bbc7", [ @@ -520124,7 +520217,7 @@ }, "secure-payment-confirmation": { "authentication-accepted.https.html": [ - "2e9611f4cc4ffe5905dde5d84f4b10827c7de38a", + "1677de3f3c0b9c2f26b9b29adfd36169f9ed76de", [ null, { @@ -520142,7 +520235,7 @@ ] ], "authentication-cross-origin.sub.https.html": [ - "a9be91b824ca2a3648c74c6a25149b86c1cf61fb", + "efdb79841585ba94bd79759fbf8deb9fe4419319", [ null, { @@ -520151,7 +520244,7 @@ ] ], "authentication-icon-data-url.https.html": [ - "b4c01f34af202e143708bb6236e2bb5df2557546", + "dbdf666a990c28d0f91bfc47c712040cf09ed317", [ null, { @@ -520160,7 +520253,7 @@ ] ], "authentication-in-iframe.sub.https.html": [ - "b3a01e33d1a6be3a7a042db4b6a4ebbd9d326d1d", + "951b540f8bfbee28d0a608a350c6c3f03a905741", [ null, { @@ -520169,7 +520262,7 @@ ] ], "authentication-invalid-icon.https.html": [ - "8987c7b28f93e94b665d78f90f00f63b8b55af96", + "84c629fbe8bf7807003634b827f10340a87b9289", [ null, { @@ -520178,7 +520271,16 @@ ] ], "authentication-rejected.https.html": [ - "4973748b3ad27e27d0e28f340ca9c494254c0edc", + "444733bd17c9f5fc9512a227b63fa5f77d177adc", + [ + null, + { + "testdriver": true + } + ] + ], + "authentication-requires-user-activation.https.html": [ + "6519086ec872884efc56b9b67853eb34c9ef7b0b", [ null, { @@ -525981,6 +526083,13 @@ } ] ], + "remove-script-element.html": [ + "9de7656f5048f2268a10a14bd2cf19335dda1de0", + [ + null, + {} + ] + ], "restriction-broadcast-channel.html": [ "7225e64cf9848921de4e33982e733104265daa43", [
diff --git a/third_party/blink/web_tests/external/wpt/accessibility/crashtests/iframe-srcdoc.html b/third_party/blink/web_tests/external/wpt/accessibility/crashtests/iframe-srcdoc.html new file mode 100644 index 0000000..74460048 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/accessibility/crashtests/iframe-srcdoc.html
@@ -0,0 +1 @@ +<iframe id="frame" style="content-visibility: hidden" srcdoc="\'<table>"</table>\'></iframe>xx
diff --git a/third_party/blink/web_tests/external/wpt/css/css-cascade/all-prop-revert-layer-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-cascade/all-prop-revert-layer-expected.txt new file mode 100644 index 0000000..8ae9b79 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-cascade/all-prop-revert-layer-expected.txt
@@ -0,0 +1,316 @@ +This is a testharness.js-based test. +Found 312 tests; 304 PASS, 8 FAIL, 0 TIMEOUT, 0 NOTRUN. +PASS accent-color +PASS align-content +PASS align-items +PASS align-self +PASS alignment-baseline +PASS animation-delay +PASS animation-direction +PASS animation-duration +PASS animation-fill-mode +PASS animation-iteration-count +PASS animation-name +PASS animation-play-state +PASS animation-timeline +PASS animation-timing-function +PASS app-region +PASS appearance +PASS backdrop-filter +PASS backface-visibility +PASS background-attachment +PASS background-blend-mode +PASS background-clip +PASS background-color +PASS background-image +PASS background-origin +PASS background-position +PASS background-repeat +PASS background-size +PASS baseline-shift +PASS block-size +PASS border-block-end-color +PASS border-block-end-style +PASS border-block-end-width +PASS border-block-start-color +PASS border-block-start-style +PASS border-block-start-width +PASS border-bottom-color +PASS border-bottom-left-radius +PASS border-bottom-right-radius +PASS border-bottom-style +PASS border-bottom-width +PASS border-collapse +PASS border-end-end-radius +PASS border-end-start-radius +FAIL border-image-outset assert_equals: Layer 3 should rollback to layer 2. expected "123" but got "0" +FAIL border-image-repeat assert_equals: Layer 3 should rollback to layer 2. expected "round" but got "stretch" +FAIL border-image-slice assert_equals: Layer 3 should rollback to layer 2. expected "123" but got "100%" +FAIL border-image-source assert_equals: Layer 3 should rollback to layer 2. expected "url(\"http://web-platform.test:8001/css/css-cascade/all-prop-revert-layer.html#ref\")" but got "none" +FAIL border-image-width assert_equals: Layer 3 should rollback to layer 2. expected "123px" but got "1" +PASS border-inline-end-color +PASS border-inline-end-style +PASS border-inline-end-width +PASS border-inline-start-color +PASS border-inline-start-style +PASS border-inline-start-width +PASS border-left-color +PASS border-left-style +PASS border-left-width +PASS border-right-color +PASS border-right-style +PASS border-right-width +PASS border-start-end-radius +PASS border-start-start-radius +PASS border-top-color +PASS border-top-left-radius +PASS border-top-right-radius +PASS border-top-style +PASS border-top-width +PASS bottom +PASS box-shadow +PASS box-sizing +PASS break-after +PASS break-before +PASS break-inside +PASS buffered-rendering +PASS caption-side +PASS caret-color +PASS clear +PASS clip +PASS clip-path +PASS clip-rule +PASS color +PASS color-interpolation +PASS color-interpolation-filters +PASS color-rendering +PASS column-count +PASS column-gap +PASS column-rule-color +PASS column-rule-style +PASS column-rule-width +PASS column-span +PASS column-width +PASS contain-intrinsic-block-size +PASS contain-intrinsic-height +PASS contain-intrinsic-inline-size +PASS contain-intrinsic-size +PASS contain-intrinsic-width +PASS container-name +PASS container-type +PASS content +PASS cursor +PASS cx +PASS cy +PASS d +PASS direction +PASS display +PASS dominant-baseline +PASS empty-cells +PASS fill +PASS fill-opacity +PASS fill-rule +PASS filter +PASS flex-basis +PASS flex-direction +PASS flex-grow +PASS flex-shrink +PASS flex-wrap +PASS float +PASS flood-color +PASS flood-opacity +PASS font-family +PASS font-kerning +PASS font-optical-sizing +PASS font-palette +PASS font-size +PASS font-size-adjust +PASS font-stretch +PASS font-style +PASS font-synthesis-small-caps +PASS font-synthesis-style +PASS font-synthesis-weight +PASS font-variant +PASS font-variant-caps +PASS font-variant-east-asian +PASS font-variant-ligatures +PASS font-variant-numeric +PASS font-weight +PASS grid-auto-columns +PASS grid-auto-flow +PASS grid-auto-rows +PASS grid-column-end +PASS grid-column-start +PASS grid-row-end +PASS grid-row-start +PASS grid-template-areas +PASS grid-template-columns +PASS grid-template-rows +PASS height +PASS hyphens +PASS image-orientation +PASS image-rendering +PASS inline-size +PASS inset-block-end +PASS inset-block-start +PASS inset-inline-end +PASS inset-inline-start +PASS isolation +PASS justify-content +PASS justify-items +PASS justify-self +PASS left +PASS letter-spacing +PASS lighting-color +FAIL line-break assert_equals: Layer 3 should rollback to layer 2. expected "anywhere" but got "auto" +PASS line-height +PASS line-height-step +PASS list-style-image +PASS list-style-position +PASS list-style-type +PASS margin-block-end +PASS margin-block-start +PASS margin-bottom +PASS margin-inline-end +PASS margin-inline-start +PASS margin-left +PASS margin-right +PASS margin-top +PASS marker-end +PASS marker-mid +PASS marker-start +PASS mask-type +PASS math-depth +PASS math-shift +PASS math-style +PASS max-block-size +PASS max-height +PASS max-inline-size +PASS max-width +PASS min-block-size +PASS min-height +PASS min-inline-size +PASS min-width +PASS mix-blend-mode +PASS object-fit +PASS object-overflow +PASS object-position +PASS object-view-box +PASS offset-anchor +PASS offset-distance +PASS offset-path +PASS offset-position +PASS offset-rotate +PASS opacity +PASS order +PASS orphans +PASS outline-color +PASS outline-offset +PASS outline-style +PASS outline-width +PASS overflow-anchor +PASS overflow-block +PASS overflow-clip-margin +PASS overflow-inline +PASS overflow-wrap +PASS overflow-x +PASS overflow-y +PASS overscroll-behavior-block +PASS overscroll-behavior-inline +PASS padding-block-end +PASS padding-block-start +PASS padding-bottom +PASS padding-inline-end +PASS padding-inline-start +PASS padding-left +PASS padding-right +PASS padding-top +PASS paint-order +PASS perspective +FAIL perspective-origin assert_equals: Layer 3 should rollback to layer 2. expected "123px 0px" but got "0px 0px" +PASS pointer-events +PASS position +PASS r +PASS resize +PASS right +PASS rotate +PASS row-gap +PASS ruby-position +PASS rx +PASS ry +PASS scale +PASS scroll-behavior +PASS scroll-margin-block-end +PASS scroll-margin-block-start +PASS scroll-margin-inline-end +PASS scroll-margin-inline-start +PASS scroll-padding-block-end +PASS scroll-padding-block-start +PASS scroll-padding-inline-end +PASS scroll-padding-inline-start +PASS scrollbar-gutter +PASS scrollbar-width +PASS shape-image-threshold +PASS shape-margin +PASS shape-outside +PASS shape-rendering +PASS speak +PASS stop-color +PASS stop-opacity +PASS stroke +PASS stroke-dasharray +PASS stroke-dashoffset +PASS stroke-linecap +PASS stroke-linejoin +PASS stroke-miterlimit +PASS stroke-opacity +PASS stroke-width +PASS tab-size +PASS table-layout +PASS text-align +PASS text-align-last +PASS text-anchor +PASS text-decoration +PASS text-decoration-color +PASS text-decoration-line +PASS text-decoration-skip-ink +PASS text-decoration-style +PASS text-emphasis-color +PASS text-emphasis-position +PASS text-emphasis-style +PASS text-indent +PASS text-justify +PASS text-overflow +PASS text-rendering +PASS text-shadow +PASS text-size-adjust +PASS text-transform +PASS text-underline-position +PASS top +PASS touch-action +PASS transform +FAIL transform-origin assert_equals: Layer 3 should rollback to layer 2. expected "123px 123px 123px" but got "0px 0px" +PASS transform-style +PASS transition-delay +PASS transition-duration +PASS transition-property +PASS transition-timing-function +PASS translate +PASS unicode-bidi +PASS user-select +PASS vector-effect +PASS vertical-align +PASS visibility +PASS white-space +PASS widows +PASS width +PASS will-change +PASS word-break +PASS word-spacing +PASS writing-mode +PASS x +PASS y +PASS z-index +PASS zoom +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/css/css-cascade/all-prop-revert-layer.html b/third_party/blink/web_tests/external/wpt/css/css-cascade/all-prop-revert-layer.html new file mode 100644 index 0000000..b031e76 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-cascade/all-prop-revert-layer.html
@@ -0,0 +1,457 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Cascade: "all: revert-layer"</title> +<link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com"> +<link rel="help" href="https://www.w3.org/TR/css-cascade-5/#revert-layer"> +<meta name="assert" content="Checks that adding 'all: revert-layer' on the last layer has no effect."> +<style> +/* Set properties to a value different than the initial one. */ +#nothing { + accent-color: #123; + align-content: baseline; + align-items: baseline; + align-self: baseline; + align-tracks: baseline; + alignment-baseline: central; + alt: "a"; + animation-composition: add; + animation-delay: 123s; + animation-direction: reverse; + animation-duration: 123s; + animation-fill-mode: both; + animation-iteration-count: 123; + animation-name: \.; + animation-play-state: paused; + animation-timeline: none; + animation-timing-function: linear; + app-region: drag; + appearance: auto; + aspect-ratio: 3 / 4; + backdrop-filter: invert(1); + backface-visibility: hidden; + background-attachment: fixed; + background-blend-mode: overlay; + background-clip: content-box; + background-color: #123; + background-image: url("#ref"); + background-origin: border-box; + background-position: 123px; + background-repeat: round; + background-size: 123px; + baseline-shift: 123px; + block-size: 123px; + border-block-end: 123px dashed #123; + border-block-start: 123px dashed #123; + border-bottom: 123px dashed #123; + border-collapse: collapse; + border-end-end-radius: 123px; + border-end-start-radius: 123px; + border-image-outset: 123; + border-image-repeat: round; + border-image-slice: 123; + border-image-source: url("#ref"); + border-image-width: 123px; + border-inline-end: 123px dashed #123; + border-inline-start: 123px dashed #123; + border-left: 123px dashed #123; + border-radius: 123px; + border-right: 123px dashed #123; + border-start-end-radius: 123px; + border-start-start-radius: 123px; + border-spacing: 123px; + border-top: 123px dashed #123; + bottom: 123px; + box-decoration-break: clone; + box-shadow: #123 123px 123px 123px 123px; + box-sizing: border-box; + break-after: avoid; + break-before: avoid; + break-inside: avoid; + buffered-rendering: static; + caption-side: bottom; + caret-color: #123; + clear: both; + clip: rect(123px, 123px, 123px, 123px); + clip-path: url("#ref"); + clip-rule: evenodd; + color: #123; + color-interpolation: auto; + color-interpolation-filters: auto; + color-rendering: optimizespeed; + color-scheme: dark; + column-count: 123; + column-fill: auto; + column-gap: 123px; + column-rule-color: #123; + column-rule-style: dashed; + column-rule-width: 123px; + column-span: all; + column-width: 123px; + contain: size; + contain-intrinsic-block-size: 123px; + contain-intrinsic-inline-size: 123px; + contain-intrinsic-size: 123px 123px; + container-name: foo; + container-type: size; + content: "b"; + counter-increment: add 123; + counter-reset: add 123; + counter-set: add 123; + cursor: none; + cx: 123px; + cy: 123px; + d: path("M 1 1"); + direction: rtl; + display: flow-root; + dominant-baseline: middle; + empty-cells: hide; + fill: #123; + fill-opacity: 0.123; + fill-rule: evenodd; + filter: url("#ref"); + flex-basis: 123px; + flex-direction: column; + flex-grow: 123; + flex-shrink: 123; + flex-wrap: wrap; + float: right; + flood-color: #123; + flood-opacity: 0.123; + font-family: "c"; + font-feature-settings: "smcp"; + font-kerning: none; + font-language-override: "d"; + font-optical-sizing: none; + font-palette: dark; + font-size: 123px; + font-size-adjust: 123; + font-stretch: 123%; + font-style: italic; + font-synthesis: none; + font-variant-alternates: historical-forms; + font-variant-caps: small-caps; + font-variant-east-asian: full-width; + font-variant-ligatures: none; + font-variant-numeric: tabular-nums; + font-variant-position: super; + font-variation-settings: "smcp" 1; + font-weight: 123; + glyph-orientation-horizontal: 123deg; + glyph-orientation-vertical: 123deg; + grid-auto-columns: 123px; + grid-auto-flow: column; + grid-auto-rows: 123px; + grid-column-end: 123; + grid-column-start: 123; + grid-row-end: 123; + grid-row-start: 123; + grid-template-areas: "."; + grid-template-columns: 123fr; + grid-template-rows: 123fr; + hanging-punctuation: first; + height: 123px; + hyphenate-character: "e"; + hyphens: auto; + image-orientation: none; + image-rendering: pixelated; + ime-mode: normal; + initial-letter: 123; + inline-size: 123px; + input-security: none; + inset-block-end: 123px; + inset-block-start: 123px; + inset-inline-end: 123px; + inset-inline-start: 123px; + isolation: isolate; + justify-content: center; + justify-items: baseline; + justify-self: baseline; + justify-tracks: center; + kerning: 123px; + left: 123px; + letter-spacing: 123px; + lighting-color: #123; + line-break: anywhere; + line-height: 123px; + line-height-step: 123px; + list-style-image: url("#ref"); + list-style-position: inside; + list-style-type: square; + margin-block-end: 123px; + margin-block-start: 123px; + margin-bottom: 123px; + margin-inline-end: 123px; + margin-inline-start: 123px; + margin-left: 123px; + margin-right: 123px; + margin-top: 123px; + marker-end: url("#ref"); + marker-mid: url("#ref"); + marker-start: url("#ref"); + mask-clip: content-box; + mask-composite: exclude; + mask-image: url("#ref"); + mask-mode: alpha; + mask-origin: content-box; + mask-position-x: 123px; + mask-position-y: 123px; + mask-repeat: round; + mask-size: 123px; + mask-type: alpha; + masonry-auto-flow: ordered; + math-depth: 123; + math-shift: compact; + math-style: compact; + max-block-size: 123px; + max-height: 123px; + max-inline-size: 123px; + max-width: 123px; + min-block-size: 123px; + min-height: 123px; + min-inline-size: 123px; + min-width: 123px; + mix-blend-mode: overlay; + object-fit: contain; + object-overflow: visible; + object-position: 123px 123%; + object-view-box: inset(123px); + offset-anchor: 123px 123%; + offset-distance: 123px; + offset-path: path("M 1 1"); + offset-position: 123px; + offset-rotate: 123deg; + opacity: 0.123; + order: 123; + orphans: 123; + outline-color: #123; + outline-offset: 123px; + outline-style: auto; + outline-width: 123px; + overflow-anchor: none; + overflow-block: auto; + overflow-clip-margin: 123px; + overflow-inline: hidden; + overflow-wrap: anywhere; + overflow-x: auto; + overflow-y: hidden; + overscroll-behavior-block: contain; + overscroll-behavior-inline: contain; + overscroll-behavior-x: contain; + overscroll-behavior-y: contain; + padding-block-end: 123px; + padding-block-start: 123px; + padding-bottom: 123px; + padding-inline-end: 123px; + padding-inline-start: 123px; + padding-left: 123px; + padding-right: 123px; + padding-top: 123px; + paint-order: fill; + perspective: 123px; + perspective-origin: 123px 123%; + pointer-events: all; + position: relative; + print-color-adjust: exact; + quotes: none; + r: 123px; + resize: both; + right: 123px; + rotate: 123deg; + row-gap: 123px; + ruby-align: center; + ruby-position: under; + rx: 123px; + ry: 123px; + scale: 123; + scroll-behavior: smooth; + scroll-margin-block-end: 123px; + scroll-margin-block-start: 123px; + scroll-margin-bottom: 123px; + scroll-margin-inline-end: 123px; + scroll-margin-inline-start: 123px; + scroll-margin-left: 123px; + scroll-margin-right: 123px; + scroll-margin-top: 123px; + scroll-padding-block-end: 123px; + scroll-padding-block-start: 123px; + scroll-padding-bottom: 123px; + scroll-padding-inline-end: 123px; + scroll-padding-inline-start: 123px; + scroll-padding-left: 123px; + scroll-padding-right: 123px; + scroll-padding-top: 123px; + scroll-snap-align: center; + scroll-snap-stop: always; + scroll-snap-type: both; + scrollbar-color: #123 #123; + scrollbar-gutter: stable; + scrollbar-width: none; + shape-image-threshold: 123; + shape-margin: 123px; + shape-outside: border-box; + shape-rendering: optimizespeed; + speak: spell-out; + speak-as: spell-out; + stop-color: #123; + stop-opacity: 0.123; + stroke: #123; + stroke-color: #123; + stroke-dasharray: 123px; + stroke-dashoffset: 123px; + stroke-linecap: round; + stroke-linejoin: round; + stroke-miterlimit: 123; + stroke-opacity: 0.123; + stroke-width: 123px; + tab-size: 123; + table-layout: fixed; + text-align: center; + text-align-last: center; + text-anchor: middle; + text-combine-upright: all; + text-decoration-color: #123; + text-decoration-line: underline; + text-decoration-skip-ink: none; + text-decoration-style: dashed; + text-decoration-thickness: 123px; + text-emphasis-color: #123; + text-emphasis-position: under right; + text-emphasis-style: dot; + text-indent: 123px; + text-justify: none; + text-orientation: sideways; + text-overflow: ellipsis; + text-rendering: optimizespeed; + text-shadow: #123 123px 123px 123px; + text-size-adjust: none; + text-transform: lowercase; + text-underline-offset: 123px; + text-underline-position: under; + top: 123px; + touch-action: none; + transform: scale(-1); + transform-box: fill-box; + transform-origin: 123px 123px 123px; + transform-style: preserve-3d; + transition-delay: 123s; + transition-duration: 123s; + transition-property: add; + transition-timing-function: linear; + translate: 123px; + unicode-bidi: plaintext; + user-select: all; + vector-effect: non-scaling-stroke; + vertical-align: 123px; + visibility: collapse; + white-space: nowrap; + widows: 123; + width: 123px; + will-change: height; + word-break: break-word; + word-spacing: 123px; + word-wrap: break-word; + writing-mode: vertical-lr; + x: 123px; + y: 123px; + z-index: 123; + zoom: 123; +} + +@layer layer1 { + /* Reset properties to their initial value */ + #target { + all: initial; + } +} + +@layer layer2 { + /* This will be populated with properties set to a non-initial value */ + #target {} +} + +@layer layer3 { + /* This should roll back to the values from the previous layer */ + #target.rollback { + all: revert-layer; + } +} +</style> + +<div id="log"></div> + +<!-- This custom element is unlikely to get important UA styles --> +<foo-bar id="target"></foo-bar> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> +const { sheet } = document.querySelector("style"); +const nonInitialStyle = sheet.cssRules[0].style; +const layer2Style = sheet.cssRules[2].cssRules[0].style; + +const target = document.getElementById("target"); +const cs = getComputedStyle(target); + +// Some properties can be forced to compute to their initial value +// unless another property is set to a certain value. +function prerequisites(property) { + switch (property) { + case "border-block-end-width": + case "border-block-start-width": + case "border-bottom-width": + case "border-inline-end-width": + case "border-inline-start-width": + case "border-left-width": + case "border-right-width": + case "border-top-width": + return "border-style: solid"; + case "column-rule-width": + return "column-rule-style: solid"; + case "outline-width": + return "outline-style: solid"; + case "rotate": + case "scale": + case "transform": + case "transform-style": + case "translate": + return "display: block"; + default: + return ""; + } +} + +const initialValues = Object.create(null); +for (let property of cs) { + if (!property.startsWith("-")) { + initialValues[property] = cs.getPropertyValue(property); + } +} + +for (let property in initialValues) { + // Skip property if the stylesheet above doesn't provide a non-initial value. + // This is to avoid having to update the test every time a new CSS property is added. + const nonInitialValue = nonInitialStyle.getPropertyValue(property); + if (nonInitialValue === "") { + continue; + } + + test(function() { + const initialValue = initialValues[property]; + assert_not_equals(initialValue, "", "Should have the initial value."); + + this.add_cleanup(() => { + layer2Style.cssText = ""; + target.classList.remove("rollback"); + }); + + layer2Style.cssText = prerequisites(property); + layer2Style.setProperty(property, nonInitialValue); + const changedValue = cs.getPropertyValue(property); + assert_not_equals(changedValue, initialValue, "Should get a different computed value."); + + target.classList.add("rollback"); + const revertedValue = cs.getPropertyValue(property); + assert_equals(revertedValue, changedValue, "Layer 3 should rollback to layer 2."); + }, property); +} +</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/cssom/idlharness-expected.txt b/third_party/blink/web_tests/external/wpt/css/cssom/idlharness-expected.txt index 1977b31d..44af348 100644 --- a/third_party/blink/web_tests/external/wpt/css/cssom/idlharness-expected.txt +++ b/third_party/blink/web_tests/external/wpt/css/cssom/idlharness-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. -Found 452 tests; 396 PASS, 56 FAIL, 0 TIMEOUT, 0 NOTRUN. +Found 452 tests; 398 PASS, 54 FAIL, 0 TIMEOUT, 0 NOTRUN. PASS idl_test setup PASS idl_test validation PASS Partial interface CSSStyleSheet: original interface defined @@ -444,9 +444,9 @@ PASS Document interface: attribute styleSheets PASS Document interface: attribute adoptedStyleSheets PASS Document interface: document must inherit property "styleSheets" with the proper type -FAIL Document interface: document must inherit property "adoptedStyleSheets" with the proper type Right-hand side of 'instanceof' is not an object +PASS Document interface: document must inherit property "adoptedStyleSheets" with the proper type PASS Document interface: new Document() must inherit property "styleSheets" with the proper type -FAIL Document interface: new Document() must inherit property "adoptedStyleSheets" with the proper type Right-hand side of 'instanceof' is not an object +PASS Document interface: new Document() must inherit property "adoptedStyleSheets" with the proper type PASS ShadowRoot interface: attribute styleSheets PASS ShadowRoot interface: attribute adoptedStyleSheets PASS ProcessingInstruction interface: attribute sheet
diff --git a/third_party/blink/web_tests/external/wpt/preload/subresource-integrity-font.html b/third_party/blink/web_tests/external/wpt/preload/subresource-integrity-font.html new file mode 100644 index 0000000..da705dc --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/preload/subresource-integrity-font.html
@@ -0,0 +1,201 @@ +<!DOCTYPE html> +<title>Subresource Integrity for font +</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/preload/resources/preload_helper.js"></script> +<script src="/common/utils.js"></script> +<script src="/common/get-host-info.sub.js"></script> +<body> +<script> + const integrities = { + sha256: 'sha256-xkrni1nquuAzPoWieTZ22i9RONF4y11sJyWgYQDVlxE=', + sha384: 'sha384-Vif8vpq+J5UhnTqtncDDyol01dZx9nurRqQcSGtlCf0L1G8P+YeTyUYyZn4LMGrl', + sha512: 'sha512-CVkJJeS4/8zBdqBHmpzMvbI987MEWpTVd1Y/w20UFU0+NWlJAQpl1d3lIyCF97CQ/N+t/gn4IkWP4pjuWWrg6A==', + incorrect_sha256: 'sha256-wrongwrongwrongwrongwrongwrongwrongvalue====', + incorrect_sha512: 'sha512-wrongwrongwrongwrongwrongwrongwrongwrongwrongwrongwrongwrongwrongwrongwrongwrongwrong===', + unknown_algo: 'foo666-8aBiAJl3ukQwSJ6eTs5wl6hGjnOtyXjcTRdAf89uIfY=' + }; + + const run_test = (preload_success, main_load_success, name, + resource_url, extra_attributes, number_of_requests) => { + const test = async_test(name); + const link = document.createElement('link'); + link.rel = 'preload'; + link.as = 'font'; + link.href = resource_url; + + for (const attribute_name in extra_attributes) { + link[attribute_name] = extra_attributes[attribute_name]; + } + + const valid_preload_failed = test.step_func(() => { + assert_unreached('Valid preload fired error handler.'); + }); + const invalid_preload_succeeded = test.step_func(() => { + assert_unreached('Invalid preload load succeeded.'); + }); + const valid_main_load_failed = test.step_func(() => { + assert_unreached('Valid main load fired error handler.'); + }); + const invalid_main_load_succeeded = test.step_func(() => { + assert_unreached('Invalid main load succeeded.'); + }); + const main_load_pass = test.step_func(() => { + verifyNumberOfResourceTimingEntries(resource_url, number_of_requests); + test.done(); + }); + + const preload_pass = test.step_func(async () => { + try { + await new FontFace('CanvasTest', `url("${resource_url}")`).load(); + } catch (error) { + if (main_load_success) { + valid_main_load_failed(); + } else { + main_load_pass(); + } + } + + if (main_load_success) { + main_load_pass(); + } else { + invalid_main_load_succeeded(); + } + }); + + if (preload_success) { + link.onload = preload_pass; + link.onerror = valid_preload_failed; + } else { + link.onload = invalid_preload_succeeded; + link.onerror = preload_pass; + } + + document.body.appendChild(link); + }; + + verifyPreloadAndRTSupport(); + + const anonymous = '&pipe=header(Access-Control-Allow-Origin,*)'; + const use_credentials = '&pipe=header(Access-Control-Allow-Credentials,true)|' + + 'header(Access-Control-Allow-Origin,' + location.origin + ')'; + const cross_origin_prefix = get_host_info().REMOTE_ORIGIN; + const file_path = '/fonts/CanvasTest.ttf'; + + // Note: About preload + font + CORS + // + // The CSS Font spec defines that font files always have to be fetched using + // anonymous-mode CORS. + // + // https://developer.mozilla.org/en-US/docs/Web/HTML/Link_types/preload#cors-enabled_fetches + // https://www.w3.org/TR/css-fonts-3/#font-fetching-requirements + // + // So that font loading (@font-face in CSS and FontFace.load()) always + // sends requests with anonymous-mode CORS. The crossOrigin attribute of + // <link rel="preload" as="font"> should be set as anonymout mode, + // too, even for same origin fetch. Otherwise, main font loading + // doesn't match the corresponding preloading due to credentials + // mode mismatch and the main font loading invokes another request. + + // Needs CORS request even for same origin preload. + run_test(true, true, '<crossorigin="anonymous"> Same-origin with correct sha256 hash.', + file_path + '?' + token(), + {integrity: integrities.sha256, crossOrigin: 'anonymous'}, 1); + + run_test(true, true, '<crossorigin="anonymous"> Same-origin with correct sha384 hash.', + file_path + '?' + token(), + {integrity: integrities.sha384, crossOrigin: 'anonymous'}, 1); + + run_test(true, true, '<crossorigin="anonymous"> Same-origin with correct sha512 hash.', + file_path + '?' + token(), + {integrity: integrities.sha512, crossOrigin: 'anonymous'}, 1); + + run_test(true, true, '<crossorigin="anonymous"> Same-origin with empty integrity.', + file_path + '?' + token(), + {integrity: '', crossOrigin: 'anonymous'}, 1); + + run_test(true, true, '<crossorigin="anonymous"> Same-origin with no integrity.', + file_path + '?' + token(), + {crossOrigin: 'anonymous'}, 1); + + run_test(false, false, '<crossorigin="anonymous"> Same-origin with incorrect hash.', + file_path + '?' + token(), + {integrity: integrities.incorrect_sha256, crossOrigin: 'anonymous'}, 1); + + run_test(true, true, '<crossorigin="anonymous"> Same-origin with correct sha256 hash, options.', + file_path + '?' + token(), + {integrity: `${integrities.sha256}?foo=bar?spam=eggs`, crossOrigin: 'anonymous'}, 1); + + run_test(true, true, '<crossorigin="anonymous"> Same-origin with unknown algorithm only.', + file_path + '?' + token(), + {integrity: integrities.unknown_algo, crossOrigin: 'anonymous'}, 1); + + run_test(true, true, '<crossorigin="anonymous"> Same-origin with multiple sha256 hashes, including correct.', + file_path + '?' + token(), + {integrity: `${integrities.sha256} ${integrities.incorrect_sha256}`, crossOrigin: 'anonymous'}, 1); + + run_test(true, true, '<crossorigin="anonymous"> Same-origin with multiple sha256 hashes, including unknown algorithm.', + file_path + '?' + token(), + {integrity: `${integrities.sha256} ${integrities.unknown_algo}`, crossOrigin: 'anonymous'}, 1); + + run_test(true, true, '<crossorigin="anonymous"> Same-origin with sha256 mismatch, sha512 match.', + file_path + '?' + token(), + {integrity: `${integrities.incorrect_sha256} ${integrities.sha512}`, crossOrigin: 'anonymous'}, 1); + + run_test(false, false, '<crossorigin="anonymous"> Same-origin with sha256 match, sha512 mismatch.', + file_path + '?' + token(), + {integrity: `${integrities.sha256} ${integrities.incorrect_sha512}`, crossOrigin: 'anonymous'}, 1); + + // Main loading shouldn't match preloading due to credentials mode mismatch + // so the number of requests should be two. + run_test(true, true, 'Same-origin, not CORS request, with correct sha256 hash.', + file_path + '?' + token(), + {integrity: integrities.sha256}, 2); + + // Main loading shouldn't match preloading due to credentials mode mismatch + // and the main loading should invoke another request. The main font loading + // always sends CORS request and doesn't support SRI by itself, so it should succeed. + run_test(false, true, 'Same-origin, not CORS request, with incorrect sha256 hash.', + file_path + '?' + token(), + {integrity: integrities.incorrect_sha256}, 2); + + run_test(true, true, '<crossorigin="anonymous"> Cross-origin with correct sha256 hash, ACAO: *.', + cross_origin_prefix + file_path + '?' + token() + anonymous, + {integrity: integrities.sha256, crossOrigin: 'anonymous'}, 1); + + run_test(false, false, '<crossorigin="anonymous"> Cross-origin with incorrect sha256 hash, ACAO: *.', + cross_origin_prefix + file_path + '?' + token() + anonymous, + {integrity: integrities.incorrect_sha256, crossOrigin: 'anonymous'}, 1); + + run_test(false, false, '<crossorigin="anonymous"> Cross-origin with correct sha256 hash, with CORS-ineligible resource.', + cross_origin_prefix + file_path + '?' + token(), + {integrity: integrities.sha256, crossOrigin: 'anonymous'}, 1); + + run_test(false, true, 'Cross-origin, not CORS request, with correct sha256.', + cross_origin_prefix + file_path + '?' + token() + anonymous, + {integrity: integrities.sha256}, 2); + + run_test(false, true, 'Cross-origin, not CORS request, with incorrect sha256.', + cross_origin_prefix + file_path + '?' + token() + anonymous, + {integrity: integrities.incorrect_sha256}, 2); + + run_test(true, true, '<crossorigin="anonymous"> Cross-origin with empty integrity.', + cross_origin_prefix + file_path + '?' + token() + anonymous, + {integrity: '', crossOrigin: 'anonymous'}, 1); + + run_test(true, true, 'Cross-origin, not CORS request, with empty integrity.', + cross_origin_prefix + file_path + '?' + token() + anonymous, + {integrity: ''}, 2); + + // Non-anonymous mode CORS preload request should mismatch the main load. + run_test(true, true, '<crossorigin="use-credentials"> Cross-origin with correct sha256 hash, CORS-eligible.', + cross_origin_prefix + file_path + '?' + token() + use_credentials, + {integrity: integrities.sha256, crossOrigin: 'use-credentials'}, 2); + + run_test(false, true, '<crossorigin="use-credentials"> Cross-origin with incorrect sha256 hash, CORS-eligible.', + cross_origin_prefix + file_path + '?' + token() + use_credentials, + {integrity: integrities.incorrect_sha256, crossOrigin: 'use-credentials'}, 2); +</script> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/resources/idlharness.js b/third_party/blink/web_tests/external/wpt/resources/idlharness.js index 53ca06d..b5eed06 100644 --- a/third_party/blink/web_tests/external/wpt/resources/idlharness.js +++ b/third_party/blink/web_tests/external/wpt/resources/idlharness.js
@@ -962,7 +962,7 @@ return; } - if (type.generic === "sequence") + if (type.generic === "sequence" || type.generic == "ObservableArray") { assert_true(Array.isArray(value), "should be an Array"); if (!value.length)
diff --git a/third_party/blink/web_tests/external/wpt/secure-payment-confirmation/authentication-accepted.https.html b/third_party/blink/web_tests/external/wpt/secure-payment-confirmation/authentication-accepted.https.html index 2e9611f..1677de3 100644 --- a/third_party/blink/web_tests/external/wpt/secure-payment-confirmation/authentication-accepted.https.html +++ b/third_party/blink/web_tests/external/wpt/secure-payment-confirmation/authentication-accepted.https.html
@@ -42,6 +42,7 @@ } }], PAYMENT_DETAILS); + await test_driver.bless('user activation'); const responsePromise = request.show(); const response = await responsePromise;
diff --git a/third_party/blink/web_tests/external/wpt/secure-payment-confirmation/authentication-cross-origin.sub.https.html b/third_party/blink/web_tests/external/wpt/secure-payment-confirmation/authentication-cross-origin.sub.https.html index a9be91b8..efdb798 100644 --- a/third_party/blink/web_tests/external/wpt/secure-payment-confirmation/authentication-cross-origin.sub.https.html +++ b/third_party/blink/web_tests/external/wpt/secure-payment-confirmation/authentication-cross-origin.sub.https.html
@@ -47,6 +47,7 @@ } }], PAYMENT_DETAILS); + await test_driver.bless('user activation'); const responsePromise = request.show(); const response = await responsePromise;
diff --git a/third_party/blink/web_tests/external/wpt/secure-payment-confirmation/authentication-icon-data-url.https.html b/third_party/blink/web_tests/external/wpt/secure-payment-confirmation/authentication-icon-data-url.https.html index b4c01f3..dbdf666 100644 --- a/third_party/blink/web_tests/external/wpt/secure-payment-confirmation/authentication-icon-data-url.https.html +++ b/third_party/blink/web_tests/external/wpt/secure-payment-confirmation/authentication-icon-data-url.https.html
@@ -43,6 +43,7 @@ } }], PAYMENT_DETAILS); + await test_driver.bless('user activation'); const responsePromise = request.show(); const response = await responsePromise;
diff --git a/third_party/blink/web_tests/external/wpt/secure-payment-confirmation/authentication-in-iframe.sub.https.html b/third_party/blink/web_tests/external/wpt/secure-payment-confirmation/authentication-in-iframe.sub.https.html index b3a01e3..951b540 100644 --- a/third_party/blink/web_tests/external/wpt/secure-payment-confirmation/authentication-in-iframe.sub.https.html +++ b/third_party/blink/web_tests/external/wpt/secure-payment-confirmation/authentication-in-iframe.sub.https.html
@@ -36,7 +36,7 @@ // Wait for the iframe to load. const readyPromise = new Promise(resolve => { window.addEventListener('message', function handler(evt) { - if (evt.source === frame.contentWindow) { + if (evt.source === frame.contentWindow && evt.data.type == 'loaded') { window.removeEventListener('message', handler); resolve(evt.data); @@ -50,7 +50,7 @@ // race. const resultPromise = new Promise(resolve => { window.addEventListener('message', function handler(evt) { - if (evt.source === frame.contentWindow) { + if (evt.source === frame.contentWindow && evt.data.type == 'spc_result') { // We're done with the child iframe now. document.body.removeChild(frame); window.removeEventListener('message', handler);
diff --git a/third_party/blink/web_tests/external/wpt/secure-payment-confirmation/authentication-invalid-icon.https.html b/third_party/blink/web_tests/external/wpt/secure-payment-confirmation/authentication-invalid-icon.https.html index 8987c7b..84c629f 100644 --- a/third_party/blink/web_tests/external/wpt/secure-payment-confirmation/authentication-invalid-icon.https.html +++ b/third_party/blink/web_tests/external/wpt/secure-payment-confirmation/authentication-invalid-icon.https.html
@@ -42,6 +42,7 @@ }, } }], PAYMENT_DETAILS); + await test_driver.bless('user activation'); await promise_rejects_dom(t, "NotSupportedError", request.show()); // Now try an icon that cannot be decoded. @@ -59,6 +60,7 @@ }, } }], PAYMENT_DETAILS); + await test_driver.bless('user activation'); await promise_rejects_dom(t, "NotSupportedError", request.show()); }, 'SPC authentication with an invalid icon'); @@ -96,6 +98,7 @@ } }], PAYMENT_DETAILS); + await test_driver.bless('user activation'); const responsePromise = request.show(); const response = await responsePromise; await response.complete('success');
diff --git a/third_party/blink/web_tests/external/wpt/secure-payment-confirmation/authentication-rejected.https.html b/third_party/blink/web_tests/external/wpt/secure-payment-confirmation/authentication-rejected.https.html index 4973748b..444733b 100644 --- a/third_party/blink/web_tests/external/wpt/secure-payment-confirmation/authentication-rejected.https.html +++ b/third_party/blink/web_tests/external/wpt/secure-payment-confirmation/authentication-rejected.https.html
@@ -43,6 +43,7 @@ } }], PAYMENT_DETAILS); + await test_driver.bless('user activation'); return promise_rejects_dom(t, "NotAllowedError", request.show()); }, 'Rejected SPC authentication'); </script>
diff --git a/third_party/blink/web_tests/external/wpt/secure-payment-confirmation/authentication-requires-user-activation.https-expected.txt b/third_party/blink/web_tests/external/wpt/secure-payment-confirmation/authentication-requires-user-activation.https-expected.txt new file mode 100644 index 0000000..184762bb --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/secure-payment-confirmation/authentication-requires-user-activation.https-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +FAIL SPC authentication not allowed without a user activation promise_test: Unhandled rejection with value: object "Error: unimplemented" +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/secure-payment-confirmation/authentication-requires-user-activation.https.html b/third_party/blink/web_tests/external/wpt/secure-payment-confirmation/authentication-requires-user-activation.https.html new file mode 100644 index 0000000..6519086 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/secure-payment-confirmation/authentication-requires-user-activation.https.html
@@ -0,0 +1,48 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Test for the 'secure-payment-confirmation' payment method authentication - requires user activation</title> +<link rel="help" href="https://w3c.github.io/secure-payment-confirmation/sctn-authentication"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="utils.sub.js"></script> +<script> +'use strict'; + +promise_test(async t => { + const authenticator = await window.test_driver.add_virtual_authenticator( + AUTHENTICATOR_OPTS); + t.add_cleanup(() => { + return window.test_driver.remove_virtual_authenticator(authenticator); + }); + + await window.test_driver.set_spc_transaction_mode("autoaccept"); + t.add_cleanup(() => { + return window.test_driver.set_spc_transaction_mode("none"); + }); + + + const credential = await createCredential(); + + const challenge = 'server challenge'; + const payeeOrigin = 'https://merchant.com'; + const displayName = 'Troycard ***1234'; + const request = new PaymentRequest([{ + supportedMethods: 'secure-payment-confirmation', + data: { + credentialIds: [credential.rawId], + challenge: Uint8Array.from(challenge, c => c.charCodeAt(0)), + rpId: window.location.hostname, + payeeOrigin, + timeout: 60000, + instrument: { + displayName, + icon: ICON_URL, + }, + } + }], PAYMENT_DETAILS); + + return promise_rejects_dom(t, "SecurityError", request.show()); +}, 'SPC authentication not allowed without a user activation'); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/secure-payment-confirmation/resources/iframe-authenticate.html b/third_party/blink/web_tests/external/wpt/secure-payment-confirmation/resources/iframe-authenticate.html index 067cb58..e6a634ff 100644 --- a/third_party/blink/web_tests/external/wpt/secure-payment-confirmation/resources/iframe-authenticate.html +++ b/third_party/blink/web_tests/external/wpt/secure-payment-confirmation/resources/iframe-authenticate.html
@@ -1,6 +1,8 @@ <!DOCTYPE html> <meta charset="utf-8"> <title>SPC Authentication iframe</title> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> <script src="../utils.sub.js"></script> <script> 'use strict'; @@ -32,6 +34,8 @@ } }], PAYMENT_DETAILS); + test_driver.set_test_context(window.parent); + await test_driver.bless('user activation'); const responsePromise = request.show(); const response = await responsePromise; @@ -42,9 +46,9 @@ // Let our parent know the results. Some WebAuthn fields cannot be cloned, so // we have to do some teardown ourselves. const clientDataJSON = JSON.parse(arrayBufferToString(cred.response.clientDataJSON)) - window.parent.postMessage({ id: cred.id, clientDataJSON }, '*'); + window.parent.postMessage({ type: 'spc_result', id: cred.id, clientDataJSON }, '*'); }); // Now let our parent know that we are ready to receive the credential ID. -window.parent.postMessage(true, '*'); +window.parent.postMessage({ type: 'loaded' }, '*'); </script>
diff --git a/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/remove-script-element.html b/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/remove-script-element.html new file mode 100644 index 0000000..9de7656f --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/remove-script-element.html
@@ -0,0 +1,23 @@ +<!DOCTYPE html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/common/utils.js"></script> +<script src="resources/utils.js"></script> +<head> +<iframe id="iframe"></iframe> +<script> +setup(() => assertSpeculationRulesIsSupported()); + +async_test(t => { + const doc = iframe.contentDocument; + const script = doc.createElement('script'); + script.type = 'speculationrules'; + script.text = `{"prerender": [{"source": "list", "urls": [] }] }`; + doc.head.appendChild(script); + iframe.remove(); + t.step_timeout(() => { + document.head.appendChild(script); + t.done(); + }, 0); +}, 'Removing speculationrules script from detached document should not crash'); +</script>
diff --git a/third_party/blink/web_tests/flag-specific/highdpi/external/wpt/css/cssom/idlharness-expected.txt b/third_party/blink/web_tests/flag-specific/highdpi/external/wpt/css/cssom/idlharness-expected.txt new file mode 100644 index 0000000..8335ac6 --- /dev/null +++ b/third_party/blink/web_tests/flag-specific/highdpi/external/wpt/css/cssom/idlharness-expected.txt
@@ -0,0 +1,456 @@ +This is a testharness.js-based test. +Found 452 tests; 397 PASS, 55 FAIL, 0 TIMEOUT, 0 NOTRUN. +PASS idl_test setup +PASS idl_test validation +PASS Partial interface CSSStyleSheet: original interface defined +PASS Partial interface CSSStyleSheet: member names are unique +PASS Partial interface mixin DocumentOrShadowRoot: original interface mixin defined +PASS Partial interface mixin DocumentOrShadowRoot: member names are unique +PASS Partial interface Window: original interface defined +PASS Partial interface Window: member names are unique +PASS Partial interface mixin DocumentOrShadowRoot[2]: member names are unique +PASS Partial interface HTMLLinkElement: member names are unique +PASS Partial interface HTMLStyleElement: member names are unique +PASS Partial interface Window[2]: member names are unique +PASS ProcessingInstruction includes LinkStyle: member names are unique +PASS HTMLElement includes ElementCSSInlineStyle: member names are unique +PASS SVGElement includes ElementCSSInlineStyle: member names are unique +PASS MathMLElement includes ElementCSSInlineStyle: member names are unique +PASS SVGElement includes GlobalEventHandlers: member names are unique +PASS SVGElement includes DocumentAndElementEventHandlers: member names are unique +PASS SVGElement includes SVGElementInstance: member names are unique +PASS SVGElement includes HTMLOrSVGElement: member names are unique +PASS SVGStyleElement includes LinkStyle: member names are unique +PASS HTMLElement includes GlobalEventHandlers: member names are unique +PASS HTMLElement includes DocumentAndElementEventHandlers: member names are unique +PASS HTMLElement includes ElementContentEditable: member names are unique +PASS HTMLElement includes HTMLOrSVGElement: member names are unique +PASS HTMLLinkElement includes LinkStyle: member names are unique +PASS HTMLStyleElement includes LinkStyle: member names are unique +PASS Window includes GlobalEventHandlers: member names are unique +PASS Window includes WindowEventHandlers: member names are unique +PASS Window includes WindowOrWorkerGlobalScope: member names are unique +PASS Window includes AnimationFrameProvider: member names are unique +PASS Window includes WindowSessionStorage: member names are unique +PASS Window includes WindowLocalStorage: member names are unique +PASS Document includes NonElementParentNode: member names are unique +PASS DocumentFragment includes NonElementParentNode: member names are unique +PASS Document includes DocumentOrShadowRoot: member names are unique +PASS ShadowRoot includes DocumentOrShadowRoot: member names are unique +PASS Document includes ParentNode: member names are unique +PASS DocumentFragment includes ParentNode: member names are unique +PASS Element includes ParentNode: member names are unique +PASS Element includes NonDocumentTypeChildNode: member names are unique +PASS CharacterData includes NonDocumentTypeChildNode: member names are unique +PASS Element includes ChildNode: member names are unique +PASS CharacterData includes ChildNode: member names are unique +PASS Element includes Slottable: member names are unique +PASS Document includes XPathEvaluatorBase: member names are unique +PASS MathMLElement includes GlobalEventHandlers: member names are unique +PASS MathMLElement includes DocumentAndElementEventHandlers: member names are unique +PASS MathMLElement includes HTMLOrSVGElement: member names are unique +PASS MediaList interface: existence and properties of interface object +PASS MediaList interface object length +PASS MediaList interface object name +PASS MediaList interface: existence and properties of interface prototype object +PASS MediaList interface: existence and properties of interface prototype object's "constructor" property +PASS MediaList interface: existence and properties of interface prototype object's @@unscopables property +PASS MediaList interface: attribute mediaText +PASS MediaList interface: stringifier +PASS MediaList interface: attribute length +PASS MediaList interface: operation item(unsigned long) +PASS MediaList interface: operation appendMedium(CSSOMString) +PASS MediaList interface: operation deleteMedium(CSSOMString) +PASS MediaList must be primary interface of sheet.media +PASS Stringification of sheet.media +PASS MediaList interface: sheet.media must inherit property "mediaText" with the proper type +PASS MediaList interface: sheet.media must inherit property "length" with the proper type +PASS MediaList interface: sheet.media must inherit property "item(unsigned long)" with the proper type +PASS MediaList interface: calling item(unsigned long) on sheet.media with too few arguments must throw TypeError +PASS MediaList interface: sheet.media must inherit property "appendMedium(CSSOMString)" with the proper type +PASS MediaList interface: calling appendMedium(CSSOMString) on sheet.media with too few arguments must throw TypeError +PASS MediaList interface: sheet.media must inherit property "deleteMedium(CSSOMString)" with the proper type +PASS MediaList interface: calling deleteMedium(CSSOMString) on sheet.media with too few arguments must throw TypeError +PASS StyleSheet interface: existence and properties of interface object +PASS StyleSheet interface object length +PASS StyleSheet interface object name +PASS StyleSheet interface: existence and properties of interface prototype object +PASS StyleSheet interface: existence and properties of interface prototype object's "constructor" property +PASS StyleSheet interface: existence and properties of interface prototype object's @@unscopables property +PASS StyleSheet interface: attribute type +PASS StyleSheet interface: attribute href +PASS StyleSheet interface: attribute ownerNode +PASS StyleSheet interface: attribute parentStyleSheet +PASS StyleSheet interface: attribute title +PASS StyleSheet interface: attribute media +PASS StyleSheet interface: attribute disabled +PASS CSSStyleSheet interface: existence and properties of interface object +PASS CSSStyleSheet interface object length +PASS CSSStyleSheet interface object name +PASS CSSStyleSheet interface: existence and properties of interface prototype object +PASS CSSStyleSheet interface: existence and properties of interface prototype object's "constructor" property +PASS CSSStyleSheet interface: existence and properties of interface prototype object's @@unscopables property +PASS CSSStyleSheet interface: attribute ownerRule +PASS CSSStyleSheet interface: attribute cssRules +PASS CSSStyleSheet interface: operation insertRule(CSSOMString, optional unsigned long) +PASS CSSStyleSheet interface: operation deleteRule(unsigned long) +PASS CSSStyleSheet interface: operation replace(USVString) +PASS CSSStyleSheet interface: operation replaceSync(USVString) +PASS CSSStyleSheet interface: attribute rules +PASS CSSStyleSheet interface: operation addRule(optional DOMString, optional DOMString, optional unsigned long) +PASS CSSStyleSheet interface: operation removeRule(optional unsigned long) +PASS CSSStyleSheet must be primary interface of sheet +PASS Stringification of sheet +PASS CSSStyleSheet interface: sheet must inherit property "ownerRule" with the proper type +PASS CSSStyleSheet interface: sheet must inherit property "cssRules" with the proper type +PASS CSSStyleSheet interface: sheet must inherit property "insertRule(CSSOMString, optional unsigned long)" with the proper type +PASS CSSStyleSheet interface: calling insertRule(CSSOMString, optional unsigned long) on sheet with too few arguments must throw TypeError +PASS CSSStyleSheet interface: sheet must inherit property "deleteRule(unsigned long)" with the proper type +PASS CSSStyleSheet interface: calling deleteRule(unsigned long) on sheet with too few arguments must throw TypeError +PASS CSSStyleSheet interface: sheet must inherit property "replace(USVString)" with the proper type +PASS CSSStyleSheet interface: calling replace(USVString) on sheet with too few arguments must throw TypeError +PASS CSSStyleSheet interface: sheet must inherit property "replaceSync(USVString)" with the proper type +PASS CSSStyleSheet interface: calling replaceSync(USVString) on sheet with too few arguments must throw TypeError +PASS CSSStyleSheet interface: sheet must inherit property "rules" with the proper type +PASS CSSStyleSheet interface: sheet must inherit property "addRule(optional DOMString, optional DOMString, optional unsigned long)" with the proper type +PASS CSSStyleSheet interface: calling addRule(optional DOMString, optional DOMString, optional unsigned long) on sheet with too few arguments must throw TypeError +PASS CSSStyleSheet interface: sheet must inherit property "removeRule(optional unsigned long)" with the proper type +PASS CSSStyleSheet interface: calling removeRule(optional unsigned long) on sheet with too few arguments must throw TypeError +PASS StyleSheet interface: sheet must inherit property "type" with the proper type +PASS StyleSheet interface: sheet must inherit property "href" with the proper type +PASS StyleSheet interface: sheet must inherit property "ownerNode" with the proper type +PASS StyleSheet interface: sheet must inherit property "parentStyleSheet" with the proper type +PASS StyleSheet interface: sheet must inherit property "title" with the proper type +PASS StyleSheet interface: sheet must inherit property "media" with the proper type +PASS StyleSheet interface: sheet must inherit property "disabled" with the proper type +PASS StyleSheetList interface: existence and properties of interface object +PASS StyleSheetList interface object length +PASS StyleSheetList interface object name +PASS StyleSheetList interface: existence and properties of interface prototype object +PASS StyleSheetList interface: existence and properties of interface prototype object's "constructor" property +PASS StyleSheetList interface: existence and properties of interface prototype object's @@unscopables property +PASS StyleSheetList interface: operation item(unsigned long) +PASS StyleSheetList interface: attribute length +PASS StyleSheetList must be primary interface of document.styleSheets +PASS Stringification of document.styleSheets +PASS StyleSheetList interface: document.styleSheets must inherit property "item(unsigned long)" with the proper type +PASS StyleSheetList interface: calling item(unsigned long) on document.styleSheets with too few arguments must throw TypeError +PASS StyleSheetList interface: document.styleSheets must inherit property "length" with the proper type +PASS CSSRuleList interface: existence and properties of interface object +PASS CSSRuleList interface object length +PASS CSSRuleList interface object name +PASS CSSRuleList interface: existence and properties of interface prototype object +PASS CSSRuleList interface: existence and properties of interface prototype object's "constructor" property +PASS CSSRuleList interface: existence and properties of interface prototype object's @@unscopables property +PASS CSSRuleList interface: operation item(unsigned long) +PASS CSSRuleList interface: attribute length +PASS CSSRuleList must be primary interface of sheet.cssRules +PASS Stringification of sheet.cssRules +PASS CSSRuleList interface: sheet.cssRules must inherit property "item(unsigned long)" with the proper type +PASS CSSRuleList interface: calling item(unsigned long) on sheet.cssRules with too few arguments must throw TypeError +PASS CSSRuleList interface: sheet.cssRules must inherit property "length" with the proper type +PASS CSSRule interface: existence and properties of interface object +PASS CSSRule interface object length +PASS CSSRule interface object name +PASS CSSRule interface: existence and properties of interface prototype object +PASS CSSRule interface: existence and properties of interface prototype object's "constructor" property +PASS CSSRule interface: existence and properties of interface prototype object's @@unscopables property +PASS CSSRule interface: attribute cssText +PASS CSSRule interface: attribute parentRule +PASS CSSRule interface: attribute parentStyleSheet +PASS CSSRule interface: attribute type +PASS CSSRule interface: constant STYLE_RULE on interface object +PASS CSSRule interface: constant STYLE_RULE on interface prototype object +PASS CSSRule interface: constant CHARSET_RULE on interface object +PASS CSSRule interface: constant CHARSET_RULE on interface prototype object +PASS CSSRule interface: constant IMPORT_RULE on interface object +PASS CSSRule interface: constant IMPORT_RULE on interface prototype object +PASS CSSRule interface: constant MEDIA_RULE on interface object +PASS CSSRule interface: constant MEDIA_RULE on interface prototype object +PASS CSSRule interface: constant FONT_FACE_RULE on interface object +PASS CSSRule interface: constant FONT_FACE_RULE on interface prototype object +PASS CSSRule interface: constant PAGE_RULE on interface object +PASS CSSRule interface: constant PAGE_RULE on interface prototype object +FAIL CSSRule interface: constant MARGIN_RULE on interface object assert_own_property: expected property "MARGIN_RULE" missing +FAIL CSSRule interface: constant MARGIN_RULE on interface prototype object assert_own_property: expected property "MARGIN_RULE" missing +PASS CSSRule interface: constant NAMESPACE_RULE on interface object +PASS CSSRule interface: constant NAMESPACE_RULE on interface prototype object +PASS CSSStyleRule interface: existence and properties of interface object +PASS CSSStyleRule interface object length +PASS CSSStyleRule interface object name +PASS CSSStyleRule interface: existence and properties of interface prototype object +PASS CSSStyleRule interface: existence and properties of interface prototype object's "constructor" property +PASS CSSStyleRule interface: existence and properties of interface prototype object's @@unscopables property +PASS CSSStyleRule interface: attribute selectorText +PASS CSSStyleRule interface: attribute style +PASS CSSStyleRule must be primary interface of sheet.cssRules[4] +PASS Stringification of sheet.cssRules[4] +PASS CSSStyleRule interface: sheet.cssRules[4] must inherit property "selectorText" with the proper type +PASS CSSStyleRule interface: sheet.cssRules[4] must inherit property "style" with the proper type +PASS CSSRule interface: sheet.cssRules[4] must inherit property "cssText" with the proper type +PASS CSSRule interface: sheet.cssRules[4] must inherit property "parentRule" with the proper type +PASS CSSRule interface: sheet.cssRules[4] must inherit property "parentStyleSheet" with the proper type +PASS CSSRule interface: sheet.cssRules[4] must inherit property "type" with the proper type +PASS CSSRule interface: sheet.cssRules[4] must inherit property "STYLE_RULE" with the proper type +PASS CSSRule interface: sheet.cssRules[4] must inherit property "CHARSET_RULE" with the proper type +PASS CSSRule interface: sheet.cssRules[4] must inherit property "IMPORT_RULE" with the proper type +PASS CSSRule interface: sheet.cssRules[4] must inherit property "MEDIA_RULE" with the proper type +PASS CSSRule interface: sheet.cssRules[4] must inherit property "FONT_FACE_RULE" with the proper type +PASS CSSRule interface: sheet.cssRules[4] must inherit property "PAGE_RULE" with the proper type +FAIL CSSRule interface: sheet.cssRules[4] must inherit property "MARGIN_RULE" with the proper type assert_inherits: property "MARGIN_RULE" not found in prototype chain +PASS CSSRule interface: sheet.cssRules[4] must inherit property "NAMESPACE_RULE" with the proper type +PASS CSSImportRule interface: existence and properties of interface object +PASS CSSImportRule interface object length +PASS CSSImportRule interface object name +PASS CSSImportRule interface: existence and properties of interface prototype object +PASS CSSImportRule interface: existence and properties of interface prototype object's "constructor" property +PASS CSSImportRule interface: existence and properties of interface prototype object's @@unscopables property +PASS CSSImportRule interface: attribute href +PASS CSSImportRule interface: attribute media +PASS CSSImportRule interface: attribute styleSheet +PASS CSSImportRule must be primary interface of sheet.cssRules[0] +PASS Stringification of sheet.cssRules[0] +PASS CSSImportRule interface: sheet.cssRules[0] must inherit property "href" with the proper type +PASS CSSImportRule interface: sheet.cssRules[0] must inherit property "media" with the proper type +PASS CSSImportRule interface: sheet.cssRules[0] must inherit property "styleSheet" with the proper type +PASS CSSRule interface: sheet.cssRules[0] must inherit property "cssText" with the proper type +PASS CSSRule interface: sheet.cssRules[0] must inherit property "parentRule" with the proper type +PASS CSSRule interface: sheet.cssRules[0] must inherit property "parentStyleSheet" with the proper type +PASS CSSRule interface: sheet.cssRules[0] must inherit property "type" with the proper type +PASS CSSRule interface: sheet.cssRules[0] must inherit property "STYLE_RULE" with the proper type +PASS CSSRule interface: sheet.cssRules[0] must inherit property "CHARSET_RULE" with the proper type +PASS CSSRule interface: sheet.cssRules[0] must inherit property "IMPORT_RULE" with the proper type +PASS CSSRule interface: sheet.cssRules[0] must inherit property "MEDIA_RULE" with the proper type +PASS CSSRule interface: sheet.cssRules[0] must inherit property "FONT_FACE_RULE" with the proper type +PASS CSSRule interface: sheet.cssRules[0] must inherit property "PAGE_RULE" with the proper type +FAIL CSSRule interface: sheet.cssRules[0] must inherit property "MARGIN_RULE" with the proper type assert_inherits: property "MARGIN_RULE" not found in prototype chain +PASS CSSRule interface: sheet.cssRules[0] must inherit property "NAMESPACE_RULE" with the proper type +PASS CSSGroupingRule interface: existence and properties of interface object +PASS CSSGroupingRule interface object length +PASS CSSGroupingRule interface object name +PASS CSSGroupingRule interface: existence and properties of interface prototype object +PASS CSSGroupingRule interface: existence and properties of interface prototype object's "constructor" property +PASS CSSGroupingRule interface: existence and properties of interface prototype object's @@unscopables property +PASS CSSGroupingRule interface: attribute cssRules +FAIL CSSGroupingRule interface: operation insertRule(CSSOMString, optional unsigned long) assert_equals: property has wrong .length expected 1 but got 2 +PASS CSSGroupingRule interface: operation deleteRule(unsigned long) +FAIL CSSPageRule interface: existence and properties of interface object assert_equals: prototype of CSSPageRule is not CSSGroupingRule expected function "function CSSGroupingRule() { [native code] }" but got function "function CSSRule() { [native code] }" +PASS CSSPageRule interface object length +PASS CSSPageRule interface object name +FAIL CSSPageRule interface: existence and properties of interface prototype object assert_equals: prototype of CSSPageRule.prototype is not CSSGroupingRule.prototype expected object "[object CSSGroupingRule]" but got object "[object CSSRule]" +PASS CSSPageRule interface: existence and properties of interface prototype object's "constructor" property +PASS CSSPageRule interface: existence and properties of interface prototype object's @@unscopables property +PASS CSSPageRule interface: attribute selectorText +PASS CSSPageRule interface: attribute style +PASS CSSPageRule must be primary interface of sheet.cssRules[2] +PASS Stringification of sheet.cssRules[2] +PASS CSSPageRule interface: sheet.cssRules[2] must inherit property "selectorText" with the proper type +PASS CSSPageRule interface: sheet.cssRules[2] must inherit property "style" with the proper type +FAIL CSSGroupingRule interface: sheet.cssRules[2] must inherit property "cssRules" with the proper type assert_inherits: property "cssRules" not found in prototype chain +FAIL CSSGroupingRule interface: sheet.cssRules[2] must inherit property "insertRule(CSSOMString, optional unsigned long)" with the proper type assert_inherits: property "insertRule" not found in prototype chain +FAIL CSSGroupingRule interface: calling insertRule(CSSOMString, optional unsigned long) on sheet.cssRules[2] with too few arguments must throw TypeError assert_inherits: property "insertRule" not found in prototype chain +FAIL CSSGroupingRule interface: sheet.cssRules[2] must inherit property "deleteRule(unsigned long)" with the proper type assert_inherits: property "deleteRule" not found in prototype chain +FAIL CSSGroupingRule interface: calling deleteRule(unsigned long) on sheet.cssRules[2] with too few arguments must throw TypeError assert_inherits: property "deleteRule" not found in prototype chain +PASS CSSRule interface: sheet.cssRules[2] must inherit property "cssText" with the proper type +PASS CSSRule interface: sheet.cssRules[2] must inherit property "parentRule" with the proper type +PASS CSSRule interface: sheet.cssRules[2] must inherit property "parentStyleSheet" with the proper type +PASS CSSRule interface: sheet.cssRules[2] must inherit property "type" with the proper type +PASS CSSRule interface: sheet.cssRules[2] must inherit property "STYLE_RULE" with the proper type +PASS CSSRule interface: sheet.cssRules[2] must inherit property "CHARSET_RULE" with the proper type +PASS CSSRule interface: sheet.cssRules[2] must inherit property "IMPORT_RULE" with the proper type +PASS CSSRule interface: sheet.cssRules[2] must inherit property "MEDIA_RULE" with the proper type +PASS CSSRule interface: sheet.cssRules[2] must inherit property "FONT_FACE_RULE" with the proper type +PASS CSSRule interface: sheet.cssRules[2] must inherit property "PAGE_RULE" with the proper type +FAIL CSSRule interface: sheet.cssRules[2] must inherit property "MARGIN_RULE" with the proper type assert_inherits: property "MARGIN_RULE" not found in prototype chain +PASS CSSRule interface: sheet.cssRules[2] must inherit property "NAMESPACE_RULE" with the proper type +FAIL CSSMarginRule interface: existence and properties of interface object assert_own_property: self does not have own property "CSSMarginRule" expected property "CSSMarginRule" missing +FAIL CSSMarginRule interface object length assert_own_property: self does not have own property "CSSMarginRule" expected property "CSSMarginRule" missing +FAIL CSSMarginRule interface object name assert_own_property: self does not have own property "CSSMarginRule" expected property "CSSMarginRule" missing +FAIL CSSMarginRule interface: existence and properties of interface prototype object assert_own_property: self does not have own property "CSSMarginRule" expected property "CSSMarginRule" missing +FAIL CSSMarginRule interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "CSSMarginRule" expected property "CSSMarginRule" missing +FAIL CSSMarginRule interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "CSSMarginRule" expected property "CSSMarginRule" missing +FAIL CSSMarginRule interface: attribute name assert_own_property: self does not have own property "CSSMarginRule" expected property "CSSMarginRule" missing +FAIL CSSMarginRule interface: attribute style assert_own_property: self does not have own property "CSSMarginRule" expected property "CSSMarginRule" missing +FAIL CSSMarginRule must be primary interface of sheet.cssRules[2].cssRules[0] assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Cannot read properties of undefined (reading '0')" +FAIL Stringification of sheet.cssRules[2].cssRules[0] assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Cannot read properties of undefined (reading '0')" +FAIL CSSMarginRule interface: sheet.cssRules[2].cssRules[0] must inherit property "name" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Cannot read properties of undefined (reading '0')" +FAIL CSSMarginRule interface: sheet.cssRules[2].cssRules[0] must inherit property "style" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Cannot read properties of undefined (reading '0')" +FAIL CSSRule interface: sheet.cssRules[2].cssRules[0] must inherit property "cssText" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Cannot read properties of undefined (reading '0')" +FAIL CSSRule interface: sheet.cssRules[2].cssRules[0] must inherit property "parentRule" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Cannot read properties of undefined (reading '0')" +FAIL CSSRule interface: sheet.cssRules[2].cssRules[0] must inherit property "parentStyleSheet" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Cannot read properties of undefined (reading '0')" +FAIL CSSRule interface: sheet.cssRules[2].cssRules[0] must inherit property "type" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Cannot read properties of undefined (reading '0')" +FAIL CSSRule interface: sheet.cssRules[2].cssRules[0] must inherit property "STYLE_RULE" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Cannot read properties of undefined (reading '0')" +FAIL CSSRule interface: sheet.cssRules[2].cssRules[0] must inherit property "CHARSET_RULE" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Cannot read properties of undefined (reading '0')" +FAIL CSSRule interface: sheet.cssRules[2].cssRules[0] must inherit property "IMPORT_RULE" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Cannot read properties of undefined (reading '0')" +FAIL CSSRule interface: sheet.cssRules[2].cssRules[0] must inherit property "MEDIA_RULE" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Cannot read properties of undefined (reading '0')" +FAIL CSSRule interface: sheet.cssRules[2].cssRules[0] must inherit property "FONT_FACE_RULE" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Cannot read properties of undefined (reading '0')" +FAIL CSSRule interface: sheet.cssRules[2].cssRules[0] must inherit property "PAGE_RULE" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Cannot read properties of undefined (reading '0')" +FAIL CSSRule interface: sheet.cssRules[2].cssRules[0] must inherit property "MARGIN_RULE" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Cannot read properties of undefined (reading '0')" +FAIL CSSRule interface: sheet.cssRules[2].cssRules[0] must inherit property "NAMESPACE_RULE" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Cannot read properties of undefined (reading '0')" +PASS CSSNamespaceRule interface: existence and properties of interface object +PASS CSSNamespaceRule interface object length +PASS CSSNamespaceRule interface object name +PASS CSSNamespaceRule interface: existence and properties of interface prototype object +PASS CSSNamespaceRule interface: existence and properties of interface prototype object's "constructor" property +PASS CSSNamespaceRule interface: existence and properties of interface prototype object's @@unscopables property +PASS CSSNamespaceRule interface: attribute namespaceURI +PASS CSSNamespaceRule interface: attribute prefix +PASS CSSNamespaceRule must be primary interface of sheet.cssRules[1] +PASS Stringification of sheet.cssRules[1] +PASS CSSNamespaceRule interface: sheet.cssRules[1] must inherit property "namespaceURI" with the proper type +PASS CSSNamespaceRule interface: sheet.cssRules[1] must inherit property "prefix" with the proper type +PASS CSSRule interface: sheet.cssRules[1] must inherit property "cssText" with the proper type +PASS CSSRule interface: sheet.cssRules[1] must inherit property "parentRule" with the proper type +PASS CSSRule interface: sheet.cssRules[1] must inherit property "parentStyleSheet" with the proper type +PASS CSSRule interface: sheet.cssRules[1] must inherit property "type" with the proper type +PASS CSSRule interface: sheet.cssRules[1] must inherit property "STYLE_RULE" with the proper type +PASS CSSRule interface: sheet.cssRules[1] must inherit property "CHARSET_RULE" with the proper type +PASS CSSRule interface: sheet.cssRules[1] must inherit property "IMPORT_RULE" with the proper type +PASS CSSRule interface: sheet.cssRules[1] must inherit property "MEDIA_RULE" with the proper type +PASS CSSRule interface: sheet.cssRules[1] must inherit property "FONT_FACE_RULE" with the proper type +PASS CSSRule interface: sheet.cssRules[1] must inherit property "PAGE_RULE" with the proper type +FAIL CSSRule interface: sheet.cssRules[1] must inherit property "MARGIN_RULE" with the proper type assert_inherits: property "MARGIN_RULE" not found in prototype chain +PASS CSSRule interface: sheet.cssRules[1] must inherit property "NAMESPACE_RULE" with the proper type +PASS CSSStyleDeclaration interface: existence and properties of interface object +PASS CSSStyleDeclaration interface object length +PASS CSSStyleDeclaration interface object name +PASS CSSStyleDeclaration interface: existence and properties of interface prototype object +PASS CSSStyleDeclaration interface: existence and properties of interface prototype object's "constructor" property +PASS CSSStyleDeclaration interface: existence and properties of interface prototype object's @@unscopables property +PASS CSSStyleDeclaration interface: attribute cssText +PASS CSSStyleDeclaration interface: attribute length +PASS CSSStyleDeclaration interface: operation item(unsigned long) +PASS CSSStyleDeclaration interface: operation getPropertyValue(CSSOMString) +PASS CSSStyleDeclaration interface: operation getPropertyPriority(CSSOMString) +PASS CSSStyleDeclaration interface: operation setProperty(CSSOMString, CSSOMString, optional CSSOMString) +PASS CSSStyleDeclaration interface: operation removeProperty(CSSOMString) +PASS CSSStyleDeclaration interface: attribute parentRule +PASS CSSStyleDeclaration interface: attribute cssFloat +PASS CSSStyleDeclaration must be primary interface of sheet.cssRules[4].style +PASS Stringification of sheet.cssRules[4].style +PASS CSSStyleDeclaration interface: sheet.cssRules[4].style must inherit property "cssText" with the proper type +PASS CSSStyleDeclaration interface: sheet.cssRules[4].style must inherit property "length" with the proper type +PASS CSSStyleDeclaration interface: sheet.cssRules[4].style must inherit property "item(unsigned long)" with the proper type +PASS CSSStyleDeclaration interface: calling item(unsigned long) on sheet.cssRules[4].style with too few arguments must throw TypeError +PASS CSSStyleDeclaration interface: sheet.cssRules[4].style must inherit property "getPropertyValue(CSSOMString)" with the proper type +PASS CSSStyleDeclaration interface: calling getPropertyValue(CSSOMString) on sheet.cssRules[4].style with too few arguments must throw TypeError +PASS CSSStyleDeclaration interface: sheet.cssRules[4].style must inherit property "getPropertyPriority(CSSOMString)" with the proper type +PASS CSSStyleDeclaration interface: calling getPropertyPriority(CSSOMString) on sheet.cssRules[4].style with too few arguments must throw TypeError +PASS CSSStyleDeclaration interface: sheet.cssRules[4].style must inherit property "setProperty(CSSOMString, CSSOMString, optional CSSOMString)" with the proper type +PASS CSSStyleDeclaration interface: calling setProperty(CSSOMString, CSSOMString, optional CSSOMString) on sheet.cssRules[4].style with too few arguments must throw TypeError +PASS CSSStyleDeclaration interface: sheet.cssRules[4].style must inherit property "removeProperty(CSSOMString)" with the proper type +PASS CSSStyleDeclaration interface: calling removeProperty(CSSOMString) on sheet.cssRules[4].style with too few arguments must throw TypeError +PASS CSSStyleDeclaration interface: sheet.cssRules[4].style must inherit property "parentRule" with the proper type +PASS CSSStyleDeclaration interface: sheet.cssRules[4].style must inherit property "cssFloat" with the proper type +PASS CSSStyleDeclaration must be primary interface of sheet.cssRules[2].style +PASS Stringification of sheet.cssRules[2].style +PASS CSSStyleDeclaration interface: sheet.cssRules[2].style must inherit property "cssText" with the proper type +PASS CSSStyleDeclaration interface: sheet.cssRules[2].style must inherit property "length" with the proper type +PASS CSSStyleDeclaration interface: sheet.cssRules[2].style must inherit property "item(unsigned long)" with the proper type +PASS CSSStyleDeclaration interface: calling item(unsigned long) on sheet.cssRules[2].style with too few arguments must throw TypeError +PASS CSSStyleDeclaration interface: sheet.cssRules[2].style must inherit property "getPropertyValue(CSSOMString)" with the proper type +PASS CSSStyleDeclaration interface: calling getPropertyValue(CSSOMString) on sheet.cssRules[2].style with too few arguments must throw TypeError +PASS CSSStyleDeclaration interface: sheet.cssRules[2].style must inherit property "getPropertyPriority(CSSOMString)" with the proper type +PASS CSSStyleDeclaration interface: calling getPropertyPriority(CSSOMString) on sheet.cssRules[2].style with too few arguments must throw TypeError +PASS CSSStyleDeclaration interface: sheet.cssRules[2].style must inherit property "setProperty(CSSOMString, CSSOMString, optional CSSOMString)" with the proper type +PASS CSSStyleDeclaration interface: calling setProperty(CSSOMString, CSSOMString, optional CSSOMString) on sheet.cssRules[2].style with too few arguments must throw TypeError +PASS CSSStyleDeclaration interface: sheet.cssRules[2].style must inherit property "removeProperty(CSSOMString)" with the proper type +PASS CSSStyleDeclaration interface: calling removeProperty(CSSOMString) on sheet.cssRules[2].style with too few arguments must throw TypeError +PASS CSSStyleDeclaration interface: sheet.cssRules[2].style must inherit property "parentRule" with the proper type +PASS CSSStyleDeclaration interface: sheet.cssRules[2].style must inherit property "cssFloat" with the proper type +FAIL CSSStyleDeclaration must be primary interface of sheet.cssRules[2].cssRules[0].style assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Cannot read properties of undefined (reading '0')" +FAIL Stringification of sheet.cssRules[2].cssRules[0].style assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Cannot read properties of undefined (reading '0')" +FAIL CSSStyleDeclaration interface: sheet.cssRules[2].cssRules[0].style must inherit property "cssText" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Cannot read properties of undefined (reading '0')" +FAIL CSSStyleDeclaration interface: sheet.cssRules[2].cssRules[0].style must inherit property "length" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Cannot read properties of undefined (reading '0')" +FAIL CSSStyleDeclaration interface: sheet.cssRules[2].cssRules[0].style must inherit property "item(unsigned long)" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Cannot read properties of undefined (reading '0')" +FAIL CSSStyleDeclaration interface: calling item(unsigned long) on sheet.cssRules[2].cssRules[0].style with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Cannot read properties of undefined (reading '0')" +FAIL CSSStyleDeclaration interface: sheet.cssRules[2].cssRules[0].style must inherit property "getPropertyValue(CSSOMString)" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Cannot read properties of undefined (reading '0')" +FAIL CSSStyleDeclaration interface: calling getPropertyValue(CSSOMString) on sheet.cssRules[2].cssRules[0].style with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Cannot read properties of undefined (reading '0')" +FAIL CSSStyleDeclaration interface: sheet.cssRules[2].cssRules[0].style must inherit property "getPropertyPriority(CSSOMString)" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Cannot read properties of undefined (reading '0')" +FAIL CSSStyleDeclaration interface: calling getPropertyPriority(CSSOMString) on sheet.cssRules[2].cssRules[0].style with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Cannot read properties of undefined (reading '0')" +FAIL CSSStyleDeclaration interface: sheet.cssRules[2].cssRules[0].style must inherit property "setProperty(CSSOMString, CSSOMString, optional CSSOMString)" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Cannot read properties of undefined (reading '0')" +FAIL CSSStyleDeclaration interface: calling setProperty(CSSOMString, CSSOMString, optional CSSOMString) on sheet.cssRules[2].cssRules[0].style with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Cannot read properties of undefined (reading '0')" +FAIL CSSStyleDeclaration interface: sheet.cssRules[2].cssRules[0].style must inherit property "removeProperty(CSSOMString)" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Cannot read properties of undefined (reading '0')" +FAIL CSSStyleDeclaration interface: calling removeProperty(CSSOMString) on sheet.cssRules[2].cssRules[0].style with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Cannot read properties of undefined (reading '0')" +FAIL CSSStyleDeclaration interface: sheet.cssRules[2].cssRules[0].style must inherit property "parentRule" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Cannot read properties of undefined (reading '0')" +FAIL CSSStyleDeclaration interface: sheet.cssRules[2].cssRules[0].style must inherit property "cssFloat" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Cannot read properties of undefined (reading '0')" +PASS CSSStyleDeclaration must be primary interface of style_element.style +PASS Stringification of style_element.style +PASS CSSStyleDeclaration interface: style_element.style must inherit property "cssText" with the proper type +PASS CSSStyleDeclaration interface: style_element.style must inherit property "length" with the proper type +PASS CSSStyleDeclaration interface: style_element.style must inherit property "item(unsigned long)" with the proper type +PASS CSSStyleDeclaration interface: calling item(unsigned long) on style_element.style with too few arguments must throw TypeError +PASS CSSStyleDeclaration interface: style_element.style must inherit property "getPropertyValue(CSSOMString)" with the proper type +PASS CSSStyleDeclaration interface: calling getPropertyValue(CSSOMString) on style_element.style with too few arguments must throw TypeError +PASS CSSStyleDeclaration interface: style_element.style must inherit property "getPropertyPriority(CSSOMString)" with the proper type +PASS CSSStyleDeclaration interface: calling getPropertyPriority(CSSOMString) on style_element.style with too few arguments must throw TypeError +PASS CSSStyleDeclaration interface: style_element.style must inherit property "setProperty(CSSOMString, CSSOMString, optional CSSOMString)" with the proper type +PASS CSSStyleDeclaration interface: calling setProperty(CSSOMString, CSSOMString, optional CSSOMString) on style_element.style with too few arguments must throw TypeError +PASS CSSStyleDeclaration interface: style_element.style must inherit property "removeProperty(CSSOMString)" with the proper type +PASS CSSStyleDeclaration interface: calling removeProperty(CSSOMString) on style_element.style with too few arguments must throw TypeError +PASS CSSStyleDeclaration interface: style_element.style must inherit property "parentRule" with the proper type +PASS CSSStyleDeclaration interface: style_element.style must inherit property "cssFloat" with the proper type +PASS CSSStyleDeclaration must be primary interface of svg_element.style +PASS Stringification of svg_element.style +PASS CSSStyleDeclaration interface: svg_element.style must inherit property "cssText" with the proper type +PASS CSSStyleDeclaration interface: svg_element.style must inherit property "length" with the proper type +PASS CSSStyleDeclaration interface: svg_element.style must inherit property "item(unsigned long)" with the proper type +PASS CSSStyleDeclaration interface: calling item(unsigned long) on svg_element.style with too few arguments must throw TypeError +PASS CSSStyleDeclaration interface: svg_element.style must inherit property "getPropertyValue(CSSOMString)" with the proper type +PASS CSSStyleDeclaration interface: calling getPropertyValue(CSSOMString) on svg_element.style with too few arguments must throw TypeError +PASS CSSStyleDeclaration interface: svg_element.style must inherit property "getPropertyPriority(CSSOMString)" with the proper type +PASS CSSStyleDeclaration interface: calling getPropertyPriority(CSSOMString) on svg_element.style with too few arguments must throw TypeError +PASS CSSStyleDeclaration interface: svg_element.style must inherit property "setProperty(CSSOMString, CSSOMString, optional CSSOMString)" with the proper type +PASS CSSStyleDeclaration interface: calling setProperty(CSSOMString, CSSOMString, optional CSSOMString) on svg_element.style with too few arguments must throw TypeError +PASS CSSStyleDeclaration interface: svg_element.style must inherit property "removeProperty(CSSOMString)" with the proper type +PASS CSSStyleDeclaration interface: calling removeProperty(CSSOMString) on svg_element.style with too few arguments must throw TypeError +PASS CSSStyleDeclaration interface: svg_element.style must inherit property "parentRule" with the proper type +PASS CSSStyleDeclaration interface: svg_element.style must inherit property "cssFloat" with the proper type +PASS CSSStyleDeclaration must be primary interface of getComputedStyle(svg_element) +PASS Stringification of getComputedStyle(svg_element) +PASS CSSStyleDeclaration interface: getComputedStyle(svg_element) must inherit property "cssText" with the proper type +PASS CSSStyleDeclaration interface: getComputedStyle(svg_element) must inherit property "length" with the proper type +PASS CSSStyleDeclaration interface: getComputedStyle(svg_element) must inherit property "item(unsigned long)" with the proper type +PASS CSSStyleDeclaration interface: calling item(unsigned long) on getComputedStyle(svg_element) with too few arguments must throw TypeError +PASS CSSStyleDeclaration interface: getComputedStyle(svg_element) must inherit property "getPropertyValue(CSSOMString)" with the proper type +PASS CSSStyleDeclaration interface: calling getPropertyValue(CSSOMString) on getComputedStyle(svg_element) with too few arguments must throw TypeError +PASS CSSStyleDeclaration interface: getComputedStyle(svg_element) must inherit property "getPropertyPriority(CSSOMString)" with the proper type +PASS CSSStyleDeclaration interface: calling getPropertyPriority(CSSOMString) on getComputedStyle(svg_element) with too few arguments must throw TypeError +PASS CSSStyleDeclaration interface: getComputedStyle(svg_element) must inherit property "setProperty(CSSOMString, CSSOMString, optional CSSOMString)" with the proper type +PASS CSSStyleDeclaration interface: calling setProperty(CSSOMString, CSSOMString, optional CSSOMString) on getComputedStyle(svg_element) with too few arguments must throw TypeError +PASS CSSStyleDeclaration interface: getComputedStyle(svg_element) must inherit property "removeProperty(CSSOMString)" with the proper type +PASS CSSStyleDeclaration interface: calling removeProperty(CSSOMString) on getComputedStyle(svg_element) with too few arguments must throw TypeError +PASS CSSStyleDeclaration interface: getComputedStyle(svg_element) must inherit property "parentRule" with the proper type +PASS CSSStyleDeclaration interface: getComputedStyle(svg_element) must inherit property "cssFloat" with the proper type +PASS CSS namespace: extended attributes +PASS CSS namespace: property descriptor +PASS CSS namespace: [[Extensible]] is true +PASS CSS namespace: [[Prototype]] is Object.prototype +PASS CSS namespace: typeof is "object" +PASS CSS namespace: has no length property +PASS CSS namespace: has no name property +PASS CSS namespace: operation escape(CSSOMString) +PASS SVGElement interface: attribute style +PASS SVGElement interface: svg_element must inherit property "style" with the proper type +PASS SVGStyleElement interface: attribute sheet +PASS HTMLElement interface: attribute style +PASS HTMLElement interface: style_element must inherit property "style" with the proper type +PASS HTMLElement interface: document.createElement("unknownelement") must inherit property "style" with the proper type +PASS HTMLLinkElement interface: attribute sheet +PASS HTMLStyleElement interface: attribute sheet +PASS Window interface: operation getComputedStyle(Element, optional CSSOMString?) +PASS Window interface: window must inherit property "getComputedStyle(Element, optional CSSOMString?)" with the proper type +PASS Window interface: calling getComputedStyle(Element, optional CSSOMString?) on window with too few arguments must throw TypeError +PASS Document interface: attribute styleSheets +PASS Document interface: attribute adoptedStyleSheets +PASS Document interface: document must inherit property "styleSheets" with the proper type +PASS Document interface: document must inherit property "adoptedStyleSheets" with the proper type +PASS Document interface: new Document() must inherit property "styleSheets" with the proper type +PASS Document interface: new Document() must inherit property "adoptedStyleSheets" with the proper type +PASS ShadowRoot interface: attribute styleSheets +PASS ShadowRoot interface: attribute adoptedStyleSheets +PASS ProcessingInstruction interface: attribute sheet +PASS ProcessingInstruction interface: xmlss_pi must inherit property "sheet" with the proper type +FAIL MathMLElement interface: attribute style assert_own_property: self does not have own property "MathMLElement" expected property "MathMLElement" missing +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/flag-specific/highdpi/external/wpt/secure-payment-confirmation/authentication-requires-user-activation.https-expected.txt b/third_party/blink/web_tests/flag-specific/highdpi/external/wpt/secure-payment-confirmation/authentication-requires-user-activation.https-expected.txt new file mode 100644 index 0000000..184762bb --- /dev/null +++ b/third_party/blink/web_tests/flag-specific/highdpi/external/wpt/secure-payment-confirmation/authentication-requires-user-activation.https-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +FAIL SPC authentication not allowed without a user activation promise_test: Unhandled rejection with value: object "Error: unimplemented" +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/wpt_internal/fenced_frame/unfenced-top.https.html b/third_party/blink/web_tests/wpt_internal/fenced_frame/unfenced-top.https.html index a1ae72e..052ececc 100644 --- a/third_party/blink/web_tests/wpt_internal/fenced_frame/unfenced-top.https.html +++ b/third_party/blink/web_tests/wpt_internal/fenced_frame/unfenced-top.https.html
@@ -82,11 +82,12 @@ return [new_window, fenced_frame_url, nested_iframe_url]; } -async function checkNavigationSucceeded(new_window, new_referrer) { +async function checkNavigationSucceeded( + new_window, new_referrer, expected_history_length) { message_received = new Promise(resolve => window.onmessage = () => resolve()); // Check that the navigation happened in the correct frame. - await new_window.execute((expected_referrer) => { + await new_window.execute((expected_referrer, expected_history_length) => { assert_not_equals(window.opener, null, `The browsing context has a window.opener, because it is the top-level frame in the opened window.`); @@ -97,14 +98,17 @@ assert_equals(window.fenced_frame, undefined, `The browsing context has been refreshed, so old variables are gone.`); - }, [new_referrer]); + assert_equals(history.length, expected_history_length, + `The history length should be as expected.`); + }, [new_referrer, expected_history_length]); // Await the postMessage from inside the frame to confirm that the opener // is unchanged. await message_received; } -// Test successful top-level navigation from an opaque-ads fenced frame. +// Test successful top-level navigation (non-refresh) from an opaque-ads +// fenced frame. promise_test(async () => { // Create a new window, where we'll navigate the outermost frame. // (We can't do it in this window, or we'd lose the testing harness.) @@ -112,6 +116,11 @@ // become the document.referrer of the navigated outermost frame). const [new_window, new_referrer,] = await createAndValidateWindow(); + // Check the history length before navigation. + const history_length = await new_window.execute(() => { + return history.length; + }); + // Navigate the window's top-level frame from inside the fenced frame. // (Navigate to the original URL, i.e. refresh the page, so that we can // still communicate via RemoteContext.) @@ -120,6 +129,31 @@ await new_window.execute(() => { window.executor.suspend(() => { window.fenced_frame.execute((refresh_url) => { + var norefresh_url = new URL(refresh_url); + norefresh_url.searchParams.append('norefresh', ''); + const window_handle = window.open(norefresh_url, '_unfencedTop'); + assert_equals(window_handle, null, + `There should be no window handle returned from + navigations through _unfencedTop.`); + }, [location.href]); + }); + }); + + // Because this is a non-refresh navigation, the history should be extended. + await checkNavigationSucceeded(new_window, new_referrer, history_length+1); +}, '_unfencedTop opaque-ads non-refresh success case'); + +// Test successful top-level refresh from an opaque-ads fenced frame. +promise_test(async () => { + const [new_window, new_referrer,] = await createAndValidateWindow(); + + const history_length = await new_window.execute(() => { + return history.length; + }); + + await new_window.execute(() => { + window.executor.suspend(() => { + window.fenced_frame.execute((refresh_url) => { const window_handle = window.open(refresh_url, '_unfencedTop'); assert_equals(window_handle, null, `There should be no window handle returned from @@ -128,21 +162,29 @@ }); }); - await checkNavigationSucceeded(new_window, new_referrer); -}, '_unfencedTop opaque-ads success case'); + // Because this is a refresh, the history should not be extended. + await checkNavigationSucceeded(new_window, new_referrer, history_length); +}, '_unfencedTop opaque-ads refresh success case'); -// Test successful top-level navigation out of an iframe nested inside an -// opaque-ads fenced frame. +// Test successful top-level navigation (non-refresh) out of an iframe nested +// inside an opaque-ads fenced frame. promise_test(async () => { const [new_window,, new_referrer] = await createAndValidateWindow(); + // Check the history length before navigation. + const history_length = await new_window.execute(() => { + return history.length; + }); + // Navigate the window's top-level frame from inside the fenced frame's // nested iframe. await new_window.execute(() => { window.executor.suspend(() => { window.fenced_frame.execute((refresh_url) => { window.nested_iframe.execute((refresh_url) => { - const window_handle = window.open(refresh_url, '_unfencedTop'); + var norefresh_url = new URL(refresh_url); + norefresh_url.searchParams.append('norefresh', ''); + const window_handle = window.open(norefresh_url, '_unfencedTop'); assert_equals(window_handle, null, `There should be no window handle returned from navigations through _unfencedTop.`); @@ -151,7 +193,8 @@ }); }); - await checkNavigationSucceeded(new_window, new_referrer); + // Because this is a non-refresh navigation, the history should be extended. + await checkNavigationSucceeded(new_window, new_referrer, history_length+1); }, '_unfencedTop opaque-ads nested iframe success case'); // Test unsuccessful navigation out of a fenced frame using _unfencedTop and
diff --git a/third_party/blink/web_tests/wpt_internal/webgpu/cts.https.html b/third_party/blink/web_tests/wpt_internal/webgpu/cts.https.html index fb66736..73ffb23 100644 --- a/third_party/blink/web_tests/wpt_internal/webgpu/cts.https.html +++ b/third_party/blink/web_tests/wpt_internal/webgpu/cts.https.html
@@ -2785,12 +2785,22 @@ <meta name=variant content='?q=webgpu:shader,execution,expression,binary,f32_logical:less_equals:*'> <meta name=variant content='?q=webgpu:shader,execution,expression,binary,f32_logical:greater_than:*'> <meta name=variant content='?q=webgpu:shader,execution,expression,binary,f32_logical:greater_equals:*'> +<meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,abs:abstract_int:*'> <meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,abs:u32:*'> <meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,abs:i32:*'> +<meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,abs:abstract_float:*'> <meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,abs:f32:*'> +<meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,abs:f16:*'> +<meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,acos:abstract_float:*'> +<meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,acos:f32:*'> +<meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,acos:f16:*'> <meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,all:bool:*'> <meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,any:bool:*'> +<meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,arrayLength:array:*'> +<meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,atan:abstract_float:*'> <meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,atan:f32:*'> +<meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,atan:f16:*'> +<meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,atan2:abstract_float:*'> <meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,atan2:f32:storageClass="uniform";vectorize="_undef_";*'> <meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,atan2:f32:storageClass="uniform";vectorize=2;*'> <meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,atan2:f32:storageClass="uniform";vectorize=3;*'> @@ -2803,44 +2813,92 @@ <meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,atan2:f32:storageClass="storage_rw";vectorize=2;*'> <meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,atan2:f32:storageClass="storage_rw";vectorize=3;*'> <meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,atan2:f32:storageClass="storage_rw";vectorize=4;*'> +<meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,atan2:f16:*'> +<meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,ceil:abstract_float:*'> <meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,ceil:f32:*'> +<meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,ceil:f16:*'> +<meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,clamp:abstract_int:*'> <meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,clamp:u32:*'> <meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,clamp:i32:*'> +<meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,clamp:abstract_float:*'> <meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,clamp:f32:*'> +<meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,clamp:f16:*'> +<meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,cos:abstract_float:*'> <meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,cos:f32:*'> +<meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,cos:f16:*'> +<meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,cosh:abstract_float:*'> +<meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,cosh:f32:*'> +<meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,cosh:f16:*'> <meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,countLeadingZeros:u32:*'> <meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,countLeadingZeros:i32:*'> <meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,countOneBits:u32:*'> <meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,countOneBits:i32:*'> <meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,countTrailingZeros:u32:*'> <meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,countTrailingZeros:i32:*'> +<meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,cross:abstract_float:*'> +<meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,cross:f32:*'> +<meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,cross:f16:*'> +<meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,exp:abstract_float:*'> +<meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,exp:f32:*'> +<meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,exp:f16:*'> +<meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,exp2:abstract_float:*'> +<meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,exp2:f32:*'> +<meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,exp2:f16:*'> <meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,extractBits:u32:*'> <meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,extractBits:i32:*'> +<meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,faceForward:abstract_float:*'> +<meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,faceForward:f32:*'> +<meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,faceForward:f16:*'> <meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,firstLeadingBit:u32:*'> <meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,firstLeadingBit:i32:*'> <meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,firstTrailingBit:u32:*'> <meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,firstTrailingBit:i32:*'> +<meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,floor:abstract_float:*'> <meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,floor:f32:*'> +<meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,floor:f16:*'> +<meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,fma:abstract_float:*'> +<meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,fma:f32:*'> +<meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,fma:f16:*'> +<meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,fract:abstract_float:*'> <meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,fract:f32:*'> +<meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,fract:f16:*'> +<meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,frexp:scalar_f32:*'> +<meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,frexp:scalar_f16:*'> +<meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,frexp:vector_f32:*'> +<meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,frexp:vector_f16:*'> <meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,insertBits:integer:*'> +<meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,inversesqrt:abstract_float:*'> <meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,inversesqrt:f32:*'> +<meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,inversesqrt:f16:*'> +<meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,ldexp:abstract_float:*'> <meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,ldexp:f32:*'> +<meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,ldexp:f16:*'> +<meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,log:abstract_float:*'> <meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,log:f32:*'> +<meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,log:f16:*'> +<meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,log2:abstract_float:*'> <meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,log2:f32:*'> -<meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,logical_built_in_functions:logical_builtin_functions,scalar_select:*'> -<meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,logical_built_in_functions:logical_builtin_functions,vector_select:*'> +<meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,log2:f16:*'> +<meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,max:abstract_int:*'> <meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,max:u32:*'> <meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,max:i32:*'> +<meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,max:abstract_float:*'> <meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,max:f32:*'> +<meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,max:f16:*'> +<meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,min:abstract_int:*'> <meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,min:u32:*'> <meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,min:i32:*'> +<meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,min:abstract_float:*'> <meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,min:f32:*'> -<meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,reverseBits:unsigned:*'> -<meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,reverseBits:signed:*'> -<meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,select:bool:*'> +<meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,min:f16:*'> +<meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,quantizeToF16:f32:*'> +<meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,reverseBits:u32:*'> +<meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,reverseBits:i32:*'> +<meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,select:scalar:*'> <meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,select:vector:*'> +<meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,sin:abstract_float:*'> <meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,sin:f32:*'> -<meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,value_testing_built_in_functions:value_testing_builtin_functions,runtime_sized_array_length:*'> +<meta name=variant content='?q=webgpu:shader,execution,expression,call,builtin,sin:f16:*'> <meta name=variant content='?q=webgpu:shader,execution,expression,unary,f32_arithmetic:negation:*'> <meta name=variant content='?q=webgpu:shader,execution,memory_model,atomicity:atomicity:memType="atomic_storage";testType="inter_workgroup"'> <meta name=variant content='?q=webgpu:shader,execution,memory_model,atomicity:atomicity:memType="atomic_storage";testType="intra_workgroup";*'> @@ -3311,9 +3369,11 @@ <meta name=variant content='?q=webgpu:shader,validation,shader_io,interpolate:type_and_sampling:*'> <meta name=variant content='?q=webgpu:shader,validation,shader_io,interpolate:require_location:*'> <meta name=variant content='?q=webgpu:shader,validation,shader_io,interpolate:integral_types:*'> +<meta name=variant content='?q=webgpu:shader,validation,shader_io,interpolate:duplicate:*'> <meta name=variant content='?q=webgpu:shader,validation,shader_io,invariant:valid_only_with_vertex_position_builtin:*'> <meta name=variant content='?q=webgpu:shader,validation,shader_io,invariant:not_valid_on_user_defined_io:*'> <meta name=variant content='?q=webgpu:shader,validation,shader_io,invariant:invalid_use_of_parameters:*'> +<meta name=variant content='?q=webgpu:shader,validation,shader_io,invariant:duplicate:*'> <meta name=variant content='?q=webgpu:shader,validation,shader_io,locations:stage_inout:*'> <meta name=variant content='?q=webgpu:shader,validation,shader_io,locations:type:*'> <meta name=variant content='?q=webgpu:shader,validation,shader_io,locations:nesting:*'>
diff --git a/third_party/webgpu-cts/ts_sources.txt b/third_party/webgpu-cts/ts_sources.txt index 65eb912..c34eee2c 100644 --- a/third_party/webgpu-cts/ts_sources.txt +++ b/third_party/webgpu-cts/ts_sources.txt
@@ -269,33 +269,41 @@ src/webgpu/shader/execution/expression/binary/f32_logical.spec.ts src/webgpu/shader/execution/expression/call/builtin/builtin.ts src/webgpu/shader/execution/expression/call/builtin/abs.spec.ts +src/webgpu/shader/execution/expression/call/builtin/acos.spec.ts src/webgpu/shader/execution/expression/call/builtin/all.spec.ts src/webgpu/shader/execution/expression/call/builtin/any.spec.ts +src/webgpu/shader/execution/expression/call/builtin/arrayLength.spec.ts src/webgpu/shader/execution/expression/call/builtin/atan.spec.ts src/webgpu/shader/execution/expression/call/builtin/atan2.spec.ts src/webgpu/shader/execution/expression/call/builtin/ceil.spec.ts src/webgpu/shader/execution/expression/call/builtin/clamp.spec.ts src/webgpu/shader/execution/expression/call/builtin/cos.spec.ts +src/webgpu/shader/execution/expression/call/builtin/cosh.spec.ts src/webgpu/shader/execution/expression/call/builtin/countLeadingZeros.spec.ts src/webgpu/shader/execution/expression/call/builtin/countOneBits.spec.ts src/webgpu/shader/execution/expression/call/builtin/countTrailingZeros.spec.ts +src/webgpu/shader/execution/expression/call/builtin/cross.spec.ts +src/webgpu/shader/execution/expression/call/builtin/exp.spec.ts +src/webgpu/shader/execution/expression/call/builtin/exp2.spec.ts src/webgpu/shader/execution/expression/call/builtin/extractBits.spec.ts +src/webgpu/shader/execution/expression/call/builtin/faceForward.spec.ts src/webgpu/shader/execution/expression/call/builtin/firstLeadingBit.spec.ts src/webgpu/shader/execution/expression/call/builtin/firstTrailingBit.spec.ts src/webgpu/shader/execution/expression/call/builtin/floor.spec.ts +src/webgpu/shader/execution/expression/call/builtin/fma.spec.ts src/webgpu/shader/execution/expression/call/builtin/fract.spec.ts +src/webgpu/shader/execution/expression/call/builtin/frexp.spec.ts src/webgpu/shader/execution/expression/call/builtin/insertBits.spec.ts src/webgpu/shader/execution/expression/call/builtin/inversesqrt.spec.ts src/webgpu/shader/execution/expression/call/builtin/ldexp.spec.ts src/webgpu/shader/execution/expression/call/builtin/log.spec.ts src/webgpu/shader/execution/expression/call/builtin/log2.spec.ts -src/webgpu/shader/execution/expression/call/builtin/logical_built_in_functions.spec.ts src/webgpu/shader/execution/expression/call/builtin/max.spec.ts src/webgpu/shader/execution/expression/call/builtin/min.spec.ts +src/webgpu/shader/execution/expression/call/builtin/quantizeToF16.spec.ts src/webgpu/shader/execution/expression/call/builtin/reverseBits.spec.ts src/webgpu/shader/execution/expression/call/builtin/select.spec.ts src/webgpu/shader/execution/expression/call/builtin/sin.spec.ts -src/webgpu/shader/execution/expression/call/builtin/value_testing_built_in_functions.spec.ts src/webgpu/shader/execution/expression/unary/unary.ts src/webgpu/shader/execution/expression/unary/f32_arithmetic.spec.ts src/webgpu/shader/execution/memory_model/memory_model_setup.ts
diff --git a/third_party/zlib/crc32.c b/third_party/zlib/crc32.c index ee8d4725..41fe8915 100644 --- a/third_party/zlib/crc32.c +++ b/third_party/zlib/crc32.c
@@ -622,6 +622,123 @@ return (const z_crc_t FAR *)crc_table; } +/* ========================================================================= + * Use ARM machine instructions if available. This will compute the CRC about + * ten times faster than the braided calculation. This code does not check for + * the presence of the CRC instruction at run time. __ARM_FEATURE_CRC32 will + * only be defined if the compilation specifies an ARM processor architecture + * that has the instructions. For example, compiling with -march=armv8.1-a or + * -march=armv8-a+crc, or -march=native if the compile machine has the crc32 + * instructions. + */ +#if defined(__aarch64__) && defined(__ARM_FEATURE_CRC32) && W == 8 \ + && defined(USE_CANONICAL_ARMV8_CRC32) + +/* + Constants empirically determined to maximize speed. These values are from + measurements on a Cortex-A57. Your mileage may vary. + */ +#define Z_BATCH 3990 /* number of words in a batch */ +#define Z_BATCH_ZEROS 0xa10d3d0c /* computed from Z_BATCH = 3990 */ +#define Z_BATCH_MIN 800 /* fewest words in a final batch */ + +unsigned long ZEXPORT crc32_z(crc, buf, len) + unsigned long crc; + const unsigned char FAR *buf; + z_size_t len; +{ + z_crc_t val; + z_word_t crc1, crc2; + const z_word_t *word; + z_word_t val0, val1, val2; + z_size_t last, last2, i; + z_size_t num; + + /* Return initial CRC, if requested. */ + if (buf == Z_NULL) return 0; + +#ifdef DYNAMIC_CRC_TABLE + once(&made, make_crc_table); +#endif /* DYNAMIC_CRC_TABLE */ + + /* Pre-condition the CRC */ + crc ^= 0xffffffff; + + /* Compute the CRC up to a word boundary. */ + while (len && ((z_size_t)buf & 7) != 0) { + len--; + val = *buf++; + __asm__ volatile("crc32b %w0, %w0, %w1" : "+r"(crc) : "r"(val)); + } + + /* Prepare to compute the CRC on full 64-bit words word[0..num-1]. */ + word = (z_word_t const *)buf; + num = len >> 3; + len &= 7; + + /* Do three interleaved CRCs to realize the throughput of one crc32x + instruction per cycle. Each CRC is calcuated on Z_BATCH words. The three + CRCs are combined into a single CRC after each set of batches. */ + while (num >= 3 * Z_BATCH) { + crc1 = 0; + crc2 = 0; + for (i = 0; i < Z_BATCH; i++) { + val0 = word[i]; + val1 = word[i + Z_BATCH]; + val2 = word[i + 2 * Z_BATCH]; + __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc) : "r"(val0)); + __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc1) : "r"(val1)); + __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc2) : "r"(val2)); + } + word += 3 * Z_BATCH; + num -= 3 * Z_BATCH; + crc = multmodp(Z_BATCH_ZEROS, crc) ^ crc1; + crc = multmodp(Z_BATCH_ZEROS, crc) ^ crc2; + } + + /* Do one last smaller batch with the remaining words, if there are enough + to pay for the combination of CRCs. */ + last = num / 3; + if (last >= Z_BATCH_MIN) { + last2 = last << 1; + crc1 = 0; + crc2 = 0; + for (i = 0; i < last; i++) { + val0 = word[i]; + val1 = word[i + last]; + val2 = word[i + last2]; + __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc) : "r"(val0)); + __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc1) : "r"(val1)); + __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc2) : "r"(val2)); + } + word += 3 * last; + num -= 3 * last; + val = x2nmodp(last, 6); + crc = multmodp(val, crc) ^ crc1; + crc = multmodp(val, crc) ^ crc2; + } + + /* Compute the CRC on any remaining words. */ + for (i = 0; i < num; i++) { + val0 = word[i]; + __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc) : "r"(val0)); + } + word += num; + + /* Complete the CRC on any remaining bytes. */ + buf = (const unsigned char FAR *)word; + while (len) { + len--; + val = *buf++; + __asm__ volatile("crc32b %w0, %w0, %w1" : "+r"(crc) : "r"(val)); + } + + /* Return the CRC, post-conditioned. */ + return crc ^ 0xffffffff; +} + +#else + /* ========================================================================= */ unsigned long ZEXPORT crc32_z(crc, buf, len) unsigned long crc; @@ -974,6 +1091,8 @@ return crc ^ 0xffffffff; } +#endif + /* ========================================================================= */ unsigned long ZEXPORT crc32(crc, buf, len) unsigned long crc;
diff --git a/third_party/zlib/zlib.h b/third_party/zlib/zlib.h index a176f93..88961b9 100644 --- a/third_party/zlib/zlib.h +++ b/third_party/zlib/zlib.h
@@ -1690,8 +1690,9 @@ ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); /* Update a running Adler-32 checksum with the bytes buf[0..len-1] and - return the updated checksum. If buf is Z_NULL, this function returns the - required initial value for the checksum. + return the updated checksum. An Adler-32 value is in the range of a 32-bit + unsigned integer. If buf is Z_NULL, this function returns the required + initial value for the checksum. An Adler-32 checksum is almost as reliable as a CRC-32 but can be computed much faster. @@ -1727,9 +1728,10 @@ ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); /* Update a running CRC-32 with the bytes buf[0..len-1] and return the - updated CRC-32. If buf is Z_NULL, this function returns the required - initial value for the crc. Pre- and post-conditioning (one's complement) is - performed within this function so it shouldn't be done by the application. + updated CRC-32. A CRC-32 value is in the range of a 32-bit unsigned integer. + If buf is Z_NULL, this function returns the required initial value for the + crc. Pre- and post-conditioning (one's complement) is performed within this + function so it shouldn't be done by the application. Usage example:
diff --git a/tools/cast3p/OWNERS b/tools/cast3p/OWNERS index 39eb6fde..e0fc48a2 100644 --- a/tools/cast3p/OWNERS +++ b/tools/cast3p/OWNERS
@@ -3,5 +3,5 @@ riazantsevv@google.com rwkeane@google.com -per-file cast_core.version=chromium-autoroll@skia-public.iam.gserviceaccount.com -per-file runtime.version=chromium-autoroll@skia-public.iam.gserviceaccount.com \ No newline at end of file +per-file cast_core.version=chromium-internal-autoroll@skia-public.iam.gserviceaccount.com +per-file runtime.version=chromium-internal-autoroll@skia-public.iam.gserviceaccount.com \ No newline at end of file
diff --git a/tools/metrics/actions/actions.xml b/tools/metrics/actions/actions.xml index 43fecfed..baac6d9 100644 --- a/tools/metrics/actions/actions.xml +++ b/tools/metrics/actions/actions.xml
@@ -2525,15 +2525,6 @@ </description> </action> -<action name="Android.Bookmarks.BottomSheet.Open"> - <owner>shaktisahu@chromium.org</owner> - <description> - User tapped on the star icon from the app menu to bookmark a page. This - resulted in opening the bookmarks bottom sheet that presents a list of - destination folders to choose from for saving the bookmark. - </description> -</action> - <action name="Android.ChromeHome.AcceptedSurvey"> <obsolete> Deprecated 1/2018. Replaced with the
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 5e64066..a2a96b5 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -19838,6 +19838,7 @@ <int value="65" label="VSH_CONNECT_FAILED"/> <int value="66" label="CONTAINER_STOP_FAILED"/> <int value="67" label="CONTAINER_STOP_CANCELLED"/> + <int value="68" label="WAYLAND_SERVER_CREATION_FAILED"/> </enum> <enum name="CrostiniSettingsEvent"> @@ -37177,7 +37178,7 @@ <int value="3392" label="DOMWindowOpenPositioningFeaturesCrossScreen"/> <int value="3393" label="DOMWindowSetWindowRectCrossScreen"/> <int value="3394" label="FullscreenCrossScreen"/> - <int value="3395" label="BatterySavingsMeta"/> + <int value="3395" label="OBSOLETE_BatterySavingsMeta"/> <int value="3396" label="DigitalGoodsGetDigitalGoodsService"/> <int value="3397" label="DigitalGoodsGetDetails"/> <int value="3398" label="DigitalGoodsAcknowledge"/> @@ -53817,6 +53818,7 @@ <int value="-1134412904" label="PrivacySandboxSettings:disabled"/> <int value="-1134307340" label="stop-loading-in-background:enabled"/> <int value="-1132704128" label="AndroidPaymentAppsFilter:disabled"/> + <int value="-1131726331" label="BackGestureRefactorAndroid:disabled"/> <int value="-1128981647" label="EnableOAuthIpp:enabled"/> <int value="-1128912963" label="MediaControlsExpandGesture:disabled"/> <int value="-1128221789" @@ -54388,6 +54390,7 @@ <int value="-747072690" label="NtpRepeatableQueries:disabled"/> <int value="-746328467" label="ExpensiveBackgroundTimerThrottling:disabled"/> <int value="-746042208" label="QuickCommands:enabled"/> + <int value="-745969829" label="BackGestureRefactorAndroid:enabled"/> <int value="-745082968" label="SyncDeviceInfoInTransportMode:disabled"/> <int value="-745005043" label="enable-experimental-accessibility-switch-access-setup-guide"/> @@ -83057,6 +83060,7 @@ label="Unpacking the (possibly patched) uncompressed archive failed."/> <int value="71" label="Rotation of the device trust key failed."/> <int value="72" label="Rotation of the device trust key succeeded."/> + <int value="73" label="Creation of shortcuts succeeded."/> </enum> <enum name="SetupInstallServiceInstallResult"> @@ -97712,6 +97716,16 @@ <int value="5" label="Load failed in preload and tab was never opened"/> </enum> +<enum name="WhatsNewStartupType"> + <int value="0" label="Called What's New ShouldShowForState"/> + <int value="1" label="Page is disabled by promotional tabs policy"/> + <int value="2" label="Page disabled due to invalid/unreadable local state"/> + <int value="3" label="Page is disabled by feature or command line flag"/> + <int value="4" label="Page has already been shown for this milestone"/> + <int value="5" label="User is ineligible for page"/> + <int value="6" label="Page is overridden by a different first run page"/> +</enum> + <enum name="WhitelistedDownloadType"> <int value="0" label="Does not match any whitelists"/> <int value="1" label="URL whitelist"/>
diff --git a/tools/metrics/histograms/metadata/android/histograms.xml b/tools/metrics/histograms/metadata/android/histograms.xml index deb63ef6..bf06f66 100644 --- a/tools/metrics/histograms/metadata/android/histograms.xml +++ b/tools/metrics/histograms/metadata/android/histograms.xml
@@ -646,6 +646,26 @@ </summary> </histogram> +<histogram name="Android.ClipBoard.getImageDuration{ImageType}" units="ms" + expires_after="2022-10-31"> + <owner>gangwu@chromium.org</owner> + <owner>wenyufu@chromium.org</owner> + <summary> + Records the duration for Android Clipboard to load the images from Uri + backed by a temporary file. Recorded when image is requested from Clipboard + (e.g Image paste), and read into memory as bytes. Record for {ImageType} + </summary> + <token key="ImageType"> + <variant name=".NonPng" + summary="image with type other than png, so encoding is needed. The + duration includes reading image as bitmap, and conversion + into png."/> + <variant name=".Png" + summary="image with type as png, so no encoding is needed. The + duration includes reading bytes from the file stream."/> + </token> +</histogram> + <histogram name="Android.ContactsPicker.AddressHasDerivedField" enum="AddressHasDerivedField" expires_after="2020-09-01"> <owner>finnur@chromium.org</owner> @@ -2741,7 +2761,7 @@ </histogram> <histogram name="Android.SearchEngineChoice.ChosenSearchEngine" - enum="OmniboxSearchEngineType" expires_after="2022-06-01"> + enum="OmniboxSearchEngineType" expires_after="2023-06-01"> <owner>fgorski@chromium.org</owner> <owner>wylieb@chromium.org</owner> <summary> @@ -2751,7 +2771,7 @@ </histogram> <histogram name="Android.SearchEngineChoice.Events" - enum="AndroidSearchEngineChoiceEvents" expires_after="2022-06-01"> + enum="AndroidSearchEngineChoiceEvents" expires_after="2023-06-01"> <owner>wylieb@chromium.org</owner> <owner>fgorski@chromium.org</owner> <summary> @@ -2760,7 +2780,7 @@ </histogram> <histogram name="Android.SearchEngineChoice.EventsV2" - enum="AndroidSearchEngineChoiceEventsV2" expires_after="2022-10-04"> + enum="AndroidSearchEngineChoiceEventsV2" expires_after="2023-06-01"> <owner>wylieb@chromium.org</owner> <owner>pavely@chromium.org</owner> <owner>fgorski@chromium.org</owner> @@ -2771,7 +2791,7 @@ </histogram> <histogram name="Android.SearchEngineChoice.SearchEngineBeforeChoicePrompt" - enum="OmniboxSearchEngineType" expires_after="2022-07-31"> + enum="OmniboxSearchEngineType" expires_after="2023-06-01"> <owner>wylieb@chromium.org</owner> <owner>fgorski@chromium.org</owner> <summary> @@ -4224,8 +4244,7 @@ <histogram name="Android.WebView.UniversalAccess.OriginUrlMismatchInHistoryUtil" - enum="BooleanAllowed" expires_after="2022-08-07"> - <owner>alexmitra@chromium.org</owner> + enum="BooleanAllowed" expires_after="2022-09-01"> <owner>torne@chromium.org</owner> <owner>src/android_webview/OWNERS</owner> <summary> @@ -4237,8 +4256,7 @@ <histogram name="Android.WebView.UniversalAccess.OriginUrlMismatchInRenderFrame" - enum="BooleanAllowed" expires_after="2022-06-04"> - <owner>alexmitra@chromium.org</owner> + enum="BooleanAllowed" expires_after="2022-09-01"> <owner>torne@chromium.org</owner> <owner>src/android_webview/OWNERS</owner> <summary> @@ -4392,7 +4410,7 @@ </histogram> <histogram name="AndroidSearchEngineLogo.Events" - enum="AndroidSearchEngineLogoEvents" expires_after="2022-06-01"> + enum="AndroidSearchEngineLogoEvents" expires_after="2023-06-01"> <owner>wylieb@chromium.org</owner> <owner>fgorski@chromium.org</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/ash/histograms.xml b/tools/metrics/histograms/metadata/ash/histograms.xml index a9c2c64f..8456b27 100644 --- a/tools/metrics/histograms/metadata/ash/histograms.xml +++ b/tools/metrics/histograms/metadata/ash/histograms.xml
@@ -1066,6 +1066,21 @@ <token key="TabletOrClamshell" variants="DisplayModes"/> </histogram> +<histogram name="Ash.CaptureModeController.ScreenRecordingLength" + units="seconds" expires_after="2022-09-09"> + <obsolete> + Replaced with + Ash.CaptureModeController.ScreenRecordingLength.{TabletOrClamshell} in M99. + </obsolete> + <owner>afakhry@chromium.org</owner> + <owner>gzadina@google.com</owner> + <summary> + Records the time of a successful video recording in capture mode. This + metric will not be recorded if a file was not successfully saved. The upper + limit of this histogram is 3 hours. + </summary> +</histogram> + <histogram name="Ash.CaptureModeController.ScreenRecordingLength.{TabletOrClamshell}" units="seconds" expires_after="2022-09-09">
diff --git a/tools/metrics/histograms/metadata/bookmarks/histograms.xml b/tools/metrics/histograms/metadata/bookmarks/histograms.xml index 07d524f..e5ed634c 100644 --- a/tools/metrics/histograms/metadata/bookmarks/histograms.xml +++ b/tools/metrics/histograms/metadata/bookmarks/histograms.xml
@@ -129,16 +129,6 @@ </summary> </histogram> -<histogram name="Bookmarks.BottomSheet.DestinationFolder" enum="BookmarkType" - expires_after="2022-06-01"> - <owner>wylieb@chromium.org</owner> - <component>UI>Browser>Bookmarks</component> - <summary> - Logs the destination directory chosen by the user when saving a bookmark via - bottom sheet on Android. - </summary> -</histogram> - <histogram name="Bookmarks.Count.OnProfileLoad" units="bookmarks" expires_after="2022-10-23"> <owner>supertri@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/custom_tabs/histograms.xml b/tools/metrics/histograms/metadata/custom_tabs/histograms.xml index 6a1ffa8d..2a7fc13 100644 --- a/tools/metrics/histograms/metadata/custom_tabs/histograms.xml +++ b/tools/metrics/histograms/metadata/custom_tabs/histograms.xml
@@ -151,7 +151,7 @@ </histogram> <histogram name="CustomTabs.DetachedResourceRequest.FinalStatus" - enum="NetErrorCodes" expires_after="2022-08-21"> + enum="NetErrorCodes" expires_after="2022-10-23"> <owner>lizeb@chromium.org</owner> <owner>cct-team@google.com</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/extensions/histograms.xml b/tools/metrics/histograms/metadata/extensions/histograms.xml index 29cdfb1..4cae66a 100644 --- a/tools/metrics/histograms/metadata/extensions/histograms.xml +++ b/tools/metrics/histograms/metadata/extensions/histograms.xml
@@ -124,7 +124,7 @@ </histogram> <histogram name="Extensions.ActiveScriptController.DeniedExtensions" - units="Extension Count" expires_after="2022-08-21"> + units="Extension Count" expires_after="2022-10-23"> <owner>rdevlin.cronin@chromium.org</owner> <owner>extensions-core@chromium.org</owner> <summary> @@ -134,7 +134,7 @@ </histogram> <histogram name="Extensions.ActiveScriptController.PermittedExtensions" - units="Extension Count" expires_after="2022-08-21"> + units="Extension Count" expires_after="2022-10-23"> <owner>rdevlin.cronin@chromium.org</owner> <owner>extensions-core@chromium.org</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/file/histograms.xml b/tools/metrics/histograms/metadata/file/histograms.xml index 2d512ef8..1c3141c 100644 --- a/tools/metrics/histograms/metadata/file/histograms.xml +++ b/tools/metrics/histograms/metadata/file/histograms.xml
@@ -524,7 +524,7 @@ </histogram> <histogram name="FileBrowser.MenuItemSelected" enum="FileManagerMenuCommands" - expires_after="2022-04-10"> + expires_after="M113"> <owner>simmonsjosh@google.com</owner> <owner>src/ui/file_manager/OWNERS</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/image/histograms.xml b/tools/metrics/histograms/metadata/image/histograms.xml index 5961057..2071bdc 100644 --- a/tools/metrics/histograms/metadata/image/histograms.xml +++ b/tools/metrics/histograms/metadata/image/histograms.xml
@@ -316,7 +316,7 @@ </histogram> <histogram name="ImageFetcher.CacheMetadataCount{ImageFetcherCacheStrategy}" - units="records" expires_after="2022-06-01"> + units="records" expires_after="2023-06-01"> <owner>fgorski@chromium.org</owner> <owner>wylieb@chromium.org</owner> <summary> @@ -328,7 +328,7 @@ </histogram> <histogram name="ImageFetcher.CacheSize{ImageFetcherCacheStrategy}" units="KB" - expires_after="2022-06-01"> + expires_after="2023-06-01"> <owner>fgorski@chromium.org</owner> <owner>wylieb@chromium.org</owner> <summary> @@ -339,7 +339,7 @@ </histogram> <histogram name="ImageFetcher.Events{ImageFetcherClients}" - enum="ImageFetcherEvent" expires_after="2022-06-01"> + enum="ImageFetcherEvent" expires_after="2023-06-01"> <owner>fgorski@chromium.org</owner> <owner>wylieb@chromium.org</owner> <summary> @@ -353,7 +353,7 @@ </histogram> <histogram name="ImageFetcher.ImageLoadFromCacheTimeJava{ImageFetcherClients}" - units="ms" expires_after="2022-06-01"> + units="ms" expires_after="2023-06-01"> <owner>fgorski@chromium.org</owner> <owner>wylieb@chromium.org</owner> <summary> @@ -366,7 +366,7 @@ </histogram> <histogram name="ImageFetcher.ImageLoadFromCacheTime{ImageFetcherClients}" - units="ms" expires_after="2022-06-01"> + units="ms" expires_after="2023-06-01"> <owner>fgorski@chromium.org</owner> <owner>wylieb@chromium.org</owner> <summary> @@ -379,7 +379,7 @@ </histogram> <histogram name="ImageFetcher.ImageLoadFromNativeTimeJava{ImageFetcherClients}" - units="ms" expires_after="2022-06-01"> + units="ms" expires_after="2023-06-01"> <owner>fgorski@chromium.org</owner> <owner>wylieb@chromium.org</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/leveldb_proto/histograms.xml b/tools/metrics/histograms/metadata/leveldb_proto/histograms.xml index eb4be80..2556a72 100644 --- a/tools/metrics/histograms/metadata/leveldb_proto/histograms.xml +++ b/tools/metrics/histograms/metadata/leveldb_proto/histograms.xml
@@ -104,7 +104,7 @@ </variants> <histogram name="LevelDB.ApproximateMemTableMemoryUse.{LevelDBClient}" - units="bytes" expires_after="2022-04-11"> + units="bytes" expires_after="2022-10-23"> <owner>nyquist@chromium.org</owner> <owner>salg@google.com</owner> <owner>chrome-owp-storage@google.com</owner> @@ -116,7 +116,7 @@ </histogram> <histogram name="ProtoDB.DestroySuccess.{LevelDBClient}" enum="BooleanSuccess" - expires_after="2022-04-11"> + expires_after="2022-10-23"> <owner>nyquist@chromium.org</owner> <owner>ssid@chromium.org</owner> <summary>Whether a ProtoDB Destroy call was successful or not.</summary> @@ -124,7 +124,7 @@ </histogram> <histogram name="ProtoDB.GetErrorStatus.{LevelDBClient}" enum="LevelDBStatus" - expires_after="2022-04-11"> + expires_after="2022-10-23"> <owner>nyquist@chromium.org</owner> <owner>ssid@chromium.org</owner> <summary> @@ -134,7 +134,7 @@ </histogram> <histogram name="ProtoDB.GetFound.{LevelDBClient}" enum="Boolean" - expires_after="2022-04-11"> + expires_after="2022-10-23"> <owner>nyquist@chromium.org</owner> <owner>ssid@chromium.org</owner> <summary>Whether a ProtoDB Get call found what was requested.</summary> @@ -142,7 +142,7 @@ </histogram> <histogram name="ProtoDB.GetSuccess.{LevelDBClient}" enum="BooleanSuccess" - expires_after="2022-04-11"> + expires_after="2022-10-23"> <owner>nyquist@chromium.org</owner> <owner>ssid@chromium.org</owner> <summary>Whether a ProtoDB Get call was successful or not.</summary> @@ -150,7 +150,7 @@ </histogram> <histogram name="ProtoDB.InitStatus.{LevelDBClient}" enum="LevelDBStatus" - expires_after="2022-04-17"> + expires_after="2022-10-23"> <owner>nyquist@chromium.org</owner> <owner>ssid@chromium.org</owner> <summary>The LevelDB Status from a ProtoDatabase Init call.</summary> @@ -158,7 +158,7 @@ </histogram> <histogram name="ProtoDB.LoadEntriesSuccess.{LevelDBClient}" - enum="BooleanSuccess" expires_after="2022-04-11"> + enum="BooleanSuccess" expires_after="2022-10-23"> <owner>nyquist@chromium.org</owner> <owner>ssid@chromium.org</owner> <summary>Whether a ProtoDB LoadEntries call was successful or not.</summary> @@ -166,7 +166,7 @@ </histogram> <histogram name="ProtoDB.LoadKeysAndEntriesSuccess.{LevelDBClient}" - enum="BooleanSuccess" expires_after="2022-04-11"> + enum="BooleanSuccess" expires_after="2022-10-23"> <owner>nyquist@chromium.org</owner> <owner>ssid@chromium.org</owner> <summary> @@ -176,7 +176,7 @@ </histogram> <histogram name="ProtoDB.LoadKeysSuccess.{LevelDBClient}" enum="BooleanSuccess" - expires_after="2022-04-11"> + expires_after="2022-10-23"> <owner>nyquist@chromium.org</owner> <owner>ssid@chromium.org</owner> <summary>Whether a ProtoDB LoadKeys call was successful or not.</summary> @@ -198,7 +198,7 @@ </histogram> <histogram name="ProtoDB.UpdateErrorStatus.{LevelDBClient}" - enum="LevelDBStatus" expires_after="2022-04-11"> + enum="LevelDBStatus" expires_after="2022-10-23"> <owner>nyquist@chromium.org</owner> <owner>ssid@chromium.org</owner> <summary> @@ -208,7 +208,7 @@ </histogram> <histogram name="ProtoDB.UpdateSuccess.{LevelDBClient}" enum="BooleanSuccess" - expires_after="2022-04-11"> + expires_after="2022-10-23"> <owner>nyquist@chromium.org</owner> <owner>ssid@chromium.org</owner> <summary>Whether a ProtoDB UpdateEntries call was successful or not.</summary>
diff --git a/tools/metrics/histograms/metadata/media/histograms.xml b/tools/metrics/histograms/metadata/media/histograms.xml index dd257b4..6e9940e 100644 --- a/tools/metrics/histograms/metadata/media/histograms.xml +++ b/tools/metrics/histograms/metadata/media/histograms.xml
@@ -946,7 +946,7 @@ </histogram> <histogram name="Media.Audio.Render.GetSourceDataTimeMax.WebRTC" - units="microseconds" expires_after="2022-08-21"> + units="microseconds" expires_after="2022-10-23"> <owner>guidou@chromium.org</owner> <owner>olka@chromium.org</owner> <summary> @@ -1298,7 +1298,7 @@ </histogram> <histogram name="Media.AudioInputControllerSessionSilenceReport" - enum="AudioInputSilenceReport" expires_after="2022-08-21"> + enum="AudioInputSilenceReport" expires_after="2022-10-23"> <owner>guidou@chromium.org</owner> <owner>olka@chromium.org</owner> <summary> @@ -3358,7 +3358,7 @@ </histogram> <histogram name="Media.MSE.Mp4ConsecutiveEmptySamples" units="samples" - expires_after="2022-08-21"> + expires_after="2022-10-23"> <owner>wolenetz@chromium.org</owner> <owner>sandersd@chromium.org</owner> <summary> @@ -3382,7 +3382,7 @@ </histogram> <histogram name="Media.MSE.Mp4SampleSize" units="bytes" - expires_after="2022-08-21"> + expires_after="2022-10-23"> <owner>wolenetz@chromium.org</owner> <owner>sandersd@chromium.org</owner> <summary> @@ -3393,7 +3393,7 @@ </histogram> <histogram name="Media.MSE.Mp4TrunSampleCount" units="samples" - expires_after="2022-08-21"> + expires_after="2022-10-23"> <owner>wolenetz@chromium.org</owner> <owner>sandersd@chromium.org</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/others/histograms.xml b/tools/metrics/histograms/metadata/others/histograms.xml index e5e0c86..337e440 100644 --- a/tools/metrics/histograms/metadata/others/histograms.xml +++ b/tools/metrics/histograms/metadata/others/histograms.xml
@@ -14529,6 +14529,18 @@ </summary> </histogram> +<histogram name="WhatsNew.StartupType" enum="WhatsNewStartupType" + expires_after="2022-08-07"> + <owner>rbpotter@chromium.org</owner> + <owner>mahmadi@chromium.org</owner> + <summary> + Records whether the What's New page should try to show, whether it is + overridden (e.g. by welcome) and whether the user is ineligible (e.g. due to + being in incognito mode). Recorded when startup tabs are being determined at + initialization. Desktop only. + </summary> +</histogram> + <histogram name="WheelScrolling.WasLatched" enum="BooleanLatched" expires_after="M77"> <owner>flackr@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/power/histograms.xml b/tools/metrics/histograms/metadata/power/histograms.xml index ece53fb..294b660 100644 --- a/tools/metrics/histograms/metadata/power/histograms.xml +++ b/tools/metrics/histograms/metadata/power/histograms.xml
@@ -1601,7 +1601,7 @@ </summary> </histogram> -<histogram base="true" name="Power.Mac" units="mW" expires_after="2022-10-16"> +<histogram base="true" name="Power.Mac" units="mW" expires_after="2022-10-23"> <owner>olivierli@chromium.org</owner> <owner>markchang@chromium.org</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/safe_browsing/histograms.xml b/tools/metrics/histograms/metadata/safe_browsing/histograms.xml index e3fd63c8..f212e213 100644 --- a/tools/metrics/histograms/metadata/safe_browsing/histograms.xml +++ b/tools/metrics/histograms/metadata/safe_browsing/histograms.xml
@@ -2142,7 +2142,7 @@ </histogram> <histogram name="SafeBrowsing.V4GetHash.CacheHit.Result" - enum="SafeBrowsingV4FullHashCacheResult" expires_after="2022-08-21"> + enum="SafeBrowsingV4FullHashCacheResult" expires_after="2022-10-23"> <owner>vakh@chromium.org</owner> <owner>chrome-safebrowsing-alerts@google.com</owner> <summary>Track cache hits for V4 full hashes.</summary>
diff --git a/tools/metrics/histograms/metadata/subresource/histograms.xml b/tools/metrics/histograms/metadata/subresource/histograms.xml index 56e9920..42fd6a1 100644 --- a/tools/metrics/histograms/metadata/subresource/histograms.xml +++ b/tools/metrics/histograms/metadata/subresource/histograms.xml
@@ -579,7 +579,7 @@ </histogram> <histogram name="SubresourceFilter.SafeBrowsing.TotalCheckTime" units="ms" - expires_after="2022-08-21"> + expires_after="2022-10-23"> <owner>alexmt@chromium.org</owner> <owner>chrome-ads-histograms@google.com</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/v8/histograms.xml b/tools/metrics/histograms/metadata/v8/histograms.xml index 6a170b3..1f33e9bc 100644 --- a/tools/metrics/histograms/metadata/v8/histograms.xml +++ b/tools/metrics/histograms/metadata/v8/histograms.xml
@@ -2061,7 +2061,7 @@ </histogram> <histogram name="V8.WasmTierUpModuleMicroSeconds" units="microseconds" - expires_after="2022-08-21"> + expires_after="2022-10-23"> <owner>ecmziegler@chromium.org</owner> <owner>adamk@chromium.org</owner> <owner>clemensb@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/variations/histograms.xml b/tools/metrics/histograms/metadata/variations/histograms.xml index bdd0911c..0ef0f0ca 100644 --- a/tools/metrics/histograms/metadata/variations/histograms.xml +++ b/tools/metrics/histograms/metadata/variations/histograms.xml
@@ -47,7 +47,7 @@ </histogram> <histogram name="Variations.AppSeedFreshness" units="minutes" - expires_after="2022-08-21"> + expires_after="2022-10-23"> <owner>rmcelrath@chromium.org</owner> <owner>ntfschr@chromium.org</owner> <owner>src/android_webview/OWNERS</owner>
diff --git a/tools/metrics/histograms/metadata/webapps/histograms.xml b/tools/metrics/histograms/metadata/webapps/histograms.xml index 91195773..ba90d4e 100644 --- a/tools/metrics/histograms/metadata/webapps/histograms.xml +++ b/tools/metrics/histograms/metadata/webapps/histograms.xml
@@ -463,6 +463,9 @@ <histogram name="WebApp.InstallIphPromo.Result" enum="WebAppInstallIphResult" expires_after="2022-05-22"> + <obsolete> + Deprecated on 2022-04. Collected metrics on IPH usage and no longer needed. + </obsolete> <owner>phillis@chromium.org</owner> <owner>dmurph@chromium.org</owner> <summary>
diff --git a/tools/traffic_annotation/summary/annotations.xml b/tools/traffic_annotation/summary/annotations.xml index 57baf65..2d6a03e 100644 --- a/tools/traffic_annotation/summary/annotations.xml +++ b/tools/traffic_annotation/summary/annotations.xml
@@ -348,7 +348,7 @@ <item id="wallpaper_google_photos_albums" added_in_milestone="99" content_hash_code="00248f64" os_list="chromeos" file_path="chrome/browser/ash/wallpaper_handlers/wallpaper_handlers.cc" /> <item id="webapk_create" added_in_milestone="99" content_hash_code="07b8fd35" os_list="android" file_path="chrome/browser/android/webapk/webapk_installer.cc" /> <item id="webapk_update" added_in_milestone="99" content_hash_code="0763f8a7" os_list="android" file_path="chrome/browser/android/webapk/webapk_installer.cc" /> - <item id="safe_browsing_extension_telemetry" added_in_milestone="98" content_hash_code="07998e68" os_list="linux,windows,chromeos" file_path="chrome/browser/safe_browsing/extension_telemetry/extension_telemetry_uploader.cc" /> + <item id="safe_browsing_extension_telemetry" added_in_milestone="98" content_hash_code="06f81c76" os_list="linux,windows,chromeos" file_path="chrome/browser/safe_browsing/extension_telemetry/extension_telemetry_uploader.cc" /> <item id="fast_pair_device_metadata_fetcher" added_in_milestone="100" content_hash_code="0655adc6" os_list="chromeos" file_path="ash/quick_pair/repository/fast_pair/device_metadata_fetcher.cc" /> <item id="fast_pair_image_decoder" added_in_milestone="99" content_hash_code="04d764bc" os_list="chromeos" file_path="ash/quick_pair/repository/fast_pair/fast_pair_image_decoder_impl.cc" /> <item id="wallpaper_google_photos_photos" added_in_milestone="100" content_hash_code="00c76007" os_list="chromeos" file_path="chrome/browser/ash/wallpaper_handlers/wallpaper_handlers.cc" />
diff --git a/ui/android/BUILD.gn b/ui/android/BUILD.gn index 097a53a..0971948 100644 --- a/ui/android/BUILD.gn +++ b/ui/android/BUILD.gn
@@ -218,7 +218,6 @@ deps = [ "//base:base_java", "//third_party/androidx:androidx_annotation_annotation_java", - "//third_party/androidx:androidx_appcompat_appcompat_java", "//third_party/androidx:androidx_appcompat_appcompat_resources_java", "//third_party/androidx:androidx_core_core_java", ] @@ -442,7 +441,9 @@ "//base:base_java", "//base:base_java_test_support", "//components/browser_ui/modaldialog/android:java", - "//third_party/android_deps:android_support_v7_appcompat_java", + "//third_party/androidx:androidx_appcompat_appcompat_java", + "//third_party/androidx:androidx_appcompat_appcompat_resources_java", + "//third_party/androidx:androidx_vectordrawable_vectordrawable_animated_java", # For androidx.test.espresso.ViewInteraction "//third_party/android_deps:espresso_java", @@ -510,7 +511,6 @@ "//base:base_junit_test_support", "//base/test:test_support_java", "//third_party/androidx:androidx_annotation_annotation_java", - "//third_party/androidx:androidx_appcompat_appcompat_java", "//third_party/androidx:androidx_appcompat_appcompat_resources_java", "//third_party/androidx:androidx_asynclayoutinflater_asynclayoutinflater_java", "//third_party/androidx:androidx_core_core_java",
diff --git a/ui/android/java/src/org/chromium/ui/base/ClipboardImpl.java b/ui/android/java/src/org/chromium/ui/base/ClipboardImpl.java index 7c067f29..70009a4 100644 --- a/ui/android/java/src/org/chromium/ui/base/ClipboardImpl.java +++ b/ui/android/java/src/org/chromium/ui/base/ClipboardImpl.java
@@ -15,6 +15,7 @@ import android.graphics.Bitmap; import android.net.Uri; import android.os.Build; +import android.os.SystemClock; import android.text.Html; import android.text.Spanned; import android.text.TextUtils; @@ -38,6 +39,7 @@ import org.chromium.base.compat.ApiHelperForO; import org.chromium.base.compat.ApiHelperForP; import org.chromium.base.compat.ApiHelperForS; +import org.chromium.base.metrics.RecordHistogram; import org.chromium.base.metrics.RecordUserAction; import org.chromium.base.task.AsyncTask; import org.chromium.components.url_formatter.UrlFormatter; @@ -298,12 +300,16 @@ // Android system clipboard contains an image, but it is not a PNG. // Try reading it as a bitmap and encoding to a PNG. try { + final long startTime = SystemClock.elapsedRealtime(); // TODO(crbug.com/1280468): This uses the unsafe ImageDecoder class. Bitmap bitmap = ApiCompatibilityUtils.getBitmapByUri(cr, uri); ByteArrayOutputStream baos = new ByteArrayOutputStream(); // |quality| is ignored since PNG encoding is lossless. See // https://developer.android.com/reference/android/graphics/Bitmap.CompressFormat#PNG. bitmap.compress(Bitmap.CompressFormat.PNG, /*quality=*/100, baos); + RecordHistogram.recordMediumTimesHistogram( + "Android.ClipBoard.getImageDuration.NonPngImages", + SystemClock.elapsedRealtime() - startTime); if (baos.size() > MAX_ALLOWED_PNG_SIZE_BYTES) return null; return baos.toByteArray(); @@ -320,10 +326,12 @@ return null; } byte[] data = new byte[(int) afd.getLength()]; - + final long startTime = SystemClock.elapsedRealtime(); fileStream = new FileInputStream(afd.getFileDescriptor()); fileStream.read(data); - + RecordHistogram.recordMediumTimesHistogram( + "Android.ClipBoard.getImageDuration.PngImages", + SystemClock.elapsedRealtime() - startTime); return data; } catch (IOException e) { return null;
diff --git a/ui/webui/resources/css/widgets.css b/ui/webui/resources/css/widgets.css index 2ba6a1a..6ccecb8 100644 --- a/ui/webui/resources/css/widgets.css +++ b/ui/webui/resources/css/widgets.css
@@ -56,7 +56,10 @@ select { -webkit-appearance: none; /* OVERRIDE */ - background-image: url(../images/select.png), + background-image: + -webkit-image-set( + url(../images/select.png) 1x, + url(../images/2x/select.png) 2x), -webkit-linear-gradient(#ededed, #ededed 38%, #dedede); background-position: right center; background-repeat: no-repeat; @@ -118,7 +121,9 @@ /* Checked ********************************************************************/ input[type='checkbox']:checked::before { - background-image: url(../images/check.png); + background-image: -webkit-image-set( + url(../images/check.png) 1x, + url(../images/2x/check.png) 2x); background-size: 100% 100%; content: ''; display: block; @@ -159,7 +164,10 @@ :enabled:hover:-webkit-any(select) { /* OVERRIDE */ - background-image: url(../images/select.png), + background-image: + -webkit-image-set( + url(../images/select.png) 1x, + url(../images/2x/select.png) 2x), -webkit-linear-gradient(#f0f0f0, #f0f0f0 38%, #e0e0e0); } </if> @@ -201,7 +209,10 @@ select:disabled { /* OVERRIDE */ - background-image: url(../images/disabled_select.png), + background-image: + -webkit-image-set( + url(../images/disabled_select.png) 1x, + url(../images/2x/disabled_select.png) 2x), -webkit-linear-gradient(#f1f1f1, #f1f1f1 38%, #e6e6e6); }
diff --git a/weblayer/shell/android/BUILD.gn b/weblayer/shell/android/BUILD.gn index 535d316e..15d4678b 100644 --- a/weblayer/shell/android/BUILD.gn +++ b/weblayer/shell/android/BUILD.gn
@@ -45,8 +45,9 @@ "$google_play_services_package:google_play_services_base_java", "//base:base_java", "//components/strictmode/android:java", - "//third_party/android_deps:android_support_v7_appcompat_java", "//third_party/androidx:androidx_annotation_annotation_java", + "//third_party/androidx:androidx_appcompat_appcompat_java", + "//third_party/androidx:androidx_fragment_fragment_java", "//weblayer/public/java", ] sources = [