diff --git a/BUILD.gn b/BUILD.gn index 69e759c3..4b37258 100644 --- a/BUILD.gn +++ b/BUILD.gn
@@ -1260,9 +1260,17 @@ "@WrappedPath(.)", ] } else { - _common_web_test_args = [ "@WrappedPath(" + rebase_path( - "//third_party/blink/tools/run_web_tests.py", - root_build_dir) + ")" ] + base_out_dir = rebase_path(get_path_info(root_build_dir, "dir"), ".") + out_dir = get_path_info(root_build_dir, "name") + _common_web_test_args = [ + "@WrappedPath(" + + rebase_path("//third_party/blink/tools/run_web_tests.py", + root_build_dir) + ")", + "--build-directory", + base_out_dir, + "--target", + out_dir, + ] } if (is_debug) { _common_web_test_args += [ "--debug" ]
diff --git a/DEPS b/DEPS index 2a982d3..46571d52 100644 --- a/DEPS +++ b/DEPS
@@ -312,7 +312,7 @@ # 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': '9b08a3f3881c1df237eea2c7ec46de8d45b1f319', + 'skia_revision': '9950dc8ec6fd376a48fb1e892ed4ef040bf07331', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # 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 ANGLE # and whatever else without interference from each other. - 'angle_revision': '21d124c4bf321a18dae1dc94602aa262fc346a8b', + 'angle_revision': '8080a736f13854f806cb115e6ab78a8f4f33d08e', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. @@ -403,7 +403,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling devtools-frontend # and whatever else without interference from each other. - 'devtools_frontend_revision': '88376a9d2adac2acf9e276df26265e935357dd7f', + 'devtools_frontend_revision': 'a11a408bd5d81d06adac27ef13e74a24630d45c6', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libprotobuf-mutator # and whatever else without interference from each other. @@ -827,12 +827,12 @@ 'src/clank': { 'url': Var('chrome_git') + '/clank/internal/apps.git' + '@' + - '03d4b8cf7dd1a2d763b7d53f7aa855954b861740', + '2ab9ac86f0c274f5df3781390b997f901bd4a958', 'condition': 'checkout_android and checkout_src_internal', }, 'src/docs/website': { - 'url': Var('chromium_git') + '/website.git' + '@' + '2c1fee75b24e8ecee921e9c61013f4ae9d98ab26', + 'url': Var('chromium_git') + '/website.git' + '@' + '02057aa20e0dd4598967e3daf2f25c815962ef1c', }, 'src/ios/third_party/earl_grey2/src': { @@ -982,7 +982,7 @@ 'packages': [ { 'package': 'chromium/third_party/androidx', - 'version': 'VVHFAfCwY9wBjzGyVHosqxrx-PoXni9idw4CSTDFUYwC', + 'version': 'FOeJcZQ2mA3UXM0yKNQ0R4aeu-xXh3kUwWXV4zko8hoC', }, ], 'condition': 'checkout_android', @@ -1198,7 +1198,7 @@ Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'), 'src/third_party/devtools-frontend-internal': { - 'url': Var('chrome_git') + '/devtools/devtools-internal.git' + '@' + '45973af663ccb3ac9e2ba7e8d245fc68e12770a0', + 'url': Var('chrome_git') + '/devtools/devtools-internal.git' + '@' + '66b4b8e55ce57e007a9abaf12ec4aacc14fbdb47', 'condition': 'checkout_src_internal', }, @@ -1526,7 +1526,7 @@ }, 'src/third_party/libvpx/source/libvpx': - Var('chromium_git') + '/webm/libvpx.git' + '@' + 'c29e63728316486082dd6083c2062434b441b77d', + Var('chromium_git') + '/webm/libvpx.git' + '@' + '19832b1702d5b0adf616a0e080abd5207c8445b5', 'src/third_party/libwebm/source': Var('chromium_git') + '/webm/libwebm.git' + '@' + 'e4fbea0c9751ae8aa86629b197a28d8276a2b0da', @@ -1658,7 +1658,7 @@ Var('pdfium_git') + '/pdfium.git' + '@' + Var('pdfium_revision'), 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + '7c4a4566938e79171e0549f1f75a69e904cdb86c', + Var('android_git') + '/platform/external/perfetto.git' + '@' + '7e63f42d755ca255162f1f327126f90e34465581', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '8ef97ff3b7332e38e61b347a2fbed425a4617151', @@ -1806,7 +1806,7 @@ 'dep_type': 'cipd', }, - 'src/third_party/vulkan-deps': '{chromium_git}/vulkan-deps@fa1e68dabb9108b6651b56bfee37a4688cdd5446', + 'src/third_party/vulkan-deps': '{chromium_git}/vulkan-deps@074f27e83c5591c976f789a7f3bd4447124e9640', 'src/third_party/vulkan_memory_allocator': Var('chromium_git') + '/external/github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator.git' + '@' + '56300b29fbfcc693ee6609ddad3fdd5b7a449a21', @@ -1969,7 +1969,7 @@ 'packages': [ { 'package': 'chromeos_internal/apps/help_app/app', - 'version': 'xaEIRf_uHmL8vWAjjU6bglibHqiGQQ-eEcmL6H6yH1MC', + 'version': 'mExQ51nVPXKFwooxZlyBddG2pwJ0WMYmwuBH3Zc2bdYC', }, ], 'condition': 'checkout_chromeos and checkout_src_internal', @@ -1980,7 +1980,7 @@ 'packages': [ { 'package': 'chromeos_internal/apps/media_app/app', - 'version': 'fTsuWvQ9rIPPCmwwfgpPo-AuM4WW1Ma4RxPE5CEbKsoC', + 'version': 'MkRfy7gnbTu93H28fxVkBaRFPdXmI_fMHyIzXc8vfTIC', }, ], 'condition': 'checkout_chromeos and checkout_src_internal', @@ -4015,7 +4015,7 @@ 'src/components/autofill/core/browser/form_parsing/internal_resources': { 'url': Var('chrome_git') + '/chrome/components/autofill_regex_patterns.git' + '@' + - 'eda22f28bded47cdfaa65a0b703fd55b80e470ce', + 'cf5d6e009247ce27beccca2d771f3105caaa4256', 'condition': 'checkout_src_internal', }, @@ -4074,7 +4074,7 @@ 'src/components/test/data/autofill/heuristics-json/internal': { 'url': Var('chrome_git') + '/chrome/test/autofill/structured_forms.git' + '@' + - 'd632ed48ff308e208535023924de938ae723a1cb', + 'd541923921b7b51397af7f095f4ecc7779d0aa22', 'condition': 'checkout_chromium_autofill_test_dependencies', },
diff --git a/android_webview/browser/aw_field_trials.cc b/android_webview/browser/aw_field_trials.cc index ecdb8ff..99d1e3f1 100644 --- a/android_webview/browser/aw_field_trials.cc +++ b/android_webview/browser/aw_field_trials.cc
@@ -105,6 +105,7 @@ // Disable Shared Storage on WebView. aw_feature_overrides.DisableFeature(blink::features::kSharedStorageAPI); + aw_feature_overrides.DisableFeature(blink::features::kSharedStorageAPIM124); // Disable scrollbar-color on WebView. aw_feature_overrides.DisableFeature(blink::features::kScrollbarColor);
diff --git a/android_webview/browser/gfx/skia_output_surface_dependency_webview.cc b/android_webview/browser/gfx/skia_output_surface_dependency_webview.cc index c2c2cfd9..a4c558f6 100644 --- a/android_webview/browser/gfx/skia_output_surface_dependency_webview.cc +++ b/android_webview/browser/gfx/skia_output_surface_dependency_webview.cc
@@ -110,13 +110,11 @@ } scoped_refptr<gl::Presenter> -SkiaOutputSurfaceDependencyWebView::CreatePresenter( - base::WeakPtr<gpu::ImageTransportSurfaceDelegate> stub) { +SkiaOutputSurfaceDependencyWebView::CreatePresenter() { return nullptr; } scoped_refptr<gl::GLSurface> SkiaOutputSurfaceDependencyWebView::CreateGLSurface( - base::WeakPtr<gpu::ImageTransportSurfaceDelegate> stub, gl::GLSurfaceFormat format) { return gl_surface_.get(); }
diff --git a/android_webview/browser/gfx/skia_output_surface_dependency_webview.h b/android_webview/browser/gfx/skia_output_surface_dependency_webview.h index 4bfdad62..3bf41c4 100644 --- a/android_webview/browser/gfx/skia_output_surface_dependency_webview.h +++ b/android_webview/browser/gfx/skia_output_surface_dependency_webview.h
@@ -53,10 +53,8 @@ scoped_refptr<base::TaskRunner> GetClientTaskRunner() override; bool IsOffscreen() override; gpu::SurfaceHandle GetSurfaceHandle() override; - scoped_refptr<gl::Presenter> CreatePresenter( - base::WeakPtr<gpu::ImageTransportSurfaceDelegate> stub) override; + scoped_refptr<gl::Presenter> CreatePresenter() override; scoped_refptr<gl::GLSurface> CreateGLSurface( - base::WeakPtr<gpu::ImageTransportSurfaceDelegate> stub, gl::GLSurfaceFormat format) override; base::ScopedClosureRunner CachePresenter(gl::Presenter* presenter) override; base::ScopedClosureRunner CacheGLSurface(gl::GLSurface* surface) override;
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/ClientHintsTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/ClientHintsTest.java index 0cecc0f..6e296e8 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/ClientHintsTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/ClientHintsTest.java
@@ -246,7 +246,7 @@ Assert.assertEquals("HEADER_NOT_FOUND", clientHintsMap.get("save-data")); Assert.assertNotEquals( "HEADER_NOT_FOUND", clientHintsMap.get("sec-ch-prefers-reduced-motion")); - Assert.assertEquals("HEADER_NOT_FOUND", clientHintsMap.get("sec-ch-ua-form-factors")); + Assert.assertNotEquals("HEADER_NOT_FOUND", clientHintsMap.get("sec-ch-ua-form-factors")); Assert.assertNotEquals( "HEADER_NOT_FOUND", clientHintsMap.get("sec-ch-prefers-reduced-transparency"));
diff --git a/ash/app_list/model/search/search_result.h b/ash/app_list/model/search/search_result.h index c2a6ea7..5ab932e 100644 --- a/ash/app_list/model/search/search_result.h +++ b/ash/app_list/model/search/search_result.h
@@ -142,6 +142,14 @@ metadata_->metrics_type = metrics_type; } + const std::optional<ContinueFileSuggestionType>& + continue_file_suggestion_type() const { + return metadata_->continue_file_suggestion_type; + } + void set_metrics_subtype(ContinueFileSuggestionType type) { + metadata_->continue_file_suggestion_type = type; + } + const Actions& actions() const { return metadata_->actions; } void SetActions(const Actions& sets);
diff --git a/ash/app_list/views/continue_task_container_view.cc b/ash/app_list/views/continue_task_container_view.cc index 36bfbbe..842f7b97 100644 --- a/ash/app_list/views/continue_task_container_view.cc +++ b/ash/app_list/views/continue_task_container_view.cc
@@ -309,7 +309,8 @@ if (notifier) { std::vector<AppListNotifier::Result> notifier_results; for (const auto* task : tasks) - notifier_results.emplace_back(task->id(), task->metrics_type()); + notifier_results.emplace_back(task->id(), task->metrics_type(), + task->continue_file_suggestion_type()); notifier->NotifyResultsUpdated(SearchResultDisplayType::kContinue, notifier_results); }
diff --git a/ash/app_list/views/recent_apps_view.cc b/ash/app_list/views/recent_apps_view.cc index 5b2c517..85aa38f 100644 --- a/ash/app_list/views/recent_apps_view.cc +++ b/ash/app_list/views/recent_apps_view.cc
@@ -219,8 +219,9 @@ if (auto* notifier = view_delegate_->GetNotifier()) { std::vector<AppListNotifier::Result> notifier_results; for (const RecentAppInfo& app : apps) - notifier_results.emplace_back(app.result->id(), - app.result->metrics_type()); + notifier_results.emplace_back( + app.result->id(), app.result->metrics_type(), + app.result->continue_file_suggestion_type()); notifier->NotifyResultsUpdated(SearchResultDisplayType::kRecentApps, notifier_results); }
diff --git a/ash/app_list/views/search_result_image_list_view.cc b/ash/app_list/views/search_result_image_list_view.cc index e4566d75..942390bb 100644 --- a/ash/app_list/views/search_result_image_list_view.cc +++ b/ash/app_list/views/search_result_image_list_view.cc
@@ -255,7 +255,8 @@ if (notifier) { std::vector<AppListNotifier::Result> notifier_results; for (const auto* result : display_results) { - notifier_results.emplace_back(result->id(), result->metrics_type()); + notifier_results.emplace_back(result->id(), result->metrics_type(), + result->continue_file_suggestion_type()); } notifier->NotifyResultsUpdated(SearchResultDisplayType::kImage, notifier_results);
diff --git a/ash/app_list/views/search_result_list_view.cc b/ash/app_list/views/search_result_list_view.cc index 074b580..ea18d5f 100644 --- a/ash/app_list/views/search_result_list_view.cc +++ b/ash/app_list/views/search_result_list_view.cc
@@ -298,7 +298,8 @@ if (notifier) { std::vector<AppListNotifier::Result> notifier_results; for (const auto* result : displayed_results) - notifier_results.emplace_back(result->id(), result->metrics_type()); + notifier_results.emplace_back(result->id(), result->metrics_type(), + result->continue_file_suggestion_type()); notifier->NotifyResultsUpdated( list_type_ == SearchResultListType::kAnswerCard ? SearchResultDisplayType::kAnswerCard
diff --git a/ash/capture_mode/capture_mode_controller.cc b/ash/capture_mode/capture_mode_controller.cc index 4e41544..3a8f202 100644 --- a/ash/capture_mode/capture_mode_controller.cc +++ b/ash/capture_mode/capture_mode_controller.cc
@@ -118,6 +118,10 @@ constexpr char kCanShowDemoToolsNudge[] = "ash.capture_mode.can_show_demo_tools_nudge"; +// An invalid IDS value used as a placeholder to not show a message in a +// notification. +constexpr int kNoMessage = -1; + // The screenshot notification button index. enum ScreenshotNotificationButtonIndex { kButtonEdit = 0, @@ -252,10 +256,12 @@ const auto type = optional_fields.image.IsEmpty() ? message_center::NOTIFICATION_TYPE_SIMPLE : message_center::NOTIFICATION_TYPE_CUSTOM; + const std::u16string message = message_id == kNoMessage + ? std::u16string() + : l10n_util::GetStringUTF16(message_id); std::unique_ptr<message_center::Notification> notification = CreateSystemNotificationPtr( - type, notification_id, l10n_util::GetStringUTF16(title_id), - l10n_util::GetStringUTF16(message_id), + type, notification_id, l10n_util::GetStringUTF16(title_id), message, l10n_util::GetStringUTF16(IDS_ASH_SCREEN_CAPTURE_DISPLAY_SOURCE), GURL(), message_center::NotifierId( @@ -1661,9 +1667,14 @@ const CaptureModeBehavior* behavior) { const bool for_video = type == CaptureModeType::kVideo; const int title_id = GetNotificationTitleIdForFile(screen_capture_path); - const int message_id = for_video && low_disk_space_threshold_reached_ - ? IDS_ASH_SCREEN_CAPTURE_LOW_STORAGE_SPACE_MESSAGE - : IDS_ASH_SCREEN_CAPTURE_MESSAGE; + int message_id; + if (for_video && low_disk_space_threshold_reached_) { + message_id = IDS_ASH_SCREEN_CAPTURE_LOW_STORAGE_SPACE_MESSAGE; + } else { + message_id = base::FeatureList::IsEnabled(features::kFileNotificationRevamp) + ? kNoMessage + : IDS_ASH_SCREEN_CAPTURE_MESSAGE; + } message_center::RichNotificationData optional_fields; optional_fields.buttons = behavior->GetNotificationButtonsInfo(for_video);
diff --git a/ash/public/cpp/app_list/app_list_metrics.h b/ash/public/cpp/app_list/app_list_metrics.h index e357ae80..fec9561 100644 --- a/ash/public/cpp/app_list/app_list_metrics.h +++ b/ash/public/cpp/app_list/app_list_metrics.h
@@ -193,6 +193,31 @@ SEARCH_RESULT_TYPE_BOUNDARY }; +// Sub-types defined for zero state file/drive suggestions that indicate +// the reason the file result was suggested. +// Used for metrics - assigned values should not change. +enum class ContinueFileSuggestionType { + // For zero state drive suggestions - file suggested because the user + // viewed it recently. + kViewedDrive = 0, + // For zero state drive suggestions - file suggested because it was + // recently modified (usually by another user). + kModifiedDrive = 1, + // For zero state drive suggestions - file suggested because the user + // modified it recently. + kModifiedByCurrentUserDrive = 2, + // For zero state drive suggestions - file suggested because it was recently + // shared with the user. + kSharedWithUserDrive = 3, + // For zero state local file suggestions - file suggested because the user + // viewed it recently. + kViewedFile = 4, + // For zero state local file suggestions - file suggested because the user + // modified it recently. + kModifiedByCurrentUserFile = 5, + kMaxValue = kModifiedByCurrentUserFile, +}; + ASH_PUBLIC_EXPORT std::string SearchSessionConclusionToString( SearchSessionConclusion conclusion);
diff --git a/ash/public/cpp/app_list/app_list_notifier.h b/ash/public/cpp/app_list/app_list_notifier.h index 0f9625c..f193c2d 100644 --- a/ash/public/cpp/app_list/app_list_notifier.h +++ b/ash/public/cpp/app_list/app_list_notifier.h
@@ -7,6 +7,7 @@ #include <stdint.h> +#include <optional> #include <string> #include <vector> @@ -30,11 +31,15 @@ using Location = ash::SearchResultDisplayType; struct Result { - Result(const std::string& id, ash::SearchResultType type) - : id(id), type(type) {} + Result(const std::string& id, + ash::SearchResultType type, + const std::optional<ash::ContinueFileSuggestionType>& + continue_file_type) + : id(id), type(type), continue_file_type(continue_file_type) {} std::string id; ash::SearchResultType type = ash::SEARCH_RESULT_TYPE_BOUNDARY; + std::optional<ash::ContinueFileSuggestionType> continue_file_type; }; class Observer : public base::CheckedObserver {
diff --git a/ash/public/cpp/app_list/app_list_types.h b/ash/public/cpp/app_list/app_list_types.h index e10ce96..b7ed93d 100644 --- a/ash/public/cpp/app_list/app_list_types.h +++ b/ash/public/cpp/app_list/app_list_types.h
@@ -823,6 +823,10 @@ // A search result type used for metrics. ash::SearchResultType metrics_type = ash::SEARCH_RESULT_TYPE_BOUNDARY; + // For file suggestions in continue section, the suggestion type - i.e. the + // reason the file was suggested to the user. + std::optional<ContinueFileSuggestionType> continue_file_suggestion_type; + // Which UI container(s) the result should be displayed in. SearchResultDisplayType display_type = SearchResultDisplayType::kList;
diff --git a/ash/webui/camera_app_ui/BUILD.gn b/ash/webui/camera_app_ui/BUILD.gn index 899470e9..4f734ba 100644 --- a/ash/webui/camera_app_ui/BUILD.gn +++ b/ash/webui/camera_app_ui/BUILD.gn
@@ -42,6 +42,7 @@ "//ash/webui/common:trusted_types_util", "//ash/webui/system_apps/public:system_web_app_config", "//ash/webui/web_applications", + "//chromeos/ash/components/dbus/session_manager:session_manager", "//chromeos/ash/components/mojo_service_manager", "//chromeos/utils", "//components/arc",
diff --git a/ash/webui/camera_app_ui/DEPS b/ash/webui/camera_app_ui/DEPS index 2e9e5d2..04dd6af 100644 --- a/ash/webui/camera_app_ui/DEPS +++ b/ash/webui/camera_app_ui/DEPS
@@ -1,4 +1,5 @@ include_rules = [ + "+chromeos/ash/components/dbus/session_manager", "+chromeos/ash/components/mojo_service_manager", "+chromeos/utils/pdf_conversion.h", "+components/arc/intent_helper",
diff --git a/ash/webui/camera_app_ui/camera_app_helper.mojom b/ash/webui/camera_app_ui/camera_app_helper.mojom index 6f21755..d7579aa 100644 --- a/ash/webui/camera_app_ui/camera_app_helper.mojom +++ b/ash/webui/camera_app_ui/camera_app_helper.mojom
@@ -50,6 +50,14 @@ Update(ScreenState state); }; +// Interface for monitoring lock state of screen. The state is detected from +// Chrome browser process and is notified to Chrome Camera App in renderer +// process. +interface ScreenLockedMonitor { + // Updates when the lock state of screen got changed. + Update(bool is_screen_locked); +}; + // Interface for monitoring the existence of external screen. The state is // detected from Chrome browser process and is notified to Chrome Camera App in // renderer process. @@ -297,4 +305,10 @@ // Gets an event sender which can be used to send events to CrOS Events. GetEventsSender() => (pending_remote<EventsSender> events_sender); + + // Registers a ScreenLockedMonitor instance and returns the initial lock + // state of screen. + // Calling the Update() whenever the screen is locked/unlocked. + SetScreenLockedMonitor(pending_remote<ScreenLockedMonitor> monitor) + => (bool is_screen_locked); };
diff --git a/ash/webui/camera_app_ui/camera_app_helper_impl.cc b/ash/webui/camera_app_ui/camera_app_helper_impl.cc index e921c30..b3e30fd 100644 --- a/ash/webui/camera_app_ui/camera_app_helper_impl.cc +++ b/ash/webui/camera_app_ui/camera_app_helper_impl.cc
@@ -204,9 +204,11 @@ DCHECK(window); window->SetProperty(kCanConsumeSystemKeysKey, true); ScreenBacklight::Get()->AddObserver(this); + ash::SessionManagerClient::Get()->AddObserver(this); } CameraAppHelperImpl::~CameraAppHelperImpl() { + ash::SessionManagerClient::Get()->RemoveObserver(this); ScreenBacklight::Get()->RemoveObserver(this); if (pending_intent_id_.has_value()) { @@ -610,4 +612,20 @@ std::move(callback).Run(events_sender_->CreateConnection()); } +void CameraAppHelperImpl::SetScreenLockedMonitor( + mojo::PendingRemote<ScreenLockedMonitor> monitor, + SetScreenLockedMonitorCallback callback) { + screen_locked_monitor_ = + mojo::Remote<ScreenLockedMonitor>(std::move(monitor)); + std::move(callback).Run(ash::SessionManagerClient::Get()->IsScreenLocked()); +} + +void CameraAppHelperImpl::ScreenLockedStateUpdated() { + if (!screen_locked_monitor_.is_bound()) { + return; + } + screen_locked_monitor_->Update( + ash::SessionManagerClient::Get()->IsScreenLocked()); +} + } // namespace ash
diff --git a/ash/webui/camera_app_ui/camera_app_helper_impl.h b/ash/webui/camera_app_ui/camera_app_helper_impl.h index 5acd61c1..3c9f4dc 100644 --- a/ash/webui/camera_app_ui/camera_app_helper_impl.h +++ b/ash/webui/camera_app_ui/camera_app_helper_impl.h
@@ -16,6 +16,7 @@ #include "ash/webui/camera_app_ui/document_scanner_service_client.h" #include "base/memory/raw_ptr.h" #include "base/memory/weak_ptr.h" +#include "chromeos/ash/components/dbus/session_manager/session_manager_client.h" #include "chromeos/services/machine_learning/public/mojom/document_scanner.mojom.h" #include "media/capture/video/chromeos/mojom/system_event_monitor.mojom.h" #include "mojo/public/cpp/bindings/receiver.h" @@ -31,6 +32,7 @@ namespace ash { class CameraAppHelperImpl : public ScreenBacklightObserver, + public SessionManagerClient::Observer, public display::DisplayObserver, public cros::mojom::CrosLidObserver, public camera_app::mojom::CameraAppHelper { @@ -49,6 +51,7 @@ camera_app::mojom::CameraUsageOwnershipMonitor; using StorageMonitor = camera_app::mojom::StorageMonitor; using LidStateMonitor = camera_app::mojom::LidStateMonitor; + using ScreenLockedMonitor = camera_app::mojom::ScreenLockedMonitor; CameraAppHelperImpl(CameraAppUI* camera_app_ui, CameraResultCallback camera_result_callback, @@ -111,6 +114,8 @@ void SetLidStateMonitor(mojo::PendingRemote<LidStateMonitor> monitor, SetLidStateMonitorCallback callback) override; void GetEventsSender(GetEventsSenderCallback callback) override; + void SetScreenLockedMonitor(mojo::PendingRemote<ScreenLockedMonitor> monitor, + SetScreenLockedMonitorCallback callback) override; private: void CheckExternalScreenState(); @@ -131,6 +136,9 @@ void OnScreenBacklightStateChanged( ScreenBacklightState screen_backlight_state) override; + // ash::SessionManagerClient::Observer overrides; + void ScreenLockedStateUpdated() override; + // display::DisplayObserver overrides; void OnDisplayAdded(const display::Display& new_display) override; void OnDisplayRemoved(const display::Display& old_display) override; @@ -176,6 +184,8 @@ mojo::Receiver<cros::mojom::CrosLidObserver> lid_observer_receiver_{this}; + mojo::Remote<ScreenLockedMonitor> screen_locked_monitor_; + mojo::Receiver<camera_app::mojom::CameraAppHelper> receiver_{this}; base::WeakPtrFactory<CameraAppHelperImpl> weak_factory_{this};
diff --git a/ash/webui/camera_app_ui/resources/js/device/camera_manager.ts b/ash/webui/camera_app_ui/resources/js/device/camera_manager.ts index 15de3dba..ff8d544 100644 --- a/ash/webui/camera_app_ui/resources/js/device/camera_manager.ts +++ b/ash/webui/camera_app_ui/resources/js/device/camera_manager.ts
@@ -5,13 +5,10 @@ import { assert, assertExists, - assertInstanceof, } from '../assert.js'; -import * as error from '../error.js'; import * as expert from '../expert.js'; import {Point} from '../geometry.js'; import * as metrics from '../metrics.js'; -import {isLocalDev} from '../models/load_time_data.js'; import {ChromeHelper} from '../mojo/chrome_helper.js'; import {LidState, ScreenState} from '../mojo/type.js'; import * as nav from '../nav.js'; @@ -19,8 +16,6 @@ import * as state from '../state.js'; import { AspectRatioSet, - ErrorLevel, - ErrorType, Facing, Mode, PerfEvent, @@ -124,25 +119,6 @@ modeConstraints, ); - // Monitors the states to stop camera when locked/minimized. - // TODO(pihsun): The IdleDetector permission is auto-granted on CrOS. For - // local dev, we can request it by IdleDetector.requestPermission(), but - // that needs to be done in a user gesture and can't be done here. - if (!isLocalDev()) { - const idleDetector = new IdleDetector(); - idleDetector.addEventListener('change', async () => { - this.locked = idleDetector.screenState === 'locked'; - if (this.locked) { - await this.reconfigure(); - } - }); - idleDetector.start().catch((e) => { - error.reportError( - ErrorType.IDLE_DETECTOR_FAILURE, ErrorLevel.ERROR, - assertInstanceof(e, Error)); - }); - } - document.addEventListener('visibilitychange', async () => { const recording = state.get(state.State.TAKING) && state.get(Mode.VIDEO); if (this.isTabletBackground() && !recording) { @@ -275,6 +251,16 @@ const lidState = await helper.initLidStateMonitor(setLidClosed); setLidClosed(lidState); + const handleScreenLockedChange = async (isScreenLocked: boolean) => { + this.locked = isScreenLocked; + if (this.locked) { + await this.reconfigure(); + } + }; + + this.locked = + await helper.initScreenLockedMonitor(handleScreenLockedChange); + const handleScreenStateChange = async () => { if (this.screenOff) { await this.reconfigure();
diff --git a/ash/webui/camera_app_ui/resources/js/local_dev_overrides.ts b/ash/webui/camera_app_ui/resources/js/local_dev_overrides.ts index 0ce94f6..0d78776 100644 --- a/ash/webui/camera_app_ui/resources/js/local_dev_overrides.ts +++ b/ash/webui/camera_app_ui/resources/js/local_dev_overrides.ts
@@ -173,6 +173,11 @@ return fakeEndpoint(); } + override async initScreenLockedMonitor( + _onChange: (isScreenLocked: boolean) => void): Promise<boolean> { + return false; + } + /* eslint-enable @typescript-eslint/require-await */ }
diff --git a/ash/webui/camera_app_ui/resources/js/mojo/chrome_helper.ts b/ash/webui/camera_app_ui/resources/js/mojo/chrome_helper.ts index 2c33b21..45d7eb9 100644 --- a/ash/webui/camera_app_ui/resources/js/mojo/chrome_helper.ts +++ b/ash/webui/camera_app_ui/resources/js/mojo/chrome_helper.ts
@@ -24,6 +24,7 @@ LidState, LidStateMonitorCallbackRouter, Rotation, + ScreenLockedMonitorCallbackRouter, ScreenState, ScreenStateMonitorCallbackRouter, StorageMonitorCallbackRouter, @@ -236,6 +237,9 @@ abstract getEventsSender(): Promise<EventsSenderRemote>; + abstract initScreenLockedMonitor(onChange: (isScreenLocked: boolean) => void): + Promise<boolean>; + /** * Creates a new instance of ChromeHelper if it is not set. Returns the * existing instance. @@ -492,4 +496,15 @@ const {eventsSender} = await this.remote.getEventsSender(); return wrapEndpoint(eventsSender); } + + override async initScreenLockedMonitor( + onChange: (isScreenLocked: boolean) => void): Promise<boolean> { + const monitorCallbackRouter = + wrapEndpoint(new ScreenLockedMonitorCallbackRouter()); + monitorCallbackRouter.update.addListener(onChange); + + const {isScreenLocked} = await this.remote.setScreenLockedMonitor( + monitorCallbackRouter.$.bindNewPipeAndPassRemote()); + return isScreenLocked; + } }
diff --git a/ash/webui/camera_app_ui/resources/js/mojo/type.ts b/ash/webui/camera_app_ui/resources/js/mojo/type.ts index 44205d5..a2da91e 100644 --- a/ash/webui/camera_app_ui/resources/js/mojo/type.ts +++ b/ash/webui/camera_app_ui/resources/js/mojo/type.ts
@@ -19,6 +19,7 @@ ExternalScreenMonitorCallbackRouter, FileMonitorResult, LidStateMonitorCallbackRouter, + ScreenLockedMonitorCallbackRouter, ScreenState, ScreenStateMonitorCallbackRouter, StorageMonitorCallbackRouter,
diff --git a/ash/webui/camera_app_ui/resources/js/type.ts b/ash/webui/camera_app_ui/resources/js/type.ts index 3817df5..0c33da3b 100644 --- a/ash/webui/camera_app_ui/resources/js/type.ts +++ b/ash/webui/camera_app_ui/resources/js/type.ts
@@ -332,7 +332,6 @@ FILE_SYSTEM_FAILURE = 'file-system-failure', FRAME_ROTATION_NOT_DISABLED = 'frame-rotation-not-disabled', HANDLE_CAMERA_RESULT_FAILURE = 'handle-camera-result-failure', - IDLE_DETECTOR_FAILURE = 'idle-detector-failure', INVALID_REVIEW_UI_STATE = 'invalid-review-ui-state', METADATA_MAPPING_FAILURE = 'metadata-mapping-failure', MULTI_WINDOW_HANDLING_FAILURE = 'multi-window-handling-failure',
diff --git a/ash/webui/common/resources/network/apn_list.js b/ash/webui/common/resources/network/apn_list.js index 9ad59f68..06aa595 100644 --- a/ash/webui/common/resources/network/apn_list.js +++ b/ash/webui/common/resources/network/apn_list.js
@@ -20,7 +20,7 @@ import {ApnDetailDialog} from '//resources/ash/common/network/apn_detail_dialog.js'; import {afterNextRender, mixinBehaviors, PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {ApnDetailDialogMode, ApnEventData} from 'chrome://resources/ash/common/network/cellular_utils.js'; -import {ApnProperties, ApnState, ApnType, ManagedCellularProperties} from 'chrome://resources/mojo/chromeos/services/network_config/public/mojom/cros_network_config.mojom-webui.js'; +import {ApnProperties, ApnSource, ApnState, ApnType, ManagedCellularProperties} from 'chrome://resources/mojo/chromeos/services/network_config/public/mojom/cros_network_config.mojom-webui.js'; import {PortalState} from 'chrome://resources/mojo/chromeos/services/network_config/public/mojom/network_types.mojom-webui.js'; import {getTemplate} from './apn_list.html.js'; @@ -336,7 +336,8 @@ !this.managedCellularProperties.apnList) { return []; } - return this.managedCellularProperties.apnList.activeValue; + return this.managedCellularProperties.apnList.activeValue.filter( + (apn) => apn.source === ApnSource.kModb); } }
diff --git a/ash/webui/common/resources/network/network_apnlist.js b/ash/webui/common/resources/network/network_apnlist.js index f97f7750..4221657a 100644 --- a/ash/webui/common/resources/network/network_apnlist.js +++ b/ash/webui/common/resources/network/network_apnlist.js
@@ -14,11 +14,11 @@ import './network_property_list_mojo.js'; import './network_shared.css.js'; +import {assert} from '//resources/ash/common/assert.js'; import {I18nBehavior} from '//resources/ash/common/i18n_behavior.js'; import {OncMojo} from '//resources/ash/common/network/onc_mojo.js'; -import {assert} from '//resources/ash/common/assert.js'; import {Polymer} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js'; -import {ApnAuthenticationType, ApnIpType, ApnProperties, ApnState, ApnType, ManagedApnProperties, ManagedProperties} from 'chrome://resources/mojo/chromeos/services/network_config/public/mojom/cros_network_config.mojom-webui.js'; +import {ApnAuthenticationType, ApnIpType, ApnProperties, ApnSource, ApnState, ApnType, ManagedApnProperties, ManagedProperties} from 'chrome://resources/mojo/chromeos/services/network_config/public/mojom/cros_network_config.mojom-webui.js'; import {getTemplate} from './network_apnlist.html.js'; @@ -88,6 +88,7 @@ authentication: ApnAuthenticationType.kAutomatic, ipType: ApnIpType.kAutomatic, apnTypes: [ApnType.kDefault], + source: ApnSource.kUi, }; }, }, @@ -155,6 +156,7 @@ state: ApnState.kEnabled, ipType: ApnIpType.kAutomatic, apnTypes: [ApnType.kDefault], + source: ApnSource.kModem, }; }, @@ -260,6 +262,7 @@ state: ApnState.kEnabled, ipType: ApnIpType.kAutomatic, apnTypes: [ApnType.kDefault], + source: ApnSource.kUi, }; apnList.push(this.otherApn_);
diff --git a/ash/webui/common/resources/quick_unlock/pin_keyboard.ts b/ash/webui/common/resources/quick_unlock/pin_keyboard.ts index d38c42b..0117190a 100644 --- a/ash/webui/common/resources/quick_unlock/pin_keyboard.ts +++ b/ash/webui/common/resources/quick_unlock/pin_keyboard.ts
@@ -488,18 +488,19 @@ /** * Called when a key event is pressed while the input element has focus. */ - private onInputKeyDown_(event: Event): void { + private onInputKeyDown_(event: KeyboardEvent): void { assertInstanceof(event, KeyboardEvent); // Up/down pressed, swallow the event to prevent the input value from // being incremented or decremented. - if (event.keyCode === 38 || event.keyCode === 40) { + if (event.keyCode === 38 || event.keyCode === 40 || + event.code === 'ArrowUp' || event.code === 'ArrowDown') { event.preventDefault(); return; } // Enter pressed. - if (event.keyCode === 13) { + if (event.keyCode === 13 || event.code === 'Enter') { this.firePinSubmitEvent_(); event.preventDefault(); return;
diff --git a/ash/webui/common/resources/sea_pen/sea_pen_options_element.html b/ash/webui/common/resources/sea_pen/sea_pen_options_element.html index 88b453f3..994eae0 100644 --- a/ash/webui/common/resources/sea_pen/sea_pen_options_element.html +++ b/ash/webui/common/resources/sea_pen/sea_pen_options_element.html
@@ -1,5 +1,5 @@ <style include="common cros-button-style"> - #options { + #container { align-items: center; color: var(--cros-text-color-primary); display: flex; @@ -14,18 +14,18 @@ overflow: hidden; } - #options.expanded { + #container.expanded { max-height: unset; } - #options cr-button { + #container cr-button { background-color: var(--cros-bg-color); border-radius: 12px; height: 36px; padding: 4px, 12px; } - #options cr-button[aria-selected] { + #container cr-button[aria-selected] { --text-color: var(--cros-button-label-color-primary); background-color: var(--cros-button-background-color-primary); border-radius: 10px; @@ -42,21 +42,18 @@ width: 20px; } - #expand { - align-items: center; - background-color: var(--cros-sys-app_base_shaded); - display: flex; - justify-content: center; + .hidden { + display: none; } - #expand > span.clickable { - color: var(--cros-text-color-prominent); - font: var(--cros-annotation-1-font); + #expandButton { + --text-color: var(--cros-text-color-prominent); } </style> -<div id="options" class$="[[getOptionsClassName_(chipsExpanded_)]]"> +<div id="container" class$="[[getOptionsClassName_(chipsExpanded_)]]"> <template is="dom-repeat" items="[[options]]" as="option"> <cr-button + class="option" on-click="onClickOption_" aria-selected$="[[isSelected_(option, selectedChip, selectedOptions)]]"> <template is="dom-if" if="[[option.previewUrl]]" restamp> @@ -65,11 +62,9 @@ [[option.translation]] </cr-button> </template> + <cr-button + id="expandButton" + class$="[[getExpandButtonClassName_(shouldShowExpandButton_)]]" + on-click="onClickExpandButton_"> + </cr-button> </div> -<template is="dom-if" if="[[shouldShowExpandButton_]]"> - <div id="expand"> - <span class="clickable" on-click="showMoreChips_"> - [[i18n('seaPenShowMoreOptions')]] - </span> - </div> -</template>
diff --git a/ash/webui/common/resources/sea_pen/sea_pen_options_element.ts b/ash/webui/common/resources/sea_pen/sea_pen_options_element.ts index 56f3bbef0..b54e101 100644 --- a/ash/webui/common/resources/sea_pen/sea_pen_options_element.ts +++ b/ash/webui/common/resources/sea_pen/sea_pen_options_element.ts
@@ -10,19 +10,21 @@ import 'chrome://resources/ash/common/personalization/common.css.js'; import 'chrome://resources/ash/common/personalization/cros_button_style.css.js'; +import {CrButtonElement} from 'chrome://resources/ash/common/cr_elements/cr_button/cr_button.js'; import {I18nMixin} from 'chrome://resources/ash/common/cr_elements/i18n_mixin.js'; import {afterNextRender, Debouncer, PolymerElement, timeOut} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {SeaPenOption} from './constants.js'; import {SeaPenTemplateChip} from './sea_pen_generated.mojom-webui.js'; import {getTemplate} from './sea_pen_options_element.html.js'; -import {ChipToken} from './sea_pen_utils.js'; +import {ChipToken, isNonEmptyArray} from './sea_pen_utils.js'; const SeaPenOptionsElementBase = I18nMixin(PolymerElement); export interface SeaPenOptionsElement { $: { - options: HTMLDivElement, + container: HTMLDivElement, + expandButton: CrButtonElement, }; } @@ -71,8 +73,8 @@ private debouncer_: Debouncer; private onResized_: () => void = () => { this.debouncer_ = - Debouncer.debounce(this.debouncer_, timeOut.after(100), () => { - this.shouldShowExpandButton_ = this.checkWhetherExpandShouldShow_(); + Debouncer.debounce(this.debouncer_, timeOut.after(50), () => { + this.calculateHiddenOptions_(); }); }; @@ -106,27 +108,83 @@ option === selectedOptions.get(selectedChip.id); } - private showMoreChips_() { - this.chipsExpanded_ = true; - this.shouldShowExpandButton_ = false; + private calculateHiddenOptions_() { + if (this.chipsExpanded_ || !isNonEmptyArray(this.options)) { + return; + } + this.shouldShowExpandButton_ = true; + const items = Array.from( + this.shadowRoot!.querySelectorAll<CrButtonElement>('.option')); + // Add a placeholder to hold the button width. + this.$.expandButton.innerText = + this.i18n('seaPenExpandOptionsButton', items.length); + const gap = 8; // 8px gap between chips. + const expandButtonWidth = this.$.expandButton.clientWidth + gap; + + let row = 1; + let remainingWidth: number = this.$.container.clientWidth; + let numHiddenItems: number = 0; + items.forEach((item, i) => { + item.classList.remove('hidden'); + const itemWidth = item.clientWidth + gap; + if (itemWidth <= remainingWidth) { + remainingWidth -= itemWidth; + } else { + // Insufficient space to fit in another chip. + switch (row) { + case 1: + remainingWidth = + this.$.container.clientWidth - itemWidth - expandButtonWidth; + row++; + break; + case 2: + // Hide expand button if the last chip can fit in the second row. + if (i < this.options!.length - 1 || + itemWidth > remainingWidth + expandButtonWidth) { + numHiddenItems = this.options!.length - i; + item.classList.add('hidden'); + } + remainingWidth = 0; + row++; + break; + case 3: + // The number of chips to display may change both ways so we always + // need to go through the whole list of chips again. + item.classList.add('hidden'); + break; + } + } + }); + this.shouldShowExpandButton_ = numHiddenItems > 0; + if (this.shouldShowExpandButton_) { + this.$.expandButton.innerText = + this.i18n('seaPenExpandOptionsButton', numHiddenItems); + } } - private checkWhetherExpandShouldShow_(): boolean { - return !this.chipsExpanded_ && - this.$.options.clientHeight < this.$.options.scrollHeight; + private onClickExpandButton_() { + this.chipsExpanded_ = true; + this.shouldShowExpandButton_ = false; + this.shadowRoot!.querySelectorAll('.option').forEach( + option => option.classList.remove('hidden')); } private onSelectedChipChanged_() { this.chipsExpanded_ = false; this.shouldShowExpandButton_ = false; afterNextRender(this, () => { - this.shouldShowExpandButton_ = this.checkWhetherExpandShouldShow_(); + // Called when the options are fully rendered. + this.calculateHiddenOptions_(); }); } private getOptionsClassName_(chipsExpanded: boolean): string { return chipsExpanded ? 'expanded' : ''; } + + private getExpandButtonClassName_(shouldShowExpandButton: boolean): string { + return shouldShowExpandButton ? '' : 'hidden'; + } } customElements.define(SeaPenOptionsElement.is, SeaPenOptionsElement);
diff --git a/ash/webui/common/sea_pen_resources.cc b/ash/webui/common/sea_pen_resources.cc index 5938a72..08f975e 100644 --- a/ash/webui/common/sea_pen_resources.cc +++ b/ash/webui/common/sea_pen_resources.cc
@@ -49,7 +49,7 @@ {"seaPenWallpaperTermsOfServiceDesc", IDS_SEA_PEN_WALLPAPER_TERMS_OF_SERVICE_DESC}, {"seaPenCreatingHighResImage", IDS_SEA_PEN_CREATING_HIGH_RES_IMAGE}, - {"seaPenShowMoreOptions", IDS_SEA_PEN_SHOW_MORE_OPTIONS}, + {"seaPenExpandOptionsButton", IDS_SEA_PEN_EXPAND_OPTIONS_BUTTON}, }; source->AddLocalizedStrings(kLocalizedStrings); }
diff --git a/ash/wm/overview/overview_grid.cc b/ash/wm/overview/overview_grid.cc index 2420d497..82760aa 100644 --- a/ash/wm/overview/overview_grid.cc +++ b/ash/wm/overview/overview_grid.cc
@@ -2113,6 +2113,13 @@ } desks_bar_view_->UpdateButtonsForSavedDeskGrid(); + + if (pine_widget_) { + pine_widget_->GetNativeWindow()->SetEventTargetingPolicy( + aura::EventTargetingPolicy::kNone); + PerformFadeOutLayer(pine_widget_->GetLayer(), /*animate=*/true, + base::DoNothing()); + } } void OverviewGrid::HideSavedDeskLibrary(bool exit_overview) { @@ -3136,6 +3143,11 @@ UpdateSaveDeskButtons(); UpdateNoWindowsWidget(/*no_items=*/empty(), /*animate=*/true, /*is_continuous_enter=*/false); + if (pine_widget_) { + pine_widget_->GetNativeWindow()->SetEventTargetingPolicy( + aura::EventTargetingPolicy::kTargetAndDescendants); + PerformFadeInLayer(pine_widget_->GetLayer(), /*animate=*/true); + } } void OverviewGrid::OnSaveDeskButtonContainerFadedOut() {
diff --git a/ash/wm/scoped_layer_tree_synchronizer.cc b/ash/wm/scoped_layer_tree_synchronizer.cc index 74958d79..a58eb48 100644 --- a/ash/wm/scoped_layer_tree_synchronizer.cc +++ b/ash/wm/scoped_layer_tree_synchronizer.cc
@@ -468,7 +468,7 @@ bool subtree_altered = false; for (ui::Layer* child : layer->children()) { subtree_altered |= - SynchronizeLayerTreeRoundedCorners(child, reference_bounds); + SynchronizeLayerTreeRoundedCornersImpl(child, reference_bounds); } return subtree_altered || layer_altered;
diff --git a/ash/wm/scoped_layer_tree_synchronizer_unittest.cc b/ash/wm/scoped_layer_tree_synchronizer_unittest.cc index 306bbee..df26b6c 100644 --- a/ash/wm/scoped_layer_tree_synchronizer_unittest.cc +++ b/ash/wm/scoped_layer_tree_synchronizer_unittest.cc
@@ -275,6 +275,15 @@ gfx::RoundedCornersF(7, 7, 20, 7); EXPECT_EQ(layer_2->rounded_corner_radii(), kUpdatedLayer2Radii); EXPECT_EQ(layer_3->rounded_corner_radii(), kLayer3Radii); + + layer_tree_synchronizer->Restore(); + + EXPECT_EQ(root->rounded_corner_radii(), kRootLayerRadii); + EXPECT_EQ(layer_1->rounded_corner_radii(), + restore_layer_tree() ? kLayer1Radii : kUpdatedLayer1Radii); + EXPECT_EQ(layer_2->rounded_corner_radii(), + restore_layer_tree() ? kLayer2Radii : kUpdatedLayer2Radii); + EXPECT_EQ(layer_3->rounded_corner_radii(), kLayer3Radii); } INSTANTIATE_TEST_SUITE_P(/* no prefix */,
diff --git a/ash/wm/window_restore/pine_screenshot_icon_row_view.cc b/ash/wm/window_restore/pine_screenshot_icon_row_view.cc index 5a165266..150d4ce 100644 --- a/ash/wm/window_restore/pine_screenshot_icon_row_view.cc +++ b/ash/wm/window_restore/pine_screenshot_icon_row_view.cc
@@ -103,7 +103,7 @@ const int height = preferred_size.height(); const auto top_left = SkPoint::Make(0.f, 0.f); - const auto bottom_left = SkPoint::Make(0.f, width); + const auto bottom_left = SkPoint::Make(0.f, kIconRowHeight); const auto bottom_right = SkPoint::Make(width, height); const int cutout_curve1_end_x = kIconRowRadius;
diff --git a/ash/wm/window_restore/pine_unittest.cc b/ash/wm/window_restore/pine_unittest.cc index 05f2d706..2bd5162 100644 --- a/ash/wm/window_restore/pine_unittest.cc +++ b/ash/wm/window_restore/pine_unittest.cc
@@ -13,7 +13,10 @@ #include "ash/style/system_dialog_delegate_view.h" #include "ash/system/toast/anchored_nudge_manager_impl.h" #include "ash/test/ash_test_base.h" +#include "ash/test/ash_test_helper.h" #include "ash/test/ash_test_util.h" +#include "ash/wm/desks/templates/saved_desk_test_helper.h" +#include "ash/wm/desks/templates/saved_desk_test_util.h" #include "ash/wm/overview/overview_controller.h" #include "ash/wm/overview/overview_grid.h" #include "ash/wm/overview/overview_grid_test_api.h" @@ -496,4 +499,30 @@ verify_widget_bounds("Zoom 2, down"); } +// Tests that the pine dialog gets hidden when we show the saved desk library. +TEST_F(PineTest, ShowSavedDeskLibrary) { + // Add one entry for the saved desk button to show up. + ash_test_helper()->saved_desk_test_helper()->WaitForDeskModels(); + AddSavedDeskEntry(ash_test_helper()->saved_desk_test_helper()->desk_model(), + base::Uuid::GenerateRandomV4(), "saved_desk", + base::Time::Now(), DeskTemplateType::kSaveAndRecall); + + // Start a pine overview session. + Shell::Get() + ->pine_controller() + ->MaybeStartPineOverviewSessionDevAccelerator(); + WaitForOverviewEntered(); + + views::Widget* pine_widget = + OverviewGridTestApi(GetOverviewGridForRoot(Shell::GetPrimaryRootWindow())) + .pine_widget(); + ASSERT_TRUE(pine_widget); + + // Click the library button and test that the dialog has zero opacity. + const views::Button* library_button = GetLibraryButton(); + ASSERT_TRUE(library_button); + LeftClickOn(library_button); + EXPECT_EQ(0.f, pine_widget->GetLayer()->GetTargetOpacity()); +} + } // namespace ash
diff --git a/base/BUILD.gn b/base/BUILD.gn index ae88c7c..0cba76b 100644 --- a/base/BUILD.gn +++ b/base/BUILD.gn
@@ -4243,6 +4243,7 @@ "containers/checked_iterators_nocompile.nc", "containers/contains_nocompile.nc", "containers/enum_set_nocompile.nc", + "containers/fixed_flat_set_nocompile.nc", "containers/heap_array_nocompile.nc", "containers/span_nocompile.nc", "containers/to_value_list_nocompile.nc", @@ -4298,6 +4299,7 @@ "android/java/src/org/chromium/base/FieldTrialList.java", "android/java/src/org/chromium/base/FileUtils.java", "android/java/src/org/chromium/base/ImportantFileWriterAndroid.java", + "android/java/src/org/chromium/base/InputHintChecker.java", "android/java/src/org/chromium/base/IntStringCallback.java", "android/java/src/org/chromium/base/JNIUtils.java", "android/java/src/org/chromium/base/JavaExceptionReporter.java", @@ -4457,6 +4459,7 @@ "android/java/src/org/chromium/base/FileUtils.java", "android/java/src/org/chromium/base/Flag.java", "android/java/src/org/chromium/base/ImportantFileWriterAndroid.java", + "android/java/src/org/chromium/base/InputHintChecker.java", "android/java/src/org/chromium/base/IntStringCallback.java", "android/java/src/org/chromium/base/IntentUtils.java", "android/java/src/org/chromium/base/JNIUtils.java",
diff --git a/base/android/input_hint_checker.cc b/base/android/input_hint_checker.cc index 2cad6a5..cbf0844 100644 --- a/base/android/input_hint_checker.cc +++ b/base/android/input_hint_checker.cc
@@ -4,6 +4,7 @@ #include "base/android/input_hint_checker.h" +#include "base/base_jni/InputHintChecker_jni.h" #include "base/feature_list.h" #include "base/metrics/field_trial_params.h" #include "base/no_destructor.h" @@ -52,6 +53,11 @@ return false; } +void InputHintChecker::SetView(JNIEnv* env, jobject root_view) { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + view_ = JavaObjectWeakGlobalRef(env, root_view); +} + // static bool InputHintChecker::HasInput() { if (!g_input_hint_enabled) { @@ -77,4 +83,9 @@ g_test_instance = nullptr; } +void JNI_InputHintChecker_SetView(_JNIEnv* env, + const JavaParamRef<jobject>& v) { + InputHintChecker::GetInstance().SetView(env, v.obj()); +} + } // namespace base::android
diff --git a/base/android/input_hint_checker.h b/base/android/input_hint_checker.h index f2e5b79..06d69ee 100644 --- a/base/android/input_hint_checker.h +++ b/base/android/input_hint_checker.h
@@ -5,7 +5,10 @@ #ifndef BASE_ANDROID_INPUT_HINT_CHECKER_H_ #define BASE_ANDROID_INPUT_HINT_CHECKER_H_ +#include "base/android/jni_weak_ref.h" +#include "base/base_export.h" #include "base/feature_list.h" +#include "base/memory/raw_ptr.h" #include "base/no_destructor.h" #include "base/threading/thread_checker.h" #include "base/time/time.h" @@ -27,11 +30,19 @@ InputHintChecker() = default; virtual ~InputHintChecker() = default; + // Returns the singleton. + static InputHintChecker& GetInstance(); + // Enables reading the input hint according to the field trial configuration. // Other methods of this class return trivial results before this // initialization is completed. static void InitializeFeatures(); + // Obtains a weak reference to |root_view| so that the following calls to + // HasInput() take the input hint for this View. Requirements for the View + // object are described in InputHintChecker.java. + void SetView(JNIEnv* env, jobject root_view); + // Fetches and returns the input hint from the Android Framework. Throttles // the calls to one every few milliseconds. When a call is made before the // minimal time interval passed since the previous call, returns false. @@ -48,8 +59,8 @@ private: friend class base::NoDestructor<InputHintChecker>; - static InputHintChecker& GetInstance(); + JavaObjectWeakGlobalRef view_; THREAD_CHECKER(thread_checker_); base::TimeTicks last_checked_; };
diff --git a/base/android/java/src/org/chromium/base/InputHintChecker.java b/base/android/java/src/org/chromium/base/InputHintChecker.java new file mode 100644 index 0000000..14d5863 --- /dev/null +++ b/base/android/java/src/org/chromium/base/InputHintChecker.java
@@ -0,0 +1,41 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.base; + +import android.os.Build; +import android.os.Build.VERSION_CODES; +import android.view.View; + +import androidx.annotation.Nullable; + +import org.jni_zero.JNINamespace; +import org.jni_zero.NativeMethods; + +/** This class allows native code to discover the root view of the current Window. */ +@JNINamespace("base::android") +public class InputHintChecker { + + /** + * Sets the current View for the next input hint requests from native. + * + * <p>Stores/replaces the global weak reference to the root view. To be effective, the View + * instance must have a ViewRootImpl attached to it (internal class in Android Framework). An + * example of such a "root view" can be obtained via `Activity.getWindow().getDecorView()`, and + * only after {@link android.app.Activity#setContentView(android.view.View)}. + * + * @param view The View to pull the input hint from next time. + */ + public static void setView(@Nullable View view) { + if (Build.VERSION.SDK_INT >= VERSION_CODES.UPSIDE_DOWN_CAKE) { + // TODO(pasko): Restrict to SDK_INT >= V when V is available in VERSION_CODES. + InputHintCheckerJni.get().setView(view); + } + } + + @NativeMethods + interface Natives { + void setView(View view); + } +}
diff --git a/base/containers/fixed_flat_set.h b/base/containers/fixed_flat_set.h index 2ac283c0..f0b9f7c 100644 --- a/base/containers/fixed_flat_set.h +++ b/base/containers/fixed_flat_set.h
@@ -84,7 +84,7 @@ // constexpr auto kSet = base::MakeFixedFlatSet<std::string_view>( // base::sorted_unique, {"bar", "baz", "foo", "qux"}); template <class Key, size_t N, class Compare = std::less<>> -constexpr fixed_flat_set<Key, N, Compare> MakeFixedFlatSet( +consteval fixed_flat_set<Key, N, Compare> MakeFixedFlatSet( sorted_unique_t, std::common_type_t<Key> (&&data)[N], const Compare& comp = Compare()) { @@ -111,8 +111,8 @@ // Note: Wrapping `Key` in `std::common_type_t` below requires callers to // explicitly specify `Key`, which is desired here. template <class Key, size_t N, class Compare = std::less<>> -constexpr fixed_flat_set<Key, N, Compare> MakeFixedFlatSet( - std::common_type_t<Key>(&&data)[N], +consteval fixed_flat_set<Key, N, Compare> MakeFixedFlatSet( + std::common_type_t<Key> (&&data)[N], const Compare& comp = Compare()) { std::sort(data, data + N, comp); return MakeFixedFlatSet<Key>(sorted_unique, std::move(data), comp);
diff --git a/base/containers/fixed_flat_set_nocompile.nc b/base/containers/fixed_flat_set_nocompile.nc new file mode 100644 index 0000000..e473489 --- /dev/null +++ b/base/containers/fixed_flat_set_nocompile.nc
@@ -0,0 +1,19 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// This is a "No Compile Test" suite. +// http://dev.chromium.org/developers/testing/no-compile-tests + +#include "base/containers/fixed_flat_set.h" + +// Constructing a fixed flat set with duplicate keys should not compile. +auto kDuplicates = base::MakeFixedFlatSet<int>({1, 1, 2, 3}); // expected-error-re {{call to consteval function 'base::MakeFixedFlatSet<{{.+}}>' is not a constant expression}} + +// Constructing a fixed flat set with the sorted_unique tag but unsorted keys +// should not compile. +auto kNotActuallySorted = base::MakeFixedFlatSet<int>(base::sorted_unique, {3, 2, 1}); // expected-error-re {{call to consteval function 'base::MakeFixedFlatSet<{{.+}}>' is not a constant expression}} + +// Constructing a fixed flat set with the sorted_unique tag but duplicate keys +// should not compile. +auto kSortedButDuplicates = base::MakeFixedFlatSet<int>(base::sorted_unique, {1, 1, 2}); // expected-error-re {{call to consteval function 'base::MakeFixedFlatSet<{{.+}}>' is not a constant expression}}
diff --git a/base/containers/fixed_flat_set_unittest.cc b/base/containers/fixed_flat_set_unittest.cc index b2efa8e..eab31245 100644 --- a/base/containers/fixed_flat_set_unittest.cc +++ b/base/containers/fixed_flat_set_unittest.cc
@@ -28,10 +28,4 @@ EXPECT_THAT(kSet, ::testing::ElementsAre("bar", "baz", "foo")); } -// Verifies that passing repeated keys to MakeFixedFlatSet results in a CHECK -// failure. -TEST(FixedFlatSetTest, RepeatedKeys) { - EXPECT_CHECK_DEATH(MakeFixedFlatSet<int>({1, 2, 3, 1})); -} - } // namespace base
diff --git a/base/task/common/task_annotator.cc b/base/task/common/task_annotator.cc index 6c515af..28e046d6 100644 --- a/base/task/common/task_annotator.cc +++ b/base/task/common/task_annotator.cc
@@ -5,8 +5,10 @@ #include "base/task/common/task_annotator.h" #include <stdint.h> + #include <algorithm> #include <array> +#include <string_view> #include "base/auto_reset.h" #include "base/check_op.h" @@ -292,7 +294,7 @@ // Static uint32_t TaskAnnotator::ScopedSetIpcHash::MD5HashMetricName( - base::StringPiece name) { + std::string_view name) { base::MD5Digest digest; base::MD5Sum(base::as_byte_span(name), &digest); uint32_t value;
diff --git a/base/task/common/task_annotator.h b/base/task/common/task_annotator.h index 4d7ffa9..6fbb6392 100644 --- a/base/task/common/task_annotator.h +++ b/base/task/common/task_annotator.h
@@ -7,11 +7,12 @@ #include <stdint.h> +#include <string_view> + #include "base/auto_reset.h" #include "base/base_export.h" #include "base/memory/raw_ptr_exclusion.h" #include "base/pending_task.h" -#include "base/strings/string_piece.h" #include "base/time/tick_clock.h" #include "base/trace_event/base_tracing.h" @@ -135,7 +136,7 @@ uint32_t GetIpcHash() const { return ipc_hash_; } const char* GetIpcInterfaceName() const { return ipc_interface_name_; } - static uint32_t MD5HashMetricName(base::StringPiece name); + static uint32_t MD5HashMetricName(std::string_view name); private: ScopedSetIpcHash(uint32_t ipc_hash, const char* ipc_interface_name);
diff --git a/base/task/sequence_manager/sequence_manager_impl.cc b/base/task/sequence_manager/sequence_manager_impl.cc index 2813990..ec89d08 100644 --- a/base/task/sequence_manager/sequence_manager_impl.cc +++ b/base/task/sequence_manager/sequence_manager_impl.cc
@@ -8,6 +8,7 @@ #include <atomic> #include <optional> #include <queue> +#include <string_view> #include <vector> #include "base/callback_list.h" @@ -1204,7 +1205,7 @@ void SequenceManagerImpl::RecordCrashKeys(const PendingTask& pending_task) { #if !BUILDFLAG(IS_NACL) && !BUILDFLAG(IS_ANDROID) // SetCrashKeyString is a no-op even if the crash key is null, but we'd still - // have construct the StringPiece that is passed in. + // have construct the std::string_view that is passed in. if (!main_thread_only().async_stack_crash_key) return; @@ -1232,7 +1233,7 @@ DCHECK_GE(pos, buffer); debug::SetCrashKeyString( main_thread_only().async_stack_crash_key, - StringPiece(pos, static_cast<size_t>(buffer_end - pos))); + std::string_view(pos, static_cast<size_t>(buffer_end - pos))); #endif // !BUILDFLAG(IS_NACL) && !BUILDFLAG(IS_ANDROID) }
diff --git a/base/task/sequence_manager/sequence_manager_impl_unittest.cc b/base/task/sequence_manager/sequence_manager_impl_unittest.cc index 06e3d4b..9a5376b 100644 --- a/base/task/sequence_manager/sequence_manager_impl_unittest.cc +++ b/base/task/sequence_manager/sequence_manager_impl_unittest.cc
@@ -5,8 +5,10 @@ #include "base/task/sequence_manager/sequence_manager_impl.h" #include <stddef.h> + #include <memory> #include <string> +#include <string_view> #include <tuple> #include <utility> #include <vector> @@ -5106,7 +5108,7 @@ public: MOCK_METHOD2(Allocate, debug::CrashKeyString*(const char name[], debug::CrashKeySize)); - MOCK_METHOD2(Set, void(debug::CrashKeyString*, StringPiece)); + MOCK_METHOD2(Set, void(debug::CrashKeyString*, std::string_view)); MOCK_METHOD1(Clear, void(debug::CrashKeyString*)); MOCK_METHOD1(OutputCrashKeysToStream, void(std::ostream&)); };
diff --git a/base/task/sequence_manager/thread_controller.cc b/base/task/sequence_manager/thread_controller.cc index b53d071..05853ec2 100644 --- a/base/task/sequence_manager/thread_controller.cc +++ b/base/task/sequence_manager/thread_controller.cc
@@ -3,7 +3,9 @@ // found in the LICENSE file. #include "base/task/sequence_manager/thread_controller.h" + #include <atomic> +#include <string_view> #include "base/check.h" #include "base/feature_list.h" @@ -46,7 +48,8 @@ constexpr TimeDelta kNonTrivialActiveIntervalLength = Milliseconds(1); constexpr TimeDelta kMediumActiveIntervalLength = Milliseconds(100); -std::string MakeSuffix(StringPiece time_suffix, StringPiece thread_name) { +std::string MakeSuffix(std::string_view time_suffix, + std::string_view thread_name) { return base::StrCat({".", time_suffix, ".", thread_name}); } @@ -87,8 +90,8 @@ std::memory_order_relaxed); } -StringPiece ThreadController::RunLevelTracker::RunLevel::GetThreadName() { - StringPiece thread_name = "Other"; +std::string_view ThreadController::RunLevelTracker::RunLevel::GetThreadName() { + std::string_view thread_name = "Other"; if (!time_keeper_->thread_name().empty()) { thread_name = time_keeper_->thread_name(); } @@ -102,7 +105,7 @@ std::string ThreadController::RunLevelTracker::RunLevel::GetSuffixForHistogram( TimeDelta duration) { - StringPiece time_suffix; + std::string_view time_suffix; if (duration < kNonTrivialActiveIntervalLength) { time_suffix = "Short"; } else if (duration < kMediumActiveIntervalLength) {
diff --git a/base/task/sequence_manager/thread_controller.h b/base/task/sequence_manager/thread_controller.h index 7b94d99f..cd61bf5 100644 --- a/base/task/sequence_manager/thread_controller.h +++ b/base/task/sequence_manager/thread_controller.h
@@ -7,6 +7,7 @@ #include <optional> #include <stack> +#include <string_view> #include <vector> #include "base/base_export.h" @@ -426,7 +427,7 @@ std::string GetSuffixForHistogram(TimeDelta duration); std::string GetSuffixForCatchAllHistogram(); - StringPiece GetThreadName(); + std::string_view GetThreadName(); const raw_ref<TimeKeeper> time_keeper_; // Must be set shortly before ~RunLevel.
diff --git a/base/task/thread_pool/thread_group.cc b/base/task/thread_pool/thread_group.cc index c33900d..c483c8a 100644 --- a/base/task/thread_pool/thread_group.cc +++ b/base/task/thread_pool/thread_group.cc
@@ -4,6 +4,7 @@ #include "base/task/thread_pool/thread_group.h" +#include <string_view> #include <utility> #include "base/check.h" @@ -140,8 +141,8 @@ destination_thread_group_ = destination_thread_group; } -ThreadGroup::ThreadGroup(StringPiece histogram_label, - StringPiece thread_group_label, +ThreadGroup::ThreadGroup(std::string_view histogram_label, + std::string_view thread_group_label, ThreadType thread_type_hint, TrackedRef<TaskTracker> task_tracker, TrackedRef<Delegate> delegate)
diff --git a/base/task/thread_pool/thread_group.h b/base/task/thread_pool/thread_group.h index a42a147..689cd69f 100644 --- a/base/task/thread_pool/thread_group.h +++ b/base/task/thread_pool/thread_group.h
@@ -8,12 +8,12 @@ #include <memory> #include <optional> #include <string> +#include <string_view> #include <vector> #include "base/base_export.h" #include "base/dcheck_is_on.h" #include "base/memory/raw_ptr.h" -#include "base/strings/string_piece.h" #include "base/task/common/checked_lock.h" #include "base/task/thread_pool/priority_queue.h" #include "base/task/thread_pool/task.h" @@ -198,8 +198,8 @@ class ThreadGroupWorkerDelegate; protected: - ThreadGroup(StringPiece histogram_label, - StringPiece thread_group_label, + ThreadGroup(std::string_view histogram_label, + std::string_view thread_group_label, ThreadType thread_type_hint, TrackedRef<TaskTracker> task_tracker, TrackedRef<Delegate> delegate);
diff --git a/base/task/thread_pool/thread_group_impl.cc b/base/task/thread_pool/thread_group_impl.cc index 3698c15..5ad680e 100644 --- a/base/task/thread_pool/thread_group_impl.cc +++ b/base/task/thread_pool/thread_group_impl.cc
@@ -5,11 +5,11 @@ #include "base/task/thread_pool/thread_group_impl.h" #include <optional> +#include <string_view> #include "base/auto_reset.h" #include "base/metrics/histogram_macros.h" #include "base/sequence_token.h" -#include "base/strings/string_piece.h" #include "base/task/common/checked_lock.h" #include "base/task/thread_pool/thread_group_worker_delegate.h" #include "base/task/thread_pool/worker_thread_waitable_event.h" @@ -113,8 +113,8 @@ std::make_unique<ScopedCommandsExecutor>(this)); } -ThreadGroupImpl::ThreadGroupImpl(StringPiece histogram_label, - StringPiece thread_group_label, +ThreadGroupImpl::ThreadGroupImpl(std::string_view histogram_label, + std::string_view thread_group_label, ThreadType thread_type_hint, TrackedRef<TaskTracker> task_tracker, TrackedRef<Delegate> delegate)
diff --git a/base/task/thread_pool/thread_group_impl.h b/base/task/thread_pool/thread_group_impl.h index 03b81d9..e939137a 100644 --- a/base/task/thread_pool/thread_group_impl.h +++ b/base/task/thread_pool/thread_group_impl.h
@@ -6,11 +6,11 @@ #define BASE_TASK_THREAD_POOL_THREAD_GROUP_IMPL_H_ #include <optional> +#include <string_view> #include <vector> #include "base/base_export.h" #include "base/gtest_prod_util.h" -#include "base/strings/string_piece.h" #include "base/synchronization/condition_variable.h" #include "base/synchronization/waitable_event.h" #include "base/task/thread_pool/task_source.h" @@ -45,8 +45,8 @@ // group's threads, it must not be empty. |thread_type_hint| is the preferred // thread type; the actual thread type depends on shutdown state and platform // capabilities. |task_tracker| keeps track of tasks. - ThreadGroupImpl(StringPiece histogram_label, - StringPiece thread_group_label, + ThreadGroupImpl(std::string_view histogram_label, + std::string_view thread_group_label, ThreadType thread_type_hint, TrackedRef<TaskTracker> task_tracker, TrackedRef<Delegate> delegate);
diff --git a/base/task/thread_pool/thread_group_semaphore.cc b/base/task/thread_pool/thread_group_semaphore.cc index 9de058bd..1759d32 100644 --- a/base/task/thread_pool/thread_group_semaphore.cc +++ b/base/task/thread_pool/thread_group_semaphore.cc
@@ -5,10 +5,10 @@ #include "base/task/thread_pool/thread_group_semaphore.h" #include <algorithm> +#include <string_view> #include "base/metrics/histogram_macros.h" #include "base/sequence_token.h" -#include "base/strings/string_piece.h" #include "base/strings/stringprintf.h" #include "base/task/common/checked_lock.h" #include "base/task/thread_pool/thread_group.h" @@ -118,8 +118,8 @@ return std::make_unique<SemaphoreScopedCommandsExecutor>(this); } -ThreadGroupSemaphore::ThreadGroupSemaphore(StringPiece histogram_label, - StringPiece thread_group_label, +ThreadGroupSemaphore::ThreadGroupSemaphore(std::string_view histogram_label, + std::string_view thread_group_label, ThreadType thread_type_hint, TrackedRef<TaskTracker> task_tracker, TrackedRef<Delegate> delegate)
diff --git a/base/task/thread_pool/thread_group_semaphore.h b/base/task/thread_pool/thread_group_semaphore.h index 227a4e2..a8409f2 100644 --- a/base/task/thread_pool/thread_group_semaphore.h +++ b/base/task/thread_pool/thread_group_semaphore.h
@@ -6,9 +6,9 @@ #define BASE_TASK_THREAD_POOL_THREAD_GROUP_SEMAPHORE_H_ #include <optional> +#include <string_view> #include "base/base_export.h" -#include "base/strings/string_piece.h" #include "base/task/thread_pool/task_source.h" #include "base/task/thread_pool/thread_group_impl.h" #include "base/task/thread_pool/worker_thread_semaphore.h" @@ -32,8 +32,8 @@ // group's threads, it must not be empty. `thread_type_hint` is the preferred // thread type; the actual thread type depends on shutdown state and platform // capabilities. `task_tracker` keeps track of tasks. - ThreadGroupSemaphore(StringPiece histogram_label, - StringPiece thread_group_label, + ThreadGroupSemaphore(std::string_view histogram_label, + std::string_view thread_group_label, ThreadType thread_type_hint, TrackedRef<TaskTracker> task_tracker, TrackedRef<Delegate> delegate);
diff --git a/base/task/thread_pool/thread_pool_impl.cc b/base/task/thread_pool/thread_pool_impl.cc index 6107054b..84ef86e5 100644 --- a/base/task/thread_pool/thread_pool_impl.cc +++ b/base/task/thread_pool/thread_pool_impl.cc
@@ -7,6 +7,7 @@ #include <algorithm> #include <optional> #include <string> +#include <string_view> #include <utility> #include "base/base_switches.h" @@ -68,10 +69,10 @@ } // namespace -ThreadPoolImpl::ThreadPoolImpl(StringPiece histogram_label) +ThreadPoolImpl::ThreadPoolImpl(std::string_view histogram_label) : ThreadPoolImpl(histogram_label, std::make_unique<TaskTrackerImpl>()) {} -ThreadPoolImpl::ThreadPoolImpl(StringPiece histogram_label, +ThreadPoolImpl::ThreadPoolImpl(std::string_view histogram_label, std::unique_ptr<TaskTrackerImpl> task_tracker, bool use_background_threads) : histogram_label_(histogram_label),
diff --git a/base/task/thread_pool/thread_pool_impl.h b/base/task/thread_pool/thread_pool_impl.h index a4b3aeff..a5f05d1 100644 --- a/base/task/thread_pool/thread_pool_impl.h +++ b/base/task/thread_pool/thread_pool_impl.h
@@ -7,13 +7,13 @@ #include <memory> #include <optional> +#include <string_view> #include "base/base_export.h" #include "base/dcheck_is_on.h" #include "base/functional/callback.h" #include "base/memory/ptr_util.h" #include "base/sequence_checker.h" -#include "base/strings/string_piece.h" #include "base/synchronization/atomic_flag.h" #include "base/task/single_thread_task_runner_thread_mode.h" #include "base/task/task_traits.h" @@ -48,12 +48,12 @@ // Creates a ThreadPoolImpl with a production TaskTracker. |histogram_label| // is used to label histograms. No histograms are recorded if it is empty. - explicit ThreadPoolImpl(StringPiece histogram_label); + explicit ThreadPoolImpl(std::string_view histogram_label); // For testing only. Creates a ThreadPoolImpl with a custom TaskTracker. // If |!use_background_threads|, background threads will run with default // priority. - ThreadPoolImpl(StringPiece histogram_label, + ThreadPoolImpl(std::string_view histogram_label, std::unique_ptr<TaskTrackerImpl> task_tracker, bool use_background_threads = true);
diff --git a/base/task/thread_pool/thread_pool_instance.cc b/base/task/thread_pool/thread_pool_instance.cc index d11c385..86ff4d95 100644 --- a/base/task/thread_pool/thread_pool_instance.cc +++ b/base/task/thread_pool/thread_pool_instance.cc
@@ -5,6 +5,7 @@ #include "base/task/thread_pool/thread_pool_instance.h" #include <algorithm> +#include <string_view> #include "base/check.h" #include "base/memory/ptr_util.h" @@ -84,7 +85,8 @@ #if !BUILDFLAG(IS_NACL) // static -void ThreadPoolInstance::CreateAndStartWithDefaultParams(StringPiece name) { +void ThreadPoolInstance::CreateAndStartWithDefaultParams( + std::string_view name) { Create(name); g_thread_pool->StartWithDefaultParams(); } @@ -102,7 +104,7 @@ } #endif // !BUILDFLAG(IS_NACL) -void ThreadPoolInstance::Create(StringPiece name) { +void ThreadPoolInstance::Create(std::string_view name) { Set(std::make_unique<internal::ThreadPoolImpl>(name)); }
diff --git a/base/task/thread_pool/thread_pool_instance.h b/base/task/thread_pool/thread_pool_instance.h index 1fd429d..47828c1 100644 --- a/base/task/thread_pool/thread_pool_instance.h +++ b/base/task/thread_pool/thread_pool_instance.h
@@ -6,11 +6,11 @@ #define BASE_TASK_THREAD_POOL_THREAD_POOL_INSTANCE_H_ #include <memory> +#include <string_view> #include "base/base_export.h" #include "base/functional/callback.h" #include "base/gtest_prod_util.h" -#include "base/strings/string_piece.h" #include "base/task/sequenced_task_runner.h" #include "base/task/single_thread_task_runner.h" #include "base/task/single_thread_task_runner_thread_mode.h" @@ -220,7 +220,7 @@ // that calls this. Start() is called by this method; it is invalid to call it // again afterwards. CHECKs on failure. For tests, prefer // base::test::TaskEnvironment (ensures isolation). - static void CreateAndStartWithDefaultParams(StringPiece name); + static void CreateAndStartWithDefaultParams(std::string_view name); // Same as CreateAndStartWithDefaultParams() but allows callers to split the // Create() and StartWithDefaultParams() calls. Start() is called by this @@ -234,7 +234,7 @@ // called. Tasks can be posted at any time but will not run until after // Start() is called. For tests, prefer base::test::TaskEnvironment // (ensures isolation). - static void Create(StringPiece name); + static void Create(std::string_view name); // Registers |thread_pool| to handle tasks posted through the thread_pool.h // API for this process. For tests, prefer base::test::TaskEnvironment
diff --git a/build/toolchain/ios/BUILD.gn b/build/toolchain/ios/BUILD.gn index 7ab995a..58676f57 100644 --- a/build/toolchain/ios/BUILD.gn +++ b/build/toolchain/ios/BUILD.gn
@@ -76,9 +76,10 @@ } } -ios_toolchain("ios_clang_arm") { +ios_toolchain("ios_clang_arm64_16_0") { toolchain_args = { - current_cpu = "arm" + current_cpu = "arm64" + ios_deployment_target = "16.0" } } @@ -88,9 +89,10 @@ } } -ios_toolchain("ios_clang_x86") { +ios_toolchain("ios_clang_x64_16_0") { toolchain_args = { - current_cpu = "x86" + current_cpu = "x64" + ios_deployment_target = "16.0" } }
diff --git a/cc/tiles/mipmap_util.cc b/cc/tiles/mipmap_util.cc index 37779072..0ca8c14 100644 --- a/cc/tiles/mipmap_util.cc +++ b/cc/tiles/mipmap_util.cc
@@ -24,7 +24,7 @@ // Increment the size by (2^mip_level - 1) so we round on when dividing it // below. base::CheckedNumeric<int> base_size = axis_base_size; - base_size += (1 << mip_level) - 1; + base_size += (1u << mip_level) - 1u; axis_base_size = base_size.ValueOrDefault(std::numeric_limits<int>::max()); return std::max(1, axis_base_size >> mip_level); }
diff --git a/cc/trees/layer_tree_host_unittest_scroll.cc b/cc/trees/layer_tree_host_unittest_scroll.cc index 471644c..88226f972 100644 --- a/cc/trees/layer_tree_host_unittest_scroll.cc +++ b/cc/trees/layer_tree_host_unittest_scroll.cc
@@ -789,8 +789,8 @@ RunTest(CompositorMode::THREADED); } -// TODO(crbug.com/1521921): Test is flaky on Mac asan. -#if BUILDFLAG(IS_MAC) && defined(ADDRESS_SANITIZER) +// TODO(crbug.com/1521921): Test is flaky on asan on multiple platforms. +#if defined(ADDRESS_SANITIZER) #define MAYBE_DeviceScaleFactor2_ScrollChild \ DISABLED_DeviceScaleFactor2_ScrollChild #else @@ -803,8 +803,9 @@ RunTest(CompositorMode::THREADED); } -// TODO(crbug.com/1521395): Test is flaky on Linux and Mac. -#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_MAC) +// TODO(crbug.com/1521395): Test is flaky on asan on multiple platforms. +#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_MAC) || \ + defined(ADDRESS_SANITIZER) #define MAYBE_DeviceScaleFactor1_ScrollRootScrollLayer \ DISABLED_DeviceScaleFactor1_ScrollRootScrollLayer #else @@ -820,7 +821,8 @@ // TODO(crbug.com/1521926): Test is flaky on Win asan. // TODO(crbug.com/1517753): Test is flaky on Mac asan. -#if (BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)) && defined(ADDRESS_SANITIZER) +// Test is flaky on asan on multiple platforms. +#if defined(ADDRESS_SANITIZER) #define MAYBE_DeviceScaleFactor15_ScrollRootScrollLayer \ DISABLED_DeviceScaleFactor15_ScrollRootScrollLayer #else @@ -834,7 +836,8 @@ RunTest(CompositorMode::THREADED); } -#if BUILDFLAG(IS_MAC) && defined(ADDRESS_SANITIZER) +// Test is flaky on asan on multiple platforms. +#if defined(ADDRESS_SANITIZER) // TODO(https://crbug.com/1521778): Fix the flakiness on Mac ASan and re-enable. #define MAYBE_DeviceScaleFactor2_ScrollRootScrollLayer \ DISABLED_DeviceScaleFactor2_ScrollRootScrollLayer
diff --git a/chrome/VERSION b/chrome/VERSION index 24bdad0..e16c493 100644 --- a/chrome/VERSION +++ b/chrome/VERSION
@@ -1,4 +1,4 @@ MAJOR=124 MINOR=0 -BUILD=6366 +BUILD=6367 PATCH=0
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index ecc791d..8d37f880e 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn
@@ -1300,6 +1300,7 @@ "//third_party/gif_player:gif_player_java", "//third_party/google-truth:google_truth_java", "//third_party/hamcrest:hamcrest_java", + "//third_party/metrics_proto:metrics_proto_java", "//ui/accessibility:ax_base_java", "//ui/accessibility:ui_accessibility_features_java", "//ui/android:ui_java", @@ -3754,6 +3755,7 @@ "java/src/org/chromium/chrome/browser/tabmodel/TabModelJniBridge.java", "java/src/org/chromium/chrome/browser/tabmodel/TabModelObserverJniBridge.java", "java/src/org/chromium/chrome/browser/usage_stats/UsageStatsBridge.java", + "java/src/org/chromium/chrome/browser/webapps/PwaRestorePromoUtils.java", "java/src/org/chromium/chrome/browser/webapps/WebApkDataProvider.java", "java/src/org/chromium/chrome/browser/webapps/WebApkHandlerDelegate.java", "java/src/org/chromium/chrome/browser/webapps/WebApkInstallService.java",
diff --git a/chrome/android/chrome_java_sources.gni b/chrome/android/chrome_java_sources.gni index 4803716..6406705 100644 --- a/chrome/android/chrome_java_sources.gni +++ b/chrome/android/chrome_java_sources.gni
@@ -1198,6 +1198,7 @@ "java/src/org/chromium/chrome/browser/webapps/AddToHomescreenMostVisitedTileClickObserver.java", "java/src/org/chromium/chrome/browser/webapps/ChromeWebApkHost.java", "java/src/org/chromium/chrome/browser/webapps/GooglePlayWebApkInstallDelegate.java", + "java/src/org/chromium/chrome/browser/webapps/PwaRestorePromoUtils.java", "java/src/org/chromium/chrome/browser/webapps/SameTaskWebApkActivity.java", "java/src/org/chromium/chrome/browser/webapps/WebApkActivityCoordinator.java", "java/src/org/chromium/chrome/browser/webapps/WebApkActivityLifecycleUmaTracker.java",
diff --git a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryView.java b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryView.java index 0093780e..2cb82da 100644 --- a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryView.java +++ b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryView.java
@@ -161,6 +161,14 @@ @Override public boolean onInterceptTouchEvent(MotionEvent event) { + final boolean isViewObscured = + (event.getFlags() & MotionEvent.FLAG_WINDOW_IS_PARTIALLY_OBSCURED) != 0 + || (event.getFlags() & MotionEvent.FLAG_WINDOW_IS_OBSCURED) != 0; + // The event is filtered out when the keyboard accessory view is fully or partially obscured + // given that no user education bubbles are shown to the user. + if (isViewObscured && !mAllowClicksWhileObscured) { + return true; + } // When keyboard accessory view is fully or partially obsured, clicks are allowed only if // the user education bubble is being displayed. After the first click // (MotionEvent.ACTION_UP), such motion events start to get filtered again. Please note that
diff --git a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/sheet_component/AccessorySheetView.java b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/sheet_component/AccessorySheetView.java index 8be7d44..496bb1e 100644 --- a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/sheet_component/AccessorySheetView.java +++ b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/sheet_component/AccessorySheetView.java
@@ -8,6 +8,7 @@ import android.content.Context; import android.util.AttributeSet; +import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.widget.FrameLayout; @@ -35,6 +36,17 @@ } @Override + public boolean onInterceptTouchEvent(MotionEvent event) { + final boolean isObscured = + (event.getFlags() & MotionEvent.FLAG_WINDOW_IS_PARTIALLY_OBSCURED) != 0 + || (event.getFlags() & MotionEvent.FLAG_WINDOW_IS_OBSCURED) != 0; + if (isObscured) { + return true; + } + return super.onInterceptTouchEvent(event); + } + + @Override protected void onFinishInflate() { super.onFinishInflate(); mViewPager = findViewById(R.id.keyboard_accessory_sheet); @@ -47,6 +59,14 @@ findViewById(R.id.sheet_header).setVisibility(View.VISIBLE); findViewById(R.id.sheet_header_shadow).setVisibility(View.VISIBLE); + // Set listener's to touch/click events so they are not propagated to the page below. + setOnTouchListener( + (view, motionEvent) -> { + performClick(); // Setting a touch listener requires this call which is a NoOp. + // Return that the motionEvent was consumed and needs no further handling. + return true; + }); + // Ensure that sub components of the sheet use the RTL direction: int layoutDirection = isLayoutRtl() ? View.LAYOUT_DIRECTION_RTL : View.LAYOUT_DIRECTION_LTR; mViewPager.setLayoutDirection(layoutDirection);
diff --git a/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/AutofillKeyboardAccessoryIntegrationTest.java b/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/AutofillKeyboardAccessoryIntegrationTest.java index 44a8c763..3dd17644 100644 --- a/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/AutofillKeyboardAccessoryIntegrationTest.java +++ b/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/AutofillKeyboardAccessoryIntegrationTest.java
@@ -4,20 +4,26 @@ package org.chromium.chrome.browser.keyboard_accessory; +import static androidx.test.espresso.Espresso.onView; import static androidx.test.espresso.action.ViewActions.click; +import static androidx.test.espresso.assertion.ViewAssertions.matches; import static androidx.test.espresso.contrib.RecyclerViewActions.actionOnItem; import static androidx.test.espresso.contrib.RecyclerViewActions.scrollTo; import static androidx.test.espresso.matcher.ViewMatchers.isAssignableFrom; +import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed; import static androidx.test.espresso.matcher.ViewMatchers.withChild; import static androidx.test.espresso.matcher.ViewMatchers.withId; import static org.junit.Assert.assertTrue; +import static org.chromium.base.test.util.ViewActionOnDescendant.performOnRecyclerViewNthItem; +import static org.chromium.chrome.browser.autofill.AutofillTestHelper.createClickActionWithFlags; import static org.chromium.chrome.browser.keyboard_accessory.ManualFillingTestHelper.selectTabAtPosition; import static org.chromium.chrome.browser.keyboard_accessory.ManualFillingTestHelper.waitToBeHidden; import static org.chromium.chrome.browser.keyboard_accessory.ManualFillingTestHelper.whenDisplayed; import android.app.Activity; +import android.view.MotionEvent; import android.view.View; import androidx.test.filters.MediumTest; @@ -161,6 +167,29 @@ } @Test + @MediumTest + public void testClicksThroughOtherSurfaceAreIgnored() + throws ExecutionException, TimeoutException, InterruptedException { + MultiWindowUtils.getInstance().setIsInMultiWindowModeForTesting(true); + loadTestPage(MultiWindowKeyboard::new); + mHelper.clickNode("NAME_FIRST", 1, FocusedFieldType.FILLABLE_NON_SEARCH_FIELD); + mHelper.waitForKeyboardAccessoryToBeShown(true); + + for (int i = 0; i < mHelper.getAccessoryBarView().getAdapter().getItemCount(); i++) { + performOnRecyclerViewNthItem( + withId(R.id.bar_items_view), + i, + createClickActionWithFlags(MotionEvent.FLAG_WINDOW_IS_OBSCURED)); + onView(withId(R.id.keyboard_accessory)).check(matches(isDisplayed())); + performOnRecyclerViewNthItem( + withId(R.id.bar_items_view), + i, + createClickActionWithFlags(MotionEvent.FLAG_WINDOW_IS_PARTIALLY_OBSCURED)); + onView(withId(R.id.keyboard_accessory)).check(matches(isDisplayed())); + } + } + + @Test @SmallTest public void testPressingBackButtonHidesAccessoryWithAutofillSuggestions() throws TimeoutException, ExecutionException {
diff --git a/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/sheet_component/AccessorySheetViewTest.java b/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/sheet_component/AccessorySheetViewTest.java index 0445c34..a539f22 100644 --- a/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/sheet_component/AccessorySheetViewTest.java +++ b/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/sheet_component/AccessorySheetViewTest.java
@@ -21,6 +21,7 @@ import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; +import static org.chromium.chrome.browser.autofill.AutofillTestHelper.createClickActionWithFlags; import static org.chromium.chrome.browser.keyboard_accessory.sheet_component.AccessorySheetProperties.ACTIVE_TAB_INDEX; import static org.chromium.chrome.browser.keyboard_accessory.sheet_component.AccessorySheetProperties.HEIGHT; import static org.chromium.chrome.browser.keyboard_accessory.sheet_component.AccessorySheetProperties.SHOW_KEYBOARD_CALLBACK; @@ -29,6 +30,7 @@ import static org.chromium.chrome.browser.keyboard_accessory.sheet_component.AccessorySheetProperties.VISIBLE; import static org.chromium.ui.test.util.ViewUtils.onViewWaiting; +import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.widget.LinearLayout; @@ -276,6 +278,29 @@ onViewWaiting(withId(R.id.sheet_header_shadow)); } + @Test + @MediumTest + public void testFiltersTouchesWhenObscured() { + Runnable runnable = mock(Runnable.class); + + TestThreadUtils.runOnUiThreadBlocking( + () -> { + mModel.get(TABS).add(createTestTabWithTextView("Header")); + mModel.set(ACTIVE_TAB_INDEX, 0); + mModel.set(SHOW_KEYBOARD_CALLBACK, runnable); + mModel.set(VISIBLE, true); + }); + + // Any clicks should be ignored when the sheet view is fully of partially obscured. + onViewWaiting(withId(R.id.show_keyboard)) + .perform(createClickActionWithFlags(MotionEvent.FLAG_WINDOW_IS_OBSCURED)); + verify(runnable, times(0)).run(); + + onViewWaiting(withId(R.id.show_keyboard)) + .perform(createClickActionWithFlags(MotionEvent.FLAG_WINDOW_IS_PARTIALLY_OBSCURED)); + verify(runnable, times(0)).run(); + } + private Tab createTestTabWithTextView(String textViewCaption) { return new Tab( "Passwords",
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 25aa8fd..25ce6a9 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
@@ -42,6 +42,7 @@ import org.chromium.base.Callback; import org.chromium.base.CommandLine; import org.chromium.base.ContextUtils; +import org.chromium.base.InputHintChecker; import org.chromium.base.Log; import org.chromium.base.PowerMonitor; import org.chromium.base.StrictModeContext; @@ -1200,10 +1201,10 @@ // Close the current UMA record and start a new UMA one. markSessionResume(); - // Inform the actity lifecycle observers. Among other things, the observers record - // metrics pertaining to the "resumed" activity. This needs to happens after - // markSessionResume has closed the old UMA record, pertaining to the previous - // (backgrounded) activity, and opened a new one pertaining to the "resumed" activity. + // Inform the activity lifecycle observers. Among other things, the observers record metrics + // pertaining to the "resumed" activity. This needs to happen after markSessionResume has + // closed the old UMA record, pertaining to the previous (backgrounded) activity, and opened + // a new one pertaining to the "resumed" activity. super.onResumeWithNative(); // Resume the ChromeActivity... @@ -1221,8 +1222,8 @@ if (webContents != null) webContents.notifyRendererPreferenceUpdate(); } - ChromeSessionState.setIsInMultiWindowMode( - MultiWindowUtils.getInstance().isInMultiWindowMode(this)); + boolean inMultiWindowMode = MultiWindowUtils.getInstance().isInMultiWindowMode(this); + ChromeSessionState.setIsInMultiWindowMode(inMultiWindowMode); boolean appIsInNightMode = getNightModeStateProvider().isInNightMode(); boolean systemIsInNightMode = SystemNightModeMonitor.getInstance().isSystemNightModeOn(); @@ -1237,6 +1238,12 @@ getManualFillingComponent().onResume(); checkForDeviceLockOnAutomotive(); + setViewForInputHint(inMultiWindowMode); + } + + private void setViewForInputHint(boolean inMultiWindowMode) { + View view = inMultiWindowMode ? null : getWindow().getDecorView(); + InputHintChecker.setView(view); } private void checkForDeviceLockOnAutomotive() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/creator/CreatorActionDelegateImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/app/creator/CreatorActionDelegateImpl.java index 950950a..a35fb84 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/app/creator/CreatorActionDelegateImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/app/creator/CreatorActionDelegateImpl.java
@@ -6,8 +6,6 @@ import android.app.Activity; -import androidx.annotation.StringRes; - import org.chromium.base.Callback; import org.chromium.base.Log; import org.chromium.base.ThreadUtils; @@ -117,38 +115,22 @@ int signinAccessPoint, BottomSheetController mBottomSheetController, WindowAndroid mWindowAndroid) { + AccountPickerBottomSheetStrings strings = + new AccountPickerBottomSheetStrings( + R.string.signin_account_picker_bottom_sheet_title_for_cormorant_signin, + R.string.signin_account_picker_bottom_sheet_subtitle_for_cormorant_signin, + R.string.close); SigninBottomSheetCoordinator signinCoordinator = new SigninBottomSheetCoordinator( mWindowAndroid, DeviceLockActivityLauncherImpl.get(), mBottomSheetController, mProfile, - new CormorantBottomSheetStrings(), + strings, () -> { showSyncConsentActivity(signinAccessPoint); }, signinAccessPoint); signinCoordinator.show(); } - - /** Stores bottom sheet strings for signin from cormorant entry point */ - public static class CormorantBottomSheetStrings implements AccountPickerBottomSheetStrings { - /** Returns the title string for the bottom sheet dialog. */ - @Override - public @StringRes int getTitle() { - return R.string.signin_account_picker_bottom_sheet_title_for_cormorant_signin; - } - - /** Returns the subtitle string for the bottom sheet dialog. */ - @Override - public @StringRes int getSubtitle() { - return R.string.signin_account_picker_bottom_sheet_subtitle_for_cormorant_signin; - } - - /** Returns the cancel button string for the bottom sheet dialog. */ - @Override - public @StringRes int getDismissButton() { - return R.string.close; - } - } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/settings/AutofillLocalIbanEditor.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/settings/AutofillLocalIbanEditor.java index 092ca0a3..74b360c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/settings/AutofillLocalIbanEditor.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/settings/AutofillLocalIbanEditor.java
@@ -13,8 +13,12 @@ import android.widget.Button; import android.widget.EditText; +import androidx.annotation.VisibleForTesting; +import androidx.fragment.app.Fragment; + import com.google.android.material.textfield.TextInputLayout; +import org.chromium.base.Callback; import org.chromium.build.annotations.UsedByReflection; import org.chromium.chrome.R; import org.chromium.chrome.browser.autofill.AutofillEditorBase; @@ -22,9 +26,13 @@ import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.settings.ProfileDependentSetting; +/** + * This class creates a view for adding a local IBAN. A local IBAN gets saved to the user's device + * only. + */ public class AutofillLocalIbanEditor extends AutofillEditorBase implements ProfileDependentSetting { - // This class creates a view for adding a local IBAN. A local IBAN gets saved to the - // user's device only. + private static Callback<Fragment> sObserverForTest; + protected Button mDoneButton; protected EditText mNickname; protected TextInputLayout mNicknameLabel; @@ -50,6 +58,9 @@ (view, hasFocus) -> mNicknameLabel.setCounterEnabled(hasFocus)); initializeButtons(v); + if (sObserverForTest != null) { + sObserverForTest.onResult(this); + } return v; } @@ -92,6 +103,11 @@ mValue.addTextChangedListener(this); } + @VisibleForTesting + public static void setObserverForTest(Callback<Fragment> observerForTest) { + sObserverForTest = observerForTest; + } + private void updateSaveButtonEnabled() { // Enable save button if IBAN value is valid. mDoneButton.setEnabled(
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/settings/AutofillPaymentMethodsFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/settings/AutofillPaymentMethodsFragment.java index db4b577..a4ec05a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/settings/AutofillPaymentMethodsFragment.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/settings/AutofillPaymentMethodsFragment.java
@@ -63,6 +63,7 @@ static final String PREF_DELETE_SAVED_CVCS = "delete_saved_cvcs"; static final String PREF_MANDATORY_REAUTH = "mandatory_reauth"; static final String PREF_SAVE_CVC = "save_cvc"; + static final String PREF_ADD_IBAN = "add_iban"; private static final String PREF_PAYMENT_APPS = "payment_apps"; static final String MANDATORY_REAUTH_EDIT_CARD_HISTOGRAM = @@ -279,6 +280,23 @@ getPreferenceScreen().addPreference(add_card_pref); } + // Add 'Add IBAN' button. Tapping it brings up the IBAN editor which allows users to type in + // a new IBAN. + if (ChromeFeatureList.isEnabled(ChromeFeatureList.AUTOFILL_ENABLE_LOCAL_IBAN) + && personalDataManager.isAutofillCreditCardEnabled()) { + Preference add_iban_pref = new Preference(getStyledContext()); + Drawable plusIcon = ApiCompatibilityUtils.getDrawable(getResources(), R.drawable.plus); + plusIcon.mutate(); + plusIcon.setColorFilter( + SemanticColorUtils.getDefaultControlColorActive(getContext()), + PorterDuff.Mode.SRC_IN); + add_iban_pref.setIcon(plusIcon); + add_iban_pref.setTitle(R.string.autofill_add_local_iban); + add_iban_pref.setKey(PREF_ADD_IBAN); + add_iban_pref.setFragment(AutofillLocalIbanEditor.class.getName()); + getPreferenceScreen().addPreference(add_iban_pref); + } + // Add the link to payment apps only after the credit card list is rebuilt. Preference payment_apps_pref = new Preference(getStyledContext()); payment_apps_pref.setTitle(R.string.payment_apps_title);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/browsing_data/BrowsingDataBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/browsing_data/BrowsingDataBridge.java index ef29589..359fefc3 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/browsing_data/BrowsingDataBridge.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/browsing_data/BrowsingDataBridge.java
@@ -7,13 +7,19 @@ import org.jni_zero.CalledByNative; import org.jni_zero.NativeMethods; +import org.chromium.base.Callback; import org.chromium.base.ThreadUtils; import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.profiles.ProfileKeyedMap; +import org.chromium.components.browser_ui.site_settings.BrowsingDataInfo; +import org.chromium.url.Origin; + +import java.util.HashMap; +import java.util.Map; /** - * Communicates between ClearBrowsingData, ImportantSitesUtils (C++) and - * ClearBrowsingDataFragment (Java UI). + * Communicates between ClearBrowsingData, ImportantSitesUtils (C++) and ClearBrowsingDataFragment + * (Java UI). */ public final class BrowsingDataBridge { private static ProfileKeyedMap<BrowsingDataBridge> sProfileMap; @@ -264,6 +270,21 @@ .setLastClearBrowsingDataTab(BrowsingDataBridge.this, mProfile, tabIndex); } + @CalledByNative + private static Object createBrowsingDataInfoMap() { + return new HashMap<Origin, BrowsingDataInfo>(); + } + + @CalledByNative + private static void insertBrowsingDataInfoIntoMap( + Map<Origin, BrowsingDataInfo> map, Origin origin, int cookieCount, long storageSize) { + map.put(origin, new BrowsingDataInfo(origin, cookieCount, storageSize)); + } + + public void fetchBrowsingDataInfo(Callback<Map<Origin, BrowsingDataInfo>> callback) { + BrowsingDataBridgeJni.get().fetchBrowsingDataInfo(mProfile, callback); + } + @NativeMethods public interface Natives { void clearBrowsingData( @@ -310,5 +331,8 @@ int getLastClearBrowsingDataTab(BrowsingDataBridge caller, Profile profile); void setLastClearBrowsingDataTab(BrowsingDataBridge caller, Profile profile, int lastTab); + + void fetchBrowsingDataInfo( + Profile profile, Callback<Map<Origin, BrowsingDataInfo>> callback); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/CompositorViewHolder.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/CompositorViewHolder.java index aa7e48a..1b45d8c0 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/CompositorViewHolder.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/CompositorViewHolder.java
@@ -308,6 +308,11 @@ } @Override + public void onWillShowBrowserControls(Tab tab) { + CompositorViewHolder.this.onWillShowBrowserControls(); + } + + @Override public void onWebContentsSwapped( Tab tab, boolean didStartLoad, boolean didFinishLoad) { // After swapping web contents, any gesture active in the old ContentView is @@ -1518,6 +1523,22 @@ setTab(tab); } + @VisibleForTesting + void onWillShowBrowserControls() { + // TODO(bokan): Flag guarding new behavior, remove once M125 ships. + // https://crbug.com/41490049. + if (!ChromeFeatureList.sBrowserControlsEarlyResize.isEnabled()) return; + + // Let observers know the controls will be shown, resize the web content + // immediately rather than waiting for the controls animation to finish. This + // helps makes the resize more predictable, in particular, when capturing + // snapshots of outgoing content for a view transition. + if (mControlsResizeView) return; + mControlsResizeView = true; + updateWebContentsSize(getCurrentTab()); + onControlsResizeViewChanged(getWebContents(), mControlsResizeView); + } + private void setTab(Tab tab) { // The StartSurfaceUserData.getInstance().getUnusedTabRestoredAtStartup() is only true when // the Start surface is showing in the startup and there isn't any Tab opened. Thus, no
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/searchwidget/SearchActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/searchwidget/SearchActivity.java index 57aed9b..3d2d674 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/searchwidget/SearchActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/searchwidget/SearchActivity.java
@@ -12,12 +12,12 @@ import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.net.Uri; -import android.text.TextUtils; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import androidx.annotation.ColorInt; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; import androidx.core.app.ActivityOptionsCompat; @@ -51,9 +51,9 @@ import org.chromium.chrome.browser.omnibox.BackKeyBehaviorDelegate; import org.chromium.chrome.browser.omnibox.LocationBarCoordinator; import org.chromium.chrome.browser.omnibox.OmniboxFeatures; -import org.chromium.chrome.browser.omnibox.OverrideUrlLoadingDelegate; import org.chromium.chrome.browser.omnibox.UrlFocusChangeListener; import org.chromium.chrome.browser.omnibox.styles.OmniboxResourceProvider; +import org.chromium.chrome.browser.omnibox.suggestions.OmniboxLoadUrlParams; import org.chromium.chrome.browser.omnibox.suggestions.OmniboxSuggestionsDropdownScrollListener; import org.chromium.chrome.browser.omnibox.suggestions.action.OmniboxActionDelegateImpl; import org.chromium.chrome.browser.omnibox.voice.VoiceRecognitionHandler; @@ -82,15 +82,13 @@ import org.chromium.components.browser_ui.widget.InsetObserver; import org.chromium.components.browser_ui.widget.InsetObserverSupplier; import org.chromium.components.external_intents.ExternalNavigationHandler; -import org.chromium.components.url_formatter.UrlFormatter; +import org.chromium.components.metrics.OmniboxEventProtos.OmniboxEventProto.PageClassification; import org.chromium.content_public.browser.LoadUrlParams; import org.chromium.content_public.browser.WebContents; import org.chromium.content_public.common.ContentUrlConstants; import org.chromium.ui.base.ActivityWindowAndroid; -import org.chromium.ui.base.PageTransition; import org.chromium.ui.base.WindowDelegate; import org.chromium.ui.modaldialog.ModalDialogManager; -import org.chromium.url.GURL; import java.lang.ref.WeakReference; @@ -158,11 +156,7 @@ private boolean mIsActivityUsable; /** Input submitted before before the native library was loaded. */ - private String mQueuedUrl; - - private @PageTransition int mQueuedTransition; - private String mQueuedPostDataType; - private byte[] mQueuedPostData; + private OmniboxLoadUrlParams mQueuedParams; /** The View that represents the search box. */ private SearchActivityLocationBarLayout mSearchBox; @@ -251,17 +245,6 @@ } } - OverrideUrlLoadingDelegate overrideUrlLoadingDelegate = - (String url, - @PageTransition int transition, - long inputStart, - String postDataType, - byte[] postData, - boolean incognito) -> { - loadUrl(url, transition, postDataType, postData); - return true; - }; - BackPressManager backPressManager = new BackPressManager(); getOnBackPressedDispatcher().addCallback(this, backPressManager.getCallback()); mLocationBarCoordinator = @@ -279,7 +262,7 @@ /* shareDelegateSupplier= */ null, /* incognitoStateProvider= */ null, getLifecycleDispatcher(), - overrideUrlLoadingDelegate, + this::loadUrl, /* backKeyBehavior= */ this, /* pageInfoAction= */ (tab, pageInfoHighlight) -> {}, IntentHandler::bringTabToFront, @@ -352,12 +335,26 @@ mIntentOrigin = SearchActivityUtils.getIntentOrigin(intent); mSearchType = SearchActivityUtils.getIntentSearchType(intent); - if (mIntentOrigin == IntentOrigin.QUICK_ACTION_SEARCH_WIDGET) { - recordQuickActionSearchType(mSearchType); + switch (mIntentOrigin) { + case IntentOrigin.CUSTOM_TAB: + // TODO(crbug/327023983): Recognize SRP. + mSearchBoxDataProvider.setPageClassification(PageClassification.OTHER_VALUE); + break; + + case IntentOrigin.QUICK_ACTION_SEARCH_WIDGET: + recordQuickActionSearchType(mSearchType); + mSearchBoxDataProvider.setPageClassification( + PageClassification.ANDROID_SHORTCUTS_WIDGET_VALUE); + break; + + case IntentOrigin.SEARCH_WIDGET: + default: + mSearchBoxDataProvider.setPageClassification( + PageClassification.ANDROID_SEARCH_WIDGET_VALUE); + break; } - mSearchBoxDataProvider.setIsFromQuickActionSearchWidget( - mIntentOrigin == IntentOrigin.QUICK_ACTION_SEARCH_WIDGET); + mSearchBoxDataProvider.setCurrentUrl(SearchActivityUtils.getIntentUrl(intent)); } @Override @@ -495,8 +492,9 @@ assert !mIsActivityUsable : "finishDeferredInitialization() incorrectly called multiple times"; mIsActivityUsable = true; - if (mQueuedUrl != null) { - loadUrl(mQueuedUrl, mQueuedTransition, mQueuedPostDataType, mQueuedPostData); + if (mQueuedParams != null) { + // SearchActivity does not support incognito operation. + loadUrl(mQueuedParams, /* isIncognito= */ false); } // TODO(tedchoc): Warmup triggers the CustomTab layout to be inflated, but this widget @@ -607,37 +605,31 @@ } } - /* package */ void loadUrl( - String url, - @PageTransition int transition, - @Nullable String postDataType, - @Nullable byte[] postData) { + /* package */ boolean loadUrl(OmniboxLoadUrlParams params, boolean isIncognito) { finish(); if (mIntentOrigin == IntentOrigin.CUSTOM_TAB) { - SearchActivityUtils.resolveOmniboxRequestForResult(this, new GURL(url)); + SearchActivityUtils.resolveOmniboxRequestForResult(this, params); overridePendingTransition(0, android.R.anim.fade_out); } else { - loadUrlInChromeBrowser(url, transition, postDataType, postData); + loadUrlInChromeBrowser(params); } + return true; } - private void loadUrlInChromeBrowser( - String url, - @PageTransition int transition, - @Nullable String postDataType, - @Nullable byte[] postData) { - // Wait until native has loaded. + private void loadUrlInChromeBrowser(@NonNull OmniboxLoadUrlParams params) { if (!mIsActivityUsable) { - mQueuedUrl = url; - mQueuedTransition = transition; - mQueuedPostDataType = postDataType; - mQueuedPostData = postData; + // Wait until native has loaded. + mQueuedParams = params; return; } - Intent intent = createIntentForStartActivity(url, postDataType, postData); + Intent intent = SearchActivityUtils.createIntentForStartActivity(this, params); if (intent == null) return; + if (mIntentOrigin == IntentOrigin.SEARCH_WIDGET) { + intent.putExtra(SearchWidgetProvider.EXTRA_FROM_SEARCH_WIDGET, true); + } + IntentUtils.safeStartActivity( this, intent, @@ -645,40 +637,8 @@ this, android.R.anim.fade_in, android.R.anim.fade_out) .toBundle()); RecordUserAction.record("SearchWidget.SearchMade"); - LocaleManager.getInstance().recordLocaleBasedSearchMetrics(true, url, transition); - } - - /** - * Creates an intent that will be used to launch Chrome. - * - * @param url The URL to be loaded. - * @param postDataType postData type. - * @param postData Post-data to include in the tab URL's request body, ex. bitmap when image - * search. - * @return the intent will be passed to ChromeLauncherActivity, null if input was emprty. - */ - private Intent createIntentForStartActivity( - String url, @Nullable String postDataType, @Nullable byte[] postData) { - // Don't do anything if the input was empty. This is done after the native check to prevent - // resending a queued query after the user deleted it. - if (TextUtils.isEmpty(url)) return null; - - // Fix up the URL and send it to the full browser. - GURL fixedUrl = UrlFormatter.fixupUrl(url); - Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(fixedUrl.getValidSpecOrEmpty())); - intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_NEW_DOCUMENT); - intent.setClass(this, ChromeLauncherActivity.class); - if (!TextUtils.isEmpty(postDataType) && postData != null && postData.length != 0) { - intent.putExtra(IntentHandler.EXTRA_POST_DATA_TYPE, postDataType); - intent.putExtra(IntentHandler.EXTRA_POST_DATA, postData); - } - if (mIntentOrigin == IntentOrigin.SEARCH_WIDGET) { - intent.putExtra(SearchWidgetProvider.EXTRA_FROM_SEARCH_WIDGET, true); - } - intent.putExtra(EXTRA_FROM_SEARCH_ACTIVITY, true); - IntentUtils.addTrustedIntentExtras(intent); - - return intent; + LocaleManager.getInstance() + .recordLocaleBasedSearchMetrics(true, params.url, params.transitionType); } private ViewGroup createContentView() { @@ -829,4 +789,8 @@ /* package */ void setActivityUsableForTesting(boolean isUsable) { mIsActivityUsable = isUsable; } + + /* package */ SearchBoxDataProvider getSearchBoxDataProvider() { + return mSearchBoxDataProvider; + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/searchwidget/SearchActivityLocationBarLayout.java b/chrome/android/java/src/org/chromium/chrome/browser/searchwidget/SearchActivityLocationBarLayout.java index 27c71d85..0eac49e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/searchwidget/SearchActivityLocationBarLayout.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/searchwidget/SearchActivityLocationBarLayout.java
@@ -65,18 +65,12 @@ ToolbarPhone.createModernLocationBarBackground(getContext()); if (OmniboxFeatures.shouldShowModernizeVisualUpdate(getContext())) { backgroundDrawable.setTint( - OmniboxFeatures.shouldShowActiveColorOnOmnibox() - ? ChromeColors.getSurfaceColor( - getContext(), R.dimen.omnibox_suggestion_bg_elevation) - : ChromeColors.getSurfaceColor( - getContext(), - R.dimen.omnibox_suggestion_dropdown_bg_elevation)); - if (OmniboxFeatures.shouldShowActiveColorOnOmnibox()) { - backgroundDrawable.setCornerRadius( - getResources() - .getDimensionPixelSize( - R.dimen.omnibox_suggestion_bg_round_corner_radius)); - } + ChromeColors.getSurfaceColor( + getContext(), R.dimen.omnibox_suggestion_bg_elevation)); + backgroundDrawable.setCornerRadius( + getResources() + .getDimensionPixelSize( + R.dimen.omnibox_suggestion_bg_round_corner_radius)); setPaddingRelative( getResources().getDimensionPixelSize(R.dimen.location_bar_start_padding_modern), getPaddingTop(),
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/searchwidget/SearchActivityUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/searchwidget/SearchActivityUtils.java index 03a1633..3db1c92bb 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/searchwidget/SearchActivityUtils.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/searchwidget/SearchActivityUtils.java
@@ -10,6 +10,8 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; +import android.net.Uri; +import android.text.TextUtils; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -17,7 +19,11 @@ import org.chromium.base.IntentUtils; import org.chromium.chrome.R; +import org.chromium.chrome.browser.IntentHandler; +import org.chromium.chrome.browser.document.ChromeLauncherActivity; +import org.chromium.chrome.browser.omnibox.suggestions.OmniboxLoadUrlParams; import org.chromium.chrome.browser.ui.searchactivityutils.SearchActivityClient; +import org.chromium.components.url_formatter.UrlFormatter; import org.chromium.url.GURL; /** Class facilitating interactions with the SearchActivity and the Omnibox. */ @@ -28,7 +34,6 @@ @VisibleForTesting /* package */ static final String EXTRA_ORIGIN = "origin"; @VisibleForTesting /* package */ static final String EXTRA_SEARCH_TYPE = "search-type"; @VisibleForTesting /* package */ static final String EXTRA_CURRENT_URL = "current-url"; - @VisibleForTesting /* package */ static final String EXTRA_URL_TO_NAVIGATE = "url-to-navigate"; // Note: while we don't rely on Actions, PendingIntents do require them to be Unique. // Responsibility to define values for PendingIntents could be offset to Caller; meantime we @@ -81,7 +86,9 @@ ACTION_SEARCH_FORMAT, IntentOrigin.CUSTOM_TAB, SearchType.TEXT)) - .putExtra(EXTRA_CURRENT_URL, currentUrl.getSpec()) + .putExtra( + EXTRA_CURRENT_URL, + GURL.isEmptyOrInvalid(currentUrl) ? null : currentUrl.getSpec()) .putExtra(EXTRA_ORIGIN, IntentOrigin.CUSTOM_TAB) .putExtra(EXTRA_SEARCH_TYPE, SearchType.TEXT) .addFlags( @@ -103,8 +110,7 @@ * @return the origin of an intent */ /* package */ static @IntentOrigin int getIntentOrigin(@NonNull Intent intent) { - if (IntentUtils.isTrustedIntentFromSelf(intent) - && IntentUtils.safeHasExtra(intent, EXTRA_ORIGIN)) { + if (IntentUtils.isTrustedIntentFromSelf(intent)) { return IntentUtils.safeGetIntExtra(intent, EXTRA_ORIGIN, IntentOrigin.UNKNOWN); } @@ -112,6 +118,18 @@ } /** + * @return the document url associated with the intent, if the intent is trusted and carries + * valid URL. + */ + /* package */ static @Nullable GURL getIntentUrl(@NonNull Intent intent) { + if (IntentUtils.isTrustedIntentFromSelf(intent)) { + var gurl = new GURL(IntentUtils.safeGetStringExtra(intent, EXTRA_CURRENT_URL)); + if (!GURL.isEmptyOrInvalid(gurl)) return gurl; + } + return null; + } + + /** * Retrieve the intent search type. * * @param intent intent received by SearchActivity @@ -119,8 +137,7 @@ */ @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE) public static @SearchType int getIntentSearchType(@NonNull Intent intent) { - if (IntentUtils.isTrustedIntentFromSelf(intent) - && IntentUtils.safeHasExtra(intent, EXTRA_SEARCH_TYPE)) { + if (IntentUtils.isTrustedIntentFromSelf(intent)) { return IntentUtils.safeGetIntExtra(intent, EXTRA_SEARCH_TYPE, SearchType.TEXT); } @@ -135,22 +152,75 @@ * results with canceled request; anything else resolves request successfully */ /* package */ static void resolveOmniboxRequestForResult( - @NonNull Activity activity, @Nullable GURL url) { - if (GURL.isEmptyOrInvalid(url)) { + @NonNull Activity activity, @NonNull OmniboxLoadUrlParams params) { + var intent = createLoadUrlIntent(activity, activity.getCallingActivity(), params); + if (intent != null) { + activity.setResult(Activity.RESULT_OK, intent); + } else { activity.setResult(Activity.RESULT_CANCELED); - return; } + } - var intent = new Intent().setPackage(activity.getCallingPackage()); + /** + * Creates an intent that can be used to launch Chrome. + * + * @param context current context + * @param params information about what url to load and what additional data to pass + * @return the intent will be passed to ChromeLauncherActivity, or null if page cannot be loaded + */ + /* package */ static @Nullable Intent createIntentForStartActivity( + Context context, OmniboxLoadUrlParams params) { + var intent = + createLoadUrlIntent( + context, new ComponentName(context, ChromeLauncherActivity.class), params); + if (intent == null) return null; + + intent.setAction(Intent.ACTION_VIEW); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_NEW_DOCUMENT); + + return intent; + } + + /** + * Create a base intent that can be further expanded to request URL loading. + * + * @param context the current context + * @param recipient the activity being targeted + * @param params the OmniboxLoadUrlParams describing what URL to load and what extra data to + * pass + * @return Intent, if all the supplied data is valid, otherwise null + */ + @VisibleForTesting + /* package */ static @Nullable Intent createLoadUrlIntent( + Context context, ComponentName recipient, OmniboxLoadUrlParams params) { + // Don't do anything if the input was empty. + if (params == null || TextUtils.isEmpty(params.url)) return null; + + // Fix up the URL and send it to the full browser. + GURL fixedUrl = UrlFormatter.fixupUrl(params.url); + if (GURL.isEmptyOrInvalid(fixedUrl)) return null; + + var intent = + new Intent() + .putExtra(SearchActivity.EXTRA_FROM_SEARCH_ACTIVITY, true) + .setComponent(recipient) + .setData(Uri.parse(fixedUrl.getSpec())); // Do not pass any of these information if the calling package is something we did not // expect, but somehow it managed to fabricate a trust token. - if (IntentUtils.intentTargetsSelf(activity, intent)) { - intent.putExtra(EXTRA_URL_TO_NAVIGATE, url.getSpec()); - IntentUtils.addTrustedIntentExtras(intent); + if (!IntentUtils.intentTargetsSelf(context, intent)) { + return null; } - activity.setResult(Activity.RESULT_OK, intent); + if (!TextUtils.isEmpty(params.postDataType) + && params.postData != null + && params.postData.length != 0) { + intent.putExtra(IntentHandler.EXTRA_POST_DATA_TYPE, params.postDataType) + .putExtra(IntentHandler.EXTRA_POST_DATA, params.postData); + } + IntentUtils.addTrustedIntentExtras(intent); + + return intent; } /** @@ -164,7 +234,7 @@ public static boolean isOmniboxResult(int requestCode, @NonNull Intent intent) { return requestCode == OMNIBOX_REQUEST_CODE && IntentUtils.isTrustedIntentFromSelf(intent) - && IntentUtils.safeHasExtra(intent, EXTRA_URL_TO_NAVIGATE); + && !TextUtils.isEmpty(intent.getDataString()); } /** @@ -180,7 +250,7 @@ int requestCode, int resultCode, @NonNull Intent intent) { if (!isOmniboxResult(requestCode, intent)) return null; if (resultCode != Activity.RESULT_OK) return GURL.emptyGURL(); - return new GURL(IntentUtils.safeGetStringExtra(intent, EXTRA_URL_TO_NAVIGATE)); + return new GURL(intent.getDataString()); } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/searchwidget/SearchBoxDataProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/searchwidget/SearchBoxDataProvider.java index a85d486c..e9ba785c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/searchwidget/SearchBoxDataProvider.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/searchwidget/SearchBoxDataProvider.java
@@ -16,20 +16,15 @@ import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.ui.searchactivityutils.SearchActivityPreferencesManager; import org.chromium.components.browser_ui.styles.ChromeColors; -import org.chromium.components.metrics.OmniboxEventProtos.OmniboxEventProto.PageClassification; import org.chromium.components.security_state.ConnectionSecurityLevel; import org.chromium.url.GURL; class SearchBoxDataProvider implements LocationBarDataProvider { - private boolean mIsFromQuickActionSearchWidget; + private /* PageClassification */ int mPageClassification; private @ColorInt int mPrimaryColor; private Tab mTab; private GURL mGurl; - SearchBoxDataProvider() { - mIsFromQuickActionSearchWidget = false; - } - /** * Called when native library is loaded and a tab has been initialized. * @@ -110,7 +105,7 @@ @Override public GURL getCurrentGurl() { - if (mGurl == null) { + if (GURL.isEmptyOrInvalid(mGurl)) { assert LibraryLoader.getInstance().isInitialized(); mGurl = new GURL(SearchActivityPreferencesManager.getCurrent().searchEngineUrl); } @@ -130,11 +125,7 @@ @Override public int getPageClassification(boolean isFocusedFromFakebox, boolean isPrefetch) { - if (mIsFromQuickActionSearchWidget) { - return PageClassification.ANDROID_SHORTCUTS_WIDGET_VALUE; - } else { - return PageClassification.ANDROID_SEARCH_WIDGET_VALUE; - } + return mPageClassification; } @Override @@ -152,7 +143,11 @@ return 0; } - void setIsFromQuickActionSearchWidget(boolean isFromQuickActionsWidget) { - mIsFromQuickActionSearchWidget = isFromQuickActionsWidget; + void setPageClassification(int pageClassification) { + mPageClassification = pageClassification; + } + + void setCurrentUrl(GURL url) { + mGurl = url; } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninBridge.java index 96fe8cc..749a8803 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninBridge.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninBridge.java
@@ -11,6 +11,7 @@ import org.jni_zero.CalledByNative; import org.chromium.base.ThreadUtils; +import org.chromium.chrome.R; import org.chromium.chrome.browser.device_lock.DeviceLockActivityLauncherImpl; import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.signin.services.IdentityServicesProvider; @@ -140,12 +141,17 @@ // bottom sheet. return; } + AccountPickerBottomSheetStrings strings = + new AccountPickerBottomSheetStrings( + R.string.signin_account_picker_dialog_title, + R.string.signin_account_picker_bottom_sheet_subtitle, + R.string.signin_account_picker_dismiss_button); factory.create( windowAndroid, bottomSheetController, new WebSigninAccountPickerDelegate(tab, new WebSigninBridge.Factory(), continueUrl), - new AccountPickerBottomSheetStrings() {}, + strings, DeviceLockActivityLauncherImpl.get(), AccountPickerLaunchMode.DEFAULT); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/site_settings/ChromeSiteSettingsDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/site_settings/ChromeSiteSettingsDelegate.java index 0f68819..6d625e3 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/site_settings/ChromeSiteSettingsDelegate.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/site_settings/ChromeSiteSettingsDelegate.java
@@ -22,6 +22,7 @@ import org.chromium.chrome.browser.LaunchIntentDispatcher; import org.chromium.chrome.browser.browserservices.intents.BrowserServicesIntentDataProvider.CustomTabsUiType; import org.chromium.chrome.browser.browserservices.permissiondelegation.InstalledWebappPermissionManager; +import org.chromium.chrome.browser.browsing_data.BrowsingDataBridge; import org.chromium.chrome.browser.customtabs.CustomTabIntentDataProvider; import org.chromium.chrome.browser.feedback.HelpAndFeedbackLauncherImpl; import org.chromium.chrome.browser.flags.ChromeFeatureList; @@ -41,6 +42,7 @@ import org.chromium.chrome.browser.webapps.WebappRegistry; import org.chromium.components.browser_ui.settings.ManagedPreferenceDelegate; import org.chromium.components.browser_ui.settings.SettingsLauncher; +import org.chromium.components.browser_ui.site_settings.BrowsingDataInfo; import org.chromium.components.browser_ui.site_settings.SiteSettingsCategory; import org.chromium.components.browser_ui.site_settings.SiteSettingsDelegate; import org.chromium.components.content_settings.ContentSettingsType; @@ -55,6 +57,7 @@ import org.chromium.content_public.common.ContentSwitches; import org.chromium.url.GURL; +import java.util.Map; import java.util.Set; /** A SiteSettingsDelegate instance that contains Chrome-specific Site Settings logic. */ @@ -340,4 +343,10 @@ ChromeFeatureList.TRACKING_PROTECTION_SETTINGS_PAGE_ROLLBACK_NOTICE) && TrackingProtectionBridge.isOffboarded(); } + + @Override + public void fetchBrowsingDataInfo( + Callback<Map<org.chromium.url.Origin, BrowsingDataInfo>> callback) { + BrowsingDataBridge.getForProfile(mProfile).fetchBrowsingDataInfo(callback); + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabBrowserControlsConstraintsHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabBrowserControlsConstraintsHelper.java index 4ad9005..c731efaf 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabBrowserControlsConstraintsHelper.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabBrowserControlsConstraintsHelper.java
@@ -193,6 +193,11 @@ && current == BrowserControlsState.HIDDEN)) { return; } + + if (current == BrowserControlsState.SHOWN || constraints == BrowserControlsState.SHOWN) { + mTab.willShowBrowserControls(); + } + if (mNativeTabBrowserControlsConstraintsHelper == 0) { mNativeTabBrowserControlsConstraintsHelper = TabBrowserControlsConstraintsHelperJni.get()
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabImpl.java index 379249a3..66daaf1f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabImpl.java
@@ -2082,6 +2082,18 @@ mLaunchType = launchType; } + /** + * Forces a resize of the web contents view to accommodate for browser controls immediately. + * + * <p>This is used to force the resize to happen at the same time as the controls are requested + * to show (potentially animate) so that web content can be adapted to the controls sooner. + */ + public void willShowBrowserControls() { + for (TabObserver observer : mObservers) { + observer.onWillShowBrowserControls(this); + } + } + @NativeMethods @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE) public interface Natives {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java index 24b213c8..7fec84c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java
@@ -805,16 +805,18 @@ mIncognitoStateProvider.isIncognitoSelected())); } else { OverrideUrlLoadingDelegate overrideUrlLoadingDelegate = - (url, transition, inputStart, postDataType, postData, incognito) -> { + (omniboxParams, isIncognito) -> { LoadUrlParams params = new LoadUrlParams( - url, transition | PageTransition.FROM_ADDRESS_BAR); - params.setInputStartTimestamp(inputStart); + omniboxParams.url, + omniboxParams.transitionType + | PageTransition.FROM_ADDRESS_BAR); + params.setInputStartTimestamp(omniboxParams.inputStartTimestamp); return ReturnToChromeUtil.handleLoadUrlWithPostDataFromStartSurface( params, - postDataType, - postData, - incognito, + omniboxParams.postDataType, + omniboxParams.postData, + isIncognito, startSurfaceParentTabSupplier.get()); }; ChromePageInfo toolbarPageInfo =
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ui/system/StatusBarColorController.java b/chrome/android/java/src/org/chromium/chrome/browser/ui/system/StatusBarColorController.java index f7870cd..d53d3d8 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ui/system/StatusBarColorController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ui/system/StatusBarColorController.java
@@ -304,6 +304,7 @@ private boolean shouldUpdateStatusBarColorForHomeSurface() { return mIsSurfacePolishEnabled && !mIsIncognito + && mStartSurfaceSupplier != null && mStartSurfaceSupplier.hasValue() && mStartSurfaceSupplier.get().isHomepageShown(); }
diff --git a/chrome/browser/webapps/android/java/src/org/chromium/chrome/browser/webapps/PwaRestorePromoUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/PwaRestorePromoUtils.java similarity index 94% rename from chrome/browser/webapps/android/java/src/org/chromium/chrome/browser/webapps/PwaRestorePromoUtils.java rename to chrome/android/java/src/org/chromium/chrome/browser/webapps/PwaRestorePromoUtils.java index c762a03..9678e5ae5 100644 --- a/chrome/browser/webapps/android/java/src/org/chromium/chrome/browser/webapps/PwaRestorePromoUtils.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/PwaRestorePromoUtils.java
@@ -11,7 +11,6 @@ import org.jni_zero.CalledByNative; import org.jni_zero.JNINamespace; -import org.jni_zero.NativeMethods; import org.chromium.base.Log; import org.chromium.base.shared_preferences.SharedPreferencesManager; @@ -139,7 +138,7 @@ private static void launchPromo( Profile profile, WindowAndroid windowAndroid, int arrowResourceId) { - PwaRestorePromoUtilsJni.get().fetchRestorableApps(profile, windowAndroid, arrowResourceId); + WebApkSyncService.fetchRestorableApps(profile, windowAndroid, arrowResourceId); // Flow continues in onRestorableAppsAvailable. } @@ -147,7 +146,6 @@ private static void onRestorableAppsAvailable( boolean success, @NonNull String[][] appList, - @NonNull int[] lastUsedInDays, WindowAndroid windowAndroid, int arrowResourceId) { BottomSheetController controller = BottomSheetControllerProvider.from(windowAndroid); @@ -157,7 +155,7 @@ Activity activity = windowAndroid.getActivity().get(); PwaRestoreBottomSheetCoordinator pwaRestoreBottomSheetCoordinator = new PwaRestoreBottomSheetCoordinator( - appList, lastUsedInDays, activity, controller, arrowResourceId); + appList, activity, controller, arrowResourceId); if (pwaRestoreBottomSheetCoordinator == null || !pwaRestoreBottomSheetCoordinator.show()) { success = false; @@ -173,10 +171,5 @@ ChromePreferenceKeys.PWA_RESTORE_PROMO_STAGE, DisplayStage.ERROR_LAUNCHING_PROMO); } - } - - @NativeMethods - interface Natives { - void fetchRestorableApps(Profile profile, WindowAndroid windowAndroid, int arrowResourceId); - } + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkSyncService.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkSyncService.java index 70c73ee..4797b39 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkSyncService.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkSyncService.java
@@ -12,8 +12,10 @@ import org.chromium.chrome.browser.browserservices.intents.BrowserServicesIntentDataProvider; import org.chromium.chrome.browser.browserservices.intents.WebappIcon; import org.chromium.chrome.browser.browserservices.intents.WebappInfo; +import org.chromium.chrome.browser.profiles.Profile; import org.chromium.components.sync.protocol.WebApkIconInfo; import org.chromium.components.sync.protocol.WebApkSpecifics; +import org.chromium.ui.base.WindowAndroid; /** Static class to update WebAPK data to sync. */ @JNINamespace("webapk") @@ -101,6 +103,11 @@ return timeInMills * 1000 + UNIX_OFFSET_MICROS; } + public static void fetchRestorableApps( + Profile profile, WindowAndroid windowAndroid, int arrowResourceId) { + WebApkSyncServiceJni.get().fetchRestorableApps(profile, windowAndroid, arrowResourceId); + } + @NativeMethods interface Natives { void onWebApkUsed(byte[] webApkSpecifics, boolean isInstall); @@ -108,5 +115,7 @@ void onWebApkUninstalled(String manifestId); void removeOldWebAPKsFromSync(long currentTimeMsSinceUnixEpoch); + + void fetchRestorableApps(Profile profile, WindowAndroid windowAndroid, int arrowResourceId); } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/settings/AutofillPaymentMethodsFragmentTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/settings/AutofillPaymentMethodsFragmentTest.java index bb6dd0a..c5a26e3 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/settings/AutofillPaymentMethodsFragmentTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/settings/AutofillPaymentMethodsFragmentTest.java
@@ -236,7 +236,10 @@ @Test @MediumTest @Restriction(DeviceRestriction.RESTRICTION_TYPE_NON_AUTO) - @DisableFeatures({ChromeFeatureList.AUTOFILL_ENABLE_CVC_STORAGE}) + @DisableFeatures({ + ChromeFeatureList.AUTOFILL_ENABLE_CVC_STORAGE, + ChromeFeatureList.AUTOFILL_ENABLE_LOCAL_IBAN + }) public void testTwoCreditCards_displaysTwoServerCards() throws Exception { mAutofillTestHelper.addServerCreditCard(SAMPLE_CARD_VISA); mAutofillTestHelper.addServerCreditCard(SAMPLE_CARD_MASTERCARD); @@ -251,7 +254,10 @@ @Test @MediumTest @Restriction(DeviceRestriction.RESTRICTION_TYPE_AUTO) - @DisableFeatures({ChromeFeatureList.AUTOFILL_ENABLE_CVC_STORAGE}) + @DisableFeatures({ + ChromeFeatureList.AUTOFILL_ENABLE_CVC_STORAGE, + ChromeFeatureList.AUTOFILL_ENABLE_LOCAL_IBAN + }) public void testTwoCreditCards_displaysTwoServerCards_mandatoryReauthNotShownOnAutomotive() throws Exception { mAutofillTestHelper.addServerCreditCard(SAMPLE_CARD_VISA); @@ -267,9 +273,11 @@ @Test @MediumTest @Restriction(DeviceRestriction.RESTRICTION_TYPE_AUTO) + @DisableFeatures(ChromeFeatureList.AUTOFILL_ENABLE_LOCAL_IBAN) @EnableFeatures({ChromeFeatureList.AUTOFILL_ENABLE_CVC_STORAGE}) - public void testTwoCreditCards_displaysTwoServerCards_mandatoryReauthNotShownOnAutomotive_ButCvcStorageEnabled() - throws Exception { + public void + testTwoCreditCards_displaysTwoServerCards_mandatoryReauthNotShownOnAutomotive_ButCvcStorageEnabled() + throws Exception { mAutofillTestHelper.addServerCreditCard(SAMPLE_CARD_VISA); mAutofillTestHelper.addServerCreditCard(SAMPLE_CARD_MASTERCARD); @@ -467,7 +475,10 @@ @Test @MediumTest @Restriction(DeviceRestriction.RESTRICTION_TYPE_NON_AUTO) - @DisableFeatures({ChromeFeatureList.AUTOFILL_ENABLE_CVC_STORAGE}) + @DisableFeatures({ + ChromeFeatureList.AUTOFILL_ENABLE_CVC_STORAGE, + ChromeFeatureList.AUTOFILL_ENABLE_LOCAL_IBAN + }) @EnableFeatures({ChromeFeatureList.AUTOFILL_ENABLE_PAYMENTS_MANDATORY_REAUTH}) public void testMandatoryReauthToggle_displayToggle() throws Exception { // Simulate the pref was enabled previously, to ensure the toggle value is set @@ -500,7 +511,8 @@ @MediumTest @DisableFeatures({ ChromeFeatureList.AUTOFILL_ENABLE_PAYMENTS_MANDATORY_REAUTH, - ChromeFeatureList.AUTOFILL_ENABLE_CVC_STORAGE + ChromeFeatureList.AUTOFILL_ENABLE_CVC_STORAGE, + ChromeFeatureList.AUTOFILL_ENABLE_LOCAL_IBAN }) public void testMandatoryReauthToggle_notShownWhenFeatureDisabled() throws Exception { SettingsActivity activity = mSettingsActivityTestRule.startSettingsActivity(); @@ -934,7 +946,10 @@ @Test @MediumTest - @DisableFeatures({ChromeFeatureList.AUTOFILL_ENABLE_PAYMENTS_MANDATORY_REAUTH}) + @DisableFeatures({ + ChromeFeatureList.AUTOFILL_ENABLE_PAYMENTS_MANDATORY_REAUTH, + ChromeFeatureList.AUTOFILL_ENABLE_LOCAL_IBAN + }) @EnableFeatures({ChromeFeatureList.AUTOFILL_ENABLE_CVC_STORAGE}) public void testSaveCvcToggle_shown() throws Exception { // Initial state, Save Cvc pref is enabled previously. @@ -959,7 +974,8 @@ @MediumTest @DisableFeatures({ ChromeFeatureList.AUTOFILL_ENABLE_CVC_STORAGE, - ChromeFeatureList.AUTOFILL_ENABLE_PAYMENTS_MANDATORY_REAUTH + ChromeFeatureList.AUTOFILL_ENABLE_PAYMENTS_MANDATORY_REAUTH, + ChromeFeatureList.AUTOFILL_ENABLE_LOCAL_IBAN }) public void testSaveCvcToggle_notShownWhenFeatureDisabled() throws Exception { SettingsActivity activity = mSettingsActivityTestRule.startSettingsActivity(); @@ -1097,6 +1113,84 @@ verify(mNativeMock).deleteSavedCvcs(NATIVE_AUTOFILL_PAYMENTS_METHODS_DELEGATE); } + @Test + @MediumTest + @DisableFeatures({ + ChromeFeatureList.AUTOFILL_ENABLE_CVC_STORAGE, + ChromeFeatureList.AUTOFILL_ENABLE_PAYMENTS_MANDATORY_REAUTH, + }) + @EnableFeatures({ChromeFeatureList.AUTOFILL_ENABLE_LOCAL_IBAN}) + @Policies.Add({@Policies.Item(key = "AutofillCreditCardEnabled", string = "true")}) + public void testAddIbanButton_shownWhenAutofillEnabled() throws Exception { + SettingsActivity activity = mSettingsActivityTestRule.startSettingsActivity(); + + // Verify that the preference on the initial screen map is only Save and Fill toggle + + // Add Card button + Add IBAN button + Payment Apps. + Assert.assertEquals(4, getPreferenceScreen(activity).getPreferenceCount()); + Assert.assertNotNull( + getPreferenceScreen(activity) + .findPreference(AutofillPaymentMethodsFragment.PREF_ADD_IBAN)); + } + + @Test + @MediumTest + @DisableFeatures({ChromeFeatureList.AUTOFILL_ENABLE_LOCAL_IBAN}) + @Policies.Add({@Policies.Item(key = "AutofillCreditCardEnabled", string = "true")}) + public void testAddIbanButton_notShownWhenAutofillEnabledButFeatureDisabled() throws Exception { + SettingsActivity activity = mSettingsActivityTestRule.startSettingsActivity(); + + Assert.assertNull( + getPreferenceScreen(activity) + .findPreference(AutofillPaymentMethodsFragment.PREF_ADD_IBAN)); + } + + @Test + @MediumTest + @EnableFeatures({ChromeFeatureList.AUTOFILL_ENABLE_LOCAL_IBAN}) + @Policies.Add({@Policies.Item(key = "AutofillCreditCardEnabled", string = "false")}) + public void testAddIbanButton_notShownWhenAutofillDisabled() throws Exception { + SettingsActivity activity = mSettingsActivityTestRule.startSettingsActivity(); + + Assert.assertNull( + getPreferenceScreen(activity) + .findPreference(AutofillPaymentMethodsFragment.PREF_ADD_IBAN)); + } + + @Test + @MediumTest + @EnableFeatures({ChromeFeatureList.AUTOFILL_ENABLE_LOCAL_IBAN}) + public void testAddIbanButtonClicked_opensLocalIbanEditor() throws Exception { + SettingsActivity activity = mSettingsActivityTestRule.startSettingsActivity(); + + Preference addIbanPreference = + getPreferenceScreen(activity) + .findPreference(AutofillPaymentMethodsFragment.PREF_ADD_IBAN); + + // Simulate click on the Add Iban button. + TestThreadUtils.runOnUiThreadBlocking(addIbanPreference::performClick); + rule.waitForFragmentToBeShown(); + + // Verify that the local IBAN editor was opened. + Assert.assertTrue(rule.getLastestShownFragment() instanceof AutofillLocalIbanEditor); + } + + @Test + @MediumTest + @EnableFeatures({ + ChromeFeatureList.AUTOFILL_ENABLE_CVC_STORAGE, + ChromeFeatureList.AUTOFILL_ENABLE_PAYMENTS_MANDATORY_REAUTH, + ChromeFeatureList.AUTOFILL_ENABLE_LOCAL_IBAN + }) + public void testAllToggles_mandatoryReauthEnabled_cvcStorageEnabled_localIbanEnabled() + throws Exception { + SettingsActivity activity = mSettingsActivityTestRule.startSettingsActivity(); + + // Verify that the preference on the initial screen map is only Save and Fill toggle + + // Mandatory Reauth toggle + CVC storage toggle + Add Card button + Add IBAN button + + // Payment Apps. + Assert.assertEquals(6, getPreferenceScreen(activity).getPreferenceCount()); + } + private void setUpBiometricAuthenticationResult(boolean success) { // We have to manually invoke the passed-in callback. doAnswer(
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/settings/AutofillTestRule.java b/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/settings/AutofillTestRule.java index e7c53f00..f045ac5 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/settings/AutofillTestRule.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/settings/AutofillTestRule.java
@@ -42,6 +42,7 @@ mFragmentShown = new CallbackHelper(); AutofillProfilesFragment.setObserverForTest(AutofillTestRule.this); AutofillLocalCardEditor.setObserverForTest(AutofillTestRule.this); + AutofillLocalIbanEditor.setObserverForTest(AutofillTestRule.this); } protected void setTextInEditorAndWait(final String[] values) throws TimeoutException {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/page_info/PageInfoViewDarkModeTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/page_info/PageInfoViewDarkModeTest.java index cca374f..cb5fdd6 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/page_info/PageInfoViewDarkModeTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/page_info/PageInfoViewDarkModeTest.java
@@ -89,7 +89,10 @@ null) .show(tab, ChromePageInfoHighlight.noHighlight()); }); - onViewWaiting(allOf(withId(R.id.page_info_url_wrapper), isDisplayed())); + onViewWaiting( + allOf(withId(R.id.page_info_url_wrapper), isDisplayed()), + true // Put Focus on dialog to fix flakiness in api 29+ with espresso 3.2. + ); } private View getPageInfoView() {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SigninAndHistoryOptInIntegrationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SigninAndHistoryOptInIntegrationTest.java index 749ac363c..e9c7196 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SigninAndHistoryOptInIntegrationTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SigninAndHistoryOptInIntegrationTest.java
@@ -284,46 +284,28 @@ @Test @MediumTest - public void testWithExistingAccount_refuseSignIn_noHistoryOptIn() { - mSigninTestRule.addAccountAndWaitForSeeding(SigninTestRule.TEST_ACCOUNT_EMAIL); - launchActivity( - NoAccountSigninMode.BOTTOM_SHEET, - WithAccountSigninMode.DEFAULT_ACCOUNT_BOTTOM_SHEET, - HistoryOptInMode.REQUIRED); - - // Verify that the collapsed sign-in bottom-sheet is shown, and skip sign-in. - onView( - allOf( - withId(R.id.account_picker_dismiss_button), - withParent(withId(R.id.account_picker_state_collapsed)), - isCompletelyDisplayed())) - .perform(click()); - - verifySigninCancelled(); - } - - @Test - @MediumTest @DisableFeatures(ChromeFeatureList.REPLACE_SYNC_PROMOS_WITH_SIGN_IN_PROMOS) @EnableFeatures(SyncFeatureMap.ENABLE_BOOKMARK_FOLDERS_FOR_ACCOUNT_STORAGE) - public void testWithExistingAccount_refuseSignin_fromBookmarks() { + public void testWithExistingAccount_dismissCollapsedBottomSheet_backPress_fromBookmarks() { // The new sign-in flow contains behaviors specific to the bookmark access point (enabling // bookmark & reading list sync after successful sign-in) therefore the access point is // overridden here to ensure correct dismissal behavior in this case. mSigninAccessPoint = SigninAccessPoint.BOOKMARK_MANAGER; mSigninTestRule.addAccountAndWaitForSeeding(SigninTestRule.TEST_ACCOUNT_EMAIL); + mBlankActivityTestRule.launchActivity(null); launchActivity( NoAccountSigninMode.BOTTOM_SHEET, WithAccountSigninMode.DEFAULT_ACCOUNT_BOTTOM_SHEET, HistoryOptInMode.REQUIRED); - - // Verify that the collapsed sign-in bottom-sheet is shown, and refuse sign-in. + // Verify that the default account bottom sheet is shown. onView( allOf( - withId(R.id.account_picker_dismiss_button), - withParent(withId(R.id.account_picker_state_collapsed)), - isCompletelyDisplayed())) - .perform(click()); + withText(SigninTestRule.TEST_ACCOUNT_EMAIL), + isDescendantOfA(withId(R.id.account_picker_state_collapsed)))) + .check(matches(isDisplayed())); + + // Press on the back button. + Espresso.pressBack(); verifySigninCancelled(); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/site_settings/ChromeSiteSettingsDelegateTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/site_settings/ChromeSiteSettingsDelegateTest.java index 35b8a12..2658e4a 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/site_settings/ChromeSiteSettingsDelegateTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/site_settings/ChromeSiteSettingsDelegateTest.java
@@ -6,10 +6,14 @@ import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.assertEquals; + import android.graphics.drawable.Drawable; +import androidx.test.core.app.ApplicationProvider; import androidx.test.filters.SmallTest; +import org.junit.Before; import org.junit.ClassRule; import org.junit.Rule; import org.junit.Test; @@ -22,13 +26,19 @@ import org.chromium.base.test.util.CommandLineFlags; import org.chromium.chrome.browser.flags.ChromeSwitches; import org.chromium.chrome.browser.profiles.ProfileManager; +import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.chrome.test.ChromeTabbedActivityTestRule; import org.chromium.chrome.test.batch.BlankCTATabInitialStateRule; +import org.chromium.components.browser_ui.site_settings.BrowsingDataInfo; +import org.chromium.content_public.browser.test.util.JavaScriptUtils; import org.chromium.content_public.browser.test.util.TestThreadUtils; import org.chromium.content_public.common.ContentSwitches; +import org.chromium.net.test.EmbeddedTestServer; import org.chromium.url.GURL; +import org.chromium.url.Origin; +import java.util.Map; import java.util.concurrent.TimeoutException; /** Tests for Chrome's SiteSettingsDelegate implementation. */ @@ -50,6 +60,15 @@ ChromeSiteSettingsDelegate mSiteSettingsDelegate; + private EmbeddedTestServer mTestServer; + + @Before + public void setUp() throws Exception { + mTestServer = + EmbeddedTestServer.createAndStartServer( + ApplicationProvider.getApplicationContext()); + } + // Tests that a fallback favicon is generated when a real one isn't found locally. // This is a regression test for crbug.com/1077716. @Test @@ -84,4 +103,47 @@ assertThat(favicon.getIntrinsicWidth()).isGreaterThan(0); assertThat(favicon.getIntrinsicHeight()).isGreaterThan(0); } + + // Tests that fetchBrowsingDataInfo returns the correct sample test data in the hashmap. + @Test + @SmallTest + public void testFetchBrowsingDataInfoCookie() throws TimeoutException { + + String url = + mTestServer.getURLWithHostName( + "browsing-data.com", "/content/test/data/browsing_data/site_data.html"); + Tab tab = sActivityTestRule.loadUrlInNewTab(url, /* incognito= */ false); + + JavaScriptUtils.executeJavaScriptAndWaitForResult(tab.getWebContents(), "setCookie()"); + + CallbackHelper helper = new CallbackHelper(); + TestThreadUtils.runOnUiThreadBlocking( + () -> { + mSiteSettingsDelegate = + new ChromeSiteSettingsDelegate( + sActivityTestRule.getActivity(), + ProfileManager.getLastUsedRegularProfile()); + + // Run browsing data fetcher is required to run on UI thread. + mSiteSettingsDelegate.fetchBrowsingDataInfo( + result -> { + assertEquals(1, result.size()); + + // Ensure that the entry matches the set cookie. + var origin = Origin.create(new GURL("http://browsing-data.com")); + var entry = + (Map.Entry<Origin, BrowsingDataInfo>) + result.entrySet().iterator().next(); + assertEquals(origin, entry.getKey()); + + var info = entry.getValue(); + assertEquals(origin, info.getOrigin()); + assertEquals(1, info.getCookieCount()); + assertEquals(0, info.getStorageSize()); + + helper.notifyCalled(); + }); + }); + helper.waitForFirst(); + } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/PwaRestoreBottomSheetIntegrationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/PwaRestoreBottomSheetIntegrationTest.java index adbed0e..4505d2be 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/PwaRestoreBottomSheetIntegrationTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/PwaRestoreBottomSheetIntegrationTest.java
@@ -201,33 +201,6 @@ @Test @SmallTest @Feature({"PwaRestore"}) - public void testOlderAppsShowSeparately() { - // This test is about ensuring that when an app was last used more than - // 30 days ago (40 specified below), it shows up in a separate ("older") - // list. - Assert.assertTrue( - setTestAppsForRestoring( - new String[][] { - {"https://example.com/app1/", "App 1"}, - {"https://example.com/app2/", "App 2"}, - {"https://example.com/app3/", "App 3"} - }, - // Days since the apps were last used (respectively). - new int[] {1, 2, 40})); - - // Ensure the promo dialog shows. - setAppsAvailableAndPromoStage(true, DisplayStage.SHOW_PROMO); - - mActivityTestRule.startMainActivityFromLauncher(); - assertDialogShown(true); - onView(withId(R.id.review_button)).perform(click()); - - onView(withText("Older")).check(matches(isDisplayed())); - } - - @Test - @SmallTest - @Feature({"PwaRestore"}) public void testNoOlderAppsShown() { // This test is about ensuring that when all apps are recent, we don't // show the separate ("Older") app list.
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/compositor/CompositorViewHolderUnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/compositor/CompositorViewHolderUnitTest.java index a0e680c..410440f 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/compositor/CompositorViewHolderUnitTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/compositor/CompositorViewHolderUnitTest.java
@@ -8,6 +8,7 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; @@ -301,6 +302,121 @@ } @Test + @EnableFeatures(ChromeFeatureList.BROWSER_CONTROLS_EARLY_RESIZE) + public void testResizeViewOnWillShowControls() { + final int topHeight = 100; + final int topMinHeight = 0; + + TabModelSelectorTabObserver tabControlsObserver = + mBrowserControlsManager.getTabControlsObserverForTesting(); + + mBrowserControlsManager.setTopControlsHeight(topHeight, topMinHeight); + + // Send initial offsets. + tabControlsObserver.onBrowserControlsOffsetChanged( + mTab, + /* topControlsOffsetY= */ -topHeight, + /* bottomControlsOffsetY= */ 0, + /* contentOffsetY= */ 0, + /* topControlsMinHeightOffsetY= */ 0, + /* bottomControlsMinHeightOffsetY= */ 0); + // Initially, the controls should be hidden. + assertTrue( + "Browser controls aren't fully hidden.", + BrowserControlsUtils.areBrowserControlsOffScreen(mBrowserControlsManager)); + + // Simulate the browser issuing a "show browser controls" signal to the renderer. + mCompositorViewHolder.onWillShowBrowserControls(); + + // This should cause the controls to start resizing the view. + verify(mCompositorView).onControlsResizeViewChanged(any(), eq(true)); + reset(mCompositorView); + + // Simulating a show-animation partially updating the controls, this shouldn't cause another + // resize. + tabControlsObserver.onBrowserControlsOffsetChanged( + mTab, + /* topControlsOffsetY= */ -topHeight / 2, + /* bottomControlsOffsetY= */ 0, + /* contentOffsetY= */ topHeight / 2, + /* topControlsMinHeightOffsetY= */ 0, + /* bottomControlsMinHeightOffsetY= */ 0); + verify(mCompositorView, never()).onControlsResizeViewChanged(any(), anyBoolean()); + reset(mCompositorView); + + // The controls finished animating in. Since they already resized the view, this should also + // be a no-op. + tabControlsObserver.onBrowserControlsOffsetChanged( + mTab, + /* topControlsOffsetY= */ 0, + /* bottomControlsOffsetY= */ 0, + /* contentOffsetY= */ topHeight, + /* topControlsMinHeightOffsetY= */ 0, + /* bottomControlsMinHeightOffsetY= */ 0); + + verify(mCompositorView, never()).onControlsResizeViewChanged(any(), anyBoolean()); + reset(mCompositorView); + + // The controls going back to hidden should resize the view as usual. + tabControlsObserver.onBrowserControlsOffsetChanged( + mTab, + /* topControlsOffsetY= */ -topHeight, + /* bottomControlsOffsetY= */ 0, + /* contentOffsetY= */ 0, + /* topControlsMinHeightOffsetY= */ 0, + /* bottomControlsMinHeightOffsetY= */ 0); + verify(mCompositorView).onControlsResizeViewChanged(any(), eq(false)); + reset(mCompositorView); + } + + // TODO(bokan): Ensure disabling the flag-guard reverts to old behavior. This test can be + // removed with the flag after M125 ships. https://crbug.com/5366846. + @Test + @DisableFeatures(ChromeFeatureList.BROWSER_CONTROLS_EARLY_RESIZE) + public void testResizeViewOnWillShowControlsFlagGuarded() { + final int topHeight = 100; + final int topMinHeight = 0; + + TabModelSelectorTabObserver tabControlsObserver = + mBrowserControlsManager.getTabControlsObserverForTesting(); + + mBrowserControlsManager.setTopControlsHeight(topHeight, topMinHeight); + + // Send initial offsets. + tabControlsObserver.onBrowserControlsOffsetChanged( + mTab, + /* topControlsOffsetY= */ -topHeight, + /* bottomControlsOffsetY= */ 0, + /* contentOffsetY= */ 0, + /* topControlsMinHeightOffsetY= */ 0, + /* bottomControlsMinHeightOffsetY= */ 0); + // Initially, the controls should be hidden. + assertTrue( + "Browser controls aren't fully hidden.", + BrowserControlsUtils.areBrowserControlsOffScreen(mBrowserControlsManager)); + + // Simulate the browser issuing a "show browser controls" signal to the renderer. + mCompositorViewHolder.onWillShowBrowserControls(); + + // This should must not cause the controls to start resizing the view yet. + verify(mCompositorView, never()).onControlsResizeViewChanged(any(), anyBoolean()); + reset(mCompositorView); + + // The controls finished animating in. Since they already resized the view, this should + // cause the resize the occur. + tabControlsObserver.onBrowserControlsOffsetChanged( + mTab, + /* topControlsOffsetY= */ 0, + /* bottomControlsOffsetY= */ 0, + /* contentOffsetY= */ topHeight, + /* topControlsMinHeightOffsetY= */ 0, + /* bottomControlsMinHeightOffsetY= */ 0); + + verify(mCompositorView).onControlsResizeViewChanged(any(), eq(true)); + reset(mCompositorView); + } + + @Test @EnableFeatures({ ChromeFeatureList.FULLSCREEN_INSETS_API_MIGRATION, ChromeFeatureList.FULLSCREEN_INSETS_API_MIGRATION_ON_AUTOMOTIVE
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/searchwidget/SearchActivityUnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/searchwidget/SearchActivityUnitTest.java index 9bb2e47..9d2be7e 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/searchwidget/SearchActivityUnitTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/searchwidget/SearchActivityUnitTest.java
@@ -4,6 +4,7 @@ package org.chromium.chrome.browser.searchwidget; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.mockito.ArgumentMatchers.any; @@ -21,6 +22,7 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; @@ -35,8 +37,11 @@ import org.chromium.base.test.BaseRobolectricTestRunner; import org.chromium.chrome.R; import org.chromium.chrome.browser.firstrun.FirstRunStatus; +import org.chromium.chrome.browser.omnibox.suggestions.OmniboxLoadUrlParams; import org.chromium.chrome.browser.signin.services.IdentityServicesProvider; import org.chromium.chrome.browser.ui.searchactivityutils.SearchActivityClient.IntentOrigin; +import org.chromium.components.metrics.OmniboxEventProtos.OmniboxEventProto.PageClassification; +import org.chromium.ui.base.PageTransition; import org.chromium.url.GURL; @RunWith(BaseRobolectricTestRunner.class) @@ -44,12 +49,17 @@ manifest = Config.NONE, shadows = {SearchActivityUnitTest.ShadowSearchActivityUtils.class}) public class SearchActivityUnitTest { + private static final OmniboxLoadUrlParams LOAD_URL_PARAMS_SIMPLE = + new OmniboxLoadUrlParams.Builder("https://abc.xyz", PageTransition.TYPED).build(); + // SearchActivityUtils call intercepting mock. private interface TestSearchActivityUtils { @IntentOrigin int getIntentOrigin(Intent intent); - void resolveOmniboxRequestForResult(Activity activity, GURL url); + void resolveOmniboxRequestForResult(Activity activity, OmniboxLoadUrlParams params); + + GURL getIntentUrl(Intent intent); } // Shadow forwarding static calls to TestSearchActivityUtils. @@ -63,8 +73,14 @@ } @Implementation - public static void resolveOmniboxRequestForResult(Activity activity, GURL url) { - sMockUtils.resolveOmniboxRequestForResult(activity, url); + public static GURL getIntentUrl(Intent intent) { + return sMockUtils.getIntentUrl(intent); + } + + @Implementation + public static void resolveOmniboxRequestForResult( + Activity activity, OmniboxLoadUrlParams params) { + sMockUtils.resolveOmniboxRequestForResult(activity, params); } } @@ -99,9 +115,12 @@ doReturn(IntentOrigin.CUSTOM_TAB).when(mUtils).getIntentOrigin(any()); mActivity.handleNewIntent(new Intent()); - mActivity.loadUrl("https://abc.xyz", 0, null, null); - verify(mUtils) - .resolveOmniboxRequestForResult(eq(mActivity), eq(new GURL("https://abc.xyz"))); + mActivity.loadUrl(LOAD_URL_PARAMS_SIMPLE, false); + ArgumentCaptor<OmniboxLoadUrlParams> captor = + ArgumentCaptor.forClass(OmniboxLoadUrlParams.class); + verify(mUtils).resolveOmniboxRequestForResult(eq(mActivity), captor.capture()); + + assertEquals("https://abc.xyz", captor.getValue().url); assertNull(mShadowActivity.getNextStartedActivity()); } @@ -110,7 +129,7 @@ doReturn(IntentOrigin.QUICK_ACTION_SEARCH_WIDGET).when(mUtils).getIntentOrigin(any()); mActivity.handleNewIntent(new Intent()); - mActivity.loadUrl("https://abc.xyz", 0, null, null); + mActivity.loadUrl(LOAD_URL_PARAMS_SIMPLE, false); verify(mUtils, never()).resolveOmniboxRequestForResult(any(), any()); assertNotNull(mShadowActivity.getNextStartedActivity()); } @@ -121,7 +140,7 @@ mActivity.setActivityUsableForTesting(false); mActivity.handleNewIntent(new Intent()); - mActivity.loadUrl("https://abc.xyz", 0, null, null); + mActivity.loadUrl(LOAD_URL_PARAMS_SIMPLE, false); verify(mUtils, never()).resolveOmniboxRequestForResult(any(), any()); assertNull(mShadowActivity.getNextStartedActivity()); } @@ -143,4 +162,51 @@ mActivity.cancelSearch(); verify(mUtils, never()).resolveOmniboxRequestForResult(any(), any()); } + + @Test + public void handleNewIntent_forSearchWidget() { + doReturn(IntentOrigin.SEARCH_WIDGET).when(mUtils).getIntentOrigin(any()); + mActivity.handleNewIntent(new Intent()); + + var data = mActivity.getSearchBoxDataProvider(); + assertEquals( + PageClassification.ANDROID_SEARCH_WIDGET_VALUE, + data.getPageClassification(true, true)); + assertEquals( + PageClassification.ANDROID_SEARCH_WIDGET_VALUE, + data.getPageClassification(true, false)); + } + + @Test + public void handleNewIntent_forQuickActionSearchWidget() { + doReturn(IntentOrigin.QUICK_ACTION_SEARCH_WIDGET).when(mUtils).getIntentOrigin(any()); + mActivity.handleNewIntent(new Intent()); + + var data = mActivity.getSearchBoxDataProvider(); + assertEquals( + PageClassification.ANDROID_SHORTCUTS_WIDGET_VALUE, + data.getPageClassification(true, true)); + assertEquals( + PageClassification.ANDROID_SHORTCUTS_WIDGET_VALUE, + data.getPageClassification(true, false)); + } + + @Test + public void handleNewIntent_forCustomTab() { + doReturn(IntentOrigin.CUSTOM_TAB).when(mUtils).getIntentOrigin(any()); + mActivity.handleNewIntent(new Intent()); + + var data = mActivity.getSearchBoxDataProvider(); + assertEquals(PageClassification.OTHER_VALUE, data.getPageClassification(true, true)); + assertEquals(PageClassification.OTHER_VALUE, data.getPageClassification(true, false)); + } + + @Test + public void handleNewIntent_passIntentUrlToLocationBarData() { + doReturn(new GURL("https://abc.xyz")).when(mUtils).getIntentUrl(any()); + mActivity.handleNewIntent(new Intent()); + + var data = mActivity.getSearchBoxDataProvider(); + assertEquals("https://abc.xyz/", data.getCurrentGurl().getSpec()); + } }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/searchwidget/SearchActivityUtilsUnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/searchwidget/SearchActivityUtilsUnitTest.java index a40aadc..c3322a573 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/searchwidget/SearchActivityUtilsUnitTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/searchwidget/SearchActivityUtilsUnitTest.java
@@ -4,37 +4,100 @@ package org.chromium.chrome.browser.searchwidget; +import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.doReturn; import android.app.Activity; import android.content.ComponentName; +import android.content.Intent; +import android.net.Uri; import android.text.TextUtils; +import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; import org.robolectric.Robolectric; import org.robolectric.Shadows; +import org.robolectric.annotation.Config; +import org.robolectric.annotation.Implementation; +import org.robolectric.annotation.Implements; import org.chromium.base.ContextUtils; import org.chromium.base.IntentUtils; import org.chromium.base.test.BaseRobolectricTestRunner; +import org.chromium.chrome.browser.IntentHandler; +import org.chromium.chrome.browser.omnibox.suggestions.OmniboxLoadUrlParams; import org.chromium.chrome.browser.ui.searchactivityutils.SearchActivityClient; import org.chromium.chrome.browser.ui.searchactivityutils.SearchActivityClient.IntentOrigin; import org.chromium.chrome.browser.ui.searchactivityutils.SearchActivityClient.SearchType; +import org.chromium.components.url_formatter.UrlFormatter; +import org.chromium.ui.base.PageTransition; import org.chromium.url.GURL; @RunWith(BaseRobolectricTestRunner.class) +@Config( + manifest = Config.NONE, + shadows = {SearchActivityUtilsUnitTest.ShadowUrlFormatter.class}) public class SearchActivityUtilsUnitTest { - // Dummy Activity class that guarantees the PackageName is valid for IntentUtils. + // Placeholder Activity class that guarantees the PackageName is valid for IntentUtils. private static class TestActivity extends Activity {} private static final GURL GOOD_URL = new GURL("https://abc.xyz"); private static final GURL EMPTY_URL = GURL.emptyGURL(); + private static final OmniboxLoadUrlParams LOAD_URL_PARAMS_NULL_URL = + new OmniboxLoadUrlParams.Builder(null, PageTransition.TYPED).build(); + private static final OmniboxLoadUrlParams LOAD_URL_PARAMS_INVALID_URL = + new OmniboxLoadUrlParams.Builder("abcde", PageTransition.TYPED).build(); + private static final OmniboxLoadUrlParams.Builder LOAD_URL_PARAMS_BUILDER = + new OmniboxLoadUrlParams.Builder("https://abc.xyz", PageTransition.TYPED); + private static final ComponentName COMPONENT_TRUSTED = + new ComponentName(ContextUtils.getApplicationContext(), SearchActivity.class); + private static final ComponentName COMPONENT_UNTRUSTED = + new ComponentName("com.some.package", "com.some.package.test.Activity"); + private Activity mActivity = Robolectric.buildActivity(TestActivity.class).setup().get(); + // UrlFormatter call intercepting mock. + private interface TestUrlFormatter { + GURL fixupUrl(String uri); + } + + @Implements(UrlFormatter.class) + public static class ShadowUrlFormatter { + static TestUrlFormatter sMockFormatter; + + @Implementation + public static GURL fixupUrl(String uri) { + return sMockFormatter.fixupUrl(uri); + } + } + + public @Rule MockitoRule mockitoRule = MockitoJUnit.rule(); + private @Mock TestUrlFormatter mFormatter; + + @Before + public void setUp() { + ShadowUrlFormatter.sMockFormatter = mFormatter; + + doAnswer( + i -> { + return new GURL(i.getArgument(0)); + }) + .when(mFormatter) + .fixupUrl(any()); + } + @Test public void createIntent_forTextSearch() { @IntentOrigin @@ -201,7 +264,7 @@ } @Test - public void getIntentOrigin_forOmniboxRequestForResult() { + public void getIntentOrigin_trustedIntent() { SearchActivityUtils.requestOmniboxForResult(mActivity, EMPTY_URL); var intent = Shadows.shadowOf(mActivity).getNextStartedActivityForResult().intent; @@ -218,7 +281,7 @@ } @Test - public void getIntentSearchType_forCustomTab() { + public void getIntentSearchType_trustedIntent() { SearchActivityUtils.requestOmniboxForResult(mActivity, EMPTY_URL); var intent = Shadows.shadowOf(mActivity).getNextStartedActivityForResult().intent; @@ -233,19 +296,66 @@ } @Test + public void getIntentSearchType_untrustedIntent() { + SearchActivityUtils.requestOmniboxForResult(mActivity, EMPTY_URL); + + var intent = Shadows.shadowOf(mActivity).getNextStartedActivityForResult().intent; + intent.removeExtra(IntentUtils.TRUSTED_APPLICATION_CODE_EXTRA); + assertEquals(SearchType.TEXT, SearchActivityUtils.getIntentSearchType(intent)); + } + + @Test + public void getIntentUrl_forNullUrl() { + SearchActivityUtils.requestOmniboxForResult(mActivity, null); + var intent = Shadows.shadowOf(mActivity).getNextStartedActivityForResult().intent; + assertNull(SearchActivityUtils.getIntentUrl(intent)); + // Remove trust + intent.removeExtra(IntentUtils.TRUSTED_APPLICATION_CODE_EXTRA); + assertNull(SearchActivityUtils.getIntentUrl(intent)); + } + + @Test + public void getIntentUrl_forEmptyUrl() { + SearchActivityUtils.requestOmniboxForResult(mActivity, GURL.emptyGURL()); + var intent = Shadows.shadowOf(mActivity).getNextStartedActivityForResult().intent; + assertNull(SearchActivityUtils.getIntentUrl(intent)); + // Remove trust + intent.removeExtra(IntentUtils.TRUSTED_APPLICATION_CODE_EXTRA); + assertNull(SearchActivityUtils.getIntentUrl(intent)); + } + + @Test + public void getIntentUrl_forInvalidUrl() { + SearchActivityUtils.requestOmniboxForResult(mActivity, new GURL("abcd")); + var intent = Shadows.shadowOf(mActivity).getNextStartedActivityForResult().intent; + assertNull(SearchActivityUtils.getIntentUrl(intent)); + // Remove trust + intent.removeExtra(IntentUtils.TRUSTED_APPLICATION_CODE_EXTRA); + assertNull(SearchActivityUtils.getIntentUrl(intent)); + } + + @Test + public void getIntentUrl_forValidUrl() { + SearchActivityUtils.requestOmniboxForResult(mActivity, new GURL("https://abc.xyz")); + var intent = Shadows.shadowOf(mActivity).getNextStartedActivityForResult().intent; + assertEquals("https://abc.xyz/", SearchActivityUtils.getIntentUrl(intent).getSpec()); + // Remove trust + intent.removeExtra(IntentUtils.TRUSTED_APPLICATION_CODE_EXTRA); + assertNull(SearchActivityUtils.getIntentUrl(intent)); + } + + @Test public void resolveOmniboxRequestForResult_successfulResolutionForValidGURL() { // Simulate environment where we received an intent from self. var activity = Shadows.shadowOf(mActivity); activity.setCallingActivity( new ComponentName(ContextUtils.getApplicationContext(), TestActivity.class)); - SearchActivityUtils.resolveOmniboxRequestForResult(mActivity, GOOD_URL); + var params = LOAD_URL_PARAMS_BUILDER.build(); + SearchActivityUtils.resolveOmniboxRequestForResult(mActivity, params); var intent = Shadows.shadowOf(mActivity).getResultIntent(); - assertTrue(intent.hasExtra(SearchActivityUtils.EXTRA_URL_TO_NAVIGATE)); - assertEquals( - GOOD_URL.getSpec(), - IntentUtils.safeGetStringExtra(intent, SearchActivityUtils.EXTRA_URL_TO_NAVIGATE)); + assertEquals("https://abc.xyz/", intent.getDataString()); assertEquals(Activity.RESULT_OK, Shadows.shadowOf(mActivity).getResultCode()); } @@ -255,14 +365,14 @@ var activity = Shadows.shadowOf(mActivity); activity.setCallingPackage("com.abc.xyz"); - SearchActivityUtils.resolveOmniboxRequestForResult(mActivity, GOOD_URL); + var params = LOAD_URL_PARAMS_BUILDER.build(); + SearchActivityUtils.resolveOmniboxRequestForResult(mActivity, params); var intent = Shadows.shadowOf(mActivity).getResultIntent(); - assertFalse(intent.hasExtra(SearchActivityUtils.EXTRA_URL_TO_NAVIGATE)); - assertFalse(IntentUtils.safeHasExtra(intent, SearchActivityUtils.EXTRA_URL_TO_NAVIGATE)); + assertNull(intent); // Respectfully tell the caller we have nothing else to share. - assertEquals(Activity.RESULT_OK, Shadows.shadowOf(mActivity).getResultCode()); + assertEquals(Activity.RESULT_CANCELED, Shadows.shadowOf(mActivity).getResultCode()); } @Test @@ -272,10 +382,10 @@ SearchActivityUtils.resolveOmniboxRequestForResult(mActivity, null); assertEquals(Activity.RESULT_CANCELED, activity.getResultCode()); - SearchActivityUtils.resolveOmniboxRequestForResult(mActivity, GURL.emptyGURL()); + SearchActivityUtils.resolveOmniboxRequestForResult(mActivity, LOAD_URL_PARAMS_NULL_URL); assertEquals(Activity.RESULT_CANCELED, activity.getResultCode()); - SearchActivityUtils.resolveOmniboxRequestForResult(mActivity, new GURL("a b")); + SearchActivityUtils.resolveOmniboxRequestForResult(mActivity, LOAD_URL_PARAMS_INVALID_URL); assertEquals(Activity.RESULT_CANCELED, activity.getResultCode()); } @@ -284,7 +394,8 @@ var activity = Shadows.shadowOf(mActivity); activity.setCallingActivity( new ComponentName(ContextUtils.getApplicationContext(), TestActivity.class)); - SearchActivityUtils.resolveOmniboxRequestForResult(mActivity, GOOD_URL); + var params = LOAD_URL_PARAMS_BUILDER.build(); + SearchActivityUtils.resolveOmniboxRequestForResult(mActivity, params); var intent = Shadows.shadowOf(mActivity).getResultIntent(); // Our own responses should always be valid. @@ -298,7 +409,8 @@ var activity = Shadows.shadowOf(mActivity); activity.setCallingActivity( new ComponentName(ContextUtils.getApplicationContext(), TestActivity.class)); - SearchActivityUtils.resolveOmniboxRequestForResult(mActivity, GOOD_URL); + var params = LOAD_URL_PARAMS_BUILDER.build(); + SearchActivityUtils.resolveOmniboxRequestForResult(mActivity, params); var intent = Shadows.shadowOf(mActivity).getResultIntent(); assertFalse( @@ -313,7 +425,8 @@ var activity = Shadows.shadowOf(mActivity); activity.setCallingActivity( new ComponentName(ContextUtils.getApplicationContext(), TestActivity.class)); - SearchActivityUtils.resolveOmniboxRequestForResult(mActivity, GOOD_URL); + var params = LOAD_URL_PARAMS_BUILDER.build(); + SearchActivityUtils.resolveOmniboxRequestForResult(mActivity, params); var intent = Shadows.shadowOf(mActivity).getResultIntent(); intent.removeExtra(IntentUtils.TRUSTED_APPLICATION_CODE_EXTRA); @@ -327,10 +440,11 @@ var activity = Shadows.shadowOf(mActivity); activity.setCallingActivity( new ComponentName(ContextUtils.getApplicationContext(), TestActivity.class)); - SearchActivityUtils.resolveOmniboxRequestForResult(mActivity, GOOD_URL); + var params = LOAD_URL_PARAMS_BUILDER.build(); + SearchActivityUtils.resolveOmniboxRequestForResult(mActivity, params); var intent = Shadows.shadowOf(mActivity).getResultIntent(); - intent.removeExtra(SearchActivityUtils.EXTRA_URL_TO_NAVIGATE); + intent.setData(null); assertFalse( SearchActivityUtils.isOmniboxResult( SearchActivityUtils.OMNIBOX_REQUEST_CODE, intent)); @@ -338,16 +452,16 @@ @Test public void getOmniboxResult_successfulResolution() { - // Resolve intent with GOOD_URL. var activity = Shadows.shadowOf(mActivity); activity.setCallingActivity( new ComponentName(ContextUtils.getApplicationContext(), TestActivity.class)); - SearchActivityUtils.resolveOmniboxRequestForResult(mActivity, GOOD_URL); + var params = LOAD_URL_PARAMS_BUILDER.build(); + SearchActivityUtils.resolveOmniboxRequestForResult(mActivity, params); // We should see the same URL on the receiving side. var intent = Shadows.shadowOf(mActivity).getResultIntent(); assertEquals( - GOOD_URL.getSpec(), + "https://abc.xyz/", SearchActivityUtils.getOmniboxResult( SearchActivityUtils.OMNIBOX_REQUEST_CODE, Activity.RESULT_OK, @@ -362,7 +476,8 @@ var activity = Shadows.shadowOf(mActivity); activity.setCallingActivity( new ComponentName(ContextUtils.getApplicationContext(), TestActivity.class)); - SearchActivityUtils.resolveOmniboxRequestForResult(mActivity, GOOD_URL); + var params = LOAD_URL_PARAMS_BUILDER.build(); + SearchActivityUtils.resolveOmniboxRequestForResult(mActivity, params); // We should see no GURL object on the receiving side: this is not our intent. var intent = Shadows.shadowOf(mActivity).getResultIntent(); @@ -378,7 +493,8 @@ var activity = Shadows.shadowOf(mActivity); activity.setCallingActivity( new ComponentName(ContextUtils.getApplicationContext(), TestActivity.class)); - SearchActivityUtils.resolveOmniboxRequestForResult(mActivity, GOOD_URL); + var params = LOAD_URL_PARAMS_BUILDER.build(); + SearchActivityUtils.resolveOmniboxRequestForResult(mActivity, params); // We should see an empty GURL on the receiving side. var intent = Shadows.shadowOf(mActivity).getResultIntent(); @@ -389,4 +505,131 @@ intent) .isEmpty()); } + + @Test + public void createLoadUrlIntent_nullParams() { + assertNull(SearchActivityUtils.createLoadUrlIntent(mActivity, COMPONENT_TRUSTED, null)); + } + + @Test + public void createLoadUrlIntent_nullUrl() { + assertNull( + SearchActivityUtils.createLoadUrlIntent( + mActivity, COMPONENT_TRUSTED, LOAD_URL_PARAMS_NULL_URL)); + } + + @Test + public void createLoadUrlIntent_invalidUrl() { + assertNull( + SearchActivityUtils.createLoadUrlIntent( + mActivity, COMPONENT_TRUSTED, LOAD_URL_PARAMS_INVALID_URL)); + } + + @Test + public void createLoadUrlIntent_invalidFixedUpUrl() { + doReturn(null).when(mFormatter).fixupUrl(any()); + assertNull( + SearchActivityUtils.createLoadUrlIntent( + mActivity, COMPONENT_TRUSTED, LOAD_URL_PARAMS_BUILDER.build())); + } + + @Test + public void createLoadUrlIntent_untrustedRecipient() { + Intent intent = + SearchActivityUtils.createLoadUrlIntent( + mActivity, COMPONENT_UNTRUSTED, LOAD_URL_PARAMS_BUILDER.build()); + assertNull(intent); + } + + @Test + public void createLoadUrlIntent_simpleParams() { + Intent intent = + SearchActivityUtils.createLoadUrlIntent( + mActivity, COMPONENT_TRUSTED, LOAD_URL_PARAMS_BUILDER.build()); + assertNotNull(intent); + + assertEquals(Uri.parse("https://abc.xyz/"), intent.getData()); + assertTrue(intent.getBooleanExtra(SearchActivity.EXTRA_FROM_SEARCH_ACTIVITY, false)); + assertEquals(COMPONENT_TRUSTED.getClassName(), intent.getComponent().getClassName()); + assertNull(intent.getStringExtra(IntentHandler.EXTRA_POST_DATA_TYPE)); + assertNull(intent.getByteArrayExtra(IntentHandler.EXTRA_POST_DATA)); + assertTrue(intent.hasExtra(IntentUtils.TRUSTED_APPLICATION_CODE_EXTRA)); + } + + @Test + public void createLoadUrlIntent_paramsWithNullPostData() { + var params = LOAD_URL_PARAMS_BUILDER.setpostDataAndType(null, "abc").build(); + Intent intent = + SearchActivityUtils.createLoadUrlIntent(mActivity, COMPONENT_TRUSTED, params); + assertNotNull(intent); + + assertEquals(Uri.parse("https://abc.xyz/"), intent.getData()); + assertTrue(intent.getBooleanExtra(SearchActivity.EXTRA_FROM_SEARCH_ACTIVITY, false)); + assertEquals(COMPONENT_TRUSTED.getClassName(), intent.getComponent().getClassName()); + assertNull(intent.getStringExtra(IntentHandler.EXTRA_POST_DATA_TYPE)); + assertNull(intent.getByteArrayExtra(IntentHandler.EXTRA_POST_DATA)); + assertTrue(intent.hasExtra(IntentUtils.TRUSTED_APPLICATION_CODE_EXTRA)); + } + + @Test + public void createLoadUrlIntent_paramsWithEmptyPostData() { + var params = LOAD_URL_PARAMS_BUILDER.setpostDataAndType(new byte[] {}, "abc").build(); + Intent intent = + SearchActivityUtils.createLoadUrlIntent(mActivity, COMPONENT_TRUSTED, params); + assertNotNull(intent); + + assertEquals(Uri.parse("https://abc.xyz/"), intent.getData()); + assertTrue(intent.getBooleanExtra(SearchActivity.EXTRA_FROM_SEARCH_ACTIVITY, false)); + assertEquals(COMPONENT_TRUSTED.getClassName(), intent.getComponent().getClassName()); + assertNull(intent.getStringExtra(IntentHandler.EXTRA_POST_DATA_TYPE)); + assertNull(intent.getByteArrayExtra(IntentHandler.EXTRA_POST_DATA)); + assertTrue(intent.hasExtra(IntentUtils.TRUSTED_APPLICATION_CODE_EXTRA)); + } + + @Test + public void createLoadUrlIntent_paramsWithNullPostDataType() { + var params = LOAD_URL_PARAMS_BUILDER.setpostDataAndType(new byte[] {1, 2, 3}, null).build(); + Intent intent = + SearchActivityUtils.createLoadUrlIntent(mActivity, COMPONENT_TRUSTED, params); + assertNotNull(intent); + + assertEquals(Uri.parse("https://abc.xyz/"), intent.getData()); + assertTrue(intent.getBooleanExtra(SearchActivity.EXTRA_FROM_SEARCH_ACTIVITY, false)); + assertEquals(COMPONENT_TRUSTED.getClassName(), intent.getComponent().getClassName()); + assertNull(intent.getStringExtra(IntentHandler.EXTRA_POST_DATA_TYPE)); + assertNull(intent.getByteArrayExtra(IntentHandler.EXTRA_POST_DATA)); + assertTrue(intent.hasExtra(IntentUtils.TRUSTED_APPLICATION_CODE_EXTRA)); + } + + @Test + public void createLoadUrlIntent_paramsWithEmptyPostDataType() { + var params = LOAD_URL_PARAMS_BUILDER.setpostDataAndType(new byte[] {1, 2, 3}, "").build(); + Intent intent = + SearchActivityUtils.createLoadUrlIntent(mActivity, COMPONENT_TRUSTED, params); + assertNotNull(intent); + + assertEquals(Uri.parse("https://abc.xyz/"), intent.getData()); + assertTrue(intent.getBooleanExtra(SearchActivity.EXTRA_FROM_SEARCH_ACTIVITY, false)); + assertEquals(COMPONENT_TRUSTED.getClassName(), intent.getComponent().getClassName()); + assertNull(intent.getStringExtra(IntentHandler.EXTRA_POST_DATA_TYPE)); + assertNull(intent.getByteArrayExtra(IntentHandler.EXTRA_POST_DATA)); + assertTrue(intent.hasExtra(IntentUtils.TRUSTED_APPLICATION_CODE_EXTRA)); + } + + @Test + public void createLoadUrlIntent_paramsWithValidPostDataType() { + var params = + LOAD_URL_PARAMS_BUILDER.setpostDataAndType(new byte[] {1, 2, 3}, "test").build(); + Intent intent = + SearchActivityUtils.createLoadUrlIntent(mActivity, COMPONENT_TRUSTED, params); + assertNotNull(intent); + + assertEquals(Uri.parse("https://abc.xyz/"), intent.getData()); + assertTrue(intent.getBooleanExtra(SearchActivity.EXTRA_FROM_SEARCH_ACTIVITY, false)); + assertEquals(COMPONENT_TRUSTED.getClassName(), intent.getComponent().getClassName()); + assertEquals("test", intent.getStringExtra(IntentHandler.EXTRA_POST_DATA_TYPE)); + assertArrayEquals( + new byte[] {1, 2, 3}, intent.getByteArrayExtra(IntentHandler.EXTRA_POST_DATA)); + assertTrue(intent.hasExtra(IntentUtils.TRUSTED_APPLICATION_CODE_EXTRA)); + } }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebappRegistryTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebappRegistryTest.java index c6febc4c..a6fe603a 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebappRegistryTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebappRegistryTest.java
@@ -37,9 +37,11 @@ import org.chromium.chrome.browser.browserservices.intents.WebappExtras; import org.chromium.chrome.browser.browserservices.intents.WebappInfo; import org.chromium.chrome.browser.browsing_data.UrlFilters; +import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.webapps.WebappRegistry.GetWebApkSpecificsImplSetWebappInfoForTesting; import org.chromium.chrome.test.util.browser.webapps.WebApkIntentDataProviderBuilder; import org.chromium.components.sync.protocol.WebApkSpecifics; +import org.chromium.ui.base.WindowAndroid; import org.chromium.ui.util.ColorUtils; import java.util.Arrays; @@ -105,6 +107,10 @@ @Override public void removeOldWebAPKsFromSync(long currentTimeMsSinceUnixEpoch) {} + + @Override + public void fetchRestorableApps( + Profile profile, WindowAndroid windowAndroid, int arrowResourceId) {} } @Before
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 57a8148..8dbe62b 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -615,6 +615,8 @@ "history_clusters/history_clusters_service_factory.h", "history_clusters/history_clusters_tab_helper.cc", "history_clusters/history_clusters_tab_helper.h", + "history_embeddings/history_embeddings_service_factory.cc", + "history_embeddings/history_embeddings_service_factory.h", "icon_loader.cc", "icon_loader.h", "icon_manager.cc", @@ -1336,6 +1338,8 @@ "privacy/privacy_metrics_service.h", "privacy/privacy_metrics_service_factory.cc", "privacy/privacy_metrics_service_factory.h", + "privacy_sandbox/privacy_sandbox_notice_confirmation.cc", + "privacy_sandbox/privacy_sandbox_notice_confirmation.h", "privacy_sandbox/privacy_sandbox_policy_handler.cc", "privacy_sandbox/privacy_sandbox_policy_handler.h", "privacy_sandbox/privacy_sandbox_service.h", @@ -3401,7 +3405,6 @@ "wallet/android/boarding_pass_bridge.cc", "wallet/android/boarding_pass_detector.cc", "wallet/android/boarding_pass_detector.h", - "webapps/pwa_restore_promo_utils_android.cc", "webapps/web_app_offline_android.cc", "webapps/webapps_client_android.cc", "webapps/webapps_client_android.h", @@ -3494,7 +3497,6 @@ "//chrome/browser/ui/webui/feed_internals:mojo_bindings", "//chrome/browser/usb/android:jni_headers", "//chrome/browser/wallet/android:jni_headers", - "//chrome/browser/webapps/android:webapps_jni_headers", "//chrome/common:non_code_constants", "//chrome/common/wallet:mojo_bindings", "//chrome/services/media_gallery_util/public/cpp",
diff --git a/chrome/browser/android/browsing_data/browsing_data_bridge.cc b/chrome/browser/android/browsing_data/browsing_data_bridge.cc index d738954..f9c2bb6 100644 --- a/chrome/browser/android/browsing_data/browsing_data_bridge.cc +++ b/chrome/browser/android/browsing_data/browsing_data_bridge.cc
@@ -22,13 +22,16 @@ #include "base/values.h" #include "chrome/android/chrome_jni_headers/BrowsingDataBridge_jni.h" #include "chrome/browser/browsing_data/browsing_data_important_sites_util.h" +#include "chrome/browser/browsing_data/chrome_browsing_data_model_delegate.h" #include "chrome/browser/browsing_data/chrome_browsing_data_remover_constants.h" #include "chrome/browser/engagement/important_sites_util.h" #include "chrome/browser/history/web_history_service_factory.h" #include "chrome/browser/profiles/profile_android.h" #include "chrome/browser/sync/sync_service_factory.h" #include "chrome/common/channel_info.h" +#include "components/browsing_data/content/browsing_data_model.h" #include "components/browsing_data/core/browsing_data_utils.h" +#include "components/browsing_data/core/features.h" #include "components/browsing_data/core/history_notice_utils.h" #include "components/browsing_data/core/pref_names.h" #include "components/prefs/pref_service.h" @@ -38,10 +41,11 @@ #include "content/public/browser/browsing_data_remover.h" using base::android::AttachCurrentThread; +using base::android::ConvertUTF8ToJavaString; using base::android::JavaParamRef; using base::android::JavaRef; -using base::android::ScopedJavaLocalRef; using base::android::ScopedJavaGlobalRef; +using base::android::ScopedJavaLocalRef; using content::BrowsingDataRemover; namespace { @@ -70,6 +74,28 @@ clear_browsing_data_tab); } +void OnBrowsingDataModelBuilt(const ScopedJavaGlobalRef<jobject>& java_callback, + std::unique_ptr<BrowsingDataModel> model) { + JNIEnv* env = base::android::AttachCurrentThread(); + ScopedJavaLocalRef<jobject> map = + Java_BrowsingDataBridge_createBrowsingDataInfoMap(env); + std::map<url::Origin, std::pair<uint64_t, uint64_t>> origin_to_data_map; + + for (const auto& [owner, key, details] : *model) { + const auto origin = BrowsingDataModel::GetOriginForDataKey(key.get()); + origin_to_data_map[origin].first += details->cookie_count; + origin_to_data_map[origin].second += details->storage_size; + } + + for (const auto& [origin, data] : origin_to_data_map) { + Java_BrowsingDataBridge_insertBrowsingDataInfoIntoMap( + env, map, origin.ToJavaObject(), /*cookieCount=*/data.first, + /*storageSize=*/data.second); + } + + base::android::RunObjectCallbackAndroid(java_callback, map); +} + } // namespace static void JNI_BrowsingDataBridge_ClearBrowsingData( @@ -331,3 +357,14 @@ GetPrefService(jprofile)->SetInteger( browsing_data::prefs::kLastClearBrowsingDataTab, tab_index); } + +static void JNI_BrowsingDataBridge_FetchBrowsingDataInfo( + JNIEnv* env, + const JavaParamRef<jobject>& jprofile, + const JavaParamRef<jobject>& java_callback) { + Profile* profile = ProfileAndroid::FromProfileAndroid(jprofile); + BrowsingDataModel::BuildFromDisk( + profile, ChromeBrowsingDataModelDelegate::CreateForProfile(profile), + base::BindOnce(&OnBrowsingDataModelBuilt, + ScopedJavaGlobalRef<jobject>(java_callback))); +}
diff --git a/chrome/browser/android/webapk/webapk_sync_bridge.cc b/chrome/browser/android/webapk/webapk_sync_bridge.cc index 69ab33d..4c22f68e 100644 --- a/chrome/browser/android/webapk/webapk_sync_bridge.cc +++ b/chrome/browser/android/webapk/webapk_sync_bridge.cc
@@ -380,6 +380,18 @@ weak_ptr_factory_.GetWeakPtr(), base::DoNothing())); } +std::vector<std::vector<std::string>> WebApkSyncBridge::GetRestorableAppsInfo() + const { + std::vector<std::vector<std::string>> results; + for (auto const& [appId, proto] : registry_) { + if (!proto->is_locally_installed() && + AppWasUsedRecently(&proto->sync_data())) { + results.push_back({appId, proto->sync_data().name()}); + } + } + return results; +} + void WebApkSyncBridge::GetData(StorageKeyList storage_keys, DataCallback callback) { auto data_batch = std::make_unique<syncer::MutableDataBatch>();
diff --git a/chrome/browser/android/webapk/webapk_sync_bridge.h b/chrome/browser/android/webapk/webapk_sync_bridge.h index 02df06b..71747ab 100644 --- a/chrome/browser/android/webapk/webapk_sync_bridge.h +++ b/chrome/browser/android/webapk/webapk_sync_bridge.h
@@ -93,6 +93,10 @@ bool is_install); void OnWebApkUninstalled(const std::string& manifest_id); + // Get the apps info for apps that are available to restore. Returns the AppId + // and the app name for each of the apps as a vector of a vector. + std::vector<std::vector<std::string>> GetRestorableAppsInfo() const; + void SetClockForTesting(std::unique_ptr<base::Clock> clock); const Registry& GetRegistryForTesting() const;
diff --git a/chrome/browser/android/webapk/webapk_sync_bridge_unittest.cc b/chrome/browser/android/webapk/webapk_sync_bridge_unittest.cc index b9830c1..f2d8eb23 100644 --- a/chrome/browser/android/webapk/webapk_sync_bridge_unittest.cc +++ b/chrome/browser/android/webapk/webapk_sync_bridge_unittest.cc
@@ -21,6 +21,7 @@ #include "components/sync/protocol/entity_data.h" #include "components/sync/test/mock_model_type_change_processor.h" #include "components/webapps/common/web_app_id.h" +#include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "url/gurl.h" @@ -1155,4 +1156,67 @@ ->is_locally_installed()); } +TEST_F(WebApkSyncBridgeTest, GetRestorableAppsInfo) { + InitSyncBridge(); + + const std::string manifest_id_1 = "https://example.com/app1"; + const std::string manifest_id_2 = "https://example.com/app2"; + const std::string manifest_id_3 = "https://example.com/app3"; + const std::string manifest_id_4 = "https://example.com/app4"; + + std::unique_ptr<WebApkProto> registry_app_1 = + CreateWebApkProto(manifest_id_1, "registry_app_1"); + registry_app_1->mutable_sync_data()->set_last_used_time_windows_epoch_micros( + UnixTsSecToWindowsTsMsec( + 1136145845.0)); // Sun Jan 01 2006 15:04:05 GMT-0500 - slightly + // before clock_.Now() (recent enough) + registry_app_1->set_is_locally_installed(true); + + std::unique_ptr<WebApkProto> registry_app_2 = + CreateWebApkProto(manifest_id_2, "registry_app_2"); + registry_app_2->mutable_sync_data()->set_last_used_time_windows_epoch_micros( + UnixTsSecToWindowsTsMsec( + 1136145845.0)); // Sun Jan 01 2006 15:04:05 GMT-0500 - slightly + // before clock_.Now() (recent enough) + registry_app_2->set_is_locally_installed(false); + + std::unique_ptr<WebApkProto> registry_app_3 = + CreateWebApkProto(manifest_id_3, "registry_app_3"); + registry_app_3->mutable_sync_data()->set_last_used_time_windows_epoch_micros( + UnixTsSecToWindowsTsMsec( + 1133726645.0)); // Sun Dec 04 2005 15:04:05 GMT-0500 - 29 days before + // clock_.Now() (recent enough) + registry_app_3->set_is_locally_installed(false); + + std::unique_ptr<WebApkProto> registry_app_4 = + CreateWebApkProto(manifest_id_4, "registry_app_4"); + registry_app_4->mutable_sync_data()->set_last_used_time_windows_epoch_micros( + UnixTsSecToWindowsTsMsec( + 1133640244.0)); // Sat Dec 03 2005 15:04:04 GMT-0500 - 30 days and 1 + // second before clock_.Now() (not recent enough) + registry_app_4->set_is_locally_installed(false); + + Registry registry; + + InsertAppIntoRegistry(®istry, std::move(registry_app_1)); + InsertAppIntoRegistry(®istry, std::move(registry_app_2)); + InsertAppIntoRegistry(®istry, std::move(registry_app_3)); + InsertAppIntoRegistry(®istry, std::move(registry_app_4)); + + database_factory().WriteRegistry(registry); + + EXPECT_CALL(processor(), ModelReadyToSync).Times(1); + EXPECT_CALL(processor(), Put).Times(0); + EXPECT_CALL(processor(), Delete).Times(0); + + InitSyncBridge(); + + EXPECT_THAT(sync_bridge().GetRestorableAppsInfo(), + testing::ElementsAre( + std::vector<std::string>{ManifestIdStrToAppId(manifest_id_2), + "registry_app_2"}, + std::vector<std::string>{ManifestIdStrToAppId(manifest_id_3), + "registry_app_3"})); +} + } // namespace webapk
diff --git a/chrome/browser/android/webapk/webapk_sync_service.cc b/chrome/browser/android/webapk/webapk_sync_service.cc index 76216ef..cc719a2 100644 --- a/chrome/browser/android/webapk/webapk_sync_service.cc +++ b/chrome/browser/android/webapk/webapk_sync_service.cc
@@ -12,14 +12,18 @@ #include "base/feature_list.h" #include "base/functional/callback_helpers.h" #include "base/logging.h" +#include "chrome/android/chrome_jni_headers/PwaRestorePromoUtils_jni.h" #include "chrome/android/chrome_jni_headers/WebApkSyncService_jni.h" #include "chrome/browser/android/webapk/webapk_sync_service_factory.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/profiles/profile_android.h" #include "chrome/browser/profiles/profile_manager.h" #include "components/sync/base/features.h" using base::android::ConvertJavaStringToUTF8; using base::android::JavaParamRef; +using base::android::ScopedJavaGlobalRef; +using base::android::ScopedJavaLocalRef; namespace webapk { @@ -76,6 +80,11 @@ sync_bridge_->RemoveOldWebAPKsFromSync(current_time_ms_since_unix_epoch); } +std::vector<std::vector<std::string>> WebApkSyncService::GetRestorableAppsInfo() + const { + return sync_bridge_->GetRestorableAppsInfo(); +} + // static static void JNI_WebApkSyncService_OnWebApkUsed( JNIEnv* env, @@ -136,4 +145,24 @@ static_cast<int64_t>(java_current_time_ms_since_unix_epoch)); } +static void JNI_WebApkSyncService_FetchRestorableApps( + JNIEnv* env, + const JavaParamRef<jobject>& jprofile, + const JavaParamRef<jobject>& jwindow_android, + int arrow_resource_id) { + Profile* profile = + ProfileAndroid::FromProfileAndroid(jprofile)->GetWeakPtr().get(); + + if (profile == nullptr) { + return; + } + + auto result = + WebApkSyncService::GetForProfile(profile)->GetRestorableAppsInfo(); + ScopedJavaLocalRef<jobjectArray> jresults = + base::android::ToJavaArrayOfStringArray(env, result); + webapps::Java_PwaRestorePromoUtils_onRestorableAppsAvailable( + env, true, jresults, jwindow_android, arrow_resource_id); +} + } // namespace webapk
diff --git a/chrome/browser/android/webapk/webapk_sync_service.h b/chrome/browser/android/webapk/webapk_sync_service.h index bb71ea1..2e1c7bc9 100644 --- a/chrome/browser/android/webapk/webapk_sync_service.h +++ b/chrome/browser/android/webapk/webapk_sync_service.h
@@ -40,6 +40,8 @@ void OnWebApkUninstalled(const std::string& manifest_id); void RemoveOldWebAPKsFromSync(int64_t current_time_ms_since_unix_epoch); + std::vector<std::vector<std::string>> GetRestorableAppsInfo() const; + private: std::unique_ptr<AbstractWebApkDatabaseFactory> database_factory_; std::unique_ptr<WebApkSyncBridge> sync_bridge_;
diff --git a/chrome/browser/apps/app_service/app_icon/app_icon_reader.cc b/chrome/browser/apps/app_service/app_icon/app_icon_reader.cc index ba00db1..2448169b 100644 --- a/chrome/browser/apps/app_service/app_icon/app_icon_reader.cc +++ b/chrome/browser/apps/app_service/app_icon/app_icon_reader.cc
@@ -22,7 +22,7 @@ bool UseSmallIcon(int32_t size_in_dip) { int size_in_px = apps_util::ConvertDipToPx( - size_in_dip, /*quantize_to_supported_scale_factor=*/true); + size_in_dip, /*quantize_to_supported_scale_factor=*/false); return size_in_px <= 32; }
diff --git a/chrome/browser/apps/link_capturing/link_capturing_navigation_throttle_browsertest.cc b/chrome/browser/apps/link_capturing/link_capturing_navigation_throttle_browsertest.cc index 959617f..5846549 100644 --- a/chrome/browser/apps/link_capturing/link_capturing_navigation_throttle_browsertest.cc +++ b/chrome/browser/apps/link_capturing/link_capturing_navigation_throttle_browsertest.cc
@@ -37,9 +37,9 @@ public: void SetUpOnMainThread() override { #if BUILDFLAG(IS_CHROMEOS_LACROS) || \ - (BUILDFLAG(IS_LINUX) && defined(MEMORY_SANITIZER)) + (BUILDFLAG(IS_LINUX) && defined(MEMORY_SANITIZER)) || BUILDFLAG(IS_MAC) // TODO(https://issues.chromium.org/329174385): Deflake tests in - // lacros_chrome_browser_tests / Linux MSan Tests. + // lacros_chrome_browser_tests / Linux MSan Tests / Mac Tests. GTEST_SKIP(); #else InProcessBrowserTest::SetUpOnMainThread();
diff --git a/chrome/browser/ash/app_list/app_list_client_impl.cc b/chrome/browser/ash/app_list/app_list_client_impl.cc index a8175bf..fe2fbc1 100644 --- a/chrome/browser/ash/app_list/app_list_client_impl.cc +++ b/chrome/browser/ash/app_list/app_list_client_impl.cc
@@ -270,7 +270,8 @@ app_list_notifier_->NotifyLaunched( result->display_type(), - ash::AppListNotifier::Result(result_id, result->metrics_type())); + ash::AppListNotifier::Result(result_id, result->metrics_type(), + result->continue_file_suggestion_type())); RecordSearchResultOpenTypeHistogram( launched_from, result->metrics_type(), @@ -333,8 +334,9 @@ auto* result = FindAppResultByAppId(search_controller_.get(), id); if (result) { app_list_notifier_->NotifyLaunched( - result->display_type(), - ash::AppListNotifier::Result(result->id(), result->metrics_type())); + result->display_type(), ash::AppListNotifier::Result( + result->id(), result->metrics_type(), + result->continue_file_suggestion_type())); } }
diff --git a/chrome/browser/ash/app_list/search/chrome_search_result.cc b/chrome/browser/ash/app_list/search/chrome_search_result.cc index eea928e..79ddc5e2 100644 --- a/chrome/browser/ash/app_list/search/chrome_search_result.cc +++ b/chrome/browser/ash/app_list/search/chrome_search_result.cc
@@ -155,6 +155,12 @@ SetSearchResultMetadata(); } +void ChromeSearchResult::SetContinueFileSuggestionType( + ash::ContinueFileSuggestionType type) { + metadata_->continue_file_suggestion_type = type; + SetSearchResultMetadata(); +} + void ChromeSearchResult::SetIsRecommendation(bool is_recommendation) { metadata_->is_recommendation = is_recommendation; SetSearchResultMetadata();
diff --git a/chrome/browser/ash/app_list/search/chrome_search_result.h b/chrome/browser/ash/app_list/search/chrome_search_result.h index 3670993..f6b4f00 100644 --- a/chrome/browser/ash/app_list/search/chrome_search_result.h +++ b/chrome/browser/ash/app_list/search/chrome_search_result.h
@@ -97,6 +97,10 @@ return metadata_->result_type; } MetricsType metrics_type() const { return metadata_->metrics_type; } + const std::optional<ash::ContinueFileSuggestionType>& + continue_file_suggestion_type() const { + return metadata_->continue_file_suggestion_type; + } const Actions& actions() const { return metadata_->actions; } double display_score() const { return metadata_->display_score; } bool is_recommendation() const { return metadata_->is_recommendation; } @@ -139,6 +143,8 @@ void SetDisplayType(DisplayType display_type); void SetResultType(ResultType result_type); void SetMetricsType(MetricsType metrics_type); + void SetContinueFileSuggestionType( + ash::ContinueFileSuggestionType continue_file_suggestion_type); void SetDisplayScore(double display_score); void SetActions(const Actions& actions); void SetIsRecommendation(bool is_recommendation);
diff --git a/chrome/browser/ash/app_list/search/files/justifications.cc b/chrome/browser/ash/app_list/search/files/justifications.cc index 961b27fe..4aff4dd 100644 --- a/chrome/browser/ash/app_list/search/files/justifications.cc +++ b/chrome/browser/ash/app_list/search/files/justifications.cc
@@ -9,6 +9,7 @@ #include "base/i18n/time_formatting.h" #include "base/strings/utf_string_conversions.h" #include "base/time/time.h" +#include "chrome/browser/ash/file_suggest/file_suggest_util.h" #include "ui/base/l10n/l10n_util.h" namespace app_list { @@ -71,14 +72,14 @@ } } -std::u16string GetActionString(JustificationType type, +std::u16string GetActionString(ash::FileSuggestionJustificationType type, const std::string& user_name) { switch (type) { - case JustificationType::kViewed: { + case ash::FileSuggestionJustificationType::kViewed: { return l10n_util::GetStringUTF16( IDS_FILE_SUGGESTION_JUSTIFICATION_YOU_VIEWED_ACTION); } - case JustificationType::kModified: { + case ash::FileSuggestionJustificationType::kModified: { if (user_name.empty()) { return l10n_util::GetStringUTF16( IDS_FILE_SUGGESTION_JUSTIFICATION_GENERIC_MODIFIED_ACTION); @@ -87,11 +88,11 @@ IDS_FILE_SUGGESTION_JUSTIFICATION_USER_MODIFIED_ACTION, base::UTF8ToUTF16(user_name)); } - case JustificationType::kModifiedByCurrentUser: { + case ash::FileSuggestionJustificationType::kModifiedByCurrentUser: { return l10n_util::GetStringUTF16( IDS_FILE_SUGGESTION_JUSTIFICATION_YOU_MODIFIED_ACTION); } - case JustificationType::kShared: { + case ash::FileSuggestionJustificationType::kShared: { if (user_name.empty()) { return l10n_util::GetStringUTF16( IDS_FILE_SUGGESTION_JUSTIFICATION_GENERIC_SHARED_ACTION); @@ -100,13 +101,16 @@ IDS_FILE_SUGGESTION_JUSTIFICATION_USER_SHARED_ACTION, base::UTF8ToUTF16(user_name)); } + case ash::FileSuggestionJustificationType::kUnknown: { + return u""; + } } } } // namespace std::optional<std::u16string> GetJustificationString( - JustificationType type, + ash::FileSuggestionJustificationType type, const base::Time& timestamp, const std::string& user_name) { if (ash::features::IsLauncherContinueSectionWithRecentsEnabled()) { @@ -115,12 +119,13 @@ GetTimeString(timestamp)); } switch (type) { - case JustificationType::kViewed: + case ash::FileSuggestionJustificationType::kViewed: return GetOpenStringFromTime(timestamp); - case JustificationType::kModified: - case JustificationType::kModifiedByCurrentUser: + case ash::FileSuggestionJustificationType::kModified: + case ash::FileSuggestionJustificationType::kModifiedByCurrentUser: return GetEditStringFromTime(timestamp); - case JustificationType::kShared: + case ash::FileSuggestionJustificationType::kShared: + case ash::FileSuggestionJustificationType::kUnknown: return std::nullopt; } }
diff --git a/chrome/browser/ash/app_list/search/files/justifications.h b/chrome/browser/ash/app_list/search/files/justifications.h index 46c9eb7..e09bf87 100644 --- a/chrome/browser/ash/app_list/search/files/justifications.h +++ b/chrome/browser/ash/app_list/search/files/justifications.h
@@ -10,14 +10,11 @@ #include "base/time/time.h" -namespace app_list { +namespace ash { +enum class FileSuggestionJustificationType; +} // namespace ash -enum class JustificationType { - kViewed, - kModified, - kModifiedByCurrentUser, - kShared, -}; +namespace app_list { // Returns a justification string for file suggestions. The justification string // describes the action that prompted the file to be suggested to the user. @@ -29,7 +26,7 @@ // if the user name is not relevant for the action, or not known (in which case // the justification will show a fallback string without user name). std::optional<std::u16string> GetJustificationString( - JustificationType type, + ash::FileSuggestionJustificationType type, const base::Time& timestamp, const std::string& user_name);
diff --git a/chrome/browser/ash/app_list/search/files/justifications_unittest.cc b/chrome/browser/ash/app_list/search/files/justifications_unittest.cc index c587019..835873a 100644 --- a/chrome/browser/ash/app_list/search/files/justifications_unittest.cc +++ b/chrome/browser/ash/app_list/search/files/justifications_unittest.cc
@@ -8,6 +8,7 @@ #include "ash/strings/grit/ash_strings.h" #include "base/test/scoped_feature_list.h" #include "base/time/time.h" +#include "chrome/browser/ash/file_suggest/file_suggest_util.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/base/l10n/l10n_util.h" @@ -29,76 +30,89 @@ base::Time now = base::Time::Now(); // Opened more recently than edited. - EXPECT_EQ(GetJustificationString(app_list::JustificationType::kViewed, - now - base::Seconds(10), /*user_name=*/""), - l10n_util::GetStringUTF16(IDS_APP_LIST_CONTINUE_OPENED_JUST_NOW)); + EXPECT_EQ( + GetJustificationString(ash::FileSuggestionJustificationType::kViewed, + now - base::Seconds(10), /*user_name=*/""), + l10n_util::GetStringUTF16(IDS_APP_LIST_CONTINUE_OPENED_JUST_NOW)); // Edited more recently than opened. - EXPECT_EQ(GetJustificationString(app_list::JustificationType::kModified, - now - base::Seconds(10), /*user_name=*/""), - l10n_util::GetStringUTF16(IDS_APP_LIST_CONTINUE_EDITED_JUST_NOW)); + EXPECT_EQ( + GetJustificationString(ash::FileSuggestionJustificationType::kModified, + now - base::Seconds(10), /*user_name=*/""), + l10n_util::GetStringUTF16(IDS_APP_LIST_CONTINUE_EDITED_JUST_NOW)); } TEST_F(JustificationsTest, EditTimes) { base::Time now = base::Time::Now(); // Just now. - EXPECT_EQ(GetJustificationString(app_list::JustificationType::kModified, - now - base::Minutes(5), /*user_name=*/""), - l10n_util::GetStringUTF16(IDS_APP_LIST_CONTINUE_EDITED_JUST_NOW)); + EXPECT_EQ( + GetJustificationString(ash::FileSuggestionJustificationType::kModified, + now - base::Minutes(5), /*user_name=*/""), + l10n_util::GetStringUTF16(IDS_APP_LIST_CONTINUE_EDITED_JUST_NOW)); // Today. - EXPECT_EQ(GetJustificationString(app_list::JustificationType::kModified, - now - base::Hours(23), /*user_name=*/""), - l10n_util::GetStringUTF16(IDS_APP_LIST_CONTINUE_EDITED_TODAY)); + EXPECT_EQ( + GetJustificationString(ash::FileSuggestionJustificationType::kModified, + now - base::Hours(23), /*user_name=*/""), + l10n_util::GetStringUTF16(IDS_APP_LIST_CONTINUE_EDITED_TODAY)); // Yesterday. - EXPECT_EQ(GetJustificationString(app_list::JustificationType::kModified, - now - base::Hours(47), /*user_name=*/""), - l10n_util::GetStringUTF16(IDS_APP_LIST_CONTINUE_EDITED_YESTERDAY)); + EXPECT_EQ( + GetJustificationString(ash::FileSuggestionJustificationType::kModified, + now - base::Hours(47), /*user_name=*/""), + l10n_util::GetStringUTF16(IDS_APP_LIST_CONTINUE_EDITED_YESTERDAY)); // Past week. - EXPECT_EQ(GetJustificationString(app_list::JustificationType::kModified, - now - base::Days(6), /*user_name=*/""), - l10n_util::GetStringUTF16(IDS_APP_LIST_CONTINUE_EDITED_PAST_WEEK)); + EXPECT_EQ( + GetJustificationString(ash::FileSuggestionJustificationType::kModified, + now - base::Days(6), /*user_name=*/""), + l10n_util::GetStringUTF16(IDS_APP_LIST_CONTINUE_EDITED_PAST_WEEK)); // Past month. - EXPECT_EQ(GetJustificationString(app_list::JustificationType::kModified, - now - base::Days(30), /*user_name=*/""), - l10n_util::GetStringUTF16(IDS_APP_LIST_CONTINUE_EDITED_PAST_MONTH)); + EXPECT_EQ( + GetJustificationString(ash::FileSuggestionJustificationType::kModified, + now - base::Days(30), /*user_name=*/""), + l10n_util::GetStringUTF16(IDS_APP_LIST_CONTINUE_EDITED_PAST_MONTH)); // No string, file too old. - EXPECT_FALSE(GetJustificationString(app_list::JustificationType::kModified, - now - base::Days(32), /*user_name=*/"")); + EXPECT_FALSE( + GetJustificationString(ash::FileSuggestionJustificationType::kModified, + now - base::Days(32), /*user_name=*/"")); } TEST_F(JustificationsTest, OpenTimes) { base::Time now = base::Time::Now(); // Just now. - EXPECT_EQ(GetJustificationString(app_list::JustificationType::kViewed, - now - base::Minutes(5), /*user_name=*/""), - l10n_util::GetStringUTF16(IDS_APP_LIST_CONTINUE_OPENED_JUST_NOW)); + EXPECT_EQ( + GetJustificationString(ash::FileSuggestionJustificationType::kViewed, + now - base::Minutes(5), /*user_name=*/""), + l10n_util::GetStringUTF16(IDS_APP_LIST_CONTINUE_OPENED_JUST_NOW)); // Today. - EXPECT_EQ(GetJustificationString(app_list::JustificationType::kViewed, - now - base::Hours(23), /*user_name=*/""), - l10n_util::GetStringUTF16(IDS_APP_LIST_CONTINUE_OPENED_TODAY)); + EXPECT_EQ( + GetJustificationString(ash::FileSuggestionJustificationType::kViewed, + now - base::Hours(23), /*user_name=*/""), + l10n_util::GetStringUTF16(IDS_APP_LIST_CONTINUE_OPENED_TODAY)); // Yesterday. - EXPECT_EQ(GetJustificationString(app_list::JustificationType::kViewed, - now - base::Hours(47), /*user_name=*/""), - l10n_util::GetStringUTF16(IDS_APP_LIST_CONTINUE_OPENED_YESTERDAY)); + EXPECT_EQ( + GetJustificationString(ash::FileSuggestionJustificationType::kViewed, + now - base::Hours(47), /*user_name=*/""), + l10n_util::GetStringUTF16(IDS_APP_LIST_CONTINUE_OPENED_YESTERDAY)); // Past week. - EXPECT_EQ(GetJustificationString(app_list::JustificationType::kViewed, - now - base::Days(6), /*user_name=*/""), - l10n_util::GetStringUTF16(IDS_APP_LIST_CONTINUE_OPENED_PAST_WEEK)); + EXPECT_EQ( + GetJustificationString(ash::FileSuggestionJustificationType::kViewed, + now - base::Days(6), /*user_name=*/""), + l10n_util::GetStringUTF16(IDS_APP_LIST_CONTINUE_OPENED_PAST_WEEK)); // Past month. - EXPECT_EQ(GetJustificationString(app_list::JustificationType::kViewed, - now - base::Days(30), /*user_name=*/""), - l10n_util::GetStringUTF16(IDS_APP_LIST_CONTINUE_OPENED_PAST_MONTH)); + EXPECT_EQ( + GetJustificationString(ash::FileSuggestionJustificationType::kViewed, + now - base::Days(30), /*user_name=*/""), + l10n_util::GetStringUTF16(IDS_APP_LIST_CONTINUE_OPENED_PAST_MONTH)); } } // namespace app_list::test
diff --git a/chrome/browser/ash/app_list/search/files/zero_state_drive_provider.cc b/chrome/browser/ash/app_list/search/files/zero_state_drive_provider.cc index ac512cb..56f57031 100644 --- a/chrome/browser/ash/app_list/search/files/zero_state_drive_provider.cc +++ b/chrome/browser/ash/app_list/search/files/zero_state_drive_provider.cc
@@ -175,8 +175,9 @@ ? ash::ToTimestampBasedScore(result, max_recency) : (1.0 - item_index / total_items); ++item_index; - provider_results.emplace_back(MakeListResult( - result.id, result.file_path, result.prediction_reason, score)); + provider_results.emplace_back( + MakeListResult(result.id, result.file_path, result.justification_type, + result.prediction_reason, score)); } SwapResults(&provider_results); @@ -186,6 +187,7 @@ std::unique_ptr<FileResult> ZeroStateDriveProvider::MakeListResult( const std::string& result_id, const base::FilePath& filepath, + ash::FileSuggestionJustificationType justification_type, const std::optional<std::u16string>& prediction_reason, const float relevance) { std::optional<std::u16string> details; @@ -197,6 +199,26 @@ ash::AppListSearchResultType::kZeroStateDrive, ash::SearchResultDisplayType::kContinue, relevance, std::u16string(), FileResult::Type::kFile, profile_); + switch (justification_type) { + case ash::FileSuggestionJustificationType::kUnknown: + break; + case ash::FileSuggestionJustificationType::kViewed: + result->SetContinueFileSuggestionType( + ash::ContinueFileSuggestionType::kViewedDrive); + break; + case ash::FileSuggestionJustificationType::kModified: + result->SetContinueFileSuggestionType( + ash::ContinueFileSuggestionType::kModifiedDrive); + break; + case ash::FileSuggestionJustificationType::kModifiedByCurrentUser: + result->SetContinueFileSuggestionType( + ash::ContinueFileSuggestionType::kModifiedByCurrentUserDrive); + break; + case ash::FileSuggestionJustificationType::kShared: + result->SetContinueFileSuggestionType( + ash::ContinueFileSuggestionType::kSharedWithUserDrive); + break; + } return result; }
diff --git a/chrome/browser/ash/app_list/search/files/zero_state_drive_provider.h b/chrome/browser/ash/app_list/search/files/zero_state_drive_provider.h index 88af4e1..1c36f2d 100644 --- a/chrome/browser/ash/app_list/search/files/zero_state_drive_provider.h +++ b/chrome/browser/ash/app_list/search/files/zero_state_drive_provider.h
@@ -75,6 +75,7 @@ std::unique_ptr<FileResult> MakeListResult( const std::string& result_id, const base::FilePath& filepath, + ash::FileSuggestionJustificationType justification_type, const std::optional<std::u16string>& prediction_reason, const float relevance);
diff --git a/chrome/browser/ash/app_list/search/files/zero_state_drive_provider_unittest.cc b/chrome/browser/ash/app_list/search/files/zero_state_drive_provider_unittest.cc index 36b58be..b9f062cb 100644 --- a/chrome/browser/ash/app_list/search/files/zero_state_drive_provider_unittest.cc +++ b/chrome/browser/ash/app_list/search/files/zero_state_drive_provider_unittest.cc
@@ -261,6 +261,7 @@ drive_fs_mount_point_.get()->CreateArbitraryFile(); suggestions.emplace_back(ash::FileSuggestionType::kDriveFile, suggested_file_path, + ash::FileSuggestionJustificationType::kUnknown, /*new_prediction_reason=*/std::nullopt, /*timestamp=*/std::nullopt, /*secondary_timestamp=*/std::nullopt,
diff --git a/chrome/browser/ash/app_list/search/files/zero_state_file_provider.cc b/chrome/browser/ash/app_list/search/files/zero_state_file_provider.cc index efec337..2546d7a 100644 --- a/chrome/browser/ash/app_list/search/files/zero_state_file_provider.cc +++ b/chrome/browser/ash/app_list/search/files/zero_state_file_provider.cc
@@ -119,6 +119,25 @@ ash::AppListSearchResultType::kZeroStateFile, ash::SearchResultDisplayType::kContinue, score, std::u16string(), FileResult::Type::kFile, profile_); + switch (results[i].justification_type) { + case ash::FileSuggestionJustificationType::kUnknown: + NOTREACHED(); + break; + case ash::FileSuggestionJustificationType::kViewed: + result->SetContinueFileSuggestionType( + ash::ContinueFileSuggestionType::kViewedFile); + break; + case ash::FileSuggestionJustificationType::kModified: + NOTREACHED(); + break; + case ash::FileSuggestionJustificationType::kModifiedByCurrentUser: + result->SetContinueFileSuggestionType( + ash::ContinueFileSuggestionType::kModifiedByCurrentUserFile); + break; + case ash::FileSuggestionJustificationType::kShared: + NOTREACHED(); + break; + } new_results.push_back(std::move(result)); } }
diff --git a/chrome/browser/ash/app_list/search/help_app_zero_state_provider_unittest.cc b/chrome/browser/ash/app_list/search/help_app_zero_state_provider_unittest.cc index 8ddc35e..f5c092e6 100644 --- a/chrome/browser/ash/app_list/search/help_app_zero_state_provider_unittest.cc +++ b/chrome/browser/ash/app_list/search/help_app_zero_state_provider_unittest.cc
@@ -120,7 +120,7 @@ app_list_notifier()->NotifyResultsUpdated( ash::SearchResultDisplayType::kContinue, {ash::AppListNotifier::Result(kReleaseNotesResultId, - ash::HELP_APP_UPDATES)}); + ash::HELP_APP_UPDATES, std::nullopt)}); EXPECT_FALSE(app_list_notifier()->FireImpressionTimerForTesting( ash::AppListNotifier::Location::kContinue));
diff --git a/chrome/browser/ash/app_list/search/search_metrics_manager.cc b/chrome/browser/ash/app_list/search/search_metrics_manager.cc index 68f9908..a80a7f082 100644 --- a/chrome/browser/ash/app_list/search/search_metrics_manager.cc +++ b/chrome/browser/ash/app_list/search/search_metrics_manager.cc
@@ -54,6 +54,17 @@ return types; } +std::set<ash::ContinueFileSuggestionType> ContinueFileTypeSet( + const std::vector<Result>& results) { + std::set<ash::ContinueFileSuggestionType> types; + for (const auto& result : results) { + if (result.continue_file_type) { + types.insert(*result.continue_file_type); + } + } + return types; +} + // Log an action on a set of search result types. void LogTypeActions(const std::string& action_name, Location location, @@ -72,6 +83,21 @@ } } +void LogContinueFileTypeActions( + const std::string& action_name, + Location location, + const std::set<ash::ContinueFileSuggestionType>& continue_file_types) { + if (location != Location::kContinue) { + return; + } + + const std::string histogram_name = base::StrCat( + {kHistogramPrefix, "Continue.FileSuggestionType.", action_name}); + for (auto type : continue_file_types) { + base::UmaHistogramEnumeration(histogram_name, type); + } +} + // Log an action for a search result view as a whole. void LogViewAction(Location location, const std::u16string& query, @@ -143,6 +169,8 @@ const std::vector<Result>& results, const std::u16string& query) { LogTypeActions("Impression", location, query, TypeSet(results)); + LogContinueFileTypeActions("Impression", location, + ContinueFileTypeSet(results)); if (!results.empty()) LogViewAction(location, query, Action::kImpression); if (location == Location::kContinue) @@ -153,6 +181,7 @@ const std::vector<Result>& results, const std::u16string& query) { LogTypeActions("Abandon", location, query, TypeSet(results)); + LogContinueFileTypeActions("Abandon", location, ContinueFileTypeSet(results)); if (!results.empty()) LogViewAction(location, query, Action::kAbandon); } @@ -171,8 +200,22 @@ types.insert(result.type); } } + + std::set<ash::ContinueFileSuggestionType> continue_file_types; + for (const auto& result : shown) { + if (result.continue_file_type && + result.continue_file_type != launched.continue_file_type) { + continue_file_types.insert(*result.continue_file_type); + } + } + LogTypeActions("Ignore", location, query, types); + LogContinueFileTypeActions("Ignore", location, continue_file_types); LogTypeActions("Launch", location, query, {launched.type}); + if (launched.continue_file_type) { + LogContinueFileTypeActions("Launch", location, + {*launched.continue_file_type}); + } // Record the launch index. int launched_index = -1;
diff --git a/chrome/browser/ash/app_list/search/test/search_metrics_test_util.cc b/chrome/browser/ash/app_list/search/test/search_metrics_test_util.cc index ed02850..64d3cf0 100644 --- a/chrome/browser/ash/app_list/search/test/search_metrics_test_util.cc +++ b/chrome/browser/ash/app_list/search/test/search_metrics_test_util.cc
@@ -4,10 +4,12 @@ #include "chrome/browser/ash/app_list/search/test/search_metrics_test_util.h" +#include <optional> + namespace app_list::test { Result CreateFakeResult(Type type, const std::string& id) { - return Result(id, type); + return Result(id, type, std::nullopt); } } // namespace app_list::test
diff --git a/chrome/browser/ash/app_mode/app_launch_utils.cc b/chrome/browser/ash/app_mode/app_launch_utils.cc index 5fc717f..1f765fa 100644 --- a/chrome/browser/ash/app_mode/app_launch_utils.cc +++ b/chrome/browser/ash/app_mode/app_launch_utils.cc
@@ -73,7 +73,7 @@ } bool ShouldAutoLaunchKioskApp(const base::CommandLine& command_line, - PrefService* local_state) { + const PrefService& local_state) { // We shouldn't auto launch kiosk app if a designated command line switch was // used. // @@ -85,7 +85,7 @@ } // We shouldn't auto launch kiosk app if powerwash screen should be shown. - if (local_state->GetBoolean(prefs::kFactoryResetRequested)) { + if (local_state.GetBoolean(prefs::kFactoryResetRequested)) { return false; }
diff --git a/chrome/browser/ash/app_mode/app_launch_utils.h b/chrome/browser/ash/app_mode/app_launch_utils.h index 78c51e3..a966f04 100644 --- a/chrome/browser/ash/app_mode/app_launch_utils.h +++ b/chrome/browser/ash/app_mode/app_launch_utils.h
@@ -32,7 +32,7 @@ // Checks whether kiosk auto launch should be started. bool ShouldAutoLaunchKioskApp(const base::CommandLine& command_line, - PrefService* local_state); + const PrefService& local_state); void CreateKioskSystemSession(const KioskAppId& kiosk_app_id, Profile* profile,
diff --git a/chrome/browser/ash/app_mode/kiosk_crash_restore_browsertest.cc b/chrome/browser/ash/app_mode/kiosk_crash_restore_browsertest.cc index b0dd60f..beaf87fa 100644 --- a/chrome/browser/ash/app_mode/kiosk_crash_restore_browsertest.cc +++ b/chrome/browser/ash/app_mode/kiosk_crash_restore_browsertest.cc
@@ -7,6 +7,7 @@ #include "ash/constants/ash_switches.h" #include "base/base64.h" +#include "base/check_deref.h" #include "base/command_line.h" #include "base/run_loop.h" #include "base/values.h" @@ -31,6 +32,14 @@ namespace ash { +namespace { + +PrefService& local_state() { + return CHECK_DEREF(g_browser_process->local_state()); +} + +} // namespace + class KioskCrashRestoreTest : public MixinBasedInProcessBrowserTest, public LocalStateMixin::Delegate { public: @@ -90,13 +99,12 @@ const std::string policy_data_string = policy_data.SerializeAsString(); // Store policy data and existing device local accounts in local state. - g_browser_process->local_state()->SetString(prefs::kDeviceSettingsCache, - base::Base64Encode(policy_data_string)); + local_state().SetString(prefs::kDeviceSettingsCache, + base::Base64Encode(policy_data_string)); base::Value::List accounts; accounts.Append(GetTestAppUserId()); - g_browser_process->local_state()->SetList("PublicAccounts", - std::move(accounts)); + local_state().SetList("PublicAccounts", std::move(accounts)); } policy::DevicePolicyBuilder device_policy_; @@ -116,7 +124,8 @@ } }; -IN_PROC_BROWSER_TEST_F(ChromeKioskCrashRestoreTest, ChromeAppNotInstalled) { +IN_PROC_BROWSER_TEST_F(ChromeKioskCrashRestoreTest, + ShouldFailToRelaunchMissingCrashedChromeApp) { // If app is not installed when restoring from crash, the kiosk launch is // expected to fail, as in that case the crash occured during the app // initialization - before the app was actually launched. @@ -132,12 +141,11 @@ } }; -IN_PROC_BROWSER_TEST_F(WebKioskCrashRestoreTest, WebKioskLaunches) { - // If app is not installed when restoring from crash, the kiosk launch is - // expected to fail, as in that case the crash occured during the app - // initialization - before the app was actually launched. - EXPECT_EQ(KioskAppLaunchError::Error::kNone, KioskAppLaunchError::Get()); +IN_PROC_BROWSER_TEST_F(WebKioskCrashRestoreTest, ShouldRelaunchCrashedWebApp) { + // Wait for the kiosk app to launch (through the crash recovery flow). KioskSessionInitializedWaiter().Wait(); + // Check there was no launch error. + EXPECT_EQ(KioskAppLaunchError::Error::kNone, KioskAppLaunchError::Get()); } } // namespace ash
diff --git a/chrome/browser/ash/app_restore/pine_browsertest.cc b/chrome/browser/ash/app_restore/pine_browsertest.cc index f556fb30d..35f62376 100644 --- a/chrome/browser/ash/app_restore/pine_browsertest.cc +++ b/chrome/browser/ash/app_restore/pine_browsertest.cc
@@ -310,8 +310,14 @@ AppLaunchInfoSaveWaiter::Wait(); } +// TODO(crbug.com/330098654): Test is flaky. // Tests that the browser windows are restored to their old window states. -IN_PROC_BROWSER_TEST_F(PineBrowserTest, WindowStates) { +#if (BUILDFLAG(IS_CHROMEOS_ASH) && defined(MEMORY_SANITIZER)) +#define MAYBE_WindowStates DISABLED_WindowStates +#else +#define MAYBE_WindowStates WindowStates +#endif +IN_PROC_BROWSER_TEST_F(PineBrowserTest, MAYBE_WindowStates) { EXPECT_TRUE(BrowserList::GetInstance()->empty()); // Verify we have entered overview. The restore button will be null if we
diff --git a/chrome/browser/ash/chrome_browser_main_parts_ash.cc b/chrome/browser/ash/chrome_browser_main_parts_ash.cc index 4be5f98..3065a2b 100644 --- a/chrome/browser/ash/chrome_browser_main_parts_ash.cc +++ b/chrome/browser/ash/chrome_browser_main_parts_ash.cc
@@ -970,7 +970,7 @@ if (base::CommandLine::ForCurrentProcess()->HasSwitch( ::switches::kTestType) || ShouldAutoLaunchKioskApp(*base::CommandLine::ForCurrentProcess(), - g_browser_process->local_state())) { + *g_browser_process->local_state())) { WizardController::SetZeroDelays(); }
diff --git a/chrome/browser/ash/crosapi/login_ash.cc b/chrome/browser/ash/crosapi/login_ash.cc index 2799c3e..71f23eef 100644 --- a/chrome/browser/ash/crosapi/login_ash.cc +++ b/chrome/browser/ash/crosapi/login_ash.cc
@@ -209,7 +209,7 @@ const user_manager::User* active_user = user_manager->GetActiveUser(); if (!active_user || active_user->GetType() != user_manager::UserType::kPublicAccount || - !user_manager->CanCurrentUserLock()) { + !active_user->CanLock()) { std::move(callback).Run(extensions::login_api_errors::kNoUnlockableSession); return; } @@ -353,7 +353,7 @@ const user_manager::UserManager* user_manager = user_manager::UserManager::Get(); const user_manager::User* active_user = user_manager->GetActiveUser(); - if (!active_user || !user_manager->CanCurrentUserLock() || + if (!active_user || !active_user->CanLock() || (user_type && active_user->GetType() != user_type)) { return extensions::login_api_errors::kNoLockableSession; } @@ -372,7 +372,7 @@ const user_manager::UserManager* user_manager = user_manager::UserManager::Get(); const user_manager::User* active_user = user_manager->GetActiveUser(); - if (!active_user || !user_manager->CanCurrentUserLock() || + if (!active_user || !active_user->CanLock() || (user_type && active_user->GetType() != user_type)) { return extensions::login_api_errors::kNoUnlockableSession; }
diff --git a/chrome/browser/ash/extensions/autotest_private/autotest_private_apitest.cc b/chrome/browser/ash/extensions/autotest_private/autotest_private_apitest.cc index ffb7f71..6624bd7 100644 --- a/chrome/browser/ash/extensions/autotest_private/autotest_private_apitest.cc +++ b/chrome/browser/ash/extensions/autotest_private/autotest_private_apitest.cc
@@ -169,9 +169,8 @@ ash::ScopedTestingCrosSettings scoped_testing_cros_settings_; }; -// Flaky on linux. -// TODO(b/327929010): re-enable the following test. -#if defined(IS_LINUX) +// TODO(crbug.com/41491890): Flaky on ASan/LSan, deflake and re-enable the test. +#if defined(ADDRESS_SANITIZER) || defined(LEAK_SANITIZER) #define MAYBE_AutotestPrivate DISABLED_AutotestPrivate #else #define MAYBE_AutotestPrivate AutotestPrivate
diff --git a/chrome/browser/ash/file_suggest/drive_file_suggestion_provider.cc b/chrome/browser/ash/file_suggest/drive_file_suggestion_provider.cc index 2b091572..6e8c535 100644 --- a/chrome/browser/ash/file_suggest/drive_file_suggestion_provider.cc +++ b/chrome/browser/ash/file_suggest/drive_file_suggestion_provider.cc
@@ -216,7 +216,8 @@ } suggest_results.emplace_back( FileSuggestionType::kDriveFile, - ReparentToDriveMount(path_or_error->get_path(), drive_service_), reason, + ReparentToDriveMount(path_or_error->get_path(), drive_service_), + FileSuggestionJustificationType::kUnknown, reason, /*timestamp=*/std::nullopt, /*secondary_timestamp=*/std::nullopt, /*score=*/std::nullopt);
diff --git a/chrome/browser/ash/file_suggest/drive_recent_file_suggestion_provider.cc b/chrome/browser/ash/file_suggest/drive_recent_file_suggestion_provider.cc index 83b029f..6005730 100644 --- a/chrome/browser/ash/file_suggest/drive_recent_file_suggestion_provider.cc +++ b/chrome/browser/ash/file_suggest/drive_recent_file_suggestion_provider.cc
@@ -79,13 +79,13 @@ FileSuggestData CreateFileSuggestionWithJustification( const base::FilePath& path, - app_list::JustificationType justification_type, + FileSuggestionJustificationType justification_type, const base::Time& timestamp, const drivefs::mojom::UserInfo* user_info) { // Use secondary timestamp for files suggested because they were shared with // the user, so they are ordered after suggestions for viewed/modified files. const bool shared_with_me_suggestion = - justification_type == app_list::JustificationType::kShared; + justification_type == FileSuggestionJustificationType::kShared; std::optional<base::Time> primary_timestamp; std::optional<base::Time> secondary_timestamp; if (shared_with_me_suggestion) { @@ -95,7 +95,7 @@ } return FileSuggestData( - FileSuggestionType::kDriveFile, path, + FileSuggestionType::kDriveFile, path, justification_type, app_list::GetJustificationString( justification_type, timestamp, user_info ? user_info->display_name : std::string()), @@ -119,7 +119,7 @@ } return CreateFileSuggestionWithJustification( - path, app_list::JustificationType::kShared, *shared_time, + path, FileSuggestionJustificationType::kShared, *shared_time, features::IsShowSharingUserInLauncherContinueSectionEnabled() ? file_metadata.sharing_user.get() : nullptr); @@ -131,7 +131,7 @@ return std::nullopt; } return CreateFileSuggestionWithJustification( - path, app_list::JustificationType::kViewed, viewed_time, + path, FileSuggestionJustificationType::kViewed, viewed_time, /*user_info=*/nullptr); } @@ -149,14 +149,14 @@ !file_metadata.modified_by_me_time->is_null() && file_metadata.modified_by_me_time >= modified_time) { return CreateFileSuggestionWithJustification( - path, app_list::JustificationType::kModifiedByCurrentUser, + path, FileSuggestionJustificationType::kModifiedByCurrentUser, *file_metadata.modified_by_me_time, /*user_info=*/nullptr); } // Last modification was by either by another user, or the last modifying user // information is not available. return CreateFileSuggestionWithJustification( - path, app_list::JustificationType::kModified, modified_time, + path, FileSuggestionJustificationType::kModified, modified_time, file_metadata.last_modifying_user.get()); }
diff --git a/chrome/browser/ash/file_suggest/file_suggest_keyed_service_unittest.cc b/chrome/browser/ash/file_suggest/file_suggest_keyed_service_unittest.cc index 0a0dddc..8523de4 100644 --- a/chrome/browser/ash/file_suggest/file_suggest_keyed_service_unittest.cc +++ b/chrome/browser/ash/file_suggest/file_suggest_keyed_service_unittest.cc
@@ -137,6 +137,7 @@ for (size_t index = 0; index < count; ++index) { suggested_file_paths.push_back(mount_point->CreateArbitraryFile()); suggestions.emplace_back(type, suggested_file_paths.back(), + ash::FileSuggestionJustificationType::kUnknown, /*new_prediction_reason=*/std::nullopt, /*timestamp=*/std::nullopt, /*secondary_timestamp=*/std::nullopt,
diff --git a/chrome/browser/ash/file_suggest/file_suggest_util.cc b/chrome/browser/ash/file_suggest/file_suggest_util.cc index 254bf38..1243908 100644 --- a/chrome/browser/ash/file_suggest/file_suggest_util.cc +++ b/chrome/browser/ash/file_suggest/file_suggest_util.cc
@@ -74,6 +74,7 @@ FileSuggestData::FileSuggestData( FileSuggestionType new_type, const base::FilePath& new_file_path, + FileSuggestionJustificationType justification_type, const std::optional<std::u16string>& new_prediction_reason, const std::optional<base::Time>& timestamp, const std::optional<base::Time>& secondary_timestamp, @@ -81,6 +82,7 @@ : type(new_type), file_path(new_file_path), id(CalculateSuggestionId(type, file_path)), + justification_type(justification_type), prediction_reason(new_prediction_reason), timestamp(timestamp), secondary_timestamp(secondary_timestamp),
diff --git a/chrome/browser/ash/file_suggest/file_suggest_util.h b/chrome/browser/ash/file_suggest/file_suggest_util.h index af6f7ab..22da5c47 100644 --- a/chrome/browser/ash/file_suggest/file_suggest_util.h +++ b/chrome/browser/ash/file_suggest/file_suggest_util.h
@@ -39,6 +39,25 @@ kLocalFile, }; +// The reason the file is suggested. +enum class FileSuggestionJustificationType { + // Used only for deprecated suggestions from drive's ItemSuggest API, for + // which the exact justification type is obscured. + kUnknown, + + // The user recently viewed the file. + kViewed, + + // The file was recently modified, usually by another user. + kModified, + + // The file was recently modified by the current user. + kModifiedByCurrentUser, + + // The file was shared with the current user. + kShared, +}; + // Returns the max amount of time from now that a file was modified or viewed to // be available as a file suggestion. base::TimeDelta GetMaxFileSuggestionRecency(); @@ -52,6 +71,7 @@ struct FileSuggestData { FileSuggestData(FileSuggestionType new_type, const base::FilePath& new_file_path, + FileSuggestionJustificationType justification_type, const std::optional<std::u16string>& new_prediction_reason, const std::optional<base::Time>& timestamp, const std::optional<base::Time>& secondary_timestamp, @@ -70,6 +90,8 @@ // The suggestion id. Calculated from `type` and `file_path`. std::string id; + FileSuggestionJustificationType justification_type; + // The reason why the file is suggested. std::optional<std::u16string> prediction_reason;
diff --git a/chrome/browser/ash/file_suggest/local_file_suggestion_provider.cc b/chrome/browser/ash/file_suggest/local_file_suggestion_provider.cc index 4c3b0098..d536eb20 100644 --- a/chrome/browser/ash/file_suggest/local_file_suggestion_provider.cc +++ b/chrome/browser/ash/file_suggest/local_file_suggestion_provider.cc
@@ -214,21 +214,25 @@ for (auto& result : results.first) { if (result.info.last_accessed > result.info.last_modified) { std::optional<std::u16string> justification_string = - app_list::GetJustificationString(app_list::JustificationType::kViewed, - result.info.last_accessed, - /*user_name=*/""); + app_list::GetJustificationString( + FileSuggestionJustificationType::kViewed, + result.info.last_accessed, + /*user_name=*/""); final_results.emplace_back( - FileSuggestionType::kLocalFile, result.path, justification_string, + FileSuggestionType::kLocalFile, result.path, + FileSuggestionJustificationType::kViewed, justification_string, /*timestamp=*/result.info.last_accessed, /*secondary_timestamp=*/std::nullopt, result.score); } else { std::optional<std::u16string> justification_string = app_list::GetJustificationString( - app_list::JustificationType::kModifiedByCurrentUser, + FileSuggestionJustificationType::kModifiedByCurrentUser, result.info.last_modified, /*user_name=*/""); final_results.emplace_back( - FileSuggestionType::kLocalFile, result.path, justification_string, + FileSuggestionType::kLocalFile, result.path, + FileSuggestionJustificationType::kModifiedByCurrentUser, + justification_string, /*timestamp=*/result.info.last_modified, /*secondary_timestamp=*/std::nullopt, result.score); }
diff --git a/chrome/browser/ash/login/app_mode/test/auto_launched_kiosk_browsertest.cc b/chrome/browser/ash/login/app_mode/test/auto_launched_kiosk_browsertest.cc index c046740..4f5f840 100644 --- a/chrome/browser/ash/login/app_mode/test/auto_launched_kiosk_browsertest.cc +++ b/chrome/browser/ash/login/app_mode/test/auto_launched_kiosk_browsertest.cc
@@ -19,6 +19,7 @@ #include "chrome/browser/ash/login/app_mode/kiosk_launch_controller.h" #include "chrome/browser/ash/login/app_mode/test/kiosk_apps_mixin.h" #include "chrome/browser/ash/login/app_mode/test/kiosk_base_test.h" +#include "chrome/browser/ash/login/app_mode/test/kiosk_test_helpers.h" #include "chrome/browser/ash/login/test/device_state_mixin.h" #include "chrome/browser/ash/login/test/local_state_mixin.h" #include "chrome/browser/ash/login/test/login_manager_mixin.h" @@ -126,16 +127,10 @@ std::unique_ptr<ScopedDevicePolicyUpdate> device_policy_update = device_state_.RequestDevicePolicyUpdate(); - em::DeviceLocalAccountsProto* const device_local_accounts = - device_policy_update->policy_payload()->mutable_device_local_accounts(); - device_local_accounts->set_auto_login_id( - KioskAppsMixin::kEnterpriseKioskAccountId); - em::DeviceLocalAccountInfoProto* const account = - device_local_accounts->add_account(); - account->set_account_id(KioskAppsMixin::kEnterpriseKioskAccountId); - account->set_type(em::DeviceLocalAccountInfoProto::ACCOUNT_TYPE_KIOSK_APP); - account->mutable_kiosk_app()->set_app_id(GetTestAppId()); + KioskAppsMixin::AppendAutoLaunchKioskAccount( + device_policy_update->policy_payload(), GetTestAppId(), + KioskAppsMixin::kEnterpriseKioskAccountId); device_policy_update.reset(); @@ -320,7 +315,7 @@ // Used to test app auto-launch flow when the launched app is not kiosk enabled. class AutoLaunchedNonKioskEnabledAppTest : public AutoLaunchedKioskTest { public: - AutoLaunchedNonKioskEnabledAppTest() {} + AutoLaunchedNonKioskEnabledAppTest() = default; AutoLaunchedNonKioskEnabledAppTest( const AutoLaunchedNonKioskEnabledAppTest&) = delete; @@ -355,7 +350,7 @@ // Used to test management API availability in kiosk sessions. class ManagementApiKioskTest : public AutoLaunchedKioskTest { public: - ManagementApiKioskTest() {} + ManagementApiKioskTest() = default; ManagementApiKioskTest(const ManagementApiKioskTest&) = delete; ManagementApiKioskTest& operator=(const ManagementApiKioskTest&) = delete;
diff --git a/chrome/browser/ash/login/app_mode/test/kiosk_apps_mixin.cc b/chrome/browser/ash/login/app_mode/test/kiosk_apps_mixin.cc index a88b606..37cf0984 100644 --- a/chrome/browser/ash/login/app_mode/test/kiosk_apps_mixin.cc +++ b/chrome/browser/ash/login/app_mode/test/kiosk_apps_mixin.cc
@@ -12,6 +12,11 @@ namespace ash { +namespace { +using enterprise_management::DeviceLocalAccountInfoProto; +using enterprise_management::DeviceLocalAccountsProto; +} // namespace + // This is a simple test app that creates an app window and immediately closes // it again. Webstore data json is in // chrome/test/data/chromeos/app_mode/webstore/inlineinstall/ @@ -33,46 +38,44 @@ // static void KioskAppsMixin::AppendKioskAccount( - enterprise_management::ChromeDeviceSettingsProto* policy_payload) { - enterprise_management::DeviceLocalAccountsProto* const device_local_accounts = - policy_payload->mutable_device_local_accounts(); + enterprise_management::ChromeDeviceSettingsProto* policy_payload, + std::string_view app_id, + std::string_view account_id) { + DeviceLocalAccountInfoProto* account = + policy_payload->mutable_device_local_accounts()->add_account(); - enterprise_management::DeviceLocalAccountInfoProto* const account = - device_local_accounts->add_account(); - account->set_account_id(KioskAppsMixin::kEnterpriseKioskAccountId); - account->set_type(enterprise_management::DeviceLocalAccountInfoProto:: - ACCOUNT_TYPE_KIOSK_APP); - account->mutable_kiosk_app()->set_app_id(KioskAppsMixin::kKioskAppId); + account->set_account_id(std::string(account_id)); + account->set_type(DeviceLocalAccountInfoProto::ACCOUNT_TYPE_KIOSK_APP); + account->mutable_kiosk_app()->set_app_id(std::string(app_id)); } // static void KioskAppsMixin::AppendWebKioskAccount( - enterprise_management::ChromeDeviceSettingsProto* policy_payload) { - enterprise_management::DeviceLocalAccountsProto* const device_local_accounts = - policy_payload->mutable_device_local_accounts(); + enterprise_management::ChromeDeviceSettingsProto* policy_payload, + std::string_view url, + std::string_view account_id) { + DeviceLocalAccountInfoProto* account = + policy_payload->mutable_device_local_accounts()->add_account(); - enterprise_management::DeviceLocalAccountInfoProto* const account = - device_local_accounts->add_account(); - account->set_account_id(KioskAppsMixin::kEnterpriseWebKioskAccountId); - account->set_type(enterprise_management::DeviceLocalAccountInfoProto:: - ACCOUNT_TYPE_WEB_KIOSK_APP); - account->mutable_web_kiosk_app()->set_url("https://example.com"); + account->set_account_id(std::string(account_id)); + account->set_type(DeviceLocalAccountInfoProto::ACCOUNT_TYPE_WEB_KIOSK_APP); + account->mutable_web_kiosk_app()->set_url(std::string(url)); } // static void KioskAppsMixin::AppendAutoLaunchKioskAccount( - enterprise_management::ChromeDeviceSettingsProto* policy_payload) { - enterprise_management::DeviceLocalAccountsProto* const device_local_accounts = - policy_payload->mutable_device_local_accounts(); + enterprise_management::ChromeDeviceSettingsProto* policy_payload, + std::string_view app_id, + std::string_view account_id) { + DeviceLocalAccountInfoProto* account = + policy_payload->mutable_device_local_accounts()->add_account(); - enterprise_management::DeviceLocalAccountInfoProto* const account = - device_local_accounts->add_account(); - account->set_account_id(KioskAppsMixin::kEnterpriseKioskAccountId); - account->set_type(enterprise_management::DeviceLocalAccountInfoProto:: - ACCOUNT_TYPE_KIOSK_APP); - account->mutable_kiosk_app()->set_app_id(KioskAppsMixin::kKioskAppId); - device_local_accounts->set_auto_login_id( - KioskAppsMixin::kEnterpriseKioskAccountId); + account->set_account_id(std::string(account_id)); + account->set_type(DeviceLocalAccountInfoProto::ACCOUNT_TYPE_KIOSK_APP); + account->mutable_kiosk_app()->set_app_id(std::string(app_id)); + + policy_payload->mutable_device_local_accounts()->set_auto_login_id( + std::string(account_id)); } KioskAppsMixin::KioskAppsMixin(InProcessBrowserTestMixinHost* host,
diff --git a/chrome/browser/ash/login/app_mode/test/kiosk_apps_mixin.h b/chrome/browser/ash/login/app_mode/test/kiosk_apps_mixin.h index 2364b34a..0152b29 100644 --- a/chrome/browser/ash/login/app_mode/test/kiosk_apps_mixin.h +++ b/chrome/browser/ash/login/app_mode/test/kiosk_apps_mixin.h
@@ -5,6 +5,8 @@ #ifndef CHROME_BROWSER_ASH_LOGIN_APP_MODE_TEST_KIOSK_APPS_MIXIN_H_ #define CHROME_BROWSER_ASH_LOGIN_APP_MODE_TEST_KIOSK_APPS_MIXIN_H_ +#include <string_view> + #include "base/memory/raw_ptr.h" #include "chrome/browser/ash/app_mode/fake_cws.h" #include "chrome/test/base/mixin_based_in_process_browser_test.h" @@ -20,11 +22,17 @@ static const char kEnterpriseWebKioskAccountId[]; static void WaitForAppsButton(); static void AppendKioskAccount( - enterprise_management::ChromeDeviceSettingsProto* policy_payload); - static void AppendWebKioskAccount( - enterprise_management::ChromeDeviceSettingsProto* policy_payload); + enterprise_management::ChromeDeviceSettingsProto* policy_payload, + std::string_view app_id = kKioskAppId, + std::string_view account_id = kEnterpriseKioskAccountId); static void AppendAutoLaunchKioskAccount( - enterprise_management::ChromeDeviceSettingsProto* policy_payload); + enterprise_management::ChromeDeviceSettingsProto* policy_payload, + std::string_view app_id = kKioskAppId, + std::string_view account_id = kEnterpriseKioskAccountId); + static void AppendWebKioskAccount( + enterprise_management::ChromeDeviceSettingsProto* policy_payload, + std::string_view url = "https://example.com", + std::string_view account_id = kEnterpriseWebKioskAccountId); KioskAppsMixin(InProcessBrowserTestMixinHost* host, net::EmbeddedTestServer* embedded_test_server);
diff --git a/chrome/browser/ash/login/enrollment/enrollment_embedded_policy_server_browsertest.cc b/chrome/browser/ash/login/enrollment/enrollment_embedded_policy_server_browsertest.cc index f3944dc6..ef33478 100644 --- a/chrome/browser/ash/login/enrollment/enrollment_embedded_policy_server_browsertest.cc +++ b/chrome/browser/ash/login/enrollment/enrollment_embedded_policy_server_browsertest.cc
@@ -378,18 +378,15 @@ }; // Requesting state keys hangs forever, but that should not matter because we're -// running on reven. -class EnrollmentOnRevenWithNoStateKeysResponse - : public EnrollmentEmbeddedPolicyServerBase { +// running on a "no chrome" device. +class EnrollmentOnNoChrome : public EnrollmentEmbeddedPolicyServerBase { public: - EnrollmentOnRevenWithNoStateKeysResponse() = default; + EnrollmentOnNoChrome() = default; - EnrollmentOnRevenWithNoStateKeysResponse( - const EnrollmentOnRevenWithNoStateKeysResponse&) = delete; - EnrollmentOnRevenWithNoStateKeysResponse& operator=( - const EnrollmentOnRevenWithNoStateKeysResponse&) = delete; + EnrollmentOnNoChrome(const EnrollmentOnNoChrome&) = delete; + EnrollmentOnNoChrome& operator=(const EnrollmentOnNoChrome&) = delete; - ~EnrollmentOnRevenWithNoStateKeysResponse() override = default; + ~EnrollmentOnNoChrome() override = default; // EnrollmentEmbeddedPolicyServerBase: void SetUpInProcessBrowserTestFixture() override { @@ -397,24 +394,18 @@ // Session manager client is initialized by DeviceStateMixin. FakeSessionManagerClient::Get()->set_state_keys_handling( FakeSessionManagerClient::ServerBackedStateKeysHandling::kNoResponse); - // reven devices are also marked 'nochrome' which is important because it - // disables Forced Re-Enrollment (FRE). If FRE is enabled, state keys are - // required. + // Devices that are marked 'nochrome' do not have Forced Re-Enrollment (FRE) + // enabled. If FRE is not enabled, then we don't request and obtain state + // keys. fake_statistics_provider_.SetMachineStatistic( system::kFirmwareTypeKey, system::kFirmwareTypeValueNonchrome); // When using a fresh ScopedFakeStatisticsProvider we also need to configure - // a few entries (serial number, machine model). - // ConfigureFakeStatisticsForZeroTouch does that for us. + // a few entries (serial number, machine model). This can be done for us by + // ConfigureFakeStatisticsForZeroTouch(). policy_server_.ConfigureFakeStatisticsForZeroTouch( &fake_statistics_provider_); } - void SetUpCommandLine(base::CommandLine* command_line) override { - EnrollmentEmbeddedPolicyServerBase::SetUpCommandLine(command_line); - - command_line->AppendSwitch(switches::kRevenBranding); - } - private: system::ScopedFakeStatisticsProvider fake_statistics_provider_; }; @@ -443,9 +434,8 @@ // The test case is the same as // EnrollmentEmbeddedPolicyServerBase.ManualEnrollment but the environment is -// different (simulate reven board, simulate state keys not being available). -IN_PROC_BROWSER_TEST_F(EnrollmentOnRevenWithNoStateKeysResponse, - ManualEnrollment) { +// different (simulates state keys not being available). +IN_PROC_BROWSER_TEST_F(EnrollmentOnNoChrome, ManualEnrollment) { TriggerEnrollmentAndSignInSuccessfully(); enrollment_ui_.WaitForStep(test::ui::kEnrollmentStepSuccess); @@ -454,6 +444,45 @@ EXPECT_TRUE(InstallAttributes::Get()->IsCloudManaged()); } +#if BUILDFLAG(GOOGLE_CHROME_BRANDING) +// Only run Flex tests on Google branded browsers, since FRE is not enabled +// otherwise, and state keys are not requested unless FRE is enabled. +// We prefer this to forcing FRE to always be on, because that code path +// short circuits the code that will actually run on devices. + +// Enrollment on Flex. Flex devices are "no chrome" but support some features +// like FRE that other "no chrome" devices don't. +class EnrollmentOnFlex : public EnrollmentOnNoChrome { + public: + EnrollmentOnFlex() = default; + + EnrollmentOnFlex(const EnrollmentOnFlex&) = delete; + EnrollmentOnFlex& operator=(const EnrollmentOnFlex&) = delete; + + ~EnrollmentOnFlex() override = default; + + void SetUpCommandLine(base::CommandLine* command_line) override { + EnrollmentEmbeddedPolicyServerBase::SetUpCommandLine(command_line); + command_line->AppendSwitch(switches::kRevenBranding); + command_line->AppendSwitchASCII( + switches::kEnterpriseEnableForcedReEnrollmentOnFlex, + policy::AutoEnrollmentTypeChecker::kForcedReEnrollmentAlways); + } +}; + +// Simple manual enrollment on Flex. +IN_PROC_BROWSER_TEST_F(EnrollmentOnFlex, ManualEnrollment) { + TriggerEnrollmentAndSignInSuccessfully(); + + enrollment_ui_.WaitForStep(test::ui::kEnrollmentStepSuccess); + test::OobeJS().ExpectTrue("Oobe.isEnrollmentSuccessfulForTest()"); + EXPECT_TRUE(StartupUtils::IsDeviceRegistered()); + EXPECT_TRUE(InstallAttributes::Get()->IsCloudManaged()); +} + +#endif // GOOGLE_CHROME_BRANDING + +// The test case is the same as // Device policy blocks dev mode and this is not prohibited by a command-line // flag. IN_PROC_BROWSER_TEST_F(EnrollmentEmbeddedPolicyServerBase,
diff --git a/chrome/browser/ash/login/lock/screen_locker.cc b/chrome/browser/ash/login/lock/screen_locker.cc index f98ef698..2e7ec4e0 100644 --- a/chrome/browser/ash/login/lock/screen_locker.cc +++ b/chrome/browser/ash/login/lock/screen_locker.cc
@@ -564,8 +564,9 @@ UserAddingScreen::Get()->Cancel(); return; } - if (g_screen_lock_observer->session_started() && - user_manager::UserManager::Get()->CanCurrentUserLock()) { + auto* active_user = user_manager::UserManager::Get()->GetActiveUser(); + if (g_screen_lock_observer->session_started() && active_user && + active_user->CanLock()) { ScreenLocker::Show(); } else { // If the current user's session cannot be locked or the user has not
diff --git a/chrome/browser/ash/login/session/chrome_session_manager.cc b/chrome/browser/ash/login/session/chrome_session_manager.cc index 9db7fa7..f1ce239 100644 --- a/chrome/browser/ash/login/session/chrome_session_manager.cc +++ b/chrome/browser/ash/login/session/chrome_session_manager.cc
@@ -13,6 +13,7 @@ #include "ash/constants/ash_features.h" #include "ash/constants/ash_switches.h" #include "ash/webui/shimless_rma/shimless_rma.h" +#include "base/check_deref.h" #include "base/command_line.h" #include "base/functional/bind.h" #include "base/functional/callback.h" @@ -21,6 +22,7 @@ #include "chrome/browser/ash/account_manager/account_manager_util.h" #include "chrome/browser/ash/app_list/app_list_client_impl.h" #include "chrome/browser/ash/app_mode/app_launch_utils.h" +#include "chrome/browser/ash/app_mode/kiosk_controller.h" #include "chrome/browser/ash/app_mode/kiosk_cryptohome_remover.h" #include "chrome/browser/ash/boot_times_recorder.h" #include "chrome/browser/ash/login/chrome_restart_request.h" @@ -215,8 +217,9 @@ } if (base::FeatureList::IsEnabled(features::kEolWarningNotifications) && - !user_profile->GetProfilePolicyConnector()->IsManaged()) + !user_profile->GetProfilePolicyConnector()->IsManaged()) { UserSessionManager::GetInstance()->CheckEolInfo(user_profile); + } UserSessionManager::GetInstance()->ShowNotificationsIfNeeded(user_profile); UserSessionManager::GetInstance()->PerformPostBrowserLaunchOOBEActions( @@ -304,10 +307,11 @@ const base::CommandLine& parsed_command_line, Profile* profile, bool is_running_test) { + auto& local_state = CHECK_DEREF(g_browser_process->local_state()); // If a forced powerwash was triggered and no confirmation from the user is // necessary, we trigger the device wipe here before the user can log in again // and return immediately because there is no need to show the login screen. - if (g_browser_process->local_state()->GetBoolean(prefs::kForceFactoryReset)) { + if (local_state.GetBoolean(prefs::kForceFactoryReset)) { SessionManagerClient::Get()->StartDeviceWipe(base::DoNothing()); return; } @@ -360,30 +364,26 @@ const user_manager::CryptohomeId cryptohome_id( parsed_command_line.GetSwitchValueASCII(switches::kLoginUser)); - user_manager::KnownUser known_user(g_browser_process->local_state()); + user_manager::KnownUser known_user(&local_state); const AccountId login_account_id( known_user.GetAccountIdByCryptohomeId(cryptohome_id)); KioskCryptohomeRemover::RemoveObsoleteCryptohomes(); - if (ShouldAutoLaunchKioskApp(parsed_command_line, - g_browser_process->local_state())) { + if (ShouldAutoLaunchKioskApp(parsed_command_line, local_state)) { VLOG(1) << "Starting Chrome with kiosk auto launch."; StartKioskSession(); - return; - } - - if (parsed_command_line.HasSwitch(switches::kLoginManager)) { + } else if (parsed_command_line.HasSwitch(switches::kLoginManager)) { oobe_configuration_->CheckConfiguration(); - if (is_running_test && !force_login_screen_in_test) + if (is_running_test && !force_login_screen_in_test) { return; + } VLOG(1) << "Starting Chrome with login/oobe screen."; StartLoginOobeSession(); - return; + } else { + VLOG(1) << "Starting Chrome with a user session."; + StartUserSession(profile, login_account_id.GetUserEmail()); } - - VLOG(1) << "Starting Chrome with a user session."; - StartUserSession(profile, login_account_id.GetUserEmail()); } void ChromeSessionManager::SessionStarted() { @@ -392,8 +392,9 @@ // Notifies UserManager so that it can update login state. user_manager::UserManager* user_manager = user_manager::UserManager::Get(); - if (user_manager) + if (user_manager) { user_manager->OnSessionStarted(); + } } void ChromeSessionManager::NotifyUserLoggedIn(const AccountId& user_account_id,
diff --git a/chrome/browser/ash/login/ui/user_adding_screen_browsertest.cc b/chrome/browser/ash/login/ui/user_adding_screen_browsertest.cc index f8a4d78..3da2299 100644 --- a/chrome/browser/ash/login/ui/user_adding_screen_browsertest.cc +++ b/chrome/browser/ash/login/ui/user_adding_screen_browsertest.cc
@@ -68,10 +68,6 @@ finished_ = false; } - void SetUserCanLock(user_manager::User* user, bool can_lock) { - user->set_can_lock(can_lock); - } - int user_adding_started() { return user_adding_started_; } int user_adding_finished() { return user_adding_finished_; } @@ -251,12 +247,12 @@ EXPECT_EQ(users_in_session_order_[i], unlock_users[i]->GetAccountId()); // Now one of the users is unable to unlock. - SetUserCanLock(user_manager->GetLoggedInUsers()[2], false); + prefs3->SetBoolean(ash::prefs::kAllowScreenLock, false); unlock_users = user_manager->GetUnlockUsers(); ASSERT_EQ(unlock_users.size(), 2u); for (int i = 0; i < 2; ++i) EXPECT_EQ(users_in_session_order_[i], unlock_users[i]->GetAccountId()); - SetUserCanLock(user_manager->GetLoggedInUsers()[2], true); + prefs3->SetBoolean(ash::prefs::kAllowScreenLock, true); // Now one of the users has not-allowed policy. // In this scenario this user is not allowed in multi-profile session but
diff --git a/chrome/browser/ash/login/users/chrome_user_manager_impl.cc b/chrome/browser/ash/login/users/chrome_user_manager_impl.cc index 07396f0..014fca7f4 100644 --- a/chrome/browser/ash/login/users/chrome_user_manager_impl.cc +++ b/chrome/browser/ash/login/users/chrome_user_manager_impl.cc
@@ -157,16 +157,12 @@ } bool GetUserLockAttributes(const user_manager::User* user, - bool* can_lock, MultiUserSignInPolicy* policy) { Profile* const profile = ProfileHelper::Get()->GetProfileByUser(user); if (!profile) { return false; } PrefService* const prefs = profile->GetPrefs(); - if (can_lock) { - *can_lock = user->can_lock() && prefs->GetBoolean(prefs::kAllowScreenLock); - } if (policy) { *policy = ParseMultiUserSignInPolicyPref( prefs->GetString(prefs::kMultiProfileUserBehaviorPref)) @@ -481,10 +477,9 @@ return user_manager::UserList(); } - bool can_primary_lock = false; MultiUserSignInPolicy primary_policy; - if (!GetUserLockAttributes(GetPrimaryUser(), &can_primary_lock, - &primary_policy)) { + auto* primary_user = GetPrimaryUser(); + if (!GetUserLockAttributes(primary_user, &primary_policy)) { // Locking is not allowed until the primary user profile is created. return user_manager::UserList(); } @@ -492,25 +487,24 @@ user_manager::UserList unlock_users; // Specific case: only one logged in user or - // primary user has primary-only multi-profile policy. + // primary user has primary-only multi-user policy. if (logged_in_users.size() == 1 || primary_policy == MultiUserSignInPolicy::kPrimaryOnly) { - if (can_primary_lock) { + if (primary_user->CanLock()) { unlock_users.push_back(primary_user_.get()); } } else { - // Fill list of potential unlock users based on multi-profile policy state. + // Fill list of potential unlock users based on multi-user policy state. for (user_manager::User* user : logged_in_users) { - bool can_lock = false; MultiUserSignInPolicy policy; - if (!GetUserLockAttributes(user, &can_lock, &policy)) { + if (!GetUserLockAttributes(user, &policy)) { continue; } - if (policy == MultiUserSignInPolicy::kUnrestricted && can_lock) { + if (policy == MultiUserSignInPolicy::kUnrestricted && user->CanLock()) { unlock_users.push_back(user); } else if (policy == MultiUserSignInPolicy::kPrimaryOnly) { NOTREACHED() - << "Spotted primary-only multi-profile policy for non-primary user"; + << "Spotted primary-only multi-user policy for non-primary user"; } } } @@ -593,17 +587,6 @@ // handled via the kAccountsPrefDeviceLocalAccounts device setting observer. } -bool ChromeUserManagerImpl::CanCurrentUserLock() const { - if (!UserManagerBase::CanCurrentUserLock()) { - return false; - } - bool can_lock = false; - if (!GetUserLockAttributes(active_user_, &can_lock, nullptr)) { - return false; - } - return can_lock; -} - const std::string& ChromeUserManagerImpl::GetApplicationLocale() const { return g_browser_process->GetApplicationLocale(); }
diff --git a/chrome/browser/ash/login/users/chrome_user_manager_impl.h b/chrome/browser/ash/login/users/chrome_user_manager_impl.h index 9fc14f0..74a807b 100644 --- a/chrome/browser/ash/login/users/chrome_user_manager_impl.h +++ b/chrome/browser/ash/login/users/chrome_user_manager_impl.h
@@ -75,7 +75,6 @@ user_manager::User::OAuthTokenStatus oauth_token_status) override; void SaveUserDisplayName(const AccountId& account_id, const std::u16string& display_name) override; - bool CanCurrentUserLock() const override; bool IsGuestSessionAllowed() const override; bool IsGaiaUserAllowed(const user_manager::User& user) const override; bool IsUserAllowed(const user_manager::User& user) const override;
diff --git a/chrome/browser/ash/login/users/fake_chrome_user_manager.cc b/chrome/browser/ash/login/users/fake_chrome_user_manager.cc index a12b31f..d2da4636 100644 --- a/chrome/browser/ash/login/users/fake_chrome_user_manager.cc +++ b/chrome/browser/ash/login/users/fake_chrome_user_manager.cc
@@ -448,10 +448,6 @@ return current_user_ephemeral_; } -bool FakeChromeUserManager::CanCurrentUserLock() const { - return current_user_can_lock_; -} - bool FakeChromeUserManager::IsUserLoggedIn() const { return logged_in_users_.size() > 0; }
diff --git a/chrome/browser/ash/login/users/fake_chrome_user_manager.h b/chrome/browser/ash/login/users/fake_chrome_user_manager.h index b000fe8..8c13f62 100644 --- a/chrome/browser/ash/login/users/fake_chrome_user_manager.h +++ b/chrome/browser/ash/login/users/fake_chrome_user_manager.h
@@ -105,7 +105,6 @@ std::optional<std::string> GetOwnerEmail() override; bool IsCurrentUserCryptohomeDataEphemeral() const override; bool IsCurrentUserNonCryptohomeDataEphemeral() const override; - bool CanCurrentUserLock() const override; bool IsUserLoggedIn() const override; bool IsLoggedInAsUserWithGaiaAccount() const override; bool IsLoggedInAsChildUser() const override; @@ -171,10 +170,6 @@ is_enterprise_managed_ = is_enterprise_managed; } - void set_current_user_can_lock(bool current_user_can_lock) { - current_user_can_lock_ = current_user_can_lock; - } - void set_last_session_active_account_id( const AccountId& last_session_active_account_id) { last_session_active_account_id_ = last_session_active_account_id; @@ -202,9 +197,6 @@ // Whether the device is enterprise managed. bool is_enterprise_managed_ = false; - - // Whether the current user can lock. - bool current_user_can_lock_ = false; }; } // namespace ash
diff --git a/chrome/browser/ash/login/users/user_manager_unittest.cc b/chrome/browser/ash/login/users/user_manager_unittest.cc index 3e6b4f420..0801161 100644 --- a/chrome/browser/ash/login/users/user_manager_unittest.cc +++ b/chrome/browser/ash/login/users/user_manager_unittest.cc
@@ -658,12 +658,12 @@ ash::ProfileHelper::GetProfilePathByUserIdHash(user->username_hash())); // Verify that the user is allowed to lock the screen. - EXPECT_TRUE(user_manager::UserManager::Get()->CanCurrentUserLock()); + EXPECT_TRUE(user_manager::UserManager::Get()->GetActiveUser()->CanLock()); EXPECT_EQ(1U, user_manager::UserManager::Get()->GetUnlockUsers().size()); // The user is not allowed to lock the screen. profile.GetPrefs()->SetBoolean(prefs::kAllowScreenLock, false); - EXPECT_FALSE(user_manager::UserManager::Get()->CanCurrentUserLock()); + EXPECT_FALSE(user_manager::UserManager::Get()->GetActiveUser()->CanLock()); EXPECT_EQ(0U, user_manager::UserManager::Get()->GetUnlockUsers().size()); ResetUserManager();
diff --git a/chrome/browser/ash/policy/core/device_cloud_policy_manager_ash_unittest.cc b/chrome/browser/ash/policy/core/device_cloud_policy_manager_ash_unittest.cc index d0c11af..5d97ae48 100644 --- a/chrome/browser/ash/policy/core/device_cloud_policy_manager_ash_unittest.cc +++ b/chrome/browser/ash/policy/core/device_cloud_policy_manager_ash_unittest.cc
@@ -531,7 +531,12 @@ EXPECT_TRUE(manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); VerifyPolicyPopulated(); - EXPECT_CALL(job_creation_handler_, OnJobCreation).Times(0); + // Trigger a policy refresh - this triggers a policy update. + DeviceManagementService::JobForTesting policy_job; + DeviceManagementService::JobConfiguration::JobType job_type; + EXPECT_CALL(job_creation_handler_, OnJobCreation) + .WillOnce(DoAll(device_management_service_.CaptureJobType(&job_type), + SaveArg<0>(&policy_job))); AllowUninterestingRemoteCommandFetches(); EXPECT_FALSE(manager_->GetManagedSessionService()); @@ -540,9 +545,9 @@ InitDeviceCloudPolicyInitializer(); - // Status uploader for reporting on enrolled devices is only created on - // connect call. - EXPECT_FALSE(manager_->GetStatusUploader()); + // Status uploader for reporting on enrolled devices is created for any + // could managed device. + EXPECT_TRUE(manager_->GetStatusUploader()); // Managed session service and reporters are created when notified by // |DeviceCloudPolicyInitializer| that the policy store is ready. EXPECT_TRUE(manager_->GetManagedSessionService());
diff --git a/chrome/browser/ash/policy/enrollment/device_cloud_policy_initializer.cc b/chrome/browser/ash/policy/enrollment/device_cloud_policy_initializer.cc index 10e49581..befd374 100644 --- a/chrome/browser/ash/policy/enrollment/device_cloud_policy_initializer.cc +++ b/chrome/browser/ash/policy/enrollment/device_cloud_policy_initializer.cc
@@ -7,12 +7,12 @@ #include <memory> #include <utility> -#include "ash/constants/ash_switches.h" #include "base/functional/bind.h" #include "base/logging.h" #include "chrome/browser/ash/policy/core/device_cloud_policy_client_factory_ash.h" #include "chrome/browser/ash/policy/core/device_cloud_policy_manager_ash.h" #include "chrome/browser/ash/policy/core/device_cloud_policy_store_ash.h" +#include "chrome/browser/ash/policy/enrollment/auto_enrollment_type_checker.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/net/system_network_context_manager.h" #include "chrome/common/chrome_content_client.h" @@ -122,15 +122,12 @@ return; } - // Currently reven devices don't support server-backed state keys, but they - // also don't support FRE/AutoRE so don't block initialization of device - // policy on state keys being available on reven. - // TODO(b/208705225): Remove this special case when reven supports state keys. - const bool allow_init_without_state_keys = ash::switches::IsRevenBranding(); - + // Devices that are able to use FRE want to wait for state keys, while others + // can proceed immediately. // TODO(b/181140445): If we had a separate state keys upload request to DM // Server we could drop the `state_keys_broker_->available()` requirement. - if (allow_init_without_state_keys || state_keys_broker_->available()) { + if (state_keys_broker_->available() || + !AutoEnrollmentTypeChecker::IsFREEnabled()) { StartConnection(CreateClient(enterprise_service_)); } }
diff --git a/chrome/browser/ash/policy/enrollment/enrollment_handler.cc b/chrome/browser/ash/policy/enrollment/enrollment_handler.cc index 2d34130..d7e14977 100644 --- a/chrome/browser/ash/policy/enrollment/enrollment_handler.cc +++ b/chrome/browser/ash/policy/enrollment/enrollment_handler.cc
@@ -267,12 +267,10 @@ return; } - // Currently reven devices don't support server-backed state keys, but they - // also don't support FRE/AutoRE so don't block enrollment on the - // availability of state keys. - // TODO(b/208705225): Remove this special case when reven supports state keys. - if (ash::switches::IsRevenBranding()) { - LOG(WARNING) << "Skipping state keys."; + // If the device does not support FRE, it doesn't need state keys. + if (!AutoEnrollmentTypeChecker::IsFREEnabled()) { + LOG(WARNING) + << "Skipping state keys since FRE is not enabled on this device."; HandleStateKeysResult({}); return; }
diff --git a/chrome/browser/ash/policy/handlers/minimum_version_policy_handler_delegate_impl.cc b/chrome/browser/ash/policy/handlers/minimum_version_policy_handler_delegate_impl.cc index 9991890..e174c4b2 100644 --- a/chrome/browser/ash/policy/handlers/minimum_version_policy_handler_delegate_impl.cc +++ b/chrome/browser/ash/policy/handlers/minimum_version_policy_handler_delegate_impl.cc
@@ -4,6 +4,7 @@ #include "chrome/browser/ash/policy/handlers/minimum_version_policy_handler_delegate_impl.h" +#include "base/check_deref.h" #include "base/command_line.h" #include "base/system/sys_info.h" #include "chrome/browser/ash/app_mode/app_launch_utils.h" @@ -26,13 +27,13 @@ namespace policy { MinimumVersionPolicyHandlerDelegateImpl:: - MinimumVersionPolicyHandlerDelegateImpl() {} + MinimumVersionPolicyHandlerDelegateImpl() = default; bool MinimumVersionPolicyHandlerDelegateImpl::IsKioskMode() const { return user_manager::UserManager::IsInitialized() && (ash::ShouldAutoLaunchKioskApp( - *(base::CommandLine::ForCurrentProcess()), - g_browser_process->local_state()) || + CHECK_DEREF(base::CommandLine::ForCurrentProcess()), + CHECK_DEREF(g_browser_process->local_state())) || user_manager::UserManager::Get()->IsLoggedInAsAnyKioskApp()); } @@ -49,11 +50,13 @@ } bool MinimumVersionPolicyHandlerDelegateImpl::IsUserEnterpriseManaged() const { - if (!IsUserLoggedIn()) + if (!IsUserLoggedIn()) { return false; + } Profile* const profile = ProfileManager::GetPrimaryUserProfile(); - if (!profile) + if (!profile) { return false; + } // TODO(https://crbug.com/1048607): Handle the case when |IsUserLoggedIn| // returns true after Auth success but |IsManaged| returns false before user // policy fetched. @@ -88,11 +91,13 @@ void MinimumVersionPolicyHandlerDelegateImpl:: HideUpdateRequiredScreenIfShown() { auto* const wizard_controller = ash::WizardController::default_controller(); - if (!wizard_controller) + if (!wizard_controller) { return; + } auto* screen = wizard_controller->GetScreen<ash::UpdateRequiredScreen>(); - if (screen->is_hidden()) + if (screen->is_hidden()) { return; + } screen->Exit(); }
diff --git a/chrome/browser/autofill/test/BUILD.gn b/chrome/browser/autofill/test/BUILD.gn index c21395f8..ec1bca68 100644 --- a/chrome/browser/autofill/test/BUILD.gn +++ b/chrome/browser/autofill/test/BUILD.gn
@@ -43,6 +43,8 @@ ":jni_headers", "//chrome/browser/profiles/android:java", "//content/public/android:content_java", + "//third_party/android_deps:espresso_java", + "//third_party/hamcrest:hamcrest_java", "//third_party/jni_zero:jni_zero_java", "//url:gurl_java", ]
diff --git a/chrome/browser/autofill/test/android/java/src/org/chromium/chrome/browser/autofill/AutofillTestHelper.java b/chrome/browser/autofill/test/android/java/src/org/chromium/chrome/browser/autofill/AutofillTestHelper.java index f77d2201..a5733eb 100644 --- a/chrome/browser/autofill/test/android/java/src/org/chromium/chrome/browser/autofill/AutofillTestHelper.java +++ b/chrome/browser/autofill/test/android/java/src/org/chromium/chrome/browser/autofill/AutofillTestHelper.java
@@ -4,6 +4,8 @@ package org.chromium.chrome.browser.autofill; +import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed; + import static org.chromium.content_public.browser.test.util.TestThreadUtils.runOnUiThreadBlocking; import static org.chromium.content_public.browser.test.util.TestThreadUtils.runOnUiThreadBlockingNoException; @@ -12,6 +14,12 @@ import android.view.MotionEvent; import android.view.View; +import androidx.test.espresso.PerformException; +import androidx.test.espresso.UiController; +import androidx.test.espresso.ViewAction; +import androidx.test.espresso.util.HumanReadables; + +import org.hamcrest.Matcher; import org.jni_zero.JNINamespace; import org.jni_zero.NativeMethods; @@ -24,6 +32,7 @@ import org.chromium.components.autofill.SubKeyRequester; import org.chromium.components.autofill.VirtualCardEnrollmentState; import org.chromium.content_public.browser.WebContents; +import org.chromium.content_public.browser.test.util.TouchCommon; import org.chromium.url.GURL; import java.util.Calendar; @@ -467,26 +476,59 @@ AutofillTestHelperJni.get().disableThresholdForCurrentlyShownAutofillPopup(webContents); } + // Creates an action which dispatches 2 motion events to the target view: + // MotionEvent.ACTION_DOWN and MotionEvent.ACTION_UP. + public static ViewAction createClickActionWithFlags(int flags) { + return new ViewAction() { + @Override + public Matcher<View> getConstraints() { + return isDisplayed(); + } + + @Override + public String getDescription() { + return "simulate click through another UI surface"; + } + + @Override + public void perform(UiController uiController, View view) { + final boolean clicked = AutofillTestHelper.singleClickView(view, flags); + if (!clicked) { + throw new PerformException.Builder() + .withActionDescription(this.getDescription()) + .withViewDescription(HumanReadables.describe(view)) + .withCause(new RuntimeException("Couldn't click the view")) + .build(); + } + uiController.loopMainThreadUntilIdle(); + } + }; + } + // Sends click event at the center of the `view` with the provided `flags`. - public static void singleClickView(View view, int flags) { + private static boolean singleClickView(View view, int flags) { int[] windowXY = new int[2]; view.getLocationInWindow(windowXY); windowXY[0] += view.getWidth() / 2; windowXY[1] += view.getHeight() / 2; + long downTime = SystemClock.uptimeMillis(); View rootView = view.getRootView(); - runOnUiThreadBlocking( - () -> { - rootView.dispatchTouchEvent( - getMotionEventWithFlags( - MotionEvent.ACTION_DOWN, flags, windowXY[0], windowXY[1])); - rootView.dispatchTouchEvent( - getMotionEventWithFlags( - MotionEvent.ACTION_UP, flags, windowXY[0], windowXY[1])); - }); + if (!TouchCommon.dispatchTouchEvent( + rootView, + getMotionEventWithFlags( + downTime, MotionEvent.ACTION_DOWN, flags, windowXY[0], windowXY[1]))) { + return false; + } + + return TouchCommon.dispatchTouchEvent( + rootView, + getMotionEventWithFlags( + downTime, MotionEvent.ACTION_UP, flags, windowXY[0], windowXY[1])); } - private static MotionEvent getMotionEventWithFlags(int action, int flags, int x, int y) { + private static MotionEvent getMotionEventWithFlags( + long downTime, int action, int flags, int x, int y) { MotionEvent.PointerProperties props = new MotionEvent.PointerProperties(); props.id = 0; MotionEvent.PointerCoords coords = new MotionEvent.PointerCoords(); @@ -495,7 +537,7 @@ coords.pressure = 1.0f; coords.size = 1.0f; return MotionEvent.obtain( - /* downTime= */ SystemClock.uptimeMillis(), + /* downTime= */ downTime, /* eventTime= */ SystemClock.uptimeMillis(), /* action= */ action, /* pointerCount= */ 1,
diff --git a/chrome/browser/browsing_data/browsing_data_model_browsertest.cc b/chrome/browser/browsing_data/browsing_data_model_browsertest.cc index b5a7d329..c252e4f 100644 --- a/chrome/browser/browsing_data/browsing_data_model_browsertest.cc +++ b/chrome/browser/browsing_data/browsing_data_model_browsertest.cc
@@ -61,6 +61,7 @@ #include "net/extras/shared_dictionary/shared_dictionary_isolation_key.h" #include "net/test/embedded_test_server/embedded_test_server.h" #include "net/test/embedded_test_server/request_handler_util.h" +#include "services/network/public/cpp/cors/cors.h" #include "services/network/public/cpp/features.h" #include "services/network/public/mojom/network_service.mojom.h" #include "services/network/test/trust_token_request_handler.h" @@ -73,6 +74,10 @@ using base::test::FeatureRef; using base::test::FeatureRefAndParams; +using net::test_server::BasicHttpResponse; +using net::test_server::HttpMethod; +using net::test_server::HttpRequest; +using net::test_server::HttpResponse; namespace { @@ -222,10 +227,9 @@ std::string client_metadata_endpoint_url; std::string id_assertion_endpoint_url; std::string login_url; - std::map< - std::string, - base::RepeatingCallback<std::unique_ptr<net::test_server::HttpResponse>( - const net::test_server::HttpRequest&)>> + std::map<std::string, + base::RepeatingCallback<std::unique_ptr<HttpResponse>( + const HttpRequest&)>> servlets; }; @@ -235,8 +239,7 @@ IdpTestServer(const IdpTestServer&) = delete; IdpTestServer& operator=(const IdpTestServer&) = delete; - std::unique_ptr<net::test_server::HttpResponse> HandleRequest( - const net::test_server::HttpRequest& request) { + std::unique_ptr<HttpResponse> HandleRequest(const HttpRequest& request) { // RP files are fetched from the /test base directory. Assume anything // to other paths is directed to the IdP. if (request.relative_url.rfind("/test", 0) == 0) { @@ -251,7 +254,7 @@ EXPECT_EQ(request.headers.at(kIdpForbiddenHeader), "?1"); } - auto response = std::make_unique<net::test_server::BasicHttpResponse>(); + auto response = std::make_unique<BasicHttpResponse>(); if (IsGetRequestWithPath(request, kExpectedConfigPath)) { BuildConfigResponseFromDetails(*response.get(), config_details_); return response; @@ -269,9 +272,9 @@ return nullptr; } - std::unique_ptr<net::test_server::HttpResponse> BuildIdpHeaderResponse( - const net::test_server::HttpRequest& request) { - auto response = std::make_unique<net::test_server::BasicHttpResponse>(); + std::unique_ptr<HttpResponse> BuildIdpHeaderResponse( + const HttpRequest& request) { + auto response = std::make_unique<BasicHttpResponse>(); if (request.relative_url.find("/header/signin") != std::string::npos) { response->AddCustomHeader(kSetLoginHeader, kLoggedInHeaderValue); } else if (request.relative_url.find("/header/signout") != @@ -291,9 +294,8 @@ } private: - void BuildConfigResponseFromDetails( - net::test_server::BasicHttpResponse& response, - const ConfigDetails& details) { + void BuildConfigResponseFromDetails(BasicHttpResponse& response, + const ConfigDetails& details) { std::string content = ConvertToJsonDictionary( {{"accounts_endpoint", details.accounts_endpoint_url}, {"client_metadata_endpoint", details.client_metadata_endpoint_url}, @@ -304,7 +306,7 @@ response.set_content_type(details.content_type); } - void BuildWellKnownResponse(net::test_server::BasicHttpResponse& response) { + void BuildWellKnownResponse(BasicHttpResponse& response) { std::string content = base::StringPrintf("{\"provider_urls\": [\"%s\"]}", kExpectedConfigPath); response.set_code(net::HTTP_OK); @@ -324,7 +326,7 @@ return out; } - bool IsGetRequestWithPath(const net::test_server::HttpRequest& request, + bool IsGetRequestWithPath(const HttpRequest& request, const std::string& expected_path) { return request.method == net::test_server::HttpMethod::METHOD_GET && request.relative_url == expected_path; @@ -344,12 +346,35 @@ "/fedcm/client_metadata_endpoint.json"; std::string id_assertion_endpoint_url = "/fedcm/id_assertion_endpoint.json"; std::string login_url = "/fedcm/login.html"; + std::map<std::string, base::RepeatingCallback<std::unique_ptr<HttpResponse>( + const HttpRequest&)>> + servlets; + servlets[id_assertion_endpoint_url] = base::BindRepeating( + [](const HttpRequest& request) -> std::unique_ptr<HttpResponse> { + EXPECT_EQ(request.method, HttpMethod::METHOD_POST); + EXPECT_EQ(request.has_content, true); + auto response = std::make_unique<BasicHttpResponse>(); + response->set_code(net::HTTP_OK); + response->set_content_type("text/json"); + DCHECK(request.headers.contains("Origin")); + response->AddCustomHeader( + network::cors::header_names::kAccessControlAllowOrigin, + request.headers.at("Origin")); + response->AddCustomHeader( + network::cors::header_names::kAccessControlAllowCredentials, + "true"); + // Standard scopes were used, so no extra permission needed. + // Return a token immediately. + response->set_content(R"({"token": ")" + std::string(kToken) + R"("})"); + return response; + }); return {net::HTTP_OK, kTestContentType, accounts_endpoint_url, client_metadata_endpoint_url, id_assertion_endpoint_url, - login_url}; + login_url, + servlets}; } void RunFedCm(const content::ToRenderFrameHost& adapter,
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index 994bbbf..66b50cf 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc
@@ -7674,10 +7674,8 @@ return true; #if BUILDFLAG(ENABLE_SCREEN_AI_SERVICE) } else if (sandbox_type == sandbox::mojom::Sandbox::kScreenAI) { - // ScreenAI service needs read access to ScreenAI component path, so that it - // would be able to find the latest downloaded version, and load its binary - // and all enclosed model files. - + // ScreenAI service needs read access to ScreenAI component binary path to + // load it. base::FilePath screen_ai_binary_path = screen_ai::ScreenAIInstallState::GetInstance() ->get_component_binary_path(); @@ -7685,11 +7683,8 @@ VLOG(1) << "Screen AI component not found."; return false; } - - CHECK(compiler->SetParameter(sandbox::policy::kParamScreenAiComponentPath, - screen_ai_binary_path.DirName().value())); - - return true; + return compiler->SetParameter(sandbox::policy::kParamScreenAiComponentPath, + screen_ai_binary_path.value()); #endif }
diff --git a/chrome/browser/chromeos/extensions/BUILD.gn b/chrome/browser/chromeos/extensions/BUILD.gn index 256c6c5..59e3d99 100644 --- a/chrome/browser/chromeos/extensions/BUILD.gn +++ b/chrome/browser/chromeos/extensions/BUILD.gn
@@ -5,10 +5,7 @@ assert(is_chromeos) source_set("constants") { - sources = [ - "controlled_pref_mapping.cc", - "controlled_pref_mapping.h", - ] + sources = [ "controlled_pref_mapping.h" ] deps = [ "//base", "//build:chromeos_buildflags",
diff --git a/chrome/browser/chromeos/extensions/controlled_pref_mapping.cc b/chrome/browser/chromeos/extensions/controlled_pref_mapping.cc deleted file mode 100644 index a8e29df..0000000 --- a/chrome/browser/chromeos/extensions/controlled_pref_mapping.cc +++ /dev/null
@@ -1,81 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include <stddef.h> - -#include "build/build_config.h" -#include "build/chromeos_buildflags.h" - -#if BUILDFLAG(IS_CHROMEOS_ASH) -#include "ash/constants/ash_pref_names.h" -#elif BUILDFLAG(IS_CHROMEOS_LACROS) -#include "chrome/common/pref_names.h" -#endif - -namespace chromeos { -namespace prefs { -#if BUILDFLAG(IS_CHROMEOS_ASH) -const char* kAccessibilityFocusHighlightEnabled = - ash::prefs::kAccessibilityFocusHighlightEnabled; -const char* kAccessibilityAutoclickEnabled = - ash::prefs::kAccessibilityAutoclickEnabled; -const char* kAccessibilityCaretHighlightEnabled = - ash::prefs::kAccessibilityCaretHighlightEnabled; -const char* kAccessibilityCursorColorEnabled = - ash::prefs::kAccessibilityCursorColorEnabled; -const char* kAccessibilityCursorHighlightEnabled = - ash::prefs::kAccessibilityCursorHighlightEnabled; -const char* kAccessibilityDictationEnabled = - ash::prefs::kAccessibilityDictationEnabled; -const char* kAccessibilityHighContrastEnabled = - ash::prefs::kAccessibilityHighContrastEnabled; -const char* kAccessibilityLargeCursorEnabled = - ash::prefs::kAccessibilityLargeCursorEnabled; -const char* kAccessibilityScreenMagnifierEnabled = - ash::prefs::kAccessibilityScreenMagnifierEnabled; -const char* kAccessibilitySelectToSpeakEnabled = - ash::prefs::kAccessibilitySelectToSpeakEnabled; -const char* kAccessibilitySpokenFeedbackEnabled = - ash::prefs::kAccessibilitySpokenFeedbackEnabled; -const char* kAccessibilityStickyKeysEnabled = - ash::prefs::kAccessibilityStickyKeysEnabled; -const char* kAccessibilitySwitchAccessEnabled = - ash::prefs::kAccessibilitySwitchAccessEnabled; -const char* kAccessibilityVirtualKeyboardEnabled = - ash::prefs::kAccessibilityVirtualKeyboardEnabled; -const char* kDockedMagnifierEnabled = ash::prefs::kDockedMagnifierEnabled; -#elif BUILDFLAG(IS_CHROMEOS_LACROS) -const char* kAccessibilityFocusHighlightEnabled = - ::prefs::kLacrosAccessibilityFocusHighlightEnabled; -const char* kAccessibilityAutoclickEnabled = - ::prefs::kLacrosAccessibilityAutoclickEnabled; -const char* kAccessibilityCaretHighlightEnabled = - ::prefs::kLacrosAccessibilityCaretHighlightEnabled; -const char* kAccessibilityCursorColorEnabled = - ::prefs::kLacrosAccessibilityCursorColorEnabled; -const char* kAccessibilityCursorHighlightEnabled = - ::prefs::kLacrosAccessibilityCursorHighlightEnabled; -const char* kAccessibilityDictationEnabled = - ::prefs::kLacrosAccessibilityDictationEnabled; -const char* kAccessibilityHighContrastEnabled = - ::prefs::kLacrosAccessibilityHighContrastEnabled; -const char* kAccessibilityLargeCursorEnabled = - ::prefs::kLacrosAccessibilityLargeCursorEnabled; -const char* kAccessibilityScreenMagnifierEnabled = - ::prefs::kLacrosAccessibilityScreenMagnifierEnabled; -const char* kAccessibilitySelectToSpeakEnabled = - ::prefs::kLacrosAccessibilitySelectToSpeakEnabled; -const char* kAccessibilitySpokenFeedbackEnabled = - ::prefs::kLacrosAccessibilitySpokenFeedbackEnabled; -const char* kAccessibilityStickyKeysEnabled = - ::prefs::kLacrosAccessibilityStickyKeysEnabled; -const char* kAccessibilitySwitchAccessEnabled = - ::prefs::kLacrosAccessibilitySwitchAccessEnabled; -const char* kAccessibilityVirtualKeyboardEnabled = - ::prefs::kLacrosAccessibilityVirtualKeyboardEnabled; -const char* kDockedMagnifierEnabled = ::prefs::kLacrosDockedMagnifierEnabled; -#endif - -} // namespace prefs -} // namespace chromeos
diff --git a/chrome/browser/chromeos/extensions/controlled_pref_mapping.h b/chrome/browser/chromeos/extensions/controlled_pref_mapping.h index 133360a..a238b93 100644 --- a/chrome/browser/chromeos/extensions/controlled_pref_mapping.h +++ b/chrome/browser/chromeos/extensions/controlled_pref_mapping.h
@@ -5,10 +5,16 @@ #ifndef CHROME_BROWSER_CHROMEOS_EXTENSIONS_CONTROLLED_PREF_MAPPING_H_ #define CHROME_BROWSER_CHROMEOS_EXTENSIONS_CONTROLLED_PREF_MAPPING_H_ -#include <stddef.h> +#include "build/build_config.h" +#include "build/chromeos_buildflags.h" -namespace chromeos { -namespace prefs { +#if BUILDFLAG(IS_CHROMEOS_ASH) +#include "ash/constants/ash_pref_names.h" +#elif BUILDFLAG(IS_CHROMEOS_LACROS) +#include "chrome/common/pref_names.h" +#endif + +namespace chromeos::prefs { // These constants are used with extension controlled prefs where the underlying // preference being controlled live in ash. In lacros they map to a pref used @@ -17,24 +23,71 @@ // FocusHighlight is special as the feature exists on several platforms. // However, extensions can only set the ash-value. -extern const char* kAccessibilityFocusHighlightEnabled; -extern const char* kAccessibilityAutoclickEnabled; -extern const char* kAccessibilityCaretHighlightEnabled; -extern const char* kAccessibilityCursorColorEnabled; -extern const char* kAccessibilityCursorHighlightEnabled; -extern const char* kAccessibilityDictationEnabled; -extern const char* kAccessibilityHighContrastEnabled; -extern const char* kAccessibilityLargeCursorEnabled; -extern const char* kAccessibilityScreenMagnifierEnabled; -extern const char* kAccessibilitySelectToSpeakEnabled; -extern const char* kAccessibilitySpokenFeedbackEnabled; -extern const char* kAccessibilityStickyKeysEnabled; -extern const char* kAccessibilitySwitchAccessEnabled; -extern const char* kAccessibilityVirtualKeyboardEnabled; -extern const char* kDockedMagnifierEnabled; +#if BUILDFLAG(IS_CHROMEOS_ASH) +inline constexpr const char* kAccessibilityFocusHighlightEnabled = + ash::prefs::kAccessibilityFocusHighlightEnabled; +inline constexpr const char* kAccessibilityAutoclickEnabled = + ash::prefs::kAccessibilityAutoclickEnabled; +inline constexpr const char* kAccessibilityCaretHighlightEnabled = + ash::prefs::kAccessibilityCaretHighlightEnabled; +inline constexpr const char* kAccessibilityCursorColorEnabled = + ash::prefs::kAccessibilityCursorColorEnabled; +inline constexpr const char* kAccessibilityCursorHighlightEnabled = + ash::prefs::kAccessibilityCursorHighlightEnabled; +inline constexpr const char* kAccessibilityDictationEnabled = + ash::prefs::kAccessibilityDictationEnabled; +inline constexpr const char* kAccessibilityHighContrastEnabled = + ash::prefs::kAccessibilityHighContrastEnabled; +inline constexpr const char* kAccessibilityLargeCursorEnabled = + ash::prefs::kAccessibilityLargeCursorEnabled; +inline constexpr const char* kAccessibilityScreenMagnifierEnabled = + ash::prefs::kAccessibilityScreenMagnifierEnabled; +inline constexpr const char* kAccessibilitySelectToSpeakEnabled = + ash::prefs::kAccessibilitySelectToSpeakEnabled; +inline constexpr const char* kAccessibilitySpokenFeedbackEnabled = + ash::prefs::kAccessibilitySpokenFeedbackEnabled; +inline constexpr const char* kAccessibilityStickyKeysEnabled = + ash::prefs::kAccessibilityStickyKeysEnabled; +inline constexpr const char* kAccessibilitySwitchAccessEnabled = + ash::prefs::kAccessibilitySwitchAccessEnabled; +inline constexpr const char* kAccessibilityVirtualKeyboardEnabled = + ash::prefs::kAccessibilityVirtualKeyboardEnabled; +inline constexpr const char* kDockedMagnifierEnabled = + ash::prefs::kDockedMagnifierEnabled; +#elif BUILDFLAG(IS_CHROMEOS_LACROS) +inline constexpr const char* kAccessibilityFocusHighlightEnabled = + ::prefs::kLacrosAccessibilityFocusHighlightEnabled; +inline constexpr const char* kAccessibilityAutoclickEnabled = + ::prefs::kLacrosAccessibilityAutoclickEnabled; +inline constexpr const char* kAccessibilityCaretHighlightEnabled = + ::prefs::kLacrosAccessibilityCaretHighlightEnabled; +inline constexpr const char* kAccessibilityCursorColorEnabled = + ::prefs::kLacrosAccessibilityCursorColorEnabled; +inline constexpr const char* kAccessibilityCursorHighlightEnabled = + ::prefs::kLacrosAccessibilityCursorHighlightEnabled; +inline constexpr const char* kAccessibilityDictationEnabled = + ::prefs::kLacrosAccessibilityDictationEnabled; +inline constexpr const char* kAccessibilityHighContrastEnabled = + ::prefs::kLacrosAccessibilityHighContrastEnabled; +inline constexpr const char* kAccessibilityLargeCursorEnabled = + ::prefs::kLacrosAccessibilityLargeCursorEnabled; +inline constexpr const char* kAccessibilityScreenMagnifierEnabled = + ::prefs::kLacrosAccessibilityScreenMagnifierEnabled; +inline constexpr const char* kAccessibilitySelectToSpeakEnabled = + ::prefs::kLacrosAccessibilitySelectToSpeakEnabled; +inline constexpr const char* kAccessibilitySpokenFeedbackEnabled = + ::prefs::kLacrosAccessibilitySpokenFeedbackEnabled; +inline constexpr const char* kAccessibilityStickyKeysEnabled = + ::prefs::kLacrosAccessibilityStickyKeysEnabled; +inline constexpr const char* kAccessibilitySwitchAccessEnabled = + ::prefs::kLacrosAccessibilitySwitchAccessEnabled; +inline constexpr const char* kAccessibilityVirtualKeyboardEnabled = + ::prefs::kLacrosAccessibilityVirtualKeyboardEnabled; +inline constexpr const char* kDockedMagnifierEnabled = + ::prefs::kLacrosDockedMagnifierEnabled; +#endif -} // namespace prefs -} // namespace chromeos +} // namespace chromeos::prefs #endif // CHROME_BROWSER_CHROMEOS_EXTENSIONS_CONTROLLED_PREF_MAPPING_H_
diff --git a/chrome/browser/chromeos/extensions/login_screen/login/login_api_ash_unittest.cc b/chrome/browser/chromeos/extensions/login_screen/login/login_api_ash_unittest.cc index 76c5fa37..3126f55 100644 --- a/chrome/browser/chromeos/extensions/login_screen/login/login_api_ash_unittest.cc +++ b/chrome/browser/chromeos/extensions/login_screen/login/login_api_ash_unittest.cc
@@ -10,6 +10,7 @@ #include <string> #include <utility> +#include "ash/constants/ash_pref_names.h" #include "base/functional/callback.h" #include "base/functional/callback_helpers.h" #include "base/memory/scoped_refptr.h" @@ -109,22 +110,32 @@ class ScopedTestingProfile { public: ScopedTestingProfile(TestingProfile* profile, - TestingProfileManager* profile_manager) - : profile_(profile), profile_manager_(profile_manager) {} + TestingProfileManager* profile_manager, + const AccountId& account_id) + : profile_(profile), + profile_manager_(profile_manager), + account_id_(account_id) { + user_manager::UserManager::Get()->OnUserProfileCreated(account_id, + profile->GetPrefs()); + } ScopedTestingProfile(const ScopedTestingProfile&) = delete; ScopedTestingProfile& operator=(const ScopedTestingProfile&) = delete; ~ScopedTestingProfile() { - profile_manager_->DeleteTestingProfile(profile_->GetProfileUserName()); + user_manager::UserManager::Get()->OnUserProfileWillBeDestroyed(account_id_); + std::string user_name = profile_->GetProfileUserName(); + profile_ = nullptr; + profile_manager_->DeleteTestingProfile(user_name); } TestingProfile* profile() { return profile_; } private: - const raw_ptr<TestingProfile, DanglingUntriaged> profile_; + raw_ptr<TestingProfile> profile_; const raw_ptr<TestingProfileManager> profile_manager_; + const AccountId account_id_; }; ash::UserContext GetPublicUserContext(const std::string& email) { @@ -190,11 +201,12 @@ std::unique_ptr<ScopedTestingProfile> AddPublicAccountUser( const std::string& email) { - fake_chrome_user_manager_->AddPublicAccountUser( + user_manager::User* user = fake_chrome_user_manager_->AddPublicAccountUser( AccountId::FromUserEmail(email)); TestingProfile* profile = profile_manager()->CreateTestingProfile(email); - return std::make_unique<ScopedTestingProfile>(profile, profile_manager()); + return std::make_unique<ScopedTestingProfile>(profile, profile_manager(), + user->GetAccountId()); } raw_ptr<ash::FakeChromeUserManager, DanglingUntriaged> @@ -350,8 +362,12 @@ ui::UserActivityDetector::Get()->set_now_for_test(now); std::unique_ptr<ScopedTestingProfile> profile = AddPublicAccountUser(kEmail); + profile->profile()->GetPrefs()->SetBoolean( + ash::prefs::kLoginExtensionApiCanLockManagedGuestSession, true); + profile->profile()->GetPrefs()->SetBoolean(ash::prefs::kAllowScreenLock, + true); + fake_chrome_user_manager_->SwitchActiveUser(AccountId::FromUserEmail(kEmail)); - fake_chrome_user_manager_->set_current_user_can_lock(true); session_manager::SessionManager::Get()->SetSessionState( session_manager::SessionState::ACTIVE); @@ -371,8 +387,12 @@ ui::UserActivityDetector::Get()->set_now_for_test(now); std::unique_ptr<ScopedTestingProfile> profile = AddPublicAccountUser(kEmail); + profile->profile()->GetPrefs()->SetBoolean( + ash::prefs::kLoginExtensionApiCanLockManagedGuestSession, true); + profile->profile()->GetPrefs()->SetBoolean(ash::prefs::kAllowScreenLock, + true); + fake_chrome_user_manager_->SwitchActiveUser(AccountId::FromUserEmail(kEmail)); - fake_chrome_user_manager_->set_current_user_can_lock(true); session_manager::SessionManager::Get()->SetSessionState( session_manager::SessionState::ACTIVE); @@ -406,8 +426,12 @@ TEST_F(LoginApiUnittest, LockManagedGuestSessionUserCannotLock) { std::unique_ptr<ScopedTestingProfile> profile = AddPublicAccountUser(kEmail); + profile->profile()->GetPrefs()->SetBoolean( + ash::prefs::kLoginExtensionApiCanLockManagedGuestSession, false); + profile->profile()->GetPrefs()->SetBoolean(ash::prefs::kAllowScreenLock, + false); + fake_chrome_user_manager_->SwitchActiveUser(AccountId::FromUserEmail(kEmail)); - fake_chrome_user_manager_->set_current_user_can_lock(false); ASSERT_EQ( login_api_errors::kNoLockableSession, @@ -417,8 +441,12 @@ TEST_F(LoginApiUnittest, LockManagedGuestSessionSessionNotActive) { std::unique_ptr<ScopedTestingProfile> profile = AddPublicAccountUser(kEmail); + profile->profile()->GetPrefs()->SetBoolean( + ash::prefs::kLoginExtensionApiCanLockManagedGuestSession, true); + profile->profile()->GetPrefs()->SetBoolean(ash::prefs::kAllowScreenLock, + true); + fake_chrome_user_manager_->SwitchActiveUser(AccountId::FromUserEmail(kEmail)); - fake_chrome_user_manager_->set_current_user_can_lock(true); session_manager::SessionManager::Get()->SetSessionState( session_manager::SessionState::LOCKED); @@ -434,8 +462,12 @@ std::unique_ptr<ScopedTestingProfile> scoped_profile = AddPublicAccountUser(kEmail); + scoped_profile->profile()->GetPrefs()->SetBoolean( + ash::prefs::kLoginExtensionApiCanLockManagedGuestSession, true); + scoped_profile->profile()->GetPrefs()->SetBoolean( + ash::prefs::kAllowScreenLock, true); + fake_chrome_user_manager_->SwitchActiveUser(AccountId::FromUserEmail(kEmail)); - fake_chrome_user_manager_->set_current_user_can_lock(true); session_manager::SessionManager::Get()->SetSessionState( session_manager::SessionState::LOCKED); @@ -463,8 +495,11 @@ std::unique_ptr<ScopedTestingProfile> scoped_profile = AddPublicAccountUser(kEmail); + scoped_profile->profile()->GetPrefs()->SetBoolean( + ash::prefs::kLoginExtensionApiCanLockManagedGuestSession, true); + scoped_profile->profile()->GetPrefs()->SetBoolean( + ash::prefs::kAllowScreenLock, true); fake_chrome_user_manager_->SwitchActiveUser(AccountId::FromUserEmail(kEmail)); - fake_chrome_user_manager_->set_current_user_can_lock(true); session_manager::SessionManager::Get()->SetSessionState( session_manager::SessionState::LOCKED); @@ -517,7 +552,11 @@ TEST_F(LoginApiUnittest, UnlockManagedGuestSessionSessionNotLocked) { std::unique_ptr<ScopedTestingProfile> scoped_profile = AddPublicAccountUser(kEmail); - fake_chrome_user_manager_->set_current_user_can_lock(true); + scoped_profile->profile()->GetPrefs()->SetBoolean( + ash::prefs::kLoginExtensionApiCanLockManagedGuestSession, true); + scoped_profile->profile()->GetPrefs()->SetBoolean( + ash::prefs::kAllowScreenLock, true); + fake_chrome_user_manager_->SwitchActiveUser(AccountId::FromUserEmail(kEmail)); ASSERT_EQ(login_api_errors::kSessionIsNotLocked, @@ -529,7 +568,11 @@ TEST_F(LoginApiUnittest, UnlockManagedGuestSessionUnlockInProgress) { std::unique_ptr<ScopedTestingProfile> scoped_profile = AddPublicAccountUser(kEmail); - fake_chrome_user_manager_->set_current_user_can_lock(true); + scoped_profile->profile()->GetPrefs()->SetBoolean( + ash::prefs::kLoginExtensionApiCanLockManagedGuestSession, true); + scoped_profile->profile()->GetPrefs()->SetBoolean( + ash::prefs::kAllowScreenLock, true); + fake_chrome_user_manager_->SwitchActiveUser(AccountId::FromUserEmail(kEmail)); session_manager::SessionManager::Get()->SetSessionState( session_manager::SessionState::LOCKED); @@ -545,7 +588,11 @@ TEST_F(LoginApiUnittest, UnlockManagedGuestSessionAuthenticationFailed) { std::unique_ptr<ScopedTestingProfile> scoped_profile = AddPublicAccountUser(kEmail); - fake_chrome_user_manager_->set_current_user_can_lock(true); + scoped_profile->profile()->GetPrefs()->SetBoolean( + ash::prefs::kLoginExtensionApiCanLockManagedGuestSession, true); + scoped_profile->profile()->GetPrefs()->SetBoolean( + ash::prefs::kAllowScreenLock, true); + fake_chrome_user_manager_->SwitchActiveUser(AccountId::FromUserEmail(kEmail)); session_manager::SessionManager::Get()->SetSessionState( session_manager::SessionState::LOCKED); @@ -579,12 +626,13 @@ protected: std::unique_ptr<ScopedTestingProfile> AddRegularUser( const std::string& email) { - fake_chrome_user_manager_->AddUserWithAffiliation( + auto* user = fake_chrome_user_manager_->AddUserWithAffiliation( AccountId::FromUserEmailGaiaId(email, kGaiaId), /* is_affiliated= */ true); TestingProfile* profile = profile_manager()->CreateTestingProfile(email); - return std::make_unique<ScopedTestingProfile>(profile, profile_manager()); + return std::make_unique<ScopedTestingProfile>(profile, profile_manager(), + user->GetAccountId()); } }; @@ -655,8 +703,12 @@ ui::UserActivityDetector::Get()->set_now_for_test(now); std::unique_ptr<ScopedTestingProfile> profile = AddRegularUser(kEmail); + profile->profile()->GetPrefs()->SetBoolean( + ash::prefs::kLoginExtensionApiCanLockManagedGuestSession, true); + profile->profile()->GetPrefs()->SetBoolean(ash::prefs::kAllowScreenLock, + true); + fake_chrome_user_manager_->SwitchActiveUser(AccountId::FromUserEmail(kEmail)); - fake_chrome_user_manager_->set_current_user_can_lock(true); session_manager::SessionManager::Get()->SetSessionState( session_manager::SessionState::ACTIVE); @@ -674,8 +726,12 @@ // session is not active for regular user. TEST_F(LoginApiUserSessionUnittest, LockUserSessionSessionNotActive) { std::unique_ptr<ScopedTestingProfile> profile = AddRegularUser(kEmail); + profile->profile()->GetPrefs()->SetBoolean( + ash::prefs::kLoginExtensionApiCanLockManagedGuestSession, true); + profile->profile()->GetPrefs()->SetBoolean(ash::prefs::kAllowScreenLock, + true); + fake_chrome_user_manager_->SwitchActiveUser(AccountId::FromUserEmail(kEmail)); - fake_chrome_user_manager_->set_current_user_can_lock(true); session_manager::SessionManager::Get()->SetSessionState( session_manager::SessionState::LOCKED); @@ -691,8 +747,12 @@ ui::UserActivityDetector::Get()->set_now_for_test(now); std::unique_ptr<ScopedTestingProfile> scoped_profile = AddRegularUser(kEmail); + scoped_profile->profile()->GetPrefs()->SetBoolean( + ash::prefs::kLoginExtensionApiCanLockManagedGuestSession, true); + scoped_profile->profile()->GetPrefs()->SetBoolean( + ash::prefs::kAllowScreenLock, true); + fake_chrome_user_manager_->SwitchActiveUser(AccountId::FromUserEmail(kEmail)); - fake_chrome_user_manager_->set_current_user_can_lock(true); session_manager::SessionManager::Get()->SetSessionState( session_manager::SessionState::LOCKED); @@ -717,7 +777,11 @@ // user session is not locked for regular user. TEST_F(LoginApiUserSessionUnittest, UnlockUserSessionSessionNotLocked) { std::unique_ptr<ScopedTestingProfile> scoped_profile = AddRegularUser(kEmail); - fake_chrome_user_manager_->set_current_user_can_lock(true); + scoped_profile->profile()->GetPrefs()->SetBoolean( + ash::prefs::kLoginExtensionApiCanLockManagedGuestSession, true); + scoped_profile->profile()->GetPrefs()->SetBoolean( + ash::prefs::kAllowScreenLock, true); + fake_chrome_user_manager_->SwitchActiveUser(AccountId::FromUserEmail(kEmail)); auto function = base::MakeRefCounted<LoginUnlockCurrentSessionFunction>(); @@ -729,7 +793,11 @@ // unlock is already in progress for regular user. TEST_F(LoginApiUserSessionUnittest, UnlockUserSessionUnlockInProgress) { std::unique_ptr<ScopedTestingProfile> scoped_profile = AddRegularUser(kEmail); - fake_chrome_user_manager_->set_current_user_can_lock(true); + scoped_profile->profile()->GetPrefs()->SetBoolean( + ash::prefs::kLoginExtensionApiCanLockManagedGuestSession, true); + scoped_profile->profile()->GetPrefs()->SetBoolean( + ash::prefs::kAllowScreenLock, true); + fake_chrome_user_manager_->SwitchActiveUser(AccountId::FromUserEmail(kEmail)); session_manager::SessionManager::Get()->SetSessionState( session_manager::SessionState::LOCKED); @@ -745,7 +813,11 @@ // on failed authentication for regular user. TEST_F(LoginApiUserSessionUnittest, UnlockUserSessionAuthenticationFailed) { std::unique_ptr<ScopedTestingProfile> scoped_profile = AddRegularUser(kEmail); - fake_chrome_user_manager_->set_current_user_can_lock(true); + scoped_profile->profile()->GetPrefs()->SetBoolean( + ash::prefs::kLoginExtensionApiCanLockManagedGuestSession, true); + scoped_profile->profile()->GetPrefs()->SetBoolean( + ash::prefs::kAllowScreenLock, true); + fake_chrome_user_manager_->SwitchActiveUser(AccountId::FromUserEmail(kEmail)); session_manager::SessionManager::Get()->SetSessionState( session_manager::SessionState::LOCKED); @@ -845,7 +917,11 @@ base::MakeRefCounted<LoginLaunchSharedManagedGuestSessionFunction>(), "[\"" + password + "\"]"); - fake_chrome_user_manager_->set_current_user_can_lock(true); + testing_profile_->profile()->GetPrefs()->SetBoolean( + ash::prefs::kLoginExtensionApiCanLockManagedGuestSession, true); + testing_profile_->profile()->GetPrefs()->SetBoolean( + ash::prefs::kAllowScreenLock, true); + fake_chrome_user_manager_->SwitchActiveUser( AccountId::FromUserEmail(kEmail)); @@ -971,7 +1047,11 @@ TEST_F(LoginApiSharedSessionUnittest, UnlockSharedSessionNotLocked) { std::unique_ptr<ScopedTestingProfile> scoped_profile = AddPublicAccountUser(kEmail); - fake_chrome_user_manager_->set_current_user_can_lock(true); + scoped_profile->profile()->GetPrefs()->SetBoolean( + ash::prefs::kLoginExtensionApiCanLockManagedGuestSession, true); + scoped_profile->profile()->GetPrefs()->SetBoolean( + ash::prefs::kAllowScreenLock, true); + ASSERT_EQ(login_api_errors::kSessionIsNotLocked, RunFunctionAndReturnError( base::MakeRefCounted<LoginUnlockSharedSessionFunction>(), @@ -983,7 +1063,11 @@ TEST_F(LoginApiSharedSessionUnittest, UnlockSharedSessionNoSharedMGS) { std::unique_ptr<ScopedTestingProfile> scoped_profile = AddPublicAccountUser(kEmail); - fake_chrome_user_manager_->set_current_user_can_lock(true); + scoped_profile->profile()->GetPrefs()->SetBoolean( + ash::prefs::kLoginExtensionApiCanLockManagedGuestSession, true); + scoped_profile->profile()->GetPrefs()->SetBoolean( + ash::prefs::kAllowScreenLock, true); + session_manager::SessionManager::Get()->SetSessionState( session_manager::SessionState::LOCKED); ASSERT_EQ(login_api_errors::kNoSharedMGSFound, @@ -1042,7 +1126,10 @@ LaunchSharedManagedGuestSession("foo"); session_manager::SessionManager::Get()->SetSessionState( session_manager::SessionState::LOCKED); - fake_chrome_user_manager_->set_current_user_can_lock(false); + testing_profile_->profile()->GetPrefs()->SetBoolean( + ash::prefs::kLoginExtensionApiCanLockManagedGuestSession, false); + testing_profile_->profile()->GetPrefs()->SetBoolean( + ash::prefs::kAllowScreenLock, false); ASSERT_EQ(login_api_errors::kNoUnlockableSession, RunFunctionAndReturnError(
diff --git a/chrome/browser/chromeos/extensions/login_screen/login/login_apitest.cc b/chrome/browser/chromeos/extensions/login_screen/login/login_apitest.cc index 1d48880..d4560290 100644 --- a/chrome/browser/chromeos/extensions/login_screen/login/login_apitest.cc +++ b/chrome/browser/chromeos/extensions/login_screen/login/login_apitest.cc
@@ -209,9 +209,10 @@ // We cannot use the email as an identifier as a different email is generated // for managed guest sessions. user_manager::UserManager* user_manager = user_manager::UserManager::Get(); - EXPECT_TRUE(user_manager->GetActiveUser()->GetType() == - user_manager::UserType::kPublicAccount); - EXPECT_FALSE(user_manager->CanCurrentUserLock()); + auto* active_user = user_manager->GetActiveUser(); + ASSERT_TRUE(active_user); + EXPECT_EQ(user_manager::UserType::kPublicAccount, active_user->GetType()); + EXPECT_FALSE(active_user->CanLock()); } IN_PROC_BROWSER_TEST_F(LoginApitest, LaunchManagedGuestSessionWithPassword) { @@ -219,7 +220,7 @@ LogInWithPassword(); user_manager::UserManager* user_manager = user_manager::UserManager::Get(); - EXPECT_TRUE(user_manager->CanCurrentUserLock()); + EXPECT_TRUE(user_manager->GetActiveUser()->CanLock()); } IN_PROC_BROWSER_TEST_F(LoginApitest, LaunchManagedGuestSessionNoAccounts) {
diff --git a/chrome/browser/commerce/product_specifications/product_specifications_service_factory.cc b/chrome/browser/commerce/product_specifications/product_specifications_service_factory.cc index 0b7d33d4..bd5a167 100644 --- a/chrome/browser/commerce/product_specifications/product_specifications_service_factory.cc +++ b/chrome/browser/commerce/product_specifications/product_specifications_service_factory.cc
@@ -5,7 +5,24 @@ #include "chrome/browser/commerce/product_specifications/product_specifications_service_factory.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/sync/model_type_store_service_factory.h" +#include "chrome/common/channel_info.h" #include "components/commerce/core/product_specifications/product_specifications_service.h" +#include "components/commerce/core/product_specifications/product_specifications_sync_bridge.h" +#include "components/sync/base/report_unrecoverable_error.h" +#include "components/sync/model/client_tag_based_model_type_processor.h" +#include "components/sync/model/model_type_store_service.h" + +namespace { + +std::unique_ptr<syncer::ClientTagBasedModelTypeProcessor> +CreateChangeProcessor() { + return std::make_unique<syncer::ClientTagBasedModelTypeProcessor>( + syncer::COMPARE, base::BindRepeating(&syncer::ReportUnrecoverableError, + chrome::GetChannel())); +} + +} // namespace namespace commerce { @@ -42,7 +59,12 @@ std::unique_ptr<KeyedService> ProductSpecificationsServiceFactory::BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const { - return std::make_unique<commerce::ProductSpecificationsService>(); + return std::make_unique<commerce::ProductSpecificationsService>( + std::make_unique<ProductSpecificationsSyncBridge>( + ModelTypeStoreServiceFactory::GetForProfile( + Profile::FromBrowserContext(context)) + ->GetStoreFactory(), + CreateChangeProcessor())); } } // namespace commerce
diff --git a/chrome/browser/component_updater/screen_ai_component_installer.cc b/chrome/browser/component_updater/screen_ai_component_installer.cc index 2b334ca..2b19d990 100644 --- a/chrome/browser/component_updater/screen_ai_component_installer.cc +++ b/chrome/browser/component_updater/screen_ai_component_installer.cc
@@ -144,7 +144,7 @@ } // Clean up. - if (!screen_ai::GetLatestComponentPath().empty()) { + if (base::PathExists(screen_ai::GetComponentDir())) { ScreenAIComponentInstallerPolicy::DeleteComponent(); } }
diff --git a/chrome/browser/devtools/protocol/autofill_handler.cc b/chrome/browser/devtools/protocol/autofill_handler.cc index 3b1e3c8..c79c3d3 100644 --- a/chrome/browser/devtools/protocol/autofill_handler.cc +++ b/chrome/browser/devtools/protocol/autofill_handler.cc
@@ -378,6 +378,11 @@ .Build()); } +void AutofillHandler::OnAutofillManagerDestroyed( + autofill::AutofillManager& manager) { + autofill_manager_observation_.Reset(); +} + void AutofillHandler::OnContentAutofillDriverFactoryDestroyed( autofill::ContentAutofillDriverFactory& factory) { autofill_manager_observation_.Reset();
diff --git a/chrome/browser/devtools/protocol/autofill_handler.h b/chrome/browser/devtools/protocol/autofill_handler.h index 0aa98a3..d3fe420 100644 --- a/chrome/browser/devtools/protocol/autofill_handler.h +++ b/chrome/browser/devtools/protocol/autofill_handler.h
@@ -62,6 +62,7 @@ absl::variant<const autofill::AutofillProfile*, const autofill::CreditCard*> profile_or_credit_card) override; + void OnAutofillManagerDestroyed(autofill::AutofillManager& manager) override; // ContentAutofillDriverFactory::Observer: void OnContentAutofillDriverFactoryDestroyed(
diff --git a/chrome/browser/enterprise/data_protection/data_protection_navigation_observer.cc b/chrome/browser/enterprise/data_protection/data_protection_navigation_observer.cc index ce264295..4663bd0 100644 --- a/chrome/browser/enterprise/data_protection/data_protection_navigation_observer.cc +++ b/chrome/browser/enterprise/data_protection/data_protection_navigation_observer.cc
@@ -315,8 +315,12 @@ // Even though some of these checks where already performed in // CreateForNavigationIfNeeded(), they still need to checked again here // to handle pages with iframes. + // + // `pending_navigation_callback_` being null implies `DidFinishNavigation` + // has already been called, so further lookups/metrics code need to run. if (!navigation_handle->IsInPrimaryMainFrame() || - !navigation_handle->HasCommitted()) { + !navigation_handle->HasCommitted() || + !pending_navigation_callback_) { return; }
diff --git a/chrome/browser/extensions/api/autofill_private/autofill_private_api.cc b/chrome/browser/extensions/api/autofill_private/autofill_private_api.cc index bc0b256..f5b988a2 100644 --- a/chrome/browser/extensions/api/autofill_private/autofill_private_api.cc +++ b/chrome/browser/extensions/api/autofill_private/autofill_private_api.cc
@@ -8,6 +8,7 @@ #include <algorithm> #include <optional> +#include <string_view> #include <utility> #include "base/functional/bind.h" @@ -108,7 +109,7 @@ autofill::AutofillProfile CreateNewAutofillProfile( autofill::PersonalDataManager* personal_data, - std::optional<base::StringPiece> country_code) { + std::optional<std::string_view> country_code) { autofill::AutofillProfile::Source source = personal_data->IsEligibleForAddressAccountStorage() ? autofill::AutofillProfile::Source::kAccount @@ -190,7 +191,7 @@ if (!existing_profile) return RespondNow(Error(kErrorDataUnavailable)); } - std::optional<base::StringPiece> country_code; + std::optional<std::string_view> country_code; if (auto it = std::find_if( address->fields.begin(), address->fields.end(), [](const auto& field) {
diff --git a/chrome/browser/extensions/api/document_scan/document_scan_apitest.cc b/chrome/browser/extensions/api/document_scan/document_scan_apitest.cc index 7f35079..6f3fe40 100644 --- a/chrome/browser/extensions/api/document_scan/document_scan_apitest.cc +++ b/chrome/browser/extensions/api/document_scan/document_scan_apitest.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 <string_view> + #include "base/auto_reset.h" #include "base/check_deref.h" #include "base/containers/map_util.h" @@ -43,7 +45,7 @@ // manifest file names to create an extension of that type. The actual location // of these files is at //chrome/test/data/extensions/api_test/document_scan/. static constexpr auto kManifestFileNames = - base::MakeFixedFlatMap<ExtensionType, base::StringPiece>( + base::MakeFixedFlatMap<ExtensionType, std::string_view>( {{ExtensionType::kChromeApp, "manifest_chrome_app.json"}, {ExtensionType::kExtensionMV2, "manifest_extension_v2.json"}, {ExtensionType::kExtensionMV3, "manifest_extension_v3.json"}});
diff --git a/chrome/browser/extensions/api/printing/printing_api_utils.cc b/chrome/browser/extensions/api/printing/printing_api_utils.cc index 7372fbb..cded56a 100644 --- a/chrome/browser/extensions/api/printing/printing_api_utils.cc +++ b/chrome/browser/extensions/api/printing/printing_api_utils.cc
@@ -5,6 +5,7 @@ #include "chrome/browser/extensions/api/printing/printing_api_utils.h" #include <memory> +#include <string_view> #include <utility> #include <vector> @@ -56,7 +57,7 @@ // A map containing the allowed vendor items. The key is an IPP attribute, // and the value is a set of allowable values for that attribute. static const base::NoDestructor< - base::flat_map<base::StringPiece, base::flat_set<base::StringPiece>>> + base::flat_map<std::string_view, base::flat_set<std::string_view>>> kVendorItemAllowList({ {"finishings", {"none", "trim"}}, });
diff --git a/chrome/browser/extensions/api/printing/printing_test_utils.cc b/chrome/browser/extensions/api/printing/printing_test_utils.cc index 2b43196..f8d11be 100644 --- a/chrome/browser/extensions/api/printing/printing_test_utils.cc +++ b/chrome/browser/extensions/api/printing/printing_test_utils.cc
@@ -4,6 +4,8 @@ #include "chrome/browser/extensions/api/printing/printing_test_utils.h" +#include <string_view> + #include "base/check_deref.h" #include "base/containers/fixed_flat_map.h" #include "base/containers/map_util.h" @@ -66,7 +68,7 @@ // manifest file names to create an extension of that type. The actual location // of these files is at //chrome/test/data/extensions/api_test/printing/. static constexpr auto kManifestFileNames = - base::MakeFixedFlatMap<ExtensionType, base::StringPiece>( + base::MakeFixedFlatMap<ExtensionType, std::string_view>( {{ExtensionType::kChromeApp, "manifest_chrome_app.json"}, {ExtensionType::kExtensionMV2, "manifest_extension.json"}, {ExtensionType::kExtensionMV3, "manifest_v3_extension.json"}});
diff --git a/chrome/browser/extensions/api/tabs/tabs_test.cc b/chrome/browser/extensions/api/tabs/tabs_test.cc index 446bad8..5fbc440 100644 --- a/chrome/browser/extensions/api/tabs/tabs_test.cc +++ b/chrome/browser/extensions/api/tabs/tabs_test.cc
@@ -1159,6 +1159,8 @@ } void SetUpDefaultCommandLine(base::CommandLine* command_line) override { + // Suppress "Welcome to Google Chrome" window + command_line->AppendSwitch(switches::kNoFirstRun); command_line->AppendSwitch(switches::kNoStartupWindow); command_line->AppendSwitch(switches::kKeepAliveForTest); }
diff --git a/chrome/browser/extensions/pref_mapping.cc b/chrome/browser/extensions/pref_mapping.cc index ca95760..fd882fc4 100644 --- a/chrome/browser/extensions/pref_mapping.cc +++ b/chrome/browser/extensions/pref_mapping.cc
@@ -218,42 +218,39 @@ // the pref in ash, or nullptr if no pref exists. crosapi::mojom::PrefPath PrefMapping::GetPrefPathForPrefName( const std::string& pref_name) const { - // TODO(crbug.com/1513684): Convert to MakeFixedFlatMap(). - static const auto name_to_extension_prefpath = - base::MakeFixedFlatMapNonConsteval<base::StringPiece, - crosapi::mojom::PrefPath>( - {{chromeos::prefs::kDockedMagnifierEnabled, - crosapi::mojom::PrefPath::kDockedMagnifierEnabled}, - {chromeos::prefs::kAccessibilityAutoclickEnabled, - crosapi::mojom::PrefPath::kAccessibilityAutoclickEnabled}, - {chromeos::prefs::kAccessibilityCaretHighlightEnabled, - crosapi::mojom::PrefPath::kAccessibilityCaretHighlightEnabled}, - {chromeos::prefs::kAccessibilityCursorColorEnabled, - crosapi::mojom::PrefPath::kAccessibilityCursorColorEnabled}, - {chromeos::prefs::kAccessibilityCursorHighlightEnabled, - crosapi::mojom::PrefPath::kAccessibilityCursorHighlightEnabled}, - {chromeos::prefs::kAccessibilityDictationEnabled, - crosapi::mojom::PrefPath::kAccessibilityDictationEnabled}, - {chromeos::prefs::kAccessibilityFocusHighlightEnabled, - crosapi::mojom::PrefPath::kAccessibilityFocusHighlightEnabled}, - {chromeos::prefs::kAccessibilityHighContrastEnabled, - crosapi::mojom::PrefPath::kAccessibilityHighContrastEnabled}, - {chromeos::prefs::kAccessibilityLargeCursorEnabled, - crosapi::mojom::PrefPath::kAccessibilityLargeCursorEnabled}, - {chromeos::prefs::kAccessibilityScreenMagnifierEnabled, - crosapi::mojom::PrefPath::kAccessibilityScreenMagnifierEnabled}, - {chromeos::prefs::kAccessibilitySelectToSpeakEnabled, - crosapi::mojom::PrefPath::kAccessibilitySelectToSpeakEnabled}, - {chromeos::prefs::kAccessibilitySpokenFeedbackEnabled, - crosapi::mojom::PrefPath:: - kExtensionAccessibilitySpokenFeedbackEnabled}, - {chromeos::prefs::kAccessibilityStickyKeysEnabled, - crosapi::mojom::PrefPath::kAccessibilityStickyKeysEnabled}, - {chromeos::prefs::kAccessibilitySwitchAccessEnabled, - crosapi::mojom::PrefPath::kAccessibilitySwitchAccessEnabled}, - {chromeos::prefs::kAccessibilityVirtualKeyboardEnabled, - crosapi::mojom::PrefPath::kAccessibilityVirtualKeyboardEnabled}, - {proxy_config::prefs::kProxy, crosapi::mojom::PrefPath::kProxy}}); + static constexpr auto name_to_extension_prefpath = base::MakeFixedFlatMap< + base::StringPiece, crosapi::mojom::PrefPath>( + {{chromeos::prefs::kDockedMagnifierEnabled, + crosapi::mojom::PrefPath::kDockedMagnifierEnabled}, + {chromeos::prefs::kAccessibilityAutoclickEnabled, + crosapi::mojom::PrefPath::kAccessibilityAutoclickEnabled}, + {chromeos::prefs::kAccessibilityCaretHighlightEnabled, + crosapi::mojom::PrefPath::kAccessibilityCaretHighlightEnabled}, + {chromeos::prefs::kAccessibilityCursorColorEnabled, + crosapi::mojom::PrefPath::kAccessibilityCursorColorEnabled}, + {chromeos::prefs::kAccessibilityCursorHighlightEnabled, + crosapi::mojom::PrefPath::kAccessibilityCursorHighlightEnabled}, + {chromeos::prefs::kAccessibilityDictationEnabled, + crosapi::mojom::PrefPath::kAccessibilityDictationEnabled}, + {chromeos::prefs::kAccessibilityFocusHighlightEnabled, + crosapi::mojom::PrefPath::kAccessibilityFocusHighlightEnabled}, + {chromeos::prefs::kAccessibilityHighContrastEnabled, + crosapi::mojom::PrefPath::kAccessibilityHighContrastEnabled}, + {chromeos::prefs::kAccessibilityLargeCursorEnabled, + crosapi::mojom::PrefPath::kAccessibilityLargeCursorEnabled}, + {chromeos::prefs::kAccessibilityScreenMagnifierEnabled, + crosapi::mojom::PrefPath::kAccessibilityScreenMagnifierEnabled}, + {chromeos::prefs::kAccessibilitySelectToSpeakEnabled, + crosapi::mojom::PrefPath::kAccessibilitySelectToSpeakEnabled}, + {chromeos::prefs::kAccessibilitySpokenFeedbackEnabled, + crosapi::mojom::PrefPath::kExtensionAccessibilitySpokenFeedbackEnabled}, + {chromeos::prefs::kAccessibilityStickyKeysEnabled, + crosapi::mojom::PrefPath::kAccessibilityStickyKeysEnabled}, + {chromeos::prefs::kAccessibilitySwitchAccessEnabled, + crosapi::mojom::PrefPath::kAccessibilitySwitchAccessEnabled}, + {chromeos::prefs::kAccessibilityVirtualKeyboardEnabled, + crosapi::mojom::PrefPath::kAccessibilityVirtualKeyboardEnabled}, + {proxy_config::prefs::kProxy, crosapi::mojom::PrefPath::kProxy}}); auto pref_iter = name_to_extension_prefpath.find(pref_name); return pref_iter == name_to_extension_prefpath.end() ? crosapi::mojom::PrefPath::kUnknown
diff --git a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/signinbottomsheet/SigninBottomSheetCoordinator.java b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/signinbottomsheet/SigninBottomSheetCoordinator.java index c0c7ab0f..ffda880 100644 --- a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/signinbottomsheet/SigninBottomSheetCoordinator.java +++ b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/signinbottomsheet/SigninBottomSheetCoordinator.java
@@ -6,7 +6,6 @@ import android.view.View; import androidx.annotation.Nullable; -import androidx.annotation.StringRes; import org.chromium.base.Callback; import org.chromium.base.metrics.RecordHistogram; @@ -55,8 +54,18 @@ mSetTestToast = false; mOnSigninSuccessCallback = onSigninSuccessCallback; mSigninAccessPoint = signinAccessPoint; - mBottomSheetStrings = - bottomSheetStrings != null ? bottomSheetStrings : new BottomSheetStrings(); + + if (bottomSheetStrings == null) { + mBottomSheetStrings = + new AccountPickerBottomSheetStrings( + R.string + .signin_account_picker_bottom_sheet_title_for_back_of_card_menu_signin, + R.string + .signin_account_picker_bottom_sheet_subtitle_for_back_of_card_menu_signin, + R.string.close); + } else { + mBottomSheetStrings = bottomSheetStrings; + } } @Override @@ -142,26 +151,4 @@ public void setToastOverrideForTesting() { this.mSetTestToast = true; } - - /** Stores bottom sheet strings for signin from back of card entry point */ - public static class BottomSheetStrings implements AccountPickerBottomSheetStrings { - /** Returns the title string for the bottom sheet dialog. */ - @Override - public @StringRes int getTitle() { - return R.string.signin_account_picker_bottom_sheet_title_for_back_of_card_menu_signin; - } - - /** Returns the subtitle string for the bottom sheet dialog. */ - @Override - public @StringRes int getSubtitle() { - return R.string - .signin_account_picker_bottom_sheet_subtitle_for_back_of_card_menu_signin; - } - - /** Returns the cancel button string for the bottom sheet dialog. */ - @Override - public @StringRes int getDismissButton() { - return R.string.close; - } - } }
diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browser/flags/android/chrome_feature_list.cc index b403197..4807eb5 100644 --- a/chrome/browser/flags/android/chrome_feature_list.cc +++ b/chrome/browser/flags/android/chrome_feature_list.cc
@@ -86,6 +86,7 @@ &autofill::features::kAutofillEnableVirtualCardMetadata, &autofill::features::kAutofillEnableCardArtImage, &autofill::features::kAutofillEnableCardProductName, + &autofill::features::kAutofillEnableLocalIban, &autofill::features::kAutofillVirtualViewStructureAndroid, &autofill::features::kAutofillEnablePaymentsMandatoryReauth, &autofill::features::kAutofillEnableMovingGPayLogoToTheRightOnClank, @@ -168,6 +169,7 @@ &kBackGestureRefactorAndroid, &kBackgroundThreadPool, &kBlockIntentsWhileLocked, + &kBrowserControlsEarlyResize, &kCacheActivityTaskID, &kCastDeviceFilter, &kClearOmniboxFocusAfterNavigation, @@ -471,6 +473,10 @@ "BlockIntentsWhileLocked", base::FEATURE_DISABLED_BY_DEFAULT); +BASE_FEATURE(kBrowserControlsEarlyResize, + "BrowserControlsEarlyResize", + base::FEATURE_ENABLED_BY_DEFAULT); + BASE_FEATURE(kCacheActivityTaskID, "CacheActivityTaskID", base::FEATURE_ENABLED_BY_DEFAULT);
diff --git a/chrome/browser/flags/android/chrome_feature_list.h b/chrome/browser/flags/android/chrome_feature_list.h index 45d911f4..bca64de9 100644 --- a/chrome/browser/flags/android/chrome_feature_list.h +++ b/chrome/browser/flags/android/chrome_feature_list.h
@@ -40,6 +40,7 @@ BASE_DECLARE_FEATURE(kBackGestureRefactorAndroid); BASE_DECLARE_FEATURE(kBackgroundThreadPool); BASE_DECLARE_FEATURE(kBlockIntentsWhileLocked); +BASE_DECLARE_FEATURE(kBrowserControlsEarlyResize); BASE_DECLARE_FEATURE(kCacheActivityTaskID); BASE_DECLARE_FEATURE(kClearOmniboxFocusAfterNavigation); BASE_DECLARE_FEATURE(kCreateNewTabInitializeRenderer);
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 088b80b..cedd825e 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
@@ -170,6 +170,7 @@ "AutofillAllowNonHttpActivation"; public static final String AUTOFILL_ENABLE_CARD_ART_IMAGE = "AutofillEnableCardArtImage"; public static final String AUTOFILL_ENABLE_CARD_PRODUCT_NAME = "AutofillEnableCardProductName"; + public static final String AUTOFILL_ENABLE_LOCAL_IBAN = "AutofillEnableLocalIban"; public static final String AUTOFILL_ENABLE_MOVING_GPAY_LOGO_TO_THE_RIGHT_ON_CLANK = "AutofillEnableMovingGPayLogoToTheRightOnClank"; public static final String AUTOFILL_ENABLE_NEW_CARD_ART_AND_NETWORK_IMAGES = @@ -199,6 +200,7 @@ public static final String BACK_GESTURE_REFACTOR = "BackGestureRefactorAndroid"; public static final String BLOCK_INTENTS_WHILE_LOCKED = "BlockIntentsWhileLocked"; public static final String BOARDING_PASS_DETECTOR = "BoardingPassDetector"; + public static final String BROWSER_CONTROLS_EARLY_RESIZE = "BrowserControlsEarlyResize"; public static final String CACHE_ACTIVITY_TASKID = "CacheActivityTaskID"; public static final String CAPTIVE_PORTAL_CERTIFICATE_LIST = "CaptivePortalCertificateList"; public static final String CCT_AUTO_TRANSLATE = "CCTAutoTranslate"; @@ -778,13 +780,14 @@ newMutableFlagWithSafeDefault(ADVANCED_PERIPHERALS_SUPPORT_TAB_STRIP, true); public static final MutableFlagWithSafeDefault sAndroidImprovedBookmarks = newMutableFlagWithSafeDefault(ANDROID_IMPROVED_BOOKMARKS, false); + public static final MutableFlagWithSafeDefault sBrowserControlsEarlyResize = + newMutableFlagWithSafeDefault(BROWSER_CONTROLS_EARLY_RESIZE, true); public static final MutableFlagWithSafeDefault sIncognitoNtpRevamp = newMutableFlagWithSafeDefault(INCOGNITO_NTP_REVAMP, false); public static final MutableFlagWithSafeDefault sIncognitoScreenshot = newMutableFlagWithSafeDefault(INCOGNITO_SCREENSHOT, false); public static final MutableFlagWithSafeDefault sNoVisibleHintForDifferentTLD = newMutableFlagWithSafeDefault(ANDROID_NO_VISIBLE_HINT_FOR_DIFFERENT_TLD, false); - public static final MutableFlagWithSafeDefault sOmniboxAnswerActions = newMutableFlagWithSafeDefault(OMNIBOX_ANSWER_ACTIONS, false); public static final MutableFlagWithSafeDefault sOmniboxHistoryClusterProvider =
diff --git a/chrome/browser/history_embeddings/history_embeddings_service_browsertest.cc b/chrome/browser/history_embeddings/history_embeddings_service_browsertest.cc index 4e4fbeb..5e49dab7 100644 --- a/chrome/browser/history_embeddings/history_embeddings_service_browsertest.cc +++ b/chrome/browser/history_embeddings/history_embeddings_service_browsertest.cc
@@ -4,9 +4,10 @@ #include "components/history_embeddings/history_embeddings_service.h" -#include "base/files/scoped_temp_dir.h" #include "base/test/scoped_feature_list.h" #include "base/test/test_future.h" +#include "chrome/browser/history_embeddings/history_embeddings_service_factory.h" +#include "chrome/browser/profiles/profile.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" @@ -19,19 +20,26 @@ class HistoryEmbeddingsBrowserTest : public InProcessBrowserTest { public: void SetUp() override { + // The feature must be enabled first or else the service isn't initialized + // properly. feature_list_.InitAndEnableFeature(kHistoryEmbeddings); - CHECK(history_dir_.CreateUniqueTempDir()); + InProcessBrowserTest::SetUp(); } protected: - base::ScopedTempDir history_dir_; base::test::ScopedFeatureList feature_list_; }; +IN_PROC_BROWSER_TEST_F(HistoryEmbeddingsBrowserTest, ServiceFactoryWorks) { + auto* service = + HistoryEmbeddingsServiceFactory::GetForProfile(browser()->profile()); + EXPECT_TRUE(service); +} + IN_PROC_BROWSER_TEST_F(HistoryEmbeddingsBrowserTest, BrowserRetrievesPassages) { - auto service = - std::make_unique<HistoryEmbeddingsService>(history_dir_.GetPath()); + auto* service = + HistoryEmbeddingsServiceFactory::GetForProfile(browser()->profile()); ASSERT_TRUE(embedded_test_server()->Start()); auto* web_contents = browser()->tab_strip_model()->GetActiveWebContents();
diff --git a/chrome/browser/history_embeddings/history_embeddings_service_factory.cc b/chrome/browser/history_embeddings/history_embeddings_service_factory.cc new file mode 100644 index 0000000..2dfaaca --- /dev/null +++ b/chrome/browser/history_embeddings/history_embeddings_service_factory.cc
@@ -0,0 +1,49 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/history_embeddings/history_embeddings_service_factory.h" + +#include "chrome/browser/history/history_service_factory.h" +#include "chrome/browser/profiles/profile.h" +#include "components/history/core/browser/history_service.h" +#include "components/history_embeddings/history_embeddings_service.h" +#include "components/keyed_service/core/service_access_type.h" + +// static +history_embeddings::HistoryEmbeddingsService* +HistoryEmbeddingsServiceFactory::GetForProfile(Profile* profile) { + return static_cast<history_embeddings::HistoryEmbeddingsService*>( + GetInstance()->GetServiceForBrowserContext(profile, /*create=*/true)); +} + +// static +HistoryEmbeddingsServiceFactory* +HistoryEmbeddingsServiceFactory::GetInstance() { + static base::NoDestructor<HistoryEmbeddingsServiceFactory> instance; + return instance.get(); +} + +HistoryEmbeddingsServiceFactory::HistoryEmbeddingsServiceFactory() + : ProfileKeyedServiceFactory("HistoryEmbeddingsService", + ProfileSelections::BuildForRegularProfile()) { + DependsOn(HistoryServiceFactory::GetInstance()); +} + +HistoryEmbeddingsServiceFactory::~HistoryEmbeddingsServiceFactory() = default; + +std::unique_ptr<KeyedService> +HistoryEmbeddingsServiceFactory::BuildServiceInstanceForBrowserContext( + content::BrowserContext* context) const { + auto* profile = Profile::FromBrowserContext(context); + auto* history_service = HistoryServiceFactory::GetForProfile( + profile, ServiceAccessType::EXPLICIT_ACCESS); + + // The embeddings service can't function without a HistoryService. This + // happens in some unit tests. + if (!history_service) { + return nullptr; + } + return std::make_unique<history_embeddings::HistoryEmbeddingsService>( + history_service->history_dir(), history_service); +}
diff --git a/chrome/browser/history_embeddings/history_embeddings_service_factory.h b/chrome/browser/history_embeddings/history_embeddings_service_factory.h new file mode 100644 index 0000000..90e0563 --- /dev/null +++ b/chrome/browser/history_embeddings/history_embeddings_service_factory.h
@@ -0,0 +1,35 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_HISTORY_EMBEDDINGS_HISTORY_EMBEDDINGS_SERVICE_FACTORY_H_ +#define CHROME_BROWSER_HISTORY_EMBEDDINGS_HISTORY_EMBEDDINGS_SERVICE_FACTORY_H_ + +#include "base/no_destructor.h" +#include "chrome/browser/profiles/profile_keyed_service_factory.h" +#include "content/public/browser/browser_context.h" + +namespace history_embeddings { +class HistoryEmbeddingsService; +} // namespace history_embeddings + +class HistoryEmbeddingsServiceFactory : public ProfileKeyedServiceFactory { + public: + // This can return nullptr in tests. + static history_embeddings::HistoryEmbeddingsService* GetForProfile( + Profile* profile); + + static HistoryEmbeddingsServiceFactory* GetInstance(); + + private: + friend base::NoDestructor<HistoryEmbeddingsServiceFactory>; + + HistoryEmbeddingsServiceFactory(); + ~HistoryEmbeddingsServiceFactory() override; + + // BrowserContextKeyedServiceFactory: + std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( + content::BrowserContext* context) const override; +}; + +#endif // CHROME_BROWSER_HISTORY_EMBEDDINGS_HISTORY_EMBEDDINGS_SERVICE_FACTORY_H_
diff --git a/chrome/browser/lens/server/proto/BUILD.gn b/chrome/browser/lens/server/proto/BUILD.gn new file mode 100644 index 0000000..4f5c364 --- /dev/null +++ b/chrome/browser/lens/server/proto/BUILD.gn
@@ -0,0 +1,25 @@ +# Copyright 2024 The Chromium Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import("//third_party/protobuf/proto_library.gni") + +_proto_files = [ + "lens_overlay_client_context.proto", + "lens_overlay_geometry.proto", + "lens_overlay_image_data.proto", + "lens_overlay_interaction_request_metadata.proto", + "lens_overlay_overlay_object.proto", + "lens_overlay_platform.proto", + "lens_overlay_polygon.proto", + "lens_overlay_request_id.proto", + "lens_overlay_service_deps.proto", + "lens_overlay_surface.proto", + "lens_overlay_text.proto", + "lens_overlay_text_query.proto", +] + +proto_library("lens_overlay_proto") { + sources = _proto_files + proto_in_dir = "." +}
diff --git a/chrome/browser/lens/server/proto/README.chromium b/chrome/browser/lens/server/proto/README.chromium new file mode 100644 index 0000000..c184c80 --- /dev/null +++ b/chrome/browser/lens/server/proto/README.chromium
@@ -0,0 +1,23 @@ +Name: Lens Protos +Short Name: lens_overlay_proto +URL: This is the canonical public repository +Version: 616837888 +Date: 2024-03-18 UTC +License: BSD +License File: LICENSE +Shipped: yes +Security Critical: Yes + +Description: +This package contains the protos that are used by the Lens team to facilitate +integration between Chrome and Google Search. +Updates to this code should be made by changing the internal copies, and then +running the export script. + +blaze run //lens/chrome/scripts/proto_export -- \ + --from_piper \ + --output=$CHROMIUM_SRC/chrome/browser/lens/server/proto + + +Local Modifications: +Unchanged from the output of the export script.
diff --git a/chrome/browser/lens/server/proto/lens_overlay_client_context.proto b/chrome/browser/lens/server/proto/lens_overlay_client_context.proto new file mode 100644 index 0000000..42c3029a --- /dev/null +++ b/chrome/browser/lens/server/proto/lens_overlay_client_context.proto
@@ -0,0 +1,47 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +syntax = 'proto3'; + +option optimize_for = LITE_RUNTIME; + +package lens; + +// Context information of the client sending the request. +message LensOverlayClientContext { + // Required. Client platform. + Platform platform = 1; + + // Optional. Client surface. + Surface surface = 2; + + // Required. Locale specific context. + LocaleContext locale_context = 4; + + // Required. Name of the package which sends the request to Lens Frontend. + string app_id = 6; + + // Logging data. + ClientLoggingData client_logging_data = 23; + + reserved 3, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22; +} + +// Describes locale context. +message LocaleContext { + // The BCP 47 language tag used to identify the language of the client. + string language = 1; + + // The CLDR region tag used to identify the region of the client. + string region = 2; + + // The CLDR time zone ID used to identify the timezone of the client. + string time_zone = 3; +} + +// Contains data that can be used for logging purposes. +message ClientLoggingData { + // Whether history is enabled. + bool is_history_eligible = 1; +}
diff --git a/chrome/browser/lens/server/proto/lens_overlay_geometry.proto b/chrome/browser/lens/server/proto/lens_overlay_geometry.proto new file mode 100644 index 0000000..a8c7fe8 --- /dev/null +++ b/chrome/browser/lens/server/proto/lens_overlay_geometry.proto
@@ -0,0 +1,32 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +syntax = 'proto2'; + +option optimize_for = LITE_RUNTIME; + +package lens; + +// Information about a center bounding box rotated around its center. +message CenterRotatedBox { + optional float center_x = 1; + optional float center_y = 2; + optional float width = 3; + optional float height = 4; + // Clockwise rotation around the center in radians. The rotation angle is + // computed before normalizing the coordinates. + optional float rotation_z = 5; + // Specifies the coordinate type of center and size. + // @note default is COORDINATE_TYPE_UNSPECIFIED, please initialize this value + // to NORMALIZED or IMAGE for Lens detection API usage. + optional CoordinateType coordinate_type = 6; +} + +// Geometric shape(s) used for tracking and detection. +message Geometry { + // Specifies the bounding box for this geometry. + optional CenterRotatedBox bounding_box = 1; + + reserved 2, 3, 4, 5, 6; +}
diff --git a/chrome/browser/lens/server/proto/lens_overlay_image_data.proto b/chrome/browser/lens/server/proto/lens_overlay_image_data.proto new file mode 100644 index 0000000..d88d5dc --- /dev/null +++ b/chrome/browser/lens/server/proto/lens_overlay_image_data.proto
@@ -0,0 +1,40 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +syntax = 'proto3'; + +option optimize_for = LITE_RUNTIME; + +package lens; + +// Data representing image. Contains image bytes or image retrieval identifier. +message ImageData { + // Image payload to process. This contains image bytes. + ImagePayload payload = 1; + + // Required. Context of the given image. + ImageMetadata image_metadata = 3; + + reserved 2; +} + +message ImagePayload { + // Required. Image byte array. + bytes image_bytes = 1; + + // Required. Metadata related to the image. + ImageMetadata image_metadata = 2 [deprecated = true]; +} + +message ImageMetadata { + // Required. Image width in pixels. Should reflect the actual size of + // image_bytes. + int32 width = 1; + + // Required. Image height in pixels. Should reflect the actual size of + // image_bytes. + int32 height = 2; + + reserved 6; +}
diff --git a/chrome/browser/lens/server/proto/lens_overlay_interaction_request_metadata.proto b/chrome/browser/lens/server/proto/lens_overlay_interaction_request_metadata.proto new file mode 100644 index 0000000..38c674d --- /dev/null +++ b/chrome/browser/lens/server/proto/lens_overlay_interaction_request_metadata.proto
@@ -0,0 +1,61 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +syntax = 'proto3'; + +option optimize_for = LITE_RUNTIME; + +package lens; + +// Metadata associated with an interaction request. +message LensOverlayInteractionRequestMetadata { + // Type of interaction request. + enum Type { + UNKNOWN = 0; + // User's tap on the screen. + TAP = 1; + // User's region selection on the screenshot. + REGION = 2; + // User's text selection on the screenshot. + TEXT_SELECTION = 3; + // User selected a bounding box to region search. + REGION_SEARCH = 4; + // Requests selection and fulfillment of a specific object. + OBJECT_FULFILLMENT = 5; + } + Type type = 1; + + // Metadata related to the selection associated with this interaction request. + message SelectionMetadata { + message Point { + float x = 1; + float y = 2; + } + message Region { + CenterRotatedBox region = 1; + } + message Object { + string object_id = 1; + Geometry geometry = 2; + } + + oneof selection { + Point point = 1; + Region region = 2; + Object object = 3; + } + } + SelectionMetadata selection_metadata = 2; + + // Metadata related to query. + message QueryMetadata { + // The text query information. + TextQuery text_query = 2; + + reserved 1; + } + QueryMetadata query_metadata = 4; + + reserved 3; +}
diff --git a/chrome/browser/lens/server/proto/lens_overlay_overlay_object.proto b/chrome/browser/lens/server/proto/lens_overlay_overlay_object.proto new file mode 100644 index 0000000..456cbf4e --- /dev/null +++ b/chrome/browser/lens/server/proto/lens_overlay_overlay_object.proto
@@ -0,0 +1,20 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +syntax = 'proto3'; + +option optimize_for = LITE_RUNTIME; + +package lens; + +// Overlay Object. +message OverlayObject { + // The id. + string id = 1; + + // The object geometry. + Geometry geometry = 2; + + reserved 3, 4, 5, 6, 7, 8; +}
diff --git a/chrome/browser/lens/server/proto/lens_overlay_platform.proto b/chrome/browser/lens/server/proto/lens_overlay_platform.proto new file mode 100644 index 0000000..de426454 --- /dev/null +++ b/chrome/browser/lens/server/proto/lens_overlay_platform.proto
@@ -0,0 +1,14 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +syntax = 'proto3'; + +option optimize_for = LITE_RUNTIME; + +package lens; + +enum Platform { + PLATFORM_UNSPECIFIED = 0; + WEB = 3; +}
diff --git a/chrome/browser/lens/server/proto/lens_overlay_polygon.proto b/chrome/browser/lens/server/proto/lens_overlay_polygon.proto new file mode 100644 index 0000000..dcac5bcb --- /dev/null +++ b/chrome/browser/lens/server/proto/lens_overlay_polygon.proto
@@ -0,0 +1,19 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +syntax = 'proto2'; + +option optimize_for = LITE_RUNTIME; + +package lens; + +// Specifies the coordinate system used for geometry protos. +enum CoordinateType { + // Unspecified default value, per proto best practice. + COORDINATE_TYPE_UNSPECIFIED = 0; + // Normalized coordinates. + NORMALIZED = 1; + // Image pixel coordinates. + IMAGE = 2; +}
diff --git a/chrome/browser/lens/server/proto/lens_overlay_request_id.proto b/chrome/browser/lens/server/proto/lens_overlay_request_id.proto new file mode 100644 index 0000000..ae7a0fef --- /dev/null +++ b/chrome/browser/lens/server/proto/lens_overlay_request_id.proto
@@ -0,0 +1,28 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +syntax = 'proto2'; + +option optimize_for = LITE_RUNTIME; + +package lens; + +// Request Id definition to support request sequencing and state lookup. +message LensOverlayRequestId { + // A unique identifier for a sequence of related Lens requests. + optional uint64 uuid = 1; + + // An id to indicate the order of the current request within a sequence of + // requests sharing the same uuid. Starts from 1, increments by 1 if there is + // a new request with the same uuid. + optional int32 sequence_id = 2; + + // An id to indicate the order of image payload sent within a sequence of + // requests sharing the same uuid. Starts from 1, increments by 1 if there is + // a new request with an image payload with the same uuid. + // Note, region search request does not increment this id. + optional int32 image_sequence_id = 3; + + reserved 4; +}
diff --git a/chrome/browser/lens/server/proto/lens_overlay_service_deps.proto b/chrome/browser/lens/server/proto/lens_overlay_service_deps.proto new file mode 100644 index 0000000..afaf9af --- /dev/null +++ b/chrome/browser/lens/server/proto/lens_overlay_service_deps.proto
@@ -0,0 +1,54 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +syntax = 'proto3'; + +option optimize_for = LITE_RUNTIME; + +package lens; + +// Request context for a Lens Overlay request. +message LensOverlayRequestContext { + // Required. Identifiers for this request. + LensOverlayRequestId request_id = 3; + + // The client context for the request. + LensOverlayClientContext client_context = 4; + + reserved 1, 2; +} + +message LensOverlayObjectsRequest { + // Required. Basic information and context for the request. + LensOverlayRequestContext request_context = 1; + + // Required. Image Data to process. + ImageData image_data = 3; + + reserved 2; +} + +message LensOverlayObjectsResponse { + // Overlay objects. + repeated OverlayObject overlay_objects = 2; + + // Text. + Text text = 3; + + reserved 1, 4, 5, 6; +} + +message LensOverlayInteractionRequest { + // Basic information and context for the request. + LensOverlayRequestContext request_context = 1; + + // Metadata associated with an interaction request. + LensOverlayInteractionRequestMetadata interaction_request_metadata = 2; +} + +message LensOverlayInteractionResponse { + optional string encoded_response = 3; + + reserved 1, 2; +}
diff --git a/chrome/browser/lens/server/proto/lens_overlay_surface.proto b/chrome/browser/lens/server/proto/lens_overlay_surface.proto new file mode 100644 index 0000000..aa46f1b --- /dev/null +++ b/chrome/browser/lens/server/proto/lens_overlay_surface.proto
@@ -0,0 +1,14 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +syntax = 'proto3'; + +option optimize_for = LITE_RUNTIME; + +package lens; + +enum Surface { + SURFACE_UNSPECIFIED = 0; + CHROMIUM = 4; +}
diff --git a/chrome/browser/lens/server/proto/lens_overlay_text.proto b/chrome/browser/lens/server/proto/lens_overlay_text.proto new file mode 100644 index 0000000..786d2df --- /dev/null +++ b/chrome/browser/lens/server/proto/lens_overlay_text.proto
@@ -0,0 +1,103 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +syntax = 'proto3'; + +option optimize_for = LITE_RUNTIME; + +package lens; + +// The text reading order. +enum WritingDirection { + DEFAULT_WRITING_DIRECTION_LEFT_TO_RIGHT = 0; + WRITING_DIRECTION_RIGHT_TO_LEFT = 1; + WRITING_DIRECTION_TOP_TO_BOTTOM = 2; +} + +message Text { + // Optional. Information describing the text. + TextLayout text_layout = 1; + + // Optional. Dominant content language of the text. Language + // code is CLDR/BCP-47. + string content_language = 2; + + reserved 3; +} + +// Nested text structure. +message TextLayout { + message Word { + // Required. Unique id within TextLayout. + TextEntityIdentifier id = 1; + + // Optional. The text in a plain text. + string plain_text = 2; + + // Optional. The text separator that should be appended after this word when + // it is concatenated with the subsequent word in the same or next + // line/paragraph into a single-line string. + string text_separator = 3; + + // Optional. The geometry of the word. + Geometry geometry = 4; + + enum Type { + // Printed text. + TEXT = 0; + // Formula type, including mathematical or chemical formulas. + FORMULA = 1; + } + + // Optional. The type of this word. + Type type = 5; + + message FormulaMetadata { + // Optional. LaTeX representation of a formula. Can be the same as + // `plain_text`. Example: "\frac{2}{x}=y". The plain text + // representation of this is available in Word.plain_text. + string latex = 1; + } + + // Optional. Metadata for formulas. This is populated for entities of + // `type=FORMULA`. + FormulaMetadata formula_metadata = 6; + } + + message Line { + // Optional. List of words in natural reading order. + repeated Word words = 1; + + // Optional. The geometry of the line. + Geometry geometry = 2; + } + + message Paragraph { + // Required. Unique id within TextLayout. + TextEntityIdentifier id = 1; + + // Optional. List of lines in natural reading order (see also + // `writing_direction`). + repeated Line lines = 2; + + // Optional. Geometry of the paragraph. + Geometry geometry = 3; + + // Optional. The text writing direction (aka reading order). + WritingDirection writing_direction = 4; + + // Optional. BCP-47 language code of the dominant language in this + // paragraph. + string content_language = 5; + } + + // Optional. List of paragraphs in natural reading order. + repeated Paragraph paragraphs = 1; +} + +message TextEntityIdentifier { + // Required. Unique entity id used to reference (and match) text entities and + // ranges. + int64 id = 1; +}
diff --git a/chrome/browser/lens/server/proto/lens_overlay_text_query.proto b/chrome/browser/lens/server/proto/lens_overlay_text_query.proto new file mode 100644 index 0000000..00b400a --- /dev/null +++ b/chrome/browser/lens/server/proto/lens_overlay_text_query.proto
@@ -0,0 +1,16 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +syntax = 'proto2'; + +option optimize_for = LITE_RUNTIME; + +package lens; + +// Contains an unstructured text query to add to an image query. +message TextQuery { + // The unstructured text query, such as "blue" or "blouse". + optional string query = 1; + optional bool is_primary = 2; +}
diff --git a/chrome/browser/media/cast_mirroring_performance_browsertest.cc b/chrome/browser/media/cast_mirroring_performance_browsertest.cc index 680f507d..446e014 100644 --- a/chrome/browser/media/cast_mirroring_performance_browsertest.cc +++ b/chrome/browser/media/cast_mirroring_performance_browsertest.cc
@@ -12,6 +12,7 @@ #include <map> #include <memory> #include <optional> +#include <string_view> #include <utility> #include <vector> @@ -26,7 +27,6 @@ #include "base/path_service.h" #include "base/strings/strcat.h" #include "base/strings/string_number_conversions.h" -#include "base/strings/string_piece.h" #include "base/strings/stringprintf.h" #include "base/task/sequenced_task_runner.h" #include "base/task/thread_pool/thread_pool_instance.h" @@ -122,7 +122,7 @@ constexpr char kTestPageLocation[] = "/cast/cast_mirroring_performance_browsertest.html"; -constexpr base::StringPiece kFullPerformanceRunSwitch = "full-performance-run"; +constexpr std::string_view kFullPerformanceRunSwitch = "full-performance-run"; // The test receiver and senders should share the target playout delay. constexpr int kTargetPlayoutDelayMs = 400; // milliseconds @@ -233,7 +233,7 @@ using TraceAnalyzerUniquePtr = std::unique_ptr<trace_analyzer::TraceAnalyzer>; void QueryTraceEvents(trace_analyzer::TraceAnalyzer* analyzer, - base::StringPiece event_name, + std::string_view event_name, trace_analyzer::TraceEventVector* events) { const trace_analyzer::Query kQuery = trace_analyzer::Query::EventNameIs(std::string(event_name)) && @@ -268,7 +268,7 @@ TraceAnalyzerUniquePtr TraceAndObserve( bool is_full_performance_run, const std::string& category_patterns, - const std::vector<base::StringPiece>& event_names, + const std::vector<std::string_view>& event_names, int required_event_count) { const base::TimeDelta observation_period = is_full_performance_run ? kFullRunObservationPeriod @@ -1111,7 +1111,7 @@ // Observe the running browser for a while, collecting a trace. TraceAnalyzerUniquePtr analyzer = TraceAndObserve( is_full_performance_run_, "gpu.capture,cast_perf_test", - std::vector<base::StringPiece>{ + std::vector<std::string_view>{ // From the Compositor/Capture pipeline... "Capture", "OnBufferReceived", "ConsumeVideoFrame", // From the Cast Sender's pipeline...
diff --git a/chrome/browser/media/media_engagement_score.cc b/chrome/browser/media/media_engagement_score.cc index 1064c5a..fdff67b 100644 --- a/chrome/browser/media/media_engagement_score.cc +++ b/chrome/browser/media/media_engagement_score.cc
@@ -4,6 +4,7 @@ #include "chrome/browser/media/media_engagement_score.h" +#include <string_view> #include <utility> #include "base/metrics/field_trial_params.h" @@ -51,7 +52,7 @@ } void GetIntegerFromScore(const base::Value::Dict& dict, - base::StringPiece key, + std::string_view key, int* out) { if (std::optional<int> v = dict.FindInt(key)) { *out = v.value();
diff --git a/chrome/browser/media/router/discovery/dial/dial_service_impl.cc b/chrome/browser/media/router/discovery/dial/dial_service_impl.cc index 795d657..fd71083 100644 --- a/chrome/browser/media/router/discovery/dial/dial_service_impl.cc +++ b/chrome/browser/media/router/discovery/dial/dial_service_impl.cc
@@ -9,6 +9,7 @@ #include <algorithm> #include <set> #include <string> +#include <string_view> #include <utility> #include <vector> @@ -346,7 +347,7 @@ return false; } std::string raw_headers = HttpUtil::AssembleRawHeaders( - base::StringPiece(response.c_str(), headers_end)); + std::string_view(response.c_str(), headers_end)); auto headers = base::MakeRefCounted<HttpResponseHeaders>(raw_headers); std::string device_url_str;
diff --git a/chrome/browser/media/router/mojo/media_router_desktop_unittest.cc b/chrome/browser/media/router/mojo/media_router_desktop_unittest.cc index eb9c19a..a3a9441 100644 --- a/chrome/browser/media/router/mojo/media_router_desktop_unittest.cc +++ b/chrome/browser/media/router/mojo/media_router_desktop_unittest.cc
@@ -9,6 +9,7 @@ #include <memory> #include <string> +#include <string_view> #include <utility> #include "base/base64.h" @@ -118,7 +119,7 @@ result = "text="; base::EscapeJSONString(message->message.value(), true, &result); } else { - const base::StringPiece src( + const std::string_view src( reinterpret_cast<const char*>(message->data.value().data()), message->data.value().size()); result = "binary=" + base::Base64Encode(src);
diff --git a/chrome/browser/media/router/providers/cast/cast_internal_message_util.cc b/chrome/browser/media/router/providers/cast/cast_internal_message_util.cc index fdab0e0..f62f3977 100644 --- a/chrome/browser/media/router/providers/cast/cast_internal_message_util.cc +++ b/chrome/browser/media/router/providers/cast/cast_internal_message_util.cc
@@ -5,6 +5,7 @@ #include "chrome/browser/media/router/providers/cast/cast_internal_message_util.h" #include <string> +#include <string_view> #include <utility> #include "base/base64url.h" @@ -12,7 +13,6 @@ #include "base/json/json_writer.h" #include "base/memory/ptr_util.h" #include "base/strings/escape.h" -#include "base/strings/string_piece.h" #include "components/media_router/common/discovery/media_sink_internal.h" #include "components/media_router/common/providers/cast/cast_media_source.h" #include "components/media_router/common/providers/cast/channel/cast_device_capability.h" @@ -115,7 +115,7 @@ std::string CastInternalMessageTypeToString(CastInternalMessage::Type type) { auto found = cast_util::EnumToString(type); DCHECK(found); - return std::string(found.value_or(base::StringPiece())); + return std::string(found.value_or(std::string_view())); } // Possible types in a receiver_action message.
diff --git a/chrome/browser/media/router/providers/cast/cast_media_route_provider.cc b/chrome/browser/media/router/providers/cast/cast_media_route_provider.cc index 7c9c33f..67b935e 100644 --- a/chrome/browser/media/router/providers/cast/cast_media_route_provider.cc +++ b/chrome/browser/media/router/providers/cast/cast_media_route_provider.cc
@@ -5,6 +5,7 @@ #include "chrome/browser/media/router/providers/cast/cast_media_route_provider.h" #include <array> +#include <string_view> #include <utility> #include <vector> @@ -43,7 +44,7 @@ constexpr char kLoggerComponent[] = "CastMediaRouteProvider"; // List of origins allowed to use a PresentationRequest to initiate mirroring. -constexpr std::array<base::StringPiece, 3> kPresentationApiAllowlist = { +constexpr std::array<std::string_view, 3> kPresentationApiAllowlist = { "https://docs.google.com", "https://meet.google.com", "https://music.youtube.com",
diff --git a/chrome/browser/media/router/providers/cast/mirroring_activity.cc b/chrome/browser/media/router/providers/cast/mirroring_activity.cc index 2f6e5d7b..988fedb 100644 --- a/chrome/browser/media/router/providers/cast/mirroring_activity.cc +++ b/chrome/browser/media/router/providers/cast/mirroring_activity.cc
@@ -11,6 +11,7 @@ #include <memory> #include <optional> #include <string> +#include <string_view> #include <utility> #include "base/command_line.h" @@ -22,7 +23,6 @@ #include "base/metrics/user_metrics_action.h" #include "base/strings/strcat.h" #include "base/strings/string_number_conversions.h" -#include "base/strings/string_piece.h" #include "base/strings/string_tokenizer.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" @@ -174,7 +174,7 @@ } // TODO(crbug.com/1363512): Remove support for sender side letterboxing. -bool ShouldForceLetterboxing(base::StringPiece model_name) { +bool ShouldForceLetterboxing(std::string_view model_name) { if (base::CommandLine::ForCurrentProcess()->HasSwitch( "disable-cast-letterboxing")) { return false; @@ -255,7 +255,7 @@ } void RecordCastStreamingSenderUma(const base::Value::Dict& all_mirroring_stats, - base::StringPiece stats_dict_key, + std::string_view stats_dict_key, int64_t target_playout_delay) { const base::Value::Dict* mirroring_stats = all_mirroring_stats.FindDict(stats_dict_key);
diff --git a/chrome/browser/media/router/providers/dial/dial_activity_manager.cc b/chrome/browser/media/router/providers/dial/dial_activity_manager.cc index 3e91e9f..41e12f6 100644 --- a/chrome/browser/media/router/providers/dial/dial_activity_manager.cc +++ b/chrome/browser/media/router/providers/dial/dial_activity_manager.cc
@@ -4,6 +4,8 @@ #include "chrome/browser/media/router/providers/dial/dial_activity_manager.h" +#include <string_view> + #include "base/containers/contains.h" #include "base/functional/bind.h" #include "base/ranges/algorithm.h" @@ -88,7 +90,7 @@ // temporary object. for (net::QueryIterator query_it(url); !query_it.IsAtEnd(); query_it.Advance()) { - const base::StringPiece key = query_it.GetKey(); + const std::string_view key = query_it.GetKey(); if (key == "clientId") { client_id = std::string(query_it.GetValue()); } else if (key == "dialPostData") {
diff --git a/chrome/browser/media/webrtc/webrtc_event_log_manager_common.cc b/chrome/browser/media/webrtc/webrtc_event_log_manager_common.cc index 5bac8fe8..e217092 100644 --- a/chrome/browser/media/webrtc/webrtc_event_log_manager_common.cc +++ b/chrome/browser/media/webrtc/webrtc_event_log_manager_common.cc
@@ -5,6 +5,7 @@ #include "chrome/browser/media/webrtc/webrtc_event_log_manager_common.h" #include <limits> +#include <string_view> #include "base/files/file_util.h" #include "base/logging.h" @@ -12,7 +13,6 @@ #include "base/metrics/histogram_functions.h" #include "base/ranges/algorithm.h" #include "base/strings/string_number_conversions.h" -#include "base/strings/string_piece.h" #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" #include "base/task/sequenced_task_runner.h" @@ -736,7 +736,7 @@ // Given a string with a textual representation of a web-app ID, return the // ID in integer form. If the textual representation does not name a valid // web-app ID, return kInvalidWebRtcEventLogWebAppId. -size_t ExtractWebAppId(base::StringPiece str) { +size_t ExtractWebAppId(std::string_view str) { DCHECK_EQ(str.length(), kWebAppIdLength); // Avoid leading '+', etc. @@ -952,7 +952,7 @@ // Expect web-app-ID. const size_t web_app_id = - ExtractWebAppId(base::StringPiece(&filename[index], kWebAppIdLength)); + ExtractWebAppId(std::string_view(&filename[index], kWebAppIdLength)); if (web_app_id == kInvalidWebRtcEventLogWebAppId) { return false; } @@ -1007,7 +1007,7 @@ // The +1 is for the underscore between the prefix and the web-app ID. // Length verified by above call to IsValidRemoteBoundLogFilename(). DCHECK_GE(filename.length(), kPrefixLength + 1 + kWebAppIdLength); - base::StringPiece id_str(&filename[kPrefixLength + 1], kWebAppIdLength); + std::string_view id_str(&filename[kPrefixLength + 1], kWebAppIdLength); return ExtractWebAppId(id_str); }
diff --git a/chrome/browser/media/webrtc/webrtc_rtp_dump_handler_unittest.cc b/chrome/browser/media/webrtc/webrtc_rtp_dump_handler_unittest.cc index 87034b68..d611b81 100644 --- a/chrome/browser/media/webrtc/webrtc_rtp_dump_handler_unittest.cc +++ b/chrome/browser/media/webrtc/webrtc_rtp_dump_handler_unittest.cc
@@ -8,6 +8,7 @@ #include <stdint.h> #include <memory> +#include <string_view> #include <utility> #include "base/files/file_util.h" @@ -98,9 +99,9 @@ *outgoing_dump = dir.AppendASCII("send"); const char dummy[] = "dummy"; EXPECT_TRUE(base::WriteFile(*incoming_dump, - base::StringPiece(dummy, std::size(dummy)))); + std::string_view(dummy, std::size(dummy)))); EXPECT_TRUE(base::WriteFile(*outgoing_dump, - base::StringPiece(dummy, std::size(dummy)))); + std::string_view(dummy, std::size(dummy)))); } void FlushTaskRunners() {
diff --git a/chrome/browser/media/webrtc/webrtc_text_log_handler.cc b/chrome/browser/media/webrtc/webrtc_text_log_handler.cc index 551b258..e47856d 100644 --- a/chrome/browser/media/webrtc/webrtc_text_log_handler.cc +++ b/chrome/browser/media/webrtc/webrtc_text_log_handler.cc
@@ -7,6 +7,7 @@ #include <map> #include <memory> #include <string> +#include <string_view> #include <utility> #include <vector> @@ -479,7 +480,7 @@ #if BUILDFLAG(IS_MAC) computer_model = base::SysInfo::HardwareModelName(); #elif BUILDFLAG(IS_CHROMEOS_ASH) - if (const std::optional<base::StringPiece> computer_model_statistic = + if (const std::optional<std::string_view> computer_model_statistic = ash::system::StatisticsProvider::GetInstance()->GetMachineStatistic( ash::system::kHardwareClassKey)) { computer_model = std::string(computer_model_statistic.value());
diff --git a/chrome/browser/new_tab_page/new_tab_page_interactive_uitest.cc b/chrome/browser/new_tab_page/new_tab_page_interactive_uitest.cc index 4a5d053..6b5fe6c 100644 --- a/chrome/browser/new_tab_page/new_tab_page_interactive_uitest.cc +++ b/chrome/browser/new_tab_page/new_tab_page_interactive_uitest.cc
@@ -219,12 +219,7 @@ // Win11 Tests x64. // TODO(crbug.com/1416880): It's also found flaky on Linux Tests, Linux Tests // (Wayland), linux-lacros-tester-rel, Mac12 Tests. -#if BUILDFLAG(IS_CHROMEOS_LACROS) -#define MAYBE_LandingPagePixelTest DISABLED_LandingPagePixelTest -#else -#define MAYBE_LandingPagePixelTest LandingPagePixelTest -#endif -IN_PROC_BROWSER_TEST_F(NewTabPageTest, MAYBE_LandingPagePixelTest) { +IN_PROC_BROWSER_TEST_F(NewTabPageTest, DISABLED_LandingPagePixelTest) { WaitForLazyLoad(); // By default WaitForNetworkLoad waits for all resources that have started // loading at this point. However, sometimes not all required resources have
diff --git a/chrome/browser/password_manager/android/password_store_android_account_backend.cc b/chrome/browser/password_manager/android/password_store_android_account_backend.cc index 4c12b38..9d17b6c 100644 --- a/chrome/browser/password_manager/android/password_store_android_account_backend.cc +++ b/chrome/browser/password_manager/android/password_store_android_account_backend.cc
@@ -15,6 +15,7 @@ #include "components/password_manager/core/browser/affiliation/affiliations_prefetcher.h" #include "components/password_manager/core/browser/features/password_features.h" #include "components/password_manager/core/browser/password_store/get_logins_with_affiliations_request_handler.h" +#include "components/password_manager/core/browser/password_store/password_model_type_controller_delegate_android.h" #include "components/password_manager/core/browser/password_store/password_store_backend_error.h" #include "components/password_manager/core/browser/password_store/password_store_backend_metrics_recorder.h" #include "components/password_manager/core/browser/password_store/split_stores_and_local_upm.h" @@ -358,7 +359,15 @@ std::unique_ptr<syncer::ProxyModelTypeControllerDelegate> PasswordStoreAndroidAccountBackend::CreateSyncControllerDelegate() { - return sync_controller_delegate_->CreateProxyModelControllerDelegate(); + // TODO: crbug.com/321220529 - Return + // PasswordModelTypeConrollerDelegateAndroid directly. + std::unique_ptr<PasswordModelTypeConrollerDelegateAndroid> delegate = + std::make_unique<PasswordModelTypeConrollerDelegateAndroid>(); + return std::make_unique<syncer::ProxyModelTypeControllerDelegate>( + base::SequencedTaskRunner::GetCurrentDefault(), + base::BindRepeating( + &PasswordModelTypeConrollerDelegateAndroid::GetWeakPtrToBaseClass, + std::move(delegate))); } SmartBubbleStatsStore*
diff --git a/chrome/browser/password_manager/android/password_store_android_account_backend.h b/chrome/browser/password_manager/android/password_store_android_account_backend.h index da42b976..ec8d552 100644 --- a/chrome/browser/password_manager/android/password_store_android_account_backend.h +++ b/chrome/browser/password_manager/android/password_store_android_account_backend.h
@@ -120,7 +120,7 @@ raw_ptr<AffiliatedMatchHelper> affiliated_match_helper_ = nullptr; raw_ptr<syncer::SyncService> sync_service_ = nullptr; - // Delegate to handle sync events. + // Legacy delegate to handle sync events. std::unique_ptr<PasswordSyncControllerDelegateAndroid> sync_controller_delegate_;
diff --git a/chrome/browser/password_manager/android/password_sync_controller_delegate_android.cc b/chrome/browser/password_manager/android/password_sync_controller_delegate_android.cc index 445c646b..dc3bedf0 100644 --- a/chrome/browser/password_manager/android/password_sync_controller_delegate_android.cc +++ b/chrome/browser/password_manager/android/password_sync_controller_delegate_android.cc
@@ -11,10 +11,6 @@ #include "components/password_manager/core/browser/password_store/android_backend_error.h" #include "components/password_manager/core/browser/password_sync_util.h" #include "components/signin/public/identity_manager/account_info.h" -#include "components/sync/engine/data_type_activation_response.h" -#include "components/sync/model/model_type_controller_delegate.h" -#include "components/sync/model/proxy_model_type_controller_delegate.h" -#include "components/sync/model/type_entities_count.h" #include "components/sync/service/sync_service.h" namespace password_manager { @@ -49,77 +45,12 @@ on_sync_shutdown_ = std::move(on_sync_shutdown); } -std::unique_ptr<syncer::ProxyModelTypeControllerDelegate> -PasswordSyncControllerDelegateAndroid::CreateProxyModelControllerDelegate() { - return std::make_unique<syncer::ProxyModelTypeControllerDelegate>( - base::SequencedTaskRunner::GetCurrentDefault(), - base::BindRepeating( - &PasswordSyncControllerDelegateAndroid::GetWeakPtrToBaseClass, - base::Unretained(this))); -} - void PasswordSyncControllerDelegateAndroid::OnSyncServiceInitialized( syncer::SyncService* sync_service) { sync_observation_.Observe(sync_service); - // TODO(crbug.com/40067770): Migrate away from `ConsentLevel::kSync` on - // Android. UpdateCredentialManagerSyncStatus(sync_service); } -void PasswordSyncControllerDelegateAndroid::OnSyncStarting( - const syncer::DataTypeActivationRequest& request, - StartCallback callback) { - // Set |skip_engine_connection| to true to indicate that, actually, this sync - // datatype doesn't depend on the built-in SyncEngine to communicate changes - // to/from the Sync server. Instead, Android specific functionality is - // leveraged to achieve similar behavior. - auto activation_response = - std::make_unique<syncer::DataTypeActivationResponse>(); - activation_response->skip_engine_connection = true; - std::move(callback).Run(std::move(activation_response)); -} - -void PasswordSyncControllerDelegateAndroid::OnSyncStopping( - syncer::SyncStopMetadataFate metadata_fate) { - switch (metadata_fate) { - case syncer::KEEP_METADATA: - // Sync got temporarily paused. Just ignore. - break; - case syncer::CLEAR_METADATA: - // The user (or something equivalent like an enterprise policy) - // permanently disrabled sync, either fully or specifically for passwords. - // This also includes more advanced cases like the user having cleared all - // sync data in the dashboard (birthday reset) or, at least in theory, the - // sync server reporting that all sync metadata is obsolete (i.e. - // CLIENT_DATA_OBSOLETE in the sync protocol). - // TODO(crbug.com/1312392): Sync was disabled. Move passwords from syncing - // storage to local storage. - NOTIMPLEMENTED(); - break; - } -} - -void PasswordSyncControllerDelegateAndroid::GetAllNodesForDebugging( - AllNodesCallback callback) { - // This is not implemented because it's not worth the hassle just to display - // debug information in chrome://sync-internals. - std::move(callback).Run(syncer::PASSWORDS, base::Value::List()); -} - -void PasswordSyncControllerDelegateAndroid::GetTypeEntitiesCountForDebugging( - base::OnceCallback<void(const syncer::TypeEntitiesCount&)> callback) const { - // This is not implemented because it's not worth the hassle just to display - // debug information in chrome://sync-internals. - std::move(callback).Run(syncer::TypeEntitiesCount(syncer::PASSWORDS)); -} - -void PasswordSyncControllerDelegateAndroid:: - RecordMemoryUsageAndCountsHistograms() { - // This is not implemented because it's not worth the hassle. Password sync - // module on Android doesn't hold any password. Instead passwords are - // requested on demand from the GMS Core. -} - void PasswordSyncControllerDelegateAndroid::OnStateChanged( syncer::SyncService* sync) { UpdateCredentialManagerSyncStatus(sync); @@ -176,18 +107,4 @@ } } -base::WeakPtr<syncer::ModelTypeControllerDelegate> -PasswordSyncControllerDelegateAndroid::GetWeakPtrToBaseClass() { - return weak_ptr_factory_.GetWeakPtr(); -} - -void PasswordSyncControllerDelegateAndroid::ClearMetadataIfStopped() { - // No metadata is managed by PasswordSyncControllerDelegateAndroid. -} - -void PasswordSyncControllerDelegateAndroid::ReportBridgeErrorForTest() { - // Not supported for Android. - NOTREACHED(); -} - } // namespace password_manager
diff --git a/chrome/browser/password_manager/android/password_sync_controller_delegate_android.h b/chrome/browser/password_manager/android/password_sync_controller_delegate_android.h index 8b6c6559..e8e9f9e 100644 --- a/chrome/browser/password_manager/android/password_sync_controller_delegate_android.h +++ b/chrome/browser/password_manager/android/password_sync_controller_delegate_android.h
@@ -16,19 +16,15 @@ #include "base/types/strong_alias.h" #include "chrome/browser/password_manager/android/password_sync_controller_delegate_bridge.h" #include "components/password_manager/core/browser/password_store/password_store_backend.h" -#include "components/sync/model/model_type_controller_delegate.h" #include "components/sync/service/sync_service.h" #include "components/sync/service/sync_service_observer.h" -namespace syncer { -class ModelTypeControllerDelegate; -} // namespace syncer - namespace password_manager { +// TODO: crbug.com/321220529 - Rename this class to indicate that it will be +// used only for recording metrics. class PasswordSyncControllerDelegateAndroid - : public syncer::ModelTypeControllerDelegate, - public syncer::SyncServiceObserver, + : public syncer::SyncServiceObserver, public PasswordSyncControllerDelegateBridge::Consumer { public: using IsPwdSyncEnabled = base::StrongAlias<struct IsPwdSyncEnabledTag, bool>; @@ -55,18 +51,6 @@ // Sets a callback to be called when the sync service is being shut down. void SetSyncShutdownCallback(base::OnceClosure(on_sync_shutdown)); - // syncer::ModelTypeControllerDelegate implementation - void OnSyncStarting(const syncer::DataTypeActivationRequest& request, - StartCallback callback) override; - void OnSyncStopping(syncer::SyncStopMetadataFate metadata_fate) override; - void GetAllNodesForDebugging(AllNodesCallback callback) override; - void GetTypeEntitiesCountForDebugging( - base::OnceCallback<void(const syncer::TypeEntitiesCount&)> callback) - const override; - void RecordMemoryUsageAndCountsHistograms() override; - void ClearMetadataIfStopped() override; - void ReportBridgeErrorForTest() override; - // syncer::SyncServiceObserver implementation. void OnStateChanged(syncer::SyncService* sync) override; void OnSyncShutdown(syncer::SyncService* sync) override; @@ -76,9 +60,6 @@ void OnCredentialManagerError(const AndroidBackendError& error, int api_error_code) override; - std::unique_ptr<syncer::ProxyModelTypeControllerDelegate> - CreateProxyModelControllerDelegate(); - // Updates |is_sync_enabled| to hold the initial sync setting. void OnSyncServiceInitialized(syncer::SyncService* sync_service); @@ -87,8 +68,6 @@ // password sync setting has changed. void UpdateCredentialManagerSyncStatus(syncer::SyncService* sync_service); - base::WeakPtr<syncer::ModelTypeControllerDelegate> GetWeakPtrToBaseClass(); - const std::unique_ptr<PasswordSyncControllerDelegateBridge> bridge_; // Last sync status set in CredentialManager.
diff --git a/chrome/browser/password_manager/chrome_webauthn_credentials_delegate_unittest.cc b/chrome/browser/password_manager/chrome_webauthn_credentials_delegate_unittest.cc index 6cad7a1f..ea69392 100644 --- a/chrome/browser/password_manager/chrome_webauthn_credentials_delegate_unittest.cc +++ b/chrome/browser/password_manager/chrome_webauthn_credentials_delegate_unittest.cc
@@ -220,8 +220,8 @@ #if !BUILDFLAG(IS_ANDROID) base::RunLoop run_loop; dialog_model()->SetAccountPreselectedCallback(base::BindLambdaForTesting( - [&](device::PublicKeyCredentialDescriptor cred) { - EXPECT_THAT(cred.id, testing::ElementsAreArray(kCredId2)); + [&](device::DiscoverableCredentialMetadata cred) { + EXPECT_THAT(cred.cred_id, testing::ElementsAreArray(kCredId2)); run_loop.Quit(); })); #endif
diff --git a/chrome/browser/pdf/pdf_extension_accessibility_test.cc b/chrome/browser/pdf/pdf_extension_accessibility_test.cc index 29fc3f77..776b98b 100644 --- a/chrome/browser/pdf/pdf_extension_accessibility_test.cc +++ b/chrome/browser/pdf/pdf_extension_accessibility_test.cc
@@ -428,13 +428,6 @@ GTEST_SKIP(); } - // TODO(accessibility): Forcing renderer accessibility means the accessibility - // tree updates in a way unexpected by the test. - if (base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kForceRendererAccessibility)) { - GTEST_SKIP(); - } - ASSERT_TRUE( LoadPdf(embedded_test_server()->GetURL("/pdf/test-bookmarks.pdf"))); @@ -445,8 +438,8 @@ "{type: 'selectAll'});")); content::ScopedAccessibilityModeOverride mode_override(ui::kAXModeComplete); - WaitForAccessibilityTreeToContainNodeWithName(contents, - "1 First Section\r\n"); + WaitForAccessibilityTreeToContainSelection(contents, "1 First Section\r\n", + "3"); ui::AXTreeUpdate ax_tree_update = GetAccessibilityTreeSnapshotForPdf(contents); ui::AXTree ax_tree(ax_tree_update); @@ -487,12 +480,6 @@ GTEST_SKIP(); } - // TODO(accessibility): Forcing renderer accessibility means the accessibility - // tree updates in a way unexpected by the test. - if (base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kForceRendererAccessibility)) { - GTEST_SKIP(); - } // Validate the context menu arguments for PDF selection when context menu is // invoked via accessibility tree. const char kExepectedPDFSelection[] = @@ -519,8 +506,8 @@ "{type: 'selectAll'});")); content::ScopedAccessibilityModeOverride mode_override(ui::kAXModeComplete); - WaitForAccessibilityTreeToContainNodeWithName(contents, - "1 First Section\r\n"); + WaitForAccessibilityTreeToContainSelection(contents, "1 First Section\r\n", + "3"); // Find pdfRoot node in the accessibility tree. content::FindAccessibilityNodeCriteria find_criteria; @@ -1328,7 +1315,7 @@ if (IsLibraryAvailable()) { screen_ai::ScreenAIInstallState::GetInstance()->SetComponentFolder( - screen_ai::GetLatestComponentBinaryPath().DirName()); + screen_ai::GetComponentBinaryPathForTests().DirName()); } else { // Set an observer to mark download as failed when requested. component_download_observer_.Observe(
diff --git a/chrome/browser/permissions/permission_manager_browsertest.cc b/chrome/browser/permissions/permission_manager_browsertest.cc index 29f54c58..8edef722b 100644 --- a/chrome/browser/permissions/permission_manager_browsertest.cc +++ b/chrome/browser/permissions/permission_manager_browsertest.cc
@@ -127,7 +127,7 @@ } // TODO(crbug.com/329645039): Re-enable this test once fixed -#if BUILDFLAG(IS_MAC) +#if BUILDFLAG(IS_MAC) || (BUILDFLAG(IS_CHROMEOS_ASH) && !defined(NDEBUG)) #define MAYBE_ServiceWorkerPermissionAfterRendererCrash \ DISABLED_ServiceWorkerPermissionAfterRendererCrash #else
diff --git a/chrome/browser/policy/configuration_policy_handler_list_factory.cc b/chrome/browser/policy/configuration_policy_handler_list_factory.cc index b22197de8..1765f50 100644 --- a/chrome/browser/policy/configuration_policy_handler_list_factory.cc +++ b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
@@ -360,6 +360,9 @@ { key::kHttpAllowlist, prefs::kHttpAllowlist, base::Value::Type::LIST }, + { key::kPrivacySandboxFingerprintingProtectionEnabled, + prefs::kFingerprintingProtectionEnabled, + base::Value::Type::BOOLEAN }, { key::kHttpsUpgradesEnabled, prefs::kHttpsUpgradesEnabled, base::Value::Type::BOOLEAN },
diff --git a/chrome/browser/privacy_sandbox/privacy_sandbox_notice_confirmation.cc b/chrome/browser/privacy_sandbox/privacy_sandbox_notice_confirmation.cc new file mode 100644 index 0000000..a35ab140 --- /dev/null +++ b/chrome/browser/privacy_sandbox/privacy_sandbox_notice_confirmation.cc
@@ -0,0 +1,84 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/privacy_sandbox/privacy_sandbox_notice_confirmation.h" + +#include "base/containers/fixed_flat_set.h" +#include "base/metrics/histogram_functions.h" +#include "chrome/browser/browser_process.h" +#include "components/privacy_sandbox/privacy_sandbox_features.h" +#include "components/variations/service/variations_service.h" +#include "components/variations/service/variations_service_utils.h" + +namespace privacy_sandbox { + +namespace { + +constexpr auto kConsentCountries = base::MakeFixedFlatSet<std::string_view>({ + "gb", "at", "ax", "be", "bg", "bl", "ch", "cy", "cz", "de", "dk", + "ee", "es", "fi", "fr", "gf", "gg", "gi", "gp", "gr", "hr", "hu", + "ie", "is", "it", "je", "ke", "li", "lt", "lu", "lv", "mf", "mt", + "mq", "nc", "nl", "no", "pf", "pl", "pm", "pt", "qa", "re", "ro", + "se", "si", "sk", "sj", "tf", "va", "wf", "yt", +}); + +enum class ConfirmationType { Notice, Consent }; + +bool IsFeatureParamEnabled(ConfirmationType confirmation_type) { + switch (confirmation_type) { + case ConfirmationType::Notice: + return privacy_sandbox::kPrivacySandboxSettings4NoticeRequired.Get(); + case ConfirmationType::Consent: + return privacy_sandbox::kPrivacySandboxSettings4ConsentRequired.Get(); + } +} + +void EmitHistogram(ConfirmationType confirmation_type, bool value) { + switch (confirmation_type) { + case ConfirmationType::Notice: + return base::UmaHistogramBoolean( + "Settings.PrivacySandbox.NoticeCheckIsMismatched", value); + case ConfirmationType::Consent: + return base::UmaHistogramBoolean( + "Settings.PrivacySandbox.ConsentCheckIsMismatched", value); + } +} + +template <typename FilterFunction> +bool IsConfirmationRequired(ConfirmationType confirmation_type, + FilterFunction filter_function) { + CHECK(g_browser_process); + bool is_confirmation_required = + privacy_sandbox::kPrivacySandboxSettings4.default_state == + base::FEATURE_ENABLED_BY_DEFAULT && + g_browser_process->variations_service() && + filter_function(variations::GetCurrentCountryCode( + g_browser_process->variations_service())); + + if (base::FeatureList::GetInstance()->IsFeatureOverridden( + privacy_sandbox::kPrivacySandboxSettings4.name)) { + bool is_confirmation_required_override = + IsFeatureParamEnabled(confirmation_type); + EmitHistogram(confirmation_type, is_confirmation_required != + is_confirmation_required_override); + return is_confirmation_required_override; + } + return is_confirmation_required; +} + +} // namespace + +bool IsConsentRequired() { + return IsConfirmationRequired( + ConfirmationType::Consent, + [](std::string_view c) { return kConsentCountries.contains(c); }); +} + +bool IsNoticeRequired() { + return IsConfirmationRequired( + ConfirmationType::Notice, + [](std::string_view c) { return !kConsentCountries.contains(c); }); +} + +} // namespace privacy_sandbox
diff --git a/chrome/browser/privacy_sandbox/privacy_sandbox_notice_confirmation.h b/chrome/browser/privacy_sandbox/privacy_sandbox_notice_confirmation.h new file mode 100644 index 0000000..268b060 --- /dev/null +++ b/chrome/browser/privacy_sandbox/privacy_sandbox_notice_confirmation.h
@@ -0,0 +1,38 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_PRIVACY_SANDBOX_PRIVACY_SANDBOX_NOTICE_CONFIRMATION_H_ +#define CHROME_BROWSER_PRIVACY_SANDBOX_PRIVACY_SANDBOX_NOTICE_CONFIRMATION_H_ + +namespace privacy_sandbox { + +/** + * Determines whether Privacy Sandbox Ads consent is required. + * + * This function checks a collection of conditions to determine if the permanent + * variation country is in a region where obtaining consent for the Privacy + * Sandbox is necessary. It also considers feature flags and overrides that + * might influence the consent requirement. + * + * Returns `true` if user consent is required for Privacy Sandbox features, + * `false` otherwise. + * + */ +bool IsConsentRequired(); + +/** + * Determines whether a the Privay Sandbox Ads notice is required. + * + * This function evaluates several criteria related to the Privacy Sandbox + * feature, the permanent variation country, and potential feature overrides to + * decide if a notice is necessary. + * + * Returns `true` if a privacy notice should be displayed, `false` otherwise. + * + */ +bool IsNoticeRequired(); + +} // namespace privacy_sandbox + +#endif // CHROME_BROWSER_PRIVACY_SANDBOX_PRIVACY_SANDBOX_NOTICE_CONFIRMATION_H_
diff --git a/chrome/browser/privacy_sandbox/privacy_sandbox_notice_confirmation_browsertest.cc b/chrome/browser/privacy_sandbox/privacy_sandbox_notice_confirmation_browsertest.cc new file mode 100644 index 0000000..f2d3fa8 --- /dev/null +++ b/chrome/browser/privacy_sandbox/privacy_sandbox_notice_confirmation_browsertest.cc
@@ -0,0 +1,226 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/test/metrics/histogram_tester.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/privacy_sandbox/privacy_sandbox_notice_confirmation.h" +#include "chrome/test/base/in_process_browser_test.h" +#include "components/privacy_sandbox/privacy_sandbox_features.h" +#include "components/variations/service/variations_service.h" +#include "components/variations/variations_switches.h" +#include "content/public/test/browser_test.h" + +namespace privacy_sandbox { +namespace { + +struct PrivacySandboxConfirmationTestData { + // Inputs + std::vector<base::test::FeatureRefAndParams> enabled_features; + std::vector<base::test::FeatureRef> disabled_features; + std::string variation_country; + // Expectations + bool expect_required; + bool expect_mismatch_histogram_true; + bool expect_mismatch_histogram_false; +}; + +class PrivacySandboxConfirmationTestBase + : public InProcessBrowserTest, + public testing::WithParamInterface<PrivacySandboxConfirmationTestData> { + public: + PrivacySandboxConfirmationTestBase() { + // Disabling the field trial testing config explicitly as some tests here + // are specifically for when the feature isn't overridden. + base::CommandLine::ForCurrentProcess()->AppendSwitch( + variations::switches::kDisableFieldTrialTestingConfig); + feature_list_.InitWithFeaturesAndParameters(GetParam().enabled_features, + GetParam().disabled_features); + } + + private: + base::test::ScopedFeatureList feature_list_; +}; + +class PrivacySandboxConsentConfirmationTest + : public PrivacySandboxConfirmationTestBase {}; + +base::test::FeatureRefAndParams ConsentFeature() { + return {kPrivacySandboxSettings4, + {{kPrivacySandboxSettings4ConsentRequiredName, "true"}}}; +} + +IN_PROC_BROWSER_TEST_P(PrivacySandboxConsentConfirmationTest, ConsentTest) { + // Setup + base::HistogramTester histogram_tester; + g_browser_process->variations_service()->OverrideStoredPermanentCountry( + GetParam().variation_country); + + EXPECT_EQ(IsConsentRequired(), GetParam().expect_required); + histogram_tester.ExpectBucketCount( + "Settings.PrivacySandbox.ConsentCheckIsMismatched", true, + GetParam().expect_mismatch_histogram_true); + histogram_tester.ExpectBucketCount( + "Settings.PrivacySandbox.ConsentCheckIsMismatched", false, + GetParam().expect_mismatch_histogram_false); +} + +INSTANTIATE_TEST_SUITE_P( + , + PrivacySandboxConsentConfirmationTest, + testing::Values( + // 1. GB + // 1.1 GB - Feature Overridden, Consent param set to true. + PrivacySandboxConfirmationTestData{ + .enabled_features = {ConsentFeature()}, + .variation_country = "gb", + // Expectations + .expect_required = true, + .expect_mismatch_histogram_false = true, + }, + // 1.2 GB - Feature Overridden. consent param not set. + PrivacySandboxConfirmationTestData{ + .enabled_features = {{kPrivacySandboxSettings4, {{}}}}, + .variation_country = "gb", + // Expectations + .expect_required = false, + .expect_mismatch_histogram_true = true, + }, + // 1.3 GB - Feature Explicitly Disabled. + PrivacySandboxConfirmationTestData{ + .disabled_features = {kPrivacySandboxSettings4}, + .variation_country = "gb", + // Expectations + .expect_required = false, + .expect_mismatch_histogram_true = true, + }, + // 1.4 GB - Feature Not Set. + PrivacySandboxConfirmationTestData{ + .variation_country = "gb", + // Expectations + .expect_required = true, + }, + // 2. US + // 2.1 US - Feature Overridden, Consent param set to true. + PrivacySandboxConfirmationTestData{ + .enabled_features = {ConsentFeature()}, + .variation_country = "us", + // Expectations + .expect_required = true, + .expect_mismatch_histogram_true = true, + }, + // 2.2 GB - Feature Overridden. consent param not set. + PrivacySandboxConfirmationTestData{ + .enabled_features = {{kPrivacySandboxSettings4, {{}}}}, + .variation_country = "us", + // Expectations + .expect_required = false, + .expect_mismatch_histogram_false = true, + }, + // 2.3 GB - Feature Explicitly Disabled. + PrivacySandboxConfirmationTestData{ + .disabled_features = {kPrivacySandboxSettings4}, + .variation_country = "us", + // Expectations + .expect_required = false, + .expect_mismatch_histogram_false = true, + }, + // 2.4 GB - Feature Not Set. + PrivacySandboxConfirmationTestData{ + .variation_country = "us", + // Expectations + .expect_required = false, + })); + +class PrivacySandboxNoticeConfirmationTest + : public PrivacySandboxConfirmationTestBase {}; + +base::test::FeatureRefAndParams NoticeFeature() { + return {kPrivacySandboxSettings4, + {{kPrivacySandboxSettings4NoticeRequiredName, "true"}}}; +} + +IN_PROC_BROWSER_TEST_P(PrivacySandboxNoticeConfirmationTest, NoticeTest) { + // Setup + base::HistogramTester histogram_tester; + g_browser_process->variations_service()->OverrideStoredPermanentCountry( + GetParam().variation_country); + + EXPECT_EQ(IsNoticeRequired(), GetParam().expect_required); + histogram_tester.ExpectBucketCount( + "Settings.PrivacySandbox.NoticeCheckIsMismatched", true, + GetParam().expect_mismatch_histogram_true); + histogram_tester.ExpectBucketCount( + "Settings.PrivacySandbox.NoticeCheckIsMismatched", false, + GetParam().expect_mismatch_histogram_false); +} + +INSTANTIATE_TEST_SUITE_P( + , + PrivacySandboxNoticeConfirmationTest, + testing::Values( + // 1. GB + // 1.1 GB - Feature Overridden, Notice param set to true. + PrivacySandboxConfirmationTestData{ + .enabled_features = {NoticeFeature()}, + .variation_country = "gb", + // Expectations + .expect_required = true, + .expect_mismatch_histogram_true = true, + }, + // 1.2 GB - Feature Overridden. notice param not set. + PrivacySandboxConfirmationTestData{ + .enabled_features = {{kPrivacySandboxSettings4, {{}}}}, + .variation_country = "gb", + // Expectations + .expect_required = false, + .expect_mismatch_histogram_false = true, + }, + // 1.3 GB - Feature Explicitly Disabled. + PrivacySandboxConfirmationTestData{ + .disabled_features = {kPrivacySandboxSettings4}, + .variation_country = "gb", + // Expectations + .expect_required = false, + .expect_mismatch_histogram_false = true, + }, + // 1.4 GB - Feature Not Set. + PrivacySandboxConfirmationTestData{ + .variation_country = "gb", + // Expectations + .expect_required = false, + }, + // 2. US + // 2.1 US - Feature Overridden, notice param set to true. + PrivacySandboxConfirmationTestData{ + .enabled_features = {NoticeFeature()}, + .variation_country = "us", + // Expectations + .expect_required = true, + .expect_mismatch_histogram_false = true, + }, + // 2.2 US - Feature Overridden. notice param not set. + PrivacySandboxConfirmationTestData{ + .enabled_features = {{kPrivacySandboxSettings4, {{}}}}, + .variation_country = "us", + // Expectations + .expect_required = false, + .expect_mismatch_histogram_true = true, + }, + // 2.3 US - Feature Explicitly Disabled. + PrivacySandboxConfirmationTestData{ + .disabled_features = {kPrivacySandboxSettings4}, + .variation_country = "us", + // Expectations + .expect_required = false, + .expect_mismatch_histogram_true = true, + }, + // 2.4 US - Feature Not Set. + PrivacySandboxConfirmationTestData{ + .variation_country = "us", + // Expectations + .expect_required = true, + })); + +} // namespace +} // namespace privacy_sandbox
diff --git a/chrome/browser/privacy_sandbox/privacy_sandbox_service_impl.cc b/chrome/browser/privacy_sandbox/privacy_sandbox_service_impl.cc index 70de39f..5d04445 100644 --- a/chrome/browser/privacy_sandbox/privacy_sandbox_service_impl.cc +++ b/chrome/browser/privacy_sandbox/privacy_sandbox_service_impl.cc
@@ -19,6 +19,7 @@ #include "base/time/time.h" #include "base/types/optional_util.h" #include "build/branding_buildflags.h" +#include "chrome/browser/privacy_sandbox/privacy_sandbox_notice_confirmation.h" #include "chrome/common/webui_url_constants.h" #include "chromeos/components/mgs/managed_guest_session_utils.h" #include "components/browsing_topics/browsing_topics_service.h" @@ -334,7 +335,7 @@ InformSentimentService(action); if (PromptAction::kNoticeAcknowledge == action || PromptAction::kNoticeOpenSettings == action) { - if (privacy_sandbox::kPrivacySandboxSettings4ConsentRequired.Get()) { + if (privacy_sandbox::IsConsentRequired()) { pref_service_->SetBoolean(prefs::kPrivacySandboxM1EEANoticeAcknowledged, true); // It's possible the user is seeing this notice as part of an upgrade to @@ -347,7 +348,7 @@ true); } } else { - DCHECK(privacy_sandbox::kPrivacySandboxSettings4NoticeRequired.Get()); + DCHECK(privacy_sandbox::IsNoticeRequired()); pref_service_->SetBoolean(prefs::kPrivacySandboxM1RowNoticeAcknowledged, true); pref_service_->SetBoolean(prefs::kPrivacySandboxM1TopicsEnabled, true); @@ -359,14 +360,14 @@ MaybeCloseOpenPrompts(); #endif // !BUILDFLAG(IS_ANDROID) } else if (PromptAction::kConsentAccepted == action) { - DCHECK(privacy_sandbox::kPrivacySandboxSettings4ConsentRequired.Get()); + DCHECK(privacy_sandbox::IsConsentRequired()); pref_service_->SetBoolean(prefs::kPrivacySandboxM1ConsentDecisionMade, true); pref_service_->SetBoolean(prefs::kPrivacySandboxM1TopicsEnabled, true); RecordUpdatedTopicsConsent( privacy_sandbox::TopicsConsentUpdateSource::kConfirmation, true); } else if (PromptAction::kConsentDeclined == action) { - DCHECK(privacy_sandbox::kPrivacySandboxSettings4ConsentRequired.Get()); + DCHECK(privacy_sandbox::IsConsentRequired()); pref_service_->SetBoolean(prefs::kPrivacySandboxM1ConsentDecisionMade, true); pref_service_->SetBoolean(prefs::kPrivacySandboxM1TopicsEnabled, false); @@ -726,7 +727,7 @@ } // EEA - if (privacy_sandbox::kPrivacySandboxSettings4ConsentRequired.Get()) { + if (privacy_sandbox::IsConsentRequired()) { // Consent decision not made if (!pref_service_->GetBoolean( prefs::kPrivacySandboxM1ConsentDecisionMade)) { @@ -754,7 +755,7 @@ } // ROW - if (privacy_sandbox::kPrivacySandboxSettings4NoticeRequired.Get()) { + if (privacy_sandbox::IsNoticeRequired()) { base::UmaHistogramEnumeration( privacy_sandbox_prompt_startup_histogram, row_notice_acknowledged ? PromptStartupState::kROWNoticeFlowCompleted @@ -941,7 +942,7 @@ } bool PrivacySandboxServiceImpl::TopicsConsentRequired() const { - return privacy_sandbox::kPrivacySandboxSettings4ConsentRequired.Get(); + return privacy_sandbox::IsConsentRequired(); } bool PrivacySandboxServiceImpl::TopicsHasActiveConsent() const { @@ -1015,14 +1016,14 @@ } // If neither a notice nor a consent is required, do not show a prompt. - if (!privacy_sandbox::kPrivacySandboxSettings4NoticeRequired.Get() && - !privacy_sandbox::kPrivacySandboxSettings4ConsentRequired.Get()) { + if (!privacy_sandbox::IsNoticeRequired() && + !privacy_sandbox::IsConsentRequired()) { return PromptType::kNone; } - // Only one of the consent or notice should be required by Finch parameters. - DCHECK(!privacy_sandbox::kPrivacySandboxSettings4NoticeRequired.Get() || - !privacy_sandbox::kPrivacySandboxSettings4ConsentRequired.Get()); + // Only one of the consent or notice should be required. + DCHECK(!privacy_sandbox::IsNoticeRequired() || + !privacy_sandbox::IsConsentRequired()); // If a prompt was suppressed once, for any reason, it will forever remain // suppressed and a prompt will not be shown. @@ -1058,8 +1059,8 @@ } if (privacy_sandbox::kPrivacySandboxSettings4RestrictedNotice.Get()) { - CHECK(privacy_sandbox::kPrivacySandboxSettings4ConsentRequired.Get() || - privacy_sandbox::kPrivacySandboxSettings4NoticeRequired.Get()); + CHECK(privacy_sandbox::IsConsentRequired() || + privacy_sandbox::IsNoticeRequired()); if (!pref_service->GetBoolean( prefs::kPrivacySandboxM1RestrictedNoticeAcknowledged) && !pref_service->GetBoolean( @@ -1080,7 +1081,7 @@ } } - if (privacy_sandbox::kPrivacySandboxSettings4ConsentRequired.Get()) { + if (privacy_sandbox::IsConsentRequired()) { if (pref_service->GetBoolean(prefs::kPrivacySandboxM1ConsentDecisionMade)) { // Since a consent decision has been made, if the eea notice has already // been acknowledged, do not show a prompt; else, show the eea notice. @@ -1109,7 +1110,7 @@ } } - DCHECK(privacy_sandbox::kPrivacySandboxSettings4NoticeRequired.Get()); + DCHECK(privacy_sandbox::IsNoticeRequired()); // If a user that migrated from EEA to ROW has already completed the EEA // consent and notice flow, set the suppression reason as such and do not show
diff --git a/chrome/browser/privacy_sandbox/privacy_sandbox_settings_delegate.cc b/chrome/browser/privacy_sandbox/privacy_sandbox_settings_delegate.cc index c7348fc..fa6a8481 100644 --- a/chrome/browser/privacy_sandbox/privacy_sandbox_settings_delegate.cc +++ b/chrome/browser/privacy_sandbox/privacy_sandbox_settings_delegate.cc
@@ -16,6 +16,7 @@ #include "build/buildflag.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/content_settings/cookie_settings_factory.h" +#include "chrome/browser/privacy_sandbox/privacy_sandbox_notice_confirmation.h" #include "chrome/browser/privacy_sandbox/tracking_protection_onboarding_factory.h" #include "chrome/browser/privacy_sandbox/tracking_protection_settings_factory.h" #include "chrome/browser/profiles/profile.h" @@ -145,7 +146,7 @@ bool PrivacySandboxSettingsDelegate::HasAppropriateTopicsConsent() const { // If the profile doesn't require a release 4 consent, then it always has // an appropriate (i.e. not required) Topics consent. - if (!privacy_sandbox::kPrivacySandboxSettings4ConsentRequired.Get()) { + if (!privacy_sandbox::IsConsentRequired()) { return true; }
diff --git a/chrome/browser/privacy_sandbox/tracking_protection_policy_handler.cc b/chrome/browser/privacy_sandbox/tracking_protection_policy_handler.cc index 272002c..56c616c 100644 --- a/chrome/browser/privacy_sandbox/tracking_protection_policy_handler.cc +++ b/chrome/browser/privacy_sandbox/tracking_protection_policy_handler.cc
@@ -25,6 +25,7 @@ void TrackingProtectionPolicyHandler::ApplyPolicySettings( const policy::PolicyMap& policies, PrefValueMap* prefs) { + // Handle IPP policy if one exists. const base::Value* ip_protection_enabled = policies.GetValue(policy::key::kPrivacySandboxIpProtectionEnabled, base::Value::Type::BOOLEAN);
diff --git a/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc b/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc index 3159705..cc2983ec 100644 --- a/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc +++ b/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc
@@ -75,6 +75,7 @@ #include "chrome/browser/history/history_service_factory.h" #include "chrome/browser/history/top_sites_factory.h" #include "chrome/browser/history_clusters/history_clusters_service_factory.h" +#include "chrome/browser/history_embeddings/history_embeddings_service_factory.h" #include "chrome/browser/image_service/image_service_factory.h" #include "chrome/browser/ip_protection/ip_protection_config_provider_factory.h" #include "chrome/browser/k_anonymity_service/k_anonymity_service_factory.h" @@ -852,6 +853,7 @@ HistoryClustersModuleServiceFactory::GetInstance(); #endif HistoryClustersServiceFactory::EnsureFactoryBuilt(); + HistoryEmbeddingsServiceFactory::GetInstance(); HistoryServiceFactory::GetInstance(); HistoryUiFaviconRequestHandlerFactory::GetInstance(); HostContentSettingsMapFactory::GetInstance();
diff --git a/chrome/browser/readaloud/android/BUILD.gn b/chrome/browser/readaloud/android/BUILD.gn index 67bb110..c589689 100644 --- a/chrome/browser/readaloud/android/BUILD.gn +++ b/chrome/browser/readaloud/android/BUILD.gn
@@ -16,6 +16,7 @@ "java/src/org/chromium/chrome/browser/readaloud/TapToSeekHandler.java", ] deps = [ + ":exceptions_java", ":hooks_java", ":metrics_java", "//base:base_java", @@ -57,6 +58,18 @@ ] } +android_library("exceptions_java") { + sources = [ + "java/src/org/chromium/chrome/browser/readaloud/exceptions/ReadAloudException.java", + "java/src/org/chromium/chrome/browser/readaloud/exceptions/ReadAloudNetworkException.java", + "java/src/org/chromium/chrome/browser/readaloud/exceptions/ReadAloudUnsupportedException.java", + ] + deps = [ + "//base:base_java", + "//third_party/androidx:androidx_annotation_annotation_java", + ] +} + android_library("metrics_java") { sources = [ "java/src/org/chromium/chrome/browser/readaloud/ReadAloudMetrics.java" ]
diff --git a/chrome/browser/readaloud/android/java/src/org/chromium/chrome/browser/readaloud/exceptions/ReadAloudException.java b/chrome/browser/readaloud/android/java/src/org/chromium/chrome/browser/readaloud/exceptions/ReadAloudException.java new file mode 100644 index 0000000..2b194f51 --- /dev/null +++ b/chrome/browser/readaloud/android/java/src/org/chromium/chrome/browser/readaloud/exceptions/ReadAloudException.java
@@ -0,0 +1,66 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.readaloud.exceptions; + +import androidx.annotation.IntDef; +import androidx.annotation.Nullable; + +/** Base class for ReadAloud exceptions reported from the service. */ +public class ReadAloudException extends Exception { + + private final @ReadAloudErrorCode int mStatusCode; + + public ReadAloudException(String message, @Nullable Throwable cause, int statusCode) { + super(message, cause); + mStatusCode = statusCode; + } + + /** Returns the status code of the error. */ + public @ReadAloudErrorCode int getStatusCode() { + return mStatusCode; + } + + @IntDef({ + ReadAloudErrorCode.OK, + ReadAloudErrorCode.CANCELLED, + ReadAloudErrorCode.UNKNOWN, + ReadAloudErrorCode.INVALID_ARGUMENT, + ReadAloudErrorCode.DEADLINE_EXCEEDED, + ReadAloudErrorCode.NOT_FOUND, + ReadAloudErrorCode.ALREADY_EXISTS, + ReadAloudErrorCode.PERMISSION_DENIED, + ReadAloudErrorCode.UNAUTHENTICATED, + ReadAloudErrorCode.RESOURCE_EXHAUSTED, + ReadAloudErrorCode.FAILED_PRECONDITION, + ReadAloudErrorCode.ABORTED, + ReadAloudErrorCode.OUT_OF_RANGE, + ReadAloudErrorCode.UNIMPLEMENTED, + ReadAloudErrorCode.INTERNAL, + ReadAloudErrorCode.UNAVAILABLE, + ReadAloudErrorCode.DATA_LOSS, + ReadAloudErrorCode.COUNT + }) + // This must be kept in sync with readaloud/enums.xml values + public @interface ReadAloudErrorCode { + int OK = 0; + int CANCELLED = 1; + int UNKNOWN = 2; + int INVALID_ARGUMENT = 3; + int DEADLINE_EXCEEDED = 4; + int NOT_FOUND = 5; + int ALREADY_EXISTS = 6; + int PERMISSION_DENIED = 7; + int UNAUTHENTICATED = 16; + int RESOURCE_EXHAUSTED = 8; + int FAILED_PRECONDITION = 9; + int ABORTED = 10; + int OUT_OF_RANGE = 11; + int UNIMPLEMENTED = 12; + int INTERNAL = 13; + int UNAVAILABLE = 14; + int DATA_LOSS = 15; + int COUNT = 17; + } +}
diff --git a/chrome/browser/readaloud/android/java/src/org/chromium/chrome/browser/readaloud/exceptions/ReadAloudNetworkException.java b/chrome/browser/readaloud/android/java/src/org/chromium/chrome/browser/readaloud/exceptions/ReadAloudNetworkException.java new file mode 100644 index 0000000..b52dbd3 --- /dev/null +++ b/chrome/browser/readaloud/android/java/src/org/chromium/chrome/browser/readaloud/exceptions/ReadAloudNetworkException.java
@@ -0,0 +1,26 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.readaloud.exceptions; + +import org.chromium.chrome.browser.readaloud.exceptions.ReadAloudException.ReadAloudErrorCode; + +/** Represents a ReadAloud error caused by network issues */ +public class ReadAloudNetworkException extends ReadAloudException { + + private int mChromeErrorCode; + + public ReadAloudNetworkException(int chromeErrorCode, @ReadAloudErrorCode int canonicalCode) { + super("Chrome network error code: " + chromeErrorCode, null, canonicalCode); + mChromeErrorCode = chromeErrorCode; + } + + /** + * An error code with negative value defined in: + * https://source.chromium.org/chromium/chromium/src/+/main:net/base/net_error_list.h + */ + public int getChromeErrorCode() { + return mChromeErrorCode; + } +}
diff --git a/chrome/browser/readaloud/android/java/src/org/chromium/chrome/browser/readaloud/exceptions/ReadAloudUnsupportedException.java b/chrome/browser/readaloud/android/java/src/org/chromium/chrome/browser/readaloud/exceptions/ReadAloudUnsupportedException.java new file mode 100644 index 0000000..f415f497 --- /dev/null +++ b/chrome/browser/readaloud/android/java/src/org/chromium/chrome/browser/readaloud/exceptions/ReadAloudUnsupportedException.java
@@ -0,0 +1,90 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.readaloud.exceptions; + +import androidx.annotation.IntDef; +import androidx.annotation.Nullable; + +import org.chromium.chrome.browser.readaloud.exceptions.ReadAloudException.ReadAloudErrorCode; + +/** A ReadAloudException representing an issue with readability. */ +public class ReadAloudUnsupportedException extends ReadAloudException { + + @IntDef({ + RejectionReason.UNKNOWN_REJECTION_REASON, RejectionReason.PAGE_DOWNLOAD_FAILURE, + RejectionReason.UNSUPPORTED_VOICE, RejectionReason.UNSUPPORTED_LANGUAGE, + RejectionReason.PAYWALL, RejectionReason.PORN, RejectionReason.VIDEO, + RejectionReason.NON_ARTICLE, + RejectionReason.TEXT_TOO_SHORT, RejectionReason.NON_TEXTUAL, + RejectionReason.UNSUPPORTED_ARTICLE_QUALITY, RejectionReason.URL_BLACKLISTED, + RejectionReason.CONTENT_TOO_LARGE, RejectionReason.INVALID_URL, + RejectionReason.DISALLOWED_FOR_READOUT, RejectionReason.BAD_REQUEST, + RejectionReason.EXPIRED_CONTENT_VERSION, RejectionReason.UNSUPPORTED_EMAIL_FORMAT, + RejectionReason.UNSUPPORTED_TUPLE_DATA_EXTRACTION, + RejectionReason.UNSUPPORTED_LATTICE_REVIEW_DATA_EXTRACTION, + RejectionReason.DISALLOWED_FOR_TRANSLATION, RejectionReason.COUNT + }) + // This must be kept in sync with readaloud/enums.xml values + public @interface RejectionReason { + int UNKNOWN_REJECTION_REASON = 0; + // The page cannot be fetched. + int PAGE_DOWNLOAD_FAILURE = 1; + // The specified voice is not supported in general, not supported for the user + // or does not match the page language. + int UNSUPPORTED_VOICE = 2; + // The specified language is not supported. + int UNSUPPORTED_LANGUAGE = 3; + // The page contains paid content. + int PAYWALL = 4; + // Porn is not allowed. + int PORN = 5; + // Video content, not suitable for narration even if it has short text in + // addition to the video. + int VIDEO = 6; + // The page cannot be parsed to an article, for whatever reason. + int NON_ARTICLE = 7; + // The text is too short. + int TEXT_TOO_SHORT = 8; + // The content is classified as data (rather than textual). + int NON_TEXTUAL = 9; + // The article quality isn't sufficient for the user. + int UNSUPPORTED_ARTICLE_QUALITY = 10; + // The URL is blacklisted. + int URL_BLACKLISTED = 11; + // The content is too large. + int CONTENT_TOO_LARGE = 12; + // The URL format is invalid or unsupported. + int INVALID_URL = 13; + // The publisher has explicitly marked the page so that it shouldn't be read + // aloud. + int DISALLOWED_FOR_READOUT = 14; + // A generic code for cases where the input is invalid. + int BAD_REQUEST = 15; + // The requested content version has expired and is no longer available. + int EXPIRED_CONTENT_VERSION = 16; + // We don't support this kind of email. + int UNSUPPORTED_EMAIL_FORMAT = 17; + // There is no Tuple data available for this url. + int UNSUPPORTED_TUPLE_DATA_EXTRACTION = 18; + // There is no LatticeReview data available for this url. + int UNSUPPORTED_LATTICE_REVIEW_DATA_EXTRACTION = 19; + // The content is not allowed to be translated. + int DISALLOWED_FOR_TRANSLATION = 20; + int COUNT = 21; + } + + private final @RejectionReason int mRejectionReason; + + public ReadAloudUnsupportedException( + String message, @Nullable Throwable cause, @RejectionReason int rejectionReason) { + super(message, cause, ReadAloudErrorCode.FAILED_PRECONDITION); + mRejectionReason = rejectionReason; + } + + /** Returns the rejection reason. */ + public @RejectionReason int getRejectionReason() { + return mRejectionReason; + } +}
diff --git a/chrome/browser/resources/ash/settings/internet_page/internet_detail_subpage.html b/chrome/browser/resources/ash/settings/internet_page/internet_detail_subpage.html index d3585f3..2132ed0 100644 --- a/chrome/browser/resources/ash/settings/internet_page/internet_detail_subpage.html +++ b/chrome/browser/resources/ash/settings/internet_page/internet_detail_subpage.html
@@ -421,7 +421,8 @@ </iron-collapse> </template> - <template is="dom-if" if="[[showDataUsage_(managedProperties_)]]"> + <template is="dom-if" if="[[showDataUsage_(managedProperties_, + trafficCountersAvailable_)]]"> <!-- Data usage toggle. --> <cr-expand-button aria-label="$i18n{TrafficCountersDataUsageLabel}" @@ -433,7 +434,9 @@ <!-- Data usage section --> <iron-collapse opened="[[dataUsageExpanded_]]"> <settings-traffic-counters id="settingsTrafficCounters" - guid="[[guid]]"> + guid="[[guid]]" + on-reset-day-changed="computeTrafficCountersAvailable_" + on-reset-data-usage-button-clicked="computeTrafficCountersAvailable_"> </settings-traffic-counters> </iron-collapse> </template>
diff --git a/chrome/browser/resources/ash/settings/internet_page/internet_detail_subpage.ts b/chrome/browser/resources/ash/settings/internet_page/internet_detail_subpage.ts index 8d65852..17ad1b2 100644 --- a/chrome/browser/resources/ash/settings/internet_page/internet_detail_subpage.ts +++ b/chrome/browser/resources/ash/settings/internet_page/internet_detail_subpage.ts
@@ -47,6 +47,7 @@ import {MojoInterfaceProviderImpl} from 'chrome://resources/ash/common/network/mojo_interface_provider.js'; import {NetworkListenerBehavior, NetworkListenerBehaviorInterface} from 'chrome://resources/ash/common/network/network_listener_behavior.js'; import {OncMojo} from 'chrome://resources/ash/common/network/onc_mojo.js'; +import {TrafficCountersAdapter} from 'chrome://resources/ash/common/traffic_counters/traffic_counters_adapter.js'; import {PrefsMixin, PrefsMixinInterface} from 'chrome://resources/cr_components/settings_prefs/prefs_mixin.js'; import {loadTimeData} from 'chrome://resources/js/load_time_data.js'; import {ActivationStateType, ApnProperties, ConfigProperties, CrosNetworkConfigInterface, GlobalPolicy, HiddenSsidMode, IPConfigProperties, ManagedProperties, MatchType, NetworkStateProperties, ProxySettings, SecurityType, VpnType} from 'chrome://resources/mojo/chromeos/services/network_config/public/mojom/cros_network_config.mojom-webui.js'; @@ -278,6 +279,14 @@ }, /** + * Tracks whether traffic counter info should be shown. + */ + trafficCountersAvailable_: { + type: Boolean, + value: false, + }, + + /** * When true, all inputs that allow state to be changed (e.g., toggles, * inputs) are disabled. */ @@ -421,6 +430,8 @@ private showHiddenToggle_: boolean; private showMeteredToggle_: boolean; private showTechnologyBadge_: string; + private trafficCountersAdapter_: TrafficCountersAdapter; + private trafficCountersAvailable_: boolean; constructor() { super(); @@ -464,6 +475,8 @@ } this.osSyncBrowserProxy_ = OsSyncBrowserProxyImpl.getInstance(); + + this.trafficCountersAdapter_ = new TrafficCountersAdapter(); } override connectedCallback(): void { @@ -472,6 +485,7 @@ this.addWebUiListener( 'os-sync-prefs-changed', this.handleOsSyncPrefsChanged_.bind(this)); this.osSyncBrowserProxy_.sendOsSyncPrefsChanged(); + this.computeTrafficCountersAvailable_(); } private afterRenderShowDeepLink_( @@ -2174,14 +2188,26 @@ return fields; } - private showDataUsage_(managedProperties: ManagedProperties| - undefined): boolean { + private async computeTrafficCountersAvailable_(): Promise<void> { + const networks = await this.trafficCountersAdapter_ + .requestTrafficCountersForActiveNetworks(); + this.trafficCountersAvailable_ = networks.some(n => n.guid === this.guid); + } + + private async showDataUsage_( + managedProperties: ManagedProperties|undefined, + trafficCountersAvailable: boolean): Promise<boolean> { if (!this.isTrafficCountersEnabled_) { return false; } - return !!managedProperties && this.guid !== '' && + const connectedToCellular = !!managedProperties && this.guid !== '' && this.isCellular_(managedProperties) && this.isConnectedState_(managedProperties); + if (!connectedToCellular) { + return false; + } + + return trafficCountersAvailable; } private hasAdvancedSection_(): boolean {
diff --git a/chrome/browser/resources/ash/settings/internet_page/settings_traffic_counters.html b/chrome/browser/resources/ash/settings/internet_page/settings_traffic_counters.html index 17b54612..2ee18ef8 100644 --- a/chrome/browser/resources/ash/settings/internet_page/settings_traffic_counters.html +++ b/chrome/browser/resources/ash/settings/internet_page/settings_traffic_counters.html
@@ -4,40 +4,39 @@ display: flex; } </style> -<template is="dom-if" if="[[trafficCountersAvailable_]]"> - <div class="settings-box single-column stretch first"> - [[i18n('TrafficCountersDataUsageDifferentFromProviderLabel')]] - </div> - <div class="settings-box single-column stretch indented first"> - <div id="data-usage-wrapper"> - <div class="start settings-box-text" aria-hidden="true"> - <div id="dataUsageLabel" class="label" aria-hidden="true"> - [[date_]] - </div> - <div id="dataUsageSubLabel" class="secondary label" aria-hidden="true"> - [[value_]] - </div> +<div class="settings-box single-column stretch first"> + [[i18n('TrafficCountersDataUsageDifferentFromProviderLabel')]] +</div> +<div class="settings-box single-column stretch indented first"> + <div id="data-usage-wrapper"> + <div class="start settings-box-text"> + <div id="dataUsageLabel" class="label"> + [[date_]] </div> - <cr-button id="resetDataUsageButton" - aria-label$="$i18n{TrafficCountersDataUsageResetLabel}" - on-click="onResetDataUsageClick_"> - [[i18n('TrafficCountersDataUsageResetButtonLabel')]] - </cr-button> - </div> - <div id="data-usage-wrapper"> - <div class="start settings-box-text" aria-hidden="true"> - <div id="daySelectionLabel" class="label"> - [[i18n('TrafficCountersDataUsageAutoResetDayOfMonthLabel')]] - </div> - <div id="daySelectionSubLabel" class="secondary label" - aria-hidden="true"> - [[i18n('TrafficCountersDataUsageAutoResetDayOfMonthSubLabel')]] - </div> + <div id="dataUsageSubLabel" class="secondary label"> + [[value_]] </div> - <div class="separator"></div> - <cr-input id="daySelectionInput" type="number" value="{{resetDay_}}" - max="31" min="1" on-change="onResetDaySelected_"> - </cr-input> </div> + <cr-button id="resetDataUsageButton" + aria-label$="$i18n{TrafficCountersDataUsageResetLabel}" + on-click="onResetDataUsageClick_"> + [[i18n('TrafficCountersDataUsageResetButtonLabel')]] + </cr-button> </div> -</template> \ No newline at end of file + <div id="data-usage-wrapper"> + <div class="start settings-box-text"> + <div id="daySelectionLabel" class="label"> + [[i18n('TrafficCountersDataUsageAutoResetDayOfMonthLabel')]] + </div> + <div id="daySelectionSubLabel" class="secondary label"> + [[i18n('TrafficCountersDataUsageAutoResetDayOfMonthSubLabel')]] + </div> + </div> + <select class="md-select" id="resetDayList" value="{{resetDay_::change}}" + on-change="onResetDaySelected_"> + <template is="dom-repeat" items="[[getDaysList_()]]"> + <option selected="[[item]]">[[item]]</option> + </template> + </select> + </div> +</div> \ No newline at end of file
diff --git a/chrome/browser/resources/ash/settings/internet_page/settings_traffic_counters.ts b/chrome/browser/resources/ash/settings/internet_page/settings_traffic_counters.ts index b78c5cf..006ca9ab 100644 --- a/chrome/browser/resources/ash/settings/internet_page/settings_traffic_counters.ts +++ b/chrome/browser/resources/ash/settings/internet_page/settings_traffic_counters.ts
@@ -63,6 +63,17 @@ const SettingsTrafficCountersElementBase = I18nMixin(PolymerElement); +export interface SettingsTrafficCountersElement { + $: { + dataUsageLabel: HTMLElement, + dataUsageSubLabel: HTMLElement, + resetDataUsageButton: HTMLButtonElement, + daySelectionLabel: HTMLElement, + daySelectionSubLabel: HTMLElement, + resetDayList: HTMLSelectElement, + }; +} + export class SettingsTrafficCountersElement extends SettingsTrafficCountersElementBase { static get is() { @@ -77,11 +88,6 @@ return { /** The network GUID to display details for. */ guid: String, - /** Tracks whether traffic counter info should be shown. */ - trafficCountersAvailable_: { - type: Boolean, - value: false, - }, /** Tracks the last reset time information. */ date_: { type: String, @@ -104,7 +110,6 @@ private date_: string; private resetDay_: number; private trafficCountersAdapter_: TrafficCountersAdapter; - private trafficCountersAvailable_: boolean; private value_: string; constructor() { @@ -121,7 +126,6 @@ * Loads all the values needed to populate the HTML. */ load(): void { - this.populateTrafficCountersAvailable_(); this.populateDate_(); this.populateDataUsageValue_(); this.populateUserSpecifiedResetDay_(); @@ -133,7 +137,10 @@ private async onResetDataUsageClick_(): Promise<void> { await this.trafficCountersAdapter_.resetTrafficCountersForNetwork( this.guid); - this.load(); + this.dispatchEvent(new CustomEvent( + 'reset-data-usage-button-clicked', {bubbles: true, composed: true})); + // this.load(); // Remove load and use appropriate listener functionality + // because the reset is changing the value to the old value } /** @@ -148,26 +155,6 @@ } /** - * Determines whether data usage should be shown. - */ - private async populateTrafficCountersAvailable_(): Promise<void> { - const result = await this.populateTrafficCountersAvailableHelper_(); - this.trafficCountersAvailable_ = result; - } - - /** - * Gathers data usage visibility information for this network. - */ - private async populateTrafficCountersAvailableHelper_(): Promise<boolean> { - if (this.guid === '') { - return false; - } - - const network = await this.getNetworkIfAvailable_(); - return !!network; - } - - /** * Determines the last reset time of the data usage. */ private async populateDate_(): Promise<void> { @@ -232,7 +219,15 @@ private onResetDaySelected_(): void { this.trafficCountersAdapter_.setTrafficCountersResetDayForNetwork( this.guid, {value: this.resetDay_}); - this.load(); + this.dispatchEvent( + new CustomEvent('reset-day-changed', {bubbles: true, composed: true})); + } + + /** + * Tracks the list of options available in the reset day dropdown. + */ + private getDaysList_(): number[] { + return Array.from({length: 31}, (_, i) => i + 1); } }
diff --git a/chrome/browser/resources/new_tab_page/modules/v2/tab_resumption/module.ts b/chrome/browser/resources/new_tab_page/modules/v2/tab_resumption/module.ts index c1dccd2..f3bc565b 100644 --- a/chrome/browser/resources/new_tab_page/modules/v2/tab_resumption/module.ts +++ b/chrome/browser/resources/new_tab_page/modules/v2/tab_resumption/module.ts
@@ -137,17 +137,21 @@ private onDismissButtonClick_() { const urls = this.tabs.map((tab: Tab) => tab.url); TabResumptionProxyImpl.getInstance().handler.dismissModule(urls); - this.dispatchEvent(new CustomEvent('dismiss-module-instance', { - bubbles: true, - composed: true, - detail: { - message: loadTimeData.getStringF( - 'dismissModuleToastMessage', - loadTimeData.getString('modulesTabResumptionSentence')), - restoreCallback: () => - TabResumptionProxyImpl.getInstance().handler.restoreModule(), - }, - })); + this.dispatchEvent(new CustomEvent( + loadTimeData.getBoolean('modulesRedesignedEnabled') ? + 'dismiss-module-instance' : + 'dismiss-module', + { + bubbles: true, + composed: true, + detail: { + message: loadTimeData.getStringF( + 'dismissModuleToastMessage', + loadTimeData.getString('modulesTabResumptionSentence')), + restoreCallback: () => + TabResumptionProxyImpl.getInstance().handler.restoreModule(), + }, + })); } private computeDomain_(tab: Tab): string {
diff --git a/chrome/browser/safe_browsing/chrome_password_protection_service.cc b/chrome/browser/safe_browsing/chrome_password_protection_service.cc index e694686..adbf199 100644 --- a/chrome/browser/safe_browsing/chrome_password_protection_service.cc +++ b/chrome/browser/safe_browsing/chrome_password_protection_service.cc
@@ -499,8 +499,8 @@ content::WebContents* web_contents, ReusedPasswordAccountType password_type, const std::string& verdict_token) { - UpdateSecurityState(SB_THREAT_TYPE_SAVED_PASSWORD_REUSE, password_type, - web_contents); + UpdateSecurityState(SBThreatType::SB_THREAT_TYPE_SAVED_PASSWORD_REUSE, + password_type, web_contents); // Starts preparing post-warning report. MaybeStartThreatDetailsCollection(web_contents, verdict_token, password_type); } @@ -522,9 +522,10 @@ } SBThreatType threat_type; if (password_type.is_account_syncing()) { - threat_type = SB_THREAT_TYPE_SIGNED_IN_SYNC_PASSWORD_REUSE; + threat_type = SBThreatType::SB_THREAT_TYPE_SIGNED_IN_SYNC_PASSWORD_REUSE; } else { - threat_type = SB_THREAT_TYPE_SIGNED_IN_NON_SYNC_PASSWORD_REUSE; + threat_type = + SBThreatType::SB_THREAT_TYPE_SIGNED_IN_NON_SYNC_PASSWORD_REUSE; } UpdateSecurityState(threat_type, password_type, web_contents); @@ -537,8 +538,8 @@ ReusedPasswordAccountType password_type, const std::string& verdict_token) { web_contents_with_unhandled_enterprise_reuses_.insert(web_contents); - UpdateSecurityState(SB_THREAT_TYPE_ENTERPRISE_PASSWORD_REUSE, password_type, - web_contents); + UpdateSecurityState(SBThreatType::SB_THREAT_TYPE_ENTERPRISE_PASSWORD_REUSE, + password_type, web_contents); // Starts preparing post-warning report. MaybeStartThreatDetailsCollection(web_contents, verdict_token, password_type); } @@ -649,14 +650,17 @@ security_interstitials::UnsafeResource resource; if (password_type.account_type() == ReusedPasswordAccountType::NON_GAIA_ENTERPRISE) { - resource.threat_type = SB_THREAT_TYPE_ENTERPRISE_PASSWORD_REUSE; + resource.threat_type = + SBThreatType::SB_THREAT_TYPE_ENTERPRISE_PASSWORD_REUSE; } else if (password_type.account_type() == ReusedPasswordAccountType::SAVED_PASSWORD) { - resource.threat_type = SB_THREAT_TYPE_SAVED_PASSWORD_REUSE; + resource.threat_type = SBThreatType::SB_THREAT_TYPE_SAVED_PASSWORD_REUSE; } else if (password_type.is_account_syncing()) { - resource.threat_type = SB_THREAT_TYPE_SIGNED_IN_SYNC_PASSWORD_REUSE; + resource.threat_type = + SBThreatType::SB_THREAT_TYPE_SIGNED_IN_SYNC_PASSWORD_REUSE; } else { - resource.threat_type = SB_THREAT_TYPE_SIGNED_IN_NON_SYNC_PASSWORD_REUSE; + resource.threat_type = + SBThreatType::SB_THREAT_TYPE_SIGNED_IN_NON_SYNC_PASSWORD_REUSE; } resource.url = web_contents->GetLastCommittedURL(); resource.render_process_id = primary_main_frame_id.child_id; @@ -1157,7 +1161,8 @@ UserMetricsAction("PasswordProtection.PageInfo.MarkSiteAsLegitimate")); // TODO(vakh): There's no good enum to report this dialog interaction. // This needs to be investigated. - UpdateSecurityState(SB_THREAT_TYPE_SAFE, password_type, web_contents); + UpdateSecurityState(SBThreatType::SB_THREAT_TYPE_SAFE, password_type, + web_contents); if (password_type.account_type() == ReusedPasswordAccountType::NON_GAIA_ENTERPRISE) { web_contents_with_unhandled_enterprise_reuses_.erase(web_contents); @@ -1407,7 +1412,7 @@ return; const GURL url_with_empty_path = url.GetWithEmptyPath(); - if (threat_type == SB_THREAT_TYPE_SAFE) { + if (threat_type == SBThreatType::SB_THREAT_TYPE_SAFE) { ui_manager_->RemoveAllowlistUrlSet( url_with_empty_path, /*navigation_id=*/std::nullopt, web_contents, /*from_pending_only=*/false); @@ -1422,14 +1427,14 @@ return; } - SBThreatType current_threat_type = SB_THREAT_TYPE_UNUSED; + SBThreatType current_threat_type = SBThreatType::SB_THREAT_TYPE_UNUSED; // If user already click-through interstitial warning, or if there's already // a dangerous security state showing, we'll override it. if (ui_manager_->IsUrlAllowlistedOrPendingForWebContents( url_with_empty_path, /*is_subresource=*/false, web_contents->GetController().GetLastCommittedEntry(), web_contents, /*allowlist_only=*/false, ¤t_threat_type)) { - DCHECK_NE(SB_THREAT_TYPE_UNUSED, current_threat_type); + DCHECK_NE(SBThreatType::SB_THREAT_TYPE_UNUSED, current_threat_type); if (current_threat_type == threat_type) return; // Resets previous threat type. @@ -1706,10 +1711,11 @@ /*allowlist_only=*/true, ¤t_threat_type)) { return false; } - return current_threat_type == SB_THREAT_TYPE_URL_PHISHING || - current_threat_type == SB_THREAT_TYPE_URL_MALWARE || - current_threat_type == SB_THREAT_TYPE_URL_UNWANTED || - current_threat_type == SB_THREAT_TYPE_URL_CLIENT_SIDE_PHISHING; + return current_threat_type == SBThreatType::SB_THREAT_TYPE_URL_PHISHING || + current_threat_type == SBThreatType::SB_THREAT_TYPE_URL_MALWARE || + current_threat_type == SBThreatType::SB_THREAT_TYPE_URL_UNWANTED || + current_threat_type == + SBThreatType::SB_THREAT_TYPE_URL_CLIENT_SIDE_PHISHING; } AccountInfo ChromePasswordProtectionService::GetAccountInfo() const {
diff --git a/chrome/browser/safe_browsing/chrome_password_protection_service_unittest.cc b/chrome/browser/safe_browsing/chrome_password_protection_service_unittest.cc index cc2fa97..7b1e0a364 100644 --- a/chrome/browser/safe_browsing/chrome_password_protection_service_unittest.cc +++ b/chrome/browser/safe_browsing/chrome_password_protection_service_unittest.cc
@@ -748,6 +748,8 @@ } TEST_F(ChromePasswordProtectionServiceTest, VerifyUpdateSecurityState) { + using enum SBThreatType; + GURL url("http://password_reuse_url.com"); NavigateAndCommit(url); SBThreatType current_threat_type = SB_THREAT_TYPE_UNUSED; @@ -775,8 +777,8 @@ web_contents(), false, ¤t_threat_type)); EXPECT_EQ(SB_THREAT_TYPE_SIGNED_IN_SYNC_PASSWORD_REUSE, current_threat_type); - service_->UpdateSecurityState(safe_browsing::SB_THREAT_TYPE_SAFE, - reused_password_type, web_contents()); + service_->UpdateSecurityState(SB_THREAT_TYPE_SAFE, reused_password_type, + web_contents()); current_threat_type = SB_THREAT_TYPE_UNUSED; service_->ui_manager()->IsUrlAllowlistedOrPendingForWebContents( url, false, web_contents()->GetController().GetLastCommittedEntry(),
diff --git a/chrome/browser/safe_browsing/client_side_detection_host_unittest.cc b/chrome/browser/safe_browsing/client_side_detection_host_unittest.cc index 3eb4422..541f47fe 100644 --- a/chrome/browser/safe_browsing/client_side_detection_host_unittest.cc +++ b/chrome/browser/safe_browsing/client_side_detection_host_unittest.cc
@@ -37,6 +37,7 @@ #include "components/safe_browsing/content/common/safe_browsing.mojom-shared.h" #include "components/safe_browsing/core/browser/db/database_manager.h" #include "components/safe_browsing/core/browser/db/test_database_manager.h" +#include "components/safe_browsing/core/browser/db/v4_protocol_manager_util.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" @@ -553,7 +554,8 @@ EXPECT_EQ(phishing_url, resource.url); EXPECT_EQ(phishing_url, resource.original_url); EXPECT_FALSE(resource.is_subresource); - EXPECT_EQ(SB_THREAT_TYPE_URL_CLIENT_SIDE_PHISHING, resource.threat_type); + EXPECT_EQ(SBThreatType::SB_THREAT_TYPE_URL_CLIENT_SIDE_PHISHING, + resource.threat_type); EXPECT_EQ(ThreatSource::CLIENT_SIDE_DETECTION, resource.threat_source); EXPECT_EQ(web_contents(), unsafe_resource_util::GetWebContentsForResource(resource)); @@ -624,7 +626,8 @@ EXPECT_EQ(other_phishing_url, resource.url); EXPECT_EQ(other_phishing_url, resource.original_url); EXPECT_FALSE(resource.is_subresource); - EXPECT_EQ(SB_THREAT_TYPE_URL_CLIENT_SIDE_PHISHING, resource.threat_type); + EXPECT_EQ(SBThreatType::SB_THREAT_TYPE_URL_CLIENT_SIDE_PHISHING, + resource.threat_type); EXPECT_EQ(ThreatSource::CLIENT_SIDE_DETECTION, resource.threat_source); EXPECT_EQ(web_contents(), unsafe_resource_util::GetWebContentsForResource(resource));
diff --git a/chrome/browser/safe_browsing/download_protection/download_protection_service_unittest.cc b/chrome/browser/safe_browsing/download_protection/download_protection_service_unittest.cc index 0dff3d3..45c4bd9 100644 --- a/chrome/browser/safe_browsing/download_protection/download_protection_service_unittest.cc +++ b/chrome/browser/safe_browsing/download_protection/download_protection_service_unittest.cc
@@ -2354,20 +2354,7 @@ { EXPECT_CALL(*sb_service_->mock_database_manager(), CheckDownloadUrl(ContainerEq(url_chain), NotNull())) - .WillOnce( - DoAll(CheckDownloadUrlDone(SB_THREAT_TYPE_SAFE), Return(false))); - RunLoop run_loop; - download_service_->CheckDownloadUrl( - &item, base::BindOnce(&DownloadProtectionServiceTest::CheckDoneCallback, - base::Unretained(this), run_loop.QuitClosure())); - run_loop.Run(); - EXPECT_TRUE(IsResult(DownloadCheckResult::SAFE)); - Mock::VerifyAndClearExpectations(sb_service_.get()); - } - { - EXPECT_CALL(*sb_service_->mock_database_manager(), - CheckDownloadUrl(ContainerEq(url_chain), NotNull())) - .WillOnce(DoAll(CheckDownloadUrlDone(SB_THREAT_TYPE_URL_MALWARE), + .WillOnce(DoAll(CheckDownloadUrlDone(SBThreatType::SB_THREAT_TYPE_SAFE), Return(false))); RunLoop run_loop; download_service_->CheckDownloadUrl( @@ -2380,7 +2367,22 @@ { EXPECT_CALL(*sb_service_->mock_database_manager(), CheckDownloadUrl(ContainerEq(url_chain), NotNull())) - .WillOnce(DoAll(CheckDownloadUrlDone(SB_THREAT_TYPE_URL_BINARY_MALWARE), + .WillOnce(DoAll( + CheckDownloadUrlDone(SBThreatType::SB_THREAT_TYPE_URL_MALWARE), + Return(false))); + RunLoop run_loop; + download_service_->CheckDownloadUrl( + &item, base::BindOnce(&DownloadProtectionServiceTest::CheckDoneCallback, + base::Unretained(this), run_loop.QuitClosure())); + run_loop.Run(); + EXPECT_TRUE(IsResult(DownloadCheckResult::SAFE)); + Mock::VerifyAndClearExpectations(sb_service_.get()); + } + { + EXPECT_CALL(*sb_service_->mock_database_manager(), + CheckDownloadUrl(ContainerEq(url_chain), NotNull())) + .WillOnce(DoAll(CheckDownloadUrlDone( + SBThreatType::SB_THREAT_TYPE_URL_BINARY_MALWARE), Return(false))); RunLoop run_loop; download_service_->CheckDownloadUrl(
diff --git a/chrome/browser/safe_browsing/download_protection/download_url_sb_client.cc b/chrome/browser/safe_browsing/download_protection/download_url_sb_client.cc index 32d0091c..e52e215 100644 --- a/chrome/browser/safe_browsing/download_protection/download_url_sb_client.cc +++ b/chrome/browser/safe_browsing/download_protection/download_url_sb_client.cc
@@ -60,7 +60,7 @@ DCHECK_CURRENTLY_ON(content::BrowserThread::UI); if (!database_manager_.get() || database_manager_->CheckDownloadUrl(url_chain_, this)) { - CheckDone(SB_THREAT_TYPE_SAFE); + CheckDone(SBThreatType::SB_THREAT_TYPE_SAFE); } else { // Add a reference to this object to prevent it from being destroyed // before url checking result is returned. @@ -69,7 +69,7 @@ } bool DownloadUrlSBClient::IsDangerous(SBThreatType threat_type) const { - return threat_type == SB_THREAT_TYPE_URL_BINARY_MALWARE; + return threat_type == SBThreatType::SB_THREAT_TYPE_URL_BINARY_MALWARE; } // Implements SafeBrowsingDatabaseManager::Client. @@ -91,7 +91,7 @@ ? DownloadCheckResult::DANGEROUS : DownloadCheckResult::SAFE; UpdateDownloadCheckStats(total_type_); - if (threat_type != SB_THREAT_TYPE_SAFE) { + if (threat_type != SBThreatType::SB_THREAT_TYPE_SAFE) { UpdateDownloadCheckStats(dangerous_type_); content::GetUIThreadTaskRunner({})->PostTask( FROM_HERE,
diff --git a/chrome/browser/safe_browsing/phishy_interaction_tracker.cc b/chrome/browser/safe_browsing/phishy_interaction_tracker.cc index c815a93..bf4151a 100644 --- a/chrome/browser/safe_browsing/phishy_interaction_tracker.cc +++ b/chrome/browser/safe_browsing/phishy_interaction_tracker.cc
@@ -154,10 +154,10 @@ /*allowlist_only=*/true, ¤t_threat_type)) { return false; } - return current_threat_type == safe_browsing::SB_THREAT_TYPE_URL_PHISHING || + return current_threat_type == SBThreatType::SB_THREAT_TYPE_URL_PHISHING || current_threat_type == - safe_browsing::SB_THREAT_TYPE_URL_CLIENT_SIDE_PHISHING || - current_threat_type == safe_browsing::SB_THREAT_TYPE_SUSPICIOUS_SITE; + SBThreatType::SB_THREAT_TYPE_URL_CLIENT_SIDE_PHISHING || + current_threat_type == SBThreatType::SB_THREAT_TYPE_SUSPICIOUS_SITE; } void PhishyInteractionTracker::HandlePhishyInteraction(
diff --git a/chrome/browser/safe_browsing/phishy_interaction_tracker_unittest.cc b/chrome/browser/safe_browsing/phishy_interaction_tracker_unittest.cc index 5aabeb8a..9dd8648a 100644 --- a/chrome/browser/safe_browsing/phishy_interaction_tracker_unittest.cc +++ b/chrome/browser/safe_browsing/phishy_interaction_tracker_unittest.cc
@@ -64,7 +64,7 @@ WebContents* web_contents, bool allowlist_only, safe_browsing::SBThreatType* threat_type) override { - *threat_type = safe_browsing::SB_THREAT_TYPE_URL_PHISHING; + *threat_type = safe_browsing::SBThreatType::SB_THREAT_TYPE_URL_PHISHING; return true; } @@ -128,7 +128,7 @@ resource.url = GURL(url); resource.is_subresource = is_subresource; resource.threat_type = - safe_browsing::SB_THREAT_TYPE_URL_CLIENT_SIDE_PHISHING; + safe_browsing::SBThreatType::SB_THREAT_TYPE_URL_CLIENT_SIDE_PHISHING; return resource; }
diff --git a/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc b/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc index 4d8c0ad..b5f767c1 100644 --- a/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc +++ b/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc
@@ -163,11 +163,11 @@ const char kInterstitialPreCommitPageHistogramSuffix[] = ".before_page_shown"; std::string GetHistogramPrefix(const SBThreatType& threat_type) { - if (threat_type == SB_THREAT_TYPE_URL_MALWARE) { + if (threat_type == SBThreatType::SB_THREAT_TYPE_URL_MALWARE) { return "malware"; - } else if (threat_type == SB_THREAT_TYPE_URL_PHISHING) { + } else if (threat_type == SBThreatType::SB_THREAT_TYPE_URL_PHISHING) { return "phishing"; - } else if (threat_type == SB_THREAT_TYPE_URL_UNWANTED) { + } else if (threat_type == SBThreatType::SB_THREAT_TYPE_URL_UNWANTED) { return "harmful"; } else { NOTREACHED(); @@ -1902,9 +1902,10 @@ SafeBrowsingBlockingPageBrowserTestWithThreatTypeAndIsolationSetting, SafeBrowsingBlockingPageBrowserTest, testing::Combine( - testing::Values(SB_THREAT_TYPE_URL_MALWARE, // Threat types - SB_THREAT_TYPE_URL_PHISHING, - SB_THREAT_TYPE_URL_UNWANTED), + testing::Values( + SBThreatType::SB_THREAT_TYPE_URL_MALWARE, // Threat types + SBThreatType::SB_THREAT_TYPE_URL_PHISHING, + SBThreatType::SB_THREAT_TYPE_URL_UNWANTED), testing::Bool())); // If isolate all sites for testing. // Check back and forward work correctly after clicking through an interstitial. @@ -1994,8 +1995,9 @@ AntiPhishingTelemetryBrowserTestWithThreatTypeAndIsolationSetting, AntiPhishingTelemetryBrowserTest, testing::Combine( - testing::Values(SB_THREAT_TYPE_URL_PHISHING, // Threat types - SB_THREAT_TYPE_URL_CLIENT_SIDE_PHISHING), + testing::Values( + SBThreatType::SB_THREAT_TYPE_URL_PHISHING, // Threat types + SBThreatType::SB_THREAT_TYPE_URL_CLIENT_SIDE_PHISHING), testing::Bool())); // If isolate all sites for testing. IN_PROC_BROWSER_TEST_P(AntiPhishingTelemetryBrowserTest, @@ -2031,7 +2033,7 @@ SBThreatType threat_type = GetThreatType(); // SB_THREAT_TYPE_URL_CLIENT_SIDE_PHISHING does not set the page_url because // its resource's navigation_url is empty. - if (threat_type == SB_THREAT_TYPE_URL_PHISHING) { + if (threat_type == SBThreatType::SB_THREAT_TYPE_URL_PHISHING) { EXPECT_EQ(report.page_url(), embedded_test_server()->GetURL(kEmptyPage)); } // Create sorted vector of interstitial interactions. Sorted by @@ -2086,12 +2088,12 @@ EXPECT_EQ(report.url(), embedded_test_server()->GetURL(kEmptyPage)); // Verify the report interactions only contain interstitial interactions. SBThreatType threat_type = GetThreatType(); - if (threat_type == SB_THREAT_TYPE_URL_PHISHING) { + if (threat_type == SBThreatType::SB_THREAT_TYPE_URL_PHISHING) { EXPECT_EQ(report.type(), ClientSafeBrowsingReportRequest_ReportType_URL_PHISHING); EXPECT_EQ(report.page_url(), embedded_test_server()->GetURL(kEmptyPage)); } - if (threat_type == SB_THREAT_TYPE_URL_CLIENT_SIDE_PHISHING) { + if (threat_type == SBThreatType::SB_THREAT_TYPE_URL_CLIENT_SIDE_PHISHING) { EXPECT_EQ( report.type(), ClientSafeBrowsingReportRequest_ReportType_URL_CLIENT_SIDE_PHISHING); @@ -2131,7 +2133,7 @@ EXPECT_EQ(report.url(), embedded_test_server()->GetURL(kEmptyPage)); SBThreatType threat_type = GetThreatType(); - if (threat_type == SB_THREAT_TYPE_URL_PHISHING) { + if (threat_type == SBThreatType::SB_THREAT_TYPE_URL_PHISHING) { EXPECT_EQ(report.page_url(), embedded_test_server()->GetURL(kEmptyPage)); } // Verify the report interaction only contains a @@ -2149,7 +2151,7 @@ SafeBrowsingHatsSurveyBrowserTest, testing::Combine( // Threat types. - testing::Values(SB_THREAT_TYPE_URL_MALWARE), + testing::Values(SBThreatType::SB_THREAT_TYPE_URL_MALWARE), // If isolate all sites for testing. testing::Bool())); @@ -2294,10 +2296,11 @@ TrustSafetySentimentSurveyV2BrowserTestWithThreatTypeAndIsolationSetting, TrustSafetySentimentSurveyV2BrowserTest, testing::Combine( - testing::Values(SB_THREAT_TYPE_URL_PHISHING, // Threat types - SB_THREAT_TYPE_URL_CLIENT_SIDE_PHISHING, - SB_THREAT_TYPE_URL_MALWARE, - SB_THREAT_TYPE_URL_UNWANTED), + testing::Values( + SBThreatType::SB_THREAT_TYPE_URL_PHISHING, // Threat types + SBThreatType::SB_THREAT_TYPE_URL_CLIENT_SIDE_PHISHING, + SBThreatType::SB_THREAT_TYPE_URL_MALWARE, + SBThreatType::SB_THREAT_TYPE_URL_UNWANTED), testing::Bool())); // If isolate all sites for testing. IN_PROC_BROWSER_TEST_P(TrustSafetySentimentSurveyV2BrowserTest, @@ -2355,10 +2358,11 @@ RedInterstitialFaceliftBrowserTestWithThreatTypeAndIsolationSetting, RedInterstitialFaceliftBrowserTest, testing::Combine( - testing::Values(SB_THREAT_TYPE_URL_PHISHING, // Threat types - SB_THREAT_TYPE_URL_MALWARE, - SB_THREAT_TYPE_URL_CLIENT_SIDE_PHISHING, - SB_THREAT_TYPE_URL_UNWANTED), + testing::Values( + SBThreatType::SB_THREAT_TYPE_URL_PHISHING, // Threat types + SBThreatType::SB_THREAT_TYPE_URL_MALWARE, + SBThreatType::SB_THREAT_TYPE_URL_CLIENT_SIDE_PHISHING, + SBThreatType::SB_THREAT_TYPE_URL_UNWANTED), testing::Bool())); // If isolate all sites for testing. IN_PROC_BROWSER_TEST_P(RedInterstitialFaceliftBrowserTest, @@ -2387,8 +2391,8 @@ ASSERT_EQ(load_time_data.Find("heading")->GetString(), base::UTF16ToUTF8(l10n_util::GetStringUTF16(IDS_HEADING_NEW))); SBThreatType threat_type = GetThreatType(); - if (threat_type == SB_THREAT_TYPE_URL_PHISHING || - threat_type == SB_THREAT_TYPE_URL_CLIENT_SIDE_PHISHING) { + if (threat_type == SBThreatType::SB_THREAT_TYPE_URL_PHISHING || + threat_type == SBThreatType::SB_THREAT_TYPE_URL_CLIENT_SIDE_PHISHING) { ASSERT_EQ(load_time_data.Find("primaryParagraph")->GetString(), base::UTF16ToUTF8(l10n_util::GetStringUTF16( IDS_PHISHING_V4_PRIMARY_PARAGRAPH_NEW))); @@ -2398,7 +2402,7 @@ ASSERT_EQ(load_time_data.Find("finalParagraph")->GetString(), base::UTF16ToUTF8(l10n_util::GetStringUTF16( IDS_PHISHING_V4_PROCEED_PARAGRAPH_NEW))); - } else if (threat_type == SB_THREAT_TYPE_URL_MALWARE) { + } else if (threat_type == SBThreatType::SB_THREAT_TYPE_URL_MALWARE) { ASSERT_EQ(load_time_data.Find("primaryParagraph")->GetString(), base::UTF16ToUTF8(l10n_util::GetStringUTF16( IDS_MALWARE_V3_PRIMARY_PARAGRAPH_NEW))); @@ -2609,7 +2613,7 @@ void NavigateAndAssertNoInterstitial() { const GURL top_frame = embedded_test_server()->GetURL("/iframe.html"); - SetURLThreatType(top_frame, SB_THREAT_TYPE_URL_PHISHING); + SetURLThreatType(top_frame, SBThreatType::SB_THREAT_TYPE_URL_PHISHING); ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), top_frame)); AssertNoInterstitial(browser()); @@ -2659,7 +2663,7 @@ // Navigate to a non-phishing page. The warning should not be delayed. const GURL url = embedded_test_server()->GetURL("/empty.html"); - SetURLThreatType(url, SB_THREAT_TYPE_URL_MALWARE); + SetURLThreatType(url, SBThreatType::SB_THREAT_TYPE_URL_MALWARE); ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url)); EXPECT_TRUE(WaitForReady(browser())); @@ -3031,7 +3035,7 @@ content::TestNavigationObserver observer1(contents); const GURL url = embedded_test_server()->GetURL("/password/password_form.html"); - SetURLThreatType(url, SB_THREAT_TYPE_URL_PHISHING); + SetURLThreatType(url, SBThreatType::SB_THREAT_TYPE_URL_PHISHING); ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url)); observer1.Wait(); @@ -3098,11 +3102,12 @@ EXPECT_TRUE(VerifyIDNDecoded()); } -INSTANTIATE_TEST_SUITE_P(SafeBrowsingBlockingPageIDNTestWithThreatType, - SafeBrowsingBlockingPageIDNTest, - testing::Values(SB_THREAT_TYPE_URL_MALWARE, - SB_THREAT_TYPE_URL_PHISHING, - SB_THREAT_TYPE_URL_UNWANTED)); +INSTANTIATE_TEST_SUITE_P( + SafeBrowsingBlockingPageIDNTestWithThreatType, + SafeBrowsingBlockingPageIDNTest, + testing::Values(SBThreatType::SB_THREAT_TYPE_URL_MALWARE, + SBThreatType::SB_THREAT_TYPE_URL_PHISHING, + SBThreatType::SB_THREAT_TYPE_URL_UNWANTED)); class SafeBrowsingBlockingPageEnhancedProtectionMessageTest : public policy::PolicyTest { @@ -3143,7 +3148,7 @@ static_cast<FakeSafeBrowsingDatabaseManager*>( service->database_manager().get()) - ->AddDangerousUrl(url, SB_THREAT_TYPE_URL_MALWARE); + ->AddDangerousUrl(url, SBThreatType::SB_THREAT_TYPE_URL_MALWARE); ASSERT_TRUE(ui_test_utils::NavigateToURL(browser, url)); EXPECT_TRUE(WaitForReady(browser)); @@ -3864,7 +3869,7 @@ // Mark the URL as dangerous for both checks. SetupUrlRealTimeVerdictInCacheManager(url, browser()->profile(), /*is_unsafe=*/true); - SetURLThreatType(url, SB_THREAT_TYPE_URL_PHISHING); + SetURLThreatType(url, SBThreatType::SB_THREAT_TYPE_URL_PHISHING); NavigateToURLAndWaitForAsyncChecks(url); // The security indicator should be downgraded while the interstitial @@ -3903,7 +3908,7 @@ EnableAsyncCheck(); // Trigger a pre commit interstitial and go back. GURL start_url = embedded_test_server()->GetURL(kEmptyPage); - SetURLThreatType(start_url, SB_THREAT_TYPE_URL_PHISHING); + SetURLThreatType(start_url, SBThreatType::SB_THREAT_TYPE_URL_PHISHING); NavigateToURLAndWaitForAsyncChecks(start_url); EXPECT_TRUE(ClickAndWaitForDetach(browser(), "primary-button")); AssertNoInterstitial(browser()); @@ -4295,9 +4300,10 @@ All, SafeBrowsingPrerenderBrowserTest, testing::Combine( - testing::Values(SB_THREAT_TYPE_URL_MALWARE, // Threat types - SB_THREAT_TYPE_URL_PHISHING, - SB_THREAT_TYPE_URL_UNWANTED), + testing::Values( + SBThreatType::SB_THREAT_TYPE_URL_MALWARE, // Threat types + SBThreatType::SB_THREAT_TYPE_URL_PHISHING, + SBThreatType::SB_THREAT_TYPE_URL_UNWANTED), testing::Bool())); // If isolate all sites for testing. // Attempt to prerender an unsafe page. The prerender navigation should be @@ -4322,10 +4328,11 @@ INSTANTIATE_TEST_SUITE_P( All, SafeBrowsingThreatDetailsPrerenderBrowserTest, - // We simulate a SB_THREAT_TYPE_URL_CLIENT_SIDE_PHISHING to trigger DOM - // detail collection. - testing::Combine(testing::Values(SB_THREAT_TYPE_URL_CLIENT_SIDE_PHISHING), - testing::Bool())); // If isolate all sites for testing. + // We simulate a SBThreatType::SB_THREAT_TYPE_URL_CLIENT_SIDE_PHISHING to + // trigger DOM detail collection. + testing::Combine( + testing::Values(SBThreatType::SB_THREAT_TYPE_URL_CLIENT_SIDE_PHISHING), + testing::Bool())); // If isolate all sites for testing. // Test that the prerendering doesn't affect on the primary's threat report. IN_PROC_BROWSER_TEST_P(SafeBrowsingThreatDetailsPrerenderBrowserTest, @@ -4487,8 +4494,9 @@ WarningShownTimestampCSBRRDisabledBrowserTestWithThreatTypeAndIsolationSetting, WarningShownTimestampCSBRRDisabledBrowserTest, testing::Combine( - testing::Values(SB_THREAT_TYPE_URL_PHISHING, // Threat types - SB_THREAT_TYPE_URL_CLIENT_SIDE_PHISHING), + testing::Values( + SBThreatType::SB_THREAT_TYPE_URL_PHISHING, // Threat types + SBThreatType::SB_THREAT_TYPE_URL_CLIENT_SIDE_PHISHING), testing::Bool())); // If isolate all sites for testing. IN_PROC_BROWSER_TEST_P(WarningShownTimestampCSBRRDisabledBrowserTest,
diff --git a/chrome/browser/safe_browsing/safe_browsing_service.cc b/chrome/browser/safe_browsing/safe_browsing_service.cc index 33754d2..f10be12 100644 --- a/chrome/browser/safe_browsing/safe_browsing_service.cc +++ b/chrome/browser/safe_browsing/safe_browsing_service.cc
@@ -663,7 +663,7 @@ resource.url = url; resource.original_url = url; resource.is_subresource = false; - resource.threat_type = SB_THREAT_TYPE_URL_PHISHING; + resource.threat_type = SBThreatType::SB_THREAT_TYPE_URL_PHISHING; const content::GlobalRenderFrameHostId primary_main_frame_id = primary_main_frame->GetGlobalId(); resource.render_process_id = primary_main_frame_id.child_id;
diff --git a/chrome/browser/safe_browsing/safe_browsing_service_browsertest.cc b/chrome/browser/safe_browsing/safe_browsing_service_browsertest.cc index 13334d3..fbf89c2 100644 --- a/chrome/browser/safe_browsing/safe_browsing_service_browsertest.cc +++ b/chrome/browser/safe_browsing/safe_browsing_service_browsertest.cc
@@ -300,7 +300,7 @@ MATCHER_P(IsUnsafeResourceFor, url, "") { return (arg.url.spec() == url.spec() && - arg.threat_type != SB_THREAT_TYPE_SAFE); + arg.threat_type != SBThreatType::SB_THREAT_TYPE_SAFE); } class ServiceEnabledHelper : public base::ThreadTestHelper { @@ -387,6 +387,8 @@ } private: + using enum SBThreatType; + friend class base::RefCountedThreadSafe<TestSBClient>; ~TestSBClient() override = default; @@ -586,6 +588,8 @@ } protected: + using enum SBThreatType; + StrictMock<MockObserver> observer_; private:
diff --git a/chrome/browser/safe_browsing/threat_details_unittest.cc b/chrome/browser/safe_browsing/threat_details_unittest.cc index ff2906b2..74e77f06 100644 --- a/chrome/browser/safe_browsing/threat_details_unittest.cc +++ b/chrome/browser/safe_browsing/threat_details_unittest.cc
@@ -278,6 +278,8 @@ bool ReportWasSent() { return ui_manager_->ReportWasSent(); } protected: + using enum SBThreatType; + TestingProfile::TestingFactories GetTestingFactories() const override { return {{HistoryServiceFactory::GetInstance(), HistoryServiceFactory::GetDefaultFactory()}};
diff --git a/chrome/browser/safe_browsing/url_checker_delegate_impl.cc b/chrome/browser/safe_browsing/url_checker_delegate_impl.cc index bb065f7..38803d6 100644 --- a/chrome/browser/safe_browsing/url_checker_delegate_impl.cc +++ b/chrome/browser/safe_browsing/url_checker_delegate_impl.cc
@@ -88,13 +88,12 @@ threat_types_(CreateSBThreatTypeSet({ // TODO(crbug.com/835961): Enable on Android when list is available. #if BUILDFLAG(SAFE_BROWSING_DB_LOCAL) - safe_browsing::SB_THREAT_TYPE_SUSPICIOUS_SITE, + safe_browsing::SBThreatType::SB_THREAT_TYPE_SUSPICIOUS_SITE, #endif - safe_browsing::SB_THREAT_TYPE_URL_MALWARE, - safe_browsing::SB_THREAT_TYPE_URL_PHISHING, - safe_browsing::SB_THREAT_TYPE_URL_UNWANTED, - safe_browsing::SB_THREAT_TYPE_BILLING - })) { + safe_browsing::SBThreatType::SB_THREAT_TYPE_URL_MALWARE, + safe_browsing::SBThreatType::SB_THREAT_TYPE_URL_PHISHING, + safe_browsing::SBThreatType::SB_THREAT_TYPE_URL_UNWANTED, + safe_browsing::SBThreatType::SB_THREAT_TYPE_BILLING})) { } UrlCheckerDelegateImpl::~UrlCheckerDelegateImpl() = default;
diff --git a/chrome/browser/screen_ai/screen_ai_dlc_installer.cc b/chrome/browser/screen_ai/screen_ai_dlc_installer.cc index 611fe4886..b421d9e 100644 --- a/chrome/browser/screen_ai/screen_ai_dlc_installer.cc +++ b/chrome/browser/screen_ai/screen_ai_dlc_installer.cc
@@ -94,7 +94,7 @@ // This function can be called only on a thread that can be blocked. bool CheckIfDlcExistsOnNonUIThread() { - return !screen_ai::GetLatestComponentBinaryPath().empty(); + return base::PathExists(screen_ai::GetComponentDir()); } void InstallInternal(InstallMetadata metadata) {
diff --git a/chrome/browser/screen_ai/screen_ai_downloader_non_chromeos.cc b/chrome/browser/screen_ai/screen_ai_downloader_non_chromeos.cc index 5cfc52b..628e3a1c 100644 --- a/chrome/browser/screen_ai/screen_ai_downloader_non_chromeos.cc +++ b/chrome/browser/screen_ai/screen_ai_downloader_non_chromeos.cc
@@ -27,34 +27,17 @@ return install_state.get(); } -ScreenAIDownloaderNonChromeOS::ScreenAIDownloaderNonChromeOS() { - // Only observe component installation state changes if it is not already - // available. - // Checking for component availability requires I/O and hence is done as an - // async task to avoid blocking. - base::ThreadPool::PostTaskAndReplyWithResult( - FROM_HERE, - {base::MayBlock(), base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN}, - base::BindOnce([]() { return !GetLatestComponentBinaryPath().empty(); }), - base::BindOnce( - &ScreenAIDownloaderNonChromeOS::OnComponentAvailabilityStateReceived, - weak_ptr_factory_.GetWeakPtr())); -} +ScreenAIDownloaderNonChromeOS::ScreenAIDownloaderNonChromeOS() = default; ScreenAIDownloaderNonChromeOS::~ScreenAIDownloaderNonChromeOS() = default; -void ScreenAIDownloaderNonChromeOS::OnComponentAvailabilityStateReceived( - bool component_exists) { - if (component_exists) { - return; - } - component_updater_observation_.Observe( - g_browser_process->component_updater()); -} - void ScreenAIDownloaderNonChromeOS::DownloadComponentInternal() { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); component_updater::RegisterScreenAIComponent( g_browser_process->component_updater()); + if (!component_updater_observation_.IsObserving()) { + component_updater_observation_.Observe( + g_browser_process->component_updater()); + } } void ScreenAIDownloaderNonChromeOS::SetLastUsageTime() {
diff --git a/chrome/browser/screen_ai/screen_ai_downloader_non_chromeos.h b/chrome/browser/screen_ai/screen_ai_downloader_non_chromeos.h index c4f8a2c..1e8c56d 100644 --- a/chrome/browser/screen_ai/screen_ai_downloader_non_chromeos.h +++ b/chrome/browser/screen_ai/screen_ai_downloader_non_chromeos.h
@@ -34,10 +34,6 @@ // ScreenAIInstallState: void DownloadComponentInternal() override; - // Constructor schedules a task to check if component already exists on local - // device, and the result is received by this function. - void OnComponentAvailabilityStateReceived(bool component_exists); - base::ScopedObservation<component_updater::ComponentUpdateService, component_updater::ComponentUpdateService::Observer> component_updater_observation_{this};
diff --git a/chrome/browser/screen_ai/screen_ai_install_state.cc b/chrome/browser/screen_ai/screen_ai_install_state.cc index f7c22ea2..b12b6d7 100644 --- a/chrome/browser/screen_ai/screen_ai_install_state.cc +++ b/chrome/browser/screen_ai/screen_ai_install_state.cc
@@ -7,8 +7,6 @@ #include <memory> #include "base/check_is_test.h" -#include "base/debug/alias.h" -#include "base/debug/dump_without_crashing.h" #include "base/files/file_path.h" #include "base/files/file_util.h" #include "base/functional/bind.h" @@ -83,32 +81,17 @@ return true; } -// TODO(b/41489907): Remove this function once we know why the path is sometimes -// unexpected. +// TODO(b/41489907): Remove this function once it's known why the binary is +// sometimes not available. // static bool ScreenAIInstallState::VerifyLibraryAvailablity( const base::FilePath& install_dir) { - // Check the file iterator heuristic to find the library in the sandbox - // returns the same directory as `install_dir`. - base::FilePath component_path = GetLatestComponentPath(); - if (component_path == install_dir) { - // The library path is verified, but it is not known if the binary exists - // and is loadable. In case it is not available, the service cannot be - // triggered. // TODO(b/41489907): Try adding a browser test for this case. - bool binary_available = !GetLatestComponentBinaryPath().empty(); + bool binary_available = + base::PathExists(install_dir.Append(GetComponentBinaryFileName())); base::UmaHistogramBoolean( "Accessibility.ScreenAI.Component.BinaryAvailable", binary_available); return binary_available; - } - - VLOG(0) << "Library is installed in an unexpected folder."; - DEBUG_ALIAS_FOR_CSTR(expected_path, component_path.MaybeAsASCII().c_str(), - 1024); - DEBUG_ALIAS_FOR_CSTR(installed_path, install_dir.MaybeAsASCII().c_str(), - 1024); - base::debug::DumpWithoutCrashing(); - return false; } ScreenAIInstallState::ScreenAIInstallState() {
diff --git a/chrome/browser/screen_ai/screen_ai_service_router_browsertest.cc b/chrome/browser/screen_ai/screen_ai_service_router_browsertest.cc index a70fc1c3..a12b580a 100644 --- a/chrome/browser/screen_ai/screen_ai_service_router_browsertest.cc +++ b/chrome/browser/screen_ai/screen_ai_service_router_browsertest.cc
@@ -130,7 +130,7 @@ // InProcessBrowserTest: void SetUpOnMainThread() override { if (IsLibraryAvailableAtStartUp()) { - base::FilePath library_path = screen_ai::GetLatestComponentBinaryPath(); + base::FilePath library_path = screen_ai::GetComponentBinaryPathForTests(); CHECK(!library_path.empty()); CHECK(base::PathExists(library_path)); ScreenAIInstallState::GetInstance()->SetComponentFolder( @@ -162,7 +162,7 @@ base::ThreadPool::PostTaskAndReplyWithResult( FROM_HERE, {base::MayBlock(), base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN}, - base::BindOnce(&screen_ai::GetLatestComponentBinaryPath), + base::BindOnce(&screen_ai::GetComponentBinaryPathForTests), base::BindOnce([](const base::FilePath component_path) { ScreenAIInstallState::GetInstance()->SetComponentFolder( component_path.DirName());
diff --git a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/send_tab_to_self/SendTabToSelfCoordinator.java b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/send_tab_to_self/SendTabToSelfCoordinator.java index 2b033c1..d4cc329 100644 --- a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/send_tab_to_self/SendTabToSelfCoordinator.java +++ b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/send_tab_to_self/SendTabToSelfCoordinator.java
@@ -6,8 +6,6 @@ import android.content.Context; -import androidx.annotation.StringRes; - import org.chromium.base.Callback; import org.chromium.chrome.R; import org.chromium.chrome.browser.profiles.Profile; @@ -194,13 +192,20 @@ case EntryPointDisplayReason.OFFER_SIGN_IN: { MetricsRecorder.recordSendingEvent(SendingEvent.SHOW_SIGNIN_PROMO); + AccountPickerBottomSheetStrings strings = + new AccountPickerBottomSheetStrings( + R.string + .signin_account_picker_bottom_sheet_title_for_send_tab_to_self, + R.string + .signin_account_picker_bottom_sheet_subtitle_for_send_tab_to_self, + R.string.cancel); new AccountPickerBottomSheetCoordinator( mWindowAndroid, mController, new SendTabToSelfAccountPickerDelegate( this::onSignInComplete, IdentityServicesProvider.get().getSigninManager(mProfile)), - new BottomSheetStrings(), + strings, mDeviceLockActivityLauncher, AccountPickerLaunchMode.DEFAULT, /* isWebSignin= */ false, @@ -218,25 +223,4 @@ mController.hideContent(mController.getCurrentSheetContent(), /* animate= */ true); show(); } - - /** A class to store the STTS specific strings for the signin bottom sheet */ - public static class BottomSheetStrings implements AccountPickerBottomSheetStrings { - /** Returns the title string for the bottom sheet dialog. */ - @Override - public @StringRes int getTitle() { - return R.string.signin_account_picker_bottom_sheet_title_for_send_tab_to_self; - } - - /** Returns the subtitle string for the bottom sheet dialog. */ - @Override - public @StringRes int getSubtitle() { - return R.string.signin_account_picker_bottom_sheet_subtitle_for_send_tab_to_self; - } - - /** Returns the cancel button string for the bottom sheet dialog. */ - @Override - public @StringRes int getDismissButton() { - return R.string.cancel; - } - } }
diff --git a/chrome/browser/support_tool/policy_data_collector.cc b/chrome/browser/support_tool/policy_data_collector.cc index deb00bf..5130b0a 100644 --- a/chrome/browser/support_tool/policy_data_collector.cc +++ b/chrome/browser/support_tool/policy_data_collector.cc
@@ -8,6 +8,7 @@ #include <optional> #include <set> #include <string> +#include <string_view> #include <utility> #include "base/containers/fixed_flat_map.h" @@ -15,7 +16,6 @@ #include "base/files/file_util.h" #include "base/json/json_writer.h" #include "base/memory/scoped_refptr.h" -#include "base/strings/string_piece.h" #include "base/task/sequenced_task_runner.h" #include "base/task/task_traits.h" #include "base/task/thread_pool.h" @@ -38,32 +38,28 @@ // Returns the PII type that `status_field` is categorised in if it's considered // as PII. std::optional<redaction::PIIType> GetPIITypeOfStatusField( - base::StringPiece status_field) { + std::string_view status_field) { // List of keys in policy status that will be considered as PII and will be // redacted selectively. // TODO(crbug.com/1513684): Convert to MakeFixedFlatMap(). - static const auto kPersonallyIdentifiableStatusFields = - base::MakeFixedFlatMapNonConsteval<base::StringPiece, - redaction::PIIType>({ + static constexpr auto kPersonallyIdentifiableStatusFields = + base::MakeFixedFlatMap<std::string_view, redaction::PIIType>({ #if !BUILDFLAG(IS_CHROMEOS_ASH) - {policy::kDeviceIdKey, redaction::PIIType::kStableIdentifier}, - {policy::kEnrollmentTokenKey, - redaction::PIIType::kStableIdentifier}, - {policy::kMachineKey, redaction::PIIType::kStableIdentifier}, + {policy::kDeviceIdKey, redaction::PIIType::kStableIdentifier}, + {policy::kEnrollmentTokenKey, redaction::PIIType::kStableIdentifier}, + {policy::kMachineKey, redaction::PIIType::kStableIdentifier}, #endif // !BUILDFLAG(IS_CHROMEOS_ASH) - {policy::kAssetIdKey, redaction::PIIType::kStableIdentifier}, - // kLocationKey is the "Asset location" which is an identifier for - // the device that is set during enterprise enrollment or by the - // administrator. - {policy::kLocationKey, redaction::PIIType::kStableIdentifier}, - {policy::kDirectoryApiIdKey, redaction::PIIType::kStableIdentifier}, - {policy::kGaiaIdKey, redaction::PIIType::kGaiaID}, - {policy::kClientIdKey, redaction::PIIType::kStableIdentifier}, - {policy::kUsernameKey, redaction::PIIType::kEmail}, - {policy::kEnterpriseDomainManagerKey, redaction::PIIType::kEmail}, { - policy::kDomainKey, redaction::PIIType::kEmail - } - }); + {policy::kAssetIdKey, redaction::PIIType::kStableIdentifier}, + // kLocationKey is the "Asset location" which is an identifier for + // the device that is set during enterprise enrollment or by the + // administrator. + {policy::kLocationKey, redaction::PIIType::kStableIdentifier}, + {policy::kDirectoryApiIdKey, redaction::PIIType::kStableIdentifier}, + {policy::kGaiaIdKey, redaction::PIIType::kGaiaID}, + {policy::kClientIdKey, redaction::PIIType::kStableIdentifier}, + {policy::kUsernameKey, redaction::PIIType::kEmail}, + {policy::kEnterpriseDomainManagerKey, redaction::PIIType::kEmail}, + {policy::kDomainKey, redaction::PIIType::kEmail}}); return kPersonallyIdentifiableStatusFields.contains(status_field) ? std::make_optional( kPersonallyIdentifiableStatusFields.at(status_field))
diff --git a/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/EmptyTabObserver.java b/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/EmptyTabObserver.java index d2ae483..df31081 100644 --- a/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/EmptyTabObserver.java +++ b/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/EmptyTabObserver.java
@@ -151,6 +151,9 @@ int bottomControlsMinHeightOffsetY) {} @Override + public void onWillShowBrowserControls(Tab tab) {} + + @Override public void onContentViewScrollingStateChanged(boolean scrolling) {} @Override
diff --git a/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/TabObserver.java b/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/TabObserver.java index de2f673..72526f1 100644 --- a/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/TabObserver.java +++ b/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/TabObserver.java
@@ -335,6 +335,13 @@ int bottomControlsMinHeightOffsetY); /** + * Called when the tab is about to notify its renderer to show the browser controls. + * + * @param tab The notifying {@link Tab}. + */ + void onWillShowBrowserControls(Tab tab); + + /** * Called when scrolling state of Tab's content view changes. * @param scrolling {@code true} if scrolling started; {@code false} if stopped. */
diff --git a/chrome/browser/touch_to_fill/autofill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/payments/TouchToFillCreditCardViewTest.java b/chrome/browser/touch_to_fill/autofill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/payments/TouchToFillCreditCardViewTest.java index 5468553..1841305 100644 --- a/chrome/browser/touch_to_fill/autofill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/payments/TouchToFillCreditCardViewTest.java +++ b/chrome/browser/touch_to_fill/autofill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/payments/TouchToFillCreditCardViewTest.java
@@ -4,7 +4,9 @@ package org.chromium.chrome.browser.touch_to_fill.payments; +import static androidx.test.espresso.Espresso.onView; import static androidx.test.espresso.matcher.ViewMatchers.assertThat; +import static androidx.test.espresso.matcher.ViewMatchers.withText; import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertEquals; @@ -13,10 +15,10 @@ import static org.junit.Assert.fail; import static org.chromium.base.test.util.CriteriaHelper.pollUiThread; +import static org.chromium.chrome.browser.autofill.AutofillTestHelper.createClickActionWithFlags; import static org.chromium.chrome.browser.autofill.AutofillTestHelper.createCreditCard; import static org.chromium.chrome.browser.autofill.AutofillTestHelper.createLocalCreditCard; import static org.chromium.chrome.browser.autofill.AutofillTestHelper.createVirtualCreditCard; -import static org.chromium.chrome.browser.autofill.AutofillTestHelper.singleClickView; import static org.chromium.chrome.browser.touch_to_fill.payments.TouchToFillCreditCardProperties.DISMISS_HANDLER; import static org.chromium.chrome.browser.touch_to_fill.payments.TouchToFillCreditCardProperties.ItemType.CREDIT_CARD; import static org.chromium.chrome.browser.touch_to_fill.payments.TouchToFillCreditCardProperties.ItemType.FILL_BUTTON; @@ -331,11 +333,22 @@ BottomSheetTestSupport.waitForOpen(mBottomSheetController); // Make sure touch events are ignored if something is drawn on top the the bottom sheet. - RecyclerView view = getCreditCards(); - for (int i = 0; i < view.getChildCount(); i++) { - singleClickView(view.getChildAt(i), MotionEvent.FLAG_WINDOW_IS_OBSCURED); - singleClickView(view.getChildAt(i), MotionEvent.FLAG_WINDOW_IS_PARTIALLY_OBSCURED); - } + onView(withText(NICKNAMED_VISA.getCardNameForAutofillDisplay())) + .perform(createClickActionWithFlags(MotionEvent.FLAG_WINDOW_IS_OBSCURED)); + onView(withText(NICKNAMED_VISA.getCardNameForAutofillDisplay())) + .perform(createClickActionWithFlags(MotionEvent.FLAG_WINDOW_IS_PARTIALLY_OBSCURED)); + onView( + withText( + mActivityTestRule + .getActivity() + .getString(R.string.autofill_credit_card_continue_button))) + .perform(createClickActionWithFlags(MotionEvent.FLAG_WINDOW_IS_OBSCURED)); + onView( + withText( + mActivityTestRule + .getActivity() + .getString(R.string.autofill_credit_card_continue_button))) + .perform(createClickActionWithFlags(MotionEvent.FLAG_WINDOW_IS_PARTIALLY_OBSCURED)); } @Test
diff --git a/chrome/browser/touch_to_fill/password_manager/android/BUILD.gn b/chrome/browser/touch_to_fill/password_manager/android/BUILD.gn index 8739504..0f47e68 100644 --- a/chrome/browser/touch_to_fill/password_manager/android/BUILD.gn +++ b/chrome/browser/touch_to_fill/password_manager/android/BUILD.gn
@@ -114,6 +114,7 @@ "//chrome/android:chrome_java", "//chrome/android:chrome_test_java", "//chrome/android:chrome_test_util_java", + "//chrome/browser/autofill/test:test_support_java", "//chrome/browser/flags:java", "//chrome/browser/password_manager/android:password_manager_resource_provider_java", "//chrome/browser/password_manager/android:public_impl_java",
diff --git a/chrome/browser/touch_to_fill/password_manager/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillViewHolder.java b/chrome/browser/touch_to_fill/password_manager/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillViewHolder.java index 5ed1e3f..0a1a1ec 100644 --- a/chrome/browser/touch_to_fill/password_manager/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillViewHolder.java +++ b/chrome/browser/touch_to_fill/password_manager/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillViewHolder.java
@@ -4,7 +4,9 @@ package org.chromium.chrome.browser.touch_to_fill; +import android.annotation.SuppressLint; import android.view.LayoutInflater; +import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; @@ -19,18 +21,24 @@ class TouchToFillViewHolder extends RecyclerView.ViewHolder { private final ViewBinder<PropertyModel, View, PropertyKey> mViewBinder; + @SuppressLint("ClickableViewAccessibility") TouchToFillViewHolder( ViewGroup parent, @LayoutRes int layout, ViewBinder<PropertyModel, View, PropertyKey> viewBinder) { super(LayoutInflater.from(parent.getContext()).inflate(layout, parent, false)); mViewBinder = viewBinder; + itemView.setFilterTouchesWhenObscured(true); + itemView.setOnTouchListener( + (View v, MotionEvent ev) -> + (ev.getFlags() & MotionEvent.FLAG_WINDOW_IS_PARTIALLY_OBSCURED) != 0); } /** - * Called whenever an item is bound to this view holder. Please note that this method - * might be called on the same list entry repeatedly, so make sure to always set a default - * for unused fields. + * Called whenever an item is bound to this view holder. Please note that this method might be + * called on the same list entry repeatedly, so make sure to always set a default for unused + * fields. + * * @param model The {@link PropertyModel} whose data needs to be displayed. */ void setupModelChangeProcessor(PropertyModel model) {
diff --git a/chrome/browser/touch_to_fill/password_manager/android/javatests/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillViewTest.java b/chrome/browser/touch_to_fill/password_manager/android/javatests/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillViewTest.java index cd5ee37..0116f96 100644 --- a/chrome/browser/touch_to_fill/password_manager/android/javatests/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillViewTest.java +++ b/chrome/browser/touch_to_fill/password_manager/android/javatests/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillViewTest.java
@@ -5,17 +5,21 @@ package org.chromium.chrome.browser.touch_to_fill; import static androidx.test.espresso.matcher.ViewMatchers.assertThat; +import static androidx.test.espresso.matcher.ViewMatchers.withId; import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.timeout; +import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.chromium.base.test.util.CriteriaHelper.pollUiThread; +import static org.chromium.chrome.browser.autofill.AutofillTestHelper.createClickActionWithFlags; import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.CredentialProperties.CREDENTIAL; import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.CredentialProperties.FORMATTED_ORIGIN; import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.CredentialProperties.ITEM_COLLECTION_INFO; @@ -32,10 +36,12 @@ import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.VISIBLE; import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.WebAuthnCredentialProperties.WEBAUTHN_CREDENTIAL; import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.WebAuthnCredentialProperties.WEBAUTHN_ITEM_COLLECTION_INFO; +import static org.chromium.ui.test.util.ViewUtils.onViewWaiting; import static java.util.Arrays.asList; import android.text.method.PasswordTransformationMethod; +import android.view.MotionEvent; import android.view.View; import android.widget.TextView; @@ -488,6 +494,35 @@ @Test @MediumTest + public void testClicksThroughObscuringSurfacesAreIgnored() { + TestThreadUtils.runOnUiThreadBlocking( + () -> { + mModel.get(SHEET_ITEMS) + .addAll( + asList( + buildCredentialItem(ANA, mItemCollectionInfo), + buildConfirmationButton(ANA, false), + buildFooterItem(false))); + mModel.set(VISIBLE, true); + }); + BottomSheetTestSupport.waitForOpen(mBottomSheetController); + + assertNotNull(getCredentials().getChildAt(0)); + assertNotNull(getCredentials().getChildAt(1)); + + onViewWaiting(withId(R.id.username)) + .perform(createClickActionWithFlags(MotionEvent.FLAG_WINDOW_IS_OBSCURED)); + onViewWaiting(withId(R.id.username)) + .perform(createClickActionWithFlags(MotionEvent.FLAG_WINDOW_IS_PARTIALLY_OBSCURED)); + onViewWaiting(withId(R.id.touch_to_fill_button_title)) + .perform(createClickActionWithFlags(MotionEvent.FLAG_WINDOW_IS_OBSCURED)); + onViewWaiting(withId(R.id.touch_to_fill_button_title)) + .perform(createClickActionWithFlags(MotionEvent.FLAG_WINDOW_IS_PARTIALLY_OBSCURED)); + verify(mCredentialCallback, times(0)).onResult(any()); + } + + @Test + @MediumTest public void testButtonTitleWithoutAutoSubmission() { final boolean showSubmitButton = false; TestThreadUtils.runOnUiThreadBlocking(
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/LocationBarMediator.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/LocationBarMediator.java index a2079bf..811dd6c 100644 --- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/LocationBarMediator.java +++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/LocationBarMediator.java
@@ -525,12 +525,7 @@ // TODO(crbug.com/1085812): Should be taking a full loaded LoadUrlParams. if (mOverrideUrlLoadingDelegate.willHandleLoadUrlWithPostData( - omniboxLoadUrlParams.url, - omniboxLoadUrlParams.transitionType, - omniboxLoadUrlParams.inputStartTimestamp, - omniboxLoadUrlParams.postDataType, - omniboxLoadUrlParams.postData, - mLocationBarDataProvider.isIncognito())) { + omniboxLoadUrlParams, mLocationBarDataProvider.isIncognito())) { return; }
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/LocationBarMediatorTest.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/LocationBarMediatorTest.java index 91bc6573..3757e76 100644 --- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/LocationBarMediatorTest.java +++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/LocationBarMediatorTest.java
@@ -451,18 +451,26 @@ mMediator.onFinishNativeInitialization(); doReturn(mTab).when(mLocationBarDataProvider).getTab(); + ArgumentCaptor<OmniboxLoadUrlParams> captor = + ArgumentCaptor.forClass(OmniboxLoadUrlParams.class); doReturn(true) .when(mOverrideUrlLoadingDelegate) - .willHandleLoadUrlWithPostData( - TEST_URL, PageTransition.TYPED, 0, null, null, false); + .willHandleLoadUrlWithPostData(any(), anyBoolean()); mMediator.loadUrl( new OmniboxLoadUrlParams.Builder(TEST_URL, PageTransition.TYPED) .setOpenInNewTab(false) .build()); verify(mOverrideUrlLoadingDelegate) - .willHandleLoadUrlWithPostData( - TEST_URL, PageTransition.TYPED, 0, null, null, false); + .willHandleLoadUrlWithPostData(captor.capture(), anyBoolean()); + + var params = captor.getValue(); + assertEquals(TEST_URL, params.url); + assertEquals(PageTransition.TYPED, params.transitionType); + assertEquals(0, params.inputStartTimestamp); + assertNull(null, params.postData); + assertNull(null, params.postDataType); + assertFalse(params.openInNewTab); verify(mTab, times(0)).loadUrl(any()); } @@ -1217,22 +1225,8 @@ // Test clicking omnibox on {@link NewTabPage}. doReturn(false) .when(mOverrideUrlLoadingDelegate) - .willHandleLoadUrlWithPostData( - eq(TEST_URL), - eq(PageTransition.TYPED), - eq(0), - eq(null), - eq(null), - anyBoolean()); - doReturn(false) - .when(mOverrideUrlLoadingDelegate) - .willHandleLoadUrlWithPostData( - eq(TEST_URL), - eq(PageTransition.TYPED), - eq(0), - eq(null), - eq(null), - anyBoolean()); + .willHandleLoadUrlWithPostData(any(), anyBoolean()); + doReturn(true).when(mTab).isNativePage(); ShadowUrlUtilities.sIsNtp = true; assertTrue(UrlUtilities.isNtpUrl(mTab.getUrl())); @@ -1291,12 +1285,7 @@ // Test clicking omnibox on {@link StartSurface}. doReturn(true) .when(mOverrideUrlLoadingDelegate) - .willHandleLoadUrlWithPostData( - TEST_URL, PageTransition.TYPED, 0, null, null, false); - doReturn(true) - .when(mOverrideUrlLoadingDelegate) - .willHandleLoadUrlWithPostData( - TEST_URL, PageTransition.GENERATED, 0, null, null, false); + .willHandleLoadUrlWithPostData(any(), anyBoolean()); // Test navigating using omnibox. mMediator.loadUrl( new OmniboxLoadUrlParams.Builder(TEST_URL, PageTransition.TYPED)
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/OverrideUrlLoadingDelegate.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/OverrideUrlLoadingDelegate.java index 5ab1555..a3a3380 100644 --- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/OverrideUrlLoadingDelegate.java +++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/OverrideUrlLoadingDelegate.java
@@ -4,7 +4,7 @@ package org.chromium.chrome.browser.omnibox; -import org.chromium.ui.base.PageTransition; +import org.chromium.chrome.browser.omnibox.suggestions.OmniboxLoadUrlParams; /** * Delegate interface that allows implementers to override the default URL loading behavior of the @@ -12,11 +12,5 @@ */ public interface OverrideUrlLoadingDelegate { /** Returns true if the delegate will handle loading for the given parameters. */ - boolean willHandleLoadUrlWithPostData( - String url, - @PageTransition int transition, - long inputStart, - String postDataType, - byte[] postData, - boolean incognito); + boolean willHandleLoadUrlWithPostData(OmniboxLoadUrlParams params, boolean incognito); }
diff --git a/chrome/browser/ui/android/signin/BUILD.gn b/chrome/browser/ui/android/signin/BUILD.gn index 9e1d81d..f7cc246 100644 --- a/chrome/browser/ui/android/signin/BUILD.gn +++ b/chrome/browser/ui/android/signin/BUILD.gn
@@ -209,6 +209,7 @@ "java/src/org/chromium/chrome/browser/ui/signin/SyncPromoControllerUITest.java", "java/src/org/chromium/chrome/browser/ui/signin/account_picker/AccountPickerBottomSheetRenderTest.java", "java/src/org/chromium/chrome/browser/ui/signin/account_picker/AccountPickerBottomSheetTest.java", + "java/src/org/chromium/chrome/browser/ui/signin/account_picker/AccountPickerBottomSheetTestUtil.java", "java/src/org/chromium/chrome/browser/ui/signin/history_sync/HistorySyncRenderTest.java", "java/src/org/chromium/chrome/browser/ui/signin/history_sync/HistorySyncTest.java", ]
diff --git a/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/SigninAccountPickerCoordinator.java b/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/SigninAccountPickerCoordinator.java index 4749d998..6a9f3a2 100644 --- a/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/SigninAccountPickerCoordinator.java +++ b/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/SigninAccountPickerCoordinator.java
@@ -138,12 +138,16 @@ bottomSheetBackPressHandler, SecondaryActivity.SIGNIN_AND_HISTORY_OPT_IN); + // TODO(crbug.com/41493768): Update the sign-in flow API to accept strings from embedder, + // and do not initialize AccountPickerBottomSheetStrings here. + AccountPickerBottomSheetStrings strings = + new AccountPickerBottomSheetStrings(R.string.sign_in_to_chrome, 0, 0); mAccountPickerBottomSheetCoordinator = new AccountPickerBottomSheetCoordinator( mWindowAndroid, mBottomSheetController, this, - new AccountPickerBottomSheetStrings() {}, + strings, mDeviceLockActivityLauncher, mAccountPickerLaunchMode, mSigninAccessPoint == SigninAccessPoint.WEB_SIGNIN,
diff --git a/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/account_picker/AccountPickerBottomSheetRenderTest.java b/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/account_picker/AccountPickerBottomSheetRenderTest.java index 1832848..89e2557 100644 --- a/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/account_picker/AccountPickerBottomSheetRenderTest.java +++ b/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/account_picker/AccountPickerBottomSheetRenderTest.java
@@ -35,7 +35,6 @@ import org.chromium.base.test.util.Restriction; import org.chromium.chrome.browser.flags.ChromeSwitches; import org.chromium.chrome.browser.night_mode.ChromeNightModeTestUtils; -import org.chromium.chrome.browser.share.send_tab_to_self.SendTabToSelfCoordinator; import org.chromium.chrome.browser.ui.signin.R; import org.chromium.chrome.test.ChromeJUnit4RunnerDelegate; import org.chromium.chrome.test.ChromeTabbedActivityTestRule; @@ -191,6 +190,22 @@ @MediumTest @Feature("RenderTest") @ParameterAnnotations.UseMethodParameter(NightModeTestUtils.NightModeParams.class) + public void testCollapsedSheetWithAccountViewForBookmarksEntryPoint(boolean nightModeEnabled) + throws IOException { + mSigninAccessPoint = SigninAccessPoint.BOOKMARK_MANAGER; + mAccountManagerTestRule.addAccount(TEST_EMAIL1, FULL_NAME1, GIVEN_NAME1, null); + buildAndShowCollapsedBottomSheet(); + ViewUtils.waitForVisibleView(allOf(withText(TEST_EMAIL1), isDisplayed())); + ViewUtils.waitForVisibleView(allOf(withText(FULL_NAME1), isDisplayed())); + mRenderTestRule.render( + mCoordinator.getBottomSheetViewForTesting(), + "collapsed_sheet_with_account_for_bookmarks"); + } + + @Test + @MediumTest + @Feature("RenderTest") + @ParameterAnnotations.UseMethodParameter(NightModeTestUtils.NightModeParams.class) public void testExpandedSheetViewForWebSigninEntryPoint(boolean nightModeEnabled) throws IOException { mAccountManagerTestRule.addAccount(TEST_EMAIL1); @@ -219,6 +234,21 @@ @MediumTest @Feature("RenderTest") @ParameterAnnotations.UseMethodParameter(NightModeTestUtils.NightModeParams.class) + public void testExpandedSheetViewForBookmarksEntryPoint(boolean nightModeEnabled) + throws IOException { + mSigninAccessPoint = SigninAccessPoint.BOOKMARK_MANAGER; + mAccountManagerTestRule.addAccount(TEST_EMAIL1); + mAccountManagerTestRule.addAccount(TEST_EMAIL2); + buildAndShowCollapsedBottomSheet(); + expandBottomSheet(); + mRenderTestRule.render( + mCoordinator.getBottomSheetViewForTesting(), "expanded_sheet_for_bookmarks"); + } + + @Test + @MediumTest + @Feature("RenderTest") + @ParameterAnnotations.UseMethodParameter(NightModeTestUtils.NightModeParams.class) public void testSignInInProgressView(boolean nightModeEnabled) throws IOException { mAccountManagerTestRule.addAccount(TEST_EMAIL1); buildAndShowCollapsedBottomSheet(); @@ -340,10 +370,6 @@ } private void buildAndShowCollapsedBottomSheet() { - AccountPickerBottomSheetStrings accountPickerBottomSheetStrings = - mSigninAccessPoint == SigninAccessPoint.SEND_TAB_TO_SELF_PROMO - ? new SendTabToSelfCoordinator.BottomSheetStrings() - : new AccountPickerBottomSheetStrings() {}; TestThreadUtils.runOnUiThreadBlocking( () -> { mCoordinator = @@ -351,7 +377,8 @@ mActivityTestRule.getActivity().getWindowAndroid(), getBottomSheetController(), mAccountPickerDelegate, - accountPickerBottomSheetStrings, + AccountPickerBottomSheetTestUtil.getBottomSheetStrings( + mSigninAccessPoint), null, AccountPickerLaunchMode.DEFAULT, /* isWebSignin= */ mSigninAccessPoint
diff --git a/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/account_picker/AccountPickerBottomSheetStrings.java b/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/account_picker/AccountPickerBottomSheetStrings.java index 8182def1..12c58022 100644 --- a/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/account_picker/AccountPickerBottomSheetStrings.java +++ b/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/account_picker/AccountPickerBottomSheetStrings.java
@@ -5,25 +5,27 @@ import androidx.annotation.StringRes; -import org.chromium.chrome.browser.ui.signin.R; +/* Class containing string resource ids for the sign-in account picker bottom sheet. */ +public final class AccountPickerBottomSheetStrings { + public final @StringRes int titleStringId; + public final @StringRes int subtitleStringId; + public final @StringRes int dismissButtonStringId; -/** - * Interface to support different implementations for bottom sheet signin - * dialog strings. - */ -public interface AccountPickerBottomSheetStrings { - /** Returns the title string for the bottom sheet dialog. */ - default @StringRes int getTitle() { - return R.string.signin_account_picker_dialog_title; - } + /** + * Create the object containing string ids for the sign-in bottom sheet. + * + * @param titleStringId ID for the title string. Should be a non-zero valid string ID. + * @param subtitleStringId ID for the subtitle string. + * @param dismissButtonStringId ID for the skip button string. + */ + public AccountPickerBottomSheetStrings( + @StringRes int titleStringId, + @StringRes int subtitleStringId, + @StringRes int dismissButtonStringId) { + assert titleStringId != 0; - /** Returns the subtitle string for the bottom sheet dialog. */ - default @StringRes int getSubtitle() { - return R.string.signin_account_picker_bottom_sheet_subtitle; - } - - /** Returns the cancel button string for the bottom sheet dialog. */ - default @StringRes int getDismissButton() { - return R.string.signin_account_picker_dismiss_button; + this.titleStringId = titleStringId; + this.subtitleStringId = subtitleStringId; + this.dismissButtonStringId = dismissButtonStringId; } }
diff --git a/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/account_picker/AccountPickerBottomSheetTest.java b/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/account_picker/AccountPickerBottomSheetTest.java index 516eacd..beaa8be3 100644 --- a/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/account_picker/AccountPickerBottomSheetTest.java +++ b/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/account_picker/AccountPickerBottomSheetTest.java
@@ -8,6 +8,7 @@ import static androidx.test.espresso.action.ViewActions.click; import static androidx.test.espresso.assertion.ViewAssertions.doesNotExist; import static androidx.test.espresso.assertion.ViewAssertions.matches; +import static androidx.test.espresso.matcher.ViewMatchers.Visibility.GONE; import static androidx.test.espresso.matcher.ViewMatchers.Visibility.VISIBLE; import static androidx.test.espresso.matcher.ViewMatchers.isCompletelyDisplayed; import static androidx.test.espresso.matcher.ViewMatchers.isDescendantOfA; @@ -67,7 +68,6 @@ import org.chromium.chrome.browser.flags.ChromeSwitches; import org.chromium.chrome.browser.preferences.ChromePreferenceKeys; import org.chromium.chrome.browser.preferences.ChromeSharedPreferences; -import org.chromium.chrome.browser.share.send_tab_to_self.SendTabToSelfCoordinator; import org.chromium.chrome.browser.signin.services.SigninPreferencesManager; import org.chromium.chrome.browser.ui.signin.R; import org.chromium.chrome.test.AutomotiveContextWrapperTestRule; @@ -223,7 +223,8 @@ sActivityTestRule.getActivity().getWindowAndroid(), getBottomSheetController(), mAccountPickerDelegateMock, - new AccountPickerBottomSheetStrings() {}, + AccountPickerBottomSheetTestUtil.getBottomSheetStrings( + mSigninAccessPoint), new CustomDeviceLockActivityLauncher(), AccountPickerLaunchMode.DEFAULT, /* isWebSignin= */ mSigninAccessPoint @@ -247,7 +248,8 @@ sActivityTestRule.getActivity().getWindowAndroid(), getBottomSheetController(), mAccountPickerDelegateMock, - new AccountPickerBottomSheetStrings() {}, + AccountPickerBottomSheetTestUtil.getBottomSheetStrings( + mSigninAccessPoint), new CustomDeviceLockActivityLauncher(), AccountPickerLaunchMode.CHOOSE_ACCOUNT, /* isWebSignin= */ mSigninAccessPoint @@ -474,7 +476,8 @@ sActivityTestRule.getActivity().getWindowAndroid(), getBottomSheetController(), mAccountPickerDelegateMock, - new AccountPickerBottomSheetStrings() {}, + AccountPickerBottomSheetTestUtil.getBottomSheetStrings( + mSigninAccessPoint), null, AccountPickerLaunchMode.DEFAULT, /* isWebSignin= */ mSigninAccessPoint @@ -767,6 +770,61 @@ @Test @MediumTest + public void testCollapsedSheetForBookmarks() { + mSigninAccessPoint = SigninAccessPoint.BOOKMARK_MANAGER; + buildAndShowBottomSheet(AccountPickerLaunchMode.DEFAULT); + + onViewFullyShownInParent( + withText(R.string.sign_in_to_chrome), R.id.account_picker_state_collapsed) + .check(matches(isDisplayed())); + onView( + allOf( + withId(R.id.account_picker_header_subtitle), + isDescendantOfA(withId(R.id.account_picker_state_collapsed)))) + .check(matches(withEffectiveVisibility(GONE))); + onView( + allOf( + withId(R.id.account_picker_dismiss_button), + isDescendantOfA(withId(R.id.account_picker_state_collapsed)))) + .check(matches(withEffectiveVisibility(GONE))); + } + + @Test + @MediumTest + public void testExpandedSheetForBookmarks() { + mSigninAccessPoint = SigninAccessPoint.BOOKMARK_MANAGER; + buildAndShowCollapsedThenExpandedBottomSheet(); + + onViewFullyShownInParent( + withText(R.string.sign_in_to_chrome), R.id.account_picker_state_expanded) + .check(matches(isDisplayed())); + onView( + allOf( + withId(R.id.account_picker_header_subtitle), + isDescendantOfA(withId(R.id.account_picker_state_expanded)))) + .check(matches(withEffectiveVisibility(GONE))); + onView( + allOf( + withId(R.id.account_picker_dismiss_button), + isDescendantOfA(withId(R.id.account_picker_state_expanded)))) + .check(doesNotExist()); + } + + @Test + @MediumTest + public void testSigninInProgressSheetForBookmarks() { + mSigninAccessPoint = SigninAccessPoint.BOOKMARK_MANAGER; + buildAndShowBottomSheet(AccountPickerLaunchMode.DEFAULT); + + clickContinueButtonAndCheckSignInInProgressSheet(); + + onVisibleView(withText(R.string.sign_in_to_chrome)).check(doesNotExist()); + onVisibleView(withId(R.id.account_picker_header_subtitle)).check(doesNotExist()); + onVisibleView(withId(R.id.account_picker_dismiss_button)).check(doesNotExist()); + } + + @Test + @MediumTest @SuppressWarnings("CheckReturnValue") public void testSigninWithAddedAccount() { var accountConsistencyHistogram = @@ -1248,10 +1306,6 @@ } private void buildAndShowBottomSheet(@AccountPickerLaunchMode int launchMode) { - AccountPickerBottomSheetStrings accountPickerBottomSheetStrings = - mSigninAccessPoint == SigninAccessPoint.SEND_TAB_TO_SELF_PROMO - ? new SendTabToSelfCoordinator.BottomSheetStrings() - : new AccountPickerBottomSheetStrings() {}; mDeviceLockActivityLauncher = new CustomDeviceLockActivityLauncher(); TestThreadUtils.runOnUiThreadBlocking( () -> { @@ -1260,7 +1314,8 @@ sActivityTestRule.getActivity().getWindowAndroid(), getBottomSheetController(), mAccountPickerDelegateMock, - accountPickerBottomSheetStrings, + AccountPickerBottomSheetTestUtil.getBottomSheetStrings( + mSigninAccessPoint), mDeviceLockActivityLauncher, launchMode, /* isWebSignin= */ mSigninAccessPoint
diff --git a/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/account_picker/AccountPickerBottomSheetTestUtil.java b/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/account_picker/AccountPickerBottomSheetTestUtil.java new file mode 100644 index 0000000..5b386cd --- /dev/null +++ b/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/account_picker/AccountPickerBottomSheetTestUtil.java
@@ -0,0 +1,30 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.ui.signin.account_picker; + +import org.chromium.chrome.browser.ui.signin.R; +import org.chromium.components.signin.metrics.SigninAccessPoint; + +final class AccountPickerBottomSheetTestUtil { + static AccountPickerBottomSheetStrings getBottomSheetStrings( + @SigninAccessPoint int accessPoint) { + switch (accessPoint) { + case SigninAccessPoint.SEND_TAB_TO_SELF_PROMO: + return new AccountPickerBottomSheetStrings( + R.string.signin_account_picker_bottom_sheet_title_for_send_tab_to_self, + R.string.signin_account_picker_bottom_sheet_subtitle_for_send_tab_to_self, + R.string.cancel); + case SigninAccessPoint.WEB_SIGNIN: + return new AccountPickerBottomSheetStrings( + R.string.signin_account_picker_dialog_title, + R.string.signin_account_picker_bottom_sheet_subtitle, + R.string.signin_account_picker_dismiss_button); + case SigninAccessPoint.BOOKMARK_MANAGER: + return new AccountPickerBottomSheetStrings(R.string.sign_in_to_chrome, 0, 0); + default: + throw new IllegalArgumentException("Access point strings not handled in tests."); + } + } +}
diff --git a/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/account_picker/AccountPickerBottomSheetView.java b/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/account_picker/AccountPickerBottomSheetView.java index c91d199..3f49d303 100644 --- a/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/account_picker/AccountPickerBottomSheetView.java +++ b/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/account_picker/AccountPickerBottomSheetView.java
@@ -186,10 +186,23 @@ for (int viewState : viewStates) { final View view = mViewFlipper.getChildAt(viewState); ((TextView) view.findViewById(R.id.account_picker_header_title)).setText(title); - ((TextViewWithLeading) view.findViewById(R.id.account_picker_header_subtitle)) - .setText(subtitle); + + TextViewWithLeading subtitleView = + ((TextViewWithLeading) view.findViewById(R.id.account_picker_header_subtitle)); + if (subtitle == 0) { + subtitleView.setVisibility(View.GONE); + } else { + subtitleView.setText(subtitle); + subtitleView.setVisibility(View.VISIBLE); + } } - mDismissButton.setText(cancelButton); + + if (cancelButton == 0) { + mDismissButton.setVisibility(View.GONE); + } else { + mDismissButton.setText(cancelButton); + mDismissButton.setVisibility(View.VISIBLE); + } } @Override
diff --git a/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/account_picker/AccountPickerBottomSheetViewBinder.java b/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/account_picker/AccountPickerBottomSheetViewBinder.java index 4ef9063..3ed997c 100644 --- a/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/account_picker/AccountPickerBottomSheetViewBinder.java +++ b/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/account_picker/AccountPickerBottomSheetViewBinder.java
@@ -42,9 +42,9 @@ AccountPickerBottomSheetStrings bottomSheetStrings = model.get(AccountPickerBottomSheetProperties.BOTTOM_SHEET_STRINGS); view.setBottomSheetStrings( - bottomSheetStrings.getTitle(), - bottomSheetStrings.getSubtitle(), - bottomSheetStrings.getDismissButton()); + bottomSheetStrings.titleStringId, + bottomSheetStrings.subtitleStringId, + bottomSheetStrings.dismissButtonStringId); } }
diff --git a/chrome/browser/ui/ash/birch/birch_keyed_service_unittest.cc b/chrome/browser/ui/ash/birch/birch_keyed_service_unittest.cc index 51516c7c..64c398c4 100644 --- a/chrome/browser/ui/ash/birch/birch_keyed_service_unittest.cc +++ b/chrome/browser/ui/ash/birch/birch_keyed_service_unittest.cc
@@ -353,11 +353,13 @@ FileSuggestionType::kDriveFile, /*suggestions=*/std::vector<FileSuggestData>{ {FileSuggestionType::kDriveFile, file_path_1, + FileSuggestionJustificationType::kUnknown, /*new_prediction_reason=*/std::nullopt, /*timestamp=*/std::nullopt, /*secondary_timestamp=*/std::nullopt, /*new_score=*/std::nullopt}, {FileSuggestionType::kDriveFile, file_path_2, + FileSuggestionJustificationType::kUnknown, /*new_prediction_reason=*/std::nullopt, /*timestamp=*/std::nullopt, /*secondary_timestamp=*/std::nullopt,
diff --git a/chrome/browser/ui/ash/holding_space/holding_space_keyed_service_unittest.cc b/chrome/browser/ui/ash/holding_space/holding_space_keyed_service_unittest.cc index dcd6246..1df599b 100644 --- a/chrome/browser/ui/ash/holding_space/holding_space_keyed_service_unittest.cc +++ b/chrome/browser/ui/ash/holding_space/holding_space_keyed_service_unittest.cc
@@ -3622,6 +3622,7 @@ FileSuggestionType::kDriveFile, /*suggestions=*/std::vector<FileSuggestData>{ {FileSuggestionType::kDriveFile, file_path_1, + FileSuggestionJustificationType::kUnknown, /*new_prediction_reason=*/std::nullopt, /*timestamp=*/std::nullopt, /*secondary_timestamp=*/std::nullopt, @@ -3630,6 +3631,7 @@ FileSuggestionType::kLocalFile, /*suggestions=*/std::vector<FileSuggestData>{ {FileSuggestionType::kLocalFile, file_path_2, + FileSuggestionJustificationType::kUnknown, /*new_prediction_reason=*/std::nullopt, /*timestamp=*/std::nullopt, /*secondary_timestamp=*/std::nullopt, @@ -3660,6 +3662,7 @@ FileSuggestionType::kDriveFile, /*suggestions=*/std::vector<FileSuggestData>{ {FileSuggestionType::kDriveFile, file_path_1, + FileSuggestionJustificationType::kUnknown, /*new_prediction_reason=*/std::nullopt, /*timestamp=*/std::nullopt, /*secondary_timestamp=*/std::nullopt, @@ -3688,6 +3691,7 @@ FileSuggestionType::kLocalFile, /*suggestions=*/std::vector<FileSuggestData>{ {FileSuggestionType::kLocalFile, file_path_2, + FileSuggestionJustificationType::kUnknown, /*new_prediction_reason=*/std::nullopt, /*timestamp=*/std::nullopt, /*secondary_timestamp=*/std::nullopt, @@ -3707,11 +3711,13 @@ FileSuggestionType::kDriveFile, /*suggestions=*/ std::vector<FileSuggestData>{{FileSuggestionType::kDriveFile, file_path_1, + FileSuggestionJustificationType::kUnknown, /*new_prediction_reason=*/std::nullopt, /*timestamp=*/std::nullopt, /*secondary_timestamp=*/std::nullopt, /*new_score=*/std::nullopt}, {FileSuggestionType::kDriveFile, file_path_3, + FileSuggestionJustificationType::kUnknown, /*new_prediction_reason=*/std::nullopt, /*timestamp=*/std::nullopt, /*secondary_timestamp=*/std::nullopt, @@ -3761,16 +3767,19 @@ FileSuggestionType::kLocalFile, /*suggestions=*/std::vector<FileSuggestData>{ {FileSuggestionType::kLocalFile, downloads_path, + ash::FileSuggestionJustificationType::kUnknown, /*new_prediction_reason=*/std::nullopt, /*timestamp=*/std::nullopt, /*secondary_timestamp=*/std::nullopt, /*new_score=*/std::nullopt}, {FileSuggestionType::kLocalFile, other_folder_path, + ash::FileSuggestionJustificationType::kUnknown, /*new_prediction_reason=*/std::nullopt, /*timestamp=*/std::nullopt, /*secondary_timestamp=*/std::nullopt, /*new_score=*/std::nullopt}, {FileSuggestionType::kLocalFile, file_path, + ash::FileSuggestionJustificationType::kUnknown, /*new_prediction_reason=*/std::nullopt, /*timestamp=*/std::nullopt, /*secondary_timestamp=*/std::nullopt, @@ -3800,6 +3809,7 @@ FileSuggestionType::kDriveFile, /*suggestions=*/std::vector<FileSuggestData>{ {FileSuggestionType::kDriveFile, file_path_1, + FileSuggestionJustificationType::kUnknown, /*new_prediction_reason=*/std::nullopt, /*timestamp=*/std::nullopt, /*secondary_timestamp=*/std::nullopt, @@ -3828,6 +3838,7 @@ FileSuggestionType::kLocalFile, /*suggestions=*/std::vector<FileSuggestData>{ {FileSuggestionType::kLocalFile, file_path_2, + FileSuggestionJustificationType::kUnknown, /*new_prediction_reason=*/std::nullopt, /*timestamp=*/std::nullopt, /*secondary_timestamp=*/std::nullopt, @@ -3949,6 +3960,7 @@ ->SetSuggestionsForType(FileSuggestionType::kLocalFile, /*suggestions=*/std::vector<FileSuggestData>{ {FileSuggestionType::kLocalFile, local_file, + FileSuggestionJustificationType::kUnknown, /*new_prediction_reason=*/std::nullopt, /*timestamp=*/std::nullopt, /*secondary_timestamp=*/std::nullopt, @@ -4011,6 +4023,7 @@ ->SetSuggestionsForType(FileSuggestionType::kLocalFile, /*suggestions=*/std::vector<FileSuggestData>{ {FileSuggestionType::kLocalFile, local_file, + FileSuggestionJustificationType::kUnknown, /*new_prediction_reason=*/std::nullopt, /*timestamp=*/std::nullopt, /*secondary_timestamp=*/std::nullopt,
diff --git a/chrome/browser/ui/bookmarks/bookmark_tab_helper.cc b/chrome/browser/ui/bookmarks/bookmark_tab_helper.cc index 551ac47..b455671 100644 --- a/chrome/browser/ui/bookmarks/bookmark_tab_helper.cc +++ b/chrome/browser/ui/bookmarks/bookmark_tab_helper.cc
@@ -14,11 +14,14 @@ #include "chrome/browser/ui/bookmarks/bookmark_tab_helper_observer.h" #include "chrome/browser/ui/bookmarks/bookmark_utils.h" #include "chrome/browser/ui/sad_tab.h" +#include "chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_keyed_service.h" +#include "chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_service_factory.h" #include "chrome/browser/ui/webui/new_tab_page/new_tab_page_ui.h" #include "chrome/browser/ui/webui/new_tab_page_third_party/new_tab_page_third_party_ui.h" #include "chrome/browser/ui/webui/ntp/new_tab_ui.h" #include "components/bookmarks/browser/bookmark_model.h" #include "components/bookmarks/common/bookmark_pref_names.h" +#include "components/saved_tab_groups/saved_tab_group_model.h" #include "components/sync_preferences/pref_service_syncable.h" #include "content/public/browser/navigation_entry.h" #include "content/public/browser/navigation_handle.h" @@ -70,10 +73,17 @@ !prefs->GetBoolean(bookmarks::prefs::kShowBookmarkBar)) return false; + const bool has_bookmarks = bookmark_model_ && bookmark_model_->HasBookmarks(); + + const tab_groups::SavedTabGroupKeyedService* stg_service = + tab_groups::SavedTabGroupServiceFactory::GetInstance()->GetForProfile( + profile); + const bool has_saved_tab_groups = + stg_service && (stg_service->model()->Count() > 0); + // The bookmark bar is only shown on the NTP if the user // has added something to it. - return IsNTP(web_contents()) && bookmark_model_ && - bookmark_model_->HasBookmarks(); + return IsNTP(web_contents()) && (has_bookmarks || has_saved_tab_groups); } void BookmarkTabHelper::AddObserver(BookmarkTabHelperObserver* observer) {
diff --git a/chrome/browser/ui/cocoa/profiles/profile_menu_controller.mm b/chrome/browser/ui/cocoa/profiles/profile_menu_controller.mm index 07178ad..f7bf36c 100644 --- a/chrome/browser/ui/cocoa/profiles/profile_menu_controller.mm +++ b/chrome/browser/ui/cocoa/profiles/profile_menu_controller.mm
@@ -177,8 +177,8 @@ header = [[NSMenuItem alloc] initWithTitle:GetProfileMenuTitle() action:nil keyEquivalent:@""]; - header.enabled = NO; } + header.enabled = NO; [menu insertItem:header atIndex:offset++]; }
diff --git a/chrome/browser/ui/hats/trust_safety_sentiment_service.cc b/chrome/browser/ui/hats/trust_safety_sentiment_service.cc index 7a69558..f4c0b68 100644 --- a/chrome/browser/ui/hats/trust_safety_sentiment_service.cc +++ b/chrome/browser/ui/hats/trust_safety_sentiment_service.cc
@@ -26,6 +26,7 @@ #include "components/prefs/pref_service.h" #include "components/privacy_sandbox/privacy_sandbox_prefs.h" #include "components/privacy_sandbox/tracking_protection_prefs.h" +#include "components/safe_browsing/core/browser/db/v4_protocol_manager_util.h" #include "components/safe_browsing/core/common/safe_browsing_prefs.h" #include "components/signin/public/base/signin_pref_names.h" #include "components/unified_consent/pref_names.h" @@ -156,11 +157,11 @@ // software, or billing threat categories. bool IsOtherSBInterstitialCategory(safe_browsing::SBThreatType threat_type) { switch (threat_type) { - case safe_browsing::SB_THREAT_TYPE_URL_PHISHING: - case safe_browsing::SB_THREAT_TYPE_URL_CLIENT_SIDE_PHISHING: - case safe_browsing::SB_THREAT_TYPE_URL_MALWARE: - case safe_browsing::SB_THREAT_TYPE_URL_UNWANTED: - case safe_browsing::SB_THREAT_TYPE_BILLING: + case safe_browsing::SBThreatType::SB_THREAT_TYPE_URL_PHISHING: + case safe_browsing::SBThreatType::SB_THREAT_TYPE_URL_CLIENT_SIDE_PHISHING: + case safe_browsing::SBThreatType::SB_THREAT_TYPE_URL_MALWARE: + case safe_browsing::SBThreatType::SB_THREAT_TYPE_URL_UNWANTED: + case safe_browsing::SBThreatType::SB_THREAT_TYPE_BILLING: return false; default: return true; @@ -437,14 +438,15 @@ product_specific_data["Enhanced protection enabled"] = safe_browsing::IsEnhancedProtectionEnabled(*profile_->GetPrefs()); product_specific_data["Threat is phishing"] = - threat_type == safe_browsing::SB_THREAT_TYPE_URL_PHISHING || - threat_type == safe_browsing::SB_THREAT_TYPE_URL_CLIENT_SIDE_PHISHING; + threat_type == safe_browsing::SBThreatType::SB_THREAT_TYPE_URL_PHISHING || + threat_type == + safe_browsing::SBThreatType::SB_THREAT_TYPE_URL_CLIENT_SIDE_PHISHING; product_specific_data["Threat is malware"] = - threat_type == safe_browsing::SB_THREAT_TYPE_URL_MALWARE; + threat_type == safe_browsing::SBThreatType::SB_THREAT_TYPE_URL_MALWARE; product_specific_data["Threat is unwanted software"] = - threat_type == safe_browsing::SB_THREAT_TYPE_URL_UNWANTED; + threat_type == safe_browsing::SBThreatType::SB_THREAT_TYPE_URL_UNWANTED; product_specific_data["Threat is billing"] = - threat_type == safe_browsing::SB_THREAT_TYPE_BILLING; + threat_type == safe_browsing::SBThreatType::SB_THREAT_TYPE_BILLING; DCHECK(!IsOtherSBInterstitialCategory(threat_type)); TriggerOccurred(FeatureArea::kSafeBrowsingInterstitial, product_specific_data);
diff --git a/chrome/browser/ui/hats/trust_safety_sentiment_service_unittest.cc b/chrome/browser/ui/hats/trust_safety_sentiment_service_unittest.cc index 91519e9..24bdcda 100644 --- a/chrome/browser/ui/hats/trust_safety_sentiment_service_unittest.cc +++ b/chrome/browser/ui/hats/trust_safety_sentiment_service_unittest.cc
@@ -1311,7 +1311,7 @@ LaunchSurvey(kHatsSurveyTriggerTrustSafetyV2SafeBrowsingInterstitial, _, _, _, _)); service()->InteractedWithSafeBrowsingInterstitial( - true, safe_browsing::SB_THREAT_TYPE_URL_PHISHING); + true, safe_browsing::SBThreatType::SB_THREAT_TYPE_URL_PHISHING); service()->OpenedNewTabPage(); CheckHistograms( {TrustSafetySentimentService::FeatureArea::kSafeBrowsingInterstitial},
diff --git a/chrome/browser/ui/startup/startup_browser_creator.cc b/chrome/browser/ui/startup/startup_browser_creator.cc index 4cbd3b99..a68953b 100644 --- a/chrome/browser/ui/startup/startup_browser_creator.cc +++ b/chrome/browser/ui/startup/startup_browser_creator.cc
@@ -581,6 +581,27 @@ /*restore_tabbed_browser=*/true); } #endif // BUILDFLAG(IS_CHROMEOS_LACROS) || BUILDFLAG(ENABLE_DICE_SUPPORT) + +#if BUILDFLAG(IS_CHROMEOS_ASH) +// Returns the app id of the kiosk app associated with the current user session. +// Returns nullopt for non-kiosk user sessions and for ARC kiosk sessions, since +// crash recovery is not supported there. +std::optional<ash::KioskAppId> GetAppId(const base::CommandLine& command_line, + Profile* profile) { + const user_manager::User* user = + ash::ProfileHelper::Get()->GetUserByProfile(profile); + if (user && user->GetType() == user_manager::UserType::kKioskApp) { + return ash::KioskAppId::ForChromeApp( + command_line.GetSwitchValueASCII(::switches::kAppId), + user->GetAccountId()); + } else if (user && user->GetType() == user_manager::UserType::kWebKioskApp) { + return ash::KioskAppId::ForWebApp(user->GetAccountId()); + } else { + return std::nullopt; + } +} +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + } // namespace StartupProfileMode StartupProfileModeFromReason( @@ -1007,17 +1028,12 @@ if (chrome::IsRunningInForcedAppMode()) { Profile* profile = profile_info.profile; - user_manager::User* user = - ash::ProfileHelper::Get()->GetUserByProfile(profile); - if (user && user->GetType() == user_manager::UserType::kKioskApp) { - ash::LaunchAppOrDie( - profile, ash::KioskAppId::ForChromeApp( - command_line.GetSwitchValueASCII(switches::kAppId), - user->GetAccountId())); - } else if (user && - user->GetType() == user_manager::UserType::kWebKioskApp) { - ash::LaunchAppOrDie(profile, - ash::KioskAppId::ForWebApp(user->GetAccountId())); + + if (auto app_id = GetAppId(command_line, profile); app_id.has_value()) { + // Skip browser launch since app mode launches its app window. + silent_launch = true; + + ash::LaunchAppOrDie(profile, app_id.value()); } else { // If we are here, we are either in ARC kiosk session or the user is // invalid. We should terminate the session in such cases. @@ -1025,8 +1041,6 @@ return false; } - // Skip browser launch since app mode launches its app window. - silent_launch = true; } #endif // BUILDFLAG(IS_CHROMEOS_ASH)
diff --git a/chrome/browser/ui/views/bubble/webui_bubble_manager.cc b/chrome/browser/ui/views/bubble/webui_bubble_manager.cc index dda13ab..b7a0011 100644 --- a/chrome/browser/ui/views/bubble/webui_bubble_manager.cc +++ b/chrome/browser/ui/views/bubble/webui_bubble_manager.cc
@@ -49,8 +49,6 @@ cache_timer_->Stop(); - bubble_init_start_time_ = base::TimeTicks::Now(); - WebUIContentsWarmupLevelRecorder warmup_level_recorder; warmup_level_recorder.BeforeContentsCreation(); bubble_view_ = CreateWebUIBubbleDialog(anchor, arrow);
diff --git a/chrome/browser/ui/views/bubble/webui_bubble_manager.h b/chrome/browser/ui/views/bubble/webui_bubble_manager.h index c62977d..ea2b2c5f0 100644 --- a/chrome/browser/ui/views/bubble/webui_bubble_manager.h +++ b/chrome/browser/ui/views/bubble/webui_bubble_manager.h
@@ -10,6 +10,7 @@ #include <string> #include <utility> +#include "base/functional/callback_forward.h" #include "base/memory/raw_ptr.h" #include "base/metrics/histogram_functions.h" #include "base/scoped_observation.h" @@ -55,9 +56,16 @@ views::Widget* GetBubbleWidget() const; + // Register a callback that will be invoked when the bubble widget is + // initialized. This is used for metrics collections. + void set_widget_initialization_callback(base::OnceClosure callback) { + widget_initialization_callback_ = std::move(callback); + } + bool bubble_using_cached_web_contents() const { return bubble_using_cached_web_contents_; } + WebUIContentsWarmupLevel contents_warmup_level() const { CHECK(contents_warmup_level_.has_value()); return *contents_warmup_level_; @@ -92,7 +100,8 @@ bubble_using_cached_web_contents_ = is_cached; } - std::optional<base::TimeTicks> bubble_init_start_time_; + // A callback that will be invoked when the bubble widget is initialized. + base::OnceClosure widget_initialization_callback_; private: void ResetContentsWrapper(); @@ -223,16 +232,9 @@ auto bubble_view = std::make_unique<WebUIBubbleDialogView>( anchor_view_, contents_wrapper->GetWeakPtr(), anchor, arrow); - // Register callback to emit histogram when the widget is created - if (bubble_init_start_time_) { - bubble_view->RegisterWidgetInitializedCallback(base::BindOnce( - [](base::TimeTicks bubble_init_start_time) { - base::UmaHistogramMediumTimes( - "Tabs.TabSearch.BubbleWidgetInitializationTime", - base::TimeTicks::Now() - bubble_init_start_time); - }, - *bubble_init_start_time_)); - bubble_init_start_time_.reset(); + if (!widget_initialization_callback_.is_null()) { + bubble_view->RegisterWidgetInitializedCallback( + std::move(widget_initialization_callback_)); } auto weak_ptr = bubble_view->GetWeakPtr();
diff --git a/chrome/browser/ui/views/media_preview/media_view_controller_base.cc b/chrome/browser/ui/views/media_preview/media_view_controller_base.cc index 3f91425e..11f15cf 100644 --- a/chrome/browser/ui/views/media_preview/media_view_controller_base.cc +++ b/chrome/browser/ui/views/media_preview/media_view_controller_base.cc
@@ -119,17 +119,19 @@ device_selector_combobox_->SetVisible(allow_device_selection_); OnComboboxSelection(); base_view_->RefreshSize(); - if (allow_device_selection_) { - AnnounceDynamicChangeIfNeeded( - previous_device_name, - l10n_util::GetStringFUTF16( - IDS_MEDIA_PREVIEW_ANNOUNCE_SELECTED_DEVICE_CHANGE, - device_name_label_->GetText())); - } + AnnounceDynamicChangeIfNeeded( + previous_device_name, + l10n_util::GetStringFUTF16( + IDS_MEDIA_PREVIEW_ANNOUNCE_SELECTED_DEVICE_CHANGE, + device_name_label_->GetText())); } void MediaViewControllerBase::OnComboboxSelection() { - source_change_callback_.Run(device_selector_combobox_->GetSelectedIndex()); + auto index = device_selector_combobox_->GetSelectedIndex(); + if (index) { + UpdateDeviceNameLabel(); + source_change_callback_.Run(index); + } } void MediaViewControllerBase::UpdateDeviceNameLabel() { @@ -148,6 +150,10 @@ return; } + if (!allow_device_selection_) { + return; + } + if (previous_device_name == device_name_label_->GetText()) { return; }
diff --git a/chrome/browser/ui/views/tab_search_bubble_host.cc b/chrome/browser/ui/views/tab_search_bubble_host.cc index 9a11177..c9c5eeb34 100644 --- a/chrome/browser/ui/views/tab_search_bubble_host.cc +++ b/chrome/browser/ui/views/tab_search_bubble_host.cc
@@ -186,6 +186,13 @@ } bubble_created_time_ = base::TimeTicks::Now(); + webui_bubble_manager_->set_widget_initialization_callback(base::BindOnce( + [](base::TimeTicks bubble_init_start_time) { + base::UmaHistogramMediumTimes( + "Tabs.TabSearch.BubbleWidgetInitializationTime", + base::TimeTicks::Now() - bubble_init_start_time); + }, + *bubble_created_time_)); webui_bubble_manager_->ShowBubble(anchor, ShouldTabSearchRenderBeforeTabStrip() ? views::BubbleBorder::TOP_LEFT
diff --git a/chrome/browser/ui/web_applications/web_app_link_capturing_browsertest.cc b/chrome/browser/ui/web_applications/web_app_link_capturing_browsertest.cc index 7afaa954..239cf0e 100644 --- a/chrome/browser/ui/web_applications/web_app_link_capturing_browsertest.cc +++ b/chrome/browser/ui/web_applications/web_app_link_capturing_browsertest.cc
@@ -507,8 +507,14 @@ #endif // !BUILDFLAG(IS_CHROMEOS) // Tests that link capturing works while inside a web app window. +// TODO(crbug.com/330148482): Flaky on Linux Debug bots. +#if BUILDFLAG(IS_LINUX) && !defined(NDEBUG) +#define MAYBE_LinkCaptureInWebAppWindow DISABLED_LinkCaptureInWebAppWindow +#else +#define MAYBE_LinkCaptureInWebAppWindow LinkCaptureInWebAppWindow +#endif IN_PROC_BROWSER_TEST_P(WebAppLinkCapturingBrowserTest, - LinkCaptureInWebAppWindow) { + MAYBE_LinkCaptureInWebAppWindow) { // Note: The order matters so the nested app navigation for installation // doesn't get captured by the parent app. webapps::AppId nested_app_id = InstallNestedApp();
diff --git a/chrome/browser/ui/webui/crashes_ui.cc b/chrome/browser/ui/webui/crashes_ui.cc index b211f65..17aed4fb 100644 --- a/chrome/browser/ui/webui/crashes_ui.cc +++ b/chrome/browser/ui/webui/crashes_ui.cc
@@ -190,7 +190,7 @@ IdentityManagerFactory::GetForProfile(Profile::FromWebUI(web_ui())); if (identity_manager) { is_internal = gaia::IsGoogleInternalAccountEmail( - identity_manager->GetPrimaryAccountInfo(signin::ConsentLevel::kSync) + identity_manager->GetPrimaryAccountInfo(signin::ConsentLevel::kSignin) .email); }
diff --git a/chrome/browser/web_applications/alternative_error_page_override_info_browsertest.cc b/chrome/browser/web_applications/alternative_error_page_override_info_browsertest.cc index 7d6e332..a1a0716b 100644 --- a/chrome/browser/web_applications/alternative_error_page_override_info_browsertest.cc +++ b/chrome/browser/web_applications/alternative_error_page_override_info_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 <string_view> + #include "base/strings/utf_string_conversions.h" #include "chrome/browser/chrome_content_browser_client.h" #include "chrome/browser/profiles/profile.h" @@ -37,7 +39,7 @@ // Helper function to prepare PWA and retrieve information from the // alternative error page function. content::mojom::AlternativeErrorPageOverrideInfoPtr GetErrorPageInfo( - base::StringPiece html) { + std::string_view html) { ChromeContentBrowserClient browser_client; content::ScopedContentBrowserClientSetting setting(&browser_client);
diff --git a/chrome/browser/web_applications/chrome_pwa_launcher/launcher_update_unittest.cc b/chrome/browser/web_applications/chrome_pwa_launcher/launcher_update_unittest.cc index e07ebb2..b96fc63 100644 --- a/chrome/browser/web_applications/chrome_pwa_launcher/launcher_update_unittest.cc +++ b/chrome/browser/web_applications/chrome_pwa_launcher/launcher_update_unittest.cc
@@ -4,6 +4,7 @@ #include "chrome/browser/web_applications/chrome_pwa_launcher/launcher_update.h" +#include <string_view> #include <vector> #include "base/files/file_util.h" @@ -17,7 +18,7 @@ namespace { void CreateFileAndWriteData(const base::FilePath& file_path, - const base::StringPiece& data) { + std::string_view data) { ASSERT_TRUE(base::WriteFile(file_path, data)); }
diff --git a/chrome/browser/web_applications/chromeos_web_app_experiments.cc b/chrome/browser/web_applications/chromeos_web_app_experiments.cc index 6f9779dd..5eed498 100644 --- a/chrome/browser/web_applications/chromeos_web_app_experiments.cc +++ b/chrome/browser/web_applications/chromeos_web_app_experiments.cc
@@ -4,6 +4,8 @@ #include "chrome/browser/web_applications/chromeos_web_app_experiments.h" +#include <string_view> + #include "base/containers/contains.h" #include "base/no_destructor.h" #include "base/strings/string_util.h" @@ -59,7 +61,7 @@ size_t ChromeOsWebAppExperiments::GetExtendedScopeScore( const webapps::AppId& app_id, - base::StringPiece url_spec) { + std::string_view url_spec) { DCHECK(chromeos::features::IsUploadOfficeToCloudEnabled()); size_t best_score = 0;
diff --git a/chrome/browser/web_applications/chromeos_web_app_experiments.h b/chrome/browser/web_applications/chromeos_web_app_experiments.h index ddc4701..2d15de1 100644 --- a/chrome/browser/web_applications/chromeos_web_app_experiments.h +++ b/chrome/browser/web_applications/chromeos_web_app_experiments.h
@@ -6,10 +6,10 @@ #define CHROME_BROWSER_WEB_APPLICATIONS_CHROMEOS_WEB_APP_EXPERIMENTS_H_ #include <optional> +#include <string_view> #include <vector> #include "base/containers/span.h" -#include "base/strings/string_piece.h" #include "components/webapps/common/web_app_id.h" #include "third_party/skia/include/core/SkColor.h" #include "url/gurl.h" @@ -40,7 +40,7 @@ // WebAppRegistrar::GetUrlInAppScopeScore()) for the experimental extended // scopes. static size_t GetExtendedScopeScore(const webapps::AppId& app_id, - base::StringPiece url_spec); + std::string_view url_spec); // Whether the manifest theme_color and background_color should be ignored for // `app_id`.
diff --git a/chrome/browser/web_applications/commands/install_preloaded_verified_app_command.cc b/chrome/browser/web_applications/commands/install_preloaded_verified_app_command.cc index 3c15599..f2d14068 100644 --- a/chrome/browser/web_applications/commands/install_preloaded_verified_app_command.cc +++ b/chrome/browser/web_applications/commands/install_preloaded_verified_app_command.cc
@@ -6,6 +6,7 @@ #include <memory> #include <string> +#include <string_view> #include <utility> #include "base/check_is_test.h" @@ -45,7 +46,7 @@ // TODO(crbug.com/1457430): Find a better way to do Lacros testing so that we // don't have to pass localhost into the allowlist. Allowlisted host must be // from a Google server. -constexpr auto kHostAllowlist = base::MakeFixedFlatSet<base::StringPiece>( +constexpr auto kHostAllowlist = base::MakeFixedFlatSet<std::string_view>( {"googleusercontent.com", "gstatic.com", "youtube.com", "127.0.0.1" /*FOR TESTING*/});
diff --git a/chrome/browser/web_applications/extensions/bookmark_app_util.cc b/chrome/browser/web_applications/extensions/bookmark_app_util.cc index 83b77a2..0ba969d 100644 --- a/chrome/browser/web_applications/extensions/bookmark_app_util.cc +++ b/chrome/browser/web_applications/extensions/bookmark_app_util.cc
@@ -6,9 +6,9 @@ #include <map> #include <memory> +#include <string_view> #include <utility> -#include "base/strings/string_piece.h" #include "base/values.h" #include "chrome/browser/web_applications/web_app_registrar.h" #include "chrome/browser/web_applications/web_app_utils.h" @@ -55,8 +55,8 @@ const GURL nav_scope = launch_url.GetWithoutFilename(); const int scope_str_length = nav_scope.spec().size(); - return base::StringPiece(nav_scope.spec()) == - base::StringPiece(url.spec()).substr(0, scope_str_length); + return std::string_view(nav_scope.spec()) == + std::string_view(url.spec()).substr(0, scope_str_length); } LaunchContainerAndType GetLaunchContainerAndTypeFromDisplayMode(
diff --git a/chrome/browser/web_applications/os_integration/os_integration_manager.cc b/chrome/browser/web_applications/os_integration/os_integration_manager.cc index 73249d3..682ce5a 100644 --- a/chrome/browser/web_applications/os_integration/os_integration_manager.cc +++ b/chrome/browser/web_applications/os_integration/os_integration_manager.cc
@@ -6,6 +6,7 @@ #include <memory> #include <optional> +#include <string_view> #include <utility> #include "base/atomic_ref_count.h" @@ -284,7 +285,7 @@ void OsIntegrationManager::UpdateOsHooks( const webapps::AppId& app_id, - base::StringPiece old_name, + std::string_view old_name, FileHandlerUpdateAction file_handlers_need_os_update, const WebAppInstallInfo& web_app_info, UpdateOsHooksCallback callback) { @@ -609,7 +610,7 @@ } void OsIntegrationManager::UpdateShortcuts(const webapps::AppId& app_id, - base::StringPiece old_name, + std::string_view old_name, ResultCallback callback) { base::SequencedTaskRunner::GetCurrentDefault()->PostTask( FROM_HERE, base::BindOnce(std::move(callback), Result::kOk));
diff --git a/chrome/browser/web_applications/os_integration/os_integration_manager.h b/chrome/browser/web_applications/os_integration/os_integration_manager.h index ddb02d4..cfbe743 100644 --- a/chrome/browser/web_applications/os_integration/os_integration_manager.h +++ b/chrome/browser/web_applications/os_integration/os_integration_manager.h
@@ -8,13 +8,13 @@ #include <bitset> #include <memory> #include <optional> +#include <string_view> #include <vector> #include "base/functional/callback_forward.h" #include "base/memory/raw_ptr.h" #include "base/memory/weak_ptr.h" #include "base/scoped_observation.h" -#include "base/strings/string_piece.h" #include "chrome/browser/web_applications/os_integration/os_integration_sub_manager.h" #include "chrome/browser/web_applications/os_integration/url_handler_manager.h" #include "chrome/browser/web_applications/os_integration/web_app_file_handler_manager.h" @@ -149,7 +149,7 @@ // virtual for testing virtual void UpdateOsHooks( const webapps::AppId& app_id, - base::StringPiece old_name, + std::string_view old_name, FileHandlerUpdateAction file_handlers_need_os_update, const WebAppInstallInfo& web_app_info, UpdateOsHooksCallback callback); @@ -214,7 +214,7 @@ base::OnceClosure callback); virtual void UpdateShortcuts(const webapps::AppId& app_id, - base::StringPiece old_name, + std::string_view old_name, ResultCallback callback); // WebAppRegistrarObserver:
diff --git a/chrome/browser/web_applications/os_integration/run_on_os_login_sub_manager_unittest.cc b/chrome/browser/web_applications/os_integration/run_on_os_login_sub_manager_unittest.cc index 3fb6c68..36439e1 100644 --- a/chrome/browser/web_applications/os_integration/run_on_os_login_sub_manager_unittest.cc +++ b/chrome/browser/web_applications/os_integration/run_on_os_login_sub_manager_unittest.cc
@@ -3,12 +3,12 @@ // found in the LICENSE file. #include <memory> +#include <string_view> #include <utility> #include "base/files/file_util.h" #include "base/json/json_reader.h" #include "base/memory/raw_ptr.h" -#include "base/strings/string_piece.h" #include "base/test/gmock_expected_support.h" #include "base/test/scoped_feature_list.h" #include "base/test/test_future.h" @@ -102,7 +102,7 @@ return result.Get<webapps::AppId>(); } - void SetWebAppSettingsListPref(const base::StringPiece pref) { + void SetWebAppSettingsListPref(const std::string_view pref) { ASSERT_OK_AND_ASSIGN( auto result, base::JSONReader::ReadAndReturnValueWithError(
diff --git a/chrome/browser/web_applications/os_integration/web_app_file_handler_registration_win.cc b/chrome/browser/web_applications/os_integration/web_app_file_handler_registration_win.cc index 5a7cb2c5..8808b72 100644 --- a/chrome/browser/web_applications/os_integration/web_app_file_handler_registration_win.cc +++ b/chrome/browser/web_applications/os_integration/web_app_file_handler_registration_win.cc
@@ -7,6 +7,7 @@ #include <iterator> #include <set> #include <string> +#include <string_view> #include "base/command_line.h" #include "base/files/file_path.h" @@ -80,7 +81,7 @@ result &= ShellUtil::AddFileAssociations( file_handler_progids.back(), app_specific_launcher_command, user_visible_app_name, - base::AsWString(base::StringPiece16(file_handler.display_name)), + base::AsWString(std::u16string_view(file_handler.display_name)), icon_path, file_extensions_wide); } if (!result)
diff --git a/chrome/browser/web_applications/os_integration/web_app_shortcut_linux_unittest.cc b/chrome/browser/web_applications/os_integration/web_app_shortcut_linux_unittest.cc index 774103b..872b3937 100644 --- a/chrome/browser/web_applications/os_integration/web_app_shortcut_linux_unittest.cc +++ b/chrome/browser/web_applications/os_integration/web_app_shortcut_linux_unittest.cc
@@ -9,6 +9,7 @@ #include <algorithm> #include <cstdlib> #include <map> +#include <string_view> #include <vector> #include "base/base_paths.h" @@ -20,7 +21,6 @@ #include "base/files/scoped_temp_dir.h" #include "base/logging.h" #include "base/nix/xdg_util.h" -#include "base/strings/string_piece.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "base/test/bind.h" @@ -48,12 +48,12 @@ MockEnvironment(const MockEnvironment&) = delete; MockEnvironment& operator=(const MockEnvironment&) = delete; - void Set(base::StringPiece name, const std::string& value) { + void Set(std::string_view name, const std::string& value) { const std::string key(name); variables_[key] = value; } - bool GetVar(base::StringPiece variable_name, std::string* result) override { + bool GetVar(std::string_view variable_name, std::string* result) override { const std::string key(variable_name); if (base::Contains(variables_, key)) { *result = variables_[key]; @@ -63,13 +63,13 @@ return false; } - bool SetVar(base::StringPiece variable_name, + bool SetVar(std::string_view variable_name, const std::string& new_value) override { ADD_FAILURE(); return false; } - bool UnSetVar(base::StringPiece variable_name) override { + bool UnSetVar(std::string_view variable_name) override { ADD_FAILURE(); return false; }
diff --git a/chrome/browser/web_applications/os_integration/web_app_shortcut_manager.cc b/chrome/browser/web_applications/os_integration/web_app_shortcut_manager.cc index 9bfb29d..bd16231 100644 --- a/chrome/browser/web_applications/os_integration/web_app_shortcut_manager.cc +++ b/chrome/browser/web_applications/os_integration/web_app_shortcut_manager.cc
@@ -6,6 +6,7 @@ #include <algorithm> #include <string> +#include <string_view> #include <vector> #include "base/command_line.h" @@ -124,7 +125,7 @@ void WebAppShortcutManager::UpdateShortcuts( const webapps::AppId& app_id, - base::StringPiece old_name, + std::string_view old_name, ResultCallback update_finished_callback) { DCHECK(CanCreateShortcuts()); GetShortcutInfoForApp(
diff --git a/chrome/browser/web_applications/os_integration/web_app_shortcut_manager.h b/chrome/browser/web_applications/os_integration/web_app_shortcut_manager.h index 6b7fa1e..c4fdb6a4 100644 --- a/chrome/browser/web_applications/os_integration/web_app_shortcut_manager.h +++ b/chrome/browser/web_applications/os_integration/web_app_shortcut_manager.h
@@ -7,6 +7,7 @@ #include <map> #include <memory> +#include <string_view> #include "base/functional/callback_forward.h" #include "base/memory/raw_ptr.h" @@ -68,7 +69,7 @@ CreateShortcutsCallback callback); // Fetch already-updated shortcut data and deploy to OS integration. void UpdateShortcuts(const webapps::AppId& app_id, - base::StringPiece old_name, + std::string_view old_name, ResultCallback update_finished_callback); void DeleteShortcuts(const webapps::AppId& app_id, const base::FilePath& shortcuts_data_dir,
diff --git a/chrome/browser/web_applications/os_integration/web_app_shortcut_win.cc b/chrome/browser/web_applications/os_integration/web_app_shortcut_win.cc index 1ec3d9a0..f26c6a6d 100644 --- a/chrome/browser/web_applications/os_integration/web_app_shortcut_win.cc +++ b/chrome/browser/web_applications/os_integration/web_app_shortcut_win.cc
@@ -9,6 +9,7 @@ #include <memory> #include <string> +#include <string_view> #include <utility> #include <vector> @@ -23,7 +24,6 @@ #include "base/hash/md5.h" #include "base/i18n/file_util_icu.h" #include "base/path_service.h" -#include "base/strings/string_piece.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "base/threading/scoped_blocking_call.h" @@ -75,7 +75,7 @@ ++it) { SkBitmap bitmap = it->AsBitmap(); - base::StringPiece image_data( + std::string_view image_data( reinterpret_cast<const char*>(bitmap.getPixels()), bitmap.computeByteSize()); base::MD5Update(&md5_context, image_data);
diff --git a/chrome/browser/web_applications/policy/web_app_policy_manager_browsertest.cc b/chrome/browser/web_applications/policy/web_app_policy_manager_browsertest.cc index 7f4a4fd..88b3624 100644 --- a/chrome/browser/web_applications/policy/web_app_policy_manager_browsertest.cc +++ b/chrome/browser/web_applications/policy/web_app_policy_manager_browsertest.cc
@@ -4,6 +4,7 @@ #include "chrome/browser/web_applications/policy/web_app_policy_manager.h" #include <memory> +#include <string_view> #include "base/command_line.h" #include "base/json/json_reader.h" @@ -112,7 +113,7 @@ return web_contents()->GetPrimaryMainFrame(); } - void SetPolicyPrefs(base::StringPiece json, + void SetPolicyPrefs(std::string_view json, std::vector<std::string> replacements = {}) { profile()->GetPrefs()->Set( prefs::kWebAppInstallForceList,
diff --git a/chrome/browser/web_applications/policy/web_app_policy_manager_unittest.cc b/chrome/browser/web_applications/policy/web_app_policy_manager_unittest.cc index b314865..79124c4 100644 --- a/chrome/browser/web_applications/policy/web_app_policy_manager_unittest.cc +++ b/chrome/browser/web_applications/policy/web_app_policy_manager_unittest.cc
@@ -5,6 +5,7 @@ #include "chrome/browser/web_applications/policy/web_app_policy_manager.h" #include <memory> +#include <string_view> #include <tuple> #include <utility> #include <vector> @@ -320,7 +321,7 @@ return options; } -void SetWebAppSettingsListPref(Profile* profile, const base::StringPiece pref) { +void SetWebAppSettingsListPref(Profile* profile, const std::string_view pref) { ASSERT_OK_AND_ASSIGN( auto result, base::JSONReader::ReadAndReturnValueWithError( @@ -330,7 +331,7 @@ } void SetWebAppInstallForceListPref(Profile* profile, - const base::StringPiece pref) { + const std::string_view pref) { ASSERT_OK_AND_ASSIGN( auto result, base::JSONReader::ReadAndReturnValueWithError(
diff --git a/chrome/browser/web_applications/policy/web_app_settings_policy_handler_unittest.cc b/chrome/browser/web_applications/policy/web_app_settings_policy_handler_unittest.cc index 682e3c0c..1a5dda5 100644 --- a/chrome/browser/web_applications/policy/web_app_settings_policy_handler_unittest.cc +++ b/chrome/browser/web_applications/policy/web_app_settings_policy_handler_unittest.cc
@@ -4,6 +4,8 @@ #include "chrome/browser/web_applications/policy/web_app_settings_policy_handler.h" +#include <string_view> + #include "base/json/json_reader.h" #include "components/policy/core/browser/policy_error_map.h" #include "components/policy/core/common/policy_map.h" @@ -85,7 +87,7 @@ } ])"; -base::Value ReturnPolicyValueFromJson(base::StringPiece policy) { +base::Value ReturnPolicyValueFromJson(std::string_view policy) { auto result = base::JSONReader::ReadAndReturnValueWithError( policy, base::JSONParserOptions::JSON_ALLOW_TRAILING_COMMAS); DCHECK(result.has_value()) << result.error().message;
diff --git a/chrome/browser/web_applications/preinstalled_app_install_features.cc b/chrome/browser/web_applications/preinstalled_app_install_features.cc index 170ca05..aba4ec4 100644 --- a/chrome/browser/web_applications/preinstalled_app_install_features.cc +++ b/chrome/browser/web_applications/preinstalled_app_install_features.cc
@@ -21,7 +21,7 @@ namespace { -constexpr const base::StringPiece kShippedPreinstalledAppInstallFeatures[] = { +constexpr const std::string_view kShippedPreinstalledAppInstallFeatures[] = { // Enables installing the PWA version of the chrome os calculator instead of // the deprecated chrome app. "DefaultCalculatorWebApp", @@ -96,14 +96,13 @@ #endif // BUILDFLAG(IS_CHROMEOS) } -bool IsPreinstalledAppInstallFeatureEnabled(base::StringPiece feature_name, +bool IsPreinstalledAppInstallFeatureEnabled(std::string_view feature_name, const Profile& profile) { if (g_always_enabled_for_testing) { return true; } - for (const base::StringPiece& feature : - kShippedPreinstalledAppInstallFeatures) { + for (std::string_view feature : kShippedPreinstalledAppInstallFeatures) { if (feature == feature_name) { return true; }
diff --git a/chrome/browser/web_applications/preinstalled_app_install_features.h b/chrome/browser/web_applications/preinstalled_app_install_features.h index 18e3bad..e295681 100644 --- a/chrome/browser/web_applications/preinstalled_app_install_features.h +++ b/chrome/browser/web_applications/preinstalled_app_install_features.h
@@ -5,8 +5,9 @@ #ifndef CHROME_BROWSER_WEB_APPLICATIONS_PREINSTALLED_APP_INSTALL_FEATURES_H_ #define CHROME_BROWSER_WEB_APPLICATIONS_PREINSTALLED_APP_INSTALL_FEATURES_H_ +#include <string_view> + #include "base/auto_reset.h" -#include "base/strings/string_piece.h" class Profile; @@ -20,7 +21,7 @@ // Returns the base::Feature in |kPreinstalledAppInstallFeatures| that // corresponds to |feature_name|. Used by external app install configs to gate // installation on features listed in |kPreinstalledAppInstallFeatures|. -bool IsPreinstalledAppInstallFeatureEnabled(base::StringPiece feature_name, +bool IsPreinstalledAppInstallFeatureEnabled(std::string_view feature_name, const Profile& profile); base::AutoReset<bool> SetPreinstalledAppInstallFeatureAlwaysEnabledForTesting();
diff --git a/chrome/browser/web_applications/preinstalled_web_app_manager_browsertest.cc b/chrome/browser/web_applications/preinstalled_web_app_manager_browsertest.cc index a1ec22c..5f3aa16 100644 --- a/chrome/browser/web_applications/preinstalled_web_app_manager_browsertest.cc +++ b/chrome/browser/web_applications/preinstalled_web_app_manager_browsertest.cc
@@ -4,6 +4,8 @@ #include "chrome/browser/web_applications/preinstalled_web_app_manager.h" +#include <string_view> + #include "base/auto_reset.h" #include "base/files/file_path.h" #include "base/files/file_util.h" @@ -230,7 +232,7 @@ // Mocks "icon.png" as chrome/test/data/web_apps/blue-192.png. std::optional<webapps::InstallResultCode> SyncPreinstalledAppConfig( const GURL& install_url, - base::StringPiece app_config_string) { + std::string_view app_config_string) { base::FilePath test_config_dir(FILE_PATH_LITERAL("test_dir")); SetPreinstalledWebAppConfigDirForTesting(&test_config_dir);
diff --git a/chrome/browser/web_applications/preinstalled_web_app_manager_unittest.cc b/chrome/browser/web_applications/preinstalled_web_app_manager_unittest.cc index 0020bbb5..55c2bfb 100644 --- a/chrome/browser/web_applications/preinstalled_web_app_manager_unittest.cc +++ b/chrome/browser/web_applications/preinstalled_web_app_manager_unittest.cc
@@ -7,6 +7,7 @@ #include <algorithm> #include <memory> #include <set> +#include <string_view> #include <vector> #include "base/command_line.h" @@ -127,7 +128,7 @@ } std::vector<ExternalInstallOptions> LoadApps( - base::StringPiece test_dir, + std::string_view test_dir, bool disable_default_apps = false) { DCHECK(profile_); @@ -203,8 +204,8 @@ return profile; } - void SetExtraWebAppsDir(base::StringPiece test_dir, - base::StringPiece extra_web_apps_dir) { + void SetExtraWebAppsDir(std::string_view test_dir, + std::string_view extra_web_apps_dir) { #if BUILDFLAG(IS_CHROMEOS_ASH) command_line_.GetProcessCommandLine()->AppendSwitchASCII( ash::switches::kExtraWebAppsDir, extra_web_apps_dir); @@ -244,7 +245,7 @@ ScopedTestingPreinstalledAppData preinstalled_web_app_override_; private: - base::FilePath GetConfigDir(base::StringPiece test_dir) { + base::FilePath GetConfigDir(std::string_view test_dir) { // Uses the chrome/test/data/web_app_default_apps/test_dir directory // that holds the *.json data files from which tests should parse as app // configs.
diff --git a/chrome/browser/web_applications/preinstalled_web_app_utils.cc b/chrome/browser/web_applications/preinstalled_web_app_utils.cc index 3df0c9b..17aa1f2 100644 --- a/chrome/browser/web_applications/preinstalled_web_app_utils.cc +++ b/chrome/browser/web_applications/preinstalled_web_app_utils.cc
@@ -4,6 +4,8 @@ #include "chrome/browser/web_applications/preinstalled_web_app_utils.h" +#include <string_view> + #include "base/files/file_util.h" #include "base/functional/bind.h" #include "base/strings/strcat.h" @@ -186,7 +188,7 @@ constexpr char kDisableIfTouchScreenWithStylusNotSupported[] = "disable_if_touchscreen_with_stylus_not_supported"; -void EnsureContains(base::Value::List& list, base::StringPiece value) { +void EnsureContains(base::Value::List& list, std::string_view value) { for (const base::Value& item : list) { if (item.is_string() && item.GetString() == value) { return; @@ -632,8 +634,8 @@ } bool IsReinstallPastMilestoneNeeded( - base::StringPiece last_preinstall_synchronize_milestone_str, - base::StringPiece current_milestone_str, + std::string_view last_preinstall_synchronize_milestone_str, + std::string_view current_milestone_str, int force_reinstall_for_milestone) { int last_preinstall_synchronize_milestone = 0; if (!base::StringToInt(last_preinstall_synchronize_milestone_str, @@ -677,7 +679,7 @@ } } -bool WasMigrationRun(Profile* profile, base::StringPiece feature_name) { +bool WasMigrationRun(Profile* profile, std::string_view feature_name) { const base::Value::List& migrated_features = profile->GetPrefs()->GetList(prefs::kWebAppsDidMigrateDefaultChromeApps); @@ -691,7 +693,7 @@ } void SetMigrationRun(Profile* profile, - base::StringPiece feature_name, + std::string_view feature_name, bool was_migrated) { ScopedListPrefUpdate update(profile->GetPrefs(), prefs::kWebAppsDidMigrateDefaultChromeApps);
diff --git a/chrome/browser/web_applications/preinstalled_web_app_utils.h b/chrome/browser/web_applications/preinstalled_web_app_utils.h index 9cd6e5b..b16bfe6 100644 --- a/chrome/browser/web_applications/preinstalled_web_app_utils.h +++ b/chrome/browser/web_applications/preinstalled_web_app_utils.h
@@ -6,8 +6,8 @@ #define CHROME_BROWSER_WEB_APPLICATIONS_PREINSTALLED_WEB_APP_UTILS_H_ #include <string> +#include <string_view> -#include "base/strings/string_piece.h" #include "base/types/expected.h" #include "chrome/browser/web_applications/external_install_options.h" #include "third_party/abseil-cpp/absl/types/variant.h" @@ -55,8 +55,8 @@ // user's data state. For example, if |force_reinstall_for_milestone| value is // 89 then we need to update the app on all browser upgrades from <89 to >=89. bool IsReinstallPastMilestoneNeeded( - base::StringPiece last_preinstall_synchronize_milestone_str, - base::StringPiece current_milestone_str, + std::string_view last_preinstall_synchronize_milestone_str, + std::string_view current_milestone_str, int force_reinstall_for_milestone); // Returns and sets whether the app indicated by `app_id` was migrated to a @@ -72,9 +72,9 @@ const std::string& app_id); // Returns and sets whether the migration was run for the feature. -bool WasMigrationRun(Profile* profile, base::StringPiece feature_name); +bool WasMigrationRun(Profile* profile, std::string_view feature_name); void SetMigrationRun(Profile* profile, - base::StringPiece feature_name, + std::string_view feature_name, bool was_migrated); // Returns whether the device has a stylus-enabled internal touchscreen, used
diff --git a/chrome/browser/web_applications/test/debug_info_printer.cc b/chrome/browser/web_applications/test/debug_info_printer.cc index fd51840..d8016463 100644 --- a/chrome/browser/web_applications/test/debug_info_printer.cc +++ b/chrome/browser/web_applications/test/debug_info_printer.cc
@@ -4,9 +4,10 @@ #include "chrome/browser/web_applications/test/debug_info_printer.h" +#include <string_view> + #include "base/command_line.h" #include "base/run_loop.h" -#include "base/strings/string_piece.h" #include "base/test/bind.h" #include "base/time/time.h" #include "chrome/browser/profiles/profile.h" @@ -24,7 +25,7 @@ namespace web_app::test { namespace { -constexpr base::StringPiece kDisableLogDebugInfoToConsole = +constexpr std::string_view kDisableLogDebugInfoToConsole = "disable-web-app-internals-log"; } // namespace
diff --git a/chrome/browser/web_applications/test/fake_os_integration_manager.cc b/chrome/browser/web_applications/test/fake_os_integration_manager.cc index f9b5f83..1ad5c01 100644 --- a/chrome/browser/web_applications/test/fake_os_integration_manager.cc +++ b/chrome/browser/web_applications/test/fake_os_integration_manager.cc
@@ -4,6 +4,8 @@ #include "chrome/browser/web_applications/test/fake_os_integration_manager.h" +#include <string_view> + #include "base/containers/contains.h" #include "base/task/sequenced_task_runner.h" #include "base/test/bind.h" @@ -116,7 +118,7 @@ void FakeOsIntegrationManager::UpdateOsHooks( const webapps::AppId& app_id, - base::StringPiece old_name, + std::string_view old_name, FileHandlerUpdateAction file_handlers_need_os_update, const WebAppInstallInfo& web_app_info, UninstallOsHooksCallback callback) {
diff --git a/chrome/browser/web_applications/test/fake_os_integration_manager.h b/chrome/browser/web_applications/test/fake_os_integration_manager.h index 4f700a6..bd7407d 100644 --- a/chrome/browser/web_applications/test/fake_os_integration_manager.h +++ b/chrome/browser/web_applications/test/fake_os_integration_manager.h
@@ -7,6 +7,7 @@ #include <map> #include <optional> +#include <string_view> #include "chrome/browser/web_applications/os_integration/os_integration_manager.h" #include "components/webapps/common/web_app_id.h" @@ -39,7 +40,7 @@ void UninstallAllOsHooks(const webapps::AppId& app_id, UninstallOsHooksCallback callback) override; void UpdateOsHooks(const webapps::AppId& app_id, - base::StringPiece old_name, + std::string_view old_name, FileHandlerUpdateAction file_handlers_need_os_update, const WebAppInstallInfo& web_app_info, UpdateOsHooksCallback callback) override;
diff --git a/chrome/browser/web_applications/test/fake_web_contents_manager.cc b/chrome/browser/web_applications/test/fake_web_contents_manager.cc index 34a62654..21292f2 100644 --- a/chrome/browser/web_applications/test/fake_web_contents_manager.cc +++ b/chrome/browser/web_applications/test/fake_web_contents_manager.cc
@@ -6,6 +6,7 @@ #include <memory> #include <optional> +#include <string_view> #include "base/functional/bind.h" #include "base/functional/callback_helpers.h" @@ -398,7 +399,7 @@ const GURL& install_url, const GURL& manifest_url, const GURL& start_url, - base::StringPiece16 name) { + std::u16string_view name) { FakePageState& install_page_state = GetOrCreatePageState(install_url); install_page_state.url_load_result = WebAppUrlLoaderResult::kUrlLoaded; install_page_state.redirection_url = std::nullopt;
diff --git a/chrome/browser/web_applications/test/fake_web_contents_manager.h b/chrome/browser/web_applications/test/fake_web_contents_manager.h index 4e02eef..a2139ba 100644 --- a/chrome/browser/web_applications/test/fake_web_contents_manager.h +++ b/chrome/browser/web_applications/test/fake_web_contents_manager.h
@@ -9,6 +9,7 @@ #include <memory> #include <optional> #include <string> +#include <string_view> #include "base/functional/callback_helpers.h" #include "base/memory/weak_ptr.h" @@ -128,7 +129,7 @@ const GURL& install_url, const GURL& manifest_url, const GURL& start_url, - base::StringPiece16 name = u"Basic app name"); + std::u16string_view name = u"Basic app name"); void SetPageState(const GURL& gurl, FakePageState page_state); FakePageState& GetOrCreatePageState(const GURL& gurl); void DeletePageState(const GURL& gurl);
diff --git a/chrome/browser/web_applications/test/prevent_close_test_base.cc b/chrome/browser/web_applications/test/prevent_close_test_base.cc index 6b51b31b..ebf8ba0 100644 --- a/chrome/browser/web_applications/test/prevent_close_test_base.cc +++ b/chrome/browser/web_applications/test/prevent_close_test_base.cc
@@ -4,6 +4,8 @@ #include "chrome/browser/web_applications/test/prevent_close_test_base.h" +#include <string_view> + #include "base/json/json_reader.h" #include "base/test/scoped_feature_list.h" #include "base/values.h" @@ -49,8 +51,8 @@ } void PreventCloseTestBase::SetPolicies( - base::StringPiece web_app_settings, - base::StringPiece web_app_install_force_list) { + std::string_view web_app_settings, + std::string_view web_app_install_force_list) { policy::PolicyMap policies; SetPolicy(&policies, policy::key::kWebAppSettings, ReturnPolicyValueFromJson(web_app_settings)); @@ -61,8 +63,8 @@ void PreventCloseTestBase::SetPoliciesAndWaitUntilInstalled( const webapps::AppId& app_id, - base::StringPiece web_app_settings, - base::StringPiece web_app_install_force_list) { + std::string_view web_app_settings, + std::string_view web_app_install_force_list) { web_app::WebAppTestInstallObserver observer(browser()->profile()); observer.BeginListening({app_id}); @@ -95,7 +97,7 @@ } base::Value PreventCloseTestBase::ReturnPolicyValueFromJson( - base::StringPiece policy) { + std::string_view policy) { auto result = base::JSONReader::ReadAndReturnValueWithError( policy, base::JSONParserOptions::JSON_ALLOW_TRAILING_COMMAS); DCHECK(result.has_value()) << result.error().message;
diff --git a/chrome/browser/web_applications/test/prevent_close_test_base.h b/chrome/browser/web_applications/test/prevent_close_test_base.h index e196985..8db9ac1 100644 --- a/chrome/browser/web_applications/test/prevent_close_test_base.h +++ b/chrome/browser/web_applications/test/prevent_close_test_base.h
@@ -5,7 +5,8 @@ #ifndef CHROME_BROWSER_WEB_APPLICATIONS_TEST_PREVENT_CLOSE_TEST_BASE_H_ #define CHROME_BROWSER_WEB_APPLICATIONS_TEST_PREVENT_CLOSE_TEST_BASE_H_ -#include "base/strings/string_piece.h" +#include <string_view> + #include "base/test/scoped_feature_list.h" #include "base/values.h" #include "chrome/browser/policy/policy_test_utils.h" @@ -32,16 +33,16 @@ void SetUpInProcessBrowserTestFixture() override; void TearDownInProcessBrowserTestFixture() override; - void SetPolicies(base::StringPiece web_app_settings, - base::StringPiece web_app_install_force_list); + void SetPolicies(std::string_view web_app_settings, + std::string_view web_app_install_force_list); void SetPoliciesAndWaitUntilInstalled( const webapps::AppId& app_id, - base::StringPiece web_app_settings, - base::StringPiece web_app_install_force_list); + std::string_view web_app_settings, + std::string_view web_app_install_force_list); void ClearWebAppSettings(); void InstallPWA(const GURL& app_url, const webapps::AppId& app_id); Browser* LaunchPWA(const webapps::AppId& app_id, bool launch_in_window); - base::Value ReturnPolicyValueFromJson(base::StringPiece policy); + base::Value ReturnPolicyValueFromJson(std::string_view policy); Profile* profile();
diff --git a/chrome/browser/web_applications/test/web_app_test_utils.cc b/chrome/browser/web_applications/test/web_app_test_utils.cc index b79db74..8ec3f5e 100644 --- a/chrome/browser/web_applications/test/web_app_test_utils.cc +++ b/chrome/browser/web_applications/test/web_app_test_utils.cc
@@ -11,6 +11,7 @@ #include <random> #include <set> #include <string> +#include <string_view> #include <type_traits> #include <utility> #include <vector> @@ -1024,7 +1025,7 @@ run_loop.Run(); } -void SetWebAppSettingsListPref(Profile* profile, const base::StringPiece pref) { +void SetWebAppSettingsListPref(Profile* profile, const std::string_view pref) { auto result = base::JSONReader::ReadAndReturnValueWithError( pref, base::JSONParserOptions::JSON_ALLOW_TRAILING_COMMAS); DCHECK(result.has_value()) << result.error().message;
diff --git a/chrome/browser/web_applications/test/web_app_test_utils.h b/chrome/browser/web_applications/test/web_app_test_utils.h index ef0c260..8724b9c 100644 --- a/chrome/browser/web_applications/test/web_app_test_utils.h +++ b/chrome/browser/web_applications/test/web_app_test_utils.h
@@ -6,10 +6,11 @@ #define CHROME_BROWSER_WEB_APPLICATIONS_TEST_WEB_APP_TEST_UTILS_H_ #include <stdint.h> + #include <memory> #include <string> +#include <string_view> -#include "base/strings/string_piece.h" #include "build/chromeos_buildflags.h" #include "chrome/browser/web_applications/os_integration/os_integration_sub_manager.h" #include "chrome/browser/web_applications/web_app_constants.h" @@ -67,7 +68,7 @@ content::StoragePartition* storage_partition, content::ServiceWorkerCapability status); -void SetWebAppSettingsListPref(Profile* profile, base::StringPiece pref); +void SetWebAppSettingsListPref(Profile* profile, std::string_view pref); void AddInstallUrlData(PrefService* pref_service, WebAppSyncBridge* sync_bridge,
diff --git a/chrome/browser/web_applications/web_app_icon_manager.cc b/chrome/browser/web_applications/web_app_icon_manager.cc index 964a20a..291d325 100644 --- a/chrome/browser/web_applications/web_app_icon_manager.cc +++ b/chrome/browser/web_applications/web_app_icon_manager.cc
@@ -10,6 +10,7 @@ #include <functional> #include <initializer_list> #include <ostream> +#include <string_view> #include <utility> #include "base/check.h" @@ -31,7 +32,6 @@ #include "base/ranges/algorithm.h" #include "base/strings/strcat.h" #include "base/strings/string_number_conversions.h" -#include "base/strings/string_piece.h" #include "base/strings/stringprintf.h" #include "base/task/sequenced_task_runner.h" #include "base/task/task_traits.h" @@ -79,7 +79,7 @@ bool HasErrors() const { return !error_log.empty(); } }; -std::string CreateError(std::initializer_list<base::StringPiece> parts) { +std::string CreateError(std::initializer_list<std::string_view> parts) { std::string error = base::StrCat(parts); LOG(ERROR) << error; return error;
diff --git a/chrome/browser/web_applications/web_app_install_utils.cc b/chrome/browser/web_applications/web_app_install_utils.cc index 817febb..bec7ac9 100644 --- a/chrome/browser/web_applications/web_app_install_utils.cc +++ b/chrome/browser/web_applications/web_app_install_utils.cc
@@ -11,6 +11,7 @@ #include <ostream> #include <set> #include <string> +#include <string_view> #include <type_traits> #include <utility> #include <vector> @@ -950,7 +951,7 @@ } void RecordDownloadedIconsHttpResultsCodeClass( - base::StringPiece histogram_name, + std::string_view histogram_name, IconsDownloadedResult result, const DownloadedIconsHttpResults& icons_http_results) { if (result != IconsDownloadedResult::kCompleted) @@ -968,7 +969,7 @@ } void RecordDownloadedIconHttpStatusCodes( - base::StringPiece histogram_name, + std::string_view histogram_name, const DownloadedIconsHttpResults& icons_http_results) { if (icons_http_results.empty()) return;
diff --git a/chrome/browser/web_applications/web_app_install_utils.h b/chrome/browser/web_applications/web_app_install_utils.h index bf670be..e44174e9 100644 --- a/chrome/browser/web_applications/web_app_install_utils.h +++ b/chrome/browser/web_applications/web_app_install_utils.h
@@ -5,11 +5,11 @@ #ifndef CHROME_BROWSER_WEB_APPLICATIONS_WEB_APP_INSTALL_UTILS_H_ #define CHROME_BROWSER_WEB_APPLICATIONS_WEB_APP_INSTALL_UTILS_H_ +#include <string_view> #include <vector> #include "base/containers/flat_map.h" #include "base/containers/flat_set.h" -#include "base/strings/string_piece.h" #include "chrome/browser/web_applications/os_integration/os_integration_manager.h" #include "chrome/browser/web_applications/web_app_constants.h" #include "chrome/browser/web_applications/web_app_icon_operations.h" @@ -100,13 +100,13 @@ // Records the class of http status code (2XX, 3XX, 4XX, 5XX) for each processed // icon url. void RecordDownloadedIconsHttpResultsCodeClass( - base::StringPiece histogram_name, + std::string_view histogram_name, IconsDownloadedResult result, const DownloadedIconsHttpResults& icons_http_results); // Records http status code for each processed icon url. void RecordDownloadedIconHttpStatusCodes( - base::StringPiece histogram_name, + std::string_view histogram_name, const DownloadedIconsHttpResults& icons_http_results); WebAppManagement::Type ConvertExternalInstallSourceToSource(
diff --git a/chrome/browser/web_applications/web_app_internals_browsertest.cc b/chrome/browser/web_applications/web_app_internals_browsertest.cc index 95a7d58c..7a90897 100644 --- a/chrome/browser/web_applications/web_app_internals_browsertest.cc +++ b/chrome/browser/web_applications/web_app_internals_browsertest.cc
@@ -3,9 +3,9 @@ // found in the LICENSE file. #include <string> +#include <string_view> #include "base/functional/callback_helpers.h" -#include "base/strings/string_piece.h" #include "base/strings/string_util.h" #include "base/test/bind.h" #include "base/test/scoped_feature_list.h" @@ -60,7 +60,7 @@ )"; // Drops all CR and LF characters. -std::string TrimLineEndings(base::StringPiece text) { +std::string TrimLineEndings(std::string_view text) { return base::CollapseWhitespaceASCII( text, /*trim_sequences_with_line_breaks=*/true);
diff --git a/chrome/browser/web_applications/web_app_internals_utils.cc b/chrome/browser/web_applications/web_app_internals_utils.cc index 56bc51ef..0e486d5 100644 --- a/chrome/browser/web_applications/web_app_internals_utils.cc +++ b/chrome/browser/web_applications/web_app_internals_utils.cc
@@ -4,10 +4,11 @@ #include "chrome/browser/web_applications/web_app_internals_utils.h" +#include <string_view> + #include "base/files/file_path.h" #include "base/json/json_file_value_serializer.h" #include "base/memory/scoped_refptr.h" -#include "base/strings/string_piece.h" #include "base/task/task_traits.h" #include "base/task/thread_pool.h" #include "base/values.h" @@ -33,7 +34,7 @@ } base::FilePath GetErrorLogFileName(const base::FilePath& web_apps_directory, - base::StringPiece subsystem_name) { + std::string_view subsystem_name) { return GetErrorLogDirectory(web_apps_directory) .AppendASCII(subsystem_name.data()) .AddExtensionASCII("log"); @@ -41,7 +42,7 @@ ErrorLogData ReadErrorLogBlocking(scoped_refptr<FileUtilsWrapper> utils, const base::FilePath& web_apps_directory, - base::StringPiece subsystem_name) { + std::string_view subsystem_name) { base::FilePath log_file_name = GetErrorLogFileName(web_apps_directory, subsystem_name); @@ -68,7 +69,7 @@ Result WriteErrorLogBlocking(scoped_refptr<FileUtilsWrapper> utils, const base::FilePath& web_apps_directory, - base::StringPiece subsystem_name, + std::string_view subsystem_name, base::Value error_log) { if (!utils->CreateDirectory(GetErrorLogDirectory(web_apps_directory))) return Result::kError; @@ -82,7 +83,7 @@ Result ClearErrorLogBlocking(scoped_refptr<FileUtilsWrapper> utils, const base::FilePath& web_apps_directory, - base::StringPiece subsystem_name) { + std::string_view subsystem_name) { base::FilePath log_file_name = GetErrorLogFileName(web_apps_directory, subsystem_name); @@ -93,7 +94,7 @@ } // namespace void ReadErrorLog(const base::FilePath& web_apps_directory, - base::StringPiece subsystem_name, + std::string_view subsystem_name, ReadErrorLogCallback callback) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); @@ -106,7 +107,7 @@ } void WriteErrorLog(const base::FilePath& web_apps_directory, - base::StringPiece subsystem_name, + std::string_view subsystem_name, base::Value error_log, FileIoCallback callback) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); @@ -120,7 +121,7 @@ } void ClearErrorLog(const base::FilePath& web_apps_directory, - base::StringPiece subsystem_name, + std::string_view subsystem_name, FileIoCallback callback) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
diff --git a/chrome/browser/web_applications/web_app_internals_utils.h b/chrome/browser/web_applications/web_app_internals_utils.h index 5b24316b..85cf5d7 100644 --- a/chrome/browser/web_applications/web_app_internals_utils.h +++ b/chrome/browser/web_applications/web_app_internals_utils.h
@@ -5,8 +5,9 @@ #ifndef CHROME_BROWSER_WEB_APPLICATIONS_WEB_APP_INTERNALS_UTILS_H_ #define CHROME_BROWSER_WEB_APPLICATIONS_WEB_APP_INTERNALS_UTILS_H_ +#include <string_view> + #include "base/functional/callback_forward.h" -#include "base/strings/string_piece.h" #include "chrome/browser/web_applications/web_app_constants.h" namespace base { @@ -20,18 +21,18 @@ base::OnceCallback<void(Result, base::Value error_log)>; void ReadErrorLog(const base::FilePath& web_apps_directory, - base::StringPiece subsystem_name, + std::string_view subsystem_name, ReadErrorLogCallback callback); using FileIoCallback = base::OnceCallback<void(Result)>; void WriteErrorLog(const base::FilePath& web_apps_directory, - base::StringPiece subsystem_name, + std::string_view subsystem_name, base::Value error_log, FileIoCallback callback); void ClearErrorLog(const base::FilePath& web_apps_directory, - base::StringPiece subsystem_name, + std::string_view subsystem_name, FileIoCallback callback); } // namespace web_app
diff --git a/chrome/browser/web_applications/web_app_pref_guardrails.cc b/chrome/browser/web_applications/web_app_pref_guardrails.cc index 6ec9ac2..10878f5 100644 --- a/chrome/browser/web_applications/web_app_pref_guardrails.cc +++ b/chrome/browser/web_applications/web_app_pref_guardrails.cc
@@ -51,7 +51,7 @@ std::optional<int> GetIntWebAppPref(const PrefService* pref_service, const webapps::AppId& app_id, - base::StringPiece path) { + std::string_view path) { const base::Value::Dict* web_app_prefs = GetWebAppDictionary(pref_service, app_id); if (!web_app_prefs) { @@ -62,7 +62,7 @@ std::optional<base::Time> GetTimeWebAppPref(const PrefService* pref_service, const webapps::AppId& app_id, - base::StringPiece path) { + std::string_view path) { const auto* web_app_prefs = GetWebAppDictionary(pref_service, app_id); if (!web_app_prefs) { return std::nullopt; @@ -375,7 +375,7 @@ } void WebAppPrefGuardrails::UpdateTimeWebAppPref(const webapps::AppId& app_id, - base::StringPiece path, + std::string_view path, base::Time value) { ScopedDictPrefUpdate update(pref_service_, prefs::kWebAppsPreferences); @@ -384,7 +384,7 @@ } void WebAppPrefGuardrails::UpdateIntWebAppPref(const webapps::AppId& app_id, - base::StringPiece path, + std::string_view path, int value) { ScopedDictPrefUpdate update(pref_service_, prefs::kWebAppsPreferences);
diff --git a/chrome/browser/web_applications/web_app_pref_guardrails.h b/chrome/browser/web_applications/web_app_pref_guardrails.h index 9fa0f1b..48ba649 100644 --- a/chrome/browser/web_applications/web_app_pref_guardrails.h +++ b/chrome/browser/web_applications/web_app_pref_guardrails.h
@@ -45,11 +45,11 @@ std::optional<int> GetIntWebAppPref(const PrefService* pref_service, const webapps::AppId& app_id, - base::StringPiece path); + std::string_view path); std::optional<base::Time> GetTimeWebAppPref(const PrefService* pref_service, const webapps::AppId& app_id, - base::StringPiece path); + std::string_view path); // WebAppPrefGuardrails provide a simple way of building guardrails based on the // number of times a prompt on an app has been ignored or dismissed in the past. @@ -149,11 +149,11 @@ // Pref update functions. void UpdateTimeWebAppPref(const webapps::AppId& app_id, - base::StringPiece path, + std::string_view path, base::Time value); void UpdateIntWebAppPref(const webapps::AppId& app_id, - base::StringPiece path, + std::string_view path, int value); raw_ptr<PrefService> pref_service_;
diff --git a/chrome/browser/web_applications/web_app_pref_guardrails_unittest.cc b/chrome/browser/web_applications/web_app_pref_guardrails_unittest.cc index 5b898c3..7e38393 100644 --- a/chrome/browser/web_applications/web_app_pref_guardrails_unittest.cc +++ b/chrome/browser/web_applications/web_app_pref_guardrails_unittest.cc
@@ -5,11 +5,11 @@ #include "chrome/browser/web_applications/web_app_pref_guardrails.h" #include <memory> +#include <string_view> #include "base/json/values_util.h" #include "base/metrics/field_trial_params.h" #include "base/rand_util.h" -#include "base/strings/string_piece.h" #include "base/time/time.h" #include "chrome/browser/web_applications/test/web_app_test.h" #include "chrome/browser/web_applications/web_app_constants.h" @@ -37,12 +37,12 @@ protected: std::optional<int> GetIntWebAppPref(const webapps::AppId& app, - base::StringPiece path) { + std::string_view path) { return ::web_app::GetIntWebAppPref(prefs(), app, path); } std::optional<base::Time> GetTimeWebAppPref(const webapps::AppId& app, - base::StringPiece path) { + std::string_view path) { return ::web_app::GetTimeWebAppPref(prefs(), app, path); }
diff --git a/chrome/browser/web_applications/web_app_unittest.cc b/chrome/browser/web_applications/web_app_unittest.cc index b8dd27d..69f4ea3 100644 --- a/chrome/browser/web_applications/web_app_unittest.cc +++ b/chrome/browser/web_applications/web_app_unittest.cc
@@ -6,6 +6,7 @@ #include <memory> #include <string> +#include <string_view> #include "base/check.h" #include "base/command_line.h" @@ -15,7 +16,6 @@ #include "base/json/json_reader.h" #include "base/json/json_writer.h" #include "base/path_service.h" -#include "base/strings/string_piece.h" #include "base/values.h" #include "build/chromeos_buildflags.h" #include "chrome/browser/web_applications/isolated_web_apps/isolated_web_app_storage_location.h" @@ -35,7 +35,7 @@ namespace { -constexpr base::StringPiece kGenerateExpectationsMessage = R"( +constexpr std::string_view kGenerateExpectationsMessage = R"( In order to regenerate expectations run the following command: out/<dir>/unit_tests \ @@ -61,7 +61,7 @@ return relative_path; } -base::FilePath GetPathToTestFile(base::StringPiece filename) { +base::FilePath GetPathToTestFile(std::string_view filename) { return GetTestDataDir().AppendASCII("web_apps").AppendASCII(filename); } @@ -72,7 +72,7 @@ } void SetContentsOrDie(const base::FilePath& filepath, - base::StringPiece contents) { + std::string_view contents) { CHECK(base::WriteFile(filepath, contents)); } @@ -83,7 +83,7 @@ return contents; } -base::Value DeserializeValueFromJsonOrDie(base::StringPiece json) { +base::Value DeserializeValueFromJsonOrDie(std::string_view json) { std::optional<base::Value> value = base::JSONReader::Read(json); CHECK(value.has_value()); return *std::move(value); @@ -96,7 +96,7 @@ } void SaveExpectationsContentsOrDie(const base::FilePath path, - base::StringPiece contents) { + std::string_view contents) { const std::string current_contents = GetContentsOrDie(path); const base::FilePath test_data_dir_relative_path =
diff --git a/chrome/browser/webapps/android/BUILD.gn b/chrome/browser/webapps/android/BUILD.gn index c3690e4..83a3b01 100644 --- a/chrome/browser/webapps/android/BUILD.gn +++ b/chrome/browser/webapps/android/BUILD.gn
@@ -9,10 +9,7 @@ android_library("java") { resources_package = "org.chromium.chrome.browser.webapps" - sources = [ - "java/src/org/chromium/chrome/browser/webapps/AddToHomescreenIPHController.java", - "java/src/org/chromium/chrome/browser/webapps/PwaRestorePromoUtils.java", - ] + sources = [ "java/src/org/chromium/chrome/browser/webapps/AddToHomescreenIPHController.java" ] deps = [ "//base:base_java", @@ -41,12 +38,4 @@ "//ui/android:ui_no_recycler_view_java", "//url:gurl_java", ] - - srcjar_deps = [ ":webapps_jni_headers" ] -} - -generate_jni("webapps_jni_headers") { - sources = [ - "java/src/org/chromium/chrome/browser/webapps/PwaRestorePromoUtils.java", - ] }
diff --git a/chrome/browser/webapps/pwa_restore_promo_utils_android.cc b/chrome/browser/webapps/pwa_restore_promo_utils_android.cc deleted file mode 100644 index 2f7ac71..0000000 --- a/chrome/browser/webapps/pwa_restore_promo_utils_android.cc +++ /dev/null
@@ -1,111 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include <memory> - -#include "base/android/jni_android.h" -#include "base/functional/bind.h" -#include "base/logging.h" -#include "base/time/time.h" -#include "chrome/browser/android/webapk/webapk_database.h" -#include "chrome/browser/android/webapk/webapk_database_factory.h" -#include "chrome/browser/android/webapk/webapk_registrar.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/profiles/profile_android.h" -#include "chrome/browser/webapps/android/webapps_jni_headers/PwaRestorePromoUtils_jni.h" -#include "components/sync/model/metadata_batch.h" -#include "components/sync/model/model_type_store.h" -#include "ui/android/window_android.h" - -using base::android::JavaParamRef; -using base::android::ScopedJavaGlobalRef; -using base::android::ScopedJavaLocalRef; - -namespace { - -class HandleWebApkDatabaseRequest { - public: - HandleWebApkDatabaseRequest(JNIEnv* env, - Profile* profile, - ui::WindowAndroid* window_android, - int arrow_resource_id) { - env_ = env; - window_android_ = window_android; - arrow_resource_id_ = arrow_resource_id; - - database_factory_ = - std::make_unique<webapk::WebApkDatabaseFactory>(profile); - - web_apk_database_ = std::make_unique<webapk::WebApkDatabase>( - database_factory_.get(), - base::BindRepeating(&HandleWebApkDatabaseRequest::ErrorCallback, - base::Unretained(this))); - - web_apk_database_->OpenDatabase(base::BindRepeating( - &HandleWebApkDatabaseRequest::DatabaseOpened, base::Unretained(this))); - } - - private: - void ReturnResultsAndDie(bool success) { - ScopedJavaLocalRef<jobjectArray> jresults = - base::android::ToJavaArrayOfStringArray(env_, results_); - ScopedJavaLocalRef<jintArray> jresults_lastUsed = - base::android::ToJavaIntArray(env_, last_used_in_days_); - webapps::Java_PwaRestorePromoUtils_onRestorableAppsAvailable( - env_, success, jresults, jresults_lastUsed, - window_android_->GetJavaObject(), arrow_resource_id_); - delete this; - } - - void DatabaseOpened(webapk::Registry registry, - std::unique_ptr<syncer::MetadataBatch> metadata_batch) { - // The registry is a map of webapps::AppId -> std::unique_ptr<WebApkProto>. - for (auto const& [appId, proto] : registry) { - results_.push_back({appId, proto->sync_data().name()}); - - base::Time timestamp = - base::Time::FromDeltaSinceWindowsEpoch(base::Microseconds( - proto->sync_data().last_used_time_windows_epoch_micros())); - last_used_in_days_.push_back((base::Time::Now() - timestamp).InDays()); - } - - ReturnResultsAndDie(true); - } - - void ErrorCallback(const syncer::ModelError& error) { - ReturnResultsAndDie(false); - } - - raw_ptr<JNIEnv> env_ = nullptr; - raw_ptr<ui::WindowAndroid> window_android_ = nullptr; - int arrow_resource_id_ = 0; - - std::unique_ptr<webapk::WebApkDatabaseFactory> database_factory_; - std::unique_ptr<webapk::WebApkDatabase> web_apk_database_; - - std::vector<std::vector<std::string>> results_; - std::vector<int> last_used_in_days_; -}; - -} // namespace - -namespace webapps { - -// static -void JNI_PwaRestorePromoUtils_FetchRestorableApps( - JNIEnv* env, - const JavaParamRef<jobject>& jprofile, - const JavaParamRef<jobject>& jwindow_android, - int arrowResourceId) { - Profile* profile = - ProfileAndroid::FromProfileAndroid(jprofile)->GetWeakPtr().get(); - ui::WindowAndroid* window_android = - ui::WindowAndroid::FromJavaWindowAndroid(jwindow_android); - - // This object handles its own lifetime. - new HandleWebApkDatabaseRequest(env, profile, window_android, - arrowResourceId); -} - -} // namespace webapps
diff --git a/chrome/browser/webauthn/authenticator_request_dialog_model.cc b/chrome/browser/webauthn/authenticator_request_dialog_model.cc index eea322e..126d7bb38 100644 --- a/chrome/browser/webauthn/authenticator_request_dialog_model.cc +++ b/chrome/browser/webauthn/authenticator_request_dialog_model.cc
@@ -1366,11 +1366,7 @@ << base::HexEncode(credential_id); const device::AuthenticatorType source = cred->source; DCHECK(account_preselected_callback_); - account_preselected_callback_.Run(device::PublicKeyCredentialDescriptor( - device::CredentialType::kPublicKey, cred->cred_id, - {cred->source == device::AuthenticatorType::kPhone - ? AuthenticatorTransport::kHybrid - : AuthenticatorTransport::kInternal})); + account_preselected_callback_.Run(*cred); ephemeral_state_.creds_.clear(); if (source != device::AuthenticatorType::kPhone && @@ -1875,9 +1871,7 @@ break; } } - account_preselected_callback_.Run(device::PublicKeyCredentialDescriptor( - device::CredentialType::kPublicKey, selected->cred_id, - {AuthenticatorTransport::kInternal})); + account_preselected_callback_.Run(*selected); } HideDialogAndDispatchToPlatformAuthenticator(
diff --git a/chrome/browser/webauthn/authenticator_request_dialog_model_unittest.cc b/chrome/browser/webauthn/authenticator_request_dialog_model_unittest.cc index b09f165..5f91edb 100644 --- a/chrome/browser/webauthn/authenticator_request_dialog_model_unittest.cc +++ b/chrome/browser/webauthn/authenticator_request_dialog_model_unittest.cc
@@ -1460,8 +1460,8 @@ model.SetHints(hints); } - model.SetAccountPreselectedCallback( - base::BindRepeating([](device::PublicKeyCredentialDescriptor cred) {})); + model.SetAccountPreselectedCallback(base::BindRepeating( + [](device::DiscoverableCredentialMetadata cred) {})); if (has_v2_cable_extension.has_value() || !test.phones.empty() || base::Contains(test.transports, @@ -2007,8 +2007,8 @@ int preselect_num_called = 0; model.SetAccountPreselectedCallback(base::BindRepeating( - [](int* i, device::PublicKeyCredentialDescriptor cred) { - EXPECT_EQ(cred.id, std::vector<uint8_t>({1, 2, 3, 4})); + [](int* i, device::DiscoverableCredentialMetadata cred) { + EXPECT_EQ(cred.cred_id, std::vector<uint8_t>({1, 2, 3, 4})); ++(*i); }, &preselect_num_called)); @@ -2041,8 +2041,8 @@ AuthenticatorRequestDialogModel model(main_rfh()); int preselect_num_called = 0; model.SetAccountPreselectedCallback(base::BindRepeating( - [](int* i, device::PublicKeyCredentialDescriptor cred) { - EXPECT_EQ(cred.id, std::vector<uint8_t>({0})); + [](int* i, device::DiscoverableCredentialMetadata cred) { + EXPECT_EQ(cred.cred_id, std::vector<uint8_t>({0})); ++(*i); }, &preselect_num_called)); @@ -2351,8 +2351,8 @@ AuthenticatorRequestDialogModel model(main_rfh()); int preselect_num_called = 0; model.SetAccountPreselectedCallback(base::BindLambdaForTesting( - [&preselect_num_called](device::PublicKeyCredentialDescriptor cred) { - EXPECT_EQ(cred.id, std::vector<uint8_t>({1})); + [&preselect_num_called](device::DiscoverableCredentialMetadata cred) { + EXPECT_EQ(cred.cred_id, std::vector<uint8_t>({1})); ++preselect_num_called; })); int request_num_called = 0; @@ -2675,7 +2675,7 @@ FidoRequestHandlerBase::RecognizedCredential::kHasRecognizedCredential; AuthenticatorRequestDialogModel model(main_rfh()); - RepeatingValueCallbackReceiver<device::PublicKeyCredentialDescriptor> + RepeatingValueCallbackReceiver<device::DiscoverableCredentialMetadata> account_preselected_callback; model.SetAccountPreselectedCallback(account_preselected_callback.Callback()); model.StartFlow(std::move(transports_info), @@ -2712,7 +2712,7 @@ AuthenticatorRequestDialogModel model(main_rfh()); model.set_allow_icloud_keychain(true); - RepeatingValueCallbackReceiver<device::PublicKeyCredentialDescriptor> + RepeatingValueCallbackReceiver<device::DiscoverableCredentialMetadata> account_preselected_callback; model.SetAccountPreselectedCallback( account_preselected_callback.Callback()); @@ -2864,7 +2864,7 @@ AuthenticatorRequestDialogModel model(main_rfh()); model.set_allow_icloud_keychain(true); - RepeatingValueCallbackReceiver<device::PublicKeyCredentialDescriptor> + RepeatingValueCallbackReceiver<device::DiscoverableCredentialMetadata> account_preselected_callback; model.SetAccountPreselectedCallback( account_preselected_callback.Callback()); @@ -2873,12 +2873,12 @@ /*is_conditional_mediation=*/false); EXPECT_EQ(model.current_step(), Step::kNotStarted); - device::PublicKeyCredentialDescriptor descriptor = + device::DiscoverableCredentialMetadata descriptor = account_preselected_callback.WaitForResult(); if (credential_source == device::AuthenticatorType::kTouchID) { - EXPECT_EQ(descriptor.id, kCred2.cred_id); + EXPECT_EQ(descriptor.cred_id, kCred2.cred_id); } else { - EXPECT_EQ(descriptor.id, kCred1FromICloudKeychain.cred_id); + EXPECT_EQ(descriptor.cred_id, kCred1FromICloudKeychain.cred_id); } } } @@ -2974,7 +2974,7 @@ model.set_cable_transport_info( /*extension_is_v2=*/std::nullopt, std::move(phones), contact_phone_callback.Callback(), std::nullopt); - RepeatingValueCallbackReceiver<device::PublicKeyCredentialDescriptor> + RepeatingValueCallbackReceiver<device::DiscoverableCredentialMetadata> account_preselected_callback; model.SetAccountPreselectedCallback(account_preselected_callback.Callback()); @@ -2998,11 +2998,10 @@ l10n_util::GetStringUTF16(IDS_PASSWORD_MANAGER_USE_GENERIC_DEVICE)); EXPECT_EQ(mech1.icon, vector_icons::kPasskeyIcon); mech1.callback.Run(); - device::PublicKeyCredentialDescriptor result = + device::DiscoverableCredentialMetadata result = account_preselected_callback.WaitForResult(); - EXPECT_EQ(result.id, kCred1.cred_id); - EXPECT_THAT(result.transports, - testing::ElementsAre(device::FidoTransportProtocol::kInternal)); + EXPECT_EQ(result.cred_id, kCred1.cred_id); + EXPECT_EQ(result.source, device::AuthenticatorType::kOther); EXPECT_EQ(request_callback.WaitForResult(), kLocalAuthenticatorId); // Reset the model as if the user had cancelled out of the operation. @@ -3020,9 +3019,8 @@ EXPECT_EQ(mech2.icon, vector_icons::kPasskeyIcon); mech2.callback.Run(); result = account_preselected_callback.WaitForResult(); - EXPECT_EQ(result.id, kCred2.cred_id); - EXPECT_THAT(result.transports, - testing::ElementsAre(device::FidoTransportProtocol::kInternal)); + EXPECT_EQ(result.cred_id, kCred2.cred_id); + EXPECT_EQ(result.source, device::AuthenticatorType::kOther); EXPECT_EQ(request_callback.WaitForResult(), kLocalAuthenticatorId); // Reset the model as if the user had cancelled out of the operation. @@ -3042,9 +3040,8 @@ EXPECT_EQ(mech3.icon, kSmartphoneIcon); mech3.callback.Run(); result = account_preselected_callback.WaitForResult(); - EXPECT_EQ(result.id, kPhoneCred1.cred_id); - EXPECT_THAT(result.transports, - testing::ElementsAre(device::FidoTransportProtocol::kHybrid)); + EXPECT_EQ(result.cred_id, kPhoneCred1.cred_id); + EXPECT_EQ(result.source, device::AuthenticatorType::kPhone); EXPECT_TRUE(contact_phone_callback.WaitForResult()); } @@ -3126,8 +3123,7 @@ &fake_win_webauthn_api); for (const auto& test_case : kWinHelloButtonGetAssertionTestCases) { AuthenticatorRequestDialogModel model(main_rfh()); - model.SetAccountPreselectedCallback( - base::BindRepeating([](device::PublicKeyCredentialDescriptor cred) {})); + model.SetAccountPreselectedCallback(base::DoNothing()); TransportAvailabilityInfo transports_info; transports_info.has_win_native_api_authenticator = true;
diff --git a/chrome/browser/webauthn/chrome_authenticator_request_delegate.cc b/chrome/browser/webauthn/chrome_authenticator_request_delegate.cc index ade3293..21b2ca0 100644 --- a/chrome/browser/webauthn/chrome_authenticator_request_delegate.cc +++ b/chrome/browser/webauthn/chrome_authenticator_request_delegate.cc
@@ -1407,8 +1407,8 @@ } void ChromeAuthenticatorRequestDelegate::OnAccountPreselected( - device::PublicKeyCredentialDescriptor descriptor) { - preselected_cred_id_ = descriptor.id; + device::DiscoverableCredentialMetadata descriptor) { + preselected_cred_id_ = descriptor.cred_id; account_preselected_callback_.Run(std::move(descriptor)); }
diff --git a/chrome/browser/webauthn/chrome_authenticator_request_delegate.h b/chrome/browser/webauthn/chrome_authenticator_request_delegate.h index 97831c8..4f13e7d 100644 --- a/chrome/browser/webauthn/chrome_authenticator_request_delegate.h +++ b/chrome/browser/webauthn/chrome_authenticator_request_delegate.h
@@ -21,6 +21,7 @@ #include "content/public/browser/authenticator_request_client_delegate.h" #include "content/public/browser/global_routing_id.h" #include "device/fido/cable/cable_discovery_data.h" +#include "device/fido/discoverable_credential_metadata.h" #include "device/fido/fido_request_handler_base.h" #include "device/fido/fido_transport_protocol.h" #include "device/fido/fido_types.h" @@ -275,7 +276,7 @@ // Stores the credential ID in `preselected_cred_id_` then forwards to the // `AccountPreselectedCallback` that was passed to // `RegisterActionCallbacks`. - void OnAccountPreselected(device::PublicKeyCredentialDescriptor); + void OnAccountPreselected(device::DiscoverableCredentialMetadata); // Called to start fetching the state of the primary account from the // trusted vault service.
diff --git a/chrome/build/lacros-arm64.pgo.txt b/chrome/build/lacros-arm64.pgo.txt index 7ee4d08..a423bf9f 100644 --- a/chrome/build/lacros-arm64.pgo.txt +++ b/chrome/build/lacros-arm64.pgo.txt
@@ -1 +1 @@ -chrome-chromeos-arm64-generic-main-1710719576-f60c7735eef5ab4f2b414f10991d5b4ba955ebdb-a459617226fe1ccbdac4361cf509fd0fa30d7db9.profdata +chrome-chromeos-arm64-generic-main-1710762904-4bcf864a5564d04f60a9ceb56c4c6912aa4902c9-078b54b8063451151653e69250c1273230c084b6.profdata
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt index 0a08e74..fb900419 100644 --- a/chrome/build/linux.pgo.txt +++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@ -chrome-linux-main-1710741335-2e62df4c4f82023f23f77c982d00e3110d1755a9-8fff5839a476032921df1ff950cd8378408e2559.profdata +chrome-linux-main-1710762904-560250b1e360f5dcc0cf9091376c9106ff876ca3-078b54b8063451151653e69250c1273230c084b6.profdata
diff --git a/chrome/build/mac-arm.pgo.txt b/chrome/build/mac-arm.pgo.txt index f53a449..9b78f346 100644 --- a/chrome/build/mac-arm.pgo.txt +++ b/chrome/build/mac-arm.pgo.txt
@@ -1 +1 @@ -chrome-mac-arm-main-1710762904-a570344fbefe629efcb75d1ea1d66e21cab1b92f-078b54b8063451151653e69250c1273230c084b6.profdata +chrome-mac-arm-main-1710777545-98c028c1f5b9e5706164e00af7f7fdf5e1449295-033921b894618860e0dde15caa4d3bd9ceb009d7.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt index eac3f1e..4a6f0ee0 100644 --- a/chrome/build/mac.pgo.txt +++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@ -chrome-mac-main-1710741335-ebdc39fd8bb8b6991a2d6dc3fdcbda8a0cfc88ce-8fff5839a476032921df1ff950cd8378408e2559.profdata +chrome-mac-main-1710762904-f26e4ecf4dacea562c518119ca4947d1c7c3b90b-078b54b8063451151653e69250c1273230c084b6.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt index 1421934..aa6add61 100644 --- a/chrome/build/win32.pgo.txt +++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@ -chrome-win32-main-1710741335-ee592b0eb9480939071831f89457b5f3b975fa7a-8fff5839a476032921df1ff950cd8378408e2559.profdata +chrome-win32-main-1710762904-7029e2916ac9fd2d70ec4e2103da3ad660bf391a-078b54b8063451151653e69250c1273230c084b6.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt index 67f4089..28806a4 100644 --- a/chrome/build/win64.pgo.txt +++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@ -chrome-win64-main-1710752066-1cbc842fa8d3da4f1a0ec312888cddd620e74317-ed50b3d6f2f53eef4a0c034ce15b894af1b27935.profdata +chrome-win64-main-1710762904-2e0092bdaae152637f22f385f0e5992225106e3c-078b54b8063451151653e69250c1273230c084b6.profdata
diff --git a/chrome/renderer/autofill/password_autofill_agent_browsertest.cc b/chrome/renderer/autofill/password_autofill_agent_browsertest.cc index cbc84c7..3fc7491 100644 --- a/chrome/renderer/autofill/password_autofill_agent_browsertest.cc +++ b/chrome/renderer/autofill/password_autofill_agent_browsertest.cc
@@ -4772,6 +4772,21 @@ SimulateUserInputChangeForElement(&username_element_, kAliceUsername); } +// Tests that user modifying the text field value does not notify the browser if +// the field is labeled as a search field. +TEST_F(PasswordAutofillAgentTest, ModifySearchField) { + LoadHTML(kSingleUsernameFormHTML); + UpdateOnlyUsernameElement(); + username_element_.SetAttribute("name", "thesearchfield"); + +#if BUILDFLAG(IS_ANDROID) + // TODO(crbug.com/1293802): User typing doesn't send focus events properly. + FocusFirstInputElement(); +#endif + EXPECT_CALL(fake_driver_, UserModifiedNonPasswordField).Times(0); + SimulateUserInputChangeForElement(&username_element_, kAliceUsername); +} + // Tests that user inputs are propagated to the browser properly when a Shadow // DOM tree starts between the <form> and <input> tags. TEST_F(PasswordAutofillAgentTest,
diff --git a/chrome/renderer/benchmarking_extension.cc b/chrome/renderer/benchmarking_extension.cc index 359030f..b7c1a78b 100644 --- a/chrome/renderer/benchmarking_extension.cc +++ b/chrome/renderer/benchmarking_extension.cc
@@ -5,6 +5,8 @@ #include "chrome/renderer/benchmarking_extension.h" #include "base/command_line.h" +#include "base/process/process_handle.h" +#include "base/threading/platform_thread.h" #include "base/time/time.h" #include "content/public/common/content_switches.h" #include "content/public/renderer/render_thread.h" @@ -18,39 +20,46 @@ class BenchmarkingWrapper : public v8::Extension { public: - BenchmarkingWrapper() : - v8::Extension(kBenchmarkingExtensionName, - "if (typeof(chrome) == 'undefined') {" - " chrome = {};" - "};" - "if (typeof(chrome.benchmarking) == 'undefined') {" - " chrome.benchmarking = {};" - "};" - "chrome.benchmarking.isSingleProcess = function() {" - " native function IsSingleProcess();" - " return IsSingleProcess();" - "};" - "chrome.Interval = function() {" - " var start_ = 0;" - " var stop_ = 0;" - " native function HiResTime();" - " this.start = function() {" - " stop_ = 0;" - " start_ = HiResTime();" - " };" - " this.stop = function() {" - " stop_ = HiResTime();" - " if (start_ == 0)" - " stop_ = 0;" - " };" - " this.microseconds = function() {" - " var stop = stop_;" - " if (stop == 0 && start_ != 0)" - " stop = HiResTime();" - " return Math.ceil(stop - start_);" - " };" - "}" - ) {} + BenchmarkingWrapper() + : v8::Extension(kBenchmarkingExtensionName, + "if (typeof(chrome) == 'undefined') {" + " chrome = {};" + "};" + "if (typeof(chrome.benchmarking) == 'undefined') {" + " chrome.benchmarking = {};" + "};" + "chrome.benchmarking.isSingleProcess = function() {" + " native function IsSingleProcess();" + " return IsSingleProcess();" + "};" + "chrome.benchmarking.getRendererPid = function() {" + " native function GetRendererPid();" + " return GetRendererPid();" + "};" + "chrome.benchmarking.getRendererMainTid = function() {" + " native function GetRendererMainTid();" + " return GetRendererMainTid();" + "};" + "chrome.Interval = function() {" + " var start_ = 0;" + " var stop_ = 0;" + " native function HiResTime();" + " this.start = function() {" + " stop_ = 0;" + " start_ = HiResTime();" + " };" + " this.stop = function() {" + " stop_ = HiResTime();" + " if (start_ == 0)" + " stop_ = 0;" + " };" + " this.microseconds = function() {" + " var stop = stop_;" + " if (stop == 0 && start_ != 0)" + " stop = HiResTime();" + " return Math.ceil(stop - start_);" + " };" + "}") {} v8::Local<v8::FunctionTemplate> GetNativeFunctionTemplate( v8::Isolate* isolate, @@ -65,6 +74,16 @@ v8::NewStringType::kInternalized) .ToLocalChecked())) { return v8::FunctionTemplate::New(isolate, HiResTime); + } else if (name->StringEquals( + v8::String::NewFromUtf8(isolate, "GetRendererPid", + v8::NewStringType::kInternalized) + .ToLocalChecked())) { + return v8::FunctionTemplate::New(isolate, GetRendererPid); + } else if (name->StringEquals( + v8::String::NewFromUtf8(isolate, "GetRendererMainTid", + v8::NewStringType::kInternalized) + .ToLocalChecked())) { + return v8::FunctionTemplate::New(isolate, GetRendererMainTid); } return v8::Local<v8::FunctionTemplate>(); @@ -79,6 +98,16 @@ args.GetReturnValue().Set( static_cast<double>(base::TimeTicks::Now().ToInternalValue())); } + + static void GetRendererPid(const v8::FunctionCallbackInfo<v8::Value>& args) { + args.GetReturnValue().Set(static_cast<int>(base::GetCurrentProcId())); + } + + static void GetRendererMainTid( + const v8::FunctionCallbackInfo<v8::Value>& args) { + args.GetReturnValue().Set( + static_cast<int>(base::PlatformThread::CurrentId())); + } }; std::unique_ptr<v8::Extension> BenchmarkingExtension::Get() {
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 32b0aa4..a50b8f69 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -2561,6 +2561,7 @@ "../browser/preloading/prefetch/search_prefetch/search_preload_unified_browsertest.cc", "../browser/preloading/prefetch/zero_suggest_prefetch/zero_suggest_prefetch_tab_helper_browsertest.cc", "../browser/privacy_sandbox/privacy_sandbox_attestations/privacy_sandbox_attestations_component_installer_browsertest.cc", + "../browser/privacy_sandbox/privacy_sandbox_notice_confirmation_browsertest.cc", "../browser/privacy_sandbox/privacy_sandbox_settings_browsertest.cc", "../browser/privacy_sandbox/tracking_protection_notice_browsertest.cc", "../browser/privacy_sandbox/tracking_protection_settings_browsertest.cc",
diff --git a/chrome/test/chromedriver/test/run_py_tests.py b/chrome/test/chromedriver/test/run_py_tests.py index 623ba31..5b8b7115 100755 --- a/chrome/test/chromedriver/test/run_py_tests.py +++ b/chrome/test/chromedriver/test/run_py_tests.py
@@ -7783,7 +7783,9 @@ ]}""" % self._accounts, 'utf-8') def respondWithTokenResponse(request): - return {'Content-Type': 'application/json'}, self._token_response + return {'Content-Type': 'application/json', + 'Access-Control-Allow-Origin': request.GetHeader('Origin'), + 'Access-Control-Allow-Credentials': 'true'}, self._token_response self._https_server.SetCallbackForPath('/.well-known/web-identity', respondWithWellKnownFile)
diff --git a/chrome/test/data/webui/chromeos/internet_detail_dialog_test.ts b/chrome/test/data/webui/chromeos/internet_detail_dialog_test.ts index 265267e..f000e1ee 100644 --- a/chrome/test/data/webui/chromeos/internet_detail_dialog_test.ts +++ b/chrome/test/data/webui/chromeos/internet_detail_dialog_test.ts
@@ -6,6 +6,8 @@ import {InternetDetailDialogElement} from 'chrome://internet-detail-dialog/internet_detail_dialog.js'; import {InternetDetailDialogBrowserProxy, InternetDetailDialogBrowserProxyImpl} from 'chrome://internet-detail-dialog/internet_detail_dialog_browser_proxy.js'; +import {CrButtonElement} from 'chrome://resources/ash/common/cr_elements/cr_button/cr_button.js'; +import {CrToastElement} from 'chrome://resources/ash/common/cr_elements/cr_toast/cr_toast.js'; import {ApnList} from 'chrome://resources/ash/common/network/apn_list.js'; import {MojoInterfaceProviderImpl} from 'chrome://resources/ash/common/network/mojo_interface_provider.js'; import {NetworkApnListElement} from 'chrome://resources/ash/common/network/network_apnlist.js'; @@ -16,11 +18,9 @@ import {NetworkProxyElement} from 'chrome://resources/ash/common/network/network_proxy.js'; import {NetworkSiminfoElement} from 'chrome://resources/ash/common/network/network_siminfo.js'; import {OncMojo} from 'chrome://resources/ash/common/network/onc_mojo.js'; -import {CrButtonElement} from 'chrome://resources/ash/common/cr_elements/cr_button/cr_button.js'; -import {CrToastElement} from 'chrome://resources/ash/common/cr_elements/cr_toast/cr_toast.js'; import {assert} from 'chrome://resources/js/assert.js'; import {loadTimeData} from 'chrome://resources/js/load_time_data.js'; -import {ApnAuthenticationType, ApnIpType, ApnProperties, ApnState, ApnType, InhibitReason, MAX_NUM_CUSTOM_APNS, SIMInfo} from 'chrome://resources/mojo/chromeos/services/network_config/public/mojom/cros_network_config.mojom-webui.js'; +import {ApnAuthenticationType, ApnIpType, ApnProperties, ApnSource, ApnState, ApnType, InhibitReason, MAX_NUM_CUSTOM_APNS, SIMInfo} from 'chrome://resources/mojo/chromeos/services/network_config/public/mojom/cros_network_config.mojom-webui.js'; import {ConnectionStateType, DeviceStateType, NetworkType, OncSource, PortalState} from 'chrome://resources/mojo/chromeos/services/network_config/public/mojom/network_types.mojom-webui.js'; import {IronCollapseElement} from 'chrome://resources/polymer/v3_0/iron-collapse/iron-collapse.js'; import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; @@ -164,7 +164,8 @@ }); } - function createApn(accessPointName: string, name?: string) { + function createApn( + accessPointName: string, source: ApnSource, name?: string) { return { accessPointName: accessPointName, id: undefined, @@ -178,6 +179,7 @@ state: ApnState.kEnabled, ipType: ApnIpType.kAutomatic, apnTypes: [ApnType.kDefault], + source: source, }; } @@ -441,7 +443,7 @@ const accessPointName = 'access point name'; await setupCellularNetwork( /* isPrimary= */ true, /* isInhibited= */ false, - createApn(accessPointName)); + createApn(accessPointName, ApnSource.kModb)); // Force a refresh. internetDetailDialog.onDeviceStateListChanged(); @@ -455,7 +457,7 @@ const name = 'name'; await setupCellularNetwork( /* isPrimary= */ true, /* isInhibited= */ false, - createApn(accessPointName, name), + createApn(accessPointName, ApnSource.kModb, name), /* customApnList= */ undefined, /* errorState= */ undefined, PortalState.kNoInternet); @@ -493,7 +495,9 @@ }); await setupCellularNetwork( /* isPrimary= */ true, /* isInhibited= */ false, - createApn(/*accessPointName=*/ 'access point name'), []); + createApn( + /*accessPointName=*/ 'access point name', ApnSource.kModb), + []); await init(); getElement('cr-expand-button').click(); @@ -515,9 +519,10 @@ // We're setting the list of APNs to the max number await setupCellularNetwork( /* isPrimary= */ true, /* isInhibited= */ false, - createApn(/*accessPointName=*/ 'access point name'), + createApn( + /*accessPointName=*/ 'access point name', ApnSource.kModb), Array(MAX_NUM_CUSTOM_APNS) - .fill(createApn(/*accessPointName=*/ 'apn'))); + .fill(createApn(/*accessPointName=*/ 'apn', ApnSource.kUi))); internetDetailDialog.onDeviceStateListChanged(); await flushAsync(); @@ -530,7 +535,9 @@ await setupCellularNetwork( /* isPrimary= */ true, /* isInhibited= */ false, - createApn(/*accessPointName=*/ 'access point name'), []); + createApn( + /*accessPointName=*/ 'access point name', ApnSource.kModb), + []); internetDetailDialog.onDeviceStateListChanged(); await flushAsync();
diff --git a/chrome/test/data/webui/chromeos/personalization_app/personalization_app_test.ts b/chrome/test/data/webui/chromeos/personalization_app/personalization_app_test.ts index 512435c..0ffaf3e7 100644 --- a/chrome/test/data/webui/chromeos/personalization_app/personalization_app_test.ts +++ b/chrome/test/data/webui/chromeos/personalization_app/personalization_app_test.ts
@@ -3,10 +3,11 @@ // found in the LICENSE file. import {DynamicColorElement, getThemeProvider, GooglePhotosAlbumsElement, GooglePhotosCollectionElement, GooglePhotosSharedAlbumDialogElement, PersonalizationRouterElement, PersonalizationThemeElement, SeaPenRouterElement, SeaPenTemplateQueryElement, setTransitionsEnabled, WallpaperCollectionsElement, WallpaperGridItemElement, WallpaperImagesElement} from 'chrome://personalization/js/personalization_app.js'; +import {CrButtonElement} from 'chrome://resources/ash/common/cr_elements/cr_button/cr_button.js'; import {assertInstanceof} from 'chrome://resources/js/assert.js'; import {SkColor} from 'chrome://resources/mojo/skia/public/mojom/skcolor.mojom-webui.js'; import {IronSelectorElement} from 'chrome://resources/polymer/v3_0/iron-selector/iron-selector.js'; -import {assertDeepEquals, assertEquals, assertFalse, assertGT, assertNotEquals, assertTrue} from 'chrome://webui-test/chai_assert.js'; +import {assertDeepEquals, assertEquals, assertFalse, assertGT, assertLE, assertNotEquals, assertTrue} from 'chrome://webui-test/chai_assert.js'; /** * @fileoverview E2E test suite for chrome://personalization. @@ -637,28 +638,26 @@ 'waiting for sea-pen-options to load'); let options = await waitUntil( - () => - seaPenOptions.shadowRoot?.querySelector<HTMLDivElement>('#options'), + () => seaPenOptions.shadowRoot?.querySelectorAll<CrButtonElement>( + '.option'), 'waiting for options to load'); - assertTrue(!!options, 'options should show up'); - assertTrue( - options.clientHeight < options.scrollHeight, - 'some options should be hidden'); + const numOptionsInitiallyShown = options.length; + assertTrue(numOptionsInitiallyShown > 0, 'some options are shown'); const expandButton = await waitUntil( - () => seaPenOptions.shadowRoot?.querySelector<HTMLSpanElement>( - '#expand > span.clickable'), + () => seaPenOptions.shadowRoot?.querySelector<CrButtonElement>( + '#expandButton'), 'wait for expand button'); assertTrue(!!expandButton, 'expand button should show up'); expandButton.click(); options = await waitUntil( - () => - seaPenOptions.shadowRoot?.querySelector<HTMLDivElement>('#options'), + () => seaPenOptions.shadowRoot?.querySelectorAll<CrButtonElement>( + '.option'), 'waiting for options to load'); - assertTrue( - options.clientHeight >= options.scrollHeight, - 'all options should show up'); + assertLE( + numOptionsInitiallyShown, options.length, + 'more options should show up after clicking expand button'); }); });
diff --git a/chrome/test/data/webui/chromeos/personalization_app/sea_pen_template_query_element_test.ts b/chrome/test/data/webui/chromeos/personalization_app/sea_pen_template_query_element_test.ts index 35813f44..f3c1333 100644 --- a/chrome/test/data/webui/chromeos/personalization_app/sea_pen_template_query_element_test.ts +++ b/chrome/test/data/webui/chromeos/personalization_app/sea_pen_template_query_element_test.ts
@@ -6,7 +6,7 @@ import 'chrome://webui-test/chromeos/mojo_webui_test_support.js'; import {SeaPenOptionsElement, SeaPenPaths, SeaPenRouterElement, SeaPenTemplateQueryElement} from 'chrome://personalization/js/personalization_app.js'; -import type {CrButtonElement} from 'chrome://resources/ash/common/cr_elements/cr_button/cr_button.js'; +import {CrButtonElement} from 'chrome://resources/ash/common/cr_elements/cr_button/cr_button.js'; import {SeaPenQuery} from 'chrome://resources/ash/common/sea_pen/sea_pen.mojom-webui.js'; import {SeaPenTemplateId} from 'chrome://resources/ash/common/sea_pen/sea_pen_generated.mojom-webui.js'; import {loadTimeData} from 'chrome://resources/js/load_time_data.js'; @@ -60,8 +60,9 @@ const unselectedTemplate = seaPenTemplateQueryElement.shadowRoot!.querySelectorAll( '#template .unselected'); - const searchButton = seaPenTemplateQueryElement.shadowRoot!.querySelector( - '#searchButton') as HTMLElement; + const searchButton = + seaPenTemplateQueryElement.shadowRoot!.querySelector<CrButtonElement>( + '#searchButton'); assertTrue(chips.length > 0, 'there should be chips to select'); assertEquals( @@ -143,8 +144,8 @@ !!seaPenOptionsElement, 'the options chips should show after clicking a chip'); const optionToSelect = - seaPenOptionsElement.shadowRoot!.querySelector( - '#options cr-button:not([aria-selected])') as HTMLElement; + seaPenOptionsElement.shadowRoot!.querySelector<CrButtonElement>( + '#container cr-button:not([aria-selected])'); const optionText = optionToSelect!.innerText; assertTrue( optionText !== chip.innerText, @@ -178,13 +179,13 @@ assertTrue( !!seaPenOptionsElement, 'the options chips should show after clicking a chip'); - const options = - seaPenOptionsElement.shadowRoot!.querySelectorAll('#options cr-button'); + const options = seaPenOptionsElement.shadowRoot!.querySelectorAll( + '#container cr-button'); assertTrue( options.length > 0, 'there should be options available to select'); const selectedOption = - seaPenOptionsElement.shadowRoot!.querySelector( - '#options cr-button[aria-selected]') as HTMLElement; + seaPenOptionsElement.shadowRoot!.querySelector<CrButtonElement>( + '#container cr-button[aria-selected]'); assertEquals( chipToSelect.innerText, selectedOption!.innerText, 'the selected chip should have an equivalent selected option'); @@ -216,13 +217,13 @@ assertTrue( !!seaPenOptionsElement, 'the options chips should show after clicking a chip'); - const options = - seaPenOptionsElement.shadowRoot!.querySelectorAll('#options cr-button'); + const options = seaPenOptionsElement.shadowRoot!.querySelectorAll( + '#container cr-button'); assertTrue( options.length > 0, 'there should be options available to select'); const selectedOption = - seaPenOptionsElement.shadowRoot!.querySelector( - '#options cr-button[aria-selected]') as HTMLElement; + seaPenOptionsElement.shadowRoot!.querySelector<CrButtonElement>( + '#container cr-button[aria-selected]'); assertTrue( !!selectedOption!.querySelector('img'), 'the selected option should contain a preview image'); @@ -256,8 +257,8 @@ !!seaPenOptionsElement, 'the options chips should show after clicking a chip'); const optionToSelect = - seaPenOptionsElement.shadowRoot!.querySelector( - '#options cr-button:not([aria-selected])') as HTMLElement; + seaPenOptionsElement.shadowRoot!.querySelector<CrButtonElement>( + '#container cr-button:not([aria-selected])'); const optionText = optionToSelect!.innerText; assertTrue( optionText !== chip.innerText, @@ -267,14 +268,15 @@ await waitAfterNextRender(seaPenTemplateQueryElement); let selectedOption = - seaPenOptionsElement.shadowRoot!.querySelector( - '#options cr-button[aria-selected]') as HTMLElement; + seaPenOptionsElement.shadowRoot!.querySelector<CrButtonElement>( + '#container cr-button[aria-selected]'); assertEquals( selectedOption!.innerText, optionText, 'the new option should now be selected'); - const selectedChip = seaPenTemplateQueryElement.shadowRoot!.querySelector( - '#template .selected') as HTMLElement; + const selectedChip = + seaPenTemplateQueryElement.shadowRoot!.querySelector<CrButtonElement>( + '#template .selected'); assertEquals( selectedChip!.innerText, optionText, 'the chip should update to match the new selected option'); @@ -282,8 +284,9 @@ chip!.click(); await waitAfterNextRender(seaPenTemplateQueryElement); - selectedOption = seaPenOptionsElement.shadowRoot!.querySelector( - '#options cr-button[aria-selected]') as HTMLElement; + selectedOption = + seaPenOptionsElement.shadowRoot!.querySelector<CrButtonElement>( + '#container cr-button[aria-selected]'); assertTrue(!selectedOption, 'Clicking the chip again will hide options.'); }); @@ -313,8 +316,8 @@ !!seaPenOptionsElement, 'the options chips should show after clicking a chip'); let selectedOption = - seaPenOptionsElement.shadowRoot!.querySelector( - '#options cr-button[aria-selected]') as HTMLElement; + seaPenOptionsElement.shadowRoot!.querySelector<CrButtonElement>( + '#container cr-button[aria-selected]'); let optionText = selectedOption!.innerText; assertTrue( optionText === chips[0]!.innerText, @@ -323,8 +326,9 @@ chips[1]!.click(); await waitAfterNextRender(seaPenTemplateQueryElement); - selectedOption = seaPenOptionsElement.shadowRoot!.querySelector( - '#options cr-button[aria-selected]') as HTMLElement; + selectedOption = + seaPenOptionsElement.shadowRoot!.querySelector<CrButtonElement>( + '#container cr-button[aria-selected]'); optionText = selectedOption!.innerText; assertTrue( optionText === chips[1]!.innerText,
diff --git a/chrome/test/data/webui/cr_components/chromeos/network/apn_list_test.js b/chrome/test/data/webui/cr_components/chromeos/network/apn_list_test.js index 75e186a..21dd0374 100644 --- a/chrome/test/data/webui/cr_components/chromeos/network/apn_list_test.js +++ b/chrome/test/data/webui/cr_components/chromeos/network/apn_list_test.js
@@ -8,7 +8,7 @@ import {ApnDetailDialogMode} from '//resources/ash/common/network/cellular_utils.js'; import {ApnList} from 'chrome://resources/ash/common/network/apn_list.js'; import {OncMojo} from 'chrome://resources/ash/common/network/onc_mojo.js'; -import {ApnProperties, ApnState, ApnType} from 'chrome://resources/mojo/chromeos/services/network_config/public/mojom/cros_network_config.mojom-webui.js'; +import {ApnProperties, ApnSource, ApnState, ApnType} from 'chrome://resources/mojo/chromeos/services/network_config/public/mojom/cros_network_config.mojom-webui.js'; import {PortalState} from 'chrome://resources/mojo/chromeos/services/network_config/public/mojom/network_types.mojom-webui.js'; import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js'; import {flushTasks} from 'chrome://webui-test/polymer_test_util.js'; @@ -403,13 +403,27 @@ apnList.managedCellularProperties = {}; assertEquals(0, getApnSelectionDialog().apnList.length); + const modbApn = { + accessPointName: 'Access Point 1', + source: ApnSource.kModb, + }; + const modemApn = { + accessPointName: 'Access Point 2', + source: ApnSource.kModem, + }; apnList.managedCellularProperties = { apnList: { - activeValue: [apn1], + activeValue: [ + modbApn, + modemApn, + ], }, }; + + // Only APNs with source kModb should be present. assertEquals(1, getApnSelectionDialog().apnList.length); - assertTrue(OncMojo.apnMatch(apn1, getApnSelectionDialog().apnList[0])); + assertTrue( + OncMojo.apnMatch(modbApn, getApnSelectionDialog().apnList[0])); const cancelButton = getApnSelectionDialog().shadowRoot.querySelector('.cancel-button');
diff --git a/chrome/test/data/webui/new_tab_page/modules/v2/tab_resumption/module_test.ts b/chrome/test/data/webui/new_tab_page/modules/v2/tab_resumption/module_test.ts index 11ed41d3..9949f871 100644 --- a/chrome/test/data/webui/new_tab_page/modules/v2/tab_resumption/module_test.ts +++ b/chrome/test/data/webui/new_tab_page/modules/v2/tab_resumption/module_test.ts
@@ -7,6 +7,7 @@ import {tabResumptionDescriptor, TabResumptionProxyImpl} from 'chrome://new-tab-page/lazy_load.js'; import {$$} from 'chrome://new-tab-page/new_tab_page.js'; import {PageHandlerRemote} from 'chrome://new-tab-page/tab_resumption.mojom-webui.js'; +import {loadTimeData} from 'chrome://resources/js/load_time_data.js'; import {assertEquals, assertTrue} from 'chrome://webui-test/chai_assert.js'; import {waitAfterNextRender} from 'chrome://webui-test/polymer_test_util.js'; import type {TestMock} from 'chrome://webui-test/test_mock.js'; @@ -39,6 +40,12 @@ suite('NewTabPageModulesTabResumptionModuleTest', () => { let handler: TestMock<PageHandlerRemote>; + suiteSetup(() => { + loadTimeData.overrideValues({ + modulesRedesignedEnabled: true, + }); + }); + setup(() => { document.body.innerHTML = window.trustedTypes!.emptyHTML; handler = installMock( @@ -127,5 +134,33 @@ restoreCallback(); assertTrue(!!moduleElement); }); + + test( + 'Header dismiss button dispatches dismiss module event in pre ' + + 'redesign launchpad', + async () => { + loadTimeData.overrideValues({ + modulesRedesignedEnabled: false, + }); + // Arrange. + const moduleElement = await initializeModule(createSampleTabs(1)); + + // Assert. + assertTrue(!!moduleElement); + const headerElement = $$(moduleElement, 'ntp-module-header'); + assertTrue(!!headerElement); + const waitForDismissEvent = + eventToPromise('dismiss-module', moduleElement); + headerElement!.dispatchEvent(new Event('dismiss-button-click')); + + const dismissEvent: DismissModuleInstanceEvent = + await waitForDismissEvent; + assertEquals(`Tabs hidden`, dismissEvent.detail.message); + + // Act. + const restoreCallback = dismissEvent.detail.restoreCallback!; + restoreCallback(); + assertTrue(!!moduleElement); + }); }); });
diff --git a/chrome/test/data/webui/settings/chromeos/apn_detail_dialog_test.ts b/chrome/test/data/webui/settings/chromeos/apn_detail_dialog_test.ts index 32f41e2d..3e46279 100644 --- a/chrome/test/data/webui/settings/chromeos/apn_detail_dialog_test.ts +++ b/chrome/test/data/webui/settings/chromeos/apn_detail_dialog_test.ts
@@ -8,7 +8,7 @@ import {ApnDetailDialogMode} from 'chrome://resources/ash/common/network/cellular_utils.js'; import {MojoInterfaceProviderImpl} from 'chrome://resources/ash/common/network/mojo_interface_provider.js'; import {OncMojo} from 'chrome://resources/ash/common/network/onc_mojo.js'; -import {ApnAuthenticationType, ApnIpType, ApnProperties, ApnState, ApnType} from 'chrome://resources/mojo/chromeos/services/network_config/public/mojom/cros_network_config.mojom-webui.js'; +import {ApnAuthenticationType, ApnIpType, ApnProperties, ApnSource, ApnState, ApnType} from 'chrome://resources/mojo/chromeos/services/network_config/public/mojom/cros_network_config.mojom-webui.js'; import {NetworkType} from 'chrome://resources/mojo/chromeos/services/network_config/public/mojom/network_types.mojom-webui.js'; import {assertEquals, assertFalse, assertNull, assertStringContains, assertTrue} from 'chrome://webui-test/chai_assert.js'; import {FakeNetworkConfig} from 'chrome://webui-test/chromeos/fake_network_config_mojom.js'; @@ -28,6 +28,7 @@ localizedName: undefined, name: undefined, attach: undefined, + source: ApnSource.kUi, }; suite('<apn-detail-dialog>', () => {
diff --git a/chrome/test/data/webui/settings/chromeos/internet_page/internet_detail_subpage_test.ts b/chrome/test/data/webui/settings/chromeos/internet_page/internet_detail_subpage_test.ts index abc1964..15cff86 100644 --- a/chrome/test/data/webui/settings/chromeos/internet_page/internet_detail_subpage_test.ts +++ b/chrome/test/data/webui/settings/chromeos/internet_page/internet_detail_subpage_test.ts
@@ -18,7 +18,7 @@ import {OncMojo} from 'chrome://resources/ash/common/network/onc_mojo.js'; import {loadTimeData} from 'chrome://resources/js/load_time_data.js'; import {getDeepActiveElement} from 'chrome://resources/js/util.js'; -import {ActivationStateType, ApnAuthenticationType, ApnIpType, ApnState, DeviceStateProperties, GlobalPolicy, InhibitReason, ManagedOpenVPNProperties, ManagedProperties, MatchType, NetworkStateProperties, ProxyMode, SuppressionType, VpnType} from 'chrome://resources/mojo/chromeos/services/network_config/public/mojom/cros_network_config.mojom-webui.js'; +import {ActivationStateType, ApnAuthenticationType, ApnIpType, ApnSource, ApnState, DeviceStateProperties, GlobalPolicy, InhibitReason, ManagedOpenVPNProperties, ManagedProperties, MatchType, NetworkStateProperties, ProxyMode, SuppressionType, VpnType} from 'chrome://resources/mojo/chromeos/services/network_config/public/mojom/cros_network_config.mojom-webui.js'; import {ConnectionStateType, DeviceStateType, IPConfigType, NetworkType, OncSource, PolicySource, PortalState} from 'chrome://resources/mojo/chromeos/services/network_config/public/mojom/network_types.mojom-webui.js'; import {assertEquals, assertFalse, assertNotEquals, assertNull, assertTrue} from 'chrome://webui-test/chai_assert.js'; import {FakeNetworkConfig} from 'chrome://webui-test/chromeos/fake_network_config_mojom.js'; @@ -1935,6 +1935,7 @@ state: ApnState.kEnabled, ipType: ApnIpType.kAutomatic, apnTypes: [], + source: ApnSource.kModb, }; cellularNetwork.typeProperties.cellular!.connectedApn!.accessPointName = apnName;
diff --git a/chrome/test/data/webui/settings/chromeos/internet_page/settings_traffic_counters_test.ts b/chrome/test/data/webui/settings/chromeos/internet_page/settings_traffic_counters_test.ts index 3a852ff0..f061edf 100644 --- a/chrome/test/data/webui/settings/chromeos/internet_page/settings_traffic_counters_test.ts +++ b/chrome/test/data/webui/settings/chromeos/internet_page/settings_traffic_counters_test.ts
@@ -11,7 +11,7 @@ import {ConnectionStateType, NetworkType} from 'chrome://resources/mojo/chromeos/services/network_config/public/mojom/network_types.mojom-webui.js'; import {Time} from 'chrome://resources/mojo/mojo/public/mojom/base/time.mojom-webui.js'; import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; -import {assertEquals, assertTrue} from 'chrome://webui-test/chai_assert.js'; +import {assertEquals} from 'chrome://webui-test/chai_assert.js'; import {FakeNetworkConfig} from 'chrome://webui-test/chromeos/fake_network_config_mojom.js'; import {flushTasks} from 'chrome://webui-test/polymer_test_util.js'; @@ -87,35 +87,15 @@ } function getDataUsageLabel(): string { - const dataUsageLabelDiv = - settingsTrafficCounters.shadowRoot!.querySelector('#dataUsageLabel'); - assertTrue(!!dataUsageLabelDiv); + const dataUsageLabelDiv = settingsTrafficCounters.$.dataUsageLabel; return dataUsageLabelDiv.textContent!.trim(); } function getDataUsageSubLabel(): string { - const dataUsageSubLabelDiv = - settingsTrafficCounters.shadowRoot!.querySelector('#dataUsageSubLabel'); - assertTrue(!!dataUsageSubLabelDiv); + const dataUsageSubLabelDiv = settingsTrafficCounters.$.dataUsageSubLabel; return dataUsageSubLabelDiv.textContent!.trim(); } - function getResetDataUsageButton(): HTMLButtonElement { - const resetDataUsageButton = - settingsTrafficCounters.shadowRoot!.querySelector<HTMLButtonElement>( - '#resetDataUsageButton'); - assertTrue(!!resetDataUsageButton); - return resetDataUsageButton; - } - - function getDaySelectionInput(): HTMLInputElement { - const daySelectionInput = - settingsTrafficCounters.shadowRoot!.querySelector<HTMLInputElement>( - '#daySelectionInput'); - assertTrue(!!daySelectionInput); - return daySelectionInput; - } - setup(() => { networkConfigRemote = new FakeNetworkConfig(); MojoInterfaceProviderImpl.getInstance().setMojoServiceRemoteForTest( @@ -191,7 +171,7 @@ assertEquals(EXPECTED_INITIAL_DATA_USAGE_LABEL, getDataUsageLabel()); assertEquals(EXPECTED_INITIAL_DATA_USAGE_SUBLABEL, getDataUsageSubLabel()); - assertEquals(31, getDaySelectionInput().value); + assertEquals(String(31), settingsTrafficCounters.$.resetDayList.value); // Simulate a reset by updating the last reset time for the cellular // network. The internal value represents two days after the initial @@ -205,7 +185,11 @@ await flushTasks(); // Reset the data usage. - getResetDataUsageButton().click(); + settingsTrafficCounters.$.resetDataUsageButton.click(); + // Load the data post reset. Note we have to include the load() in tests + // and not in onResetDataUsageClicked_() because SettingTrafficCounters' + // parent element handles the reloading in prod. + settingsTrafficCounters.load(); await flushTasks(); assertEquals(EXPECTED_POST_RESET_DATA_USAGE_LABEL, getDataUsageLabel());
diff --git a/chromeos/ash/components/audio/audio_device_metrics_handler.cc b/chromeos/ash/components/audio/audio_device_metrics_handler.cc index f99fc350..db43f36 100644 --- a/chromeos/ash/components/audio/audio_device_metrics_handler.cc +++ b/chromeos/ash/components/audio/audio_device_metrics_handler.cc
@@ -15,10 +15,13 @@ bool is_input, bool is_switched, bool is_chrome_restarts, + const AudioDeviceList& previous_device_list, const AudioDeviceList& current_device_list) const { std::string system_switch_histogram_name; std::string device_count_histogram_name; std::string device_set_histogram_name; + std::string before_and_after_device_set_histogram_name; + if (is_chrome_restarts) { system_switch_histogram_name = is_input @@ -36,6 +39,12 @@ kSystemSwitchInputAudioDeviceSetChromeRestarts : AudioDeviceMetricsHandler:: kSystemSwitchOutputAudioDeviceSetChromeRestarts; + before_and_after_device_set_histogram_name = + is_input + ? AudioDeviceMetricsHandler:: + kSystemSwitchInputBeforeAndAfterAudioDeviceSetChromeRestarts + : AudioDeviceMetricsHandler:: + kSystemSwitchOutputBeforeAndAfterAudioDeviceSetChromeRestarts; } else { device_count_histogram_name = is_input ? AudioDeviceMetricsHandler:: @@ -47,6 +56,12 @@ kSystemNotSwitchInputAudioDeviceSetChromeRestarts : AudioDeviceMetricsHandler:: kSystemNotSwitchOutputAudioDeviceSetChromeRestarts; + before_and_after_device_set_histogram_name = + is_input + ? AudioDeviceMetricsHandler:: + kSystemNotSwitchInputBeforeAndAfterAudioDeviceSetChromeRestarts + : AudioDeviceMetricsHandler:: + kSystemNotSwitchOutputBeforeAndAfterAudioDeviceSetChromeRestarts; } } else { system_switch_histogram_name = @@ -66,6 +81,12 @@ kSystemSwitchInputAudioDeviceSetNonChromeRestarts : AudioDeviceMetricsHandler:: kSystemSwitchOutputAudioDeviceSetNonChromeRestarts; + before_and_after_device_set_histogram_name = + is_input + ? AudioDeviceMetricsHandler:: + kSystemSwitchInputBeforeAndAfterAudioDeviceSetNonChromeRestarts + : AudioDeviceMetricsHandler:: + kSystemSwitchOutputBeforeAndAfterAudioDeviceSetNonChromeRestarts; } else { device_count_histogram_name = is_input @@ -78,6 +99,12 @@ kSystemNotSwitchInputAudioDeviceSetNonChromeRestarts : AudioDeviceMetricsHandler:: kSystemNotSwitchOutputAudioDeviceSetNonChromeRestarts; + before_and_after_device_set_histogram_name = + is_input + ? AudioDeviceMetricsHandler:: + kSystemNotSwitchInputBeforeAndAfterAudioDeviceSetNonChromeRestarts + : AudioDeviceMetricsHandler:: + kSystemNotSwitchOutputBeforeAndAfterAudioDeviceSetNonChromeRestarts; } } @@ -92,6 +119,11 @@ // Record the encoded device set. base::UmaHistogramSparse(device_set_histogram_name, EncodeAudioDeviceSet(current_device_list)); + + // Record the before and after encoded device sets. + base::UmaHistogramSparse(before_and_after_device_set_histogram_name, + EncodeBeforeAndAfterAudioDeviceSets( + previous_device_list, current_device_list)); } } // namespace ash
diff --git a/chromeos/ash/components/audio/audio_device_metrics_handler.h b/chromeos/ash/components/audio/audio_device_metrics_handler.h index 930b5b0e..a930fea4 100644 --- a/chromeos/ash/components/audio/audio_device_metrics_handler.h +++ b/chromeos/ash/components/audio/audio_device_metrics_handler.h
@@ -91,6 +91,43 @@ "ChromeOS.AudioSelection.Output.SystemNotSwitchAudio.AudioDeviceSet." "NonChromeRestarts"; + // A series of histogram metrics to record the before and after condition + // of audio device types when the system selection decision is made after + // audio device has changed, separated + // by chrome restarts or not. + static constexpr char + kSystemSwitchInputBeforeAndAfterAudioDeviceSetChromeRestarts[] = + "ChromeOS.AudioSelection.Input.SystemSwitchAudio." + "BeforeAndAfterAudioDeviceSet.ChromeRestarts"; + static constexpr char + kSystemNotSwitchInputBeforeAndAfterAudioDeviceSetChromeRestarts[] = + "ChromeOS.AudioSelection.Input.SystemNotSwitchAudio." + "BeforeAndAfterAudioDeviceSet.ChromeRestarts"; + static constexpr char + kSystemSwitchOutputBeforeAndAfterAudioDeviceSetChromeRestarts[] = + "ChromeOS.AudioSelection.Output.SystemSwitchAudio." + "BeforeAndAfterAudioDeviceSet.ChromeRestarts"; + static constexpr char + kSystemNotSwitchOutputBeforeAndAfterAudioDeviceSetChromeRestarts[] = + "ChromeOS.AudioSelection.Output.SystemNotSwitchAudio." + "BeforeAndAfterAudioDeviceSet.ChromeRestarts"; + static constexpr char + kSystemSwitchInputBeforeAndAfterAudioDeviceSetNonChromeRestarts[] = + "ChromeOS.AudioSelection.Input.SystemSwitchAudio." + "BeforeAndAfterAudioDeviceSet.NonChromeRestarts"; + static constexpr char + kSystemNotSwitchInputBeforeAndAfterAudioDeviceSetNonChromeRestarts[] = + "ChromeOS.AudioSelection.Input.SystemNotSwitchAudio." + "BeforeAndAfterAudioDeviceSet.NonChromeRestarts"; + static constexpr char + kSystemSwitchOutputBeforeAndAfterAudioDeviceSetNonChromeRestarts[] = + "ChromeOS.AudioSelection.Output.SystemSwitchAudio." + "BeforeAndAfterAudioDeviceSet.NonChromeRestarts"; + static constexpr char + kSystemNotSwitchOutputBeforeAndAfterAudioDeviceSetNonChromeRestarts[] = + "ChromeOS.AudioSelection.Output.SystemNotSwitchAudio." + "BeforeAndAfterAudioDeviceSet.NonChromeRestarts"; + // Record system selection related metrics in the case of chrome restarts, // including system boots and users sign out, as well as the case of normal // user hotplug or unplug. @@ -98,6 +135,7 @@ bool is_input, bool is_switched, bool is_chrome_restarts, + const AudioDeviceList& previous_device_list, const AudioDeviceList& current_device_list) const; };
diff --git a/chromeos/ash/components/audio/audio_device_metrics_handler_unittest.cc b/chromeos/ash/components/audio/audio_device_metrics_handler_unittest.cc index 8673d57..f2ab7bf1 100644 --- a/chromeos/ash/components/audio/audio_device_metrics_handler_unittest.cc +++ b/chromeos/ash/components/audio/audio_device_metrics_handler_unittest.cc
@@ -26,6 +26,7 @@ RecordAudioSelectionMetrics_NonChromeRestarts) { AudioDevice input_USB = AudioDevice(NewInputNode("USB")); AudioDevice input_BLUETOOTH = AudioDevice(NewInputNode("BLUETOOTH")); + AudioDeviceList previous_devices = {input_USB}; AudioDeviceList current_devices = {input_USB, input_BLUETOOTH}; for (const bool is_input : {true, false}) { @@ -33,7 +34,7 @@ audio_device_metrics_handler() .RecordAudioSelectionMetricsSeparatedByChromeRestarts( is_input, is_switched, /*is_chrome_restarts=*/false, - current_devices); + previous_devices, current_devices); std::string system_switch_histogram_name = is_input ? AudioDeviceMetricsHandler:: @@ -77,9 +78,32 @@ : AudioDeviceMetricsHandler:: kSystemNotSwitchOutputAudioDeviceSetNonChromeRestarts; } + histogram_tester().ExpectBucketCount( device_set_histogram_name, EncodeAudioDeviceSet(current_devices), /*bucket_count=*/1); + + std::string before_and_after_device_set_histogram_name; + if (is_switched) { + before_and_after_device_set_histogram_name = + is_input + ? AudioDeviceMetricsHandler:: + kSystemSwitchInputBeforeAndAfterAudioDeviceSetNonChromeRestarts + : AudioDeviceMetricsHandler:: + kSystemSwitchOutputBeforeAndAfterAudioDeviceSetNonChromeRestarts; + } else { + before_and_after_device_set_histogram_name = + is_input + ? AudioDeviceMetricsHandler:: + kSystemNotSwitchInputBeforeAndAfterAudioDeviceSetNonChromeRestarts + : AudioDeviceMetricsHandler:: + kSystemNotSwitchOutputBeforeAndAfterAudioDeviceSetNonChromeRestarts; + } + histogram_tester().ExpectBucketCount( + before_and_after_device_set_histogram_name, + EncodeBeforeAndAfterAudioDeviceSets(previous_devices, + current_devices), + /*bucket_count=*/1); } } } @@ -88,6 +112,7 @@ RecordAudioSelectionMetrics_ChromeRestarts) { AudioDevice input_USB = AudioDevice(NewInputNode("USB")); AudioDevice input_BLUETOOTH = AudioDevice(NewInputNode("BLUETOOTH")); + AudioDeviceList previous_devices = {}; AudioDeviceList current_devices = {input_USB, input_BLUETOOTH}; for (const bool is_input : {true, false}) { @@ -95,7 +120,7 @@ audio_device_metrics_handler() .RecordAudioSelectionMetricsSeparatedByChromeRestarts( is_input, is_switched, /*is_chrome_restarts=*/true, - current_devices); + previous_devices, current_devices); std::string system_switch_histogram_name = is_input @@ -140,6 +165,28 @@ histogram_tester().ExpectBucketCount( device_set_histogram_name, EncodeAudioDeviceSet(current_devices), /*bucket_count=*/1); + + std::string before_and_after_device_set_histogram_name; + if (is_switched) { + before_and_after_device_set_histogram_name = + is_input + ? AudioDeviceMetricsHandler:: + kSystemSwitchInputBeforeAndAfterAudioDeviceSetChromeRestarts + : AudioDeviceMetricsHandler:: + kSystemSwitchOutputBeforeAndAfterAudioDeviceSetChromeRestarts; + } else { + before_and_after_device_set_histogram_name = + is_input + ? AudioDeviceMetricsHandler:: + kSystemNotSwitchInputBeforeAndAfterAudioDeviceSetChromeRestarts + : AudioDeviceMetricsHandler:: + kSystemNotSwitchOutputBeforeAndAfterAudioDeviceSetChromeRestarts; + } + histogram_tester().ExpectBucketCount( + before_and_after_device_set_histogram_name, + EncodeBeforeAndAfterAudioDeviceSets(previous_devices, + current_devices), + /*bucket_count=*/1); } } }
diff --git a/chromeos/ash/components/audio/audio_device_selection_unittest.cc b/chromeos/ash/components/audio/audio_device_selection_unittest.cc index c3794bb..b9df428 100644 --- a/chromeos/ash/components/audio/audio_device_selection_unittest.cc +++ b/chromeos/ash/components/audio/audio_device_selection_unittest.cc
@@ -339,6 +339,23 @@ AudioDevice(output_USB)}), /*bucket_count=*/1); + histogram_tester().ExpectBucketCount( + AudioDeviceMetricsHandler:: + kSystemSwitchInputBeforeAndAfterAudioDeviceSetNonChromeRestarts, + EncodeBeforeAndAfterAudioDeviceSets( + /*device_set_before=*/{AudioDevice(output_internal)}, + /*device_set_after=*/{AudioDevice(output_internal), + AudioDevice(output_USB)}), + /*bucket_count=*/1); + histogram_tester().ExpectBucketCount( + AudioDeviceMetricsHandler:: + kSystemSwitchOutputBeforeAndAfterAudioDeviceSetNonChromeRestarts, + EncodeBeforeAndAfterAudioDeviceSets( + /*device_set_before=*/{AudioDevice(output_internal)}, + /*device_set_after=*/{AudioDevice(output_internal), + AudioDevice(output_USB)}), + /*bucket_count=*/1); + // User switches input device immediately. // Expect to record user overrides system decision of switching input // device. @@ -422,6 +439,17 @@ AudioDevice(input_bluetooth_nb)}), /*bucket_count=*/1); + histogram_tester().ExpectBucketCount( + AudioDeviceMetricsHandler:: + kSystemNotSwitchInputBeforeAndAfterAudioDeviceSetNonChromeRestarts, + EncodeBeforeAndAfterAudioDeviceSets( + /*device_set_before=*/{AudioDevice(output_internal), + AudioDevice(output_USB)}, + /*device_set_after=*/{AudioDevice(output_internal), + AudioDevice(output_USB), + AudioDevice(input_bluetooth_nb)}), + /*bucket_count=*/1); + // User switches to USB input after some time. // Expect to record user overrides system decision of not switching input // device. @@ -480,6 +508,17 @@ AudioDevice(input_bluetooth_nb)}), /*bucket_count=*/1); + histogram_tester().ExpectBucketCount( + AudioDeviceMetricsHandler:: + kSystemSwitchInputBeforeAndAfterAudioDeviceSetNonChromeRestarts, + EncodeBeforeAndAfterAudioDeviceSets( + /*device_set_before=*/{AudioDevice(input_internal), + AudioDevice(input_bluetooth_nb), + AudioDevice(input_USB)}, + /*device_set_after=*/{AudioDevice(input_internal), + AudioDevice(input_bluetooth_nb)}), + /*bucket_count=*/1); + // User switches to input_bluetooth_nb after some time. // Expect to record user overrides system decision of switching input device. FastForwardBy(base::Minutes(kTimeDeltaInMinuteC)); @@ -584,6 +623,23 @@ /*device_set_after=*/{AudioDevice(input_internal), AudioDevice(input_USB)}), /*bucket_count=*/1); + + histogram_tester().ExpectBucketCount( + AudioDeviceMetricsHandler:: + kSystemSwitchInputBeforeAndAfterAudioDeviceSetChromeRestarts, + EncodeBeforeAndAfterAudioDeviceSets( + /*device_set_before=*/{}, + /*device_set_after=*/{AudioDevice(input_internal), + AudioDevice(input_USB)}), + /*bucket_count=*/1); + histogram_tester().ExpectBucketCount( + AudioDeviceMetricsHandler:: + kSystemSwitchOutputBeforeAndAfterAudioDeviceSetChromeRestarts, + EncodeBeforeAndAfterAudioDeviceSets( + /*device_set_before=*/{}, + /*device_set_after=*/{AudioDevice(input_internal), + AudioDevice(input_USB)}), + /*bucket_count=*/1); } TEST_F(AudioDeviceSelectionTest, DevicePrefEviction) {
diff --git a/chromeos/ash/components/audio/cras_audio_handler.cc b/chromeos/ash/components/audio/cras_audio_handler.cc index 84a0d4fa..b18c740 100644 --- a/chromeos/ash/components/audio/cras_audio_handler.cc +++ b/chromeos/ash/components/audio/cras_audio_handler.cc
@@ -1236,6 +1236,7 @@ audio_device_metrics_handler_ .RecordAudioSelectionMetricsSeparatedByChromeRestarts( /*is_input=*/true, is_switched, is_chrome_restarts_, + /*previous_device_list=*/previous_input_devices, /*current_device_list=*/input_devices); // Set up timestamp. Make sure setting one timestamp will reset the other, @@ -1280,6 +1281,7 @@ audio_device_metrics_handler_ .RecordAudioSelectionMetricsSeparatedByChromeRestarts( /*is_input=*/false, is_switched, is_chrome_restarts_, + /*previous_device_list=*/previous_output_devices, /*current_device_list=*/output_devices); // Set up timestamp. Make sure setting one timestamp will reset the other,
diff --git a/chromeos/ash/components/dbus/userdataauth/fake_userdataauth_client.cc b/chromeos/ash/components/dbus/userdataauth/fake_userdataauth_client.cc index a573cd31..fc7ebfa0 100644 --- a/chromeos/ash/components/dbus/userdataauth/fake_userdataauth_client.cc +++ b/chromeos/ash/components/dbus/userdataauth/fake_userdataauth_client.cc
@@ -1567,18 +1567,8 @@ CryptohomeErrorCode::CRYPTOHOME_INVALID_AUTH_SESSION_TOKEN)); return; } - if (!auth_session->second.authenticated) { - reply.set_status( - ::user_data_auth::AUTH_SESSION_STATUS_FURTHER_FACTOR_REQUIRED); - return; - } + base::TimeDelta time_left = auth_session->second.lifetime - base::Time::Now(); - if (time_left.is_negative()) { - reply.set_status( - ::user_data_auth::AUTH_SESSION_STATUS_INVALID_AUTH_SESSION); - return; - } - reply.set_status(::user_data_auth::AUTH_SESSION_STATUS_AUTHENTICATED); reply.mutable_auth_properties()->add_authorized_for( auth_session->second.requested_auth_session_intent); reply.mutable_auth_properties()->set_seconds_left(time_left.InSeconds());
diff --git a/chromeos/ash/components/growth/campaigns_manager.cc b/chromeos/ash/components/growth/campaigns_manager.cc index dab38ba6..5f2b792 100644 --- a/chromeos/ash/components/growth/campaigns_manager.cc +++ b/chromeos/ash/components/growth/campaigns_manager.cc
@@ -129,6 +129,10 @@ return match_result; } +void CampaignsManager::SetOpenedApp(const std::string& app_id) { + matcher_.SetOpenedApp(app_id); +} + void CampaignsManager::OnCampaignsComponentLoaded( base::OnceClosure load_callback, bool in_oobe,
diff --git a/chromeos/ash/components/growth/campaigns_manager.h b/chromeos/ash/components/growth/campaigns_manager.h index 39fad80..1f8c189d 100644 --- a/chromeos/ash/components/growth/campaigns_manager.h +++ b/chromeos/ash/components/growth/campaigns_manager.h
@@ -59,6 +59,10 @@ // TODO(b/308684443): Rename this to `GetCampaignBySlotAndRegisterTrial`. const Campaign* GetCampaignBySlot(Slot slot) const; + // Set the current opened app. Used in `CampaignsMatcher` for matching + // opened app targeting. + void SetOpenedApp(const std::string& app_id); + ActionMap& actions_map() { return actions_map_; } private:
diff --git a/chromeos/ash/components/growth/campaigns_manager_unittest.cc b/chromeos/ash/components/growth/campaigns_manager_unittest.cc index 32ab80ca..d871788 100644 --- a/chromeos/ash/components/growth/campaigns_manager_unittest.cc +++ b/chromeos/ash/components/growth/campaigns_manager_unittest.cc
@@ -266,6 +266,17 @@ kValidCampaignsFileTemplate, session_targeting.c_str())); } + void LoadComponentWithAppsOpenedTargeting(const std::string& apps_opened) { + auto session_targeting = base::StringPrintf(R"( + "session": { + "appsOpened": %s + } + )", + apps_opened.c_str()); + LoadComponentAndVerifyLoadComplete(base::StringPrintf( + kValidCampaignsFileTemplate, session_targeting.c_str())); + } + base::test::TaskEnvironment task_environment_; MockCampaignsManagerClient mock_client_; base::ScopedTempDir temp_dir_; @@ -1098,4 +1109,56 @@ /*count=*/1); } +TEST_F(CampaignsManagerTest, GetCampaignAppsOpened) { + campaigns_manager_->SetOpenedApp("app_id_1"); + + LoadComponentWithAppsOpenedTargeting( + R"([ + {"appId": "app_id_1"}, + {"appId": "app_id_10"}, + {"appId": "app_id_15"} + ])"); + + VerifyDemoModePayload( + campaigns_manager_->GetCampaignBySlot(Slot::kDemoModeApp)); +} + +TEST_F(CampaignsManagerTest, GetCampaignAppsOpenedOrRelationship) { + campaigns_manager_->SetOpenedApp("app_id_10"); + + LoadComponentWithAppsOpenedTargeting( + R"([ + {"appId": "app_id_1"}, + {"appId": "app_id_10"}, + {"appId": "app_id_15"} + ])"); + + VerifyDemoModePayload( + campaigns_manager_->GetCampaignBySlot(Slot::kDemoModeApp)); +} + +TEST_F(CampaignsManagerTest, GetCampaignAppOpenedMismatch) { + campaigns_manager_->SetOpenedApp("app_id_2"); + + LoadComponentWithAppsOpenedTargeting( + R"([ + {"appId": "app_id_1"}, + {"appId": "app_id_10"}, + {"appId": "app_id_15"} + ])"); + + ASSERT_EQ(nullptr, campaigns_manager_->GetCampaignBySlot(Slot::kDemoModeApp)); +} + +TEST_F(CampaignsManagerTest, GetCampaignAppOpenedNoOpenedApp) { + LoadComponentWithAppsOpenedTargeting( + R"([ + {"appId": "app_id_1"}, + {"appId": "app_id_10"}, + {"appId": "app_id_15"} + ])"); + + ASSERT_EQ(nullptr, campaigns_manager_->GetCampaignBySlot(Slot::kDemoModeApp)); +} + } // namespace growth
diff --git a/chromeos/ash/components/growth/campaigns_matcher.cc b/chromeos/ash/components/growth/campaigns_matcher.cc index fcc17a3..ea9a7ae 100644 --- a/chromeos/ash/components/growth/campaigns_matcher.cc +++ b/chromeos/ash/components/growth/campaigns_matcher.cc
@@ -21,6 +21,7 @@ namespace growth { namespace { + inline constexpr char kCampaignsExperimentTag[] = "exp_tag"; bool MatchPref(const base::Value::List* criterias, @@ -96,16 +97,6 @@ return base::Contains(*experiment_tags, exp_tag); } -bool MatchSessionTargeting(const SessionTargeting& targeting) { - if (!targeting.IsValid()) { - // Campaigns matched if there is no demo mode targeting. - return true; - } - - return MatchSchedulings(targeting.GetSchedulings()) && - MatchExperimentTags(targeting.GetExperimentTags()); -} - } // namespace CampaignsMatcher::CampaignsMatcher(CampaignsManagerClient* client, @@ -117,6 +108,10 @@ campaigns_ = campaigns; } +void CampaignsMatcher::SetOpenedApp(const std::string& app_id) { + opened_app_id_ = app_id; +} + void CampaignsMatcher::SetPrefs(PrefService* prefs) { prefs_ = prefs; } @@ -274,6 +269,40 @@ return MatchMilestone(targeting); } +bool CampaignsMatcher::MatchOpenedApp( + std::vector<std::unique_ptr<AppTargeting>> apps_opened_targeting) const { + if (apps_opened_targeting.empty()) { + // Campaigns matched if apps opened targeting is empty. + return true; + } + + for (const auto& app : apps_opened_targeting) { + auto* app_id = app->GetAppId(); + + if (!app_id) { + // Ignore if app id is missing from the targeting. + continue; + } + + if (*app_id == opened_app_id_) { + return true; + } + } + return false; +} + +bool CampaignsMatcher::MatchSessionTargeting( + const SessionTargeting& targeting) const { + if (!targeting.IsValid()) { + // Campaigns matched if there is no demo mode targeting. + return true; + } + + return MatchSchedulings(targeting.GetSchedulings()) && + MatchExperimentTags(targeting.GetExperimentTags()) && + MatchOpenedApp(targeting.GetAppsOpened()); +} + bool CampaignsMatcher::Matched(const Targetings* targetings) const { // TODO(b/299305911): Add metrics to track matching latency. if (!targetings || targetings->empty()) {
diff --git a/chromeos/ash/components/growth/campaigns_matcher.h b/chromeos/ash/components/growth/campaigns_matcher.h index 9bebcd3..2fb09f75 100644 --- a/chromeos/ash/components/growth/campaigns_matcher.h +++ b/chromeos/ash/components/growth/campaigns_matcher.h
@@ -25,6 +25,8 @@ void SetCampaigns(const CampaignsPerSlot* campaigns); + void SetOpenedApp(const std::string& app_id); + // Select the targeted campaign for the given `slot`. Returns nullptr if no // campaign found for the given `slot`. const Campaign* GetCampaignBySlot(Slot slot) const; @@ -37,6 +39,9 @@ bool MatchMilestone(const DeviceTargeting& targeting) const; bool MatchDeviceTargeting(const DeviceTargeting& targeting) const; bool MatchExperimentTagTargeting(const base::Value::List* targeting) const; + bool MatchOpenedApp( + std::vector<std::unique_ptr<AppTargeting>> apps_opened_targeting) const; + bool MatchSessionTargeting(const SessionTargeting& targeting) const; bool Matched(const Targetings* targetings) const; // Owned by CampaignsManager. @@ -44,6 +49,7 @@ raw_ptr<CampaignsManagerClient> client_ = nullptr; raw_ptr<PrefService> local_state_ = nullptr; raw_ptr<PrefService> prefs_ = nullptr; + std::string opened_app_id_; }; } // namespace growth
diff --git a/chromeos/ash/components/growth/campaigns_model.cc b/chromeos/ash/components/growth/campaigns_model.cc index a05245a4..dde43e7c 100644 --- a/chromeos/ash/components/growth/campaigns_model.cc +++ b/chromeos/ash/components/growth/campaigns_model.cc
@@ -47,6 +47,10 @@ inline constexpr char kSchedulingStart[] = "start"; inline constexpr char kSchedulingEnd[] = "end"; +// Opened App Targeting paths. +inline constexpr char kAppsOpenedTargetings[] = "appsOpened"; +inline constexpr char kAppId[] = "appId"; + // Experiment Tag Targeting paths. inline constexpr char kExperimentTargetings[] = "experimentTags"; @@ -179,6 +183,16 @@ return GetBoolCriteria(kFeatureAware); } +// Apps Targeting. +AppTargeting::AppTargeting(const base::Value::Dict* app_dict) + : app_dict_(app_dict) {} + +AppTargeting::~AppTargeting() = default; + +const std::string* AppTargeting::GetAppId() const { + return app_dict_->FindString(kAppId); +} + // Scheduling Targeting. SchedulingTargeting::SchedulingTargeting( const base::Value::Dict* scheduling_dict) @@ -239,4 +253,25 @@ return GetListCriteria(kExperimentTargetings); } +const std::vector<std::unique_ptr<AppTargeting>> +SessionTargeting::GetAppsOpened() const { + std::vector<std::unique_ptr<AppTargeting>> app_targetings; + + auto* app_targeting_dicts = GetListCriteria(kAppsOpenedTargetings); + if (!app_targeting_dicts) { + return app_targetings; + } + + for (auto& app_targeting_dict : *app_targeting_dicts) { + if (!app_targeting_dict.is_dict()) { + // TODO(b/329124927): Record error. + continue; + } + app_targetings.push_back( + std::make_unique<AppTargeting>(&app_targeting_dict.GetDict())); + } + + return app_targetings; +} + } // namespace growth
diff --git a/chromeos/ash/components/growth/campaigns_model.h b/chromeos/ash/components/growth/campaigns_model.h index 12467917..22c4b387 100644 --- a/chromeos/ash/components/growth/campaigns_model.h +++ b/chromeos/ash/components/growth/campaigns_model.h
@@ -99,8 +99,7 @@ class TargetingBase { public: - explicit TargetingBase(const Targeting* targeting_dict, - const char* targeting_path); + TargetingBase(const Targeting* targeting_dict, const char* targeting_path); TargetingBase(const TargetingBase&) = delete; TargetingBase& operator=(const TargetingBase) = delete; ~TargetingBase(); @@ -184,7 +183,7 @@ // Start and end are the number of seconds since epoch in UTC. class SchedulingTargeting { public: - explicit SchedulingTargeting(const base::Value::Dict* scheduling); + explicit SchedulingTargeting(const base::Value::Dict* scheduling_dict); SchedulingTargeting(const SchedulingTargeting&) = delete; SchedulingTargeting& operator=(const SchedulingTargeting) = delete; ~SchedulingTargeting(); @@ -196,6 +195,25 @@ raw_ptr<const base::Value::Dict> scheduling_dict_; }; +// Wrapper around app targeting dictionary. +// +// The structure looks like: +// { +// "appId": "app_id", +// } +class AppTargeting { + public: + explicit AppTargeting(const base::Value::Dict* app); + AppTargeting(const AppTargeting&) = delete; + AppTargeting& operator=(const AppTargeting) = delete; + ~AppTargeting(); + + const std::string* GetAppId() const; + + private: + raw_ptr<const base::Value::Dict> app_dict_; +}; + // Wrapper around scheduling targeting dictionary. // // The structure looks like: @@ -212,6 +230,8 @@ const std::vector<std::unique_ptr<SchedulingTargeting>> GetSchedulings() const; const base::Value::List* GetExperimentTags() const; + // Returns a list of apps to be matched against the current opened app. + const std::vector<std::unique_ptr<AppTargeting>> GetAppsOpened() const; }; } // namespace growth
diff --git a/chromeos/ash/components/login/auth/auth_performer.cc b/chromeos/ash/components/login/auth/auth_performer.cc index bf99b0f..76ddfea 100644 --- a/chromeos/ash/components/login/auth/auth_performer.cc +++ b/chromeos/ash/components/login/auth/auth_performer.cc
@@ -639,44 +639,20 @@ if (cryptohome::ErrorMatches( error, user_data_auth::CRYPTOHOME_INVALID_AUTH_SESSION_TOKEN)) { // Do not trigger error handling - std::move(callback).Run(AuthSessionStatus(), base::TimeDelta(), - std::move(context), + std::move(callback).Run(std::move(context), /*cryptohome_error=*/std::nullopt); return; } if (cryptohome::HasError(error)) { LOGIN_LOG(EVENT) << "Failed to get authsession status " << error; - std::move(callback).Run(AuthSessionStatus(), base::TimeDelta(), - std::move(context), AuthenticationError{error}); + std::move(callback).Run(std::move(context), AuthenticationError{error}); return; } CHECK(reply.has_value()); CHECK(reply->has_auth_properties()); - // TODO(b/301078137): As lifetime is now stored in UserContext, - // there is no need to pass it separately. - base::TimeDelta lifetime; - AuthSessionStatus status; - switch (reply->status()) { - case ::user_data_auth::AUTH_SESSION_STATUS_NOT_SET: - case ::user_data_auth::AUTH_SESSION_STATUS_INVALID_AUTH_SESSION: - break; - case ::user_data_auth::AUTH_SESSION_STATUS_FURTHER_FACTOR_REQUIRED: - status.Put(AuthSessionLevel::kSessionIsValid); - // Once we support multi-factor authentication (and have partially - // authenticated sessions) we might need to use value from reply. - lifetime = base::TimeDelta::Max(); - break; - case ::user_data_auth::AUTH_SESSION_STATUS_AUTHENTICATED: - status.Put(AuthSessionLevel::kSessionIsValid); - status.Put(AuthSessionLevel::kCryptohomeStrong); - lifetime = base::Seconds(reply->auth_properties().seconds_left()); - break; - default: - NOTREACHED(); - } FillAuthenticationData(request_start, reply->auth_properties(), *context); - std::move(callback).Run(status, lifetime, std::move(context), + std::move(callback).Run(std::move(context), /*cryptohome_error=*/std::nullopt); }
diff --git a/chromeos/ash/components/login/auth/auth_performer.h b/chromeos/ash/components/login/auth/auth_performer.h index e996074..e13e9263 100644 --- a/chromeos/ash/components/login/auth/auth_performer.h +++ b/chromeos/ash/components/login/auth/auth_performer.h
@@ -46,9 +46,7 @@ std::optional<AuthenticationError>)>; using AuthSessionStatusCallback = - base::OnceCallback<void(AuthSessionStatus status, - base::TimeDelta lifetime, - std::unique_ptr<UserContext>, + base::OnceCallback<void(std::unique_ptr<UserContext>, std::optional<AuthenticationError>)>; using RecoveryRequestCallback = base::OnceCallback<void(std::optional<RecoveryRequest>,
diff --git a/chromeos/ash/components/network/onc/onc_translation_tables.cc b/chromeos/ash/components/network/onc/onc_translation_tables.cc index f3af660..a8f88f9 100644 --- a/chromeos/ash/components/network/onc/onc_translation_tables.cc +++ b/chromeos/ash/components/network/onc/onc_translation_tables.cc
@@ -21,6 +21,9 @@ namespace { +const char kShillApnSourceModem[] = "modem"; +const char kShillApnSourceModb[] = "modb"; + const FieldTranslationEntry eap_fields[] = { {::onc::eap::kAnonymousIdentity, shill::kEapAnonymousIdentityProperty}, // This field is converted during translation, see onc_translator_*. @@ -465,7 +468,12 @@ {::onc::cellular_apn::kIpTypeIpv4Ipv6, shill::kApnIpTypeV4V6}, {nullptr}}; -// TODO(b/328437440) Change temp properties to shill dbus constants. +const StringTranslationEntry kApnSourceTranslationTable[] = { + {::onc::cellular_apn::kSourceModem, kShillApnSourceModem}, + {::onc::cellular_apn::kSourceModb, kShillApnSourceModb}, + {::onc::cellular_apn::kSourceUi, shill::kApnSourceUi}, + {nullptr}}; + const StringTranslationEntry kCheckCaptivePortalTranslationTable[] = { {::onc::check_captive_portal::kFalse, "false"}, {::onc::check_captive_portal::kHTTPOnly, "http-only"},
diff --git a/chromeos/ash/components/network/onc/onc_translation_tables.h b/chromeos/ash/components/network/onc/onc_translation_tables.h index 5cff268..a64a4fb 100644 --- a/chromeos/ash/components/network/onc/onc_translation_tables.h +++ b/chromeos/ash/components/network/onc/onc_translation_tables.h
@@ -49,6 +49,8 @@ COMPONENT_EXPORT(CHROMEOS_NETWORK) extern const StringTranslationEntry kApnIpTypeTranslationTable[]; COMPONENT_EXPORT(CHROMEOS_NETWORK) +extern const StringTranslationEntry kApnSourceTranslationTable[]; +COMPONENT_EXPORT(CHROMEOS_NETWORK) extern const StringTranslationEntry kCheckCaptivePortalTranslationTable[]; // A separate translation table for cellular properties that are stored in a
diff --git a/chromeos/ash/components/network/onc/onc_translator_shill_to_onc.cc b/chromeos/ash/components/network/onc/onc_translator_shill_to_onc.cc index b5cf827e..018fa6a 100644 --- a/chromeos/ash/components/network/onc/onc_translator_shill_to_onc.cc +++ b/chromeos/ash/components/network/onc/onc_translator_shill_to_onc.cc
@@ -616,6 +616,10 @@ kApnIpTypeTranslationTable, ::onc::cellular_apn::kIpType); + TranslateWithTableAndSet(shill::kApnSourceProperty, + kApnSourceTranslationTable, + ::onc::cellular_apn::kSource); + const std::string shill_apn_types = FindStringKeyOrEmpty(*shill_dictionary_, shill::kApnTypesProperty);
diff --git a/chromeos/ash/services/network_config/cros_network_config.cc b/chromeos/ash/services/network_config/cros_network_config.cc index 9c22835..6e1af64 100644 --- a/chromeos/ash/services/network_config/cros_network_config.cc +++ b/chromeos/ash/services/network_config/cros_network_config.cc
@@ -1104,6 +1104,20 @@ return ::onc::cellular_apn::kIpTypeAutomatic; } +std::string MojoApnSourceToOnc(mojom::ApnSource source) { + DCHECK(features::IsApnRevampEnabled()); + switch (source) { + case mojom::ApnSource::kModem: + return ::onc::cellular_apn::kSourceModem; + case mojom::ApnSource::kModb: + return ::onc::cellular_apn::kSourceModb; + case mojom::ApnSource::kUi: + return ::onc::cellular_apn::kSourceUi; + } + NOTREACHED() << "Unexpected mojo ApnSource: " << source; + return ::onc::cellular_apn::kSourceModem; +} + std::vector<std::string> MojoApnTypesToOnc( const std::vector<mojom::ApnType>& apn_types) { DCHECK(features::IsApnRevampEnabled()); @@ -1927,6 +1941,7 @@ MojoApnStateTypeToOnc(apn_props.state)); apn.Set(::onc::cellular_apn::kIpType, MojoApnIpTypeToOnc(apn_props.ip_type)); + apn.Set(::onc::cellular_apn::kSource, MojoApnSourceToOnc(apn_props.source)); base::Value::List apn_types; for (const std::string& apn_type : MojoApnTypesToOnc(apn_props.apn_types)) apn_types.Append(apn_type);
diff --git a/chromeos/ash/services/network_config/cros_network_config_unittest.cc b/chromeos/ash/services/network_config/cros_network_config_unittest.cc index d46a43b..f35e34b 100644 --- a/chromeos/ash/services/network_config/cros_network_config_unittest.cc +++ b/chromeos/ash/services/network_config/cros_network_config_unittest.cc
@@ -215,6 +215,7 @@ test_apn_data.id = kCellularTestApnId1; test_apn_data.onc_authentication = kCellularTestApnAuthenticationType1; test_apn_data.onc_ip_type = ::onc::cellular_apn::kIpTypeIpv4; + test_apn_data.onc_source = ::onc::cellular_apn::kSourceModb; test_apn_data.onc_apn_types.emplace_back(kCellularTestApnTypes1); return test_apn_data.AsApnShillDict(); } @@ -2883,6 +2884,8 @@ test_apn1.attach = kCellularTestApnAttach1; test_apn1.mojo_ip_type = mojom::ApnIpType::kIpv4; test_apn1.onc_ip_type = ::onc::cellular_apn::kIpTypeIpv4; + test_apn1.mojo_source = mojom::ApnSource::kUi; + test_apn1.onc_source = ::onc::cellular_apn::kSourceUi; test_apn1.mojo_authentication = mojom::ApnAuthenticationType::kPap; test_apn1.onc_authentication = ::onc::cellular_apn::kAuthenticationPap; test_apn1.mojo_apn_types = {mojom::ApnType::kDefault, @@ -2917,6 +2920,8 @@ test_apn2.attach = kCellularTestApnAttach2; test_apn2.mojo_ip_type = mojom::ApnIpType::kIpv4Ipv6; test_apn2.onc_ip_type = ::onc::cellular_apn::kIpTypeIpv4Ipv6; + test_apn2.onc_source = ::onc::cellular_apn::kSourceUi; + test_apn2.mojo_source = mojom::ApnSource::kUi; test_apn2.mojo_authentication = mojom::ApnAuthenticationType::kChap; test_apn2.onc_authentication = ::onc::cellular_apn::kAuthenticationChap; test_apn2.mojo_apn_types = {mojom::ApnType::kDefault,
diff --git a/chromeos/ash/services/network_config/test_apn_data.cc b/chromeos/ash/services/network_config/test_apn_data.cc index 5c29e2b9..4d24fe9 100644 --- a/chromeos/ash/services/network_config/test_apn_data.cc +++ b/chromeos/ash/services/network_config/test_apn_data.cc
@@ -38,7 +38,9 @@ mojo_authentication(mojom::ApnAuthenticationType::kAutomatic), onc_authentication(::onc::cellular_apn::kAuthenticationAutomatic), mojo_ip_type(mojom::ApnIpType::kAutomatic), - onc_ip_type(::onc::cellular_apn::kIpTypeAutomatic) {} + onc_ip_type(::onc::cellular_apn::kIpTypeAutomatic), + mojo_source(mojom::ApnSource::kUi), + onc_source(::onc::cellular_apn::kSourceUi) {} TestApnData::TestApnData(std::string access_point_name, std::string name, @@ -52,6 +54,8 @@ std::string onc_authentication, mojom::ApnIpType mojo_ip_type, std::string onc_ip_type, + mojom::ApnSource mojo_source, + std::string onc_source, const std::vector<mojom::ApnType>& mojo_apn_types, const std::vector<std::string>& onc_apn_types) : access_point_name(access_point_name), @@ -66,6 +70,8 @@ onc_authentication(onc_authentication), mojo_ip_type(mojo_ip_type), onc_ip_type(onc_ip_type), + mojo_source(mojo_source), + onc_source(onc_source), mojo_apn_types(mojo_apn_types), onc_apn_types(onc_apn_types) {} @@ -84,6 +90,7 @@ apn->ip_type = mojo_ip_type; apn->apn_types = mojo_apn_types; apn->state = mojo_state; + apn->source = mojo_source; } return apn; } @@ -100,6 +107,7 @@ apn.Set(::onc::cellular_apn::kId, id); apn.Set(::onc::cellular_apn::kState, onc_state); apn.Set(::onc::cellular_apn::kIpType, onc_ip_type); + apn.Set(::onc::cellular_apn::kSource, onc_source); base::Value::List apn_types; for (const std::string& apn_type : onc_apn_types) @@ -172,6 +180,7 @@ if (features::IsApnRevampEnabled()) { ret &= mojo_ip_type == apn.ip_type; ret &= mojo_apn_types == apn.apn_types; + ret &= mojo_source == apn.source; } return ret; } @@ -206,6 +215,13 @@ ret &= IsPropertyEquals(onc_apn, ::onc::cellular_apn::kIpType, onc_ip_type); + const std::string* source = + onc_apn.FindString(::onc::cellular_apn::kSource); + if (source) { + ret &= + IsPropertyEquals(onc_apn, ::onc::cellular_apn::kSource, onc_source); + } + if (const base::Value::List* apn_types = onc_apn.FindList(::onc::cellular_apn::kApnTypes)) { if (onc_apn_types.size() != apn_types->size())
diff --git a/chromeos/ash/services/network_config/test_apn_data.h b/chromeos/ash/services/network_config/test_apn_data.h index 28a1a29c..9d5a60c 100644 --- a/chromeos/ash/services/network_config/test_apn_data.h +++ b/chromeos/ash/services/network_config/test_apn_data.h
@@ -35,6 +35,8 @@ std::string onc_authentication, chromeos::network_config::mojom::ApnIpType mojo_ip_type, std::string onc_ip_type, + chromeos::network_config::mojom::ApnSource mojo_source, + std::string onc_source, const std::vector<chromeos::network_config::mojom::ApnType>& mojo_apn_types, const std::vector<std::string>& onc_apn_types); @@ -57,6 +59,9 @@ chromeos::network_config::mojom::ApnIpType mojo_ip_type; std::string onc_ip_type; + chromeos::network_config::mojom::ApnSource mojo_source; + std::string onc_source; + std::vector<chromeos::network_config::mojom::ApnType> mojo_apn_types; std::vector<std::string> onc_apn_types;
diff --git a/chromeos/chromeos_strings.grd b/chromeos/chromeos_strings.grd index 0c772f5..7d92556 100644 --- a/chromeos/chromeos_strings.grd +++ b/chromeos/chromeos_strings.grd
@@ -3180,8 +3180,8 @@ <message name="IDS_SEA_PEN_CREATING_HIGH_RES_IMAGE" desc="The message displayed when the high resolution image is being created."> Creating hi-res image… </message> - <message name="IDS_SEA_PEN_SHOW_MORE_OPTIONS" desc="The button which will load more chip options when clicked."> - Show more + <message name="IDS_SEA_PEN_EXPAND_OPTIONS_BUTTON" desc="The button which will load more chip options when clicked."> + +<ph name="NUM_HIDDEN_OPTIONS">$1<ex>10</ex></ph> more </message> <!-- Sea Pen Templates (AUTOGENERATED - contact assistive-eng@google.com before editing) -->
diff --git a/chromeos/chromeos_strings_grd/IDS_SEA_PEN_EXPAND_OPTIONS_BUTTON.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SEA_PEN_EXPAND_OPTIONS_BUTTON.png.sha1 new file mode 100644 index 0000000..a9405e7c --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_SEA_PEN_EXPAND_OPTIONS_BUTTON.png.sha1
@@ -0,0 +1 @@ +db576faf670c987a99a8be26971bee8c0fec62e5 \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_SEA_PEN_SHOW_MORE_OPTIONS.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SEA_PEN_SHOW_MORE_OPTIONS.png.sha1 deleted file mode 100644 index eb3e13b..0000000 --- a/chromeos/chromeos_strings_grd/IDS_SEA_PEN_SHOW_MORE_OPTIONS.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -fa0cc4c55d06c7f51a44f6b417c7c84969297961 \ No newline at end of file
diff --git a/chromeos/components/test/data/onc/shill_cellular_with_state_apn_revamp.json b/chromeos/components/test/data/onc/shill_cellular_with_state_apn_revamp.json index 41ce99e..64b47f6 100644 --- a/chromeos/components/test/data/onc/shill_cellular_with_state_apn_revamp.json +++ b/chromeos/components/test/data/onc/shill_cellular_with_state_apn_revamp.json
@@ -22,6 +22,7 @@ "apn": "test-apn", "apn_types": "DEFAULT", "name": "test-apn-name", + "apn_source": "modem", "username": "test-username", "password": "test-password" }, @@ -30,6 +31,7 @@ "apn_types": "IA", "authentication": "pap", "ip_type": "", + "apn_source": "modb", "name": "test-apn-name-2", "username": "test-username-2", "password": "test-password-2" @@ -39,6 +41,7 @@ "apn_types": "DEFAULT", "authentication": "chap", "ip_type": "ipv6", + "apn_source": "modem", "name": "test-apn-name-3", "username": "test-username-3", "password": "test-password-3" @@ -48,6 +51,7 @@ "apn_types": "DEFAULT,IA", "authentication": "pap", "ip_type": "ipv4v6", + "apn_source": "modb", "name": "test-apn-name-4", "username": "test-username-4", "password": "test-password-4" @@ -60,6 +64,7 @@ "apn": "test-apn0", "apn_types": "DUN", "ip_type": "ipv4", + "apn_source": "modem", "username": "test-username0", "password": "test-password0" },
diff --git a/chromeos/components/test/data/onc/translation_of_shill_cellular_with_state_apn_revamp.onc b/chromeos/components/test/data/onc/translation_of_shill_cellular_with_state_apn_revamp.onc index 67548a0..321d4b5 100644 --- a/chromeos/components/test/data/onc/translation_of_shill_cellular_with_state_apn_revamp.onc +++ b/chromeos/components/test/data/onc/translation_of_shill_cellular_with_state_apn_revamp.onc
@@ -27,6 +27,7 @@ "AccessPointName": "test-apn", "ApnTypes": ["Default"], "Name": "test-apn-name", + "Source": "Modem", "Username": "test-username", "Password": "test-password" }, @@ -34,6 +35,7 @@ "AccessPointName": "test-apn-2", "ApnTypes": ["Attach"], "Authentication": "PAP", + "Source": "Modb", "Name": "test-apn-name-2", "Username": "test-username-2", "Password": "test-password-2" @@ -43,6 +45,7 @@ "ApnTypes": ["Default"], "Authentication": "CHAP", "IpType": "IPv6", + "Source": "Modem", "Name": "test-apn-name-3", "Username": "test-username-3", "Password": "test-password-3" @@ -52,6 +55,7 @@ "ApnTypes": ["Default", "Attach"], "Authentication": "PAP", "IpType": "IPv4orIPv6", + "Source": "Modb", "Name": "test-apn-name-4", "Username": "test-username-4", "Password": "test-password-4" @@ -60,6 +64,7 @@ "AccessPointName": "test-apn0", "ApnTypes": ["Tether"], "IpType": "IPv4", + "Source": "Modem", "Password": "test-password0", "Username": "test-username0" }, {
diff --git a/chromeos/services/network_config/public/cpp/cros_network_config_util.cc b/chromeos/services/network_config/public/cpp/cros_network_config_util.cc index 62ffd4e..ab0224f 100644 --- a/chromeos/services/network_config/public/cpp/cros_network_config_util.cc +++ b/chromeos/services/network_config/public/cpp/cros_network_config_util.cc
@@ -94,6 +94,22 @@ return mojom::ApnIpType::kAutomatic; } +mojom::ApnSource OncApnSourceToMojo(const std::optional<std::string>& source) { + if (!source.has_value() || source->empty() || + source == ::onc::cellular_apn::kSourceModem) { + return mojom::ApnSource::kModem; + } + if (source == ::onc::cellular_apn::kSourceModb) { + return mojom::ApnSource::kModb; + } + if (source == ::onc::cellular_apn::kSourceUi) { + return mojom::ApnSource::kUi; + } + + NET_LOG(DEBUG) << "Unexpected APN source: " << source.value(); + return mojom::ApnSource::kModem; +} + } // namespace bool GetBoolean(const base::Value::Dict* dict, @@ -397,6 +413,8 @@ OncApnIpTypeToMojo(GetString(onc_apn, ::onc::cellular_apn::kIpType)); apn->apn_types = OncApnTypesToMojo( GetRequiredStringList(onc_apn, ::onc::cellular_apn::kApnTypes)); + apn->source = + OncApnSourceToMojo(GetString(onc_apn, ::onc::cellular_apn::kSource)); } return apn;
diff --git a/chromeos/services/network_config/public/mojom/cros_network_config.mojom b/chromeos/services/network_config/public/mojom/cros_network_config.mojom index f95b4bc..ebf0259 100644 --- a/chromeos/services/network_config/public/mojom/cros_network_config.mojom +++ b/chromeos/services/network_config/public/mojom/cros_network_config.mojom
@@ -397,6 +397,13 @@ kTether, }; +// Sources for APNs. +enum ApnSource { + kModem, + kModb, + kUi, +}; + struct ApnProperties { string access_point_name; // This id will only be set for custom APNs. @@ -420,6 +427,7 @@ ApnState state; ApnIpType ip_type; array<ApnType> apn_types; + ApnSource source; }; struct RoamingProperties {
diff --git a/clank b/clank index 03d4b8c..2ab9ac8 160000 --- a/clank +++ b/clank
@@ -1 +1 @@ -Subproject commit 03d4b8cf7dd1a2d763b7d53f7aa855954b861740 +Subproject commit 2ab9ac86f0c274f5df3781390b997f901bd4a958
diff --git a/components/attribution_reporting/event_trigger_data.cc b/components/attribution_reporting/event_trigger_data.cc index fe4270e..1ad1a9a 100644 --- a/components/attribution_reporting/event_trigger_data.cc +++ b/components/attribution_reporting/event_trigger_data.cc
@@ -8,6 +8,7 @@ #include <utility> +#include "base/check_op.h" #include "base/types/expected.h" #include "base/types/expected_macros.h" #include "base/values.h" @@ -22,6 +23,7 @@ using ::attribution_reporting::mojom::TriggerRegistrationError; constexpr char kTriggerData[] = "trigger_data"; +constexpr char kValue[] = "value"; } // namespace @@ -79,4 +81,31 @@ return dict; } +// static +base::expected<EventTriggerValue, mojom::TriggerRegistrationError> +EventTriggerValue::Parse(const base::Value::Dict& dict) { + const base::Value* v = dict.Find(kValue); + if (!v) { + return EventTriggerValue(); + } + + ASSIGN_OR_RETURN(uint32_t value, ParseUint32(*v), [](ParseError) { + return TriggerRegistrationError::kEventValueInvalid; + }); + + if (value == 0) { + return base::unexpected(TriggerRegistrationError::kEventValueInvalid); + } + + return EventTriggerValue(value); +} + +EventTriggerValue::EventTriggerValue(uint32_t value) : value_(value) { + CHECK_GT(value_, 0u); +} + +void EventTriggerValue::Serialize(base::Value::Dict& dict) const { + dict.Set(kValue, Uint32ToJson(value_)); +} + } // namespace attribution_reporting
diff --git a/components/attribution_reporting/event_trigger_data.h b/components/attribution_reporting/event_trigger_data.h index 1d427eb..968c766 100644 --- a/components/attribution_reporting/event_trigger_data.h +++ b/components/attribution_reporting/event_trigger_data.h
@@ -17,6 +17,34 @@ namespace attribution_reporting { +class COMPONENT_EXPORT(ATTRIBUTION_REPORTING) EventTriggerValue { + public: + static base::expected<EventTriggerValue, mojom::TriggerRegistrationError> + Parse(const base::Value::Dict&); + + EventTriggerValue() = default; + + // `CHECK()`s that the given value is non-zero. + explicit EventTriggerValue(uint32_t); + + EventTriggerValue(const EventTriggerValue&) = default; + EventTriggerValue& operator=(const EventTriggerValue&) = default; + + EventTriggerValue(EventTriggerValue&&) = default; + EventTriggerValue& operator=(EventTriggerValue&&) = default; + + // This implicit conversion is allowed to ease drop-in use of + // this type in places currently requiring `uint32_t` with prior validation. + operator uint32_t() const { // NOLINT + return value_; + } + + void Serialize(base::Value::Dict&) const; + + private: + uint32_t value_ = 1; +}; + struct COMPONENT_EXPORT(ATTRIBUTION_REPORTING) EventTriggerData { static base::expected<EventTriggerData, mojom::TriggerRegistrationError> FromJSON(base::Value& value); @@ -40,6 +68,8 @@ // are used. FilterPair filters; + // TODO(crbug.com/40287976): Add an `EventTriggerValue` field called `value`. + EventTriggerData(); EventTriggerData(uint64_t data,
diff --git a/components/attribution_reporting/event_trigger_data_unittest.cc b/components/attribution_reporting/event_trigger_data_unittest.cc index bd01171..23b8e33 100644 --- a/components/attribution_reporting/event_trigger_data_unittest.cc +++ b/components/attribution_reporting/event_trigger_data_unittest.cc
@@ -4,6 +4,10 @@ #include "components/attribution_reporting/event_trigger_data.h" +#include <stdint.h> + +#include <limits> + #include "base/test/gmock_expected_support.h" #include "base/test/values_test_util.h" #include "base/time/time.h" @@ -161,5 +165,77 @@ } } +TEST(EventTriggerValueTest, Constructor) { + EXPECT_EQ(EventTriggerValue(), 1u); + EXPECT_EQ(EventTriggerValue(5), 5u); + EXPECT_DEATH_IF_SUPPORTED(EventTriggerValue(0), ""); +} + +TEST(EventTriggerValueTest, Parse) { + const struct { + const char* description; + const char* json; + ::testing::Matcher< + base::expected<EventTriggerValue, TriggerRegistrationError>> + matches; + } kTestCases[] = { + { + "empty", + R"json({})json", + ValueIs(1), + }, + { + "wrong_type", + R"json({"value":null})json", + ErrorIs(TriggerRegistrationError::kEventValueInvalid), + }, + { + "zero", + R"json({"value":0})json", + ErrorIs(TriggerRegistrationError::kEventValueInvalid), + }, + { + "negative", + R"json({"value":-1})json", + ErrorIs(TriggerRegistrationError::kEventValueInvalid), + }, + { + "fractional", + R"json({"value":1.5})json", + ErrorIs(TriggerRegistrationError::kEventValueInvalid), + }, + { + "maximal", + R"json({"value":4294967295})json", + ValueIs(std::numeric_limits<uint32_t>::max()), + }, + { + "too_large", + R"json({"value":4294967296})json", + ErrorIs(TriggerRegistrationError::kEventValueInvalid), + }, + }; + + for (const auto& test_case : kTestCases) { + SCOPED_TRACE(test_case.description); + const base::Value::Dict dict = base::test::ParseJsonDict(test_case.json); + EXPECT_THAT(EventTriggerValue::Parse(dict), test_case.matches); + } +} + +TEST(EventTriggerValueTest, Serialize) { + { + base::Value::Dict dict; + EventTriggerValue(5).Serialize(dict); + EXPECT_THAT(dict, base::test::IsJson(R"json({"value": 5})json")); + } + + { + base::Value::Dict dict; + EventTriggerValue(std::numeric_limits<uint32_t>::max()).Serialize(dict); + EXPECT_THAT(dict, base::test::IsJson(R"json({"value": 4294967295})json")); + } +} + } // namespace } // namespace attribution_reporting
diff --git a/components/attribution_reporting/parsing_utils.cc b/components/attribution_reporting/parsing_utils.cc index 4106322..4b4ace12 100644 --- a/components/attribution_reporting/parsing_utils.cc +++ b/components/attribution_reporting/parsing_utils.cc
@@ -183,9 +183,7 @@ } } -base::expected<uint32_t, mojom::SourceRegistrationError> ParseUint32( - const base::Value& value, - const mojom::SourceRegistrationError error) { +base::expected<uint32_t, ParseError> ParseUint32(const base::Value& value) { // We use `base::Value::GetIfDouble()`, which coerces if the value is an // integer, because not all `uint32_t` can be represented by 32-bit `int`. // We use `std::modf` to check that the fractional part of the `double` is 0. @@ -200,7 +198,7 @@ if (double int_part; !double_value.has_value() || std::modf(*double_value, &int_part) != 0 || !base::IsValueInRangeForNumericType<uint32_t>(*double_value)) { - return base::unexpected(error); + return base::unexpected(ParseError()); } return static_cast<uint32_t>(*double_value);
diff --git a/components/attribution_reporting/parsing_utils.h b/components/attribution_reporting/parsing_utils.h index a32748e..63f7d42 100644 --- a/components/attribution_reporting/parsing_utils.h +++ b/components/attribution_reporting/parsing_utils.h
@@ -89,9 +89,7 @@ std::string_view key, base::TimeDelta value); -base::expected<uint32_t, mojom::SourceRegistrationError> ParseUint32( - const base::Value&, - mojom::SourceRegistrationError error); +base::expected<uint32_t, ParseError> ParseUint32(const base::Value&); base::Value Uint32ToJson(uint32_t);
diff --git a/components/attribution_reporting/summary_buckets.cc b/components/attribution_reporting/summary_buckets.cc index 2d8508c3..dc19c5c 100644 --- a/components/attribution_reporting/summary_buckets.cc +++ b/components/attribution_reporting/summary_buckets.cc
@@ -88,10 +88,9 @@ uint32_t prev = 0; for (const base::Value& item : *list) { - ASSIGN_OR_RETURN( - uint32_t start, - ParseUint32(item, - SourceRegistrationError::kSummaryBucketsValueInvalid)); + ASSIGN_OR_RETURN(uint32_t start, ParseUint32(item), [](ParseError) { + return SourceRegistrationError::kSummaryBucketsValueInvalid; + }); if (start <= prev) { return base::unexpected(
diff --git a/components/attribution_reporting/trigger_config.cc b/components/attribution_reporting/trigger_config.cc index 610e1420..daf47e4f 100644 --- a/components/attribution_reporting/trigger_config.cc +++ b/components/attribution_reporting/trigger_config.cc
@@ -75,11 +75,9 @@ trigger_data_indices.reserve(new_size); for (const base::Value& item : *list) { - ASSIGN_OR_RETURN( - uint32_t trigger_data, - ParseUint32( - item, - SourceRegistrationError::kTriggerSpecTriggerDataValueInvalid)); + ASSIGN_OR_RETURN(uint32_t trigger_data, ParseUint32(item), [](ParseError) { + return SourceRegistrationError::kTriggerSpecTriggerDataValueInvalid; + }); auto [_, inserted] = trigger_data_indices.try_emplace(trigger_data, spec_index);
diff --git a/components/attribution_reporting/trigger_registration.cc b/components/attribution_reporting/trigger_registration.cc index 09242704..4747313 100644 --- a/components/attribution_reporting/trigger_registration.cc +++ b/components/attribution_reporting/trigger_registration.cc
@@ -114,8 +114,7 @@ void RecordTriggerRegistrationError(TriggerRegistrationError error) { static_assert(TriggerRegistrationError::kMaxValue == - TriggerRegistrationError:: - kTriggerContextIdInvalidSourceRegistrationTimeConfig, + TriggerRegistrationError::kEventValueInvalid, "Update ConversionTriggerRegistrationError enum."); base::UmaHistogramEnumeration("Conversions.TriggerRegistrationError10", error);
diff --git a/components/attribution_reporting/trigger_registration_error.mojom b/components/attribution_reporting/trigger_registration_error.mojom index 52cb525..78e848a 100644 --- a/components/attribution_reporting/trigger_registration_error.mojom +++ b/components/attribution_reporting/trigger_registration_error.mojom
@@ -45,4 +45,6 @@ kTriggerContextIdInvalidValue = 27, kTriggerContextIdInvalidSourceRegistrationTimeConfig = 28, + + kEventValueInvalid = 29, };
diff --git a/components/autofill/content/renderer/password_autofill_agent.cc b/components/autofill/content/renderer/password_autofill_agent.cc index 62a01a7..4b736895 100644 --- a/components/autofill/content/renderer/password_autofill_agent.cc +++ b/components/autofill/content/renderer/password_autofill_agent.cc
@@ -808,6 +808,13 @@ static base::NoDestructor<WebString> kName("name"); std::u16string name_attribute = element.GetAttribute(*kName).Utf16(); std::u16string id_attribute = element.GetIdAttribute().Utf16(); + static base::NoDestructor<WebString> kLabel("label"); + std::u16string label_attribute = element.GetAttribute(*kLabel).Utf16(); + + if (!password_manager::util::CanBeConsideredAsSingleUsername( + name_attribute, id_attribute, label_attribute)) { + return; + } bool is_likely_otp = autofill::MatchesRegex<password_manager::constants::kOneTimePwdRe>(
diff --git a/components/autofill/core/browser/BUILD.gn b/components/autofill/core/browser/BUILD.gn index fa00bb1..2be06f9f 100644 --- a/components/autofill/core/browser/BUILD.gn +++ b/components/autofill/core/browser/BUILD.gn
@@ -299,8 +299,6 @@ "merchant_promo_code_manager.h", "metrics/address_data_cleaner_metrics.cc", "metrics/address_data_cleaner_metrics.h", - "metrics/address_rewriter_in_profile_subset_metrics.cc", - "metrics/address_rewriter_in_profile_subset_metrics.h", "metrics/autofill_metrics.cc", "metrics/autofill_metrics.h", "metrics/autofill_metrics_utils.cc", @@ -1137,7 +1135,6 @@ "logging/text_log_receiver_unittest.cc", "manual_testing_import_unittest.cc", "merchant_promo_code_manager_unittest.cc", - "metrics/address_rewriter_in_profile_subset_metrics_unittest.cc", "metrics/autofill_metrics_unittest.cc", "metrics/fallback_autocomplete_unrecognized_metrics_unittest.cc", "metrics/field_filling_stats_and_score_metrics_unittest.cc",
diff --git a/components/autofill/core/browser/autofill_external_delegate.cc b/components/autofill/core/browser/autofill_external_delegate.cc index c51a314..37196b7 100644 --- a/components/autofill/core/browser/autofill_external_delegate.cc +++ b/components/autofill/core/browser/autofill_external_delegate.cc
@@ -34,7 +34,6 @@ #include "components/autofill/core/browser/field_type_utils.h" #include "components/autofill/core/browser/field_types.h" #include "components/autofill/core/browser/filling_product.h" -#include "components/autofill/core/browser/metrics/address_rewriter_in_profile_subset_metrics.h" #include "components/autofill/core/browser/metrics/autofill_metrics.h" #include "components/autofill/core/browser/metrics/granular_filling_metrics.h" #include "components/autofill/core/browser/metrics/log_event.h" @@ -536,8 +535,7 @@ break; case PopupItemId::kFillFullAddress: autofill_metrics::LogFillingMethodUsed( - autofill_metrics::AutofillFillingMethodMetric::kGroupFillingAddress, - FillingProduct::kAddress, + FillingMethod::kGroupFillingAddress, FillingProduct::kAddress, /*triggering_field_type_matches_filling_product=*/true); FillAutofillFormData( suggestion.popup_item_id, @@ -548,8 +546,7 @@ break; case PopupItemId::kFillFullName: autofill_metrics::LogFillingMethodUsed( - autofill_metrics::AutofillFillingMethodMetric::kGroupFillingName, - FillingProduct::kAddress, + FillingMethod::kGroupFillingName, FillingProduct::kAddress, /*triggering_field_type_matches_filling_product=*/true); FillAutofillFormData( suggestion.popup_item_id, @@ -560,9 +557,7 @@ break; case PopupItemId::kFillFullPhoneNumber: autofill_metrics::LogFillingMethodUsed( - autofill_metrics::AutofillFillingMethodMetric:: - kGroupFillingPhoneNumber, - FillingProduct::kAddress, + FillingMethod::kGroupFillingPhoneNumber, FillingProduct::kAddress, /*triggering_field_type_matches_filling_product=*/true); FillAutofillFormData( suggestion.popup_item_id, @@ -574,8 +569,7 @@ break; case PopupItemId::kFillFullEmail: autofill_metrics::LogFillingMethodUsed( - autofill_metrics::AutofillFillingMethodMetric::kGroupFillingEmail, - FillingProduct::kAddress, + FillingMethod::kGroupFillingEmail, FillingProduct::kAddress, /*triggering_field_type_matches_filling_product=*/true); FillAutofillFormData( suggestion.popup_item_id, @@ -706,11 +700,8 @@ GetFillingProductFromPopupItemId(PopupItemId::kAddressEntry), manager_->client().IsOffTheRecord()); autofill_metrics::LogFillingMethodUsed( - autofill_metrics::AutofillFillingMethodMetric::kFullForm, - FillingProduct::kAddress, + FillingMethod::kFullForm, FillingProduct::kAddress, /*triggering_field_type_matches_filling_product=*/true); - autofill_metrics::LogUserAcceptedPreviouslyHiddenProfileSuggestion( - suggestion.hidden_prior_to_address_rewriter_usage); FillAutofillFormData( suggestion.popup_item_id, suggestion.GetPayload<Suggestion::BackendId>(), /*is_preview=*/false, @@ -719,8 +710,7 @@ break; case PopupItemId::kFillEverythingFromAddressProfile: autofill_metrics::LogFillingMethodUsed( - autofill_metrics::AutofillFillingMethodMetric::kFullForm, - FillingProduct::kAddress, + FillingMethod::kFullForm, FillingProduct::kAddress, /*triggering_field_type_matches_filling_product=*/true); FillAutofillFormData( suggestion.popup_item_id, @@ -1016,8 +1006,7 @@ IsAddressType(autofill_trigger_field->Type().GetStorableType()); autofill_metrics::LogFillingMethodUsed( - autofill_metrics::AutofillFillingMethodMetric::kFieldByFieldFilling, - FillingProduct::kAddress, + FillingMethod::kFieldByFieldFilling, FillingProduct::kAddress, /*triggering_field_type_matches_filling_product=*/ is_triggering_field_address);
diff --git a/components/autofill/core/browser/autofill_external_delegate_unittest.cc b/components/autofill/core/browser/autofill_external_delegate_unittest.cc index e7024bee..5fa85700 100644 --- a/components/autofill/core/browser/autofill_external_delegate_unittest.cc +++ b/components/autofill/core/browser/autofill_external_delegate_unittest.cc
@@ -1244,7 +1244,7 @@ // suggestion (`PopupItemId`) accepted. struct FillingMethodMetricsTestParams { const PopupItemId popup_item_id; - const autofill_metrics::AutofillFillingMethodMetric target_metric; + const FillingMethod target_metric; const std::string test_name; }; @@ -1254,31 +1254,27 @@ const FillingMethodMetricsTestParams kFillingMethodMetricsTestCases[] = { {.popup_item_id = PopupItemId::kAddressEntry, - .target_metric = autofill_metrics::AutofillFillingMethodMetric::kFullForm, + .target_metric = FillingMethod::kFullForm, .test_name = "addressEntry"}, {.popup_item_id = PopupItemId::kFillEverythingFromAddressProfile, - .target_metric = autofill_metrics::AutofillFillingMethodMetric::kFullForm, + .target_metric = FillingMethod::kFullForm, .test_name = "fillEverythingFromAddressProfile"}, {.popup_item_id = PopupItemId::kAddressFieldByFieldFilling, - .target_metric = - autofill_metrics::AutofillFillingMethodMetric::kFieldByFieldFilling, + .target_metric = FillingMethod::kFieldByFieldFilling, .test_name = "fieldByFieldFilling"}, {.popup_item_id = PopupItemId::kFillFullAddress, - .target_metric = - autofill_metrics::AutofillFillingMethodMetric::kGroupFillingAddress, + .target_metric = FillingMethod::kGroupFillingAddress, .test_name = "fillFullAddress"}, {.popup_item_id = PopupItemId::kFillFullPhoneNumber, - .target_metric = autofill_metrics::AutofillFillingMethodMetric:: - kGroupFillingPhoneNumber, + .target_metric = FillingMethod::kGroupFillingPhoneNumber, .test_name = "fillFullPhoneNumber"}, {.popup_item_id = PopupItemId::kFillFullEmail, - .target_metric = - autofill_metrics::AutofillFillingMethodMetric::kGroupFillingEmail, + .target_metric = FillingMethod::kGroupFillingEmail, .test_name = "fillFullEmail"}, }; // Tests that for a certain `PopupItemId` accepted, the expected -// `AutofillFillingMethodMetric` is recorded. +// `FillingMethod` is recorded. TEST_P(FillingMethodMetricsUnitTest, RecordFillingMethodForPopupType) { IssueOnQuery(); const FillingMethodMetricsTestParams& params = GetParam(); @@ -1292,8 +1288,7 @@ // Field-by-field filling is the only filling method that can fill // unclassified fields. - if (params.target_metric == - autofill_metrics::AutofillFillingMethodMetric::kFieldByFieldFilling) { + if (params.target_metric == FillingMethod::kFieldByFieldFilling) { get_triggering_autofill_field()->SetTypeTo(AutofillType(UNKNOWN_TYPE)); external_delegate().DidAcceptSuggestion(suggestion, SuggestionPosition{.row = 0});
diff --git a/components/autofill/core/browser/autofill_granular_filling_utils.cc b/components/autofill/core/browser/autofill_granular_filling_utils.cc index 25f0ecdd..1b523d4 100644 --- a/components/autofill/core/browser/autofill_granular_filling_utils.cc +++ b/components/autofill/core/browser/autofill_granular_filling_utils.cc
@@ -38,18 +38,27 @@ } // namespace -AutofillFillingMethod GetFillingMethodFromTargetedFields( +FillingMethod GetFillingMethodFromTargetedFields( const FieldTypeSet& targeted_field_types) { if (targeted_field_types == kAllFieldTypes) { - return AutofillFillingMethod::kFullForm; + return FillingMethod::kFullForm; } - if (AreFieldsGranularFillingGroup(targeted_field_types)) { - return AutofillFillingMethod::kGroupFilling; + if (targeted_field_types == GetFieldTypesOfGroup(FieldTypeGroup::kName)) { + return FillingMethod::kGroupFillingName; + } + if (targeted_field_types == GetAddressFieldsForGroupFilling()) { + return FillingMethod::kGroupFillingAddress; + } + if (targeted_field_types == GetFieldTypesOfGroup(FieldTypeGroup::kEmail)) { + return FillingMethod::kGroupFillingEmail; + } + if (targeted_field_types == GetFieldTypesOfGroup(FieldTypeGroup::kPhone)) { + return FillingMethod::kGroupFillingPhoneNumber; } if (targeted_field_types.size() == 1) { - return AutofillFillingMethod::kFieldByFieldFilling; + return FillingMethod::kFieldByFieldFilling; } - return AutofillFillingMethod::kNone; + return FillingMethod::kNone; } FieldTypeSet GetAddressFieldsForGroupFilling() { @@ -69,14 +78,17 @@ const FieldTypeSet& last_targeted_field_types, FieldType triggering_field_type) { switch (GetFillingMethodFromTargetedFields(last_targeted_field_types)) { - case AutofillFillingMethod::kGroupFilling: + case FillingMethod::kGroupFillingName: + case FillingMethod::kGroupFillingAddress: + case FillingMethod::kGroupFillingEmail: + case FillingMethod::kGroupFillingPhoneNumber: return GetServerFieldsForFieldGroup( GroupTypeOfFieldType(triggering_field_type)); - case AutofillFillingMethod::kFullForm: + case FillingMethod::kFullForm: return kAllFieldTypes; - case AutofillFillingMethod::kFieldByFieldFilling: + case FillingMethod::kFieldByFieldFilling: return {triggering_field_type}; - case AutofillFillingMethod::kNone: + case FillingMethod::kNone: break; } NOTREACHED_NORETURN();
diff --git a/components/autofill/core/browser/autofill_granular_filling_utils.h b/components/autofill/core/browser/autofill_granular_filling_utils.h index 7d0596b..fdb31c8 100644 --- a/components/autofill/core/browser/autofill_granular_filling_utils.h +++ b/components/autofill/core/browser/autofill_granular_filling_utils.h
@@ -15,16 +15,23 @@ // different popup surfaces a user can use to interact with Autofill, which may // lead to a different set of fields being filled. These sets/groups can be // either the full form, a group of related fields or a single field. -enum class AutofillFillingMethod : uint8_t { +enum class FillingMethod : uint8_t { // User chose to fill the whole form. Either from the main suggestion or from // the extended menu `PopupItemId::kFillEverything`. kFullForm = 0, - // User chose one of the group filling options, such as name, address or phone - // number. - kGroupFilling = 1, + // User chose to fill all name fields. + kGroupFillingName = 1, + // User chose to fill all address fields. + kGroupFillingAddress = 2, + // User chose to fill all email fields. + kGroupFillingEmail = 3, + // User chose to fill all phone number fields. + kGroupFillingPhoneNumber = 4, // User chose to fill a specific field. - kFieldByFieldFilling = 2, - kNone = 3, + kFieldByFieldFilling = 5, + // Used for default values. + kNone = 6, + kMaxValue = kNone }; // Helper method that returns all address related fields for the purpose of @@ -40,7 +47,7 @@ bool AreFieldsGranularFillingGroup(const FieldTypeSet& field_types); // Returns the autofill filling method corresponding to `targeted_fields`. -AutofillFillingMethod GetFillingMethodFromTargetedFields( +FillingMethod GetFillingMethodFromTargetedFields( const FieldTypeSet& targeted_field_types); // Returns a set of fields to be filled, given the last targeted fields and
diff --git a/components/autofill/core/browser/autofill_granular_filling_utils_unittest.cc b/components/autofill/core/browser/autofill_granular_filling_utils_unittest.cc index e246b5a..fc2e295f 100644 --- a/components/autofill/core/browser/autofill_granular_filling_utils_unittest.cc +++ b/components/autofill/core/browser/autofill_granular_filling_utils_unittest.cc
@@ -44,7 +44,7 @@ } // The test below asserts that when the last targeted fields match -// `AutofillFillingMethod::kGroupFilling`, +// `FillingMethod::kGroupFillingFoo`, // `GetTargetServerFieldsForTypeAndLastTargetedFields()` returns a set of fields // that match the group of the triggering field. TEST(
diff --git a/components/autofill/core/browser/autofill_suggestion_generator.cc b/components/autofill/core/browser/autofill_suggestion_generator.cc index 92acf3ee..c4d0f91 100644 --- a/components/autofill/core/browser/autofill_suggestion_generator.cc +++ b/components/autofill/core/browser/autofill_suggestion_generator.cc
@@ -39,7 +39,6 @@ #include "components/autofill/core/browser/form_structure.h" #include "components/autofill/core/browser/geo/address_i18n.h" #include "components/autofill/core/browser/geo/phone_number_i18n.h" -#include "components/autofill/core/browser/metrics/address_rewriter_in_profile_subset_metrics.h" #include "components/autofill/core/browser/metrics/autofill_metrics.h" #include "components/autofill/core/browser/metrics/payments/card_metadata_metrics.h" #include "components/autofill/core/browser/payments/autofill_offer_manager.h" @@ -69,6 +68,10 @@ namespace { +constexpr DenseSet<FillingMethod> kGroupFillingMethods = { + FillingMethod::kGroupFillingName, FillingMethod::kGroupFillingAddress, + FillingMethod::kGroupFillingEmail, FillingMethod::kGroupFillingPhoneNumber}; + // Returns the credit card field |value| trimmed from whitespace and with stop // characters removed. std::u16string SanitizeCreditCardFieldValue(const std::u16string& value) { @@ -700,13 +703,16 @@ switch (GetFillingMethodFromTargetedFields( last_targeted_fields.value_or(kAllFieldTypes))) { - case AutofillFillingMethod::kGroupFilling: + case FillingMethod::kGroupFillingName: + case FillingMethod::kGroupFillingAddress: + case FillingMethod::kGroupFillingEmail: + case FillingMethod::kGroupFillingPhoneNumber: return get_popup_item_id_for_group_filling(); - case AutofillFillingMethod::kFullForm: + case FillingMethod::kFullForm: return PopupItemId::kAddressEntry; - case AutofillFillingMethod::kFieldByFieldFilling: + case FillingMethod::kFieldByFieldFilling: return PopupItemId::kAddressFieldByFieldFilling; - case AutofillFillingMethod::kNone: + case FillingMethod::kNone: NOTREACHED_NORETURN(); } } @@ -717,32 +723,25 @@ // filling behaviour. Returns an empty string when no granular filling label // needs to be applied for a profile. std::u16string GetGranularFillingLabels( - std::optional<FieldTypeSet> last_targeted_fields, - FieldType triggering_field_type) { - AutofillFillingMethod filling_method = GetFillingMethodFromTargetedFields( + std::optional<FieldTypeSet> last_targeted_fields) { + FillingMethod filling_method = GetFillingMethodFromTargetedFields( last_targeted_fields.value_or(kAllFieldTypes)); - if (filling_method != AutofillFillingMethod::kGroupFilling) { + if (!kGroupFillingMethods.contains(filling_method)) { return u""; } - switch (GroupTypeOfFieldType(triggering_field_type)) { - case FieldTypeGroup::kName: + switch (filling_method) { + case FillingMethod::kGroupFillingName: return l10n_util::GetStringUTF16( IDS_AUTOFILL_FILL_NAME_GROUP_POPUP_OPTION_SELECTED); - case FieldTypeGroup::kCompany: - case FieldTypeGroup::kAddress: + case FillingMethod::kGroupFillingAddress: return l10n_util::GetStringUTF16( IDS_AUTOFILL_FILL_ADDRESS_GROUP_POPUP_OPTION_SELECTED); - case FieldTypeGroup::kNoGroup: - case FieldTypeGroup::kPhone: - case FieldTypeGroup::kEmail: - case FieldTypeGroup::kCreditCard: - case FieldTypeGroup::kPasswordField: - case FieldTypeGroup::kTransaction: - case FieldTypeGroup::kUsernameField: - case FieldTypeGroup::kUnfillable: - case FieldTypeGroup::kIban: + case FillingMethod::kGroupFillingEmail: + case FillingMethod::kGroupFillingPhoneNumber: return u""; + default: + NOTREACHED_NORETURN(); } } @@ -765,10 +764,10 @@ int GetNumberOfMinimalFieldsToShow( FieldType trigger_field_type, std::optional<FieldTypeSet> last_targeted_fields) { - AutofillFillingMethod filling_method = GetFillingMethodFromTargetedFields( + FillingMethod filling_method = GetFillingMethodFromTargetedFields( last_targeted_fields.value_or(kAllFieldTypes)); - if (filling_method == AutofillFillingMethod::kGroupFilling) { + if (kGroupFillingMethods.contains(filling_method)) { // If an address field cannot provide sufficient information about the // address, then `ADDRESS_HOME_LINE1` should be part of the label. // Otherwise, no general labels are needed in group filling mode. Only @@ -845,7 +844,7 @@ } const std::u16string suggestions_granular_filling_label = - GetGranularFillingLabels(last_targeted_fields, trigger_field_type); + GetGranularFillingLabels(last_targeted_fields); const std::vector<std::u16string> suggestions_differentiating_labels = GetProfileSuggestionLabels(profiles, field_types, trigger_field_type, @@ -1027,12 +1026,10 @@ trigger_source != AutofillSuggestionTriggerSource::kManualFallbackAddress ? trigger_field.value : u""; - std::vector<raw_ptr<const AutofillProfile, VectorExperimental>> profiles_to_suggest = GetProfilesToSuggest( trigger_field_type, field_value_for_filtering, trigger_field.is_autofilled, field_types, trigger_source); - // If autofill for addresses is triggered from the context menu on an address // field and no suggestions can be shown (i.e. if a user has only addresses // without emails and then triggers autofill from the context menu on an email @@ -1052,48 +1049,15 @@ {UNKNOWN_TYPE}, trigger_field, UNKNOWN_TYPE, std::move(last_targeted_fields), trigger_source); } - - // Find the profiles that were hidden prior to the effects of the feature - // kAutofillUseAddressRewriterInProfileSubsetComparison. - std::set<std::string> previously_hidden_profiles_guid; - for (const AutofillProfile* profile : profiles_to_suggest) { - previously_hidden_profiles_guid.insert(profile->guid()); - } - constexpr FieldTypeSet street_address_field_types = { - ADDRESS_HOME_STREET_ADDRESS, ADDRESS_HOME_LINE1, ADDRESS_HOME_LINE2, - ADDRESS_HOME_LINE3}; - FieldTypeSet field_types_without_address_types = field_types; - field_types_without_address_types.erase_all(street_address_field_types); - - // Autofill already considers suggestions as different if the suggestion's - // main text, to be filled in the triggering field, differs regardless of - // the other fields. - std::vector<raw_ptr<const AutofillProfile, VectorExperimental>> - previously_suggested_profiles = - street_address_field_types.contains(trigger_field_type) - ? profiles_to_suggest - : GetProfilesToSuggest( - trigger_field_type, field_value_for_filtering, - trigger_field.is_autofilled, - field_types_without_address_types, trigger_source); - for (const AutofillProfile* profile : previously_suggested_profiles) { - previously_hidden_profiles_guid.erase(profile->guid()); - } - autofill_metrics::LogPreviouslyHiddenProfileSuggestionNumber( - previously_hidden_profiles_guid.size()); - std::vector<Suggestion> suggestions = CreateSuggestionsFromProfiles( profiles_to_suggest, field_types, last_targeted_fields, - trigger_field_type, trigger_field.max_length, - previously_hidden_profiles_guid); + trigger_field_type, trigger_field.max_length); if (suggestions.empty()) { return suggestions; } - base::ranges::move(GetAddressFooterSuggestions(trigger_field.is_autofilled), std::back_inserter(suggestions)); - return suggestions; } @@ -1121,7 +1085,6 @@ sorted_profiles.begin() + std::min(kMaxDisplayedAddressSuggestions, sorted_profiles.size())); } - // When suggesting with no prefix to match, suppress disused address // suggestions as well as those based on invalid profile data if the // `trigger_source` is not @@ -1133,7 +1096,6 @@ AutofillClock::Now() - kDisusedDataModelTimeDelta; RemoveProfilesNotUsedSinceTimestamp(min_last_used, sorted_profiles); } - std::vector<const AutofillProfile*> matched_profiles = GetPrefixMatchedProfiles(sorted_profiles, trigger_field_type, field_contents, field_contents_canon, @@ -1165,16 +1127,13 @@ const FieldTypeSet& field_types, std::optional<FieldTypeSet> last_targeted_fields, FieldType trigger_field_type, - uint64_t trigger_field_max_length, - const std::set<std::string>& previously_hidden_profiles_guid) { + uint64_t trigger_field_max_length) { std::vector<Suggestion> suggestions; std::string app_locale = personal_data().app_locale(); - std::vector<std::vector<Suggestion::Text>> labels = CreateSuggestionLabelsWithGranularFillingDetails( profiles, field_types, last_targeted_fields, trigger_field_type, app_locale); - // This will be used to check if suggestions should be supported with icons. const bool contains_profile_related_fields = base::ranges::count_if(field_types, [](FieldType field_type) { @@ -1184,7 +1143,6 @@ field_type_group == FieldTypeGroup::kPhone || field_type_group == FieldTypeGroup::kEmail; }) > 1; - FieldTypeGroup trigger_field_type_group = GroupTypeOfFieldType(trigger_field_type); for (size_t i = 0; i < profiles.size(); ++i) { @@ -1208,7 +1166,6 @@ *profile, app_locale, ShouldUseNationalFormatPhoneNumber(trigger_field_type)); } - suggestions.emplace_back(main_text); suggestions.back().labels.emplace_back(std::move(labels[i])); suggestions.back().payload = Suggestion::Guid(profile->guid()); @@ -1216,8 +1173,6 @@ l10n_util::GetStringUTF16(IDS_AUTOFILL_A11Y_ANNOUNCE_FILLED_FORM); suggestions.back().popup_item_id = popup_item_id; suggestions.back().is_acceptable = IsAddressType(trigger_field_type); - suggestions.back().hidden_prior_to_address_rewriter_usage = - previously_hidden_profiles_guid.contains(profile->guid()); if (suggestions.back().popup_item_id == PopupItemId::kAddressFieldByFieldFilling) { suggestions.back().field_by_field_filling_type_used = @@ -1236,7 +1191,6 @@ suggestions.back().icon = Suggestion::Icon::kAccount; } } - if (profile && profile->source() == AutofillProfile::Source::kAccount && profile->initial_creator_id() != AutofillProfile::kInitialCreatorOrModifierChrome) { @@ -1244,7 +1198,6 @@ feature_engagement:: kIPHAutofillExternalAccountProfileSuggestionFeature.name; } - if (base::FeatureList::IsEnabled( features::kAutofillGranularFillingAvailable)) { // TODO(crbug.com/1502162): Make the granular filling options vary @@ -1254,7 +1207,6 @@ suggestions.back()); } } - // Add devtools test addresses suggestion if it exists. A suggestion will // exist if devtools is open and therefore test addresses were set. if (std::optional<Suggestion> test_addresses_suggestion = @@ -1263,7 +1215,6 @@ suggestions.insert(suggestions.begin(), std::move(*test_addresses_suggestion)); } - return suggestions; }
diff --git a/components/autofill/core/browser/autofill_suggestion_generator.h b/components/autofill/core/browser/autofill_suggestion_generator.h index 766dda76..70c853e 100644 --- a/components/autofill/core/browser/autofill_suggestion_generator.h +++ b/components/autofill/core/browser/autofill_suggestion_generator.h
@@ -165,8 +165,7 @@ const FieldTypeSet& field_types, std::optional<FieldTypeSet> last_targeted_fields, FieldType trigger_field_type, - uint64_t trigger_field_max_length, - const std::set<std::string>& previously_hidden_profiles_guid = {}); + uint64_t trigger_field_max_length); // Creates a suggestion for the given `credit_card`. `virtual_card_option` // suggests whether the suggestion is a virtual card option.
diff --git a/components/autofill/core/browser/autofill_suggestion_generator_test_api.h b/components/autofill/core/browser/autofill_suggestion_generator_test_api.h index f5b6a2f..c8b20598 100644 --- a/components/autofill/core/browser/autofill_suggestion_generator_test_api.h +++ b/components/autofill/core/browser/autofill_suggestion_generator_test_api.h
@@ -49,11 +49,10 @@ const FieldTypeSet& field_types, std::optional<FieldTypeSet> last_targeted_fields, FieldType trigger_field_type, - uint64_t trigger_field_max_length, - const std::set<std::string>& previously_hidden_profiles_guid = {}) { + uint64_t trigger_field_max_length) { return suggestion_generator_->CreateSuggestionsFromProfiles( profiles, field_types, last_targeted_fields, trigger_field_type, - trigger_field_max_length, previously_hidden_profiles_guid); + trigger_field_max_length); } Suggestion CreateCreditCardSuggestion(
diff --git a/components/autofill/core/browser/browser_autofill_manager_unittest.cc b/components/autofill/core/browser/browser_autofill_manager_unittest.cc index 7395b332..f383190 100644 --- a/components/autofill/core/browser/browser_autofill_manager_unittest.cc +++ b/components/autofill/core/browser/browser_autofill_manager_unittest.cc
@@ -3664,7 +3664,7 @@ .autofill_skipped_status = FieldFillingSkipReason::kNotSkipped, .was_autofilled_before_security_policy = OptionalBoolean::kTrue, .had_value_after_filling = OptionalBoolean::kTrue, - .filling_method = AutofillFillingMethod::kFullForm, + .filling_method = FillingMethod::kFullForm, .filling_prevented_by_iframe_security_policy = OptionalBoolean::kFalse, }); EXPECT_THAT(autofill_field_ptr->field_log_events(), @@ -3742,7 +3742,7 @@ .autofill_skipped_status = FieldFillingSkipReason::kNotSkipped, .was_autofilled_before_security_policy = OptionalBoolean::kTrue, .had_value_after_filling = OptionalBoolean::kTrue, - .filling_method = AutofillFillingMethod::kFullForm, + .filling_method = FillingMethod::kFullForm, .filling_prevented_by_iframe_security_policy = OptionalBoolean::kFalse, }); @@ -3755,7 +3755,7 @@ .autofill_skipped_status = FieldFillingSkipReason::kNoValueToFill, .was_autofilled_before_security_policy = OptionalBoolean::kFalse, .had_value_after_filling = OptionalBoolean::kFalse, - .filling_method = AutofillFillingMethod::kNone, + .filling_method = FillingMethod::kNone, .filling_prevented_by_iframe_security_policy = OptionalBoolean::kUndefined, }); @@ -3777,7 +3777,7 @@ .autofill_skipped_status = FieldFillingSkipReason::kNotSkipped, .was_autofilled_before_security_policy = OptionalBoolean::kTrue, .had_value_after_filling = OptionalBoolean::kTrue, - .filling_method = AutofillFillingMethod::kFullForm, + .filling_method = FillingMethod::kFullForm, .filling_prevented_by_iframe_security_policy = OptionalBoolean::kFalse, }); @@ -3813,7 +3813,7 @@ .autofill_skipped_status = FieldFillingSkipReason::kNotSkipped, .was_autofilled_before_security_policy = OptionalBoolean::kTrue, .had_value_after_filling = OptionalBoolean::kTrue, - .filling_method = AutofillFillingMethod::kFullForm, + .filling_method = FillingMethod::kFullForm, .filling_prevented_by_iframe_security_policy = OptionalBoolean::kFalse, })); @@ -3845,7 +3845,7 @@ .autofill_skipped_status = FieldFillingSkipReason::kNotSkipped, .was_autofilled_before_security_policy = OptionalBoolean::kTrue, .had_value_after_filling = OptionalBoolean::kTrue, - .filling_method = AutofillFillingMethod::kGroupFilling, + .filling_method = FillingMethod::kGroupFillingName, .filling_prevented_by_iframe_security_policy = OptionalBoolean::kFalse, })); @@ -3877,7 +3877,7 @@ .autofill_skipped_status = FieldFillingSkipReason::kNotSkipped, .was_autofilled_before_security_policy = OptionalBoolean::kTrue, .had_value_after_filling = OptionalBoolean::kTrue, - .filling_method = AutofillFillingMethod::kFieldByFieldFilling, + .filling_method = FillingMethod::kFieldByFieldFilling, .filling_prevented_by_iframe_security_policy = OptionalBoolean::kFalse, })); @@ -3944,7 +3944,7 @@ .autofill_skipped_status = FieldFillingSkipReason::kNotSkipped, .was_autofilled_before_security_policy = OptionalBoolean::kTrue, .had_value_after_filling = OptionalBoolean::kTrue, - .filling_method = AutofillFillingMethod::kFullForm, + .filling_method = FillingMethod::kFullForm, .filling_prevented_by_iframe_security_policy = OptionalBoolean::kFalse, }; @@ -3974,7 +3974,7 @@ .autofill_skipped_status = FieldFillingSkipReason::kNotSkipped, .was_autofilled_before_security_policy = OptionalBoolean::kTrue, .had_value_after_filling = OptionalBoolean::kTrue, - .filling_method = AutofillFillingMethod::kFullForm, + .filling_method = FillingMethod::kFullForm, .filling_prevented_by_iframe_security_policy = OptionalBoolean::kFalse}); } else if (autofill_field_ptr->parseable_label() == u"Phone Number" || @@ -3985,7 +3985,7 @@ expected_event.had_value_after_filling = OptionalBoolean::kFalse; expected_event.filling_prevented_by_iframe_security_policy = OptionalBoolean::kUndefined; - expected_event.filling_method = AutofillFillingMethod::kNone; + expected_event.filling_method = FillingMethod::kNone; expected_event.autofill_skipped_status = FieldFillingSkipReason::kNoValueToFill; expected_events.push_back(expected_event); @@ -3995,7 +3995,7 @@ .autofill_skipped_status = FieldFillingSkipReason::kNotSkipped, .was_autofilled_before_security_policy = OptionalBoolean::kTrue, .had_value_after_filling = OptionalBoolean::kTrue, - .filling_method = AutofillFillingMethod::kFullForm, + .filling_method = FillingMethod::kFullForm, .filling_prevented_by_iframe_security_policy = OptionalBoolean::kFalse}); } else { @@ -4007,7 +4007,7 @@ FieldFillingSkipReason::kAutofilledFieldsNotRefill, .was_autofilled_before_security_policy = OptionalBoolean::kFalse, .had_value_after_filling = OptionalBoolean::kTrue, - .filling_method = AutofillFillingMethod::kNone, + .filling_method = FillingMethod::kNone, .filling_prevented_by_iframe_security_policy = OptionalBoolean::kUndefined}); } @@ -4060,7 +4060,7 @@ .autofill_skipped_status = FieldFillingSkipReason::kNotSkipped, .was_autofilled_before_security_policy = OptionalBoolean::kTrue, .had_value_after_filling = OptionalBoolean::kTrue, - .filling_method = AutofillFillingMethod::kFullForm, + .filling_method = FillingMethod::kFullForm, .filling_prevented_by_iframe_security_policy = OptionalBoolean::kFalse, }; @@ -4137,7 +4137,7 @@ .autofill_skipped_status = FieldFillingSkipReason::kNotSkipped, .was_autofilled_before_security_policy = OptionalBoolean::kTrue, .had_value_after_filling = OptionalBoolean::kTrue, - .filling_method = AutofillFillingMethod::kFullForm, + .filling_method = FillingMethod::kFullForm, .filling_prevented_by_iframe_security_policy = OptionalBoolean::kFalse, }; @@ -4170,7 +4170,7 @@ .autofill_skipped_status = FieldFillingSkipReason::kNoValueToFill, .was_autofilled_before_security_policy = OptionalBoolean::kFalse, .had_value_after_filling = OptionalBoolean::kFalse, - .filling_method = AutofillFillingMethod::kNone, + .filling_method = FillingMethod::kNone, .filling_prevented_by_iframe_security_policy = OptionalBoolean::kUndefined, });
diff --git a/components/autofill/core/browser/data_model/autofill_profile.cc b/components/autofill/core/browser/data_model/autofill_profile.cc index e65fde4..0e8a584 100644 --- a/components/autofill/core/browser/data_model/autofill_profile.cc +++ b/components/autofill/core/browser/data_model/autofill_profile.cc
@@ -41,7 +41,6 @@ #include "components/autofill/core/browser/geo/autofill_country.h" #include "components/autofill/core/browser/geo/phone_number_i18n.h" #include "components/autofill/core/browser/geo/state_names.h" -#include "components/autofill/core/browser/metrics/address_rewriter_in_profile_subset_metrics.h" #include "components/autofill/core/browser/metrics/autofill_metrics.h" #include "components/autofill/core/browser/profile_token_quality.h" #include "components/autofill/core/browser/validation.h"
diff --git a/components/autofill/core/browser/form_filler.cc b/components/autofill/core/browser/form_filler.cc index 57328ca..2d6c743b 100644 --- a/components/autofill/core/browser/form_filler.cc +++ b/components/autofill/core/browser/form_filler.cc
@@ -450,7 +450,7 @@ .autofill_skipped_status = FieldFillingSkipReason::kNotSkipped, .was_autofilled_before_security_policy = ToOptionalBoolean(true), .had_value_after_filling = ToOptionalBoolean(true), - .filling_method = AutofillFillingMethod::kFieldByFieldFilling}); + .filling_method = FillingMethod::kFieldByFieldFilling}); } manager_->driver().ApplyFieldAction(action_type, action_persistence, field.global_id(), value); @@ -626,7 +626,7 @@ skip_reasons[autofill_field->global_id()], .was_autofilled_before_security_policy = OptionalBoolean::kFalse, .had_value_after_filling = ToOptionalBoolean(has_value_before), - .filling_method = AutofillFillingMethod::kNone, + .filling_method = FillingMethod::kNone, .value_that_would_have_been_filled_in_a_prefilled_field_hash = value_that_would_have_been_filled_in_a_prefilled_field_hash(), }); @@ -697,8 +697,8 @@ features::kAutofillGranularFillingAvailable) ? GetFillingMethodFromTargetedFields( trigger_details.field_types_to_fill) - : AutofillFillingMethod::kFullForm - : AutofillFillingMethod::kNone, + : FillingMethod::kFullForm + : FillingMethod::kNone, }); } LOG_AF(buffer)
diff --git a/components/autofill/core/browser/form_parsing/internal_resources b/components/autofill/core/browser/form_parsing/internal_resources index eda22f2..cf5d6e0 160000 --- a/components/autofill/core/browser/form_parsing/internal_resources +++ b/components/autofill/core/browser/form_parsing/internal_resources
@@ -1 +1 @@ -Subproject commit eda22f28bded47cdfaa65a0b703fd55b80e470ce +Subproject commit cf5d6e009247ce27beccca2d771f3105caaa4256
diff --git a/components/autofill/core/browser/form_parsing/resources/legacy_regex_patterns.json b/components/autofill/core/browser/form_parsing/resources/legacy_regex_patterns.json index ba0461a..d6d4dc43 100644 --- a/components/autofill/core/browser/form_parsing/resources/legacy_regex_patterns.json +++ b/components/autofill/core/browser/form_parsing/resources/legacy_regex_patterns.json
@@ -1617,7 +1617,7 @@ "CREDIT_CARD_NUMBER": { "en": [ { - "positive_pattern": "(?:card|cc|acct).?(?:number|#|no|num|field(?!s)|pan)|0000 ?0000 ?0000 ?0000|1234 ?1234 ?1234 ?1234", + "positive_pattern": "(?:card|cc|acct).?(?:number|#|no|num|field(?!s)|pan)|0000 ?0000 ?0000 ?0000|1234 ?1234 ?1234 ?1234|^xxxx ?xxxx ?xxxx ?xxxx$", "positive_score": 1.0, "negative_pattern": null, "match_field_attributes": ["LABEL", "NAME"],
diff --git a/components/autofill/core/browser/metrics/address_rewriter_in_profile_subset_metrics.cc b/components/autofill/core/browser/metrics/address_rewriter_in_profile_subset_metrics.cc deleted file mode 100644 index 9669f0d..0000000 --- a/components/autofill/core/browser/metrics/address_rewriter_in_profile_subset_metrics.cc +++ /dev/null
@@ -1,22 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/autofill/core/browser/metrics/address_rewriter_in_profile_subset_metrics.h" - -#include "base/metrics/histogram_functions.h" -#include "base/metrics/user_metrics.h" - -namespace autofill::autofill_metrics { - -void LogPreviouslyHiddenProfileSuggestionNumber(size_t hidden_profiles_number) { - base::UmaHistogramCounts100("Autofill.PreviouslyHiddenSuggestionNumber", - hidden_profiles_number); -} - -void LogUserAcceptedPreviouslyHiddenProfileSuggestion(bool previously_hidden) { - base::UmaHistogramBoolean("Autofill.AcceptedPreviouslyHiddenSuggestion", - previously_hidden); -} - -} // namespace autofill::autofill_metrics
diff --git a/components/autofill/core/browser/metrics/address_rewriter_in_profile_subset_metrics.h b/components/autofill/core/browser/metrics/address_rewriter_in_profile_subset_metrics.h deleted file mode 100644 index 7f17bd1c..0000000 --- a/components/autofill/core/browser/metrics/address_rewriter_in_profile_subset_metrics.h +++ /dev/null
@@ -1,25 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_METRICS_ADDRESS_REWRITER_IN_PROFILE_SUBSET_METRICS_H_ -#define COMPONENTS_AUTOFILL_CORE_BROWSER_METRICS_ADDRESS_REWRITER_IN_PROFILE_SUBSET_METRICS_H_ - -#include <stddef.h> - -namespace autofill::autofill_metrics { - -// Records the number of suggestions that were hidden prior to the effects of -// the feature kAutofillUseAddressRewriterInProfileSubsetComparison. Emitted -// once per suggestion generation. -void LogPreviouslyHiddenProfileSuggestionNumber(size_t hidden_profiles_number); - -// Records whether the user accepted a suggestion that was previously hidden -// prior to the effects caused by the feature -// kAutofillUseAddressRewriterInProfileSubsetComparison. Emitted every time the -// user accepts a `PopupItemId::kAddressEntry` suggestion. -void LogUserAcceptedPreviouslyHiddenProfileSuggestion(bool previously_hidden); - -} // namespace autofill::autofill_metrics - -#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_METRICS_ADDRESS_REWRITER_IN_PROFILE_SUBSET_METRICS_H_
diff --git a/components/autofill/core/browser/metrics/address_rewriter_in_profile_subset_metrics_unittest.cc b/components/autofill/core/browser/metrics/address_rewriter_in_profile_subset_metrics_unittest.cc deleted file mode 100644 index 9d49a2b..0000000 --- a/components/autofill/core/browser/metrics/address_rewriter_in_profile_subset_metrics_unittest.cc +++ /dev/null
@@ -1,95 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include <optional> -#include <string> - -#include "base/test/metrics/histogram_tester.h" -#include "base/test/metrics/user_action_tester.h" -#include "base/test/scoped_feature_list.h" -#include "components/autofill/core/browser/autofill_suggestion_generator.h" -#include "components/autofill/core/browser/autofill_test_utils.h" -#include "components/autofill/core/browser/autofill_trigger_details.h" -#include "components/autofill/core/browser/data_model/autofill_profile_comparator.h" -#include "components/autofill/core/browser/field_types.h" -#include "components/autofill/core/browser/metrics/autofill_metrics_test_base.h" -#include "components/autofill/core/browser/ui/popup_item_ids.h" -#include "components/autofill/core/browser/ui/suggestion.h" -#include "components/autofill/core/common/aliases.h" -#include "components/autofill/core/common/autofill_features.h" -#include "components/autofill/core/common/form_field_data.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace autofill::autofill_metrics { - -namespace { - -class AddressRewriterInProfileSubsetMetricsTest - : public autofill_metrics::AutofillMetricsBaseTest, - public testing::Test { - public: - void SetUp() override { - SetUpHelper(); - scoped_feature_list_.InitAndEnableFeature( - features::kAutofillUseAddressRewriterInProfileSubsetComparison); - } - void TearDown() override { TearDownHelper(); } - - protected: - base::test::ScopedFeatureList scoped_feature_list_; -}; - -// Tests that previously hidden suggestions are correctly set and detected and -// that we correctly emit the metrics responsible for counting those suggestions -// and detecting when the user accepts one of those suggestions. -TEST_F(AddressRewriterInProfileSubsetMetricsTest, PreviouslyHiddenSuggestion) { - personal_data().ClearProfiles(); - - AutofillProfile profile_a(AddressCountryCode("US")); - profile_a.SetRawInfo(NAME_FULL, u"first last"); - profile_a.SetRawInfo(ADDRESS_HOME_LINE1, u"123 Main Street"); - profile_a.SetRawInfo(EMAIL_ADDRESS, u"email@foo.com"); - profile_a.set_use_count(100); - personal_data().AddProfile(profile_a); - - AutofillProfile profile_b(AddressCountryCode("US")); - profile_b.SetRawInfo(NAME_FULL, u"first last"); - profile_b.SetRawInfo(ADDRESS_HOME_LINE1, u"124 Main Street"); - personal_data().AddProfile(profile_b); - - FormData form = test::CreateTestAddressFormData(); - autofill_manager().OnFormsSeen({form}, {}); - external_delegate().OnQuery( - form, form.fields.front(), gfx::RectF(), - AutofillSuggestionTriggerSource::kFormControlElementClicked); - - base::HistogramTester histogram_tester; - AutofillSuggestionGenerator suggestion_generator(*autofill_client_); - std::vector<Suggestion> suggestions = - suggestion_generator.GetSuggestionsForProfiles( - {NAME_FULL, ADDRESS_HOME_LINE1}, FormFieldData(), NAME_FULL, - std::nullopt, AutofillSuggestionTriggerSource::kUnspecified); - histogram_tester.ExpectUniqueSample( - "Autofill.PreviouslyHiddenSuggestionNumber", 1, 1); - ASSERT_EQ(suggestions.size(), 4u); - EXPECT_FALSE(suggestions[0].hidden_prior_to_address_rewriter_usage); - EXPECT_TRUE(suggestions[1].hidden_prior_to_address_rewriter_usage); - EXPECT_EQ(suggestions[2].popup_item_id, PopupItemId::kSeparator); - EXPECT_EQ(suggestions[3].popup_item_id, PopupItemId::kAutofillOptions); - - external_delegate().DidAcceptSuggestion( - suggestions[0], AutofillPopupDelegate::SuggestionPosition{.row = 0}); - histogram_tester.ExpectUniqueSample( - "Autofill.AcceptedPreviouslyHiddenSuggestion", 0, 1); - - external_delegate().DidAcceptSuggestion( - suggestions[1], AutofillPopupDelegate::SuggestionPosition{.row = 1}); - EXPECT_THAT(histogram_tester.GetAllSamples( - "Autofill.AcceptedPreviouslyHiddenSuggestion"), - base::BucketsAre(base::Bucket(0, 1), base::Bucket(1, 1))); -} - -} // namespace - -} // namespace autofill::autofill_metrics
diff --git a/components/autofill/core/browser/metrics/field_filling_stats_and_score_metrics.cc b/components/autofill/core/browser/metrics/field_filling_stats_and_score_metrics.cc index 5ffc4a17..89831c9 100644 --- a/components/autofill/core/browser/metrics/field_filling_stats_and_score_metrics.cc +++ b/components/autofill/core/browser/metrics/field_filling_stats_and_score_metrics.cc
@@ -127,13 +127,13 @@ form_type, base::StrCat({"Autofill.FieldFillingStats."}), filling_stats); } -void LogAddressFieldFillingStatsForAutofillFillingMethod( - AutofillFillingMethod filling_method, +void LogAddressFieldFillingStatsForFillingMethod( + FillingMethod filling_method, const FormGroupFillingStats& filling_stats) { LogFieldFillingStatsWithHistogramPrefix( FormType::kAddressForm, base::StrCat({"Autofill.FieldFillingStats.", - AutofillFillingMethodToStringView(filling_method), "."}), + FillingMethodToCompactStringView(filling_method), "."}), filling_stats); } @@ -216,14 +216,14 @@ LogFormFillingComplexScore(FormType::kCreditCardForm, cc_filling_stats); } -void LogAddressFieldFillingStatsAndScoreByAutofillFillingMethod( - const base::flat_map<AutofillFillingMethod, +void LogAddressFieldFillingStatsAndScoreByFillingMethod( + const base::flat_map<FillingMethod, autofill_metrics::FormGroupFillingStats>& address_filling_stats_by_filling_method) { autofill_metrics::FormGroupFillingStats any; for (const auto& filling_stats : address_filling_stats_by_filling_method) { - LogAddressFieldFillingStatsForAutofillFillingMethod(filling_stats.first, - filling_stats.second); + LogAddressFieldFillingStatsForFillingMethod(filling_stats.first, + filling_stats.second); MergeFormGroupFillingStats(filling_stats.second, any); } LogFieldFillingStatsWithHistogramPrefix(
diff --git a/components/autofill/core/browser/metrics/field_filling_stats_and_score_metrics.h b/components/autofill/core/browser/metrics/field_filling_stats_and_score_metrics.h index f50b821a..a59f732 100644 --- a/components/autofill/core/browser/metrics/field_filling_stats_and_score_metrics.h +++ b/components/autofill/core/browser/metrics/field_filling_stats_and_score_metrics.h
@@ -27,9 +27,9 @@ const FormGroupFillingStats& cc_filling_stats, const FormGroupFillingStats& ac_unrecognized_address_field_stats); -// Same as above but keyed by `AutofillFillingMethod`. -void LogAddressFieldFillingStatsAndScoreByAutofillFillingMethod( - const base::flat_map<AutofillFillingMethod, +// Same as above but keyed by `FillingMethod`. +void LogAddressFieldFillingStatsAndScoreByFillingMethod( + const base::flat_map<FillingMethod, autofill_metrics::FormGroupFillingStats>& address_filling_stats_by_filling_method);
diff --git a/components/autofill/core/browser/metrics/field_filling_stats_and_score_metrics_unittest.cc b/components/autofill/core/browser/metrics/field_filling_stats_and_score_metrics_unittest.cc index 8900a004..6397e78 100644 --- a/components/autofill/core/browser/metrics/field_filling_stats_and_score_metrics_unittest.cc +++ b/components/autofill/core/browser/metrics/field_filling_stats_and_score_metrics_unittest.cc
@@ -19,7 +19,7 @@ namespace { FillFieldLogEvent GetFillFieldLogEventWithFillingMethod( - AutofillFillingMethod filling_method) { + FillingMethod filling_method) { return FillFieldLogEvent{ .fill_event_id = GetNextFillEventId(), .had_value_before_filling = ToOptionalBoolean(false), @@ -30,8 +30,7 @@ .filling_prevented_by_iframe_security_policy = OptionalBoolean::kFalse}; } -std::vector<test::FieldDescription> GetTestFormDataFields( - AutofillFillingMethod filling_method = AutofillFillingMethod::kFullForm) { +std::vector<test::FieldDescription> GetTestFormDataFields() { return { {.role = NAME_FULL, .value = u"First Middle Last", .is_autofilled = true}, // Those two fields are going to be changed to a value of the @@ -163,57 +162,54 @@ ExpectFieldFillingStatsUniqueSample(histogram_tester, "Address.Total", 14); } -// Same as above but for different filling methods. Using the same form we set -// the first 2 fields filling method's to be -// `AutofillFillingMethod::kGroupFilling` and -// `AutofillFillingMethod::kFieldByFieldFilling` respectively. For the different -// filling methods, assert that they have emitted the expected metrics. Note -// that metrics related to a filled not being autofilled like -// `ManuallyFilledToSameType` are always counted in the Any bucket of filling -// methods, since the other ones by definition means that the filled was -// autofilled. +// Same as above but for different filling methods. Note that metrics related to +// a filled not being autofilled like `ManuallyFilledToSameType` are always +// counted in the Any bucket of filling methods, since the other ones by +// definition means that the filled was autofilled. TEST_F(AutofillFieldFillingStatsAndScoreMetricsTest, FillingStats_FillingMethod) { base::test::ScopedFeatureList features( features::kAutofillGranularFillingAvailable); - const FormData& form = GetAndAddSeenFormWithFields( - GetTestFormDataFields(AutofillFillingMethod::kGroupFilling)); + const FormData& form = GetAndAddSeenFormWithFields(GetTestFormDataFields()); FormStructure* form_structure = autofill_manager().FindCachedFormById(form.global_id()); - // Make the first filling method be `AutofillFillingMethod::kGroupFilling`. + form_structure->field(0)->AppendLogEventIfNotRepeated( - GetFillFieldLogEventWithFillingMethod( - AutofillFillingMethod::kGroupFilling)); - // Make the second field filling method be - // `AutofillFillingMethod::kFieldByFieldFilling`. + GetFillFieldLogEventWithFillingMethod(FillingMethod::kGroupFillingName)); form_structure->field(1)->AppendLogEventIfNotRepeated( GetFillFieldLogEventWithFillingMethod( - AutofillFillingMethod::kFieldByFieldFilling)); - // Make all other filled fields, be `AutofillFillingMethod::kFullForm`. - for (size_t i = 2; i < form_structure->fields().size(); i++) { + FillingMethod::kGroupFillingAddress)); + form_structure->field(2)->AppendLogEventIfNotRepeated( + GetFillFieldLogEventWithFillingMethod( + FillingMethod::kFieldByFieldFilling)); + + // Make all other filled fields, be `FillingMethod::kFullForm`. + for (size_t i = 3; i < form_structure->fields().size(); i++) { AutofillField* field = form_structure->field(i); if (field->is_autofilled) { - field->AppendLogEventIfNotRepeated(GetFillFieldLogEventWithFillingMethod( - AutofillFillingMethod::kFullForm)); + field->AppendLogEventIfNotRepeated( + GetFillFieldLogEventWithFillingMethod(FillingMethod::kFullForm)); } } base::HistogramTester histogram_tester; SimulationOfDefaultUserChangesOnAddedFormTextFields(); - SubmitForm(form); // The first field which was simply accepted had - // AutofillFillingMethod::kGroupFilling as filling method. + // FillingMethod::kGroupFillingAddress as filling method. ExpectFieldFillingStatsUniqueSample(histogram_tester, "GroupFilling.Address.Accepted", 1); + // The second field was corrected. + ExpectFieldFillingStatsUniqueSample( + histogram_tester, "GroupFilling.Address.CorrectedToSameType", 1); ExpectFieldFillingStatsUniqueSample(histogram_tester, - "GroupFilling.Address.TotalFilled", 1); + "GroupFilling.Address.TotalFilled", 2); ExpectFieldFillingStatsUniqueSample(histogram_tester, - "GroupFilling.Address.Total", 1); + "GroupFilling.Address.Total", 2); - // The second field which was changed to the same type had - // AutofillFillingMethod::kGroupFilling as filling method. + // The third field which was changed to the same type had + // FillingMethod::kGroupFillingAddress as filling method. ExpectFieldFillingStatsUniqueSample(histogram_tester, "FieldByFieldFilling.Address." "CorrectedToSameType", @@ -223,7 +219,7 @@ ExpectFieldFillingStatsUniqueSample(histogram_tester, "FieldByFieldFilling.Address.Total", 1); - // The other filled fields had AutofillFillingMethod::kFullForm as filling + // The other filled fields had FillingMethod::kFullForm as filling // method ExpectFieldFillingStatsUniqueSample( histogram_tester, "FullForm.Address.CorrectedToDifferentType", 1); @@ -232,11 +228,11 @@ ExpectFieldFillingStatsUniqueSample(histogram_tester, "FullForm.Address.CorrectedToEmpty", 1); ExpectFieldFillingStatsUniqueSample(histogram_tester, - "FullForm.Address.TotalFilled", 5); + "FullForm.Address.TotalFilled", 4); ExpectFieldFillingStatsUniqueSample(histogram_tester, - "FullForm.Address.TotalCorrected", 4); + "FullForm.Address.TotalCorrected", 3); ExpectFieldFillingStatsUniqueSample(histogram_tester, - "FullForm.Address.Total", 5); + "FullForm.Address.Total", 4); // Manually filled fields are only counted under Any since they have no // filling method.
diff --git a/components/autofill/core/browser/metrics/granular_filling_metrics.cc b/components/autofill/core/browser/metrics/granular_filling_metrics.cc index b1b2f8d..e034113d 100644 --- a/components/autofill/core/browser/metrics/granular_filling_metrics.cc +++ b/components/autofill/core/browser/metrics/granular_filling_metrics.cc
@@ -68,7 +68,7 @@ user_accepted_delete); } -void LogFillingMethodUsed(AutofillFillingMethodMetric filling_method, +void LogFillingMethodUsed(FillingMethod filling_method, FillingProduct filling_product, bool triggering_field_type_matches_filling_product) { base::UmaHistogramEnumeration(
diff --git a/components/autofill/core/browser/metrics/granular_filling_metrics.h b/components/autofill/core/browser/metrics/granular_filling_metrics.h index fd512db..8fb79a0 100644 --- a/components/autofill/core/browser/metrics/granular_filling_metrics.h +++ b/components/autofill/core/browser/metrics/granular_filling_metrics.h
@@ -5,29 +5,12 @@ #ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_METRICS_GRANULAR_FILLING_METRICS_H_ #define COMPONENTS_AUTOFILL_CORE_BROWSER_METRICS_GRANULAR_FILLING_METRICS_H_ +#include "components/autofill/core/browser/autofill_granular_filling_utils.h" #include "components/autofill/core/browser/field_types.h" #include "components/autofill/core/browser/filling_product.h" namespace autofill::autofill_metrics { -// Represents the filling method chosen by the user. -enum class AutofillFillingMethodMetric { - // User chose to fill the whole form. Either from the main suggestion or from - // the extended menu `PopupItemId::kFillEverything`. - kFullForm = 0, - // User chose to fill all name fields. - kGroupFillingName = 1, - // User chose to fill all address fields. - kGroupFillingAddress = 2, - // User chose to fill all email fields. - kGroupFillingEmail = 3, - // User chose to fill all phone number fields. - kGroupFillingPhoneNumber = 4, - // User chose to fill a specific field. - kFieldByFieldFilling = 5, - kMaxValue = kFieldByFieldFilling -}; - // These values are persisted to UMA logs. Entries should not be renumbered // and numeric values should never be reused. This is a subset of field // types that can be chosen when the user fills a specific field using one of @@ -63,13 +46,13 @@ // dialog is opened from the Autofill popup. void LogDeleteAddressProfileFromExtendedMenu(bool user_accepted_delete); -// Logs the `AutofillFillingMethodMetric` chosen by the user. +// Logs the `FillingMethod` chosen by the user. // `filling_product` defines what type of filling the user chose, for example // address or payment. `triggering_field_type_matches_filling_product` defines // whether the `filling_product` chosen matches the triggering field type. For // example, if an user chose to fill their address profile into an unclassified // field, triggering_field_type_matches_filling_product will be false. -void LogFillingMethodUsed(AutofillFillingMethodMetric filling_method, +void LogFillingMethodUsed(FillingMethod filling_method, FillingProduct filling_product, bool triggering_field_type_matches_filling_product);
diff --git a/components/autofill/core/browser/metrics/granular_filling_metrics_utils.cc b/components/autofill/core/browser/metrics/granular_filling_metrics_utils.cc index ec1060d..30f90a7 100644 --- a/components/autofill/core/browser/metrics/granular_filling_metrics_utils.cc +++ b/components/autofill/core/browser/metrics/granular_filling_metrics_utils.cc
@@ -7,57 +7,71 @@ #include "base/containers/adapters.h" #include "base/containers/flat_map.h" #include "components/autofill/core/browser/autofill_field.h" +#include "components/autofill/core/browser/autofill_granular_filling_utils.h" #include "components/autofill/core/browser/metrics/autofill_metrics_utils.h" namespace autofill::autofill_metrics { namespace { -// Gets the last `AutofillFillingMethod` logged for a `field`. If the filled was -// never filled using Autofill, returns `AutofillFillingMethod::kNone`. +// Gets the last `FillingMethod` logged for a `field`. If the filled was +// never filled using Autofill, returns `FillingMethod::kNone`. // `field_log_events()` returns all log events that were added to a field in -// chronological order, so in order to know the last `AutofillFillingMethod` +// chronological order, so in order to know the last `FillingMethod` // used for `field` we can look for the latest log event in the array of type // `FillFieldLogEvent` that has a its filling method different to -// `AutofillFillingMethod::kNone`. -AutofillFillingMethod GetLastFieldAutofillFillingMethod( - const AutofillField& field) { +// `FillingMethod::kNone`. +FillingMethod GetLastFieldFillingMethod(const AutofillField& field) { for (const auto& log_event : base::Reversed(field.field_log_events())) { - auto* event = absl::get_if<FillFieldLogEvent>(&log_event); - if (event && event->filling_method != AutofillFillingMethod::kNone) { - return event->filling_method; + if (auto* event = absl::get_if<FillFieldLogEvent>(&log_event)) { + switch (event->filling_method) { + case FillingMethod::kFullForm: + return FillingMethod::kFullForm; + case FillingMethod::kGroupFillingName: + case FillingMethod::kGroupFillingAddress: + case FillingMethod::kGroupFillingEmail: + case FillingMethod::kGroupFillingPhoneNumber: + // For metric purposes, we do not care about the type of group filling + // that was used. + return FillingMethod::kGroupFillingAddress; + case FillingMethod::kFieldByFieldFilling: + return FillingMethod::kFieldByFieldFilling; + case FillingMethod::kNone: + break; + } } } - return AutofillFillingMethod::kNone; + return FillingMethod::kNone; } } // namespace -std::string_view AutofillFillingMethodToStringView( - AutofillFillingMethod filling_method) { +std::string_view FillingMethodToCompactStringView( + FillingMethod filling_method) { switch (filling_method) { - case AutofillFillingMethod::kFullForm: + case FillingMethod::kFullForm: return "FullForm"; - case AutofillFillingMethod::kGroupFilling: + case FillingMethod::kGroupFillingName: + case FillingMethod::kGroupFillingAddress: + case FillingMethod::kGroupFillingEmail: + case FillingMethod::kGroupFillingPhoneNumber: return "GroupFilling"; - case AutofillFillingMethod::kFieldByFieldFilling: + case FillingMethod::kFieldByFieldFilling: return "FieldByFieldFilling"; - case AutofillFillingMethod::kNone: + case FillingMethod::kNone: return "None"; } } -void AddFillingStatsForAutofillFillingMethod( +void AddFillingStatsForFillingMethod( const AutofillField& field, - base::flat_map<AutofillFillingMethod, - autofill_metrics::FormGroupFillingStats>& + base::flat_map<FillingMethod, autofill_metrics::FormGroupFillingStats>& field_stats_by_filling_method) { - const AutofillFillingMethod filling_method = - GetLastFieldAutofillFillingMethod(field); + const FillingMethod filling_method = GetLastFieldFillingMethod(field); auto filling_stats_form_autofill_filling_method_it = field_stats_by_filling_method.find(filling_method); - // If this is not the first field that has a certain `AutofillFillingMethod`, + // If this is not the first field that has a certain `FillingMethod`, // update the existing entry to include the `field`s `FieldFillingStatus`. // Otherwise create a new entry in the map for the field`s filling method and // set the `FormGroupFillingStats` for the `field`s `FieldFillingStatus` as @@ -65,11 +79,10 @@ if (filling_stats_form_autofill_filling_method_it != field_stats_by_filling_method.end()) { filling_stats_form_autofill_filling_method_it->second.AddFieldFillingStatus( - autofill_metrics::GetFieldFillingStatus(field)); + GetFieldFillingStatus(field)); } else { - autofill_metrics::FormGroupFillingStats filling_method_stats; - filling_method_stats.AddFieldFillingStatus( - autofill_metrics::GetFieldFillingStatus(field)); + FormGroupFillingStats filling_method_stats; + filling_method_stats.AddFieldFillingStatus(GetFieldFillingStatus(field)); field_stats_by_filling_method[filling_method] = filling_method_stats; } }
diff --git a/components/autofill/core/browser/metrics/granular_filling_metrics_utils.h b/components/autofill/core/browser/metrics/granular_filling_metrics_utils.h index 78703e30..298382c 100644 --- a/components/autofill/core/browser/metrics/granular_filling_metrics_utils.h +++ b/components/autofill/core/browser/metrics/granular_filling_metrics_utils.h
@@ -18,16 +18,15 @@ namespace autofill_metrics { -// Given a `AutofillFillingMethod` returns its `std::string_view` -// representation. -std::string_view AutofillFillingMethodToStringView( - AutofillFillingMethod filling_method); +// Given a `FillingMethod` returns its `std::string_view` representation. Also +// squashes all group filling enums to "GroupFilling". +std::string_view FillingMethodToCompactStringView(FillingMethod filling_method); // Computes and adds the `FillingStats` of `field` to the correct key -// (`AutofillFillingMethod`) in `field_stats_by_filling_method`. -void AddFillingStatsForAutofillFillingMethod( +// (`FillingMethod`) in `field_stats_by_filling_method`. +void AddFillingStatsForFillingMethod( const AutofillField& field, - base::flat_map<AutofillFillingMethod, FormGroupFillingStats>& + base::flat_map<FillingMethod, FormGroupFillingStats>& field_stats_by_filling_method); } // namespace autofill_metrics
diff --git a/components/autofill/core/browser/metrics/log_event.h b/components/autofill/core/browser/metrics/log_event.h index 68e4baa..1d8bcff0 100644 --- a/components/autofill/core/browser/metrics/log_event.h +++ b/components/autofill/core/browser/metrics/log_event.h
@@ -102,11 +102,11 @@ internal::IsRequired(); // Whether the field had a value after this fill operation. OptionalBoolean had_value_after_filling = internal::IsRequired(); - // The `AutofillFillingMethod` used to fill the field. This represents the + // The `FillingMethod` used to fill the field. This represents the // different popup surfaces a user can use to interact with Autofill, which // may lead to a different set of fields being filled. These sets/groups can // be either the full form, a group of related fields or a single field. - AutofillFillingMethod filling_method = AutofillFillingMethod::kNone; + FillingMethod filling_method = FillingMethod::kNone; // Records whether filling was ever prevented because of the cross c // autofill security policy that applies to credit cards. OptionalBoolean filling_prevented_by_iframe_security_policy =
diff --git a/components/autofill/core/browser/metrics/quality_metrics.cc b/components/autofill/core/browser/metrics/quality_metrics.cc index ab6eb6b..9c6250d 100644 --- a/components/autofill/core/browser/metrics/quality_metrics.cc +++ b/components/autofill/core/browser/metrics/quality_metrics.cc
@@ -47,8 +47,8 @@ autofill_metrics::FormGroupFillingStats cc_field_stats; autofill_metrics::FormGroupFillingStats ac_unrecognized_address_field_stats; - // Same as above, but keyed by `AutofillFillingMethod`. - base::flat_map<AutofillFillingMethod, autofill_metrics::FormGroupFillingStats> + // Same as above, but keyed by `FillingMethod`. + base::flat_map<FillingMethod, autofill_metrics::FormGroupFillingStats> address_field_stats_by_filling_method; // Count the number of autofilled and corrected non-credit card fields with @@ -154,13 +154,13 @@ autofill_metrics::GetFieldFillingStatus(*field)); } // For address forms we want to emit filling stats metrics per - // `AutofillFillingMethod`. Therefore, the stats generated are added to - // a map keyed by `AutofillFillingMethod`, so that later, metrics can + // `FillingMethod`. Therefore, the stats generated are added to + // a map keyed by `FillingMethod`, so that later, metrics can // emitted for each method used. if (base::FeatureList::IsEnabled( features::kAutofillGranularFillingAvailable) & is_address_form_field) { - AddFillingStatsForAutofillFillingMethod( + AddFillingStatsForFillingMethod( *field, address_field_stats_by_filling_method); } @@ -372,7 +372,7 @@ autofill_metrics::LogFieldFillingStatsAndScore( address_field_stats, cc_field_stats, ac_unrecognized_address_field_stats); - LogAddressFieldFillingStatsAndScoreByAutofillFillingMethod( + LogAddressFieldFillingStatsAndScoreByFillingMethod( address_field_stats_by_filling_method); if (card_form) {
diff --git a/components/autofill/core/browser/ui/suggestion.h b/components/autofill/core/browser/ui/suggestion.h index 15b449e..1afcdea 100644 --- a/components/autofill/core/browser/ui/suggestion.h +++ b/components/autofill/core/browser/ui/suggestion.h
@@ -236,11 +236,6 @@ // Whether the user is able to preview the suggestion by hovering on it or // accept it by clicking on it. bool is_acceptable = true; - - // Denotes whether this suggestion was hidden prior to the effects caused by - // kAutofillUseAddressRewriterInProfileSubsetComparison. - // TODO(crbug.com/1439742): Remove when the feature launches. - bool hidden_prior_to_address_rewriter_usage = false; }; std::string_view ConvertIconToPrintableString(Suggestion::Icon icon);
diff --git a/components/autofill/core/common/autofill_features.cc b/components/autofill/core/common/autofill_features.cc index 7d98c03..8a3b9202b 100644 --- a/components/autofill/core/common/autofill_features.cc +++ b/components/autofill/core/common/autofill_features.cc
@@ -386,7 +386,7 @@ base::FEATURE_DISABLED_BY_DEFAULT); // Changes Autofill Clear Form into Undo Autofill. -BASE_FEATURE(kAutofillUndo, "AutofillUndo", base::FEATURE_ENABLED_BY_DEFAULT); +BASE_FEATURE(kAutofillUndo, "AutofillUndo", base::FEATURE_DISABLED_BY_DEFAULT); // When enabled, some local heuristic predictions will take precedence over the // autocomplete attribute and server predictions, when determining a field's @@ -554,7 +554,7 @@ // TODO(crbug.com/1459990): Clean up when launched. BASE_FEATURE(kAutofillTestFormWithDevtools, "AutofillTestFormWithDevtools", - base::FEATURE_DISABLED_BY_DEFAULT); + base::FEATURE_ENABLED_BY_DEFAULT); // Allows silent profile updates even when the profile import requirements are // not met.
diff --git a/components/autofill/core/common/autofill_regex_constants.h b/components/autofill/core/common/autofill_regex_constants.h index f77ab5ff..cc949e8b 100644 --- a/components/autofill/core/common/autofill_regex_constants.h +++ b/components/autofill/core/common/autofill_regex_constants.h
@@ -279,7 +279,8 @@ // E.g. "número de (?:la )?tarjeta" in es-MX, "número do cartão" in pt-BR u"|(numero|número|numéro)(?!.*(document|fono|phone|réservation))" u"|0000 ?0000 ?0000 ?0000" - u"|1234 ?1234 ?1234 ?1234"; + u"|1234 ?1234 ?1234 ?1234" + u"|^xxxx ?xxxx ?xxxx ?xxxx$"; inline constexpr char16_t kCardCvcRe[] = u"verification|card.?identification|security.?code|card.?code"
diff --git a/components/blocked_content/safe_browsing_triggered_popup_blocker_unittest.cc b/components/blocked_content/safe_browsing_triggered_popup_blocker_unittest.cc index eaf2507..3b8ef30 100644 --- a/components/blocked_content/safe_browsing_triggered_popup_blocker_unittest.cc +++ b/components/blocked_content/safe_browsing_triggered_popup_blocker_unittest.cc
@@ -117,7 +117,8 @@ metadata.subresource_filter_match [safe_browsing::SubresourceFilterType::ABUSIVE] = level; fake_safe_browsing_database()->AddBlocklistedUrl( - url, safe_browsing::SB_THREAT_TYPE_SUBRESOURCE_FILTER, metadata); + url, safe_browsing::SBThreatType::SB_THREAT_TYPE_SUBRESOURCE_FILTER, + metadata); } void MarkUrlAsAbusiveEnforce(const GURL& url) {
diff --git a/components/bookmarks/browser/bookmark_client.cc b/components/bookmarks/browser/bookmark_client.cc index 70b54c6..7f0b7ce 100644 --- a/components/bookmarks/browser/bookmark_client.cc +++ b/components/bookmarks/browser/bookmark_client.cc
@@ -10,6 +10,10 @@ void BookmarkClient::Init(BookmarkModel* model) {} +void BookmarkClient::RequiredRecoveryToLoad( + const std::multimap<int64_t, int64_t>& + local_or_syncable_reassigned_ids_per_old_id) {} + const BookmarkNode* BookmarkClient::GetSuggestedSaveLocation(const GURL& url) { return nullptr; }
diff --git a/components/bookmarks/browser/bookmark_client.h b/components/bookmarks/browser/bookmark_client.h index b7d81bbd..cb2a8c4 100644 --- a/components/bookmarks/browser/bookmark_client.h +++ b/components/bookmarks/browser/bookmark_client.h
@@ -6,6 +6,7 @@ #define COMPONENTS_BOOKMARKS_BROWSER_BOOKMARK_CLIENT_H_ #include <cstdint> +#include <map> #include <string> #include <unordered_map> #include <utility> @@ -43,6 +44,14 @@ // Called during initialization of BookmarkModel. virtual void Init(BookmarkModel* model); + // Called when loading from disk triggered some recovery, meaning that IDs or + // UUIDs could have been reassigned. If IDs were reassigned, which is not + // always the case, `local_or_syncable_reassigned_ids_per_old_id` contains + // the mapping from old IDs (before reassignment) to new ones. + virtual void RequiredRecoveryToLoad( + const std::multimap<int64_t, int64_t>& + local_or_syncable_reassigned_ids_per_old_id); + // Gets a bookmark folder that the provided URL can be saved to. If nullptr is // returned, the bookmark is saved to the default location (usually this is // the last modified folder). This affords features the option to override the
diff --git a/components/bookmarks/browser/bookmark_codec.cc b/components/bookmarks/browser/bookmark_codec.cc index 08d2203..f64e9a50 100644 --- a/components/bookmarks/browser/bookmark_codec.cc +++ b/components/bookmarks/browser/bookmark_codec.cc
@@ -267,7 +267,8 @@ std::string id_string; int64_t id = 0; - if (ids_valid_) { + + { const std::string* string = value.FindString(kIdKey); if (!string || !base::StringToInt64(*string, &id) || id <= 0 || ids_.count(id) != 0) { @@ -461,6 +462,7 @@ BookmarkNode* other_node, BookmarkNode* mobile_node) { ids_.clear(); + reassigned_ids_per_old_id_.clear(); ReassignIDsHelper(bb_node); ReassignIDsHelper(other_node); ReassignIDsHelper(mobile_node); @@ -469,7 +471,9 @@ void BookmarkCodec::ReassignIDsHelper(BookmarkNode* node) { DCHECK(node); + const int64_t old_id = node->id(); node->set_id(++maximum_id_); + reassigned_ids_per_old_id_.emplace(old_id, node->id()); ids_.insert(node->id()); for (const auto& child : node->children()) ReassignIDsHelper(child.get());
diff --git a/components/bookmarks/browser/bookmark_codec.h b/components/bookmarks/browser/bookmark_codec.h index b92fdc5..9a5e6e4 100644 --- a/components/bookmarks/browser/bookmark_codec.h +++ b/components/bookmarks/browser/bookmark_codec.h
@@ -7,6 +7,7 @@ #include <stdint.h> +#include <map> #include <memory> #include <set> #include <string> @@ -69,6 +70,12 @@ // false after encoding. bool ids_reassigned() const { return ids_reassigned_; } + // If IDs are reassigned during decoding, it returns the mapping from old + // (i.e. on-disk) ID to the newly-assigned ones. + std::multimap<int64_t, int64_t> release_reassigned_ids_per_old_id() { + return std::move(reassigned_ids_per_old_id_); + } + // Test-only APIs. const std::string& ComputedChecksumForTest() const { return computed_checksum_; @@ -172,6 +179,10 @@ // Whether or not IDs were reassigned by the codec. bool ids_reassigned_{false}; + // Mapping from old ID to new IDs if IDs were reassigned. Note that old IDs + // may contain duplicates, and therefore the mapping could be ambiguous. + std::multimap<int64_t, int64_t> reassigned_ids_per_old_id_; + // Whether or not UUIDs were reassigned by the codec. bool uuids_reassigned_{false};
diff --git a/components/bookmarks/browser/bookmark_codec_unittest.cc b/components/bookmarks/browser/bookmark_codec_unittest.cc index ed823684..beb241e 100644 --- a/components/bookmarks/browser/bookmark_codec_unittest.cc +++ b/components/bookmarks/browser/bookmark_codec_unittest.cc
@@ -22,13 +22,16 @@ #include "components/bookmarks/browser/bookmark_model.h" #include "components/bookmarks/browser/bookmark_uuids.h" #include "components/bookmarks/test/test_bookmark_client.h" +#include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -using base::ASCIIToUTF16; - namespace bookmarks { namespace { +using base::ASCIIToUTF16; +using testing::ElementsAre; +using testing::Pair; + const char16_t kUrl1Title[] = u"url1"; const char kUrl1Url[] = "http://www.url1.com"; const char16_t kUrl2Title[] = u"url2"; @@ -521,6 +524,11 @@ EXPECT_EQ(decoder.release_assigned_ids(), std::set<int64_t>({1, 2, 3, 4, 5, 6, 7, 8, 9})); EXPECT_EQ(10, decoded_model->next_node_id()); + + EXPECT_THAT( + decoder.release_reassigned_ids_per_old_id(), + ElementsAre(Pair(1, 1), Pair(3, 2), Pair(4, 4), Pair(4, 5), Pair(5, 3), + Pair(6, 6), Pair(7, 8), Pair(9, 9), Pair(10, 7))); } TEST_F(BookmarkCodecTest, DecodeWithAlreadyAssignedIds) {
diff --git a/components/bookmarks/browser/bookmark_load_details.h b/components/bookmarks/browser/bookmark_load_details.h index 43a11a2..8cbdba4 100644 --- a/components/bookmarks/browser/bookmark_load_details.h +++ b/components/bookmarks/browser/bookmark_load_details.h
@@ -5,6 +5,7 @@ #ifndef COMPONENTS_BOOKMARKS_BROWSER_BOOKMARK_LOAD_DETAILS_H_ #define COMPONENTS_BOOKMARKS_BROWSER_BOOKMARK_LOAD_DETAILS_H_ +#include <map> #include <memory> #include <string> @@ -79,6 +80,17 @@ void set_ids_reassigned(bool value) { ids_reassigned_ = value; } bool ids_reassigned() const { return ids_reassigned_; } + // If IDs are reassigned during decoding, this represents the mapping from old + // (i.e. on-disk) ID to the newly-assigned ones. + const std::multimap<int64_t, int64_t>& + local_or_syncable_reassigned_ids_per_old_id() const { + return local_or_syncable_reassigned_ids_per_old_id_; + } + void set_local_or_syncable_reassigned_ids_per_old_id( + std::multimap<int64_t, int64_t> value) { + local_or_syncable_reassigned_ids_per_old_id_ = std::move(value); + } + // Returns the string blob representing the sync metadata in the json file. // The string blob is set during decode time upon the call to Bookmark::Load. void set_local_or_syncable_sync_metadata_str(std::string sync_metadata_str) { @@ -133,6 +145,7 @@ UuidIndex account_uuid_index_; int64_t max_id_ = 1; bool ids_reassigned_ = false; + std::multimap<int64_t, int64_t> local_or_syncable_reassigned_ids_per_old_id_; bool required_recovery_ = false; scoped_refptr<UrlIndex> url_index_; raw_ptr<BookmarkPermanentNode> bb_node_;
diff --git a/components/bookmarks/browser/bookmark_model.cc b/components/bookmarks/browser/bookmark_model.cc index 8600c0c..dffdc15 100644 --- a/components/bookmarks/browser/bookmark_model.cc +++ b/components/bookmarks/browser/bookmark_model.cc
@@ -1230,20 +1230,6 @@ DCHECK(!loaded_); DCHECK(details->required_recovery() || !details->ids_reassigned()); - if (details->required_recovery()) { - // If the from-disk loading went through a recovery (e.g. IDs were - // reassigned due to collisions), it is best to save the result back to - // disk so it won't keep happening upon every restart. - if (local_or_syncable_store_) { - local_or_syncable_store_->ScheduleSave(); - } - - if (account_store_) { - CHECK(AreFoldersForAccountStorageAllowed()); - account_store_->ScheduleSave(); - } - } - next_node_id_ = details->max_id(); titled_url_index_ = details->owned_titled_url_index(); uuid_index_[NodeTypeForUuidLookup::kLocalOrSyncableNodes] = @@ -1281,6 +1267,23 @@ loaded_ = true; + if (details->required_recovery()) { + // If the from-disk loading went through a recovery (e.g. IDs were + // reassigned due to collisions), it is best to save the result back to + // disk so it won't keep happening upon every restart. + if (local_or_syncable_store_) { + local_or_syncable_store_->ScheduleSave(); + } + + if (account_store_) { + CHECK(AreFoldersForAccountStorageAllowed()); + account_store_->ScheduleSave(); + } + + client_->RequiredRecoveryToLoad( + details->local_or_syncable_reassigned_ids_per_old_id()); + } + client_->DecodeLocalOrSyncableBookmarkSyncMetadata( details->local_or_syncable_sync_metadata_str(), local_or_syncable_store_
diff --git a/components/bookmarks/browser/model_loader.cc b/components/bookmarks/browser/model_loader.cc index a593905e..b2b97fd 100644 --- a/components/bookmarks/browser/model_loader.cc +++ b/components/bookmarks/browser/model_loader.cc
@@ -119,6 +119,8 @@ codec.ids_reassigned()); details->set_required_recovery(details->required_recovery() || codec.required_recovery()); + details->set_local_or_syncable_reassigned_ids_per_old_id( + codec.release_reassigned_ids_per_old_id()); } }
diff --git a/components/browser_sync/sync_client_utils.cc b/components/browser_sync/sync_client_utils.cc index dd8f70f..05c1143 100644 --- a/components/browser_sync/sync_client_utils.cc +++ b/components/browser_sync/sync_client_utils.cc
@@ -315,14 +315,19 @@ CHECK(helper_->account_bookmark_sync_service_); CHECK(helper_->local_bookmark_sync_service_->bookmark_model_view()); CHECK(helper_->account_bookmark_sync_service_->bookmark_model_view()); - // Merge all local bookmarks into the account bookmark model. - sync_bookmarks::LocalBookmarkModelMerger( - helper_->local_bookmark_sync_service_->bookmark_model_view(), - helper_->account_bookmark_sync_service_->bookmark_model_view()) - .Merge(); - // Remove all bookmarks from the local model. - helper_->local_bookmark_sync_service_->bookmark_model_view() - ->RemoveAllSyncableNodes(); + // Guard against absence of account bookmarks. For example, this can + // happen if the initial download hasn't completed. + if (helper_->account_bookmark_sync_service_->bookmark_model_view() + ->bookmark_bar_node() != nullptr) { + // Merge all local bookmarks into the account bookmark model. + sync_bookmarks::LocalBookmarkModelMerger( + helper_->local_bookmark_sync_service_->bookmark_model_view(), + helper_->account_bookmark_sync_service_->bookmark_model_view()) + .Merge(); + // Remove all bookmarks from the local model. + helper_->local_bookmark_sync_service_->bookmark_model_view() + ->RemoveAllSyncableNodes(); + } } if (types_.Has(syncer::READING_LIST)) { CHECK(helper_->dual_reading_list_model_);
diff --git a/components/browser_ui/site_settings/android/BUILD.gn b/components/browser_ui/site_settings/android/BUILD.gn index d14a0f3..53fdc5e 100644 --- a/components/browser_ui/site_settings/android/BUILD.gn +++ b/components/browser_ui/site_settings/android/BUILD.gn
@@ -57,6 +57,7 @@ "java/src/org/chromium/components/browser_ui/site_settings/AllSiteSettings.java", "java/src/org/chromium/components/browser_ui/site_settings/AutoDarkMetrics.java", "java/src/org/chromium/components/browser_ui/site_settings/BaseSiteSettingsFragment.java", + "java/src/org/chromium/components/browser_ui/site_settings/BrowsingDataInfo.java", "java/src/org/chromium/components/browser_ui/site_settings/ChosenObjectInfo.java", "java/src/org/chromium/components/browser_ui/site_settings/ChosenObjectSettings.java", "java/src/org/chromium/components/browser_ui/site_settings/ClearWebsiteStorage.java",
diff --git a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/BrowsingDataInfo.java b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/BrowsingDataInfo.java new file mode 100644 index 0000000..b92035f --- /dev/null +++ b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/BrowsingDataInfo.java
@@ -0,0 +1,44 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.components.browser_ui.site_settings; + +import androidx.annotation.VisibleForTesting; + +import org.chromium.components.browser_ui.site_settings.WebsitePreferenceBridge.StorageInfoClearedCallback; +import org.chromium.content_public.browser.BrowserContextHandle; +import org.chromium.url.Origin; + +import java.io.Serializable; + +/** Browsing Data information for a given origin. */ +public class BrowsingDataInfo implements Serializable { + private final Origin mOrigin; + private final int mCookieCount; + private final long mStorageSize; + + @VisibleForTesting + public BrowsingDataInfo(Origin origin, int cookieCount, long storageSize) { + mOrigin = origin; + mCookieCount = cookieCount; + mStorageSize = storageSize; + } + + public Origin getOrigin() { + return mOrigin; + } + + public void clear( + BrowserContextHandle browserContextHandle, StorageInfoClearedCallback callback) { + // TODO(b/254415177): Implement data deletion through BDM. + } + + public long getStorageSize() { + return mStorageSize; + } + + public int getCookieCount() { + return mCookieCount; + } +}
diff --git a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SiteSettingsDelegate.java b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SiteSettingsDelegate.java index e973e06..7032d60 100644 --- a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SiteSettingsDelegate.java +++ b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SiteSettingsDelegate.java
@@ -16,6 +16,7 @@ import org.chromium.content_public.browser.BrowserContextHandle; import org.chromium.url.GURL; +import java.util.Map; import java.util.Set; /** @@ -164,6 +165,11 @@ /** Called when the view this delegate is assigned to gets destroyed. */ void onDestroyView(); - /** @return whether the Tracking Protection offboarding notice should be shown in the Settings. */ + /** + * @return whether the Tracking Protection offboarding notice should be shown in the Settings. + */ boolean shouldShowSettingsOffboardingNotice(); + + /** Builds browsing data model from BrowserContext and returns entries in callback */ + void fetchBrowsingDataInfo(Callback<Map<org.chromium.url.Origin, BrowsingDataInfo>> callback); }
diff --git a/components/browsing_data/content/browsing_data_model.cc b/components/browsing_data/content/browsing_data_model.cc index 6406903..4553194 100644 --- a/components/browsing_data/content/browsing_data_model.cc +++ b/components/browsing_data/content/browsing_data_model.cc
@@ -19,6 +19,7 @@ #include "components/attribution_reporting/features.h" #include "components/browsing_data/content/browsing_data_quota_helper.h" #include "components/browsing_data/content/shared_worker_info.h" +#include "components/browsing_data/core/browsing_data_utils.h" #include "components/browsing_data/core/features.h" #include "components/services/storage/public/mojom/storage_usage_info.mojom.h" #include "components/services/storage/shared_storage/shared_storage_manager.h" @@ -644,6 +645,45 @@ data_owner); } +const url::Origin BrowsingDataModel::GetOriginForDataKey( + const BrowsingDataModel::DataKey& data_key) { + return absl::visit( + base::Overloaded{ + [](const url::Origin& origin) { return origin; }, + [](const content::InterestGroupManager::InterestGroupDataKey + interest_group_key) { return interest_group_key.owner; }, + [](const content::AttributionDataModel::DataKey + attribution_reporting_key) { + return attribution_reporting_key.reporting_origin(); + }, + [](const content::PrivateAggregationDataModel::DataKey + private_aggregation_key) { + return private_aggregation_key.reporting_origin(); + }, + [](const blink::StorageKey& storage_key) { + return storage_key.origin(); + }, + [](const content::SessionStorageUsageInfo& info) { + return info.storage_key.origin(); + }, + [](const browsing_data::SharedWorkerInfo& info) { + return info.storage_key.origin(); + }, + [](const net::SharedDictionaryIsolationKey& key) { + return key.frame_origin(); + }, + [](const net::CanonicalCookie& cookie) { + GURL cookie_url = net::cookie_util::CookieOriginToURL( + cookie.Domain(), cookie.SecureAttribute()); + return url::Origin::Create(cookie_url); + }, + [](const webid::FederatedIdentityDataModel::DataKey& data_key) { + return data_key.relying_party_embedder(); + }, + }, + data_key); +} + bool BrowsingDataModel::BrowsingDataEntryView::Matches( const url::Origin& origin) const { return absl::visit(base::Overloaded{[&](const std::string& entry_host) {
diff --git a/components/browsing_data/content/browsing_data_model.h b/components/browsing_data/content/browsing_data_model.h index ff6bbc3..0309aeb 100644 --- a/components/browsing_data/content/browsing_data_model.h +++ b/components/browsing_data/content/browsing_data_model.h
@@ -233,6 +233,10 @@ // Retrieves the host from the data owner. static const std::string GetHost(const DataOwner& data_owner); + // Retrieves the owning origin for a specific data key. + static const url::Origin GetOriginForDataKey( + const BrowsingDataModel::DataKey& data_key); + // Consults supported storage backends to create and populate a Model based // on the current state of `browser_context`. static void BuildFromDisk(
diff --git a/components/commerce/core/product_specifications/BUILD.gn b/components/commerce/core/product_specifications/BUILD.gn index 106786e..00b097f 100644 --- a/components/commerce/core/product_specifications/BUILD.gn +++ b/components/commerce/core/product_specifications/BUILD.gn
@@ -6,7 +6,13 @@ sources = [ "product_specifications_service.cc", "product_specifications_service.h", + "product_specifications_sync_bridge.cc", + "product_specifications_sync_bridge.h", ] - deps = [ "//components/keyed_service/core" ] + deps = [ + "//components/keyed_service/core", + "//components/sync", + "//components/sync/model", + ] public_deps = [] }
diff --git a/components/commerce/core/product_specifications/DEPS b/components/commerce/core/product_specifications/DEPS index a82819d6..a9e9a15 100644 --- a/components/commerce/core/product_specifications/DEPS +++ b/components/commerce/core/product_specifications/DEPS
@@ -1,3 +1,5 @@ include_rules = [ "+components/keyed_service", + "+components/sync/protocol", + "+components/sync/model", ]
diff --git a/components/commerce/core/product_specifications/product_specifications_service.cc b/components/commerce/core/product_specifications/product_specifications_service.cc index cc6dce6..0d710c5 100644 --- a/components/commerce/core/product_specifications/product_specifications_service.cc +++ b/components/commerce/core/product_specifications/product_specifications_service.cc
@@ -6,7 +6,9 @@ namespace commerce { -ProductSpecificationsService::ProductSpecificationsService() = default; +ProductSpecificationsService::ProductSpecificationsService( + std::unique_ptr<ProductSpecificationsSyncBridge> bridge) + : bridge_(std::move(bridge)) {} ProductSpecificationsService::~ProductSpecificationsService() = default;
diff --git a/components/commerce/core/product_specifications/product_specifications_service.h b/components/commerce/core/product_specifications/product_specifications_service.h index 28b46a3e..eb8cab4 100644 --- a/components/commerce/core/product_specifications/product_specifications_service.h +++ b/components/commerce/core/product_specifications/product_specifications_service.h
@@ -5,6 +5,7 @@ #ifndef COMPONENTS_COMMERCE_CORE_PRODUCT_SPECIFICATIONS_PRODUCT_SPECIFICATIONS_SERVICE_H_ #define COMPONENTS_COMMERCE_CORE_PRODUCT_SPECIFICATIONS_PRODUCT_SPECIFICATIONS_SERVICE_H_ +#include "components/commerce/core/product_specifications/product_specifications_sync_bridge.h" #include "components/keyed_service/core/keyed_service.h" namespace commerce { @@ -12,12 +13,16 @@ // Acquires synced data about product specifications. class ProductSpecificationsService : public KeyedService { public: - ProductSpecificationsService(); + explicit ProductSpecificationsService( + std::unique_ptr<ProductSpecificationsSyncBridge> bridge); ProductSpecificationsService(const ProductSpecificationsService&) = delete; ProductSpecificationsService& operator=(const ProductSpecificationsService&) = delete; ~ProductSpecificationsService() override; + + private: + std::unique_ptr<ProductSpecificationsSyncBridge> bridge_; }; } // namespace commerce
diff --git a/components/commerce/core/product_specifications/product_specifications_sync_bridge.cc b/components/commerce/core/product_specifications/product_specifications_sync_bridge.cc new file mode 100644 index 0000000..6fbdfc95 --- /dev/null +++ b/components/commerce/core/product_specifications/product_specifications_sync_bridge.cc
@@ -0,0 +1,70 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/commerce/core/product_specifications/product_specifications_sync_bridge.h" + +#include "components/sync/base/model_type.h" +#include "components/sync/model/metadata_batch.h" +#include "components/sync/model/model_type_change_processor.h" +#include "components/sync/model/model_type_store.h" + +namespace commerce { + +ProductSpecificationsSyncBridge::ProductSpecificationsSyncBridge( + syncer::OnceModelTypeStoreFactory create_store_callback, + std::unique_ptr<syncer::ModelTypeChangeProcessor> change_processor) + : syncer::ModelTypeSyncBridge(std::move(change_processor)) {} + +ProductSpecificationsSyncBridge::~ProductSpecificationsSyncBridge() = default; + +std::unique_ptr<syncer::MetadataChangeList> +ProductSpecificationsSyncBridge::CreateMetadataChangeList() { + // TODO(b/329519916) implement + NOTIMPLEMENTED(); + return nullptr; +} + +std::optional<syncer::ModelError> +ProductSpecificationsSyncBridge::MergeFullSyncData( + std::unique_ptr<syncer::MetadataChangeList> metadata_change_list, + syncer::EntityChangeList entity_changes) { + // TODO(b/329519487) implement + NOTIMPLEMENTED(); + return std::nullopt; +} +std::optional<syncer::ModelError> +ProductSpecificationsSyncBridge::ApplyIncrementalSyncChanges( + std::unique_ptr<syncer::MetadataChangeList> metadata_change_list, + syncer::EntityChangeList entity_changes) { + // TODO(b/329519488) implement + NOTIMPLEMENTED(); + return std::nullopt; +} + +std::string ProductSpecificationsSyncBridge::GetStorageKey( + const syncer::EntityData& entity_data) { + // TODO(b/329520372) implement + NOTIMPLEMENTED(); + return ""; +} +std::string ProductSpecificationsSyncBridge::GetClientTag( + const syncer::EntityData& entity_data) { + // TODO(b/329520414) implement + NOTIMPLEMENTED(); + return ""; +} + +void ProductSpecificationsSyncBridge::GetData(StorageKeyList storage_keys, + DataCallback callback) { + // TODO(b/329520479) implement + NOTIMPLEMENTED(); +} + +void ProductSpecificationsSyncBridge::GetAllDataForDebugging( + DataCallback callback) { + // TODO(b/329520107) implement + NOTIMPLEMENTED(); +} + +} // namespace commerce
diff --git a/components/commerce/core/product_specifications/product_specifications_sync_bridge.h b/components/commerce/core/product_specifications/product_specifications_sync_bridge.h new file mode 100644 index 0000000..e3d99922 --- /dev/null +++ b/components/commerce/core/product_specifications/product_specifications_sync_bridge.h
@@ -0,0 +1,45 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_COMMERCE_CORE_PRODUCT_SPECIFICATIONS_PRODUCT_SPECIFICATIONS_SYNC_BRIDGE_H_ +#define COMPONENTS_COMMERCE_CORE_PRODUCT_SPECIFICATIONS_PRODUCT_SPECIFICATIONS_SYNC_BRIDGE_H_ + +#include "components/sync/model/entity_change.h" +#include "components/sync/model/model_type_store.h" +#include "components/sync/model/model_type_sync_bridge.h" +#include "components/sync/protocol/entity_data.h" + +namespace syncer { +class MetadataChangeList; +class ModelError; +} // namespace syncer + +namespace commerce { + +// Integration point between sync and ProductSpecificationService. +class ProductSpecificationsSyncBridge : public syncer::ModelTypeSyncBridge { + public: + ProductSpecificationsSyncBridge( + syncer::OnceModelTypeStoreFactory create_store_callback, + std::unique_ptr<syncer::ModelTypeChangeProcessor> change_processor); + ~ProductSpecificationsSyncBridge() override; + + // syncer::ModelTypeSyncBridge: + std::unique_ptr<syncer::MetadataChangeList> CreateMetadataChangeList() + override; + std::optional<syncer::ModelError> MergeFullSyncData( + std::unique_ptr<syncer::MetadataChangeList> metadata_change_list, + syncer::EntityChangeList entity_changes) override; + std::optional<syncer::ModelError> ApplyIncrementalSyncChanges( + std::unique_ptr<syncer::MetadataChangeList> metadata_change_list, + syncer::EntityChangeList entity_changes) override; + std::string GetStorageKey(const syncer::EntityData& entity_data) override; + std::string GetClientTag(const syncer::EntityData& entity_data) override; + void GetData(StorageKeyList storage_keys, DataCallback callback) override; + void GetAllDataForDebugging(DataCallback callback) override; +}; + +} // namespace commerce + +#endif // COMPONENTS_COMMERCE_CORE_PRODUCT_SPECIFICATIONS_PRODUCT_SPECIFICATIONS_SYNC_BRIDGE_H_
diff --git a/components/content_settings/core/common/content_settings_constraints.cc b/components/content_settings/core/common/content_settings_constraints.cc index a5468986..f6ccd17 100644 --- a/components/content_settings/core/common/content_settings_constraints.cc +++ b/components/content_settings/core/common/content_settings_constraints.cc
@@ -24,16 +24,9 @@ ContentSettingConstraints::~ContentSettingConstraints() = default; bool ContentSettingConstraints::operator==( - const ContentSettingConstraints& other) const { - return std::tuple(expiration(), session_model_, - track_last_visit_for_autoexpiration_) == - std::tuple(other.expiration(), other.session_model_, - other.track_last_visit_for_autoexpiration_); -} + const ContentSettingConstraints& other) const = default; bool ContentSettingConstraints::operator!=( - const ContentSettingConstraints& other) const { - return !(*this == other); -} + const ContentSettingConstraints& other) const = default; } // namespace content_settings
diff --git a/components/content_settings/core/common/content_settings_constraints_unittest.cc b/components/content_settings/core/common/content_settings_constraints_unittest.cc index 3323bca4..6c918100 100644 --- a/components/content_settings/core/common/content_settings_constraints_unittest.cc +++ b/components/content_settings/core/common/content_settings_constraints_unittest.cc
@@ -36,14 +36,6 @@ ContentSettingConstraints old_constraints; env().FastForwardBy(base::Seconds(1)); ContentSettingConstraints new_constraints; - // The creation time differs, but there's no lifetime, so these are - // equivalent. - EXPECT_EQ(old_constraints, new_constraints); - - old_constraints.set_lifetime(base::Days(1)); - new_constraints.set_lifetime(base::Days(1)); - // Now there is a lifetime associated with the constraint, so the different - // creation time makes a difference. EXPECT_NE(old_constraints, new_constraints); }
diff --git a/components/content_settings/core/common/content_settings_metadata.cc b/components/content_settings/core/common/content_settings_metadata.cc index e4291cdb..6e0de0d 100644 --- a/components/content_settings/core/common/content_settings_metadata.cc +++ b/components/content_settings/core/common/content_settings_metadata.cc
@@ -34,12 +34,7 @@ return !expiration().is_null() && expiration() < clock->Now(); } -bool RuleMetaData::operator==(const RuleMetaData& other) const { - return std::tie(last_modified_, last_used_, last_visited_, expiration_, - session_model_, lifetime_) == - std::tie(other.last_modified_, other.last_used_, other.last_visited_, - other.expiration_, other.session_model_, other.lifetime_); -} +bool RuleMetaData::operator==(const RuleMetaData& other) const = default; // static base::TimeDelta RuleMetaData::ComputeLifetime(base::TimeDelta lifetime,
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 d551908..8510b0d7 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
@@ -36,9 +36,6 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; /** * Class that controls navigations and allows to intercept them. It is used on Android to 'convert' @@ -108,9 +105,8 @@ int NUM_ENTRIES = 6; } - private static final List<String> MDOC_SCHEMES = - new ArrayList<String>(Arrays.asList("mdoc", "mdl-openid4vp", "mdoc-openid4vp")); - private static final String OPENID4VP_SCHEME = "openid4vp"; + private static final String MDOC_SCHEME = "mdoc"; + private static final String OPENID4VP_SCHEME_SUFFIX = "openid4vp"; private static final String MAIN_FRAME_INTENT_LAUNCH_NAME = "Android.Intent.MainFrameIntentLaunch"; @@ -329,9 +325,9 @@ scheme = InterceptScheme.ACCEPTED_SCHEME; } else if (UrlUtilities.hasIntentScheme(escapedUrl)) { scheme = InterceptScheme.INTENT_SCHEME; - } else if (MDOC_SCHEMES.contains(escapedUrl.getScheme())) { + } else if (MDOC_SCHEME.equals(escapedUrl.getScheme())) { scheme = InterceptScheme.MDOC_SCHEME; - } else if (OPENID4VP_SCHEME.equals(escapedUrl.getScheme())) { + } else if (escapedUrl.getScheme().endsWith(OPENID4VP_SCHEME_SUFFIX)) { scheme = InterceptScheme.OPENID4VP_SCHEME; } RecordHistogram.recordEnumeratedHistogram(
diff --git a/components/facilitated_payments/android/java/src/org/chromium/components/facilitated_payments/FacilitatedPaymentsApiClient.java b/components/facilitated_payments/android/java/src/org/chromium/components/facilitated_payments/FacilitatedPaymentsApiClient.java index 9c7d805e..b80baec4 100644 --- a/components/facilitated_payments/android/java/src/org/chromium/components/facilitated_payments/FacilitatedPaymentsApiClient.java +++ b/components/facilitated_payments/android/java/src/org/chromium/components/facilitated_payments/FacilitatedPaymentsApiClient.java
@@ -19,7 +19,7 @@ protected final Delegate mDelegate; /** - * Interface for overridding the type of object that is created by + * Interface for overriding the type of object that is created by * FacilitatedPaymentsApiClient.create(). * Example usage: * @@ -48,17 +48,19 @@ /** The delegate for the facilitated payment API client. */ public interface Delegate { /** - * Notifies the delegate whether the facilitated payment API is available. + * Notifies the delegate whether the facilitated payment API is available. If the API is not + * available, the user should not be prompted with a payment UI. * * @param isAvailable Whether the facilitated payment API is available. */ default void onIsAvailable(boolean isAvailable) {} /** - * Returns a client token that is used for initiating payment. + * Provides an opaque client token to the delegate, which can use this token for initiating + * a payment. * - * @param clientToken An opaque client token for initiating payment. Can be null or empty to - * indicate a failure. + * @param clientToken An opaque client token for initiating a payment. Can be null or empty + * to indicate a failure. */ default void onGetClientToken(byte[] clientToken) {} @@ -103,8 +105,6 @@ /** * Checks whether this client has the ability to invoke facilitated payment API. Will invoke a * delegate callback with the result. - * - * @return True if has ability to invoke facilitated payment API. */ public void isAvailable() { mDelegate.onIsAvailable(/* isAvailable= */ false);
diff --git a/components/history/core/browser/history_service.cc b/components/history/core/browser/history_service.cc index b3b28b74..4f694ba6 100644 --- a/components/history/core/browser/history_service.cc +++ b/components/history/core/browser/history_service.cc
@@ -1429,6 +1429,8 @@ TRACE_EVENT0("browser,startup", "HistoryService::Init"); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + history_dir_ = history_database_params.history_dir; + // Unit tests can inject `backend_task_runner_` before this is called. if (!backend_task_runner_) { backend_task_runner_ = base::ThreadPool::CreateSequencedTaskRunner(
diff --git a/components/history/core/browser/history_service.h b/components/history/core/browser/history_service.h index 087f114..c190bfda 100644 --- a/components/history/core/browser/history_service.h +++ b/components/history/core/browser/history_service.h
@@ -114,6 +114,9 @@ return Init(false, history_database_params); } + // Returns the directory containing the History databases. + const base::FilePath& history_dir() const { return history_dir_; } + // Triggers the backend to load if it hasn't already, and then returns whether // it's finished loading. // Note: Virtual needed for mocking. @@ -1130,6 +1133,9 @@ SEQUENCE_CHECKER(sequence_checker_); + // The directory containing the History databases. + base::FilePath history_dir_; + // The TaskRunner to which HistoryBackend tasks are posted. Nullptr once // Cleanup() is called. scoped_refptr<base::SequencedTaskRunner> backend_task_runner_;
diff --git a/components/history_embeddings/BUILD.gn b/components/history_embeddings/BUILD.gn index 908cb165..d3910706 100644 --- a/components/history_embeddings/BUILD.gn +++ b/components/history_embeddings/BUILD.gn
@@ -43,6 +43,8 @@ deps = [ ":history_embeddings", "//base/test:test_support", + "//components/history/core/browser", + "//components/history/core/test", "//components/history_embeddings/proto:history_embeddings_proto", "//components/os_crypt/sync", "//components/os_crypt/sync:test_support",
diff --git a/components/history_embeddings/history_embeddings_service.cc b/components/history_embeddings/history_embeddings_service.cc index 86b2b3af..005f6d0 100644 --- a/components/history_embeddings/history_embeddings_service.cc +++ b/components/history_embeddings/history_embeddings_service.cc
@@ -62,7 +62,8 @@ //////////////////////////////////////////////////////////////////////////////// HistoryEmbeddingsService::HistoryEmbeddingsService( - const base::FilePath& storage_dir) + const base::FilePath& storage_dir, + history::HistoryService* history_service) : weak_ptr_factory_(this) { if (!base::FeatureList::IsEnabled(kHistoryEmbeddings)) { // If the feature flag is disabled, skip initialization. Note we don't also @@ -70,6 +71,9 @@ return; } + CHECK(history_service); + history_service_observation_.Observe(history_service); + storage_ = base::SequenceBound<Storage>( base::ThreadPool::CreateSequencedTaskRunner( {base::MayBlock(), base::TaskPriority::USER_BLOCKING, @@ -106,6 +110,12 @@ storage_.Reset(); } +void HistoryEmbeddingsService::OnURLsDeleted( + history::HistoryService* history_service, + const history::DeletionInfo& deletion_info) { + // TODO(b/329495955): Implement actual cleanup of storage for this deletion. +} + HistoryEmbeddingsService::Storage::Storage(const base::FilePath& storage_dir) : sql_database(storage_dir) {}
diff --git a/components/history_embeddings/history_embeddings_service.h b/components/history_embeddings/history_embeddings_service.h index 8339da49c..0916733 100644 --- a/components/history_embeddings/history_embeddings_service.h +++ b/components/history_embeddings/history_embeddings_service.h
@@ -12,6 +12,8 @@ #include "base/functional/callback.h" #include "base/memory/weak_ptr.h" #include "base/threading/sequence_bound.h" +#include "components/history/core/browser/history_service.h" +#include "components/history/core/browser/history_service_observer.h" #include "components/history_embeddings/sql_database.h" #include "components/history_embeddings/vector_database.h" #include "components/keyed_service/core/keyed_service.h" @@ -23,10 +25,13 @@ using ComputeEmbeddingsCallback = base::OnceCallback<std::vector<Embedding>(const UrlPassages&)>; -class HistoryEmbeddingsService : public KeyedService { +class HistoryEmbeddingsService : public KeyedService, + public history::HistoryServiceObserver { public: // `storage_dir` will generally be the Profile directory. - explicit HistoryEmbeddingsService(const base::FilePath& storage_dir); + // `history_service` is never nullptr. + HistoryEmbeddingsService(const base::FilePath& storage_dir, + history::HistoryService* history_service); HistoryEmbeddingsService(const HistoryEmbeddingsService&) = delete; HistoryEmbeddingsService& operator=(const HistoryEmbeddingsService&) = delete; ~HistoryEmbeddingsService() override; @@ -40,6 +45,10 @@ // KeyedService: void Shutdown() override; + // history::HistoryServiceObserver: + void OnURLsDeleted(history::HistoryService* history_service, + const history::DeletionInfo& deletion_info) override; + private: FRIEND_TEST_ALL_PREFIXES(HistoryEmbeddingsTest, ConstructsAndComputesEmbeddings); @@ -64,6 +73,11 @@ // Called indirectly via RetrievePassages when passage extraction completes. void OnPassagesRetrieved(PassagesCallback callback, UrlPassages passages); + // Tracks the observed history service, for cleanup. + base::ScopedObservation<history::HistoryService, + history::HistoryServiceObserver> + history_service_observation_{this}; + // Storage is bound to a separate sequence. // This will be null if the feature flag is disabled. base::SequenceBound<Storage> storage_;
diff --git a/components/history_embeddings/history_embeddings_service_unittest.cc b/components/history_embeddings/history_embeddings_service_unittest.cc index d85fa6e..2342ce3 100644 --- a/components/history_embeddings/history_embeddings_service_unittest.cc +++ b/components/history_embeddings/history_embeddings_service_unittest.cc
@@ -8,22 +8,36 @@ #include "base/files/file_path.h" #include "base/files/scoped_temp_dir.h" +#include "base/test/task_environment.h" +#include "components/history/core/browser/history_service.h" +#include "components/history/core/test/history_service_test_util.h" #include "testing/gtest/include/gtest/gtest.h" namespace history_embeddings { class HistoryEmbeddingsTest : public testing::Test { public: - void SetUp() override { CHECK(history_dir_.CreateUniqueTempDir()); } + void SetUp() override { + CHECK(history_dir_.CreateUniqueTempDir()); + + history_service_ = + history::CreateHistoryService(history_dir_.GetPath(), true); + CHECK(history_service_); + } void TearDown() override {} protected: + base::test::TaskEnvironment task_environment_{ + base::test::SingleThreadTaskEnvironment::TimeSource::MOCK_TIME}; + base::ScopedTempDir history_dir_; + std::unique_ptr<history::HistoryService> history_service_; }; TEST_F(HistoryEmbeddingsTest, Constructs) { - std::make_unique<HistoryEmbeddingsService>(history_dir_.GetPath()); + std::make_unique<HistoryEmbeddingsService>(history_dir_.GetPath(), + history_service_.get()); } } // namespace history_embeddings
diff --git a/components/minidump_uploader/android/java/src/org/chromium/components/minidump_uploader/MinidumpUploader.java b/components/minidump_uploader/android/java/src/org/chromium/components/minidump_uploader/MinidumpUploader.java index dc7fbc0..e2501f9 100644 --- a/components/minidump_uploader/android/java/src/org/chromium/components/minidump_uploader/MinidumpUploader.java +++ b/components/minidump_uploader/android/java/src/org/chromium/components/minidump_uploader/MinidumpUploader.java
@@ -132,14 +132,16 @@ new GZIPOutputStream(connection.getOutputStream())) { streamCopy(minidumpInputStream, requestBodyStream); int responseCode = connection.getResponseCode(); + // The crash server returns the crash ID in the response body. + String responseContent = getResponseContentAsString(connection); + String uploadId = responseContent != null ? responseContent : "unknown"; if (isSuccessful(responseCode)) { - // The crash server returns the crash ID in the response body. - String responseContent = getResponseContentAsString(connection); - String uploadId = responseContent != null ? responseContent : "unknown"; return Result.success(uploadId); } else { // Return the remote error code and message. - return Result.uploadError(responseCode, connection.getResponseMessage()); + return Result.uploadError( + responseCode, + connection.getResponseMessage() + " uploadId: " + uploadId); } } finally { connection.disconnect();
diff --git a/components/onc/onc_constants.cc b/components/onc/onc_constants.cc index c4aae95..ab5f6fd 100644 --- a/components/onc/onc_constants.cc +++ b/components/onc/onc_constants.cc
@@ -197,6 +197,10 @@ const char kApnTypeDefault[] = "Default"; const char kApnTypeAttach[] = "Attach"; const char kApnTypeTether[] = "Tether"; +const char kSource[] = "Source"; +const char kSourceModem[] = "Modem"; +const char kSourceModb[] = "Modb"; +const char kSourceUi[] = "Ui"; } // namespace cellular_apn namespace cellular_found_network {
diff --git a/components/onc/onc_constants.h b/components/onc/onc_constants.h index 99f41cff..88ee538 100644 --- a/components/onc/onc_constants.h +++ b/components/onc/onc_constants.h
@@ -214,6 +214,10 @@ COMPONENT_EXPORT(ONC) extern const char kApnTypeDefault[]; COMPONENT_EXPORT(ONC) extern const char kApnTypeAttach[]; COMPONENT_EXPORT(ONC) extern const char kApnTypeTether[]; +COMPONENT_EXPORT(ONC) extern const char kSource[]; +COMPONENT_EXPORT(ONC) extern const char kSourceUi[]; +COMPONENT_EXPORT(ONC) extern const char kSourceModb[]; +COMPONENT_EXPORT(ONC) extern const char kSourceModem[]; } // namespace cellular_apn namespace cellular_found_network {
diff --git a/components/password_manager/DEPS b/components/password_manager/DEPS index 4a54537..d18c16b 100644 --- a/components/password_manager/DEPS +++ b/components/password_manager/DEPS
@@ -4,6 +4,7 @@ "+components/os_crypt/sync", "+components/prefs", "+components/strings/grit", + "+components/sync/engine", "+components/sync/model", "+components/sync/protocol", "+net/base",
diff --git a/components/password_manager/core/browser/form_parsing/form_data_parser.cc b/components/password_manager/core/browser/form_parsing/form_data_parser.cc index 70aaf3f..1f9bff6 100644 --- a/components/password_manager/core/browser/form_parsing/form_data_parser.cc +++ b/components/password_manager/core/browser/form_parsing/form_data_parser.cc
@@ -33,6 +33,7 @@ #include "components/password_manager/core/browser/password_form.h" #include "components/password_manager/core/common/password_manager_constants.h" #include "components/password_manager/core/common/password_manager_features.h" +#include "components/password_manager/core/common/password_manager_util.h" using autofill::FieldPropertiesFlags; using autofill::FormData; @@ -356,6 +357,11 @@ return nullptr; } +bool CanBeConsideredAsSingleUsernameField(const FormFieldData* field) { + return field && password_manager::util::CanBeConsideredAsSingleUsername( + field->name_attribute, field->id_attribute, field->label); +} + // Given a `new_password` field tries to find a matching confirmation_password // field in `processed_fields` that succeeds `new_password` and has matching // interactability and value. @@ -429,7 +435,8 @@ break; case CredentialFieldType::kSingleUsername: processed_field = FindField(processed_fields, prediction); - if (processed_field) { + if (processed_field && + CanBeConsideredAsSingleUsernameField(processed_field->field)) { result->username = processed_field->field; result->is_single_username = true; base::UmaHistogramBoolean(
diff --git a/components/password_manager/core/browser/form_parsing/form_data_parser_unittest.cc b/components/password_manager/core/browser/form_parsing/form_data_parser_unittest.cc index 119d0bb..30a9bef 100644 --- a/components/password_manager/core/browser/form_parsing/form_data_parser_unittest.cc +++ b/components/password_manager/core/browser/form_parsing/form_data_parser_unittest.cc
@@ -2942,6 +2942,16 @@ .prediction = {.type = autofill::PASSWORD}}, }, }, + { + .description_for_logging = "Field labeled as seach field", + .fields = + { + {.role = ElementRole::NONE, + .name = u"search_bar", + .form_control_type = FormControlType::kInputText, + .prediction = {.type = autofill::SINGLE_USERNAME}}, + }, + }, }); }
diff --git a/components/password_manager/core/browser/password_store/BUILD.gn b/components/password_manager/core/browser/password_store/BUILD.gn index f5ac3c2b..f6f6f8d7 100644 --- a/components/password_manager/core/browser/password_store/BUILD.gn +++ b/components/password_manager/core/browser/password_store/BUILD.gn
@@ -70,6 +70,7 @@ "//components/safe_browsing/core/common:safe_browsing_prefs", "//components/sync/base", "//components/sync/base:features", + "//components/sync/engine", "//components/sync/model", "//components/sync/protocol", "//sql", @@ -80,6 +81,8 @@ if (is_android) { sources += [ "android_backend_error.h", + "password_model_type_controller_delegate_android.cc", + "password_model_type_controller_delegate_android.h", "split_stores_and_local_upm.cc", "split_stores_and_local_upm.h", ]
diff --git a/components/password_manager/core/browser/password_store/password_model_type_controller_delegate_android.cc b/components/password_manager/core/browser/password_store/password_model_type_controller_delegate_android.cc new file mode 100644 index 0000000..15cf260 --- /dev/null +++ b/components/password_manager/core/browser/password_store/password_model_type_controller_delegate_android.cc
@@ -0,0 +1,70 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/password_manager/core/browser/password_store/password_model_type_controller_delegate_android.h" + +#include "base/notreached.h" +#include "components/sync/engine/data_type_activation_response.h" +#include "components/sync/model/type_entities_count.h" + +namespace password_manager { + +PasswordModelTypeConrollerDelegateAndroid:: + PasswordModelTypeConrollerDelegateAndroid() = default; +PasswordModelTypeConrollerDelegateAndroid:: + ~PasswordModelTypeConrollerDelegateAndroid() = default; + +void PasswordModelTypeConrollerDelegateAndroid::OnSyncStarting( + const syncer::DataTypeActivationRequest& request, + StartCallback callback) { + // Set `skip_engine_connection` to true to indicate that, actually, this sync + // datatype doesn't depend on the built-in SyncEngine to communicate changes + // to/from the Sync server. Instead, Android specific functionality is + // leveraged to achieve similar behavior. + auto activation_response = + std::make_unique<syncer::DataTypeActivationResponse>(); + activation_response->skip_engine_connection = true; + std::move(callback).Run(std::move(activation_response)); +} + +void PasswordModelTypeConrollerDelegateAndroid::OnSyncStopping( + syncer::SyncStopMetadataFate metadata_fate) {} + +void PasswordModelTypeConrollerDelegateAndroid::GetAllNodesForDebugging( + AllNodesCallback callback) { + // This is not implemented because it's not worth the hassle just to display + // debug information in chrome://sync-internals. + std::move(callback).Run(syncer::PASSWORDS, base::Value::List()); +} + +void PasswordModelTypeConrollerDelegateAndroid:: + GetTypeEntitiesCountForDebugging( + base::OnceCallback<void(const syncer::TypeEntitiesCount&)> callback) + const { + // This is not implemented because it's not worth the hassle just to display + // debug information in chrome://sync-internals. + std::move(callback).Run(syncer::TypeEntitiesCount(syncer::PASSWORDS)); +} + +void PasswordModelTypeConrollerDelegateAndroid:: + RecordMemoryUsageAndCountsHistograms() { + // This is not implemented because it's not worth the hassle. Password sync + // module on Android doesn't hold any password. Instead passwords are + // requested on demand from the GMS Core. +} + +void PasswordModelTypeConrollerDelegateAndroid::ClearMetadataIfStopped() { + // No metadata is managed by PasswordModelTypeControllerDelegate. +} + +void PasswordModelTypeConrollerDelegateAndroid::ReportBridgeErrorForTest() { + // Not supported for Android. + NOTREACHED(); +} + +base::WeakPtr<syncer::ModelTypeControllerDelegate> +PasswordModelTypeConrollerDelegateAndroid::GetWeakPtrToBaseClass() { + return weak_ptr_factory_.GetWeakPtr(); +} +} // namespace password_manager
diff --git a/components/password_manager/core/browser/password_store/password_model_type_controller_delegate_android.h b/components/password_manager/core/browser/password_store/password_model_type_controller_delegate_android.h new file mode 100644 index 0000000..311c6123 --- /dev/null +++ b/components/password_manager/core/browser/password_store/password_model_type_controller_delegate_android.h
@@ -0,0 +1,50 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_PASSWORD_STORE_PASSWORD_MODEL_TYPE_CONTROLLER_DELEGATE_ANDROID_H_ +#define COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_PASSWORD_STORE_PASSWORD_MODEL_TYPE_CONTROLLER_DELEGATE_ANDROID_H_ + +#include "base/memory/weak_ptr.h" +#include "components/sync/model/model_type_controller_delegate.h" + +namespace password_manager { + +// This class implements `syncer::ModelTypeControllerDelegate` but skips +// conntecting to sync engine. It will be used to disable password sync +// machinery and rely on GMS instead. +class PasswordModelTypeConrollerDelegateAndroid + : public syncer::ModelTypeControllerDelegate { + public: + PasswordModelTypeConrollerDelegateAndroid(); + PasswordModelTypeConrollerDelegateAndroid( + const PasswordModelTypeConrollerDelegateAndroid&) = delete; + PasswordModelTypeConrollerDelegateAndroid( + PasswordModelTypeConrollerDelegateAndroid&&) = delete; + PasswordModelTypeConrollerDelegateAndroid& operator=( + const PasswordModelTypeConrollerDelegateAndroid&) = delete; + PasswordModelTypeConrollerDelegateAndroid& operator=( + PasswordModelTypeConrollerDelegateAndroid&&) = delete; + ~PasswordModelTypeConrollerDelegateAndroid() override; + + // syncer::ModelTypeControllerDelegate implementation. + void OnSyncStarting(const syncer::DataTypeActivationRequest& request, + StartCallback callback) override; + void OnSyncStopping(syncer::SyncStopMetadataFate metadata_fate) override; + void GetAllNodesForDebugging(AllNodesCallback callback) override; + void GetTypeEntitiesCountForDebugging( + base::OnceCallback<void(const syncer::TypeEntitiesCount&)> callback) + const override; + void RecordMemoryUsageAndCountsHistograms() override; + void ClearMetadataIfStopped() override; + void ReportBridgeErrorForTest() override; + + base::WeakPtr<syncer::ModelTypeControllerDelegate> GetWeakPtrToBaseClass(); + + private: + base::WeakPtrFactory<PasswordModelTypeConrollerDelegateAndroid> + weak_ptr_factory_{this}; +}; +} // namespace password_manager + +#endif // COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_PASSWORD_STORE_PASSWORD_MODEL_TYPE_CONTROLLER_DELEGATE_ANDROID_H_
diff --git a/components/password_manager/core/common/password_manager_constants.h b/components/password_manager/core/common/password_manager_constants.h index 8e048514..2dbf520b 100644 --- a/components/password_manager/core/common/password_manager_constants.h +++ b/components/password_manager/core/common/password_manager_constants.h
@@ -63,6 +63,8 @@ inline constexpr char16_t kPhoneValueRe[] = u"^[0-9()+-]{6,25}$"; inline constexpr char16_t kUsernameLikeValueRe[] = u"[A-Za-z0-9_\\-.]{7,30}"; +inline constexpr char16_t kSearch[] = u"search"; + } // namespace password_manager::constants #endif // COMPONENTS_PASSWORD_MANAGER_CORE_COMMON_PASSWORD_MANAGER_CONSTANTS_H_
diff --git a/components/password_manager/core/common/password_manager_util.cc b/components/password_manager/core/common/password_manager_util.cc index dca8fbe..3f6f75b5 100644 --- a/components/password_manager/core/common/password_manager_util.cc +++ b/components/password_manager/core/common/password_manager_util.cc
@@ -4,8 +4,6 @@ #include "components/password_manager/core/common/password_manager_util.h" -#include <string> - #include "base/ranges/algorithm.h" #include "components/autofill/core/common/form_data.h" #include "components/autofill/core/common/form_field_data.h" @@ -28,4 +26,15 @@ }); } +bool CanBeConsideredAsSingleUsername(const std::u16string& name, + const std::u16string& id, + const std::u16string& label) { + return (name.find(password_manager::constants::kSearch) == + std::u16string::npos) && + (id.find(password_manager::constants::kSearch) == + std::u16string::npos) && + (label.find(password_manager::constants::kSearch) == + std::u16string::npos); +} + } // namespace password_manager::util
diff --git a/components/password_manager/core/common/password_manager_util.h b/components/password_manager/core/common/password_manager_util.h index 8806732..c79c322 100644 --- a/components/password_manager/core/common/password_manager_util.h +++ b/components/password_manager/core/common/password_manager_util.h
@@ -5,6 +5,8 @@ #ifndef COMPONENTS_PASSWORD_MANAGER_CORE_COMMON_PASSWORD_MANAGER_UTIL_H_ #define COMPONENTS_PASSWORD_MANAGER_CORE_COMMON_PASSWORD_MANAGER_UTIL_H_ +#include <string> + namespace autofill { struct FormData; } // namespace autofill @@ -16,6 +18,12 @@ // with autocomplete="username", or a textfield with autocomplete="webauthn". bool IsRendererRecognizedCredentialForm(const autofill::FormData& form); +// Returns whether field attributes allow to consider it as a single username +// field (e.g. don't indicate it's a search field). +bool CanBeConsideredAsSingleUsername(const std::u16string& name, + const std::u16string& id, + const std::u16string& label); + } // namespace password_manager::util #endif // COMPONENTS_PASSWORD_MANAGER_CORE_COMMON_PASSWORD_MANAGER_UTIL_H_
diff --git a/components/policy/core/browser/webui/machine_level_user_cloud_policy_status_provider.cc b/components/policy/core/browser/webui/machine_level_user_cloud_policy_status_provider.cc index 5f2fc02f..ef895979 100644 --- a/components/policy/core/browser/webui/machine_level_user_cloud_policy_status_provider.cc +++ b/components/policy/core/browser/webui/machine_level_user_cloud_policy_status_provider.cc
@@ -33,9 +33,6 @@ namespace policy { -const char kDeviceIdKey[] = "deviceId"; -const char kMachineKey[] = "machine"; - MachineLevelUserCloudPolicyStatusProvider:: MachineLevelUserCloudPolicyStatusProvider( CloudPolicyCore* core,
diff --git a/components/policy/core/browser/webui/machine_level_user_cloud_policy_status_provider.h b/components/policy/core/browser/webui/machine_level_user_cloud_policy_status_provider.h index 233fdbb..cd2231c 100644 --- a/components/policy/core/browser/webui/machine_level_user_cloud_policy_status_provider.h +++ b/components/policy/core/browser/webui/machine_level_user_cloud_policy_status_provider.h
@@ -19,8 +19,8 @@ // The following constants identify top-level keys in the dictionary returned by // and are specific to MachineLevelUserCloudPolicyStatusProvider. -POLICY_EXPORT extern const char kDeviceIdKey[]; -POLICY_EXPORT extern const char kMachineKey[]; +inline constexpr char kDeviceIdKey[] = "deviceId"; +inline constexpr char kMachineKey[] = "machine"; struct POLICY_EXPORT MachineLevelUserCloudPolicyContext { std::string enrollmentToken;
diff --git a/components/policy/core/browser/webui/policy_status_provider.cc b/components/policy/core/browser/webui/policy_status_provider.cc index a46ae1e4..7c24e13 100644 --- a/components/policy/core/browser/webui/policy_status_provider.cc +++ b/components/policy/core/browser/webui/policy_status_provider.cc
@@ -26,19 +26,6 @@ namespace policy { -const char kPolicyDescriptionKey[] = "policyDescriptionKey"; -const char kFlexOrgWarningKey[] = "flexOrgWarning"; - -const char kAssetIdKey[] = "assetId"; -const char kLocationKey[] = "location"; -const char kDirectoryApiIdKey[] = "directoryApiId"; -const char kGaiaIdKey[] = "gaiaId"; -const char kClientIdKey[] = "clientId"; -const char kUsernameKey[] = "username"; -const char kEnterpriseDomainManagerKey[] = "enterpriseDomainManager"; -const char kDomainKey[] = "domain"; -const char kEnrollmentTokenKey[] = "enrollmentToken"; - namespace { // Formats the association state indicated by |data|. If |data| is NULL, the
diff --git a/components/policy/core/browser/webui/policy_status_provider.h b/components/policy/core/browser/webui/policy_status_provider.h index d6da2b3..e40c57b9 100644 --- a/components/policy/core/browser/webui/policy_status_provider.h +++ b/components/policy/core/browser/webui/policy_status_provider.h
@@ -28,20 +28,20 @@ class CloudPolicyCore; class CloudPolicyStore; -POLICY_EXPORT extern const char kPolicyDescriptionKey[]; -POLICY_EXPORT extern const char kFlexOrgWarningKey[]; +inline constexpr char kPolicyDescriptionKey[] = "policyDescriptionKey"; +inline constexpr char kFlexOrgWarningKey[] = "flexOrgWarning"; // The following constants identify top-level keys in the dictionary returned by // PolicyStatusProvider. -POLICY_EXPORT extern const char kAssetIdKey[]; -POLICY_EXPORT extern const char kLocationKey[]; -POLICY_EXPORT extern const char kDirectoryApiIdKey[]; -POLICY_EXPORT extern const char kGaiaIdKey[]; -POLICY_EXPORT extern const char kClientIdKey[]; -POLICY_EXPORT extern const char kUsernameKey[]; -POLICY_EXPORT extern const char kEnterpriseDomainManagerKey[]; -POLICY_EXPORT extern const char kDomainKey[]; -POLICY_EXPORT extern const char kEnrollmentTokenKey[]; +inline constexpr char kAssetIdKey[] = "assetId"; +inline constexpr char kLocationKey[] = "location"; +inline constexpr char kDirectoryApiIdKey[] = "directoryApiId"; +inline constexpr char kGaiaIdKey[] = "gaiaId"; +inline constexpr char kClientIdKey[] = "clientId"; +inline constexpr char kUsernameKey[] = "username"; +inline constexpr char kEnterpriseDomainManagerKey[] = "enterpriseDomainManager"; +inline constexpr char kDomainKey[] = "domain"; +inline constexpr char kEnrollmentTokenKey[] = "enrollmentToken"; // An interface for querying the status of a policy provider. It surfaces // things like last fetch time or status of the backing store, but not the
diff --git a/components/policy/core/common/policy_logger.cc b/components/policy/core/common/policy_logger.cc index 35795614..7039ad0 100644 --- a/components/policy/core/common/policy_logger.cc +++ b/components/policy/core/common/policy_logger.cc
@@ -8,6 +8,7 @@ #include <string_view> #include <utility> +#include "base/check_is_test.h" #include "base/functional/bind.h" #include "base/i18n/time_formatting.h" #include "base/no_destructor.h" @@ -221,11 +222,13 @@ } size_t PolicyLogger::GetPolicyLogsSizeForTesting() { + CHECK_IS_TEST(); base::AutoLock lock(lock_); return logs_.size(); } -void PolicyLogger::ResetLoggerAfterTest() { +void PolicyLogger::ResetLoggerForTesting() { + CHECK_IS_TEST(); base::AutoLock lock(lock_); logs_.erase(logs_.begin(), logs_.end()); is_log_deletion_scheduled_ = false;
diff --git a/components/policy/core/common/policy_logger.h b/components/policy/core/common/policy_logger.h index 6b871bb..87fd342 100644 --- a/components/policy/core/common/policy_logger.h +++ b/components/policy/core/common/policy_logger.h
@@ -164,7 +164,7 @@ // Clears `logs_` and sets `is_log_deletion_scheduled_` as cleanup after every // test. - void ResetLoggerAfterTest(); + void ResetLoggerForTesting(); private: // Adds a new log to the logs_ list and calls `ScheduleOldLogsDeletion` if
diff --git a/components/policy/core/common/policy_logger_unittest.cc b/components/policy/core/common/policy_logger_unittest.cc index 621af54..f6c1e3a 100644 --- a/components/policy/core/common/policy_logger_unittest.cc +++ b/components/policy/core/common/policy_logger_unittest.cc
@@ -36,9 +36,8 @@ // Clears the logs list and resets the deletion flag before the test and its // tasks are deleted. This is important to prevent tests from affecting each // other's results. - void TearDown() override { - policy::PolicyLogger::GetInstance()->ResetLoggerAfterTest(); - PlatformTest::TearDown(); + void SetUp() override { + policy::PolicyLogger::GetInstance()->ResetLoggerForTesting(); } base::test::ScopedFeatureList scoped_feature_list_;
diff --git a/components/policy/resources/templates/policies.yaml b/components/policy/resources/templates/policies.yaml index 208e71c..0ac9c82 100644 --- a/components/policy/resources/templates/policies.yaml +++ b/components/policy/resources/templates/policies.yaml
@@ -1238,6 +1238,7 @@ 1237: EnterpriseLogoUrl 1238: CustomProfileLabel 1239: ProfileLabel + 1240: PrivacySandboxFingerprintingProtectionEnabled atomic_groups: 1: Homepage 2: RemoteAccess
diff --git a/components/policy/resources/templates/policy_definitions/PrivacySandbox/PrivacySandboxFingerprintingProtectionEnabled.yaml b/components/policy/resources/templates/policy_definitions/PrivacySandbox/PrivacySandboxFingerprintingProtectionEnabled.yaml new file mode 100644 index 0000000..ab7b7ed --- /dev/null +++ b/components/policy/resources/templates/policy_definitions/PrivacySandbox/PrivacySandboxFingerprintingProtectionEnabled.yaml
@@ -0,0 +1,28 @@ +caption: Choose whether the <ph name="PRIVACY_SANDBOX_NAME">Privacy Sandbox</ph> Fingerprinting Protection feature is to be enabled. +default: false +desc: |- + A policy to control whether the <ph name="PRIVACY_SANDBOX_NAME">Privacy Sandbox</ph> Fingerprinting Protection setting is to be enabled or disabled for your users. + + If you set this policy to Disabled, then the Fingerprinting Protection feature setting will be turned off for your users. + If you set this policy to Enabled, your users will have the Fingerprinting Protection feature setting turned on. + If the policy is not set, users will be able to turn on or off the Fingerprinting Protection feature in their UI settings. The default state will be false or disabled, meaning the Fingerprinting Protection feature will be turned off. +example_value: true +features: + dynamic_refresh: true + per_profile: true +items: +- caption: Enable the Fingerprinting Protection feature. + value: true +- caption: Disable the Fingerprinting Protection feature. + value: false +owners: +- johnykim@google.com +- file://components/privacy_sandbox/OWNERS +schema: + type: boolean +supported_on: + - chrome.*:124- + - chrome_os:124- + - android:124- +tags: [] +type: main
diff --git a/components/policy/test/data/pref_mapping/PrivacySandboxFingerprintingProtectionEnabled.json b/components/policy/test/data/pref_mapping/PrivacySandboxFingerprintingProtectionEnabled.json new file mode 100644 index 0000000..042b024b --- /dev/null +++ b/components/policy/test/data/pref_mapping/PrivacySandboxFingerprintingProtectionEnabled.json
@@ -0,0 +1,20 @@ +[ + { + "os": [ + "win", + "linux", + "mac", + "chromeos_ash", + "chromeos_lacros", + "android" + ], + "simple_policy_pref_mapping_test": { + "pref_name": "tracking_protection.fingerprinting_protection_enabled", + "default_value": false, + "values_to_test": [ + true, + false + ] + } + } +]
diff --git a/components/proxy_config/BUILD.gn b/components/proxy_config/BUILD.gn index a8bc0e37..44934fee 100644 --- a/components/proxy_config/BUILD.gn +++ b/components/proxy_config/BUILD.gn
@@ -13,7 +13,6 @@ "proxy_config_dictionary.cc", "proxy_config_dictionary.h", "proxy_config_export.h", - "proxy_config_pref_names.cc", "proxy_config_pref_names.h", "proxy_prefs.cc", "proxy_prefs.h",
diff --git a/components/proxy_config/proxy_config_pref_names.cc b/components/proxy_config/proxy_config_pref_names.cc deleted file mode 100644 index a63c49a..0000000 --- a/components/proxy_config/proxy_config_pref_names.cc +++ /dev/null
@@ -1,18 +0,0 @@ -// Copyright 2015 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/proxy_config/proxy_config_pref_names.h" - -namespace proxy_config { -namespace prefs { - -// Preference to store proxy settings. -const char kProxy[] = "proxy"; - -// A boolean pref that controls whether proxy settings from shared network -// settings (accordingly from device policy) are applied or ignored. -const char kUseSharedProxies[] = "settings.use_shared_proxies"; - -} // namespace prefs -} // namespace proxy_config
diff --git a/components/proxy_config/proxy_config_pref_names.h b/components/proxy_config/proxy_config_pref_names.h index 4b1c165..02826f9 100644 --- a/components/proxy_config/proxy_config_pref_names.h +++ b/components/proxy_config/proxy_config_pref_names.h
@@ -5,15 +5,15 @@ #ifndef COMPONENTS_PROXY_CONFIG_PROXY_CONFIG_PREF_NAMES_H_ #define COMPONENTS_PROXY_CONFIG_PROXY_CONFIG_PREF_NAMES_H_ -#include "components/proxy_config/proxy_config_export.h" +namespace proxy_config::prefs { -namespace proxy_config { -namespace prefs { +// Preference to store proxy settings. +inline constexpr char kProxy[] = "proxy"; -PROXY_CONFIG_EXPORT extern const char kProxy[]; -PROXY_CONFIG_EXPORT extern const char kUseSharedProxies[]; +// A boolean pref that controls whether proxy settings from shared network +// settings (accordingly from device policy) are applied or ignored. +inline constexpr char kUseSharedProxies[] = "settings.use_shared_proxies"; -} // namespace prefs -} // namespace proxy_config +} // namespace proxy_config::prefs #endif // COMPONENTS_PROXY_CONFIG_PROXY_CONFIG_PREF_NAMES_H_
diff --git a/components/safe_browsing/android/remote_database_manager.cc b/components/safe_browsing/android/remote_database_manager.cc index 88d0ef8e..29f2257 100644 --- a/components/safe_browsing/android/remote_database_manager.cc +++ b/components/safe_browsing/android/remote_database_manager.cc
@@ -303,8 +303,8 @@ base::BindOnce(&ClientRequest::OnRequestDoneWeak, req->GetWeakPtr())); SafeBrowsingApiHandlerBridge::GetInstance().StartHashDatabaseUrlCheck( std::move(callback), url, - CreateSBThreatTypeSet( - {SB_THREAT_TYPE_SUBRESOURCE_FILTER, SB_THREAT_TYPE_URL_PHISHING})); + CreateSBThreatTypeSet({SBThreatType::SB_THREAT_TYPE_SUBRESOURCE_FILTER, + SBThreatType::SB_THREAT_TYPE_URL_PHISHING})); current_requests_.push_back(req.release()); @@ -380,7 +380,7 @@ for (safe_browsing::RemoteSafeBrowsingDatabaseManager::ClientRequest* req : to_callback) { DVLOG(1) << "Stopping: Invoking unfinished req for URL " << req->url(); - req->OnRequestDone(SB_THREAT_TYPE_SAFE, ThreatMetadata()); + req->OnRequestDone(SBThreatType::SB_THREAT_TYPE_SAFE, ThreatMetadata()); } enabled_ = false;
diff --git a/components/safe_browsing/android/remote_database_manager_unittest.cc b/components/safe_browsing/android/remote_database_manager_unittest.cc index 83de837..a4d8856e 100644 --- a/components/safe_browsing/android/remote_database_manager_unittest.cc +++ b/components/safe_browsing/android/remote_database_manager_unittest.cc
@@ -107,6 +107,8 @@ class RemoteDatabaseManagerTest : public testing::Test { protected: + using enum SBThreatType; + RemoteDatabaseManagerTest() {} void SetUp() override {
diff --git a/components/safe_browsing/android/safe_browsing_api_handler_bridge.cc b/components/safe_browsing/android/safe_browsing_api_handler_bridge.cc index af9e42a..a242df1 100644 --- a/components/safe_browsing/android/safe_browsing_api_handler_bridge.cc +++ b/components/safe_browsing/android/safe_browsing_api_handler_bridge.cc
@@ -276,6 +276,7 @@ // a few. SafetyNetJavaThreatType SBThreatTypeToSafetyNetJavaThreatType( const SBThreatType& sb_threat_type) { + using enum SBThreatType; switch (sb_threat_type) { case SB_THREAT_TYPE_BILLING: return SafetyNetJavaThreatType::BILLING; @@ -313,6 +314,7 @@ // Convert a Java threat type for SafeBrowsing to a SBThreatType. SBThreatType SafeBrowsingJavaToSBThreatType( SafeBrowsingJavaThreatType java_threat_num) { + using enum SBThreatType; switch (java_threat_num) { case SafeBrowsingJavaThreatType::NO_THREAT: return SB_THREAT_TYPE_SAFE; @@ -334,6 +336,7 @@ // support a few. SafeBrowsingJavaThreatType SBThreatTypeToSafeBrowsingApiJavaThreatType( const SBThreatType& sb_threat_type) { + using enum SBThreatType; switch (sb_threat_type) { case SB_THREAT_TYPE_URL_PHISHING: return SafeBrowsingJavaThreatType::SOCIAL_ENGINEERING; @@ -356,13 +359,14 @@ const SBThreatTypeSet& threat_types) { DCHECK_LT(0u, threat_types.size()); size_t threat_type_size = - base::Contains(threat_types, SB_THREAT_TYPE_SUBRESOURCE_FILTER) + base::Contains(threat_types, + SBThreatType::SB_THREAT_TYPE_SUBRESOURCE_FILTER) ? threat_types.size() + 1 : threat_types.size(); int int_threat_types[threat_type_size]; int* itr = &int_threat_types[0]; for (auto threat_type : threat_types) { - if (threat_type == SB_THREAT_TYPE_SUBRESOURCE_FILTER) { + if (threat_type == SBThreatType::SB_THREAT_TYPE_SUBRESOURCE_FILTER) { *itr++ = static_cast<int>( SafeBrowsingJavaThreatType::ABUSIVE_EXPERIENCE_VIOLATION); *itr++ = @@ -471,14 +475,16 @@ DCHECK_EQ(result_status, SafetyNetRemoteCallResultStatus::INTERNAL_ERROR); ReportUmaResult(UmaRemoteCallResult::INTERNAL_ERROR); } - std::move(*callback).Run(SB_THREAT_TYPE_SAFE, ThreatMetadata()); + std::move(*callback).Run(SBThreatType::SB_THREAT_TYPE_SAFE, + ThreatMetadata()); return; } // Shortcut for safe, so we don't have to parse JSON. if (metadata == "{}") { ReportUmaResult(UmaRemoteCallResult::SAFE); - std::move(*callback).Run(SB_THREAT_TYPE_SAFE, ThreatMetadata()); + std::move(*callback).Run(SBThreatType::SB_THREAT_TYPE_SAFE, + ThreatMetadata()); } else { // Unsafe, assuming we can parse the JSON. SBThreatType worst_threat; @@ -553,7 +559,7 @@ if (!IsResponseFromJavaValid(callback->protocol, lookup_result, threat_type, threat_attributes, response_status)) { std::move(*(callback->response_callback)) - .Run(SB_THREAT_TYPE_SAFE, ThreatMetadata()); + .Run(SBThreatType::SB_THREAT_TYPE_SAFE, ThreatMetadata()); return; } @@ -563,7 +569,7 @@ .OnSafeBrowsingApiNonRecoverableFailure(); } std::move(*(callback->response_callback)) - .Run(SB_THREAT_TYPE_SAFE, ThreatMetadata()); + .Run(SBThreatType::SB_THREAT_TYPE_SAFE, ThreatMetadata()); return; } @@ -657,8 +663,9 @@ // Mark all requests as safe. Only users who have an old, broken GMSCore or // have sideloaded Chrome w/o PlayStore should land here. content::GetUIThreadTaskRunner({})->PostTask( - FROM_HERE, base::BindOnce(std::move(*callback), SB_THREAT_TYPE_SAFE, - ThreatMetadata())); + FROM_HERE, + base::BindOnce(std::move(*callback), SBThreatType::SB_THREAT_TYPE_SAFE, + ThreatMetadata())); ReportUmaResult(UmaRemoteCallResult::UNSUPPORTED); return; } @@ -720,7 +727,8 @@ bool SafeBrowsingApiHandlerBridge::StartCSDAllowlistCheck(const GURL& url) { if (interceptor_for_testing_) return false; - return StartAllowlistCheck(url, safe_browsing::SB_THREAT_TYPE_CSD_ALLOWLIST); + return StartAllowlistCheck( + url, safe_browsing::SBThreatType::SB_THREAT_TYPE_CSD_ALLOWLIST); } void SafeBrowsingApiHandlerBridge::OnSafeBrowsingApiNonRecoverableFailure() {
diff --git a/components/safe_browsing/android/safe_browsing_api_handler_bridge_unittest.cc b/components/safe_browsing/android/safe_browsing_api_handler_bridge_unittest.cc index 007874c..2519a07 100644 --- a/components/safe_browsing/android/safe_browsing_api_handler_bridge_unittest.cc +++ b/components/safe_browsing/android/safe_browsing_api_handler_bridge_unittest.cc
@@ -53,9 +53,10 @@ } SBThreatTypeSet GetAllThreatTypes() { - return CreateSBThreatTypeSet( - {SB_THREAT_TYPE_URL_UNWANTED, SB_THREAT_TYPE_URL_MALWARE, - SB_THREAT_TYPE_URL_PHISHING, SB_THREAT_TYPE_BILLING}); + return CreateSBThreatTypeSet({SBThreatType::SB_THREAT_TYPE_URL_UNWANTED, + SBThreatType::SB_THREAT_TYPE_URL_MALWARE, + SBThreatType::SB_THREAT_TYPE_URL_PHISHING, + SBThreatType::SB_THREAT_TYPE_BILLING}); } } // namespace @@ -82,6 +83,8 @@ } protected: + using enum SBThreatType; + void AddSafetyNetBlocklistResponse(const GURL& url, const std::string& metadata, const std::vector<SafetyNetJavaThreatType>&
diff --git a/components/safe_browsing/android/safe_browsing_api_handler_util.cc b/components/safe_browsing/android/safe_browsing_api_handler_util.cc index 435c4b5..5d58cb8 100644 --- a/components/safe_browsing/android/safe_browsing_api_handler_util.cc +++ b/components/safe_browsing/android/safe_browsing_api_handler_util.cc
@@ -80,6 +80,7 @@ SBThreatType SafetyNetJavaToSBThreatType( SafetyNetJavaThreatType java_threat_num) { + using enum SBThreatType; switch (java_threat_num) { case SafetyNetJavaThreatType::POTENTIALLY_HARMFUL_APPLICATION: return SB_THREAT_TYPE_URL_MALWARE; @@ -109,7 +110,8 @@ UmaRemoteCallResult ParseJsonFromGMSCore(const std::string& metadata_str, SBThreatType* worst_sb_threat_type, ThreatMetadata* metadata) { - *worst_sb_threat_type = SB_THREAT_TYPE_SAFE; // Default to safe. + *worst_sb_threat_type = + SBThreatType::SB_THREAT_TYPE_SAFE; // Default to safe. *metadata = ThreatMetadata(); // Default values. if (metadata_str.empty()) @@ -161,12 +163,15 @@ } *worst_sb_threat_type = SafetyNetJavaToSBThreatType(worst_threat_type); - if (*worst_sb_threat_type == SB_THREAT_TYPE_SAFE || !worst_match) + if (*worst_sb_threat_type == SBThreatType::SB_THREAT_TYPE_SAFE || + !worst_match) { return UmaRemoteCallResult::JSON_UNKNOWN_THREAT; + } // Fill in the metadata metadata->population_id = ParseUserPopulation(*worst_match); - if (*worst_sb_threat_type == SB_THREAT_TYPE_SUBRESOURCE_FILTER) { + if (*worst_sb_threat_type == + SBThreatType::SB_THREAT_TYPE_SUBRESOURCE_FILTER) { metadata->subresource_filter_match = ParseSubresourceFilterMatch(*worst_match); }
diff --git a/components/safe_browsing/android/safe_browsing_api_handler_util_unittest.cc b/components/safe_browsing/android/safe_browsing_api_handler_util_unittest.cc index e1a975c..b79a2f5 100644 --- a/components/safe_browsing/android/safe_browsing_api_handler_util_unittest.cc +++ b/components/safe_browsing/android/safe_browsing_api_handler_util_unittest.cc
@@ -16,6 +16,8 @@ class SafeBrowsingApiHandlerUtilTest : public ::testing::Test { protected: + using enum SBThreatType; + SBThreatType threat_; ThreatMetadata meta_; const ThreatMetadata empty_meta_;
diff --git a/components/safe_browsing/content/browser/async_check_tracker_unittest.cc b/components/safe_browsing/content/browser/async_check_tracker_unittest.cc index 5562a27..5654313 100644 --- a/components/safe_browsing/content/browser/async_check_tracker_unittest.cc +++ b/components/safe_browsing/content/browser/async_check_tracker_unittest.cc
@@ -94,7 +94,7 @@ // load_post_commit_error_page is false. UnsafeResource resource; resource.url = url_; - resource.threat_type = SB_THREAT_TYPE_URL_PHISHING; + resource.threat_type = SBThreatType::SB_THREAT_TYPE_URL_PHISHING; resource.navigation_id = navigation_id; ui_manager_->AddUnsafeResource(url_, resource); } @@ -208,7 +208,7 @@ CallDidFinishNavigation(handle, /*has_committed=*/true); EXPECT_EQ(ui_manager_->DisplayBlockingPageCalledTimes(), 1); UnsafeResource resource = ui_manager_->GetDisplayedResource(); - EXPECT_EQ(resource.threat_type, SB_THREAT_TYPE_URL_PHISHING); + EXPECT_EQ(resource.threat_type, SBThreatType::SB_THREAT_TYPE_URL_PHISHING); EXPECT_EQ(resource.url, url_); EXPECT_EQ(resource.render_process_id, main_rfh()->GetGlobalId().child_id); EXPECT_EQ(resource.render_frame_token, main_rfh()->GetFrameToken().value()); @@ -234,7 +234,7 @@ /*all_checks_completed=*/true); EXPECT_EQ(ui_manager_->DisplayBlockingPageCalledTimes(), 1); UnsafeResource resource = ui_manager_->GetDisplayedResource(); - EXPECT_EQ(resource.threat_type, SB_THREAT_TYPE_URL_PHISHING); + EXPECT_EQ(resource.threat_type, SBThreatType::SB_THREAT_TYPE_URL_PHISHING); EXPECT_EQ(resource.url, url_); EXPECT_EQ(resource.render_process_id, main_rfh()->GetGlobalId().child_id); EXPECT_EQ(resource.render_frame_token, main_rfh()->GetFrameToken().value()); @@ -245,7 +245,7 @@ base::HistogramTester histograms; content::MockNavigationHandle handle(web_contents()); UnsafeResource resource; - resource.threat_type = SB_THREAT_TYPE_URL_PHISHING; + resource.threat_type = SBThreatType::SB_THREAT_TYPE_URL_PHISHING; resource.frame_tree_node_id = main_rfh()->GetFrameTreeNodeId(); resource.navigation_id = handle.GetNavigationId(); @@ -273,7 +273,7 @@ TEST_F(AsyncCheckTrackerTest, IsMainPageLoadPending_NoNavigationId) { content::MockNavigationHandle handle(web_contents()); UnsafeResource resource; - resource.threat_type = SB_THREAT_TYPE_URL_PHISHING; + resource.threat_type = SBThreatType::SB_THREAT_TYPE_URL_PHISHING; resource.frame_tree_node_id = main_rfh()->GetFrameTreeNodeId(); EXPECT_TRUE(AsyncCheckTracker::IsMainPageLoadPending(resource)); @@ -281,7 +281,7 @@ // If there is no navigation id associated with the resource, whether the // main page load is pending is determined by // UnsafeResource::IsMainPageLoadPendingWithSyncCheck. - resource.threat_type = SB_THREAT_TYPE_URL_CLIENT_SIDE_PHISHING; + resource.threat_type = SBThreatType::SB_THREAT_TYPE_URL_CLIENT_SIDE_PHISHING; EXPECT_FALSE(AsyncCheckTracker::IsMainPageLoadPending(resource)); } @@ -290,7 +290,7 @@ tracker_->SetNavigationTimestampsSizeThresholdForTesting( kLocalNavigationTimestampsSizeThreshold); UnsafeResource resource; - resource.threat_type = SB_THREAT_TYPE_URL_PHISHING; + resource.threat_type = SBThreatType::SB_THREAT_TYPE_URL_PHISHING; resource.frame_tree_node_id = main_rfh()->GetFrameTreeNodeId(); std::vector<int64_t> old_navigation_ids; @@ -335,7 +335,7 @@ tracker_->SetNavigationTimestampsSizeThresholdForTesting( kLocalNavigationTimestampsSizeThreshold); UnsafeResource resource; - resource.threat_type = SB_THREAT_TYPE_URL_PHISHING; + resource.threat_type = SBThreatType::SB_THREAT_TYPE_URL_PHISHING; resource.frame_tree_node_id = main_rfh()->GetFrameTreeNodeId(); content::MockNavigationHandle handle(url_, main_rfh()); @@ -362,7 +362,7 @@ TEST_F(AsyncCheckTrackerTest, GetBlockedPageCommittedTimestamp) { content::MockNavigationHandle handle(web_contents()); UnsafeResource resource; - resource.threat_type = SB_THREAT_TYPE_URL_PHISHING; + resource.threat_type = SBThreatType::SB_THREAT_TYPE_URL_PHISHING; resource.frame_tree_node_id = main_rfh()->GetFrameTreeNodeId(); resource.navigation_id = handle.GetNavigationId();
diff --git a/components/safe_browsing/content/browser/base_blocking_page.cc b/components/safe_browsing/content/browser/base_blocking_page.cc index e615454f..29ae339f 100644 --- a/components/safe_browsing/content/browser/base_blocking_page.cc +++ b/components/safe_browsing/content/browser/base_blocking_page.cc
@@ -207,6 +207,8 @@ security_interstitials::BaseSafeBrowsingErrorUI::SBInterstitialReason BaseBlockingPage::GetInterstitialReason( const UnsafeResourceList& unsafe_resources) { + using enum SBThreatType; + bool harmful = false; for (auto iter = unsafe_resources.begin(); iter != unsafe_resources.end(); ++iter) { @@ -349,6 +351,7 @@ // static bool BaseBlockingPage::ShouldReportThreatDetails(SBThreatType threat_type) { + using enum SBThreatType; return threat_type == SB_THREAT_TYPE_BILLING || threat_type == SB_THREAT_TYPE_URL_CLIENT_SIDE_PHISHING || threat_type == SB_THREAT_TYPE_URL_MALWARE ||
diff --git a/components/safe_browsing/content/browser/base_ui_manager.cc b/components/safe_browsing/content/browser/base_ui_manager.cc index cbf152c..1998f20 100644 --- a/components/safe_browsing/content/browser/base_ui_manager.cc +++ b/components/safe_browsing/content/browser/base_ui_manager.cc
@@ -152,32 +152,33 @@ // Returns the corresponding ThreatSeverity to a SBThreatType // Keep the same as v4_local_database_manager GetThreatSeverity() ThreatSeverity GetThreatSeverity(safe_browsing::SBThreatType threat_type) { + using enum SBThreatType; switch (threat_type) { - case safe_browsing::SB_THREAT_TYPE_URL_MALWARE: - case safe_browsing::SB_THREAT_TYPE_URL_BINARY_MALWARE: - case safe_browsing::SB_THREAT_TYPE_URL_PHISHING: - case safe_browsing::SB_THREAT_TYPE_MANAGED_POLICY_BLOCK: - case safe_browsing::SB_THREAT_TYPE_MANAGED_POLICY_WARN: + case SB_THREAT_TYPE_URL_MALWARE: + case SB_THREAT_TYPE_URL_BINARY_MALWARE: + case SB_THREAT_TYPE_URL_PHISHING: + case SB_THREAT_TYPE_MANAGED_POLICY_BLOCK: + case SB_THREAT_TYPE_MANAGED_POLICY_WARN: return 0; - case safe_browsing::SB_THREAT_TYPE_URL_UNWANTED: + case SB_THREAT_TYPE_URL_UNWANTED: return 1; - case safe_browsing::SB_THREAT_TYPE_API_ABUSE: - case safe_browsing::SB_THREAT_TYPE_URL_CLIENT_SIDE_PHISHING: - case safe_browsing::SB_THREAT_TYPE_SUBRESOURCE_FILTER: - case safe_browsing::SB_THREAT_TYPE_SIGNED_IN_SYNC_PASSWORD_REUSE: - case safe_browsing::SB_THREAT_TYPE_ENTERPRISE_PASSWORD_REUSE: - case safe_browsing::SB_THREAT_TYPE_SAVED_PASSWORD_REUSE: - case safe_browsing::SB_THREAT_TYPE_SIGNED_IN_NON_SYNC_PASSWORD_REUSE: + case SB_THREAT_TYPE_API_ABUSE: + case SB_THREAT_TYPE_URL_CLIENT_SIDE_PHISHING: + case SB_THREAT_TYPE_SUBRESOURCE_FILTER: + case SB_THREAT_TYPE_SIGNED_IN_SYNC_PASSWORD_REUSE: + case SB_THREAT_TYPE_ENTERPRISE_PASSWORD_REUSE: + case SB_THREAT_TYPE_SAVED_PASSWORD_REUSE: + case SB_THREAT_TYPE_SIGNED_IN_NON_SYNC_PASSWORD_REUSE: return 2; - case safe_browsing::SB_THREAT_TYPE_CSD_ALLOWLIST: - case safe_browsing::SB_THREAT_TYPE_HIGH_CONFIDENCE_ALLOWLIST: + case SB_THREAT_TYPE_CSD_ALLOWLIST: + case SB_THREAT_TYPE_HIGH_CONFIDENCE_ALLOWLIST: return 3; - case safe_browsing::SB_THREAT_TYPE_SUSPICIOUS_SITE: + case SB_THREAT_TYPE_SUSPICIOUS_SITE: return 4; - case safe_browsing::SB_THREAT_TYPE_BILLING: + case SB_THREAT_TYPE_BILLING: return 15; - case safe_browsing::SB_THREAT_TYPE_UNUSED: - case safe_browsing::SB_THREAT_TYPE_SAFE: + case SB_THREAT_TYPE_UNUSED: + case SB_THREAT_TYPE_SAFE: return std::numeric_limits<ThreatSeverity>::max(); default: NOTREACHED(); @@ -240,7 +241,7 @@ continue; } - SBThreatType url_threat_type = SB_THREAT_TYPE_SAFE; + SBThreatType url_threat_type = SBThreatType::SB_THREAT_TYPE_SAFE; bool allowlisted = site_list->Contains(lookup_url, &url_threat_type); // We only check if the url is in the non-pending allowlist if // allowlist_only is true. @@ -249,9 +250,10 @@ } if (allowlisted) { any_allowlisted = true; - ThreatSeverity severity = url_threat_type == SB_THREAT_TYPE_SAFE - ? std::numeric_limits<ThreatSeverity>::max() - : GetThreatSeverity(url_threat_type); + ThreatSeverity severity = + url_threat_type == SBThreatType::SB_THREAT_TYPE_SAFE + ? std::numeric_limits<ThreatSeverity>::max() + : GetThreatSeverity(url_threat_type); if (severity > min_severity) { continue; } @@ -289,6 +291,8 @@ } void BaseUIManager::DisplayBlockingPage(const UnsafeResource& resource) { + using enum SBThreatType; + DCHECK_CURRENTLY_ON(BrowserThread::UI); bool is_frame = resource.is_subframe || resource.request_destination ==
diff --git a/components/safe_browsing/content/browser/client_report_util.cc b/components/safe_browsing/content/browser/client_report_util.cc index 81d87761..82d1c6f5 100644 --- a/components/safe_browsing/content/browser/client_report_util.cc +++ b/components/safe_browsing/content/browser/client_report_util.cc
@@ -31,6 +31,8 @@ } CSBRR::ReportType GetReportTypeFromSBThreatType(SBThreatType threat_type) { + using enum SBThreatType; + switch (threat_type) { case SB_THREAT_TYPE_URL_PHISHING: return CSBRR::URL_PHISHING; @@ -72,13 +74,15 @@ case SB_THREAT_TYPE_MANAGED_POLICY_BLOCK: // Gated by SafeBrowsingBlockingPage::ShouldReportThreatDetails. NOTREACHED() << "We should not send report for threat type: " - << threat_type; + << static_cast<int>(threat_type); return CSBRR::UNKNOWN; } } CSBRR::WarningShownInfo::WarningUXType GetWarningUXTypeFromSBThreatType( SBThreatType threat_type) { + using enum SBThreatType; + switch (threat_type) { case SB_THREAT_TYPE_URL_PHISHING: return CSBRR::WarningShownInfo::PHISHING_INTERSTITIAL; @@ -113,7 +117,7 @@ case SB_THREAT_TYPE_MANAGED_POLICY_WARN: case SB_THREAT_TYPE_MANAGED_POLICY_BLOCK: NOTREACHED() << "We should not send report for threat type: " - << threat_type; + << static_cast<int>(threat_type); return CSBRR::WarningShownInfo::UNKNOWN; } }
diff --git a/components/safe_browsing/content/browser/client_report_util_unittest.cc b/components/safe_browsing/content/browser/client_report_util_unittest.cc index 15d0202..4b25292 100644 --- a/components/safe_browsing/content/browser/client_report_util_unittest.cc +++ b/components/safe_browsing/content/browser/client_report_util_unittest.cc
@@ -18,7 +18,7 @@ security_interstitials::UnsafeResource resource = security_interstitials::UnsafeResource(); resource.url = GURL(kPhishingUrl); - resource.threat_type = SB_THREAT_TYPE_URL_PHISHING; + resource.threat_type = SBThreatType::SB_THREAT_TYPE_URL_PHISHING; resource.request_destination = network::mojom::RequestDestination::kDocument; return resource;
diff --git a/components/safe_browsing/content/browser/client_side_detection_host.cc b/components/safe_browsing/content/browser/client_side_detection_host.cc index 8dcf0d44..d960b5f 100644 --- a/components/safe_browsing/content/browser/client_side_detection_host.cc +++ b/components/safe_browsing/content/browser/client_side_detection_host.cc
@@ -793,7 +793,8 @@ resource.url = phishing_url; resource.original_url = phishing_url; resource.is_subresource = false; - resource.threat_type = SB_THREAT_TYPE_URL_CLIENT_SIDE_PHISHING; + resource.threat_type = + SBThreatType::SB_THREAT_TYPE_URL_CLIENT_SIDE_PHISHING; resource.threat_source = safe_browsing::ThreatSource::CLIENT_SIDE_DETECTION; resource.render_process_id = primary_main_frame_id.child_id;
diff --git a/components/safe_browsing/content/browser/triggers/ad_sampler_trigger.cc b/components/safe_browsing/content/browser/triggers/ad_sampler_trigger.cc index a882aafe..b811464 100644 --- a/components/safe_browsing/content/browser/triggers/ad_sampler_trigger.cc +++ b/components/safe_browsing/content/browser/triggers/ad_sampler_trigger.cc
@@ -138,7 +138,7 @@ const content::GlobalRenderFrameHostId primary_main_frame_id = primary_main_frame->GetGlobalId(); security_interstitials::UnsafeResource resource; - resource.threat_type = SB_THREAT_TYPE_AD_SAMPLE; + resource.threat_type = SBThreatType::SB_THREAT_TYPE_AD_SAMPLE; resource.url = web_contents()->GetURL(); resource.render_process_id = primary_main_frame_id.child_id; resource.render_frame_token = primary_main_frame->GetFrameToken().value();
diff --git a/components/safe_browsing/content/browser/triggers/suspicious_site_trigger.cc b/components/safe_browsing/content/browser/triggers/suspicious_site_trigger.cc index 8f5e6cb..b12fb3c 100644 --- a/components/safe_browsing/content/browser/triggers/suspicious_site_trigger.cc +++ b/components/safe_browsing/content/browser/triggers/suspicious_site_trigger.cc
@@ -92,7 +92,7 @@ primary_rfh.GetGlobalId(); security_interstitials::UnsafeResource resource; - resource.threat_type = SB_THREAT_TYPE_SUSPICIOUS_SITE; + resource.threat_type = SBThreatType::SB_THREAT_TYPE_SUSPICIOUS_SITE; resource.url = primary_rfh.GetLastCommittedURL(); resource.render_process_id = primary_rfh_id.child_id; resource.render_frame_token = primary_rfh.GetFrameToken().value();
diff --git a/components/safe_browsing/content/browser/ui_manager.cc b/components/safe_browsing/content/browser/ui_manager.cc index 802185db..a1c7bd2 100644 --- a/components/safe_browsing/content/browser/ui_manager.cc +++ b/components/safe_browsing/content/browser/ui_manager.cc
@@ -280,7 +280,8 @@ DVLOG(1) << "ReportSafeBrowsingHit: " << hit_report->malicious_url << " " << hit_report->page_url << " " << hit_report->referrer_url << " " - << hit_report->is_subresource << " " << hit_report->threat_type; + << hit_report->is_subresource << " " + << static_cast<int>(hit_report->threat_type); delegate_->GetPingManager(web_contents->GetBrowserContext()) ->ReportSafeBrowsingHit(std::move(hit_report)); } @@ -305,41 +306,42 @@ // static std::string SafeBrowsingUIManager::GetThreatTypeStringForInterstitial( safe_browsing::SBThreatType threat_type) { + using enum SBThreatType; + switch (threat_type) { - case safe_browsing::SB_THREAT_TYPE_URL_PHISHING: - case safe_browsing::SB_THREAT_TYPE_URL_CLIENT_SIDE_PHISHING: + case SB_THREAT_TYPE_URL_PHISHING: + case SB_THREAT_TYPE_URL_CLIENT_SIDE_PHISHING: return "SOCIAL_ENGINEERING"; - case safe_browsing::SB_THREAT_TYPE_URL_MALWARE: + case SB_THREAT_TYPE_URL_MALWARE: return "MALWARE"; - case safe_browsing::SB_THREAT_TYPE_URL_UNWANTED: + case SB_THREAT_TYPE_URL_UNWANTED: return "UNWANTED_SOFTWARE"; - case safe_browsing::SB_THREAT_TYPE_BILLING: + case SB_THREAT_TYPE_BILLING: return "THREAT_TYPE_UNSPECIFIED"; - case safe_browsing::SB_THREAT_TYPE_MANAGED_POLICY_WARN: + case SB_THREAT_TYPE_MANAGED_POLICY_WARN: return "MANAGED_POLICY_WARN"; - case safe_browsing::SB_THREAT_TYPE_MANAGED_POLICY_BLOCK: + case SB_THREAT_TYPE_MANAGED_POLICY_BLOCK: return "MANAGED_POLICY_BLOCK"; - case safe_browsing::SB_THREAT_TYPE_UNUSED: - case safe_browsing::SB_THREAT_TYPE_SAFE: - case safe_browsing::SB_THREAT_TYPE_URL_BINARY_MALWARE: - case safe_browsing::SB_THREAT_TYPE_EXTENSION: - case safe_browsing::SB_THREAT_TYPE_BLOCKLISTED_RESOURCE: - case safe_browsing::SB_THREAT_TYPE_API_ABUSE: - case safe_browsing::SB_THREAT_TYPE_SUBRESOURCE_FILTER: - case safe_browsing::SB_THREAT_TYPE_CSD_ALLOWLIST: - case safe_browsing:: - DEPRECATED_SB_THREAT_TYPE_URL_PASSWORD_PROTECTION_PHISHING: - case safe_browsing::DEPRECATED_SB_THREAT_TYPE_URL_CLIENT_SIDE_MALWARE: - case safe_browsing::SB_THREAT_TYPE_SAVED_PASSWORD_REUSE: - case safe_browsing::SB_THREAT_TYPE_SIGNED_IN_SYNC_PASSWORD_REUSE: - case safe_browsing::SB_THREAT_TYPE_SIGNED_IN_NON_SYNC_PASSWORD_REUSE: - case safe_browsing::SB_THREAT_TYPE_AD_SAMPLE: - case safe_browsing::SB_THREAT_TYPE_BLOCKED_AD_POPUP: - case safe_browsing::SB_THREAT_TYPE_BLOCKED_AD_REDIRECT: - case safe_browsing::SB_THREAT_TYPE_SUSPICIOUS_SITE: - case safe_browsing::SB_THREAT_TYPE_ENTERPRISE_PASSWORD_REUSE: - case safe_browsing::SB_THREAT_TYPE_APK_DOWNLOAD: - case safe_browsing::SB_THREAT_TYPE_HIGH_CONFIDENCE_ALLOWLIST: + case SB_THREAT_TYPE_UNUSED: + case SB_THREAT_TYPE_SAFE: + case SB_THREAT_TYPE_URL_BINARY_MALWARE: + case SB_THREAT_TYPE_EXTENSION: + case SB_THREAT_TYPE_BLOCKLISTED_RESOURCE: + case SB_THREAT_TYPE_API_ABUSE: + case SB_THREAT_TYPE_SUBRESOURCE_FILTER: + case SB_THREAT_TYPE_CSD_ALLOWLIST: + case DEPRECATED_SB_THREAT_TYPE_URL_PASSWORD_PROTECTION_PHISHING: + case DEPRECATED_SB_THREAT_TYPE_URL_CLIENT_SIDE_MALWARE: + case SB_THREAT_TYPE_SAVED_PASSWORD_REUSE: + case SB_THREAT_TYPE_SIGNED_IN_SYNC_PASSWORD_REUSE: + case SB_THREAT_TYPE_SIGNED_IN_NON_SYNC_PASSWORD_REUSE: + case SB_THREAT_TYPE_AD_SAMPLE: + case SB_THREAT_TYPE_BLOCKED_AD_POPUP: + case SB_THREAT_TYPE_BLOCKED_AD_REDIRECT: + case SB_THREAT_TYPE_SUSPICIOUS_SITE: + case SB_THREAT_TYPE_ENTERPRISE_PASSWORD_REUSE: + case SB_THREAT_TYPE_APK_DOWNLOAD: + case SB_THREAT_TYPE_HIGH_CONFIDENCE_ALLOWLIST: NOTREACHED(); break; } @@ -412,7 +414,7 @@ if (proceed && !resources.empty()) { #if !BUILDFLAG(IS_ANDROID) if (resources[0].threat_type == - safe_browsing::SB_THREAT_TYPE_MANAGED_POLICY_WARN) { + SBThreatType::SB_THREAT_TYPE_MANAGED_POLICY_WARN) { delegate_->TriggerUrlFilteringInterstitialExtensionEventIfDesired( web_contents, main_frame_url, "ENTERPRISE_WARNED_BYPASS", resources[0].rt_lookup_response);
diff --git a/components/safe_browsing/content/browser/ui_manager_unittest.cc b/components/safe_browsing/content/browser/ui_manager_unittest.cc index d65d1b9..dd675ed7 100644 --- a/components/safe_browsing/content/browser/ui_manager_unittest.cc +++ b/components/safe_browsing/content/browser/ui_manager_unittest.cc
@@ -281,7 +281,8 @@ security_interstitials::UnsafeResource MakeUnsafeResource( const char* url, bool is_subresource, - const SBThreatType threat_type = SB_THREAT_TYPE_URL_MALWARE) { + const SBThreatType threat_type = + SBThreatType::SB_THREAT_TYPE_URL_MALWARE) { auto* primary_main_frame = web_contents()->GetPrimaryMainFrame(); return MakeUnsafeResource(url, is_subresource, primary_main_frame->GetGlobalId(), @@ -422,7 +423,7 @@ security_interstitials::UnsafeResource resource_phishing = MakeUnsafeResource(kBadURL, false /* is_subresource */); - resource_phishing.threat_type = SB_THREAT_TYPE_URL_PHISHING; + resource_phishing.threat_type = SBThreatType::SB_THREAT_TYPE_URL_PHISHING; EXPECT_TRUE(IsAllowlisted(resource_phishing)); } @@ -668,7 +669,7 @@ MakeUnsafeResource(kBadURL, false /* is_subresource */); resource.threat_source = safe_browsing::ThreatSource::REMOTE; // Make it a post commit interstitial. - resource.threat_type = SB_THREAT_TYPE_URL_CLIENT_SIDE_PHISHING; + resource.threat_type = SBThreatType::SB_THREAT_TYPE_URL_CLIENT_SIDE_PHISHING; SafeBrowsingCallbackWaiter waiter; resource.callback = @@ -707,8 +708,9 @@ TEST_F(SafeBrowsingUIManagerTest, AllowlistSetSeverestThreatTypeInRedirectChain) { - security_interstitials::UnsafeResource resource = MakeUnsafeResource( - kGoodURL, false /* is_subresource */, SB_THREAT_TYPE_API_ABUSE); + security_interstitials::UnsafeResource resource = + MakeUnsafeResource(kGoodURL, false /* is_subresource */, + SBThreatType::SB_THREAT_TYPE_API_ABUSE); AddToAllowlist(resource, true); auto navigation = content::NavigationSimulator::CreateBrowserInitiated( @@ -735,8 +737,9 @@ &threat_type)); EXPECT_EQ(threat_type, resource.threat_type); - security_interstitials::UnsafeResource redirect_resource = MakeUnsafeResource( - kRedirectURL, false /* is_subresource */, SB_THREAT_TYPE_BILLING); + security_interstitials::UnsafeResource redirect_resource = + MakeUnsafeResource(kRedirectURL, false /* is_subresource */, + SBThreatType::SB_THREAT_TYPE_BILLING); AddToAllowlist(redirect_resource, true); // The second redirect url has a less severe threat type, the final @@ -749,7 +752,7 @@ redirect_resource = MakeUnsafeResource(kRedirectURL, false /* is_subresource */, - SB_THREAT_TYPE_MANAGED_POLICY_BLOCK); + SBThreatType::SB_THREAT_TYPE_MANAGED_POLICY_BLOCK); AddToAllowlist(redirect_resource, true); // Now that the second redirect url has a more severe threat type, the final
diff --git a/components/safe_browsing/content/browser/web_api_handshake_checker_unittest.cc b/components/safe_browsing/content/browser/web_api_handshake_checker_unittest.cc index 91a4ae3b..705af2d4 100644 --- a/components/safe_browsing/content/browser/web_api_handshake_checker_unittest.cc +++ b/components/safe_browsing/content/browser/web_api_handshake_checker_unittest.cc
@@ -24,8 +24,8 @@ explicit FakeUrlCheckerDelegate( scoped_refptr<SafeBrowsingDatabaseManager> database_manager) : database_manager_(database_manager), - threat_types_( - SBThreatTypeSet({safe_browsing::SB_THREAT_TYPE_URL_PHISHING})) {} + threat_types_(SBThreatTypeSet( + {safe_browsing::SBThreatType::SB_THREAT_TYPE_URL_PHISHING})) {} // UrlCheckerDelegate overrides: void MaybeDestroyNoStatePrefetchContents( @@ -145,7 +145,8 @@ TEST_P(WebApiHandshakeCheckerTest, CheckDangerousUrl) { base::HistogramTester histogram_tester; const GURL kUrl("https://example.test"); - database_manager()->AddDangerousUrl(kUrl, SB_THREAT_TYPE_URL_PHISHING); + database_manager()->AddDangerousUrl( + kUrl, SBThreatType::SB_THREAT_TYPE_URL_PHISHING); if (GetParam()) { EXPECT_EQ(Check(kUrl), WebApiHandshakeChecker::CheckResult::kProceed); } else {
diff --git a/components/safe_browsing/core/browser/db/fake_database_manager.cc b/components/safe_browsing/core/browser/db/fake_database_manager.cc index c526c691..5eb1cbe 100644 --- a/components/safe_browsing/core/browser/db/fake_database_manager.cc +++ b/components/safe_browsing/core/browser/db/fake_database_manager.cc
@@ -48,8 +48,9 @@ return true; const SBThreatType result_threat_type = it->second; - if (result_threat_type == SB_THREAT_TYPE_SAFE) + if (result_threat_type == SBThreatType::SB_THREAT_TYPE_SAFE) { return true; + } ThreatPatternType pattern_type = ThreatPatternType::NONE; const auto it1 = dangerous_patterns_.find(url); @@ -75,8 +76,9 @@ continue; const SBThreatType result_threat_type = it->second; - if (result_threat_type == SB_THREAT_TYPE_SAFE) + if (result_threat_type == SBThreatType::SB_THREAT_TYPE_SAFE) { continue; + } sb_task_runner()->PostTask( FROM_HERE,
diff --git a/components/safe_browsing/core/browser/db/v4_database.cc b/components/safe_browsing/core/browser/db/v4_database.cc index 5181dd1..6b3e8fa 100644 --- a/components/safe_browsing/core/browser/db/v4_database.cc +++ b/components/safe_browsing/core/browser/db/v4_database.cc
@@ -437,7 +437,7 @@ list_id_(list_id), sb_threat_type_(sb_threat_type) { DCHECK(!fetch_updates_ || !filename_.empty()); - DCHECK_NE(SB_THREAT_TYPE_SAFE, sb_threat_type_); + DCHECK_NE(SBThreatType::SB_THREAT_TYPE_SAFE, sb_threat_type_); } ListInfo::~ListInfo() {}
diff --git a/components/safe_browsing/core/browser/db/v4_database_unittest.cc b/components/safe_browsing/core/browser/db/v4_database_unittest.cc index 7b5bf6e..8ffb28a 100644 --- a/components/safe_browsing/core/browser/db/v4_database_unittest.cc +++ b/components/safe_browsing/core/browser/db/v4_database_unittest.cc
@@ -110,13 +110,13 @@ void SetupInfoMapAndExpectedState() { list_infos_.emplace_back(true, "win_url_malware", win_malware_id_, - SB_THREAT_TYPE_URL_MALWARE); + SBThreatType::SB_THREAT_TYPE_URL_MALWARE); expected_identifiers_.push_back(win_malware_id_); expected_store_paths_.push_back( database_dirname_.AppendASCII("win_url_malware.store")); list_infos_.emplace_back(true, "linux_url_malware", linux_malware_id_, - SB_THREAT_TYPE_URL_MALWARE); + SBThreatType::SB_THREAT_TYPE_URL_MALWARE); expected_identifiers_.push_back(linux_malware_id_); expected_store_paths_.push_back( database_dirname_.AppendASCII("linux_url_malware.store"));
diff --git a/components/safe_browsing/core/browser/db/v4_local_database_manager.cc b/components/safe_browsing/core/browser/db/v4_local_database_manager.cc index 13c3931..ee17e9a4 100644 --- a/components/safe_browsing/core/browser/db/v4_local_database_manager.cc +++ b/components/safe_browsing/core/browser/db/v4_local_database_manager.cc
@@ -66,6 +66,8 @@ const char* const kStoreFileNamesToDelete[] = {"IpMalware.store"}; ListInfos GetListInfos() { + using enum SBThreatType; + // NOTE(vakh): When adding a store here, add the corresponding store-specific // histograms also. // The first argument to ListInfo specifies whether to sync hash prefixes for @@ -173,6 +175,8 @@ // This is only valid for types that are passed to GetBrowseUrl(). ListIdentifier GetUrlIdFromSBThreatType(SBThreatType sb_threat_type) { + using enum SBThreatType; + switch (sb_threat_type) { case SB_THREAT_TYPE_URL_MALWARE: return GetUrlMalwareId(); @@ -286,13 +290,14 @@ const std::vector<GURL>& urls) : client(client), client_callback_type(client_callback_type), - most_severe_threat_type(SB_THREAT_TYPE_SAFE), + most_severe_threat_type(SBThreatType::SB_THREAT_TYPE_SAFE), stores_to_check(stores_to_check), urls(urls) { for (const auto& url : urls) { V4ProtocolManagerUtil::UrlToFullHashes(url, &full_hashes); } - full_hash_threat_types.assign(full_hashes.size(), SB_THREAT_TYPE_SAFE); + full_hash_threat_types.assign(full_hashes.size(), + SBThreatType::SB_THREAT_TYPE_SAFE); } V4LocalDatabaseManager::PendingCheck::PendingCheck( @@ -302,11 +307,12 @@ const std::set<FullHashStr>& full_hashes_set) : client(client), client_callback_type(client_callback_type), - most_severe_threat_type(SB_THREAT_TYPE_SAFE), + most_severe_threat_type(SBThreatType::SB_THREAT_TYPE_SAFE), stores_to_check(stores_to_check) { full_hashes.assign(full_hashes_set.begin(), full_hashes_set.end()); DCHECK(full_hashes.size()); - full_hash_threat_types.assign(full_hashes.size(), SB_THREAT_TYPE_SAFE); + full_hash_threat_types.assign(full_hashes.size(), + SBThreatType::SB_THREAT_TYPE_SAFE); } V4LocalDatabaseManager::PendingCheck::~PendingCheck() { @@ -824,8 +830,8 @@ const ListIdentifier& list_id) { auto it = base::ranges::find(list_infos_, list_id, &ListInfo::list_id); DCHECK(list_infos_.end() != it); - DCHECK_NE(SB_THREAT_TYPE_SAFE, it->sb_threat_type()); - DCHECK_NE(SB_THREAT_TYPE_UNUSED, it->sb_threat_type()); + DCHECK_NE(SBThreatType::SB_THREAT_TYPE_SAFE, it->sb_threat_type()); + DCHECK_NE(SBThreatType::SB_THREAT_TYPE_UNUSED, it->sb_threat_type()); return it->sb_threat_type(); } @@ -935,9 +941,9 @@ } else if (check->client_callback_type == ClientCallbackType::CHECK_CSD_ALLOWLIST) { if (GetPrefixMatchesIsAsync()) { - check->most_severe_threat_type = did_match_allowlist - ? SB_THREAT_TYPE_CSD_ALLOWLIST - : SB_THREAT_TYPE_SAFE; + check->most_severe_threat_type = + did_match_allowlist ? SBThreatType::SB_THREAT_TYPE_CSD_ALLOWLIST + : SBThreatType::SB_THREAT_TYPE_SAFE; RespondToClient(std::move(check)); } } else { @@ -1229,10 +1235,10 @@ case ClientCallbackType::CHECK_CSD_ALLOWLIST: { DCHECK_EQ(1u, check->urls.size()); - bool did_match_allowlist = - check->most_severe_threat_type == SB_THREAT_TYPE_CSD_ALLOWLIST; - DCHECK(did_match_allowlist || - check->most_severe_threat_type == SB_THREAT_TYPE_SAFE); + bool did_match_allowlist = check->most_severe_threat_type == + SBThreatType::SB_THREAT_TYPE_CSD_ALLOWLIST; + DCHECK(did_match_allowlist || check->most_severe_threat_type == + SBThreatType::SB_THREAT_TYPE_SAFE); check->client->OnCheckAllowlistUrlResult(did_match_allowlist); break; } @@ -1242,7 +1248,8 @@ check->full_hashes.size()); std::set<FullHashStr> unsafe_extension_ids; for (size_t i = 0; i < check->full_hash_threat_types.size(); i++) { - if (check->full_hash_threat_types[i] == SB_THREAT_TYPE_EXTENSION) { + if (check->full_hash_threat_types[i] == + SBThreatType::SB_THREAT_TYPE_EXTENSION) { unsafe_extension_ids.insert(check->full_hashes[i]); } }
diff --git a/components/safe_browsing/core/browser/db/v4_local_database_manager_unittest.cc b/components/safe_browsing/core/browser/db/v4_local_database_manager_unittest.cc index 510bae5a..1806ddc 100644 --- a/components/safe_browsing/core/browser/db/v4_local_database_manager_unittest.cc +++ b/components/safe_browsing/core/browser/db/v4_local_database_manager_unittest.cc
@@ -275,7 +275,8 @@ const std::string& threat_hash) override { ASSERT_EQ(expected_urls_[0], url); ASSERT_EQ(expected_sb_threat_type_, threat_type); - ASSERT_EQ(threat_type == SB_THREAT_TYPE_SAFE, threat_hash.empty()); + ASSERT_EQ(threat_type == SBThreatType::SB_THREAT_TYPE_SAFE, + threat_hash.empty()); on_check_resource_url_result_called_ = true; } @@ -319,7 +320,8 @@ void OnCheckAllowlistUrlResult(bool is_allowlisted) override { EXPECT_EQ(match_expected_, is_allowlisted); - EXPECT_EQ(SB_THREAT_TYPE_CSD_ALLOWLIST, expected_sb_threat_type_); + EXPECT_EQ(SBThreatType::SB_THREAT_TYPE_CSD_ALLOWLIST, + expected_sb_threat_type_); callback_called_ = true; } @@ -392,6 +394,8 @@ class V4LocalDatabaseManagerTest : public PlatformTest { public: + using enum SBThreatType; + V4LocalDatabaseManagerTest() : task_runner_(new base::TestSimpleTaskRunner) {} void SetUp() override {
diff --git a/components/safe_browsing/core/browser/db/v4_protocol_manager_util.cc b/components/safe_browsing/core/browser/db/v4_protocol_manager_util.cc index b76f204f..09bc16b 100644 --- a/components/safe_browsing/core/browser/db/v4_protocol_manager_util.cc +++ b/components/safe_browsing/core/browser/db/v4_protocol_manager_util.cc
@@ -210,11 +210,11 @@ bool SBThreatTypeSetIsValidForCheckBrowseUrl(const SBThreatTypeSet& set) { for (SBThreatType type : set) { switch (type) { - case SB_THREAT_TYPE_URL_PHISHING: - case SB_THREAT_TYPE_URL_MALWARE: - case SB_THREAT_TYPE_URL_UNWANTED: - case SB_THREAT_TYPE_SUSPICIOUS_SITE: - case SB_THREAT_TYPE_BILLING: + case SBThreatType::SB_THREAT_TYPE_URL_PHISHING: + case SBThreatType::SB_THREAT_TYPE_URL_MALWARE: + case SBThreatType::SB_THREAT_TYPE_URL_UNWANTED: + case SBThreatType::SB_THREAT_TYPE_SUSPICIOUS_SITE: + case SBThreatType::SB_THREAT_TYPE_BILLING: break; default:
diff --git a/components/safe_browsing/core/browser/hash_realtime_mechanism.cc b/components/safe_browsing/core/browser/hash_realtime_mechanism.cc index 869d9373..99733ca 100644 --- a/components/safe_browsing/core/browser/hash_realtime_mechanism.cc +++ b/components/safe_browsing/core/browser/hash_realtime_mechanism.cc
@@ -119,8 +119,9 @@ weak_factory_.GetWeakPtr())); if (result.is_safe_synchronously) { // No match found in the database, so conclude this is safe. - OnHashDatabaseCompleteCheckResultInternal( - SB_THREAT_TYPE_SAFE, ThreatMetadata(), /*threat_source=*/std::nullopt); + OnHashDatabaseCompleteCheckResultInternal(SBThreatType::SB_THREAT_TYPE_SAFE, + ThreatMetadata(), + /*threat_source=*/std::nullopt); // NOTE: Calling OnHashDatabaseCompleteCheckResultInternal results in the // synchronous destruction of this object, so there is nothing safe to do // here but return.
diff --git a/components/safe_browsing/core/browser/hashprefix_realtime/hash_realtime_service_unittest.cc b/components/safe_browsing/core/browser/hashprefix_realtime/hash_realtime_service_unittest.cc index 46d9608..4a58079e5 100644 --- a/components/safe_browsing/core/browser/hashprefix_realtime/hash_realtime_service_unittest.cc +++ b/components/safe_browsing/core/browser/hashprefix_realtime/hash_realtime_service_unittest.cc
@@ -747,6 +747,8 @@ }; TEST_F(HashRealTimeServiceTest, TestLookup_OneHash) { + using enum SBThreatType; + struct TestCase { std::optional<V5::ThreatType> response_threat_type; std::optional<std::vector<V5::ThreatAttribute>> response_threat_attributes;
diff --git a/components/safe_browsing/core/browser/ping_manager.cc b/components/safe_browsing/core/browser/ping_manager.cc index 0a01dcae..60cd1d5 100644 --- a/components/safe_browsing/core/browser/ping_manager.cc +++ b/components/safe_browsing/core/browser/ping_manager.cc
@@ -340,6 +340,8 @@ GURL PingManager::SafeBrowsingHitUrl( safe_browsing::HitReport* hit_report) const { + using enum SBThreatType; + DCHECK(hit_report->threat_type == SB_THREAT_TYPE_URL_MALWARE || hit_report->threat_type == SB_THREAT_TYPE_URL_PHISHING || hit_report->threat_type == SB_THREAT_TYPE_URL_UNWANTED ||
diff --git a/components/safe_browsing/core/browser/ping_manager_unittest.cc b/components/safe_browsing/core/browser/ping_manager_unittest.cc index e5a040c..1646c4ae3 100644 --- a/components/safe_browsing/core/browser/ping_manager_unittest.cc +++ b/components/safe_browsing/core/browser/ping_manager_unittest.cc
@@ -56,6 +56,8 @@ }; class PingManagerTest : public testing::Test { protected: + using enum SBThreatType; + void SetUp() override; void TearDown() override; void RunReportThreatDetailsTest(
diff --git a/components/safe_browsing/core/browser/realtime/url_lookup_service_base.cc b/components/safe_browsing/core/browser/realtime/url_lookup_service_base.cc index 6a757b24..006b7fcd 100644 --- a/components/safe_browsing/core/browser/realtime/url_lookup_service_base.cc +++ b/components/safe_browsing/core/browser/realtime/url_lookup_service_base.cc
@@ -187,6 +187,8 @@ SBThreatType RealTimeUrlLookupServiceBase::GetSBThreatTypeForRTThreatType( RTLookupResponse::ThreatInfo::ThreatType rt_threat_type, RTLookupResponse::ThreatInfo::VerdictType rt_verdict_type) { + using enum SBThreatType; + if (rt_threat_type == RTLookupResponse::ThreatInfo::MANAGED_POLICY) { switch (rt_verdict_type) { case RTLookupResponse::ThreatInfo::DANGEROUS:
diff --git a/components/safe_browsing/core/browser/realtime/url_lookup_service_unittest.cc b/components/safe_browsing/core/browser/realtime/url_lookup_service_unittest.cc index 0911cdc..066db313 100644 --- a/components/safe_browsing/core/browser/realtime/url_lookup_service_unittest.cc +++ b/components/safe_browsing/core/browser/realtime/url_lookup_service_unittest.cc
@@ -417,6 +417,8 @@ } TEST_F(RealTimeUrlLookupServiceTest, TestGetSBThreatTypeForRTThreatType) { + using enum SBThreatType; + EXPECT_EQ(SB_THREAT_TYPE_URL_MALWARE, RealTimeUrlLookupServiceBase::GetSBThreatTypeForRTThreatType( RTLookupResponse::ThreatInfo::WEB_MALWARE,
diff --git a/components/safe_browsing/core/browser/safe_browsing_hats_delegate.cc b/components/safe_browsing/core/browser/safe_browsing_hats_delegate.cc index f9316889..abb928f 100644 --- a/components/safe_browsing/core/browser/safe_browsing_hats_delegate.cc +++ b/components/safe_browsing/core/browser/safe_browsing_hats_delegate.cc
@@ -32,13 +32,13 @@ // concerned with report types that HaTS will target. std::string ThreatTypeToReportType(SBThreatType threat_type) { switch (threat_type) { - case SB_THREAT_TYPE_URL_PHISHING: + case SBThreatType::SB_THREAT_TYPE_URL_PHISHING: return "URL_PHISHING"; - case SB_THREAT_TYPE_URL_MALWARE: + case SBThreatType::SB_THREAT_TYPE_URL_MALWARE: return "URL_MALWARE"; - case SB_THREAT_TYPE_URL_UNWANTED: + case SBThreatType::SB_THREAT_TYPE_URL_UNWANTED: return "URL_UNWANTED"; - case SB_THREAT_TYPE_URL_CLIENT_SIDE_PHISHING: + case SBThreatType::SB_THREAT_TYPE_URL_CLIENT_SIDE_PHISHING: return "URL_CLIENT_SIDE_PHISHING"; default: return "UNSUPPORTED_THREAT_TYPE";
diff --git a/components/safe_browsing/core/browser/safe_browsing_hats_delegate_unittest.cc b/components/safe_browsing/core/browser/safe_browsing_hats_delegate_unittest.cc index 84b8918..49c97a18 100644 --- a/components/safe_browsing/core/browser/safe_browsing_hats_delegate_unittest.cc +++ b/components/safe_browsing/core/browser/safe_browsing_hats_delegate_unittest.cc
@@ -13,6 +13,9 @@ static constexpr char kAllReportTypeFilters[] = "URL_PHISHING,URL_MALWARE,URL_UNWANTED,URL_CLIENT_SIDE_PHISHING"; static constexpr char kAllDidProceedFilters[] = "TRUE,FALSE"; + + protected: + using enum SBThreatType; }; TEST_F(SafeBrowsingHatsDelegateTest, IsSurveyCandidateWithAllFilters) {
diff --git a/components/safe_browsing/core/browser/safe_browsing_lookup_mechanism.cc b/components/safe_browsing/core/browser/safe_browsing_lookup_mechanism.cc index 2b07dc6..5a1559a 100644 --- a/components/safe_browsing/core/browser/safe_browsing_lookup_mechanism.cc +++ b/components/safe_browsing/core/browser/safe_browsing_lookup_mechanism.cc
@@ -32,7 +32,8 @@ metadata(metadata), threat_source(threat_source), url_real_time_lookup_response(std::move(url_real_time_lookup_response)) { - DCHECK(threat_source.has_value() || threat_type == SB_THREAT_TYPE_SAFE); + DCHECK(threat_source.has_value() || + threat_type == SBThreatType::SB_THREAT_TYPE_SAFE); } SafeBrowsingLookupMechanism::CompleteCheckResult::~CompleteCheckResult() =
diff --git a/components/safe_browsing/core/browser/safe_browsing_url_checker_impl.cc b/components/safe_browsing/core/browser/safe_browsing_url_checker_impl.cc index c9e1d03..59e6d558 100644 --- a/components/safe_browsing/core/browser/safe_browsing_url_checker_impl.cc +++ b/components/safe_browsing/core/browser/safe_browsing_url_checker_impl.cc
@@ -80,7 +80,7 @@ break; } - // TODO(drubery): Make SBThreatType an `enum class`, so we can use + // TODO(drubery): Make SBThreatType an `enum class` so we can use // the template instantiations relying on kMaxValue here. base::UmaHistogramEnumeration( "SafeBrowsing.CheckUrl.FirstRequestThreatType", threat_type, @@ -281,12 +281,12 @@ if (timed_out) { // Any pending callbacks on this URL check should be skipped. weak_factory_.InvalidateWeakPtrs(); - OnUrlResultInternalAndMaybeDeleteSelf(urls_[next_index_].url, - safe_browsing::SB_THREAT_TYPE_SAFE, - ThreatMetadata(), - /*threat_source=*/std::nullopt, - /*rt_lookup_response=*/nullptr, - /*timed_out=*/true, performed_check); + OnUrlResultInternalAndMaybeDeleteSelf( + urls_[next_index_].url, + safe_browsing::SBThreatType::SB_THREAT_TYPE_SAFE, ThreatMetadata(), + /*threat_source=*/std::nullopt, + /*rt_lookup_response=*/nullptr, + /*timed_out=*/true, performed_check); } else { OnUrlResultInternalAndMaybeDeleteSelf( result.value()->url, result.value()->threat_type, @@ -304,6 +304,8 @@ std::unique_ptr<RTLookupResponse> rt_lookup_response, bool timed_out, PerformedCheck performed_check) { + using enum SBThreatType; + DCHECK_EQ(STATE_CHECKING_URL, state_); DCHECK_LT(next_index_, urls_.size()); DCHECK_EQ(urls_[next_index_].url, url); @@ -455,7 +457,7 @@ request_destination_); SBThreatType threat_type = CheckWebUIUrls(url); - if (threat_type != safe_browsing::SB_THREAT_TYPE_SAFE) { + if (threat_type != SBThreatType::SB_THREAT_TYPE_SAFE) { state_ = STATE_CHECKING_URL; TRACE_EVENT_NESTABLE_ASYNC_BEGIN1( "safe_browsing", "CheckUrl", TRACE_ID_LOCAL(this), "url", url.spec()); @@ -597,19 +599,20 @@ } SBThreatType SafeBrowsingUrlCheckerImpl::CheckWebUIUrls(const GURL& url) { + using enum SBThreatType; if (url == kChromeUISafeBrowsingMatchMalwareUrl) { - return safe_browsing::SB_THREAT_TYPE_URL_MALWARE; + return SB_THREAT_TYPE_URL_MALWARE; } if (url == kChromeUISafeBrowsingMatchPhishingUrl) { - return safe_browsing::SB_THREAT_TYPE_URL_PHISHING; + return SB_THREAT_TYPE_URL_PHISHING; } if (url == kChromeUISafeBrowsingMatchUnwantedUrl) { - return safe_browsing::SB_THREAT_TYPE_URL_UNWANTED; + return SB_THREAT_TYPE_URL_UNWANTED; } if (url == kChromeUISafeBrowsingMatchBillingUrl) { - return safe_browsing::SB_THREAT_TYPE_BILLING; + return SB_THREAT_TYPE_BILLING; } - return safe_browsing::SB_THREAT_TYPE_SAFE; + return SB_THREAT_TYPE_SAFE; } bool SafeBrowsingUrlCheckerImpl::RunNextCallbackAndMaybeDeleteSelf(
diff --git a/components/safe_browsing/core/browser/safe_browsing_url_checker_impl_unittest.cc b/components/safe_browsing/core/browser/safe_browsing_url_checker_impl_unittest.cc index 600ca734..644b06d3 100644 --- a/components/safe_browsing/core/browser/safe_browsing_url_checker_impl_unittest.cc +++ b/components/safe_browsing/core/browser/safe_browsing_url_checker_impl_unittest.cc
@@ -64,7 +64,7 @@ DCHECK(base::Contains(urls_threat_type_, url)); DCHECK(base::Contains(urls_delayed_callback_, url)); EXPECT_EQ(check_type, expected_check_type_); - if (urls_threat_type_[url] == SB_THREAT_TYPE_SAFE) { + if (urls_threat_type_[url] == SBThreatType::SB_THREAT_TYPE_SAFE) { return true; } if (!urls_delayed_callback_[url]) { @@ -182,8 +182,8 @@ public: explicit MockUrlCheckerDelegate(SafeBrowsingDatabaseManager* database_manager) : database_manager_(database_manager), - threat_types_( - SBThreatTypeSet({safe_browsing::SB_THREAT_TYPE_URL_PHISHING})) {} + threat_types_(SBThreatTypeSet( + {safe_browsing::SBThreatType::SB_THREAT_TYPE_URL_PHISHING})) {} MOCK_METHOD1(MaybeDestroyNoStatePrefetchContents, void(base::OnceCallback<content::WebContents*()>)); @@ -242,6 +242,8 @@ RTLookupResponseCallback response_callback, scoped_refptr<base::SequencedTaskRunner> callback_task_runner, SessionID tab_id) override { + using enum SBThreatType; + std::string url = gurl.spec(); DCHECK(base::Contains(url_details_, url)); auto response = std::make_unique<RTLookupResponse>(); @@ -443,6 +445,8 @@ } protected: + using enum SBThreatType; + void CheckHashRealTimeMetrics(std::optional<bool> expected_local_match_result, std::optional<bool> expected_is_service_found, bool expected_can_check_reputation) { @@ -514,7 +518,7 @@ hash_realtime_utils::HashRealTimeSelection::kNone); GURL url("https://example.test/"); - database_manager_->SetThreatTypeForUrl(url, SB_THREAT_TYPE_SAFE, + database_manager_->SetThreatTypeForUrl(url, SBThreatType::SB_THREAT_TYPE_SAFE, /*delayed_callback=*/false); base::MockCallback<SafeBrowsingUrlCheckerImpl::NativeCheckUrlCallback> callback;
diff --git a/components/safe_browsing/core/browser/url_realtime_mechanism.cc b/components/safe_browsing/core/browser/url_realtime_mechanism.cc index 48e635f68..75389ed 100644 --- a/components/safe_browsing/core/browser/url_realtime_mechanism.cc +++ b/components/safe_browsing/core/browser/url_realtime_mechanism.cc
@@ -20,9 +20,8 @@ constexpr char kMatchResultHistogramName[] = "SafeBrowsing.RT.LocalMatch.Result"; -void RecordLocalMatchResult( - bool has_match, - std::string url_lookup_service_metric_suffix) { +void RecordLocalMatchResult(bool has_match, + std::string url_lookup_service_metric_suffix) { AsyncMatch match_result = has_match ? AsyncMatch::MATCH : AsyncMatch::NO_MATCH; base::UmaHistogramEnumeration(kMatchResultHistogramName, match_result); @@ -175,7 +174,7 @@ RTLookupResponse::ThreatInfo::VerdictType rt_verdict_type = RTLookupResponse::ThreatInfo::SAFE; - SBThreatType sb_threat_type = SB_THREAT_TYPE_SAFE; + SBThreatType sb_threat_type = SBThreatType::SB_THREAT_TYPE_SAFE; if (response && (response->threat_info_size() > 0)) { rt_verdict_type = response->threat_info(0).verdict_type(); sb_threat_type = @@ -185,7 +184,8 @@ MaybePerformSuspiciousSiteDetection(rt_verdict_type); - if (is_cached_response && sb_threat_type == SB_THREAT_TYPE_SAFE) { + if (is_cached_response && + sb_threat_type == SBThreatType::SB_THREAT_TYPE_SAFE) { is_cached_safe_url_ = true; PerformHashBasedCheck(url_); // NOTE: Calling PerformHashBasedCheck may result in the synchronous @@ -216,8 +216,9 @@ } if (is_safe_synchronously || !can_check_db_) { // No match found in the database, so conclude this is safe. - OnHashDatabaseCompleteCheckResultInternal( - SB_THREAT_TYPE_SAFE, ThreatMetadata(), /*threat_source=*/std::nullopt); + OnHashDatabaseCompleteCheckResultInternal(SBThreatType::SB_THREAT_TYPE_SAFE, + ThreatMetadata(), + /*threat_source=*/std::nullopt); // NOTE: Calling OnHashDatabaseCompleteCheckResultInternal results in the // synchronous destruction of this object, so there is nothing safe to do // here but return.
diff --git a/components/safe_browsing/ios/browser/safe_browsing_url_allow_list_unittest.mm b/components/safe_browsing/ios/browser/safe_browsing_url_allow_list_unittest.mm index 9048536..07d35e6 100644 --- a/components/safe_browsing/ios/browser/safe_browsing_url_allow_list_unittest.mm +++ b/components/safe_browsing/ios/browser/safe_browsing_url_allow_list_unittest.mm
@@ -13,9 +13,10 @@ namespace { // Constants used in tests. -const SBThreatType kFirstThreatType = safe_browsing::SB_THREAT_TYPE_URL_MALWARE; +const SBThreatType kFirstThreatType = + safe_browsing::SBThreatType::SB_THREAT_TYPE_URL_MALWARE; const SBThreatType kSecondThreatType = - safe_browsing::SB_THREAT_TYPE_URL_PHISHING; + safe_browsing::SBThreatType::SB_THREAT_TYPE_URL_PHISHING; // Mocked SafeBrowsingUrlAllowList::Observer for use in tests. class MockAllowListObserver : public SafeBrowsingUrlAllowList::Observer { public:
diff --git a/components/signin/core/browser/account_reconcilor.cc b/components/signin/core/browser/account_reconcilor.cc index ada6c17..844d27e 100644 --- a/components/signin/core/browser/account_reconcilor.cc +++ b/components/signin/core/browser/account_reconcilor.cc
@@ -597,14 +597,6 @@ // Revoking the token for the primary account is not supported (it should be // signed out or put to auth error state instead). delegate_->RevokeSecondaryTokensForReconcileIfNeeded(verified_gaia_accounts); - if (!delegate_->IsUpdateCookieAllowed()) { - // TODO(b/320279580): Record reconcilor operation if tokens were revoked to - // match cookies. - error_during_last_reconcile_ = GoogleServiceAuthError::AuthErrorNone(); - CalculateIfMultiloginReconcileIsDone(); - ScheduleStartReconcileIfChromeAccountsChanged(); - return; - } std::vector<CoreAccountId> chrome_accounts = LoadValidAccountsFromTokenService();
diff --git a/components/signin/core/browser/account_reconcilor_delegate.cc b/components/signin/core/browser/account_reconcilor_delegate.cc index b046242..76937dc 100644 --- a/components/signin/core/browser/account_reconcilor_delegate.cc +++ b/components/signin/core/browser/account_reconcilor_delegate.cc
@@ -22,10 +22,6 @@ return false; } -bool AccountReconcilorDelegate::IsUpdateCookieAllowed() const { - return true; -} - gaia::GaiaSource AccountReconcilorDelegate::GetGaiaApiSource() const { NOTREACHED() << "Reconcile is not enabled, no Gaia API calls should be made."; return gaia::GaiaSource::kChrome;
diff --git a/components/signin/core/browser/account_reconcilor_delegate.h b/components/signin/core/browser/account_reconcilor_delegate.h index f54cca5..1602c6b 100644 --- a/components/signin/core/browser/account_reconcilor_delegate.h +++ b/components/signin/core/browser/account_reconcilor_delegate.h
@@ -29,11 +29,6 @@ // false. virtual bool IsReconcileEnabled() const; - // Returns true if calling OAuthMultiLogin to update cookies to match - // refresh tokens is allowed. Used in Dice to disable updating cookies when - // the user is not signed in to chrome. - virtual bool IsUpdateCookieAllowed() const; - // Returns the value to set in the "source" parameter for Gaia API calls. virtual gaia::GaiaSource GetGaiaApiSource() const;
diff --git a/components/signin/core/browser/account_reconcilor_unittest.cc b/components/signin/core/browser/account_reconcilor_unittest.cc index 16e7458..083a7b4 100644 --- a/components/signin/core/browser/account_reconcilor_unittest.cc +++ b/components/signin/core/browser/account_reconcilor_unittest.cc
@@ -1587,17 +1587,42 @@ kDiceParamsUnoPreChromeSignIn = { // clang-format off // See `kDiceParams` above for detailed params format. - { "", "A", IsFirstReconcile::kBoth, "", "", "A" }, - { "AB", "", IsFirstReconcile::kBoth, "", "" , "" }, - { "AB", "A", IsFirstReconcile::kBoth, "", "A", "A" }, - { "A", "B", IsFirstReconcile::kBoth, "", "" , "B" }, - { "xA", "A", IsFirstReconcile::kBoth, "", "", "A" }, - { "xAB", "A", IsFirstReconcile::kBoth, "", "", "A" }, + // First account in cookie doesn't have a token. + { "", "A", IsFirstReconcile::kBoth, "X", "", "" }, + { "xA", "A", IsFirstReconcile::kBoth, "X", "", "" }, + { "B", "AB", IsFirstReconcile::kFirst, "UB", "B", "B" }, + { "B", "AB", IsFirstReconcile::kNotFirst, "X", "", "" }, + { "xAB", "A", IsFirstReconcile::kBoth, "X", "" , "" }, - // Account marked as invalid in cookies. - { "A", "xA", IsFirstReconcile::kBoth, "", "", "xA" }, - { "AB", "AxB", IsFirstReconcile::kBoth, "", "A", "AxB" }, - { "xA", "xA", IsFirstReconcile::kBoth, "", "", "xA" }, + // Invalid first account in cookie doesn't have a token. + { "xA", "xA", IsFirstReconcile::kBoth, "", "", "xA" }, + { "", "xAB", IsFirstReconcile::kBoth, "X", "", "" }, + { "B", "xAB", IsFirstReconcile::kBoth, "", "B", "xAB" }, + { "B", "xABC", IsFirstReconcile::kBoth, "UB", "B", "B" }, + + // Invalid first account in cookie. + { "A", "xA", IsFirstReconcile::kBoth, "", "", "xA" }, + { "A", "xAB", IsFirstReconcile::kBoth, "X", "", "" }, + { "AB", "xABC", IsFirstReconcile::kBoth, "UB", "B", "B" }, + + // Tokens not in the cookie. + { "CB", "B", IsFirstReconcile::kBoth, "", "B", "B" }, + { "AB", "", IsFirstReconcile::kBoth, "", "" , "" }, + { "AB", "AxB", IsFirstReconcile::kBoth, "", "A", "AxB" }, + + // Tokens and cookies need update. + { "A", "B", IsFirstReconcile::kBoth, "X", "" , "" }, + + // Secondary account without token. + { "B", "BC", IsFirstReconcile::kBoth, "UB", "B", "B" }, + + // Consistent. + // Added to check Reconcile is Idempotent. + { "B", "B", IsFirstReconcile::kBoth, "", "B", "B" }, + { "", "", IsFirstReconcile::kBoth, "", "", "" }, + { "", "xA", IsFirstReconcile::kBoth, "", "", "xA" }, + { "A", "AxB", IsFirstReconcile::kBoth, "", "A", "AxB" }, + // clang-format on }; class AccountReconcilorTestDiceExplicitBrowserSignin @@ -1617,6 +1642,7 @@ // Checks one row of the `kDiceParamsUnoPreChromeSignIn` table above. TEST_P(AccountReconcilorTestDicePreChromeSignIn, TableRowTest) { SetAccountConsistency(signin::AccountConsistencyMethod::kDice); + CheckReconcileIdempotent(kDiceParamsUnoPreChromeSignIn, GetParam()); RunRowTest(GetParam()); }
diff --git a/components/signin/core/browser/dice_account_reconcilor_delegate.cc b/components/signin/core/browser/dice_account_reconcilor_delegate.cc index 7218abc..87e404d 100644 --- a/components/signin/core/browser/dice_account_reconcilor_delegate.cc +++ b/components/signin/core/browser/dice_account_reconcilor_delegate.cc
@@ -98,21 +98,17 @@ return true; } -bool DiceAccountReconcilorDelegate::IsUpdateCookieAllowed() const { +bool DiceAccountReconcilorDelegate::IsCookieBasedConsistencyMode() const { CHECK(IsReconcileEnabled()); - if (switches::IsExplicitBrowserSigninUIOnDesktopEnabled( - switches::ExplicitBrowserSigninPhase::kExperimental)) { - // If the user is not signed in to chrome, cookie updates (OAuthMultiLogin) - // is not allowed. In this mode, cookies are the source of truth. - return identity_manager_->HasPrimaryAccount( - GetConsentLevelForPrimaryAccount()); - } - return true; + return switches::IsExplicitBrowserSigninUIOnDesktopEnabled( + switches::ExplicitBrowserSigninPhase::kExperimental) && + !identity_manager_->HasPrimaryAccount( + GetConsentLevelForPrimaryAccount()); } void DiceAccountReconcilorDelegate::MatchTokensWithAccountsInCookie( const std::vector<gaia::ListedAccount>& gaia_accounts) { - CHECK(!IsUpdateCookieAllowed()); + CHECK(IsCookieBasedConsistencyMode()); const signin_metrics::SourceForRefreshTokenOperation source = signin_metrics::SourceForRefreshTokenOperation:: kAccountReconcilor_RevokeTokensNotInCookies; @@ -270,6 +266,12 @@ const std::vector<CoreAccountId>& chrome_accounts, const std::vector<gaia::ListedAccount>& gaia_accounts, bool first_execution) const { + // If Gaia accounts are empty, any combination of accounts can be set and + // logout is not needed. + if (gaia_accounts.empty()) { + return false; + } + CoreAccountId primary_account = identity_manager_->GetPrimaryAccountId( GetConsentLevelForPrimaryAccount()); @@ -277,11 +279,6 @@ identity_manager_->HasAccountWithRefreshTokenInPersistentErrorState( primary_account); - // If Gaia accounts are empty, any combination of accounts can be set and - // logout is not needed. - if (gaia_accounts.empty()) - return false; - // On first execution, it's generally OK to reorder accounts. Only logout if // the primary account needs to be removed from the first position in cookies // (it would be unacceptable to swap another account there). @@ -289,18 +286,26 @@ return !primary_account.empty() && primary_has_error && gaia_accounts[0].id == primary_account && gaia_accounts[0].valid; } - // If there is a valid Sync account, then it's ok to reorder the accounts + // If there is a valid primary account, then it's ok to reorder the accounts // even though Chrome is running (the accounts would be reordered on the next // startup, and this avoids a logout). if (!primary_account.empty() && !primary_has_error) { return false; } - // If the first gaia account doesn't have token then logout. Exception: If the - // first gaia account is invalid, but it can be left in its place (this is - // possible only if there is no need to delete gaia accounts). Other accounts - // will be added after. - return !base::Contains(chrome_accounts, gaia_accounts[0].id) && - ShouldDeleteAccountsFromGaia(chrome_accounts, gaia_accounts); + + // The default gaia account doesn't have token. + if (!base::Contains(chrome_accounts, gaia_accounts[0].id)) { + if (IsCookieBasedConsistencyMode()) { + // Logout only if the default cookie account is valid. + return gaia_accounts[0].valid; + } + + // Logout with the exception: If the first gaia account is invalid, but it + // can be left in its place (this is possible only if there is no need to + // delete gaia accounts). Other accounts will be added after. + return ShouldDeleteAccountsFromGaia(chrome_accounts, gaia_accounts); + } + return false; } CoreAccountId DiceAccountReconcilorDelegate::GetFirstGaiaAccountForMultilogin( @@ -309,10 +314,10 @@ const std::vector<gaia::ListedAccount>& gaia_accounts, bool first_execution, bool primary_has_error) const { - bool valid_sync_account = !primary_account.empty() && !primary_has_error; - // On first execution if there is a valid sync account, then primary + bool valid_primary_account = !primary_account.empty() && !primary_has_error; + // On first execution if there is a valid primary account, then primary // account should be set to the first position. - if (first_execution && valid_sync_account) { + if (first_execution && valid_primary_account) { return primary_account; } // In case accounts in cookies are accidentally lost we @@ -324,9 +329,9 @@ DCHECK(!first_execution); return last_known_first_account_; } - // If there are no cookies and a valid sync account, then we can + // If there are no cookies and a valid primary account, then we can // set primary account to first position without reordering. - if (gaia_accounts.empty() && valid_sync_account) { + if (gaia_accounts.empty() && valid_primary_account) { return primary_account; } // Empty account means that there is no special requirements for @@ -374,8 +379,8 @@ kAccountReconcilor_GaiaCookiesUpdated, signin_metrics::ProfileSignout::kGaiaCookieUpdated, /*revoke_only_if_in_error=*/true); - if (!IsUpdateCookieAllowed()) { - // Cookie update not enabled, match tokens with Gaia accounts. + if (IsCookieBasedConsistencyMode()) { + // Refresh tokens with no equivalent account in the cookie are revoked. MatchTokensWithAccountsInCookie(gaia_accounts); } } @@ -395,8 +400,8 @@ return; } - // In the UNO model the primary account should not be signed out if the - // account cookie is deleted by user action. + // In the UNO model the primary account should not be signed out if + // authentication cookies are deleted by user action. if (switches::IsExplicitBrowserSigninUIOnDesktopEnabled( switches::ExplicitBrowserSigninPhase::kExperimental) && !identity_manager_->HasPrimaryAccount(ConsentLevel::kSync)) {
diff --git a/components/signin/core/browser/dice_account_reconcilor_delegate.h b/components/signin/core/browser/dice_account_reconcilor_delegate.h index fea1581..c63cc41a 100644 --- a/components/signin/core/browser/dice_account_reconcilor_delegate.h +++ b/components/signin/core/browser/dice_account_reconcilor_delegate.h
@@ -28,7 +28,6 @@ // AccountReconcilorDelegate: bool IsReconcileEnabled() const override; - bool IsUpdateCookieAllowed() const override; gaia::GaiaSource GetGaiaApiSource() const override; void RevokeSecondaryTokensForReconcileIfNeeded( const std::vector<gaia::ListedAccount>& gaia_accounts) override; @@ -41,6 +40,19 @@ bool first_execution) override; ConsentLevel GetConsentLevelForPrimaryAccount() const override; + // Returns true if explicit browser sign in is enabled and Chrome isn't signed + // in. + // In this mode: + // - First, refresh tokens that do not have a valid counter account in the + // cookie are revoked. + // - Then if needed, the cookie is updated to remove accounts that do not + // have a refresh token. This is possible: + // (1) If the user has signed out from chrome while being offline. + // (2) If an account is moved from a profile to another as part of the + // Sign in interception flows or as a result of merge sync data flow. + // Public for testing. + bool IsCookieBasedConsistencyMode() const; + private: // Possible inconsistency reasons between tokens and gaia cookies. // These values are persisted to logs. Entries should not be renumbered and
diff --git a/components/signin/core/browser/dice_account_reconcilor_delegate_unittest.cc b/components/signin/core/browser/dice_account_reconcilor_delegate_unittest.cc index 8039cd2..57244f7 100644 --- a/components/signin/core/browser/dice_account_reconcilor_delegate_unittest.cc +++ b/components/signin/core/browser/dice_account_reconcilor_delegate_unittest.cc
@@ -36,11 +36,17 @@ return gaia_account; } -class DiceAccountReconcilorDelegateTest : public testing::Test { +class DiceAccountReconcilorDelegateTest : public testing::TestWithParam<bool> { public: DiceAccountReconcilorDelegateTest() : delegate_(identity_manager(), - identity_test_environment_.signin_client()) {} + identity_test_environment_.signin_client()) { + if (IsExplicitBrowserSigninEnabled()) { + scoped_feature_list_.InitAndEnableFeature(switches::kUnoDesktop); + } else { + scoped_feature_list_.InitAndDisableFeature(switches::kUnoDesktop); + } + } DiceAccountReconcilorDelegate& delegate() { return delegate_; } @@ -48,38 +54,45 @@ return identity_test_environment_; } + bool IsExplicitBrowserSigninEnabled() { return GetParam(); } + IdentityManager* identity_manager() { return identity_test_environment().identity_manager(); } private: base::test::SingleThreadTaskEnvironment task_environment_; - base::test::ScopedFeatureList scoped_feature_list_{switches::kUnoDesktop}; + base::test::ScopedFeatureList scoped_feature_list_; IdentityTestEnvironment identity_test_environment_; DiceAccountReconcilorDelegate delegate_; }; -TEST_F(DiceAccountReconcilorDelegateTest, GetConsentLevelForPrimaryAccount) { - // Uno enabled. - EXPECT_EQ(delegate().GetConsentLevelForPrimaryAccount(), - ConsentLevel::kSignin); +TEST_P(DiceAccountReconcilorDelegateTest, GetConsentLevelForPrimaryAccount) { + signin::ConsentLevel consent_level = IsExplicitBrowserSigninEnabled() + ? ConsentLevel::kSignin + : ConsentLevel::kSync; + EXPECT_EQ(delegate().GetConsentLevelForPrimaryAccount(), consent_level); } -TEST_F(DiceAccountReconcilorDelegateTest, - IsUpdateCookieAllowedPreChromeSignIn) { - EXPECT_FALSE(delegate().IsUpdateCookieAllowed()); +TEST_P(DiceAccountReconcilorDelegateTest, + IsCookieBasedConsistencyModePreChromeSignIn) { + EXPECT_EQ(delegate().IsCookieBasedConsistencyMode(), + IsExplicitBrowserSigninEnabled()); } -TEST_F(DiceAccountReconcilorDelegateTest, - IsUpdateCookieAllowedPostChromeSignIn) { +TEST_P(DiceAccountReconcilorDelegateTest, + IsCookieBasedConsistencyModePostChromeSignIn) { identity_test_environment().MakePrimaryAccountAvailable( kPrimaryAccountEmail, ConsentLevel::kSignin); ASSERT_TRUE(identity_manager()->HasPrimaryAccount(ConsentLevel::kSignin)); - EXPECT_TRUE(delegate().IsUpdateCookieAllowed()); + EXPECT_FALSE(delegate().IsCookieBasedConsistencyMode()); } -TEST_F(DiceAccountReconcilorDelegateTest, +TEST_P(DiceAccountReconcilorDelegateTest, RevokeSecondaryTokensForReconcileIfNeededPreChromeSignIn) { + if (!IsExplicitBrowserSigninEnabled()) { + GTEST_SKIP(); + } AccountInfo valid_account = identity_test_environment().MakeAccountAvailable("account@gmail.com"); @@ -109,7 +122,7 @@ ::testing::UnorderedElementsAre( valid_account, account_with_invalid_refresh_token, no_cookie_account, invalid_cookie_account)); - ASSERT_FALSE(delegate().IsUpdateCookieAllowed()); + ASSERT_TRUE(delegate().IsCookieBasedConsistencyMode()); const std::vector<gaia::ListedAccount> gaia_signed_in_accounts{ GetListedAccountFromAccountInfo(valid_account), @@ -123,43 +136,42 @@ EXPECT_THAT(chrome_accounts[0], ::testing::Eq(valid_account)); } -TEST(DiceAccountReconcilorDelegateTestUnoDisabled, - RevokeSecondaryTokensForReconcile) { - base::test::SingleThreadTaskEnvironment task_environment; - base::test::ScopedFeatureList scoped_feature_list; - IdentityTestEnvironment identity_test_environment; - IdentityManager* identity_manager = - identity_test_environment.identity_manager(); - DiceAccountReconcilorDelegate delegate( - identity_manager, identity_test_environment.signin_client()); - - EXPECT_TRUE(delegate.IsUpdateCookieAllowed()); - - scoped_feature_list.InitAndDisableFeature(switches::kUnoDesktop); - +TEST_P(DiceAccountReconcilorDelegateTest, RevokeSecondaryTokensForReconcile) { AccountInfo valid_account = - identity_test_environment.MakeAccountAvailable("account@gmail.com"); + identity_test_environment().MakeAccountAvailable("account@gmail.com"); + if (IsExplicitBrowserSigninEnabled()) { + identity_test_environment().SetPrimaryAccount(valid_account.email, + ConsentLevel::kSignin); + } + EXPECT_FALSE(delegate().IsCookieBasedConsistencyMode()); // Accounts with invalid refresh token should be revoked. AccountInfo account_with_invalid_refresh_token = - identity_test_environment.MakeAccountAvailable( + identity_test_environment().MakeAccountAvailable( AccountAvailabilityOptionsBuilder() .WithRefreshToken(GaiaConstants::kInvalidRefreshToken) .Build("invalid_refresh_token@gmail.com")); - // Uno disabled, only accounts with invalid refresh tokens should be revoked. + // Only accounts with invalid refresh tokens should be revoked. AccountInfo no_cookie_account = - identity_test_environment.MakeAccountAvailable("no_cookie@gmail.com"); - EXPECT_EQ(identity_manager->GetAccountsWithRefreshTokens().size(), 3u); + identity_test_environment().MakeAccountAvailable("no_cookie@gmail.com"); + EXPECT_EQ(identity_manager()->GetAccountsWithRefreshTokens().size(), 3u); const std::vector<gaia::ListedAccount> gaia_signed_in_accounts{ GetListedAccountFromAccountInfo(valid_account), GetListedAccountFromAccountInfo(account_with_invalid_refresh_token)}; - delegate.RevokeSecondaryTokensForReconcileIfNeeded(gaia_signed_in_accounts); + delegate().RevokeSecondaryTokensForReconcileIfNeeded(gaia_signed_in_accounts); EXPECT_THAT( - identity_manager->GetAccountsWithRefreshTokens(), + identity_manager()->GetAccountsWithRefreshTokens(), ::testing::UnorderedElementsAre(valid_account, no_cookie_account)); } +INSTANTIATE_TEST_SUITE_P(, + DiceAccountReconcilorDelegateTest, + testing::Bool(), + [](const ::testing::TestParamInfo<bool>& info) { + return info.param ? "Explicit" : "Implicit"; + }); + } // namespace } // namespace signin
diff --git a/components/subresource_filter/content/browser/content_activation_list_utils.cc b/components/subresource_filter/content/browser/content_activation_list_utils.cc index f78bcd6..11ceea0 100644 --- a/components/subresource_filter/content/browser/content_activation_list_utils.cc +++ b/components/subresource_filter/content/browser/content_activation_list_utils.cc
@@ -60,7 +60,7 @@ bool* warning) { DCHECK(warning); bool is_phishing_interstitial = - (threat_type == safe_browsing::SB_THREAT_TYPE_URL_PHISHING); + (threat_type == safe_browsing::SBThreatType::SB_THREAT_TYPE_URL_PHISHING); bool is_soc_engineering_ads_interstitial = threat_type_metadata.threat_pattern_type == safe_browsing::ThreatPatternType::SOCIAL_ENGINEERING_ADS; @@ -69,7 +69,8 @@ return ActivationList::SOCIAL_ENG_ADS_INTERSTITIAL; } return ActivationList::PHISHING_INTERSTITIAL; - } else if (threat_type == safe_browsing::SB_THREAT_TYPE_SUBRESOURCE_FILTER) { + } else if (threat_type == + safe_browsing::SBThreatType::SB_THREAT_TYPE_SUBRESOURCE_FILTER) { return GetSubresourceFilterMatch(threat_type_metadata, warning); } return ActivationList::NONE;
diff --git a/components/subresource_filter/content/browser/content_activation_list_utils_unittest.cc b/components/subresource_filter/content/browser/content_activation_list_utils_unittest.cc index 526cde8..2d7b755 100644 --- a/components/subresource_filter/content/browser/content_activation_list_utils_unittest.cc +++ b/components/subresource_filter/content/browser/content_activation_list_utils_unittest.cc
@@ -4,6 +4,7 @@ #include "components/subresource_filter/content/browser/content_activation_list_utils.h" #include "base/test/scoped_feature_list.h" +#include "components/safe_browsing/core/browser/db/v4_protocol_manager_util.h" #include "components/subresource_filter/core/browser/subresource_filter_features.h" #include "testing/gtest/include/gtest/gtest.h" @@ -12,6 +13,8 @@ enum class AdBlockOnAbusiveSitesTest { kEnabled, kDisabled }; TEST(ContentActivationListUtilsTest, GetListForThreatTypeAndMetadata) { + using enum safe_browsing::SBThreatType; + typedef safe_browsing::SubresourceFilterType Type; typedef safe_browsing::SubresourceFilterLevel Level; const struct { @@ -24,105 +27,105 @@ bool expected_warning; } kTestCases[]{ {"Phishing_With_SocialEngineeringAds", - safe_browsing::SB_THREAT_TYPE_URL_PHISHING, + SB_THREAT_TYPE_URL_PHISHING, safe_browsing::ThreatPatternType::SOCIAL_ENGINEERING_ADS, {}, AdBlockOnAbusiveSitesTest::kDisabled, ActivationList::SOCIAL_ENG_ADS_INTERSTITIAL, false}, {"Phishing_Without_SocialEngineeringAds", - safe_browsing::SB_THREAT_TYPE_URL_PHISHING, + SB_THREAT_TYPE_URL_PHISHING, safe_browsing::ThreatPatternType::NONE, {}, AdBlockOnAbusiveSitesTest::kDisabled, ActivationList::PHISHING_INTERSTITIAL, false}, {"Empty_SubresourceFilterMatch", - safe_browsing::SB_THREAT_TYPE_SUBRESOURCE_FILTER, + SB_THREAT_TYPE_SUBRESOURCE_FILTER, safe_browsing::ThreatPatternType::NONE, {}, AdBlockOnAbusiveSitesTest::kDisabled, ActivationList::SUBRESOURCE_FILTER, false}, {"BetterAds_Warn_DisableAdBlockOnAbusiveSites", - safe_browsing::SB_THREAT_TYPE_SUBRESOURCE_FILTER, + SB_THREAT_TYPE_SUBRESOURCE_FILTER, safe_browsing::ThreatPatternType::NONE, {{Type::BETTER_ADS, Level::WARN}}, AdBlockOnAbusiveSitesTest::kDisabled, ActivationList::BETTER_ADS, true}, {"BetterAds_Enforce_DisableAdBlockOnAbusiveSites", - safe_browsing::SB_THREAT_TYPE_SUBRESOURCE_FILTER, + SB_THREAT_TYPE_SUBRESOURCE_FILTER, safe_browsing::ThreatPatternType::NONE, {{Type::BETTER_ADS, Level::ENFORCE}}, AdBlockOnAbusiveSitesTest::kDisabled, ActivationList::BETTER_ADS, false}, {"Abusive_Warn_DisableAdBlockOnAbusiveSites", - safe_browsing::SB_THREAT_TYPE_SUBRESOURCE_FILTER, + SB_THREAT_TYPE_SUBRESOURCE_FILTER, safe_browsing::ThreatPatternType::NONE, {{Type::ABUSIVE, Level::WARN}}, AdBlockOnAbusiveSitesTest::kDisabled, ActivationList::NONE, false}, {"Abusive_Enforce_DisableAdBlockOnAbusiveSites", - safe_browsing::SB_THREAT_TYPE_SUBRESOURCE_FILTER, + SB_THREAT_TYPE_SUBRESOURCE_FILTER, safe_browsing::ThreatPatternType::NONE, {{Type::ABUSIVE, Level::ENFORCE}}, AdBlockOnAbusiveSitesTest::kDisabled, ActivationList::NONE, false}, {"BetterAds_Warn_EnableAdBlockOnAbusiveSites", - safe_browsing::SB_THREAT_TYPE_SUBRESOURCE_FILTER, + SB_THREAT_TYPE_SUBRESOURCE_FILTER, safe_browsing::ThreatPatternType::NONE, {{Type::BETTER_ADS, Level::WARN}}, AdBlockOnAbusiveSitesTest::kEnabled, ActivationList::BETTER_ADS, true}, {"BetterAds_Enforce_EnableAdBlockOnAbusiveSites", - safe_browsing::SB_THREAT_TYPE_SUBRESOURCE_FILTER, + SB_THREAT_TYPE_SUBRESOURCE_FILTER, safe_browsing::ThreatPatternType::NONE, {{Type::BETTER_ADS, Level::ENFORCE}}, AdBlockOnAbusiveSitesTest::kEnabled, ActivationList::BETTER_ADS, false}, {"Abusive_Warn_EnableAdBlockOnAbusiveSites", - safe_browsing::SB_THREAT_TYPE_SUBRESOURCE_FILTER, + SB_THREAT_TYPE_SUBRESOURCE_FILTER, safe_browsing::ThreatPatternType::NONE, {{Type::ABUSIVE, Level::WARN}}, AdBlockOnAbusiveSitesTest::kEnabled, ActivationList::ABUSIVE, true}, {"Abusive_Enforce_EnableAdBlockOnAbusiveSites", - safe_browsing::SB_THREAT_TYPE_SUBRESOURCE_FILTER, + SB_THREAT_TYPE_SUBRESOURCE_FILTER, safe_browsing::ThreatPatternType::NONE, {{Type::ABUSIVE, Level::ENFORCE}}, AdBlockOnAbusiveSitesTest::kEnabled, ActivationList::ABUSIVE, false}, {"BetterAds_Warn_Abusive_Warn_EnableAdBlockOnAbusiveSites", - safe_browsing::SB_THREAT_TYPE_SUBRESOURCE_FILTER, + SB_THREAT_TYPE_SUBRESOURCE_FILTER, safe_browsing::ThreatPatternType::NONE, {{Type::ABUSIVE, Level::WARN}, {Type::BETTER_ADS, Level::WARN}}, AdBlockOnAbusiveSitesTest::kDisabled, ActivationList::BETTER_ADS, true}, {"BetterAds_Warn_Abusive_Enforce_EnableAdBlockOnAbusiveSites", - safe_browsing::SB_THREAT_TYPE_SUBRESOURCE_FILTER, + SB_THREAT_TYPE_SUBRESOURCE_FILTER, safe_browsing::ThreatPatternType::NONE, {{Type::ABUSIVE, Level::ENFORCE}, {Type::BETTER_ADS, Level::WARN}}, AdBlockOnAbusiveSitesTest::kEnabled, ActivationList::ABUSIVE, false}, {"BetterAds_Enforce_Abusive_Warn_EnableAdBlockOnAbusiveSites", - safe_browsing::SB_THREAT_TYPE_SUBRESOURCE_FILTER, + SB_THREAT_TYPE_SUBRESOURCE_FILTER, safe_browsing::ThreatPatternType::NONE, {{Type::ABUSIVE, Level::WARN}, {Type::BETTER_ADS, Level::ENFORCE}}, AdBlockOnAbusiveSitesTest::kEnabled, ActivationList::BETTER_ADS, false}, {"BetterAds_Enforce_Abusive_Enforce_EnableAdBlockOnAbusiveSites", - safe_browsing::SB_THREAT_TYPE_SUBRESOURCE_FILTER, + SB_THREAT_TYPE_SUBRESOURCE_FILTER, safe_browsing::ThreatPatternType::NONE, {{Type::ABUSIVE, Level::ENFORCE}, {Type::BETTER_ADS, Level::ENFORCE}}, AdBlockOnAbusiveSitesTest::kEnabled,
diff --git a/components/subresource_filter/content/browser/subresource_filter_safe_browsing_activation_throttle_unittest.cc b/components/subresource_filter/content/browser/subresource_filter_safe_browsing_activation_throttle_unittest.cc index 653e281..09988f4 100644 --- a/components/subresource_filter/content/browser/subresource_filter_safe_browsing_activation_throttle_unittest.cc +++ b/components/subresource_filter/content/browser/subresource_filter_safe_browsing_activation_throttle_unittest.cc
@@ -125,22 +125,22 @@ const ActivationListTestData kActivationListTestData[] = { {kActivationListSocialEngineeringAdsInterstitial, ActivationList::SOCIAL_ENG_ADS_INTERSTITIAL, - safe_browsing::SB_THREAT_TYPE_URL_PHISHING, + safe_browsing::SBThreatType::SB_THREAT_TYPE_URL_PHISHING, safe_browsing::ThreatPatternType::SOCIAL_ENGINEERING_ADS, {}}, {kActivationListPhishingInterstitial, ActivationList::PHISHING_INTERSTITIAL, - safe_browsing::SB_THREAT_TYPE_URL_PHISHING, + safe_browsing::SBThreatType::SB_THREAT_TYPE_URL_PHISHING, safe_browsing::ThreatPatternType::NONE, {}}, {kActivationListSubresourceFilter, ActivationList::SUBRESOURCE_FILTER, - safe_browsing::SB_THREAT_TYPE_SUBRESOURCE_FILTER, + safe_browsing::SBThreatType::SB_THREAT_TYPE_SUBRESOURCE_FILTER, safe_browsing::ThreatPatternType::NONE, {}}, {kActivationListSubresourceFilter, ActivationList::BETTER_ADS, - safe_browsing::SB_THREAT_TYPE_SUBRESOURCE_FILTER, + safe_browsing::SBThreatType::SB_THREAT_TYPE_SUBRESOURCE_FILTER, safe_browsing::ThreatPatternType::NONE, {{SBType::BETTER_ADS, SBLevel::ENFORCE}}}, }; @@ -326,11 +326,12 @@ SimulateCommit(navigation_simulator())); } - void ConfigureForMatch(const GURL& url, - safe_browsing::SBThreatType pattern_type = - safe_browsing::SB_THREAT_TYPE_SUBRESOURCE_FILTER, - const safe_browsing::ThreatMetadata& metadata = - safe_browsing::ThreatMetadata()) { + void ConfigureForMatch( + const GURL& url, + safe_browsing::SBThreatType pattern_type = + safe_browsing::SBThreatType::SB_THREAT_TYPE_SUBRESOURCE_FILTER, + const safe_browsing::ThreatMetadata& metadata = + safe_browsing::ThreatMetadata()) { fake_safe_browsing_database_->AddBlocklistedUrl(url, pattern_type, metadata); } @@ -554,7 +555,8 @@ safe_browsing::ThreatMetadata metadata; metadata.threat_pattern_type = safe_browsing::ThreatPatternType::SOCIAL_ENGINEERING_ADS; - ConfigureForMatch(match_url, safe_browsing::SB_THREAT_TYPE_URL_PHISHING, + ConfigureForMatch(match_url, + safe_browsing::SBThreatType::SB_THREAT_TYPE_URL_PHISHING, metadata); SimulateNavigateAndCommit({match_url}, main_rfh()); EXPECT_EQ(mojom::ActivationLevel::kDisabled, @@ -636,6 +638,8 @@ } TEST_F(SubresourceFilterSafeBrowsingActivationThrottleTest, ActivationList) { + using enum safe_browsing::SBThreatType; + const struct { mojom::ActivationLevel expected_activation_level; ActivationList activation_list; @@ -643,56 +647,51 @@ safe_browsing::ThreatPatternType threat_type_metadata; } kTestCases[] = { {mojom::ActivationLevel::kDisabled, ActivationList::NONE, - safe_browsing::SB_THREAT_TYPE_URL_PHISHING, + SB_THREAT_TYPE_URL_PHISHING, safe_browsing::ThreatPatternType::SOCIAL_ENGINEERING_ADS}, {mojom::ActivationLevel::kDisabled, - ActivationList::SOCIAL_ENG_ADS_INTERSTITIAL, - safe_browsing::SB_THREAT_TYPE_URL_PHISHING, + ActivationList::SOCIAL_ENG_ADS_INTERSTITIAL, SB_THREAT_TYPE_URL_PHISHING, safe_browsing::ThreatPatternType::NONE}, {mojom::ActivationLevel::kDisabled, - ActivationList::SOCIAL_ENG_ADS_INTERSTITIAL, - safe_browsing::SB_THREAT_TYPE_URL_PHISHING, + ActivationList::SOCIAL_ENG_ADS_INTERSTITIAL, SB_THREAT_TYPE_URL_PHISHING, safe_browsing::ThreatPatternType::MALWARE_LANDING}, {mojom::ActivationLevel::kDisabled, - ActivationList::SOCIAL_ENG_ADS_INTERSTITIAL, - safe_browsing::SB_THREAT_TYPE_URL_PHISHING, + ActivationList::SOCIAL_ENG_ADS_INTERSTITIAL, SB_THREAT_TYPE_URL_PHISHING, safe_browsing::ThreatPatternType::MALWARE_DISTRIBUTION}, {mojom::ActivationLevel::kDisabled, ActivationList::PHISHING_INTERSTITIAL, - safe_browsing::SB_THREAT_TYPE_API_ABUSE, + SB_THREAT_TYPE_API_ABUSE, safe_browsing::ThreatPatternType::SOCIAL_ENGINEERING_ADS}, {mojom::ActivationLevel::kDisabled, ActivationList::PHISHING_INTERSTITIAL, - safe_browsing::SB_THREAT_TYPE_BLOCKLISTED_RESOURCE, + SB_THREAT_TYPE_BLOCKLISTED_RESOURCE, safe_browsing::ThreatPatternType::SOCIAL_ENGINEERING_ADS}, {mojom::ActivationLevel::kDisabled, ActivationList::PHISHING_INTERSTITIAL, - safe_browsing::SB_THREAT_TYPE_URL_BINARY_MALWARE, + SB_THREAT_TYPE_URL_BINARY_MALWARE, safe_browsing::ThreatPatternType::SOCIAL_ENGINEERING_ADS}, {mojom::ActivationLevel::kDisabled, ActivationList::PHISHING_INTERSTITIAL, - safe_browsing::SB_THREAT_TYPE_URL_UNWANTED, + SB_THREAT_TYPE_URL_UNWANTED, safe_browsing::ThreatPatternType::SOCIAL_ENGINEERING_ADS}, {mojom::ActivationLevel::kDisabled, ActivationList::PHISHING_INTERSTITIAL, - safe_browsing::SB_THREAT_TYPE_URL_MALWARE, + SB_THREAT_TYPE_URL_MALWARE, safe_browsing::ThreatPatternType::SOCIAL_ENGINEERING_ADS}, {mojom::ActivationLevel::kDisabled, ActivationList::PHISHING_INTERSTITIAL, - safe_browsing::SB_THREAT_TYPE_URL_CLIENT_SIDE_PHISHING, + SB_THREAT_TYPE_URL_CLIENT_SIDE_PHISHING, safe_browsing::ThreatPatternType::SOCIAL_ENGINEERING_ADS}, {mojom::ActivationLevel::kDisabled, ActivationList::PHISHING_INTERSTITIAL, - safe_browsing::SB_THREAT_TYPE_SAFE, + SB_THREAT_TYPE_SAFE, safe_browsing::ThreatPatternType::SOCIAL_ENGINEERING_ADS}, {mojom::ActivationLevel::kEnabled, ActivationList::PHISHING_INTERSTITIAL, - safe_browsing::SB_THREAT_TYPE_URL_PHISHING, - safe_browsing::ThreatPatternType::NONE}, + SB_THREAT_TYPE_URL_PHISHING, safe_browsing::ThreatPatternType::NONE}, {mojom::ActivationLevel::kEnabled, - ActivationList::SOCIAL_ENG_ADS_INTERSTITIAL, - safe_browsing::SB_THREAT_TYPE_URL_PHISHING, + ActivationList::SOCIAL_ENG_ADS_INTERSTITIAL, SB_THREAT_TYPE_URL_PHISHING, safe_browsing::ThreatPatternType::SOCIAL_ENGINEERING_ADS}, {mojom::ActivationLevel::kEnabled, ActivationList::PHISHING_INTERSTITIAL, - safe_browsing::SB_THREAT_TYPE_URL_PHISHING, + SB_THREAT_TYPE_URL_PHISHING, safe_browsing::ThreatPatternType::SOCIAL_ENGINEERING_ADS}, {mojom::ActivationLevel::kEnabled, ActivationList::SUBRESOURCE_FILTER, - safe_browsing::SB_THREAT_TYPE_SUBRESOURCE_FILTER, + SB_THREAT_TYPE_SUBRESOURCE_FILTER, safe_browsing::ThreatPatternType::NONE}, {mojom::ActivationLevel::kDisabled, ActivationList::PHISHING_INTERSTITIAL, - safe_browsing::SB_THREAT_TYPE_SUBRESOURCE_FILTER, + SB_THREAT_TYPE_SUBRESOURCE_FILTER, safe_browsing::ThreatPatternType::NONE}, }; const GURL test_url("https://matched_url.com/"); @@ -1056,8 +1055,10 @@ scoped_configuration()->ResetConfiguration({config_p1, config_p2}); // Configure the URLs to match on different lists, phishing is worse. - ConfigureForMatch(bad_url, safe_browsing::SB_THREAT_TYPE_SUBRESOURCE_FILTER); - ConfigureForMatch(worse_url, safe_browsing::SB_THREAT_TYPE_URL_PHISHING); + ConfigureForMatch( + bad_url, safe_browsing::SBThreatType::SB_THREAT_TYPE_SUBRESOURCE_FILTER); + ConfigureForMatch(worse_url, + safe_browsing::SBThreatType::SB_THREAT_TYPE_URL_PHISHING); // Check cases where there are multiple redirects. Activation only triggers // on the final url, but redirect position is evaluated based on the worst. @@ -1120,8 +1121,9 @@ metadata.threat_pattern_type = safe_browsing::ThreatPatternType::NONE; metadata.subresource_filter_match = safe_browsing::SubresourceFilterMatch( {{SBType::ABUSIVE, SBLevel::ENFORCE}}); - ConfigureForMatch(url, safe_browsing::SB_THREAT_TYPE_SUBRESOURCE_FILTER, - metadata); + ConfigureForMatch( + url, safe_browsing::SBThreatType::SB_THREAT_TYPE_SUBRESOURCE_FILTER, + metadata); SimulateStartAndExpectProceed(url); SimulateCommitAndExpectProceed();
diff --git a/components/subresource_filter/content/browser/subresource_filter_safe_browsing_client.cc b/components/subresource_filter/content/browser/subresource_filter_safe_browsing_client.cc index 13c47e5..db927d3 100644 --- a/components/subresource_filter/content/browser/subresource_filter_safe_browsing_client.cc +++ b/components/subresource_filter/content/browser/subresource_filter_safe_browsing_client.cc
@@ -23,7 +23,7 @@ SubresourceFilterSafeBrowsingClient::CheckResult::ToTracedValue() const { auto value = std::make_unique<base::trace_event::TracedValue>(); value->SetInteger("request_id", request_id); - value->SetInteger("threat_type", threat_type); + value->SetInteger("threat_type", static_cast<int>(threat_type)); value->SetValue("threat_metadata", threat_metadata.ToTracedValue().get()); value->SetInteger("duration (us)", (base::TimeTicks::Now() - start_time).InMicroseconds());
diff --git a/components/subresource_filter/content/browser/subresource_filter_safe_browsing_client_request.cc b/components/subresource_filter/content/browser/subresource_filter_safe_browsing_client_request.cc index 42e3e57..99468f4 100644 --- a/components/subresource_filter/content/browser/subresource_filter_safe_browsing_client_request.cc +++ b/components/subresource_filter/content/browser/subresource_filter_safe_browsing_client_request.cc
@@ -52,7 +52,7 @@ if (synchronous_finish) { request_completed_ = true; SendCheckResultToClient(false /* served_from_network */, - safe_browsing::SB_THREAT_TYPE_SAFE, + safe_browsing::SBThreatType::SB_THREAT_TYPE_SAFE, safe_browsing::ThreatMetadata()); return; } @@ -76,7 +76,7 @@ void SubresourceFilterSafeBrowsingClientRequest::OnCheckUrlTimeout() { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); SendCheckResultToClient(true /* served_from_network */, - safe_browsing::SB_THREAT_TYPE_SAFE, + safe_browsing::SBThreatType::SB_THREAT_TYPE_SAFE, safe_browsing::ThreatMetadata()); }
diff --git a/components/subresource_filter/content/browser/subresource_filter_test_harness.cc b/components/subresource_filter/content/browser/subresource_filter_test_harness.cc index fa71357..7f796f8 100644 --- a/components/subresource_filter/content/browser/subresource_filter_test_harness.cc +++ b/components/subresource_filter/content/browser/subresource_filter_test_harness.cc
@@ -165,7 +165,7 @@ void SubresourceFilterTestHarness::ConfigureAsSubresourceFilterOnlyURL( const GURL& url) { fake_safe_browsing_database()->AddBlocklistedUrl( - url, safe_browsing::SB_THREAT_TYPE_SUBRESOURCE_FILTER); + url, safe_browsing::SBThreatType::SB_THREAT_TYPE_SUBRESOURCE_FILTER); } void SubresourceFilterTestHarness::RemoveURLFromBlocklist(const GURL& url) {
diff --git a/components/sync_bookmarks/local_bookmark_model_merger.cc b/components/sync_bookmarks/local_bookmark_model_merger.cc index 30f0de8..1d3c391 100644 --- a/components/sync_bookmarks/local_bookmark_model_merger.cc +++ b/components/sync_bookmarks/local_bookmark_model_merger.cc
@@ -94,6 +94,10 @@ LocalBookmarkModelMerger::~LocalBookmarkModelMerger() = default; void LocalBookmarkModelMerger::Merge() { + CHECK(account_model_->bookmark_bar_node()); + CHECK(account_model_->mobile_node()); + CHECK(account_model_->other_node()); + // Algorithm description: // Match up the roots and recursively do the following: // * For each local node for the current local parent node, either @@ -178,9 +182,11 @@ const bookmarks::BookmarkNode* const account_child = account_child_ptr.get(); - // Non-syncable nodes (e.g. managed nodes) are not expected to exist in the - // account BookmarkModel instance. - CHECK(account_model_->IsNodeSyncable(account_child)); + // Ignore non-syncable nodes (e.g. managed bookmarks), which don't need + // merging. + if (!account_model_->IsNodeSyncable(account_child)) { + continue; + } // If a UUID match exists, it takes precedence over semantic matching. if (FindMatchingLocalNodeByUuid(account_child)) {
diff --git a/components/sync_bookmarks/local_bookmark_model_merger_unittest.cc b/components/sync_bookmarks/local_bookmark_model_merger_unittest.cc index a26a2f1d..8bdb9f07 100644 --- a/components/sync_bookmarks/local_bookmark_model_merger_unittest.cc +++ b/components/sync_bookmarks/local_bookmark_model_merger_unittest.cc
@@ -12,10 +12,12 @@ #include "base/strings/utf_ostream_operators.h" #include "base/strings/utf_string_conversions.h" +#include "base/test/scoped_feature_list.h" #include "base/uuid.h" #include "components/bookmarks/browser/bookmark_model.h" #include "components/bookmarks/browser/bookmark_node.h" #include "components/bookmarks/test/test_bookmark_client.h" +#include "components/sync/base/features.h" #include "components/sync_bookmarks/bookmark_model_view.h" #include "components/sync_bookmarks/test_bookmark_model_view.h" #include "testing/gmock/include/gmock/gmock.h" @@ -156,18 +158,36 @@ std::optional<base::Uuid> uuid_; }; -std::unique_ptr<TestBookmarkModelView> BuildModel( +std::unique_ptr<TestBookmarkModelView> BuildLocalModel( const std::vector<FolderBuilder::FolderOrUrl>& children_of_bookmark_bar) { - auto model = std::make_unique<TestBookmarkModelView>(); + auto model = std::make_unique<TestBookmarkModelView>( + TestBookmarkModelView::ViewType::kLocalOrSyncableNodes); FolderBuilder::AddChildrenTo(model.get(), model->bookmark_bar_node(), children_of_bookmark_bar); return model; } -} // namespace +std::unique_ptr<TestBookmarkModelView> BuildAccountModel( + const std::vector<FolderBuilder::FolderOrUrl>& children_of_bookmark_bar) { + auto model = std::make_unique<TestBookmarkModelView>( + TestBookmarkModelView::ViewType::kAccountNodes); + model->EnsurePermanentNodesExist(); + FolderBuilder::AddChildrenTo(model.get(), model->bookmark_bar_node(), + children_of_bookmark_bar); + return model; +} -TEST(LocalBookmarkModelMergerTest, - ShouldUploadEntireLocalModelIfAccountModelEmpty) { +class LocalBookmarkModelMergerTest : public testing::Test { + protected: + LocalBookmarkModelMergerTest() = default; + ~LocalBookmarkModelMergerTest() override = default; + + base::test::ScopedFeatureList feature_list_{ + syncer::kEnableBookmarkFoldersForAccountStorage}; +}; + +TEST_F(LocalBookmarkModelMergerTest, + ShouldUploadEntireLocalModelIfAccountModelEmpty) { const std::string kFolder1Title = "folder1"; const std::string kFolder2Title = "folder2"; @@ -190,16 +210,16 @@ // |- url3(http://www.url3.com) // |- url4(http://www.url4.com) std::unique_ptr<BookmarkModelView> local_model = - BuildModel({FolderBuilder(kFolder1Title) - .SetChildren({UrlBuilder(kUrl1Title, kUrl1), - UrlBuilder(kUrl2Title, kUrl2)}), - FolderBuilder(kFolder2Title) - .SetChildren({UrlBuilder(kUrl3Title, kUrl3), - UrlBuilder(kUrl4Title, kUrl4)})}); + BuildLocalModel({FolderBuilder(kFolder1Title) + .SetChildren({UrlBuilder(kUrl1Title, kUrl1), + UrlBuilder(kUrl2Title, kUrl2)}), + FolderBuilder(kFolder2Title) + .SetChildren({UrlBuilder(kUrl3Title, kUrl3), + UrlBuilder(kUrl4Title, kUrl4)})}); // -------- The account model -------- // bookmark_bar - std::unique_ptr<BookmarkModelView> account_model = BuildModel({}); + std::unique_ptr<BookmarkModelView> account_model = BuildAccountModel({}); // -------- Exercise the merge logic -------- LocalBookmarkModelMerger(local_model.get(), account_model.get()).Merge(); @@ -216,7 +236,7 @@ MatchesUrl(kUrl4Title, kUrl4))))); } -TEST(LocalBookmarkModelMergerTest, ShouldIgnoreManagedNodes) { +TEST_F(LocalBookmarkModelMergerTest, ShouldIgnoreManagedNodes) { const std::string kUrl1Title = "url1"; const std::string kUrl2Title = "url2"; @@ -243,7 +263,7 @@ // -------- The account model -------- // bookmark_bar - std::unique_ptr<TestBookmarkModelView> account_model = BuildModel({}); + std::unique_ptr<TestBookmarkModelView> account_model = BuildAccountModel({}); // -------- Exercise the merge logic -------- LocalBookmarkModelMerger(&local_model, account_model.get()).Merge(); @@ -260,7 +280,7 @@ IsEmpty()); } -TEST(LocalBookmarkModelMergerTest, ShouldUploadLocalUuid) { +TEST_F(LocalBookmarkModelMergerTest, ShouldUploadLocalUuid) { const std::string kUrl1Title = "url1"; const GURL kUrl1("http://www.url1.com/"); const base::Uuid kUrl1Uuid = base::Uuid::GenerateRandomV4(); @@ -269,11 +289,11 @@ // bookmark_bar // | - bookmark(kUuid/kLocalTitle) std::unique_ptr<BookmarkModelView> local_model = - BuildModel({UrlBuilder(kUrl1Title, kUrl1).SetUuid(kUrl1Uuid)}); + BuildLocalModel({UrlBuilder(kUrl1Title, kUrl1).SetUuid(kUrl1Uuid)}); // -------- The account model -------- // bookmark_bar - std::unique_ptr<BookmarkModelView> account_model = BuildModel({}); + std::unique_ptr<BookmarkModelView> account_model = BuildAccountModel({}); // -------- Exercise the merge logic -------- LocalBookmarkModelMerger(local_model.get(), account_model.get()).Merge(); @@ -284,7 +304,7 @@ ElementsAre(MatchesUrlWithUuid(kUrl1Title, kUrl1, kUrl1Uuid))); } -TEST(LocalBookmarkModelMergerTest, ShouldNotUploadDuplicateBySemantics) { +TEST_F(LocalBookmarkModelMergerTest, ShouldNotUploadDuplicateBySemantics) { const std::string kFolder1Title = "folder1"; const std::string kUrl1Title = "url1"; @@ -301,9 +321,9 @@ // |- url1(http://www.url1.com) // |- url2(http://www.url2.com) std::unique_ptr<BookmarkModelView> local_model = - BuildModel({FolderBuilder(kFolder1Title) - .SetChildren({UrlBuilder(kUrl1Title, kUrl1), - UrlBuilder(kUrl2Title, kUrl2)})}); + BuildLocalModel({FolderBuilder(kFolder1Title) + .SetChildren({UrlBuilder(kUrl1Title, kUrl1), + UrlBuilder(kUrl2Title, kUrl2)})}); // -------- The account model -------- // bookmark_bar @@ -311,9 +331,9 @@ // |- url2(http://www.url2.com) // |- url3(http://www.url3.com) std::unique_ptr<BookmarkModelView> account_model = - BuildModel({FolderBuilder(kFolder1Title) - .SetChildren({UrlBuilder(kUrl2Title, kUrl2), - UrlBuilder(kUrl3Title, kUrl3)})}); + BuildAccountModel({FolderBuilder(kFolder1Title) + .SetChildren({UrlBuilder(kUrl2Title, kUrl2), + UrlBuilder(kUrl3Title, kUrl3)})}); // -------- Exercise the merge logic -------- LocalBookmarkModelMerger(local_model.get(), account_model.get()).Merge(); @@ -331,7 +351,7 @@ MatchesUrl(kUrl1Title, kUrl1))))); } -TEST(LocalBookmarkModelMergerTest, ShouldMergeLocalAndAccountModels) { +TEST_F(LocalBookmarkModelMergerTest, ShouldMergeLocalAndAccountModels) { const std::string kFolder1Title = "folder1"; const std::string kFolder2Title = "folder2"; const std::string kFolder3Title = "folder3"; @@ -356,12 +376,12 @@ // |- url3(http://www.url3.com) // |- url4(http://www.url4.com) std::unique_ptr<BookmarkModelView> local_model = - BuildModel({FolderBuilder(kFolder1Title) - .SetChildren({UrlBuilder(kUrl1Title, kUrl1), - UrlBuilder(kUrl2Title, kUrl2)}), - FolderBuilder(kFolder2Title) - .SetChildren({UrlBuilder(kUrl3Title, kUrl3), - UrlBuilder(kUrl4Title, kUrl4)})}); + BuildLocalModel({FolderBuilder(kFolder1Title) + .SetChildren({UrlBuilder(kUrl1Title, kUrl1), + UrlBuilder(kUrl2Title, kUrl2)}), + FolderBuilder(kFolder2Title) + .SetChildren({UrlBuilder(kUrl3Title, kUrl3), + UrlBuilder(kUrl4Title, kUrl4)})}); // -------- The account model -------- // bookmark_bar @@ -371,13 +391,13 @@ // |- folder 3 // |- url3(http://www.url3.com) // |- url4(http://www.url4.com) - std::unique_ptr<BookmarkModelView> account_model = - BuildModel({FolderBuilder(kFolder1Title) - .SetChildren({UrlBuilder(kUrl1Title, kUrl1), - UrlBuilder(kUrl2Title, kAnotherUrl2)}), - FolderBuilder(kFolder3Title) - .SetChildren({UrlBuilder(kUrl3Title, kUrl3), - UrlBuilder(kUrl4Title, kUrl4)})}); + std::unique_ptr<BookmarkModelView> account_model = BuildAccountModel( + {FolderBuilder(kFolder1Title) + .SetChildren({UrlBuilder(kUrl1Title, kUrl1), + UrlBuilder(kUrl2Title, kAnotherUrl2)}), + FolderBuilder(kFolder3Title) + .SetChildren({UrlBuilder(kUrl3Title, kUrl3), + UrlBuilder(kUrl4Title, kUrl4)})}); // -------- Exercise the merge logic -------- LocalBookmarkModelMerger(local_model.get(), account_model.get()).Merge(); @@ -411,18 +431,18 @@ // This tests that truncated titles produced by legacy clients are properly // matched. -TEST(LocalBookmarkModelMergerTest, - ShouldMergeLocalAndAccountNodesWhenAccountHasLegacyTruncatedTitle) { +TEST_F(LocalBookmarkModelMergerTest, + ShouldMergeLocalAndAccountNodesWhenAccountHasLegacyTruncatedTitle) { const std::string kLocalLongTitle(300, 'A'); const std::string kAccountTruncatedTitle(255, 'A'); // -------- The local model -------- std::unique_ptr<BookmarkModelView> local_model = - BuildModel({FolderBuilder(kLocalLongTitle)}); + BuildLocalModel({FolderBuilder(kLocalLongTitle)}); // -------- The account model -------- std::unique_ptr<BookmarkModelView> account_model = - BuildModel({FolderBuilder(kAccountTruncatedTitle)}); + BuildAccountModel({FolderBuilder(kAccountTruncatedTitle)}); // -------- Exercise the merge logic -------- LocalBookmarkModelMerger(local_model.get(), account_model.get()).Merge(); @@ -434,18 +454,18 @@ // This test checks that local node with truncated title will merge with account // node which has full title. -TEST(LocalBookmarkModelMergerTest, - ShouldMergeLocalAndAccountNodesWhenLocalHasLegacyTruncatedTitle) { +TEST_F(LocalBookmarkModelMergerTest, + ShouldMergeLocalAndAccountNodesWhenLocalHasLegacyTruncatedTitle) { const std::string kAccountFullTitle(300, 'A'); const std::string kLocalTruncatedTitle(255, 'A'); // -------- The local model -------- std::unique_ptr<BookmarkModelView> local_model = - BuildModel({FolderBuilder(kLocalTruncatedTitle)}); + BuildLocalModel({FolderBuilder(kLocalTruncatedTitle)}); // -------- The account model -------- std::unique_ptr<BookmarkModelView> account_model = - BuildModel({FolderBuilder(kAccountFullTitle)}); + BuildAccountModel({FolderBuilder(kAccountFullTitle)}); // -------- Exercise the merge logic -------- LocalBookmarkModelMerger(local_model.get(), account_model.get()).Merge(); @@ -457,7 +477,7 @@ ElementsAre(MatchesFolder(kLocalTruncatedTitle, IsEmpty()))); } -TEST(LocalBookmarkModelMergerTest, ShouldMergeBookmarkByUuid) { +TEST_F(LocalBookmarkModelMergerTest, ShouldMergeBookmarkByUuid) { const std::string kLocalTitle = "Title 1"; const std::string kAccountTitle = "Title 2"; const GURL kUrl("http://www.foo.com/"); @@ -467,13 +487,13 @@ // bookmark_bar // | - bookmark(kUuid/kLocalTitle) std::unique_ptr<BookmarkModelView> local_model = - BuildModel({UrlBuilder(kLocalTitle, kUrl).SetUuid(kUuid)}); + BuildLocalModel({UrlBuilder(kLocalTitle, kUrl).SetUuid(kUuid)}); // -------- The account model -------- // bookmark_bar // | - bookmark(kUuid/kAccountTitle) std::unique_ptr<BookmarkModelView> account_model = - BuildModel({UrlBuilder(kAccountTitle, kUrl).SetUuid(kUuid)}); + BuildAccountModel({UrlBuilder(kAccountTitle, kUrl).SetUuid(kUuid)}); // -------- Exercise the merge logic -------- LocalBookmarkModelMerger(local_model.get(), account_model.get()).Merge(); @@ -485,8 +505,8 @@ ElementsAre(MatchesUrlWithUuid(kLocalTitle, kUrl, kUuid))); } -TEST(LocalBookmarkModelMergerTest, - ShouldMergeBookmarkByUuidDespiteDifferentParent) { +TEST_F(LocalBookmarkModelMergerTest, + ShouldMergeBookmarkByUuidDespiteDifferentParent) { const std::string kFolderTitle = "Folder Title"; const std::string kLocalTitle = "Title 1"; const std::string kAccountTitle = "Title 2"; @@ -497,13 +517,13 @@ // bookmark_bar // |- bookmark(kUuid/kLocalTitle) std::unique_ptr<BookmarkModelView> local_model = - BuildModel({UrlBuilder(kLocalTitle, kUrl).SetUuid(kUuid)}); + BuildLocalModel({UrlBuilder(kLocalTitle, kUrl).SetUuid(kUuid)}); // -------- The account model -------- // bookmark_bar // | - folder // | - bookmark(kUuid/kAccountTitle) - std::unique_ptr<BookmarkModelView> account_model = BuildModel( + std::unique_ptr<BookmarkModelView> account_model = BuildAccountModel( {FolderBuilder(kFolderTitle) .SetChildren({UrlBuilder(kAccountTitle, kUrl).SetUuid(kUuid)})}); @@ -520,7 +540,8 @@ kLocalTitle, kUrl, kUuid))))); } -TEST(LocalBookmarkModelMergerTest, ShouldNotMergeBySemanticsIfDifferentParent) { +TEST_F(LocalBookmarkModelMergerTest, + ShouldNotMergeBySemanticsIfDifferentParent) { const std::string kFolder1Title = "folder1"; const std::string kFolder2Title = "folder2"; @@ -535,7 +556,7 @@ // |- folder 1 // |- folder 2 // |- url1(http://www.url1.com) - std::unique_ptr<BookmarkModelView> local_model = BuildModel( + std::unique_ptr<BookmarkModelView> local_model = BuildLocalModel( {FolderBuilder(kFolder1Title) .SetChildren({FolderBuilder(kFolder2Title) .SetChildren({UrlBuilder(kUrl1Title, kUrl1)})})}); @@ -545,8 +566,8 @@ // |- folder 2 // |- url2(http://www.url2.com) std::unique_ptr<BookmarkModelView> account_model = - BuildModel({FolderBuilder(kFolder2Title) - .SetChildren({UrlBuilder(kUrl2Title, kUrl2)})}); + BuildAccountModel({FolderBuilder(kFolder2Title) + .SetChildren({UrlBuilder(kUrl2Title, kUrl2)})}); // -------- Exercise the merge logic -------- LocalBookmarkModelMerger(local_model.get(), account_model.get()).Merge(); @@ -568,7 +589,7 @@ kUrl1Title, kUrl1))))))); } -TEST(LocalBookmarkModelMergerTest, ShouldMergeFolderByUuidAndNotSemantics) { +TEST_F(LocalBookmarkModelMergerTest, ShouldMergeFolderByUuidAndNotSemantics) { const std::string kTitle1 = "Title 1"; const std::string kTitle2 = "Title 2"; const GURL kUrl("http://www.foo.com/"); @@ -580,14 +601,14 @@ // | - folder 1 (kUuid1/kTitle1) // | - folder 2 (kUuid2/kTitle2) std::unique_ptr<BookmarkModelView> local_model = - BuildModel({FolderBuilder(kTitle1).SetUuid(kUuid1).SetChildren( + BuildLocalModel({FolderBuilder(kTitle1).SetUuid(kUuid1).SetChildren( {FolderBuilder(kTitle2).SetUuid(kUuid2)})}); // -------- The account model -------- // bookmark_bar // | - folder (kUuid2/kTitle1) std::unique_ptr<BookmarkModelView> account_model = - BuildModel({FolderBuilder(kTitle1).SetUuid(kUuid2)}); + BuildAccountModel({FolderBuilder(kTitle1).SetUuid(kUuid2)}); // -------- Exercise the merge logic -------- LocalBookmarkModelMerger(local_model.get(), account_model.get()).Merge(); @@ -604,7 +625,7 @@ MatchesFolderWithUuid(kTitle1, kUuid1, IsEmpty()))); } -TEST( +TEST_F( LocalBookmarkModelMergerTest, ShouldIgnoreFolderSemanticsMatchAndLaterMatchByUuidWithSemanticsNodeFirst) { const std::string kLocalOnlyTitle = "LocalOnlyTitle"; @@ -620,16 +641,16 @@ // | - folder (kUuid2/kLocalOnlyTitle) // | - bookmark std::unique_ptr<BookmarkModelView> local_model = - BuildModel({FolderBuilder(kMatchingTitle).SetUuid(kUuid1), - FolderBuilder(kLocalOnlyTitle) - .SetUuid(kUuid2) - .SetChildren({UrlBuilder(kUrlTitle, kUrl)})}); + BuildLocalModel({FolderBuilder(kMatchingTitle).SetUuid(kUuid1), + FolderBuilder(kLocalOnlyTitle) + .SetUuid(kUuid2) + .SetChildren({UrlBuilder(kUrlTitle, kUrl)})}); // -------- The account model -------- // bookmark_bar // | - folder (kUuid2/kMatchingTitle) std::unique_ptr<BookmarkModelView> account_model = - BuildModel({FolderBuilder(kMatchingTitle).SetUuid(kUuid2)}); + BuildAccountModel({FolderBuilder(kMatchingTitle).SetUuid(kUuid2)}); // -------- Exercise the merge logic -------- LocalBookmarkModelMerger(local_model.get(), account_model.get()).Merge(); @@ -650,8 +671,8 @@ MatchesFolderWithUuid(kMatchingTitle, kUuid1, IsEmpty()))); } -TEST(LocalBookmarkModelMergerTest, - ShouldIgnoreFolderSemanticsMatchAndLaterMatchByUuidWithUuidNodeFirst) { +TEST_F(LocalBookmarkModelMergerTest, + ShouldIgnoreFolderSemanticsMatchAndLaterMatchByUuidWithUuidNodeFirst) { const std::string kLocalOnlyTitle = "LocalOnlyTitle"; const std::string kMatchingTitle = "MatchingTitle"; const base::Uuid kUuid1 = base::Uuid::GenerateRandomV4(); @@ -665,16 +686,16 @@ // | - bookmark // | - folder (kUuid1/kMatchingTitle) std::unique_ptr<BookmarkModelView> local_model = - BuildModel({FolderBuilder(kLocalOnlyTitle) - .SetUuid(kUuid2) - .SetChildren({UrlBuilder(kUrlTitle, kUrl)}), - FolderBuilder(kMatchingTitle).SetUuid(kUuid1)}); + BuildLocalModel({FolderBuilder(kLocalOnlyTitle) + .SetUuid(kUuid2) + .SetChildren({UrlBuilder(kUrlTitle, kUrl)}), + FolderBuilder(kMatchingTitle).SetUuid(kUuid1)}); // -------- The account model -------- // bookmark_bar // | - folder (kUuid2/kMatchingTitle) std::unique_ptr<BookmarkModelView> account_model = - BuildModel({FolderBuilder(kMatchingTitle).SetUuid(kUuid2)}); + BuildAccountModel({FolderBuilder(kMatchingTitle).SetUuid(kUuid2)}); // -------- Exercise the merge logic -------- LocalBookmarkModelMerger(local_model.get(), account_model.get()).Merge(); @@ -695,8 +716,8 @@ MatchesFolderWithUuid(kMatchingTitle, kUuid1, IsEmpty()))); } -TEST(LocalBookmarkModelMergerTest, - ShouldReplaceBookmarkUuidWithConflictingURLs) { +TEST_F(LocalBookmarkModelMergerTest, + ShouldReplaceBookmarkUuidWithConflictingURLs) { const std::string kTitle = "Title"; const GURL kUrl1("http://www.foo.com/"); const GURL kUrl2("http://www.bar.com/"); @@ -706,13 +727,13 @@ // bookmark_bar // | - bookmark (kUuid/kUrl1) std::unique_ptr<BookmarkModelView> local_model = - BuildModel({UrlBuilder(kTitle, kUrl1).SetUuid(kUuid)}); + BuildLocalModel({UrlBuilder(kTitle, kUrl1).SetUuid(kUuid)}); // -------- The account model -------- // bookmark_bar // | - bookmark (kUuid/kUrl2) std::unique_ptr<BookmarkModelView> account_model = - BuildModel({UrlBuilder(kTitle, kUrl2).SetUuid(kUuid)}); + BuildAccountModel({UrlBuilder(kTitle, kUrl2).SetUuid(kUuid)}); // -------- Exercise the merge logic -------- LocalBookmarkModelMerger(local_model.get(), account_model.get()).Merge(); @@ -728,8 +749,8 @@ MatchesUrlWithUuid(kTitle, kUrl1, Ne(kUuid)))); } -TEST(LocalBookmarkModelMergerTest, - ShouldReplaceBookmarkUuidWithConflictingTypes) { +TEST_F(LocalBookmarkModelMergerTest, + ShouldReplaceBookmarkUuidWithConflictingTypes) { const GURL kUrl1("http://www.foo.com/"); const std::string kTitle = "Title"; const base::Uuid kUuid = base::Uuid::GenerateRandomV4(); @@ -738,13 +759,13 @@ // bookmark_bar // | - bookmark (kUuid/kUrl1) std::unique_ptr<BookmarkModelView> local_model = - BuildModel({UrlBuilder(kTitle, kUrl1).SetUuid(kUuid)}); + BuildLocalModel({UrlBuilder(kTitle, kUrl1).SetUuid(kUuid)}); // -------- The account model -------- // bookmark_bar // | - folder(kUuid) std::unique_ptr<BookmarkModelView> account_model = - BuildModel({FolderBuilder(kTitle).SetUuid(kUuid)}); + BuildAccountModel({FolderBuilder(kTitle).SetUuid(kUuid)}); // -------- Exercise the merge logic -------- LocalBookmarkModelMerger(local_model.get(), account_model.get()).Merge(); @@ -760,8 +781,8 @@ MatchesUrlWithUuid(kTitle, kUrl1, Ne(kUuid)))); } -TEST(LocalBookmarkModelMergerTest, - ShouldReplaceBookmarkUuidWithConflictingTypesAndLocalChildren) { +TEST_F(LocalBookmarkModelMergerTest, + ShouldReplaceBookmarkUuidWithConflictingTypesAndLocalChildren) { const std::string kFolderTitle = "Folder Title"; const std::string kUrl1Title = "url1"; const std::string kUrl2Title = "url2"; @@ -774,15 +795,15 @@ // | - folder (kUuid) // | - bookmark (kUrl1) std::unique_ptr<BookmarkModelView> local_model = - BuildModel({FolderBuilder(kFolderTitle) - .SetUuid(kUuid) - .SetChildren({UrlBuilder(kUrl1Title, kUrl1)})}); + BuildLocalModel({FolderBuilder(kFolderTitle) + .SetUuid(kUuid) + .SetChildren({UrlBuilder(kUrl1Title, kUrl1)})}); // -------- The account model -------- // bookmark_bar // | - bookmark (kUuid/kUrl2) std::unique_ptr<BookmarkModelView> account_model = - BuildModel({UrlBuilder(kUrl2Title, kUrl2).SetUuid(kUuid)}); + BuildAccountModel({UrlBuilder(kUrl2Title, kUrl2).SetUuid(kUuid)}); // -------- Exercise the merge logic -------- LocalBookmarkModelMerger(local_model.get(), account_model.get()).Merge(); @@ -801,4 +822,6 @@ ElementsAre(MatchesUrl(kUrl1Title, kUrl1))))); } +} // namespace + } // namespace sync_bookmarks
diff --git a/components/test/data/autofill/heuristics-json/internal b/components/test/data/autofill/heuristics-json/internal index d632ed4..d541923 160000 --- a/components/test/data/autofill/heuristics-json/internal +++ b/components/test/data/autofill/heuristics-json/internal
@@ -1 +1 @@ -Subproject commit d632ed48ff308e208535023924de938ae723a1cb +Subproject commit d541923921b7b51397af7f095f4ecc7779d0aa22
diff --git a/components/user_manager/fake_user_manager.cc b/components/user_manager/fake_user_manager.cc index c92d01656..edc27a6 100644 --- a/components/user_manager/fake_user_manager.cc +++ b/components/user_manager/fake_user_manager.cc
@@ -278,10 +278,6 @@ return false; } -bool FakeUserManager::CanCurrentUserLock() const { - return false; -} - bool FakeUserManager::IsUserLoggedIn() const { return logged_in_users_.size() > 0; }
diff --git a/components/user_manager/fake_user_manager.h b/components/user_manager/fake_user_manager.h index bff5079..e80b863 100644 --- a/components/user_manager/fake_user_manager.h +++ b/components/user_manager/fake_user_manager.h
@@ -98,7 +98,6 @@ const std::string& display_email) override {} std::optional<std::string> GetOwnerEmail() override; bool IsCurrentUserNonCryptohomeDataEphemeral() const override; - bool CanCurrentUserLock() const override; bool IsUserLoggedIn() const override; bool IsLoggedInAsUserWithGaiaAccount() const override; bool IsLoggedInAsManagedGuestSession() const override;
diff --git a/components/user_manager/user.cc b/components/user_manager/user.cc index fd558f7..8163865 100644 --- a/components/user_manager/user.cc +++ b/components/user_manager/user.cc
@@ -8,12 +8,14 @@ #include <memory> +#include "ash/constants/ash_pref_names.h" #include "base/functional/callback.h" #include "base/logging.h" #include "base/metrics/histogram_macros.h" #include "base/strings/utf_string_conversions.h" #include "base/threading/thread_restrictions.h" #include "components/account_id/account_id.h" +#include "components/prefs/pref_service.h" #include "components/user_manager/user_manager.h" #include "google_apis/gaia/gaia_auth_util.h" @@ -73,11 +75,6 @@ // so they do not set |display_email_|. break; } - - if (type_ == user_manager::UserType::kRegular || - type_ == user_manager::UserType::kChild) { - set_can_lock(true); - } } User::~User() = default; @@ -148,6 +145,31 @@ return GetUserName(account_id_.GetUserEmail()); } +bool User::CanLock() const { + switch (type_) { + case user_manager::UserType::kRegular: + case user_manager::UserType::kChild: + if (!profile_prefs_) { + return false; + } + break; + case user_manager::UserType::kKioskApp: + case user_manager::UserType::kArcKioskApp: + case user_manager::UserType::kWebKioskApp: + case user_manager::UserType::kGuest: + return false; + case user_manager::UserType::kPublicAccount: + if (!profile_prefs_ || + !profile_prefs_->GetBoolean( + ash::prefs::kLoginExtensionApiCanLockManagedGuestSession)) { + return false; + } + break; + } + + return profile_prefs_->GetBoolean(ash::prefs::kAllowScreenLock); +} + bool User::HasDefaultImage() const { return UserManager::Get()->IsValidDefaultUserImageId(image_index_); } @@ -156,10 +178,6 @@ return display_email_; } -bool User::can_lock() const { - return can_lock_; -} - const std::string& User::username_hash() const { return username_hash_; }
diff --git a/components/user_manager/user.h b/components/user_manager/user.h index 64e1b9a..2548ac1 100644 --- a/components/user_manager/user.h +++ b/components/user_manager/user.h
@@ -143,6 +143,12 @@ // email if available and use_display_name == true. Otherwise use canonical. std::string GetAccountName(bool use_display_email) const; + // True if the user's session can be locked (i.e. the user has a password with + // which to unlock the session). + // This depends on Profile preference, and if it's not yet ready, this + // returns false as fallback. + bool CanLock() const; + // Whether the user has a default image. bool HasDefaultImage() const; @@ -179,10 +185,6 @@ // user's next sign-in. bool force_online_signin() const { return force_online_signin_; } - // True if the user's session can be locked (i.e. the user has a password with - // which to unlock the session). - bool can_lock() const; - // Returns empty string when home dir hasn't been mounted yet. const std::string& username_hash() const; @@ -288,8 +290,6 @@ void set_is_logged_in(bool is_logged_in) { is_logged_in_ = is_logged_in; } - void set_can_lock(bool can_lock) { can_lock_ = can_lock; } - void set_is_active(bool is_active) { is_active_ = is_active; } void SetProfileIsCreated(); @@ -332,9 +332,6 @@ // True if current user image is being loaded from file. bool image_is_loading_ = false; - // True if user is able to lock screen. - bool can_lock_ = false; - // True if user is currently logged in in current session. bool is_logged_in_ = false;
diff --git a/components/user_manager/user_manager.h b/components/user_manager/user_manager.h index 15c391d..dd7ac80b 100644 --- a/components/user_manager/user_manager.h +++ b/components/user_manager/user_manager.h
@@ -372,10 +372,6 @@ // user's cryptohome is ephemeral. virtual bool IsCurrentUserCryptohomeDataEphemeral() const = 0; - // Returns true if the current user's session can be locked (i.e. the user has - // a password with which to unlock the session). - virtual bool CanCurrentUserLock() const = 0; - // Returns true if at least one user has signed in. virtual bool IsUserLoggedIn() const = 0;
diff --git a/components/user_manager/user_manager_base.cc b/components/user_manager/user_manager_base.cc index c458073d..677966d 100644 --- a/components/user_manager/user_manager_base.cc +++ b/components/user_manager/user_manager_base.cc
@@ -659,11 +659,6 @@ IsUserCryptohomeDataEphemeral(GetActiveUser()->GetAccountId()); } -bool UserManagerBase::CanCurrentUserLock() const { - DCHECK(!task_runner_ || task_runner_->RunsTasksInCurrentSequence()); - return IsUserLoggedIn() && active_user_->can_lock(); -} - bool UserManagerBase::IsUserLoggedIn() const { DCHECK(!task_runner_ || task_runner_->RunsTasksInCurrentSequence()); return active_user_; @@ -1142,14 +1137,6 @@ user->SetProfileIsCreated(); user->SetProfilePrefs(prefs); - // Managed Guest Sessions can be lockable if launched via the chrome.login - // extension API. - if (user->GetType() == user_manager::UserType::kPublicAccount && prefs && - prefs->GetBoolean( - ash::prefs::kLoginExtensionApiCanLockManagedGuestSession)) { - user->set_can_lock(true); - } - for (auto& observer : observer_list_) { observer.OnUserProfileCreated(*user); }
diff --git a/components/user_manager/user_manager_base.h b/components/user_manager/user_manager_base.h index 8c001db..4109cf0 100644 --- a/components/user_manager/user_manager_base.h +++ b/components/user_manager/user_manager_base.h
@@ -134,7 +134,6 @@ void SetIsCurrentUserNew(bool is_new) override; bool IsCurrentUserNonCryptohomeDataEphemeral() const override; bool IsCurrentUserCryptohomeDataEphemeral() const override; - bool CanCurrentUserLock() const override; bool IsUserLoggedIn() const override; bool IsLoggedInAsUserWithGaiaAccount() const override; bool IsLoggedInAsChildUser() const override;
diff --git a/components/viz/service/display_embedder/image_context_impl.cc b/components/viz/service/display_embedder/image_context_impl.cc index be873f0..14cfe31 100644 --- a/components/viz/service/display_embedder/image_context_impl.cc +++ b/components/viz/service/display_embedder/image_context_impl.cc
@@ -149,10 +149,11 @@ for (int plane_index = 0; plane_index < num_planes; plane_index++) { SkISize sk_size = gfx::SizeToSkISize(format().GetPlaneSize(plane_index, size())); - + auto tex_info = + gpu::FallbackGraphiteBackendTextureInfo(tex_infos[plane_index]); graphite_fallback_textures_.push_back( context_state->gpu_main_graphite_recorder()->createBackendTexture( - sk_size, tex_infos[plane_index])); + sk_size, tex_info)); SkColorType color_type = ToClosestSkColorType(/*gpu_compositing=*/true, format(), plane_index);
diff --git a/components/viz/service/display_embedder/skia_output_surface_dependency.h b/components/viz/service/display_embedder/skia_output_surface_dependency.h index fa4992262..5b2c881 100644 --- a/components/viz/service/display_embedder/skia_output_surface_dependency.h +++ b/components/viz/service/display_embedder/skia_output_surface_dependency.h
@@ -30,7 +30,6 @@ class DawnContextProvider; class GpuDriverBugWorkarounds; -class ImageTransportSurfaceDelegate; class MailboxManager; class SharedContextState; class SharedImageManager; @@ -80,10 +79,8 @@ // return kNullSurfaceHandle. virtual bool IsOffscreen() = 0; virtual gpu::SurfaceHandle GetSurfaceHandle() = 0; - virtual scoped_refptr<gl::Presenter> CreatePresenter( - base::WeakPtr<gpu::ImageTransportSurfaceDelegate> stub) = 0; + virtual scoped_refptr<gl::Presenter> CreatePresenter() = 0; virtual scoped_refptr<gl::GLSurface> CreateGLSurface( - base::WeakPtr<gpu::ImageTransportSurfaceDelegate> stub, gl::GLSurfaceFormat format) = 0; // Hold a ref of the given surface until the returned closure is fired. virtual base::ScopedClosureRunner CacheGLSurface(gl::GLSurface* surface) = 0;
diff --git a/components/viz/service/display_embedder/skia_output_surface_dependency_impl.cc b/components/viz/service/display_embedder/skia_output_surface_dependency_impl.cc index 0e546d5..23a3f75 100644 --- a/components/viz/service/display_embedder/skia_output_surface_dependency_impl.cc +++ b/components/viz/service/display_embedder/skia_output_surface_dependency_impl.cc
@@ -102,8 +102,8 @@ return surface_handle_; } -scoped_refptr<gl::Presenter> SkiaOutputSurfaceDependencyImpl::CreatePresenter( - base::WeakPtr<gpu::ImageTransportSurfaceDelegate> stub) { +scoped_refptr<gl::Presenter> +SkiaOutputSurfaceDependencyImpl::CreatePresenter() { DCHECK(!IsOffscreen()); auto context_state = GetSharedContextState(); @@ -116,21 +116,16 @@ } #endif - auto presenter = gpu::ImageTransportSurface::CreatePresenter( - context_state->display(), stub, surface_handle_); - if (presenter && - GetGpuDriverBugWorkarounds().rely_on_implicit_sync_for_swap_buffers) { - presenter->SetRelyOnImplicitSync(); - } - return presenter; + return gpu::ImageTransportSurface::CreatePresenter( + context_state->display(), GetGpuDriverBugWorkarounds(), + GetGpuFeatureInfo(), surface_handle_); } scoped_refptr<gl::GLSurface> SkiaOutputSurfaceDependencyImpl::CreateGLSurface( - base::WeakPtr<gpu::ImageTransportSurfaceDelegate> stub, gl::GLSurfaceFormat format) { CHECK(!IsOffscreen()); return gpu::ImageTransportSurface::CreateNativeGLSurface( - GetSharedContextState()->display(), stub, surface_handle_, format); + GetSharedContextState()->display(), surface_handle_, format); } base::ScopedClosureRunner SkiaOutputSurfaceDependencyImpl::CachePresenter(
diff --git a/components/viz/service/display_embedder/skia_output_surface_dependency_impl.h b/components/viz/service/display_embedder/skia_output_surface_dependency_impl.h index 2b00c4e..1066875 100644 --- a/components/viz/service/display_embedder/skia_output_surface_dependency_impl.h +++ b/components/viz/service/display_embedder/skia_output_surface_dependency_impl.h
@@ -47,10 +47,8 @@ bool IsOffscreen() override; gpu::SurfaceHandle GetSurfaceHandle() override; scoped_refptr<gl::GLSurface> CreateGLSurface( - base::WeakPtr<gpu::ImageTransportSurfaceDelegate> stub, gl::GLSurfaceFormat format) override; - scoped_refptr<gl::Presenter> CreatePresenter( - base::WeakPtr<gpu::ImageTransportSurfaceDelegate> stub) override; + scoped_refptr<gl::Presenter> CreatePresenter() override; base::ScopedClosureRunner CachePresenter(gl::Presenter* presenter) override; base::ScopedClosureRunner CacheGLSurface(gl::GLSurface* surface) override; scoped_refptr<base::TaskRunner> GetClientTaskRunner() override;
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc index 76b5e571..f3b3e35 100644 --- a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc +++ b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc
@@ -2131,7 +2131,7 @@ shared_gpu_deps_->memory_tracker(), GetDidSwapBuffersCompleteCallback()); } else { - presenter_ = dependency_->CreatePresenter(weak_ptr_factory_.GetWeakPtr()); + presenter_ = dependency_->CreatePresenter(); if (!presenter_) { gl::GLSurfaceFormat format; #if BUILDFLAG(IS_ANDROID) @@ -2140,8 +2140,7 @@ format.SetRGB565(); } #endif - gl_surface_ = - dependency_->CreateGLSurface(weak_ptr_factory_.GetWeakPtr(), format); + gl_surface_ = dependency_->CreateGLSurface(format); if (!gl_surface_) { return false; } @@ -2166,6 +2165,7 @@ shared_gpu_deps_->memory_tracker(), GetDidSwapBuffersCompleteCallback(), GetReleaseOverlaysCallback()); #else // !BUILDFLAG(IS_WIN) + AddChildWindowToBrowser(presenter_->GetWindow()); output_device_ = std::make_unique<SkiaOutputDeviceDComp>( dependency_, shared_image_factory_.get(), shared_image_representation_factory_.get(), context_state_.get(), @@ -2237,7 +2237,7 @@ output_presenter = OutputPresenterFuchsia::Create(window_surface_.get(), dependency_); #else - presenter_ = dependency_->CreatePresenter(weak_ptr_factory_.GetWeakPtr()); + presenter_ = dependency_->CreatePresenter(); if (presenter_) { output_presenter = std::make_unique<OutputPresenterGL>( presenter_, dependency_, shared_image_factory_.get(), @@ -2318,7 +2318,7 @@ } #elif BUILDFLAG(IS_WIN) - presenter_ = dependency_->CreatePresenter(weak_ptr_factory_.GetWeakPtr()); + presenter_ = dependency_->CreatePresenter(); if (presenter_) { output_device_ = std::make_unique<SkiaOutputDeviceDComp>( dependency_, shared_image_factory_.get(), @@ -2339,7 +2339,7 @@ return true; #elif BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_CHROMEOS) - presenter_ = dependency_->CreatePresenter(weak_ptr_factory_.GetWeakPtr()); + presenter_ = dependency_->CreatePresenter(); #if BUILDFLAG(IS_ANDROID) if (!presenter_) { @@ -2385,7 +2385,7 @@ shared_gpu_deps_->memory_tracker(), GetDidSwapBuffersCompleteCallback()); } else { - presenter_ = dependency_->CreatePresenter(weak_ptr_factory_.GetWeakPtr()); + presenter_ = dependency_->CreatePresenter(); CHECK(presenter_); #if BUILDFLAG(IS_MAC) @@ -2631,11 +2631,6 @@ return feature_info_.get(); } -const gpu::GpuPreferences& SkiaOutputSurfaceImplOnGpu::GetGpuPreferences() - const { - return gpu_preferences_; -} - void SkiaOutputSurfaceImplOnGpu::DidSwapBuffersCompleteInternal( gpu::SwapBuffersCompleteParams params, const gfx::Size& pixel_size,
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h index f5d4ece..e3703e2e 100644 --- a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h +++ b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h
@@ -35,7 +35,6 @@ #include "gpu/command_buffer/common/sync_token.h" #include "gpu/command_buffer/service/shared_context_state.h" #include "gpu/command_buffer/service/shared_image/shared_image_representation.h" -#include "gpu/ipc/service/image_transport_surface_delegate.h" #include "media/gpu/buildflags.h" #include "mojo/public/cpp/bindings/pending_receiver.h" #include "third_party/skia/include/core/SkSurface.h" @@ -95,8 +94,7 @@ // The SkiaOutputSurface implementation running on the GPU thread. This class // should be created, used and destroyed on the GPU thread. class SkiaOutputSurfaceImplOnGpu - : public gpu::ImageTransportSurfaceDelegate, - public gpu::SharedContextState::ContextLostObserver { + : public gpu::SharedContextState::ContextLostObserver { public: using DidSwapBufferCompleteCallback = base::RepeatingCallback<void(gpu::SwapBuffersCompleteParams, @@ -243,12 +241,10 @@ // gpu::SharedContextState::ContextLostObserver implementation: void OnContextLost() override; - // gpu::ImageTransportSurfaceDelegate implementation: #if BUILDFLAG(IS_WIN) - void AddChildWindowToBrowser(gpu::SurfaceHandle child_window) override; + void AddChildWindowToBrowser(gpu::SurfaceHandle child_window); #endif - const gpu::gles2::FeatureInfo* GetFeatureInfo() const override; - const gpu::GpuPreferences& GetGpuPreferences() const override; + const gpu::gles2::FeatureInfo* GetFeatureInfo() const; void PostTaskToClientThread(base::OnceClosure closure) { dependency_->PostTaskToClientThread(std::move(closure));
diff --git a/components/viz/test/test_raster_interface.cc b/components/viz/test/test_raster_interface.cc index 9167688a9..fb002d9 100644 --- a/components/viz/test/test_raster_interface.cc +++ b/components/viz/test/test_raster_interface.cc
@@ -202,4 +202,16 @@ } } +bool TestRasterInterface::ReadbackImagePixels( + const gpu::Mailbox& source_mailbox, + const SkImageInfo& dst_info, + GLuint dst_row_bytes, + int src_x, + int src_y, + int plane_index, + void* dst_pixels) { + auto size = dst_info.computeByteSize(dst_row_bytes); + memset(dst_pixels, 0, size); + return true; +} } // namespace viz
diff --git a/components/viz/test/test_raster_interface.h b/components/viz/test/test_raster_interface.h index 805e2acee..18026a0 100644 --- a/components/viz/test/test_raster_interface.h +++ b/components/viz/test/test_raster_interface.h
@@ -154,13 +154,13 @@ const gfx::Point& paste_location, base::OnceCallback<void()> release_mailbox, base::OnceCallback<void(bool)> readback_done) override {} - void ReadbackImagePixels(const gpu::Mailbox& source_mailbox, + bool ReadbackImagePixels(const gpu::Mailbox& source_mailbox, const SkImageInfo& dst_info, GLuint dst_row_bytes, int src_x, int src_y, int plane_index, - void* dst_pixels) override {} + void* dst_pixels) override; GLuint CreateAndConsumeForGpuRaster(const gpu::Mailbox& mailbox) override; GLuint CreateAndConsumeForGpuRaster( const scoped_refptr<gpu::ClientSharedImage>& shared_image) override;
diff --git a/components/webapps/browser/android/java/src/org/chromium/components/webapps/pwa_restore_ui/PwaRestoreBottomSheetCoordinator.java b/components/webapps/browser/android/java/src/org/chromium/components/webapps/pwa_restore_ui/PwaRestoreBottomSheetCoordinator.java index 941f131..e6be2de 100644 --- a/components/webapps/browser/android/java/src/org/chromium/components/webapps/pwa_restore_ui/PwaRestoreBottomSheetCoordinator.java +++ b/components/webapps/browser/android/java/src/org/chromium/components/webapps/pwa_restore_ui/PwaRestoreBottomSheetCoordinator.java
@@ -31,7 +31,6 @@ @MainThread public PwaRestoreBottomSheetCoordinator( @NonNull String[][] appList, - @NonNull int[] lastUsedInDays, Activity activity, BottomSheetController bottomSheetController, int backArrowId) { @@ -39,14 +38,8 @@ ArrayList<PwaRestoreProperties.AppInfo> recentApps = new ArrayList(); ArrayList<PwaRestoreProperties.AppInfo> olderApps = new ArrayList(); - int i = 0; for (String[] app : appList) { - if (lastUsedInDays[i] < CUTOFF_FOR_OLDER_APPS_IN_DAYS) { - recentApps.add(new PwaRestoreProperties.AppInfo(app[0], app[1], lastUsedInDays[i])); - } else { - olderApps.add(new PwaRestoreProperties.AppInfo(app[0], app[1], lastUsedInDays[i])); - } - i++; + recentApps.add(new PwaRestoreProperties.AppInfo(app[0], app[1], 0)); } mView = new PwaRestoreBottomSheetView(activity);
diff --git a/components/webapps/browser/android/java/src/org/chromium/components/webapps/pwa_restore_ui/PwaRestoreBottomSheetCoordinatorTest.java b/components/webapps/browser/android/java/src/org/chromium/components/webapps/pwa_restore_ui/PwaRestoreBottomSheetCoordinatorTest.java index b9b86a3..45691c3f 100644 --- a/components/webapps/browser/android/java/src/org/chromium/components/webapps/pwa_restore_ui/PwaRestoreBottomSheetCoordinatorTest.java +++ b/components/webapps/browser/android/java/src/org/chromium/components/webapps/pwa_restore_ui/PwaRestoreBottomSheetCoordinatorTest.java
@@ -49,8 +49,6 @@ {"appId2", "App 2"}, {"appId3", "App 3"}, }; - // How long ago (in days) since the apps in the mDefaultAppList were used. - private final int[] mLastUsedList = new int[] {1, 1, 35}; @Mock private BottomSheetController mBottomSheetControllerMock; @@ -71,7 +69,6 @@ PwaRestoreBottomSheetCoordinator coordinator = new PwaRestoreBottomSheetCoordinator( mDefaultAppList, - mLastUsedList, mActivity, mBottomSheetControllerMock, /* backArrowId= */ 0); @@ -120,7 +117,6 @@ PwaRestoreBottomSheetCoordinator coordinator = new PwaRestoreBottomSheetCoordinator( mDefaultAppList, - mLastUsedList, mActivity, mBottomSheetControllerMock, /* backArrowId= */ 0);
diff --git a/components/webapps/browser/android/java/src/org/chromium/components/webapps/pwa_restore_ui/PwaRestoreBottomSheetViewRenderTest.java b/components/webapps/browser/android/java/src/org/chromium/components/webapps/pwa_restore_ui/PwaRestoreBottomSheetViewRenderTest.java index 471e97a8..6f4b57f1 100644 --- a/components/webapps/browser/android/java/src/org/chromium/components/webapps/pwa_restore_ui/PwaRestoreBottomSheetViewRenderTest.java +++ b/components/webapps/browser/android/java/src/org/chromium/components/webapps/pwa_restore_ui/PwaRestoreBottomSheetViewRenderTest.java
@@ -85,10 +85,9 @@ {"bar", "Foo"}, {"foobar", "Barfoo"}, }; - int[] lastUsedList = {1, 2, 3}; mCoordinator = new PwaRestoreBottomSheetCoordinator( - appList, lastUsedList, sActivity, null, R.drawable.ic_arrow_back_24dp); + appList, sActivity, null, R.drawable.ic_arrow_back_24dp); PropertyModel model = mCoordinator.getModelForTesting(); model.set(PwaRestoreProperties.VIEW_STATE, PwaRestoreProperties.ViewState.PREVIEW);
diff --git a/content/browser/content_index/content_index_browsertest.cc b/content/browser/content_index/content_index_browsertest.cc index 38ca39d..4e4f1e0 100644 --- a/content/browser/content_index/content_index_browsertest.cc +++ b/content/browser/content_index/content_index_browsertest.cc
@@ -194,7 +194,8 @@ std::string result = RunScriptWithResult( "addContent('id2', [{src: '/single_face.jpg'}], 'forcefail')"); EXPECT_EQ(result, - "TypeError - The provided launch URL is not offline-capable."); + "TypeError - Failed to execute 'add' on 'ContentIndex': The " + "provided launch URL is not offline-capable."); } } // namespace
diff --git a/content/browser/fenced_frame/fenced_frame_config.h b/content/browser/fenced_frame/fenced_frame_config.h index f7b766e..a671673 100644 --- a/content/browser/fenced_frame/fenced_frame_config.h +++ b/content/browser/fenced_frame/fenced_frame_config.h
@@ -515,9 +515,8 @@ } // Safe to call multiple times (will do nothing after the first time). - void DisableUntrustedNetwork() { + void MarkUntrustedNetworkDisabled() { CHECK(can_disable_untrusted_network_); - // TODO(crbug.com/1294933): Actually disable network. has_disabled_untrusted_network_ = true; }
diff --git a/content/browser/interest_group/auction_runner.cc b/content/browser/interest_group/auction_runner.cc index 016c3b5..c8409c09 100644 --- a/content/browser/interest_group/auction_runner.cc +++ b/content/browser/interest_group/auction_runner.cc
@@ -230,13 +230,14 @@ "Invalid auction ID in ResolvedDeprecatedRenderURLReplacementsPromise"); return; } - if (!config->deprecated_render_url_replacements.is_promise()) { + if (!config->non_shared_params.deprecated_render_url_replacements + .is_promise()) { mojo::ReportBadMessage( "ResolvedDeprecatedRenderURLReplacementsPromise updating non-promise"); return; } - config->deprecated_render_url_replacements = + config->non_shared_params.deprecated_render_url_replacements = blink::AuctionConfig::MaybePromiseDeprecatedRenderURLReplacements:: FromValue(deprecated_render_url_replacements); NotifyPromiseResolved(auction_id.get(), config);
diff --git a/content/browser/interest_group/interest_group_auction.cc b/content/browser/interest_group/interest_group_auction.cc index c7d58ba..0e42803 100644 --- a/content/browser/interest_group/interest_group_auction.cc +++ b/content/browser/interest_group/interest_group_auction.cc
@@ -3821,7 +3821,7 @@ const std::vector<blink::AuctionConfig::AdKeywordReplacement>& InterestGroupAuction::GetDeprecatedRenderURLReplacements() { - return config_->deprecated_render_url_replacements.value(); + return config_->non_shared_params.deprecated_render_url_replacements.value(); } InterestGroupAuction::LeaderInfo::LeaderInfo() = default;
diff --git a/content/browser/interest_group/interest_group_browsertest.cc b/content/browser/interest_group/interest_group_browsertest.cc index 9dc8ccc..c1fe55e 100644 --- a/content/browser/interest_group/interest_group_browsertest.cc +++ b/content/browser/interest_group/interest_group_browsertest.cc
@@ -9036,12 +9036,17 @@ seller: $1, decisionLogicURL: $2, interestGroupBuyers: [$1], + // Signal for verifying that what goes into scoreAd matches + // the deprecatedRenderURLReplacements. + sellerSignals: {deprecatedRenderURLReplacementsExpected: undefined}, deprecatedRenderURLReplacements: maybePromise({$3: "render_cars", "%%echo%%": "echo"}) })", test_origin, embedded_https_test_server().GetURL( - "a.test", "/interest_group/decision_logic.js"), + "a.test", + "/interest_group/" + "decision_logic_deprecated_render_url_replacements_validator.js"), "${INTEREST_GROUP_NAME}"); auto result = RunAuctionAndWait(auction_config, /*execution_target=*/std::nullopt); @@ -9159,12 +9164,18 @@ seller: $1, decisionLogicURL: $2, interestGroupBuyers: [$1], + // Signal for verifying that what goes into scoreAd matches + // the deprecatedRenderURLReplacements. + sellerSignals: {deprecatedRenderURLReplacementsExpected: + {$3: "render_cars", "%%echo%%": "echo"}}, deprecatedRenderURLReplacements: maybePromise({$3: "render_cars", "%%echo%%": "echo"}) })", test_origin, embedded_https_test_server().GetURL( - "a.test", "/interest_group/decision_logic.js"), + "a.test", + "/interest_group/" + "decision_logic_deprecated_render_url_replacements_validator.js"), "${INTEREST_GROUP_NAME}"); auto result = RunAuctionAndWait(auction_config); GURL urn_url = GURL(result.ExtractString()); @@ -9318,6 +9329,9 @@ // Signal to the top-level seller to allow participation in a // component auction. auctionSignals: "sellerAllowsComponentAuction", + // Signal for verifying that what goes into scoreAd matches + // the deprecatedRenderURLReplacements. + sellerSignals: {deprecatedRenderURLReplacementsExpected: undefined}, componentAuctions: [{ seller: $1, decisionLogicURL: $2, @@ -9326,13 +9340,19 @@ // in a component auction. auctionSignals: "bidderAllowsComponentAuction,"+ "sellerAllowsComponentAuction", + // Signal for verifying that what goes into scoreAd matches + // the deprecatedRenderURLReplacements. + sellerSignals: {deprecatedRenderURLReplacementsExpected: + {$3: "render_cars", "%%echo%%": "echo"}}, deprecatedRenderURLReplacements: maybePromise({$3: "render_cars", "%%echo%%": "echo"}) }] })", test_origin, embedded_https_test_server().GetURL( - "a.test", "/interest_group/decision_logic.js"), + "a.test", + "/interest_group/" + "decision_logic_deprecated_render_url_replacements_validator.js"), "${INTEREST_GROUP_NAME}"); auto result = RunAuctionAndWait(auction_config); GURL urn_url = GURL(result.ExtractString());
diff --git a/content/browser/preloading/prefetch/prefetch_container.cc b/content/browser/preloading/prefetch/prefetch_container.cc index 0d7df99..2a39822 100644 --- a/content/browser/preloading/prefetch/prefetch_container.cc +++ b/content/browser/preloading/prefetch/prefetch_container.cc
@@ -1315,10 +1315,7 @@ // separate network context, which means responses cached before the prefetch // are not visible to the prefetch, and anything cached by this request will // not be visible outside of the network context. - request->load_flags = - base::FeatureList::IsEnabled(features::kPrefetchUsesHTTPCache) - ? net::LOAD_PREFETCH - : net::LOAD_DISABLE_CACHE | net::LOAD_PREFETCH; + request->load_flags = net::LOAD_PREFETCH; request->credentials_mode = network::mojom::CredentialsMode::kInclude; request->headers.MergeFrom(additional_headers); request->headers.SetHeader(kCorsExemptPurposeHeaderName, "prefetch");
diff --git a/content/browser/preloading/prefetch/prefetch_features.cc b/content/browser/preloading/prefetch/prefetch_features.cc index d58d6a8..b980740 100644 --- a/content/browser/preloading/prefetch/prefetch_features.cc +++ b/content/browser/preloading/prefetch/prefetch_features.cc
@@ -26,10 +26,6 @@ "PrefetchBrowserInitiatedTriggers", base::FEATURE_DISABLED_BY_DEFAULT); -BASE_FEATURE(kPrefetchUsesHTTPCache, - "PrefetchUsesHTTPCache", - base::FEATURE_ENABLED_BY_DEFAULT); - BASE_FEATURE(kPrefetchClientHints, "PrefetchClientHints", base::FEATURE_ENABLED_BY_DEFAULT);
diff --git a/content/browser/preloading/prerender/prerender_browsertest.cc b/content/browser/preloading/prerender/prerender_browsertest.cc index a4d564e..15f29cac 100644 --- a/content/browser/preloading/prerender/prerender_browsertest.cc +++ b/content/browser/preloading/prerender/prerender_browsertest.cc
@@ -1135,20 +1135,16 @@ enum class PrerenderingResult { kSuccess, kFailed }; enum class BodySize { kSmall, kLarge }; -enum class PrefetchHTTPCache { kEnabled, kDisabled }; class PrerenderAndPrefetchBrowserTest : public PrerenderBrowserTest, - public testing::WithParamInterface<std::tuple<PrerenderingResult, - BodySize, - PrefetchReusableForTests, - PrefetchHTTPCache>> { + public testing::WithParamInterface< + std::tuple<PrerenderingResult, BodySize, PrefetchReusableForTests>> { public: // Provides meaningful param names instead of /0, /1, ... static std::string DescribeParams( const testing::TestParamInfo<ParamType>& info) { - auto [prerendering_result, body_size, prefetch_reusable, - prefetch_uses_http_cache] = info.param; + auto [prerendering_result, body_size, prefetch_reusable] = info.param; std::stringstream params_description; switch (prerendering_result) { case PrerenderingResult::kSuccess: @@ -1174,14 +1170,6 @@ params_description << "_PrefetchReusableDisabled"; break; } - switch (prefetch_uses_http_cache) { - case PrefetchHTTPCache::kEnabled: - params_description << "_SameSitePrefetchUsesHTTPCacheEnabled"; - break; - case PrefetchHTTPCache::kDisabled: - params_description << "_SameSitePrefetchUsesHTTPCacheDisabled"; - break; - } return params_description.str(); } @@ -1203,15 +1191,6 @@ break; } - switch (std::get<PrefetchHTTPCache>(GetParam())) { - case PrefetchHTTPCache::kEnabled: - enabled_features.push_back({features::kPrefetchUsesHTTPCache, {}}); - break; - case PrefetchHTTPCache::kDisabled: - disabled_features.push_back(features::kPrefetchUsesHTTPCache); - break; - } - sub_feature_list_.InitWithFeaturesAndParameters(enabled_features, disabled_features); PrerenderBrowserTest::SetUp(); @@ -1304,16 +1283,10 @@ EXPECT_EQ(delivery_type, "navigational-prefetch"); } else { // The prefetched result can't be used for navigation for large body - // due to PrefetchDataPipeTee buffer limit. - if (std::get<3>(GetParam()) == PrefetchHTTPCache::kEnabled) { - // A cached response from the HTTP cache is used instead, we still - // should not see another request. - EXPECT_EQ(GetRequestCount(kPrerenderingUrl), 1); - EXPECT_EQ(delivery_type, "cache"); - } else { - EXPECT_EQ(GetRequestCount(kPrerenderingUrl), 2); - EXPECT_EQ(delivery_type, ""); - } + // due to PrefetchDataPipeTee buffer limit. A cached response from the + // HTTP cache is used instead, we still should not see another request. + EXPECT_EQ(GetRequestCount(kPrerenderingUrl), 1); + EXPECT_EQ(delivery_type, "cache"); } break; } @@ -1337,9 +1310,7 @@ testing::Combine(testing::Values(PrerenderingResult::kSuccess, PrerenderingResult::kFailed), testing::Values(BodySize::kSmall, BodySize::kLarge), - testing::ValuesIn(PrefetchReusableValuesForTests()), - testing::Values(PrefetchHTTPCache::kEnabled, - PrefetchHTTPCache::kDisabled)), + testing::ValuesIn(PrefetchReusableValuesForTests())), PrerenderAndPrefetchBrowserTest::DescribeParams); // Tests that the speculationrules-triggered prerender would be destroyed after
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc index 5244267c6..6066f87e 100644 --- a/content/browser/renderer_host/render_frame_host_impl.cc +++ b/content/browser/renderer_host/render_frame_host_impl.cc
@@ -9166,10 +9166,80 @@ return; } - properties->DisableUntrustedNetwork(); + // Register the nonce in the network service's data structure to deny network + // access. + CHECK(properties->partition_nonce().has_value()); + StoragePartition* storage_partition = GetStoragePartition(); + // TODO(crbug.com/41488151): Audit all existing transient IsolationInfo + // constructors to ensure that they are tagged with the relevant partition + // nonce. + storage_partition->GetNetworkContext()->RevokeNetworkForNonce( + properties->partition_nonce()->GetValueIgnoringVisibility(), + base::BindOnce( + &RenderFrameHostImpl::RevokeNetworkForNonceCallback, + weak_ptr_factory_.GetWeakPtr(), + properties->partition_nonce()->GetValueIgnoringVisibility(), + std::move(callback))); +} + +void RenderFrameHostImpl::RevokeNetworkForNonceCallback( + base::UnguessableToken nonce, + DisableUntrustedNetworkInFencedFrameCallback callback) { + std::optional<FencedFrameProperties>& properties = + frame_tree_node_->GetFencedFrameProperties(); + // If the revoked nonce no longer corresponds to an active fenced frame tree + // due to timing, do nothing. + // TODO(https://crbug.com/936696): After enabling RenderDocument fully, this + // condition and the `nonce` argument to the callback can be removed. + if (!properties.has_value() || !properties->partition_nonce().has_value() || + properties->partition_nonce()->GetValueIgnoringVisibility() != nonce) { + std::move(callback).Run(); + return; + } + // Now that the nonce has been revoked, mark the fenced frame tree's network + // as having been disabled in the fenced frame properties. + properties->MarkUntrustedNetworkDisabled(); std::move(callback).Run(); } +void RenderFrameHostImpl::ExemptUrlFromNetworkRevocationForTesting( + const GURL& exempted_url, + ExemptUrlFromNetworkRevocationForTestingCallback callback) { + if (!blink::features::IsFencedFramesEnabled()) { + mojo::ReportBadMessage( + "DisableUntrustedNetworkInFencedFrame() received while " + "fenced frames not enabled."); + return; + } + if (!base::FeatureList::IsEnabled( + blink::features::kFencedFramesLocalUnpartitionedDataAccess)) { + mojo::ReportBadMessage( + "DisableUntrustedNetworkInFencedFrame() received while " + "FencedFramesLocalUnpartitionedDataAccess not enabled."); + return; + } + if (!base::FeatureList::IsEnabled( + blink::features::kExemptUrlFromNetworkRevocationForTesting)) { + mojo::ReportBadMessage( + "DisableUntrustedNetworkInFencedFrame() received while " + "ExemptUrlFromNetworkRevocationForTesting not enabled."); + return; + } + + std::optional<FencedFrameProperties>& properties = + frame_tree_node_->GetFencedFrameProperties(); + if (!properties.has_value() || !properties->partition_nonce().has_value()) { + std::move(callback).Run(); + return; + } + GetStoragePartition() + ->GetNetworkContext() + ->ExemptUrlFromNetworkRevocationForNonce( + exempted_url, + properties->partition_nonce()->GetValueIgnoringVisibility(), + std::move(callback)); +} + void RenderFrameHostImpl::OnViewTransitionOptInChanged( blink::mojom::ViewTransitionSameOriginOptIn view_transition_opt_in) { ViewTransitionOptInState::GetOrCreateForCurrentDocument(this)
diff --git a/content/browser/renderer_host/render_frame_host_impl.h b/content/browser/renderer_host/render_frame_host_impl.h index 143a178..5b0b04d 100644 --- a/content/browser/renderer_host/render_frame_host_impl.h +++ b/content/browser/renderer_host/render_frame_host_impl.h
@@ -2444,6 +2444,9 @@ bool cross_origin_exposed) override; void DisableUntrustedNetworkInFencedFrame( DisableUntrustedNetworkInFencedFrameCallback callback) override; + void ExemptUrlFromNetworkRevocationForTesting( + const GURL& exempted_url, + ExemptUrlFromNetworkRevocationForTestingCallback callback) override; void SendLegacyTechEvent( const std::string& type, blink::mojom::LegacyTechEventCodeLocationPtr code_location) override; @@ -4120,6 +4123,13 @@ // is gone. void CleanUpMediaStreams(); + // Mark network as having been disabled for `nonce` in the active fenced frame + // properties once it was disabled in the network service, and resolve the + // `callback` which came from the window.fence.disableUntrustedNetwork call. + void RevokeNetworkForNonceCallback( + base::UnguessableToken nonce, + DisableUntrustedNetworkInFencedFrameCallback callback); + // The RenderViewHost that this RenderFrameHost is associated with. // // It is kept alive as long as any RenderFrameHosts or RenderFrameProxyHosts
diff --git a/content/browser/renderer_host/render_widget_host_view_android.cc b/content/browser/renderer_host/render_widget_host_view_android.cc index 56f29c4..21df7e2 100644 --- a/content/browser/renderer_host/render_widget_host_view_android.cc +++ b/content/browser/renderer_host/render_widget_host_view_android.cc
@@ -753,6 +753,11 @@ return frame_host->GetPage().virtual_keyboard_mode(); } +viz::SurfaceId RenderWidgetHostViewAndroid::GetFallbackSurfaceIdForTesting() + const { + return delegated_frame_host_->GetFallbackSurfaceIdForTesting(); // IN-TEST +} + bool RenderWidgetHostViewAndroid::SynchronizeVisualProperties( const cc::DeadlinePolicy& deadline_policy, const std::optional<viz::LocalSurfaceId>& child_local_surface_id,
diff --git a/content/browser/renderer_host/render_widget_host_view_android.h b/content/browser/renderer_host/render_widget_host_view_android.h index a3b6695..c6e59139 100644 --- a/content/browser/renderer_host/render_widget_host_view_android.h +++ b/content/browser/renderer_host/render_widget_host_view_android.h
@@ -228,6 +228,7 @@ void TransferTouches( const std::vector<std::unique_ptr<ui::TouchEvent>>& touches) override; ui::mojom::VirtualKeyboardMode GetVirtualKeyboardMode() override; + viz::SurfaceId GetFallbackSurfaceIdForTesting() const override; // ui::EventHandlerAndroid implementation. bool OnTouchEvent(const ui::MotionEventAndroid& m) override;
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc index 094686284..e065ce0 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura.cc +++ b/content/browser/renderer_host/render_widget_host_view_aura.cc
@@ -688,6 +688,11 @@ delegated_frame_host_->CancelSuccessfulPresentationTimeRequest(); } +viz::SurfaceId RenderWidgetHostViewAura::GetFallbackSurfaceIdForTesting() + const { + return delegated_frame_host_->GetFallbackSurfaceIdForTesting(); // IN-TEST +} + bool RenderWidgetHostViewAura::ShouldSkipCursorUpdate() const { aura::Window* root_window = window_->GetRootWindow(); DCHECK(root_window);
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.h b/content/browser/renderer_host/render_widget_host_view_aura.h index e44b23e0..1fabbf3 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura.h +++ b/content/browser/renderer_host/render_widget_host_view_aura.h
@@ -216,6 +216,7 @@ // TODO(lanwei): Use TestApi interface to write functions that are used in // tests and remove FRIEND_TEST_ALL_PREFIXES. void SetLastPointerType(ui::EventPointerType last_pointer_type) override; + viz::SurfaceId GetFallbackSurfaceIdForTesting() const override; // Overridden from ui::TextInputClient: void SetCompositionText(const ui::CompositionText& composition) override;
diff --git a/content/browser/renderer_host/render_widget_host_view_base.cc b/content/browser/renderer_host/render_widget_host_view_base.cc index 577d2ad5..6b6902c0 100644 --- a/content/browser/renderer_host/render_widget_host_view_base.cc +++ b/content/browser/renderer_host/render_widget_host_view_base.cc
@@ -470,6 +470,12 @@ return false; } +viz::SurfaceId RenderWidgetHostViewBase::GetFallbackSurfaceIdForTesting() + const { + NOTREACHED(); + return viz::SurfaceId(); +} + void RenderWidgetHostViewBase::SetWidgetType(WidgetType widget_type) { widget_type_ = widget_type; }
diff --git a/content/browser/renderer_host/render_widget_host_view_base.h b/content/browser/renderer_host/render_widget_host_view_base.h index 6f246e3..116046b 100644 --- a/content/browser/renderer_host/render_widget_host_view_base.h +++ b/content/browser/renderer_host/render_widget_host_view_base.h
@@ -630,6 +630,8 @@ return !!view_transition_resources_; } + virtual viz::SurfaceId GetFallbackSurfaceIdForTesting() const; + protected: explicit RenderWidgetHostViewBase(RenderWidgetHost* host); ~RenderWidgetHostViewBase() override;
diff --git a/content/browser/renderer_host/render_widget_host_view_browsertest.cc b/content/browser/renderer_host/render_widget_host_view_browsertest.cc index 2bdaf42..c074b3e 100644 --- a/content/browser/renderer_host/render_widget_host_view_browsertest.cc +++ b/content/browser/renderer_host/render_widget_host_view_browsertest.cc
@@ -394,6 +394,8 @@ // is maintained as the fallback. The DelegatedFrameHost should have not have // a valid active viz::LocalSurfaceId until the first surface after navigation // has been embedded. + rwhva = static_cast<RenderWidgetHostViewAndroid*>(rwhvb); + dfh = rwhva->delegated_frame_host_for_testing(); EXPECT_TRUE(dfh->HasPrimarySurface()); EXPECT_FALSE(dfh->IsPrimarySurfaceEvicted()); EXPECT_EQ(initial_local_surface_id, @@ -430,6 +432,7 @@ ASSERT_TRUE(rwhvb); viz::LocalSurfaceId rwhvb_local_surface_id = rwhvb->GetLocalSurfaceId(); EXPECT_TRUE(rwhvb_local_surface_id.is_valid()); + viz::SurfaceId initial_surface_id = rwhvb->GetCurrentSurfaceId(); // Hide the view before performing the next navigation. shell()->web_contents()->WasHidden(); @@ -462,11 +465,23 @@ // If this takes too long we hit a timeout that attempts to reset us back to // the initial surface. So that some content state can be presented. // - // If a navigation were to fail, then this would be invoked before any new - // surface is embedded. For which we expect it to clear out the fallback - // surfaces. As we cannot fallback to a surface from before navigation. + // If a navigation were to fail and stayed in the same RenderFrameHost, then + // this would be invoked before any new surface is embedded. For which we + // expect it to clear out the fallback surfaces. As we cannot fallback to a + // surface from before navigation. + // + // However, if the navigation involves a change of RenderFrameHosts (and thus + // RenderWidgetViewHosts) we will embed a new surface early on when creating + // the speculative RenderFrameHosts. This is OK because the surface is not + // related to the previous page's surface, so we won't be showing the previous + // page's content as a fallback. rwhvb->ResetFallbackToFirstNavigationSurface(); - EXPECT_FALSE(rwhvb->HasFallbackSurface()); + if (ShouldCreateNewHostForAllFrames()) { + EXPECT_TRUE(rwhvb->HasFallbackSurface()); + EXPECT_NE(rwhvb->GetFallbackSurfaceIdForTesting(), initial_surface_id); + } else { + EXPECT_FALSE(rwhvb->HasFallbackSurface()); + } #if BUILDFLAG(IS_ANDROID) // Navigating while hidden should not generate a new surface. @@ -474,6 +489,8 @@ // The DelegatedFrameHost should have not have a valid active // viz::LocalSurfaceId until the first surface after navigation has been // embedded. + rwhva = static_cast<RenderWidgetHostViewAndroid*>(rwhvb); + dfh = rwhva->delegated_frame_host_for_testing(); EXPECT_FALSE(dfh->HasPrimarySurface()); EXPECT_TRUE(dfh->IsPrimarySurfaceEvicted()); EXPECT_FALSE(dfh->content_layer()->surface_id().is_valid());
diff --git a/content/browser/renderer_host/render_widget_host_view_mac.h b/content/browser/renderer_host/render_widget_host_view_mac.h index d4e154d..5497f4e 100644 --- a/content/browser/renderer_host/render_widget_host_view_mac.h +++ b/content/browser/renderer_host/render_widget_host_view_mac.h
@@ -162,6 +162,7 @@ gfx::NativeViewAccessible AccessibilityGetNativeViewAccessibleForWindow() override; std::optional<SkColor> GetBackgroundColor() override; + viz::SurfaceId GetFallbackSurfaceIdForTesting() const override; void TransformPointToRootSurface(gfx::PointF* point) override; gfx::Rect GetBoundsInRootWindow() override;
diff --git a/content/browser/renderer_host/render_widget_host_view_mac.mm b/content/browser/renderer_host/render_widget_host_view_mac.mm index 72b957c..a2c2c78 100644 --- a/content/browser/renderer_host/render_widget_host_view_mac.mm +++ b/content/browser/renderer_host/render_widget_host_view_mac.mm
@@ -1623,6 +1623,11 @@ return (color && *color == SK_ColorTRANSPARENT) ? SK_ColorWHITE : color; } +viz::SurfaceId RenderWidgetHostViewMac::GetFallbackSurfaceIdForTesting() const { + return browser_compositor_->GetDelegatedFrameHost() + ->GetFallbackSurfaceIdForTesting(); // IN-TEST +} + void RenderWidgetHostViewMac::SetBackgroundLayerColor(SkColor color) { if (color == background_layer_color_) return;
diff --git a/content/browser/theme_helper.cc b/content/browser/theme_helper.cc index f770074..54dabd4 100644 --- a/content/browser/theme_helper.cc +++ b/content/browser/theme_helper.cc
@@ -29,8 +29,6 @@ mojom::UpdateSystemColorInfoParams::New(); params->is_dark_mode = native_theme->ShouldUseDarkColors(); params->forced_colors = native_theme->InForcedColorsMode(); - const auto& colors = native_theme->GetSystemColors(); - params->colors.insert(colors.begin(), colors.end()); #if BUILDFLAG(IS_CHROMEOS) params->accent_color = native_theme->user_color();
diff --git a/content/browser/tracing/trace_report/trace_report_internals_ui.cc b/content/browser/tracing/trace_report/trace_report_internals_ui.cc index 9831510..9b970f9 100644 --- a/content/browser/tracing/trace_report/trace_report_internals_ui.cc +++ b/content/browser/tracing/trace_report/trace_report_internals_ui.cc
@@ -33,7 +33,9 @@ source->OverrideContentSecurityPolicy( network::mojom::CSPDirectiveName::TrustedTypes, "trusted-types static-types polymer-html-literal " - "polymer-template-event-attribute-policy;"); + "polymer-template-event-attribute-policy " + // Add TrustedTypes policies necessary for using Lit. + "lit-html-desktop;"); } TraceReportInternalsUI::~TraceReportInternalsUI() = default;
diff --git a/content/browser/webauth/authenticator_impl_unittest.cc b/content/browser/webauth/authenticator_impl_unittest.cc index 17dcf43..3a45abcf 100644 --- a/content/browser/webauth/authenticator_impl_unittest.cc +++ b/content/browser/webauth/authenticator_impl_unittest.cc
@@ -6774,13 +6774,11 @@ EXPECT_EQ(info.has_platform_authenticator_credential, device::FidoRequestHandlerBase::RecognizedCredential:: kHasRecognizedCredential); - EXPECT_TRUE(base::Contains( + const auto cred = std::ranges::find( info.recognized_credentials, *config_.preselected_credential_id, - &device::DiscoverableCredentialMetadata::cred_id)); - std::move(account_preselected_callback_) - .Run(device::PublicKeyCredentialDescriptor( - device::CredentialType::kPublicKey, - *config_.preselected_credential_id)); + &device::DiscoverableCredentialMetadata::cred_id); + ASSERT_NE(cred, info.recognized_credentials.end()); + std::move(account_preselected_callback_).Run(*cred); request_callback_.Run(*config_.preselected_authenticator_id); } } @@ -8422,6 +8420,40 @@ } } +// Tests that preselecting a credential sets the response user entity to that of +// the credential metadata if it is not present in the response. +// Regression test for crbug.com/329412574. +TEST_F(ResidentKeyAuthenticatorImplTest, PreselectCredentialUserEntity) { + device::VirtualCtap2Device::Config config; + config.resident_key_support = true; + config.internal_uv_support = true; + config.omit_user_entity_on_allow_credentials_requests = true; + virtual_device_factory_->SetCtap2Config(config); + virtual_device_factory_->SetTransport( + device::FidoTransportProtocol::kInternal); + virtual_device_factory_->mutable_state()->fingerprints_enrolled = true; + constexpr char kAuthenticatorId[] = "internal-authenticator"; + virtual_device_factory_->mutable_state()->device_id_override = + kAuthenticatorId; + std::vector<uint8_t> kCredId{{1, 2, 3, 4}}; + std::vector<uint8_t> kUserId{{5, 6, 7, 8}}; + + ASSERT_TRUE(virtual_device_factory_->mutable_state()->InjectResidentKey( + kCredId, kTestRelyingPartyId, kUserId, std::nullopt, std::nullopt)); + + // |SelectAccount| should not be called if an account was chosen from + // pre-select UI. + test_client_.delegate_config.expected_accounts = "<invalid>"; + + test_client_.delegate_config.preselected_credential_id = kCredId; + test_client_.delegate_config.preselected_authenticator_id = kAuthenticatorId; + PublicKeyCredentialRequestOptionsPtr options(get_credential_options()); + GetAssertionResult result = AuthenticatorGetAssertion(std::move(options)); + EXPECT_EQ(result.status, AuthenticatorStatus::SUCCESS); + EXPECT_EQ(result.response->info->raw_id, kCredId); + EXPECT_EQ(result.response->user_handle, kUserId); +} + class InternalAuthenticatorImplTest : public AuthenticatorTestBase { protected: InternalAuthenticatorImplTest() = default;
diff --git a/content/browser/webid/webid_browsertest.cc b/content/browser/webid/webid_browsertest.cc index 801f966..47e0791 100644 --- a/content/browser/webid/webid_browsertest.cc +++ b/content/browser/webid/webid_browsertest.cc
@@ -43,6 +43,7 @@ #include "net/test/embedded_test_server/embedded_test_server.h" #include "net/test/embedded_test_server/http_request.h" #include "net/test/embedded_test_server/http_response.h" +#include "services/network/public/cpp/cors/cors.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/common/features.h" @@ -319,12 +320,36 @@ "/fedcm/client_metadata_endpoint.json"; std::string id_assertion_endpoint_url = "/fedcm/id_assertion_endpoint.json"; std::string login_url = "/fedcm/login.html"; + std::map<std::string, base::RepeatingCallback<std::unique_ptr<HttpResponse>( + const HttpRequest&)>> + servlets; + servlets[id_assertion_endpoint_url] = base::BindRepeating( + [](const HttpRequest& request) -> std::unique_ptr<HttpResponse> { + EXPECT_EQ(request.method, HttpMethod::METHOD_POST); + EXPECT_EQ(request.has_content, true); + auto response = std::make_unique<BasicHttpResponse>(); + response->set_code(net::HTTP_OK); + response->set_content_type("text/json"); + CHECK(request.headers.contains("Origin")); + response->AddCustomHeader( + network::cors::header_names::kAccessControlAllowOrigin, + request.headers.at("Origin")); + response->AddCustomHeader( + network::cors::header_names::kAccessControlAllowCredentials, + "true"); + // Standard scopes were used, so no extra permission needed. + // Return a token immediately. + response->set_content(R"({"token": ")" + std::string(kToken) + + R"("})"); + return response; + }); return {net::HTTP_OK, kTestContentType, accounts_endpoint_url, client_metadata_endpoint_url, id_assertion_endpoint_url, - login_url}; + login_url, + servlets}; } IdpTestServer* idp_server() { return idp_server_.get(); } @@ -1205,6 +1230,13 @@ auto response = std::make_unique<BasicHttpResponse>(); response->set_code(net::HTTP_OK); response->set_content_type("text/json"); + DCHECK(request.headers.contains("Origin")); + response->AddCustomHeader( + network::cors::header_names::kAccessControlAllowOrigin, + request.headers.at("Origin")); + response->AddCustomHeader( + network::cors::header_names::kAccessControlAllowCredentials, + "true"); // Standard scopes were used, so no extra permission needed. // Return a token immediately. response->set_content(R"({"token": "[request lgtm!]"})"); @@ -1278,6 +1310,13 @@ // return a continuation url instead of a token. auto body = R"({"continue_on": ")" + url + R"("})"; response->set_content(body); + DCHECK(request.headers.contains("Origin")); + response->AddCustomHeader( + network::cors::header_names::kAccessControlAllowOrigin, + request.headers.at("Origin")); + response->AddCustomHeader( + network::cors::header_names::kAccessControlAllowCredentials, + "true"); return response; }, continue_on); @@ -1386,6 +1425,13 @@ response->set_content_type("text/json"); response->set_content( R"({"error": {"code": "invalid_request", "url": "https://idp.com/error"}})"); + DCHECK(request.headers.contains("Origin")); + response->AddCustomHeader( + network::cors::header_names::kAccessControlAllowOrigin, + request.headers.at("Origin")); + response->AddCustomHeader( + network::cors::header_names::kAccessControlAllowCredentials, + "true"); return response; });
diff --git a/content/common/features.cc b/content/common/features.cc index c0b0ee48..432f0b26 100644 --- a/content/common/features.cc +++ b/content/common/features.cc
@@ -202,7 +202,7 @@ // Enables CORS checks on the ID assertion endpoint of the FedCM API. BASE_FEATURE(kFedCmIdAssertionCORS, "FedCmIdAssertionCORS", - base::FEATURE_DISABLED_BY_DEFAULT); + base::FEATURE_ENABLED_BY_DEFAULT); // Enables metrics collection for signin status mismatches. Also enables // parsing the signin status HTTP headers.
diff --git a/content/common/renderer.mojom b/content/common/renderer.mojom index 9220ce0..b8e3470f 100644 --- a/content/common/renderer.mojom +++ b/content/common/renderer.mojom
@@ -30,14 +30,11 @@ }; struct UpdateSystemColorInfoParams { +// TODO(crbug.com/40779801): Remove `forced_colors` when we use the forced +// colors web setting in Blink. bool is_dark_mode; bool forced_colors; - // uint32 represents a SkColor in the map. - // TODO(crbug.com/1251637): These colors should be consolidated into the - // renderer's ColorProviders. - map<SystemThemeColor, uint32> colors; - // Accent color used by the system. Currently only set on ChromeOS. uint32? accent_color; };
diff --git a/content/public/browser/authenticator_request_client_delegate.h b/content/public/browser/authenticator_request_client_delegate.h index a8e18cde..12d0bc2 100644 --- a/content/public/browser/authenticator_request_client_delegate.h +++ b/content/public/browser/authenticator_request_client_delegate.h
@@ -170,7 +170,7 @@ : public device::FidoRequestHandlerBase::Observer { public: using AccountPreselectedCallback = - base::RepeatingCallback<void(device::PublicKeyCredentialDescriptor)>; + base::RepeatingCallback<void(device::DiscoverableCredentialMetadata)>; // Failure reasons that might be of interest to the user, so the embedder may // decide to inform the user.
diff --git a/content/public/common/url_utils.cc b/content/public/common/url_utils.cc index 619c8a1..2be8a1a4 100644 --- a/content/public/common/url_utils.cc +++ b/content/public/common/url_utils.cc
@@ -6,12 +6,12 @@ #include <set> #include <string> +#include <string_view> #include "base/check_op.h" #include "base/containers/contains.h" #include "base/containers/fixed_flat_set.h" #include "base/feature_list.h" -#include "base/strings/string_piece.h" #include "build/build_config.h" #include "content/common/url_schemes.h" #include "content/public/common/content_client.h" @@ -19,6 +19,7 @@ #include "content/public/common/url_constants.h" #include "third_party/blink/public/common/chrome_debug_urls.h" #include "url/gurl.h" +#include "url/url_constants.h" #include "url/url_util.h" namespace content { @@ -77,16 +78,19 @@ } bool IsSafeRedirectTarget(const GURL& from_url, const GURL& to_url) { - static const auto kUnsafeSchemes = base::MakeFixedFlatSet<base::StringPiece>({ - url::kAboutScheme, url::kFileScheme, url::kFileSystemScheme, - url::kBlobScheme, + static constexpr auto kUnsafeSchemes = + base::MakeFixedFlatSet<std::string_view>({ + url::kAboutScheme, + url::kFileScheme, + url::kFileSystemScheme, + url::kBlobScheme, #if !defined(CHROMECAST_BUILD) - url::kDataScheme, + url::kDataScheme, #endif #if BUILDFLAG(IS_ANDROID) - url::kContentScheme, + url::kContentScheme, #endif - }); + }); if (HasWebUIScheme(to_url)) return false; if (!kUnsafeSchemes.contains(to_url.scheme_piece()))
diff --git a/content/public/test/android/javatests/src/org/chromium/content_public/browser/test/util/TouchCommon.java b/content/public/test/android/javatests/src/org/chromium/content_public/browser/test/util/TouchCommon.java index 28d2c6a..34e95b79 100644 --- a/content/public/test/android/javatests/src/org/chromium/content_public/browser/test/util/TouchCommon.java +++ b/content/public/test/android/javatests/src/org/chromium/content_public/browser/test/util/TouchCommon.java
@@ -331,10 +331,11 @@ /** * Sends a MotionEvent to the specified view. + * * @param view The view that should receive the event. * @param event The view to be dispatched. */ - private static boolean dispatchTouchEvent(final View view, final MotionEvent event) { + public static boolean dispatchTouchEvent(final View view, final MotionEvent event) { try { return TestThreadUtils.runOnUiThreadBlocking( new Callable<Boolean>() {
diff --git a/content/public/test/browser_test_utils.cc b/content/public/test/browser_test_utils.cc index 029a6e8..f19026f 100644 --- a/content/public/test/browser_test_utils.cc +++ b/content/public/test/browser_test_utils.cc
@@ -2126,6 +2126,29 @@ } } +void WaitForAccessibilityTreeToContainSelection( + WebContents* web_contents, + base::StringPiece selection_start_name, + base::StringPiece selection_end_name) { + while (true) { + AccessibilityNotificationWaiter accessibility_waiter( + web_contents, ui::AXMode(), + ui::AXEventGenerator::Event::DOCUMENT_SELECTION_CHANGED); + ASSERT_TRUE(accessibility_waiter.WaitForNotification()); + content::BrowserAccessibilityManager* manager = + accessibility_waiter.event_browser_accessibility_manager(); + + const ui::AXTreeData& tree_data = manager->GetTreeData(); + ui::AXNode* sel_start = manager->GetNode(tree_data.sel_anchor_object_id); + ui::AXNode* sel_end = manager->GetNode(tree_data.sel_focus_object_id); + if (sel_start && sel_end && + sel_start->GetNameUTF8() == selection_start_name && + sel_end->GetNameUTF8() == selection_end_name) { + break; + } + } +} + ui::AXTreeUpdate GetAccessibilityTreeSnapshot(WebContents* web_contents) { WebContentsImpl* web_contents_impl = static_cast<WebContentsImpl*>(web_contents);
diff --git a/content/public/test/browser_test_utils.h b/content/public/test/browser_test_utils.h index 338251f7..434ef11 100644 --- a/content/public/test/browser_test_utils.h +++ b/content/public/test/browser_test_utils.h
@@ -1068,6 +1068,15 @@ void WaitForAccessibilityTreeToContainNodeWithName(WebContents* web_contents, base::StringPiece name); +// Waits for a document selection changed event then checks to see if the +// accessibility tree has a selection start and end with the given name(s). +// Keeps looping until the text is found (or the +// test times out). +void WaitForAccessibilityTreeToContainSelection( + WebContents* web_contents, + base::StringPiece selection_start_name, + base::StringPiece selection_end_name); + // Get a snapshot of a web page's accessibility tree. ui::AXTreeUpdate GetAccessibilityTreeSnapshot(WebContents* web_contents);
diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc index 1952b50..3594bc7 100644 --- a/content/renderer/render_thread_impl.cc +++ b/content/renderer/render_thread_impl.cc
@@ -1530,7 +1530,7 @@ auto* native_theme = ui::NativeTheme::GetInstanceForWeb(); bool did_system_color_info_change = native_theme->UpdateSystemColorInfo( - params->is_dark_mode, params->forced_colors, params->colors); + params->is_dark_mode, params->forced_colors); did_system_color_info_change |= native_theme->user_color() != params->accent_color;
diff --git a/content/services/auction_worklet/seller_worklet.cc b/content/services/auction_worklet/seller_worklet.cc index 7c287cce..9fc6d30f 100644 --- a/content/services/auction_worklet/seller_worklet.cc +++ b/content/services/auction_worklet/seller_worklet.cc
@@ -48,6 +48,7 @@ #include "mojo/public/cpp/bindings/remote.h" #include "services/network/public/mojom/url_loader_factory.mojom.h" #include "third_party/blink/public/common/features.h" +#include "third_party/blink/public/common/features_generated.h" #include "third_party/blink/public/common/interest_group/ad_auction_currencies.h" #include "third_party/blink/public/common/interest_group/ad_display_size.h" #include "third_party/blink/public/common/interest_group/ad_display_size_utils.h" @@ -390,6 +391,30 @@ return false; } + DCHECK(!auction_ad_config_non_shared_params.deprecated_render_url_replacements + .is_promise()); + + if (!auction_ad_config_non_shared_params.deprecated_render_url_replacements + .value() + .empty()) { + v8::Local<v8::Object> deprecated_render_url_replacements = + v8::Object::New(isolate); + for (const auto& kv : auction_ad_config_non_shared_params + .deprecated_render_url_replacements.value()) { + v8::Local<v8::String> v8_replacement; + if (!v8_helper->CreateUtf8String(kv.replacement) + .ToLocal(&v8_replacement)) { + return false; + } + if (!v8_helper->InsertValue(kv.match, v8_replacement, + deprecated_render_url_replacements)) { + return false; + } + } + auction_config_dict.Set("deprecatedRenderURLReplacements", + deprecated_render_url_replacements); + } + if (auction_ad_config_non_shared_params.seller_timeout.has_value() && !v8_helper->InsertJsonValue( context, "sellerTimeout",
diff --git a/content/services/auction_worklet/seller_worklet_unittest.cc b/content/services/auction_worklet/seller_worklet_unittest.cc index e0b8ab9a..e9060d79 100644 --- a/content/services/auction_worklet/seller_worklet_unittest.cc +++ b/content/services/auction_worklet/seller_worklet_unittest.cc
@@ -3351,6 +3351,13 @@ blink::AuctionConfig::MaybePromiseBuyerTimeouts::FromValue( std::move(buyer_cumulative_timeouts)); + std::vector<blink::AuctionConfig::AdKeywordReplacement> example_replacement = + {blink::AuctionConfig::AdKeywordReplacement({"${SELLER}", "ExampleSSP"})}; + + auction_ad_config_non_shared_params_.deprecated_render_url_replacements = + blink::AuctionConfig::MaybePromiseDeprecatedRenderURLReplacements:: + FromValue(std::move(example_replacement)); + blink::AuctionConfig::BuyerCurrencies buyer_currencies; buyer_currencies.per_buyer_currencies.emplace(); buyer_currencies.per_buyer_currencies @@ -3384,7 +3391,8 @@ "perBuyerTimeouts":{"https://a.com":100,"*":150}, "perBuyerCumulativeTimeouts":{"https://a.com":101,"*":151}, "perBuyerPrioritySignals":{"https://a.com":{"signals_c":0.5}, - "*": {"signals_d":0}} + "*": {"signals_d":0}}, + "deprecatedRenderURLReplacements": {"${SELLER}":"ExampleSSP"} })"; RunReportResultCreatedScriptExpectingResult( "auctionConfig", /*extra_code=*/std::string(), kExpectedJson1, @@ -5890,5 +5898,44 @@ "not defined."}); } +class SellerWorkletDeprecatedRenderURLReplacementsEnabledTest + : public SellerWorkletTest { + public: + SellerWorkletDeprecatedRenderURLReplacementsEnabledTest() { + feature_list_.InitAndEnableFeature( + blink::features::kFledgeDeprecatedRenderURLReplacements); + } + + protected: + base::test::ScopedFeatureList feature_list_; +}; + +TEST_F(SellerWorkletDeprecatedRenderURLReplacementsEnabledTest, + DeprecatedRenderURLReplacementsArePresentInScoreAdJavascript) { + const std::vector<blink::AuctionConfig::AdKeywordReplacement> + example_replacement = {blink::AuctionConfig::AdKeywordReplacement( + {"${SELLER}", "ExampleSSP"})}; + + auction_ad_config_non_shared_params_.deprecated_render_url_replacements = + blink::AuctionConfig::MaybePromiseDeprecatedRenderURLReplacements:: + FromValue(std::move(example_replacement)); + + std::string render_url_replacements_validator = + R"( + const replacementsJson = + JSON.stringify(auctionConfig.deprecatedRenderURLReplacements); + if (!(replacementsJson === "{\"${SELLER}\":\"ExampleSSP\"}")) { + throw new Error('deprecatedRenderURLReplacements is incorrect' + + 'or missing.'); + })"; + + RunScoreAdWithJavascriptExpectingResult( + CreateScoreAdScript("1", render_url_replacements_validator), 1, + /*expected_errors=*/{}, mojom::ComponentAuctionModifiedBidParamsPtr(), + /*expected_data_version=*/std::nullopt, + /*expected_debug_loss_report_url=*/std::nullopt, + /*expected_debug_win_report_url=*/std::nullopt); +} + } // namespace } // namespace auction_worklet
diff --git a/content/test/content_test_bundle_data.filelist b/content/test/content_test_bundle_data.filelist index abb1906..f1cdd8e 100644 --- a/content/test/content_test_bundle_data.filelist +++ b/content/test/content_test_bundle_data.filelist
@@ -6663,6 +6663,8 @@ data/interest_group/decision_argument_validator.js.mock-http-headers data/interest_group/decision_logic.js data/interest_group/decision_logic.js.mock-http-headers +data/interest_group/decision_logic_deprecated_render_url_replacements_validator.js +data/interest_group/decision_logic_deprecated_render_url_replacements_validator.js.mock-http-headers data/interest_group/decision_logic_expect_top_frame_a_test.js data/interest_group/decision_logic_expect_top_frame_a_test.js.mock-http-headers data/interest_group/decision_logic_loop_forever.js
diff --git a/content/test/data/fuzzer_corpus/ad_auction_service_mojolpm_fuzzer/basic_auction.textproto b/content/test/data/fuzzer_corpus/ad_auction_service_mojolpm_fuzzer/basic_auction.textproto index 124f1d41..c92a20b 100644 --- a/content/test/data/fuzzer_corpus/ad_auction_service_mojolpm_fuzzer/basic_auction.textproto +++ b/content/test/data/fuzzer_corpus/ad_auction_service_mojolpm_fuzzer/basic_auction.textproto
@@ -142,6 +142,9 @@ m_all_buyers_multi_bid_limit: 1 m_component_auctions { } + m_deprecated_render_url_replacements { + old: 1 + } m_max_trusted_scoring_signals_url_length: 0 } } @@ -149,9 +152,6 @@ m_direct_from_seller_signals { old: 1 } - m_deprecated_render_url_replacements { - old: 1 - } m_expects_direct_from_seller_signals_header_ad_slot: false m_seller_experiment_group_id: 0 m_all_buyer_experiment_group_id: 0
diff --git a/content/test/data/interest_group/decision_logic_deprecated_render_url_replacements_validator.js b/content/test/data/interest_group/decision_logic_deprecated_render_url_replacements_validator.js new file mode 100644 index 0000000..d656e46 --- /dev/null +++ b/content/test/data/interest_group/decision_logic_deprecated_render_url_replacements_validator.js
@@ -0,0 +1,33 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +function scoreAd( + adMetadata, bid, auctionConfig, trustedScoringSignals, + browserSignals) { + validateDeprecatedRenderURLReplacements( + auctionConfig.deprecatedRenderURLReplacements, + auctionConfig.sellerSignals.deprecatedRenderURLReplacementsExpected); + // `auctionSignals` controls whether or not component auctions are allowed. + let allowComponentAuction = + typeof auctionConfig.auctionSignals === 'string' && + auctionConfig.auctionSignals.includes('sellerAllowsComponentAuction'); + return { + desirability: bid, + allowComponentAuction: allowComponentAuction + }; +} + +function validateDeprecatedRenderURLReplacements( + deprecatedRenderURLReplacements, + deprecatedRenderURLReplacementsExpected) { + const replacementsExpectedJSON = + JSON.stringify(deprecatedRenderURLReplacementsExpected); + const replacementsJSON = + JSON.stringify(deprecatedRenderURLReplacements); + + if (replacementsJSON !== replacementsExpectedJSON) { + throw 'Wrong deprecatedRenderURLReplacements ' + + replacementsJSON + " should be " + replacementsExpectedJSON; + } +}
diff --git a/content/test/data/interest_group/decision_logic_deprecated_render_url_replacements_validator.js.mock-http-headers b/content/test/data/interest_group/decision_logic_deprecated_render_url_replacements_validator.js.mock-http-headers new file mode 100644 index 0000000..a1c1c883 --- /dev/null +++ b/content/test/data/interest_group/decision_logic_deprecated_render_url_replacements_validator.js.mock-http-headers
@@ -0,0 +1,3 @@ +HTTP/1.1 200 OK +Content-Type: Application/Javascript +Ad-Auction-Allowed: true
diff --git a/device/fido/get_assertion_request_handler.cc b/device/fido/get_assertion_request_handler.cc index df29a32..19aceacf 100644 --- a/device/fido/get_assertion_request_handler.cc +++ b/device/fido/get_assertion_request_handler.cc
@@ -31,9 +31,11 @@ #include "device/fido/fido_discovery_factory.h" #include "device/fido/fido_parsing_utils.h" #include "device/fido/fido_transport_protocol.h" +#include "device/fido/fido_types.h" #include "device/fido/filter.h" #include "device/fido/pin.h" #include "device/fido/public_key_credential_descriptor.h" +#include "device/fido/public_key_credential_user_entity.h" #if BUILDFLAG(IS_MAC) #include "device/fido/mac/authenticator.h" @@ -410,10 +412,10 @@ GetAssertionRequestHandler::~GetAssertionRequestHandler() = default; void GetAssertionRequestHandler::PreselectAccount( - PublicKeyCredentialDescriptor credential) { + DiscoverableCredentialMetadata credential) { DCHECK(!preselected_credential_); DCHECK(request_.allow_list.empty() || - base::Contains(request_.allow_list, credential.id, + base::Contains(request_.allow_list, credential.cred_id, &PublicKeyCredentialDescriptor::id)); preselected_credential_ = std::move(credential); } @@ -510,7 +512,11 @@ } if (preselected_credential_) { - request.allow_list = {*preselected_credential_}; + request.allow_list = {PublicKeyCredentialDescriptor( + CredentialType::kPublicKey, preselected_credential_->cred_id, + {preselected_credential_->source == device::AuthenticatorType::kPhone + ? FidoTransportProtocol::kHybrid + : FidoTransportProtocol::kInternal})}; } ReportGetAssertionRequestTransport(authenticator); @@ -780,8 +786,16 @@ // selection dialog by setting the `userSelected` flag. DCHECK_EQ(responses.size(), 1u); DCHECK(responses.at(0).credential && - responses.at(0).credential->id == preselected_credential_->id); + responses.at(0).credential->id == preselected_credential_->cred_id); responses.at(0).user_selected = true; + + // When the user preselects a credential, Chrome will set it in the + // allow-list, even if the RP requested an empty allow list. Unfortunately, + // android may omit the user handle for allow-list requests. Set the user + // handle from the preselected credential metadata to work around this bug. + if (!responses.at(0).user_entity) { + responses.at(0).user_entity = preselected_credential_->user; + } } ReportGetAssertionResponseTransport(authenticator);
diff --git a/device/fido/get_assertion_request_handler.h b/device/fido/get_assertion_request_handler.h index 5d3e4ec..199d08c 100644 --- a/device/fido/get_assertion_request_handler.h +++ b/device/fido/get_assertion_request_handler.h
@@ -16,6 +16,7 @@ #include "device/fido/auth_token_requester.h" #include "device/fido/authenticator_get_assertion_response.h" #include "device/fido/ctap_get_assertion_request.h" +#include "device/fido/discoverable_credential_metadata.h" #include "device/fido/fido_constants.h" #include "device/fido/fido_request_handler_base.h" #include "device/fido/fido_transport_protocol.h" @@ -79,7 +80,7 @@ // Filters the allow list of the get assertion request to the given // |credential|. - void PreselectAccount(PublicKeyCredentialDescriptor credential); + void PreselectAccount(DiscoverableCredentialMetadata credential); base::WeakPtr<GetAssertionRequestHandler> GetWeakPtr(); @@ -154,7 +155,7 @@ // preselected_credential_ is set when the UI invokes `PreselectAccount()`. It // contains the credential chosen by the user during a request prior to // dispatching to the authenticator. - std::optional<PublicKeyCredentialDescriptor> preselected_credential_; + std::optional<DiscoverableCredentialMetadata> preselected_credential_; SEQUENCE_CHECKER(my_sequence_checker_); base::WeakPtrFactory<GetAssertionRequestHandler> weak_factory_{this};
diff --git a/device/fido/virtual_ctap2_device.cc b/device/fido/virtual_ctap2_device.cc index 23d52f8..019cf93 100644 --- a/device/fido/virtual_ctap2_device.cc +++ b/device/fido/virtual_ctap2_device.cc
@@ -1747,7 +1747,9 @@ fido_parsing_utils::Materialize(registration.first)); } - if (registration.second->is_resident) { + if (registration.second->is_resident && + (request.allow_list.empty() || + !config_.omit_user_entity_on_allow_credentials_requests)) { assertion.user_entity = registration.second->user.value(); }
diff --git a/device/fido/virtual_ctap2_device.h b/device/fido/virtual_ctap2_device.h index d3736e9..481e9fe 100644 --- a/device/fido/virtual_ctap2_device.h +++ b/device/fido/virtual_ctap2_device.h
@@ -212,6 +212,12 @@ // assertions. bool ignore_u2f_credentials = false; + // omit_user_entity_on_allow_credentials_requests causes get assertion + // requests to omit the user entity for non empty allow lists, even if the + // credential is discoverable. This matches the behaviour of some Android + // devices. + bool omit_user_entity_on_allow_credentials_requests = false; + // pin_protocol is the PIN protocol version that this authenticator supports // and reports in the pinProtocols field of the authenticatorGetInfo // response.
diff --git a/docs/updater/protocol_3_1.md b/docs/updater/protocol_3_1.md index 1758257a..989a11c6 100644 --- a/docs/updater/protocol_3_1.md +++ b/docs/updater/protocol_3_1.md
@@ -365,7 +365,7 @@ unknown, or that the concept of enabling/disabling does not exist. "0" indicates that the application is disabled. "1" indicates that the app is enabled. Default: "-1". - * `fp`: The current [differential fingerprint](#differential-fingerprint) of + * `fp`: The current [differential fingerprint](#differential-updates) of the application, or "" if unknown. Default: "". * `iid`: Installation ID is an opaque token that identifies an installation flow. The installation ID is a unique identifier embedded into a @@ -709,7 +709,7 @@ Packages can also come in differential update forms. Clients should attempt a differential patch of package first, and fall back to a full package if the differential patch fails to apply. A package object has the following members: - * `fp`: The [differential fingerprint](#differential-fingerprints) of the + * `fp`: The [differential fingerprint](#differential-updates) of the new version of the package. * `size`: The size of the file, in octets. * `sizediff`: The size of the differential file, in octets, if one is @@ -874,7 +874,7 @@ Depending on the event type, additional members may be present: For `type == 2` events: - * `nextfp`: The [differential fingerprint](#differential-fingerprints) that + * `nextfp`: The [differential fingerprint](#differential-updates) that the client was attempting to update to, regardless of whether that update was successful. * `nextversion`: The application version that the client was attempting to @@ -893,7 +893,7 @@ `diffresult`. * `diffextracode1`: As `extracode1` but for differential updates. Similar to `diffresult`. - * `previousfp`: The [differential fingerprint](#differential-fingerprints) + * `previousfp`: The [differential fingerprint](#differential-updates) the client had prior to the update, regardless of whether that update was successful. * `previousversion`: The application version the client had prior to the
diff --git a/docs/website b/docs/website index 2c1fee7..02057aa 160000 --- a/docs/website +++ b/docs/website
@@ -1 +1 @@ -Subproject commit 2c1fee75b24e8ecee921e9c61013f4ae9d98ab26 +Subproject commit 02057aa20e0dd4598967e3daf2f25c815962ef1c
diff --git a/gpu/command_buffer/client/gles2_c_lib_autogen.h b/gpu/command_buffer/client/gles2_c_lib_autogen.h index b8f8a45..645dce2a 100644 --- a/gpu/command_buffer/client/gles2_c_lib_autogen.h +++ b/gpu/command_buffer/client/gles2_c_lib_autogen.h
@@ -1719,7 +1719,7 @@ texture, target, internal_format, type, src_x, src_y, width, height, flip_y, src_mailbox); } -void GL_APIENTRY +GLboolean GL_APIENTRY GLES2ReadbackARGBImagePixelsINTERNAL(const GLbyte* mailbox, const void* dst_color_space, GLuint dst_color_space_size, @@ -1733,7 +1733,7 @@ GLint src_y, GLint plane_index, void* pixels) { - gles2::GetGLContext()->ReadbackARGBImagePixelsINTERNAL( + return gles2::GetGLContext()->ReadbackARGBImagePixelsINTERNAL( mailbox, dst_color_space, dst_color_space_size, dst_size, dst_width, dst_height, dst_color_type, dst_alpha_type, dst_row_bytes, src_x, src_y, plane_index, pixels);
diff --git a/gpu/command_buffer/client/gles2_implementation.cc b/gpu/command_buffer/client/gles2_implementation.cc index e02399b..ff1dad8e5 100644 --- a/gpu/command_buffer/client/gles2_implementation.cc +++ b/gpu/command_buffer/client/gles2_implementation.cc
@@ -4715,7 +4715,7 @@ pixel_offsets[1], pixel_offsets[2], pixel_offsets[3]); } -void GLES2Implementation::ReadbackARGBImagePixelsINTERNAL( +GLboolean GLES2Implementation::ReadbackARGBImagePixelsINTERNAL( const GLbyte* mailbox, const void* dst_sk_color_space, GLuint dst_color_space_size, @@ -4761,7 +4761,7 @@ ScopedMappedMemoryPtr scoped_shared_memory(total_size, helper(), mapped_memory_.get()); if (!scoped_shared_memory.valid()) { - return; + return GL_FALSE; } GLint shm_id = scoped_shared_memory.shm_id(); @@ -4790,9 +4790,10 @@ WaitForCmd(); if (!*readback_result) { - return; + return GL_FALSE; } memcpy(pixels, static_cast<uint8_t*>(shm_address) + pixels_offset, dst_size); + return GL_FALSE; } void GLES2Implementation::ReadPixels(GLint xoffset,
diff --git a/gpu/command_buffer/client/gles2_implementation_autogen.h b/gpu/command_buffer/client/gles2_implementation_autogen.h index cee7b50..64c45dbf 100644 --- a/gpu/command_buffer/client/gles2_implementation_autogen.h +++ b/gpu/command_buffer/client/gles2_implementation_autogen.h
@@ -1209,19 +1209,19 @@ GLboolean flip_y, const GLbyte* src_mailbox) override; -void ReadbackARGBImagePixelsINTERNAL(const GLbyte* mailbox, - const void* dst_color_space, - GLuint dst_color_space_size, - GLuint dst_size, - GLuint dst_width, - GLuint dst_height, - GLuint dst_color_type, - GLuint dst_alpha_type, - GLuint dst_row_bytes, - GLint src_x, - GLint src_y, - GLint plane_index, - void* pixels) override; +GLboolean ReadbackARGBImagePixelsINTERNAL(const GLbyte* mailbox, + const void* dst_color_space, + GLuint dst_color_space_size, + GLuint dst_size, + GLuint dst_width, + GLuint dst_height, + GLuint dst_color_type, + GLuint dst_alpha_type, + GLuint dst_row_bytes, + GLint src_x, + GLint src_y, + GLint plane_index, + void* pixels) override; void WritePixelsYUVINTERNAL(const GLbyte* mailbox, GLuint src_size_plane1,
diff --git a/gpu/command_buffer/client/gles2_interface_autogen.h b/gpu/command_buffer/client/gles2_interface_autogen.h index e8c9e68..7536f7a9 100644 --- a/gpu/command_buffer/client/gles2_interface_autogen.h +++ b/gpu/command_buffer/client/gles2_interface_autogen.h
@@ -904,19 +904,19 @@ GLsizei height, GLboolean flip_y, const GLbyte* src_mailbox) = 0; -virtual void ReadbackARGBImagePixelsINTERNAL(const GLbyte* mailbox, - const void* dst_color_space, - GLuint dst_color_space_size, - GLuint dst_size, - GLuint dst_width, - GLuint dst_height, - GLuint dst_color_type, - GLuint dst_alpha_type, - GLuint dst_row_bytes, - GLint src_x, - GLint src_y, - GLint plane_index, - void* pixels) = 0; +virtual GLboolean ReadbackARGBImagePixelsINTERNAL(const GLbyte* mailbox, + const void* dst_color_space, + GLuint dst_color_space_size, + GLuint dst_size, + GLuint dst_width, + GLuint dst_height, + GLuint dst_color_type, + GLuint dst_alpha_type, + GLuint dst_row_bytes, + GLint src_x, + GLint src_y, + GLint plane_index, + void* pixels) = 0; virtual void WritePixelsYUVINTERNAL(const GLbyte* mailbox, GLuint src_size_plane1, GLuint src_size_plane2,
diff --git a/gpu/command_buffer/client/gles2_interface_stub_autogen.h b/gpu/command_buffer/client/gles2_interface_stub_autogen.h index 98d47a044..692501a 100644 --- a/gpu/command_buffer/client/gles2_interface_stub_autogen.h +++ b/gpu/command_buffer/client/gles2_interface_stub_autogen.h
@@ -875,19 +875,19 @@ GLsizei height, GLboolean flip_y, const GLbyte* src_mailbox) override; -void ReadbackARGBImagePixelsINTERNAL(const GLbyte* mailbox, - const void* dst_color_space, - GLuint dst_color_space_size, - GLuint dst_size, - GLuint dst_width, - GLuint dst_height, - GLuint dst_color_type, - GLuint dst_alpha_type, - GLuint dst_row_bytes, - GLint src_x, - GLint src_y, - GLint plane_index, - void* pixels) override; +GLboolean ReadbackARGBImagePixelsINTERNAL(const GLbyte* mailbox, + const void* dst_color_space, + GLuint dst_color_space_size, + GLuint dst_size, + GLuint dst_width, + GLuint dst_height, + GLuint dst_color_type, + GLuint dst_alpha_type, + GLuint dst_row_bytes, + GLint src_x, + GLint src_y, + GLint plane_index, + void* pixels) override; void WritePixelsYUVINTERNAL(const GLbyte* mailbox, GLuint src_size_plane1, GLuint src_size_plane2,
diff --git a/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h b/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h index 44c41b203..f5d0958 100644 --- a/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h +++ b/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h
@@ -1178,7 +1178,7 @@ GLsizei /* height */, GLboolean /* flip_y */, const GLbyte* /* src_mailbox */) {} -void GLES2InterfaceStub::ReadbackARGBImagePixelsINTERNAL( +GLboolean GLES2InterfaceStub::ReadbackARGBImagePixelsINTERNAL( const GLbyte* /* mailbox */, const void* /* dst_color_space */, GLuint /* dst_color_space_size */, @@ -1191,7 +1191,9 @@ GLint /* src_x */, GLint /* src_y */, GLint /* plane_index */, - void* /* pixels */) {} + void* /* pixels */) { + return 0; +} void GLES2InterfaceStub::WritePixelsYUVINTERNAL( const GLbyte* /* mailbox */, GLuint /* src_size_plane1 */,
diff --git a/gpu/command_buffer/client/gles2_trace_implementation_autogen.h b/gpu/command_buffer/client/gles2_trace_implementation_autogen.h index 7b0df1e1..f6a29b7 100644 --- a/gpu/command_buffer/client/gles2_trace_implementation_autogen.h +++ b/gpu/command_buffer/client/gles2_trace_implementation_autogen.h
@@ -875,19 +875,19 @@ GLsizei height, GLboolean flip_y, const GLbyte* src_mailbox) override; -void ReadbackARGBImagePixelsINTERNAL(const GLbyte* mailbox, - const void* dst_color_space, - GLuint dst_color_space_size, - GLuint dst_size, - GLuint dst_width, - GLuint dst_height, - GLuint dst_color_type, - GLuint dst_alpha_type, - GLuint dst_row_bytes, - GLint src_x, - GLint src_y, - GLint plane_index, - void* pixels) override; +GLboolean ReadbackARGBImagePixelsINTERNAL(const GLbyte* mailbox, + const void* dst_color_space, + GLuint dst_color_space_size, + GLuint dst_size, + GLuint dst_width, + GLuint dst_height, + GLuint dst_color_type, + GLuint dst_alpha_type, + GLuint dst_row_bytes, + GLint src_x, + GLint src_y, + GLint plane_index, + void* pixels) override; void WritePixelsYUVINTERNAL(const GLbyte* mailbox, GLuint src_size_plane1, GLuint src_size_plane2,
diff --git a/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h b/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h index 2d759eb..183105c7 100644 --- a/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h +++ b/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h
@@ -2486,7 +2486,7 @@ src_mailbox); } -void GLES2TraceImplementation::ReadbackARGBImagePixelsINTERNAL( +GLboolean GLES2TraceImplementation::ReadbackARGBImagePixelsINTERNAL( const GLbyte* mailbox, const void* dst_color_space, GLuint dst_color_space_size, @@ -2502,7 +2502,7 @@ void* pixels) { TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::ReadbackARGBImagePixelsINTERNAL"); - gl_->ReadbackARGBImagePixelsINTERNAL( + return gl_->ReadbackARGBImagePixelsINTERNAL( mailbox, dst_color_space, dst_color_space_size, dst_size, dst_width, dst_height, dst_color_type, dst_alpha_type, dst_row_bytes, src_x, src_y, plane_index, pixels);
diff --git a/gpu/command_buffer/client/raster_implementation.cc b/gpu/command_buffer/client/raster_implementation.cc index ebf2dcf..2363ec5 100644 --- a/gpu/command_buffer/client/raster_implementation.cc +++ b/gpu/command_buffer/client/raster_implementation.cc
@@ -91,6 +91,10 @@ namespace { +BASE_FEATURE(kDisableErrorHandlingForReadback, + "kDisableErrorHandlingForReadback", + base::FEATURE_DISABLED_BY_DEFAULT); + BASE_FEATURE(kPaintCacheBudgetConfigurableFeature, "PaintCacheBudgetConfigurableFeature", base::FEATURE_ENABLED_BY_DEFAULT); @@ -1539,7 +1543,7 @@ return decode_sync_token; } -void RasterImplementation::ReadbackImagePixelsINTERNAL( +bool RasterImplementation::ReadbackImagePixelsINTERNAL( const gpu::Mailbox& source_mailbox, const SkImageInfo& dst_info, GLuint dst_row_bytes, @@ -1580,7 +1584,7 @@ if (readback_done) { std::move(readback_done).Run(/*success=*/false); } - return; + return false; } GLint shm_id = scoped_shared_memory->shm_id(); @@ -1632,12 +1636,14 @@ WaitForCmd(); if (!*readback_result) { - return; + return false; } memcpy(dst_pixels, static_cast<uint8_t*>(shm_address) + pixels_offset, dst_size); } + + return true; } void RasterImplementation::OnAsyncARGBReadbackDone( @@ -1721,7 +1727,7 @@ std::move(readback_done), out); } -void RasterImplementation::ReadbackImagePixels( +bool RasterImplementation::ReadbackImagePixels( const gpu::Mailbox& source_mailbox, const SkImageInfo& dst_info, GLuint dst_row_bytes, @@ -1730,9 +1736,10 @@ int plane_index, void* dst_pixels) { TRACE_EVENT0("gpu", "RasterImplementation::ReadbackImagePixels"); - ReadbackImagePixelsINTERNAL(source_mailbox, dst_info, dst_row_bytes, src_x, - src_y, plane_index, - base::OnceCallback<void(bool)>(), dst_pixels); + return ReadbackImagePixelsINTERNAL( + source_mailbox, dst_info, dst_row_bytes, src_x, src_y, plane_index, + base::OnceCallback<void(bool)>(), dst_pixels) || + base::FeatureList::IsEnabled(kDisableErrorHandlingForReadback); } void RasterImplementation::ReadbackYUVPixelsAsync(
diff --git a/gpu/command_buffer/client/raster_implementation.h b/gpu/command_buffer/client/raster_implementation.h index e9ea8ded0f..d8590094 100644 --- a/gpu/command_buffer/client/raster_implementation.h +++ b/gpu/command_buffer/client/raster_implementation.h
@@ -203,7 +203,7 @@ const gfx::Point& paste_location, base::OnceCallback<void()> release_mailbox, base::OnceCallback<void(bool)> readback_done) override; - void ReadbackImagePixels(const gpu::Mailbox& source_mailbox, + bool ReadbackImagePixels(const gpu::Mailbox& source_mailbox, const SkImageInfo& dst_info, GLuint dst_row_bytes, int src_x, @@ -350,7 +350,7 @@ SyncToken* decode_sync_token, ClientDiscardableHandle handle); - void ReadbackImagePixelsINTERNAL(const gpu::Mailbox& source_mailbox, + bool ReadbackImagePixelsINTERNAL(const gpu::Mailbox& source_mailbox, const SkImageInfo& dst_info, GLuint dst_row_bytes, int src_x,
diff --git a/gpu/command_buffer/client/raster_implementation_gles.cc b/gpu/command_buffer/client/raster_implementation_gles.cc index a5ec9c64..333208ad 100644 --- a/gpu/command_buffer/client/raster_implementation_gles.cc +++ b/gpu/command_buffer/client/raster_implementation_gles.cc
@@ -32,6 +32,12 @@ namespace { +// This is kill-switch for fixing error handling of ReadbackImagePixels +// function. +BASE_FEATURE(kDisableErrorHandlingForReadbackGLES, + "kDisableErrorHandlingForReadbackGLES", + base::FEATURE_DISABLED_BY_DEFAULT); + GLenum SkColorTypeToGLDataFormat(SkColorType color_type, bool supports_rg) { switch (color_type) { case kRGBA_8888_SkColorType: @@ -519,7 +525,7 @@ std::move(release_mailbox).Run(); } -void RasterImplementationGLES::ReadbackImagePixels( +bool RasterImplementationGLES::ReadbackImagePixels( const gpu::Mailbox& source_mailbox, const SkImageInfo& dst_info, GLuint dst_row_bytes, @@ -535,13 +541,14 @@ } GLuint dst_size = dst_info.computeByteSize(dst_row_bytes); - gl_->ReadbackARGBImagePixelsINTERNAL( - source_mailbox.name, - dst_color_space_data ? dst_color_space_data->data() : nullptr, - dst_color_space_data ? dst_color_space_data->size() : 0, dst_size, - dst_info.width(), dst_info.height(), dst_info.colorType(), - dst_info.alphaType(), dst_row_bytes, src_x, src_y, plane_index, - dst_pixels); + return gl_->ReadbackARGBImagePixelsINTERNAL( + source_mailbox.name, + dst_color_space_data ? dst_color_space_data->data() : nullptr, + dst_color_space_data ? dst_color_space_data->size() : 0, dst_size, + dst_info.width(), dst_info.height(), dst_info.colorType(), + dst_info.alphaType(), dst_row_bytes, src_x, src_y, plane_index, + dst_pixels) || + base::FeatureList::IsEnabled(kDisableErrorHandlingForReadbackGLES); } GLuint RasterImplementationGLES::CreateAndConsumeForGpuRaster(
diff --git a/gpu/command_buffer/client/raster_implementation_gles.h b/gpu/command_buffer/client/raster_implementation_gles.h index 35dbf1c..713b583f 100644 --- a/gpu/command_buffer/client/raster_implementation_gles.h +++ b/gpu/command_buffer/client/raster_implementation_gles.h
@@ -152,7 +152,7 @@ base::OnceCallback<void()> release_mailbox, base::OnceCallback<void(bool)> readback_done) override; - void ReadbackImagePixels(const gpu::Mailbox& source_mailbox, + bool ReadbackImagePixels(const gpu::Mailbox& source_mailbox, const SkImageInfo& dst_info, GLuint dst_row_bytes, int src_x,
diff --git a/gpu/command_buffer/client/raster_interface.h b/gpu/command_buffer/client/raster_interface.h index f775f2a..062a169 100644 --- a/gpu/command_buffer/client/raster_interface.h +++ b/gpu/command_buffer/client/raster_interface.h
@@ -197,7 +197,7 @@ // applies to multiplanar textures in mailboxes, for example YUV images // produced by the VideoDecoder. |plane_index| as 0 should be passed for known // single-plane textures. - virtual void ReadbackImagePixels(const gpu::Mailbox& source_mailbox, + virtual bool ReadbackImagePixels(const gpu::Mailbox& source_mailbox, const SkImageInfo& dst_info, GLuint dst_row_bytes, int src_x,
diff --git a/gpu/command_buffer/gles2_cmd_buffer_functions.txt b/gpu/command_buffer/gles2_cmd_buffer_functions.txt index 5908b94..4dacf67 100644 --- a/gpu/command_buffer/gles2_cmd_buffer_functions.txt +++ b/gpu/command_buffer/gles2_cmd_buffer_functions.txt
@@ -383,7 +383,7 @@ GL_APICALL void GL_APIENTRY glConvertYUVAMailboxesToTextureINTERNAL (GLuint texture, GLenum target, GLuint internal_format, GLenum type, GLint src_x, GLint src_y, GLsizei width, GLsizei height, GLboolean flip_y, GLenum planes_yuv_color_space, GLenum plane_config, GLenum subsampling, const GLbyte* mailboxes); GL_APICALL void GL_APIENTRY glCopySharedImageINTERNAL (GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, GLboolean unpack_flip_y, const GLbyte* mailboxes); GL_APICALL void GL_APIENTRY glCopySharedImageToTextureINTERNAL (GLuint texture, GLenum target, GLuint internal_format, GLenum type, GLint src_x, GLint src_y, GLsizei width, GLsizei height, GLboolean flip_y, const GLbyte* src_mailbox); -GL_APICALL void GL_APIENTRY glReadbackARGBImagePixelsINTERNAL (const GLbyte* mailbox, const void* dst_color_space, GLuint dst_color_space_size, GLuint dst_size, GLuint dst_width, GLuint dst_height, GLuint dst_color_type, GLuint dst_alpha_type, GLuint dst_row_bytes, GLint src_x, GLint src_y, GLint plane_index, void* pixels); +GL_APICALL GLboolean GL_APIENTRY glReadbackARGBImagePixelsINTERNAL (const GLbyte* mailbox, const void* dst_color_space, GLuint dst_color_space_size, GLuint dst_size, GLuint dst_width, GLuint dst_height, GLuint dst_color_type, GLuint dst_alpha_type, GLuint dst_row_bytes, GLint src_x, GLint src_y, GLint plane_index, void* pixels); GL_APICALL void GL_APIENTRY glWritePixelsYUVINTERNAL (const GLbyte* mailbox, GLuint src_size_plane1, GLuint src_size_plane2, GLuint src_size_plane3, GLuint src_size_plane4, GLuint src_width, GLuint src_height, GLuint src_plane_config, GLuint src_subsampling, GLuint src_datatype, GLuint src_row_bytes_plane1, GLuint src_row_bytes_plane2, GLuint src_row_bytes_plane3, GLuint src_row_bytes_plane4, const void* src_pixels_plane1, const void* src_pixels_plane2, const void* src_pixels_plane3, const void* src_pixels_plane4); // Extension OES_draw_buffers_indexed
diff --git a/gpu/command_buffer/service/feature_info.cc b/gpu/command_buffer/service/feature_info.cc index 6d3b0063..701850c 100644 --- a/gpu/command_buffer/service/feature_info.cc +++ b/gpu/command_buffer/service/feature_info.cc
@@ -189,10 +189,6 @@ InitializeBasicState(base::CommandLine::InitializedForCurrentProcess() ? base::CommandLine::ForCurrentProcess() : nullptr); - feature_flags_.android_surface_control = - gpu_feature_info - .status_values[GPU_FEATURE_TYPE_ANDROID_SURFACE_CONTROL] == - gpu::kGpuFeatureStatusEnabled; #if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_CAST_ANDROID) || \ BUILDFLAG(IS_FUCHSIA)
diff --git a/gpu/command_buffer/service/feature_info.h b/gpu/command_buffer/service/feature_info.h index f1f2d446..a984a89 100644 --- a/gpu/command_buffer/service/feature_info.h +++ b/gpu/command_buffer/service/feature_info.h
@@ -131,7 +131,6 @@ bool mesa_framebuffer_flip_y = false; bool ovr_multiview2 = false; bool khr_parallel_shader_compile = false; - bool android_surface_control = false; bool khr_robust_buffer_access_behavior = false; bool webgl_multi_draw = false; bool nv_internalformat_sample_query = false;
diff --git a/gpu/command_buffer/service/shared_image/shared_image_backing.h b/gpu/command_buffer/service/shared_image/shared_image_backing.h index 53a649a0..cc1ebcae 100644 --- a/gpu/command_buffer/service/shared_image/shared_image_backing.h +++ b/gpu/command_buffer/service/shared_image/shared_image_backing.h
@@ -140,6 +140,7 @@ bool is_thread_safe() const { return !!lock_; } bool is_ref_counted() const { return is_ref_counted_; } gfx::BufferUsage buffer_usage() const { return buffer_usage_.value(); } + const std::string& debug_label() const { return debug_label_; } void OnContextLost(); @@ -263,8 +264,6 @@ friend class SharedImageManager; friend class CompoundImageBacking; - const std::string& debug_label() const { return debug_label_; } - virtual std::unique_ptr<GLTextureImageRepresentation> ProduceGLTexture( SharedImageManager* manager, MemoryTypeTracker* tracker);
diff --git a/gpu/command_buffer/service/shared_image/shared_image_format_service_utils.cc b/gpu/command_buffer/service/shared_image/shared_image_format_service_utils.cc index 135be19..b9b19e7 100644 --- a/gpu/command_buffer/service/shared_image/shared_image_format_service_utils.cc +++ b/gpu/command_buffer/service/shared_image/shared_image_format_service_utils.cc
@@ -627,15 +627,21 @@ CHECK_EQ(gr_context_type, GrContextType::kGraphiteDawn); #if BUILDFLAG(SKIA_USE_DAWN) skgpu::graphite::DawnTextureInfo dawn_texture_info; - wgpu::TextureFormat wgpu_format = + wgpu::TextureFormat wgpu_view_format = gpu::ToDawnTextureViewFormat(format, plane_index); - if (wgpu_format == wgpu::TextureFormat::Undefined) { + if (wgpu_view_format == wgpu::TextureFormat::Undefined) { return dawn_texture_info; } dawn_texture_info.fSampleCount = 1; - dawn_texture_info.fFormat = wgpu_format; + // For multiplanar shared image, we don't know the real texture format until + // the promise image is fulfilled, so set the fFormat to Undefined for now. + dawn_texture_info.fFormat = format.is_multi_plane() + ? wgpu::TextureFormat::Undefined + : wgpu_view_format; + dawn_texture_info.fViewFormat = wgpu_view_format; // The aspect is always defaulted to all as multiplanar copies are not // needed by the display compositor. + // TODO(324422644): set fAspect to Undefined for multiplanar format. dawn_texture_info.fAspect = wgpu::TextureAspect::All; // For promise textures, just need TextureBinding usage for sampling // except for dcomp scanout which needs rendering and copy usages as well. @@ -659,13 +665,15 @@ bool supports_multiplanar_rendering, bool supports_multiplanar_copy) { skgpu::graphite::DawnTextureInfo dawn_texture_info; - wgpu::TextureFormat wgpu_format = + wgpu::TextureFormat wgpu_view_format = ToDawnTextureViewFormat(format, plane_index); - if (wgpu_format == wgpu::TextureFormat::Undefined) { + if (wgpu_view_format == wgpu::TextureFormat::Undefined) { return dawn_texture_info; } dawn_texture_info.fSampleCount = 1; - dawn_texture_info.fFormat = wgpu_format; + dawn_texture_info.fFormat = + is_yuv_plane ? ToDawnFormat(format) : wgpu_view_format; + dawn_texture_info.fViewFormat = wgpu_view_format; dawn_texture_info.fAspect = ToDawnTextureAspect(is_yuv_plane, plane_index); dawn_texture_info.fUsage = SupportedDawnTextureUsage( is_yuv_plane, scanout_dcomp_surface, supports_multiplanar_rendering, @@ -681,4 +689,20 @@ } #endif +skgpu::graphite::TextureInfo FallbackGraphiteBackendTextureInfo( + const skgpu::graphite::TextureInfo& texture_info) { +#if BUILDFLAG(SKIA_USE_DAWN) + skgpu::graphite::DawnTextureInfo info; + if (texture_info.getDawnTextureInfo(&info) && + info.fFormat == wgpu::TextureFormat::Undefined) { + // For multiplanar textures, the fFormat of promise images is Undefined, + // so the fViewFormat should be used to create fallback textures. + info.fFormat = info.fViewFormat; + info.fAspect = wgpu::TextureAspect::All; + return skgpu::graphite::TextureInfo(info); + } +#endif + return texture_info; +} + } // namespace gpu
diff --git a/gpu/command_buffer/service/shared_image/shared_image_format_service_utils.h b/gpu/command_buffer/service/shared_image/shared_image_format_service_utils.h index 8cc1a790..857ac53 100644 --- a/gpu/command_buffer/service/shared_image/shared_image_format_service_utils.h +++ b/gpu/command_buffer/service/shared_image/shared_image_format_service_utils.h
@@ -210,6 +210,10 @@ bool mipmapped = false); #endif +GPU_GLES2_EXPORT +skgpu::graphite::TextureInfo FallbackGraphiteBackendTextureInfo( + const skgpu::graphite::TextureInfo& texture_info); + } // namespace gpu #endif // GPU_COMMAND_BUFFER_SERVICE_SHARED_IMAGE_SHARED_IMAGE_FORMAT_SERVICE_UTILS_H_
diff --git a/gpu/command_buffer/service/shared_image/shared_image_representation.h b/gpu/command_buffer/service/shared_image/shared_image_representation.h index 0c43f4a..57098b2 100644 --- a/gpu/command_buffer/service/shared_image/shared_image_representation.h +++ b/gpu/command_buffer/service/shared_image/shared_image_representation.h
@@ -115,6 +115,8 @@ SkAlphaType alpha_type() const { return backing_->alpha_type(); } uint32_t usage() const { return backing_->usage(); } const gpu::Mailbox& mailbox() const { return backing_->mailbox(); } + const std::string& debug_label() const { return backing_->debug_label(); } + const char* backing_name() const { return backing_->GetName(); } MemoryTypeTracker* tracker() { return tracker_; } bool IsCleared() const { return backing_->IsCleared(); } void SetCleared() { backing_->SetCleared(); }
diff --git a/gpu/ipc/service/BUILD.gn b/gpu/ipc/service/BUILD.gn index cfbc983..6716bd24 100644 --- a/gpu/ipc/service/BUILD.gn +++ b/gpu/ipc/service/BUILD.gn
@@ -41,7 +41,6 @@ "image_decode_accelerator_stub.h", "image_decode_accelerator_worker.h", "image_transport_surface.h", - "image_transport_surface_delegate.h", "raster_command_buffer_stub.cc", "raster_command_buffer_stub.h", "shared_image_stub.cc",
diff --git a/gpu/ipc/service/gles2_command_buffer_stub.cc b/gpu/ipc/service/gles2_command_buffer_stub.cc index c905fc33..dd81fbec 100644 --- a/gpu/ipc/service/gles2_command_buffer_stub.cc +++ b/gpu/ipc/service/gles2_command_buffer_stub.cc
@@ -196,8 +196,7 @@ // offscreen. auto surface_format = default_surface->GetFormat(); surface_ = ImageTransportSurface::CreateNativeGLSurface( - display, weak_ptr_factory_.GetWeakPtr(), init_params.surface_handle, - surface_format); + display, init_params.surface_handle, surface_format); if (!surface_ || !surface_->Initialize(surface_format)) { surface_ = nullptr; LOG(ERROR) << "ContextResult::kSurfaceFailure: Failed to create surface."; @@ -390,21 +389,6 @@ return gpu::ContextResult::kSuccess; } -#if BUILDFLAG(IS_WIN) -void GLES2CommandBufferStub::AddChildWindowToBrowser( - gpu::SurfaceHandle child_window) { - NOTREACHED(); -} -#endif - -const gles2::FeatureInfo* GLES2CommandBufferStub::GetFeatureInfo() const { - return context_group_->feature_info(); -} - -const GpuPreferences& GLES2CommandBufferStub::GetGpuPreferences() const { - return context_group_->gpu_preferences(); -} - MemoryTracker* GLES2CommandBufferStub::GetContextGroupMemoryTracker() const { return context_group_->memory_tracker(); }
diff --git a/gpu/ipc/service/gles2_command_buffer_stub.h b/gpu/ipc/service/gles2_command_buffer_stub.h index f48b26a..efa169bb 100644 --- a/gpu/ipc/service/gles2_command_buffer_stub.h +++ b/gpu/ipc/service/gles2_command_buffer_stub.h
@@ -7,10 +7,8 @@ #include "base/containers/circular_deque.h" #include "base/memory/raw_ptr.h" -#include "base/memory/weak_ptr.h" #include "build/build_config.h" #include "gpu/ipc/service/command_buffer_stub.h" -#include "gpu/ipc/service/image_transport_surface_delegate.h" #include "ui/gfx/gpu_fence_handle.h" namespace gpu { @@ -18,8 +16,7 @@ struct Mailbox; class GPU_IPC_SERVICE_EXPORT GLES2CommandBufferStub final - : public CommandBufferStub, - public ImageTransportSurfaceDelegate { + : public CommandBufferStub { public: GLES2CommandBufferStub(GpuChannel* channel, const mojom::CreateCommandBufferParams& init_params, @@ -47,13 +44,6 @@ // DecoderClient implementation. void OnGpuSwitched(gl::GpuPreference active_gpu_heuristic) override; -// ImageTransportSurfaceDelegate implementation: -#if BUILDFLAG(IS_WIN) - void AddChildWindowToBrowser(gpu::SurfaceHandle child_window) override; -#endif - const gles2::FeatureInfo* GetFeatureInfo() const override; - const GpuPreferences& GetGpuPreferences() const override; - private: // CommandBufferStub overrides: void OnSetDefaultFramebufferSharedImage(const Mailbox& mailbox,
diff --git a/gpu/ipc/service/image_transport_surface.h b/gpu/ipc/service/image_transport_surface.h index 12585e0..0d177cd 100644 --- a/gpu/ipc/service/image_transport_surface.h +++ b/gpu/ipc/service/image_transport_surface.h
@@ -16,7 +16,8 @@ #include "ui/gl/presenter.h" namespace gpu { -class ImageTransportSurfaceDelegate; +class GpuDriverBugWorkarounds; +struct GpuFeatureInfo; // The GPU process is agnostic as to how it displays results. On some platforms // it renders directly to window. On others it renders offscreen and transports @@ -31,7 +32,8 @@ // presentation using GLSurface by calling `CreateNativeGLSurface` below. static scoped_refptr<gl::Presenter> CreatePresenter( gl::GLDisplay* display, - base::WeakPtr<ImageTransportSurfaceDelegate> stub, + const GpuDriverBugWorkarounds& workarounds, + const GpuFeatureInfo& gpu_feature_info, SurfaceHandle surface_handle); // Creates the appropriate native surface depending on the GL implementation. @@ -39,7 +41,6 @@ // scoped_refptr should be returned. static scoped_refptr<gl::GLSurface> CreateNativeGLSurface( gl::GLDisplay* display, - base::WeakPtr<ImageTransportSurfaceDelegate> stub, SurfaceHandle surface_handle, gl::GLSurfaceFormat format);
diff --git a/gpu/ipc/service/image_transport_surface_android.cc b/gpu/ipc/service/image_transport_surface_android.cc index 38106c0..ccf2dd04 100644 --- a/gpu/ipc/service/image_transport_surface_android.cc +++ b/gpu/ipc/service/image_transport_surface_android.cc
@@ -14,10 +14,8 @@ #include "base/functional/overloaded.h" #include "base/logging.h" #include "base/task/single_thread_task_runner.h" -#include "gpu/command_buffer/service/feature_info.h" -#include "gpu/config/gpu_finch_features.h" +#include "gpu/config/gpu_feature_info.h" #include "gpu/ipc/common/gpu_surface_lookup.h" -#include "gpu/ipc/service/image_transport_surface_delegate.h" #include "third_party/abseil-cpp/absl/types/variant.h" #include "ui/gl/android/scoped_a_native_window.h" #include "ui/gl/gl_surface_egl.h" @@ -29,14 +27,16 @@ // static scoped_refptr<gl::Presenter> ImageTransportSurface::CreatePresenter( gl::GLDisplay* display, - base::WeakPtr<ImageTransportSurfaceDelegate> delegate, + const GpuDriverBugWorkarounds& workarounds, + const GpuFeatureInfo& gpu_feature_info, SurfaceHandle surface_handle) { if (gl::GetGLImplementation() == gl::kGLImplementationMockGL || gl::GetGLImplementation() == gl::kGLImplementationStubGL) return nullptr; - if (!delegate || - !delegate->GetFeatureInfo()->feature_flags().android_surface_control) { + if (gpu_feature_info + .status_values[GPU_FEATURE_TYPE_ANDROID_SURFACE_CONTROL] != + gpu::kGpuFeatureStatusEnabled) { return nullptr; } @@ -77,7 +77,6 @@ // static scoped_refptr<gl::GLSurface> ImageTransportSurface::CreateNativeGLSurface( gl::GLDisplay* display, - base::WeakPtr<ImageTransportSurfaceDelegate> delegate, SurfaceHandle surface_handle, gl::GLSurfaceFormat format) { if (gl::GetGLImplementation() == gl::kGLImplementationMockGL ||
diff --git a/gpu/ipc/service/image_transport_surface_delegate.h b/gpu/ipc/service/image_transport_surface_delegate.h deleted file mode 100644 index 2dc9b44b..0000000 --- a/gpu/ipc/service/image_transport_surface_delegate.h +++ /dev/null
@@ -1,40 +0,0 @@ -// Copyright 2016 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef GPU_IPC_SERVICE_IMAGE_TRANSPORT_SURFACE_DELEGATE_H_ -#define GPU_IPC_SERVICE_IMAGE_TRANSPORT_SURFACE_DELEGATE_H_ - -#include "base/functional/callback.h" -#include "build/build_config.h" -#include "gpu/ipc/common/surface_handle.h" -#include "gpu/ipc/service/gpu_ipc_service_export.h" -#include "ui/gfx/gpu_fence_handle.h" - -namespace gpu { -struct GpuPreferences; - -namespace gles2 { -class FeatureInfo; -} - -class GPU_IPC_SERVICE_EXPORT ImageTransportSurfaceDelegate { - public: -#if BUILDFLAG(IS_WIN) - // Sends the created child window to the browser process so that it can be - // parented to the browser process window - virtual void AddChildWindowToBrowser(gpu::SurfaceHandle child_window) = 0; -#endif - - // Returns the features available for the ContextGroup. - virtual const gles2::FeatureInfo* GetFeatureInfo() const = 0; - - virtual const GpuPreferences& GetGpuPreferences() const = 0; - - protected: - virtual ~ImageTransportSurfaceDelegate() = default; -}; - -} // namespace gpu - -#endif // GPU_IPC_SERVICE_IMAGE_TRANSPORT_SURFACE_DELEGATE_H_
diff --git a/gpu/ipc/service/image_transport_surface_fuchsia.cc b/gpu/ipc/service/image_transport_surface_fuchsia.cc index 0ad31b31..5278321 100644 --- a/gpu/ipc/service/image_transport_surface_fuchsia.cc +++ b/gpu/ipc/service/image_transport_surface_fuchsia.cc
@@ -13,7 +13,8 @@ // static scoped_refptr<gl::Presenter> ImageTransportSurface::CreatePresenter( gl::GLDisplay* display, - base::WeakPtr<ImageTransportSurfaceDelegate> delegate, + const GpuDriverBugWorkarounds& workarounds, + const GpuFeatureInfo& gpu_feature_info, SurfaceHandle surface_handle) { return nullptr; } @@ -21,7 +22,6 @@ // static scoped_refptr<gl::GLSurface> ImageTransportSurface::CreateNativeGLSurface( gl::GLDisplay* display, - base::WeakPtr<ImageTransportSurfaceDelegate> delegate, SurfaceHandle surface_handle, gl::GLSurfaceFormat format) { if (gl::GetGLImplementation() == gl::kGLImplementationMockGL ||
diff --git a/gpu/ipc/service/image_transport_surface_ios.mm b/gpu/ipc/service/image_transport_surface_ios.mm index ed7dca7..f9a2df27 100644 --- a/gpu/ipc/service/image_transport_surface_ios.mm +++ b/gpu/ipc/service/image_transport_surface_ios.mm
@@ -14,7 +14,8 @@ // static scoped_refptr<gl::Presenter> ImageTransportSurface::CreatePresenter( gl::GLDisplay* display, - base::WeakPtr<ImageTransportSurfaceDelegate> delegate, + const GpuDriverBugWorkarounds& workarounds, + const GpuFeatureInfo& gpu_feature_info, SurfaceHandle surface_handle) { DCHECK_NE(surface_handle, kNullSurfaceHandle); if (gl::GetGLImplementation() == gl::kGLImplementationEGLGLES2 || @@ -28,7 +29,6 @@ // static scoped_refptr<gl::GLSurface> ImageTransportSurface::CreateNativeGLSurface( gl::GLDisplay* display, - base::WeakPtr<ImageTransportSurfaceDelegate> delegate, SurfaceHandle surface_handle, gl::GLSurfaceFormat format) { DCHECK_NE(surface_handle, kNullSurfaceHandle);
diff --git a/gpu/ipc/service/image_transport_surface_linux.cc b/gpu/ipc/service/image_transport_surface_linux.cc index d4ef5efd..f2f6653e8 100644 --- a/gpu/ipc/service/image_transport_surface_linux.cc +++ b/gpu/ipc/service/image_transport_surface_linux.cc
@@ -12,7 +12,8 @@ // static scoped_refptr<gl::Presenter> ImageTransportSurface::CreatePresenter( gl::GLDisplay* display, - base::WeakPtr<ImageTransportSurfaceDelegate> delegate, + const GpuDriverBugWorkarounds& workarounds, + const GpuFeatureInfo& gpu_feature_info, SurfaceHandle surface_handle) { DCHECK_NE(surface_handle, kNullSurfaceHandle); #if BUILDFLAG(IS_OZONE) @@ -25,7 +26,6 @@ // static scoped_refptr<gl::GLSurface> ImageTransportSurface::CreateNativeGLSurface( gl::GLDisplay* display, - base::WeakPtr<ImageTransportSurfaceDelegate> delegate, SurfaceHandle surface_handle, gl::GLSurfaceFormat format) { DCHECK_NE(surface_handle, kNullSurfaceHandle);
diff --git a/gpu/ipc/service/image_transport_surface_mac.mm b/gpu/ipc/service/image_transport_surface_mac.mm index 557b9bc1..cb322842 100644 --- a/gpu/ipc/service/image_transport_surface_mac.mm +++ b/gpu/ipc/service/image_transport_surface_mac.mm
@@ -14,7 +14,8 @@ // static scoped_refptr<gl::Presenter> ImageTransportSurface::CreatePresenter( gl::GLDisplay* display, - base::WeakPtr<ImageTransportSurfaceDelegate> delegate, + const GpuDriverBugWorkarounds& workarounds, + const GpuFeatureInfo& gpu_feature_info, SurfaceHandle surface_handle) { DCHECK_NE(surface_handle, kNullSurfaceHandle); if (gl::GetGLImplementation() == gl::kGLImplementationEGLGLES2 || @@ -28,7 +29,6 @@ // static scoped_refptr<gl::GLSurface> ImageTransportSurface::CreateNativeGLSurface( gl::GLDisplay* display, - base::WeakPtr<ImageTransportSurfaceDelegate> delegate, SurfaceHandle surface_handle, gl::GLSurfaceFormat format) { DCHECK_NE(surface_handle, kNullSurfaceHandle);
diff --git a/gpu/ipc/service/image_transport_surface_overlay_mac.mm b/gpu/ipc/service/image_transport_surface_overlay_mac.mm index 9599d5f3..6b4b723f 100644 --- a/gpu/ipc/service/image_transport_surface_overlay_mac.mm +++ b/gpu/ipc/service/image_transport_surface_overlay_mac.mm
@@ -18,7 +18,6 @@ #include "gpu/command_buffer/common/swap_buffers_complete_params.h" #include "gpu/ipc/service/gpu_channel_manager.h" #include "gpu/ipc/service/gpu_channel_manager_delegate.h" -#include "gpu/ipc/service/image_transport_surface_delegate.h" #include "ui/accelerated_widget_mac/ca_layer_tree_coordinator.h" #include "ui/base/cocoa/remote_layer_api.h" #include "ui/base/ui_base_switches.h"
diff --git a/gpu/ipc/service/image_transport_surface_win.cc b/gpu/ipc/service/image_transport_surface_win.cc index 9d8447cf..68a43b82 100644 --- a/gpu/ipc/service/image_transport_surface_win.cc +++ b/gpu/ipc/service/image_transport_surface_win.cc
@@ -7,9 +7,7 @@ #include <memory> #include "base/win/windows_version.h" -#include "gpu/command_buffer/service/feature_info.h" -#include "gpu/config/gpu_preferences.h" -#include "gpu/ipc/service/image_transport_surface_delegate.h" +#include "gpu/config/gpu_driver_bug_workarounds.h" #include "ui/gfx/native_widget_types.h" #include "ui/gl/dcomp_presenter.h" #include "ui/gl/direct_composition_support.h" @@ -44,18 +42,15 @@ // static scoped_refptr<gl::Presenter> ImageTransportSurface::CreatePresenter( gl::GLDisplay* display, - base::WeakPtr<ImageTransportSurfaceDelegate> delegate, + const GpuDriverBugWorkarounds& workarounds, + const GpuFeatureInfo& gpu_feature_info, SurfaceHandle surface_handle) { if (gl::DirectCompositionSupported()) { - auto settings = - CreatDCompPresenterSettings(delegate->GetFeatureInfo()->workarounds()); - auto presenter = base::MakeRefCounted<gl::DCompPresenter>( - display->GetAs<gl::GLDisplayEGL>(), settings); + auto settings = CreatDCompPresenterSettings(workarounds); + auto presenter = base::MakeRefCounted<gl::DCompPresenter>(settings); if (!presenter->Initialize()) { return nullptr; } - - delegate->AddChildWindowToBrowser(presenter->window()); return presenter; } @@ -65,7 +60,6 @@ // static scoped_refptr<gl::GLSurface> ImageTransportSurface::CreateNativeGLSurface( gl::GLDisplay* display, - base::WeakPtr<ImageTransportSurfaceDelegate> delegate, SurfaceHandle surface_handle, gl::GLSurfaceFormat format) { DCHECK_NE(surface_handle, kNullSurfaceHandle);
diff --git a/infra/inclusive_language_presubmit_exempt_dirs.txt b/infra/inclusive_language_presubmit_exempt_dirs.txt index 4617261..e69e9fa 100644 --- a/infra/inclusive_language_presubmit_exempt_dirs.txt +++ b/infra/inclusive_language_presubmit_exempt_dirs.txt
@@ -84,6 +84,7 @@ chrome/install_static 1 1 chromeos/ash/components/carrier_lock 3 1 chromeos/ash/components/network/onc 1 1 +chromeos/ash/services/ime/public/cpp/shared_lib/proto 1 1 chromeos/ash/services/ime/public/mojom 1 1 chromeos/crosapi 2 1 chromeos/lacros 2 1
diff --git a/ios/chrome/app/BUILD.gn b/ios/chrome/app/BUILD.gn index 8dd93e7..7f169bf 100644 --- a/ios/chrome/app/BUILD.gn +++ b/ios/chrome/app/BUILD.gn
@@ -535,6 +535,7 @@ "//ios/chrome/browser/browser_state/model", "//ios/chrome/browser/browsing_data/model", "//ios/chrome/browser/commerce/model/push_notification", + "//ios/chrome/browser/content_settings/model", "//ios/chrome/browser/crash_report/model", "//ios/chrome/browser/crash_report/model:model_internal", "//ios/chrome/browser/crash_report/model/breadcrumbs", @@ -575,6 +576,7 @@ "//ios/chrome/browser/shared/model/application_context", "//ios/chrome/browser/shared/model/browser_state", "//ios/chrome/browser/shared/model/paths", + "//ios/chrome/browser/shared/model/prefs:pref_names", "//ios/chrome/browser/shared/model/web_state_list", "//ios/chrome/browser/shared/public/commands", "//ios/chrome/browser/shared/public/features", @@ -609,6 +611,7 @@ "//ios/net", "//ios/public/provider/chrome/browser/app_distribution:app_distribution_api", "//ios/public/provider/chrome/browser/overrides:overrides_api", + "//ios/public/provider/chrome/browser/raccoon:raccoon_api", "//ios/public/provider/chrome/browser/signin:choice_api", "//ios/public/provider/chrome/browser/ui_utils:ui_utils_api", "//ios/public/provider/chrome/browser/user_feedback:user_feedback_api",
diff --git a/ios/chrome/app/main_controller.mm b/ios/chrome/app/main_controller.mm index b7b44a1d..4fb157e7 100644 --- a/ios/chrome/app/main_controller.mm +++ b/ios/chrome/app/main_controller.mm
@@ -23,6 +23,7 @@ #import "components/component_updater/installer_policies/optimization_hints_component_installer.h" #import "components/component_updater/installer_policies/safety_tips_component_installer.h" #import "components/component_updater/url_param_filter_remover.h" +#import "components/content_settings/core/browser/host_content_settings_map.h" #import "components/enterprise/idle/idle_features.h" #import "components/feature_engagement/public/event_constants.h" #import "components/feature_engagement/public/tracker.h" @@ -67,6 +68,7 @@ #import "ios/chrome/browser/browsing_data/model/browsing_data_remover.h" #import "ios/chrome/browser/browsing_data/model/browsing_data_remover_factory.h" #import "ios/chrome/browser/browsing_data/model/sessions_storage_util.h" +#import "ios/chrome/browser/content_settings/model/host_content_settings_map_factory.h" #import "ios/chrome/browser/crash_report/model/crash_helper.h" #import "ios/chrome/browser/crash_report/model/crash_keys_helper.h" #import "ios/chrome/browser/crash_report/model/crash_loop_detection_util.h" @@ -109,6 +111,7 @@ #import "ios/chrome/browser/shared/model/browser_state/chrome_browser_state.h" #import "ios/chrome/browser/shared/model/browser_state/chrome_browser_state_manager.h" #import "ios/chrome/browser/shared/model/paths/paths.h" +#import "ios/chrome/browser/shared/model/prefs/pref_names.h" #import "ios/chrome/browser/shared/model/web_state_list/web_state_list.h" #import "ios/chrome/browser/shared/public/commands/browser_coordinator_commands.h" #import "ios/chrome/browser/shared/public/commands/command_dispatcher.h" @@ -136,6 +139,7 @@ #import "ios/net/empty_nsurlcache.h" #import "ios/public/provider/chrome/browser/app_distribution/app_distribution_api.h" #import "ios/public/provider/chrome/browser/overrides/overrides_api.h" +#import "ios/public/provider/chrome/browser/raccoon/raccoon_api.h" #import "ios/public/provider/chrome/browser/ui_utils/ui_utils_api.h" #import "ios/public/provider/chrome/browser/user_feedback/user_feedback_api.h" #import "ios/web/public/webui/web_ui_ios_controller_factory.h" @@ -701,6 +705,17 @@ browserState, std::make_unique<MainControllerAuthenticationServiceDelegate>( browserState, self)); + + // Force desktop mode when raccoon is enabled. + if (ios::provider::IsRaccoonEnabled()) { + if (!browserState->GetPrefs()->GetBoolean(prefs::kUserAgentWasChanged)) { + HostContentSettingsMap* settingsMap = + ios::HostContentSettingsMapFactory::GetForBrowserState(browserState); + settingsMap->SetDefaultContentSetting( + ContentSettingsType::REQUEST_DESKTOP_SITE, CONTENT_SETTING_ALLOW); + browserState->GetPrefs()->SetBoolean(prefs::kUserAgentWasChanged, true); + } + } } #pragma mark - AppStateObserver
diff --git a/ios/chrome/browser/bookmarks/model/bookmark_client_impl.cc b/ios/chrome/browser/bookmarks/model/bookmark_client_impl.cc index 9eb8d6d..30fae9c 100644 --- a/ios/chrome/browser/bookmarks/model/bookmark_client_impl.cc +++ b/ios/chrome/browser/bookmarks/model/bookmark_client_impl.cc
@@ -21,8 +21,10 @@ #include "components/sync_bookmarks/bookmark_model_view.h" #include "components/sync_bookmarks/bookmark_sync_service.h" #include "components/undo/bookmark_undo_service.h" +#include "ios/chrome/browser/bookmarks/model/bookmarks_utils.h" #include "ios/chrome/browser/favicon/model/favicon_service_factory.h" #include "ios/chrome/browser/history/model/history_service_factory.h" +#include "ios/chrome/browser/shared/model/browser_state/chrome_browser_state.h" BookmarkClientImpl::BookmarkClientImpl( ChromeBrowserState* browser_state, @@ -47,6 +49,26 @@ model_ = model; } +void BookmarkClientImpl::RequiredRecoveryToLoad( + const std::multimap<int64_t, int64_t>& + local_or_syncable_reassigned_ids_per_old_id) { + if (!account_bookmark_sync_service_) { + // `account_bookmark_sync_service_` being null means `this` does NOT deal + // with two BookmarkSyncService instances. This implies there must be two + // BookmarkClientImpl instances (one per BookmarkSyncService) and therefore + // two BookmarkModel instances too. Do nothing in that case, as the + // migration in this function is primarily about the case where this client + // transitioned from having two BookmarkModel instances to having one. + return; + } + + if (browser_state_->GetPrefs()) { + MigrateLastUsedBookmarkFolderUponLocalIdsReassigned( + browser_state_->GetPrefs(), + local_or_syncable_reassigned_ids_per_old_id); + } +} + base::CancelableTaskTracker::TaskId BookmarkClientImpl::GetFaviconImageForPageURL( const GURL& page_url,
diff --git a/ios/chrome/browser/bookmarks/model/bookmark_client_impl.h b/ios/chrome/browser/bookmarks/model/bookmark_client_impl.h index d62208aee..6303dba 100644 --- a/ios/chrome/browser/bookmarks/model/bookmark_client_impl.h +++ b/ios/chrome/browser/bookmarks/model/bookmark_client_impl.h
@@ -43,6 +43,9 @@ // bookmarks::BookmarkClient: void Init(bookmarks::BookmarkModel* model) override; + void RequiredRecoveryToLoad( + const std::multimap<int64_t, int64_t>& + local_or_syncable_reassigned_ids_per_old_id) override; base::CancelableTaskTracker::TaskId GetFaviconImageForPageURL( const GURL& page_url, favicon_base::FaviconImageCallback callback,
diff --git a/ios/chrome/browser/bookmarks/model/bookmarks_utils.cc b/ios/chrome/browser/bookmarks/model/bookmarks_utils.cc index fae6d53..2c47cc5 100644 --- a/ios/chrome/browser/bookmarks/model/bookmarks_utils.cc +++ b/ios/chrome/browser/bookmarks/model/bookmarks_utils.cc
@@ -63,6 +63,21 @@ LegacyBookmarkModel* model) { DCHECK(model->loaded()); std::vector<const BookmarkNode*> nodes; + + // When dealing with account bookmarks, it is possible that they don't + // actually exist (e.g. the user is signed out). It is guaranteed that all + // exist or none. + if (!model->mobile_node()) { + // Account bookmarks do not exist, no need to return them. + DCHECK(!model->bookmark_bar_node()); + DCHECK(!model->other_node()); + return nodes; + } + + // Account bookmarks do exist (all three). Return them. + DCHECK(model->bookmark_bar_node()); + DCHECK(model->other_node()); + nodes.push_back(model->mobile_node()); nodes.push_back(model->bookmark_bar_node()); nodes.push_back(model->other_node()); @@ -118,10 +133,51 @@ } // Either preferences is not set, or refers to a non-existing folder. - BookmarkModelType type = (is_account_bookmark_model_available) + BookmarkModelType type = (is_account_bookmark_model_available && + account_bookmark_model->mobile_node() != nullptr) ? BookmarkModelType::kAccount : BookmarkModelType::kLocalOrSyncable; LegacyBookmarkModel* bookmark_model = GetBookmarkModelForType( type, local_or_syncable_bookmark_model, account_bookmark_model); return bookmark_model->mobile_node(); } + +void MigrateLastUsedBookmarkFolderUponLocalIdsReassigned( + PrefService* prefs, + const std::multimap<int64_t, int64_t>& + local_or_syncable_reassigned_ids_per_old_id) { + const int64_t node_id_in_prefs = + prefs->GetInt64(prefs::kIosBookmarkLastUsedFolderReceivingBookmarks); + + if (node_id_in_prefs == kLastUsedBookmarkFolderNone) { + return; + } + + const BookmarkModelType type = static_cast<BookmarkModelType>( + prefs->GetInteger(prefs::kIosBookmarkLastUsedStorageReceivingBookmarks)); + if (type != BookmarkModelType::kLocalOrSyncable) { + // Account bookmarks don't get their IDs reassigned as a result of the + // migration covered here (the adoption of a single BookmarkModel on iOS, + // whereas previously this client may have used two of them). + return; + } + + const size_t match_count = + local_or_syncable_reassigned_ids_per_old_id.count(node_id_in_prefs); + if (match_count == 0) { + // ID not reassigned; nothing to do. + return; + } + + if (match_count != 1) { + // ID reassignment ambiguous: this should be very rare and hence not + // supported. + return; + } + + const int64_t new_node_id = + local_or_syncable_reassigned_ids_per_old_id.find(node_id_in_prefs) + ->second; + prefs->SetInt64(prefs::kIosBookmarkLastUsedFolderReceivingBookmarks, + new_node_id); +}
diff --git a/ios/chrome/browser/bookmarks/model/bookmarks_utils.h b/ios/chrome/browser/bookmarks/model/bookmarks_utils.h index 3a7cc6c..25d5d4f 100644 --- a/ios/chrome/browser/bookmarks/model/bookmarks_utils.h +++ b/ios/chrome/browser/bookmarks/model/bookmarks_utils.h
@@ -5,6 +5,7 @@ #ifndef IOS_CHROME_BROWSER_BOOKMARKS_MODEL_BOOKMARKS_UTILS_H_ #define IOS_CHROME_BROWSER_BOOKMARKS_MODEL_BOOKMARKS_UTILS_H_ +#include <map> #include <set> #include <vector> @@ -68,4 +69,11 @@ LegacyBookmarkModel* profile_bookmark_model, LegacyBookmarkModel* account_bookmark_model); +// Used when on-disk bookmark IDs have been reassigned and therefore the prefs +// need to be migrated accordingly. +void MigrateLastUsedBookmarkFolderUponLocalIdsReassigned( + PrefService* prefs, + const std::multimap<int64_t, int64_t>& + local_or_syncable_reassigned_ids_per_old_id); + #endif // IOS_CHROME_BROWSER_BOOKMARKS_MODEL_BOOKMARKS_UTILS_H_
diff --git a/ios/chrome/browser/bookmarks/model/legacy_bookmark_model_with_shared_underlying_model.cc b/ios/chrome/browser/bookmarks/model/legacy_bookmark_model_with_shared_underlying_model.cc index 5e6efd2..a949786 100644 --- a/ios/chrome/browser/bookmarks/model/legacy_bookmark_model_with_shared_underlying_model.cc +++ b/ios/chrome/browser/bookmarks/model/legacy_bookmark_model_with_shared_underlying_model.cc
@@ -283,12 +283,7 @@ const bookmarks::BookmarkNode* parent, size_t index, bool added_by_user) { - if (parent->is_root()) { - // Account permanent folders were just created. - // TODO(crbug.com/326185948): Figure out a way to notify observers. - return; - } - if (IsNodeExcludedFromView(parent)) { + if (!parent->is_root() && IsNodeExcludedFromView(parent)) { return; } for (bookmarks::BookmarkModelObserver& observer : observers_) { @@ -300,7 +295,7 @@ const bookmarks::BookmarkNode* parent, size_t old_index, const bookmarks::BookmarkNode* node) { - if (IsNodeExcludedFromView(node)) { + if (!parent->is_root() && IsNodeExcludedFromView(parent)) { return; } for (bookmarks::BookmarkModelObserver& observer : observers_) { @@ -313,12 +308,7 @@ size_t old_index, const bookmarks::BookmarkNode* node, const std::set<GURL>& no_longer_bookmarked) { - if (parent->is_root()) { - // Account permanent folders were just removed. - // TODO(crbug.com/326185948): Figure out a way to notify observers. - return; - } - if (IsNodeExcludedFromView(parent)) { + if (!parent->is_root() && IsNodeExcludedFromView(parent)) { return; } // It isn't possible to compute `no_longer_bookmarked` so the workaround here
diff --git a/ios/chrome/browser/bookmarks/model/legacy_bookmark_model_with_shared_underlying_model.h b/ios/chrome/browser/bookmarks/model/legacy_bookmark_model_with_shared_underlying_model.h index 16418f3..b8d41b7 100644 --- a/ios/chrome/browser/bookmarks/model/legacy_bookmark_model_with_shared_underlying_model.h +++ b/ios/chrome/browser/bookmarks/model/legacy_bookmark_model_with_shared_underlying_model.h
@@ -132,6 +132,11 @@ const raw_ptr<const bookmarks::BookmarkNode> managed_node_; }; + // Predicate that determines whether a specific node is relevant or visible + // in the context of this view. For example, if `this` is exposing account + // bookmarks, then this predicate will exclude local-or-syncable nodes, + // including permanent folders themselves. It always returns false for the + // root node. NodeExcludedFromViewPredicate GetNodeExcludedFromViewPredicate() const; bool IsNodeExcludedFromView(const bookmarks::BookmarkNode* node) const;
diff --git a/ios/chrome/browser/safe_browsing/model/safe_browsing_blocking_page_unittest.mm b/ios/chrome/browser/safe_browsing/model/safe_browsing_blocking_page_unittest.mm index af93017..768840c 100644 --- a/ios/chrome/browser/safe_browsing/model/safe_browsing_blocking_page_unittest.mm +++ b/ios/chrome/browser/safe_browsing/model/safe_browsing_blocking_page_unittest.mm
@@ -36,7 +36,8 @@ UnsafeResource CreateResource(web::WebState* web_state, const GURL& url) { UnsafeResource resource; resource.url = url; - resource.threat_type = safe_browsing::SB_THREAT_TYPE_URL_MALWARE; + resource.threat_type = + safe_browsing::SBThreatType::SB_THREAT_TYPE_URL_MALWARE; resource.weak_web_state = web_state->GetWeakPtr(); resource.threat_source = safe_browsing::ThreatSource::LOCAL_PVER4; return resource;
diff --git a/ios/chrome/browser/shared/coordinator/scene/scene_controller.mm b/ios/chrome/browser/shared/coordinator/scene/scene_controller.mm index b69ee3d..9575af8 100644 --- a/ios/chrome/browser/shared/coordinator/scene/scene_controller.mm +++ b/ios/chrome/browser/shared/coordinator/scene/scene_controller.mm
@@ -2042,6 +2042,19 @@ } } +- (void)prepareToPresentModal:(ProceduralBlock)completion { + if (self.mainCoordinator.isTabGridActive || + (self.currentInterface.incognito && ![self isIncognitoForced])) { + __weak __typeof(self) weakSelf = self; + [self closePresentedViews:YES + completion:^{ + [weakSelf openNonIncognitoTab:completion]; + }]; + return; + } + [self dismissModalDialogsWithCompletion:completion]; +} + // Returns YES if the current Tab is available to present a view controller. - (BOOL)isTabAvailableToPresentViewController { if (self.signinCoordinator) { @@ -3644,6 +3657,39 @@ } } +// Open a non-incognito tab, if one exists. If one doesn't exist, open a new +// one. If incognito is forced, an incognito tab will be opened. +- (void)openNonIncognitoTab:(ProceduralBlock)completion { + if (self.mainInterface.browser->GetWebStateList()->GetActiveWebState()) { + // Reuse an existing tab, if one exists. + ApplicationMode mode = [self isIncognitoForced] ? ApplicationMode::INCOGNITO + : ApplicationMode::NORMAL; + [self setCurrentInterfaceForMode:mode]; + if (self.mainCoordinator.isTabGridActive) { + [self.mainCoordinator + showTabViewController:self.currentInterface.viewController + incognito:self.currentInterface.incognito + completion:completion]; + [self setIncognitoContentVisible:self.currentInterface.incognito]; + } else { + if (completion) { + completion(); + } + } + } else { + // Open a new NTP. + UrlLoadParams params = UrlLoadParams::InNewTab(GURL(kChromeUINewTabURL)); + params.web_params.transition_type = ui::PAGE_TRANSITION_TYPED; + ApplicationModeForTabOpening mode = + [self isIncognitoForced] ? ApplicationModeForTabOpening::INCOGNITO + : ApplicationModeForTabOpening::NORMAL; + [self dismissModalsAndMaybeOpenSelectedTabInMode:mode + withUrlLoadParams:params + dismissOmnibox:YES + completion:completion]; + } +} + #pragma mark - IncognitoInterstitialCoordinatorDelegate - (void)shouldStopIncognitoInterstitial:
diff --git a/ios/chrome/browser/shared/model/prefs/browser_prefs.mm b/ios/chrome/browser/shared/model/prefs/browser_prefs.mm index c61d036..2fcb293b 100644 --- a/ios/chrome/browser/shared/model/prefs/browser_prefs.mm +++ b/ios/chrome/browser/shared/model/prefs/browser_prefs.mm
@@ -763,6 +763,8 @@ // to the top Most Visited Sites. registry->RegisterListPref(prefs::kIosLatestMostVisitedSites, PrefRegistry::LOSSY_PREF); + + registry->RegisterBooleanPref(prefs::kUserAgentWasChanged, false); } // This method should be periodically pruned of year+ old migrations.
diff --git a/ios/chrome/browser/shared/model/prefs/pref_names.h b/ios/chrome/browser/shared/model/prefs/pref_names.h index ca78c907..2885f8b1 100644 --- a/ios/chrome/browser/shared/model/prefs/pref_names.h +++ b/ios/chrome/browser/shared/model/prefs/pref_names.h
@@ -573,6 +573,10 @@ inline constexpr char kInsecureFormWarningsEnabled[] = "ios.insecure_form_warnings_enabled"; +// TODO(crbug.com/329381234) Remove once we have a better solution. +// This value is true if the default user agent was changed. To be used +// only when raccoon is enabled. +inline constexpr char kUserAgentWasChanged[] = "UserAgentWasChanged"; } // namespace prefs #endif // IOS_CHROME_BROWSER_PREFS_PREF_NAMES_H_
diff --git a/ios/chrome/browser/shared/public/commands/application_commands.h b/ios/chrome/browser/shared/public/commands/application_commands.h index ae73795..146c728a 100644 --- a/ios/chrome/browser/shared/public/commands/application_commands.h +++ b/ios/chrome/browser/shared/public/commands/application_commands.h
@@ -147,6 +147,10 @@ // Open a new window with `userActivity` - (void)openNewWindowWithActivity:(NSUserActivity*)userActivity; +// Closes all open modals and ensures that a non-incognito tab is open. If +// incognito is forced, then it will ensure an incognito tab is open. +- (void)prepareToPresentModal:(ProceduralBlock)completion; + @end #endif // IOS_CHROME_BROWSER_SHARED_PUBLIC_COMMANDS_APPLICATION_COMMANDS_H_
diff --git a/ios/chrome/browser/shared/public/features/features.mm b/ios/chrome/browser/shared/public/features/features.mm index 29303ce66..cdee2c73 100644 --- a/ios/chrome/browser/shared/public/features/features.mm +++ b/ios/chrome/browser/shared/public/features/features.mm
@@ -201,7 +201,7 @@ BASE_FEATURE(kSpotlightDonateNewIntents, "SpotlightDonateNewIntents", - base::FEATURE_DISABLED_BY_DEFAULT); + base::FEATURE_ENABLED_BY_DEFAULT); BASE_FEATURE(kConsistencyNewAccountInterface, "ConsistencyNewAccountInterface",
diff --git a/ios/chrome/browser/tips_notifications/model/tips_notification_client.mm b/ios/chrome/browser/tips_notifications/model/tips_notification_client.mm index 9eaefa7..8339495 100644 --- a/ios/chrome/browser/tips_notifications/model/tips_notification_client.mm +++ b/ios/chrome/browser/tips_notifications/model/tips_notification_client.mm
@@ -309,7 +309,7 @@ Browser* browser = GetSceneLevelForegroundActiveBrowser(); id<ApplicationCommands> application_handler = HandlerForProtocol(browser->GetCommandDispatcher(), ApplicationCommands); - [application_handler dismissModalDialogsWithCompletion:^{ + [application_handler prepareToPresentModal:^{ id<SettingsCommands> settings_handler = HandlerForProtocol(browser->GetCommandDispatcher(), SettingsCommands); [settings_handler @@ -325,7 +325,7 @@ Browser* browser = GetSceneLevelForegroundActiveBrowser(); id<ApplicationCommands> application_handler = HandlerForProtocol(browser->GetCommandDispatcher(), ApplicationCommands); - [application_handler dismissModalDialogsWithCompletion:^{ + [application_handler prepareToPresentModal:^{ [HandlerForProtocol(browser->GetCommandDispatcher(), BrowserCoordinatorCommands) showWhatsNew]; }]; @@ -356,7 +356,7 @@ id<ApplicationCommands> application_handler = HandlerForProtocol(browser->GetCommandDispatcher(), ApplicationCommands); - [application_handler dismissModalDialogsWithCompletion:^{ + [application_handler prepareToPresentModal:^{ [HandlerForProtocol(browser->GetCommandDispatcher(), SigninPresenter) showSignin:command]; }];
diff --git a/ios/chrome/browser/tips_notifications/model/tips_notification_client_unittest.mm b/ios/chrome/browser/tips_notifications/model/tips_notification_client_unittest.mm index 2aa395e..81d129ae 100644 --- a/ios/chrome/browser/tips_notifications/model/tips_notification_client_unittest.mm +++ b/ios/chrome/browser/tips_notifications/model/tips_notification_client_unittest.mm
@@ -128,15 +128,15 @@ kTipsNotificationsSentPref, 0); } - // Stubs the `dismissModalDialogsWithCompletion:` method from - // `ApplicationCommands` so that it immediately calls the completion block. - void StubDismissModalDialogs() { + // Stubs the `prepareToPresentModal:` method from `ApplicationCommands` so + // that it immediately calls the completion block. + void StubPrepareToPresentModal() { mock_application_handler_ = OCMProtocolMock(@protocol(ApplicationCommands)); [[[mock_application_handler_ stub] andDo:^(NSInvocation* invocation) { void (^block)(); [invocation getArgument:&block atIndex:2]; block(); - }] dismissModalDialogsWithCompletion:[OCMArg any]]; + }] prepareToPresentModal:[OCMArg any]]; [browser_->GetCommandDispatcher() startDispatchingToTarget:mock_application_handler_ forProtocol:@protocol(ApplicationCommands)]; @@ -205,7 +205,7 @@ // Tests that the client handles a Default Browser notification response. TEST_F(TipsNotificationClientTest, DefaultBrowserHandle) { - StubDismissModalDialogs(); + StubPrepareToPresentModal(); id mock_handler = OCMProtocolMock(@protocol(SettingsCommands)); OCMExpect([mock_handler showDefaultBrowserSettingsFromViewController:nil @@ -240,7 +240,7 @@ // Tests that the client handles a Whats New notification response. TEST_F(TipsNotificationClientTest, WhatsNewHandle) { - StubDismissModalDialogs(); + StubPrepareToPresentModal(); id mock_handler = OCMProtocolMock(@protocol(BrowserCoordinatorCommands)); OCMExpect([mock_handler showWhatsNew]); [browser_->GetCommandDispatcher()
diff --git a/ios/chrome/browser/ui/autofill/form_input_accessory/form_input_accessory_view_controller.mm b/ios/chrome/browser/ui/autofill/form_input_accessory/form_input_accessory_view_controller.mm index c37dc36..0655308 100644 --- a/ios/chrome/browser/ui/autofill/form_input_accessory/form_input_accessory_view_controller.mm +++ b/ios/chrome/browser/ui/autofill/form_input_accessory/form_input_accessory_view_controller.mm
@@ -294,6 +294,8 @@ forDataType:(manual_fill::ManualFillDataType)dataType { DCHECK(IsKeyboardAccessoryUpgradeEnabled()); + self.formInputAccessoryView.hidden = YES; + [_formInputAccessoryViewControllerDelegate formInputAccessoryViewController:self didPressManualFillButton:button @@ -302,6 +304,8 @@ // Resets this view to its original state. Can be animated. - (void)resetAnimated:(BOOL)animated { + self.formInputAccessoryView.hidden = NO; + [self.formSuggestionView resetContentInsetAndDelegateAnimated:animated]; [self.manualFillAccessoryViewController resetAnimated:animated]; self.brandingViewController.keyboardAccessoryVisible =
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/expanded_manual_fill_coordinator.h b/ios/chrome/browser/ui/autofill/manual_fill/expanded_manual_fill_coordinator.h index aaa31f2..f24f952 100644 --- a/ios/chrome/browser/ui/autofill/manual_fill/expanded_manual_fill_coordinator.h +++ b/ios/chrome/browser/ui/autofill/manual_fill/expanded_manual_fill_coordinator.h
@@ -20,6 +20,8 @@ @class ManualFillInjectionHandler; @class ExpandedManualFillCoordinator; +@protocol PasswordCoordinatorDelegate; + // Delegate for the ExpandedManualFillCoordinator. @protocol ExpandedManualFillCoordinatorDelegate @@ -48,8 +50,10 @@ // instantiate the ManualFillPasswordCoordinator. @property(nonatomic, assign) std::string frameID; -// The delegate to communicate with the parent coordinator. -@property(nonatomic, weak) id<ExpandedManualFillCoordinatorDelegate> delegate; +// The delegate to communicate with the FormInputAccessoryCoordinator. +@property(nonatomic, weak) + id<ExpandedManualFillCoordinatorDelegate, PasswordCoordinatorDelegate> + delegate; // Designated initializer. `dataType` represents the type of manual filling // options to show in the expanded manual fill view.
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/expanded_manual_fill_coordinator.mm b/ios/chrome/browser/ui/autofill/manual_fill/expanded_manual_fill_coordinator.mm index 14715a5..fa8d96a 100644 --- a/ios/chrome/browser/ui/autofill/manual_fill/expanded_manual_fill_coordinator.mm +++ b/ios/chrome/browser/ui/autofill/manual_fill/expanded_manual_fill_coordinator.mm
@@ -20,8 +20,7 @@ @interface ExpandedManualFillCoordinator () < ExpandedManualFillViewControllerDelegate, AddressCoordinatorDelegate, - CardCoordinatorDelegate, - PasswordCoordinatorDelegate> + CardCoordinatorDelegate> // Main view controller for this coordinator. @property(nonatomic, strong) @@ -84,24 +83,6 @@ // now. } -#pragma mark - PasswordCoordinatorDelegate - -- (void)openPasswordManager { - // TODO(b/40942168): Implement logic. -} - -- (void)openPasswordSettings { - // TODO(b/40942168): Implement logic. -} - -- (void)openAllPasswordsPicker { - // TODO(b/40942168): Implement logic. -} - -- (void)openPasswordSuggestion { - // TODO(b/40942168): Implement logic. -} - #pragma mark - CardCoordinatorDelegate - (void)openCardSettings { @@ -160,7 +141,7 @@ invokedOnObfuscatedField:self.invokedOnObfuscatedField formID:self.formID frameID:self.frameID]; - passwordCoordinator.delegate = self; + passwordCoordinator.delegate = self.delegate; self.expandedManualFillViewController.childViewController = passwordCoordinator.viewController;
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/password_view_controller_egtest.mm b/ios/chrome/browser/ui/autofill/manual_fill/password_view_controller_egtest.mm index df74418..0dc85ed 100644 --- a/ios/chrome/browser/ui/autofill/manual_fill/password_view_controller_egtest.mm +++ b/ios/chrome/browser/ui/autofill/manual_fill/password_view_controller_egtest.mm
@@ -171,6 +171,15 @@ assertWithMatcher:grey_sufficientlyVisible()]; } +// Verifies that the keyboard is up and not covered by the password manual fill +// view. +void CheckKeyboardIsUpAndNotCovered() { + GREYAssertTrue([EarlGrey isKeyboardShownWithError:nil], + @"Keyboard should be shown"); + [[EarlGrey selectElementWithMatcher:ManualFallbackPasswordTableViewMatcher()] + assertWithMatcher:grey_notVisible()]; +} + } // namespace // Integration Tests for Mannual Fallback Passwords View Controller. @@ -250,13 +259,6 @@ // Opens the "Other Passwords" screen. - (void)openOtherPasswords { - // TODO(crbug.com/326405006): Adapt test once the "Select Password..." action - // works with the Keyboard Accessory Upgrade feature. - if ([AutofillAppInterface isKeyboardAccessoryUpgradeEnabled]) { - EARL_GREY_TEST_SKIPPED(@"The Select Password... action does not yet work " - @"with the Keyboard Accessory Upgrade feature."); - } - // Bring up the keyboard. [[EarlGrey selectElementWithMatcher:chrome_test_util::WebViewMatcher()] performAction:TapWebElementWithId(kFormElementUsername)]; @@ -319,13 +321,6 @@ // Tests that the "Manage Passwords..." action works. - (void)testManagePasswordsActionOpensPasswordManager { - // TODO(crbug.com/326405046): Adapt test once the "Manage Passwords..." action - // works with the Keyboard Accessory Upgrade feature. - if ([AutofillAppInterface isKeyboardAccessoryUpgradeEnabled]) { - EARL_GREY_TEST_SKIPPED(@"The Manage Passwords... action does not yet work " - @"with the Keyboard Accessory Upgrade feature."); - } - // Bring up the keyboard. [[EarlGrey selectElementWithMatcher:chrome_test_util::WebViewMatcher()] performAction:TapWebElementWithId(kFormElementUsername)]; @@ -337,7 +332,7 @@ [[EarlGrey selectElementWithMatcher:ManualFallbackManagePasswordsMatcher()] performAction:grey_tap()]; - // Verify the password settings opened. + // Verify that the Password Manager opened. // Changed minimum visible percentage to 70% for Passwords table view in // settings because subviews cover > 25% in smaller screens(eg. iPhone 6s). [[EarlGrey @@ -348,26 +343,15 @@ // Tests that the Password Manager is dismissed when local authentication fails // after tapping "Manage Passwords...". - (void)testManagePasswordsActionWithFailedAuthDismissesPasswordManager { - // TODO(crbug.com/326405046): Adapt test once the "Manage Passwords..." action - // works with the Keyboard Accessory Upgrade feature. - if ([AutofillAppInterface isKeyboardAccessoryUpgradeEnabled]) { - EARL_GREY_TEST_SKIPPED(@"The Manage Passwords... action does not yet work " - @"with the Keyboard Accessory Upgrade feature."); - } - CheckPasswordManagerUIDismissesAfterFailedAuthentication( ManualFallbackManagePasswordsMatcher()); + + // The keyboard should be visible. + CheckKeyboardIsUpAndNotCovered(); } // Tests that the "Manage Settings..." action works. - (void)testManageSettingsActionOpensPasswordSettings { - // TODO(crbug.com/326405262): Adapt test once the "Manage Settings..." action - // works with the Keyboard Accessory Upgrade feature. - if ([AutofillAppInterface isKeyboardAccessoryUpgradeEnabled]) { - EARL_GREY_TEST_SKIPPED(@"The Manage Settings... action does not yet work " - @"with the Keyboard Accessory Upgrade feature."); - } - // Bring up the keyboard. [[EarlGrey selectElementWithMatcher:chrome_test_util::WebViewMatcher()] performAction:TapWebElementWithId(kFormElementUsername)]; @@ -389,26 +373,15 @@ // Tests that Password Settings is dismissed when local authentication fails // after tapping "Manage Settings...". - (void)testManageSettingsActionWithFailedAuthDismissesPasswordSettings { - // TODO(crbug.com/326405262): Adapt test once the "Manage Settings..." action - // works with the Keyboard Accessory Upgrade feature. - if ([AutofillAppInterface isKeyboardAccessoryUpgradeEnabled]) { - EARL_GREY_TEST_SKIPPED(@"The Manage Settings... action does not yet work " - @"with the Keyboard Accessory Upgrade feature."); - } - CheckPasswordManagerUIDismissesAfterFailedAuthentication( ManualFallbackManageSettingsMatcher()); + + // The keyboard should be visible. + CheckKeyboardIsUpAndNotCovered(); } // Tests that the "Manage Passwords..." action works in incognito mode. - (void)testManagePasswordsActionOpensPasswordSettingsInIncognito { - // TODO(crbug.com/326405046): Adapt test once the "Manage Passwords..." action - // works with the Keyboard Accessory Upgrade feature. - if ([AutofillAppInterface isKeyboardAccessoryUpgradeEnabled]) { - EARL_GREY_TEST_SKIPPED(@"The Manage Passwords... action does not yet work " - @"with the Keyboard Accessory Upgrade feature."); - } - // Open a tab in incognito. [ChromeEarlGrey openNewIncognitoTab]; [self loadLoginPage]; @@ -424,7 +397,7 @@ [[EarlGrey selectElementWithMatcher:ManualFallbackManagePasswordsMatcher()] performAction:grey_tap()]; - // Verify the password settings opened. + // Verify that the Password Manager opened. // Changed minimum visible percentage to 70% for Passwords table view in // settings because subviews cover > 25% in smaller screens(eg. iPhone 6s). [[EarlGrey @@ -434,13 +407,6 @@ // Tests that the "Manage Settings..." action works in incognito mode. - (void)testManageSettingsActionOpensPasswordSettingsInIncognito { - // TODO(crbug.com/326405262): Adapt test once the "Manage Settings..." action - // works with the Keyboard Accessory Upgrade feature. - if ([AutofillAppInterface isKeyboardAccessoryUpgradeEnabled]) { - EARL_GREY_TEST_SKIPPED(@"The Manage Settings... action does not yet work " - @"with the Keyboard Accessory Upgrade feature."); - } - // Open a tab in incognito. [ChromeEarlGrey openNewIncognitoTab]; [self loadLoginPage]; @@ -465,13 +431,6 @@ // Tests that the "Select Password..." action works in incognito mode. - (void)testSelectPasswordActionInIncognito { - // TODO(crbug.com/326405006): Adapt test once the "Select Password..." action - // works with the Keyboard Accessory Upgrade feature. - if ([AutofillAppInterface isKeyboardAccessoryUpgradeEnabled]) { - EARL_GREY_TEST_SKIPPED(@"The Select Password... action does not yet work " - @"with the Keyboard Accessory Upgrade feature."); - } - // Open a tab in incognito. [ChromeEarlGrey openNewIncognitoTab]; [self loadLoginPage]; @@ -486,13 +445,6 @@ // Tests that returning from "Manage Settings..." leaves the keyboard and the // icons in the right state. - (void)testPasswordsStateAfterPresentingManageSettings { - // TODO(crbug.com/326405262): Adapt test once the "Manage Settings..." action - // works with the Keyboard Accessory Upgrade feature. - if ([AutofillAppInterface isKeyboardAccessoryUpgradeEnabled]) { - EARL_GREY_TEST_SKIPPED(@"The Manage Settings... action does not yet work " - @"with the Keyboard Accessory Upgrade feature."); - } - // Bring up the keyboard. [[EarlGrey selectElementWithMatcher:chrome_test_util::WebViewMatcher()] performAction:TapWebElementWithId(kFormElementUsername)]; @@ -500,9 +452,13 @@ // Open the password manual fill view. OpenPasswordManualFillView(/*has_suggestions=*/false); - // Verify the status of the icon. - [[EarlGrey selectElementWithMatcher:ManualFallbackPasswordIconMatcher()] - assertWithMatcher:grey_not(grey_userInteractionEnabled())]; + // Icons are not present when the Keyboard Accessory Upgrade feature is + // enabled. + if (![AutofillAppInterface isKeyboardAccessoryUpgradeEnabled]) { + // Verify the status of the icon. + [[EarlGrey selectElementWithMatcher:ManualFallbackPasswordIconMatcher()] + assertWithMatcher:grey_not(grey_userInteractionEnabled())]; + } // Tap the "Manage Passwords..." action. [[EarlGrey selectElementWithMatcher:ManualFallbackManageSettingsMatcher()] @@ -516,28 +472,24 @@ [[EarlGrey selectElementWithMatcher:NavigationBarDoneButton()] performAction:grey_tap()]; - // Verify the status of the icons. - [[EarlGrey selectElementWithMatcher:ManualFallbackPasswordIconMatcher()] - assertWithMatcher:grey_sufficientlyVisible()]; - [[EarlGrey selectElementWithMatcher:ManualFallbackPasswordIconMatcher()] - assertWithMatcher:grey_userInteractionEnabled()]; - [[EarlGrey selectElementWithMatcher:ManualFallbackKeyboardIconMatcher()] - assertWithMatcher:grey_not(grey_sufficientlyVisible())]; + // Icons are not present when the Keyboard Accessory Upgrade feature is + // enabled. + if (![AutofillAppInterface isKeyboardAccessoryUpgradeEnabled]) { + // Verify the status of the icons. + [[EarlGrey selectElementWithMatcher:ManualFallbackPasswordIconMatcher()] + assertWithMatcher:grey_sufficientlyVisible()]; + [[EarlGrey selectElementWithMatcher:ManualFallbackPasswordIconMatcher()] + assertWithMatcher:grey_userInteractionEnabled()]; + [[EarlGrey selectElementWithMatcher:ManualFallbackKeyboardIconMatcher()] + assertWithMatcher:grey_not(grey_sufficientlyVisible())]; + } - // Verify the keyboard is not cover by the password view. - [[EarlGrey selectElementWithMatcher:ManualFallbackPasswordTableViewMatcher()] - assertWithMatcher:grey_notVisible()]; + // Verify that the keyboard is not covered by the password view. + CheckKeyboardIsUpAndNotCovered(); } // Tests that the "Select Password..." action works. -- (void)testUseOtherPasswordActionOpens { - // TODO(crbug.com/326405006): Adapt test once the "Select Password..." action - // works with the Keyboard Accessory Upgrade feature. - if ([AutofillAppInterface isKeyboardAccessoryUpgradeEnabled]) { - EARL_GREY_TEST_SKIPPED(@"The Select Password... action does not yet work " - @"with the Keyboard Accessory Upgrade feature."); - } - +- (void)testSelectPasswordActionOpensOtherPasswordList { [self openOtherPasswords]; [[EarlGrey @@ -546,14 +498,7 @@ } // Tests that the "Select Password..." screen won't open if canceled. -- (void)testUseOtherPasswordActionCloses { - // TODO(crbug.com/326405006): Adapt test once the "Select Password..." action - // works with the Keyboard Accessory Upgrade feature. - if ([AutofillAppInterface isKeyboardAccessoryUpgradeEnabled]) { - EARL_GREY_TEST_SKIPPED(@"The Select Password... action does not yet work " - @"with the Keyboard Accessory Upgrade feature."); - } - +- (void)testCancellingSelectPasswordAction { // Bring up the keyboard. [[EarlGrey selectElementWithMatcher:chrome_test_util::WebViewMatcher()] performAction:TapWebElementWithId(kFormElementUsername)]; @@ -569,20 +514,14 @@ [[EarlGrey selectElementWithMatcher:CancelUsingOtherPasswordButton()] performAction:grey_tap()]; - // Verify the use other passwords not opened. + // Verify that the other password list is not opened. [[EarlGrey selectElementWithMatcher:ManualFallbackOtherPasswordsDismissMatcher()] assertWithMatcher:grey_nil()]; } -- (void)testCloseOtherPasswordsViaSwipeDown { - // TODO(crbug.com/326405006): Adapt test once the "Select Password..." action - // works with the Keyboard Accessory Upgrade feature. - if ([AutofillAppInterface isKeyboardAccessoryUpgradeEnabled]) { - EARL_GREY_TEST_SKIPPED(@"The Select Password... action does not yet work " - @"with the Keyboard Accessory Upgrade feature."); - } - +// Tests that the other password list can be dismissed with a swipe down. +- (void)testClosingOtherPasswordListViaSwipeDown { [self openOtherPasswords]; [[EarlGrey @@ -608,14 +547,7 @@ // Tests that the "Select Password..." UI is dismissed after failed local // authentication. -- (void)testUseOtherPasswordUIDismissedAfterFailedAuth { - // TODO(crbug.com/326405006): Adapt test once the "Select Password..." action - // works with the Keyboard Accessory Upgrade feature. - if ([AutofillAppInterface isKeyboardAccessoryUpgradeEnabled]) { - EARL_GREY_TEST_SKIPPED(@"The Select Password... action does not yet work " - @"with the Keyboard Accessory Upgrade feature."); - } - +- (void)testOtherPasswordListUIDismissedAfterFailedAuth { // Setup failed authentication. [PasswordSettingsAppInterface mockReauthenticationModuleExpectedResult: ReauthenticationResult::kFailure]; @@ -643,18 +575,14 @@ [[EarlGrey selectElementWithMatcher:ManualFallbackOtherPasswordsDismissMatcher()] assertWithMatcher:grey_nil()]; + + // The keyboard should be visible. + CheckKeyboardIsUpAndNotCovered(); } // Tests that returning from "Select Password..." leaves the view and icons // in the right state. -- (void)testPasswordsStateAfterPresentingUseOtherPassword { - // TODO(crbug.com/326405006): Adapt test once the "Select Password..." action - // works with the Keyboard Accessory Upgrade feature. - if ([AutofillAppInterface isKeyboardAccessoryUpgradeEnabled]) { - EARL_GREY_TEST_SKIPPED(@"The Select Password... action does not yet work " - @"with the Keyboard Accessory Upgrade feature."); - } - +- (void)testPasswordsStateAfterPresentingOtherPasswordList { [self openOtherPasswords]; [[EarlGrey @@ -665,29 +593,25 @@ [[EarlGrey selectElementWithMatcher:NavigationBarDoneButton()] performAction:grey_tap()]; - // Verify the status of the icons. - [[EarlGrey selectElementWithMatcher:ManualFallbackPasswordIconMatcher()] - assertWithMatcher:grey_sufficientlyVisible()]; - [[EarlGrey selectElementWithMatcher:ManualFallbackPasswordIconMatcher()] - assertWithMatcher:grey_userInteractionEnabled()]; - [[EarlGrey selectElementWithMatcher:ManualFallbackKeyboardIconMatcher()] - assertWithMatcher:grey_not(grey_sufficientlyVisible())]; + // Icons are not present when the Keyboard Accessory Upgrade feature is + // enabled. + if (![AutofillAppInterface isKeyboardAccessoryUpgradeEnabled]) { + // Verify the status of the icons. + [[EarlGrey selectElementWithMatcher:ManualFallbackPasswordIconMatcher()] + assertWithMatcher:grey_sufficientlyVisible()]; + [[EarlGrey selectElementWithMatcher:ManualFallbackPasswordIconMatcher()] + assertWithMatcher:grey_userInteractionEnabled()]; + [[EarlGrey selectElementWithMatcher:ManualFallbackKeyboardIconMatcher()] + assertWithMatcher:grey_not(grey_sufficientlyVisible())]; + } - // Verify the keyboard is not cover by the password view. - [[EarlGrey selectElementWithMatcher:ManualFallbackPasswordTableViewMatcher()] - assertWithMatcher:grey_notVisible()]; + // Verify that the keyboard is not covered by the password view. + CheckKeyboardIsUpAndNotCovered(); } // Tests that the Password View Controller is still present after tapping the // search bar. - (void)testPasswordControllerWhileSearching { - // TODO(crbug.com/326405006): Adapt test once the "Select Password..." action - // works with the Keyboard Accessory Upgrade feature. - if ([AutofillAppInterface isKeyboardAccessoryUpgradeEnabled]) { - EARL_GREY_TEST_SKIPPED(@"The Select Password... action does not yet work " - @"with the Keyboard Accessory Upgrade feature."); - } - // Bring up the keyboard. [[EarlGrey selectElementWithMatcher:chrome_test_util::WebViewMatcher()] performAction:TapWebElementWithId(kFormElementUsername)]; @@ -703,8 +627,7 @@ [[EarlGrey selectElementWithMatcher:ConfirmUsingOtherPasswordButton()] performAction:grey_tap()]; - // Verify the use other passwords opened and that the saved password is - // visible. + // Verify that the all saved password list is visible. [[EarlGrey selectElementWithMatcher:ManualFallbackOtherPasswordsDismissMatcher()] assertWithMatcher:grey_sufficientlyVisible()]; @@ -937,13 +860,16 @@ } // Tests password generation on manual fallback. -// TODO(crbug.com/1394448): enable the test with fix. -- (void)DISABLED_testPasswordGenerationOnManualFallback { - // Disable the test on iOS 15.3 due to build failure. - // TODO(crbug.com/1304685): enable the test with fix. - if (@available(iOS 15.3, *)) { - EARL_GREY_TEST_DISABLED(@"Test disabled on iOS 15.3."); +- (void)testPasswordGenerationOnManualFallback { + // TODO(crbug.com/326265397): Enable test for Keyboard Accessory Upgrade + // feature once the keyboard accessory is hidden whenever the expanded manual + // fill view is shown. + if ([AutofillAppInterface isKeyboardAccessoryUpgradeEnabled]) { + EARL_GREY_TEST_SKIPPED( + @"The keyboard currently blocks the Suggest Strong Password sheet when " + @"the Keyboard Accessory Upgrade feature is enabled."); } + [SigninEarlGreyUI signinWithFakeIdentity:[FakeSystemIdentity fakeIdentity1]]; [ChromeEarlGrey waitForSyncEngineInitialized:YES syncTimeout:base::Seconds(10)];
diff --git a/ios/chrome/browser/ui/bookmarks/editor/bookmarks_editor_mediator.mm b/ios/chrome/browser/ui/bookmarks/editor/bookmarks_editor_mediator.mm index a283539..7d1b313 100644 --- a/ios/chrome/browser/ui/bookmarks/editor/bookmarks_editor_mediator.mm +++ b/ios/chrome/browser/ui/bookmarks/editor/bookmarks_editor_mediator.mm
@@ -207,7 +207,14 @@ // This might happen when the user has changed `self.folder` but has not // commited the changes by pressing done. And in the background the chosen // folder was deleted. - [self changeFolder:model->mobile_node()]; + if (model->mobile_node()) { + [self changeFolder:model->mobile_node()]; + } else { + // When dealing with account bookmarks, it is possible that permanent + // folders no longer exist (e.g. the user signed out). In this case, fall + // back to the local model. + [self changeFolder:_localOrSyncableBookmarkModel->mobile_node()]; + } } }
diff --git a/ios/chrome/browser/ui/bookmarks/folder_chooser/bookmarks_folder_chooser_view_controller.mm b/ios/chrome/browser/ui/bookmarks/folder_chooser/bookmarks_folder_chooser_view_controller.mm index 58dd70c5..4c472c5b 100644 --- a/ios/chrome/browser/ui/bookmarks/folder_chooser/bookmarks_folder_chooser_view_controller.mm +++ b/ios/chrome/browser/ui/bookmarks/folder_chooser/bookmarks_folder_chooser_view_controller.mm
@@ -149,7 +149,8 @@ // If `parent` (selected folder) is `nullptr`, set the root folder of // the corresponding section to be the parent folder. parentNode = - (sectionID == SectionIdentifierAccountBookmarks) + (sectionID == SectionIdentifierAccountBookmarks && + [_dataSource.accountDataSource mobileFolderNode] != nullptr) ? [_dataSource.accountDataSource mobileFolderNode] : [_dataSource.localOrSyncableDataSource mobileFolderNode]; }
diff --git a/ios/chrome/browser/ui/bookmarks/folder_editor/bookmarks_folder_editor_view_controller.mm b/ios/chrome/browser/ui/bookmarks/folder_editor/bookmarks_folder_editor_view_controller.mm index 21269a4e..227d58b 100644 --- a/ios/chrome/browser/ui/bookmarks/folder_editor/bookmarks_folder_editor_view_controller.mm +++ b/ios/chrome/browser/ui/bookmarks/folder_editor/bookmarks_folder_editor_view_controller.mm
@@ -437,7 +437,14 @@ // This might happen when the user has changed `_parentFolder` but has not // commited the changes by pressing done. And in the background the chosen // folder was deleted. - _parentFolder = model->mobile_node(); + if (model->mobile_node()) { + _parentFolder = model->mobile_node(); + } else { + // When dealing with account bookmarks, it is possible that permanent + // folders no longer exist (e.g. the user signed out). In this case, fall + // back to the local model. + _parentFolder = _localOrSyncableBookmarkModel->mobile_node(); + } [self updateParentFolderState]; } }
diff --git a/ios/chrome/browser/ui/bookmarks/home/bookmarks_home_mediator.mm b/ios/chrome/browser/ui/bookmarks/home/bookmarks_home_mediator.mm index 4fa73c29..8c805e5f 100644 --- a/ios/chrome/browser/ui/bookmarks/home/bookmarks_home_mediator.mm +++ b/ios/chrome/browser/ui/bookmarks/home/bookmarks_home_mediator.mm
@@ -521,6 +521,9 @@ #pragma mark - Properties - (LegacyBookmarkModel*)displayedBookmarkModel { + if (!self.displayedNode) { + return _localOrSyncableBookmarkModel.get(); + } return bookmark_utils_ios::GetBookmarkModelForNode( self.displayedNode, _localOrSyncableBookmarkModel.get(), _accountBookmarkModel.get());
diff --git a/ios/chrome/browser/ui/push_notification/notifications_opt_in_alert_coordinator.mm b/ios/chrome/browser/ui/push_notification/notifications_opt_in_alert_coordinator.mm index c6168b4..390de77 100644 --- a/ios/chrome/browser/ui/push_notification/notifications_opt_in_alert_coordinator.mm +++ b/ios/chrome/browser/ui/push_notification/notifications_opt_in_alert_coordinator.mm
@@ -16,6 +16,7 @@ #import "ios/chrome/browser/shared/model/browser_state/browser_state_info_cache.h" #import "ios/chrome/browser/shared/model/browser_state/chrome_browser_state.h" #import "ios/chrome/browser/shared/model/browser_state/chrome_browser_state_manager.h" +#import "ios/chrome/browser/shared/public/commands/application_commands.h" #import "ios/chrome/browser/shared/public/commands/command_dispatcher.h" #import "ios/chrome/browser/shared/public/commands/settings_commands.h" #import "ios/chrome/browser/shared/public/commands/snackbar_commands.h" @@ -140,16 +141,23 @@ NSString* buttonText = l10n_util::GetNSString(IDS_IOS_NOTIFICATIONS_MANAGE_SETTINGS); // Show snackbar confirmation. - id<SnackbarCommands> snackbarHandler = HandlerForProtocol( - self.browser->GetCommandDispatcher(), SnackbarCommands); - __weak id<SettingsCommands> weakSettingsHandler = HandlerForProtocol( - self.browser->GetCommandDispatcher(), SettingsCommands); - [snackbarHandler showSnackbarWithMessage:self.confirmationMessage - buttonText:buttonText - messageAction:^{ - [weakSettingsHandler showNotificationsSettings]; - } - completionAction:nil]; + + CommandDispatcher* dispatcher = self.browser->GetCommandDispatcher(); + id<SnackbarCommands> snackbarHandler = + HandlerForProtocol(dispatcher, SnackbarCommands); + __weak id<SettingsCommands> weakSettingsHandler = + HandlerForProtocol(dispatcher, SettingsCommands); + __weak id<ApplicationCommands> weakApplicationHandler = + HandlerForProtocol(dispatcher, ApplicationCommands); + [snackbarHandler + showSnackbarWithMessage:self.confirmationMessage + buttonText:buttonText + messageAction:^{ + [weakApplicationHandler prepareToPresentModal:^{ + [weakSettingsHandler showNotificationsSettings]; + }]; + } + completionAction:nil]; } // Opens the iOS settings app to the app's Notification permissions.
diff --git a/ios/chrome/browser/ui/search_engine_choice/snippet_search_engine_button.mm b/ios/chrome/browser/ui/search_engine_choice/snippet_search_engine_button.mm index de82f79..78b539d6 100644 --- a/ios/chrome/browser/ui/search_engine_choice/snippet_search_engine_button.mm +++ b/ios/chrome/browser/ui/search_engine_choice/snippet_search_engine_button.mm
@@ -396,7 +396,7 @@ switch (newSnippetButtonState) { case SnippetButtonState::kOneLine: chevronButton.transform = - CGAffineTransformRotate(CGAffineTransformIdentity, upRotation); + CGAffineTransformRotate(CGAffineTransformIdentity, downRotation); snippetLabelOneLine.alpha = 1; snippetLabelExpanded.alpha = 0; snippetLabelOneLineConstraint.priority = UILayoutPriorityDefaultLow; @@ -404,7 +404,7 @@ break; case SnippetButtonState::kExpanded: chevronButton.transform = - CGAffineTransformRotate(CGAffineTransformIdentity, downRotation); + CGAffineTransformRotate(CGAffineTransformIdentity, upRotation); snippetLabelOneLine.alpha = 0; snippetLabelExpanded.alpha = 1; snippetLabelOneLineConstraint.priority = UILayoutPriorityDefaultHigh;
diff --git a/ios/chrome/browser/ui/settings/autofill/autofill_add_credit_card_mediator.mm b/ios/chrome/browser/ui/settings/autofill/autofill_add_credit_card_mediator.mm index fa484060..cd25e3bc 100644 --- a/ios/chrome/browser/ui/settings/autofill/autofill_add_credit_card_mediator.mm +++ b/ios/chrome/browser/ui/settings/autofill/autofill_add_credit_card_mediator.mm
@@ -16,19 +16,14 @@ #import "ios/chrome/browser/ui/settings/autofill/autofill_add_credit_card_mediator_delegate.h" #import "ios/chrome/browser/ui/settings/autofill/autofill_credit_card_util.h" -@interface AutofillAddCreditCardMediator () +@implementation AutofillAddCreditCardMediator { + // This property is for an interface which sends a response about saving the + // credit card either the credit card is valid or it is invalid. + __weak id<AddCreditCardMediatorDelegate> _addCreditCardMediatorDelegate; -// Used for adding new CreditCard object. -@property(nonatomic, assign) autofill::PersonalDataManager* personalDataManager; - -// This property is for an interface which sends a response about saving the -// credit card either the credit card is valid or it is invalid. -@property(nonatomic, weak) id<AddCreditCardMediatorDelegate> - addCreditCardMediatorDelegate; - -@end - -@implementation AutofillAddCreditCardMediator + // Used for adding new CreditCard object. + raw_ptr<autofill::PersonalDataManager> _personalDataManager; +} - (instancetype)initWithDelegate:(id<AddCreditCardMediatorDelegate>) addCreditCardMediatorDelegate @@ -64,26 +59,25 @@ // Validates the credit card number, expiration date, and nickname. if (!creditCard.HasValidCardNumber()) { - [self.addCreditCardMediatorDelegate + [_addCreditCardMediatorDelegate creditCardMediatorHasInvalidCardNumber:self]; return; } if (!creditCard.HasValidExpirationDate()) { - [self.addCreditCardMediatorDelegate + [_addCreditCardMediatorDelegate creditCardMediatorHasInvalidExpirationDate:self]; return; } if (!autofill::CreditCard::IsNicknameValid( base::SysNSStringToUTF16(cardNickname))) { - [self.addCreditCardMediatorDelegate - creditCardMediatorHasInvalidNickname:self]; + [_addCreditCardMediatorDelegate creditCardMediatorHasInvalidNickname:self]; return; } autofill::CreditCard* savedCreditCard = - self.personalDataManager->GetCreditCardByNumber( + _personalDataManager->GetCreditCardByNumber( base::SysNSStringToUTF8(cardNumber)); // If the credit card number already exist in saved credit card @@ -100,23 +94,22 @@ cardNickname:cardNickname appLocal:appLocal]; - self.personalDataManager->UpdateCreditCard(savedCreditCardCopy); + _personalDataManager->UpdateCreditCard(savedCreditCardCopy); } else { base::RecordAction( base::UserMetricsAction("MobileAddCreditCard.CreditCardAdded")); - base::UmaHistogramCounts100( - "Autofill.PaymentMethods.SettingsPage." - "StoredCreditCardCountBeforeCardAdded", - self.personalDataManager->GetCreditCards().size()); - self.personalDataManager->AddCreditCard(creditCard); + base::UmaHistogramCounts100("Autofill.PaymentMethods.SettingsPage." + "StoredCreditCardCountBeforeCardAdded", + _personalDataManager->GetCreditCards().size()); + _personalDataManager->AddCreditCard(creditCard); } - [self.addCreditCardMediatorDelegate creditCardMediatorDidFinish:self]; + [_addCreditCardMediatorDelegate creditCardMediatorDidFinish:self]; } - (void)addCreditCardViewControllerDidCancel: (AutofillAddCreditCardViewController*)viewController { - [self.addCreditCardMediatorDelegate creditCardMediatorDidFinish:self]; + [_addCreditCardMediatorDelegate creditCardMediatorDidFinish:self]; } - (bool)addCreditCardViewController:
diff --git a/ios/chrome/browser/ui/settings/autofill/autofill_settings_profile_edit_table_view_controller.mm b/ios/chrome/browser/ui/settings/autofill/autofill_settings_profile_edit_table_view_controller.mm index fbdeb2b0..1cb2d96 100644 --- a/ios/chrome/browser/ui/settings/autofill/autofill_settings_profile_edit_table_view_controller.mm +++ b/ios/chrome/browser/ui/settings/autofill/autofill_settings_profile_edit_table_view_controller.mm
@@ -26,24 +26,22 @@ @interface AutofillSettingsProfileEditTableViewController () -@property(nonatomic, weak) - id<AutofillSettingsProfileEditTableViewControllerDelegate> - delegate; - -// If YES, a section is shown in the view to migrate the profile to account. -@property(nonatomic, assign) BOOL showMigrateToAccountSection; - -// If YES, denotes that the view shown is to edit the incomplete profiles so -// that it can migrated to account. -@property(nonatomic, assign) BOOL editIncompleteProfileForAccountView; - // Stores the signed in user email, or the empty string if the user is not // signed-in. @property(nonatomic, readonly) NSString* userEmail; @end -@implementation AutofillSettingsProfileEditTableViewController +@implementation AutofillSettingsProfileEditTableViewController { + __weak id<AutofillSettingsProfileEditTableViewControllerDelegate> _delegate; + + // If YES, a section is shown in the view to migrate the profile to account. + BOOL _showMigrateToAccountSection; + + // If YES, denotes that the view shown is to edit the incomplete profiles so + // that it can migrated to account. + BOOL _editIncompleteProfileForAccountView; +} #pragma mark - Initialization @@ -84,7 +82,7 @@ [self.handler loadModel]; TableViewModel* model = self.tableViewModel; - if (self.showMigrateToAccountSection) { + if (_showMigrateToAccountSection) { [model addItem:[self migrateToAccountRecommendationItem] toSectionWithIdentifier:AutofillProfileDetailsSectionIdentifierFields]; [model addItem:[self migrateToAccountButtonItem] @@ -113,13 +111,13 @@ if (!self.tableView.editing) { [self.handler updateProfileData]; - if (self.editIncompleteProfileForAccountView) { - [self.delegate didTapMigrateToAccountButton]; + if (_editIncompleteProfileForAccountView) { + [_delegate didTapMigrateToAccountButton]; [self showPostMigrationToast]; [self.handler setMoveToAccountFromSettings:NO]; - self.editIncompleteProfileForAccountView = NO; + _editIncompleteProfileForAccountView = NO; } else { - [self.delegate didEditAutofillProfileFromSettings]; + [_delegate didEditAutofillProfileFromSettings]; } } @@ -155,8 +153,8 @@ } if (itemType == AutofillProfileDetailsItemTypeMigrateToAccountButton) { [self.tableView deselectRowAtIndexPath:indexPath animated:YES]; - if ([self.delegate isMinimumAddress]) { - [self.delegate didTapMigrateToAccountButton]; + if ([_delegate isMinimumAddress]) { + [_delegate didTapMigrateToAccountButton]; __weak __typeof(self) weakSelf = self; void (^completion)(BOOL) = ^(BOOL) { [weakSelf showPostMigrationToast]; @@ -164,7 +162,7 @@ [self removeMigrateButton:completion]; } else { // Show the profile in the edit mode. - self.editIncompleteProfileForAccountView = YES; + _editIncompleteProfileForAccountView = YES; [self removeMigrateButton:nil]; [self editButtonPressed]; [self.handler setMoveToAccountFromSettings:YES]; @@ -273,7 +271,7 @@ withRowAnimation:UITableViewRowAnimationAutomatic]; } completion:onCompletion]; - self.showMigrateToAccountSection = NO; + _showMigrateToAccountSection = NO; } - (void)showPostMigrationToast {
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/tab_groups/create_tab_group_mediator.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/tab_groups/create_tab_group_mediator.mm index 07269a8..7f0d6e3 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/tab_groups/create_tab_group_mediator.mm +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/tab_groups/create_tab_group_mediator.mm
@@ -127,7 +127,7 @@ if (snapshot) { [_snapshots addObject:snapshot]; } else { - [_snapshots addObject:[NSNull null]]; + [_snapshots addObject:[[UIImage alloc] init]]; } } @@ -137,7 +137,7 @@ if (favicon) { [_favicons addObject:favicon]; } else { - [_favicons addObject:[NSNull null]]; + [_favicons addObject:[[UIImage alloc] init]]; } }
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/tab_groups/create_tab_group_view_controller.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/tab_groups/create_tab_group_view_controller.mm index 53224394..96d0661 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/tab_groups/create_tab_group_view_controller.mm +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/tab_groups/create_tab_group_view_controller.mm
@@ -76,6 +76,13 @@ const TabGroup* _tabGroup; // Number of selected items. NSInteger _numberOfSelectedItems; + + // Configured view that handle the snapshots dispositions. + TabGroupSnapshotsView* _snapshotsView; + // Constraints for the snapshots view, depending on if we display one or + // multiple snapshots. + NSArray<NSLayoutConstraint*>* _singleSnapshotConstraints; + NSArray<NSLayoutConstraint*>* _multipleSnapshotsConstraints; } - (instancetype)initWithHandler:(id<TabGroupsCommands>)handler @@ -632,39 +639,23 @@ snapshotsBackground.layer.cornerRadius = kSnapshotViewCornerRadius; snapshotsBackground.opaque = NO; - UIView* snapshotView; - CGFloat sizeConstraint; - // TODO(crbug.com/1501837): Remove this and move it inside - // TabGroupSnapshotsView so it uses the group tab view object. - if ([_snapshots count] == 1u || [_favicons count] == 1u) { - snapshotView = [[TabGroupSnapshotsView alloc] - initWithSnapshot:[self imageFromObject:_snapshots.firstObject] - favicon:[self imageFromObject:_favicons.firstObject]]; - - [snapshotsBackground addSubview:snapshotView]; - sizeConstraint = kSingleSnapshotRatio; - } else { // TODO(crbug.com/1501837): Remove the creation of tab group infos once the // appropriate method is implemented. - NSMutableArray<GroupTabInfo*>* tabGroupInfos = - [[NSMutableArray alloc] init]; - for (NSUInteger i = 0; i < [_snapshots count] && i < [_favicons count]; - i++) { - GroupTabInfo* tabGroupInfo = [[GroupTabInfo alloc] init]; - tabGroupInfo.snapshot = _snapshots[i]; - tabGroupInfo.favicon = _favicons[i]; - [tabGroupInfos addObject:tabGroupInfo]; - } - snapshotView = [[TabGroupSnapshotsView alloc] - initWithTabGroupInfos:tabGroupInfos - size:_numberOfSelectedItems - light:self.traitCollection.userInterfaceStyle == - UIUserInterfaceStyleLight - cell:NO]; - - [snapshotsBackground addSubview:snapshotView]; - sizeConstraint = kMultipleSnapshotsRatio; + NSMutableArray<GroupTabInfo*>* tabGroupInfos = [[NSMutableArray alloc] init]; + for (NSUInteger i = 0; i < MIN([_snapshots count], [_favicons count]); ++i) { + GroupTabInfo* tabGroupInfo = [[GroupTabInfo alloc] init]; + tabGroupInfo.snapshot = _snapshots[i]; + tabGroupInfo.favicon = _favicons[i]; + [tabGroupInfos addObject:tabGroupInfo]; } + _snapshotsView = [[TabGroupSnapshotsView alloc] + initWithTabGroupInfos:tabGroupInfos + size:_numberOfSelectedItems + light:self.traitCollection.userInterfaceStyle == + UIUserInterfaceStyleLight + cell:NO]; + + [snapshotsBackground addSubview:_snapshotsView]; NSLayoutConstraint* backgroundHeightConstraint = [snapshotsBackground.heightAnchor @@ -673,22 +664,34 @@ // reduced instead of other elements where the user can interact with. backgroundHeightConstraint.priority = UILayoutPriorityDefaultLow; + _singleSnapshotConstraints = @[ + [_snapshotsView.widthAnchor + constraintEqualToAnchor:snapshotsBackground.widthAnchor + multiplier:kSingleSnapshotRatio], + [_snapshotsView.heightAnchor + constraintEqualToAnchor:snapshotsBackground.heightAnchor + multiplier:kSingleSnapshotRatio] + ]; + _multipleSnapshotsConstraints = @[ + [_snapshotsView.widthAnchor + constraintEqualToAnchor:snapshotsBackground.widthAnchor + multiplier:kMultipleSnapshotsRatio], + [_snapshotsView.heightAnchor + constraintEqualToAnchor:snapshotsBackground.heightAnchor + multiplier:kMultipleSnapshotsRatio] + ]; + [NSLayoutConstraint activateConstraints:@[ backgroundHeightConstraint, [snapshotsBackground.widthAnchor constraintEqualToAnchor:snapshotsBackground.heightAnchor multiplier:kSnapshotViewRatio], - [snapshotView.centerXAnchor + [_snapshotsView.centerXAnchor constraintEqualToAnchor:snapshotsBackground.centerXAnchor], - [snapshotView.centerYAnchor + [_snapshotsView.centerYAnchor constraintEqualToAnchor:snapshotsBackground.centerYAnchor], - [snapshotView.widthAnchor - constraintEqualToAnchor:snapshotsBackground.widthAnchor - multiplier:sizeConstraint], - [snapshotView.heightAnchor - constraintEqualToAnchor:snapshotsBackground.heightAnchor - multiplier:sizeConstraint], ]]; + [self applyConstraints]; return snapshotsBackground; } @@ -703,19 +706,33 @@ favicons:(NSArray<UIImage*>*)favicons numberOfSelectedItems:(NSInteger)numberOfSelectedItems { // TODO(crbug.com/1501837): Pass an array of Group Tab Info. + NSMutableArray<GroupTabInfo*>* tabGroupInfos = [[NSMutableArray alloc] init]; + for (NSUInteger i = 0; i < MIN([snapshots count], [favicons count]); ++i) { + GroupTabInfo* info = [[GroupTabInfo alloc] init]; + info.snapshot = snapshots[i]; + info.favicon = favicons[i]; + [tabGroupInfos addObject:info]; + } _snapshots = snapshots; _favicons = favicons; _numberOfSelectedItems = numberOfSelectedItems; + [_snapshotsView + configureTabGroupSnapshotsViewWithTabGroupInfos:tabGroupInfos + size:_numberOfSelectedItems]; + [self applyConstraints]; } #pragma mark - Private Helpers -// Returns the picture is it is a picture and nil if not. -- (UIImage*)imageFromObject:(id)object { - if ([object isKindOfClass:[NSNull class]]) { - return [[UIImage alloc] init]; +// Activates or deactivates the appropriate constraints. +- (void)applyConstraints { + if (_numberOfSelectedItems == 1) { + [NSLayoutConstraint deactivateConstraints:_multipleSnapshotsConstraints]; + [NSLayoutConstraint activateConstraints:_singleSnapshotConstraints]; + } else { + [NSLayoutConstraint deactivateConstraints:_singleSnapshotConstraints]; + [NSLayoutConstraint activateConstraints:_multipleSnapshotsConstraints]; } - return object; } @end
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/tab_groups/group_tab_view.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/tab_groups/group_tab_view.mm index 93cc067d..6494e30 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/tab_groups/group_tab_view.mm +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/tab_groups/group_tab_view.mm
@@ -199,7 +199,6 @@ _bottomFaviconView.hidden = NO; } _snapshotFaviconView.hidden = NO; - return; } - (void)configureWithFavicons:(NSArray<UIImage*>*)favicons { @@ -215,7 +214,6 @@ - (void)configureWithFavicons:(NSArray<UIImage*>*)favicons remainingTabsNumber:(NSInteger)remainingTabsNumber { - CHECK_EQ([favicons count], 3u); [self configureWithFavicons:favicons]; _viewList[3].hidden = NO; _bottomTrailingFaviconLabel.hidden = NO;
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/tab_groups/tab_group_snapshots_view.h b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/tab_groups/tab_group_snapshots_view.h index 663468b..aba724d 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/tab_groups/tab_group_snapshots_view.h +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/tab_groups/tab_group_snapshots_view.h
@@ -13,8 +13,6 @@ // snapshots. @interface TabGroupSnapshotsView : UIView -- (instancetype)initWithSnapshot:(UIImage*)snapshot favicon:(UIImage*)favicon; - - (instancetype)initWithTabGroupInfos:(NSArray<GroupTabInfo*>*)tabGroupInfos size:(NSUInteger)size light:(BOOL)isLight
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/tab_groups/tab_group_snapshots_view.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/tab_groups/tab_group_snapshots_view.mm index 32adc2e..2865c14 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/tab_groups/tab_group_snapshots_view.mm +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/tab_groups/tab_group_snapshots_view.mm
@@ -15,12 +15,6 @@ #import "ios/chrome/common/ui/util/constraints_ui_util.h" namespace { -constexpr CGFloat kFaviconSize = 16; -constexpr CGFloat kFaviconPadding = 8; -constexpr CGFloat kFaviconMargin = 4; -constexpr CGFloat kFaviconCornerRadius = 7; -constexpr CGFloat kSnapshotCornerRadius = 12; -constexpr CGFloat kSnapshotOverlayAlpha = 0.14; constexpr CGFloat kSpacing = 4; constexpr CGFloat kFinalViewCornerRadius = 16; } // namespace @@ -32,75 +26,7 @@ NSUInteger _tabGroupTabNumber; UIStackView* _firstLine; UIStackView* _secondLine; -} - -// TODO(crbug.com/1501837): Remove this and use GroupTabView instead. -- (instancetype)initWithSnapshot:(UIImage*)snapshot favicon:(UIImage*)favicon { - CHECK(IsTabGroupInGridEnabled()) - << "You should not be able to create a tab group snapshot view outside " - "the Tab Groups experiment."; - self = [super init]; - if (self) { - UIView* finalView = self; - finalView.translatesAutoresizingMaskIntoConstraints = NO; - - TopAlignedImageView* snapshotView = [[TopAlignedImageView alloc] init]; - snapshotView.image = snapshot; - snapshotView.translatesAutoresizingMaskIntoConstraints = NO; - snapshotView.layer.cornerRadius = kSnapshotCornerRadius; - snapshotView.contentMode = UIViewContentModeScaleAspectFill; - snapshotView.clipsToBounds = YES; - - GradientView* snapshotOverlay = [[GradientView alloc] - initWithTopColor:[[UIColor blackColor] colorWithAlphaComponent:0] - bottomColor:[[UIColor blackColor] - colorWithAlphaComponent:kSnapshotOverlayAlpha]]; - snapshotOverlay.translatesAutoresizingMaskIntoConstraints = NO; - [snapshotView addSubview:snapshotOverlay]; - AddSameConstraints(snapshotOverlay, snapshotView); - - // Add a favicon only if there is one. - // TODO(crbug.com/1501837): Condition should be removed once we garanty to - // have at least the default favicon. - if (favicon && !CGSizeEqualToSize(favicon.size, CGSizeZero)) { - UIImageView* faviconImageView = [[UIImageView alloc] init]; - faviconImageView.translatesAutoresizingMaskIntoConstraints = NO; - faviconImageView.contentMode = UIViewContentModeScaleAspectFill; - faviconImageView.image = favicon; - - UIView* faviconBackground = [[UIView alloc] init]; - faviconBackground.translatesAutoresizingMaskIntoConstraints = NO; - faviconBackground.backgroundColor = UIColor.whiteColor; - faviconBackground.layer.cornerRadius = kFaviconCornerRadius; - faviconBackground.clipsToBounds = YES; - - [faviconBackground addSubview:faviconImageView]; - AddSameCenterConstraints(faviconBackground, faviconImageView); - - [snapshotView addSubview:faviconBackground]; - - [NSLayoutConstraint activateConstraints:@[ - [faviconImageView.widthAnchor constraintEqualToConstant:kFaviconSize], - [faviconImageView.heightAnchor constraintEqualToConstant:kFaviconSize], - [faviconBackground.widthAnchor - constraintEqualToAnchor:faviconImageView.widthAnchor - constant:kFaviconPadding], - [faviconBackground.heightAnchor - constraintEqualToAnchor:faviconImageView.heightAnchor - constant:kFaviconPadding], - [faviconBackground.trailingAnchor - constraintEqualToAnchor:snapshotView.trailingAnchor - constant:-kFaviconMargin], - [faviconBackground.bottomAnchor - constraintEqualToAnchor:snapshotView.bottomAnchor - constant:-kFaviconMargin], - ]]; - } - - [finalView addSubview:snapshotView]; - AddSameConstraints(finalView, snapshotView); - } - return self; + GroupTabView* _singleView; } - (instancetype)initWithTabGroupInfos:(NSArray<GroupTabInfo*>*)tabGroupInfos @@ -133,6 +59,18 @@ [self configureTabGroupSnapshotsViewWithTabGroupInfos:tabGroupInfos size:size]; + if (!_isCell) { + _singleView = [[GroupTabView alloc] initWithIsCell:_isCell]; + _singleView.translatesAutoresizingMaskIntoConstraints = NO; + [_singleView configureWithSnapshot:tabGroupInfos.firstObject.snapshot + favicon:tabGroupInfos.firstObject.favicon]; + [self addSubview:_singleView]; + AddSameConstraints(_singleView, self); + _singleView.hidden = size > 1; + _firstLine.hidden = size == 1; + _secondLine.hidden = size == 1; + } + if (@available(iOS 17, *)) { [self registerForTraitChanges:@[ UITraitVerticalSizeClass.self ] withAction:@selector(updateViews)]; @@ -240,7 +178,18 @@ size:(NSUInteger)size { _tabGroupInfos = [self prepareInfos:tabGroupInfos]; _tabGroupTabNumber = size; - [self updateViews]; + if (!_isCell && (size == 1)) { + _singleView.hidden = NO; + _firstLine.hidden = YES; + _secondLine.hidden = YES; + [_singleView configureWithSnapshot:tabGroupInfos.firstObject.snapshot + favicon:tabGroupInfos.firstObject.favicon]; + } else { + _singleView.hidden = YES; + _firstLine.hidden = NO; + _secondLine.hidden = NO; + [self updateViews]; + } } - (void)updateViews {
diff --git a/ios/chrome/browser/webui/ui_bundled/interstitials/interstitial_ui_util.mm b/ios/chrome/browser/webui/ui_bundled/interstitials/interstitial_ui_util.mm index bdcf37a..004250b 100644 --- a/ios/chrome/browser/webui/ui_bundled/interstitials/interstitial_ui_util.mm +++ b/ios/chrome/browser/webui/ui_bundled/interstitials/interstitial_ui_util.mm
@@ -144,8 +144,9 @@ std::unique_ptr<security_interstitials::IOSSecurityInterstitialPage> CreateSafeBrowsingBlockingPage(web::WebState* web_state, const GURL& url) { - safe_browsing::SBThreatType threat_type = - safe_browsing::SB_THREAT_TYPE_URL_MALWARE; + using enum safe_browsing::SBThreatType; + + safe_browsing::SBThreatType threat_type = SB_THREAT_TYPE_URL_MALWARE; GURL request_url("http://example.com"); GURL main_frame_url(request_url); @@ -164,16 +165,16 @@ if (net::GetValueForKeyInQuery( url, kChromeInterstitialSafeBrowsingTypeQueryKey, &type_param)) { if (type_param == kChromeInterstitialSafeBrowsingTypeMalwareValue) { - threat_type = safe_browsing::SB_THREAT_TYPE_URL_MALWARE; + threat_type = SB_THREAT_TYPE_URL_MALWARE; } else if (type_param == kChromeInterstitialSafeBrowsingTypePhishingValue) { - threat_type = safe_browsing::SB_THREAT_TYPE_URL_PHISHING; + threat_type = SB_THREAT_TYPE_URL_PHISHING; } else if (type_param == kChromeInterstitialSafeBrowsingTypeUnwantedValue) { - threat_type = safe_browsing::SB_THREAT_TYPE_URL_UNWANTED; + threat_type = SB_THREAT_TYPE_URL_UNWANTED; } else if (type_param == kChromeInterstitialSafeBrowsingTypeClientsidePhishingValue) { - threat_type = safe_browsing::SB_THREAT_TYPE_URL_CLIENT_SIDE_PHISHING; + threat_type = SB_THREAT_TYPE_URL_CLIENT_SIDE_PHISHING; } else if (type_param == kChromeInterstitialSafeBrowsingTypeBillingValue) { - threat_type = safe_browsing::SB_THREAT_TYPE_BILLING; + threat_type = SB_THREAT_TYPE_BILLING; } }
diff --git a/ios/chrome/common/ui/elements/form_input_accessory_view.mm b/ios/chrome/common/ui/elements/form_input_accessory_view.mm index baec006..6b289ab 100644 --- a/ios/chrome/common/ui/elements/form_input_accessory_view.mm +++ b/ios/chrome/common/ui/elements/form_input_accessory_view.mm
@@ -89,6 +89,11 @@ UIButton* _omniboxTypingShield; // Height constraint used to show/hide the `omniboxTypingShield`. NSLayoutConstraint* _omniboxTypingShieldHeightConstraint; + // Bottom constraint used to show/hide the `omniboxTypingShield`. + NSLayoutConstraint* _omniboxTypingShieldBottomConstraint; + // Bottom constraint used to show/hide the `omniboxTypingShield` when the view + // is hidden. + NSLayoutConstraint* _omniboxTypingShieldHiddenBottomConstraint; // View containing the leading and trailing buttons. UIView* _contentView; // Whether we are using the large accessory view. @@ -490,10 +495,13 @@ LayoutSides::kTop | LayoutSides::kLeading | LayoutSides::kTrailing); _omniboxTypingShieldHeightConstraint = [_omniboxTypingShield.heightAnchor constraintEqualToConstant:0]; + _omniboxTypingShieldBottomConstraint = [_omniboxTypingShield.bottomAnchor + constraintEqualToAnchor:_contentView.topAnchor]; + _omniboxTypingShieldHiddenBottomConstraint = + [_omniboxTypingShield.bottomAnchor + constraintEqualToAnchor:self.bottomAnchor]; [NSLayoutConstraint activateConstraints:@[ - _omniboxTypingShieldHeightConstraint, - [_omniboxTypingShield.bottomAnchor - constraintEqualToAnchor:_contentView.topAnchor] + _omniboxTypingShieldHeightConstraint, _omniboxTypingShieldBottomConstraint ]]; [_omniboxTypingShield addTarget:self action:@selector(omniboxTypingShieldTapped) @@ -515,4 +523,20 @@ : [UIColor colorNamed:kBackgroundColor]; } +#pragma mark - UIView + +- (void)setHidden:(BOOL)hidden { + [super setHidden:hidden]; + + // The bottom omnibox is anchored to the typing shield. If we don't change the + // shield's anchor, when hiding the accessory view, there is a blank space the + // size of the keyboard accessory view between the top of the view below the + // accessory view and the omnibox. By changing the anchor here, the omnibox + // appears directly above the view below the accessory view, without any gaps. + _omniboxTypingShieldBottomConstraint.active = !hidden; + _omniboxTypingShieldHiddenBottomConstraint.active = hidden; + + [self layoutIfNeeded]; +} + @end
diff --git a/ios/web_view/internal/safe_browsing/cwv_unsafe_url_handler.mm b/ios/web_view/internal/safe_browsing/cwv_unsafe_url_handler.mm index 8079b98..aca10c2 100644 --- a/ios/web_view/internal/safe_browsing/cwv_unsafe_url_handler.mm +++ b/ios/web_view/internal/safe_browsing/cwv_unsafe_url_handler.mm
@@ -16,14 +16,16 @@ CWVUnsafeURLThreatType CWVUnsafeURLThreatTypeFromSBThreatType( safe_browsing::SBThreatType threatType) { + using enum safe_browsing::SBThreatType; + switch (threatType) { - case safe_browsing::SB_THREAT_TYPE_BILLING: + case SB_THREAT_TYPE_BILLING: return CWVUnsafeURLThreatTypeBilling; - case safe_browsing::SB_THREAT_TYPE_URL_MALWARE: + case SB_THREAT_TYPE_URL_MALWARE: return CWVUnsafeURLThreatTypeMalware; - case safe_browsing::SB_THREAT_TYPE_URL_UNWANTED: + case SB_THREAT_TYPE_URL_UNWANTED: return CWVUnsafeURLThreatTypeUnwanted; - case safe_browsing::SB_THREAT_TYPE_URL_PHISHING: + case SB_THREAT_TYPE_URL_PHISHING: return CWVUnsafeURLThreatTypePhishing; default: NOTREACHED() << "Update CWVUnsafeURLThreatType for new threat type.";
diff --git a/media/base/media_switches.cc b/media/base/media_switches.cc index d87a8f0..f474c05 100644 --- a/media/base/media_switches.cc +++ b/media/base/media_switches.cc
@@ -1805,8 +1805,8 @@ // Convert SharedBitmap to SharedImage for media resources. BASE_FEATURE(kMediaSharedBitmapToSharedImage, - "MediaSharedBitmapToSharedImage", - base::FEATURE_ENABLED_BY_DEFAULT); + "MediaSharedBitmapToSharedImage_DoNotEnable", + base::FEATURE_DISABLED_BY_DEFAULT); bool IsChromeWideEchoCancellationEnabled() { #if BUILDFLAG(CHROME_WIDE_ECHO_CANCELLATION)
diff --git a/media/base/video_util.cc b/media/base/video_util.cc index bf50495a..2af63e0 100644 --- a/media/base/video_util.cc +++ b/media/base/video_util.cc
@@ -210,6 +210,7 @@ auto info = SkImageInfo::Make(src_rect.width(), src_rect.height(), sk_color_type, sk_alpha_type); + bool result = false; // Perform readback for a mailbox per plane for legacy shared image format // types where planes and mailboxes are 1:1. With multiplanar shared images, // there's one shared image mailbox for multiplanar formats so perform @@ -218,16 +219,18 @@ const gpu::MailboxHolder& holder = src_frame.mailbox_holder(src_plane); DCHECK(!holder.mailbox.IsZero()); ri->WaitSyncTokenCHROMIUM(holder.sync_token.GetConstData()); - ri->ReadbackImagePixels(holder.mailbox, info, dest_stride, src_rect.x(), - src_rect.y(), /*plane_index=*/0, dest_pixels); + result = + ri->ReadbackImagePixels(holder.mailbox, info, dest_stride, src_rect.x(), + src_rect.y(), /*plane_index=*/0, dest_pixels); } else { const gpu::MailboxHolder& holder = src_frame.mailbox_holder(0); DCHECK(!holder.mailbox.IsZero()); ri->WaitSyncTokenCHROMIUM(holder.sync_token.GetConstData()); - ri->ReadbackImagePixels(holder.mailbox, info, dest_stride, src_rect.x(), - src_rect.y(), src_plane, dest_pixels); + result = + ri->ReadbackImagePixels(holder.mailbox, info, dest_stride, src_rect.x(), + src_rect.y(), src_plane, dest_pixels); } - return ri->GetGraphicsResetStatusKHR() == GL_NO_ERROR && + return result && ri->GetGraphicsResetStatusKHR() == GL_NO_ERROR && ri->GetError() == GL_NO_ERROR; }
diff --git a/media/renderers/paint_canvas_video_renderer.cc b/media/renderers/paint_canvas_video_renderer.cc index 6466879..b98fdcf 100644 --- a/media/renderers/paint_canvas_video_renderer.cc +++ b/media/renderers/paint_canvas_video_renderer.cc
@@ -943,9 +943,8 @@ return sk_image_->readPixels(dst_info, dst_pixels, dst_row_bytes, src_x, src_y); } - ri->ReadbackImagePixels(mailbox_, dst_info, dst_info.minRowBytes(), src_x, - src_y, /*plane_index=*/0, dst_pixels); - return true; + return ri->ReadbackImagePixels(mailbox_, dst_info, dst_info.minRowBytes(), + src_x, src_y, /*plane_index=*/0, dst_pixels); } void FlushPendingSkiaOps() override {
diff --git a/net/base/net_error_list.h b/net/base/net_error_list.h index 69ceb113..dff37088 100644 --- a/net/base/net_error_list.h +++ b/net/base/net_error_list.h
@@ -127,6 +127,10 @@ // The request was blocked by CORB or ORB. NET_ERROR(BLOCKED_BY_ORB, -32) +// The request was blocked because it originated from a frame that has disabled +// network access. +NET_ERROR(NETWORK_ACCESS_REVOKED, -33) + // A connection was closed (corresponding to a TCP FIN). NET_ERROR(CONNECTION_CLOSED, -100)
diff --git a/net/http/transport_security_state_static.pins b/net/http/transport_security_state_static.pins index 57f0312b..7b96385 100644 --- a/net/http/transport_security_state_static.pins +++ b/net/http/transport_security_state_static.pins
@@ -43,9 +43,9 @@ # hash function for preloaded entries again (we have already done so once). # -# Last updated: 2024-03-17 12:55 UTC +# Last updated: 2024-03-18 12:56 UTC PinsListTimestamp -1710680130 +1710766571 TestSPKI sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
diff --git a/net/http/transport_security_state_static_pins.json b/net/http/transport_security_state_static_pins.json index 84724c9..9b29ad4 100644 --- a/net/http/transport_security_state_static_pins.json +++ b/net/http/transport_security_state_static_pins.json
@@ -31,7 +31,7 @@ // the 'static_spki_hashes' and 'bad_static_spki_hashes' fields in 'pinsets' // refer to, and the timestamp at which the pins list was last updated. // -// Last updated: 2024-03-17 12:55 UTC +// Last updated: 2024-03-18 12:56 UTC // { "pinsets": [
diff --git a/sandbox/policy/mac/screen_ai.sb b/sandbox/policy/mac/screen_ai.sb index 9602dcb..48b02a9a 100644 --- a/sandbox/policy/mac/screen_ai.sb +++ b/sandbox/policy/mac/screen_ai.sb
@@ -4,7 +4,7 @@ ; --- The contents of common.sb implicitly included here. --- -; Required to load the libscreen_ai.so binary downloaded by the component +; Required to load the libchromescreen_ai.so binary downloaded by the component ; updater. (define screen-ai-component-path "SCREEN_AI_COMPONENT_PATH") -(allow file-read* (subpath (param screen-ai-component-path))) +(allow file-read* (path (param screen-ai-component-path)))
diff --git a/services/network/cors/cors_url_loader_factory.cc b/services/network/cors/cors_url_loader_factory.cc index 021bb175..55c19e04 100644 --- a/services/network/cors/cors_url_loader_factory.cc +++ b/services/network/cors/cors_url_loader_factory.cc
@@ -373,18 +373,31 @@ factory_override_ ? factory_override_->get() : network_loader_factory_.get(); DCHECK(inner_url_loader_factory); + + const net::IsolationInfo* isolation_info_ptr = &isolation_info_; + auto isolation_info = URLLoader::GetIsolationInfo( + isolation_info_, automatically_assign_isolation_info_, resource_request); + if (isolation_info.has_value()) { + isolation_info_ptr = &isolation_info.value(); + } + + // Check if the initiator's network access has been revoked. + // This check is only relevant if there is a partition nonce in the + // isolation info. (All requests originating from a fenced frame have a + // nonce specified.) + if (isolation_info.has_value() && isolation_info->nonce().has_value() && + !context_->IsNetworkForNonceAndUrlAllowed(*isolation_info->nonce(), + resource_request.url)) { + mojo::Remote<mojom::URLLoaderClient>(std::move(client)) + ->OnComplete( + URLLoaderCompletionStatus(net::ERR_NETWORK_ACCESS_REVOKED)); + return; + } + if (!disable_web_security_) { mojo::PendingRemote<mojom::DevToolsObserver> devtools_observer = GetDevToolsObserver(resource_request); - const net::IsolationInfo* isolation_info_ptr = &isolation_info_; - auto isolation_info = URLLoader::GetIsolationInfo( - isolation_info_, automatically_assign_isolation_info_, - resource_request); - if (isolation_info) { - isolation_info_ptr = &isolation_info.value(); - } - scoped_refptr<SharedDictionaryStorage> shared_dictionary_storage = shared_dictionary_storage_; if (context_->GetSharedDictionaryManager() &&
diff --git a/services/network/network_context.cc b/services/network/network_context.cc index ecefb42..16e8cf4 100644 --- a/services/network/network_context.cc +++ b/services/network/network_context.cc
@@ -3027,4 +3027,44 @@ url_request_context_->set_cookie_deprecation_label(label); } +void NetworkContext::RevokeNetworkForNonce( + const base::UnguessableToken& nonce, + RevokeNetworkForNonceCallback callback) { + network_revocation_nonces_.insert(nonce); + // TODO(crbug.com/41488151): Cancel requests in progress. + std::move(callback).Run(); +} + +void NetworkContext::ExemptUrlFromNetworkRevocationForNonce( + const GURL& exempted_url, + const base::UnguessableToken& nonce, + ExemptUrlFromNetworkRevocationForNonceCallback callback) { + GURL url_without_filename = exempted_url.GetWithoutFilename(); + if (network_revocation_exemptions_.contains(nonce)) { + network_revocation_exemptions_.find(nonce)->second.insert( + url_without_filename); + } else { + network_revocation_exemptions_.insert({nonce, {url_without_filename}}); + } + std::move(callback).Run(); +} + +bool NetworkContext::IsNetworkForNonceAndUrlAllowed( + const base::UnguessableToken& nonce, + const GURL& url) const { + // If network hasn't been revoked for the nonce, it's allowed. + if (!network_revocation_nonces_.contains(nonce)) { + return true; + } + // If network has been revoked for the nonce, but the url is exempted, it's + // allowed. + if (network_revocation_exemptions_.contains(nonce) && + network_revocation_exemptions_.find(nonce)->second.contains( + url.GetWithoutFilename())) { + return true; + } + // The nonce was revoked and the url isn't exempted. + return false; +} + } // namespace network
diff --git a/services/network/network_context.h b/services/network/network_context.h index bf94d00..a3ba05c 100644 --- a/services/network/network_context.h +++ b/services/network/network_context.h
@@ -526,6 +526,12 @@ const scoped_refptr<net::X509Certificate>& certificate) override; void SetCookieDeprecationLabel( const std::optional<std::string>& label) override; + void RevokeNetworkForNonce(const base::UnguessableToken& nonce, + RevokeNetworkForNonceCallback callback) override; + void ExemptUrlFromNetworkRevocationForNonce( + const GURL& exempted_url, + const base::UnguessableToken& nonce, + ExemptUrlFromNetworkRevocationForNonceCallback callback) override; // Destroys |request| when a proxy lookup completes. void OnProxyLookupComplete(ProxyLookupRequest* proxy_lookup_request); @@ -653,6 +659,12 @@ const std::vector<net::ReportingEndpoint>& endpoints) override; #endif // BUILDFLAG(ENABLE_REPORTING) + // Checks whether network access for the partition nonce `nonce` and url + // `url` is allowed. See `network_revocation_nonces_` and + // `network_revocation_exemptions_`. + bool IsNetworkForNonceAndUrlAllowed(const base::UnguessableToken& nonce, + const GURL& url) const; + private: class NetworkContextHttpAuthPreferences : public net::HttpAuthPreferences { public: @@ -968,6 +980,21 @@ scoped_refptr<MojoBackendFileOperationsFactory> http_cache_file_operations_factory_; + // A data structure that tracks partition nonces whose network requests + // should be blocked, for fenced frames network revocation. + // https://github.com/WICG/fenced-frame/blob/master/explainer/fenced_frames_with_local_unpartitioned_data_access.md#revoking-network-access + // New nonces are inserted by `RevokeNetworkForNonce`, + // and membership is checked with `IsNetworkForNonceAndUrlAllowed`. + std::set<base::UnguessableToken> network_revocation_nonces_; + + // A data structure that tracks urls that should be exempted from network + // revocation, to facilitate testing. + // New urls are inserted by + // `ExemptUrlFromNetworkRevocationForNonce` + // and membership is checked with `IsNetworkForNonceAndUrlAllowed`. + std::map<base::UnguessableToken, std::set<GURL>> + network_revocation_exemptions_; + SEQUENCE_CHECKER(sequence_checker_); base::WeakPtrFactory<NetworkContext> weak_factory_{this};
diff --git a/services/network/network_context_unittest.cc b/services/network/network_context_unittest.cc index aaff061..6d3382b4 100644 --- a/services/network/network_context_unittest.cc +++ b/services/network/network_context_unittest.cc
@@ -237,15 +237,17 @@ // If |site_for_cookies| is null, any non-empty NIK is fine. Otherwise, the // NIK must be consistent with |site_for_cookies|. - if (request.site_for_cookies.IsNull()) { - params->isolation_info = net::IsolationInfo::Create( - net::IsolationInfo::RequestType::kOther, - url::Origin::Create(GURL(kTopFrameOriginForFetchRequest)), - url::Origin::Create(GURL(kFrameOriginForFetchRequest)), - request.site_for_cookies); - } else { - params->isolation_info = net::IsolationInfo::CreateForInternalRequest( - url::Origin::Create(request.site_for_cookies.RepresentativeUrl())); + if (params->isolation_info.IsEmpty()) { + if (request.site_for_cookies.IsNull()) { + params->isolation_info = net::IsolationInfo::Create( + net::IsolationInfo::RequestType::kOther, + url::Origin::Create(GURL(kTopFrameOriginForFetchRequest)), + url::Origin::Create(GURL(kFrameOriginForFetchRequest)), + request.site_for_cookies); + } else { + params->isolation_info = net::IsolationInfo::CreateForInternalRequest( + url::Origin::Create(request.site_for_cookies.RepresentativeUrl())); + } } network_context->CreateURLLoaderFactory( @@ -7834,6 +7836,281 @@ AssertBadMessage(); } +TEST_F(NetworkContextTest, RevokeNetworkForNonceTest) { + std::unique_ptr<NetworkContext> network_context = + CreateContextWithParams(CreateNetworkContextParamsForTesting()); + + const base::UnguessableToken nonce1 = base::UnguessableToken::Create(); + const base::UnguessableToken nonce2 = base::UnguessableToken::Create(); + + const GURL kFooHttpsUrl = GURL("https://foo.com"); + + // Revoke nonce1 but not nonce2. + { + base::test::TestFuture<void> revoked; + network_context->RevokeNetworkForNonce( + nonce1, base::BindOnce(revoked.GetCallback())); + EXPECT_TRUE(revoked.Wait()); + EXPECT_FALSE( + network_context->IsNetworkForNonceAndUrlAllowed(nonce1, kFooHttpsUrl)); + EXPECT_TRUE( + network_context->IsNetworkForNonceAndUrlAllowed(nonce2, kFooHttpsUrl)); + } + + // Redundant revocations should have no effect. + { + base::test::TestFuture<void> revoked; + network_context->RevokeNetworkForNonce( + nonce1, base::BindOnce(revoked.GetCallback())); + EXPECT_TRUE(revoked.Wait()); + EXPECT_FALSE( + network_context->IsNetworkForNonceAndUrlAllowed(nonce1, kFooHttpsUrl)); + EXPECT_TRUE( + network_context->IsNetworkForNonceAndUrlAllowed(nonce2, kFooHttpsUrl)); + } + + // Revoke nonce2 too. + { + base::test::TestFuture<void> revoked; + network_context->RevokeNetworkForNonce( + nonce2, base::BindOnce(revoked.GetCallback())); + EXPECT_TRUE(revoked.Wait()); + EXPECT_FALSE( + network_context->IsNetworkForNonceAndUrlAllowed(nonce1, kFooHttpsUrl)); + EXPECT_FALSE( + network_context->IsNetworkForNonceAndUrlAllowed(nonce2, kFooHttpsUrl)); + } +} + +TEST_F(NetworkContextTest, RevokeNetworkForNonceDisablesNewRequestsTest) { + net::test_server::EmbeddedTestServer test_server( + net::test_server::EmbeddedTestServer::TYPE_HTTPS); + test_server.AddDefaultHandlers( + base::FilePath(FILE_PATH_LITERAL("services/test/data"))); + ASSERT_TRUE(test_server.Start()); + GURL server_url = test_server.GetURL("/echo"); + + std::unique_ptr<NetworkContext> network_context = + CreateContextWithParams(CreateNetworkContextParamsForTesting()); + + const base::UnguessableToken nonce = base::UnguessableToken::Create(); + const base::UnguessableToken nonce2 = base::UnguessableToken::Create(); + ResourceRequest request; + request.url = server_url; + + // A nonced network request should initially succeed. + { + auto params = mojom::URLLoaderFactoryParams::New(); + params->isolation_info = + net::IsolationInfo::CreateTransientWithNonce(nonce); + std::unique_ptr<TestURLLoaderClient> client = + FetchRequest(request, network_context.get(), mojom::kURLLoadOptionNone, + mojom::kBrowserProcessId, std::move(params)); + EXPECT_EQ(net::OK, client->completion_status().error_code); + } + + { + base::test::TestFuture<void> revoked; + network_context->RevokeNetworkForNonce( + nonce, base::BindOnce(revoked.GetCallback())); + EXPECT_TRUE(revoked.Wait()); + EXPECT_FALSE( + network_context->IsNetworkForNonceAndUrlAllowed(nonce, server_url)); + } + + // After revoking network for the nonce, the request should fail with + // NETWORK_ACCESS_REVOKED. + { + auto params = mojom::URLLoaderFactoryParams::New(); + params->isolation_info = + net::IsolationInfo::CreateTransientWithNonce(nonce); + std::unique_ptr<TestURLLoaderClient> client = + FetchRequest(request, network_context.get(), mojom::kURLLoadOptionNone, + mojom::kBrowserProcessId, std::move(params)); + EXPECT_EQ(net::ERR_NETWORK_ACCESS_REVOKED, + client->completion_status().error_code); + } + + { + base::test::TestFuture<void> exempted; + network_context->ExemptUrlFromNetworkRevocationForNonce( + GURL(server_url), nonce, base::BindOnce(exempted.GetCallback())); + EXPECT_TRUE(exempted.Wait()); + } + + // After exempting the url, the request should succeed even though the nonce + // is revoked. + { + auto params = mojom::URLLoaderFactoryParams::New(); + params->is_trusted = true; + params->isolation_info = + net::IsolationInfo::CreateTransientWithNonce(nonce); + std::unique_ptr<TestURLLoaderClient> client = + FetchRequest(request, network_context.get(), mojom::kURLLoadOptionNone, + mojom::kBrowserProcessId, std::move(params)); + EXPECT_EQ(net::OK, client->completion_status().error_code); + } + + // But the exemption should have no effect on other nonces. + { + base::test::TestFuture<void> revoked; + network_context->RevokeNetworkForNonce( + nonce2, base::BindOnce(revoked.GetCallback())); + EXPECT_TRUE(revoked.Wait()); + EXPECT_FALSE( + network_context->IsNetworkForNonceAndUrlAllowed(nonce2, server_url)); + } + { + auto params = mojom::URLLoaderFactoryParams::New(); + params->isolation_info = + net::IsolationInfo::CreateTransientWithNonce(nonce2); + std::unique_ptr<TestURLLoaderClient> client = + FetchRequest(request, network_context.get(), mojom::kURLLoadOptionNone, + mojom::kBrowserProcessId, std::move(params)); + EXPECT_EQ(net::ERR_NETWORK_ACCESS_REVOKED, + client->completion_status().error_code); + } +} + +// ExemptUrlFromNetworkRevocationForNonce(exempted_url, nonce) exempts +// future requests that have the same "url without filename" as `exempted_url` +// under the nonce `nonce`. +TEST_F(NetworkContextTest, ExemptUrlFromNetworkRevocationForNonceTest) { + std::unique_ptr<NetworkContext> network_context = + CreateContextWithParams(CreateNetworkContextParamsForTesting()); + + const std::string kFooHttpsUrl = "https://foo.com"; + const std::string kFooHttpUrl = "http://foo.com"; + const std::string kBarHttpsUrl = "https://bar.com"; + + const base::UnguessableToken nonce = base::UnguessableToken::Create(); + const base::UnguessableToken nonce2 = base::UnguessableToken::Create(); + + // For `nonce` exempt kFooHttpsUrl but not kBarHttpsUrl. + { + base::test::TestFuture<void> exempted; + network_context->ExemptUrlFromNetworkRevocationForNonce( + GURL(kFooHttpsUrl), nonce, base::BindOnce(exempted.GetCallback())); + EXPECT_TRUE(exempted.Wait()); + } + // Since `nonce` isn't revoked yet, everything should be allowed. + EXPECT_TRUE(network_context->IsNetworkForNonceAndUrlAllowed( + nonce, GURL(kFooHttpsUrl))); + EXPECT_TRUE(network_context->IsNetworkForNonceAndUrlAllowed( + nonce, GURL(kFooHttpsUrl + "?baz=qux"))); + EXPECT_TRUE(network_context->IsNetworkForNonceAndUrlAllowed( + nonce, GURL(kFooHttpsUrl + "#section"))); + EXPECT_TRUE(network_context->IsNetworkForNonceAndUrlAllowed( + nonce, GURL(kFooHttpsUrl + "/baz/qux.html"))); + EXPECT_TRUE(network_context->IsNetworkForNonceAndUrlAllowed( + nonce, GURL(kFooHttpUrl))); + EXPECT_TRUE(network_context->IsNetworkForNonceAndUrlAllowed( + nonce, GURL(kBarHttpsUrl))); + + // Revoke `nonce`. + { + base::test::TestFuture<void> revoked; + network_context->RevokeNetworkForNonce( + nonce, base::BindOnce(revoked.GetCallback())); + EXPECT_TRUE(revoked.Wait()); + } + // Now for `nonce` kFooHttpsUrl should be exempted, but kBarHttpsUrl blocked. + EXPECT_TRUE(network_context->IsNetworkForNonceAndUrlAllowed( + nonce, GURL(kFooHttpsUrl))); + EXPECT_TRUE(network_context->IsNetworkForNonceAndUrlAllowed( + nonce, GURL(kFooHttpsUrl + "?baz=qux"))); + EXPECT_TRUE(network_context->IsNetworkForNonceAndUrlAllowed( + nonce, GURL(kFooHttpsUrl + "#section"))); + EXPECT_FALSE(network_context->IsNetworkForNonceAndUrlAllowed( + nonce, GURL(kFooHttpsUrl + "/baz/qux.html"))); + EXPECT_FALSE(network_context->IsNetworkForNonceAndUrlAllowed( + nonce, GURL(kFooHttpUrl))); + EXPECT_FALSE(network_context->IsNetworkForNonceAndUrlAllowed( + nonce, GURL(kBarHttpsUrl))); + + // Redundant exemptions should have no effect. + { + base::test::TestFuture<void> exempted; + network_context->ExemptUrlFromNetworkRevocationForNonce( + GURL(kFooHttpsUrl), nonce, base::BindOnce(exempted.GetCallback())); + EXPECT_TRUE(exempted.Wait()); + } + EXPECT_TRUE(network_context->IsNetworkForNonceAndUrlAllowed( + nonce, GURL(kFooHttpsUrl))); + EXPECT_TRUE(network_context->IsNetworkForNonceAndUrlAllowed( + nonce, GURL(kFooHttpsUrl + "?baz=qux"))); + EXPECT_TRUE(network_context->IsNetworkForNonceAndUrlAllowed( + nonce, GURL(kFooHttpsUrl + "#section"))); + EXPECT_FALSE(network_context->IsNetworkForNonceAndUrlAllowed( + nonce, GURL(kFooHttpsUrl + "/baz/qux.html"))); + EXPECT_FALSE(network_context->IsNetworkForNonceAndUrlAllowed( + nonce, GURL(kFooHttpUrl))); + EXPECT_FALSE(network_context->IsNetworkForNonceAndUrlAllowed( + nonce, GURL(kBarHttpsUrl))); + + // For `nonce` exempt a file rooted at kBarHttpsUrl too. + { + base::test::TestFuture<void> exempted; + network_context->ExemptUrlFromNetworkRevocationForNonce( + GURL(kBarHttpsUrl + "/baz/qux.html?a=b"), nonce, + base::BindOnce(exempted.GetCallback())); + EXPECT_TRUE(exempted.Wait()); + } + EXPECT_TRUE(network_context->IsNetworkForNonceAndUrlAllowed( + nonce, GURL(kFooHttpsUrl))); + EXPECT_FALSE(network_context->IsNetworkForNonceAndUrlAllowed( + nonce, GURL(kBarHttpsUrl))); + EXPECT_TRUE(network_context->IsNetworkForNonceAndUrlAllowed( + nonce, GURL(kBarHttpsUrl + "/baz/qux.html?c=d"))); + EXPECT_FALSE(network_context->IsNetworkForNonceAndUrlAllowed( + nonce, GURL(kBarHttpsUrl + "/baz"))); + EXPECT_TRUE(network_context->IsNetworkForNonceAndUrlAllowed( + nonce, GURL(kBarHttpsUrl + "/baz/"))); + EXPECT_TRUE(network_context->IsNetworkForNonceAndUrlAllowed( + nonce, GURL(kBarHttpsUrl + "/baz/corge.html"))); + + // Revoke `nonce2`. + { + base::test::TestFuture<void> revoked; + network_context->RevokeNetworkForNonce( + nonce2, base::BindOnce(revoked.GetCallback())); + EXPECT_TRUE(revoked.Wait()); + } + // Nothing should be exempted for `nonce2`. + EXPECT_FALSE(network_context->IsNetworkForNonceAndUrlAllowed( + nonce2, GURL(kFooHttpsUrl))); + EXPECT_FALSE(network_context->IsNetworkForNonceAndUrlAllowed( + nonce2, GURL(kFooHttpsUrl + "?baz=qux"))); + EXPECT_FALSE(network_context->IsNetworkForNonceAndUrlAllowed( + nonce2, GURL(kFooHttpsUrl + "#section"))); + EXPECT_FALSE(network_context->IsNetworkForNonceAndUrlAllowed( + nonce2, GURL(kFooHttpsUrl + "/baz/qux.html"))); + EXPECT_FALSE(network_context->IsNetworkForNonceAndUrlAllowed( + nonce2, GURL(kFooHttpUrl))); + EXPECT_FALSE(network_context->IsNetworkForNonceAndUrlAllowed( + nonce2, GURL(kBarHttpsUrl))); + + // Exempt kFooHttpsUrl for `nonce2`. + { + base::test::TestFuture<void> exempted; + network_context->ExemptUrlFromNetworkRevocationForNonce( + GURL(kFooHttpsUrl), nonce, base::BindOnce(exempted.GetCallback())); + EXPECT_TRUE(exempted.Wait()); + } + EXPECT_TRUE(network_context->IsNetworkForNonceAndUrlAllowed( + nonce, GURL(kFooHttpsUrl))); + EXPECT_TRUE(network_context->IsNetworkForNonceAndUrlAllowed( + nonce, GURL(kFooHttpsUrl + "?baz=qux"))); + EXPECT_TRUE(network_context->IsNetworkForNonceAndUrlAllowed( + nonce, GURL(kFooHttpsUrl + "#section"))); + EXPECT_FALSE(network_context->IsNetworkForNonceAndUrlAllowed( + nonce, GURL(kFooHttpsUrl + "/baz/qux.html"))); + EXPECT_FALSE(network_context->IsNetworkForNonceAndUrlAllowed( + nonce, GURL(kFooHttpUrl))); + EXPECT_FALSE(network_context->IsNetworkForNonceAndUrlAllowed( + nonce, GURL(kBarHttpsUrl))); +} + class NetworkContextBrowserCookieTest : public NetworkContextTest, public testing::WithParamInterface</*should_add_browser_cookies=*/bool> {
diff --git a/services/network/public/mojom/network_context.mojom b/services/network/public/mojom/network_context.mojom index e6b9d32..c774dfc 100644 --- a/services/network/public/mojom/network_context.mojom +++ b/services/network/public/mojom/network_context.mojom
@@ -1657,4 +1657,18 @@ // Sets cookie deprecation label. SetCookieDeprecationLabel(string? label); + + // Register that all network requests with `nonce` as their partition nonce + // should be blocked. + // Used for fenced frames network revocation: + // https://github.com/WICG/fenced-frame/blob/master/explainer/fenced_frames_with_local_unpartitioned_data_access.md#revoking-network-access + RevokeNetworkForNonce(mojo_base.mojom.UnguessableToken nonce) => (); + + // Register that network requests operating under the nonce `nonce` whose url + // without filename is `exempted_url` should be exempt from network + // revocation. This can be called before network is revoked for `nonce` with + // `RevokeNetworkForNonce`, and it will store the exemption so that it can + // take effect afterwards. + ExemptUrlFromNetworkRevocationForNonce( + url.mojom.Url exempted_url, mojo_base.mojom.UnguessableToken nonce) => (); };
diff --git a/services/network/test/test_network_context.h b/services/network/test/test_network_context.h index 73cfd54..5868a904 100644 --- a/services/network/test/test_network_context.h +++ b/services/network/test/test_network_context.h
@@ -340,6 +340,12 @@ const scoped_refptr<net::X509Certificate>& certificate) override {} void SetCookieDeprecationLabel( const std::optional<std::string>& label) override {} + void RevokeNetworkForNonce(const base::UnguessableToken& nonce, + RevokeNetworkForNonceCallback callback) override {} + void ExemptUrlFromNetworkRevocationForNonce( + const GURL& exempted_url, + const base::UnguessableToken& nonce, + ExemptUrlFromNetworkRevocationForNonceCallback callback) override {} }; } // namespace network
diff --git a/services/screen_ai/public/cpp/utilities.cc b/services/screen_ai/public/cpp/utilities.cc index 67ab80cb..a420fa7 100644 --- a/services/screen_ai/public/cpp/utilities.cc +++ b/services/screen_ai/public/cpp/utilities.cc
@@ -96,6 +96,9 @@ } #endif // BUILDFLAG(ENABLE_SCREEN_AI_BROWSERTESTS) +#if BUILDFLAG(IS_CHROMEOS) + return base::FilePath::FromASCII(kScreenAIDlcRootPath); +#else base::FilePath components_dir; if (!base::PathService::Get(component_updater::DIR_COMPONENT_USER, &components_dir) || @@ -104,45 +107,11 @@ } return components_dir.Append(kScreenAISubDirName); -} - -base::FilePath GetLatestComponentPath() { -#if BUILDFLAG(ENABLE_SCREEN_AI_BROWSERTESTS) - if (features::IsScreenAITestModeEnabled()) { - CHECK_IS_TEST(); - return GetComponentDir(); - } -#endif // BUILDFLAG(ENABLE_SCREEN_AI_BROWSERTESTS) - - base::FilePath latest_version_dir; -#if BUILDFLAG(IS_CHROMEOS) - latest_version_dir = base::FilePath::FromASCII(kScreenAIDlcRootPath); -#else - base::FilePath screen_ai_dir = GetComponentDir(); - if (screen_ai_dir.empty()) - return base::FilePath(); - - // Get latest version. - base::FileEnumerator enumerator(screen_ai_dir, - /*recursive=*/false, - base::FileEnumerator::DIRECTORIES); - base::Version latest_version; - for (base::FilePath version_dir = enumerator.Next(); !version_dir.empty(); - version_dir = enumerator.Next()) { - base::Version this_version(version_dir.BaseName().AsUTF8Unsafe()); - if (this_version.IsValid() && - (!latest_version.IsValid() || this_version > latest_version)) { - latest_version = std::move(this_version); - latest_version_dir = std::move(version_dir); - } - } #endif - - return latest_version_dir; } -base::FilePath GetLatestComponentBinaryPath() { - base::FilePath component_path = GetLatestComponentPath(); +base::FilePath GetComponentBinaryPathForTests() { + base::FilePath component_path = GetComponentDir(); if (component_path.empty()) { return component_path;
diff --git a/services/screen_ai/public/cpp/utilities.h b/services/screen_ai/public/cpp/utilities.h index 5fd7524..0b30fc4 100644 --- a/services/screen_ai/public/cpp/utilities.h +++ b/services/screen_ai/public/cpp/utilities.h
@@ -9,16 +9,9 @@ namespace screen_ai { -// Returns the absolute path of the highest-versioned component directory. -// TODO(crbug.com/329755916): This function is deprecated, remove. -base::FilePath GetLatestComponentPath(); - -// Get the absolute path of the ScreenAI component. This function verifies that -// the binary exists on disk and can be opened. It may return empty if some -// other piece of software has opened the binary file with restrictive -// permissions (e.g., "security" software or malware protection). -// TODO(crbug.com/329755916): This function is deprecated, remove. -base::FilePath GetLatestComponentBinaryPath(); +// Get the absolute path of the ScreenAI component binary for tests. This +// function verifies that the binary exists on disk and can be opened. +base::FilePath GetComponentBinaryPathForTests(); // Returns the install directory relative to components folder. base::FilePath GetRelativeInstallDir();
diff --git a/testing/buildbot/autoshard_exceptions.json b/testing/buildbot/autoshard_exceptions.json index 2af911ba..616dd34 100644 --- a/testing/buildbot/autoshard_exceptions.json +++ b/testing/buildbot/autoshard_exceptions.json
@@ -310,63 +310,63 @@ }, "lacros_chrome_browsertests Lacros version skew testing ash beta": { "debug": { - "avg_num_builds_per_peak_hour": 88, - "estimated_bot_hour_delta": -1.64, - "prev_avg_pending_time_sec": 49.2, + "avg_num_builds_per_peak_hour": 101, + "estimated_bot_hour_delta": 1.43, + "prev_avg_pending_time_sec": 45.7, "prev_p50_pending_time_sec": 1.0, - "prev_p90_pending_time_sec": 168.0, - "prev_percentile_duration_minutes": 12.35, - "prev_shard_count": 6, - "simulated_max_shard_duration": 14.82, - "test_overhead_min": 1.1166666666666667, + "prev_p90_pending_time_sec": 146.0, + "prev_percentile_duration_minutes": 16.48, + "prev_shard_count": 5, + "simulated_max_shard_duration": 13.88, + "test_overhead_min": 0.85, "try_builder": "linux-lacros-rel" }, - "shards": 5 + "shards": 6 }, "lacros_chrome_browsertests Lacros version skew testing ash canary": { "debug": { - "avg_num_builds_per_peak_hour": 88, - "estimated_bot_hour_delta": -1.69, - "prev_avg_pending_time_sec": 48.8, + "avg_num_builds_per_peak_hour": 101, + "estimated_bot_hour_delta": 1.29, + "prev_avg_pending_time_sec": 45.3, "prev_p50_pending_time_sec": 1.0, - "prev_p90_pending_time_sec": 167.0, - "prev_percentile_duration_minutes": 12.38, - "prev_shard_count": 6, - "simulated_max_shard_duration": 14.86, - "test_overhead_min": 1.15, + "prev_p90_pending_time_sec": 144.0, + "prev_percentile_duration_minutes": 16.54, + "prev_shard_count": 5, + "simulated_max_shard_duration": 13.91, + "test_overhead_min": 0.7666666666666667, "try_builder": "linux-lacros-rel" }, - "shards": 5 + "shards": 6 }, "lacros_chrome_browsertests Lacros version skew testing ash dev": { "debug": { - "avg_num_builds_per_peak_hour": 88, - "estimated_bot_hour_delta": -1.52, - "prev_avg_pending_time_sec": 48.6, + "avg_num_builds_per_peak_hour": 101, + "estimated_bot_hour_delta": 1.4, + "prev_avg_pending_time_sec": 45.2, "prev_p50_pending_time_sec": 1.0, - "prev_p90_pending_time_sec": 167.0, - "prev_percentile_duration_minutes": 12.36, - "prev_shard_count": 6, - "simulated_max_shard_duration": 14.83, - "test_overhead_min": 1.0333333333333334, + "prev_p90_pending_time_sec": 143.0, + "prev_percentile_duration_minutes": 16.51, + "prev_shard_count": 5, + "simulated_max_shard_duration": 13.9, + "test_overhead_min": 0.8333333333333334, "try_builder": "linux-lacros-rel" }, - "shards": 5 + "shards": 6 }, "lacros_chrome_browsertests Lacros version skew testing ash stable": { "debug": { - "avg_num_builds_per_peak_hour": 88, - "estimated_bot_hour_delta": -1.59, - "prev_avg_pending_time_sec": 48.6, + "avg_num_builds_per_peak_hour": 101, + "estimated_bot_hour_delta": 1.46, + "prev_avg_pending_time_sec": 45.2, "prev_p50_pending_time_sec": 1.0, - "prev_p90_pending_time_sec": 166.0, - "prev_percentile_duration_minutes": 12.34, - "prev_shard_count": 6, - "simulated_max_shard_duration": 14.81, - "test_overhead_min": 1.0833333333333333, + "prev_p90_pending_time_sec": 143.0, + "prev_percentile_duration_minutes": 16.44, + "prev_shard_count": 5, + "simulated_max_shard_duration": 13.84, + "test_overhead_min": 0.8666666666666667, "try_builder": "linux-lacros-rel" }, - "shards": 5 + "shards": 6 } } }, @@ -700,17 +700,18 @@ "Win10 Tests x64": { "content_browsertests": { "debug": { - "avg_num_builds_per_peak_hour": "71.0", - "estimated_bot_hour_delta": "-5.43", - "prev_avg_pending_time_sec": "194.8", - "prev_p50_pending_time_sec": "77.0", - "prev_p90_pending_time_sec": "599.0", - "prev_percentile_duration_minutes": "12.62", - "prev_shard_count": "12", - "simulated_max_shard_duration": "15.14", + "avg_num_builds_per_peak_hour": 101, + "estimated_bot_hour_delta": -0.76, + "prev_avg_pending_time_sec": 98.6, + "prev_p50_pending_time_sec": 3.0, + "prev_p90_pending_time_sec": 291.0, + "prev_percentile_duration_minutes": 13.29, + "prev_shard_count": 10, + "simulated_max_shard_duration": 14.72, + "test_overhead_min": 0.45, "try_builder": "win-rel" }, - "shards": "10" + "shards": 9 }, "updater_tests_system": { "debug": {
diff --git a/testing/buildbot/chromium.chromiumos.json b/testing/buildbot/chromium.chromiumos.json index 9b71f9c..f466416 100644 --- a/testing/buildbot/chromium.chromiumos.json +++ b/testing/buildbot/chromium.chromiumos.json
@@ -5616,7 +5616,7 @@ "os": "Ubuntu-22.04" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 5 + "shards": 6 }, "test": "lacros_chrome_browsertests", "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests/", @@ -5646,7 +5646,7 @@ "os": "Ubuntu-22.04" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 5 + "shards": 6 }, "test": "lacros_chrome_browsertests", "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests/", @@ -5676,7 +5676,7 @@ "os": "Ubuntu-22.04" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 5 + "shards": 6 }, "test": "lacros_chrome_browsertests", "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests/", @@ -5706,7 +5706,7 @@ "os": "Ubuntu-22.04" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 5 + "shards": 6 }, "test": "lacros_chrome_browsertests", "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests/",
diff --git a/testing/buildbot/chromium.gpu.fyi.json b/testing/buildbot/chromium.gpu.fyi.json index f5eb261e..653a63b 100644 --- a/testing/buildbot/chromium.gpu.fyi.json +++ b/testing/buildbot/chromium.gpu.fyi.json
@@ -6566,7 +6566,6 @@ "os": "Ubuntu-22.04.3", "pool": "chromium.tests.gpu" }, - "expiration": 21600, "hard_timeout": 1800, "idempotent": false, "io_timeout": 1800, @@ -7577,7 +7576,6 @@ "os": "Ubuntu-22.04.3", "pool": "chromium.tests.gpu" }, - "expiration": 21600, "hard_timeout": 1800, "io_timeout": 1800, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -7604,7 +7602,6 @@ "os": "Ubuntu-22.04.3", "pool": "chromium.tests.gpu" }, - "expiration": 21600, "hard_timeout": 1800, "io_timeout": 1800, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", @@ -7635,7 +7632,6 @@ "os": "Ubuntu-22.04.3", "pool": "chromium.tests.gpu" }, - "expiration": 21600, "hard_timeout": 1800, "io_timeout": 1800, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -7658,7 +7654,6 @@ "os": "Ubuntu-22.04.3", "pool": "chromium.tests.gpu" }, - "expiration": 21600, "hard_timeout": 1800, "io_timeout": 1800, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -7685,7 +7680,6 @@ "os": "Ubuntu-22.04.3", "pool": "chromium.tests.gpu" }, - "expiration": 21600, "hard_timeout": 1800, "io_timeout": 1800, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -7709,7 +7703,6 @@ "os": "Ubuntu-22.04.3", "pool": "chromium.tests.gpu" }, - "expiration": 21600, "hard_timeout": 1800, "io_timeout": 1800, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -7746,7 +7739,6 @@ "os": "Ubuntu-22.04.3", "pool": "chromium.tests.gpu" }, - "expiration": 21600, "hard_timeout": 1800, "idempotent": false, "io_timeout": 1800, @@ -7790,7 +7782,6 @@ "os": "Ubuntu-22.04.3", "pool": "chromium.tests.gpu" }, - "expiration": 21600, "hard_timeout": 1800, "idempotent": false, "io_timeout": 1800, @@ -7825,7 +7816,6 @@ "os": "Ubuntu-22.04.3", "pool": "chromium.tests.gpu" }, - "expiration": 21600, "hard_timeout": 1800, "idempotent": false, "io_timeout": 1800, @@ -7860,7 +7850,6 @@ "os": "Ubuntu-22.04.3", "pool": "chromium.tests.gpu" }, - "expiration": 21600, "hard_timeout": 1800, "idempotent": false, "io_timeout": 1800, @@ -7899,7 +7888,6 @@ "os": "Ubuntu-22.04.3", "pool": "chromium.tests.gpu" }, - "expiration": 21600, "hard_timeout": 1800, "idempotent": false, "io_timeout": 1800, @@ -7944,7 +7932,6 @@ "os": "Ubuntu-22.04.3", "pool": "chromium.tests.gpu" }, - "expiration": 21600, "hard_timeout": 1800, "idempotent": false, "io_timeout": 1800, @@ -7980,7 +7967,6 @@ "os": "Ubuntu-22.04.3", "pool": "chromium.tests.gpu" }, - "expiration": 21600, "hard_timeout": 1800, "idempotent": false, "io_timeout": 1800, @@ -8016,7 +8002,6 @@ "os": "Ubuntu-22.04.3", "pool": "chromium.tests.gpu" }, - "expiration": 21600, "hard_timeout": 1800, "idempotent": false, "io_timeout": 1800, @@ -8054,7 +8039,6 @@ "os": "Ubuntu-22.04.3", "pool": "chromium.tests.gpu" }, - "expiration": 21600, "hard_timeout": 1800, "idempotent": false, "io_timeout": 1800, @@ -8092,7 +8076,6 @@ "os": "Ubuntu-22.04.3", "pool": "chromium.tests.gpu" }, - "expiration": 21600, "hard_timeout": 1800, "idempotent": false, "io_timeout": 1800, @@ -24955,7 +24938,6 @@ "os": "Windows-10-19045.3930", "pool": "chromium.tests.gpu" }, - "expiration": 21600, "hard_timeout": 1800, "io_timeout": 1800, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -24982,7 +24964,6 @@ "os": "Windows-10-19045.3930", "pool": "chromium.tests.gpu" }, - "expiration": 21600, "hard_timeout": 1800, "io_timeout": 1800, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", @@ -25014,7 +24995,6 @@ "os": "Windows-10-19045.3930", "pool": "chromium.tests.gpu" }, - "expiration": 21600, "hard_timeout": 1800, "io_timeout": 1800, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -25039,7 +25019,6 @@ "os": "Windows-10-19045.3930", "pool": "chromium.tests.gpu" }, - "expiration": 21600, "hard_timeout": 1800, "io_timeout": 1800, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -25065,7 +25044,6 @@ "os": "Windows-10-19045.3930", "pool": "chromium.tests.gpu" }, - "expiration": 21600, "hard_timeout": 1800, "io_timeout": 1800, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -25089,7 +25067,6 @@ "os": "Windows-10-19045.3930", "pool": "chromium.tests.gpu" }, - "expiration": 21600, "hard_timeout": 1800, "io_timeout": 1800, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -25110,7 +25087,6 @@ "os": "Windows-10-19045.3930", "pool": "chromium.tests.gpu" }, - "expiration": 21600, "hard_timeout": 1800, "io_timeout": 1800, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -25135,7 +25111,6 @@ "os": "Windows-10-19045.3930", "pool": "chromium.tests.gpu" }, - "expiration": 21600, "hard_timeout": 1800, "io_timeout": 1800, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -25162,7 +25137,6 @@ "os": "Windows-10-19045.3930", "pool": "chromium.tests.gpu" }, - "expiration": 21600, "hard_timeout": 1800, "io_timeout": 1800, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -25186,7 +25160,6 @@ "os": "Windows-10-19045.3930", "pool": "chromium.tests.gpu" }, - "expiration": 21600, "hard_timeout": 1800, "io_timeout": 1800, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -25224,7 +25197,6 @@ "os": "Windows-10-19045.3930", "pool": "chromium.tests.gpu" }, - "expiration": 21600, "hard_timeout": 1800, "idempotent": false, "io_timeout": 1800, @@ -25269,7 +25241,6 @@ "os": "Windows-10-19045.3930", "pool": "chromium.tests.gpu" }, - "expiration": 21600, "hard_timeout": 1800, "idempotent": false, "io_timeout": 1800, @@ -25305,7 +25276,6 @@ "os": "Windows-10-19045.3930", "pool": "chromium.tests.gpu" }, - "expiration": 21600, "hard_timeout": 1800, "idempotent": false, "io_timeout": 1800, @@ -25341,7 +25311,6 @@ "os": "Windows-10-19045.3930", "pool": "chromium.tests.gpu" }, - "expiration": 21600, "hard_timeout": 1800, "idempotent": false, "io_timeout": 1800, @@ -25381,7 +25350,6 @@ "os": "Windows-10-19045.3930", "pool": "chromium.tests.gpu" }, - "expiration": 21600, "hard_timeout": 1800, "idempotent": false, "io_timeout": 1800, @@ -25427,7 +25395,6 @@ "os": "Windows-10-19045.3930", "pool": "chromium.tests.gpu" }, - "expiration": 21600, "hard_timeout": 1800, "idempotent": false, "io_timeout": 1800, @@ -25464,7 +25431,6 @@ "os": "Windows-10-19045.3930", "pool": "chromium.tests.gpu" }, - "expiration": 21600, "hard_timeout": 1800, "idempotent": false, "io_timeout": 1800, @@ -25501,7 +25467,6 @@ "os": "Windows-10-19045.3930", "pool": "chromium.tests.gpu" }, - "expiration": 21600, "hard_timeout": 1800, "idempotent": false, "io_timeout": 1800, @@ -25538,7 +25503,6 @@ "os": "Windows-10-19045.3930", "pool": "chromium.tests.gpu" }, - "expiration": 21600, "hard_timeout": 1800, "idempotent": false, "io_timeout": 1800, @@ -25577,7 +25541,6 @@ "os": "Windows-10-19045.3930", "pool": "chromium.tests.gpu" }, - "expiration": 21600, "hard_timeout": 1800, "idempotent": false, "io_timeout": 1800, @@ -25616,7 +25579,6 @@ "os": "Windows-10-19045.3930", "pool": "chromium.tests.gpu" }, - "expiration": 21600, "hard_timeout": 1800, "idempotent": false, "io_timeout": 1800, @@ -25655,7 +25617,6 @@ "os": "Windows-10-19045.3930", "pool": "chromium.tests.gpu" }, - "expiration": 21600, "hard_timeout": 1800, "idempotent": false, "io_timeout": 1800,
diff --git a/testing/buildbot/chromium.win.json b/testing/buildbot/chromium.win.json index a3e90d086..58011755 100644 --- a/testing/buildbot/chromium.win.json +++ b/testing/buildbot/chromium.win.json
@@ -539,7 +539,7 @@ "os": "Windows-10-19045" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 10 + "shards": 9 }, "test": "content_browsertests", "test_id_prefix": "ninja://content/test:content_browsertests/"
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl index 024e29a..ebb0295 100644 --- a/testing/buildbot/waterfalls.pyl +++ b/testing/buildbot/waterfalls.pyl
@@ -4283,7 +4283,6 @@ 'os_type': 'lacros', 'browser_config': 'release', 'mixins': [ - 'limited_capacity_bot', 'linux_amd_rx_5500_xt', ], 'test_suites': { @@ -4355,11 +4354,7 @@ 'Linux FYI Release (AMD RX 5500 XT)': { 'os_type': 'linux', 'browser_config': 'release', - # There are only two bots of this type in the Swarming pool right now, - # so we have to increase the default expiration time of 1 hour - # to prevent webgl2_conformance_tests' shards from timing out. 'mixins': [ - 'limited_capacity_bot', 'linux_amd_rx_5500_xt', ], 'test_suites': { @@ -4660,12 +4655,9 @@ }, }, 'Win10 FYI x64 Release (AMD RX 5500 XT)': { - # This bot currently only has two pieces of hardware behind it, - # and is being qualified for potential scale-out. 'os_type': 'win', 'browser_config': 'release_x64', 'mixins': [ - 'limited_capacity_bot', 'win10_amd_rx_5500_xt_stable', ], 'test_suites': {
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index 72a6d03..c9a890f 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -186,23 +186,6 @@ ] } ], - "AccountStorageOnDesktopFollowup": [ - { - "platforms": [ - "linux", - "mac", - "windows" - ], - "experiments": [ - { - "name": "Enabled", - "enable_features": [ - "ButterOnDesktopFollowup" - ] - } - ] - } - ], "AdaptiveChargingParamTuning": [ { "platforms": [ @@ -1929,6 +1912,25 @@ ] } ], + "AutofillUndo": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "AutofillUndo" + ] + } + ] + } + ], "AutofillUploadVotesForFieldsWithEmail": [ { "platforms": [ @@ -2486,27 +2488,6 @@ ] } ], - "BlinkSchedulerPrioritizeNavigationIPCs": [ - { - "platforms": [ - "android", - "android_webview", - "chromeos", - "chromeos_lacros", - "linux", - "mac", - "windows" - ], - "experiments": [ - { - "name": "Enabled", - "enable_features": [ - "BlinkSchedulerPrioritizeNavigationIPCs" - ] - } - ] - } - ], "BlockMidiByDefault": [ { "platforms": [ @@ -2766,6 +2747,23 @@ ] } ], + "ButterOnDesktopFollowup": [ + { + "platforms": [ + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "ButterOnDesktopFollowup" + ] + } + ] + } + ], "CCTMinimized": [ { "platforms": [ @@ -12893,6 +12891,23 @@ ] } ], + "PartitionAllocParameterTuning": [ + { + "platforms": [ + "mac" + ], + "experiments": [ + { + "name": "Enabled_20240318", + "enable_features": [ + "BlinkUseLargeEmptySlotSpanRingForBufferRoot", + "PartitionAllocAdjustSizeWhenInForeground", + "PartitionAllocLargeEmptySlotSpanRing" + ] + } + ] + } + ], "PartitionAllocUnretainedDanglingPtr": [ { "platforms": [ @@ -19003,32 +19018,6 @@ ] } ], - "UseUtilityThreadGroup": [ - { - "platforms": [ - "android", - "android_weblayer", - "android_webview", - "chromeos", - "chromeos_lacros", - "fuchsia", - "ios", - "linux", - "mac", - "windows" - ], - "experiments": [ - { - "name": "Enabled", - "enable_features": [ - "UseUtilityThreadGroup", - "V8ConcurrentMarkingHighPriorityThreads", - "V8ConcurrentSparkplugHighPriorityThreads" - ] - } - ] - } - ], "UseV1MetricsTerminationHoldback": [ { "platforms": [
diff --git a/third_party/angle b/third_party/angle index 21d124c..8080a73 160000 --- a/third_party/angle +++ b/third_party/angle
@@ -1 +1 @@ -Subproject commit 21d124c4bf321a18dae1dc94602aa262fc346a8b +Subproject commit 8080a736f13854f806cb115e6ab78a8f4f33d08e
diff --git a/third_party/beto-core/BUILD.gn b/third_party/beto-core/BUILD.gn index b73ed4b..a30baba 100644 --- a/third_party/beto-core/BUILD.gn +++ b/third_party/beto-core/BUILD.gn
@@ -17,59 +17,72 @@ ":handle_map_unittests", ":ldt_all_tests", ":ldt_c_sample", - ":ldt_ffi_tests", + # ":ldt_ffi_tests", ":lock_adapter_unittests", ":np_adv_examples_v0", ":np_adv_examples_v1", ":np_adv_unittests", - ":np_cpp_tests", - ":np_rust_sample", + # ":np_cpp_tests", + # ":np_rust_sample", ] } -test("np_cpp_tests") { - sources = [ - "src/nearby/presence/np_cpp_ffi/shared/shared_test_util.cc", - "src/nearby/presence/np_cpp_ffi/tests/byte_buffer_tests.cc", - "src/nearby/presence/np_cpp_ffi/tests/credential_book_tests.cc", - "src/nearby/presence/np_cpp_ffi/tests/credential_slab_tests.cc", - "src/nearby/presence/np_cpp_ffi/tests/deserialize_result_tests.cc", - "src/nearby/presence/np_cpp_ffi/tests/np_cpp_test.cc", - "src/nearby/presence/np_cpp_ffi/tests/np_cpp_test.h", - "src/nearby/presence/np_cpp_ffi/tests/v0_encrypted_deserialization_tests.cc", - "src/nearby/presence/np_cpp_ffi/tests/v0_encrypted_serialization_tests.cc", - "src/nearby/presence/np_cpp_ffi/tests/v0_unencrypted_deserialization_tests.cc", - "src/nearby/presence/np_cpp_ffi/tests/v0_unencrypted_serialization_tests.cc", - "src/nearby/presence/np_cpp_ffi/tests/v1_encrypted_deserialization_tests.cc", - "src/nearby/presence/np_cpp_ffi/tests/v1_unencrypted_deserialization_tests.cc", - ] - include_dirs = [ - "src/nearby/presence/np_cpp_ffi/include", - "src/nearby/presence/np_c_ffi/include/cpp", - "src/nearby/presence/np_cpp_ffi/shared", - ] - deps = [ - ":nearby_protocol", - "//base/test:run_all_unittests", - "//testing/gtest", - ] +# TODO(crbug.com/328082374): Fix and remove the -Wno-error flags in these targets +# test("np_cpp_tests") { +# sources = [ +# "src/nearby/presence/np_cpp_ffi/shared/shared_test_util.cc", +# "src/nearby/presence/np_cpp_ffi/tests/byte_buffer_tests.cc", +# "src/nearby/presence/np_cpp_ffi/tests/credential_book_tests.cc", +# "src/nearby/presence/np_cpp_ffi/tests/credential_slab_tests.cc", +# "src/nearby/presence/np_cpp_ffi/tests/deserialize_result_tests.cc", +# "src/nearby/presence/np_cpp_ffi/tests/np_cpp_test.cc", +# "src/nearby/presence/np_cpp_ffi/tests/np_cpp_test.h", +# "src/nearby/presence/np_cpp_ffi/tests/v0_encrypted_deserialization_tests.cc", +# "src/nearby/presence/np_cpp_ffi/tests/v0_encrypted_serialization_tests.cc", +# "src/nearby/presence/np_cpp_ffi/tests/v0_unencrypted_deserialization_tests.cc", +# "src/nearby/presence/np_cpp_ffi/tests/v0_unencrypted_serialization_tests.cc", +# "src/nearby/presence/np_cpp_ffi/tests/v1_encrypted_deserialization_tests.cc", +# "src/nearby/presence/np_cpp_ffi/tests/v1_unencrypted_deserialization_tests.cc", +# ] +# include_dirs = [ +# "src/nearby/presence/np_cpp_ffi/include", +# "src/nearby/presence/np_c_ffi/include/cpp", +# "src/nearby/presence/np_cpp_ffi/shared", +# ] +# deps = [ +# ":nearby_protocol", +# "//base/test:run_all_unittests", +# "//testing/gtest", +# ] - # TODO(crbug.com/328082374): Fix and remove these warnings. - cflags = [ - "-Wno-error=deprecated-declarations", - "-Wno-error=sign-compare", - ] -} +# cflags = [ +# "-Wno-error=deprecated-declarations", +# "-Wno-error=sign-compare", +# ] +# } -executable("np_rust_sample") { - sources = [ "src/nearby/presence/np_cpp_ffi/sample/main.cc" ] - include_dirs = [ - "src/nearby/presence/np_cpp_ffi/include", - "src/nearby/presence/np_c_ffi/include/cpp", - ] - deps = [ ":nearby_protocol" ] - cflags = [ "-Wno-error=deprecated-declarations" ] -} +# executable("np_rust_sample") { +# sources = [ "src/nearby/presence/np_cpp_ffi/sample/main.cc" ] +# include_dirs = [ +# "src/nearby/presence/np_cpp_ffi/include", +# "src/nearby/presence/np_c_ffi/include/cpp", +# ] +# deps = [ ":nearby_protocol" ] +# cflags = [ "-Wno-error=deprecated-declarations" ] +# } + +# test("ldt_ffi_tests") { +# sources = [ "src/nearby/presence/ldt_np_adv_ffi/c/tests/ldt_ffi_tests.cc" ] +# include_dirs = [ "src/nearby/presence/ldt_np_adv_ffi/c/include" ] +# defines = [ "LDT_TEST_VECTORS=\"third_party/beto-core/src/nearby/presence/ldt_np_adv/resources/test/np_adv_test_vectors.json\"" ] +# cflags = [ "-Wno-error=sign-compare" ] +# deps = [ +# ":ldt_np_adv_ffi", +# "//base/test:run_all_unittests", +# "//testing/gtest", +# "//third_party/jsoncpp:jsoncpp", +# ] +# } source_set("nearby_protocol") { sources = [ "src/nearby/presence/np_cpp_ffi/nearby_protocol.cc" ] @@ -321,19 +334,6 @@ deps = [ ":ldt_np_adv_ffi" ] } -test("ldt_ffi_tests") { - sources = [ "src/nearby/presence/ldt_np_adv_ffi/c/tests/ldt_ffi_tests.cc" ] - include_dirs = [ "src/nearby/presence/ldt_np_adv_ffi/c/include" ] - defines = [ "LDT_TEST_VECTORS=\"third_party/beto-core/src/nearby/presence/ldt_np_adv/resources/test/np_adv_test_vectors.json\"" ] - cflags = [ "-Wno-error=sign-compare" ] - deps = [ - ":ldt_np_adv_ffi", - "//base/test:run_all_unittests", - "//testing/gtest", - "//third_party/jsoncpp:jsoncpp", - ] -} - rust_static_library("ldt_np_adv_ffi") { crate_name = "ldt_np_adv_ffi" crate_root = "src/nearby/presence/ldt_np_adv_ffi/src/lib.rs"
diff --git a/third_party/blink/common/features.cc b/third_party/blink/common/features.cc index 28c6dd76..ae93b7d 100644 --- a/third_party/blink/common/features.cc +++ b/third_party/blink/common/features.cc
@@ -583,7 +583,7 @@ // Enable `form-factors` client hint. BASE_FEATURE(kClientHintsFormFactors, "ClientHintsFormFactors", - base::FEATURE_DISABLED_BY_DEFAULT); + base::FEATURE_ENABLED_BY_DEFAULT); // Enable `sec-ch-prefers-reduced-transparency` client hint. BASE_FEATURE(kClientHintsPrefersReducedTransparency, @@ -944,12 +944,18 @@ "FencedFramesAutomaticBeaconCredentials", base::FEATURE_ENABLED_BY_DEFAULT); -// Controls functionality related to network revocation/local unpartitioned data -// access in fenced frames. +// Controls functionality related to network revocation/local unpartitioned +// data access in fenced frames. BASE_FEATURE(kFencedFramesLocalUnpartitionedDataAccess, "FencedFramesLocalUnpartitionedDataAccess", base::FEATURE_DISABLED_BY_DEFAULT); +// Controls access to an API to exempt certain URLs from fenced frame +// network revocation to facilitate testing. +BASE_FEATURE(kExemptUrlFromNetworkRevocationForTesting, + "ExemptUrlFromNetworkRevocationForTesting", + base::FEATURE_DISABLED_BY_DEFAULT); + // Use "style" and "json" destinations for CSS and JSON modules. // https://crbug.com/1491336 BASE_FEATURE(kFetchDestinationJsonCssModules,
diff --git a/third_party/blink/common/interest_group/auction_config.cc b/third_party/blink/common/interest_group/auction_config.cc index c9ddf5a6..90b4e3e 100644 --- a/third_party/blink/common/interest_group/auction_config.cc +++ b/third_party/blink/common/interest_group/auction_config.cc
@@ -122,6 +122,9 @@ if (non_shared_params.buyer_cumulative_timeouts.is_promise()) { ++total; } + if (non_shared_params.deprecated_render_url_replacements.is_promise()) { + ++total; + } if (direct_from_seller_signals.is_promise()) { ++total; } @@ -131,9 +134,6 @@ if (expects_additional_bids) { ++total; } - if (deprecated_render_url_replacements.is_promise()) { - ++total; - } for (const blink::AuctionConfig& sub_auction : non_shared_params.component_auctions) { total += sub_auction.NumPromises();
diff --git a/third_party/blink/common/interest_group/auction_config_mojom_traits.cc b/third_party/blink/common/interest_group/auction_config_mojom_traits.cc index c3faf35..8cf726b 100644 --- a/third_party/blink/common/interest_group/auction_config_mojom_traits.cc +++ b/third_party/blink/common/interest_group/auction_config_mojom_traits.cc
@@ -215,7 +215,9 @@ !data.ReadAllSlotsRequestedSizes(&out->all_slots_requested_sizes) || !data.ReadPerBuyerMultiBidLimits(&out->per_buyer_multi_bid_limits) || !data.ReadAuctionNonce(&out->auction_nonce) || - !data.ReadComponentAuctions(&out->component_auctions)) { + !data.ReadComponentAuctions(&out->component_auctions) || + !data.ReadDeprecatedRenderUrlReplacements( + &out->deprecated_render_url_replacements)) { return false; } @@ -304,9 +306,7 @@ !data.ReadPerBuyerExperimentGroupIds( &out->per_buyer_experiment_group_ids) || !data.ReadAggregationCoordinatorOrigin( - &out->aggregation_coordinator_origin) || - !data.ReadDeprecatedRenderUrlReplacements( - &out->deprecated_render_url_replacements)) { + &out->aggregation_coordinator_origin)) { return false; }
diff --git a/third_party/blink/common/interest_group/auction_config_test_util.cc b/third_party/blink/common/interest_group/auction_config_test_util.cc index 7ec654d..b358822 100644 --- a/third_party/blink/common/interest_group/auction_config_test_util.cc +++ b/third_party/blink/common/interest_group/auction_config_test_util.cc
@@ -32,8 +32,13 @@ const url::Origin buyer = url::Origin::Create(GURL("https://buyer.test")); auction_config.per_buyer_experiment_group_ids[buyer] = 3; - auction_config.deprecated_render_url_replacements = blink::AuctionConfig:: - MaybePromiseDeprecatedRenderURLReplacements::FromValue({}); + const std::vector<blink::AuctionConfig::AdKeywordReplacement> + deprecated_render_url_replacements = { + blink::AuctionConfig::AdKeywordReplacement( + {"${SELLER}", "ExampleSSP"})}; + auction_config.non_shared_params.deprecated_render_url_replacements = + blink::AuctionConfig::MaybePromiseDeprecatedRenderURLReplacements:: + FromValue(deprecated_render_url_replacements); AuctionConfig::NonSharedParams& non_shared_params = auction_config.non_shared_params;
diff --git a/third_party/blink/common/interest_group/devtools_serialization.cc b/third_party/blink/common/interest_group/devtools_serialization.cc index 795e4fe..bc455ac 100644 --- a/third_party/blink/common/interest_group/devtools_serialization.cc +++ b/third_party/blink/common/interest_group/devtools_serialization.cc
@@ -345,7 +345,8 @@ SerializeIntoDict("trustedScoringSignalsURL", conf.trusted_scoring_signals_url, result); SerializeIntoDict("deprecatedRenderURLReplacements", - conf.deprecated_render_url_replacements, result); + conf.non_shared_params.deprecated_render_url_replacements, + result); SerializeIntoDict("interestGroupBuyers", conf.non_shared_params.interest_group_buyers, result); SerializeIntoDict("auctionSignals", conf.non_shared_params.auction_signals,
diff --git a/third_party/blink/common/interest_group/devtools_serialization_unittest.cc b/third_party/blink/common/interest_group/devtools_serialization_unittest.cc index 80e4573..f4a0b067 100644 --- a/third_party/blink/common/interest_group/devtools_serialization_unittest.cc +++ b/third_party/blink/common/interest_group/devtools_serialization_unittest.cc
@@ -119,7 +119,10 @@ "maxTrustedScoringSignalsURLLength": 2560, "deprecatedRenderURLReplacements" : { "pending": false, - "value": [ ] + "value": [ { + "match": "${SELLER}", + "replacement": "ExampleSSP" + } ] }, "interestGroupBuyers": [ "https://buyer.test" ], "perBuyerCumulativeTimeouts": {
diff --git a/third_party/blink/public/common/features.h b/third_party/blink/public/common/features.h index 8a23ccd..f9eae80 100644 --- a/third_party/blink/public/common/features.h +++ b/third_party/blink/public/common/features.h
@@ -487,6 +487,8 @@ BLINK_COMMON_EXPORT BASE_DECLARE_FEATURE( kFencedFramesLocalUnpartitionedDataAccess); +BLINK_COMMON_EXPORT BASE_DECLARE_FEATURE( + kExemptUrlFromNetworkRevocationForTesting); BLINK_COMMON_EXPORT BASE_DECLARE_FEATURE(kFetchDestinationJsonCssModules);
diff --git a/third_party/blink/public/common/interest_group/auction_config.h b/third_party/blink/public/common/interest_group/auction_config.h index 8c0fa91a..a41203fa 100644 --- a/third_party/blink/public/common/interest_group/auction_config.h +++ b/third_party/blink/public/common/interest_group/auction_config.h
@@ -369,6 +369,10 @@ // level auction config can have component auctions. std::vector<AuctionConfig> component_auctions; + // Opaque map object, representing the replacements for ad creative urls. + MaybePromiseDeprecatedRenderURLReplacements + deprecated_render_url_replacements; + // The maximum length limit for the trusted scoring signal fetch URL. Can // only be set as either 0 or a positive number. A value of 0 indicates that // there is no limit. @@ -407,10 +411,6 @@ std::optional<GURL> decision_logic_url; std::optional<GURL> trusted_scoring_signals_url; - // Opaque map object, representing the replacements for ad creative urls. - MaybePromiseDeprecatedRenderURLReplacements - deprecated_render_url_replacements; - // Other parameters are grouped in a struct that is passed to SellerWorklets. NonSharedParams non_shared_params; @@ -462,7 +462,7 @@ * If the value has special validation logic, add a test to third_party/blink/common/interest_group/auction_config_mojom_traits_test.cc (If it's just passing along some values, adding to CreateFullAuctionConfig() - will provide some coverage automatically). + will provide some coverage automatically). )"); };
diff --git a/third_party/blink/public/common/interest_group/auction_config_mojom_traits.h b/third_party/blink/public/common/interest_group/auction_config_mojom_traits.h index c427bb0..33b26165 100644 --- a/third_party/blink/public/common/interest_group/auction_config_mojom_traits.h +++ b/third_party/blink/public/common/interest_group/auction_config_mojom_traits.h
@@ -389,6 +389,13 @@ return params.all_slots_requested_sizes; } + static const blink::AuctionConfig:: + MaybePromiseDeprecatedRenderURLReplacements& + deprecated_render_url_replacements( + const blink::AuctionConfig::NonSharedParams& params) { + return params.deprecated_render_url_replacements; + } + static const base::flat_map<url::Origin, uint16_t>& per_buyer_multi_bid_limits( const blink::AuctionConfig::NonSharedParams& params) { @@ -471,11 +478,6 @@ return config.per_buyer_experiment_group_ids; } - static const blink::AuctionConfig:: - MaybePromiseDeprecatedRenderURLReplacements& - deprecated_render_url_replacements(const blink::AuctionConfig& config) { - return config.deprecated_render_url_replacements; - } static bool expects_additional_bids(const blink::AuctionConfig& config) { return config.expects_additional_bids;
diff --git a/third_party/blink/public/mojom/frame/frame.mojom b/third_party/blink/public/mojom/frame/frame.mojom index 05d08a8..3354cbfa 100644 --- a/third_party/blink/public/mojom/frame/frame.mojom +++ b/third_party/blink/public/mojom/frame/frame.mojom
@@ -665,6 +665,12 @@ // the future) and gain access to unpartitioned storage. DisableUntrustedNetworkInFencedFrame() => (); + // A test-only IPC to exempt `exempted_url` from fenced frames network + // revocation immediately above (`DisableUntrustedNetworkInFencedFrame`). + // Used primarily to exempt the fenced frames remote context executor pattern + // in WPT from network revocation. + ExemptUrlFromNetworkRevocationForTesting(url.mojom.Url exempted_url) => (); + // Notify the browser that there is a legacy technology used by the page. // The event contains the technology `type` and code location from the // ExecutionContext.
diff --git a/third_party/blink/public/mojom/interest_group/interest_group_types.mojom b/third_party/blink/public/mojom/interest_group/interest_group_types.mojom index dc1d089..53226293 100644 --- a/third_party/blink/public/mojom/interest_group/interest_group_types.mojom +++ b/third_party/blink/public/mojom/interest_group/interest_group_types.mojom
@@ -493,6 +493,9 @@ // level auction config can have component auctions. array<AuctionAdConfig> component_auctions; + // The ad render url replacements for their respective ad URL. If promise is + // never given, this will resolve to an empty vector. + AuctionAdConfigMaybePromiseDeprecatedRenderURLReplacements deprecated_render_url_replacements; // The maximum length limit for the trusted scoring signal fetch URL. Can // only be set as either 0 or a positive number. A value of 0 indicates // that there is no limit. @@ -535,9 +538,6 @@ // renderer process. See details in the DirectFromSellerSignals comment. AuctionAdConfigMaybePromiseDirectFromSellerSignals direct_from_seller_signals; - // The ad render url replacements for their respective ad URL. If promise is - // never given, this will resolve to an empty vector. - AuctionAdConfigMaybePromiseDeprecatedRenderURLReplacements deprecated_render_url_replacements; // Like `direct_from_seller_signals`, but passed from the page via a different // mechanism. `direct_from_seller_signals` searches for the contents of
diff --git a/third_party/blink/public/platform/web_theme_engine.h b/third_party/blink/public/platform/web_theme_engine.h index 25d0897..72afd223 100644 --- a/third_party/blink/public/platform/web_theme_engine.h +++ b/third_party/blink/public/platform/web_theme_engine.h
@@ -213,7 +213,6 @@ struct SystemColorInfoState { bool is_dark_mode = false; bool forced_colors = false; - std::map<SystemThemeColor, uint32_t> colors; }; #if BUILDFLAG(IS_MAC) @@ -296,15 +295,10 @@ const ui::ColorProvider*, const std::optional<SkColor>& accent_color = std::nullopt) {} - virtual std::optional<SkColor> GetSystemColor( - SystemThemeColor system_theme) const { - return std::nullopt; - } - virtual std::optional<SkColor> GetAccentColor() const { return std::nullopt; } virtual ForcedColors GetForcedColors() const { return ForcedColors::kNone; } - virtual void OverrideForcedColorsTheme(bool is_dark_theme) {} + virtual void OverrideForcedColorsTheme() {} virtual void SetForcedColors(const blink::ForcedColors forced_colors) {} virtual void ResetToSystemColors( SystemColorInfoState system_color_info_state) {}
diff --git a/third_party/blink/renderer/core/css/css_properties.json5 b/third_party/blink/renderer/core/css/css_properties.json5 index 8ead926d..c7b8ec69 100644 --- a/third_party/blink/renderer/core/css/css_properties.json5 +++ b/third_party/blink/renderer/core/css/css_properties.json5
@@ -1722,7 +1722,6 @@ default_value: "StyleContentAlignmentData(ContentPosition::kNormal, ContentDistributionType::kDefault, OverflowAlignment::kDefault)", type_name: "StyleContentAlignmentData", converter: "ConvertContentAlignmentData", - valid_for_position_try: true, }, { name: "align-items", @@ -1733,7 +1732,6 @@ default_value: "StyleSelfAlignmentData(ItemPosition::kNormal, OverflowAlignment::kDefault)", type_name: "StyleSelfAlignmentData", converter: "ConvertSelfOrDefaultAlignmentData", - valid_for_position_try: true, }, { name: "alignment-baseline", @@ -3317,7 +3315,6 @@ default_value: "StyleContentAlignmentData(ContentPosition::kNormal, ContentDistributionType::kDefault, OverflowAlignment::kDefault)", type_name: "StyleContentAlignmentData", converter: "ConvertContentAlignmentData", - valid_for_position_try: true, }, { name: "justify-items", @@ -3328,7 +3325,6 @@ default_value: "StyleSelfAlignmentData(ItemPosition::kLegacy, OverflowAlignment::kDefault)", type_name: "StyleSelfAlignmentData", converter: "ConvertSelfOrDefaultAlignmentData", - valid_for_position_try: true, }, { name: "justify-self", @@ -4275,6 +4271,7 @@ typedom_types: ["Keyword"], runtime_flag: "CSSAnchorPositioning", valid_for_permission_element: true, + valid_for_position_try: true, }, { name: "position-fallback-bounds", @@ -4312,7 +4309,7 @@ keywords: ["normal", "most-width", "most-height", "most-block-size", "most-inline-size"], typedom_types: ["Keyword"], default_value: "normal", - runtime_flag: "CSSAnchorPositioning", + runtime_flag: "CSSPositionTryOrder", }, { name: "quotes", @@ -7580,6 +7577,7 @@ name: "place-self", longhands: ["align-self", "justify-self"], property_methods: ["ParseShorthand", "CSSValueFromComputedStyleInternal"], + valid_for_position_try: true, }, { name: "grid-area", @@ -7743,7 +7741,7 @@ name: "position-try", longhands: ["position-try-order", "position-try-options"], property_methods: ["ParseShorthand", "CSSValueFromComputedStyleInternal"], - runtime_flag: "CSSAnchorPositioning", + runtime_flag: "CSSPositionTryOrder", }, { name: "scroll-margin",
diff --git a/third_party/blink/renderer/core/css/selector_checker.cc b/third_party/blink/renderer/core/css/selector_checker.cc index 57bbddd0..0c08be31 100644 --- a/third_party/blink/renderer/core/css/selector_checker.cc +++ b/third_party/blink/renderer/core/css/selector_checker.cc
@@ -1794,7 +1794,7 @@ return false; case CSSSelector::kPseudoSelectAuthorDatalist: if (auto* select = DynamicTo<HTMLSelectElement>(element)) { - return select->SlottedDatalist(); + return select->FirstChildDatalist(); } return false; case CSSSelector::kPseudoDialogInTopLayer:
diff --git a/third_party/blink/renderer/core/exported/web_view_impl.cc b/third_party/blink/renderer/core/exported/web_view_impl.cc index 735b6ae3e..fb042e6 100644 --- a/third_party/blink/renderer/core/exported/web_view_impl.cc +++ b/third_party/blink/renderer/core/exported/web_view_impl.cc
@@ -3309,7 +3309,12 @@ void WebViewImpl::UpdateColorProviders( const ColorProviderColorMaps& color_provider_colors) { - page_->UpdateColorProviders(color_provider_colors); + bool color_providers_did_change = + page_->UpdateColorProviders(color_provider_colors); + if (color_providers_did_change) { + Page::PlatformColorsChanged(); + Page::ColorSchemeChanged(); + } } void WebViewImpl::SetBaseBackgroundColorOverrideTransparent(
diff --git a/third_party/blink/renderer/core/highlight/highlight_style_utils.cc b/third_party/blink/renderer/core/highlight/highlight_style_utils.cc index 150ece34..6b40ab5 100644 --- a/third_party/blink/renderer/core/highlight/highlight_style_utils.cc +++ b/third_party/blink/renderer/core/highlight/highlight_style_utils.cc
@@ -41,14 +41,6 @@ : originating_style.UsedColorScheme(); } -Color PreviousLayerColor(const ComputedStyle& originating_style, - std::optional<Color> previous_layer_color) { - if (previous_layer_color) { - return *previous_layer_color; - } - return originating_style.VisitedDependentColor(GetCSSPropertyColor()); -} - // Returns the forced foreground color for the given |pseudo|. Color ForcedForegroundColor(PseudoId pseudo, mojom::blink::ColorScheme color_scheme, @@ -287,7 +279,10 @@ if (maybe_color) { return maybe_color.value(); } - return PreviousLayerColor(originating_style, current_color); + if (!current_color) { + return originating_style.VisitedDependentColor(GetCSSPropertyColor()); + } + return current_color.value(); } // Returns the used value of the given <color>-valued |property|, taking into @@ -442,6 +437,7 @@ highlight_style.selection_decoration_lines = TextDecorationLine::kNone; highlight_style.selection_decoration_color = Color::kBlack; } + Color text_decoration_color = Color::kBlack; // Each highlight overlay’s shadows are completely independent of any shadows // specified on the originating element (or the other highlight overlays). @@ -486,6 +482,15 @@ } else { colors_from_previous_layer.Put(HighlightColorProperty::kStrokeColor); } + + maybe_color = MaybeResolveColor(document, style, pseudo_style, pseudo, + GetCSSPropertyTextDecorationColor()); + if (maybe_color) { + text_decoration_color = maybe_color.value(); + } else { + colors_from_previous_layer.Put( + HighlightColorProperty::kTextDecorationColor); + } } if (pseudo_style) { @@ -513,7 +518,7 @@ // Some code paths that do not use the highlight overlay painting system // may not resolve the color, so set it now. highlight_style.selection_decoration_color = - PreviousLayerColor(style, previous_layer_text_style.current_color); + previous_layer_text_style.current_color; colors_from_previous_layer.Put( HighlightColorProperty::kSelectionDecorationColor); } @@ -525,39 +530,43 @@ highlight_style.shadow = nullptr; } - return {highlight_style, colors_from_previous_layer}; + return {highlight_style, text_decoration_color, colors_from_previous_layer}; } -TextPaintStyle HighlightStyleUtils::ResolveColorsFromPreviousLayer( - const HighlightTextPaintStyle unresolved_style, - const TextPaintStyle& previous_layer_style) { - if (unresolved_style.properties_using_current_color.Empty()) { - return unresolved_style.style; +void HighlightStyleUtils::ResolveColorsFromPreviousLayer( + HighlightTextPaintStyle& text_style, + const HighlightTextPaintStyle& previous_layer_style) { + if (text_style.properties_using_current_color.Empty()) { + return; } - TextPaintStyle result = unresolved_style.style; - if (unresolved_style.properties_using_current_color.Has( + if (text_style.properties_using_current_color.Has( HighlightColorProperty::kCurrentColor)) { - result.current_color = previous_layer_style.current_color; + text_style.style.current_color = previous_layer_style.style.current_color; } - if (unresolved_style.properties_using_current_color.Has( + if (text_style.properties_using_current_color.Has( HighlightColorProperty::kFillColor)) { - result.fill_color = previous_layer_style.fill_color; + text_style.style.fill_color = previous_layer_style.style.fill_color; } - if (unresolved_style.properties_using_current_color.Has( + if (text_style.properties_using_current_color.Has( HighlightColorProperty::kStrokeColor)) { - result.stroke_color = previous_layer_style.stroke_color; + text_style.style.stroke_color = previous_layer_style.style.stroke_color; } - if (unresolved_style.properties_using_current_color.Has( + if (text_style.properties_using_current_color.Has( HighlightColorProperty::kEmphasisColor)) { - result.emphasis_mark_color = previous_layer_style.emphasis_mark_color; + text_style.style.emphasis_mark_color = + previous_layer_style.style.emphasis_mark_color; } - if (unresolved_style.properties_using_current_color.Has( + if (text_style.properties_using_current_color.Has( HighlightColorProperty::kSelectionDecorationColor)) { - result.selection_decoration_color = - previous_layer_style.selection_decoration_color; + text_style.style.selection_decoration_color = + previous_layer_style.style.selection_decoration_color; } - return result; + if (text_style.properties_using_current_color.Has( + HighlightColorProperty::kTextDecorationColor)) { + text_style.text_decoration_color = + previous_layer_style.text_decoration_color; + } } bool HighlightStyleUtils::ShouldInvalidateVisualOverflow(
diff --git a/third_party/blink/renderer/core/highlight/highlight_style_utils.h b/third_party/blink/renderer/core/highlight/highlight_style_utils.h index 6a6958c0..3d96431 100644 --- a/third_party/blink/renderer/core/highlight/highlight_style_utils.h +++ b/third_party/blink/renderer/core/highlight/highlight_style_utils.h
@@ -36,13 +36,16 @@ kStrokeColor, kEmphasisColor, kSelectionDecorationColor, + kTextDecorationColor, + // When adding another, update HighlightColorPropertySet below. }; using HighlightColorPropertySet = base::EnumSet<HighlightColorProperty, HighlightColorProperty::kCurrentColor, - HighlightColorProperty::kSelectionDecorationColor>; + HighlightColorProperty::kTextDecorationColor>; struct HighlightTextPaintStyle { TextPaintStyle style; + Color text_decoration_color; HighlightColorPropertySet properties_using_current_color; }; @@ -83,9 +86,9 @@ PseudoId pseudo, const AtomicString& pseudo_argument = g_null_atom); - static TextPaintStyle ResolveColorsFromPreviousLayer( - HighlightTextPaintStyle unresolved_style, - const TextPaintStyle& previous_layer_style); + static void ResolveColorsFromPreviousLayer( + HighlightTextPaintStyle& text_style, + const HighlightTextPaintStyle& previous_layer_style); static bool ShouldInvalidateVisualOverflow(const Node& node, DocumentMarker::MarkerType type);
diff --git a/third_party/blink/renderer/core/html/forms/html_button_element.cc b/third_party/blink/renderer/core/html/forms/html_button_element.cc index 556c5c1..25cff3d 100644 --- a/third_party/blink/renderer/core/html/forms/html_button_element.cc +++ b/third_party/blink/renderer/core/html/forms/html_button_element.cc
@@ -163,7 +163,7 @@ CHECK(RuntimeEnabledFeatures::StylableSelectEnabled()); // For native popups, use HTMLSelectElement's codepath. For <datalist> // popover popups, use the HTMLFormControlElement popover code path. - if (!select->SlottedDatalist()) { + if (!select->FirstChildDatalist()) { select->DefaultEventHandler(event); } }
diff --git a/third_party/blink/renderer/core/html/forms/html_form_control_element.cc b/third_party/blink/renderer/core/html/forms/html_form_control_element.cc index 94fa51c..7b21305 100644 --- a/third_party/blink/renderer/core/html/forms/html_form_control_element.cc +++ b/third_party/blink/renderer/core/html/forms/html_form_control_element.cc
@@ -368,7 +368,7 @@ if (!target_element && RuntimeEnabledFeatures::StylableSelectEnabled()) { if (auto* button = DynamicTo<HTMLButtonElement>(this)) { if (auto* select = button->OwnerSelect()) { - if (auto* datalist = select->SlottedDatalist()) { + if (auto* datalist = select->FirstChildDatalist()) { target_element = datalist; } }
diff --git a/third_party/blink/renderer/core/html/forms/html_select_element.cc b/third_party/blink/renderer/core/html/forms/html_select_element.cc index dc68a88..b84cec6 100644 --- a/third_party/blink/renderer/core/html/forms/html_select_element.cc +++ b/third_party/blink/renderer/core/html/forms/html_select_element.cc
@@ -1202,7 +1202,7 @@ return; } - if (SlottedButton() && SlottedDatalist()) { + if (SlottedButton() && FirstChildDatalist()) { // If there is a custom <button> and <datalist> at the same time, then the // popover triggering code will handle everything for now. // TODO(crbug.com/1511354): Implement keyboard behavior for stylable @@ -1641,10 +1641,6 @@ return select_type_->SlottedButton(); } -HTMLDataListElement* HTMLSelectElement::SlottedDatalist() const { - return select_type_->SlottedDatalist(); -} - HTMLDataListElement* HTMLSelectElement::FirstChildDatalist() const { return first_child_datalist_; }
diff --git a/third_party/blink/renderer/core/html/forms/html_select_element.h b/third_party/blink/renderer/core/html/forms/html_select_element.h index cc3d4d4..5e249956 100644 --- a/third_party/blink/renderer/core/html/forms/html_select_element.h +++ b/third_party/blink/renderer/core/html/forms/html_select_element.h
@@ -203,19 +203,18 @@ bool HandleInvokeInternal(HTMLElement& invoker, AtomicString& action) override; - // SlottedButton and SlottedDatalist return the first child <button> or - // <datalist> in the light dom tree. If this select is in a state where the - // <button> or <datalist> can't be rendered, such as a <select multiple>, then - // nullptr will be returned. Since these methods are called during style - // calculation to compute internal pseudo-classes, the value of the appearance - // property is not checked. + // SlottedButton returns the first child <button> in the light dom tree. If + // this select is in a state where the <button> can't be rendered, such as a + // <select multiple>, then nullptr will be returned. Since this method is + // called during style calculation to compute internal pseudo-classes, the + // value of the appearance property is not checked. HTMLButtonElement* SlottedButton() const; - HTMLDataListElement* SlottedDatalist() const; - // FirstChildDatalist returns the first child <datalist> of this <select>. - // Unlike SlottedDatalist(), it will return the first child <datalist> - // regardless of slotting or any other state in the element, which is useful - // in cases where we aren't allowed to recalc slot assignment. + // FirstChildDatalist returns the first child <datalist> of this <select>, + // which will get slotted into the UA shadowroot. It is kept up to date with a + // mutation observer, which calls RecalcFirstChildDatalist. This doesn't just + // look at the slot's assigned nodes because we can't run slot assignment in + // some cases when we need to find the datalist. HTMLDataListElement* FirstChildDatalist() const; void RecalcFirstChildDatalist();
diff --git a/third_party/blink/renderer/core/html/forms/select_type.cc b/third_party/blink/renderer/core/html/forms/select_type.cc index ec9d964..ac13721 100644 --- a/third_party/blink/renderer/core/html/forms/select_type.cc +++ b/third_party/blink/renderer/core/html/forms/select_type.cc
@@ -116,7 +116,6 @@ void CreateShadowSubtree(ShadowRoot& root) override; void ManuallyAssignSlots() override; HTMLButtonElement* SlottedButton() const override; - HTMLDataListElement* SlottedDatalist() const override; bool IsAppearanceBikeshed() const override; Element& InnerElement() const override; void ShowPopup(PopupMenu::ShowEventType type) override; @@ -395,15 +394,6 @@ return To<HTMLButtonElement>(button_slot_->FirstAssignedNode()); } -HTMLDataListElement* MenuListSelectType::SlottedDatalist() const { - if (!RuntimeEnabledFeatures::StylableSelectEnabled()) { - CHECK(!datalist_slot_); - return nullptr; - } - CHECK(datalist_slot_); - return To<HTMLDataListElement>(datalist_slot_->FirstAssignedNode()); -} - bool MenuListSelectType::IsAppearanceBikeshed() const { if (!RuntimeEnabledFeatures::StylableSelectEnabled()) { return false; @@ -419,7 +409,7 @@ } void MenuListSelectType::ShowPopup(PopupMenu::ShowEventType type) { - if (auto* datalist = SlottedDatalist()) { + if (auto* datalist = select_->FirstChildDatalist()) { if (IsAppearanceBikeshed()) { // TODO(crbug.com/1511354): Instead of calling ShowPopover here, we should // create a method in HTMLSelectElement like @@ -821,7 +811,6 @@ void CreateShadowSubtree(ShadowRoot&) override; void ManuallyAssignSlots() override; HTMLButtonElement* SlottedButton() const override; - HTMLDataListElement* SlottedDatalist() const override; bool IsAppearanceBikeshed() const override; private: @@ -1481,10 +1470,6 @@ return nullptr; } -HTMLDataListElement* ListBoxSelectType::SlottedDatalist() const { - return nullptr; -} - bool ListBoxSelectType::IsAppearanceBikeshed() const { return false; }
diff --git a/third_party/blink/renderer/core/html/forms/select_type.h b/third_party/blink/renderer/core/html/forms/select_type.h index 6b82c3c..c2993889 100644 --- a/third_party/blink/renderer/core/html/forms/select_type.h +++ b/third_party/blink/renderer/core/html/forms/select_type.h
@@ -64,7 +64,6 @@ virtual void CreateShadowSubtree(ShadowRoot& root) = 0; virtual void ManuallyAssignSlots() = 0; virtual HTMLButtonElement* SlottedButton() const = 0; - virtual HTMLDataListElement* SlottedDatalist() const = 0; virtual bool IsAppearanceBikeshed() const = 0; virtual Element& InnerElement() const; virtual void ShowPopup(PopupMenu::ShowEventType type);
diff --git a/third_party/blink/renderer/core/inspector/inspector_emulation_agent.cc b/third_party/blink/renderer/core/inspector/inspector_emulation_agent.cc index 6866305a..65b6575 100644 --- a/third_party/blink/renderer/core/inspector/inspector_emulation_agent.cc +++ b/third_party/blink/renderer/core/inspector/inspector_emulation_agent.cc
@@ -311,8 +311,7 @@ } else { is_dark_mode = prefers_color_scheme_value == "dark"; } - WebThemeEngineHelper::GetNativeThemeEngine()->OverrideForcedColorsTheme( - is_dark_mode); + WebThemeEngineHelper::GetNativeThemeEngine()->OverrideForcedColorsTheme(); GetWebViewImpl()->GetPage()->EmulateForcedColors(is_dark_mode); } else if (forced_colors_value == "none") { if (!forced_colors_override_) {
diff --git a/third_party/blink/renderer/core/layout/absolute_utils.cc b/third_party/blink/renderer/core/layout/absolute_utils.cc index 8c66cdd4..0b88834 100644 --- a/third_party/blink/renderer/core/layout/absolute_utils.cc +++ b/third_party/blink/renderer/core/layout/absolute_utils.cc
@@ -22,22 +22,6 @@ using InsetBias = InsetModifiedContainingBlock::InsetBias; -StyleSelfAlignmentData AlignSelf(const ComputedStyle& style, - ItemPosition normal_behavior) { - return RuntimeEnabledFeatures::LayoutAlignForPositionedEnabled() - ? style.ResolvedAlignSelf(normal_behavior) - : StyleSelfAlignmentData(ItemPosition::kNormal, - OverflowAlignment::kDefault); -} - -StyleSelfAlignmentData JustifySelf(const ComputedStyle& style, - ItemPosition normal_behavior) { - return RuntimeEnabledFeatures::LayoutAlignForPositionedEnabled() - ? style.ResolvedJustifySelf(normal_behavior) - : StyleSelfAlignmentData(ItemPosition::kNormal, - OverflowAlignment::kDefault); -} - inline InsetBias GetStaticPositionInsetBias( LogicalStaticPosition::InlineEdge inline_edge) { switch (inline_edge) { @@ -463,10 +447,12 @@ IsParallelWritingMode(container_writing_direction.GetWritingMode(), self_writing_direction.GetWritingMode()); return is_parallel - ? LogicalAlignment{JustifySelf(style, justify_normal_behavior), - AlignSelf(style, align_normal_behavior)} - : LogicalAlignment{AlignSelf(style, align_normal_behavior), - JustifySelf(style, justify_normal_behavior)}; + ? LogicalAlignment{style.ResolvedJustifySelf( + justify_normal_behavior), + style.ResolvedAlignSelf(align_normal_behavior)} + : LogicalAlignment{ + style.ResolvedAlignSelf(align_normal_behavior), + style.ResolvedJustifySelf(justify_normal_behavior)}; } LogicalAnchorCenterPosition ComputeAnchorCenterPosition(
diff --git a/third_party/blink/renderer/core/layout/layout_theme.cc b/third_party/blink/renderer/core/layout/layout_theme.cc index f5eb2ef..cbac3fe 100644 --- a/third_party/blink/renderer/core/layout/layout_theme.cc +++ b/third_party/blink/renderer/core/layout/layout_theme.cc
@@ -527,13 +527,13 @@ : caret_blink_interval_; } -// TODO(crbug.com/1231644): Use color_provider to get the system colors if -// available. Color LayoutTheme::SystemColor(CSSValueID css_value_id, mojom::blink::ColorScheme color_scheme, const ui::ColorProvider* color_provider) const { - if (!WebTestSupport::IsRunningWebTest() && InForcedColorsMode()) - return SystemColorFromNativeTheme(css_value_id, color_scheme); + if (color_provider && !WebTestSupport::IsRunningWebTest()) { + return SystemColorFromColorProvider(css_value_id, color_scheme, + color_provider); + } return DefaultSystemColor(css_value_id, color_scheme); } @@ -651,21 +651,24 @@ return Color(); } -Color LayoutTheme::SystemColorFromNativeTheme( +Color LayoutTheme::SystemColorFromColorProvider( CSSValueID css_value_id, - mojom::blink::ColorScheme color_scheme) const { - blink::WebThemeEngine::SystemThemeColor theme_color; + mojom::blink::ColorScheme color_scheme, + const ui::ColorProvider* color_provider) const { + CHECK(!color_provider->IsColorMapEmpty()); + SkColor system_theme_color; switch (css_value_id) { case CSSValueID::kActivetext: case CSSValueID::kLinktext: case CSSValueID::kVisitedtext: - theme_color = blink::WebThemeEngine::SystemThemeColor::kHotlight; + system_theme_color = + color_provider->GetColor(ui::kColorCssSystemHotlight); break; case CSSValueID::kButtonface: case CSSValueID::kButtonhighlight: case CSSValueID::kButtonshadow: case CSSValueID::kThreedface: - theme_color = blink::WebThemeEngine::SystemThemeColor::kButtonFace; + system_theme_color = color_provider->GetColor(ui::kColorCssSystemBtnFace); break; case CSSValueID::kButtonborder: case CSSValueID::kButtontext: @@ -677,16 +680,19 @@ case CSSValueID::kThreedlightshadow: case CSSValueID::kThreedshadow: case CSSValueID::kWindowframe: - theme_color = blink::WebThemeEngine::SystemThemeColor::kButtonText; + system_theme_color = color_provider->GetColor(ui::kColorCssSystemBtnText); break; case CSSValueID::kGraytext: - theme_color = blink::WebThemeEngine::SystemThemeColor::kGrayText; + system_theme_color = + color_provider->GetColor(ui::kColorCssSystemGrayText); break; case CSSValueID::kHighlight: - theme_color = blink::WebThemeEngine::SystemThemeColor::kHighlight; + system_theme_color = + color_provider->GetColor(ui::kColorCssSystemHighlight); break; case CSSValueID::kHighlighttext: - theme_color = blink::WebThemeEngine::SystemThemeColor::kHighlightText; + system_theme_color = + color_provider->GetColor(ui::kColorCssSystemHighlightText); break; case CSSValueID::kCanvas: case CSSValueID::kField: @@ -698,7 +704,7 @@ case CSSValueID::kMenu: case CSSValueID::kScrollbar: case CSSValueID::kWindow: - theme_color = blink::WebThemeEngine::SystemThemeColor::kWindow; + system_theme_color = color_provider->GetColor(ui::kColorCssSystemWindow); break; case CSSValueID::kCanvastext: case CSSValueID::kFieldtext: @@ -708,16 +714,14 @@ case CSSValueID::kInfotext: case CSSValueID::kMenutext: case CSSValueID::kWindowtext: - theme_color = blink::WebThemeEngine::SystemThemeColor::kWindowText; + system_theme_color = + color_provider->GetColor(ui::kColorCssSystemWindowText); break; default: return DefaultSystemColor(css_value_id, color_scheme); } - const std::optional<SkColor> system_color = - WebThemeEngineHelper::GetNativeThemeEngine()->GetSystemColor(theme_color); - if (system_color) - return Color::FromSkColor((system_color.value())); - return DefaultSystemColor(css_value_id, color_scheme); + + return Color::FromSkColor(system_theme_color); } Color LayoutTheme::PlatformTextSearchHighlightColor(
diff --git a/third_party/blink/renderer/core/layout/layout_theme.h b/third_party/blink/renderer/core/layout/layout_theme.h index 25d17e9..99f1a8e 100644 --- a/third_party/blink/renderer/core/layout/layout_theme.h +++ b/third_party/blink/renderer/core/layout/layout_theme.h
@@ -239,9 +239,10 @@ Color DefaultSystemColor(CSSValueID, mojom::blink::ColorScheme color_scheme) const; - Color SystemColorFromNativeTheme( + Color SystemColorFromColorProvider( CSSValueID, - mojom::blink::ColorScheme color_scheme) const; + mojom::blink::ColorScheme color_scheme, + const ui::ColorProvider* color_provider) const; private: // This function is to be implemented in your platform-specific theme
diff --git a/third_party/blink/renderer/core/layout/layout_theme_android.cc b/third_party/blink/renderer/core/layout/layout_theme_android.cc index c2eccab9..05f0d1b 100644 --- a/third_party/blink/renderer/core/layout/layout_theme_android.cc +++ b/third_party/blink/renderer/core/layout/layout_theme_android.cc
@@ -20,6 +20,17 @@ LayoutThemeAndroid::~LayoutThemeAndroid() {} +Color LayoutThemeAndroid::SystemColor( + CSSValueID css_value_id, + mojom::blink::ColorScheme color_scheme, + const ui::ColorProvider* color_provider) const { + // Color providers are not supported for Android, so we should always use + // DefaultSystemColor() for system colors. + // TODO(crbug.com/40779801): This override can be removed if we can always + // guarantee the provider is nullptr for Android. + return DefaultSystemColor(css_value_id, color_scheme); +} + Color LayoutThemeAndroid::PlatformActiveSelectionBackgroundColor( mojom::blink::ColorScheme color_scheme) const { return color_scheme == mojom::blink::ColorScheme::kDark
diff --git a/third_party/blink/renderer/core/layout/layout_theme_android.h b/third_party/blink/renderer/core/layout/layout_theme_android.h index bf25ba1..98edc665 100644 --- a/third_party/blink/renderer/core/layout/layout_theme_android.h +++ b/third_party/blink/renderer/core/layout/layout_theme_android.h
@@ -12,6 +12,9 @@ class LayoutThemeAndroid final : public LayoutThemeMobile { public: static scoped_refptr<LayoutTheme> Create(); + Color SystemColor(CSSValueID, + mojom::blink::ColorScheme color_scheme, + const ui::ColorProvider* color_provider) const override; bool DelegatesMenuListRendering() const override { return true; } Color PlatformActiveSelectionBackgroundColor( mojom::blink::ColorScheme color_scheme) const override;
diff --git a/third_party/blink/renderer/core/layout/layout_theme_win.cc b/third_party/blink/renderer/core/layout/layout_theme_win.cc index b4dce90..653bb64 100644 --- a/third_party/blink/renderer/core/layout/layout_theme_win.cc +++ b/third_party/blink/renderer/core/layout/layout_theme_win.cc
@@ -20,20 +20,4 @@ return *layout_theme; } -// TODO(crbug.com/1231644): Use color_provider to get the system colors if -// available. -Color LayoutThemeWin::SystemColor( - CSSValueID css_value_id, - mojom::blink::ColorScheme color_scheme, - const ui::ColorProvider* color_provider) const { - // Fall back to the default system colors if the color scheme is dark and - // forced colors is not enabled. - if (WebTestSupport::IsRunningWebTest() || - (color_scheme == mojom::blink::ColorScheme::kDark && - !InForcedColorsMode())) { - return DefaultSystemColor(css_value_id, color_scheme); - } - return SystemColorFromNativeTheme(css_value_id, color_scheme); -} - } // namespace blink
diff --git a/third_party/blink/renderer/core/layout/layout_theme_win.h b/third_party/blink/renderer/core/layout/layout_theme_win.h index c6574695..7af0d98 100644 --- a/third_party/blink/renderer/core/layout/layout_theme_win.h +++ b/third_party/blink/renderer/core/layout/layout_theme_win.h
@@ -13,10 +13,6 @@ public: static scoped_refptr<LayoutTheme> Create(); - Color SystemColor(CSSValueID css_value_id, - mojom::blink::ColorScheme color_scheme, - const ui::ColorProvider* color_provider) const override; - // TODO(crbug.com/1092093): Implement IsAccentColorCustomized and // GetAccentColor to support system accent colors in windows. };
diff --git a/third_party/blink/renderer/core/layout/out_of_flow_layout_part.cc b/third_party/blink/renderer/core/layout/out_of_flow_layout_part.cc index 3afbb89..a127a95 100644 --- a/third_party/blink/renderer/core/layout/out_of_flow_layout_part.cc +++ b/third_party/blink/renderer/core/layout/out_of_flow_layout_part.cc
@@ -1939,28 +1939,26 @@ builder.SetReplacedPercentageResolutionSize( space.PercentageResolutionSize()); - if (RuntimeEnabledFeatures::LayoutAlignForPositionedEnabled()) { - const bool is_parallel = - IsParallelWritingMode(container_writing_direction.GetWritingMode(), - candidate_writing_direction.GetWritingMode()); - const ItemPosition inline_position = - (is_parallel ? candidate_style.JustifySelf() - : candidate_style.AlignSelf()) - .GetPosition(); - const bool is_inline_stretch = !imcb.has_auto_inline_inset && - inline_position == ItemPosition::kStretch; - if (is_inline_stretch) { - builder.SetInlineAutoBehavior(AutoSizeBehavior::kStretchExplicit); - } - const ItemPosition block_position = - (is_parallel ? candidate_style.AlignSelf() - : candidate_style.JustifySelf()) - .GetPosition(); - const bool is_block_stretch = !imcb.has_auto_block_inset && - block_position == ItemPosition::kStretch; - if (is_block_stretch) { - builder.SetBlockAutoBehavior(AutoSizeBehavior::kStretchExplicit); - } + const bool is_parallel = + IsParallelWritingMode(container_writing_direction.GetWritingMode(), + candidate_writing_direction.GetWritingMode()); + const ItemPosition inline_position = + (is_parallel ? candidate_style.JustifySelf() + : candidate_style.AlignSelf()) + .GetPosition(); + const bool is_inline_stretch = !imcb.has_auto_inline_inset && + inline_position == ItemPosition::kStretch; + if (is_inline_stretch) { + builder.SetInlineAutoBehavior(AutoSizeBehavior::kStretchExplicit); + } + const ItemPosition block_position = + (is_parallel ? candidate_style.AlignSelf() + : candidate_style.JustifySelf()) + .GetPosition(); + const bool is_block_stretch = + !imcb.has_auto_block_inset && block_position == ItemPosition::kStretch; + if (is_block_stretch) { + builder.SetBlockAutoBehavior(AutoSizeBehavior::kStretchExplicit); } replaced_size =
diff --git a/third_party/blink/renderer/core/page/page.cc b/third_party/blink/renderer/core/page/page.cc index 74ca723b..7748fef 100644 --- a/third_party/blink/renderer/core/page/page.cc +++ b/third_party/blink/renderer/core/page/page.cc
@@ -509,7 +509,7 @@ emulated_forced_colors_provider_.reset(); } -void Page::UpdateColorProviders( +bool Page::UpdateColorProviders( const ColorProviderColorMaps& color_provider_colors) { // Color maps should not be empty as they are needed to create the color // providers. @@ -544,9 +544,7 @@ did_color_provider_update = true; } - if (did_color_provider_update) { - InvalidatePaint(); - } + return did_color_provider_update; } void Page::UpdateColorProvidersForTest() {
diff --git a/third_party/blink/renderer/core/page/page.h b/third_party/blink/renderer/core/page/page.h index a8bb45c7..9b13953 100644 --- a/third_party/blink/renderer/core/page/page.h +++ b/third_party/blink/renderer/core/page/page.h
@@ -165,7 +165,7 @@ void EmulateForcedColors(bool is_dark_theme); void DisableEmulatedForcedColors(); - void UpdateColorProviders( + bool UpdateColorProviders( const ColorProviderColorMaps& color_provider_colors); void UpdateColorProvidersForTest(); const ui::ColorProvider* GetColorProviderForPainting(
diff --git a/third_party/blink/renderer/core/paint/highlight_overlay.cc b/third_party/blink/renderer/core/paint/highlight_overlay.cc index fa0b6674..cc5273c 100644 --- a/third_party/blink/renderer/core/paint/highlight_overlay.cc +++ b/third_party/blink/renderer/core/paint/highlight_overlay.cc
@@ -4,6 +4,7 @@ #include "third_party/blink/renderer/core/paint/highlight_overlay.h" +#include "third_party/blink/renderer/core/css/properties/longhands.h" #include "third_party/blink/renderer/core/dom/text.h" #include "third_party/blink/renderer/core/editing/frame_selection.h" #include "third_party/blink/renderer/core/editing/markers/custom_highlight_marker.h" @@ -178,7 +179,7 @@ result.AppendNumber(Offset()); result.Append(edge_type == HighlightEdgeType::kStart ? "<" : ">"); result.Append(HighlightTypeToString(layer_type)); - result.Append(String::Number<uint16_t>(layer_index)); + result.AppendNumber(layer_index); return result.ToString(); } @@ -221,8 +222,12 @@ HighlightDecoration::HighlightDecoration(HighlightLayerType type, uint16_t layer_index, - HighlightRange range) - : type(type), layer_index(layer_index), range(range) {} + HighlightRange range, + Color override_color) + : type(type), + layer_index(layer_index), + range(range), + highlight_override_color(override_color) {} String HighlightDecoration::ToString() const { StringBuilder result{}; @@ -244,16 +249,22 @@ HighlightPart::HighlightPart(HighlightLayerType type, uint16_t layer_index, HighlightRange range, + TextPaintStyle style, Vector<HighlightDecoration> decorations) : type(type), layer_index(layer_index), range(range), + style(style), decorations(std::move(decorations)) {} HighlightPart::HighlightPart(HighlightLayerType type, uint16_t layer_index, HighlightRange range) - : HighlightPart(type, layer_index, range, Vector<HighlightDecoration>{}) {} + : HighlightPart(type, + layer_index, + range, + TextPaintStyle(), + Vector<HighlightDecoration>{}) {} String HighlightPart::ToString() const { StringBuilder result{}; @@ -324,6 +335,9 @@ layers[0].style = &originating_style; layers[0].text_style.style = originating_text_style; + layers[0].text_style.text_decoration_color = + originating_style.VisitedDependentColor( + GetCSSPropertyTextDecorationColor()); layers[0].decorations_in_effect = originating_style.HasAppliedTextDecorations() ? originating_style.TextDecorationsInEffect() @@ -495,10 +509,14 @@ const TextFragmentPaintInfo& content_offsets, const HeapVector<HighlightLayer>& layers, const Vector<HighlightEdge>& edges) { + const HighlightStyleUtils::HighlightTextPaintStyle& originating_text_style = + layers[0].text_style; const HighlightDecoration originating_decoration{ HighlightLayerType::kOriginating, 0, - {content_offsets.from, content_offsets.to}}; + {content_offsets.from, content_offsets.to}, + originating_text_style.text_decoration_color}; + Vector<HighlightPart> result{}; Vector<std::optional<HighlightRange>> active(layers.size()); std::optional<unsigned> prev_offset{}; @@ -506,6 +524,7 @@ result.push_back(HighlightPart{HighlightLayerType::kOriginating, 0, {content_offsets.from, content_offsets.to}, + originating_text_style.style, {originating_decoration}}); return result; } @@ -515,6 +534,7 @@ 0, {content_offsets.from, ClampOffset(edges.front().Offset(), content_offsets)}, + originating_text_style.style, {originating_decoration}}); } for (const HighlightEdge& edge : edges) { @@ -528,8 +548,11 @@ HighlightPart part{HighlightLayerType::kOriginating, 0, {part_from, part_to}, + originating_text_style.style, {originating_decoration}}; - for (wtf_size_t i = 0; i < layers.size(); i++) { + HighlightStyleUtils::HighlightTextPaintStyle previous_layer_style = + originating_text_style; + for (wtf_size_t i = 1; i < layers.size(); i++) { if (active[i]) { unsigned decoration_from = ClampOffset(active[i]->from, content_offsets); @@ -537,10 +560,17 @@ ClampOffset(active[i]->to, content_offsets); part.type = layers[i].type; part.layer_index = static_cast<uint16_t>(i); + HighlightStyleUtils::HighlightTextPaintStyle part_style = + layers[i].text_style; + HighlightStyleUtils::ResolveColorsFromPreviousLayer( + part_style, previous_layer_style); + part.style = part_style.style; part.decorations.push_back( HighlightDecoration{layers[i].type, static_cast<uint16_t>(i), - {decoration_from, decoration_to}}); + {decoration_from, decoration_to}, + part_style.text_decoration_color}); + previous_layer_style = part_style; } } result.push_back(part); @@ -564,6 +594,7 @@ 0, {ClampOffset(edges.back().Offset(), content_offsets), content_offsets.to}, + originating_text_style.style, {originating_decoration}}); } return result;
diff --git a/third_party/blink/renderer/core/paint/highlight_overlay.h b/third_party/blink/renderer/core/paint/highlight_overlay.h index 119e938f..a08f0fb6 100644 --- a/third_party/blink/renderer/core/paint/highlight_overlay.h +++ b/third_party/blink/renderer/core/paint/highlight_overlay.h
@@ -129,7 +129,8 @@ public: HighlightDecoration(HighlightLayerType type, uint16_t layer_index, - HighlightRange range); + HighlightRange range, + Color override_color); String ToString() const; @@ -139,6 +140,7 @@ HighlightLayerType type; uint16_t layer_index; HighlightRange range; + Color highlight_override_color; }; // Represents a |range| of the fragment that needs its text proper painted in @@ -154,6 +156,7 @@ HighlightPart(HighlightLayerType, uint16_t, HighlightRange, + TextPaintStyle, Vector<HighlightDecoration>); HighlightPart(HighlightLayerType, uint16_t, HighlightRange); @@ -165,6 +168,7 @@ HighlightLayerType type; uint16_t layer_index; HighlightRange range; + TextPaintStyle style; Vector<HighlightDecoration> decorations; };
diff --git a/third_party/blink/renderer/core/paint/highlight_overlay_test.cc b/third_party/blink/renderer/core/paint/highlight_overlay_test.cc index fbf10ee0..8c49fc02 100644 --- a/third_party/blink/renderer/core/paint/highlight_overlay_test.cc +++ b/third_party/blink/renderer/core/paint/highlight_overlay_test.cc
@@ -34,7 +34,13 @@ class HighlightOverlayTest : public PageTestBase { public: - HighlightOverlayTest() : PageTestBase() {} + TextPaintStyle CreatePaintStyle(Color color) { + return TextPaintStyle{color, color, + color, color, + 2, ::blink::mojom::blink::ColorScheme::kLight, + nullptr, TextDecorationLine::kNone, + color, kPaintOrderNormal}; + } }; TEST_F(HighlightOverlayTest, ComputeLayers) { @@ -332,6 +338,58 @@ GetDocument(), node, text_style, paint_style, paint_info, &selection, *custom, *grammar, *spelling, *target); + // Set up paint styles for each layer + Color originating_color(0, 0, 0); + HighlightStyleUtils::HighlightColorPropertySet originating_current_colors; + HighlightStyleUtils::HighlightTextPaintStyle originating_text_style{ + CreatePaintStyle(originating_color), originating_color, + originating_current_colors}; + layers[0].text_style = originating_text_style; + + Color foo_color(0, 0, 1); + HighlightStyleUtils::HighlightColorPropertySet foo_current_colors; + HighlightStyleUtils::HighlightTextPaintStyle foo_text_style{ + CreatePaintStyle(foo_color), foo_color, foo_current_colors}; + layers[1].text_style = foo_text_style; + + Color bar_color(0, 0, 2); + HighlightStyleUtils::HighlightColorPropertySet bar_current_colors{ + HighlightStyleUtils::HighlightColorProperty::kCurrentColor, + HighlightStyleUtils::HighlightColorProperty::kFillColor, + HighlightStyleUtils::HighlightColorProperty::kStrokeColor, + HighlightStyleUtils::HighlightColorProperty::kEmphasisColor, + HighlightStyleUtils::HighlightColorProperty::kSelectionDecorationColor, + HighlightStyleUtils::HighlightColorProperty::kTextDecorationColor}; + HighlightStyleUtils::HighlightTextPaintStyle bar_text_style{ + CreatePaintStyle(bar_color), bar_color, bar_current_colors}; + layers[2].text_style = bar_text_style; + + Color spelling_color(0, 0, 3); + HighlightStyleUtils::HighlightColorPropertySet spelling_current_colors; + HighlightStyleUtils::HighlightTextPaintStyle spelling_text_style{ + CreatePaintStyle(spelling_color), spelling_color, + spelling_current_colors}; + layers[3].text_style = spelling_text_style; + + Color target_color(0, 0, 4); + HighlightStyleUtils::HighlightColorPropertySet target_current_colors{ + HighlightStyleUtils::HighlightColorProperty::kCurrentColor, + HighlightStyleUtils::HighlightColorProperty::kFillColor, + HighlightStyleUtils::HighlightColorProperty::kStrokeColor, + HighlightStyleUtils::HighlightColorProperty::kEmphasisColor, + HighlightStyleUtils::HighlightColorProperty::kSelectionDecorationColor, + HighlightStyleUtils::HighlightColorProperty::kTextDecorationColor}; + HighlightStyleUtils::HighlightTextPaintStyle target_text_style{ + CreatePaintStyle(target_color), target_color, target_current_colors}; + layers[4].text_style = target_text_style; + + Color selection_color(0, 0, 5); + HighlightStyleUtils::HighlightColorPropertySet selection_current_colors; + HighlightStyleUtils::HighlightTextPaintStyle selection_text_style{ + CreatePaintStyle(selection_color), selection_color, + selection_current_colors}; + layers[5].text_style = selection_text_style; + // 0 6 10 15 20 24 // brown fxo oevr lazy dgo today // [ ] originating @@ -348,8 +406,8 @@ // clang-format off EXPECT_EQ(HighlightOverlay::ComputeParts(originating, layers, edges), (Vector<HighlightPart>{ - HighlightPart{HighlightLayerType::kOriginating, 0, {0,25}, - {{HighlightLayerType::kOriginating, 0, {0,25}}}}, + HighlightPart{HighlightLayerType::kOriginating, 0, {0,25}, originating_text_style.style, + {{HighlightLayerType::kOriginating, 0, {0,25}, originating_color}}}, })) << "should return correct kOriginating part when nothing is highlighted"; @@ -368,45 +426,45 @@ EXPECT_EQ(HighlightOverlay::ComputeParts(originating, layers, edges2), (Vector<HighlightPart>{ - HighlightPart{HighlightLayerType::kCustom, 1, {0,6}, - {{HighlightLayerType::kOriginating, 0, {0,25}}, - {HighlightLayerType::kCustom, 1, {0,14}}}}, - HighlightPart{HighlightLayerType::kSpelling, 3, {6,9}, - {{HighlightLayerType::kOriginating, 0, {0,25}}, - {HighlightLayerType::kCustom, 1,{ 0,14}}, - {HighlightLayerType::kSpelling, 3, {6,9}}}}, - HighlightPart{HighlightLayerType::kCustom, 1, {9,10}, - {{HighlightLayerType::kOriginating, 0, {0,25}}, - {HighlightLayerType::kCustom, 1, {0,14}}}}, - HighlightPart{HighlightLayerType::kSpelling, 3, {10,13}, - {{HighlightLayerType::kOriginating, 0, {0,25}}, - {HighlightLayerType::kCustom, 1, {0,14}}, - {HighlightLayerType::kCustom, 2, {10,19}}, - {HighlightLayerType::kSpelling, 3, {10,14}}}}, - HighlightPart{HighlightLayerType::kSelection, 5, {13,14}, - {{HighlightLayerType::kOriginating, 0, {0,25}}, - {HighlightLayerType::kCustom, 1, {0,14}}, - {HighlightLayerType::kCustom, 2, {10,19}}, - {HighlightLayerType::kSpelling, 3, {10,14}}, - {HighlightLayerType::kSelection, 5, {13,19}}}}, - HighlightPart{HighlightLayerType::kSelection, 5, {14,15}, - {{HighlightLayerType::kOriginating, 0, {0,25}}, - {HighlightLayerType::kCustom, 2, {10,19}}, - {HighlightLayerType::kSelection, 5, {13,19}}}}, - HighlightPart{HighlightLayerType::kSelection, 5, {15,19}, - {{HighlightLayerType::kOriginating, 0, {0,25}}, - {HighlightLayerType::kCustom, 2, {10,19}}, - {HighlightLayerType::kTargetText, 4, {15,23}}, - {HighlightLayerType::kSelection, 5, {13,19}}}}, - HighlightPart{HighlightLayerType::kTargetText, 4, {19,20}, - {{HighlightLayerType::kOriginating, 0, {0,25}}, - {HighlightLayerType::kTargetText, 4, {15,23}}}}, - HighlightPart{HighlightLayerType::kTargetText, 4, {20,23}, - {{HighlightLayerType::kOriginating, 0, {0,25}}, - {HighlightLayerType::kSpelling, 3, {20,23}}, - {HighlightLayerType::kTargetText, 4, {15,23}}}}, - HighlightPart{HighlightLayerType::kOriginating, 0, {23,25}, - {{HighlightLayerType::kOriginating, 0, {0,25}}}}, + HighlightPart{HighlightLayerType::kCustom, 1, {0,6}, foo_text_style.style, + {{HighlightLayerType::kOriginating, 0, {0,25}, originating_color}, + {HighlightLayerType::kCustom, 1, {0,14}, foo_color}}}, + HighlightPart{HighlightLayerType::kSpelling, 3, {6,9}, spelling_text_style.style, + {{HighlightLayerType::kOriginating, 0, {0,25}, originating_color}, + {HighlightLayerType::kCustom, 1, {0,14}, foo_color}, + {HighlightLayerType::kSpelling, 3, {6,9}, spelling_color}}}, + HighlightPart{HighlightLayerType::kCustom, 1, {9,10}, foo_text_style.style, + {{HighlightLayerType::kOriginating, 0, {0,25}, originating_color}, + {HighlightLayerType::kCustom, 1, {0,14}, foo_color}}}, + HighlightPart{HighlightLayerType::kSpelling, 3, {10,13}, spelling_text_style.style, + {{HighlightLayerType::kOriginating, 0, {0,25}, originating_color}, + {HighlightLayerType::kCustom, 1, {0,14}, foo_color}, + {HighlightLayerType::kCustom, 2, {10,19}, foo_color}, + {HighlightLayerType::kSpelling, 3, {10,14}, spelling_color}}}, + HighlightPart{HighlightLayerType::kSelection, 5, {13,14}, selection_text_style.style, + {{HighlightLayerType::kOriginating, 0, {0,25}, originating_color}, + {HighlightLayerType::kCustom, 1, {0,14}, foo_color}, + {HighlightLayerType::kCustom, 2, {10,19}, foo_color}, + {HighlightLayerType::kSpelling, 3, {10,14}, spelling_color}, + {HighlightLayerType::kSelection, 5, {13,19}, selection_color}}}, + HighlightPart{HighlightLayerType::kSelection, 5, {14,15}, selection_text_style.style, + {{HighlightLayerType::kOriginating, 0, {0,25}, originating_color}, + {HighlightLayerType::kCustom, 2, {10,19}, originating_color}, + {HighlightLayerType::kSelection, 5, {13,19}, selection_color}}}, + HighlightPart{HighlightLayerType::kSelection, 5, {15,19}, selection_text_style.style, + {{HighlightLayerType::kOriginating, 0, {0,25}, originating_color}, + {HighlightLayerType::kCustom, 2, {10,19}, originating_color}, + {HighlightLayerType::kTargetText, 4, {15,23}, originating_color}, + {HighlightLayerType::kSelection, 5, {13,19}, selection_color}}}, + HighlightPart{HighlightLayerType::kTargetText, 4, {19,20}, originating_text_style.style, + {{HighlightLayerType::kOriginating, 0, {0,25}, originating_color}, + {HighlightLayerType::kTargetText, 4, {15,23}, originating_color}}}, + HighlightPart{HighlightLayerType::kTargetText, 4, {20,23}, spelling_text_style.style, + {{HighlightLayerType::kOriginating, 0, {0,25}, originating_color}, + {HighlightLayerType::kSpelling, 3, {20,23}, spelling_color}, + {HighlightLayerType::kTargetText, 4, {15,23}, spelling_color}}}, + HighlightPart{HighlightLayerType::kOriginating, 0, {23,25}, originating_text_style.style, + {{HighlightLayerType::kOriginating, 0, {0,25}, originating_color}}}, })) << "should return correct parts given several active highlights"; @@ -426,44 +484,44 @@ EXPECT_EQ(HighlightOverlay::ComputeParts(originating, layers, edges3), (Vector<HighlightPart>{ - HighlightPart{HighlightLayerType::kOriginating, 0, {0,6}, - {{HighlightLayerType::kOriginating, 0, {0,25}}}}, - HighlightPart{HighlightLayerType::kSpelling, 3, {6,9}, - {{HighlightLayerType::kOriginating, 0, {0,25}}, - {HighlightLayerType::kCustom, 1, {6,14}}, - {HighlightLayerType::kSpelling, 3, {6,9}}}}, - HighlightPart{HighlightLayerType::kCustom, 1, {9,10}, - {{HighlightLayerType::kOriginating, 0, {0,25}}, - {HighlightLayerType::kCustom, 1, {6,14}}}}, - HighlightPart{HighlightLayerType::kSpelling, 3, {10,13}, - {{HighlightLayerType::kOriginating, 0, {0,25}}, - {HighlightLayerType::kCustom, 1, {6,14}}, - {HighlightLayerType::kCustom, 2, {10,19}}, - {HighlightLayerType::kSpelling, 3, {10,14}}}}, - HighlightPart{HighlightLayerType::kSelection, 5, {13,14}, - {{HighlightLayerType::kOriginating, 0, {0,25}}, - {HighlightLayerType::kCustom, 1, {6,14}}, - {HighlightLayerType::kCustom, 2, {10,19}}, - {HighlightLayerType::kSpelling, 3, {10,14}}, - {HighlightLayerType::kSelection, 5, {13,19}}}}, - HighlightPart{HighlightLayerType::kSelection, 5, {14,15}, - {{HighlightLayerType::kOriginating, 0, {0,25}}, - {HighlightLayerType::kCustom, 2, {10,19}}, - {HighlightLayerType::kSelection, 5, {13,19}}}}, - HighlightPart{HighlightLayerType::kSelection, 5, {15,19}, - {{HighlightLayerType::kOriginating, 0, {0,25}}, - {HighlightLayerType::kCustom, 2, {10,19}}, - {HighlightLayerType::kTargetText, 4, {15,23}}, - {HighlightLayerType::kSelection, 5, {13,19}}}}, - HighlightPart{HighlightLayerType::kTargetText, 4, {19,20}, - {{HighlightLayerType::kOriginating, 0, {0,25}}, - {HighlightLayerType::kTargetText, 4, {15,23}}}}, - HighlightPart{HighlightLayerType::kTargetText, 4, {20,23}, - {{HighlightLayerType::kOriginating, 0, {0,25}}, - {HighlightLayerType::kSpelling, 3, {20,23}}, - {HighlightLayerType::kTargetText, 4,{15,23}}}}, - HighlightPart{HighlightLayerType::kOriginating, 0, {23,25}, - {{HighlightLayerType::kOriginating, 0, {0,25}}}}, + HighlightPart{HighlightLayerType::kOriginating, 0, {0,6}, originating_text_style.style, + {{HighlightLayerType::kOriginating, 0, {0,25}, originating_color}}}, + HighlightPart{HighlightLayerType::kSpelling, 3, {6,9}, spelling_text_style.style, + {{HighlightLayerType::kOriginating, 0, {0,25}, originating_color}, + {HighlightLayerType::kCustom, 1, {6,14}, foo_color}, + {HighlightLayerType::kSpelling, 3, {6,9}, spelling_color}}}, + HighlightPart{HighlightLayerType::kCustom, 1, {9,10}, foo_text_style.style, + {{HighlightLayerType::kOriginating, 0, {0,25}, originating_color}, + {HighlightLayerType::kCustom, 1, {6,14}, foo_color}}}, + HighlightPart{HighlightLayerType::kSpelling, 3, {10,13}, spelling_text_style.style, + {{HighlightLayerType::kOriginating, 0, {0,25}, originating_color}, + {HighlightLayerType::kCustom, 1, {6,14}, foo_color}, + {HighlightLayerType::kCustom, 2, {10,19}, foo_color}, + {HighlightLayerType::kSpelling, 3, {10,14}, spelling_color}}}, + HighlightPart{HighlightLayerType::kSelection, 5, {13,14}, selection_text_style.style, + {{HighlightLayerType::kOriginating, 0, {0,25}, originating_color}, + {HighlightLayerType::kCustom, 1, {6,14}, foo_color}, + {HighlightLayerType::kCustom, 2, {10,19}, foo_color}, + {HighlightLayerType::kSpelling, 3, {10,14}, spelling_color}, + {HighlightLayerType::kSelection, 5, {13,19}, selection_color}}}, + HighlightPart{HighlightLayerType::kSelection, 5, {14,15}, selection_text_style.style, + {{HighlightLayerType::kOriginating, 0, {0,25}, originating_color}, + {HighlightLayerType::kCustom, 2, {10,19}, originating_color}, + {HighlightLayerType::kSelection, 5, {13,19}, selection_color}}}, + HighlightPart{HighlightLayerType::kSelection, 5, {15,19}, selection_text_style.style, + {{HighlightLayerType::kOriginating, 0, {0,25}, originating_color}, + {HighlightLayerType::kCustom, 2, {10,19}, originating_color}, + {HighlightLayerType::kTargetText, 4, {15,23}, originating_color}, + {HighlightLayerType::kSelection, 5, {13,19}, selection_color}}}, + HighlightPart{HighlightLayerType::kTargetText, 4, {19,20}, originating_text_style.style, + {{HighlightLayerType::kOriginating, 0, {0,25}, originating_color}, + {HighlightLayerType::kTargetText, 4, {15,23}, originating_color}}}, + HighlightPart{HighlightLayerType::kTargetText, 4, {20,23}, spelling_text_style.style, + {{HighlightLayerType::kOriginating, 0, {0,25}, originating_color}, + {HighlightLayerType::kSpelling, 3, {20,23}, spelling_color}, + {HighlightLayerType::kTargetText, 4, {15,23}, spelling_color}}}, + HighlightPart{HighlightLayerType::kOriginating, 0, {23,25}, originating_text_style.style, + {{HighlightLayerType::kOriginating, 0, {0,25}, originating_color}}}, })) << "correct when first edge starts after start of originating fragment"; @@ -484,33 +542,33 @@ EXPECT_EQ(HighlightOverlay::ComputeParts(originating2, layers, edges4), (Vector<HighlightPart>{ - HighlightPart{HighlightLayerType::kSpelling, 3, {8,9}, - {{HighlightLayerType::kOriginating, 0, {8,18}}, - {HighlightLayerType::kCustom, 1, {8,14}}, - {HighlightLayerType::kSpelling, 3, {8,9}}}}, - HighlightPart{HighlightLayerType::kCustom, 1, {9,10}, - {{HighlightLayerType::kOriginating, 0, {8,18}}, - {HighlightLayerType::kCustom, 1, {8,14}}}}, - HighlightPart{HighlightLayerType::kSpelling, 3, {10,13}, - {{HighlightLayerType::kOriginating, 0, {8,18}}, - {HighlightLayerType::kCustom, 1, {8,14}}, - {HighlightLayerType::kCustom, 2, {10,18}}, - {HighlightLayerType::kSpelling, 3, {10,14}}}}, - HighlightPart{HighlightLayerType::kSelection, 5, {13,14}, - {{HighlightLayerType::kOriginating, 0, {8,18}}, - {HighlightLayerType::kCustom, 1, {8,14}}, - {HighlightLayerType::kCustom, 2, {10,18}}, - {HighlightLayerType::kSpelling, 3, {10,14}}, - {HighlightLayerType::kSelection, 5, {13,18}}}}, - HighlightPart{HighlightLayerType::kSelection, 5, {14,15}, - {{HighlightLayerType::kOriginating, 0, {8,18}}, - {HighlightLayerType::kCustom, 2, {10,18}}, - {HighlightLayerType::kSelection, 5, {13,18}}}}, - HighlightPart{HighlightLayerType::kSelection, 5, {15,18}, - {{HighlightLayerType::kOriginating, 0, {8,18}}, - {HighlightLayerType::kCustom, 2, {10,18}}, - {HighlightLayerType::kTargetText, 4, {15,18}}, - {HighlightLayerType::kSelection, 5, {13,18}}}}, + HighlightPart{HighlightLayerType::kSpelling, 3, {8,9}, spelling_text_style.style, + {{HighlightLayerType::kOriginating, 0, {8,18}, originating_color}, + {HighlightLayerType::kCustom, 1, {8,14}, foo_color}, + {HighlightLayerType::kSpelling, 3, {8,9}, spelling_color}}}, + HighlightPart{HighlightLayerType::kCustom, 1, {9,10}, foo_text_style.style, + {{HighlightLayerType::kOriginating, 0, {8,18}, originating_color}, + {HighlightLayerType::kCustom, 1, {8,14}, foo_color}}}, + HighlightPart{HighlightLayerType::kSpelling, 3, {10,13}, spelling_text_style.style, + {{HighlightLayerType::kOriginating, 0, {8,18}, originating_color}, + {HighlightLayerType::kCustom, 1, {8,14}, foo_color}, + {HighlightLayerType::kCustom, 2, {10,18}, foo_color}, + {HighlightLayerType::kSpelling, 3, {10,14}, spelling_color}}}, + HighlightPart{HighlightLayerType::kSelection, 5, {13,14}, selection_text_style.style, + {{HighlightLayerType::kOriginating, 0, {8,18}, originating_color}, + {HighlightLayerType::kCustom, 1, {8,14}, foo_color}, + {HighlightLayerType::kCustom, 2, {10,18}, foo_color}, + {HighlightLayerType::kSpelling, 3, {10,14}, spelling_color}, + {HighlightLayerType::kSelection, 5, {13,18}, selection_color}}}, + HighlightPart{HighlightLayerType::kSelection, 5, {14,15}, selection_text_style.style, + {{HighlightLayerType::kOriginating, 0, {8,18}, originating_color}, + {HighlightLayerType::kCustom, 2, {10,18}, originating_color}, + {HighlightLayerType::kSelection, 5, {13,18}, selection_color}}}, + HighlightPart{HighlightLayerType::kSelection, 5, {15,18}, selection_text_style.style, + {{HighlightLayerType::kOriginating, 0, {8,18}, originating_color}, + {HighlightLayerType::kCustom, 2, {10,18}, originating_color}, + {HighlightLayerType::kTargetText, 4, {15,18}, originating_color}, + {HighlightLayerType::kSelection, 5, {13,18}, selection_color}}}, })) << "should clamp result to originating fragment offsets"; @@ -529,16 +587,16 @@ EXPECT_EQ(HighlightOverlay::ComputeParts(originating2, layers, edges5), (Vector<HighlightPart>{ - HighlightPart{HighlightLayerType::kSpelling, 3, {8,9}, - {{HighlightLayerType::kOriginating, 0, {8,18}}, - {HighlightLayerType::kSpelling, 3, {8,9}}}}, - HighlightPart{HighlightLayerType::kOriginating, 0, {9,10}, - {{HighlightLayerType::kOriginating, 0, {8,18}}}}, - HighlightPart{HighlightLayerType::kSpelling, 3, {10,14}, - {{HighlightLayerType::kOriginating, 0, {8,18}}, - {HighlightLayerType::kSpelling, 3, {10,14}}}}, - HighlightPart{HighlightLayerType::kOriginating, 0, {14,18}, - {{HighlightLayerType::kOriginating, 0, {8,18}}}}, + HighlightPart{HighlightLayerType::kSpelling, 3, {8,9}, spelling_text_style.style, + {{HighlightLayerType::kOriginating, 0, {8,18}, originating_color}, + {HighlightLayerType::kSpelling, 3, {8,9}, spelling_color}}}, + HighlightPart{HighlightLayerType::kOriginating, 0, {9,10}, originating_text_style.style, + {{HighlightLayerType::kOriginating, 0, {8,18}, originating_color}}}, + HighlightPart{HighlightLayerType::kSpelling, 3, {10,14}, spelling_text_style.style, + {{HighlightLayerType::kOriginating, 0, {8,18}, originating_color}, + {HighlightLayerType::kSpelling, 3, {10,14}, spelling_color}}}, + HighlightPart{HighlightLayerType::kOriginating, 0, {14,18}, originating_text_style.style, + {{HighlightLayerType::kOriginating, 0, {8,18}, originating_color}}}, })) << "should not crash if there is a gap in active layers"; @@ -559,8 +617,8 @@ EXPECT_EQ(HighlightOverlay::ComputeParts(originating3, layers, edges6), (Vector<HighlightPart>{ - HighlightPart{HighlightLayerType::kOriginating, 0, {1,4}, - {{HighlightLayerType::kOriginating, 0, {1,4}}}}, + HighlightPart{HighlightLayerType::kOriginating, 0, {1,4}, originating_text_style.style, + {{HighlightLayerType::kOriginating, 0, {1,4}, originating_color}}}, })) << "correct when first edge starts after end of originating fragment"; @@ -581,8 +639,8 @@ EXPECT_EQ(HighlightOverlay::ComputeParts(originating4, layers, edges7), (Vector<HighlightPart>{ - HighlightPart{HighlightLayerType::kOriginating, 0, {25,28}, - {{HighlightLayerType::kOriginating, 0, {25,28}}}}, + HighlightPart{HighlightLayerType::kOriginating, 0, {25,28}, originating_text_style.style, + {{HighlightLayerType::kOriginating, 0, {25,28}, originating_color}}}, })) << "correct when last edge ends before start of originating fragment"; }
diff --git a/third_party/blink/renderer/core/paint/highlight_painter.cc b/third_party/blink/renderer/core/paint/highlight_painter.cc index a9844284..5979b20 100644 --- a/third_party/blink/renderer/core/paint/highlight_painter.cc +++ b/third_party/blink/renderer/core/paint/highlight_painter.cc
@@ -855,29 +855,20 @@ } } - // For each overlay, paint the text proper over every highlighted range, - // except any parts for which we’re not the topmost active highlight. - for (wtf_size_t i = 0; i < layers_.size(); ++i) { - HighlightLayer& layer = layers_[i]; - if (layer.type == HighlightLayerType::kOriginating || - layer.type == HighlightLayerType::kSelection) { + // For each part, paint the text proper over every highlighted range, + for (auto part : parts_) { + if (part.type == HighlightLayerType::kOriginating || + part.type == HighlightLayerType::kSelection) { continue; } - for (const HighlightPart& part : parts_) { - if (part.layer_index != static_cast<uint16_t>(i)) { - continue; - } - - // TODO(crbug.com/1434114) expand range to include partial glyphs, then - // paint with clipping (TextPainter::PaintSelectedText) - PaintDecorationsExceptLineThrough(part); - text_painter_.Paint( - fragment_paint_info_.Slice(part.range.from, part.range.to), - layer.text_style.style, node_id, foreground_auto_dark_mode_, - TextPainterBase::kTextProperOnly); - PaintDecorationsOnlyLineThrough(part); - } + // TODO(crbug.com/1434114) expand range to include partial glyphs, then + // paint with clipping (TextPainter::PaintSelectedText) + PaintDecorationsExceptLineThrough(part); + text_painter_.Paint( + fragment_paint_info_.Slice(part.range.from, part.range.to), part.style, + node_id, foreground_auto_dark_mode_, TextPainterBase::kTextProperOnly); + PaintDecorationsOnlyLineThrough(part); } // Paint ::selection foreground, including its shadows. @@ -1071,16 +1062,10 @@ if (part.type != HighlightLayerType::kOriginating) { if (decoration.type == HighlightLayerType::kOriginating) { - decoration_info->SetHighlightOverrideColor( - layers_[part.layer_index].text_style.style.current_color); + decoration_info->SetHighlightOverrideColor(part.style.current_color); } else { decoration_info->SetHighlightOverrideColor( - HighlightStyleUtils::ResolveColor( - layout_object_->GetDocument(), originating_style_, - decoration_layer.style.Get(), decoration_layer.PseudoId(), - GetCSSPropertyTextDecorationColor(), - layers_[decoration.layer_index - 1] - .text_style.style.current_color)); + decoration.highlight_override_color); } } @@ -1134,16 +1119,10 @@ if (part.type != HighlightLayerType::kOriginating) { if (decoration.type == HighlightLayerType::kOriginating) { - decoration_info->SetHighlightOverrideColor( - layers_[part.layer_index].text_style.style.current_color); + decoration_info->SetHighlightOverrideColor(part.style.current_color); } else { decoration_info->SetHighlightOverrideColor( - HighlightStyleUtils::ResolveColor( - layout_object_->GetDocument(), originating_style_, - decoration_layer.style.Get(), decoration_layer.PseudoId(), - GetCSSPropertyTextDecorationColor(), - layers_[decoration.layer_index - 1] - .text_style.style.current_color)); + decoration.highlight_override_color); } }
diff --git a/third_party/blink/renderer/core/testing/fake_local_frame_host.cc b/third_party/blink/renderer/core/testing/fake_local_frame_host.cc index f0742d3a..f1175c8c 100644 --- a/third_party/blink/renderer/core/testing/fake_local_frame_host.cc +++ b/third_party/blink/renderer/core/testing/fake_local_frame_host.cc
@@ -274,6 +274,12 @@ std::move(callback).Run(); } +void FakeLocalFrameHost::ExemptUrlFromNetworkRevocationForTesting( + const blink::KURL& exempted_url, + ExemptUrlFromNetworkRevocationForTestingCallback callback) { + std::move(callback).Run(); +} + void FakeLocalFrameHost::SendLegacyTechEvent( const WTF::String& type, mojom::blink::LegacyTechEventCodeLocationPtr code_location) {}
diff --git a/third_party/blink/renderer/core/testing/fake_local_frame_host.h b/third_party/blink/renderer/core/testing/fake_local_frame_host.h index 566684cf..861205e 100644 --- a/third_party/blink/renderer/core/testing/fake_local_frame_host.h +++ b/third_party/blink/renderer/core/testing/fake_local_frame_host.h
@@ -189,6 +189,9 @@ bool cross_origin_exposed) override; void DisableUntrustedNetworkInFencedFrame( DisableUntrustedNetworkInFencedFrameCallback callback) override; + void ExemptUrlFromNetworkRevocationForTesting( + const blink::KURL& exempted_url, + ExemptUrlFromNetworkRevocationForTestingCallback callback) override; void SendLegacyTechEvent( const WTF::String& type, mojom::blink::LegacyTechEventCodeLocationPtr code_location) override;
diff --git a/third_party/blink/renderer/core/testing/internals.cc b/third_party/blink/renderer/core/testing/internals.cc index 13fa89f..aff535eb0 100644 --- a/third_party/blink/renderer/core/testing/internals.cc +++ b/third_party/blink/renderer/core/testing/internals.cc
@@ -4050,4 +4050,38 @@ return promise; } +ScriptPromise Internals::exemptUrlFromNetworkRevocation( + ScriptState* script_state, + const String& url) { + if (!blink::features::IsFencedFramesEnabled()) { + return ScriptPromise(); + } + if (!base::FeatureList::IsEnabled( + blink::features::kFencedFramesLocalUnpartitionedDataAccess)) { + return ScriptPromise(); + } + if (!base::FeatureList::IsEnabled( + blink::features::kExemptUrlFromNetworkRevocationForTesting)) { + return ScriptPromise(); + } + if (!GetFrame()) { + return ScriptPromise(); + } + LocalFrame* frame = GetFrame(); + DCHECK(frame->GetDocument()); + auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); + ScriptPromise promise = resolver->Promise(); + frame->GetLocalFrameHostRemote().ExemptUrlFromNetworkRevocationForTesting( + url_test_helpers::ToKURL(url.Utf8()), + resolver->WrapCallbackInScriptScope( + WTF::BindOnce(&Internals::ExemptUrlFromNetworkRevocationComplete, + WrapPersistent(this)))); + return promise; +} + +void Internals::ExemptUrlFromNetworkRevocationComplete( + ScriptPromiseResolver* resolver) { + resolver->Resolve(); +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/testing/internals.h b/third_party/blink/renderer/core/testing/internals.h index cd01533..171a16e 100644 --- a/third_party/blink/renderer/core/testing/internals.h +++ b/third_party/blink/renderer/core/testing/internals.h
@@ -640,6 +640,8 @@ ScriptPromiseTyped<IDLString> LCPPrediction(ScriptState*, Document* document); + ScriptPromise exemptUrlFromNetworkRevocation(ScriptState*, const String& url); + private: Document* ContextDocument() const; Vector<String> IconURLs(Document*, int icon_types_mask) const; @@ -658,6 +660,8 @@ ExceptionState&); void ResolveResourcePriority(ScriptPromiseResolverTyped<IDLLong>*, int resource_load_priority); + void ExemptUrlFromNetworkRevocationComplete(ScriptPromiseResolver* resolver); + Member<InternalRuntimeFlags> runtime_flags_; Member<Document> document_; std::optional<ColorSchemeHelper> color_scheme_helper_;
diff --git a/third_party/blink/renderer/core/testing/internals.idl b/third_party/blink/renderer/core/testing/internals.idl index 5ce29d6..aaaffa30 100644 --- a/third_party/blink/renderer/core/testing/internals.idl +++ b/third_party/blink/renderer/core/testing/internals.idl
@@ -455,4 +455,8 @@ // failed. Returns element_locator format string. [CallWith=ScriptState] Promise<DOMString> LCPPrediction(Document document); + // Exempt `url` from fenced frames network revocation for the current + // NetworkContext. Intended to be used to allow remote context executors to + // continue functioning in fenced frame WPTs after network is revoked. + [CallWith=ScriptState] Promise<undefined> exemptUrlFromNetworkRevocation(USVString url); };
diff --git a/third_party/blink/renderer/modules/ad_auction/navigator_auction.cc b/third_party/blink/renderer/modules/ad_auction/navigator_auction.cc index 1426a646..a392a95 100644 --- a/third_party/blink/renderer/modules/ad_auction/navigator_auction.cc +++ b/third_party/blink/renderer/modules/ad_auction/navigator_auction.cc
@@ -1653,7 +1653,8 @@ mojom::blink::AuctionAdConfig& output) { if (!input.hasDeprecatedRenderURLReplacements()) { // If the page passed no ad replacements, do nothing and pass an empty map. - output.deprecated_render_url_replacements = mojom::blink:: + output.auction_ad_config_non_shared_params + ->deprecated_render_url_replacements = mojom::blink:: AuctionAdConfigMaybePromiseDeprecatedRenderURLReplacements::NewValue( {}); return; @@ -1663,7 +1664,8 @@ MakeGarbageCollected<NavigatorAuction::AuctionHandle:: DeprecatedRenderURLReplacementsResolved>( auction_handle, auction_id->Clone(), input.seller())); - output.deprecated_render_url_replacements = mojom::blink:: + output.auction_ad_config_non_shared_params + ->deprecated_render_url_replacements = mojom::blink:: AuctionAdConfigMaybePromiseDeprecatedRenderURLReplacements::NewPromise(0); }
diff --git a/third_party/blink/renderer/modules/cache_storage/cache.cc b/third_party/blink/renderer/modules/cache_storage/cache.cc index b3a18b5..1731202 100644 --- a/third_party/blink/renderer/modules/cache_storage/cache.cc +++ b/third_party/blink/renderer/modules/cache_storage/cache.cc
@@ -183,8 +183,9 @@ const ExceptionContext& exception_context, int64_t trace_id) : resolver_( - MakeGarbageCollected<ScriptPromiseResolver>(script_state, - exception_context)), + MakeGarbageCollected<ScriptPromiseResolverTyped<IDLUndefined>>( + script_state, + exception_context)), cache_(cache), method_name_(method_name), request_list_(request_list), @@ -198,7 +199,9 @@ } // Must be called prior to starting the load of any response. - ScriptPromise Promise() const { return resolver_->Promise(); } + ScriptPromiseTyped<IDLUndefined> Promise() const { + return resolver_->Promise(); + } AbortSignal* Signal() const { return abort_controller_ ? abort_controller_->signal() : nullptr; @@ -230,24 +233,15 @@ } void FailedResponse() { - ScriptState* state = resolver_->GetScriptState(); - if (state->ContextIsValid()) { - ScriptState::Scope scope(state); - resolver_->Reject(V8ThrowDOMException::CreateOrEmpty( - state->GetIsolate(), DOMExceptionCode::kNetworkError, - method_name_ + " encountered a network error")); - } + resolver_->RejectWithDOMException( + DOMExceptionCode::kNetworkError, + method_name_ + " encountered a network error"); Stop(); } void AbortedResponse() { - ScriptState* state = resolver_->GetScriptState(); - if (state->ContextIsValid()) { - ScriptState::Scope scope(state); - resolver_->Reject(V8ThrowDOMException::CreateOrEmpty( - state->GetIsolate(), DOMExceptionCode::kAbortError, - method_name_ + " was aborted")); - } + resolver_->RejectWithDOMException(DOMExceptionCode::kAbortError, + method_name_ + " was aborted"); Stop(); } @@ -281,7 +275,7 @@ stopped_ = true; } - Member<ScriptPromiseResolver> resolver_; + Member<ScriptPromiseResolverTyped<IDLUndefined>> resolver_; Member<AbortController> abort_controller_; Member<Cache> cache_; const String method_name_; @@ -381,11 +375,12 @@ class Cache::BarrierCallbackForPutComplete final : public GarbageCollected<BarrierCallbackForPutComplete> { public: - BarrierCallbackForPutComplete(wtf_size_t number_of_operations, - Cache* cache, - const String& method_name, - ScriptPromiseResolver* resolver, - int64_t trace_id) + BarrierCallbackForPutComplete( + wtf_size_t number_of_operations, + Cache* cache, + const String& method_name, + ScriptPromiseResolverTyped<IDLUndefined>* resolver, + int64_t trace_id) : number_of_remaining_operations_(number_of_operations), cache_(cache), method_name_(method_name), @@ -419,7 +414,7 @@ resolver_->WrapCallbackInScriptScope(WTF::BindOnce( [](const String& method_name, base::TimeTicks start_time, int operation_count, int64_t trace_id, Cache* _, - ScriptPromiseResolver* resolver, + ScriptPromiseResolverTyped<IDLUndefined>* resolver, mojom::blink::CacheStorageVerboseErrorPtr error) { base::TimeDelta elapsed = base::TimeTicks::Now() - start_time; TRACE_EVENT_WITH_FLOW1( @@ -463,25 +458,15 @@ if (!StillActive()) return; completed_ = true; - ScriptState* state = resolver_->GetScriptState(); - if (!state->ContextIsValid()) - return; - ScriptState::Scope scope(state); - resolver_->Reject( - V8ThrowException::CreateTypeError(state->GetIsolate(), error_message)); + resolver_->RejectWithTypeError(error_message); } void Abort() { if (!StillActive()) return; completed_ = true; - ScriptState* state = resolver_->GetScriptState(); - if (!state->ContextIsValid()) - return; - ScriptState::Scope scope(state); - resolver_->Reject(V8ThrowDOMException::CreateOrEmpty( - state->GetIsolate(), DOMExceptionCode::kAbortError, - method_name_ + " was aborted")); + resolver_->RejectWithDOMException(DOMExceptionCode::kAbortError, + method_name_ + " was aborted"); } virtual void Trace(Visitor* visitor) const { @@ -532,7 +517,7 @@ int number_of_remaining_operations_; Member<Cache> cache_; const String method_name_; - Member<ScriptPromiseResolver> resolver_; + Member<ScriptPromiseResolverTyped<IDLUndefined>> resolver_; Vector<mojom::blink::BatchOperationPtr> batch_operations_; const int64_t trace_id_; }; @@ -757,9 +742,9 @@ return MatchAllImpl(script_state, request_object, options, exception_state); } -ScriptPromise Cache::add(ScriptState* script_state, - const V8RequestInfo* request, - ExceptionState& exception_state) { +ScriptPromiseTyped<IDLUndefined> Cache::add(ScriptState* script_state, + const V8RequestInfo* request, + ExceptionState& exception_state) { DCHECK(request); HeapVector<Member<Request>> requests; switch (request->GetContentType()) { @@ -770,15 +755,16 @@ requests.push_back(Request::Create( script_state, request->GetAsUSVString(), exception_state)); if (exception_state.HadException()) - return ScriptPromise(); + return ScriptPromiseTyped<IDLUndefined>(); break; } return AddAllImpl(script_state, "Cache.add()", requests, exception_state); } -ScriptPromise Cache::addAll(ScriptState* script_state, - const HeapVector<Member<V8RequestInfo>>& requests, - ExceptionState& exception_state) { +ScriptPromiseTyped<IDLUndefined> Cache::addAll( + ScriptState* script_state, + const HeapVector<Member<V8RequestInfo>>& requests, + ExceptionState& exception_state) { HeapVector<Member<Request>> request_objects; for (const V8RequestInfo* request : requests) { switch (request->GetContentType()) { @@ -789,7 +775,7 @@ request_objects.push_back(Request::Create( script_state, request->GetAsUSVString(), exception_state)); if (exception_state.HadException()) - return ScriptPromise(); + return ScriptPromiseTyped<IDLUndefined>(); break; } } @@ -817,10 +803,10 @@ return DeleteImpl(script_state, request_object, options, exception_state); } -ScriptPromise Cache::put(ScriptState* script_state, - const V8RequestInfo* request_info, - Response* response, - ExceptionState& exception_state) { +ScriptPromiseTyped<IDLUndefined> Cache::put(ScriptState* script_state, + const V8RequestInfo* request_info, + Response* response, + ExceptionState& exception_state) { DCHECK(request_info); int64_t trace_id = blink::cache_storage::CreateTraceId(); TRACE_EVENT_WITH_FLOW0("CacheStorage", "Cache::put", @@ -834,13 +820,13 @@ request = Request::Create(script_state, request_info->GetAsUSVString(), exception_state); if (exception_state.HadException()) - return ScriptPromise(); + return ScriptPromiseTyped<IDLUndefined>(); break; } ValidateRequestForPut(request, exception_state); if (exception_state.HadException()) - return ScriptPromise(); + return ScriptPromiseTyped<IDLUndefined>(); auto* barrier_callback = MakeGarbageCollected<BarrierCallbackForPutResponse>( script_state, this, "Cache.put()", @@ -848,7 +834,7 @@ trace_id); // We must get the promise before any rejections can happen during loading. - ScriptPromise promise = barrier_callback->Promise(); + auto promise = barrier_callback->Promise(); auto* loader = MakeGarbageCollected<ResponseBodyLoader>( script_state, barrier_callback, /*index=*/0, @@ -1072,22 +1058,23 @@ return promise; } -ScriptPromise Cache::AddAllImpl(ScriptState* script_state, - const String& method_name, - const HeapVector<Member<Request>>& request_list, - ExceptionState& exception_state) { +ScriptPromiseTyped<IDLUndefined> Cache::AddAllImpl( + ScriptState* script_state, + const String& method_name, + const HeapVector<Member<Request>>& request_list, + ExceptionState& exception_state) { int64_t trace_id = blink::cache_storage::CreateTraceId(); TRACE_EVENT_WITH_FLOW0("CacheStorage", "Cache::AddAllImpl", TRACE_ID_GLOBAL(trace_id), TRACE_EVENT_FLAG_FLOW_OUT); if (request_list.empty()) - return ScriptPromise::CastUndefined(script_state); + return ToResolvedUndefinedPromise(script_state); // Validate all requests before starting to load or store any of them. for (wtf_size_t i = 0; i < request_list.size(); ++i) { ValidateRequestForPut(request_list[i], exception_state); if (exception_state.HadException()) - return ScriptPromise(); + return ScriptPromiseTyped<IDLUndefined>(); } auto* barrier_callback = MakeGarbageCollected<BarrierCallbackForPutResponse>( @@ -1095,7 +1082,7 @@ exception_state.GetContext(), trace_id); // We must get the promise before any rejections can happen during loading. - ScriptPromise promise = barrier_callback->Promise(); + auto promise = barrier_callback->Promise(); // Begin loading each of the requests. for (wtf_size_t i = 0; i < request_list.size(); ++i) { @@ -1198,7 +1185,7 @@ return promise; } -void Cache::PutImpl(ScriptPromiseResolver* resolver, +void Cache::PutImpl(ScriptPromiseResolverTyped<IDLUndefined>* resolver, const String& method_name, const HeapVector<Member<Request>>& requests, const HeapVector<Member<Response>>& responses,
diff --git a/third_party/blink/renderer/modules/cache_storage/cache.h b/third_party/blink/renderer/modules/cache_storage/cache.h index f89c25a..2d9f7186 100644 --- a/third_party/blink/renderer/modules/cache_storage/cache.h +++ b/third_party/blink/renderer/modules/cache_storage/cache.h
@@ -11,6 +11,7 @@ #include "mojo/public/cpp/bindings/pending_associated_remote.h" #include "third_party/blink/public/mojom/cache_storage/cache_storage.mojom-blink.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" +#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" #include "third_party/blink/renderer/bindings/core/v8/v8_typedefs.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_cache_query_options.h" #include "third_party/blink/renderer/core/fetch/global_fetch.h" @@ -46,7 +47,6 @@ class ExceptionState; class Response; class Request; -class ScriptPromiseResolver; class ScriptState; class MODULES_EXPORT Cache : public ScriptWrappable { @@ -73,20 +73,21 @@ const V8RequestInfo* request, const CacheQueryOptions* options, ExceptionState& exception_state); - ScriptPromise add(ScriptState* script_state, - const V8RequestInfo* request, - ExceptionState& exception_state); - ScriptPromise addAll(ScriptState* script_state, - const HeapVector<Member<V8RequestInfo>>& requests, - ExceptionState& exception_state); + ScriptPromiseTyped<IDLUndefined> add(ScriptState* script_state, + const V8RequestInfo* request, + ExceptionState& exception_state); + ScriptPromiseTyped<IDLUndefined> addAll( + ScriptState* script_state, + const HeapVector<Member<V8RequestInfo>>& requests, + ExceptionState& exception_state); ScriptPromiseTyped<IDLBoolean> Delete(ScriptState* script_state, const V8RequestInfo* request, const CacheQueryOptions* options, ExceptionState& exception_state); - ScriptPromise put(ScriptState* script_state, - const V8RequestInfo* request, - Response* response, - ExceptionState& exception_state); + ScriptPromiseTyped<IDLUndefined> put(ScriptState* script_state, + const V8RequestInfo* request, + Response* response, + ExceptionState& exception_state); ScriptPromiseTyped<IDLSequence<Request>> keys(ScriptState*, ExceptionState&); ScriptPromiseTyped<IDLSequence<Request>> keys( ScriptState* script_state, @@ -116,15 +117,16 @@ const Request*, const CacheQueryOptions*, ExceptionState&); - ScriptPromise AddAllImpl(ScriptState*, - const String& method_name, - const HeapVector<Member<Request>>&, - ExceptionState&); + ScriptPromiseTyped<IDLUndefined> AddAllImpl( + ScriptState*, + const String& method_name, + const HeapVector<Member<Request>>&, + ExceptionState&); ScriptPromiseTyped<IDLBoolean> DeleteImpl(ScriptState*, const Request*, const CacheQueryOptions*, ExceptionState&); - void PutImpl(ScriptPromiseResolver*, + void PutImpl(ScriptPromiseResolverTyped<IDLUndefined>*, const String& method_name, const HeapVector<Member<Request>>&, const HeapVector<Member<Response>>&,
diff --git a/third_party/blink/renderer/modules/cache_storage/cache.idl b/third_party/blink/renderer/modules/cache_storage/cache.idl index 4c50fd9..9ad1f6f7 100644 --- a/third_party/blink/renderer/modules/cache_storage/cache.idl +++ b/third_party/blink/renderer/modules/cache_storage/cache.idl
@@ -16,13 +16,13 @@ optional CacheQueryOptions options = {}); [CallWith=ScriptState, MeasureAs=CacheStorageWrite, RaisesException] - Promise<void> add(RequestInfo request); + Promise<undefined> add(RequestInfo request); [CallWith=ScriptState, MeasureAs=CacheStorageWrite, RaisesException] - Promise<void> addAll(sequence<RequestInfo> requests); + Promise<undefined> addAll(sequence<RequestInfo> requests); [CallWith=ScriptState, MeasureAs=CacheStorageWrite, RaisesException] - Promise<void> put(RequestInfo request, Response response); + Promise<undefined> put(RequestInfo request, Response response); [ CallWith=ScriptState,
diff --git a/third_party/blink/renderer/modules/clipboard/clipboard.cc b/third_party/blink/renderer/modules/clipboard/clipboard.cc index c7abc60d..1b5f599 100644 --- a/third_party/blink/renderer/modules/clipboard/clipboard.cc +++ b/third_party/blink/renderer/modules/clipboard/clipboard.cc
@@ -45,16 +45,18 @@ script_state, exception_state); } -ScriptPromise Clipboard::write(ScriptState* script_state, - const HeapVector<Member<ClipboardItem>>& data, - ExceptionState& exception_state) { +ScriptPromiseTyped<IDLUndefined> Clipboard::write( + ScriptState* script_state, + const HeapVector<Member<ClipboardItem>>& data, + ExceptionState& exception_state) { return ClipboardPromise::CreateForWrite(GetExecutionContext(), script_state, std::move(data), exception_state); } -ScriptPromise Clipboard::writeText(ScriptState* script_state, - const String& data, - ExceptionState& exception_state) { +ScriptPromiseTyped<IDLUndefined> Clipboard::writeText( + ScriptState* script_state, + const String& data, + ExceptionState& exception_state) { return ClipboardPromise::CreateForWriteText( GetExecutionContext(), script_state, data, exception_state); }
diff --git a/third_party/blink/renderer/modules/clipboard/clipboard.h b/third_party/blink/renderer/modules/clipboard/clipboard.h index 8d1301f..08aceee 100644 --- a/third_party/blink/renderer/modules/clipboard/clipboard.h +++ b/third_party/blink/renderer/modules/clipboard/clipboard.h
@@ -38,10 +38,13 @@ } ScriptPromiseTyped<IDLString> readText(ScriptState*, ExceptionState&); - ScriptPromise write(ScriptState*, - const HeapVector<Member<ClipboardItem>>&, - ExceptionState&); - ScriptPromise writeText(ScriptState*, const String&, ExceptionState&); + ScriptPromiseTyped<IDLUndefined> write( + ScriptState*, + const HeapVector<Member<ClipboardItem>>&, + ExceptionState&); + ScriptPromiseTyped<IDLUndefined> writeText(ScriptState*, + const String&, + ExceptionState&); // EventTarget const AtomicString& InterfaceName() const override;
diff --git a/third_party/blink/renderer/modules/clipboard/clipboard_promise.cc b/third_party/blink/renderer/modules/clipboard/clipboard_promise.cc index 13e6ab07..d2eb2b55 100644 --- a/third_party/blink/renderer/modules/clipboard/clipboard_promise.cc +++ b/third_party/blink/renderer/modules/clipboard/clipboard_promise.cc
@@ -146,35 +146,39 @@ } // static -ScriptPromise ClipboardPromise::CreateForWrite( +ScriptPromiseTyped<IDLUndefined> ClipboardPromise::CreateForWrite( ExecutionContext* context, ScriptState* script_state, const HeapVector<Member<ClipboardItem>>& items, ExceptionState& exception_state) { if (!script_state->ContextIsValid()) { - return ScriptPromise(); + return ScriptPromiseTyped<IDLUndefined>(); } + auto* resolver = + MakeGarbageCollected<ScriptPromiseResolverTyped<IDLUndefined>>( + script_state, exception_state.GetContext()); ClipboardPromise* clipboard_promise = MakeGarbageCollected<ClipboardPromise>( - context, script_state, exception_state); - ScriptPromise promise = - clipboard_promise->script_promise_resolver_->Promise(); + context, resolver, exception_state); + auto promise = resolver->Promise(); clipboard_promise->HandleWrite(items); return promise; } // static -ScriptPromise ClipboardPromise::CreateForWriteText( +ScriptPromiseTyped<IDLUndefined> ClipboardPromise::CreateForWriteText( ExecutionContext* context, ScriptState* script_state, const String& data, ExceptionState& exception_state) { if (!script_state->ContextIsValid()) { - return ScriptPromise(); + return ScriptPromiseTyped<IDLUndefined>(); } + auto* resolver = + MakeGarbageCollected<ScriptPromiseResolverTyped<IDLUndefined>>( + script_state, exception_state.GetContext()); ClipboardPromise* clipboard_promise = MakeGarbageCollected<ClipboardPromise>( - context, script_state, exception_state); - ScriptPromise promise = - clipboard_promise->script_promise_resolver_->Promise(); + context, resolver, exception_state); + auto promise = resolver->Promise(); clipboard_promise->HandleWriteText(data); return promise; } @@ -216,7 +220,7 @@ // will still commit gracefully. if (clipboard_representation_index_ == clipboard_item_data_.size()) { local_frame->GetSystemClipboard()->CommitWrite(); - script_promise_resolver_->Resolve(); + script_promise_resolver_->DowncastTo<IDLUndefined>()->Resolve(); return; } @@ -252,8 +256,6 @@ void ClipboardPromise::HandleRead(ClipboardUnsanitizedFormats* formats) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - DCHECK(GetScriptState()->GetIsolate()->InContext()) - << "should be safe to RejectWithDOMException"; if (RuntimeEnabledFeatures::ClipboardUnsanitizedContentEnabled() && formats && formats->hasUnsanitized() && !formats->unsanitized().empty()) { @@ -296,8 +298,6 @@ const HeapVector<Member<ClipboardItem>>& clipboard_items) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(GetExecutionContext()); - DCHECK(GetScriptState()->GetIsolate()->InContext()) - << "should be safe to RejectWithDOMException"; if (clipboard_items.size() > 1) { script_promise_resolver_->RejectWithDOMException( @@ -307,7 +307,7 @@ } if (!clipboard_items.size()) { // Do nothing if there are no ClipboardItems. - script_promise_resolver_->Resolve(); + script_promise_resolver_->DowncastTo<IDLUndefined>()->Resolve(); return; } @@ -346,9 +346,9 @@ void ClipboardPromise::HandleReadWithPermission( mojom::blink::PermissionStatus status) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - DCHECK(GetExecutionContext()); - DCHECK(GetScriptState()->GetIsolate()->InContext()) - << "should be safe to RejectWithDOMException"; + if (!GetExecutionContext()) { + return; + } if (status != mojom::blink::PermissionStatus::GRANTED) { script_promise_resolver_->RejectWithDOMException( DOMExceptionCode::kNotAllowedError, "Read permission denied."); @@ -356,11 +356,8 @@ } SystemClipboard* system_clipboard = GetLocalFrame()->GetSystemClipboard(); - system_clipboard->ReadAvailableCustomAndStandardFormats( - script_promise_resolver_->WrapCallbackInScriptScope( - base::IgnoreArgs<ScriptPromiseResolver*>( - WTF::BindOnce(&ClipboardPromise::OnReadAvailableFormatNames, - WrapPersistent(this))))); + system_clipboard->ReadAvailableCustomAndStandardFormats(WTF::BindOnce( + &ClipboardPromise::OnReadAvailableFormatNames, WrapPersistent(this))); } void ClipboardPromise::ResolveRead() { @@ -397,7 +394,9 @@ void ClipboardPromise::OnReadAvailableFormatNames( const Vector<String>& format_names) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - DCHECK(GetExecutionContext()); + if (!GetExecutionContext()) { + return; + } clipboard_item_data_.ReserveInitialCapacity(format_names.size()); for (const String& format_name : format_names) { @@ -439,9 +438,9 @@ void ClipboardPromise::HandleReadTextWithPermission( mojom::blink::PermissionStatus status) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - DCHECK(GetExecutionContext()); - DCHECK(GetScriptState()->GetIsolate()->InContext()) - << "should be safe to RejectWithDOMException"; + if (!GetExecutionContext()) { + return; + } if (status != mojom::blink::PermissionStatus::GRANTED) { script_promise_resolver_->RejectWithDOMException( DOMExceptionCode::kNotAllowedError, "Read permission denied."); @@ -458,17 +457,14 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); GetClipboardTaskRunner()->PostTask( - FROM_HERE, script_promise_resolver_->WrapCallbackInScriptScope( - base::IgnoreArgs<ScriptPromiseResolver*>(WTF::BindOnce( - &ClipboardPromise::WriteBlobs, WrapPersistent(this), - WrapPersistent(blob_list))))); + FROM_HERE, + WTF::BindOnce(&ClipboardPromise::WriteBlobs, WrapPersistent(this), + WrapPersistent(blob_list))); } void ClipboardPromise::WriteBlobs(HeapVector<Member<Blob>>* blob_list) { wtf_size_t clipboard_item_index = 0; CHECK_EQ(write_clipboard_item_types_.size(), blob_list->size()); - DCHECK(GetScriptState()->GetIsolate()->InContext()) - << "should be safe to RejectWithDOMException"; for (const auto& blob_item : *blob_list) { const String& type = write_clipboard_item_types_[clipboard_item_index]; const String& type_with_args = blob_item->type(); @@ -499,9 +495,9 @@ void ClipboardPromise::HandleWriteWithPermission( mojom::blink::PermissionStatus status) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - DCHECK(GetExecutionContext()); - DCHECK(GetScriptState()->GetIsolate()->InContext()) - << "should be safe to RejectWithDOMException"; + if (!GetExecutionContext()) { + return; + } if (status != mojom::blink::PermissionStatus::GRANTED) { script_promise_resolver_->RejectWithDOMException( DOMExceptionCode::kNotAllowedError, "Write permission denied."); @@ -527,6 +523,7 @@ } } ScriptState* script_state = GetScriptState(); + ScriptState::Scope scope(script_state); BlobPromiseResolverFunction::Create( script_state, ScriptPromise::All(script_state, promise_list), this); } @@ -534,9 +531,9 @@ void ClipboardPromise::HandleWriteTextWithPermission( mojom::blink::PermissionStatus status) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - DCHECK(GetExecutionContext()); - DCHECK(GetScriptState()->GetIsolate()->InContext()) - << "should be safe to RejectWithDOMException"; + if (!GetExecutionContext()) { + return; + } if (status != mojom::blink::PermissionStatus::GRANTED) { script_promise_resolver_->RejectWithDOMException( DOMExceptionCode::kNotAllowedError, "Write permission denied."); @@ -546,12 +543,10 @@ SystemClipboard* system_clipboard = GetLocalFrame()->GetSystemClipboard(); system_clipboard->WritePlainText(plain_text_); system_clipboard->CommitWrite(); - script_promise_resolver_->Resolve(); + script_promise_resolver_->DowncastTo<IDLUndefined>()->Resolve(); } void ClipboardPromise::RejectBlobPromise(const String& exception_text) { - DCHECK(GetScriptState()->GetIsolate()->InContext()) - << "should be safe to RejectWithDOMException"; script_promise_resolver_->RejectWithDOMException( DOMExceptionCode::kNotAllowedError, exception_text); } @@ -576,8 +571,6 @@ DCHECK(script_promise_resolver_); DCHECK(permission == mojom::blink::PermissionName::CLIPBOARD_READ || permission == mojom::blink::PermissionName::CLIPBOARD_WRITE); - DCHECK(GetScriptState()->GetIsolate()->InContext()) - << "should be safe to RejectWithDOMException"; ExecutionContext* context = GetExecutionContext(); DCHECK(context); @@ -619,11 +612,8 @@ ->GetContentSettingsClient() ->AllowWriteToClipboard()))) { GetClipboardTaskRunner()->PostTask( - FROM_HERE, - WTF::BindOnce( - script_promise_resolver_->WrapCallbackInScriptScope( - base::IgnoreArgs<ScriptPromiseResolver*>(std::move(callback))), - mojom::blink::PermissionStatus::GRANTED)); + FROM_HERE, WTF::BindOnce(std::move(callback), + mojom::blink::PermissionStatus::GRANTED)); return; } @@ -633,11 +623,8 @@ (permission == mojom::blink::PermissionName::CLIPBOARD_READ && ClipboardCommands::IsExecutingPaste(*context)))) { GetClipboardTaskRunner()->PostTask( - FROM_HERE, - WTF::BindOnce( - script_promise_resolver_->WrapCallbackInScriptScope( - base::IgnoreArgs<ScriptPromiseResolver*>(std::move(callback))), - mojom::blink::PermissionStatus::GRANTED)); + FROM_HERE, WTF::BindOnce(std::move(callback), + mojom::blink::PermissionStatus::GRANTED)); return; } @@ -658,9 +645,7 @@ // `ContentBrowserClient::IsClipboardPasteAllowed()`. permission_service_->RequestPermission( std::move(permission_descriptor), - /*user_gesture=*/has_transient_user_activation, - script_promise_resolver_->WrapCallbackInScriptScope( - base::IgnoreArgs<ScriptPromiseResolver*>(std::move(callback)))); + /*user_gesture=*/has_transient_user_activation, std::move(callback)); } LocalFrame* ClipboardPromise::GetLocalFrame() const {
diff --git a/third_party/blink/renderer/modules/clipboard/clipboard_promise.h b/third_party/blink/renderer/modules/clipboard/clipboard_promise.h index d001d0fe..31d5a73b 100644 --- a/third_party/blink/renderer/modules/clipboard/clipboard_promise.h +++ b/third_party/blink/renderer/modules/clipboard/clipboard_promise.h
@@ -58,7 +58,7 @@ // Creates a promise for writing supported MIME types to the clipboard. // Spec: https://w3c.github.io/clipboard-apis/#dom-clipboard-write - static ScriptPromise CreateForWrite( + static ScriptPromiseTyped<IDLUndefined> CreateForWrite( ExecutionContext* execution_context, ScriptState* script_state, const HeapVector<Member<ClipboardItem>>& items, @@ -67,10 +67,11 @@ // Creates a promise for writing text to the clipboard. // `text`: The text to be written to the clipboard. // Spec: https://w3c.github.io/clipboard-apis/#dom-clipboard-writetext - static ScriptPromise CreateForWriteText(ExecutionContext* execution_context, - ScriptState* script_state, - const String& text, - ExceptionState& exception_state); + static ScriptPromiseTyped<IDLUndefined> CreateForWriteText( + ExecutionContext* execution_context, + ScriptState* script_state, + const String& text, + ExceptionState& exception_state); // Use one of the above factories to construct. This ctor is public for // `MakeGarbageCollected<>`.
diff --git a/third_party/blink/renderer/modules/compute_pressure/pressure_observer.cc b/third_party/blink/renderer/modules/compute_pressure/pressure_observer.cc index 4ed797c3..d22f90a 100644 --- a/third_party/blink/renderer/modules/compute_pressure/pressure_observer.cc +++ b/third_party/blink/renderer/modules/compute_pressure/pressure_observer.cc
@@ -59,20 +59,21 @@ {V8PressureSource(V8PressureSource::Enum::kCpu)}); } -ScriptPromise PressureObserver::observe(ScriptState* script_state, - V8PressureSource source, - ExceptionState& exception_state) { +ScriptPromiseTyped<IDLUndefined> PressureObserver::observe( + ScriptState* script_state, + V8PressureSource source, + ExceptionState& exception_state) { if (!base::FeatureList::IsEnabled(blink::features::kComputePressure)) { exception_state.ThrowDOMException(DOMExceptionCode::kNotSupportedError, "Compute Pressure API is not available."); - return ScriptPromise(); + return ScriptPromiseTyped<IDLUndefined>(); } ExecutionContext* execution_context = ExecutionContext::From(script_state); if (execution_context->IsContextDestroyed()) { exception_state.ThrowDOMException(DOMExceptionCode::kNotSupportedError, "Execution context is detached."); - return ScriptPromise(); + return ScriptPromiseTyped<IDLUndefined>(); } // Checks whether the document is allowed by Permissions Policy to call @@ -82,11 +83,12 @@ ReportOptions::kReportOnFailure)) { exception_state.ThrowDOMException(DOMExceptionCode::kNotAllowedError, kFeaturePolicyBlocked); - return ScriptPromise(); + return ScriptPromiseTyped<IDLUndefined>(); } - auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>( - script_state, exception_state.GetContext()); + auto* resolver = + MakeGarbageCollected<ScriptPromiseResolverTyped<IDLUndefined>>( + script_state, exception_state.GetContext()); pending_resolvers_[ToSourceIndex(source.AsEnum())].insert(resolver); if (!manager_) { @@ -312,12 +314,6 @@ void PressureObserver::ResolvePendingResolvers(V8PressureSource::Enum source) { const auto source_index = ToSourceIndex(source); for (const auto& resolver : pending_resolvers_[source_index]) { - ScriptState* const script_state = resolver->GetScriptState(); - // Check if callback's resolver is still valid. - if (!IsInParallelAlgorithmRunnable(resolver->GetExecutionContext(), - script_state)) { - continue; - } resolver->Resolve(); } pending_resolvers_[source_index].clear(); @@ -328,14 +324,6 @@ const String& message) { const auto source_index = ToSourceIndex(source); for (const auto& resolver : pending_resolvers_[source_index]) { - ScriptState* const script_state = resolver->GetScriptState(); - // Check if callback's resolver is still valid. - if (!IsInParallelAlgorithmRunnable(resolver->GetExecutionContext(), - script_state)) { - continue; - } - // Enter into resolver's context to support creating DOMException. - ScriptState::Scope script_state_scope(resolver->GetScriptState()); resolver->RejectWithDOMException(exception_code, message); } pending_resolvers_[source_index].clear();
diff --git a/third_party/blink/renderer/modules/compute_pressure/pressure_observer.h b/third_party/blink/renderer/modules/compute_pressure/pressure_observer.h index ffab80d..cd391870 100644 --- a/third_party/blink/renderer/modules/compute_pressure/pressure_observer.h +++ b/third_party/blink/renderer/modules/compute_pressure/pressure_observer.h
@@ -7,6 +7,8 @@ #include "services/device/public/mojom/pressure_manager.mojom-blink.h" #include "services/device/public/mojom/pressure_update.mojom-blink.h" +#include "third_party/blink/renderer/bindings/core/v8/script_promise.h" +#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_pressure_source.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_pressure_state.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_pressure_update_callback.h" @@ -34,8 +36,6 @@ class PressureObserverManager; class PressureObserverOptions; class PressureRecord; -class ScriptPromise; -class ScriptPromiseResolver; class ScriptState; class PressureObserver final : public ScriptWrappable { @@ -52,7 +52,9 @@ ExceptionState&); // PressureObserver IDL implementation. - ScriptPromise observe(ScriptState*, V8PressureSource, ExceptionState&); + ScriptPromiseTyped<IDLUndefined> observe(ScriptState*, + V8PressureSource, + ExceptionState&); void unobserve(V8PressureSource); void disconnect(); HeapVector<Member<PressureRecord>> takeRecords(); @@ -112,7 +114,7 @@ // https://w3c.github.io/compute-pressure/#dfn-samplerate double sample_rate_; - HeapHashSet<Member<ScriptPromiseResolver>> + HeapHashSet<Member<ScriptPromiseResolverTyped<IDLUndefined>>> pending_resolvers_[V8PressureSource::kEnumSize]; // Manages rate obfuscation mitigation parameters.
diff --git a/third_party/blink/renderer/modules/compute_pressure/pressure_observer.idl b/third_party/blink/renderer/modules/compute_pressure/pressure_observer.idl index c106ad7f..fd25b27 100644 --- a/third_party/blink/renderer/modules/compute_pressure/pressure_observer.idl +++ b/third_party/blink/renderer/modules/compute_pressure/pressure_observer.idl
@@ -23,7 +23,7 @@ CallWith=ScriptState, MeasureAs=PressureObserver_Observe, RaisesException - ] Promise<void> observe(PressureSource source); + ] Promise<undefined> observe(PressureSource source); [ MeasureAs=PressureObserver_Unobserve
diff --git a/third_party/blink/renderer/modules/content_index/content_index.cc b/third_party/blink/renderer/modules/content_index/content_index.cc index fad14fa..b8021da 100644 --- a/third_party/blink/renderer/modules/content_index/content_index.cc +++ b/third_party/blink/renderer/modules/content_index/content_index.cc
@@ -88,13 +88,14 @@ ContentIndex::~ContentIndex() = default; -ScriptPromise ContentIndex::add(ScriptState* script_state, - const ContentDescription* description, - ExceptionState& exception_state) { +ScriptPromiseTyped<IDLUndefined> ContentIndex::add( + ScriptState* script_state, + const ContentDescription* description, + ExceptionState& exception_state) { if (!registration_->active()) { exception_state.ThrowTypeError( "No active registration available on the ServiceWorkerRegistration."); - return ScriptPromise(); + return ScriptPromiseTyped<IDLUndefined>(); } ExecutionContext* execution_context = ExecutionContext::From(script_state); @@ -102,45 +103,43 @@ exception_state.ThrowDOMException( DOMExceptionCode::kNotAllowedError, "ContentIndex is not allowed in fenced frames."); - return ScriptPromise(); + return ScriptPromiseTyped<IDLUndefined>(); } WTF::String description_error = ValidateDescription(*description, registration_.Get()); if (!description_error.IsNull()) { exception_state.ThrowTypeError(description_error); - return ScriptPromise(); + return ScriptPromiseTyped<IDLUndefined>(); } - auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>( - script_state, exception_state.GetContext()); - ScriptPromise promise = resolver->Promise(); + auto* resolver = + MakeGarbageCollected<ScriptPromiseResolverTyped<IDLUndefined>>( + script_state, exception_state.GetContext()); + auto promise = resolver->Promise(); auto mojo_description = mojom::blink::ContentDescription::From(description); auto category = mojo_description->category; GetService()->GetIconSizes( - category, resolver->WrapCallbackInScriptScope(WTF::BindOnce( - &ContentIndex::DidGetIconSizes, WrapPersistent(this), - std::move(mojo_description)))); + category, + WTF::BindOnce(&ContentIndex::DidGetIconSizes, WrapPersistent(this), + std::move(mojo_description), WrapPersistent(resolver))); return promise; } void ContentIndex::DidGetIconSizes( mojom::blink::ContentDescriptionPtr description, - ScriptPromiseResolver* resolver, + ScriptPromiseResolverTyped<IDLUndefined>* resolver, const Vector<gfx::Size>& icon_sizes) { if (!icon_sizes.empty() && description->icons.empty()) { - resolver->Reject(V8ThrowException::CreateTypeError( - resolver->GetScriptState()->GetIsolate(), "icons must be provided")); + resolver->RejectWithTypeError("icons must be provided"); return; } if (!registration_->GetExecutionContext()) { // The SW execution context is not valid for some reason. Bail out. - resolver->Reject(V8ThrowException::CreateTypeError( - resolver->GetScriptState()->GetIsolate(), - "Service worker is no longer valid.")); + resolver->RejectWithTypeError("Service worker is no longer valid."); return; } @@ -150,29 +149,26 @@ } auto* icon_loader = MakeGarbageCollected<ContentIndexIconLoader>(); - icon_loader->Start(registration_->GetExecutionContext(), - std::move(description), icon_sizes, - resolver->WrapCallbackInScriptScope(WTF::BindOnce( - &ContentIndex::DidGetIcons, WrapPersistent(this)))); + icon_loader->Start( + registration_->GetExecutionContext(), std::move(description), icon_sizes, + WTF::BindOnce(&ContentIndex::DidGetIcons, WrapPersistent(this), + WrapPersistent(resolver))); } -void ContentIndex::DidGetIcons(ScriptPromiseResolver* resolver, - mojom::blink::ContentDescriptionPtr description, - Vector<SkBitmap> icons) { +void ContentIndex::DidGetIcons( + ScriptPromiseResolverTyped<IDLUndefined>* resolver, + mojom::blink::ContentDescriptionPtr description, + Vector<SkBitmap> icons) { for (const auto& icon : icons) { if (icon.isNull()) { - resolver->Reject(V8ThrowException::CreateTypeError( - resolver->GetScriptState()->GetIsolate(), - "Icon could not be loaded")); + resolver->RejectWithTypeError("Icon could not be loaded"); return; } } if (!registration_->GetExecutionContext()) { // The SW execution context is not valid for some reason. Bail out. - resolver->Reject(V8ThrowException::CreateTypeError( - resolver->GetScriptState()->GetIsolate(), - "Service worker is no longer valid.")); + resolver->RejectWithTypeError("Service worker is no longer valid."); return; } @@ -182,9 +178,9 @@ if (base::FeatureList::IsEnabled(features::kContentIndexCheckOffline)) { GetService()->CheckOfflineCapability( registration_->RegistrationId(), launch_url, - resolver->WrapCallbackInScriptScope(WTF::BindOnce( - &ContentIndex::DidCheckOfflineCapability, WrapPersistent(this), - launch_url, std::move(description), std::move(icons)))); + WTF::BindOnce(&ContentIndex::DidCheckOfflineCapability, + WrapPersistent(this), launch_url, std::move(description), + std::move(icons), WrapPersistent(resolver))); return; } @@ -197,52 +193,49 @@ KURL launch_url, mojom::blink::ContentDescriptionPtr description, Vector<SkBitmap> icons, - ScriptPromiseResolver* resolver, + ScriptPromiseResolverTyped<IDLUndefined>* resolver, bool is_offline_capable) { if (!is_offline_capable) { - resolver->Reject(V8ThrowException::CreateTypeError( - resolver->GetScriptState()->GetIsolate(), - "The provided launch URL is not offline-capable.")); + resolver->RejectWithTypeError( + "The provided launch URL is not offline-capable."); return; } - GetService()->Add(registration_->RegistrationId(), std::move(description), - icons, launch_url, - resolver->WrapCallbackInScriptScope(WTF::BindOnce( - &ContentIndex::DidAdd, WrapPersistent(this)))); + GetService()->Add( + registration_->RegistrationId(), std::move(description), icons, + launch_url, + WTF::BindOnce(&ContentIndex::DidAdd, WrapPersistent(resolver))); } -void ContentIndex::DidAdd(ScriptPromiseResolver* resolver, +void ContentIndex::DidAdd(ScriptPromiseResolverTyped<IDLUndefined>* resolver, mojom::blink::ContentIndexError error) { switch (error) { case mojom::blink::ContentIndexError::NONE: resolver->Resolve(); return; case mojom::blink::ContentIndexError::STORAGE_ERROR: - resolver->Reject(V8ThrowDOMException::CreateOrDie( - resolver->GetScriptState()->GetIsolate(), + resolver->RejectWithDOMException( DOMExceptionCode::kAbortError, - "Failed to add description due to I/O error.")); + "Failed to add description due to I/O error."); return; case mojom::blink::ContentIndexError::INVALID_PARAMETER: // The renderer should have been killed. NOTREACHED(); return; case mojom::blink::ContentIndexError::NO_SERVICE_WORKER: - resolver->Reject(V8ThrowException::CreateTypeError( - resolver->GetScriptState()->GetIsolate(), - "Service worker must be active")); + resolver->RejectWithTypeError("Service worker must be active"); return; } } -ScriptPromise ContentIndex::deleteDescription(ScriptState* script_state, - const String& id, - ExceptionState& exception_state) { +ScriptPromiseTyped<IDLUndefined> ContentIndex::deleteDescription( + ScriptState* script_state, + const String& id, + ExceptionState& exception_state) { if (!registration_->active()) { exception_state.ThrowTypeError( "No active registration available on the ServiceWorkerRegistration."); - return ScriptPromise(); + return ScriptPromiseTyped<IDLUndefined>(); } ExecutionContext* execution_context = ExecutionContext::From(script_state); @@ -250,32 +243,32 @@ exception_state.ThrowDOMException( DOMExceptionCode::kNotAllowedError, "ContentIndex is not allowed in fenced frames."); - return ScriptPromise(); + return ScriptPromiseTyped<IDLUndefined>(); } - auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>( - script_state, exception_state.GetContext()); - ScriptPromise promise = resolver->Promise(); + auto* resolver = + MakeGarbageCollected<ScriptPromiseResolverTyped<IDLUndefined>>( + script_state, exception_state.GetContext()); + auto promise = resolver->Promise(); - GetService()->Delete( - registration_->RegistrationId(), id, - resolver->WrapCallbackInScriptScope(WTF::BindOnce( - &ContentIndex::DidDeleteDescription, WrapPersistent(this)))); + GetService()->Delete(registration_->RegistrationId(), id, + WTF::BindOnce(&ContentIndex::DidDeleteDescription, + WrapPersistent(resolver))); return promise; } -void ContentIndex::DidDeleteDescription(ScriptPromiseResolver* resolver, - mojom::blink::ContentIndexError error) { +void ContentIndex::DidDeleteDescription( + ScriptPromiseResolverTyped<IDLUndefined>* resolver, + mojom::blink::ContentIndexError error) { switch (error) { case mojom::blink::ContentIndexError::NONE: resolver->Resolve(); return; case mojom::blink::ContentIndexError::STORAGE_ERROR: - resolver->Reject(V8ThrowDOMException::CreateOrDie( - resolver->GetScriptState()->GetIsolate(), + resolver->RejectWithDOMException( DOMExceptionCode::kAbortError, - "Failed to delete description due to I/O error.")); + "Failed to delete description due to I/O error."); return; case mojom::blink::ContentIndexError::INVALID_PARAMETER: // The renderer should have been killed. @@ -310,10 +303,9 @@ script_state, exception_state.GetContext()); auto promise = resolver->Promise(); - GetService()->GetDescriptions( - registration_->RegistrationId(), - resolver->WrapCallbackInScriptScope(WTF::BindOnce( - &ContentIndex::DidGetDescriptions, WrapPersistent(this)))); + GetService()->GetDescriptions(registration_->RegistrationId(), + WTF::BindOnce(&ContentIndex::DidGetDescriptions, + WrapPersistent(resolver))); return promise; }
diff --git a/third_party/blink/renderer/modules/content_index/content_index.h b/third_party/blink/renderer/modules/content_index/content_index.h index f86b57a..3023801 100644 --- a/third_party/blink/renderer/modules/content_index/content_index.h +++ b/third_party/blink/renderer/modules/content_index/content_index.h
@@ -31,12 +31,13 @@ ~ContentIndex() override; // Web-exposed function defined in the IDL file. - ScriptPromise add(ScriptState* script_state, - const ContentDescription* description, - ExceptionState& exception_state); - ScriptPromise deleteDescription(ScriptState* script_state, - const String& id, - ExceptionState& exception_state); + ScriptPromiseTyped<IDLUndefined> add(ScriptState* script_state, + const ContentDescription* description, + ExceptionState& exception_state); + ScriptPromiseTyped<IDLUndefined> deleteDescription( + ScriptState* script_state, + const String& id, + ExceptionState& exception_state); ScriptPromiseTyped<IDLSequence<ContentDescription>> getDescriptions( ScriptState* script_state, ExceptionState& exception_state); @@ -48,22 +49,23 @@ // Callbacks. void DidGetIconSizes(mojom::blink::ContentDescriptionPtr description, - ScriptPromiseResolver* resolver, + ScriptPromiseResolverTyped<IDLUndefined>* resolver, const Vector<gfx::Size>& icon_sizes); - void DidGetIcons(ScriptPromiseResolver* resolver, + void DidGetIcons(ScriptPromiseResolverTyped<IDLUndefined>* resolver, mojom::blink::ContentDescriptionPtr description, Vector<SkBitmap> icons); void DidCheckOfflineCapability( KURL launch_url, mojom::blink::ContentDescriptionPtr description, Vector<SkBitmap> icons, - ScriptPromiseResolver* resolver, + ScriptPromiseResolverTyped<IDLUndefined>* resolver, bool is_offline_capable); - void DidAdd(ScriptPromiseResolver* resolver, - mojom::blink::ContentIndexError error); - void DidDeleteDescription(ScriptPromiseResolver* resolver, - mojom::blink::ContentIndexError error); - void DidGetDescriptions( + static void DidAdd(ScriptPromiseResolverTyped<IDLUndefined>* resolver, + mojom::blink::ContentIndexError error); + static void DidDeleteDescription( + ScriptPromiseResolverTyped<IDLUndefined>* resolver, + mojom::blink::ContentIndexError error); + static void DidGetDescriptions( ScriptPromiseResolverTyped<IDLSequence<ContentDescription>>* resolver, mojom::blink::ContentIndexError error, Vector<mojom::blink::ContentDescriptionPtr> descriptions);
diff --git a/third_party/blink/renderer/modules/content_index/content_index.idl b/third_party/blink/renderer/modules/content_index/content_index.idl index 642f257..1c0703c89 100644 --- a/third_party/blink/renderer/modules/content_index/content_index.idl +++ b/third_party/blink/renderer/modules/content_index/content_index.idl
@@ -8,7 +8,7 @@ Exposed=(Window,Worker), RuntimeEnabled=ContentIndex ] interface ContentIndex { - [CallWith=ScriptState, RaisesException, MeasureAs=ContentIndexAdd] Promise<void> add(ContentDescription description); - [CallWith=ScriptState, RaisesException, MeasureAs=ContentIndexDelete, ImplementedAs=deleteDescription] Promise<void> delete(DOMString id); + [CallWith=ScriptState, RaisesException, MeasureAs=ContentIndexAdd] Promise<undefined> add(ContentDescription description); + [CallWith=ScriptState, RaisesException, MeasureAs=ContentIndexDelete, ImplementedAs=deleteDescription] Promise<undefined> delete(DOMString id); [CallWith=ScriptState, RaisesException, MeasureAs=ContentIndexGet, ImplementedAs=getDescriptions] Promise<sequence<ContentDescription>> getAll(); };
diff --git a/third_party/blink/renderer/modules/cookie_store/cookie_store.cc b/third_party/blink/renderer/modules/cookie_store/cookie_store.cc index 872e7ac..63bb25335 100644 --- a/third_party/blink/renderer/modules/cookie_store/cookie_store.cc +++ b/third_party/blink/renderer/modules/cookie_store/cookie_store.cc
@@ -333,28 +333,31 @@ return promise; } -ScriptPromise CookieStore::set(ScriptState* script_state, - const String& name, - const String& value, - ExceptionState& exception_state) { +ScriptPromiseTyped<IDLUndefined> CookieStore::set( + ScriptState* script_state, + const String& name, + const String& value, + ExceptionState& exception_state) { CookieInit* set_options = CookieInit::Create(); set_options->setName(name); set_options->setValue(value); return set(script_state, set_options, exception_state); } -ScriptPromise CookieStore::set(ScriptState* script_state, - const CookieInit* options, - ExceptionState& exception_state) { +ScriptPromiseTyped<IDLUndefined> CookieStore::set( + ScriptState* script_state, + const CookieInit* options, + ExceptionState& exception_state) { UseCounter::Count(CurrentExecutionContext(script_state->GetIsolate()), WebFeature::kCookieStoreAPI); return DoWrite(script_state, options, exception_state); } -ScriptPromise CookieStore::Delete(ScriptState* script_state, - const String& name, - ExceptionState& exception_state) { +ScriptPromiseTyped<IDLUndefined> CookieStore::Delete( + ScriptState* script_state, + const String& name, + ExceptionState& exception_state) { UseCounter::Count(CurrentExecutionContext(script_state->GetIsolate()), WebFeature::kCookieStoreAPI); @@ -365,9 +368,10 @@ return DoWrite(script_state, set_options, exception_state); } -ScriptPromise CookieStore::Delete(ScriptState* script_state, - const CookieStoreDeleteOptions* options, - ExceptionState& exception_state) { +ScriptPromiseTyped<IDLUndefined> CookieStore::Delete( + ScriptState* script_state, + const CookieStoreDeleteOptions* options, + ExceptionState& exception_state) { CookieInit* set_options = CookieInit::Create(); set_options->setName(options->name()); set_options->setValue("deleted"); @@ -511,14 +515,15 @@ resolver->Resolve(cookie); } -ScriptPromise CookieStore::DoWrite(ScriptState* script_state, - const CookieInit* options, - ExceptionState& exception_state) { +ScriptPromiseTyped<IDLUndefined> CookieStore::DoWrite( + ScriptState* script_state, + const CookieInit* options, + ExceptionState& exception_state) { ExecutionContext* context = ExecutionContext::From(script_state); if (!context->GetSecurityOrigin()->CanAccessCookies()) { exception_state.ThrowSecurityError( "Access to the CookieStore API is denied in this context."); - return ScriptPromise(); + return ScriptPromiseTyped<IDLUndefined>(); } net::CookieInclusionStatus status; @@ -527,7 +532,7 @@ if (!canonical_cookie) { DCHECK(exception_state.HadException()); - return ScriptPromise(); + return ScriptPromiseTyped<IDLUndefined>(); } // Since a canonical cookie exists, the status should have no exclusion // reasons associated with it. @@ -536,11 +541,12 @@ if (!backend_) { exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError, "CookieStore backend went away"); - return ScriptPromise(); + return ScriptPromiseTyped<IDLUndefined>(); } - auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>( - script_state, exception_state.GetContext()); + auto* resolver = + MakeGarbageCollected<ScriptPromiseResolverTyped<IDLUndefined>>( + script_state, exception_state.GetContext()); backend_->SetCanonicalCookie( *std::move(canonical_cookie), default_cookie_url_, default_site_for_cookies_, default_top_frame_origin_, @@ -551,17 +557,13 @@ } // static -void CookieStore::OnSetCanonicalCookieResult(ScriptPromiseResolver* resolver, - bool backend_success) { - ScriptState* script_state = resolver->GetScriptState(); - if (!script_state->ContextIsValid()) - return; - ScriptState::Scope scope(script_state); - +void CookieStore::OnSetCanonicalCookieResult( + ScriptPromiseResolverTyped<IDLUndefined>* resolver, + bool backend_success) { if (!backend_success) { - resolver->Reject(V8ThrowDOMException::CreateOrEmpty( - script_state->GetIsolate(), DOMExceptionCode::kUnknownError, - "An unknown error occurred while writing the cookie.")); + resolver->RejectWithDOMException( + DOMExceptionCode::kUnknownError, + "An unknown error occurred while writing the cookie."); return; } resolver->Resolve();
diff --git a/third_party/blink/renderer/modules/cookie_store/cookie_store.h b/third_party/blink/renderer/modules/cookie_store/cookie_store.h index 1dccd1d..a84afc9 100644 --- a/third_party/blink/renderer/modules/cookie_store/cookie_store.h +++ b/third_party/blink/renderer/modules/cookie_store/cookie_store.h
@@ -55,15 +55,19 @@ ScriptPromiseTyped<IDLNullable<CookieListItem>> get(ScriptState*, const CookieStoreGetOptions*, ExceptionState&); - ScriptPromise set(ScriptState*, - const String& name, - const String& value, - ExceptionState&); - ScriptPromise set(ScriptState*, const CookieInit*, ExceptionState&); - ScriptPromise Delete(ScriptState*, const String& name, ExceptionState&); - ScriptPromise Delete(ScriptState*, - const CookieStoreDeleteOptions*, - ExceptionState&); + ScriptPromiseTyped<IDLUndefined> set(ScriptState*, + const String& name, + const String& value, + ExceptionState&); + ScriptPromiseTyped<IDLUndefined> set(ScriptState*, + const CookieInit*, + ExceptionState&); + ScriptPromiseTyped<IDLUndefined> Delete(ScriptState*, + const String& name, + ExceptionState&); + ScriptPromiseTyped<IDLUndefined> Delete(ScriptState*, + const CookieStoreDeleteOptions*, + ExceptionState&); // GarbageCollected void Trace(Visitor* visitor) const override; @@ -114,10 +118,13 @@ backend_result); // Common code in CookieStore::delete and CookieStore::set. - ScriptPromise DoWrite(ScriptState*, const CookieInit*, ExceptionState&); + ScriptPromiseTyped<IDLUndefined> DoWrite(ScriptState*, + const CookieInit*, + ExceptionState&); - static void OnSetCanonicalCookieResult(ScriptPromiseResolver*, - bool backend_result); + static void OnSetCanonicalCookieResult( + ScriptPromiseResolverTyped<IDLUndefined>*, + bool backend_result); // Called when a change event listener is added. //
diff --git a/third_party/blink/renderer/modules/cookie_store/cookie_store.idl b/third_party/blink/renderer/modules/cookie_store/cookie_store.idl index 1c2993bc..a2591d8e 100644 --- a/third_party/blink/renderer/modules/cookie_store/cookie_store.idl +++ b/third_party/blink/renderer/modules/cookie_store/cookie_store.idl
@@ -19,14 +19,14 @@ optional CookieStoreGetOptions options = {}); // https://wicg.github.io/cookie-store/explainer.html#the-modifications-api - [CallWith=ScriptState, Measure, RaisesException] Promise<void> set( + [CallWith=ScriptState, Measure, RaisesException] Promise<undefined> set( USVString name, USVString value); - [CallWith=ScriptState, Measure, RaisesException] Promise<void> set( + [CallWith=ScriptState, Measure, RaisesException] Promise<undefined> set( CookieInit cookieInit); [CallWith=ScriptState, ImplementedAs=Delete, Measure, RaisesException] - Promise<void> delete(USVString name); + Promise<undefined> delete(USVString name); [CallWith=ScriptState, ImplementedAs=Delete, Measure, RaisesException] - Promise<void> delete(CookieStoreDeleteOptions options); + Promise<undefined> delete(CookieStoreDeleteOptions options); // https://wicg.github.io/cookie-store/explainer.html#the-change-events-api [Exposed=Window] attribute EventHandler onchange;
diff --git a/third_party/blink/renderer/modules/cookie_store/cookie_store_manager.cc b/third_party/blink/renderer/modules/cookie_store/cookie_store_manager.cc index 491e944..9377b00 100644 --- a/third_party/blink/renderer/modules/cookie_store/cookie_store_manager.cc +++ b/third_party/blink/renderer/modules/cookie_store/cookie_store_manager.cc
@@ -110,7 +110,7 @@ execution_context->GetTaskRunner(TaskType::kDOMManipulation))); } -ScriptPromise CookieStoreManager::subscribe( +ScriptPromiseTyped<IDLUndefined> CookieStoreManager::subscribe( ScriptState* script_state, const HeapVector<Member<CookieStoreGetOptions>>& subscriptions, ExceptionState& exception_state) { @@ -122,13 +122,14 @@ exception_state); if (backend_subscription.is_null()) { DCHECK(exception_state.HadException()); - return ScriptPromise(); + return ScriptPromiseTyped<IDLUndefined>(); } backend_subscriptions.push_back(std::move(backend_subscription)); } - auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>( - script_state, exception_state.GetContext()); + auto* resolver = + MakeGarbageCollected<ScriptPromiseResolverTyped<IDLUndefined>>( + script_state, exception_state.GetContext()); backend_->AddSubscriptions( registration_->RegistrationId(), std::move(backend_subscriptions), WTF::BindOnce(&CookieStoreManager::OnSubscribeResult, @@ -136,7 +137,7 @@ return resolver->Promise(); } -ScriptPromise CookieStoreManager::unsubscribe( +ScriptPromiseTyped<IDLUndefined> CookieStoreManager::unsubscribe( ScriptState* script_state, const HeapVector<Member<CookieStoreGetOptions>>& subscriptions, ExceptionState& exception_state) { @@ -148,13 +149,14 @@ exception_state); if (backend_subscription.is_null()) { DCHECK(exception_state.HadException()); - return ScriptPromise(); + return ScriptPromiseTyped<IDLUndefined>(); } backend_subscriptions.push_back(std::move(backend_subscription)); } - auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>( - script_state, exception_state.GetContext()); + auto* resolver = + MakeGarbageCollected<ScriptPromiseResolverTyped<IDLUndefined>>( + script_state, exception_state.GetContext()); backend_->RemoveSubscriptions( registration_->RegistrationId(), std::move(backend_subscriptions), WTF::BindOnce(&CookieStoreManager::OnSubscribeResult, @@ -188,17 +190,13 @@ ScriptWrappable::Trace(visitor); } -void CookieStoreManager::OnSubscribeResult(ScriptPromiseResolver* resolver, - bool backend_success) { - ScriptState* script_state = resolver->GetScriptState(); - if (!script_state->ContextIsValid()) - return; - ScriptState::Scope scope(script_state); - +void CookieStoreManager::OnSubscribeResult( + ScriptPromiseResolverTyped<IDLUndefined>* resolver, + bool backend_success) { if (!backend_success) { - resolver->Reject(V8ThrowDOMException::CreateOrEmpty( - script_state->GetIsolate(), DOMExceptionCode::kUnknownError, - "An unknown error occurred while subscribing to cookie changes.")); + resolver->RejectWithDOMException( + DOMExceptionCode::kUnknownError, + "An unknown error occurred while subscribing to cookie changes."); return; } resolver->Resolve(); @@ -208,15 +206,10 @@ ScriptPromiseResolverTyped<IDLSequence<CookieStoreGetOptions>>* resolver, Vector<mojom::blink::CookieChangeSubscriptionPtr> backend_result, bool backend_success) { - ScriptState* script_state = resolver->GetScriptState(); - if (!script_state->ContextIsValid()) - return; - ScriptState::Scope scope(script_state); - if (!backend_success) { - resolver->Reject(V8ThrowDOMException::CreateOrEmpty( - script_state->GetIsolate(), DOMExceptionCode::kUnknownError, - "An unknown error occurred while subscribing to cookie changes.")); + resolver->RejectWithDOMException( + DOMExceptionCode::kUnknownError, + "An unknown error occurred while subscribing to cookie changes."); return; }
diff --git a/third_party/blink/renderer/modules/cookie_store/cookie_store_manager.h b/third_party/blink/renderer/modules/cookie_store/cookie_store_manager.h index b4afa26..d0f2a776 100644 --- a/third_party/blink/renderer/modules/cookie_store/cookie_store_manager.h +++ b/third_party/blink/renderer/modules/cookie_store/cookie_store_manager.h
@@ -36,11 +36,11 @@ ~CookieStoreManager() override = default; - ScriptPromise subscribe( + ScriptPromiseTyped<IDLUndefined> subscribe( ScriptState* script_state, const HeapVector<Member<CookieStoreGetOptions>>& subscriptions, ExceptionState& exception_state); - ScriptPromise unsubscribe( + ScriptPromiseTyped<IDLUndefined> unsubscribe( ScriptState* script_state, const HeapVector<Member<CookieStoreGetOptions>>& subscription, ExceptionState& exception_state); @@ -58,7 +58,8 @@ // registration is live. When CookieStoreManager is used from a Window global, // the CookieStoreManager needs to live through the mojo call, so it can keep // its ServiceWorkerRegistration alive. - void OnSubscribeResult(ScriptPromiseResolver* resolver, bool backend_result); + void OnSubscribeResult(ScriptPromiseResolverTyped<IDLUndefined>* resolver, + bool backend_result); void OnGetSubscriptionsResult( ScriptPromiseResolverTyped<IDLSequence<CookieStoreGetOptions>>* resolver, Vector<mojom::blink::CookieChangeSubscriptionPtr> backend_result,
diff --git a/third_party/blink/renderer/modules/cookie_store/cookie_store_manager.idl b/third_party/blink/renderer/modules/cookie_store/cookie_store_manager.idl index 16d0f95..c2eb29cd 100644 --- a/third_party/blink/renderer/modules/cookie_store/cookie_store_manager.idl +++ b/third_party/blink/renderer/modules/cookie_store/cookie_store_manager.idl
@@ -9,11 +9,11 @@ SecureContext ] interface CookieStoreManager { [CallWith=ScriptState, MeasureAs=CookieStoreAPI, RaisesException] - Promise<void> subscribe(sequence<CookieStoreGetOptions> subscriptions); + Promise<undefined> subscribe(sequence<CookieStoreGetOptions> subscriptions); [CallWith=ScriptState, MeasureAs=CookieStoreAPI, RaisesException] Promise<sequence<CookieStoreGetOptions>> getSubscriptions(); [CallWith=ScriptState, MeasureAs=CookieStoreAPI, RaisesException] - Promise<void> unsubscribe(sequence<CookieStoreGetOptions> subscriptions); + Promise<undefined> unsubscribe(sequence<CookieStoreGetOptions> subscriptions); };
diff --git a/third_party/blink/renderer/modules/credentialmanagement/authentication_credentials_container.cc b/third_party/blink/renderer/modules/credentialmanagement/authentication_credentials_container.cc index 9f20864f..988195f 100644 --- a/third_party/blink/renderer/modules/credentialmanagement/authentication_credentials_container.cc +++ b/third_party/blink/renderer/modules/credentialmanagement/authentication_credentials_container.cc
@@ -693,7 +693,7 @@ void OnPreventSilentAccessComplete( std::unique_ptr<ScopedPromiseResolver> scoped_resolver) { - auto* resolver = scoped_resolver->Release(); + auto* resolver = scoped_resolver->Release()->DowncastTo<IDLUndefined>(); const auto required_origin_type = RequiredOriginType::kSecure; AssertSecurityRequirementsBeforeResponse(resolver, required_origin_type); @@ -1955,10 +1955,13 @@ return promise; } -ScriptPromise AuthenticationCredentialsContainer::preventSilentAccess( +ScriptPromiseTyped<IDLUndefined> +AuthenticationCredentialsContainer::preventSilentAccess( ScriptState* script_state) { - auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); - ScriptPromise promise = resolver->Promise(); + auto* resolver = + MakeGarbageCollected<ScriptPromiseResolverTyped<IDLUndefined>>( + script_state); + auto promise = resolver->Promise(); const auto required_origin_type = RequiredOriginType::kSecure; if (!CheckSecurityRequirementsBeforeRequest(resolver, required_origin_type)) { return promise;
diff --git a/third_party/blink/renderer/modules/credentialmanagement/authentication_credentials_container.h b/third_party/blink/renderer/modules/credentialmanagement/authentication_credentials_container.h index 49cdadc..9ec565c 100644 --- a/third_party/blink/renderer/modules/credentialmanagement/authentication_credentials_container.h +++ b/third_party/blink/renderer/modules/credentialmanagement/authentication_credentials_container.h
@@ -41,7 +41,7 @@ ScriptState*, const CredentialCreationOptions*, ExceptionState&) override; - ScriptPromise preventSilentAccess(ScriptState*) override; + ScriptPromiseTyped<IDLUndefined> preventSilentAccess(ScriptState*) override; void Trace(Visitor*) const override;
diff --git a/third_party/blink/renderer/modules/credentialmanagement/credentials_container.h b/third_party/blink/renderer/modules/credentialmanagement/credentials_container.h index a24da3a..9f206f58 100644 --- a/third_party/blink/renderer/modules/credentialmanagement/credentials_container.h +++ b/third_party/blink/renderer/modules/credentialmanagement/credentials_container.h
@@ -15,7 +15,6 @@ class CredentialCreationOptions; class CredentialRequestOptions; class ExceptionState; -class ScriptPromise; class ScriptState; class MODULES_EXPORT CredentialsContainer : public ScriptWrappable { @@ -32,7 +31,8 @@ ExceptionState&) = 0; virtual ScriptPromiseTyped<IDLNullable<Credential>> create(ScriptState*, const CredentialCreationOptions*, ExceptionState&) = 0; - virtual ScriptPromise preventSilentAccess(ScriptState*) = 0; + virtual ScriptPromiseTyped<IDLUndefined> preventSilentAccess( + ScriptState*) = 0; void Trace(Visitor*) const override; };
diff --git a/third_party/blink/renderer/modules/credentialmanagement/credentials_container.idl b/third_party/blink/renderer/modules/credentialmanagement/credentials_container.idl index aef8182..ea5001df 100644 --- a/third_party/blink/renderer/modules/credentialmanagement/credentials_container.idl +++ b/third_party/blink/renderer/modules/credentialmanagement/credentials_container.idl
@@ -9,5 +9,5 @@ [CallWith=ScriptState, RaisesException, MeasureAs=CredentialManagerGet] Promise<Credential?> get(optional CredentialRequestOptions options = {}); [CallWith=ScriptState, RaisesException, MeasureAs=CredentialManagerStore] Promise<Credential> store(Credential credential); [CallWith=ScriptState, RaisesException, MeasureAs=CredentialManagerCreate] Promise<Credential?> create(optional CredentialCreationOptions options = {}); - [CallWith=ScriptState, MeasureAs=CredentialManagerPreventSilentAccess] Promise<void> preventSilentAccess(); + [CallWith=ScriptState, MeasureAs=CredentialManagerPreventSilentAccess] Promise<undefined> preventSilentAccess(); };
diff --git a/third_party/blink/renderer/modules/credentialmanagement/identity_credential.cc b/third_party/blink/renderer/modules/credentialmanagement/identity_credential.cc index 01f0d92..f073178 100644 --- a/third_party/blink/renderer/modules/credentialmanagement/identity_credential.cc +++ b/third_party/blink/renderer/modules/credentialmanagement/identity_credential.cc
@@ -31,10 +31,11 @@ kMaxValue = kFailedOrigin }; -void OnDisconnect(ScriptPromiseResolver* resolver, DisconnectStatus status) { +void OnDisconnect(ScriptPromiseResolverTyped<IDLUndefined>* resolver, + DisconnectStatus status) { if (status != DisconnectStatus::kSuccess) { - resolver->Reject(MakeGarbageCollected<DOMException>( - DOMExceptionCode::kNetworkError, "Error disconnecting account.")); + resolver->RejectWithDOMException(DOMExceptionCode::kNetworkError, + "Error disconnecting account."); return; } resolver->Resolve(); @@ -80,8 +81,7 @@ WTF::String error = "Refused to connect to '" + provider_url.ElidedString() + "' because it violates the document's Content Security Policy."; - resolver->Reject(MakeGarbageCollected<DOMException>( - DOMExceptionCode::kNetworkError, error)); + resolver->RejectWithDOMException(DOMExceptionCode::kNetworkError, error); return true; } @@ -96,38 +96,38 @@ } // static -ScriptPromise IdentityCredential::disconnect( +ScriptPromiseTyped<IDLUndefined> IdentityCredential::disconnect( ScriptState* script_state, const blink::IdentityCredentialDisconnectOptions* options, ExceptionState& exception_state) { - auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); - ScriptPromise promise = resolver->Promise(); + auto* resolver = + MakeGarbageCollected<ScriptPromiseResolverTyped<IDLUndefined>>( + script_state); + auto promise = resolver->Promise(); if (!options->hasConfigURL()) { - resolver->Reject(V8ThrowException::CreateTypeError( - script_state->GetIsolate(), "configURL is required")); + resolver->RejectWithTypeError("configURL is required"); return promise; } if (!options->hasClientId()) { - resolver->Reject(V8ThrowException::CreateTypeError( - script_state->GetIsolate(), "clientId is required")); + resolver->RejectWithTypeError("clientId is required"); return promise; } if (!resolver->GetExecutionContext()->IsFeatureEnabled( mojom::blink::PermissionsPolicyFeature::kIdentityCredentialsGet)) { - resolver->Reject(MakeGarbageCollected<DOMException>( + resolver->RejectWithDOMException( DOMExceptionCode::kNotAllowedError, "The 'identity-credentials-get` feature is not enabled in this " - "document.")); + "document."); return promise; } KURL provider_url(options->configURL()); if (!provider_url.IsValid()) { - resolver->Reject(MakeGarbageCollected<DOMException>( - DOMExceptionCode::kInvalidStateError, "configURL is invalid")); + resolver->RejectWithDOMException(DOMExceptionCode::kInvalidStateError, + "configURL is invalid"); return promise; }
diff --git a/third_party/blink/renderer/modules/credentialmanagement/identity_credential.h b/third_party/blink/renderer/modules/credentialmanagement/identity_credential.h index 765e8b6..8c17f95 100644 --- a/third_party/blink/renderer/modules/credentialmanagement/identity_credential.h +++ b/third_party/blink/renderer/modules/credentialmanagement/identity_credential.h
@@ -36,7 +36,7 @@ const String& token() const { return token_; } const bool& isAutoSelected() const { return is_auto_selected_; } - static ScriptPromise disconnect( + static ScriptPromiseTyped<IDLUndefined> disconnect( ScriptState*, const IdentityCredentialDisconnectOptions* options, ExceptionState&);
diff --git a/third_party/blink/renderer/modules/credentialmanagement/identity_credential.idl b/third_party/blink/renderer/modules/credentialmanagement/identity_credential.idl index 15e3166..cbdf176 100644 --- a/third_party/blink/renderer/modules/credentialmanagement/identity_credential.idl +++ b/third_party/blink/renderer/modules/credentialmanagement/identity_credential.idl
@@ -21,6 +21,6 @@ readonly attribute boolean isAutoSelected; // https://github.com/fedidcg/FedCM/pull/515 - [RuntimeEnabled=FedCmDisconnect, CallWith=ScriptState, RaisesException, MeasureAs=FedCmDisconnect] static Promise<void> disconnect(optional IdentityCredentialDisconnectOptions options = {}); + [RuntimeEnabled=FedCmDisconnect, CallWith=ScriptState, RaisesException, MeasureAs=FedCmDisconnect] static Promise<undefined> disconnect(optional IdentityCredentialDisconnectOptions options = {}); };
diff --git a/third_party/blink/renderer/modules/credentialmanagement/identity_credentials_container.cc b/third_party/blink/renderer/modules/credentialmanagement/identity_credentials_container.cc index 430d354..5a042ec 100644 --- a/third_party/blink/renderer/modules/credentialmanagement/identity_credentials_container.cc +++ b/third_party/blink/renderer/modules/credentialmanagement/identity_credentials_container.cc
@@ -74,9 +74,9 @@ return ScriptPromiseTyped<IDLNullable<Credential>>(); } -ScriptPromise IdentityCredentialsContainer::preventSilentAccess( - ScriptState* script_state) { - return ScriptPromise(); +ScriptPromiseTyped<IDLUndefined> +IdentityCredentialsContainer::preventSilentAccess(ScriptState* script_state) { + return ScriptPromiseTyped<IDLUndefined>(); } void IdentityCredentialsContainer::Trace(Visitor* visitor) const {
diff --git a/third_party/blink/renderer/modules/credentialmanagement/identity_credentials_container.h b/third_party/blink/renderer/modules/credentialmanagement/identity_credentials_container.h index b47ecc38..622fca8 100644 --- a/third_party/blink/renderer/modules/credentialmanagement/identity_credentials_container.h +++ b/third_party/blink/renderer/modules/credentialmanagement/identity_credentials_container.h
@@ -35,7 +35,7 @@ ScriptState*, const CredentialCreationOptions*, ExceptionState&) override; - ScriptPromise preventSilentAccess(ScriptState*) override; + ScriptPromiseTyped<IDLUndefined> preventSilentAccess(ScriptState*) override; void Trace(Visitor*) const override; };
diff --git a/third_party/blink/renderer/modules/credentialmanagement/identity_provider.cc b/third_party/blink/renderer/modules/credentialmanagement/identity_provider.cc index 5fdafe5..f6f0bc07 100644 --- a/third_party/blink/renderer/modules/credentialmanagement/identity_provider.cc +++ b/third_party/blink/renderer/modules/credentialmanagement/identity_provider.cc
@@ -139,12 +139,12 @@ resolver->Resolve(true); } -ScriptPromise IdentityProvider::registerIdentityProvider( +ScriptPromiseTyped<IDLBoolean> IdentityProvider::registerIdentityProvider( ScriptState* script_state, const String& configURL) { auto* resolver = MakeGarbageCollected<ScriptPromiseResolverTyped<IDLBoolean>>( script_state); - ScriptPromise promise = resolver->Promise(); + auto promise = resolver->Promise(); auto* request = CredentialManagerProxy::From(script_state)->FederatedAuthRequest(); @@ -154,21 +154,24 @@ return promise; } -void OnUnregisterIdP(ScriptPromiseResolver* resolver, bool accepted) { +void OnUnregisterIdP(ScriptPromiseResolverTyped<IDLUndefined>* resolver, + bool accepted) { if (!accepted) { - resolver->Reject(MakeGarbageCollected<DOMException>( + resolver->RejectWithDOMException( DOMExceptionCode::kNotAllowedError, - "Not allowed to unregister the Identity Provider.")); + "Not allowed to unregister the Identity Provider."); return; } resolver->Resolve(); } -ScriptPromise IdentityProvider::unregisterIdentityProvider( +ScriptPromiseTyped<IDLUndefined> IdentityProvider::unregisterIdentityProvider( ScriptState* script_state, const String& configURL) { - auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); - ScriptPromise promise = resolver->Promise(); + auto* resolver = + MakeGarbageCollected<ScriptPromiseResolverTyped<IDLUndefined>>( + script_state); + auto promise = resolver->Promise(); auto* request = CredentialManagerProxy::From(script_state)->FederatedAuthRequest(); @@ -179,19 +182,23 @@ return promise; } -void OnResolveTokenRequest(ScriptPromiseResolver* resolver, bool accepted) { +void OnResolveTokenRequest(ScriptPromiseResolverTyped<IDLUndefined>* resolver, + bool accepted) { if (!accepted) { - resolver->Reject(MakeGarbageCollected<DOMException>( - DOMExceptionCode::kNotAllowedError, "Not allowed to provide a token.")); + resolver->RejectWithDOMException(DOMExceptionCode::kNotAllowedError, + "Not allowed to provide a token."); return; } resolver->Resolve(); } -ScriptPromise IdentityProvider::resolve(ScriptState* script_state, - const String& token) { - auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); - ScriptPromise promise = resolver->Promise(); +ScriptPromiseTyped<IDLUndefined> IdentityProvider::resolve( + ScriptState* script_state, + const String& token) { + auto* resolver = + MakeGarbageCollected<ScriptPromiseResolverTyped<IDLUndefined>>( + script_state); + auto promise = resolver->Promise(); auto* request = CredentialManagerProxy::From(script_state)->FederatedAuthRequest();
diff --git a/third_party/blink/renderer/modules/credentialmanagement/identity_provider.h b/third_party/blink/renderer/modules/credentialmanagement/identity_provider.h index c406a3a..84957d05 100644 --- a/third_party/blink/renderer/modules/credentialmanagement/identity_provider.h +++ b/third_party/blink/renderer/modules/credentialmanagement/identity_provider.h
@@ -25,9 +25,12 @@ ExceptionState&); static void close(ScriptState*); - static ScriptPromise registerIdentityProvider(ScriptState*, const String&); - static ScriptPromise unregisterIdentityProvider(ScriptState*, const String&); - static ScriptPromise resolve(ScriptState*, const String&); + static ScriptPromiseTyped<IDLBoolean> registerIdentityProvider(ScriptState*, + const String&); + static ScriptPromiseTyped<IDLUndefined> unregisterIdentityProvider( + ScriptState*, + const String&); + static ScriptPromiseTyped<IDLUndefined> resolve(ScriptState*, const String&); }; } // namespace blink
diff --git a/third_party/blink/renderer/modules/credentialmanagement/identity_provider.idl b/third_party/blink/renderer/modules/credentialmanagement/identity_provider.idl index d46be38..c11e6df 100644 --- a/third_party/blink/renderer/modules/credentialmanagement/identity_provider.idl +++ b/third_party/blink/renderer/modules/credentialmanagement/identity_provider.idl
@@ -23,12 +23,12 @@ static void close(); [RuntimeEnabled=FedCmIdPRegistration, CallWith=ScriptState, ImplementedAs=registerIdentityProvider] - static Promise<void> register(USVString configURL); + static Promise<undefined> register(USVString configURL); [RuntimeEnabled=FedCmIdPRegistration, CallWith=ScriptState, ImplementedAs=unregisterIdentityProvider] - static Promise<void> unregister(USVString configURL); + static Promise<undefined> unregister(USVString configURL); // Allows an IdP to return a token to the RP from the content area, as opposed to // over HTTP with the id_assertion_endpoint. [RuntimeEnabled=FedCmAuthz, CallWith=ScriptState] - static Promise<void> resolve(USVString token); + static Promise<undefined> resolve(USVString token); };
diff --git a/third_party/blink/renderer/modules/credentialmanagement/testing/internals_fed_cm.cc b/third_party/blink/renderer/modules/credentialmanagement/testing/internals_fed_cm.cc index 1588dee..c548a696 100644 --- a/third_party/blink/renderer/modules/credentialmanagement/testing/internals_fed_cm.cc +++ b/third_party/blink/renderer/modules/credentialmanagement/testing/internals_fed_cm.cc
@@ -99,7 +99,7 @@ } // static -ScriptPromise InternalsFedCm::selectFedCmAccount( +ScriptPromiseTyped<IDLUndefined> InternalsFedCm::selectFedCmAccount( ScriptState* script_state, Internals&, int account_index, @@ -112,10 +112,12 @@ exception_state.ThrowDOMException( DOMExceptionCode::kInvalidModificationError, "A negative account index is not allowed"); + return ScriptPromiseTyped<IDLUndefined>(); } - auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>( - script_state, exception_state.GetContext()); - ScriptPromise promise = resolver->Promise(); + auto* resolver = + MakeGarbageCollected<ScriptPromiseResolverTyped<IDLUndefined>>( + script_state, exception_state.GetContext()); + auto promise = resolver->Promise(); // Get the interface so `federated_auth_request_automation` can be moved // below. test::mojom::blink::FederatedAuthRequestAutomation* @@ -126,7 +128,7 @@ WTF::BindOnce( // While we only really need |resolver|, we also take the // mojo::Remote<> so that it remains alive after this function exits. - [](ScriptPromiseResolver* resolver, + [](ScriptPromiseResolverTyped<IDLUndefined>* resolver, mojo::Remote<test::mojom::blink::FederatedAuthRequestAutomation>, bool success) { if (success) { @@ -141,14 +143,17 @@ } // static -ScriptPromise InternalsFedCm::dismissFedCmDialog(ScriptState* script_state, - Internals&) { +ScriptPromiseTyped<IDLUndefined> InternalsFedCm::dismissFedCmDialog( + ScriptState* script_state, + Internals&) { mojo::Remote<test::mojom::blink::FederatedAuthRequestAutomation> federated_auth_request_automation = CreateFedAuthRequestAutomation(script_state); - auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); - ScriptPromise promise = resolver->Promise(); + auto* resolver = + MakeGarbageCollected<ScriptPromiseResolverTyped<IDLUndefined>>( + script_state); + auto promise = resolver->Promise(); // Get the interface so `federated_auth_request_automation` can be moved // below. test::mojom::blink::FederatedAuthRequestAutomation* @@ -157,7 +162,7 @@ raw_federated_auth_request_automation->DismissFedCmDialog(WTF::BindOnce( // While we only really need |resolver|, we also take the // mojo::Remote<> so that it remains alive after this function exits. - [](ScriptPromiseResolver* resolver, + [](ScriptPromiseResolverTyped<IDLUndefined>* resolver, mojo::Remote<test::mojom::blink::FederatedAuthRequestAutomation>, bool success) { if (success) { @@ -171,7 +176,7 @@ } // static -ScriptPromise InternalsFedCm::clickFedCmDialogButton( +ScriptPromiseTyped<IDLUndefined> InternalsFedCm::clickFedCmDialogButton( ScriptState* script_state, Internals&, const V8DialogButton& v8_button) { @@ -179,8 +184,10 @@ federated_auth_request_automation = CreateFedAuthRequestAutomation(script_state); - auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); - ScriptPromise promise = resolver->Promise(); + auto* resolver = + MakeGarbageCollected<ScriptPromiseResolverTyped<IDLUndefined>>( + script_state); + auto promise = resolver->Promise(); test::mojom::blink::DialogButton button; switch (v8_button.AsEnum()) { @@ -205,7 +212,7 @@ WTF::BindOnce( // While we only really need |resolver|, we also take the // mojo::Remote<> so that it remains alive after this function exits. - [](ScriptPromiseResolver* resolver, + [](ScriptPromiseResolverTyped<IDLUndefined>* resolver, mojo::Remote<test::mojom::blink::FederatedAuthRequestAutomation>, bool success) { if (success) {
diff --git a/third_party/blink/renderer/modules/credentialmanagement/testing/internals_fed_cm.h b/third_party/blink/renderer/modules/credentialmanagement/testing/internals_fed_cm.h index 2f0d530..c99bf5fa 100644 --- a/third_party/blink/renderer/modules/credentialmanagement/testing/internals_fed_cm.h +++ b/third_party/blink/renderer/modules/credentialmanagement/testing/internals_fed_cm.h
@@ -22,14 +22,16 @@ static ScriptPromiseTyped<IDLString> getFedCmDialogType(ScriptState*, Internals&); static ScriptPromiseTyped<IDLString> getFedCmTitle(ScriptState*, Internals&); - static ScriptPromise selectFedCmAccount(ScriptState*, - Internals&, - int account_index, - ExceptionState&); - static ScriptPromise dismissFedCmDialog(ScriptState*, Internals&); - static ScriptPromise clickFedCmDialogButton(ScriptState*, - Internals&, - const V8DialogButton& button); + static ScriptPromiseTyped<IDLUndefined> selectFedCmAccount(ScriptState*, + Internals&, + int account_index, + ExceptionState&); + static ScriptPromiseTyped<IDLUndefined> dismissFedCmDialog(ScriptState*, + Internals&); + static ScriptPromiseTyped<IDLUndefined> clickFedCmDialogButton( + ScriptState*, + Internals&, + const V8DialogButton& button); }; } // namespace blink
diff --git a/third_party/blink/renderer/modules/credentialmanagement/testing/internals_fed_cm.idl b/third_party/blink/renderer/modules/credentialmanagement/testing/internals_fed_cm.idl index 4151f8ff..002c358 100644 --- a/third_party/blink/renderer/modules/credentialmanagement/testing/internals_fed_cm.idl +++ b/third_party/blink/renderer/modules/credentialmanagement/testing/internals_fed_cm.idl
@@ -14,7 +14,7 @@ ] partial interface Internals { [CallWith=ScriptState] Promise<DOMString> getFedCmDialogType(); [CallWith=ScriptState] Promise<DOMString> getFedCmTitle(); - [CallWith=ScriptState, RaisesException] Promise<void> selectFedCmAccount(long accountIndex); - [CallWith=ScriptState] Promise<void> dismissFedCmDialog(); - [CallWith=ScriptState] Promise<void> clickFedCmDialogButton(DialogButton dialogButton); + [CallWith=ScriptState, RaisesException] Promise<undefined> selectFedCmAccount(long accountIndex); + [CallWith=ScriptState] Promise<undefined> dismissFedCmDialog(); + [CallWith=ScriptState] Promise<undefined> clickFedCmDialogButton(DialogButton dialogButton); };
diff --git a/third_party/blink/renderer/platform/graphics/mailbox_texture_backing.cc b/third_party/blink/renderer/platform/graphics/mailbox_texture_backing.cc index 8106822c..bc7bfa6b 100644 --- a/third_party/blink/renderer/platform/graphics/mailbox_texture_backing.cc +++ b/third_party/blink/renderer/platform/graphics/mailbox_texture_backing.cc
@@ -74,9 +74,12 @@ static_cast<uint8_t*>(image_pixels->writable_data()); gpu::raster::RasterInterface* ri = context_provider_wrapper_->ContextProvider()->RasterInterface(); - ri->ReadbackImagePixels(mailbox_, sk_image_info_, - static_cast<GLuint>(sk_image_info_.minRowBytes()), - 0, 0, /*plane_index=*/0, writable_pixels); + if (!ri->ReadbackImagePixels( + mailbox_, sk_image_info_, + static_cast<GLuint>(sk_image_info_.minRowBytes()), 0, 0, + /*plane_index=*/0, writable_pixels)) { + return nullptr; + } return SkImages::RasterFromData(sk_image_info_, std::move(image_pixels), sk_image_info_.minRowBytes()); @@ -98,10 +101,9 @@ gpu::raster::RasterInterface* ri = context_provider_wrapper_->ContextProvider()->RasterInterface(); - ri->ReadbackImagePixels(mailbox_, dst_info, - static_cast<GLuint>(dst_info.minRowBytes()), src_x, - src_y, /*plane_index=*/0, dst_pixels); - return true; + return ri->ReadbackImagePixels(mailbox_, dst_info, + static_cast<GLuint>(dst_info.minRowBytes()), + src_x, src_y, /*plane_index=*/0, dst_pixels); } else if (sk_image_) { return sk_image_->readPixels(dst_info, dst_pixels, dst_row_bytes, src_x, src_y);
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5 index fa8e4cf6..bb20644 100644 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -991,6 +991,13 @@ name: "CSSPositionStickyStaticScrollPosition", status: "test", }, + { + // Support the position-try-order property. Currently not implied by the + // anchor positioning feature. + // https://drafts.csswg.org/css-anchor-position-1/#position-try-order-property + name: "CSSPositionTryOrder", + status: "test", + }, // https://drafts.csswg.org/css-values-5/#progress // progress(), media-progress(), container-progress() { @@ -2201,10 +2208,6 @@ settable_from_internals: true, }, { - name: "LayoutAlignForPositioned", - status: "stable", - }, - { name: "LayoutFlexNewRowAlgorithmV3", status: "test", },
diff --git a/third_party/blink/renderer/platform/theme/web_theme_engine_default.cc b/third_party/blink/renderer/platform/theme/web_theme_engine_default.cc index 1f196b4c..c50cd63 100644 --- a/third_party/blink/renderer/platform/theme/web_theme_engine_default.cc +++ b/third_party/blink/renderer/platform/theme/web_theme_engine_default.cc
@@ -289,12 +289,6 @@ return ui::NativeTheme::GetInstanceForWeb()->GetPaintedScrollbarTrackInset(); } -std::optional<SkColor> WebThemeEngineDefault::GetSystemColor( - WebThemeEngine::SystemThemeColor system_theme_color) const { - return ui::NativeTheme::GetInstanceForWeb()->GetSystemThemeColor( - NativeSystemThemeColor(system_theme_color)); -} - std::optional<SkColor> WebThemeEngineDefault::GetAccentColor() const { return ui::NativeTheme::GetInstanceForWeb()->user_color(); } @@ -319,56 +313,24 @@ : ForcedColors::kNone; } -// TODO(samomekarajr): Remove this when fully migrated to the color pipeline. -void WebThemeEngineDefault::OverrideForcedColorsTheme(bool is_dark_theme) { - // Colors were chosen based on Windows 10 default light and dark high contrast - // themes. - const base::flat_map<ui::NativeTheme::SystemThemeColor, uint32_t> dark_theme{ - {ui::NativeTheme::SystemThemeColor::kButtonFace, 0xFF000000}, - {ui::NativeTheme::SystemThemeColor::kButtonText, 0xFFFFFFFF}, - {ui::NativeTheme::SystemThemeColor::kGrayText, 0xFF3FF23F}, - {ui::NativeTheme::SystemThemeColor::kHighlight, 0xFF1AEBFF}, - {ui::NativeTheme::SystemThemeColor::kHighlightText, 0xFF000000}, - {ui::NativeTheme::SystemThemeColor::kHotlight, 0xFFFFFF00}, - {ui::NativeTheme::SystemThemeColor::kMenuHighlight, 0xFF800080}, - {ui::NativeTheme::SystemThemeColor::kScrollbar, 0xFF000000}, - {ui::NativeTheme::SystemThemeColor::kWindow, 0xFF000000}, - {ui::NativeTheme::SystemThemeColor::kWindowText, 0xFFFFFFFF}, - }; - const base::flat_map<ui::NativeTheme::SystemThemeColor, uint32_t> light_theme{ - {ui::NativeTheme::SystemThemeColor::kButtonFace, 0xFFFFFFFF}, - {ui::NativeTheme::SystemThemeColor::kButtonText, 0xFF000000}, - {ui::NativeTheme::SystemThemeColor::kGrayText, 0xFF600000}, - {ui::NativeTheme::SystemThemeColor::kHighlight, 0xFF37006E}, - {ui::NativeTheme::SystemThemeColor::kHighlightText, 0xFFFFFFFF}, - {ui::NativeTheme::SystemThemeColor::kHotlight, 0xFF00009F}, - {ui::NativeTheme::SystemThemeColor::kMenuHighlight, 0xFF000000}, - {ui::NativeTheme::SystemThemeColor::kScrollbar, 0xFFFFFFFF}, - {ui::NativeTheme::SystemThemeColor::kWindow, 0xFFFFFFFF}, - {ui::NativeTheme::SystemThemeColor::kWindowText, 0xFF000000}, - }; - ui::NativeTheme::GetInstanceForWeb()->UpdateSystemColorInfo( - false, true, is_dark_theme ? dark_theme : light_theme); +// TODO(crbug.com/40779801): Remove this when we use the forced colors web +// setting in Blink. +void WebThemeEngineDefault::OverrideForcedColorsTheme() { + ui::NativeTheme::GetInstanceForWeb()->UpdateSystemColorInfo(false, true); } - void WebThemeEngineDefault::SetForcedColors(const ForcedColors forced_colors) { ui::NativeTheme::GetInstanceForWeb()->set_forced_colors( forced_colors == ForcedColors::kActive); } +// TODO(crbug.com/40779801): Remove this when we use the forced colors web +// setting in Blink. void WebThemeEngineDefault::ResetToSystemColors( SystemColorInfoState system_color_info_state) { - base::flat_map<ui::NativeTheme::SystemThemeColor, uint32_t> colors; - - for (const auto& color : system_color_info_state.colors) { - colors.insert({NativeSystemThemeColor(color.first), color.second}); - } - ui::NativeTheme::GetInstanceForWeb()->UpdateSystemColorInfo( system_color_info_state.is_dark_mode, - system_color_info_state.forced_colors, colors); - + system_color_info_state.forced_colors); } WebThemeEngine::SystemColorInfoState @@ -379,14 +341,6 @@ state.forced_colors = ui::NativeTheme::GetInstanceForWeb()->InForcedColorsMode(); - std::map<SystemThemeColor, uint32_t> colors; - auto native_theme_colors = - ui::NativeTheme::GetInstanceForWeb()->GetSystemColors(); - for (const auto& color : native_theme_colors) { - colors.insert({WebThemeSystemThemeColor(color.first), color.second}); - } - state.colors = colors; - return state; }
diff --git a/third_party/blink/renderer/platform/theme/web_theme_engine_default.h b/third_party/blink/renderer/platform/theme/web_theme_engine_default.h index b7b3827..cc0d307 100644 --- a/third_party/blink/renderer/platform/theme/web_theme_engine_default.h +++ b/third_party/blink/renderer/platform/theme/web_theme_engine_default.h
@@ -32,8 +32,6 @@ bool SupportsNinePatch(Part part) const override; gfx::Size NinePatchCanvasSize(Part part) const override; gfx::Rect NinePatchAperture(Part part) const override; - std::optional<SkColor> GetSystemColor( - WebThemeEngine::SystemThemeColor system_theme_color) const override; std::optional<SkColor> GetAccentColor() const override; #if BUILDFLAG(IS_WIN) // Caches the scrollbar metrics. These are retrieved in the browser and passed @@ -45,7 +43,7 @@ int32_t horizontal_arrow_bitmap_width); #endif ForcedColors GetForcedColors() const override; - void OverrideForcedColorsTheme(bool is_dark_theme) override; + void OverrideForcedColorsTheme() override; void SetForcedColors(const ForcedColors forced_colors) override; void ResetToSystemColors( WebThemeEngine::SystemColorInfoState system_color_info_state) override;
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index f778da84..20c115c 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -2620,6 +2620,7 @@ crbug.com/626703 external/wpt/uievents/mouse/mouse_boundary_events_after_removing_last_over_element.html [ Failure ] # ====== New tests from wpt-importer added here ====== +crbug.com/626703 external/wpt/css/css-contain/contain-style-counters-002.html [ Failure ] crbug.com/626703 external/wpt/css/css-color/oklab-l-almost-0.html [ Failure ] crbug.com/626703 [ Mac14-arm64 ] external/wpt/css/css-color/oklab-l-almost-1.html [ Failure ] crbug.com/626703 [ Mac14 ] external/wpt/css/css-color/oklab-l-almost-1.html [ Failure ] @@ -6247,7 +6248,6 @@ [ Debug Mac13 ] fast/dom/shadow/selections-in-shadow.html [ Skip Timeout ] [ Debug Mac13 ] virtual/controls-refresh-hc/fast/forms/color-scheme/media/video-playback-speed-menu.html [ Skip Timeout ] [ Debug Mac13 ] virtual/keepalive-in-browser-migration/external/wpt/fetch/metadata/generated/element-iframe.https.sub.html [ Skip Timeout ] -[ Debug Mac13 ] virtual/threaded-no-composited-antialiasing/animations/responsive/interpolation/background-position-responsive.html [ Skip Timeout ] [ Debug Mac13 ] http/tests/devtools/elements/styles-4/styles-update-links-1.js [ Skip Timeout ] [ Debug Mac13 ] external/wpt/html/anonymous-iframe/embedding.tentative.https.window.html?10-10 [ Failure ] [ Debug Mac13 ] http/tests/devtools/console/console-tests.js [ Skip Timeout ] @@ -6286,7 +6286,6 @@ [ Debug Mac13 ] accessibility/aom-computed-int-properties.html [ Skip Timeout ] [ Debug Mac13 ] fast/scroll-behavior/overscroll-behavior.html [ Failure ] [ Debug Mac13 ] http/tests/devtools/elements/inspect-limited-children.js [ Skip Timeout ] -[ Debug Mac13 ] virtual/threaded-no-composited-antialiasing/animations/responsive/responsive-neutral-keyframe.html [ Skip Timeout ] [ Debug Mac13 ] accessibility/inline-text-word-boundary-causes-crash.html [ Skip Timeout ] [ Debug Mac13 ] animations/custom-properties/registered-var-to-registered-animating.html [ Skip Timeout ] [ Debug Mac13 ] virtual/threaded-no-composited-antialiasing/animations/custom-properties/registered-neutral-keyframe.html [ Crash ] @@ -6305,7 +6304,6 @@ [ Debug Mac13 ] virtual/threaded/fast/events/pinch/pinch-zoom-pan-position-fixed.html [ Skip Timeout ] [ Debug Mac13 ] fullscreen/anonymous-block-merge-crash.html [ Failure ] [ Debug Mac13 ] http/tests/devtools/cache-storage/cache-entry-deletion.js [ Skip Timeout ] -[ Debug Mac13 ] virtual/threaded-no-composited-antialiasing/animations/responsive/interpolation/box-shadow-responsive.html [ Skip Timeout ] [ Debug Mac13 ] virtual/threaded-prefer-compositing/fast/scroll-behavior/main-frame-scroll.html [ Skip Timeout ] [ Debug Mac13 ] external/wpt/storage-access-api/hasStorageAccess.sub.https.window.html [ Crash ] [ Debug Mac13 ] http/tests/devtools/elements/styles-4/styles-source-lines-inline.js [ Skip Timeout ]
diff --git a/third_party/blink/web_tests/TestLists/skia-vulkan-swiftshader b/third_party/blink/web_tests/TestLists/skia-vulkan-swiftshader index 0415c34..b8aad8e3 100644 --- a/third_party/blink/web_tests/TestLists/skia-vulkan-swiftshader +++ b/third_party/blink/web_tests/TestLists/skia-vulkan-swiftshader
@@ -408,7 +408,6 @@ animations/prefixed/keyframes-cssom-unprefixed-01.html animations/prefixed/keyframes-unprefixed-01.html animations/prefixed/string-keyframes-identifier-prefixed.html -animations/responsive/interpolation/box-shadow-responsive.html animations/responsive/responsive-neutral-keyframes.html animations/responsive/svg-responsive-to-timing-updates.html animations/retain-zero-percent.html
diff --git a/third_party/blink/web_tests/VirtualTestSuites b/third_party/blink/web_tests/VirtualTestSuites index 299e7a8..229195a0 100644 --- a/third_party/blink/web_tests/VirtualTestSuites +++ b/third_party/blink/web_tests/VirtualTestSuites
@@ -1886,7 +1886,7 @@ "external/wpt/fetch/private-network-access/fenced-frame.tentative.https.window.js", "external/wpt/fetch/private-network-access/fenced-frame-no-preflight-required.tentative.https.window.js" ], - "args": ["--enable-features=FencedFrames:implementation_type/mparch,PrivacySandboxAdsAPIsOverride,SharedStorageAPI,NoncedPartitionedCookies,Fledge,InterestGroupStorage,AdInterestGroupAPI,AllowURNsInIframes,BiddingAndScoringDebugReportingAPI,ComputePressure,FencedFramesEnforceFocus,FencedFramesM120FeaturesPart1,FencedFramesM120FeaturesPart2,FencedFramesCrossOriginAutomaticBeacons,FencedFramesLocalUnpartitionedDataAccess", + "args": ["--enable-features=FencedFrames:implementation_type/mparch,PrivacySandboxAdsAPIsOverride,SharedStorageAPI,NoncedPartitionedCookies,Fledge,InterestGroupStorage,AdInterestGroupAPI,AllowURNsInIframes,BiddingAndScoringDebugReportingAPI,ComputePressure,FencedFramesEnforceFocus,FencedFramesM120FeaturesPart1,FencedFramesM120FeaturesPart2,FencedFramesCrossOriginAutomaticBeacons,FencedFramesLocalUnpartitionedDataAccess,ExemptUrlFromNetworkRevocationForTesting", "--enable-blink-features=FencedFramesAPIChanges,FencedFramesDefaultMode", "--disable-threaded-compositing", "--disable-threaded-animation"], "expires": "Dec 31, 2023"
diff --git a/third_party/blink/web_tests/animations/responsive/interpolation/background-position-responsive.html b/third_party/blink/web_tests/animations/responsive/interpolation/background-position-responsive.html deleted file mode 100644 index 10f734c6d..0000000 --- a/third_party/blink/web_tests/animations/responsive/interpolation/background-position-responsive.html +++ /dev/null
@@ -1,41 +0,0 @@ -<!DOCTYPE html> -<script src="resources/responsive-test.js"></script> -<script> -assertCSSResponsive({ - property: 'background-position', - from: neutralKeyframe, - to: '100px 100px', - configurations: [{ - state: {underlying: '20px 60px'}, - expect: [ - {at: 0.25, is: '40px 70px'}, - {at: 0.75, is: '80px 90px'}, - ], - }, { - state: {underlying: '60px 20px'}, - expect: [ - {at: 0.25, is: '70px 40px'}, - {at: 0.75, is: '90px 80px'}, - ], - }], -}); - -assertCSSResponsive({ - property: 'background-position', - from: 'inherit', - to: '100px 100px', - configurations: [{ - state: {inherited: '20px 60px'}, - expect: [ - {at: 0.25, is: '40px 70px'}, - {at: 0.75, is: '80px 90px'}, - ], - }, { - state: {inherited: '60px 20px'}, - expect: [ - {at: 0.25, is: '70px 40px'}, - {at: 0.75, is: '90px 80px'}, - ], - }], -}); -</script>
diff --git a/third_party/blink/web_tests/animations/responsive/interpolation/box-shadow-responsive.html b/third_party/blink/web_tests/animations/responsive/interpolation/box-shadow-responsive.html deleted file mode 100644 index ad5b4ae9..0000000 --- a/third_party/blink/web_tests/animations/responsive/interpolation/box-shadow-responsive.html +++ /dev/null
@@ -1,41 +0,0 @@ -<!DOCTYPE html> -<script src="resources/responsive-test.js"></script> -<script> -assertCSSResponsive({ - property: 'box-shadow', - from: 'green 20px 20px 20px 20px', - to: 'inherit', - configurations: [{ - state: {inherited: 'blue 0px 0px 0px 0px'}, - expect: [ - {at: 0.25, is: 'rgb(0, 96, 64) 15px 15px 15px 15px'}, - {at: 0.75, is: 'rgb(0, 32, 191) 5px 5px 5px 5px'}, - ], - }, { - state: {inherited: 'yellow 100px 100px 100px 100px'}, - expect: [ - {at: 0.25, is: 'rgb(64, 160, 0) 40px 40px 40px 40px'}, - {at: 0.75, is: 'rgb(191, 223, 0) 80px 80px 80px 80px'}, - ], - }], -}); - -assertCSSResponsive({ - property: 'box-shadow', - from: 'inherit', - to: 'green 20px 20px 20px 20px', - configurations: [{ - state: {inherited: 'blue 0px 0px 0px 0px, yellow 100px 100px 100px 100px'}, - expect: [ - {at: 0.25, is: 'rgb(0, 32, 191) 5px 5px 5px 5px, rgba(255, 255, 0, 0.75) 75px 75px 75px 75px'}, - {at: 0.75, is: 'rgb(0, 96, 64) 15px 15px 15px 15px, rgba(255, 255, 0, 0.25) 25px 25px 25px 25px'}, - ], - }, { - state: {inherited: 'yellow 100px 100px 100px 100px'}, - expect: [ - {at: 0.25, is: 'rgb(191, 223, 0) 80px 80px 80px 80px'}, - {at: 0.75, is: 'rgb(64, 160, 0) 40px 40px 40px 40px'}, - ], - }], -}); -</script>
diff --git a/third_party/blink/web_tests/animations/responsive/responsive-neutral-keyframe-expected.html b/third_party/blink/web_tests/animations/responsive/responsive-neutral-keyframe-expected.html deleted file mode 100644 index 87abf1f7..0000000 --- a/third_party/blink/web_tests/animations/responsive/responsive-neutral-keyframe-expected.html +++ /dev/null
@@ -1,2 +0,0 @@ -<!DOCTYPE html> -<div style="translate: 100px">Test.</div>
diff --git a/third_party/blink/web_tests/animations/responsive/responsive-neutral-keyframe.html b/third_party/blink/web_tests/animations/responsive/responsive-neutral-keyframe.html deleted file mode 100644 index efa2197..0000000 --- a/third_party/blink/web_tests/animations/responsive/responsive-neutral-keyframe.html +++ /dev/null
@@ -1,24 +0,0 @@ -<!DOCTYPE html> -<div id="target">Test.</div> -<script> -if (window.testRunner) - testRunner.waitUntilDone(); - -function waitForCompositor() { - return document.body.animate({opacity: [1, 1]}, 1).finished; -} - -target.animate({translate: '100px'}, 1e8); - -requestAnimationFrame(() => { - requestAnimationFrame(() => { - target.style.translate = '100px'; - requestAnimationFrame(() => { - waitForCompositor().then(() => { - if (window.testRunner) - testRunner.notifyDone(); - }); - }); - }); -}); -</script>
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 f4b6048..0a7e5b773 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
@@ -101754,12 +101754,12 @@ ] ], "contain-style-counters-002.html": [ - "48494ce2be7f7e0039acc8327187417a3b64c495", + "862ee789b7a508ce26c84415325f9c6cf99c0db3", [ null, [ [ - "/css/css-contain/reference/contain-style-counters-001-ref.html", + "/css/css-contain/reference/contain-style-counters-002-ref.html", "==" ] ], @@ -303626,11 +303626,11 @@ ], "parsing": { "color-computed-color-mix-function-expected.txt": [ - "e6dca61e55cfa1625c6f92158feb8354ffd6a094", + "d47cba9d853e72afe7d3485cb4914032076f15c0", [] ], "color-computed-relative-color-expected.txt": [ - "a9d32e6f304c2d763c07ce3be161f64e9b0f776c", + "5685549d8b67f11c7e1e2ff95ddefeb047d210e4", [] ], "color-valid-hsl-expected.txt": [ @@ -303638,7 +303638,7 @@ [] ], "color-valid-relative-color-expected.txt": [ - "b55eed3b173624f2712140a65ee383d8338d53d4", + "2f72d60fb5cac2e2ba153c065cbf1f7b3ecbc75c", [] ], "opacity-valid-expected.txt": [ @@ -304999,6 +304999,10 @@ "c0c652b3351930655b713d3e6907ee70ec42bd69", [] ], + "contain-style-counters-002-ref.html": [ + "7a14112c44c2ab42036f46659f32565089d9da1b", + [] + ], "contain-style-counters-003-ref.html": [ "12f9b989fd2402d5e8af279cd03f03931856270e", [] @@ -441041,7 +441045,7 @@ ] ], "color-computed-color-mix-function.html": [ - "b54aa0da12ad9216fc148b0094b45b9c9d53fb70", + "4ac7cb6a272e358ea077306646c83acb2cb3596b", [ null, {} @@ -441083,7 +441087,7 @@ ] ], "color-computed-relative-color.html": [ - "95c8eee226b6c28bb2e970cb9c1d3c372613df2e", + "53d25e0a55d11d14a4c16441ffaab9edc0410123", [ null, {} @@ -441160,14 +441164,14 @@ ] ], "color-invalid-relative-color.html": [ - "2cb3a252917251efeb4fb4018498849fe385c401", + "67390070365ef33e1d0570f863f35d9a5e3f07a2", [ null, {} ] ], "color-invalid-rgb.html": [ - "90dd082f2ae9a2024e411669bbbe68a82868fa2f", + "08d4c6735aeabc81bfcf4d1c1f28c3f28540bc42", [ null, {} @@ -441230,7 +441234,7 @@ ] ], "color-valid-relative-color.html": [ - "5f83f0f0746c376be9b9c5ef57b22379854fe374", + "5c351bca33d10d030f495e2960967a4e45a1e16d", [ null, {}
diff --git a/third_party/blink/web_tests/external/wpt/credential-management/support/fedcm/continue_on.py b/third_party/blink/web_tests/external/wpt/credential-management/support/fedcm/continue_on.py index 42b4f3f..6a1a9900 100644 --- a/third_party/blink/web_tests/external/wpt/credential-management/support/fedcm/continue_on.py +++ b/third_party/blink/web_tests/external/wpt/credential-management/support/fedcm/continue_on.py
@@ -7,6 +7,8 @@ return request_error response.headers.set(b"Content-Type", b"application/json") + response.headers.set(b"Access-Control-Allow-Origin", request.headers.get(b"Origin")) + response.headers.set(b"Access-Control-Allow-Credentials", "true") return "{\"continue_on\": \"resolve.html\"}"
diff --git a/third_party/blink/web_tests/external/wpt/credential-management/support/fedcm/request-params-check.py b/third_party/blink/web_tests/external/wpt/credential-management/support/fedcm/request-params-check.py index 6c610e6..08c28e32 100644 --- a/third_party/blink/web_tests/external/wpt/credential-management/support/fedcm/request-params-check.py +++ b/third_party/blink/web_tests/external/wpt/credential-management/support/fedcm/request-params-check.py
@@ -63,12 +63,16 @@ return (539, [], "Should not have Origin") def tokenCheck(request): - common_error = commonCheck(request) + common_error = commonCheck(request, b"cors") if (common_error): return common_error common_credentialed_error = commonCredentialedRequestCheck(request) if (common_credentialed_error): return common_credentialed_error + # The value of the Sec-Fetch-Site header can vary depending on the IdP origin + # but it should not be 'none'. + if request.headers.get(b"Sec-Fetch-Site") == b"none": + return (538, [], "Wrong Sec-Fetch-Site header") post_error = commonPostCheck(request) if (post_error): @@ -86,8 +90,9 @@ if (common_error): return common_error - if request.cookies.get(b"cookie") != b"1": - return (537, [], "Missing cookie") + common_credentialed_error = commonCredentialedRequestCheck(request) + if (common_credentialed_error): + return common_credentialed_error # The value of the Sec-Fetch-Site header can vary depending on the IdP origin # but it should not be 'none'. if request.headers.get(b"Sec-Fetch-Site") == b"none":
diff --git a/third_party/blink/web_tests/external/wpt/credential-management/support/fedcm/token_with_account_id.py b/third_party/blink/web_tests/external/wpt/credential-management/support/fedcm/token_with_account_id.py index 52fb201..04e7b5b 100644 --- a/third_party/blink/web_tests/external/wpt/credential-management/support/fedcm/token_with_account_id.py +++ b/third_party/blink/web_tests/external/wpt/credential-management/support/fedcm/token_with_account_id.py
@@ -7,6 +7,8 @@ return request_error response.headers.set(b"Content-Type", b"application/json") + response.headers.set(b"Access-Control-Allow-Origin", request.headers.get(b"Origin")) + response.headers.set(b"Access-Control-Allow-Credentials", "true") account_id = request.POST.get(b"account_id") return "{\"token\": \"account_id=" + account_id.decode("utf-8") + "\"}"
diff --git a/third_party/blink/web_tests/external/wpt/credential-management/support/fedcm/token_with_auto_selected_flag.py b/third_party/blink/web_tests/external/wpt/credential-management/support/fedcm/token_with_auto_selected_flag.py index 93ccf3e..3e011ce7 100644 --- a/third_party/blink/web_tests/external/wpt/credential-management/support/fedcm/token_with_auto_selected_flag.py +++ b/third_party/blink/web_tests/external/wpt/credential-management/support/fedcm/token_with_auto_selected_flag.py
@@ -7,6 +7,8 @@ return request_error response.headers.set(b"Content-Type", b"application/json") + response.headers.set(b"Access-Control-Allow-Origin", request.headers.get(b"Origin")) + response.headers.set(b"Access-Control-Allow-Credentials", "true") is_auto_selected = request.POST.get(b"is_auto_selected") return "{\"token\": \"is_auto_selected=" + is_auto_selected.decode("utf-8") + "\"}"
diff --git a/third_party/blink/web_tests/external/wpt/credential-management/support/fedcm/token_with_http_error.py b/third_party/blink/web_tests/external/wpt/credential-management/support/fedcm/token_with_http_error.py index c8d95ab6..05b9945 100644 --- a/third_party/blink/web_tests/external/wpt/credential-management/support/fedcm/token_with_http_error.py +++ b/third_party/blink/web_tests/external/wpt/credential-management/support/fedcm/token_with_http_error.py
@@ -7,6 +7,8 @@ return request_error response.headers.set(b"Content-Type", b"application/json") + response.headers.set(b"Access-Control-Allow-Origin", request.headers.get(b"Origin")) + response.headers.set(b"Access-Control-Allow-Credentials", "true") response.status = (403, b"Forbidden") return "{\"token\": \"token\"}"
diff --git a/third_party/blink/web_tests/external/wpt/credential-management/support/fedcm/token_with_rp_mode.py b/third_party/blink/web_tests/external/wpt/credential-management/support/fedcm/token_with_rp_mode.py index 5157364..add634c9 100644 --- a/third_party/blink/web_tests/external/wpt/credential-management/support/fedcm/token_with_rp_mode.py +++ b/third_party/blink/web_tests/external/wpt/credential-management/support/fedcm/token_with_rp_mode.py
@@ -7,6 +7,8 @@ return request_error response.headers.set(b"Content-Type", b"application/json") + response.headers.set(b"Access-Control-Allow-Origin", request.headers.get(b"Origin")) + response.headers.set(b"Access-Control-Allow-Credentials", "true") rp_mode = request.POST.get(b"mode") return "{\"token\": \"mode=" + rp_mode.decode("utf-8") + "\"}"
diff --git a/third_party/blink/web_tests/external/wpt/css/css-anchor-position/at-position-try-allowed-declarations.html b/third_party/blink/web_tests/external/wpt/css/css-anchor-position/at-position-try-allowed-declarations.html index 622e982..5586000e 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-anchor-position/at-position-try-allowed-declarations.html +++ b/third_party/blink/web_tests/external/wpt/css/css-anchor-position/at-position-try-allowed-declarations.html
@@ -74,12 +74,12 @@ test_allowed_declaration('max-inline-size'); // Box alignment properties are allowed -test_allowed_declaration('justify-content', 'normal'); -test_allowed_declaration('align-content', 'normal'); -test_allowed_declaration('justify-items', 'normal'); -test_allowed_declaration('align-items', 'normal'); test_allowed_declaration('justify-self', 'normal'); test_allowed_declaration('align-self', 'normal'); +test_allowed_declaration('place-self', 'normal'); + +// The 'position-anchor' property is allowed +test_allowed_declaration('position-anchor', '--anchor'); // Custom properties are disallowed test_disallowed_declaration('--custom'); @@ -91,6 +91,10 @@ test_disallowed_declaration('display'); test_disallowed_declaration('position'); test_disallowed_declaration('float'); +test_disallowed_declaration('justify-content', 'normal'); +test_disallowed_declaration('align-content', 'normal'); +test_disallowed_declaration('justify-items', 'normal'); +test_disallowed_declaration('align-items', 'normal'); // 'revert' and 'revert-layer' are disallowed test_disallowed_declaration('top', 'revert');
diff --git a/third_party/blink/web_tests/external/wpt/css/css-anchor-position/at-position-try-cssom.html b/third_party/blink/web_tests/external/wpt/css/css-anchor-position/at-position-try-cssom.html index dc248f4..91172c5 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-anchor-position/at-position-try-cssom.html +++ b/third_party/blink/web_tests/external/wpt/css/css-anchor-position/at-position-try-cssom.html
@@ -6,7 +6,7 @@ <script src="/resources/testharnessreport.js"></script> <div id="anchor"></div> -<div id="not-anchor"></div> +<div id="other-anchor"></div> <div id="target"></div> <script> @@ -32,11 +32,11 @@ test(t => { const style = createStyle(t, ` @position-try --pf { top: anchor(top); left: 0; } - #anchor, #not-anchor, #target { + #anchor, #other-anchor, #target { position: absolute; width: 100px; height: 100px; } #anchor { top: 100px; left: 0; anchor-name: --a; } - #not-anchor { top: 200px; left: 0; anchor-name: --b; } + #other-anchor { top: 200px; left: 0; anchor-name: --b; } #target { position-try-options: --pf; position-anchor: --a; left: 999999px; } `); const positionTryRule = style.sheet.cssRules[0]; @@ -50,12 +50,17 @@ assert_equals(target.getBoundingClientRect().left, 100); assert_equals(target.getBoundingClientRect().top, 100); - // These properties are disallowed in `@position-try` rule, and hence should not affect + // This property are disallowed in `@position-try` rule, and hence should not affect // position fallback. - positionTryRule.style.setProperty('position-anchor', '--b'); positionTryRule.style.setProperty('position', 'static'); assert_equals(target.getBoundingClientRect().left, 100); assert_equals(target.getBoundingClientRect().top, 100); + + // `position-anchor` is an allowed property in `@position-try` and should affect position fallback. + positionTryRule.style.setProperty('position-anchor', '--b'); + assert_equals(target.getBoundingClientRect().left, 100); + assert_equals(target.getBoundingClientRect().top, 200); + }, 'CSSPositionTryRule.style.setProperty setting allowed and disallowed properties'); </script>
diff --git a/third_party/blink/web_tests/wpt_internal/css/css-anchor-position/try-cascade.html b/third_party/blink/web_tests/external/wpt/css/css-anchor-position/position-try-cascade.html similarity index 86% rename from third_party/blink/web_tests/wpt_internal/css/css-anchor-position/try-cascade.html rename to third_party/blink/web_tests/external/wpt/css/css-anchor-position/position-try-cascade.html index 12f25b9..c5ee04b3 100644 --- a/third_party/blink/web_tests/wpt_internal/css/css-anchor-position/try-cascade.html +++ b/third_party/blink/web_tests/external/wpt/css/css-anchor-position/position-try-cascade.html
@@ -1,5 +1,6 @@ <!DOCTYPE html> <title>CSS Anchor Positioning Test: @position-try and cascade interaction</title> +<link rel="help" href="https://drafts.csswg.org/css-anchor-position-1/#fallback-apply"> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> <style> @@ -26,7 +27,7 @@ } </style> -<!-- Basic @try rule --> +<!-- Basic @position-try rule --> <div class=cb> <div id=abs_try class=abs></div> </div> @@ -34,7 +35,7 @@ test(() => { assert_equals(abs_try.offsetLeft, 50); assert_equals(abs_try.offsetTop, 50); - }, '@try rule applies'); + }, '@position-try rule applies'); </script> <!-- Inline style --> @@ -45,7 +46,7 @@ test(() => { assert_equals(abs_inline.offsetLeft, 50); assert_equals(abs_inline.offsetTop, 50); - }, '@try rule wins over inline style'); + }, '@position-try rule wins over inline style'); </script> <!-- !important --> @@ -61,7 +62,7 @@ test(() => { assert_equals(abs_important.offsetLeft, 10); assert_equals(abs_important.offsetTop, 50); - }, '@try rule does not win over !important'); + }, '@position-try rule does not win over !important'); </script> <!-- Animations --> @@ -81,7 +82,7 @@ test(() => { assert_equals(abs_animation.offsetLeft, 50); assert_equals(abs_animation.offsetTop, 20); - }, '@try rule does not win over animations'); + }, '@position-try rule does not win over animations'); </script> <!-- Transitions -->
diff --git a/third_party/blink/web_tests/wpt_internal/css/css-anchor-position/try-initial-transition.html b/third_party/blink/web_tests/external/wpt/css/css-anchor-position/position-try-initial-transition.html similarity index 91% rename from third_party/blink/web_tests/wpt_internal/css/css-anchor-position/try-initial-transition.html rename to third_party/blink/web_tests/external/wpt/css/css-anchor-position/position-try-initial-transition.html index a26696d..0e81607 100644 --- a/third_party/blink/web_tests/wpt_internal/css/css-anchor-position/try-initial-transition.html +++ b/third_party/blink/web_tests/external/wpt/css/css-anchor-position/position-try-initial-transition.html
@@ -1,5 +1,6 @@ <!DOCTYPE html> <title>CSS Anchor Positioning Test: Initial @position-try does not trigger a transition</title> +<link rel="help" href="https://drafts.csswg.org/css-anchor-position-1/#fallback-apply"> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> <div id=cb>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-computed-color-mix-function-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-computed-color-mix-function-expected.txt index e6dca61..d47cba9 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-computed-color-mix-function-expected.txt +++ b/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-computed-color-mix-function-expected.txt
@@ -1,9 +1,9 @@ This is a testharness.js-based test. Found 8 FAIL, 0 TIMEOUT, 0 NOTRUN. [FAIL] Property color value 'color-mix(in hsl, white, blue)' - Colors do not match.\nActual: color(srgb 0.875 0.625 0.875)\nExpected: color(srgb 0.62 0.62 0.87).\nError: assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 0.62 +/- 0.01, expected 0.62 but got 0.875 + Colors do not match.\nActual: color(srgb 0.875 0.625 0.875)\nExpected: color(srgb 0.625 0.625 0.875).\nError: assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 0.625 +/- 0.01, expected 0.625 but got 0.875 [FAIL] Property color value 'color-mix(in hsl, white 10%, blue)' - Colors do not match.\nActual: color(srgb 0.307 0.145 0.955)\nExpected: color(srgb 0.15 0.15 0.96).\nError: assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 0.15 +/- 0.01, expected 0.15 but got 0.307 + Colors do not match.\nActual: color(srgb 0.307 0.145 0.955)\nExpected: color(srgb 0.145 0.145 0.955).\nError: assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 0.145 +/- 0.01, expected 0.145 but got 0.307 [FAIL] Property color value 'color-mix(in hwb, white, blue)' Colors do not match.\nActual: color(srgb 1 0.5 1)\nExpected: color(srgb 0.5 0.5 1).\nError: assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 0.5 +/- 0.01, expected 0.5 but got 1 [FAIL] Property color value 'color-mix(in hwb, white 10%, blue)'
diff --git a/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-computed-color-mix-function.html b/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-computed-color-mix-function.html index b54aa0d..4ac7cb6 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-computed-color-mix-function.html +++ b/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-computed-color-mix-function.html
@@ -42,8 +42,8 @@ fuzzy_test_computed_color(`color-mix(in hsl, hsl(120deg 10% 20% / 0), hsl(30deg 30% 40%))`, `color(srgb 0.46 0.52 0.28 / 0.5)`); fuzzy_test_computed_color(`color-mix(in hsl, hsl(120deg 10% 20% / 0) 10%, hsl(30deg 30% 40%))`, `color(srgb 0.52 0.436 0.28 / 0.9)`); - fuzzy_test_computed_color(`color-mix(in hsl, white, blue)`, `color(srgb 0.62 0.62 0.87)`); - fuzzy_test_computed_color(`color-mix(in hsl, white 10%, blue)`, `color(srgb 0.15 0.15 0.96)`); + fuzzy_test_computed_color(`color-mix(in hsl, white, blue)`, `color(srgb 0.625 0.625 0.875)`); + fuzzy_test_computed_color(`color-mix(in hsl, white 10%, blue)`, `color(srgb 0.145 0.145 0.955)`); fuzzy_test_computed_color(`color-mix(in hsl, hsl(40deg 50% 50%), hsl(60deg 50% 50%))`, `color(srgb 0.75 0.666667 0.25)`); fuzzy_test_computed_color(`color-mix(in hsl, hsl(60deg 50% 50%), hsl(40deg 50% 50%))`, `color(srgb 0.75 0.666667 0.25)`); @@ -421,8 +421,8 @@ fuzzy_test_computed_color(`color-mix(in oklab, oklab(0.1 0.2 0.3 / 0), oklab(0.3 0.4 0.5))`, 'oklab(0.3 0.4 0.5 / 0.5)'); fuzzy_test_computed_color(`color-mix(in oklab, oklab(0.1 0.2 0.3 / 0) 10%, oklab(0.3 0.4 0.5))`, 'oklab(0.3 0.4 0.5 / 0.9)'); - fuzzy_test_computed_color(`color-mix(in oklab, white, blue)`, `oklab(0.73 -0.02 -0.16)`); - fuzzy_test_computed_color(`color-mix(in oklab, white 10%, blue)`, `oklab(0.51 -0.03 -0.28)`); + fuzzy_test_computed_color(`color-mix(in oklab, white, blue)`, `oklab(0.726 -0.016 -0.156)`); + fuzzy_test_computed_color(`color-mix(in oklab, white 10%, blue)`, `oklab(0.507 -0.029 -0.28)`); fuzzy_test_computed_color(`color-mix(in oklab, oklab(none none none), oklab(none none none))`, `oklab(none none none)`); fuzzy_test_computed_color(`color-mix(in oklab, oklab(none none none), oklab(0.5 0.6 0.7))`, `oklab(0.5 0.6 0.7)`);
diff --git a/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-computed-relative-color-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-computed-relative-color-expected.txt index a9d32e6f..5685549 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-computed-relative-color-expected.txt +++ b/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-computed-relative-color-expected.txt
@@ -1,11 +1,35 @@ This is a testharness.js-based test. -Found 18 FAIL, 0 TIMEOUT, 0 NOTRUN. +Found 46 FAIL, 0 TIMEOUT, 0 NOTRUN. [FAIL] Property color value 'rgb(from color-mix(in srgb, red, red) r g b / alpha)' assert_true: 'rgb(from color-mix(in srgb, red, red) r g b / alpha)' is a supported value for color. expected true got false +[FAIL] Property color value 'hsl(from rebeccapurple h alpha l / s)' + Colors do not match.\nActual: color(srgb 0.4 0 0.8 / 0.5)\nExpected: color(srgb 0.4 0.396 0.404 / 1).\nError: assert_array_approx_equals: Numeric parameters are approximately equal. property 1, expected 0.396 +/- 0.01, expected 0.396 but got 0 +[FAIL] Property color value 'hsl(from rebeccapurple h l l / l)' + Colors do not match.\nActual: color(srgb 0.4 0.24 0.56 / 0.4)\nExpected: color(srgb 0.4 0.24 0.56 / 1).\nError: assert_array_approx_equals: Numeric parameters are approximately equal. property 3, expected 1 +/- 0.01, expected 1 but got 0.4 +[FAIL] Property color value 'hsl(from rebeccapurple h alpha alpha / alpha)' + Colors do not match.\nActual: color(srgb 1 1 1)\nExpected: color(srgb 0.01 0.01 0.01).\nError: assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 0.01 +/- 0.01, expected 0.01 but got 1 +[FAIL] Property color value 'hsl(from rgb(20%, 40%, 60%, 80%) h alpha l / s)' + Colors do not match.\nActual: color(srgb 0.08 0.4 0.72 / 0.5)\nExpected: color(srgb 0.397 0.4 0.403 / 1).\nError: assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 0.397 +/- 0.01, expected 0.397 but got 0.08 +[FAIL] Property color value 'hsl(from rgb(20%, 40%, 60%, 80%) h l l / l)' + Colors do not match.\nActual: color(srgb 0.24 0.4 0.56 / 0.4)\nExpected: color(srgb 0.24 0.4 0.56 / 1).\nError: assert_array_approx_equals: Numeric parameters are approximately equal. property 3, expected 1 +/- 0.01, expected 1 but got 0.4 +[FAIL] Property color value 'hsl(from rgb(20%, 40%, 60%, 80%) h alpha alpha / alpha)' + Colors do not match.\nActual: color(srgb 0.64 0.8 0.96 / 0.8)\nExpected: color(srgb 0.01 0.01 0.01 / 0.8).\nError: assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 0.01 +/- 0.01, expected 0.01 but got 0.64 [FAIL] Property color value 'hsl(from hsl(20 30 40 / 0.8) calc(h + 1) calc(s + 1) calc(l + 1) / calc(alpha + 0.01))' - Colors do not match.\nActual: color(srgb 0.88 1.556 1.92 / 0.81)\nExpected: color(srgb 0.54 0.37 0.28 / 0.81).\nError: assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 0.54 +/- 0.01, expected 0.54 but got 0.88 + Colors do not match.\nActual: color(srgb 0.88 1.556 1.92 / 0.81)\nExpected: color(srgb 0.537 0.372 0.283 / 0.81).\nError: assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 0.537 +/- 0.01, expected 0.537 but got 0.88 [FAIL] Property color value 'hsl(from color-mix(in srgb, red, red) h s l / alpha)' assert_true: 'hsl(from color-mix(in srgb, red, red) h s l / alpha)' is a supported value for color. expected true got false +[FAIL] Property color value 'hwb(from rebeccapurple h alpha w / b)' + Colors do not match.\nActual: color(srgb 0.833333 0.833333 0.833333 / 0.4)\nExpected: color(srgb 0.405 0.01 0.8).\nError: assert_array_approx_equals: Numeric parameters are approximately equal. lengths differ, expected 3 got 4 +[FAIL] Property color value 'hwb(from rebeccapurple h w w / w)' + Colors do not match.\nActual: color(srgb 0.5 0.2 0.8 / 0.2)\nExpected: color(srgb 0.5 0.2 0.8).\nError: assert_array_approx_equals: Numeric parameters are approximately equal. lengths differ, expected 3 got 4 +[FAIL] Property color value 'hwb(from rebeccapurple h alpha alpha / alpha)' + Colors do not match.\nActual: color(srgb 0.5 0.5 0.5)\nExpected: color(srgb 0.5 0.01 0.99).\nError: assert_array_approx_equals: Numeric parameters are approximately equal. property 1, expected 0.01 +/- 0.01, expected 0.01 but got 0.5 +[FAIL] Property color value 'hwb(from rgb(20%, 40%, 60%, 80%) h alpha w / b)' + Colors do not match.\nActual: color(srgb 0.8 0.8 0.8 / 0.4)\nExpected: color(srgb 0.01 0.404 0.8).\nError: assert_array_approx_equals: Numeric parameters are approximately equal. lengths differ, expected 3 got 4 +[FAIL] Property color value 'hwb(from rgb(20%, 40%, 60%, 80%) h w w / w)' + Colors do not match.\nActual: color(srgb 0.2 0.5 0.8 / 0.2)\nExpected: color(srgb 0.2 0.5 0.8).\nError: assert_array_approx_equals: Numeric parameters are approximately equal. lengths differ, expected 3 got 4 +[FAIL] Property color value 'hwb(from rgb(20%, 40%, 60%, 80%) h alpha alpha / alpha)' + Colors do not match.\nActual: color(srgb 0.5 0.5 0.5 / 0.8)\nExpected: color(srgb 0.01 0.5 0.992 / 0.8).\nError: assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 0.01 +/- 0.01, expected 0.01 but got 0.5 [FAIL] Property color value 'hwb(from hwb(20 30 40 / 0.8) calc(h + 1) calc(w + 1) calc(b + 1) / calc(alpha + 0.01))' Colors do not match.\nActual: color(srgb 0.481481 0.481481 0.481481 / 0.81)\nExpected: color(srgb 0.59 0.41 0.31 / 0.81).\nError: assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 0.59 +/- 0.01, expected 0.59 but got 0.481481 [FAIL] Property color value 'hwb(from color-mix(in srgb, red, red) h w b / alpha)' @@ -36,5 +60,37 @@ assert_true: 'color(from color-mix(in xyz, color(xyz-d50 0.7 0.5 0.3), color(xyz-d50 0.7 0.5 0.3)) xyz-d50 x y z / alpha)' is a supported value for color. expected true got false [FAIL] Property color value 'color(from color-mix(in xyz, color(xyz-d65 0.7 0.5 0.3), color(xyz-d65 0.7 0.5 0.3)) xyz-d65 x y z / alpha)' assert_true: 'color(from color-mix(in xyz, color(xyz-d65 0.7 0.5 0.3), color(xyz-d65 0.7 0.5 0.3)) xyz-d65 x y z / alpha)' is a supported value for color. expected true got false +[FAIL] Property color value 'color(from rgb(from color(xyz-d50 0.99 0.88 0.77) r g b) xyz-d50 x y z)' + Colors do not match.\nActual: color(xyz-d50 0.989872 0.879877 0.769926)\nExpected: color(xyz-d50 0.99 0.88 0.77).\nError: assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 0.99 +/- 0.0001, expected 0.99 but got 0.989872 +[FAIL] Property color value 'color(from hsl(from color(xyz-d50 0.99 0.88 0.77) h s l) xyz-d50 x y z)' + Colors do not match.\nActual: color(xyz-d50 0.989872 0.879877 0.769926)\nExpected: color(xyz-d50 0.99 0.88 0.77).\nError: assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 0.99 +/- 0.0001, expected 0.99 but got 0.989872 +[FAIL] Property color value 'color(from hwb(from color(xyz-d50 0.99 0.88 0.77) h w b) xyz-d50 x y z)' + Colors do not match.\nActual: color(xyz-d50 0.989872 0.879877 0.769926)\nExpected: color(xyz-d50 0.99 0.88 0.77).\nError: assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 0.99 +/- 0.0001, expected 0.99 but got 0.989872 +[FAIL] Property color value 'color(from color(from color(xyz-d50 0.99 0.88 0.77) srgb r g b) xyz-d50 x y z)' + Colors do not match.\nActual: color(xyz-d50 0.989872 0.879877 0.769926)\nExpected: color(xyz-d50 0.99 0.88 0.77).\nError: assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 0.99 +/- 0.0001, expected 0.99 but got 0.989872 +[FAIL] Property color value 'color(from color(from color(xyz-d50 0.99 0.88 0.77) display-p3 r g b) xyz-d50 x y z)' + Colors do not match.\nActual: color(xyz-d50 0.989831 0.879845 0.769913)\nExpected: color(xyz-d50 0.99 0.88 0.77).\nError: assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 0.99 +/- 0.0001, expected 0.99 but got 0.989831 +[FAIL] Property color value 'color(from color(from color(xyz-d50 0.99 0.88 0.77) a98-rgb r g b) xyz-d50 x y z)' + Colors do not match.\nActual: color(xyz-d50 0.989614 0.879695 0.769795)\nExpected: color(xyz-d50 0.99 0.88 0.77).\nError: assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 0.99 +/- 0.0001, expected 0.99 but got 0.989614 +[FAIL] Property color value 'color(from color(from color(xyz-d50 0.99 0.88 0.77) prophoto-rgb r g b) xyz-d50 x y z)' + Colors do not match.\nActual: color(xyz-d50 0.989682 0.879725 0.769775)\nExpected: color(xyz-d50 0.99 0.88 0.77).\nError: assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 0.99 +/- 0.0001, expected 0.99 but got 0.989682 +[FAIL] Property color value 'color(from color(from color(xyz-d50 0.99 0.88 0.77) rec2020 r g b) xyz-d50 x y z)' + Colors do not match.\nActual: color(xyz-d50 0.98984 0.879861 0.769847)\nExpected: color(xyz-d50 0.99 0.88 0.77).\nError: assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 0.99 +/- 0.0001, expected 0.99 but got 0.98984 +[FAIL] Property color value 'color(from rgb(from color(xyz-d65 0.99 0.88 0.77) r g b) xyz-d65 x y z)' + Colors do not match.\nActual: color(xyz-d65 0.989888 0.879886 0.769923)\nExpected: color(xyz-d65 0.99 0.88 0.77).\nError: assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 0.99 +/- 0.0001, expected 0.99 but got 0.989888 +[FAIL] Property color value 'color(from hsl(from color(xyz-d65 0.99 0.88 0.77) h s l) xyz-d65 x y z)' + Colors do not match.\nActual: color(xyz-d65 0.989888 0.879886 0.769923)\nExpected: color(xyz-d65 0.99 0.88 0.77).\nError: assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 0.99 +/- 0.0001, expected 0.99 but got 0.989888 +[FAIL] Property color value 'color(from hwb(from color(xyz-d65 0.99 0.88 0.77) h w b) xyz-d65 x y z)' + Colors do not match.\nActual: color(xyz-d65 0.989888 0.879886 0.769923)\nExpected: color(xyz-d65 0.99 0.88 0.77).\nError: assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 0.99 +/- 0.0001, expected 0.99 but got 0.989888 +[FAIL] Property color value 'color(from color(from color(xyz-d65 0.99 0.88 0.77) srgb r g b) xyz-d65 x y z)' + Colors do not match.\nActual: color(xyz-d65 0.989888 0.879886 0.769923)\nExpected: color(xyz-d65 0.99 0.88 0.77).\nError: assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 0.99 +/- 0.0001, expected 0.99 but got 0.989888 +[FAIL] Property color value 'color(from color(from color(xyz-d65 0.99 0.88 0.77) display-p3 r g b) xyz-d65 x y z)' + Colors do not match.\nActual: color(xyz-d65 0.989874 0.879875 0.76992)\nExpected: color(xyz-d65 0.99 0.88 0.77).\nError: assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 0.99 +/- 0.0001, expected 0.99 but got 0.989874 +[FAIL] Property color value 'color(from color(from color(xyz-d65 0.99 0.88 0.77) a98-rgb r g b) xyz-d65 x y z)' + Colors do not match.\nActual: color(xyz-d65 0.989656 0.879729 0.769826)\nExpected: color(xyz-d65 0.99 0.88 0.77).\nError: assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 0.99 +/- 0.0001, expected 0.99 but got 0.989656 +[FAIL] Property color value 'color(from color(from color(xyz-d65 0.99 0.88 0.77) prophoto-rgb r g b) xyz-d65 x y z)' + Colors do not match.\nActual: color(xyz-d65 0.989647 0.879721 0.769892)\nExpected: color(xyz-d65 0.99 0.88 0.77).\nError: assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 0.99 +/- 0.0001, expected 0.99 but got 0.989647 +[FAIL] Property color value 'color(from color(from color(xyz-d65 0.99 0.88 0.77) rec2020 r g b) xyz-d65 x y z)' + Colors do not match.\nActual: color(xyz-d65 0.989824 0.879848 0.769848)\nExpected: color(xyz-d65 0.99 0.88 0.77).\nError: assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 0.99 +/- 0.0001, expected 0.99 but got 0.989824 Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-computed-relative-color.html b/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-computed-relative-color.html index 95c8eee..53d25e0 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-computed-relative-color.html +++ b/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-computed-relative-color.html
@@ -165,18 +165,18 @@ // Testing valid permutation (types match). fuzzy_test_computed_color(`hsl(from rebeccapurple h l s)`, `color(srgb 0.5 0.3 0.7)`); - fuzzy_test_computed_color(`hsl(from rebeccapurple h alpha l / s)`, `color(srgb 0.4 0 0.8 / 0.5)`); - fuzzy_test_computed_color(`hsl(from rebeccapurple h l l / l)`, `color(srgb 0.4 0.24 0.56 / 0.4)`); - fuzzy_test_computed_color(`hsl(from rebeccapurple h alpha alpha / alpha)`, `color(srgb 1 1 1)`); + fuzzy_test_computed_color(`hsl(from rebeccapurple h alpha l / s)`, `color(srgb 0.4 0.396 0.404 / 1)`); + fuzzy_test_computed_color(`hsl(from rebeccapurple h l l / l)`, `color(srgb 0.4 0.24 0.56 / 1)`); + fuzzy_test_computed_color(`hsl(from rebeccapurple h alpha alpha / alpha)`, `color(srgb 0.01 0.01 0.01)`); fuzzy_test_computed_color(`hsl(from rgb(20%, 40%, 60%, 80%) h l s)`, `color(srgb 0.3 0.5 0.7 / 0.8)`); - fuzzy_test_computed_color(`hsl(from rgb(20%, 40%, 60%, 80%) h alpha l / s)`, `color(srgb 0.08 0.4 0.72 / 0.5)`); - fuzzy_test_computed_color(`hsl(from rgb(20%, 40%, 60%, 80%) h l l / l)`, `color(srgb 0.24 0.4 0.56 / 0.4)`); - fuzzy_test_computed_color(`hsl(from rgb(20%, 40%, 60%, 80%) h alpha alpha / alpha)`, `color(srgb 0.64 0.8 0.96 / 0.8)`); + fuzzy_test_computed_color(`hsl(from rgb(20%, 40%, 60%, 80%) h alpha l / s)`, `color(srgb 0.397 0.4 0.403 / 1)`); + fuzzy_test_computed_color(`hsl(from rgb(20%, 40%, 60%, 80%) h l l / l)`, `color(srgb 0.24 0.4 0.56 / 1)`); + fuzzy_test_computed_color(`hsl(from rgb(20%, 40%, 60%, 80%) h alpha alpha / alpha)`, `color(srgb 0.01 0.01 0.01 / 0.8)`); // Testing with calc(). fuzzy_test_computed_color(`hsl(from rebeccapurple calc(h) calc(s) calc(l))`, `color(srgb 0.4 0.2 0.6)`); fuzzy_test_computed_color(`hsl(from rgb(20%, 40%, 60%, 80%) calc(h) calc(s) calc(l) / calc(alpha))`, `color(srgb 0.2 0.4 0.6 / 0.8)`); - fuzzy_test_computed_color(`hsl(from hsl(20 30 40 / 0.8) calc(h + 1) calc(s + 1) calc(l + 1) / calc(alpha + 0.01))`, `color(srgb 0.54 0.37 0.28 / 0.81)`); // hsl(21 31 41) + fuzzy_test_computed_color(`hsl(from hsl(20 30 40 / 0.8) calc(h + 1) calc(s + 1) calc(l + 1) / calc(alpha + 0.01))`, `color(srgb 0.537 0.372 0.283 / 0.81)`); // hsl(21 31 41) fuzzy_test_computed_color(`hsl(from rebeccapurple calc((h / 360) * 360deg) calc((s / 100) * 100%) calc((l / 100) * 100%) / calc(alpha * 100%))`, `color(srgb 0.4 0.2 0.6)`); // Testing with 'none'. Missing components are resolved to zero during color space conversion. @@ -240,13 +240,13 @@ // Testing valid permutation (types match). fuzzy_test_computed_color(`hwb(from rebeccapurple h b w)`, `color(srgb 0.6 0.4 0.8)`); - fuzzy_test_computed_color(`hwb(from rebeccapurple h alpha w / b)`, `color(srgb 0.8333 0.8333 0.8333 / 0.4)`); - fuzzy_test_computed_color(`hwb(from rebeccapurple h w w / w)`, `color(srgb 0.5 0.2 0.8 / 0.2)`); - fuzzy_test_computed_color(`hwb(from rebeccapurple h alpha alpha / alpha)`, `color(srgb 0.5 0.5 0.5)`); + fuzzy_test_computed_color(`hwb(from rebeccapurple h alpha w / b)`, `color(srgb 0.405 0.01 0.8)`); + fuzzy_test_computed_color(`hwb(from rebeccapurple h w w / w)`, `color(srgb 0.5 0.2 0.8)`); + fuzzy_test_computed_color(`hwb(from rebeccapurple h alpha alpha / alpha)`, `color(srgb 0.5 0.01 0.99)`); fuzzy_test_computed_color(`hwb(from rgb(20%, 40%, 60%, 80%) h b w)`, `color(srgb 0.4 0.6 0.8 / 0.8)`); - fuzzy_test_computed_color(`hwb(from rgb(20%, 40%, 60%, 80%) h alpha w / b)`, `color(srgb 0.8 0.8 0.8 / 0.4)`); - fuzzy_test_computed_color(`hwb(from rgb(20%, 40%, 60%, 80%) h w w / w)`, `color(srgb 0.2 0.5 0.8 / 0.2)`); - fuzzy_test_computed_color(`hwb(from rgb(20%, 40%, 60%, 80%) h alpha alpha / alpha)`, `color(srgb 0.5 0.5 0.5 / 0.8)`); + fuzzy_test_computed_color(`hwb(from rgb(20%, 40%, 60%, 80%) h alpha w / b)`, `color(srgb 0.01 0.404 0.8)`); + fuzzy_test_computed_color(`hwb(from rgb(20%, 40%, 60%, 80%) h w w / w)`, `color(srgb 0.2 0.5 0.8)`); + fuzzy_test_computed_color(`hwb(from rgb(20%, 40%, 60%, 80%) h alpha alpha / alpha)`, `color(srgb 0.01 0.5 0.992 / 0.8)`); // Testing with calc(). fuzzy_test_computed_color(`hwb(from rebeccapurple calc(h) calc(w) calc(b))`, `color(srgb 0.4 0.2 0.6)`); @@ -744,6 +744,26 @@ fuzzy_test_computed_color(`oklch(from color(srgb 0.25 0.5 0.75) l c h)`, `oklch(0.585502 0.118254 250.546)`, 0.02); // Larger values means larger epsilon. fuzzy_test_computed_color(`color(from oklch(72.322% 0.12403 247.996) srgb r g b)`, `color(srgb 0.382631 0.672756 0.938904)`, 0.001); + // Test that conversion are relatively lossless. + for (const colorSpace of ["xyz-d50", "xyz-d65"]) { + fuzzy_test_computed_color(`color(from rgb(from color(${colorSpace} 0.99 0.88 0.77) r g b) ${colorSpace} x y z)`, `color(${colorSpace} 0.99 0.88 0.77)`, 0.0001); + fuzzy_test_computed_color(`color(from hsl(from color(${colorSpace} 0.99 0.88 0.77) h s l) ${colorSpace} x y z)`, `color(${colorSpace} 0.99 0.88 0.77)`, 0.0001); + fuzzy_test_computed_color(`color(from hwb(from color(${colorSpace} 0.99 0.88 0.77) h w b) ${colorSpace} x y z)`, `color(${colorSpace} 0.99 0.88 0.77)`, 0.0001); + fuzzy_test_computed_color(`color(from lab(from color(${colorSpace} 0.99 0.88 0.77) l a b) ${colorSpace} x y z)`, `color(${colorSpace} 0.99 0.88 0.77)`, 0.0001); + fuzzy_test_computed_color(`color(from lch(from color(${colorSpace} 0.99 0.88 0.77) l c h) ${colorSpace} x y z)`, `color(${colorSpace} 0.99 0.88 0.77)`, 0.0001); + fuzzy_test_computed_color(`color(from oklab(from color(${colorSpace} 0.99 0.88 0.77) l a b) ${colorSpace} x y z)`, `color(${colorSpace} 0.99 0.88 0.77)`, 0.0001); + fuzzy_test_computed_color(`color(from oklch(from color(${colorSpace} 0.99 0.88 0.77) l c h) ${colorSpace} x y z)`, `color(${colorSpace} 0.99 0.88 0.77)`, 0.0001); + fuzzy_test_computed_color(`color(from color(from color(${colorSpace} 0.99 0.88 0.77) srgb r g b) ${colorSpace} x y z)`, `color(${colorSpace} 0.99 0.88 0.77)`, 0.0001); + fuzzy_test_computed_color(`color(from color(from color(${colorSpace} 0.99 0.88 0.77) srgb-linear r g b) ${colorSpace} x y z)`, `color(${colorSpace} 0.99 0.88 0.77)`, 0.0001); + fuzzy_test_computed_color(`color(from color(from color(${colorSpace} 0.99 0.88 0.77) display-p3 r g b) ${colorSpace} x y z)`, `color(${colorSpace} 0.99 0.88 0.77)`, 0.0001); + fuzzy_test_computed_color(`color(from color(from color(${colorSpace} 0.99 0.88 0.77) a98-rgb r g b) ${colorSpace} x y z)`, `color(${colorSpace} 0.99 0.88 0.77)`, 0.0001); + fuzzy_test_computed_color(`color(from color(from color(${colorSpace} 0.99 0.88 0.77) prophoto-rgb r g b) ${colorSpace} x y z)`, `color(${colorSpace} 0.99 0.88 0.77)`, 0.0001); + fuzzy_test_computed_color(`color(from color(from color(${colorSpace} 0.99 0.88 0.77) rec2020 r g b) ${colorSpace} x y z)`, `color(${colorSpace} 0.99 0.88 0.77)`, 0.0001); + fuzzy_test_computed_color(`color(from color(from color(${colorSpace} 0.99 0.88 0.77) xyz x y z) ${colorSpace} x y z)`, `color(${colorSpace} 0.99 0.88 0.77)`, 0.0001); + fuzzy_test_computed_color(`color(from color(from color(${colorSpace} 0.99 0.88 0.77) xyz-d50 x y z) ${colorSpace} x y z)`, `color(${colorSpace} 0.99 0.88 0.77)`, 0.0001); + fuzzy_test_computed_color(`color(from color(from color(${colorSpace} 0.99 0.88 0.77) xyz-d65 x y z) ${colorSpace} x y z)`, `color(${colorSpace} 0.99 0.88 0.77)`, 0.0001); + } + // Spec Examples: https://www.w3.org/TR/css-color-5/#relative-colors // All examples here have multiple stages of calculations so minor disagreements in the values of keyword colors and other constants can compound. // These tests require a wider epsilon of 0.02.
diff --git a/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-invalid-relative-color.html b/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-invalid-relative-color.html index 2cb3a252..6739007 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-invalid-relative-color.html +++ b/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-invalid-relative-color.html
@@ -28,9 +28,9 @@ test_invalid_value(`color`, `rgb(from rebeccapurple l g b)`); test_invalid_value(`color`, `rgb(from rebeccapurple h g b)`); - // Testing invalid function name variation (only rgb() is valid, rgba() is invalid) - test_invalid_value(`color`, `rgba(from rebeccapurple r g b)`); - test_invalid_value(`color`, `rgba(from rgb(10%, 20%, 30%, 40%) r g b / alpha)`); + // Testing invalid separator + test_invalid_value(`color`, `rgb(from rebeccapurple, r, g, b)`); + test_invalid_value(`color`, `rgba(from rgb(10%, 20%, 30%, 40%), r, g, b, alpha)`); // Testing with calc(). test_invalid_value(`color`, `rgb(from rebeccapurple calc(r + 1%) g b)`); @@ -47,9 +47,9 @@ test_invalid_value(`color`, `hsl(from rebeccapurple x s l)`); test_invalid_value(`color`, `hsl(from rebeccapurple h g b)`); - // Testing invalid function name variation (only hsl() is valid, hsla() is invalid) - test_invalid_value(`color`, `hsla(from rebeccapurple h s l)`); - test_invalid_value(`color`, `hsla(from rgb(10%, 20%, 30%, 40%) h s l / alpha)`); + // Testing invalid separator + test_invalid_value(`color`, `hsl(from rebeccapurple, h, s, l)`); + test_invalid_value(`color`, `hsla(from rgb(10%, 20%, 30%, 40%), h, s, l, alpha)`); // Testing with calc(). test_invalid_value(`color`, `hsl(from rebeccapurple calc(h + 1deg) s l)`);
diff --git a/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-valid-relative-color-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-valid-relative-color-expected.txt index b55eed3..2f72d60f 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-valid-relative-color-expected.txt +++ b/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-valid-relative-color-expected.txt
@@ -1,17 +1,5 @@ This is a testharness.js-based test. -Found 58 FAIL, 0 TIMEOUT, 0 NOTRUN. -[FAIL] e.style['color'] = "rgb(from rebeccapurple b alpha r / g)" should set the property value - Colors do not match.\nActual: color(srgb 0.6 0.00392157 0.4)\nExpected: color(srgb 0.6 1 0.4 / 0.2).\nError: assert_array_approx_equals: Numeric parameters are approximately equal. lengths differ, expected 4 got 3 -[FAIL] e.style['color'] = "rgb(from rebeccapurple r r r / r)" should set the property value - Colors do not match.\nActual: color(srgb 0.4 0.4 0.4)\nExpected: color(srgb 0.4 0.4 0.4 / 0.4).\nError: assert_array_approx_equals: Numeric parameters are approximately equal. lengths differ, expected 4 got 3 -[FAIL] e.style['color'] = "rgb(from rebeccapurple alpha alpha alpha / alpha)" should set the property value - Colors do not match.\nActual: color(srgb 0.00392157 0.00392157 0.00392157)\nExpected: color(srgb 1 1 1).\nError: assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 1 +/- 0.01, expected 1 but got 0.00392157 -[FAIL] e.style['color'] = "rgb(from rgb(20%, 40%, 60%, 80%) b alpha r / g)" should set the property value - Colors do not match.\nActual: color(srgb 0.6 0.00313725 0.2)\nExpected: color(srgb 0.6 0.8 0.2 / 0.4).\nError: assert_array_approx_equals: Numeric parameters are approximately equal. lengths differ, expected 4 got 3 -[FAIL] e.style['color'] = "rgb(from rgb(20%, 40%, 60%, 80%) r r r / r)" should set the property value - Colors do not match.\nActual: color(srgb 0.2 0.2 0.2)\nExpected: color(srgb 0.2 0.2 0.2 / 0.2).\nError: assert_array_approx_equals: Numeric parameters are approximately equal. lengths differ, expected 4 got 3 -[FAIL] e.style['color'] = "rgb(from rgb(20%, 40%, 60%, 80%) alpha alpha alpha / alpha)" should set the property value - Colors do not match.\nActual: color(srgb 0.00313725 0.00313725 0.00313725 / 0.8)\nExpected: color(srgb 0.8 0.8 0.8 / 0.8).\nError: assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 0.8 +/- 0.01, expected 0.8 but got 0.00313725 +Found 175 FAIL, 0 TIMEOUT, 0 NOTRUN. [FAIL] e.style['color'] = "rgb(from rebeccapurple none none none)" should set the property value Colors do not match.\nActual: color(srgb 0 0 0)\nExpected: color(srgb none none none).\nError: assert_array_approx_equals: Numeric parameters are approximately equal. lengths differ, expected 0 got 3 [FAIL] e.style['color'] = "rgb(from rebeccapurple none none none / none)" should set the property value @@ -26,38 +14,286 @@ assert_not_equals: property should be set got disallowed value "" [FAIL] e.style['color'] = "rgb(from color-mix(in srgb, red, red) r g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -[FAIL] e.style['color'] = "hsl(from rebeccapurple none none none)" should set the property value - Colors do not match.\nActual: color(srgb 0 0 0)\nExpected: color(srgb none none none).\nError: assert_array_approx_equals: Numeric parameters are approximately equal. lengths differ, expected 0 got 3 +[FAIL] e.style['color'] = "rgba(from rebeccapurple r g b)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "rgba(from rebeccapurple r g b / alpha)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "rgba(from rgb(20%, 40%, 60%, 80%) r g b / alpha)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "rgba(from hsl(120deg 20% 50% / .5) r g b / alpha)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "rgba(from rgb(from rebeccapurple r g b) r g b)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "rgba(from rebeccapurple 0 0 0)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "rgba(from rebeccapurple 0 0 0 / 0)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "rgba(from rebeccapurple 0 g b / alpha)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "rgba(from rebeccapurple r 0 b / alpha)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "rgba(from rebeccapurple r g 0 / alpha)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "rgba(from rebeccapurple r g b / 0)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "rgba(from rgb(20%, 40%, 60%, 80%) 0 g b / alpha)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "rgba(from rgb(20%, 40%, 60%, 80%) r 0 b / alpha)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "rgba(from rgb(20%, 40%, 60%, 80%) r g 0 / alpha)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "rgba(from rgb(20%, 40%, 60%, 80%) r g b / 0)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "rgba(from rebeccapurple 25 g b / alpha)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "rgba(from rebeccapurple r 25 b / alpha)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "rgba(from rebeccapurple r g 25 / alpha)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "rgba(from rebeccapurple r g b / .25)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "rgba(from rgb(20%, 40%, 60%, 80%) 25 g b / alpha)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "rgba(from rgb(20%, 40%, 60%, 80%) r 25 b / alpha)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "rgba(from rgb(20%, 40%, 60%, 80%) r g 25 / alpha)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "rgba(from rgb(20%, 40%, 60%, 80%) r g b / .20)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "rgba(from rebeccapurple 20% g b / alpha)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "rgba(from rebeccapurple r 20% b / alpha)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "rgba(from rebeccapurple r g 20% / alpha)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "rgba(from rebeccapurple r g b / 20%)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "rgba(from rgb(20%, 40%, 60%, 80%) 20% g b / alpha)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "rgba(from rgb(20%, 40%, 60%, 80%) r 20% b / alpha)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "rgba(from rgb(20%, 40%, 60%, 80%) r g 20% / alpha)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "rgba(from rgb(20%, 40%, 60%, 80%) r g b / 20%)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "rgba(from rebeccapurple 25 g b / 25%)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "rgba(from rebeccapurple r 25 b / 25%)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "rgba(from rebeccapurple r g 25 / 25%)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "rgba(from rgb(20%, 40%, 60%, 80%) 25 g b / 25%)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "rgba(from rgb(20%, 40%, 60%, 80%) r 25 b / 25%)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "rgba(from rgb(20%, 40%, 60%, 80%) r g 25 / 25%)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "rgba(from rebeccapurple g b r)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "rgba(from rebeccapurple b alpha r / g)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "rgba(from rebeccapurple r r r / r)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "rgba(from rebeccapurple alpha alpha alpha / alpha)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "rgba(from rgb(20%, 40%, 60%, 80%) g b r)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "rgba(from rgb(20%, 40%, 60%, 80%) b alpha r / g)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "rgba(from rgb(20%, 40%, 60%, 80%) r r r / r)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "rgba(from rgb(20%, 40%, 60%, 80%) alpha alpha alpha / alpha)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "rgba(from rebeccapurple r 20% 10)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "rgba(from rebeccapurple r 10 20%)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "rgba(from rebeccapurple 0% 10 10)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "rgba(from rgb(20%, 40%, 60%, 80%) r 20% 10)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "rgba(from rgb(20%, 40%, 60%, 80%) r 10 20%)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "rgba(from rgb(20%, 40%, 60%, 80%) 0% 10 10)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "rgba(from rebeccapurple calc(r) calc(g) calc(b))" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "rgba(from rebeccapurple r calc(g * 2) 10)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "rgba(from rebeccapurple b calc(r * .5) 10)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "rgba(from rebeccapurple r calc(g * .5 + g * .5) 10)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "rgba(from rebeccapurple r calc(b * .5 - g * .5) 10)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "rgba(from rgb(20%, 40%, 60%, 80%) calc(r) calc(g) calc(b) / calc(alpha))" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "rgba(from rebeccapurple none none none)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "rgba(from rebeccapurple none none none / none)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "rgba(from rebeccapurple r g none)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "rgba(from rebeccapurple r g none / alpha)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "rgba(from rebeccapurple r g b / none)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "rgba(from rgb(20% 40% 60% / 80%) r g none / alpha)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "rgba(from rgb(20% 40% 60% / 80%) r g b / none)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "rgba(from rgb(none none none) r g b)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "rgba(from rgb(none none none / none) r g b / alpha)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "rgba(from rgb(20% none 60%) r g b)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "rgba(from rgb(20% 40% 60% / none) r g b / alpha)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "rgba(from currentColor r g b)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "rgba(from color-mix(in srgb, red, red) r g b / alpha)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "hsl(from rebeccapurple h alpha l / s)" should set the property value + Colors do not match.\nActual: color(srgb 0.4 0 0.8 / 0.5)\nExpected: color(srgb 0.4 0.396 0.404).\nError: assert_array_approx_equals: Numeric parameters are approximately equal. lengths differ, expected 3 got 4 +[FAIL] e.style['color'] = "hsl(from rebeccapurple h l l / l)" should set the property value + Colors do not match.\nActual: color(srgb 0.4 0.24 0.56 / 0.4)\nExpected: color(srgb 0.4 0.24 0.56).\nError: assert_array_approx_equals: Numeric parameters are approximately equal. lengths differ, expected 3 got 4 +[FAIL] e.style['color'] = "hsl(from rebeccapurple h alpha alpha / alpha)" should set the property value + Colors do not match.\nActual: color(srgb 1 1 1)\nExpected: color(srgb 0.01 0.01 0.01).\nError: assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 0.01 +/- 0.01, expected 0.01 but got 1 +[FAIL] e.style['color'] = "hsl(from rgb(20%, 40%, 60%, 80%) h alpha l / s)" should set the property value + Colors do not match.\nActual: color(srgb 0.08 0.4 0.72 / 0.5)\nExpected: color(srgb 0.4 0.4 0.4).\nError: assert_array_approx_equals: Numeric parameters are approximately equal. lengths differ, expected 3 got 4 +[FAIL] e.style['color'] = "hsl(from rgb(20%, 40%, 60%, 80%) h l l / l)" should set the property value + Colors do not match.\nActual: color(srgb 0.24 0.4 0.56 / 0.4)\nExpected: color(srgb 0.24 0.4 0.56).\nError: assert_array_approx_equals: Numeric parameters are approximately equal. lengths differ, expected 3 got 4 +[FAIL] e.style['color'] = "hsl(from rgb(20%, 40%, 60%, 80%) h alpha alpha / alpha)" should set the property value + Colors do not match.\nActual: color(srgb 0.64 0.8 0.96 / 0.8)\nExpected: color(srgb 0.01 0.01 0.01 / 0.8).\nError: assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 0.01 +/- 0.01, expected 0.01 but got 0.64 [FAIL] e.style['color'] = "hsl(from rebeccapurple none none none / none)" should set the property value - Colors do not match.\nActual: color(srgb 0 0 0 / none)\nExpected: color(srgb none none none / none).\nError: assert_array_approx_equals: Numeric parameters are approximately equal. lengths differ, expected 0 got 3 -[FAIL] e.style['color'] = "hsl(from rebeccapurple h s none)" should set the property value - Colors do not match.\nActual: color(srgb 0 0 0)\nExpected: color(srgb 0 0 none).\nError: assert_array_approx_equals: Numeric parameters are approximately equal. lengths differ, expected 2 got 3 -[FAIL] e.style['color'] = "hsl(from rebeccapurple h s none / alpha)" should set the property value - Colors do not match.\nActual: color(srgb 0 0 0)\nExpected: color(srgb 0 0 none).\nError: assert_array_approx_equals: Numeric parameters are approximately equal. lengths differ, expected 2 got 3 -[FAIL] e.style['color'] = "hsl(from rebeccapurple none s l / alpha)" should set the property value - Colors do not match.\nActual: color(srgb 0.6 0.2 0.2)\nExpected: color(srgb none 0.2 0.2).\nError: assert_array_approx_equals: Numeric parameters are approximately equal. lengths differ, expected 2 got 3 -[FAIL] e.style['color'] = "hsl(from hsl(120deg 20% 50% / .5) h s none / alpha)" should set the property value - Colors do not match.\nActual: color(srgb 0 0 0 / 0.5)\nExpected: color(srgb 0 0 none / 0.5).\nError: assert_array_approx_equals: Numeric parameters are approximately equal. lengths differ, expected 3 got 4 -[FAIL] e.style['color'] = "hsl(from hsl(120deg 20% 50% / .5) none s l / alpha)" should set the property value - Colors do not match.\nActual: color(srgb 0.6 0.4 0.4 / 0.5)\nExpected: color(srgb none 0.4 0.4 / 0.5).\nError: assert_array_approx_equals: Numeric parameters are approximately equal. lengths differ, expected 3 got 4 + Colors do not match.\nActual: color(srgb 0 0 0 / none)\nExpected: color(srgb 0 0 0 / 0).\nError: assert_array_approx_equals: Numeric parameters are approximately equal. lengths differ, expected 4 got 3 [FAIL] e.style['color'] = "hsl(from currentColor h s l)" should set the property value assert_not_equals: property should be set got disallowed value "" [FAIL] e.style['color'] = "hsl(from color-mix(in srgb, red, red) h s l / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -[FAIL] e.style['color'] = "hwb(from rebeccapurple none none none)" should set the property value - Colors do not match.\nActual: color(srgb 1 0 0)\nExpected: color(srgb none none none).\nError: assert_array_approx_equals: Numeric parameters are approximately equal. lengths differ, expected 0 got 3 -[FAIL] e.style['color'] = "hwb(from rebeccapurple none none none / none)" should set the property value - Colors do not match.\nActual: color(srgb 1 0 0 / none)\nExpected: color(srgb none none none / none).\nError: assert_array_approx_equals: Numeric parameters are approximately equal. lengths differ, expected 0 got 3 -[FAIL] e.style['color'] = "hwb(from rebeccapurple h w none)" should set the property value - Colors do not match.\nActual: color(srgb 0.6 0.2 1)\nExpected: color(srgb 0.6 0.2 none).\nError: assert_array_approx_equals: Numeric parameters are approximately equal. lengths differ, expected 2 got 3 -[FAIL] e.style['color'] = "hwb(from rebeccapurple h w none / alpha)" should set the property value - Colors do not match.\nActual: color(srgb 0.6 0.2 1)\nExpected: color(srgb 0.6 0.2 none).\nError: assert_array_approx_equals: Numeric parameters are approximately equal. lengths differ, expected 2 got 3 -[FAIL] e.style['color'] = "hwb(from rebeccapurple none w b / alpha)" should set the property value - Colors do not match.\nActual: color(srgb 0.6 0.2 0.2)\nExpected: color(srgb none 0.2 0.2).\nError: assert_array_approx_equals: Numeric parameters are approximately equal. lengths differ, expected 2 got 3 -[FAIL] e.style['color'] = "hwb(from hwb(120deg 20% 50% / .5) h w none / alpha)" should set the property value - Colors do not match.\nActual: color(srgb 0.2 1 0.2 / 0.5)\nExpected: color(srgb 0.2 1 none / 0.5).\nError: assert_array_approx_equals: Numeric parameters are approximately equal. lengths differ, expected 3 got 4 -[FAIL] e.style['color'] = "hwb(from hwb(120deg 20% 50% / .5) none w b / alpha)" should set the property value - Colors do not match.\nActual: color(srgb 0.5 0.2 0.2 / 0.5)\nExpected: color(srgb none 0.2 0.2 / 0.5).\nError: assert_array_approx_equals: Numeric parameters are approximately equal. lengths differ, expected 3 got 4 +[FAIL] e.style['color'] = "hsla(from rebeccapurple h s l)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "hsla(from rebeccapurple h s l / alpha)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "hsla(from rgb(20%, 40%, 60%, 80%) h s l / alpha)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "hsla(from hsl(120deg 20% 50% / .5) h s l / alpha)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "hsla(from hsl(from rebeccapurple h s l) h s l)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "hsla(from rebeccapurple 0 0% 0%)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "hsla(from rebeccapurple 0deg 0% 0%)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "hsla(from rebeccapurple 0 0% 0% / 0)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "hsla(from rebeccapurple 0deg 0% 0% / 0)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "hsla(from rebeccapurple 0 s l / alpha)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "hsla(from rebeccapurple 0deg s l / alpha)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "hsla(from rebeccapurple h 0% l / alpha)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "hsla(from rebeccapurple h s 0% / alpha)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "hsla(from rebeccapurple h s l / 0)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "hsla(from rgb(20%, 40%, 60%, 80%) 0 s l / alpha)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "hsla(from rgb(20%, 40%, 60%, 80%) 0deg s l / alpha)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "hsla(from rgb(20%, 40%, 60%, 80%) h 0% l / alpha)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "hsla(from rgb(20%, 40%, 60%, 80%) h s 0% / alpha)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "hsla(from rgb(20%, 40%, 60%, 80%) h s l / 0)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "hsla(from rebeccapurple 25 s l / alpha)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "hsla(from rebeccapurple 25deg s l / alpha)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "hsla(from rebeccapurple h 20% l / alpha)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "hsla(from rebeccapurple h s 20% / alpha)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "hsla(from rebeccapurple h s l / .25)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "hsla(from rgb(20%, 40%, 60%, 80%) 25 s l / alpha)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "hsla(from rgb(20%, 40%, 60%, 80%) 25deg s l / alpha)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "hsla(from rgb(20%, 40%, 60%, 80%) h 20% l / alpha)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "hsla(from rgb(20%, 40%, 60%, 80%) h s 20% / alpha)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "hsla(from rgb(20%, 40%, 60%, 80%) h s l / .2)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "hsla(from rebeccapurple h l s)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "hsla(from rebeccapurple h alpha l / s)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "hsla(from rebeccapurple h l l / l)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "hsla(from rebeccapurple h alpha alpha / alpha)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "hsla(from rgb(20%, 40%, 60%, 80%) h l s)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "hsla(from rgb(20%, 40%, 60%, 80%) h alpha l / s)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "hsla(from rgb(20%, 40%, 60%, 80%) h l l / l)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "hsla(from rgb(20%, 40%, 60%, 80%) h alpha alpha / alpha)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "hsla(from rebeccapurple calc(h) calc(s) calc(l))" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "hsla(from rgb(20%, 40%, 60%, 80%) calc(h) calc(s) calc(l) / calc(alpha))" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "hsla(from rebeccapurple none none none)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "hsla(from rebeccapurple none none none / none)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "hsla(from rebeccapurple h s none)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "hsla(from rebeccapurple h s none / alpha)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "hsla(from rebeccapurple h s l / none)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "hsla(from rebeccapurple none s l / alpha)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "hsla(from hsl(120deg 20% 50% / .5) h s none / alpha)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "hsla(from hsl(120deg 20% 50% / .5) h s l / none)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "hsla(from hsl(120deg 20% 50% / .5) none s l / alpha)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "hsla(from hsl(none none none) h s l)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "hsla(from hsl(none none none / none) h s l / alpha)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "hsla(from hsl(120deg none 50% / .5) h s l)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "hsla(from hsl(120deg 20% 50% / none) h s l / alpha)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "hsla(from hsl(none 20% 50% / .5) h s l / alpha)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "hsla(from currentColor h s l)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "hsla(from color-mix(in srgb, red, red) h s l / alpha)" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['color'] = "hwb(from rebeccapurple h alpha w / b)" should set the property value + Colors do not match.\nActual: color(srgb 0.833333 0.833333 0.833333 / 0.4)\nExpected: color(srgb 0.405 0.01 0.8 / 1).\nError: assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 0.405 +/- 0.01, expected 0.405 but got 0.833333 +[FAIL] e.style['color'] = "hwb(from rebeccapurple h w w / w)" should set the property value + Colors do not match.\nActual: color(srgb 0.5 0.2 0.8 / 0.2)\nExpected: color(srgb 0.5 0.2 0.8).\nError: assert_array_approx_equals: Numeric parameters are approximately equal. lengths differ, expected 3 got 4 +[FAIL] e.style['color'] = "hwb(from rebeccapurple h alpha alpha / alpha)" should set the property value + Colors do not match.\nActual: color(srgb 0.5 0.5 0.5)\nExpected: color(srgb 0.5 0.01 0.99).\nError: assert_array_approx_equals: Numeric parameters are approximately equal. property 1, expected 0.01 +/- 0.01, expected 0.01 but got 0.5 +[FAIL] e.style['color'] = "hwb(from rgb(20%, 40%, 60%, 80%) h alpha w / b)" should set the property value + Colors do not match.\nActual: color(srgb 0.8 0.8 0.8 / 0.4)\nExpected: color(srgb 0.01 0.404 0.8).\nError: assert_array_approx_equals: Numeric parameters are approximately equal. lengths differ, expected 3 got 4 +[FAIL] e.style['color'] = "hwb(from rgb(20%, 40%, 60%, 80%) h w w / w)" should set the property value + Colors do not match.\nActual: color(srgb 0.2 0.5 0.8 / 0.2)\nExpected: color(srgb 0.2 0.5 0.8).\nError: assert_array_approx_equals: Numeric parameters are approximately equal. lengths differ, expected 3 got 4 +[FAIL] e.style['color'] = "hwb(from rgb(20%, 40%, 60%, 80%) h alpha alpha / alpha)" should set the property value + Colors do not match.\nActual: color(srgb 0.5 0.5 0.5 / 0.8)\nExpected: color(srgb 0.01 0.5 0.99 / 0.8).\nError: assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 0.01 +/- 0.01, expected 0.01 but got 0.5 [FAIL] e.style['color'] = "hwb(from currentColor h w b)" should set the property value assert_not_equals: property should be set got disallowed value "" [FAIL] e.style['color'] = "hwb(from color-mix(in srgb, red, red) h w b / alpha)" should set the property value @@ -66,8 +302,6 @@ assert_not_equals: property should be set got disallowed value "" [FAIL] e.style['color'] = "lab(from color-mix(in lab, lab(25 20 50), lab(25 20 50)) l a b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -[FAIL] e.style['color'] = "oklab(from oklab(0.7 0.25 -0.15) l calc(a / 2) calc(b / 3))" should set the property value - Colors do not match.\nActual: oklab(0.7 0.125 -0.05)\nExpected: oklab(0.7 0.125 -0.075).\nError: assert_array_approx_equals: Numeric parameters are approximately equal. property 2, expected -0.075 +/- 0.01, expected -0.075 but got -0.05 [FAIL] e.style['color'] = "oklab(from currentColor l a b)" should set the property value assert_not_equals: property should be set got disallowed value "" [FAIL] e.style['color'] = "oklab(from color-mix(in oklab, oklab(0.25 0.2 0.5), oklab(0.25 0.2 0.5)) l a b / alpha)" should set the property value
diff --git a/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-valid-relative-color.html b/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-valid-relative-color.html index 5f83f0f..5c351bc 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-valid-relative-color.html +++ b/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-valid-relative-color.html
@@ -24,185 +24,189 @@ <body> <script> // rgb(from ...) + for (const rgbFunction of ["rgb", "rgba"]) { - // Testing no modifications. - fuzzy_test_valid_color(`rgb(from rebeccapurple r g b)`, `color(srgb 0.4 0.2 0.6)`); - fuzzy_test_valid_color(`rgb(from rebeccapurple r g b / alpha)`, `color(srgb 0.4 0.2 0.6)`); - fuzzy_test_valid_color(`rgb(from rgb(20%, 40%, 60%, 80%) r g b / alpha)`, `color(srgb 0.2 0.4 0.6 / 0.8)`); - fuzzy_test_valid_color(`rgb(from hsl(120deg 20% 50% / .5) r g b / alpha)`, `color(srgb 0.4 0.6 0.4 / 0.5)`); + // Testing no modifications. + fuzzy_test_valid_color(`${rgbFunction}(from rebeccapurple r g b)`, `color(srgb 0.4 0.2 0.6)`); + fuzzy_test_valid_color(`${rgbFunction}(from rebeccapurple r g b / alpha)`, `color(srgb 0.4 0.2 0.6)`); + fuzzy_test_valid_color(`${rgbFunction}(from rgb(20%, 40%, 60%, 80%) r g b / alpha)`, `color(srgb 0.2 0.4 0.6 / 0.8)`); + fuzzy_test_valid_color(`${rgbFunction}(from hsl(120deg 20% 50% / .5) r g b / alpha)`, `color(srgb 0.4 0.6 0.4 / 0.5)`); - // Test nesting relative colors. - fuzzy_test_valid_color(`rgb(from rgb(from rebeccapurple r g b) r g b)`, `color(srgb 0.4 0.2 0.6)`); + // Test nesting relative colors. + fuzzy_test_valid_color(`${rgbFunction}(from rgb(from rebeccapurple r g b) r g b)`, `color(srgb 0.4 0.2 0.6)`); - // Testing replacement with 0. - fuzzy_test_valid_color(`rgb(from rebeccapurple 0 0 0)`, `color(srgb 0 0 0)`); - fuzzy_test_valid_color(`rgb(from rebeccapurple 0 0 0 / 0)`, `color(srgb 0 0 0 / 0)`); - fuzzy_test_valid_color(`rgb(from rebeccapurple 0 g b / alpha)`, `color(srgb 0 0.2 0.6)`); - fuzzy_test_valid_color(`rgb(from rebeccapurple r 0 b / alpha)`, `color(srgb 0.4 0 0.6)`); - fuzzy_test_valid_color(`rgb(from rebeccapurple r g 0 / alpha)`, `color(srgb 0.4 0.2 0)`); - fuzzy_test_valid_color(`rgb(from rebeccapurple r g b / 0)`, `color(srgb 0.4 0.2 0.6 / 0)`); - fuzzy_test_valid_color(`rgb(from rgb(20%, 40%, 60%, 80%) 0 g b / alpha)`, `color(srgb 0 0.4 0.6 / 0.8)`); - fuzzy_test_valid_color(`rgb(from rgb(20%, 40%, 60%, 80%) r 0 b / alpha)`, `color(srgb 0.2 0 0.6 / 0.8)`); - fuzzy_test_valid_color(`rgb(from rgb(20%, 40%, 60%, 80%) r g 0 / alpha)`, `color(srgb 0.2 0.4 0 / 0.8)`); - fuzzy_test_valid_color(`rgb(from rgb(20%, 40%, 60%, 80%) r g b / 0)`, `color(srgb 0.2 0.4 0.6 / 0)`); + // Testing replacement with 0. + fuzzy_test_valid_color(`${rgbFunction}(from rebeccapurple 0 0 0)`, `color(srgb 0 0 0)`); + fuzzy_test_valid_color(`${rgbFunction}(from rebeccapurple 0 0 0 / 0)`, `color(srgb 0 0 0 / 0)`); + fuzzy_test_valid_color(`${rgbFunction}(from rebeccapurple 0 g b / alpha)`, `color(srgb 0 0.2 0.6)`); + fuzzy_test_valid_color(`${rgbFunction}(from rebeccapurple r 0 b / alpha)`, `color(srgb 0.4 0 0.6)`); + fuzzy_test_valid_color(`${rgbFunction}(from rebeccapurple r g 0 / alpha)`, `color(srgb 0.4 0.2 0)`); + fuzzy_test_valid_color(`${rgbFunction}(from rebeccapurple r g b / 0)`, `color(srgb 0.4 0.2 0.6 / 0)`); + fuzzy_test_valid_color(`${rgbFunction}(from rgb(20%, 40%, 60%, 80%) 0 g b / alpha)`, `color(srgb 0 0.4 0.6 / 0.8)`); + fuzzy_test_valid_color(`${rgbFunction}(from rgb(20%, 40%, 60%, 80%) r 0 b / alpha)`, `color(srgb 0.2 0 0.6 / 0.8)`); + fuzzy_test_valid_color(`${rgbFunction}(from rgb(20%, 40%, 60%, 80%) r g 0 / alpha)`, `color(srgb 0.2 0.4 0 / 0.8)`); + fuzzy_test_valid_color(`${rgbFunction}(from rgb(20%, 40%, 60%, 80%) r g b / 0)`, `color(srgb 0.2 0.4 0.6 / 0)`); - // Testing replacement with a number. - fuzzy_test_valid_color(`rgb(from rebeccapurple 25 g b / alpha)`, `color(srgb 0.098 0.2 0.6)`); - fuzzy_test_valid_color(`rgb(from rebeccapurple r 25 b / alpha)`, `color(srgb 0.4 0.098 0.6)`); - fuzzy_test_valid_color(`rgb(from rebeccapurple r g 25 / alpha)`, `color(srgb 0.4 0.2 0.098)`); - fuzzy_test_valid_color(`rgb(from rebeccapurple r g b / .25)`, `color(srgb 0.4 0.2 0.6 / 0.25)`); - fuzzy_test_valid_color(`rgb(from rgb(20%, 40%, 60%, 80%) 25 g b / alpha)`, `color(srgb 0.098 0.4 0.6 / 0.8)`); - fuzzy_test_valid_color(`rgb(from rgb(20%, 40%, 60%, 80%) r 25 b / alpha)`, `color(srgb 0.2 0.098 0.6 / 0.8)`); - fuzzy_test_valid_color(`rgb(from rgb(20%, 40%, 60%, 80%) r g 25 / alpha)`, `color(srgb 0.2 0.4 0.098 / 0.8)`); - fuzzy_test_valid_color(`rgb(from rgb(20%, 40%, 60%, 80%) r g b / .20)`, `color(srgb 0.2 0.4 0.6 / 0.2)`); + // Testing replacement with a number. + fuzzy_test_valid_color(`${rgbFunction}(from rebeccapurple 25 g b / alpha)`, `color(srgb 0.098 0.2 0.6)`); + fuzzy_test_valid_color(`${rgbFunction}(from rebeccapurple r 25 b / alpha)`, `color(srgb 0.4 0.098 0.6)`); + fuzzy_test_valid_color(`${rgbFunction}(from rebeccapurple r g 25 / alpha)`, `color(srgb 0.4 0.2 0.098)`); + fuzzy_test_valid_color(`${rgbFunction}(from rebeccapurple r g b / .25)`, `color(srgb 0.4 0.2 0.6 / 0.25)`); + fuzzy_test_valid_color(`${rgbFunction}(from rgb(20%, 40%, 60%, 80%) 25 g b / alpha)`, `color(srgb 0.098 0.4 0.6 / 0.8)`); + fuzzy_test_valid_color(`${rgbFunction}(from rgb(20%, 40%, 60%, 80%) r 25 b / alpha)`, `color(srgb 0.2 0.098 0.6 / 0.8)`); + fuzzy_test_valid_color(`${rgbFunction}(from rgb(20%, 40%, 60%, 80%) r g 25 / alpha)`, `color(srgb 0.2 0.4 0.098 / 0.8)`); + fuzzy_test_valid_color(`${rgbFunction}(from rgb(20%, 40%, 60%, 80%) r g b / .20)`, `color(srgb 0.2 0.4 0.6 / 0.2)`); - // Testing replacement with a percentage. - fuzzy_test_valid_color(`rgb(from rebeccapurple 20% g b / alpha)`, `color(srgb 0.2 0.2 0.6)`); - fuzzy_test_valid_color(`rgb(from rebeccapurple r 20% b / alpha)`, `color(srgb 0.4 0.2 0.6)`); - fuzzy_test_valid_color(`rgb(from rebeccapurple r g 20% / alpha)`, `color(srgb 0.4 0.2 0.2)`); - fuzzy_test_valid_color(`rgb(from rebeccapurple r g b / 20%)`, `color(srgb 0.4 0.2 0.6 / 0.2)`); - fuzzy_test_valid_color(`rgb(from rgb(20%, 40%, 60%, 80%) 20% g b / alpha)`, `color(srgb 0.2 0.4 0.6 / 0.8)`); - fuzzy_test_valid_color(`rgb(from rgb(20%, 40%, 60%, 80%) r 20% b / alpha)`, `color(srgb 0.2 0.2 0.6 / 0.8)`); - fuzzy_test_valid_color(`rgb(from rgb(20%, 40%, 60%, 80%) r g 20% / alpha)`, `color(srgb 0.2 0.4 0.2 / 0.8)`); - fuzzy_test_valid_color(`rgb(from rgb(20%, 40%, 60%, 80%) r g b / 20%)`, `color(srgb 0.2 0.4 0.6 / 0.2)`); + // Testing replacement with a percentage. + fuzzy_test_valid_color(`${rgbFunction}(from rebeccapurple 20% g b / alpha)`, `color(srgb 0.2 0.2 0.6)`); + fuzzy_test_valid_color(`${rgbFunction}(from rebeccapurple r 20% b / alpha)`, `color(srgb 0.4 0.2 0.6)`); + fuzzy_test_valid_color(`${rgbFunction}(from rebeccapurple r g 20% / alpha)`, `color(srgb 0.4 0.2 0.2)`); + fuzzy_test_valid_color(`${rgbFunction}(from rebeccapurple r g b / 20%)`, `color(srgb 0.4 0.2 0.6 / 0.2)`); + fuzzy_test_valid_color(`${rgbFunction}(from rgb(20%, 40%, 60%, 80%) 20% g b / alpha)`, `color(srgb 0.2 0.4 0.6 / 0.8)`); + fuzzy_test_valid_color(`${rgbFunction}(from rgb(20%, 40%, 60%, 80%) r 20% b / alpha)`, `color(srgb 0.2 0.2 0.6 / 0.8)`); + fuzzy_test_valid_color(`${rgbFunction}(from rgb(20%, 40%, 60%, 80%) r g 20% / alpha)`, `color(srgb 0.2 0.4 0.2 / 0.8)`); + fuzzy_test_valid_color(`${rgbFunction}(from rgb(20%, 40%, 60%, 80%) r g b / 20%)`, `color(srgb 0.2 0.4 0.6 / 0.2)`); - // Testing replacement with a number for r, g, b but percent for alpha. - fuzzy_test_valid_color(`rgb(from rebeccapurple 25 g b / 25%)`, `color(srgb 0.098 0.2 0.6 / 0.25)`); - fuzzy_test_valid_color(`rgb(from rebeccapurple r 25 b / 25%)`, `color(srgb 0.4 0.098 0.6 / 0.25)`); - fuzzy_test_valid_color(`rgb(from rebeccapurple r g 25 / 25%)`, `color(srgb 0.4 0.2 0.098 / 0.25)`); - fuzzy_test_valid_color(`rgb(from rgb(20%, 40%, 60%, 80%) 25 g b / 25%)`, `color(srgb 0.098 0.4 0.6 / 0.25)`); - fuzzy_test_valid_color(`rgb(from rgb(20%, 40%, 60%, 80%) r 25 b / 25%)`, `color(srgb 0.2 0.098 0.6 / 0.25)`); - fuzzy_test_valid_color(`rgb(from rgb(20%, 40%, 60%, 80%) r g 25 / 25%)`, `color(srgb 0.2 0.4 0.098 / 0.25)`); + // Testing replacement with a number for r, g, b but percent for alpha. + fuzzy_test_valid_color(`${rgbFunction}(from rebeccapurple 25 g b / 25%)`, `color(srgb 0.098 0.2 0.6 / 0.25)`); + fuzzy_test_valid_color(`${rgbFunction}(from rebeccapurple r 25 b / 25%)`, `color(srgb 0.4 0.098 0.6 / 0.25)`); + fuzzy_test_valid_color(`${rgbFunction}(from rebeccapurple r g 25 / 25%)`, `color(srgb 0.4 0.2 0.098 / 0.25)`); + fuzzy_test_valid_color(`${rgbFunction}(from rgb(20%, 40%, 60%, 80%) 25 g b / 25%)`, `color(srgb 0.098 0.4 0.6 / 0.25)`); + fuzzy_test_valid_color(`${rgbFunction}(from rgb(20%, 40%, 60%, 80%) r 25 b / 25%)`, `color(srgb 0.2 0.098 0.6 / 0.25)`); + fuzzy_test_valid_color(`${rgbFunction}(from rgb(20%, 40%, 60%, 80%) r g 25 / 25%)`, `color(srgb 0.2 0.4 0.098 / 0.25)`); - // Testing permutation. - fuzzy_test_valid_color(`rgb(from rebeccapurple g b r)`, `color(srgb 0.2 0.6 0.4)`); - fuzzy_test_valid_color(`rgb(from rebeccapurple b alpha r / g)`, `color(srgb 0.6 1 0.4 / 0.2)`); - fuzzy_test_valid_color(`rgb(from rebeccapurple r r r / r)`, `color(srgb 0.4 0.4 0.4 / 0.4)`); - fuzzy_test_valid_color(`rgb(from rebeccapurple alpha alpha alpha / alpha)`, `color(srgb 1 1 1)`); - fuzzy_test_valid_color(`rgb(from rgb(20%, 40%, 60%, 80%) g b r)`, `color(srgb 0.4 0.6 0.2 / 0.8)`); - fuzzy_test_valid_color(`rgb(from rgb(20%, 40%, 60%, 80%) b alpha r / g)`, `color(srgb 0.6 0.8 0.2 / 0.4)`); - fuzzy_test_valid_color(`rgb(from rgb(20%, 40%, 60%, 80%) r r r / r)`, `color(srgb 0.2 0.2 0.2 / 0.2)`); - fuzzy_test_valid_color(`rgb(from rgb(20%, 40%, 60%, 80%) alpha alpha alpha / alpha)`, `color(srgb 0.8 0.8 0.8 / 0.8)`); + // Testing permutation. + fuzzy_test_valid_color(`${rgbFunction}(from rebeccapurple g b r)`, `color(srgb 0.2 0.6 0.4)`); + fuzzy_test_valid_color(`${rgbFunction}(from rebeccapurple b alpha r / g)`, `color(srgb 0.6 0.004 0.4)`); + fuzzy_test_valid_color(`${rgbFunction}(from rebeccapurple r r r / r)`, `color(srgb 0.4 0.4 0.4)`); + fuzzy_test_valid_color(`${rgbFunction}(from rebeccapurple alpha alpha alpha / alpha)`, `color(srgb 0.004 0.004 0.004)`); + fuzzy_test_valid_color(`${rgbFunction}(from rgb(20%, 40%, 60%, 80%) g b r)`, `color(srgb 0.4 0.6 0.2 / 0.8)`); + fuzzy_test_valid_color(`${rgbFunction}(from rgb(20%, 40%, 60%, 80%) b alpha r / g)`, `color(srgb 0.6 0.003 0.2)`); + fuzzy_test_valid_color(`${rgbFunction}(from rgb(20%, 40%, 60%, 80%) r r r / r)`, `color(srgb 0.2 0.2 0.2)`); + fuzzy_test_valid_color(`${rgbFunction}(from rgb(20%, 40%, 60%, 80%) alpha alpha alpha / alpha)`, `color(srgb 0.003 0.003 0.003 / 0.8)`); - // Testing mixes of number and percentage. (These would not be allowed in the non-relative syntax). - fuzzy_test_valid_color(`rgb(from rebeccapurple r 20% 10)`, `color(srgb 0.4 0.2 0.0392)`); - fuzzy_test_valid_color(`rgb(from rebeccapurple r 10 20%)`, `color(srgb 0.4 0.0392 0.2)`); - fuzzy_test_valid_color(`rgb(from rebeccapurple 0% 10 10)`, `color(srgb 0 0.0392 0.0392)`); - fuzzy_test_valid_color(`rgb(from rgb(20%, 40%, 60%, 80%) r 20% 10)`, `color(srgb 0.2 0.2 0.0392 / 0.8)`); - fuzzy_test_valid_color(`rgb(from rgb(20%, 40%, 60%, 80%) r 10 20%)`, `color(srgb 0.2 0.0392 0.2 / 0.8)`); - fuzzy_test_valid_color(`rgb(from rgb(20%, 40%, 60%, 80%) 0% 10 10)`, `color(srgb 0 0.0392 0.0392 / 0.8)`); + // Testing mixes of number and percentage. (These would not be allowed in the non-relative syntax). + fuzzy_test_valid_color(`${rgbFunction}(from rebeccapurple r 20% 10)`, `color(srgb 0.4 0.2 0.0392)`); + fuzzy_test_valid_color(`${rgbFunction}(from rebeccapurple r 10 20%)`, `color(srgb 0.4 0.0392 0.2)`); + fuzzy_test_valid_color(`${rgbFunction}(from rebeccapurple 0% 10 10)`, `color(srgb 0 0.0392 0.0392)`); + fuzzy_test_valid_color(`${rgbFunction}(from rgb(20%, 40%, 60%, 80%) r 20% 10)`, `color(srgb 0.2 0.2 0.0392 / 0.8)`); + fuzzy_test_valid_color(`${rgbFunction}(from rgb(20%, 40%, 60%, 80%) r 10 20%)`, `color(srgb 0.2 0.0392 0.2 / 0.8)`); + fuzzy_test_valid_color(`${rgbFunction}(from rgb(20%, 40%, 60%, 80%) 0% 10 10)`, `color(srgb 0 0.0392 0.0392 / 0.8)`); - // r g b - // 102 51 153 - // 40% 20% 60% - // Testing with calc(). - fuzzy_test_valid_color(`rgb(from rebeccapurple calc(r) calc(g) calc(b))`, `color(srgb 0.4 0.2 0.6)`); - fuzzy_test_valid_color(`rgb(from rebeccapurple r calc(g * 2) 10)`, `color(srgb 0.4 0.4 0.0392)`); - fuzzy_test_valid_color(`rgb(from rebeccapurple b calc(r * .5) 10)`, `color(srgb 0.6 0.2 0.0392)`); - fuzzy_test_valid_color(`rgb(from rebeccapurple r calc(g * .5 + g * .5) 10)`, `color(srgb 0.4 0.2 0.0392)`); - fuzzy_test_valid_color(`rgb(from rebeccapurple r calc(b * .5 - g * .5) 10)`, `color(srgb 0.4 0.2 0.0392)`); - fuzzy_test_valid_color(`rgb(from rgb(20%, 40%, 60%, 80%) calc(r) calc(g) calc(b) / calc(alpha))`, `color(srgb 0.2 0.4 0.6 / 0.8)`); + // r g b + // 102 51 153 + // 40% 20% 60% + // Testing with calc(). + fuzzy_test_valid_color(`${rgbFunction}(from rebeccapurple calc(r) calc(g) calc(b))`, `color(srgb 0.4 0.2 0.6)`); + fuzzy_test_valid_color(`${rgbFunction}(from rebeccapurple r calc(g * 2) 10)`, `color(srgb 0.4 0.4 0.0392)`); + fuzzy_test_valid_color(`${rgbFunction}(from rebeccapurple b calc(r * .5) 10)`, `color(srgb 0.6 0.2 0.0392)`); + fuzzy_test_valid_color(`${rgbFunction}(from rebeccapurple r calc(g * .5 + g * .5) 10)`, `color(srgb 0.4 0.2 0.0392)`); + fuzzy_test_valid_color(`${rgbFunction}(from rebeccapurple r calc(b * .5 - g * .5) 10)`, `color(srgb 0.4 0.2 0.0392)`); + fuzzy_test_valid_color(`${rgbFunction}(from rgb(20%, 40%, 60%, 80%) calc(r) calc(g) calc(b) / calc(alpha))`, `color(srgb 0.2 0.4 0.6 / 0.8)`); - // Testing with 'none'. - fuzzy_test_valid_color(`rgb(from rebeccapurple none none none)`, `color(srgb none none none)`); - fuzzy_test_valid_color(`rgb(from rebeccapurple none none none / none)`, `color(srgb none none none / none)`); - fuzzy_test_valid_color(`rgb(from rebeccapurple r g none)`, `color(srgb 0.4 0.2 none)`); - fuzzy_test_valid_color(`rgb(from rebeccapurple r g none / alpha)`, `color(srgb 0.4 0.2 none)`); - fuzzy_test_valid_color(`rgb(from rebeccapurple r g b / none)`, `color(srgb 0.4 0.2 0.6 / none)`); - fuzzy_test_valid_color(`rgb(from rgb(20% 40% 60% / 80%) r g none / alpha)`, `color(srgb 0.2 0.4 none / 0.8)`); - fuzzy_test_valid_color(`rgb(from rgb(20% 40% 60% / 80%) r g b / none)`, `color(srgb 0.2 0.4 0.6 / none)`); - // FIXME: Clarify with spec editors if 'none' should pass through to the constants. - fuzzy_test_valid_color(`rgb(from rgb(none none none) r g b)`, `color(srgb 0 0 0)`); - fuzzy_test_valid_color(`rgb(from rgb(none none none / none) r g b / alpha)`, `color(srgb 0 0 0 / 0)`); - fuzzy_test_valid_color(`rgb(from rgb(20% none 60%) r g b)`, `color(srgb 0.2 0 0.6)`); - fuzzy_test_valid_color(`rgb(from rgb(20% 40% 60% / none) r g b / alpha)`, `color(srgb 0.2 0.4 0.6 / 0)`); + // Testing with 'none'. + fuzzy_test_valid_color(`${rgbFunction}(from rebeccapurple none none none)`, `color(srgb none none none)`); + fuzzy_test_valid_color(`${rgbFunction}(from rebeccapurple none none none / none)`, `color(srgb none none none / none)`); + fuzzy_test_valid_color(`${rgbFunction}(from rebeccapurple r g none)`, `color(srgb 0.4 0.2 none)`); + fuzzy_test_valid_color(`${rgbFunction}(from rebeccapurple r g none / alpha)`, `color(srgb 0.4 0.2 none)`); + fuzzy_test_valid_color(`${rgbFunction}(from rebeccapurple r g b / none)`, `color(srgb 0.4 0.2 0.6 / none)`); + fuzzy_test_valid_color(`${rgbFunction}(from rgb(20% 40% 60% / 80%) r g none / alpha)`, `color(srgb 0.2 0.4 none / 0.8)`); + fuzzy_test_valid_color(`${rgbFunction}(from rgb(20% 40% 60% / 80%) r g b / none)`, `color(srgb 0.2 0.4 0.6 / none)`); + // FIXME: Clarify with spec editors if 'none' should pass through to the constants. + fuzzy_test_valid_color(`${rgbFunction}(from rgb(none none none) r g b)`, `color(srgb 0 0 0)`); + fuzzy_test_valid_color(`${rgbFunction}(from rgb(none none none / none) r g b / alpha)`, `color(srgb 0 0 0 / 0)`); + fuzzy_test_valid_color(`${rgbFunction}(from rgb(20% none 60%) r g b)`, `color(srgb 0.2 0 0.6)`); + fuzzy_test_valid_color(`${rgbFunction}(from rgb(20% 40% 60% / none) r g b / alpha)`, `color(srgb 0.2 0.4 0.6 / 0)`); - // Testing with 'currentColor' - fuzzy_test_valid_color(`rgb(from currentColor r g b)`, `rgb(from currentColor r g b)`); + // Testing with 'currentColor' + fuzzy_test_valid_color(`${rgbFunction}(from currentColor r g b)`, `rgb(from currentColor r g b)`); - // color-mix - fuzzy_test_valid_color(`rgb(from color-mix(in srgb, red, red) r g b / alpha)`, `color(srgb 1 0 0)`); + // color-mix + fuzzy_test_valid_color(`${rgbFunction}(from color-mix(in srgb, red, red) r g b / alpha)`, `color(srgb 1 0 0)`); + } // hsl(from ...) + for (const hslFunction of ["hsl", "hsla"]) { - // Testing no modifications. - fuzzy_test_valid_color(`hsl(from rebeccapurple h s l)`, `color(srgb 0.4 0.2 0.6)`); - fuzzy_test_valid_color(`hsl(from rebeccapurple h s l / alpha)`, `color(srgb 0.4 0.2 0.6)`); - fuzzy_test_valid_color(`hsl(from rgb(20%, 40%, 60%, 80%) h s l / alpha)`, `color(srgb 0.2 0.4 0.6 / 0.8)`); - fuzzy_test_valid_color(`hsl(from hsl(120deg 20% 50% / .5) h s l / alpha)`, `color(srgb 0.4 0.6 0.4 / 0.5)`); + // Testing no modifications. + fuzzy_test_valid_color(`${hslFunction}(from rebeccapurple h s l)`, `color(srgb 0.4 0.2 0.6)`); + fuzzy_test_valid_color(`${hslFunction}(from rebeccapurple h s l / alpha)`, `color(srgb 0.4 0.2 0.6)`); + fuzzy_test_valid_color(`${hslFunction}(from rgb(20%, 40%, 60%, 80%) h s l / alpha)`, `color(srgb 0.2 0.4 0.6 / 0.8)`); + fuzzy_test_valid_color(`${hslFunction}(from hsl(120deg 20% 50% / .5) h s l / alpha)`, `color(srgb 0.4 0.6 0.4 / 0.5)`); - // Test nesting relative colors. - fuzzy_test_valid_color(`hsl(from hsl(from rebeccapurple h s l) h s l)`, `color(srgb 0.4 0.2 0.6)`); + // Test nesting relative colors. + fuzzy_test_valid_color(`${hslFunction}(from hsl(from rebeccapurple h s l) h s l)`, `color(srgb 0.4 0.2 0.6)`); - // Testing replacement with 0. - fuzzy_test_valid_color(`hsl(from rebeccapurple 0 0% 0%)`, `color(srgb 0 0 0)`); - fuzzy_test_valid_color(`hsl(from rebeccapurple 0deg 0% 0%)`, `color(srgb 0 0 0)`); - fuzzy_test_valid_color(`hsl(from rebeccapurple 0 0% 0% / 0)`, `color(srgb 0 0 0 / 0)`); - fuzzy_test_valid_color(`hsl(from rebeccapurple 0deg 0% 0% / 0)`, `color(srgb 0 0 0 / 0)`); - fuzzy_test_valid_color(`hsl(from rebeccapurple 0 s l / alpha)`, `color(srgb 0.6 0.2 0.2)`); - fuzzy_test_valid_color(`hsl(from rebeccapurple 0deg s l / alpha)`, `color(srgb 0.6 0.2 0.2)`); - fuzzy_test_valid_color(`hsl(from rebeccapurple h 0% l / alpha)`, `color(srgb 0.4 0.4 0.4)`); - fuzzy_test_valid_color(`hsl(from rebeccapurple h s 0% / alpha)`, `color(srgb 0 0 0)`); - fuzzy_test_valid_color(`hsl(from rebeccapurple h s l / 0)`, `color(srgb 0.4 0.2 0.6 / 0)`); - fuzzy_test_valid_color(`hsl(from rgb(20%, 40%, 60%, 80%) 0 s l / alpha)`, `color(srgb 0.6 0.2 0.2 / 0.8)`); - fuzzy_test_valid_color(`hsl(from rgb(20%, 40%, 60%, 80%) 0deg s l / alpha)`, `color(srgb 0.6 0.2 0.2 / 0.8)`); - fuzzy_test_valid_color(`hsl(from rgb(20%, 40%, 60%, 80%) h 0% l / alpha)`, `color(srgb 0.4 0.4 0.4 / 0.8)`); - fuzzy_test_valid_color(`hsl(from rgb(20%, 40%, 60%, 80%) h s 0% / alpha)`, `color(srgb 0 0 0 / 0.8)`); - fuzzy_test_valid_color(`hsl(from rgb(20%, 40%, 60%, 80%) h s l / 0)`, `color(srgb 0.2 0.4 0.6 / 0)`); + // Testing replacement with 0. + fuzzy_test_valid_color(`${hslFunction}(from rebeccapurple 0 0% 0%)`, `color(srgb 0 0 0)`); + fuzzy_test_valid_color(`${hslFunction}(from rebeccapurple 0deg 0% 0%)`, `color(srgb 0 0 0)`); + fuzzy_test_valid_color(`${hslFunction}(from rebeccapurple 0 0% 0% / 0)`, `color(srgb 0 0 0 / 0)`); + fuzzy_test_valid_color(`${hslFunction}(from rebeccapurple 0deg 0% 0% / 0)`, `color(srgb 0 0 0 / 0)`); + fuzzy_test_valid_color(`${hslFunction}(from rebeccapurple 0 s l / alpha)`, `color(srgb 0.6 0.2 0.2)`); + fuzzy_test_valid_color(`${hslFunction}(from rebeccapurple 0deg s l / alpha)`, `color(srgb 0.6 0.2 0.2)`); + fuzzy_test_valid_color(`${hslFunction}(from rebeccapurple h 0% l / alpha)`, `color(srgb 0.4 0.4 0.4)`); + fuzzy_test_valid_color(`${hslFunction}(from rebeccapurple h s 0% / alpha)`, `color(srgb 0 0 0)`); + fuzzy_test_valid_color(`${hslFunction}(from rebeccapurple h s l / 0)`, `color(srgb 0.4 0.2 0.6 / 0)`); + fuzzy_test_valid_color(`${hslFunction}(from rgb(20%, 40%, 60%, 80%) 0 s l / alpha)`, `color(srgb 0.6 0.2 0.2 / 0.8)`); + fuzzy_test_valid_color(`${hslFunction}(from rgb(20%, 40%, 60%, 80%) 0deg s l / alpha)`, `color(srgb 0.6 0.2 0.2 / 0.8)`); + fuzzy_test_valid_color(`${hslFunction}(from rgb(20%, 40%, 60%, 80%) h 0% l / alpha)`, `color(srgb 0.4 0.4 0.4 / 0.8)`); + fuzzy_test_valid_color(`${hslFunction}(from rgb(20%, 40%, 60%, 80%) h s 0% / alpha)`, `color(srgb 0 0 0 / 0.8)`); + fuzzy_test_valid_color(`${hslFunction}(from rgb(20%, 40%, 60%, 80%) h s l / 0)`, `color(srgb 0.2 0.4 0.6 / 0)`); - fuzzy_test_valid_color(`hsl(from rebeccapurple 25 s l / alpha)`, `color(srgb 0.6 0.3667 0.2)`); - fuzzy_test_valid_color(`hsl(from rebeccapurple 25deg s l / alpha)`, `color(srgb 0.6 0.3667 0.2)`); - fuzzy_test_valid_color(`hsl(from rebeccapurple h 20% l / alpha)`, `color(srgb 0.4 0.32 0.48)`); - // hsl(from rebeccapurple h s 20% / alpha) is equivalent to color(srgb 0.2 0.1 0.3). - // For the green channel: 0.1 * 255 = 25.5. This should get rounded towards infinity to 26. - // https://www.w3.org/TR/css-color-4/#rgb-functions - fuzzy_test_valid_color(`hsl(from rebeccapurple h s 20% / alpha)`, `color(srgb 0.2 0.1 0.3)`); - fuzzy_test_valid_color(`hsl(from rebeccapurple h s l / .25)`, `color(srgb 0.4 0.2 0.6 / 0.25)`); - fuzzy_test_valid_color(`hsl(from rgb(20%, 40%, 60%, 80%) 25 s l / alpha)`, `color(srgb 0.6 0.3667 0.2 / 0.8)`); - fuzzy_test_valid_color(`hsl(from rgb(20%, 40%, 60%, 80%) 25deg s l / alpha)`, `color(srgb 0.6 0.3667 0.2 / 0.8)`); - fuzzy_test_valid_color(`hsl(from rgb(20%, 40%, 60%, 80%) h 20% l / alpha)`, `color(srgb 0.32 0.4 0.48 / 0.8)`); - // hsl(from rgb(20%, 40%, 60%, 80%) h s 20% / alpha) is equivalent to color(srgb 0.1 0.2 0.3). - // For the red channel: 0.1 * 255 = 25.5. This should get rounded towards infinity to 26. - // https://www.w3.org/TR/css-color-4/#rgb-functions - fuzzy_test_valid_color(`hsl(from rgb(20%, 40%, 60%, 80%) h s 20% / alpha)`, `color(srgb 0.1 0.2 0.3 / 0.8)`); - fuzzy_test_valid_color(`hsl(from rgb(20%, 40%, 60%, 80%) h s l / .2)`, `color(srgb 0.2 0.4 0.6 / 0.2)`); + fuzzy_test_valid_color(`${hslFunction}(from rebeccapurple 25 s l / alpha)`, `color(srgb 0.6 0.3667 0.2)`); + fuzzy_test_valid_color(`${hslFunction}(from rebeccapurple 25deg s l / alpha)`, `color(srgb 0.6 0.3667 0.2)`); + fuzzy_test_valid_color(`${hslFunction}(from rebeccapurple h 20% l / alpha)`, `color(srgb 0.4 0.32 0.48)`); + // hsl(from rebeccapurple h s 20% / alpha) is equivalent to color(srgb 0.2 0.1 0.3). + // For the green channel: 0.1 * 255 = 25.5. This should get rounded towards infinity to 26. + // https://www.w3.org/TR/css-color-4/#rgb-functions + fuzzy_test_valid_color(`${hslFunction}(from rebeccapurple h s 20% / alpha)`, `color(srgb 0.2 0.1 0.3)`); + fuzzy_test_valid_color(`${hslFunction}(from rebeccapurple h s l / .25)`, `color(srgb 0.4 0.2 0.6 / 0.25)`); + fuzzy_test_valid_color(`${hslFunction}(from rgb(20%, 40%, 60%, 80%) 25 s l / alpha)`, `color(srgb 0.6 0.3667 0.2 / 0.8)`); + fuzzy_test_valid_color(`${hslFunction}(from rgb(20%, 40%, 60%, 80%) 25deg s l / alpha)`, `color(srgb 0.6 0.3667 0.2 / 0.8)`); + fuzzy_test_valid_color(`${hslFunction}(from rgb(20%, 40%, 60%, 80%) h 20% l / alpha)`, `color(srgb 0.32 0.4 0.48 / 0.8)`); + // hsl(from rgb(20%, 40%, 60%, 80%) h s 20% / alpha) is equivalent to color(srgb 0.1 0.2 0.3). + // For the red channel: 0.1 * 255 = 25.5. This should get rounded towards infinity to 26. + // https://www.w3.org/TR/css-color-4/#rgb-functions + fuzzy_test_valid_color(`${hslFunction}(from rgb(20%, 40%, 60%, 80%) h s 20% / alpha)`, `color(srgb 0.1 0.2 0.3 / 0.8)`); + fuzzy_test_valid_color(`${hslFunction}(from rgb(20%, 40%, 60%, 80%) h s l / .2)`, `color(srgb 0.2 0.4 0.6 / 0.2)`); - // Testing valid permutation (types match). - fuzzy_test_valid_color(`hsl(from rebeccapurple h l s)`, `color(srgb 0.5 0.3 0.7)`); - fuzzy_test_valid_color(`hsl(from rebeccapurple h alpha l / s)`, `color(srgb 0.4 0 0.8 / 0.5)`); - fuzzy_test_valid_color(`hsl(from rebeccapurple h l l / l)`, `color(srgb 0.4 0.24 0.56 / 0.4)`); - fuzzy_test_valid_color(`hsl(from rebeccapurple h alpha alpha / alpha)`, `color(srgb 1 1 1)`); - fuzzy_test_valid_color(`hsl(from rgb(20%, 40%, 60%, 80%) h l s)`, `color(srgb 0.3 0.5 0.7 / 0.8)`); - fuzzy_test_valid_color(`hsl(from rgb(20%, 40%, 60%, 80%) h alpha l / s)`, `color(srgb 0.08 0.4 0.72 / 0.5)`); - fuzzy_test_valid_color(`hsl(from rgb(20%, 40%, 60%, 80%) h l l / l)`, `color(srgb 0.24 0.4 0.56 / 0.4)`); - fuzzy_test_valid_color(`hsl(from rgb(20%, 40%, 60%, 80%) h alpha alpha / alpha)`, `color(srgb 0.64 0.8 0.96 / 0.8)`); + // Testing valid permutation (types match). + fuzzy_test_valid_color(`${hslFunction}(from rebeccapurple h l s)`, `color(srgb 0.5 0.3 0.7)`); + fuzzy_test_valid_color(`${hslFunction}(from rebeccapurple h alpha l / s)`, `color(srgb 0.4 0.396 0.404)`); + fuzzy_test_valid_color(`${hslFunction}(from rebeccapurple h l l / l)`, `color(srgb 0.4 0.24 0.56)`); + fuzzy_test_valid_color(`${hslFunction}(from rebeccapurple h alpha alpha / alpha)`, `color(srgb 0.01 0.01 0.01)`); + fuzzy_test_valid_color(`${hslFunction}(from rgb(20%, 40%, 60%, 80%) h l s)`, `color(srgb 0.3 0.5 0.7 / 0.8)`); + fuzzy_test_valid_color(`${hslFunction}(from rgb(20%, 40%, 60%, 80%) h alpha l / s)`, `color(srgb 0.4 0.4 0.4)`); + fuzzy_test_valid_color(`${hslFunction}(from rgb(20%, 40%, 60%, 80%) h l l / l)`, `color(srgb 0.24 0.4 0.56)`); + fuzzy_test_valid_color(`${hslFunction}(from rgb(20%, 40%, 60%, 80%) h alpha alpha / alpha)`, `color(srgb 0.01 0.01 0.01 / 0.8)`); - // Testing with calc(). - fuzzy_test_valid_color(`hsl(from rebeccapurple calc(h) calc(s) calc(l))`, `color(srgb 0.4 0.2 0.6)`); - fuzzy_test_valid_color(`hsl(from rgb(20%, 40%, 60%, 80%) calc(h) calc(s) calc(l) / calc(alpha))`, `color(srgb 0.2 0.4 0.6 / 0.8)`); + // Testing with calc(). + fuzzy_test_valid_color(`${hslFunction}(from rebeccapurple calc(h) calc(s) calc(l))`, `color(srgb 0.4 0.2 0.6)`); + fuzzy_test_valid_color(`${hslFunction}(from rgb(20%, 40%, 60%, 80%) calc(h) calc(s) calc(l) / calc(alpha))`, `color(srgb 0.2 0.4 0.6 / 0.8)`); - // Testing with 'none'. - fuzzy_test_valid_color(`hsl(from rebeccapurple none none none)`, `color(srgb none none none)`); - fuzzy_test_valid_color(`hsl(from rebeccapurple none none none / none)`, `color(srgb none none none / none)`); - fuzzy_test_valid_color(`hsl(from rebeccapurple h s none)`, `color(srgb 0 0 none)`); - fuzzy_test_valid_color(`hsl(from rebeccapurple h s none / alpha)`, `color(srgb 0 0 none)`); - fuzzy_test_valid_color(`hsl(from rebeccapurple h s l / none)`, `color(srgb 0.4 0.2 0.6 / none)`); - fuzzy_test_valid_color(`hsl(from rebeccapurple none s l / alpha)`, `color(srgb none 0.2 0.2)`); - fuzzy_test_valid_color(`hsl(from hsl(120deg 20% 50% / .5) h s none / alpha)`, `color(srgb 0 0 none / 0.5)`); - fuzzy_test_valid_color(`hsl(from hsl(120deg 20% 50% / .5) h s l / none)`, `color(srgb 0.4 0.6 0.4 / none)`); - fuzzy_test_valid_color(`hsl(from hsl(120deg 20% 50% / .5) none s l / alpha)`, `color(srgb none 0.4 0.4 / 0.5)`); - // FIXME: Clarify with spec editors if 'none' should pass through to the constants. - fuzzy_test_valid_color(`hsl(from hsl(none none none) h s l)`, `color(srgb 0 0 0)`); - fuzzy_test_valid_color(`hsl(from hsl(none none none / none) h s l / alpha)`, `color(srgb 0 0 0 / 0)`); - fuzzy_test_valid_color(`hsl(from hsl(120deg none 50% / .5) h s l)`, `color(srgb 0.5 0.5 0.5 / 0.5)`); - fuzzy_test_valid_color(`hsl(from hsl(120deg 20% 50% / none) h s l / alpha)`, `color(srgb 0.4 0.6 0.4 / 0)`); - fuzzy_test_valid_color(`hsl(from hsl(none 20% 50% / .5) h s l / alpha)`, `color(srgb 0.6 0.4 0.4 / 0.5)`); + // Testing with 'none'. + fuzzy_test_valid_color(`${hslFunction}(from rebeccapurple none none none)`, `color(srgb 0 0 0)`); + fuzzy_test_valid_color(`${hslFunction}(from rebeccapurple none none none / none)`, `color(srgb 0 0 0 / 0)`); + fuzzy_test_valid_color(`${hslFunction}(from rebeccapurple h s none)`, `color(srgb 0 0 0)`); + fuzzy_test_valid_color(`${hslFunction}(from rebeccapurple h s none / alpha)`, `color(srgb 0 0 0)`); + fuzzy_test_valid_color(`${hslFunction}(from rebeccapurple h s l / none)`, `color(srgb 0.4 0.2 0.6 / none)`); + fuzzy_test_valid_color(`${hslFunction}(from rebeccapurple none s l / alpha)`, `color(srgb 0.6 0.2 0.2)`); + fuzzy_test_valid_color(`${hslFunction}(from hsl(120deg 20% 50% / .5) h s none / alpha)`, `color(srgb 0 0 0 / 0.5)`); + fuzzy_test_valid_color(`${hslFunction}(from hsl(120deg 20% 50% / .5) h s l / none)`, `color(srgb 0.4 0.6 0.4 / none)`); + fuzzy_test_valid_color(`${hslFunction}(from hsl(120deg 20% 50% / .5) none s l / alpha)`, `color(srgb 0.6 0.4 0.4 / 0.5)`); + // FIXME: Clarify with spec editors if 'none' should pass through to the constants. + fuzzy_test_valid_color(`${hslFunction}(from hsl(none none none) h s l)`, `color(srgb 0 0 0)`); + fuzzy_test_valid_color(`${hslFunction}(from hsl(none none none / none) h s l / alpha)`, `color(srgb 0 0 0 / 0)`); + fuzzy_test_valid_color(`${hslFunction}(from hsl(120deg none 50% / .5) h s l)`, `color(srgb 0.5 0.5 0.5 / 0.5)`); + fuzzy_test_valid_color(`${hslFunction}(from hsl(120deg 20% 50% / none) h s l / alpha)`, `color(srgb 0.4 0.6 0.4 / 0)`); + fuzzy_test_valid_color(`${hslFunction}(from hsl(none 20% 50% / .5) h s l / alpha)`, `color(srgb 0.6 0.4 0.4 / 0.5)`); - // Testing with 'currentColor' - fuzzy_test_valid_color(`hsl(from currentColor h s l)`, `hsl(from currentColor h s l)`); + // Testing with 'currentColor' + fuzzy_test_valid_color(`${hslFunction}(from currentColor h s l)`, `hsl(from currentColor h s l)`); - // color-mix - fuzzy_test_valid_color(`hsl(from color-mix(in srgb, red, red) h s l / alpha)`, `color(srgb 1 0 0)`); + // color-mix + fuzzy_test_valid_color(`${hslFunction}(from color-mix(in srgb, red, red) h s l / alpha)`, `color(srgb 1 0 0)`); + } // hwb(from ...) @@ -245,28 +249,28 @@ // Testing valid permutation (types match). fuzzy_test_valid_color(`hwb(from rebeccapurple h b w)`, `color(srgb 0.6 0.4 0.8)`); - fuzzy_test_valid_color(`hwb(from rebeccapurple h alpha w / b)`, `color(srgb 0.8333 0.8333 0.8333 / 0.4)`); - fuzzy_test_valid_color(`hwb(from rebeccapurple h w w / w)`, `color(srgb 0.5 0.2 0.8 / 0.2)`); - fuzzy_test_valid_color(`hwb(from rebeccapurple h alpha alpha / alpha)`, `color(srgb 0.5 0.5 0.5)`); + fuzzy_test_valid_color(`hwb(from rebeccapurple h alpha w / b)`, `color(srgb 0.405 0.01 0.8 / 1)`); + fuzzy_test_valid_color(`hwb(from rebeccapurple h w w / w)`, `color(srgb 0.5 0.2 0.8)`); + fuzzy_test_valid_color(`hwb(from rebeccapurple h alpha alpha / alpha)`, `color(srgb 0.5 0.01 0.99)`); fuzzy_test_valid_color(`hwb(from rgb(20%, 40%, 60%, 80%) h b w)`, `color(srgb 0.4 0.6 0.8 / 0.8)`); - fuzzy_test_valid_color(`hwb(from rgb(20%, 40%, 60%, 80%) h alpha w / b)`, `color(srgb 0.8 0.8 0.8 / 0.4)`); - fuzzy_test_valid_color(`hwb(from rgb(20%, 40%, 60%, 80%) h w w / w)`, `color(srgb 0.2 0.5 0.8 / 0.2)`); - fuzzy_test_valid_color(`hwb(from rgb(20%, 40%, 60%, 80%) h alpha alpha / alpha)`, `color(srgb 0.5 0.5 0.5 / 0.8)`); + fuzzy_test_valid_color(`hwb(from rgb(20%, 40%, 60%, 80%) h alpha w / b)`, `color(srgb 0.01 0.404 0.8)`); + fuzzy_test_valid_color(`hwb(from rgb(20%, 40%, 60%, 80%) h w w / w)`, `color(srgb 0.2 0.5 0.8)`); + fuzzy_test_valid_color(`hwb(from rgb(20%, 40%, 60%, 80%) h alpha alpha / alpha)`, `color(srgb 0.01 0.5 0.99 / 0.8)`); // Testing with calc(). fuzzy_test_valid_color(`hwb(from rebeccapurple calc(h) calc(w) calc(b))`, `color(srgb 0.4 0.2 0.6)`); fuzzy_test_valid_color(`hwb(from rgb(20%, 40%, 60%, 80%) calc(h) calc(w) calc(b) / calc(alpha))`, `color(srgb 0.2 0.4 0.6 / 0.8)`); // Testing with 'none'. - fuzzy_test_valid_color(`hwb(from rebeccapurple none none none)`, `color(srgb none none none)`); - fuzzy_test_valid_color(`hwb(from rebeccapurple none none none / none)`, `color(srgb none none none / none)`); - fuzzy_test_valid_color(`hwb(from rebeccapurple h w none)`, `color(srgb 0.6 0.2 none)`); - fuzzy_test_valid_color(`hwb(from rebeccapurple h w none / alpha)`, `color(srgb 0.6 0.2 none)`); + fuzzy_test_valid_color(`hwb(from rebeccapurple none none none)`, `color(srgb 1 0 0)`); + fuzzy_test_valid_color(`hwb(from rebeccapurple none none none / none)`, `color(srgb 1 0 0 / none)`); + fuzzy_test_valid_color(`hwb(from rebeccapurple h w none)`, `color(srgb 0.6 0.2 1)`); + fuzzy_test_valid_color(`hwb(from rebeccapurple h w none / alpha)`, `color(srgb 0.6 0.2 1)`); fuzzy_test_valid_color(`hwb(from rebeccapurple h w b / none)`, `color(srgb 0.4 0.2 0.6 / none)`); - fuzzy_test_valid_color(`hwb(from rebeccapurple none w b / alpha)`, `color(srgb none 0.2 0.2)`); - fuzzy_test_valid_color(`hwb(from hwb(120deg 20% 50% / .5) h w none / alpha)`, `color(srgb 0.2 1 none / 0.5)`); + fuzzy_test_valid_color(`hwb(from rebeccapurple none w b / alpha)`, `color(srgb 0.6 0.2 0.2)`); + fuzzy_test_valid_color(`hwb(from hwb(120deg 20% 50% / .5) h w none / alpha)`, `color(srgb 0.2 1 0.2 / 0.5)`); fuzzy_test_valid_color(`hwb(from hwb(120deg 20% 50% / .5) h w b / none)`, `color(srgb 0.2 0.5 0.2 / none)`); - fuzzy_test_valid_color(`hwb(from hwb(120deg 20% 50% / .5) none w b / alpha)`, `color(srgb none 0.2 0.2 / 0.5)`); + fuzzy_test_valid_color(`hwb(from hwb(120deg 20% 50% / .5) none w b / alpha)`, `color(srgb 0.5 0.2 0.2 / 0.5)`); // FIXME: Clarify with spec editors if 'none' should pass through to the constants. fuzzy_test_valid_color(`hwb(from hwb(none none none) h w b)`, `color(srgb 1 0 0)`); fuzzy_test_valid_color(`hwb(from hwb(none none none / none) h w b / alpha)`, `color(srgb 1 0 0 / 0)`); @@ -400,7 +404,7 @@ fuzzy_test_valid_color(`oklab(from oklab(0.25 0.2 0.5) calc(l) calc(a) calc(b))`, `oklab(0.25 0.2 0.5)`); fuzzy_test_valid_color(`oklab(from oklab(0.25 0.2 0.5 / 40%) calc(l) calc(a) calc(b) / calc(alpha))`, `oklab(0.25 0.2 0.5 / 0.4)`); fuzzy_test_valid_color(`oklab(from oklab(0.7 0.25 -0.15) calc(l - 0.2) a b)`, `oklab(0.5 0.25 -0.15)`); - fuzzy_test_valid_color(`oklab(from oklab(0.7 0.25 -0.15) l calc(a / 2) calc(b / 3))`, `oklab(0.7 0.125 -0.075)`); + fuzzy_test_valid_color(`oklab(from oklab(0.7 0.25 -0.15) l calc(a / 2) calc(b / 3))`, `oklab(0.7 0.125 -0.05)`); // Testing with 'none'. fuzzy_test_valid_color(`oklab(from oklab(0.25 0.2 0.5) none none none)`, `oklab(none none none)`);
diff --git a/third_party/blink/web_tests/external/wpt/css/css-contain/contain-style-counters-002.html b/third_party/blink/web_tests/external/wpt/css/css-contain/contain-style-counters-002.html index 48494ce2..862ee789 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-contain/contain-style-counters-002.html +++ b/third_party/blink/web_tests/external/wpt/css/css-contain/contain-style-counters-002.html
@@ -5,10 +5,9 @@ <title>CSS Containment Test: 'contain: style' and counter (with 'display: contents')</title> <link rel="help" href="https://www.w3.org/TR/css-contain-1/#containment-style"> - <link rel=help href="https://github.com/w3c/csswg-drafts/issues/7392"> - <link rel="match" href="reference/contain-style-counters-001-ref.html"> - - <meta content="This test checks that when an element has 'contain: style', then counters which may be affecting its subtree are reset to 0 for such scope. In this test, the div#test does not generate a principal box because of 'display: contents'. Despite that particular condition, 'contain: style' will have an effect on div#test." name="assert"> + <link rel="match" href="reference/contain-style-counters-002-ref.html"> + <link rel="help" href="https://github.com/w3c/csswg-drafts/issues/7392"> + <meta content="This test checks that when an element has 'contain: style', then counters which may be affecting its subtree are not reset if they don't generate a box, e.g. due to display: contents" name="assert"> <style> div#create-counter @@ -29,14 +28,6 @@ font-size: 3em; } - /* - Other types of containment (size, layout, paint) have no - effect on box that do not generate a principal box which - is the case here with div#test because of 'display: contents'. - But in this test, 'contain: style' will apply and will - have a rendering effect on the counter. - */ - div#test span { counter-increment: counter-of-span 5; @@ -61,7 +52,7 @@ </style> - <p>Test passes if there is the digit 5. + <p>Test passes if there is the number 14. <div id="create-counter"></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-contain/reference/contain-style-counters-002-ref.html b/third_party/blink/web_tests/external/wpt/css/css-contain/reference/contain-style-counters-002-ref.html new file mode 100644 index 0000000..7a14112 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-contain/reference/contain-style-counters-002-ref.html
@@ -0,0 +1,18 @@ +<!DOCTYPE html> + + <meta charset="UTF-8"> + + <title>CSS Reference Test</title> + + <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/"> + + <style> + div + { + font-size: 3em; + } + </style> + + <p>Test passes if there is the number 14. + + <div>14</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-highlight-api/painting/custom-highlight-painting-019-ref.html b/third_party/blink/web_tests/external/wpt/css/css-highlight-api/painting/custom-highlight-painting-019-ref.html new file mode 100644 index 0000000..22662336 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-highlight-api/painting/custom-highlight-painting-019-ref.html
@@ -0,0 +1,13 @@ +<!DOCTYPE html> +<meta charset="UTF-8"> +<title>CSS Highlight API Reference: Non-overlapping highlight colors</title> +<style> + body { + text-decoration: 2px green underline; + } + #highlight { + color:blue; + text-decoration: 2px blue underline; + } +</style> +<body><span id="highlight">This part should be blue</span> and this part should be black
diff --git a/third_party/blink/web_tests/external/wpt/css/css-highlight-api/painting/custom-highlight-painting-019.html b/third_party/blink/web_tests/external/wpt/css/css-highlight-api/painting/custom-highlight-painting-019.html new file mode 100644 index 0000000..8c5ccbf --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-highlight-api/painting/custom-highlight-painting-019.html
@@ -0,0 +1,39 @@ +<!DOCTYPE html> +<meta charset="UTF-8"> +<title>CSS Highlight API Test: Non-overlapping highlight colors</title> +<link rel="author" title="Stephen Chenney" href="mailto:schenney@igalia.com"> +<link rel="help" href="https://drafts.csswg.org/css-pseudo-4/#highlight-text"> +<link rel="match" href="custom-highlight-painting-019-ref.html"> +<meta name="assert" value="When painting non-overlapping highlights the current color should be resolved against the next layer beneath the highlight at the current location within the span."> +<meta name="fuzzy" content="0-130;0-4"> +<style> + body { + text-decoration: 2px green underline; + } + ::highlight(foo) { + color:blue; + text-decoration: 2px blue underline; + } + ::highlight(bar) { + text-decoration-line: underline; + text-decoration-thickness: 2px; + } +</style> +<body>This part should be blue and this part should be black +<script> + let textNode = document.body.firstChild; + + let r1 = new Range(); + r1.setStart(textNode, 0); + r1.setEnd(textNode, 24); + + let r2 = new Range(); + r2.setStart(textNode, 29); + r2.setEnd(textNode, 54); + + let h1 = new Highlight(r1); + let h2 = new Highlight(r2); + + CSS.highlights.set("foo", h1); + CSS.highlights.set("bar", h2); +</script> \ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/web-animations/responsive/background-position-responsive.html b/third_party/blink/web_tests/external/wpt/web-animations/responsive/background-position-responsive.html new file mode 100644 index 0000000..7b1a6cd --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/web-animations/responsive/background-position-responsive.html
@@ -0,0 +1,53 @@ +<!DOCTYPE html> +<head> + <meta charset="utf-8"> + <meta name="viewport" content="width=device-width, initial-scale=1"> + <title>Animation with neutral keyframe is responsive to change in underlying style</title> + <link rel="help" href="https://www.w3.org/TR/web-animations-1/#the-effect-value-of-a-keyframe-animation-effect"> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <script src="responsive-test.js"></script> +</head> +<body></body> +<script type="text/javascript"> + promise_test(async t => { + const responsiveTest = + createResponsiveTest(t, { + property: 'backgroundPosition', + to: '100px 100px' + }); + await responsiveTest.ready; + responsiveTest.underlyingValue = '20px 60px'; + responsiveTest.assertResponsive([ + {at: 0.25, is: '40px 70px'}, + {at: 0.75, is: '80px 90px'}, + ]); + responsiveTest.underlyingValue = '60px 20px'; + responsiveTest.assertResponsive([ + {at: 0.25, is: '70px 40px'}, + {at: 0.75, is: '90px 80px'}, + ]); + }, 'Animating from a neutral keyframe when the underlying style is ' + + 'explicitly set'); + + promise_test(async t => { + const responsiveTest = + createResponsiveTest(t, { + property: 'backgroundPosition', + from: 'inherit', + to: '100px 100px' + }); + await responsiveTest.ready; + responsiveTest.inheritedValue = '20px 60px'; + responsiveTest.assertResponsive([ + {at: 0.25, is: '40px 70px'}, + {at: 0.75, is: '80px 90px'}, + ]); + responsiveTest.inheritedValue = '60px 20px'; + responsiveTest.assertResponsive([ + {at: 0.25, is: '70px 40px'}, + {at: 0.75, is: '90px 80px'}, + ]); + }, 'Animating from a neutral keyframe when the underlying style is ' + + 'inherited from the parent'); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/web-animations/responsive/box-shadow-responsive.html b/third_party/blink/web_tests/external/wpt/web-animations/responsive/box-shadow-responsive.html new file mode 100644 index 0000000..4f5325d --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/web-animations/responsive/box-shadow-responsive.html
@@ -0,0 +1,61 @@ +<!DOCTYPE html> +<head> + <meta charset="utf-8"> + <meta name="viewport" content="width=device-width, initial-scale=1"> + <title>Animation with neutral keyframe is responsive to change in underlying style</title> + <link rel="help" href="https://www.w3.org/TR/web-animations-1/#the-effect-value-of-a-keyframe-animation-effect"> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <script src="responsive-test.js"></script> +</head> +<body></body> +<script type="text/javascript"> + promise_test(async t => { + const responsiveTest = + createResponsiveTest(t, { + property: 'boxShadow', + from: 'green 20px 20px 20px 20px', + to: 'inherit', + }); + await responsiveTest.ready; + responsiveTest.inheritedValue = 'blue 0px 0px 0px 0px'; + responsiveTest.assertResponsive([ + {at: 0.25, is: 'rgb(0, 96, 64) 15px 15px 15px 15px'}, + {at: 0.75, is: 'rgb(0, 32, 191) 5px 5px 5px 5px'}, + ]); + responsiveTest.inheritedValue = 'yellow 100px 100px 100px 100px'; + responsiveTest.assertResponsive([ + {at: 0.25, is: 'rgb(64, 160, 0) 40px 40px 40px 40px'}, + {at: 0.75, is: 'rgb(191, 223, 0) 80px 80px 80px 80px'}, + ]); + }, 'Animating to inherit responsive to change in style'); + + promise_test(async t => { + const responsiveTest = + createResponsiveTest(t, { + property: 'boxShadow', + from: 'inherit', + to: 'green 20px 20px 20px 20px', + }); + await responsiveTest.ready; + responsiveTest.inheritedValue = + 'blue 0px 0px 0px 0px, yellow 100px 100px 100px 100px'; + responsiveTest.assertResponsive([ + { + at: 0.25, + is: 'rgb(0, 32, 191) 5px 5px 5px 5px, ' + + 'rgba(255, 255, 0, 0.75) 75px 75px 75px 75px' + }, + { + at: 0.75, + is: 'rgb(0, 96, 64) 15px 15px 15px 15px, ' + + 'rgba(255, 255, 0, 0.25) 25px 25px 25px 25px' + }, + ]); + responsiveTest.inheritedValue = 'yellow 100px 100px 100px 100px'; + responsiveTest.assertResponsive([ + {at: 0.25, is: 'rgb(191, 223, 0) 80px 80px 80px 80px'}, + {at: 0.75, is: 'rgb(64, 160, 0) 40px 40px 40px 40px'}, + ]); + }, 'Animating from inherit responsive to change in style'); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/web-animations/responsive/neutral-keyframe-ref.html b/third_party/blink/web_tests/external/wpt/web-animations/responsive/neutral-keyframe-ref.html new file mode 100644 index 0000000..3893330 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/web-animations/responsive/neutral-keyframe-ref.html
@@ -0,0 +1,16 @@ +<!DOCTYPE html> +<html> +<head> + <style type="text/css"> + #block { + background-color: green; + height: 100px; + width: 100px; + transform: translate(100px); + } + </style> +</head> +<body> + <div id="block"></div> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/web-animations/responsive/neutral-keyframe.html b/third_party/blink/web_tests/external/wpt/web-animations/responsive/neutral-keyframe.html new file mode 100644 index 0000000..813aa7c0 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/web-animations/responsive/neutral-keyframe.html
@@ -0,0 +1,41 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<head> + <meta charset="utf-8"> + <meta name="viewport" content="width=device-width, initial-scale=1"> + <title>Animation with neutral keyframe is responsive to change in underlying style</title> + <link rel="help" href="https://www.w3.org/TR/web-animations-1/#the-effect-value-of-a-keyframe-animation-effect"> + <link rel="match" href="neutral-keyframe-ref.html"> + <script src="/common/reftest-wait.js"></script> + <script src="/web-animations/testcommon.js"></script> + <style type="text/css"> + #block { + background-color: green; + height: 100px; + width: 100px; + } + </style> +</head> +<body> + <div id="block"></div> +</body> +<script> + window.onload = async () => { + const target = document.getElementById('block'); + const anim = target.animate({ translate: '200px' }, + { + duration: 10000, + easing: 'steps(1,jump-end)' + }); + await anim.ready; + await waitForNextFrame(); + // The neutral keyframe value changes from transform 'none' to '100px'. + // Since using jump-end for the easing function, the animated value is the + // underlying (neutral) value. If the box is not translated, then the change + // to the underlying value is not taking effect. + target.style.translate = '100px'; + await waitForNextFrame(); + takeScreenshot(); + }; +</script> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/web-animations/responsive/responsive-test.js b/third_party/blink/web_tests/external/wpt/web-animations/responsive/responsive-test.js new file mode 100644 index 0000000..feca5325 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/web-animations/responsive/responsive-test.js
@@ -0,0 +1,65 @@ +class ResponsiveTest { + constructor(target, property, keyframes) { + this.property = property; + this.target = target; + this.duration = 1000; + this.anim = target.animate(keyframes, this.duration); + this.anim.pause(); + } + + get ready() { + return new Promise(resolve => { + this.anim.ready.then(resolve); + }); + } + + set underlyingValue(value) { + this.target.style[this.property] = value; + } + + set inheritedValue(value) { + this.target.parentElement.style[this.property] = value; + } + + // The testCases are of the form: + // [{at: <fractional_progress>, is: <computed style> }, ...] + assertResponsive(testCases) { + for (let i = 0; i < testCases.length; i++) { + const testCase = testCases[i]; + this.anim.currentTime = this.duration * testCase.at; + assert_equals(getComputedStyle(this.target)[this.property], testCase.is, + `${this.property} at ${testCase.at}`); + } + } +} + +// Creates a test that allows setting the underlying style of the target +// element or its parent. +// Options are of the form: +// property: required property in camelcase form as used in the +// web animation API. +// from: optional starting keyframe as a string. +// to: optional ending keyframe as a string. +function createResponsiveTest(test, options) { + const parent = document.createElement('div'); + const target = document.createElement('div'); + document.body.appendChild(parent); + parent.appendChild(target); + const property = options.property; + const keyframes = []; + const createKeyframe = (value) => { + const keyframe = {}; + keyframe[property] = value; + return keyframe; + } + if (options.from) { + keyframes.push(createKeyframe(options.from)); + } + if (options.to) { + keyframes.push(createKeyframe(options.to)); + } + test.add_cleanup(() => { + parent.remove(); + }); + return new ResponsiveTest(target, property, keyframes); +}
diff --git a/third_party/blink/web_tests/flag-specific/disable-site-isolation-trials/external/wpt/html/browsers/browsing-the-web/history-traversal/event-order/same-document-traverse-immediate-expected.txt b/third_party/blink/web_tests/flag-specific/disable-site-isolation-trials/external/wpt/html/browsers/browsing-the-web/history-traversal/event-order/same-document-traverse-immediate-expected.txt new file mode 100644 index 0000000..645331c2 --- /dev/null +++ b/third_party/blink/web_tests/flag-specific/disable-site-isolation-trials/external/wpt/html/browsers/browsing-the-web/history-traversal/event-order/same-document-traverse-immediate-expected.txt
@@ -0,0 +1,5 @@ +This is a testharness.js-based test. +[FAIL] when traversing back, before hashchange + assert_array_equals: lengths differ, expected array ["load", "popstate", "hashchange"] length 3, got ["load", "popstate", "popstate", "hashchange"] length 4 +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/http/tests/content_index/content-index.html b/third_party/blink/web_tests/http/tests/content_index/content-index.html index c861c02..1a4c735 100644 --- a/third_party/blink/web_tests/http/tests/content_index/content-index.html +++ b/third_party/blink/web_tests/http/tests/content_index/content-index.html
@@ -26,13 +26,13 @@ `Failed to execute 'add' on 'ContentIndex': Invalid icon URL protocol`); await expectTypeErrorWithMessage( index.add(createDescription({includeIcons: false})), - 'icons must be provided'); + `Failed to execute 'add' on 'ContentIndex': icons must be provided`); await expectTypeErrorWithMessage( index.add(createDescription({iconUrl: '/non-existent-icon.png'})), - 'Icon could not be loaded'); + `Failed to execute 'add' on 'ContentIndex': Icon could not be loaded`); await expectTypeErrorWithMessage( index.add(createDescription({iconUrl: '/resources/dummy.txt'})), - 'Icon could not be loaded'); + `Failed to execute 'add' on 'ContentIndex': Icon could not be loaded`); await expectTypeErrorWithMessage( index.add(createDescription({url: 'https://other-domain.com/'})), @@ -69,7 +69,7 @@ testRunner.simulateWebContentIndexDelete('register-again'); const swMessage = await waitForMessageFromServiceWorker(); - assert_equals(swMessage, 'Failed to add description due to I/O error.'); + assert_equals(swMessage, `Failed to execute 'add' on 'ContentIndex': Failed to add description due to I/O error.`); // Make sure it is actually deleted and no new content was added. const descriptions = await index.getAll();
diff --git a/third_party/blink/web_tests/http/tests/resources/fedcm/token.php b/third_party/blink/web_tests/http/tests/resources/fedcm/token.php index 9ed8352..131891d 100644 --- a/third_party/blink/web_tests/http/tests/resources/fedcm/token.php +++ b/third_party/blink/web_tests/http/tests/resources/fedcm/token.php
@@ -1,9 +1,7 @@ <?php header("Content-Type: application/json"); -if (isset($_GET['origin'])) { - header("Access-Control-Allow-Origin: " . $_GET['origin']); - header("Access-Control-Allow-Credentials: true"); -} +header("Access-Control-Allow-Origin: " . $_SERVER["HTTP_ORIGIN"]); +header("Access-Control-Allow-Credentials: true"); ?> { "token": "<?php echo $_POST["account_id"]; ?>"
diff --git a/third_party/blink/web_tests/wpt_internal/fenced_frame/autoplay.https.html b/third_party/blink/web_tests/wpt_internal/fenced_frame/autoplay.https.html index 92ba299..38eccb6 100644 --- a/third_party/blink/web_tests/wpt_internal/fenced_frame/autoplay.https.html +++ b/third_party/blink/web_tests/wpt_internal/fenced_frame/autoplay.https.html
@@ -9,7 +9,7 @@ <body></body> <script> promise_test(async () => { - const frame = attachFencedFrameContext(); + const frame = await attachFencedFrameContext(); let audioSuspended = await frame.execute(async () => { internals.settings.setAutoplayPolicy('user-gesture-required');
diff --git a/third_party/blink/web_tests/external/wpt/fenced-frame/content-shared-storage-get.https.html b/third_party/blink/web_tests/wpt_internal/fenced_frame/content-shared-storage-get.https.html similarity index 99% rename from third_party/blink/web_tests/external/wpt/fenced-frame/content-shared-storage-get.https.html rename to third_party/blink/web_tests/wpt_internal/fenced_frame/content-shared-storage-get.https.html index 8afa8de5..d83182e 100644 --- a/third_party/blink/web_tests/external/wpt/fenced-frame/content-shared-storage-get.https.html +++ b/third_party/blink/web_tests/wpt_internal/fenced_frame/content-shared-storage-get.https.html
@@ -139,3 +139,4 @@ </script> </body> +
diff --git a/third_party/blink/web_tests/external/wpt/fenced-frame/disable-untrusted-network.https.html b/third_party/blink/web_tests/wpt_internal/fenced_frame/disable-untrusted-network.https.html similarity index 99% rename from third_party/blink/web_tests/external/wpt/fenced-frame/disable-untrusted-network.https.html rename to third_party/blink/web_tests/wpt_internal/fenced_frame/disable-untrusted-network.https.html index 726728e..ae400d4 100644 --- a/third_party/blink/web_tests/external/wpt/fenced-frame/disable-untrusted-network.https.html +++ b/third_party/blink/web_tests/wpt_internal/fenced_frame/disable-untrusted-network.https.html
@@ -19,13 +19,6 @@ await promise; }); - const same_origin_iframe = await attachIFrameContext(); - await same_origin_iframe.execute(async () => { - const promise = window.fence.disableUntrustedNetwork(); - assert_true(typeof promise.then != 'undefined'); - await promise; - }); - const cross_origin_iframe = await attachIFrameContext({ origin: get_host_info().HTTPS_REMOTE_ORIGIN}); await cross_origin_iframe.execute(async () => { @@ -40,6 +33,13 @@ } }); + const same_origin_iframe = await attachIFrameContext(); + await same_origin_iframe.execute(async () => { + const promise = window.fence.disableUntrustedNetwork(); + assert_true(typeof promise.then != 'undefined'); + await promise; + }); + const promise = window.fence.disableUntrustedNetwork(); assert_true(typeof promise.then != 'undefined'); await promise; @@ -47,3 +47,4 @@ }, 'window.fence.disableUntrustedNetwork availability'); </script> </body> +
diff --git a/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/remote-context-executor.https.html b/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/remote-context-executor.https.html index 6b2f5cc..aca9a04 100644 --- a/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/remote-context-executor.https.html +++ b/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/remote-context-executor.https.html
@@ -21,6 +21,13 @@ await new Promise(resolve => requestAnimationFrame(resolve)); } + // Exempt the remote context dispatch server from network revocation, + // so that you can continue to control fenced frames after network is + // disabled. + const remote_context_dispatcher_url = dispatcher_url + `?uuid=${uuid}`; + await window.internals.exemptUrlFromNetworkRevocation( + remote_context_dispatcher_url); + // Create a RemoteContext Executor, which will wait in the background // for scripts to execute. window.executor = new Executor(uuid);
diff --git a/third_party/blink/web_tests/external/wpt/fenced-frame/resources/unreached.https.html b/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/unreached.https.html similarity index 100% rename from third_party/blink/web_tests/external/wpt/fenced-frame/resources/unreached.https.html rename to third_party/blink/web_tests/wpt_internal/fenced_frame/resources/unreached.https.html
diff --git a/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/utils.js b/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/utils.js index 503a3210..bcfe02f 100644 --- a/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/utils.js +++ b/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/utils.js
@@ -26,6 +26,10 @@ return new URL(REMOTE_EXECUTOR_URL, origin); } +function getRemoteContextDispatcherURL(origin) { + return new URL(dispatcher_path, origin); +} + async function runSelectRawURL(href, resolve_to_config = false) { try { await sharedStorage.worklet.addModule( @@ -192,13 +196,14 @@ } // Builds a URL to be used as a remote context executor. -function generateRemoteContextURL(headers, origin) { +async function generateRemoteContextURL(headers, origin) { // Generate the unique id for the parent/child channel. const uuid = token(); + const effective_origin = origin ? origin : location.origin; // Use the absolute path of the remote context executor source file, so that // nested contexts will work. - const url = getRemoteContextURL(origin ? origin : location.origin); + const url = getRemoteContextURL(effective_origin); url.searchParams.append('uuid', uuid); // Add the header to allow loading in a fenced frame. @@ -214,6 +219,12 @@ }); url.searchParams.append('pipe', formatted_headers.join('|')); + // Exempt the remote context dispatcher URL from network revocation, so RPC + // execution will still work to orchestrate tests after network is revoked. + const remote_context_dispatcher_url = + getRemoteContextDispatcherURL(effective_origin) + `?uuid=${uuid}`; + await window.internals.exemptUrlFromNetworkRevocation(remote_context_dispatcher_url); + return [uuid, url]; } @@ -249,6 +260,11 @@ } }; + // If `object` is null (e.g. a window created with noopener), set it to a + // dummy value so that the Proxy constructor won't fail. + if (object == null) { + object = {}; + } const proxy = new Proxy(object, handler); return proxy; } @@ -259,8 +275,8 @@ // then resolves to the RemoteContext if the property isn't found. // The proxy also has an extra attribute `execute`, which is an alias for the // remote context's `execute_script(fn, args=[])`. -function attachContext(object_constructor, html, headers, origin) { - const [uuid, url] = generateRemoteContextURL(headers, origin); +async function attachContext(object_constructor, html, headers, origin) { + const [uuid, url] = await generateRemoteContextURL(headers, origin); const object = object_constructor(url); return buildRemoteContextForObject(object, uuid, html); } @@ -274,7 +290,7 @@ async function attachOpaqueContext( generator_api, resolve_to_config, ad_with_size, requested_size, automatic_beacon, object_constructor, html, headers, origin) { - const [uuid, url] = generateRemoteContextURL(headers, origin); + const [uuid, url] = await generateRemoteContextURL(headers, origin); const id = await ( generator_api == 'fledge' ? generateURNFromFledge(
diff --git a/third_party/blink/web_tests/wpt_internal/fenced_frame/revoke-fetch.https.html b/third_party/blink/web_tests/wpt_internal/fenced_frame/revoke-fetch.https.html new file mode 100644 index 0000000..a2e26e1d --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/fenced_frame/revoke-fetch.https.html
@@ -0,0 +1,32 @@ +<!DOCTYPE html> +<title>Test that window.fence.disableUntrustedNetwork disables + the Fetch API.</title> +<meta name="timeout" content="long"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/common/utils.js"></script> +<script src="/common/dispatcher/dispatcher.js"></script> +<script src="resources/utils.js"></script> + +<body> +<script> + +promise_test(async(t) => { + const fencedframe = await attachFencedFrameContext(); + const destination_url = new URL('resources/dummy.html', location.href); + await fencedframe.execute(async (destination_url) => { + const response_success = await fetch(destination_url); + await window.fence.disableUntrustedNetwork(); + try { + const response_failure = await fetch(destination_url); + assert_unreached('The fetch should throw an exception.'); + } catch (e) { + assert_equals(e.name, 'TypeError'); + assert_equals(e.message, 'Failed to fetch'); + } + }, [destination_url]); +}, 'window.fence.disableUntrustedNetwork disables the Fetch API'); + +</script> +</body> +
diff --git a/third_party/blink/web_tests/wpt_internal/fenced_frame/revoke-iframe-navigation.https.html b/third_party/blink/web_tests/wpt_internal/fenced_frame/revoke-iframe-navigation.https.html new file mode 100644 index 0000000..ef5d997 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/fenced_frame/revoke-iframe-navigation.https.html
@@ -0,0 +1,33 @@ +<!DOCTYPE html> +<title>Test that window.fence.disableUntrustedNetwork disables + navigations of iframes nested in fenced frames.</title> +<meta name="timeout" content="long"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/common/utils.js"></script> +<script src="/common/dispatcher/dispatcher.js"></script> +<script src="resources/utils.js"></script> + +<body> +<script> + +promise_test(async(t) => { + const fencedframe = await attachFencedFrameContext(); + await fencedframe.execute(async () => { + await window.fence.disableUntrustedNetwork(); + }); + const navigation_promise = + fencedframe.execute(async () => { + const nested_iframe = await attachIFrameContext(); + return nested_iframe.execute(() => { return 'nav success'; }); }, + []); + const result = await Promise.race([ + navigation_promise, + new Promise((resolve, reject) => t.step_timeout( + () => resolve('timeout'), 2000))]); + assert_equals(result, 'timeout'); +}, 'window.fence.disableUntrustedNetwork disables FF->IF navigation'); + +</script> +</body> +
diff --git a/third_party/blink/web_tests/external/wpt/fenced-frame/revoke-nested-fenced-frame-in-iframe-navigation.https.html b/third_party/blink/web_tests/wpt_internal/fenced_frame/revoke-nested-fenced-frame-in-iframe-navigation.https.html similarity index 100% rename from third_party/blink/web_tests/external/wpt/fenced-frame/revoke-nested-fenced-frame-in-iframe-navigation.https.html rename to third_party/blink/web_tests/wpt_internal/fenced_frame/revoke-nested-fenced-frame-in-iframe-navigation.https.html
diff --git a/third_party/blink/web_tests/external/wpt/fenced-frame/revoke-nested-fenced-frame-navigation.https.html b/third_party/blink/web_tests/wpt_internal/fenced_frame/revoke-nested-fenced-frame-navigation.https.html similarity index 100% rename from third_party/blink/web_tests/external/wpt/fenced-frame/revoke-nested-fenced-frame-navigation.https.html rename to third_party/blink/web_tests/wpt_internal/fenced_frame/revoke-nested-fenced-frame-navigation.https.html
diff --git a/third_party/blink/web_tests/external/wpt/fenced-frame/revoke-popup.https.html b/third_party/blink/web_tests/wpt_internal/fenced_frame/revoke-popup.https.html similarity index 96% rename from third_party/blink/web_tests/external/wpt/fenced-frame/revoke-popup.https.html rename to third_party/blink/web_tests/wpt_internal/fenced_frame/revoke-popup.https.html index e4a2bb26..cbdd8f85 100644 --- a/third_party/blink/web_tests/external/wpt/fenced-frame/revoke-popup.https.html +++ b/third_party/blink/web_tests/wpt_internal/fenced_frame/revoke-popup.https.html
@@ -30,7 +30,7 @@ // After disabling network, popup navigations should not work. assert_true(navigator.userActivation.isActive, 'The frame should have user activation.'); - window.popup = attachWindowContext(); + window.popup = await attachWindowContext(); }); const result = await Promise.race([
diff --git a/third_party/blink/web_tests/wpt_internal/fenced_frame/revoke-self-navigation.https.html b/third_party/blink/web_tests/wpt_internal/fenced_frame/revoke-self-navigation.https.html new file mode 100644 index 0000000..c839018 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/fenced_frame/revoke-self-navigation.https.html
@@ -0,0 +1,32 @@ +<!DOCTYPE html> +<title>Test that window.fence.disableUntrustedNetwork disables + self-navigation of fenced frame roots.</title> +<meta name="timeout" content="long"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/common/utils.js"></script> +<script src="/common/dispatcher/dispatcher.js"></script> +<script src="resources/utils.js"></script> + +<body> +<script> + +promise_test(async(t) => { + const fencedframe = await attachFencedFrameContext(); + await fencedframe.execute(async () => { + await window.fence.disableUntrustedNetwork(); + window.executor.suspend(() => { location.href = location.href; }); + }); + + // The old remote context has been suspended, and network revocation should + // have prevented it from reloading. + const result = await Promise.race([ + fencedframe.execute(() => { return 'nav success'; }), + new Promise((resolve, reject) => t.step_timeout( + () => resolve('timeout'), 2000))]); + assert_equals(result, 'timeout'); +}, 'window.fence.disableUntrustedNetwork disables FF self navigation'); + +</script> +</body> +
diff --git a/third_party/blink/web_tests/external/wpt/fenced-frame/revoke-unfenced-top-navigation.https.html b/third_party/blink/web_tests/wpt_internal/fenced_frame/revoke-unfenced-top-navigation.https.html similarity index 100% rename from third_party/blink/web_tests/external/wpt/fenced-frame/revoke-unfenced-top-navigation.https.html rename to third_party/blink/web_tests/wpt_internal/fenced_frame/revoke-unfenced-top-navigation.https.html
diff --git a/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/old_vt_promises_bfcache.html b/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/old_vt_promises_bfcache.html new file mode 100644 index 0000000..18397ab --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/old_vt_promises_bfcache.html
@@ -0,0 +1,115 @@ +<!DOCTYPE html> +<title>VT object created on the old Document is skipped before persisting in BFCache</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<link rel="author" href="mailto:khushalsagar@chromium.org"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/common/utils.js"></script> +<script src="/common/dispatcher/dispatcher.js"></script> +<script src="/html/browsers/browsing-the-web/back-forward-cache/resources/helper.sub.js"></script> +<script> +// runBfcacheTest opens a popup to pageA which navigates to pageB and then +// back, ensuring pageA is stored in the BFCache. + +runBfcacheTest({ + funcBeforeNavigation: async () => { + // This function executes in pageA + + function addTransitionOptIn() { + let css = '@view-transition { navigation: auto; }'; + let style = document.createElement('style'); + style.appendChild(document.createTextNode(css)); + document.head.appendChild(style); + } + addTransitionOptIn(); + + // Wait for at least one frame to ensure there is a transition on the + // navigation. + function waitForAtLeastOneFrame() { + return new Promise(resolve => { + // Different web engines work slightly different on this area but waiting + // for two requestAnimationFrames() to happen, one after another, should be + // sufficient to ensure at least one frame has been generated anywhere. + window.requestAnimationFrame(() => { + window.requestAnimationFrame(() => { + resolve(); + }); + }); + }); + } + await waitForAtLeastOneFrame(); + + onpageswap = (e) => { + if (e.viewTransition == null) + return; + + document.documentElement.classList.add('transition'); + + e.viewTransition.updateCallbackDone.then(() => { + document.documentElement.classList.add('updateCallbackDone'); + }); + + e.viewTransition.ready.catch(() => { + document.documentElement.classList.add('ready'); + }); + + e.viewTransition.finished.then(() => { + document.documentElement.classList.add('finished'); + }); + } + }, + funcBeforeBackNavigation: async () => { + // This function executes in pageB + + function addTransitionOptIn() { + let css = '@view-transition { navigation: auto; }'; + let style = document.createElement('style'); + style.appendChild(document.createTextNode(css)); + document.head.appendChild(style); + } + addTransitionOptIn(); + + // Wait for at least one frame to ensure there is a transition on the + // navigation. + function waitForAtLeastOneFrame() { + return new Promise(resolve => { + // Different web engines work slightly different on this area but waiting + // for two requestAnimationFrames() to happen, one after another, should be + // sufficient to ensure at least one frame has been generated anywhere. + window.requestAnimationFrame(() => { + window.requestAnimationFrame(() => { + resolve(); + }); + }); + }); + } + await waitForAtLeastOneFrame(); + }, + funcAfterAssertion: async (pageA, pageB, t) => { + assert_true( + await pageA.execute_script(() => { + return document.documentElement.classList.contains('transition'); + }), + 'navigation had viewTransition'); + + assert_true( + await pageA.execute_script(() => { + return document.documentElement.classList.contains('updateCallbackDone'); + }), + 'updateCallbackDone was resolved'); + + assert_true( + await pageA.execute_script(() => { + return document.documentElement.classList.contains('ready'); + }), + 'ready was rejected'); + + assert_true( + await pageA.execute_script(() => { + return document.documentElement.classList.contains('finished'); + }), + 'finished was resolved'); + }, + targetOrigin: originSameOrigin, +}); +</script>
diff --git a/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/resources/transition-out-of-bfcache.html b/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/resources/transition-out-of-bfcache.html deleted file mode 100644 index 8969097..0000000 --- a/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/resources/transition-out-of-bfcache.html +++ /dev/null
@@ -1,30 +0,0 @@ -<!DOCTYPE html> -<html class="reftest-wait"> -<title>View transitions: BFCache navigation helper</title> -<link rel="help" href="https://github.com/WICG/view-transitions"> -<link rel="author" href="mailto:vmpstr@chromium.org"> -<meta name="view-transition" content="same-origin"> -<script src="/common/reftest-wait.js"></script> -<style> -html { background: red; } -div { - width: 200px; - height: 200px; - background: white; - color: black; - position: absolute; - top: 40px; - right: 8px; - view-transition-name: target; -} -::view-transition-group(*) { - animation-duration: 0s; -} -</style> -<div id=target></div> -<script> -window.onload = () => { - requestAnimationFrame(() => history.back()); -}; -</script> -</html>
diff --git a/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/transition-out-of-bfcache-manual.html b/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/transition-out-of-bfcache-manual.html deleted file mode 100644 index 953ed5e2..0000000 --- a/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/transition-out-of-bfcache-manual.html +++ /dev/null
@@ -1,62 +0,0 @@ -<!DOCTYPE html> -<html class="reftest-wait"> -<title>View transitions: BFCache navigation manual</title> -<link rel="help" href="https://github.com/WICG/view-transitions"> -<link rel="author" href="mailto:vmpstr@chromium.org"> -<!-- TODO(crbug.com/1416670 ): Automated test crashes - manual for now -<xxlink rel="match" href="transition-out-of-bfcache-ref.html"> ---> -<meta name="view-transition" content="same-origin"> -<script src="/common/reftest-wait.js"></script> -<style> -html { background: red; } -#target { - width: 200px; - height: 200px; - background: black; - color: white; - position: absolute; - top: 40px; - view-transition-name: target; -} - -::view-transition { - background: lightblue; -} - -::view-transition-group(root) { - visibility: hidden; - animation-duration: 500s; -} - -::view-transition-group(target) { - animation-duration: 0s; -} -::view-transition-new(target) { - animation: unset; - opacity: 1; -} -::view-transition-old(target) { - animation: unset; - opacity: 0; -} -</style> -<div id=target><div id=log></div>You should see lightblue background with a black square that says "BFCache" followed by this text.</div> -<script> -function startTest() { - const old_url = "/transition-out-of-bfcache-manual.html"; - const new_url = "/resources/transition-out-of-bfcache.html"; - window.location.href = window.location.href.replace(old_url, new_url); -} - -window.addEventListener("pageshow", (e) => { - if (e.persisted) { - log.innerHTML = "BFCache" - requestAnimationFrame(takeScreenshot); - } else { - log.innerHTML = "Non-BFCache" - requestAnimationFrame(startTest); - } -}); -</script> -</html>
diff --git a/third_party/devtools-frontend-internal b/third_party/devtools-frontend-internal index 45973af..66b4b8e 160000 --- a/third_party/devtools-frontend-internal +++ b/third_party/devtools-frontend-internal
@@ -1 +1 @@ -Subproject commit 45973af663ccb3ac9e2ba7e8d245fc68e12770a0 +Subproject commit 66b4b8e55ce57e007a9abaf12ec4aacc14fbdb47
diff --git a/third_party/devtools-frontend/src b/third_party/devtools-frontend/src index 88376a9..a11a408 160000 --- a/third_party/devtools-frontend/src +++ b/third_party/devtools-frontend/src
@@ -1 +1 @@ -Subproject commit 88376a9d2adac2acf9e276df26265e935357dd7f +Subproject commit a11a408bd5d81d06adac27ef13e74a24630d45c6
diff --git a/third_party/libvpx/README.chromium b/third_party/libvpx/README.chromium index 044315a..bd1541ee 100644 --- a/third_party/libvpx/README.chromium +++ b/third_party/libvpx/README.chromium
@@ -1,7 +1,7 @@ Name: libvpx URL: https://chromium.googlesource.com/webm/libvpx Version: N/A -Revision: c29e63728316486082dd6083c2062434b441b77d +Revision: 19832b1702d5b0adf616a0e080abd5207c8445b5 CPEPrefix: cpe:/a:webmproject:libvpx:1.14.0 License: BSD License File: source/libvpx/LICENSE
diff --git a/third_party/libvpx/source/config/vpx_version.h b/third_party/libvpx/source/config/vpx_version.h index 4e9a0016..74957c76 100644 --- a/third_party/libvpx/source/config/vpx_version.h +++ b/third_party/libvpx/source/config/vpx_version.h
@@ -2,8 +2,8 @@ #define VERSION_MAJOR 1 #define VERSION_MINOR 14 #define VERSION_PATCH 0 -#define VERSION_EXTRA "199-gc29e63728" +#define VERSION_EXTRA "200-g19832b170" #define VERSION_PACKED \ ((VERSION_MAJOR << 16) | (VERSION_MINOR << 8) | (VERSION_PATCH)) -#define VERSION_STRING_NOSP "v1.14.0-199-gc29e63728" -#define VERSION_STRING " v1.14.0-199-gc29e63728" +#define VERSION_STRING_NOSP "v1.14.0-200-g19832b170" +#define VERSION_STRING " v1.14.0-200-g19832b170"
diff --git a/third_party/libvpx/source/libvpx b/third_party/libvpx/source/libvpx index c29e637..19832b1 160000 --- a/third_party/libvpx/source/libvpx +++ b/third_party/libvpx/source/libvpx
@@ -1 +1 @@ -Subproject commit c29e63728316486082dd6083c2062434b441b77d +Subproject commit 19832b1702d5b0adf616a0e080abd5207c8445b5
diff --git a/third_party/perfetto b/third_party/perfetto index 7c4a456..7e63f42 160000 --- a/third_party/perfetto +++ b/third_party/perfetto
@@ -1 +1 @@ -Subproject commit 7c4a4566938e79171e0549f1f75a69e904cdb86c +Subproject commit 7e63f42d755ca255162f1f327126f90e34465581
diff --git a/third_party/rust/bytemuck/v1/BUILD.gn b/third_party/rust/bytemuck/v1/BUILD.gn new file mode 100644 index 0000000..a3f0149 --- /dev/null +++ b/third_party/rust/bytemuck/v1/BUILD.gn
@@ -0,0 +1,47 @@ +# Copyright 2023 The Chromium Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# @generated from third_party/rust/chromium_crates_io/BUILD.gn.hbs by +# tools/crates/gnrt. +# Do not edit! + +import("//build/rust/cargo_crate.gni") + +cargo_crate("lib") { + crate_name = "bytemuck" + epoch = "1" + crate_type = "rlib" + crate_root = + "//third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/src/lib.rs" + sources = [ + "//third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/src/allocation.rs", + "//third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/src/anybitpattern.rs", + "//third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/src/checked.rs", + "//third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/src/contiguous.rs", + "//third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/src/internal.rs", + "//third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/src/lib.rs", + "//third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/src/must.rs", + "//third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/src/no_uninit.rs", + "//third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/src/offset_of.rs", + "//third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/src/pod.rs", + "//third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/src/pod_in_option.rs", + "//third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/src/transparent.rs", + "//third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/src/zeroable.rs", + "//third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/src/zeroable_in_option.rs", + ] + inputs = [] + + build_native_rust_unit_tests = false + edition = "2018" + cargo_pkg_version = "1.14.3" + cargo_pkg_authors = "Lokathor <zefria@gmail.com>" + cargo_pkg_name = "bytemuck" + cargo_pkg_description = "A crate for mucking around with piles of bytes." + library_configs -= [ "//build/config/compiler:chromium_code" ] + library_configs += [ "//build/config/compiler:no_chromium_code" ] + executable_configs -= [ "//build/config/compiler:chromium_code" ] + executable_configs += [ "//build/config/compiler:no_chromium_code" ] + proc_macro_configs -= [ "//build/config/compiler:chromium_code" ] + proc_macro_configs += [ "//build/config/compiler:no_chromium_code" ] +}
diff --git a/third_party/rust/bytemuck/v1/README.chromium b/third_party/rust/bytemuck/v1/README.chromium new file mode 100644 index 0000000..3f445de7 --- /dev/null +++ b/third_party/rust/bytemuck/v1/README.chromium
@@ -0,0 +1,9 @@ +Name: bytemuck +URL: https://crates.io/crates/bytemuck +Description: A crate for mucking around with piles of bytes. +Version: 1.14.3 +Security Critical: yes +Shipped: yes +License: Apache 2.0 +License File: //third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/LICENSE-APACHE +Revision: 49eed864acb5791f61753bfeae488718d481f1f3
diff --git a/third_party/rust/chromium_crates_io/Cargo.lock b/third_party/rust/chromium_crates_io/Cargo.lock index 46319fd8..06bea0ff 100644 --- a/third_party/rust/chromium_crates_io/Cargo.lock +++ b/third_party/rust/chromium_crates_io/Cargo.lock
@@ -36,6 +36,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] +name = "bytemuck" +version = "1.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] name = "bytes" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -57,6 +62,7 @@ "anyhow", "base64", "bitflags", + "bytemuck", "bytes", "cfg-if", "cxx",
diff --git a/third_party/rust/chromium_crates_io/Cargo.toml b/third_party/rust/chromium_crates_io/Cargo.toml index a76f6e3..4e52fe78 100644 --- a/third_party/rust/chromium_crates_io/Cargo.toml +++ b/third_party/rust/chromium_crates_io/Cargo.toml
@@ -19,6 +19,7 @@ anyhow = "1" base64 = "0.13" bitflags = "2" +bytemuck = "1" bytes = "1" cfg-if = "1" cxx = "1"
diff --git a/third_party/rust/chromium_crates_io/supply-chain/audits.toml b/third_party/rust/chromium_crates_io/supply-chain/audits.toml index af2ac13..1bce12e 100644 --- a/third_party/rust/chromium_crates_io/supply-chain/audits.toml +++ b/third_party/rust/chromium_crates_io/supply-chain/audits.toml
@@ -150,6 +150,18 @@ * Additional discussion and/or notes may be found in https://crrev.com/c/5238056 """ +[[audits.bytemuck]] +who = "Lukasz Anforowicz <lukasza@chromium.org>" +criteria = "safe-to-deploy" +version = "1.14.3" +notes = "Additional review notes may be found in https://crrev.com/c/5362675." + +[[audits.bytemuck]] +who = "Lukasz Anforowicz <lukasza@chromium.org>" +criteria = ["does-not-implement-crypto", "ub-risk-2"] +delta = "1.13.1 -> 1.14.3" +notes = "Additional review notes may be found in https://crrev.com/c/5362675." + [[audits.bytes]] who = "agl@chromium.org" criteria = ["safe-to-run", "does-not-implement-crypto"]
diff --git a/third_party/rust/chromium_crates_io/supply-chain/config.toml b/third_party/rust/chromium_crates_io/supply-chain/config.toml index 9f1e0fcd..36181fe 100644 --- a/third_party/rust/chromium_crates_io/supply-chain/config.toml +++ b/third_party/rust/chromium_crates_io/supply-chain/config.toml
@@ -70,6 +70,9 @@ [policy."bitflags:2.4.2"] criteria = ["does-not-implement-crypto", "safe-to-deploy", "ub-risk-2"] +[policy."bytemuck:1.14.3"] +criteria = ["does-not-implement-crypto", "safe-to-deploy", "ub-risk-2"] + [policy."bytes:1.5.0"] criteria = ["does-not-implement-crypto", "safe-to-run"]
diff --git a/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/.cargo-checksum.json b/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/.cargo-checksum.json new file mode 100644 index 0000000..697c9ce --- /dev/null +++ b/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/.cargo-checksum.json
@@ -0,0 +1 @@ +{"files":{}}
diff --git a/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/.cargo/config.toml b/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/.cargo/config.toml new file mode 100644 index 0000000..9d8a446b --- /dev/null +++ b/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/.cargo/config.toml
@@ -0,0 +1,4 @@ +[alias] + +# The list of features should be the same as the one under `[package.metadata.docs.rs]` +nightly_docs = "doc --no-deps -F nightly_docs,derive,extern_crate_alloc,extern_crate_std,zeroable_maybe_uninit,zeroable_atomics,min_const_generics,wasm_simd,must_cast"
diff --git a/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/.cargo_vcs_info.json b/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/.cargo_vcs_info.json new file mode 100644 index 0000000..6dd2892 --- /dev/null +++ b/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/.cargo_vcs_info.json
@@ -0,0 +1,6 @@ +{ + "git": { + "sha1": "49eed864acb5791f61753bfeae488718d481f1f3" + }, + "path_in_vcs": "" +} \ No newline at end of file
diff --git a/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/.github/FUNDING.yml b/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/.github/FUNDING.yml new file mode 100644 index 0000000..3509ccc1 --- /dev/null +++ b/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/.github/FUNDING.yml
@@ -0,0 +1,3 @@ +# These are supported funding model platforms + +github: [Lokathor]
diff --git a/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/.github/workflows/rust.yml b/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/.github/workflows/rust.yml new file mode 100644 index 0000000..0fb1358 --- /dev/null +++ b/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/.github/workflows/rust.yml
@@ -0,0 +1,113 @@ +name: Rust + +on: + push: {} + pull_request: {} + +env: + RUST_BACKTRACE: 1 + +jobs: + test: + name: Test Rust ${{ matrix.rust }} on ${{ matrix.os }} + runs-on: ${{ matrix.os }} + strategy: + matrix: + # it's a little tempting to use `matrix` to do a cartesian product with + # our `--feature` config here, but doing so will be very slow, as the + # free tier only supports up to 20 job runners at a time. + include: + # versions (all on linux-x86_64) + - { rust: 1.34.0, os: ubuntu-latest } + - { rust: stable, os: ubuntu-latest } + - { rust: beta, os: ubuntu-latest } + - { rust: nightly, os: ubuntu-latest } + # non-linux platforms (ones which don't require `cross`) + - { rust: stable, os: macos-latest } + - { rust: stable, os: windows-latest } + - { rust: stable-x86_64-gnu, os: windows-latest } + - { rust: stable-i686-msvc, os: windows-latest } + - { rust: stable-i686-gnu, os: windows-latest } + steps: + - uses: hecrj/setup-rust-action@v1 + with: + rust-version: ${{ matrix.rust }} + - uses: actions/checkout@v3 + - run: cargo test --verbose + - run: cargo test --verbose --no-default-features + - run: cargo test --verbose + - run: cargo test --verbose --all-features + if: matrix.rust == 'nightly' + - run: cargo test --verbose --manifest-path=derive/Cargo.toml --all-features + if: matrix.rust == 'nightly' + + cross-test: + name: Test on ${{ matrix.target }} with cross + runs-on: ubuntu-latest + strategy: + matrix: + # we once had mips runners for Big-endian coverage but those got demoted to tier 3. + target: [i686-unknown-linux-gnu] + steps: + - uses: hecrj/setup-rust-action@v1 + with: + rust-version: nightly + - uses: actions/checkout@v3 + - run: cargo install cross + - run: cross test --verbose --target=${{ matrix.target }} --no-default-features + - run: cross test --verbose --target=${{ matrix.target }} + - run: cross test --verbose --target=${{ matrix.target }} --all-features + if: matrix.rust == 'nightly' + - run: cross test --verbose --target=${{ matrix.target }} --manifest-path=derive/Cargo.toml --all-features + if: matrix.rust == 'nightly' + + miri-test: + name: Test with miri + runs-on: ubuntu-latest + env: + MIRIFLAGS: -Zmiri-tag-raw-pointers + steps: + - uses: hecrj/setup-rust-action@v1 + with: + rust-version: nightly + components: miri + - uses: actions/checkout@v3 + # Note(Lokathor): We got some cached json errors, and so we cargo clean for this run. + - run: rm -fr target + - run: cargo miri test --verbose --no-default-features + - run: cargo miri test --verbose --all-features + - run: cd derive && rm -fr target && cargo miri test --verbose --all-features + + sanitizer-test: + name: Test with -Zsanitizer=${{ matrix.sanitizer }} + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + sanitizer: [address, memory, leak] + steps: + - uses: actions/checkout@v3 + - uses: hecrj/setup-rust-action@v1 + with: + rust-version: nightly + components: rust-src + - name: Test with sanitizer + env: + RUSTFLAGS: -Zsanitizer=${{ matrix.sanitizer }} + RUSTDOCFLAGS: -Zsanitizer=${{ matrix.sanitizer }} + ASAN_OPTIONS: detect_stack_use_after_return=1 + # Asan's leak detection occasionally complains about some small leaks if + # backtraces are captured. + RUST_BACKTRACE: 0 + # We don't run `derive`'s unit tests here the way we do elsewhere (for + # example, in `miri-test` above), as at the moment we can't easily build + # the `proc_macro` runtime with sanitizers on. IIUC doing this would + # require a custom rustc build, and... lol nope. + # + # This would mean only part of the code running under the sanitizer would + # actually include the sanitizer's checks, which is a recipe for false + # positives, so we just skip it, the generated code is what we care + # about anyway. + run: | + cargo test -Zbuild-std --verbose --target=x86_64-unknown-linux-gnu --no-default-features + cargo test -Zbuild-std --verbose --target=x86_64-unknown-linux-gnu --all-features
diff --git a/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/.gitignore b/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/.gitignore new file mode 100644 index 0000000..fb743703 --- /dev/null +++ b/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/.gitignore
@@ -0,0 +1,10 @@ + +Cargo.lock +/target/ +/.vscode/ + +# These are backup files generated by rustfmt +**/*.rs.bk + +/derive/target/ +/derive/.vscode/
diff --git a/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/Cargo.toml b/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/Cargo.toml new file mode 100644 index 0000000..6ff3200 --- /dev/null +++ b/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/Cargo.toml
@@ -0,0 +1,75 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies. +# +# If you are reading this file be aware that the original Cargo.toml +# will likely look very different (and much more reasonable). +# See Cargo.toml.orig for the original contents. + +[package] +edition = "2018" +name = "bytemuck" +version = "1.14.3" +authors = ["Lokathor <zefria@gmail.com>"] +exclude = ["/pedantic.bat"] +description = "A crate for mucking around with piles of bytes." +readme = "README.md" +keywords = [ + "transmute", + "bytes", + "casting", +] +categories = [ + "encoding", + "no-std", +] +license = "Zlib OR Apache-2.0 OR MIT" +repository = "https://github.com/Lokathor/bytemuck" + +[package.metadata.docs.rs] +features = [ + "nightly_docs", + "derive", + "extern_crate_alloc", + "extern_crate_std", + "zeroable_maybe_uninit", + "zeroable_atomics", + "min_const_generics", + "wasm_simd", + "must_cast", +] + +[package.metadata.playground] +features = [ + "derive", + "extern_crate_alloc", + "extern_crate_std", + "zeroable_maybe_uninit", + "zeroable_atomics", + "min_const_generics", + "wasm_simd", + "must_cast", +] + +[dependencies.bytemuck_derive] +version = "1.4" +optional = true + +[features] +aarch64_simd = [] +align_offset = [] +derive = ["bytemuck_derive"] +extern_crate_alloc = [] +extern_crate_std = ["extern_crate_alloc"] +min_const_generics = [] +must_cast = [] +nightly_docs = [] +nightly_portable_simd = [] +nightly_stdsimd = [] +unsound_ptr_pod_impl = [] +wasm_simd = [] +zeroable_atomics = [] +zeroable_maybe_uninit = []
diff --git a/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/Cargo.toml.orig b/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/Cargo.toml.orig new file mode 100644 index 0000000..53050f02 --- /dev/null +++ b/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/Cargo.toml.orig
@@ -0,0 +1,75 @@ +[package] +name = "bytemuck" +description = "A crate for mucking around with piles of bytes." +version = "1.14.3" +authors = ["Lokathor <zefria@gmail.com>"] +repository = "https://github.com/Lokathor/bytemuck" +readme = "README.md" +keywords = ["transmute", "bytes", "casting"] +categories = ["encoding", "no-std"] +edition = "2018" +license = "Zlib OR Apache-2.0 OR MIT" +exclude = ["/pedantic.bat"] + +[features] +# In v2 we'll fix these names to be more "normal". +derive = ["bytemuck_derive"] +extern_crate_alloc = [] +extern_crate_std = ["extern_crate_alloc"] +zeroable_maybe_uninit = [] +zeroable_atomics = [] + +# All MSRV notes below are GUIDELINES and future versions may require even more +# MSRV on any feature. + +# MSRV 1.36: Use `align_offset` method instead of casting to `usize` to check +# alignment of pointers, this *may* improve codegen in some cases (but it has +# never been formally benchmarked!) +align_offset = [] + +min_const_generics = [] # MSRV 1.51: support arrays via min_const_generics + +wasm_simd = [] # MSRV 1.54.0: support wasm simd types +aarch64_simd = [] # MSRV 1.59.0: support aarch64 simd types + +must_cast = [] # MSRV 1.57.0: support the `must` module. + +# Do not use if you can avoid it, because this is **unsound**!!!! +unsound_ptr_pod_impl = [] + +# NOT SEMVER SUPPORTED! TEMPORARY ONLY! +nightly_portable_simd = [] +nightly_stdsimd = [] + +# Improved documentation using the nightly toolchain +nightly_docs = [] + +[dependencies] +bytemuck_derive = { version = "1.4", path = "derive", optional = true } + +[package.metadata.docs.rs] +# Note(Lokathor): Don't use all-features or it would use `unsound_ptr_pod_impl` too. +features = [ + "nightly_docs", + "derive", + "extern_crate_alloc", + "extern_crate_std", + "zeroable_maybe_uninit", + "zeroable_atomics", + "min_const_generics", + "wasm_simd", + "must_cast", +] + +[package.metadata.playground] +# Note(Lokathor): Don't use all-features or it would use `unsound_ptr_pod_impl` too. +features = [ + "derive", + "extern_crate_alloc", + "extern_crate_std", + "zeroable_maybe_uninit", + "zeroable_atomics", + "min_const_generics", + "wasm_simd", + "must_cast", +]
diff --git a/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/LICENSE-APACHE b/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/LICENSE-APACHE new file mode 100644 index 0000000..1d02268d --- /dev/null +++ b/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/LICENSE-APACHE
@@ -0,0 +1,61 @@ +Apache License +Version 2.0, January 2004 +http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. + + "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. + 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. + 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. + 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: + (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and + (b) You must cause any modified files to carry prominent notices stating that You changed the files; and + (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and + (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. + + You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. + 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. + 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. + 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. + 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. + 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + +To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License.
diff --git a/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/LICENSE-MIT b/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/LICENSE-MIT new file mode 100644 index 0000000..0aa88160 --- /dev/null +++ b/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/LICENSE-MIT
@@ -0,0 +1,9 @@ +MIT License + +Copyright (c) 2019 Daniel "Lokathor" Gee. + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/LICENSE-ZLIB b/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/LICENSE-ZLIB new file mode 100644 index 0000000..aa2dabe --- /dev/null +++ b/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/LICENSE-ZLIB
@@ -0,0 +1,11 @@ +Copyright (c) 2019 Daniel "Lokathor" Gee. + +This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source distribution.
diff --git a/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/README.md b/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/README.md new file mode 100644 index 0000000..7b91a05 --- /dev/null +++ b/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/README.md
@@ -0,0 +1,60 @@ +* **[Latest Docs.rs Here](https://docs.rs/bytemuck/)** + +[](https://opensource.org/licenses/Zlib) + +[](https://crates.io/crates/bytemuck) + +# bytemuck + +A crate for mucking around with piles of bytes. + +This crate lets you safely perform "bit cast" operations between data types. +That's where you take a value and just reinterpret the bits as being some other +type of value, without changing the bits. + +* This is **not** like the [`as` keyword][keyword-as] +* This is **not** like the [`From` trait][from-trait] +* It is **most like** [`f32::to_bits`][f32-to_bits], just generalized to let you + convert between all sorts of data types. + +[keyword-as]: https://doc.rust-lang.org/nightly/std/keyword.as.html +[from-trait]: https://doc.rust-lang.org/nightly/core/convert/trait.From.html +[f32-to_bits]: https://doc.rust-lang.org/nightly/std/primitive.f32.html#method.to_bits + +### Here's the part you're more likely to care about: *you can do this with slices too!* + +When a slice is involved it's not a *direct* bitcast. Instead, the `cast_slice` +and `cast_slice_mut` functions will pull apart a slice's data and give you a new +slice that's the same span of memory just viewed as the new type. If the size of +the slice's element changes then the length of the slice you get back will be +changed accordingly. + +This lets you cast a slice of color values into a slice of `u8` and send it to +the GPU, or things like that. I'm sure there's other examples, but honestly this +crate is as popular as it is mostly because of Rust's 3D graphics community +wanting to cast slices of different types into byte slices for sending to the +GPU. Hi friends! Push those vertices, or whatever it is that you all do. + +## See Also + +While `bytemuck` is full of unsafe code, I've also started a "sibling crate" +called [bitfrob](https://docs.rs/bitfrob/latest/bitfrob/), which is where +operations that are 100% safe will be added. + +## Stability + +* The crate is 1.0 and I consider this it to be "basically done". New features + are usually being accepted when other people want to put in the work, but + myself I wanna move on to using `bytemuck` in bigger projects. +* The default build of the `bytemuck` crate will continue to work with `rustc-1.34` + for at least the rest of the `1.y.z` versions. +* Any other cargo features of the crate **are not** held to the same standard, and + may work only on the latest Stable or even only on latest Nightly. + +**Future Plans:** Once the [Safe Transmute Project][pg-st] completes and +stabilizes ("eventually") this crate will be updated to use that as the +underlying mechanism for transmutation bounds, and a 2.0 version of `bytemuck` +will be released. The hope is for the 1.0 to 2.0 transition to be as seamless as +possible, but the future is always uncertain. + +[pg-st]: https://rust-lang.github.io/rfcs/2835-project-safe-transmute.html
diff --git a/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/changelog.md b/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/changelog.md new file mode 100644 index 0000000..aa0e379 --- /dev/null +++ b/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/changelog.md
@@ -0,0 +1,281 @@ +# `bytemuck` changelog + +## 1.14.3 + +* The new std simd nightly features are apparently arch-specific. + This adjusts the feature activation to be x86/ x86_64 only. + +## 1.14.2 + +* Changes the name of the Nightly feature activated by the crate's + `nightly_stdsimd` feature. This is needed as of (approximately) Nightly + 2024-02-06 and later, because the Nightly feature was changed. + +## 1.14.1 + +* docs clarifications. + +## 1.14 + +* `write_zeroes` and `fill_zeroes` functions: Writes (to one) or fills (a slice) + zero bytes to all bytes covered by the provided reference. If your type has + padding, this will even zero out the padding bytes. +* `align_offset` feature: causes pointer alignment checks to use the + `align_offset` pointer method rather than as-casting the pointer to `usize`. + This *may* improve codegen, if the compiler would have otherwise thought that + the pointer address escaped. No formal benchmarks have been done either way. +* `must_cast` feature: Adds `must_*` family of functions. These functions will + fail to compile if the cast requested can't be statically known to succeed. + The error messages can be kinda bad when this happens, but eliminating the + possibility of a runtime error might be worth it to you. + +## 1.13.1 + +* Remove the requirement for the *source* data type to be `AnyBitPattern` on + `pod_collect_to_vec`, allowing you to pod collect vecs of `char` into vecs of + `u32`, or whatever. + +## 1.13 + +* Now depends on `bytemuck_derive-1.4.0` +* Various small enhancements that would have been patch version updates, but + which have been rolled into this minor version update. + +## 1.12.4 + +* This has additional impls for existing traits and cleans up some internal code, + but there's no new functions so I guess it counts as just a patch release. + +## 1.12.3 + +* This bugfix makes the crate do stuff with `Arc` or not based on the + `target_has_atomic` config. Previously, some targets that have allocation but + not atomics were getting errors. This raises the MSRV of the + `extern_crate_alloc` feature to 1.60, but opt-in features are *not* considered + to be hard locked to 1.34 like the basic build of the crate is. + +## 1.12.2 + +* Fixes `try_pod_read_unaligned` bug that made it always fail unless the target + type was exactly pointer sized in which case UB *could* happen. The + `CheckedBitPattern::is_valid_bit_pattern` was being asked to check that a + *reference* to the `pod` value was a valid bit pattern, rather than the actual + bit pattern itself, and so the check could in some cases be illegally + bypassed. + +## 1.12.1 + +* Patch bumped the required `bytemuck_derive` version because of a regression in + how it handled `align(N)` attributes. + +## 1.12 + +* This minor version bump is caused by a version bump in our `bytemuck_derive` + dependency, which is in turn caused by a mixup in the minimum version of `syn` + that `bytemuck_derive` uses. See [Issue + 122](https://github.com/Lokathor/bytemuck/issues/122). There's not any + specific "new" API as you might normally expect from a minor version bump. +* [pali](https://github.com/pali6) fixed a problem with SPIR-V builds being + broken. The error handling functions were trying to be generic over `Display`, + which the error types normally support, except on SPIR-V targets (which run on + the GPU and don't have text formatting). + +## 1.11 + +* [WaffleLapkin](https://github.com/WaffleLapkin) added `wrap_box` and `peel_box` + to the `TransparentWrapperAlloc` trait. Default impls of these functions are + provided, and (as usual with the transparent trait stuff) you should not override + the default versions. + +## 1.10 + +* [TheEdward162](https://github.com/TheEdward162) added the `ZeroableInOption` + and `PodInOption` traits. These are for types that are `Zeroable` or `Pod` + *when in an option*, but not on their own. We provide impls for the various + "NonZeroINTEGER" types in `core`, and if you need to newtype a NonZero value + then you can impl these traits when you use `repr(transparent)`. + +## 1.9.1 + +* Bumped the minimum `bytemuck_derive` dependency version from `1.0` to `1.1`. + The fact that `bytemuck` and `bytemuck_derive` are separate crates at all is + an unfortunate technical limit of current Rust, woe and calamity. + +## 1.9.0 + +* [fu5ha](https://github.com/fu5ha) added the `NoUninit`, `AnyBitPattern`, and + `CheckedBitPattern` traits. This allows for a more fine-grained level of + detail in what casting operations are allowed for a type. Types that already + implement `Zeroable` and `Pod` will have a blanket impl for these new traits. + This is a "preview" of the direction that the crate will probably go in the + eventual 2.0 version. We're still waiting on [Project Safe + Transmute](https://github.com/rust-lang/project-safe-transmute) for an actual + 2.0 version of the crate, but until then please enjoy this preview. +* Also Fusha added better support for `union` types in the derive macros. I + still don't know how any of the proc-macro stuff works at all, so please + direct questions to her. + +## 1.8.0 + +* `try_pod_read_unaligned` and `pod_read_unaligned` let you go from `&[u8]` to + `T:Pod` without worrying about alignment. + +## 1.7.3 + +* Experimental support for the `portable_simd` language extension under the + `nightly_portable_simd` cargo feature. As the name implies, this is an + experimental crate feature and it's **not** part of the semver contract. All + it does is add the appropriate `Zeroable` and `Pod` impls. + +## 1.7.2 + +* Why does this repo keep being hit with publishing problems? What did I do to + deserve this curse, Ferris? This doesn't ever happen with tinyvec or fermium, + only bytemuck. + +## 1.7.1 + +* **Soundness Fix:** The wrap/peel methods for owned value conversion, added to + `TransparentWrapper` in 1.6, can cause a double-drop if used with types that + impl `Drop`. The fix was simply to add a `ManuallyDrop` layer around the value + before doing the `transmute_copy` that is used to wrap/peel. While this fix + could technically be backported to the 1.6 series, since 1.7 is semver + compatible anyway the 1.6 series has simply been yanked. + +## 1.7 + +* In response to [Unsafe Code Guidelines Issue + #286](https://github.com/rust-lang/unsafe-code-guidelines/issues/286), this + version of Bytemuck has a ***Soundness-Required Breaking Change***. This is + "allowed" under Rust's backwards-compatibility guidelines, but it's still + annoying of course so we're trying to keep the damage minimal. + * **The Reason:** It turns out that pointer values should not have been `Pod`. More + specifically, `ptr as usize` is *not* the same operation as calling + `transmute::<_, usize>(ptr)`. + * LLVM has yet to fully sort out their story, but until they do, transmuting + pointers can cause miscompilations. They may fix things up in the future, + but we're not gonna just wait and have broken code in the mean time. + * **The Fix:** The breaking change is that the `Pod` impls for `*const T`, + `*mut T`, and `Option<NonNull<T>` are now gated behind the + `unsound_ptr_pod_impl` feature, which is off by default. + * You are *strongly discouraged* from using this feature, but if a dependency + of yours doesn't work when you upgrade to 1.7 because it relied on pointer + casting, then you might wish to temporarily enable the feature just to get + that dependency to build. Enabled features are global across all users of a + given semver compatible version, so if you enable the feature in your own + crate, your dependency will also end up getting the feature too, and then + it'll be able to compile. + * Please move away from using this feature as soon as you can. Consider it to + *already* be deprecated. + * [PR 65](https://github.com/Lokathor/bytemuck/pull/65) + +## 1.6.3 + +* Small goof with an errant `;`, so [PR 69](https://github.com/Lokathor/bytemuck/pull/69) + *actually* got things working on SPIR-V. + +## 1.6.2 + +cargo upload goof! ignore this one. + +## 1.6.1 + +* [DJMcNab](https://github.com/DJMcNab) did a fix so that the crate can build for SPIR-V + [PR 67](https://github.com/Lokathor/bytemuck/pull/67) + +## 1.6 + +* The `TransparentWrapper` trait now has more methods. More ways to wrap, and + now you can "peel" too! Note that we don't call it "unwrap" because that name + is too strongly associated with the Option/Result methods. + Thanks to [LU15W1R7H](https://github.com/LU15W1R7H) for doing + [PR 58](https://github.com/Lokathor/bytemuck/pull/58) +* Min Const Generics! Now there's Pod and Zeroable for arrays of any size when + you turn on the `min_const_generics` crate feature. + [zakarumych](https://github.com/zakarumych) got the work started in + [PR 59](https://github.com/Lokathor/bytemuck/pull/59), + and [chorman0773](https://github.com/chorman0773) finished off the task in + [PR 63](https://github.com/Lokathor/bytemuck/pull/63) + +## 1.5.1 + +* Fix `bytes_of` failing on zero sized types. + [PR 53](https://github.com/Lokathor/bytemuck/pull/53) + +## 1.5 + +* Added `pod_collect_to_vec`, which will gather a slice into a vec, +allowing you to change the pod type while also safely ignoring alignment. +[PR 50](https://github.com/Lokathor/bytemuck/pull/50) + +## 1.4.2 + +* [Kimundi](https://github.com/Kimundi) fixed an issue that could make `try_zeroed_box` +stack overflow for large values at low optimization levels. +[PR 43](https://github.com/Lokathor/bytemuck/pull/43) + +## 1.4.1 + +* [thomcc](https://github.com/thomcc) fixed up the CI and patched over a soundness hole in `offset_of!`. +[PR 38](https://github.com/Lokathor/bytemuck/pull/38) + +## 1.4 + +* [icewind1991](https://github.com/icewind1991) has contributed the proc-macros + for deriving impls of `Pod`, `TransparentWrapper`, `Zeroable`!! Everyone has + been waiting for this one folks! It's a big deal. Just enable the `derive` + cargo feature and then you'll be able to derive the traits on your types. It + generates all the appropriate tests for you. +* The `zeroable_maybe_uninit` feature now adds a `Zeroable` impl to the + `MaybeUninit` type. This is only behind a feature flag because `MaybeUninit` + didn't exist back in `1.34.0` (the minimum rust version of `bytemuck`). + +## 1.3.1 + +* The entire crate is now available under the `Apache-2.0 OR MIT` license as + well as the previous `Zlib` license + [#24](https://github.com/Lokathor/bytemuck/pull/24). +* [HeroicKatora](https://github.com/HeroicKatora) added the + `try_zeroed_slice_box` function + [#10](https://github.com/Lokathor/bytemuck/pull/17). `zeroed_slice_box` is + also available. +* The `offset_of!` macro now supports a 2-arg version. For types that impl + Default, it'll just make an instance using `default` and then call over to the + 3-arg version. +* The `PodCastError` type now supports `Hash` and `Display`. Also if you enable + the `extern_crate_std` feature then it will support `std::error::Error`. +* We now provide a `TransparentWrapper<T>` impl for `core::num::Wrapper<T>`. +* The error type of `try_from_bytes` and `try_from_bytes_mut` when the input + isn't aligned has been corrected from being `AlignmentMismatch` (intended for + allocation casting only) to `TargetAlignmentGreaterAndInputNotAligned`. + +## 1.3.0 + +* Had a bug because the CI was messed up! It wasn't soundness related, because + it prevented the crate from building entirely if the `extern_crate_alloc` + feature was used. Still, this is yanked, sorry. + +## 1.2.0 + +* [thomcc](https://github.com/thomcc) added many things: + * A fully sound `offset_of!` macro + [#10](https://github.com/Lokathor/bytemuck/pull/10) + * A `Contiguous` trait for when you've got enums with declared values + all in a row [#12](https://github.com/Lokathor/bytemuck/pull/12) + * A `TransparentWrapper` marker trait for when you want to more clearly + enable adding and removing a wrapper struct to its inner value + [#15](https://github.com/Lokathor/bytemuck/pull/15) + * Now MIRI is run on CI in every single push! + [#16](https://github.com/Lokathor/bytemuck/pull/16) + +## 1.1.0 + +* [SimonSapin](https://github.com/SimonSapin) added `from_bytes`, + `from_bytes_mut`, `try_from_bytes`, and `try_from_bytes_mut` ([PR + Link](https://github.com/Lokathor/bytemuck/pull/8)) + +## 1.0.1 + +* Changed to the [zlib](https://opensource.org/licenses/Zlib) license. +* Added much more proper documentation. +* Reduced the minimum Rust version to 1.34
diff --git a/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/rustfmt.toml b/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/rustfmt.toml new file mode 100644 index 0000000..689ceb1 --- /dev/null +++ b/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/rustfmt.toml
@@ -0,0 +1,16 @@ +# Based on +# https://github.com/rust-lang/rustfmt/blob/rustfmt-1.4.19/Configurations.md + +# Stable +edition = "2018" +fn_args_layout = "Compressed" +max_width = 80 +tab_spaces = 2 +use_field_init_shorthand = true +use_try_shorthand = true +use_small_heuristics = "Max" + +# Unstable +format_code_in_doc_comments = true +imports_granularity = "Crate" +wrap_comments = true
diff --git a/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/src/allocation.rs b/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/src/allocation.rs new file mode 100644 index 0000000..20006749 --- /dev/null +++ b/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/src/allocation.rs
@@ -0,0 +1,803 @@ +#![cfg(feature = "extern_crate_alloc")] + +//! Stuff to boost things in the `alloc` crate. +//! +//! * You must enable the `extern_crate_alloc` feature of `bytemuck` or you will +//! not be able to use this module! This is generally done by adding the +//! feature to the dependency in Cargo.toml like so: +//! +//! `bytemuck = { version = "VERSION_YOU_ARE_USING", features = +//! ["extern_crate_alloc"]}` + +use super::*; +#[cfg(target_has_atomic = "ptr")] +use alloc::sync::Arc; +use alloc::{ + alloc::{alloc_zeroed, Layout}, + boxed::Box, + rc::Rc, + vec, + vec::Vec, +}; +use core::ops::{Deref, DerefMut}; + +/// As [`try_cast_box`](try_cast_box), but unwraps for you. +#[inline] +pub fn cast_box<A: NoUninit, B: AnyBitPattern>(input: Box<A>) -> Box<B> { + try_cast_box(input).map_err(|(e, _v)| e).unwrap() +} + +/// Attempts to cast the content type of a [`Box`](alloc::boxed::Box). +/// +/// On failure you get back an error along with the starting `Box`. +/// +/// ## Failure +/// +/// * The start and end content type of the `Box` must have the exact same +/// alignment. +/// * The start and end size of the `Box` must have the exact same size. +#[inline] +pub fn try_cast_box<A: NoUninit, B: AnyBitPattern>( + input: Box<A>, +) -> Result<Box<B>, (PodCastError, Box<A>)> { + if align_of::<A>() != align_of::<B>() { + Err((PodCastError::AlignmentMismatch, input)) + } else if size_of::<A>() != size_of::<B>() { + Err((PodCastError::SizeMismatch, input)) + } else { + // Note(Lokathor): This is much simpler than with the Vec casting! + let ptr: *mut B = Box::into_raw(input) as *mut B; + Ok(unsafe { Box::from_raw(ptr) }) + } +} + +/// Allocates a `Box<T>` with all of the contents being zeroed out. +/// +/// This uses the global allocator to create a zeroed allocation and _then_ +/// turns it into a Box. In other words, it's 100% assured that the zeroed data +/// won't be put temporarily on the stack. You can make a box of any size +/// without fear of a stack overflow. +/// +/// ## Failure +/// +/// This fails if the allocation fails. +#[inline] +pub fn try_zeroed_box<T: Zeroable>() -> Result<Box<T>, ()> { + if size_of::<T>() == 0 { + // This will not allocate but simply create a dangling pointer. + let dangling = core::ptr::NonNull::dangling().as_ptr(); + return Ok(unsafe { Box::from_raw(dangling) }); + } + let layout = Layout::new::<T>(); + let ptr = unsafe { alloc_zeroed(layout) }; + if ptr.is_null() { + // we don't know what the error is because `alloc_zeroed` is a dumb API + Err(()) + } else { + Ok(unsafe { Box::<T>::from_raw(ptr as *mut T) }) + } +} + +/// As [`try_zeroed_box`], but unwraps for you. +#[inline] +pub fn zeroed_box<T: Zeroable>() -> Box<T> { + try_zeroed_box().unwrap() +} + +/// Allocates a `Vec<T>` of length and capacity exactly equal to `length` and +/// all elements zeroed. +/// +/// ## Failure +/// +/// This fails if the allocation fails, or if a layout cannot be calculated for +/// the allocation. +pub fn try_zeroed_vec<T: Zeroable>(length: usize) -> Result<Vec<T>, ()> { + if length == 0 { + Ok(Vec::new()) + } else { + let boxed_slice = try_zeroed_slice_box(length)?; + Ok(boxed_slice.into_vec()) + } +} + +/// As [`try_zeroed_vec`] but unwraps for you +pub fn zeroed_vec<T: Zeroable>(length: usize) -> Vec<T> { + try_zeroed_vec(length).unwrap() +} + +/// Allocates a `Box<[T]>` with all contents being zeroed out. +/// +/// This uses the global allocator to create a zeroed allocation and _then_ +/// turns it into a Box. In other words, it's 100% assured that the zeroed data +/// won't be put temporarily on the stack. You can make a box of any size +/// without fear of a stack overflow. +/// +/// ## Failure +/// +/// This fails if the allocation fails, or if a layout cannot be calculated for +/// the allocation. +#[inline] +pub fn try_zeroed_slice_box<T: Zeroable>( + length: usize, +) -> Result<Box<[T]>, ()> { + if size_of::<T>() == 0 || length == 0 { + // This will not allocate but simply create a dangling slice pointer. + let dangling = core::ptr::NonNull::dangling().as_ptr(); + let dangling_slice = core::ptr::slice_from_raw_parts_mut(dangling, length); + return Ok(unsafe { Box::from_raw(dangling_slice) }); + } + let layout = core::alloc::Layout::array::<T>(length).map_err(|_| ())?; + let ptr = unsafe { alloc_zeroed(layout) }; + if ptr.is_null() { + // we don't know what the error is because `alloc_zeroed` is a dumb API + Err(()) + } else { + let slice = + unsafe { core::slice::from_raw_parts_mut(ptr as *mut T, length) }; + Ok(unsafe { Box::<[T]>::from_raw(slice) }) + } +} + +/// As [`try_zeroed_slice_box`](try_zeroed_slice_box), but unwraps for you. +pub fn zeroed_slice_box<T: Zeroable>(length: usize) -> Box<[T]> { + try_zeroed_slice_box(length).unwrap() +} + +/// As [`try_cast_slice_box`](try_cast_slice_box), but unwraps for you. +#[inline] +pub fn cast_slice_box<A: NoUninit, B: AnyBitPattern>( + input: Box<[A]>, +) -> Box<[B]> { + try_cast_slice_box(input).map_err(|(e, _v)| e).unwrap() +} + +/// Attempts to cast the content type of a `Box<[T]>`. +/// +/// On failure you get back an error along with the starting `Box<[T]>`. +/// +/// ## Failure +/// +/// * The start and end content type of the `Box<[T]>` must have the exact same +/// alignment. +/// * The start and end content size in bytes of the `Box<[T]>` must be the +/// exact same. +#[inline] +pub fn try_cast_slice_box<A: NoUninit, B: AnyBitPattern>( + input: Box<[A]>, +) -> Result<Box<[B]>, (PodCastError, Box<[A]>)> { + if align_of::<A>() != align_of::<B>() { + Err((PodCastError::AlignmentMismatch, input)) + } else if size_of::<A>() != size_of::<B>() { + if size_of::<A>() * input.len() % size_of::<B>() != 0 { + // If the size in bytes of the underlying buffer does not match an exact + // multiple of the size of B, we cannot cast between them. + Err((PodCastError::SizeMismatch, input)) + } else { + // Because the size is an exact multiple, we can now change the length + // of the slice and recreate the Box + // NOTE: This is a valid operation because according to the docs of + // std::alloc::GlobalAlloc::dealloc(), the Layout that was used to alloc + // the block must be the same Layout that is used to dealloc the block. + // Luckily, Layout only stores two things, the alignment, and the size in + // bytes. So as long as both of those stay the same, the Layout will + // remain a valid input to dealloc. + let length = size_of::<A>() * input.len() / size_of::<B>(); + let box_ptr: *mut A = Box::into_raw(input) as *mut A; + let ptr: *mut [B] = + unsafe { core::slice::from_raw_parts_mut(box_ptr as *mut B, length) }; + Ok(unsafe { Box::<[B]>::from_raw(ptr) }) + } + } else { + let box_ptr: *mut [A] = Box::into_raw(input); + let ptr: *mut [B] = box_ptr as *mut [B]; + Ok(unsafe { Box::<[B]>::from_raw(ptr) }) + } +} + +/// As [`try_cast_vec`](try_cast_vec), but unwraps for you. +#[inline] +pub fn cast_vec<A: NoUninit, B: AnyBitPattern>(input: Vec<A>) -> Vec<B> { + try_cast_vec(input).map_err(|(e, _v)| e).unwrap() +} + +/// Attempts to cast the content type of a [`Vec`](alloc::vec::Vec). +/// +/// On failure you get back an error along with the starting `Vec`. +/// +/// ## Failure +/// +/// * The start and end content type of the `Vec` must have the exact same +/// alignment. +/// * The start and end content size in bytes of the `Vec` must be the exact +/// same. +/// * The start and end capacity in bytes of the `Vec` must be the exact same. +#[inline] +pub fn try_cast_vec<A: NoUninit, B: AnyBitPattern>( + input: Vec<A>, +) -> Result<Vec<B>, (PodCastError, Vec<A>)> { + if align_of::<A>() != align_of::<B>() { + Err((PodCastError::AlignmentMismatch, input)) + } else if size_of::<A>() != size_of::<B>() { + if size_of::<A>() * input.len() % size_of::<B>() != 0 + || size_of::<A>() * input.capacity() % size_of::<B>() != 0 + { + // If the size in bytes of the underlying buffer does not match an exact + // multiple of the size of B, we cannot cast between them. + // Note that we have to pay special attention to make sure that both + // length and capacity are valid under B, as we do not want to + // change which bytes are considered part of the initialized slice + // of the Vec + Err((PodCastError::SizeMismatch, input)) + } else { + // Because the size is an exact multiple, we can now change the length and + // capacity and recreate the Vec + // NOTE: This is a valid operation because according to the docs of + // std::alloc::GlobalAlloc::dealloc(), the Layout that was used to alloc + // the block must be the same Layout that is used to dealloc the block. + // Luckily, Layout only stores two things, the alignment, and the size in + // bytes. So as long as both of those stay the same, the Layout will + // remain a valid input to dealloc. + + // Note(Lokathor): First we record the length and capacity, which don't + // have any secret provenance metadata. + let length: usize = size_of::<A>() * input.len() / size_of::<B>(); + let capacity: usize = size_of::<A>() * input.capacity() / size_of::<B>(); + // Note(Lokathor): Next we "pre-forget" the old Vec by wrapping with + // ManuallyDrop, because if we used `core::mem::forget` after taking the + // pointer then that would invalidate our pointer. In nightly there's a + // "into raw parts" method, which we can switch this too eventually. + let mut manual_drop_vec = ManuallyDrop::new(input); + let vec_ptr: *mut A = manual_drop_vec.as_mut_ptr(); + let ptr: *mut B = vec_ptr as *mut B; + Ok(unsafe { Vec::from_raw_parts(ptr, length, capacity) }) + } + } else { + // Note(Lokathor): First we record the length and capacity, which don't have + // any secret provenance metadata. + let length: usize = input.len(); + let capacity: usize = input.capacity(); + // Note(Lokathor): Next we "pre-forget" the old Vec by wrapping with + // ManuallyDrop, because if we used `core::mem::forget` after taking the + // pointer then that would invalidate our pointer. In nightly there's a + // "into raw parts" method, which we can switch this too eventually. + let mut manual_drop_vec = ManuallyDrop::new(input); + let vec_ptr: *mut A = manual_drop_vec.as_mut_ptr(); + let ptr: *mut B = vec_ptr as *mut B; + Ok(unsafe { Vec::from_raw_parts(ptr, length, capacity) }) + } +} + +/// This "collects" a slice of pod data into a vec of a different pod type. +/// +/// Unlike with [`cast_slice`] and [`cast_slice_mut`], this will always work. +/// +/// The output vec will be of a minimal size/capacity to hold the slice given. +/// +/// ```rust +/// # use bytemuck::*; +/// let halfwords: [u16; 4] = [5, 6, 7, 8]; +/// let vec_of_words: Vec<u32> = pod_collect_to_vec(&halfwords); +/// if cfg!(target_endian = "little") { +/// assert_eq!(&vec_of_words[..], &[0x0006_0005, 0x0008_0007][..]) +/// } else { +/// assert_eq!(&vec_of_words[..], &[0x0005_0006, 0x0007_0008][..]) +/// } +/// ``` +pub fn pod_collect_to_vec<A: NoUninit, B: NoUninit + AnyBitPattern>( + src: &[A], +) -> Vec<B> { + let src_size = size_of_val(src); + // Note(Lokathor): dst_count is rounded up so that the dest will always be at + // least as many bytes as the src. + let dst_count = src_size / size_of::<B>() + + if src_size % size_of::<B>() != 0 { 1 } else { 0 }; + let mut dst = vec![B::zeroed(); dst_count]; + + let src_bytes: &[u8] = cast_slice(src); + let dst_bytes: &mut [u8] = cast_slice_mut(&mut dst[..]); + dst_bytes[..src_size].copy_from_slice(src_bytes); + dst +} + +/// As [`try_cast_rc`](try_cast_rc), but unwraps for you. +#[inline] +pub fn cast_rc<A: NoUninit + AnyBitPattern, B: NoUninit + AnyBitPattern>( + input: Rc<A>, +) -> Rc<B> { + try_cast_rc(input).map_err(|(e, _v)| e).unwrap() +} + +/// Attempts to cast the content type of a [`Rc`](alloc::rc::Rc). +/// +/// On failure you get back an error along with the starting `Rc`. +/// +/// The bounds on this function are the same as [`cast_mut`], because a user +/// could call `Rc::get_unchecked_mut` on the output, which could be observable +/// in the input. +/// +/// ## Failure +/// +/// * The start and end content type of the `Rc` must have the exact same +/// alignment. +/// * The start and end size of the `Rc` must have the exact same size. +#[inline] +pub fn try_cast_rc<A: NoUninit + AnyBitPattern, B: NoUninit + AnyBitPattern>( + input: Rc<A>, +) -> Result<Rc<B>, (PodCastError, Rc<A>)> { + if align_of::<A>() != align_of::<B>() { + Err((PodCastError::AlignmentMismatch, input)) + } else if size_of::<A>() != size_of::<B>() { + Err((PodCastError::SizeMismatch, input)) + } else { + // Safety: Rc::from_raw requires size and alignment match, which is met. + let ptr: *const B = Rc::into_raw(input) as *const B; + Ok(unsafe { Rc::from_raw(ptr) }) + } +} + +/// As [`try_cast_arc`](try_cast_arc), but unwraps for you. +#[inline] +#[cfg(target_has_atomic = "ptr")] +pub fn cast_arc<A: NoUninit + AnyBitPattern, B: NoUninit + AnyBitPattern>( + input: Arc<A>, +) -> Arc<B> { + try_cast_arc(input).map_err(|(e, _v)| e).unwrap() +} + +/// Attempts to cast the content type of a [`Arc`](alloc::sync::Arc). +/// +/// On failure you get back an error along with the starting `Arc`. +/// +/// The bounds on this function are the same as [`cast_mut`], because a user +/// could call `Rc::get_unchecked_mut` on the output, which could be observable +/// in the input. +/// +/// ## Failure +/// +/// * The start and end content type of the `Arc` must have the exact same +/// alignment. +/// * The start and end size of the `Arc` must have the exact same size. +#[inline] +#[cfg(target_has_atomic = "ptr")] +pub fn try_cast_arc< + A: NoUninit + AnyBitPattern, + B: NoUninit + AnyBitPattern, +>( + input: Arc<A>, +) -> Result<Arc<B>, (PodCastError, Arc<A>)> { + if align_of::<A>() != align_of::<B>() { + Err((PodCastError::AlignmentMismatch, input)) + } else if size_of::<A>() != size_of::<B>() { + Err((PodCastError::SizeMismatch, input)) + } else { + // Safety: Arc::from_raw requires size and alignment match, which is met. + let ptr: *const B = Arc::into_raw(input) as *const B; + Ok(unsafe { Arc::from_raw(ptr) }) + } +} + +/// As [`try_cast_slice_rc`](try_cast_slice_rc), but unwraps for you. +#[inline] +pub fn cast_slice_rc< + A: NoUninit + AnyBitPattern, + B: NoUninit + AnyBitPattern, +>( + input: Rc<[A]>, +) -> Rc<[B]> { + try_cast_slice_rc(input).map_err(|(e, _v)| e).unwrap() +} + +/// Attempts to cast the content type of a `Rc<[T]>`. +/// +/// On failure you get back an error along with the starting `Rc<[T]>`. +/// +/// The bounds on this function are the same as [`cast_mut`], because a user +/// could call `Rc::get_unchecked_mut` on the output, which could be observable +/// in the input. +/// +/// ## Failure +/// +/// * The start and end content type of the `Rc<[T]>` must have the exact same +/// alignment. +/// * The start and end content size in bytes of the `Rc<[T]>` must be the exact +/// same. +#[inline] +pub fn try_cast_slice_rc< + A: NoUninit + AnyBitPattern, + B: NoUninit + AnyBitPattern, +>( + input: Rc<[A]>, +) -> Result<Rc<[B]>, (PodCastError, Rc<[A]>)> { + if align_of::<A>() != align_of::<B>() { + Err((PodCastError::AlignmentMismatch, input)) + } else if size_of::<A>() != size_of::<B>() { + if size_of::<A>() * input.len() % size_of::<B>() != 0 { + // If the size in bytes of the underlying buffer does not match an exact + // multiple of the size of B, we cannot cast between them. + Err((PodCastError::SizeMismatch, input)) + } else { + // Because the size is an exact multiple, we can now change the length + // of the slice and recreate the Rc + // NOTE: This is a valid operation because according to the docs of + // std::rc::Rc::from_raw(), the type U that was in the original Rc<U> + // acquired from Rc::into_raw() must have the same size alignment and + // size of the type T in the new Rc<T>. So as long as both the size + // and alignment stay the same, the Rc will remain a valid Rc. + let length = size_of::<A>() * input.len() / size_of::<B>(); + let rc_ptr: *const A = Rc::into_raw(input) as *const A; + // Must use ptr::slice_from_raw_parts, because we cannot make an + // intermediate const reference, because it has mutable provenance, + // nor an intermediate mutable reference, because it could be aliased. + let ptr = core::ptr::slice_from_raw_parts(rc_ptr as *const B, length); + Ok(unsafe { Rc::<[B]>::from_raw(ptr) }) + } + } else { + let rc_ptr: *const [A] = Rc::into_raw(input); + let ptr: *const [B] = rc_ptr as *const [B]; + Ok(unsafe { Rc::<[B]>::from_raw(ptr) }) + } +} + +/// As [`try_cast_slice_arc`](try_cast_slice_arc), but unwraps for you. +#[inline] +#[cfg(target_has_atomic = "ptr")] +pub fn cast_slice_arc< + A: NoUninit + AnyBitPattern, + B: NoUninit + AnyBitPattern, +>( + input: Arc<[A]>, +) -> Arc<[B]> { + try_cast_slice_arc(input).map_err(|(e, _v)| e).unwrap() +} + +/// Attempts to cast the content type of a `Arc<[T]>`. +/// +/// On failure you get back an error along with the starting `Arc<[T]>`. +/// +/// The bounds on this function are the same as [`cast_mut`], because a user +/// could call `Rc::get_unchecked_mut` on the output, which could be observable +/// in the input. +/// +/// ## Failure +/// +/// * The start and end content type of the `Arc<[T]>` must have the exact same +/// alignment. +/// * The start and end content size in bytes of the `Arc<[T]>` must be the +/// exact same. +#[inline] +#[cfg(target_has_atomic = "ptr")] +pub fn try_cast_slice_arc< + A: NoUninit + AnyBitPattern, + B: NoUninit + AnyBitPattern, +>( + input: Arc<[A]>, +) -> Result<Arc<[B]>, (PodCastError, Arc<[A]>)> { + if align_of::<A>() != align_of::<B>() { + Err((PodCastError::AlignmentMismatch, input)) + } else if size_of::<A>() != size_of::<B>() { + if size_of::<A>() * input.len() % size_of::<B>() != 0 { + // If the size in bytes of the underlying buffer does not match an exact + // multiple of the size of B, we cannot cast between them. + Err((PodCastError::SizeMismatch, input)) + } else { + // Because the size is an exact multiple, we can now change the length + // of the slice and recreate the Arc + // NOTE: This is a valid operation because according to the docs of + // std::sync::Arc::from_raw(), the type U that was in the original Arc<U> + // acquired from Arc::into_raw() must have the same size alignment and + // size of the type T in the new Arc<T>. So as long as both the size + // and alignment stay the same, the Arc will remain a valid Arc. + let length = size_of::<A>() * input.len() / size_of::<B>(); + let arc_ptr: *const A = Arc::into_raw(input) as *const A; + // Must use ptr::slice_from_raw_parts, because we cannot make an + // intermediate const reference, because it has mutable provenance, + // nor an intermediate mutable reference, because it could be aliased. + let ptr = core::ptr::slice_from_raw_parts(arc_ptr as *const B, length); + Ok(unsafe { Arc::<[B]>::from_raw(ptr) }) + } + } else { + let arc_ptr: *const [A] = Arc::into_raw(input); + let ptr: *const [B] = arc_ptr as *const [B]; + Ok(unsafe { Arc::<[B]>::from_raw(ptr) }) + } +} + +/// An extension trait for `TransparentWrapper` and alloc types. +pub trait TransparentWrapperAlloc<Inner: ?Sized>: + TransparentWrapper<Inner> +{ + /// Convert a vec of the inner type into a vec of the wrapper type. + fn wrap_vec(s: Vec<Inner>) -> Vec<Self> + where + Self: Sized, + Inner: Sized, + { + let mut s = core::mem::ManuallyDrop::new(s); + + let length = s.len(); + let capacity = s.capacity(); + let ptr = s.as_mut_ptr(); + + unsafe { + // SAFETY: + // * ptr comes from Vec (and will not be double-dropped) + // * the two types have the identical representation + // * the len and capacity fields are valid + Vec::from_raw_parts(ptr as *mut Self, length, capacity) + } + } + + /// Convert a box to the inner type into a box to the wrapper + /// type. + #[inline] + fn wrap_box(s: Box<Inner>) -> Box<Self> { + assert!(size_of::<*mut Inner>() == size_of::<*mut Self>()); + + unsafe { + // A pointer cast doesn't work here because rustc can't tell that + // the vtables match (because of the `?Sized` restriction relaxation). + // A `transmute` doesn't work because the sizes are unspecified. + // + // SAFETY: + // * The unsafe contract requires that pointers to Inner and Self have + // identical representations + // * Box is guaranteed to have representation identical to a (non-null) + // pointer + // * The pointer comes from a box (and thus satisfies all safety + // requirements of Box) + let inner_ptr: *mut Inner = Box::into_raw(s); + let wrapper_ptr: *mut Self = transmute!(inner_ptr); + Box::from_raw(wrapper_ptr) + } + } + + /// Convert an [`Rc`](alloc::rc::Rc) to the inner type into an `Rc` to the + /// wrapper type. + #[inline] + fn wrap_rc(s: Rc<Inner>) -> Rc<Self> { + assert!(size_of::<*mut Inner>() == size_of::<*mut Self>()); + + unsafe { + // A pointer cast doesn't work here because rustc can't tell that + // the vtables match (because of the `?Sized` restriction relaxation). + // A `transmute` doesn't work because the layout of Rc is unspecified. + // + // SAFETY: + // * The unsafe contract requires that pointers to Inner and Self have + // identical representations, and that the size and alignment of Inner + // and Self are the same, which meets the safety requirements of + // Rc::from_raw + let inner_ptr: *const Inner = Rc::into_raw(s); + let wrapper_ptr: *const Self = transmute!(inner_ptr); + Rc::from_raw(wrapper_ptr) + } + } + + /// Convert an [`Arc`](alloc::sync::Arc) to the inner type into an `Arc` to + /// the wrapper type. + #[inline] + #[cfg(target_has_atomic = "ptr")] + fn wrap_arc(s: Arc<Inner>) -> Arc<Self> { + assert!(size_of::<*mut Inner>() == size_of::<*mut Self>()); + + unsafe { + // A pointer cast doesn't work here because rustc can't tell that + // the vtables match (because of the `?Sized` restriction relaxation). + // A `transmute` doesn't work because the layout of Arc is unspecified. + // + // SAFETY: + // * The unsafe contract requires that pointers to Inner and Self have + // identical representations, and that the size and alignment of Inner + // and Self are the same, which meets the safety requirements of + // Arc::from_raw + let inner_ptr: *const Inner = Arc::into_raw(s); + let wrapper_ptr: *const Self = transmute!(inner_ptr); + Arc::from_raw(wrapper_ptr) + } + } + + /// Convert a vec of the wrapper type into a vec of the inner type. + fn peel_vec(s: Vec<Self>) -> Vec<Inner> + where + Self: Sized, + Inner: Sized, + { + let mut s = core::mem::ManuallyDrop::new(s); + + let length = s.len(); + let capacity = s.capacity(); + let ptr = s.as_mut_ptr(); + + unsafe { + // SAFETY: + // * ptr comes from Vec (and will not be double-dropped) + // * the two types have the identical representation + // * the len and capacity fields are valid + Vec::from_raw_parts(ptr as *mut Inner, length, capacity) + } + } + + /// Convert a box to the wrapper type into a box to the inner + /// type. + #[inline] + fn peel_box(s: Box<Self>) -> Box<Inner> { + assert!(size_of::<*mut Inner>() == size_of::<*mut Self>()); + + unsafe { + // A pointer cast doesn't work here because rustc can't tell that + // the vtables match (because of the `?Sized` restriction relaxation). + // A `transmute` doesn't work because the sizes are unspecified. + // + // SAFETY: + // * The unsafe contract requires that pointers to Inner and Self have + // identical representations + // * Box is guaranteed to have representation identical to a (non-null) + // pointer + // * The pointer comes from a box (and thus satisfies all safety + // requirements of Box) + let wrapper_ptr: *mut Self = Box::into_raw(s); + let inner_ptr: *mut Inner = transmute!(wrapper_ptr); + Box::from_raw(inner_ptr) + } + } + + /// Convert an [`Rc`](alloc::rc::Rc) to the wrapper type into an `Rc` to the + /// inner type. + #[inline] + fn peel_rc(s: Rc<Self>) -> Rc<Inner> { + assert!(size_of::<*mut Inner>() == size_of::<*mut Self>()); + + unsafe { + // A pointer cast doesn't work here because rustc can't tell that + // the vtables match (because of the `?Sized` restriction relaxation). + // A `transmute` doesn't work because the layout of Rc is unspecified. + // + // SAFETY: + // * The unsafe contract requires that pointers to Inner and Self have + // identical representations, and that the size and alignment of Inner + // and Self are the same, which meets the safety requirements of + // Rc::from_raw + let wrapper_ptr: *const Self = Rc::into_raw(s); + let inner_ptr: *const Inner = transmute!(wrapper_ptr); + Rc::from_raw(inner_ptr) + } + } + + /// Convert an [`Arc`](alloc::sync::Arc) to the wrapper type into an `Arc` to + /// the inner type. + #[inline] + #[cfg(target_has_atomic = "ptr")] + fn peel_arc(s: Arc<Self>) -> Arc<Inner> { + assert!(size_of::<*mut Inner>() == size_of::<*mut Self>()); + + unsafe { + // A pointer cast doesn't work here because rustc can't tell that + // the vtables match (because of the `?Sized` restriction relaxation). + // A `transmute` doesn't work because the layout of Arc is unspecified. + // + // SAFETY: + // * The unsafe contract requires that pointers to Inner and Self have + // identical representations, and that the size and alignment of Inner + // and Self are the same, which meets the safety requirements of + // Arc::from_raw + let wrapper_ptr: *const Self = Arc::into_raw(s); + let inner_ptr: *const Inner = transmute!(wrapper_ptr); + Arc::from_raw(inner_ptr) + } + } +} + +impl<I: ?Sized, T: ?Sized + TransparentWrapper<I>> TransparentWrapperAlloc<I> + for T +{ +} + +/// As `Box<[u8]>`, but remembers the original alignment. +pub struct BoxBytes { + // SAFETY: `ptr` is owned, was allocated with `layout`, and points to + // `layout.size()` initialized bytes. + ptr: NonNull<u8>, + layout: Layout, +} + +impl Deref for BoxBytes { + type Target = [u8]; + + fn deref(&self) -> &Self::Target { + // SAFETY: See type invariant. + unsafe { + core::slice::from_raw_parts(self.ptr.as_ptr(), self.layout.size()) + } + } +} + +impl DerefMut for BoxBytes { + fn deref_mut(&mut self) -> &mut Self::Target { + // SAFETY: See type invariant. + unsafe { + core::slice::from_raw_parts_mut(self.ptr.as_ptr(), self.layout.size()) + } + } +} + +impl Drop for BoxBytes { + fn drop(&mut self) { + // SAFETY: See type invariant. + unsafe { alloc::alloc::dealloc(self.ptr.as_ptr(), self.layout) }; + } +} + +impl<T: NoUninit> From<Box<T>> for BoxBytes { + fn from(value: Box<T>) -> Self { + let layout = Layout::new::<T>(); + let ptr = Box::into_raw(value) as *mut u8; + // SAFETY: Box::into_raw() returns a non-null pointer. + let ptr = unsafe { NonNull::new_unchecked(ptr) }; + BoxBytes { ptr, layout } + } +} + +/// Re-interprets `Box<T>` as `BoxBytes`. +#[inline] +pub fn box_bytes_of<T: NoUninit>(input: Box<T>) -> BoxBytes { + input.into() +} + +/// Re-interprets `BoxBytes` as `Box<T>`. +/// +/// ## Panics +/// +/// This is [`try_from_box_bytes`] but will panic on error and the input will be +/// dropped. +#[inline] +pub fn from_box_bytes<T: AnyBitPattern>(input: BoxBytes) -> Box<T> { + try_from_box_bytes(input).map_err(|(error, _)| error).unwrap() +} + +/// Re-interprets `BoxBytes` as `Box<T>`. +/// +/// ## Panics +/// +/// * If the input isn't aligned for the new type +/// * If the input's length isn’t exactly the size of the new type +#[inline] +pub fn try_from_box_bytes<T: AnyBitPattern>( + input: BoxBytes, +) -> Result<Box<T>, (PodCastError, BoxBytes)> { + let layout = Layout::new::<T>(); + if input.layout.align() != layout.align() { + return Err((PodCastError::AlignmentMismatch, input)); + } else if input.layout.size() != layout.size() { + return Err((PodCastError::SizeMismatch, input)); + } else { + let (ptr, _) = input.into_raw_parts(); + // SAFETY: See type invariant. + Ok(unsafe { Box::from_raw(ptr.as_ptr() as *mut T) }) + } +} + +impl BoxBytes { + /// Constructs a `BoxBytes` from its raw parts. + /// + /// # Safety + /// + /// The pointer is owned, has been allocated with the provided layout, and + /// points to `layout.size()` initialized bytes. + pub unsafe fn from_raw_parts(ptr: NonNull<u8>, layout: Layout) -> Self { + BoxBytes { ptr, layout } + } + + /// Deconstructs a `BoxBytes` into its raw parts. + /// + /// The pointer is owned, has been allocated with the provided layout, and + /// points to `layout.size()` initialized bytes. + pub fn into_raw_parts(self) -> (NonNull<u8>, Layout) { + let me = ManuallyDrop::new(self); + (me.ptr, me.layout) + } + + /// Returns the original layout. + pub fn layout(&self) -> Layout { + self.layout + } +}
diff --git a/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/src/anybitpattern.rs b/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/src/anybitpattern.rs new file mode 100644 index 0000000..56c6bc6 --- /dev/null +++ b/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/src/anybitpattern.rs
@@ -0,0 +1,61 @@ +use crate::{Pod, Zeroable}; + +/// Marker trait for "plain old data" types that are valid for any bit pattern. +/// +/// The requirements for this is very similar to [`Pod`], +/// except that the type can allow uninit (or padding) bytes. +/// This limits what you can do with a type of this kind, but also broadens the +/// included types to `repr(C)` `struct`s that contain padding as well as +/// `union`s. Notably, you can only cast *immutable* references and *owned* +/// values into [`AnyBitPattern`] types, not *mutable* references. +/// +/// [`Pod`] is a subset of [`AnyBitPattern`], meaning that any `T: Pod` is also +/// [`AnyBitPattern`] but any `T: AnyBitPattern` is not necessarily [`Pod`]. +/// +/// [`AnyBitPattern`] is a subset of [`Zeroable`], meaning that any `T: +/// AnyBitPattern` is also [`Zeroable`], but any `T: Zeroable` is not +/// necessarily [`AnyBitPattern`] +/// +/// # Derive +/// +/// A `#[derive(AnyBitPattern)]` macro is provided under the `derive` feature +/// flag which will automatically validate the requirements of this trait and +/// implement the trait for you for both structs and enums. This is the +/// recommended method for implementing the trait, however it's also possible to +/// do manually. If you implement it manually, you *must* carefully follow the +/// below safety rules. +/// +/// * *NOTE: even `C-style`, fieldless enums are intentionally **excluded** from +/// this trait, since it is **unsound** for an enum to have a discriminant value +/// that is not one of its defined variants. +/// +/// # Safety +/// +/// Similar to [`Pod`] except we disregard the rule about it must not contain +/// uninit bytes. Still, this is a quite strong guarantee about a type, so *be +/// careful* when implementing it manually. +/// +/// * The type must be inhabited (eg: no +/// [Infallible](core::convert::Infallible)). +/// * The type must be valid for any bit pattern of its backing memory. +/// * Structs need to have all fields also be `AnyBitPattern`. +/// * It is disallowed for types to contain pointer types, `Cell`, `UnsafeCell`, +/// atomics, and any other forms of interior mutability. +/// * More precisely: A shared reference to the type must allow reads, and +/// *only* reads. RustBelt's separation logic is based on the notion that a +/// type is allowed to define a sharing predicate, its own invariant that must +/// hold for shared references, and this predicate is the reasoning that allow +/// it to deal with atomic and cells etc. We require the sharing predicate to +/// be trivial and permit only read-only access. +/// * There's probably more, don't mess it up (I mean it). +pub unsafe trait AnyBitPattern: + Zeroable + Sized + Copy + 'static +{ +} + +unsafe impl<T: Pod> AnyBitPattern for T {} + +#[cfg(feature = "zeroable_maybe_uninit")] +#[cfg_attr(feature = "nightly_docs", doc(cfg(feature = "zeroable_maybe_uninit")))] +unsafe impl<T> AnyBitPattern for core::mem::MaybeUninit<T> where T: AnyBitPattern +{}
diff --git a/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/src/checked.rs b/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/src/checked.rs new file mode 100644 index 0000000..ae45823 --- /dev/null +++ b/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/src/checked.rs
@@ -0,0 +1,522 @@ +//! Checked versions of the casting functions exposed in crate root +//! that support [`CheckedBitPattern`] types. + +use crate::{ + internal::{self, something_went_wrong}, + AnyBitPattern, NoUninit, +}; + +/// A marker trait that allows types that have some invalid bit patterns to be +/// used in places that otherwise require [`AnyBitPattern`] or [`Pod`] types by +/// performing a runtime check on a perticular set of bits. This is particularly +/// useful for types like fieldless ('C-style') enums, [`char`], bool, and +/// structs containing them. +/// +/// To do this, we define a `Bits` type which is a type with equivalent layout +/// to `Self` other than the invalid bit patterns which disallow `Self` from +/// being [`AnyBitPattern`]. This `Bits` type must itself implement +/// [`AnyBitPattern`]. Then, we implement a function that checks whether a +/// certain instance of the `Bits` is also a valid bit pattern of `Self`. If +/// this check passes, then we can allow casting from the `Bits` to `Self` (and +/// therefore, any type which is able to be cast to `Bits` is also able to be +/// cast to `Self`). +/// +/// [`AnyBitPattern`] is a subset of [`CheckedBitPattern`], meaning that any `T: +/// AnyBitPattern` is also [`CheckedBitPattern`]. This means you can also use +/// any [`AnyBitPattern`] type in the checked versions of casting functions in +/// this module. If it's possible, prefer implementing [`AnyBitPattern`] for +/// your type directly instead of [`CheckedBitPattern`] as it gives greater +/// flexibility. +/// +/// # Derive +/// +/// A `#[derive(CheckedBitPattern)]` macro is provided under the `derive` +/// feature flag which will automatically validate the requirements of this +/// trait and implement the trait for you for both enums and structs. This is +/// the recommended method for implementing the trait, however it's also +/// possible to do manually. +/// +/// # Example +/// +/// If manually implementing the trait, we can do something like so: +/// +/// ```rust +/// use bytemuck::{CheckedBitPattern, NoUninit}; +/// +/// #[repr(u32)] +/// #[derive(Copy, Clone)] +/// enum MyEnum { +/// Variant0 = 0, +/// Variant1 = 1, +/// Variant2 = 2, +/// } +/// +/// unsafe impl CheckedBitPattern for MyEnum { +/// type Bits = u32; +/// +/// fn is_valid_bit_pattern(bits: &u32) -> bool { +/// match *bits { +/// 0 | 1 | 2 => true, +/// _ => false, +/// } +/// } +/// } +/// +/// // It is often useful to also implement `NoUninit` on our `CheckedBitPattern` types. +/// // This will allow us to do casting of mutable references (and mutable slices). +/// // It is not always possible to do so, but in this case we have no padding so it is. +/// unsafe impl NoUninit for MyEnum {} +/// ``` +/// +/// We can now use relevant casting functions. For example, +/// +/// ```rust +/// # use bytemuck::{CheckedBitPattern, NoUninit}; +/// # #[repr(u32)] +/// # #[derive(Copy, Clone, PartialEq, Eq, Debug)] +/// # enum MyEnum { +/// # Variant0 = 0, +/// # Variant1 = 1, +/// # Variant2 = 2, +/// # } +/// # unsafe impl NoUninit for MyEnum {} +/// # unsafe impl CheckedBitPattern for MyEnum { +/// # type Bits = u32; +/// # fn is_valid_bit_pattern(bits: &u32) -> bool { +/// # match *bits { +/// # 0 | 1 | 2 => true, +/// # _ => false, +/// # } +/// # } +/// # } +/// use bytemuck::{bytes_of, bytes_of_mut}; +/// use bytemuck::checked; +/// +/// let bytes = bytes_of(&2u32); +/// let result = checked::try_from_bytes::<MyEnum>(bytes); +/// assert_eq!(result, Ok(&MyEnum::Variant2)); +/// +/// // Fails for invalid discriminant +/// let bytes = bytes_of(&100u32); +/// let result = checked::try_from_bytes::<MyEnum>(bytes); +/// assert!(result.is_err()); +/// +/// // Since we implemented NoUninit, we can also cast mutably from an original type +/// // that is `NoUninit + AnyBitPattern`: +/// let mut my_u32 = 2u32; +/// { +/// let as_enum_mut = checked::cast_mut::<_, MyEnum>(&mut my_u32); +/// assert_eq!(as_enum_mut, &mut MyEnum::Variant2); +/// *as_enum_mut = MyEnum::Variant0; +/// } +/// assert_eq!(my_u32, 0u32); +/// ``` +/// +/// # Safety +/// +/// * `Self` *must* have the same layout as the specified `Bits` except for +/// the possible invalid bit patterns being checked during +/// [`is_valid_bit_pattern`]. +/// * This almost certainly means your type must be `#[repr(C)]` or a similar +/// specified repr, but if you think you know better, you probably don't. If +/// you still think you know better, be careful and have fun. And don't mess +/// it up (I mean it). +/// * If [`is_valid_bit_pattern`] returns true, then the bit pattern contained +/// in `bits` must also be valid for an instance of `Self`. +/// * Probably more, don't mess it up (I mean it 2.0) +/// +/// [`is_valid_bit_pattern`]: CheckedBitPattern::is_valid_bit_pattern +/// [`Pod`]: crate::Pod +pub unsafe trait CheckedBitPattern: Copy { + /// `Self` *must* have the same layout as the specified `Bits` except for + /// the possible invalid bit patterns being checked during + /// [`is_valid_bit_pattern`]. + /// + /// [`is_valid_bit_pattern`]: CheckedBitPattern::is_valid_bit_pattern + type Bits: AnyBitPattern; + + /// If this function returns true, then it must be valid to reinterpret `bits` + /// as `&Self`. + fn is_valid_bit_pattern(bits: &Self::Bits) -> bool; +} + +unsafe impl<T: AnyBitPattern> CheckedBitPattern for T { + type Bits = T; + + #[inline(always)] + fn is_valid_bit_pattern(_bits: &T) -> bool { + true + } +} + +unsafe impl CheckedBitPattern for char { + type Bits = u32; + + #[inline] + fn is_valid_bit_pattern(bits: &Self::Bits) -> bool { + core::char::from_u32(*bits).is_some() + } +} + +unsafe impl CheckedBitPattern for bool { + type Bits = u8; + + #[inline] + fn is_valid_bit_pattern(bits: &Self::Bits) -> bool { + match *bits { + 0 | 1 => true, + _ => false, + } + } +} + +// Rust 1.70.0 documents that NonZero[int] has the same layout as [int]. +macro_rules! impl_checked_for_nonzero { + ($($nonzero:ty: $primitive:ty),* $(,)?) => { + $( + unsafe impl CheckedBitPattern for $nonzero { + type Bits = $primitive; + + #[inline] + fn is_valid_bit_pattern(bits: &Self::Bits) -> bool { + *bits != 0 + } + } + )* + }; +} +impl_checked_for_nonzero! { + core::num::NonZeroU8: u8, + core::num::NonZeroI8: i8, + core::num::NonZeroU16: u16, + core::num::NonZeroI16: i16, + core::num::NonZeroU32: u32, + core::num::NonZeroI32: i32, + core::num::NonZeroU64: u64, + core::num::NonZeroI64: i64, + core::num::NonZeroI128: i128, + core::num::NonZeroU128: u128, + core::num::NonZeroUsize: usize, + core::num::NonZeroIsize: isize, +} + +/// The things that can go wrong when casting between [`CheckedBitPattern`] data +/// forms. +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub enum CheckedCastError { + /// An error occurred during a true-[`Pod`] cast + /// + /// [`Pod`]: crate::Pod + PodCastError(crate::PodCastError), + /// When casting to a [`CheckedBitPattern`] type, it is possible that the + /// original data contains an invalid bit pattern. If so, the cast will + /// fail and this error will be returned. Will never happen on casts + /// between [`Pod`] types. + /// + /// [`Pod`]: crate::Pod + InvalidBitPattern, +} + +#[cfg(not(target_arch = "spirv"))] +impl core::fmt::Display for CheckedCastError { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{:?}", self) + } +} +#[cfg(feature = "extern_crate_std")] +#[cfg_attr(feature = "nightly_docs", doc(cfg(feature = "extern_crate_std")))] +impl std::error::Error for CheckedCastError {} + +impl From<crate::PodCastError> for CheckedCastError { + fn from(err: crate::PodCastError) -> CheckedCastError { + CheckedCastError::PodCastError(err) + } +} + +/// Re-interprets `&[u8]` as `&T`. +/// +/// ## Failure +/// +/// * If the slice isn't aligned for the new type +/// * If the slice's length isn’t exactly the size of the new type +/// * If the slice contains an invalid bit pattern for `T` +#[inline] +pub fn try_from_bytes<T: CheckedBitPattern>( + s: &[u8], +) -> Result<&T, CheckedCastError> { + let pod = crate::try_from_bytes(s)?; + + if <T as CheckedBitPattern>::is_valid_bit_pattern(pod) { + Ok(unsafe { &*(pod as *const <T as CheckedBitPattern>::Bits as *const T) }) + } else { + Err(CheckedCastError::InvalidBitPattern) + } +} + +/// Re-interprets `&mut [u8]` as `&mut T`. +/// +/// ## Failure +/// +/// * If the slice isn't aligned for the new type +/// * If the slice's length isn’t exactly the size of the new type +/// * If the slice contains an invalid bit pattern for `T` +#[inline] +pub fn try_from_bytes_mut<T: CheckedBitPattern + NoUninit>( + s: &mut [u8], +) -> Result<&mut T, CheckedCastError> { + let pod = unsafe { internal::try_from_bytes_mut(s) }?; + + if <T as CheckedBitPattern>::is_valid_bit_pattern(pod) { + Ok(unsafe { &mut *(pod as *mut <T as CheckedBitPattern>::Bits as *mut T) }) + } else { + Err(CheckedCastError::InvalidBitPattern) + } +} + +/// Reads from the bytes as if they were a `T`. +/// +/// ## Failure +/// * If the `bytes` length is not equal to `size_of::<T>()`. +/// * If the slice contains an invalid bit pattern for `T` +#[inline] +pub fn try_pod_read_unaligned<T: CheckedBitPattern>( + bytes: &[u8], +) -> Result<T, CheckedCastError> { + let pod = crate::try_pod_read_unaligned(bytes)?; + + if <T as CheckedBitPattern>::is_valid_bit_pattern(&pod) { + Ok(unsafe { transmute!(pod) }) + } else { + Err(CheckedCastError::InvalidBitPattern) + } +} + +/// Try to cast `T` into `U`. +/// +/// Note that for this particular type of cast, alignment isn't a factor. The +/// input value is semantically copied into the function and then returned to a +/// new memory location which will have whatever the required alignment of the +/// output type is. +/// +/// ## Failure +/// +/// * If the types don't have the same size this fails. +/// * If `a` contains an invalid bit pattern for `B` this fails. +#[inline] +pub fn try_cast<A: NoUninit, B: CheckedBitPattern>( + a: A, +) -> Result<B, CheckedCastError> { + let pod = crate::try_cast(a)?; + + if <B as CheckedBitPattern>::is_valid_bit_pattern(&pod) { + Ok(unsafe { transmute!(pod) }) + } else { + Err(CheckedCastError::InvalidBitPattern) + } +} + +/// Try to convert a `&T` into `&U`. +/// +/// ## Failure +/// +/// * If the reference isn't aligned in the new type +/// * If the source type and target type aren't the same size. +/// * If `a` contains an invalid bit pattern for `B` this fails. +#[inline] +pub fn try_cast_ref<A: NoUninit, B: CheckedBitPattern>( + a: &A, +) -> Result<&B, CheckedCastError> { + let pod = crate::try_cast_ref(a)?; + + if <B as CheckedBitPattern>::is_valid_bit_pattern(pod) { + Ok(unsafe { &*(pod as *const <B as CheckedBitPattern>::Bits as *const B) }) + } else { + Err(CheckedCastError::InvalidBitPattern) + } +} + +/// Try to convert a `&mut T` into `&mut U`. +/// +/// As [`try_cast_ref`], but `mut`. +#[inline] +pub fn try_cast_mut< + A: NoUninit + AnyBitPattern, + B: CheckedBitPattern + NoUninit, +>( + a: &mut A, +) -> Result<&mut B, CheckedCastError> { + let pod = unsafe { internal::try_cast_mut(a) }?; + + if <B as CheckedBitPattern>::is_valid_bit_pattern(pod) { + Ok(unsafe { &mut *(pod as *mut <B as CheckedBitPattern>::Bits as *mut B) }) + } else { + Err(CheckedCastError::InvalidBitPattern) + } +} + +/// Try to convert `&[A]` into `&[B]` (possibly with a change in length). +/// +/// * `input.as_ptr() as usize == output.as_ptr() as usize` +/// * `input.len() * size_of::<A>() == output.len() * size_of::<B>()` +/// +/// ## Failure +/// +/// * If the target type has a greater alignment requirement and the input slice +/// isn't aligned. +/// * If the target element type is a different size from the current element +/// type, and the output slice wouldn't be a whole number of elements when +/// accounting for the size change (eg: 3 `u16` values is 1.5 `u32` values, so +/// that's a failure). +/// * Similarly, you can't convert between a [ZST](https://doc.rust-lang.org/nomicon/exotic-sizes.html#zero-sized-types-zsts) +/// and a non-ZST. +/// * If any element of the converted slice would contain an invalid bit pattern +/// for `B` this fails. +#[inline] +pub fn try_cast_slice<A: NoUninit, B: CheckedBitPattern>( + a: &[A], +) -> Result<&[B], CheckedCastError> { + let pod = crate::try_cast_slice(a)?; + + if pod.iter().all(|pod| <B as CheckedBitPattern>::is_valid_bit_pattern(pod)) { + Ok(unsafe { + core::slice::from_raw_parts(pod.as_ptr() as *const B, pod.len()) + }) + } else { + Err(CheckedCastError::InvalidBitPattern) + } +} + +/// Try to convert `&mut [A]` into `&mut [B]` (possibly with a change in +/// length). +/// +/// As [`try_cast_slice`], but `&mut`. +#[inline] +pub fn try_cast_slice_mut< + A: NoUninit + AnyBitPattern, + B: CheckedBitPattern + NoUninit, +>( + a: &mut [A], +) -> Result<&mut [B], CheckedCastError> { + let pod = unsafe { internal::try_cast_slice_mut(a) }?; + + if pod.iter().all(|pod| <B as CheckedBitPattern>::is_valid_bit_pattern(pod)) { + Ok(unsafe { + core::slice::from_raw_parts_mut(pod.as_mut_ptr() as *mut B, pod.len()) + }) + } else { + Err(CheckedCastError::InvalidBitPattern) + } +} + +/// Re-interprets `&[u8]` as `&T`. +/// +/// ## Panics +/// +/// This is [`try_from_bytes`] but will panic on error. +#[inline] +pub fn from_bytes<T: CheckedBitPattern>(s: &[u8]) -> &T { + match try_from_bytes(s) { + Ok(t) => t, + Err(e) => something_went_wrong("from_bytes", e), + } +} + +/// Re-interprets `&mut [u8]` as `&mut T`. +/// +/// ## Panics +/// +/// This is [`try_from_bytes_mut`] but will panic on error. +#[inline] +pub fn from_bytes_mut<T: NoUninit + CheckedBitPattern>(s: &mut [u8]) -> &mut T { + match try_from_bytes_mut(s) { + Ok(t) => t, + Err(e) => something_went_wrong("from_bytes_mut", e), + } +} + +/// Reads the slice into a `T` value. +/// +/// ## Panics +/// * This is like `try_pod_read_unaligned` but will panic on failure. +#[inline] +pub fn pod_read_unaligned<T: CheckedBitPattern>(bytes: &[u8]) -> T { + match try_pod_read_unaligned(bytes) { + Ok(t) => t, + Err(e) => something_went_wrong("pod_read_unaligned", e), + } +} + +/// Cast `T` into `U` +/// +/// ## Panics +/// +/// * This is like [`try_cast`], but will panic on a size mismatch. +#[inline] +pub fn cast<A: NoUninit, B: CheckedBitPattern>(a: A) -> B { + match try_cast(a) { + Ok(t) => t, + Err(e) => something_went_wrong("cast", e), + } +} + +/// Cast `&mut T` into `&mut U`. +/// +/// ## Panics +/// +/// This is [`try_cast_mut`] but will panic on error. +#[inline] +pub fn cast_mut< + A: NoUninit + AnyBitPattern, + B: NoUninit + CheckedBitPattern, +>( + a: &mut A, +) -> &mut B { + match try_cast_mut(a) { + Ok(t) => t, + Err(e) => something_went_wrong("cast_mut", e), + } +} + +/// Cast `&T` into `&U`. +/// +/// ## Panics +/// +/// This is [`try_cast_ref`] but will panic on error. +#[inline] +pub fn cast_ref<A: NoUninit, B: CheckedBitPattern>(a: &A) -> &B { + match try_cast_ref(a) { + Ok(t) => t, + Err(e) => something_went_wrong("cast_ref", e), + } +} + +/// Cast `&[A]` into `&[B]`. +/// +/// ## Panics +/// +/// This is [`try_cast_slice`] but will panic on error. +#[inline] +pub fn cast_slice<A: NoUninit, B: CheckedBitPattern>(a: &[A]) -> &[B] { + match try_cast_slice(a) { + Ok(t) => t, + Err(e) => something_went_wrong("cast_slice", e), + } +} + +/// Cast `&mut [T]` into `&mut [U]`. +/// +/// ## Panics +/// +/// This is [`try_cast_slice_mut`] but will panic on error. +#[inline] +pub fn cast_slice_mut< + A: NoUninit + AnyBitPattern, + B: NoUninit + CheckedBitPattern, +>( + a: &mut [A], +) -> &mut [B] { + match try_cast_slice_mut(a) { + Ok(t) => t, + Err(e) => something_went_wrong("cast_slice_mut", e), + } +}
diff --git a/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/src/contiguous.rs b/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/src/contiguous.rs new file mode 100644 index 0000000..538514bb --- /dev/null +++ b/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/src/contiguous.rs
@@ -0,0 +1,202 @@ +use super::*; + +/// A trait indicating that: +/// +/// 1. A type has an equivalent representation to some known integral type. +/// 2. All instances of this type fall in a fixed range of values. +/// 3. Within that range, there are no gaps. +/// +/// This is generally useful for fieldless enums (aka "c-style" enums), however +/// it's important that it only be used for those with an explicit `#[repr]`, as +/// `#[repr(Rust)]` fieldess enums have an unspecified layout. +/// +/// Additionally, you shouldn't assume that all implementations are enums. Any +/// type which meets the requirements above while following the rules under +/// "Safety" below is valid. +/// +/// # Example +/// +/// ``` +/// # use bytemuck::Contiguous; +/// #[repr(u8)] +/// #[derive(Debug, Copy, Clone, PartialEq)] +/// enum Foo { +/// A = 0, +/// B = 1, +/// C = 2, +/// D = 3, +/// E = 4, +/// } +/// unsafe impl Contiguous for Foo { +/// type Int = u8; +/// const MIN_VALUE: u8 = Foo::A as u8; +/// const MAX_VALUE: u8 = Foo::E as u8; +/// } +/// assert_eq!(Foo::from_integer(3).unwrap(), Foo::D); +/// assert_eq!(Foo::from_integer(8), None); +/// assert_eq!(Foo::C.into_integer(), 2); +/// ``` +/// # Safety +/// +/// This is an unsafe trait, and incorrectly implementing it is undefined +/// behavior. +/// +/// Informally, by implementing it, you're asserting that `C` is identical to +/// the integral type `C::Int`, and that every `C` falls between `C::MIN_VALUE` +/// and `C::MAX_VALUE` exactly once, without any gaps. +/// +/// Precisely, the guarantees you must uphold when implementing `Contiguous` for +/// some type `C` are: +/// +/// 1. The size of `C` and `C::Int` must be the same, and neither may be a ZST. +/// (Note: alignment is explicitly allowed to differ) +/// +/// 2. `C::Int` must be a primitive integer, and not a wrapper type. In the +/// future, this may be lifted to include cases where the behavior is +/// identical for a relevant set of traits (Ord, arithmetic, ...). +/// +/// 3. All `C::Int`s which are in the *inclusive* range between `C::MIN_VALUE` +/// and `C::MAX_VALUE` are bitwise identical to unique valid instances of +/// `C`. +/// +/// 4. There exist no instances of `C` such that their bitpatterns, when +/// interpreted as instances of `C::Int`, fall outside of the `MAX_VALUE` / +/// `MIN_VALUE` range -- It is legal for unsafe code to assume that if it +/// gets a `C` that implements `Contiguous`, it is in the appropriate range. +/// +/// 5. Finally, you promise not to provide overridden implementations of +/// `Contiguous::from_integer` and `Contiguous::into_integer`. +/// +/// For clarity, the following rules could be derived from the above, but are +/// listed explicitly: +/// +/// - `C::MAX_VALUE` must be greater or equal to `C::MIN_VALUE` (therefore, `C` +/// must be an inhabited type). +/// +/// - There exist no two values between `MIN_VALUE` and `MAX_VALUE` such that +/// when interpreted as a `C` they are considered identical (by, say, match). +pub unsafe trait Contiguous: Copy + 'static { + /// The primitive integer type with an identical representation to this + /// type. + /// + /// Contiguous is broadly intended for use with fieldless enums, and for + /// these the correct integer type is easy: The enum should have a + /// `#[repr(Int)]` or `#[repr(C)]` attribute, (if it does not, it is + /// *unsound* to implement `Contiguous`!). + /// + /// - For `#[repr(Int)]`, use the listed `Int`. e.g. `#[repr(u8)]` should use + /// `type Int = u8`. + /// + /// - For `#[repr(C)]`, use whichever type the C compiler will use to + /// represent the given enum. This is usually `c_int` (from `std::os::raw` + /// or `libc`), but it's up to you to make the determination as the + /// implementer of the unsafe trait. + /// + /// For precise rules, see the list under "Safety" above. + type Int: Copy + Ord; + + /// The upper *inclusive* bound for valid instances of this type. + const MAX_VALUE: Self::Int; + + /// The lower *inclusive* bound for valid instances of this type. + const MIN_VALUE: Self::Int; + + /// If `value` is within the range for valid instances of this type, + /// returns `Some(converted_value)`, otherwise, returns `None`. + /// + /// This is a trait method so that you can write `value.into_integer()` in + /// your code. It is a contract of this trait that if you implement + /// `Contiguous` on your type you **must not** override this method. + /// + /// # Panics + /// + /// We will not panic for any correct implementation of `Contiguous`, but + /// *may* panic if we detect an incorrect one. + /// + /// This is undefined behavior regardless, so it could have been the nasal + /// demons at that point anyway ;). + #[inline] + fn from_integer(value: Self::Int) -> Option<Self> { + // Guard against an illegal implementation of Contiguous. Annoyingly we + // can't rely on `transmute` to do this for us (see below), but + // whatever, this gets compiled into nothing in release. + assert!(size_of::<Self>() == size_of::<Self::Int>()); + if Self::MIN_VALUE <= value && value <= Self::MAX_VALUE { + // SAFETY: We've checked their bounds (and their size, even though + // they've sworn under the Oath Of Unsafe Rust that that already + // matched) so this is allowed by `Contiguous`'s unsafe contract. + // + // So, the `transmute!`. ideally we'd use transmute here, which + // is more obviously safe. Sadly, we can't, as these types still + // have unspecified sizes. + Some(unsafe { transmute!(value) }) + } else { + None + } + } + + /// Perform the conversion from `C` into the underlying integral type. This + /// mostly exists otherwise generic code would need unsafe for the `value as + /// integer` + /// + /// This is a trait method so that you can write `value.into_integer()` in + /// your code. It is a contract of this trait that if you implement + /// `Contiguous` on your type you **must not** override this method. + /// + /// # Panics + /// + /// We will not panic for any correct implementation of `Contiguous`, but + /// *may* panic if we detect an incorrect one. + /// + /// This is undefined behavior regardless, so it could have been the nasal + /// demons at that point anyway ;). + #[inline] + fn into_integer(self) -> Self::Int { + // Guard against an illegal implementation of Contiguous. Annoyingly we + // can't rely on `transmute` to do the size check for us (see + // `from_integer's comment`), but whatever, this gets compiled into + // nothing in release. Note that we don't check the result of cast + assert!(size_of::<Self>() == size_of::<Self::Int>()); + + // SAFETY: The unsafe contract requires that these have identical + // representations, and that the range be entirely valid. Using + // transmute! instead of transmute here is annoying, but is required + // as `Self` and `Self::Int` have unspecified sizes still. + unsafe { transmute!(self) } + } +} + +macro_rules! impl_contiguous { + ($($src:ty as $repr:ident in [$min:expr, $max:expr];)*) => {$( + unsafe impl Contiguous for $src { + type Int = $repr; + const MAX_VALUE: $repr = $max; + const MIN_VALUE: $repr = $min; + } + )*}; +} + +impl_contiguous! { + bool as u8 in [0, 1]; + + u8 as u8 in [0, u8::max_value()]; + u16 as u16 in [0, u16::max_value()]; + u32 as u32 in [0, u32::max_value()]; + u64 as u64 in [0, u64::max_value()]; + u128 as u128 in [0, u128::max_value()]; + usize as usize in [0, usize::max_value()]; + + i8 as i8 in [i8::min_value(), i8::max_value()]; + i16 as i16 in [i16::min_value(), i16::max_value()]; + i32 as i32 in [i32::min_value(), i32::max_value()]; + i64 as i64 in [i64::min_value(), i64::max_value()]; + i128 as i128 in [i128::min_value(), i128::max_value()]; + isize as isize in [isize::min_value(), isize::max_value()]; + + NonZeroU8 as u8 in [1, u8::max_value()]; + NonZeroU16 as u16 in [1, u16::max_value()]; + NonZeroU32 as u32 in [1, u32::max_value()]; + NonZeroU64 as u64 in [1, u64::max_value()]; + NonZeroU128 as u128 in [1, u128::max_value()]; + NonZeroUsize as usize in [1, usize::max_value()]; +}
diff --git a/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/src/internal.rs b/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/src/internal.rs new file mode 100644 index 0000000..3ede50ff --- /dev/null +++ b/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/src/internal.rs
@@ -0,0 +1,402 @@ +//! Internal implementation of casting functions not bound by marker traits +//! and therefore marked as unsafe. This is used so that we don't need to +//! duplicate the business logic contained in these functions between the +//! versions exported in the crate root, `checked`, and `relaxed` modules. +#![allow(unused_unsafe)] + +use crate::PodCastError; +use core::{marker::*, mem::*}; + +/* + +Note(Lokathor): We've switched all of the `unwrap` to `match` because there is +apparently a bug: https://github.com/rust-lang/rust/issues/68667 +and it doesn't seem to show up in simple godbolt examples but has been reported +as having an impact when there's a cast mixed in with other more complicated +code around it. Rustc/LLVM ends up missing that the `Err` can't ever happen for +particular type combinations, and then it doesn't fully eliminated the panic +possibility code branch. + +*/ + +/// Immediately panics. +#[cfg(not(target_arch = "spirv"))] +#[cold] +#[inline(never)] +pub(crate) fn something_went_wrong<D: core::fmt::Display>( + _src: &str, _err: D, +) -> ! { + // Note(Lokathor): Keeping the panic here makes the panic _formatting_ go + // here too, which helps assembly readability and also helps keep down + // the inline pressure. + panic!("{src}>{err}", src = _src, err = _err); +} + +/// Immediately panics. +#[cfg(target_arch = "spirv")] +#[cold] +#[inline(never)] +pub(crate) fn something_went_wrong<D>(_src: &str, _err: D) -> ! { + // Note: On the spirv targets from [rust-gpu](https://github.com/EmbarkStudios/rust-gpu) + // panic formatting cannot be used. We we just give a generic error message + // The chance that the panicking version of these functions will ever get + // called on spir-v targets with invalid inputs is small, but giving a + // simple error message is better than no error message at all. + panic!("Called a panicing helper from bytemuck which paniced"); +} + +/// Re-interprets `&T` as `&[u8]`. +/// +/// Any ZST becomes an empty slice, and in that case the pointer value of that +/// empty slice might not match the pointer value of the input reference. +#[inline(always)] +pub(crate) unsafe fn bytes_of<T: Copy>(t: &T) -> &[u8] { + if size_of::<T>() == 0 { + &[] + } else { + match try_cast_slice::<T, u8>(core::slice::from_ref(t)) { + Ok(s) => s, + Err(_) => unreachable!(), + } + } +} + +/// Re-interprets `&mut T` as `&mut [u8]`. +/// +/// Any ZST becomes an empty slice, and in that case the pointer value of that +/// empty slice might not match the pointer value of the input reference. +#[inline] +pub(crate) unsafe fn bytes_of_mut<T: Copy>(t: &mut T) -> &mut [u8] { + if size_of::<T>() == 0 { + &mut [] + } else { + match try_cast_slice_mut::<T, u8>(core::slice::from_mut(t)) { + Ok(s) => s, + Err(_) => unreachable!(), + } + } +} + +/// Re-interprets `&[u8]` as `&T`. +/// +/// ## Panics +/// +/// This is [`try_from_bytes`] but will panic on error. +#[inline] +pub(crate) unsafe fn from_bytes<T: Copy>(s: &[u8]) -> &T { + match try_from_bytes(s) { + Ok(t) => t, + Err(e) => something_went_wrong("from_bytes", e), + } +} + +/// Re-interprets `&mut [u8]` as `&mut T`. +/// +/// ## Panics +/// +/// This is [`try_from_bytes_mut`] but will panic on error. +#[inline] +pub(crate) unsafe fn from_bytes_mut<T: Copy>(s: &mut [u8]) -> &mut T { + match try_from_bytes_mut(s) { + Ok(t) => t, + Err(e) => something_went_wrong("from_bytes_mut", e), + } +} + +/// Reads from the bytes as if they were a `T`. +/// +/// ## Failure +/// * If the `bytes` length is not equal to `size_of::<T>()`. +#[inline] +pub(crate) unsafe fn try_pod_read_unaligned<T: Copy>( + bytes: &[u8], +) -> Result<T, PodCastError> { + if bytes.len() != size_of::<T>() { + Err(PodCastError::SizeMismatch) + } else { + Ok(unsafe { (bytes.as_ptr() as *const T).read_unaligned() }) + } +} + +/// Reads the slice into a `T` value. +/// +/// ## Panics +/// * This is like `try_pod_read_unaligned` but will panic on failure. +#[inline] +pub(crate) unsafe fn pod_read_unaligned<T: Copy>(bytes: &[u8]) -> T { + match try_pod_read_unaligned(bytes) { + Ok(t) => t, + Err(e) => something_went_wrong("pod_read_unaligned", e), + } +} + +/// Checks if `ptr` is aligned to an `align` memory boundary. +/// +/// ## Panics +/// * If `align` is not a power of two. This includes when `align` is zero. +#[inline] +pub(crate) fn is_aligned_to(ptr: *const (), align: usize) -> bool { + #[cfg(feature = "align_offset")] + { + // This is in a way better than `ptr as usize % align == 0`, + // because casting a pointer to an integer has the side effect that it + // exposes the pointer's provenance, which may theoretically inhibit + // some compiler optimizations. + ptr.align_offset(align) == 0 + } + #[cfg(not(feature = "align_offset"))] + { + ((ptr as usize) % align) == 0 + } +} + +/// Re-interprets `&[u8]` as `&T`. +/// +/// ## Failure +/// +/// * If the slice isn't aligned for the new type +/// * If the slice's length isn’t exactly the size of the new type +#[inline] +pub(crate) unsafe fn try_from_bytes<T: Copy>( + s: &[u8], +) -> Result<&T, PodCastError> { + if s.len() != size_of::<T>() { + Err(PodCastError::SizeMismatch) + } else if !is_aligned_to(s.as_ptr() as *const (), align_of::<T>()) { + Err(PodCastError::TargetAlignmentGreaterAndInputNotAligned) + } else { + Ok(unsafe { &*(s.as_ptr() as *const T) }) + } +} + +/// Re-interprets `&mut [u8]` as `&mut T`. +/// +/// ## Failure +/// +/// * If the slice isn't aligned for the new type +/// * If the slice's length isn’t exactly the size of the new type +#[inline] +pub(crate) unsafe fn try_from_bytes_mut<T: Copy>( + s: &mut [u8], +) -> Result<&mut T, PodCastError> { + if s.len() != size_of::<T>() { + Err(PodCastError::SizeMismatch) + } else if !is_aligned_to(s.as_ptr() as *const (), align_of::<T>()) { + Err(PodCastError::TargetAlignmentGreaterAndInputNotAligned) + } else { + Ok(unsafe { &mut *(s.as_mut_ptr() as *mut T) }) + } +} + +/// Cast `T` into `U` +/// +/// ## Panics +/// +/// * This is like [`try_cast`](try_cast), but will panic on a size mismatch. +#[inline] +pub(crate) unsafe fn cast<A: Copy, B: Copy>(a: A) -> B { + if size_of::<A>() == size_of::<B>() { + unsafe { transmute!(a) } + } else { + something_went_wrong("cast", PodCastError::SizeMismatch) + } +} + +/// Cast `&mut T` into `&mut U`. +/// +/// ## Panics +/// +/// This is [`try_cast_mut`] but will panic on error. +#[inline] +pub(crate) unsafe fn cast_mut<A: Copy, B: Copy>(a: &mut A) -> &mut B { + if size_of::<A>() == size_of::<B>() && align_of::<A>() >= align_of::<B>() { + // Plz mr compiler, just notice that we can't ever hit Err in this case. + match try_cast_mut(a) { + Ok(b) => b, + Err(_) => unreachable!(), + } + } else { + match try_cast_mut(a) { + Ok(b) => b, + Err(e) => something_went_wrong("cast_mut", e), + } + } +} + +/// Cast `&T` into `&U`. +/// +/// ## Panics +/// +/// This is [`try_cast_ref`] but will panic on error. +#[inline] +pub(crate) unsafe fn cast_ref<A: Copy, B: Copy>(a: &A) -> &B { + if size_of::<A>() == size_of::<B>() && align_of::<A>() >= align_of::<B>() { + // Plz mr compiler, just notice that we can't ever hit Err in this case. + match try_cast_ref(a) { + Ok(b) => b, + Err(_) => unreachable!(), + } + } else { + match try_cast_ref(a) { + Ok(b) => b, + Err(e) => something_went_wrong("cast_ref", e), + } + } +} + +/// Cast `&[A]` into `&[B]`. +/// +/// ## Panics +/// +/// This is [`try_cast_slice`] but will panic on error. +#[inline] +pub(crate) unsafe fn cast_slice<A: Copy, B: Copy>(a: &[A]) -> &[B] { + match try_cast_slice(a) { + Ok(b) => b, + Err(e) => something_went_wrong("cast_slice", e), + } +} + +/// Cast `&mut [T]` into `&mut [U]`. +/// +/// ## Panics +/// +/// This is [`try_cast_slice_mut`] but will panic on error. +#[inline] +pub(crate) unsafe fn cast_slice_mut<A: Copy, B: Copy>(a: &mut [A]) -> &mut [B] { + match try_cast_slice_mut(a) { + Ok(b) => b, + Err(e) => something_went_wrong("cast_slice_mut", e), + } +} + +/// Try to cast `T` into `U`. +/// +/// Note that for this particular type of cast, alignment isn't a factor. The +/// input value is semantically copied into the function and then returned to a +/// new memory location which will have whatever the required alignment of the +/// output type is. +/// +/// ## Failure +/// +/// * If the types don't have the same size this fails. +#[inline] +pub(crate) unsafe fn try_cast<A: Copy, B: Copy>( + a: A, +) -> Result<B, PodCastError> { + if size_of::<A>() == size_of::<B>() { + Ok(unsafe { transmute!(a) }) + } else { + Err(PodCastError::SizeMismatch) + } +} + +/// Try to convert a `&T` into `&U`. +/// +/// ## Failure +/// +/// * If the reference isn't aligned in the new type +/// * If the source type and target type aren't the same size. +#[inline] +pub(crate) unsafe fn try_cast_ref<A: Copy, B: Copy>( + a: &A, +) -> Result<&B, PodCastError> { + // Note(Lokathor): everything with `align_of` and `size_of` will optimize away + // after monomorphization. + if align_of::<B>() > align_of::<A>() + && !is_aligned_to(a as *const A as *const (), align_of::<B>()) + { + Err(PodCastError::TargetAlignmentGreaterAndInputNotAligned) + } else if size_of::<B>() == size_of::<A>() { + Ok(unsafe { &*(a as *const A as *const B) }) + } else { + Err(PodCastError::SizeMismatch) + } +} + +/// Try to convert a `&mut T` into `&mut U`. +/// +/// As [`try_cast_ref`], but `mut`. +#[inline] +pub(crate) unsafe fn try_cast_mut<A: Copy, B: Copy>( + a: &mut A, +) -> Result<&mut B, PodCastError> { + // Note(Lokathor): everything with `align_of` and `size_of` will optimize away + // after monomorphization. + if align_of::<B>() > align_of::<A>() + && !is_aligned_to(a as *const A as *const (), align_of::<B>()) + { + Err(PodCastError::TargetAlignmentGreaterAndInputNotAligned) + } else if size_of::<B>() == size_of::<A>() { + Ok(unsafe { &mut *(a as *mut A as *mut B) }) + } else { + Err(PodCastError::SizeMismatch) + } +} + +/// Try to convert `&[A]` into `&[B]` (possibly with a change in length). +/// +/// * `input.as_ptr() as usize == output.as_ptr() as usize` +/// * `input.len() * size_of::<A>() == output.len() * size_of::<B>()` +/// +/// ## Failure +/// +/// * If the target type has a greater alignment requirement and the input slice +/// isn't aligned. +/// * If the target element type is a different size from the current element +/// type, and the output slice wouldn't be a whole number of elements when +/// accounting for the size change (eg: 3 `u16` values is 1.5 `u32` values, so +/// that's a failure). +/// * Similarly, you can't convert between a [ZST](https://doc.rust-lang.org/nomicon/exotic-sizes.html#zero-sized-types-zsts) +/// and a non-ZST. +#[inline] +pub(crate) unsafe fn try_cast_slice<A: Copy, B: Copy>( + a: &[A], +) -> Result<&[B], PodCastError> { + // Note(Lokathor): everything with `align_of` and `size_of` will optimize away + // after monomorphization. + if align_of::<B>() > align_of::<A>() + && !is_aligned_to(a.as_ptr() as *const (), align_of::<B>()) + { + Err(PodCastError::TargetAlignmentGreaterAndInputNotAligned) + } else if size_of::<B>() == size_of::<A>() { + Ok(unsafe { core::slice::from_raw_parts(a.as_ptr() as *const B, a.len()) }) + } else if size_of::<A>() == 0 || size_of::<B>() == 0 { + Err(PodCastError::SizeMismatch) + } else if core::mem::size_of_val(a) % size_of::<B>() == 0 { + let new_len = core::mem::size_of_val(a) / size_of::<B>(); + Ok(unsafe { core::slice::from_raw_parts(a.as_ptr() as *const B, new_len) }) + } else { + Err(PodCastError::OutputSliceWouldHaveSlop) + } +} + +/// Try to convert `&mut [A]` into `&mut [B]` (possibly with a change in +/// length). +/// +/// As [`try_cast_slice`], but `&mut`. +#[inline] +pub(crate) unsafe fn try_cast_slice_mut<A: Copy, B: Copy>( + a: &mut [A], +) -> Result<&mut [B], PodCastError> { + // Note(Lokathor): everything with `align_of` and `size_of` will optimize away + // after monomorphization. + if align_of::<B>() > align_of::<A>() + && !is_aligned_to(a.as_ptr() as *const (), align_of::<B>()) + { + Err(PodCastError::TargetAlignmentGreaterAndInputNotAligned) + } else if size_of::<B>() == size_of::<A>() { + Ok(unsafe { + core::slice::from_raw_parts_mut(a.as_mut_ptr() as *mut B, a.len()) + }) + } else if size_of::<A>() == 0 || size_of::<B>() == 0 { + Err(PodCastError::SizeMismatch) + } else if core::mem::size_of_val(a) % size_of::<B>() == 0 { + let new_len = core::mem::size_of_val(a) / size_of::<B>(); + Ok(unsafe { + core::slice::from_raw_parts_mut(a.as_mut_ptr() as *mut B, new_len) + }) + } else { + Err(PodCastError::OutputSliceWouldHaveSlop) + } +}
diff --git a/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/src/lib.rs b/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/src/lib.rs new file mode 100644 index 0000000..a810bb4 --- /dev/null +++ b/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/src/lib.rs
@@ -0,0 +1,508 @@ +#![no_std] +#![warn(missing_docs)] +#![allow(clippy::match_like_matches_macro)] +#![allow(clippy::uninlined_format_args)] +#![cfg_attr(feature = "nightly_docs", feature(doc_cfg))] +#![cfg_attr(feature = "nightly_portable_simd", feature(portable_simd))] +#![cfg_attr( + all( + feature = "nightly_stdsimd", + any(target_arch = "x86_64", target_arch = "x86") + ), + feature(stdarch_x86_avx512) +)] + +//! This crate gives small utilities for casting between plain data types. +//! +//! ## Basics +//! +//! Data comes in five basic forms in Rust, so we have five basic casting +//! functions: +//! +//! * `T` uses [`cast`] +//! * `&T` uses [`cast_ref`] +//! * `&mut T` uses [`cast_mut`] +//! * `&[T]` uses [`cast_slice`] +//! * `&mut [T]` uses [`cast_slice_mut`] +//! +//! Depending on the function, the [`NoUninit`] and/or [`AnyBitPattern`] traits +//! are used to maintain memory safety. +//! +//! **Historical Note:** When the crate first started the [`Pod`] trait was used +//! instead, and so you may hear people refer to that, but it has the strongest +//! requirements and people eventually wanted the more fine-grained system, so +//! here we are. All types that impl `Pod` have a blanket impl to also support +//! `NoUninit` and `AnyBitPattern`. The traits unfortunately do not have a +//! perfectly clean hierarchy for semver reasons. +//! +//! ## Failures +//! +//! Some casts will never fail, and other casts might fail. +//! +//! * `cast::<u32, f32>` always works (and [`f32::from_bits`]). +//! * `cast_ref::<[u8; 4], u32>` might fail if the specific array reference +//! given at runtime doesn't have alignment 4. +//! +//! In addition to the "normal" forms of each function, which will panic on +//! invalid input, there's also `try_` versions which will return a `Result`. +//! +//! If you would like to statically ensure that a cast will work at runtime you +//! can use the `must_cast` crate feature and the `must_` casting functions. A +//! "must cast" that can't be statically known to be valid will cause a +//! compilation error (and sometimes a very hard to read compilation error). +//! +//! ## Using Your Own Types +//! +//! All the functions listed above are guarded by the [`Pod`] trait, which is a +//! sub-trait of the [`Zeroable`] trait. +//! +//! If you enable the crate's `derive` feature then these traits can be derived +//! on your own types. The derive macros will perform the necessary checks on +//! your type declaration, and trigger an error if your type does not qualify. +//! +//! The derive macros might not cover all edge cases, and sometimes they will +//! error when actually everything is fine. As a last resort you can impl these +//! traits manually. However, these traits are `unsafe`, and you should +//! carefully read the requirements before using a manual implementation. +//! +//! ## Cargo Features +//! +//! The crate supports Rust 1.34 when no features are enabled, and so there's +//! cargo features for thing that you might consider "obvious". +//! +//! The cargo features **do not** promise any particular MSRV, and they may +//! increase their MSRV in new versions. +//! +//! * `derive`: Provide derive macros for the various traits. +//! * `extern_crate_alloc`: Provide utilities for `alloc` related types such as +//! Box and Vec. +//! * `zeroable_maybe_uninit` and `zeroable_atomics`: Provide more [`Zeroable`] +//! impls. +//! * `wasm_simd` and `aarch64_simd`: Support more SIMD types. +//! * `min_const_generics`: Provides appropriate impls for arrays of all lengths +//! instead of just for a select list of array lengths. +//! * `must_cast`: Provides the `must_` functions, which will compile error if +//! the requested cast can't be statically verified. + +#[cfg(all(target_arch = "aarch64", feature = "aarch64_simd"))] +use core::arch::aarch64; +#[cfg(all(target_arch = "wasm32", feature = "wasm_simd"))] +use core::arch::wasm32; +#[cfg(target_arch = "x86")] +use core::arch::x86; +#[cfg(target_arch = "x86_64")] +use core::arch::x86_64; +// +use core::{marker::*, mem::*, num::*, ptr::*}; + +// Used from macros to ensure we aren't using some locally defined name and +// actually are referencing libcore. This also would allow pre-2018 edition +// crates to use our macros, but I'm not sure how important that is. +#[doc(hidden)] +pub use ::core as __core; + +#[cfg(not(feature = "min_const_generics"))] +macro_rules! impl_unsafe_marker_for_array { + ( $marker:ident , $( $n:expr ),* ) => { + $(unsafe impl<T> $marker for [T; $n] where T: $marker {})* + } +} + +/// A macro to transmute between two types without requiring knowing size +/// statically. +macro_rules! transmute { + ($val:expr) => { + ::core::mem::transmute_copy(&::core::mem::ManuallyDrop::new($val)) + }; +} + +/// A macro to implement marker traits for various simd types. +/// #[allow(unused)] because the impls are only compiled on relevant platforms +/// with relevant cargo features enabled. +#[allow(unused)] +macro_rules! impl_unsafe_marker_for_simd { + ($(#[cfg($cfg_predicate:meta)])? unsafe impl $trait:ident for $platform:ident :: {}) => {}; + ($(#[cfg($cfg_predicate:meta)])? unsafe impl $trait:ident for $platform:ident :: { $first_type:ident $(, $types:ident)* $(,)? }) => { + $( #[cfg($cfg_predicate)] )? + $( #[cfg_attr(feature = "nightly_docs", doc(cfg($cfg_predicate)))] )? + unsafe impl $trait for $platform::$first_type {} + $( #[cfg($cfg_predicate)] )? // To prevent recursion errors if nothing is going to be expanded anyway. + impl_unsafe_marker_for_simd!($( #[cfg($cfg_predicate)] )? unsafe impl $trait for $platform::{ $( $types ),* }); + }; +} + +#[cfg(feature = "extern_crate_std")] +extern crate std; + +#[cfg(feature = "extern_crate_alloc")] +extern crate alloc; +#[cfg(feature = "extern_crate_alloc")] +#[cfg_attr(feature = "nightly_docs", doc(cfg(feature = "extern_crate_alloc")))] +pub mod allocation; +#[cfg(feature = "extern_crate_alloc")] +pub use allocation::*; + +mod anybitpattern; +pub use anybitpattern::*; + +pub mod checked; +pub use checked::CheckedBitPattern; + +mod internal; + +mod zeroable; +pub use zeroable::*; +mod zeroable_in_option; +pub use zeroable_in_option::*; + +mod pod; +pub use pod::*; +mod pod_in_option; +pub use pod_in_option::*; + +#[cfg(feature = "must_cast")] +mod must; +#[cfg(feature = "must_cast")] +#[cfg_attr(feature = "nightly_docs", doc(cfg(feature = "must_cast")))] +pub use must::*; + +mod no_uninit; +pub use no_uninit::*; + +mod contiguous; +pub use contiguous::*; + +mod offset_of; +// ^ no import, the module only has a macro_rules, which are cursed and don't +// follow normal import/export rules. + +mod transparent; +pub use transparent::*; + +#[cfg(feature = "derive")] +#[cfg_attr(feature = "nightly_docs", doc(cfg(feature = "derive")))] +pub use bytemuck_derive::{ + AnyBitPattern, ByteEq, ByteHash, CheckedBitPattern, Contiguous, NoUninit, + Pod, TransparentWrapper, Zeroable, +}; + +/// The things that can go wrong when casting between [`Pod`] data forms. +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub enum PodCastError { + /// You tried to cast a slice to an element type with a higher alignment + /// requirement but the slice wasn't aligned. + TargetAlignmentGreaterAndInputNotAligned, + /// If the element size changes then the output slice changes length + /// accordingly. If the output slice wouldn't be a whole number of elements + /// then the conversion fails. + OutputSliceWouldHaveSlop, + /// When casting a slice you can't convert between ZST elements and non-ZST + /// elements. When casting an individual `T`, `&T`, or `&mut T` value the + /// source size and destination size must be an exact match. + SizeMismatch, + /// For this type of cast the alignments must be exactly the same and they + /// were not so now you're sad. + /// + /// This error is generated **only** by operations that cast allocated types + /// (such as `Box` and `Vec`), because in that case the alignment must stay + /// exact. + AlignmentMismatch, +} +#[cfg(not(target_arch = "spirv"))] +impl core::fmt::Display for PodCastError { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{:?}", self) + } +} +#[cfg(feature = "extern_crate_std")] +#[cfg_attr(feature = "nightly_docs", doc(cfg(feature = "extern_crate_std")))] +impl std::error::Error for PodCastError {} + +/// Re-interprets `&T` as `&[u8]`. +/// +/// Any ZST becomes an empty slice, and in that case the pointer value of that +/// empty slice might not match the pointer value of the input reference. +#[inline] +pub fn bytes_of<T: NoUninit>(t: &T) -> &[u8] { + unsafe { internal::bytes_of(t) } +} + +/// Re-interprets `&mut T` as `&mut [u8]`. +/// +/// Any ZST becomes an empty slice, and in that case the pointer value of that +/// empty slice might not match the pointer value of the input reference. +#[inline] +pub fn bytes_of_mut<T: NoUninit + AnyBitPattern>(t: &mut T) -> &mut [u8] { + unsafe { internal::bytes_of_mut(t) } +} + +/// Re-interprets `&[u8]` as `&T`. +/// +/// ## Panics +/// +/// This is like [`try_from_bytes`] but will panic on error. +#[inline] +pub fn from_bytes<T: AnyBitPattern>(s: &[u8]) -> &T { + unsafe { internal::from_bytes(s) } +} + +/// Re-interprets `&mut [u8]` as `&mut T`. +/// +/// ## Panics +/// +/// This is like [`try_from_bytes_mut`] but will panic on error. +#[inline] +pub fn from_bytes_mut<T: NoUninit + AnyBitPattern>(s: &mut [u8]) -> &mut T { + unsafe { internal::from_bytes_mut(s) } +} + +/// Reads from the bytes as if they were a `T`. +/// +/// Unlike [`from_bytes`], the slice doesn't need to respect alignment of `T`, +/// only sizes must match. +/// +/// ## Failure +/// * If the `bytes` length is not equal to `size_of::<T>()`. +#[inline] +pub fn try_pod_read_unaligned<T: AnyBitPattern>( + bytes: &[u8], +) -> Result<T, PodCastError> { + unsafe { internal::try_pod_read_unaligned(bytes) } +} + +/// Reads the slice into a `T` value. +/// +/// Unlike [`from_bytes`], the slice doesn't need to respect alignment of `T`, +/// only sizes must match. +/// +/// ## Panics +/// * This is like `try_pod_read_unaligned` but will panic on failure. +#[inline] +pub fn pod_read_unaligned<T: AnyBitPattern>(bytes: &[u8]) -> T { + unsafe { internal::pod_read_unaligned(bytes) } +} + +/// Re-interprets `&[u8]` as `&T`. +/// +/// ## Failure +/// +/// * If the slice isn't aligned for the new type +/// * If the slice's length isn’t exactly the size of the new type +#[inline] +pub fn try_from_bytes<T: AnyBitPattern>(s: &[u8]) -> Result<&T, PodCastError> { + unsafe { internal::try_from_bytes(s) } +} + +/// Re-interprets `&mut [u8]` as `&mut T`. +/// +/// ## Failure +/// +/// * If the slice isn't aligned for the new type +/// * If the slice's length isn’t exactly the size of the new type +#[inline] +pub fn try_from_bytes_mut<T: NoUninit + AnyBitPattern>( + s: &mut [u8], +) -> Result<&mut T, PodCastError> { + unsafe { internal::try_from_bytes_mut(s) } +} + +/// Cast `T` into `U` +/// +/// ## Panics +/// +/// * This is like [`try_cast`], but will panic on a size mismatch. +#[inline] +pub fn cast<A: NoUninit, B: AnyBitPattern>(a: A) -> B { + unsafe { internal::cast(a) } +} + +/// Cast `&mut T` into `&mut U`. +/// +/// ## Panics +/// +/// This is [`try_cast_mut`] but will panic on error. +#[inline] +pub fn cast_mut<A: NoUninit + AnyBitPattern, B: NoUninit + AnyBitPattern>( + a: &mut A, +) -> &mut B { + unsafe { internal::cast_mut(a) } +} + +/// Cast `&T` into `&U`. +/// +/// ## Panics +/// +/// This is [`try_cast_ref`] but will panic on error. +#[inline] +pub fn cast_ref<A: NoUninit, B: AnyBitPattern>(a: &A) -> &B { + unsafe { internal::cast_ref(a) } +} + +/// Cast `&[A]` into `&[B]`. +/// +/// ## Panics +/// +/// This is [`try_cast_slice`] but will panic on error. +#[inline] +pub fn cast_slice<A: NoUninit, B: AnyBitPattern>(a: &[A]) -> &[B] { + unsafe { internal::cast_slice(a) } +} + +/// Cast `&mut [T]` into `&mut [U]`. +/// +/// ## Panics +/// +/// This is [`try_cast_slice_mut`] but will panic on error. +#[inline] +pub fn cast_slice_mut< + A: NoUninit + AnyBitPattern, + B: NoUninit + AnyBitPattern, +>( + a: &mut [A], +) -> &mut [B] { + unsafe { internal::cast_slice_mut(a) } +} + +/// As [`align_to`](https://doc.rust-lang.org/std/primitive.slice.html#method.align_to), +/// but safe because of the [`Pod`] bound. +#[inline] +pub fn pod_align_to<T: NoUninit, U: AnyBitPattern>( + vals: &[T], +) -> (&[T], &[U], &[T]) { + unsafe { vals.align_to::<U>() } +} + +/// As [`align_to_mut`](https://doc.rust-lang.org/std/primitive.slice.html#method.align_to_mut), +/// but safe because of the [`Pod`] bound. +#[inline] +pub fn pod_align_to_mut< + T: NoUninit + AnyBitPattern, + U: NoUninit + AnyBitPattern, +>( + vals: &mut [T], +) -> (&mut [T], &mut [U], &mut [T]) { + unsafe { vals.align_to_mut::<U>() } +} + +/// Try to cast `T` into `U`. +/// +/// Note that for this particular type of cast, alignment isn't a factor. The +/// input value is semantically copied into the function and then returned to a +/// new memory location which will have whatever the required alignment of the +/// output type is. +/// +/// ## Failure +/// +/// * If the types don't have the same size this fails. +#[inline] +pub fn try_cast<A: NoUninit, B: AnyBitPattern>( + a: A, +) -> Result<B, PodCastError> { + unsafe { internal::try_cast(a) } +} + +/// Try to convert a `&T` into `&U`. +/// +/// ## Failure +/// +/// * If the reference isn't aligned in the new type +/// * If the source type and target type aren't the same size. +#[inline] +pub fn try_cast_ref<A: NoUninit, B: AnyBitPattern>( + a: &A, +) -> Result<&B, PodCastError> { + unsafe { internal::try_cast_ref(a) } +} + +/// Try to convert a `&mut T` into `&mut U`. +/// +/// As [`try_cast_ref`], but `mut`. +#[inline] +pub fn try_cast_mut< + A: NoUninit + AnyBitPattern, + B: NoUninit + AnyBitPattern, +>( + a: &mut A, +) -> Result<&mut B, PodCastError> { + unsafe { internal::try_cast_mut(a) } +} + +/// Try to convert `&[A]` into `&[B]` (possibly with a change in length). +/// +/// * `input.as_ptr() as usize == output.as_ptr() as usize` +/// * `input.len() * size_of::<A>() == output.len() * size_of::<B>()` +/// +/// ## Failure +/// +/// * If the target type has a greater alignment requirement and the input slice +/// isn't aligned. +/// * If the target element type is a different size from the current element +/// type, and the output slice wouldn't be a whole number of elements when +/// accounting for the size change (eg: 3 `u16` values is 1.5 `u32` values, so +/// that's a failure). +/// * Similarly, you can't convert between a [ZST](https://doc.rust-lang.org/nomicon/exotic-sizes.html#zero-sized-types-zsts) +/// and a non-ZST. +#[inline] +pub fn try_cast_slice<A: NoUninit, B: AnyBitPattern>( + a: &[A], +) -> Result<&[B], PodCastError> { + unsafe { internal::try_cast_slice(a) } +} + +/// Try to convert `&mut [A]` into `&mut [B]` (possibly with a change in +/// length). +/// +/// As [`try_cast_slice`], but `&mut`. +#[inline] +pub fn try_cast_slice_mut< + A: NoUninit + AnyBitPattern, + B: NoUninit + AnyBitPattern, +>( + a: &mut [A], +) -> Result<&mut [B], PodCastError> { + unsafe { internal::try_cast_slice_mut(a) } +} + +/// Fill all bytes of `target` with zeroes (see [`Zeroable`]). +/// +/// This is similar to `*target = Zeroable::zeroed()`, but guarantees that any +/// padding bytes in `target` are zeroed as well. +/// +/// See also [`fill_zeroes`], if you have a slice rather than a single value. +#[inline] +pub fn write_zeroes<T: Zeroable>(target: &mut T) { + struct EnsureZeroWrite<T>(*mut T); + impl<T> Drop for EnsureZeroWrite<T> { + #[inline(always)] + fn drop(&mut self) { + unsafe { + core::ptr::write_bytes(self.0, 0u8, 1); + } + } + } + unsafe { + let guard = EnsureZeroWrite(target); + core::ptr::drop_in_place(guard.0); + drop(guard); + } +} + +/// Fill all bytes of `slice` with zeroes (see [`Zeroable`]). +/// +/// This is similar to `slice.fill(Zeroable::zeroed())`, but guarantees that any +/// padding bytes in `slice` are zeroed as well. +/// +/// See also [`write_zeroes`], which zeroes all bytes of a single value rather +/// than a slice. +#[inline] +pub fn fill_zeroes<T: Zeroable>(slice: &mut [T]) { + if core::mem::needs_drop::<T>() { + // If `T` needs to be dropped then we have to do this one item at a time, in + // case one of the intermediate drops does a panic. + slice.iter_mut().for_each(write_zeroes); + } else { + // Otherwise we can be really fast and just fill everthing with zeros. + let len = core::mem::size_of_val::<[T]>(slice); + unsafe { core::ptr::write_bytes(slice.as_mut_ptr() as *mut u8, 0u8, len) } + } +}
diff --git a/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/src/must.rs b/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/src/must.rs new file mode 100644 index 0000000..8373e711 --- /dev/null +++ b/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/src/must.rs
@@ -0,0 +1,203 @@ +#![allow(clippy::module_name_repetitions)] +#![allow(clippy::let_unit_value)] +#![allow(clippy::let_underscore_untyped)] +#![allow(clippy::ptr_as_ptr)] + +use crate::{AnyBitPattern, NoUninit}; +use core::mem::{align_of, size_of}; + +struct Cast<A, B>((A, B)); +impl<A, B> Cast<A, B> { + const ASSERT_ALIGN_GREATER_THAN_EQUAL: () = + assert!(align_of::<A>() >= align_of::<B>()); + const ASSERT_SIZE_EQUAL: () = assert!(size_of::<A>() == size_of::<B>()); + const ASSERT_SIZE_MULTIPLE_OF: () = assert!( + (size_of::<A>() == 0) == (size_of::<B>() == 0) + && (size_of::<A>() % size_of::<B>() == 0) + ); +} + +// Workaround for https://github.com/rust-lang/miri/issues/2423. +// Miri currently doesn't see post-monomorphization errors until runtime, +// so `compile_fail` tests relying on post-monomorphization errors don't +// actually fail. Instead use `should_panic` under miri as a workaround. +#[cfg(miri)] +macro_rules! post_mono_compile_fail_doctest { + () => { + "```should_panic" + }; +} +#[cfg(not(miri))] +macro_rules! post_mono_compile_fail_doctest { + () => { + "```compile_fail,E0080" + }; +} + +/// Cast `A` into `B` if infalliable, or fail to compile. +/// +/// Note that for this particular type of cast, alignment isn't a factor. The +/// input value is semantically copied into the function and then returned to a +/// new memory location which will have whatever the required alignment of the +/// output type is. +/// +/// ## Failure +/// +/// * If the types don't have the same size this fails to compile. +/// +/// ## Examples +/// ``` +/// // compiles: +/// let bytes: [u8; 2] = bytemuck::must_cast(12_u16); +/// ``` +#[doc = post_mono_compile_fail_doctest!()] +/// // fails to compile (size mismatch): +/// let bytes : [u8; 3] = bytemuck::must_cast(12_u16); +/// ``` +#[inline] +pub fn must_cast<A: NoUninit, B: AnyBitPattern>(a: A) -> B { + let _ = Cast::<A, B>::ASSERT_SIZE_EQUAL; + unsafe { transmute!(a) } +} + +/// Convert `&A` into `&B` if infalliable, or fail to compile. +/// +/// ## Failure +/// +/// * If the target type has a greater alignment requirement. +/// * If the source type and target type aren't the same size. +/// +/// ## Examples +/// ``` +/// // compiles: +/// let bytes: &[u8; 2] = bytemuck::must_cast_ref(&12_u16); +/// ``` +#[doc = post_mono_compile_fail_doctest!()] +/// // fails to compile (size mismatch): +/// let bytes : &[u8; 3] = bytemuck::must_cast_ref(&12_u16); +/// ``` +#[doc = post_mono_compile_fail_doctest!()] +/// // fails to compile (alignment requirements increased): +/// let bytes : &u16 = bytemuck::must_cast_ref(&[1u8, 2u8]); +/// ``` +#[inline] +pub fn must_cast_ref<A: NoUninit, B: AnyBitPattern>(a: &A) -> &B { + let _ = Cast::<A, B>::ASSERT_SIZE_EQUAL; + let _ = Cast::<A, B>::ASSERT_ALIGN_GREATER_THAN_EQUAL; + unsafe { &*(a as *const A as *const B) } +} + +/// Convert a `&mut A` into `&mut B` if infalliable, or fail to compile. +/// +/// As [`must_cast_ref`], but `mut`. +/// +/// ## Examples +/// ``` +/// let mut i = 12_u16; +/// // compiles: +/// let bytes: &mut [u8; 2] = bytemuck::must_cast_mut(&mut i); +/// ``` +#[doc = post_mono_compile_fail_doctest!()] +/// # let mut bytes: &mut [u8; 2] = &mut [1, 2]; +/// // fails to compile (alignment requirements increased): +/// let i : &mut u16 = bytemuck::must_cast_mut(bytes); +/// ``` +#[doc = post_mono_compile_fail_doctest!()] +/// # let mut i = 12_u16; +/// // fails to compile (size mismatch): +/// let bytes : &mut [u8; 3] = bytemuck::must_cast_mut(&mut i); +/// ``` +#[inline] +pub fn must_cast_mut< + A: NoUninit + AnyBitPattern, + B: NoUninit + AnyBitPattern, +>( + a: &mut A, +) -> &mut B { + let _ = Cast::<A, B>::ASSERT_SIZE_EQUAL; + let _ = Cast::<A, B>::ASSERT_ALIGN_GREATER_THAN_EQUAL; + unsafe { &mut *(a as *mut A as *mut B) } +} + +/// Convert `&[A]` into `&[B]` (possibly with a change in length) if +/// infalliable, or fail to compile. +/// +/// * `input.as_ptr() as usize == output.as_ptr() as usize` +/// * `input.len() * size_of::<A>() == output.len() * size_of::<B>()` +/// +/// ## Failure +/// +/// * If the target type has a greater alignment requirement. +/// * If the target element type doesn't evenly fit into the the current element +/// type (eg: 3 `u16` values is 1.5 `u32` values, so that's a failure). +/// * Similarly, you can't convert between a [ZST](https://doc.rust-lang.org/nomicon/exotic-sizes.html#zero-sized-types-zsts) +/// and a non-ZST. +/// +/// ## Examples +/// ``` +/// let indicies: &[u16] = &[1, 2, 3]; +/// // compiles: +/// let bytes: &[u8] = bytemuck::must_cast_slice(indicies); +/// ``` +#[doc = post_mono_compile_fail_doctest!()] +/// # let bytes : &[u8] = &[1, 0, 2, 0, 3, 0]; +/// // fails to compile (bytes.len() might not be a multiple of 2): +/// let byte_pairs : &[[u8; 2]] = bytemuck::must_cast_slice(bytes); +/// ``` +#[doc = post_mono_compile_fail_doctest!()] +/// # let byte_pairs : &[[u8; 2]] = &[[1, 0], [2, 0], [3, 0]]; +/// // fails to compile (alignment requirements increased): +/// let indicies : &[u16] = bytemuck::must_cast_slice(byte_pairs); +/// ``` +#[inline] +pub fn must_cast_slice<A: NoUninit, B: AnyBitPattern>(a: &[A]) -> &[B] { + let _ = Cast::<A, B>::ASSERT_SIZE_MULTIPLE_OF; + let _ = Cast::<A, B>::ASSERT_ALIGN_GREATER_THAN_EQUAL; + let new_len = if size_of::<A>() == size_of::<B>() { + a.len() + } else { + a.len() * (size_of::<A>() / size_of::<B>()) + }; + unsafe { core::slice::from_raw_parts(a.as_ptr() as *const B, new_len) } +} + +/// Convert `&mut [A]` into `&mut [B]` (possibly with a change in length) if +/// infalliable, or fail to compile. +/// +/// As [`must_cast_slice`], but `&mut`. +/// +/// ## Examples +/// ``` +/// let mut indicies = [1, 2, 3]; +/// let indicies: &mut [u16] = &mut indicies; +/// // compiles: +/// let bytes: &mut [u8] = bytemuck::must_cast_slice_mut(indicies); +/// ``` +#[doc = post_mono_compile_fail_doctest!()] +/// # let mut bytes = [1, 0, 2, 0, 3, 0]; +/// # let bytes : &mut [u8] = &mut bytes[..]; +/// // fails to compile (bytes.len() might not be a multiple of 2): +/// let byte_pairs : &mut [[u8; 2]] = bytemuck::must_cast_slice_mut(bytes); +/// ``` +#[doc = post_mono_compile_fail_doctest!()] +/// # let mut byte_pairs = [[1, 0], [2, 0], [3, 0]]; +/// # let byte_pairs : &mut [[u8; 2]] = &mut byte_pairs[..]; +/// // fails to compile (alignment requirements increased): +/// let indicies : &mut [u16] = bytemuck::must_cast_slice_mut(byte_pairs); +/// ``` +#[inline] +pub fn must_cast_slice_mut< + A: NoUninit + AnyBitPattern, + B: NoUninit + AnyBitPattern, +>( + a: &mut [A], +) -> &mut [B] { + let _ = Cast::<A, B>::ASSERT_SIZE_MULTIPLE_OF; + let _ = Cast::<A, B>::ASSERT_ALIGN_GREATER_THAN_EQUAL; + let new_len = if size_of::<A>() == size_of::<B>() { + a.len() + } else { + a.len() * (size_of::<A>() / size_of::<B>()) + }; + unsafe { core::slice::from_raw_parts_mut(a.as_mut_ptr() as *mut B, new_len) } +}
diff --git a/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/src/no_uninit.rs b/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/src/no_uninit.rs new file mode 100644 index 0000000..5fda0c9 --- /dev/null +++ b/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/src/no_uninit.rs
@@ -0,0 +1,80 @@ +use crate::Pod; +use core::num::{ + NonZeroI128, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8, NonZeroIsize, + NonZeroU128, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize, +}; + +/// Marker trait for "plain old data" types with no uninit (or padding) bytes. +/// +/// The requirements for this is very similar to [`Pod`], +/// except that it doesn't require that all bit patterns of the type are valid, +/// i.e. it does not require the type to be [`Zeroable`][crate::Zeroable]. +/// This limits what you can do with a type of this kind, but also broadens the +/// included types to things like C-style enums. Notably, you can only cast from +/// *immutable* references to a [`NoUninit`] type into *immutable* references of +/// any other type, no casting of mutable references or mutable references to +/// slices etc. +/// +/// [`Pod`] is a subset of [`NoUninit`], meaning that any `T: Pod` is also +/// [`NoUninit`] but any `T: NoUninit` is not necessarily [`Pod`]. If possible, +/// prefer implementing [`Pod`] directly. To get more [`Pod`]-like functionality +/// for a type that is only [`NoUninit`], consider also implementing +/// [`CheckedBitPattern`][crate::CheckedBitPattern]. +/// +/// # Derive +/// +/// A `#[derive(NoUninit)]` macro is provided under the `derive` feature flag +/// which will automatically validate the requirements of this trait and +/// implement the trait for you for both enums and structs. This is the +/// recommended method for implementing the trait, however it's also possible to +/// do manually. If you implement it manually, you *must* carefully follow the +/// below safety rules. +/// +/// # Safety +/// +/// The same as [`Pod`] except we disregard the rule about it must +/// allow any bit pattern (i.e. it does not need to be +/// [`Zeroable`][crate::Zeroable]). Still, this is a quite strong guarantee +/// about a type, so *be careful* whem implementing it manually. +/// +/// * The type must be inhabited (eg: no +/// [Infallible](core::convert::Infallible)). +/// * The type must not contain any uninit (or padding) bytes, either in the +/// middle or on the end (eg: no `#[repr(C)] struct Foo(u8, u16)`, which has +/// padding in the middle, and also no `#[repr(C)] struct Foo(u16, u8)`, which +/// has padding on the end). +/// * Structs need to have all fields also be `NoUninit`. +/// * Structs need to be `repr(C)` or `repr(transparent)`. In the case of +/// `repr(C)`, the `packed` and `align` repr modifiers can be used as long as +/// all other rules end up being followed. +/// * Enums need to have an explicit `#[repr(Int)]` +/// * Enums must have only fieldless variants +/// * It is disallowed for types to contain pointer types, `Cell`, `UnsafeCell`, +/// atomics, and any other forms of interior mutability. +/// * More precisely: A shared reference to the type must allow reads, and +/// *only* reads. RustBelt's separation logic is based on the notion that a +/// type is allowed to define a sharing predicate, its own invariant that must +/// hold for shared references, and this predicate is the reasoning that allow +/// it to deal with atomic and cells etc. We require the sharing predicate to +/// be trivial and permit only read-only access. +/// * There's probably more, don't mess it up (I mean it). +pub unsafe trait NoUninit: Sized + Copy + 'static {} + +unsafe impl<T: Pod> NoUninit for T {} + +unsafe impl NoUninit for char {} + +unsafe impl NoUninit for bool {} + +unsafe impl NoUninit for NonZeroU8 {} +unsafe impl NoUninit for NonZeroI8 {} +unsafe impl NoUninit for NonZeroU16 {} +unsafe impl NoUninit for NonZeroI16 {} +unsafe impl NoUninit for NonZeroU32 {} +unsafe impl NoUninit for NonZeroI32 {} +unsafe impl NoUninit for NonZeroU64 {} +unsafe impl NoUninit for NonZeroI64 {} +unsafe impl NoUninit for NonZeroU128 {} +unsafe impl NoUninit for NonZeroI128 {} +unsafe impl NoUninit for NonZeroUsize {} +unsafe impl NoUninit for NonZeroIsize {}
diff --git a/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/src/offset_of.rs b/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/src/offset_of.rs new file mode 100644 index 0000000..7e8aedfd --- /dev/null +++ b/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/src/offset_of.rs
@@ -0,0 +1,135 @@ +#![forbid(unsafe_code)] + +/// Find the offset in bytes of the given `$field` of `$Type`. Requires an +/// already initialized `$instance` value to work with. +/// +/// This is similar to the macro from [`memoffset`](https://docs.rs/memoffset), +/// however it uses no `unsafe` code. +/// +/// This macro has a 3-argument and 2-argument version. +/// * In the 3-arg version you specify an instance of the type, the type itself, +/// and the field name. +/// * In the 2-arg version the macro will call the [`default`](Default::default) +/// method to make a temporary instance of the type for you. +/// +/// The output of this macro is the byte offset of the field (as a `usize`). The +/// calculations of the macro are fixed across the entire program, but if the +/// type used is `repr(Rust)` then they're *not* fixed across compilations or +/// compilers. +/// +/// ## Examples +/// +/// ### 3-arg Usage +/// +/// ```rust +/// # use bytemuck::offset_of; +/// // enums can't derive default, and for this example we don't pick one +/// enum MyExampleEnum { +/// A, +/// B, +/// C, +/// } +/// +/// // so now our struct here doesn't have Default +/// #[repr(C)] +/// struct MyNotDefaultType { +/// pub counter: i32, +/// pub some_field: MyExampleEnum, +/// } +/// +/// // but we provide an instance of the type and it's all good. +/// let val = MyNotDefaultType { counter: 5, some_field: MyExampleEnum::A }; +/// assert_eq!(offset_of!(val, MyNotDefaultType, some_field), 4); +/// ``` +/// +/// ### 2-arg Usage +/// +/// ```rust +/// # use bytemuck::offset_of; +/// #[derive(Default)] +/// #[repr(C)] +/// struct Vertex { +/// pub loc: [f32; 3], +/// pub color: [f32; 3], +/// } +/// // if the type impls Default the macro can make its own default instance. +/// assert_eq!(offset_of!(Vertex, loc), 0); +/// assert_eq!(offset_of!(Vertex, color), 12); +/// ``` +/// +/// # Usage with `#[repr(packed)]` structs +/// +/// Attempting to compute the offset of a `#[repr(packed)]` struct with +/// `bytemuck::offset_of!` requires an `unsafe` block. We hope to relax this in +/// the future, but currently it is required to work around a soundness hole in +/// Rust (See [rust-lang/rust#27060]). +/// +/// [rust-lang/rust#27060]: https://github.com/rust-lang/rust/issues/27060 +/// +/// <p style="background:rgba(255,181,77,0.16);padding:0.75em;"> +/// <strong>Warning:</strong> This is only true for versions of bytemuck > +/// 1.4.0. Previous versions of +/// <code style="background:rgba(41,24,0,0.1);">bytemuck::offset_of!</code> +/// will only emit a warning when used on the field of a packed struct in safe +/// code, which can lead to unsoundness. +/// </p> +/// +/// For example, the following will fail to compile: +/// +/// ```compile_fail +/// #[repr(C, packed)] +/// #[derive(Default)] +/// struct Example { +/// field: u32, +/// } +/// // Doesn't compile: +/// let _offset = bytemuck::offset_of!(Example, field); +/// ``` +/// +/// While the error message this generates will mention the +/// `safe_packed_borrows` lint, the macro will still fail to compile even if +/// that lint is `#[allow]`ed: +/// +/// ```compile_fail +/// # #[repr(C, packed)] #[derive(Default)] struct Example { field: u32 } +/// // Still doesn't compile: +/// #[allow(safe_packed_borrows)] +/// { +/// let _offset = bytemuck::offset_of!(Example, field); +/// } +/// ``` +/// +/// This *can* be worked around by using `unsafe`, but it is only sound to do so +/// if you can guarantee that taking a reference to the field is sound. +/// +/// In practice, this means it only works for fields of align(1) types, or if +/// you know the field's offset in advance (defeating the point of `offset_of`) +/// and can prove that the struct's alignment and the field's offset are enough +/// to prove the field's alignment. +/// +/// Once the `raw_ref` macros are available, a future version of this crate will +/// use them to lift the limitations of packed structs. For the duration of the +/// `1.x` version of this crate that will be behind an on-by-default cargo +/// feature (to maintain minimum rust version support). +#[macro_export] +macro_rules! offset_of { + ($instance:expr, $Type:path, $field:tt) => {{ + #[forbid(safe_packed_borrows)] + { + // This helps us guard against field access going through a Deref impl. + #[allow(clippy::unneeded_field_pattern)] + let $Type { $field: _, .. }; + let reference: &$Type = &$instance; + let address = reference as *const _ as usize; + let field_pointer = &reference.$field as *const _ as usize; + // These asserts/unwraps are compiled away at release, and defend against + // the case where somehow a deref impl is still invoked. + let result = field_pointer.checked_sub(address).unwrap(); + assert!(result <= $crate::__core::mem::size_of::<$Type>()); + result + } + }}; + ($Type:path, $field:tt) => {{ + $crate::offset_of!(<$Type as Default>::default(), $Type, $field) + }}; +}
diff --git a/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/src/pod.rs b/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/src/pod.rs new file mode 100644 index 0000000..2cec1c2 --- /dev/null +++ b/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/src/pod.rs
@@ -0,0 +1,165 @@ +use super::*; + +/// Marker trait for "plain old data". +/// +/// The point of this trait is that once something is marked "plain old data" +/// you can really go to town with the bit fiddling and bit casting. Therefore, +/// it's a relatively strong claim to make about a type. Do not add this to your +/// type casually. +/// +/// **Reminder:** The results of casting around bytes between data types are +/// _endian dependant_. Little-endian machines are the most common, but +/// big-endian machines do exist (and big-endian is also used for "network +/// order" bytes). +/// +/// ## Safety +/// +/// * The type must be inhabited (eg: no +/// [Infallible](core::convert::Infallible)). +/// * The type must allow any bit pattern (eg: no `bool` or `char`, which have +/// illegal bit patterns). +/// * The type must not contain any uninit (or padding) bytes, either in the +/// middle or on the end (eg: no `#[repr(C)] struct Foo(u8, u16)`, which has +/// padding in the middle, and also no `#[repr(C)] struct Foo(u16, u8)`, which +/// has padding on the end). +/// * The type needs to have all fields also be `Pod`. +/// * The type needs to be `repr(C)` or `repr(transparent)`. In the case of +/// `repr(C)`, the `packed` and `align` repr modifiers can be used as long as +/// all other rules end up being followed. +/// * It is disallowed for types to contain pointer types, `Cell`, `UnsafeCell`, +/// atomics, and any other forms of interior mutability. +/// * More precisely: A shared reference to the type must allow reads, and +/// *only* reads. RustBelt's separation logic is based on the notion that a +/// type is allowed to define a sharing predicate, its own invariant that must +/// hold for shared references, and this predicate is the reasoning that allow +/// it to deal with atomic and cells etc. We require the sharing predicate to +/// be trivial and permit only read-only access. +pub unsafe trait Pod: Zeroable + Copy + 'static {} + +unsafe impl Pod for () {} +unsafe impl Pod for u8 {} +unsafe impl Pod for i8 {} +unsafe impl Pod for u16 {} +unsafe impl Pod for i16 {} +unsafe impl Pod for u32 {} +unsafe impl Pod for i32 {} +unsafe impl Pod for u64 {} +unsafe impl Pod for i64 {} +unsafe impl Pod for usize {} +unsafe impl Pod for isize {} +unsafe impl Pod for u128 {} +unsafe impl Pod for i128 {} +unsafe impl Pod for f32 {} +unsafe impl Pod for f64 {} +unsafe impl<T: Pod> Pod for Wrapping<T> {} + +#[cfg(feature = "unsound_ptr_pod_impl")] +#[cfg_attr( + feature = "nightly_docs", + doc(cfg(feature = "unsound_ptr_pod_impl")) +)] +unsafe impl<T: 'static> Pod for *mut T {} +#[cfg(feature = "unsound_ptr_pod_impl")] +#[cfg_attr( + feature = "nightly_docs", + doc(cfg(feature = "unsound_ptr_pod_impl")) +)] +unsafe impl<T: 'static> Pod for *const T {} +#[cfg(feature = "unsound_ptr_pod_impl")] +#[cfg_attr( + feature = "nightly_docs", + doc(cfg(feature = "unsound_ptr_pod_impl")) +)] +unsafe impl<T: 'static> PodInOption for NonNull<T> {} + +unsafe impl<T: ?Sized + 'static> Pod for PhantomData<T> {} +unsafe impl Pod for PhantomPinned {} +unsafe impl<T: Pod> Pod for ManuallyDrop<T> {} + +// Note(Lokathor): MaybeUninit can NEVER be Pod. + +#[cfg(feature = "min_const_generics")] +#[cfg_attr(feature = "nightly_docs", doc(cfg(feature = "min_const_generics")))] +unsafe impl<T, const N: usize> Pod for [T; N] where T: Pod {} + +#[cfg(not(feature = "min_const_generics"))] +impl_unsafe_marker_for_array!( + Pod, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 48, 64, 96, 128, 256, + 512, 1024, 2048, 4096 +); + +impl_unsafe_marker_for_simd!( + #[cfg(all(target_arch = "wasm32", feature = "wasm_simd"))] + unsafe impl Pod for wasm32::{v128} +); + +impl_unsafe_marker_for_simd!( + #[cfg(all(target_arch = "aarch64", feature = "aarch64_simd"))] + unsafe impl Pod for aarch64::{ + float32x2_t, float32x2x2_t, float32x2x3_t, float32x2x4_t, float32x4_t, + float32x4x2_t, float32x4x3_t, float32x4x4_t, float64x1_t, float64x1x2_t, + float64x1x3_t, float64x1x4_t, float64x2_t, float64x2x2_t, float64x2x3_t, + float64x2x4_t, int16x4_t, int16x4x2_t, int16x4x3_t, int16x4x4_t, int16x8_t, + int16x8x2_t, int16x8x3_t, int16x8x4_t, int32x2_t, int32x2x2_t, int32x2x3_t, + int32x2x4_t, int32x4_t, int32x4x2_t, int32x4x3_t, int32x4x4_t, int64x1_t, + int64x1x2_t, int64x1x3_t, int64x1x4_t, int64x2_t, int64x2x2_t, int64x2x3_t, + int64x2x4_t, int8x16_t, int8x16x2_t, int8x16x3_t, int8x16x4_t, int8x8_t, + int8x8x2_t, int8x8x3_t, int8x8x4_t, poly16x4_t, poly16x4x2_t, poly16x4x3_t, + poly16x4x4_t, poly16x8_t, poly16x8x2_t, poly16x8x3_t, poly16x8x4_t, + poly64x1_t, poly64x1x2_t, poly64x1x3_t, poly64x1x4_t, poly64x2_t, + poly64x2x2_t, poly64x2x3_t, poly64x2x4_t, poly8x16_t, poly8x16x2_t, + poly8x16x3_t, poly8x16x4_t, poly8x8_t, poly8x8x2_t, poly8x8x3_t, poly8x8x4_t, + uint16x4_t, uint16x4x2_t, uint16x4x3_t, uint16x4x4_t, uint16x8_t, + uint16x8x2_t, uint16x8x3_t, uint16x8x4_t, uint32x2_t, uint32x2x2_t, + uint32x2x3_t, uint32x2x4_t, uint32x4_t, uint32x4x2_t, uint32x4x3_t, + uint32x4x4_t, uint64x1_t, uint64x1x2_t, uint64x1x3_t, uint64x1x4_t, + uint64x2_t, uint64x2x2_t, uint64x2x3_t, uint64x2x4_t, uint8x16_t, + uint8x16x2_t, uint8x16x3_t, uint8x16x4_t, uint8x8_t, uint8x8x2_t, + uint8x8x3_t, uint8x8x4_t, + } +); + +impl_unsafe_marker_for_simd!( + #[cfg(target_arch = "x86")] + unsafe impl Pod for x86::{ + __m128i, __m128, __m128d, + __m256i, __m256, __m256d, + } +); + +impl_unsafe_marker_for_simd!( + #[cfg(target_arch = "x86_64")] + unsafe impl Pod for x86_64::{ + __m128i, __m128, __m128d, + __m256i, __m256, __m256d, + } +); + +#[cfg(feature = "nightly_portable_simd")] +#[cfg_attr( + feature = "nightly_docs", + doc(cfg(feature = "nightly_portable_simd")) +)] +unsafe impl<T, const N: usize> Pod for core::simd::Simd<T, N> +where + T: core::simd::SimdElement + Pod, + core::simd::LaneCount<N>: core::simd::SupportedLaneCount, +{ +} + +impl_unsafe_marker_for_simd!( + #[cfg(all(target_arch = "x86", feature = "nightly_stdsimd"))] + unsafe impl Pod for x86::{ + __m128bh, __m256bh, __m512, + __m512bh, __m512d, __m512i, + } +); + +impl_unsafe_marker_for_simd!( + #[cfg(all(target_arch = "x86_64", feature = "nightly_stdsimd"))] + unsafe impl Pod for x86_64::{ + __m128bh, __m256bh, __m512, + __m512bh, __m512d, __m512i, + } +);
diff --git a/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/src/pod_in_option.rs b/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/src/pod_in_option.rs new file mode 100644 index 0000000..3327e99 --- /dev/null +++ b/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/src/pod_in_option.rs
@@ -0,0 +1,27 @@ +use super::*; + +// Note(Lokathor): This is the neat part!! +unsafe impl<T: PodInOption> Pod for Option<T> {} + +/// Trait for types which are [Pod](Pod) when wrapped in +/// [Option](core::option::Option). +/// +/// ## Safety +/// +/// * `Option<T>` must uphold the same invariants as [Pod](Pod). +/// * **Reminder:** pointers are **not** pod! **Do not** mix this trait with a +/// newtype over [NonNull](core::ptr::NonNull). +pub unsafe trait PodInOption: ZeroableInOption + Copy + 'static {} + +unsafe impl PodInOption for NonZeroI8 {} +unsafe impl PodInOption for NonZeroI16 {} +unsafe impl PodInOption for NonZeroI32 {} +unsafe impl PodInOption for NonZeroI64 {} +unsafe impl PodInOption for NonZeroI128 {} +unsafe impl PodInOption for NonZeroIsize {} +unsafe impl PodInOption for NonZeroU8 {} +unsafe impl PodInOption for NonZeroU16 {} +unsafe impl PodInOption for NonZeroU32 {} +unsafe impl PodInOption for NonZeroU64 {} +unsafe impl PodInOption for NonZeroU128 {} +unsafe impl PodInOption for NonZeroUsize {}
diff --git a/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/src/transparent.rs b/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/src/transparent.rs new file mode 100644 index 0000000..5b9fe0e --- /dev/null +++ b/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/src/transparent.rs
@@ -0,0 +1,288 @@ +use super::*; + +/// A trait which indicates that a type is a `#[repr(transparent)]` wrapper +/// around the `Inner` value. +/// +/// This allows safely copy transmuting between the `Inner` type and the +/// `TransparentWrapper` type. Functions like `wrap_{}` convert from the inner +/// type to the wrapper type and `peel_{}` functions do the inverse conversion +/// from the wrapper type to the inner type. We deliberately do not call the +/// wrapper-removing methods "unwrap" because at this point that word is too +/// strongly tied to the Option/ Result methods. +/// +/// # Safety +/// +/// The safety contract of `TransparentWrapper` is relatively simple: +/// +/// For a given `Wrapper` which implements `TransparentWrapper<Inner>`: +/// +/// 1. `Wrapper` must be a wrapper around `Inner` with an identical data +/// representations. This either means that it must be a +/// `#[repr(transparent)]` struct which contains a either a field of type +/// `Inner` (or a field of some other transparent wrapper for `Inner`) as +/// the only non-ZST field. +/// +/// 2. Any fields *other* than the `Inner` field must be trivially constructable +/// ZSTs, for example `PhantomData`, `PhantomPinned`, etc. (When deriving +/// `TransparentWrapper` on a type with ZST fields, the ZST fields must be +/// [`Zeroable`]). +/// +/// 3. The `Wrapper` may not impose additional alignment requirements over +/// `Inner`. +/// - Note: this is currently guaranteed by `repr(transparent)`, but there +/// have been discussions of lifting it, so it's stated here explicitly. +/// +/// 4. All functions on `TransparentWrapper` **may not** be overridden. +/// +/// ## Caveats +/// +/// If the wrapper imposes additional constraints upon the inner type which are +/// required for safety, it's responsible for ensuring those still hold -- this +/// generally requires preventing access to instances of the inner type, as +/// implementing `TransparentWrapper<U> for T` means anybody can call +/// `T::cast_ref(any_instance_of_u)`. +/// +/// For example, it would be invalid to implement TransparentWrapper for `str` +/// to implement `TransparentWrapper` around `[u8]` because of this. +/// +/// # Examples +/// +/// ## Basic +/// +/// ``` +/// use bytemuck::TransparentWrapper; +/// # #[derive(Default)] +/// # struct SomeStruct(u32); +/// +/// #[repr(transparent)] +/// struct MyWrapper(SomeStruct); +/// +/// unsafe impl TransparentWrapper<SomeStruct> for MyWrapper {} +/// +/// // interpret a reference to &SomeStruct as a &MyWrapper +/// let thing = SomeStruct::default(); +/// let inner_ref: &MyWrapper = MyWrapper::wrap_ref(&thing); +/// +/// // Works with &mut too. +/// let mut mut_thing = SomeStruct::default(); +/// let inner_mut: &mut MyWrapper = MyWrapper::wrap_mut(&mut mut_thing); +/// +/// # let _ = (inner_ref, inner_mut); // silence warnings +/// ``` +/// +/// ## Use with dynamically sized types +/// +/// ``` +/// use bytemuck::TransparentWrapper; +/// +/// #[repr(transparent)] +/// struct Slice<T>([T]); +/// +/// unsafe impl<T> TransparentWrapper<[T]> for Slice<T> {} +/// +/// let s = Slice::wrap_ref(&[1u32, 2, 3]); +/// assert_eq!(&s.0, &[1, 2, 3]); +/// +/// let mut buf = [1, 2, 3u8]; +/// let sm = Slice::wrap_mut(&mut buf); +/// ``` +/// +/// ## Deriving +/// +/// When deriving, the non-wrapped fields must uphold all the normal requirements, +/// and must also be `Zeroable`. +/// +#[cfg_attr(feature = "derive", doc = "```")] +#[cfg_attr( + not(feature = "derive"), + doc = "```ignore +// This example requires the `derive` feature." +)] +/// use bytemuck::TransparentWrapper; +/// use std::marker::PhantomData; +/// +/// #[derive(TransparentWrapper)] +/// #[repr(transparent)] +/// #[transparent(usize)] +/// struct Wrapper<T: ?Sized>(usize, PhantomData<T>); // PhantomData<T> implements Zeroable for all T +/// ``` +/// +/// Here, an error will occur, because `MyZst` does not implement `Zeroable`. +/// +#[cfg_attr(feature = "derive", doc = "```compile_fail")] +#[cfg_attr( + not(feature = "derive"), + doc = "```ignore +// This example requires the `derive` feature." +)] +/// use bytemuck::TransparentWrapper; +/// struct MyZst; +/// +/// #[derive(TransparentWrapper)] +/// #[repr(transparent)] +/// #[transparent(usize)] +/// struct Wrapper(usize, MyZst); // MyZst does not implement Zeroable +/// ``` +pub unsafe trait TransparentWrapper<Inner: ?Sized> { + /// Convert the inner type into the wrapper type. + #[inline] + fn wrap(s: Inner) -> Self + where + Self: Sized, + Inner: Sized, + { + // SAFETY: The unsafe contract requires that `Self` and `Inner` have + // identical representations. + unsafe { transmute!(s) } + } + + /// Convert a reference to the inner type into a reference to the wrapper + /// type. + #[inline] + fn wrap_ref(s: &Inner) -> &Self { + unsafe { + assert!(size_of::<*const Inner>() == size_of::<*const Self>()); + // A pointer cast doesn't work here because rustc can't tell that + // the vtables match (because of the `?Sized` restriction relaxation). + // A `transmute` doesn't work because the sizes are unspecified. + // + // SAFETY: The unsafe contract requires that these two have + // identical representations. + let inner_ptr = s as *const Inner; + let wrapper_ptr: *const Self = transmute!(inner_ptr); + &*wrapper_ptr + } + } + + /// Convert a mutable reference to the inner type into a mutable reference to + /// the wrapper type. + #[inline] + fn wrap_mut(s: &mut Inner) -> &mut Self { + unsafe { + assert!(size_of::<*mut Inner>() == size_of::<*mut Self>()); + // A pointer cast doesn't work here because rustc can't tell that + // the vtables match (because of the `?Sized` restriction relaxation). + // A `transmute` doesn't work because the sizes are unspecified. + // + // SAFETY: The unsafe contract requires that these two have + // identical representations. + let inner_ptr = s as *mut Inner; + let wrapper_ptr: *mut Self = transmute!(inner_ptr); + &mut *wrapper_ptr + } + } + + /// Convert a slice to the inner type into a slice to the wrapper type. + #[inline] + fn wrap_slice(s: &[Inner]) -> &[Self] + where + Self: Sized, + Inner: Sized, + { + unsafe { + assert!(size_of::<*const Inner>() == size_of::<*const Self>()); + assert!(align_of::<*const Inner>() == align_of::<*const Self>()); + // SAFETY: The unsafe contract requires that these two have + // identical representations (size and alignment). + core::slice::from_raw_parts(s.as_ptr() as *const Self, s.len()) + } + } + + /// Convert a mutable slice to the inner type into a mutable slice to the + /// wrapper type. + #[inline] + fn wrap_slice_mut(s: &mut [Inner]) -> &mut [Self] + where + Self: Sized, + Inner: Sized, + { + unsafe { + assert!(size_of::<*mut Inner>() == size_of::<*mut Self>()); + assert!(align_of::<*mut Inner>() == align_of::<*mut Self>()); + // SAFETY: The unsafe contract requires that these two have + // identical representations (size and alignment). + core::slice::from_raw_parts_mut(s.as_mut_ptr() as *mut Self, s.len()) + } + } + + /// Convert the wrapper type into the inner type. + #[inline] + fn peel(s: Self) -> Inner + where + Self: Sized, + Inner: Sized, + { + unsafe { transmute!(s) } + } + + /// Convert a reference to the wrapper type into a reference to the inner + /// type. + #[inline] + fn peel_ref(s: &Self) -> &Inner { + unsafe { + assert!(size_of::<*const Inner>() == size_of::<*const Self>()); + // A pointer cast doesn't work here because rustc can't tell that + // the vtables match (because of the `?Sized` restriction relaxation). + // A `transmute` doesn't work because the sizes are unspecified. + // + // SAFETY: The unsafe contract requires that these two have + // identical representations. + let wrapper_ptr = s as *const Self; + let inner_ptr: *const Inner = transmute!(wrapper_ptr); + &*inner_ptr + } + } + + /// Convert a mutable reference to the wrapper type into a mutable reference + /// to the inner type. + #[inline] + fn peel_mut(s: &mut Self) -> &mut Inner { + unsafe { + assert!(size_of::<*mut Inner>() == size_of::<*mut Self>()); + // A pointer cast doesn't work here because rustc can't tell that + // the vtables match (because of the `?Sized` restriction relaxation). + // A `transmute` doesn't work because the sizes are unspecified. + // + // SAFETY: The unsafe contract requires that these two have + // identical representations. + let wrapper_ptr = s as *mut Self; + let inner_ptr: *mut Inner = transmute!(wrapper_ptr); + &mut *inner_ptr + } + } + + /// Convert a slice to the wrapped type into a slice to the inner type. + #[inline] + fn peel_slice(s: &[Self]) -> &[Inner] + where + Self: Sized, + Inner: Sized, + { + unsafe { + assert!(size_of::<*const Inner>() == size_of::<*const Self>()); + assert!(align_of::<*const Inner>() == align_of::<*const Self>()); + // SAFETY: The unsafe contract requires that these two have + // identical representations (size and alignment). + core::slice::from_raw_parts(s.as_ptr() as *const Inner, s.len()) + } + } + + /// Convert a mutable slice to the wrapped type into a mutable slice to the + /// inner type. + #[inline] + fn peel_slice_mut(s: &mut [Self]) -> &mut [Inner] + where + Self: Sized, + Inner: Sized, + { + unsafe { + assert!(size_of::<*mut Inner>() == size_of::<*mut Self>()); + assert!(align_of::<*mut Inner>() == align_of::<*mut Self>()); + // SAFETY: The unsafe contract requires that these two have + // identical representations (size and alignment). + core::slice::from_raw_parts_mut(s.as_mut_ptr() as *mut Inner, s.len()) + } + } +} + +unsafe impl<T> TransparentWrapper<T> for core::num::Wrapping<T> {}
diff --git a/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/src/zeroable.rs b/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/src/zeroable.rs new file mode 100644 index 0000000..b64a9bff --- /dev/null +++ b/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/src/zeroable.rs
@@ -0,0 +1,245 @@ +use super::*; + +/// Trait for types that can be safely created with +/// [`zeroed`](core::mem::zeroed). +/// +/// An all-zeroes value may or may not be the same value as the +/// [Default](core::default::Default) value of the type. +/// +/// ## Safety +/// +/// * Your type must be inhabited (eg: no +/// [Infallible](core::convert::Infallible)). +/// * Your type must be allowed to be an "all zeroes" bit pattern (eg: no +/// [`NonNull<T>`](core::ptr::NonNull)). +/// +/// ## Features +/// +/// Some `impl`s are feature gated due to the MSRV policy: +/// +/// * `MaybeUninit<T>` was not available in 1.34.0, but is available under the +/// `zeroable_maybe_uninit` feature flag. +/// * `Atomic*` types require Rust 1.60.0 or later to work on certain platforms, +/// but is available under the `zeroable_atomics` feature flag. +/// * `[T; N]` for arbitrary `N` requires the `min_const_generics` feature flag. +pub unsafe trait Zeroable: Sized { + /// Calls [`zeroed`](core::mem::zeroed). + /// + /// This is a trait method so that you can write `MyType::zeroed()` in your + /// code. It is a contract of this trait that if you implement it on your type + /// you **must not** override this method. + #[inline] + fn zeroed() -> Self { + unsafe { core::mem::zeroed() } + } +} +unsafe impl Zeroable for () {} +unsafe impl Zeroable for bool {} +unsafe impl Zeroable for char {} +unsafe impl Zeroable for u8 {} +unsafe impl Zeroable for i8 {} +unsafe impl Zeroable for u16 {} +unsafe impl Zeroable for i16 {} +unsafe impl Zeroable for u32 {} +unsafe impl Zeroable for i32 {} +unsafe impl Zeroable for u64 {} +unsafe impl Zeroable for i64 {} +unsafe impl Zeroable for usize {} +unsafe impl Zeroable for isize {} +unsafe impl Zeroable for u128 {} +unsafe impl Zeroable for i128 {} +unsafe impl Zeroable for f32 {} +unsafe impl Zeroable for f64 {} +unsafe impl<T: Zeroable> Zeroable for Wrapping<T> {} +unsafe impl<T: Zeroable> Zeroable for core::cmp::Reverse<T> {} + +// Note: we can't implement this for all `T: ?Sized` types because it would +// create NULL pointers for vtables. +// Maybe one day this could be changed to be implemented for +// `T: ?Sized where <T as core::ptr::Pointee>::Metadata: Zeroable`. +unsafe impl<T> Zeroable for *mut T {} +unsafe impl<T> Zeroable for *const T {} +unsafe impl<T> Zeroable for *mut [T] {} +unsafe impl<T> Zeroable for *const [T] {} +unsafe impl Zeroable for *mut str {} +unsafe impl Zeroable for *const str {} + +unsafe impl<T: ?Sized> Zeroable for PhantomData<T> {} +unsafe impl Zeroable for PhantomPinned {} +unsafe impl<T: Zeroable> Zeroable for ManuallyDrop<T> {} +unsafe impl<T: Zeroable> Zeroable for core::cell::UnsafeCell<T> {} +unsafe impl<T: Zeroable> Zeroable for core::cell::Cell<T> {} + +#[cfg(feature = "zeroable_atomics")] +#[cfg_attr(feature = "nightly_docs", doc(cfg(feature = "zeroable_atomics")))] +mod atomic_impls { + use super::Zeroable; + + #[cfg(target_has_atomic = "8")] + unsafe impl Zeroable for core::sync::atomic::AtomicBool {} + #[cfg(target_has_atomic = "8")] + unsafe impl Zeroable for core::sync::atomic::AtomicU8 {} + #[cfg(target_has_atomic = "8")] + unsafe impl Zeroable for core::sync::atomic::AtomicI8 {} + + #[cfg(target_has_atomic = "16")] + unsafe impl Zeroable for core::sync::atomic::AtomicU16 {} + #[cfg(target_has_atomic = "16")] + unsafe impl Zeroable for core::sync::atomic::AtomicI16 {} + + #[cfg(target_has_atomic = "32")] + unsafe impl Zeroable for core::sync::atomic::AtomicU32 {} + #[cfg(target_has_atomic = "32")] + unsafe impl Zeroable for core::sync::atomic::AtomicI32 {} + + #[cfg(target_has_atomic = "64")] + unsafe impl Zeroable for core::sync::atomic::AtomicU64 {} + #[cfg(target_has_atomic = "64")] + unsafe impl Zeroable for core::sync::atomic::AtomicI64 {} + + #[cfg(target_has_atomic = "ptr")] + unsafe impl Zeroable for core::sync::atomic::AtomicUsize {} + #[cfg(target_has_atomic = "ptr")] + unsafe impl Zeroable for core::sync::atomic::AtomicIsize {} + + #[cfg(target_has_atomic = "ptr")] + unsafe impl<T> Zeroable for core::sync::atomic::AtomicPtr<T> {} +} + +#[cfg(feature = "zeroable_maybe_uninit")] +#[cfg_attr( + feature = "nightly_docs", + doc(cfg(feature = "zeroable_maybe_uninit")) +)] +unsafe impl<T> Zeroable for core::mem::MaybeUninit<T> {} + +unsafe impl<A: Zeroable> Zeroable for (A,) {} +unsafe impl<A: Zeroable, B: Zeroable> Zeroable for (A, B) {} +unsafe impl<A: Zeroable, B: Zeroable, C: Zeroable> Zeroable for (A, B, C) {} +unsafe impl<A: Zeroable, B: Zeroable, C: Zeroable, D: Zeroable> Zeroable + for (A, B, C, D) +{ +} +unsafe impl<A: Zeroable, B: Zeroable, C: Zeroable, D: Zeroable, E: Zeroable> + Zeroable for (A, B, C, D, E) +{ +} +unsafe impl< + A: Zeroable, + B: Zeroable, + C: Zeroable, + D: Zeroable, + E: Zeroable, + F: Zeroable, + > Zeroable for (A, B, C, D, E, F) +{ +} +unsafe impl< + A: Zeroable, + B: Zeroable, + C: Zeroable, + D: Zeroable, + E: Zeroable, + F: Zeroable, + G: Zeroable, + > Zeroable for (A, B, C, D, E, F, G) +{ +} +unsafe impl< + A: Zeroable, + B: Zeroable, + C: Zeroable, + D: Zeroable, + E: Zeroable, + F: Zeroable, + G: Zeroable, + H: Zeroable, + > Zeroable for (A, B, C, D, E, F, G, H) +{ +} + +#[cfg(feature = "min_const_generics")] +#[cfg_attr(feature = "nightly_docs", doc(cfg(feature = "min_const_generics")))] +unsafe impl<T, const N: usize> Zeroable for [T; N] where T: Zeroable {} + +#[cfg(not(feature = "min_const_generics"))] +impl_unsafe_marker_for_array!( + Zeroable, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 48, 64, 96, 128, 256, + 512, 1024, 2048, 4096 +); + +impl_unsafe_marker_for_simd!( + #[cfg(all(target_arch = "wasm32", feature = "wasm_simd"))] + unsafe impl Zeroable for wasm32::{v128} +); + +impl_unsafe_marker_for_simd!( + #[cfg(all(target_arch = "aarch64", feature = "aarch64_simd"))] + unsafe impl Zeroable for aarch64::{ + float32x2_t, float32x2x2_t, float32x2x3_t, float32x2x4_t, float32x4_t, + float32x4x2_t, float32x4x3_t, float32x4x4_t, float64x1_t, float64x1x2_t, + float64x1x3_t, float64x1x4_t, float64x2_t, float64x2x2_t, float64x2x3_t, + float64x2x4_t, int16x4_t, int16x4x2_t, int16x4x3_t, int16x4x4_t, int16x8_t, + int16x8x2_t, int16x8x3_t, int16x8x4_t, int32x2_t, int32x2x2_t, int32x2x3_t, + int32x2x4_t, int32x4_t, int32x4x2_t, int32x4x3_t, int32x4x4_t, int64x1_t, + int64x1x2_t, int64x1x3_t, int64x1x4_t, int64x2_t, int64x2x2_t, int64x2x3_t, + int64x2x4_t, int8x16_t, int8x16x2_t, int8x16x3_t, int8x16x4_t, int8x8_t, + int8x8x2_t, int8x8x3_t, int8x8x4_t, poly16x4_t, poly16x4x2_t, poly16x4x3_t, + poly16x4x4_t, poly16x8_t, poly16x8x2_t, poly16x8x3_t, poly16x8x4_t, + poly64x1_t, poly64x1x2_t, poly64x1x3_t, poly64x1x4_t, poly64x2_t, + poly64x2x2_t, poly64x2x3_t, poly64x2x4_t, poly8x16_t, poly8x16x2_t, + poly8x16x3_t, poly8x16x4_t, poly8x8_t, poly8x8x2_t, poly8x8x3_t, poly8x8x4_t, + uint16x4_t, uint16x4x2_t, uint16x4x3_t, uint16x4x4_t, uint16x8_t, + uint16x8x2_t, uint16x8x3_t, uint16x8x4_t, uint32x2_t, uint32x2x2_t, + uint32x2x3_t, uint32x2x4_t, uint32x4_t, uint32x4x2_t, uint32x4x3_t, + uint32x4x4_t, uint64x1_t, uint64x1x2_t, uint64x1x3_t, uint64x1x4_t, + uint64x2_t, uint64x2x2_t, uint64x2x3_t, uint64x2x4_t, uint8x16_t, + uint8x16x2_t, uint8x16x3_t, uint8x16x4_t, uint8x8_t, uint8x8x2_t, + uint8x8x3_t, uint8x8x4_t, + } +); + +impl_unsafe_marker_for_simd!( + #[cfg(target_arch = "x86")] + unsafe impl Zeroable for x86::{ + __m128i, __m128, __m128d, + __m256i, __m256, __m256d, + } +); + +impl_unsafe_marker_for_simd!( + #[cfg(target_arch = "x86_64")] + unsafe impl Zeroable for x86_64::{ + __m128i, __m128, __m128d, + __m256i, __m256, __m256d, + } +); + +#[cfg(feature = "nightly_portable_simd")] +#[cfg_attr( + feature = "nightly_docs", + doc(cfg(feature = "nightly_portable_simd")) +)] +unsafe impl<T, const N: usize> Zeroable for core::simd::Simd<T, N> +where + T: core::simd::SimdElement + Zeroable, + core::simd::LaneCount<N>: core::simd::SupportedLaneCount, +{ +} + +impl_unsafe_marker_for_simd!( + #[cfg(all(target_arch = "x86", feature = "nightly_stdsimd"))] + unsafe impl Zeroable for x86::{ + __m128bh, __m256bh, __m512, + __m512bh, __m512d, __m512i, + } +); + +impl_unsafe_marker_for_simd!( + #[cfg(all(target_arch = "x86_64", feature = "nightly_stdsimd"))] + unsafe impl Zeroable for x86_64::{ + __m128bh, __m256bh, __m512, + __m512bh, __m512d, __m512i, + } +);
diff --git a/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/src/zeroable_in_option.rs b/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/src/zeroable_in_option.rs new file mode 100644 index 0000000..c4cf158a --- /dev/null +++ b/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/src/zeroable_in_option.rs
@@ -0,0 +1,35 @@ +use super::*; + +// Note(Lokathor): This is the neat part!! +unsafe impl<T: ZeroableInOption> Zeroable for Option<T> {} + +/// Trait for types which are [Zeroable](Zeroable) when wrapped in +/// [Option](core::option::Option). +/// +/// ## Safety +/// +/// * `Option<YourType>` must uphold the same invariants as +/// [Zeroable](Zeroable). +pub unsafe trait ZeroableInOption: Sized {} + +unsafe impl ZeroableInOption for NonZeroI8 {} +unsafe impl ZeroableInOption for NonZeroI16 {} +unsafe impl ZeroableInOption for NonZeroI32 {} +unsafe impl ZeroableInOption for NonZeroI64 {} +unsafe impl ZeroableInOption for NonZeroI128 {} +unsafe impl ZeroableInOption for NonZeroIsize {} +unsafe impl ZeroableInOption for NonZeroU8 {} +unsafe impl ZeroableInOption for NonZeroU16 {} +unsafe impl ZeroableInOption for NonZeroU32 {} +unsafe impl ZeroableInOption for NonZeroU64 {} +unsafe impl ZeroableInOption for NonZeroU128 {} +unsafe impl ZeroableInOption for NonZeroUsize {} + +// Note: this does not create NULL vtable because we get `None` anyway. +unsafe impl<T: ?Sized> ZeroableInOption for NonNull<T> {} +unsafe impl<T: ?Sized> ZeroableInOption for &'_ T {} +unsafe impl<T: ?Sized> ZeroableInOption for &'_ mut T {} + +#[cfg(feature = "extern_crate_alloc")] +#[cfg_attr(feature = "nightly_docs", doc(cfg(feature = "extern_crate_alloc")))] +unsafe impl<T: ?Sized> ZeroableInOption for alloc::boxed::Box<T> {}
diff --git a/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/tests/array_tests.rs b/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/tests/array_tests.rs new file mode 100644 index 0000000..4b9782bb --- /dev/null +++ b/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/tests/array_tests.rs
@@ -0,0 +1,12 @@ +#[test] +pub fn test_cast_array() { + let x = [0u32, 1u32, 2u32]; + let _: [u16; 6] = bytemuck::cast(x); +} + +#[cfg(feature = "min_const_generics")] +#[test] +pub fn test_cast_long_array() { + let x = [0u32; 65]; + let _: [u16; 130] = bytemuck::cast(x); +}
diff --git a/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/tests/cast_slice_tests.rs b/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/tests/cast_slice_tests.rs new file mode 100644 index 0000000..ce6dedc6 --- /dev/null +++ b/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/tests/cast_slice_tests.rs
@@ -0,0 +1,197 @@ +#![allow(clippy::unnecessary_cast)] +#![allow(clippy::manual_slice_size_calculation)] + +use core::mem::size_of; + +use bytemuck::*; + +#[test] +fn test_try_cast_slice() { + // some align4 data + let u32_slice: &[u32] = &[4, 5, 6]; + // the same data as align1 + let the_bytes: &[u8] = try_cast_slice(u32_slice).unwrap(); + + assert_eq!( + u32_slice.as_ptr() as *const u32 as usize, + the_bytes.as_ptr() as *const u8 as usize + ); + assert_eq!( + u32_slice.len() * size_of::<u32>(), + the_bytes.len() * size_of::<u8>() + ); + + // by taking one byte off the front, we're definitely mis-aligned for u32. + let mis_aligned_bytes = &the_bytes[1..]; + assert_eq!( + try_cast_slice::<u8, u32>(mis_aligned_bytes), + Err(PodCastError::TargetAlignmentGreaterAndInputNotAligned) + ); + + // by taking one byte off the end, we're aligned but would have slop bytes for + // u32 + let the_bytes_len_minus1 = the_bytes.len() - 1; + let slop_bytes = &the_bytes[..the_bytes_len_minus1]; + assert_eq!( + try_cast_slice::<u8, u32>(slop_bytes), + Err(PodCastError::OutputSliceWouldHaveSlop) + ); + + // if we don't mess with it we can up-alignment cast + try_cast_slice::<u8, u32>(the_bytes).unwrap(); +} + +#[test] +fn test_try_cast_slice_mut() { + // some align4 data + let u32_slice: &mut [u32] = &mut [4, 5, 6]; + let u32_len = u32_slice.len(); + let u32_ptr = u32_slice.as_ptr(); + + // the same data as align1 + let the_bytes: &mut [u8] = try_cast_slice_mut(u32_slice).unwrap(); + let the_bytes_len = the_bytes.len(); + let the_bytes_ptr = the_bytes.as_ptr(); + + assert_eq!( + u32_ptr as *const u32 as usize, + the_bytes_ptr as *const u8 as usize + ); + assert_eq!(u32_len * size_of::<u32>(), the_bytes_len * size_of::<u8>()); + + // by taking one byte off the front, we're definitely mis-aligned for u32. + let mis_aligned_bytes = &mut the_bytes[1..]; + assert_eq!( + try_cast_slice_mut::<u8, u32>(mis_aligned_bytes), + Err(PodCastError::TargetAlignmentGreaterAndInputNotAligned) + ); + + // by taking one byte off the end, we're aligned but would have slop bytes for + // u32 + let the_bytes_len_minus1 = the_bytes.len() - 1; + let slop_bytes = &mut the_bytes[..the_bytes_len_minus1]; + assert_eq!( + try_cast_slice_mut::<u8, u32>(slop_bytes), + Err(PodCastError::OutputSliceWouldHaveSlop) + ); + + // if we don't mess with it we can up-alignment cast + try_cast_slice_mut::<u8, u32>(the_bytes).unwrap(); +} + +#[test] +fn test_types() { + let _: i32 = cast(1.0_f32); + let _: &mut i32 = cast_mut(&mut 1.0_f32); + let _: &i32 = cast_ref(&1.0_f32); + let _: &[i32] = cast_slice(&[1.0_f32]); + let _: &mut [i32] = cast_slice_mut(&mut [1.0_f32]); + // + let _: Result<i32, PodCastError> = try_cast(1.0_f32); + let _: Result<&mut i32, PodCastError> = try_cast_mut(&mut 1.0_f32); + let _: Result<&i32, PodCastError> = try_cast_ref(&1.0_f32); + let _: Result<&[i32], PodCastError> = try_cast_slice(&[1.0_f32]); + let _: Result<&mut [i32], PodCastError> = try_cast_slice_mut(&mut [1.0_f32]); +} + +#[test] +fn test_bytes_of() { + assert_eq!(bytes_of(&0xaabbccdd_u32), &0xaabbccdd_u32.to_ne_bytes()); + assert_eq!( + bytes_of_mut(&mut 0xaabbccdd_u32), + &mut 0xaabbccdd_u32.to_ne_bytes() + ); + let mut a = 0xaabbccdd_u32; + let a_addr = &a as *const _ as usize; + // ensure addresses match. + assert_eq!(bytes_of(&a).as_ptr() as usize, a_addr); + assert_eq!(bytes_of_mut(&mut a).as_ptr() as usize, a_addr); +} + +#[test] +fn test_try_from_bytes() { + let u32s = [0xaabbccdd, 0x11223344_u32]; + let bytes = bytemuck::cast_slice::<u32, u8>(&u32s); + assert_eq!(try_from_bytes::<u32>(&bytes[..4]), Ok(&u32s[0])); + assert_eq!( + try_from_bytes::<u32>(&bytes[..5]), + Err(PodCastError::SizeMismatch) + ); + assert_eq!( + try_from_bytes::<u32>(&bytes[..3]), + Err(PodCastError::SizeMismatch) + ); + assert_eq!( + try_from_bytes::<u32>(&bytes[1..5]), + Err(PodCastError::TargetAlignmentGreaterAndInputNotAligned) + ); +} + +#[test] +fn test_try_from_bytes_mut() { + let mut abcd = 0xaabbccdd; + let mut u32s = [abcd, 0x11223344_u32]; + let bytes = bytemuck::cast_slice_mut::<u32, u8>(&mut u32s); + assert_eq!(try_from_bytes_mut::<u32>(&mut bytes[..4]), Ok(&mut abcd)); + assert_eq!(try_from_bytes_mut::<u32>(&mut bytes[..4]), Ok(&mut abcd)); + assert_eq!( + try_from_bytes_mut::<u32>(&mut bytes[..5]), + Err(PodCastError::SizeMismatch) + ); + assert_eq!( + try_from_bytes_mut::<u32>(&mut bytes[..3]), + Err(PodCastError::SizeMismatch) + ); + assert_eq!( + try_from_bytes::<u32>(&bytes[1..5]), + Err(PodCastError::TargetAlignmentGreaterAndInputNotAligned) + ); +} + +#[test] +fn test_from_bytes() { + let abcd = 0xaabbccdd_u32; + let aligned_bytes = bytemuck::bytes_of(&abcd); + assert_eq!(from_bytes::<u32>(aligned_bytes), &abcd); + assert!(core::ptr::eq(from_bytes(aligned_bytes), &abcd)); +} + +#[test] +fn test_from_bytes_mut() { + let mut a = 0xaabbccdd_u32; + let a_addr = &a as *const _ as usize; + let aligned_bytes = bytemuck::bytes_of_mut(&mut a); + assert_eq!(*from_bytes_mut::<u32>(aligned_bytes), 0xaabbccdd_u32); + assert_eq!( + from_bytes_mut::<u32>(aligned_bytes) as *const u32 as usize, + a_addr + ); +} + +// like #[should_panic], but can be a part of another test, instead of requiring +// it to be it's own test. +macro_rules! should_panic { + ($ex:expr) => { + assert!( + std::panic::catch_unwind(|| { + let _ = $ex; + }) + .is_err(), + concat!("should have panicked: `", stringify!($ex), "`") + ); + }; +} + +#[test] +fn test_panics() { + should_panic!(cast_slice::<u8, u32>(&[1u8, 2u8])); + should_panic!(cast_slice_mut::<u8, u32>(&mut [1u8, 2u8])); + should_panic!(from_bytes::<u32>(&[1u8, 2])); + should_panic!(from_bytes::<u32>(&[1u8, 2, 3, 4, 5])); + should_panic!(from_bytes_mut::<u32>(&mut [1u8, 2])); + should_panic!(from_bytes_mut::<u32>(&mut [1u8, 2, 3, 4, 5])); + // use cast_slice on some u32s to get some align>=4 bytes, so we can know + // we'll give from_bytes unaligned ones. + let aligned_bytes = bytemuck::cast_slice::<u32, u8>(&[0, 0]); + should_panic!(from_bytes::<u32>(&aligned_bytes[1..5])); +}
diff --git a/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/tests/checked_tests.rs b/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/tests/checked_tests.rs new file mode 100644 index 0000000..c7c5640a --- /dev/null +++ b/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/tests/checked_tests.rs
@@ -0,0 +1,419 @@ +#![allow(clippy::unnecessary_cast)] +#![allow(clippy::manual_slice_size_calculation)] + +use core::{ + mem::size_of, + num::{NonZeroU32, NonZeroU8}, +}; + +use bytemuck::{checked::CheckedCastError, *}; + +#[test] +fn test_try_cast_slice() { + // some align4 data + let nonzero_u32_slice: &[NonZeroU32] = &[ + NonZeroU32::new(4).unwrap(), + NonZeroU32::new(5).unwrap(), + NonZeroU32::new(6).unwrap(), + ]; + + // contains bytes with invalid bitpattern for NonZeroU8 + assert_eq!( + checked::try_cast_slice::<NonZeroU32, NonZeroU8>(nonzero_u32_slice), + Err(CheckedCastError::InvalidBitPattern) + ); + + // the same data as align1 + let the_bytes: &[u8] = checked::try_cast_slice(nonzero_u32_slice).unwrap(); + + assert_eq!( + nonzero_u32_slice.as_ptr() as *const NonZeroU32 as usize, + the_bytes.as_ptr() as *const u8 as usize + ); + assert_eq!( + nonzero_u32_slice.len() * size_of::<NonZeroU32>(), + the_bytes.len() * size_of::<u8>() + ); + + // by taking one byte off the front, we're definitely mis-aligned for + // NonZeroU32. + let mis_aligned_bytes = &the_bytes[1..]; + assert_eq!( + checked::try_cast_slice::<u8, NonZeroU32>(mis_aligned_bytes), + Err(CheckedCastError::PodCastError( + PodCastError::TargetAlignmentGreaterAndInputNotAligned + )) + ); + + // by taking one byte off the end, we're aligned but would have slop bytes for + // NonZeroU32 + let the_bytes_len_minus1 = the_bytes.len() - 1; + let slop_bytes = &the_bytes[..the_bytes_len_minus1]; + assert_eq!( + checked::try_cast_slice::<u8, NonZeroU32>(slop_bytes), + Err(CheckedCastError::PodCastError(PodCastError::OutputSliceWouldHaveSlop)) + ); + + // if we don't mess with it we can up-alignment cast + checked::try_cast_slice::<u8, NonZeroU32>(the_bytes).unwrap(); +} + +#[test] +fn test_try_cast_slice_mut() { + // some align4 data + let u32_slice: &mut [u32] = &mut [4, 5, 6]; + + // contains bytes with invalid bitpattern for NonZeroU8 + assert_eq!( + checked::try_cast_slice_mut::<u32, NonZeroU8>(u32_slice), + Err(CheckedCastError::InvalidBitPattern) + ); + + // some align4 data + let u32_slice: &mut [u32] = &mut [0x4444_4444, 0x5555_5555, 0x6666_6666]; + let u32_len = u32_slice.len(); + let u32_ptr = u32_slice.as_ptr(); + + // the same data as align1, nonzero bytes + let the_nonzero_bytes: &mut [NonZeroU8] = + checked::try_cast_slice_mut(u32_slice).unwrap(); + let the_nonzero_bytes_len = the_nonzero_bytes.len(); + let the_nonzero_bytes_ptr = the_nonzero_bytes.as_ptr(); + + assert_eq!( + u32_ptr as *const u32 as usize, + the_nonzero_bytes_ptr as *const NonZeroU8 as usize + ); + assert_eq!( + u32_len * size_of::<u32>(), + the_nonzero_bytes_len * size_of::<NonZeroU8>() + ); + + // the same data as align1 + let the_bytes: &mut [u8] = checked::try_cast_slice_mut(u32_slice).unwrap(); + let the_bytes_len = the_bytes.len(); + let the_bytes_ptr = the_bytes.as_ptr(); + + assert_eq!( + u32_ptr as *const u32 as usize, + the_bytes_ptr as *const u8 as usize + ); + assert_eq!( + u32_len * size_of::<u32>(), + the_bytes_len * size_of::<NonZeroU8>() + ); + + // by taking one byte off the front, we're definitely mis-aligned for u32. + let mis_aligned_bytes = &mut the_bytes[1..]; + assert_eq!( + checked::try_cast_slice_mut::<u8, NonZeroU32>(mis_aligned_bytes), + Err(CheckedCastError::PodCastError( + PodCastError::TargetAlignmentGreaterAndInputNotAligned + )) + ); + + // by taking one byte off the end, we're aligned but would have slop bytes for + // NonZeroU32 + let the_bytes_len_minus1 = the_bytes.len() - 1; + let slop_bytes = &mut the_bytes[..the_bytes_len_minus1]; + assert_eq!( + checked::try_cast_slice_mut::<u8, NonZeroU32>(slop_bytes), + Err(CheckedCastError::PodCastError(PodCastError::OutputSliceWouldHaveSlop)) + ); + + // if we don't mess with it we can up-alignment cast, since there are no + // zeroes in the original slice + checked::try_cast_slice_mut::<u8, NonZeroU32>(the_bytes).unwrap(); +} + +#[test] +fn test_types() { + let _: NonZeroU32 = checked::cast(1.0_f32); + let _: &mut NonZeroU32 = checked::cast_mut(&mut 1.0_f32); + let _: &NonZeroU32 = checked::cast_ref(&1.0_f32); + let _: &[NonZeroU32] = checked::cast_slice(&[1.0_f32]); + let _: &mut [NonZeroU32] = checked::cast_slice_mut(&mut [1.0_f32]); + // + let _: Result<NonZeroU32, CheckedCastError> = checked::try_cast(1.0_f32); + let _: Result<&mut NonZeroU32, CheckedCastError> = + checked::try_cast_mut(&mut 1.0_f32); + let _: Result<&NonZeroU32, CheckedCastError> = + checked::try_cast_ref(&1.0_f32); + let _: Result<&[NonZeroU32], CheckedCastError> = + checked::try_cast_slice(&[1.0_f32]); + let _: Result<&mut [NonZeroU32], CheckedCastError> = + checked::try_cast_slice_mut(&mut [1.0_f32]); +} + +#[test] +fn test_try_pod_read_unaligned() { + let u32s = [0xaabbccdd, 0x11223344_u32]; + let bytes = bytemuck::checked::cast_slice::<u32, u8>(&u32s); + + #[cfg(target_endian = "big")] + assert_eq!( + checked::try_pod_read_unaligned::<NonZeroU32>(&bytes[1..5]), + Ok(NonZeroU32::new(0xbbccdd11).unwrap()) + ); + #[cfg(target_endian = "little")] + assert_eq!( + checked::try_pod_read_unaligned::<NonZeroU32>(&bytes[1..5]), + Ok(NonZeroU32::new(0x44aabbcc).unwrap()) + ); + + let u32s = [0; 2]; + let bytes = bytemuck::checked::cast_slice::<u32, u8>(&u32s); + + assert_eq!( + checked::try_pod_read_unaligned::<NonZeroU32>(&bytes[1..5]), + Err(CheckedCastError::InvalidBitPattern) + ); +} + +#[test] +fn test_try_from_bytes() { + let nonzero_u32s = [ + NonZeroU32::new(0xaabbccdd).unwrap(), + NonZeroU32::new(0x11223344).unwrap(), + ]; + let bytes = bytemuck::checked::cast_slice::<NonZeroU32, u8>(&nonzero_u32s); + assert_eq!( + checked::try_from_bytes::<NonZeroU32>(&bytes[..4]), + Ok(&nonzero_u32s[0]) + ); + assert_eq!( + checked::try_from_bytes::<NonZeroU32>(&bytes[..5]), + Err(CheckedCastError::PodCastError(PodCastError::SizeMismatch)) + ); + assert_eq!( + checked::try_from_bytes::<NonZeroU32>(&bytes[..3]), + Err(CheckedCastError::PodCastError(PodCastError::SizeMismatch)) + ); + assert_eq!( + checked::try_from_bytes::<NonZeroU32>(&bytes[1..5]), + Err(CheckedCastError::PodCastError( + PodCastError::TargetAlignmentGreaterAndInputNotAligned + )) + ); + + let zero_u32s = [0, 0x11223344_u32]; + let bytes = bytemuck::checked::cast_slice::<u32, u8>(&zero_u32s); + assert_eq!( + checked::try_from_bytes::<NonZeroU32>(&bytes[..4]), + Err(CheckedCastError::InvalidBitPattern) + ); + assert_eq!( + checked::try_from_bytes::<NonZeroU32>(&bytes[4..]), + Ok(&NonZeroU32::new(zero_u32s[1]).unwrap()) + ); + assert_eq!( + checked::try_from_bytes::<NonZeroU32>(&bytes[..5]), + Err(CheckedCastError::PodCastError(PodCastError::SizeMismatch)) + ); + assert_eq!( + checked::try_from_bytes::<NonZeroU32>(&bytes[..3]), + Err(CheckedCastError::PodCastError(PodCastError::SizeMismatch)) + ); + assert_eq!( + checked::try_from_bytes::<NonZeroU32>(&bytes[1..5]), + Err(CheckedCastError::PodCastError( + PodCastError::TargetAlignmentGreaterAndInputNotAligned + )) + ); +} + +#[test] +fn test_try_from_bytes_mut() { + let a = 0xaabbccdd_u32; + let b = 0x11223344_u32; + let mut u32s = [a, b]; + let bytes = bytemuck::checked::cast_slice_mut::<u32, u8>(&mut u32s); + assert_eq!( + checked::try_from_bytes_mut::<NonZeroU32>(&mut bytes[..4]), + Ok(&mut NonZeroU32::new(a).unwrap()) + ); + assert_eq!( + checked::try_from_bytes_mut::<NonZeroU32>(&mut bytes[4..]), + Ok(&mut NonZeroU32::new(b).unwrap()) + ); + assert_eq!( + checked::try_from_bytes_mut::<NonZeroU32>(&mut bytes[..5]), + Err(CheckedCastError::PodCastError(PodCastError::SizeMismatch)) + ); + assert_eq!( + checked::try_from_bytes_mut::<NonZeroU32>(&mut bytes[..3]), + Err(CheckedCastError::PodCastError(PodCastError::SizeMismatch)) + ); + assert_eq!( + checked::try_from_bytes::<NonZeroU32>(&bytes[1..5]), + Err(CheckedCastError::PodCastError( + PodCastError::TargetAlignmentGreaterAndInputNotAligned + )) + ); + + let mut u32s = [0, b]; + let bytes = bytemuck::checked::cast_slice_mut::<u32, u8>(&mut u32s); + assert_eq!( + checked::try_from_bytes_mut::<NonZeroU32>(&mut bytes[..4]), + Err(CheckedCastError::InvalidBitPattern) + ); + assert_eq!( + checked::try_from_bytes_mut::<NonZeroU32>(&mut bytes[4..]), + Ok(&mut NonZeroU32::new(b).unwrap()) + ); + assert_eq!( + checked::try_from_bytes_mut::<NonZeroU32>(&mut bytes[..5]), + Err(CheckedCastError::PodCastError(PodCastError::SizeMismatch)) + ); + assert_eq!( + checked::try_from_bytes_mut::<NonZeroU32>(&mut bytes[..3]), + Err(CheckedCastError::PodCastError(PodCastError::SizeMismatch)) + ); + assert_eq!( + checked::try_from_bytes::<NonZeroU32>(&bytes[1..5]), + Err(CheckedCastError::PodCastError( + PodCastError::TargetAlignmentGreaterAndInputNotAligned + )) + ); +} + +#[test] +fn test_from_bytes() { + let abcd = 0xaabbccdd_u32; + let aligned_bytes = bytemuck::bytes_of(&abcd); + assert_eq!( + checked::from_bytes::<NonZeroU32>(aligned_bytes), + &NonZeroU32::new(abcd).unwrap() + ); + assert!(core::ptr::eq( + checked::from_bytes(aligned_bytes) as *const NonZeroU32 as *const u32, + &abcd + )); +} + +#[test] +fn test_from_bytes_mut() { + let mut a = 0xaabbccdd_u32; + let a_addr = &a as *const _ as usize; + let aligned_bytes = bytemuck::bytes_of_mut(&mut a); + assert_eq!( + *checked::from_bytes_mut::<NonZeroU32>(aligned_bytes), + NonZeroU32::new(0xaabbccdd).unwrap() + ); + assert_eq!( + checked::from_bytes_mut::<NonZeroU32>(aligned_bytes) as *const NonZeroU32 + as usize, + a_addr + ); +} + +// like #[should_panic], but can be a part of another test, instead of requiring +// it to be it's own test. +macro_rules! should_panic { + ($ex:expr) => { + assert!( + std::panic::catch_unwind(|| { + let _ = $ex; + }) + .is_err(), + concat!("should have panicked: `", stringify!($ex), "`") + ); + }; +} + +#[test] +fn test_panics() { + should_panic!(checked::cast::<u32, NonZeroU32>(0)); + should_panic!(checked::cast_ref::<u32, NonZeroU32>(&0)); + should_panic!(checked::cast_mut::<u32, NonZeroU32>(&mut 0)); + should_panic!(checked::cast_slice::<u8, NonZeroU32>(&[1u8, 2u8])); + should_panic!(checked::cast_slice_mut::<u8, NonZeroU32>(&mut [1u8, 2u8])); + should_panic!(checked::from_bytes::<NonZeroU32>(&[1u8, 2])); + should_panic!(checked::from_bytes::<NonZeroU32>(&[1u8, 2, 3, 4, 5])); + should_panic!(checked::from_bytes_mut::<NonZeroU32>(&mut [1u8, 2])); + should_panic!(checked::from_bytes_mut::<NonZeroU32>(&mut [1u8, 2, 3, 4, 5])); + // use cast_slice on some u32s to get some align>=4 bytes, so we can know + // we'll give from_bytes unaligned ones. + let aligned_bytes = bytemuck::cast_slice::<u32, u8>(&[0, 0]); + should_panic!(checked::from_bytes::<NonZeroU32>(aligned_bytes)); + should_panic!(checked::from_bytes::<NonZeroU32>(&aligned_bytes[1..5])); + should_panic!(checked::pod_read_unaligned::<NonZeroU32>( + &aligned_bytes[1..5] + )); +} + +#[test] +fn test_char() { + assert_eq!(checked::try_cast::<u32, char>(0), Ok('\0')); + assert_eq!(checked::try_cast::<u32, char>(0xd7ff), Ok('\u{d7ff}')); + assert_eq!( + checked::try_cast::<u32, char>(0xd800), + Err(CheckedCastError::InvalidBitPattern) + ); + assert_eq!( + checked::try_cast::<u32, char>(0xdfff), + Err(CheckedCastError::InvalidBitPattern) + ); + assert_eq!(checked::try_cast::<u32, char>(0xe000), Ok('\u{e000}')); + assert_eq!(checked::try_cast::<u32, char>(0x10ffff), Ok('\u{10ffff}')); + assert_eq!( + checked::try_cast::<u32, char>(0x110000), + Err(CheckedCastError::InvalidBitPattern) + ); + assert_eq!( + checked::try_cast::<u32, char>(-1i32 as u32), + Err(CheckedCastError::InvalidBitPattern) + ); +} + +#[test] +fn test_bool() { + assert_eq!(checked::try_cast::<u8, bool>(0), Ok(false)); + assert_eq!(checked::try_cast::<u8, bool>(1), Ok(true)); + for i in 2..=255 { + assert_eq!( + checked::try_cast::<u8, bool>(i), + Err(CheckedCastError::InvalidBitPattern) + ); + } + + assert_eq!(checked::try_from_bytes::<bool>(&[1]), Ok(&true)); + assert_eq!( + checked::try_from_bytes::<bool>(&[3]), + Err(CheckedCastError::InvalidBitPattern) + ); + assert_eq!( + checked::try_from_bytes::<bool>(&[0, 1]), + Err(CheckedCastError::PodCastError(PodCastError::SizeMismatch)) + ); +} + +#[test] +fn test_all_nonzero() { + use core::num::*; + macro_rules! test_nonzero { + ($nonzero:ty: $primitive:ty) => { + assert_eq!( + checked::try_cast::<$primitive, $nonzero>(0), + Err(CheckedCastError::InvalidBitPattern) + ); + assert_eq!( + checked::try_cast::<$primitive, $nonzero>(1), + Ok(<$nonzero>::new(1).unwrap()) + ); + }; + } + + test_nonzero!(NonZeroU8: u8); + test_nonzero!(NonZeroI8: i8); + test_nonzero!(NonZeroU16: u16); + test_nonzero!(NonZeroI16: i16); + test_nonzero!(NonZeroU32: u32); + test_nonzero!(NonZeroI32: i32); + test_nonzero!(NonZeroU64: u64); + test_nonzero!(NonZeroI64: i64); + test_nonzero!(NonZeroU128: u128); + test_nonzero!(NonZeroI128: i128); + test_nonzero!(NonZeroUsize: usize); + test_nonzero!(NonZeroIsize: isize); +}
diff --git a/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/tests/derive.rs b/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/tests/derive.rs new file mode 100644 index 0000000..1c6b10e --- /dev/null +++ b/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/tests/derive.rs
@@ -0,0 +1,77 @@ +#![cfg(feature = "derive")] +#![allow(dead_code)] + +use bytemuck::{ByteEq, ByteHash, Pod, TransparentWrapper, Zeroable}; +use std::marker::PhantomData; + +#[derive(Copy, Clone, Pod, Zeroable, ByteEq, ByteHash)] +#[repr(C)] +struct Test { + a: u16, + b: u16, +} + +#[derive(TransparentWrapper)] +#[repr(transparent)] +struct TransparentSingle { + a: u16, +} + +#[derive(TransparentWrapper)] +#[repr(transparent)] +#[transparent(u16)] +struct TransparentWithZeroSized { + a: u16, + b: (), +} + +#[derive(TransparentWrapper)] +#[repr(transparent)] +struct TransparentWithGeneric<T: ?Sized> { + a: T, +} + +/// Ensuring that no additional bounds are emitted. +/// See https://github.com/Lokathor/bytemuck/issues/145 +fn test_generic<T>(x: T) -> TransparentWithGeneric<T> { + TransparentWithGeneric::wrap(x) +} + +#[derive(TransparentWrapper)] +#[repr(transparent)] +#[transparent(T)] +struct TransparentWithGenericAndZeroSized<T: ?Sized> { + a: (), + b: T, +} + +/// Ensuring that no additional bounds are emitted. +/// See https://github.com/Lokathor/bytemuck/issues/145 +fn test_generic_with_zst<T>(x: T) -> TransparentWithGenericAndZeroSized<T> { + TransparentWithGenericAndZeroSized::wrap(x) +} + +#[derive(TransparentWrapper)] +#[repr(transparent)] +struct TransparentUnsized { + a: dyn std::fmt::Debug, +} + +type DynDebug = dyn std::fmt::Debug; + +#[derive(TransparentWrapper)] +#[repr(transparent)] +#[transparent(DynDebug)] +struct TransparentUnsizedWithZeroSized { + a: (), + b: DynDebug, +} + +#[derive(TransparentWrapper)] +#[repr(transparent)] +#[transparent(DynDebug)] +struct TransparentUnsizedWithGenericZeroSizeds<T: ?Sized, U: ?Sized> { + a: PhantomData<T>, + b: PhantomData<U>, + c: DynDebug, +}
diff --git a/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/tests/doc_tests.rs b/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/tests/doc_tests.rs new file mode 100644 index 0000000..92b1b5c --- /dev/null +++ b/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/tests/doc_tests.rs
@@ -0,0 +1,124 @@ +#![allow(clippy::disallowed_names)] +#![allow(dead_code)] + +//! Cargo miri doesn't run doctests yet, so we duplicate these here. It's +//! probably not that important to sweat keeping these perfectly up to date, but +//! we should try to catch the cases where the primary tests are doctests. +use bytemuck::*; + +// Miri doesn't run on doctests, so... copypaste to the rescue. +#[test] +fn test_transparent_slice() { + #[repr(transparent)] + struct Slice<T>([T]); + + unsafe impl<T> TransparentWrapper<[T]> for Slice<T> {} + + let s = Slice::wrap_ref(&[1u32, 2, 3]); + assert_eq!(&s.0, &[1, 2, 3]); + + let mut buf = [1, 2, 3u8]; + let _sm = Slice::wrap_mut(&mut buf); +} + +#[test] +fn test_transparent_basic() { + #[derive(Default)] + struct SomeStruct(u32); + + #[repr(transparent)] + struct MyWrapper(SomeStruct); + + unsafe impl TransparentWrapper<SomeStruct> for MyWrapper {} + + // interpret a reference to &SomeStruct as a &MyWrapper + let thing = SomeStruct::default(); + let wrapped_ref: &MyWrapper = MyWrapper::wrap_ref(&thing); + + // Works with &mut too. + let mut mut_thing = SomeStruct::default(); + let wrapped_mut: &mut MyWrapper = MyWrapper::wrap_mut(&mut mut_thing); + let _ = (wrapped_ref, wrapped_mut); +} + +// Work around miri not running doctests +#[test] +fn test_contiguous_doc() { + #[repr(u8)] + #[derive(Debug, Copy, Clone, PartialEq)] + enum Foo { + A = 0, + B = 1, + C = 2, + D = 3, + E = 4, + } + unsafe impl Contiguous for Foo { + type Int = u8; + const MIN_VALUE: u8 = Foo::A as u8; + const MAX_VALUE: u8 = Foo::E as u8; + } + + assert_eq!(Foo::from_integer(3).unwrap(), Foo::D); + assert_eq!(Foo::from_integer(8), None); + assert_eq!(Foo::C.into_integer(), 2); + assert_eq!(Foo::B.into_integer(), Foo::B as u8); +} + +#[test] +fn test_offsetof_vertex() { + #[repr(C)] + struct Vertex { + pos: [f32; 2], + uv: [u16; 2], + color: [u8; 4], + } + unsafe impl Zeroable for Vertex {} + + let pos = offset_of!(Zeroable::zeroed(), Vertex, pos); + let uv = offset_of!(Zeroable::zeroed(), Vertex, uv); + let color = offset_of!(Zeroable::zeroed(), Vertex, color); + + assert_eq!(pos, 0); + assert_eq!(uv, 8); + assert_eq!(color, 12); +} + +#[test] +fn test_offsetof_nonpod() { + #[derive(Default)] + struct Foo { + a: u8, + b: &'static str, + c: i32, + } + + let a_offset = offset_of!(Default::default(), Foo, a); + let b_offset = offset_of!(Default::default(), Foo, b); + let c_offset = offset_of!(Default::default(), Foo, c); + + assert_ne!(a_offset, b_offset); + assert_ne!(b_offset, c_offset); + // We can't check against hardcoded values for a repr(Rust) type, + // but prove to ourself this way. + + let foo = Foo::default(); + // Note: offsets are in bytes. + let as_bytes = &foo as *const _ as *const u8; + + // We're using wrapping_offset here because it's not worth + // the unsafe block, but it would be valid to use `add` instead, + // as it cannot overflow. + assert_eq!( + &foo.a as *const _ as usize, + as_bytes.wrapping_add(a_offset) as usize + ); + assert_eq!( + &foo.b as *const _ as usize, + as_bytes.wrapping_add(b_offset) as usize + ); + assert_eq!( + &foo.c as *const _ as usize, + as_bytes.wrapping_add(c_offset) as usize + ); +}
diff --git a/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/tests/offset_of_tests.rs b/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/tests/offset_of_tests.rs new file mode 100644 index 0000000..4cad5d4 --- /dev/null +++ b/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/tests/offset_of_tests.rs
@@ -0,0 +1,60 @@ +#![allow(clippy::disallowed_names)] +use bytemuck::{offset_of, Zeroable}; + +#[test] +fn test_offset_of_vertex() { + #[repr(C)] + struct Vertex { + pos: [f32; 2], + uv: [u16; 2], + color: [u8; 4], + } + unsafe impl Zeroable for Vertex {} + + let pos = offset_of!(Zeroable::zeroed(), Vertex, pos); + let uv = offset_of!(Zeroable::zeroed(), Vertex, uv); + let color = offset_of!(Zeroable::zeroed(), Vertex, color); + + assert_eq!(pos, 0); + assert_eq!(uv, 8); + assert_eq!(color, 12); +} + +#[test] +fn test_offset_of_foo() { + #[derive(Default)] + struct Foo { + a: u8, + b: &'static str, + c: i32, + } + + let a_offset = offset_of!(Default::default(), Foo, a); + let b_offset = offset_of!(Default::default(), Foo, b); + let c_offset = offset_of!(Default::default(), Foo, c); + + assert_ne!(a_offset, b_offset); + assert_ne!(b_offset, c_offset); + // We can't check against hardcoded values for a repr(Rust) type, + // but prove to ourself this way. + + let foo = Foo::default(); + // Note: offsets are in bytes. + let as_bytes = &foo as *const _ as *const u8; + + // we're using wrapping_offset here because it's not worth + // the unsafe block, but it would be valid to use `add` instead, + // as it cannot overflow. + assert_eq!( + &foo.a as *const _ as usize, + as_bytes.wrapping_add(a_offset) as usize + ); + assert_eq!( + &foo.b as *const _ as usize, + as_bytes.wrapping_add(b_offset) as usize + ); + assert_eq!( + &foo.c as *const _ as usize, + as_bytes.wrapping_add(c_offset) as usize + ); +}
diff --git a/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/tests/std_tests.rs b/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/tests/std_tests.rs new file mode 100644 index 0000000..b881e5e5 --- /dev/null +++ b/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/tests/std_tests.rs
@@ -0,0 +1,107 @@ +#![allow(clippy::uninlined_format_args)] +#![allow(unused_imports)] +//! The integration tests seem to always have `std` linked, so things that would +//! depend on that can go here. + +use bytemuck::*; +use core::num::NonZeroU8; + +#[test] +fn test_transparent_vtabled() { + use core::fmt::Display; + + #[repr(transparent)] + struct DisplayTraitObj(dyn Display); + + unsafe impl TransparentWrapper<dyn Display> for DisplayTraitObj {} + + impl Display for DisplayTraitObj { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + self.0.fmt(f) + } + } + + let v = DisplayTraitObj::wrap_ref(&5i32); + let s = format!("{}", v); + assert_eq!(s, "5"); + + let mut x = 100i32; + let v_mut = DisplayTraitObj::wrap_mut(&mut x); + let s = format!("{}", v_mut); + assert_eq!(s, "100"); +} + +#[test] +#[cfg(feature = "extern_crate_alloc")] +fn test_large_box_alloc() { + type SuperPage = [[u8; 4096]; 4096]; + let _: Box<SuperPage> = try_zeroed_box().unwrap(); +} + +#[test] +#[cfg(feature = "extern_crate_alloc")] +fn test_zero_sized_box_alloc() { + #[repr(align(4096))] + struct Empty; + unsafe impl Zeroable for Empty {} + let _: Box<Empty> = try_zeroed_box().unwrap(); +} + +#[test] +#[cfg(feature = "extern_crate_alloc")] +fn test_try_from_box_bytes() { + // Different layout: target alignment is greater than source alignment. + assert_eq!( + try_from_box_bytes::<u32>(Box::new([0u8; 4]).into()).map_err(|(x, _)| x), + Err(PodCastError::AlignmentMismatch) + ); + + // Different layout: target alignment is less than source alignment. + assert_eq!( + try_from_box_bytes::<u32>(Box::new(0u64).into()).map_err(|(x, _)| x), + Err(PodCastError::AlignmentMismatch) + ); + + // Different layout: target size is greater than source size. + assert_eq!( + try_from_box_bytes::<[u32; 2]>(Box::new(0u32).into()).map_err(|(x, _)| x), + Err(PodCastError::SizeMismatch) + ); + + // Different layout: target size is less than source size. + assert_eq!( + try_from_box_bytes::<u32>(Box::new([0u32; 2]).into()).map_err(|(x, _)| x), + Err(PodCastError::SizeMismatch) + ); + + // Round trip: alignment is equal to size. + assert_eq!(*from_box_bytes::<u32>(Box::new(1000u32).into()), 1000u32); + + // Round trip: alignment is divider of size. + assert_eq!(&*from_box_bytes::<[u8; 5]>(Box::new(*b"hello").into()), b"hello"); + + // It's ok for T to have uninitialized bytes. + #[cfg(feature = "derive")] + { + #[derive(Debug, Copy, Clone, PartialEq, Eq, AnyBitPattern)] + struct Foo(u8, u16); + assert_eq!( + *from_box_bytes::<Foo>(Box::new([0xc5c5u16; 2]).into()), + Foo(0xc5u8, 0xc5c5u16) + ); + } +} + +#[test] +#[cfg(feature = "extern_crate_alloc")] +fn test_box_bytes_of() { + assert_eq!(&*box_bytes_of(Box::new(*b"hello")), b"hello"); + + #[cfg(target_endian = "big")] + assert_eq!(&*box_bytes_of(Box::new(0x12345678)), b"\x12\x34\x56\x78"); + #[cfg(target_endian = "little")] + assert_eq!(&*box_bytes_of(Box::new(0x12345678)), b"\x78\x56\x34\x12"); + + // It's ok for T to have invalid bit patterns. + assert_eq!(&*box_bytes_of(Box::new(NonZeroU8::new(0xc5))), b"\xc5"); +}
diff --git a/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/tests/transparent.rs b/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/tests/transparent.rs new file mode 100644 index 0000000..be26c21 --- /dev/null +++ b/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/tests/transparent.rs
@@ -0,0 +1,116 @@ +// Currently this test doesn't actually check the output of the functions. +// It's only here for miri to check for any potential undefined behaviour. +// TODO: check function results + +#[test] +fn test_transparent_wrapper() { + // An external type defined in a different crate. + #[derive(Debug, Copy, Clone, Default)] + struct Foreign(u8); + + use bytemuck::TransparentWrapper; + + #[derive(Debug, Copy, Clone)] + #[repr(transparent)] + struct Wrapper(Foreign); + + unsafe impl TransparentWrapper<Foreign> for Wrapper {} + + // Traits can be implemented on crate-local wrapper. + unsafe impl bytemuck::Zeroable for Wrapper {} + unsafe impl bytemuck::Pod for Wrapper {} + + impl PartialEq<u8> for Foreign { + fn eq(&self, &other: &u8) -> bool { + self.0 == other + } + } + + impl PartialEq<u8> for Wrapper { + fn eq(&self, &other: &u8) -> bool { + self.0 == other + } + } + + let _: u8 = bytemuck::cast(Wrapper::wrap(Foreign::default())); + let _: Foreign = Wrapper::peel(bytemuck::cast(u8::default())); + + let _: &u8 = bytemuck::cast_ref(Wrapper::wrap_ref(&Foreign::default())); + let _: &Foreign = Wrapper::peel_ref(bytemuck::cast_ref(&u8::default())); + + let _: &mut u8 = + bytemuck::cast_mut(Wrapper::wrap_mut(&mut Foreign::default())); + let _: &mut Foreign = + Wrapper::peel_mut(bytemuck::cast_mut(&mut u8::default())); + + let _: &[u8] = + bytemuck::cast_slice(Wrapper::wrap_slice(&[Foreign::default()])); + let _: &[Foreign] = + Wrapper::peel_slice(bytemuck::cast_slice(&[u8::default()])); + + let _: &mut [u8] = + bytemuck::cast_slice_mut(Wrapper::wrap_slice_mut( + &mut [Foreign::default()], + )); + let _: &mut [Foreign] = + Wrapper::peel_slice_mut(bytemuck::cast_slice_mut(&mut [u8::default()])); + + let _: &[u8] = bytemuck::bytes_of(Wrapper::wrap_ref(&Foreign::default())); + let _: &Foreign = Wrapper::peel_ref(bytemuck::from_bytes(&[u8::default()])); + + let _: &mut [u8] = + bytemuck::bytes_of_mut(Wrapper::wrap_mut(&mut Foreign::default())); + let _: &mut Foreign = + Wrapper::peel_mut(bytemuck::from_bytes_mut(&mut [u8::default()])); + + // not sure if this is the right usage + let _ = + bytemuck::pod_align_to::<_, u8>(Wrapper::wrap_slice(&[Foreign::default()])); + // counterpart? + + // not sure if this is the right usage + let _ = bytemuck::pod_align_to_mut::<_, u8>(Wrapper::wrap_slice_mut(&mut [ + Foreign::default(), + ])); + // counterpart? + + #[cfg(feature = "extern_crate_alloc")] + { + use bytemuck::allocation::TransparentWrapperAlloc; + use std::rc::Rc; + + let a: Vec<Foreign> = vec![Foreign::default(); 2]; + + let b: Vec<Wrapper> = Wrapper::wrap_vec(a); + assert_eq!(b, [0, 0]); + + let c: Vec<Foreign> = Wrapper::peel_vec(b); + assert_eq!(c, [0, 0]); + + let d: Box<Foreign> = Box::new(Foreign::default()); + + let e: Box<Wrapper> = Wrapper::wrap_box(d); + assert_eq!(&*e, &0); + let f: Box<Foreign> = Wrapper::peel_box(e); + assert_eq!(&*f, &0); + + let g: Rc<Foreign> = Rc::new(Foreign::default()); + + let h: Rc<Wrapper> = Wrapper::wrap_rc(g); + assert_eq!(&*h, &0); + let i: Rc<Foreign> = Wrapper::peel_rc(h); + assert_eq!(&*i, &0); + + #[cfg(target_has_atomic = "ptr")] + { + use std::sync::Arc; + + let j: Arc<Foreign> = Arc::new(Foreign::default()); + + let k: Arc<Wrapper> = Wrapper::wrap_arc(j); + assert_eq!(&*k, &0); + let l: Arc<Foreign> = Wrapper::peel_arc(k); + assert_eq!(&*l, &0); + } + } +}
diff --git a/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/tests/wrapper_forgets.rs b/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/tests/wrapper_forgets.rs new file mode 100644 index 0000000..54847444 --- /dev/null +++ b/third_party/rust/chromium_crates_io/vendor/bytemuck-1.14.3/tests/wrapper_forgets.rs
@@ -0,0 +1,13 @@ +use bytemuck::TransparentWrapper; + +#[repr(transparent)] +struct Wrap(Box<u32>); + +// SAFETY: it's #[repr(transparent)] +unsafe impl TransparentWrapper<Box<u32>> for Wrap {} + +fn main() { + let value = Box::new(5); + // This used to duplicate the wrapped value, creating a double free :( + Wrap::wrap(value); +}
diff --git a/third_party/skia b/third_party/skia index 9b08a3f..9950dc8 160000 --- a/third_party/skia +++ b/third_party/skia
@@ -1 +1 @@ -Subproject commit 9b08a3f3881c1df237eea2c7ec46de8d45b1f319 +Subproject commit 9950dc8ec6fd376a48fb1e892ed4ef040bf07331
diff --git a/third_party/vulkan-deps b/third_party/vulkan-deps index fa1e68d..074f27e 160000 --- a/third_party/vulkan-deps +++ b/third_party/vulkan-deps
@@ -1 +1 @@ -Subproject commit fa1e68dabb9108b6651b56bfee37a4688cdd5446 +Subproject commit 074f27e83c5591c976f789a7f3bd4447124e9640
diff --git a/tools/clang/scripts/update.py b/tools/clang/scripts/update.py index 677ce05..1c9c6fc 100755 --- a/tools/clang/scripts/update.py +++ b/tools/clang/scripts/update.py
@@ -138,7 +138,7 @@ output_file.write(gzip_decode.flush()) print(' Done.') return - except urllib.error.URLError as e: + except (ConnectionError, urllib.error.URLError) as e: sys.stdout.write('\n') print(e) if num_retries == 0 or isinstance(
diff --git a/tools/licenses/licenses.py b/tools/licenses/licenses.py index cc7b17e1..f3a8ba37 100755 --- a/tools/licenses/licenses.py +++ b/tools/licenses/licenses.py
@@ -641,6 +641,10 @@ if path in THIRD_PARTY_FOR_BUILD_FILES_ONLY: return [], [] + # gclient creates empty directories for conditionally downloaded submodules. + if not os.listdir(os.path.join(root, path)): + return [], [] + # Get the metadata values, from # (a) looking up the path in SPECIAL_CASES; or # (b) parsing the metadata from a README.chromium file. @@ -798,7 +802,8 @@ extra_paths.update(extra_third_party_dirs) for dir in extra_paths: - if dir not in prune_paths: + # They might not exist due to gclient conditions. + if dir not in prune_paths and os.path.exists(os.path.join(root, dir)): third_party_dirs.add(dir) ProcessAdditionalReadmePathsJson(root, dir, third_party_dirs)
diff --git a/tools/licenses/licenses_test.py b/tools/licenses/licenses_test.py index cb0221e..33ec2402 100755 --- a/tools/licenses/licenses_test.py +++ b/tools/licenses/licenses_test.py
@@ -83,7 +83,7 @@ def test_parse_dir(self): # No metadata file found in directory - test_path = os.path.join('tools', 'licenses', 'foo') + test_path = os.path.join('tools', 'licenses', 'test_dir_with_missing_files') with self.assertRaisesRegex( licenses.LicenseError, "missing third party metadata file or licenses.py SPECIAL_CASES"):
diff --git a/tools/licenses/test_dir_with_missing_files/non_empty_directory b/tools/licenses/test_dir_with_missing_files/non_empty_directory new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tools/licenses/test_dir_with_missing_files/non_empty_directory
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index c43e0497..b49c3a3f 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -3216,6 +3216,7 @@ <int value="-102" label="CONNECTION_REFUSED"/> <int value="-101" label="CONNECTION_RESET"/> <int value="-100" label="CONNECTION_CLOSED"/> + <int value="-33" label="NETWORK_ACCESS_REVOKED"/> <int value="-32" label="BLOCKED_BY_ORB"/> <int value="-31" label="H2_OR_QUIC_REQUIRED"/> <int value="-30" label="BLOCKED_BY_CSP"/> @@ -4047,6 +4048,7 @@ <int value="28" label="trigger_context_id disallowed for aggregatable_source_registration_time"/> + <int value="29" label="event_trigger_data value field is invalid"/> </enum> <enum name="ConversionTriggerVerificationGetHeadersStatus"> @@ -27078,6 +27080,7 @@ <int value="30" label="BLOCKED_BY_CSP"/> <int value="31" label="H2_OR_QUIC_REQUIRED"/> <int value="32" label="BLOCKED_BY_ORB"/> + <int value="33" label="NETWORK_ACCESS_REVOKED"/> <int value="100" label="CONNECTION_CLOSED"/> <int value="101" label="CONNECTION_RESET"/> <int value="102" label="CONNECTION_REFUSED"/>
diff --git a/tools/metrics/histograms/metadata/apps/enums.xml b/tools/metrics/histograms/metadata/apps/enums.xml index fe61b28..7ae0e8c 100644 --- a/tools/metrics/histograms/metadata/apps/enums.xml +++ b/tools/metrics/histograms/metadata/apps/enums.xml
@@ -78,6 +78,15 @@ <int value="3" label="PWA"/> </enum> +<enum name="AppListContinueFileSuggestionType"> + <int value="0" label="Recently viewed drive file"/> + <int value="1" label="Recently modified drive file"/> + <int value="2" label="Drive file recently modified by user"/> + <int value="3" label="Drive file recently shared with user"/> + <int value="4" label="Recently viewed local file"/> + <int value="5" label="Local file recently modified by user"/> +</enum> + <enum name="AppListFederatedActions"> <int value="0" label="Impression"/> <int value="1" label="Launch"/>
diff --git a/tools/metrics/histograms/metadata/apps/histograms.xml b/tools/metrics/histograms/metadata/apps/histograms.xml index cf39c53..c001f31b 100644 --- a/tools/metrics/histograms/metadata/apps/histograms.xml +++ b/tools/metrics/histograms/metadata/apps/histograms.xml
@@ -939,6 +939,37 @@ </token> </histogram> +<histogram + name="Apps.AppList.Search.Continue.FileSuggestionType.{SearchAction}" + enum="AppListContinueFileSuggestionType" expires_after="2024-07-31"> + <owner>tbarzic@google.com</owner> + <owner>chromeos-launcher@google.com</owner> + <summary> + Tracks launches, impressions, abandons, and ignores for search result sub + types in the launcher continue section. These metrics are all emitted once + for each unique displayed search result sub type, for results that have a + subtype defined. + + For example, if we show the user three recently modified drive files and two + recently viewed drive files, and the user clicks a recently modified drive + file, then we would record: one impression for each of recently modified + drive file and recently viewed drive file, one launch for recently modified + drive file, and one abandon for recently viewed drive file. + + Launch. Emitted after an impression, if the user launches a result. + + Abandon. Emitted after an impression, if the user closes the launcher or + moves to a different view. + + Ignore. Emitted after an impression, if the user then launched a different + result. + + Impression. Emitted if either a) a set of results is displayed for 2 seconds + or b) the user interacted with a result, eg. by clicking it. + </summary> + <token key="SearchAction" variants="SearchAction"/> +</histogram> + <histogram name="Apps.AppList.Search.ContinueResultCount.{Type}" units="count" expires_after="2024-09-14"> <owner>dgrebenyuk@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/autofill/histograms.xml b/tools/metrics/histograms/metadata/autofill/histograms.xml index 8eff0185..50df16c 100644 --- a/tools/metrics/histograms/metadata/autofill/histograms.xml +++ b/tools/metrics/histograms/metadata/autofill/histograms.xml
@@ -593,17 +593,6 @@ </summary> </histogram> -<histogram name="Autofill.AcceptedPreviouslyHiddenSuggestion" enum="Boolean" - expires_after="2024-12-12"> - <owner>jihadghanna@google.com</owner> - <owner>chrome-autofill-alerts@google.com</owner> - <summary> - Logs if the suggestion accepted by the user was previously hidden due to - address types being initially ignored in profile subset comparison. Emitted - every time a user accepts a `PopupItemId::kAddressEntry` suggestion. - </summary> -</histogram> - <histogram name="Autofill.Address.IsEnabled.PageLoad" enum="BooleanEnabled" expires_after="2024-09-01"> <owner>koerber@google.com</owner> @@ -3776,17 +3765,6 @@ <token key="FormType" variants="Autofill.Ablation.FormType"/> </histogram> -<histogram name="Autofill.PreviouslyHiddenSuggestionNumber" units="suggestions" - expires_after="2024-12-12"> - <owner>jihadghanna@google.com</owner> - <owner>chrome-autofill-alerts@google.com</owner> - <summary> - Logs the number suggestion displayed to the user that were previously hidden - due to address types being initially ignored in profile subset comparison. - Emitted once per suggestion generation. - </summary> -</histogram> - <histogram name="Autofill.ProfileDeleted.{DeletionType}" enum="BooleanAutofillDeleteAddress" expires_after="2024-10-01"> <owner>tchudakov@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/cros_audio/histograms.xml b/tools/metrics/histograms/metadata/cros_audio/histograms.xml index 5f8b35c1..1f654e0 100644 --- a/tools/metrics/histograms/metadata/cros_audio/histograms.xml +++ b/tools/metrics/histograms/metadata/cros_audio/histograms.xml
@@ -166,6 +166,30 @@ </histogram> <histogram + name="ChromeOS.AudioSelection.{AudioType}.System{SwitchDecision}Audio.BeforeAndAfterAudioDeviceSet.{IsChromeRestarts}" + units="counts" expires_after="2025-02-25"> + <owner>zhangwenyu@google.com</owner> + <owner>cros-peripherals@google.com</owner> + <summary> + Similar to + ChromeOS.AudioSelection.{AudioType}.System{SwitchDecision}Audio.BeforeAndAfterAudioDeviceSet + but only recorded in cases of {IsChromeRestarts}. + </summary> + <token key="AudioType"> + <variant name="Input" summary="input"/> + <variant name="Output" summary="output"/> + </token> + <token key="SwitchDecision"> + <variant name="NotSwitch" summary="not switching"/> + <variant name="Switch" summary="switching"/> + </token> + <token key="IsChromeRestarts"> + <variant name="ChromeRestarts" summary="chrome restarts"/> + <variant name="NonChromeRestarts" summary="non chrome restarts"/> + </token> +</histogram> + +<histogram name="ChromeOS.AudioSelection.{AudioType}.UserOverrideSystem{SwitchDecision}TimeElapsed" units="minutes" expires_after="2024-09-01"> <owner>zhangwenyu@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/enterprise/enums.xml b/tools/metrics/histograms/metadata/enterprise/enums.xml index 2e9e1c27..3f50cd8 100644 --- a/tools/metrics/histograms/metadata/enterprise/enums.xml +++ b/tools/metrics/histograms/metadata/enterprise/enums.xml
@@ -2079,6 +2079,7 @@ <int value="1237" label="EnterpriseLogoUrl"/> <int value="1238" label="CustomProfileLabel"/> <int value="1239" label="ProfileLabel"/> + <int value="1240" label="PrivacySandboxFingerprintingProtectionEnabled"/> </enum> <enum name="EnterprisePoliciesSources">
diff --git a/tools/metrics/histograms/metadata/history/histograms.xml b/tools/metrics/histograms/metadata/history/histograms.xml index 75ae8a52..6c50ef9c 100644 --- a/tools/metrics/histograms/metadata/history/histograms.xml +++ b/tools/metrics/histograms/metadata/history/histograms.xml
@@ -494,35 +494,6 @@ </summary> </histogram> -<histogram name="History.Clusters.Backend.BatchEntityLookupLatency2" units="ms" - expires_after="2024-09-01"> - <owner>mcrouse@chromium.org</owner> - <owner>chrome-journeys@google.com</owner> - <component>UI>Browser>Journeys</component> - <summary> - Logs the latency of querying entities for all the visits being clustered by - the on-device backend. Logged when clusters have been calculated based on - any request to cluster visits, which could be triggered from several things, - including loading the journeys UI, putting a query in the journeys page, - etc.. - </summary> -</histogram> - -<histogram name="History.Clusters.Backend.BatchEntityLookupSize" units="count" - expires_after="2024-09-01"> - <owner>mcrouse@chromium.org</owner> - <owner>chrome-journeys@google.com</owner> - <component>UI>Browser>Journeys</component> - <summary> - Logs the number of entities to be queried for their metadata when preparing - to start clustering. The number of entities is the size of the entire batch - which is over all visits provided to the backend for clustering. Logged when - clusters are requested based on any request to cluster visits, which could - be triggered from several things, including loading the journeys UI, putting - a query in the journeys page, etc.. - </summary> -</histogram> - <histogram name="History.Clusters.Backend.ClusterSimilarityHeuristicsProcessor.ClusterSearchTermOverriden" enum="Boolean" expires_after="2024-04-28"> @@ -593,50 +564,6 @@ </summary> </histogram> -<histogram - name="History.Clusters.Backend.ContentClustering.NumClustersAfterMerge" - units="counts" expires_after="2024-02-11"> - <owner>sophiechang@chromium.org</owner> - <owner>chrome-journeys@google.com</owner> - <component>UI>Browser>Journeys</component> - <summary> - Records the number of clusters after merging similar clusters based on - content. Logged when clusters have been calculated based on any request to - cluster visits, which could be triggered from several things, including - loading the journeys UI, putting a query in the journeys page, etc... - </summary> -</histogram> - -<histogram - name="History.Clusters.Backend.ContentClustering.NumClustersBeforeMerge" - units="counts" expires_after="2024-02-11"> - <owner>sophiechang@chromium.org</owner> - <owner>chrome-journeys@google.com</owner> - <component>UI>Browser>Journeys</component> - <summary> - Records the number of clusters before merging similar clusters based on - content. Logged when clusters have been calculated based on any request to - cluster visits, which could be triggered from several things, including - loading the journeys UI, putting a query in the journeys page, etc... - </summary> -</histogram> - -<histogram - name="History.Clusters.Backend.ContentClustering.PairwiseMergeNumIterations" - units="counts" expires_after="2024-03-24"> - <owner>sophiechang@chromium.org</owner> - <owner>chrome-journeys@google.com</owner> - <component>UI>Browser>Journeys</component> - <summary> - Records the number of iterations it took for a batch of clusters to converge - during a pairwise merge of similar clusters based on content, up to a - Finch-configured maximum. Logged when clusters have been calculated based on - any request to cluster visits, which could be triggered from several things, - including loading the journeys UI, putting a query in the journeys page, - etc... - </summary> -</histogram> - <histogram name="History.Clusters.Backend.ContextClusterer.ThreadTime" units="ms" expires_after="2024-09-01"> <owner>sophiechang@chromium.org</owner> @@ -653,21 +580,6 @@ </summary> </histogram> -<histogram name="History.Clusters.Backend.EntityIdGathering.ThreadTime" - units="ms" expires_after="2024-09-01"> - <owner>sophiechang@chromium.org</owner> - <owner>chrome-journeys@google.com</owner> - <component>UI>Browser>Journeys</component> - <summary> - Logs the time taken to gather all entity IDs that require fetching - additional metadata for, which is performed on the UI thread. This does not - include any thread hop or queuing delay. Logged when clusters have been - calculated based on any request to cluster visits, which could be triggered - from several things, including loading the journeys UI, putting a query in - the journeys page, etc... - </summary> -</histogram> - <histogram name="History.Clusters.Backend.FilterClusterProcessor.ClusterFilterReason{Source}" enum="ClusterFilterReason" expires_after="2024-08-04">
diff --git a/tools/metrics/histograms/metadata/settings/histograms.xml b/tools/metrics/histograms/metadata/settings/histograms.xml index 4dd4bf5..ade1d8cc8 100644 --- a/tools/metrics/histograms/metadata/settings/histograms.xml +++ b/tools/metrics/histograms/metadata/settings/histograms.xml
@@ -312,6 +312,16 @@ </summary> </histogram> +<histogram name="Settings.PrivacySandbox.ConsentCheckIsMismatched" + enum="Boolean" expires_after="2024-08-28"> + <owner>boujane@google.com</owner> + <owner>koilos@google.com</owner> + <summary> + Records mismatches between the calculated consent requirement and any + overrides applied to the Privacy Sandbox consent param. + </summary> +</histogram> + <histogram name="Settings.PrivacySandbox.DialogDisplayHost" enum="SettingsPrivacySandboxDialogDisplayHostHash" expires_after="2024-09-01"> @@ -386,6 +396,16 @@ </summary> </histogram> +<histogram name="Settings.PrivacySandbox.NoticeCheckIsMismatched" + enum="Boolean" expires_after="2024-08-28"> + <owner>boujane@google.com</owner> + <owner>koilos@google.com</owner> + <summary> + Records mismatches between the calculated notice requirement and any + overrides applied to the Privacy Sandbox notice param. + </summary> +</histogram> + <histogram name="Settings.PrivacySandbox.PrivacySandboxReferrer" enum="PrivacySandboxReferrer" expires_after="2023-02-12"> <owner>andzaytsev@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/sync/histograms.xml b/tools/metrics/histograms/metadata/sync/histograms.xml index c7bfc3b1..8e9373c1 100644 --- a/tools/metrics/histograms/metadata/sync/histograms.xml +++ b/tools/metrics/histograms/metadata/sync/histograms.xml
@@ -1740,7 +1740,7 @@ </histogram> <histogram name="Sync.ThrottledSomeModelTypes" enum="SyncModelTypes" - expires_after="2024-04-28"> + expires_after="2025-04-28"> <owner>victorvianna@google.com</owner> <owner>src/components/sync/OWNERS</owner> <component>Services>Sync</component>
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json index 4483e99..658bd499 100644 --- a/tools/perf/core/perfetto_binary_roller/binary_deps.json +++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -6,7 +6,7 @@ }, "win": { "hash": "62fc1bf75382e1baf67c8922603dd0843e307f60", - "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/bee15bb3172197dc48e65aa67f41037bc140c6d1/trace_processor_shell.exe" + "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/7e63f42d755ca255162f1f327126f90e34465581/trace_processor_shell.exe" }, "linux_arm": { "hash": "aa33f55a1523af4f0fa33f09a2d7ec44276e6b18", @@ -14,7 +14,7 @@ }, "mac": { "hash": "f2a5ce0a81f47f6386e9560f6291da78e1c82fe0", - "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/mac/bee15bb3172197dc48e65aa67f41037bc140c6d1/trace_processor_shell" + "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/mac/7e63f42d755ca255162f1f327126f90e34465581/trace_processor_shell" }, "mac_arm64": { "hash": "efba8361ce036a2249cdf34180ac8c671a1caf69", @@ -22,7 +22,7 @@ }, "linux": { "hash": "ad33541876d824c897dfc65e8422e1c91b8149ea", - "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/bee15bb3172197dc48e65aa67f41037bc140c6d1/trace_processor_shell" + "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/7e63f42d755ca255162f1f327126f90e34465581/trace_processor_shell" } }, "power_profile.sql": {
diff --git a/ui/accessibility/accessibility_features.cc b/ui/accessibility/accessibility_features.cc index 851df8a..e00a4623 100644 --- a/ui/accessibility/accessibility_features.cc +++ b/ui/accessibility/accessibility_features.cc
@@ -203,7 +203,7 @@ BASE_FEATURE(kAccessibilityExtraLargeCursor, "AccessibilityExtraLargeCursor", - base::FEATURE_DISABLED_BY_DEFAULT); + base::FEATURE_ENABLED_BY_DEFAULT); bool IsAccessibilityExtraLargeCursorEnabled() { return base::FeatureList::IsEnabled( ::features::kAccessibilityExtraLargeCursor);
diff --git a/ui/base/ime/init/input_method_initializer.cc b/ui/base/ime/init/input_method_initializer.cc index a500669..bddb5c06 100644 --- a/ui/base/ime/init/input_method_initializer.cc +++ b/ui/base/ime/init/input_method_initializer.cc
@@ -32,6 +32,16 @@ #endif } +void RestartInputMethod() { +#if !BUILDFLAG(IS_CHROMEOS_ASH) && BUILDFLAG(IS_WIN) + // Some tests don't have a TSFBridge and may cause error if we set one. + if (TSFBridge::GetInstance()) { + TSFBridge::Shutdown(); + TSFBridge::Initialize(); + } +#endif +} + void InitializeInputMethodForTesting() { #if defined(USE_AURA) && BUILDFLAG(IS_LINUX) GetInputMethodContextFactoryForTest() =
diff --git a/ui/base/ime/init/input_method_initializer.h b/ui/base/ime/init/input_method_initializer.h index 358bdc9..ef14c6e3 100644 --- a/ui/base/ime/init/input_method_initializer.h +++ b/ui/base/ime/init/input_method_initializer.h
@@ -17,6 +17,10 @@ // called in the UI thread after input method is used. COMPONENT_EXPORT(UI_BASE_IME_INIT) void ShutdownInputMethod(); +// https://crbug.com/41486958 +// Prevent TSF from hanging on Windows, for details read links above. +COMPONENT_EXPORT(UI_BASE_IME_INIT) void RestartInputMethod(); + // Initializes thread-local resources for input method. This function is // intended to be called from Setup function of unit tests. COMPONENT_EXPORT(UI_BASE_IME_INIT) void InitializeInputMethodForTesting();
diff --git a/ui/base/test/cocoa_helper.mm b/ui/base/test/cocoa_helper.mm index dd5a3fc..c57232c 100644 --- a/ui/base/test/cocoa_helper.mm +++ b/ui/base/test/cocoa_helper.mm
@@ -252,6 +252,13 @@ WeakWindowVector windows = ApplicationWindows(); WeakWindowSet windows_set(windows.begin(), windows.end()); + // Ignore TextInputUIMacHelper.framework created TUINSWindow. We have no + // control or documentation about these windows, ignoring them seems like the + // best approach. + std::erase_if(windows_set, [](NSWindow* __weak set_window) { + return [set_window isKindOfClass:NSClassFromString(@"TUINSWindow")]; + }); + // Subtract away the initial windows. The current window set will not have any // nil values, as it was just obtained, so subtracting away the nil from any // initial windows that have been closed is safe.
diff --git a/ui/gl/dcomp_presenter.cc b/ui/gl/dcomp_presenter.cc index c46e6ce..41f858c 100644 --- a/ui/gl/dcomp_presenter.cc +++ b/ui/gl/dcomp_presenter.cc
@@ -30,7 +30,7 @@ DCompPresenter::PendingFrame& DCompPresenter::PendingFrame::operator=( PendingFrame&& other) = default; -DCompPresenter::DCompPresenter(GLDisplayEGL* display, const Settings& settings) +DCompPresenter::DCompPresenter(const Settings& settings) : task_runner_(base::SingleThreadTaskRunner::GetCurrentDefault()), max_pending_frames_(settings.max_pending_frames), layer_tree_(std::make_unique<DCLayerTree>( @@ -55,7 +55,7 @@ child_window_.Initialize(); - if (!layer_tree_->Initialize(window(), d3d11_device_)) { + if (!layer_tree_->Initialize(child_window_.window(), d3d11_device_)) { return false; } @@ -265,4 +265,8 @@ StartOrStopVSyncThread(); } +HWND DCompPresenter::GetWindow() const { + return child_window_.window(); +} + } // namespace gl
diff --git a/ui/gl/dcomp_presenter.h b/ui/gl/dcomp_presenter.h index 001ef2a..b3965b64 100644 --- a/ui/gl/dcomp_presenter.h +++ b/ui/gl/dcomp_presenter.h
@@ -55,8 +55,7 @@ bool no_downscaled_overlay_promotion = false; }; - DCompPresenter(GLDisplayEGL* display, - const Settings& settings); + explicit DCompPresenter(const Settings& settings); DCompPresenter(const DCompPresenter&) = delete; DCompPresenter& operator=(const DCompPresenter&) = delete; @@ -95,7 +94,7 @@ mojo::PendingReceiver<gfx::mojom::DelegatedInkPointRenderer> pending_receiver) override; - HWND window() const { return child_window_.window(); } + HWND GetWindow() const override; scoped_refptr<base::TaskRunner> GetWindowTaskRunnerForTesting();
diff --git a/ui/gl/dcomp_presenter_unittest.cc b/ui/gl/dcomp_presenter_unittest.cc index 869ea0b..d2afd0b 100644 --- a/ui/gl/dcomp_presenter_unittest.cc +++ b/ui/gl/dcomp_presenter_unittest.cc
@@ -237,8 +237,7 @@ scoped_refptr<DCompPresenter> CreateDCompPresenter() { DCompPresenter::Settings settings; scoped_refptr<DCompPresenter> presenter = - base::MakeRefCounted<DCompPresenter>( - gl::GLSurfaceEGL::GetGLDisplayEGL(), settings); + base::MakeRefCounted<DCompPresenter>(settings); EXPECT_TRUE(presenter->Initialize()); // ImageTransportSurfaceDelegate::AddChildWindowToBrowser() is called in @@ -246,7 +245,7 @@ // gpu/ipc/service/image_transport_presenter_delegate.h, here we directly // executes the required minimum code. if (parent_window_) - ::SetParent(presenter->window(), parent_window_); + ::SetParent(presenter->GetWindow(), parent_window_); return presenter; }
diff --git a/ui/gl/delegated_ink_point_renderer_gpu_unittest.cc b/ui/gl/delegated_ink_point_renderer_gpu_unittest.cc index 135f57b2..9f2525ed 100644 --- a/ui/gl/delegated_ink_point_renderer_gpu_unittest.cc +++ b/ui/gl/delegated_ink_point_renderer_gpu_unittest.cc
@@ -137,16 +137,12 @@ private: void CreateDCompPresenter() { DCompPresenter::Settings settings; - presenter_ = base::MakeRefCounted<DCompPresenter>( - gl::GLSurfaceEGL::GetGLDisplayEGL(), settings); + presenter_ = base::MakeRefCounted<DCompPresenter>(settings); EXPECT_TRUE(presenter_->Initialize()); - // ImageTransportSurfaceDelegate::AddChildWindowToBrowser() is called in - // production code here. However, to remove dependency from - // gpu/ipc/service/image_transport_surface_delegate.h, here we directly - // executes the required minimum code. + // Add our child window to the root window. if (parent_window_) - ::SetParent(presenter_->window(), parent_window_); + ::SetParent(presenter_->GetWindow(), parent_window_); } void DestroyPresenter(scoped_refptr<DCompPresenter> presenter) {
diff --git a/ui/gl/direct_composition_surface_win_unittest.cc b/ui/gl/direct_composition_surface_win_unittest.cc index 90155dc..d2e46a1 100644 --- a/ui/gl/direct_composition_surface_win_unittest.cc +++ b/ui/gl/direct_composition_surface_win_unittest.cc
@@ -170,10 +170,7 @@ gl::GLSurfaceEGL::GetGLDisplayEGL(), settings); EXPECT_TRUE(surface->Initialize(GLSurfaceFormat())); - // ImageTransportSurfaceDelegate::AddChildWindowToBrowser() is called in - // production code here. However, to remove dependency from - // gpu/ipc/service/image_transport_surface_delegate.h, here we directly - // executes the required minimum code. + // Add our child window to the root window. if (parent_window_) ::SetParent(surface->window(), parent_window_);
diff --git a/ui/gl/presenter.h b/ui/gl/presenter.h index 852265e..7da4ed1f 100644 --- a/ui/gl/presenter.h +++ b/ui/gl/presenter.h
@@ -30,6 +30,10 @@ #include "base/android/scoped_hardware_buffer_fence_sync.h" #endif +#if BUILDFLAG(IS_WIN) +#include "base/win/windows_types.h" +#endif + namespace gfx { namespace mojom { class DelegatedInkPointRenderer; @@ -148,6 +152,7 @@ virtual void InitDelegatedInkPointRendererReceiver( mojo::PendingReceiver<gfx::mojom::DelegatedInkPointRenderer> pending_receiver) {} + virtual HWND GetWindow() const = 0; #endif // Tells the presenter to rely on implicit sync when presenting buffers.
diff --git a/ui/native_theme/native_theme.cc b/ui/native_theme/native_theme.cc index c5bcbe6..2e0502f3 100644 --- a/ui/native_theme/native_theme.cc +++ b/ui/native_theme/native_theme.cc
@@ -293,10 +293,7 @@ system_colors_ = colors; } -bool NativeTheme::UpdateSystemColorInfo( - bool is_dark_mode, - bool forced_colors, - const base::flat_map<SystemThemeColor, uint32_t>& colors) { +bool NativeTheme::UpdateSystemColorInfo(bool is_dark_mode, bool forced_colors) { bool did_system_color_info_change = false; if (is_dark_mode != ShouldUseDarkColors()) { did_system_color_info_change = true; @@ -306,12 +303,6 @@ did_system_color_info_change = true; set_forced_colors(forced_colors); } - for (const auto& color : colors) { - if (color.second != GetSystemThemeColor(color.first)) { - did_system_color_info_change = true; - system_colors_[color.first] = color.second; - } - } return did_system_color_info_change; } @@ -392,14 +383,6 @@ notify_observers = true; } - // TODO(samomekarajr): Take this out when fully migrated to the color - // pipeline. - const auto& system_colors = observed_theme->GetSystemColors(); - if (theme_to_update_->HasDifferentSystemColors(system_colors)) { - theme_to_update_->set_system_colors(system_colors); - notify_observers = true; - } - if (notify_observers) { DCHECK(theme_to_update_->UserHasContrastPreference() || !theme_to_update_->InForcedColorsMode());
diff --git a/ui/native_theme/native_theme.h b/ui/native_theme/native_theme.h index e1c2037..399e914 100644 --- a/ui/native_theme/native_theme.h +++ b/ui/native_theme/native_theme.h
@@ -566,13 +566,12 @@ return should_use_system_accent_color_; } + // TODO(crbug.com/40779801): Remove this when we use the forced colors web + // setting in Blink. // Updates the state of dark mode, forced colors mode, and the map of system // colors. Returns true if NativeTheme was updated as a result, or false if // the state of NativeTheme was untouched. - bool UpdateSystemColorInfo( - bool is_dark_mode, - bool forced_colors, - const base::flat_map<SystemThemeColor, uint32_t>& colors); + bool UpdateSystemColorInfo(bool is_dark_mode, bool forced_colors); // On certain platforms, currently only Mac, there is a unique visual for // pressed states.
diff --git a/ui/views/cocoa/native_widget_mac_ns_window_host.mm b/ui/views/cocoa/native_widget_mac_ns_window_host.mm index 800e715..7201c4c 100644 --- a/ui/views/cocoa/native_widget_mac_ns_window_host.mm +++ b/ui/views/cocoa/native_widget_mac_ns_window_host.mm
@@ -1258,6 +1258,14 @@ bool is_key, bool is_content_first_responder, bool full_keyboard_access_enabled) { + // We need `setRemoteUIApp` to YES to support some accessibility + // features on out-of-process remote cocoa windows like those used + // for PWAs. However this breaks accessibility on in-process windows, + // so set it back to NO when a local window gains focus. See + // https://crbug.com/41485830. + if (is_key && features::IsAccessibilityRemoteUIAppEnabled()) { + [NSAccessibilityRemoteUIElement setRemoteUIApp:!!application_host_]; + } // Explicitly set the keyboard accessibility state on regaining key // window status. if (is_key && is_content_first_responder) @@ -1416,11 +1424,6 @@ ui::RemoteAccessibility::GetRemoteElementFromToken(view_token); [remote_view_accessible_ setWindowUIElement:remote_window_accessible_]; [remote_view_accessible_ setTopLevelUIElement:remote_window_accessible_]; - - if (features::IsAccessibilityRemoteUIAppEnabled() && - ![NSAccessibilityRemoteUIElement isRemoteUIApp]) { - [NSAccessibilityRemoteUIElement setRemoteUIApp:YES]; - } } bool NativeWidgetMacNSWindowHost::GetRootViewAccessibilityToken(
diff --git a/ui/views/win/hwnd_message_handler.cc b/ui/views/win/hwnd_message_handler.cc index 7516856..b1f7412 100644 --- a/ui/views/win/hwnd_message_handler.cc +++ b/ui/views/win/hwnd_message_handler.cc
@@ -37,6 +37,7 @@ #include "ui/accessibility/platform/ax_fragment_root_win.h" #include "ui/accessibility/platform/ax_platform_node_win.h" #include "ui/accessibility/platform/ax_system_caret_win.h" +#include "ui/base/ime/init/input_method_initializer.h" #include "ui/base/ime/text_input_client.h" #include "ui/base/ime/text_input_type.h" #include "ui/base/ui_base_features.h" @@ -1853,6 +1854,15 @@ display::win::ScreenWin::UpdateDisplayInfos(); SetBoundsInternal(gfx::Rect(*reinterpret_cast<RECT*>(l_param)), false); delegate_->HandleWindowScaleFactorChanged(scaling_factor); + + // https://crbug.com/41486958 + // On Windows, TSF will hang the browser window and stuck KEYBOARD and MOUSE + // window messages when user is using a non-English IME (Chinese: Microsoft + // Pinyin, etc..) and try typing on any textarea after a DPI change when + // window is minimized. This hacky workaround fix that problem, as same + // reproduce procedure no longer triggers the hang. + ui::RestartInputMethod(); + return 0; }
diff --git a/url/BUILD.gn b/url/BUILD.gn index b5edb89f..aedf1bf 100644 --- a/url/BUILD.gn +++ b/url/BUILD.gn
@@ -49,7 +49,6 @@ "url_canon_stdstring.cc", "url_canon_stdstring.h", "url_canon_stdurl.cc", - "url_constants.cc", "url_constants.h", "url_features.cc", "url_features.h",
diff --git a/url/android/java/src/org/chromium/url/Origin.java b/url/android/java/src/org/chromium/url/Origin.java index f1e90aa..b4c2970 100644 --- a/url/android/java/src/org/chromium/url/Origin.java +++ b/url/android/java/src/org/chromium/url/Origin.java
@@ -8,6 +8,8 @@ import org.jni_zero.JNINamespace; import org.jni_zero.NativeMethods; +import java.util.Objects; + /** An origin is either a (scheme, host, port) tuple or is opaque. */ @JNINamespace("url") public class Origin { @@ -94,6 +96,35 @@ return mIsOpaque; } + @Override + public final int hashCode() { + return Objects.hash(mScheme, mHost, mPort, mIsOpaque, mTokenHighBits, mTokenLowBits); + } + + @Override + public final boolean equals(Object other) { + if (other == this) return true; + if (!(other instanceof Origin)) return false; + + Origin that = (Origin) other; + + return mScheme.equals(that.mScheme) + && mHost.equals(that.mHost) + && mPort == that.mPort + && mIsOpaque == that.mIsOpaque + && mTokenHighBits == that.mTokenHighBits + && mTokenLowBits == that.mTokenLowBits; + } + + /** + * Returns a String representing the Origin in structure of scheme://host:port or the string + * "null" if it's opaque. + */ + @Override + public String toString() { + return isOpaque() ? "null" : String.format("%s://%s:%s", mScheme, mHost, mPort); + } + @CalledByNative private long toNativeOrigin() { return OriginJni.get()
diff --git a/url/url_constants.h b/url/url_constants.h index 5eda4e89..b201483 100644 --- a/url/url_constants.h +++ b/url/url_constants.h
@@ -7,63 +7,60 @@ #include <stddef.h> -#include "base/component_export.h" - namespace url { -COMPONENT_EXPORT(URL) extern const char kAboutBlankURL[]; -COMPONENT_EXPORT(URL) extern const char16_t kAboutBlankURL16[]; -COMPONENT_EXPORT(URL) extern const char kAboutSrcdocURL[]; -COMPONENT_EXPORT(URL) extern const char16_t kAboutSrcdocURL16[]; +inline constexpr char kAboutBlankURL[] = "about:blank"; +inline constexpr char16_t kAboutBlankURL16[] = u"about:blank"; +inline constexpr char kAboutSrcdocURL[] = "about:srcdoc"; +inline constexpr char16_t kAboutSrcdocURL16[] = u"about:srcdoc"; -COMPONENT_EXPORT(URL) extern const char kAboutBlankPath[]; -COMPONENT_EXPORT(URL) extern const char16_t kAboutBlankPath16[]; -COMPONENT_EXPORT(URL) extern const char kAboutSrcdocPath[]; -COMPONENT_EXPORT(URL) extern const char16_t kAboutSrcdocPath16[]; +inline constexpr char kAboutBlankPath[] = "blank"; +inline constexpr char16_t kAboutBlankPath16[] = u"blank"; +inline constexpr char kAboutSrcdocPath[] = "srcdoc"; +inline constexpr char16_t kAboutSrcdocPath16[] = u"srcdoc"; -COMPONENT_EXPORT(URL) extern const char kAboutScheme[]; -COMPONENT_EXPORT(URL) extern const char16_t kAboutScheme16[]; -COMPONENT_EXPORT(URL) extern const char kBlobScheme[]; -COMPONENT_EXPORT(URL) extern const char16_t kBlobScheme16[]; -// The content scheme is specific to Android for identifying a stored file. -COMPONENT_EXPORT(URL) extern const char kContentScheme[]; -COMPONENT_EXPORT(URL) extern const char16_t kContentScheme16[]; -COMPONENT_EXPORT(URL) extern const char kContentIDScheme[]; -COMPONENT_EXPORT(URL) extern const char16_t kContentIDScheme16[]; -COMPONENT_EXPORT(URL) extern const char kDataScheme[]; -COMPONENT_EXPORT(URL) extern const char16_t kDataScheme16[]; -COMPONENT_EXPORT(URL) extern const char kFileScheme[]; -COMPONENT_EXPORT(URL) extern const char16_t kFileScheme16[]; -COMPONENT_EXPORT(URL) extern const char kFileSystemScheme[]; -COMPONENT_EXPORT(URL) extern const char16_t kFileSystemScheme16[]; -COMPONENT_EXPORT(URL) extern const char kFtpScheme[]; -COMPONENT_EXPORT(URL) extern const char16_t kFtpScheme16[]; -COMPONENT_EXPORT(URL) extern const char kHttpScheme[]; -COMPONENT_EXPORT(URL) extern const char16_t kHttpScheme16[]; -COMPONENT_EXPORT(URL) extern const char kHttpsScheme[]; -COMPONENT_EXPORT(URL) extern const char16_t kHttpsScheme16[]; -COMPONENT_EXPORT(URL) extern const char kJavaScriptScheme[]; -COMPONENT_EXPORT(URL) extern const char16_t kJavaScriptScheme16[]; -COMPONENT_EXPORT(URL) extern const char kMailToScheme[]; -COMPONENT_EXPORT(URL) extern const char16_t kMailToScheme16[]; -COMPONENT_EXPORT(URL) extern const char kTelScheme[]; -COMPONENT_EXPORT(URL) extern const char16_t kTelScheme16[]; -COMPONENT_EXPORT(URL) extern const char kUrnScheme[]; -COMPONENT_EXPORT(URL) extern const char16_t kUrnScheme16[]; -COMPONENT_EXPORT(URL) extern const char kUuidInPackageScheme[]; -COMPONENT_EXPORT(URL) extern const char16_t kUuidInPackageScheme16[]; -COMPONENT_EXPORT(URL) extern const char kWebcalScheme[]; -COMPONENT_EXPORT(URL) extern const char16_t kWebcalScheme16[]; -COMPONENT_EXPORT(URL) extern const char kWsScheme[]; -COMPONENT_EXPORT(URL) extern const char16_t kWsScheme16[]; -COMPONENT_EXPORT(URL) extern const char kWssScheme[]; -COMPONENT_EXPORT(URL) extern const char16_t kWssScheme16[]; +inline constexpr char kAboutScheme[] = "about"; +inline constexpr char16_t kAboutScheme16[] = u"about"; +inline constexpr char kBlobScheme[] = "blob"; +inline constexpr char16_t kBlobScheme16[] = u"blob"; +inline constexpr char kContentScheme[] = "content"; +inline constexpr char16_t kContentScheme16[] = u"content"; +inline constexpr char kContentIDScheme[] = "cid"; +inline constexpr char16_t kContentIDScheme16[] = u"cid"; +inline constexpr char kDataScheme[] = "data"; +inline constexpr char16_t kDataScheme16[] = u"data"; +inline constexpr char kFileScheme[] = "file"; +inline constexpr char16_t kFileScheme16[] = u"file"; +inline constexpr char kFileSystemScheme[] = "filesystem"; +inline constexpr char16_t kFileSystemScheme16[] = u"filesystem"; +inline constexpr char kFtpScheme[] = "ftp"; +inline constexpr char16_t kFtpScheme16[] = u"ftp"; +inline constexpr char kHttpScheme[] = "http"; +inline constexpr char16_t kHttpScheme16[] = u"http"; +inline constexpr char kHttpsScheme[] = "https"; +inline constexpr char16_t kHttpsScheme16[] = u"https"; +inline constexpr char kJavaScriptScheme[] = "javascript"; +inline constexpr char16_t kJavaScriptScheme16[] = u"javascript"; +inline constexpr char kMailToScheme[] = "mailto"; +inline constexpr char16_t kMailToScheme16[] = u"mailto"; +inline constexpr char kTelScheme[] = "tel"; +inline constexpr char16_t kTelScheme16[] = u"tel"; +inline constexpr char kUrnScheme[] = "urn"; +inline constexpr char16_t kUrnScheme16[] = u"urn"; +inline constexpr char kUuidInPackageScheme[] = "uuid-in-package"; +inline constexpr char16_t kUuidInPackageScheme16[] = u"uuid-in-package"; +inline constexpr char kWebcalScheme[] = "webcal"; +inline constexpr char16_t kWebcalScheme16[] = u"webcal"; +inline constexpr char kWsScheme[] = "ws"; +inline constexpr char16_t kWsScheme16[] = u"ws"; +inline constexpr char kWssScheme[] = "wss"; +inline constexpr char16_t kWssScheme16[] = u"wss"; // Used to separate a standard scheme and the hostname: "://". -COMPONENT_EXPORT(URL) extern const char kStandardSchemeSeparator[]; -COMPONENT_EXPORT(URL) extern const char16_t kStandardSchemeSeparator16[]; +inline constexpr char kStandardSchemeSeparator[] = "://"; +inline constexpr char16_t kStandardSchemeSeparator16[] = u"://"; -COMPONENT_EXPORT(URL) extern const size_t kMaxURLChars; +inline constexpr size_t kMaxURLChars = 2 * 1024 * 1024; } // namespace url